From dff8e4cb05d361792ed7b276cb802ac412e8e8d8 Mon Sep 17 00:00:00 2001 From: Packit Service Date: Mar 27 2021 04:21:33 +0000 Subject: NetworkManager-1.32.0 base --- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7f95c77 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,216 @@ +Guidelines for Contributing +=========================== + + +Community +--------- + +Check out website https://networkmanager.dev and our [GNOME page](https://wiki.gnome.org/Projects/NetworkManager). + +The release tarballs can be found at [download.gnome.org](https://download.gnome.org/sources/NetworkManager/). + +Our mailing list is networkmanager-list@gnome.org ([archive](https://mail.gnome.org/archives/networkmanager-list/)). + +Find us on IRC channel `#nm` on freenode. + +Report issues and send patches via [gitlab.freedesktop.org](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/) +or our mailing list. + + +Legal +----- + +NetworkManager is partly licensed under terms of GNU Lesser General Public License +version 2 or later ([LGPL-2.1-or-later](COPYING.LGPL)). That is for example the case for libnm. +For historical reasons, the daemon itself is licensed under terms of GNU General +Public License, version 2 or later ([GPL-2.0-or-later](COPYING)). See the SPDX license comment +in the source files. + +Note that all new contributions to NetworkManager **MUST** be made under terms of +LGPL-2.1-or-later, that is also the case for files that are currently licensed GPL-2.0-or-later. +The reason is that we might one day use the code under terms of LGPL-2.1-or-later and all +new contributions already must already agree to that. +For more details see [RELICENSE.md](RELICENSE.md). + + +Coding Standard +--------------- + +The formatting uses clang-format with clang 11.0. Run +`./contrib/scripts/nm-code-format.sh -i` to reformat the code +or call `clang-format` yourself. +You may also call `./contrib/scripts/nm-code-format-container.sh` +which runs a Fedora 33 container using podman. +You are welcome to not bother and open a merge request with +wrong formatting, but note that we then will automatically adjust +your contribution before merging. + +The automatic reformatting was done by commit 328fb90f3e0d4e35975aff63944ac0412d7893a5. +Use `--ignore-rev` option or `--ignore-revs-file .git-blame-ignore-revs` to ignore +the reformatting commit with git-blame: + +``` +$ git config --add 'blame.ignoreRevsFile' '.git-blame-ignore-revs' +``` + +Since our coding style is entirely automated, the following are just +some details of the style we use: + +* Indent with 4 spaces. (_no_ tabs). + +* Have no space between the function name and the opening '('. + - GOOD: `g_strdup(x)` + - BAD: `g_strdup (x)` + +* C-style comments + - GOOD: `f(x); /* comment */` + - BAD: `f(x); // comment` + +* Keep assignments in the variable declaration area pretty short. + - GOOD: `MyObject *object;` + - BAD: `MyObject *object = complex_and_long_init_function(arg1, arg2, arg3);` + +* 80-cols is a guideline, don't make the code uncomfortable in order to fit in + less than 80 cols. + +* Constants are CAPS_WITH_UNDERSCORES and use the preprocessor. + - GOOD: `#define MY_CONSTANT 42` + - BAD: `static const unsigned myConstant = 42;` + + +Assertions in NetworkManager code +--------------------------------- + +There are different kind of assertions. Use the one that is appropriate. + +1) `g_return_*()` from glib. This is usually enabled in release builds and + can be disabled with `G_DISABLE_CHECKS` define. This uses `g_log()` with + `G_LOG_LEVEL_CRITICAL` level (which allows the program to continue, + unless `G_DEBUG=fatal-criticals` or `G_DEBUG=fatal-warnings` is set). As such, + this is usually the preferred way for assertions that are supposed to be + enabled by default. \ + \ + Optimally, after a `g_return_*()` failure the program can still continue. This is + also the reason why `g_return_*()` is preferable over `g_assert()`. + For example, that is often not the case for functions that return a `GError`, because + `g_return_*()` will return failure without setting the error output. That often leads + to a crash immediately after, because the caller requires the `GError` to be set. + Make a reasonable effort so that an assertion failure may allow the process + to proceed. But don't put too much effort in it. After all, it's an assertion + failure that is not supposed to happen either way. + +2) `nm_assert()` from NetworkManager. This is disabled by default in release + builds, but enabled if you build `--with-more-assertions`. See the `WITH_MORE_ASSERTS` + define. This is preferred for assertions that are expensive to check or + nor necessary to check frequently. It's also for conditions that can easily + be verified to be true and where future refactoring is unlikely to break the + invariant. + Use such asserts deliberately and assume they are removed from production builds. + +3) `g_assert()` from glib. This is used in unit tests and commonly enabled + in release builds. It can be disabled with `G_DISABLE_ASSERT` define. + Since such an assertion failure results in a hard crash, you + should almost always prefer `g_return_*()` over `g_assert()` (except in unit tests). + +4) `assert()` from C89's ``. It is usually enabled in release builds and + can be disabled with `NDEBUG` define. Don't use it in NetworkManager, + it's basically like g_assert(). + +5) `g_log()` from glib. These are always compiled in, depending on the logging level + they act as assertions too. `G_LOG_LEVEL_ERROR` messages abort the program, `G_LOG_LEVEL_CRITICAL` + log a critical warning (like `g_return_*()`, see `G_DEBUG=fatal-criticals`) + and `G_LOG_LEVEL_WARNING` logs a warning (see `G_DEBUG=fatal-warnings`). + `G_LOG_LEVEL_DEBUG` level is usually not printed, unless `G_MESSAGES_DEBUG` environment + variable enables it. \ + \ + In general, avoid using `g_log()` in NetworkManager. We have nm-logging instead + which logs to syslog or systemd-journald. + From a library like libnm it might make sense to log warnings (if something + is really wrong) or debug messages. But better don't. If it's important, + find a way to report the condition via the API to the caller. If it's + not important, keep silent. + In particular, don't use levels `G_LOG_LEVEL_CRITICAL` and `G_LOG_LEVEL_WARNING` because + we treat them as assertions and we want to run all out tests with `G_DEBUG=fatal-warnings`. + +6) `g_warn_if_*()` from glib. These are always compiled in and log a `G_LOG_LEVEL_WARNING` + warning. Don't use this. + +7) `G_TYPE_CHECK_INSTANCE_CAST()` from glib. Unless building with `WITH_MORE_ASSERTS`, + we set `G_DISABLE_CAST_CHECKS`. This means, cast macros like `NM_DEVICE(ptr)` + translate to plain C pointer casts. Use such cast macros deliberately, in production + code they are cheap, with more asserts enabled they check that the pointer type is + suitable. + +Of course, every assertion failure is a bug, and calling it must have no side effects. + +Theoretically, you are welcome to set `G_DISABLE_CHECKS`, `G_DISABLE_ASSERT` and +`NDEBUG` in production builds. In practice, nobody tests such a configuration, so beware. + +For testing, you also want to run NetworkManager with environment variable +`G_DEBUG=fatal-warnings` to crash upon `G_LOG_LEVEL_CRITICAL` and `G_LOG_LEVEL_WARNING` +`g_log()` message. NetworkManager won't use these levels for regular logging +but for assertions. + + +Git Notes (refs/notes/bugs) +--------------------------- + +We use special tags in commit messages like "Fixes", "cherry picked from" and "Ignore-Backport". +The [find-backports](contrib/scripts/find-backports) script uses these to find patches that +should be backported to older branches. Sometimes we don't know a-priory to mark a commit +with these tags so we can instead use the `bugs` notes. + +The git notes reference is called "refs/notes/bugs". + +So configure: + +``` +$ git config --add 'remote.origin.fetch' 'refs/notes/bugs:refs/notes/bugs' +$ git config --add 'notes.displayref' 'refs/notes/bugs' +``` + +For example, set notes with + +``` +$ git notes --ref refs/notes/bugs add -m "(cherry picked from $COMMIT_SHA)" HEAD +``` + +You should see the notes in git-log output as well. + +To resync our local notes use: + +``` +$ git fetch origin refs/notes/bugs:refs/notes/bugs -f +``` + +Code Structure +--------------------------- + +`./contrib`- Contains a lot of required package, configuration for different platform and environment, build NM from source tree. + +`./data`- Contains some configurations and rules. + +`./docs`- Contains the generated documentation for libnm and for the D-Bus API. + +`./examples`- Some code examples for basic networking operations and status checking. + +`./introspection`- XML docs describing various D-Bus interface and their properties. + +`./m4`- Contains M4 macros source files for autoconf. + +`./man`- NM manual files. + +`./po`- contains text-based portable object file. These .PO files are referenced by GNU gettext as a property file and these files are human readable used for translating purpose. + +`./src`- source code for libnm, nmcli, nm-cloud-setup, nmtui… + +`./tools`- tools for generating the intermediate files or merging the file. + +Cscope/ctags +--------------------------- + +NetworkManager's source code is large. It may be a good idea to use tools like cscope/ctags to index the +source code and navigate it. These tools can integrate with editors like `Vim` and `Emacs`. See: + +- http://cscope.sourceforge.net/cscope_vim_tutorial.html +- https://www.emacswiki.org/emacs/CScopeAndEmacs diff --git a/Makefile.am b/Makefile.am index 9279672..d1706e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -110,20 +110,27 @@ include config-extra.h.mk DISTCLEANFILES += config-extra.h -$(libnm_core_lib_h_pub_mkenums): config-extra.h -libnm-core/.dirstamp: config-extra.h -shared/.dirstamp: config-extra.h -shared/nm-base/.dirstamp: config-extra.h -shared/nm-glib-aux/.dirstamp: config-extra.h -shared/nm-glib-aux/tests/.dirstamp: config-extra.h -shared/nm-platform/.dirstamp: config-extra.h -shared/nm-platform/tests/.dirstamp: config-extra.h -shared/nm-std-aux/.dirstamp: config-extra.h -shared/nm-udev-aux/.dirstamp: config-extra.h -shared/systemd/.dirstamp: config-extra.h -shared/systemd/src/basic/.dirstamp: config-extra.h -shared/systemd/src/shared/.dirstamp: config-extra.h -src/core/dhcp/.dirstamp: config-extra.h +$(src_libnm_core_public_mkenums_h): config-extra.h +$(src_libnm_core_public_mkenums_c): config-extra.h +src/libnm-core-impl/.dirstamp: config-extra.h +src/libnm-core-impl/.dirstamp: config-extra.h +src/libnm-base/.dirstamp: config-extra.h +src/libnm-glib-aux/.dirstamp: config-extra.h +src/libnm-glib-aux/tests/.dirstamp: config-extra.h +src/libnm-log-core/.dirstamp: config-extra.h +src/libnm-log-null/.dirstamp: config-extra.h +src/libnm-platform/.dirstamp: config-extra.h +src/libnm-platform/tests/.dirstamp: config-extra.h +src/libnm-platform/wifi/.dirstamp: config-extra.h +src/libnm-platform/wpan/.dirstamp: config-extra.h +src/libnm-std-aux/.dirstamp: config-extra.h +src/libnm-udev-aux/.dirstamp: config-extra.h +src/libnm-systemd-shared/.dirstamp: config-extra.h +src/libnm-systemd-shared/src/basic/.dirstamp: config-extra.h +src/libnm-systemd-shared/src/shared/.dirstamp: config-extra.h +src/libnm-client-public/.dirstamp: config-extra.h +src/libnm-client-public/.dirstamp: config-extra.h +src/core/dhcp/.dirstamp: config-extra.h ############################################################################### @@ -212,514 +219,660 @@ DISTCLEANFILES += $(polkit_policy_DATA) ############################################################################### EXTRA_DIST += \ - shared/c-stdaux/src/c-stdaux.h \ + src/c-stdaux/src/c-stdaux.h \ $(NULL) ############################################################################### -noinst_LTLIBRARIES += shared/libcsiphash.la +noinst_LTLIBRARIES += src/c-siphash/libc-siphash.la -shared_libcsiphash_la_CFLAGS = \ +src_c_siphash_libc_siphash_la_CFLAGS = \ $(AM_CFLAGS) \ -std=c11 \ - -I$(srcdir)/shared/c-stdaux/src \ + -I$(srcdir)/src/c-stdaux/src \ $(NULL) -shared_libcsiphash_la_CPPFLAGS = \ +src_c_siphash_libc_siphash_la_CPPFLAGS = \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -shared_libcsiphash_la_LDFLAGS = \ +src_c_siphash_libc_siphash_la_LDFLAGS = \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_libcsiphash_la_SOURCES = \ - shared/c-siphash/src/c-siphash.c \ - shared/c-siphash/src/c-siphash.h \ +src_c_siphash_libc_siphash_la_SOURCES = \ + src/c-siphash/src/c-siphash.c \ + src/c-siphash/src/c-siphash.h \ $(NULL) ############################################################################### -noinst_LTLIBRARIES += shared/libcrbtree.la +noinst_LTLIBRARIES += src/c-rbtree/libc-rbtree.la -shared_libcrbtree_la_CFLAGS = \ +src_c_rbtree_libc_rbtree_la_CFLAGS = \ $(AM_CFLAGS) \ -std=c11 \ - -I$(srcdir)/shared/c-stdaux/src \ + -I$(srcdir)/src/c-stdaux/src \ $(NULL) -shared_libcrbtree_la_CPPFLAGS = \ +src_c_rbtree_libc_rbtree_la_CPPFLAGS = \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -shared_libcrbtree_la_LDFLAGS = \ +src_c_rbtree_libc_rbtree_la_LDFLAGS = \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_libcrbtree_la_SOURCES = \ - shared/c-rbtree/src/c-rbtree.c \ - shared/c-rbtree/src/c-rbtree.h \ - shared/c-rbtree/src/c-rbtree-private.h \ +src_c_rbtree_libc_rbtree_la_SOURCES = \ + src/c-rbtree/src/c-rbtree.c \ + src/c-rbtree/src/c-rbtree.h \ + src/c-rbtree/src/c-rbtree-private.h \ $(NULL) ############################################################################### -noinst_LTLIBRARIES += shared/libnacd.la +noinst_LTLIBRARIES += src/n-acd/libn-acd.la -shared_libnacd_la_CFLAGS = \ +src_n_acd_libn_acd_la_CFLAGS = \ $(AM_CFLAGS) \ -std=c11 \ -Wno-pointer-arith \ -Wno-vla \ $(NULL) -shared_libnacd_la_CPPFLAGS = \ +src_n_acd_libn_acd_la_CPPFLAGS = \ -D_GNU_SOURCE \ -DSO_ATTACH_BPF=50 \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -I$(srcdir)/shared/c-stdaux/src \ - -I$(srcdir)/shared/c-list/src \ - -I$(srcdir)/shared/c-siphash/src \ - -I$(srcdir)/shared/c-rbtree/src \ + -I$(srcdir)/src/c-stdaux/src \ + -I$(srcdir)/src/c-list/src \ + -I$(srcdir)/src/c-siphash/src \ + -I$(srcdir)/src/c-rbtree/src \ $(NULL) -shared_libnacd_la_LDFLAGS = \ +src_n_acd_libn_acd_la_LDFLAGS = \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_libnacd_la_SOURCES = \ - shared/n-acd/src/n-acd.c \ - shared/n-acd/src/n-acd.h \ - shared/n-acd/src/n-acd-private.h \ - shared/n-acd/src/n-acd-probe.c \ - shared/n-acd/src/util/timer.c \ - shared/n-acd/src/util/timer.h \ +src_n_acd_libn_acd_la_SOURCES = \ + src/n-acd/src/n-acd.c \ + src/n-acd/src/n-acd.h \ + src/n-acd/src/n-acd-private.h \ + src/n-acd/src/n-acd-probe.c \ + src/n-acd/src/util/timer.c \ + src/n-acd/src/util/timer.h \ $(NULL) if WITH_EBPF -shared_libnacd_la_SOURCES += shared/n-acd/src/n-acd-bpf.c +src_n_acd_libn_acd_la_SOURCES += src/n-acd/src/n-acd-bpf.c else -shared_libnacd_la_SOURCES += shared/n-acd/src/n-acd-bpf-fallback.c +src_n_acd_libn_acd_la_SOURCES += src/n-acd/src/n-acd-bpf-fallback.c endif ############################################################################### -noinst_LTLIBRARIES += shared/libndhcp4.la +noinst_LTLIBRARIES += src/n-dhcp4/libn-dhcp4.la -shared_libndhcp4_la_CFLAGS = \ +src_n_dhcp4_libn_dhcp4_la_CFLAGS = \ $(AM_CFLAGS) \ -std=c11 \ -Wno-error=declaration-after-statement \ -Wno-pointer-arith \ $(NULL) -shared_libndhcp4_la_CPPFLAGS = \ +src_n_dhcp4_libn_dhcp4_la_CPPFLAGS = \ -D_GNU_SOURCE \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -I$(srcdir)/shared/c-stdaux/src \ - -I$(srcdir)/shared/c-list/src \ - -I$(srcdir)/shared/c-siphash/src \ + -I$(srcdir)/src/c-stdaux/src \ + -I$(srcdir)/src/c-list/src \ + -I$(srcdir)/src/c-siphash/src \ $(NULL) -shared_libndhcp4_la_LDFLAGS = \ - $(SANITIZER_LIB_LDFLAGS) +src_n_dhcp4_libn_dhcp4_la_LDFLAGS = \ + $(SANITIZER_LIB_LDFLAGS) \ + $(NULL) -shared_libndhcp4_la_SOURCES = \ - shared/n-dhcp4/src/n-dhcp4-c-connection.c \ - shared/n-dhcp4/src/n-dhcp4-c-lease.c \ - shared/n-dhcp4/src/n-dhcp4-c-probe.c \ - shared/n-dhcp4/src/n-dhcp4-client.c \ - shared/n-dhcp4/src/n-dhcp4-incoming.c \ - shared/n-dhcp4/src/n-dhcp4-outgoing.c \ - shared/n-dhcp4/src/n-dhcp4-private.h \ - shared/n-dhcp4/src/n-dhcp4-socket.c \ - shared/n-dhcp4/src/n-dhcp4.h \ - shared/n-dhcp4/src/util/packet.c \ - shared/n-dhcp4/src/util/packet.h \ - shared/n-dhcp4/src/util/socket.c \ - shared/n-dhcp4/src/util/socket.h \ +src_n_dhcp4_libn_dhcp4_la_SOURCES = \ + src/n-dhcp4/src/n-dhcp4-c-connection.c \ + src/n-dhcp4/src/n-dhcp4-c-lease.c \ + src/n-dhcp4/src/n-dhcp4-c-probe.c \ + src/n-dhcp4/src/n-dhcp4-client.c \ + src/n-dhcp4/src/n-dhcp4-incoming.c \ + src/n-dhcp4/src/n-dhcp4-outgoing.c \ + src/n-dhcp4/src/n-dhcp4-private.h \ + src/n-dhcp4/src/n-dhcp4-socket.c \ + src/n-dhcp4/src/n-dhcp4.h \ + src/n-dhcp4/src/util/packet.c \ + src/n-dhcp4/src/util/packet.h \ + src/n-dhcp4/src/util/socket.c \ + src/n-dhcp4/src/util/socket.h \ $(NULL) ############################################################################### -noinst_LTLIBRARIES += shared/nm-std-aux/libnm-std-aux.la +noinst_LTLIBRARIES += src/libnm-std-aux/libnm-std-aux.la -shared_nm_std_aux_libnm_std_aux_la_CPPFLAGS = \ +src_libnm_std_aux_libnm_std_aux_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnm"\" \ $(NULL) -shared_nm_std_aux_libnm_std_aux_la_SOURCES = \ - shared/c-list/src/c-list.h \ - shared/nm-std-aux/c-list-util.c \ - shared/nm-std-aux/c-list-util.h \ - shared/nm-std-aux/nm-dbus-compat.h \ - shared/nm-std-aux/nm-default-std.h \ - shared/nm-std-aux/nm-networkmanager-compilation.h \ - shared/nm-std-aux/nm-std-aux.h \ - shared/nm-std-aux/nm-std-utils.c \ - shared/nm-std-aux/nm-std-utils.h \ - shared/nm-std-aux/unaligned.h \ +src_libnm_std_aux_libnm_std_aux_la_SOURCES = \ + src/c-list/src/c-list.h \ + src/libnm-std-aux/c-list-util.c \ + src/libnm-std-aux/c-list-util.h \ + src/libnm-std-aux/nm-dbus-compat.h \ + src/libnm-std-aux/nm-default-std.h \ + src/libnm-std-aux/nm-networkmanager-compilation.h \ + src/libnm-std-aux/nm-std-aux.h \ + src/libnm-std-aux/nm-std-utils.c \ + src/libnm-std-aux/nm-std-utils.h \ + src/libnm-std-aux/unaligned.h \ $(NULL) -shared_nm_std_aux_libnm_std_aux_la_LDFLAGS = \ +src_libnm_std_aux_libnm_std_aux_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) +EXTRA_DIST += src/libnm-std-aux/meson.build + ############################################################################### -shared_nm_glib_aux_cppflags = \ +src_libnm_glib_aux_cppflags = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(GLIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnm"\" \ - $(NULL) - -noinst_LTLIBRARIES += shared/nm-glib-aux/libnm-glib-aux.la - -shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS = \ - $(shared_nm_glib_aux_cppflags) \ - $(NULL) - -shared_nm_glib_aux_libnm_glib_aux_la_SOURCES = \ - shared/nm-glib-aux/nm-c-list.h \ - shared/nm-glib-aux/nm-dbus-aux.c \ - shared/nm-glib-aux/nm-dbus-aux.h \ - shared/nm-glib-aux/nm-dedup-multi.c \ - shared/nm-glib-aux/nm-dedup-multi.h \ - shared/nm-glib-aux/nm-default-glib-i18n-lib.h \ - shared/nm-glib-aux/nm-default-glib-i18n-prog.h \ - shared/nm-glib-aux/nm-default-glib.h \ - shared/nm-glib-aux/nm-enum-utils.c \ - shared/nm-glib-aux/nm-enum-utils.h \ - shared/nm-glib-aux/nm-errno.c \ - shared/nm-glib-aux/nm-errno.h \ - shared/nm-glib-aux/nm-gassert-patch.h \ - shared/nm-glib-aux/nm-glib.h \ - shared/nm-glib-aux/nm-hash-utils.c \ - shared/nm-glib-aux/nm-hash-utils.h \ - shared/nm-glib-aux/nm-io-utils.c \ - shared/nm-glib-aux/nm-io-utils.h \ - shared/nm-glib-aux/nm-jansson.h \ - shared/nm-glib-aux/nm-json-aux.c \ - shared/nm-glib-aux/nm-json-aux.h \ - shared/nm-glib-aux/nm-keyfile-aux.c \ - shared/nm-glib-aux/nm-keyfile-aux.h \ - shared/nm-glib-aux/nm-logging-base.c \ - shared/nm-glib-aux/nm-logging-base.h \ - shared/nm-glib-aux/nm-logging-fwd.h \ - shared/nm-glib-aux/nm-macros-internal.h \ - shared/nm-glib-aux/nm-obj.h \ - shared/nm-glib-aux/nm-random-utils.c \ - shared/nm-glib-aux/nm-random-utils.h \ - shared/nm-glib-aux/nm-ref-string.c \ - shared/nm-glib-aux/nm-ref-string.h \ - shared/nm-glib-aux/nm-secret-utils.c \ - shared/nm-glib-aux/nm-secret-utils.h \ - shared/nm-glib-aux/nm-shared-utils.c \ - shared/nm-glib-aux/nm-shared-utils.h \ - shared/nm-glib-aux/nm-str-buf.h \ - shared/nm-glib-aux/nm-time-utils.c \ - shared/nm-glib-aux/nm-time-utils.h \ - shared/nm-glib-aux/nm-value-type.h \ - $(NULL) - -shared_nm_glib_aux_libnm_glib_aux_la_LDFLAGS = \ + $(NULL) + +noinst_LTLIBRARIES += src/libnm-glib-aux/libnm-glib-aux.la + +src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS = \ + $(src_libnm_glib_aux_cppflags) \ + $(NULL) + +src_libnm_glib_aux_libnm_glib_aux_la_SOURCES = \ + src/libnm-glib-aux/nm-c-list.h \ + src/libnm-glib-aux/nm-dbus-aux.c \ + src/libnm-glib-aux/nm-dbus-aux.h \ + src/libnm-glib-aux/nm-dedup-multi.c \ + src/libnm-glib-aux/nm-dedup-multi.h \ + src/libnm-glib-aux/nm-default-glib-i18n-lib.h \ + src/libnm-glib-aux/nm-default-glib-i18n-prog.h \ + src/libnm-glib-aux/nm-default-glib.h \ + src/libnm-glib-aux/nm-enum-utils.c \ + src/libnm-glib-aux/nm-enum-utils.h \ + src/libnm-glib-aux/nm-errno.c \ + src/libnm-glib-aux/nm-errno.h \ + src/libnm-glib-aux/nm-gassert-patch.h \ + src/libnm-glib-aux/nm-glib.h \ + src/libnm-glib-aux/nm-hash-utils.c \ + src/libnm-glib-aux/nm-hash-utils.h \ + src/libnm-glib-aux/nm-io-utils.c \ + src/libnm-glib-aux/nm-io-utils.h \ + src/libnm-glib-aux/nm-jansson.h \ + src/libnm-glib-aux/nm-json-aux.c \ + src/libnm-glib-aux/nm-json-aux.h \ + src/libnm-glib-aux/nm-keyfile-aux.c \ + src/libnm-glib-aux/nm-keyfile-aux.h \ + src/libnm-glib-aux/nm-logging-base.c \ + src/libnm-glib-aux/nm-logging-base.h \ + src/libnm-glib-aux/nm-logging-fwd.h \ + src/libnm-glib-aux/nm-logging-syslog.h \ + src/libnm-glib-aux/nm-macros-internal.h \ + src/libnm-glib-aux/nm-obj.h \ + src/libnm-glib-aux/nm-random-utils.c \ + src/libnm-glib-aux/nm-random-utils.h \ + src/libnm-glib-aux/nm-ref-string.c \ + src/libnm-glib-aux/nm-ref-string.h \ + src/libnm-glib-aux/nm-secret-utils.c \ + src/libnm-glib-aux/nm-secret-utils.h \ + src/libnm-glib-aux/nm-shared-utils.c \ + src/libnm-glib-aux/nm-shared-utils.h \ + src/libnm-glib-aux/nm-str-buf.h \ + src/libnm-glib-aux/nm-test-utils.h \ + src/libnm-glib-aux/nm-time-utils.c \ + src/libnm-glib-aux/nm-time-utils.h \ + src/libnm-glib-aux/nm-value-type.h \ + $(NULL) + +src_libnm_glib_aux_libnm_glib_aux_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_nm_glib_aux_libnm_glib_aux_la_LIBADD = \ +src_libnm_glib_aux_libnm_glib_aux_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) +EXTRA_DIST += src/libnm-glib-aux/meson.build + ############################################################################### -noinst_LTLIBRARIES += shared/nm-udev-aux/libnm-udev-aux.la +noinst_LTLIBRARIES += src/libnm-udev-aux/libnm-udev-aux.la -shared_nm_udev_aux_libnm_udev_aux_la_CPPFLAGS = \ - $(shared_nm_glib_aux_cppflags) \ +src_libnm_udev_aux_libnm_udev_aux_la_CPPFLAGS = \ + $(src_libnm_glib_aux_cppflags) \ $(LIBUDEV_CFLAGS) \ $(NULL) -shared_nm_udev_aux_libnm_udev_aux_la_SOURCES = \ - shared/nm-udev-aux/nm-udev-utils.c \ - shared/nm-udev-aux/nm-udev-utils.h \ +src_libnm_udev_aux_libnm_udev_aux_la_SOURCES = \ + src/libnm-udev-aux/nm-udev-utils.c \ + src/libnm-udev-aux/nm-udev-utils.h \ $(NULL) -shared_nm_udev_aux_libnm_udev_aux_la_LDFLAGS = \ +src_libnm_udev_aux_libnm_udev_aux_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_nm_udev_aux_libnm_udev_aux_la_LIBADD = \ +src_libnm_udev_aux_libnm_udev_aux_la_LIBADD = \ $(GLIB_LIBS) \ $(LIBUDEV_LIBS) \ $(NULL) +EXTRA_DIST += src/libnm-udev-aux/meson.build + ############################################################################### -noinst_LTLIBRARIES += shared/nm-base/libnm-base.la +noinst_LTLIBRARIES += src/libnm-base/libnm-base.la -shared_nm_base_libnm_base_la_CPPFLAGS = \ - $(shared_nm_glib_aux_cppflags) \ +src_libnm_base_libnm_base_la_CPPFLAGS = \ + $(src_libnm_glib_aux_cppflags) \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(NULL) -shared_nm_base_libnm_base_la_SOURCES = \ - shared/nm-base/nm-base.h \ - shared/nm-base/nm-ethtool-base.c \ - shared/nm-base/nm-ethtool-base.h \ - shared/nm-base/nm-ethtool-utils-base.h \ +src_libnm_base_libnm_base_la_SOURCES = \ + src/libnm-base/nm-base.h \ + src/libnm-base/nm-config-base.h \ + src/libnm-base/nm-ethtool-base.c \ + src/libnm-base/nm-ethtool-base.h \ + src/libnm-base/nm-ethtool-utils-base.h \ + src/libnm-base/nm-net-aux.c \ + src/libnm-base/nm-net-aux.h \ $(NULL) -shared_nm_base_libnm_base_la_LDFLAGS = \ +src_libnm_base_libnm_base_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_nm_base_libnm_base_la_LIBADD = \ +src_libnm_base_libnm_base_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) +EXTRA_DIST += src/libnm-base/meson.build + ############################################################################### -noinst_LTLIBRARIES += shared/nm-log-core/libnm-log-core.la +noinst_LTLIBRARIES += src/libnm-log-core/libnm-log-core.la -shared_nm_log_core_libnm_log_core_la_CPPFLAGS = \ +src_libnm_log_core_libnm_log_core_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(GLIB_CFLAGS) \ $(SYSTEMD_JOURNAL_CFLAGS) \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ $(NULL) -shared_nm_log_core_libnm_log_core_la_SOURCES = \ - shared/nm-log-core/nm-logging.c \ - shared/nm-log-core/nm-logging.h \ +src_libnm_log_core_libnm_log_core_la_SOURCES = \ + src/libnm-log-core/nm-logging.c \ + src/libnm-log-core/nm-logging.h \ $(NULL) -shared_nm_log_core_libnm_log_core_la_LDFLAGS = \ +src_libnm_log_core_libnm_log_core_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_nm_log_core_libnm_log_core_la_LIBADD = \ +src_libnm_log_core_libnm_log_core_la_LIBADD = \ $(GLIB_LIBS) \ $(SYSTEMD_JOURNAL_LIBS) \ $(NULL) +EXTRA_DIST += src/libnm-log-core/meson.build + +noinst_LTLIBRARIES += src/libnm-log-null/libnm-log-null.la + +src_libnm_log_null_libnm_log_null_la_CPPFLAGS = \ + $(dflt_cppflags) \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + $(CODE_COVERAGE_CFLAGS) \ + $(SANITIZER_LIB_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(NULL) + +src_libnm_log_null_libnm_log_null_la_SOURCES = \ + src/libnm-log-null/nm-logging-null.c \ + $(NULL) + +src_libnm_log_null_libnm_log_null_la_LIBADD = \ + $(GLIB_LIBS) \ + $(CODE_COVERAGE_LDFLAGS) \ + $(NULL) + +EXTRA_DIST += src/libnm-log-null/meson.build + ############################################################################### -noinst_LTLIBRARIES += shared/nm-platform/libnm-platform.la +noinst_LTLIBRARIES += src/libnm-platform/libnm-platform.la -shared_nm_platform_libnm_platform_la_CPPFLAGS = \ - $(shared_nm_glib_aux_cppflags) \ +src_libnm_platform_libnm_platform_la_CPPFLAGS = \ + $(src_libnm_glib_aux_cppflags) \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(NULL) -shared_nm_platform_libnm_platform_la_SOURCES = \ - shared/nm-platform/nm-netlink.c \ - shared/nm-platform/nm-netlink.h \ - shared/nm-platform/nm-platform-utils.c \ - shared/nm-platform/nm-platform-utils.h \ - shared/nm-platform/nmp-base.h \ - shared/nm-platform/nmp-netns.c \ - shared/nm-platform/nmp-netns.h \ +src_libnm_platform_libnm_platform_la_SOURCES = \ + \ + src/linux-headers/nl802154.h \ + \ + src/libnm-platform/nm-linux-platform.c \ + src/libnm-platform/nm-linux-platform.h \ + src/libnm-platform/nm-netlink.c \ + src/libnm-platform/nm-netlink.h \ + src/libnm-platform/nm-platform-private.h \ + src/libnm-platform/nm-platform-utils.c \ + src/libnm-platform/nm-platform-utils.h \ + src/libnm-platform/nm-platform.c \ + src/libnm-platform/nm-platform.h \ + src/libnm-platform/nmp-base.h \ + src/libnm-platform/nmp-netns.c \ + src/libnm-platform/nmp-netns.h \ + src/libnm-platform/nmp-object.c \ + src/libnm-platform/nmp-object.h \ + src/libnm-platform/nmp-rules-manager.c \ + src/libnm-platform/nmp-rules-manager.h \ + src/libnm-platform/wifi/nm-wifi-utils-nl80211.c \ + src/libnm-platform/wifi/nm-wifi-utils-nl80211.h \ + src/libnm-platform/wifi/nm-wifi-utils-private.h \ + src/libnm-platform/wifi/nm-wifi-utils.c \ + src/libnm-platform/wifi/nm-wifi-utils.h \ + src/libnm-platform/wpan/nm-wpan-utils.c \ + src/libnm-platform/wpan/nm-wpan-utils.h \ + \ $(NULL) -shared_nm_platform_libnm_platform_la_LDFLAGS = \ +if WITH_WEXT +src_libnm_platform_libnm_platform_la_SOURCES += \ + src/libnm-platform/wifi/nm-wifi-utils-wext.c \ + src/libnm-platform/wifi/nm-wifi-utils-wext.h \ + $(NULL) +endif + +src_libnm_platform_libnm_platform_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_nm_platform_libnm_platform_la_LIBADD = \ +src_libnm_platform_libnm_platform_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) +EXTRA_DIST += src/libnm-platform/meson.build + ############################################################################### -check_programs += shared/nm-platform/tests/test-nm-platform +check_programs += src/libnm-platform/tests/test-nm-platform -shared_nm_platform_tests_test_nm_platform_CPPFLAGS = \ +src_libnm_platform_tests_test_nm_platform_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -DG_LOG_DOMAIN=\""test"\" \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(SYSTEMD_JOURNAL_CFLAGS) \ $(GLIB_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -shared_nm_platform_tests_test_nm_platform_LDFLAGS = \ +src_libnm_platform_tests_test_nm_platform_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -shared_nm_platform_tests_test_nm_platform_LDADD = \ - shared/nm-platform/libnm-platform.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ +src_libnm_platform_tests_test_nm_platform_LDADD = \ + src/libnm-platform/libnm-platform.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(SYSTEMD_JOURNAL_LIBS) \ $(GLIB_LIBS) \ $(NULL) EXTRA_DIST += \ - shared/nm-platform/tests/meson.build \ + src/libnm-platform/tests/meson.build \ $(NULL) ############################################################################### -noinst_LTLIBRARIES += libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la +noinst_LTLIBRARIES += src/libnm-core-aux-intern/libnm-core-aux-intern.la -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_CPPFLAGS = \ +src_libnm_core_aux_intern_libnm_core_aux_intern_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ + -I$(builddir)/src \ + -I$(srcdir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnm"\" \ $(NULL) -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_SOURCES = \ - libnm-core/nm-libnm-core-intern/nm-auth-subject.c \ - libnm-core/nm-libnm-core-intern/nm-auth-subject.h \ - libnm-core/nm-libnm-core-intern/nm-common-macros.h \ - libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c \ - libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.h \ +src_libnm_core_aux_intern_libnm_core_aux_intern_la_SOURCES = \ + src/libnm-core-aux-intern/nm-auth-subject.c \ + src/libnm-core-aux-intern/nm-auth-subject.h \ + src/libnm-core-aux-intern/nm-common-macros.h \ + src/libnm-core-aux-intern/nm-libnm-core-utils.c \ + src/libnm-core-aux-intern/nm-libnm-core-utils.h \ $(NULL) -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_LDFLAGS = \ +src_libnm_core_aux_intern_libnm_core_aux_intern_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_LIBADD = \ +src_libnm_core_aux_intern_libnm_core_aux_intern_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) -$(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_libnm_core_aux_intern_libnm_core_aux_intern_la_OBJECTS): $(src_libnm_core_public_mkenums_h) -EXTRA_DIST += libnm-core/nm-libnm-core-intern/README.md +EXTRA_DIST += \ + src/libnm-core-aux-intern/README.md \ + src/libnm-core-aux-intern/meson.build \ + $(NULL) ############################################################################### -noinst_LTLIBRARIES += libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la +noinst_LTLIBRARIES += src/libnm-core-aux-extern/libnm-core-aux-extern.la -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_CPPFLAGS = \ +src_libnm_core_aux_extern_libnm_core_aux_extern_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnm"\" \ $(NULL) -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_SOURCES = \ - libnm-core/nm-libnm-core-aux/nm-dispatcher-api.h \ - libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c \ - libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.h \ +src_libnm_core_aux_extern_libnm_core_aux_extern_la_SOURCES = \ + src/libnm-core-aux-extern/nm-dispatcher-api.h \ + src/libnm-core-aux-extern/nm-libnm-core-aux.c \ + src/libnm-core-aux-extern/nm-libnm-core-aux.h \ $(NULL) -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_LDFLAGS = \ +src_libnm_core_aux_extern_libnm_core_aux_extern_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_LIBADD = \ +src_libnm_core_aux_extern_libnm_core_aux_extern_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) -$(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_libnm_core_aux_extern_libnm_core_aux_extern_la_OBJECTS): $(src_libnm_core_public_mkenums_h) -EXTRA_DIST += libnm-core/nm-libnm-core-aux/README.md +EXTRA_DIST += \ + src/libnm-core-aux-extern/README.md \ + src/libnm-core-aux-extern/meson.build \ + $(NULL) ############################################################################### -noinst_LTLIBRARIES += libnm/nm-libnm-aux/libnm-libnm-aux.la +noinst_LTLIBRARIES += src/libnm-client-aux-extern/libnm-client-aux-extern.la -libnm_nm_libnm_aux_libnm_libnm_aux_la_CPPFLAGS = \ +src_libnm_client_aux_extern_libnm_client_aux_extern_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnmc"\" \ $(NULL) -libnm_nm_libnm_aux_libnm_libnm_aux_la_SOURCES = \ - libnm/nm-libnm-aux/nm-libnm-aux.c \ - libnm/nm-libnm-aux/nm-libnm-aux.h \ +src_libnm_client_aux_extern_libnm_client_aux_extern_la_SOURCES = \ + src/libnm-client-aux-extern/nm-libnm-aux.c \ + src/libnm-client-aux-extern/nm-libnm-aux.h \ $(NULL) -libnm_nm_libnm_aux_libnm_libnm_aux_la_LDFLAGS = \ +src_libnm_client_aux_extern_libnm_client_aux_extern_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -libnm_nm_libnm_aux_libnm_libnm_aux_la_LIBADD = \ +src_libnm_client_aux_extern_libnm_client_aux_extern_la_LIBADD = \ $(GLIB_LIBS) \ - libnm/libnm.la \ + src/libnm-client-impl/libnm.la \ $(NULL) -$(libnm_nm_libnm_aux_libnm_libnm_aux_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_nm_libnm_aux_libnm_libnm_aux_la_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_libnm_client_aux_extern_libnm_client_aux_extern_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_client_aux_extern_libnm_client_aux_extern_la_OBJECTS): $(src_libnm_client_public_mkenums_h) -EXTRA_DIST += libnm/nm-libnm-aux/README.md +EXTRA_DIST += \ + src/libnm-client-aux-extern/README.md \ + src/libnm-client-aux-extern/meson.build \ + $(NULL) ############################################################################### +check_programs += src/libnm-client-aux-extern/tests/test-libnm-client-aux + +src_libnm_client_aux_extern_tests_test_libnm_client_aux_CPPFLAGS = \ + $(dflt_cppflags) \ + -I$(srcdir)/src/libnm-core-public \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + $(CODE_COVERAGE_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(SANITIZER_LIB_CFLAGS) \ + $(NULL) + +src_libnm_client_aux_extern_tests_test_libnm_client_aux_LDFLAGS = \ + $(CODE_COVERAGE_LDFLAGS) \ + $(SANITIZER_EXEC_LDFLAGS) \ + $(NULL) + +src_libnm_client_aux_extern_tests_test_libnm_client_aux_LDADD = \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + src/libnm-client-impl/libnm.la \ + $(GLIB_LIBS) \ + $(NULL) + +$(src_libnm_client_aux_extern_tests_test_libnm_client_aux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_client_aux_extern_tests_test_libnm_client_aux_OBJECTS): $(src_libnm_client_public_mkenums_h) + +############################################################################### + +noinst_LTLIBRARIES += src/libnm-client-test/libnm-client-test.la + +src_libnm_client_test_libnm_client_test_la_CPPFLAGS = \ + $(dflt_cppflags) \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ + $(CODE_COVERAGE_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(SANITIZER_LIB_CFLAGS) \ + $(NULL) + +src_libnm_client_test_libnm_client_test_la_SOURCES = \ + src/libnm-client-test/nm-test-libnm-utils.h \ + src/libnm-client-test/nm-test-utils-impl.c \ + $(NULL) + +src_libnm_client_test_libnm_client_test_la_LDFLAGS = \ + $(CODE_COVERAGE_LDFLAGS) \ + $(SANITIZER_LIB_LDFLAGS) \ + $(NULL) + +src_libnm_client_test_libnm_client_test_la_LIBADD = \ + $(GLIB_LIBS) \ + $(NULL) + +$(src_libnm_client_test_libnm_client_test_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_client_test_libnm_client_test_la_OBJECTS): $(src_libnm_client_public_mkenums_h) + EXTRA_DIST += \ - shared/nm-glib-aux/tests/meson.build \ - shared/README.md \ + src/libnm-client-test/meson.build \ $(NULL) ############################################################################### -check_programs += shared/nm-glib-aux/tests/test-shared-general +EXTRA_DIST += \ + src/libnm-glib-aux/tests/meson.build \ + $(NULL) -shared_nm_glib_aux_tests_test_shared_general_CPPFLAGS = \ +check_programs += src/libnm-glib-aux/tests/test-shared-general + +src_libnm_glib_aux_tests_test_shared_general_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -DG_LOG_DOMAIN=\""test"\" \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -shared_nm_glib_aux_tests_test_shared_general_LDFLAGS = \ +src_libnm_glib_aux_tests_test_shared_general_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -shared_nm_glib_aux_tests_test_shared_general_LDADD = \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/systemd/libnm-systemd-logging-stub.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ +src_libnm_glib_aux_tests_test_shared_general_LDADD = \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(NULL) @@ -727,29 +880,29 @@ shared_nm_glib_aux_tests_test_shared_general_LDADD = \ if WITH_JANSSON -check_programs += shared/nm-glib-aux/tests/test-json-aux +check_programs += src/libnm-glib-aux/tests/test-json-aux -shared_nm_glib_aux_tests_test_json_aux_CPPFLAGS = \ +src_libnm_glib_aux_tests_test_json_aux_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -DG_LOG_DOMAIN=\""test"\" \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(JANSSON_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -shared_nm_glib_aux_tests_test_json_aux_LDFLAGS = \ +src_libnm_glib_aux_tests_test_json_aux_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -shared_nm_glib_aux_tests_test_json_aux_LDADD = \ +src_libnm_glib_aux_tests_test_json_aux_LDADD = \ $(JANSSON_LIBS) \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/systemd/libnm-systemd-logging-stub.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(NULL) @@ -988,8 +1141,8 @@ dbusinterfaces_DATA = \ CLEANFILES += $(introspection_sources) CLEANFILES += $(DBUS_INTERFACE_DOCS) -$(libnm_libnm_static_la_OBJECTS): $(introspection_sources) -$(libnm_libnm_la_OBJECTS): $(introspection_sources) +$(src_libnm_client_impl_libnm_client_impl_la_OBJECTS): $(introspection_sources) +$(src_libnm_client_impl_libnm_la_OBJECTS): $(introspection_sources) EXTRA_DIST += \ $(dbusinterfaces_DATA) \ @@ -1002,292 +1155,305 @@ check_local += check-docs ############################################################################### -libnm_core_lib_h_pub_real = \ - libnm-core/nm-connection.h \ - libnm-core/nm-core-types.h \ - libnm-core/nm-dbus-interface.h \ - libnm-core/nm-errors.h \ - libnm-core/nm-keyfile.h \ - libnm-core/nm-setting-6lowpan.h \ - libnm-core/nm-setting-8021x.h \ - libnm-core/nm-setting-adsl.h \ - libnm-core/nm-setting-bluetooth.h \ - libnm-core/nm-setting-bond.h \ - libnm-core/nm-setting-bridge-port.h \ - libnm-core/nm-setting-bridge.h \ - libnm-core/nm-setting-cdma.h \ - libnm-core/nm-setting-connection.h \ - libnm-core/nm-setting-dcb.h \ - libnm-core/nm-setting-dummy.h \ - libnm-core/nm-setting-ethtool.h \ - libnm-core/nm-setting-generic.h \ - libnm-core/nm-setting-gsm.h \ - libnm-core/nm-setting-hostname.h \ - libnm-core/nm-setting-infiniband.h \ - libnm-core/nm-setting-ip-config.h \ - libnm-core/nm-setting-ip-tunnel.h \ - libnm-core/nm-setting-ip4-config.h \ - libnm-core/nm-setting-ip6-config.h \ - libnm-core/nm-setting-macsec.h \ - libnm-core/nm-setting-macvlan.h \ - libnm-core/nm-setting-match.h \ - libnm-core/nm-setting-olpc-mesh.h \ - libnm-core/nm-setting-ovs-bridge.h \ - libnm-core/nm-setting-ovs-dpdk.h \ - libnm-core/nm-setting-ovs-external-ids.h \ - libnm-core/nm-setting-ovs-interface.h \ - libnm-core/nm-setting-ovs-patch.h \ - libnm-core/nm-setting-ovs-port.h \ - libnm-core/nm-setting-ppp.h \ - libnm-core/nm-setting-pppoe.h \ - libnm-core/nm-setting-proxy.h \ - libnm-core/nm-setting-serial.h \ - libnm-core/nm-setting-sriov.h \ - libnm-core/nm-setting-tc-config.h \ - libnm-core/nm-setting-team-port.h \ - libnm-core/nm-setting-team.h \ - libnm-core/nm-setting-tun.h \ - libnm-core/nm-setting-user.h \ - libnm-core/nm-setting-veth.h \ - libnm-core/nm-setting-vlan.h \ - libnm-core/nm-setting-vpn.h \ - libnm-core/nm-setting-vrf.h \ - libnm-core/nm-setting-vxlan.h \ - libnm-core/nm-setting-wifi-p2p.h \ - libnm-core/nm-setting-wimax.h \ - libnm-core/nm-setting-wired.h \ - libnm-core/nm-setting-wireguard.h \ - libnm-core/nm-setting-wireless-security.h \ - libnm-core/nm-setting-wireless.h \ - libnm-core/nm-setting-wpan.h \ - libnm-core/nm-setting.h \ - libnm-core/nm-simple-connection.h \ - libnm-core/nm-utils.h \ - libnm-core/nm-version-macros.h \ - libnm-core/nm-version.h \ - libnm-core/nm-vpn-dbus-interface.h \ - libnm-core/nm-vpn-editor-plugin.h \ - libnm-core/nm-vpn-plugin-info.h \ - $(NULL) -libnm_core_lib_h_pub_mkenums = \ - libnm-core/nm-core-enum-types.h \ - $(NULL) -libnm_core_lib_h_priv = \ - libnm-core/nm-connection-private.h \ - libnm-core/nm-core-internal.h \ - libnm-core/nm-core-types-internal.h \ - libnm-core/nm-crypto-impl.h \ - libnm-core/nm-crypto.h \ - libnm-core/nm-default-libnm-core.h \ - libnm-core/nm-keyfile-internal.h \ - libnm-core/nm-keyfile-utils.h \ - libnm-core/nm-meta-setting-base-impl.h \ - libnm-core/nm-meta-setting-base.h \ - libnm-core/nm-property-compare.h \ - libnm-core/nm-setting-private.h \ - libnm-core/nm-team-utils.h \ - libnm-core/nm-utils-private.h \ - $(NULL) -libnm_core_lib_c_settings_real = \ - libnm-core/nm-setting-6lowpan.c \ - libnm-core/nm-setting-8021x.c \ - libnm-core/nm-setting-adsl.c \ - libnm-core/nm-setting-bluetooth.c \ - libnm-core/nm-setting-bond.c \ - libnm-core/nm-setting-bridge-port.c \ - libnm-core/nm-setting-bridge.c \ - libnm-core/nm-setting-cdma.c \ - libnm-core/nm-setting-connection.c \ - libnm-core/nm-setting-dcb.c \ - libnm-core/nm-setting-dummy.c \ - libnm-core/nm-setting-ethtool.c \ - libnm-core/nm-setting-generic.c \ - libnm-core/nm-setting-gsm.c \ - libnm-core/nm-setting-hostname.c \ - libnm-core/nm-setting-infiniband.c \ - libnm-core/nm-setting-ip-config.c \ - libnm-core/nm-setting-ip-tunnel.c \ - libnm-core/nm-setting-ip4-config.c \ - libnm-core/nm-setting-ip6-config.c \ - libnm-core/nm-setting-macsec.c \ - libnm-core/nm-setting-macvlan.c \ - libnm-core/nm-setting-match.c \ - libnm-core/nm-setting-olpc-mesh.c \ - libnm-core/nm-setting-ovs-bridge.c \ - libnm-core/nm-setting-ovs-dpdk.c \ - libnm-core/nm-setting-ovs-external-ids.c \ - libnm-core/nm-setting-ovs-interface.c \ - libnm-core/nm-setting-ovs-patch.c \ - libnm-core/nm-setting-ovs-port.c \ - libnm-core/nm-setting-ppp.c \ - libnm-core/nm-setting-pppoe.c \ - libnm-core/nm-setting-proxy.c \ - libnm-core/nm-setting-serial.c \ - libnm-core/nm-setting-sriov.c \ - libnm-core/nm-setting-tc-config.c \ - libnm-core/nm-setting-team-port.c \ - libnm-core/nm-setting-team.c \ - libnm-core/nm-setting-tun.c \ - libnm-core/nm-setting-user.c \ - libnm-core/nm-setting-veth.c \ - libnm-core/nm-setting-vlan.c \ - libnm-core/nm-setting-vpn.c \ - libnm-core/nm-setting-vrf.c \ - libnm-core/nm-setting-vxlan.c \ - libnm-core/nm-setting-wifi-p2p.c \ - libnm-core/nm-setting-wimax.c \ - libnm-core/nm-setting-wired.c \ - libnm-core/nm-setting-wireguard.c \ - libnm-core/nm-setting-wireless-security.c \ - libnm-core/nm-setting-wireless.c \ - libnm-core/nm-setting-wpan.c \ - $(NULL) -libnm_core_lib_c_real = \ - $(libnm_core_lib_c_settings_real) \ - libnm-core/nm-connection.c \ - libnm-core/nm-crypto.c \ - libnm-core/nm-dbus-utils.c \ - libnm-core/nm-errors.c \ - libnm-core/nm-keyfile-utils.c \ - libnm-core/nm-keyfile.c \ - libnm-core/nm-meta-setting-base-impl.c \ - libnm-core/nm-property-compare.c \ - libnm-core/nm-setting.c \ - libnm-core/nm-simple-connection.c \ - libnm-core/nm-team-utils.c \ - libnm-core/nm-utils.c \ - libnm-core/nm-vpn-editor-plugin.c \ - libnm-core/nm-vpn-plugin-info.c \ - $(NULL) - -libnm_core_lib_c_mkenums = \ - libnm-core/nm-core-enum-types.c +src_libnm_core_impl_lib_h_pub_real = \ + src/libnm-core-public/nm-connection.h \ + src/libnm-core-public/nm-core-types.h \ + src/libnm-core-public/nm-dbus-interface.h \ + src/libnm-core-public/nm-errors.h \ + src/libnm-core-public/nm-keyfile.h \ + src/libnm-core-public/nm-setting-6lowpan.h \ + src/libnm-core-public/nm-setting-8021x.h \ + src/libnm-core-public/nm-setting-adsl.h \ + src/libnm-core-public/nm-setting-bluetooth.h \ + src/libnm-core-public/nm-setting-bond.h \ + src/libnm-core-public/nm-setting-bridge-port.h \ + src/libnm-core-public/nm-setting-bridge.h \ + src/libnm-core-public/nm-setting-cdma.h \ + src/libnm-core-public/nm-setting-connection.h \ + src/libnm-core-public/nm-setting-dcb.h \ + src/libnm-core-public/nm-setting-dummy.h \ + src/libnm-core-public/nm-setting-ethtool.h \ + src/libnm-core-public/nm-setting-generic.h \ + src/libnm-core-public/nm-setting-gsm.h \ + src/libnm-core-public/nm-setting-hostname.h \ + src/libnm-core-public/nm-setting-infiniband.h \ + src/libnm-core-public/nm-setting-ip-config.h \ + src/libnm-core-public/nm-setting-ip-tunnel.h \ + src/libnm-core-public/nm-setting-ip4-config.h \ + src/libnm-core-public/nm-setting-ip6-config.h \ + src/libnm-core-public/nm-setting-macsec.h \ + src/libnm-core-public/nm-setting-macvlan.h \ + src/libnm-core-public/nm-setting-match.h \ + src/libnm-core-public/nm-setting-olpc-mesh.h \ + src/libnm-core-public/nm-setting-ovs-bridge.h \ + src/libnm-core-public/nm-setting-ovs-dpdk.h \ + src/libnm-core-public/nm-setting-ovs-external-ids.h \ + src/libnm-core-public/nm-setting-ovs-interface.h \ + src/libnm-core-public/nm-setting-ovs-patch.h \ + src/libnm-core-public/nm-setting-ovs-port.h \ + src/libnm-core-public/nm-setting-ppp.h \ + src/libnm-core-public/nm-setting-pppoe.h \ + src/libnm-core-public/nm-setting-proxy.h \ + src/libnm-core-public/nm-setting-serial.h \ + src/libnm-core-public/nm-setting-sriov.h \ + src/libnm-core-public/nm-setting-tc-config.h \ + src/libnm-core-public/nm-setting-team-port.h \ + src/libnm-core-public/nm-setting-team.h \ + src/libnm-core-public/nm-setting-tun.h \ + src/libnm-core-public/nm-setting-user.h \ + src/libnm-core-public/nm-setting-veth.h \ + src/libnm-core-public/nm-setting-vlan.h \ + src/libnm-core-public/nm-setting-vpn.h \ + src/libnm-core-public/nm-setting-vrf.h \ + src/libnm-core-public/nm-setting-vxlan.h \ + src/libnm-core-public/nm-setting-wifi-p2p.h \ + src/libnm-core-public/nm-setting-wimax.h \ + src/libnm-core-public/nm-setting-wired.h \ + src/libnm-core-public/nm-setting-wireguard.h \ + src/libnm-core-public/nm-setting-wireless-security.h \ + src/libnm-core-public/nm-setting-wireless.h \ + src/libnm-core-public/nm-setting-wpan.h \ + src/libnm-core-public/nm-setting.h \ + src/libnm-core-public/nm-simple-connection.h \ + src/libnm-core-public/nm-utils.h \ + src/libnm-core-public/nm-version-macros.h \ + src/libnm-core-public/nm-version.h \ + src/libnm-core-public/nm-vpn-dbus-interface.h \ + src/libnm-core-public/nm-vpn-editor-plugin.h \ + src/libnm-core-public/nm-vpn-plugin-info.h \ + $(NULL) +src_libnm_core_public_mkenums_h = \ + src/libnm-core-public/nm-core-enum-types.h \ + $(NULL) +src_libnm_core_impl_lib_h_priv = \ + src/libnm-core-impl/nm-connection-private.h \ + src/libnm-core-impl/nm-crypto-impl.h \ + src/libnm-core-impl/nm-crypto.h \ + src/libnm-core-impl/nm-default-libnm-core.h \ + src/libnm-core-impl/nm-property-compare.h \ + src/libnm-core-impl/nm-setting-private.h \ + src/libnm-core-impl/nm-team-utils.h \ + src/libnm-core-impl/nm-utils-private.h \ + src/libnm-core-intern/nm-core-internal.h \ + src/libnm-core-intern/nm-keyfile-internal.h \ + src/libnm-core-intern/nm-keyfile-utils.h \ + src/libnm-core-intern/nm-meta-setting-base-impl.h \ + src/libnm-core-intern/nm-meta-setting-base.h \ + $(NULL) +src_libnm_core_impl_lib_c_settings_real = \ + src/libnm-core-impl/nm-setting-6lowpan.c \ + src/libnm-core-impl/nm-setting-8021x.c \ + src/libnm-core-impl/nm-setting-adsl.c \ + src/libnm-core-impl/nm-setting-bluetooth.c \ + src/libnm-core-impl/nm-setting-bond.c \ + src/libnm-core-impl/nm-setting-bridge-port.c \ + src/libnm-core-impl/nm-setting-bridge.c \ + src/libnm-core-impl/nm-setting-cdma.c \ + src/libnm-core-impl/nm-setting-connection.c \ + src/libnm-core-impl/nm-setting-dcb.c \ + src/libnm-core-impl/nm-setting-dummy.c \ + src/libnm-core-impl/nm-setting-ethtool.c \ + src/libnm-core-impl/nm-setting-generic.c \ + src/libnm-core-impl/nm-setting-gsm.c \ + src/libnm-core-impl/nm-setting-hostname.c \ + src/libnm-core-impl/nm-setting-infiniband.c \ + src/libnm-core-impl/nm-setting-ip-config.c \ + src/libnm-core-impl/nm-setting-ip-tunnel.c \ + src/libnm-core-impl/nm-setting-ip4-config.c \ + src/libnm-core-impl/nm-setting-ip6-config.c \ + src/libnm-core-impl/nm-setting-macsec.c \ + src/libnm-core-impl/nm-setting-macvlan.c \ + src/libnm-core-impl/nm-setting-match.c \ + src/libnm-core-impl/nm-setting-olpc-mesh.c \ + src/libnm-core-impl/nm-setting-ovs-bridge.c \ + src/libnm-core-impl/nm-setting-ovs-dpdk.c \ + src/libnm-core-impl/nm-setting-ovs-external-ids.c \ + src/libnm-core-impl/nm-setting-ovs-interface.c \ + src/libnm-core-impl/nm-setting-ovs-patch.c \ + src/libnm-core-impl/nm-setting-ovs-port.c \ + src/libnm-core-impl/nm-setting-ppp.c \ + src/libnm-core-impl/nm-setting-pppoe.c \ + src/libnm-core-impl/nm-setting-proxy.c \ + src/libnm-core-impl/nm-setting-serial.c \ + src/libnm-core-impl/nm-setting-sriov.c \ + src/libnm-core-impl/nm-setting-tc-config.c \ + src/libnm-core-impl/nm-setting-team-port.c \ + src/libnm-core-impl/nm-setting-team.c \ + src/libnm-core-impl/nm-setting-tun.c \ + src/libnm-core-impl/nm-setting-user.c \ + src/libnm-core-impl/nm-setting-veth.c \ + src/libnm-core-impl/nm-setting-vlan.c \ + src/libnm-core-impl/nm-setting-vpn.c \ + src/libnm-core-impl/nm-setting-vrf.c \ + src/libnm-core-impl/nm-setting-vxlan.c \ + src/libnm-core-impl/nm-setting-wifi-p2p.c \ + src/libnm-core-impl/nm-setting-wimax.c \ + src/libnm-core-impl/nm-setting-wired.c \ + src/libnm-core-impl/nm-setting-wireguard.c \ + src/libnm-core-impl/nm-setting-wireless-security.c \ + src/libnm-core-impl/nm-setting-wireless.c \ + src/libnm-core-impl/nm-setting-wpan.c \ + $(NULL) +src_libnm_core_impl_lib_c_real = \ + $(src_libnm_core_impl_lib_c_settings_real) \ + src/libnm-core-impl/nm-connection.c \ + src/libnm-core-impl/nm-crypto.c \ + src/libnm-core-impl/nm-dbus-utils.c \ + src/libnm-core-impl/nm-errors.c \ + src/libnm-core-impl/nm-keyfile-utils.c \ + src/libnm-core-impl/nm-keyfile.c \ + src/libnm-core-impl/nm-meta-setting-base-impl.c \ + src/libnm-core-impl/nm-property-compare.c \ + src/libnm-core-impl/nm-setting.c \ + src/libnm-core-impl/nm-simple-connection.c \ + src/libnm-core-impl/nm-team-utils.c \ + src/libnm-core-impl/nm-utils.c \ + src/libnm-core-impl/nm-vpn-editor-plugin.c \ + src/libnm-core-impl/nm-vpn-plugin-info.c \ + $(NULL) + +src_libnm_core_public_mkenums_c = \ + src/libnm-core-public/nm-core-enum-types.c \ + $(NULL) libnminclude_HEADERS += \ - $(libnm_core_lib_h_pub_real) + $(src_libnm_core_impl_lib_h_pub_real) nodist_libnminclude_HEADERS += \ - $(libnm_core_lib_h_pub_mkenums) + $(src_libnm_core_public_mkenums_h) + +EXTRA_DIST += \ + src/libnm-core-impl/README.md \ + src/libnm-core-impl/meson.build \ + src/libnm-core-intern/README.md \ + src/libnm-core-intern/meson.build \ + src/libnm-core-public/README.md \ + src/libnm-core-public/meson.build \ + $(NULL) ############################################################################### dflt_cppflags_libnm_core = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(LIBUDEV_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -noinst_LTLIBRARIES += libnm-core/libnm-core.la +noinst_LTLIBRARIES += src/libnm-core-impl/libnm-core-impl.la + +src/libnm-client-public/nm-enum-types.h.stamp: src/libnm-client-public/.dirstamp +src/libnm-client-public/nm-enum-types.c.stamp: src/libnm-client-public/.dirstamp GLIB_GENERATED += \ - $(libnm_core_lib_h_pub_mkenums) \ - $(libnm_core_lib_c_mkenums) -nm_core_enum_types_sources = $(libnm_core_lib_h_pub_real) - -nm_core_enum_types_MKENUMS_C_FLAGS = --identifier-prefix NM --fhead '\#include "libnm-core/nm-default-libnm-core.h"\n' - -libnm-core/nm-core-enum-types.h.stamp: libnm-core/.dirstamp -libnm-core/nm-core-enum-types.c.stamp: libnm-core/.dirstamp - -$(dispatcher_libnm_dispatcher_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(dispatcher_nm_dispatcher_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_libnm_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_libnm_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_tests_libnm_vpn_plugin_utils_test_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_NetworkManager_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_adsl_libnm_device_plugin_adsl_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_team_libnm_device_plugin_team_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_wifi_libnm_device_plugin_wifi_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_wwan_libnm_device_plugin_wwan_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_ovs_libnm_device_plugin_ovs_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -libnm_core_libnm_core_la_CPPFLAGS = \ + $(src_libnm_core_public_mkenums_h) \ + $(src_libnm_core_public_mkenums_c) \ + $(NULL) +nm_core_enum_types_sources = $(src_libnm_core_impl_lib_h_pub_real) + +nm_core_enum_types_MKENUMS_C_FLAGS = --fhead '\#undef G_LOG_DOMAIN\n\#include "src/libnm-core-impl/nm-default-libnm-core.h"\n' + +src/libnm-core-public/nm-core-enum-types.h.stamp: src/libnm-core-public/.dirstamp +src/libnm-core-public/nm-core-enum-types.c.stamp: src/libnm-core-public/.dirstamp + +$(src_nm_dispatcher_libnm_dispatcher_core_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_dispatcher_nm_dispatcher_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_libnm_core_impl_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_client_impl_libnm_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_contrib_tests_libnm_vpn_plugin_utils_test_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_NetworkManager_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_adsl_libnm_device_plugin_adsl_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_team_libnm_device_plugin_team_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_wifi_libnm_device_plugin_wifi_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_wwan_libnm_device_plugin_wwan_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_ovs_libnm_device_plugin_ovs_la_OBJECTS): $(src_libnm_core_public_mkenums_h) + +src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS = \ $(dflt_cppflags_libnm_core) \ - -DG_LOG_DOMAIN=\""libnm"\" \ + -I$(srcdir)/src/libnm-core-intern/ \ $(NULL) -libnm_core_libnm_core_la_SOURCES = \ - $(libnm_core_lib_h_pub_real) \ - $(libnm_core_lib_h_priv) \ - $(libnm_core_lib_c_real) +src_libnm_core_impl_libnm_core_impl_la_SOURCES = \ + $(src_libnm_core_impl_lib_h_pub_real) \ + $(src_libnm_core_impl_lib_h_priv) \ + $(src_libnm_core_impl_lib_c_real) -nodist_libnm_core_libnm_core_la_SOURCES = \ - $(libnm_core_lib_h_pub_mkenums) \ - $(libnm_core_lib_c_mkenums) +nodist_src_libnm_core_impl_libnm_core_impl_la_SOURCES = \ + $(src_libnm_core_public_mkenums_h) \ + $(src_libnm_core_public_mkenums_c) \ + $(NULL) -libnm_core_libnm_core_la_LIBADD = \ +src_libnm_core_impl_libnm_core_impl_la_LIBADD = \ $(GLIB_LIBS) \ $(UUID_LIBS) \ $(NULL) -libnm_core_libnm_core_la_LDFLAGS = \ +src_libnm_core_impl_libnm_core_impl_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) EXTRA_DIST += \ - libnm-core/nm-crypto-gnutls.c \ - libnm-core/nm-crypto-nss.c \ - libnm-core/meson.build \ + src/libnm-core-impl/nm-crypto-gnutls.c \ + src/libnm-core-impl/nm-crypto-nss.c \ + src/libnm-core-impl/meson.build \ $(NULL) -libnm-core/nm-vpn-dbus-types.xml: libnm-core/nm-vpn-dbus-interface.h tools/enums-to-docbook.pl - @$(MKDIR_P) libnm-core/ +src/libnm-core-public/nm-vpn-dbus-types.xml: src/libnm-core-public/nm-vpn-dbus-interface.h tools/enums-to-docbook.pl + @$(MKDIR_P) src/libnm-core-public/ $(AM_V_GEN) @PERL@ $(srcdir)/tools/enums-to-docbook.pl 'nm-vpn-dbus-types' 'VPN Plugin D-Bus API Types' $< >$@ -libnm-core/nm-dbus-types.xml: libnm-core/nm-dbus-interface.h tools/enums-to-docbook.pl - @$(MKDIR_P) libnm-core/ +src/libnm-core-public/nm-dbus-types.xml: src/libnm-core-public/nm-dbus-interface.h tools/enums-to-docbook.pl + @$(MKDIR_P) src/libnm-core-public/ $(AM_V_GEN) @PERL@ $(srcdir)/tools/enums-to-docbook.pl 'nm-dbus-types' 'NetworkManager D-Bus API Types' $< >$@ BUILT_SOURCES += \ - libnm-core/nm-vpn-dbus-types.xml \ - libnm-core/nm-dbus-types.xml + src/libnm-core-public/nm-vpn-dbus-types.xml \ + src/libnm-core-public/nm-dbus-types.xml dist_dependencies += \ - libnm-core/nm-vpn-dbus-types.xml \ - libnm-core/nm-dbus-types.xml + src/libnm-core-public/nm-vpn-dbus-types.xml \ + src/libnm-core-public/nm-dbus-types.xml ############################################################################### if HAVE_CRYPTO_GNUTLS if WITH_GNUTLS -libnm_crypto_lib = libnm-core/libnm-crypto-gnutls.la +libnm_crypto_lib = src/libnm-core-impl/libnm-crypto-gnutls.la else -check_ltlibraries += libnm-core/libnm-crypto-gnutls.la +check_ltlibraries += src/libnm-core-impl/libnm-crypto-gnutls.la endif -libnm_core_libnm_crypto_gnutls_la_SOURCES = libnm-core/nm-crypto-gnutls.c -libnm_core_libnm_crypto_gnutls_la_CPPFLAGS = \ - $(libnm_core_libnm_core_la_CPPFLAGS) \ +src_libnm_core_impl_libnm_crypto_gnutls_la_SOURCES = src/libnm-core-impl/nm-crypto-gnutls.c +src_libnm_core_impl_libnm_crypto_gnutls_la_CPPFLAGS = \ + $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) \ $(GNUTLS_CFLAGS) -libnm_core_libnm_crypto_gnutls_la_LDFLAGS = \ - $(libnm_core_libnm_core_la_LDFLAGS) -libnm_core_libnm_crypto_gnutls_la_LIBADD = \ +src_libnm_core_impl_libnm_crypto_gnutls_la_LDFLAGS = \ + $(src_libnm_core_impl_libnm_core_impl_la_LDFLAGS) +src_libnm_core_impl_libnm_crypto_gnutls_la_LIBADD = \ $(GLIB_LIBS) \ $(GNUTLS_LIBS) endif if HAVE_CRYPTO_NSS if WITH_NSS -libnm_crypto_lib = libnm-core/libnm-crypto-nss.la +libnm_crypto_lib = src/libnm-core-impl/libnm-crypto-nss.la else -check_ltlibraries += libnm-core/libnm-crypto-nss.la +check_ltlibraries += src/libnm-core-impl/libnm-crypto-nss.la endif -libnm_core_libnm_crypto_nss_la_SOURCES = libnm-core/nm-crypto-nss.c -libnm_core_libnm_crypto_nss_la_CPPFLAGS = \ - $(libnm_core_libnm_core_la_CPPFLAGS) \ +src_libnm_core_impl_libnm_crypto_nss_la_SOURCES = src/libnm-core-impl/nm-crypto-nss.c +src_libnm_core_impl_libnm_crypto_nss_la_CPPFLAGS = \ + $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) \ $(NSS_CFLAGS) -libnm_core_libnm_crypto_nss_la_LDFLAGS = \ - $(libnm_core_libnm_core_la_LDFLAGS) -libnm_core_libnm_crypto_nss_la_LIBADD = \ +src_libnm_core_impl_libnm_crypto_nss_la_LDFLAGS = \ + $(src_libnm_core_impl_libnm_core_impl_la_LDFLAGS) +src_libnm_core_impl_libnm_crypto_nss_la_LIBADD = \ $(GLIB_LIBS) \ $(NSS_LIBS) endif @@ -1297,92 +1463,94 @@ noinst_LTLIBRARIES += $(libnm_crypto_lib) ############################################################################### check_programs += \ - libnm-core/tests/test-compare \ - libnm-core/tests/test-crypto \ - libnm-core/tests/test-general \ - libnm-core/tests/test-keyfile \ - libnm-core/tests/test-secrets \ - libnm-core/tests/test-setting \ - libnm-core/tests/test-settings-defaults + src/libnm-core-impl/tests/test-compare \ + src/libnm-core-impl/tests/test-crypto \ + src/libnm-core-impl/tests/test-general \ + src/libnm-core-impl/tests/test-keyfile \ + src/libnm-core-impl/tests/test-secrets \ + src/libnm-core-impl/tests/test-setting \ + src/libnm-core-impl/tests/test-settings-defaults GLIB_GENERATED += \ - libnm-core/tests/nm-core-tests-enum-types.h \ - libnm-core/tests/nm-core-tests-enum-types.c -nm_core_tests_enum_types_sources = libnm-core/tests/test-general-enums.h -nm_core_tests_enum_types_MKENUMS_C_FLAGS = --fhead '\#include "libnm-core/nm-default-libnm-core.h"\n' - -libnm-core/tests/nm-core-tests-enum-types.h.stamp: libnm-core/tests/.dirstamp -libnm-core/tests/nm-core-tests-enum-types.c.stamp: libnm-core/tests/.dirstamp - -$(libnm_core_tests_test_general_OBJECTS): libnm-core/tests/nm-core-tests-enum-types.h - -libnm_core_tests_cppflags = \ - -I$(srcdir)/libnm-core/tests \ - -I$(builddir)/libnm-core/tests \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.h \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.c +nm_core_tests_enum_types_sources = src/libnm-core-impl/tests/test-general-enums.h +nm_core_tests_enum_types_MKENUMS_C_FLAGS = --fhead '\#undef G_LOG_DOMAIN\n\#include "src/libnm-core-impl/nm-default-libnm-core.h"\n' + +src/libnm-core-impl/tests/nm-core-tests-enum-types.h.stamp: src/libnm-core-impl/tests/.dirstamp +src/libnm-core-impl/tests/nm-core-tests-enum-types.c.stamp: src/libnm-core-impl/tests/.dirstamp + +$(src_libnm_core_impl_tests_test_general_OBJECTS): src/libnm-core-impl/tests/nm-core-tests-enum-types.h + +src_libnm_core_impl_tests_cppflags = \ + -I$(builddir)/src/libnm-core-impl/tests \ + -I$(srcdir)/src/libnm-core-impl/tests \ + -I$(srcdir)/src/libnm-core-impl \ + -I$(srcdir)/src/ \ + -I$(builddir)/src/ \ $(dflt_cppflags_libnm_core) \ - -DG_LOG_DOMAIN=\""test"\" \ $(SANITIZER_EXEC_CFLAGS) \ $(NULL) -libnm_core_tests_test_compare_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_crypto_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_general_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_keyfile_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_secrets_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_setting_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_settings_defaults_CPPFLAGS = $(libnm_core_tests_cppflags) +src_libnm_core_impl_tests_test_compare_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_crypto_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_general_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_keyfile_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_secrets_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_setting_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_settings_defaults_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) -libnm_core_tests_test_general_SOURCES = \ - libnm-core/tests/test-general-enums.h \ - libnm-core/tests/test-general.c \ +src_libnm_core_impl_tests_test_general_SOURCES = \ + src/libnm-core-impl/tests/test-general-enums.h \ + src/libnm-core-impl/tests/test-general.c \ $(NULL) -nodist_libnm_core_tests_test_general_SOURCES = \ - libnm-core/tests/nm-core-tests-enum-types.c \ - libnm-core/tests/nm-core-tests-enum-types.h \ +nodist_src_libnm_core_impl_tests_test_general_SOURCES = \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.c \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.h \ $(NULL) -libnm_core_tests_ldadd = \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la \ +src_libnm_core_impl_tests_ldadd = \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la \ $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/systemd/libnm-systemd-logging-stub.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(NULL) -libnm_core_tests_ldflags = \ +src_libnm_core_impl_tests_ldflags = \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -libnm_core_tests_test_compare_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_crypto_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_general_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_keyfile_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_secrets_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_setting_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_settings_defaults_LDADD = $(libnm_core_tests_ldadd) - -libnm_core_tests_test_compare_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_crypto_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_general_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_keyfile_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_secrets_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_setting_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_settings_defaults_LDFLAGS = $(libnm_core_tests_ldflags) - -$(libnm_core_tests_test_compare_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_crypto_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_general_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_keyfile_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_secrets_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_setting_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_settings_defaults_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +src_libnm_core_impl_tests_test_compare_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_crypto_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_general_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_keyfile_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_secrets_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_setting_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_settings_defaults_LDADD = $(src_libnm_core_impl_tests_ldadd) + +src_libnm_core_impl_tests_test_compare_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_crypto_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_general_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_keyfile_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_secrets_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_setting_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_settings_defaults_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) + +$(src_libnm_core_impl_tests_test_compare_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_crypto_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_general_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_keyfile_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_secrets_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_setting_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_settings_defaults_OBJECTS): $(src_libnm_core_public_mkenums_h) # test-cert.p12 created with: # @@ -1394,344 +1562,350 @@ $(libnm_core_tests_test_settings_defaults_OBJECTS): $(libnm_core_lib_h_pub_mkenu # -out test-cert.p12 EXTRA_DIST += \ - libnm-core/tests/certs/ca-no-ending-newline.pem \ - libnm-core/tests/certs/pkcs8-decrypted.der \ - libnm-core/tests/certs/pkcs8-enc-key.pem \ - libnm-core/tests/certs/pkcs8-noenc-key.pem \ - libnm-core/tests/certs/test2_ca_cert.pem \ - libnm-core/tests/certs/test2-cert.p12 \ - libnm-core/tests/certs/test2_key_and_cert.pem \ - libnm-core/tests/certs/test-aes-128-key.pem \ - libnm-core/tests/certs/test-aes-256-key.pem \ - libnm-core/tests/certs/test_ca_cert.der \ - libnm-core/tests/certs/test_ca_cert.pem \ - libnm-core/tests/certs/test-ca-cert.pem \ - libnm-core/tests/certs/test-cert.p12 \ - libnm-core/tests/certs/test_key_and_cert.pem \ - libnm-core/tests/certs/test-key-and-cert.pem \ - libnm-core/tests/certs/test-key-only-decrypted.der \ - libnm-core/tests/certs/test-key-only-decrypted.pem \ - libnm-core/tests/certs/test-key-only.pem \ - libnm-core/tests/certs/test-tpm2wrapped-key.pem \ - libnm-core/tests/nm-core-tests-enum-types.c.template \ - libnm-core/tests/nm-core-tests-enum-types.h.template \ - libnm-core/tests/meson.build + src/libnm-core-impl/tests/certs/ca-no-ending-newline.pem \ + src/libnm-core-impl/tests/certs/pkcs8-decrypted.der \ + src/libnm-core-impl/tests/certs/pkcs8-enc-key.pem \ + src/libnm-core-impl/tests/certs/pkcs8-noenc-key.pem \ + src/libnm-core-impl/tests/certs/test2_ca_cert.pem \ + src/libnm-core-impl/tests/certs/test2-cert.p12 \ + src/libnm-core-impl/tests/certs/test2_key_and_cert.pem \ + src/libnm-core-impl/tests/certs/test-aes-128-key.pem \ + src/libnm-core-impl/tests/certs/test-aes-256-key.pem \ + src/libnm-core-impl/tests/certs/test_ca_cert.der \ + src/libnm-core-impl/tests/certs/test_ca_cert.pem \ + src/libnm-core-impl/tests/certs/test-ca-cert.pem \ + src/libnm-core-impl/tests/certs/test-cert.p12 \ + src/libnm-core-impl/tests/certs/test_key_and_cert.pem \ + src/libnm-core-impl/tests/certs/test-key-and-cert.pem \ + src/libnm-core-impl/tests/certs/test-key-only-decrypted.der \ + src/libnm-core-impl/tests/certs/test-key-only-decrypted.pem \ + src/libnm-core-impl/tests/certs/test-key-only.pem \ + src/libnm-core-impl/tests/certs/test-tpm2wrapped-key.pem \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.c.template \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.h.template \ + src/libnm-core-impl/tests/meson.build ############################################################################### libnm_lib_h_pub_real = \ - libnm/NetworkManager.h \ - libnm/nm-access-point.h \ - libnm/nm-active-connection.h \ - libnm/nm-autoptr.h \ - libnm/nm-checkpoint.h \ - libnm/nm-client.h \ - libnm/nm-device-6lowpan.h \ - libnm/nm-device-adsl.h \ - libnm/nm-device-bond.h \ - libnm/nm-device-bridge.h \ - libnm/nm-device-bt.h \ - libnm/nm-device-dummy.h \ - libnm/nm-device-ethernet.h \ - libnm/nm-device-generic.h \ - libnm/nm-device-infiniband.h \ - libnm/nm-device-ip-tunnel.h \ - libnm/nm-device-macsec.h \ - libnm/nm-device-macvlan.h \ - libnm/nm-device-modem.h \ - libnm/nm-device-olpc-mesh.h \ - libnm/nm-device-ovs-bridge.h \ - libnm/nm-device-ovs-interface.h \ - libnm/nm-device-ovs-port.h \ - libnm/nm-device-ppp.h \ - libnm/nm-device-team.h \ - libnm/nm-device-tun.h \ - libnm/nm-device-veth.h \ - libnm/nm-device-vlan.h \ - libnm/nm-device-vrf.h \ - libnm/nm-device-vxlan.h \ - libnm/nm-device-wifi-p2p.h \ - libnm/nm-device-wifi.h \ - libnm/nm-device-wimax.h \ - libnm/nm-device-wireguard.h \ - libnm/nm-device-wpan.h \ - libnm/nm-device.h \ - libnm/nm-dhcp-config.h \ - libnm/nm-ethtool-utils.h \ - libnm/nm-ip-config.h \ - libnm/nm-object.h \ - libnm/nm-remote-connection.h \ - libnm/nm-secret-agent-old.h \ - libnm/nm-types.h \ - libnm/nm-vpn-connection.h \ - libnm/nm-vpn-editor.h \ - libnm/nm-vpn-plugin-old.h \ - libnm/nm-vpn-service-plugin.h \ - libnm/nm-wifi-p2p-peer.h \ - libnm/nm-wimax-nsp.h -libnm_lib_h_pub_mkenums = \ - libnm/nm-enum-types.h + src/libnm-client-public/NetworkManager.h \ + src/libnm-client-public/nm-access-point.h \ + src/libnm-client-public/nm-active-connection.h \ + src/libnm-client-public/nm-autoptr.h \ + src/libnm-client-public/nm-checkpoint.h \ + src/libnm-client-public/nm-client.h \ + src/libnm-client-public/nm-device-6lowpan.h \ + src/libnm-client-public/nm-device-adsl.h \ + src/libnm-client-public/nm-device-bond.h \ + src/libnm-client-public/nm-device-bridge.h \ + src/libnm-client-public/nm-device-bt.h \ + src/libnm-client-public/nm-device-dummy.h \ + src/libnm-client-public/nm-device-ethernet.h \ + src/libnm-client-public/nm-device-generic.h \ + src/libnm-client-public/nm-device-infiniband.h \ + src/libnm-client-public/nm-device-ip-tunnel.h \ + src/libnm-client-public/nm-device-macsec.h \ + src/libnm-client-public/nm-device-macvlan.h \ + src/libnm-client-public/nm-device-modem.h \ + src/libnm-client-public/nm-device-olpc-mesh.h \ + src/libnm-client-public/nm-device-ovs-bridge.h \ + src/libnm-client-public/nm-device-ovs-interface.h \ + src/libnm-client-public/nm-device-ovs-port.h \ + src/libnm-client-public/nm-device-ppp.h \ + src/libnm-client-public/nm-device-team.h \ + src/libnm-client-public/nm-device-tun.h \ + src/libnm-client-public/nm-device-veth.h \ + src/libnm-client-public/nm-device-vlan.h \ + src/libnm-client-public/nm-device-vrf.h \ + src/libnm-client-public/nm-device-vxlan.h \ + src/libnm-client-public/nm-device-wifi-p2p.h \ + src/libnm-client-public/nm-device-wifi.h \ + src/libnm-client-public/nm-device-wimax.h \ + src/libnm-client-public/nm-device-wireguard.h \ + src/libnm-client-public/nm-device-wpan.h \ + src/libnm-client-public/nm-device.h \ + src/libnm-client-public/nm-dhcp-config.h \ + src/libnm-client-public/nm-ethtool-utils.h \ + src/libnm-client-public/nm-ip-config.h \ + src/libnm-client-public/nm-object.h \ + src/libnm-client-public/nm-remote-connection.h \ + src/libnm-client-public/nm-secret-agent-old.h \ + src/libnm-client-public/nm-types.h \ + src/libnm-client-public/nm-vpn-connection.h \ + src/libnm-client-public/nm-vpn-editor.h \ + src/libnm-client-public/nm-vpn-plugin-old.h \ + src/libnm-client-public/nm-vpn-service-plugin.h \ + src/libnm-client-public/nm-wifi-p2p-peer.h \ + src/libnm-client-public/nm-wimax-nsp.h \ + $(NULL) +src_libnm_client_public_mkenums_h = \ + src/libnm-client-public/nm-enum-types.h \ + $(NULL) libnm_lib_h_priv = \ - libnm/nm-dbus-helpers.h \ - libnm/nm-default-client.h \ - libnm/nm-default-libnm.h \ - libnm/nm-device-private.h \ - libnm/nm-dhcp4-config.h \ - libnm/nm-dhcp6-config.h \ - libnm/nm-dns-manager.h \ - libnm/nm-ip4-config.h \ - libnm/nm-ip6-config.h \ - libnm/nm-libnm-utils.h \ - libnm/nm-object-private.h \ - libnm/nm-remote-connection-private.h \ + src/libnm-client-impl/nm-dbus-helpers.h \ + src/libnm-client-aux-extern/nm-default-client.h \ + src/libnm-client-impl/nm-default-libnm.h \ + src/libnm-client-impl/nm-device-private.h \ + src/libnm-client-impl/nm-dhcp4-config.h \ + src/libnm-client-impl/nm-dhcp6-config.h \ + src/libnm-client-impl/nm-dns-manager.h \ + src/libnm-client-impl/nm-ip4-config.h \ + src/libnm-client-impl/nm-ip6-config.h \ + src/libnm-client-impl/nm-libnm-utils.h \ + src/libnm-client-impl/nm-object-private.h \ + src/libnm-client-impl/nm-remote-connection-private.h \ $(NULL) libnm_lib_c_real = \ - libnm/nm-client.c \ - libnm/nm-object.c \ - libnm/nm-device.c \ - libnm/nm-active-connection.c \ + src/libnm-client-impl/nm-client.c \ + src/libnm-client-impl/nm-object.c \ + src/libnm-client-impl/nm-device.c \ + src/libnm-client-impl/nm-active-connection.c \ \ - libnm/nm-access-point.c \ - libnm/nm-checkpoint.c \ - libnm/nm-dbus-helpers.c \ - libnm/nm-device-6lowpan.c \ - libnm/nm-device-adsl.c \ - libnm/nm-device-bond.c \ - libnm/nm-device-bridge.c \ - libnm/nm-device-bt.c \ - libnm/nm-device-dummy.c \ - libnm/nm-device-ethernet.c \ - libnm/nm-device-generic.c \ - libnm/nm-device-infiniband.c \ - libnm/nm-device-ip-tunnel.c \ - libnm/nm-device-macsec.c \ - libnm/nm-device-macvlan.c \ - libnm/nm-device-modem.c \ - libnm/nm-device-olpc-mesh.c \ - libnm/nm-device-ovs-bridge.c \ - libnm/nm-device-ovs-interface.c \ - libnm/nm-device-ovs-port.c \ - libnm/nm-device-ppp.c \ - libnm/nm-device-team.c \ - libnm/nm-device-tun.c \ - libnm/nm-device-veth.c \ - libnm/nm-device-vlan.c \ - libnm/nm-device-vrf.c \ - libnm/nm-device-vxlan.c \ - libnm/nm-device-wifi-p2p.c \ - libnm/nm-device-wifi.c \ - libnm/nm-device-wimax.c \ - libnm/nm-device-wireguard.c \ - libnm/nm-device-wpan.c \ - libnm/nm-dhcp-config.c \ - libnm/nm-dhcp4-config.c \ - libnm/nm-dhcp6-config.c \ - libnm/nm-dns-manager.c \ - libnm/nm-ip-config.c \ - libnm/nm-ip4-config.c \ - libnm/nm-ip6-config.c \ - libnm/nm-libnm-utils.c \ - libnm/nm-remote-connection.c \ - libnm/nm-secret-agent-old.c \ - libnm/nm-vpn-connection.c \ - libnm/nm-vpn-editor.c \ - libnm/nm-vpn-plugin-old.c \ - libnm/nm-vpn-service-plugin.c \ - libnm/nm-wifi-p2p-peer.c \ - libnm/nm-wimax-nsp.c \ - $(NULL) -libnm_lib_c_mkenums = \ - libnm/nm-enum-types.c - -libnm_lib_cppflags = \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ - $(dflt_cppflags_libnm_core) \ - -DG_LOG_DOMAIN=\""libnm"\" \ + src/libnm-client-impl/nm-access-point.c \ + src/libnm-client-impl/nm-checkpoint.c \ + src/libnm-client-impl/nm-dbus-helpers.c \ + src/libnm-client-impl/nm-device-6lowpan.c \ + src/libnm-client-impl/nm-device-adsl.c \ + src/libnm-client-impl/nm-device-bond.c \ + src/libnm-client-impl/nm-device-bridge.c \ + src/libnm-client-impl/nm-device-bt.c \ + src/libnm-client-impl/nm-device-dummy.c \ + src/libnm-client-impl/nm-device-ethernet.c \ + src/libnm-client-impl/nm-device-generic.c \ + src/libnm-client-impl/nm-device-infiniband.c \ + src/libnm-client-impl/nm-device-ip-tunnel.c \ + src/libnm-client-impl/nm-device-macsec.c \ + src/libnm-client-impl/nm-device-macvlan.c \ + src/libnm-client-impl/nm-device-modem.c \ + src/libnm-client-impl/nm-device-olpc-mesh.c \ + src/libnm-client-impl/nm-device-ovs-bridge.c \ + src/libnm-client-impl/nm-device-ovs-interface.c \ + src/libnm-client-impl/nm-device-ovs-port.c \ + src/libnm-client-impl/nm-device-ppp.c \ + src/libnm-client-impl/nm-device-team.c \ + src/libnm-client-impl/nm-device-tun.c \ + src/libnm-client-impl/nm-device-veth.c \ + src/libnm-client-impl/nm-device-vlan.c \ + src/libnm-client-impl/nm-device-vrf.c \ + src/libnm-client-impl/nm-device-vxlan.c \ + src/libnm-client-impl/nm-device-wifi-p2p.c \ + src/libnm-client-impl/nm-device-wifi.c \ + src/libnm-client-impl/nm-device-wimax.c \ + src/libnm-client-impl/nm-device-wireguard.c \ + src/libnm-client-impl/nm-device-wpan.c \ + src/libnm-client-impl/nm-dhcp-config.c \ + src/libnm-client-impl/nm-dhcp4-config.c \ + src/libnm-client-impl/nm-dhcp6-config.c \ + src/libnm-client-impl/nm-dns-manager.c \ + src/libnm-client-impl/nm-ip-config.c \ + src/libnm-client-impl/nm-ip4-config.c \ + src/libnm-client-impl/nm-ip6-config.c \ + src/libnm-client-impl/nm-libnm-utils.c \ + src/libnm-client-impl/nm-remote-connection.c \ + src/libnm-client-impl/nm-secret-agent-old.c \ + src/libnm-client-impl/nm-vpn-connection.c \ + src/libnm-client-impl/nm-vpn-editor.c \ + src/libnm-client-impl/nm-vpn-plugin-old.c \ + src/libnm-client-impl/nm-vpn-service-plugin.c \ + src/libnm-client-impl/nm-wifi-p2p-peer.c \ + src/libnm-client-impl/nm-wimax-nsp.c \ + $(NULL) +src_libnm_client_public_mkenums_c = \ + src/libnm-client-public/nm-enum-types.c \ $(NULL) libnminclude_HEADERS += \ $(libnm_lib_h_pub_real) nodist_libnminclude_HEADERS += \ - $(libnm_lib_h_pub_mkenums) + $(src_libnm_client_public_mkenums_h) ############################################################################### -noinst_LTLIBRARIES += libnm/libnm_static.la +noinst_LTLIBRARIES += src/libnm-client-impl/libnm-client-impl.la -libnm_libnm_static_la_CPPFLAGS = \ +src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS = \ + -I$(builddir)/src/libnm-client-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(srcdir)/src \ + $(dflt_cppflags_libnm_core) \ $(INTROSPECTION_CFLAGS) \ - $(libnm_lib_cppflags) \ $(NULL) -libnm_libnm_static_la_SOURCES = \ +src_libnm_client_impl_libnm_client_impl_la_SOURCES = \ $(libnm_lib_c_real) \ $(NULL) -nodist_libnm_libnm_static_la_SOURCES = \ - $(libnm_lib_h_pub_mkenums) \ - $(libnm_lib_c_mkenums) \ +nodist_src_libnm_client_impl_libnm_client_impl_la_SOURCES = \ + $(src_libnm_client_public_mkenums_h) \ + $(src_libnm_client_public_mkenums_c) \ $(NULL) -libnm_libnm_static_la_LIBADD = \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la \ +src_libnm_client_impl_libnm_client_impl_la_LIBADD = \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la \ $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ introspection/libnmdbus.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/systemd/libnm-systemd-logging-stub.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(DL_LIBS) \ $(UUID_LIBS) \ $(LIBUDEV_LIBS) \ $(NULL) -$(libnm_libnm_static_la_OBJECTS) : $(libnm_lib_h_pub_mkenums) -$(libnm_libnm_static_la_OBJECTS) : $(libnm_core_lib_h_pub_mkenums) +$(src_libnm_client_impl_libnm_client_impl_la_OBJECTS) : $(src_libnm_client_public_mkenums_h) +$(src_libnm_client_impl_libnm_client_impl_la_OBJECTS) : $(src_libnm_core_public_mkenums_h) ############################################################################### -lib_LTLIBRARIES += libnm/libnm.la +lib_LTLIBRARIES += src/libnm-client-impl/libnm.la GLIB_GENERATED += \ - $(libnm_lib_h_pub_mkenums) \ - $(libnm_lib_c_mkenums) + $(src_libnm_client_public_mkenums_h) \ + $(src_libnm_client_public_mkenums_c) nm_enum_types_sources = \ - $(libnm_lib_h_pub_mkenums) \ + $(src_libnm_client_public_mkenums_h) \ $(libnm_lib_h_pub_real) -nm_enum_types_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include "nm-core-enum-types.h"\n' -nm_enum_types_MKENUMS_C_FLAGS = --identifier-prefix NM --fhead '\#include "libnm/nm-default-libnm.h"\n' - -$(dispatcher_nm_dispatcher_OBJECTS): $(libnm_lib_h_pub_mkenums) -$(dispatcher_libnm_dispatcher_core_la_OBJECTS): $(libnm_lib_h_pub_mkenums) -$(libnm_libnm_la_OBJECTS): $(libnm_lib_h_pub_mkenums) -$(libnm_tests_libnm_vpn_plugin_utils_test_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -libnm_libnm_la_CPPFLAGS = \ - $(libnm_lib_cppflags) \ +nm_enum_types_MKENUMS_H_FLAGS = --fhead '\#include "nm-core-enum-types.h"\n' +nm_enum_types_MKENUMS_C_FLAGS = --fhead '\#undef G_LOG_DOMAIN\n\#include "libnm-client-impl/nm-default-libnm.h"\n' + +$(src_nm_dispatcher_nm_dispatcher_OBJECTS): $(src_libnm_client_public_mkenums_h) +$(src_nm_dispatcher_libnm_dispatcher_core_la_OBJECTS): $(src_libnm_client_public_mkenums_h) +$(src_libnm_client_impl_libnm_la_OBJECTS): $(src_libnm_client_public_mkenums_h) +$(src_contrib_tests_libnm_vpn_plugin_utils_test_la_OBJECTS): $(src_libnm_client_public_mkenums_h) + +src_libnm_client_impl_libnm_la_CPPFLAGS = \ + -I$(builddir)/src/libnm-client-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(srcdir)/src \ + $(dflt_cppflags_libnm_core) \ $(LIBUDEV_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -libnm_libnm_la_SOURCES = \ +src_libnm_client_impl_libnm_la_SOURCES = \ $(libnm_lib_h_pub_real) \ $(libnm_lib_h_priv) \ $(NULL) -EXTRA_libnm_libnm_la_DEPENDENCIES = \ - libnm/libnm.ver +EXTRA_src_libnm_client_impl_libnm_la_DEPENDENCIES = \ + src/libnm-client-impl/libnm.ver -libnm_libnm_la_LIBADD = \ - libnm/libnm_static.la \ +src_libnm_client_impl_libnm_la_LIBADD = \ + src/libnm-client-impl/libnm-client-impl.la \ $(NULL) -libnm_libnm_la_LDFLAGS = \ - -Wl,--version-script="$(srcdir)/libnm/libnm.ver" \ +src_libnm_client_impl_libnm_la_LDFLAGS = \ + -Wl,--version-script="$(srcdir)/src/libnm-client-impl/libnm.ver" \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ -version-info "1:0:1" -check-local-exports-libnm: libnm/libnm.la - $(srcdir)/tools/check-exports.sh "$(builddir)/libnm/.libs/libnm.so" "$(srcdir)/libnm/libnm.ver" +check-local-exports-libnm: src/libnm-client-impl/libnm.la + $(srcdir)/tools/check-exports.sh "$(builddir)/src/libnm-client-impl/.libs/libnm.so" "$(srcdir)/src/libnm-client-impl/libnm.ver" check_local += check-local-exports-libnm -pkgconfig_DATA += libnm/libnm.pc +pkgconfig_DATA += src/libnm-client-impl/libnm.pc DISTCLEANFILES += \ - libnm/libnm.pc + src/libnm-client-impl/libnm.pc EXTRA_DIST += \ - libnm/nm-enum-types.c.template \ - libnm/nm-enum-types.h.template \ + src/libnm-client-public/nm-enum-types.c.template \ + src/libnm-client-public/nm-enum-types.h.template \ \ - libnm/libnm.pc.in \ - libnm/libnm.ver + src/libnm-client-impl/libnm.pc.in \ + src/libnm-client-impl/libnm.ver -libnm_NM_1_0_typelib = +src_libnm_client_impl_NM_1_0_typelib = if HAVE_INTROSPECTION -libnm_NM_1_0_typelib += libnm/NM-1.0.typelib - -libnm/NM-1.0.gir: libnm/libnm.la -libnm_NM_1_0_gir_INCLUDES = Gio-2.0 -libnm_NM_1_0_gir_PACKAGES = gio-2.0 -libnm_NM_1_0_gir_EXPORT_PACKAGES = libnm -libnm_NM_1_0_gir_CFLAGS = \ - $(libnm_libnm_la_CPPFLAGS) \ +src_libnm_client_impl_NM_1_0_typelib += src/libnm-client-impl/NM-1.0.typelib + +src/libnm-client-impl/NM-1.0.gir: src/libnm-client-impl/libnm.la +src_libnm_client_impl_NM_1_0_gir_INCLUDES = Gio-2.0 +src_libnm_client_impl_NM_1_0_gir_PACKAGES = gio-2.0 +src_libnm_client_impl_NM_1_0_gir_EXPORT_PACKAGES = libnm +src_libnm_client_impl_NM_1_0_gir_CFLAGS = \ + $(src_libnm_client_impl_libnm_la_CPPFLAGS) \ -DNETWORKMANAGER_COMPILATION \ $(NULL) -libnm_NM_1_0_gir_LIBS = libnm/libnm.la -libnm_NM_1_0_gir_FILES = \ - $(libnm_core_lib_h_pub_mkenums) \ - $(libnm_core_lib_h_pub_real) \ - $(libnm_core_lib_c_mkenums) \ - $(libnm_core_lib_c_real) \ - $(libnm_lib_h_pub_mkenums) \ +src_libnm_client_impl_NM_1_0_gir_LIBS = src/libnm-client-impl/libnm.la +src_libnm_client_impl_NM_1_0_gir_FILES = \ + $(src_libnm_core_public_mkenums_h) \ + $(src_libnm_core_impl_lib_h_pub_real) \ + $(src_libnm_core_public_mkenums_c) \ + $(src_libnm_core_impl_lib_c_real) \ + $(src_libnm_client_public_mkenums_h) \ $(libnm_lib_h_pub_real) \ - $(libnm_lib_c_mkenums) \ + $(src_libnm_client_public_mkenums_c) \ $(libnm_lib_c_real) -libnm_NM_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm +src_libnm_client_impl_NM_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm -libnm/libnm.typelib: libnm/libnm.gir - $(INTROSPECTION_COMPILER) --includedir=$(srcdir)/libnm-core --includedir=$(builddir)/libnm-core --includedir=$(srcdir)/libnm --includedir=$(builddir)/libnm $< -o $@ +src/libnm-client-impl/libnm.typelib: src/libnm-client-impl/libnm.gir + $(INTROSPECTION_COMPILER) --includedir=$(srcdir)/src/libnm-core-public --includedir=$(builddir)/src/libnm-core-public --includedir=$(srcdir)/libnm-client-public --includedir=$(builddir)/libnm-client-public $< -o $@ -INTROSPECTION_GIRS += libnm/NM-1.0.gir +INTROSPECTION_GIRS += src/libnm-client-impl/NM-1.0.gir libnm_noinst_data = \ - clients/cli/generate-docs-nm-settings-nmcli.xml \ - libnm/nm-property-infos-dbus.xml \ - libnm/nm-property-infos-ifcfg-rh.xml \ - libnm/nm-property-infos-keyfile.xml \ - libnm/nm-property-infos-nmcli.xml \ - libnm/nm-settings-docs-gir.xml \ + src/nmcli/generate-docs-nm-settings-nmcli.xml \ man/nm-settings-docs-dbus.xml \ man/nm-settings-docs-nmcli.xml \ + src/libnm-client-impl/nm-property-infos-dbus.xml \ + src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml \ + src/libnm-client-impl/nm-property-infos-keyfile.xml \ + src/libnm-client-impl/nm-property-infos-nmcli.xml \ + src/libnm-client-impl/nm-settings-docs-gir.xml \ + src/libnmc-setting/settings-docs-input.xml \ $(NULL) noinst_DATA += $(libnm_noinst_data) -EXTRA_DIST += clients/cli/generate-docs-nm-settings-nmcli.xml.in +EXTRA_DIST += src/nmcli/generate-docs-nm-settings-nmcli.xml.in if BUILD_DOCS -clients/cli/generate-docs-nm-settings-nmcli.xml: clients/cli/generate-docs-nm-settings-nmcli - $(AM_V_GEN) clients/cli/generate-docs-nm-settings-nmcli > "$@" -check-local-generate-docs-nm-settings-nmcli: clients/cli/generate-docs-nm-settings-nmcli.xml +src/nmcli/generate-docs-nm-settings-nmcli.xml: src/nmcli/generate-docs-nm-settings-nmcli + $(AM_V_GEN) src/nmcli/generate-docs-nm-settings-nmcli > "$@" +check-local-generate-docs-nm-settings-nmcli: src/nmcli/generate-docs-nm-settings-nmcli.xml $(srcdir)/tools/check-compare-generated.sh "$(srcdir)" "$(builddir)" "$<" check_local += check-local-generate-docs-nm-settings-nmcli -DISTCLEANFILES += clients/cli/generate-docs-nm-settings-nmcli.xml +DISTCLEANFILES += src/nmcli/generate-docs-nm-settings-nmcli.xml else -clients/cli/generate-docs-nm-settings-nmcli.xml: clients/cli/generate-docs-nm-settings-nmcli.xml.in +src/nmcli/generate-docs-nm-settings-nmcli.xml: src/nmcli/generate-docs-nm-settings-nmcli.xml.in $(AM_V_GEN) cp $^ $@ check-local-generate-docs-nm-settings-nmcli: endif -libnm_docs_sources = $(libnm_core_lib_c_settings_real) +libnm_docs_sources = $(src_libnm_core_impl_lib_c_settings_real) -libnm/nm-property-infos-%.xml: tools/generate-docs-nm-property-infos.pl $(libnm_docs_sources) +src/libnm-client-impl/nm-property-infos-%.xml: tools/generate-docs-nm-property-infos.pl $(libnm_docs_sources) $(AM_V_GEN) $(srcdir)/tools/generate-docs-nm-property-infos.pl $(patsubst nm-property-infos-%.xml,%,$(notdir $@)) $@ $(filter-out $<,$^) -libnm/nm-settings-docs-gir.xml: tools/generate-docs-nm-settings-docs-gir.py libnm/NM-1.0.gir libnm/NM-1.0.typelib libnm/libnm.la $(libnm_docs_sources) +src/libnm-client-impl/nm-settings-docs-gir.xml: tools/generate-docs-nm-settings-docs-gir.py src/libnm-client-impl/NM-1.0.gir src/libnm-client-impl/NM-1.0.typelib src/libnm-client-impl/libnm.la $(libnm_docs_sources) $(AM_V_GEN) \ - export GI_TYPELIB_PATH=$(abs_builddir)/libnm$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \ - export LD_LIBRARY_PATH=$(abs_builddir)/libnm/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \ - $(call set_sanitizer_env,$(abs_builddir)/libnm/.libs/libnm.so); \ + export GI_TYPELIB_PATH=$(abs_builddir)/src/libnm-client-impl$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \ + export LD_LIBRARY_PATH=$(abs_builddir)/src/libnm-client-impl/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \ + $(call set_sanitizer_env,$(abs_builddir)/src/libnm-client-impl/.libs/libnm.so); \ "$(PYTHON)" \ $(srcdir)/tools/generate-docs-nm-settings-docs-gir.py \ - --gir $(builddir)/libnm/NM-1.0.gir \ + --gir $(builddir)/src/libnm-client-impl/NM-1.0.gir \ --output $@ -man/nm-settings-docs-nmcli.xml: clients/cli/generate-docs-nm-settings-nmcli.xml libnm/nm-property-infos-nmcli.xml libnm/nm-settings-docs-gir.xml tools/generate-docs-nm-settings-docs-merge.py man/common.ent +man/nm-settings-docs-nmcli.xml: src/nmcli/generate-docs-nm-settings-nmcli.xml src/libnm-client-impl/nm-property-infos-nmcli.xml src/libnm-client-impl/nm-settings-docs-gir.xml tools/generate-docs-nm-settings-docs-merge.py man/common.ent $(AM_V_GEN) "$(PYTHON)" $(srcdir)/tools/generate-docs-nm-settings-docs-merge.py --only-from-first $@ $(wordlist 1,3,$^) -man/nm-settings-docs-%.xml: libnm/nm-property-infos-%.xml libnm/nm-settings-docs-gir.xml tools/generate-docs-nm-settings-docs-merge.py man/common.ent +src/libnmc-setting/settings-docs-input.xml: src/libnm-client-impl/nm-property-infos-nmcli.xml src/libnm-client-impl/nm-settings-docs-gir.xml tools/generate-docs-nm-settings-docs-merge.py + $(AM_V_GEN) "$(PYTHON)" $(srcdir)/tools/generate-docs-nm-settings-docs-merge.py $@ $(wordlist 1,2,$^) + +man/nm-settings-docs-%.xml: src/libnm-client-impl/nm-property-infos-%.xml src/libnm-client-impl/nm-settings-docs-gir.xml tools/generate-docs-nm-settings-docs-merge.py man/common.ent $(AM_V_GEN) "$(PYTHON)" $(srcdir)/tools/generate-docs-nm-settings-docs-merge.py $@ $(wordlist 1,2,$^) EXTRA_DIST += $(libnm_noinst_data) @@ -1743,116 +1917,106 @@ EXTRA_DIST += \ tools/generate-docs-nm-property-infos.pl \ tools/generate-docs-nm-settings-docs-merge.py \ tools/generate-docs-nm-settings-docs-gir.py \ - libnm/meson.build \ + src/libnm-client-impl/meson.build \ $(NULL) ############################################################################### -check_programs += libnm/tests/test-libnm +check_programs += src/libnm-client-impl/tests/test-libnm -libnm_tests_programs_req_introspection = \ - libnm/tests/test-nm-client \ - libnm/tests/test-remote-settings-client \ - libnm/tests/test-secret-agent +src_libnm_client_impl_tests_programs_req_introspection = \ + src/libnm-client-impl/tests/test-nm-client \ + src/libnm-client-impl/tests/test-remote-settings-client \ + src/libnm-client-impl/tests/test-secret-agent if HAVE_INTROSPECTION -check_programs += $(libnm_tests_programs_req_introspection) +check_programs += $(src_libnm_client_impl_tests_programs_req_introspection) else -check_programs_norun += $(libnm_tests_programs_req_introspection) +check_programs_norun += $(src_libnm_client_impl_tests_programs_req_introspection) endif -libnm_tests_cppflags = \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ +src_libnm_client_impl_tests_cppflags = \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(dflt_cppflags_libnm_core) \ - -DG_LOG_DOMAIN=\""test"\" \ $(SANITIZER_EXEC_CFLAGS) \ $(NULL) -libnm_tests_ldadd = \ - libnm/libnm_static.la \ +src_libnm_client_impl_tests_ldadd = \ + src/libnm-client-test/libnm-client-test.la \ + src/libnm-client-impl/libnm-client-impl.la \ $(GLIB_LIBS) \ $(NULL) -libnm_tests_ldflags = \ +src_libnm_client_impl_tests_ldflags = \ $(SANITIZER_EXEC_LDFLAGS) -libnm_tests_test_libnm_CPPFLAGS = $(libnm_tests_cppflags) -libnm_tests_test_nm_client_CPPFLAGS = $(libnm_tests_cppflags) -libnm_tests_test_remote_settings_client_CPPFLAGS = $(libnm_tests_cppflags) -libnm_tests_test_secret_agent_CPPFLAGS = $(libnm_tests_cppflags) +src_libnm_client_impl_tests_test_libnm_CPPFLAGS = $(src_libnm_client_impl_tests_cppflags) +src_libnm_client_impl_tests_test_nm_client_CPPFLAGS = $(src_libnm_client_impl_tests_cppflags) +src_libnm_client_impl_tests_test_remote_settings_client_CPPFLAGS = $(src_libnm_client_impl_tests_cppflags) +src_libnm_client_impl_tests_test_secret_agent_CPPFLAGS = $(src_libnm_client_impl_tests_cppflags) -libnm_tests_test_libnm_SOURCES = \ - shared/nm-utils/nm-compat.c \ - libnm/tests/test-libnm.c \ +src_libnm_client_impl_tests_test_libnm_SOURCES = \ + src/contrib/nm-compat.c \ + src/contrib/nm-compat.h \ + src/libnm-client-impl/tests/test-libnm.c \ $(NULL) -libnm_tests_test_nm_client_SOURCES = \ - shared/nm-test-utils-impl.c \ - shared/nm-test-libnm-utils.h \ - libnm/tests/test-nm-client.c - -libnm_tests_test_remote_settings_client_SOURCES = \ - shared/nm-test-utils-impl.c \ - shared/nm-test-libnm-utils.h \ - libnm/tests/test-remote-settings-client.c - -libnm_tests_test_secret_agent_SOURCES = \ - shared/nm-test-utils-impl.c \ - shared/nm-test-libnm-utils.h \ - libnm/tests/test-secret-agent.c +src_libnm_client_impl_tests_test_libnm_LDADD = $(src_libnm_client_impl_tests_ldadd) +src_libnm_client_impl_tests_test_nm_client_LDADD = $(src_libnm_client_impl_tests_ldadd) +src_libnm_client_impl_tests_test_remote_settings_client_LDADD = $(src_libnm_client_impl_tests_ldadd) +src_libnm_client_impl_tests_test_secret_agent_LDADD = $(src_libnm_client_impl_tests_ldadd) -libnm_tests_test_libnm_LDADD = $(libnm_tests_ldadd) -libnm_tests_test_nm_client_LDADD = $(libnm_tests_ldadd) -libnm_tests_test_remote_settings_client_LDADD = $(libnm_tests_ldadd) -libnm_tests_test_secret_agent_LDADD = $(libnm_tests_ldadd) +src_libnm_client_impl_tests_test_libnm_LDFLAGS = $(src_libnm_client_impl_tests_ldflags) +src_libnm_client_impl_tests_test_nm_client_LDFLAGS = $(src_libnm_client_impl_tests_ldflags) +src_libnm_client_impl_tests_test_remote_settings_client_LDFLAGS = $(src_libnm_client_impl_tests_ldflags) +src_libnm_client_impl_tests_test_secret_agent_LDFLAGS = $(src_libnm_client_impl_tests_ldflags) -libnm_tests_test_libnm_LDFLAGS = $(libnm_tests_ldflags) -libnm_tests_test_nm_client_LDFLAGS = $(libnm_tests_ldflags) -libnm_tests_test_remote_settings_client_LDFLAGS = $(libnm_tests_ldflags) -libnm_tests_test_secret_agent_LDFLAGS = $(libnm_tests_ldflags) - -$(libnm_tests_test_libnm_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_tests_test_nm_client_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_tests_test_remote_settings_client_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_tests_test_secret_agent_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_libnm_client_impl_tests_test_libnm_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(src_libnm_client_impl_tests_test_nm_client_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(src_libnm_client_impl_tests_test_remote_settings_client_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(src_libnm_client_impl_tests_test_secret_agent_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) # tools/test-networkmanager-service.py uses libnm's typelib. Ensure it # is built first. -$(libnm_tests_test_nm_client_OBJECTS): $(libnm_NM_1_0_typelib) -$(libnm_tests_test_remote_settings_client_OBJECTS): $(libnm_NM_1_0_typelib) -$(libnm_tests_test_secret_agent_OBJECTS): $(libnm_NM_1_0_typelib) +$(src_libnm_client_impl_tests_test_nm_client_OBJECTS): $(src_libnm_client_impl_NM_1_0_typelib) +$(src_libnm_client_impl_tests_test_remote_settings_client_OBJECTS): $(src_libnm_client_impl_NM_1_0_typelib) +$(src_libnm_client_impl_tests_test_secret_agent_OBJECTS): $(src_libnm_client_impl_NM_1_0_typelib) + +EXTRA_DIST += \ + src/libnm-client-impl/tests/meson.build ############################################################################### # just test, that we can build "nm-vpn-plugin-utils.c" -check_ltlibraries += libnm/tests/libnm-vpn-plugin-utils-test.la +check_ltlibraries += src/contrib/tests/libnm-vpn-plugin-utils-test.la -libnm_tests_libnm_vpn_plugin_utils_test_la_SOURCES = \ - shared/nm-utils/nm-vpn-plugin-utils.c \ - shared/nm-utils/nm-vpn-plugin-utils.h \ +src_contrib_tests_libnm_vpn_plugin_utils_test_la_SOURCES = \ + src/contrib/nm-vpn-plugin-utils.c \ + src/contrib/nm-vpn-plugin-utils.h \ $(NULL) -libnm_tests_libnm_vpn_plugin_utils_test_la_CFLAGS = \ +src_contrib_tests_libnm_vpn_plugin_utils_test_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(GLIB_CFLAGS) \ $(SANITIZER_EXEC_CFLAGS) \ - -DG_LOG_DOMAIN=\""test"\" \ $(NULL) -libnm_tests_libnm_vpn_plugin_utils_test_la_LIBADD = \ +src_contrib_tests_libnm_vpn_plugin_utils_test_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) EXTRA_DIST += \ - libnm/tests/meson.build + src/contrib/meson.build \ + src/contrib/tests/meson.build \ + $(NULL) ############################################################################### # src/core/ @@ -1861,7 +2025,6 @@ EXTRA_DIST += \ src_core_cppflags_base = \ -I$(srcdir)/src/core \ $(dflt_cppflags_libnm_core) \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ $(SANITIZER_EXEC_CFLAGS) \ $(NULL) @@ -1916,171 +2079,154 @@ check_local += check-config-options libsystemd_cppflags = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/shared/systemd/ \ - -I$(srcdir)/shared/systemd/sd-adapt-shared \ - -I$(srcdir)/shared/systemd/src/basic \ - -I$(srcdir)/shared/systemd/src/shared \ + -I$(srcdir)/src/ \ + -I$(builddir)/src/ \ + -I$(srcdir)/src/libnm-systemd-shared/ \ + -I$(srcdir)/src/libnm-systemd-shared/sd-adapt-shared \ + -I$(srcdir)/src/libnm-systemd-shared/src/basic \ + -I$(srcdir)/src/libnm-systemd-shared/src/shared \ $(LIBSYSTEMD_NM_CFLAGS) \ $(GLIB_CFLAGS) \ $(CODE_COVERAGE_CFLAGS) \ $(NULL) -noinst_LTLIBRARIES += shared/systemd/libnm-systemd-logging-stub.la +noinst_LTLIBRARIES += src/libnm-systemd-shared/libnm-systemd-shared.la -shared_systemd_libnm_systemd_logging_stub_la_CPPFLAGS = \ +src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS = \ $(libsystemd_cppflags) \ - -DG_LOG_DOMAIN=\""libnm"\" \ - $(NULL) - -shared_systemd_libnm_systemd_logging_stub_la_SOURCES = \ - shared/systemd/nm-logging-stub.c \ $(NULL) -shared_systemd_libnm_systemd_logging_stub_la_LIBADD = \ - $(GLIB_LIBS) \ - $(CODE_COVERAGE_LDFLAGS) \ - $(NULL) - -noinst_LTLIBRARIES += shared/systemd/libnm-systemd-shared.la - -shared_systemd_libnm_systemd_shared_la_CPPFLAGS = \ - $(libsystemd_cppflags) \ - -DG_LOG_DOMAIN=\""libnm"\" \ - $(NULL) - -shared_systemd_libnm_systemd_shared_la_SOURCES = \ - shared/systemd/nm-default-systemd-shared.h \ - shared/systemd/nm-sd-utils-shared.c \ - shared/systemd/nm-sd-utils-shared.h \ - shared/systemd/sd-adapt-shared/architecture.h \ - shared/systemd/sd-adapt-shared/arphrd-list.h \ - shared/systemd/sd-adapt-shared/blockdev-util.h \ - shared/systemd/sd-adapt-shared/build.h \ - shared/systemd/sd-adapt-shared/copy.h \ - shared/systemd/sd-adapt-shared/def.h \ - shared/systemd/sd-adapt-shared/dhcp-server-internal.h \ - shared/systemd/sd-adapt-shared/dirent-util.h \ - shared/systemd/sd-adapt-shared/errno-list.h \ - shared/systemd/sd-adapt-shared/glob-util.h \ - shared/systemd/sd-adapt-shared/gunicode.h \ - shared/systemd/sd-adapt-shared/idn-util.h \ - shared/systemd/sd-adapt-shared/ioprio.h \ - shared/systemd/sd-adapt-shared/locale-util.h \ - shared/systemd/sd-adapt-shared/memfd-util.h \ - shared/systemd/sd-adapt-shared/missing_fs.h \ - shared/systemd/sd-adapt-shared/missing_keyctl.h \ - shared/systemd/sd-adapt-shared/missing_magic.h \ - shared/systemd/sd-adapt-shared/missing_network.h \ - shared/systemd/sd-adapt-shared/missing_sched.h \ - shared/systemd/sd-adapt-shared/missing_timerfd.h \ - shared/systemd/sd-adapt-shared/mkdir.h \ - shared/systemd/sd-adapt-shared/namespace-util.h \ - shared/systemd/sd-adapt-shared/nm-sd-adapt-shared.h \ - shared/systemd/sd-adapt-shared/nulstr-util.h \ - shared/systemd/sd-adapt-shared/raw-clone.h \ - shared/systemd/sd-adapt-shared/rlimit-util.h \ - shared/systemd/sd-adapt-shared/terminal-util.h \ - shared/systemd/sd-adapt-shared/unaligned.h \ - shared/systemd/sd-adapt-shared/user-util.h \ - shared/systemd/sd-adapt-shared/virt.h \ - shared/systemd/src/basic/alloc-util.c \ - shared/systemd/src/basic/alloc-util.h \ - shared/systemd/src/basic/async.h \ - shared/systemd/src/basic/cgroup-util.h \ - shared/systemd/src/basic/env-file.c \ - shared/systemd/src/basic/env-file.h \ - shared/systemd/src/basic/env-util.c \ - shared/systemd/src/basic/env-util.h \ - shared/systemd/src/basic/errno-util.h \ - shared/systemd/src/basic/escape.c \ - shared/systemd/src/basic/escape.h \ - shared/systemd/src/basic/ether-addr-util.c \ - shared/systemd/src/basic/ether-addr-util.h \ - shared/systemd/src/basic/extract-word.c \ - shared/systemd/src/basic/extract-word.h \ - shared/systemd/src/basic/fd-util.c \ - shared/systemd/src/basic/fd-util.h \ - shared/systemd/src/basic/fileio.c \ - shared/systemd/src/basic/fileio.h \ - shared/systemd/src/basic/format-util.c \ - shared/systemd/src/basic/format-util.h \ - shared/systemd/src/basic/fs-util.c \ - shared/systemd/src/basic/fs-util.h \ - shared/systemd/src/basic/hash-funcs.c \ - shared/systemd/src/basic/hash-funcs.h \ - shared/systemd/src/basic/hashmap.c \ - shared/systemd/src/basic/hashmap.h \ - shared/systemd/src/basic/hexdecoct.c \ - shared/systemd/src/basic/hexdecoct.h \ - shared/systemd/src/basic/hostname-util.c \ - shared/systemd/src/basic/hostname-util.h \ - shared/systemd/src/basic/in-addr-util.c \ - shared/systemd/src/basic/in-addr-util.h \ - shared/systemd/src/basic/io-util.c \ - shared/systemd/src/basic/io-util.h \ - shared/systemd/src/basic/list.h \ - shared/systemd/src/basic/log.h \ - shared/systemd/src/basic/macro.h \ - shared/systemd/src/basic/memory-util.c \ - shared/systemd/src/basic/memory-util.h \ - shared/systemd/src/basic/mempool.c \ - shared/systemd/src/basic/mempool.h \ - shared/systemd/src/basic/missing_fcntl.h \ - shared/systemd/src/basic/missing_random.h \ - shared/systemd/src/basic/missing_socket.h \ - shared/systemd/src/basic/missing_stat.h \ - shared/systemd/src/basic/missing_syscall.h \ - shared/systemd/src/basic/missing_type.h \ - shared/systemd/src/basic/parse-util.c \ - shared/systemd/src/basic/parse-util.h \ - shared/systemd/src/basic/path-util.c \ - shared/systemd/src/basic/path-util.h \ - shared/systemd/src/basic/prioq.c \ - shared/systemd/src/basic/prioq.h \ - shared/systemd/src/basic/process-util.c \ - shared/systemd/src/basic/process-util.h \ - shared/systemd/src/basic/random-util.c \ - shared/systemd/src/basic/random-util.h \ - shared/systemd/src/basic/ratelimit.c \ - shared/systemd/src/basic/ratelimit.h \ - shared/systemd/src/basic/set.h \ - shared/systemd/src/basic/signal-util.c \ - shared/systemd/src/basic/signal-util.h \ - shared/systemd/src/basic/siphash24.h \ - shared/systemd/src/basic/socket-util.c \ - shared/systemd/src/basic/socket-util.h \ - shared/systemd/src/basic/sort-util.h \ - shared/systemd/src/basic/sparse-endian.h \ - shared/systemd/src/basic/stat-util.c \ - shared/systemd/src/basic/stat-util.h \ - shared/systemd/src/basic/stdio-util.h \ - shared/systemd/src/basic/string-table.c \ - shared/systemd/src/basic/string-table.h \ - shared/systemd/src/basic/string-util.c \ - shared/systemd/src/basic/string-util.h \ - shared/systemd/src/basic/strv.c \ - shared/systemd/src/basic/strv.h \ - shared/systemd/src/basic/strxcpyx.c \ - shared/systemd/src/basic/strxcpyx.h \ - shared/systemd/src/basic/time-util.c \ - shared/systemd/src/basic/time-util.h \ - shared/systemd/src/basic/tmpfile-util.c \ - shared/systemd/src/basic/tmpfile-util.h \ - shared/systemd/src/basic/umask-util.h \ - shared/systemd/src/basic/utf8.c \ - shared/systemd/src/basic/utf8.h \ - shared/systemd/src/basic/util.c \ - shared/systemd/src/basic/util.h \ - shared/systemd/src/shared/dns-domain.c \ - shared/systemd/src/shared/dns-domain.h \ - shared/systemd/src/shared/log-link.h \ - shared/systemd/src/shared/web-util.c \ - shared/systemd/src/shared/web-util.h \ - $(NULL) - -shared_systemd_libnm_systemd_shared_la_LIBADD = \ +src_libnm_systemd_shared_libnm_systemd_shared_la_SOURCES = \ + src/libnm-systemd-shared/nm-default-systemd-shared.h \ + src/libnm-systemd-shared/nm-sd-utils-shared.c \ + src/libnm-systemd-shared/nm-sd-utils-shared.h \ + src/libnm-systemd-shared/sd-adapt-shared/architecture.h \ + src/libnm-systemd-shared/sd-adapt-shared/arphrd-list.h \ + src/libnm-systemd-shared/sd-adapt-shared/blockdev-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/build.h \ + src/libnm-systemd-shared/sd-adapt-shared/copy.h \ + src/libnm-systemd-shared/sd-adapt-shared/def.h \ + src/libnm-systemd-shared/sd-adapt-shared/dhcp-server-internal.h \ + src/libnm-systemd-shared/sd-adapt-shared/dirent-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/errno-list.h \ + src/libnm-systemd-shared/sd-adapt-shared/glob-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/gunicode.h \ + src/libnm-systemd-shared/sd-adapt-shared/idn-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/ioprio.h \ + src/libnm-systemd-shared/sd-adapt-shared/locale-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/memfd-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_fs.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_keyctl.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_magic.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_network.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_sched.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_timerfd.h \ + src/libnm-systemd-shared/sd-adapt-shared/mkdir.h \ + src/libnm-systemd-shared/sd-adapt-shared/namespace-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h \ + src/libnm-systemd-shared/sd-adapt-shared/nulstr-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/raw-clone.h \ + src/libnm-systemd-shared/sd-adapt-shared/rlimit-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/terminal-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/unaligned.h \ + src/libnm-systemd-shared/sd-adapt-shared/user-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/virt.h \ + src/libnm-systemd-shared/src/basic/alloc-util.c \ + src/libnm-systemd-shared/src/basic/alloc-util.h \ + src/libnm-systemd-shared/src/basic/async.h \ + src/libnm-systemd-shared/src/basic/cgroup-util.h \ + src/libnm-systemd-shared/src/basic/env-file.c \ + src/libnm-systemd-shared/src/basic/env-file.h \ + src/libnm-systemd-shared/src/basic/env-util.c \ + src/libnm-systemd-shared/src/basic/env-util.h \ + src/libnm-systemd-shared/src/basic/errno-util.h \ + src/libnm-systemd-shared/src/basic/escape.c \ + src/libnm-systemd-shared/src/basic/escape.h \ + src/libnm-systemd-shared/src/basic/ether-addr-util.c \ + src/libnm-systemd-shared/src/basic/ether-addr-util.h \ + src/libnm-systemd-shared/src/basic/extract-word.c \ + src/libnm-systemd-shared/src/basic/extract-word.h \ + src/libnm-systemd-shared/src/basic/fd-util.c \ + src/libnm-systemd-shared/src/basic/fd-util.h \ + src/libnm-systemd-shared/src/basic/fileio.c \ + src/libnm-systemd-shared/src/basic/fileio.h \ + src/libnm-systemd-shared/src/basic/format-util.c \ + src/libnm-systemd-shared/src/basic/format-util.h \ + src/libnm-systemd-shared/src/basic/fs-util.c \ + src/libnm-systemd-shared/src/basic/fs-util.h \ + src/libnm-systemd-shared/src/basic/hash-funcs.c \ + src/libnm-systemd-shared/src/basic/hash-funcs.h \ + src/libnm-systemd-shared/src/basic/hashmap.c \ + src/libnm-systemd-shared/src/basic/hashmap.h \ + src/libnm-systemd-shared/src/basic/hexdecoct.c \ + src/libnm-systemd-shared/src/basic/hexdecoct.h \ + src/libnm-systemd-shared/src/basic/hostname-util.c \ + src/libnm-systemd-shared/src/basic/hostname-util.h \ + src/libnm-systemd-shared/src/basic/in-addr-util.c \ + src/libnm-systemd-shared/src/basic/in-addr-util.h \ + src/libnm-systemd-shared/src/basic/io-util.c \ + src/libnm-systemd-shared/src/basic/io-util.h \ + src/libnm-systemd-shared/src/basic/list.h \ + src/libnm-systemd-shared/src/basic/log.h \ + src/libnm-systemd-shared/src/basic/macro.h \ + src/libnm-systemd-shared/src/basic/memory-util.c \ + src/libnm-systemd-shared/src/basic/memory-util.h \ + src/libnm-systemd-shared/src/basic/mempool.c \ + src/libnm-systemd-shared/src/basic/mempool.h \ + src/libnm-systemd-shared/src/basic/missing_fcntl.h \ + src/libnm-systemd-shared/src/basic/missing_random.h \ + src/libnm-systemd-shared/src/basic/missing_socket.h \ + src/libnm-systemd-shared/src/basic/missing_stat.h \ + src/libnm-systemd-shared/src/basic/missing_syscall.h \ + src/libnm-systemd-shared/src/basic/missing_type.h \ + src/libnm-systemd-shared/src/basic/parse-util.c \ + src/libnm-systemd-shared/src/basic/parse-util.h \ + src/libnm-systemd-shared/src/basic/path-util.c \ + src/libnm-systemd-shared/src/basic/path-util.h \ + src/libnm-systemd-shared/src/basic/prioq.c \ + src/libnm-systemd-shared/src/basic/prioq.h \ + src/libnm-systemd-shared/src/basic/process-util.c \ + src/libnm-systemd-shared/src/basic/process-util.h \ + src/libnm-systemd-shared/src/basic/random-util.c \ + src/libnm-systemd-shared/src/basic/random-util.h \ + src/libnm-systemd-shared/src/basic/ratelimit.c \ + src/libnm-systemd-shared/src/basic/ratelimit.h \ + src/libnm-systemd-shared/src/basic/set.h \ + src/libnm-systemd-shared/src/basic/signal-util.c \ + src/libnm-systemd-shared/src/basic/signal-util.h \ + src/libnm-systemd-shared/src/basic/siphash24.h \ + src/libnm-systemd-shared/src/basic/socket-util.c \ + src/libnm-systemd-shared/src/basic/socket-util.h \ + src/libnm-systemd-shared/src/basic/sort-util.h \ + src/libnm-systemd-shared/src/basic/sparse-endian.h \ + src/libnm-systemd-shared/src/basic/stat-util.c \ + src/libnm-systemd-shared/src/basic/stat-util.h \ + src/libnm-systemd-shared/src/basic/stdio-util.h \ + src/libnm-systemd-shared/src/basic/string-table.c \ + src/libnm-systemd-shared/src/basic/string-table.h \ + src/libnm-systemd-shared/src/basic/string-util.c \ + src/libnm-systemd-shared/src/basic/string-util.h \ + src/libnm-systemd-shared/src/basic/strv.c \ + src/libnm-systemd-shared/src/basic/strv.h \ + src/libnm-systemd-shared/src/basic/strxcpyx.c \ + src/libnm-systemd-shared/src/basic/strxcpyx.h \ + src/libnm-systemd-shared/src/basic/time-util.c \ + src/libnm-systemd-shared/src/basic/time-util.h \ + src/libnm-systemd-shared/src/basic/tmpfile-util.c \ + src/libnm-systemd-shared/src/basic/tmpfile-util.h \ + src/libnm-systemd-shared/src/basic/umask-util.h \ + src/libnm-systemd-shared/src/basic/utf8.c \ + src/libnm-systemd-shared/src/basic/utf8.h \ + src/libnm-systemd-shared/src/basic/util.c \ + src/libnm-systemd-shared/src/basic/util.h \ + src/libnm-systemd-shared/src/shared/dns-domain.c \ + src/libnm-systemd-shared/src/shared/dns-domain.h \ + src/libnm-systemd-shared/src/shared/log-link.h \ + src/libnm-systemd-shared/src/shared/web-util.c \ + src/libnm-systemd-shared/src/shared/web-util.h \ + $(NULL) + +src_libnm_systemd_shared_libnm_systemd_shared_la_LIBADD = \ $(GLIB_LIBS) \ $(CODE_COVERAGE_LDFLAGS) \ $(NULL) @@ -2089,14 +2235,14 @@ shared_systemd_libnm_systemd_shared_la_LIBADD = \ src_core_libnm_systemd_core_la_cppflags = \ $(libsystemd_cppflags) \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src \ -I$(srcdir)/src/core \ -I$(srcdir)/src/core/systemd/sd-adapt-core \ -I$(srcdir)/src/core/systemd/src/systemd \ -I$(srcdir)/src/core/systemd/src/libsystemd-network \ -I$(srcdir)/src/core/systemd/src/libsystemd/sd-event \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ $(NULL) src_core_libnm_systemd_core_la_libadd = \ @@ -2178,7 +2324,7 @@ src_core_libnm_systemd_core_la_LIBADD = \ $(GLIB_LIBS) \ $(CODE_COVERAGE_LDFLAGS) \ $(NULL) -$(src_core_libnm_systemd_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_libnm_systemd_core_la_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ src/core/systemd/meson.build @@ -2197,23 +2343,6 @@ src_core_libNetworkManagerBase_la_SOURCES = \ src/core/NetworkManagerUtils.c \ src/core/NetworkManagerUtils.h \ \ - src/core/platform/nmp-object.c \ - src/core/platform/nmp-object.h \ - src/core/platform/nm-platform.c \ - src/core/platform/nm-platform.h \ - src/core/platform/nm-platform-private.h \ - src/core/platform/nm-linux-platform.c \ - src/core/platform/nm-linux-platform.h \ - src/core/platform/nmp-rules-manager.c \ - src/core/platform/nmp-rules-manager.h \ - src/core/platform/wifi/nm-wifi-utils-nl80211.c \ - src/core/platform/wifi/nm-wifi-utils-nl80211.h \ - src/core/platform/wifi/nm-wifi-utils-private.h \ - src/core/platform/wifi/nm-wifi-utils.c \ - src/core/platform/wifi/nm-wifi-utils.h \ - src/core/platform/wpan/nm-wpan-utils.c \ - src/core/platform/wpan/nm-wpan-utils.h \ - \ src/core/ndisc/nm-lndp-ndisc.c \ src/core/ndisc/nm-lndp-ndisc.h \ src/core/ndisc/nm-ndisc.c \ @@ -2256,21 +2385,12 @@ src_core_libNetworkManagerBase_la_SOURCES = \ \ $(NULL) -if WITH_WEXT -src_core_libNetworkManagerBase_la_SOURCES += \ - src/core/platform/wifi/nm-wifi-utils-wext.c \ - src/core/platform/wifi/nm-wifi-utils-wext.h -endif - src_core_libNetworkManagerBase_la_LIBADD = \ $(GLIB_LIBS) \ $(LIBUDEV_LIBS) \ $(NULL) -$(src_core_libNetworkManagerBase_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -EXTRA_DIST += \ - src/core/platform/linux/nl802154.h +$(src_core_libNetworkManagerBase_la_OBJECTS): $(src_libnm_core_public_mkenums_h) ############################################################################### @@ -2457,22 +2577,22 @@ src_core_libNetworkManager_la_SOURCES = \ src_core_libNetworkManager_la_LIBADD = \ src/core/libNetworkManagerBase.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la \ $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-platform/libnm-platform.la \ - shared/nm-base/libnm-base.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ src/core/libnm-systemd-core.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/libnacd.la \ - shared/libndhcp4.la \ - shared/libcrbtree.la \ - shared/libcsiphash.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/n-acd/libn-acd.la \ + src/n-dhcp4/libn-dhcp4.la \ + src/c-rbtree/libc-rbtree.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(LIBUDEV_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ @@ -2485,7 +2605,7 @@ src_core_libNetworkManager_la_LIBADD = \ $(LIBCURL_LIBS) \ $(NULL) -$(src_core_libNetworkManager_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_libNetworkManager_la_OBJECTS): $(src_libnm_core_public_mkenums_h) ############################################################################### @@ -2512,7 +2632,7 @@ src_core_libNetworkManagerTest_la_LIBADD = \ $(LIBUDEV_LIBS) \ $(NULL) -$(src_core_libNetworkManagerTest_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_libNetworkManagerTest_la_OBJECTS): $(src_libnm_core_public_mkenums_h) ############################################################################### @@ -2533,7 +2653,7 @@ src_core_NetworkManager_all_sym_LDFLAGS = \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -$(src_core_NetworkManager_all_sym_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_NetworkManager_all_sym_OBJECTS): $(src_libnm_core_public_mkenums_h) src/core/NetworkManager.ver: src/core/NetworkManager-all-sym $(core_plugins) $(AM_V_GEN) NM="$(NM)" "$(srcdir)/tools/create-exports-NetworkManager.sh" --called-from-build "$(srcdir)" @@ -2559,7 +2679,7 @@ src_core_NetworkManager_LDFLAGS = \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -$(src_core_NetworkManager_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_NetworkManager_OBJECTS): $(src_libnm_core_public_mkenums_h) ############################################################################### @@ -2570,22 +2690,22 @@ src_core_nm_iface_helper_SOURCES = \ src_core_nm_iface_helper_LDADD = \ src/core/libNetworkManagerBase.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la \ $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-platform/libnm-platform.la \ - shared/nm-base/libnm-base.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ src/core/libnm-systemd-core.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/libnacd.la \ - shared/libndhcp4.la \ - shared/libcrbtree.la \ - shared/libcsiphash.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/n-acd/libn-acd.la \ + src/n-dhcp4/libn-dhcp4.la \ + src/c-rbtree/libc-rbtree.la \ + src/c-siphash/libc-siphash.la \ $(SYSTEMD_JOURNAL_LIBS) \ $(GLIB_LIBS) \ $(LIBUDEV_LIBS) \ @@ -2597,336 +2717,330 @@ src_core_nm_iface_helper_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) -$(src_core_nm_iface_helper_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_nm_iface_helper_OBJECTS): $(src_libnm_core_public_mkenums_h) ############################################################################### -noinst_LTLIBRARIES += src/core/initrd/libnmi-core.la - -src_core_initrd_libnmi_core_la_CPPFLAGS = \ - $(src_core_cppflags) +noinst_LTLIBRARIES += src/nm-initrd-generator/libnmi-core.la -src_core_initrd_libnmi_core_la_SOURCES = \ - src/core/initrd/nm-initrd-generator.h \ - src/core/initrd/nmi-cmdline-reader.c \ - src/core/initrd/nmi-dt-reader.c \ - src/core/initrd/nmi-ibft-reader.c \ +src_nm_initrd_generator_libnmi_core_la_CPPFLAGS = \ + $(dflt_cppflags) \ + -I$(srcdir)/src/libnm-core-public \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + $(CODE_COVERAGE_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(LIBUDEV_CFLAGS) \ + $(SYSTEMD_JOURNAL_CFLAGS) \ + $(SANITIZER_LIB_CFLAGS) \ $(NULL) -libexec_PROGRAMS += src/core/initrd/nm-initrd-generator +src_nm_initrd_generator_libnmi_core_la_SOURCES = \ + src/nm-initrd-generator/nm-initrd-generator.h \ + src/nm-initrd-generator/nmi-cmdline-reader.c \ + src/nm-initrd-generator/nmi-dt-reader.c \ + src/nm-initrd-generator/nmi-ibft-reader.c \ + $(NULL) -src_core_initrd_nm_initrd_generator_CPPFLAGS = \ - $(src_core_cppflags) +libexec_PROGRAMS += src/nm-initrd-generator/nm-initrd-generator -src_core_initrd_nm_initrd_generator_SOURCES = \ - src/core/initrd/nm-initrd-generator.c +src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS = \ + $(dflt_cppflags) \ + -I$(srcdir)/src/libnm-core-public \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + $(CODE_COVERAGE_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(LIBUDEV_CFLAGS) \ + $(SYSTEMD_JOURNAL_CFLAGS) \ + $(SANITIZER_EXEC_CFLAGS) \ + $(NULL) -src_core_initrd_nm_initrd_generator_LDADD = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerBase.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la \ +src_nm_initrd_generator_nm_initrd_generator_LDADD = \ + src/nm-initrd-generator/libnmi-core.la \ + src/libnm-core-impl/libnm-core-impl.la \ $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-platform/libnm-platform.la \ - shared/nm-base/libnm-base.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libndhcp4.la \ - shared/libcsiphash.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(SYSTEMD_JOURNAL_LIBS) \ $(GLIB_LIBS) \ $(NULL) -src_core_initrd_nm_initrd_generator_LDFLAGS = \ +src_nm_initrd_generator_nm_initrd_generator_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ - $(SANITIZER_EXEC_LDFLAGS) + $(SANITIZER_EXEC_LDFLAGS) \ + $(NULL) -check_programs += src/core/initrd/tests/test-dt-reader +check_programs += src/nm-initrd-generator/tests/test-dt-reader -src_core_initrd_tests_test_dt_reader_CPPFLAGS = \ - $(src_core_cppflags) \ - $(NULL) +src_nm_initrd_generator_tests_test_dt_reader_CPPFLAGS = \ + $(src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS) -src_core_initrd_tests_test_dt_reader_LDFLAGS = \ +src_nm_initrd_generator_tests_test_dt_reader_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -src_core_initrd_tests_test_dt_reader_LDADD = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerTest.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - $(GLIB_LIBS) \ - $(NULL) +src_nm_initrd_generator_tests_test_dt_reader_LDADD = \ + $(src_nm_initrd_generator_nm_initrd_generator_LDADD) -check_programs += src/core/initrd/tests/test-ibft-reader +check_programs += src/nm-initrd-generator/tests/test-ibft-reader -src_core_initrd_tests_test_ibft_reader_CPPFLAGS = \ - $(src_core_cppflags) \ - $(NULL) +src_nm_initrd_generator_tests_test_ibft_reader_CPPFLAGS = \ + $(src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS) -src_core_initrd_tests_test_ibft_reader_LDFLAGS = \ +src_nm_initrd_generator_tests_test_ibft_reader_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -src_core_initrd_tests_test_ibft_reader_LDADD = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerTest.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - $(GLIB_LIBS) \ - $(NULL) +src_nm_initrd_generator_tests_test_ibft_reader_LDADD = \ + $(src_nm_initrd_generator_nm_initrd_generator_LDADD) -EXTRA_DIST += \ - src/core/initrd/meson.build \ - src/core/initrd/tests/meson.build \ - src/core/initrd/tests/sysfs/class/net/eth0/address \ - src/core/initrd/tests/sysfs/class/net/eth2/address \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/hostname \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/dhcp \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/flags \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/isns-server \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/pri-radius-server \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/slp-server \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/sec-radius-server \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/index \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/flags \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/nic-assoc \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/chap-type \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/flags \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/target-name \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/nic-assoc \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/ip-addr \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/chap-type \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/index \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/lun \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/flags \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/port \ - src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/oem_table_id \ - src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/oem_id \ - src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/signature \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/prefix-len \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/hostname \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/gateway \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/mac \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/vlan \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/primary-dns \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/dhcp \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/origin \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/secondary-dns \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/ip-addr \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/subnet-mask \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/index \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/flags \ - src/core/initrd/tests/sysfs-bad-dns1/class/net/eth0/address \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-bad-dns2/class/net/eth0/address \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-bad-gateway/class/net/eth0/address \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-bad-ipaddr/class/net/eth0/address \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-dhcp/class/net/eth0/address \ - src/core/initrd/tests/sysfs-dhcp/class/net/eth1/address \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/gateway \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/mac \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/vlan \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/primary-dns \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/origin \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/secondary-dns \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/index \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/target-name \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/ip-addr \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/index \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/lun \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/port \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootpath \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-request \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-response \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/broadcast-ip \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/client-ip \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/client-name \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/domain-name \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/gateway-ip \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/name \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/netmask-ip \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/root-path \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/server-ip \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/tftp-file \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/vendor-options \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/device_type \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/local-mac-address \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/mac-address \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/name \ - src/core/initrd/tests/sysfs-dt-tftp/firmware/devicetree/base/chosen/bootpath \ - src/core/initrd/tests/sysfs-static/class/net/eth0/address \ - src/core/initrd/tests/sysfs-static/class/net/eth1/address \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-static/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/gateway \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/mac \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/vlan \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/primary-dns \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/origin \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/secondary-dns \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/index \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target1/target-name \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target1/ip-addr \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target1/index \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target1/lun \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target1/port \ - src/core/initrd/tests/sysfs-vlan/class/net/eth0/address \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/port \ - $(NULL) - -check_programs += src/core/initrd/tests/test-cmdline-reader - -src_core_initrd_tests_test_cmdline_reader_CPPFLAGS = \ - $(src_core_cppflags) \ - $(NULL) +check_programs += src/nm-initrd-generator/tests/test-cmdline-reader -src_core_initrd_tests_test_cmdline_reader_LDFLAGS = \ - $(CODE_COVERAGE_LDFLAGS) \ - $(SANITIZER_EXEC_LDFLAGS) +src_nm_initrd_generator_tests_test_cmdline_reader_CPPFLAGS = \ + $(src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS) -src_core_initrd_tests_test_cmdline_reader_LDADD = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerTest.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - $(GLIB_LIBS) \ +src_nm_initrd_generator_tests_test_cmdline_reader_LDFLAGS = \ + $(CODE_COVERAGE_LDFLAGS) \ + $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -$(src_core_initrd_libnmi_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_initrd_nm_initrd_generator_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_initrd_tests_test_cmdline_reader_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_initrd_tests_test_ibft_reader_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_initrd_tests_test_dt_reader_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +src_nm_initrd_generator_tests_test_cmdline_reader_LDADD = \ + $(src_nm_initrd_generator_nm_initrd_generator_LDADD) + +$(src_nm_initrd_generator_libnmi_core_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_initrd_generator_nm_initrd_generator_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_initrd_generator_tests_test_cmdline_reader_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_initrd_generator_tests_test_ibft_reader_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_initrd_generator_tests_test_dt_reader_OBJECTS): $(src_libnm_core_public_mkenums_h) + +EXTRA_DIST += \ + src/nm-initrd-generator/meson.build \ + src/nm-initrd-generator/tests/meson.build \ + src/nm-initrd-generator/tests/sysfs/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs/class/net/eth2/address \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/hostname \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/dhcp \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/flags \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/isns-server \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/pri-radius-server \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/slp-server \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/sec-radius-server \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/index \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/flags \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/nic-assoc \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/chap-type \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/flags \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/target-name \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/nic-assoc \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/ip-addr \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/chap-type \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/index \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/lun \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/flags \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/port \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/acpi_header/oem_table_id \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/acpi_header/oem_id \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/acpi_header/signature \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/prefix-len \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/hostname \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/gateway \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/mac \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/vlan \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/primary-dns \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/dhcp \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/origin \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/secondary-dns \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/ip-addr \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/subnet-mask \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/index \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/flags \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-dhcp/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-dhcp/class/net/eth1/address \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/gateway \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/mac \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/vlan \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/primary-dns \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/origin \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/index \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/target-name \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/ip-addr \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/index \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/lun \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/port \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/bootpath \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-request \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-response \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/broadcast-ip \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/client-ip \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/client-name \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/domain-name \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/gateway-ip \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/name \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/netmask-ip \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/root-path \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/server-ip \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/tftp-file \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/vendor-options \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/device_type \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/local-mac-address \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/mac-address \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/name \ + src/nm-initrd-generator/tests/sysfs-dt-tftp/firmware/devicetree/base/chosen/bootpath \ + src/nm-initrd-generator/tests/sysfs-static/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-static/class/net/eth1/address \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/gateway \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/mac \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/vlan \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/primary-dns \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/origin \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/index \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/target-name \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/ip-addr \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/index \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/lun \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/port \ + src/nm-initrd-generator/tests/sysfs-vlan/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/port \ + $(NULL) ############################################################################### @@ -2943,9 +3057,8 @@ libexec_PROGRAMS += src/core/dhcp/nm-dhcp-helper src_core_dhcp_nm_dhcp_helper_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -DG_LOG_DOMAIN=\""nm-dhcp-helper"\" \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(GLIB_CFLAGS) \ $(NULL) @@ -2984,8 +3097,8 @@ src_core_dhcp_tests_test_dhcp_utils_LDADD = $(src_core_dhcp_tests_ldadd) src_core_dhcp_tests_test_dhcp_dhclient_LDFLAGS = $(src_core_tests_ldflags) src_core_dhcp_tests_test_dhcp_utils_LDFLAGS = $(src_core_tests_ldflags) -$(src_core_dhcp_tests_test_dhcp_dhclient_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_dhcp_tests_test_dhcp_utils_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_dhcp_tests_test_dhcp_dhclient_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_dhcp_tests_test_dhcp_utils_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ src/core/dhcp/tests/test-dhclient-duid.leases \ @@ -3004,10 +3117,10 @@ pppd_plugin_LTLIBRARIES += src/core/ppp/nm-pppd-plugin.la src_core_ppp_nm_pppd_plugin_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -DG_LOG_DOMAIN=\""nm-pppd-plugin"\" \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ $(GLIB_CFLAGS) src_core_ppp_nm_pppd_plugin_la_SOURCES = \ @@ -3023,7 +3136,7 @@ src_core_ppp_nm_pppd_plugin_la_LIBADD = \ $(DL_LIBS) \ $(NULL) -$(src_core_ppp_nm_pppd_plugin_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_ppp_nm_pppd_plugin_la_OBJECTS): $(src_libnm_core_public_mkenums_h) src_core_ppp_libnm_ppp_plugin_la_SOURCES = \ src/core/ppp/nm-pppd-plugin.h \ @@ -3048,7 +3161,7 @@ src_core_ppp_libnm_ppp_plugin_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) -$(src_core_ppp_libnm_ppp_plugin_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_ppp_libnm_ppp_plugin_la_OBJECTS): $(src_libnm_core_public_mkenums_h) endif @@ -3071,7 +3184,7 @@ src_core_settings_plugins_keyfile_tests_test_keyfile_settings_LDFLAGS = \ src_core_settings_plugins_keyfile_tests_test_keyfile_settings_LDADD = \ src/core/libNetworkManagerTest.la -$(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection \ @@ -3167,7 +3280,7 @@ src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_SOURCES = \ src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS = $(src_core_cppflags_base) -$(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_OBJECTS): $(src_libnm_core_public_mkenums_h) ############################################################################### @@ -3189,7 +3302,7 @@ src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_LIBADD = \ src/core/settings/plugins/ifcfg-rh/libnms-ifcfg-rh-core.la $(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_OBJECTS): src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.h -$(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_OBJECTS): $(src_libnm_core_public_mkenums_h) check-local-symbols-settings-ifcfg-rh: src/core/settings/plugins/ifcfg-rh/libnm-settings-plugin-ifcfg-rh.la $(call check_so_symbols,$(builddir)/src/core/settings/plugins/ifcfg-rh/.libs/libnm-settings-plugin-ifcfg-rh.so) @@ -3216,7 +3329,7 @@ src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_LDADD = \ src/core/settings/plugins/ifcfg-rh/libnms-ifcfg-rh-core.la \ src/core/libNetworkManagerTest.la -$(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_OBJECTS): $(src_libnm_core_public_mkenums_h) dist_libexec_SCRIPTS += \ src/core/settings/plugins/ifcfg-rh/nm-ifup \ @@ -3509,8 +3622,8 @@ src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_LIBADD = \ $(LIBUDEV_LIBS) \ $(NULL) -$(src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_OBJECTS): $(src_libnm_core_public_mkenums_h) check-local-symbols-settings-ifupdown: src/core/settings/plugins/ifupdown/libnm-settings-plugin-ifupdown.la $(call check_so_symbols,$(builddir)/src/core/settings/plugins/ifupdown/.libs/libnm-settings-plugin-ifupdown.so) @@ -3533,7 +3646,7 @@ src_core_settings_plugins_ifupdown_tests_test_ifupdown_LDADD = \ $(GLIB_LIBS) \ $(NULL) -$(src_core_settings_plugins_ifupdown_tests_test_ifupdown_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_settings_plugins_ifupdown_tests_test_ifupdown_OBJECTS): $(src_libnm_core_public_mkenums_h) endif @@ -3642,7 +3755,7 @@ src_core_devices_wwan_libnm_wwan_la_LIBADD = \ $(LIBSYSTEMD_LIBS) \ $(MM_GLIB_LIBS) -$(src_core_devices_wwan_libnm_wwan_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_devices_wwan_libnm_wwan_la_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_src_core_devices_wwan_libnm_wwan_la_DEPENDENCIES = \ src/core/devices/wwan/libnm-wwan.ver @@ -3694,7 +3807,7 @@ src_core_devices_wwan_tests_test_service_providers_LDADD = \ check_programs += src/core/devices/wwan/tests/test-service-providers -$(src_core_devices_wwan_tests_test_service_providers_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_devices_wwan_tests_test_service_providers_OBJECTS): $(src_libnm_core_public_mkenums_h) endif @@ -3736,7 +3849,7 @@ src_core_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS += $(BLUEZ5_CFLAGS) src_core_devices_bluetooth_libnm_bluetooth_utils_la_LIBADD += $(BLUEZ5_LIBS) endif -$(src_core_devices_bluetooth_libnm_bluetooth_utils_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_devices_bluetooth_libnm_bluetooth_utils_la_OBJECTS): $(src_libnm_core_public_mkenums_h) ############################################################################### @@ -3780,7 +3893,7 @@ src_core_devices_bluetooth_tests_nm_bt_test_LDADD = \ $(GLIB_LIBS) \ $(NULL) -$(src_core_devices_bluetooth_tests_nm_bt_test_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_devices_bluetooth_tests_nm_bt_test_OBJECTS): $(src_libnm_core_public_mkenums_h) ############################################################################### @@ -3835,7 +3948,7 @@ src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS = $(src_core_cppflags_device_p src_core_devices_wifi_libnm_wifi_base_la_LIBADD = \ $(GLIB_LIBS) -$(src_core_devices_wifi_libnm_wifi_base_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_devices_wifi_libnm_wifi_base_la_OBJECTS): $(src_libnm_core_public_mkenums_h) core_plugins += src/core/devices/wifi/libnm-device-plugin-wifi.la @@ -3875,7 +3988,7 @@ src_core_devices_wifi_tests_test_devices_wifi_LDADD = \ src_core_devices_wifi_tests_test_devices_wifi_LDFLAGS = $(SANITIZER_EXEC_LDFLAGS) -$(src_core_devices_wifi_tests_test_devices_wifi_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_devices_wifi_tests_test_devices_wifi_OBJECTS): $(src_libnm_core_public_mkenums_h) endif @@ -3992,7 +4105,7 @@ src_core_dnsmasq_tests_test_dnsmasq_utils_LDADD = \ src_core_dnsmasq_tests_test_dnsmasq_utils_LDFLAGS = \ $(SANITIZER_EXEC_LDFLAGS) -$(src_core_dnsmasq_tests_test_dnsmasq_utils_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_dnsmasq_tests_test_dnsmasq_utils_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ src/core/dnsmasq/tests/meson.build @@ -4091,19 +4204,19 @@ src_core_platform_tests_test_tc_linux_LDFLAGS = $(src_core_platform_tests_ldflag src_core_platform_tests_test_tc_linux_LDADD = $(src_core_platform_tests_libadd) -$(src_core_platform_tests_monitor_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_address_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_address_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_cleanup_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_cleanup_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_link_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_link_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_nmp_object_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_platform_general_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_route_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_route_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_tc_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_tc_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_platform_tests_monitor_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_address_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_address_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_cleanup_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_cleanup_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_link_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_link_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_nmp_object_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_platform_general_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_route_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_route_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_tc_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_tc_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ src/core/platform/tests/meson.build \ @@ -4131,8 +4244,8 @@ src_core_devices_tests_test_acd_LDFLAGS = $(src_core_devices_tests_ldflags) src_core_devices_tests_test_acd_LDADD = \ src/core/libNetworkManagerTest.la -$(src_core_devices_tests_test_lldp_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_tests_test_acd_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_devices_tests_test_lldp_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_tests_test_acd_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ src/core/devices/tests/meson.build @@ -4160,8 +4273,8 @@ src_core_ndisc_tests_test_ndisc_fake_CPPFLAGS = $(src_core_cppflags_test) src_core_ndisc_tests_test_ndisc_fake_LDFLAGS = $(src_core_ndisc_tests_ldflags) src_core_ndisc_tests_test_ndisc_fake_LDADD = $(src_core_ndisc_tests_ldadd) -$(src_core_ndisc_tests_test_ndisc_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_ndisc_tests_test_ndisc_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_ndisc_tests_test_ndisc_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_ndisc_tests_test_ndisc_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ src/core/ndisc/tests/meson.build @@ -4180,7 +4293,7 @@ src_core_supplicant_tests_test_supplicant_config_LDADD = \ src_core_supplicant_tests_test_supplicant_config_LDFLAGS = \ $(SANITIZER_EXEC_LDFLAGS) -$(src_core_supplicant_tests_test_supplicant_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_supplicant_tests_test_supplicant_config_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ src/core/supplicant/tests/certs/test-ca-cert.pem \ @@ -4206,7 +4319,7 @@ src_core_tests_config_test_config_LDADD = \ src_core_tests_config_test_config_LDFLAGS = \ $(SANITIZER_EXEC_LDFLAGS) -$(src_core_tests_config_test_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_tests_config_test_config_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ src/core/tests/config/NetworkManager.conf \ @@ -4275,14 +4388,14 @@ src_core_tests_test_l3cfg_CPPFLAGS = $(src_core_cppflags_test) src_core_tests_test_l3cfg_LDFLAGS = $(src_core_devices_tests_ldflags) src_core_tests_test_l3cfg_LDADD = $(src_core_tests_ldadd) -$(src_core_tests_test_core_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_core_with_expect_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_dcb_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_ip4_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_ip6_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_l3cfg_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_utils_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_wired_defname_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_tests_test_core_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_core_with_expect_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_dcb_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_ip4_config_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_ip6_config_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_l3cfg_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_utils_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_wired_defname_OBJECTS): $(src_libnm_core_public_mkenums_h) src_core_tests_test_systemd_CPPFLAGS = \ $(src_core_libnm_systemd_core_la_cppflags) \ @@ -4294,91 +4407,88 @@ src_core_tests_test_systemd_LDFLAGS = \ src_core_tests_test_systemd_LDADD = \ src/core/libnm-systemd-core.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/libcsiphash.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(CODE_COVERAGE_LDFLAGS) \ $(NULL) -$(src_core_tests_test_systemd_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_tests_test_systemd_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ src/core/tests/test-secret-agent.py \ src/core/tests/meson.build ############################################################################### -# dispatcher +# src/nm-dispatcher ############################################################################### dispatcher_nmdbus_dispatcher_sources = \ - dispatcher/nmdbus-dispatcher.h \ - dispatcher/nmdbus-dispatcher.c \ + src/nm-dispatcher/nmdbus-dispatcher.h \ + src/nm-dispatcher/nmdbus-dispatcher.c \ $(NULL) -dispatcher/nmdbus-dispatcher.h: dispatcher/nm-dispatcher.xml - @$(MKDIR_P) dispatcher/ +src/nm-dispatcher/nmdbus-dispatcher.h: src/nm-dispatcher/nm-dispatcher.xml + @$(MKDIR_P) src/nm-dispatcher/ $(AM_V_GEN) gdbus-codegen \ --generate-c-code $(basename $@) \ --c-namespace NMDBus \ --interface-prefix org.freedesktop \ $< -dispatcher/nmdbus-dispatcher.c: dispatcher/nmdbus-dispatcher.h +src/nm-dispatcher/nmdbus-dispatcher.c: src/nm-dispatcher/nmdbus-dispatcher.h CLEANFILES += $(dispatcher_nmdbus_dispatcher_sources) ############################################################################### -libexec_PROGRAMS += dispatcher/nm-dispatcher +libexec_PROGRAMS += src/nm-dispatcher/nm-dispatcher -noinst_LTLIBRARIES += \ - dispatcher/libnm-dispatcher-core.la +noinst_LTLIBRARIES += src/nm-dispatcher/libnm-dispatcher-core.la dispatcher_cppflags = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ - -I$(srcdir)/dispatcher \ - -I$(builddir)/dispatcher \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(builddir)/src/libnm-client-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(GLIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""nm-dispatcher"\" \ $(NULL) -dispatcher_libnm_dispatcher_core_la_SOURCES = \ - dispatcher/nm-dispatcher-utils.c \ - dispatcher/nm-dispatcher-utils.h \ +src_nm_dispatcher_libnm_dispatcher_core_la_SOURCES = \ + src/nm-dispatcher/nm-dispatcher-utils.c \ + src/nm-dispatcher/nm-dispatcher-utils.h \ $(NULL) -dispatcher_libnm_dispatcher_core_la_CPPFLAGS = $(dispatcher_cppflags) +src_nm_dispatcher_libnm_dispatcher_core_la_CPPFLAGS = $(dispatcher_cppflags) -dispatcher_libnm_dispatcher_core_la_LIBADD = \ - libnm/libnm.la \ +src_nm_dispatcher_libnm_dispatcher_core_la_LIBADD = \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) -dispatcher_nm_dispatcher_SOURCES = \ - dispatcher/nm-dispatcher.c \ +src_nm_dispatcher_nm_dispatcher_SOURCES = \ + src/nm-dispatcher/nm-dispatcher.c \ $(NULL) -dispatcher_nm_dispatcher_CPPFLAGS = $(dispatcher_cppflags) +src_nm_dispatcher_nm_dispatcher_CPPFLAGS = $(dispatcher_cppflags) -dispatcher_nm_dispatcher_LDFLAGS = \ +src_nm_dispatcher_nm_dispatcher_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -dispatcher_nm_dispatcher_LDADD = \ - dispatcher/libnm-dispatcher-core.la \ - libnm/libnm.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - $(GLIB_LIBS) +src_nm_dispatcher_nm_dispatcher_LDADD = \ + src/nm-dispatcher/libnm-dispatcher-core.la \ + src/libnm-client-impl/libnm.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + $(GLIB_LIBS) \ + $(NULL) -dispatcher/org.freedesktop.nm_dispatcher.service: $(srcdir)/dispatcher/org.freedesktop.nm_dispatcher.service.in +src/nm-dispatcher/org.freedesktop.nm_dispatcher.service: $(srcdir)/src/nm-dispatcher/org.freedesktop.nm_dispatcher.service.in @sed \ -e 's|@sbindir[@]|$(sbindir)|g' \ -e 's|@sysconfdir[@]|$(sysconfdir)|g' \ @@ -4386,8 +4496,8 @@ dispatcher/org.freedesktop.nm_dispatcher.service: $(srcdir)/dispatcher/org.freed -e 's|@libexecdir[@]|$(libexecdir)|g' \ $< >$@ -dbusactivation_DATA += dispatcher/org.freedesktop.nm_dispatcher.service -CLEANFILES += dispatcher/org.freedesktop.nm_dispatcher.service +dbusactivation_DATA += src/nm-dispatcher/org.freedesktop.nm_dispatcher.service +CLEANFILES += src/nm-dispatcher/org.freedesktop.nm_dispatcher.service install-data-hook-dispatcher: $(mkinstalldirs) -m 0755 $(DESTDIR)$(nmconfdir)/dispatcher.d @@ -4401,338 +4511,288 @@ install-data-hook-dispatcher: install_data_hook += install-data-hook-dispatcher - -dbusservice_DATA += dispatcher/nm-dispatcher.conf +dbusservice_DATA += src/nm-dispatcher/nm-dispatcher.conf EXTRA_DIST += \ - dispatcher/nm-dispatcher.conf \ - dispatcher/org.freedesktop.nm_dispatcher.service.in \ - dispatcher/nm-dispatcher.xml \ - dispatcher/meson.build + src/nm-dispatcher/nm-dispatcher.conf \ + src/nm-dispatcher/org.freedesktop.nm_dispatcher.service.in \ + src/nm-dispatcher/nm-dispatcher.xml \ + src/nm-dispatcher/meson.build \ + $(NULL) ############################################################################### -# dispatcher/tests +# src/nm-dispatcher/tests ############################################################################### -check_programs += dispatcher/tests/test-dispatcher-envp +check_programs += src/nm-dispatcher/tests/test-dispatcher-envp -dispatcher_tests_test_dispatcher_envp_CPPFLAGS = \ +src_nm_dispatcher_tests_test_dispatcher_envp_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ - -I$(srcdir)/dispatcher \ - -I$(builddir)/dispatcher \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(GLIB_CFLAGS) \ $(SANITIZER_EXEC_CFLAGS) \ $(INTROSPECTION_EXTRA_CFLAGS) \ $(NULL) -dispatcher_tests_test_dispatcher_envp_SOURCES = \ - dispatcher/tests/test-dispatcher-envp.c \ +src_nm_dispatcher_tests_test_dispatcher_envp_SOURCES = \ + src/nm-dispatcher/tests/test-dispatcher-envp.c \ $(NULL) -nodist_dispatcher_tests_test_dispatcher_envp_SOURCES = $(dispatcher_nmdbus_dispatcher_sources) +nodist_src_nm_dispatcher_tests_test_dispatcher_envp_SOURCES = $(dispatcher_nmdbus_dispatcher_sources) -$(dispatcher_tests_test_dispatcher_envp_OBJECTS): $(dispatcher_nmdbus_dispatcher_sources) +$(src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS): $(dispatcher_nmdbus_dispatcher_sources) +$(src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS): $(src_libnm_client_public_mkenums_h) -dispatcher_tests_test_dispatcher_envp_LDFLAGS = \ +src_nm_dispatcher_tests_test_dispatcher_envp_LDFLAGS = \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -dispatcher_tests_test_dispatcher_envp_LDADD = \ - dispatcher/libnm-dispatcher-core.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - libnm/libnm.la \ +src_nm_dispatcher_tests_test_dispatcher_envp_LDADD = \ + src/nm-dispatcher/libnm-dispatcher-core.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(NULL) -$(dispatcher_tests_test_dispatcher_envp_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS): $(src_libnm_core_public_mkenums_h) EXTRA_DIST += \ - dispatcher/tests/dispatcher-connectivity-full \ - dispatcher/tests/dispatcher-connectivity-unknown \ - dispatcher/tests/dispatcher-down \ - dispatcher/tests/dispatcher-external \ - dispatcher/tests/dispatcher-up \ - dispatcher/tests/dispatcher-vpn-down \ - dispatcher/tests/dispatcher-vpn-up \ - dispatcher/tests/meson.build \ + src/nm-dispatcher/tests/dispatcher-connectivity-full \ + src/nm-dispatcher/tests/dispatcher-connectivity-unknown \ + src/nm-dispatcher/tests/dispatcher-down \ + src/nm-dispatcher/tests/dispatcher-external \ + src/nm-dispatcher/tests/dispatcher-up \ + src/nm-dispatcher/tests/dispatcher-vpn-down \ + src/nm-dispatcher/tests/dispatcher-vpn-up \ + src/nm-dispatcher/tests/meson.build \ $(NULL) ############################################################################### -# clients +# src/nm-online ############################################################################### -bin_PROGRAMS += clients/nm-online +bin_PROGRAMS += src/nm-online/nm-online -clients_nm_online_CPPFLAGS = \ +src_nm_online_nm_online_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(GLIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""nm-online"\" \ $(NULL) -clients_nm_online_LDFLAGS = \ +src_nm_online_nm_online_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -clients_nm_online_LDADD = \ - libnm/libnm.la \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ +src_nm_online_nm_online_LDADD = \ + src/libnm-client-impl/libnm.la \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(NULL) -$(clients_nm_online_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_nm_online_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_nm_online_nm_online_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_online_nm_online_OBJECTS): $(src_libnm_client_public_mkenums_h) -EXTRA_DIST += \ - clients/meson.build +EXTRA_DIST += src/nm-online/meson.build ############################################################################### -# clients/common +# src/libnmc-base ############################################################################### clients_cppflags = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ - -I$(srcdir)/clients/common \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(srcdir)/src/libnm-core-public \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(GLIB_CFLAGS) \ $(SANITIZER_EXEC_CFLAGS) \ $(NULL) -check_ltlibraries += clients/common/libnmc-base.la +check_ltlibraries += src/libnmc-base/libnmc-base.la -clients_common_libnmc_base_la_SOURCES = \ - clients/common/nm-secret-agent-simple.c \ - clients/common/nm-secret-agent-simple.h \ - clients/common/nm-vpn-helpers.c \ - clients/common/nm-vpn-helpers.h \ - clients/common/nm-client-utils.c \ - clients/common/nm-client-utils.h \ - clients/common/nm-polkit-listener.c \ - clients/common/nm-polkit-listener.h \ +src_libnmc_base_libnmc_base_la_SOURCES = \ + src/libnmc-base/nm-client-utils.c \ + src/libnmc-base/nm-client-utils.h \ + src/libnmc-base/nm-polkit-listener.c \ + src/libnmc-base/nm-polkit-listener.h \ + src/libnmc-base/nm-secret-agent-simple.c \ + src/libnmc-base/nm-secret-agent-simple.h \ + src/libnmc-base/nm-vpn-helpers.c \ + src/libnmc-base/nm-vpn-helpers.h \ $(NULL) EXTRA_DIST += \ - clients/common/qrcodegen.c \ - clients/common/qrcodegen.h + src/libnmc-base/qrcodegen.c \ + src/libnmc-base/qrcodegen.h \ + $(NULL) -clients_common_libnmc_base_la_CPPFLAGS = \ +src_libnmc_base_libnmc_base_la_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""libnmc"\" \ $(NULL) -clients_common_libnmc_base_la_LIBADD = \ - libnm/libnm.la \ +src_libnmc_base_libnmc_base_la_LIBADD = \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(NULL) -$(clients_common_libnmc_base_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_common_libnmc_base_la_OBJECTS): $(libnm_lib_h_pub_mkenums) -$(clients_common_libnmc_base_la_OBJECTS): clients/common/.dirstamp +$(src_libnmc_base_libnmc_base_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnmc_base_libnmc_base_la_OBJECTS): $(src_libnm_client_public_mkenums_h) -clients_common_settings_doc_h = clients/common/settings-docs.h +############################################################################### +# src/libnmc-setting +############################################################################### + +libnmc_setting_settings_doc_h = src/libnmc-setting/settings-docs.h if BUILD_DOCS -$(clients_common_settings_doc_h): clients/common/settings-docs.xsl libnm/nm-settings-docs-gir.xml clients/common/.dirstamp +$(libnmc_setting_settings_doc_h): src/libnmc-setting/settings-docs.xsl src/libnmc-setting/settings-docs-input.xml src/libnmc-setting/.dirstamp $(AM_V_GEN) $(XSLTPROC) --output $@ $< $(word 2,$^) -DISTCLEANFILES += $(clients_common_settings_doc_h) -check-local-settings-docs: $(clients_common_settings_doc_h) - $(srcdir)/tools/check-compare-generated.sh "$(srcdir)" "$(builddir)" "$(clients_common_settings_doc_h)" +DISTCLEANFILES += $(libnmc_setting_settings_doc_h) +check-local-settings-docs: $(libnmc_setting_settings_doc_h) + $(srcdir)/tools/check-compare-generated.sh "$(srcdir)" "$(builddir)" "$(libnmc_setting_settings_doc_h)" check_local += check-local-settings-docs else -$(clients_common_settings_doc_h): $(clients_common_settings_doc_h).in clients/common/.dirstamp - $(AM_V_GEN) cp "$(srcdir)/$(clients_common_settings_doc_h).in" "$(builddir)/$(clients_common_settings_doc_h)" +$(libnmc_setting_settings_doc_h): $(libnmc_setting_settings_doc_h).in src/libnmc-setting/.dirstamp + $(AM_V_GEN) cp "$(srcdir)/$(libnmc_setting_settings_doc_h).in" "$(builddir)/$(libnmc_setting_settings_doc_h)" check-local-settings-docs: endif EXTRA_DIST += \ - $(clients_common_settings_doc_h) \ - $(clients_common_settings_doc_h).in + $(libnmc_setting_settings_doc_h) \ + $(libnmc_setting_settings_doc_h).in -if HAVE_INTROSPECTION -check_ltlibraries += clients/common/libnmc.la -else -EXTRA_LTLIBRARIES += clients/common/libnmc.la -endif +check_ltlibraries += src/libnmc-setting/libnmc-setting.la -clients_common_libnmc_la_SOURCES = \ - clients/common/nm-meta-setting-base-impl.c \ - clients/common/nm-meta-setting-base-impl.h \ - clients/common/nm-meta-setting-base.h \ - \ - clients/common/nm-meta-setting-desc.c \ - clients/common/nm-meta-setting-desc.h \ - clients/common/nm-meta-setting-access.c \ - clients/common/nm-meta-setting-access.h \ +src_libnmc_setting_libnmc_setting_la_SOURCES = \ + src/libnmc-setting/nm-meta-setting-access.c \ + src/libnmc-setting/nm-meta-setting-access.h \ + src/libnmc-setting/nm-meta-setting-base-impl.c \ + src/libnmc-setting/nm-meta-setting-base-impl.h \ + src/libnmc-setting/nm-meta-setting-base.h \ + src/libnmc-setting/nm-meta-setting-desc.c \ + src/libnmc-setting/nm-meta-setting-desc.h \ $(NULL) -clients_common_libnmc_la_CPPFLAGS = \ +src_libnmc_setting_libnmc_setting_la_CPPFLAGS = \ $(clients_cppflags) \ - -I$(builddir)/clients/common \ - -DG_LOG_DOMAIN=\""libnmc"\" \ $(NULL) -clients_common_libnmc_la_LIBADD = \ - libnm/libnm.la \ +src_libnmc_setting_libnmc_setting_la_LIBADD = \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(NULL) -$(clients_common_libnmc_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_common_libnmc_la_OBJECTS): $(clients_common_settings_doc_h) -$(clients_common_libnmc_la_OBJECTS): clients/common/.dirstamp +$(src_libnmc_setting_libnmc_setting_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnmc_setting_libnmc_setting_la_OBJECTS): $(src_libnm_client_public_mkenums_h) +$(src_libnmc_setting_libnmc_setting_la_OBJECTS): $(libnmc_setting_settings_doc_h) +$(src_libnmc_setting_libnmc_setting_la_OBJECTS): src/libnmc-setting/.dirstamp -if HAVE_INTROSPECTION -check_programs += clients/common/tests/test-clients-common -else -if BUILD_NMCLI -check_programs += clients/common/tests/test-clients-common -endif -endif +############################################################################### + +check_programs += src/libnmc-setting/tests/test-libnmc-setting -clients_common_tests_test_clients_common_CPPFLAGS = \ - -I$(srcdir)/clients/common/tests \ +src_libnmc_setting_tests_test_libnmc_setting_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""test"\" \ $(NULL) -clients_common_tests_test_clients_common_LDFLAGS = \ - $(SANITIZER_EXEC_LDFLAGS) +src_libnmc_setting_tests_test_libnmc_setting_LDFLAGS = \ + $(SANITIZER_EXEC_LDFLAGS) \ + $(NULL) -clients_common_tests_test_clients_common_LDADD = \ - clients/common/libnmc.la \ - clients/common/libnmc-base.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - libnm/libnm.la \ +src_libnmc_setting_tests_test_libnmc_setting_LDADD = \ + src/libnmc-setting/libnmc-setting.la \ + src/libnmc-base/libnmc-base.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) -$(clients_common_tests_test_clients_common_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -############################################################################### +$(src_libnmc_setting_tests_test_libnmc_setting_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnmc_setting_tests_test_libnmc_setting_OBJECTS): $(src_libnm_client_public_mkenums_h) EXTRA_DIST += \ - clients/common/tests/wg-test0.conf \ - clients/common/tests/wg-test1.conf \ - clients/common/tests/wg-test2.conf \ - clients/common/tests/wg-test3.conf \ - $(NULL) - -############################################################################### - -check_programs += clients/common/tests/test-libnm-core-aux - -clients_common_tests_test_libnm_core_aux_CPPFLAGS = \ - $(dflt_cppflags) \ - -I$(builddir)/shared \ - -I$(srcdir)/shared \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm \ - -I$(srcdir)/libnm \ - -DG_LOG_DOMAIN=\""test"\" \ - $(CODE_COVERAGE_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(SANITIZER_LIB_CFLAGS) \ + src/libnmc-setting/tests/wg-test0.conf \ + src/libnmc-setting/tests/wg-test1.conf \ + src/libnmc-setting/tests/wg-test2.conf \ + src/libnmc-setting/tests/wg-test3.conf \ $(NULL) -clients_common_tests_test_libnm_core_aux_LDFLAGS = \ - $(CODE_COVERAGE_LDFLAGS) \ - $(SANITIZER_EXEC_LDFLAGS) \ - $(NULL) - -clients_common_tests_test_libnm_core_aux_LDADD = \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - libnm/libnm.la \ - $(GLIB_LIBS) \ - $(NULL) - -$(clients_common_tests_test_libnm_core_aux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_common_tests_test_libnm_core_aux_OBJECTS): $(libnm_lib_h_pub_mkenums) - ############################################################################### -# clients/cli +# src/nmcli ############################################################################### if BUILD_NMCLI -bin_PROGRAMS += clients/cli/nmcli - -clients_cli_nmcli_SOURCES = \ - clients/cli/common.c \ - clients/cli/common.h \ - clients/cli/utils.c \ - clients/cli/utils.h \ - clients/cli/agent.c \ - clients/cli/general.c \ - clients/cli/connections.c \ - clients/cli/connections.h \ - clients/cli/devices.c \ - clients/cli/devices.h \ - clients/cli/settings.c \ - clients/cli/settings.h \ - clients/cli/nmcli.c \ - clients/cli/nmcli.h \ - clients/cli/polkit-agent.c \ - clients/cli/polkit-agent.h \ - $(NULL) - -clients_cli_nmcli_CPPFLAGS = \ - -I$(srcdir)/clients/cli \ +bin_PROGRAMS += src/nmcli/nmcli + +src_nmcli_nmcli_SOURCES = \ + src/nmcli/common.c \ + src/nmcli/common.h \ + src/nmcli/utils.c \ + src/nmcli/utils.h \ + src/nmcli/agent.c \ + src/nmcli/general.c \ + src/nmcli/connections.c \ + src/nmcli/connections.h \ + src/nmcli/devices.c \ + src/nmcli/devices.h \ + src/nmcli/settings.c \ + src/nmcli/settings.h \ + src/nmcli/nmcli.c \ + src/nmcli/nmcli.h \ + src/nmcli/polkit-agent.c \ + src/nmcli/polkit-agent.h \ + $(NULL) + +src_nmcli_nmcli_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""nmcli"\" \ - $(NULL) - -clients_cli_nmcli_LDADD = \ - clients/common/libnmc.la \ - clients/common/libnmc-base.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - libnm/libnm.la \ + $(NULL) + +src_nmcli_nmcli_LDADD = \ + src/libnmc-setting/libnmc-setting.la \ + src/libnmc-base/libnmc-base.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(READLINE_LIBS) -clients_cli_nmcli_LDFLAGS = \ +src_nmcli_nmcli_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) -$(clients_cli_nmcli_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_cli_nmcli_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_nmcli_nmcli_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nmcli_nmcli_OBJECTS): $(src_libnm_client_public_mkenums_h) install-data-hook-nmcli: $(mkinstalldirs) $(DESTDIR)$(completiondir) - $(INSTALL_DATA) $(srcdir)/clients/cli/nmcli-completion $(DESTDIR)$(completiondir)/nmcli + $(INSTALL_DATA) $(srcdir)/src/nmcli/nmcli-completion $(DESTDIR)$(completiondir)/nmcli install_data_hook += install-data-hook-nmcli @@ -4745,227 +4805,238 @@ endif ############################################################################### -noinst_PROGRAMS += clients/cli/generate-docs-nm-settings-nmcli +noinst_PROGRAMS += src/nmcli/generate-docs-nm-settings-nmcli -clients_cli_generate_docs_nm_settings_nmcli_SOURCES = \ - clients/cli/generate-docs-nm-settings-nmcli.c \ +src_nmcli_generate_docs_nm_settings_nmcli_SOURCES = \ + src/nmcli/generate-docs-nm-settings-nmcli.c \ $(NULL) -clients_cli_generate_docs_nm_settings_nmcli_CPPFLAGS = \ - -I$(srcdir)/clients/common \ +src_nmcli_generate_docs_nm_settings_nmcli_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""nmcli"\" \ - $(NULL) - -clients_cli_generate_docs_nm_settings_nmcli_LDADD = \ - clients/common/libnmc.la \ - clients/common/libnmc-base.la \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - libnm/libnm.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ + $(NULL) + +src_nmcli_generate_docs_nm_settings_nmcli_LDADD = \ + src/libnmc-setting/libnmc-setting.la \ + src/libnmc-base/libnmc-base.la \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-client-impl/libnm.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(NULL) -clients_cli_generate_docs_nm_settings_nmcli_LDFLAGS = \ +src_nmcli_generate_docs_nm_settings_nmcli_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -$(clients_cli_generate_docs_nm_settings_nmcli_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_cli_generate_docs_nm_settings_nmcli_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_nmcli_generate_docs_nm_settings_nmcli_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nmcli_generate_docs_nm_settings_nmcli_OBJECTS): $(src_libnm_client_public_mkenums_h) ############################################################################### EXTRA_DIST += \ - clients/cli/nmcli-completion \ - clients/cli/meson.build \ - clients/common/settings-docs.xsl \ - clients/common/meson.build \ - clients/common/tests/meson.build + src/nmcli/nmcli-completion \ + src/nmcli/meson.build \ + src/libnmc-setting/settings-docs.xsl \ + src/libnmc-setting/meson.build \ + src/libnmc-setting/tests/meson.build ############################################################################### -# clients/tui +# src/libnmt-newt ############################################################################### if BUILD_NMTUI -noinst_LIBRARIES += clients/tui/newt/libnmt-newt.a - -clients_tui_newt_libnmt_newt_a_SOURCES = \ - clients/tui/newt/nmt-newt.h \ - clients/tui/newt/nmt-newt-types.h \ - clients/tui/newt/nmt-newt-button.c \ - clients/tui/newt/nmt-newt-button.h \ - clients/tui/newt/nmt-newt-button-box.c \ - clients/tui/newt/nmt-newt-button-box.h \ - clients/tui/newt/nmt-newt-checkbox.c \ - clients/tui/newt/nmt-newt-checkbox.h \ - clients/tui/newt/nmt-newt-component.c \ - clients/tui/newt/nmt-newt-component.h \ - clients/tui/newt/nmt-newt-container.c \ - clients/tui/newt/nmt-newt-container.h \ - clients/tui/newt/nmt-newt-entry.c \ - clients/tui/newt/nmt-newt-entry.h \ - clients/tui/newt/nmt-newt-entry-numeric.c \ - clients/tui/newt/nmt-newt-entry-numeric.h \ - clients/tui/newt/nmt-newt-form.c \ - clients/tui/newt/nmt-newt-form.h \ - clients/tui/newt/nmt-newt-grid.c \ - clients/tui/newt/nmt-newt-grid.h \ - clients/tui/newt/nmt-newt-hacks.c \ - clients/tui/newt/nmt-newt-hacks.h \ - clients/tui/newt/nmt-newt-label.c \ - clients/tui/newt/nmt-newt-label.h \ - clients/tui/newt/nmt-newt-listbox.c \ - clients/tui/newt/nmt-newt-listbox.h \ - clients/tui/newt/nmt-newt-popup.c \ - clients/tui/newt/nmt-newt-popup.h \ - clients/tui/newt/nmt-newt-section.c \ - clients/tui/newt/nmt-newt-section.h \ - clients/tui/newt/nmt-newt-separator.c \ - clients/tui/newt/nmt-newt-separator.h \ - clients/tui/newt/nmt-newt-stack.c \ - clients/tui/newt/nmt-newt-stack.h \ - clients/tui/newt/nmt-newt-textbox.c \ - clients/tui/newt/nmt-newt-textbox.h \ - clients/tui/newt/nmt-newt-toggle-button.c \ - clients/tui/newt/nmt-newt-toggle-button.h \ - clients/tui/newt/nmt-newt-utils.c \ - clients/tui/newt/nmt-newt-utils.h \ - clients/tui/newt/nmt-newt-widget.c \ - clients/tui/newt/nmt-newt-widget.h \ - $(NULL) - -clients_tui_newt_libnmt_newt_a_CPPFLAGS = \ +noinst_LIBRARIES += src/libnmt-newt/libnmt-newt.a + +src_libnmt_newt_libnmt_newt_a_SOURCES = \ + src/libnmt-newt/nmt-newt-button-box.c \ + src/libnmt-newt/nmt-newt-button-box.h \ + src/libnmt-newt/nmt-newt-button.c \ + src/libnmt-newt/nmt-newt-button.h \ + src/libnmt-newt/nmt-newt-checkbox.c \ + src/libnmt-newt/nmt-newt-checkbox.h \ + src/libnmt-newt/nmt-newt-component.c \ + src/libnmt-newt/nmt-newt-component.h \ + src/libnmt-newt/nmt-newt-container.c \ + src/libnmt-newt/nmt-newt-container.h \ + src/libnmt-newt/nmt-newt-entry-numeric.c \ + src/libnmt-newt/nmt-newt-entry-numeric.h \ + src/libnmt-newt/nmt-newt-entry.c \ + src/libnmt-newt/nmt-newt-entry.h \ + src/libnmt-newt/nmt-newt-form.c \ + src/libnmt-newt/nmt-newt-form.h \ + src/libnmt-newt/nmt-newt-grid.c \ + src/libnmt-newt/nmt-newt-grid.h \ + src/libnmt-newt/nmt-newt-hacks.c \ + src/libnmt-newt/nmt-newt-hacks.h \ + src/libnmt-newt/nmt-newt-label.c \ + src/libnmt-newt/nmt-newt-label.h \ + src/libnmt-newt/nmt-newt-listbox.c \ + src/libnmt-newt/nmt-newt-listbox.h \ + src/libnmt-newt/nmt-newt-popup.c \ + src/libnmt-newt/nmt-newt-popup.h \ + src/libnmt-newt/nmt-newt-section.c \ + src/libnmt-newt/nmt-newt-section.h \ + src/libnmt-newt/nmt-newt-separator.c \ + src/libnmt-newt/nmt-newt-separator.h \ + src/libnmt-newt/nmt-newt-stack.c \ + src/libnmt-newt/nmt-newt-stack.h \ + src/libnmt-newt/nmt-newt-textbox.c \ + src/libnmt-newt/nmt-newt-textbox.h \ + src/libnmt-newt/nmt-newt-toggle-button.c \ + src/libnmt-newt/nmt-newt-toggle-button.h \ + src/libnmt-newt/nmt-newt-types.h \ + src/libnmt-newt/nmt-newt-utils.c \ + src/libnmt-newt/nmt-newt-utils.h \ + src/libnmt-newt/nmt-newt-widget.c \ + src/libnmt-newt/nmt-newt-widget.h \ + src/libnmt-newt/nmt-newt.h \ + $(NULL) + +src_libnmt_newt_libnmt_newt_a_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""nmtui"\" \ $(NEWT_CFLAGS) \ $(NULL) -$(clients_tui_newt_libnmt_newt_a_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_libnmt_newt_libnmt_newt_a_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnmt_newt_libnmt_newt_a_OBJECTS): $(src_libnm_client_public_mkenums_h) + +endif -bin_PROGRAMS += clients/tui/nmtui +EXTRA_DIST += src/libnmt-newt/meson.build -clients_tui_nmtui_SOURCES = \ - clients/tui/nmtui.c \ - clients/tui/nmtui.h \ - clients/tui/nmtui-connect.c \ - clients/tui/nmtui-connect.h \ - clients/tui/nmtui-edit.c \ - clients/tui/nmtui-edit.h \ - clients/tui/nmtui-hostname.c \ - clients/tui/nmtui-hostname.h \ +############################################################################### +# src/nmtui +############################################################################### + +if BUILD_NMTUI + +bin_PROGRAMS += src/nmtui/nmtui + +src_nmtui_nmtui_SOURCES = \ + src/nmtui/nmtui.c \ + src/nmtui/nmtui.h \ + src/nmtui/nmtui-connect.c \ + src/nmtui/nmtui-connect.h \ + src/nmtui/nmtui-edit.c \ + src/nmtui/nmtui-edit.h \ + src/nmtui/nmtui-hostname.c \ + src/nmtui/nmtui-hostname.h \ \ - clients/tui/nm-editor-bindings.c \ - clients/tui/nm-editor-bindings.h \ - clients/tui/nm-editor-utils.c \ - clients/tui/nm-editor-utils.h \ + src/nmtui/nm-editor-bindings.c \ + src/nmtui/nm-editor-bindings.h \ + src/nmtui/nm-editor-utils.c \ + src/nmtui/nm-editor-utils.h \ \ - clients/tui/nmt-address-list.c \ - clients/tui/nmt-address-list.h \ - clients/tui/nmt-connect-connection-list.c \ - clients/tui/nmt-connect-connection-list.h \ - clients/tui/nmt-device-entry.c \ - clients/tui/nmt-device-entry.h \ - clients/tui/nmt-edit-connection-list.c \ - clients/tui/nmt-edit-connection-list.h \ - clients/tui/nmt-editor-grid.c \ - clients/tui/nmt-editor-grid.h \ - clients/tui/nmt-editor-page.c \ - clients/tui/nmt-editor-page.h \ - clients/tui/nmt-editor-page-device.c \ - clients/tui/nmt-editor-page-device.h \ - clients/tui/nmt-editor-section.c \ - clients/tui/nmt-editor-section.h \ - clients/tui/nmt-editor.c \ - clients/tui/nmt-editor.h \ - clients/tui/nmt-ip-entry.c \ - clients/tui/nmt-ip-entry.h \ - clients/tui/nmt-mac-entry.c \ - clients/tui/nmt-mac-entry.h \ - clients/tui/nmt-mtu-entry.c \ - clients/tui/nmt-mtu-entry.h \ - clients/tui/nmt-page-bond.c \ - clients/tui/nmt-page-bond.h \ - clients/tui/nmt-page-bridge.c \ - clients/tui/nmt-page-bridge.h \ - clients/tui/nmt-page-bridge-port.c \ - clients/tui/nmt-page-bridge-port.h \ - clients/tui/nmt-page-dsl.c \ - clients/tui/nmt-page-dsl.h \ - clients/tui/nmt-page-ethernet.c \ - clients/tui/nmt-page-ethernet.h \ - clients/tui/nmt-page-infiniband.c \ - clients/tui/nmt-page-infiniband.h \ - clients/tui/nmt-page-ip-tunnel.c \ - clients/tui/nmt-page-ip-tunnel.h \ - clients/tui/nmt-page-ip4.c \ - clients/tui/nmt-page-ip4.h \ - clients/tui/nmt-page-ip6.c \ - clients/tui/nmt-page-ip6.h \ - clients/tui/nmt-page-ppp.c \ - clients/tui/nmt-page-ppp.h \ - clients/tui/nmt-page-team.c \ - clients/tui/nmt-page-team.h \ - clients/tui/nmt-page-team-port.c \ - clients/tui/nmt-page-team-port.h \ - clients/tui/nmt-page-vlan.c \ - clients/tui/nmt-page-vlan.h \ - clients/tui/nmt-page-wifi.c \ - clients/tui/nmt-page-wifi.h \ - clients/tui/nmt-password-dialog.c \ - clients/tui/nmt-password-dialog.h \ - clients/tui/nmt-password-fields.c \ - clients/tui/nmt-password-fields.h \ - clients/tui/nmt-route-editor.c \ - clients/tui/nmt-route-editor.h \ - clients/tui/nmt-route-entry.c \ - clients/tui/nmt-route-entry.h \ - clients/tui/nmt-route-table.c \ - clients/tui/nmt-route-table.h \ - clients/tui/nmt-slave-list.c \ - clients/tui/nmt-slave-list.h \ - clients/tui/nmt-utils.c \ - clients/tui/nmt-utils.h \ - clients/tui/nmt-widget-list.c \ - clients/tui/nmt-widget-list.h \ - $(NULL) - -clients_tui_nmtui_CPPFLAGS = \ - -I$(srcdir)/clients/tui/newt \ + src/nmtui/nmt-address-list.c \ + src/nmtui/nmt-address-list.h \ + src/nmtui/nmt-connect-connection-list.c \ + src/nmtui/nmt-connect-connection-list.h \ + src/nmtui/nmt-device-entry.c \ + src/nmtui/nmt-device-entry.h \ + src/nmtui/nmt-edit-connection-list.c \ + src/nmtui/nmt-edit-connection-list.h \ + src/nmtui/nmt-editor-grid.c \ + src/nmtui/nmt-editor-grid.h \ + src/nmtui/nmt-editor-page.c \ + src/nmtui/nmt-editor-page.h \ + src/nmtui/nmt-editor-page-device.c \ + src/nmtui/nmt-editor-page-device.h \ + src/nmtui/nmt-editor-section.c \ + src/nmtui/nmt-editor-section.h \ + src/nmtui/nmt-editor.c \ + src/nmtui/nmt-editor.h \ + src/nmtui/nmt-ip-entry.c \ + src/nmtui/nmt-ip-entry.h \ + src/nmtui/nmt-mac-entry.c \ + src/nmtui/nmt-mac-entry.h \ + src/nmtui/nmt-mtu-entry.c \ + src/nmtui/nmt-mtu-entry.h \ + src/nmtui/nmt-page-bond.c \ + src/nmtui/nmt-page-bond.h \ + src/nmtui/nmt-page-bridge.c \ + src/nmtui/nmt-page-bridge.h \ + src/nmtui/nmt-page-bridge-port.c \ + src/nmtui/nmt-page-bridge-port.h \ + src/nmtui/nmt-page-dsl.c \ + src/nmtui/nmt-page-dsl.h \ + src/nmtui/nmt-page-ethernet.c \ + src/nmtui/nmt-page-ethernet.h \ + src/nmtui/nmt-page-infiniband.c \ + src/nmtui/nmt-page-infiniband.h \ + src/nmtui/nmt-page-ip-tunnel.c \ + src/nmtui/nmt-page-ip-tunnel.h \ + src/nmtui/nmt-page-ip4.c \ + src/nmtui/nmt-page-ip4.h \ + src/nmtui/nmt-page-ip6.c \ + src/nmtui/nmt-page-ip6.h \ + src/nmtui/nmt-page-ppp.c \ + src/nmtui/nmt-page-ppp.h \ + src/nmtui/nmt-page-team.c \ + src/nmtui/nmt-page-team.h \ + src/nmtui/nmt-page-team-port.c \ + src/nmtui/nmt-page-team-port.h \ + src/nmtui/nmt-page-vlan.c \ + src/nmtui/nmt-page-vlan.h \ + src/nmtui/nmt-page-wifi.c \ + src/nmtui/nmt-page-wifi.h \ + src/nmtui/nmt-password-dialog.c \ + src/nmtui/nmt-password-dialog.h \ + src/nmtui/nmt-password-fields.c \ + src/nmtui/nmt-password-fields.h \ + src/nmtui/nmt-route-editor.c \ + src/nmtui/nmt-route-editor.h \ + src/nmtui/nmt-route-entry.c \ + src/nmtui/nmt-route-entry.h \ + src/nmtui/nmt-route-table.c \ + src/nmtui/nmt-route-table.h \ + src/nmtui/nmt-slave-list.c \ + src/nmtui/nmt-slave-list.h \ + src/nmtui/nmt-utils.c \ + src/nmtui/nmt-utils.h \ + src/nmtui/nmt-widget-list.c \ + src/nmtui/nmt-widget-list.h \ + $(NULL) + +src_nmtui_nmtui_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""nmtui"\" \ $(NEWT_CFLAGS) \ $(NULL) -clients_tui_nmtui_LDFLAGS = \ +src_nmtui_nmtui_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) -clients_tui_nmtui_LDADD = \ - clients/tui/newt/libnmt-newt.a \ - clients/common/libnmc.la \ - clients/common/libnmc-base.la \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - libnm/libnm.la \ +src_nmtui_nmtui_LDADD = \ + src/libnmt-newt/libnmt-newt.a \ + src/libnmc-setting/libnmc-setting.la \ + src/libnmc-base/libnmc-base.la \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(NEWT_LIBS) \ $(NULL) -$(clients_tui_nmtui_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_nmtui_nmtui_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nmtui_nmtui_OBJECTS): $(src_libnm_client_public_mkenums_h) -nmtui_links = nmtui-edit nmtui-connect nmtui-hostname +nmtui_links = \ + nmtui-edit \ + nmtui-connect \ + nmtui-hostname \ + $(NULL) install-exec-hook-nmtui: for link in $(nmtui_links); do \ @@ -4983,88 +5054,84 @@ uninstall_hook += uninstall-hook-nmtui endif -EXTRA_DIST += \ - clients/tui/meson.build \ - clients/tui/newt/meson.build +EXTRA_DIST += src/nmtui/meson.build ############################################################################### -# clients/nm-cloud-setup +# src/nm-cloud-setup ############################################################################### if BUILD_NM_CLOUD_SETUP -noinst_LIBRARIES += clients/cloud-setup/libnm-cloud-setup-core.a +noinst_LIBRARIES += src/nm-cloud-setup/libnm-cloud-setup-core.a -clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES = \ - clients/cloud-setup/nm-cloud-setup-utils.c \ - clients/cloud-setup/nm-cloud-setup-utils.h \ - clients/cloud-setup/nm-http-client.c \ - clients/cloud-setup/nm-http-client.h \ - clients/cloud-setup/nmcs-provider.c \ - clients/cloud-setup/nmcs-provider.h \ - clients/cloud-setup/nmcs-provider-ec2.c \ - clients/cloud-setup/nmcs-provider-ec2.h \ - clients/cloud-setup/nmcs-provider-gcp.c \ - clients/cloud-setup/nmcs-provider-gcp.h \ - clients/cloud-setup/nmcs-provider-azure.c \ - clients/cloud-setup/nmcs-provider-azure.h \ +src_nm_cloud_setup_libnm_cloud_setup_core_a_SOURCES = \ + src/nm-cloud-setup/nm-cloud-setup-utils.c \ + src/nm-cloud-setup/nm-cloud-setup-utils.h \ + src/nm-cloud-setup/nm-http-client.c \ + src/nm-cloud-setup/nm-http-client.h \ + src/nm-cloud-setup/nmcs-provider.c \ + src/nm-cloud-setup/nmcs-provider.h \ + src/nm-cloud-setup/nmcs-provider-ec2.c \ + src/nm-cloud-setup/nmcs-provider-ec2.h \ + src/nm-cloud-setup/nmcs-provider-gcp.c \ + src/nm-cloud-setup/nmcs-provider-gcp.h \ + src/nm-cloud-setup/nmcs-provider-azure.c \ + src/nm-cloud-setup/nmcs-provider-azure.h \ $(NULL) -clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS = \ +src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""nm-cloud-setup"\" \ $(LIBCURL_CFLAGS) \ $(NULL) -$(clients_cloud_setup_libnm_cloud_setup_core_a_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_cloud_setup_libnm_cloud_setup_core_a_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_nm_cloud_setup_libnm_cloud_setup_core_a_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_cloud_setup_libnm_cloud_setup_core_a_OBJECTS): $(src_libnm_client_public_mkenums_h) -libexec_PROGRAMS += clients/cloud-setup/nm-cloud-setup +libexec_PROGRAMS += src/nm-cloud-setup/nm-cloud-setup -clients_cloud_setup_nm_cloud_setup_SOURCES = \ - clients/cloud-setup/main.c \ +src_nm_cloud_setup_nm_cloud_setup_SOURCES = \ + src/nm-cloud-setup/main.c \ $(NULL) -clients_cloud_setup_nm_cloud_setup_CPPFLAGS = \ +src_nm_cloud_setup_nm_cloud_setup_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""nm-cloud-setup"\" \ $(LIBCURL_CFLAGS) \ $(NULL) -clients_cloud_setup_nm_cloud_setup_LDFLAGS = \ +src_nm_cloud_setup_nm_cloud_setup_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -clients_cloud_setup_nm_cloud_setup_LDADD = \ - clients/cloud-setup/libnm-cloud-setup-core.a \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - libnm/libnm.la \ +src_nm_cloud_setup_nm_cloud_setup_LDADD = \ + src/nm-cloud-setup/libnm-cloud-setup-core.a \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(LIBCURL_LIBS) \ $(NULL) -$(clients_cloud_setup_nm_cloud_setup_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_cloud_setup_nm_cloud_setup_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_nm_cloud_setup_nm_cloud_setup_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_cloud_setup_nm_cloud_setup_OBJECTS): $(src_libnm_client_public_mkenums_h) if HAVE_SYSTEMD systemdsystemunit_DATA += \ - clients/cloud-setup/nm-cloud-setup.service \ - clients/cloud-setup/nm-cloud-setup.timer \ + src/nm-cloud-setup/nm-cloud-setup.service \ + src/nm-cloud-setup/nm-cloud-setup.timer \ $(NULL) -clients/cloud-setup/nm-cloud-setup.service: $(srcdir)/clients/cloud-setup/nm-cloud-setup.service.in +src/nm-cloud-setup/nm-cloud-setup.service: $(srcdir)/src/nm-cloud-setup/nm-cloud-setup.service.in $(AM_V_GEN) $(data_edit) $< >$@ install-data-hook-cloud-setup: install-data-hook-dispatcher - $(INSTALL_SCRIPT) "$(srcdir)/clients/cloud-setup/90-nm-cloud-setup.sh" "$(DESTDIR)$(nmlibdir)/dispatcher.d/no-wait.d/" + $(INSTALL_SCRIPT) "$(srcdir)/src/nm-cloud-setup/90-nm-cloud-setup.sh" "$(DESTDIR)$(nmlibdir)/dispatcher.d/no-wait.d/" ln -fs no-wait.d/90-nm-cloud-setup.sh "$(DESTDIR)$(nmlibdir)/dispatcher.d/90-nm-cloud-setup.sh" install_data_hook += install-data-hook-cloud-setup @@ -5078,77 +5145,71 @@ uninstall_hook += uninstall-hook-cloud-setup endif EXTRA_DIST += \ - clients/cloud-setup/90-nm-cloud-setup.sh \ - clients/cloud-setup/meson.build \ - clients/cloud-setup/nm-cloud-setup.service.in \ - clients/cloud-setup/nm-cloud-setup.timer \ - clients/cloud-setup/tests/meson.build \ + src/nm-cloud-setup/90-nm-cloud-setup.sh \ + src/nm-cloud-setup/meson.build \ + src/nm-cloud-setup/nm-cloud-setup.service.in \ + src/nm-cloud-setup/nm-cloud-setup.timer \ + src/nm-cloud-setup/tests/meson.build \ $(NULL) CLEANFILES += \ - clients/cloud-setup/nm-cloud-setup.service + src/nm-cloud-setup/nm-cloud-setup.service -check_programs += clients/cloud-setup/tests/test-cloud-setup-general +check_programs += src/nm-cloud-setup/tests/test-cloud-setup-general -clients_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS = \ +src_nm_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS = \ $(clients_cppflags) \ - -I$(srcdir)/clients/cloud-setup \ - -DG_LOG_DOMAIN=\""tests"\" \ $(LIBCURL_CFLAGS) \ $(NULL) -clients_cloud_setup_tests_test_cloud_setup_general_LDFLAGS = \ +src_nm_cloud_setup_tests_test_cloud_setup_general_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -clients_cloud_setup_tests_test_cloud_setup_general_LDADD = \ - clients/cloud-setup/libnm-cloud-setup-core.a \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - libnm/libnm.la \ +src_nm_cloud_setup_tests_test_cloud_setup_general_LDADD = \ + src/nm-cloud-setup/libnm-cloud-setup-core.a \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(LIBCURL_LIBS) \ $(NULL) -$(clients_cloud_setup_tests_test_cloud_setup_general_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_cloud_setup_tests_test_cloud_setup_general_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_nm_cloud_setup_tests_test_cloud_setup_general_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_cloud_setup_tests_test_cloud_setup_general_OBJECTS): $(src_libnm_client_public_mkenums_h) endif ############################################################################### -# clients/tests +# src/tests/client ############################################################################### -check-local-clients-tests-test-client: clients/cli/nmcli clients/tests/test-client.py - mkdir -p "$(builddir)/clients/tests/" - "$(builddir)/clients/cli/nmcli" --version - GI_TYPELIB_PATH="$(abs_builddir)/libnm$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}" \ - LD_LIBRARY_PATH="$(abs_builddir)/libnm/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}" \ - NM_TEST_CLIENT_BUILDDIR="$(abs_builddir)" \ - NM_TEST_CLIENT_NMCLI_PATH=clients/cli/nmcli \ - "$(PYTHON)" \ - $(srcdir)/clients/tests/test-client.py -v &> "$(builddir)/clients/tests/test-client.log" && r=ok; \ - cat "$(builddir)/clients/tests/test-client.log"; \ - test "$$r" = ok +check-local-tests-client: src/nmcli/nmcli src/tests/client/test-client.py + "$(srcdir)/src/tests/client/test-client.sh" "$(builddir)" "$(srcdir)" "$(PYTHON)" -check_local += check-local-clients-tests-test-client +check_local += check-local-tests-client -CLEANFILES += clients/tests/test-client.log +CLEANFILES += src/tests/client/test-client.log EXTRA_DIST += \ - clients/tests/test-client.py \ - clients/tests/test-client.check-on-disk/test_001.expected \ - clients/tests/test-client.check-on-disk/test_002.expected \ - clients/tests/test-client.check-on-disk/test_003.expected \ - clients/tests/test-client.check-on-disk/test_004.expected \ + src/tests/client/test-client.sh \ + src/tests/client/test-client.py \ + src/tests/client/test-client.check-on-disk/test_001.expected \ + src/tests/client/test-client.check-on-disk/test_002.expected \ + src/tests/client/test-client.check-on-disk/test_003.expected \ + src/tests/client/test-client.check-on-disk/test_004.expected \ + \ + src/tests/client/meson.build \ $(NULL) +############################################################################### + check-local-gitlab-ci: "$(srcdir)/tools/check-gitlab-ci.sh" "$(srcdir)" @@ -5259,9 +5320,9 @@ if HAVE_INTROSPECTION man/nm-settings-%.xml: man/nm-settings-%.xsl man/nm-settings-docs-%.xml man/common.ent $(AM_V_GEN) $(XSLTPROC) --output $@ $(xsltproc_flags) $< $(word 2,$^) -man/nm-settings-keyfile.xml: man/nm-settings-keyfile.xsl libnm/nm-property-infos-keyfile.xml man/common.ent +man/nm-settings-keyfile.xml: man/nm-settings-keyfile.xsl src/libnm-client-impl/nm-property-infos-keyfile.xml man/common.ent $(AM_V_GEN) $(XSLTPROC) --output $@ $(xsltproc_flags) $< $(word 2,$^) -man/nm-settings-ifcfg-rh.xml: man/nm-settings-ifcfg-rh.xsl libnm/nm-property-infos-ifcfg-rh.xml man/common.ent +man/nm-settings-ifcfg-rh.xml: man/nm-settings-ifcfg-rh.xsl src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml man/common.ent $(AM_V_GEN) $(XSLTPROC) --output $@ $(xsltproc_flags) $< $(word 2,$^) CLEANFILES += $(man_nm_settings_xml) @@ -5270,12 +5331,14 @@ endif man_pages += \ man/NetworkManager.8 \ + man/NetworkManager-dispatcher.8 \ man/NetworkManager.conf.5 \ man/nm-online.1 \ man/nm-initrd-generator.8 \ man/nmcli-examples.7 \ man/nmcli.1 \ - man/nmtui.1 + man/nmtui.1 \ + $(NULL) man_pages_autogen += \ man/nm-settings-dbus.5 \ @@ -5362,10 +5425,10 @@ if ENABLE_VAPIGEN VAPIGEN_VAPIS += \ vapi/libnm.vapi -vapi/libnm.vapi: $(builddir)/libnm/NM-1.0.gir vapi/libnm.deps vapi/NM-1.0.metadata +vapi/libnm.vapi: $(builddir)/src/libnm-client-impl/NM-1.0.gir vapi/libnm.deps vapi/NM-1.0.metadata vapi_libnm_vapi_METADATADIRS = $(srcdir)/vapi -vapi_libnm_vapi_FILES = $(builddir)/libnm/NM-1.0.gir +vapi_libnm_vapi_FILES = $(builddir)/src/libnm-client-impl/NM-1.0.gir vapi_libnm_vapi_DEPS = gio-2.0 vapi_DATA += \ @@ -5409,7 +5472,7 @@ plugin_LTLIBRARIES += $(core_plugins) TESTS += $(check_programs) EXTRA_DIST += \ - CONTRIBUTING \ + CONTRIBUTING.md \ COPYING.LGPL \ COPYING.GFDL \ \ @@ -5433,18 +5496,11 @@ EXTRA_DIST += \ \ po/meson.build \ \ - shared/nm-test-libnm-utils.h \ - shared/nm-test-utils-impl.c \ - shared/nm-utils/nm-compat.c \ - shared/nm-utils/nm-compat.h \ - shared/nm-utils/nm-test-utils.h \ - shared/nm-utils/nm-vpn-editor-plugin-call.h \ - shared/nm-utils/nm-vpn-plugin-macros.h \ - shared/nm-utils/nm-vpn-plugin-utils.c \ - shared/nm-utils/nm-vpn-plugin-utils.h \ - shared/meson.build \ + src/meson.build \ + \ + src/libnm-core-public/nm-version-macros.h.in \ \ - libnm-core/nm-version-macros.h.in \ + src/contrib/nm-vpn-editor-plugin-call.h \ \ tools/check-config-options.sh \ tools/check-docs.sh \ @@ -5521,7 +5577,7 @@ uninstall-hook: $(uninstall_hook) ############################################################################### cscope: - cscope -b -q -R -sshared -ssrc -slibnm-core -slibnm -sclients; + cscope -b -q -R -sshared -ssrc -slibnm -sclients; ############################################################################### diff --git a/Makefile.examples b/Makefile.examples index 3cb4629..437b1e0 100644 --- a/Makefile.examples +++ b/Makefile.examples @@ -3,12 +3,10 @@ ############################################################################### examples_C_glib_cppflags = \ - -I$(top_srcdir)/shared \ - -I$(top_builddir)/shared \ - -I$(top_srcdir)/libnm-core \ - -I$(top_builddir)/libnm-core \ - -I$(top_srcdir)/libnm \ - -I$(top_builddir)/libnm \ + -I$(top_srcdir)/src/libnm-core-public \ + -I$(top_builddir)/src/libnm-core-public \ + -I$(top_srcdir)/src/libnm-client-public \ + -I$(top_builddir)/src/libnm-client-public \ $(GLIB_CFLAGS) examples_C_glib_cppflags_gdbus = $(examples_C_glib_cppflags) @@ -22,30 +20,32 @@ check_programs_norun += \ examples/C/glib/list-connections-gdbus \ examples/C/glib/list-connections-libnm \ examples/C/glib/monitor-nm-running-gdbus \ - examples/C/glib/monitor-nm-state-gdbus + examples/C/glib/monitor-nm-state-gdbus \ + examples/C/glib/vpn-import-libnm \ + $(NULL) examples_C_glib_add_connection_gdbus_CPPFLAGS = $(examples_C_glib_cppflags_gdbus) examples_C_glib_add_connection_gdbus_LDADD = \ $(GLIB_LIBS) \ $(UUID_LIBS) -$(examples_C_glib_add_connection_gdbus_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(examples_C_glib_add_connection_gdbus_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) examples_C_glib_add_connection_libnm_CPPFLAGS = $(examples_C_glib_cppflags_libnm) examples_C_glib_add_connection_libnm_LDADD = \ - libnm/libnm.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) -$(examples_C_glib_add_connection_libnm_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(examples_C_glib_add_connection_libnm_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) examples_C_glib_get_active_connections_gdbus_CPPFLAGS = $(examples_C_glib_cppflags_gdbus) examples_C_glib_get_active_connections_gdbus_LDADD = \ $(GLIB_LIBS) -$(examples_C_glib_get_active_connections_gdbus_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(examples_C_glib_get_active_connections_gdbus_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) examples_C_glib_get_ap_info_libnm_CPPFLAGS = $(examples_C_glib_cppflags_libnm) examples_C_glib_get_ap_info_libnm_LDADD = \ - libnm/libnm.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) -$(examples_C_glib_get_ap_info_libnm_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(examples_C_glib_get_ap_info_libnm_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) examples_C_glib_list_connections_gdbus_CPPFLAGS = $(examples_C_glib_cppflags_gdbus) examples_C_glib_list_connections_gdbus_LDADD = \ @@ -53,9 +53,9 @@ examples_C_glib_list_connections_gdbus_LDADD = \ examples_C_glib_list_connections_libnm_CPPFLAGS = $(examples_C_glib_cppflags_libnm) examples_C_glib_list_connections_libnm_LDADD = \ - libnm/libnm.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) -$(examples_C_glib_list_connections_libnm_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(examples_C_glib_list_connections_libnm_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) examples_C_glib_monitor_nm_running_gdbus_CPPFLAGS = $(examples_C_glib_cppflags_gdbus) examples_C_glib_monitor_nm_running_gdbus_LDADD = \ @@ -65,6 +65,12 @@ examples_C_glib_monitor_nm_state_gdbus_CPPFLAGS = $(examples_C_glib_cppflags_gdb examples_C_glib_monitor_nm_state_gdbus_LDADD = \ $(GLIB_LIBS) +examples_C_glib_vpn_import_libnm_CPPFLAGS = $(examples_C_glib_cppflags_libnm) +examples_C_glib_vpn_import_libnm_LDADD = \ + src/libnm-client-impl/libnm.la \ + $(GLIB_LIBS) +$(examples_C_glib_vpn_import_libnm_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) + EXTRA_DIST += \ examples/C/glib/meson.build @@ -75,8 +81,10 @@ EXTRA_DIST += \ if WITH_QT examples_C_qt_cppflags = \ - -I$(top_srcdir)/libnm-core \ - -I$(top_builddir)/libnm-core \ + -I$(top_builddir)/src/libnm-core-public \ + -I$(top_srcdir)/src/libnm-core-public \ + -I$(top_builddir)/libnm \ + -I$(top_srcdir)/libnm \ -I$(builddir)/examples/C/qt \ $(DBUS_CFLAGS) \ $(QT_CFLAGS) diff --git a/Makefile.in b/Makefile.in index 1aa0d70..3f8ff73 100644 --- a/Makefile.in +++ b/Makefile.in @@ -136,44 +136,45 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = src/core/NetworkManager-all-sym$(EXEEXT) \ - clients/cli/generate-docs-nm-settings-nmcli$(EXEEXT) \ - $(am__EXEEXT_20) -check_PROGRAMS = $(am__EXEEXT_18) + src/nmcli/generate-docs-nm-settings-nmcli$(EXEEXT) \ + $(am__EXEEXT_18) +check_PROGRAMS = $(am__EXEEXT_16) sbin_PROGRAMS = src/core/NetworkManager$(EXEEXT) -bin_PROGRAMS = clients/nm-online$(EXEEXT) $(am__EXEEXT_1) \ +bin_PROGRAMS = src/nm-online/nm-online$(EXEEXT) $(am__EXEEXT_1) \ $(am__EXEEXT_2) libexec_PROGRAMS = src/core/nm-iface-helper$(EXEEXT) \ - src/core/initrd/nm-initrd-generator$(EXEEXT) \ + src/nm-initrd-generator/nm-initrd-generator$(EXEEXT) \ src/core/dhcp/nm-dhcp-helper$(EXEEXT) \ - dispatcher/nm-dispatcher$(EXEEXT) $(am__EXEEXT_19) -TESTS = $(am__EXEEXT_13) + src/nm-dispatcher/nm-dispatcher$(EXEEXT) $(am__EXEEXT_17) +TESTS = $(am__EXEEXT_11) @HAVE_DOCS_TRUE@am__append_1 = \ @HAVE_DOCS_TRUE@ docs/libnm \ @HAVE_DOCS_TRUE@ docs/api @BUILD_DOCS_FALSE@am__append_2 = dist-configure-check -@WITH_EBPF_TRUE@am__append_3 = shared/n-acd/src/n-acd-bpf.c -@WITH_EBPF_FALSE@am__append_4 = shared/n-acd/src/n-acd-bpf-fallback.c +@WITH_EBPF_TRUE@am__append_3 = src/n-acd/src/n-acd-bpf.c +@WITH_EBPF_FALSE@am__append_4 = src/n-acd/src/n-acd-bpf-fallback.c +@WITH_WEXT_TRUE@am__append_5 = \ +@WITH_WEXT_TRUE@ src/libnm-platform/wifi/nm-wifi-utils-wext.c \ +@WITH_WEXT_TRUE@ src/libnm-platform/wifi/nm-wifi-utils-wext.h \ +@WITH_WEXT_TRUE@ $(NULL) + ############################################################################### -@WITH_JANSSON_TRUE@am__append_5 = shared/nm-glib-aux/tests/test-json-aux -@HAVE_CRYPTO_GNUTLS_TRUE@@WITH_GNUTLS_FALSE@am__append_6 = libnm-core/libnm-crypto-gnutls.la -@HAVE_CRYPTO_NSS_TRUE@@WITH_NSS_FALSE@am__append_7 = libnm-core/libnm-crypto-nss.la -@HAVE_INTROSPECTION_TRUE@am__append_8 = libnm/NM-1.0.typelib -@HAVE_INTROSPECTION_TRUE@am__append_9 = libnm/NM-1.0.gir -@HAVE_INTROSPECTION_TRUE@am__append_10 = $(libnm_noinst_data) -@HAVE_INTROSPECTION_TRUE@am__append_11 = clients/cli/generate-docs-nm-settings-nmcli.xml.in \ +@WITH_JANSSON_TRUE@am__append_6 = src/libnm-glib-aux/tests/test-json-aux +@HAVE_CRYPTO_GNUTLS_TRUE@@WITH_GNUTLS_FALSE@am__append_7 = src/libnm-core-impl/libnm-crypto-gnutls.la +@HAVE_CRYPTO_NSS_TRUE@@WITH_NSS_FALSE@am__append_8 = src/libnm-core-impl/libnm-crypto-nss.la +@HAVE_INTROSPECTION_TRUE@am__append_9 = src/libnm-client-impl/NM-1.0.typelib +@HAVE_INTROSPECTION_TRUE@am__append_10 = src/libnm-client-impl/NM-1.0.gir +@HAVE_INTROSPECTION_TRUE@am__append_11 = $(libnm_noinst_data) +@HAVE_INTROSPECTION_TRUE@am__append_12 = src/nmcli/generate-docs-nm-settings-nmcli.xml.in \ @HAVE_INTROSPECTION_TRUE@ $(libnm_noinst_data) -@BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@am__append_12 = check-local-generate-docs-nm-settings-nmcli -@BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@am__append_13 = clients/cli/generate-docs-nm-settings-nmcli.xml -@HAVE_INTROSPECTION_TRUE@am__append_14 = $(libnm_noinst_data) -@HAVE_INTROSPECTION_TRUE@am__append_15 = $(libnm_tests_programs_req_introspection) -@HAVE_INTROSPECTION_FALSE@am__append_16 = $(libnm_tests_programs_req_introspection) -@REQUIRE_ROOT_TESTS_TRUE@am__append_17 = -DREQUIRE_ROOT_TESTS=1 -@WITH_WEXT_TRUE@am__append_18 = \ -@WITH_WEXT_TRUE@ src/core/platform/wifi/nm-wifi-utils-wext.c \ -@WITH_WEXT_TRUE@ src/core/platform/wifi/nm-wifi-utils-wext.h - +@BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@am__append_13 = check-local-generate-docs-nm-settings-nmcli +@BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@am__append_14 = src/nmcli/generate-docs-nm-settings-nmcli.xml +@HAVE_INTROSPECTION_TRUE@am__append_15 = $(libnm_noinst_data) +@HAVE_INTROSPECTION_TRUE@am__append_16 = $(src_libnm_client_impl_tests_programs_req_introspection) +@HAVE_INTROSPECTION_FALSE@am__append_17 = $(src_libnm_client_impl_tests_programs_req_introspection) +@REQUIRE_ROOT_TESTS_TRUE@am__append_18 = -DREQUIRE_ROOT_TESTS=1 ############################################################################### # src/core/ppp @@ -265,104 +266,104 @@ TESTS = $(am__EXEEXT_13) @WITH_TEAMDCTL_TRUE@am__append_47 = src/core/devices/team/libnm-device-plugin-team.la @WITH_TEAMDCTL_TRUE@am__append_48 = check-local-devices-team @WITH_OPENVSWITCH_TRUE@am__append_49 = src/core/devices/ovs/libnm-device-plugin-ovs.la -@BUILD_DOCS_TRUE@am__append_50 = $(clients_common_settings_doc_h) +@BUILD_DOCS_TRUE@am__append_50 = $(libnmc_setting_settings_doc_h) @BUILD_DOCS_TRUE@am__append_51 = check-local-settings-docs -@HAVE_INTROSPECTION_TRUE@am__append_52 = clients/common/libnmc.la -@HAVE_INTROSPECTION_FALSE@am__append_53 = clients/common/libnmc.la -@HAVE_INTROSPECTION_TRUE@am__append_54 = clients/common/tests/test-clients-common -@BUILD_NMCLI_TRUE@@HAVE_INTROSPECTION_FALSE@am__append_55 = clients/common/tests/test-clients-common ############################################################################### -# clients/cli +# src/nmcli +############################################################################### +@BUILD_NMCLI_TRUE@am__append_52 = src/nmcli/nmcli +@BUILD_NMCLI_TRUE@am__append_53 = install-data-hook-nmcli +@BUILD_NMCLI_TRUE@am__append_54 = uninstall-hook-nmcli + +############################################################################### +# src/libnmt-newt ############################################################################### -@BUILD_NMCLI_TRUE@am__append_56 = clients/cli/nmcli -@BUILD_NMCLI_TRUE@am__append_57 = install-data-hook-nmcli -@BUILD_NMCLI_TRUE@am__append_58 = uninstall-hook-nmcli +@BUILD_NMTUI_TRUE@am__append_55 = src/libnmt-newt/libnmt-newt.a ############################################################################### -# clients/tui +# src/nmtui ############################################################################### -@BUILD_NMTUI_TRUE@am__append_59 = clients/tui/newt/libnmt-newt.a -@BUILD_NMTUI_TRUE@am__append_60 = clients/tui/nmtui -@BUILD_NMTUI_TRUE@am__append_61 = install-exec-hook-nmtui -@BUILD_NMTUI_TRUE@am__append_62 = uninstall-hook-nmtui +@BUILD_NMTUI_TRUE@am__append_56 = src/nmtui/nmtui +@BUILD_NMTUI_TRUE@am__append_57 = install-exec-hook-nmtui +@BUILD_NMTUI_TRUE@am__append_58 = uninstall-hook-nmtui ############################################################################### -# clients/nm-cloud-setup +# src/nm-cloud-setup ############################################################################### -@BUILD_NM_CLOUD_SETUP_TRUE@am__append_63 = clients/cloud-setup/libnm-cloud-setup-core.a -@BUILD_NM_CLOUD_SETUP_TRUE@am__append_64 = clients/cloud-setup/nm-cloud-setup -@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@am__append_65 = \ -@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ clients/cloud-setup/nm-cloud-setup.service \ -@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ clients/cloud-setup/nm-cloud-setup.timer \ +@BUILD_NM_CLOUD_SETUP_TRUE@am__append_59 = src/nm-cloud-setup/libnm-cloud-setup-core.a +@BUILD_NM_CLOUD_SETUP_TRUE@am__append_60 = src/nm-cloud-setup/nm-cloud-setup +@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@am__append_61 = \ +@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ src/nm-cloud-setup/nm-cloud-setup.service \ +@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ src/nm-cloud-setup/nm-cloud-setup.timer \ @BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ $(NULL) -@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@am__append_66 = install-data-hook-cloud-setup -@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@am__append_67 = uninstall-hook-cloud-setup -@BUILD_NM_CLOUD_SETUP_TRUE@am__append_68 = \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/90-nm-cloud-setup.sh \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/meson.build \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nm-cloud-setup.service.in \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nm-cloud-setup.timer \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/tests/meson.build \ +@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@am__append_62 = install-data-hook-cloud-setup +@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@am__append_63 = uninstall-hook-cloud-setup +@BUILD_NM_CLOUD_SETUP_TRUE@am__append_64 = \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/90-nm-cloud-setup.sh \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/meson.build \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nm-cloud-setup.service.in \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nm-cloud-setup.timer \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/tests/meson.build \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(NULL) -@BUILD_NM_CLOUD_SETUP_TRUE@am__append_69 = \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nm-cloud-setup.service +@BUILD_NM_CLOUD_SETUP_TRUE@am__append_65 = \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nm-cloud-setup.service -@BUILD_NM_CLOUD_SETUP_TRUE@am__append_70 = clients/cloud-setup/tests/test-cloud-setup-general +@BUILD_NM_CLOUD_SETUP_TRUE@am__append_66 = src/nm-cloud-setup/tests/test-cloud-setup-general ############################################################################### # data ############################################################################### -@HAVE_SYSTEMD_TRUE@am__append_71 = \ +@HAVE_SYSTEMD_TRUE@am__append_67 = \ @HAVE_SYSTEMD_TRUE@ data/NetworkManager.service \ @HAVE_SYSTEMD_TRUE@ data/NetworkManager-wait-online.service \ @HAVE_SYSTEMD_TRUE@ data/NetworkManager-dispatcher.service \ @HAVE_SYSTEMD_TRUE@ $(NULL) -@HAVE_INTROSPECTION_TRUE@am__append_72 = $(man_nm_settings_xml) -@CONFIG_PLUGIN_IFCFG_RH_TRUE@am__append_73 = man/nm-settings-ifcfg-rh.5 -@CONFIG_PLUGIN_IFCFG_RH_FALSE@am__append_74 = man/nm-settings-ifcfg-rh.5 -@CONFIG_PLUGIN_IFCFG_RH_FALSE@am__append_75 = man/nm-settings-ifcfg-rh.5 -@WITH_OPENVSWITCH_TRUE@am__append_76 = man/nm-openvswitch.7 -@WITH_OPENVSWITCH_FALSE@am__append_77 = man/nm-openvswitch.7 -@WITH_OPENVSWITCH_FALSE@am__append_78 = man/nm-openvswitch.7 -@BUILD_NM_CLOUD_SETUP_TRUE@am__append_79 = man/nm-cloud-setup.8 -@BUILD_NM_CLOUD_SETUP_FALSE@am__append_80 = man/nm-cloud-setup.8 -@BUILD_NM_CLOUD_SETUP_FALSE@am__append_81 = man/nm-cloud-setup.8 -@HAVE_DOCS_TRUE@am__append_82 = install-data-hook-man -@HAVE_DOCS_TRUE@am__append_83 = uninstall-hook-man -@HAVE_DOCS_TRUE@am__append_84 = $(man_pages) $(man_pages_autogen) -@BUILD_DOCS_TRUE@am__append_85 = $(man_pages) $(man_pages_autogen) +@HAVE_INTROSPECTION_TRUE@am__append_68 = $(man_nm_settings_xml) +@CONFIG_PLUGIN_IFCFG_RH_TRUE@am__append_69 = man/nm-settings-ifcfg-rh.5 +@CONFIG_PLUGIN_IFCFG_RH_FALSE@am__append_70 = man/nm-settings-ifcfg-rh.5 +@CONFIG_PLUGIN_IFCFG_RH_FALSE@am__append_71 = man/nm-settings-ifcfg-rh.5 +@WITH_OPENVSWITCH_TRUE@am__append_72 = man/nm-openvswitch.7 +@WITH_OPENVSWITCH_FALSE@am__append_73 = man/nm-openvswitch.7 +@WITH_OPENVSWITCH_FALSE@am__append_74 = man/nm-openvswitch.7 +@BUILD_NM_CLOUD_SETUP_TRUE@am__append_75 = man/nm-cloud-setup.8 +@BUILD_NM_CLOUD_SETUP_FALSE@am__append_76 = man/nm-cloud-setup.8 +@BUILD_NM_CLOUD_SETUP_FALSE@am__append_77 = man/nm-cloud-setup.8 +@HAVE_DOCS_TRUE@am__append_78 = install-data-hook-man +@HAVE_DOCS_TRUE@am__append_79 = uninstall-hook-man +@HAVE_DOCS_TRUE@am__append_80 = $(man_pages) $(man_pages_autogen) +@BUILD_DOCS_TRUE@am__append_81 = $(man_pages) $(man_pages_autogen) ############################################################################### # vapi ############################################################################### -@ENABLE_VAPIGEN_TRUE@am__append_86 = \ +@ENABLE_VAPIGEN_TRUE@am__append_82 = \ @ENABLE_VAPIGEN_TRUE@ vapi/libnm.vapi -@ENABLE_VAPIGEN_TRUE@am__append_87 = \ +@ENABLE_VAPIGEN_TRUE@am__append_83 = \ @ENABLE_VAPIGEN_TRUE@ $(VAPIGEN_VAPIS) \ @ENABLE_VAPIGEN_TRUE@ $(VAPIGEN_VAPIS:.vapi=.deps) -@ENABLE_VAPIGEN_TRUE@am__append_88 = $(VAPIGEN_VAPIS) +@ENABLE_VAPIGEN_TRUE@am__append_84 = $(VAPIGEN_VAPIS) ############################################################################### -@ENABLE_TESTS_TRUE@am__append_89 = $(check_programs) $(check_programs_norun) -@ENABLE_TESTS_TRUE@am__append_90 = $(check_ltlibraries) -@ENABLE_TESTS_FALSE@am__append_91 = $(check_programs) $(check_programs_norun) -@ENABLE_TESTS_FALSE@am__append_92 = $(check_ltlibraries) -@WITH_QT_TRUE@am__append_93 = \ +@ENABLE_TESTS_TRUE@am__append_85 = $(check_programs) $(check_programs_norun) +@ENABLE_TESTS_TRUE@am__append_86 = $(check_ltlibraries) +@ENABLE_TESTS_FALSE@am__append_87 = $(check_programs) $(check_programs_norun) +@ENABLE_TESTS_FALSE@am__append_88 = $(check_ltlibraries) +@WITH_QT_TRUE@am__append_89 = \ @WITH_QT_TRUE@ examples/C/qt/add-connection-wired \ @WITH_QT_TRUE@ examples/C/qt/list-connections \ @WITH_QT_TRUE@ examples/C/qt/change-ipv4-addresses \ @WITH_QT_TRUE@ examples/C/qt/monitor-nm-running -@WITH_QT_TRUE@am__append_94 = \ +@WITH_QT_TRUE@am__append_90 = \ @WITH_QT_TRUE@ examples/C/qt/monitor-nm-running.moc -@WITH_PYTHON_BLACK_TRUE@am__append_95 = check-python-black +@WITH_PYTHON_BLACK_TRUE@am__append_91 = check-python-black subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ @@ -388,12 +389,12 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = libnm-core/nm-version-macros.h libnm/libnm.pc \ - data/org.freedesktop.NetworkManager.policy.in \ - NetworkManager.pc +CONFIG_CLEAN_FILES = data/org.freedesktop.NetworkManager.policy.in \ + NetworkManager.pc src/libnm-client-impl/libnm.pc \ + src/libnm-core-public/nm-version-macros.h CONFIG_CLEAN_VPATH_FILES = -@BUILD_NMCLI_TRUE@am__EXEEXT_1 = clients/cli/nmcli$(EXEEXT) -@BUILD_NMTUI_TRUE@am__EXEEXT_2 = clients/tui/nmtui$(EXEEXT) +@BUILD_NMCLI_TRUE@am__EXEEXT_1 = src/nmcli/nmcli$(EXEEXT) +@BUILD_NMTUI_TRUE@am__EXEEXT_2 = src/nmtui/nmtui$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" \ "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(libdir)" \ "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(pppd_plugindir)" \ @@ -408,31 +409,32 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" \ "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(typelibdir)" \ "$(DESTDIR)$(udevrulesdir)" "$(DESTDIR)$(vapidir)" \ "$(DESTDIR)$(libnmincludedir)" "$(DESTDIR)$(libnmincludedir)" -@WITH_JANSSON_TRUE@am__EXEEXT_3 = shared/nm-glib-aux/tests/test-json-aux$(EXEEXT) -am__EXEEXT_4 = libnm/tests/test-nm-client$(EXEEXT) \ - libnm/tests/test-remote-settings-client$(EXEEXT) \ - libnm/tests/test-secret-agent$(EXEEXT) +@WITH_JANSSON_TRUE@am__EXEEXT_3 = src/libnm-glib-aux/tests/test-json-aux$(EXEEXT) +am__EXEEXT_4 = src/libnm-client-impl/tests/test-nm-client$(EXEEXT) \ + src/libnm-client-impl/tests/test-remote-settings-client$(EXEEXT) \ + src/libnm-client-impl/tests/test-secret-agent$(EXEEXT) @HAVE_INTROSPECTION_TRUE@am__EXEEXT_5 = $(am__EXEEXT_4) @CONFIG_PLUGIN_IFCFG_RH_TRUE@am__EXEEXT_6 = src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh$(EXEEXT) @CONFIG_PLUGIN_IFUPDOWN_TRUE@am__EXEEXT_7 = src/core/settings/plugins/ifupdown/tests/test-ifupdown$(EXEEXT) @WITH_MODEM_MANAGER_1_TRUE@am__EXEEXT_8 = src/core/devices/wwan/tests/test-service-providers$(EXEEXT) @WITH_WIFI_TRUE@am__EXEEXT_9 = src/core/devices/wifi/tests/test-devices-wifi$(EXEEXT) -@HAVE_INTROSPECTION_TRUE@am__EXEEXT_10 = clients/common/tests/test-clients-common$(EXEEXT) -@BUILD_NMCLI_TRUE@@HAVE_INTROSPECTION_FALSE@am__EXEEXT_11 = clients/common/tests/test-clients-common$(EXEEXT) -@BUILD_NM_CLOUD_SETUP_TRUE@am__EXEEXT_12 = clients/cloud-setup/tests/test-cloud-setup-general$(EXEEXT) -am__EXEEXT_13 = shared/nm-platform/tests/test-nm-platform$(EXEEXT) \ - shared/nm-glib-aux/tests/test-shared-general$(EXEEXT) \ - $(am__EXEEXT_3) libnm-core/tests/test-compare$(EXEEXT) \ - libnm-core/tests/test-crypto$(EXEEXT) \ - libnm-core/tests/test-general$(EXEEXT) \ - libnm-core/tests/test-keyfile$(EXEEXT) \ - libnm-core/tests/test-secrets$(EXEEXT) \ - libnm-core/tests/test-setting$(EXEEXT) \ - libnm-core/tests/test-settings-defaults$(EXEEXT) \ - libnm/tests/test-libnm$(EXEEXT) $(am__EXEEXT_5) \ - src/core/initrd/tests/test-dt-reader$(EXEEXT) \ - src/core/initrd/tests/test-ibft-reader$(EXEEXT) \ - src/core/initrd/tests/test-cmdline-reader$(EXEEXT) \ +@BUILD_NM_CLOUD_SETUP_TRUE@am__EXEEXT_10 = src/nm-cloud-setup/tests/test-cloud-setup-general$(EXEEXT) +am__EXEEXT_11 = src/libnm-platform/tests/test-nm-platform$(EXEEXT) \ + src/libnm-client-aux-extern/tests/test-libnm-client-aux$(EXEEXT) \ + src/libnm-glib-aux/tests/test-shared-general$(EXEEXT) \ + $(am__EXEEXT_3) \ + src/libnm-core-impl/tests/test-compare$(EXEEXT) \ + src/libnm-core-impl/tests/test-crypto$(EXEEXT) \ + src/libnm-core-impl/tests/test-general$(EXEEXT) \ + src/libnm-core-impl/tests/test-keyfile$(EXEEXT) \ + src/libnm-core-impl/tests/test-secrets$(EXEEXT) \ + src/libnm-core-impl/tests/test-setting$(EXEEXT) \ + src/libnm-core-impl/tests/test-settings-defaults$(EXEEXT) \ + src/libnm-client-impl/tests/test-libnm$(EXEEXT) \ + $(am__EXEEXT_5) \ + src/nm-initrd-generator/tests/test-dt-reader$(EXEEXT) \ + src/nm-initrd-generator/tests/test-ibft-reader$(EXEEXT) \ + src/nm-initrd-generator/tests/test-cmdline-reader$(EXEEXT) \ src/core/dhcp/tests/test-dhcp-dhclient$(EXEEXT) \ src/core/dhcp/tests/test-dhcp-utils$(EXEEXT) \ src/core/settings/plugins/keyfile/tests/test-keyfile-settings$(EXEEXT) \ @@ -465,18 +467,17 @@ am__EXEEXT_13 = shared/nm-platform/tests/test-nm-platform$(EXEEXT) \ src/core/tests/test-systemd$(EXEEXT) \ src/core/tests/test-utils$(EXEEXT) \ src/core/tests/test-wired-defname$(EXEEXT) \ - dispatcher/tests/test-dispatcher-envp$(EXEEXT) \ - $(am__EXEEXT_10) $(am__EXEEXT_11) \ - clients/common/tests/test-libnm-core-aux$(EXEEXT) \ - $(am__EXEEXT_12) -@HAVE_INTROSPECTION_FALSE@am__EXEEXT_14 = $(am__EXEEXT_4) -@WITH_MODEM_MANAGER_1_TRUE@am__EXEEXT_15 = src/core/devices/bluetooth/tests/nm-bt-test$(EXEEXT) -@WITH_QT_TRUE@am__EXEEXT_16 = \ + src/nm-dispatcher/tests/test-dispatcher-envp$(EXEEXT) \ + src/libnmc-setting/tests/test-libnmc-setting$(EXEEXT) \ + $(am__EXEEXT_10) +@HAVE_INTROSPECTION_FALSE@am__EXEEXT_12 = $(am__EXEEXT_4) +@WITH_MODEM_MANAGER_1_TRUE@am__EXEEXT_13 = src/core/devices/bluetooth/tests/nm-bt-test$(EXEEXT) +@WITH_QT_TRUE@am__EXEEXT_14 = \ @WITH_QT_TRUE@ examples/C/qt/add-connection-wired$(EXEEXT) \ @WITH_QT_TRUE@ examples/C/qt/list-connections$(EXEEXT) \ @WITH_QT_TRUE@ examples/C/qt/change-ipv4-addresses$(EXEEXT) \ @WITH_QT_TRUE@ examples/C/qt/monitor-nm-running$(EXEEXT) -am__EXEEXT_17 = $(am__EXEEXT_14) $(am__EXEEXT_15) \ +am__EXEEXT_15 = $(am__EXEEXT_12) $(am__EXEEXT_13) \ src/core/platform/tests/monitor$(EXEEXT) \ src/core/ndisc/tests/test-ndisc-linux$(EXEEXT) \ examples/C/glib/add-connection-gdbus$(EXEEXT) \ @@ -487,10 +488,10 @@ am__EXEEXT_17 = $(am__EXEEXT_14) $(am__EXEEXT_15) \ examples/C/glib/list-connections-libnm$(EXEEXT) \ examples/C/glib/monitor-nm-running-gdbus$(EXEEXT) \ examples/C/glib/monitor-nm-state-gdbus$(EXEEXT) \ - $(am__EXEEXT_16) -@ENABLE_TESTS_FALSE@am__EXEEXT_18 = $(am__EXEEXT_13) $(am__EXEEXT_17) -@BUILD_NM_CLOUD_SETUP_TRUE@am__EXEEXT_19 = clients/cloud-setup/nm-cloud-setup$(EXEEXT) -@ENABLE_TESTS_TRUE@am__EXEEXT_20 = $(am__EXEEXT_13) $(am__EXEEXT_17) + examples/C/glib/vpn-import-libnm$(EXEEXT) $(am__EXEEXT_14) +@ENABLE_TESTS_FALSE@am__EXEEXT_16 = $(am__EXEEXT_11) $(am__EXEEXT_15) +@BUILD_NM_CLOUD_SETUP_TRUE@am__EXEEXT_17 = src/nm-cloud-setup/nm-cloud-setup$(EXEEXT) +@ENABLE_TESTS_TRUE@am__EXEEXT_18 = $(am__EXEEXT_11) $(am__EXEEXT_15) PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) $(noinst_PROGRAMS) \ $(sbin_PROGRAMS) LIBRARIES = $(noinst_LIBRARIES) @@ -528,129 +529,96 @@ AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = -clients_cloud_setup_libnm_cloud_setup_core_a_AR = $(AR) $(ARFLAGS) -clients_cloud_setup_libnm_cloud_setup_core_a_LIBADD = -am__clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES_DIST = \ - clients/cloud-setup/nm-cloud-setup-utils.c \ - clients/cloud-setup/nm-cloud-setup-utils.h \ - clients/cloud-setup/nm-http-client.c \ - clients/cloud-setup/nm-http-client.h \ - clients/cloud-setup/nmcs-provider.c \ - clients/cloud-setup/nmcs-provider.h \ - clients/cloud-setup/nmcs-provider-ec2.c \ - clients/cloud-setup/nmcs-provider-ec2.h \ - clients/cloud-setup/nmcs-provider-gcp.c \ - clients/cloud-setup/nmcs-provider-gcp.h \ - clients/cloud-setup/nmcs-provider-azure.c \ - clients/cloud-setup/nmcs-provider-azure.h +src_libnmt_newt_libnmt_newt_a_AR = $(AR) $(ARFLAGS) +src_libnmt_newt_libnmt_newt_a_LIBADD = +am__src_libnmt_newt_libnmt_newt_a_SOURCES_DIST = \ + src/libnmt-newt/nmt-newt-button-box.c \ + src/libnmt-newt/nmt-newt-button-box.h \ + src/libnmt-newt/nmt-newt-button.c \ + src/libnmt-newt/nmt-newt-button.h \ + src/libnmt-newt/nmt-newt-checkbox.c \ + src/libnmt-newt/nmt-newt-checkbox.h \ + src/libnmt-newt/nmt-newt-component.c \ + src/libnmt-newt/nmt-newt-component.h \ + src/libnmt-newt/nmt-newt-container.c \ + src/libnmt-newt/nmt-newt-container.h \ + src/libnmt-newt/nmt-newt-entry-numeric.c \ + src/libnmt-newt/nmt-newt-entry-numeric.h \ + src/libnmt-newt/nmt-newt-entry.c \ + src/libnmt-newt/nmt-newt-entry.h \ + src/libnmt-newt/nmt-newt-form.c \ + src/libnmt-newt/nmt-newt-form.h \ + src/libnmt-newt/nmt-newt-grid.c \ + src/libnmt-newt/nmt-newt-grid.h \ + src/libnmt-newt/nmt-newt-hacks.c \ + src/libnmt-newt/nmt-newt-hacks.h \ + src/libnmt-newt/nmt-newt-label.c \ + src/libnmt-newt/nmt-newt-label.h \ + src/libnmt-newt/nmt-newt-listbox.c \ + src/libnmt-newt/nmt-newt-listbox.h \ + src/libnmt-newt/nmt-newt-popup.c \ + src/libnmt-newt/nmt-newt-popup.h \ + src/libnmt-newt/nmt-newt-section.c \ + src/libnmt-newt/nmt-newt-section.h \ + src/libnmt-newt/nmt-newt-separator.c \ + src/libnmt-newt/nmt-newt-separator.h \ + src/libnmt-newt/nmt-newt-stack.c \ + src/libnmt-newt/nmt-newt-stack.h \ + src/libnmt-newt/nmt-newt-textbox.c \ + src/libnmt-newt/nmt-newt-textbox.h \ + src/libnmt-newt/nmt-newt-toggle-button.c \ + src/libnmt-newt/nmt-newt-toggle-button.h \ + src/libnmt-newt/nmt-newt-types.h \ + src/libnmt-newt/nmt-newt-utils.c \ + src/libnmt-newt/nmt-newt-utils.h \ + src/libnmt-newt/nmt-newt-widget.c \ + src/libnmt-newt/nmt-newt-widget.h src/libnmt-newt/nmt-newt.h am__dirstamp = $(am__leading_dot)dirstamp -@BUILD_NM_CLOUD_SETUP_TRUE@am_clients_cloud_setup_libnm_cloud_setup_core_a_OBJECTS = clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.$(OBJEXT) \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.$(OBJEXT) \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.$(OBJEXT) \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.$(OBJEXT) \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.$(OBJEXT) \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.$(OBJEXT) -clients_cloud_setup_libnm_cloud_setup_core_a_OBJECTS = \ - $(am_clients_cloud_setup_libnm_cloud_setup_core_a_OBJECTS) -clients_tui_newt_libnmt_newt_a_AR = $(AR) $(ARFLAGS) -clients_tui_newt_libnmt_newt_a_LIBADD = -am__clients_tui_newt_libnmt_newt_a_SOURCES_DIST = \ - clients/tui/newt/nmt-newt.h clients/tui/newt/nmt-newt-types.h \ - clients/tui/newt/nmt-newt-button.c \ - clients/tui/newt/nmt-newt-button.h \ - clients/tui/newt/nmt-newt-button-box.c \ - clients/tui/newt/nmt-newt-button-box.h \ - clients/tui/newt/nmt-newt-checkbox.c \ - clients/tui/newt/nmt-newt-checkbox.h \ - clients/tui/newt/nmt-newt-component.c \ - clients/tui/newt/nmt-newt-component.h \ - clients/tui/newt/nmt-newt-container.c \ - clients/tui/newt/nmt-newt-container.h \ - clients/tui/newt/nmt-newt-entry.c \ - clients/tui/newt/nmt-newt-entry.h \ - clients/tui/newt/nmt-newt-entry-numeric.c \ - clients/tui/newt/nmt-newt-entry-numeric.h \ - clients/tui/newt/nmt-newt-form.c \ - clients/tui/newt/nmt-newt-form.h \ - clients/tui/newt/nmt-newt-grid.c \ - clients/tui/newt/nmt-newt-grid.h \ - clients/tui/newt/nmt-newt-hacks.c \ - clients/tui/newt/nmt-newt-hacks.h \ - clients/tui/newt/nmt-newt-label.c \ - clients/tui/newt/nmt-newt-label.h \ - clients/tui/newt/nmt-newt-listbox.c \ - clients/tui/newt/nmt-newt-listbox.h \ - clients/tui/newt/nmt-newt-popup.c \ - clients/tui/newt/nmt-newt-popup.h \ - clients/tui/newt/nmt-newt-section.c \ - clients/tui/newt/nmt-newt-section.h \ - clients/tui/newt/nmt-newt-separator.c \ - clients/tui/newt/nmt-newt-separator.h \ - clients/tui/newt/nmt-newt-stack.c \ - clients/tui/newt/nmt-newt-stack.h \ - clients/tui/newt/nmt-newt-textbox.c \ - clients/tui/newt/nmt-newt-textbox.h \ - clients/tui/newt/nmt-newt-toggle-button.c \ - clients/tui/newt/nmt-newt-toggle-button.h \ - clients/tui/newt/nmt-newt-utils.c \ - clients/tui/newt/nmt-newt-utils.h \ - clients/tui/newt/nmt-newt-widget.c \ - clients/tui/newt/nmt-newt-widget.h -@BUILD_NMTUI_TRUE@am_clients_tui_newt_libnmt_newt_a_OBJECTS = clients/tui/newt/libnmt_newt_a-nmt-newt-button.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-component.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-container.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-entry.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-form.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-grid.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-label.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-popup.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-section.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-separator.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-stack.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-utils.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt_newt_a-nmt-newt-widget.$(OBJEXT) -clients_tui_newt_libnmt_newt_a_OBJECTS = \ - $(am_clients_tui_newt_libnmt_newt_a_OBJECTS) -am__DEPENDENCIES_1 = -clients_common_libnmc_base_la_DEPENDENCIES = libnm/libnm.la \ - $(am__DEPENDENCIES_1) -am_clients_common_libnmc_base_la_OBJECTS = \ - clients/common/libnmc_base_la-nm-secret-agent-simple.lo \ - clients/common/libnmc_base_la-nm-vpn-helpers.lo \ - clients/common/libnmc_base_la-nm-client-utils.lo \ - clients/common/libnmc_base_la-nm-polkit-listener.lo -clients_common_libnmc_base_la_OBJECTS = \ - $(am_clients_common_libnmc_base_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -@ENABLE_TESTS_FALSE@am_clients_common_libnmc_base_la_rpath = -@ENABLE_TESTS_TRUE@am_clients_common_libnmc_base_la_rpath = -clients_common_libnmc_la_DEPENDENCIES = libnm/libnm.la \ - $(am__DEPENDENCIES_1) -am_clients_common_libnmc_la_OBJECTS = \ - clients/common/libnmc_la-nm-meta-setting-base-impl.lo \ - clients/common/libnmc_la-nm-meta-setting-desc.lo \ - clients/common/libnmc_la-nm-meta-setting-access.lo -clients_common_libnmc_la_OBJECTS = \ - $(am_clients_common_libnmc_la_OBJECTS) -@ENABLE_TESTS_FALSE@@HAVE_INTROSPECTION_TRUE@am_clients_common_libnmc_la_rpath = -@ENABLE_TESTS_TRUE@@HAVE_INTROSPECTION_TRUE@am_clients_common_libnmc_la_rpath = -@HAVE_INTROSPECTION_FALSE@am_clients_common_libnmc_la_rpath = -dispatcher_libnm_dispatcher_core_la_DEPENDENCIES = libnm/libnm.la \ - $(am__DEPENDENCIES_1) -am_dispatcher_libnm_dispatcher_core_la_OBJECTS = \ - dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo -dispatcher_libnm_dispatcher_core_la_OBJECTS = \ - $(am_dispatcher_libnm_dispatcher_core_la_OBJECTS) +@BUILD_NMTUI_TRUE@am_src_libnmt_newt_libnmt_newt_a_OBJECTS = src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-button.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-component.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-container.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-form.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-label.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-section.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.$(OBJEXT) +src_libnmt_newt_libnmt_newt_a_OBJECTS = \ + $(am_src_libnmt_newt_libnmt_newt_a_OBJECTS) +src_nm_cloud_setup_libnm_cloud_setup_core_a_AR = $(AR) $(ARFLAGS) +src_nm_cloud_setup_libnm_cloud_setup_core_a_LIBADD = +am__src_nm_cloud_setup_libnm_cloud_setup_core_a_SOURCES_DIST = \ + src/nm-cloud-setup/nm-cloud-setup-utils.c \ + src/nm-cloud-setup/nm-cloud-setup-utils.h \ + src/nm-cloud-setup/nm-http-client.c \ + src/nm-cloud-setup/nm-http-client.h \ + src/nm-cloud-setup/nmcs-provider.c \ + src/nm-cloud-setup/nmcs-provider.h \ + src/nm-cloud-setup/nmcs-provider-ec2.c \ + src/nm-cloud-setup/nmcs-provider-ec2.h \ + src/nm-cloud-setup/nmcs-provider-gcp.c \ + src/nm-cloud-setup/nmcs-provider-gcp.h \ + src/nm-cloud-setup/nmcs-provider-azure.c \ + src/nm-cloud-setup/nmcs-provider-azure.h +@BUILD_NM_CLOUD_SETUP_TRUE@am_src_nm_cloud_setup_libnm_cloud_setup_core_a_OBJECTS = src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.$(OBJEXT) \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.$(OBJEXT) \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.$(OBJEXT) \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.$(OBJEXT) \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.$(OBJEXT) \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.$(OBJEXT) +src_nm_cloud_setup_libnm_cloud_setup_core_a_OBJECTS = \ + $(am_src_nm_cloud_setup_libnm_cloud_setup_core_a_OBJECTS) introspection_libnmdbus_la_LIBADD = am__objects_1 = introspection/libnmdbus_la-org.freedesktop.NetworkManager.AccessPoint.lo \ introspection/libnmdbus_la-org.freedesktop.NetworkManager.AgentManager.lo \ @@ -703,413 +671,35 @@ am__objects_1 = introspection/libnmdbus_la-org.freedesktop.NetworkManager.Access nodist_introspection_libnmdbus_la_OBJECTS = $(am__objects_1) introspection_libnmdbus_la_OBJECTS = \ $(nodist_introspection_libnmdbus_la_OBJECTS) -libnm_core_libnm_core_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) -am__objects_2 = -am__objects_3 = libnm-core/libnm_core_la-nm-setting-6lowpan.lo \ - libnm-core/libnm_core_la-nm-setting-8021x.lo \ - libnm-core/libnm_core_la-nm-setting-adsl.lo \ - libnm-core/libnm_core_la-nm-setting-bluetooth.lo \ - libnm-core/libnm_core_la-nm-setting-bond.lo \ - libnm-core/libnm_core_la-nm-setting-bridge-port.lo \ - libnm-core/libnm_core_la-nm-setting-bridge.lo \ - libnm-core/libnm_core_la-nm-setting-cdma.lo \ - libnm-core/libnm_core_la-nm-setting-connection.lo \ - libnm-core/libnm_core_la-nm-setting-dcb.lo \ - libnm-core/libnm_core_la-nm-setting-dummy.lo \ - libnm-core/libnm_core_la-nm-setting-ethtool.lo \ - libnm-core/libnm_core_la-nm-setting-generic.lo \ - libnm-core/libnm_core_la-nm-setting-gsm.lo \ - libnm-core/libnm_core_la-nm-setting-hostname.lo \ - libnm-core/libnm_core_la-nm-setting-infiniband.lo \ - libnm-core/libnm_core_la-nm-setting-ip-config.lo \ - libnm-core/libnm_core_la-nm-setting-ip-tunnel.lo \ - libnm-core/libnm_core_la-nm-setting-ip4-config.lo \ - libnm-core/libnm_core_la-nm-setting-ip6-config.lo \ - libnm-core/libnm_core_la-nm-setting-macsec.lo \ - libnm-core/libnm_core_la-nm-setting-macvlan.lo \ - libnm-core/libnm_core_la-nm-setting-match.lo \ - libnm-core/libnm_core_la-nm-setting-olpc-mesh.lo \ - libnm-core/libnm_core_la-nm-setting-ovs-bridge.lo \ - libnm-core/libnm_core_la-nm-setting-ovs-dpdk.lo \ - libnm-core/libnm_core_la-nm-setting-ovs-external-ids.lo \ - libnm-core/libnm_core_la-nm-setting-ovs-interface.lo \ - libnm-core/libnm_core_la-nm-setting-ovs-patch.lo \ - libnm-core/libnm_core_la-nm-setting-ovs-port.lo \ - libnm-core/libnm_core_la-nm-setting-ppp.lo \ - libnm-core/libnm_core_la-nm-setting-pppoe.lo \ - libnm-core/libnm_core_la-nm-setting-proxy.lo \ - libnm-core/libnm_core_la-nm-setting-serial.lo \ - libnm-core/libnm_core_la-nm-setting-sriov.lo \ - libnm-core/libnm_core_la-nm-setting-tc-config.lo \ - libnm-core/libnm_core_la-nm-setting-team-port.lo \ - libnm-core/libnm_core_la-nm-setting-team.lo \ - libnm-core/libnm_core_la-nm-setting-tun.lo \ - libnm-core/libnm_core_la-nm-setting-user.lo \ - libnm-core/libnm_core_la-nm-setting-veth.lo \ - libnm-core/libnm_core_la-nm-setting-vlan.lo \ - libnm-core/libnm_core_la-nm-setting-vpn.lo \ - libnm-core/libnm_core_la-nm-setting-vrf.lo \ - libnm-core/libnm_core_la-nm-setting-vxlan.lo \ - libnm-core/libnm_core_la-nm-setting-wifi-p2p.lo \ - libnm-core/libnm_core_la-nm-setting-wimax.lo \ - libnm-core/libnm_core_la-nm-setting-wired.lo \ - libnm-core/libnm_core_la-nm-setting-wireguard.lo \ - libnm-core/libnm_core_la-nm-setting-wireless-security.lo \ - libnm-core/libnm_core_la-nm-setting-wireless.lo \ - libnm-core/libnm_core_la-nm-setting-wpan.lo -am__objects_4 = $(am__objects_3) \ - libnm-core/libnm_core_la-nm-connection.lo \ - libnm-core/libnm_core_la-nm-crypto.lo \ - libnm-core/libnm_core_la-nm-dbus-utils.lo \ - libnm-core/libnm_core_la-nm-errors.lo \ - libnm-core/libnm_core_la-nm-keyfile-utils.lo \ - libnm-core/libnm_core_la-nm-keyfile.lo \ - libnm-core/libnm_core_la-nm-meta-setting-base-impl.lo \ - libnm-core/libnm_core_la-nm-property-compare.lo \ - libnm-core/libnm_core_la-nm-setting.lo \ - libnm-core/libnm_core_la-nm-simple-connection.lo \ - libnm-core/libnm_core_la-nm-team-utils.lo \ - libnm-core/libnm_core_la-nm-utils.lo \ - libnm-core/libnm_core_la-nm-vpn-editor-plugin.lo \ - libnm-core/libnm_core_la-nm-vpn-plugin-info.lo -am_libnm_core_libnm_core_la_OBJECTS = $(am__objects_2) \ - $(am__objects_2) $(am__objects_4) -am__objects_5 = libnm-core/libnm_core_la-nm-core-enum-types.lo -nodist_libnm_core_libnm_core_la_OBJECTS = $(am__objects_2) \ - $(am__objects_5) -libnm_core_libnm_core_la_OBJECTS = \ - $(am_libnm_core_libnm_core_la_OBJECTS) \ - $(nodist_libnm_core_libnm_core_la_OBJECTS) -libnm_core_libnm_core_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libnm_core_libnm_core_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -@HAVE_CRYPTO_GNUTLS_TRUE@libnm_core_libnm_crypto_gnutls_la_DEPENDENCIES = \ -@HAVE_CRYPTO_GNUTLS_TRUE@ $(am__DEPENDENCIES_1) \ -@HAVE_CRYPTO_GNUTLS_TRUE@ $(am__DEPENDENCIES_1) -am__libnm_core_libnm_crypto_gnutls_la_SOURCES_DIST = \ - libnm-core/nm-crypto-gnutls.c -@HAVE_CRYPTO_GNUTLS_TRUE@am_libnm_core_libnm_crypto_gnutls_la_OBJECTS = libnm-core/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo -libnm_core_libnm_crypto_gnutls_la_OBJECTS = \ - $(am_libnm_core_libnm_crypto_gnutls_la_OBJECTS) -libnm_core_libnm_crypto_gnutls_la_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_core_libnm_crypto_gnutls_la_LDFLAGS) $(LDFLAGS) -o $@ -@ENABLE_TESTS_FALSE@@HAVE_CRYPTO_GNUTLS_TRUE@@WITH_GNUTLS_FALSE@am_libnm_core_libnm_crypto_gnutls_la_rpath = -@ENABLE_TESTS_TRUE@@HAVE_CRYPTO_GNUTLS_TRUE@@WITH_GNUTLS_FALSE@am_libnm_core_libnm_crypto_gnutls_la_rpath = -@HAVE_CRYPTO_GNUTLS_TRUE@@WITH_GNUTLS_TRUE@am_libnm_core_libnm_crypto_gnutls_la_rpath = -@HAVE_CRYPTO_NSS_TRUE@libnm_core_libnm_crypto_nss_la_DEPENDENCIES = \ -@HAVE_CRYPTO_NSS_TRUE@ $(am__DEPENDENCIES_1) \ -@HAVE_CRYPTO_NSS_TRUE@ $(am__DEPENDENCIES_1) -am__libnm_core_libnm_crypto_nss_la_SOURCES_DIST = \ - libnm-core/nm-crypto-nss.c -@HAVE_CRYPTO_NSS_TRUE@am_libnm_core_libnm_crypto_nss_la_OBJECTS = libnm-core/libnm_crypto_nss_la-nm-crypto-nss.lo -libnm_core_libnm_crypto_nss_la_OBJECTS = \ - $(am_libnm_core_libnm_crypto_nss_la_OBJECTS) -libnm_core_libnm_crypto_nss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_core_libnm_crypto_nss_la_LDFLAGS) $(LDFLAGS) -o $@ -@ENABLE_TESTS_FALSE@@HAVE_CRYPTO_NSS_TRUE@@WITH_NSS_FALSE@am_libnm_core_libnm_crypto_nss_la_rpath = -@ENABLE_TESTS_TRUE@@HAVE_CRYPTO_NSS_TRUE@@WITH_NSS_FALSE@am_libnm_core_libnm_crypto_nss_la_rpath = -@HAVE_CRYPTO_NSS_TRUE@@WITH_NSS_TRUE@am_libnm_core_libnm_crypto_nss_la_rpath = -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_1) -am_libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_OBJECTS = libnm-core/nm-libnm-core-aux/libnm_libnm_core_aux_la-nm-libnm-core-aux.lo -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_OBJECTS = $(am_libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_OBJECTS) -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_LINK = \ - $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_1) -am_libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_OBJECTS = libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-auth-subject.lo \ - libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-libnm-core-utils.lo -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_OBJECTS = $(am_libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_OBJECTS) -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_LINK = \ - $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -libnm_libnm_la_DEPENDENCIES = libnm/libnm_static.la -am_libnm_libnm_la_OBJECTS = $(am__objects_2) $(am__objects_2) -libnm_libnm_la_OBJECTS = $(am_libnm_libnm_la_OBJECTS) -libnm_libnm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libnm_libnm_la_LDFLAGS) $(LDFLAGS) -o \ - $@ -libnm_libnm_static_la_DEPENDENCIES = \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la introspection/libnmdbus.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/systemd/libnm-systemd-logging-stub.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__objects_6 = libnm/libnm_static_la-nm-client.lo \ - libnm/libnm_static_la-nm-object.lo \ - libnm/libnm_static_la-nm-device.lo \ - libnm/libnm_static_la-nm-active-connection.lo \ - libnm/libnm_static_la-nm-access-point.lo \ - libnm/libnm_static_la-nm-checkpoint.lo \ - libnm/libnm_static_la-nm-dbus-helpers.lo \ - libnm/libnm_static_la-nm-device-6lowpan.lo \ - libnm/libnm_static_la-nm-device-adsl.lo \ - libnm/libnm_static_la-nm-device-bond.lo \ - libnm/libnm_static_la-nm-device-bridge.lo \ - libnm/libnm_static_la-nm-device-bt.lo \ - libnm/libnm_static_la-nm-device-dummy.lo \ - libnm/libnm_static_la-nm-device-ethernet.lo \ - libnm/libnm_static_la-nm-device-generic.lo \ - libnm/libnm_static_la-nm-device-infiniband.lo \ - libnm/libnm_static_la-nm-device-ip-tunnel.lo \ - libnm/libnm_static_la-nm-device-macsec.lo \ - libnm/libnm_static_la-nm-device-macvlan.lo \ - libnm/libnm_static_la-nm-device-modem.lo \ - libnm/libnm_static_la-nm-device-olpc-mesh.lo \ - libnm/libnm_static_la-nm-device-ovs-bridge.lo \ - libnm/libnm_static_la-nm-device-ovs-interface.lo \ - libnm/libnm_static_la-nm-device-ovs-port.lo \ - libnm/libnm_static_la-nm-device-ppp.lo \ - libnm/libnm_static_la-nm-device-team.lo \ - libnm/libnm_static_la-nm-device-tun.lo \ - libnm/libnm_static_la-nm-device-veth.lo \ - libnm/libnm_static_la-nm-device-vlan.lo \ - libnm/libnm_static_la-nm-device-vrf.lo \ - libnm/libnm_static_la-nm-device-vxlan.lo \ - libnm/libnm_static_la-nm-device-wifi-p2p.lo \ - libnm/libnm_static_la-nm-device-wifi.lo \ - libnm/libnm_static_la-nm-device-wimax.lo \ - libnm/libnm_static_la-nm-device-wireguard.lo \ - libnm/libnm_static_la-nm-device-wpan.lo \ - libnm/libnm_static_la-nm-dhcp-config.lo \ - libnm/libnm_static_la-nm-dhcp4-config.lo \ - libnm/libnm_static_la-nm-dhcp6-config.lo \ - libnm/libnm_static_la-nm-dns-manager.lo \ - libnm/libnm_static_la-nm-ip-config.lo \ - libnm/libnm_static_la-nm-ip4-config.lo \ - libnm/libnm_static_la-nm-ip6-config.lo \ - libnm/libnm_static_la-nm-libnm-utils.lo \ - libnm/libnm_static_la-nm-remote-connection.lo \ - libnm/libnm_static_la-nm-secret-agent-old.lo \ - libnm/libnm_static_la-nm-vpn-connection.lo \ - libnm/libnm_static_la-nm-vpn-editor.lo \ - libnm/libnm_static_la-nm-vpn-plugin-old.lo \ - libnm/libnm_static_la-nm-vpn-service-plugin.lo \ - libnm/libnm_static_la-nm-wifi-p2p-peer.lo \ - libnm/libnm_static_la-nm-wimax-nsp.lo -am_libnm_libnm_static_la_OBJECTS = $(am__objects_6) -am__objects_7 = libnm/libnm_static_la-nm-enum-types.lo -nodist_libnm_libnm_static_la_OBJECTS = $(am__objects_2) \ - $(am__objects_7) -libnm_libnm_static_la_OBJECTS = $(am_libnm_libnm_static_la_OBJECTS) \ - $(nodist_libnm_libnm_static_la_OBJECTS) -libnm_nm_libnm_aux_libnm_libnm_aux_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_1) libnm/libnm.la -am_libnm_nm_libnm_aux_libnm_libnm_aux_la_OBJECTS = \ - libnm/nm-libnm-aux/libnm_libnm_aux_la-nm-libnm-aux.lo -libnm_nm_libnm_aux_libnm_libnm_aux_la_OBJECTS = \ - $(am_libnm_nm_libnm_aux_libnm_libnm_aux_la_OBJECTS) -libnm_nm_libnm_aux_libnm_libnm_aux_la_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_nm_libnm_aux_libnm_libnm_aux_la_LDFLAGS) $(LDFLAGS) -o \ - $@ -libnm_tests_libnm_vpn_plugin_utils_test_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_1) -am_libnm_tests_libnm_vpn_plugin_utils_test_la_OBJECTS = shared/nm-utils/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo -libnm_tests_libnm_vpn_plugin_utils_test_la_OBJECTS = \ - $(am_libnm_tests_libnm_vpn_plugin_utils_test_la_OBJECTS) -libnm_tests_libnm_vpn_plugin_utils_test_la_LINK = $(LIBTOOL) \ - $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) \ - $(libnm_tests_libnm_vpn_plugin_utils_test_la_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -@ENABLE_TESTS_FALSE@am_libnm_tests_libnm_vpn_plugin_utils_test_la_rpath = -@ENABLE_TESTS_TRUE@am_libnm_tests_libnm_vpn_plugin_utils_test_la_rpath = -shared_libcrbtree_la_LIBADD = -am_shared_libcrbtree_la_OBJECTS = \ - shared/c-rbtree/src/libcrbtree_la-c-rbtree.lo -shared_libcrbtree_la_OBJECTS = $(am_shared_libcrbtree_la_OBJECTS) -shared_libcrbtree_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(shared_libcrbtree_la_CFLAGS) $(CFLAGS) \ - $(shared_libcrbtree_la_LDFLAGS) $(LDFLAGS) -o $@ -shared_libcsiphash_la_LIBADD = -am_shared_libcsiphash_la_OBJECTS = \ - shared/c-siphash/src/libcsiphash_la-c-siphash.lo -shared_libcsiphash_la_OBJECTS = $(am_shared_libcsiphash_la_OBJECTS) -shared_libcsiphash_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(shared_libcsiphash_la_CFLAGS) $(CFLAGS) \ - $(shared_libcsiphash_la_LDFLAGS) $(LDFLAGS) -o $@ -shared_libnacd_la_LIBADD = -am__shared_libnacd_la_SOURCES_DIST = shared/n-acd/src/n-acd.c \ - shared/n-acd/src/n-acd.h shared/n-acd/src/n-acd-private.h \ - shared/n-acd/src/n-acd-probe.c shared/n-acd/src/util/timer.c \ - shared/n-acd/src/util/timer.h shared/n-acd/src/n-acd-bpf.c \ - shared/n-acd/src/n-acd-bpf-fallback.c -@WITH_EBPF_TRUE@am__objects_8 = \ -@WITH_EBPF_TRUE@ shared/n-acd/src/libnacd_la-n-acd-bpf.lo -@WITH_EBPF_FALSE@am__objects_9 = shared/n-acd/src/libnacd_la-n-acd-bpf-fallback.lo -am_shared_libnacd_la_OBJECTS = shared/n-acd/src/libnacd_la-n-acd.lo \ - shared/n-acd/src/libnacd_la-n-acd-probe.lo \ - shared/n-acd/src/util/libnacd_la-timer.lo $(am__objects_8) \ - $(am__objects_9) -shared_libnacd_la_OBJECTS = $(am_shared_libnacd_la_OBJECTS) -shared_libnacd_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(shared_libnacd_la_CFLAGS) $(CFLAGS) \ - $(shared_libnacd_la_LDFLAGS) $(LDFLAGS) -o $@ -shared_libndhcp4_la_LIBADD = -am_shared_libndhcp4_la_OBJECTS = \ - shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-connection.lo \ - shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-lease.lo \ - shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-probe.lo \ - shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-client.lo \ - shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-incoming.lo \ - shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-outgoing.lo \ - shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-socket.lo \ - shared/n-dhcp4/src/util/libndhcp4_la-packet.lo \ - shared/n-dhcp4/src/util/libndhcp4_la-socket.lo -shared_libndhcp4_la_OBJECTS = $(am_shared_libndhcp4_la_OBJECTS) -shared_libndhcp4_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +src_c_rbtree_libc_rbtree_la_LIBADD = +am_src_c_rbtree_libc_rbtree_la_OBJECTS = \ + src/c-rbtree/src/libc_rbtree_la-c-rbtree.lo +src_c_rbtree_libc_rbtree_la_OBJECTS = \ + $(am_src_c_rbtree_libc_rbtree_la_OBJECTS) +src_c_rbtree_libc_rbtree_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) \ - $(shared_libndhcp4_la_LDFLAGS) $(LDFLAGS) -o $@ -shared_nm_base_libnm_base_la_DEPENDENCIES = $(am__DEPENDENCIES_1) -am_shared_nm_base_libnm_base_la_OBJECTS = \ - shared/nm-base/libnm_base_la-nm-ethtool-base.lo -shared_nm_base_libnm_base_la_OBJECTS = \ - $(am_shared_nm_base_libnm_base_la_OBJECTS) -shared_nm_base_libnm_base_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(src_c_rbtree_libc_rbtree_la_CFLAGS) $(CFLAGS) \ + $(src_c_rbtree_libc_rbtree_la_LDFLAGS) $(LDFLAGS) -o $@ +src_c_siphash_libc_siphash_la_LIBADD = +am_src_c_siphash_libc_siphash_la_OBJECTS = \ + src/c-siphash/src/libc_siphash_la-c-siphash.lo +src_c_siphash_libc_siphash_la_OBJECTS = \ + $(am_src_c_siphash_libc_siphash_la_OBJECTS) +src_c_siphash_libc_siphash_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(shared_nm_base_libnm_base_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -shared_nm_glib_aux_libnm_glib_aux_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_1) -am_shared_nm_glib_aux_libnm_glib_aux_la_OBJECTS = \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-errno.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo \ - shared/nm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo -shared_nm_glib_aux_libnm_glib_aux_la_OBJECTS = \ - $(am_shared_nm_glib_aux_libnm_glib_aux_la_OBJECTS) -shared_nm_glib_aux_libnm_glib_aux_la_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(shared_nm_glib_aux_libnm_glib_aux_la_LDFLAGS) $(LDFLAGS) -o \ - $@ -shared_nm_log_core_libnm_log_core_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_shared_nm_log_core_libnm_log_core_la_OBJECTS = \ - shared/nm-log-core/libnm_log_core_la-nm-logging.lo -shared_nm_log_core_libnm_log_core_la_OBJECTS = \ - $(am_shared_nm_log_core_libnm_log_core_la_OBJECTS) -shared_nm_log_core_libnm_log_core_la_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(shared_nm_log_core_libnm_log_core_la_LDFLAGS) $(LDFLAGS) -o \ - $@ -shared_nm_platform_libnm_platform_la_DEPENDENCIES = \ + $(src_c_siphash_libc_siphash_la_CFLAGS) $(CFLAGS) \ + $(src_c_siphash_libc_siphash_la_LDFLAGS) $(LDFLAGS) -o $@ +am__DEPENDENCIES_1 = +src_contrib_tests_libnm_vpn_plugin_utils_test_la_DEPENDENCIES = \ $(am__DEPENDENCIES_1) -am_shared_nm_platform_libnm_platform_la_OBJECTS = \ - shared/nm-platform/libnm_platform_la-nm-netlink.lo \ - shared/nm-platform/libnm_platform_la-nm-platform-utils.lo \ - shared/nm-platform/libnm_platform_la-nmp-netns.lo -shared_nm_platform_libnm_platform_la_OBJECTS = \ - $(am_shared_nm_platform_libnm_platform_la_OBJECTS) -shared_nm_platform_libnm_platform_la_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(shared_nm_platform_libnm_platform_la_LDFLAGS) $(LDFLAGS) -o \ - $@ -shared_nm_std_aux_libnm_std_aux_la_LIBADD = -am_shared_nm_std_aux_libnm_std_aux_la_OBJECTS = \ - shared/nm-std-aux/libnm_std_aux_la-c-list-util.lo \ - shared/nm-std-aux/libnm_std_aux_la-nm-std-utils.lo -shared_nm_std_aux_libnm_std_aux_la_OBJECTS = \ - $(am_shared_nm_std_aux_libnm_std_aux_la_OBJECTS) -shared_nm_std_aux_libnm_std_aux_la_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(shared_nm_std_aux_libnm_std_aux_la_LDFLAGS) $(LDFLAGS) -o $@ -shared_nm_udev_aux_libnm_udev_aux_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_shared_nm_udev_aux_libnm_udev_aux_la_OBJECTS = \ - shared/nm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo -shared_nm_udev_aux_libnm_udev_aux_la_OBJECTS = \ - $(am_shared_nm_udev_aux_libnm_udev_aux_la_OBJECTS) -shared_nm_udev_aux_libnm_udev_aux_la_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(shared_nm_udev_aux_libnm_udev_aux_la_LDFLAGS) $(LDFLAGS) -o \ - $@ -shared_systemd_libnm_systemd_logging_stub_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_shared_systemd_libnm_systemd_logging_stub_la_OBJECTS = shared/systemd/libnm_systemd_logging_stub_la-nm-logging-stub.lo -shared_systemd_libnm_systemd_logging_stub_la_OBJECTS = \ - $(am_shared_systemd_libnm_systemd_logging_stub_la_OBJECTS) -shared_systemd_libnm_systemd_shared_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_shared_systemd_libnm_systemd_shared_la_OBJECTS = \ - shared/systemd/libnm_systemd_shared_la-nm-sd-utils-shared.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-alloc-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-env-file.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-env-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-escape.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-ether-addr-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-extract-word.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-fd-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-fileio.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-format-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-fs-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-hash-funcs.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-hashmap.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-hexdecoct.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-hostname-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-in-addr-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-io-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-memory-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-mempool.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-parse-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-path-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-prioq.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-process-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-random-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-ratelimit.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-signal-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-socket-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-stat-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-string-table.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-string-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-strv.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-strxcpyx.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-time-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-tmpfile-util.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-utf8.lo \ - shared/systemd/src/basic/libnm_systemd_shared_la-util.lo \ - shared/systemd/src/shared/libnm_systemd_shared_la-dns-domain.lo \ - shared/systemd/src/shared/libnm_systemd_shared_la-web-util.lo -shared_systemd_libnm_systemd_shared_la_OBJECTS = \ - $(am_shared_systemd_libnm_systemd_shared_la_OBJECTS) +am_src_contrib_tests_libnm_vpn_plugin_utils_test_la_OBJECTS = src/contrib/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo +src_contrib_tests_libnm_vpn_plugin_utils_test_la_OBJECTS = $(am_src_contrib_tests_libnm_vpn_plugin_utils_test_la_OBJECTS) +@ENABLE_TESTS_FALSE@am_src_contrib_tests_libnm_vpn_plugin_utils_test_la_rpath = +@ENABLE_TESTS_TRUE@am_src_contrib_tests_libnm_vpn_plugin_utils_test_la_rpath = src_core_devices_adsl_libnm_device_plugin_adsl_la_DEPENDENCIES = \ $(am__DEPENDENCIES_1) am_src_core_devices_adsl_libnm_device_plugin_adsl_la_OBJECTS = src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo \ @@ -1130,9 +720,9 @@ am__src_core_devices_bluetooth_libnm_bluetooth_utils_la_SOURCES_DIST = \ src/core/devices/bluetooth/nm-bt-error.h \ src/core/devices/bluetooth/nm-bluez5-dun.c \ src/core/devices/bluetooth/nm-bluez5-dun.h -@WITH_BLUEZ5_DUN_TRUE@@WITH_MODEM_MANAGER_1_TRUE@am__objects_10 = src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo +@WITH_BLUEZ5_DUN_TRUE@@WITH_MODEM_MANAGER_1_TRUE@am__objects_2 = src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo @WITH_MODEM_MANAGER_1_TRUE@am_src_core_devices_bluetooth_libnm_bluetooth_utils_la_OBJECTS = src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo \ -@WITH_MODEM_MANAGER_1_TRUE@ $(am__objects_10) +@WITH_MODEM_MANAGER_1_TRUE@ $(am__objects_2) src_core_devices_bluetooth_libnm_bluetooth_utils_la_OBJECTS = $(am_src_core_devices_bluetooth_libnm_bluetooth_utils_la_OBJECTS) @WITH_MODEM_MANAGER_1_TRUE@am_src_core_devices_bluetooth_libnm_bluetooth_utils_la_rpath = @WITH_MODEM_MANAGER_1_TRUE@src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_DEPENDENCIES = src/core/devices/bluetooth/libnm-bluetooth-utils.la \ @@ -1233,7 +823,7 @@ am__src_core_devices_wifi_libnm_wifi_base_la_SOURCES_DIST = \ src/core/devices/wifi/nm-device-iwd.h \ src/core/devices/wifi/nm-iwd-manager.c \ src/core/devices/wifi/nm-iwd-manager.h -@WITH_IWD_TRUE@@WITH_WIFI_TRUE@am__objects_11 = src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo \ +@WITH_IWD_TRUE@@WITH_WIFI_TRUE@am__objects_3 = src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo \ @WITH_IWD_TRUE@@WITH_WIFI_TRUE@ src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo @WITH_WIFI_TRUE@am_src_core_devices_wifi_libnm_wifi_base_la_OBJECTS = src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo \ @WITH_WIFI_TRUE@ src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo \ @@ -1242,7 +832,7 @@ am__src_core_devices_wifi_libnm_wifi_base_la_SOURCES_DIST = \ @WITH_WIFI_TRUE@ src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo \ @WITH_WIFI_TRUE@ src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo \ @WITH_WIFI_TRUE@ src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo \ -@WITH_WIFI_TRUE@ $(am__objects_11) +@WITH_WIFI_TRUE@ $(am__objects_3) src_core_devices_wifi_libnm_wifi_base_la_OBJECTS = \ $(am_src_core_devices_wifi_libnm_wifi_base_la_OBJECTS) @WITH_WIFI_TRUE@am_src_core_devices_wifi_libnm_wifi_base_la_rpath = @@ -1277,12 +867,12 @@ am__src_core_devices_wwan_libnm_wwan_la_SOURCES_DIST = \ src/core/devices/wwan/nm-service-providers.h \ src/core/devices/wwan/nm-modem-ofono.c \ src/core/devices/wwan/nm-modem-ofono.h -@WITH_MODEM_MANAGER_1_TRUE@@WITH_OFONO_TRUE@am__objects_12 = src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo +@WITH_MODEM_MANAGER_1_TRUE@@WITH_OFONO_TRUE@am__objects_4 = src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo @WITH_MODEM_MANAGER_1_TRUE@am_src_core_devices_wwan_libnm_wwan_la_OBJECTS = src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo \ @WITH_MODEM_MANAGER_1_TRUE@ src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo \ @WITH_MODEM_MANAGER_1_TRUE@ src/core/devices/wwan/libnm_wwan_la-nm-modem.lo \ @WITH_MODEM_MANAGER_1_TRUE@ src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo \ -@WITH_MODEM_MANAGER_1_TRUE@ $(am__objects_12) +@WITH_MODEM_MANAGER_1_TRUE@ $(am__objects_4) src_core_devices_wwan_libnm_wwan_la_OBJECTS = \ $(am_src_core_devices_wwan_libnm_wwan_la_OBJECTS) src_core_devices_wwan_libnm_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) \ @@ -1292,27 +882,21 @@ src_core_devices_wwan_libnm_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) \ $@ @WITH_MODEM_MANAGER_1_TRUE@am_src_core_devices_wwan_libnm_wwan_la_rpath = \ @WITH_MODEM_MANAGER_1_TRUE@ -rpath $(plugindir) -src_core_initrd_libnmi_core_la_LIBADD = -am_src_core_initrd_libnmi_core_la_OBJECTS = \ - src/core/initrd/libnmi_core_la-nmi-cmdline-reader.lo \ - src/core/initrd/libnmi_core_la-nmi-dt-reader.lo \ - src/core/initrd/libnmi_core_la-nmi-ibft-reader.lo -src_core_initrd_libnmi_core_la_OBJECTS = \ - $(am_src_core_initrd_libnmi_core_la_OBJECTS) src_core_libNetworkManager_la_DEPENDENCIES = \ src/core/libNetworkManagerBase.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-platform/libnm-platform.la \ - shared/nm-base/libnm-base.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la $(libnm_crypto_lib) \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ src/core/libnm-systemd-core.la \ - shared/systemd/libnm-systemd-shared.la shared/libnacd.la \ - shared/libndhcp4.la shared/libcrbtree.la shared/libcsiphash.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/n-acd/libn-acd.la src/n-dhcp4/libn-dhcp4.la \ + src/c-rbtree/libc-rbtree.la src/c-siphash/libc-siphash.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @@ -1401,58 +985,9 @@ src_core_libNetworkManager_la_OBJECTS = \ $(am_src_core_libNetworkManager_la_OBJECTS) src_core_libNetworkManagerBase_la_DEPENDENCIES = \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__src_core_libNetworkManagerBase_la_SOURCES_DIST = \ - src/core/nm-core-utils.c src/core/nm-core-utils.h \ - src/core/NetworkManagerUtils.c src/core/NetworkManagerUtils.h \ - src/core/platform/nmp-object.c src/core/platform/nmp-object.h \ - src/core/platform/nm-platform.c \ - src/core/platform/nm-platform.h \ - src/core/platform/nm-platform-private.h \ - src/core/platform/nm-linux-platform.c \ - src/core/platform/nm-linux-platform.h \ - src/core/platform/nmp-rules-manager.c \ - src/core/platform/nmp-rules-manager.h \ - src/core/platform/wifi/nm-wifi-utils-nl80211.c \ - src/core/platform/wifi/nm-wifi-utils-nl80211.h \ - src/core/platform/wifi/nm-wifi-utils-private.h \ - src/core/platform/wifi/nm-wifi-utils.c \ - src/core/platform/wifi/nm-wifi-utils.h \ - src/core/platform/wpan/nm-wpan-utils.c \ - src/core/platform/wpan/nm-wpan-utils.h \ - src/core/ndisc/nm-lndp-ndisc.c src/core/ndisc/nm-lndp-ndisc.h \ - src/core/ndisc/nm-ndisc.c src/core/ndisc/nm-ndisc.h \ - src/core/ndisc/nm-ndisc-private.h src/core/nm-dbus-utils.c \ - src/core/nm-dbus-utils.h src/core/nm-dbus-object.c \ - src/core/nm-dbus-object.h src/core/nm-netns.c \ - src/core/nm-netns.h src/core/nm-l3-config-data.c \ - src/core/nm-l3-config-data.h src/core/nm-l3-ipv4ll.c \ - src/core/nm-l3-ipv4ll.h src/core/nm-l3cfg.c \ - src/core/nm-l3cfg.h src/core/nm-ip-config.c \ - src/core/nm-ip-config.h src/core/nm-ip4-config.c \ - src/core/nm-ip4-config.h src/core/nm-ip6-config.c \ - src/core/nm-ip6-config.h src/core/dhcp/nm-dhcp-client.c \ - src/core/dhcp/nm-dhcp-client.h \ - src/core/dhcp/nm-dhcp-client-logging.h \ - src/core/dhcp/nm-dhcp-nettools.c src/core/dhcp/nm-dhcp-utils.c \ - src/core/dhcp/nm-dhcp-utils.h src/core/dhcp/nm-dhcp-options.c \ - src/core/dhcp/nm-dhcp-options.h \ - src/core/dhcp/nm-dhcp-systemd.c \ - src/core/dhcp/nm-dhcp-manager.c \ - src/core/dhcp/nm-dhcp-manager.h src/core/main-utils.c \ - src/core/main-utils.h \ - src/core/platform/wifi/nm-wifi-utils-wext.c \ - src/core/platform/wifi/nm-wifi-utils-wext.h -@WITH_WEXT_TRUE@am__objects_13 = src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-wext.lo am_src_core_libNetworkManagerBase_la_OBJECTS = \ src/core/libNetworkManagerBase_la-nm-core-utils.lo \ src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo \ - src/core/platform/libNetworkManagerBase_la-nmp-object.lo \ - src/core/platform/libNetworkManagerBase_la-nm-platform.lo \ - src/core/platform/libNetworkManagerBase_la-nm-linux-platform.lo \ - src/core/platform/libNetworkManagerBase_la-nmp-rules-manager.lo \ - src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-nl80211.lo \ - src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils.lo \ - src/core/platform/wpan/libNetworkManagerBase_la-nm-wpan-utils.lo \ src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo \ src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo \ src/core/libNetworkManagerBase_la-nm-dbus-utils.lo \ @@ -1470,8 +1005,7 @@ am_src_core_libNetworkManagerBase_la_OBJECTS = \ src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo \ src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo \ src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo \ - src/core/libNetworkManagerBase_la-main-utils.lo \ - $(am__objects_13) + src/core/libNetworkManagerBase_la-main-utils.lo src_core_libNetworkManagerBase_la_OBJECTS = \ $(am_src_core_libNetworkManagerBase_la_OBJECTS) src_core_libNetworkManagerTest_la_DEPENDENCIES = \ @@ -1605,274 +1139,471 @@ am__src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_SOURCES_DIST = sr @CONFIG_PLUGIN_IFUPDOWN_TRUE@ src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_OBJECTS = $(am_src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_OBJECTS) @CONFIG_PLUGIN_IFUPDOWN_TRUE@am_src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_rpath = -am_clients_cli_generate_docs_nm_settings_nmcli_OBJECTS = clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.$(OBJEXT) -clients_cli_generate_docs_nm_settings_nmcli_OBJECTS = \ - $(am_clients_cli_generate_docs_nm_settings_nmcli_OBJECTS) -clients_cli_generate_docs_nm_settings_nmcli_DEPENDENCIES = \ - clients/common/libnmc.la clients/common/libnmc-base.la \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la libnm/libnm.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ +src_libnm_base_libnm_base_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_src_libnm_base_libnm_base_la_OBJECTS = \ + src/libnm-base/libnm_base_la-nm-ethtool-base.lo \ + src/libnm-base/libnm_base_la-nm-net-aux.lo +src_libnm_base_libnm_base_la_OBJECTS = \ + $(am_src_libnm_base_libnm_base_la_OBJECTS) +src_libnm_base_libnm_base_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(src_libnm_base_libnm_base_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_libnm_client_aux_extern_libnm_client_aux_extern_la_DEPENDENCIES = \ + $(am__DEPENDENCIES_1) src/libnm-client-impl/libnm.la +am_src_libnm_client_aux_extern_libnm_client_aux_extern_la_OBJECTS = src/libnm-client-aux-extern/libnm_client_aux_extern_la-nm-libnm-aux.lo +src_libnm_client_aux_extern_libnm_client_aux_extern_la_OBJECTS = $(am_src_libnm_client_aux_extern_libnm_client_aux_extern_la_OBJECTS) +src_libnm_client_aux_extern_libnm_client_aux_extern_la_LINK = \ + $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_client_aux_extern_libnm_client_aux_extern_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_libnm_client_impl_libnm_client_impl_la_DEPENDENCIES = \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la $(libnm_crypto_lib) \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la introspection/libnmdbus.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__objects_5 = \ + src/libnm-client-impl/libnm_client_impl_la-nm-client.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-object.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-active-connection.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-access-point.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-checkpoint.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-dbus-helpers.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-6lowpan.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-adsl.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-bond.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-bridge.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-bt.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-dummy.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-ethernet.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-generic.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-infiniband.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-ip-tunnel.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-macsec.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-macvlan.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-modem.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-olpc-mesh.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-bridge.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-interface.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-port.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-ppp.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-team.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-tun.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-veth.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-vlan.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-vrf.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-vxlan.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi-p2p.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-wimax.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-wireguard.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-device-wpan.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-dhcp-config.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-dhcp4-config.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-dhcp6-config.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-dns-manager.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-ip-config.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-ip4-config.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-ip6-config.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-libnm-utils.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-remote-connection.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-secret-agent-old.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-vpn-connection.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-vpn-editor.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-vpn-plugin-old.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-vpn-service-plugin.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-wifi-p2p-peer.lo \ + src/libnm-client-impl/libnm_client_impl_la-nm-wimax-nsp.lo +am_src_libnm_client_impl_libnm_client_impl_la_OBJECTS = \ + $(am__objects_5) +am__objects_6 = +am__objects_7 = src/libnm-client-public/libnm_client_impl_libnm_client_impl_la-nm-enum-types.lo +nodist_src_libnm_client_impl_libnm_client_impl_la_OBJECTS = \ + $(am__objects_6) $(am__objects_7) +src_libnm_client_impl_libnm_client_impl_la_OBJECTS = \ + $(am_src_libnm_client_impl_libnm_client_impl_la_OBJECTS) \ + $(nodist_src_libnm_client_impl_libnm_client_impl_la_OBJECTS) +src_libnm_client_impl_libnm_la_DEPENDENCIES = \ + src/libnm-client-impl/libnm-client-impl.la +am_src_libnm_client_impl_libnm_la_OBJECTS = $(am__objects_6) \ + $(am__objects_6) +src_libnm_client_impl_libnm_la_OBJECTS = \ + $(am_src_libnm_client_impl_libnm_la_OBJECTS) +src_libnm_client_impl_libnm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_client_impl_libnm_la_LDFLAGS) $(LDFLAGS) -o $@ +src_libnm_client_test_libnm_client_test_la_DEPENDENCIES = \ $(am__DEPENDENCIES_1) -clients_cli_generate_docs_nm_settings_nmcli_LINK = $(LIBTOOL) \ +am_src_libnm_client_test_libnm_client_test_la_OBJECTS = src/libnm-client-test/libnm_client_test_la-nm-test-utils-impl.lo +src_libnm_client_test_libnm_client_test_la_OBJECTS = \ + $(am_src_libnm_client_test_libnm_client_test_la_OBJECTS) +src_libnm_client_test_libnm_client_test_la_LINK = $(LIBTOOL) \ $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(clients_cli_generate_docs_nm_settings_nmcli_LDFLAGS) \ + $(src_libnm_client_test_libnm_client_test_la_LDFLAGS) \ $(LDFLAGS) -o $@ -am__clients_cli_nmcli_SOURCES_DIST = clients/cli/common.c \ - clients/cli/common.h clients/cli/utils.c clients/cli/utils.h \ - clients/cli/agent.c clients/cli/general.c \ - clients/cli/connections.c clients/cli/connections.h \ - clients/cli/devices.c clients/cli/devices.h \ - clients/cli/settings.c clients/cli/settings.h \ - clients/cli/nmcli.c clients/cli/nmcli.h \ - clients/cli/polkit-agent.c clients/cli/polkit-agent.h -@BUILD_NMCLI_TRUE@am_clients_cli_nmcli_OBJECTS = \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli-common.$(OBJEXT) \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli-utils.$(OBJEXT) \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli-agent.$(OBJEXT) \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli-general.$(OBJEXT) \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli-connections.$(OBJEXT) \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli-devices.$(OBJEXT) \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli-settings.$(OBJEXT) \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli-nmcli.$(OBJEXT) \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli-polkit-agent.$(OBJEXT) -clients_cli_nmcli_OBJECTS = $(am_clients_cli_nmcli_OBJECTS) -@BUILD_NMCLI_TRUE@clients_cli_nmcli_DEPENDENCIES = \ -@BUILD_NMCLI_TRUE@ clients/common/libnmc.la \ -@BUILD_NMCLI_TRUE@ clients/common/libnmc-base.la \ -@BUILD_NMCLI_TRUE@ libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ -@BUILD_NMCLI_TRUE@ libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ -@BUILD_NMCLI_TRUE@ shared/nm-base/libnm-base.la \ -@BUILD_NMCLI_TRUE@ shared/nm-glib-aux/libnm-glib-aux.la \ -@BUILD_NMCLI_TRUE@ shared/nm-std-aux/libnm-std-aux.la \ -@BUILD_NMCLI_TRUE@ shared/libcsiphash.la \ -@BUILD_NMCLI_TRUE@ libnm/nm-libnm-aux/libnm-libnm-aux.la \ -@BUILD_NMCLI_TRUE@ libnm/libnm.la $(am__DEPENDENCIES_1) \ -@BUILD_NMCLI_TRUE@ $(am__DEPENDENCIES_1) -clients_cli_nmcli_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(clients_cli_nmcli_LDFLAGS) $(LDFLAGS) \ - -o $@ -am__clients_cloud_setup_nm_cloud_setup_SOURCES_DIST = \ - clients/cloud-setup/main.c -@BUILD_NM_CLOUD_SETUP_TRUE@am_clients_cloud_setup_nm_cloud_setup_OBJECTS = clients/cloud-setup/nm_cloud_setup-main.$(OBJEXT) -clients_cloud_setup_nm_cloud_setup_OBJECTS = \ - $(am_clients_cloud_setup_nm_cloud_setup_OBJECTS) -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_nm_cloud_setup_DEPENDENCIES = clients/cloud-setup/libnm-cloud-setup-core.a \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm/nm-libnm-aux/libnm-libnm-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-base/libnm-base.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-glib-aux/libnm-glib-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-std-aux/libnm-std-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/libcsiphash.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm/libnm.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ $(am__DEPENDENCIES_1) \ -@BUILD_NM_CLOUD_SETUP_TRUE@ $(am__DEPENDENCIES_1) -clients_cloud_setup_nm_cloud_setup_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(clients_cloud_setup_nm_cloud_setup_LDFLAGS) $(LDFLAGS) -o $@ -clients_cloud_setup_tests_test_cloud_setup_general_SOURCES = \ - clients/cloud-setup/tests/test-cloud-setup-general.c -clients_cloud_setup_tests_test_cloud_setup_general_OBJECTS = clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.$(OBJEXT) -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_tests_test_cloud_setup_general_DEPENDENCIES = clients/cloud-setup/libnm-cloud-setup-core.a \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm/nm-libnm-aux/libnm-libnm-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-base/libnm-base.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-glib-aux/libnm-glib-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-std-aux/libnm-std-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/libcsiphash.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm/libnm.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ $(am__DEPENDENCIES_1) \ -@BUILD_NM_CLOUD_SETUP_TRUE@ $(am__DEPENDENCIES_1) -clients_cloud_setup_tests_test_cloud_setup_general_LINK = $(LIBTOOL) \ +src_libnm_core_aux_extern_libnm_core_aux_extern_la_DEPENDENCIES = \ + $(am__DEPENDENCIES_1) +am_src_libnm_core_aux_extern_libnm_core_aux_extern_la_OBJECTS = src/libnm-core-aux-extern/libnm_core_aux_extern_la-nm-libnm-core-aux.lo +src_libnm_core_aux_extern_libnm_core_aux_extern_la_OBJECTS = $(am_src_libnm_core_aux_extern_libnm_core_aux_extern_la_OBJECTS) +src_libnm_core_aux_extern_libnm_core_aux_extern_la_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_core_aux_extern_libnm_core_aux_extern_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_libnm_core_aux_intern_libnm_core_aux_intern_la_DEPENDENCIES = \ + $(am__DEPENDENCIES_1) +am_src_libnm_core_aux_intern_libnm_core_aux_intern_la_OBJECTS = src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-auth-subject.lo \ + src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-libnm-core-utils.lo +src_libnm_core_aux_intern_libnm_core_aux_intern_la_OBJECTS = $(am_src_libnm_core_aux_intern_libnm_core_aux_intern_la_OBJECTS) +src_libnm_core_aux_intern_libnm_core_aux_intern_la_LINK = $(LIBTOOL) \ $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(clients_cloud_setup_tests_test_cloud_setup_general_LDFLAGS) \ + $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_LDFLAGS) \ $(LDFLAGS) -o $@ -clients_common_tests_test_clients_common_SOURCES = \ - clients/common/tests/test-clients-common.c -clients_common_tests_test_clients_common_OBJECTS = clients/common/tests/test_clients_common-test-clients-common.$(OBJEXT) -clients_common_tests_test_clients_common_DEPENDENCIES = \ - clients/common/libnmc.la clients/common/libnmc-base.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ - libnm/libnm.la $(am__DEPENDENCIES_1) -clients_common_tests_test_clients_common_LINK = $(LIBTOOL) $(AM_V_lt) \ +src_libnm_core_impl_libnm_core_impl_la_DEPENDENCIES = \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__objects_8 = \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-6lowpan.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-8021x.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-adsl.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-bluetooth.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-bond.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge-port.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-cdma.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-connection.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-dcb.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-dummy.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ethtool.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-generic.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-gsm.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-hostname.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-infiniband.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-config.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-tunnel.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip4-config.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip6-config.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-macsec.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-macvlan.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-match.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-olpc-mesh.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-bridge.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-dpdk.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-external-ids.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-interface.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-patch.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-port.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-ppp.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-pppoe.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-proxy.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-serial.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-sriov.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-tc-config.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-team-port.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-team.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-tun.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-user.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-veth.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-vlan.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-vpn.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-vrf.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-vxlan.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-wifi-p2p.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-wimax.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-wired.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireguard.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless-security.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting-wpan.lo +am__objects_9 = $(am__objects_8) \ + src/libnm-core-impl/libnm_core_impl_la-nm-connection.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-crypto.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-dbus-utils.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-errors.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-keyfile-utils.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-keyfile.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-meta-setting-base-impl.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-property-compare.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-setting.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-simple-connection.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-team-utils.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-utils.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-vpn-editor-plugin.lo \ + src/libnm-core-impl/libnm_core_impl_la-nm-vpn-plugin-info.lo +am_src_libnm_core_impl_libnm_core_impl_la_OBJECTS = $(am__objects_6) \ + $(am__objects_6) $(am__objects_9) +am__objects_10 = src/libnm-core-public/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.lo +nodist_src_libnm_core_impl_libnm_core_impl_la_OBJECTS = \ + $(am__objects_6) $(am__objects_10) +src_libnm_core_impl_libnm_core_impl_la_OBJECTS = \ + $(am_src_libnm_core_impl_libnm_core_impl_la_OBJECTS) \ + $(nodist_src_libnm_core_impl_libnm_core_impl_la_OBJECTS) +src_libnm_core_impl_libnm_core_impl_la_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(clients_common_tests_test_clients_common_LDFLAGS) $(LDFLAGS) \ + $(src_libnm_core_impl_libnm_core_impl_la_LDFLAGS) $(LDFLAGS) \ -o $@ -clients_common_tests_test_libnm_core_aux_SOURCES = \ - clients/common/tests/test-libnm-core-aux.c -clients_common_tests_test_libnm_core_aux_OBJECTS = clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.$(OBJEXT) -clients_common_tests_test_libnm_core_aux_DEPENDENCIES = \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ - libnm/libnm.la $(am__DEPENDENCIES_1) -clients_common_tests_test_libnm_core_aux_LINK = $(LIBTOOL) $(AM_V_lt) \ +@HAVE_CRYPTO_GNUTLS_TRUE@src_libnm_core_impl_libnm_crypto_gnutls_la_DEPENDENCIES = \ +@HAVE_CRYPTO_GNUTLS_TRUE@ $(am__DEPENDENCIES_1) \ +@HAVE_CRYPTO_GNUTLS_TRUE@ $(am__DEPENDENCIES_1) +am__src_libnm_core_impl_libnm_crypto_gnutls_la_SOURCES_DIST = \ + src/libnm-core-impl/nm-crypto-gnutls.c +@HAVE_CRYPTO_GNUTLS_TRUE@am_src_libnm_core_impl_libnm_crypto_gnutls_la_OBJECTS = src/libnm-core-impl/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo +src_libnm_core_impl_libnm_crypto_gnutls_la_OBJECTS = \ + $(am_src_libnm_core_impl_libnm_crypto_gnutls_la_OBJECTS) +src_libnm_core_impl_libnm_crypto_gnutls_la_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_core_impl_libnm_crypto_gnutls_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@ENABLE_TESTS_FALSE@@HAVE_CRYPTO_GNUTLS_TRUE@@WITH_GNUTLS_FALSE@am_src_libnm_core_impl_libnm_crypto_gnutls_la_rpath = +@ENABLE_TESTS_TRUE@@HAVE_CRYPTO_GNUTLS_TRUE@@WITH_GNUTLS_FALSE@am_src_libnm_core_impl_libnm_crypto_gnutls_la_rpath = +@HAVE_CRYPTO_GNUTLS_TRUE@@WITH_GNUTLS_TRUE@am_src_libnm_core_impl_libnm_crypto_gnutls_la_rpath = +@HAVE_CRYPTO_NSS_TRUE@src_libnm_core_impl_libnm_crypto_nss_la_DEPENDENCIES = \ +@HAVE_CRYPTO_NSS_TRUE@ $(am__DEPENDENCIES_1) \ +@HAVE_CRYPTO_NSS_TRUE@ $(am__DEPENDENCIES_1) +am__src_libnm_core_impl_libnm_crypto_nss_la_SOURCES_DIST = \ + src/libnm-core-impl/nm-crypto-nss.c +@HAVE_CRYPTO_NSS_TRUE@am_src_libnm_core_impl_libnm_crypto_nss_la_OBJECTS = src/libnm-core-impl/libnm_crypto_nss_la-nm-crypto-nss.lo +src_libnm_core_impl_libnm_crypto_nss_la_OBJECTS = \ + $(am_src_libnm_core_impl_libnm_crypto_nss_la_OBJECTS) +src_libnm_core_impl_libnm_crypto_nss_la_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(clients_common_tests_test_libnm_core_aux_LDFLAGS) $(LDFLAGS) \ + $(src_libnm_core_impl_libnm_crypto_nss_la_LDFLAGS) $(LDFLAGS) \ -o $@ -clients_nm_online_SOURCES = clients/nm-online.c -clients_nm_online_OBJECTS = clients/nm_online-nm-online.$(OBJEXT) -clients_nm_online_DEPENDENCIES = libnm/libnm.la \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ +@ENABLE_TESTS_FALSE@@HAVE_CRYPTO_NSS_TRUE@@WITH_NSS_FALSE@am_src_libnm_core_impl_libnm_crypto_nss_la_rpath = +@ENABLE_TESTS_TRUE@@HAVE_CRYPTO_NSS_TRUE@@WITH_NSS_FALSE@am_src_libnm_core_impl_libnm_crypto_nss_la_rpath = +@HAVE_CRYPTO_NSS_TRUE@@WITH_NSS_TRUE@am_src_libnm_core_impl_libnm_crypto_nss_la_rpath = +src_libnm_glib_aux_libnm_glib_aux_la_DEPENDENCIES = \ $(am__DEPENDENCIES_1) -clients_nm_online_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(clients_nm_online_LDFLAGS) $(LDFLAGS) \ - -o $@ -am__clients_tui_nmtui_SOURCES_DIST = clients/tui/nmtui.c \ - clients/tui/nmtui.h clients/tui/nmtui-connect.c \ - clients/tui/nmtui-connect.h clients/tui/nmtui-edit.c \ - clients/tui/nmtui-edit.h clients/tui/nmtui-hostname.c \ - clients/tui/nmtui-hostname.h clients/tui/nm-editor-bindings.c \ - clients/tui/nm-editor-bindings.h clients/tui/nm-editor-utils.c \ - clients/tui/nm-editor-utils.h clients/tui/nmt-address-list.c \ - clients/tui/nmt-address-list.h \ - clients/tui/nmt-connect-connection-list.c \ - clients/tui/nmt-connect-connection-list.h \ - clients/tui/nmt-device-entry.c clients/tui/nmt-device-entry.h \ - clients/tui/nmt-edit-connection-list.c \ - clients/tui/nmt-edit-connection-list.h \ - clients/tui/nmt-editor-grid.c clients/tui/nmt-editor-grid.h \ - clients/tui/nmt-editor-page.c clients/tui/nmt-editor-page.h \ - clients/tui/nmt-editor-page-device.c \ - clients/tui/nmt-editor-page-device.h \ - clients/tui/nmt-editor-section.c \ - clients/tui/nmt-editor-section.h clients/tui/nmt-editor.c \ - clients/tui/nmt-editor.h clients/tui/nmt-ip-entry.c \ - clients/tui/nmt-ip-entry.h clients/tui/nmt-mac-entry.c \ - clients/tui/nmt-mac-entry.h clients/tui/nmt-mtu-entry.c \ - clients/tui/nmt-mtu-entry.h clients/tui/nmt-page-bond.c \ - clients/tui/nmt-page-bond.h clients/tui/nmt-page-bridge.c \ - clients/tui/nmt-page-bridge.h \ - clients/tui/nmt-page-bridge-port.c \ - clients/tui/nmt-page-bridge-port.h clients/tui/nmt-page-dsl.c \ - clients/tui/nmt-page-dsl.h clients/tui/nmt-page-ethernet.c \ - clients/tui/nmt-page-ethernet.h \ - clients/tui/nmt-page-infiniband.c \ - clients/tui/nmt-page-infiniband.h \ - clients/tui/nmt-page-ip-tunnel.c \ - clients/tui/nmt-page-ip-tunnel.h clients/tui/nmt-page-ip4.c \ - clients/tui/nmt-page-ip4.h clients/tui/nmt-page-ip6.c \ - clients/tui/nmt-page-ip6.h clients/tui/nmt-page-ppp.c \ - clients/tui/nmt-page-ppp.h clients/tui/nmt-page-team.c \ - clients/tui/nmt-page-team.h clients/tui/nmt-page-team-port.c \ - clients/tui/nmt-page-team-port.h clients/tui/nmt-page-vlan.c \ - clients/tui/nmt-page-vlan.h clients/tui/nmt-page-wifi.c \ - clients/tui/nmt-page-wifi.h clients/tui/nmt-password-dialog.c \ - clients/tui/nmt-password-dialog.h \ - clients/tui/nmt-password-fields.c \ - clients/tui/nmt-password-fields.h \ - clients/tui/nmt-route-editor.c clients/tui/nmt-route-editor.h \ - clients/tui/nmt-route-entry.c clients/tui/nmt-route-entry.h \ - clients/tui/nmt-route-table.c clients/tui/nmt-route-table.h \ - clients/tui/nmt-slave-list.c clients/tui/nmt-slave-list.h \ - clients/tui/nmt-utils.c clients/tui/nmt-utils.h \ - clients/tui/nmt-widget-list.c clients/tui/nmt-widget-list.h -@BUILD_NMTUI_TRUE@am_clients_tui_nmtui_OBJECTS = \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmtui.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmtui-connect.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmtui-edit.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmtui-hostname.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nm-editor-bindings.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nm-editor-utils.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-address-list.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-connect-connection-list.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-device-entry.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-edit-connection-list.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-editor-grid.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-editor-page.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-editor-page-device.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-editor-section.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-editor.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-ip-entry.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-mac-entry.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-mtu-entry.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-bond.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-bridge.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-bridge-port.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-dsl.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-ethernet.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-infiniband.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-ip-tunnel.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-ip4.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-ip6.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-ppp.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-team.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-team-port.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-vlan.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-page-wifi.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-password-dialog.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-password-fields.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-route-editor.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-route-entry.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-route-table.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-slave-list.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-utils.$(OBJEXT) \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-nmt-widget-list.$(OBJEXT) -clients_tui_nmtui_OBJECTS = $(am_clients_tui_nmtui_OBJECTS) -@BUILD_NMTUI_TRUE@clients_tui_nmtui_DEPENDENCIES = \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt-newt.a \ -@BUILD_NMTUI_TRUE@ clients/common/libnmc.la \ -@BUILD_NMTUI_TRUE@ clients/common/libnmc-base.la \ -@BUILD_NMTUI_TRUE@ libnm/nm-libnm-aux/libnm-libnm-aux.la \ -@BUILD_NMTUI_TRUE@ libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ -@BUILD_NMTUI_TRUE@ libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ -@BUILD_NMTUI_TRUE@ shared/nm-base/libnm-base.la \ -@BUILD_NMTUI_TRUE@ shared/nm-glib-aux/libnm-glib-aux.la \ -@BUILD_NMTUI_TRUE@ shared/nm-std-aux/libnm-std-aux.la \ -@BUILD_NMTUI_TRUE@ shared/libcsiphash.la libnm/libnm.la \ -@BUILD_NMTUI_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -clients_tui_nmtui_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(clients_tui_nmtui_LDFLAGS) $(LDFLAGS) \ - -o $@ -am_dispatcher_nm_dispatcher_OBJECTS = \ - dispatcher/nm_dispatcher-nm-dispatcher.$(OBJEXT) -dispatcher_nm_dispatcher_OBJECTS = \ - $(am_dispatcher_nm_dispatcher_OBJECTS) -dispatcher_nm_dispatcher_DEPENDENCIES = \ - dispatcher/libnm-dispatcher-core.la libnm/libnm.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ +am_src_libnm_glib_aux_libnm_glib_aux_la_OBJECTS = \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-errno.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo \ + src/libnm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo +src_libnm_glib_aux_libnm_glib_aux_la_OBJECTS = \ + $(am_src_libnm_glib_aux_libnm_glib_aux_la_OBJECTS) +src_libnm_glib_aux_libnm_glib_aux_la_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_glib_aux_libnm_glib_aux_la_LDFLAGS) $(LDFLAGS) -o \ + $@ +src_libnm_log_core_libnm_log_core_la_DEPENDENCIES = \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_src_libnm_log_core_libnm_log_core_la_OBJECTS = \ + src/libnm-log-core/libnm_log_core_la-nm-logging.lo +src_libnm_log_core_libnm_log_core_la_OBJECTS = \ + $(am_src_libnm_log_core_libnm_log_core_la_OBJECTS) +src_libnm_log_core_libnm_log_core_la_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_log_core_libnm_log_core_la_LDFLAGS) $(LDFLAGS) -o \ + $@ +src_libnm_log_null_libnm_log_null_la_DEPENDENCIES = \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_src_libnm_log_null_libnm_log_null_la_OBJECTS = \ + src/libnm-log-null/libnm_log_null_la-nm-logging-null.lo +src_libnm_log_null_libnm_log_null_la_OBJECTS = \ + $(am_src_libnm_log_null_libnm_log_null_la_OBJECTS) +src_libnm_platform_libnm_platform_la_DEPENDENCIES = \ $(am__DEPENDENCIES_1) -dispatcher_nm_dispatcher_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(dispatcher_nm_dispatcher_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_dispatcher_tests_test_dispatcher_envp_OBJECTS = dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.$(OBJEXT) -am__objects_14 = dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.$(OBJEXT) -nodist_dispatcher_tests_test_dispatcher_envp_OBJECTS = \ - $(am__objects_14) -dispatcher_tests_test_dispatcher_envp_OBJECTS = \ - $(am_dispatcher_tests_test_dispatcher_envp_OBJECTS) \ - $(nodist_dispatcher_tests_test_dispatcher_envp_OBJECTS) -dispatcher_tests_test_dispatcher_envp_DEPENDENCIES = \ - dispatcher/libnm-dispatcher-core.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ - libnm/libnm.la $(am__DEPENDENCIES_1) -dispatcher_tests_test_dispatcher_envp_LINK = $(LIBTOOL) $(AM_V_lt) \ +am__src_libnm_platform_libnm_platform_la_SOURCES_DIST = \ + src/linux-headers/nl802154.h \ + src/libnm-platform/nm-linux-platform.c \ + src/libnm-platform/nm-linux-platform.h \ + src/libnm-platform/nm-netlink.c \ + src/libnm-platform/nm-netlink.h \ + src/libnm-platform/nm-platform-private.h \ + src/libnm-platform/nm-platform-utils.c \ + src/libnm-platform/nm-platform-utils.h \ + src/libnm-platform/nm-platform.c \ + src/libnm-platform/nm-platform.h src/libnm-platform/nmp-base.h \ + src/libnm-platform/nmp-netns.c src/libnm-platform/nmp-netns.h \ + src/libnm-platform/nmp-object.c \ + src/libnm-platform/nmp-object.h \ + src/libnm-platform/nmp-rules-manager.c \ + src/libnm-platform/nmp-rules-manager.h \ + src/libnm-platform/wifi/nm-wifi-utils-nl80211.c \ + src/libnm-platform/wifi/nm-wifi-utils-nl80211.h \ + src/libnm-platform/wifi/nm-wifi-utils-private.h \ + src/libnm-platform/wifi/nm-wifi-utils.c \ + src/libnm-platform/wifi/nm-wifi-utils.h \ + src/libnm-platform/wpan/nm-wpan-utils.c \ + src/libnm-platform/wpan/nm-wpan-utils.h \ + src/libnm-platform/wifi/nm-wifi-utils-wext.c \ + src/libnm-platform/wifi/nm-wifi-utils-wext.h +@WITH_WEXT_TRUE@am__objects_11 = src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-wext.lo +am_src_libnm_platform_libnm_platform_la_OBJECTS = \ + src/libnm-platform/libnm_platform_la-nm-linux-platform.lo \ + src/libnm-platform/libnm_platform_la-nm-netlink.lo \ + src/libnm-platform/libnm_platform_la-nm-platform-utils.lo \ + src/libnm-platform/libnm_platform_la-nm-platform.lo \ + src/libnm-platform/libnm_platform_la-nmp-netns.lo \ + src/libnm-platform/libnm_platform_la-nmp-object.lo \ + src/libnm-platform/libnm_platform_la-nmp-rules-manager.lo \ + src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-nl80211.lo \ + src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils.lo \ + src/libnm-platform/wpan/libnm_platform_la-nm-wpan-utils.lo \ + $(am__objects_11) +src_libnm_platform_libnm_platform_la_OBJECTS = \ + $(am_src_libnm_platform_libnm_platform_la_OBJECTS) +src_libnm_platform_libnm_platform_la_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_platform_libnm_platform_la_LDFLAGS) $(LDFLAGS) -o \ + $@ +src_libnm_std_aux_libnm_std_aux_la_LIBADD = +am_src_libnm_std_aux_libnm_std_aux_la_OBJECTS = \ + src/libnm-std-aux/libnm_std_aux_la-c-list-util.lo \ + src/libnm-std-aux/libnm_std_aux_la-nm-std-utils.lo +src_libnm_std_aux_libnm_std_aux_la_OBJECTS = \ + $(am_src_libnm_std_aux_libnm_std_aux_la_OBJECTS) +src_libnm_std_aux_libnm_std_aux_la_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(dispatcher_tests_test_dispatcher_envp_LDFLAGS) $(LDFLAGS) -o \ + $(src_libnm_std_aux_libnm_std_aux_la_LDFLAGS) $(LDFLAGS) -o $@ +src_libnm_systemd_shared_libnm_systemd_shared_la_DEPENDENCIES = \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_src_libnm_systemd_shared_libnm_systemd_shared_la_OBJECTS = src/libnm-systemd-shared/libnm_systemd_shared_la-nm-sd-utils-shared.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-alloc-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-file.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-escape.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ether-addr-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-extract-word.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fd-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fileio.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-format-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fs-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hash-funcs.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hashmap.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hexdecoct.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hostname-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-in-addr-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-io-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-memory-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-mempool.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-parse-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-path-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-prioq.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-process-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-random-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ratelimit.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-signal-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-socket-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-stat-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-table.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strv.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strxcpyx.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-time-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-tmpfile-util.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-utf8.lo \ + src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-util.lo \ + src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-dns-domain.lo \ + src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-web-util.lo +src_libnm_systemd_shared_libnm_systemd_shared_la_OBJECTS = $(am_src_libnm_systemd_shared_libnm_systemd_shared_la_OBJECTS) +src_libnm_udev_aux_libnm_udev_aux_la_DEPENDENCIES = \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_src_libnm_udev_aux_libnm_udev_aux_la_OBJECTS = \ + src/libnm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo +src_libnm_udev_aux_libnm_udev_aux_la_OBJECTS = \ + $(am_src_libnm_udev_aux_libnm_udev_aux_la_OBJECTS) +src_libnm_udev_aux_libnm_udev_aux_la_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_udev_aux_libnm_udev_aux_la_LDFLAGS) $(LDFLAGS) -o \ $@ +src_libnmc_base_libnmc_base_la_DEPENDENCIES = \ + src/libnm-client-impl/libnm.la $(am__DEPENDENCIES_1) +am_src_libnmc_base_libnmc_base_la_OBJECTS = \ + src/libnmc-base/libnmc_base_la-nm-client-utils.lo \ + src/libnmc-base/libnmc_base_la-nm-polkit-listener.lo \ + src/libnmc-base/libnmc_base_la-nm-secret-agent-simple.lo \ + src/libnmc-base/libnmc_base_la-nm-vpn-helpers.lo +src_libnmc_base_libnmc_base_la_OBJECTS = \ + $(am_src_libnmc_base_libnmc_base_la_OBJECTS) +@ENABLE_TESTS_FALSE@am_src_libnmc_base_libnmc_base_la_rpath = +@ENABLE_TESTS_TRUE@am_src_libnmc_base_libnmc_base_la_rpath = +src_libnmc_setting_libnmc_setting_la_DEPENDENCIES = \ + src/libnm-client-impl/libnm.la $(am__DEPENDENCIES_1) +am_src_libnmc_setting_libnmc_setting_la_OBJECTS = src/libnmc-setting/libnmc_setting_la-nm-meta-setting-access.lo \ + src/libnmc-setting/libnmc_setting_la-nm-meta-setting-base-impl.lo \ + src/libnmc-setting/libnmc_setting_la-nm-meta-setting-desc.lo +src_libnmc_setting_libnmc_setting_la_OBJECTS = \ + $(am_src_libnmc_setting_libnmc_setting_la_OBJECTS) +@ENABLE_TESTS_FALSE@am_src_libnmc_setting_libnmc_setting_la_rpath = +@ENABLE_TESTS_TRUE@am_src_libnmc_setting_libnmc_setting_la_rpath = +src_n_acd_libn_acd_la_LIBADD = +am__src_n_acd_libn_acd_la_SOURCES_DIST = src/n-acd/src/n-acd.c \ + src/n-acd/src/n-acd.h src/n-acd/src/n-acd-private.h \ + src/n-acd/src/n-acd-probe.c src/n-acd/src/util/timer.c \ + src/n-acd/src/util/timer.h src/n-acd/src/n-acd-bpf.c \ + src/n-acd/src/n-acd-bpf-fallback.c +@WITH_EBPF_TRUE@am__objects_12 = \ +@WITH_EBPF_TRUE@ src/n-acd/src/libn_acd_la-n-acd-bpf.lo +@WITH_EBPF_FALSE@am__objects_13 = src/n-acd/src/libn_acd_la-n-acd-bpf-fallback.lo +am_src_n_acd_libn_acd_la_OBJECTS = src/n-acd/src/libn_acd_la-n-acd.lo \ + src/n-acd/src/libn_acd_la-n-acd-probe.lo \ + src/n-acd/src/util/libn_acd_la-timer.lo $(am__objects_12) \ + $(am__objects_13) +src_n_acd_libn_acd_la_OBJECTS = $(am_src_n_acd_libn_acd_la_OBJECTS) +src_n_acd_libn_acd_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) \ + $(src_n_acd_libn_acd_la_LDFLAGS) $(LDFLAGS) -o $@ +src_n_dhcp4_libn_dhcp4_la_LIBADD = +am_src_n_dhcp4_libn_dhcp4_la_OBJECTS = \ + src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-connection.lo \ + src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-lease.lo \ + src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-probe.lo \ + src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-client.lo \ + src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-incoming.lo \ + src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-outgoing.lo \ + src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-socket.lo \ + src/n-dhcp4/src/util/libn_dhcp4_la-packet.lo \ + src/n-dhcp4/src/util/libn_dhcp4_la-socket.lo +src_n_dhcp4_libn_dhcp4_la_OBJECTS = \ + $(am_src_n_dhcp4_libn_dhcp4_la_OBJECTS) +src_n_dhcp4_libn_dhcp4_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) \ + $(src_n_dhcp4_libn_dhcp4_la_LDFLAGS) $(LDFLAGS) -o $@ +src_nm_dispatcher_libnm_dispatcher_core_la_DEPENDENCIES = \ + src/libnm-client-impl/libnm.la $(am__DEPENDENCIES_1) +am_src_nm_dispatcher_libnm_dispatcher_core_la_OBJECTS = src/nm-dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo +src_nm_dispatcher_libnm_dispatcher_core_la_OBJECTS = \ + $(am_src_nm_dispatcher_libnm_dispatcher_core_la_OBJECTS) +src_nm_initrd_generator_libnmi_core_la_LIBADD = +am_src_nm_initrd_generator_libnmi_core_la_OBJECTS = \ + src/nm-initrd-generator/libnmi_core_la-nmi-cmdline-reader.lo \ + src/nm-initrd-generator/libnmi_core_la-nmi-dt-reader.lo \ + src/nm-initrd-generator/libnmi_core_la-nmi-ibft-reader.lo +src_nm_initrd_generator_libnmi_core_la_OBJECTS = \ + $(am_src_nm_initrd_generator_libnmi_core_la_OBJECTS) examples_C_glib_add_connection_gdbus_SOURCES = \ examples/C/glib/add-connection-gdbus.c examples_C_glib_add_connection_gdbus_OBJECTS = examples/C/glib/add_connection_gdbus-add-connection-gdbus.$(OBJEXT) @@ -1881,8 +1612,8 @@ examples_C_glib_add_connection_gdbus_DEPENDENCIES = \ examples_C_glib_add_connection_libnm_SOURCES = \ examples/C/glib/add-connection-libnm.c examples_C_glib_add_connection_libnm_OBJECTS = examples/C/glib/add_connection_libnm-add-connection-libnm.$(OBJEXT) -examples_C_glib_add_connection_libnm_DEPENDENCIES = libnm/libnm.la \ - $(am__DEPENDENCIES_1) +examples_C_glib_add_connection_libnm_DEPENDENCIES = \ + src/libnm-client-impl/libnm.la $(am__DEPENDENCIES_1) examples_C_glib_get_active_connections_gdbus_SOURCES = \ examples/C/glib/get-active-connections-gdbus.c examples_C_glib_get_active_connections_gdbus_OBJECTS = examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.$(OBJEXT) @@ -1892,8 +1623,8 @@ examples_C_glib_get_ap_info_libnm_SOURCES = \ examples/C/glib/get-ap-info-libnm.c examples_C_glib_get_ap_info_libnm_OBJECTS = \ examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.$(OBJEXT) -examples_C_glib_get_ap_info_libnm_DEPENDENCIES = libnm/libnm.la \ - $(am__DEPENDENCIES_1) +examples_C_glib_get_ap_info_libnm_DEPENDENCIES = \ + src/libnm-client-impl/libnm.la $(am__DEPENDENCIES_1) examples_C_glib_list_connections_gdbus_SOURCES = \ examples/C/glib/list-connections-gdbus.c examples_C_glib_list_connections_gdbus_OBJECTS = examples/C/glib/list_connections_gdbus-list-connections-gdbus.$(OBJEXT) @@ -1902,8 +1633,8 @@ examples_C_glib_list_connections_gdbus_DEPENDENCIES = \ examples_C_glib_list_connections_libnm_SOURCES = \ examples/C/glib/list-connections-libnm.c examples_C_glib_list_connections_libnm_OBJECTS = examples/C/glib/list_connections_libnm-list-connections-libnm.$(OBJEXT) -examples_C_glib_list_connections_libnm_DEPENDENCIES = libnm/libnm.la \ - $(am__DEPENDENCIES_1) +examples_C_glib_list_connections_libnm_DEPENDENCIES = \ + src/libnm-client-impl/libnm.la $(am__DEPENDENCIES_1) examples_C_glib_monitor_nm_running_gdbus_SOURCES = \ examples/C/glib/monitor-nm-running-gdbus.c examples_C_glib_monitor_nm_running_gdbus_OBJECTS = examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.$(OBJEXT) @@ -1914,6 +1645,12 @@ examples_C_glib_monitor_nm_state_gdbus_SOURCES = \ examples_C_glib_monitor_nm_state_gdbus_OBJECTS = examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.$(OBJEXT) examples_C_glib_monitor_nm_state_gdbus_DEPENDENCIES = \ $(am__DEPENDENCIES_1) +examples_C_glib_vpn_import_libnm_SOURCES = \ + examples/C/glib/vpn-import-libnm.c +examples_C_glib_vpn_import_libnm_OBJECTS = \ + examples/C/glib/vpn_import_libnm-vpn-import-libnm.$(OBJEXT) +examples_C_glib_vpn_import_libnm_DEPENDENCIES = \ + src/libnm-client-impl/libnm.la $(am__DEPENDENCIES_1) am__examples_C_qt_add_connection_wired_SOURCES_DIST = \ examples/C/qt/add-connection-wired.cpp @WITH_QT_TRUE@am_examples_C_qt_add_connection_wired_OBJECTS = examples/C/qt/add_connection_wired-add-connection-wired.$(OBJEXT) @@ -1942,161 +1679,6 @@ examples_C_qt_monitor_nm_running_OBJECTS = \ $(am_examples_C_qt_monitor_nm_running_OBJECTS) @WITH_QT_TRUE@examples_C_qt_monitor_nm_running_DEPENDENCIES = \ @WITH_QT_TRUE@ $(am__DEPENDENCIES_1) -libnm_core_tests_test_compare_SOURCES = \ - libnm-core/tests/test-compare.c -libnm_core_tests_test_compare_OBJECTS = \ - libnm-core/tests/test_compare-test-compare.$(OBJEXT) -am__DEPENDENCIES_3 = \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/systemd/libnm-systemd-logging-stub.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ - $(am__DEPENDENCIES_1) -libnm_core_tests_test_compare_DEPENDENCIES = $(am__DEPENDENCIES_3) -libnm_core_tests_test_compare_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_core_tests_test_compare_LDFLAGS) $(LDFLAGS) -o $@ -libnm_core_tests_test_crypto_SOURCES = libnm-core/tests/test-crypto.c -libnm_core_tests_test_crypto_OBJECTS = \ - libnm-core/tests/test_crypto-test-crypto.$(OBJEXT) -libnm_core_tests_test_crypto_DEPENDENCIES = $(am__DEPENDENCIES_3) -libnm_core_tests_test_crypto_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libnm_core_tests_test_crypto_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_libnm_core_tests_test_general_OBJECTS = \ - libnm-core/tests/test_general-test-general.$(OBJEXT) -nodist_libnm_core_tests_test_general_OBJECTS = libnm-core/tests/test_general-nm-core-tests-enum-types.$(OBJEXT) -libnm_core_tests_test_general_OBJECTS = \ - $(am_libnm_core_tests_test_general_OBJECTS) \ - $(nodist_libnm_core_tests_test_general_OBJECTS) -libnm_core_tests_test_general_DEPENDENCIES = $(am__DEPENDENCIES_3) -libnm_core_tests_test_general_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_core_tests_test_general_LDFLAGS) $(LDFLAGS) -o $@ -libnm_core_tests_test_keyfile_SOURCES = \ - libnm-core/tests/test-keyfile.c -libnm_core_tests_test_keyfile_OBJECTS = \ - libnm-core/tests/test_keyfile-test-keyfile.$(OBJEXT) -libnm_core_tests_test_keyfile_DEPENDENCIES = $(am__DEPENDENCIES_3) -libnm_core_tests_test_keyfile_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_core_tests_test_keyfile_LDFLAGS) $(LDFLAGS) -o $@ -libnm_core_tests_test_secrets_SOURCES = \ - libnm-core/tests/test-secrets.c -libnm_core_tests_test_secrets_OBJECTS = \ - libnm-core/tests/test_secrets-test-secrets.$(OBJEXT) -libnm_core_tests_test_secrets_DEPENDENCIES = $(am__DEPENDENCIES_3) -libnm_core_tests_test_secrets_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_core_tests_test_secrets_LDFLAGS) $(LDFLAGS) -o $@ -libnm_core_tests_test_setting_SOURCES = \ - libnm-core/tests/test-setting.c -libnm_core_tests_test_setting_OBJECTS = \ - libnm-core/tests/test_setting-test-setting.$(OBJEXT) -libnm_core_tests_test_setting_DEPENDENCIES = $(am__DEPENDENCIES_3) -libnm_core_tests_test_setting_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_core_tests_test_setting_LDFLAGS) $(LDFLAGS) -o $@ -libnm_core_tests_test_settings_defaults_SOURCES = \ - libnm-core/tests/test-settings-defaults.c -libnm_core_tests_test_settings_defaults_OBJECTS = libnm-core/tests/test_settings_defaults-test-settings-defaults.$(OBJEXT) -libnm_core_tests_test_settings_defaults_DEPENDENCIES = \ - $(am__DEPENDENCIES_3) -libnm_core_tests_test_settings_defaults_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_core_tests_test_settings_defaults_LDFLAGS) $(LDFLAGS) \ - -o $@ -am_libnm_tests_test_libnm_OBJECTS = \ - shared/nm-utils/libnm_tests_test_libnm-nm-compat.$(OBJEXT) \ - libnm/tests/test_libnm-test-libnm.$(OBJEXT) -libnm_tests_test_libnm_OBJECTS = $(am_libnm_tests_test_libnm_OBJECTS) -am__DEPENDENCIES_4 = libnm/libnm_static.la $(am__DEPENDENCIES_1) -libnm_tests_test_libnm_DEPENDENCIES = $(am__DEPENDENCIES_4) -libnm_tests_test_libnm_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libnm_tests_test_libnm_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_libnm_tests_test_nm_client_OBJECTS = shared/libnm_tests_test_nm_client-nm-test-utils-impl.$(OBJEXT) \ - libnm/tests/test_nm_client-test-nm-client.$(OBJEXT) -libnm_tests_test_nm_client_OBJECTS = \ - $(am_libnm_tests_test_nm_client_OBJECTS) -libnm_tests_test_nm_client_DEPENDENCIES = $(am__DEPENDENCIES_4) -libnm_tests_test_nm_client_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libnm_tests_test_nm_client_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_libnm_tests_test_remote_settings_client_OBJECTS = shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.$(OBJEXT) \ - libnm/tests/test_remote_settings_client-test-remote-settings-client.$(OBJEXT) -libnm_tests_test_remote_settings_client_OBJECTS = \ - $(am_libnm_tests_test_remote_settings_client_OBJECTS) -libnm_tests_test_remote_settings_client_DEPENDENCIES = \ - $(am__DEPENDENCIES_4) -libnm_tests_test_remote_settings_client_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_tests_test_remote_settings_client_LDFLAGS) $(LDFLAGS) \ - -o $@ -am_libnm_tests_test_secret_agent_OBJECTS = shared/libnm_tests_test_secret_agent-nm-test-utils-impl.$(OBJEXT) \ - libnm/tests/test_secret_agent-test-secret-agent.$(OBJEXT) -libnm_tests_test_secret_agent_OBJECTS = \ - $(am_libnm_tests_test_secret_agent_OBJECTS) -libnm_tests_test_secret_agent_DEPENDENCIES = $(am__DEPENDENCIES_4) -libnm_tests_test_secret_agent_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_tests_test_secret_agent_LDFLAGS) $(LDFLAGS) -o $@ -shared_nm_glib_aux_tests_test_json_aux_SOURCES = \ - shared/nm-glib-aux/tests/test-json-aux.c -shared_nm_glib_aux_tests_test_json_aux_OBJECTS = shared/nm-glib-aux/tests/test_json_aux-test-json-aux.$(OBJEXT) -@WITH_JANSSON_TRUE@shared_nm_glib_aux_tests_test_json_aux_DEPENDENCIES = \ -@WITH_JANSSON_TRUE@ $(am__DEPENDENCIES_1) \ -@WITH_JANSSON_TRUE@ shared/nm-glib-aux/libnm-glib-aux.la \ -@WITH_JANSSON_TRUE@ shared/systemd/libnm-systemd-logging-stub.la \ -@WITH_JANSSON_TRUE@ shared/nm-std-aux/libnm-std-aux.la \ -@WITH_JANSSON_TRUE@ shared/libcsiphash.la $(am__DEPENDENCIES_1) -shared_nm_glib_aux_tests_test_json_aux_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(shared_nm_glib_aux_tests_test_json_aux_LDFLAGS) $(LDFLAGS) \ - -o $@ -shared_nm_glib_aux_tests_test_shared_general_SOURCES = \ - shared/nm-glib-aux/tests/test-shared-general.c -shared_nm_glib_aux_tests_test_shared_general_OBJECTS = shared/nm-glib-aux/tests/test_shared_general-test-shared-general.$(OBJEXT) -shared_nm_glib_aux_tests_test_shared_general_DEPENDENCIES = \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/systemd/libnm-systemd-logging-stub.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ - $(am__DEPENDENCIES_1) -shared_nm_glib_aux_tests_test_shared_general_LINK = $(LIBTOOL) \ - $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(shared_nm_glib_aux_tests_test_shared_general_LDFLAGS) \ - $(LDFLAGS) -o $@ -shared_nm_platform_tests_test_nm_platform_SOURCES = \ - shared/nm-platform/tests/test-nm-platform.c -shared_nm_platform_tests_test_nm_platform_OBJECTS = shared/nm-platform/tests/test_nm_platform-test-nm-platform.$(OBJEXT) -shared_nm_platform_tests_test_nm_platform_DEPENDENCIES = \ - shared/nm-platform/libnm-platform.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -shared_nm_platform_tests_test_nm_platform_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(shared_nm_platform_tests_test_nm_platform_LDFLAGS) \ - $(LDFLAGS) -o $@ am_src_core_NetworkManager_OBJECTS = \ src/core/NetworkManager-main.$(OBJEXT) src_core_NetworkManager_OBJECTS = \ @@ -2217,81 +1799,13 @@ src_core_dnsmasq_tests_test_dnsmasq_utils_LINK = $(LIBTOOL) $(AM_V_lt) \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(src_core_dnsmasq_tests_test_dnsmasq_utils_LDFLAGS) \ $(LDFLAGS) -o $@ -am_src_core_initrd_nm_initrd_generator_OBJECTS = src/core/initrd/nm_initrd_generator-nm-initrd-generator.$(OBJEXT) -src_core_initrd_nm_initrd_generator_OBJECTS = \ - $(am_src_core_initrd_nm_initrd_generator_OBJECTS) -src_core_initrd_nm_initrd_generator_DEPENDENCIES = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerBase.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-platform/libnm-platform.la \ - shared/nm-base/libnm-base.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libndhcp4.la \ - shared/libcsiphash.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) -src_core_initrd_nm_initrd_generator_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(src_core_initrd_nm_initrd_generator_LDFLAGS) $(LDFLAGS) -o \ - $@ -src_core_initrd_tests_test_cmdline_reader_SOURCES = \ - src/core/initrd/tests/test-cmdline-reader.c -src_core_initrd_tests_test_cmdline_reader_OBJECTS = src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.$(OBJEXT) -src_core_initrd_tests_test_cmdline_reader_DEPENDENCIES = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerTest.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ - $(am__DEPENDENCIES_1) -src_core_initrd_tests_test_cmdline_reader_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(src_core_initrd_tests_test_cmdline_reader_LDFLAGS) \ - $(LDFLAGS) -o $@ -src_core_initrd_tests_test_dt_reader_SOURCES = \ - src/core/initrd/tests/test-dt-reader.c -src_core_initrd_tests_test_dt_reader_OBJECTS = \ - src/core/initrd/tests/test_dt_reader-test-dt-reader.$(OBJEXT) -src_core_initrd_tests_test_dt_reader_DEPENDENCIES = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerTest.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ - $(am__DEPENDENCIES_1) -src_core_initrd_tests_test_dt_reader_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(src_core_initrd_tests_test_dt_reader_LDFLAGS) $(LDFLAGS) -o \ - $@ -src_core_initrd_tests_test_ibft_reader_SOURCES = \ - src/core/initrd/tests/test-ibft-reader.c -src_core_initrd_tests_test_ibft_reader_OBJECTS = src/core/initrd/tests/test_ibft_reader-test-ibft-reader.$(OBJEXT) -src_core_initrd_tests_test_ibft_reader_DEPENDENCIES = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerTest.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la shared/libcsiphash.la \ - $(am__DEPENDENCIES_1) -src_core_initrd_tests_test_ibft_reader_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(src_core_initrd_tests_test_ibft_reader_LDFLAGS) $(LDFLAGS) \ - -o $@ src_core_ndisc_tests_test_ndisc_fake_SOURCES = \ src/core/ndisc/tests/test-ndisc-fake.c src_core_ndisc_tests_test_ndisc_fake_OBJECTS = src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.$(OBJEXT) -am__DEPENDENCIES_5 = src/core/libNetworkManagerTest.la \ +am__DEPENDENCIES_3 = src/core/libNetworkManagerTest.la \ $(am__DEPENDENCIES_1) src_core_ndisc_tests_test_ndisc_fake_DEPENDENCIES = \ - $(am__DEPENDENCIES_5) + $(am__DEPENDENCIES_3) src_core_ndisc_tests_test_ndisc_fake_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2301,7 +1815,7 @@ src_core_ndisc_tests_test_ndisc_linux_SOURCES = \ src/core/ndisc/tests/test-ndisc-linux.c src_core_ndisc_tests_test_ndisc_linux_OBJECTS = src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.$(OBJEXT) src_core_ndisc_tests_test_ndisc_linux_DEPENDENCIES = \ - $(am__DEPENDENCIES_5) + $(am__DEPENDENCIES_3) src_core_ndisc_tests_test_ndisc_linux_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2313,18 +1827,19 @@ src_core_nm_iface_helper_OBJECTS = \ $(am_src_core_nm_iface_helper_OBJECTS) src_core_nm_iface_helper_DEPENDENCIES = \ src/core/libNetworkManagerBase.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-platform/libnm-platform.la \ - shared/nm-base/libnm-base.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la $(libnm_crypto_lib) \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ src/core/libnm-systemd-core.la \ - shared/systemd/libnm-systemd-shared.la shared/libnacd.la \ - shared/libndhcp4.la shared/libcrbtree.la shared/libcsiphash.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/n-acd/libn-acd.la src/n-dhcp4/libn-dhcp4.la \ + src/c-rbtree/libc-rbtree.la src/c-siphash/libc-siphash.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) @@ -2336,9 +1851,9 @@ src_core_platform_tests_monitor_SOURCES = \ src/core/platform/tests/monitor.c src_core_platform_tests_monitor_OBJECTS = \ src/core/platform/tests/monitor-monitor.$(OBJEXT) -am__DEPENDENCIES_6 = src/core/libNetworkManagerTest.la \ +am__DEPENDENCIES_4 = src/core/libNetworkManagerTest.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -src_core_platform_tests_monitor_DEPENDENCIES = $(am__DEPENDENCIES_6) +src_core_platform_tests_monitor_DEPENDENCIES = $(am__DEPENDENCIES_4) src_core_platform_tests_monitor_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) \ @@ -2347,7 +1862,7 @@ am_src_core_platform_tests_test_address_fake_OBJECTS = src/core/platform/tests/t src_core_platform_tests_test_address_fake_OBJECTS = \ $(am_src_core_platform_tests_test_address_fake_OBJECTS) src_core_platform_tests_test_address_fake_DEPENDENCIES = \ - $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_4) src_core_platform_tests_test_address_fake_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2357,7 +1872,7 @@ am_src_core_platform_tests_test_address_linux_OBJECTS = src/core/platform/tests/ src_core_platform_tests_test_address_linux_OBJECTS = \ $(am_src_core_platform_tests_test_address_linux_OBJECTS) src_core_platform_tests_test_address_linux_DEPENDENCIES = \ - $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_4) src_core_platform_tests_test_address_linux_LINK = $(LIBTOOL) \ $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2367,7 +1882,7 @@ am_src_core_platform_tests_test_cleanup_fake_OBJECTS = src/core/platform/tests/t src_core_platform_tests_test_cleanup_fake_OBJECTS = \ $(am_src_core_platform_tests_test_cleanup_fake_OBJECTS) src_core_platform_tests_test_cleanup_fake_DEPENDENCIES = \ - $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_4) src_core_platform_tests_test_cleanup_fake_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2377,7 +1892,7 @@ am_src_core_platform_tests_test_cleanup_linux_OBJECTS = src/core/platform/tests/ src_core_platform_tests_test_cleanup_linux_OBJECTS = \ $(am_src_core_platform_tests_test_cleanup_linux_OBJECTS) src_core_platform_tests_test_cleanup_linux_DEPENDENCIES = \ - $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_4) src_core_platform_tests_test_cleanup_linux_LINK = $(LIBTOOL) \ $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2388,7 +1903,7 @@ am_src_core_platform_tests_test_link_fake_OBJECTS = \ src_core_platform_tests_test_link_fake_OBJECTS = \ $(am_src_core_platform_tests_test_link_fake_OBJECTS) src_core_platform_tests_test_link_fake_DEPENDENCIES = \ - $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_4) src_core_platform_tests_test_link_fake_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2399,7 +1914,7 @@ am_src_core_platform_tests_test_link_linux_OBJECTS = \ src_core_platform_tests_test_link_linux_OBJECTS = \ $(am_src_core_platform_tests_test_link_linux_OBJECTS) src_core_platform_tests_test_link_linux_DEPENDENCIES = \ - $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_4) src_core_platform_tests_test_link_linux_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2430,7 +1945,7 @@ am_src_core_platform_tests_test_route_fake_OBJECTS = \ src_core_platform_tests_test_route_fake_OBJECTS = \ $(am_src_core_platform_tests_test_route_fake_OBJECTS) src_core_platform_tests_test_route_fake_DEPENDENCIES = \ - $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_4) src_core_platform_tests_test_route_fake_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2441,7 +1956,7 @@ am_src_core_platform_tests_test_route_linux_OBJECTS = \ src_core_platform_tests_test_route_linux_OBJECTS = \ $(am_src_core_platform_tests_test_route_linux_OBJECTS) src_core_platform_tests_test_route_linux_DEPENDENCIES = \ - $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_4) src_core_platform_tests_test_route_linux_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2452,7 +1967,7 @@ am_src_core_platform_tests_test_tc_fake_OBJECTS = \ src_core_platform_tests_test_tc_fake_OBJECTS = \ $(am_src_core_platform_tests_test_tc_fake_OBJECTS) src_core_platform_tests_test_tc_fake_DEPENDENCIES = \ - $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_4) src_core_platform_tests_test_tc_fake_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2463,7 +1978,7 @@ am_src_core_platform_tests_test_tc_linux_OBJECTS = \ src_core_platform_tests_test_tc_linux_OBJECTS = \ $(am_src_core_platform_tests_test_tc_linux_OBJECTS) src_core_platform_tests_test_tc_linux_DEPENDENCIES = \ - $(am__DEPENDENCIES_6) + $(am__DEPENDENCIES_4) src_core_platform_tests_test_tc_linux_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -2578,8 +2093,9 @@ src_core_tests_test_systemd_OBJECTS = \ src/core/tests/test_systemd-test-systemd.$(OBJEXT) src_core_tests_test_systemd_DEPENDENCIES = \ src/core/libnm-systemd-core.la \ - shared/systemd/libnm-systemd-shared.la shared/libcsiphash.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/c-siphash/libc-siphash.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) src_core_tests_test_systemd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(src_core_tests_test_systemd_LDFLAGS) \ @@ -2601,132 +2117,553 @@ src_core_tests_test_wired_defname_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(src_core_tests_test_wired_defname_LDFLAGS) $(LDFLAGS) -o $@ -am__dist_libexec_SCRIPTS_DIST = \ - src/core/settings/plugins/ifcfg-rh/nm-ifup \ - src/core/settings/plugins/ifcfg-rh/nm-ifdown -SCRIPTS = $(dist_libexec_SCRIPTS) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = clients/$(DEPDIR)/nm_online-nm-online.Po \ - clients/cli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po \ - clients/cli/$(DEPDIR)/nmcli-agent.Po \ - clients/cli/$(DEPDIR)/nmcli-common.Po \ - clients/cli/$(DEPDIR)/nmcli-connections.Po \ - clients/cli/$(DEPDIR)/nmcli-devices.Po \ - clients/cli/$(DEPDIR)/nmcli-general.Po \ - clients/cli/$(DEPDIR)/nmcli-nmcli.Po \ - clients/cli/$(DEPDIR)/nmcli-polkit-agent.Po \ - clients/cli/$(DEPDIR)/nmcli-settings.Po \ - clients/cli/$(DEPDIR)/nmcli-utils.Po \ - clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po \ - clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po \ - clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po \ - clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po \ - clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po \ - clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po \ - clients/cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po \ - clients/cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po \ - clients/common/$(DEPDIR)/libnmc_base_la-nm-client-utils.Plo \ - clients/common/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Plo \ - clients/common/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Plo \ - clients/common/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Plo \ - clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-access.Plo \ - clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-base-impl.Plo \ - clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-desc.Plo \ - clients/common/tests/$(DEPDIR)/test_clients_common-test-clients-common.Po \ - clients/common/tests/$(DEPDIR)/test_libnm_core_aux-test-libnm-core-aux.Po \ - clients/tui/$(DEPDIR)/nmtui-nm-editor-bindings.Po \ - clients/tui/$(DEPDIR)/nmtui-nm-editor-utils.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-address-list.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-device-entry.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-editor-grid.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-editor-page.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-editor-section.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-editor.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-ip-entry.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-mac-entry.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-bond.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-dsl.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-ip4.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-ip6.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-ppp.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-team-port.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-team.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-vlan.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-page-wifi.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-password-dialog.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-password-fields.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-route-editor.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-route-entry.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-route-table.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-slave-list.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-utils.Po \ - clients/tui/$(DEPDIR)/nmtui-nmt-widget-list.Po \ - clients/tui/$(DEPDIR)/nmtui-nmtui-connect.Po \ - clients/tui/$(DEPDIR)/nmtui-nmtui-edit.Po \ - clients/tui/$(DEPDIR)/nmtui-nmtui-hostname.Po \ - clients/tui/$(DEPDIR)/nmtui-nmtui.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po \ - clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po \ - dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Plo \ - dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po \ - dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po \ - dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po \ - examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po \ - examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Po \ - examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Po \ - examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Po \ - examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Po \ - examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Po \ - examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Po \ - examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Po \ - examples/C/qt/$(DEPDIR)/add_connection_wired-add-connection-wired.Po \ - examples/C/qt/$(DEPDIR)/change_ipv4_addresses-change-ipv4-addresses.Po \ - examples/C/qt/$(DEPDIR)/list_connections-list-connections.Po \ - examples/C/qt/$(DEPDIR)/monitor_nm_running-monitor-nm-running.Po \ - introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.AccessPoint.Plo \ - introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.AgentManager.Plo \ - introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.Checkpoint.Plo \ +src_libnm_client_aux_extern_tests_test_libnm_client_aux_SOURCES = \ + src/libnm-client-aux-extern/tests/test-libnm-client-aux.c +src_libnm_client_aux_extern_tests_test_libnm_client_aux_OBJECTS = src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.$(OBJEXT) +src_libnm_client_aux_extern_tests_test_libnm_client_aux_DEPENDENCIES = \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la src/libnm-client-impl/libnm.la \ + $(am__DEPENDENCIES_1) +src_libnm_client_aux_extern_tests_test_libnm_client_aux_LINK = \ + $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_client_aux_extern_tests_test_libnm_client_aux_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_src_libnm_client_impl_tests_test_libnm_OBJECTS = src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.$(OBJEXT) \ + src/libnm-client-impl/tests/test_libnm-test-libnm.$(OBJEXT) +src_libnm_client_impl_tests_test_libnm_OBJECTS = \ + $(am_src_libnm_client_impl_tests_test_libnm_OBJECTS) +am__DEPENDENCIES_5 = src/libnm-client-test/libnm-client-test.la \ + src/libnm-client-impl/libnm-client-impl.la \ + $(am__DEPENDENCIES_1) +src_libnm_client_impl_tests_test_libnm_DEPENDENCIES = \ + $(am__DEPENDENCIES_5) +src_libnm_client_impl_tests_test_libnm_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_client_impl_tests_test_libnm_LDFLAGS) $(LDFLAGS) \ + -o $@ +src_libnm_client_impl_tests_test_nm_client_SOURCES = \ + src/libnm-client-impl/tests/test-nm-client.c +src_libnm_client_impl_tests_test_nm_client_OBJECTS = src/libnm-client-impl/tests/test_nm_client-test-nm-client.$(OBJEXT) +src_libnm_client_impl_tests_test_nm_client_DEPENDENCIES = \ + $(am__DEPENDENCIES_5) +src_libnm_client_impl_tests_test_nm_client_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_client_impl_tests_test_nm_client_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_libnm_client_impl_tests_test_remote_settings_client_SOURCES = \ + src/libnm-client-impl/tests/test-remote-settings-client.c +src_libnm_client_impl_tests_test_remote_settings_client_OBJECTS = src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.$(OBJEXT) +src_libnm_client_impl_tests_test_remote_settings_client_DEPENDENCIES = \ + $(am__DEPENDENCIES_5) +src_libnm_client_impl_tests_test_remote_settings_client_LINK = \ + $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_client_impl_tests_test_remote_settings_client_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_libnm_client_impl_tests_test_secret_agent_SOURCES = \ + src/libnm-client-impl/tests/test-secret-agent.c +src_libnm_client_impl_tests_test_secret_agent_OBJECTS = src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.$(OBJEXT) +src_libnm_client_impl_tests_test_secret_agent_DEPENDENCIES = \ + $(am__DEPENDENCIES_5) +src_libnm_client_impl_tests_test_secret_agent_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_client_impl_tests_test_secret_agent_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_libnm_core_impl_tests_test_compare_SOURCES = \ + src/libnm-core-impl/tests/test-compare.c +src_libnm_core_impl_tests_test_compare_OBJECTS = \ + src/libnm-core-impl/tests/test_compare-test-compare.$(OBJEXT) +am__DEPENDENCIES_6 = \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la $(libnm_crypto_lib) \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la $(am__DEPENDENCIES_1) +src_libnm_core_impl_tests_test_compare_DEPENDENCIES = \ + $(am__DEPENDENCIES_6) +src_libnm_core_impl_tests_test_compare_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_core_impl_tests_test_compare_LDFLAGS) $(LDFLAGS) \ + -o $@ +src_libnm_core_impl_tests_test_crypto_SOURCES = \ + src/libnm-core-impl/tests/test-crypto.c +src_libnm_core_impl_tests_test_crypto_OBJECTS = \ + src/libnm-core-impl/tests/test_crypto-test-crypto.$(OBJEXT) +src_libnm_core_impl_tests_test_crypto_DEPENDENCIES = \ + $(am__DEPENDENCIES_6) +src_libnm_core_impl_tests_test_crypto_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_core_impl_tests_test_crypto_LDFLAGS) $(LDFLAGS) -o \ + $@ +am_src_libnm_core_impl_tests_test_general_OBJECTS = \ + src/libnm-core-impl/tests/test_general-test-general.$(OBJEXT) +nodist_src_libnm_core_impl_tests_test_general_OBJECTS = src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.$(OBJEXT) +src_libnm_core_impl_tests_test_general_OBJECTS = \ + $(am_src_libnm_core_impl_tests_test_general_OBJECTS) \ + $(nodist_src_libnm_core_impl_tests_test_general_OBJECTS) +src_libnm_core_impl_tests_test_general_DEPENDENCIES = \ + $(am__DEPENDENCIES_6) +src_libnm_core_impl_tests_test_general_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_core_impl_tests_test_general_LDFLAGS) $(LDFLAGS) \ + -o $@ +src_libnm_core_impl_tests_test_keyfile_SOURCES = \ + src/libnm-core-impl/tests/test-keyfile.c +src_libnm_core_impl_tests_test_keyfile_OBJECTS = \ + src/libnm-core-impl/tests/test_keyfile-test-keyfile.$(OBJEXT) +src_libnm_core_impl_tests_test_keyfile_DEPENDENCIES = \ + $(am__DEPENDENCIES_6) +src_libnm_core_impl_tests_test_keyfile_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_core_impl_tests_test_keyfile_LDFLAGS) $(LDFLAGS) \ + -o $@ +src_libnm_core_impl_tests_test_secrets_SOURCES = \ + src/libnm-core-impl/tests/test-secrets.c +src_libnm_core_impl_tests_test_secrets_OBJECTS = \ + src/libnm-core-impl/tests/test_secrets-test-secrets.$(OBJEXT) +src_libnm_core_impl_tests_test_secrets_DEPENDENCIES = \ + $(am__DEPENDENCIES_6) +src_libnm_core_impl_tests_test_secrets_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_core_impl_tests_test_secrets_LDFLAGS) $(LDFLAGS) \ + -o $@ +src_libnm_core_impl_tests_test_setting_SOURCES = \ + src/libnm-core-impl/tests/test-setting.c +src_libnm_core_impl_tests_test_setting_OBJECTS = \ + src/libnm-core-impl/tests/test_setting-test-setting.$(OBJEXT) +src_libnm_core_impl_tests_test_setting_DEPENDENCIES = \ + $(am__DEPENDENCIES_6) +src_libnm_core_impl_tests_test_setting_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_core_impl_tests_test_setting_LDFLAGS) $(LDFLAGS) \ + -o $@ +src_libnm_core_impl_tests_test_settings_defaults_SOURCES = \ + src/libnm-core-impl/tests/test-settings-defaults.c +src_libnm_core_impl_tests_test_settings_defaults_OBJECTS = src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.$(OBJEXT) +src_libnm_core_impl_tests_test_settings_defaults_DEPENDENCIES = \ + $(am__DEPENDENCIES_6) +src_libnm_core_impl_tests_test_settings_defaults_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_core_impl_tests_test_settings_defaults_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_libnm_glib_aux_tests_test_json_aux_SOURCES = \ + src/libnm-glib-aux/tests/test-json-aux.c +src_libnm_glib_aux_tests_test_json_aux_OBJECTS = src/libnm-glib-aux/tests/test_json_aux-test-json-aux.$(OBJEXT) +@WITH_JANSSON_TRUE@src_libnm_glib_aux_tests_test_json_aux_DEPENDENCIES = \ +@WITH_JANSSON_TRUE@ $(am__DEPENDENCIES_1) \ +@WITH_JANSSON_TRUE@ src/libnm-glib-aux/libnm-glib-aux.la \ +@WITH_JANSSON_TRUE@ src/libnm-log-null/libnm-log-null.la \ +@WITH_JANSSON_TRUE@ src/libnm-std-aux/libnm-std-aux.la \ +@WITH_JANSSON_TRUE@ src/c-siphash/libc-siphash.la \ +@WITH_JANSSON_TRUE@ $(am__DEPENDENCIES_1) +src_libnm_glib_aux_tests_test_json_aux_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_glib_aux_tests_test_json_aux_LDFLAGS) $(LDFLAGS) \ + -o $@ +src_libnm_glib_aux_tests_test_shared_general_SOURCES = \ + src/libnm-glib-aux/tests/test-shared-general.c +src_libnm_glib_aux_tests_test_shared_general_OBJECTS = src/libnm-glib-aux/tests/test_shared_general-test-shared-general.$(OBJEXT) +src_libnm_glib_aux_tests_test_shared_general_DEPENDENCIES = \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la $(am__DEPENDENCIES_1) +src_libnm_glib_aux_tests_test_shared_general_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_glib_aux_tests_test_shared_general_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_libnm_platform_tests_test_nm_platform_SOURCES = \ + src/libnm-platform/tests/test-nm-platform.c +src_libnm_platform_tests_test_nm_platform_OBJECTS = src/libnm-platform/tests/test_nm_platform-test-nm-platform.$(OBJEXT) +src_libnm_platform_tests_test_nm_platform_DEPENDENCIES = \ + src/libnm-platform/libnm-platform.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +src_libnm_platform_tests_test_nm_platform_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnm_platform_tests_test_nm_platform_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_libnmc_setting_tests_test_libnmc_setting_SOURCES = \ + src/libnmc-setting/tests/test-libnmc-setting.c +src_libnmc_setting_tests_test_libnmc_setting_OBJECTS = src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.$(OBJEXT) +src_libnmc_setting_tests_test_libnmc_setting_DEPENDENCIES = \ + src/libnmc-setting/libnmc-setting.la \ + src/libnmc-base/libnmc-base.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la src/libnm-client-impl/libnm.la \ + $(am__DEPENDENCIES_1) +src_libnmc_setting_tests_test_libnmc_setting_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_libnmc_setting_tests_test_libnmc_setting_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__src_nm_cloud_setup_nm_cloud_setup_SOURCES_DIST = \ + src/nm-cloud-setup/main.c +@BUILD_NM_CLOUD_SETUP_TRUE@am_src_nm_cloud_setup_nm_cloud_setup_OBJECTS = src/nm-cloud-setup/nm_cloud_setup-main.$(OBJEXT) +src_nm_cloud_setup_nm_cloud_setup_OBJECTS = \ + $(am_src_nm_cloud_setup_nm_cloud_setup_OBJECTS) +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_nm_cloud_setup_DEPENDENCIES = src/nm-cloud-setup/libnm-cloud-setup-core.a \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-client-aux-extern/libnm-client-aux-extern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-core-aux-extern/libnm-core-aux-extern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-core-aux-intern/libnm-core-aux-intern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-base/libnm-base.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-glib-aux/libnm-glib-aux.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-std-aux/libnm-std-aux.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/c-siphash/libc-siphash.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-client-impl/libnm.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ $(am__DEPENDENCIES_1) \ +@BUILD_NM_CLOUD_SETUP_TRUE@ $(am__DEPENDENCIES_1) +src_nm_cloud_setup_nm_cloud_setup_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_nm_cloud_setup_nm_cloud_setup_LDFLAGS) $(LDFLAGS) -o $@ +src_nm_cloud_setup_tests_test_cloud_setup_general_SOURCES = \ + src/nm-cloud-setup/tests/test-cloud-setup-general.c +src_nm_cloud_setup_tests_test_cloud_setup_general_OBJECTS = src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.$(OBJEXT) +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_tests_test_cloud_setup_general_DEPENDENCIES = src/nm-cloud-setup/libnm-cloud-setup-core.a \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-client-aux-extern/libnm-client-aux-extern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-core-aux-extern/libnm-core-aux-extern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-core-aux-intern/libnm-core-aux-intern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-base/libnm-base.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-glib-aux/libnm-glib-aux.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-std-aux/libnm-std-aux.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/c-siphash/libc-siphash.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-client-impl/libnm.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ $(am__DEPENDENCIES_1) \ +@BUILD_NM_CLOUD_SETUP_TRUE@ $(am__DEPENDENCIES_1) +src_nm_cloud_setup_tests_test_cloud_setup_general_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_nm_cloud_setup_tests_test_cloud_setup_general_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_src_nm_dispatcher_nm_dispatcher_OBJECTS = \ + src/nm-dispatcher/nm_dispatcher-nm-dispatcher.$(OBJEXT) +src_nm_dispatcher_nm_dispatcher_OBJECTS = \ + $(am_src_nm_dispatcher_nm_dispatcher_OBJECTS) +src_nm_dispatcher_nm_dispatcher_DEPENDENCIES = \ + src/nm-dispatcher/libnm-dispatcher-core.la \ + src/libnm-client-impl/libnm.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la $(am__DEPENDENCIES_1) +src_nm_dispatcher_nm_dispatcher_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(src_nm_dispatcher_nm_dispatcher_LDFLAGS) $(LDFLAGS) -o $@ +am_src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS = src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.$(OBJEXT) +am__objects_14 = src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.$(OBJEXT) +nodist_src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS = \ + $(am__objects_14) +src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS = \ + $(am_src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS) \ + $(nodist_src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS) +src_nm_dispatcher_tests_test_dispatcher_envp_DEPENDENCIES = \ + src/nm-dispatcher/libnm-dispatcher-core.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la src/libnm-client-impl/libnm.la \ + $(am__DEPENDENCIES_1) +src_nm_dispatcher_tests_test_dispatcher_envp_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_nm_dispatcher_tests_test_dispatcher_envp_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_nm_initrd_generator_nm_initrd_generator_SOURCES = \ + src/nm-initrd-generator/nm-initrd-generator.c +src_nm_initrd_generator_nm_initrd_generator_OBJECTS = src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.$(OBJEXT) +src_nm_initrd_generator_nm_initrd_generator_DEPENDENCIES = \ + src/nm-initrd-generator/libnmi-core.la \ + src/libnm-core-impl/libnm-core-impl.la $(libnm_crypto_lib) \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +src_nm_initrd_generator_nm_initrd_generator_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_nm_initrd_generator_nm_initrd_generator_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_nm_initrd_generator_tests_test_cmdline_reader_SOURCES = \ + src/nm-initrd-generator/tests/test-cmdline-reader.c +src_nm_initrd_generator_tests_test_cmdline_reader_OBJECTS = src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.$(OBJEXT) +am__DEPENDENCIES_7 = src/nm-initrd-generator/libnmi-core.la \ + src/libnm-core-impl/libnm-core-impl.la $(libnm_crypto_lib) \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +src_nm_initrd_generator_tests_test_cmdline_reader_DEPENDENCIES = \ + $(am__DEPENDENCIES_7) +src_nm_initrd_generator_tests_test_cmdline_reader_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_nm_initrd_generator_tests_test_cmdline_reader_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_nm_initrd_generator_tests_test_dt_reader_SOURCES = \ + src/nm-initrd-generator/tests/test-dt-reader.c +src_nm_initrd_generator_tests_test_dt_reader_OBJECTS = src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.$(OBJEXT) +src_nm_initrd_generator_tests_test_dt_reader_DEPENDENCIES = \ + $(am__DEPENDENCIES_7) +src_nm_initrd_generator_tests_test_dt_reader_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_nm_initrd_generator_tests_test_dt_reader_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_nm_initrd_generator_tests_test_ibft_reader_SOURCES = \ + src/nm-initrd-generator/tests/test-ibft-reader.c +src_nm_initrd_generator_tests_test_ibft_reader_OBJECTS = src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.$(OBJEXT) +src_nm_initrd_generator_tests_test_ibft_reader_DEPENDENCIES = \ + $(am__DEPENDENCIES_7) +src_nm_initrd_generator_tests_test_ibft_reader_LINK = $(LIBTOOL) \ + $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_nm_initrd_generator_tests_test_ibft_reader_LDFLAGS) \ + $(LDFLAGS) -o $@ +src_nm_online_nm_online_SOURCES = src/nm-online/nm-online.c +src_nm_online_nm_online_OBJECTS = \ + src/nm-online/nm_online-nm-online.$(OBJEXT) +src_nm_online_nm_online_DEPENDENCIES = src/libnm-client-impl/libnm.la \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la $(am__DEPENDENCIES_1) +src_nm_online_nm_online_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(src_nm_online_nm_online_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_src_nmcli_generate_docs_nm_settings_nmcli_OBJECTS = src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.$(OBJEXT) +src_nmcli_generate_docs_nm_settings_nmcli_OBJECTS = \ + $(am_src_nmcli_generate_docs_nm_settings_nmcli_OBJECTS) +src_nmcli_generate_docs_nm_settings_nmcli_DEPENDENCIES = \ + src/libnmc-setting/libnmc-setting.la \ + src/libnmc-base/libnmc-base.la \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la src/libnm-client-impl/libnm.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la $(am__DEPENDENCIES_1) +src_nmcli_generate_docs_nm_settings_nmcli_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(src_nmcli_generate_docs_nm_settings_nmcli_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__src_nmcli_nmcli_SOURCES_DIST = src/nmcli/common.c \ + src/nmcli/common.h src/nmcli/utils.c src/nmcli/utils.h \ + src/nmcli/agent.c src/nmcli/general.c src/nmcli/connections.c \ + src/nmcli/connections.h src/nmcli/devices.c \ + src/nmcli/devices.h src/nmcli/settings.c src/nmcli/settings.h \ + src/nmcli/nmcli.c src/nmcli/nmcli.h src/nmcli/polkit-agent.c \ + src/nmcli/polkit-agent.h +@BUILD_NMCLI_TRUE@am_src_nmcli_nmcli_OBJECTS = \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli-common.$(OBJEXT) \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli-utils.$(OBJEXT) \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli-agent.$(OBJEXT) \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli-general.$(OBJEXT) \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli-connections.$(OBJEXT) \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli-devices.$(OBJEXT) \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli-settings.$(OBJEXT) \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli-nmcli.$(OBJEXT) \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli-polkit-agent.$(OBJEXT) +src_nmcli_nmcli_OBJECTS = $(am_src_nmcli_nmcli_OBJECTS) +@BUILD_NMCLI_TRUE@src_nmcli_nmcli_DEPENDENCIES = \ +@BUILD_NMCLI_TRUE@ src/libnmc-setting/libnmc-setting.la \ +@BUILD_NMCLI_TRUE@ src/libnmc-base/libnmc-base.la \ +@BUILD_NMCLI_TRUE@ src/libnm-core-aux-extern/libnm-core-aux-extern.la \ +@BUILD_NMCLI_TRUE@ src/libnm-core-aux-intern/libnm-core-aux-intern.la \ +@BUILD_NMCLI_TRUE@ src/libnm-base/libnm-base.la \ +@BUILD_NMCLI_TRUE@ src/libnm-glib-aux/libnm-glib-aux.la \ +@BUILD_NMCLI_TRUE@ src/libnm-std-aux/libnm-std-aux.la \ +@BUILD_NMCLI_TRUE@ src/c-siphash/libc-siphash.la \ +@BUILD_NMCLI_TRUE@ src/libnm-client-aux-extern/libnm-client-aux-extern.la \ +@BUILD_NMCLI_TRUE@ src/libnm-client-impl/libnm.la \ +@BUILD_NMCLI_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +src_nmcli_nmcli_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(src_nmcli_nmcli_LDFLAGS) $(LDFLAGS) \ + -o $@ +am__src_nmtui_nmtui_SOURCES_DIST = src/nmtui/nmtui.c src/nmtui/nmtui.h \ + src/nmtui/nmtui-connect.c src/nmtui/nmtui-connect.h \ + src/nmtui/nmtui-edit.c src/nmtui/nmtui-edit.h \ + src/nmtui/nmtui-hostname.c src/nmtui/nmtui-hostname.h \ + src/nmtui/nm-editor-bindings.c src/nmtui/nm-editor-bindings.h \ + src/nmtui/nm-editor-utils.c src/nmtui/nm-editor-utils.h \ + src/nmtui/nmt-address-list.c src/nmtui/nmt-address-list.h \ + src/nmtui/nmt-connect-connection-list.c \ + src/nmtui/nmt-connect-connection-list.h \ + src/nmtui/nmt-device-entry.c src/nmtui/nmt-device-entry.h \ + src/nmtui/nmt-edit-connection-list.c \ + src/nmtui/nmt-edit-connection-list.h \ + src/nmtui/nmt-editor-grid.c src/nmtui/nmt-editor-grid.h \ + src/nmtui/nmt-editor-page.c src/nmtui/nmt-editor-page.h \ + src/nmtui/nmt-editor-page-device.c \ + src/nmtui/nmt-editor-page-device.h \ + src/nmtui/nmt-editor-section.c src/nmtui/nmt-editor-section.h \ + src/nmtui/nmt-editor.c src/nmtui/nmt-editor.h \ + src/nmtui/nmt-ip-entry.c src/nmtui/nmt-ip-entry.h \ + src/nmtui/nmt-mac-entry.c src/nmtui/nmt-mac-entry.h \ + src/nmtui/nmt-mtu-entry.c src/nmtui/nmt-mtu-entry.h \ + src/nmtui/nmt-page-bond.c src/nmtui/nmt-page-bond.h \ + src/nmtui/nmt-page-bridge.c src/nmtui/nmt-page-bridge.h \ + src/nmtui/nmt-page-bridge-port.c \ + src/nmtui/nmt-page-bridge-port.h src/nmtui/nmt-page-dsl.c \ + src/nmtui/nmt-page-dsl.h src/nmtui/nmt-page-ethernet.c \ + src/nmtui/nmt-page-ethernet.h src/nmtui/nmt-page-infiniband.c \ + src/nmtui/nmt-page-infiniband.h src/nmtui/nmt-page-ip-tunnel.c \ + src/nmtui/nmt-page-ip-tunnel.h src/nmtui/nmt-page-ip4.c \ + src/nmtui/nmt-page-ip4.h src/nmtui/nmt-page-ip6.c \ + src/nmtui/nmt-page-ip6.h src/nmtui/nmt-page-ppp.c \ + src/nmtui/nmt-page-ppp.h src/nmtui/nmt-page-team.c \ + src/nmtui/nmt-page-team.h src/nmtui/nmt-page-team-port.c \ + src/nmtui/nmt-page-team-port.h src/nmtui/nmt-page-vlan.c \ + src/nmtui/nmt-page-vlan.h src/nmtui/nmt-page-wifi.c \ + src/nmtui/nmt-page-wifi.h src/nmtui/nmt-password-dialog.c \ + src/nmtui/nmt-password-dialog.h \ + src/nmtui/nmt-password-fields.c \ + src/nmtui/nmt-password-fields.h src/nmtui/nmt-route-editor.c \ + src/nmtui/nmt-route-editor.h src/nmtui/nmt-route-entry.c \ + src/nmtui/nmt-route-entry.h src/nmtui/nmt-route-table.c \ + src/nmtui/nmt-route-table.h src/nmtui/nmt-slave-list.c \ + src/nmtui/nmt-slave-list.h src/nmtui/nmt-utils.c \ + src/nmtui/nmt-utils.h src/nmtui/nmt-widget-list.c \ + src/nmtui/nmt-widget-list.h +@BUILD_NMTUI_TRUE@am_src_nmtui_nmtui_OBJECTS = \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmtui.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmtui-connect.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmtui-edit.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmtui-hostname.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nm-editor-bindings.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nm-editor-utils.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-address-list.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-connect-connection-list.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-device-entry.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-edit-connection-list.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-editor-grid.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-editor-page.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-editor-page-device.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-editor-section.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-editor.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-ip-entry.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-mac-entry.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-mtu-entry.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-bond.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-bridge.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-bridge-port.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-dsl.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-ethernet.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-infiniband.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-ip-tunnel.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-ip4.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-ip6.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-ppp.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-team.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-team-port.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-vlan.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-page-wifi.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-password-dialog.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-password-fields.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-route-editor.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-route-entry.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-route-table.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-slave-list.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-utils.$(OBJEXT) \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-nmt-widget-list.$(OBJEXT) +src_nmtui_nmtui_OBJECTS = $(am_src_nmtui_nmtui_OBJECTS) +@BUILD_NMTUI_TRUE@src_nmtui_nmtui_DEPENDENCIES = \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt-newt.a \ +@BUILD_NMTUI_TRUE@ src/libnmc-setting/libnmc-setting.la \ +@BUILD_NMTUI_TRUE@ src/libnmc-base/libnmc-base.la \ +@BUILD_NMTUI_TRUE@ src/libnm-client-aux-extern/libnm-client-aux-extern.la \ +@BUILD_NMTUI_TRUE@ src/libnm-core-aux-extern/libnm-core-aux-extern.la \ +@BUILD_NMTUI_TRUE@ src/libnm-core-aux-intern/libnm-core-aux-intern.la \ +@BUILD_NMTUI_TRUE@ src/libnm-base/libnm-base.la \ +@BUILD_NMTUI_TRUE@ src/libnm-glib-aux/libnm-glib-aux.la \ +@BUILD_NMTUI_TRUE@ src/libnm-std-aux/libnm-std-aux.la \ +@BUILD_NMTUI_TRUE@ src/c-siphash/libc-siphash.la \ +@BUILD_NMTUI_TRUE@ src/libnm-client-impl/libnm.la \ +@BUILD_NMTUI_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +src_nmtui_nmtui_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(src_nmtui_nmtui_LDFLAGS) $(LDFLAGS) \ + -o $@ +am__dist_libexec_SCRIPTS_DIST = \ + src/core/settings/plugins/ifcfg-rh/nm-ifup \ + src/core/settings/plugins/ifcfg-rh/nm-ifdown +SCRIPTS = $(dist_libexec_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po \ + examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Po \ + examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Po \ + examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Po \ + examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Po \ + examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Po \ + examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Po \ + examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Po \ + examples/C/glib/$(DEPDIR)/vpn_import_libnm-vpn-import-libnm.Po \ + examples/C/qt/$(DEPDIR)/add_connection_wired-add-connection-wired.Po \ + examples/C/qt/$(DEPDIR)/change_ipv4_addresses-change-ipv4-addresses.Po \ + examples/C/qt/$(DEPDIR)/list_connections-list-connections.Po \ + examples/C/qt/$(DEPDIR)/monitor_nm_running-monitor-nm-running.Po \ + introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.AccessPoint.Plo \ + introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.AgentManager.Plo \ + introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.Checkpoint.Plo \ introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.Connection.Active.Plo \ introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.DHCP4Config.Plo \ introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.DHCP6Config.Plo \ @@ -2772,229 +2709,10 @@ am__depfiles_remade = clients/$(DEPDIR)/nm_online-nm-online.Po \ introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.VPN.Connection.Plo \ introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.VPN.Plugin.Plo \ introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.WifiP2PPeer.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-connection.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-core-enum-types.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-crypto.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-dbus-utils.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-errors.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile-utils.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-meta-setting-base-impl.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-property-compare.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-6lowpan.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-8021x.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-adsl.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bluetooth.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bond.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge-port.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-cdma.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-connection.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dcb.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dummy.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ethtool.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-generic.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-gsm.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-hostname.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-infiniband.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-config.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-tunnel.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip4-config.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip6-config.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macsec.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macvlan.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-match.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-olpc-mesh.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-bridge.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-dpdk.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-external-ids.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-interface.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-patch.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-port.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ppp.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-pppoe.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-proxy.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-serial.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-sriov.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tc-config.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team-port.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tun.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-user.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-veth.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vlan.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vpn.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vrf.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vxlan.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wifi-p2p.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wimax.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wired.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireguard.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless-security.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wpan.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-setting.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-simple-connection.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-team-utils.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-utils.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-editor-plugin.Plo \ - libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-plugin-info.Plo \ - libnm-core/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Plo \ - libnm-core/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Plo \ - libnm-core/nm-libnm-core-aux/$(DEPDIR)/libnm_libnm_core_aux_la-nm-libnm-core-aux.Plo \ - libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-auth-subject.Plo \ - libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-libnm-core-utils.Plo \ - libnm-core/tests/$(DEPDIR)/test_compare-test-compare.Po \ - libnm-core/tests/$(DEPDIR)/test_crypto-test-crypto.Po \ - libnm-core/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po \ - libnm-core/tests/$(DEPDIR)/test_general-test-general.Po \ - libnm-core/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po \ - libnm-core/tests/$(DEPDIR)/test_secrets-test-secrets.Po \ - libnm-core/tests/$(DEPDIR)/test_setting-test-setting.Po \ - libnm-core/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po \ - libnm/$(DEPDIR)/libnm_static_la-nm-access-point.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-active-connection.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-checkpoint.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-client.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-dbus-helpers.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-6lowpan.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-adsl.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-bond.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-bridge.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-bt.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-dummy.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-ethernet.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-generic.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-infiniband.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-ip-tunnel.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-macsec.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-macvlan.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-modem.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-olpc-mesh.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-bridge.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-interface.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-port.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-ppp.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-team.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-tun.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-veth.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-vlan.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-vrf.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-vxlan.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi-p2p.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-wimax.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-wireguard.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device-wpan.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-device.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-dhcp-config.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-dhcp4-config.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-dhcp6-config.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-dns-manager.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-enum-types.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-ip-config.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-ip4-config.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-ip6-config.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-libnm-utils.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-object.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-remote-connection.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-secret-agent-old.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-vpn-connection.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-vpn-editor.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-vpn-plugin-old.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-vpn-service-plugin.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-wifi-p2p-peer.Plo \ - libnm/$(DEPDIR)/libnm_static_la-nm-wimax-nsp.Plo \ - libnm/nm-libnm-aux/$(DEPDIR)/libnm_libnm_aux_la-nm-libnm-aux.Plo \ - libnm/tests/$(DEPDIR)/test_libnm-test-libnm.Po \ - libnm/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po \ - libnm/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po \ - libnm/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po \ - shared/$(DEPDIR)/libnm_tests_test_nm_client-nm-test-utils-impl.Po \ - shared/$(DEPDIR)/libnm_tests_test_remote_settings_client-nm-test-utils-impl.Po \ - shared/$(DEPDIR)/libnm_tests_test_secret_agent-nm-test-utils-impl.Po \ - shared/c-rbtree/src/$(DEPDIR)/libcrbtree_la-c-rbtree.Plo \ - shared/c-siphash/src/$(DEPDIR)/libcsiphash_la-c-siphash.Plo \ - shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf-fallback.Plo \ - shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf.Plo \ - shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-probe.Plo \ - shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd.Plo \ - shared/n-acd/src/util/$(DEPDIR)/libnacd_la-timer.Plo \ - shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-connection.Plo \ - shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-lease.Plo \ - shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-probe.Plo \ - shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-client.Plo \ - shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-incoming.Plo \ - shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-outgoing.Plo \ - shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-socket.Plo \ - shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-packet.Plo \ - shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-socket.Plo \ - shared/nm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Plo \ - shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Plo \ - shared/nm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po \ - shared/nm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po \ - shared/nm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Plo \ - shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Plo \ - shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Plo \ - shared/nm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Plo \ - shared/nm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po \ - shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Plo \ - shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Plo \ - shared/nm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Plo \ - shared/nm-utils/$(DEPDIR)/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Plo \ - shared/nm-utils/$(DEPDIR)/libnm_tests_test_libnm-nm-compat.Po \ - shared/systemd/$(DEPDIR)/libnm_systemd_logging_stub_la-nm-logging-stub.Plo \ - shared/systemd/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Plo \ - shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Plo \ - shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Plo \ - shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Plo \ + src/c-rbtree/src/$(DEPDIR)/libc_rbtree_la-c-rbtree.Plo \ + src/c-siphash/src/$(DEPDIR)/libc_siphash_la-c-siphash.Plo \ + src/contrib/$(DEPDIR)/libnm_client_impl_tests_test_libnm-nm-compat.Po \ + src/contrib/$(DEPDIR)/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Plo \ src/core/$(DEPDIR)/NetworkManager-main.Po \ src/core/$(DEPDIR)/NetworkManager_all_sym-main.Po \ src/core/$(DEPDIR)/libNetworkManagerBase_la-NetworkManagerUtils.Plo \ @@ -3115,22 +2833,11 @@ am__depfiles_remade = clients/$(DEPDIR)/nm_online-nm-online.Po \ src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-manager.Plo \ src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-utils.Plo \ src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Po \ - src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Plo \ - src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Plo \ - src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Plo \ - src/core/initrd/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po \ - src/core/initrd/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po \ - src/core/initrd/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po \ - src/core/initrd/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po \ src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-lndp-ndisc.Plo \ src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-ndisc.Plo \ src/core/ndisc/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-ndisc.Plo \ src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Po \ src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Po \ - src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-linux-platform.Plo \ - src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-platform.Plo \ - src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-object.Plo \ - src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-rules-manager.Plo \ src/core/platform/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-platform.Plo \ src/core/platform/tests/$(DEPDIR)/libNetworkManagerTest_la-test-common.Plo \ src/core/platform/tests/$(DEPDIR)/monitor-monitor.Po \ @@ -3146,10 +2853,6 @@ am__depfiles_remade = clients/$(DEPDIR)/nm_online-nm-online.Po \ src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Po \ src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Po \ src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Po \ - src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-nl80211.Plo \ - src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-wext.Plo \ - src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils.Plo \ - src/core/platform/wpan/$(DEPDIR)/libNetworkManagerBase_la-nm-wpan-utils.Plo \ src/core/ppp/$(DEPDIR)/libNetworkManager_la-nm-ppp-manager-call.Plo \ src/core/ppp/$(DEPDIR)/libnm_ppp_plugin_la-nm-ppp-manager.Plo \ src/core/ppp/$(DEPDIR)/nm_pppd_plugin_la-nm-pppd-plugin.Plo \ @@ -3220,7 +2923,332 @@ am__depfiles_remade = clients/$(DEPDIR)/nm_online-nm-online.Po \ src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Po \ src/core/tests/config/$(DEPDIR)/test_config-test-config.Po \ src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-connection.Plo \ - src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Plo + src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Plo \ + src/libnm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Plo \ + src/libnm-base/$(DEPDIR)/libnm_base_la-nm-net-aux.Plo \ + src/libnm-client-aux-extern/$(DEPDIR)/libnm_client_aux_extern_la-nm-libnm-aux.Plo \ + src/libnm-client-aux-extern/tests/$(DEPDIR)/test_libnm_client_aux-test-libnm-client-aux.Po \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-access-point.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-active-connection.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-checkpoint.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-client.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dbus-helpers.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-6lowpan.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-adsl.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bond.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bridge.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bt.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-dummy.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ethernet.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-generic.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-infiniband.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ip-tunnel.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macsec.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macvlan.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-modem.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-olpc-mesh.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-bridge.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-interface.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-port.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ppp.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-team.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-tun.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-veth.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vlan.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vrf.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vxlan.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi-p2p.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wimax.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wireguard.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wpan.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp-config.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp4-config.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp6-config.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dns-manager.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip-config.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip4-config.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip6-config.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-libnm-utils.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-object.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-remote-connection.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-secret-agent-old.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-connection.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-editor.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-plugin-old.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-service-plugin.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wifi-p2p-peer.Plo \ + src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wimax-nsp.Plo \ + src/libnm-client-impl/tests/$(DEPDIR)/test_libnm-test-libnm.Po \ + src/libnm-client-impl/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po \ + src/libnm-client-impl/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po \ + src/libnm-client-impl/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po \ + src/libnm-client-public/$(DEPDIR)/libnm_client_impl_libnm_client_impl_la-nm-enum-types.Plo \ + src/libnm-client-test/$(DEPDIR)/libnm_client_test_la-nm-test-utils-impl.Plo \ + src/libnm-core-aux-extern/$(DEPDIR)/libnm_core_aux_extern_la-nm-libnm-core-aux.Plo \ + src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-auth-subject.Plo \ + src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-libnm-core-utils.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-connection.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-crypto.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-dbus-utils.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-errors.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile-utils.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-meta-setting-base-impl.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-property-compare.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-6lowpan.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-8021x.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-adsl.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bluetooth.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bond.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge-port.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-cdma.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-connection.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dcb.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dummy.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ethtool.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-generic.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-gsm.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-hostname.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-infiniband.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-config.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-tunnel.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip4-config.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip6-config.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macsec.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macvlan.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-match.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-olpc-mesh.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-bridge.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-dpdk.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-external-ids.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-interface.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-patch.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-port.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ppp.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-pppoe.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-proxy.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-serial.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-sriov.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tc-config.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team-port.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tun.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-user.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-veth.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vlan.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vpn.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vrf.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vxlan.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wifi-p2p.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wimax.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wired.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireguard.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless-security.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wpan.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-simple-connection.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-team-utils.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-utils.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-editor-plugin.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-plugin-info.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Plo \ + src/libnm-core-impl/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Plo \ + src/libnm-core-impl/tests/$(DEPDIR)/test_compare-test-compare.Po \ + src/libnm-core-impl/tests/$(DEPDIR)/test_crypto-test-crypto.Po \ + src/libnm-core-impl/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po \ + src/libnm-core-impl/tests/$(DEPDIR)/test_general-test-general.Po \ + src/libnm-core-impl/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po \ + src/libnm-core-impl/tests/$(DEPDIR)/test_secrets-test-secrets.Po \ + src/libnm-core-impl/tests/$(DEPDIR)/test_setting-test-setting.Po \ + src/libnm-core-impl/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po \ + src/libnm-core-public/$(DEPDIR)/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Plo \ + src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Plo \ + src/libnm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po \ + src/libnm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po \ + src/libnm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Plo \ + src/libnm-log-null/$(DEPDIR)/libnm_log_null_la-nm-logging-null.Plo \ + src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-linux-platform.Plo \ + src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Plo \ + src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Plo \ + src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform.Plo \ + src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Plo \ + src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-object.Plo \ + src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-rules-manager.Plo \ + src/libnm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po \ + src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-nl80211.Plo \ + src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-wext.Plo \ + src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils.Plo \ + src/libnm-platform/wpan/$(DEPDIR)/libnm_platform_la-nm-wpan-utils.Plo \ + src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Plo \ + src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Plo \ + src/libnm-systemd-shared/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Plo \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Plo \ + src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Plo \ + src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Plo \ + src/libnm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Plo \ + src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-client-utils.Plo \ + src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Plo \ + src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Plo \ + src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Plo \ + src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-access.Plo \ + src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-base-impl.Plo \ + src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-desc.Plo \ + src/libnmc-setting/tests/$(DEPDIR)/test_libnmc_setting-test-libnmc-setting.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po \ + src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po \ + src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf-fallback.Plo \ + src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf.Plo \ + src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-probe.Plo \ + src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd.Plo \ + src/n-acd/src/util/$(DEPDIR)/libn_acd_la-timer.Plo \ + src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-connection.Plo \ + src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-lease.Plo \ + src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-probe.Plo \ + src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-client.Plo \ + src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-incoming.Plo \ + src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-outgoing.Plo \ + src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-socket.Plo \ + src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-packet.Plo \ + src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-socket.Plo \ + src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po \ + src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po \ + src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po \ + src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po \ + src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po \ + src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po \ + src/nm-cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po \ + src/nm-cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po \ + src/nm-dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Plo \ + src/nm-dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po \ + src/nm-dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po \ + src/nm-dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po \ + src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Plo \ + src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Plo \ + src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Plo \ + src/nm-initrd-generator/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po \ + src/nm-initrd-generator/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po \ + src/nm-initrd-generator/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po \ + src/nm-initrd-generator/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po \ + src/nm-online/$(DEPDIR)/nm_online-nm-online.Po \ + src/nmcli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po \ + src/nmcli/$(DEPDIR)/nmcli-agent.Po \ + src/nmcli/$(DEPDIR)/nmcli-common.Po \ + src/nmcli/$(DEPDIR)/nmcli-connections.Po \ + src/nmcli/$(DEPDIR)/nmcli-devices.Po \ + src/nmcli/$(DEPDIR)/nmcli-general.Po \ + src/nmcli/$(DEPDIR)/nmcli-nmcli.Po \ + src/nmcli/$(DEPDIR)/nmcli-polkit-agent.Po \ + src/nmcli/$(DEPDIR)/nmcli-settings.Po \ + src/nmcli/$(DEPDIR)/nmcli-utils.Po \ + src/nmtui/$(DEPDIR)/nmtui-nm-editor-bindings.Po \ + src/nmtui/$(DEPDIR)/nmtui-nm-editor-utils.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-address-list.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-device-entry.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-editor-grid.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-editor-section.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-editor.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-ip-entry.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-mac-entry.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-bond.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-dsl.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip4.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip6.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-ppp.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-team-port.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-team.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-vlan.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-page-wifi.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-password-dialog.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-password-fields.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-route-editor.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-route-entry.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-route-table.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-slave-list.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-utils.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmt-widget-list.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmtui-connect.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmtui-edit.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmtui-hostname.Po \ + src/nmtui/$(DEPDIR)/nmtui-nmtui.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -3258,33 +3286,12 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = -SOURCES = $(clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES) \ - $(clients_tui_newt_libnmt_newt_a_SOURCES) \ - $(clients_common_libnmc_base_la_SOURCES) \ - $(clients_common_libnmc_la_SOURCES) \ - $(dispatcher_libnm_dispatcher_core_la_SOURCES) \ +SOURCES = $(src_libnmt_newt_libnmt_newt_a_SOURCES) \ + $(src_nm_cloud_setup_libnm_cloud_setup_core_a_SOURCES) \ $(nodist_introspection_libnmdbus_la_SOURCES) \ - $(libnm_core_libnm_core_la_SOURCES) \ - $(nodist_libnm_core_libnm_core_la_SOURCES) \ - $(libnm_core_libnm_crypto_gnutls_la_SOURCES) \ - $(libnm_core_libnm_crypto_nss_la_SOURCES) \ - $(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_SOURCES) \ - $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_SOURCES) \ - $(libnm_libnm_la_SOURCES) $(libnm_libnm_static_la_SOURCES) \ - $(nodist_libnm_libnm_static_la_SOURCES) \ - $(libnm_nm_libnm_aux_libnm_libnm_aux_la_SOURCES) \ - $(libnm_tests_libnm_vpn_plugin_utils_test_la_SOURCES) \ - $(shared_libcrbtree_la_SOURCES) \ - $(shared_libcsiphash_la_SOURCES) $(shared_libnacd_la_SOURCES) \ - $(shared_libndhcp4_la_SOURCES) \ - $(shared_nm_base_libnm_base_la_SOURCES) \ - $(shared_nm_glib_aux_libnm_glib_aux_la_SOURCES) \ - $(shared_nm_log_core_libnm_log_core_la_SOURCES) \ - $(shared_nm_platform_libnm_platform_la_SOURCES) \ - $(shared_nm_std_aux_libnm_std_aux_la_SOURCES) \ - $(shared_nm_udev_aux_libnm_udev_aux_la_SOURCES) \ - $(shared_systemd_libnm_systemd_logging_stub_la_SOURCES) \ - $(shared_systemd_libnm_systemd_shared_la_SOURCES) \ + $(src_c_rbtree_libc_rbtree_la_SOURCES) \ + $(src_c_siphash_libc_siphash_la_SOURCES) \ + $(src_contrib_tests_libnm_vpn_plugin_utils_test_la_SOURCES) \ $(src_core_devices_adsl_libnm_device_plugin_adsl_la_SOURCES) \ $(src_core_devices_bluetooth_libnm_bluetooth_utils_la_SOURCES) \ $(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_SOURCES) \ @@ -3294,7 +3301,6 @@ SOURCES = $(clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES) \ $(src_core_devices_wifi_libnm_wifi_base_la_SOURCES) \ $(src_core_devices_wwan_libnm_device_plugin_wwan_la_SOURCES) \ $(src_core_devices_wwan_libnm_wwan_la_SOURCES) \ - $(src_core_initrd_libnmi_core_la_SOURCES) \ $(src_core_libNetworkManager_la_SOURCES) \ $(src_core_libNetworkManagerBase_la_SOURCES) \ $(src_core_libNetworkManagerTest_la_SOURCES) \ @@ -3306,16 +3312,31 @@ SOURCES = $(clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES) \ $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_SOURCES) \ $(src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_SOURCES) \ $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_SOURCES) \ - $(clients_cli_generate_docs_nm_settings_nmcli_SOURCES) \ - $(clients_cli_nmcli_SOURCES) \ - $(clients_cloud_setup_nm_cloud_setup_SOURCES) \ - clients/cloud-setup/tests/test-cloud-setup-general.c \ - clients/common/tests/test-clients-common.c \ - clients/common/tests/test-libnm-core-aux.c clients/nm-online.c \ - $(clients_tui_nmtui_SOURCES) \ - $(dispatcher_nm_dispatcher_SOURCES) \ - $(dispatcher_tests_test_dispatcher_envp_SOURCES) \ - $(nodist_dispatcher_tests_test_dispatcher_envp_SOURCES) \ + $(src_libnm_base_libnm_base_la_SOURCES) \ + $(src_libnm_client_aux_extern_libnm_client_aux_extern_la_SOURCES) \ + $(src_libnm_client_impl_libnm_client_impl_la_SOURCES) \ + $(nodist_src_libnm_client_impl_libnm_client_impl_la_SOURCES) \ + $(src_libnm_client_impl_libnm_la_SOURCES) \ + $(src_libnm_client_test_libnm_client_test_la_SOURCES) \ + $(src_libnm_core_aux_extern_libnm_core_aux_extern_la_SOURCES) \ + $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_SOURCES) \ + $(src_libnm_core_impl_libnm_core_impl_la_SOURCES) \ + $(nodist_src_libnm_core_impl_libnm_core_impl_la_SOURCES) \ + $(src_libnm_core_impl_libnm_crypto_gnutls_la_SOURCES) \ + $(src_libnm_core_impl_libnm_crypto_nss_la_SOURCES) \ + $(src_libnm_glib_aux_libnm_glib_aux_la_SOURCES) \ + $(src_libnm_log_core_libnm_log_core_la_SOURCES) \ + $(src_libnm_log_null_libnm_log_null_la_SOURCES) \ + $(src_libnm_platform_libnm_platform_la_SOURCES) \ + $(src_libnm_std_aux_libnm_std_aux_la_SOURCES) \ + $(src_libnm_systemd_shared_libnm_systemd_shared_la_SOURCES) \ + $(src_libnm_udev_aux_libnm_udev_aux_la_SOURCES) \ + $(src_libnmc_base_libnmc_base_la_SOURCES) \ + $(src_libnmc_setting_libnmc_setting_la_SOURCES) \ + $(src_n_acd_libn_acd_la_SOURCES) \ + $(src_n_dhcp4_libn_dhcp4_la_SOURCES) \ + $(src_nm_dispatcher_libnm_dispatcher_core_la_SOURCES) \ + $(src_nm_initrd_generator_libnmi_core_la_SOURCES) \ examples/C/glib/add-connection-gdbus.c \ examples/C/glib/add-connection-libnm.c \ examples/C/glib/get-active-connections-gdbus.c \ @@ -3324,24 +3345,11 @@ SOURCES = $(clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES) \ examples/C/glib/list-connections-libnm.c \ examples/C/glib/monitor-nm-running-gdbus.c \ examples/C/glib/monitor-nm-state-gdbus.c \ + examples/C/glib/vpn-import-libnm.c \ $(examples_C_qt_add_connection_wired_SOURCES) \ $(examples_C_qt_change_ipv4_addresses_SOURCES) \ $(examples_C_qt_list_connections_SOURCES) \ $(examples_C_qt_monitor_nm_running_SOURCES) \ - libnm-core/tests/test-compare.c libnm-core/tests/test-crypto.c \ - $(libnm_core_tests_test_general_SOURCES) \ - $(nodist_libnm_core_tests_test_general_SOURCES) \ - libnm-core/tests/test-keyfile.c \ - libnm-core/tests/test-secrets.c \ - libnm-core/tests/test-setting.c \ - libnm-core/tests/test-settings-defaults.c \ - $(libnm_tests_test_libnm_SOURCES) \ - $(libnm_tests_test_nm_client_SOURCES) \ - $(libnm_tests_test_remote_settings_client_SOURCES) \ - $(libnm_tests_test_secret_agent_SOURCES) \ - shared/nm-glib-aux/tests/test-json-aux.c \ - shared/nm-glib-aux/tests/test-shared-general.c \ - shared/nm-platform/tests/test-nm-platform.c \ $(src_core_NetworkManager_SOURCES) \ $(src_core_NetworkManager_all_sym_SOURCES) \ src/core/devices/bluetooth/tests/nm-bt-test.c \ @@ -3353,10 +3361,6 @@ SOURCES = $(clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES) \ src/core/dhcp/tests/test-dhcp-dhclient.c \ src/core/dhcp/tests/test-dhcp-utils.c \ src/core/dnsmasq/tests/test-dnsmasq-utils.c \ - $(src_core_initrd_nm_initrd_generator_SOURCES) \ - src/core/initrd/tests/test-cmdline-reader.c \ - src/core/initrd/tests/test-dt-reader.c \ - src/core/initrd/tests/test-ibft-reader.c \ src/core/ndisc/tests/test-ndisc-fake.c \ src/core/ndisc/tests/test-ndisc-linux.c \ $(src_core_nm_iface_helper_SOURCES) \ @@ -3383,32 +3387,41 @@ SOURCES = $(clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES) \ src/core/tests/test-dcb.c src/core/tests/test-ip4-config.c \ src/core/tests/test-ip6-config.c src/core/tests/test-l3cfg.c \ src/core/tests/test-systemd.c src/core/tests/test-utils.c \ - src/core/tests/test-wired-defname.c -DIST_SOURCES = $(am__clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES_DIST) \ - $(am__clients_tui_newt_libnmt_newt_a_SOURCES_DIST) \ - $(clients_common_libnmc_base_la_SOURCES) \ - $(clients_common_libnmc_la_SOURCES) \ - $(dispatcher_libnm_dispatcher_core_la_SOURCES) \ - $(libnm_core_libnm_core_la_SOURCES) \ - $(am__libnm_core_libnm_crypto_gnutls_la_SOURCES_DIST) \ - $(am__libnm_core_libnm_crypto_nss_la_SOURCES_DIST) \ - $(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_SOURCES) \ - $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_SOURCES) \ - $(libnm_libnm_la_SOURCES) $(libnm_libnm_static_la_SOURCES) \ - $(libnm_nm_libnm_aux_libnm_libnm_aux_la_SOURCES) \ - $(libnm_tests_libnm_vpn_plugin_utils_test_la_SOURCES) \ - $(shared_libcrbtree_la_SOURCES) \ - $(shared_libcsiphash_la_SOURCES) \ - $(am__shared_libnacd_la_SOURCES_DIST) \ - $(shared_libndhcp4_la_SOURCES) \ - $(shared_nm_base_libnm_base_la_SOURCES) \ - $(shared_nm_glib_aux_libnm_glib_aux_la_SOURCES) \ - $(shared_nm_log_core_libnm_log_core_la_SOURCES) \ - $(shared_nm_platform_libnm_platform_la_SOURCES) \ - $(shared_nm_std_aux_libnm_std_aux_la_SOURCES) \ - $(shared_nm_udev_aux_libnm_udev_aux_la_SOURCES) \ - $(shared_systemd_libnm_systemd_logging_stub_la_SOURCES) \ - $(shared_systemd_libnm_systemd_shared_la_SOURCES) \ + src/core/tests/test-wired-defname.c \ + src/libnm-client-aux-extern/tests/test-libnm-client-aux.c \ + $(src_libnm_client_impl_tests_test_libnm_SOURCES) \ + src/libnm-client-impl/tests/test-nm-client.c \ + src/libnm-client-impl/tests/test-remote-settings-client.c \ + src/libnm-client-impl/tests/test-secret-agent.c \ + src/libnm-core-impl/tests/test-compare.c \ + src/libnm-core-impl/tests/test-crypto.c \ + $(src_libnm_core_impl_tests_test_general_SOURCES) \ + $(nodist_src_libnm_core_impl_tests_test_general_SOURCES) \ + src/libnm-core-impl/tests/test-keyfile.c \ + src/libnm-core-impl/tests/test-secrets.c \ + src/libnm-core-impl/tests/test-setting.c \ + src/libnm-core-impl/tests/test-settings-defaults.c \ + src/libnm-glib-aux/tests/test-json-aux.c \ + src/libnm-glib-aux/tests/test-shared-general.c \ + src/libnm-platform/tests/test-nm-platform.c \ + src/libnmc-setting/tests/test-libnmc-setting.c \ + $(src_nm_cloud_setup_nm_cloud_setup_SOURCES) \ + src/nm-cloud-setup/tests/test-cloud-setup-general.c \ + $(src_nm_dispatcher_nm_dispatcher_SOURCES) \ + $(src_nm_dispatcher_tests_test_dispatcher_envp_SOURCES) \ + $(nodist_src_nm_dispatcher_tests_test_dispatcher_envp_SOURCES) \ + src/nm-initrd-generator/nm-initrd-generator.c \ + src/nm-initrd-generator/tests/test-cmdline-reader.c \ + src/nm-initrd-generator/tests/test-dt-reader.c \ + src/nm-initrd-generator/tests/test-ibft-reader.c \ + src/nm-online/nm-online.c \ + $(src_nmcli_generate_docs_nm_settings_nmcli_SOURCES) \ + $(src_nmcli_nmcli_SOURCES) $(src_nmtui_nmtui_SOURCES) +DIST_SOURCES = $(am__src_libnmt_newt_libnmt_newt_a_SOURCES_DIST) \ + $(am__src_nm_cloud_setup_libnm_cloud_setup_core_a_SOURCES_DIST) \ + $(src_c_rbtree_libc_rbtree_la_SOURCES) \ + $(src_c_siphash_libc_siphash_la_SOURCES) \ + $(src_contrib_tests_libnm_vpn_plugin_utils_test_la_SOURCES) \ $(src_core_devices_adsl_libnm_device_plugin_adsl_la_SOURCES) \ $(am__src_core_devices_bluetooth_libnm_bluetooth_utils_la_SOURCES_DIST) \ $(am__src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_SOURCES_DIST) \ @@ -3418,9 +3431,8 @@ DIST_SOURCES = $(am__clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES_DIST) $(am__src_core_devices_wifi_libnm_wifi_base_la_SOURCES_DIST) \ $(am__src_core_devices_wwan_libnm_device_plugin_wwan_la_SOURCES_DIST) \ $(am__src_core_devices_wwan_libnm_wwan_la_SOURCES_DIST) \ - $(src_core_initrd_libnmi_core_la_SOURCES) \ $(src_core_libNetworkManager_la_SOURCES) \ - $(am__src_core_libNetworkManagerBase_la_SOURCES_DIST) \ + $(src_core_libNetworkManagerBase_la_SOURCES) \ $(src_core_libNetworkManagerTest_la_SOURCES) \ $(src_core_libnm_systemd_core_la_SOURCES) \ $(am__src_core_ppp_libnm_ppp_plugin_la_SOURCES_DIST) \ @@ -3429,15 +3441,29 @@ DIST_SOURCES = $(am__clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES_DIST) $(am__src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_SOURCES_DIST) \ $(am__src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_SOURCES_DIST) \ $(am__src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_SOURCES_DIST) \ - $(clients_cli_generate_docs_nm_settings_nmcli_SOURCES) \ - $(am__clients_cli_nmcli_SOURCES_DIST) \ - $(am__clients_cloud_setup_nm_cloud_setup_SOURCES_DIST) \ - clients/cloud-setup/tests/test-cloud-setup-general.c \ - clients/common/tests/test-clients-common.c \ - clients/common/tests/test-libnm-core-aux.c clients/nm-online.c \ - $(am__clients_tui_nmtui_SOURCES_DIST) \ - $(dispatcher_nm_dispatcher_SOURCES) \ - $(dispatcher_tests_test_dispatcher_envp_SOURCES) \ + $(src_libnm_base_libnm_base_la_SOURCES) \ + $(src_libnm_client_aux_extern_libnm_client_aux_extern_la_SOURCES) \ + $(src_libnm_client_impl_libnm_client_impl_la_SOURCES) \ + $(src_libnm_client_impl_libnm_la_SOURCES) \ + $(src_libnm_client_test_libnm_client_test_la_SOURCES) \ + $(src_libnm_core_aux_extern_libnm_core_aux_extern_la_SOURCES) \ + $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_SOURCES) \ + $(src_libnm_core_impl_libnm_core_impl_la_SOURCES) \ + $(am__src_libnm_core_impl_libnm_crypto_gnutls_la_SOURCES_DIST) \ + $(am__src_libnm_core_impl_libnm_crypto_nss_la_SOURCES_DIST) \ + $(src_libnm_glib_aux_libnm_glib_aux_la_SOURCES) \ + $(src_libnm_log_core_libnm_log_core_la_SOURCES) \ + $(src_libnm_log_null_libnm_log_null_la_SOURCES) \ + $(am__src_libnm_platform_libnm_platform_la_SOURCES_DIST) \ + $(src_libnm_std_aux_libnm_std_aux_la_SOURCES) \ + $(src_libnm_systemd_shared_libnm_systemd_shared_la_SOURCES) \ + $(src_libnm_udev_aux_libnm_udev_aux_la_SOURCES) \ + $(src_libnmc_base_libnmc_base_la_SOURCES) \ + $(src_libnmc_setting_libnmc_setting_la_SOURCES) \ + $(am__src_n_acd_libn_acd_la_SOURCES_DIST) \ + $(src_n_dhcp4_libn_dhcp4_la_SOURCES) \ + $(src_nm_dispatcher_libnm_dispatcher_core_la_SOURCES) \ + $(src_nm_initrd_generator_libnmi_core_la_SOURCES) \ examples/C/glib/add-connection-gdbus.c \ examples/C/glib/add-connection-libnm.c \ examples/C/glib/get-active-connections-gdbus.c \ @@ -3446,23 +3472,11 @@ DIST_SOURCES = $(am__clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES_DIST) examples/C/glib/list-connections-libnm.c \ examples/C/glib/monitor-nm-running-gdbus.c \ examples/C/glib/monitor-nm-state-gdbus.c \ + examples/C/glib/vpn-import-libnm.c \ $(am__examples_C_qt_add_connection_wired_SOURCES_DIST) \ $(am__examples_C_qt_change_ipv4_addresses_SOURCES_DIST) \ $(am__examples_C_qt_list_connections_SOURCES_DIST) \ $(am__examples_C_qt_monitor_nm_running_SOURCES_DIST) \ - libnm-core/tests/test-compare.c libnm-core/tests/test-crypto.c \ - $(libnm_core_tests_test_general_SOURCES) \ - libnm-core/tests/test-keyfile.c \ - libnm-core/tests/test-secrets.c \ - libnm-core/tests/test-setting.c \ - libnm-core/tests/test-settings-defaults.c \ - $(libnm_tests_test_libnm_SOURCES) \ - $(libnm_tests_test_nm_client_SOURCES) \ - $(libnm_tests_test_remote_settings_client_SOURCES) \ - $(libnm_tests_test_secret_agent_SOURCES) \ - shared/nm-glib-aux/tests/test-json-aux.c \ - shared/nm-glib-aux/tests/test-shared-general.c \ - shared/nm-platform/tests/test-nm-platform.c \ $(src_core_NetworkManager_SOURCES) \ $(src_core_NetworkManager_all_sym_SOURCES) \ src/core/devices/bluetooth/tests/nm-bt-test.c \ @@ -3474,10 +3488,6 @@ DIST_SOURCES = $(am__clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES_DIST) src/core/dhcp/tests/test-dhcp-dhclient.c \ src/core/dhcp/tests/test-dhcp-utils.c \ src/core/dnsmasq/tests/test-dnsmasq-utils.c \ - $(src_core_initrd_nm_initrd_generator_SOURCES) \ - src/core/initrd/tests/test-cmdline-reader.c \ - src/core/initrd/tests/test-dt-reader.c \ - src/core/initrd/tests/test-ibft-reader.c \ src/core/ndisc/tests/test-ndisc-fake.c \ src/core/ndisc/tests/test-ndisc-linux.c \ $(src_core_nm_iface_helper_SOURCES) \ @@ -3504,7 +3514,35 @@ DIST_SOURCES = $(am__clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES_DIST) src/core/tests/test-dcb.c src/core/tests/test-ip4-config.c \ src/core/tests/test-ip6-config.c src/core/tests/test-l3cfg.c \ src/core/tests/test-systemd.c src/core/tests/test-utils.c \ - src/core/tests/test-wired-defname.c + src/core/tests/test-wired-defname.c \ + src/libnm-client-aux-extern/tests/test-libnm-client-aux.c \ + $(src_libnm_client_impl_tests_test_libnm_SOURCES) \ + src/libnm-client-impl/tests/test-nm-client.c \ + src/libnm-client-impl/tests/test-remote-settings-client.c \ + src/libnm-client-impl/tests/test-secret-agent.c \ + src/libnm-core-impl/tests/test-compare.c \ + src/libnm-core-impl/tests/test-crypto.c \ + $(src_libnm_core_impl_tests_test_general_SOURCES) \ + src/libnm-core-impl/tests/test-keyfile.c \ + src/libnm-core-impl/tests/test-secrets.c \ + src/libnm-core-impl/tests/test-setting.c \ + src/libnm-core-impl/tests/test-settings-defaults.c \ + src/libnm-glib-aux/tests/test-json-aux.c \ + src/libnm-glib-aux/tests/test-shared-general.c \ + src/libnm-platform/tests/test-nm-platform.c \ + src/libnmc-setting/tests/test-libnmc-setting.c \ + $(am__src_nm_cloud_setup_nm_cloud_setup_SOURCES_DIST) \ + src/nm-cloud-setup/tests/test-cloud-setup-general.c \ + $(src_nm_dispatcher_nm_dispatcher_SOURCES) \ + $(src_nm_dispatcher_tests_test_dispatcher_envp_SOURCES) \ + src/nm-initrd-generator/nm-initrd-generator.c \ + src/nm-initrd-generator/tests/test-cmdline-reader.c \ + src/nm-initrd-generator/tests/test-dt-reader.c \ + src/nm-initrd-generator/tests/test-ibft-reader.c \ + src/nm-online/nm-online.c \ + $(src_nmcli_generate_docs_nm_settings_nmcli_SOURCES) \ + $(am__src_nmcli_nmcli_SOURCES_DIST) \ + $(am__src_nmtui_nmtui_SOURCES_DIST) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ @@ -3751,12 +3789,12 @@ am__DIST_COMMON = $(srcdir)/Makefile.examples $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/tap-driver.sh \ $(top_srcdir)/build-aux/test-driver \ $(top_srcdir)/data/org.freedesktop.NetworkManager.policy.in.in \ - $(top_srcdir)/libnm-core/nm-version-macros.h.in \ - $(top_srcdir)/libnm/libnm.pc.in ABOUT-NLS AUTHORS COPYING \ - ChangeLog INSTALL NEWS README TODO build-aux/compile \ - build-aux/config.guess build-aux/config.rpath \ - build-aux/config.sub build-aux/depcomp build-aux/install-sh \ - build-aux/ltmain.sh build-aux/missing + $(top_srcdir)/src/libnm-client-impl/libnm.pc.in \ + $(top_srcdir)/src/libnm-core-public/nm-version-macros.h.in \ + ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL NEWS README TODO \ + build-aux/compile build-aux/config.guess \ + build-aux/config.rpath build-aux/config.sub build-aux/depcomp \ + build-aux/install-sh build-aux/ltmain.sh build-aux/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -4127,33 +4165,37 @@ AUTOMAKE_OPTIONS = subdir-objects ############################################################################### ############################################################################### -noinst_LTLIBRARIES = shared/libcsiphash.la shared/libcrbtree.la \ - shared/libnacd.la shared/libndhcp4.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-base/libnm-base.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-platform/libnm-platform.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - introspection/libnmdbus.la libnm-core/libnm-core.la \ - $(libnm_crypto_lib) libnm/libnm_static.la \ + +############################################################################### +noinst_LTLIBRARIES = src/c-siphash/libc-siphash.la \ + src/c-rbtree/libc-rbtree.la src/n-acd/libn-acd.la \ + src/n-dhcp4/libn-dhcp4.la src/libnm-std-aux/libnm-std-aux.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-client-test/libnm-client-test.la \ + introspection/libnmdbus.la \ + src/libnm-core-impl/libnm-core-impl.la $(libnm_crypto_lib) \ + src/libnm-client-impl/libnm-client-impl.la \ src/core/libNetworkManagerBase.la \ src/core/libNetworkManager.la src/core/libnm-systemd-core.la \ - $(NULL) shared/systemd/libnm-systemd-logging-stub.la \ - shared/systemd/libnm-systemd-shared.la \ - src/core/initrd/libnmi-core.la $(am__append_22) \ + $(NULL) src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/nm-initrd-generator/libnmi-core.la $(am__append_22) \ $(am__append_30) $(am__append_37) $(am__append_42) \ - dispatcher/libnm-dispatcher-core.la $(am__append_90) -check_LTLIBRARIES = $(am__append_92) -noinst_LIBRARIES = $(am__append_59) $(am__append_63) -noinst_DATA = $(am__append_10) + src/nm-dispatcher/libnm-dispatcher-core.la $(am__append_86) +check_LTLIBRARIES = $(am__append_88) +noinst_LIBRARIES = $(am__append_55) $(am__append_59) +noinst_DATA = $(am__append_11) dist_libexec_SCRIPTS = $(am__append_26) ############################################################################### -lib_LTLIBRARIES = libnm/libnm.la +lib_LTLIBRARIES = src/libnm-client-impl/libnm.la plugin_LTLIBRARIES = $(core_plugins) ############################################################################### @@ -4164,25 +4206,26 @@ core_plugins = $(am__append_19) $(am__append_21) $(am__append_29) \ $(am__append_33) $(am__append_44) $(am__append_47) \ $(am__append_49) service_DATA = -man_MANS = $(am__append_84) +man_MANS = $(am__append_80) examples_DATA = data/server.conf CLEANFILES = $(introspection_sources) $(DBUS_INTERFACE_DOCS) \ src/core/NetworkManager.ver $(am__append_23) \ $(dispatcher_nmdbus_dispatcher_sources) \ - dispatcher/org.freedesktop.nm_dispatcher.service \ - $(am__append_69) clients/tests/test-client.log \ + src/nm-dispatcher/org.freedesktop.nm_dispatcher.service \ + $(am__append_65) src/tests/client/test-client.log \ data/NetworkManager-dispatcher.service \ data/NetworkManager-wait-online.service \ data/NetworkManager.service data/server.conf $(NULL) \ - $(am__append_72) man/common.ent $(am__append_85) \ - $(am__append_88) $(GLIB_GENERATED) $(INTROSPECTION_GIRS) \ + $(am__append_68) man/common.ent $(am__append_81) \ + $(am__append_84) $(GLIB_GENERATED) $(INTROSPECTION_GIRS) \ $(typelib_DATA) cscope.in.out cscope.out cscope.po.out $(NULL) \ - $(am__append_94) + $(am__append_90) ############################################################################### DISTCLEANFILES = config-extra.h intltool-extract intltool-merge \ - intltool-update $(polkit_policy_DATA) libnm/libnm.pc \ - $(am__append_13) $(am__append_14) $(am__append_50) + intltool-update $(polkit_policy_DATA) \ + src/libnm-client-impl/libnm.pc $(am__append_14) \ + $(am__append_15) $(am__append_50) ############################################################################### @@ -4206,260 +4249,277 @@ DISTCLEANFILES = config-extra.h intltool-extract intltool-merge \ ############################################################################### ############################################################################### - -############################################################################### # examples ############################################################################### -EXTRA_DIST = shared/c-stdaux/src/c-stdaux.h $(NULL) \ - shared/nm-platform/tests/meson.build $(NULL) \ - libnm-core/nm-libnm-core-intern/README.md \ - libnm-core/nm-libnm-core-aux/README.md \ - libnm/nm-libnm-aux/README.md \ - shared/nm-glib-aux/tests/meson.build shared/README.md $(NULL) \ +EXTRA_DIST = src/c-stdaux/src/c-stdaux.h $(NULL) \ + src/libnm-std-aux/meson.build src/libnm-glib-aux/meson.build \ + src/libnm-udev-aux/meson.build src/libnm-base/meson.build \ + src/libnm-log-core/meson.build src/libnm-log-null/meson.build \ + src/libnm-platform/meson.build \ + src/libnm-platform/tests/meson.build $(NULL) \ + src/libnm-core-aux-intern/README.md \ + src/libnm-core-aux-intern/meson.build $(NULL) \ + src/libnm-core-aux-extern/README.md \ + src/libnm-core-aux-extern/meson.build $(NULL) \ + src/libnm-client-aux-extern/README.md \ + src/libnm-client-aux-extern/meson.build $(NULL) \ + src/libnm-client-test/meson.build $(NULL) \ + src/libnm-glib-aux/tests/meson.build $(NULL) \ $(dbusinterfaces_DATA) introspection/meson.build \ - libnm-core/nm-crypto-gnutls.c libnm-core/nm-crypto-nss.c \ - libnm-core/meson.build $(NULL) \ - libnm-core/tests/certs/ca-no-ending-newline.pem \ - libnm-core/tests/certs/pkcs8-decrypted.der \ - libnm-core/tests/certs/pkcs8-enc-key.pem \ - libnm-core/tests/certs/pkcs8-noenc-key.pem \ - libnm-core/tests/certs/test2_ca_cert.pem \ - libnm-core/tests/certs/test2-cert.p12 \ - libnm-core/tests/certs/test2_key_and_cert.pem \ - libnm-core/tests/certs/test-aes-128-key.pem \ - libnm-core/tests/certs/test-aes-256-key.pem \ - libnm-core/tests/certs/test_ca_cert.der \ - libnm-core/tests/certs/test_ca_cert.pem \ - libnm-core/tests/certs/test-ca-cert.pem \ - libnm-core/tests/certs/test-cert.p12 \ - libnm-core/tests/certs/test_key_and_cert.pem \ - libnm-core/tests/certs/test-key-and-cert.pem \ - libnm-core/tests/certs/test-key-only-decrypted.der \ - libnm-core/tests/certs/test-key-only-decrypted.pem \ - libnm-core/tests/certs/test-key-only.pem \ - libnm-core/tests/certs/test-tpm2wrapped-key.pem \ - libnm-core/tests/nm-core-tests-enum-types.c.template \ - libnm-core/tests/nm-core-tests-enum-types.h.template \ - libnm-core/tests/meson.build libnm/nm-enum-types.c.template \ - libnm/nm-enum-types.h.template libnm/libnm.pc.in \ - libnm/libnm.ver $(am__append_11) \ + src/libnm-core-impl/README.md src/libnm-core-impl/meson.build \ + src/libnm-core-intern/README.md \ + src/libnm-core-intern/meson.build \ + src/libnm-core-public/README.md \ + src/libnm-core-public/meson.build $(NULL) \ + src/libnm-core-impl/nm-crypto-gnutls.c \ + src/libnm-core-impl/nm-crypto-nss.c \ + src/libnm-core-impl/meson.build $(NULL) \ + src/libnm-core-impl/tests/certs/ca-no-ending-newline.pem \ + src/libnm-core-impl/tests/certs/pkcs8-decrypted.der \ + src/libnm-core-impl/tests/certs/pkcs8-enc-key.pem \ + src/libnm-core-impl/tests/certs/pkcs8-noenc-key.pem \ + src/libnm-core-impl/tests/certs/test2_ca_cert.pem \ + src/libnm-core-impl/tests/certs/test2-cert.p12 \ + src/libnm-core-impl/tests/certs/test2_key_and_cert.pem \ + src/libnm-core-impl/tests/certs/test-aes-128-key.pem \ + src/libnm-core-impl/tests/certs/test-aes-256-key.pem \ + src/libnm-core-impl/tests/certs/test_ca_cert.der \ + src/libnm-core-impl/tests/certs/test_ca_cert.pem \ + src/libnm-core-impl/tests/certs/test-ca-cert.pem \ + src/libnm-core-impl/tests/certs/test-cert.p12 \ + src/libnm-core-impl/tests/certs/test_key_and_cert.pem \ + src/libnm-core-impl/tests/certs/test-key-and-cert.pem \ + src/libnm-core-impl/tests/certs/test-key-only-decrypted.der \ + src/libnm-core-impl/tests/certs/test-key-only-decrypted.pem \ + src/libnm-core-impl/tests/certs/test-key-only.pem \ + src/libnm-core-impl/tests/certs/test-tpm2wrapped-key.pem \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.c.template \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.h.template \ + src/libnm-core-impl/tests/meson.build \ + src/libnm-client-public/nm-enum-types.c.template \ + src/libnm-client-public/nm-enum-types.h.template \ + src/libnm-client-impl/libnm.pc.in \ + src/libnm-client-impl/libnm.ver $(am__append_12) \ tools/generate-docs-nm-property-infos.pl \ tools/generate-docs-nm-settings-docs-merge.py \ - tools/generate-docs-nm-settings-docs-gir.py libnm/meson.build \ - $(NULL) libnm/tests/meson.build src/core/systemd/meson.build \ - src/core/platform/linux/nl802154.h src/core/initrd/meson.build \ - src/core/initrd/tests/meson.build \ - src/core/initrd/tests/sysfs/class/net/eth0/address \ - src/core/initrd/tests/sysfs/class/net/eth2/address \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/hostname \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/dhcp \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/flags \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/isns-server \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/pri-radius-server \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/slp-server \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/sec-radius-server \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/index \ - src/core/initrd/tests/sysfs/firmware/ibft/initiator/flags \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/nic-assoc \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/chap-type \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/flags \ - src/core/initrd/tests/sysfs/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/target-name \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/nic-assoc \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/ip-addr \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/chap-type \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/index \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/lun \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/flags \ - src/core/initrd/tests/sysfs/firmware/ibft/target2/port \ - src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/oem_table_id \ - src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/oem_id \ - src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/signature \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/prefix-len \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/hostname \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/gateway \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/mac \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/vlan \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/primary-dns \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/dhcp \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/origin \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/secondary-dns \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/ip-addr \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/subnet-mask \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/index \ - src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/flags \ - src/core/initrd/tests/sysfs-bad-dns1/class/net/eth0/address \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-bad-dns2/class/net/eth0/address \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-bad-gateway/class/net/eth0/address \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-bad-ipaddr/class/net/eth0/address \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-dhcp/class/net/eth0/address \ - src/core/initrd/tests/sysfs-dhcp/class/net/eth1/address \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/gateway \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/mac \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/vlan \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/primary-dns \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/origin \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/secondary-dns \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/index \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/target-name \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/ip-addr \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/index \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/lun \ - src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/port \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootpath \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-request \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-response \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/broadcast-ip \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/client-ip \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/client-name \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/domain-name \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/gateway-ip \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/name \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/netmask-ip \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/root-path \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/server-ip \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/tftp-file \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/vendor-options \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/device_type \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/local-mac-address \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/mac-address \ - src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/name \ - src/core/initrd/tests/sysfs-dt-tftp/firmware/devicetree/base/chosen/bootpath \ - src/core/initrd/tests/sysfs-static/class/net/eth0/address \ - src/core/initrd/tests/sysfs-static/class/net/eth1/address \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/gateway \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/primary-dns \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/secondary-dns \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-static/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target0/port \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/gateway \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/mac \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/vlan \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/primary-dns \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/origin \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/secondary-dns \ - src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/index \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target1/target-name \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target1/ip-addr \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target1/index \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target1/lun \ - src/core/initrd/tests/sysfs-static/firmware/ibft/target1/port \ - src/core/initrd/tests/sysfs-vlan/class/net/eth0/address \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/prefix-len \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/mac \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/vlan \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/origin \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/ip-addr \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/subnet-mask \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/index \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/initiator/initiator-name \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/target-name \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/ip-addr \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/index \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/lun \ - src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/port \ + tools/generate-docs-nm-settings-docs-gir.py \ + src/libnm-client-impl/meson.build $(NULL) \ + src/libnm-client-impl/tests/meson.build \ + src/contrib/meson.build src/contrib/tests/meson.build $(NULL) \ + src/core/systemd/meson.build \ + src/nm-initrd-generator/meson.build \ + src/nm-initrd-generator/tests/meson.build \ + src/nm-initrd-generator/tests/sysfs/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs/class/net/eth2/address \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/hostname \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/dhcp \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet0/flags \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/isns-server \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/pri-radius-server \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/slp-server \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/sec-radius-server \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/index \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/initiator/flags \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/nic-assoc \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/chap-type \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/flags \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/target-name \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/nic-assoc \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/ip-addr \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/chap-type \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/index \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/lun \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/flags \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/target2/port \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/acpi_header/oem_table_id \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/acpi_header/oem_id \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/acpi_header/signature \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/prefix-len \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/hostname \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/gateway \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/mac \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/vlan \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/primary-dns \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/dhcp \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/origin \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/secondary-dns \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/ip-addr \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/subnet-mask \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/index \ + src/nm-initrd-generator/tests/sysfs/firmware/ibft/ethernet2/flags \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-bad-dns1/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-bad-dns2/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-bad-gateway/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-bad-ipaddr/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-dhcp/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-dhcp/class/net/eth1/address \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/gateway \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/mac \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/vlan \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/primary-dns \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/origin \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/ethernet1/index \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/target-name \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/ip-addr \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/index \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/lun \ + src/nm-initrd-generator/tests/sysfs-dhcp/firmware/ibft/target1/port \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/bootpath \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-request \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-response \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/broadcast-ip \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/client-ip \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/client-name \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/domain-name \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/gateway-ip \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/name \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/netmask-ip \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/root-path \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/server-ip \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/tftp-file \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/chosen/vendor-options \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/device_type \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/local-mac-address \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/mac-address \ + src/nm-initrd-generator/tests/sysfs-dt/firmware/devicetree/base/ethernet/name \ + src/nm-initrd-generator/tests/sysfs-dt-tftp/firmware/devicetree/base/chosen/bootpath \ + src/nm-initrd-generator/tests/sysfs-static/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-static/class/net/eth1/address \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/gateway \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/primary-dns \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target0/port \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/gateway \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/mac \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/vlan \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/primary-dns \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/origin \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/secondary-dns \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/ethernet1/index \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/target-name \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/ip-addr \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/index \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/lun \ + src/nm-initrd-generator/tests/sysfs-static/firmware/ibft/target1/port \ + src/nm-initrd-generator/tests/sysfs-vlan/class/net/eth0/address \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/prefix-len \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/mac \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/vlan \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/origin \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/subnet-mask \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/ethernet0/index \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/initiator/initiator-name \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/target-name \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/ip-addr \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/index \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/lun \ + src/nm-initrd-generator/tests/sysfs-vlan/firmware/ibft/target0/port \ $(NULL) src/core/org.freedesktop.NetworkManager.conf \ src/core/nm-test-utils-core.h src/core/meson.build \ src/core/dhcp/meson.build \ @@ -4763,61 +4823,60 @@ EXTRA_DIST = shared/c-stdaux/src/c-stdaux.h $(NULL) \ src/core/tests/config/conf.d/90-last.conf \ src/core/tests/config/meson.build \ src/core/tests/test-secret-agent.py src/core/tests/meson.build \ - dispatcher/nm-dispatcher.conf \ - dispatcher/org.freedesktop.nm_dispatcher.service.in \ - dispatcher/nm-dispatcher.xml dispatcher/meson.build \ - dispatcher/tests/dispatcher-connectivity-full \ - dispatcher/tests/dispatcher-connectivity-unknown \ - dispatcher/tests/dispatcher-down \ - dispatcher/tests/dispatcher-external \ - dispatcher/tests/dispatcher-up \ - dispatcher/tests/dispatcher-vpn-down \ - dispatcher/tests/dispatcher-vpn-up \ - dispatcher/tests/meson.build $(NULL) clients/meson.build \ - clients/common/qrcodegen.c clients/common/qrcodegen.h \ - $(clients_common_settings_doc_h) \ - $(clients_common_settings_doc_h).in \ - clients/common/tests/wg-test0.conf \ - clients/common/tests/wg-test1.conf \ - clients/common/tests/wg-test2.conf \ - clients/common/tests/wg-test3.conf $(NULL) \ - clients/cli/nmcli-completion clients/cli/meson.build \ - clients/common/settings-docs.xsl clients/common/meson.build \ - clients/common/tests/meson.build clients/tui/meson.build \ - clients/tui/newt/meson.build $(am__append_68) \ - clients/tests/test-client.py \ - clients/tests/test-client.check-on-disk/test_001.expected \ - clients/tests/test-client.check-on-disk/test_002.expected \ - clients/tests/test-client.check-on-disk/test_003.expected \ - clients/tests/test-client.check-on-disk/test_004.expected \ - $(NULL) data/84-nm-drivers.rules data/85-nm-unmanaged.rules \ - data/90-nm-thunderbolt.rules \ + src/nm-dispatcher/nm-dispatcher.conf \ + src/nm-dispatcher/org.freedesktop.nm_dispatcher.service.in \ + src/nm-dispatcher/nm-dispatcher.xml \ + src/nm-dispatcher/meson.build $(NULL) \ + src/nm-dispatcher/tests/dispatcher-connectivity-full \ + src/nm-dispatcher/tests/dispatcher-connectivity-unknown \ + src/nm-dispatcher/tests/dispatcher-down \ + src/nm-dispatcher/tests/dispatcher-external \ + src/nm-dispatcher/tests/dispatcher-up \ + src/nm-dispatcher/tests/dispatcher-vpn-down \ + src/nm-dispatcher/tests/dispatcher-vpn-up \ + src/nm-dispatcher/tests/meson.build $(NULL) \ + src/nm-online/meson.build src/libnmc-base/qrcodegen.c \ + src/libnmc-base/qrcodegen.h $(NULL) \ + $(libnmc_setting_settings_doc_h) \ + $(libnmc_setting_settings_doc_h).in \ + src/libnmc-setting/tests/wg-test0.conf \ + src/libnmc-setting/tests/wg-test1.conf \ + src/libnmc-setting/tests/wg-test2.conf \ + src/libnmc-setting/tests/wg-test3.conf $(NULL) \ + src/nmcli/nmcli-completion src/nmcli/meson.build \ + src/libnmc-setting/settings-docs.xsl \ + src/libnmc-setting/meson.build \ + src/libnmc-setting/tests/meson.build \ + src/libnmt-newt/meson.build src/nmtui/meson.build \ + $(am__append_64) src/tests/client/test-client.sh \ + src/tests/client/test-client.py \ + src/tests/client/test-client.check-on-disk/test_001.expected \ + src/tests/client/test-client.check-on-disk/test_002.expected \ + src/tests/client/test-client.check-on-disk/test_003.expected \ + src/tests/client/test-client.check-on-disk/test_004.expected \ + src/tests/client/meson.build $(NULL) data/84-nm-drivers.rules \ + data/85-nm-unmanaged.rules data/90-nm-thunderbolt.rules \ data/NetworkManager-dispatcher.service.in \ data/NetworkManager-wait-online-systemd-pre200.service.in \ data/NetworkManager-wait-online.service.in \ data/NetworkManager.service.in data/meson.build \ data/nm-shared.xml data/server.conf.in $(NULL) \ - $(am__append_74) $(am__append_77) $(am__append_80) \ + $(am__append_70) $(am__append_73) $(am__append_76) \ man/common.ent.in $(man_nm_settings_xml) $(addsuffix \ .xsl,$(basename $(man_nm_settings_xml))) $(man_pages) \ $(addsuffix .xml,$(basename $(man_pages))) \ $(man_pages_autogen) $(NULL) man/meson.build \ vapi/NM-1.0.metadata vapi/libnm.deps vapi/meson.build \ - CONTRIBUTING COPYING.LGPL COPYING.GFDL NetworkManager.pc.in \ + CONTRIBUTING.md COPYING.LGPL COPYING.GFDL NetworkManager.pc.in \ intltool-extract.in intltool-merge.in intltool-update.in \ linker-script-binary.ver linker-script-devices.ver \ linker-script-settings.ver src/core/ppp/nm-ppp-plugin.ver \ Makefile.glib autogen.sh lsan.suppressions \ valgrind.suppressions meson.build meson_options.txt \ config.h.meson config-extra.h.meson docs/meson.build \ - po/meson.build shared/nm-test-libnm-utils.h \ - shared/nm-test-utils-impl.c shared/nm-utils/nm-compat.c \ - shared/nm-utils/nm-compat.h shared/nm-utils/nm-test-utils.h \ - shared/nm-utils/nm-vpn-editor-plugin-call.h \ - shared/nm-utils/nm-vpn-plugin-macros.h \ - shared/nm-utils/nm-vpn-plugin-utils.c \ - shared/nm-utils/nm-vpn-plugin-utils.h shared/meson.build \ - libnm-core/nm-version-macros.h.in \ + po/meson.build src/meson.build \ + src/libnm-core-public/nm-version-macros.h.in \ + src/contrib/nm-vpn-editor-plugin-call.h \ tools/check-config-options.sh tools/check-docs.sh \ tools/check-exports.sh tools/check-compare-generated.sh \ tools/check-gitlab-ci.sh tools/check-tree.sh \ @@ -4882,30 +4941,34 @@ EXTRA_DIST = shared/c-stdaux/src/c-stdaux.h $(NULL) \ examples/shell/get-hostname.sh examples/shell/list-devices.sh \ examples/shell/disconnect-device.sh \ examples/shell/active-wifi.sh $(NULL) -EXTRA_LTLIBRARIES = $(am__append_53) +EXTRA_LTLIBRARIES = dist_hook = dist-hook-settings-ifcfg-rh-alias-files -dist_dependencies = libnm-core/nm-vpn-dbus-types.xml \ - libnm-core/nm-dbus-types.xml $(am__append_75) $(am__append_78) \ - $(am__append_81) $(man_pages) $(man_pages_autogen) +dist_dependencies = src/libnm-core-public/nm-vpn-dbus-types.xml \ + src/libnm-core-public/nm-dbus-types.xml $(am__append_71) \ + $(am__append_74) $(am__append_77) $(man_pages) \ + $(man_pages_autogen) dist_configure_check = $(am__append_2) install_data_hook = install-data-hook-dirs $(am__append_27) \ - install-data-hook-dispatcher $(am__append_57) $(am__append_66) \ - $(am__append_82) -install_exec_hook = $(am__append_61) -uninstall_hook = $(am__append_58) $(am__append_62) $(am__append_67) \ - $(am__append_83) -BUILT_SOURCES = libnm-core/nm-vpn-dbus-types.xml \ - libnm-core/nm-dbus-types.xml $(gir_DATA) $(typelib_DATA) -GLIB_GENERATED = $(libnm_core_lib_h_pub_mkenums) \ - $(libnm_core_lib_c_mkenums) \ - libnm-core/tests/nm-core-tests-enum-types.h \ - libnm-core/tests/nm-core-tests-enum-types.c \ - $(libnm_lib_h_pub_mkenums) $(libnm_lib_c_mkenums) -man_pages = man/NetworkManager.8 man/NetworkManager.conf.5 \ - man/nm-online.1 man/nm-initrd-generator.8 man/nmcli-examples.7 \ - man/nmcli.1 man/nmtui.1 $(am__append_76) $(am__append_79) + install-data-hook-dispatcher $(am__append_53) $(am__append_62) \ + $(am__append_78) +install_exec_hook = $(am__append_57) +uninstall_hook = $(am__append_54) $(am__append_58) $(am__append_63) \ + $(am__append_79) +BUILT_SOURCES = src/libnm-core-public/nm-vpn-dbus-types.xml \ + src/libnm-core-public/nm-dbus-types.xml $(gir_DATA) \ + $(typelib_DATA) +GLIB_GENERATED = $(src_libnm_core_public_mkenums_h) \ + $(src_libnm_core_public_mkenums_c) $(NULL) \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.h \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.c \ + $(src_libnm_client_public_mkenums_h) \ + $(src_libnm_client_public_mkenums_c) +man_pages = man/NetworkManager.8 man/NetworkManager-dispatcher.8 \ + man/NetworkManager.conf.5 man/nm-online.1 \ + man/nm-initrd-generator.8 man/nmcli-examples.7 man/nmcli.1 \ + man/nmtui.1 $(NULL) $(am__append_72) $(am__append_75) man_pages_autogen = man/nm-settings-dbus.5 man/nm-settings-keyfile.5 \ - man/nm-settings-nmcli.5 $(NULL) $(am__append_73) + man/nm-settings-nmcli.5 $(NULL) $(am__append_69) ############################################################################### @@ -4932,19 +4995,24 @@ man_pages_autogen = man/nm-settings-dbus.5 man/nm-settings-keyfile.5 \ ############################################################################### ############################################################################### -# dispatcher/tests +# src/nm-dispatcher/tests ############################################################################### ############################################################################### -check_programs = shared/nm-platform/tests/test-nm-platform \ - shared/nm-glib-aux/tests/test-shared-general $(am__append_5) \ - libnm-core/tests/test-compare libnm-core/tests/test-crypto \ - libnm-core/tests/test-general libnm-core/tests/test-keyfile \ - libnm-core/tests/test-secrets libnm-core/tests/test-setting \ - libnm-core/tests/test-settings-defaults libnm/tests/test-libnm \ - $(am__append_15) src/core/initrd/tests/test-dt-reader \ - src/core/initrd/tests/test-ibft-reader \ - src/core/initrd/tests/test-cmdline-reader \ +check_programs = src/libnm-platform/tests/test-nm-platform \ + src/libnm-client-aux-extern/tests/test-libnm-client-aux \ + src/libnm-glib-aux/tests/test-shared-general $(am__append_6) \ + src/libnm-core-impl/tests/test-compare \ + src/libnm-core-impl/tests/test-crypto \ + src/libnm-core-impl/tests/test-general \ + src/libnm-core-impl/tests/test-keyfile \ + src/libnm-core-impl/tests/test-secrets \ + src/libnm-core-impl/tests/test-setting \ + src/libnm-core-impl/tests/test-settings-defaults \ + src/libnm-client-impl/tests/test-libnm $(am__append_16) \ + src/nm-initrd-generator/tests/test-dt-reader \ + src/nm-initrd-generator/tests/test-ibft-reader \ + src/nm-initrd-generator/tests/test-cmdline-reader \ src/core/dhcp/tests/test-dhcp-dhclient \ src/core/dhcp/tests/test-dhcp-utils \ src/core/settings/plugins/keyfile/tests/test-keyfile-settings \ @@ -4971,10 +5039,9 @@ check_programs = shared/nm-platform/tests/test-nm-platform \ src/core/tests/test-ip4-config src/core/tests/test-ip6-config \ src/core/tests/test-l3cfg src/core/tests/test-systemd \ src/core/tests/test-utils src/core/tests/test-wired-defname \ - $(NULL) dispatcher/tests/test-dispatcher-envp $(am__append_54) \ - $(am__append_55) clients/common/tests/test-libnm-core-aux \ - $(am__append_70) -check_programs_norun = $(am__append_16) $(am__append_41) \ + $(NULL) src/nm-dispatcher/tests/test-dispatcher-envp \ + src/libnmc-setting/tests/test-libnmc-setting $(am__append_66) +check_programs_norun = $(am__append_17) $(am__append_41) \ src/core/platform/tests/monitor \ src/core/ndisc/tests/test-ndisc-linux \ examples/C/glib/add-connection-gdbus \ @@ -4984,46 +5051,49 @@ check_programs_norun = $(am__append_16) $(am__append_41) \ examples/C/glib/list-connections-gdbus \ examples/C/glib/list-connections-libnm \ examples/C/glib/monitor-nm-running-gdbus \ - examples/C/glib/monitor-nm-state-gdbus $(am__append_93) + examples/C/glib/monitor-nm-state-gdbus \ + examples/C/glib/vpn-import-libnm $(NULL) $(am__append_89) ############################################################################### # just test, that we can build "nm-vpn-plugin-utils.c" ############################################################################### -check_ltlibraries = $(am__append_6) $(am__append_7) \ - libnm/tests/libnm-vpn-plugin-utils-test.la \ +check_ltlibraries = $(am__append_7) $(am__append_8) \ + src/contrib/tests/libnm-vpn-plugin-utils-test.la \ src/core/libNetworkManagerTest.la \ - clients/common/libnmc-base.la $(am__append_52) -check_local = check-docs check-local-exports-libnm $(am__append_12) \ + src/libnmc-base/libnmc-base.la \ + src/libnmc-setting/libnmc-setting.la +check_local = check-docs check-local-exports-libnm $(am__append_13) \ check-config-options $(am__append_24) $(am__append_31) \ check-local-devices-adsl $(am__append_35) $(am__append_45) \ - $(am__append_48) $(am__append_51) \ - check-local-clients-tests-test-client check-local-gitlab-ci \ - $(am__append_95) check-tree check-po-msgfmt -VAPIGEN_VAPIS = $(am__append_86) -dbusservice_DATA = $(am__append_28) dispatcher/nm-dispatcher.conf \ + $(am__append_48) $(am__append_51) check-local-tests-client \ + check-local-gitlab-ci $(am__append_91) check-tree \ + check-po-msgfmt +VAPIGEN_VAPIS = $(am__append_82) +dbusservice_DATA = $(am__append_28) \ + src/nm-dispatcher/nm-dispatcher.conf \ src/core/org.freedesktop.NetworkManager.conf dbusactivation_DATA = \ - dispatcher/org.freedesktop.nm_dispatcher.service -systemdsystemunit_DATA = $(am__append_65) $(am__append_71) -INTROSPECTION_GIRS = $(am__append_9) + src/nm-dispatcher/org.freedesktop.nm_dispatcher.service +systemdsystemunit_DATA = $(am__append_61) $(am__append_67) +INTROSPECTION_GIRS = $(am__append_10) INTROSPECTION_SCANNER_ARGS = INTROSPECTION_COMPILER_ARGS = # Pass SANITIZER_ENV where a command that uses built libraries is # executed, to suppress possible errors INTROSPECTION_SCANNER_ENV = $(SANITIZER_ENV) LDFLAGS="$(SANITIZER_LIB_LDFLAGS)" libnmincludedir = $(includedir)/libnm -libnminclude_HEADERS = $(libnm_core_lib_h_pub_real) \ +libnminclude_HEADERS = $(src_libnm_core_impl_lib_h_pub_real) \ $(libnm_lib_h_pub_real) -nodist_libnminclude_HEADERS = $(libnm_core_lib_h_pub_mkenums) \ - $(libnm_lib_h_pub_mkenums) +nodist_libnminclude_HEADERS = $(src_libnm_core_public_mkenums_h) \ + $(src_libnm_client_public_mkenums_h) pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libnm/libnm.pc +pkgconfig_DATA = src/libnm-client-impl/libnm.pc pppd_plugindir = $(PPPD_PLUGIN_DIR) pppd_plugin_LTLIBRARIES = $(am__append_20) vapidir = $(datadir)/vala/vapi -vapi_DATA = $(am__append_87) +vapi_DATA = $(am__append_83) examplesdir = $(docdir)/examples rundir = $(runstatedir)/NetworkManager statedir = $(localstatedir)/lib/NetworkManager @@ -5089,443 +5159,536 @@ dist_polkit_policy_in_in_files = \ data/org.freedesktop.NetworkManager.policy.in.in polkit_policy_DATA = $(dist_polkit_policy_in_in_files:.policy.in.in=.policy) -shared_libcsiphash_la_CFLAGS = \ +src_c_siphash_libc_siphash_la_CFLAGS = \ $(AM_CFLAGS) \ -std=c11 \ - -I$(srcdir)/shared/c-stdaux/src \ + -I$(srcdir)/src/c-stdaux/src \ $(NULL) -shared_libcsiphash_la_CPPFLAGS = \ +src_c_siphash_libc_siphash_la_CPPFLAGS = \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -shared_libcsiphash_la_LDFLAGS = \ +src_c_siphash_libc_siphash_la_LDFLAGS = \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_libcsiphash_la_SOURCES = \ - shared/c-siphash/src/c-siphash.c \ - shared/c-siphash/src/c-siphash.h \ +src_c_siphash_libc_siphash_la_SOURCES = \ + src/c-siphash/src/c-siphash.c \ + src/c-siphash/src/c-siphash.h \ $(NULL) -shared_libcrbtree_la_CFLAGS = \ +src_c_rbtree_libc_rbtree_la_CFLAGS = \ $(AM_CFLAGS) \ -std=c11 \ - -I$(srcdir)/shared/c-stdaux/src \ + -I$(srcdir)/src/c-stdaux/src \ $(NULL) -shared_libcrbtree_la_CPPFLAGS = \ +src_c_rbtree_libc_rbtree_la_CPPFLAGS = \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -shared_libcrbtree_la_LDFLAGS = \ +src_c_rbtree_libc_rbtree_la_LDFLAGS = \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_libcrbtree_la_SOURCES = \ - shared/c-rbtree/src/c-rbtree.c \ - shared/c-rbtree/src/c-rbtree.h \ - shared/c-rbtree/src/c-rbtree-private.h \ +src_c_rbtree_libc_rbtree_la_SOURCES = \ + src/c-rbtree/src/c-rbtree.c \ + src/c-rbtree/src/c-rbtree.h \ + src/c-rbtree/src/c-rbtree-private.h \ $(NULL) -shared_libnacd_la_CFLAGS = \ +src_n_acd_libn_acd_la_CFLAGS = \ $(AM_CFLAGS) \ -std=c11 \ -Wno-pointer-arith \ -Wno-vla \ $(NULL) -shared_libnacd_la_CPPFLAGS = \ +src_n_acd_libn_acd_la_CPPFLAGS = \ -D_GNU_SOURCE \ -DSO_ATTACH_BPF=50 \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -I$(srcdir)/shared/c-stdaux/src \ - -I$(srcdir)/shared/c-list/src \ - -I$(srcdir)/shared/c-siphash/src \ - -I$(srcdir)/shared/c-rbtree/src \ + -I$(srcdir)/src/c-stdaux/src \ + -I$(srcdir)/src/c-list/src \ + -I$(srcdir)/src/c-siphash/src \ + -I$(srcdir)/src/c-rbtree/src \ $(NULL) -shared_libnacd_la_LDFLAGS = \ +src_n_acd_libn_acd_la_LDFLAGS = \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_libnacd_la_SOURCES = shared/n-acd/src/n-acd.c \ - shared/n-acd/src/n-acd.h shared/n-acd/src/n-acd-private.h \ - shared/n-acd/src/n-acd-probe.c shared/n-acd/src/util/timer.c \ - shared/n-acd/src/util/timer.h $(NULL) $(am__append_3) \ +src_n_acd_libn_acd_la_SOURCES = src/n-acd/src/n-acd.c \ + src/n-acd/src/n-acd.h src/n-acd/src/n-acd-private.h \ + src/n-acd/src/n-acd-probe.c src/n-acd/src/util/timer.c \ + src/n-acd/src/util/timer.h $(NULL) $(am__append_3) \ $(am__append_4) -shared_libndhcp4_la_CFLAGS = \ +src_n_dhcp4_libn_dhcp4_la_CFLAGS = \ $(AM_CFLAGS) \ -std=c11 \ -Wno-error=declaration-after-statement \ -Wno-pointer-arith \ $(NULL) -shared_libndhcp4_la_CPPFLAGS = \ +src_n_dhcp4_libn_dhcp4_la_CPPFLAGS = \ -D_GNU_SOURCE \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -I$(srcdir)/shared/c-stdaux/src \ - -I$(srcdir)/shared/c-list/src \ - -I$(srcdir)/shared/c-siphash/src \ + -I$(srcdir)/src/c-stdaux/src \ + -I$(srcdir)/src/c-list/src \ + -I$(srcdir)/src/c-siphash/src \ + $(NULL) + +src_n_dhcp4_libn_dhcp4_la_LDFLAGS = \ + $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_libndhcp4_la_LDFLAGS = \ - $(SANITIZER_LIB_LDFLAGS) - -shared_libndhcp4_la_SOURCES = \ - shared/n-dhcp4/src/n-dhcp4-c-connection.c \ - shared/n-dhcp4/src/n-dhcp4-c-lease.c \ - shared/n-dhcp4/src/n-dhcp4-c-probe.c \ - shared/n-dhcp4/src/n-dhcp4-client.c \ - shared/n-dhcp4/src/n-dhcp4-incoming.c \ - shared/n-dhcp4/src/n-dhcp4-outgoing.c \ - shared/n-dhcp4/src/n-dhcp4-private.h \ - shared/n-dhcp4/src/n-dhcp4-socket.c \ - shared/n-dhcp4/src/n-dhcp4.h \ - shared/n-dhcp4/src/util/packet.c \ - shared/n-dhcp4/src/util/packet.h \ - shared/n-dhcp4/src/util/socket.c \ - shared/n-dhcp4/src/util/socket.h \ +src_n_dhcp4_libn_dhcp4_la_SOURCES = \ + src/n-dhcp4/src/n-dhcp4-c-connection.c \ + src/n-dhcp4/src/n-dhcp4-c-lease.c \ + src/n-dhcp4/src/n-dhcp4-c-probe.c \ + src/n-dhcp4/src/n-dhcp4-client.c \ + src/n-dhcp4/src/n-dhcp4-incoming.c \ + src/n-dhcp4/src/n-dhcp4-outgoing.c \ + src/n-dhcp4/src/n-dhcp4-private.h \ + src/n-dhcp4/src/n-dhcp4-socket.c \ + src/n-dhcp4/src/n-dhcp4.h \ + src/n-dhcp4/src/util/packet.c \ + src/n-dhcp4/src/util/packet.h \ + src/n-dhcp4/src/util/socket.c \ + src/n-dhcp4/src/util/socket.h \ $(NULL) -shared_nm_std_aux_libnm_std_aux_la_CPPFLAGS = \ +src_libnm_std_aux_libnm_std_aux_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnm"\" \ $(NULL) -shared_nm_std_aux_libnm_std_aux_la_SOURCES = \ - shared/c-list/src/c-list.h \ - shared/nm-std-aux/c-list-util.c \ - shared/nm-std-aux/c-list-util.h \ - shared/nm-std-aux/nm-dbus-compat.h \ - shared/nm-std-aux/nm-default-std.h \ - shared/nm-std-aux/nm-networkmanager-compilation.h \ - shared/nm-std-aux/nm-std-aux.h \ - shared/nm-std-aux/nm-std-utils.c \ - shared/nm-std-aux/nm-std-utils.h \ - shared/nm-std-aux/unaligned.h \ +src_libnm_std_aux_libnm_std_aux_la_SOURCES = \ + src/c-list/src/c-list.h \ + src/libnm-std-aux/c-list-util.c \ + src/libnm-std-aux/c-list-util.h \ + src/libnm-std-aux/nm-dbus-compat.h \ + src/libnm-std-aux/nm-default-std.h \ + src/libnm-std-aux/nm-networkmanager-compilation.h \ + src/libnm-std-aux/nm-std-aux.h \ + src/libnm-std-aux/nm-std-utils.c \ + src/libnm-std-aux/nm-std-utils.h \ + src/libnm-std-aux/unaligned.h \ $(NULL) -shared_nm_std_aux_libnm_std_aux_la_LDFLAGS = \ +src_libnm_std_aux_libnm_std_aux_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) ############################################################################### -shared_nm_glib_aux_cppflags = \ +src_libnm_glib_aux_cppflags = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(GLIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnm"\" \ $(NULL) -shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS = \ - $(shared_nm_glib_aux_cppflags) \ +src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS = \ + $(src_libnm_glib_aux_cppflags) \ $(NULL) -shared_nm_glib_aux_libnm_glib_aux_la_SOURCES = \ - shared/nm-glib-aux/nm-c-list.h \ - shared/nm-glib-aux/nm-dbus-aux.c \ - shared/nm-glib-aux/nm-dbus-aux.h \ - shared/nm-glib-aux/nm-dedup-multi.c \ - shared/nm-glib-aux/nm-dedup-multi.h \ - shared/nm-glib-aux/nm-default-glib-i18n-lib.h \ - shared/nm-glib-aux/nm-default-glib-i18n-prog.h \ - shared/nm-glib-aux/nm-default-glib.h \ - shared/nm-glib-aux/nm-enum-utils.c \ - shared/nm-glib-aux/nm-enum-utils.h \ - shared/nm-glib-aux/nm-errno.c \ - shared/nm-glib-aux/nm-errno.h \ - shared/nm-glib-aux/nm-gassert-patch.h \ - shared/nm-glib-aux/nm-glib.h \ - shared/nm-glib-aux/nm-hash-utils.c \ - shared/nm-glib-aux/nm-hash-utils.h \ - shared/nm-glib-aux/nm-io-utils.c \ - shared/nm-glib-aux/nm-io-utils.h \ - shared/nm-glib-aux/nm-jansson.h \ - shared/nm-glib-aux/nm-json-aux.c \ - shared/nm-glib-aux/nm-json-aux.h \ - shared/nm-glib-aux/nm-keyfile-aux.c \ - shared/nm-glib-aux/nm-keyfile-aux.h \ - shared/nm-glib-aux/nm-logging-base.c \ - shared/nm-glib-aux/nm-logging-base.h \ - shared/nm-glib-aux/nm-logging-fwd.h \ - shared/nm-glib-aux/nm-macros-internal.h \ - shared/nm-glib-aux/nm-obj.h \ - shared/nm-glib-aux/nm-random-utils.c \ - shared/nm-glib-aux/nm-random-utils.h \ - shared/nm-glib-aux/nm-ref-string.c \ - shared/nm-glib-aux/nm-ref-string.h \ - shared/nm-glib-aux/nm-secret-utils.c \ - shared/nm-glib-aux/nm-secret-utils.h \ - shared/nm-glib-aux/nm-shared-utils.c \ - shared/nm-glib-aux/nm-shared-utils.h \ - shared/nm-glib-aux/nm-str-buf.h \ - shared/nm-glib-aux/nm-time-utils.c \ - shared/nm-glib-aux/nm-time-utils.h \ - shared/nm-glib-aux/nm-value-type.h \ +src_libnm_glib_aux_libnm_glib_aux_la_SOURCES = \ + src/libnm-glib-aux/nm-c-list.h \ + src/libnm-glib-aux/nm-dbus-aux.c \ + src/libnm-glib-aux/nm-dbus-aux.h \ + src/libnm-glib-aux/nm-dedup-multi.c \ + src/libnm-glib-aux/nm-dedup-multi.h \ + src/libnm-glib-aux/nm-default-glib-i18n-lib.h \ + src/libnm-glib-aux/nm-default-glib-i18n-prog.h \ + src/libnm-glib-aux/nm-default-glib.h \ + src/libnm-glib-aux/nm-enum-utils.c \ + src/libnm-glib-aux/nm-enum-utils.h \ + src/libnm-glib-aux/nm-errno.c \ + src/libnm-glib-aux/nm-errno.h \ + src/libnm-glib-aux/nm-gassert-patch.h \ + src/libnm-glib-aux/nm-glib.h \ + src/libnm-glib-aux/nm-hash-utils.c \ + src/libnm-glib-aux/nm-hash-utils.h \ + src/libnm-glib-aux/nm-io-utils.c \ + src/libnm-glib-aux/nm-io-utils.h \ + src/libnm-glib-aux/nm-jansson.h \ + src/libnm-glib-aux/nm-json-aux.c \ + src/libnm-glib-aux/nm-json-aux.h \ + src/libnm-glib-aux/nm-keyfile-aux.c \ + src/libnm-glib-aux/nm-keyfile-aux.h \ + src/libnm-glib-aux/nm-logging-base.c \ + src/libnm-glib-aux/nm-logging-base.h \ + src/libnm-glib-aux/nm-logging-fwd.h \ + src/libnm-glib-aux/nm-logging-syslog.h \ + src/libnm-glib-aux/nm-macros-internal.h \ + src/libnm-glib-aux/nm-obj.h \ + src/libnm-glib-aux/nm-random-utils.c \ + src/libnm-glib-aux/nm-random-utils.h \ + src/libnm-glib-aux/nm-ref-string.c \ + src/libnm-glib-aux/nm-ref-string.h \ + src/libnm-glib-aux/nm-secret-utils.c \ + src/libnm-glib-aux/nm-secret-utils.h \ + src/libnm-glib-aux/nm-shared-utils.c \ + src/libnm-glib-aux/nm-shared-utils.h \ + src/libnm-glib-aux/nm-str-buf.h \ + src/libnm-glib-aux/nm-test-utils.h \ + src/libnm-glib-aux/nm-time-utils.c \ + src/libnm-glib-aux/nm-time-utils.h \ + src/libnm-glib-aux/nm-value-type.h \ $(NULL) -shared_nm_glib_aux_libnm_glib_aux_la_LDFLAGS = \ +src_libnm_glib_aux_libnm_glib_aux_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_nm_glib_aux_libnm_glib_aux_la_LIBADD = \ +src_libnm_glib_aux_libnm_glib_aux_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) -shared_nm_udev_aux_libnm_udev_aux_la_CPPFLAGS = \ - $(shared_nm_glib_aux_cppflags) \ +src_libnm_udev_aux_libnm_udev_aux_la_CPPFLAGS = \ + $(src_libnm_glib_aux_cppflags) \ $(LIBUDEV_CFLAGS) \ $(NULL) -shared_nm_udev_aux_libnm_udev_aux_la_SOURCES = \ - shared/nm-udev-aux/nm-udev-utils.c \ - shared/nm-udev-aux/nm-udev-utils.h \ +src_libnm_udev_aux_libnm_udev_aux_la_SOURCES = \ + src/libnm-udev-aux/nm-udev-utils.c \ + src/libnm-udev-aux/nm-udev-utils.h \ $(NULL) -shared_nm_udev_aux_libnm_udev_aux_la_LDFLAGS = \ +src_libnm_udev_aux_libnm_udev_aux_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_nm_udev_aux_libnm_udev_aux_la_LIBADD = \ +src_libnm_udev_aux_libnm_udev_aux_la_LIBADD = \ $(GLIB_LIBS) \ $(LIBUDEV_LIBS) \ $(NULL) -shared_nm_base_libnm_base_la_CPPFLAGS = \ - $(shared_nm_glib_aux_cppflags) \ +src_libnm_base_libnm_base_la_CPPFLAGS = \ + $(src_libnm_glib_aux_cppflags) \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(NULL) -shared_nm_base_libnm_base_la_SOURCES = \ - shared/nm-base/nm-base.h \ - shared/nm-base/nm-ethtool-base.c \ - shared/nm-base/nm-ethtool-base.h \ - shared/nm-base/nm-ethtool-utils-base.h \ +src_libnm_base_libnm_base_la_SOURCES = \ + src/libnm-base/nm-base.h \ + src/libnm-base/nm-config-base.h \ + src/libnm-base/nm-ethtool-base.c \ + src/libnm-base/nm-ethtool-base.h \ + src/libnm-base/nm-ethtool-utils-base.h \ + src/libnm-base/nm-net-aux.c \ + src/libnm-base/nm-net-aux.h \ $(NULL) -shared_nm_base_libnm_base_la_LDFLAGS = \ +src_libnm_base_libnm_base_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_nm_base_libnm_base_la_LIBADD = \ +src_libnm_base_libnm_base_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) -shared_nm_log_core_libnm_log_core_la_CPPFLAGS = \ +src_libnm_log_core_libnm_log_core_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(GLIB_CFLAGS) \ $(SYSTEMD_JOURNAL_CFLAGS) \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ $(NULL) -shared_nm_log_core_libnm_log_core_la_SOURCES = \ - shared/nm-log-core/nm-logging.c \ - shared/nm-log-core/nm-logging.h \ +src_libnm_log_core_libnm_log_core_la_SOURCES = \ + src/libnm-log-core/nm-logging.c \ + src/libnm-log-core/nm-logging.h \ $(NULL) -shared_nm_log_core_libnm_log_core_la_LDFLAGS = \ +src_libnm_log_core_libnm_log_core_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_nm_log_core_libnm_log_core_la_LIBADD = \ +src_libnm_log_core_libnm_log_core_la_LIBADD = \ $(GLIB_LIBS) \ $(SYSTEMD_JOURNAL_LIBS) \ $(NULL) -shared_nm_platform_libnm_platform_la_CPPFLAGS = \ - $(shared_nm_glib_aux_cppflags) \ +src_libnm_log_null_libnm_log_null_la_CPPFLAGS = \ + $(dflt_cppflags) \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + $(CODE_COVERAGE_CFLAGS) \ + $(SANITIZER_LIB_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(NULL) + +src_libnm_log_null_libnm_log_null_la_SOURCES = \ + src/libnm-log-null/nm-logging-null.c \ + $(NULL) + +src_libnm_log_null_libnm_log_null_la_LIBADD = \ + $(GLIB_LIBS) \ + $(CODE_COVERAGE_LDFLAGS) \ $(NULL) -shared_nm_platform_libnm_platform_la_SOURCES = \ - shared/nm-platform/nm-netlink.c \ - shared/nm-platform/nm-netlink.h \ - shared/nm-platform/nm-platform-utils.c \ - shared/nm-platform/nm-platform-utils.h \ - shared/nm-platform/nmp-base.h \ - shared/nm-platform/nmp-netns.c \ - shared/nm-platform/nmp-netns.h \ +src_libnm_platform_libnm_platform_la_CPPFLAGS = \ + $(src_libnm_glib_aux_cppflags) \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(NULL) -shared_nm_platform_libnm_platform_la_LDFLAGS = \ +src_libnm_platform_libnm_platform_la_SOURCES = \ + src/linux-headers/nl802154.h \ + src/libnm-platform/nm-linux-platform.c \ + src/libnm-platform/nm-linux-platform.h \ + src/libnm-platform/nm-netlink.c \ + src/libnm-platform/nm-netlink.h \ + src/libnm-platform/nm-platform-private.h \ + src/libnm-platform/nm-platform-utils.c \ + src/libnm-platform/nm-platform-utils.h \ + src/libnm-platform/nm-platform.c \ + src/libnm-platform/nm-platform.h src/libnm-platform/nmp-base.h \ + src/libnm-platform/nmp-netns.c src/libnm-platform/nmp-netns.h \ + src/libnm-platform/nmp-object.c \ + src/libnm-platform/nmp-object.h \ + src/libnm-platform/nmp-rules-manager.c \ + src/libnm-platform/nmp-rules-manager.h \ + src/libnm-platform/wifi/nm-wifi-utils-nl80211.c \ + src/libnm-platform/wifi/nm-wifi-utils-nl80211.h \ + src/libnm-platform/wifi/nm-wifi-utils-private.h \ + src/libnm-platform/wifi/nm-wifi-utils.c \ + src/libnm-platform/wifi/nm-wifi-utils.h \ + src/libnm-platform/wpan/nm-wpan-utils.c \ + src/libnm-platform/wpan/nm-wpan-utils.h $(NULL) \ + $(am__append_5) +src_libnm_platform_libnm_platform_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -shared_nm_platform_libnm_platform_la_LIBADD = \ +src_libnm_platform_libnm_platform_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) -shared_nm_platform_tests_test_nm_platform_CPPFLAGS = \ +src_libnm_platform_tests_test_nm_platform_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -DG_LOG_DOMAIN=\""test"\" \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(SYSTEMD_JOURNAL_CFLAGS) \ $(GLIB_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -shared_nm_platform_tests_test_nm_platform_LDFLAGS = \ +src_libnm_platform_tests_test_nm_platform_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -shared_nm_platform_tests_test_nm_platform_LDADD = \ - shared/nm-platform/libnm-platform.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ +src_libnm_platform_tests_test_nm_platform_LDADD = \ + src/libnm-platform/libnm-platform.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(SYSTEMD_JOURNAL_LIBS) \ $(GLIB_LIBS) \ $(NULL) -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_CPPFLAGS = \ +src_libnm_core_aux_intern_libnm_core_aux_intern_la_CPPFLAGS = \ + $(dflt_cppflags) \ + -I$(builddir)/src \ + -I$(srcdir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + $(CODE_COVERAGE_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(SANITIZER_LIB_CFLAGS) \ + $(NULL) + +src_libnm_core_aux_intern_libnm_core_aux_intern_la_SOURCES = \ + src/libnm-core-aux-intern/nm-auth-subject.c \ + src/libnm-core-aux-intern/nm-auth-subject.h \ + src/libnm-core-aux-intern/nm-common-macros.h \ + src/libnm-core-aux-intern/nm-libnm-core-utils.c \ + src/libnm-core-aux-intern/nm-libnm-core-utils.h \ + $(NULL) + +src_libnm_core_aux_intern_libnm_core_aux_intern_la_LDFLAGS = \ + $(CODE_COVERAGE_LDFLAGS) \ + $(SANITIZER_LIB_LDFLAGS) \ + $(NULL) + +src_libnm_core_aux_intern_libnm_core_aux_intern_la_LIBADD = \ + $(GLIB_LIBS) \ + $(NULL) + +src_libnm_core_aux_extern_libnm_core_aux_extern_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnm"\" \ $(NULL) -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_SOURCES = \ - libnm-core/nm-libnm-core-intern/nm-auth-subject.c \ - libnm-core/nm-libnm-core-intern/nm-auth-subject.h \ - libnm-core/nm-libnm-core-intern/nm-common-macros.h \ - libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c \ - libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.h \ +src_libnm_core_aux_extern_libnm_core_aux_extern_la_SOURCES = \ + src/libnm-core-aux-extern/nm-dispatcher-api.h \ + src/libnm-core-aux-extern/nm-libnm-core-aux.c \ + src/libnm-core-aux-extern/nm-libnm-core-aux.h \ $(NULL) -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_LDFLAGS = \ +src_libnm_core_aux_extern_libnm_core_aux_extern_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_LIBADD = \ +src_libnm_core_aux_extern_libnm_core_aux_extern_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_CPPFLAGS = \ +src_libnm_client_aux_extern_libnm_client_aux_extern_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnm"\" \ $(NULL) -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_SOURCES = \ - libnm-core/nm-libnm-core-aux/nm-dispatcher-api.h \ - libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c \ - libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.h \ +src_libnm_client_aux_extern_libnm_client_aux_extern_la_SOURCES = \ + src/libnm-client-aux-extern/nm-libnm-aux.c \ + src/libnm-client-aux-extern/nm-libnm-aux.h \ $(NULL) -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_LDFLAGS = \ +src_libnm_client_aux_extern_libnm_client_aux_extern_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_LIBADD = \ +src_libnm_client_aux_extern_libnm_client_aux_extern_la_LIBADD = \ + $(GLIB_LIBS) \ + src/libnm-client-impl/libnm.la \ + $(NULL) + +src_libnm_client_aux_extern_tests_test_libnm_client_aux_CPPFLAGS = \ + $(dflt_cppflags) \ + -I$(srcdir)/src/libnm-core-public \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + $(CODE_COVERAGE_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(SANITIZER_LIB_CFLAGS) \ + $(NULL) + +src_libnm_client_aux_extern_tests_test_libnm_client_aux_LDFLAGS = \ + $(CODE_COVERAGE_LDFLAGS) \ + $(SANITIZER_EXEC_LDFLAGS) \ + $(NULL) + +src_libnm_client_aux_extern_tests_test_libnm_client_aux_LDADD = \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(NULL) -libnm_nm_libnm_aux_libnm_libnm_aux_la_CPPFLAGS = \ +src_libnm_client_test_libnm_client_test_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnmc"\" \ $(NULL) -libnm_nm_libnm_aux_libnm_libnm_aux_la_SOURCES = \ - libnm/nm-libnm-aux/nm-libnm-aux.c \ - libnm/nm-libnm-aux/nm-libnm-aux.h \ +src_libnm_client_test_libnm_client_test_la_SOURCES = \ + src/libnm-client-test/nm-test-libnm-utils.h \ + src/libnm-client-test/nm-test-utils-impl.c \ $(NULL) -libnm_nm_libnm_aux_libnm_libnm_aux_la_LDFLAGS = \ +src_libnm_client_test_libnm_client_test_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) -libnm_nm_libnm_aux_libnm_libnm_aux_la_LIBADD = \ +src_libnm_client_test_libnm_client_test_la_LIBADD = \ $(GLIB_LIBS) \ - libnm/libnm.la \ $(NULL) -shared_nm_glib_aux_tests_test_shared_general_CPPFLAGS = \ +src_libnm_glib_aux_tests_test_shared_general_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -DG_LOG_DOMAIN=\""test"\" \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -shared_nm_glib_aux_tests_test_shared_general_LDFLAGS = \ +src_libnm_glib_aux_tests_test_shared_general_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -shared_nm_glib_aux_tests_test_shared_general_LDADD = \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/systemd/libnm-systemd-logging-stub.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ +src_libnm_glib_aux_tests_test_shared_general_LDADD = \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(NULL) -@WITH_JANSSON_TRUE@shared_nm_glib_aux_tests_test_json_aux_CPPFLAGS = \ +@WITH_JANSSON_TRUE@src_libnm_glib_aux_tests_test_json_aux_CPPFLAGS = \ @WITH_JANSSON_TRUE@ $(dflt_cppflags) \ -@WITH_JANSSON_TRUE@ -I$(srcdir)/shared \ -@WITH_JANSSON_TRUE@ -DG_LOG_DOMAIN=\""test"\" \ +@WITH_JANSSON_TRUE@ -I$(srcdir)/src \ +@WITH_JANSSON_TRUE@ -I$(builddir)/src \ @WITH_JANSSON_TRUE@ $(CODE_COVERAGE_CFLAGS) \ @WITH_JANSSON_TRUE@ $(GLIB_CFLAGS) \ @WITH_JANSSON_TRUE@ $(JANSSON_CFLAGS) \ @WITH_JANSSON_TRUE@ $(SANITIZER_LIB_CFLAGS) \ @WITH_JANSSON_TRUE@ $(NULL) -@WITH_JANSSON_TRUE@shared_nm_glib_aux_tests_test_json_aux_LDFLAGS = \ +@WITH_JANSSON_TRUE@src_libnm_glib_aux_tests_test_json_aux_LDFLAGS = \ @WITH_JANSSON_TRUE@ $(CODE_COVERAGE_LDFLAGS) \ @WITH_JANSSON_TRUE@ $(SANITIZER_EXEC_LDFLAGS) \ @WITH_JANSSON_TRUE@ $(NULL) -@WITH_JANSSON_TRUE@shared_nm_glib_aux_tests_test_json_aux_LDADD = \ +@WITH_JANSSON_TRUE@src_libnm_glib_aux_tests_test_json_aux_LDADD = \ @WITH_JANSSON_TRUE@ $(JANSSON_LIBS) \ -@WITH_JANSSON_TRUE@ shared/nm-glib-aux/libnm-glib-aux.la \ -@WITH_JANSSON_TRUE@ shared/systemd/libnm-systemd-logging-stub.la \ -@WITH_JANSSON_TRUE@ shared/nm-std-aux/libnm-std-aux.la \ -@WITH_JANSSON_TRUE@ shared/libcsiphash.la \ +@WITH_JANSSON_TRUE@ src/libnm-glib-aux/libnm-glib-aux.la \ +@WITH_JANSSON_TRUE@ src/libnm-log-null/libnm-log-null.la \ +@WITH_JANSSON_TRUE@ src/libnm-std-aux/libnm-std-aux.la \ +@WITH_JANSSON_TRUE@ src/c-siphash/libc-siphash.la \ @WITH_JANSSON_TRUE@ $(GLIB_LIBS) \ @WITH_JANSSON_TRUE@ $(NULL) @@ -5740,462 +5903,463 @@ dbusinterfaces_DATA = \ ############################################################################### -libnm_core_lib_h_pub_real = \ - libnm-core/nm-connection.h \ - libnm-core/nm-core-types.h \ - libnm-core/nm-dbus-interface.h \ - libnm-core/nm-errors.h \ - libnm-core/nm-keyfile.h \ - libnm-core/nm-setting-6lowpan.h \ - libnm-core/nm-setting-8021x.h \ - libnm-core/nm-setting-adsl.h \ - libnm-core/nm-setting-bluetooth.h \ - libnm-core/nm-setting-bond.h \ - libnm-core/nm-setting-bridge-port.h \ - libnm-core/nm-setting-bridge.h \ - libnm-core/nm-setting-cdma.h \ - libnm-core/nm-setting-connection.h \ - libnm-core/nm-setting-dcb.h \ - libnm-core/nm-setting-dummy.h \ - libnm-core/nm-setting-ethtool.h \ - libnm-core/nm-setting-generic.h \ - libnm-core/nm-setting-gsm.h \ - libnm-core/nm-setting-hostname.h \ - libnm-core/nm-setting-infiniband.h \ - libnm-core/nm-setting-ip-config.h \ - libnm-core/nm-setting-ip-tunnel.h \ - libnm-core/nm-setting-ip4-config.h \ - libnm-core/nm-setting-ip6-config.h \ - libnm-core/nm-setting-macsec.h \ - libnm-core/nm-setting-macvlan.h \ - libnm-core/nm-setting-match.h \ - libnm-core/nm-setting-olpc-mesh.h \ - libnm-core/nm-setting-ovs-bridge.h \ - libnm-core/nm-setting-ovs-dpdk.h \ - libnm-core/nm-setting-ovs-external-ids.h \ - libnm-core/nm-setting-ovs-interface.h \ - libnm-core/nm-setting-ovs-patch.h \ - libnm-core/nm-setting-ovs-port.h \ - libnm-core/nm-setting-ppp.h \ - libnm-core/nm-setting-pppoe.h \ - libnm-core/nm-setting-proxy.h \ - libnm-core/nm-setting-serial.h \ - libnm-core/nm-setting-sriov.h \ - libnm-core/nm-setting-tc-config.h \ - libnm-core/nm-setting-team-port.h \ - libnm-core/nm-setting-team.h \ - libnm-core/nm-setting-tun.h \ - libnm-core/nm-setting-user.h \ - libnm-core/nm-setting-veth.h \ - libnm-core/nm-setting-vlan.h \ - libnm-core/nm-setting-vpn.h \ - libnm-core/nm-setting-vrf.h \ - libnm-core/nm-setting-vxlan.h \ - libnm-core/nm-setting-wifi-p2p.h \ - libnm-core/nm-setting-wimax.h \ - libnm-core/nm-setting-wired.h \ - libnm-core/nm-setting-wireguard.h \ - libnm-core/nm-setting-wireless-security.h \ - libnm-core/nm-setting-wireless.h \ - libnm-core/nm-setting-wpan.h \ - libnm-core/nm-setting.h \ - libnm-core/nm-simple-connection.h \ - libnm-core/nm-utils.h \ - libnm-core/nm-version-macros.h \ - libnm-core/nm-version.h \ - libnm-core/nm-vpn-dbus-interface.h \ - libnm-core/nm-vpn-editor-plugin.h \ - libnm-core/nm-vpn-plugin-info.h \ +src_libnm_core_impl_lib_h_pub_real = \ + src/libnm-core-public/nm-connection.h \ + src/libnm-core-public/nm-core-types.h \ + src/libnm-core-public/nm-dbus-interface.h \ + src/libnm-core-public/nm-errors.h \ + src/libnm-core-public/nm-keyfile.h \ + src/libnm-core-public/nm-setting-6lowpan.h \ + src/libnm-core-public/nm-setting-8021x.h \ + src/libnm-core-public/nm-setting-adsl.h \ + src/libnm-core-public/nm-setting-bluetooth.h \ + src/libnm-core-public/nm-setting-bond.h \ + src/libnm-core-public/nm-setting-bridge-port.h \ + src/libnm-core-public/nm-setting-bridge.h \ + src/libnm-core-public/nm-setting-cdma.h \ + src/libnm-core-public/nm-setting-connection.h \ + src/libnm-core-public/nm-setting-dcb.h \ + src/libnm-core-public/nm-setting-dummy.h \ + src/libnm-core-public/nm-setting-ethtool.h \ + src/libnm-core-public/nm-setting-generic.h \ + src/libnm-core-public/nm-setting-gsm.h \ + src/libnm-core-public/nm-setting-hostname.h \ + src/libnm-core-public/nm-setting-infiniband.h \ + src/libnm-core-public/nm-setting-ip-config.h \ + src/libnm-core-public/nm-setting-ip-tunnel.h \ + src/libnm-core-public/nm-setting-ip4-config.h \ + src/libnm-core-public/nm-setting-ip6-config.h \ + src/libnm-core-public/nm-setting-macsec.h \ + src/libnm-core-public/nm-setting-macvlan.h \ + src/libnm-core-public/nm-setting-match.h \ + src/libnm-core-public/nm-setting-olpc-mesh.h \ + src/libnm-core-public/nm-setting-ovs-bridge.h \ + src/libnm-core-public/nm-setting-ovs-dpdk.h \ + src/libnm-core-public/nm-setting-ovs-external-ids.h \ + src/libnm-core-public/nm-setting-ovs-interface.h \ + src/libnm-core-public/nm-setting-ovs-patch.h \ + src/libnm-core-public/nm-setting-ovs-port.h \ + src/libnm-core-public/nm-setting-ppp.h \ + src/libnm-core-public/nm-setting-pppoe.h \ + src/libnm-core-public/nm-setting-proxy.h \ + src/libnm-core-public/nm-setting-serial.h \ + src/libnm-core-public/nm-setting-sriov.h \ + src/libnm-core-public/nm-setting-tc-config.h \ + src/libnm-core-public/nm-setting-team-port.h \ + src/libnm-core-public/nm-setting-team.h \ + src/libnm-core-public/nm-setting-tun.h \ + src/libnm-core-public/nm-setting-user.h \ + src/libnm-core-public/nm-setting-veth.h \ + src/libnm-core-public/nm-setting-vlan.h \ + src/libnm-core-public/nm-setting-vpn.h \ + src/libnm-core-public/nm-setting-vrf.h \ + src/libnm-core-public/nm-setting-vxlan.h \ + src/libnm-core-public/nm-setting-wifi-p2p.h \ + src/libnm-core-public/nm-setting-wimax.h \ + src/libnm-core-public/nm-setting-wired.h \ + src/libnm-core-public/nm-setting-wireguard.h \ + src/libnm-core-public/nm-setting-wireless-security.h \ + src/libnm-core-public/nm-setting-wireless.h \ + src/libnm-core-public/nm-setting-wpan.h \ + src/libnm-core-public/nm-setting.h \ + src/libnm-core-public/nm-simple-connection.h \ + src/libnm-core-public/nm-utils.h \ + src/libnm-core-public/nm-version-macros.h \ + src/libnm-core-public/nm-version.h \ + src/libnm-core-public/nm-vpn-dbus-interface.h \ + src/libnm-core-public/nm-vpn-editor-plugin.h \ + src/libnm-core-public/nm-vpn-plugin-info.h \ $(NULL) -libnm_core_lib_h_pub_mkenums = \ - libnm-core/nm-core-enum-types.h \ +src_libnm_core_public_mkenums_h = \ + src/libnm-core-public/nm-core-enum-types.h \ $(NULL) -libnm_core_lib_h_priv = \ - libnm-core/nm-connection-private.h \ - libnm-core/nm-core-internal.h \ - libnm-core/nm-core-types-internal.h \ - libnm-core/nm-crypto-impl.h \ - libnm-core/nm-crypto.h \ - libnm-core/nm-default-libnm-core.h \ - libnm-core/nm-keyfile-internal.h \ - libnm-core/nm-keyfile-utils.h \ - libnm-core/nm-meta-setting-base-impl.h \ - libnm-core/nm-meta-setting-base.h \ - libnm-core/nm-property-compare.h \ - libnm-core/nm-setting-private.h \ - libnm-core/nm-team-utils.h \ - libnm-core/nm-utils-private.h \ +src_libnm_core_impl_lib_h_priv = \ + src/libnm-core-impl/nm-connection-private.h \ + src/libnm-core-impl/nm-crypto-impl.h \ + src/libnm-core-impl/nm-crypto.h \ + src/libnm-core-impl/nm-default-libnm-core.h \ + src/libnm-core-impl/nm-property-compare.h \ + src/libnm-core-impl/nm-setting-private.h \ + src/libnm-core-impl/nm-team-utils.h \ + src/libnm-core-impl/nm-utils-private.h \ + src/libnm-core-intern/nm-core-internal.h \ + src/libnm-core-intern/nm-keyfile-internal.h \ + src/libnm-core-intern/nm-keyfile-utils.h \ + src/libnm-core-intern/nm-meta-setting-base-impl.h \ + src/libnm-core-intern/nm-meta-setting-base.h \ $(NULL) -libnm_core_lib_c_settings_real = \ - libnm-core/nm-setting-6lowpan.c \ - libnm-core/nm-setting-8021x.c \ - libnm-core/nm-setting-adsl.c \ - libnm-core/nm-setting-bluetooth.c \ - libnm-core/nm-setting-bond.c \ - libnm-core/nm-setting-bridge-port.c \ - libnm-core/nm-setting-bridge.c \ - libnm-core/nm-setting-cdma.c \ - libnm-core/nm-setting-connection.c \ - libnm-core/nm-setting-dcb.c \ - libnm-core/nm-setting-dummy.c \ - libnm-core/nm-setting-ethtool.c \ - libnm-core/nm-setting-generic.c \ - libnm-core/nm-setting-gsm.c \ - libnm-core/nm-setting-hostname.c \ - libnm-core/nm-setting-infiniband.c \ - libnm-core/nm-setting-ip-config.c \ - libnm-core/nm-setting-ip-tunnel.c \ - libnm-core/nm-setting-ip4-config.c \ - libnm-core/nm-setting-ip6-config.c \ - libnm-core/nm-setting-macsec.c \ - libnm-core/nm-setting-macvlan.c \ - libnm-core/nm-setting-match.c \ - libnm-core/nm-setting-olpc-mesh.c \ - libnm-core/nm-setting-ovs-bridge.c \ - libnm-core/nm-setting-ovs-dpdk.c \ - libnm-core/nm-setting-ovs-external-ids.c \ - libnm-core/nm-setting-ovs-interface.c \ - libnm-core/nm-setting-ovs-patch.c \ - libnm-core/nm-setting-ovs-port.c \ - libnm-core/nm-setting-ppp.c \ - libnm-core/nm-setting-pppoe.c \ - libnm-core/nm-setting-proxy.c \ - libnm-core/nm-setting-serial.c \ - libnm-core/nm-setting-sriov.c \ - libnm-core/nm-setting-tc-config.c \ - libnm-core/nm-setting-team-port.c \ - libnm-core/nm-setting-team.c \ - libnm-core/nm-setting-tun.c \ - libnm-core/nm-setting-user.c \ - libnm-core/nm-setting-veth.c \ - libnm-core/nm-setting-vlan.c \ - libnm-core/nm-setting-vpn.c \ - libnm-core/nm-setting-vrf.c \ - libnm-core/nm-setting-vxlan.c \ - libnm-core/nm-setting-wifi-p2p.c \ - libnm-core/nm-setting-wimax.c \ - libnm-core/nm-setting-wired.c \ - libnm-core/nm-setting-wireguard.c \ - libnm-core/nm-setting-wireless-security.c \ - libnm-core/nm-setting-wireless.c \ - libnm-core/nm-setting-wpan.c \ +src_libnm_core_impl_lib_c_settings_real = \ + src/libnm-core-impl/nm-setting-6lowpan.c \ + src/libnm-core-impl/nm-setting-8021x.c \ + src/libnm-core-impl/nm-setting-adsl.c \ + src/libnm-core-impl/nm-setting-bluetooth.c \ + src/libnm-core-impl/nm-setting-bond.c \ + src/libnm-core-impl/nm-setting-bridge-port.c \ + src/libnm-core-impl/nm-setting-bridge.c \ + src/libnm-core-impl/nm-setting-cdma.c \ + src/libnm-core-impl/nm-setting-connection.c \ + src/libnm-core-impl/nm-setting-dcb.c \ + src/libnm-core-impl/nm-setting-dummy.c \ + src/libnm-core-impl/nm-setting-ethtool.c \ + src/libnm-core-impl/nm-setting-generic.c \ + src/libnm-core-impl/nm-setting-gsm.c \ + src/libnm-core-impl/nm-setting-hostname.c \ + src/libnm-core-impl/nm-setting-infiniband.c \ + src/libnm-core-impl/nm-setting-ip-config.c \ + src/libnm-core-impl/nm-setting-ip-tunnel.c \ + src/libnm-core-impl/nm-setting-ip4-config.c \ + src/libnm-core-impl/nm-setting-ip6-config.c \ + src/libnm-core-impl/nm-setting-macsec.c \ + src/libnm-core-impl/nm-setting-macvlan.c \ + src/libnm-core-impl/nm-setting-match.c \ + src/libnm-core-impl/nm-setting-olpc-mesh.c \ + src/libnm-core-impl/nm-setting-ovs-bridge.c \ + src/libnm-core-impl/nm-setting-ovs-dpdk.c \ + src/libnm-core-impl/nm-setting-ovs-external-ids.c \ + src/libnm-core-impl/nm-setting-ovs-interface.c \ + src/libnm-core-impl/nm-setting-ovs-patch.c \ + src/libnm-core-impl/nm-setting-ovs-port.c \ + src/libnm-core-impl/nm-setting-ppp.c \ + src/libnm-core-impl/nm-setting-pppoe.c \ + src/libnm-core-impl/nm-setting-proxy.c \ + src/libnm-core-impl/nm-setting-serial.c \ + src/libnm-core-impl/nm-setting-sriov.c \ + src/libnm-core-impl/nm-setting-tc-config.c \ + src/libnm-core-impl/nm-setting-team-port.c \ + src/libnm-core-impl/nm-setting-team.c \ + src/libnm-core-impl/nm-setting-tun.c \ + src/libnm-core-impl/nm-setting-user.c \ + src/libnm-core-impl/nm-setting-veth.c \ + src/libnm-core-impl/nm-setting-vlan.c \ + src/libnm-core-impl/nm-setting-vpn.c \ + src/libnm-core-impl/nm-setting-vrf.c \ + src/libnm-core-impl/nm-setting-vxlan.c \ + src/libnm-core-impl/nm-setting-wifi-p2p.c \ + src/libnm-core-impl/nm-setting-wimax.c \ + src/libnm-core-impl/nm-setting-wired.c \ + src/libnm-core-impl/nm-setting-wireguard.c \ + src/libnm-core-impl/nm-setting-wireless-security.c \ + src/libnm-core-impl/nm-setting-wireless.c \ + src/libnm-core-impl/nm-setting-wpan.c \ $(NULL) -libnm_core_lib_c_real = \ - $(libnm_core_lib_c_settings_real) \ - libnm-core/nm-connection.c \ - libnm-core/nm-crypto.c \ - libnm-core/nm-dbus-utils.c \ - libnm-core/nm-errors.c \ - libnm-core/nm-keyfile-utils.c \ - libnm-core/nm-keyfile.c \ - libnm-core/nm-meta-setting-base-impl.c \ - libnm-core/nm-property-compare.c \ - libnm-core/nm-setting.c \ - libnm-core/nm-simple-connection.c \ - libnm-core/nm-team-utils.c \ - libnm-core/nm-utils.c \ - libnm-core/nm-vpn-editor-plugin.c \ - libnm-core/nm-vpn-plugin-info.c \ +src_libnm_core_impl_lib_c_real = \ + $(src_libnm_core_impl_lib_c_settings_real) \ + src/libnm-core-impl/nm-connection.c \ + src/libnm-core-impl/nm-crypto.c \ + src/libnm-core-impl/nm-dbus-utils.c \ + src/libnm-core-impl/nm-errors.c \ + src/libnm-core-impl/nm-keyfile-utils.c \ + src/libnm-core-impl/nm-keyfile.c \ + src/libnm-core-impl/nm-meta-setting-base-impl.c \ + src/libnm-core-impl/nm-property-compare.c \ + src/libnm-core-impl/nm-setting.c \ + src/libnm-core-impl/nm-simple-connection.c \ + src/libnm-core-impl/nm-team-utils.c \ + src/libnm-core-impl/nm-utils.c \ + src/libnm-core-impl/nm-vpn-editor-plugin.c \ + src/libnm-core-impl/nm-vpn-plugin-info.c \ $(NULL) -libnm_core_lib_c_mkenums = \ - libnm-core/nm-core-enum-types.c +src_libnm_core_public_mkenums_c = \ + src/libnm-core-public/nm-core-enum-types.c \ + $(NULL) ############################################################################### dflt_cppflags_libnm_core = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src \ $(CODE_COVERAGE_CFLAGS) \ $(GLIB_CFLAGS) \ $(LIBUDEV_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -nm_core_enum_types_sources = $(libnm_core_lib_h_pub_real) -nm_core_enum_types_MKENUMS_C_FLAGS = --identifier-prefix NM --fhead '\#include "libnm-core/nm-default-libnm-core.h"\n' -libnm_core_libnm_core_la_CPPFLAGS = \ +nm_core_enum_types_sources = $(src_libnm_core_impl_lib_h_pub_real) +nm_core_enum_types_MKENUMS_C_FLAGS = --fhead '\#undef G_LOG_DOMAIN\n\#include "src/libnm-core-impl/nm-default-libnm-core.h"\n' +src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS = \ $(dflt_cppflags_libnm_core) \ - -DG_LOG_DOMAIN=\""libnm"\" \ + -I$(srcdir)/src/libnm-core-intern/ \ $(NULL) -libnm_core_libnm_core_la_SOURCES = \ - $(libnm_core_lib_h_pub_real) \ - $(libnm_core_lib_h_priv) \ - $(libnm_core_lib_c_real) +src_libnm_core_impl_libnm_core_impl_la_SOURCES = \ + $(src_libnm_core_impl_lib_h_pub_real) \ + $(src_libnm_core_impl_lib_h_priv) \ + $(src_libnm_core_impl_lib_c_real) -nodist_libnm_core_libnm_core_la_SOURCES = \ - $(libnm_core_lib_h_pub_mkenums) \ - $(libnm_core_lib_c_mkenums) +nodist_src_libnm_core_impl_libnm_core_impl_la_SOURCES = \ + $(src_libnm_core_public_mkenums_h) \ + $(src_libnm_core_public_mkenums_c) \ + $(NULL) -libnm_core_libnm_core_la_LIBADD = \ +src_libnm_core_impl_libnm_core_impl_la_LIBADD = \ $(GLIB_LIBS) \ $(UUID_LIBS) \ $(NULL) -libnm_core_libnm_core_la_LDFLAGS = \ +src_libnm_core_impl_libnm_core_impl_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ $(NULL) ############################################################################### -@HAVE_CRYPTO_GNUTLS_TRUE@@WITH_GNUTLS_TRUE@libnm_crypto_lib = libnm-core/libnm-crypto-gnutls.la -@HAVE_CRYPTO_NSS_TRUE@@WITH_NSS_TRUE@libnm_crypto_lib = libnm-core/libnm-crypto-nss.la -@HAVE_CRYPTO_GNUTLS_TRUE@libnm_core_libnm_crypto_gnutls_la_SOURCES = libnm-core/nm-crypto-gnutls.c -@HAVE_CRYPTO_GNUTLS_TRUE@libnm_core_libnm_crypto_gnutls_la_CPPFLAGS = \ -@HAVE_CRYPTO_GNUTLS_TRUE@ $(libnm_core_libnm_core_la_CPPFLAGS) \ +@HAVE_CRYPTO_GNUTLS_TRUE@@WITH_GNUTLS_TRUE@libnm_crypto_lib = src/libnm-core-impl/libnm-crypto-gnutls.la +@HAVE_CRYPTO_NSS_TRUE@@WITH_NSS_TRUE@libnm_crypto_lib = src/libnm-core-impl/libnm-crypto-nss.la +@HAVE_CRYPTO_GNUTLS_TRUE@src_libnm_core_impl_libnm_crypto_gnutls_la_SOURCES = src/libnm-core-impl/nm-crypto-gnutls.c +@HAVE_CRYPTO_GNUTLS_TRUE@src_libnm_core_impl_libnm_crypto_gnutls_la_CPPFLAGS = \ +@HAVE_CRYPTO_GNUTLS_TRUE@ $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) \ @HAVE_CRYPTO_GNUTLS_TRUE@ $(GNUTLS_CFLAGS) -@HAVE_CRYPTO_GNUTLS_TRUE@libnm_core_libnm_crypto_gnutls_la_LDFLAGS = \ -@HAVE_CRYPTO_GNUTLS_TRUE@ $(libnm_core_libnm_core_la_LDFLAGS) +@HAVE_CRYPTO_GNUTLS_TRUE@src_libnm_core_impl_libnm_crypto_gnutls_la_LDFLAGS = \ +@HAVE_CRYPTO_GNUTLS_TRUE@ $(src_libnm_core_impl_libnm_core_impl_la_LDFLAGS) -@HAVE_CRYPTO_GNUTLS_TRUE@libnm_core_libnm_crypto_gnutls_la_LIBADD = \ +@HAVE_CRYPTO_GNUTLS_TRUE@src_libnm_core_impl_libnm_crypto_gnutls_la_LIBADD = \ @HAVE_CRYPTO_GNUTLS_TRUE@ $(GLIB_LIBS) \ @HAVE_CRYPTO_GNUTLS_TRUE@ $(GNUTLS_LIBS) -@HAVE_CRYPTO_NSS_TRUE@libnm_core_libnm_crypto_nss_la_SOURCES = libnm-core/nm-crypto-nss.c -@HAVE_CRYPTO_NSS_TRUE@libnm_core_libnm_crypto_nss_la_CPPFLAGS = \ -@HAVE_CRYPTO_NSS_TRUE@ $(libnm_core_libnm_core_la_CPPFLAGS) \ +@HAVE_CRYPTO_NSS_TRUE@src_libnm_core_impl_libnm_crypto_nss_la_SOURCES = src/libnm-core-impl/nm-crypto-nss.c +@HAVE_CRYPTO_NSS_TRUE@src_libnm_core_impl_libnm_crypto_nss_la_CPPFLAGS = \ +@HAVE_CRYPTO_NSS_TRUE@ $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) \ @HAVE_CRYPTO_NSS_TRUE@ $(NSS_CFLAGS) -@HAVE_CRYPTO_NSS_TRUE@libnm_core_libnm_crypto_nss_la_LDFLAGS = \ -@HAVE_CRYPTO_NSS_TRUE@ $(libnm_core_libnm_core_la_LDFLAGS) +@HAVE_CRYPTO_NSS_TRUE@src_libnm_core_impl_libnm_crypto_nss_la_LDFLAGS = \ +@HAVE_CRYPTO_NSS_TRUE@ $(src_libnm_core_impl_libnm_core_impl_la_LDFLAGS) -@HAVE_CRYPTO_NSS_TRUE@libnm_core_libnm_crypto_nss_la_LIBADD = \ +@HAVE_CRYPTO_NSS_TRUE@src_libnm_core_impl_libnm_crypto_nss_la_LIBADD = \ @HAVE_CRYPTO_NSS_TRUE@ $(GLIB_LIBS) \ @HAVE_CRYPTO_NSS_TRUE@ $(NSS_LIBS) -nm_core_tests_enum_types_sources = libnm-core/tests/test-general-enums.h -nm_core_tests_enum_types_MKENUMS_C_FLAGS = --fhead '\#include "libnm-core/nm-default-libnm-core.h"\n' -libnm_core_tests_cppflags = \ - -I$(srcdir)/libnm-core/tests \ - -I$(builddir)/libnm-core/tests \ +nm_core_tests_enum_types_sources = src/libnm-core-impl/tests/test-general-enums.h +nm_core_tests_enum_types_MKENUMS_C_FLAGS = --fhead '\#undef G_LOG_DOMAIN\n\#include "src/libnm-core-impl/nm-default-libnm-core.h"\n' +src_libnm_core_impl_tests_cppflags = \ + -I$(builddir)/src/libnm-core-impl/tests \ + -I$(srcdir)/src/libnm-core-impl/tests \ + -I$(srcdir)/src/libnm-core-impl \ + -I$(srcdir)/src/ \ + -I$(builddir)/src/ \ $(dflt_cppflags_libnm_core) \ - -DG_LOG_DOMAIN=\""test"\" \ $(SANITIZER_EXEC_CFLAGS) \ $(NULL) -libnm_core_tests_test_compare_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_crypto_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_general_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_keyfile_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_secrets_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_setting_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_settings_defaults_CPPFLAGS = $(libnm_core_tests_cppflags) -libnm_core_tests_test_general_SOURCES = \ - libnm-core/tests/test-general-enums.h \ - libnm-core/tests/test-general.c \ +src_libnm_core_impl_tests_test_compare_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_crypto_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_general_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_keyfile_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_secrets_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_setting_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_settings_defaults_CPPFLAGS = $(src_libnm_core_impl_tests_cppflags) +src_libnm_core_impl_tests_test_general_SOURCES = \ + src/libnm-core-impl/tests/test-general-enums.h \ + src/libnm-core-impl/tests/test-general.c \ $(NULL) -nodist_libnm_core_tests_test_general_SOURCES = \ - libnm-core/tests/nm-core-tests-enum-types.c \ - libnm-core/tests/nm-core-tests-enum-types.h \ +nodist_src_libnm_core_impl_tests_test_general_SOURCES = \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.c \ + src/libnm-core-impl/tests/nm-core-tests-enum-types.h \ $(NULL) -libnm_core_tests_ldadd = \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la \ +src_libnm_core_impl_tests_ldadd = \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la \ $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/systemd/libnm-systemd-logging-stub.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(NULL) -libnm_core_tests_ldflags = \ +src_libnm_core_impl_tests_ldflags = \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -libnm_core_tests_test_compare_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_crypto_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_general_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_keyfile_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_secrets_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_setting_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_settings_defaults_LDADD = $(libnm_core_tests_ldadd) -libnm_core_tests_test_compare_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_crypto_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_general_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_keyfile_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_secrets_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_setting_LDFLAGS = $(libnm_core_tests_ldflags) -libnm_core_tests_test_settings_defaults_LDFLAGS = $(libnm_core_tests_ldflags) +src_libnm_core_impl_tests_test_compare_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_crypto_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_general_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_keyfile_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_secrets_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_setting_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_settings_defaults_LDADD = $(src_libnm_core_impl_tests_ldadd) +src_libnm_core_impl_tests_test_compare_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_crypto_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_general_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_keyfile_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_secrets_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_setting_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) +src_libnm_core_impl_tests_test_settings_defaults_LDFLAGS = $(src_libnm_core_impl_tests_ldflags) ############################################################################### libnm_lib_h_pub_real = \ - libnm/NetworkManager.h \ - libnm/nm-access-point.h \ - libnm/nm-active-connection.h \ - libnm/nm-autoptr.h \ - libnm/nm-checkpoint.h \ - libnm/nm-client.h \ - libnm/nm-device-6lowpan.h \ - libnm/nm-device-adsl.h \ - libnm/nm-device-bond.h \ - libnm/nm-device-bridge.h \ - libnm/nm-device-bt.h \ - libnm/nm-device-dummy.h \ - libnm/nm-device-ethernet.h \ - libnm/nm-device-generic.h \ - libnm/nm-device-infiniband.h \ - libnm/nm-device-ip-tunnel.h \ - libnm/nm-device-macsec.h \ - libnm/nm-device-macvlan.h \ - libnm/nm-device-modem.h \ - libnm/nm-device-olpc-mesh.h \ - libnm/nm-device-ovs-bridge.h \ - libnm/nm-device-ovs-interface.h \ - libnm/nm-device-ovs-port.h \ - libnm/nm-device-ppp.h \ - libnm/nm-device-team.h \ - libnm/nm-device-tun.h \ - libnm/nm-device-veth.h \ - libnm/nm-device-vlan.h \ - libnm/nm-device-vrf.h \ - libnm/nm-device-vxlan.h \ - libnm/nm-device-wifi-p2p.h \ - libnm/nm-device-wifi.h \ - libnm/nm-device-wimax.h \ - libnm/nm-device-wireguard.h \ - libnm/nm-device-wpan.h \ - libnm/nm-device.h \ - libnm/nm-dhcp-config.h \ - libnm/nm-ethtool-utils.h \ - libnm/nm-ip-config.h \ - libnm/nm-object.h \ - libnm/nm-remote-connection.h \ - libnm/nm-secret-agent-old.h \ - libnm/nm-types.h \ - libnm/nm-vpn-connection.h \ - libnm/nm-vpn-editor.h \ - libnm/nm-vpn-plugin-old.h \ - libnm/nm-vpn-service-plugin.h \ - libnm/nm-wifi-p2p-peer.h \ - libnm/nm-wimax-nsp.h - -libnm_lib_h_pub_mkenums = \ - libnm/nm-enum-types.h + src/libnm-client-public/NetworkManager.h \ + src/libnm-client-public/nm-access-point.h \ + src/libnm-client-public/nm-active-connection.h \ + src/libnm-client-public/nm-autoptr.h \ + src/libnm-client-public/nm-checkpoint.h \ + src/libnm-client-public/nm-client.h \ + src/libnm-client-public/nm-device-6lowpan.h \ + src/libnm-client-public/nm-device-adsl.h \ + src/libnm-client-public/nm-device-bond.h \ + src/libnm-client-public/nm-device-bridge.h \ + src/libnm-client-public/nm-device-bt.h \ + src/libnm-client-public/nm-device-dummy.h \ + src/libnm-client-public/nm-device-ethernet.h \ + src/libnm-client-public/nm-device-generic.h \ + src/libnm-client-public/nm-device-infiniband.h \ + src/libnm-client-public/nm-device-ip-tunnel.h \ + src/libnm-client-public/nm-device-macsec.h \ + src/libnm-client-public/nm-device-macvlan.h \ + src/libnm-client-public/nm-device-modem.h \ + src/libnm-client-public/nm-device-olpc-mesh.h \ + src/libnm-client-public/nm-device-ovs-bridge.h \ + src/libnm-client-public/nm-device-ovs-interface.h \ + src/libnm-client-public/nm-device-ovs-port.h \ + src/libnm-client-public/nm-device-ppp.h \ + src/libnm-client-public/nm-device-team.h \ + src/libnm-client-public/nm-device-tun.h \ + src/libnm-client-public/nm-device-veth.h \ + src/libnm-client-public/nm-device-vlan.h \ + src/libnm-client-public/nm-device-vrf.h \ + src/libnm-client-public/nm-device-vxlan.h \ + src/libnm-client-public/nm-device-wifi-p2p.h \ + src/libnm-client-public/nm-device-wifi.h \ + src/libnm-client-public/nm-device-wimax.h \ + src/libnm-client-public/nm-device-wireguard.h \ + src/libnm-client-public/nm-device-wpan.h \ + src/libnm-client-public/nm-device.h \ + src/libnm-client-public/nm-dhcp-config.h \ + src/libnm-client-public/nm-ethtool-utils.h \ + src/libnm-client-public/nm-ip-config.h \ + src/libnm-client-public/nm-object.h \ + src/libnm-client-public/nm-remote-connection.h \ + src/libnm-client-public/nm-secret-agent-old.h \ + src/libnm-client-public/nm-types.h \ + src/libnm-client-public/nm-vpn-connection.h \ + src/libnm-client-public/nm-vpn-editor.h \ + src/libnm-client-public/nm-vpn-plugin-old.h \ + src/libnm-client-public/nm-vpn-service-plugin.h \ + src/libnm-client-public/nm-wifi-p2p-peer.h \ + src/libnm-client-public/nm-wimax-nsp.h \ + $(NULL) + +src_libnm_client_public_mkenums_h = \ + src/libnm-client-public/nm-enum-types.h \ + $(NULL) libnm_lib_h_priv = \ - libnm/nm-dbus-helpers.h \ - libnm/nm-default-client.h \ - libnm/nm-default-libnm.h \ - libnm/nm-device-private.h \ - libnm/nm-dhcp4-config.h \ - libnm/nm-dhcp6-config.h \ - libnm/nm-dns-manager.h \ - libnm/nm-ip4-config.h \ - libnm/nm-ip6-config.h \ - libnm/nm-libnm-utils.h \ - libnm/nm-object-private.h \ - libnm/nm-remote-connection-private.h \ + src/libnm-client-impl/nm-dbus-helpers.h \ + src/libnm-client-aux-extern/nm-default-client.h \ + src/libnm-client-impl/nm-default-libnm.h \ + src/libnm-client-impl/nm-device-private.h \ + src/libnm-client-impl/nm-dhcp4-config.h \ + src/libnm-client-impl/nm-dhcp6-config.h \ + src/libnm-client-impl/nm-dns-manager.h \ + src/libnm-client-impl/nm-ip4-config.h \ + src/libnm-client-impl/nm-ip6-config.h \ + src/libnm-client-impl/nm-libnm-utils.h \ + src/libnm-client-impl/nm-object-private.h \ + src/libnm-client-impl/nm-remote-connection-private.h \ $(NULL) libnm_lib_c_real = \ - libnm/nm-client.c \ - libnm/nm-object.c \ - libnm/nm-device.c \ - libnm/nm-active-connection.c \ + src/libnm-client-impl/nm-client.c \ + src/libnm-client-impl/nm-object.c \ + src/libnm-client-impl/nm-device.c \ + src/libnm-client-impl/nm-active-connection.c \ \ - libnm/nm-access-point.c \ - libnm/nm-checkpoint.c \ - libnm/nm-dbus-helpers.c \ - libnm/nm-device-6lowpan.c \ - libnm/nm-device-adsl.c \ - libnm/nm-device-bond.c \ - libnm/nm-device-bridge.c \ - libnm/nm-device-bt.c \ - libnm/nm-device-dummy.c \ - libnm/nm-device-ethernet.c \ - libnm/nm-device-generic.c \ - libnm/nm-device-infiniband.c \ - libnm/nm-device-ip-tunnel.c \ - libnm/nm-device-macsec.c \ - libnm/nm-device-macvlan.c \ - libnm/nm-device-modem.c \ - libnm/nm-device-olpc-mesh.c \ - libnm/nm-device-ovs-bridge.c \ - libnm/nm-device-ovs-interface.c \ - libnm/nm-device-ovs-port.c \ - libnm/nm-device-ppp.c \ - libnm/nm-device-team.c \ - libnm/nm-device-tun.c \ - libnm/nm-device-veth.c \ - libnm/nm-device-vlan.c \ - libnm/nm-device-vrf.c \ - libnm/nm-device-vxlan.c \ - libnm/nm-device-wifi-p2p.c \ - libnm/nm-device-wifi.c \ - libnm/nm-device-wimax.c \ - libnm/nm-device-wireguard.c \ - libnm/nm-device-wpan.c \ - libnm/nm-dhcp-config.c \ - libnm/nm-dhcp4-config.c \ - libnm/nm-dhcp6-config.c \ - libnm/nm-dns-manager.c \ - libnm/nm-ip-config.c \ - libnm/nm-ip4-config.c \ - libnm/nm-ip6-config.c \ - libnm/nm-libnm-utils.c \ - libnm/nm-remote-connection.c \ - libnm/nm-secret-agent-old.c \ - libnm/nm-vpn-connection.c \ - libnm/nm-vpn-editor.c \ - libnm/nm-vpn-plugin-old.c \ - libnm/nm-vpn-service-plugin.c \ - libnm/nm-wifi-p2p-peer.c \ - libnm/nm-wimax-nsp.c \ + src/libnm-client-impl/nm-access-point.c \ + src/libnm-client-impl/nm-checkpoint.c \ + src/libnm-client-impl/nm-dbus-helpers.c \ + src/libnm-client-impl/nm-device-6lowpan.c \ + src/libnm-client-impl/nm-device-adsl.c \ + src/libnm-client-impl/nm-device-bond.c \ + src/libnm-client-impl/nm-device-bridge.c \ + src/libnm-client-impl/nm-device-bt.c \ + src/libnm-client-impl/nm-device-dummy.c \ + src/libnm-client-impl/nm-device-ethernet.c \ + src/libnm-client-impl/nm-device-generic.c \ + src/libnm-client-impl/nm-device-infiniband.c \ + src/libnm-client-impl/nm-device-ip-tunnel.c \ + src/libnm-client-impl/nm-device-macsec.c \ + src/libnm-client-impl/nm-device-macvlan.c \ + src/libnm-client-impl/nm-device-modem.c \ + src/libnm-client-impl/nm-device-olpc-mesh.c \ + src/libnm-client-impl/nm-device-ovs-bridge.c \ + src/libnm-client-impl/nm-device-ovs-interface.c \ + src/libnm-client-impl/nm-device-ovs-port.c \ + src/libnm-client-impl/nm-device-ppp.c \ + src/libnm-client-impl/nm-device-team.c \ + src/libnm-client-impl/nm-device-tun.c \ + src/libnm-client-impl/nm-device-veth.c \ + src/libnm-client-impl/nm-device-vlan.c \ + src/libnm-client-impl/nm-device-vrf.c \ + src/libnm-client-impl/nm-device-vxlan.c \ + src/libnm-client-impl/nm-device-wifi-p2p.c \ + src/libnm-client-impl/nm-device-wifi.c \ + src/libnm-client-impl/nm-device-wimax.c \ + src/libnm-client-impl/nm-device-wireguard.c \ + src/libnm-client-impl/nm-device-wpan.c \ + src/libnm-client-impl/nm-dhcp-config.c \ + src/libnm-client-impl/nm-dhcp4-config.c \ + src/libnm-client-impl/nm-dhcp6-config.c \ + src/libnm-client-impl/nm-dns-manager.c \ + src/libnm-client-impl/nm-ip-config.c \ + src/libnm-client-impl/nm-ip4-config.c \ + src/libnm-client-impl/nm-ip6-config.c \ + src/libnm-client-impl/nm-libnm-utils.c \ + src/libnm-client-impl/nm-remote-connection.c \ + src/libnm-client-impl/nm-secret-agent-old.c \ + src/libnm-client-impl/nm-vpn-connection.c \ + src/libnm-client-impl/nm-vpn-editor.c \ + src/libnm-client-impl/nm-vpn-plugin-old.c \ + src/libnm-client-impl/nm-vpn-service-plugin.c \ + src/libnm-client-impl/nm-wifi-p2p-peer.c \ + src/libnm-client-impl/nm-wimax-nsp.c \ $(NULL) -libnm_lib_c_mkenums = \ - libnm/nm-enum-types.c - -libnm_lib_cppflags = \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ - $(dflt_cppflags_libnm_core) \ - -DG_LOG_DOMAIN=\""libnm"\" \ +src_libnm_client_public_mkenums_c = \ + src/libnm-client-public/nm-enum-types.c \ $(NULL) -libnm_libnm_static_la_CPPFLAGS = \ +src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS = \ + -I$(builddir)/src/libnm-client-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(srcdir)/src \ + $(dflt_cppflags_libnm_core) \ $(INTROSPECTION_CFLAGS) \ - $(libnm_lib_cppflags) \ $(NULL) -libnm_libnm_static_la_SOURCES = \ +src_libnm_client_impl_libnm_client_impl_la_SOURCES = \ $(libnm_lib_c_real) \ $(NULL) -nodist_libnm_libnm_static_la_SOURCES = \ - $(libnm_lib_h_pub_mkenums) \ - $(libnm_lib_c_mkenums) \ +nodist_src_libnm_client_impl_libnm_client_impl_la_SOURCES = \ + $(src_libnm_client_public_mkenums_h) \ + $(src_libnm_client_public_mkenums_c) \ $(NULL) -libnm_libnm_static_la_LIBADD = \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la \ +src_libnm_client_impl_libnm_client_impl_la_LIBADD = \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la \ $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ introspection/libnmdbus.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/systemd/libnm-systemd-logging-stub.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/libnm-log-null/libnm-log-null.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(DL_LIBS) \ $(UUID_LIBS) \ @@ -6203,140 +6367,129 @@ libnm_libnm_static_la_LIBADD = \ $(NULL) nm_enum_types_sources = \ - $(libnm_lib_h_pub_mkenums) \ + $(src_libnm_client_public_mkenums_h) \ $(libnm_lib_h_pub_real) -nm_enum_types_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include "nm-core-enum-types.h"\n' -nm_enum_types_MKENUMS_C_FLAGS = --identifier-prefix NM --fhead '\#include "libnm/nm-default-libnm.h"\n' -libnm_libnm_la_CPPFLAGS = \ - $(libnm_lib_cppflags) \ +nm_enum_types_MKENUMS_H_FLAGS = --fhead '\#include "nm-core-enum-types.h"\n' +nm_enum_types_MKENUMS_C_FLAGS = --fhead '\#undef G_LOG_DOMAIN\n\#include "libnm-client-impl/nm-default-libnm.h"\n' +src_libnm_client_impl_libnm_la_CPPFLAGS = \ + -I$(builddir)/src/libnm-client-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(srcdir)/src \ + $(dflt_cppflags_libnm_core) \ $(LIBUDEV_CFLAGS) \ $(SANITIZER_LIB_CFLAGS) \ $(NULL) -libnm_libnm_la_SOURCES = \ +src_libnm_client_impl_libnm_la_SOURCES = \ $(libnm_lib_h_pub_real) \ $(libnm_lib_h_priv) \ $(NULL) -EXTRA_libnm_libnm_la_DEPENDENCIES = \ - libnm/libnm.ver +EXTRA_src_libnm_client_impl_libnm_la_DEPENDENCIES = \ + src/libnm-client-impl/libnm.ver -libnm_libnm_la_LIBADD = \ - libnm/libnm_static.la \ +src_libnm_client_impl_libnm_la_LIBADD = \ + src/libnm-client-impl/libnm-client-impl.la \ $(NULL) -libnm_libnm_la_LDFLAGS = \ - -Wl,--version-script="$(srcdir)/libnm/libnm.ver" \ +src_libnm_client_impl_libnm_la_LDFLAGS = \ + -Wl,--version-script="$(srcdir)/src/libnm-client-impl/libnm.ver" \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_LIB_LDFLAGS) \ -version-info "1:0:1" -libnm_NM_1_0_typelib = $(am__append_8) -@HAVE_INTROSPECTION_TRUE@libnm_NM_1_0_gir_INCLUDES = Gio-2.0 -@HAVE_INTROSPECTION_TRUE@libnm_NM_1_0_gir_PACKAGES = gio-2.0 -@HAVE_INTROSPECTION_TRUE@libnm_NM_1_0_gir_EXPORT_PACKAGES = libnm -@HAVE_INTROSPECTION_TRUE@libnm_NM_1_0_gir_CFLAGS = \ -@HAVE_INTROSPECTION_TRUE@ $(libnm_libnm_la_CPPFLAGS) \ +src_libnm_client_impl_NM_1_0_typelib = $(am__append_9) +@HAVE_INTROSPECTION_TRUE@src_libnm_client_impl_NM_1_0_gir_INCLUDES = Gio-2.0 +@HAVE_INTROSPECTION_TRUE@src_libnm_client_impl_NM_1_0_gir_PACKAGES = gio-2.0 +@HAVE_INTROSPECTION_TRUE@src_libnm_client_impl_NM_1_0_gir_EXPORT_PACKAGES = libnm +@HAVE_INTROSPECTION_TRUE@src_libnm_client_impl_NM_1_0_gir_CFLAGS = \ +@HAVE_INTROSPECTION_TRUE@ $(src_libnm_client_impl_libnm_la_CPPFLAGS) \ @HAVE_INTROSPECTION_TRUE@ -DNETWORKMANAGER_COMPILATION \ @HAVE_INTROSPECTION_TRUE@ $(NULL) -@HAVE_INTROSPECTION_TRUE@libnm_NM_1_0_gir_LIBS = libnm/libnm.la -@HAVE_INTROSPECTION_TRUE@libnm_NM_1_0_gir_FILES = \ -@HAVE_INTROSPECTION_TRUE@ $(libnm_core_lib_h_pub_mkenums) \ -@HAVE_INTROSPECTION_TRUE@ $(libnm_core_lib_h_pub_real) \ -@HAVE_INTROSPECTION_TRUE@ $(libnm_core_lib_c_mkenums) \ -@HAVE_INTROSPECTION_TRUE@ $(libnm_core_lib_c_real) \ -@HAVE_INTROSPECTION_TRUE@ $(libnm_lib_h_pub_mkenums) \ +@HAVE_INTROSPECTION_TRUE@src_libnm_client_impl_NM_1_0_gir_LIBS = src/libnm-client-impl/libnm.la +@HAVE_INTROSPECTION_TRUE@src_libnm_client_impl_NM_1_0_gir_FILES = \ +@HAVE_INTROSPECTION_TRUE@ $(src_libnm_core_public_mkenums_h) \ +@HAVE_INTROSPECTION_TRUE@ $(src_libnm_core_impl_lib_h_pub_real) \ +@HAVE_INTROSPECTION_TRUE@ $(src_libnm_core_public_mkenums_c) \ +@HAVE_INTROSPECTION_TRUE@ $(src_libnm_core_impl_lib_c_real) \ +@HAVE_INTROSPECTION_TRUE@ $(src_libnm_client_public_mkenums_h) \ @HAVE_INTROSPECTION_TRUE@ $(libnm_lib_h_pub_real) \ -@HAVE_INTROSPECTION_TRUE@ $(libnm_lib_c_mkenums) \ +@HAVE_INTROSPECTION_TRUE@ $(src_libnm_client_public_mkenums_c) \ @HAVE_INTROSPECTION_TRUE@ $(libnm_lib_c_real) -@HAVE_INTROSPECTION_TRUE@libnm_NM_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm +@HAVE_INTROSPECTION_TRUE@src_libnm_client_impl_NM_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm @HAVE_INTROSPECTION_TRUE@libnm_noinst_data = \ -@HAVE_INTROSPECTION_TRUE@ clients/cli/generate-docs-nm-settings-nmcli.xml \ -@HAVE_INTROSPECTION_TRUE@ libnm/nm-property-infos-dbus.xml \ -@HAVE_INTROSPECTION_TRUE@ libnm/nm-property-infos-ifcfg-rh.xml \ -@HAVE_INTROSPECTION_TRUE@ libnm/nm-property-infos-keyfile.xml \ -@HAVE_INTROSPECTION_TRUE@ libnm/nm-property-infos-nmcli.xml \ -@HAVE_INTROSPECTION_TRUE@ libnm/nm-settings-docs-gir.xml \ +@HAVE_INTROSPECTION_TRUE@ src/nmcli/generate-docs-nm-settings-nmcli.xml \ @HAVE_INTROSPECTION_TRUE@ man/nm-settings-docs-dbus.xml \ @HAVE_INTROSPECTION_TRUE@ man/nm-settings-docs-nmcli.xml \ +@HAVE_INTROSPECTION_TRUE@ src/libnm-client-impl/nm-property-infos-dbus.xml \ +@HAVE_INTROSPECTION_TRUE@ src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml \ +@HAVE_INTROSPECTION_TRUE@ src/libnm-client-impl/nm-property-infos-keyfile.xml \ +@HAVE_INTROSPECTION_TRUE@ src/libnm-client-impl/nm-property-infos-nmcli.xml \ +@HAVE_INTROSPECTION_TRUE@ src/libnm-client-impl/nm-settings-docs-gir.xml \ +@HAVE_INTROSPECTION_TRUE@ src/libnmc-setting/settings-docs-input.xml \ @HAVE_INTROSPECTION_TRUE@ $(NULL) -@HAVE_INTROSPECTION_TRUE@libnm_docs_sources = $(libnm_core_lib_c_settings_real) -libnm_tests_programs_req_introspection = \ - libnm/tests/test-nm-client \ - libnm/tests/test-remote-settings-client \ - libnm/tests/test-secret-agent +@HAVE_INTROSPECTION_TRUE@libnm_docs_sources = $(src_libnm_core_impl_lib_c_settings_real) +src_libnm_client_impl_tests_programs_req_introspection = \ + src/libnm-client-impl/tests/test-nm-client \ + src/libnm-client-impl/tests/test-remote-settings-client \ + src/libnm-client-impl/tests/test-secret-agent -libnm_tests_cppflags = \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ +src_libnm_client_impl_tests_cppflags = \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(dflt_cppflags_libnm_core) \ - -DG_LOG_DOMAIN=\""test"\" \ $(SANITIZER_EXEC_CFLAGS) \ $(NULL) -libnm_tests_ldadd = \ - libnm/libnm_static.la \ +src_libnm_client_impl_tests_ldadd = \ + src/libnm-client-test/libnm-client-test.la \ + src/libnm-client-impl/libnm-client-impl.la \ $(GLIB_LIBS) \ $(NULL) -libnm_tests_ldflags = \ +src_libnm_client_impl_tests_ldflags = \ $(SANITIZER_EXEC_LDFLAGS) -libnm_tests_test_libnm_CPPFLAGS = $(libnm_tests_cppflags) -libnm_tests_test_nm_client_CPPFLAGS = $(libnm_tests_cppflags) -libnm_tests_test_remote_settings_client_CPPFLAGS = $(libnm_tests_cppflags) -libnm_tests_test_secret_agent_CPPFLAGS = $(libnm_tests_cppflags) -libnm_tests_test_libnm_SOURCES = \ - shared/nm-utils/nm-compat.c \ - libnm/tests/test-libnm.c \ +src_libnm_client_impl_tests_test_libnm_CPPFLAGS = $(src_libnm_client_impl_tests_cppflags) +src_libnm_client_impl_tests_test_nm_client_CPPFLAGS = $(src_libnm_client_impl_tests_cppflags) +src_libnm_client_impl_tests_test_remote_settings_client_CPPFLAGS = $(src_libnm_client_impl_tests_cppflags) +src_libnm_client_impl_tests_test_secret_agent_CPPFLAGS = $(src_libnm_client_impl_tests_cppflags) +src_libnm_client_impl_tests_test_libnm_SOURCES = \ + src/contrib/nm-compat.c \ + src/contrib/nm-compat.h \ + src/libnm-client-impl/tests/test-libnm.c \ $(NULL) -libnm_tests_test_nm_client_SOURCES = \ - shared/nm-test-utils-impl.c \ - shared/nm-test-libnm-utils.h \ - libnm/tests/test-nm-client.c - -libnm_tests_test_remote_settings_client_SOURCES = \ - shared/nm-test-utils-impl.c \ - shared/nm-test-libnm-utils.h \ - libnm/tests/test-remote-settings-client.c - -libnm_tests_test_secret_agent_SOURCES = \ - shared/nm-test-utils-impl.c \ - shared/nm-test-libnm-utils.h \ - libnm/tests/test-secret-agent.c - -libnm_tests_test_libnm_LDADD = $(libnm_tests_ldadd) -libnm_tests_test_nm_client_LDADD = $(libnm_tests_ldadd) -libnm_tests_test_remote_settings_client_LDADD = $(libnm_tests_ldadd) -libnm_tests_test_secret_agent_LDADD = $(libnm_tests_ldadd) -libnm_tests_test_libnm_LDFLAGS = $(libnm_tests_ldflags) -libnm_tests_test_nm_client_LDFLAGS = $(libnm_tests_ldflags) -libnm_tests_test_remote_settings_client_LDFLAGS = $(libnm_tests_ldflags) -libnm_tests_test_secret_agent_LDFLAGS = $(libnm_tests_ldflags) -libnm_tests_libnm_vpn_plugin_utils_test_la_SOURCES = \ - shared/nm-utils/nm-vpn-plugin-utils.c \ - shared/nm-utils/nm-vpn-plugin-utils.h \ +src_libnm_client_impl_tests_test_libnm_LDADD = $(src_libnm_client_impl_tests_ldadd) +src_libnm_client_impl_tests_test_nm_client_LDADD = $(src_libnm_client_impl_tests_ldadd) +src_libnm_client_impl_tests_test_remote_settings_client_LDADD = $(src_libnm_client_impl_tests_ldadd) +src_libnm_client_impl_tests_test_secret_agent_LDADD = $(src_libnm_client_impl_tests_ldadd) +src_libnm_client_impl_tests_test_libnm_LDFLAGS = $(src_libnm_client_impl_tests_ldflags) +src_libnm_client_impl_tests_test_nm_client_LDFLAGS = $(src_libnm_client_impl_tests_ldflags) +src_libnm_client_impl_tests_test_remote_settings_client_LDFLAGS = $(src_libnm_client_impl_tests_ldflags) +src_libnm_client_impl_tests_test_secret_agent_LDFLAGS = $(src_libnm_client_impl_tests_ldflags) +src_contrib_tests_libnm_vpn_plugin_utils_test_la_SOURCES = \ + src/contrib/nm-vpn-plugin-utils.c \ + src/contrib/nm-vpn-plugin-utils.h \ $(NULL) -libnm_tests_libnm_vpn_plugin_utils_test_la_CFLAGS = \ +src_contrib_tests_libnm_vpn_plugin_utils_test_la_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(GLIB_CFLAGS) \ $(SANITIZER_EXEC_CFLAGS) \ - -DG_LOG_DOMAIN=\""test"\" \ $(NULL) -libnm_tests_libnm_vpn_plugin_utils_test_la_LIBADD = \ +src_contrib_tests_libnm_vpn_plugin_utils_test_la_LIBADD = \ $(GLIB_LIBS) \ $(NULL) @@ -6347,7 +6500,6 @@ libnm_tests_libnm_vpn_plugin_utils_test_la_LIBADD = \ src_core_cppflags_base = \ -I$(srcdir)/src/core \ $(dflt_cppflags_libnm_core) \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ $(SANITIZER_EXEC_CFLAGS) \ $(NULL) @@ -6371,173 +6523,158 @@ src_core_cppflags = \ \ $(NULL) -src_core_cppflags_test = $(src_core_cppflags) $(NULL) $(am__append_17) +src_core_cppflags_test = $(src_core_cppflags) $(NULL) $(am__append_18) src_core_ldflags = $(CODE_COVERAGE_LDFLAGS) ############################################################################### libsystemd_cppflags = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/shared/systemd/ \ - -I$(srcdir)/shared/systemd/sd-adapt-shared \ - -I$(srcdir)/shared/systemd/src/basic \ - -I$(srcdir)/shared/systemd/src/shared \ + -I$(srcdir)/src/ \ + -I$(builddir)/src/ \ + -I$(srcdir)/src/libnm-systemd-shared/ \ + -I$(srcdir)/src/libnm-systemd-shared/sd-adapt-shared \ + -I$(srcdir)/src/libnm-systemd-shared/src/basic \ + -I$(srcdir)/src/libnm-systemd-shared/src/shared \ $(LIBSYSTEMD_NM_CFLAGS) \ $(GLIB_CFLAGS) \ $(CODE_COVERAGE_CFLAGS) \ $(NULL) -shared_systemd_libnm_systemd_logging_stub_la_CPPFLAGS = \ - $(libsystemd_cppflags) \ - -DG_LOG_DOMAIN=\""libnm"\" \ - $(NULL) - -shared_systemd_libnm_systemd_logging_stub_la_SOURCES = \ - shared/systemd/nm-logging-stub.c \ - $(NULL) - -shared_systemd_libnm_systemd_logging_stub_la_LIBADD = \ - $(GLIB_LIBS) \ - $(CODE_COVERAGE_LDFLAGS) \ - $(NULL) - -shared_systemd_libnm_systemd_shared_la_CPPFLAGS = \ +src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS = \ $(libsystemd_cppflags) \ - -DG_LOG_DOMAIN=\""libnm"\" \ $(NULL) -shared_systemd_libnm_systemd_shared_la_SOURCES = \ - shared/systemd/nm-default-systemd-shared.h \ - shared/systemd/nm-sd-utils-shared.c \ - shared/systemd/nm-sd-utils-shared.h \ - shared/systemd/sd-adapt-shared/architecture.h \ - shared/systemd/sd-adapt-shared/arphrd-list.h \ - shared/systemd/sd-adapt-shared/blockdev-util.h \ - shared/systemd/sd-adapt-shared/build.h \ - shared/systemd/sd-adapt-shared/copy.h \ - shared/systemd/sd-adapt-shared/def.h \ - shared/systemd/sd-adapt-shared/dhcp-server-internal.h \ - shared/systemd/sd-adapt-shared/dirent-util.h \ - shared/systemd/sd-adapt-shared/errno-list.h \ - shared/systemd/sd-adapt-shared/glob-util.h \ - shared/systemd/sd-adapt-shared/gunicode.h \ - shared/systemd/sd-adapt-shared/idn-util.h \ - shared/systemd/sd-adapt-shared/ioprio.h \ - shared/systemd/sd-adapt-shared/locale-util.h \ - shared/systemd/sd-adapt-shared/memfd-util.h \ - shared/systemd/sd-adapt-shared/missing_fs.h \ - shared/systemd/sd-adapt-shared/missing_keyctl.h \ - shared/systemd/sd-adapt-shared/missing_magic.h \ - shared/systemd/sd-adapt-shared/missing_network.h \ - shared/systemd/sd-adapt-shared/missing_sched.h \ - shared/systemd/sd-adapt-shared/missing_timerfd.h \ - shared/systemd/sd-adapt-shared/mkdir.h \ - shared/systemd/sd-adapt-shared/namespace-util.h \ - shared/systemd/sd-adapt-shared/nm-sd-adapt-shared.h \ - shared/systemd/sd-adapt-shared/nulstr-util.h \ - shared/systemd/sd-adapt-shared/raw-clone.h \ - shared/systemd/sd-adapt-shared/rlimit-util.h \ - shared/systemd/sd-adapt-shared/terminal-util.h \ - shared/systemd/sd-adapt-shared/unaligned.h \ - shared/systemd/sd-adapt-shared/user-util.h \ - shared/systemd/sd-adapt-shared/virt.h \ - shared/systemd/src/basic/alloc-util.c \ - shared/systemd/src/basic/alloc-util.h \ - shared/systemd/src/basic/async.h \ - shared/systemd/src/basic/cgroup-util.h \ - shared/systemd/src/basic/env-file.c \ - shared/systemd/src/basic/env-file.h \ - shared/systemd/src/basic/env-util.c \ - shared/systemd/src/basic/env-util.h \ - shared/systemd/src/basic/errno-util.h \ - shared/systemd/src/basic/escape.c \ - shared/systemd/src/basic/escape.h \ - shared/systemd/src/basic/ether-addr-util.c \ - shared/systemd/src/basic/ether-addr-util.h \ - shared/systemd/src/basic/extract-word.c \ - shared/systemd/src/basic/extract-word.h \ - shared/systemd/src/basic/fd-util.c \ - shared/systemd/src/basic/fd-util.h \ - shared/systemd/src/basic/fileio.c \ - shared/systemd/src/basic/fileio.h \ - shared/systemd/src/basic/format-util.c \ - shared/systemd/src/basic/format-util.h \ - shared/systemd/src/basic/fs-util.c \ - shared/systemd/src/basic/fs-util.h \ - shared/systemd/src/basic/hash-funcs.c \ - shared/systemd/src/basic/hash-funcs.h \ - shared/systemd/src/basic/hashmap.c \ - shared/systemd/src/basic/hashmap.h \ - shared/systemd/src/basic/hexdecoct.c \ - shared/systemd/src/basic/hexdecoct.h \ - shared/systemd/src/basic/hostname-util.c \ - shared/systemd/src/basic/hostname-util.h \ - shared/systemd/src/basic/in-addr-util.c \ - shared/systemd/src/basic/in-addr-util.h \ - shared/systemd/src/basic/io-util.c \ - shared/systemd/src/basic/io-util.h \ - shared/systemd/src/basic/list.h \ - shared/systemd/src/basic/log.h \ - shared/systemd/src/basic/macro.h \ - shared/systemd/src/basic/memory-util.c \ - shared/systemd/src/basic/memory-util.h \ - shared/systemd/src/basic/mempool.c \ - shared/systemd/src/basic/mempool.h \ - shared/systemd/src/basic/missing_fcntl.h \ - shared/systemd/src/basic/missing_random.h \ - shared/systemd/src/basic/missing_socket.h \ - shared/systemd/src/basic/missing_stat.h \ - shared/systemd/src/basic/missing_syscall.h \ - shared/systemd/src/basic/missing_type.h \ - shared/systemd/src/basic/parse-util.c \ - shared/systemd/src/basic/parse-util.h \ - shared/systemd/src/basic/path-util.c \ - shared/systemd/src/basic/path-util.h \ - shared/systemd/src/basic/prioq.c \ - shared/systemd/src/basic/prioq.h \ - shared/systemd/src/basic/process-util.c \ - shared/systemd/src/basic/process-util.h \ - shared/systemd/src/basic/random-util.c \ - shared/systemd/src/basic/random-util.h \ - shared/systemd/src/basic/ratelimit.c \ - shared/systemd/src/basic/ratelimit.h \ - shared/systemd/src/basic/set.h \ - shared/systemd/src/basic/signal-util.c \ - shared/systemd/src/basic/signal-util.h \ - shared/systemd/src/basic/siphash24.h \ - shared/systemd/src/basic/socket-util.c \ - shared/systemd/src/basic/socket-util.h \ - shared/systemd/src/basic/sort-util.h \ - shared/systemd/src/basic/sparse-endian.h \ - shared/systemd/src/basic/stat-util.c \ - shared/systemd/src/basic/stat-util.h \ - shared/systemd/src/basic/stdio-util.h \ - shared/systemd/src/basic/string-table.c \ - shared/systemd/src/basic/string-table.h \ - shared/systemd/src/basic/string-util.c \ - shared/systemd/src/basic/string-util.h \ - shared/systemd/src/basic/strv.c \ - shared/systemd/src/basic/strv.h \ - shared/systemd/src/basic/strxcpyx.c \ - shared/systemd/src/basic/strxcpyx.h \ - shared/systemd/src/basic/time-util.c \ - shared/systemd/src/basic/time-util.h \ - shared/systemd/src/basic/tmpfile-util.c \ - shared/systemd/src/basic/tmpfile-util.h \ - shared/systemd/src/basic/umask-util.h \ - shared/systemd/src/basic/utf8.c \ - shared/systemd/src/basic/utf8.h \ - shared/systemd/src/basic/util.c \ - shared/systemd/src/basic/util.h \ - shared/systemd/src/shared/dns-domain.c \ - shared/systemd/src/shared/dns-domain.h \ - shared/systemd/src/shared/log-link.h \ - shared/systemd/src/shared/web-util.c \ - shared/systemd/src/shared/web-util.h \ +src_libnm_systemd_shared_libnm_systemd_shared_la_SOURCES = \ + src/libnm-systemd-shared/nm-default-systemd-shared.h \ + src/libnm-systemd-shared/nm-sd-utils-shared.c \ + src/libnm-systemd-shared/nm-sd-utils-shared.h \ + src/libnm-systemd-shared/sd-adapt-shared/architecture.h \ + src/libnm-systemd-shared/sd-adapt-shared/arphrd-list.h \ + src/libnm-systemd-shared/sd-adapt-shared/blockdev-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/build.h \ + src/libnm-systemd-shared/sd-adapt-shared/copy.h \ + src/libnm-systemd-shared/sd-adapt-shared/def.h \ + src/libnm-systemd-shared/sd-adapt-shared/dhcp-server-internal.h \ + src/libnm-systemd-shared/sd-adapt-shared/dirent-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/errno-list.h \ + src/libnm-systemd-shared/sd-adapt-shared/glob-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/gunicode.h \ + src/libnm-systemd-shared/sd-adapt-shared/idn-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/ioprio.h \ + src/libnm-systemd-shared/sd-adapt-shared/locale-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/memfd-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_fs.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_keyctl.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_magic.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_network.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_sched.h \ + src/libnm-systemd-shared/sd-adapt-shared/missing_timerfd.h \ + src/libnm-systemd-shared/sd-adapt-shared/mkdir.h \ + src/libnm-systemd-shared/sd-adapt-shared/namespace-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h \ + src/libnm-systemd-shared/sd-adapt-shared/nulstr-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/raw-clone.h \ + src/libnm-systemd-shared/sd-adapt-shared/rlimit-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/terminal-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/unaligned.h \ + src/libnm-systemd-shared/sd-adapt-shared/user-util.h \ + src/libnm-systemd-shared/sd-adapt-shared/virt.h \ + src/libnm-systemd-shared/src/basic/alloc-util.c \ + src/libnm-systemd-shared/src/basic/alloc-util.h \ + src/libnm-systemd-shared/src/basic/async.h \ + src/libnm-systemd-shared/src/basic/cgroup-util.h \ + src/libnm-systemd-shared/src/basic/env-file.c \ + src/libnm-systemd-shared/src/basic/env-file.h \ + src/libnm-systemd-shared/src/basic/env-util.c \ + src/libnm-systemd-shared/src/basic/env-util.h \ + src/libnm-systemd-shared/src/basic/errno-util.h \ + src/libnm-systemd-shared/src/basic/escape.c \ + src/libnm-systemd-shared/src/basic/escape.h \ + src/libnm-systemd-shared/src/basic/ether-addr-util.c \ + src/libnm-systemd-shared/src/basic/ether-addr-util.h \ + src/libnm-systemd-shared/src/basic/extract-word.c \ + src/libnm-systemd-shared/src/basic/extract-word.h \ + src/libnm-systemd-shared/src/basic/fd-util.c \ + src/libnm-systemd-shared/src/basic/fd-util.h \ + src/libnm-systemd-shared/src/basic/fileio.c \ + src/libnm-systemd-shared/src/basic/fileio.h \ + src/libnm-systemd-shared/src/basic/format-util.c \ + src/libnm-systemd-shared/src/basic/format-util.h \ + src/libnm-systemd-shared/src/basic/fs-util.c \ + src/libnm-systemd-shared/src/basic/fs-util.h \ + src/libnm-systemd-shared/src/basic/hash-funcs.c \ + src/libnm-systemd-shared/src/basic/hash-funcs.h \ + src/libnm-systemd-shared/src/basic/hashmap.c \ + src/libnm-systemd-shared/src/basic/hashmap.h \ + src/libnm-systemd-shared/src/basic/hexdecoct.c \ + src/libnm-systemd-shared/src/basic/hexdecoct.h \ + src/libnm-systemd-shared/src/basic/hostname-util.c \ + src/libnm-systemd-shared/src/basic/hostname-util.h \ + src/libnm-systemd-shared/src/basic/in-addr-util.c \ + src/libnm-systemd-shared/src/basic/in-addr-util.h \ + src/libnm-systemd-shared/src/basic/io-util.c \ + src/libnm-systemd-shared/src/basic/io-util.h \ + src/libnm-systemd-shared/src/basic/list.h \ + src/libnm-systemd-shared/src/basic/log.h \ + src/libnm-systemd-shared/src/basic/macro.h \ + src/libnm-systemd-shared/src/basic/memory-util.c \ + src/libnm-systemd-shared/src/basic/memory-util.h \ + src/libnm-systemd-shared/src/basic/mempool.c \ + src/libnm-systemd-shared/src/basic/mempool.h \ + src/libnm-systemd-shared/src/basic/missing_fcntl.h \ + src/libnm-systemd-shared/src/basic/missing_random.h \ + src/libnm-systemd-shared/src/basic/missing_socket.h \ + src/libnm-systemd-shared/src/basic/missing_stat.h \ + src/libnm-systemd-shared/src/basic/missing_syscall.h \ + src/libnm-systemd-shared/src/basic/missing_type.h \ + src/libnm-systemd-shared/src/basic/parse-util.c \ + src/libnm-systemd-shared/src/basic/parse-util.h \ + src/libnm-systemd-shared/src/basic/path-util.c \ + src/libnm-systemd-shared/src/basic/path-util.h \ + src/libnm-systemd-shared/src/basic/prioq.c \ + src/libnm-systemd-shared/src/basic/prioq.h \ + src/libnm-systemd-shared/src/basic/process-util.c \ + src/libnm-systemd-shared/src/basic/process-util.h \ + src/libnm-systemd-shared/src/basic/random-util.c \ + src/libnm-systemd-shared/src/basic/random-util.h \ + src/libnm-systemd-shared/src/basic/ratelimit.c \ + src/libnm-systemd-shared/src/basic/ratelimit.h \ + src/libnm-systemd-shared/src/basic/set.h \ + src/libnm-systemd-shared/src/basic/signal-util.c \ + src/libnm-systemd-shared/src/basic/signal-util.h \ + src/libnm-systemd-shared/src/basic/siphash24.h \ + src/libnm-systemd-shared/src/basic/socket-util.c \ + src/libnm-systemd-shared/src/basic/socket-util.h \ + src/libnm-systemd-shared/src/basic/sort-util.h \ + src/libnm-systemd-shared/src/basic/sparse-endian.h \ + src/libnm-systemd-shared/src/basic/stat-util.c \ + src/libnm-systemd-shared/src/basic/stat-util.h \ + src/libnm-systemd-shared/src/basic/stdio-util.h \ + src/libnm-systemd-shared/src/basic/string-table.c \ + src/libnm-systemd-shared/src/basic/string-table.h \ + src/libnm-systemd-shared/src/basic/string-util.c \ + src/libnm-systemd-shared/src/basic/string-util.h \ + src/libnm-systemd-shared/src/basic/strv.c \ + src/libnm-systemd-shared/src/basic/strv.h \ + src/libnm-systemd-shared/src/basic/strxcpyx.c \ + src/libnm-systemd-shared/src/basic/strxcpyx.h \ + src/libnm-systemd-shared/src/basic/time-util.c \ + src/libnm-systemd-shared/src/basic/time-util.h \ + src/libnm-systemd-shared/src/basic/tmpfile-util.c \ + src/libnm-systemd-shared/src/basic/tmpfile-util.h \ + src/libnm-systemd-shared/src/basic/umask-util.h \ + src/libnm-systemd-shared/src/basic/utf8.c \ + src/libnm-systemd-shared/src/basic/utf8.h \ + src/libnm-systemd-shared/src/basic/util.c \ + src/libnm-systemd-shared/src/basic/util.h \ + src/libnm-systemd-shared/src/shared/dns-domain.c \ + src/libnm-systemd-shared/src/shared/dns-domain.h \ + src/libnm-systemd-shared/src/shared/log-link.h \ + src/libnm-systemd-shared/src/shared/web-util.c \ + src/libnm-systemd-shared/src/shared/web-util.h \ $(NULL) -shared_systemd_libnm_systemd_shared_la_LIBADD = \ +src_libnm_systemd_shared_libnm_systemd_shared_la_LIBADD = \ $(GLIB_LIBS) \ $(CODE_COVERAGE_LDFLAGS) \ $(NULL) @@ -6546,14 +6683,14 @@ shared_systemd_libnm_systemd_shared_la_LIBADD = \ ############################################################################### src_core_libnm_systemd_core_la_cppflags = \ $(libsystemd_cppflags) \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src \ -I$(srcdir)/src/core \ -I$(srcdir)/src/core/systemd/sd-adapt-core \ -I$(srcdir)/src/core/systemd/src/systemd \ -I$(srcdir)/src/core/systemd/src/libsystemd-network \ -I$(srcdir)/src/core/systemd/src/libsystemd/sd-event \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ $(NULL) src_core_libnm_systemd_core_la_libadd = \ @@ -6642,44 +6779,56 @@ src_core_libNetworkManagerBase_la_CPPFLAGS = \ $(libsystemd_cppflags) \ $(src_core_cppflags) -src_core_libNetworkManagerBase_la_SOURCES = src/core/nm-core-utils.c \ - src/core/nm-core-utils.h src/core/NetworkManagerUtils.c \ - src/core/NetworkManagerUtils.h src/core/platform/nmp-object.c \ - src/core/platform/nmp-object.h src/core/platform/nm-platform.c \ - src/core/platform/nm-platform.h \ - src/core/platform/nm-platform-private.h \ - src/core/platform/nm-linux-platform.c \ - src/core/platform/nm-linux-platform.h \ - src/core/platform/nmp-rules-manager.c \ - src/core/platform/nmp-rules-manager.h \ - src/core/platform/wifi/nm-wifi-utils-nl80211.c \ - src/core/platform/wifi/nm-wifi-utils-nl80211.h \ - src/core/platform/wifi/nm-wifi-utils-private.h \ - src/core/platform/wifi/nm-wifi-utils.c \ - src/core/platform/wifi/nm-wifi-utils.h \ - src/core/platform/wpan/nm-wpan-utils.c \ - src/core/platform/wpan/nm-wpan-utils.h \ - src/core/ndisc/nm-lndp-ndisc.c src/core/ndisc/nm-lndp-ndisc.h \ - src/core/ndisc/nm-ndisc.c src/core/ndisc/nm-ndisc.h \ - src/core/ndisc/nm-ndisc-private.h src/core/nm-dbus-utils.c \ - src/core/nm-dbus-utils.h src/core/nm-dbus-object.c \ - src/core/nm-dbus-object.h src/core/nm-netns.c \ - src/core/nm-netns.h src/core/nm-l3-config-data.c \ - src/core/nm-l3-config-data.h src/core/nm-l3-ipv4ll.c \ - src/core/nm-l3-ipv4ll.h src/core/nm-l3cfg.c \ - src/core/nm-l3cfg.h src/core/nm-ip-config.c \ - src/core/nm-ip-config.h src/core/nm-ip4-config.c \ - src/core/nm-ip4-config.h src/core/nm-ip6-config.c \ - src/core/nm-ip6-config.h src/core/dhcp/nm-dhcp-client.c \ +src_core_libNetworkManagerBase_la_SOURCES = \ + \ + src/core/nm-core-utils.c \ + src/core/nm-core-utils.h \ + \ + src/core/NetworkManagerUtils.c \ + src/core/NetworkManagerUtils.h \ + \ + src/core/ndisc/nm-lndp-ndisc.c \ + src/core/ndisc/nm-lndp-ndisc.h \ + src/core/ndisc/nm-ndisc.c \ + src/core/ndisc/nm-ndisc.h \ + src/core/ndisc/nm-ndisc-private.h \ + \ + src/core/nm-dbus-utils.c \ + src/core/nm-dbus-utils.h \ + src/core/nm-dbus-object.c \ + src/core/nm-dbus-object.h \ + src/core/nm-netns.c \ + src/core/nm-netns.h \ + src/core/nm-l3-config-data.c \ + src/core/nm-l3-config-data.h \ + src/core/nm-l3-ipv4ll.c \ + src/core/nm-l3-ipv4ll.h \ + src/core/nm-l3cfg.c \ + src/core/nm-l3cfg.h \ + src/core/nm-ip-config.c \ + src/core/nm-ip-config.h \ + src/core/nm-ip4-config.c \ + src/core/nm-ip4-config.h \ + src/core/nm-ip6-config.c \ + src/core/nm-ip6-config.h \ + \ + src/core/dhcp/nm-dhcp-client.c \ src/core/dhcp/nm-dhcp-client.h \ src/core/dhcp/nm-dhcp-client-logging.h \ - src/core/dhcp/nm-dhcp-nettools.c src/core/dhcp/nm-dhcp-utils.c \ - src/core/dhcp/nm-dhcp-utils.h src/core/dhcp/nm-dhcp-options.c \ + src/core/dhcp/nm-dhcp-nettools.c \ + src/core/dhcp/nm-dhcp-utils.c \ + src/core/dhcp/nm-dhcp-utils.h \ + src/core/dhcp/nm-dhcp-options.c \ src/core/dhcp/nm-dhcp-options.h \ src/core/dhcp/nm-dhcp-systemd.c \ src/core/dhcp/nm-dhcp-manager.c \ - src/core/dhcp/nm-dhcp-manager.h src/core/main-utils.c \ - src/core/main-utils.h $(NULL) $(am__append_18) + src/core/dhcp/nm-dhcp-manager.h \ + \ + src/core/main-utils.c \ + src/core/main-utils.h \ + \ + $(NULL) + src_core_libNetworkManagerBase_la_LIBADD = \ $(GLIB_LIBS) \ $(LIBUDEV_LIBS) \ @@ -6869,22 +7018,22 @@ src_core_libNetworkManager_la_SOURCES = \ src_core_libNetworkManager_la_LIBADD = \ src/core/libNetworkManagerBase.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la \ $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-platform/libnm-platform.la \ - shared/nm-base/libnm-base.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ src/core/libnm-systemd-core.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/libnacd.la \ - shared/libndhcp4.la \ - shared/libcrbtree.la \ - shared/libcsiphash.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/n-acd/libn-acd.la \ + src/n-dhcp4/libn-dhcp4.la \ + src/c-rbtree/libc-rbtree.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(LIBUDEV_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ @@ -6956,22 +7105,22 @@ src_core_nm_iface_helper_SOURCES = \ src_core_nm_iface_helper_LDADD = \ src/core/libNetworkManagerBase.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-impl/libnm-core-impl.la \ $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-platform/libnm-platform.la \ - shared/nm-base/libnm-base.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ src/core/libnm-systemd-core.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/libnacd.la \ - shared/libndhcp4.la \ - shared/libcrbtree.la \ - shared/libcsiphash.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/n-acd/libn-acd.la \ + src/n-dhcp4/libn-dhcp4.la \ + src/c-rbtree/libc-rbtree.la \ + src/c-siphash/libc-siphash.la \ $(SYSTEMD_JOURNAL_LIBS) \ $(GLIB_LIBS) \ $(LIBUDEV_LIBS) \ @@ -6983,106 +7132,99 @@ src_core_nm_iface_helper_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) -src_core_initrd_libnmi_core_la_CPPFLAGS = \ - $(src_core_cppflags) - -src_core_initrd_libnmi_core_la_SOURCES = \ - src/core/initrd/nm-initrd-generator.h \ - src/core/initrd/nmi-cmdline-reader.c \ - src/core/initrd/nmi-dt-reader.c \ - src/core/initrd/nmi-ibft-reader.c \ +src_nm_initrd_generator_libnmi_core_la_CPPFLAGS = \ + $(dflt_cppflags) \ + -I$(srcdir)/src/libnm-core-public \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + $(CODE_COVERAGE_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(LIBUDEV_CFLAGS) \ + $(SYSTEMD_JOURNAL_CFLAGS) \ + $(SANITIZER_LIB_CFLAGS) \ $(NULL) -src_core_initrd_nm_initrd_generator_CPPFLAGS = \ - $(src_core_cppflags) +src_nm_initrd_generator_libnmi_core_la_SOURCES = \ + src/nm-initrd-generator/nm-initrd-generator.h \ + src/nm-initrd-generator/nmi-cmdline-reader.c \ + src/nm-initrd-generator/nmi-dt-reader.c \ + src/nm-initrd-generator/nmi-ibft-reader.c \ + $(NULL) -src_core_initrd_nm_initrd_generator_SOURCES = \ - src/core/initrd/nm-initrd-generator.c +src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS = \ + $(dflt_cppflags) \ + -I$(srcdir)/src/libnm-core-public \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + $(CODE_COVERAGE_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(LIBUDEV_CFLAGS) \ + $(SYSTEMD_JOURNAL_CFLAGS) \ + $(SANITIZER_EXEC_CFLAGS) \ + $(NULL) -src_core_initrd_nm_initrd_generator_LDADD = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerBase.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/libnm-core.la \ +src_nm_initrd_generator_nm_initrd_generator_LDADD = \ + src/nm-initrd-generator/libnmi-core.la \ + src/libnm-core-impl/libnm-core-impl.la \ $(libnm_crypto_lib) \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-platform/libnm-platform.la \ - shared/nm-base/libnm-base.la \ - shared/nm-log-core/libnm-log-core.la \ - shared/nm-udev-aux/libnm-udev-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libndhcp4.la \ - shared/libcsiphash.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-base/libnm-base.la \ + src/libnm-log-core/libnm-log-core.la \ + src/libnm-platform/libnm-platform.la \ + src/libnm-udev-aux/libnm-udev-aux.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(SYSTEMD_JOURNAL_LIBS) \ $(GLIB_LIBS) \ $(NULL) -src_core_initrd_nm_initrd_generator_LDFLAGS = \ +src_nm_initrd_generator_nm_initrd_generator_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ - $(SANITIZER_EXEC_LDFLAGS) - -src_core_initrd_tests_test_dt_reader_CPPFLAGS = \ - $(src_core_cppflags) \ + $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -src_core_initrd_tests_test_dt_reader_LDFLAGS = \ +src_nm_initrd_generator_tests_test_dt_reader_CPPFLAGS = \ + $(src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS) + +src_nm_initrd_generator_tests_test_dt_reader_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -src_core_initrd_tests_test_dt_reader_LDADD = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerTest.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - $(GLIB_LIBS) \ - $(NULL) +src_nm_initrd_generator_tests_test_dt_reader_LDADD = \ + $(src_nm_initrd_generator_nm_initrd_generator_LDADD) -src_core_initrd_tests_test_ibft_reader_CPPFLAGS = \ - $(src_core_cppflags) \ - $(NULL) +src_nm_initrd_generator_tests_test_ibft_reader_CPPFLAGS = \ + $(src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS) -src_core_initrd_tests_test_ibft_reader_LDFLAGS = \ +src_nm_initrd_generator_tests_test_ibft_reader_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -src_core_initrd_tests_test_ibft_reader_LDADD = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerTest.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - $(GLIB_LIBS) \ - $(NULL) +src_nm_initrd_generator_tests_test_ibft_reader_LDADD = \ + $(src_nm_initrd_generator_nm_initrd_generator_LDADD) -src_core_initrd_tests_test_cmdline_reader_CPPFLAGS = \ - $(src_core_cppflags) \ - $(NULL) +src_nm_initrd_generator_tests_test_cmdline_reader_CPPFLAGS = \ + $(src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS) -src_core_initrd_tests_test_cmdline_reader_LDFLAGS = \ +src_nm_initrd_generator_tests_test_cmdline_reader_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ - $(SANITIZER_EXEC_LDFLAGS) - -src_core_initrd_tests_test_cmdline_reader_LDADD = \ - src/core/initrd/libnmi-core.la \ - src/core/libNetworkManagerTest.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - $(GLIB_LIBS) \ + $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) +src_nm_initrd_generator_tests_test_cmdline_reader_LDADD = \ + $(src_nm_initrd_generator_nm_initrd_generator_LDADD) + src_core_dhcp_nm_dhcp_helper_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -DG_LOG_DOMAIN=\""nm-dhcp-helper"\" \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(GLIB_CFLAGS) \ $(NULL) @@ -7111,10 +7253,10 @@ src_core_dhcp_tests_test_dhcp_dhclient_LDFLAGS = $(src_core_tests_ldflags) src_core_dhcp_tests_test_dhcp_utils_LDFLAGS = $(src_core_tests_ldflags) @WITH_PPP_TRUE@src_core_ppp_nm_pppd_plugin_la_CPPFLAGS = \ @WITH_PPP_TRUE@ $(dflt_cppflags) \ -@WITH_PPP_TRUE@ -I$(srcdir)/shared \ -@WITH_PPP_TRUE@ -I$(builddir)/shared \ -@WITH_PPP_TRUE@ -I$(srcdir)/libnm-core \ -@WITH_PPP_TRUE@ -DG_LOG_DOMAIN=\""nm-pppd-plugin"\" \ +@WITH_PPP_TRUE@ -I$(srcdir)/src \ +@WITH_PPP_TRUE@ -I$(builddir)/src \ +@WITH_PPP_TRUE@ -I$(builddir)/src/libnm-core-public \ +@WITH_PPP_TRUE@ -I$(srcdir)/src/libnm-core-public \ @WITH_PPP_TRUE@ $(GLIB_CFLAGS) @WITH_PPP_TRUE@src_core_ppp_nm_pppd_plugin_la_SOURCES = \ @@ -7665,541 +7807,499 @@ src_core_tests_test_systemd_LDFLAGS = \ src_core_tests_test_systemd_LDADD = \ src/core/libnm-systemd-core.la \ - shared/systemd/libnm-systemd-shared.la \ - shared/libcsiphash.la \ + src/libnm-systemd-shared/libnm-systemd-shared.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(CODE_COVERAGE_LDFLAGS) \ $(NULL) ############################################################################### -# dispatcher +# src/nm-dispatcher ############################################################################### dispatcher_nmdbus_dispatcher_sources = \ - dispatcher/nmdbus-dispatcher.h \ - dispatcher/nmdbus-dispatcher.c \ + src/nm-dispatcher/nmdbus-dispatcher.h \ + src/nm-dispatcher/nmdbus-dispatcher.c \ $(NULL) dispatcher_cppflags = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ - -I$(srcdir)/dispatcher \ - -I$(builddir)/dispatcher \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(builddir)/src/libnm-client-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(GLIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""nm-dispatcher"\" \ $(NULL) -dispatcher_libnm_dispatcher_core_la_SOURCES = \ - dispatcher/nm-dispatcher-utils.c \ - dispatcher/nm-dispatcher-utils.h \ +src_nm_dispatcher_libnm_dispatcher_core_la_SOURCES = \ + src/nm-dispatcher/nm-dispatcher-utils.c \ + src/nm-dispatcher/nm-dispatcher-utils.h \ $(NULL) -dispatcher_libnm_dispatcher_core_la_CPPFLAGS = $(dispatcher_cppflags) -dispatcher_libnm_dispatcher_core_la_LIBADD = \ - libnm/libnm.la \ +src_nm_dispatcher_libnm_dispatcher_core_la_CPPFLAGS = $(dispatcher_cppflags) +src_nm_dispatcher_libnm_dispatcher_core_la_LIBADD = \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) -dispatcher_nm_dispatcher_SOURCES = \ - dispatcher/nm-dispatcher.c \ +src_nm_dispatcher_nm_dispatcher_SOURCES = \ + src/nm-dispatcher/nm-dispatcher.c \ $(NULL) -dispatcher_nm_dispatcher_CPPFLAGS = $(dispatcher_cppflags) -dispatcher_nm_dispatcher_LDFLAGS = \ +src_nm_dispatcher_nm_dispatcher_CPPFLAGS = $(dispatcher_cppflags) +src_nm_dispatcher_nm_dispatcher_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -dispatcher_nm_dispatcher_LDADD = \ - dispatcher/libnm-dispatcher-core.la \ - libnm/libnm.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - $(GLIB_LIBS) +src_nm_dispatcher_nm_dispatcher_LDADD = \ + src/nm-dispatcher/libnm-dispatcher-core.la \ + src/libnm-client-impl/libnm.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + $(GLIB_LIBS) \ + $(NULL) -dispatcher_tests_test_dispatcher_envp_CPPFLAGS = \ +src_nm_dispatcher_tests_test_dispatcher_envp_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ - -I$(srcdir)/dispatcher \ - -I$(builddir)/dispatcher \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ + -I$(srcdir)/src \ + -I$(builddir)/src \ $(GLIB_CFLAGS) \ $(SANITIZER_EXEC_CFLAGS) \ $(INTROSPECTION_EXTRA_CFLAGS) \ $(NULL) -dispatcher_tests_test_dispatcher_envp_SOURCES = \ - dispatcher/tests/test-dispatcher-envp.c \ +src_nm_dispatcher_tests_test_dispatcher_envp_SOURCES = \ + src/nm-dispatcher/tests/test-dispatcher-envp.c \ $(NULL) -nodist_dispatcher_tests_test_dispatcher_envp_SOURCES = $(dispatcher_nmdbus_dispatcher_sources) -dispatcher_tests_test_dispatcher_envp_LDFLAGS = \ +nodist_src_nm_dispatcher_tests_test_dispatcher_envp_SOURCES = $(dispatcher_nmdbus_dispatcher_sources) +src_nm_dispatcher_tests_test_dispatcher_envp_LDFLAGS = \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -dispatcher_tests_test_dispatcher_envp_LDADD = \ - dispatcher/libnm-dispatcher-core.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - libnm/libnm.la \ +src_nm_dispatcher_tests_test_dispatcher_envp_LDADD = \ + src/nm-dispatcher/libnm-dispatcher-core.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(NULL) -clients_nm_online_CPPFLAGS = \ +src_nm_online_nm_online_CPPFLAGS = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(GLIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""nm-online"\" \ $(NULL) -clients_nm_online_LDFLAGS = \ +src_nm_online_nm_online_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -clients_nm_online_LDADD = \ - libnm/libnm.la \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ +src_nm_online_nm_online_LDADD = \ + src/libnm-client-impl/libnm.la \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(NULL) ############################################################################### -# clients/common +# src/libnmc-base ############################################################################### clients_cppflags = \ $(dflt_cppflags) \ - -I$(srcdir)/shared \ - -I$(builddir)/shared \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ - -I$(srcdir)/clients/common \ + -I$(srcdir)/src \ + -I$(builddir)/src \ + -I$(srcdir)/src/libnm-core-public \ + -I$(builddir)/src/libnm-core-public \ + -I$(srcdir)/src/libnm-client-public \ + -I$(builddir)/src/libnm-client-public \ $(GLIB_CFLAGS) \ $(SANITIZER_EXEC_CFLAGS) \ $(NULL) -clients_common_libnmc_base_la_SOURCES = \ - clients/common/nm-secret-agent-simple.c \ - clients/common/nm-secret-agent-simple.h \ - clients/common/nm-vpn-helpers.c \ - clients/common/nm-vpn-helpers.h \ - clients/common/nm-client-utils.c \ - clients/common/nm-client-utils.h \ - clients/common/nm-polkit-listener.c \ - clients/common/nm-polkit-listener.h \ +src_libnmc_base_libnmc_base_la_SOURCES = \ + src/libnmc-base/nm-client-utils.c \ + src/libnmc-base/nm-client-utils.h \ + src/libnmc-base/nm-polkit-listener.c \ + src/libnmc-base/nm-polkit-listener.h \ + src/libnmc-base/nm-secret-agent-simple.c \ + src/libnmc-base/nm-secret-agent-simple.h \ + src/libnmc-base/nm-vpn-helpers.c \ + src/libnmc-base/nm-vpn-helpers.h \ $(NULL) -clients_common_libnmc_base_la_CPPFLAGS = \ +src_libnmc_base_libnmc_base_la_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""libnmc"\" \ $(NULL) -clients_common_libnmc_base_la_LIBADD = \ - libnm/libnm.la \ +src_libnmc_base_libnmc_base_la_LIBADD = \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(NULL) -clients_common_settings_doc_h = clients/common/settings-docs.h -clients_common_libnmc_la_SOURCES = \ - clients/common/nm-meta-setting-base-impl.c \ - clients/common/nm-meta-setting-base-impl.h \ - clients/common/nm-meta-setting-base.h \ - \ - clients/common/nm-meta-setting-desc.c \ - clients/common/nm-meta-setting-desc.h \ - clients/common/nm-meta-setting-access.c \ - clients/common/nm-meta-setting-access.h \ - $(NULL) -clients_common_libnmc_la_CPPFLAGS = \ - $(clients_cppflags) \ - -I$(builddir)/clients/common \ - -DG_LOG_DOMAIN=\""libnmc"\" \ - $(NULL) - -clients_common_libnmc_la_LIBADD = \ - libnm/libnm.la \ - $(GLIB_LIBS) \ +############################################################################### +# src/libnmc-setting +############################################################################### +libnmc_setting_settings_doc_h = src/libnmc-setting/settings-docs.h +src_libnmc_setting_libnmc_setting_la_SOURCES = \ + src/libnmc-setting/nm-meta-setting-access.c \ + src/libnmc-setting/nm-meta-setting-access.h \ + src/libnmc-setting/nm-meta-setting-base-impl.c \ + src/libnmc-setting/nm-meta-setting-base-impl.h \ + src/libnmc-setting/nm-meta-setting-base.h \ + src/libnmc-setting/nm-meta-setting-desc.c \ + src/libnmc-setting/nm-meta-setting-desc.h \ $(NULL) -clients_common_tests_test_clients_common_CPPFLAGS = \ - -I$(srcdir)/clients/common/tests \ +src_libnmc_setting_libnmc_setting_la_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""test"\" \ $(NULL) -clients_common_tests_test_clients_common_LDFLAGS = \ - $(SANITIZER_EXEC_LDFLAGS) - -clients_common_tests_test_clients_common_LDADD = \ - clients/common/libnmc.la \ - clients/common/libnmc-base.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - libnm/libnm.la \ - $(GLIB_LIBS) +src_libnmc_setting_libnmc_setting_la_LIBADD = \ + src/libnm-client-impl/libnm.la \ + $(GLIB_LIBS) \ + $(NULL) -clients_common_tests_test_libnm_core_aux_CPPFLAGS = \ - $(dflt_cppflags) \ - -I$(builddir)/shared \ - -I$(srcdir)/shared \ - -I$(builddir)/libnm-core \ - -I$(srcdir)/libnm-core \ - -I$(builddir)/libnm \ - -I$(srcdir)/libnm \ - -DG_LOG_DOMAIN=\""test"\" \ - $(CODE_COVERAGE_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(SANITIZER_LIB_CFLAGS) \ +src_libnmc_setting_tests_test_libnmc_setting_CPPFLAGS = \ + $(clients_cppflags) \ $(NULL) -clients_common_tests_test_libnm_core_aux_LDFLAGS = \ - $(CODE_COVERAGE_LDFLAGS) \ +src_libnmc_setting_tests_test_libnmc_setting_LDFLAGS = \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -clients_common_tests_test_libnm_core_aux_LDADD = \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ - libnm/libnm.la \ - $(GLIB_LIBS) \ - $(NULL) +src_libnmc_setting_tests_test_libnmc_setting_LDADD = \ + src/libnmc-setting/libnmc-setting.la \ + src/libnmc-base/libnmc-base.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ + src/libnm-client-impl/libnm.la \ + $(GLIB_LIBS) -@BUILD_NMCLI_TRUE@clients_cli_nmcli_SOURCES = \ -@BUILD_NMCLI_TRUE@ clients/cli/common.c \ -@BUILD_NMCLI_TRUE@ clients/cli/common.h \ -@BUILD_NMCLI_TRUE@ clients/cli/utils.c \ -@BUILD_NMCLI_TRUE@ clients/cli/utils.h \ -@BUILD_NMCLI_TRUE@ clients/cli/agent.c \ -@BUILD_NMCLI_TRUE@ clients/cli/general.c \ -@BUILD_NMCLI_TRUE@ clients/cli/connections.c \ -@BUILD_NMCLI_TRUE@ clients/cli/connections.h \ -@BUILD_NMCLI_TRUE@ clients/cli/devices.c \ -@BUILD_NMCLI_TRUE@ clients/cli/devices.h \ -@BUILD_NMCLI_TRUE@ clients/cli/settings.c \ -@BUILD_NMCLI_TRUE@ clients/cli/settings.h \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli.c \ -@BUILD_NMCLI_TRUE@ clients/cli/nmcli.h \ -@BUILD_NMCLI_TRUE@ clients/cli/polkit-agent.c \ -@BUILD_NMCLI_TRUE@ clients/cli/polkit-agent.h \ +@BUILD_NMCLI_TRUE@src_nmcli_nmcli_SOURCES = \ +@BUILD_NMCLI_TRUE@ src/nmcli/common.c \ +@BUILD_NMCLI_TRUE@ src/nmcli/common.h \ +@BUILD_NMCLI_TRUE@ src/nmcli/utils.c \ +@BUILD_NMCLI_TRUE@ src/nmcli/utils.h \ +@BUILD_NMCLI_TRUE@ src/nmcli/agent.c \ +@BUILD_NMCLI_TRUE@ src/nmcli/general.c \ +@BUILD_NMCLI_TRUE@ src/nmcli/connections.c \ +@BUILD_NMCLI_TRUE@ src/nmcli/connections.h \ +@BUILD_NMCLI_TRUE@ src/nmcli/devices.c \ +@BUILD_NMCLI_TRUE@ src/nmcli/devices.h \ +@BUILD_NMCLI_TRUE@ src/nmcli/settings.c \ +@BUILD_NMCLI_TRUE@ src/nmcli/settings.h \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli.c \ +@BUILD_NMCLI_TRUE@ src/nmcli/nmcli.h \ +@BUILD_NMCLI_TRUE@ src/nmcli/polkit-agent.c \ +@BUILD_NMCLI_TRUE@ src/nmcli/polkit-agent.h \ @BUILD_NMCLI_TRUE@ $(NULL) -@BUILD_NMCLI_TRUE@clients_cli_nmcli_CPPFLAGS = \ -@BUILD_NMCLI_TRUE@ -I$(srcdir)/clients/cli \ +@BUILD_NMCLI_TRUE@src_nmcli_nmcli_CPPFLAGS = \ @BUILD_NMCLI_TRUE@ $(clients_cppflags) \ -@BUILD_NMCLI_TRUE@ -DG_LOG_DOMAIN=\""nmcli"\" \ @BUILD_NMCLI_TRUE@ $(NULL) -@BUILD_NMCLI_TRUE@clients_cli_nmcli_LDADD = \ -@BUILD_NMCLI_TRUE@ clients/common/libnmc.la \ -@BUILD_NMCLI_TRUE@ clients/common/libnmc-base.la \ -@BUILD_NMCLI_TRUE@ libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ -@BUILD_NMCLI_TRUE@ libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ -@BUILD_NMCLI_TRUE@ shared/nm-base/libnm-base.la \ -@BUILD_NMCLI_TRUE@ shared/nm-glib-aux/libnm-glib-aux.la \ -@BUILD_NMCLI_TRUE@ shared/nm-std-aux/libnm-std-aux.la \ -@BUILD_NMCLI_TRUE@ shared/libcsiphash.la \ -@BUILD_NMCLI_TRUE@ libnm/nm-libnm-aux/libnm-libnm-aux.la \ -@BUILD_NMCLI_TRUE@ libnm/libnm.la \ +@BUILD_NMCLI_TRUE@src_nmcli_nmcli_LDADD = \ +@BUILD_NMCLI_TRUE@ src/libnmc-setting/libnmc-setting.la \ +@BUILD_NMCLI_TRUE@ src/libnmc-base/libnmc-base.la \ +@BUILD_NMCLI_TRUE@ src/libnm-core-aux-extern/libnm-core-aux-extern.la \ +@BUILD_NMCLI_TRUE@ src/libnm-core-aux-intern/libnm-core-aux-intern.la \ +@BUILD_NMCLI_TRUE@ src/libnm-base/libnm-base.la \ +@BUILD_NMCLI_TRUE@ src/libnm-glib-aux/libnm-glib-aux.la \ +@BUILD_NMCLI_TRUE@ src/libnm-std-aux/libnm-std-aux.la \ +@BUILD_NMCLI_TRUE@ src/c-siphash/libc-siphash.la \ +@BUILD_NMCLI_TRUE@ src/libnm-client-aux-extern/libnm-client-aux-extern.la \ +@BUILD_NMCLI_TRUE@ src/libnm-client-impl/libnm.la \ @BUILD_NMCLI_TRUE@ $(GLIB_LIBS) \ @BUILD_NMCLI_TRUE@ $(READLINE_LIBS) -@BUILD_NMCLI_TRUE@clients_cli_nmcli_LDFLAGS = \ +@BUILD_NMCLI_TRUE@src_nmcli_nmcli_LDFLAGS = \ @BUILD_NMCLI_TRUE@ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ @BUILD_NMCLI_TRUE@ $(SANITIZER_EXEC_LDFLAGS) -clients_cli_generate_docs_nm_settings_nmcli_SOURCES = \ - clients/cli/generate-docs-nm-settings-nmcli.c \ +src_nmcli_generate_docs_nm_settings_nmcli_SOURCES = \ + src/nmcli/generate-docs-nm-settings-nmcli.c \ $(NULL) -clients_cli_generate_docs_nm_settings_nmcli_CPPFLAGS = \ - -I$(srcdir)/clients/common \ +src_nmcli_generate_docs_nm_settings_nmcli_CPPFLAGS = \ $(clients_cppflags) \ - -DG_LOG_DOMAIN=\""nmcli"\" \ $(NULL) -clients_cli_generate_docs_nm_settings_nmcli_LDADD = \ - clients/common/libnmc.la \ - clients/common/libnmc-base.la \ - libnm/nm-libnm-aux/libnm-libnm-aux.la \ - libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ - libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ - shared/nm-base/libnm-base.la \ - libnm/libnm.la \ - shared/nm-glib-aux/libnm-glib-aux.la \ - shared/nm-std-aux/libnm-std-aux.la \ - shared/libcsiphash.la \ +src_nmcli_generate_docs_nm_settings_nmcli_LDADD = \ + src/libnmc-setting/libnmc-setting.la \ + src/libnmc-base/libnmc-base.la \ + src/libnm-client-aux-extern/libnm-client-aux-extern.la \ + src/libnm-core-aux-extern/libnm-core-aux-extern.la \ + src/libnm-core-aux-intern/libnm-core-aux-intern.la \ + src/libnm-base/libnm-base.la \ + src/libnm-client-impl/libnm.la \ + src/libnm-glib-aux/libnm-glib-aux.la \ + src/libnm-std-aux/libnm-std-aux.la \ + src/c-siphash/libc-siphash.la \ $(GLIB_LIBS) \ $(NULL) -clients_cli_generate_docs_nm_settings_nmcli_LDFLAGS = \ +src_nmcli_generate_docs_nm_settings_nmcli_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ $(SANITIZER_EXEC_LDFLAGS) \ $(NULL) -@BUILD_NMTUI_TRUE@clients_tui_newt_libnmt_newt_a_SOURCES = \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-types.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-button.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-button.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-button-box.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-button-box.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-checkbox.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-checkbox.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-component.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-component.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-container.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-container.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-entry.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-entry.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-entry-numeric.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-entry-numeric.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-form.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-form.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-grid.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-grid.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-hacks.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-hacks.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-label.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-label.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-listbox.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-listbox.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-popup.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-popup.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-section.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-section.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-separator.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-separator.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-stack.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-stack.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-textbox.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-textbox.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-toggle-button.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-toggle-button.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-utils.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-utils.h \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-widget.c \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/nmt-newt-widget.h \ +@BUILD_NMTUI_TRUE@src_libnmt_newt_libnmt_newt_a_SOURCES = \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-button-box.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-button-box.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-button.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-button.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-checkbox.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-checkbox.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-component.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-component.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-container.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-container.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-entry-numeric.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-entry-numeric.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-entry.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-entry.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-form.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-form.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-grid.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-grid.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-hacks.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-hacks.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-label.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-label.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-listbox.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-listbox.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-popup.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-popup.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-section.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-section.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-separator.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-separator.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-stack.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-stack.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-textbox.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-textbox.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-toggle-button.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-toggle-button.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-types.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-utils.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-utils.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-widget.c \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt-widget.h \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/nmt-newt.h \ @BUILD_NMTUI_TRUE@ $(NULL) -@BUILD_NMTUI_TRUE@clients_tui_newt_libnmt_newt_a_CPPFLAGS = \ +@BUILD_NMTUI_TRUE@src_libnmt_newt_libnmt_newt_a_CPPFLAGS = \ @BUILD_NMTUI_TRUE@ $(clients_cppflags) \ -@BUILD_NMTUI_TRUE@ -DG_LOG_DOMAIN=\""nmtui"\" \ @BUILD_NMTUI_TRUE@ $(NEWT_CFLAGS) \ @BUILD_NMTUI_TRUE@ $(NULL) -@BUILD_NMTUI_TRUE@clients_tui_nmtui_SOURCES = \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-connect.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-connect.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-edit.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-edit.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-hostname.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmtui-hostname.h \ +@BUILD_NMTUI_TRUE@src_nmtui_nmtui_SOURCES = \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-connect.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-connect.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-edit.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-edit.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-hostname.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmtui-hostname.h \ @BUILD_NMTUI_TRUE@ \ -@BUILD_NMTUI_TRUE@ clients/tui/nm-editor-bindings.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nm-editor-bindings.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nm-editor-utils.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nm-editor-utils.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nm-editor-bindings.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nm-editor-bindings.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nm-editor-utils.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nm-editor-utils.h \ @BUILD_NMTUI_TRUE@ \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-address-list.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-address-list.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-connect-connection-list.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-connect-connection-list.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-device-entry.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-device-entry.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-edit-connection-list.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-edit-connection-list.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-editor-grid.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-editor-grid.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-editor-page.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-editor-page.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-editor-page-device.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-editor-page-device.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-editor-section.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-editor-section.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-editor.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-editor.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-ip-entry.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-ip-entry.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-mac-entry.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-mac-entry.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-mtu-entry.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-mtu-entry.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-bond.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-bond.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-bridge.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-bridge.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-bridge-port.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-bridge-port.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-dsl.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-dsl.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-ethernet.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-ethernet.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-infiniband.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-infiniband.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-ip-tunnel.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-ip-tunnel.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-ip4.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-ip4.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-ip6.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-ip6.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-ppp.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-ppp.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-team.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-team.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-team-port.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-team-port.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-vlan.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-vlan.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-wifi.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-page-wifi.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-password-dialog.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-password-dialog.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-password-fields.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-password-fields.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-route-editor.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-route-editor.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-route-entry.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-route-entry.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-route-table.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-route-table.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-slave-list.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-slave-list.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-utils.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-utils.h \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-widget-list.c \ -@BUILD_NMTUI_TRUE@ clients/tui/nmt-widget-list.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-address-list.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-address-list.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-connect-connection-list.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-connect-connection-list.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-device-entry.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-device-entry.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-edit-connection-list.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-edit-connection-list.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-editor-grid.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-editor-grid.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-editor-page.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-editor-page.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-editor-page-device.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-editor-page-device.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-editor-section.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-editor-section.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-editor.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-editor.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-ip-entry.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-ip-entry.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-mac-entry.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-mac-entry.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-mtu-entry.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-mtu-entry.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-bond.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-bond.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-bridge.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-bridge.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-bridge-port.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-bridge-port.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-dsl.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-dsl.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-ethernet.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-ethernet.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-infiniband.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-infiniband.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-ip-tunnel.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-ip-tunnel.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-ip4.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-ip4.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-ip6.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-ip6.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-ppp.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-ppp.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-team.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-team.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-team-port.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-team-port.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-vlan.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-vlan.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-wifi.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-page-wifi.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-password-dialog.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-password-dialog.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-password-fields.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-password-fields.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-route-editor.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-route-editor.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-route-entry.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-route-entry.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-route-table.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-route-table.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-slave-list.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-slave-list.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-utils.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-utils.h \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-widget-list.c \ +@BUILD_NMTUI_TRUE@ src/nmtui/nmt-widget-list.h \ @BUILD_NMTUI_TRUE@ $(NULL) -@BUILD_NMTUI_TRUE@clients_tui_nmtui_CPPFLAGS = \ -@BUILD_NMTUI_TRUE@ -I$(srcdir)/clients/tui/newt \ +@BUILD_NMTUI_TRUE@src_nmtui_nmtui_CPPFLAGS = \ @BUILD_NMTUI_TRUE@ $(clients_cppflags) \ -@BUILD_NMTUI_TRUE@ -DG_LOG_DOMAIN=\""nmtui"\" \ @BUILD_NMTUI_TRUE@ $(NEWT_CFLAGS) \ @BUILD_NMTUI_TRUE@ $(NULL) -@BUILD_NMTUI_TRUE@clients_tui_nmtui_LDFLAGS = \ +@BUILD_NMTUI_TRUE@src_nmtui_nmtui_LDFLAGS = \ @BUILD_NMTUI_TRUE@ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ @BUILD_NMTUI_TRUE@ $(SANITIZER_EXEC_LDFLAGS) -@BUILD_NMTUI_TRUE@clients_tui_nmtui_LDADD = \ -@BUILD_NMTUI_TRUE@ clients/tui/newt/libnmt-newt.a \ -@BUILD_NMTUI_TRUE@ clients/common/libnmc.la \ -@BUILD_NMTUI_TRUE@ clients/common/libnmc-base.la \ -@BUILD_NMTUI_TRUE@ libnm/nm-libnm-aux/libnm-libnm-aux.la \ -@BUILD_NMTUI_TRUE@ libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ -@BUILD_NMTUI_TRUE@ libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ -@BUILD_NMTUI_TRUE@ shared/nm-base/libnm-base.la \ -@BUILD_NMTUI_TRUE@ shared/nm-glib-aux/libnm-glib-aux.la \ -@BUILD_NMTUI_TRUE@ shared/nm-std-aux/libnm-std-aux.la \ -@BUILD_NMTUI_TRUE@ shared/libcsiphash.la \ -@BUILD_NMTUI_TRUE@ libnm/libnm.la \ +@BUILD_NMTUI_TRUE@src_nmtui_nmtui_LDADD = \ +@BUILD_NMTUI_TRUE@ src/libnmt-newt/libnmt-newt.a \ +@BUILD_NMTUI_TRUE@ src/libnmc-setting/libnmc-setting.la \ +@BUILD_NMTUI_TRUE@ src/libnmc-base/libnmc-base.la \ +@BUILD_NMTUI_TRUE@ src/libnm-client-aux-extern/libnm-client-aux-extern.la \ +@BUILD_NMTUI_TRUE@ src/libnm-core-aux-extern/libnm-core-aux-extern.la \ +@BUILD_NMTUI_TRUE@ src/libnm-core-aux-intern/libnm-core-aux-intern.la \ +@BUILD_NMTUI_TRUE@ src/libnm-base/libnm-base.la \ +@BUILD_NMTUI_TRUE@ src/libnm-glib-aux/libnm-glib-aux.la \ +@BUILD_NMTUI_TRUE@ src/libnm-std-aux/libnm-std-aux.la \ +@BUILD_NMTUI_TRUE@ src/c-siphash/libc-siphash.la \ +@BUILD_NMTUI_TRUE@ src/libnm-client-impl/libnm.la \ @BUILD_NMTUI_TRUE@ $(GLIB_LIBS) \ @BUILD_NMTUI_TRUE@ $(NEWT_LIBS) \ @BUILD_NMTUI_TRUE@ $(NULL) -@BUILD_NMTUI_TRUE@nmtui_links = nmtui-edit nmtui-connect nmtui-hostname -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_libnm_cloud_setup_core_a_SOURCES = \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nm-cloud-setup-utils.c \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nm-cloud-setup-utils.h \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nm-http-client.c \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nm-http-client.h \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nmcs-provider.c \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nmcs-provider.h \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nmcs-provider-ec2.c \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nmcs-provider-ec2.h \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nmcs-provider-gcp.c \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nmcs-provider-gcp.h \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nmcs-provider-azure.c \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/nmcs-provider-azure.h \ +@BUILD_NMTUI_TRUE@nmtui_links = \ +@BUILD_NMTUI_TRUE@ nmtui-edit \ +@BUILD_NMTUI_TRUE@ nmtui-connect \ +@BUILD_NMTUI_TRUE@ nmtui-hostname \ +@BUILD_NMTUI_TRUE@ $(NULL) + +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_libnm_cloud_setup_core_a_SOURCES = \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nm-cloud-setup-utils.c \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nm-cloud-setup-utils.h \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nm-http-client.c \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nm-http-client.h \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nmcs-provider.c \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nmcs-provider.h \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nmcs-provider-ec2.c \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nmcs-provider-ec2.h \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nmcs-provider-gcp.c \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nmcs-provider-gcp.h \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nmcs-provider-azure.c \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/nmcs-provider-azure.h \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(NULL) -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS = \ +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS = \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(clients_cppflags) \ -@BUILD_NM_CLOUD_SETUP_TRUE@ -DG_LOG_DOMAIN=\""nm-cloud-setup"\" \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(LIBCURL_CFLAGS) \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(NULL) -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_nm_cloud_setup_SOURCES = \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/main.c \ +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_nm_cloud_setup_SOURCES = \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/main.c \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(NULL) -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_nm_cloud_setup_CPPFLAGS = \ +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_nm_cloud_setup_CPPFLAGS = \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(clients_cppflags) \ -@BUILD_NM_CLOUD_SETUP_TRUE@ -DG_LOG_DOMAIN=\""nm-cloud-setup"\" \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(LIBCURL_CFLAGS) \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(NULL) -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_nm_cloud_setup_LDFLAGS = \ +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_nm_cloud_setup_LDFLAGS = \ @BUILD_NM_CLOUD_SETUP_TRUE@ -Wl,--version-script="$(srcdir)/linker-script-binary.ver" \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(SANITIZER_EXEC_LDFLAGS) \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(NULL) -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_nm_cloud_setup_LDADD = \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/libnm-cloud-setup-core.a \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm/nm-libnm-aux/libnm-libnm-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-base/libnm-base.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-glib-aux/libnm-glib-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-std-aux/libnm-std-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/libcsiphash.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm/libnm.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_nm_cloud_setup_LDADD = \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/libnm-cloud-setup-core.a \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-client-aux-extern/libnm-client-aux-extern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-core-aux-extern/libnm-core-aux-extern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-core-aux-intern/libnm-core-aux-intern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-base/libnm-base.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-glib-aux/libnm-glib-aux.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-std-aux/libnm-std-aux.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/c-siphash/libc-siphash.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-client-impl/libnm.la \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(GLIB_LIBS) \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(LIBCURL_LIBS) \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(NULL) -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS = \ +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS = \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(clients_cppflags) \ -@BUILD_NM_CLOUD_SETUP_TRUE@ -I$(srcdir)/clients/cloud-setup \ -@BUILD_NM_CLOUD_SETUP_TRUE@ -DG_LOG_DOMAIN=\""tests"\" \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(LIBCURL_CFLAGS) \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(NULL) -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_tests_test_cloud_setup_general_LDFLAGS = \ +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_tests_test_cloud_setup_general_LDFLAGS = \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(CODE_COVERAGE_LDFLAGS) \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(SANITIZER_EXEC_LDFLAGS) \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(NULL) -@BUILD_NM_CLOUD_SETUP_TRUE@clients_cloud_setup_tests_test_cloud_setup_general_LDADD = \ -@BUILD_NM_CLOUD_SETUP_TRUE@ clients/cloud-setup/libnm-cloud-setup-core.a \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm/nm-libnm-aux/libnm-libnm-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-base/libnm-base.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-glib-aux/libnm-glib-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/nm-std-aux/libnm-std-aux.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ shared/libcsiphash.la \ -@BUILD_NM_CLOUD_SETUP_TRUE@ libnm/libnm.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@src_nm_cloud_setup_tests_test_cloud_setup_general_LDADD = \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/nm-cloud-setup/libnm-cloud-setup-core.a \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-client-aux-extern/libnm-client-aux-extern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-core-aux-extern/libnm-core-aux-extern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-core-aux-intern/libnm-core-aux-intern.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-base/libnm-base.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-glib-aux/libnm-glib-aux.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-std-aux/libnm-std-aux.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/c-siphash/libc-siphash.la \ +@BUILD_NM_CLOUD_SETUP_TRUE@ src/libnm-client-impl/libnm.la \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(GLIB_LIBS) \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(LIBCURL_LIBS) \ @BUILD_NM_CLOUD_SETUP_TRUE@ $(NULL) @@ -8231,7 +8331,7 @@ man_nm_settings_xml = \ $(NULL) @ENABLE_VAPIGEN_TRUE@vapi_libnm_vapi_METADATADIRS = $(srcdir)/vapi -@ENABLE_VAPIGEN_TRUE@vapi_libnm_vapi_FILES = $(builddir)/libnm/NM-1.0.gir +@ENABLE_VAPIGEN_TRUE@vapi_libnm_vapi_FILES = $(builddir)/src/libnm-client-impl/NM-1.0.gir @ENABLE_VAPIGEN_TRUE@vapi_libnm_vapi_DEPS = gio-2.0 ############################################################################### @@ -8241,12 +8341,10 @@ typelibdir = $(libdir)/girepository-1.0 typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) dbusservicedir = $(DBUS_SYS_DIR) examples_C_glib_cppflags = \ - -I$(top_srcdir)/shared \ - -I$(top_builddir)/shared \ - -I$(top_srcdir)/libnm-core \ - -I$(top_builddir)/libnm-core \ - -I$(top_srcdir)/libnm \ - -I$(top_builddir)/libnm \ + -I$(top_srcdir)/src/libnm-core-public \ + -I$(top_builddir)/src/libnm-core-public \ + -I$(top_srcdir)/src/libnm-client-public \ + -I$(top_builddir)/src/libnm-client-public \ $(GLIB_CFLAGS) examples_C_glib_cppflags_gdbus = $(examples_C_glib_cppflags) @@ -8258,7 +8356,7 @@ examples_C_glib_add_connection_gdbus_LDADD = \ examples_C_glib_add_connection_libnm_CPPFLAGS = $(examples_C_glib_cppflags_libnm) examples_C_glib_add_connection_libnm_LDADD = \ - libnm/libnm.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) examples_C_glib_get_active_connections_gdbus_CPPFLAGS = $(examples_C_glib_cppflags_gdbus) @@ -8267,7 +8365,7 @@ examples_C_glib_get_active_connections_gdbus_LDADD = \ examples_C_glib_get_ap_info_libnm_CPPFLAGS = $(examples_C_glib_cppflags_libnm) examples_C_glib_get_ap_info_libnm_LDADD = \ - libnm/libnm.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) examples_C_glib_list_connections_gdbus_CPPFLAGS = $(examples_C_glib_cppflags_gdbus) @@ -8276,7 +8374,7 @@ examples_C_glib_list_connections_gdbus_LDADD = \ examples_C_glib_list_connections_libnm_CPPFLAGS = $(examples_C_glib_cppflags_libnm) examples_C_glib_list_connections_libnm_LDADD = \ - libnm/libnm.la \ + src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) examples_C_glib_monitor_nm_running_gdbus_CPPFLAGS = $(examples_C_glib_cppflags_gdbus) @@ -8287,13 +8385,20 @@ examples_C_glib_monitor_nm_state_gdbus_CPPFLAGS = $(examples_C_glib_cppflags_gdb examples_C_glib_monitor_nm_state_gdbus_LDADD = \ $(GLIB_LIBS) +examples_C_glib_vpn_import_libnm_CPPFLAGS = $(examples_C_glib_cppflags_libnm) +examples_C_glib_vpn_import_libnm_LDADD = \ + src/libnm-client-impl/libnm.la \ + $(GLIB_LIBS) + ############################################################################### # examples/C/qt ############################################################################### @WITH_QT_TRUE@examples_C_qt_cppflags = \ -@WITH_QT_TRUE@ -I$(top_srcdir)/libnm-core \ -@WITH_QT_TRUE@ -I$(top_builddir)/libnm-core \ +@WITH_QT_TRUE@ -I$(top_builddir)/src/libnm-core-public \ +@WITH_QT_TRUE@ -I$(top_srcdir)/src/libnm-core-public \ +@WITH_QT_TRUE@ -I$(top_builddir)/libnm \ +@WITH_QT_TRUE@ -I$(top_srcdir)/libnm \ @WITH_QT_TRUE@ -I$(builddir)/examples/C/qt \ @WITH_QT_TRUE@ $(DBUS_CFLAGS) \ @WITH_QT_TRUE@ $(QT_CFLAGS) @@ -8376,14 +8481,14 @@ $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) distclean-hdr: -rm -f config.h stamp-h1 -libnm-core/nm-version-macros.h: $(top_builddir)/config.status $(top_srcdir)/libnm-core/nm-version-macros.h.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -libnm/libnm.pc: $(top_builddir)/config.status $(top_srcdir)/libnm/libnm.pc.in - cd $(top_builddir) && $(SHELL) ./config.status $@ data/org.freedesktop.NetworkManager.policy.in: $(top_builddir)/config.status $(top_srcdir)/data/org.freedesktop.NetworkManager.policy.in.in cd $(top_builddir) && $(SHELL) ./config.status $@ NetworkManager.pc: $(top_builddir)/config.status $(srcdir)/NetworkManager.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ +src/libnm-client-impl/libnm.pc: $(top_builddir)/config.status $(top_srcdir)/src/libnm-client-impl/libnm.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +src/libnm-core-public/nm-version-macros.h: $(top_builddir)/config.status $(top_srcdir)/src/libnm-core-public/nm-version-macros.h.in + cd $(top_builddir) && $(SHELL) ./config.status $@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ @@ -8679,151 +8784,106 @@ clean-pppd_pluginLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } -clients/cloud-setup/$(am__dirstamp): - @$(MKDIR_P) clients/cloud-setup - @: > clients/cloud-setup/$(am__dirstamp) -clients/cloud-setup/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) clients/cloud-setup/$(DEPDIR) - @: > clients/cloud-setup/$(DEPDIR)/$(am__dirstamp) -clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.$(OBJEXT): \ - clients/cloud-setup/$(am__dirstamp) \ - clients/cloud-setup/$(DEPDIR)/$(am__dirstamp) -clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.$(OBJEXT): \ - clients/cloud-setup/$(am__dirstamp) \ - clients/cloud-setup/$(DEPDIR)/$(am__dirstamp) -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.$(OBJEXT): \ - clients/cloud-setup/$(am__dirstamp) \ - clients/cloud-setup/$(DEPDIR)/$(am__dirstamp) -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.$(OBJEXT): \ - clients/cloud-setup/$(am__dirstamp) \ - clients/cloud-setup/$(DEPDIR)/$(am__dirstamp) -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.$(OBJEXT): \ - clients/cloud-setup/$(am__dirstamp) \ - clients/cloud-setup/$(DEPDIR)/$(am__dirstamp) -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.$(OBJEXT): \ - clients/cloud-setup/$(am__dirstamp) \ - clients/cloud-setup/$(DEPDIR)/$(am__dirstamp) - -clients/cloud-setup/libnm-cloud-setup-core.a: $(clients_cloud_setup_libnm_cloud_setup_core_a_OBJECTS) $(clients_cloud_setup_libnm_cloud_setup_core_a_DEPENDENCIES) $(EXTRA_clients_cloud_setup_libnm_cloud_setup_core_a_DEPENDENCIES) clients/cloud-setup/$(am__dirstamp) - $(AM_V_at)-rm -f clients/cloud-setup/libnm-cloud-setup-core.a - $(AM_V_AR)$(clients_cloud_setup_libnm_cloud_setup_core_a_AR) clients/cloud-setup/libnm-cloud-setup-core.a $(clients_cloud_setup_libnm_cloud_setup_core_a_OBJECTS) $(clients_cloud_setup_libnm_cloud_setup_core_a_LIBADD) - $(AM_V_at)$(RANLIB) clients/cloud-setup/libnm-cloud-setup-core.a -clients/tui/newt/$(am__dirstamp): - @$(MKDIR_P) clients/tui/newt - @: > clients/tui/newt/$(am__dirstamp) -clients/tui/newt/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) clients/tui/newt/$(DEPDIR) - @: > clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-button.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-component.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-container.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-entry.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-form.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-grid.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-label.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-popup.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-section.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-separator.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-stack.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-utils.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) -clients/tui/newt/libnmt_newt_a-nmt-newt-widget.$(OBJEXT): \ - clients/tui/newt/$(am__dirstamp) \ - clients/tui/newt/$(DEPDIR)/$(am__dirstamp) - -clients/tui/newt/libnmt-newt.a: $(clients_tui_newt_libnmt_newt_a_OBJECTS) $(clients_tui_newt_libnmt_newt_a_DEPENDENCIES) $(EXTRA_clients_tui_newt_libnmt_newt_a_DEPENDENCIES) clients/tui/newt/$(am__dirstamp) - $(AM_V_at)-rm -f clients/tui/newt/libnmt-newt.a - $(AM_V_AR)$(clients_tui_newt_libnmt_newt_a_AR) clients/tui/newt/libnmt-newt.a $(clients_tui_newt_libnmt_newt_a_OBJECTS) $(clients_tui_newt_libnmt_newt_a_LIBADD) - $(AM_V_at)$(RANLIB) clients/tui/newt/libnmt-newt.a -clients/common/$(am__dirstamp): - @$(MKDIR_P) clients/common - @: > clients/common/$(am__dirstamp) -clients/common/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) clients/common/$(DEPDIR) - @: > clients/common/$(DEPDIR)/$(am__dirstamp) -clients/common/libnmc_base_la-nm-secret-agent-simple.lo: \ - clients/common/$(am__dirstamp) \ - clients/common/$(DEPDIR)/$(am__dirstamp) -clients/common/libnmc_base_la-nm-vpn-helpers.lo: \ - clients/common/$(am__dirstamp) \ - clients/common/$(DEPDIR)/$(am__dirstamp) -clients/common/libnmc_base_la-nm-client-utils.lo: \ - clients/common/$(am__dirstamp) \ - clients/common/$(DEPDIR)/$(am__dirstamp) -clients/common/libnmc_base_la-nm-polkit-listener.lo: \ - clients/common/$(am__dirstamp) \ - clients/common/$(DEPDIR)/$(am__dirstamp) - -clients/common/libnmc-base.la: $(clients_common_libnmc_base_la_OBJECTS) $(clients_common_libnmc_base_la_DEPENDENCIES) $(EXTRA_clients_common_libnmc_base_la_DEPENDENCIES) clients/common/$(am__dirstamp) - $(AM_V_CCLD)$(LINK) $(am_clients_common_libnmc_base_la_rpath) $(clients_common_libnmc_base_la_OBJECTS) $(clients_common_libnmc_base_la_LIBADD) $(LIBS) -clients/common/libnmc_la-nm-meta-setting-base-impl.lo: \ - clients/common/$(am__dirstamp) \ - clients/common/$(DEPDIR)/$(am__dirstamp) -clients/common/libnmc_la-nm-meta-setting-desc.lo: \ - clients/common/$(am__dirstamp) \ - clients/common/$(DEPDIR)/$(am__dirstamp) -clients/common/libnmc_la-nm-meta-setting-access.lo: \ - clients/common/$(am__dirstamp) \ - clients/common/$(DEPDIR)/$(am__dirstamp) - -clients/common/libnmc.la: $(clients_common_libnmc_la_OBJECTS) $(clients_common_libnmc_la_DEPENDENCIES) $(EXTRA_clients_common_libnmc_la_DEPENDENCIES) clients/common/$(am__dirstamp) - $(AM_V_CCLD)$(LINK) $(am_clients_common_libnmc_la_rpath) $(clients_common_libnmc_la_OBJECTS) $(clients_common_libnmc_la_LIBADD) $(LIBS) -dispatcher/$(am__dirstamp): - @$(MKDIR_P) dispatcher - @: > dispatcher/$(am__dirstamp) -dispatcher/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) dispatcher/$(DEPDIR) - @: > dispatcher/$(DEPDIR)/$(am__dirstamp) -dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo: \ - dispatcher/$(am__dirstamp) \ - dispatcher/$(DEPDIR)/$(am__dirstamp) - -dispatcher/libnm-dispatcher-core.la: $(dispatcher_libnm_dispatcher_core_la_OBJECTS) $(dispatcher_libnm_dispatcher_core_la_DEPENDENCIES) $(EXTRA_dispatcher_libnm_dispatcher_core_la_DEPENDENCIES) dispatcher/$(am__dirstamp) - $(AM_V_CCLD)$(LINK) $(dispatcher_libnm_dispatcher_core_la_OBJECTS) $(dispatcher_libnm_dispatcher_core_la_LIBADD) $(LIBS) +src/libnmt-newt/$(am__dirstamp): + @$(MKDIR_P) src/libnmt-newt + @: > src/libnmt-newt/$(am__dirstamp) +src/libnmt-newt/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnmt-newt/$(DEPDIR) + @: > src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-button.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-component.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-container.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-form.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-label.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-section.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) +src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.$(OBJEXT): \ + src/libnmt-newt/$(am__dirstamp) \ + src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) + +src/libnmt-newt/libnmt-newt.a: $(src_libnmt_newt_libnmt_newt_a_OBJECTS) $(src_libnmt_newt_libnmt_newt_a_DEPENDENCIES) $(EXTRA_src_libnmt_newt_libnmt_newt_a_DEPENDENCIES) src/libnmt-newt/$(am__dirstamp) + $(AM_V_at)-rm -f src/libnmt-newt/libnmt-newt.a + $(AM_V_AR)$(src_libnmt_newt_libnmt_newt_a_AR) src/libnmt-newt/libnmt-newt.a $(src_libnmt_newt_libnmt_newt_a_OBJECTS) $(src_libnmt_newt_libnmt_newt_a_LIBADD) + $(AM_V_at)$(RANLIB) src/libnmt-newt/libnmt-newt.a +src/nm-cloud-setup/$(am__dirstamp): + @$(MKDIR_P) src/nm-cloud-setup + @: > src/nm-cloud-setup/$(am__dirstamp) +src/nm-cloud-setup/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nm-cloud-setup/$(DEPDIR) + @: > src/nm-cloud-setup/$(DEPDIR)/$(am__dirstamp) +src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.$(OBJEXT): \ + src/nm-cloud-setup/$(am__dirstamp) \ + src/nm-cloud-setup/$(DEPDIR)/$(am__dirstamp) +src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.$(OBJEXT): \ + src/nm-cloud-setup/$(am__dirstamp) \ + src/nm-cloud-setup/$(DEPDIR)/$(am__dirstamp) +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.$(OBJEXT): \ + src/nm-cloud-setup/$(am__dirstamp) \ + src/nm-cloud-setup/$(DEPDIR)/$(am__dirstamp) +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.$(OBJEXT): \ + src/nm-cloud-setup/$(am__dirstamp) \ + src/nm-cloud-setup/$(DEPDIR)/$(am__dirstamp) +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.$(OBJEXT): \ + src/nm-cloud-setup/$(am__dirstamp) \ + src/nm-cloud-setup/$(DEPDIR)/$(am__dirstamp) +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.$(OBJEXT): \ + src/nm-cloud-setup/$(am__dirstamp) \ + src/nm-cloud-setup/$(DEPDIR)/$(am__dirstamp) + +src/nm-cloud-setup/libnm-cloud-setup-core.a: $(src_nm_cloud_setup_libnm_cloud_setup_core_a_OBJECTS) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_DEPENDENCIES) $(EXTRA_src_nm_cloud_setup_libnm_cloud_setup_core_a_DEPENDENCIES) src/nm-cloud-setup/$(am__dirstamp) + $(AM_V_at)-rm -f src/nm-cloud-setup/libnm-cloud-setup-core.a + $(AM_V_AR)$(src_nm_cloud_setup_libnm_cloud_setup_core_a_AR) src/nm-cloud-setup/libnm-cloud-setup-core.a $(src_nm_cloud_setup_libnm_cloud_setup_core_a_OBJECTS) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_LIBADD) + $(AM_V_at)$(RANLIB) src/nm-cloud-setup/libnm-cloud-setup-core.a introspection/$(am__dirstamp): @$(MKDIR_P) introspection @: > introspection/$(am__dirstamp) @@ -8977,752 +9037,51 @@ introspection/libnmdbus_la-org.freedesktop.NetworkManager.lo: \ introspection/libnmdbus.la: $(introspection_libnmdbus_la_OBJECTS) $(introspection_libnmdbus_la_DEPENDENCIES) $(EXTRA_introspection_libnmdbus_la_DEPENDENCIES) introspection/$(am__dirstamp) $(AM_V_CCLD)$(LINK) $(introspection_libnmdbus_la_OBJECTS) $(introspection_libnmdbus_la_LIBADD) $(LIBS) -libnm-core/$(am__dirstamp): - @$(MKDIR_P) libnm-core - @: > libnm-core/$(am__dirstamp) -libnm-core/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) libnm-core/$(DEPDIR) - @: > libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-6lowpan.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-8021x.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-adsl.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-bluetooth.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-bond.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-bridge-port.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-bridge.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-cdma.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-connection.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-dcb.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-dummy.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ethtool.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-generic.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-gsm.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-hostname.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-infiniband.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ip-config.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ip-tunnel.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ip4-config.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ip6-config.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-macsec.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-macvlan.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-match.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-olpc-mesh.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ovs-bridge.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ovs-dpdk.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ovs-external-ids.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ovs-interface.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ovs-patch.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ovs-port.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-ppp.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-pppoe.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-proxy.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-serial.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-sriov.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-tc-config.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-team-port.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-team.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-tun.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-user.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-veth.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-vlan.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-vpn.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-vrf.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-vxlan.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-wifi-p2p.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-wimax.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-wired.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-wireguard.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-wireless-security.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-wireless.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting-wpan.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-connection.lo: libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-crypto.lo: libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-dbus-utils.lo: libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-errors.lo: libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-keyfile-utils.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-keyfile.lo: libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-meta-setting-base-impl.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-property-compare.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-setting.lo: libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-simple-connection.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-team-utils.lo: libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-utils.lo: libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-vpn-editor-plugin.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-vpn-plugin-info.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) -libnm-core/libnm_core_la-nm-core-enum-types.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) - -libnm-core/libnm-core.la: $(libnm_core_libnm_core_la_OBJECTS) $(libnm_core_libnm_core_la_DEPENDENCIES) $(EXTRA_libnm_core_libnm_core_la_DEPENDENCIES) libnm-core/$(am__dirstamp) - $(AM_V_CCLD)$(libnm_core_libnm_core_la_LINK) $(libnm_core_libnm_core_la_OBJECTS) $(libnm_core_libnm_core_la_LIBADD) $(LIBS) -libnm-core/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) - -libnm-core/libnm-crypto-gnutls.la: $(libnm_core_libnm_crypto_gnutls_la_OBJECTS) $(libnm_core_libnm_crypto_gnutls_la_DEPENDENCIES) $(EXTRA_libnm_core_libnm_crypto_gnutls_la_DEPENDENCIES) libnm-core/$(am__dirstamp) - $(AM_V_CCLD)$(libnm_core_libnm_crypto_gnutls_la_LINK) $(am_libnm_core_libnm_crypto_gnutls_la_rpath) $(libnm_core_libnm_crypto_gnutls_la_OBJECTS) $(libnm_core_libnm_crypto_gnutls_la_LIBADD) $(LIBS) -libnm-core/libnm_crypto_nss_la-nm-crypto-nss.lo: \ - libnm-core/$(am__dirstamp) \ - libnm-core/$(DEPDIR)/$(am__dirstamp) - -libnm-core/libnm-crypto-nss.la: $(libnm_core_libnm_crypto_nss_la_OBJECTS) $(libnm_core_libnm_crypto_nss_la_DEPENDENCIES) $(EXTRA_libnm_core_libnm_crypto_nss_la_DEPENDENCIES) libnm-core/$(am__dirstamp) - $(AM_V_CCLD)$(libnm_core_libnm_crypto_nss_la_LINK) $(am_libnm_core_libnm_crypto_nss_la_rpath) $(libnm_core_libnm_crypto_nss_la_OBJECTS) $(libnm_core_libnm_crypto_nss_la_LIBADD) $(LIBS) -libnm-core/nm-libnm-core-aux/$(am__dirstamp): - @$(MKDIR_P) libnm-core/nm-libnm-core-aux - @: > libnm-core/nm-libnm-core-aux/$(am__dirstamp) -libnm-core/nm-libnm-core-aux/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) libnm-core/nm-libnm-core-aux/$(DEPDIR) - @: > libnm-core/nm-libnm-core-aux/$(DEPDIR)/$(am__dirstamp) -libnm-core/nm-libnm-core-aux/libnm_libnm_core_aux_la-nm-libnm-core-aux.lo: \ - libnm-core/nm-libnm-core-aux/$(am__dirstamp) \ - libnm-core/nm-libnm-core-aux/$(DEPDIR)/$(am__dirstamp) - -libnm-core/nm-libnm-core-aux/libnm-libnm-core-aux.la: $(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_OBJECTS) $(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_DEPENDENCIES) $(EXTRA_libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_DEPENDENCIES) libnm-core/nm-libnm-core-aux/$(am__dirstamp) - $(AM_V_CCLD)$(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_LINK) $(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_OBJECTS) $(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_LIBADD) $(LIBS) -libnm-core/nm-libnm-core-intern/$(am__dirstamp): - @$(MKDIR_P) libnm-core/nm-libnm-core-intern - @: > libnm-core/nm-libnm-core-intern/$(am__dirstamp) -libnm-core/nm-libnm-core-intern/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) libnm-core/nm-libnm-core-intern/$(DEPDIR) - @: > libnm-core/nm-libnm-core-intern/$(DEPDIR)/$(am__dirstamp) -libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-auth-subject.lo: \ - libnm-core/nm-libnm-core-intern/$(am__dirstamp) \ - libnm-core/nm-libnm-core-intern/$(DEPDIR)/$(am__dirstamp) -libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-libnm-core-utils.lo: \ - libnm-core/nm-libnm-core-intern/$(am__dirstamp) \ - libnm-core/nm-libnm-core-intern/$(DEPDIR)/$(am__dirstamp) - -libnm-core/nm-libnm-core-intern/libnm-libnm-core-intern.la: $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_OBJECTS) $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_DEPENDENCIES) $(EXTRA_libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_DEPENDENCIES) libnm-core/nm-libnm-core-intern/$(am__dirstamp) - $(AM_V_CCLD)$(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_LINK) $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_OBJECTS) $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_LIBADD) $(LIBS) -libnm/$(am__dirstamp): - @$(MKDIR_P) libnm - @: > libnm/$(am__dirstamp) - -libnm/libnm.la: $(libnm_libnm_la_OBJECTS) $(libnm_libnm_la_DEPENDENCIES) $(EXTRA_libnm_libnm_la_DEPENDENCIES) libnm/$(am__dirstamp) - $(AM_V_CCLD)$(libnm_libnm_la_LINK) -rpath $(libdir) $(libnm_libnm_la_OBJECTS) $(libnm_libnm_la_LIBADD) $(LIBS) -libnm/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) libnm/$(DEPDIR) - @: > libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-client.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-object.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-active-connection.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-access-point.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-checkpoint.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-dbus-helpers.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-6lowpan.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-adsl.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-bond.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-bridge.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-bt.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-dummy.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-ethernet.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-generic.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-infiniband.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-ip-tunnel.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-macsec.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-macvlan.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-modem.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-olpc-mesh.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-ovs-bridge.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-ovs-interface.lo: \ - libnm/$(am__dirstamp) libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-ovs-port.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-ppp.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-team.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-tun.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-veth.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-vlan.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-vrf.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-vxlan.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-wifi-p2p.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-wifi.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-wimax.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-wireguard.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-device-wpan.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-dhcp-config.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-dhcp4-config.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-dhcp6-config.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-dns-manager.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-ip-config.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-ip4-config.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-ip6-config.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-libnm-utils.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-remote-connection.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-secret-agent-old.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-vpn-connection.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-vpn-editor.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-vpn-plugin-old.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-vpn-service-plugin.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-wifi-p2p-peer.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-wimax-nsp.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) -libnm/libnm_static_la-nm-enum-types.lo: libnm/$(am__dirstamp) \ - libnm/$(DEPDIR)/$(am__dirstamp) - -libnm/libnm_static.la: $(libnm_libnm_static_la_OBJECTS) $(libnm_libnm_static_la_DEPENDENCIES) $(EXTRA_libnm_libnm_static_la_DEPENDENCIES) libnm/$(am__dirstamp) - $(AM_V_CCLD)$(LINK) $(libnm_libnm_static_la_OBJECTS) $(libnm_libnm_static_la_LIBADD) $(LIBS) -libnm/nm-libnm-aux/$(am__dirstamp): - @$(MKDIR_P) libnm/nm-libnm-aux - @: > libnm/nm-libnm-aux/$(am__dirstamp) -libnm/nm-libnm-aux/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) libnm/nm-libnm-aux/$(DEPDIR) - @: > libnm/nm-libnm-aux/$(DEPDIR)/$(am__dirstamp) -libnm/nm-libnm-aux/libnm_libnm_aux_la-nm-libnm-aux.lo: \ - libnm/nm-libnm-aux/$(am__dirstamp) \ - libnm/nm-libnm-aux/$(DEPDIR)/$(am__dirstamp) - -libnm/nm-libnm-aux/libnm-libnm-aux.la: $(libnm_nm_libnm_aux_libnm_libnm_aux_la_OBJECTS) $(libnm_nm_libnm_aux_libnm_libnm_aux_la_DEPENDENCIES) $(EXTRA_libnm_nm_libnm_aux_libnm_libnm_aux_la_DEPENDENCIES) libnm/nm-libnm-aux/$(am__dirstamp) - $(AM_V_CCLD)$(libnm_nm_libnm_aux_libnm_libnm_aux_la_LINK) $(libnm_nm_libnm_aux_libnm_libnm_aux_la_OBJECTS) $(libnm_nm_libnm_aux_libnm_libnm_aux_la_LIBADD) $(LIBS) -shared/nm-utils/$(am__dirstamp): - @$(MKDIR_P) shared/nm-utils - @: > shared/nm-utils/$(am__dirstamp) -shared/nm-utils/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/nm-utils/$(DEPDIR) - @: > shared/nm-utils/$(DEPDIR)/$(am__dirstamp) -shared/nm-utils/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo: \ - shared/nm-utils/$(am__dirstamp) \ - shared/nm-utils/$(DEPDIR)/$(am__dirstamp) -libnm/tests/$(am__dirstamp): - @$(MKDIR_P) libnm/tests - @: > libnm/tests/$(am__dirstamp) - -libnm/tests/libnm-vpn-plugin-utils-test.la: $(libnm_tests_libnm_vpn_plugin_utils_test_la_OBJECTS) $(libnm_tests_libnm_vpn_plugin_utils_test_la_DEPENDENCIES) $(EXTRA_libnm_tests_libnm_vpn_plugin_utils_test_la_DEPENDENCIES) libnm/tests/$(am__dirstamp) - $(AM_V_CCLD)$(libnm_tests_libnm_vpn_plugin_utils_test_la_LINK) $(am_libnm_tests_libnm_vpn_plugin_utils_test_la_rpath) $(libnm_tests_libnm_vpn_plugin_utils_test_la_OBJECTS) $(libnm_tests_libnm_vpn_plugin_utils_test_la_LIBADD) $(LIBS) -shared/c-rbtree/src/$(am__dirstamp): - @$(MKDIR_P) shared/c-rbtree/src - @: > shared/c-rbtree/src/$(am__dirstamp) -shared/c-rbtree/src/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/c-rbtree/src/$(DEPDIR) - @: > shared/c-rbtree/src/$(DEPDIR)/$(am__dirstamp) -shared/c-rbtree/src/libcrbtree_la-c-rbtree.lo: \ - shared/c-rbtree/src/$(am__dirstamp) \ - shared/c-rbtree/src/$(DEPDIR)/$(am__dirstamp) -shared/$(am__dirstamp): - @$(MKDIR_P) shared - @: > shared/$(am__dirstamp) - -shared/libcrbtree.la: $(shared_libcrbtree_la_OBJECTS) $(shared_libcrbtree_la_DEPENDENCIES) $(EXTRA_shared_libcrbtree_la_DEPENDENCIES) shared/$(am__dirstamp) - $(AM_V_CCLD)$(shared_libcrbtree_la_LINK) $(shared_libcrbtree_la_OBJECTS) $(shared_libcrbtree_la_LIBADD) $(LIBS) -shared/c-siphash/src/$(am__dirstamp): - @$(MKDIR_P) shared/c-siphash/src - @: > shared/c-siphash/src/$(am__dirstamp) -shared/c-siphash/src/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/c-siphash/src/$(DEPDIR) - @: > shared/c-siphash/src/$(DEPDIR)/$(am__dirstamp) -shared/c-siphash/src/libcsiphash_la-c-siphash.lo: \ - shared/c-siphash/src/$(am__dirstamp) \ - shared/c-siphash/src/$(DEPDIR)/$(am__dirstamp) - -shared/libcsiphash.la: $(shared_libcsiphash_la_OBJECTS) $(shared_libcsiphash_la_DEPENDENCIES) $(EXTRA_shared_libcsiphash_la_DEPENDENCIES) shared/$(am__dirstamp) - $(AM_V_CCLD)$(shared_libcsiphash_la_LINK) $(shared_libcsiphash_la_OBJECTS) $(shared_libcsiphash_la_LIBADD) $(LIBS) -shared/n-acd/src/$(am__dirstamp): - @$(MKDIR_P) shared/n-acd/src - @: > shared/n-acd/src/$(am__dirstamp) -shared/n-acd/src/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/n-acd/src/$(DEPDIR) - @: > shared/n-acd/src/$(DEPDIR)/$(am__dirstamp) -shared/n-acd/src/libnacd_la-n-acd.lo: \ - shared/n-acd/src/$(am__dirstamp) \ - shared/n-acd/src/$(DEPDIR)/$(am__dirstamp) -shared/n-acd/src/libnacd_la-n-acd-probe.lo: \ - shared/n-acd/src/$(am__dirstamp) \ - shared/n-acd/src/$(DEPDIR)/$(am__dirstamp) -shared/n-acd/src/util/$(am__dirstamp): - @$(MKDIR_P) shared/n-acd/src/util - @: > shared/n-acd/src/util/$(am__dirstamp) -shared/n-acd/src/util/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/n-acd/src/util/$(DEPDIR) - @: > shared/n-acd/src/util/$(DEPDIR)/$(am__dirstamp) -shared/n-acd/src/util/libnacd_la-timer.lo: \ - shared/n-acd/src/util/$(am__dirstamp) \ - shared/n-acd/src/util/$(DEPDIR)/$(am__dirstamp) -shared/n-acd/src/libnacd_la-n-acd-bpf.lo: \ - shared/n-acd/src/$(am__dirstamp) \ - shared/n-acd/src/$(DEPDIR)/$(am__dirstamp) -shared/n-acd/src/libnacd_la-n-acd-bpf-fallback.lo: \ - shared/n-acd/src/$(am__dirstamp) \ - shared/n-acd/src/$(DEPDIR)/$(am__dirstamp) - -shared/libnacd.la: $(shared_libnacd_la_OBJECTS) $(shared_libnacd_la_DEPENDENCIES) $(EXTRA_shared_libnacd_la_DEPENDENCIES) shared/$(am__dirstamp) - $(AM_V_CCLD)$(shared_libnacd_la_LINK) $(shared_libnacd_la_OBJECTS) $(shared_libnacd_la_LIBADD) $(LIBS) -shared/n-dhcp4/src/$(am__dirstamp): - @$(MKDIR_P) shared/n-dhcp4/src - @: > shared/n-dhcp4/src/$(am__dirstamp) -shared/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/n-dhcp4/src/$(DEPDIR) - @: > shared/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-connection.lo: \ - shared/n-dhcp4/src/$(am__dirstamp) \ - shared/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-lease.lo: \ - shared/n-dhcp4/src/$(am__dirstamp) \ - shared/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-probe.lo: \ - shared/n-dhcp4/src/$(am__dirstamp) \ - shared/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-client.lo: \ - shared/n-dhcp4/src/$(am__dirstamp) \ - shared/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-incoming.lo: \ - shared/n-dhcp4/src/$(am__dirstamp) \ - shared/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-outgoing.lo: \ - shared/n-dhcp4/src/$(am__dirstamp) \ - shared/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-socket.lo: \ - shared/n-dhcp4/src/$(am__dirstamp) \ - shared/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) -shared/n-dhcp4/src/util/$(am__dirstamp): - @$(MKDIR_P) shared/n-dhcp4/src/util - @: > shared/n-dhcp4/src/util/$(am__dirstamp) -shared/n-dhcp4/src/util/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/n-dhcp4/src/util/$(DEPDIR) - @: > shared/n-dhcp4/src/util/$(DEPDIR)/$(am__dirstamp) -shared/n-dhcp4/src/util/libndhcp4_la-packet.lo: \ - shared/n-dhcp4/src/util/$(am__dirstamp) \ - shared/n-dhcp4/src/util/$(DEPDIR)/$(am__dirstamp) -shared/n-dhcp4/src/util/libndhcp4_la-socket.lo: \ - shared/n-dhcp4/src/util/$(am__dirstamp) \ - shared/n-dhcp4/src/util/$(DEPDIR)/$(am__dirstamp) - -shared/libndhcp4.la: $(shared_libndhcp4_la_OBJECTS) $(shared_libndhcp4_la_DEPENDENCIES) $(EXTRA_shared_libndhcp4_la_DEPENDENCIES) shared/$(am__dirstamp) - $(AM_V_CCLD)$(shared_libndhcp4_la_LINK) $(shared_libndhcp4_la_OBJECTS) $(shared_libndhcp4_la_LIBADD) $(LIBS) -shared/nm-base/$(am__dirstamp): - @$(MKDIR_P) shared/nm-base - @: > shared/nm-base/$(am__dirstamp) -shared/nm-base/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/nm-base/$(DEPDIR) - @: > shared/nm-base/$(DEPDIR)/$(am__dirstamp) -shared/nm-base/libnm_base_la-nm-ethtool-base.lo: \ - shared/nm-base/$(am__dirstamp) \ - shared/nm-base/$(DEPDIR)/$(am__dirstamp) - -shared/nm-base/libnm-base.la: $(shared_nm_base_libnm_base_la_OBJECTS) $(shared_nm_base_libnm_base_la_DEPENDENCIES) $(EXTRA_shared_nm_base_libnm_base_la_DEPENDENCIES) shared/nm-base/$(am__dirstamp) - $(AM_V_CCLD)$(shared_nm_base_libnm_base_la_LINK) $(shared_nm_base_libnm_base_la_OBJECTS) $(shared_nm_base_libnm_base_la_LIBADD) $(LIBS) -shared/nm-glib-aux/$(am__dirstamp): - @$(MKDIR_P) shared/nm-glib-aux - @: > shared/nm-glib-aux/$(am__dirstamp) -shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/nm-glib-aux/$(DEPDIR) - @: > shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-errno.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo: \ - shared/nm-glib-aux/$(am__dirstamp) \ - shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) - -shared/nm-glib-aux/libnm-glib-aux.la: $(shared_nm_glib_aux_libnm_glib_aux_la_OBJECTS) $(shared_nm_glib_aux_libnm_glib_aux_la_DEPENDENCIES) $(EXTRA_shared_nm_glib_aux_libnm_glib_aux_la_DEPENDENCIES) shared/nm-glib-aux/$(am__dirstamp) - $(AM_V_CCLD)$(shared_nm_glib_aux_libnm_glib_aux_la_LINK) $(shared_nm_glib_aux_libnm_glib_aux_la_OBJECTS) $(shared_nm_glib_aux_libnm_glib_aux_la_LIBADD) $(LIBS) -shared/nm-log-core/$(am__dirstamp): - @$(MKDIR_P) shared/nm-log-core - @: > shared/nm-log-core/$(am__dirstamp) -shared/nm-log-core/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/nm-log-core/$(DEPDIR) - @: > shared/nm-log-core/$(DEPDIR)/$(am__dirstamp) -shared/nm-log-core/libnm_log_core_la-nm-logging.lo: \ - shared/nm-log-core/$(am__dirstamp) \ - shared/nm-log-core/$(DEPDIR)/$(am__dirstamp) - -shared/nm-log-core/libnm-log-core.la: $(shared_nm_log_core_libnm_log_core_la_OBJECTS) $(shared_nm_log_core_libnm_log_core_la_DEPENDENCIES) $(EXTRA_shared_nm_log_core_libnm_log_core_la_DEPENDENCIES) shared/nm-log-core/$(am__dirstamp) - $(AM_V_CCLD)$(shared_nm_log_core_libnm_log_core_la_LINK) $(shared_nm_log_core_libnm_log_core_la_OBJECTS) $(shared_nm_log_core_libnm_log_core_la_LIBADD) $(LIBS) -shared/nm-platform/$(am__dirstamp): - @$(MKDIR_P) shared/nm-platform - @: > shared/nm-platform/$(am__dirstamp) -shared/nm-platform/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/nm-platform/$(DEPDIR) - @: > shared/nm-platform/$(DEPDIR)/$(am__dirstamp) -shared/nm-platform/libnm_platform_la-nm-netlink.lo: \ - shared/nm-platform/$(am__dirstamp) \ - shared/nm-platform/$(DEPDIR)/$(am__dirstamp) -shared/nm-platform/libnm_platform_la-nm-platform-utils.lo: \ - shared/nm-platform/$(am__dirstamp) \ - shared/nm-platform/$(DEPDIR)/$(am__dirstamp) -shared/nm-platform/libnm_platform_la-nmp-netns.lo: \ - shared/nm-platform/$(am__dirstamp) \ - shared/nm-platform/$(DEPDIR)/$(am__dirstamp) - -shared/nm-platform/libnm-platform.la: $(shared_nm_platform_libnm_platform_la_OBJECTS) $(shared_nm_platform_libnm_platform_la_DEPENDENCIES) $(EXTRA_shared_nm_platform_libnm_platform_la_DEPENDENCIES) shared/nm-platform/$(am__dirstamp) - $(AM_V_CCLD)$(shared_nm_platform_libnm_platform_la_LINK) $(shared_nm_platform_libnm_platform_la_OBJECTS) $(shared_nm_platform_libnm_platform_la_LIBADD) $(LIBS) -shared/nm-std-aux/$(am__dirstamp): - @$(MKDIR_P) shared/nm-std-aux - @: > shared/nm-std-aux/$(am__dirstamp) -shared/nm-std-aux/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/nm-std-aux/$(DEPDIR) - @: > shared/nm-std-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-std-aux/libnm_std_aux_la-c-list-util.lo: \ - shared/nm-std-aux/$(am__dirstamp) \ - shared/nm-std-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-std-aux/libnm_std_aux_la-nm-std-utils.lo: \ - shared/nm-std-aux/$(am__dirstamp) \ - shared/nm-std-aux/$(DEPDIR)/$(am__dirstamp) - -shared/nm-std-aux/libnm-std-aux.la: $(shared_nm_std_aux_libnm_std_aux_la_OBJECTS) $(shared_nm_std_aux_libnm_std_aux_la_DEPENDENCIES) $(EXTRA_shared_nm_std_aux_libnm_std_aux_la_DEPENDENCIES) shared/nm-std-aux/$(am__dirstamp) - $(AM_V_CCLD)$(shared_nm_std_aux_libnm_std_aux_la_LINK) $(shared_nm_std_aux_libnm_std_aux_la_OBJECTS) $(shared_nm_std_aux_libnm_std_aux_la_LIBADD) $(LIBS) -shared/nm-udev-aux/$(am__dirstamp): - @$(MKDIR_P) shared/nm-udev-aux - @: > shared/nm-udev-aux/$(am__dirstamp) -shared/nm-udev-aux/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/nm-udev-aux/$(DEPDIR) - @: > shared/nm-udev-aux/$(DEPDIR)/$(am__dirstamp) -shared/nm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo: \ - shared/nm-udev-aux/$(am__dirstamp) \ - shared/nm-udev-aux/$(DEPDIR)/$(am__dirstamp) - -shared/nm-udev-aux/libnm-udev-aux.la: $(shared_nm_udev_aux_libnm_udev_aux_la_OBJECTS) $(shared_nm_udev_aux_libnm_udev_aux_la_DEPENDENCIES) $(EXTRA_shared_nm_udev_aux_libnm_udev_aux_la_DEPENDENCIES) shared/nm-udev-aux/$(am__dirstamp) - $(AM_V_CCLD)$(shared_nm_udev_aux_libnm_udev_aux_la_LINK) $(shared_nm_udev_aux_libnm_udev_aux_la_OBJECTS) $(shared_nm_udev_aux_libnm_udev_aux_la_LIBADD) $(LIBS) -shared/systemd/$(am__dirstamp): - @$(MKDIR_P) shared/systemd - @: > shared/systemd/$(am__dirstamp) -shared/systemd/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/systemd/$(DEPDIR) - @: > shared/systemd/$(DEPDIR)/$(am__dirstamp) -shared/systemd/libnm_systemd_logging_stub_la-nm-logging-stub.lo: \ - shared/systemd/$(am__dirstamp) \ - shared/systemd/$(DEPDIR)/$(am__dirstamp) - -shared/systemd/libnm-systemd-logging-stub.la: $(shared_systemd_libnm_systemd_logging_stub_la_OBJECTS) $(shared_systemd_libnm_systemd_logging_stub_la_DEPENDENCIES) $(EXTRA_shared_systemd_libnm_systemd_logging_stub_la_DEPENDENCIES) shared/systemd/$(am__dirstamp) - $(AM_V_CCLD)$(LINK) $(shared_systemd_libnm_systemd_logging_stub_la_OBJECTS) $(shared_systemd_libnm_systemd_logging_stub_la_LIBADD) $(LIBS) -shared/systemd/libnm_systemd_shared_la-nm-sd-utils-shared.lo: \ - shared/systemd/$(am__dirstamp) \ - shared/systemd/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/$(am__dirstamp): - @$(MKDIR_P) shared/systemd/src/basic - @: > shared/systemd/src/basic/$(am__dirstamp) -shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/systemd/src/basic/$(DEPDIR) - @: > shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-alloc-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-env-file.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-env-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-escape.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-ether-addr-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-extract-word.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-fd-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-fileio.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-format-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-fs-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-hash-funcs.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-hashmap.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-hexdecoct.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-hostname-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-in-addr-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-io-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-memory-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-mempool.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-parse-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-path-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-prioq.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-process-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-random-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-ratelimit.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-signal-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-socket-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-stat-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-string-table.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-string-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-strv.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-strxcpyx.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-time-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-tmpfile-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-utf8.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/basic/libnm_systemd_shared_la-util.lo: \ - shared/systemd/src/basic/$(am__dirstamp) \ - shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/shared/$(am__dirstamp): - @$(MKDIR_P) shared/systemd/src/shared - @: > shared/systemd/src/shared/$(am__dirstamp) -shared/systemd/src/shared/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/systemd/src/shared/$(DEPDIR) - @: > shared/systemd/src/shared/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/shared/libnm_systemd_shared_la-dns-domain.lo: \ - shared/systemd/src/shared/$(am__dirstamp) \ - shared/systemd/src/shared/$(DEPDIR)/$(am__dirstamp) -shared/systemd/src/shared/libnm_systemd_shared_la-web-util.lo: \ - shared/systemd/src/shared/$(am__dirstamp) \ - shared/systemd/src/shared/$(DEPDIR)/$(am__dirstamp) - -shared/systemd/libnm-systemd-shared.la: $(shared_systemd_libnm_systemd_shared_la_OBJECTS) $(shared_systemd_libnm_systemd_shared_la_DEPENDENCIES) $(EXTRA_shared_systemd_libnm_systemd_shared_la_DEPENDENCIES) shared/systemd/$(am__dirstamp) - $(AM_V_CCLD)$(LINK) $(shared_systemd_libnm_systemd_shared_la_OBJECTS) $(shared_systemd_libnm_systemd_shared_la_LIBADD) $(LIBS) +src/c-rbtree/src/$(am__dirstamp): + @$(MKDIR_P) src/c-rbtree/src + @: > src/c-rbtree/src/$(am__dirstamp) +src/c-rbtree/src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/c-rbtree/src/$(DEPDIR) + @: > src/c-rbtree/src/$(DEPDIR)/$(am__dirstamp) +src/c-rbtree/src/libc_rbtree_la-c-rbtree.lo: \ + src/c-rbtree/src/$(am__dirstamp) \ + src/c-rbtree/src/$(DEPDIR)/$(am__dirstamp) +src/c-rbtree/$(am__dirstamp): + @$(MKDIR_P) src/c-rbtree + @: > src/c-rbtree/$(am__dirstamp) + +src/c-rbtree/libc-rbtree.la: $(src_c_rbtree_libc_rbtree_la_OBJECTS) $(src_c_rbtree_libc_rbtree_la_DEPENDENCIES) $(EXTRA_src_c_rbtree_libc_rbtree_la_DEPENDENCIES) src/c-rbtree/$(am__dirstamp) + $(AM_V_CCLD)$(src_c_rbtree_libc_rbtree_la_LINK) $(src_c_rbtree_libc_rbtree_la_OBJECTS) $(src_c_rbtree_libc_rbtree_la_LIBADD) $(LIBS) +src/c-siphash/src/$(am__dirstamp): + @$(MKDIR_P) src/c-siphash/src + @: > src/c-siphash/src/$(am__dirstamp) +src/c-siphash/src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/c-siphash/src/$(DEPDIR) + @: > src/c-siphash/src/$(DEPDIR)/$(am__dirstamp) +src/c-siphash/src/libc_siphash_la-c-siphash.lo: \ + src/c-siphash/src/$(am__dirstamp) \ + src/c-siphash/src/$(DEPDIR)/$(am__dirstamp) +src/c-siphash/$(am__dirstamp): + @$(MKDIR_P) src/c-siphash + @: > src/c-siphash/$(am__dirstamp) + +src/c-siphash/libc-siphash.la: $(src_c_siphash_libc_siphash_la_OBJECTS) $(src_c_siphash_libc_siphash_la_DEPENDENCIES) $(EXTRA_src_c_siphash_libc_siphash_la_DEPENDENCIES) src/c-siphash/$(am__dirstamp) + $(AM_V_CCLD)$(src_c_siphash_libc_siphash_la_LINK) $(src_c_siphash_libc_siphash_la_OBJECTS) $(src_c_siphash_libc_siphash_la_LIBADD) $(LIBS) +src/contrib/$(am__dirstamp): + @$(MKDIR_P) src/contrib + @: > src/contrib/$(am__dirstamp) +src/contrib/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/contrib/$(DEPDIR) + @: > src/contrib/$(DEPDIR)/$(am__dirstamp) +src/contrib/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo: \ + src/contrib/$(am__dirstamp) \ + src/contrib/$(DEPDIR)/$(am__dirstamp) +src/contrib/tests/$(am__dirstamp): + @$(MKDIR_P) src/contrib/tests + @: > src/contrib/tests/$(am__dirstamp) + +src/contrib/tests/libnm-vpn-plugin-utils-test.la: $(src_contrib_tests_libnm_vpn_plugin_utils_test_la_OBJECTS) $(src_contrib_tests_libnm_vpn_plugin_utils_test_la_DEPENDENCIES) $(EXTRA_src_contrib_tests_libnm_vpn_plugin_utils_test_la_DEPENDENCIES) src/contrib/tests/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(am_src_contrib_tests_libnm_vpn_plugin_utils_test_la_rpath) $(src_contrib_tests_libnm_vpn_plugin_utils_test_la_OBJECTS) $(src_contrib_tests_libnm_vpn_plugin_utils_test_la_LIBADD) $(LIBS) src/core/devices/adsl/$(am__dirstamp): @$(MKDIR_P) src/core/devices/adsl @: > src/core/devices/adsl/$(am__dirstamp) @@ -9876,24 +9235,6 @@ src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo: \ src/core/devices/wwan/libnm-wwan.la: $(src_core_devices_wwan_libnm_wwan_la_OBJECTS) $(src_core_devices_wwan_libnm_wwan_la_DEPENDENCIES) $(EXTRA_src_core_devices_wwan_libnm_wwan_la_DEPENDENCIES) src/core/devices/wwan/$(am__dirstamp) $(AM_V_CCLD)$(src_core_devices_wwan_libnm_wwan_la_LINK) $(am_src_core_devices_wwan_libnm_wwan_la_rpath) $(src_core_devices_wwan_libnm_wwan_la_OBJECTS) $(src_core_devices_wwan_libnm_wwan_la_LIBADD) $(LIBS) -src/core/initrd/$(am__dirstamp): - @$(MKDIR_P) src/core/initrd - @: > src/core/initrd/$(am__dirstamp) -src/core/initrd/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) src/core/initrd/$(DEPDIR) - @: > src/core/initrd/$(DEPDIR)/$(am__dirstamp) -src/core/initrd/libnmi_core_la-nmi-cmdline-reader.lo: \ - src/core/initrd/$(am__dirstamp) \ - src/core/initrd/$(DEPDIR)/$(am__dirstamp) -src/core/initrd/libnmi_core_la-nmi-dt-reader.lo: \ - src/core/initrd/$(am__dirstamp) \ - src/core/initrd/$(DEPDIR)/$(am__dirstamp) -src/core/initrd/libnmi_core_la-nmi-ibft-reader.lo: \ - src/core/initrd/$(am__dirstamp) \ - src/core/initrd/$(DEPDIR)/$(am__dirstamp) - -src/core/initrd/libnmi-core.la: $(src_core_initrd_libnmi_core_la_OBJECTS) $(src_core_initrd_libnmi_core_la_DEPENDENCIES) $(EXTRA_src_core_initrd_libnmi_core_la_DEPENDENCIES) src/core/initrd/$(am__dirstamp) - $(AM_V_CCLD)$(LINK) $(src_core_initrd_libnmi_core_la_OBJECTS) $(src_core_initrd_libnmi_core_la_LIBADD) $(LIBS) src/core/$(am__dirstamp): @$(MKDIR_P) src/core @: > src/core/$(am__dirstamp) @@ -10171,45 +9512,6 @@ src/core/libNetworkManagerBase_la-nm-core-utils.lo: \ src/core/$(am__dirstamp) src/core/$(DEPDIR)/$(am__dirstamp) src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo: \ src/core/$(am__dirstamp) src/core/$(DEPDIR)/$(am__dirstamp) -src/core/platform/$(am__dirstamp): - @$(MKDIR_P) src/core/platform - @: > src/core/platform/$(am__dirstamp) -src/core/platform/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) src/core/platform/$(DEPDIR) - @: > src/core/platform/$(DEPDIR)/$(am__dirstamp) -src/core/platform/libNetworkManagerBase_la-nmp-object.lo: \ - src/core/platform/$(am__dirstamp) \ - src/core/platform/$(DEPDIR)/$(am__dirstamp) -src/core/platform/libNetworkManagerBase_la-nm-platform.lo: \ - src/core/platform/$(am__dirstamp) \ - src/core/platform/$(DEPDIR)/$(am__dirstamp) -src/core/platform/libNetworkManagerBase_la-nm-linux-platform.lo: \ - src/core/platform/$(am__dirstamp) \ - src/core/platform/$(DEPDIR)/$(am__dirstamp) -src/core/platform/libNetworkManagerBase_la-nmp-rules-manager.lo: \ - src/core/platform/$(am__dirstamp) \ - src/core/platform/$(DEPDIR)/$(am__dirstamp) -src/core/platform/wifi/$(am__dirstamp): - @$(MKDIR_P) src/core/platform/wifi - @: > src/core/platform/wifi/$(am__dirstamp) -src/core/platform/wifi/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) src/core/platform/wifi/$(DEPDIR) - @: > src/core/platform/wifi/$(DEPDIR)/$(am__dirstamp) -src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-nl80211.lo: \ - src/core/platform/wifi/$(am__dirstamp) \ - src/core/platform/wifi/$(DEPDIR)/$(am__dirstamp) -src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils.lo: \ - src/core/platform/wifi/$(am__dirstamp) \ - src/core/platform/wifi/$(DEPDIR)/$(am__dirstamp) -src/core/platform/wpan/$(am__dirstamp): - @$(MKDIR_P) src/core/platform/wpan - @: > src/core/platform/wpan/$(am__dirstamp) -src/core/platform/wpan/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) src/core/platform/wpan/$(DEPDIR) - @: > src/core/platform/wpan/$(DEPDIR)/$(am__dirstamp) -src/core/platform/wpan/libNetworkManagerBase_la-nm-wpan-utils.lo: \ - src/core/platform/wpan/$(am__dirstamp) \ - src/core/platform/wpan/$(DEPDIR)/$(am__dirstamp) src/core/ndisc/$(am__dirstamp): @$(MKDIR_P) src/core/ndisc @: > src/core/ndisc/$(am__dirstamp) @@ -10260,15 +9562,18 @@ src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo: \ src/core/dhcp/$(DEPDIR)/$(am__dirstamp) src/core/libNetworkManagerBase_la-main-utils.lo: \ src/core/$(am__dirstamp) src/core/$(DEPDIR)/$(am__dirstamp) -src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-wext.lo: \ - src/core/platform/wifi/$(am__dirstamp) \ - src/core/platform/wifi/$(DEPDIR)/$(am__dirstamp) src/core/libNetworkManagerBase.la: $(src_core_libNetworkManagerBase_la_OBJECTS) $(src_core_libNetworkManagerBase_la_DEPENDENCIES) $(EXTRA_src_core_libNetworkManagerBase_la_DEPENDENCIES) src/core/$(am__dirstamp) $(AM_V_CCLD)$(LINK) $(src_core_libNetworkManagerBase_la_OBJECTS) $(src_core_libNetworkManagerBase_la_LIBADD) $(LIBS) src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo: \ src/core/ndisc/$(am__dirstamp) \ src/core/ndisc/$(DEPDIR)/$(am__dirstamp) +src/core/platform/$(am__dirstamp): + @$(MKDIR_P) src/core/platform + @: > src/core/platform/$(am__dirstamp) +src/core/platform/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/core/platform/$(DEPDIR) + @: > src/core/platform/$(DEPDIR)/$(am__dirstamp) src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo: \ src/core/platform/$(am__dirstamp) \ src/core/platform/$(DEPDIR)/$(am__dirstamp) @@ -10461,237 +9766,913 @@ src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.l src/core/settings/plugins/ifupdown/libnms-ifupdown-core.la: $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_OBJECTS) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_DEPENDENCIES) $(EXTRA_src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_DEPENDENCIES) src/core/settings/plugins/ifupdown/$(am__dirstamp) $(AM_V_CCLD)$(LINK) $(am_src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_rpath) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_OBJECTS) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_LIBADD) $(LIBS) -clients/cli/$(am__dirstamp): - @$(MKDIR_P) clients/cli - @: > clients/cli/$(am__dirstamp) -clients/cli/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) clients/cli/$(DEPDIR) - @: > clients/cli/$(DEPDIR)/$(am__dirstamp) -clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.$(OBJEXT): \ - clients/cli/$(am__dirstamp) \ - clients/cli/$(DEPDIR)/$(am__dirstamp) - -clients/cli/generate-docs-nm-settings-nmcli$(EXEEXT): $(clients_cli_generate_docs_nm_settings_nmcli_OBJECTS) $(clients_cli_generate_docs_nm_settings_nmcli_DEPENDENCIES) $(EXTRA_clients_cli_generate_docs_nm_settings_nmcli_DEPENDENCIES) clients/cli/$(am__dirstamp) - @rm -f clients/cli/generate-docs-nm-settings-nmcli$(EXEEXT) - $(AM_V_CCLD)$(clients_cli_generate_docs_nm_settings_nmcli_LINK) $(clients_cli_generate_docs_nm_settings_nmcli_OBJECTS) $(clients_cli_generate_docs_nm_settings_nmcli_LDADD) $(LIBS) -clients/cli/nmcli-common.$(OBJEXT): clients/cli/$(am__dirstamp) \ - clients/cli/$(DEPDIR)/$(am__dirstamp) -clients/cli/nmcli-utils.$(OBJEXT): clients/cli/$(am__dirstamp) \ - clients/cli/$(DEPDIR)/$(am__dirstamp) -clients/cli/nmcli-agent.$(OBJEXT): clients/cli/$(am__dirstamp) \ - clients/cli/$(DEPDIR)/$(am__dirstamp) -clients/cli/nmcli-general.$(OBJEXT): clients/cli/$(am__dirstamp) \ - clients/cli/$(DEPDIR)/$(am__dirstamp) -clients/cli/nmcli-connections.$(OBJEXT): clients/cli/$(am__dirstamp) \ - clients/cli/$(DEPDIR)/$(am__dirstamp) -clients/cli/nmcli-devices.$(OBJEXT): clients/cli/$(am__dirstamp) \ - clients/cli/$(DEPDIR)/$(am__dirstamp) -clients/cli/nmcli-settings.$(OBJEXT): clients/cli/$(am__dirstamp) \ - clients/cli/$(DEPDIR)/$(am__dirstamp) -clients/cli/nmcli-nmcli.$(OBJEXT): clients/cli/$(am__dirstamp) \ - clients/cli/$(DEPDIR)/$(am__dirstamp) -clients/cli/nmcli-polkit-agent.$(OBJEXT): clients/cli/$(am__dirstamp) \ - clients/cli/$(DEPDIR)/$(am__dirstamp) - -clients/cli/nmcli$(EXEEXT): $(clients_cli_nmcli_OBJECTS) $(clients_cli_nmcli_DEPENDENCIES) $(EXTRA_clients_cli_nmcli_DEPENDENCIES) clients/cli/$(am__dirstamp) - @rm -f clients/cli/nmcli$(EXEEXT) - $(AM_V_CCLD)$(clients_cli_nmcli_LINK) $(clients_cli_nmcli_OBJECTS) $(clients_cli_nmcli_LDADD) $(LIBS) -clients/cloud-setup/nm_cloud_setup-main.$(OBJEXT): \ - clients/cloud-setup/$(am__dirstamp) \ - clients/cloud-setup/$(DEPDIR)/$(am__dirstamp) - -clients/cloud-setup/nm-cloud-setup$(EXEEXT): $(clients_cloud_setup_nm_cloud_setup_OBJECTS) $(clients_cloud_setup_nm_cloud_setup_DEPENDENCIES) $(EXTRA_clients_cloud_setup_nm_cloud_setup_DEPENDENCIES) clients/cloud-setup/$(am__dirstamp) - @rm -f clients/cloud-setup/nm-cloud-setup$(EXEEXT) - $(AM_V_CCLD)$(clients_cloud_setup_nm_cloud_setup_LINK) $(clients_cloud_setup_nm_cloud_setup_OBJECTS) $(clients_cloud_setup_nm_cloud_setup_LDADD) $(LIBS) -clients/cloud-setup/tests/$(am__dirstamp): - @$(MKDIR_P) clients/cloud-setup/tests - @: > clients/cloud-setup/tests/$(am__dirstamp) -clients/cloud-setup/tests/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) clients/cloud-setup/tests/$(DEPDIR) - @: > clients/cloud-setup/tests/$(DEPDIR)/$(am__dirstamp) -clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.$(OBJEXT): \ - clients/cloud-setup/tests/$(am__dirstamp) \ - clients/cloud-setup/tests/$(DEPDIR)/$(am__dirstamp) - -clients/cloud-setup/tests/test-cloud-setup-general$(EXEEXT): $(clients_cloud_setup_tests_test_cloud_setup_general_OBJECTS) $(clients_cloud_setup_tests_test_cloud_setup_general_DEPENDENCIES) $(EXTRA_clients_cloud_setup_tests_test_cloud_setup_general_DEPENDENCIES) clients/cloud-setup/tests/$(am__dirstamp) - @rm -f clients/cloud-setup/tests/test-cloud-setup-general$(EXEEXT) - $(AM_V_CCLD)$(clients_cloud_setup_tests_test_cloud_setup_general_LINK) $(clients_cloud_setup_tests_test_cloud_setup_general_OBJECTS) $(clients_cloud_setup_tests_test_cloud_setup_general_LDADD) $(LIBS) -clients/common/tests/$(am__dirstamp): - @$(MKDIR_P) clients/common/tests - @: > clients/common/tests/$(am__dirstamp) -clients/common/tests/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) clients/common/tests/$(DEPDIR) - @: > clients/common/tests/$(DEPDIR)/$(am__dirstamp) -clients/common/tests/test_clients_common-test-clients-common.$(OBJEXT): \ - clients/common/tests/$(am__dirstamp) \ - clients/common/tests/$(DEPDIR)/$(am__dirstamp) - -clients/common/tests/test-clients-common$(EXEEXT): $(clients_common_tests_test_clients_common_OBJECTS) $(clients_common_tests_test_clients_common_DEPENDENCIES) $(EXTRA_clients_common_tests_test_clients_common_DEPENDENCIES) clients/common/tests/$(am__dirstamp) - @rm -f clients/common/tests/test-clients-common$(EXEEXT) - $(AM_V_CCLD)$(clients_common_tests_test_clients_common_LINK) $(clients_common_tests_test_clients_common_OBJECTS) $(clients_common_tests_test_clients_common_LDADD) $(LIBS) -clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.$(OBJEXT): \ - clients/common/tests/$(am__dirstamp) \ - clients/common/tests/$(DEPDIR)/$(am__dirstamp) - -clients/common/tests/test-libnm-core-aux$(EXEEXT): $(clients_common_tests_test_libnm_core_aux_OBJECTS) $(clients_common_tests_test_libnm_core_aux_DEPENDENCIES) $(EXTRA_clients_common_tests_test_libnm_core_aux_DEPENDENCIES) clients/common/tests/$(am__dirstamp) - @rm -f clients/common/tests/test-libnm-core-aux$(EXEEXT) - $(AM_V_CCLD)$(clients_common_tests_test_libnm_core_aux_LINK) $(clients_common_tests_test_libnm_core_aux_OBJECTS) $(clients_common_tests_test_libnm_core_aux_LDADD) $(LIBS) -clients/$(am__dirstamp): - @$(MKDIR_P) clients - @: > clients/$(am__dirstamp) -clients/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) clients/$(DEPDIR) - @: > clients/$(DEPDIR)/$(am__dirstamp) -clients/nm_online-nm-online.$(OBJEXT): clients/$(am__dirstamp) \ - clients/$(DEPDIR)/$(am__dirstamp) - -clients/nm-online$(EXEEXT): $(clients_nm_online_OBJECTS) $(clients_nm_online_DEPENDENCIES) $(EXTRA_clients_nm_online_DEPENDENCIES) clients/$(am__dirstamp) - @rm -f clients/nm-online$(EXEEXT) - $(AM_V_CCLD)$(clients_nm_online_LINK) $(clients_nm_online_OBJECTS) $(clients_nm_online_LDADD) $(LIBS) -clients/tui/$(am__dirstamp): - @$(MKDIR_P) clients/tui - @: > clients/tui/$(am__dirstamp) -clients/tui/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) clients/tui/$(DEPDIR) - @: > clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmtui.$(OBJEXT): clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmtui-connect.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmtui-edit.$(OBJEXT): clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmtui-hostname.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nm-editor-bindings.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nm-editor-utils.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-address-list.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-connect-connection-list.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-device-entry.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-edit-connection-list.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-editor-grid.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-editor-page.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-editor-page-device.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-editor-section.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-editor.$(OBJEXT): clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-ip-entry.$(OBJEXT): clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-mac-entry.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-mtu-entry.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-bond.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-bridge.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-bridge-port.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-dsl.$(OBJEXT): clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-ethernet.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-infiniband.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-ip-tunnel.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-ip4.$(OBJEXT): clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-ip6.$(OBJEXT): clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-ppp.$(OBJEXT): clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-team.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-team-port.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-vlan.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-page-wifi.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-password-dialog.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-password-fields.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-route-editor.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-route-entry.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-route-table.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-slave-list.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-utils.$(OBJEXT): clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) -clients/tui/nmtui-nmt-widget-list.$(OBJEXT): \ - clients/tui/$(am__dirstamp) \ - clients/tui/$(DEPDIR)/$(am__dirstamp) - -clients/tui/nmtui$(EXEEXT): $(clients_tui_nmtui_OBJECTS) $(clients_tui_nmtui_DEPENDENCIES) $(EXTRA_clients_tui_nmtui_DEPENDENCIES) clients/tui/$(am__dirstamp) - @rm -f clients/tui/nmtui$(EXEEXT) - $(AM_V_CCLD)$(clients_tui_nmtui_LINK) $(clients_tui_nmtui_OBJECTS) $(clients_tui_nmtui_LDADD) $(LIBS) -dispatcher/nm_dispatcher-nm-dispatcher.$(OBJEXT): \ - dispatcher/$(am__dirstamp) \ - dispatcher/$(DEPDIR)/$(am__dirstamp) - -dispatcher/nm-dispatcher$(EXEEXT): $(dispatcher_nm_dispatcher_OBJECTS) $(dispatcher_nm_dispatcher_DEPENDENCIES) $(EXTRA_dispatcher_nm_dispatcher_DEPENDENCIES) dispatcher/$(am__dirstamp) - @rm -f dispatcher/nm-dispatcher$(EXEEXT) - $(AM_V_CCLD)$(dispatcher_nm_dispatcher_LINK) $(dispatcher_nm_dispatcher_OBJECTS) $(dispatcher_nm_dispatcher_LDADD) $(LIBS) -dispatcher/tests/$(am__dirstamp): - @$(MKDIR_P) dispatcher/tests - @: > dispatcher/tests/$(am__dirstamp) -dispatcher/tests/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) dispatcher/tests/$(DEPDIR) - @: > dispatcher/tests/$(DEPDIR)/$(am__dirstamp) -dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.$(OBJEXT): \ - dispatcher/tests/$(am__dirstamp) \ - dispatcher/tests/$(DEPDIR)/$(am__dirstamp) -dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.$(OBJEXT): \ - dispatcher/$(am__dirstamp) \ - dispatcher/$(DEPDIR)/$(am__dirstamp) - -dispatcher/tests/test-dispatcher-envp$(EXEEXT): $(dispatcher_tests_test_dispatcher_envp_OBJECTS) $(dispatcher_tests_test_dispatcher_envp_DEPENDENCIES) $(EXTRA_dispatcher_tests_test_dispatcher_envp_DEPENDENCIES) dispatcher/tests/$(am__dirstamp) - @rm -f dispatcher/tests/test-dispatcher-envp$(EXEEXT) - $(AM_V_CCLD)$(dispatcher_tests_test_dispatcher_envp_LINK) $(dispatcher_tests_test_dispatcher_envp_OBJECTS) $(dispatcher_tests_test_dispatcher_envp_LDADD) $(LIBS) +src/libnm-base/$(am__dirstamp): + @$(MKDIR_P) src/libnm-base + @: > src/libnm-base/$(am__dirstamp) +src/libnm-base/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-base/$(DEPDIR) + @: > src/libnm-base/$(DEPDIR)/$(am__dirstamp) +src/libnm-base/libnm_base_la-nm-ethtool-base.lo: \ + src/libnm-base/$(am__dirstamp) \ + src/libnm-base/$(DEPDIR)/$(am__dirstamp) +src/libnm-base/libnm_base_la-nm-net-aux.lo: \ + src/libnm-base/$(am__dirstamp) \ + src/libnm-base/$(DEPDIR)/$(am__dirstamp) + +src/libnm-base/libnm-base.la: $(src_libnm_base_libnm_base_la_OBJECTS) $(src_libnm_base_libnm_base_la_DEPENDENCIES) $(EXTRA_src_libnm_base_libnm_base_la_DEPENDENCIES) src/libnm-base/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_base_libnm_base_la_LINK) $(src_libnm_base_libnm_base_la_OBJECTS) $(src_libnm_base_libnm_base_la_LIBADD) $(LIBS) +src/libnm-client-aux-extern/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-aux-extern + @: > src/libnm-client-aux-extern/$(am__dirstamp) +src/libnm-client-aux-extern/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-aux-extern/$(DEPDIR) + @: > src/libnm-client-aux-extern/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-aux-extern/libnm_client_aux_extern_la-nm-libnm-aux.lo: \ + src/libnm-client-aux-extern/$(am__dirstamp) \ + src/libnm-client-aux-extern/$(DEPDIR)/$(am__dirstamp) + +src/libnm-client-aux-extern/libnm-client-aux-extern.la: $(src_libnm_client_aux_extern_libnm_client_aux_extern_la_OBJECTS) $(src_libnm_client_aux_extern_libnm_client_aux_extern_la_DEPENDENCIES) $(EXTRA_src_libnm_client_aux_extern_libnm_client_aux_extern_la_DEPENDENCIES) src/libnm-client-aux-extern/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_client_aux_extern_libnm_client_aux_extern_la_LINK) $(src_libnm_client_aux_extern_libnm_client_aux_extern_la_OBJECTS) $(src_libnm_client_aux_extern_libnm_client_aux_extern_la_LIBADD) $(LIBS) +src/libnm-client-impl/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-impl + @: > src/libnm-client-impl/$(am__dirstamp) +src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-impl/$(DEPDIR) + @: > src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-client.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-object.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-active-connection.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-access-point.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-checkpoint.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-dbus-helpers.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-6lowpan.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-adsl.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-bond.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-bridge.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-bt.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-dummy.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-ethernet.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-generic.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-infiniband.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-ip-tunnel.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-macsec.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-macvlan.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-modem.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-olpc-mesh.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-bridge.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-interface.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-port.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-ppp.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-team.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-tun.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-veth.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-vlan.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-vrf.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-vxlan.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi-p2p.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-wimax.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-wireguard.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-device-wpan.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-dhcp-config.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-dhcp4-config.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-dhcp6-config.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-dns-manager.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-ip-config.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-ip4-config.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-ip6-config.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-libnm-utils.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-remote-connection.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-secret-agent-old.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-vpn-connection.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-vpn-editor.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-vpn-plugin-old.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-vpn-service-plugin.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-wifi-p2p-peer.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/libnm_client_impl_la-nm-wimax-nsp.lo: \ + src/libnm-client-impl/$(am__dirstamp) \ + src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-public/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-public + @: > src/libnm-client-public/$(am__dirstamp) +src/libnm-client-public/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-public/$(DEPDIR) + @: > src/libnm-client-public/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-public/libnm_client_impl_libnm_client_impl_la-nm-enum-types.lo: \ + src/libnm-client-public/$(am__dirstamp) \ + src/libnm-client-public/$(DEPDIR)/$(am__dirstamp) + +src/libnm-client-impl/libnm-client-impl.la: $(src_libnm_client_impl_libnm_client_impl_la_OBJECTS) $(src_libnm_client_impl_libnm_client_impl_la_DEPENDENCIES) $(EXTRA_src_libnm_client_impl_libnm_client_impl_la_DEPENDENCIES) src/libnm-client-impl/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(src_libnm_client_impl_libnm_client_impl_la_OBJECTS) $(src_libnm_client_impl_libnm_client_impl_la_LIBADD) $(LIBS) + +src/libnm-client-impl/libnm.la: $(src_libnm_client_impl_libnm_la_OBJECTS) $(src_libnm_client_impl_libnm_la_DEPENDENCIES) $(EXTRA_src_libnm_client_impl_libnm_la_DEPENDENCIES) src/libnm-client-impl/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_client_impl_libnm_la_LINK) -rpath $(libdir) $(src_libnm_client_impl_libnm_la_OBJECTS) $(src_libnm_client_impl_libnm_la_LIBADD) $(LIBS) +src/libnm-client-test/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-test + @: > src/libnm-client-test/$(am__dirstamp) +src/libnm-client-test/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-test/$(DEPDIR) + @: > src/libnm-client-test/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-test/libnm_client_test_la-nm-test-utils-impl.lo: \ + src/libnm-client-test/$(am__dirstamp) \ + src/libnm-client-test/$(DEPDIR)/$(am__dirstamp) + +src/libnm-client-test/libnm-client-test.la: $(src_libnm_client_test_libnm_client_test_la_OBJECTS) $(src_libnm_client_test_libnm_client_test_la_DEPENDENCIES) $(EXTRA_src_libnm_client_test_libnm_client_test_la_DEPENDENCIES) src/libnm-client-test/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_client_test_libnm_client_test_la_LINK) $(src_libnm_client_test_libnm_client_test_la_OBJECTS) $(src_libnm_client_test_libnm_client_test_la_LIBADD) $(LIBS) +src/libnm-core-aux-extern/$(am__dirstamp): + @$(MKDIR_P) src/libnm-core-aux-extern + @: > src/libnm-core-aux-extern/$(am__dirstamp) +src/libnm-core-aux-extern/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-core-aux-extern/$(DEPDIR) + @: > src/libnm-core-aux-extern/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-aux-extern/libnm_core_aux_extern_la-nm-libnm-core-aux.lo: \ + src/libnm-core-aux-extern/$(am__dirstamp) \ + src/libnm-core-aux-extern/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-aux-extern/libnm-core-aux-extern.la: $(src_libnm_core_aux_extern_libnm_core_aux_extern_la_OBJECTS) $(src_libnm_core_aux_extern_libnm_core_aux_extern_la_DEPENDENCIES) $(EXTRA_src_libnm_core_aux_extern_libnm_core_aux_extern_la_DEPENDENCIES) src/libnm-core-aux-extern/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_core_aux_extern_libnm_core_aux_extern_la_LINK) $(src_libnm_core_aux_extern_libnm_core_aux_extern_la_OBJECTS) $(src_libnm_core_aux_extern_libnm_core_aux_extern_la_LIBADD) $(LIBS) +src/libnm-core-aux-intern/$(am__dirstamp): + @$(MKDIR_P) src/libnm-core-aux-intern + @: > src/libnm-core-aux-intern/$(am__dirstamp) +src/libnm-core-aux-intern/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-core-aux-intern/$(DEPDIR) + @: > src/libnm-core-aux-intern/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-auth-subject.lo: \ + src/libnm-core-aux-intern/$(am__dirstamp) \ + src/libnm-core-aux-intern/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-libnm-core-utils.lo: \ + src/libnm-core-aux-intern/$(am__dirstamp) \ + src/libnm-core-aux-intern/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-aux-intern/libnm-core-aux-intern.la: $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_OBJECTS) $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_DEPENDENCIES) $(EXTRA_src_libnm_core_aux_intern_libnm_core_aux_intern_la_DEPENDENCIES) src/libnm-core-aux-intern/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_core_aux_intern_libnm_core_aux_intern_la_LINK) $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_OBJECTS) $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_LIBADD) $(LIBS) +src/libnm-core-impl/$(am__dirstamp): + @$(MKDIR_P) src/libnm-core-impl + @: > src/libnm-core-impl/$(am__dirstamp) +src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-core-impl/$(DEPDIR) + @: > src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-6lowpan.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-8021x.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-adsl.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-bluetooth.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-bond.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge-port.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-cdma.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-connection.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-dcb.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-dummy.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ethtool.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-generic.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-gsm.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-hostname.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-infiniband.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-config.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-tunnel.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip4-config.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip6-config.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-macsec.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-macvlan.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-match.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-olpc-mesh.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-bridge.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-dpdk.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-external-ids.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-interface.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-patch.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-port.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ppp.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-pppoe.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-proxy.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-serial.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-sriov.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-tc-config.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-team-port.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-team.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-tun.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-user.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-veth.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-vlan.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-vpn.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-vrf.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-vxlan.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wifi-p2p.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wimax.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wired.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireguard.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless-security.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wpan.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-connection.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-crypto.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-dbus-utils.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-errors.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-keyfile-utils.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-keyfile.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-meta-setting-base-impl.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-property-compare.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-setting.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-simple-connection.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-team-utils.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-utils.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-vpn-editor-plugin.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/libnm_core_impl_la-nm-vpn-plugin-info.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-public/$(am__dirstamp): + @$(MKDIR_P) src/libnm-core-public + @: > src/libnm-core-public/$(am__dirstamp) +src/libnm-core-public/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-core-public/$(DEPDIR) + @: > src/libnm-core-public/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-public/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.lo: \ + src/libnm-core-public/$(am__dirstamp) \ + src/libnm-core-public/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-impl/libnm-core-impl.la: $(src_libnm_core_impl_libnm_core_impl_la_OBJECTS) $(src_libnm_core_impl_libnm_core_impl_la_DEPENDENCIES) $(EXTRA_src_libnm_core_impl_libnm_core_impl_la_DEPENDENCIES) src/libnm-core-impl/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_core_impl_libnm_core_impl_la_LINK) $(src_libnm_core_impl_libnm_core_impl_la_OBJECTS) $(src_libnm_core_impl_libnm_core_impl_la_LIBADD) $(LIBS) +src/libnm-core-impl/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-impl/libnm-crypto-gnutls.la: $(src_libnm_core_impl_libnm_crypto_gnutls_la_OBJECTS) $(src_libnm_core_impl_libnm_crypto_gnutls_la_DEPENDENCIES) $(EXTRA_src_libnm_core_impl_libnm_crypto_gnutls_la_DEPENDENCIES) src/libnm-core-impl/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_core_impl_libnm_crypto_gnutls_la_LINK) $(am_src_libnm_core_impl_libnm_crypto_gnutls_la_rpath) $(src_libnm_core_impl_libnm_crypto_gnutls_la_OBJECTS) $(src_libnm_core_impl_libnm_crypto_gnutls_la_LIBADD) $(LIBS) +src/libnm-core-impl/libnm_crypto_nss_la-nm-crypto-nss.lo: \ + src/libnm-core-impl/$(am__dirstamp) \ + src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-impl/libnm-crypto-nss.la: $(src_libnm_core_impl_libnm_crypto_nss_la_OBJECTS) $(src_libnm_core_impl_libnm_crypto_nss_la_DEPENDENCIES) $(EXTRA_src_libnm_core_impl_libnm_crypto_nss_la_DEPENDENCIES) src/libnm-core-impl/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_core_impl_libnm_crypto_nss_la_LINK) $(am_src_libnm_core_impl_libnm_crypto_nss_la_rpath) $(src_libnm_core_impl_libnm_crypto_nss_la_OBJECTS) $(src_libnm_core_impl_libnm_crypto_nss_la_LIBADD) $(LIBS) +src/libnm-glib-aux/$(am__dirstamp): + @$(MKDIR_P) src/libnm-glib-aux + @: > src/libnm-glib-aux/$(am__dirstamp) +src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-glib-aux/$(DEPDIR) + @: > src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-errno.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo: \ + src/libnm-glib-aux/$(am__dirstamp) \ + src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) + +src/libnm-glib-aux/libnm-glib-aux.la: $(src_libnm_glib_aux_libnm_glib_aux_la_OBJECTS) $(src_libnm_glib_aux_libnm_glib_aux_la_DEPENDENCIES) $(EXTRA_src_libnm_glib_aux_libnm_glib_aux_la_DEPENDENCIES) src/libnm-glib-aux/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_glib_aux_libnm_glib_aux_la_LINK) $(src_libnm_glib_aux_libnm_glib_aux_la_OBJECTS) $(src_libnm_glib_aux_libnm_glib_aux_la_LIBADD) $(LIBS) +src/libnm-log-core/$(am__dirstamp): + @$(MKDIR_P) src/libnm-log-core + @: > src/libnm-log-core/$(am__dirstamp) +src/libnm-log-core/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-log-core/$(DEPDIR) + @: > src/libnm-log-core/$(DEPDIR)/$(am__dirstamp) +src/libnm-log-core/libnm_log_core_la-nm-logging.lo: \ + src/libnm-log-core/$(am__dirstamp) \ + src/libnm-log-core/$(DEPDIR)/$(am__dirstamp) + +src/libnm-log-core/libnm-log-core.la: $(src_libnm_log_core_libnm_log_core_la_OBJECTS) $(src_libnm_log_core_libnm_log_core_la_DEPENDENCIES) $(EXTRA_src_libnm_log_core_libnm_log_core_la_DEPENDENCIES) src/libnm-log-core/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_log_core_libnm_log_core_la_LINK) $(src_libnm_log_core_libnm_log_core_la_OBJECTS) $(src_libnm_log_core_libnm_log_core_la_LIBADD) $(LIBS) +src/libnm-log-null/$(am__dirstamp): + @$(MKDIR_P) src/libnm-log-null + @: > src/libnm-log-null/$(am__dirstamp) +src/libnm-log-null/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-log-null/$(DEPDIR) + @: > src/libnm-log-null/$(DEPDIR)/$(am__dirstamp) +src/libnm-log-null/libnm_log_null_la-nm-logging-null.lo: \ + src/libnm-log-null/$(am__dirstamp) \ + src/libnm-log-null/$(DEPDIR)/$(am__dirstamp) + +src/libnm-log-null/libnm-log-null.la: $(src_libnm_log_null_libnm_log_null_la_OBJECTS) $(src_libnm_log_null_libnm_log_null_la_DEPENDENCIES) $(EXTRA_src_libnm_log_null_libnm_log_null_la_DEPENDENCIES) src/libnm-log-null/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(src_libnm_log_null_libnm_log_null_la_OBJECTS) $(src_libnm_log_null_libnm_log_null_la_LIBADD) $(LIBS) +src/libnm-platform/$(am__dirstamp): + @$(MKDIR_P) src/libnm-platform + @: > src/libnm-platform/$(am__dirstamp) +src/libnm-platform/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-platform/$(DEPDIR) + @: > src/libnm-platform/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/libnm_platform_la-nm-linux-platform.lo: \ + src/libnm-platform/$(am__dirstamp) \ + src/libnm-platform/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/libnm_platform_la-nm-netlink.lo: \ + src/libnm-platform/$(am__dirstamp) \ + src/libnm-platform/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/libnm_platform_la-nm-platform-utils.lo: \ + src/libnm-platform/$(am__dirstamp) \ + src/libnm-platform/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/libnm_platform_la-nm-platform.lo: \ + src/libnm-platform/$(am__dirstamp) \ + src/libnm-platform/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/libnm_platform_la-nmp-netns.lo: \ + src/libnm-platform/$(am__dirstamp) \ + src/libnm-platform/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/libnm_platform_la-nmp-object.lo: \ + src/libnm-platform/$(am__dirstamp) \ + src/libnm-platform/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/libnm_platform_la-nmp-rules-manager.lo: \ + src/libnm-platform/$(am__dirstamp) \ + src/libnm-platform/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/wifi/$(am__dirstamp): + @$(MKDIR_P) src/libnm-platform/wifi + @: > src/libnm-platform/wifi/$(am__dirstamp) +src/libnm-platform/wifi/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-platform/wifi/$(DEPDIR) + @: > src/libnm-platform/wifi/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-nl80211.lo: \ + src/libnm-platform/wifi/$(am__dirstamp) \ + src/libnm-platform/wifi/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils.lo: \ + src/libnm-platform/wifi/$(am__dirstamp) \ + src/libnm-platform/wifi/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/wpan/$(am__dirstamp): + @$(MKDIR_P) src/libnm-platform/wpan + @: > src/libnm-platform/wpan/$(am__dirstamp) +src/libnm-platform/wpan/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-platform/wpan/$(DEPDIR) + @: > src/libnm-platform/wpan/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/wpan/libnm_platform_la-nm-wpan-utils.lo: \ + src/libnm-platform/wpan/$(am__dirstamp) \ + src/libnm-platform/wpan/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-wext.lo: \ + src/libnm-platform/wifi/$(am__dirstamp) \ + src/libnm-platform/wifi/$(DEPDIR)/$(am__dirstamp) + +src/libnm-platform/libnm-platform.la: $(src_libnm_platform_libnm_platform_la_OBJECTS) $(src_libnm_platform_libnm_platform_la_DEPENDENCIES) $(EXTRA_src_libnm_platform_libnm_platform_la_DEPENDENCIES) src/libnm-platform/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_platform_libnm_platform_la_LINK) $(src_libnm_platform_libnm_platform_la_OBJECTS) $(src_libnm_platform_libnm_platform_la_LIBADD) $(LIBS) +src/libnm-std-aux/$(am__dirstamp): + @$(MKDIR_P) src/libnm-std-aux + @: > src/libnm-std-aux/$(am__dirstamp) +src/libnm-std-aux/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-std-aux/$(DEPDIR) + @: > src/libnm-std-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-std-aux/libnm_std_aux_la-c-list-util.lo: \ + src/libnm-std-aux/$(am__dirstamp) \ + src/libnm-std-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-std-aux/libnm_std_aux_la-nm-std-utils.lo: \ + src/libnm-std-aux/$(am__dirstamp) \ + src/libnm-std-aux/$(DEPDIR)/$(am__dirstamp) + +src/libnm-std-aux/libnm-std-aux.la: $(src_libnm_std_aux_libnm_std_aux_la_OBJECTS) $(src_libnm_std_aux_libnm_std_aux_la_DEPENDENCIES) $(EXTRA_src_libnm_std_aux_libnm_std_aux_la_DEPENDENCIES) src/libnm-std-aux/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_std_aux_libnm_std_aux_la_LINK) $(src_libnm_std_aux_libnm_std_aux_la_OBJECTS) $(src_libnm_std_aux_libnm_std_aux_la_LIBADD) $(LIBS) +src/libnm-systemd-shared/$(am__dirstamp): + @$(MKDIR_P) src/libnm-systemd-shared + @: > src/libnm-systemd-shared/$(am__dirstamp) +src/libnm-systemd-shared/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-systemd-shared/$(DEPDIR) + @: > src/libnm-systemd-shared/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/libnm_systemd_shared_la-nm-sd-utils-shared.lo: \ + src/libnm-systemd-shared/$(am__dirstamp) \ + src/libnm-systemd-shared/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/$(am__dirstamp): + @$(MKDIR_P) src/libnm-systemd-shared/src/basic + @: > src/libnm-systemd-shared/src/basic/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-systemd-shared/src/basic/$(DEPDIR) + @: > src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-alloc-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-file.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-escape.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ether-addr-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-extract-word.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fd-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fileio.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-format-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fs-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hash-funcs.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hashmap.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hexdecoct.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hostname-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-in-addr-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-io-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-memory-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-mempool.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-parse-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-path-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-prioq.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-process-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-random-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ratelimit.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-signal-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-socket-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-stat-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-table.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strv.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strxcpyx.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-time-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-tmpfile-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-utf8.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-util.lo: \ + src/libnm-systemd-shared/src/basic/$(am__dirstamp) \ + src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/shared/$(am__dirstamp): + @$(MKDIR_P) src/libnm-systemd-shared/src/shared + @: > src/libnm-systemd-shared/src/shared/$(am__dirstamp) +src/libnm-systemd-shared/src/shared/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-systemd-shared/src/shared/$(DEPDIR) + @: > src/libnm-systemd-shared/src/shared/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-dns-domain.lo: \ + src/libnm-systemd-shared/src/shared/$(am__dirstamp) \ + src/libnm-systemd-shared/src/shared/$(DEPDIR)/$(am__dirstamp) +src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-web-util.lo: \ + src/libnm-systemd-shared/src/shared/$(am__dirstamp) \ + src/libnm-systemd-shared/src/shared/$(DEPDIR)/$(am__dirstamp) + +src/libnm-systemd-shared/libnm-systemd-shared.la: $(src_libnm_systemd_shared_libnm_systemd_shared_la_OBJECTS) $(src_libnm_systemd_shared_libnm_systemd_shared_la_DEPENDENCIES) $(EXTRA_src_libnm_systemd_shared_libnm_systemd_shared_la_DEPENDENCIES) src/libnm-systemd-shared/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(src_libnm_systemd_shared_libnm_systemd_shared_la_OBJECTS) $(src_libnm_systemd_shared_libnm_systemd_shared_la_LIBADD) $(LIBS) +src/libnm-udev-aux/$(am__dirstamp): + @$(MKDIR_P) src/libnm-udev-aux + @: > src/libnm-udev-aux/$(am__dirstamp) +src/libnm-udev-aux/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-udev-aux/$(DEPDIR) + @: > src/libnm-udev-aux/$(DEPDIR)/$(am__dirstamp) +src/libnm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo: \ + src/libnm-udev-aux/$(am__dirstamp) \ + src/libnm-udev-aux/$(DEPDIR)/$(am__dirstamp) + +src/libnm-udev-aux/libnm-udev-aux.la: $(src_libnm_udev_aux_libnm_udev_aux_la_OBJECTS) $(src_libnm_udev_aux_libnm_udev_aux_la_DEPENDENCIES) $(EXTRA_src_libnm_udev_aux_libnm_udev_aux_la_DEPENDENCIES) src/libnm-udev-aux/$(am__dirstamp) + $(AM_V_CCLD)$(src_libnm_udev_aux_libnm_udev_aux_la_LINK) $(src_libnm_udev_aux_libnm_udev_aux_la_OBJECTS) $(src_libnm_udev_aux_libnm_udev_aux_la_LIBADD) $(LIBS) +src/libnmc-base/$(am__dirstamp): + @$(MKDIR_P) src/libnmc-base + @: > src/libnmc-base/$(am__dirstamp) +src/libnmc-base/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnmc-base/$(DEPDIR) + @: > src/libnmc-base/$(DEPDIR)/$(am__dirstamp) +src/libnmc-base/libnmc_base_la-nm-client-utils.lo: \ + src/libnmc-base/$(am__dirstamp) \ + src/libnmc-base/$(DEPDIR)/$(am__dirstamp) +src/libnmc-base/libnmc_base_la-nm-polkit-listener.lo: \ + src/libnmc-base/$(am__dirstamp) \ + src/libnmc-base/$(DEPDIR)/$(am__dirstamp) +src/libnmc-base/libnmc_base_la-nm-secret-agent-simple.lo: \ + src/libnmc-base/$(am__dirstamp) \ + src/libnmc-base/$(DEPDIR)/$(am__dirstamp) +src/libnmc-base/libnmc_base_la-nm-vpn-helpers.lo: \ + src/libnmc-base/$(am__dirstamp) \ + src/libnmc-base/$(DEPDIR)/$(am__dirstamp) + +src/libnmc-base/libnmc-base.la: $(src_libnmc_base_libnmc_base_la_OBJECTS) $(src_libnmc_base_libnmc_base_la_DEPENDENCIES) $(EXTRA_src_libnmc_base_libnmc_base_la_DEPENDENCIES) src/libnmc-base/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(am_src_libnmc_base_libnmc_base_la_rpath) $(src_libnmc_base_libnmc_base_la_OBJECTS) $(src_libnmc_base_libnmc_base_la_LIBADD) $(LIBS) +src/libnmc-setting/$(am__dirstamp): + @$(MKDIR_P) src/libnmc-setting + @: > src/libnmc-setting/$(am__dirstamp) +src/libnmc-setting/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnmc-setting/$(DEPDIR) + @: > src/libnmc-setting/$(DEPDIR)/$(am__dirstamp) +src/libnmc-setting/libnmc_setting_la-nm-meta-setting-access.lo: \ + src/libnmc-setting/$(am__dirstamp) \ + src/libnmc-setting/$(DEPDIR)/$(am__dirstamp) +src/libnmc-setting/libnmc_setting_la-nm-meta-setting-base-impl.lo: \ + src/libnmc-setting/$(am__dirstamp) \ + src/libnmc-setting/$(DEPDIR)/$(am__dirstamp) +src/libnmc-setting/libnmc_setting_la-nm-meta-setting-desc.lo: \ + src/libnmc-setting/$(am__dirstamp) \ + src/libnmc-setting/$(DEPDIR)/$(am__dirstamp) + +src/libnmc-setting/libnmc-setting.la: $(src_libnmc_setting_libnmc_setting_la_OBJECTS) $(src_libnmc_setting_libnmc_setting_la_DEPENDENCIES) $(EXTRA_src_libnmc_setting_libnmc_setting_la_DEPENDENCIES) src/libnmc-setting/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(am_src_libnmc_setting_libnmc_setting_la_rpath) $(src_libnmc_setting_libnmc_setting_la_OBJECTS) $(src_libnmc_setting_libnmc_setting_la_LIBADD) $(LIBS) +src/n-acd/src/$(am__dirstamp): + @$(MKDIR_P) src/n-acd/src + @: > src/n-acd/src/$(am__dirstamp) +src/n-acd/src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/n-acd/src/$(DEPDIR) + @: > src/n-acd/src/$(DEPDIR)/$(am__dirstamp) +src/n-acd/src/libn_acd_la-n-acd.lo: src/n-acd/src/$(am__dirstamp) \ + src/n-acd/src/$(DEPDIR)/$(am__dirstamp) +src/n-acd/src/libn_acd_la-n-acd-probe.lo: \ + src/n-acd/src/$(am__dirstamp) \ + src/n-acd/src/$(DEPDIR)/$(am__dirstamp) +src/n-acd/src/util/$(am__dirstamp): + @$(MKDIR_P) src/n-acd/src/util + @: > src/n-acd/src/util/$(am__dirstamp) +src/n-acd/src/util/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/n-acd/src/util/$(DEPDIR) + @: > src/n-acd/src/util/$(DEPDIR)/$(am__dirstamp) +src/n-acd/src/util/libn_acd_la-timer.lo: \ + src/n-acd/src/util/$(am__dirstamp) \ + src/n-acd/src/util/$(DEPDIR)/$(am__dirstamp) +src/n-acd/src/libn_acd_la-n-acd-bpf.lo: src/n-acd/src/$(am__dirstamp) \ + src/n-acd/src/$(DEPDIR)/$(am__dirstamp) +src/n-acd/src/libn_acd_la-n-acd-bpf-fallback.lo: \ + src/n-acd/src/$(am__dirstamp) \ + src/n-acd/src/$(DEPDIR)/$(am__dirstamp) +src/n-acd/$(am__dirstamp): + @$(MKDIR_P) src/n-acd + @: > src/n-acd/$(am__dirstamp) + +src/n-acd/libn-acd.la: $(src_n_acd_libn_acd_la_OBJECTS) $(src_n_acd_libn_acd_la_DEPENDENCIES) $(EXTRA_src_n_acd_libn_acd_la_DEPENDENCIES) src/n-acd/$(am__dirstamp) + $(AM_V_CCLD)$(src_n_acd_libn_acd_la_LINK) $(src_n_acd_libn_acd_la_OBJECTS) $(src_n_acd_libn_acd_la_LIBADD) $(LIBS) +src/n-dhcp4/src/$(am__dirstamp): + @$(MKDIR_P) src/n-dhcp4/src + @: > src/n-dhcp4/src/$(am__dirstamp) +src/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/n-dhcp4/src/$(DEPDIR) + @: > src/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-connection.lo: \ + src/n-dhcp4/src/$(am__dirstamp) \ + src/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-lease.lo: \ + src/n-dhcp4/src/$(am__dirstamp) \ + src/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-probe.lo: \ + src/n-dhcp4/src/$(am__dirstamp) \ + src/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-client.lo: \ + src/n-dhcp4/src/$(am__dirstamp) \ + src/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-incoming.lo: \ + src/n-dhcp4/src/$(am__dirstamp) \ + src/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-outgoing.lo: \ + src/n-dhcp4/src/$(am__dirstamp) \ + src/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-socket.lo: \ + src/n-dhcp4/src/$(am__dirstamp) \ + src/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/src/util/$(am__dirstamp): + @$(MKDIR_P) src/n-dhcp4/src/util + @: > src/n-dhcp4/src/util/$(am__dirstamp) +src/n-dhcp4/src/util/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/n-dhcp4/src/util/$(DEPDIR) + @: > src/n-dhcp4/src/util/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/src/util/libn_dhcp4_la-packet.lo: \ + src/n-dhcp4/src/util/$(am__dirstamp) \ + src/n-dhcp4/src/util/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/src/util/libn_dhcp4_la-socket.lo: \ + src/n-dhcp4/src/util/$(am__dirstamp) \ + src/n-dhcp4/src/util/$(DEPDIR)/$(am__dirstamp) +src/n-dhcp4/$(am__dirstamp): + @$(MKDIR_P) src/n-dhcp4 + @: > src/n-dhcp4/$(am__dirstamp) + +src/n-dhcp4/libn-dhcp4.la: $(src_n_dhcp4_libn_dhcp4_la_OBJECTS) $(src_n_dhcp4_libn_dhcp4_la_DEPENDENCIES) $(EXTRA_src_n_dhcp4_libn_dhcp4_la_DEPENDENCIES) src/n-dhcp4/$(am__dirstamp) + $(AM_V_CCLD)$(src_n_dhcp4_libn_dhcp4_la_LINK) $(src_n_dhcp4_libn_dhcp4_la_OBJECTS) $(src_n_dhcp4_libn_dhcp4_la_LIBADD) $(LIBS) +src/nm-dispatcher/$(am__dirstamp): + @$(MKDIR_P) src/nm-dispatcher + @: > src/nm-dispatcher/$(am__dirstamp) +src/nm-dispatcher/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nm-dispatcher/$(DEPDIR) + @: > src/nm-dispatcher/$(DEPDIR)/$(am__dirstamp) +src/nm-dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo: \ + src/nm-dispatcher/$(am__dirstamp) \ + src/nm-dispatcher/$(DEPDIR)/$(am__dirstamp) + +src/nm-dispatcher/libnm-dispatcher-core.la: $(src_nm_dispatcher_libnm_dispatcher_core_la_OBJECTS) $(src_nm_dispatcher_libnm_dispatcher_core_la_DEPENDENCIES) $(EXTRA_src_nm_dispatcher_libnm_dispatcher_core_la_DEPENDENCIES) src/nm-dispatcher/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(src_nm_dispatcher_libnm_dispatcher_core_la_OBJECTS) $(src_nm_dispatcher_libnm_dispatcher_core_la_LIBADD) $(LIBS) +src/nm-initrd-generator/$(am__dirstamp): + @$(MKDIR_P) src/nm-initrd-generator + @: > src/nm-initrd-generator/$(am__dirstamp) +src/nm-initrd-generator/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nm-initrd-generator/$(DEPDIR) + @: > src/nm-initrd-generator/$(DEPDIR)/$(am__dirstamp) +src/nm-initrd-generator/libnmi_core_la-nmi-cmdline-reader.lo: \ + src/nm-initrd-generator/$(am__dirstamp) \ + src/nm-initrd-generator/$(DEPDIR)/$(am__dirstamp) +src/nm-initrd-generator/libnmi_core_la-nmi-dt-reader.lo: \ + src/nm-initrd-generator/$(am__dirstamp) \ + src/nm-initrd-generator/$(DEPDIR)/$(am__dirstamp) +src/nm-initrd-generator/libnmi_core_la-nmi-ibft-reader.lo: \ + src/nm-initrd-generator/$(am__dirstamp) \ + src/nm-initrd-generator/$(DEPDIR)/$(am__dirstamp) + +src/nm-initrd-generator/libnmi-core.la: $(src_nm_initrd_generator_libnmi_core_la_OBJECTS) $(src_nm_initrd_generator_libnmi_core_la_DEPENDENCIES) $(EXTRA_src_nm_initrd_generator_libnmi_core_la_DEPENDENCIES) src/nm-initrd-generator/$(am__dirstamp) + $(AM_V_CCLD)$(LINK) $(src_nm_initrd_generator_libnmi_core_la_OBJECTS) $(src_nm_initrd_generator_libnmi_core_la_LIBADD) $(LIBS) examples/C/glib/$(am__dirstamp): @$(MKDIR_P) examples/C/glib @: > examples/C/glib/$(am__dirstamp) @@ -10754,6 +10735,13 @@ examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.$(OBJEXT): \ examples/C/glib/monitor-nm-state-gdbus$(EXEEXT): $(examples_C_glib_monitor_nm_state_gdbus_OBJECTS) $(examples_C_glib_monitor_nm_state_gdbus_DEPENDENCIES) $(EXTRA_examples_C_glib_monitor_nm_state_gdbus_DEPENDENCIES) examples/C/glib/$(am__dirstamp) @rm -f examples/C/glib/monitor-nm-state-gdbus$(EXEEXT) $(AM_V_CCLD)$(LINK) $(examples_C_glib_monitor_nm_state_gdbus_OBJECTS) $(examples_C_glib_monitor_nm_state_gdbus_LDADD) $(LIBS) +examples/C/glib/vpn_import_libnm-vpn-import-libnm.$(OBJEXT): \ + examples/C/glib/$(am__dirstamp) \ + examples/C/glib/$(DEPDIR)/$(am__dirstamp) + +examples/C/glib/vpn-import-libnm$(EXEEXT): $(examples_C_glib_vpn_import_libnm_OBJECTS) $(examples_C_glib_vpn_import_libnm_DEPENDENCIES) $(EXTRA_examples_C_glib_vpn_import_libnm_DEPENDENCIES) examples/C/glib/$(am__dirstamp) + @rm -f examples/C/glib/vpn-import-libnm$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(examples_C_glib_vpn_import_libnm_OBJECTS) $(examples_C_glib_vpn_import_libnm_LDADD) $(LIBS) examples/C/qt/$(am__dirstamp): @$(MKDIR_P) examples/C/qt @: > examples/C/qt/$(am__dirstamp) @@ -10788,140 +10776,6 @@ examples/C/qt/monitor_nm_running-monitor-nm-running.$(OBJEXT): \ examples/C/qt/monitor-nm-running$(EXEEXT): $(examples_C_qt_monitor_nm_running_OBJECTS) $(examples_C_qt_monitor_nm_running_DEPENDENCIES) $(EXTRA_examples_C_qt_monitor_nm_running_DEPENDENCIES) examples/C/qt/$(am__dirstamp) @rm -f examples/C/qt/monitor-nm-running$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(examples_C_qt_monitor_nm_running_OBJECTS) $(examples_C_qt_monitor_nm_running_LDADD) $(LIBS) -libnm-core/tests/$(am__dirstamp): - @$(MKDIR_P) libnm-core/tests - @: > libnm-core/tests/$(am__dirstamp) -libnm-core/tests/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) libnm-core/tests/$(DEPDIR) - @: > libnm-core/tests/$(DEPDIR)/$(am__dirstamp) -libnm-core/tests/test_compare-test-compare.$(OBJEXT): \ - libnm-core/tests/$(am__dirstamp) \ - libnm-core/tests/$(DEPDIR)/$(am__dirstamp) - -libnm-core/tests/test-compare$(EXEEXT): $(libnm_core_tests_test_compare_OBJECTS) $(libnm_core_tests_test_compare_DEPENDENCIES) $(EXTRA_libnm_core_tests_test_compare_DEPENDENCIES) libnm-core/tests/$(am__dirstamp) - @rm -f libnm-core/tests/test-compare$(EXEEXT) - $(AM_V_CCLD)$(libnm_core_tests_test_compare_LINK) $(libnm_core_tests_test_compare_OBJECTS) $(libnm_core_tests_test_compare_LDADD) $(LIBS) -libnm-core/tests/test_crypto-test-crypto.$(OBJEXT): \ - libnm-core/tests/$(am__dirstamp) \ - libnm-core/tests/$(DEPDIR)/$(am__dirstamp) - -libnm-core/tests/test-crypto$(EXEEXT): $(libnm_core_tests_test_crypto_OBJECTS) $(libnm_core_tests_test_crypto_DEPENDENCIES) $(EXTRA_libnm_core_tests_test_crypto_DEPENDENCIES) libnm-core/tests/$(am__dirstamp) - @rm -f libnm-core/tests/test-crypto$(EXEEXT) - $(AM_V_CCLD)$(libnm_core_tests_test_crypto_LINK) $(libnm_core_tests_test_crypto_OBJECTS) $(libnm_core_tests_test_crypto_LDADD) $(LIBS) -libnm-core/tests/test_general-test-general.$(OBJEXT): \ - libnm-core/tests/$(am__dirstamp) \ - libnm-core/tests/$(DEPDIR)/$(am__dirstamp) -libnm-core/tests/test_general-nm-core-tests-enum-types.$(OBJEXT): \ - libnm-core/tests/$(am__dirstamp) \ - libnm-core/tests/$(DEPDIR)/$(am__dirstamp) - -libnm-core/tests/test-general$(EXEEXT): $(libnm_core_tests_test_general_OBJECTS) $(libnm_core_tests_test_general_DEPENDENCIES) $(EXTRA_libnm_core_tests_test_general_DEPENDENCIES) libnm-core/tests/$(am__dirstamp) - @rm -f libnm-core/tests/test-general$(EXEEXT) - $(AM_V_CCLD)$(libnm_core_tests_test_general_LINK) $(libnm_core_tests_test_general_OBJECTS) $(libnm_core_tests_test_general_LDADD) $(LIBS) -libnm-core/tests/test_keyfile-test-keyfile.$(OBJEXT): \ - libnm-core/tests/$(am__dirstamp) \ - libnm-core/tests/$(DEPDIR)/$(am__dirstamp) - -libnm-core/tests/test-keyfile$(EXEEXT): $(libnm_core_tests_test_keyfile_OBJECTS) $(libnm_core_tests_test_keyfile_DEPENDENCIES) $(EXTRA_libnm_core_tests_test_keyfile_DEPENDENCIES) libnm-core/tests/$(am__dirstamp) - @rm -f libnm-core/tests/test-keyfile$(EXEEXT) - $(AM_V_CCLD)$(libnm_core_tests_test_keyfile_LINK) $(libnm_core_tests_test_keyfile_OBJECTS) $(libnm_core_tests_test_keyfile_LDADD) $(LIBS) -libnm-core/tests/test_secrets-test-secrets.$(OBJEXT): \ - libnm-core/tests/$(am__dirstamp) \ - libnm-core/tests/$(DEPDIR)/$(am__dirstamp) - -libnm-core/tests/test-secrets$(EXEEXT): $(libnm_core_tests_test_secrets_OBJECTS) $(libnm_core_tests_test_secrets_DEPENDENCIES) $(EXTRA_libnm_core_tests_test_secrets_DEPENDENCIES) libnm-core/tests/$(am__dirstamp) - @rm -f libnm-core/tests/test-secrets$(EXEEXT) - $(AM_V_CCLD)$(libnm_core_tests_test_secrets_LINK) $(libnm_core_tests_test_secrets_OBJECTS) $(libnm_core_tests_test_secrets_LDADD) $(LIBS) -libnm-core/tests/test_setting-test-setting.$(OBJEXT): \ - libnm-core/tests/$(am__dirstamp) \ - libnm-core/tests/$(DEPDIR)/$(am__dirstamp) - -libnm-core/tests/test-setting$(EXEEXT): $(libnm_core_tests_test_setting_OBJECTS) $(libnm_core_tests_test_setting_DEPENDENCIES) $(EXTRA_libnm_core_tests_test_setting_DEPENDENCIES) libnm-core/tests/$(am__dirstamp) - @rm -f libnm-core/tests/test-setting$(EXEEXT) - $(AM_V_CCLD)$(libnm_core_tests_test_setting_LINK) $(libnm_core_tests_test_setting_OBJECTS) $(libnm_core_tests_test_setting_LDADD) $(LIBS) -libnm-core/tests/test_settings_defaults-test-settings-defaults.$(OBJEXT): \ - libnm-core/tests/$(am__dirstamp) \ - libnm-core/tests/$(DEPDIR)/$(am__dirstamp) - -libnm-core/tests/test-settings-defaults$(EXEEXT): $(libnm_core_tests_test_settings_defaults_OBJECTS) $(libnm_core_tests_test_settings_defaults_DEPENDENCIES) $(EXTRA_libnm_core_tests_test_settings_defaults_DEPENDENCIES) libnm-core/tests/$(am__dirstamp) - @rm -f libnm-core/tests/test-settings-defaults$(EXEEXT) - $(AM_V_CCLD)$(libnm_core_tests_test_settings_defaults_LINK) $(libnm_core_tests_test_settings_defaults_OBJECTS) $(libnm_core_tests_test_settings_defaults_LDADD) $(LIBS) -shared/nm-utils/libnm_tests_test_libnm-nm-compat.$(OBJEXT): \ - shared/nm-utils/$(am__dirstamp) \ - shared/nm-utils/$(DEPDIR)/$(am__dirstamp) -libnm/tests/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) libnm/tests/$(DEPDIR) - @: > libnm/tests/$(DEPDIR)/$(am__dirstamp) -libnm/tests/test_libnm-test-libnm.$(OBJEXT): \ - libnm/tests/$(am__dirstamp) \ - libnm/tests/$(DEPDIR)/$(am__dirstamp) - -libnm/tests/test-libnm$(EXEEXT): $(libnm_tests_test_libnm_OBJECTS) $(libnm_tests_test_libnm_DEPENDENCIES) $(EXTRA_libnm_tests_test_libnm_DEPENDENCIES) libnm/tests/$(am__dirstamp) - @rm -f libnm/tests/test-libnm$(EXEEXT) - $(AM_V_CCLD)$(libnm_tests_test_libnm_LINK) $(libnm_tests_test_libnm_OBJECTS) $(libnm_tests_test_libnm_LDADD) $(LIBS) -shared/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/$(DEPDIR) - @: > shared/$(DEPDIR)/$(am__dirstamp) -shared/libnm_tests_test_nm_client-nm-test-utils-impl.$(OBJEXT): \ - shared/$(am__dirstamp) shared/$(DEPDIR)/$(am__dirstamp) -libnm/tests/test_nm_client-test-nm-client.$(OBJEXT): \ - libnm/tests/$(am__dirstamp) \ - libnm/tests/$(DEPDIR)/$(am__dirstamp) - -libnm/tests/test-nm-client$(EXEEXT): $(libnm_tests_test_nm_client_OBJECTS) $(libnm_tests_test_nm_client_DEPENDENCIES) $(EXTRA_libnm_tests_test_nm_client_DEPENDENCIES) libnm/tests/$(am__dirstamp) - @rm -f libnm/tests/test-nm-client$(EXEEXT) - $(AM_V_CCLD)$(libnm_tests_test_nm_client_LINK) $(libnm_tests_test_nm_client_OBJECTS) $(libnm_tests_test_nm_client_LDADD) $(LIBS) -shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.$(OBJEXT): \ - shared/$(am__dirstamp) shared/$(DEPDIR)/$(am__dirstamp) -libnm/tests/test_remote_settings_client-test-remote-settings-client.$(OBJEXT): \ - libnm/tests/$(am__dirstamp) \ - libnm/tests/$(DEPDIR)/$(am__dirstamp) - -libnm/tests/test-remote-settings-client$(EXEEXT): $(libnm_tests_test_remote_settings_client_OBJECTS) $(libnm_tests_test_remote_settings_client_DEPENDENCIES) $(EXTRA_libnm_tests_test_remote_settings_client_DEPENDENCIES) libnm/tests/$(am__dirstamp) - @rm -f libnm/tests/test-remote-settings-client$(EXEEXT) - $(AM_V_CCLD)$(libnm_tests_test_remote_settings_client_LINK) $(libnm_tests_test_remote_settings_client_OBJECTS) $(libnm_tests_test_remote_settings_client_LDADD) $(LIBS) -shared/libnm_tests_test_secret_agent-nm-test-utils-impl.$(OBJEXT): \ - shared/$(am__dirstamp) shared/$(DEPDIR)/$(am__dirstamp) -libnm/tests/test_secret_agent-test-secret-agent.$(OBJEXT): \ - libnm/tests/$(am__dirstamp) \ - libnm/tests/$(DEPDIR)/$(am__dirstamp) - -libnm/tests/test-secret-agent$(EXEEXT): $(libnm_tests_test_secret_agent_OBJECTS) $(libnm_tests_test_secret_agent_DEPENDENCIES) $(EXTRA_libnm_tests_test_secret_agent_DEPENDENCIES) libnm/tests/$(am__dirstamp) - @rm -f libnm/tests/test-secret-agent$(EXEEXT) - $(AM_V_CCLD)$(libnm_tests_test_secret_agent_LINK) $(libnm_tests_test_secret_agent_OBJECTS) $(libnm_tests_test_secret_agent_LDADD) $(LIBS) -shared/nm-glib-aux/tests/$(am__dirstamp): - @$(MKDIR_P) shared/nm-glib-aux/tests - @: > shared/nm-glib-aux/tests/$(am__dirstamp) -shared/nm-glib-aux/tests/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/nm-glib-aux/tests/$(DEPDIR) - @: > shared/nm-glib-aux/tests/$(DEPDIR)/$(am__dirstamp) -shared/nm-glib-aux/tests/test_json_aux-test-json-aux.$(OBJEXT): \ - shared/nm-glib-aux/tests/$(am__dirstamp) \ - shared/nm-glib-aux/tests/$(DEPDIR)/$(am__dirstamp) - -shared/nm-glib-aux/tests/test-json-aux$(EXEEXT): $(shared_nm_glib_aux_tests_test_json_aux_OBJECTS) $(shared_nm_glib_aux_tests_test_json_aux_DEPENDENCIES) $(EXTRA_shared_nm_glib_aux_tests_test_json_aux_DEPENDENCIES) shared/nm-glib-aux/tests/$(am__dirstamp) - @rm -f shared/nm-glib-aux/tests/test-json-aux$(EXEEXT) - $(AM_V_CCLD)$(shared_nm_glib_aux_tests_test_json_aux_LINK) $(shared_nm_glib_aux_tests_test_json_aux_OBJECTS) $(shared_nm_glib_aux_tests_test_json_aux_LDADD) $(LIBS) -shared/nm-glib-aux/tests/test_shared_general-test-shared-general.$(OBJEXT): \ - shared/nm-glib-aux/tests/$(am__dirstamp) \ - shared/nm-glib-aux/tests/$(DEPDIR)/$(am__dirstamp) - -shared/nm-glib-aux/tests/test-shared-general$(EXEEXT): $(shared_nm_glib_aux_tests_test_shared_general_OBJECTS) $(shared_nm_glib_aux_tests_test_shared_general_DEPENDENCIES) $(EXTRA_shared_nm_glib_aux_tests_test_shared_general_DEPENDENCIES) shared/nm-glib-aux/tests/$(am__dirstamp) - @rm -f shared/nm-glib-aux/tests/test-shared-general$(EXEEXT) - $(AM_V_CCLD)$(shared_nm_glib_aux_tests_test_shared_general_LINK) $(shared_nm_glib_aux_tests_test_shared_general_OBJECTS) $(shared_nm_glib_aux_tests_test_shared_general_LDADD) $(LIBS) -shared/nm-platform/tests/$(am__dirstamp): - @$(MKDIR_P) shared/nm-platform/tests - @: > shared/nm-platform/tests/$(am__dirstamp) -shared/nm-platform/tests/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) shared/nm-platform/tests/$(DEPDIR) - @: > shared/nm-platform/tests/$(DEPDIR)/$(am__dirstamp) -shared/nm-platform/tests/test_nm_platform-test-nm-platform.$(OBJEXT): \ - shared/nm-platform/tests/$(am__dirstamp) \ - shared/nm-platform/tests/$(DEPDIR)/$(am__dirstamp) - -shared/nm-platform/tests/test-nm-platform$(EXEEXT): $(shared_nm_platform_tests_test_nm_platform_OBJECTS) $(shared_nm_platform_tests_test_nm_platform_DEPENDENCIES) $(EXTRA_shared_nm_platform_tests_test_nm_platform_DEPENDENCIES) shared/nm-platform/tests/$(am__dirstamp) - @rm -f shared/nm-platform/tests/test-nm-platform$(EXEEXT) - $(AM_V_CCLD)$(shared_nm_platform_tests_test_nm_platform_LINK) $(shared_nm_platform_tests_test_nm_platform_OBJECTS) $(shared_nm_platform_tests_test_nm_platform_LDADD) $(LIBS) src/core/NetworkManager-main.$(OBJEXT): src/core/$(am__dirstamp) \ src/core/$(DEPDIR)/$(am__dirstamp) @@ -11036,40 +10890,6 @@ src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.$(OBJEXT): \ src/core/dnsmasq/tests/test-dnsmasq-utils$(EXEEXT): $(src_core_dnsmasq_tests_test_dnsmasq_utils_OBJECTS) $(src_core_dnsmasq_tests_test_dnsmasq_utils_DEPENDENCIES) $(EXTRA_src_core_dnsmasq_tests_test_dnsmasq_utils_DEPENDENCIES) src/core/dnsmasq/tests/$(am__dirstamp) @rm -f src/core/dnsmasq/tests/test-dnsmasq-utils$(EXEEXT) $(AM_V_CCLD)$(src_core_dnsmasq_tests_test_dnsmasq_utils_LINK) $(src_core_dnsmasq_tests_test_dnsmasq_utils_OBJECTS) $(src_core_dnsmasq_tests_test_dnsmasq_utils_LDADD) $(LIBS) -src/core/initrd/nm_initrd_generator-nm-initrd-generator.$(OBJEXT): \ - src/core/initrd/$(am__dirstamp) \ - src/core/initrd/$(DEPDIR)/$(am__dirstamp) - -src/core/initrd/nm-initrd-generator$(EXEEXT): $(src_core_initrd_nm_initrd_generator_OBJECTS) $(src_core_initrd_nm_initrd_generator_DEPENDENCIES) $(EXTRA_src_core_initrd_nm_initrd_generator_DEPENDENCIES) src/core/initrd/$(am__dirstamp) - @rm -f src/core/initrd/nm-initrd-generator$(EXEEXT) - $(AM_V_CCLD)$(src_core_initrd_nm_initrd_generator_LINK) $(src_core_initrd_nm_initrd_generator_OBJECTS) $(src_core_initrd_nm_initrd_generator_LDADD) $(LIBS) -src/core/initrd/tests/$(am__dirstamp): - @$(MKDIR_P) src/core/initrd/tests - @: > src/core/initrd/tests/$(am__dirstamp) -src/core/initrd/tests/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) src/core/initrd/tests/$(DEPDIR) - @: > src/core/initrd/tests/$(DEPDIR)/$(am__dirstamp) -src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.$(OBJEXT): \ - src/core/initrd/tests/$(am__dirstamp) \ - src/core/initrd/tests/$(DEPDIR)/$(am__dirstamp) - -src/core/initrd/tests/test-cmdline-reader$(EXEEXT): $(src_core_initrd_tests_test_cmdline_reader_OBJECTS) $(src_core_initrd_tests_test_cmdline_reader_DEPENDENCIES) $(EXTRA_src_core_initrd_tests_test_cmdline_reader_DEPENDENCIES) src/core/initrd/tests/$(am__dirstamp) - @rm -f src/core/initrd/tests/test-cmdline-reader$(EXEEXT) - $(AM_V_CCLD)$(src_core_initrd_tests_test_cmdline_reader_LINK) $(src_core_initrd_tests_test_cmdline_reader_OBJECTS) $(src_core_initrd_tests_test_cmdline_reader_LDADD) $(LIBS) -src/core/initrd/tests/test_dt_reader-test-dt-reader.$(OBJEXT): \ - src/core/initrd/tests/$(am__dirstamp) \ - src/core/initrd/tests/$(DEPDIR)/$(am__dirstamp) - -src/core/initrd/tests/test-dt-reader$(EXEEXT): $(src_core_initrd_tests_test_dt_reader_OBJECTS) $(src_core_initrd_tests_test_dt_reader_DEPENDENCIES) $(EXTRA_src_core_initrd_tests_test_dt_reader_DEPENDENCIES) src/core/initrd/tests/$(am__dirstamp) - @rm -f src/core/initrd/tests/test-dt-reader$(EXEEXT) - $(AM_V_CCLD)$(src_core_initrd_tests_test_dt_reader_LINK) $(src_core_initrd_tests_test_dt_reader_OBJECTS) $(src_core_initrd_tests_test_dt_reader_LDADD) $(LIBS) -src/core/initrd/tests/test_ibft_reader-test-ibft-reader.$(OBJEXT): \ - src/core/initrd/tests/$(am__dirstamp) \ - src/core/initrd/tests/$(DEPDIR)/$(am__dirstamp) - -src/core/initrd/tests/test-ibft-reader$(EXEEXT): $(src_core_initrd_tests_test_ibft_reader_OBJECTS) $(src_core_initrd_tests_test_ibft_reader_DEPENDENCIES) $(EXTRA_src_core_initrd_tests_test_ibft_reader_DEPENDENCIES) src/core/initrd/tests/$(am__dirstamp) - @rm -f src/core/initrd/tests/test-ibft-reader$(EXEEXT) - $(AM_V_CCLD)$(src_core_initrd_tests_test_ibft_reader_LINK) $(src_core_initrd_tests_test_ibft_reader_OBJECTS) $(src_core_initrd_tests_test_ibft_reader_LDADD) $(LIBS) src/core/ndisc/tests/$(am__dirstamp): @$(MKDIR_P) src/core/ndisc/tests @: > src/core/ndisc/tests/$(am__dirstamp) @@ -11324,6 +11144,374 @@ src/core/tests/test_wired_defname-test-wired-defname.$(OBJEXT): \ src/core/tests/test-wired-defname$(EXEEXT): $(src_core_tests_test_wired_defname_OBJECTS) $(src_core_tests_test_wired_defname_DEPENDENCIES) $(EXTRA_src_core_tests_test_wired_defname_DEPENDENCIES) src/core/tests/$(am__dirstamp) @rm -f src/core/tests/test-wired-defname$(EXEEXT) $(AM_V_CCLD)$(src_core_tests_test_wired_defname_LINK) $(src_core_tests_test_wired_defname_OBJECTS) $(src_core_tests_test_wired_defname_LDADD) $(LIBS) +src/libnm-client-aux-extern/tests/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-aux-extern/tests + @: > src/libnm-client-aux-extern/tests/$(am__dirstamp) +src/libnm-client-aux-extern/tests/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-aux-extern/tests/$(DEPDIR) + @: > src/libnm-client-aux-extern/tests/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.$(OBJEXT): \ + src/libnm-client-aux-extern/tests/$(am__dirstamp) \ + src/libnm-client-aux-extern/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-client-aux-extern/tests/test-libnm-client-aux$(EXEEXT): $(src_libnm_client_aux_extern_tests_test_libnm_client_aux_OBJECTS) $(src_libnm_client_aux_extern_tests_test_libnm_client_aux_DEPENDENCIES) $(EXTRA_src_libnm_client_aux_extern_tests_test_libnm_client_aux_DEPENDENCIES) src/libnm-client-aux-extern/tests/$(am__dirstamp) + @rm -f src/libnm-client-aux-extern/tests/test-libnm-client-aux$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_client_aux_extern_tests_test_libnm_client_aux_LINK) $(src_libnm_client_aux_extern_tests_test_libnm_client_aux_OBJECTS) $(src_libnm_client_aux_extern_tests_test_libnm_client_aux_LDADD) $(LIBS) +src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.$(OBJEXT): \ + src/contrib/$(am__dirstamp) \ + src/contrib/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/tests/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-impl/tests + @: > src/libnm-client-impl/tests/$(am__dirstamp) +src/libnm-client-impl/tests/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-client-impl/tests/$(DEPDIR) + @: > src/libnm-client-impl/tests/$(DEPDIR)/$(am__dirstamp) +src/libnm-client-impl/tests/test_libnm-test-libnm.$(OBJEXT): \ + src/libnm-client-impl/tests/$(am__dirstamp) \ + src/libnm-client-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-client-impl/tests/test-libnm$(EXEEXT): $(src_libnm_client_impl_tests_test_libnm_OBJECTS) $(src_libnm_client_impl_tests_test_libnm_DEPENDENCIES) $(EXTRA_src_libnm_client_impl_tests_test_libnm_DEPENDENCIES) src/libnm-client-impl/tests/$(am__dirstamp) + @rm -f src/libnm-client-impl/tests/test-libnm$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_client_impl_tests_test_libnm_LINK) $(src_libnm_client_impl_tests_test_libnm_OBJECTS) $(src_libnm_client_impl_tests_test_libnm_LDADD) $(LIBS) +src/libnm-client-impl/tests/test_nm_client-test-nm-client.$(OBJEXT): \ + src/libnm-client-impl/tests/$(am__dirstamp) \ + src/libnm-client-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-client-impl/tests/test-nm-client$(EXEEXT): $(src_libnm_client_impl_tests_test_nm_client_OBJECTS) $(src_libnm_client_impl_tests_test_nm_client_DEPENDENCIES) $(EXTRA_src_libnm_client_impl_tests_test_nm_client_DEPENDENCIES) src/libnm-client-impl/tests/$(am__dirstamp) + @rm -f src/libnm-client-impl/tests/test-nm-client$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_client_impl_tests_test_nm_client_LINK) $(src_libnm_client_impl_tests_test_nm_client_OBJECTS) $(src_libnm_client_impl_tests_test_nm_client_LDADD) $(LIBS) +src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.$(OBJEXT): \ + src/libnm-client-impl/tests/$(am__dirstamp) \ + src/libnm-client-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-client-impl/tests/test-remote-settings-client$(EXEEXT): $(src_libnm_client_impl_tests_test_remote_settings_client_OBJECTS) $(src_libnm_client_impl_tests_test_remote_settings_client_DEPENDENCIES) $(EXTRA_src_libnm_client_impl_tests_test_remote_settings_client_DEPENDENCIES) src/libnm-client-impl/tests/$(am__dirstamp) + @rm -f src/libnm-client-impl/tests/test-remote-settings-client$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_client_impl_tests_test_remote_settings_client_LINK) $(src_libnm_client_impl_tests_test_remote_settings_client_OBJECTS) $(src_libnm_client_impl_tests_test_remote_settings_client_LDADD) $(LIBS) +src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.$(OBJEXT): \ + src/libnm-client-impl/tests/$(am__dirstamp) \ + src/libnm-client-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-client-impl/tests/test-secret-agent$(EXEEXT): $(src_libnm_client_impl_tests_test_secret_agent_OBJECTS) $(src_libnm_client_impl_tests_test_secret_agent_DEPENDENCIES) $(EXTRA_src_libnm_client_impl_tests_test_secret_agent_DEPENDENCIES) src/libnm-client-impl/tests/$(am__dirstamp) + @rm -f src/libnm-client-impl/tests/test-secret-agent$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_client_impl_tests_test_secret_agent_LINK) $(src_libnm_client_impl_tests_test_secret_agent_OBJECTS) $(src_libnm_client_impl_tests_test_secret_agent_LDADD) $(LIBS) +src/libnm-core-impl/tests/$(am__dirstamp): + @$(MKDIR_P) src/libnm-core-impl/tests + @: > src/libnm-core-impl/tests/$(am__dirstamp) +src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-core-impl/tests/$(DEPDIR) + @: > src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/tests/test_compare-test-compare.$(OBJEXT): \ + src/libnm-core-impl/tests/$(am__dirstamp) \ + src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-impl/tests/test-compare$(EXEEXT): $(src_libnm_core_impl_tests_test_compare_OBJECTS) $(src_libnm_core_impl_tests_test_compare_DEPENDENCIES) $(EXTRA_src_libnm_core_impl_tests_test_compare_DEPENDENCIES) src/libnm-core-impl/tests/$(am__dirstamp) + @rm -f src/libnm-core-impl/tests/test-compare$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_core_impl_tests_test_compare_LINK) $(src_libnm_core_impl_tests_test_compare_OBJECTS) $(src_libnm_core_impl_tests_test_compare_LDADD) $(LIBS) +src/libnm-core-impl/tests/test_crypto-test-crypto.$(OBJEXT): \ + src/libnm-core-impl/tests/$(am__dirstamp) \ + src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-impl/tests/test-crypto$(EXEEXT): $(src_libnm_core_impl_tests_test_crypto_OBJECTS) $(src_libnm_core_impl_tests_test_crypto_DEPENDENCIES) $(EXTRA_src_libnm_core_impl_tests_test_crypto_DEPENDENCIES) src/libnm-core-impl/tests/$(am__dirstamp) + @rm -f src/libnm-core-impl/tests/test-crypto$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_core_impl_tests_test_crypto_LINK) $(src_libnm_core_impl_tests_test_crypto_OBJECTS) $(src_libnm_core_impl_tests_test_crypto_LDADD) $(LIBS) +src/libnm-core-impl/tests/test_general-test-general.$(OBJEXT): \ + src/libnm-core-impl/tests/$(am__dirstamp) \ + src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp) +src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.$(OBJEXT): \ + src/libnm-core-impl/tests/$(am__dirstamp) \ + src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-impl/tests/test-general$(EXEEXT): $(src_libnm_core_impl_tests_test_general_OBJECTS) $(src_libnm_core_impl_tests_test_general_DEPENDENCIES) $(EXTRA_src_libnm_core_impl_tests_test_general_DEPENDENCIES) src/libnm-core-impl/tests/$(am__dirstamp) + @rm -f src/libnm-core-impl/tests/test-general$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_core_impl_tests_test_general_LINK) $(src_libnm_core_impl_tests_test_general_OBJECTS) $(src_libnm_core_impl_tests_test_general_LDADD) $(LIBS) +src/libnm-core-impl/tests/test_keyfile-test-keyfile.$(OBJEXT): \ + src/libnm-core-impl/tests/$(am__dirstamp) \ + src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-impl/tests/test-keyfile$(EXEEXT): $(src_libnm_core_impl_tests_test_keyfile_OBJECTS) $(src_libnm_core_impl_tests_test_keyfile_DEPENDENCIES) $(EXTRA_src_libnm_core_impl_tests_test_keyfile_DEPENDENCIES) src/libnm-core-impl/tests/$(am__dirstamp) + @rm -f src/libnm-core-impl/tests/test-keyfile$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_core_impl_tests_test_keyfile_LINK) $(src_libnm_core_impl_tests_test_keyfile_OBJECTS) $(src_libnm_core_impl_tests_test_keyfile_LDADD) $(LIBS) +src/libnm-core-impl/tests/test_secrets-test-secrets.$(OBJEXT): \ + src/libnm-core-impl/tests/$(am__dirstamp) \ + src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-impl/tests/test-secrets$(EXEEXT): $(src_libnm_core_impl_tests_test_secrets_OBJECTS) $(src_libnm_core_impl_tests_test_secrets_DEPENDENCIES) $(EXTRA_src_libnm_core_impl_tests_test_secrets_DEPENDENCIES) src/libnm-core-impl/tests/$(am__dirstamp) + @rm -f src/libnm-core-impl/tests/test-secrets$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_core_impl_tests_test_secrets_LINK) $(src_libnm_core_impl_tests_test_secrets_OBJECTS) $(src_libnm_core_impl_tests_test_secrets_LDADD) $(LIBS) +src/libnm-core-impl/tests/test_setting-test-setting.$(OBJEXT): \ + src/libnm-core-impl/tests/$(am__dirstamp) \ + src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-impl/tests/test-setting$(EXEEXT): $(src_libnm_core_impl_tests_test_setting_OBJECTS) $(src_libnm_core_impl_tests_test_setting_DEPENDENCIES) $(EXTRA_src_libnm_core_impl_tests_test_setting_DEPENDENCIES) src/libnm-core-impl/tests/$(am__dirstamp) + @rm -f src/libnm-core-impl/tests/test-setting$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_core_impl_tests_test_setting_LINK) $(src_libnm_core_impl_tests_test_setting_OBJECTS) $(src_libnm_core_impl_tests_test_setting_LDADD) $(LIBS) +src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.$(OBJEXT): \ + src/libnm-core-impl/tests/$(am__dirstamp) \ + src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-core-impl/tests/test-settings-defaults$(EXEEXT): $(src_libnm_core_impl_tests_test_settings_defaults_OBJECTS) $(src_libnm_core_impl_tests_test_settings_defaults_DEPENDENCIES) $(EXTRA_src_libnm_core_impl_tests_test_settings_defaults_DEPENDENCIES) src/libnm-core-impl/tests/$(am__dirstamp) + @rm -f src/libnm-core-impl/tests/test-settings-defaults$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_core_impl_tests_test_settings_defaults_LINK) $(src_libnm_core_impl_tests_test_settings_defaults_OBJECTS) $(src_libnm_core_impl_tests_test_settings_defaults_LDADD) $(LIBS) +src/libnm-glib-aux/tests/$(am__dirstamp): + @$(MKDIR_P) src/libnm-glib-aux/tests + @: > src/libnm-glib-aux/tests/$(am__dirstamp) +src/libnm-glib-aux/tests/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-glib-aux/tests/$(DEPDIR) + @: > src/libnm-glib-aux/tests/$(DEPDIR)/$(am__dirstamp) +src/libnm-glib-aux/tests/test_json_aux-test-json-aux.$(OBJEXT): \ + src/libnm-glib-aux/tests/$(am__dirstamp) \ + src/libnm-glib-aux/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-glib-aux/tests/test-json-aux$(EXEEXT): $(src_libnm_glib_aux_tests_test_json_aux_OBJECTS) $(src_libnm_glib_aux_tests_test_json_aux_DEPENDENCIES) $(EXTRA_src_libnm_glib_aux_tests_test_json_aux_DEPENDENCIES) src/libnm-glib-aux/tests/$(am__dirstamp) + @rm -f src/libnm-glib-aux/tests/test-json-aux$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_glib_aux_tests_test_json_aux_LINK) $(src_libnm_glib_aux_tests_test_json_aux_OBJECTS) $(src_libnm_glib_aux_tests_test_json_aux_LDADD) $(LIBS) +src/libnm-glib-aux/tests/test_shared_general-test-shared-general.$(OBJEXT): \ + src/libnm-glib-aux/tests/$(am__dirstamp) \ + src/libnm-glib-aux/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-glib-aux/tests/test-shared-general$(EXEEXT): $(src_libnm_glib_aux_tests_test_shared_general_OBJECTS) $(src_libnm_glib_aux_tests_test_shared_general_DEPENDENCIES) $(EXTRA_src_libnm_glib_aux_tests_test_shared_general_DEPENDENCIES) src/libnm-glib-aux/tests/$(am__dirstamp) + @rm -f src/libnm-glib-aux/tests/test-shared-general$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_glib_aux_tests_test_shared_general_LINK) $(src_libnm_glib_aux_tests_test_shared_general_OBJECTS) $(src_libnm_glib_aux_tests_test_shared_general_LDADD) $(LIBS) +src/libnm-platform/tests/$(am__dirstamp): + @$(MKDIR_P) src/libnm-platform/tests + @: > src/libnm-platform/tests/$(am__dirstamp) +src/libnm-platform/tests/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnm-platform/tests/$(DEPDIR) + @: > src/libnm-platform/tests/$(DEPDIR)/$(am__dirstamp) +src/libnm-platform/tests/test_nm_platform-test-nm-platform.$(OBJEXT): \ + src/libnm-platform/tests/$(am__dirstamp) \ + src/libnm-platform/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnm-platform/tests/test-nm-platform$(EXEEXT): $(src_libnm_platform_tests_test_nm_platform_OBJECTS) $(src_libnm_platform_tests_test_nm_platform_DEPENDENCIES) $(EXTRA_src_libnm_platform_tests_test_nm_platform_DEPENDENCIES) src/libnm-platform/tests/$(am__dirstamp) + @rm -f src/libnm-platform/tests/test-nm-platform$(EXEEXT) + $(AM_V_CCLD)$(src_libnm_platform_tests_test_nm_platform_LINK) $(src_libnm_platform_tests_test_nm_platform_OBJECTS) $(src_libnm_platform_tests_test_nm_platform_LDADD) $(LIBS) +src/libnmc-setting/tests/$(am__dirstamp): + @$(MKDIR_P) src/libnmc-setting/tests + @: > src/libnmc-setting/tests/$(am__dirstamp) +src/libnmc-setting/tests/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/libnmc-setting/tests/$(DEPDIR) + @: > src/libnmc-setting/tests/$(DEPDIR)/$(am__dirstamp) +src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.$(OBJEXT): \ + src/libnmc-setting/tests/$(am__dirstamp) \ + src/libnmc-setting/tests/$(DEPDIR)/$(am__dirstamp) + +src/libnmc-setting/tests/test-libnmc-setting$(EXEEXT): $(src_libnmc_setting_tests_test_libnmc_setting_OBJECTS) $(src_libnmc_setting_tests_test_libnmc_setting_DEPENDENCIES) $(EXTRA_src_libnmc_setting_tests_test_libnmc_setting_DEPENDENCIES) src/libnmc-setting/tests/$(am__dirstamp) + @rm -f src/libnmc-setting/tests/test-libnmc-setting$(EXEEXT) + $(AM_V_CCLD)$(src_libnmc_setting_tests_test_libnmc_setting_LINK) $(src_libnmc_setting_tests_test_libnmc_setting_OBJECTS) $(src_libnmc_setting_tests_test_libnmc_setting_LDADD) $(LIBS) +src/nm-cloud-setup/nm_cloud_setup-main.$(OBJEXT): \ + src/nm-cloud-setup/$(am__dirstamp) \ + src/nm-cloud-setup/$(DEPDIR)/$(am__dirstamp) + +src/nm-cloud-setup/nm-cloud-setup$(EXEEXT): $(src_nm_cloud_setup_nm_cloud_setup_OBJECTS) $(src_nm_cloud_setup_nm_cloud_setup_DEPENDENCIES) $(EXTRA_src_nm_cloud_setup_nm_cloud_setup_DEPENDENCIES) src/nm-cloud-setup/$(am__dirstamp) + @rm -f src/nm-cloud-setup/nm-cloud-setup$(EXEEXT) + $(AM_V_CCLD)$(src_nm_cloud_setup_nm_cloud_setup_LINK) $(src_nm_cloud_setup_nm_cloud_setup_OBJECTS) $(src_nm_cloud_setup_nm_cloud_setup_LDADD) $(LIBS) +src/nm-cloud-setup/tests/$(am__dirstamp): + @$(MKDIR_P) src/nm-cloud-setup/tests + @: > src/nm-cloud-setup/tests/$(am__dirstamp) +src/nm-cloud-setup/tests/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nm-cloud-setup/tests/$(DEPDIR) + @: > src/nm-cloud-setup/tests/$(DEPDIR)/$(am__dirstamp) +src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.$(OBJEXT): \ + src/nm-cloud-setup/tests/$(am__dirstamp) \ + src/nm-cloud-setup/tests/$(DEPDIR)/$(am__dirstamp) + +src/nm-cloud-setup/tests/test-cloud-setup-general$(EXEEXT): $(src_nm_cloud_setup_tests_test_cloud_setup_general_OBJECTS) $(src_nm_cloud_setup_tests_test_cloud_setup_general_DEPENDENCIES) $(EXTRA_src_nm_cloud_setup_tests_test_cloud_setup_general_DEPENDENCIES) src/nm-cloud-setup/tests/$(am__dirstamp) + @rm -f src/nm-cloud-setup/tests/test-cloud-setup-general$(EXEEXT) + $(AM_V_CCLD)$(src_nm_cloud_setup_tests_test_cloud_setup_general_LINK) $(src_nm_cloud_setup_tests_test_cloud_setup_general_OBJECTS) $(src_nm_cloud_setup_tests_test_cloud_setup_general_LDADD) $(LIBS) +src/nm-dispatcher/nm_dispatcher-nm-dispatcher.$(OBJEXT): \ + src/nm-dispatcher/$(am__dirstamp) \ + src/nm-dispatcher/$(DEPDIR)/$(am__dirstamp) + +src/nm-dispatcher/nm-dispatcher$(EXEEXT): $(src_nm_dispatcher_nm_dispatcher_OBJECTS) $(src_nm_dispatcher_nm_dispatcher_DEPENDENCIES) $(EXTRA_src_nm_dispatcher_nm_dispatcher_DEPENDENCIES) src/nm-dispatcher/$(am__dirstamp) + @rm -f src/nm-dispatcher/nm-dispatcher$(EXEEXT) + $(AM_V_CCLD)$(src_nm_dispatcher_nm_dispatcher_LINK) $(src_nm_dispatcher_nm_dispatcher_OBJECTS) $(src_nm_dispatcher_nm_dispatcher_LDADD) $(LIBS) +src/nm-dispatcher/tests/$(am__dirstamp): + @$(MKDIR_P) src/nm-dispatcher/tests + @: > src/nm-dispatcher/tests/$(am__dirstamp) +src/nm-dispatcher/tests/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nm-dispatcher/tests/$(DEPDIR) + @: > src/nm-dispatcher/tests/$(DEPDIR)/$(am__dirstamp) +src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.$(OBJEXT): \ + src/nm-dispatcher/tests/$(am__dirstamp) \ + src/nm-dispatcher/tests/$(DEPDIR)/$(am__dirstamp) +src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.$(OBJEXT): \ + src/nm-dispatcher/$(am__dirstamp) \ + src/nm-dispatcher/$(DEPDIR)/$(am__dirstamp) + +src/nm-dispatcher/tests/test-dispatcher-envp$(EXEEXT): $(src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS) $(src_nm_dispatcher_tests_test_dispatcher_envp_DEPENDENCIES) $(EXTRA_src_nm_dispatcher_tests_test_dispatcher_envp_DEPENDENCIES) src/nm-dispatcher/tests/$(am__dirstamp) + @rm -f src/nm-dispatcher/tests/test-dispatcher-envp$(EXEEXT) + $(AM_V_CCLD)$(src_nm_dispatcher_tests_test_dispatcher_envp_LINK) $(src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS) $(src_nm_dispatcher_tests_test_dispatcher_envp_LDADD) $(LIBS) +src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.$(OBJEXT): \ + src/nm-initrd-generator/$(am__dirstamp) \ + src/nm-initrd-generator/$(DEPDIR)/$(am__dirstamp) + +src/nm-initrd-generator/nm-initrd-generator$(EXEEXT): $(src_nm_initrd_generator_nm_initrd_generator_OBJECTS) $(src_nm_initrd_generator_nm_initrd_generator_DEPENDENCIES) $(EXTRA_src_nm_initrd_generator_nm_initrd_generator_DEPENDENCIES) src/nm-initrd-generator/$(am__dirstamp) + @rm -f src/nm-initrd-generator/nm-initrd-generator$(EXEEXT) + $(AM_V_CCLD)$(src_nm_initrd_generator_nm_initrd_generator_LINK) $(src_nm_initrd_generator_nm_initrd_generator_OBJECTS) $(src_nm_initrd_generator_nm_initrd_generator_LDADD) $(LIBS) +src/nm-initrd-generator/tests/$(am__dirstamp): + @$(MKDIR_P) src/nm-initrd-generator/tests + @: > src/nm-initrd-generator/tests/$(am__dirstamp) +src/nm-initrd-generator/tests/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nm-initrd-generator/tests/$(DEPDIR) + @: > src/nm-initrd-generator/tests/$(DEPDIR)/$(am__dirstamp) +src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.$(OBJEXT): \ + src/nm-initrd-generator/tests/$(am__dirstamp) \ + src/nm-initrd-generator/tests/$(DEPDIR)/$(am__dirstamp) + +src/nm-initrd-generator/tests/test-cmdline-reader$(EXEEXT): $(src_nm_initrd_generator_tests_test_cmdline_reader_OBJECTS) $(src_nm_initrd_generator_tests_test_cmdline_reader_DEPENDENCIES) $(EXTRA_src_nm_initrd_generator_tests_test_cmdline_reader_DEPENDENCIES) src/nm-initrd-generator/tests/$(am__dirstamp) + @rm -f src/nm-initrd-generator/tests/test-cmdline-reader$(EXEEXT) + $(AM_V_CCLD)$(src_nm_initrd_generator_tests_test_cmdline_reader_LINK) $(src_nm_initrd_generator_tests_test_cmdline_reader_OBJECTS) $(src_nm_initrd_generator_tests_test_cmdline_reader_LDADD) $(LIBS) +src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.$(OBJEXT): \ + src/nm-initrd-generator/tests/$(am__dirstamp) \ + src/nm-initrd-generator/tests/$(DEPDIR)/$(am__dirstamp) + +src/nm-initrd-generator/tests/test-dt-reader$(EXEEXT): $(src_nm_initrd_generator_tests_test_dt_reader_OBJECTS) $(src_nm_initrd_generator_tests_test_dt_reader_DEPENDENCIES) $(EXTRA_src_nm_initrd_generator_tests_test_dt_reader_DEPENDENCIES) src/nm-initrd-generator/tests/$(am__dirstamp) + @rm -f src/nm-initrd-generator/tests/test-dt-reader$(EXEEXT) + $(AM_V_CCLD)$(src_nm_initrd_generator_tests_test_dt_reader_LINK) $(src_nm_initrd_generator_tests_test_dt_reader_OBJECTS) $(src_nm_initrd_generator_tests_test_dt_reader_LDADD) $(LIBS) +src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.$(OBJEXT): \ + src/nm-initrd-generator/tests/$(am__dirstamp) \ + src/nm-initrd-generator/tests/$(DEPDIR)/$(am__dirstamp) + +src/nm-initrd-generator/tests/test-ibft-reader$(EXEEXT): $(src_nm_initrd_generator_tests_test_ibft_reader_OBJECTS) $(src_nm_initrd_generator_tests_test_ibft_reader_DEPENDENCIES) $(EXTRA_src_nm_initrd_generator_tests_test_ibft_reader_DEPENDENCIES) src/nm-initrd-generator/tests/$(am__dirstamp) + @rm -f src/nm-initrd-generator/tests/test-ibft-reader$(EXEEXT) + $(AM_V_CCLD)$(src_nm_initrd_generator_tests_test_ibft_reader_LINK) $(src_nm_initrd_generator_tests_test_ibft_reader_OBJECTS) $(src_nm_initrd_generator_tests_test_ibft_reader_LDADD) $(LIBS) +src/nm-online/$(am__dirstamp): + @$(MKDIR_P) src/nm-online + @: > src/nm-online/$(am__dirstamp) +src/nm-online/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nm-online/$(DEPDIR) + @: > src/nm-online/$(DEPDIR)/$(am__dirstamp) +src/nm-online/nm_online-nm-online.$(OBJEXT): \ + src/nm-online/$(am__dirstamp) \ + src/nm-online/$(DEPDIR)/$(am__dirstamp) + +src/nm-online/nm-online$(EXEEXT): $(src_nm_online_nm_online_OBJECTS) $(src_nm_online_nm_online_DEPENDENCIES) $(EXTRA_src_nm_online_nm_online_DEPENDENCIES) src/nm-online/$(am__dirstamp) + @rm -f src/nm-online/nm-online$(EXEEXT) + $(AM_V_CCLD)$(src_nm_online_nm_online_LINK) $(src_nm_online_nm_online_OBJECTS) $(src_nm_online_nm_online_LDADD) $(LIBS) +src/nmcli/$(am__dirstamp): + @$(MKDIR_P) src/nmcli + @: > src/nmcli/$(am__dirstamp) +src/nmcli/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nmcli/$(DEPDIR) + @: > src/nmcli/$(DEPDIR)/$(am__dirstamp) +src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.$(OBJEXT): \ + src/nmcli/$(am__dirstamp) src/nmcli/$(DEPDIR)/$(am__dirstamp) + +src/nmcli/generate-docs-nm-settings-nmcli$(EXEEXT): $(src_nmcli_generate_docs_nm_settings_nmcli_OBJECTS) $(src_nmcli_generate_docs_nm_settings_nmcli_DEPENDENCIES) $(EXTRA_src_nmcli_generate_docs_nm_settings_nmcli_DEPENDENCIES) src/nmcli/$(am__dirstamp) + @rm -f src/nmcli/generate-docs-nm-settings-nmcli$(EXEEXT) + $(AM_V_CCLD)$(src_nmcli_generate_docs_nm_settings_nmcli_LINK) $(src_nmcli_generate_docs_nm_settings_nmcli_OBJECTS) $(src_nmcli_generate_docs_nm_settings_nmcli_LDADD) $(LIBS) +src/nmcli/nmcli-common.$(OBJEXT): src/nmcli/$(am__dirstamp) \ + src/nmcli/$(DEPDIR)/$(am__dirstamp) +src/nmcli/nmcli-utils.$(OBJEXT): src/nmcli/$(am__dirstamp) \ + src/nmcli/$(DEPDIR)/$(am__dirstamp) +src/nmcli/nmcli-agent.$(OBJEXT): src/nmcli/$(am__dirstamp) \ + src/nmcli/$(DEPDIR)/$(am__dirstamp) +src/nmcli/nmcli-general.$(OBJEXT): src/nmcli/$(am__dirstamp) \ + src/nmcli/$(DEPDIR)/$(am__dirstamp) +src/nmcli/nmcli-connections.$(OBJEXT): src/nmcli/$(am__dirstamp) \ + src/nmcli/$(DEPDIR)/$(am__dirstamp) +src/nmcli/nmcli-devices.$(OBJEXT): src/nmcli/$(am__dirstamp) \ + src/nmcli/$(DEPDIR)/$(am__dirstamp) +src/nmcli/nmcli-settings.$(OBJEXT): src/nmcli/$(am__dirstamp) \ + src/nmcli/$(DEPDIR)/$(am__dirstamp) +src/nmcli/nmcli-nmcli.$(OBJEXT): src/nmcli/$(am__dirstamp) \ + src/nmcli/$(DEPDIR)/$(am__dirstamp) +src/nmcli/nmcli-polkit-agent.$(OBJEXT): src/nmcli/$(am__dirstamp) \ + src/nmcli/$(DEPDIR)/$(am__dirstamp) + +src/nmcli/nmcli$(EXEEXT): $(src_nmcli_nmcli_OBJECTS) $(src_nmcli_nmcli_DEPENDENCIES) $(EXTRA_src_nmcli_nmcli_DEPENDENCIES) src/nmcli/$(am__dirstamp) + @rm -f src/nmcli/nmcli$(EXEEXT) + $(AM_V_CCLD)$(src_nmcli_nmcli_LINK) $(src_nmcli_nmcli_OBJECTS) $(src_nmcli_nmcli_LDADD) $(LIBS) +src/nmtui/$(am__dirstamp): + @$(MKDIR_P) src/nmtui + @: > src/nmtui/$(am__dirstamp) +src/nmtui/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nmtui/$(DEPDIR) + @: > src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmtui.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmtui-connect.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmtui-edit.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmtui-hostname.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nm-editor-bindings.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nm-editor-utils.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-address-list.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-connect-connection-list.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-device-entry.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-edit-connection-list.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-editor-grid.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-editor-page.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-editor-page-device.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-editor-section.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-editor.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-ip-entry.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-mac-entry.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-mtu-entry.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-bond.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-bridge.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-bridge-port.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-dsl.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-ethernet.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-infiniband.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-ip-tunnel.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-ip4.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-ip6.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-ppp.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-team.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-team-port.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-vlan.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-page-wifi.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-password-dialog.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-password-fields.$(OBJEXT): \ + src/nmtui/$(am__dirstamp) src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-route-editor.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-route-entry.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-route-table.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-slave-list.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-utils.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) +src/nmtui/nmtui-nmt-widget-list.$(OBJEXT): src/nmtui/$(am__dirstamp) \ + src/nmtui/$(DEPDIR)/$(am__dirstamp) + +src/nmtui/nmtui$(EXEEXT): $(src_nmtui_nmtui_OBJECTS) $(src_nmtui_nmtui_DEPENDENCIES) $(EXTRA_src_nmtui_nmtui_DEPENDENCIES) src/nmtui/$(am__dirstamp) + @rm -f src/nmtui/nmtui$(EXEEXT) + $(AM_V_CCLD)$(src_nmtui_nmtui_LINK) $(src_nmtui_nmtui_OBJECTS) $(src_nmtui_nmtui_LDADD) $(LIBS) install-dist_libexecSCRIPTS: $(dist_libexec_SCRIPTS) @$(NORMAL_INSTALL) @list='$(dist_libexec_SCRIPTS)'; test -n "$(libexecdir)" || list=; \ @@ -11362,69 +11550,16 @@ uninstall-dist_libexecSCRIPTS: mostlyclean-compile: -rm -f *.$(OBJEXT) - -rm -f clients/*.$(OBJEXT) - -rm -f clients/cli/*.$(OBJEXT) - -rm -f clients/cloud-setup/*.$(OBJEXT) - -rm -f clients/cloud-setup/tests/*.$(OBJEXT) - -rm -f clients/common/*.$(OBJEXT) - -rm -f clients/common/*.lo - -rm -f clients/common/tests/*.$(OBJEXT) - -rm -f clients/tui/*.$(OBJEXT) - -rm -f clients/tui/newt/*.$(OBJEXT) - -rm -f dispatcher/*.$(OBJEXT) - -rm -f dispatcher/*.lo - -rm -f dispatcher/tests/*.$(OBJEXT) -rm -f examples/C/glib/*.$(OBJEXT) -rm -f examples/C/qt/*.$(OBJEXT) -rm -f introspection/*.$(OBJEXT) -rm -f introspection/*.lo - -rm -f libnm-core/*.$(OBJEXT) - -rm -f libnm-core/*.lo - -rm -f libnm-core/nm-libnm-core-aux/*.$(OBJEXT) - -rm -f libnm-core/nm-libnm-core-aux/*.lo - -rm -f libnm-core/nm-libnm-core-intern/*.$(OBJEXT) - -rm -f libnm-core/nm-libnm-core-intern/*.lo - -rm -f libnm-core/tests/*.$(OBJEXT) - -rm -f libnm/*.$(OBJEXT) - -rm -f libnm/*.lo - -rm -f libnm/nm-libnm-aux/*.$(OBJEXT) - -rm -f libnm/nm-libnm-aux/*.lo - -rm -f libnm/tests/*.$(OBJEXT) - -rm -f shared/*.$(OBJEXT) - -rm -f shared/c-rbtree/src/*.$(OBJEXT) - -rm -f shared/c-rbtree/src/*.lo - -rm -f shared/c-siphash/src/*.$(OBJEXT) - -rm -f shared/c-siphash/src/*.lo - -rm -f shared/n-acd/src/*.$(OBJEXT) - -rm -f shared/n-acd/src/*.lo - -rm -f shared/n-acd/src/util/*.$(OBJEXT) - -rm -f shared/n-acd/src/util/*.lo - -rm -f shared/n-dhcp4/src/*.$(OBJEXT) - -rm -f shared/n-dhcp4/src/*.lo - -rm -f shared/n-dhcp4/src/util/*.$(OBJEXT) - -rm -f shared/n-dhcp4/src/util/*.lo - -rm -f shared/nm-base/*.$(OBJEXT) - -rm -f shared/nm-base/*.lo - -rm -f shared/nm-glib-aux/*.$(OBJEXT) - -rm -f shared/nm-glib-aux/*.lo - -rm -f shared/nm-glib-aux/tests/*.$(OBJEXT) - -rm -f shared/nm-log-core/*.$(OBJEXT) - -rm -f shared/nm-log-core/*.lo - -rm -f shared/nm-platform/*.$(OBJEXT) - -rm -f shared/nm-platform/*.lo - -rm -f shared/nm-platform/tests/*.$(OBJEXT) - -rm -f shared/nm-std-aux/*.$(OBJEXT) - -rm -f shared/nm-std-aux/*.lo - -rm -f shared/nm-udev-aux/*.$(OBJEXT) - -rm -f shared/nm-udev-aux/*.lo - -rm -f shared/nm-utils/*.$(OBJEXT) - -rm -f shared/nm-utils/*.lo - -rm -f shared/systemd/*.$(OBJEXT) - -rm -f shared/systemd/*.lo - -rm -f shared/systemd/src/basic/*.$(OBJEXT) - -rm -f shared/systemd/src/basic/*.lo - -rm -f shared/systemd/src/shared/*.$(OBJEXT) - -rm -f shared/systemd/src/shared/*.lo + -rm -f src/c-rbtree/src/*.$(OBJEXT) + -rm -f src/c-rbtree/src/*.lo + -rm -f src/c-siphash/src/*.$(OBJEXT) + -rm -f src/c-siphash/src/*.lo + -rm -f src/contrib/*.$(OBJEXT) + -rm -f src/contrib/*.lo -rm -f src/core/*.$(OBJEXT) -rm -f src/core/*.lo -rm -f src/core/devices/*.$(OBJEXT) @@ -11453,9 +11588,6 @@ mostlyclean-compile: -rm -f src/core/dnsmasq/*.$(OBJEXT) -rm -f src/core/dnsmasq/*.lo -rm -f src/core/dnsmasq/tests/*.$(OBJEXT) - -rm -f src/core/initrd/*.$(OBJEXT) - -rm -f src/core/initrd/*.lo - -rm -f src/core/initrd/tests/*.$(OBJEXT) -rm -f src/core/ndisc/*.$(OBJEXT) -rm -f src/core/ndisc/*.lo -rm -f src/core/ndisc/tests/*.$(OBJEXT) @@ -11463,10 +11595,6 @@ mostlyclean-compile: -rm -f src/core/platform/*.lo -rm -f src/core/platform/tests/*.$(OBJEXT) -rm -f src/core/platform/tests/*.lo - -rm -f src/core/platform/wifi/*.$(OBJEXT) - -rm -f src/core/platform/wifi/*.lo - -rm -f src/core/platform/wpan/*.$(OBJEXT) - -rm -f src/core/platform/wpan/*.lo -rm -f src/core/ppp/*.$(OBJEXT) -rm -f src/core/ppp/*.lo -rm -f src/core/settings/*.$(OBJEXT) @@ -11497,102 +11625,80 @@ mostlyclean-compile: -rm -f src/core/tests/config/*.$(OBJEXT) -rm -f src/core/vpn/*.$(OBJEXT) -rm -f src/core/vpn/*.lo + -rm -f src/libnm-base/*.$(OBJEXT) + -rm -f src/libnm-base/*.lo + -rm -f src/libnm-client-aux-extern/*.$(OBJEXT) + -rm -f src/libnm-client-aux-extern/*.lo + -rm -f src/libnm-client-aux-extern/tests/*.$(OBJEXT) + -rm -f src/libnm-client-impl/*.$(OBJEXT) + -rm -f src/libnm-client-impl/*.lo + -rm -f src/libnm-client-impl/tests/*.$(OBJEXT) + -rm -f src/libnm-client-public/*.$(OBJEXT) + -rm -f src/libnm-client-public/*.lo + -rm -f src/libnm-client-test/*.$(OBJEXT) + -rm -f src/libnm-client-test/*.lo + -rm -f src/libnm-core-aux-extern/*.$(OBJEXT) + -rm -f src/libnm-core-aux-extern/*.lo + -rm -f src/libnm-core-aux-intern/*.$(OBJEXT) + -rm -f src/libnm-core-aux-intern/*.lo + -rm -f src/libnm-core-impl/*.$(OBJEXT) + -rm -f src/libnm-core-impl/*.lo + -rm -f src/libnm-core-impl/tests/*.$(OBJEXT) + -rm -f src/libnm-core-public/*.$(OBJEXT) + -rm -f src/libnm-core-public/*.lo + -rm -f src/libnm-glib-aux/*.$(OBJEXT) + -rm -f src/libnm-glib-aux/*.lo + -rm -f src/libnm-glib-aux/tests/*.$(OBJEXT) + -rm -f src/libnm-log-core/*.$(OBJEXT) + -rm -f src/libnm-log-core/*.lo + -rm -f src/libnm-log-null/*.$(OBJEXT) + -rm -f src/libnm-log-null/*.lo + -rm -f src/libnm-platform/*.$(OBJEXT) + -rm -f src/libnm-platform/*.lo + -rm -f src/libnm-platform/tests/*.$(OBJEXT) + -rm -f src/libnm-platform/wifi/*.$(OBJEXT) + -rm -f src/libnm-platform/wifi/*.lo + -rm -f src/libnm-platform/wpan/*.$(OBJEXT) + -rm -f src/libnm-platform/wpan/*.lo + -rm -f src/libnm-std-aux/*.$(OBJEXT) + -rm -f src/libnm-std-aux/*.lo + -rm -f src/libnm-systemd-shared/*.$(OBJEXT) + -rm -f src/libnm-systemd-shared/*.lo + -rm -f src/libnm-systemd-shared/src/basic/*.$(OBJEXT) + -rm -f src/libnm-systemd-shared/src/basic/*.lo + -rm -f src/libnm-systemd-shared/src/shared/*.$(OBJEXT) + -rm -f src/libnm-systemd-shared/src/shared/*.lo + -rm -f src/libnm-udev-aux/*.$(OBJEXT) + -rm -f src/libnm-udev-aux/*.lo + -rm -f src/libnmc-base/*.$(OBJEXT) + -rm -f src/libnmc-base/*.lo + -rm -f src/libnmc-setting/*.$(OBJEXT) + -rm -f src/libnmc-setting/*.lo + -rm -f src/libnmc-setting/tests/*.$(OBJEXT) + -rm -f src/libnmt-newt/*.$(OBJEXT) + -rm -f src/n-acd/src/*.$(OBJEXT) + -rm -f src/n-acd/src/*.lo + -rm -f src/n-acd/src/util/*.$(OBJEXT) + -rm -f src/n-acd/src/util/*.lo + -rm -f src/n-dhcp4/src/*.$(OBJEXT) + -rm -f src/n-dhcp4/src/*.lo + -rm -f src/n-dhcp4/src/util/*.$(OBJEXT) + -rm -f src/n-dhcp4/src/util/*.lo + -rm -f src/nm-cloud-setup/*.$(OBJEXT) + -rm -f src/nm-cloud-setup/tests/*.$(OBJEXT) + -rm -f src/nm-dispatcher/*.$(OBJEXT) + -rm -f src/nm-dispatcher/*.lo + -rm -f src/nm-dispatcher/tests/*.$(OBJEXT) + -rm -f src/nm-initrd-generator/*.$(OBJEXT) + -rm -f src/nm-initrd-generator/*.lo + -rm -f src/nm-initrd-generator/tests/*.$(OBJEXT) + -rm -f src/nm-online/*.$(OBJEXT) + -rm -f src/nmcli/*.$(OBJEXT) + -rm -f src/nmtui/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@clients/$(DEPDIR)/nm_online-nm-online.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cli/$(DEPDIR)/nmcli-agent.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cli/$(DEPDIR)/nmcli-common.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cli/$(DEPDIR)/nmcli-connections.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cli/$(DEPDIR)/nmcli-devices.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cli/$(DEPDIR)/nmcli-general.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cli/$(DEPDIR)/nmcli-nmcli.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cli/$(DEPDIR)/nmcli-polkit-agent.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cli/$(DEPDIR)/nmcli-settings.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cli/$(DEPDIR)/nmcli-utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/common/$(DEPDIR)/libnmc_base_la-nm-client-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/common/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/common/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/common/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-access.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-base-impl.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-desc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/common/tests/$(DEPDIR)/test_clients_common-test-clients-common.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/common/tests/$(DEPDIR)/test_libnm_core_aux-test-libnm-core-aux.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nm-editor-bindings.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nm-editor-utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-address-list.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-device-entry.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-editor-grid.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-editor-page.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-editor-section.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-editor.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-ip-entry.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-mac-entry.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-bond.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-dsl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-ip4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-ip6.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-ppp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-team-port.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-team.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-vlan.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-page-wifi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-password-dialog.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-password-fields.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-route-editor.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-route-entry.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-route-table.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-slave-list.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmt-widget-list.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmtui-connect.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmtui-edit.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmtui-hostname.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/$(DEPDIR)/nmtui-nmtui.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Po@am__quote@ # am--include-marker @@ -11601,6 +11707,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@examples/C/glib/$(DEPDIR)/vpn_import_libnm-vpn-import-libnm.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@examples/C/qt/$(DEPDIR)/add_connection_wired-add-connection-wired.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@examples/C/qt/$(DEPDIR)/change_ipv4_addresses-change-ipv4-addresses.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@examples/C/qt/$(DEPDIR)/list_connections-list-connections.Po@am__quote@ # am--include-marker @@ -11653,229 +11760,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.VPN.Connection.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.VPN.Plugin.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.WifiP2PPeer.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-connection.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-core-enum-types.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-crypto.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-dbus-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-errors.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-meta-setting-base-impl.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-property-compare.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-6lowpan.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-8021x.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-adsl.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bluetooth.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bond.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge-port.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-cdma.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-connection.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dcb.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dummy.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ethtool.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-generic.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-gsm.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-hostname.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-infiniband.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-config.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-tunnel.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip4-config.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip6-config.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macsec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macvlan.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-match.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-olpc-mesh.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-bridge.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-dpdk.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-external-ids.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-interface.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-patch.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-port.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ppp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-pppoe.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-proxy.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-serial.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-sriov.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tc-config.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team-port.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tun.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-user.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-veth.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vlan.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vpn.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vrf.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vxlan.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wifi-p2p.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wimax.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wired.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireguard.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless-security.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wpan.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-setting.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-simple-connection.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-team-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-editor-plugin.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-plugin-info.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/nm-libnm-core-aux/$(DEPDIR)/libnm_libnm_core_aux_la-nm-libnm-core-aux.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-auth-subject.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-libnm-core-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/tests/$(DEPDIR)/test_compare-test-compare.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/tests/$(DEPDIR)/test_crypto-test-crypto.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/tests/$(DEPDIR)/test_general-test-general.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/tests/$(DEPDIR)/test_secrets-test-secrets.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/tests/$(DEPDIR)/test_setting-test-setting.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm-core/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-access-point.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-active-connection.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-checkpoint.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-client.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-dbus-helpers.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-6lowpan.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-adsl.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-bond.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-bridge.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-bt.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-dummy.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-ethernet.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-generic.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-infiniband.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-ip-tunnel.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-macsec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-macvlan.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-modem.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-olpc-mesh.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-bridge.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-interface.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-port.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-ppp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-team.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-tun.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-veth.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-vlan.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-vrf.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-vxlan.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi-p2p.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-wimax.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-wireguard.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device-wpan.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-device.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-dhcp-config.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-dhcp4-config.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-dhcp6-config.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-dns-manager.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-enum-types.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-ip-config.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-ip4-config.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-ip6-config.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-libnm-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-object.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-remote-connection.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-secret-agent-old.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-vpn-connection.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-vpn-editor.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-vpn-plugin-old.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-vpn-service-plugin.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-wifi-p2p-peer.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/$(DEPDIR)/libnm_static_la-nm-wimax-nsp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/nm-libnm-aux/$(DEPDIR)/libnm_libnm_aux_la-nm-libnm-aux.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/tests/$(DEPDIR)/test_libnm-test-libnm.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libnm/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/$(DEPDIR)/libnm_tests_test_nm_client-nm-test-utils-impl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/$(DEPDIR)/libnm_tests_test_remote_settings_client-nm-test-utils-impl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/$(DEPDIR)/libnm_tests_test_secret_agent-nm-test-utils-impl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/c-rbtree/src/$(DEPDIR)/libcrbtree_la-c-rbtree.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/c-siphash/src/$(DEPDIR)/libcsiphash_la-c-siphash.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf-fallback.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-probe.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-acd/src/util/$(DEPDIR)/libnacd_la-timer.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-connection.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-lease.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-probe.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-client.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-incoming.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-outgoing.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-socket.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-packet.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-socket.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-utils/$(DEPDIR)/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/nm-utils/$(DEPDIR)/libnm_tests_test_libnm-nm-compat.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/$(DEPDIR)/libnm_systemd_logging_stub_la-nm-logging-stub.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/c-rbtree/src/$(DEPDIR)/libc_rbtree_la-c-rbtree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/c-siphash/src/$(DEPDIR)/libc_siphash_la-c-siphash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/contrib/$(DEPDIR)/libnm_client_impl_tests_test_libnm-nm-compat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/contrib/$(DEPDIR)/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/NetworkManager-main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/NetworkManager_all_sym-main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/$(DEPDIR)/libNetworkManagerBase_la-NetworkManagerUtils.Plo@am__quote@ # am--include-marker @@ -11996,22 +11884,11 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-manager.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/initrd/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/initrd/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/initrd/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/initrd/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-lndp-ndisc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-ndisc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/ndisc/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-ndisc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-linux-platform.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-platform.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-object.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-rules-manager.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-platform.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/tests/$(DEPDIR)/libNetworkManagerTest_la-test-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/tests/$(DEPDIR)/monitor-monitor.Po@am__quote@ # am--include-marker @@ -12027,10 +11904,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-nl80211.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-wext.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@src/core/platform/wpan/$(DEPDIR)/libNetworkManagerBase_la-nm-wpan-utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/ppp/$(DEPDIR)/libNetworkManager_la-nm-ppp-manager-call.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/ppp/$(DEPDIR)/libnm_ppp_plugin_la-nm-ppp-manager.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/ppp/$(DEPDIR)/nm_pppd_plugin_la-nm-pppd-plugin.Plo@am__quote@ # am--include-marker @@ -12102,6 +11975,331 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/core/tests/config/$(DEPDIR)/test_config-test-config.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-connection.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-base/$(DEPDIR)/libnm_base_la-nm-net-aux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-aux-extern/$(DEPDIR)/libnm_client_aux_extern_la-nm-libnm-aux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-aux-extern/tests/$(DEPDIR)/test_libnm_client_aux-test-libnm-client-aux.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-access-point.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-active-connection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-checkpoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-client.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dbus-helpers.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-6lowpan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-adsl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bond.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bridge.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-dummy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ethernet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-generic.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-infiniband.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ip-tunnel.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macsec.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macvlan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-modem.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-olpc-mesh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-bridge.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-interface.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-port.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ppp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-team.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-tun.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-veth.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vlan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vrf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vxlan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi-p2p.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wimax.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wireguard.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wpan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp4-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp6-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dns-manager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip4-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip6-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-libnm-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-object.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-remote-connection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-secret-agent-old.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-connection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-editor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-plugin-old.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-service-plugin.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wifi-p2p-peer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wimax-nsp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/tests/$(DEPDIR)/test_libnm-test-libnm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-impl/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-public/$(DEPDIR)/libnm_client_impl_libnm_client_impl_la-nm-enum-types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-client-test/$(DEPDIR)/libnm_client_test_la-nm-test-utils-impl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-aux-extern/$(DEPDIR)/libnm_core_aux_extern_la-nm-libnm-core-aux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-auth-subject.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-libnm-core-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-connection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-crypto.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-dbus-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-errors.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-meta-setting-base-impl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-property-compare.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-6lowpan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-8021x.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-adsl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bluetooth.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bond.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge-port.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-cdma.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-connection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dcb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dummy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ethtool.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-generic.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-gsm.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-hostname.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-infiniband.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-tunnel.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip4-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip6-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macsec.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macvlan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-match.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-olpc-mesh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-bridge.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-dpdk.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-external-ids.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-interface.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-patch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-port.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ppp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-pppoe.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-proxy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-serial.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-sriov.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tc-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team-port.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tun.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-user.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-veth.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vlan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vpn.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vrf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vxlan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wifi-p2p.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wimax.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wired.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireguard.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless-security.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wpan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-simple-connection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-team-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-editor-plugin.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-plugin-info.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/tests/$(DEPDIR)/test_compare-test-compare.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/tests/$(DEPDIR)/test_crypto-test-crypto.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/tests/$(DEPDIR)/test_general-test-general.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/tests/$(DEPDIR)/test_secrets-test-secrets.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/tests/$(DEPDIR)/test_setting-test-setting.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-impl/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-core-public/$(DEPDIR)/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-log-null/$(DEPDIR)/libnm_log_null_la-nm-logging-null.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-linux-platform.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-object.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-rules-manager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-nl80211.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-wext.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-platform/wpan/$(DEPDIR)/libnm_platform_la-nm-wpan-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-client-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-access.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-base-impl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-desc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmc-setting/tests/$(DEPDIR)/test_libnmc_setting-test-libnmc-setting.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf-fallback.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-probe.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-acd/src/util/$(DEPDIR)/libn_acd_la-timer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-connection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-lease.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-probe.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-client.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-incoming.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-outgoing.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-socket.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-packet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-socket.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-initrd-generator/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-initrd-generator/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-initrd-generator/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-initrd-generator/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nm-online/$(DEPDIR)/nm_online-nm-online.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmcli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmcli/$(DEPDIR)/nmcli-agent.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmcli/$(DEPDIR)/nmcli-common.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmcli/$(DEPDIR)/nmcli-connections.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmcli/$(DEPDIR)/nmcli-devices.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmcli/$(DEPDIR)/nmcli-general.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmcli/$(DEPDIR)/nmcli-nmcli.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmcli/$(DEPDIR)/nmcli-polkit-agent.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmcli/$(DEPDIR)/nmcli-settings.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmcli/$(DEPDIR)/nmcli-utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nm-editor-bindings.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nm-editor-utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-address-list.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-device-entry.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-editor-grid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-editor-section.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-editor.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-ip-entry.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-mac-entry.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-bond.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-dsl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip4.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip6.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-ppp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-team-port.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-team.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-vlan.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-page-wifi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-password-dialog.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-password-fields.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-route-editor.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-route-entry.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-route-table.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-slave-list.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmt-widget-list.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmtui-connect.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmtui-edit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmtui-hostname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/nmtui/$(DEPDIR)/nmtui-nmtui.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @@ -12133,425 +12331,369 @@ am--depfiles: $(am__depfiles_remade) @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.o: clients/cloud-setup/nm-cloud-setup-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.o -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.o `test -f 'clients/cloud-setup/nm-cloud-setup-utils.c' || echo '$(srcdir)/'`clients/cloud-setup/nm-cloud-setup-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nm-cloud-setup-utils.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.o `test -f 'clients/cloud-setup/nm-cloud-setup-utils.c' || echo '$(srcdir)/'`clients/cloud-setup/nm-cloud-setup-utils.c - -clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.obj: clients/cloud-setup/nm-cloud-setup-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.obj -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.obj `if test -f 'clients/cloud-setup/nm-cloud-setup-utils.c'; then $(CYGPATH_W) 'clients/cloud-setup/nm-cloud-setup-utils.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nm-cloud-setup-utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nm-cloud-setup-utils.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.obj `if test -f 'clients/cloud-setup/nm-cloud-setup-utils.c'; then $(CYGPATH_W) 'clients/cloud-setup/nm-cloud-setup-utils.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nm-cloud-setup-utils.c'; fi` - -clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.o: clients/cloud-setup/nm-http-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.o -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.o `test -f 'clients/cloud-setup/nm-http-client.c' || echo '$(srcdir)/'`clients/cloud-setup/nm-http-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nm-http-client.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.o `test -f 'clients/cloud-setup/nm-http-client.c' || echo '$(srcdir)/'`clients/cloud-setup/nm-http-client.c - -clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.obj: clients/cloud-setup/nm-http-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.obj -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.obj `if test -f 'clients/cloud-setup/nm-http-client.c'; then $(CYGPATH_W) 'clients/cloud-setup/nm-http-client.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nm-http-client.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nm-http-client.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nm-http-client.obj `if test -f 'clients/cloud-setup/nm-http-client.c'; then $(CYGPATH_W) 'clients/cloud-setup/nm-http-client.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nm-http-client.c'; fi` - -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.o: clients/cloud-setup/nmcs-provider.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.o -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.o `test -f 'clients/cloud-setup/nmcs-provider.c' || echo '$(srcdir)/'`clients/cloud-setup/nmcs-provider.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nmcs-provider.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.o `test -f 'clients/cloud-setup/nmcs-provider.c' || echo '$(srcdir)/'`clients/cloud-setup/nmcs-provider.c - -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.obj: clients/cloud-setup/nmcs-provider.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.obj -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.obj `if test -f 'clients/cloud-setup/nmcs-provider.c'; then $(CYGPATH_W) 'clients/cloud-setup/nmcs-provider.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nmcs-provider.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nmcs-provider.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.obj `if test -f 'clients/cloud-setup/nmcs-provider.c'; then $(CYGPATH_W) 'clients/cloud-setup/nmcs-provider.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nmcs-provider.c'; fi` - -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.o: clients/cloud-setup/nmcs-provider-ec2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.o -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.o `test -f 'clients/cloud-setup/nmcs-provider-ec2.c' || echo '$(srcdir)/'`clients/cloud-setup/nmcs-provider-ec2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nmcs-provider-ec2.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.o `test -f 'clients/cloud-setup/nmcs-provider-ec2.c' || echo '$(srcdir)/'`clients/cloud-setup/nmcs-provider-ec2.c - -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.obj: clients/cloud-setup/nmcs-provider-ec2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.obj -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.obj `if test -f 'clients/cloud-setup/nmcs-provider-ec2.c'; then $(CYGPATH_W) 'clients/cloud-setup/nmcs-provider-ec2.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nmcs-provider-ec2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nmcs-provider-ec2.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.o: src/libnmt-newt/nmt-newt-button-box.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.o `test -f 'src/libnmt-newt/nmt-newt-button-box.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-button-box.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-button-box.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.obj `if test -f 'clients/cloud-setup/nmcs-provider-ec2.c'; then $(CYGPATH_W) 'clients/cloud-setup/nmcs-provider-ec2.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nmcs-provider-ec2.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.o `test -f 'src/libnmt-newt/nmt-newt-button-box.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-button-box.c -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.o: clients/cloud-setup/nmcs-provider-gcp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.o -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.o `test -f 'clients/cloud-setup/nmcs-provider-gcp.c' || echo '$(srcdir)/'`clients/cloud-setup/nmcs-provider-gcp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nmcs-provider-gcp.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.obj: src/libnmt-newt/nmt-newt-button-box.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.obj `if test -f 'src/libnmt-newt/nmt-newt-button-box.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-button-box.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-button-box.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-button-box.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.o `test -f 'clients/cloud-setup/nmcs-provider-gcp.c' || echo '$(srcdir)/'`clients/cloud-setup/nmcs-provider-gcp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-button-box.obj `if test -f 'src/libnmt-newt/nmt-newt-button-box.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-button-box.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-button-box.c'; fi` -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.obj: clients/cloud-setup/nmcs-provider-gcp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.obj -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.obj `if test -f 'clients/cloud-setup/nmcs-provider-gcp.c'; then $(CYGPATH_W) 'clients/cloud-setup/nmcs-provider-gcp.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nmcs-provider-gcp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nmcs-provider-gcp.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-button.o: src/libnmt-newt/nmt-newt-button.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-button.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-button.o `test -f 'src/libnmt-newt/nmt-newt-button.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-button.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-button.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-button.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.obj `if test -f 'clients/cloud-setup/nmcs-provider-gcp.c'; then $(CYGPATH_W) 'clients/cloud-setup/nmcs-provider-gcp.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nmcs-provider-gcp.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-button.o `test -f 'src/libnmt-newt/nmt-newt-button.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-button.c -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.o: clients/cloud-setup/nmcs-provider-azure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.o -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.o `test -f 'clients/cloud-setup/nmcs-provider-azure.c' || echo '$(srcdir)/'`clients/cloud-setup/nmcs-provider-azure.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nmcs-provider-azure.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-button.obj: src/libnmt-newt/nmt-newt-button.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-button.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-button.obj `if test -f 'src/libnmt-newt/nmt-newt-button.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-button.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-button.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-button.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-button.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.o `test -f 'clients/cloud-setup/nmcs-provider-azure.c' || echo '$(srcdir)/'`clients/cloud-setup/nmcs-provider-azure.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-button.obj `if test -f 'src/libnmt-newt/nmt-newt-button.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-button.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-button.c'; fi` -clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.obj: clients/cloud-setup/nmcs-provider-azure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.obj -MD -MP -MF clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Tpo -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.obj `if test -f 'clients/cloud-setup/nmcs-provider-azure.c'; then $(CYGPATH_W) 'clients/cloud-setup/nmcs-provider-azure.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nmcs-provider-azure.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Tpo clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/nmcs-provider-azure.c' object='clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.o: src/libnmt-newt/nmt-newt-checkbox.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.o `test -f 'src/libnmt-newt/nmt-newt-checkbox.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-checkbox.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-checkbox.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.obj `if test -f 'clients/cloud-setup/nmcs-provider-azure.c'; then $(CYGPATH_W) 'clients/cloud-setup/nmcs-provider-azure.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/nmcs-provider-azure.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.o `test -f 'src/libnmt-newt/nmt-newt-checkbox.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-checkbox.c -clients/tui/newt/libnmt_newt_a-nmt-newt-button.o: clients/tui/newt/nmt-newt-button.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-button.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-button.o `test -f 'clients/tui/newt/nmt-newt-button.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-button.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-button.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-button.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.obj: src/libnmt-newt/nmt-newt-checkbox.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.obj `if test -f 'src/libnmt-newt/nmt-newt-checkbox.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-checkbox.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-checkbox.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-checkbox.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-button.o `test -f 'clients/tui/newt/nmt-newt-button.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-button.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-checkbox.obj `if test -f 'src/libnmt-newt/nmt-newt-checkbox.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-checkbox.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-checkbox.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-button.obj: clients/tui/newt/nmt-newt-button.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-button.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-button.obj `if test -f 'clients/tui/newt/nmt-newt-button.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-button.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-button.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-button.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-button.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-component.o: src/libnmt-newt/nmt-newt-component.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-component.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-component.o `test -f 'src/libnmt-newt/nmt-newt-component.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-component.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-component.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-component.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-button.obj `if test -f 'clients/tui/newt/nmt-newt-button.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-button.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-button.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-component.o `test -f 'src/libnmt-newt/nmt-newt-component.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-component.c -clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.o: clients/tui/newt/nmt-newt-button-box.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.o `test -f 'clients/tui/newt/nmt-newt-button-box.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-button-box.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-button-box.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-component.obj: src/libnmt-newt/nmt-newt-component.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-component.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-component.obj `if test -f 'src/libnmt-newt/nmt-newt-component.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-component.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-component.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-component.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-component.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.o `test -f 'clients/tui/newt/nmt-newt-button-box.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-button-box.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-component.obj `if test -f 'src/libnmt-newt/nmt-newt-component.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-component.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-component.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.obj: clients/tui/newt/nmt-newt-button-box.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.obj `if test -f 'clients/tui/newt/nmt-newt-button-box.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-button-box.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-button-box.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-button-box.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-container.o: src/libnmt-newt/nmt-newt-container.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-container.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-container.o `test -f 'src/libnmt-newt/nmt-newt-container.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-container.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-container.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-container.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-button-box.obj `if test -f 'clients/tui/newt/nmt-newt-button-box.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-button-box.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-button-box.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-container.o `test -f 'src/libnmt-newt/nmt-newt-container.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-container.c -clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.o: clients/tui/newt/nmt-newt-checkbox.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.o `test -f 'clients/tui/newt/nmt-newt-checkbox.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-checkbox.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-checkbox.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-container.obj: src/libnmt-newt/nmt-newt-container.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-container.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-container.obj `if test -f 'src/libnmt-newt/nmt-newt-container.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-container.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-container.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-container.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-container.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.o `test -f 'clients/tui/newt/nmt-newt-checkbox.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-checkbox.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-container.obj `if test -f 'src/libnmt-newt/nmt-newt-container.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-container.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-container.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.obj: clients/tui/newt/nmt-newt-checkbox.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.obj `if test -f 'clients/tui/newt/nmt-newt-checkbox.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-checkbox.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-checkbox.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-checkbox.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.o: src/libnmt-newt/nmt-newt-entry-numeric.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.o `test -f 'src/libnmt-newt/nmt-newt-entry-numeric.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-entry-numeric.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-entry-numeric.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-checkbox.obj `if test -f 'clients/tui/newt/nmt-newt-checkbox.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-checkbox.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-checkbox.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.o `test -f 'src/libnmt-newt/nmt-newt-entry-numeric.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-entry-numeric.c -clients/tui/newt/libnmt_newt_a-nmt-newt-component.o: clients/tui/newt/nmt-newt-component.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-component.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-component.o `test -f 'clients/tui/newt/nmt-newt-component.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-component.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-component.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-component.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.obj: src/libnmt-newt/nmt-newt-entry-numeric.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.obj `if test -f 'src/libnmt-newt/nmt-newt-entry-numeric.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-entry-numeric.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-entry-numeric.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-entry-numeric.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-component.o `test -f 'clients/tui/newt/nmt-newt-component.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-component.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-entry-numeric.obj `if test -f 'src/libnmt-newt/nmt-newt-entry-numeric.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-entry-numeric.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-entry-numeric.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-component.obj: clients/tui/newt/nmt-newt-component.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-component.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-component.obj `if test -f 'clients/tui/newt/nmt-newt-component.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-component.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-component.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-component.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-component.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.o: src/libnmt-newt/nmt-newt-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.o `test -f 'src/libnmt-newt/nmt-newt-entry.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-entry.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-entry.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-component.obj `if test -f 'clients/tui/newt/nmt-newt-component.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-component.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-component.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.o `test -f 'src/libnmt-newt/nmt-newt-entry.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-entry.c -clients/tui/newt/libnmt_newt_a-nmt-newt-container.o: clients/tui/newt/nmt-newt-container.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-container.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-container.o `test -f 'clients/tui/newt/nmt-newt-container.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-container.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-container.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-container.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.obj: src/libnmt-newt/nmt-newt-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.obj `if test -f 'src/libnmt-newt/nmt-newt-entry.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-entry.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-entry.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-container.o `test -f 'clients/tui/newt/nmt-newt-container.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-container.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-entry.obj `if test -f 'src/libnmt-newt/nmt-newt-entry.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-entry.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-container.obj: clients/tui/newt/nmt-newt-container.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-container.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-container.obj `if test -f 'clients/tui/newt/nmt-newt-container.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-container.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-container.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-container.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-container.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-form.o: src/libnmt-newt/nmt-newt-form.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-form.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-form.o `test -f 'src/libnmt-newt/nmt-newt-form.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-form.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-form.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-form.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-container.obj `if test -f 'clients/tui/newt/nmt-newt-container.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-container.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-container.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-form.o `test -f 'src/libnmt-newt/nmt-newt-form.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-form.c -clients/tui/newt/libnmt_newt_a-nmt-newt-entry.o: clients/tui/newt/nmt-newt-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-entry.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-entry.o `test -f 'clients/tui/newt/nmt-newt-entry.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-entry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-entry.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-entry.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-form.obj: src/libnmt-newt/nmt-newt-form.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-form.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-form.obj `if test -f 'src/libnmt-newt/nmt-newt-form.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-form.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-form.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-form.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-form.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-entry.o `test -f 'clients/tui/newt/nmt-newt-entry.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-entry.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-form.obj `if test -f 'src/libnmt-newt/nmt-newt-form.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-form.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-form.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-entry.obj: clients/tui/newt/nmt-newt-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-entry.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-entry.obj `if test -f 'clients/tui/newt/nmt-newt-entry.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-entry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-entry.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-entry.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.o: src/libnmt-newt/nmt-newt-grid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.o `test -f 'src/libnmt-newt/nmt-newt-grid.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-grid.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-grid.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-entry.obj `if test -f 'clients/tui/newt/nmt-newt-entry.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-entry.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.o `test -f 'src/libnmt-newt/nmt-newt-grid.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-grid.c -clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.o: clients/tui/newt/nmt-newt-entry-numeric.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.o `test -f 'clients/tui/newt/nmt-newt-entry-numeric.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-entry-numeric.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-entry-numeric.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.obj: src/libnmt-newt/nmt-newt-grid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.obj `if test -f 'src/libnmt-newt/nmt-newt-grid.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-grid.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-grid.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-grid.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.o `test -f 'clients/tui/newt/nmt-newt-entry-numeric.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-entry-numeric.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-grid.obj `if test -f 'src/libnmt-newt/nmt-newt-grid.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-grid.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-grid.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.obj: clients/tui/newt/nmt-newt-entry-numeric.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.obj `if test -f 'clients/tui/newt/nmt-newt-entry-numeric.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-entry-numeric.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-entry-numeric.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-entry-numeric.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.o: src/libnmt-newt/nmt-newt-hacks.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.o `test -f 'src/libnmt-newt/nmt-newt-hacks.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-hacks.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-hacks.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-entry-numeric.obj `if test -f 'clients/tui/newt/nmt-newt-entry-numeric.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-entry-numeric.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-entry-numeric.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.o `test -f 'src/libnmt-newt/nmt-newt-hacks.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-hacks.c -clients/tui/newt/libnmt_newt_a-nmt-newt-form.o: clients/tui/newt/nmt-newt-form.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-form.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-form.o `test -f 'clients/tui/newt/nmt-newt-form.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-form.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-form.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-form.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.obj: src/libnmt-newt/nmt-newt-hacks.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.obj `if test -f 'src/libnmt-newt/nmt-newt-hacks.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-hacks.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-hacks.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-hacks.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-form.o `test -f 'clients/tui/newt/nmt-newt-form.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-form.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-hacks.obj `if test -f 'src/libnmt-newt/nmt-newt-hacks.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-hacks.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-hacks.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-form.obj: clients/tui/newt/nmt-newt-form.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-form.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-form.obj `if test -f 'clients/tui/newt/nmt-newt-form.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-form.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-form.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-form.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-form.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-label.o: src/libnmt-newt/nmt-newt-label.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-label.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-label.o `test -f 'src/libnmt-newt/nmt-newt-label.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-label.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-label.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-label.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-form.obj `if test -f 'clients/tui/newt/nmt-newt-form.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-form.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-form.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-label.o `test -f 'src/libnmt-newt/nmt-newt-label.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-label.c -clients/tui/newt/libnmt_newt_a-nmt-newt-grid.o: clients/tui/newt/nmt-newt-grid.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-grid.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-grid.o `test -f 'clients/tui/newt/nmt-newt-grid.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-grid.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-grid.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-grid.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-label.obj: src/libnmt-newt/nmt-newt-label.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-label.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-label.obj `if test -f 'src/libnmt-newt/nmt-newt-label.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-label.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-label.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-label.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-label.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-grid.o `test -f 'clients/tui/newt/nmt-newt-grid.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-grid.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-label.obj `if test -f 'src/libnmt-newt/nmt-newt-label.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-label.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-label.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-grid.obj: clients/tui/newt/nmt-newt-grid.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-grid.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-grid.obj `if test -f 'clients/tui/newt/nmt-newt-grid.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-grid.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-grid.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-grid.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-grid.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.o: src/libnmt-newt/nmt-newt-listbox.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.o `test -f 'src/libnmt-newt/nmt-newt-listbox.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-listbox.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-listbox.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-grid.obj `if test -f 'clients/tui/newt/nmt-newt-grid.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-grid.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-grid.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.o `test -f 'src/libnmt-newt/nmt-newt-listbox.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-listbox.c -clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.o: clients/tui/newt/nmt-newt-hacks.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.o `test -f 'clients/tui/newt/nmt-newt-hacks.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-hacks.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-hacks.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.obj: src/libnmt-newt/nmt-newt-listbox.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.obj `if test -f 'src/libnmt-newt/nmt-newt-listbox.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-listbox.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-listbox.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-listbox.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.o `test -f 'clients/tui/newt/nmt-newt-hacks.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-hacks.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-listbox.obj `if test -f 'src/libnmt-newt/nmt-newt-listbox.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-listbox.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-listbox.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.obj: clients/tui/newt/nmt-newt-hacks.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.obj `if test -f 'clients/tui/newt/nmt-newt-hacks.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-hacks.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-hacks.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-hacks.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.o: src/libnmt-newt/nmt-newt-popup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.o `test -f 'src/libnmt-newt/nmt-newt-popup.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-popup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-popup.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-hacks.obj `if test -f 'clients/tui/newt/nmt-newt-hacks.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-hacks.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-hacks.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.o `test -f 'src/libnmt-newt/nmt-newt-popup.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-popup.c -clients/tui/newt/libnmt_newt_a-nmt-newt-label.o: clients/tui/newt/nmt-newt-label.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-label.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-label.o `test -f 'clients/tui/newt/nmt-newt-label.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-label.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-label.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-label.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.obj: src/libnmt-newt/nmt-newt-popup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.obj `if test -f 'src/libnmt-newt/nmt-newt-popup.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-popup.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-popup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-popup.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-label.o `test -f 'clients/tui/newt/nmt-newt-label.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-label.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-popup.obj `if test -f 'src/libnmt-newt/nmt-newt-popup.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-popup.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-popup.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-label.obj: clients/tui/newt/nmt-newt-label.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-label.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-label.obj `if test -f 'clients/tui/newt/nmt-newt-label.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-label.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-label.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-label.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-label.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-section.o: src/libnmt-newt/nmt-newt-section.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-section.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-section.o `test -f 'src/libnmt-newt/nmt-newt-section.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-section.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-section.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-section.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-label.obj `if test -f 'clients/tui/newt/nmt-newt-label.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-label.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-label.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-section.o `test -f 'src/libnmt-newt/nmt-newt-section.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-section.c -clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.o: clients/tui/newt/nmt-newt-listbox.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.o `test -f 'clients/tui/newt/nmt-newt-listbox.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-listbox.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-listbox.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-section.obj: src/libnmt-newt/nmt-newt-section.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-section.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-section.obj `if test -f 'src/libnmt-newt/nmt-newt-section.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-section.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-section.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-section.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-section.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.o `test -f 'clients/tui/newt/nmt-newt-listbox.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-listbox.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-section.obj `if test -f 'src/libnmt-newt/nmt-newt-section.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-section.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-section.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.obj: clients/tui/newt/nmt-newt-listbox.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.obj `if test -f 'clients/tui/newt/nmt-newt-listbox.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-listbox.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-listbox.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-listbox.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.o: src/libnmt-newt/nmt-newt-separator.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.o `test -f 'src/libnmt-newt/nmt-newt-separator.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-separator.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-separator.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-listbox.obj `if test -f 'clients/tui/newt/nmt-newt-listbox.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-listbox.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-listbox.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.o `test -f 'src/libnmt-newt/nmt-newt-separator.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-separator.c -clients/tui/newt/libnmt_newt_a-nmt-newt-popup.o: clients/tui/newt/nmt-newt-popup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-popup.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-popup.o `test -f 'clients/tui/newt/nmt-newt-popup.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-popup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-popup.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-popup.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.obj: src/libnmt-newt/nmt-newt-separator.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.obj `if test -f 'src/libnmt-newt/nmt-newt-separator.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-separator.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-separator.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-separator.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-popup.o `test -f 'clients/tui/newt/nmt-newt-popup.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-popup.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-separator.obj `if test -f 'src/libnmt-newt/nmt-newt-separator.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-separator.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-separator.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-popup.obj: clients/tui/newt/nmt-newt-popup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-popup.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-popup.obj `if test -f 'clients/tui/newt/nmt-newt-popup.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-popup.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-popup.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-popup.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-popup.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.o: src/libnmt-newt/nmt-newt-stack.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.o `test -f 'src/libnmt-newt/nmt-newt-stack.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-stack.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-stack.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-popup.obj `if test -f 'clients/tui/newt/nmt-newt-popup.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-popup.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-popup.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.o `test -f 'src/libnmt-newt/nmt-newt-stack.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-stack.c -clients/tui/newt/libnmt_newt_a-nmt-newt-section.o: clients/tui/newt/nmt-newt-section.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-section.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-section.o `test -f 'clients/tui/newt/nmt-newt-section.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-section.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-section.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-section.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.obj: src/libnmt-newt/nmt-newt-stack.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.obj `if test -f 'src/libnmt-newt/nmt-newt-stack.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-stack.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-stack.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-stack.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-section.o `test -f 'clients/tui/newt/nmt-newt-section.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-section.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-stack.obj `if test -f 'src/libnmt-newt/nmt-newt-stack.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-stack.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-stack.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-section.obj: clients/tui/newt/nmt-newt-section.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-section.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-section.obj `if test -f 'clients/tui/newt/nmt-newt-section.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-section.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-section.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-section.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-section.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.o: src/libnmt-newt/nmt-newt-textbox.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.o `test -f 'src/libnmt-newt/nmt-newt-textbox.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-textbox.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-textbox.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-section.obj `if test -f 'clients/tui/newt/nmt-newt-section.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-section.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-section.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.o `test -f 'src/libnmt-newt/nmt-newt-textbox.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-textbox.c -clients/tui/newt/libnmt_newt_a-nmt-newt-separator.o: clients/tui/newt/nmt-newt-separator.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-separator.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-separator.o `test -f 'clients/tui/newt/nmt-newt-separator.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-separator.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-separator.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-separator.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.obj: src/libnmt-newt/nmt-newt-textbox.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.obj `if test -f 'src/libnmt-newt/nmt-newt-textbox.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-textbox.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-textbox.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-textbox.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-separator.o `test -f 'clients/tui/newt/nmt-newt-separator.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-separator.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-textbox.obj `if test -f 'src/libnmt-newt/nmt-newt-textbox.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-textbox.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-textbox.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-separator.obj: clients/tui/newt/nmt-newt-separator.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-separator.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-separator.obj `if test -f 'clients/tui/newt/nmt-newt-separator.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-separator.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-separator.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-separator.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-separator.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.o: src/libnmt-newt/nmt-newt-toggle-button.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.o `test -f 'src/libnmt-newt/nmt-newt-toggle-button.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-toggle-button.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-toggle-button.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-separator.obj `if test -f 'clients/tui/newt/nmt-newt-separator.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-separator.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-separator.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.o `test -f 'src/libnmt-newt/nmt-newt-toggle-button.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-toggle-button.c -clients/tui/newt/libnmt_newt_a-nmt-newt-stack.o: clients/tui/newt/nmt-newt-stack.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-stack.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-stack.o `test -f 'clients/tui/newt/nmt-newt-stack.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-stack.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-stack.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-stack.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.obj: src/libnmt-newt/nmt-newt-toggle-button.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.obj `if test -f 'src/libnmt-newt/nmt-newt-toggle-button.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-toggle-button.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-toggle-button.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-toggle-button.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-stack.o `test -f 'clients/tui/newt/nmt-newt-stack.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-stack.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-toggle-button.obj `if test -f 'src/libnmt-newt/nmt-newt-toggle-button.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-toggle-button.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-toggle-button.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-stack.obj: clients/tui/newt/nmt-newt-stack.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-stack.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-stack.obj `if test -f 'clients/tui/newt/nmt-newt-stack.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-stack.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-stack.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-stack.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-stack.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.o: src/libnmt-newt/nmt-newt-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.o `test -f 'src/libnmt-newt/nmt-newt-utils.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-utils.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-stack.obj `if test -f 'clients/tui/newt/nmt-newt-stack.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-stack.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-stack.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.o `test -f 'src/libnmt-newt/nmt-newt-utils.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-utils.c -clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.o: clients/tui/newt/nmt-newt-textbox.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.o `test -f 'clients/tui/newt/nmt-newt-textbox.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-textbox.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-textbox.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.obj: src/libnmt-newt/nmt-newt-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.obj `if test -f 'src/libnmt-newt/nmt-newt-utils.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-utils.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.o `test -f 'clients/tui/newt/nmt-newt-textbox.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-textbox.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-utils.obj `if test -f 'src/libnmt-newt/nmt-newt-utils.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-utils.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.obj: clients/tui/newt/nmt-newt-textbox.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.obj `if test -f 'clients/tui/newt/nmt-newt-textbox.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-textbox.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-textbox.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-textbox.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.o: src/libnmt-newt/nmt-newt-widget.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.o -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.o `test -f 'src/libnmt-newt/nmt-newt-widget.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-widget.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-widget.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-textbox.obj `if test -f 'clients/tui/newt/nmt-newt-textbox.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-textbox.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-textbox.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.o `test -f 'src/libnmt-newt/nmt-newt-widget.c' || echo '$(srcdir)/'`src/libnmt-newt/nmt-newt-widget.c -clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.o: clients/tui/newt/nmt-newt-toggle-button.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.o `test -f 'clients/tui/newt/nmt-newt-toggle-button.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-toggle-button.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-toggle-button.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.o' libtool=no @AMDEPBACKSLASH@ +src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.obj: src/libnmt-newt/nmt-newt-widget.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.obj -MD -MP -MF src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Tpo -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.obj `if test -f 'src/libnmt-newt/nmt-newt-widget.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-widget.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-widget.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Tpo src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmt-newt/nmt-newt-widget.c' object='src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.o `test -f 'clients/tui/newt/nmt-newt-toggle-button.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-toggle-button.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmt_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmt-newt/libnmt_newt_a-nmt-newt-widget.obj `if test -f 'src/libnmt-newt/nmt-newt-widget.c'; then $(CYGPATH_W) 'src/libnmt-newt/nmt-newt-widget.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmt-newt/nmt-newt-widget.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.obj: clients/tui/newt/nmt-newt-toggle-button.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.obj `if test -f 'clients/tui/newt/nmt-newt-toggle-button.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-toggle-button.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-toggle-button.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-toggle-button.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.o: src/nm-cloud-setup/nm-cloud-setup-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.o -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.o `test -f 'src/nm-cloud-setup/nm-cloud-setup-utils.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nm-cloud-setup-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nm-cloud-setup-utils.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-toggle-button.obj `if test -f 'clients/tui/newt/nmt-newt-toggle-button.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-toggle-button.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-toggle-button.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.o `test -f 'src/nm-cloud-setup/nm-cloud-setup-utils.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nm-cloud-setup-utils.c -clients/tui/newt/libnmt_newt_a-nmt-newt-utils.o: clients/tui/newt/nmt-newt-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-utils.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-utils.o `test -f 'clients/tui/newt/nmt-newt-utils.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-utils.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-utils.o' libtool=no @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.obj: src/nm-cloud-setup/nm-cloud-setup-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.obj -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.obj `if test -f 'src/nm-cloud-setup/nm-cloud-setup-utils.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nm-cloud-setup-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nm-cloud-setup-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nm-cloud-setup-utils.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-utils.o `test -f 'clients/tui/newt/nmt-newt-utils.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-cloud-setup-utils.obj `if test -f 'src/nm-cloud-setup/nm-cloud-setup-utils.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nm-cloud-setup-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nm-cloud-setup-utils.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-utils.obj: clients/tui/newt/nmt-newt-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-utils.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-utils.obj `if test -f 'clients/tui/newt/nmt-newt-utils.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-utils.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-utils.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-utils.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.o: src/nm-cloud-setup/nm-http-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.o -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.o `test -f 'src/nm-cloud-setup/nm-http-client.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nm-http-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nm-http-client.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-utils.obj `if test -f 'clients/tui/newt/nmt-newt-utils.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-utils.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-utils.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.o `test -f 'src/nm-cloud-setup/nm-http-client.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nm-http-client.c -clients/tui/newt/libnmt_newt_a-nmt-newt-widget.o: clients/tui/newt/nmt-newt-widget.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-widget.o -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-widget.o `test -f 'clients/tui/newt/nmt-newt-widget.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-widget.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-widget.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-widget.o' libtool=no @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.obj: src/nm-cloud-setup/nm-http-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.obj -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.obj `if test -f 'src/nm-cloud-setup/nm-http-client.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nm-http-client.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nm-http-client.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nm-http-client.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-widget.o `test -f 'clients/tui/newt/nmt-newt-widget.c' || echo '$(srcdir)/'`clients/tui/newt/nmt-newt-widget.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nm-http-client.obj `if test -f 'src/nm-cloud-setup/nm-http-client.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nm-http-client.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nm-http-client.c'; fi` -clients/tui/newt/libnmt_newt_a-nmt-newt-widget.obj: clients/tui/newt/nmt-newt-widget.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/newt/libnmt_newt_a-nmt-newt-widget.obj -MD -MP -MF clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Tpo -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-widget.obj `if test -f 'clients/tui/newt/nmt-newt-widget.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-widget.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-widget.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Tpo clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/newt/nmt-newt-widget.c' object='clients/tui/newt/libnmt_newt_a-nmt-newt-widget.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.o: src/nm-cloud-setup/nmcs-provider.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.o -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.o `test -f 'src/nm-cloud-setup/nmcs-provider.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nmcs-provider.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nmcs-provider.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_newt_libnmt_newt_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/newt/libnmt_newt_a-nmt-newt-widget.obj `if test -f 'clients/tui/newt/nmt-newt-widget.c'; then $(CYGPATH_W) 'clients/tui/newt/nmt-newt-widget.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/newt/nmt-newt-widget.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.o `test -f 'src/nm-cloud-setup/nmcs-provider.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nmcs-provider.c -clients/common/libnmc_base_la-nm-secret-agent-simple.lo: clients/common/nm-secret-agent-simple.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/libnmc_base_la-nm-secret-agent-simple.lo -MD -MP -MF clients/common/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Tpo -c -o clients/common/libnmc_base_la-nm-secret-agent-simple.lo `test -f 'clients/common/nm-secret-agent-simple.c' || echo '$(srcdir)/'`clients/common/nm-secret-agent-simple.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Tpo clients/common/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/nm-secret-agent-simple.c' object='clients/common/libnmc_base_la-nm-secret-agent-simple.lo' libtool=yes @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.obj: src/nm-cloud-setup/nmcs-provider.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.obj -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.obj `if test -f 'src/nm-cloud-setup/nmcs-provider.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nmcs-provider.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nmcs-provider.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nmcs-provider.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/libnmc_base_la-nm-secret-agent-simple.lo `test -f 'clients/common/nm-secret-agent-simple.c' || echo '$(srcdir)/'`clients/common/nm-secret-agent-simple.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider.obj `if test -f 'src/nm-cloud-setup/nmcs-provider.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nmcs-provider.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nmcs-provider.c'; fi` -clients/common/libnmc_base_la-nm-vpn-helpers.lo: clients/common/nm-vpn-helpers.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/libnmc_base_la-nm-vpn-helpers.lo -MD -MP -MF clients/common/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Tpo -c -o clients/common/libnmc_base_la-nm-vpn-helpers.lo `test -f 'clients/common/nm-vpn-helpers.c' || echo '$(srcdir)/'`clients/common/nm-vpn-helpers.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Tpo clients/common/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/nm-vpn-helpers.c' object='clients/common/libnmc_base_la-nm-vpn-helpers.lo' libtool=yes @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.o: src/nm-cloud-setup/nmcs-provider-ec2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.o -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.o `test -f 'src/nm-cloud-setup/nmcs-provider-ec2.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nmcs-provider-ec2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nmcs-provider-ec2.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/libnmc_base_la-nm-vpn-helpers.lo `test -f 'clients/common/nm-vpn-helpers.c' || echo '$(srcdir)/'`clients/common/nm-vpn-helpers.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.o `test -f 'src/nm-cloud-setup/nmcs-provider-ec2.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nmcs-provider-ec2.c -clients/common/libnmc_base_la-nm-client-utils.lo: clients/common/nm-client-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/libnmc_base_la-nm-client-utils.lo -MD -MP -MF clients/common/$(DEPDIR)/libnmc_base_la-nm-client-utils.Tpo -c -o clients/common/libnmc_base_la-nm-client-utils.lo `test -f 'clients/common/nm-client-utils.c' || echo '$(srcdir)/'`clients/common/nm-client-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/$(DEPDIR)/libnmc_base_la-nm-client-utils.Tpo clients/common/$(DEPDIR)/libnmc_base_la-nm-client-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/nm-client-utils.c' object='clients/common/libnmc_base_la-nm-client-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.obj: src/nm-cloud-setup/nmcs-provider-ec2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.obj -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.obj `if test -f 'src/nm-cloud-setup/nmcs-provider-ec2.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nmcs-provider-ec2.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nmcs-provider-ec2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nmcs-provider-ec2.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/libnmc_base_la-nm-client-utils.lo `test -f 'clients/common/nm-client-utils.c' || echo '$(srcdir)/'`clients/common/nm-client-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-ec2.obj `if test -f 'src/nm-cloud-setup/nmcs-provider-ec2.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nmcs-provider-ec2.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nmcs-provider-ec2.c'; fi` -clients/common/libnmc_base_la-nm-polkit-listener.lo: clients/common/nm-polkit-listener.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/libnmc_base_la-nm-polkit-listener.lo -MD -MP -MF clients/common/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Tpo -c -o clients/common/libnmc_base_la-nm-polkit-listener.lo `test -f 'clients/common/nm-polkit-listener.c' || echo '$(srcdir)/'`clients/common/nm-polkit-listener.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Tpo clients/common/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/nm-polkit-listener.c' object='clients/common/libnmc_base_la-nm-polkit-listener.lo' libtool=yes @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.o: src/nm-cloud-setup/nmcs-provider-gcp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.o -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.o `test -f 'src/nm-cloud-setup/nmcs-provider-gcp.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nmcs-provider-gcp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nmcs-provider-gcp.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/libnmc_base_la-nm-polkit-listener.lo `test -f 'clients/common/nm-polkit-listener.c' || echo '$(srcdir)/'`clients/common/nm-polkit-listener.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.o `test -f 'src/nm-cloud-setup/nmcs-provider-gcp.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nmcs-provider-gcp.c -clients/common/libnmc_la-nm-meta-setting-base-impl.lo: clients/common/nm-meta-setting-base-impl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/libnmc_la-nm-meta-setting-base-impl.lo -MD -MP -MF clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-base-impl.Tpo -c -o clients/common/libnmc_la-nm-meta-setting-base-impl.lo `test -f 'clients/common/nm-meta-setting-base-impl.c' || echo '$(srcdir)/'`clients/common/nm-meta-setting-base-impl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-base-impl.Tpo clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-base-impl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/nm-meta-setting-base-impl.c' object='clients/common/libnmc_la-nm-meta-setting-base-impl.lo' libtool=yes @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.obj: src/nm-cloud-setup/nmcs-provider-gcp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.obj -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.obj `if test -f 'src/nm-cloud-setup/nmcs-provider-gcp.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nmcs-provider-gcp.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nmcs-provider-gcp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nmcs-provider-gcp.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/libnmc_la-nm-meta-setting-base-impl.lo `test -f 'clients/common/nm-meta-setting-base-impl.c' || echo '$(srcdir)/'`clients/common/nm-meta-setting-base-impl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-gcp.obj `if test -f 'src/nm-cloud-setup/nmcs-provider-gcp.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nmcs-provider-gcp.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nmcs-provider-gcp.c'; fi` -clients/common/libnmc_la-nm-meta-setting-desc.lo: clients/common/nm-meta-setting-desc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/libnmc_la-nm-meta-setting-desc.lo -MD -MP -MF clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-desc.Tpo -c -o clients/common/libnmc_la-nm-meta-setting-desc.lo `test -f 'clients/common/nm-meta-setting-desc.c' || echo '$(srcdir)/'`clients/common/nm-meta-setting-desc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-desc.Tpo clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-desc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/nm-meta-setting-desc.c' object='clients/common/libnmc_la-nm-meta-setting-desc.lo' libtool=yes @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.o: src/nm-cloud-setup/nmcs-provider-azure.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.o -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.o `test -f 'src/nm-cloud-setup/nmcs-provider-azure.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nmcs-provider-azure.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nmcs-provider-azure.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/libnmc_la-nm-meta-setting-desc.lo `test -f 'clients/common/nm-meta-setting-desc.c' || echo '$(srcdir)/'`clients/common/nm-meta-setting-desc.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.o `test -f 'src/nm-cloud-setup/nmcs-provider-azure.c' || echo '$(srcdir)/'`src/nm-cloud-setup/nmcs-provider-azure.c -clients/common/libnmc_la-nm-meta-setting-access.lo: clients/common/nm-meta-setting-access.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/libnmc_la-nm-meta-setting-access.lo -MD -MP -MF clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-access.Tpo -c -o clients/common/libnmc_la-nm-meta-setting-access.lo `test -f 'clients/common/nm-meta-setting-access.c' || echo '$(srcdir)/'`clients/common/nm-meta-setting-access.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-access.Tpo clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-access.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/nm-meta-setting-access.c' object='clients/common/libnmc_la-nm-meta-setting-access.lo' libtool=yes @AMDEPBACKSLASH@ +src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.obj: src/nm-cloud-setup/nmcs-provider-azure.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.obj -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Tpo -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.obj `if test -f 'src/nm-cloud-setup/nmcs-provider-azure.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nmcs-provider-azure.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nmcs-provider-azure.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Tpo src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/nmcs-provider-azure.c' object='src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_libnmc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/libnmc_la-nm-meta-setting-access.lo `test -f 'clients/common/nm-meta-setting-access.c' || echo '$(srcdir)/'`clients/common/nm-meta-setting-access.c - -dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo: dispatcher/nm-dispatcher-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_libnm_dispatcher_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo -MD -MP -MF dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Tpo -c -o dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo `test -f 'dispatcher/nm-dispatcher-utils.c' || echo '$(srcdir)/'`dispatcher/nm-dispatcher-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Tpo dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dispatcher/nm-dispatcher-utils.c' object='dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_libnm_dispatcher_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo `test -f 'dispatcher/nm-dispatcher-utils.c' || echo '$(srcdir)/'`dispatcher/nm-dispatcher-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_libnm_cloud_setup_core_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/libnm_cloud_setup_core_a-nmcs-provider-azure.obj `if test -f 'src/nm-cloud-setup/nmcs-provider-azure.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/nmcs-provider-azure.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/nmcs-provider-azure.c'; fi` introspection/libnmdbus_la-org.freedesktop.NetworkManager.AccessPoint.lo: introspection/org.freedesktop.NetworkManager.AccessPoint.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(introspection_libnmdbus_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT introspection/libnmdbus_la-org.freedesktop.NetworkManager.AccessPoint.lo -MD -MP -MF introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.AccessPoint.Tpo -c -o introspection/libnmdbus_la-org.freedesktop.NetworkManager.AccessPoint.lo `test -f 'introspection/org.freedesktop.NetworkManager.AccessPoint.c' || echo '$(srcdir)/'`introspection/org.freedesktop.NetworkManager.AccessPoint.c @@ -12889,4534 +13031,4576 @@ introspection/libnmdbus_la-org.freedesktop.NetworkManager.lo: introspection/org. @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(introspection_libnmdbus_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o introspection/libnmdbus_la-org.freedesktop.NetworkManager.lo `test -f 'introspection/org.freedesktop.NetworkManager.c' || echo '$(srcdir)/'`introspection/org.freedesktop.NetworkManager.c -libnm-core/libnm_core_la-nm-setting-6lowpan.lo: libnm-core/nm-setting-6lowpan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-6lowpan.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-6lowpan.Tpo -c -o libnm-core/libnm_core_la-nm-setting-6lowpan.lo `test -f 'libnm-core/nm-setting-6lowpan.c' || echo '$(srcdir)/'`libnm-core/nm-setting-6lowpan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-6lowpan.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-6lowpan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-6lowpan.c' object='libnm-core/libnm_core_la-nm-setting-6lowpan.lo' libtool=yes @AMDEPBACKSLASH@ +src/c-rbtree/src/libc_rbtree_la-c-rbtree.lo: src/c-rbtree/src/c-rbtree.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_c_rbtree_libc_rbtree_la_CPPFLAGS) $(CPPFLAGS) $(src_c_rbtree_libc_rbtree_la_CFLAGS) $(CFLAGS) -MT src/c-rbtree/src/libc_rbtree_la-c-rbtree.lo -MD -MP -MF src/c-rbtree/src/$(DEPDIR)/libc_rbtree_la-c-rbtree.Tpo -c -o src/c-rbtree/src/libc_rbtree_la-c-rbtree.lo `test -f 'src/c-rbtree/src/c-rbtree.c' || echo '$(srcdir)/'`src/c-rbtree/src/c-rbtree.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/c-rbtree/src/$(DEPDIR)/libc_rbtree_la-c-rbtree.Tpo src/c-rbtree/src/$(DEPDIR)/libc_rbtree_la-c-rbtree.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/c-rbtree/src/c-rbtree.c' object='src/c-rbtree/src/libc_rbtree_la-c-rbtree.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-6lowpan.lo `test -f 'libnm-core/nm-setting-6lowpan.c' || echo '$(srcdir)/'`libnm-core/nm-setting-6lowpan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_c_rbtree_libc_rbtree_la_CPPFLAGS) $(CPPFLAGS) $(src_c_rbtree_libc_rbtree_la_CFLAGS) $(CFLAGS) -c -o src/c-rbtree/src/libc_rbtree_la-c-rbtree.lo `test -f 'src/c-rbtree/src/c-rbtree.c' || echo '$(srcdir)/'`src/c-rbtree/src/c-rbtree.c -libnm-core/libnm_core_la-nm-setting-8021x.lo: libnm-core/nm-setting-8021x.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-8021x.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-8021x.Tpo -c -o libnm-core/libnm_core_la-nm-setting-8021x.lo `test -f 'libnm-core/nm-setting-8021x.c' || echo '$(srcdir)/'`libnm-core/nm-setting-8021x.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-8021x.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-8021x.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-8021x.c' object='libnm-core/libnm_core_la-nm-setting-8021x.lo' libtool=yes @AMDEPBACKSLASH@ +src/c-siphash/src/libc_siphash_la-c-siphash.lo: src/c-siphash/src/c-siphash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_c_siphash_libc_siphash_la_CPPFLAGS) $(CPPFLAGS) $(src_c_siphash_libc_siphash_la_CFLAGS) $(CFLAGS) -MT src/c-siphash/src/libc_siphash_la-c-siphash.lo -MD -MP -MF src/c-siphash/src/$(DEPDIR)/libc_siphash_la-c-siphash.Tpo -c -o src/c-siphash/src/libc_siphash_la-c-siphash.lo `test -f 'src/c-siphash/src/c-siphash.c' || echo '$(srcdir)/'`src/c-siphash/src/c-siphash.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/c-siphash/src/$(DEPDIR)/libc_siphash_la-c-siphash.Tpo src/c-siphash/src/$(DEPDIR)/libc_siphash_la-c-siphash.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/c-siphash/src/c-siphash.c' object='src/c-siphash/src/libc_siphash_la-c-siphash.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-8021x.lo `test -f 'libnm-core/nm-setting-8021x.c' || echo '$(srcdir)/'`libnm-core/nm-setting-8021x.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_c_siphash_libc_siphash_la_CPPFLAGS) $(CPPFLAGS) $(src_c_siphash_libc_siphash_la_CFLAGS) $(CFLAGS) -c -o src/c-siphash/src/libc_siphash_la-c-siphash.lo `test -f 'src/c-siphash/src/c-siphash.c' || echo '$(srcdir)/'`src/c-siphash/src/c-siphash.c -libnm-core/libnm_core_la-nm-setting-adsl.lo: libnm-core/nm-setting-adsl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-adsl.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-adsl.Tpo -c -o libnm-core/libnm_core_la-nm-setting-adsl.lo `test -f 'libnm-core/nm-setting-adsl.c' || echo '$(srcdir)/'`libnm-core/nm-setting-adsl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-adsl.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-adsl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-adsl.c' object='libnm-core/libnm_core_la-nm-setting-adsl.lo' libtool=yes @AMDEPBACKSLASH@ +src/contrib/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo: src/contrib/nm-vpn-plugin-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_contrib_tests_libnm_vpn_plugin_utils_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/contrib/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo -MD -MP -MF src/contrib/$(DEPDIR)/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Tpo -c -o src/contrib/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo `test -f 'src/contrib/nm-vpn-plugin-utils.c' || echo '$(srcdir)/'`src/contrib/nm-vpn-plugin-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/contrib/$(DEPDIR)/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Tpo src/contrib/$(DEPDIR)/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/contrib/nm-vpn-plugin-utils.c' object='src/contrib/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-adsl.lo `test -f 'libnm-core/nm-setting-adsl.c' || echo '$(srcdir)/'`libnm-core/nm-setting-adsl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_contrib_tests_libnm_vpn_plugin_utils_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/contrib/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo `test -f 'src/contrib/nm-vpn-plugin-utils.c' || echo '$(srcdir)/'`src/contrib/nm-vpn-plugin-utils.c -libnm-core/libnm_core_la-nm-setting-bluetooth.lo: libnm-core/nm-setting-bluetooth.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-bluetooth.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bluetooth.Tpo -c -o libnm-core/libnm_core_la-nm-setting-bluetooth.lo `test -f 'libnm-core/nm-setting-bluetooth.c' || echo '$(srcdir)/'`libnm-core/nm-setting-bluetooth.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bluetooth.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bluetooth.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-bluetooth.c' object='libnm-core/libnm_core_la-nm-setting-bluetooth.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo: src/core/devices/adsl/nm-atm-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_adsl_libnm_device_plugin_adsl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo -MD -MP -MF src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-atm-manager.Tpo -c -o src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo `test -f 'src/core/devices/adsl/nm-atm-manager.c' || echo '$(srcdir)/'`src/core/devices/adsl/nm-atm-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-atm-manager.Tpo src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-atm-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/adsl/nm-atm-manager.c' object='src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-bluetooth.lo `test -f 'libnm-core/nm-setting-bluetooth.c' || echo '$(srcdir)/'`libnm-core/nm-setting-bluetooth.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_adsl_libnm_device_plugin_adsl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo `test -f 'src/core/devices/adsl/nm-atm-manager.c' || echo '$(srcdir)/'`src/core/devices/adsl/nm-atm-manager.c -libnm-core/libnm_core_la-nm-setting-bond.lo: libnm-core/nm-setting-bond.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-bond.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bond.Tpo -c -o libnm-core/libnm_core_la-nm-setting-bond.lo `test -f 'libnm-core/nm-setting-bond.c' || echo '$(srcdir)/'`libnm-core/nm-setting-bond.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bond.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bond.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-bond.c' object='libnm-core/libnm_core_la-nm-setting-bond.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-device-adsl.lo: src/core/devices/adsl/nm-device-adsl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_adsl_libnm_device_plugin_adsl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-device-adsl.lo -MD -MP -MF src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-device-adsl.Tpo -c -o src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-device-adsl.lo `test -f 'src/core/devices/adsl/nm-device-adsl.c' || echo '$(srcdir)/'`src/core/devices/adsl/nm-device-adsl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-device-adsl.Tpo src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-device-adsl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/adsl/nm-device-adsl.c' object='src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-device-adsl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-bond.lo `test -f 'libnm-core/nm-setting-bond.c' || echo '$(srcdir)/'`libnm-core/nm-setting-bond.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_adsl_libnm_device_plugin_adsl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-device-adsl.lo `test -f 'src/core/devices/adsl/nm-device-adsl.c' || echo '$(srcdir)/'`src/core/devices/adsl/nm-device-adsl.c -libnm-core/libnm_core_la-nm-setting-bridge-port.lo: libnm-core/nm-setting-bridge-port.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-bridge-port.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge-port.Tpo -c -o libnm-core/libnm_core_la-nm-setting-bridge-port.lo `test -f 'libnm-core/nm-setting-bridge-port.c' || echo '$(srcdir)/'`libnm-core/nm-setting-bridge-port.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge-port.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge-port.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-bridge-port.c' object='libnm-core/libnm_core_la-nm-setting-bridge-port.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo: src/core/devices/bluetooth/nm-bt-error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo -MD -MP -MF src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bt-error.Tpo -c -o src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo `test -f 'src/core/devices/bluetooth/nm-bt-error.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bt-error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bt-error.Tpo src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bt-error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/nm-bt-error.c' object='src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-bridge-port.lo `test -f 'libnm-core/nm-setting-bridge-port.c' || echo '$(srcdir)/'`libnm-core/nm-setting-bridge-port.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo `test -f 'src/core/devices/bluetooth/nm-bt-error.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bt-error.c -libnm-core/libnm_core_la-nm-setting-bridge.lo: libnm-core/nm-setting-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-bridge.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge.Tpo -c -o libnm-core/libnm_core_la-nm-setting-bridge.lo `test -f 'libnm-core/nm-setting-bridge.c' || echo '$(srcdir)/'`libnm-core/nm-setting-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-bridge.c' object='libnm-core/libnm_core_la-nm-setting-bridge.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo: src/core/devices/bluetooth/nm-bluez5-dun.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo -MD -MP -MF src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bluez5-dun.Tpo -c -o src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo `test -f 'src/core/devices/bluetooth/nm-bluez5-dun.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bluez5-dun.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bluez5-dun.Tpo src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bluez5-dun.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/nm-bluez5-dun.c' object='src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-bridge.lo `test -f 'libnm-core/nm-setting-bridge.c' || echo '$(srcdir)/'`libnm-core/nm-setting-bridge.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo `test -f 'src/core/devices/bluetooth/nm-bluez5-dun.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bluez5-dun.c -libnm-core/libnm_core_la-nm-setting-cdma.lo: libnm-core/nm-setting-cdma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-cdma.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-cdma.Tpo -c -o libnm-core/libnm_core_la-nm-setting-cdma.lo `test -f 'libnm-core/nm-setting-cdma.c' || echo '$(srcdir)/'`libnm-core/nm-setting-cdma.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-cdma.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-cdma.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-cdma.c' object='libnm-core/libnm_core_la-nm-setting-cdma.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-bluez-manager.lo: src/core/devices/bluetooth/nm-bluez-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-bluez-manager.lo -MD -MP -MF src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-bluez-manager.Tpo -c -o src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-bluez-manager.lo `test -f 'src/core/devices/bluetooth/nm-bluez-manager.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bluez-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-bluez-manager.Tpo src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-bluez-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/nm-bluez-manager.c' object='src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-bluez-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-cdma.lo `test -f 'libnm-core/nm-setting-cdma.c' || echo '$(srcdir)/'`libnm-core/nm-setting-cdma.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-bluez-manager.lo `test -f 'src/core/devices/bluetooth/nm-bluez-manager.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bluez-manager.c -libnm-core/libnm_core_la-nm-setting-connection.lo: libnm-core/nm-setting-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-connection.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-connection.Tpo -c -o libnm-core/libnm_core_la-nm-setting-connection.lo `test -f 'libnm-core/nm-setting-connection.c' || echo '$(srcdir)/'`libnm-core/nm-setting-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-connection.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-connection.c' object='libnm-core/libnm_core_la-nm-setting-connection.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-device-bt.lo: src/core/devices/bluetooth/nm-device-bt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-device-bt.lo -MD -MP -MF src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-device-bt.Tpo -c -o src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-device-bt.lo `test -f 'src/core/devices/bluetooth/nm-device-bt.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-device-bt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-device-bt.Tpo src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-device-bt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/nm-device-bt.c' object='src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-device-bt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-connection.lo `test -f 'libnm-core/nm-setting-connection.c' || echo '$(srcdir)/'`libnm-core/nm-setting-connection.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-device-bt.lo `test -f 'src/core/devices/bluetooth/nm-device-bt.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-device-bt.c -libnm-core/libnm_core_la-nm-setting-dcb.lo: libnm-core/nm-setting-dcb.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-dcb.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dcb.Tpo -c -o libnm-core/libnm_core_la-nm-setting-dcb.lo `test -f 'libnm-core/nm-setting-dcb.c' || echo '$(srcdir)/'`libnm-core/nm-setting-dcb.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dcb.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dcb.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-dcb.c' object='libnm-core/libnm_core_la-nm-setting-dcb.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovsdb.lo: src/core/devices/ovs/nm-ovsdb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovsdb.lo -MD -MP -MF src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovsdb.Tpo -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovsdb.lo `test -f 'src/core/devices/ovs/nm-ovsdb.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-ovsdb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovsdb.Tpo src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovsdb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/ovs/nm-ovsdb.c' object='src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovsdb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-dcb.lo `test -f 'libnm-core/nm-setting-dcb.c' || echo '$(srcdir)/'`libnm-core/nm-setting-dcb.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovsdb.lo `test -f 'src/core/devices/ovs/nm-ovsdb.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-ovsdb.c -libnm-core/libnm_core_la-nm-setting-dummy.lo: libnm-core/nm-setting-dummy.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-dummy.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dummy.Tpo -c -o libnm-core/libnm_core_la-nm-setting-dummy.lo `test -f 'libnm-core/nm-setting-dummy.c' || echo '$(srcdir)/'`libnm-core/nm-setting-dummy.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dummy.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dummy.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-dummy.c' object='libnm-core/libnm_core_la-nm-setting-dummy.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovs-factory.lo: src/core/devices/ovs/nm-ovs-factory.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovs-factory.lo -MD -MP -MF src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovs-factory.Tpo -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovs-factory.lo `test -f 'src/core/devices/ovs/nm-ovs-factory.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-ovs-factory.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovs-factory.Tpo src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovs-factory.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/ovs/nm-ovs-factory.c' object='src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovs-factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-dummy.lo `test -f 'libnm-core/nm-setting-dummy.c' || echo '$(srcdir)/'`libnm-core/nm-setting-dummy.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovs-factory.lo `test -f 'src/core/devices/ovs/nm-ovs-factory.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-ovs-factory.c -libnm-core/libnm_core_la-nm-setting-ethtool.lo: libnm-core/nm-setting-ethtool.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ethtool.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ethtool.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ethtool.lo `test -f 'libnm-core/nm-setting-ethtool.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ethtool.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ethtool.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ethtool.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ethtool.c' object='libnm-core/libnm_core_la-nm-setting-ethtool.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-interface.lo: src/core/devices/ovs/nm-device-ovs-interface.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-interface.lo -MD -MP -MF src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-interface.Tpo -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-interface.lo `test -f 'src/core/devices/ovs/nm-device-ovs-interface.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-interface.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-interface.Tpo src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-interface.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/ovs/nm-device-ovs-interface.c' object='src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-interface.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ethtool.lo `test -f 'libnm-core/nm-setting-ethtool.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ethtool.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-interface.lo `test -f 'src/core/devices/ovs/nm-device-ovs-interface.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-interface.c -libnm-core/libnm_core_la-nm-setting-generic.lo: libnm-core/nm-setting-generic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-generic.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-generic.Tpo -c -o libnm-core/libnm_core_la-nm-setting-generic.lo `test -f 'libnm-core/nm-setting-generic.c' || echo '$(srcdir)/'`libnm-core/nm-setting-generic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-generic.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-generic.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-generic.c' object='libnm-core/libnm_core_la-nm-setting-generic.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-port.lo: src/core/devices/ovs/nm-device-ovs-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-port.lo -MD -MP -MF src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-port.Tpo -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-port.lo `test -f 'src/core/devices/ovs/nm-device-ovs-port.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-port.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-port.Tpo src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-port.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/ovs/nm-device-ovs-port.c' object='src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-port.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-generic.lo `test -f 'libnm-core/nm-setting-generic.c' || echo '$(srcdir)/'`libnm-core/nm-setting-generic.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-port.lo `test -f 'src/core/devices/ovs/nm-device-ovs-port.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-port.c -libnm-core/libnm_core_la-nm-setting-gsm.lo: libnm-core/nm-setting-gsm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-gsm.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-gsm.Tpo -c -o libnm-core/libnm_core_la-nm-setting-gsm.lo `test -f 'libnm-core/nm-setting-gsm.c' || echo '$(srcdir)/'`libnm-core/nm-setting-gsm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-gsm.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-gsm.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-gsm.c' object='libnm-core/libnm_core_la-nm-setting-gsm.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.lo: src/core/devices/ovs/nm-device-ovs-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.lo -MD -MP -MF src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.Tpo -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.lo `test -f 'src/core/devices/ovs/nm-device-ovs-bridge.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.Tpo src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/ovs/nm-device-ovs-bridge.c' object='src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-gsm.lo `test -f 'libnm-core/nm-setting-gsm.c' || echo '$(srcdir)/'`libnm-core/nm-setting-gsm.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.lo `test -f 'src/core/devices/ovs/nm-device-ovs-bridge.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-bridge.c -libnm-core/libnm_core_la-nm-setting-hostname.lo: libnm-core/nm-setting-hostname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-hostname.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-hostname.Tpo -c -o libnm-core/libnm_core_la-nm-setting-hostname.lo `test -f 'libnm-core/nm-setting-hostname.c' || echo '$(srcdir)/'`libnm-core/nm-setting-hostname.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-hostname.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-hostname.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-hostname.c' object='libnm-core/libnm_core_la-nm-setting-hostname.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/team/libnm_device_plugin_team_la-nm-team-factory.lo: src/core/devices/team/nm-team-factory.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_team_libnm_device_plugin_team_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/team/libnm_device_plugin_team_la-nm-team-factory.lo -MD -MP -MF src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-team-factory.Tpo -c -o src/core/devices/team/libnm_device_plugin_team_la-nm-team-factory.lo `test -f 'src/core/devices/team/nm-team-factory.c' || echo '$(srcdir)/'`src/core/devices/team/nm-team-factory.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-team-factory.Tpo src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-team-factory.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/team/nm-team-factory.c' object='src/core/devices/team/libnm_device_plugin_team_la-nm-team-factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-hostname.lo `test -f 'libnm-core/nm-setting-hostname.c' || echo '$(srcdir)/'`libnm-core/nm-setting-hostname.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_team_libnm_device_plugin_team_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/team/libnm_device_plugin_team_la-nm-team-factory.lo `test -f 'src/core/devices/team/nm-team-factory.c' || echo '$(srcdir)/'`src/core/devices/team/nm-team-factory.c -libnm-core/libnm_core_la-nm-setting-infiniband.lo: libnm-core/nm-setting-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-infiniband.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-infiniband.Tpo -c -o libnm-core/libnm_core_la-nm-setting-infiniband.lo `test -f 'libnm-core/nm-setting-infiniband.c' || echo '$(srcdir)/'`libnm-core/nm-setting-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-infiniband.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-infiniband.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-infiniband.c' object='libnm-core/libnm_core_la-nm-setting-infiniband.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/team/libnm_device_plugin_team_la-nm-device-team.lo: src/core/devices/team/nm-device-team.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_team_libnm_device_plugin_team_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/team/libnm_device_plugin_team_la-nm-device-team.lo -MD -MP -MF src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-device-team.Tpo -c -o src/core/devices/team/libnm_device_plugin_team_la-nm-device-team.lo `test -f 'src/core/devices/team/nm-device-team.c' || echo '$(srcdir)/'`src/core/devices/team/nm-device-team.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-device-team.Tpo src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-device-team.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/team/nm-device-team.c' object='src/core/devices/team/libnm_device_plugin_team_la-nm-device-team.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-infiniband.lo `test -f 'libnm-core/nm-setting-infiniband.c' || echo '$(srcdir)/'`libnm-core/nm-setting-infiniband.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_team_libnm_device_plugin_team_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/team/libnm_device_plugin_team_la-nm-device-team.lo `test -f 'src/core/devices/team/nm-device-team.c' || echo '$(srcdir)/'`src/core/devices/team/nm-device-team.c -libnm-core/libnm_core_la-nm-setting-ip-config.lo: libnm-core/nm-setting-ip-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ip-config.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-config.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ip-config.lo `test -f 'libnm-core/nm-setting-ip-config.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ip-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-config.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ip-config.c' object='libnm-core/libnm_core_la-nm-setting-ip-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wifi/libnm_device_plugin_wifi_la-nm-wifi-factory.lo: src/core/devices/wifi/nm-wifi-factory.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_device_plugin_wifi_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_device_plugin_wifi_la-nm-wifi-factory.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_device_plugin_wifi_la-nm-wifi-factory.Tpo -c -o src/core/devices/wifi/libnm_device_plugin_wifi_la-nm-wifi-factory.lo `test -f 'src/core/devices/wifi/nm-wifi-factory.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-factory.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_device_plugin_wifi_la-nm-wifi-factory.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_device_plugin_wifi_la-nm-wifi-factory.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-wifi-factory.c' object='src/core/devices/wifi/libnm_device_plugin_wifi_la-nm-wifi-factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ip-config.lo `test -f 'libnm-core/nm-setting-ip-config.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ip-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_device_plugin_wifi_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_device_plugin_wifi_la-nm-wifi-factory.lo `test -f 'src/core/devices/wifi/nm-wifi-factory.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-factory.c -libnm-core/libnm_core_la-nm-setting-ip-tunnel.lo: libnm-core/nm-setting-ip-tunnel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ip-tunnel.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-tunnel.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ip-tunnel.lo `test -f 'libnm-core/nm-setting-ip-tunnel.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ip-tunnel.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-tunnel.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-tunnel.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ip-tunnel.c' object='libnm-core/libnm_core_la-nm-setting-ip-tunnel.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo: src/core/devices/wifi/nm-device-olpc-mesh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-olpc-mesh.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo `test -f 'src/core/devices/wifi/nm-device-olpc-mesh.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-olpc-mesh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-olpc-mesh.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-olpc-mesh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-device-olpc-mesh.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ip-tunnel.lo `test -f 'libnm-core/nm-setting-ip-tunnel.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ip-tunnel.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo `test -f 'src/core/devices/wifi/nm-device-olpc-mesh.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-olpc-mesh.c -libnm-core/libnm_core_la-nm-setting-ip4-config.lo: libnm-core/nm-setting-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ip4-config.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip4-config.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ip4-config.lo `test -f 'libnm-core/nm-setting-ip4-config.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip4-config.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip4-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ip4-config.c' object='libnm-core/libnm_core_la-nm-setting-ip4-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo: src/core/devices/wifi/nm-device-wifi-p2p.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi-p2p.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo `test -f 'src/core/devices/wifi/nm-device-wifi-p2p.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-wifi-p2p.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi-p2p.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi-p2p.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-device-wifi-p2p.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ip4-config.lo `test -f 'libnm-core/nm-setting-ip4-config.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ip4-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo `test -f 'src/core/devices/wifi/nm-device-wifi-p2p.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-wifi-p2p.c -libnm-core/libnm_core_la-nm-setting-ip6-config.lo: libnm-core/nm-setting-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ip6-config.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip6-config.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ip6-config.lo `test -f 'libnm-core/nm-setting-ip6-config.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip6-config.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip6-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ip6-config.c' object='libnm-core/libnm_core_la-nm-setting-ip6-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi.lo: src/core/devices/wifi/nm-device-wifi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi.lo `test -f 'src/core/devices/wifi/nm-device-wifi.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-wifi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-device-wifi.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ip6-config.lo `test -f 'libnm-core/nm-setting-ip6-config.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ip6-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi.lo `test -f 'src/core/devices/wifi/nm-device-wifi.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-wifi.c -libnm-core/libnm_core_la-nm-setting-macsec.lo: libnm-core/nm-setting-macsec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-macsec.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macsec.Tpo -c -o libnm-core/libnm_core_la-nm-setting-macsec.lo `test -f 'libnm-core/nm-setting-macsec.c' || echo '$(srcdir)/'`libnm-core/nm-setting-macsec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macsec.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macsec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-macsec.c' object='libnm-core/libnm_core_la-nm-setting-macsec.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-ap.lo: src/core/devices/wifi/nm-wifi-ap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-ap.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-ap.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-ap.lo `test -f 'src/core/devices/wifi/nm-wifi-ap.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-ap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-ap.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-ap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-wifi-ap.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-ap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-macsec.lo `test -f 'libnm-core/nm-setting-macsec.c' || echo '$(srcdir)/'`libnm-core/nm-setting-macsec.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-ap.lo `test -f 'src/core/devices/wifi/nm-wifi-ap.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-ap.c -libnm-core/libnm_core_la-nm-setting-macvlan.lo: libnm-core/nm-setting-macvlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-macvlan.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macvlan.Tpo -c -o libnm-core/libnm_core_la-nm-setting-macvlan.lo `test -f 'libnm-core/nm-setting-macvlan.c' || echo '$(srcdir)/'`libnm-core/nm-setting-macvlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macvlan.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macvlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-macvlan.c' object='libnm-core/libnm_core_la-nm-setting-macvlan.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo: src/core/devices/wifi/nm-wifi-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-common.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo `test -f 'src/core/devices/wifi/nm-wifi-common.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-common.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-common.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-wifi-common.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-macvlan.lo `test -f 'libnm-core/nm-setting-macvlan.c' || echo '$(srcdir)/'`libnm-core/nm-setting-macvlan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo `test -f 'src/core/devices/wifi/nm-wifi-common.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-common.c -libnm-core/libnm_core_la-nm-setting-match.lo: libnm-core/nm-setting-match.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-match.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-match.Tpo -c -o libnm-core/libnm_core_la-nm-setting-match.lo `test -f 'libnm-core/nm-setting-match.c' || echo '$(srcdir)/'`libnm-core/nm-setting-match.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-match.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-match.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-match.c' object='libnm-core/libnm_core_la-nm-setting-match.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo: src/core/devices/wifi/nm-wifi-p2p-peer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-p2p-peer.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo `test -f 'src/core/devices/wifi/nm-wifi-p2p-peer.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-p2p-peer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-p2p-peer.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-p2p-peer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-wifi-p2p-peer.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-match.lo `test -f 'libnm-core/nm-setting-match.c' || echo '$(srcdir)/'`libnm-core/nm-setting-match.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo `test -f 'src/core/devices/wifi/nm-wifi-p2p-peer.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-p2p-peer.c -libnm-core/libnm_core_la-nm-setting-olpc-mesh.lo: libnm-core/nm-setting-olpc-mesh.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-olpc-mesh.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-olpc-mesh.Tpo -c -o libnm-core/libnm_core_la-nm-setting-olpc-mesh.lo `test -f 'libnm-core/nm-setting-olpc-mesh.c' || echo '$(srcdir)/'`libnm-core/nm-setting-olpc-mesh.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-olpc-mesh.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-olpc-mesh.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-olpc-mesh.c' object='libnm-core/libnm_core_la-nm-setting-olpc-mesh.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo: src/core/devices/wifi/nm-wifi-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-utils.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo `test -f 'src/core/devices/wifi/nm-wifi-utils.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-utils.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-wifi-utils.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-olpc-mesh.lo `test -f 'libnm-core/nm-setting-olpc-mesh.c' || echo '$(srcdir)/'`libnm-core/nm-setting-olpc-mesh.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo `test -f 'src/core/devices/wifi/nm-wifi-utils.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-utils.c -libnm-core/libnm_core_la-nm-setting-ovs-bridge.lo: libnm-core/nm-setting-ovs-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ovs-bridge.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-bridge.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ovs-bridge.lo `test -f 'libnm-core/nm-setting-ovs-bridge.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-bridge.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-bridge.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ovs-bridge.c' object='libnm-core/libnm_core_la-nm-setting-ovs-bridge.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo: src/core/devices/wifi/nm-device-iwd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-iwd.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo `test -f 'src/core/devices/wifi/nm-device-iwd.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-iwd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-iwd.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-iwd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-device-iwd.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ovs-bridge.lo `test -f 'libnm-core/nm-setting-ovs-bridge.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-bridge.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo `test -f 'src/core/devices/wifi/nm-device-iwd.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-iwd.c -libnm-core/libnm_core_la-nm-setting-ovs-dpdk.lo: libnm-core/nm-setting-ovs-dpdk.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ovs-dpdk.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-dpdk.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ovs-dpdk.lo `test -f 'libnm-core/nm-setting-ovs-dpdk.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-dpdk.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-dpdk.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-dpdk.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ovs-dpdk.c' object='libnm-core/libnm_core_la-nm-setting-ovs-dpdk.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo: src/core/devices/wifi/nm-iwd-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-iwd-manager.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo `test -f 'src/core/devices/wifi/nm-iwd-manager.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-iwd-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-iwd-manager.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-iwd-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-iwd-manager.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ovs-dpdk.lo `test -f 'libnm-core/nm-setting-ovs-dpdk.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-dpdk.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo `test -f 'src/core/devices/wifi/nm-iwd-manager.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-iwd-manager.c -libnm-core/libnm_core_la-nm-setting-ovs-external-ids.lo: libnm-core/nm-setting-ovs-external-ids.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ovs-external-ids.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-external-ids.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ovs-external-ids.lo `test -f 'libnm-core/nm-setting-ovs-external-ids.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-external-ids.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-external-ids.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-external-ids.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ovs-external-ids.c' object='libnm-core/libnm_core_la-nm-setting-ovs-external-ids.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-wwan-factory.lo: src/core/devices/wwan/nm-wwan-factory.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_device_plugin_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-wwan-factory.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-wwan-factory.Tpo -c -o src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-wwan-factory.lo `test -f 'src/core/devices/wwan/nm-wwan-factory.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-wwan-factory.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-wwan-factory.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-wwan-factory.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-wwan-factory.c' object='src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-wwan-factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ovs-external-ids.lo `test -f 'libnm-core/nm-setting-ovs-external-ids.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-external-ids.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_device_plugin_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-wwan-factory.lo `test -f 'src/core/devices/wwan/nm-wwan-factory.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-wwan-factory.c -libnm-core/libnm_core_la-nm-setting-ovs-interface.lo: libnm-core/nm-setting-ovs-interface.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ovs-interface.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-interface.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ovs-interface.lo `test -f 'libnm-core/nm-setting-ovs-interface.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-interface.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-interface.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-interface.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ovs-interface.c' object='libnm-core/libnm_core_la-nm-setting-ovs-interface.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-device-modem.lo: src/core/devices/wwan/nm-device-modem.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_device_plugin_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-device-modem.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-device-modem.Tpo -c -o src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-device-modem.lo `test -f 'src/core/devices/wwan/nm-device-modem.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-device-modem.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-device-modem.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-device-modem.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-device-modem.c' object='src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-device-modem.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ovs-interface.lo `test -f 'libnm-core/nm-setting-ovs-interface.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-interface.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_device_plugin_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-device-modem.lo `test -f 'src/core/devices/wwan/nm-device-modem.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-device-modem.c -libnm-core/libnm_core_la-nm-setting-ovs-patch.lo: libnm-core/nm-setting-ovs-patch.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ovs-patch.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-patch.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ovs-patch.lo `test -f 'libnm-core/nm-setting-ovs-patch.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-patch.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-patch.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-patch.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ovs-patch.c' object='libnm-core/libnm_core_la-nm-setting-ovs-patch.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo: src/core/devices/wwan/nm-modem-broadband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-broadband.Tpo -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo `test -f 'src/core/devices/wwan/nm-modem-broadband.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-broadband.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-broadband.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-broadband.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-modem-broadband.c' object='src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ovs-patch.lo `test -f 'libnm-core/nm-setting-ovs-patch.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-patch.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo `test -f 'src/core/devices/wwan/nm-modem-broadband.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-broadband.c -libnm-core/libnm_core_la-nm-setting-ovs-port.lo: libnm-core/nm-setting-ovs-port.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ovs-port.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-port.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ovs-port.lo `test -f 'libnm-core/nm-setting-ovs-port.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-port.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-port.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-port.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ovs-port.c' object='libnm-core/libnm_core_la-nm-setting-ovs-port.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo: src/core/devices/wwan/nm-modem-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-manager.Tpo -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo `test -f 'src/core/devices/wwan/nm-modem-manager.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-manager.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-modem-manager.c' object='src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ovs-port.lo `test -f 'libnm-core/nm-setting-ovs-port.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ovs-port.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo `test -f 'src/core/devices/wwan/nm-modem-manager.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-manager.c -libnm-core/libnm_core_la-nm-setting-ppp.lo: libnm-core/nm-setting-ppp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-ppp.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ppp.Tpo -c -o libnm-core/libnm_core_la-nm-setting-ppp.lo `test -f 'libnm-core/nm-setting-ppp.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ppp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ppp.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ppp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-ppp.c' object='libnm-core/libnm_core_la-nm-setting-ppp.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wwan/libnm_wwan_la-nm-modem.lo: src/core/devices/wwan/nm-modem.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_wwan_la-nm-modem.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem.Tpo -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem.lo `test -f 'src/core/devices/wwan/nm-modem.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-modem.c' object='src/core/devices/wwan/libnm_wwan_la-nm-modem.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-ppp.lo `test -f 'libnm-core/nm-setting-ppp.c' || echo '$(srcdir)/'`libnm-core/nm-setting-ppp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem.lo `test -f 'src/core/devices/wwan/nm-modem.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem.c -libnm-core/libnm_core_la-nm-setting-pppoe.lo: libnm-core/nm-setting-pppoe.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-pppoe.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-pppoe.Tpo -c -o libnm-core/libnm_core_la-nm-setting-pppoe.lo `test -f 'libnm-core/nm-setting-pppoe.c' || echo '$(srcdir)/'`libnm-core/nm-setting-pppoe.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-pppoe.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-pppoe.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-pppoe.c' object='libnm-core/libnm_core_la-nm-setting-pppoe.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo: src/core/devices/wwan/nm-service-providers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-service-providers.Tpo -c -o src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo `test -f 'src/core/devices/wwan/nm-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-service-providers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-service-providers.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-service-providers.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-service-providers.c' object='src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-pppoe.lo `test -f 'libnm-core/nm-setting-pppoe.c' || echo '$(srcdir)/'`libnm-core/nm-setting-pppoe.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo `test -f 'src/core/devices/wwan/nm-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-service-providers.c -libnm-core/libnm_core_la-nm-setting-proxy.lo: libnm-core/nm-setting-proxy.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-proxy.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-proxy.Tpo -c -o libnm-core/libnm_core_la-nm-setting-proxy.lo `test -f 'libnm-core/nm-setting-proxy.c' || echo '$(srcdir)/'`libnm-core/nm-setting-proxy.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-proxy.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-proxy.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-proxy.c' object='libnm-core/libnm_core_la-nm-setting-proxy.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo: src/core/devices/wwan/nm-modem-ofono.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-ofono.Tpo -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo `test -f 'src/core/devices/wwan/nm-modem-ofono.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-ofono.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-ofono.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-ofono.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-modem-ofono.c' object='src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-proxy.lo `test -f 'libnm-core/nm-setting-proxy.c' || echo '$(srcdir)/'`libnm-core/nm-setting-proxy.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo `test -f 'src/core/devices/wwan/nm-modem-ofono.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-ofono.c -libnm-core/libnm_core_la-nm-setting-serial.lo: libnm-core/nm-setting-serial.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-serial.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-serial.Tpo -c -o libnm-core/libnm_core_la-nm-setting-serial.lo `test -f 'libnm-core/nm-setting-serial.c' || echo '$(srcdir)/'`libnm-core/nm-setting-serial.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-serial.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-serial.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-serial.c' object='libnm-core/libnm_core_la-nm-setting-serial.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-checkpoint.lo: src/core/nm-checkpoint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-checkpoint.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint.Tpo -c -o src/core/libNetworkManager_la-nm-checkpoint.lo `test -f 'src/core/nm-checkpoint.c' || echo '$(srcdir)/'`src/core/nm-checkpoint.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-checkpoint.c' object='src/core/libNetworkManager_la-nm-checkpoint.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-serial.lo `test -f 'libnm-core/nm-setting-serial.c' || echo '$(srcdir)/'`libnm-core/nm-setting-serial.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-checkpoint.lo `test -f 'src/core/nm-checkpoint.c' || echo '$(srcdir)/'`src/core/nm-checkpoint.c -libnm-core/libnm_core_la-nm-setting-sriov.lo: libnm-core/nm-setting-sriov.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-sriov.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-sriov.Tpo -c -o libnm-core/libnm_core_la-nm-setting-sriov.lo `test -f 'libnm-core/nm-setting-sriov.c' || echo '$(srcdir)/'`libnm-core/nm-setting-sriov.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-sriov.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-sriov.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-sriov.c' object='libnm-core/libnm_core_la-nm-setting-sriov.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-checkpoint-manager.lo: src/core/nm-checkpoint-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-checkpoint-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint-manager.Tpo -c -o src/core/libNetworkManager_la-nm-checkpoint-manager.lo `test -f 'src/core/nm-checkpoint-manager.c' || echo '$(srcdir)/'`src/core/nm-checkpoint-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-checkpoint-manager.c' object='src/core/libNetworkManager_la-nm-checkpoint-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-sriov.lo `test -f 'libnm-core/nm-setting-sriov.c' || echo '$(srcdir)/'`libnm-core/nm-setting-sriov.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-checkpoint-manager.lo `test -f 'src/core/nm-checkpoint-manager.c' || echo '$(srcdir)/'`src/core/nm-checkpoint-manager.c -libnm-core/libnm_core_la-nm-setting-tc-config.lo: libnm-core/nm-setting-tc-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-tc-config.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tc-config.Tpo -c -o libnm-core/libnm_core_la-nm-setting-tc-config.lo `test -f 'libnm-core/nm-setting-tc-config.c' || echo '$(srcdir)/'`libnm-core/nm-setting-tc-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tc-config.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tc-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-tc-config.c' object='libnm-core/libnm_core_la-nm-setting-tc-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-acd-manager.lo: src/core/devices/nm-acd-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-acd-manager.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-acd-manager.Tpo -c -o src/core/devices/libNetworkManager_la-nm-acd-manager.lo `test -f 'src/core/devices/nm-acd-manager.c' || echo '$(srcdir)/'`src/core/devices/nm-acd-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-acd-manager.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-acd-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-acd-manager.c' object='src/core/devices/libNetworkManager_la-nm-acd-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-tc-config.lo `test -f 'libnm-core/nm-setting-tc-config.c' || echo '$(srcdir)/'`libnm-core/nm-setting-tc-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-acd-manager.lo `test -f 'src/core/devices/nm-acd-manager.c' || echo '$(srcdir)/'`src/core/devices/nm-acd-manager.c -libnm-core/libnm_core_la-nm-setting-team-port.lo: libnm-core/nm-setting-team-port.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-team-port.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team-port.Tpo -c -o libnm-core/libnm_core_la-nm-setting-team-port.lo `test -f 'libnm-core/nm-setting-team-port.c' || echo '$(srcdir)/'`libnm-core/nm-setting-team-port.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team-port.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team-port.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-team-port.c' object='libnm-core/libnm_core_la-nm-setting-team-port.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-lldp-listener.lo: src/core/devices/nm-lldp-listener.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-lldp-listener.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-lldp-listener.Tpo -c -o src/core/devices/libNetworkManager_la-nm-lldp-listener.lo `test -f 'src/core/devices/nm-lldp-listener.c' || echo '$(srcdir)/'`src/core/devices/nm-lldp-listener.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-lldp-listener.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-lldp-listener.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-lldp-listener.c' object='src/core/devices/libNetworkManager_la-nm-lldp-listener.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-team-port.lo `test -f 'libnm-core/nm-setting-team-port.c' || echo '$(srcdir)/'`libnm-core/nm-setting-team-port.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-lldp-listener.lo `test -f 'src/core/devices/nm-lldp-listener.c' || echo '$(srcdir)/'`src/core/devices/nm-lldp-listener.c -libnm-core/libnm_core_la-nm-setting-team.lo: libnm-core/nm-setting-team.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-team.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team.Tpo -c -o libnm-core/libnm_core_la-nm-setting-team.lo `test -f 'libnm-core/nm-setting-team.c' || echo '$(srcdir)/'`libnm-core/nm-setting-team.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-team.c' object='libnm-core/libnm_core_la-nm-setting-team.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device.lo: src/core/devices/nm-device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device.lo `test -f 'src/core/devices/nm-device.c' || echo '$(srcdir)/'`src/core/devices/nm-device.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device.c' object='src/core/devices/libNetworkManager_la-nm-device.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-team.lo `test -f 'libnm-core/nm-setting-team.c' || echo '$(srcdir)/'`libnm-core/nm-setting-team.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device.lo `test -f 'src/core/devices/nm-device.c' || echo '$(srcdir)/'`src/core/devices/nm-device.c -libnm-core/libnm_core_la-nm-setting-tun.lo: libnm-core/nm-setting-tun.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-tun.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tun.Tpo -c -o libnm-core/libnm_core_la-nm-setting-tun.lo `test -f 'libnm-core/nm-setting-tun.c' || echo '$(srcdir)/'`libnm-core/nm-setting-tun.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tun.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tun.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-tun.c' object='libnm-core/libnm_core_la-nm-setting-tun.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-ethernet-utils.lo: src/core/devices/nm-device-ethernet-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-ethernet-utils.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet-utils.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-ethernet-utils.lo `test -f 'src/core/devices/nm-device-ethernet-utils.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ethernet-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet-utils.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-ethernet-utils.c' object='src/core/devices/libNetworkManager_la-nm-device-ethernet-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-tun.lo `test -f 'libnm-core/nm-setting-tun.c' || echo '$(srcdir)/'`libnm-core/nm-setting-tun.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-ethernet-utils.lo `test -f 'src/core/devices/nm-device-ethernet-utils.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ethernet-utils.c -libnm-core/libnm_core_la-nm-setting-user.lo: libnm-core/nm-setting-user.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-user.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-user.Tpo -c -o libnm-core/libnm_core_la-nm-setting-user.lo `test -f 'libnm-core/nm-setting-user.c' || echo '$(srcdir)/'`libnm-core/nm-setting-user.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-user.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-user.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-user.c' object='libnm-core/libnm_core_la-nm-setting-user.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-factory.lo: src/core/devices/nm-device-factory.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-factory.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-factory.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-factory.lo `test -f 'src/core/devices/nm-device-factory.c' || echo '$(srcdir)/'`src/core/devices/nm-device-factory.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-factory.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-factory.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-factory.c' object='src/core/devices/libNetworkManager_la-nm-device-factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-user.lo `test -f 'libnm-core/nm-setting-user.c' || echo '$(srcdir)/'`libnm-core/nm-setting-user.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-factory.lo `test -f 'src/core/devices/nm-device-factory.c' || echo '$(srcdir)/'`src/core/devices/nm-device-factory.c -libnm-core/libnm_core_la-nm-setting-veth.lo: libnm-core/nm-setting-veth.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-veth.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-veth.Tpo -c -o libnm-core/libnm_core_la-nm-setting-veth.lo `test -f 'libnm-core/nm-setting-veth.c' || echo '$(srcdir)/'`libnm-core/nm-setting-veth.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-veth.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-veth.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-veth.c' object='libnm-core/libnm_core_la-nm-setting-veth.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-generic.lo: src/core/devices/nm-device-generic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-generic.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-generic.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-generic.lo `test -f 'src/core/devices/nm-device-generic.c' || echo '$(srcdir)/'`src/core/devices/nm-device-generic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-generic.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-generic.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-generic.c' object='src/core/devices/libNetworkManager_la-nm-device-generic.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-veth.lo `test -f 'libnm-core/nm-setting-veth.c' || echo '$(srcdir)/'`libnm-core/nm-setting-veth.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-generic.lo `test -f 'src/core/devices/nm-device-generic.c' || echo '$(srcdir)/'`src/core/devices/nm-device-generic.c -libnm-core/libnm_core_la-nm-setting-vlan.lo: libnm-core/nm-setting-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-vlan.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vlan.Tpo -c -o libnm-core/libnm_core_la-nm-setting-vlan.lo `test -f 'libnm-core/nm-setting-vlan.c' || echo '$(srcdir)/'`libnm-core/nm-setting-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vlan.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-vlan.c' object='libnm-core/libnm_core_la-nm-setting-vlan.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-6lowpan.lo: src/core/devices/nm-device-6lowpan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-6lowpan.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-6lowpan.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-6lowpan.lo `test -f 'src/core/devices/nm-device-6lowpan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-6lowpan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-6lowpan.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-6lowpan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-6lowpan.c' object='src/core/devices/libNetworkManager_la-nm-device-6lowpan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-vlan.lo `test -f 'libnm-core/nm-setting-vlan.c' || echo '$(srcdir)/'`libnm-core/nm-setting-vlan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-6lowpan.lo `test -f 'src/core/devices/nm-device-6lowpan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-6lowpan.c -libnm-core/libnm_core_la-nm-setting-vpn.lo: libnm-core/nm-setting-vpn.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-vpn.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vpn.Tpo -c -o libnm-core/libnm_core_la-nm-setting-vpn.lo `test -f 'libnm-core/nm-setting-vpn.c' || echo '$(srcdir)/'`libnm-core/nm-setting-vpn.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vpn.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vpn.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-vpn.c' object='libnm-core/libnm_core_la-nm-setting-vpn.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-bond.lo: src/core/devices/nm-device-bond.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-bond.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bond.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-bond.lo `test -f 'src/core/devices/nm-device-bond.c' || echo '$(srcdir)/'`src/core/devices/nm-device-bond.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bond.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bond.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-bond.c' object='src/core/devices/libNetworkManager_la-nm-device-bond.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-vpn.lo `test -f 'libnm-core/nm-setting-vpn.c' || echo '$(srcdir)/'`libnm-core/nm-setting-vpn.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-bond.lo `test -f 'src/core/devices/nm-device-bond.c' || echo '$(srcdir)/'`src/core/devices/nm-device-bond.c -libnm-core/libnm_core_la-nm-setting-vrf.lo: libnm-core/nm-setting-vrf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-vrf.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vrf.Tpo -c -o libnm-core/libnm_core_la-nm-setting-vrf.lo `test -f 'libnm-core/nm-setting-vrf.c' || echo '$(srcdir)/'`libnm-core/nm-setting-vrf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vrf.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vrf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-vrf.c' object='libnm-core/libnm_core_la-nm-setting-vrf.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-bridge.lo: src/core/devices/nm-device-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-bridge.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bridge.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-bridge.lo `test -f 'src/core/devices/nm-device-bridge.c' || echo '$(srcdir)/'`src/core/devices/nm-device-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bridge.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bridge.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-bridge.c' object='src/core/devices/libNetworkManager_la-nm-device-bridge.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-vrf.lo `test -f 'libnm-core/nm-setting-vrf.c' || echo '$(srcdir)/'`libnm-core/nm-setting-vrf.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-bridge.lo `test -f 'src/core/devices/nm-device-bridge.c' || echo '$(srcdir)/'`src/core/devices/nm-device-bridge.c -libnm-core/libnm_core_la-nm-setting-vxlan.lo: libnm-core/nm-setting-vxlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-vxlan.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vxlan.Tpo -c -o libnm-core/libnm_core_la-nm-setting-vxlan.lo `test -f 'libnm-core/nm-setting-vxlan.c' || echo '$(srcdir)/'`libnm-core/nm-setting-vxlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vxlan.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vxlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-vxlan.c' object='libnm-core/libnm_core_la-nm-setting-vxlan.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-dummy.lo: src/core/devices/nm-device-dummy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-dummy.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-dummy.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-dummy.lo `test -f 'src/core/devices/nm-device-dummy.c' || echo '$(srcdir)/'`src/core/devices/nm-device-dummy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-dummy.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-dummy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-dummy.c' object='src/core/devices/libNetworkManager_la-nm-device-dummy.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-vxlan.lo `test -f 'libnm-core/nm-setting-vxlan.c' || echo '$(srcdir)/'`libnm-core/nm-setting-vxlan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-dummy.lo `test -f 'src/core/devices/nm-device-dummy.c' || echo '$(srcdir)/'`src/core/devices/nm-device-dummy.c -libnm-core/libnm_core_la-nm-setting-wifi-p2p.lo: libnm-core/nm-setting-wifi-p2p.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-wifi-p2p.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wifi-p2p.Tpo -c -o libnm-core/libnm_core_la-nm-setting-wifi-p2p.lo `test -f 'libnm-core/nm-setting-wifi-p2p.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wifi-p2p.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wifi-p2p.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wifi-p2p.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-wifi-p2p.c' object='libnm-core/libnm_core_la-nm-setting-wifi-p2p.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-ethernet.lo: src/core/devices/nm-device-ethernet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-ethernet.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-ethernet.lo `test -f 'src/core/devices/nm-device-ethernet.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ethernet.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-ethernet.c' object='src/core/devices/libNetworkManager_la-nm-device-ethernet.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-wifi-p2p.lo `test -f 'libnm-core/nm-setting-wifi-p2p.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wifi-p2p.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-ethernet.lo `test -f 'src/core/devices/nm-device-ethernet.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ethernet.c -libnm-core/libnm_core_la-nm-setting-wimax.lo: libnm-core/nm-setting-wimax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-wimax.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wimax.Tpo -c -o libnm-core/libnm_core_la-nm-setting-wimax.lo `test -f 'libnm-core/nm-setting-wimax.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wimax.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wimax.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wimax.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-wimax.c' object='libnm-core/libnm_core_la-nm-setting-wimax.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-infiniband.lo: src/core/devices/nm-device-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-infiniband.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-infiniband.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-infiniband.lo `test -f 'src/core/devices/nm-device-infiniband.c' || echo '$(srcdir)/'`src/core/devices/nm-device-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-infiniband.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-infiniband.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-infiniband.c' object='src/core/devices/libNetworkManager_la-nm-device-infiniband.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-wimax.lo `test -f 'libnm-core/nm-setting-wimax.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wimax.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-infiniband.lo `test -f 'src/core/devices/nm-device-infiniband.c' || echo '$(srcdir)/'`src/core/devices/nm-device-infiniband.c -libnm-core/libnm_core_la-nm-setting-wired.lo: libnm-core/nm-setting-wired.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-wired.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wired.Tpo -c -o libnm-core/libnm_core_la-nm-setting-wired.lo `test -f 'libnm-core/nm-setting-wired.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wired.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wired.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wired.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-wired.c' object='libnm-core/libnm_core_la-nm-setting-wired.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-ip-tunnel.lo: src/core/devices/nm-device-ip-tunnel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-ip-tunnel.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ip-tunnel.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-ip-tunnel.lo `test -f 'src/core/devices/nm-device-ip-tunnel.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ip-tunnel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ip-tunnel.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ip-tunnel.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-ip-tunnel.c' object='src/core/devices/libNetworkManager_la-nm-device-ip-tunnel.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-wired.lo `test -f 'libnm-core/nm-setting-wired.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wired.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-ip-tunnel.lo `test -f 'src/core/devices/nm-device-ip-tunnel.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ip-tunnel.c -libnm-core/libnm_core_la-nm-setting-wireguard.lo: libnm-core/nm-setting-wireguard.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-wireguard.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireguard.Tpo -c -o libnm-core/libnm_core_la-nm-setting-wireguard.lo `test -f 'libnm-core/nm-setting-wireguard.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wireguard.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireguard.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireguard.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-wireguard.c' object='libnm-core/libnm_core_la-nm-setting-wireguard.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-macsec.lo: src/core/devices/nm-device-macsec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-macsec.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macsec.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-macsec.lo `test -f 'src/core/devices/nm-device-macsec.c' || echo '$(srcdir)/'`src/core/devices/nm-device-macsec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macsec.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macsec.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-macsec.c' object='src/core/devices/libNetworkManager_la-nm-device-macsec.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-wireguard.lo `test -f 'libnm-core/nm-setting-wireguard.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wireguard.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-macsec.lo `test -f 'src/core/devices/nm-device-macsec.c' || echo '$(srcdir)/'`src/core/devices/nm-device-macsec.c -libnm-core/libnm_core_la-nm-setting-wireless-security.lo: libnm-core/nm-setting-wireless-security.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-wireless-security.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless-security.Tpo -c -o libnm-core/libnm_core_la-nm-setting-wireless-security.lo `test -f 'libnm-core/nm-setting-wireless-security.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wireless-security.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless-security.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless-security.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-wireless-security.c' object='libnm-core/libnm_core_la-nm-setting-wireless-security.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-macvlan.lo: src/core/devices/nm-device-macvlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-macvlan.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macvlan.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-macvlan.lo `test -f 'src/core/devices/nm-device-macvlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-macvlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macvlan.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macvlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-macvlan.c' object='src/core/devices/libNetworkManager_la-nm-device-macvlan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-wireless-security.lo `test -f 'libnm-core/nm-setting-wireless-security.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wireless-security.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-macvlan.lo `test -f 'src/core/devices/nm-device-macvlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-macvlan.c -libnm-core/libnm_core_la-nm-setting-wireless.lo: libnm-core/nm-setting-wireless.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-wireless.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless.Tpo -c -o libnm-core/libnm_core_la-nm-setting-wireless.lo `test -f 'libnm-core/nm-setting-wireless.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wireless.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-wireless.c' object='libnm-core/libnm_core_la-nm-setting-wireless.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-ppp.lo: src/core/devices/nm-device-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-ppp.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ppp.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-ppp.lo `test -f 'src/core/devices/nm-device-ppp.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ppp.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ppp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-ppp.c' object='src/core/devices/libNetworkManager_la-nm-device-ppp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-wireless.lo `test -f 'libnm-core/nm-setting-wireless.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wireless.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-ppp.lo `test -f 'src/core/devices/nm-device-ppp.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ppp.c -libnm-core/libnm_core_la-nm-setting-wpan.lo: libnm-core/nm-setting-wpan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting-wpan.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wpan.Tpo -c -o libnm-core/libnm_core_la-nm-setting-wpan.lo `test -f 'libnm-core/nm-setting-wpan.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wpan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wpan.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wpan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting-wpan.c' object='libnm-core/libnm_core_la-nm-setting-wpan.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-tun.lo: src/core/devices/nm-device-tun.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-tun.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-tun.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-tun.lo `test -f 'src/core/devices/nm-device-tun.c' || echo '$(srcdir)/'`src/core/devices/nm-device-tun.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-tun.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-tun.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-tun.c' object='src/core/devices/libNetworkManager_la-nm-device-tun.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting-wpan.lo `test -f 'libnm-core/nm-setting-wpan.c' || echo '$(srcdir)/'`libnm-core/nm-setting-wpan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-tun.lo `test -f 'src/core/devices/nm-device-tun.c' || echo '$(srcdir)/'`src/core/devices/nm-device-tun.c -libnm-core/libnm_core_la-nm-connection.lo: libnm-core/nm-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-connection.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-connection.Tpo -c -o libnm-core/libnm_core_la-nm-connection.lo `test -f 'libnm-core/nm-connection.c' || echo '$(srcdir)/'`libnm-core/nm-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-connection.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-connection.c' object='libnm-core/libnm_core_la-nm-connection.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-veth.lo: src/core/devices/nm-device-veth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-veth.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-veth.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-veth.lo `test -f 'src/core/devices/nm-device-veth.c' || echo '$(srcdir)/'`src/core/devices/nm-device-veth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-veth.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-veth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-veth.c' object='src/core/devices/libNetworkManager_la-nm-device-veth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-connection.lo `test -f 'libnm-core/nm-connection.c' || echo '$(srcdir)/'`libnm-core/nm-connection.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-veth.lo `test -f 'src/core/devices/nm-device-veth.c' || echo '$(srcdir)/'`src/core/devices/nm-device-veth.c -libnm-core/libnm_core_la-nm-crypto.lo: libnm-core/nm-crypto.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-crypto.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-crypto.Tpo -c -o libnm-core/libnm_core_la-nm-crypto.lo `test -f 'libnm-core/nm-crypto.c' || echo '$(srcdir)/'`libnm-core/nm-crypto.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-crypto.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-crypto.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-crypto.c' object='libnm-core/libnm_core_la-nm-crypto.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-vlan.lo: src/core/devices/nm-device-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-vlan.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vlan.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-vlan.lo `test -f 'src/core/devices/nm-device-vlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vlan.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-vlan.c' object='src/core/devices/libNetworkManager_la-nm-device-vlan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-crypto.lo `test -f 'libnm-core/nm-crypto.c' || echo '$(srcdir)/'`libnm-core/nm-crypto.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-vlan.lo `test -f 'src/core/devices/nm-device-vlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vlan.c -libnm-core/libnm_core_la-nm-dbus-utils.lo: libnm-core/nm-dbus-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-dbus-utils.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-dbus-utils.Tpo -c -o libnm-core/libnm_core_la-nm-dbus-utils.lo `test -f 'libnm-core/nm-dbus-utils.c' || echo '$(srcdir)/'`libnm-core/nm-dbus-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-dbus-utils.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-dbus-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-dbus-utils.c' object='libnm-core/libnm_core_la-nm-dbus-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-vrf.lo: src/core/devices/nm-device-vrf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-vrf.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vrf.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-vrf.lo `test -f 'src/core/devices/nm-device-vrf.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vrf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vrf.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vrf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-vrf.c' object='src/core/devices/libNetworkManager_la-nm-device-vrf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-dbus-utils.lo `test -f 'libnm-core/nm-dbus-utils.c' || echo '$(srcdir)/'`libnm-core/nm-dbus-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-vrf.lo `test -f 'src/core/devices/nm-device-vrf.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vrf.c -libnm-core/libnm_core_la-nm-errors.lo: libnm-core/nm-errors.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-errors.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-errors.Tpo -c -o libnm-core/libnm_core_la-nm-errors.lo `test -f 'libnm-core/nm-errors.c' || echo '$(srcdir)/'`libnm-core/nm-errors.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-errors.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-errors.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-errors.c' object='libnm-core/libnm_core_la-nm-errors.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-vxlan.lo: src/core/devices/nm-device-vxlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-vxlan.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vxlan.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-vxlan.lo `test -f 'src/core/devices/nm-device-vxlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vxlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vxlan.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vxlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-vxlan.c' object='src/core/devices/libNetworkManager_la-nm-device-vxlan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-errors.lo `test -f 'libnm-core/nm-errors.c' || echo '$(srcdir)/'`libnm-core/nm-errors.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-vxlan.lo `test -f 'src/core/devices/nm-device-vxlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vxlan.c -libnm-core/libnm_core_la-nm-keyfile-utils.lo: libnm-core/nm-keyfile-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-keyfile-utils.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile-utils.Tpo -c -o libnm-core/libnm_core_la-nm-keyfile-utils.lo `test -f 'libnm-core/nm-keyfile-utils.c' || echo '$(srcdir)/'`libnm-core/nm-keyfile-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile-utils.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-keyfile-utils.c' object='libnm-core/libnm_core_la-nm-keyfile-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-wireguard.lo: src/core/devices/nm-device-wireguard.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-wireguard.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wireguard.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-wireguard.lo `test -f 'src/core/devices/nm-device-wireguard.c' || echo '$(srcdir)/'`src/core/devices/nm-device-wireguard.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wireguard.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wireguard.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-wireguard.c' object='src/core/devices/libNetworkManager_la-nm-device-wireguard.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-keyfile-utils.lo `test -f 'libnm-core/nm-keyfile-utils.c' || echo '$(srcdir)/'`libnm-core/nm-keyfile-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-wireguard.lo `test -f 'src/core/devices/nm-device-wireguard.c' || echo '$(srcdir)/'`src/core/devices/nm-device-wireguard.c -libnm-core/libnm_core_la-nm-keyfile.lo: libnm-core/nm-keyfile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-keyfile.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile.Tpo -c -o libnm-core/libnm_core_la-nm-keyfile.lo `test -f 'libnm-core/nm-keyfile.c' || echo '$(srcdir)/'`libnm-core/nm-keyfile.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-keyfile.c' object='libnm-core/libnm_core_la-nm-keyfile.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/devices/libNetworkManager_la-nm-device-wpan.lo: src/core/devices/nm-device-wpan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-wpan.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wpan.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-wpan.lo `test -f 'src/core/devices/nm-device-wpan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-wpan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wpan.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wpan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-wpan.c' object='src/core/devices/libNetworkManager_la-nm-device-wpan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-keyfile.lo `test -f 'libnm-core/nm-keyfile.c' || echo '$(srcdir)/'`libnm-core/nm-keyfile.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-wpan.lo `test -f 'src/core/devices/nm-device-wpan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-wpan.c -libnm-core/libnm_core_la-nm-meta-setting-base-impl.lo: libnm-core/nm-meta-setting-base-impl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-meta-setting-base-impl.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-meta-setting-base-impl.Tpo -c -o libnm-core/libnm_core_la-nm-meta-setting-base-impl.lo `test -f 'libnm-core/nm-meta-setting-base-impl.c' || echo '$(srcdir)/'`libnm-core/nm-meta-setting-base-impl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-meta-setting-base-impl.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-meta-setting-base-impl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-meta-setting-base-impl.c' object='libnm-core/libnm_core_la-nm-meta-setting-base-impl.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcanon.lo: src/core/dhcp/nm-dhcp-dhcpcanon.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcanon.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcanon.Tpo -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcanon.lo `test -f 'src/core/dhcp/nm-dhcp-dhcpcanon.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhcpcanon.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcanon.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcanon.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-dhcpcanon.c' object='src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcanon.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-meta-setting-base-impl.lo `test -f 'libnm-core/nm-meta-setting-base-impl.c' || echo '$(srcdir)/'`libnm-core/nm-meta-setting-base-impl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcanon.lo `test -f 'src/core/dhcp/nm-dhcp-dhcpcanon.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhcpcanon.c -libnm-core/libnm_core_la-nm-property-compare.lo: libnm-core/nm-property-compare.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-property-compare.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-property-compare.Tpo -c -o libnm-core/libnm_core_la-nm-property-compare.lo `test -f 'libnm-core/nm-property-compare.c' || echo '$(srcdir)/'`libnm-core/nm-property-compare.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-property-compare.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-property-compare.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-property-compare.c' object='libnm-core/libnm_core_la-nm-property-compare.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient.lo: src/core/dhcp/nm-dhcp-dhclient.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient.Tpo -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient.lo `test -f 'src/core/dhcp/nm-dhcp-dhclient.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhclient.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-dhclient.c' object='src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-property-compare.lo `test -f 'libnm-core/nm-property-compare.c' || echo '$(srcdir)/'`libnm-core/nm-property-compare.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient.lo `test -f 'src/core/dhcp/nm-dhcp-dhclient.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhclient.c -libnm-core/libnm_core_la-nm-setting.lo: libnm-core/nm-setting.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-setting.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-setting.Tpo -c -o libnm-core/libnm_core_la-nm-setting.lo `test -f 'libnm-core/nm-setting.c' || echo '$(srcdir)/'`libnm-core/nm-setting.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-setting.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-setting.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-setting.c' object='libnm-core/libnm_core_la-nm-setting.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcd.lo: src/core/dhcp/nm-dhcp-dhcpcd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcd.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcd.Tpo -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcd.lo `test -f 'src/core/dhcp/nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhcpcd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcd.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-dhcpcd.c' object='src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-setting.lo `test -f 'libnm-core/nm-setting.c' || echo '$(srcdir)/'`libnm-core/nm-setting.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcd.lo `test -f 'src/core/dhcp/nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhcpcd.c -libnm-core/libnm_core_la-nm-simple-connection.lo: libnm-core/nm-simple-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-simple-connection.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-simple-connection.Tpo -c -o libnm-core/libnm_core_la-nm-simple-connection.lo `test -f 'libnm-core/nm-simple-connection.c' || echo '$(srcdir)/'`libnm-core/nm-simple-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-simple-connection.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-simple-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-simple-connection.c' object='libnm-core/libnm_core_la-nm-simple-connection.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dhcp/libNetworkManager_la-nm-dhcp-listener.lo: src/core/dhcp/nm-dhcp-listener.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManager_la-nm-dhcp-listener.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-listener.Tpo -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-listener.lo `test -f 'src/core/dhcp/nm-dhcp-listener.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-listener.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-listener.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-listener.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-listener.c' object='src/core/dhcp/libNetworkManager_la-nm-dhcp-listener.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-simple-connection.lo `test -f 'libnm-core/nm-simple-connection.c' || echo '$(srcdir)/'`libnm-core/nm-simple-connection.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-listener.lo `test -f 'src/core/dhcp/nm-dhcp-listener.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-listener.c -libnm-core/libnm_core_la-nm-team-utils.lo: libnm-core/nm-team-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-team-utils.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-team-utils.Tpo -c -o libnm-core/libnm_core_la-nm-team-utils.lo `test -f 'libnm-core/nm-team-utils.c' || echo '$(srcdir)/'`libnm-core/nm-team-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-team-utils.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-team-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-team-utils.c' object='libnm-core/libnm_core_la-nm-team-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient-utils.lo: src/core/dhcp/nm-dhcp-dhclient-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient-utils.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient-utils.Tpo -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient-utils.lo `test -f 'src/core/dhcp/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhclient-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient-utils.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-dhclient-utils.c' object='src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-team-utils.lo `test -f 'libnm-core/nm-team-utils.c' || echo '$(srcdir)/'`libnm-core/nm-team-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient-utils.lo `test -f 'src/core/dhcp/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhclient-utils.c -libnm-core/libnm_core_la-nm-utils.lo: libnm-core/nm-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-utils.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-utils.Tpo -c -o libnm-core/libnm_core_la-nm-utils.lo `test -f 'libnm-core/nm-utils.c' || echo '$(srcdir)/'`libnm-core/nm-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-utils.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-utils.c' object='libnm-core/libnm_core_la-nm-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dns/libNetworkManager_la-nm-dns-manager.lo: src/core/dns/nm-dns-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dns/libNetworkManager_la-nm-dns-manager.lo -MD -MP -MF src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-manager.Tpo -c -o src/core/dns/libNetworkManager_la-nm-dns-manager.lo `test -f 'src/core/dns/nm-dns-manager.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-manager.Tpo src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dns/nm-dns-manager.c' object='src/core/dns/libNetworkManager_la-nm-dns-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-utils.lo `test -f 'libnm-core/nm-utils.c' || echo '$(srcdir)/'`libnm-core/nm-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dns/libNetworkManager_la-nm-dns-manager.lo `test -f 'src/core/dns/nm-dns-manager.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-manager.c -libnm-core/libnm_core_la-nm-vpn-editor-plugin.lo: libnm-core/nm-vpn-editor-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-vpn-editor-plugin.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-editor-plugin.Tpo -c -o libnm-core/libnm_core_la-nm-vpn-editor-plugin.lo `test -f 'libnm-core/nm-vpn-editor-plugin.c' || echo '$(srcdir)/'`libnm-core/nm-vpn-editor-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-editor-plugin.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-editor-plugin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-vpn-editor-plugin.c' object='libnm-core/libnm_core_la-nm-vpn-editor-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dns/libNetworkManager_la-nm-dns-plugin.lo: src/core/dns/nm-dns-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dns/libNetworkManager_la-nm-dns-plugin.lo -MD -MP -MF src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-plugin.Tpo -c -o src/core/dns/libNetworkManager_la-nm-dns-plugin.lo `test -f 'src/core/dns/nm-dns-plugin.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-plugin.Tpo src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dns/nm-dns-plugin.c' object='src/core/dns/libNetworkManager_la-nm-dns-plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-vpn-editor-plugin.lo `test -f 'libnm-core/nm-vpn-editor-plugin.c' || echo '$(srcdir)/'`libnm-core/nm-vpn-editor-plugin.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dns/libNetworkManager_la-nm-dns-plugin.lo `test -f 'src/core/dns/nm-dns-plugin.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-plugin.c -libnm-core/libnm_core_la-nm-vpn-plugin-info.lo: libnm-core/nm-vpn-plugin-info.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-vpn-plugin-info.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-plugin-info.Tpo -c -o libnm-core/libnm_core_la-nm-vpn-plugin-info.lo `test -f 'libnm-core/nm-vpn-plugin-info.c' || echo '$(srcdir)/'`libnm-core/nm-vpn-plugin-info.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-plugin-info.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-plugin-info.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-vpn-plugin-info.c' object='libnm-core/libnm_core_la-nm-vpn-plugin-info.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dns/libNetworkManager_la-nm-dns-dnsmasq.lo: src/core/dns/nm-dns-dnsmasq.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dns/libNetworkManager_la-nm-dns-dnsmasq.lo -MD -MP -MF src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-dnsmasq.Tpo -c -o src/core/dns/libNetworkManager_la-nm-dns-dnsmasq.lo `test -f 'src/core/dns/nm-dns-dnsmasq.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-dnsmasq.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-dnsmasq.Tpo src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-dnsmasq.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dns/nm-dns-dnsmasq.c' object='src/core/dns/libNetworkManager_la-nm-dns-dnsmasq.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-vpn-plugin-info.lo `test -f 'libnm-core/nm-vpn-plugin-info.c' || echo '$(srcdir)/'`libnm-core/nm-vpn-plugin-info.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dns/libNetworkManager_la-nm-dns-dnsmasq.lo `test -f 'src/core/dns/nm-dns-dnsmasq.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-dnsmasq.c -libnm-core/libnm_core_la-nm-core-enum-types.lo: libnm-core/nm-core-enum-types.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_core_la-nm-core-enum-types.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_core_la-nm-core-enum-types.Tpo -c -o libnm-core/libnm_core_la-nm-core-enum-types.lo `test -f 'libnm-core/nm-core-enum-types.c' || echo '$(srcdir)/'`libnm-core/nm-core-enum-types.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_core_la-nm-core-enum-types.Tpo libnm-core/$(DEPDIR)/libnm_core_la-nm-core-enum-types.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-core-enum-types.c' object='libnm-core/libnm_core_la-nm-core-enum-types.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dns/libNetworkManager_la-nm-dns-systemd-resolved.lo: src/core/dns/nm-dns-systemd-resolved.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dns/libNetworkManager_la-nm-dns-systemd-resolved.lo -MD -MP -MF src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-systemd-resolved.Tpo -c -o src/core/dns/libNetworkManager_la-nm-dns-systemd-resolved.lo `test -f 'src/core/dns/nm-dns-systemd-resolved.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-systemd-resolved.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-systemd-resolved.Tpo src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-systemd-resolved.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dns/nm-dns-systemd-resolved.c' object='src/core/dns/libNetworkManager_la-nm-dns-systemd-resolved.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_core_la-nm-core-enum-types.lo `test -f 'libnm-core/nm-core-enum-types.c' || echo '$(srcdir)/'`libnm-core/nm-core-enum-types.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dns/libNetworkManager_la-nm-dns-systemd-resolved.lo `test -f 'src/core/dns/nm-dns-systemd-resolved.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-systemd-resolved.c -libnm-core/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo: libnm-core/nm-crypto-gnutls.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_crypto_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Tpo -c -o libnm-core/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo `test -f 'libnm-core/nm-crypto-gnutls.c' || echo '$(srcdir)/'`libnm-core/nm-crypto-gnutls.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Tpo libnm-core/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-crypto-gnutls.c' object='libnm-core/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dns/libNetworkManager_la-nm-dns-unbound.lo: src/core/dns/nm-dns-unbound.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dns/libNetworkManager_la-nm-dns-unbound.lo -MD -MP -MF src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-unbound.Tpo -c -o src/core/dns/libNetworkManager_la-nm-dns-unbound.lo `test -f 'src/core/dns/nm-dns-unbound.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-unbound.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-unbound.Tpo src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-unbound.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dns/nm-dns-unbound.c' object='src/core/dns/libNetworkManager_la-nm-dns-unbound.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_crypto_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo `test -f 'libnm-core/nm-crypto-gnutls.c' || echo '$(srcdir)/'`libnm-core/nm-crypto-gnutls.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dns/libNetworkManager_la-nm-dns-unbound.lo `test -f 'src/core/dns/nm-dns-unbound.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-unbound.c -libnm-core/libnm_crypto_nss_la-nm-crypto-nss.lo: libnm-core/nm-crypto-nss.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_crypto_nss_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/libnm_crypto_nss_la-nm-crypto-nss.lo -MD -MP -MF libnm-core/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Tpo -c -o libnm-core/libnm_crypto_nss_la-nm-crypto-nss.lo `test -f 'libnm-core/nm-crypto-nss.c' || echo '$(srcdir)/'`libnm-core/nm-crypto-nss.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Tpo libnm-core/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-crypto-nss.c' object='libnm-core/libnm_crypto_nss_la-nm-crypto-nss.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-manager.lo: src/core/dnsmasq/nm-dnsmasq-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-manager.lo -MD -MP -MF src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-manager.Tpo -c -o src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-manager.lo `test -f 'src/core/dnsmasq/nm-dnsmasq-manager.c' || echo '$(srcdir)/'`src/core/dnsmasq/nm-dnsmasq-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-manager.Tpo src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dnsmasq/nm-dnsmasq-manager.c' object='src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_libnm_crypto_nss_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/libnm_crypto_nss_la-nm-crypto-nss.lo `test -f 'libnm-core/nm-crypto-nss.c' || echo '$(srcdir)/'`libnm-core/nm-crypto-nss.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-manager.lo `test -f 'src/core/dnsmasq/nm-dnsmasq-manager.c' || echo '$(srcdir)/'`src/core/dnsmasq/nm-dnsmasq-manager.c -libnm-core/nm-libnm-core-aux/libnm_libnm_core_aux_la-nm-libnm-core-aux.lo: libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/nm-libnm-core-aux/libnm_libnm_core_aux_la-nm-libnm-core-aux.lo -MD -MP -MF libnm-core/nm-libnm-core-aux/$(DEPDIR)/libnm_libnm_core_aux_la-nm-libnm-core-aux.Tpo -c -o libnm-core/nm-libnm-core-aux/libnm_libnm_core_aux_la-nm-libnm-core-aux.lo `test -f 'libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c' || echo '$(srcdir)/'`libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/nm-libnm-core-aux/$(DEPDIR)/libnm_libnm_core_aux_la-nm-libnm-core-aux.Tpo libnm-core/nm-libnm-core-aux/$(DEPDIR)/libnm_libnm_core_aux_la-nm-libnm-core-aux.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c' object='libnm-core/nm-libnm-core-aux/libnm_libnm_core_aux_la-nm-libnm-core-aux.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-utils.lo: src/core/dnsmasq/nm-dnsmasq-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-utils.lo -MD -MP -MF src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-utils.Tpo -c -o src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-utils.lo `test -f 'src/core/dnsmasq/nm-dnsmasq-utils.c' || echo '$(srcdir)/'`src/core/dnsmasq/nm-dnsmasq-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-utils.Tpo src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dnsmasq/nm-dnsmasq-utils.c' object='src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/nm-libnm-core-aux/libnm_libnm_core_aux_la-nm-libnm-core-aux.lo `test -f 'libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c' || echo '$(srcdir)/'`libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-utils.lo `test -f 'src/core/dnsmasq/nm-dnsmasq-utils.c' || echo '$(srcdir)/'`src/core/dnsmasq/nm-dnsmasq-utils.c -libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-auth-subject.lo: libnm-core/nm-libnm-core-intern/nm-auth-subject.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-auth-subject.lo -MD -MP -MF libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-auth-subject.Tpo -c -o libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-auth-subject.lo `test -f 'libnm-core/nm-libnm-core-intern/nm-auth-subject.c' || echo '$(srcdir)/'`libnm-core/nm-libnm-core-intern/nm-auth-subject.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-auth-subject.Tpo libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-auth-subject.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-libnm-core-intern/nm-auth-subject.c' object='libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-auth-subject.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/ppp/libNetworkManager_la-nm-ppp-manager-call.lo: src/core/ppp/nm-ppp-manager-call.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ppp/libNetworkManager_la-nm-ppp-manager-call.lo -MD -MP -MF src/core/ppp/$(DEPDIR)/libNetworkManager_la-nm-ppp-manager-call.Tpo -c -o src/core/ppp/libNetworkManager_la-nm-ppp-manager-call.lo `test -f 'src/core/ppp/nm-ppp-manager-call.c' || echo '$(srcdir)/'`src/core/ppp/nm-ppp-manager-call.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ppp/$(DEPDIR)/libNetworkManager_la-nm-ppp-manager-call.Tpo src/core/ppp/$(DEPDIR)/libNetworkManager_la-nm-ppp-manager-call.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ppp/nm-ppp-manager-call.c' object='src/core/ppp/libNetworkManager_la-nm-ppp-manager-call.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-auth-subject.lo `test -f 'libnm-core/nm-libnm-core-intern/nm-auth-subject.c' || echo '$(srcdir)/'`libnm-core/nm-libnm-core-intern/nm-auth-subject.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ppp/libNetworkManager_la-nm-ppp-manager-call.lo `test -f 'src/core/ppp/nm-ppp-manager-call.c' || echo '$(srcdir)/'`src/core/ppp/nm-ppp-manager-call.c -libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-libnm-core-utils.lo: libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-libnm-core-utils.lo -MD -MP -MF libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-libnm-core-utils.Tpo -c -o libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-libnm-core-utils.lo `test -f 'libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c' || echo '$(srcdir)/'`libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-libnm-core-utils.Tpo libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-libnm-core-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c' object='libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-libnm-core-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-hostname-manager.lo: src/core/nm-hostname-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-hostname-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-hostname-manager.Tpo -c -o src/core/libNetworkManager_la-nm-hostname-manager.lo `test -f 'src/core/nm-hostname-manager.c' || echo '$(srcdir)/'`src/core/nm-hostname-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-hostname-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-hostname-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-hostname-manager.c' object='src/core/libNetworkManager_la-nm-hostname-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/nm-libnm-core-intern/libnm_libnm_core_intern_la-nm-libnm-core-utils.lo `test -f 'libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c' || echo '$(srcdir)/'`libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-hostname-manager.lo `test -f 'src/core/nm-hostname-manager.c' || echo '$(srcdir)/'`src/core/nm-hostname-manager.c -libnm/libnm_static_la-nm-client.lo: libnm/nm-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-client.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-client.Tpo -c -o libnm/libnm_static_la-nm-client.lo `test -f 'libnm/nm-client.c' || echo '$(srcdir)/'`libnm/nm-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-client.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-client.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-client.c' object='libnm/libnm_static_la-nm-client.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/libNetworkManager_la-nm-agent-manager.lo: src/core/settings/nm-agent-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-agent-manager.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-agent-manager.Tpo -c -o src/core/settings/libNetworkManager_la-nm-agent-manager.lo `test -f 'src/core/settings/nm-agent-manager.c' || echo '$(srcdir)/'`src/core/settings/nm-agent-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-agent-manager.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-agent-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-agent-manager.c' object='src/core/settings/libNetworkManager_la-nm-agent-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-client.lo `test -f 'libnm/nm-client.c' || echo '$(srcdir)/'`libnm/nm-client.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-agent-manager.lo `test -f 'src/core/settings/nm-agent-manager.c' || echo '$(srcdir)/'`src/core/settings/nm-agent-manager.c -libnm/libnm_static_la-nm-object.lo: libnm/nm-object.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-object.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-object.Tpo -c -o libnm/libnm_static_la-nm-object.lo `test -f 'libnm/nm-object.c' || echo '$(srcdir)/'`libnm/nm-object.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-object.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-object.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-object.c' object='libnm/libnm_static_la-nm-object.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/libNetworkManager_la-nm-secret-agent.lo: src/core/settings/nm-secret-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-secret-agent.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-secret-agent.Tpo -c -o src/core/settings/libNetworkManager_la-nm-secret-agent.lo `test -f 'src/core/settings/nm-secret-agent.c' || echo '$(srcdir)/'`src/core/settings/nm-secret-agent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-secret-agent.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-secret-agent.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-secret-agent.c' object='src/core/settings/libNetworkManager_la-nm-secret-agent.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-object.lo `test -f 'libnm/nm-object.c' || echo '$(srcdir)/'`libnm/nm-object.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-secret-agent.lo `test -f 'src/core/settings/nm-secret-agent.c' || echo '$(srcdir)/'`src/core/settings/nm-secret-agent.c -libnm/libnm_static_la-nm-device.lo: libnm/nm-device.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device.Tpo -c -o libnm/libnm_static_la-nm-device.lo `test -f 'libnm/nm-device.c' || echo '$(srcdir)/'`libnm/nm-device.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device.c' object='libnm/libnm_static_la-nm-device.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/libNetworkManager_la-nm-settings-connection.lo: src/core/settings/nm-settings-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-settings-connection.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-connection.Tpo -c -o src/core/settings/libNetworkManager_la-nm-settings-connection.lo `test -f 'src/core/settings/nm-settings-connection.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-connection.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-settings-connection.c' object='src/core/settings/libNetworkManager_la-nm-settings-connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device.lo `test -f 'libnm/nm-device.c' || echo '$(srcdir)/'`libnm/nm-device.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-settings-connection.lo `test -f 'src/core/settings/nm-settings-connection.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-connection.c -libnm/libnm_static_la-nm-active-connection.lo: libnm/nm-active-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-active-connection.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-active-connection.Tpo -c -o libnm/libnm_static_la-nm-active-connection.lo `test -f 'libnm/nm-active-connection.c' || echo '$(srcdir)/'`libnm/nm-active-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-active-connection.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-active-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-active-connection.c' object='libnm/libnm_static_la-nm-active-connection.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/libNetworkManager_la-nm-settings-storage.lo: src/core/settings/nm-settings-storage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-settings-storage.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-storage.Tpo -c -o src/core/settings/libNetworkManager_la-nm-settings-storage.lo `test -f 'src/core/settings/nm-settings-storage.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-storage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-storage.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-storage.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-settings-storage.c' object='src/core/settings/libNetworkManager_la-nm-settings-storage.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-active-connection.lo `test -f 'libnm/nm-active-connection.c' || echo '$(srcdir)/'`libnm/nm-active-connection.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-settings-storage.lo `test -f 'src/core/settings/nm-settings-storage.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-storage.c -libnm/libnm_static_la-nm-access-point.lo: libnm/nm-access-point.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-access-point.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-access-point.Tpo -c -o libnm/libnm_static_la-nm-access-point.lo `test -f 'libnm/nm-access-point.c' || echo '$(srcdir)/'`libnm/nm-access-point.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-access-point.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-access-point.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-access-point.c' object='libnm/libnm_static_la-nm-access-point.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/libNetworkManager_la-nm-settings-plugin.lo: src/core/settings/nm-settings-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-settings-plugin.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-plugin.Tpo -c -o src/core/settings/libNetworkManager_la-nm-settings-plugin.lo `test -f 'src/core/settings/nm-settings-plugin.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-plugin.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-settings-plugin.c' object='src/core/settings/libNetworkManager_la-nm-settings-plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-access-point.lo `test -f 'libnm/nm-access-point.c' || echo '$(srcdir)/'`libnm/nm-access-point.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-settings-plugin.lo `test -f 'src/core/settings/nm-settings-plugin.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-plugin.c -libnm/libnm_static_la-nm-checkpoint.lo: libnm/nm-checkpoint.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-checkpoint.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-checkpoint.Tpo -c -o libnm/libnm_static_la-nm-checkpoint.lo `test -f 'libnm/nm-checkpoint.c' || echo '$(srcdir)/'`libnm/nm-checkpoint.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-checkpoint.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-checkpoint.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-checkpoint.c' object='libnm/libnm_static_la-nm-checkpoint.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/libNetworkManager_la-nm-settings.lo: src/core/settings/nm-settings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-settings.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings.Tpo -c -o src/core/settings/libNetworkManager_la-nm-settings.lo `test -f 'src/core/settings/nm-settings.c' || echo '$(srcdir)/'`src/core/settings/nm-settings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-settings.c' object='src/core/settings/libNetworkManager_la-nm-settings.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-checkpoint.lo `test -f 'libnm/nm-checkpoint.c' || echo '$(srcdir)/'`libnm/nm-checkpoint.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-settings.lo `test -f 'src/core/settings/nm-settings.c' || echo '$(srcdir)/'`src/core/settings/nm-settings.c -libnm/libnm_static_la-nm-dbus-helpers.lo: libnm/nm-dbus-helpers.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-dbus-helpers.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-dbus-helpers.Tpo -c -o libnm/libnm_static_la-nm-dbus-helpers.lo `test -f 'libnm/nm-dbus-helpers.c' || echo '$(srcdir)/'`libnm/nm-dbus-helpers.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-dbus-helpers.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-dbus-helpers.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-dbus-helpers.c' object='libnm/libnm_static_la-nm-dbus-helpers.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/libNetworkManager_la-nm-settings-utils.lo: src/core/settings/nm-settings-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-settings-utils.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-utils.Tpo -c -o src/core/settings/libNetworkManager_la-nm-settings-utils.lo `test -f 'src/core/settings/nm-settings-utils.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-utils.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-settings-utils.c' object='src/core/settings/libNetworkManager_la-nm-settings-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-dbus-helpers.lo `test -f 'libnm/nm-dbus-helpers.c' || echo '$(srcdir)/'`libnm/nm-dbus-helpers.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-settings-utils.lo `test -f 'src/core/settings/nm-settings-utils.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-utils.c -libnm/libnm_static_la-nm-device-6lowpan.lo: libnm/nm-device-6lowpan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-6lowpan.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-6lowpan.Tpo -c -o libnm/libnm_static_la-nm-device-6lowpan.lo `test -f 'libnm/nm-device-6lowpan.c' || echo '$(srcdir)/'`libnm/nm-device-6lowpan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-6lowpan.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-6lowpan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-6lowpan.c' object='libnm/libnm_static_la-nm-device-6lowpan.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-storage.lo: src/core/settings/plugins/keyfile/nms-keyfile-storage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-storage.lo -MD -MP -MF src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-storage.Tpo -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-storage.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-storage.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-storage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-storage.Tpo src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-storage.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/nms-keyfile-storage.c' object='src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-storage.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-6lowpan.lo `test -f 'libnm/nm-device-6lowpan.c' || echo '$(srcdir)/'`libnm/nm-device-6lowpan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-storage.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-storage.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-storage.c -libnm/libnm_static_la-nm-device-adsl.lo: libnm/nm-device-adsl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-adsl.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-adsl.Tpo -c -o libnm/libnm_static_la-nm-device-adsl.lo `test -f 'libnm/nm-device-adsl.c' || echo '$(srcdir)/'`libnm/nm-device-adsl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-adsl.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-adsl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-adsl.c' object='libnm/libnm_static_la-nm-device-adsl.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-plugin.lo: src/core/settings/plugins/keyfile/nms-keyfile-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-plugin.lo -MD -MP -MF src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-plugin.Tpo -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-plugin.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-plugin.Tpo src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/nms-keyfile-plugin.c' object='src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-adsl.lo `test -f 'libnm/nm-device-adsl.c' || echo '$(srcdir)/'`libnm/nm-device-adsl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-plugin.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-plugin.c -libnm/libnm_static_la-nm-device-bond.lo: libnm/nm-device-bond.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-bond.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-bond.Tpo -c -o libnm/libnm_static_la-nm-device-bond.lo `test -f 'libnm/nm-device-bond.c' || echo '$(srcdir)/'`libnm/nm-device-bond.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-bond.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-bond.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-bond.c' object='libnm/libnm_static_la-nm-device-bond.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-reader.lo: src/core/settings/plugins/keyfile/nms-keyfile-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-reader.lo -MD -MP -MF src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-reader.Tpo -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-reader.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-reader.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-reader.Tpo src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-reader.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/nms-keyfile-reader.c' object='src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-reader.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-bond.lo `test -f 'libnm/nm-device-bond.c' || echo '$(srcdir)/'`libnm/nm-device-bond.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-reader.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-reader.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-reader.c -libnm/libnm_static_la-nm-device-bridge.lo: libnm/nm-device-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-bridge.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-bridge.Tpo -c -o libnm/libnm_static_la-nm-device-bridge.lo `test -f 'libnm/nm-device-bridge.c' || echo '$(srcdir)/'`libnm/nm-device-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-bridge.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-bridge.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-bridge.c' object='libnm/libnm_static_la-nm-device-bridge.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-utils.lo: src/core/settings/plugins/keyfile/nms-keyfile-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-utils.lo -MD -MP -MF src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-utils.Tpo -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-utils.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-utils.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-utils.Tpo src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/nms-keyfile-utils.c' object='src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-bridge.lo `test -f 'libnm/nm-device-bridge.c' || echo '$(srcdir)/'`libnm/nm-device-bridge.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-utils.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-utils.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-utils.c -libnm/libnm_static_la-nm-device-bt.lo: libnm/nm-device-bt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-bt.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-bt.Tpo -c -o libnm/libnm_static_la-nm-device-bt.lo `test -f 'libnm/nm-device-bt.c' || echo '$(srcdir)/'`libnm/nm-device-bt.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-bt.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-bt.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-bt.c' object='libnm/libnm_static_la-nm-device-bt.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-writer.lo: src/core/settings/plugins/keyfile/nms-keyfile-writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-writer.lo -MD -MP -MF src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-writer.Tpo -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-writer.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-writer.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-writer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-writer.Tpo src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-writer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/nms-keyfile-writer.c' object='src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-writer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-bt.lo `test -f 'libnm/nm-device-bt.c' || echo '$(srcdir)/'`libnm/nm-device-bt.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-writer.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-writer.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-writer.c -libnm/libnm_static_la-nm-device-dummy.lo: libnm/nm-device-dummy.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-dummy.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-dummy.Tpo -c -o libnm/libnm_static_la-nm-device-dummy.lo `test -f 'libnm/nm-device-dummy.c' || echo '$(srcdir)/'`libnm/nm-device-dummy.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-dummy.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-dummy.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-dummy.c' object='libnm/libnm_static_la-nm-device-dummy.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/supplicant/libNetworkManager_la-nm-supplicant-config.lo: src/core/supplicant/nm-supplicant-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/libNetworkManager_la-nm-supplicant-config.lo -MD -MP -MF src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-config.Tpo -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-config.lo `test -f 'src/core/supplicant/nm-supplicant-config.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-config.Tpo src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/nm-supplicant-config.c' object='src/core/supplicant/libNetworkManager_la-nm-supplicant-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-dummy.lo `test -f 'libnm/nm-device-dummy.c' || echo '$(srcdir)/'`libnm/nm-device-dummy.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-config.lo `test -f 'src/core/supplicant/nm-supplicant-config.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-config.c -libnm/libnm_static_la-nm-device-ethernet.lo: libnm/nm-device-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-ethernet.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-ethernet.Tpo -c -o libnm/libnm_static_la-nm-device-ethernet.lo `test -f 'libnm/nm-device-ethernet.c' || echo '$(srcdir)/'`libnm/nm-device-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-ethernet.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-ethernet.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-ethernet.c' object='libnm/libnm_static_la-nm-device-ethernet.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/supplicant/libNetworkManager_la-nm-supplicant-interface.lo: src/core/supplicant/nm-supplicant-interface.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/libNetworkManager_la-nm-supplicant-interface.lo -MD -MP -MF src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-interface.Tpo -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-interface.lo `test -f 'src/core/supplicant/nm-supplicant-interface.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-interface.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-interface.Tpo src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-interface.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/nm-supplicant-interface.c' object='src/core/supplicant/libNetworkManager_la-nm-supplicant-interface.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-ethernet.lo `test -f 'libnm/nm-device-ethernet.c' || echo '$(srcdir)/'`libnm/nm-device-ethernet.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-interface.lo `test -f 'src/core/supplicant/nm-supplicant-interface.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-interface.c -libnm/libnm_static_la-nm-device-generic.lo: libnm/nm-device-generic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-generic.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-generic.Tpo -c -o libnm/libnm_static_la-nm-device-generic.lo `test -f 'libnm/nm-device-generic.c' || echo '$(srcdir)/'`libnm/nm-device-generic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-generic.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-generic.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-generic.c' object='libnm/libnm_static_la-nm-device-generic.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/supplicant/libNetworkManager_la-nm-supplicant-manager.lo: src/core/supplicant/nm-supplicant-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/libNetworkManager_la-nm-supplicant-manager.lo -MD -MP -MF src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-manager.Tpo -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-manager.lo `test -f 'src/core/supplicant/nm-supplicant-manager.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-manager.Tpo src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/nm-supplicant-manager.c' object='src/core/supplicant/libNetworkManager_la-nm-supplicant-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-generic.lo `test -f 'libnm/nm-device-generic.c' || echo '$(srcdir)/'`libnm/nm-device-generic.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-manager.lo `test -f 'src/core/supplicant/nm-supplicant-manager.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-manager.c -libnm/libnm_static_la-nm-device-infiniband.lo: libnm/nm-device-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-infiniband.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-infiniband.Tpo -c -o libnm/libnm_static_la-nm-device-infiniband.lo `test -f 'libnm/nm-device-infiniband.c' || echo '$(srcdir)/'`libnm/nm-device-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-infiniband.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-infiniband.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-infiniband.c' object='libnm/libnm_static_la-nm-device-infiniband.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/supplicant/libNetworkManager_la-nm-supplicant-settings-verify.lo: src/core/supplicant/nm-supplicant-settings-verify.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/libNetworkManager_la-nm-supplicant-settings-verify.lo -MD -MP -MF src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-settings-verify.Tpo -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-settings-verify.lo `test -f 'src/core/supplicant/nm-supplicant-settings-verify.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-settings-verify.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-settings-verify.Tpo src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-settings-verify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/nm-supplicant-settings-verify.c' object='src/core/supplicant/libNetworkManager_la-nm-supplicant-settings-verify.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-infiniband.lo `test -f 'libnm/nm-device-infiniband.c' || echo '$(srcdir)/'`libnm/nm-device-infiniband.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-settings-verify.lo `test -f 'src/core/supplicant/nm-supplicant-settings-verify.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-settings-verify.c -libnm/libnm_static_la-nm-device-ip-tunnel.lo: libnm/nm-device-ip-tunnel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-ip-tunnel.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-ip-tunnel.Tpo -c -o libnm/libnm_static_la-nm-device-ip-tunnel.lo `test -f 'libnm/nm-device-ip-tunnel.c' || echo '$(srcdir)/'`libnm/nm-device-ip-tunnel.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-ip-tunnel.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-ip-tunnel.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-ip-tunnel.c' object='libnm/libnm_static_la-nm-device-ip-tunnel.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/vpn/libNetworkManager_la-nm-vpn-connection.lo: src/core/vpn/nm-vpn-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/vpn/libNetworkManager_la-nm-vpn-connection.lo -MD -MP -MF src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-connection.Tpo -c -o src/core/vpn/libNetworkManager_la-nm-vpn-connection.lo `test -f 'src/core/vpn/nm-vpn-connection.c' || echo '$(srcdir)/'`src/core/vpn/nm-vpn-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-connection.Tpo src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/vpn/nm-vpn-connection.c' object='src/core/vpn/libNetworkManager_la-nm-vpn-connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-ip-tunnel.lo `test -f 'libnm/nm-device-ip-tunnel.c' || echo '$(srcdir)/'`libnm/nm-device-ip-tunnel.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/vpn/libNetworkManager_la-nm-vpn-connection.lo `test -f 'src/core/vpn/nm-vpn-connection.c' || echo '$(srcdir)/'`src/core/vpn/nm-vpn-connection.c -libnm/libnm_static_la-nm-device-macsec.lo: libnm/nm-device-macsec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-macsec.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-macsec.Tpo -c -o libnm/libnm_static_la-nm-device-macsec.lo `test -f 'libnm/nm-device-macsec.c' || echo '$(srcdir)/'`libnm/nm-device-macsec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-macsec.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-macsec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-macsec.c' object='libnm/libnm_static_la-nm-device-macsec.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/vpn/libNetworkManager_la-nm-vpn-manager.lo: src/core/vpn/nm-vpn-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/vpn/libNetworkManager_la-nm-vpn-manager.lo -MD -MP -MF src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Tpo -c -o src/core/vpn/libNetworkManager_la-nm-vpn-manager.lo `test -f 'src/core/vpn/nm-vpn-manager.c' || echo '$(srcdir)/'`src/core/vpn/nm-vpn-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Tpo src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/vpn/nm-vpn-manager.c' object='src/core/vpn/libNetworkManager_la-nm-vpn-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-macsec.lo `test -f 'libnm/nm-device-macsec.c' || echo '$(srcdir)/'`libnm/nm-device-macsec.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/vpn/libNetworkManager_la-nm-vpn-manager.lo `test -f 'src/core/vpn/nm-vpn-manager.c' || echo '$(srcdir)/'`src/core/vpn/nm-vpn-manager.c -libnm/libnm_static_la-nm-device-macvlan.lo: libnm/nm-device-macvlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-macvlan.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-macvlan.Tpo -c -o libnm/libnm_static_la-nm-device-macvlan.lo `test -f 'libnm/nm-device-macvlan.c' || echo '$(srcdir)/'`libnm/nm-device-macvlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-macvlan.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-macvlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-macvlan.c' object='libnm/libnm_static_la-nm-device-macvlan.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-act-request.lo: src/core/nm-act-request.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-act-request.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-act-request.Tpo -c -o src/core/libNetworkManager_la-nm-act-request.lo `test -f 'src/core/nm-act-request.c' || echo '$(srcdir)/'`src/core/nm-act-request.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-act-request.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-act-request.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-act-request.c' object='src/core/libNetworkManager_la-nm-act-request.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-macvlan.lo `test -f 'libnm/nm-device-macvlan.c' || echo '$(srcdir)/'`libnm/nm-device-macvlan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-act-request.lo `test -f 'src/core/nm-act-request.c' || echo '$(srcdir)/'`src/core/nm-act-request.c -libnm/libnm_static_la-nm-device-modem.lo: libnm/nm-device-modem.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-modem.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-modem.Tpo -c -o libnm/libnm_static_la-nm-device-modem.lo `test -f 'libnm/nm-device-modem.c' || echo '$(srcdir)/'`libnm/nm-device-modem.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-modem.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-modem.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-modem.c' object='libnm/libnm_static_la-nm-device-modem.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-active-connection.lo: src/core/nm-active-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-active-connection.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-active-connection.Tpo -c -o src/core/libNetworkManager_la-nm-active-connection.lo `test -f 'src/core/nm-active-connection.c' || echo '$(srcdir)/'`src/core/nm-active-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-active-connection.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-active-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-active-connection.c' object='src/core/libNetworkManager_la-nm-active-connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-modem.lo `test -f 'libnm/nm-device-modem.c' || echo '$(srcdir)/'`libnm/nm-device-modem.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-active-connection.lo `test -f 'src/core/nm-active-connection.c' || echo '$(srcdir)/'`src/core/nm-active-connection.c -libnm/libnm_static_la-nm-device-olpc-mesh.lo: libnm/nm-device-olpc-mesh.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-olpc-mesh.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-olpc-mesh.Tpo -c -o libnm/libnm_static_la-nm-device-olpc-mesh.lo `test -f 'libnm/nm-device-olpc-mesh.c' || echo '$(srcdir)/'`libnm/nm-device-olpc-mesh.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-olpc-mesh.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-olpc-mesh.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-olpc-mesh.c' object='libnm/libnm_static_la-nm-device-olpc-mesh.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-audit-manager.lo: src/core/nm-audit-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-audit-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-audit-manager.Tpo -c -o src/core/libNetworkManager_la-nm-audit-manager.lo `test -f 'src/core/nm-audit-manager.c' || echo '$(srcdir)/'`src/core/nm-audit-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-audit-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-audit-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-audit-manager.c' object='src/core/libNetworkManager_la-nm-audit-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-olpc-mesh.lo `test -f 'libnm/nm-device-olpc-mesh.c' || echo '$(srcdir)/'`libnm/nm-device-olpc-mesh.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-audit-manager.lo `test -f 'src/core/nm-audit-manager.c' || echo '$(srcdir)/'`src/core/nm-audit-manager.c -libnm/libnm_static_la-nm-device-ovs-bridge.lo: libnm/nm-device-ovs-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-ovs-bridge.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-bridge.Tpo -c -o libnm/libnm_static_la-nm-device-ovs-bridge.lo `test -f 'libnm/nm-device-ovs-bridge.c' || echo '$(srcdir)/'`libnm/nm-device-ovs-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-bridge.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-bridge.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-ovs-bridge.c' object='libnm/libnm_static_la-nm-device-ovs-bridge.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-dbus-manager.lo: src/core/nm-dbus-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-dbus-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-dbus-manager.Tpo -c -o src/core/libNetworkManager_la-nm-dbus-manager.lo `test -f 'src/core/nm-dbus-manager.c' || echo '$(srcdir)/'`src/core/nm-dbus-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-dbus-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-dbus-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dbus-manager.c' object='src/core/libNetworkManager_la-nm-dbus-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-ovs-bridge.lo `test -f 'libnm/nm-device-ovs-bridge.c' || echo '$(srcdir)/'`libnm/nm-device-ovs-bridge.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-dbus-manager.lo `test -f 'src/core/nm-dbus-manager.c' || echo '$(srcdir)/'`src/core/nm-dbus-manager.c -libnm/libnm_static_la-nm-device-ovs-interface.lo: libnm/nm-device-ovs-interface.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-ovs-interface.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-interface.Tpo -c -o libnm/libnm_static_la-nm-device-ovs-interface.lo `test -f 'libnm/nm-device-ovs-interface.c' || echo '$(srcdir)/'`libnm/nm-device-ovs-interface.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-interface.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-interface.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-ovs-interface.c' object='libnm/libnm_static_la-nm-device-ovs-interface.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-config.lo: src/core/nm-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-config.Tpo -c -o src/core/libNetworkManager_la-nm-config.lo `test -f 'src/core/nm-config.c' || echo '$(srcdir)/'`src/core/nm-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-config.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-config.c' object='src/core/libNetworkManager_la-nm-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-ovs-interface.lo `test -f 'libnm/nm-device-ovs-interface.c' || echo '$(srcdir)/'`libnm/nm-device-ovs-interface.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-config.lo `test -f 'src/core/nm-config.c' || echo '$(srcdir)/'`src/core/nm-config.c -libnm/libnm_static_la-nm-device-ovs-port.lo: libnm/nm-device-ovs-port.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-ovs-port.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-port.Tpo -c -o libnm/libnm_static_la-nm-device-ovs-port.lo `test -f 'libnm/nm-device-ovs-port.c' || echo '$(srcdir)/'`libnm/nm-device-ovs-port.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-port.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-port.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-ovs-port.c' object='libnm/libnm_static_la-nm-device-ovs-port.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-config-data.lo: src/core/nm-config-data.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-config-data.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-config-data.Tpo -c -o src/core/libNetworkManager_la-nm-config-data.lo `test -f 'src/core/nm-config-data.c' || echo '$(srcdir)/'`src/core/nm-config-data.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-config-data.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-config-data.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-config-data.c' object='src/core/libNetworkManager_la-nm-config-data.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-ovs-port.lo `test -f 'libnm/nm-device-ovs-port.c' || echo '$(srcdir)/'`libnm/nm-device-ovs-port.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-config-data.lo `test -f 'src/core/nm-config-data.c' || echo '$(srcdir)/'`src/core/nm-config-data.c -libnm/libnm_static_la-nm-device-ppp.lo: libnm/nm-device-ppp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-ppp.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-ppp.Tpo -c -o libnm/libnm_static_la-nm-device-ppp.lo `test -f 'libnm/nm-device-ppp.c' || echo '$(srcdir)/'`libnm/nm-device-ppp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-ppp.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-ppp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-ppp.c' object='libnm/libnm_static_la-nm-device-ppp.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-connectivity.lo: src/core/nm-connectivity.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-connectivity.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-connectivity.Tpo -c -o src/core/libNetworkManager_la-nm-connectivity.lo `test -f 'src/core/nm-connectivity.c' || echo '$(srcdir)/'`src/core/nm-connectivity.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-connectivity.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-connectivity.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-connectivity.c' object='src/core/libNetworkManager_la-nm-connectivity.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-ppp.lo `test -f 'libnm/nm-device-ppp.c' || echo '$(srcdir)/'`libnm/nm-device-ppp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-connectivity.lo `test -f 'src/core/nm-connectivity.c' || echo '$(srcdir)/'`src/core/nm-connectivity.c -libnm/libnm_static_la-nm-device-team.lo: libnm/nm-device-team.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-team.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-team.Tpo -c -o libnm/libnm_static_la-nm-device-team.lo `test -f 'libnm/nm-device-team.c' || echo '$(srcdir)/'`libnm/nm-device-team.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-team.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-team.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-team.c' object='libnm/libnm_static_la-nm-device-team.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-dcb.lo: src/core/nm-dcb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-dcb.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-dcb.Tpo -c -o src/core/libNetworkManager_la-nm-dcb.lo `test -f 'src/core/nm-dcb.c' || echo '$(srcdir)/'`src/core/nm-dcb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-dcb.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-dcb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dcb.c' object='src/core/libNetworkManager_la-nm-dcb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-team.lo `test -f 'libnm/nm-device-team.c' || echo '$(srcdir)/'`libnm/nm-device-team.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-dcb.lo `test -f 'src/core/nm-dcb.c' || echo '$(srcdir)/'`src/core/nm-dcb.c -libnm/libnm_static_la-nm-device-tun.lo: libnm/nm-device-tun.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-tun.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-tun.Tpo -c -o libnm/libnm_static_la-nm-device-tun.lo `test -f 'libnm/nm-device-tun.c' || echo '$(srcdir)/'`libnm/nm-device-tun.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-tun.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-tun.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-tun.c' object='libnm/libnm_static_la-nm-device-tun.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-dhcp-config.lo: src/core/nm-dhcp-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-dhcp-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-dhcp-config.Tpo -c -o src/core/libNetworkManager_la-nm-dhcp-config.lo `test -f 'src/core/nm-dhcp-config.c' || echo '$(srcdir)/'`src/core/nm-dhcp-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-dhcp-config.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-dhcp-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dhcp-config.c' object='src/core/libNetworkManager_la-nm-dhcp-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-tun.lo `test -f 'libnm/nm-device-tun.c' || echo '$(srcdir)/'`libnm/nm-device-tun.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-dhcp-config.lo `test -f 'src/core/nm-dhcp-config.c' || echo '$(srcdir)/'`src/core/nm-dhcp-config.c -libnm/libnm_static_la-nm-device-veth.lo: libnm/nm-device-veth.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-veth.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-veth.Tpo -c -o libnm/libnm_static_la-nm-device-veth.lo `test -f 'libnm/nm-device-veth.c' || echo '$(srcdir)/'`libnm/nm-device-veth.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-veth.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-veth.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-veth.c' object='libnm/libnm_static_la-nm-device-veth.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-dispatcher.lo: src/core/nm-dispatcher.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-dispatcher.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-dispatcher.Tpo -c -o src/core/libNetworkManager_la-nm-dispatcher.lo `test -f 'src/core/nm-dispatcher.c' || echo '$(srcdir)/'`src/core/nm-dispatcher.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-dispatcher.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-dispatcher.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dispatcher.c' object='src/core/libNetworkManager_la-nm-dispatcher.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-veth.lo `test -f 'libnm/nm-device-veth.c' || echo '$(srcdir)/'`libnm/nm-device-veth.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-dispatcher.lo `test -f 'src/core/nm-dispatcher.c' || echo '$(srcdir)/'`src/core/nm-dispatcher.c -libnm/libnm_static_la-nm-device-vlan.lo: libnm/nm-device-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-vlan.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-vlan.Tpo -c -o libnm/libnm_static_la-nm-device-vlan.lo `test -f 'libnm/nm-device-vlan.c' || echo '$(srcdir)/'`libnm/nm-device-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-vlan.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-vlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-vlan.c' object='libnm/libnm_static_la-nm-device-vlan.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-firewall-manager.lo: src/core/nm-firewall-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-firewall-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-firewall-manager.Tpo -c -o src/core/libNetworkManager_la-nm-firewall-manager.lo `test -f 'src/core/nm-firewall-manager.c' || echo '$(srcdir)/'`src/core/nm-firewall-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-firewall-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-firewall-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-firewall-manager.c' object='src/core/libNetworkManager_la-nm-firewall-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-vlan.lo `test -f 'libnm/nm-device-vlan.c' || echo '$(srcdir)/'`libnm/nm-device-vlan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-firewall-manager.lo `test -f 'src/core/nm-firewall-manager.c' || echo '$(srcdir)/'`src/core/nm-firewall-manager.c -libnm/libnm_static_la-nm-device-vrf.lo: libnm/nm-device-vrf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-vrf.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-vrf.Tpo -c -o libnm/libnm_static_la-nm-device-vrf.lo `test -f 'libnm/nm-device-vrf.c' || echo '$(srcdir)/'`libnm/nm-device-vrf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-vrf.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-vrf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-vrf.c' object='libnm/libnm_static_la-nm-device-vrf.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-proxy-config.lo: src/core/nm-proxy-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-proxy-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-proxy-config.Tpo -c -o src/core/libNetworkManager_la-nm-proxy-config.lo `test -f 'src/core/nm-proxy-config.c' || echo '$(srcdir)/'`src/core/nm-proxy-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-proxy-config.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-proxy-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-proxy-config.c' object='src/core/libNetworkManager_la-nm-proxy-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-vrf.lo `test -f 'libnm/nm-device-vrf.c' || echo '$(srcdir)/'`libnm/nm-device-vrf.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-proxy-config.lo `test -f 'src/core/nm-proxy-config.c' || echo '$(srcdir)/'`src/core/nm-proxy-config.c -libnm/libnm_static_la-nm-device-vxlan.lo: libnm/nm-device-vxlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-vxlan.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-vxlan.Tpo -c -o libnm/libnm_static_la-nm-device-vxlan.lo `test -f 'libnm/nm-device-vxlan.c' || echo '$(srcdir)/'`libnm/nm-device-vxlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-vxlan.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-vxlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-vxlan.c' object='libnm/libnm_static_la-nm-device-vxlan.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-auth-manager.lo: src/core/nm-auth-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-auth-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-manager.Tpo -c -o src/core/libNetworkManager_la-nm-auth-manager.lo `test -f 'src/core/nm-auth-manager.c' || echo '$(srcdir)/'`src/core/nm-auth-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-auth-manager.c' object='src/core/libNetworkManager_la-nm-auth-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-vxlan.lo `test -f 'libnm/nm-device-vxlan.c' || echo '$(srcdir)/'`libnm/nm-device-vxlan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-auth-manager.lo `test -f 'src/core/nm-auth-manager.c' || echo '$(srcdir)/'`src/core/nm-auth-manager.c -libnm/libnm_static_la-nm-device-wifi-p2p.lo: libnm/nm-device-wifi-p2p.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-wifi-p2p.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi-p2p.Tpo -c -o libnm/libnm_static_la-nm-device-wifi-p2p.lo `test -f 'libnm/nm-device-wifi-p2p.c' || echo '$(srcdir)/'`libnm/nm-device-wifi-p2p.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi-p2p.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi-p2p.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-wifi-p2p.c' object='libnm/libnm_static_la-nm-device-wifi-p2p.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-auth-utils.lo: src/core/nm-auth-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-auth-utils.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-utils.Tpo -c -o src/core/libNetworkManager_la-nm-auth-utils.lo `test -f 'src/core/nm-auth-utils.c' || echo '$(srcdir)/'`src/core/nm-auth-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-utils.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-auth-utils.c' object='src/core/libNetworkManager_la-nm-auth-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-wifi-p2p.lo `test -f 'libnm/nm-device-wifi-p2p.c' || echo '$(srcdir)/'`libnm/nm-device-wifi-p2p.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-auth-utils.lo `test -f 'src/core/nm-auth-utils.c' || echo '$(srcdir)/'`src/core/nm-auth-utils.c -libnm/libnm_static_la-nm-device-wifi.lo: libnm/nm-device-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-wifi.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi.Tpo -c -o libnm/libnm_static_la-nm-device-wifi.lo `test -f 'libnm/nm-device-wifi.c' || echo '$(srcdir)/'`libnm/nm-device-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-wifi.c' object='libnm/libnm_static_la-nm-device-wifi.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-manager.lo: src/core/nm-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-manager.Tpo -c -o src/core/libNetworkManager_la-nm-manager.lo `test -f 'src/core/nm-manager.c' || echo '$(srcdir)/'`src/core/nm-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-manager.c' object='src/core/libNetworkManager_la-nm-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-wifi.lo `test -f 'libnm/nm-device-wifi.c' || echo '$(srcdir)/'`libnm/nm-device-wifi.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-manager.lo `test -f 'src/core/nm-manager.c' || echo '$(srcdir)/'`src/core/nm-manager.c -libnm/libnm_static_la-nm-device-wimax.lo: libnm/nm-device-wimax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-wimax.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-wimax.Tpo -c -o libnm/libnm_static_la-nm-device-wimax.lo `test -f 'libnm/nm-device-wimax.c' || echo '$(srcdir)/'`libnm/nm-device-wimax.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-wimax.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-wimax.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-wimax.c' object='libnm/libnm_static_la-nm-device-wimax.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-pacrunner-manager.lo: src/core/nm-pacrunner-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-pacrunner-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-pacrunner-manager.Tpo -c -o src/core/libNetworkManager_la-nm-pacrunner-manager.lo `test -f 'src/core/nm-pacrunner-manager.c' || echo '$(srcdir)/'`src/core/nm-pacrunner-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-pacrunner-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-pacrunner-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-pacrunner-manager.c' object='src/core/libNetworkManager_la-nm-pacrunner-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-wimax.lo `test -f 'libnm/nm-device-wimax.c' || echo '$(srcdir)/'`libnm/nm-device-wimax.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-pacrunner-manager.lo `test -f 'src/core/nm-pacrunner-manager.c' || echo '$(srcdir)/'`src/core/nm-pacrunner-manager.c -libnm/libnm_static_la-nm-device-wireguard.lo: libnm/nm-device-wireguard.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-wireguard.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-wireguard.Tpo -c -o libnm/libnm_static_la-nm-device-wireguard.lo `test -f 'libnm/nm-device-wireguard.c' || echo '$(srcdir)/'`libnm/nm-device-wireguard.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-wireguard.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-wireguard.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-wireguard.c' object='libnm/libnm_static_la-nm-device-wireguard.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-policy.lo: src/core/nm-policy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-policy.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-policy.Tpo -c -o src/core/libNetworkManager_la-nm-policy.lo `test -f 'src/core/nm-policy.c' || echo '$(srcdir)/'`src/core/nm-policy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-policy.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-policy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-policy.c' object='src/core/libNetworkManager_la-nm-policy.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-wireguard.lo `test -f 'libnm/nm-device-wireguard.c' || echo '$(srcdir)/'`libnm/nm-device-wireguard.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-policy.lo `test -f 'src/core/nm-policy.c' || echo '$(srcdir)/'`src/core/nm-policy.c -libnm/libnm_static_la-nm-device-wpan.lo: libnm/nm-device-wpan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-device-wpan.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-device-wpan.Tpo -c -o libnm/libnm_static_la-nm-device-wpan.lo `test -f 'libnm/nm-device-wpan.c' || echo '$(srcdir)/'`libnm/nm-device-wpan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-device-wpan.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-device-wpan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-device-wpan.c' object='libnm/libnm_static_la-nm-device-wpan.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-rfkill-manager.lo: src/core/nm-rfkill-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-rfkill-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-rfkill-manager.Tpo -c -o src/core/libNetworkManager_la-nm-rfkill-manager.lo `test -f 'src/core/nm-rfkill-manager.c' || echo '$(srcdir)/'`src/core/nm-rfkill-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-rfkill-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-rfkill-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-rfkill-manager.c' object='src/core/libNetworkManager_la-nm-rfkill-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-device-wpan.lo `test -f 'libnm/nm-device-wpan.c' || echo '$(srcdir)/'`libnm/nm-device-wpan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-rfkill-manager.lo `test -f 'src/core/nm-rfkill-manager.c' || echo '$(srcdir)/'`src/core/nm-rfkill-manager.c -libnm/libnm_static_la-nm-dhcp-config.lo: libnm/nm-dhcp-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-dhcp-config.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-dhcp-config.Tpo -c -o libnm/libnm_static_la-nm-dhcp-config.lo `test -f 'libnm/nm-dhcp-config.c' || echo '$(srcdir)/'`libnm/nm-dhcp-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-dhcp-config.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-dhcp-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-dhcp-config.c' object='libnm/libnm_static_la-nm-dhcp-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-session-monitor.lo: src/core/nm-session-monitor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-session-monitor.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-session-monitor.Tpo -c -o src/core/libNetworkManager_la-nm-session-monitor.lo `test -f 'src/core/nm-session-monitor.c' || echo '$(srcdir)/'`src/core/nm-session-monitor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-session-monitor.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-session-monitor.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-session-monitor.c' object='src/core/libNetworkManager_la-nm-session-monitor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-dhcp-config.lo `test -f 'libnm/nm-dhcp-config.c' || echo '$(srcdir)/'`libnm/nm-dhcp-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-session-monitor.lo `test -f 'src/core/nm-session-monitor.c' || echo '$(srcdir)/'`src/core/nm-session-monitor.c -libnm/libnm_static_la-nm-dhcp4-config.lo: libnm/nm-dhcp4-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-dhcp4-config.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-dhcp4-config.Tpo -c -o libnm/libnm_static_la-nm-dhcp4-config.lo `test -f 'libnm/nm-dhcp4-config.c' || echo '$(srcdir)/'`libnm/nm-dhcp4-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-dhcp4-config.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-dhcp4-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-dhcp4-config.c' object='libnm/libnm_static_la-nm-dhcp4-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-keep-alive.lo: src/core/nm-keep-alive.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-keep-alive.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-keep-alive.Tpo -c -o src/core/libNetworkManager_la-nm-keep-alive.lo `test -f 'src/core/nm-keep-alive.c' || echo '$(srcdir)/'`src/core/nm-keep-alive.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-keep-alive.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-keep-alive.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-keep-alive.c' object='src/core/libNetworkManager_la-nm-keep-alive.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-dhcp4-config.lo `test -f 'libnm/nm-dhcp4-config.c' || echo '$(srcdir)/'`libnm/nm-dhcp4-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-keep-alive.lo `test -f 'src/core/nm-keep-alive.c' || echo '$(srcdir)/'`src/core/nm-keep-alive.c -libnm/libnm_static_la-nm-dhcp6-config.lo: libnm/nm-dhcp6-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-dhcp6-config.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-dhcp6-config.Tpo -c -o libnm/libnm_static_la-nm-dhcp6-config.lo `test -f 'libnm/nm-dhcp6-config.c' || echo '$(srcdir)/'`libnm/nm-dhcp6-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-dhcp6-config.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-dhcp6-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-dhcp6-config.c' object='libnm/libnm_static_la-nm-dhcp6-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManager_la-nm-sleep-monitor.lo: src/core/nm-sleep-monitor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-sleep-monitor.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-sleep-monitor.Tpo -c -o src/core/libNetworkManager_la-nm-sleep-monitor.lo `test -f 'src/core/nm-sleep-monitor.c' || echo '$(srcdir)/'`src/core/nm-sleep-monitor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-sleep-monitor.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-sleep-monitor.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-sleep-monitor.c' object='src/core/libNetworkManager_la-nm-sleep-monitor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-dhcp6-config.lo `test -f 'libnm/nm-dhcp6-config.c' || echo '$(srcdir)/'`libnm/nm-dhcp6-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-sleep-monitor.lo `test -f 'src/core/nm-sleep-monitor.c' || echo '$(srcdir)/'`src/core/nm-sleep-monitor.c -libnm/libnm_static_la-nm-dns-manager.lo: libnm/nm-dns-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-dns-manager.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-dns-manager.Tpo -c -o libnm/libnm_static_la-nm-dns-manager.lo `test -f 'libnm/nm-dns-manager.c' || echo '$(srcdir)/'`libnm/nm-dns-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-dns-manager.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-dns-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-dns-manager.c' object='libnm/libnm_static_la-nm-dns-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManagerBase_la-nm-core-utils.lo: src/core/nm-core-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-core-utils.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-core-utils.Tpo -c -o src/core/libNetworkManagerBase_la-nm-core-utils.lo `test -f 'src/core/nm-core-utils.c' || echo '$(srcdir)/'`src/core/nm-core-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-core-utils.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-core-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-core-utils.c' object='src/core/libNetworkManagerBase_la-nm-core-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-dns-manager.lo `test -f 'libnm/nm-dns-manager.c' || echo '$(srcdir)/'`libnm/nm-dns-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-core-utils.lo `test -f 'src/core/nm-core-utils.c' || echo '$(srcdir)/'`src/core/nm-core-utils.c -libnm/libnm_static_la-nm-ip-config.lo: libnm/nm-ip-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-ip-config.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-ip-config.Tpo -c -o libnm/libnm_static_la-nm-ip-config.lo `test -f 'libnm/nm-ip-config.c' || echo '$(srcdir)/'`libnm/nm-ip-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-ip-config.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-ip-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-ip-config.c' object='libnm/libnm_static_la-nm-ip-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo: src/core/NetworkManagerUtils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-NetworkManagerUtils.Tpo -c -o src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo `test -f 'src/core/NetworkManagerUtils.c' || echo '$(srcdir)/'`src/core/NetworkManagerUtils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-NetworkManagerUtils.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-NetworkManagerUtils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/NetworkManagerUtils.c' object='src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-ip-config.lo `test -f 'libnm/nm-ip-config.c' || echo '$(srcdir)/'`libnm/nm-ip-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo `test -f 'src/core/NetworkManagerUtils.c' || echo '$(srcdir)/'`src/core/NetworkManagerUtils.c -libnm/libnm_static_la-nm-ip4-config.lo: libnm/nm-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-ip4-config.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-ip4-config.Tpo -c -o libnm/libnm_static_la-nm-ip4-config.lo `test -f 'libnm/nm-ip4-config.c' || echo '$(srcdir)/'`libnm/nm-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-ip4-config.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-ip4-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-ip4-config.c' object='libnm/libnm_static_la-nm-ip4-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo: src/core/ndisc/nm-lndp-ndisc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo -MD -MP -MF src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-lndp-ndisc.Tpo -c -o src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo `test -f 'src/core/ndisc/nm-lndp-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-lndp-ndisc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-lndp-ndisc.Tpo src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-lndp-ndisc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/nm-lndp-ndisc.c' object='src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-ip4-config.lo `test -f 'libnm/nm-ip4-config.c' || echo '$(srcdir)/'`libnm/nm-ip4-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo `test -f 'src/core/ndisc/nm-lndp-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-lndp-ndisc.c -libnm/libnm_static_la-nm-ip6-config.lo: libnm/nm-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-ip6-config.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-ip6-config.Tpo -c -o libnm/libnm_static_la-nm-ip6-config.lo `test -f 'libnm/nm-ip6-config.c' || echo '$(srcdir)/'`libnm/nm-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-ip6-config.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-ip6-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-ip6-config.c' object='libnm/libnm_static_la-nm-ip6-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo: src/core/ndisc/nm-ndisc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo -MD -MP -MF src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-ndisc.Tpo -c -o src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo `test -f 'src/core/ndisc/nm-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-ndisc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-ndisc.Tpo src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-ndisc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/nm-ndisc.c' object='src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-ip6-config.lo `test -f 'libnm/nm-ip6-config.c' || echo '$(srcdir)/'`libnm/nm-ip6-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo `test -f 'src/core/ndisc/nm-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-ndisc.c -libnm/libnm_static_la-nm-libnm-utils.lo: libnm/nm-libnm-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-libnm-utils.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-libnm-utils.Tpo -c -o libnm/libnm_static_la-nm-libnm-utils.lo `test -f 'libnm/nm-libnm-utils.c' || echo '$(srcdir)/'`libnm/nm-libnm-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-libnm-utils.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-libnm-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-libnm-utils.c' object='libnm/libnm_static_la-nm-libnm-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManagerBase_la-nm-dbus-utils.lo: src/core/nm-dbus-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-dbus-utils.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-utils.Tpo -c -o src/core/libNetworkManagerBase_la-nm-dbus-utils.lo `test -f 'src/core/nm-dbus-utils.c' || echo '$(srcdir)/'`src/core/nm-dbus-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-utils.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dbus-utils.c' object='src/core/libNetworkManagerBase_la-nm-dbus-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-libnm-utils.lo `test -f 'libnm/nm-libnm-utils.c' || echo '$(srcdir)/'`libnm/nm-libnm-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-dbus-utils.lo `test -f 'src/core/nm-dbus-utils.c' || echo '$(srcdir)/'`src/core/nm-dbus-utils.c -libnm/libnm_static_la-nm-remote-connection.lo: libnm/nm-remote-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-remote-connection.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-remote-connection.Tpo -c -o libnm/libnm_static_la-nm-remote-connection.lo `test -f 'libnm/nm-remote-connection.c' || echo '$(srcdir)/'`libnm/nm-remote-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-remote-connection.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-remote-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-remote-connection.c' object='libnm/libnm_static_la-nm-remote-connection.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManagerBase_la-nm-dbus-object.lo: src/core/nm-dbus-object.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-dbus-object.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-object.Tpo -c -o src/core/libNetworkManagerBase_la-nm-dbus-object.lo `test -f 'src/core/nm-dbus-object.c' || echo '$(srcdir)/'`src/core/nm-dbus-object.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-object.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-object.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dbus-object.c' object='src/core/libNetworkManagerBase_la-nm-dbus-object.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-remote-connection.lo `test -f 'libnm/nm-remote-connection.c' || echo '$(srcdir)/'`libnm/nm-remote-connection.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-dbus-object.lo `test -f 'src/core/nm-dbus-object.c' || echo '$(srcdir)/'`src/core/nm-dbus-object.c -libnm/libnm_static_la-nm-secret-agent-old.lo: libnm/nm-secret-agent-old.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-secret-agent-old.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-secret-agent-old.Tpo -c -o libnm/libnm_static_la-nm-secret-agent-old.lo `test -f 'libnm/nm-secret-agent-old.c' || echo '$(srcdir)/'`libnm/nm-secret-agent-old.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-secret-agent-old.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-secret-agent-old.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-secret-agent-old.c' object='libnm/libnm_static_la-nm-secret-agent-old.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManagerBase_la-nm-netns.lo: src/core/nm-netns.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-netns.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-netns.Tpo -c -o src/core/libNetworkManagerBase_la-nm-netns.lo `test -f 'src/core/nm-netns.c' || echo '$(srcdir)/'`src/core/nm-netns.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-netns.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-netns.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-netns.c' object='src/core/libNetworkManagerBase_la-nm-netns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-secret-agent-old.lo `test -f 'libnm/nm-secret-agent-old.c' || echo '$(srcdir)/'`libnm/nm-secret-agent-old.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-netns.lo `test -f 'src/core/nm-netns.c' || echo '$(srcdir)/'`src/core/nm-netns.c -libnm/libnm_static_la-nm-vpn-connection.lo: libnm/nm-vpn-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-vpn-connection.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-vpn-connection.Tpo -c -o libnm/libnm_static_la-nm-vpn-connection.lo `test -f 'libnm/nm-vpn-connection.c' || echo '$(srcdir)/'`libnm/nm-vpn-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-vpn-connection.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-vpn-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-vpn-connection.c' object='libnm/libnm_static_la-nm-vpn-connection.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManagerBase_la-nm-l3-config-data.lo: src/core/nm-l3-config-data.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-l3-config-data.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-config-data.Tpo -c -o src/core/libNetworkManagerBase_la-nm-l3-config-data.lo `test -f 'src/core/nm-l3-config-data.c' || echo '$(srcdir)/'`src/core/nm-l3-config-data.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-config-data.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-config-data.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-l3-config-data.c' object='src/core/libNetworkManagerBase_la-nm-l3-config-data.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-vpn-connection.lo `test -f 'libnm/nm-vpn-connection.c' || echo '$(srcdir)/'`libnm/nm-vpn-connection.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-l3-config-data.lo `test -f 'src/core/nm-l3-config-data.c' || echo '$(srcdir)/'`src/core/nm-l3-config-data.c -libnm/libnm_static_la-nm-vpn-editor.lo: libnm/nm-vpn-editor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-vpn-editor.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-vpn-editor.Tpo -c -o libnm/libnm_static_la-nm-vpn-editor.lo `test -f 'libnm/nm-vpn-editor.c' || echo '$(srcdir)/'`libnm/nm-vpn-editor.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-vpn-editor.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-vpn-editor.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-vpn-editor.c' object='libnm/libnm_static_la-nm-vpn-editor.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManagerBase_la-nm-l3-ipv4ll.lo: src/core/nm-l3-ipv4ll.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-l3-ipv4ll.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-ipv4ll.Tpo -c -o src/core/libNetworkManagerBase_la-nm-l3-ipv4ll.lo `test -f 'src/core/nm-l3-ipv4ll.c' || echo '$(srcdir)/'`src/core/nm-l3-ipv4ll.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-ipv4ll.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-ipv4ll.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-l3-ipv4ll.c' object='src/core/libNetworkManagerBase_la-nm-l3-ipv4ll.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-vpn-editor.lo `test -f 'libnm/nm-vpn-editor.c' || echo '$(srcdir)/'`libnm/nm-vpn-editor.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-l3-ipv4ll.lo `test -f 'src/core/nm-l3-ipv4ll.c' || echo '$(srcdir)/'`src/core/nm-l3-ipv4ll.c -libnm/libnm_static_la-nm-vpn-plugin-old.lo: libnm/nm-vpn-plugin-old.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-vpn-plugin-old.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-vpn-plugin-old.Tpo -c -o libnm/libnm_static_la-nm-vpn-plugin-old.lo `test -f 'libnm/nm-vpn-plugin-old.c' || echo '$(srcdir)/'`libnm/nm-vpn-plugin-old.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-vpn-plugin-old.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-vpn-plugin-old.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-vpn-plugin-old.c' object='libnm/libnm_static_la-nm-vpn-plugin-old.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManagerBase_la-nm-l3cfg.lo: src/core/nm-l3cfg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-l3cfg.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3cfg.Tpo -c -o src/core/libNetworkManagerBase_la-nm-l3cfg.lo `test -f 'src/core/nm-l3cfg.c' || echo '$(srcdir)/'`src/core/nm-l3cfg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3cfg.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3cfg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-l3cfg.c' object='src/core/libNetworkManagerBase_la-nm-l3cfg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-vpn-plugin-old.lo `test -f 'libnm/nm-vpn-plugin-old.c' || echo '$(srcdir)/'`libnm/nm-vpn-plugin-old.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-l3cfg.lo `test -f 'src/core/nm-l3cfg.c' || echo '$(srcdir)/'`src/core/nm-l3cfg.c -libnm/libnm_static_la-nm-vpn-service-plugin.lo: libnm/nm-vpn-service-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-vpn-service-plugin.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-vpn-service-plugin.Tpo -c -o libnm/libnm_static_la-nm-vpn-service-plugin.lo `test -f 'libnm/nm-vpn-service-plugin.c' || echo '$(srcdir)/'`libnm/nm-vpn-service-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-vpn-service-plugin.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-vpn-service-plugin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-vpn-service-plugin.c' object='libnm/libnm_static_la-nm-vpn-service-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManagerBase_la-nm-ip-config.lo: src/core/nm-ip-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-ip-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip-config.Tpo -c -o src/core/libNetworkManagerBase_la-nm-ip-config.lo `test -f 'src/core/nm-ip-config.c' || echo '$(srcdir)/'`src/core/nm-ip-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip-config.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-ip-config.c' object='src/core/libNetworkManagerBase_la-nm-ip-config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-ip-config.lo `test -f 'src/core/nm-ip-config.c' || echo '$(srcdir)/'`src/core/nm-ip-config.c + +src/core/libNetworkManagerBase_la-nm-ip4-config.lo: src/core/nm-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-ip4-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip4-config.Tpo -c -o src/core/libNetworkManagerBase_la-nm-ip4-config.lo `test -f 'src/core/nm-ip4-config.c' || echo '$(srcdir)/'`src/core/nm-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip4-config.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip4-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-ip4-config.c' object='src/core/libNetworkManagerBase_la-nm-ip4-config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-ip4-config.lo `test -f 'src/core/nm-ip4-config.c' || echo '$(srcdir)/'`src/core/nm-ip4-config.c + +src/core/libNetworkManagerBase_la-nm-ip6-config.lo: src/core/nm-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-ip6-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip6-config.Tpo -c -o src/core/libNetworkManagerBase_la-nm-ip6-config.lo `test -f 'src/core/nm-ip6-config.c' || echo '$(srcdir)/'`src/core/nm-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip6-config.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip6-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-ip6-config.c' object='src/core/libNetworkManagerBase_la-nm-ip6-config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-ip6-config.lo `test -f 'src/core/nm-ip6-config.c' || echo '$(srcdir)/'`src/core/nm-ip6-config.c + +src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-client.lo: src/core/dhcp/nm-dhcp-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-client.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-client.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-client.lo `test -f 'src/core/dhcp/nm-dhcp-client.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-client.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-client.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-client.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-client.lo `test -f 'src/core/dhcp/nm-dhcp-client.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-client.c + +src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-nettools.lo: src/core/dhcp/nm-dhcp-nettools.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-nettools.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-nettools.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-nettools.lo `test -f 'src/core/dhcp/nm-dhcp-nettools.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-nettools.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-nettools.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-nettools.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-nettools.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-nettools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-vpn-service-plugin.lo `test -f 'libnm/nm-vpn-service-plugin.c' || echo '$(srcdir)/'`libnm/nm-vpn-service-plugin.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-nettools.lo `test -f 'src/core/dhcp/nm-dhcp-nettools.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-nettools.c -libnm/libnm_static_la-nm-wifi-p2p-peer.lo: libnm/nm-wifi-p2p-peer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-wifi-p2p-peer.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-wifi-p2p-peer.Tpo -c -o libnm/libnm_static_la-nm-wifi-p2p-peer.lo `test -f 'libnm/nm-wifi-p2p-peer.c' || echo '$(srcdir)/'`libnm/nm-wifi-p2p-peer.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-wifi-p2p-peer.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-wifi-p2p-peer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-wifi-p2p-peer.c' object='libnm/libnm_static_la-nm-wifi-p2p-peer.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-utils.lo: src/core/dhcp/nm-dhcp-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-utils.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-utils.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-utils.lo `test -f 'src/core/dhcp/nm-dhcp-utils.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-utils.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-utils.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-wifi-p2p-peer.lo `test -f 'libnm/nm-wifi-p2p-peer.c' || echo '$(srcdir)/'`libnm/nm-wifi-p2p-peer.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-utils.lo `test -f 'src/core/dhcp/nm-dhcp-utils.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-utils.c -libnm/libnm_static_la-nm-wimax-nsp.lo: libnm/nm-wimax-nsp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-wimax-nsp.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-wimax-nsp.Tpo -c -o libnm/libnm_static_la-nm-wimax-nsp.lo `test -f 'libnm/nm-wimax-nsp.c' || echo '$(srcdir)/'`libnm/nm-wimax-nsp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-wimax-nsp.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-wimax-nsp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-wimax-nsp.c' object='libnm/libnm_static_la-nm-wimax-nsp.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo: src/core/dhcp/nm-dhcp-options.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-options.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo `test -f 'src/core/dhcp/nm-dhcp-options.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-options.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-options.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-options.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-options.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-wimax-nsp.lo `test -f 'libnm/nm-wimax-nsp.c' || echo '$(srcdir)/'`libnm/nm-wimax-nsp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo `test -f 'src/core/dhcp/nm-dhcp-options.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-options.c -libnm/libnm_static_la-nm-enum-types.lo: libnm/nm-enum-types.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/libnm_static_la-nm-enum-types.lo -MD -MP -MF libnm/$(DEPDIR)/libnm_static_la-nm-enum-types.Tpo -c -o libnm/libnm_static_la-nm-enum-types.lo `test -f 'libnm/nm-enum-types.c' || echo '$(srcdir)/'`libnm/nm-enum-types.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/$(DEPDIR)/libnm_static_la-nm-enum-types.Tpo libnm/$(DEPDIR)/libnm_static_la-nm-enum-types.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-enum-types.c' object='libnm/libnm_static_la-nm-enum-types.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo: src/core/dhcp/nm-dhcp-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-systemd.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo `test -f 'src/core/dhcp/nm-dhcp-systemd.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-systemd.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-systemd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-systemd.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_libnm_static_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/libnm_static_la-nm-enum-types.lo `test -f 'libnm/nm-enum-types.c' || echo '$(srcdir)/'`libnm/nm-enum-types.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo `test -f 'src/core/dhcp/nm-dhcp-systemd.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-systemd.c -libnm/nm-libnm-aux/libnm_libnm_aux_la-nm-libnm-aux.lo: libnm/nm-libnm-aux/nm-libnm-aux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_nm_libnm_aux_libnm_libnm_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/nm-libnm-aux/libnm_libnm_aux_la-nm-libnm-aux.lo -MD -MP -MF libnm/nm-libnm-aux/$(DEPDIR)/libnm_libnm_aux_la-nm-libnm-aux.Tpo -c -o libnm/nm-libnm-aux/libnm_libnm_aux_la-nm-libnm-aux.lo `test -f 'libnm/nm-libnm-aux/nm-libnm-aux.c' || echo '$(srcdir)/'`libnm/nm-libnm-aux/nm-libnm-aux.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/nm-libnm-aux/$(DEPDIR)/libnm_libnm_aux_la-nm-libnm-aux.Tpo libnm/nm-libnm-aux/$(DEPDIR)/libnm_libnm_aux_la-nm-libnm-aux.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/nm-libnm-aux/nm-libnm-aux.c' object='libnm/nm-libnm-aux/libnm_libnm_aux_la-nm-libnm-aux.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo: src/core/dhcp/nm-dhcp-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-manager.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo `test -f 'src/core/dhcp/nm-dhcp-manager.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-manager.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-manager.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_nm_libnm_aux_libnm_libnm_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/nm-libnm-aux/libnm_libnm_aux_la-nm-libnm-aux.lo `test -f 'libnm/nm-libnm-aux/nm-libnm-aux.c' || echo '$(srcdir)/'`libnm/nm-libnm-aux/nm-libnm-aux.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo `test -f 'src/core/dhcp/nm-dhcp-manager.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-manager.c -shared/nm-utils/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo: shared/nm-utils/nm-vpn-plugin-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_tests_libnm_vpn_plugin_utils_test_la_CFLAGS) $(CFLAGS) -MT shared/nm-utils/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo -MD -MP -MF shared/nm-utils/$(DEPDIR)/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Tpo -c -o shared/nm-utils/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo `test -f 'shared/nm-utils/nm-vpn-plugin-utils.c' || echo '$(srcdir)/'`shared/nm-utils/nm-vpn-plugin-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-utils/$(DEPDIR)/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Tpo shared/nm-utils/$(DEPDIR)/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-utils/nm-vpn-plugin-utils.c' object='shared/nm-utils/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/libNetworkManagerBase_la-main-utils.lo: src/core/main-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-main-utils.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-main-utils.Tpo -c -o src/core/libNetworkManagerBase_la-main-utils.lo `test -f 'src/core/main-utils.c' || echo '$(srcdir)/'`src/core/main-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-main-utils.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-main-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/main-utils.c' object='src/core/libNetworkManagerBase_la-main-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_tests_libnm_vpn_plugin_utils_test_la_CFLAGS) $(CFLAGS) -c -o shared/nm-utils/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.lo `test -f 'shared/nm-utils/nm-vpn-plugin-utils.c' || echo '$(srcdir)/'`shared/nm-utils/nm-vpn-plugin-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-main-utils.lo `test -f 'src/core/main-utils.c' || echo '$(srcdir)/'`src/core/main-utils.c -shared/c-rbtree/src/libcrbtree_la-c-rbtree.lo: shared/c-rbtree/src/c-rbtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libcrbtree_la_CPPFLAGS) $(CPPFLAGS) $(shared_libcrbtree_la_CFLAGS) $(CFLAGS) -MT shared/c-rbtree/src/libcrbtree_la-c-rbtree.lo -MD -MP -MF shared/c-rbtree/src/$(DEPDIR)/libcrbtree_la-c-rbtree.Tpo -c -o shared/c-rbtree/src/libcrbtree_la-c-rbtree.lo `test -f 'shared/c-rbtree/src/c-rbtree.c' || echo '$(srcdir)/'`shared/c-rbtree/src/c-rbtree.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/c-rbtree/src/$(DEPDIR)/libcrbtree_la-c-rbtree.Tpo shared/c-rbtree/src/$(DEPDIR)/libcrbtree_la-c-rbtree.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/c-rbtree/src/c-rbtree.c' object='shared/c-rbtree/src/libcrbtree_la-c-rbtree.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo: src/core/ndisc/nm-fake-ndisc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo -MD -MP -MF src/core/ndisc/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-ndisc.Tpo -c -o src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo `test -f 'src/core/ndisc/nm-fake-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-fake-ndisc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-ndisc.Tpo src/core/ndisc/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-ndisc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/nm-fake-ndisc.c' object='src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libcrbtree_la_CPPFLAGS) $(CPPFLAGS) $(shared_libcrbtree_la_CFLAGS) $(CFLAGS) -c -o shared/c-rbtree/src/libcrbtree_la-c-rbtree.lo `test -f 'shared/c-rbtree/src/c-rbtree.c' || echo '$(srcdir)/'`shared/c-rbtree/src/c-rbtree.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo `test -f 'src/core/ndisc/nm-fake-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-fake-ndisc.c -shared/c-siphash/src/libcsiphash_la-c-siphash.lo: shared/c-siphash/src/c-siphash.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libcsiphash_la_CPPFLAGS) $(CPPFLAGS) $(shared_libcsiphash_la_CFLAGS) $(CFLAGS) -MT shared/c-siphash/src/libcsiphash_la-c-siphash.lo -MD -MP -MF shared/c-siphash/src/$(DEPDIR)/libcsiphash_la-c-siphash.Tpo -c -o shared/c-siphash/src/libcsiphash_la-c-siphash.lo `test -f 'shared/c-siphash/src/c-siphash.c' || echo '$(srcdir)/'`shared/c-siphash/src/c-siphash.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/c-siphash/src/$(DEPDIR)/libcsiphash_la-c-siphash.Tpo shared/c-siphash/src/$(DEPDIR)/libcsiphash_la-c-siphash.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/c-siphash/src/c-siphash.c' object='shared/c-siphash/src/libcsiphash_la-c-siphash.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo: src/core/platform/nm-fake-platform.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo -MD -MP -MF src/core/platform/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-platform.Tpo -c -o src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo `test -f 'src/core/platform/nm-fake-platform.c' || echo '$(srcdir)/'`src/core/platform/nm-fake-platform.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-platform.Tpo src/core/platform/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-platform.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/nm-fake-platform.c' object='src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libcsiphash_la_CPPFLAGS) $(CPPFLAGS) $(shared_libcsiphash_la_CFLAGS) $(CFLAGS) -c -o shared/c-siphash/src/libcsiphash_la-c-siphash.lo `test -f 'shared/c-siphash/src/c-siphash.c' || echo '$(srcdir)/'`shared/c-siphash/src/c-siphash.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo `test -f 'src/core/platform/nm-fake-platform.c' || echo '$(srcdir)/'`src/core/platform/nm-fake-platform.c -shared/n-acd/src/libnacd_la-n-acd.lo: shared/n-acd/src/n-acd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libnacd_la_CPPFLAGS) $(CPPFLAGS) $(shared_libnacd_la_CFLAGS) $(CFLAGS) -MT shared/n-acd/src/libnacd_la-n-acd.lo -MD -MP -MF shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd.Tpo -c -o shared/n-acd/src/libnacd_la-n-acd.lo `test -f 'shared/n-acd/src/n-acd.c' || echo '$(srcdir)/'`shared/n-acd/src/n-acd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd.Tpo shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-acd/src/n-acd.c' object='shared/n-acd/src/libnacd_la-n-acd.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/platform/tests/libNetworkManagerTest_la-test-common.lo: src/core/platform/tests/test-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/libNetworkManagerTest_la-test-common.lo -MD -MP -MF src/core/platform/tests/$(DEPDIR)/libNetworkManagerTest_la-test-common.Tpo -c -o src/core/platform/tests/libNetworkManagerTest_la-test-common.lo `test -f 'src/core/platform/tests/test-common.c' || echo '$(srcdir)/'`src/core/platform/tests/test-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/libNetworkManagerTest_la-test-common.Tpo src/core/platform/tests/$(DEPDIR)/libNetworkManagerTest_la-test-common.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-common.c' object='src/core/platform/tests/libNetworkManagerTest_la-test-common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libnacd_la_CPPFLAGS) $(CPPFLAGS) $(shared_libnacd_la_CFLAGS) $(CFLAGS) -c -o shared/n-acd/src/libnacd_la-n-acd.lo `test -f 'shared/n-acd/src/n-acd.c' || echo '$(srcdir)/'`shared/n-acd/src/n-acd.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/libNetworkManagerTest_la-test-common.lo `test -f 'src/core/platform/tests/test-common.c' || echo '$(srcdir)/'`src/core/platform/tests/test-common.c -shared/n-acd/src/libnacd_la-n-acd-probe.lo: shared/n-acd/src/n-acd-probe.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libnacd_la_CPPFLAGS) $(CPPFLAGS) $(shared_libnacd_la_CFLAGS) $(CFLAGS) -MT shared/n-acd/src/libnacd_la-n-acd-probe.lo -MD -MP -MF shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-probe.Tpo -c -o shared/n-acd/src/libnacd_la-n-acd-probe.lo `test -f 'shared/n-acd/src/n-acd-probe.c' || echo '$(srcdir)/'`shared/n-acd/src/n-acd-probe.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-probe.Tpo shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-probe.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-acd/src/n-acd-probe.c' object='shared/n-acd/src/libnacd_la-n-acd-probe.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/libnm_systemd_core_la-nm-sd-utils-core.lo: src/core/systemd/nm-sd-utils-core.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/libnm_systemd_core_la-nm-sd-utils-core.lo -MD -MP -MF src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-core.Tpo -c -o src/core/systemd/libnm_systemd_core_la-nm-sd-utils-core.lo `test -f 'src/core/systemd/nm-sd-utils-core.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd-utils-core.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-core.Tpo src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-core.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/nm-sd-utils-core.c' object='src/core/systemd/libnm_systemd_core_la-nm-sd-utils-core.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libnacd_la_CPPFLAGS) $(CPPFLAGS) $(shared_libnacd_la_CFLAGS) $(CFLAGS) -c -o shared/n-acd/src/libnacd_la-n-acd-probe.lo `test -f 'shared/n-acd/src/n-acd-probe.c' || echo '$(srcdir)/'`shared/n-acd/src/n-acd-probe.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/libnm_systemd_core_la-nm-sd-utils-core.lo `test -f 'src/core/systemd/nm-sd-utils-core.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd-utils-core.c -shared/n-acd/src/util/libnacd_la-timer.lo: shared/n-acd/src/util/timer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libnacd_la_CPPFLAGS) $(CPPFLAGS) $(shared_libnacd_la_CFLAGS) $(CFLAGS) -MT shared/n-acd/src/util/libnacd_la-timer.lo -MD -MP -MF shared/n-acd/src/util/$(DEPDIR)/libnacd_la-timer.Tpo -c -o shared/n-acd/src/util/libnacd_la-timer.lo `test -f 'shared/n-acd/src/util/timer.c' || echo '$(srcdir)/'`shared/n-acd/src/util/timer.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-acd/src/util/$(DEPDIR)/libnacd_la-timer.Tpo shared/n-acd/src/util/$(DEPDIR)/libnacd_la-timer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-acd/src/util/timer.c' object='shared/n-acd/src/util/libnacd_la-timer.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/libnm_systemd_core_la-nm-sd.lo: src/core/systemd/nm-sd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/libnm_systemd_core_la-nm-sd.lo -MD -MP -MF src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd.Tpo -c -o src/core/systemd/libnm_systemd_core_la-nm-sd.lo `test -f 'src/core/systemd/nm-sd.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd.Tpo src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/nm-sd.c' object='src/core/systemd/libnm_systemd_core_la-nm-sd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libnacd_la_CPPFLAGS) $(CPPFLAGS) $(shared_libnacd_la_CFLAGS) $(CFLAGS) -c -o shared/n-acd/src/util/libnacd_la-timer.lo `test -f 'shared/n-acd/src/util/timer.c' || echo '$(srcdir)/'`shared/n-acd/src/util/timer.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/libnm_systemd_core_la-nm-sd.lo `test -f 'src/core/systemd/nm-sd.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd.c -shared/n-acd/src/libnacd_la-n-acd-bpf.lo: shared/n-acd/src/n-acd-bpf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libnacd_la_CPPFLAGS) $(CPPFLAGS) $(shared_libnacd_la_CFLAGS) $(CFLAGS) -MT shared/n-acd/src/libnacd_la-n-acd-bpf.lo -MD -MP -MF shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf.Tpo -c -o shared/n-acd/src/libnacd_la-n-acd-bpf.lo `test -f 'shared/n-acd/src/n-acd-bpf.c' || echo '$(srcdir)/'`shared/n-acd/src/n-acd-bpf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf.Tpo shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-acd/src/n-acd-bpf.c' object='shared/n-acd/src/libnacd_la-n-acd-bpf.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/libnm_systemd_core_la-nm-sd-utils-dhcp.lo: src/core/systemd/nm-sd-utils-dhcp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/libnm_systemd_core_la-nm-sd-utils-dhcp.lo -MD -MP -MF src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-dhcp.Tpo -c -o src/core/systemd/libnm_systemd_core_la-nm-sd-utils-dhcp.lo `test -f 'src/core/systemd/nm-sd-utils-dhcp.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd-utils-dhcp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-dhcp.Tpo src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-dhcp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/nm-sd-utils-dhcp.c' object='src/core/systemd/libnm_systemd_core_la-nm-sd-utils-dhcp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libnacd_la_CPPFLAGS) $(CPPFLAGS) $(shared_libnacd_la_CFLAGS) $(CFLAGS) -c -o shared/n-acd/src/libnacd_la-n-acd-bpf.lo `test -f 'shared/n-acd/src/n-acd-bpf.c' || echo '$(srcdir)/'`shared/n-acd/src/n-acd-bpf.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/libnm_systemd_core_la-nm-sd-utils-dhcp.lo `test -f 'src/core/systemd/nm-sd-utils-dhcp.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd-utils-dhcp.c -shared/n-acd/src/libnacd_la-n-acd-bpf-fallback.lo: shared/n-acd/src/n-acd-bpf-fallback.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libnacd_la_CPPFLAGS) $(CPPFLAGS) $(shared_libnacd_la_CFLAGS) $(CFLAGS) -MT shared/n-acd/src/libnacd_la-n-acd-bpf-fallback.lo -MD -MP -MF shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf-fallback.Tpo -c -o shared/n-acd/src/libnacd_la-n-acd-bpf-fallback.lo `test -f 'shared/n-acd/src/n-acd-bpf-fallback.c' || echo '$(srcdir)/'`shared/n-acd/src/n-acd-bpf-fallback.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf-fallback.Tpo shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf-fallback.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-acd/src/n-acd-bpf-fallback.c' object='shared/n-acd/src/libnacd_la-n-acd-bpf-fallback.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/sd-adapt-core/libnm_systemd_core_la-nm-sd-adapt-core.lo: src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/sd-adapt-core/libnm_systemd_core_la-nm-sd-adapt-core.lo -MD -MP -MF src/core/systemd/sd-adapt-core/$(DEPDIR)/libnm_systemd_core_la-nm-sd-adapt-core.Tpo -c -o src/core/systemd/sd-adapt-core/libnm_systemd_core_la-nm-sd-adapt-core.lo `test -f 'src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c' || echo '$(srcdir)/'`src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/sd-adapt-core/$(DEPDIR)/libnm_systemd_core_la-nm-sd-adapt-core.Tpo src/core/systemd/sd-adapt-core/$(DEPDIR)/libnm_systemd_core_la-nm-sd-adapt-core.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c' object='src/core/systemd/sd-adapt-core/libnm_systemd_core_la-nm-sd-adapt-core.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libnacd_la_CPPFLAGS) $(CPPFLAGS) $(shared_libnacd_la_CFLAGS) $(CFLAGS) -c -o shared/n-acd/src/libnacd_la-n-acd-bpf-fallback.lo `test -f 'shared/n-acd/src/n-acd-bpf-fallback.c' || echo '$(srcdir)/'`shared/n-acd/src/n-acd-bpf-fallback.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/sd-adapt-core/libnm_systemd_core_la-nm-sd-adapt-core.lo `test -f 'src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c' || echo '$(srcdir)/'`src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-connection.lo: shared/n-dhcp4/src/n-dhcp4-c-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -MT shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-connection.lo -MD -MP -MF shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-connection.Tpo -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-connection.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-c-connection.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-c-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-connection.Tpo shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-dhcp4/src/n-dhcp4-c-connection.c' object='shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-connection.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-arp-util.lo: src/core/systemd/src/libsystemd-network/arp-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-arp-util.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-arp-util.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-arp-util.lo `test -f 'src/core/systemd/src/libsystemd-network/arp-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/arp-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-arp-util.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-arp-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/arp-util.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-arp-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-connection.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-c-connection.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-c-connection.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-arp-util.lo `test -f 'src/core/systemd/src/libsystemd-network/arp-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/arp-util.c -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-lease.lo: shared/n-dhcp4/src/n-dhcp4-c-lease.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -MT shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-lease.lo -MD -MP -MF shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-lease.Tpo -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-lease.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-c-lease.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-c-lease.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-lease.Tpo shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-lease.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-dhcp4/src/n-dhcp4-c-lease.c' object='shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-lease.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-identifier.lo: src/core/systemd/src/libsystemd-network/dhcp-identifier.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-identifier.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-identifier.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-identifier.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-identifier.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-identifier.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-identifier.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-identifier.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp-identifier.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-identifier.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-lease.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-c-lease.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-c-lease.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-identifier.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-identifier.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-identifier.c -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-probe.lo: shared/n-dhcp4/src/n-dhcp4-c-probe.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -MT shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-probe.lo -MD -MP -MF shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-probe.Tpo -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-probe.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-c-probe.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-c-probe.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-probe.Tpo shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-probe.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-dhcp4/src/n-dhcp4-c-probe.c' object='shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-probe.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-network.lo: src/core/systemd/src/libsystemd-network/dhcp-network.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-network.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-network.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-network.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-network.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-network.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-network.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp-network.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-network.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-c-probe.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-c-probe.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-c-probe.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-network.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-network.c -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-client.lo: shared/n-dhcp4/src/n-dhcp4-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -MT shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-client.lo -MD -MP -MF shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-client.Tpo -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-client.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-client.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-client.Tpo shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-client.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-dhcp4/src/n-dhcp4-client.c' object='shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-client.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-option.lo: src/core/systemd/src/libsystemd-network/dhcp-option.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-option.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-option.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-option.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-option.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-option.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-option.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-option.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp-option.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-option.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-client.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-client.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-client.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-option.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-option.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-option.c -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-incoming.lo: shared/n-dhcp4/src/n-dhcp4-incoming.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -MT shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-incoming.lo -MD -MP -MF shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-incoming.Tpo -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-incoming.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-incoming.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-incoming.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-incoming.Tpo shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-incoming.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-dhcp4/src/n-dhcp4-incoming.c' object='shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-incoming.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-packet.lo: src/core/systemd/src/libsystemd-network/dhcp-packet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-packet.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-packet.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-packet.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-packet.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-packet.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-packet.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-packet.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp-packet.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-packet.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-incoming.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-incoming.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-incoming.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-packet.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-packet.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-packet.c -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-outgoing.lo: shared/n-dhcp4/src/n-dhcp4-outgoing.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -MT shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-outgoing.lo -MD -MP -MF shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-outgoing.Tpo -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-outgoing.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-outgoing.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-outgoing.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-outgoing.Tpo shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-outgoing.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-dhcp4/src/n-dhcp4-outgoing.c' object='shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-outgoing.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-network.lo: src/core/systemd/src/libsystemd-network/dhcp6-network.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-network.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-network.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-network.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp6-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp6-network.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-network.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-network.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp6-network.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-network.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-outgoing.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-outgoing.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-outgoing.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-network.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp6-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp6-network.c -shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-socket.lo: shared/n-dhcp4/src/n-dhcp4-socket.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -MT shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-socket.lo -MD -MP -MF shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-socket.Tpo -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-socket.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-socket.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-socket.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-socket.Tpo shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-socket.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-dhcp4/src/n-dhcp4-socket.c' object='shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-socket.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-option.lo: src/core/systemd/src/libsystemd-network/dhcp6-option.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-option.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-option.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-option.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp6-option.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp6-option.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-option.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-option.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp6-option.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-option.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -c -o shared/n-dhcp4/src/libndhcp4_la-n-dhcp4-socket.lo `test -f 'shared/n-dhcp4/src/n-dhcp4-socket.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/n-dhcp4-socket.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-option.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp6-option.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp6-option.c -shared/n-dhcp4/src/util/libndhcp4_la-packet.lo: shared/n-dhcp4/src/util/packet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -MT shared/n-dhcp4/src/util/libndhcp4_la-packet.lo -MD -MP -MF shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-packet.Tpo -c -o shared/n-dhcp4/src/util/libndhcp4_la-packet.lo `test -f 'shared/n-dhcp4/src/util/packet.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/util/packet.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-packet.Tpo shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-packet.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-dhcp4/src/util/packet.c' object='shared/n-dhcp4/src/util/libndhcp4_la-packet.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-neighbor.lo: src/core/systemd/src/libsystemd-network/lldp-neighbor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-neighbor.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-neighbor.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-neighbor.lo `test -f 'src/core/systemd/src/libsystemd-network/lldp-neighbor.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/lldp-neighbor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-neighbor.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-neighbor.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/lldp-neighbor.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-neighbor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -c -o shared/n-dhcp4/src/util/libndhcp4_la-packet.lo `test -f 'shared/n-dhcp4/src/util/packet.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/util/packet.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-neighbor.lo `test -f 'src/core/systemd/src/libsystemd-network/lldp-neighbor.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/lldp-neighbor.c -shared/n-dhcp4/src/util/libndhcp4_la-socket.lo: shared/n-dhcp4/src/util/socket.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -MT shared/n-dhcp4/src/util/libndhcp4_la-socket.lo -MD -MP -MF shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-socket.Tpo -c -o shared/n-dhcp4/src/util/libndhcp4_la-socket.lo `test -f 'shared/n-dhcp4/src/util/socket.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/util/socket.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-socket.Tpo shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-socket.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/n-dhcp4/src/util/socket.c' object='shared/n-dhcp4/src/util/libndhcp4_la-socket.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-network.lo: src/core/systemd/src/libsystemd-network/lldp-network.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-network.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-network.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-network.lo `test -f 'src/core/systemd/src/libsystemd-network/lldp-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/lldp-network.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-network.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-network.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/lldp-network.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-network.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_libndhcp4_la_CPPFLAGS) $(CPPFLAGS) $(shared_libndhcp4_la_CFLAGS) $(CFLAGS) -c -o shared/n-dhcp4/src/util/libndhcp4_la-socket.lo `test -f 'shared/n-dhcp4/src/util/socket.c' || echo '$(srcdir)/'`shared/n-dhcp4/src/util/socket.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-network.lo `test -f 'src/core/systemd/src/libsystemd-network/lldp-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/lldp-network.c -shared/nm-base/libnm_base_la-nm-ethtool-base.lo: shared/nm-base/nm-ethtool-base.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_base_libnm_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-base/libnm_base_la-nm-ethtool-base.lo -MD -MP -MF shared/nm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Tpo -c -o shared/nm-base/libnm_base_la-nm-ethtool-base.lo `test -f 'shared/nm-base/nm-ethtool-base.c' || echo '$(srcdir)/'`shared/nm-base/nm-ethtool-base.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Tpo shared/nm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-base/nm-ethtool-base.c' object='shared/nm-base/libnm_base_la-nm-ethtool-base.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-network-internal.lo: src/core/systemd/src/libsystemd-network/network-internal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-network-internal.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-network-internal.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-network-internal.lo `test -f 'src/core/systemd/src/libsystemd-network/network-internal.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/network-internal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-network-internal.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-network-internal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/network-internal.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-network-internal.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_base_libnm_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-base/libnm_base_la-nm-ethtool-base.lo `test -f 'shared/nm-base/nm-ethtool-base.c' || echo '$(srcdir)/'`shared/nm-base/nm-ethtool-base.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-network-internal.lo `test -f 'src/core/systemd/src/libsystemd-network/network-internal.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/network-internal.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo: shared/nm-glib-aux/nm-dbus-aux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo `test -f 'shared/nm-glib-aux/nm-dbus-aux.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-dbus-aux.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-dbus-aux.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-client.lo: src/core/systemd/src/libsystemd-network/sd-dhcp-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-client.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-client.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-client.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp-client.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-client.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-dhcp-client.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-client.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo `test -f 'shared/nm-glib-aux/nm-dbus-aux.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-dbus-aux.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-client.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp-client.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp-client.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo: shared/nm-glib-aux/nm-dedup-multi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo `test -f 'shared/nm-glib-aux/nm-dedup-multi.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-dedup-multi.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-dedup-multi.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-lease.lo: src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-lease.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-lease.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-lease.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-lease.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-lease.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-lease.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo `test -f 'shared/nm-glib-aux/nm-dedup-multi.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-dedup-multi.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-lease.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo: shared/nm-glib-aux/nm-enum-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo `test -f 'shared/nm-glib-aux/nm-enum-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-enum-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-enum-utils.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-client.lo: src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-client.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-client.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-client.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-client.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-client.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo `test -f 'shared/nm-glib-aux/nm-enum-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-enum-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-client.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-errno.lo: shared/nm-glib-aux/nm-errno.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-errno.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-errno.lo `test -f 'shared/nm-glib-aux/nm-errno.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-errno.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-errno.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-errno.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-lease.lo: src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-lease.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-lease.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-lease.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-lease.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-lease.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-lease.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-errno.lo `test -f 'shared/nm-glib-aux/nm-errno.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-errno.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-lease.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo: shared/nm-glib-aux/nm-hash-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo `test -f 'shared/nm-glib-aux/nm-hash-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-hash-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-hash-utils.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4acd.lo: src/core/systemd/src/libsystemd-network/sd-ipv4acd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4acd.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4acd.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4acd.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-ipv4acd.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-ipv4acd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4acd.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4acd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-ipv4acd.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4acd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo `test -f 'shared/nm-glib-aux/nm-hash-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-hash-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4acd.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-ipv4acd.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-ipv4acd.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo: shared/nm-glib-aux/nm-io-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo `test -f 'shared/nm-glib-aux/nm-io-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-io-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-io-utils.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4ll.lo: src/core/systemd/src/libsystemd-network/sd-ipv4ll.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4ll.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4ll.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4ll.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-ipv4ll.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-ipv4ll.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4ll.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4ll.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-ipv4ll.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4ll.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo `test -f 'shared/nm-glib-aux/nm-io-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-io-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4ll.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-ipv4ll.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-ipv4ll.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo: shared/nm-glib-aux/nm-json-aux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo `test -f 'shared/nm-glib-aux/nm-json-aux.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-json-aux.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-json-aux.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-lldp.lo: src/core/systemd/src/libsystemd-network/sd-lldp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-lldp.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-lldp.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-lldp.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-lldp.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-lldp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-lldp.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-lldp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-lldp.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-lldp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo `test -f 'shared/nm-glib-aux/nm-json-aux.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-json-aux.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-lldp.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-lldp.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-lldp.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo: shared/nm-glib-aux/nm-keyfile-aux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo `test -f 'shared/nm-glib-aux/nm-keyfile-aux.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-keyfile-aux.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-keyfile-aux.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-event-util.lo: src/core/systemd/src/libsystemd/sd-event/event-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-event-util.lo -MD -MP -MF src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-event-util.Tpo -c -o src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-event-util.lo `test -f 'src/core/systemd/src/libsystemd/sd-event/event-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-event/event-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-event-util.Tpo src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-event-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd/sd-event/event-util.c' object='src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-event-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo `test -f 'shared/nm-glib-aux/nm-keyfile-aux.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-keyfile-aux.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-event-util.lo `test -f 'src/core/systemd/src/libsystemd/sd-event/event-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-event/event-util.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo: shared/nm-glib-aux/nm-logging-base.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo `test -f 'shared/nm-glib-aux/nm-logging-base.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-logging-base.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-logging-base.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-sd-event.lo: src/core/systemd/src/libsystemd/sd-event/sd-event.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-sd-event.lo -MD -MP -MF src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-sd-event.Tpo -c -o src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-sd-event.lo `test -f 'src/core/systemd/src/libsystemd/sd-event/sd-event.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-event/sd-event.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-sd-event.Tpo src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-sd-event.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd/sd-event/sd-event.c' object='src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-sd-event.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo `test -f 'shared/nm-glib-aux/nm-logging-base.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-logging-base.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-sd-event.lo `test -f 'src/core/systemd/src/libsystemd/sd-event/sd-event.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-event/sd-event.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo: shared/nm-glib-aux/nm-random-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo `test -f 'shared/nm-glib-aux/nm-random-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-random-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-random-utils.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-id128-util.lo: src/core/systemd/src/libsystemd/sd-id128/id128-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-id128-util.lo -MD -MP -MF src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-id128-util.Tpo -c -o src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-id128-util.lo `test -f 'src/core/systemd/src/libsystemd/sd-id128/id128-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-id128/id128-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-id128-util.Tpo src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-id128-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd/sd-id128/id128-util.c' object='src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-id128-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo `test -f 'shared/nm-glib-aux/nm-random-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-random-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-id128-util.lo `test -f 'src/core/systemd/src/libsystemd/sd-id128/id128-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-id128/id128-util.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo: shared/nm-glib-aux/nm-ref-string.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo `test -f 'shared/nm-glib-aux/nm-ref-string.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-ref-string.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-ref-string.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-sd-id128.lo: src/core/systemd/src/libsystemd/sd-id128/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-sd-id128.lo -MD -MP -MF src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-sd-id128.Tpo -c -o src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-sd-id128.lo `test -f 'src/core/systemd/src/libsystemd/sd-id128/sd-id128.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-id128/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-sd-id128.Tpo src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-sd-id128.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd/sd-id128/sd-id128.c' object='src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-sd-id128.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo `test -f 'shared/nm-glib-aux/nm-ref-string.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-ref-string.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-sd-id128.lo `test -f 'src/core/systemd/src/libsystemd/sd-id128/sd-id128.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-id128/sd-id128.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo: shared/nm-glib-aux/nm-secret-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo `test -f 'shared/nm-glib-aux/nm-secret-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-secret-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-secret-utils.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/ppp/libnm_ppp_plugin_la-nm-ppp-manager.lo: src/core/ppp/nm-ppp-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ppp_libnm_ppp_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ppp/libnm_ppp_plugin_la-nm-ppp-manager.lo -MD -MP -MF src/core/ppp/$(DEPDIR)/libnm_ppp_plugin_la-nm-ppp-manager.Tpo -c -o src/core/ppp/libnm_ppp_plugin_la-nm-ppp-manager.lo `test -f 'src/core/ppp/nm-ppp-manager.c' || echo '$(srcdir)/'`src/core/ppp/nm-ppp-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ppp/$(DEPDIR)/libnm_ppp_plugin_la-nm-ppp-manager.Tpo src/core/ppp/$(DEPDIR)/libnm_ppp_plugin_la-nm-ppp-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ppp/nm-ppp-manager.c' object='src/core/ppp/libnm_ppp_plugin_la-nm-ppp-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo `test -f 'shared/nm-glib-aux/nm-secret-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-secret-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ppp_libnm_ppp_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ppp/libnm_ppp_plugin_la-nm-ppp-manager.lo `test -f 'src/core/ppp/nm-ppp-manager.c' || echo '$(srcdir)/'`src/core/ppp/nm-ppp-manager.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo: shared/nm-glib-aux/nm-shared-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo `test -f 'shared/nm-glib-aux/nm-shared-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-shared-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-shared-utils.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/ppp/nm_pppd_plugin_la-nm-pppd-plugin.lo: src/core/ppp/nm-pppd-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ppp_nm_pppd_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ppp/nm_pppd_plugin_la-nm-pppd-plugin.lo -MD -MP -MF src/core/ppp/$(DEPDIR)/nm_pppd_plugin_la-nm-pppd-plugin.Tpo -c -o src/core/ppp/nm_pppd_plugin_la-nm-pppd-plugin.lo `test -f 'src/core/ppp/nm-pppd-plugin.c' || echo '$(srcdir)/'`src/core/ppp/nm-pppd-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ppp/$(DEPDIR)/nm_pppd_plugin_la-nm-pppd-plugin.Tpo src/core/ppp/$(DEPDIR)/nm_pppd_plugin_la-nm-pppd-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ppp/nm-pppd-plugin.c' object='src/core/ppp/nm_pppd_plugin_la-nm-pppd-plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo `test -f 'shared/nm-glib-aux/nm-shared-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-shared-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ppp_nm_pppd_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ppp/nm_pppd_plugin_la-nm-pppd-plugin.lo `test -f 'src/core/ppp/nm-pppd-plugin.c' || echo '$(srcdir)/'`src/core/ppp/nm-pppd-plugin.c -shared/nm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo: shared/nm-glib-aux/nm-time-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo -MD -MP -MF shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Tpo -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo `test -f 'shared/nm-glib-aux/nm-time-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-time-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Tpo shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/nm-time-utils.c' object='shared/nm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.lo: src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c' object='src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo `test -f 'shared/nm-glib-aux/nm-time-utils.c' || echo '$(srcdir)/'`shared/nm-glib-aux/nm-time-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c -shared/nm-log-core/libnm_log_core_la-nm-logging.lo: shared/nm-log-core/nm-logging.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_log_core_libnm_log_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-log-core/libnm_log_core_la-nm-logging.lo -MD -MP -MF shared/nm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Tpo -c -o shared/nm-log-core/libnm_log_core_la-nm-logging.lo `test -f 'shared/nm-log-core/nm-logging.c' || echo '$(srcdir)/'`shared/nm-log-core/nm-logging.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Tpo shared/nm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-log-core/nm-logging.c' object='shared/nm-log-core/libnm_log_core_la-nm-logging.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.lo: src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c' object='src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_log_core_libnm_log_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-log-core/libnm_log_core_la-nm-logging.lo `test -f 'shared/nm-log-core/nm-logging.c' || echo '$(srcdir)/'`shared/nm-log-core/nm-logging.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c -shared/nm-platform/libnm_platform_la-nm-netlink.lo: shared/nm-platform/nm-netlink.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-platform/libnm_platform_la-nm-netlink.lo -MD -MP -MF shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Tpo -c -o shared/nm-platform/libnm_platform_la-nm-netlink.lo `test -f 'shared/nm-platform/nm-netlink.c' || echo '$(srcdir)/'`shared/nm-platform/nm-netlink.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Tpo shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-platform/nm-netlink.c' object='shared/nm-platform/libnm_platform_la-nm-netlink.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/ifcfg-rh/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.lo: src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnmdbus_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c' object='src/core/settings/plugins/ifcfg-rh/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-platform/libnm_platform_la-nm-netlink.lo `test -f 'shared/nm-platform/nm-netlink.c' || echo '$(srcdir)/'`shared/nm-platform/nm-netlink.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnmdbus_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c -shared/nm-platform/libnm_platform_la-nm-platform-utils.lo: shared/nm-platform/nm-platform-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-platform/libnm_platform_la-nm-platform-utils.lo -MD -MP -MF shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Tpo -c -o shared/nm-platform/libnm_platform_la-nm-platform-utils.lo `test -f 'shared/nm-platform/nm-platform-utils.c' || echo '$(srcdir)/'`shared/nm-platform/nm-platform-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Tpo shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-platform/nm-platform-utils.c' object='shared/nm-platform/libnm_platform_la-nm-platform-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-shvar.lo: src/core/settings/plugins/ifcfg-rh/shvar.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-shvar.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-shvar.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-shvar.lo `test -f 'src/core/settings/plugins/ifcfg-rh/shvar.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/shvar.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-shvar.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-shvar.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/shvar.c' object='src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-shvar.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-platform/libnm_platform_la-nm-platform-utils.lo `test -f 'shared/nm-platform/nm-platform-utils.c' || echo '$(srcdir)/'`shared/nm-platform/nm-platform-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-shvar.lo `test -f 'src/core/settings/plugins/ifcfg-rh/shvar.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/shvar.c -shared/nm-platform/libnm_platform_la-nmp-netns.lo: shared/nm-platform/nmp-netns.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-platform/libnm_platform_la-nmp-netns.lo -MD -MP -MF shared/nm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Tpo -c -o shared/nm-platform/libnm_platform_la-nmp-netns.lo `test -f 'shared/nm-platform/nmp-netns.c' || echo '$(srcdir)/'`shared/nm-platform/nmp-netns.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Tpo shared/nm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-platform/nmp-netns.c' object='shared/nm-platform/libnm_platform_la-nmp-netns.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.lo: src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c' object='src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-platform/libnm_platform_la-nmp-netns.lo `test -f 'shared/nm-platform/nmp-netns.c' || echo '$(srcdir)/'`shared/nm-platform/nmp-netns.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c -shared/nm-std-aux/libnm_std_aux_la-c-list-util.lo: shared/nm-std-aux/c-list-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_std_aux_libnm_std_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-std-aux/libnm_std_aux_la-c-list-util.lo -MD -MP -MF shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Tpo -c -o shared/nm-std-aux/libnm_std_aux_la-c-list-util.lo `test -f 'shared/nm-std-aux/c-list-util.c' || echo '$(srcdir)/'`shared/nm-std-aux/c-list-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Tpo shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-std-aux/c-list-util.c' object='shared/nm-std-aux/libnm_std_aux_la-c-list-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.lo: src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c' object='src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_std_aux_libnm_std_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-std-aux/libnm_std_aux_la-c-list-util.lo `test -f 'shared/nm-std-aux/c-list-util.c' || echo '$(srcdir)/'`shared/nm-std-aux/c-list-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c -shared/nm-std-aux/libnm_std_aux_la-nm-std-utils.lo: shared/nm-std-aux/nm-std-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_std_aux_libnm_std_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-std-aux/libnm_std_aux_la-nm-std-utils.lo -MD -MP -MF shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Tpo -c -o shared/nm-std-aux/libnm_std_aux_la-nm-std-utils.lo `test -f 'shared/nm-std-aux/nm-std-utils.c' || echo '$(srcdir)/'`shared/nm-std-aux/nm-std-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Tpo shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-std-aux/nm-std-utils.c' object='shared/nm-std-aux/libnm_std_aux_la-nm-std-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.lo: src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c' object='src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_std_aux_libnm_std_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-std-aux/libnm_std_aux_la-nm-std-utils.lo `test -f 'shared/nm-std-aux/nm-std-utils.c' || echo '$(srcdir)/'`shared/nm-std-aux/nm-std-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c -shared/nm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo: shared/nm-udev-aux/nm-udev-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_udev_aux_libnm_udev_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo -MD -MP -MF shared/nm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Tpo -c -o shared/nm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo `test -f 'shared/nm-udev-aux/nm-udev-utils.c' || echo '$(srcdir)/'`shared/nm-udev-aux/nm-udev-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Tpo shared/nm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-udev-aux/nm-udev-utils.c' object='shared/nm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/ifupdown/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.lo: src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifupdown/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.lo -MD -MP -MF src/core/settings/plugins/ifupdown/$(DEPDIR)/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.Tpo -c -o src/core/settings/plugins/ifupdown/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifupdown/$(DEPDIR)/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.Tpo src/core/settings/plugins/ifupdown/$(DEPDIR)/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c' object='src/core/settings/plugins/ifupdown/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_udev_aux_libnm_udev_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo `test -f 'shared/nm-udev-aux/nm-udev-utils.c' || echo '$(srcdir)/'`shared/nm-udev-aux/nm-udev-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifupdown/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c -shared/systemd/libnm_systemd_logging_stub_la-nm-logging-stub.lo: shared/systemd/nm-logging-stub.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_logging_stub_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/libnm_systemd_logging_stub_la-nm-logging-stub.lo -MD -MP -MF shared/systemd/$(DEPDIR)/libnm_systemd_logging_stub_la-nm-logging-stub.Tpo -c -o shared/systemd/libnm_systemd_logging_stub_la-nm-logging-stub.lo `test -f 'shared/systemd/nm-logging-stub.c' || echo '$(srcdir)/'`shared/systemd/nm-logging-stub.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/$(DEPDIR)/libnm_systemd_logging_stub_la-nm-logging-stub.Tpo shared/systemd/$(DEPDIR)/libnm_systemd_logging_stub_la-nm-logging-stub.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/nm-logging-stub.c' object='shared/systemd/libnm_systemd_logging_stub_la-nm-logging-stub.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.lo: src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.lo -MD -MP -MF src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.Tpo -c -o src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.Tpo src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c' object='src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_logging_stub_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/libnm_systemd_logging_stub_la-nm-logging-stub.lo `test -f 'shared/systemd/nm-logging-stub.c' || echo '$(srcdir)/'`shared/systemd/nm-logging-stub.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c -shared/systemd/libnm_systemd_shared_la-nm-sd-utils-shared.lo: shared/systemd/nm-sd-utils-shared.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/libnm_systemd_shared_la-nm-sd-utils-shared.lo -MD -MP -MF shared/systemd/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Tpo -c -o shared/systemd/libnm_systemd_shared_la-nm-sd-utils-shared.lo `test -f 'shared/systemd/nm-sd-utils-shared.c' || echo '$(srcdir)/'`shared/systemd/nm-sd-utils-shared.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Tpo shared/systemd/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/nm-sd-utils-shared.c' object='shared/systemd/libnm_systemd_shared_la-nm-sd-utils-shared.lo' libtool=yes @AMDEPBACKSLASH@ +src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo: src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo -MD -MP -MF src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-parser.Tpo -c -o src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-parser.Tpo src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c' object='src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/libnm_systemd_shared_la-nm-sd-utils-shared.lo `test -f 'shared/systemd/nm-sd-utils-shared.c' || echo '$(srcdir)/'`shared/systemd/nm-sd-utils-shared.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c -shared/systemd/src/basic/libnm_systemd_shared_la-alloc-util.lo: shared/systemd/src/basic/alloc-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-alloc-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-alloc-util.lo `test -f 'shared/systemd/src/basic/alloc-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/alloc-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/alloc-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-alloc-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-base/libnm_base_la-nm-ethtool-base.lo: src/libnm-base/nm-ethtool-base.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_base_libnm_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-base/libnm_base_la-nm-ethtool-base.lo -MD -MP -MF src/libnm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Tpo -c -o src/libnm-base/libnm_base_la-nm-ethtool-base.lo `test -f 'src/libnm-base/nm-ethtool-base.c' || echo '$(srcdir)/'`src/libnm-base/nm-ethtool-base.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Tpo src/libnm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-base/nm-ethtool-base.c' object='src/libnm-base/libnm_base_la-nm-ethtool-base.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-alloc-util.lo `test -f 'shared/systemd/src/basic/alloc-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/alloc-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_base_libnm_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-base/libnm_base_la-nm-ethtool-base.lo `test -f 'src/libnm-base/nm-ethtool-base.c' || echo '$(srcdir)/'`src/libnm-base/nm-ethtool-base.c -shared/systemd/src/basic/libnm_systemd_shared_la-env-file.lo: shared/systemd/src/basic/env-file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-env-file.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-env-file.lo `test -f 'shared/systemd/src/basic/env-file.c' || echo '$(srcdir)/'`shared/systemd/src/basic/env-file.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/env-file.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-env-file.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-base/libnm_base_la-nm-net-aux.lo: src/libnm-base/nm-net-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_base_libnm_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-base/libnm_base_la-nm-net-aux.lo -MD -MP -MF src/libnm-base/$(DEPDIR)/libnm_base_la-nm-net-aux.Tpo -c -o src/libnm-base/libnm_base_la-nm-net-aux.lo `test -f 'src/libnm-base/nm-net-aux.c' || echo '$(srcdir)/'`src/libnm-base/nm-net-aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-base/$(DEPDIR)/libnm_base_la-nm-net-aux.Tpo src/libnm-base/$(DEPDIR)/libnm_base_la-nm-net-aux.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-base/nm-net-aux.c' object='src/libnm-base/libnm_base_la-nm-net-aux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-env-file.lo `test -f 'shared/systemd/src/basic/env-file.c' || echo '$(srcdir)/'`shared/systemd/src/basic/env-file.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_base_libnm_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-base/libnm_base_la-nm-net-aux.lo `test -f 'src/libnm-base/nm-net-aux.c' || echo '$(srcdir)/'`src/libnm-base/nm-net-aux.c -shared/systemd/src/basic/libnm_systemd_shared_la-env-util.lo: shared/systemd/src/basic/env-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-env-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-env-util.lo `test -f 'shared/systemd/src/basic/env-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/env-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/env-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-env-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-aux-extern/libnm_client_aux_extern_la-nm-libnm-aux.lo: src/libnm-client-aux-extern/nm-libnm-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_aux_extern_libnm_client_aux_extern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-aux-extern/libnm_client_aux_extern_la-nm-libnm-aux.lo -MD -MP -MF src/libnm-client-aux-extern/$(DEPDIR)/libnm_client_aux_extern_la-nm-libnm-aux.Tpo -c -o src/libnm-client-aux-extern/libnm_client_aux_extern_la-nm-libnm-aux.lo `test -f 'src/libnm-client-aux-extern/nm-libnm-aux.c' || echo '$(srcdir)/'`src/libnm-client-aux-extern/nm-libnm-aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-aux-extern/$(DEPDIR)/libnm_client_aux_extern_la-nm-libnm-aux.Tpo src/libnm-client-aux-extern/$(DEPDIR)/libnm_client_aux_extern_la-nm-libnm-aux.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-aux-extern/nm-libnm-aux.c' object='src/libnm-client-aux-extern/libnm_client_aux_extern_la-nm-libnm-aux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-env-util.lo `test -f 'shared/systemd/src/basic/env-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/env-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_aux_extern_libnm_client_aux_extern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-aux-extern/libnm_client_aux_extern_la-nm-libnm-aux.lo `test -f 'src/libnm-client-aux-extern/nm-libnm-aux.c' || echo '$(srcdir)/'`src/libnm-client-aux-extern/nm-libnm-aux.c -shared/systemd/src/basic/libnm_systemd_shared_la-escape.lo: shared/systemd/src/basic/escape.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-escape.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-escape.lo `test -f 'shared/systemd/src/basic/escape.c' || echo '$(srcdir)/'`shared/systemd/src/basic/escape.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/escape.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-escape.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-client.lo: src/libnm-client-impl/nm-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-client.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-client.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-client.lo `test -f 'src/libnm-client-impl/nm-client.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-client.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-client.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-client.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-escape.lo `test -f 'shared/systemd/src/basic/escape.c' || echo '$(srcdir)/'`shared/systemd/src/basic/escape.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-client.lo `test -f 'src/libnm-client-impl/nm-client.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-client.c -shared/systemd/src/basic/libnm_systemd_shared_la-ether-addr-util.lo: shared/systemd/src/basic/ether-addr-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-ether-addr-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-ether-addr-util.lo `test -f 'shared/systemd/src/basic/ether-addr-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/ether-addr-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/ether-addr-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-ether-addr-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-object.lo: src/libnm-client-impl/nm-object.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-object.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-object.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-object.lo `test -f 'src/libnm-client-impl/nm-object.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-object.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-object.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-object.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-object.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-object.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-ether-addr-util.lo `test -f 'shared/systemd/src/basic/ether-addr-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/ether-addr-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-object.lo `test -f 'src/libnm-client-impl/nm-object.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-object.c -shared/systemd/src/basic/libnm_systemd_shared_la-extract-word.lo: shared/systemd/src/basic/extract-word.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-extract-word.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-extract-word.lo `test -f 'shared/systemd/src/basic/extract-word.c' || echo '$(srcdir)/'`shared/systemd/src/basic/extract-word.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/extract-word.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-extract-word.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device.lo: src/libnm-client-impl/nm-device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device.lo `test -f 'src/libnm-client-impl/nm-device.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-extract-word.lo `test -f 'shared/systemd/src/basic/extract-word.c' || echo '$(srcdir)/'`shared/systemd/src/basic/extract-word.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device.lo `test -f 'src/libnm-client-impl/nm-device.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device.c -shared/systemd/src/basic/libnm_systemd_shared_la-fd-util.lo: shared/systemd/src/basic/fd-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-fd-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-fd-util.lo `test -f 'shared/systemd/src/basic/fd-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/fd-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/fd-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-fd-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-active-connection.lo: src/libnm-client-impl/nm-active-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-active-connection.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-active-connection.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-active-connection.lo `test -f 'src/libnm-client-impl/nm-active-connection.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-active-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-active-connection.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-active-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-active-connection.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-active-connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-fd-util.lo `test -f 'shared/systemd/src/basic/fd-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/fd-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-active-connection.lo `test -f 'src/libnm-client-impl/nm-active-connection.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-active-connection.c -shared/systemd/src/basic/libnm_systemd_shared_la-fileio.lo: shared/systemd/src/basic/fileio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-fileio.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-fileio.lo `test -f 'shared/systemd/src/basic/fileio.c' || echo '$(srcdir)/'`shared/systemd/src/basic/fileio.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/fileio.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-fileio.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-access-point.lo: src/libnm-client-impl/nm-access-point.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-access-point.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-access-point.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-access-point.lo `test -f 'src/libnm-client-impl/nm-access-point.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-access-point.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-access-point.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-access-point.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-access-point.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-access-point.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-fileio.lo `test -f 'shared/systemd/src/basic/fileio.c' || echo '$(srcdir)/'`shared/systemd/src/basic/fileio.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-access-point.lo `test -f 'src/libnm-client-impl/nm-access-point.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-access-point.c -shared/systemd/src/basic/libnm_systemd_shared_la-format-util.lo: shared/systemd/src/basic/format-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-format-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-format-util.lo `test -f 'shared/systemd/src/basic/format-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/format-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/format-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-format-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-checkpoint.lo: src/libnm-client-impl/nm-checkpoint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-checkpoint.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-checkpoint.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-checkpoint.lo `test -f 'src/libnm-client-impl/nm-checkpoint.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-checkpoint.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-checkpoint.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-checkpoint.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-checkpoint.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-checkpoint.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-format-util.lo `test -f 'shared/systemd/src/basic/format-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/format-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-checkpoint.lo `test -f 'src/libnm-client-impl/nm-checkpoint.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-checkpoint.c -shared/systemd/src/basic/libnm_systemd_shared_la-fs-util.lo: shared/systemd/src/basic/fs-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-fs-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-fs-util.lo `test -f 'shared/systemd/src/basic/fs-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/fs-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/fs-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-fs-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-dbus-helpers.lo: src/libnm-client-impl/nm-dbus-helpers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-dbus-helpers.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dbus-helpers.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-dbus-helpers.lo `test -f 'src/libnm-client-impl/nm-dbus-helpers.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-dbus-helpers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dbus-helpers.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dbus-helpers.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-dbus-helpers.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-dbus-helpers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-fs-util.lo `test -f 'shared/systemd/src/basic/fs-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/fs-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-dbus-helpers.lo `test -f 'src/libnm-client-impl/nm-dbus-helpers.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-dbus-helpers.c -shared/systemd/src/basic/libnm_systemd_shared_la-hash-funcs.lo: shared/systemd/src/basic/hash-funcs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-hash-funcs.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-hash-funcs.lo `test -f 'shared/systemd/src/basic/hash-funcs.c' || echo '$(srcdir)/'`shared/systemd/src/basic/hash-funcs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/hash-funcs.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-hash-funcs.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-6lowpan.lo: src/libnm-client-impl/nm-device-6lowpan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-6lowpan.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-6lowpan.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-6lowpan.lo `test -f 'src/libnm-client-impl/nm-device-6lowpan.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-6lowpan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-6lowpan.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-6lowpan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-6lowpan.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-6lowpan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-hash-funcs.lo `test -f 'shared/systemd/src/basic/hash-funcs.c' || echo '$(srcdir)/'`shared/systemd/src/basic/hash-funcs.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-6lowpan.lo `test -f 'src/libnm-client-impl/nm-device-6lowpan.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-6lowpan.c -shared/systemd/src/basic/libnm_systemd_shared_la-hashmap.lo: shared/systemd/src/basic/hashmap.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-hashmap.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-hashmap.lo `test -f 'shared/systemd/src/basic/hashmap.c' || echo '$(srcdir)/'`shared/systemd/src/basic/hashmap.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/hashmap.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-hashmap.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-adsl.lo: src/libnm-client-impl/nm-device-adsl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-adsl.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-adsl.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-adsl.lo `test -f 'src/libnm-client-impl/nm-device-adsl.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-adsl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-adsl.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-adsl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-adsl.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-adsl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-hashmap.lo `test -f 'shared/systemd/src/basic/hashmap.c' || echo '$(srcdir)/'`shared/systemd/src/basic/hashmap.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-adsl.lo `test -f 'src/libnm-client-impl/nm-device-adsl.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-adsl.c -shared/systemd/src/basic/libnm_systemd_shared_la-hexdecoct.lo: shared/systemd/src/basic/hexdecoct.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-hexdecoct.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-hexdecoct.lo `test -f 'shared/systemd/src/basic/hexdecoct.c' || echo '$(srcdir)/'`shared/systemd/src/basic/hexdecoct.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/hexdecoct.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-hexdecoct.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-bond.lo: src/libnm-client-impl/nm-device-bond.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-bond.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bond.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-bond.lo `test -f 'src/libnm-client-impl/nm-device-bond.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-bond.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bond.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bond.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-bond.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-bond.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-hexdecoct.lo `test -f 'shared/systemd/src/basic/hexdecoct.c' || echo '$(srcdir)/'`shared/systemd/src/basic/hexdecoct.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-bond.lo `test -f 'src/libnm-client-impl/nm-device-bond.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-bond.c -shared/systemd/src/basic/libnm_systemd_shared_la-hostname-util.lo: shared/systemd/src/basic/hostname-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-hostname-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-hostname-util.lo `test -f 'shared/systemd/src/basic/hostname-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/hostname-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/hostname-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-hostname-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-bridge.lo: src/libnm-client-impl/nm-device-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-bridge.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bridge.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-bridge.lo `test -f 'src/libnm-client-impl/nm-device-bridge.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bridge.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bridge.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-bridge.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-bridge.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-hostname-util.lo `test -f 'shared/systemd/src/basic/hostname-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/hostname-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-bridge.lo `test -f 'src/libnm-client-impl/nm-device-bridge.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-bridge.c -shared/systemd/src/basic/libnm_systemd_shared_la-in-addr-util.lo: shared/systemd/src/basic/in-addr-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-in-addr-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-in-addr-util.lo `test -f 'shared/systemd/src/basic/in-addr-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/in-addr-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/in-addr-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-in-addr-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-bt.lo: src/libnm-client-impl/nm-device-bt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-bt.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bt.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-bt.lo `test -f 'src/libnm-client-impl/nm-device-bt.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-bt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bt.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-bt.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-bt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-in-addr-util.lo `test -f 'shared/systemd/src/basic/in-addr-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/in-addr-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-bt.lo `test -f 'src/libnm-client-impl/nm-device-bt.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-bt.c -shared/systemd/src/basic/libnm_systemd_shared_la-io-util.lo: shared/systemd/src/basic/io-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-io-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-io-util.lo `test -f 'shared/systemd/src/basic/io-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/io-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/io-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-io-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-dummy.lo: src/libnm-client-impl/nm-device-dummy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-dummy.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-dummy.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-dummy.lo `test -f 'src/libnm-client-impl/nm-device-dummy.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-dummy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-dummy.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-dummy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-dummy.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-dummy.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-io-util.lo `test -f 'shared/systemd/src/basic/io-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/io-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-dummy.lo `test -f 'src/libnm-client-impl/nm-device-dummy.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-dummy.c -shared/systemd/src/basic/libnm_systemd_shared_la-memory-util.lo: shared/systemd/src/basic/memory-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-memory-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-memory-util.lo `test -f 'shared/systemd/src/basic/memory-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/memory-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/memory-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-memory-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-ethernet.lo: src/libnm-client-impl/nm-device-ethernet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-ethernet.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ethernet.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ethernet.lo `test -f 'src/libnm-client-impl/nm-device-ethernet.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ethernet.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ethernet.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ethernet.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-ethernet.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-ethernet.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-memory-util.lo `test -f 'shared/systemd/src/basic/memory-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/memory-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ethernet.lo `test -f 'src/libnm-client-impl/nm-device-ethernet.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ethernet.c -shared/systemd/src/basic/libnm_systemd_shared_la-mempool.lo: shared/systemd/src/basic/mempool.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-mempool.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-mempool.lo `test -f 'shared/systemd/src/basic/mempool.c' || echo '$(srcdir)/'`shared/systemd/src/basic/mempool.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/mempool.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-mempool.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-generic.lo: src/libnm-client-impl/nm-device-generic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-generic.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-generic.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-generic.lo `test -f 'src/libnm-client-impl/nm-device-generic.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-generic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-generic.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-generic.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-generic.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-generic.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-mempool.lo `test -f 'shared/systemd/src/basic/mempool.c' || echo '$(srcdir)/'`shared/systemd/src/basic/mempool.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-generic.lo `test -f 'src/libnm-client-impl/nm-device-generic.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-generic.c -shared/systemd/src/basic/libnm_systemd_shared_la-parse-util.lo: shared/systemd/src/basic/parse-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-parse-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-parse-util.lo `test -f 'shared/systemd/src/basic/parse-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/parse-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/parse-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-parse-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-infiniband.lo: src/libnm-client-impl/nm-device-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-infiniband.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-infiniband.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-infiniband.lo `test -f 'src/libnm-client-impl/nm-device-infiniband.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-infiniband.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-infiniband.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-infiniband.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-infiniband.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-parse-util.lo `test -f 'shared/systemd/src/basic/parse-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/parse-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-infiniband.lo `test -f 'src/libnm-client-impl/nm-device-infiniband.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-infiniband.c -shared/systemd/src/basic/libnm_systemd_shared_la-path-util.lo: shared/systemd/src/basic/path-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-path-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-path-util.lo `test -f 'shared/systemd/src/basic/path-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/path-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/path-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-path-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-ip-tunnel.lo: src/libnm-client-impl/nm-device-ip-tunnel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-ip-tunnel.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ip-tunnel.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ip-tunnel.lo `test -f 'src/libnm-client-impl/nm-device-ip-tunnel.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ip-tunnel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ip-tunnel.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ip-tunnel.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-ip-tunnel.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-ip-tunnel.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-path-util.lo `test -f 'shared/systemd/src/basic/path-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/path-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ip-tunnel.lo `test -f 'src/libnm-client-impl/nm-device-ip-tunnel.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ip-tunnel.c -shared/systemd/src/basic/libnm_systemd_shared_la-prioq.lo: shared/systemd/src/basic/prioq.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-prioq.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-prioq.lo `test -f 'shared/systemd/src/basic/prioq.c' || echo '$(srcdir)/'`shared/systemd/src/basic/prioq.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/prioq.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-prioq.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-macsec.lo: src/libnm-client-impl/nm-device-macsec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-macsec.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macsec.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-macsec.lo `test -f 'src/libnm-client-impl/nm-device-macsec.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-macsec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macsec.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macsec.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-macsec.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-macsec.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-prioq.lo `test -f 'shared/systemd/src/basic/prioq.c' || echo '$(srcdir)/'`shared/systemd/src/basic/prioq.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-macsec.lo `test -f 'src/libnm-client-impl/nm-device-macsec.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-macsec.c -shared/systemd/src/basic/libnm_systemd_shared_la-process-util.lo: shared/systemd/src/basic/process-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-process-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-process-util.lo `test -f 'shared/systemd/src/basic/process-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/process-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/process-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-process-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-macvlan.lo: src/libnm-client-impl/nm-device-macvlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-macvlan.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macvlan.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-macvlan.lo `test -f 'src/libnm-client-impl/nm-device-macvlan.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-macvlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macvlan.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macvlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-macvlan.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-macvlan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-process-util.lo `test -f 'shared/systemd/src/basic/process-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/process-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-macvlan.lo `test -f 'src/libnm-client-impl/nm-device-macvlan.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-macvlan.c -shared/systemd/src/basic/libnm_systemd_shared_la-random-util.lo: shared/systemd/src/basic/random-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-random-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-random-util.lo `test -f 'shared/systemd/src/basic/random-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/random-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/random-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-random-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-modem.lo: src/libnm-client-impl/nm-device-modem.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-modem.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-modem.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-modem.lo `test -f 'src/libnm-client-impl/nm-device-modem.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-modem.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-modem.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-modem.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-modem.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-modem.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-random-util.lo `test -f 'shared/systemd/src/basic/random-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/random-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-modem.lo `test -f 'src/libnm-client-impl/nm-device-modem.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-modem.c -shared/systemd/src/basic/libnm_systemd_shared_la-ratelimit.lo: shared/systemd/src/basic/ratelimit.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-ratelimit.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-ratelimit.lo `test -f 'shared/systemd/src/basic/ratelimit.c' || echo '$(srcdir)/'`shared/systemd/src/basic/ratelimit.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/ratelimit.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-ratelimit.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-olpc-mesh.lo: src/libnm-client-impl/nm-device-olpc-mesh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-olpc-mesh.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-olpc-mesh.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-olpc-mesh.lo `test -f 'src/libnm-client-impl/nm-device-olpc-mesh.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-olpc-mesh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-olpc-mesh.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-olpc-mesh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-olpc-mesh.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-olpc-mesh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-ratelimit.lo `test -f 'shared/systemd/src/basic/ratelimit.c' || echo '$(srcdir)/'`shared/systemd/src/basic/ratelimit.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-olpc-mesh.lo `test -f 'src/libnm-client-impl/nm-device-olpc-mesh.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-olpc-mesh.c -shared/systemd/src/basic/libnm_systemd_shared_la-signal-util.lo: shared/systemd/src/basic/signal-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-signal-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-signal-util.lo `test -f 'shared/systemd/src/basic/signal-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/signal-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/signal-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-signal-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-bridge.lo: src/libnm-client-impl/nm-device-ovs-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-bridge.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-bridge.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-bridge.lo `test -f 'src/libnm-client-impl/nm-device-ovs-bridge.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ovs-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-bridge.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-bridge.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-ovs-bridge.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-bridge.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-signal-util.lo `test -f 'shared/systemd/src/basic/signal-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/signal-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-bridge.lo `test -f 'src/libnm-client-impl/nm-device-ovs-bridge.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ovs-bridge.c -shared/systemd/src/basic/libnm_systemd_shared_la-socket-util.lo: shared/systemd/src/basic/socket-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-socket-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-socket-util.lo `test -f 'shared/systemd/src/basic/socket-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/socket-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/socket-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-socket-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-interface.lo: src/libnm-client-impl/nm-device-ovs-interface.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-interface.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-interface.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-interface.lo `test -f 'src/libnm-client-impl/nm-device-ovs-interface.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ovs-interface.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-interface.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-interface.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-ovs-interface.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-interface.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-socket-util.lo `test -f 'shared/systemd/src/basic/socket-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/socket-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-interface.lo `test -f 'src/libnm-client-impl/nm-device-ovs-interface.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ovs-interface.c -shared/systemd/src/basic/libnm_systemd_shared_la-stat-util.lo: shared/systemd/src/basic/stat-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-stat-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-stat-util.lo `test -f 'shared/systemd/src/basic/stat-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/stat-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/stat-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-stat-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-port.lo: src/libnm-client-impl/nm-device-ovs-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-port.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-port.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-port.lo `test -f 'src/libnm-client-impl/nm-device-ovs-port.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ovs-port.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-port.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-port.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-ovs-port.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-port.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-stat-util.lo `test -f 'shared/systemd/src/basic/stat-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/stat-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ovs-port.lo `test -f 'src/libnm-client-impl/nm-device-ovs-port.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ovs-port.c -shared/systemd/src/basic/libnm_systemd_shared_la-string-table.lo: shared/systemd/src/basic/string-table.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-string-table.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-string-table.lo `test -f 'shared/systemd/src/basic/string-table.c' || echo '$(srcdir)/'`shared/systemd/src/basic/string-table.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/string-table.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-string-table.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-ppp.lo: src/libnm-client-impl/nm-device-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-ppp.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ppp.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ppp.lo `test -f 'src/libnm-client-impl/nm-device-ppp.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ppp.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ppp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-ppp.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-ppp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-string-table.lo `test -f 'shared/systemd/src/basic/string-table.c' || echo '$(srcdir)/'`shared/systemd/src/basic/string-table.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-ppp.lo `test -f 'src/libnm-client-impl/nm-device-ppp.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-ppp.c -shared/systemd/src/basic/libnm_systemd_shared_la-string-util.lo: shared/systemd/src/basic/string-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-string-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-string-util.lo `test -f 'shared/systemd/src/basic/string-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/string-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/string-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-string-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-team.lo: src/libnm-client-impl/nm-device-team.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-team.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-team.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-team.lo `test -f 'src/libnm-client-impl/nm-device-team.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-team.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-team.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-team.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-team.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-team.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-string-util.lo `test -f 'shared/systemd/src/basic/string-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/string-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-team.lo `test -f 'src/libnm-client-impl/nm-device-team.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-team.c -shared/systemd/src/basic/libnm_systemd_shared_la-strv.lo: shared/systemd/src/basic/strv.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-strv.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-strv.lo `test -f 'shared/systemd/src/basic/strv.c' || echo '$(srcdir)/'`shared/systemd/src/basic/strv.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/strv.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-strv.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-tun.lo: src/libnm-client-impl/nm-device-tun.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-tun.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-tun.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-tun.lo `test -f 'src/libnm-client-impl/nm-device-tun.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-tun.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-tun.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-tun.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-tun.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-tun.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-strv.lo `test -f 'shared/systemd/src/basic/strv.c' || echo '$(srcdir)/'`shared/systemd/src/basic/strv.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-tun.lo `test -f 'src/libnm-client-impl/nm-device-tun.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-tun.c -shared/systemd/src/basic/libnm_systemd_shared_la-strxcpyx.lo: shared/systemd/src/basic/strxcpyx.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-strxcpyx.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-strxcpyx.lo `test -f 'shared/systemd/src/basic/strxcpyx.c' || echo '$(srcdir)/'`shared/systemd/src/basic/strxcpyx.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/strxcpyx.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-strxcpyx.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-veth.lo: src/libnm-client-impl/nm-device-veth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-veth.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-veth.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-veth.lo `test -f 'src/libnm-client-impl/nm-device-veth.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-veth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-veth.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-veth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-veth.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-veth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-strxcpyx.lo `test -f 'shared/systemd/src/basic/strxcpyx.c' || echo '$(srcdir)/'`shared/systemd/src/basic/strxcpyx.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-veth.lo `test -f 'src/libnm-client-impl/nm-device-veth.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-veth.c -shared/systemd/src/basic/libnm_systemd_shared_la-time-util.lo: shared/systemd/src/basic/time-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-time-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-time-util.lo `test -f 'shared/systemd/src/basic/time-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/time-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/time-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-time-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-vlan.lo: src/libnm-client-impl/nm-device-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-vlan.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vlan.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-vlan.lo `test -f 'src/libnm-client-impl/nm-device-vlan.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vlan.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-vlan.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-vlan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-time-util.lo `test -f 'shared/systemd/src/basic/time-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/time-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-vlan.lo `test -f 'src/libnm-client-impl/nm-device-vlan.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-vlan.c -shared/systemd/src/basic/libnm_systemd_shared_la-tmpfile-util.lo: shared/systemd/src/basic/tmpfile-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-tmpfile-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-tmpfile-util.lo `test -f 'shared/systemd/src/basic/tmpfile-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/tmpfile-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/tmpfile-util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-tmpfile-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-vrf.lo: src/libnm-client-impl/nm-device-vrf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-vrf.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vrf.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-vrf.lo `test -f 'src/libnm-client-impl/nm-device-vrf.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-vrf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vrf.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vrf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-vrf.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-vrf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-tmpfile-util.lo `test -f 'shared/systemd/src/basic/tmpfile-util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/tmpfile-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-vrf.lo `test -f 'src/libnm-client-impl/nm-device-vrf.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-vrf.c -shared/systemd/src/basic/libnm_systemd_shared_la-utf8.lo: shared/systemd/src/basic/utf8.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-utf8.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-utf8.lo `test -f 'shared/systemd/src/basic/utf8.c' || echo '$(srcdir)/'`shared/systemd/src/basic/utf8.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/utf8.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-utf8.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-vxlan.lo: src/libnm-client-impl/nm-device-vxlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-vxlan.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vxlan.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-vxlan.lo `test -f 'src/libnm-client-impl/nm-device-vxlan.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-vxlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vxlan.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vxlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-vxlan.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-vxlan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-utf8.lo `test -f 'shared/systemd/src/basic/utf8.c' || echo '$(srcdir)/'`shared/systemd/src/basic/utf8.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-vxlan.lo `test -f 'src/libnm-client-impl/nm-device-vxlan.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-vxlan.c -shared/systemd/src/basic/libnm_systemd_shared_la-util.lo: shared/systemd/src/basic/util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/basic/libnm_systemd_shared_la-util.lo -MD -MP -MF shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Tpo -c -o shared/systemd/src/basic/libnm_systemd_shared_la-util.lo `test -f 'shared/systemd/src/basic/util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Tpo shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/basic/util.c' object='shared/systemd/src/basic/libnm_systemd_shared_la-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi-p2p.lo: src/libnm-client-impl/nm-device-wifi-p2p.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi-p2p.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi-p2p.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi-p2p.lo `test -f 'src/libnm-client-impl/nm-device-wifi-p2p.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-wifi-p2p.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi-p2p.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi-p2p.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-wifi-p2p.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi-p2p.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/basic/libnm_systemd_shared_la-util.lo `test -f 'shared/systemd/src/basic/util.c' || echo '$(srcdir)/'`shared/systemd/src/basic/util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi-p2p.lo `test -f 'src/libnm-client-impl/nm-device-wifi-p2p.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-wifi-p2p.c -shared/systemd/src/shared/libnm_systemd_shared_la-dns-domain.lo: shared/systemd/src/shared/dns-domain.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/shared/libnm_systemd_shared_la-dns-domain.lo -MD -MP -MF shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Tpo -c -o shared/systemd/src/shared/libnm_systemd_shared_la-dns-domain.lo `test -f 'shared/systemd/src/shared/dns-domain.c' || echo '$(srcdir)/'`shared/systemd/src/shared/dns-domain.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Tpo shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/shared/dns-domain.c' object='shared/systemd/src/shared/libnm_systemd_shared_la-dns-domain.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi.lo: src/libnm-client-impl/nm-device-wifi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi.lo `test -f 'src/libnm-client-impl/nm-device-wifi.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-wifi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-wifi.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/shared/libnm_systemd_shared_la-dns-domain.lo `test -f 'shared/systemd/src/shared/dns-domain.c' || echo '$(srcdir)/'`shared/systemd/src/shared/dns-domain.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-wifi.lo `test -f 'src/libnm-client-impl/nm-device-wifi.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-wifi.c -shared/systemd/src/shared/libnm_systemd_shared_la-web-util.lo: shared/systemd/src/shared/web-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/systemd/src/shared/libnm_systemd_shared_la-web-util.lo -MD -MP -MF shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Tpo -c -o shared/systemd/src/shared/libnm_systemd_shared_la-web-util.lo `test -f 'shared/systemd/src/shared/web-util.c' || echo '$(srcdir)/'`shared/systemd/src/shared/web-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Tpo shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/systemd/src/shared/web-util.c' object='shared/systemd/src/shared/libnm_systemd_shared_la-web-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-wimax.lo: src/libnm-client-impl/nm-device-wimax.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-wimax.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wimax.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-wimax.lo `test -f 'src/libnm-client-impl/nm-device-wimax.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-wimax.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wimax.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wimax.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-wimax.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-wimax.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_systemd_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/systemd/src/shared/libnm_systemd_shared_la-web-util.lo `test -f 'shared/systemd/src/shared/web-util.c' || echo '$(srcdir)/'`shared/systemd/src/shared/web-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-wimax.lo `test -f 'src/libnm-client-impl/nm-device-wimax.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-wimax.c -src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo: src/core/devices/adsl/nm-atm-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_adsl_libnm_device_plugin_adsl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo -MD -MP -MF src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-atm-manager.Tpo -c -o src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo `test -f 'src/core/devices/adsl/nm-atm-manager.c' || echo '$(srcdir)/'`src/core/devices/adsl/nm-atm-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-atm-manager.Tpo src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-atm-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/adsl/nm-atm-manager.c' object='src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-wireguard.lo: src/libnm-client-impl/nm-device-wireguard.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-wireguard.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wireguard.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-wireguard.lo `test -f 'src/libnm-client-impl/nm-device-wireguard.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-wireguard.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wireguard.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wireguard.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-wireguard.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-wireguard.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_adsl_libnm_device_plugin_adsl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-atm-manager.lo `test -f 'src/core/devices/adsl/nm-atm-manager.c' || echo '$(srcdir)/'`src/core/devices/adsl/nm-atm-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-wireguard.lo `test -f 'src/libnm-client-impl/nm-device-wireguard.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-wireguard.c -src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-device-adsl.lo: src/core/devices/adsl/nm-device-adsl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_adsl_libnm_device_plugin_adsl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-device-adsl.lo -MD -MP -MF src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-device-adsl.Tpo -c -o src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-device-adsl.lo `test -f 'src/core/devices/adsl/nm-device-adsl.c' || echo '$(srcdir)/'`src/core/devices/adsl/nm-device-adsl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-device-adsl.Tpo src/core/devices/adsl/$(DEPDIR)/libnm_device_plugin_adsl_la-nm-device-adsl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/adsl/nm-device-adsl.c' object='src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-device-adsl.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-device-wpan.lo: src/libnm-client-impl/nm-device-wpan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-device-wpan.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wpan.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-wpan.lo `test -f 'src/libnm-client-impl/nm-device-wpan.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-wpan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wpan.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wpan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-device-wpan.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-device-wpan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_adsl_libnm_device_plugin_adsl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/adsl/libnm_device_plugin_adsl_la-nm-device-adsl.lo `test -f 'src/core/devices/adsl/nm-device-adsl.c' || echo '$(srcdir)/'`src/core/devices/adsl/nm-device-adsl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-device-wpan.lo `test -f 'src/libnm-client-impl/nm-device-wpan.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-device-wpan.c -src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo: src/core/devices/bluetooth/nm-bt-error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo -MD -MP -MF src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bt-error.Tpo -c -o src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo `test -f 'src/core/devices/bluetooth/nm-bt-error.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bt-error.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bt-error.Tpo src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bt-error.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/nm-bt-error.c' object='src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-dhcp-config.lo: src/libnm-client-impl/nm-dhcp-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-dhcp-config.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp-config.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-dhcp-config.lo `test -f 'src/libnm-client-impl/nm-dhcp-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-dhcp-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp-config.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-dhcp-config.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-dhcp-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bt-error.lo `test -f 'src/core/devices/bluetooth/nm-bt-error.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bt-error.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-dhcp-config.lo `test -f 'src/libnm-client-impl/nm-dhcp-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-dhcp-config.c -src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo: src/core/devices/bluetooth/nm-bluez5-dun.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo -MD -MP -MF src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bluez5-dun.Tpo -c -o src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo `test -f 'src/core/devices/bluetooth/nm-bluez5-dun.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bluez5-dun.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bluez5-dun.Tpo src/core/devices/bluetooth/$(DEPDIR)/libnm_bluetooth_utils_la-nm-bluez5-dun.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/nm-bluez5-dun.c' object='src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-dhcp4-config.lo: src/libnm-client-impl/nm-dhcp4-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-dhcp4-config.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp4-config.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-dhcp4-config.lo `test -f 'src/libnm-client-impl/nm-dhcp4-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-dhcp4-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp4-config.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp4-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-dhcp4-config.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-dhcp4-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/libnm_bluetooth_utils_la-nm-bluez5-dun.lo `test -f 'src/core/devices/bluetooth/nm-bluez5-dun.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bluez5-dun.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-dhcp4-config.lo `test -f 'src/libnm-client-impl/nm-dhcp4-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-dhcp4-config.c -src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-bluez-manager.lo: src/core/devices/bluetooth/nm-bluez-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-bluez-manager.lo -MD -MP -MF src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-bluez-manager.Tpo -c -o src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-bluez-manager.lo `test -f 'src/core/devices/bluetooth/nm-bluez-manager.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bluez-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-bluez-manager.Tpo src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-bluez-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/nm-bluez-manager.c' object='src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-bluez-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-dhcp6-config.lo: src/libnm-client-impl/nm-dhcp6-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-dhcp6-config.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp6-config.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-dhcp6-config.lo `test -f 'src/libnm-client-impl/nm-dhcp6-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-dhcp6-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp6-config.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp6-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-dhcp6-config.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-dhcp6-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-bluez-manager.lo `test -f 'src/core/devices/bluetooth/nm-bluez-manager.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-bluez-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-dhcp6-config.lo `test -f 'src/libnm-client-impl/nm-dhcp6-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-dhcp6-config.c -src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-device-bt.lo: src/core/devices/bluetooth/nm-device-bt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-device-bt.lo -MD -MP -MF src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-device-bt.Tpo -c -o src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-device-bt.lo `test -f 'src/core/devices/bluetooth/nm-device-bt.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-device-bt.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-device-bt.Tpo src/core/devices/bluetooth/$(DEPDIR)/libnm_device_plugin_bluetooth_la-nm-device-bt.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/nm-device-bt.c' object='src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-device-bt.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-dns-manager.lo: src/libnm-client-impl/nm-dns-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-dns-manager.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dns-manager.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-dns-manager.lo `test -f 'src/libnm-client-impl/nm-dns-manager.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-dns-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dns-manager.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dns-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-dns-manager.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-dns-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/libnm_device_plugin_bluetooth_la-nm-device-bt.lo `test -f 'src/core/devices/bluetooth/nm-device-bt.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/nm-device-bt.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-dns-manager.lo `test -f 'src/libnm-client-impl/nm-dns-manager.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-dns-manager.c -src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovsdb.lo: src/core/devices/ovs/nm-ovsdb.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovsdb.lo -MD -MP -MF src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovsdb.Tpo -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovsdb.lo `test -f 'src/core/devices/ovs/nm-ovsdb.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-ovsdb.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovsdb.Tpo src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovsdb.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/ovs/nm-ovsdb.c' object='src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovsdb.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-ip-config.lo: src/libnm-client-impl/nm-ip-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-ip-config.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip-config.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-ip-config.lo `test -f 'src/libnm-client-impl/nm-ip-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-ip-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip-config.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-ip-config.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-ip-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovsdb.lo `test -f 'src/core/devices/ovs/nm-ovsdb.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-ovsdb.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-ip-config.lo `test -f 'src/libnm-client-impl/nm-ip-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-ip-config.c -src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovs-factory.lo: src/core/devices/ovs/nm-ovs-factory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovs-factory.lo -MD -MP -MF src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovs-factory.Tpo -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovs-factory.lo `test -f 'src/core/devices/ovs/nm-ovs-factory.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-ovs-factory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovs-factory.Tpo src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-ovs-factory.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/ovs/nm-ovs-factory.c' object='src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovs-factory.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-ip4-config.lo: src/libnm-client-impl/nm-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-ip4-config.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip4-config.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-ip4-config.lo `test -f 'src/libnm-client-impl/nm-ip4-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip4-config.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip4-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-ip4-config.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-ip4-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-ovs-factory.lo `test -f 'src/core/devices/ovs/nm-ovs-factory.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-ovs-factory.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-ip4-config.lo `test -f 'src/libnm-client-impl/nm-ip4-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-ip4-config.c -src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-interface.lo: src/core/devices/ovs/nm-device-ovs-interface.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-interface.lo -MD -MP -MF src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-interface.Tpo -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-interface.lo `test -f 'src/core/devices/ovs/nm-device-ovs-interface.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-interface.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-interface.Tpo src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-interface.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/ovs/nm-device-ovs-interface.c' object='src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-interface.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-ip6-config.lo: src/libnm-client-impl/nm-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-ip6-config.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip6-config.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-ip6-config.lo `test -f 'src/libnm-client-impl/nm-ip6-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip6-config.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip6-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-ip6-config.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-ip6-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-interface.lo `test -f 'src/core/devices/ovs/nm-device-ovs-interface.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-interface.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-ip6-config.lo `test -f 'src/libnm-client-impl/nm-ip6-config.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-ip6-config.c -src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-port.lo: src/core/devices/ovs/nm-device-ovs-port.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-port.lo -MD -MP -MF src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-port.Tpo -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-port.lo `test -f 'src/core/devices/ovs/nm-device-ovs-port.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-port.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-port.Tpo src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-port.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/ovs/nm-device-ovs-port.c' object='src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-port.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-libnm-utils.lo: src/libnm-client-impl/nm-libnm-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-libnm-utils.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-libnm-utils.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-libnm-utils.lo `test -f 'src/libnm-client-impl/nm-libnm-utils.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-libnm-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-libnm-utils.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-libnm-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-libnm-utils.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-libnm-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-port.lo `test -f 'src/core/devices/ovs/nm-device-ovs-port.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-port.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-libnm-utils.lo `test -f 'src/libnm-client-impl/nm-libnm-utils.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-libnm-utils.c -src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.lo: src/core/devices/ovs/nm-device-ovs-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.lo -MD -MP -MF src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.Tpo -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.lo `test -f 'src/core/devices/ovs/nm-device-ovs-bridge.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.Tpo src/core/devices/ovs/$(DEPDIR)/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/ovs/nm-device-ovs-bridge.c' object='src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-remote-connection.lo: src/libnm-client-impl/nm-remote-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-remote-connection.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-remote-connection.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-remote-connection.lo `test -f 'src/libnm-client-impl/nm-remote-connection.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-remote-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-remote-connection.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-remote-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-remote-connection.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-remote-connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/ovs/libnm_device_plugin_ovs_la-nm-device-ovs-bridge.lo `test -f 'src/core/devices/ovs/nm-device-ovs-bridge.c' || echo '$(srcdir)/'`src/core/devices/ovs/nm-device-ovs-bridge.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-remote-connection.lo `test -f 'src/libnm-client-impl/nm-remote-connection.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-remote-connection.c -src/core/devices/team/libnm_device_plugin_team_la-nm-team-factory.lo: src/core/devices/team/nm-team-factory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_team_libnm_device_plugin_team_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/team/libnm_device_plugin_team_la-nm-team-factory.lo -MD -MP -MF src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-team-factory.Tpo -c -o src/core/devices/team/libnm_device_plugin_team_la-nm-team-factory.lo `test -f 'src/core/devices/team/nm-team-factory.c' || echo '$(srcdir)/'`src/core/devices/team/nm-team-factory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-team-factory.Tpo src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-team-factory.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/team/nm-team-factory.c' object='src/core/devices/team/libnm_device_plugin_team_la-nm-team-factory.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-secret-agent-old.lo: src/libnm-client-impl/nm-secret-agent-old.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-secret-agent-old.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-secret-agent-old.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-secret-agent-old.lo `test -f 'src/libnm-client-impl/nm-secret-agent-old.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-secret-agent-old.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-secret-agent-old.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-secret-agent-old.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-secret-agent-old.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-secret-agent-old.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_team_libnm_device_plugin_team_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/team/libnm_device_plugin_team_la-nm-team-factory.lo `test -f 'src/core/devices/team/nm-team-factory.c' || echo '$(srcdir)/'`src/core/devices/team/nm-team-factory.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-secret-agent-old.lo `test -f 'src/libnm-client-impl/nm-secret-agent-old.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-secret-agent-old.c -src/core/devices/team/libnm_device_plugin_team_la-nm-device-team.lo: src/core/devices/team/nm-device-team.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_team_libnm_device_plugin_team_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/team/libnm_device_plugin_team_la-nm-device-team.lo -MD -MP -MF src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-device-team.Tpo -c -o src/core/devices/team/libnm_device_plugin_team_la-nm-device-team.lo `test -f 'src/core/devices/team/nm-device-team.c' || echo '$(srcdir)/'`src/core/devices/team/nm-device-team.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-device-team.Tpo src/core/devices/team/$(DEPDIR)/libnm_device_plugin_team_la-nm-device-team.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/team/nm-device-team.c' object='src/core/devices/team/libnm_device_plugin_team_la-nm-device-team.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-vpn-connection.lo: src/libnm-client-impl/nm-vpn-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-vpn-connection.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-connection.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-vpn-connection.lo `test -f 'src/libnm-client-impl/nm-vpn-connection.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-vpn-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-connection.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-vpn-connection.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-vpn-connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_team_libnm_device_plugin_team_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/team/libnm_device_plugin_team_la-nm-device-team.lo `test -f 'src/core/devices/team/nm-device-team.c' || echo '$(srcdir)/'`src/core/devices/team/nm-device-team.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-vpn-connection.lo `test -f 'src/libnm-client-impl/nm-vpn-connection.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-vpn-connection.c -src/core/devices/wifi/libnm_device_plugin_wifi_la-nm-wifi-factory.lo: src/core/devices/wifi/nm-wifi-factory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_device_plugin_wifi_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_device_plugin_wifi_la-nm-wifi-factory.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_device_plugin_wifi_la-nm-wifi-factory.Tpo -c -o src/core/devices/wifi/libnm_device_plugin_wifi_la-nm-wifi-factory.lo `test -f 'src/core/devices/wifi/nm-wifi-factory.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-factory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_device_plugin_wifi_la-nm-wifi-factory.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_device_plugin_wifi_la-nm-wifi-factory.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-wifi-factory.c' object='src/core/devices/wifi/libnm_device_plugin_wifi_la-nm-wifi-factory.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-vpn-editor.lo: src/libnm-client-impl/nm-vpn-editor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-vpn-editor.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-editor.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-vpn-editor.lo `test -f 'src/libnm-client-impl/nm-vpn-editor.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-vpn-editor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-editor.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-editor.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-vpn-editor.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-vpn-editor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_device_plugin_wifi_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_device_plugin_wifi_la-nm-wifi-factory.lo `test -f 'src/core/devices/wifi/nm-wifi-factory.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-factory.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-vpn-editor.lo `test -f 'src/libnm-client-impl/nm-vpn-editor.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-vpn-editor.c -src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo: src/core/devices/wifi/nm-device-olpc-mesh.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-olpc-mesh.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo `test -f 'src/core/devices/wifi/nm-device-olpc-mesh.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-olpc-mesh.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-olpc-mesh.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-olpc-mesh.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-device-olpc-mesh.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-vpn-plugin-old.lo: src/libnm-client-impl/nm-vpn-plugin-old.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-vpn-plugin-old.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-plugin-old.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-vpn-plugin-old.lo `test -f 'src/libnm-client-impl/nm-vpn-plugin-old.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-vpn-plugin-old.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-plugin-old.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-plugin-old.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-vpn-plugin-old.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-vpn-plugin-old.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-olpc-mesh.lo `test -f 'src/core/devices/wifi/nm-device-olpc-mesh.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-olpc-mesh.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-vpn-plugin-old.lo `test -f 'src/libnm-client-impl/nm-vpn-plugin-old.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-vpn-plugin-old.c -src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo: src/core/devices/wifi/nm-device-wifi-p2p.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi-p2p.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo `test -f 'src/core/devices/wifi/nm-device-wifi-p2p.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-wifi-p2p.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi-p2p.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi-p2p.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-device-wifi-p2p.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-vpn-service-plugin.lo: src/libnm-client-impl/nm-vpn-service-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-vpn-service-plugin.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-service-plugin.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-vpn-service-plugin.lo `test -f 'src/libnm-client-impl/nm-vpn-service-plugin.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-vpn-service-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-service-plugin.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-service-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-vpn-service-plugin.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-vpn-service-plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi-p2p.lo `test -f 'src/core/devices/wifi/nm-device-wifi-p2p.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-wifi-p2p.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-vpn-service-plugin.lo `test -f 'src/libnm-client-impl/nm-vpn-service-plugin.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-vpn-service-plugin.c -src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi.lo: src/core/devices/wifi/nm-device-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi.lo `test -f 'src/core/devices/wifi/nm-device-wifi.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-wifi.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-device-wifi.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-wifi-p2p-peer.lo: src/libnm-client-impl/nm-wifi-p2p-peer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-wifi-p2p-peer.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wifi-p2p-peer.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-wifi-p2p-peer.lo `test -f 'src/libnm-client-impl/nm-wifi-p2p-peer.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-wifi-p2p-peer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wifi-p2p-peer.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wifi-p2p-peer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-wifi-p2p-peer.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-wifi-p2p-peer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-wifi.lo `test -f 'src/core/devices/wifi/nm-device-wifi.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-wifi.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-wifi-p2p-peer.lo `test -f 'src/libnm-client-impl/nm-wifi-p2p-peer.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-wifi-p2p-peer.c -src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-ap.lo: src/core/devices/wifi/nm-wifi-ap.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-ap.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-ap.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-ap.lo `test -f 'src/core/devices/wifi/nm-wifi-ap.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-ap.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-ap.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-ap.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-wifi-ap.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-ap.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-impl/libnm_client_impl_la-nm-wimax-nsp.lo: src/libnm-client-impl/nm-wimax-nsp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/libnm_client_impl_la-nm-wimax-nsp.lo -MD -MP -MF src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wimax-nsp.Tpo -c -o src/libnm-client-impl/libnm_client_impl_la-nm-wimax-nsp.lo `test -f 'src/libnm-client-impl/nm-wimax-nsp.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-wimax-nsp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wimax-nsp.Tpo src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wimax-nsp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/nm-wimax-nsp.c' object='src/libnm-client-impl/libnm_client_impl_la-nm-wimax-nsp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-ap.lo `test -f 'src/core/devices/wifi/nm-wifi-ap.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-ap.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/libnm_client_impl_la-nm-wimax-nsp.lo `test -f 'src/libnm-client-impl/nm-wimax-nsp.c' || echo '$(srcdir)/'`src/libnm-client-impl/nm-wimax-nsp.c -src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo: src/core/devices/wifi/nm-wifi-common.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-common.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo `test -f 'src/core/devices/wifi/nm-wifi-common.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-common.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-common.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-common.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-wifi-common.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-public/libnm_client_impl_libnm_client_impl_la-nm-enum-types.lo: src/libnm-client-public/nm-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-public/libnm_client_impl_libnm_client_impl_la-nm-enum-types.lo -MD -MP -MF src/libnm-client-public/$(DEPDIR)/libnm_client_impl_libnm_client_impl_la-nm-enum-types.Tpo -c -o src/libnm-client-public/libnm_client_impl_libnm_client_impl_la-nm-enum-types.lo `test -f 'src/libnm-client-public/nm-enum-types.c' || echo '$(srcdir)/'`src/libnm-client-public/nm-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-public/$(DEPDIR)/libnm_client_impl_libnm_client_impl_la-nm-enum-types.Tpo src/libnm-client-public/$(DEPDIR)/libnm_client_impl_libnm_client_impl_la-nm-enum-types.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-public/nm-enum-types.c' object='src/libnm-client-public/libnm_client_impl_libnm_client_impl_la-nm-enum-types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-common.lo `test -f 'src/core/devices/wifi/nm-wifi-common.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-common.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_libnm_client_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-public/libnm_client_impl_libnm_client_impl_la-nm-enum-types.lo `test -f 'src/libnm-client-public/nm-enum-types.c' || echo '$(srcdir)/'`src/libnm-client-public/nm-enum-types.c -src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo: src/core/devices/wifi/nm-wifi-p2p-peer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-p2p-peer.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo `test -f 'src/core/devices/wifi/nm-wifi-p2p-peer.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-p2p-peer.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-p2p-peer.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-p2p-peer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-wifi-p2p-peer.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-client-test/libnm_client_test_la-nm-test-utils-impl.lo: src/libnm-client-test/nm-test-utils-impl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_test_libnm_client_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-test/libnm_client_test_la-nm-test-utils-impl.lo -MD -MP -MF src/libnm-client-test/$(DEPDIR)/libnm_client_test_la-nm-test-utils-impl.Tpo -c -o src/libnm-client-test/libnm_client_test_la-nm-test-utils-impl.lo `test -f 'src/libnm-client-test/nm-test-utils-impl.c' || echo '$(srcdir)/'`src/libnm-client-test/nm-test-utils-impl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-test/$(DEPDIR)/libnm_client_test_la-nm-test-utils-impl.Tpo src/libnm-client-test/$(DEPDIR)/libnm_client_test_la-nm-test-utils-impl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-test/nm-test-utils-impl.c' object='src/libnm-client-test/libnm_client_test_la-nm-test-utils-impl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-p2p-peer.lo `test -f 'src/core/devices/wifi/nm-wifi-p2p-peer.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-p2p-peer.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_test_libnm_client_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-test/libnm_client_test_la-nm-test-utils-impl.lo `test -f 'src/libnm-client-test/nm-test-utils-impl.c' || echo '$(srcdir)/'`src/libnm-client-test/nm-test-utils-impl.c -src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo: src/core/devices/wifi/nm-wifi-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-utils.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo `test -f 'src/core/devices/wifi/nm-wifi-utils.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-utils.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-wifi-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-wifi-utils.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-aux-extern/libnm_core_aux_extern_la-nm-libnm-core-aux.lo: src/libnm-core-aux-extern/nm-libnm-core-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_aux_extern_libnm_core_aux_extern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-aux-extern/libnm_core_aux_extern_la-nm-libnm-core-aux.lo -MD -MP -MF src/libnm-core-aux-extern/$(DEPDIR)/libnm_core_aux_extern_la-nm-libnm-core-aux.Tpo -c -o src/libnm-core-aux-extern/libnm_core_aux_extern_la-nm-libnm-core-aux.lo `test -f 'src/libnm-core-aux-extern/nm-libnm-core-aux.c' || echo '$(srcdir)/'`src/libnm-core-aux-extern/nm-libnm-core-aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-aux-extern/$(DEPDIR)/libnm_core_aux_extern_la-nm-libnm-core-aux.Tpo src/libnm-core-aux-extern/$(DEPDIR)/libnm_core_aux_extern_la-nm-libnm-core-aux.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-aux-extern/nm-libnm-core-aux.c' object='src/libnm-core-aux-extern/libnm_core_aux_extern_la-nm-libnm-core-aux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-wifi-utils.lo `test -f 'src/core/devices/wifi/nm-wifi-utils.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-wifi-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_aux_extern_libnm_core_aux_extern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-aux-extern/libnm_core_aux_extern_la-nm-libnm-core-aux.lo `test -f 'src/libnm-core-aux-extern/nm-libnm-core-aux.c' || echo '$(srcdir)/'`src/libnm-core-aux-extern/nm-libnm-core-aux.c -src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo: src/core/devices/wifi/nm-device-iwd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-iwd.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo `test -f 'src/core/devices/wifi/nm-device-iwd.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-iwd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-iwd.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-device-iwd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-device-iwd.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-auth-subject.lo: src/libnm-core-aux-intern/nm-auth-subject.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-auth-subject.lo -MD -MP -MF src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-auth-subject.Tpo -c -o src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-auth-subject.lo `test -f 'src/libnm-core-aux-intern/nm-auth-subject.c' || echo '$(srcdir)/'`src/libnm-core-aux-intern/nm-auth-subject.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-auth-subject.Tpo src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-auth-subject.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-aux-intern/nm-auth-subject.c' object='src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-auth-subject.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-device-iwd.lo `test -f 'src/core/devices/wifi/nm-device-iwd.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-device-iwd.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-auth-subject.lo `test -f 'src/libnm-core-aux-intern/nm-auth-subject.c' || echo '$(srcdir)/'`src/libnm-core-aux-intern/nm-auth-subject.c -src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo: src/core/devices/wifi/nm-iwd-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo -MD -MP -MF src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-iwd-manager.Tpo -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo `test -f 'src/core/devices/wifi/nm-iwd-manager.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-iwd-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-iwd-manager.Tpo src/core/devices/wifi/$(DEPDIR)/libnm_wifi_base_la-nm-iwd-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/nm-iwd-manager.c' object='src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-libnm-core-utils.lo: src/libnm-core-aux-intern/nm-libnm-core-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-libnm-core-utils.lo -MD -MP -MF src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-libnm-core-utils.Tpo -c -o src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-libnm-core-utils.lo `test -f 'src/libnm-core-aux-intern/nm-libnm-core-utils.c' || echo '$(srcdir)/'`src/libnm-core-aux-intern/nm-libnm-core-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-libnm-core-utils.Tpo src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-libnm-core-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-aux-intern/nm-libnm-core-utils.c' object='src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-libnm-core-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_libnm_wifi_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/libnm_wifi_base_la-nm-iwd-manager.lo `test -f 'src/core/devices/wifi/nm-iwd-manager.c' || echo '$(srcdir)/'`src/core/devices/wifi/nm-iwd-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_aux_intern_libnm_core_aux_intern_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-aux-intern/libnm_core_aux_intern_la-nm-libnm-core-utils.lo `test -f 'src/libnm-core-aux-intern/nm-libnm-core-utils.c' || echo '$(srcdir)/'`src/libnm-core-aux-intern/nm-libnm-core-utils.c -src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-wwan-factory.lo: src/core/devices/wwan/nm-wwan-factory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_device_plugin_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-wwan-factory.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-wwan-factory.Tpo -c -o src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-wwan-factory.lo `test -f 'src/core/devices/wwan/nm-wwan-factory.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-wwan-factory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-wwan-factory.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-wwan-factory.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-wwan-factory.c' object='src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-wwan-factory.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-6lowpan.lo: src/libnm-core-impl/nm-setting-6lowpan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-6lowpan.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-6lowpan.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-6lowpan.lo `test -f 'src/libnm-core-impl/nm-setting-6lowpan.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-6lowpan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-6lowpan.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-6lowpan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-6lowpan.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-6lowpan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_device_plugin_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-wwan-factory.lo `test -f 'src/core/devices/wwan/nm-wwan-factory.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-wwan-factory.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-6lowpan.lo `test -f 'src/libnm-core-impl/nm-setting-6lowpan.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-6lowpan.c -src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-device-modem.lo: src/core/devices/wwan/nm-device-modem.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_device_plugin_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-device-modem.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-device-modem.Tpo -c -o src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-device-modem.lo `test -f 'src/core/devices/wwan/nm-device-modem.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-device-modem.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-device-modem.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_device_plugin_wwan_la-nm-device-modem.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-device-modem.c' object='src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-device-modem.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-8021x.lo: src/libnm-core-impl/nm-setting-8021x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-8021x.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-8021x.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-8021x.lo `test -f 'src/libnm-core-impl/nm-setting-8021x.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-8021x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-8021x.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-8021x.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-8021x.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-8021x.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_device_plugin_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_device_plugin_wwan_la-nm-device-modem.lo `test -f 'src/core/devices/wwan/nm-device-modem.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-device-modem.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-8021x.lo `test -f 'src/libnm-core-impl/nm-setting-8021x.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-8021x.c -src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo: src/core/devices/wwan/nm-modem-broadband.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-broadband.Tpo -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo `test -f 'src/core/devices/wwan/nm-modem-broadband.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-broadband.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-broadband.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-broadband.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-modem-broadband.c' object='src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-adsl.lo: src/libnm-core-impl/nm-setting-adsl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-adsl.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-adsl.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-adsl.lo `test -f 'src/libnm-core-impl/nm-setting-adsl.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-adsl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-adsl.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-adsl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-adsl.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-adsl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-broadband.lo `test -f 'src/core/devices/wwan/nm-modem-broadband.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-broadband.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-adsl.lo `test -f 'src/libnm-core-impl/nm-setting-adsl.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-adsl.c -src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo: src/core/devices/wwan/nm-modem-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-manager.Tpo -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo `test -f 'src/core/devices/wwan/nm-modem-manager.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-manager.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-modem-manager.c' object='src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-bluetooth.lo: src/libnm-core-impl/nm-setting-bluetooth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-bluetooth.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bluetooth.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-bluetooth.lo `test -f 'src/libnm-core-impl/nm-setting-bluetooth.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-bluetooth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bluetooth.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bluetooth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-bluetooth.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-bluetooth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-manager.lo `test -f 'src/core/devices/wwan/nm-modem-manager.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-bluetooth.lo `test -f 'src/libnm-core-impl/nm-setting-bluetooth.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-bluetooth.c -src/core/devices/wwan/libnm_wwan_la-nm-modem.lo: src/core/devices/wwan/nm-modem.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_wwan_la-nm-modem.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem.Tpo -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem.lo `test -f 'src/core/devices/wwan/nm-modem.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-modem.c' object='src/core/devices/wwan/libnm_wwan_la-nm-modem.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-bond.lo: src/libnm-core-impl/nm-setting-bond.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-bond.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bond.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-bond.lo `test -f 'src/libnm-core-impl/nm-setting-bond.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-bond.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bond.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bond.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-bond.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-bond.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem.lo `test -f 'src/core/devices/wwan/nm-modem.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-bond.lo `test -f 'src/libnm-core-impl/nm-setting-bond.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-bond.c -src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo: src/core/devices/wwan/nm-service-providers.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-service-providers.Tpo -c -o src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo `test -f 'src/core/devices/wwan/nm-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-service-providers.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-service-providers.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-service-providers.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-service-providers.c' object='src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge-port.lo: src/libnm-core-impl/nm-setting-bridge-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge-port.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge-port.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge-port.lo `test -f 'src/libnm-core-impl/nm-setting-bridge-port.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-bridge-port.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge-port.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge-port.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-bridge-port.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge-port.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_wwan_la-nm-service-providers.lo `test -f 'src/core/devices/wwan/nm-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-service-providers.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge-port.lo `test -f 'src/libnm-core-impl/nm-setting-bridge-port.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-bridge-port.c -src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo: src/core/devices/wwan/nm-modem-ofono.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-ofono.Tpo -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo `test -f 'src/core/devices/wwan/nm-modem-ofono.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-ofono.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-ofono.Tpo src/core/devices/wwan/$(DEPDIR)/libnm_wwan_la-nm-modem-ofono.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-modem-ofono.c' object='src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge.lo: src/libnm-core-impl/nm-setting-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge.lo `test -f 'src/libnm-core-impl/nm-setting-bridge.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-bridge.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_libnm_wwan_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/libnm_wwan_la-nm-modem-ofono.lo `test -f 'src/core/devices/wwan/nm-modem-ofono.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-modem-ofono.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-bridge.lo `test -f 'src/libnm-core-impl/nm-setting-bridge.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-bridge.c -src/core/initrd/libnmi_core_la-nmi-cmdline-reader.lo: src/core/initrd/nmi-cmdline-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/libnmi_core_la-nmi-cmdline-reader.lo -MD -MP -MF src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Tpo -c -o src/core/initrd/libnmi_core_la-nmi-cmdline-reader.lo `test -f 'src/core/initrd/nmi-cmdline-reader.c' || echo '$(srcdir)/'`src/core/initrd/nmi-cmdline-reader.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Tpo src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/nmi-cmdline-reader.c' object='src/core/initrd/libnmi_core_la-nmi-cmdline-reader.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-cdma.lo: src/libnm-core-impl/nm-setting-cdma.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-cdma.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-cdma.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-cdma.lo `test -f 'src/libnm-core-impl/nm-setting-cdma.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-cdma.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-cdma.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-cdma.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-cdma.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-cdma.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/libnmi_core_la-nmi-cmdline-reader.lo `test -f 'src/core/initrd/nmi-cmdline-reader.c' || echo '$(srcdir)/'`src/core/initrd/nmi-cmdline-reader.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-cdma.lo `test -f 'src/libnm-core-impl/nm-setting-cdma.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-cdma.c -src/core/initrd/libnmi_core_la-nmi-dt-reader.lo: src/core/initrd/nmi-dt-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/libnmi_core_la-nmi-dt-reader.lo -MD -MP -MF src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Tpo -c -o src/core/initrd/libnmi_core_la-nmi-dt-reader.lo `test -f 'src/core/initrd/nmi-dt-reader.c' || echo '$(srcdir)/'`src/core/initrd/nmi-dt-reader.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Tpo src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/nmi-dt-reader.c' object='src/core/initrd/libnmi_core_la-nmi-dt-reader.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-connection.lo: src/libnm-core-impl/nm-setting-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-connection.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-connection.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-connection.lo `test -f 'src/libnm-core-impl/nm-setting-connection.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-connection.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-connection.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/libnmi_core_la-nmi-dt-reader.lo `test -f 'src/core/initrd/nmi-dt-reader.c' || echo '$(srcdir)/'`src/core/initrd/nmi-dt-reader.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-connection.lo `test -f 'src/libnm-core-impl/nm-setting-connection.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-connection.c -src/core/initrd/libnmi_core_la-nmi-ibft-reader.lo: src/core/initrd/nmi-ibft-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/libnmi_core_la-nmi-ibft-reader.lo -MD -MP -MF src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Tpo -c -o src/core/initrd/libnmi_core_la-nmi-ibft-reader.lo `test -f 'src/core/initrd/nmi-ibft-reader.c' || echo '$(srcdir)/'`src/core/initrd/nmi-ibft-reader.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Tpo src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/nmi-ibft-reader.c' object='src/core/initrd/libnmi_core_la-nmi-ibft-reader.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-dcb.lo: src/libnm-core-impl/nm-setting-dcb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-dcb.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dcb.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-dcb.lo `test -f 'src/libnm-core-impl/nm-setting-dcb.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-dcb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dcb.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dcb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-dcb.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-dcb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/libnmi_core_la-nmi-ibft-reader.lo `test -f 'src/core/initrd/nmi-ibft-reader.c' || echo '$(srcdir)/'`src/core/initrd/nmi-ibft-reader.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-dcb.lo `test -f 'src/libnm-core-impl/nm-setting-dcb.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-dcb.c -src/core/libNetworkManager_la-nm-checkpoint.lo: src/core/nm-checkpoint.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-checkpoint.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint.Tpo -c -o src/core/libNetworkManager_la-nm-checkpoint.lo `test -f 'src/core/nm-checkpoint.c' || echo '$(srcdir)/'`src/core/nm-checkpoint.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-checkpoint.c' object='src/core/libNetworkManager_la-nm-checkpoint.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-dummy.lo: src/libnm-core-impl/nm-setting-dummy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-dummy.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dummy.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-dummy.lo `test -f 'src/libnm-core-impl/nm-setting-dummy.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-dummy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dummy.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dummy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-dummy.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-dummy.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-checkpoint.lo `test -f 'src/core/nm-checkpoint.c' || echo '$(srcdir)/'`src/core/nm-checkpoint.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-dummy.lo `test -f 'src/libnm-core-impl/nm-setting-dummy.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-dummy.c -src/core/libNetworkManager_la-nm-checkpoint-manager.lo: src/core/nm-checkpoint-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-checkpoint-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint-manager.Tpo -c -o src/core/libNetworkManager_la-nm-checkpoint-manager.lo `test -f 'src/core/nm-checkpoint-manager.c' || echo '$(srcdir)/'`src/core/nm-checkpoint-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-checkpoint-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-checkpoint-manager.c' object='src/core/libNetworkManager_la-nm-checkpoint-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ethtool.lo: src/libnm-core-impl/nm-setting-ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ethtool.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ethtool.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ethtool.lo `test -f 'src/libnm-core-impl/nm-setting-ethtool.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ethtool.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ethtool.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ethtool.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ethtool.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-checkpoint-manager.lo `test -f 'src/core/nm-checkpoint-manager.c' || echo '$(srcdir)/'`src/core/nm-checkpoint-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ethtool.lo `test -f 'src/libnm-core-impl/nm-setting-ethtool.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ethtool.c -src/core/devices/libNetworkManager_la-nm-acd-manager.lo: src/core/devices/nm-acd-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-acd-manager.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-acd-manager.Tpo -c -o src/core/devices/libNetworkManager_la-nm-acd-manager.lo `test -f 'src/core/devices/nm-acd-manager.c' || echo '$(srcdir)/'`src/core/devices/nm-acd-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-acd-manager.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-acd-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-acd-manager.c' object='src/core/devices/libNetworkManager_la-nm-acd-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-generic.lo: src/libnm-core-impl/nm-setting-generic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-generic.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-generic.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-generic.lo `test -f 'src/libnm-core-impl/nm-setting-generic.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-generic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-generic.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-generic.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-generic.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-generic.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-acd-manager.lo `test -f 'src/core/devices/nm-acd-manager.c' || echo '$(srcdir)/'`src/core/devices/nm-acd-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-generic.lo `test -f 'src/libnm-core-impl/nm-setting-generic.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-generic.c -src/core/devices/libNetworkManager_la-nm-lldp-listener.lo: src/core/devices/nm-lldp-listener.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-lldp-listener.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-lldp-listener.Tpo -c -o src/core/devices/libNetworkManager_la-nm-lldp-listener.lo `test -f 'src/core/devices/nm-lldp-listener.c' || echo '$(srcdir)/'`src/core/devices/nm-lldp-listener.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-lldp-listener.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-lldp-listener.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-lldp-listener.c' object='src/core/devices/libNetworkManager_la-nm-lldp-listener.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-gsm.lo: src/libnm-core-impl/nm-setting-gsm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-gsm.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-gsm.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-gsm.lo `test -f 'src/libnm-core-impl/nm-setting-gsm.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-gsm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-gsm.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-gsm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-gsm.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-gsm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-lldp-listener.lo `test -f 'src/core/devices/nm-lldp-listener.c' || echo '$(srcdir)/'`src/core/devices/nm-lldp-listener.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-gsm.lo `test -f 'src/libnm-core-impl/nm-setting-gsm.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-gsm.c -src/core/devices/libNetworkManager_la-nm-device.lo: src/core/devices/nm-device.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device.lo `test -f 'src/core/devices/nm-device.c' || echo '$(srcdir)/'`src/core/devices/nm-device.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device.c' object='src/core/devices/libNetworkManager_la-nm-device.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-hostname.lo: src/libnm-core-impl/nm-setting-hostname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-hostname.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-hostname.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-hostname.lo `test -f 'src/libnm-core-impl/nm-setting-hostname.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-hostname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-hostname.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-hostname.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-hostname.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-hostname.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device.lo `test -f 'src/core/devices/nm-device.c' || echo '$(srcdir)/'`src/core/devices/nm-device.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-hostname.lo `test -f 'src/libnm-core-impl/nm-setting-hostname.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-hostname.c -src/core/devices/libNetworkManager_la-nm-device-ethernet-utils.lo: src/core/devices/nm-device-ethernet-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-ethernet-utils.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet-utils.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-ethernet-utils.lo `test -f 'src/core/devices/nm-device-ethernet-utils.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ethernet-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet-utils.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-ethernet-utils.c' object='src/core/devices/libNetworkManager_la-nm-device-ethernet-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-infiniband.lo: src/libnm-core-impl/nm-setting-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-infiniband.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-infiniband.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-infiniband.lo `test -f 'src/libnm-core-impl/nm-setting-infiniband.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-infiniband.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-infiniband.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-infiniband.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-infiniband.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-ethernet-utils.lo `test -f 'src/core/devices/nm-device-ethernet-utils.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ethernet-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-infiniband.lo `test -f 'src/libnm-core-impl/nm-setting-infiniband.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-infiniband.c -src/core/devices/libNetworkManager_la-nm-device-factory.lo: src/core/devices/nm-device-factory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-factory.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-factory.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-factory.lo `test -f 'src/core/devices/nm-device-factory.c' || echo '$(srcdir)/'`src/core/devices/nm-device-factory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-factory.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-factory.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-factory.c' object='src/core/devices/libNetworkManager_la-nm-device-factory.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-config.lo: src/libnm-core-impl/nm-setting-ip-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-config.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-config.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-config.lo `test -f 'src/libnm-core-impl/nm-setting-ip-config.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ip-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-config.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ip-config.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-factory.lo `test -f 'src/core/devices/nm-device-factory.c' || echo '$(srcdir)/'`src/core/devices/nm-device-factory.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-config.lo `test -f 'src/libnm-core-impl/nm-setting-ip-config.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ip-config.c -src/core/devices/libNetworkManager_la-nm-device-generic.lo: src/core/devices/nm-device-generic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-generic.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-generic.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-generic.lo `test -f 'src/core/devices/nm-device-generic.c' || echo '$(srcdir)/'`src/core/devices/nm-device-generic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-generic.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-generic.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-generic.c' object='src/core/devices/libNetworkManager_la-nm-device-generic.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-tunnel.lo: src/libnm-core-impl/nm-setting-ip-tunnel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-tunnel.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-tunnel.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-tunnel.lo `test -f 'src/libnm-core-impl/nm-setting-ip-tunnel.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ip-tunnel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-tunnel.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-tunnel.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ip-tunnel.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-tunnel.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-generic.lo `test -f 'src/core/devices/nm-device-generic.c' || echo '$(srcdir)/'`src/core/devices/nm-device-generic.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip-tunnel.lo `test -f 'src/libnm-core-impl/nm-setting-ip-tunnel.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ip-tunnel.c -src/core/devices/libNetworkManager_la-nm-device-6lowpan.lo: src/core/devices/nm-device-6lowpan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-6lowpan.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-6lowpan.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-6lowpan.lo `test -f 'src/core/devices/nm-device-6lowpan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-6lowpan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-6lowpan.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-6lowpan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-6lowpan.c' object='src/core/devices/libNetworkManager_la-nm-device-6lowpan.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip4-config.lo: src/libnm-core-impl/nm-setting-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip4-config.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip4-config.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip4-config.lo `test -f 'src/libnm-core-impl/nm-setting-ip4-config.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip4-config.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip4-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ip4-config.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip4-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-6lowpan.lo `test -f 'src/core/devices/nm-device-6lowpan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-6lowpan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip4-config.lo `test -f 'src/libnm-core-impl/nm-setting-ip4-config.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ip4-config.c -src/core/devices/libNetworkManager_la-nm-device-bond.lo: src/core/devices/nm-device-bond.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-bond.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bond.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-bond.lo `test -f 'src/core/devices/nm-device-bond.c' || echo '$(srcdir)/'`src/core/devices/nm-device-bond.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bond.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bond.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-bond.c' object='src/core/devices/libNetworkManager_la-nm-device-bond.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip6-config.lo: src/libnm-core-impl/nm-setting-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip6-config.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip6-config.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip6-config.lo `test -f 'src/libnm-core-impl/nm-setting-ip6-config.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip6-config.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip6-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ip6-config.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip6-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-bond.lo `test -f 'src/core/devices/nm-device-bond.c' || echo '$(srcdir)/'`src/core/devices/nm-device-bond.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ip6-config.lo `test -f 'src/libnm-core-impl/nm-setting-ip6-config.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ip6-config.c -src/core/devices/libNetworkManager_la-nm-device-bridge.lo: src/core/devices/nm-device-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-bridge.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bridge.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-bridge.lo `test -f 'src/core/devices/nm-device-bridge.c' || echo '$(srcdir)/'`src/core/devices/nm-device-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bridge.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-bridge.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-bridge.c' object='src/core/devices/libNetworkManager_la-nm-device-bridge.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-macsec.lo: src/libnm-core-impl/nm-setting-macsec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-macsec.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macsec.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-macsec.lo `test -f 'src/libnm-core-impl/nm-setting-macsec.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-macsec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macsec.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macsec.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-macsec.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-macsec.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-bridge.lo `test -f 'src/core/devices/nm-device-bridge.c' || echo '$(srcdir)/'`src/core/devices/nm-device-bridge.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-macsec.lo `test -f 'src/libnm-core-impl/nm-setting-macsec.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-macsec.c -src/core/devices/libNetworkManager_la-nm-device-dummy.lo: src/core/devices/nm-device-dummy.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-dummy.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-dummy.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-dummy.lo `test -f 'src/core/devices/nm-device-dummy.c' || echo '$(srcdir)/'`src/core/devices/nm-device-dummy.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-dummy.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-dummy.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-dummy.c' object='src/core/devices/libNetworkManager_la-nm-device-dummy.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-macvlan.lo: src/libnm-core-impl/nm-setting-macvlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-macvlan.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macvlan.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-macvlan.lo `test -f 'src/libnm-core-impl/nm-setting-macvlan.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-macvlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macvlan.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macvlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-macvlan.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-macvlan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-dummy.lo `test -f 'src/core/devices/nm-device-dummy.c' || echo '$(srcdir)/'`src/core/devices/nm-device-dummy.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-macvlan.lo `test -f 'src/libnm-core-impl/nm-setting-macvlan.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-macvlan.c -src/core/devices/libNetworkManager_la-nm-device-ethernet.lo: src/core/devices/nm-device-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-ethernet.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-ethernet.lo `test -f 'src/core/devices/nm-device-ethernet.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ethernet.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-ethernet.c' object='src/core/devices/libNetworkManager_la-nm-device-ethernet.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-match.lo: src/libnm-core-impl/nm-setting-match.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-match.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-match.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-match.lo `test -f 'src/libnm-core-impl/nm-setting-match.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-match.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-match.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-match.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-match.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-match.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-ethernet.lo `test -f 'src/core/devices/nm-device-ethernet.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ethernet.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-match.lo `test -f 'src/libnm-core-impl/nm-setting-match.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-match.c -src/core/devices/libNetworkManager_la-nm-device-infiniband.lo: src/core/devices/nm-device-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-infiniband.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-infiniband.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-infiniband.lo `test -f 'src/core/devices/nm-device-infiniband.c' || echo '$(srcdir)/'`src/core/devices/nm-device-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-infiniband.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-infiniband.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-infiniband.c' object='src/core/devices/libNetworkManager_la-nm-device-infiniband.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-olpc-mesh.lo: src/libnm-core-impl/nm-setting-olpc-mesh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-olpc-mesh.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-olpc-mesh.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-olpc-mesh.lo `test -f 'src/libnm-core-impl/nm-setting-olpc-mesh.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-olpc-mesh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-olpc-mesh.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-olpc-mesh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-olpc-mesh.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-olpc-mesh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-infiniband.lo `test -f 'src/core/devices/nm-device-infiniband.c' || echo '$(srcdir)/'`src/core/devices/nm-device-infiniband.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-olpc-mesh.lo `test -f 'src/libnm-core-impl/nm-setting-olpc-mesh.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-olpc-mesh.c -src/core/devices/libNetworkManager_la-nm-device-ip-tunnel.lo: src/core/devices/nm-device-ip-tunnel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-ip-tunnel.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ip-tunnel.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-ip-tunnel.lo `test -f 'src/core/devices/nm-device-ip-tunnel.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ip-tunnel.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ip-tunnel.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ip-tunnel.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-ip-tunnel.c' object='src/core/devices/libNetworkManager_la-nm-device-ip-tunnel.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-bridge.lo: src/libnm-core-impl/nm-setting-ovs-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-bridge.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-bridge.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-bridge.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-bridge.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-bridge.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-bridge.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ovs-bridge.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-bridge.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-ip-tunnel.lo `test -f 'src/core/devices/nm-device-ip-tunnel.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ip-tunnel.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-bridge.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-bridge.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-bridge.c -src/core/devices/libNetworkManager_la-nm-device-macsec.lo: src/core/devices/nm-device-macsec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-macsec.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macsec.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-macsec.lo `test -f 'src/core/devices/nm-device-macsec.c' || echo '$(srcdir)/'`src/core/devices/nm-device-macsec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macsec.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macsec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-macsec.c' object='src/core/devices/libNetworkManager_la-nm-device-macsec.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-dpdk.lo: src/libnm-core-impl/nm-setting-ovs-dpdk.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-dpdk.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-dpdk.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-dpdk.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-dpdk.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-dpdk.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-dpdk.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-dpdk.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ovs-dpdk.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-dpdk.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-macsec.lo `test -f 'src/core/devices/nm-device-macsec.c' || echo '$(srcdir)/'`src/core/devices/nm-device-macsec.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-dpdk.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-dpdk.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-dpdk.c -src/core/devices/libNetworkManager_la-nm-device-macvlan.lo: src/core/devices/nm-device-macvlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-macvlan.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macvlan.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-macvlan.lo `test -f 'src/core/devices/nm-device-macvlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-macvlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macvlan.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-macvlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-macvlan.c' object='src/core/devices/libNetworkManager_la-nm-device-macvlan.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-external-ids.lo: src/libnm-core-impl/nm-setting-ovs-external-ids.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-external-ids.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-external-ids.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-external-ids.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-external-ids.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-external-ids.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-external-ids.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-external-ids.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ovs-external-ids.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-external-ids.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-macvlan.lo `test -f 'src/core/devices/nm-device-macvlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-macvlan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-external-ids.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-external-ids.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-external-ids.c -src/core/devices/libNetworkManager_la-nm-device-ppp.lo: src/core/devices/nm-device-ppp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-ppp.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ppp.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-ppp.lo `test -f 'src/core/devices/nm-device-ppp.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ppp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ppp.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-ppp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-ppp.c' object='src/core/devices/libNetworkManager_la-nm-device-ppp.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-interface.lo: src/libnm-core-impl/nm-setting-ovs-interface.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-interface.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-interface.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-interface.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-interface.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-interface.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-interface.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-interface.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ovs-interface.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-interface.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-ppp.lo `test -f 'src/core/devices/nm-device-ppp.c' || echo '$(srcdir)/'`src/core/devices/nm-device-ppp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-interface.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-interface.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-interface.c -src/core/devices/libNetworkManager_la-nm-device-tun.lo: src/core/devices/nm-device-tun.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-tun.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-tun.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-tun.lo `test -f 'src/core/devices/nm-device-tun.c' || echo '$(srcdir)/'`src/core/devices/nm-device-tun.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-tun.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-tun.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-tun.c' object='src/core/devices/libNetworkManager_la-nm-device-tun.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-patch.lo: src/libnm-core-impl/nm-setting-ovs-patch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-patch.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-patch.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-patch.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-patch.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-patch.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-patch.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-patch.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ovs-patch.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-patch.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-tun.lo `test -f 'src/core/devices/nm-device-tun.c' || echo '$(srcdir)/'`src/core/devices/nm-device-tun.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-patch.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-patch.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-patch.c -src/core/devices/libNetworkManager_la-nm-device-veth.lo: src/core/devices/nm-device-veth.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-veth.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-veth.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-veth.lo `test -f 'src/core/devices/nm-device-veth.c' || echo '$(srcdir)/'`src/core/devices/nm-device-veth.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-veth.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-veth.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-veth.c' object='src/core/devices/libNetworkManager_la-nm-device-veth.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-port.lo: src/libnm-core-impl/nm-setting-ovs-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-port.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-port.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-port.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-port.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-port.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-port.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-port.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ovs-port.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-port.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-veth.lo `test -f 'src/core/devices/nm-device-veth.c' || echo '$(srcdir)/'`src/core/devices/nm-device-veth.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ovs-port.lo `test -f 'src/libnm-core-impl/nm-setting-ovs-port.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ovs-port.c -src/core/devices/libNetworkManager_la-nm-device-vlan.lo: src/core/devices/nm-device-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-vlan.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vlan.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-vlan.lo `test -f 'src/core/devices/nm-device-vlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vlan.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-vlan.c' object='src/core/devices/libNetworkManager_la-nm-device-vlan.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-ppp.lo: src/libnm-core-impl/nm-setting-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-ppp.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ppp.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ppp.lo `test -f 'src/libnm-core-impl/nm-setting-ppp.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ppp.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ppp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-ppp.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-ppp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-vlan.lo `test -f 'src/core/devices/nm-device-vlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vlan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-ppp.lo `test -f 'src/libnm-core-impl/nm-setting-ppp.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-ppp.c -src/core/devices/libNetworkManager_la-nm-device-vrf.lo: src/core/devices/nm-device-vrf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-vrf.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vrf.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-vrf.lo `test -f 'src/core/devices/nm-device-vrf.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vrf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vrf.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vrf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-vrf.c' object='src/core/devices/libNetworkManager_la-nm-device-vrf.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-pppoe.lo: src/libnm-core-impl/nm-setting-pppoe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-pppoe.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-pppoe.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-pppoe.lo `test -f 'src/libnm-core-impl/nm-setting-pppoe.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-pppoe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-pppoe.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-pppoe.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-pppoe.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-pppoe.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-vrf.lo `test -f 'src/core/devices/nm-device-vrf.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vrf.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-pppoe.lo `test -f 'src/libnm-core-impl/nm-setting-pppoe.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-pppoe.c -src/core/devices/libNetworkManager_la-nm-device-vxlan.lo: src/core/devices/nm-device-vxlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-vxlan.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vxlan.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-vxlan.lo `test -f 'src/core/devices/nm-device-vxlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vxlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vxlan.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-vxlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-vxlan.c' object='src/core/devices/libNetworkManager_la-nm-device-vxlan.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-proxy.lo: src/libnm-core-impl/nm-setting-proxy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-proxy.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-proxy.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-proxy.lo `test -f 'src/libnm-core-impl/nm-setting-proxy.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-proxy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-proxy.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-proxy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-proxy.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-proxy.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-vxlan.lo `test -f 'src/core/devices/nm-device-vxlan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-vxlan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-proxy.lo `test -f 'src/libnm-core-impl/nm-setting-proxy.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-proxy.c -src/core/devices/libNetworkManager_la-nm-device-wireguard.lo: src/core/devices/nm-device-wireguard.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-wireguard.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wireguard.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-wireguard.lo `test -f 'src/core/devices/nm-device-wireguard.c' || echo '$(srcdir)/'`src/core/devices/nm-device-wireguard.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wireguard.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wireguard.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-wireguard.c' object='src/core/devices/libNetworkManager_la-nm-device-wireguard.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-serial.lo: src/libnm-core-impl/nm-setting-serial.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-serial.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-serial.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-serial.lo `test -f 'src/libnm-core-impl/nm-setting-serial.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-serial.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-serial.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-serial.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-serial.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-serial.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-wireguard.lo `test -f 'src/core/devices/nm-device-wireguard.c' || echo '$(srcdir)/'`src/core/devices/nm-device-wireguard.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-serial.lo `test -f 'src/libnm-core-impl/nm-setting-serial.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-serial.c -src/core/devices/libNetworkManager_la-nm-device-wpan.lo: src/core/devices/nm-device-wpan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/libNetworkManager_la-nm-device-wpan.lo -MD -MP -MF src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wpan.Tpo -c -o src/core/devices/libNetworkManager_la-nm-device-wpan.lo `test -f 'src/core/devices/nm-device-wpan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-wpan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wpan.Tpo src/core/devices/$(DEPDIR)/libNetworkManager_la-nm-device-wpan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/nm-device-wpan.c' object='src/core/devices/libNetworkManager_la-nm-device-wpan.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-sriov.lo: src/libnm-core-impl/nm-setting-sriov.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-sriov.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-sriov.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-sriov.lo `test -f 'src/libnm-core-impl/nm-setting-sriov.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-sriov.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-sriov.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-sriov.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-sriov.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-sriov.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/libNetworkManager_la-nm-device-wpan.lo `test -f 'src/core/devices/nm-device-wpan.c' || echo '$(srcdir)/'`src/core/devices/nm-device-wpan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-sriov.lo `test -f 'src/libnm-core-impl/nm-setting-sriov.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-sriov.c -src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcanon.lo: src/core/dhcp/nm-dhcp-dhcpcanon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcanon.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcanon.Tpo -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcanon.lo `test -f 'src/core/dhcp/nm-dhcp-dhcpcanon.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhcpcanon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcanon.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcanon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-dhcpcanon.c' object='src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcanon.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-tc-config.lo: src/libnm-core-impl/nm-setting-tc-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-tc-config.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tc-config.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-tc-config.lo `test -f 'src/libnm-core-impl/nm-setting-tc-config.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-tc-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tc-config.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tc-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-tc-config.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-tc-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcanon.lo `test -f 'src/core/dhcp/nm-dhcp-dhcpcanon.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhcpcanon.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-tc-config.lo `test -f 'src/libnm-core-impl/nm-setting-tc-config.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-tc-config.c -src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient.lo: src/core/dhcp/nm-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient.Tpo -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient.lo `test -f 'src/core/dhcp/nm-dhcp-dhclient.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-dhclient.c' object='src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-team-port.lo: src/libnm-core-impl/nm-setting-team-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-team-port.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team-port.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-team-port.lo `test -f 'src/libnm-core-impl/nm-setting-team-port.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-team-port.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team-port.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team-port.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-team-port.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-team-port.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient.lo `test -f 'src/core/dhcp/nm-dhcp-dhclient.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhclient.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-team-port.lo `test -f 'src/libnm-core-impl/nm-setting-team-port.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-team-port.c -src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcd.lo: src/core/dhcp/nm-dhcp-dhcpcd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcd.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcd.Tpo -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcd.lo `test -f 'src/core/dhcp/nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhcpcd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcd.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhcpcd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-dhcpcd.c' object='src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcd.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-team.lo: src/libnm-core-impl/nm-setting-team.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-team.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-team.lo `test -f 'src/libnm-core-impl/nm-setting-team.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-team.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-team.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-team.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhcpcd.lo `test -f 'src/core/dhcp/nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhcpcd.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-team.lo `test -f 'src/libnm-core-impl/nm-setting-team.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-team.c -src/core/dhcp/libNetworkManager_la-nm-dhcp-listener.lo: src/core/dhcp/nm-dhcp-listener.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManager_la-nm-dhcp-listener.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-listener.Tpo -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-listener.lo `test -f 'src/core/dhcp/nm-dhcp-listener.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-listener.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-listener.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-listener.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-listener.c' object='src/core/dhcp/libNetworkManager_la-nm-dhcp-listener.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-tun.lo: src/libnm-core-impl/nm-setting-tun.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-tun.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tun.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-tun.lo `test -f 'src/libnm-core-impl/nm-setting-tun.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-tun.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tun.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tun.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-tun.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-tun.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-listener.lo `test -f 'src/core/dhcp/nm-dhcp-listener.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-listener.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-tun.lo `test -f 'src/libnm-core-impl/nm-setting-tun.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-tun.c -src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient-utils.lo: src/core/dhcp/nm-dhcp-dhclient-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient-utils.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient-utils.Tpo -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient-utils.lo `test -f 'src/core/dhcp/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhclient-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient-utils.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManager_la-nm-dhcp-dhclient-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-dhclient-utils.c' object='src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-user.lo: src/libnm-core-impl/nm-setting-user.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-user.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-user.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-user.lo `test -f 'src/libnm-core-impl/nm-setting-user.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-user.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-user.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-user.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-user.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-user.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManager_la-nm-dhcp-dhclient-utils.lo `test -f 'src/core/dhcp/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-dhclient-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-user.lo `test -f 'src/libnm-core-impl/nm-setting-user.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-user.c -src/core/dns/libNetworkManager_la-nm-dns-manager.lo: src/core/dns/nm-dns-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dns/libNetworkManager_la-nm-dns-manager.lo -MD -MP -MF src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-manager.Tpo -c -o src/core/dns/libNetworkManager_la-nm-dns-manager.lo `test -f 'src/core/dns/nm-dns-manager.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-manager.Tpo src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dns/nm-dns-manager.c' object='src/core/dns/libNetworkManager_la-nm-dns-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-veth.lo: src/libnm-core-impl/nm-setting-veth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-veth.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-veth.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-veth.lo `test -f 'src/libnm-core-impl/nm-setting-veth.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-veth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-veth.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-veth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-veth.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-veth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dns/libNetworkManager_la-nm-dns-manager.lo `test -f 'src/core/dns/nm-dns-manager.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-veth.lo `test -f 'src/libnm-core-impl/nm-setting-veth.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-veth.c -src/core/dns/libNetworkManager_la-nm-dns-plugin.lo: src/core/dns/nm-dns-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dns/libNetworkManager_la-nm-dns-plugin.lo -MD -MP -MF src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-plugin.Tpo -c -o src/core/dns/libNetworkManager_la-nm-dns-plugin.lo `test -f 'src/core/dns/nm-dns-plugin.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-plugin.Tpo src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-plugin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dns/nm-dns-plugin.c' object='src/core/dns/libNetworkManager_la-nm-dns-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-vlan.lo: src/libnm-core-impl/nm-setting-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-vlan.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vlan.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-vlan.lo `test -f 'src/libnm-core-impl/nm-setting-vlan.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vlan.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-vlan.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-vlan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dns/libNetworkManager_la-nm-dns-plugin.lo `test -f 'src/core/dns/nm-dns-plugin.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-plugin.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-vlan.lo `test -f 'src/libnm-core-impl/nm-setting-vlan.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-vlan.c -src/core/dns/libNetworkManager_la-nm-dns-dnsmasq.lo: src/core/dns/nm-dns-dnsmasq.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dns/libNetworkManager_la-nm-dns-dnsmasq.lo -MD -MP -MF src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-dnsmasq.Tpo -c -o src/core/dns/libNetworkManager_la-nm-dns-dnsmasq.lo `test -f 'src/core/dns/nm-dns-dnsmasq.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-dnsmasq.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-dnsmasq.Tpo src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-dnsmasq.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dns/nm-dns-dnsmasq.c' object='src/core/dns/libNetworkManager_la-nm-dns-dnsmasq.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-vpn.lo: src/libnm-core-impl/nm-setting-vpn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-vpn.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vpn.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-vpn.lo `test -f 'src/libnm-core-impl/nm-setting-vpn.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-vpn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vpn.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vpn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-vpn.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-vpn.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dns/libNetworkManager_la-nm-dns-dnsmasq.lo `test -f 'src/core/dns/nm-dns-dnsmasq.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-dnsmasq.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-vpn.lo `test -f 'src/libnm-core-impl/nm-setting-vpn.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-vpn.c -src/core/dns/libNetworkManager_la-nm-dns-systemd-resolved.lo: src/core/dns/nm-dns-systemd-resolved.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dns/libNetworkManager_la-nm-dns-systemd-resolved.lo -MD -MP -MF src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-systemd-resolved.Tpo -c -o src/core/dns/libNetworkManager_la-nm-dns-systemd-resolved.lo `test -f 'src/core/dns/nm-dns-systemd-resolved.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-systemd-resolved.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-systemd-resolved.Tpo src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-systemd-resolved.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dns/nm-dns-systemd-resolved.c' object='src/core/dns/libNetworkManager_la-nm-dns-systemd-resolved.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-vrf.lo: src/libnm-core-impl/nm-setting-vrf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-vrf.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vrf.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-vrf.lo `test -f 'src/libnm-core-impl/nm-setting-vrf.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-vrf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vrf.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vrf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-vrf.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-vrf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dns/libNetworkManager_la-nm-dns-systemd-resolved.lo `test -f 'src/core/dns/nm-dns-systemd-resolved.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-systemd-resolved.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-vrf.lo `test -f 'src/libnm-core-impl/nm-setting-vrf.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-vrf.c -src/core/dns/libNetworkManager_la-nm-dns-unbound.lo: src/core/dns/nm-dns-unbound.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dns/libNetworkManager_la-nm-dns-unbound.lo -MD -MP -MF src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-unbound.Tpo -c -o src/core/dns/libNetworkManager_la-nm-dns-unbound.lo `test -f 'src/core/dns/nm-dns-unbound.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-unbound.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-unbound.Tpo src/core/dns/$(DEPDIR)/libNetworkManager_la-nm-dns-unbound.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dns/nm-dns-unbound.c' object='src/core/dns/libNetworkManager_la-nm-dns-unbound.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-vxlan.lo: src/libnm-core-impl/nm-setting-vxlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-vxlan.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vxlan.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-vxlan.lo `test -f 'src/libnm-core-impl/nm-setting-vxlan.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-vxlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vxlan.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vxlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-vxlan.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-vxlan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dns/libNetworkManager_la-nm-dns-unbound.lo `test -f 'src/core/dns/nm-dns-unbound.c' || echo '$(srcdir)/'`src/core/dns/nm-dns-unbound.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-vxlan.lo `test -f 'src/libnm-core-impl/nm-setting-vxlan.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-vxlan.c -src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-manager.lo: src/core/dnsmasq/nm-dnsmasq-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-manager.lo -MD -MP -MF src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-manager.Tpo -c -o src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-manager.lo `test -f 'src/core/dnsmasq/nm-dnsmasq-manager.c' || echo '$(srcdir)/'`src/core/dnsmasq/nm-dnsmasq-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-manager.Tpo src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dnsmasq/nm-dnsmasq-manager.c' object='src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wifi-p2p.lo: src/libnm-core-impl/nm-setting-wifi-p2p.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-wifi-p2p.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wifi-p2p.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wifi-p2p.lo `test -f 'src/libnm-core-impl/nm-setting-wifi-p2p.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wifi-p2p.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wifi-p2p.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wifi-p2p.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-wifi-p2p.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-wifi-p2p.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-manager.lo `test -f 'src/core/dnsmasq/nm-dnsmasq-manager.c' || echo '$(srcdir)/'`src/core/dnsmasq/nm-dnsmasq-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wifi-p2p.lo `test -f 'src/libnm-core-impl/nm-setting-wifi-p2p.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wifi-p2p.c -src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-utils.lo: src/core/dnsmasq/nm-dnsmasq-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-utils.lo -MD -MP -MF src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-utils.Tpo -c -o src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-utils.lo `test -f 'src/core/dnsmasq/nm-dnsmasq-utils.c' || echo '$(srcdir)/'`src/core/dnsmasq/nm-dnsmasq-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-utils.Tpo src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dnsmasq/nm-dnsmasq-utils.c' object='src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wimax.lo: src/libnm-core-impl/nm-setting-wimax.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-wimax.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wimax.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wimax.lo `test -f 'src/libnm-core-impl/nm-setting-wimax.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wimax.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wimax.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wimax.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-wimax.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-wimax.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dnsmasq/libNetworkManager_la-nm-dnsmasq-utils.lo `test -f 'src/core/dnsmasq/nm-dnsmasq-utils.c' || echo '$(srcdir)/'`src/core/dnsmasq/nm-dnsmasq-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wimax.lo `test -f 'src/libnm-core-impl/nm-setting-wimax.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wimax.c -src/core/ppp/libNetworkManager_la-nm-ppp-manager-call.lo: src/core/ppp/nm-ppp-manager-call.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ppp/libNetworkManager_la-nm-ppp-manager-call.lo -MD -MP -MF src/core/ppp/$(DEPDIR)/libNetworkManager_la-nm-ppp-manager-call.Tpo -c -o src/core/ppp/libNetworkManager_la-nm-ppp-manager-call.lo `test -f 'src/core/ppp/nm-ppp-manager-call.c' || echo '$(srcdir)/'`src/core/ppp/nm-ppp-manager-call.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ppp/$(DEPDIR)/libNetworkManager_la-nm-ppp-manager-call.Tpo src/core/ppp/$(DEPDIR)/libNetworkManager_la-nm-ppp-manager-call.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ppp/nm-ppp-manager-call.c' object='src/core/ppp/libNetworkManager_la-nm-ppp-manager-call.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wired.lo: src/libnm-core-impl/nm-setting-wired.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-wired.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wired.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wired.lo `test -f 'src/libnm-core-impl/nm-setting-wired.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wired.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wired.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wired.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-wired.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-wired.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ppp/libNetworkManager_la-nm-ppp-manager-call.lo `test -f 'src/core/ppp/nm-ppp-manager-call.c' || echo '$(srcdir)/'`src/core/ppp/nm-ppp-manager-call.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wired.lo `test -f 'src/libnm-core-impl/nm-setting-wired.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wired.c -src/core/libNetworkManager_la-nm-hostname-manager.lo: src/core/nm-hostname-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-hostname-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-hostname-manager.Tpo -c -o src/core/libNetworkManager_la-nm-hostname-manager.lo `test -f 'src/core/nm-hostname-manager.c' || echo '$(srcdir)/'`src/core/nm-hostname-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-hostname-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-hostname-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-hostname-manager.c' object='src/core/libNetworkManager_la-nm-hostname-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireguard.lo: src/libnm-core-impl/nm-setting-wireguard.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireguard.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireguard.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireguard.lo `test -f 'src/libnm-core-impl/nm-setting-wireguard.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wireguard.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireguard.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireguard.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-wireguard.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireguard.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireguard.lo `test -f 'src/libnm-core-impl/nm-setting-wireguard.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wireguard.c + +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless-security.lo: src/libnm-core-impl/nm-setting-wireless-security.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless-security.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless-security.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless-security.lo `test -f 'src/libnm-core-impl/nm-setting-wireless-security.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wireless-security.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless-security.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless-security.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-wireless-security.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless-security.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-hostname-manager.lo `test -f 'src/core/nm-hostname-manager.c' || echo '$(srcdir)/'`src/core/nm-hostname-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless-security.lo `test -f 'src/libnm-core-impl/nm-setting-wireless-security.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wireless-security.c -src/core/settings/libNetworkManager_la-nm-agent-manager.lo: src/core/settings/nm-agent-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-agent-manager.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-agent-manager.Tpo -c -o src/core/settings/libNetworkManager_la-nm-agent-manager.lo `test -f 'src/core/settings/nm-agent-manager.c' || echo '$(srcdir)/'`src/core/settings/nm-agent-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-agent-manager.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-agent-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-agent-manager.c' object='src/core/settings/libNetworkManager_la-nm-agent-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless.lo: src/libnm-core-impl/nm-setting-wireless.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless.lo `test -f 'src/libnm-core-impl/nm-setting-wireless.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wireless.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-wireless.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-agent-manager.lo `test -f 'src/core/settings/nm-agent-manager.c' || echo '$(srcdir)/'`src/core/settings/nm-agent-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wireless.lo `test -f 'src/libnm-core-impl/nm-setting-wireless.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wireless.c -src/core/settings/libNetworkManager_la-nm-secret-agent.lo: src/core/settings/nm-secret-agent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-secret-agent.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-secret-agent.Tpo -c -o src/core/settings/libNetworkManager_la-nm-secret-agent.lo `test -f 'src/core/settings/nm-secret-agent.c' || echo '$(srcdir)/'`src/core/settings/nm-secret-agent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-secret-agent.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-secret-agent.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-secret-agent.c' object='src/core/settings/libNetworkManager_la-nm-secret-agent.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting-wpan.lo: src/libnm-core-impl/nm-setting-wpan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting-wpan.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wpan.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wpan.lo `test -f 'src/libnm-core-impl/nm-setting-wpan.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wpan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wpan.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wpan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting-wpan.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting-wpan.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-secret-agent.lo `test -f 'src/core/settings/nm-secret-agent.c' || echo '$(srcdir)/'`src/core/settings/nm-secret-agent.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting-wpan.lo `test -f 'src/libnm-core-impl/nm-setting-wpan.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting-wpan.c -src/core/settings/libNetworkManager_la-nm-settings-connection.lo: src/core/settings/nm-settings-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-settings-connection.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-connection.Tpo -c -o src/core/settings/libNetworkManager_la-nm-settings-connection.lo `test -f 'src/core/settings/nm-settings-connection.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-connection.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-settings-connection.c' object='src/core/settings/libNetworkManager_la-nm-settings-connection.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-connection.lo: src/libnm-core-impl/nm-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-connection.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-connection.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-connection.lo `test -f 'src/libnm-core-impl/nm-connection.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-connection.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-connection.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-settings-connection.lo `test -f 'src/core/settings/nm-settings-connection.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-connection.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-connection.lo `test -f 'src/libnm-core-impl/nm-connection.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-connection.c -src/core/settings/libNetworkManager_la-nm-settings-storage.lo: src/core/settings/nm-settings-storage.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-settings-storage.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-storage.Tpo -c -o src/core/settings/libNetworkManager_la-nm-settings-storage.lo `test -f 'src/core/settings/nm-settings-storage.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-storage.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-storage.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-storage.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-settings-storage.c' object='src/core/settings/libNetworkManager_la-nm-settings-storage.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-crypto.lo: src/libnm-core-impl/nm-crypto.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-crypto.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-crypto.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-crypto.lo `test -f 'src/libnm-core-impl/nm-crypto.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-crypto.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-crypto.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-crypto.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-crypto.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-crypto.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-settings-storage.lo `test -f 'src/core/settings/nm-settings-storage.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-storage.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-crypto.lo `test -f 'src/libnm-core-impl/nm-crypto.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-crypto.c -src/core/settings/libNetworkManager_la-nm-settings-plugin.lo: src/core/settings/nm-settings-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-settings-plugin.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-plugin.Tpo -c -o src/core/settings/libNetworkManager_la-nm-settings-plugin.lo `test -f 'src/core/settings/nm-settings-plugin.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-plugin.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-plugin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-settings-plugin.c' object='src/core/settings/libNetworkManager_la-nm-settings-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-dbus-utils.lo: src/libnm-core-impl/nm-dbus-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-dbus-utils.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-dbus-utils.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-dbus-utils.lo `test -f 'src/libnm-core-impl/nm-dbus-utils.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-dbus-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-dbus-utils.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-dbus-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-dbus-utils.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-dbus-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-settings-plugin.lo `test -f 'src/core/settings/nm-settings-plugin.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-plugin.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-dbus-utils.lo `test -f 'src/libnm-core-impl/nm-dbus-utils.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-dbus-utils.c -src/core/settings/libNetworkManager_la-nm-settings.lo: src/core/settings/nm-settings.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-settings.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings.Tpo -c -o src/core/settings/libNetworkManager_la-nm-settings.lo `test -f 'src/core/settings/nm-settings.c' || echo '$(srcdir)/'`src/core/settings/nm-settings.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-settings.c' object='src/core/settings/libNetworkManager_la-nm-settings.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-errors.lo: src/libnm-core-impl/nm-errors.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-errors.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-errors.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-errors.lo `test -f 'src/libnm-core-impl/nm-errors.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-errors.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-errors.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-errors.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-errors.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-errors.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-settings.lo `test -f 'src/core/settings/nm-settings.c' || echo '$(srcdir)/'`src/core/settings/nm-settings.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-errors.lo `test -f 'src/libnm-core-impl/nm-errors.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-errors.c -src/core/settings/libNetworkManager_la-nm-settings-utils.lo: src/core/settings/nm-settings-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/libNetworkManager_la-nm-settings-utils.lo -MD -MP -MF src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-utils.Tpo -c -o src/core/settings/libNetworkManager_la-nm-settings-utils.lo `test -f 'src/core/settings/nm-settings-utils.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-utils.Tpo src/core/settings/$(DEPDIR)/libNetworkManager_la-nm-settings-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/nm-settings-utils.c' object='src/core/settings/libNetworkManager_la-nm-settings-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-keyfile-utils.lo: src/libnm-core-impl/nm-keyfile-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-keyfile-utils.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile-utils.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-keyfile-utils.lo `test -f 'src/libnm-core-impl/nm-keyfile-utils.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-keyfile-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile-utils.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-keyfile-utils.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-keyfile-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/libNetworkManager_la-nm-settings-utils.lo `test -f 'src/core/settings/nm-settings-utils.c' || echo '$(srcdir)/'`src/core/settings/nm-settings-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-keyfile-utils.lo `test -f 'src/libnm-core-impl/nm-keyfile-utils.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-keyfile-utils.c -src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-storage.lo: src/core/settings/plugins/keyfile/nms-keyfile-storage.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-storage.lo -MD -MP -MF src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-storage.Tpo -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-storage.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-storage.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-storage.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-storage.Tpo src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-storage.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/nms-keyfile-storage.c' object='src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-storage.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-keyfile.lo: src/libnm-core-impl/nm-keyfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-keyfile.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-keyfile.lo `test -f 'src/libnm-core-impl/nm-keyfile.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-keyfile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-keyfile.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-keyfile.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-storage.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-storage.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-storage.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-keyfile.lo `test -f 'src/libnm-core-impl/nm-keyfile.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-keyfile.c -src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-plugin.lo: src/core/settings/plugins/keyfile/nms-keyfile-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-plugin.lo -MD -MP -MF src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-plugin.Tpo -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-plugin.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-plugin.Tpo src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-plugin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/nms-keyfile-plugin.c' object='src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-meta-setting-base-impl.lo: src/libnm-core-impl/nm-meta-setting-base-impl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-meta-setting-base-impl.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-meta-setting-base-impl.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-meta-setting-base-impl.lo `test -f 'src/libnm-core-impl/nm-meta-setting-base-impl.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-meta-setting-base-impl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-meta-setting-base-impl.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-meta-setting-base-impl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-meta-setting-base-impl.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-meta-setting-base-impl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-plugin.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-plugin.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-meta-setting-base-impl.lo `test -f 'src/libnm-core-impl/nm-meta-setting-base-impl.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-meta-setting-base-impl.c -src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-reader.lo: src/core/settings/plugins/keyfile/nms-keyfile-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-reader.lo -MD -MP -MF src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-reader.Tpo -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-reader.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-reader.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-reader.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-reader.Tpo src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-reader.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/nms-keyfile-reader.c' object='src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-reader.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-property-compare.lo: src/libnm-core-impl/nm-property-compare.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-property-compare.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-property-compare.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-property-compare.lo `test -f 'src/libnm-core-impl/nm-property-compare.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-property-compare.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-property-compare.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-property-compare.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-property-compare.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-property-compare.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-reader.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-reader.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-reader.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-property-compare.lo `test -f 'src/libnm-core-impl/nm-property-compare.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-property-compare.c -src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-utils.lo: src/core/settings/plugins/keyfile/nms-keyfile-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-utils.lo -MD -MP -MF src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-utils.Tpo -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-utils.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-utils.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-utils.Tpo src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/nms-keyfile-utils.c' object='src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-setting.lo: src/libnm-core-impl/nm-setting.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-setting.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting.lo `test -f 'src/libnm-core-impl/nm-setting.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-setting.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-setting.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-utils.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-utils.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-setting.lo `test -f 'src/libnm-core-impl/nm-setting.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-setting.c -src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-writer.lo: src/core/settings/plugins/keyfile/nms-keyfile-writer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-writer.lo -MD -MP -MF src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-writer.Tpo -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-writer.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-writer.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-writer.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-writer.Tpo src/core/settings/plugins/keyfile/$(DEPDIR)/libNetworkManager_la-nms-keyfile-writer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/nms-keyfile-writer.c' object='src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-writer.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-simple-connection.lo: src/libnm-core-impl/nm-simple-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-simple-connection.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-simple-connection.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-simple-connection.lo `test -f 'src/libnm-core-impl/nm-simple-connection.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-simple-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-simple-connection.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-simple-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-simple-connection.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-simple-connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/libNetworkManager_la-nms-keyfile-writer.lo `test -f 'src/core/settings/plugins/keyfile/nms-keyfile-writer.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/nms-keyfile-writer.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-simple-connection.lo `test -f 'src/libnm-core-impl/nm-simple-connection.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-simple-connection.c -src/core/supplicant/libNetworkManager_la-nm-supplicant-config.lo: src/core/supplicant/nm-supplicant-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/libNetworkManager_la-nm-supplicant-config.lo -MD -MP -MF src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-config.Tpo -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-config.lo `test -f 'src/core/supplicant/nm-supplicant-config.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-config.Tpo src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/nm-supplicant-config.c' object='src/core/supplicant/libNetworkManager_la-nm-supplicant-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-team-utils.lo: src/libnm-core-impl/nm-team-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-team-utils.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-team-utils.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-team-utils.lo `test -f 'src/libnm-core-impl/nm-team-utils.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-team-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-team-utils.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-team-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-team-utils.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-team-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-config.lo `test -f 'src/core/supplicant/nm-supplicant-config.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-team-utils.lo `test -f 'src/libnm-core-impl/nm-team-utils.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-team-utils.c -src/core/supplicant/libNetworkManager_la-nm-supplicant-interface.lo: src/core/supplicant/nm-supplicant-interface.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/libNetworkManager_la-nm-supplicant-interface.lo -MD -MP -MF src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-interface.Tpo -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-interface.lo `test -f 'src/core/supplicant/nm-supplicant-interface.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-interface.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-interface.Tpo src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-interface.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/nm-supplicant-interface.c' object='src/core/supplicant/libNetworkManager_la-nm-supplicant-interface.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-utils.lo: src/libnm-core-impl/nm-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-utils.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-utils.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-utils.lo `test -f 'src/libnm-core-impl/nm-utils.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-utils.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-utils.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-interface.lo `test -f 'src/core/supplicant/nm-supplicant-interface.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-interface.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-utils.lo `test -f 'src/libnm-core-impl/nm-utils.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-utils.c -src/core/supplicant/libNetworkManager_la-nm-supplicant-manager.lo: src/core/supplicant/nm-supplicant-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/libNetworkManager_la-nm-supplicant-manager.lo -MD -MP -MF src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-manager.Tpo -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-manager.lo `test -f 'src/core/supplicant/nm-supplicant-manager.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-manager.Tpo src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/nm-supplicant-manager.c' object='src/core/supplicant/libNetworkManager_la-nm-supplicant-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-vpn-editor-plugin.lo: src/libnm-core-impl/nm-vpn-editor-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-vpn-editor-plugin.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-editor-plugin.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-vpn-editor-plugin.lo `test -f 'src/libnm-core-impl/nm-vpn-editor-plugin.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-vpn-editor-plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-editor-plugin.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-editor-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-vpn-editor-plugin.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-vpn-editor-plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-manager.lo `test -f 'src/core/supplicant/nm-supplicant-manager.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-vpn-editor-plugin.lo `test -f 'src/libnm-core-impl/nm-vpn-editor-plugin.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-vpn-editor-plugin.c -src/core/supplicant/libNetworkManager_la-nm-supplicant-settings-verify.lo: src/core/supplicant/nm-supplicant-settings-verify.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/libNetworkManager_la-nm-supplicant-settings-verify.lo -MD -MP -MF src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-settings-verify.Tpo -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-settings-verify.lo `test -f 'src/core/supplicant/nm-supplicant-settings-verify.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-settings-verify.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-settings-verify.Tpo src/core/supplicant/$(DEPDIR)/libNetworkManager_la-nm-supplicant-settings-verify.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/nm-supplicant-settings-verify.c' object='src/core/supplicant/libNetworkManager_la-nm-supplicant-settings-verify.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_core_impl_la-nm-vpn-plugin-info.lo: src/libnm-core-impl/nm-vpn-plugin-info.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_core_impl_la-nm-vpn-plugin-info.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-plugin-info.Tpo -c -o src/libnm-core-impl/libnm_core_impl_la-nm-vpn-plugin-info.lo `test -f 'src/libnm-core-impl/nm-vpn-plugin-info.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-vpn-plugin-info.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-plugin-info.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-plugin-info.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-vpn-plugin-info.c' object='src/libnm-core-impl/libnm_core_impl_la-nm-vpn-plugin-info.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/libNetworkManager_la-nm-supplicant-settings-verify.lo `test -f 'src/core/supplicant/nm-supplicant-settings-verify.c' || echo '$(srcdir)/'`src/core/supplicant/nm-supplicant-settings-verify.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_core_impl_la-nm-vpn-plugin-info.lo `test -f 'src/libnm-core-impl/nm-vpn-plugin-info.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-vpn-plugin-info.c -src/core/vpn/libNetworkManager_la-nm-vpn-connection.lo: src/core/vpn/nm-vpn-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/vpn/libNetworkManager_la-nm-vpn-connection.lo -MD -MP -MF src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-connection.Tpo -c -o src/core/vpn/libNetworkManager_la-nm-vpn-connection.lo `test -f 'src/core/vpn/nm-vpn-connection.c' || echo '$(srcdir)/'`src/core/vpn/nm-vpn-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-connection.Tpo src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/vpn/nm-vpn-connection.c' object='src/core/vpn/libNetworkManager_la-nm-vpn-connection.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-public/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.lo: src/libnm-core-public/nm-core-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-public/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.lo -MD -MP -MF src/libnm-core-public/$(DEPDIR)/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.Tpo -c -o src/libnm-core-public/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.lo `test -f 'src/libnm-core-public/nm-core-enum-types.c' || echo '$(srcdir)/'`src/libnm-core-public/nm-core-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-public/$(DEPDIR)/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.Tpo src/libnm-core-public/$(DEPDIR)/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-public/nm-core-enum-types.c' object='src/libnm-core-public/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/vpn/libNetworkManager_la-nm-vpn-connection.lo `test -f 'src/core/vpn/nm-vpn-connection.c' || echo '$(srcdir)/'`src/core/vpn/nm-vpn-connection.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-public/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.lo `test -f 'src/libnm-core-public/nm-core-enum-types.c' || echo '$(srcdir)/'`src/libnm-core-public/nm-core-enum-types.c -src/core/vpn/libNetworkManager_la-nm-vpn-manager.lo: src/core/vpn/nm-vpn-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/vpn/libNetworkManager_la-nm-vpn-manager.lo -MD -MP -MF src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Tpo -c -o src/core/vpn/libNetworkManager_la-nm-vpn-manager.lo `test -f 'src/core/vpn/nm-vpn-manager.c' || echo '$(srcdir)/'`src/core/vpn/nm-vpn-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Tpo src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/vpn/nm-vpn-manager.c' object='src/core/vpn/libNetworkManager_la-nm-vpn-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo: src/libnm-core-impl/nm-crypto-gnutls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_crypto_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Tpo -c -o src/libnm-core-impl/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo `test -f 'src/libnm-core-impl/nm-crypto-gnutls.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-crypto-gnutls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-crypto-gnutls.c' object='src/libnm-core-impl/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/vpn/libNetworkManager_la-nm-vpn-manager.lo `test -f 'src/core/vpn/nm-vpn-manager.c' || echo '$(srcdir)/'`src/core/vpn/nm-vpn-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_crypto_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_crypto_gnutls_la-nm-crypto-gnutls.lo `test -f 'src/libnm-core-impl/nm-crypto-gnutls.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-crypto-gnutls.c -src/core/libNetworkManager_la-nm-act-request.lo: src/core/nm-act-request.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-act-request.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-act-request.Tpo -c -o src/core/libNetworkManager_la-nm-act-request.lo `test -f 'src/core/nm-act-request.c' || echo '$(srcdir)/'`src/core/nm-act-request.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-act-request.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-act-request.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-act-request.c' object='src/core/libNetworkManager_la-nm-act-request.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-core-impl/libnm_crypto_nss_la-nm-crypto-nss.lo: src/libnm-core-impl/nm-crypto-nss.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_crypto_nss_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/libnm_crypto_nss_la-nm-crypto-nss.lo -MD -MP -MF src/libnm-core-impl/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Tpo -c -o src/libnm-core-impl/libnm_crypto_nss_la-nm-crypto-nss.lo `test -f 'src/libnm-core-impl/nm-crypto-nss.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-crypto-nss.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Tpo src/libnm-core-impl/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/nm-crypto-nss.c' object='src/libnm-core-impl/libnm_crypto_nss_la-nm-crypto-nss.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-act-request.lo `test -f 'src/core/nm-act-request.c' || echo '$(srcdir)/'`src/core/nm-act-request.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_libnm_crypto_nss_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/libnm_crypto_nss_la-nm-crypto-nss.lo `test -f 'src/libnm-core-impl/nm-crypto-nss.c' || echo '$(srcdir)/'`src/libnm-core-impl/nm-crypto-nss.c -src/core/libNetworkManager_la-nm-active-connection.lo: src/core/nm-active-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-active-connection.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-active-connection.Tpo -c -o src/core/libNetworkManager_la-nm-active-connection.lo `test -f 'src/core/nm-active-connection.c' || echo '$(srcdir)/'`src/core/nm-active-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-active-connection.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-active-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-active-connection.c' object='src/core/libNetworkManager_la-nm-active-connection.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo: src/libnm-glib-aux/nm-dbus-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo `test -f 'src/libnm-glib-aux/nm-dbus-aux.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-dbus-aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-dbus-aux.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-active-connection.lo `test -f 'src/core/nm-active-connection.c' || echo '$(srcdir)/'`src/core/nm-active-connection.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-dbus-aux.lo `test -f 'src/libnm-glib-aux/nm-dbus-aux.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-dbus-aux.c -src/core/libNetworkManager_la-nm-audit-manager.lo: src/core/nm-audit-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-audit-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-audit-manager.Tpo -c -o src/core/libNetworkManager_la-nm-audit-manager.lo `test -f 'src/core/nm-audit-manager.c' || echo '$(srcdir)/'`src/core/nm-audit-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-audit-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-audit-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-audit-manager.c' object='src/core/libNetworkManager_la-nm-audit-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo: src/libnm-glib-aux/nm-dedup-multi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo `test -f 'src/libnm-glib-aux/nm-dedup-multi.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-dedup-multi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-dedup-multi.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-audit-manager.lo `test -f 'src/core/nm-audit-manager.c' || echo '$(srcdir)/'`src/core/nm-audit-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-dedup-multi.lo `test -f 'src/libnm-glib-aux/nm-dedup-multi.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-dedup-multi.c -src/core/libNetworkManager_la-nm-dbus-manager.lo: src/core/nm-dbus-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-dbus-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-dbus-manager.Tpo -c -o src/core/libNetworkManager_la-nm-dbus-manager.lo `test -f 'src/core/nm-dbus-manager.c' || echo '$(srcdir)/'`src/core/nm-dbus-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-dbus-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-dbus-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dbus-manager.c' object='src/core/libNetworkManager_la-nm-dbus-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo: src/libnm-glib-aux/nm-enum-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo `test -f 'src/libnm-glib-aux/nm-enum-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-enum-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-enum-utils.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-dbus-manager.lo `test -f 'src/core/nm-dbus-manager.c' || echo '$(srcdir)/'`src/core/nm-dbus-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-enum-utils.lo `test -f 'src/libnm-glib-aux/nm-enum-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-enum-utils.c -src/core/libNetworkManager_la-nm-config.lo: src/core/nm-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-config.Tpo -c -o src/core/libNetworkManager_la-nm-config.lo `test -f 'src/core/nm-config.c' || echo '$(srcdir)/'`src/core/nm-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-config.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-config.c' object='src/core/libNetworkManager_la-nm-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-errno.lo: src/libnm-glib-aux/nm-errno.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-errno.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-errno.lo `test -f 'src/libnm-glib-aux/nm-errno.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-errno.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-errno.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-errno.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-config.lo `test -f 'src/core/nm-config.c' || echo '$(srcdir)/'`src/core/nm-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-errno.lo `test -f 'src/libnm-glib-aux/nm-errno.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-errno.c -src/core/libNetworkManager_la-nm-config-data.lo: src/core/nm-config-data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-config-data.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-config-data.Tpo -c -o src/core/libNetworkManager_la-nm-config-data.lo `test -f 'src/core/nm-config-data.c' || echo '$(srcdir)/'`src/core/nm-config-data.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-config-data.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-config-data.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-config-data.c' object='src/core/libNetworkManager_la-nm-config-data.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo: src/libnm-glib-aux/nm-hash-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo `test -f 'src/libnm-glib-aux/nm-hash-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-hash-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-hash-utils.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-config-data.lo `test -f 'src/core/nm-config-data.c' || echo '$(srcdir)/'`src/core/nm-config-data.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-hash-utils.lo `test -f 'src/libnm-glib-aux/nm-hash-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-hash-utils.c -src/core/libNetworkManager_la-nm-connectivity.lo: src/core/nm-connectivity.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-connectivity.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-connectivity.Tpo -c -o src/core/libNetworkManager_la-nm-connectivity.lo `test -f 'src/core/nm-connectivity.c' || echo '$(srcdir)/'`src/core/nm-connectivity.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-connectivity.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-connectivity.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-connectivity.c' object='src/core/libNetworkManager_la-nm-connectivity.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo: src/libnm-glib-aux/nm-io-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo `test -f 'src/libnm-glib-aux/nm-io-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-io-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-io-utils.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-connectivity.lo `test -f 'src/core/nm-connectivity.c' || echo '$(srcdir)/'`src/core/nm-connectivity.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-io-utils.lo `test -f 'src/libnm-glib-aux/nm-io-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-io-utils.c -src/core/libNetworkManager_la-nm-dcb.lo: src/core/nm-dcb.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-dcb.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-dcb.Tpo -c -o src/core/libNetworkManager_la-nm-dcb.lo `test -f 'src/core/nm-dcb.c' || echo '$(srcdir)/'`src/core/nm-dcb.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-dcb.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-dcb.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dcb.c' object='src/core/libNetworkManager_la-nm-dcb.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo: src/libnm-glib-aux/nm-json-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo `test -f 'src/libnm-glib-aux/nm-json-aux.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-json-aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-json-aux.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-dcb.lo `test -f 'src/core/nm-dcb.c' || echo '$(srcdir)/'`src/core/nm-dcb.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-json-aux.lo `test -f 'src/libnm-glib-aux/nm-json-aux.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-json-aux.c -src/core/libNetworkManager_la-nm-dhcp-config.lo: src/core/nm-dhcp-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-dhcp-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-dhcp-config.Tpo -c -o src/core/libNetworkManager_la-nm-dhcp-config.lo `test -f 'src/core/nm-dhcp-config.c' || echo '$(srcdir)/'`src/core/nm-dhcp-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-dhcp-config.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-dhcp-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dhcp-config.c' object='src/core/libNetworkManager_la-nm-dhcp-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo: src/libnm-glib-aux/nm-keyfile-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo `test -f 'src/libnm-glib-aux/nm-keyfile-aux.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-keyfile-aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-keyfile-aux.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-dhcp-config.lo `test -f 'src/core/nm-dhcp-config.c' || echo '$(srcdir)/'`src/core/nm-dhcp-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-keyfile-aux.lo `test -f 'src/libnm-glib-aux/nm-keyfile-aux.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-keyfile-aux.c -src/core/libNetworkManager_la-nm-dispatcher.lo: src/core/nm-dispatcher.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-dispatcher.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-dispatcher.Tpo -c -o src/core/libNetworkManager_la-nm-dispatcher.lo `test -f 'src/core/nm-dispatcher.c' || echo '$(srcdir)/'`src/core/nm-dispatcher.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-dispatcher.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-dispatcher.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dispatcher.c' object='src/core/libNetworkManager_la-nm-dispatcher.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo: src/libnm-glib-aux/nm-logging-base.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo `test -f 'src/libnm-glib-aux/nm-logging-base.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-logging-base.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-logging-base.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-dispatcher.lo `test -f 'src/core/nm-dispatcher.c' || echo '$(srcdir)/'`src/core/nm-dispatcher.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-logging-base.lo `test -f 'src/libnm-glib-aux/nm-logging-base.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-logging-base.c -src/core/libNetworkManager_la-nm-firewall-manager.lo: src/core/nm-firewall-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-firewall-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-firewall-manager.Tpo -c -o src/core/libNetworkManager_la-nm-firewall-manager.lo `test -f 'src/core/nm-firewall-manager.c' || echo '$(srcdir)/'`src/core/nm-firewall-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-firewall-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-firewall-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-firewall-manager.c' object='src/core/libNetworkManager_la-nm-firewall-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo: src/libnm-glib-aux/nm-random-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo `test -f 'src/libnm-glib-aux/nm-random-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-random-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-random-utils.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-firewall-manager.lo `test -f 'src/core/nm-firewall-manager.c' || echo '$(srcdir)/'`src/core/nm-firewall-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-random-utils.lo `test -f 'src/libnm-glib-aux/nm-random-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-random-utils.c -src/core/libNetworkManager_la-nm-proxy-config.lo: src/core/nm-proxy-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-proxy-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-proxy-config.Tpo -c -o src/core/libNetworkManager_la-nm-proxy-config.lo `test -f 'src/core/nm-proxy-config.c' || echo '$(srcdir)/'`src/core/nm-proxy-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-proxy-config.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-proxy-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-proxy-config.c' object='src/core/libNetworkManager_la-nm-proxy-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo: src/libnm-glib-aux/nm-ref-string.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo `test -f 'src/libnm-glib-aux/nm-ref-string.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-ref-string.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-ref-string.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-proxy-config.lo `test -f 'src/core/nm-proxy-config.c' || echo '$(srcdir)/'`src/core/nm-proxy-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-ref-string.lo `test -f 'src/libnm-glib-aux/nm-ref-string.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-ref-string.c -src/core/libNetworkManager_la-nm-auth-manager.lo: src/core/nm-auth-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-auth-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-manager.Tpo -c -o src/core/libNetworkManager_la-nm-auth-manager.lo `test -f 'src/core/nm-auth-manager.c' || echo '$(srcdir)/'`src/core/nm-auth-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-auth-manager.c' object='src/core/libNetworkManager_la-nm-auth-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo: src/libnm-glib-aux/nm-secret-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo `test -f 'src/libnm-glib-aux/nm-secret-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-secret-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-secret-utils.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-auth-manager.lo `test -f 'src/core/nm-auth-manager.c' || echo '$(srcdir)/'`src/core/nm-auth-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-secret-utils.lo `test -f 'src/libnm-glib-aux/nm-secret-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-secret-utils.c -src/core/libNetworkManager_la-nm-auth-utils.lo: src/core/nm-auth-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-auth-utils.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-utils.Tpo -c -o src/core/libNetworkManager_la-nm-auth-utils.lo `test -f 'src/core/nm-auth-utils.c' || echo '$(srcdir)/'`src/core/nm-auth-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-utils.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-auth-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-auth-utils.c' object='src/core/libNetworkManager_la-nm-auth-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo: src/libnm-glib-aux/nm-shared-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo `test -f 'src/libnm-glib-aux/nm-shared-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-shared-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-shared-utils.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-auth-utils.lo `test -f 'src/core/nm-auth-utils.c' || echo '$(srcdir)/'`src/core/nm-auth-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-shared-utils.lo `test -f 'src/libnm-glib-aux/nm-shared-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-shared-utils.c -src/core/libNetworkManager_la-nm-manager.lo: src/core/nm-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-manager.Tpo -c -o src/core/libNetworkManager_la-nm-manager.lo `test -f 'src/core/nm-manager.c' || echo '$(srcdir)/'`src/core/nm-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-manager.c' object='src/core/libNetworkManager_la-nm-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo: src/libnm-glib-aux/nm-time-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo -MD -MP -MF src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Tpo -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo `test -f 'src/libnm-glib-aux/nm-time-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-time-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Tpo src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/nm-time-utils.c' object='src/libnm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-manager.lo `test -f 'src/core/nm-manager.c' || echo '$(srcdir)/'`src/core/nm-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_libnm_glib_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/libnm_glib_aux_la-nm-time-utils.lo `test -f 'src/libnm-glib-aux/nm-time-utils.c' || echo '$(srcdir)/'`src/libnm-glib-aux/nm-time-utils.c -src/core/libNetworkManager_la-nm-pacrunner-manager.lo: src/core/nm-pacrunner-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-pacrunner-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-pacrunner-manager.Tpo -c -o src/core/libNetworkManager_la-nm-pacrunner-manager.lo `test -f 'src/core/nm-pacrunner-manager.c' || echo '$(srcdir)/'`src/core/nm-pacrunner-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-pacrunner-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-pacrunner-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-pacrunner-manager.c' object='src/core/libNetworkManager_la-nm-pacrunner-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-log-core/libnm_log_core_la-nm-logging.lo: src/libnm-log-core/nm-logging.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_log_core_libnm_log_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-log-core/libnm_log_core_la-nm-logging.lo -MD -MP -MF src/libnm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Tpo -c -o src/libnm-log-core/libnm_log_core_la-nm-logging.lo `test -f 'src/libnm-log-core/nm-logging.c' || echo '$(srcdir)/'`src/libnm-log-core/nm-logging.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Tpo src/libnm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-log-core/nm-logging.c' object='src/libnm-log-core/libnm_log_core_la-nm-logging.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-pacrunner-manager.lo `test -f 'src/core/nm-pacrunner-manager.c' || echo '$(srcdir)/'`src/core/nm-pacrunner-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_log_core_libnm_log_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-log-core/libnm_log_core_la-nm-logging.lo `test -f 'src/libnm-log-core/nm-logging.c' || echo '$(srcdir)/'`src/libnm-log-core/nm-logging.c -src/core/libNetworkManager_la-nm-policy.lo: src/core/nm-policy.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-policy.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-policy.Tpo -c -o src/core/libNetworkManager_la-nm-policy.lo `test -f 'src/core/nm-policy.c' || echo '$(srcdir)/'`src/core/nm-policy.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-policy.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-policy.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-policy.c' object='src/core/libNetworkManager_la-nm-policy.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-log-null/libnm_log_null_la-nm-logging-null.lo: src/libnm-log-null/nm-logging-null.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_log_null_libnm_log_null_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-log-null/libnm_log_null_la-nm-logging-null.lo -MD -MP -MF src/libnm-log-null/$(DEPDIR)/libnm_log_null_la-nm-logging-null.Tpo -c -o src/libnm-log-null/libnm_log_null_la-nm-logging-null.lo `test -f 'src/libnm-log-null/nm-logging-null.c' || echo '$(srcdir)/'`src/libnm-log-null/nm-logging-null.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-log-null/$(DEPDIR)/libnm_log_null_la-nm-logging-null.Tpo src/libnm-log-null/$(DEPDIR)/libnm_log_null_la-nm-logging-null.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-log-null/nm-logging-null.c' object='src/libnm-log-null/libnm_log_null_la-nm-logging-null.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-policy.lo `test -f 'src/core/nm-policy.c' || echo '$(srcdir)/'`src/core/nm-policy.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_log_null_libnm_log_null_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-log-null/libnm_log_null_la-nm-logging-null.lo `test -f 'src/libnm-log-null/nm-logging-null.c' || echo '$(srcdir)/'`src/libnm-log-null/nm-logging-null.c -src/core/libNetworkManager_la-nm-rfkill-manager.lo: src/core/nm-rfkill-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-rfkill-manager.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-rfkill-manager.Tpo -c -o src/core/libNetworkManager_la-nm-rfkill-manager.lo `test -f 'src/core/nm-rfkill-manager.c' || echo '$(srcdir)/'`src/core/nm-rfkill-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-rfkill-manager.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-rfkill-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-rfkill-manager.c' object='src/core/libNetworkManager_la-nm-rfkill-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/libnm_platform_la-nm-linux-platform.lo: src/libnm-platform/nm-linux-platform.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/libnm_platform_la-nm-linux-platform.lo -MD -MP -MF src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-linux-platform.Tpo -c -o src/libnm-platform/libnm_platform_la-nm-linux-platform.lo `test -f 'src/libnm-platform/nm-linux-platform.c' || echo '$(srcdir)/'`src/libnm-platform/nm-linux-platform.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-linux-platform.Tpo src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-linux-platform.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/nm-linux-platform.c' object='src/libnm-platform/libnm_platform_la-nm-linux-platform.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-rfkill-manager.lo `test -f 'src/core/nm-rfkill-manager.c' || echo '$(srcdir)/'`src/core/nm-rfkill-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/libnm_platform_la-nm-linux-platform.lo `test -f 'src/libnm-platform/nm-linux-platform.c' || echo '$(srcdir)/'`src/libnm-platform/nm-linux-platform.c -src/core/libNetworkManager_la-nm-session-monitor.lo: src/core/nm-session-monitor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-session-monitor.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-session-monitor.Tpo -c -o src/core/libNetworkManager_la-nm-session-monitor.lo `test -f 'src/core/nm-session-monitor.c' || echo '$(srcdir)/'`src/core/nm-session-monitor.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-session-monitor.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-session-monitor.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-session-monitor.c' object='src/core/libNetworkManager_la-nm-session-monitor.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/libnm_platform_la-nm-netlink.lo: src/libnm-platform/nm-netlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/libnm_platform_la-nm-netlink.lo -MD -MP -MF src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Tpo -c -o src/libnm-platform/libnm_platform_la-nm-netlink.lo `test -f 'src/libnm-platform/nm-netlink.c' || echo '$(srcdir)/'`src/libnm-platform/nm-netlink.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Tpo src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/nm-netlink.c' object='src/libnm-platform/libnm_platform_la-nm-netlink.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-session-monitor.lo `test -f 'src/core/nm-session-monitor.c' || echo '$(srcdir)/'`src/core/nm-session-monitor.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/libnm_platform_la-nm-netlink.lo `test -f 'src/libnm-platform/nm-netlink.c' || echo '$(srcdir)/'`src/libnm-platform/nm-netlink.c -src/core/libNetworkManager_la-nm-keep-alive.lo: src/core/nm-keep-alive.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-keep-alive.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-keep-alive.Tpo -c -o src/core/libNetworkManager_la-nm-keep-alive.lo `test -f 'src/core/nm-keep-alive.c' || echo '$(srcdir)/'`src/core/nm-keep-alive.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-keep-alive.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-keep-alive.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-keep-alive.c' object='src/core/libNetworkManager_la-nm-keep-alive.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/libnm_platform_la-nm-platform-utils.lo: src/libnm-platform/nm-platform-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/libnm_platform_la-nm-platform-utils.lo -MD -MP -MF src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Tpo -c -o src/libnm-platform/libnm_platform_la-nm-platform-utils.lo `test -f 'src/libnm-platform/nm-platform-utils.c' || echo '$(srcdir)/'`src/libnm-platform/nm-platform-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Tpo src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/nm-platform-utils.c' object='src/libnm-platform/libnm_platform_la-nm-platform-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-keep-alive.lo `test -f 'src/core/nm-keep-alive.c' || echo '$(srcdir)/'`src/core/nm-keep-alive.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/libnm_platform_la-nm-platform-utils.lo `test -f 'src/libnm-platform/nm-platform-utils.c' || echo '$(srcdir)/'`src/libnm-platform/nm-platform-utils.c -src/core/libNetworkManager_la-nm-sleep-monitor.lo: src/core/nm-sleep-monitor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManager_la-nm-sleep-monitor.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManager_la-nm-sleep-monitor.Tpo -c -o src/core/libNetworkManager_la-nm-sleep-monitor.lo `test -f 'src/core/nm-sleep-monitor.c' || echo '$(srcdir)/'`src/core/nm-sleep-monitor.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManager_la-nm-sleep-monitor.Tpo src/core/$(DEPDIR)/libNetworkManager_la-nm-sleep-monitor.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-sleep-monitor.c' object='src/core/libNetworkManager_la-nm-sleep-monitor.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/libnm_platform_la-nm-platform.lo: src/libnm-platform/nm-platform.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/libnm_platform_la-nm-platform.lo -MD -MP -MF src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform.Tpo -c -o src/libnm-platform/libnm_platform_la-nm-platform.lo `test -f 'src/libnm-platform/nm-platform.c' || echo '$(srcdir)/'`src/libnm-platform/nm-platform.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform.Tpo src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/nm-platform.c' object='src/libnm-platform/libnm_platform_la-nm-platform.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManager_la-nm-sleep-monitor.lo `test -f 'src/core/nm-sleep-monitor.c' || echo '$(srcdir)/'`src/core/nm-sleep-monitor.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/libnm_platform_la-nm-platform.lo `test -f 'src/libnm-platform/nm-platform.c' || echo '$(srcdir)/'`src/libnm-platform/nm-platform.c -src/core/libNetworkManagerBase_la-nm-core-utils.lo: src/core/nm-core-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-core-utils.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-core-utils.Tpo -c -o src/core/libNetworkManagerBase_la-nm-core-utils.lo `test -f 'src/core/nm-core-utils.c' || echo '$(srcdir)/'`src/core/nm-core-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-core-utils.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-core-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-core-utils.c' object='src/core/libNetworkManagerBase_la-nm-core-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/libnm_platform_la-nmp-netns.lo: src/libnm-platform/nmp-netns.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/libnm_platform_la-nmp-netns.lo -MD -MP -MF src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Tpo -c -o src/libnm-platform/libnm_platform_la-nmp-netns.lo `test -f 'src/libnm-platform/nmp-netns.c' || echo '$(srcdir)/'`src/libnm-platform/nmp-netns.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Tpo src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/nmp-netns.c' object='src/libnm-platform/libnm_platform_la-nmp-netns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-core-utils.lo `test -f 'src/core/nm-core-utils.c' || echo '$(srcdir)/'`src/core/nm-core-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/libnm_platform_la-nmp-netns.lo `test -f 'src/libnm-platform/nmp-netns.c' || echo '$(srcdir)/'`src/libnm-platform/nmp-netns.c -src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo: src/core/NetworkManagerUtils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-NetworkManagerUtils.Tpo -c -o src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo `test -f 'src/core/NetworkManagerUtils.c' || echo '$(srcdir)/'`src/core/NetworkManagerUtils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-NetworkManagerUtils.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-NetworkManagerUtils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/NetworkManagerUtils.c' object='src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/libnm_platform_la-nmp-object.lo: src/libnm-platform/nmp-object.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/libnm_platform_la-nmp-object.lo -MD -MP -MF src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-object.Tpo -c -o src/libnm-platform/libnm_platform_la-nmp-object.lo `test -f 'src/libnm-platform/nmp-object.c' || echo '$(srcdir)/'`src/libnm-platform/nmp-object.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-object.Tpo src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-object.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/nmp-object.c' object='src/libnm-platform/libnm_platform_la-nmp-object.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-NetworkManagerUtils.lo `test -f 'src/core/NetworkManagerUtils.c' || echo '$(srcdir)/'`src/core/NetworkManagerUtils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/libnm_platform_la-nmp-object.lo `test -f 'src/libnm-platform/nmp-object.c' || echo '$(srcdir)/'`src/libnm-platform/nmp-object.c -src/core/platform/libNetworkManagerBase_la-nmp-object.lo: src/core/platform/nmp-object.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/libNetworkManagerBase_la-nmp-object.lo -MD -MP -MF src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-object.Tpo -c -o src/core/platform/libNetworkManagerBase_la-nmp-object.lo `test -f 'src/core/platform/nmp-object.c' || echo '$(srcdir)/'`src/core/platform/nmp-object.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-object.Tpo src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-object.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/nmp-object.c' object='src/core/platform/libNetworkManagerBase_la-nmp-object.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/libnm_platform_la-nmp-rules-manager.lo: src/libnm-platform/nmp-rules-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/libnm_platform_la-nmp-rules-manager.lo -MD -MP -MF src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-rules-manager.Tpo -c -o src/libnm-platform/libnm_platform_la-nmp-rules-manager.lo `test -f 'src/libnm-platform/nmp-rules-manager.c' || echo '$(srcdir)/'`src/libnm-platform/nmp-rules-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-rules-manager.Tpo src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-rules-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/nmp-rules-manager.c' object='src/libnm-platform/libnm_platform_la-nmp-rules-manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/libNetworkManagerBase_la-nmp-object.lo `test -f 'src/core/platform/nmp-object.c' || echo '$(srcdir)/'`src/core/platform/nmp-object.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/libnm_platform_la-nmp-rules-manager.lo `test -f 'src/libnm-platform/nmp-rules-manager.c' || echo '$(srcdir)/'`src/libnm-platform/nmp-rules-manager.c -src/core/platform/libNetworkManagerBase_la-nm-platform.lo: src/core/platform/nm-platform.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/libNetworkManagerBase_la-nm-platform.lo -MD -MP -MF src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-platform.Tpo -c -o src/core/platform/libNetworkManagerBase_la-nm-platform.lo `test -f 'src/core/platform/nm-platform.c' || echo '$(srcdir)/'`src/core/platform/nm-platform.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-platform.Tpo src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-platform.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/nm-platform.c' object='src/core/platform/libNetworkManagerBase_la-nm-platform.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-nl80211.lo: src/libnm-platform/wifi/nm-wifi-utils-nl80211.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-nl80211.lo -MD -MP -MF src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-nl80211.Tpo -c -o src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-nl80211.lo `test -f 'src/libnm-platform/wifi/nm-wifi-utils-nl80211.c' || echo '$(srcdir)/'`src/libnm-platform/wifi/nm-wifi-utils-nl80211.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-nl80211.Tpo src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-nl80211.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/wifi/nm-wifi-utils-nl80211.c' object='src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-nl80211.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/libNetworkManagerBase_la-nm-platform.lo `test -f 'src/core/platform/nm-platform.c' || echo '$(srcdir)/'`src/core/platform/nm-platform.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-nl80211.lo `test -f 'src/libnm-platform/wifi/nm-wifi-utils-nl80211.c' || echo '$(srcdir)/'`src/libnm-platform/wifi/nm-wifi-utils-nl80211.c -src/core/platform/libNetworkManagerBase_la-nm-linux-platform.lo: src/core/platform/nm-linux-platform.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/libNetworkManagerBase_la-nm-linux-platform.lo -MD -MP -MF src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-linux-platform.Tpo -c -o src/core/platform/libNetworkManagerBase_la-nm-linux-platform.lo `test -f 'src/core/platform/nm-linux-platform.c' || echo '$(srcdir)/'`src/core/platform/nm-linux-platform.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-linux-platform.Tpo src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-linux-platform.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/nm-linux-platform.c' object='src/core/platform/libNetworkManagerBase_la-nm-linux-platform.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils.lo: src/libnm-platform/wifi/nm-wifi-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils.lo -MD -MP -MF src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils.Tpo -c -o src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils.lo `test -f 'src/libnm-platform/wifi/nm-wifi-utils.c' || echo '$(srcdir)/'`src/libnm-platform/wifi/nm-wifi-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils.Tpo src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/wifi/nm-wifi-utils.c' object='src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/libNetworkManagerBase_la-nm-linux-platform.lo `test -f 'src/core/platform/nm-linux-platform.c' || echo '$(srcdir)/'`src/core/platform/nm-linux-platform.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils.lo `test -f 'src/libnm-platform/wifi/nm-wifi-utils.c' || echo '$(srcdir)/'`src/libnm-platform/wifi/nm-wifi-utils.c -src/core/platform/libNetworkManagerBase_la-nmp-rules-manager.lo: src/core/platform/nmp-rules-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/libNetworkManagerBase_la-nmp-rules-manager.lo -MD -MP -MF src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-rules-manager.Tpo -c -o src/core/platform/libNetworkManagerBase_la-nmp-rules-manager.lo `test -f 'src/core/platform/nmp-rules-manager.c' || echo '$(srcdir)/'`src/core/platform/nmp-rules-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-rules-manager.Tpo src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-rules-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/nmp-rules-manager.c' object='src/core/platform/libNetworkManagerBase_la-nmp-rules-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/wpan/libnm_platform_la-nm-wpan-utils.lo: src/libnm-platform/wpan/nm-wpan-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/wpan/libnm_platform_la-nm-wpan-utils.lo -MD -MP -MF src/libnm-platform/wpan/$(DEPDIR)/libnm_platform_la-nm-wpan-utils.Tpo -c -o src/libnm-platform/wpan/libnm_platform_la-nm-wpan-utils.lo `test -f 'src/libnm-platform/wpan/nm-wpan-utils.c' || echo '$(srcdir)/'`src/libnm-platform/wpan/nm-wpan-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/wpan/$(DEPDIR)/libnm_platform_la-nm-wpan-utils.Tpo src/libnm-platform/wpan/$(DEPDIR)/libnm_platform_la-nm-wpan-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/wpan/nm-wpan-utils.c' object='src/libnm-platform/wpan/libnm_platform_la-nm-wpan-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/libNetworkManagerBase_la-nmp-rules-manager.lo `test -f 'src/core/platform/nmp-rules-manager.c' || echo '$(srcdir)/'`src/core/platform/nmp-rules-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/wpan/libnm_platform_la-nm-wpan-utils.lo `test -f 'src/libnm-platform/wpan/nm-wpan-utils.c' || echo '$(srcdir)/'`src/libnm-platform/wpan/nm-wpan-utils.c -src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-nl80211.lo: src/core/platform/wifi/nm-wifi-utils-nl80211.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-nl80211.lo -MD -MP -MF src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-nl80211.Tpo -c -o src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-nl80211.lo `test -f 'src/core/platform/wifi/nm-wifi-utils-nl80211.c' || echo '$(srcdir)/'`src/core/platform/wifi/nm-wifi-utils-nl80211.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-nl80211.Tpo src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-nl80211.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/wifi/nm-wifi-utils-nl80211.c' object='src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-nl80211.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-wext.lo: src/libnm-platform/wifi/nm-wifi-utils-wext.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-wext.lo -MD -MP -MF src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-wext.Tpo -c -o src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-wext.lo `test -f 'src/libnm-platform/wifi/nm-wifi-utils-wext.c' || echo '$(srcdir)/'`src/libnm-platform/wifi/nm-wifi-utils-wext.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-wext.Tpo src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-wext.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/wifi/nm-wifi-utils-wext.c' object='src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-wext.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-nl80211.lo `test -f 'src/core/platform/wifi/nm-wifi-utils-nl80211.c' || echo '$(srcdir)/'`src/core/platform/wifi/nm-wifi-utils-nl80211.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_libnm_platform_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/wifi/libnm_platform_la-nm-wifi-utils-wext.lo `test -f 'src/libnm-platform/wifi/nm-wifi-utils-wext.c' || echo '$(srcdir)/'`src/libnm-platform/wifi/nm-wifi-utils-wext.c -src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils.lo: src/core/platform/wifi/nm-wifi-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils.lo -MD -MP -MF src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils.Tpo -c -o src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils.lo `test -f 'src/core/platform/wifi/nm-wifi-utils.c' || echo '$(srcdir)/'`src/core/platform/wifi/nm-wifi-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils.Tpo src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/wifi/nm-wifi-utils.c' object='src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-std-aux/libnm_std_aux_la-c-list-util.lo: src/libnm-std-aux/c-list-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_std_aux_libnm_std_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-std-aux/libnm_std_aux_la-c-list-util.lo -MD -MP -MF src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Tpo -c -o src/libnm-std-aux/libnm_std_aux_la-c-list-util.lo `test -f 'src/libnm-std-aux/c-list-util.c' || echo '$(srcdir)/'`src/libnm-std-aux/c-list-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Tpo src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-std-aux/c-list-util.c' object='src/libnm-std-aux/libnm_std_aux_la-c-list-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils.lo `test -f 'src/core/platform/wifi/nm-wifi-utils.c' || echo '$(srcdir)/'`src/core/platform/wifi/nm-wifi-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_std_aux_libnm_std_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-std-aux/libnm_std_aux_la-c-list-util.lo `test -f 'src/libnm-std-aux/c-list-util.c' || echo '$(srcdir)/'`src/libnm-std-aux/c-list-util.c -src/core/platform/wpan/libNetworkManagerBase_la-nm-wpan-utils.lo: src/core/platform/wpan/nm-wpan-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/wpan/libNetworkManagerBase_la-nm-wpan-utils.lo -MD -MP -MF src/core/platform/wpan/$(DEPDIR)/libNetworkManagerBase_la-nm-wpan-utils.Tpo -c -o src/core/platform/wpan/libNetworkManagerBase_la-nm-wpan-utils.lo `test -f 'src/core/platform/wpan/nm-wpan-utils.c' || echo '$(srcdir)/'`src/core/platform/wpan/nm-wpan-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/wpan/$(DEPDIR)/libNetworkManagerBase_la-nm-wpan-utils.Tpo src/core/platform/wpan/$(DEPDIR)/libNetworkManagerBase_la-nm-wpan-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/wpan/nm-wpan-utils.c' object='src/core/platform/wpan/libNetworkManagerBase_la-nm-wpan-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-std-aux/libnm_std_aux_la-nm-std-utils.lo: src/libnm-std-aux/nm-std-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_std_aux_libnm_std_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-std-aux/libnm_std_aux_la-nm-std-utils.lo -MD -MP -MF src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Tpo -c -o src/libnm-std-aux/libnm_std_aux_la-nm-std-utils.lo `test -f 'src/libnm-std-aux/nm-std-utils.c' || echo '$(srcdir)/'`src/libnm-std-aux/nm-std-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Tpo src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-std-aux/nm-std-utils.c' object='src/libnm-std-aux/libnm_std_aux_la-nm-std-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/wpan/libNetworkManagerBase_la-nm-wpan-utils.lo `test -f 'src/core/platform/wpan/nm-wpan-utils.c' || echo '$(srcdir)/'`src/core/platform/wpan/nm-wpan-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_std_aux_libnm_std_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-std-aux/libnm_std_aux_la-nm-std-utils.lo `test -f 'src/libnm-std-aux/nm-std-utils.c' || echo '$(srcdir)/'`src/libnm-std-aux/nm-std-utils.c -src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo: src/core/ndisc/nm-lndp-ndisc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo -MD -MP -MF src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-lndp-ndisc.Tpo -c -o src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo `test -f 'src/core/ndisc/nm-lndp-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-lndp-ndisc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-lndp-ndisc.Tpo src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-lndp-ndisc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/nm-lndp-ndisc.c' object='src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/libnm_systemd_shared_la-nm-sd-utils-shared.lo: src/libnm-systemd-shared/nm-sd-utils-shared.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/libnm_systemd_shared_la-nm-sd-utils-shared.lo -MD -MP -MF src/libnm-systemd-shared/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Tpo -c -o src/libnm-systemd-shared/libnm_systemd_shared_la-nm-sd-utils-shared.lo `test -f 'src/libnm-systemd-shared/nm-sd-utils-shared.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/nm-sd-utils-shared.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Tpo src/libnm-systemd-shared/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/nm-sd-utils-shared.c' object='src/libnm-systemd-shared/libnm_systemd_shared_la-nm-sd-utils-shared.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/libNetworkManagerBase_la-nm-lndp-ndisc.lo `test -f 'src/core/ndisc/nm-lndp-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-lndp-ndisc.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/libnm_systemd_shared_la-nm-sd-utils-shared.lo `test -f 'src/libnm-systemd-shared/nm-sd-utils-shared.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/nm-sd-utils-shared.c -src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo: src/core/ndisc/nm-ndisc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo -MD -MP -MF src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-ndisc.Tpo -c -o src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo `test -f 'src/core/ndisc/nm-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-ndisc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-ndisc.Tpo src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-ndisc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/nm-ndisc.c' object='src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-alloc-util.lo: src/libnm-systemd-shared/src/basic/alloc-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-alloc-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-alloc-util.lo `test -f 'src/libnm-systemd-shared/src/basic/alloc-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/alloc-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/alloc-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-alloc-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/libNetworkManagerBase_la-nm-ndisc.lo `test -f 'src/core/ndisc/nm-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-ndisc.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-alloc-util.lo `test -f 'src/libnm-systemd-shared/src/basic/alloc-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/alloc-util.c -src/core/libNetworkManagerBase_la-nm-dbus-utils.lo: src/core/nm-dbus-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-dbus-utils.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-utils.Tpo -c -o src/core/libNetworkManagerBase_la-nm-dbus-utils.lo `test -f 'src/core/nm-dbus-utils.c' || echo '$(srcdir)/'`src/core/nm-dbus-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-utils.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dbus-utils.c' object='src/core/libNetworkManagerBase_la-nm-dbus-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-file.lo: src/libnm-systemd-shared/src/basic/env-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-file.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-file.lo `test -f 'src/libnm-systemd-shared/src/basic/env-file.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/env-file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/env-file.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-file.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-dbus-utils.lo `test -f 'src/core/nm-dbus-utils.c' || echo '$(srcdir)/'`src/core/nm-dbus-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-file.lo `test -f 'src/libnm-systemd-shared/src/basic/env-file.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/env-file.c -src/core/libNetworkManagerBase_la-nm-dbus-object.lo: src/core/nm-dbus-object.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-dbus-object.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-object.Tpo -c -o src/core/libNetworkManagerBase_la-nm-dbus-object.lo `test -f 'src/core/nm-dbus-object.c' || echo '$(srcdir)/'`src/core/nm-dbus-object.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-object.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-dbus-object.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-dbus-object.c' object='src/core/libNetworkManagerBase_la-nm-dbus-object.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-util.lo: src/libnm-systemd-shared/src/basic/env-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-util.lo `test -f 'src/libnm-systemd-shared/src/basic/env-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/env-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/env-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-dbus-object.lo `test -f 'src/core/nm-dbus-object.c' || echo '$(srcdir)/'`src/core/nm-dbus-object.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-env-util.lo `test -f 'src/libnm-systemd-shared/src/basic/env-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/env-util.c -src/core/libNetworkManagerBase_la-nm-netns.lo: src/core/nm-netns.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-netns.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-netns.Tpo -c -o src/core/libNetworkManagerBase_la-nm-netns.lo `test -f 'src/core/nm-netns.c' || echo '$(srcdir)/'`src/core/nm-netns.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-netns.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-netns.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-netns.c' object='src/core/libNetworkManagerBase_la-nm-netns.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-escape.lo: src/libnm-systemd-shared/src/basic/escape.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-escape.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-escape.lo `test -f 'src/libnm-systemd-shared/src/basic/escape.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/escape.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/escape.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-escape.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-netns.lo `test -f 'src/core/nm-netns.c' || echo '$(srcdir)/'`src/core/nm-netns.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-escape.lo `test -f 'src/libnm-systemd-shared/src/basic/escape.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/escape.c -src/core/libNetworkManagerBase_la-nm-l3-config-data.lo: src/core/nm-l3-config-data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-l3-config-data.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-config-data.Tpo -c -o src/core/libNetworkManagerBase_la-nm-l3-config-data.lo `test -f 'src/core/nm-l3-config-data.c' || echo '$(srcdir)/'`src/core/nm-l3-config-data.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-config-data.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-config-data.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-l3-config-data.c' object='src/core/libNetworkManagerBase_la-nm-l3-config-data.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ether-addr-util.lo: src/libnm-systemd-shared/src/basic/ether-addr-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ether-addr-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ether-addr-util.lo `test -f 'src/libnm-systemd-shared/src/basic/ether-addr-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/ether-addr-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/ether-addr-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ether-addr-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-l3-config-data.lo `test -f 'src/core/nm-l3-config-data.c' || echo '$(srcdir)/'`src/core/nm-l3-config-data.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ether-addr-util.lo `test -f 'src/libnm-systemd-shared/src/basic/ether-addr-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/ether-addr-util.c -src/core/libNetworkManagerBase_la-nm-l3-ipv4ll.lo: src/core/nm-l3-ipv4ll.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-l3-ipv4ll.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-ipv4ll.Tpo -c -o src/core/libNetworkManagerBase_la-nm-l3-ipv4ll.lo `test -f 'src/core/nm-l3-ipv4ll.c' || echo '$(srcdir)/'`src/core/nm-l3-ipv4ll.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-ipv4ll.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3-ipv4ll.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-l3-ipv4ll.c' object='src/core/libNetworkManagerBase_la-nm-l3-ipv4ll.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-extract-word.lo: src/libnm-systemd-shared/src/basic/extract-word.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-extract-word.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-extract-word.lo `test -f 'src/libnm-systemd-shared/src/basic/extract-word.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/extract-word.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/extract-word.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-extract-word.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-l3-ipv4ll.lo `test -f 'src/core/nm-l3-ipv4ll.c' || echo '$(srcdir)/'`src/core/nm-l3-ipv4ll.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-extract-word.lo `test -f 'src/libnm-systemd-shared/src/basic/extract-word.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/extract-word.c -src/core/libNetworkManagerBase_la-nm-l3cfg.lo: src/core/nm-l3cfg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-l3cfg.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3cfg.Tpo -c -o src/core/libNetworkManagerBase_la-nm-l3cfg.lo `test -f 'src/core/nm-l3cfg.c' || echo '$(srcdir)/'`src/core/nm-l3cfg.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3cfg.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-l3cfg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-l3cfg.c' object='src/core/libNetworkManagerBase_la-nm-l3cfg.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fd-util.lo: src/libnm-systemd-shared/src/basic/fd-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fd-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fd-util.lo `test -f 'src/libnm-systemd-shared/src/basic/fd-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/fd-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/fd-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fd-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-l3cfg.lo `test -f 'src/core/nm-l3cfg.c' || echo '$(srcdir)/'`src/core/nm-l3cfg.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fd-util.lo `test -f 'src/libnm-systemd-shared/src/basic/fd-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/fd-util.c -src/core/libNetworkManagerBase_la-nm-ip-config.lo: src/core/nm-ip-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-ip-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip-config.Tpo -c -o src/core/libNetworkManagerBase_la-nm-ip-config.lo `test -f 'src/core/nm-ip-config.c' || echo '$(srcdir)/'`src/core/nm-ip-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip-config.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-ip-config.c' object='src/core/libNetworkManagerBase_la-nm-ip-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fileio.lo: src/libnm-systemd-shared/src/basic/fileio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fileio.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fileio.lo `test -f 'src/libnm-systemd-shared/src/basic/fileio.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/fileio.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/fileio.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fileio.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-ip-config.lo `test -f 'src/core/nm-ip-config.c' || echo '$(srcdir)/'`src/core/nm-ip-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fileio.lo `test -f 'src/libnm-systemd-shared/src/basic/fileio.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/fileio.c -src/core/libNetworkManagerBase_la-nm-ip4-config.lo: src/core/nm-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-ip4-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip4-config.Tpo -c -o src/core/libNetworkManagerBase_la-nm-ip4-config.lo `test -f 'src/core/nm-ip4-config.c' || echo '$(srcdir)/'`src/core/nm-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip4-config.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip4-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-ip4-config.c' object='src/core/libNetworkManagerBase_la-nm-ip4-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-format-util.lo: src/libnm-systemd-shared/src/basic/format-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-format-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-format-util.lo `test -f 'src/libnm-systemd-shared/src/basic/format-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/format-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/format-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-format-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-ip4-config.lo `test -f 'src/core/nm-ip4-config.c' || echo '$(srcdir)/'`src/core/nm-ip4-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-format-util.lo `test -f 'src/libnm-systemd-shared/src/basic/format-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/format-util.c -src/core/libNetworkManagerBase_la-nm-ip6-config.lo: src/core/nm-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-nm-ip6-config.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip6-config.Tpo -c -o src/core/libNetworkManagerBase_la-nm-ip6-config.lo `test -f 'src/core/nm-ip6-config.c' || echo '$(srcdir)/'`src/core/nm-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip6-config.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-nm-ip6-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-ip6-config.c' object='src/core/libNetworkManagerBase_la-nm-ip6-config.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fs-util.lo: src/libnm-systemd-shared/src/basic/fs-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fs-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fs-util.lo `test -f 'src/libnm-systemd-shared/src/basic/fs-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/fs-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/fs-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fs-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-nm-ip6-config.lo `test -f 'src/core/nm-ip6-config.c' || echo '$(srcdir)/'`src/core/nm-ip6-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-fs-util.lo `test -f 'src/libnm-systemd-shared/src/basic/fs-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/fs-util.c -src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-client.lo: src/core/dhcp/nm-dhcp-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-client.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-client.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-client.lo `test -f 'src/core/dhcp/nm-dhcp-client.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-client.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-client.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-client.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-client.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hash-funcs.lo: src/libnm-systemd-shared/src/basic/hash-funcs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hash-funcs.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hash-funcs.lo `test -f 'src/libnm-systemd-shared/src/basic/hash-funcs.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/hash-funcs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/hash-funcs.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hash-funcs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-client.lo `test -f 'src/core/dhcp/nm-dhcp-client.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-client.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hash-funcs.lo `test -f 'src/libnm-systemd-shared/src/basic/hash-funcs.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/hash-funcs.c -src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-nettools.lo: src/core/dhcp/nm-dhcp-nettools.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-nettools.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-nettools.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-nettools.lo `test -f 'src/core/dhcp/nm-dhcp-nettools.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-nettools.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-nettools.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-nettools.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-nettools.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-nettools.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hashmap.lo: src/libnm-systemd-shared/src/basic/hashmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hashmap.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hashmap.lo `test -f 'src/libnm-systemd-shared/src/basic/hashmap.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/hashmap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/hashmap.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hashmap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-nettools.lo `test -f 'src/core/dhcp/nm-dhcp-nettools.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-nettools.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hashmap.lo `test -f 'src/libnm-systemd-shared/src/basic/hashmap.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/hashmap.c -src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-utils.lo: src/core/dhcp/nm-dhcp-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-utils.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-utils.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-utils.lo `test -f 'src/core/dhcp/nm-dhcp-utils.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-utils.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-utils.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hexdecoct.lo: src/libnm-systemd-shared/src/basic/hexdecoct.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hexdecoct.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hexdecoct.lo `test -f 'src/libnm-systemd-shared/src/basic/hexdecoct.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/hexdecoct.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/hexdecoct.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hexdecoct.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-utils.lo `test -f 'src/core/dhcp/nm-dhcp-utils.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hexdecoct.lo `test -f 'src/libnm-systemd-shared/src/basic/hexdecoct.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/hexdecoct.c -src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo: src/core/dhcp/nm-dhcp-options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-options.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo `test -f 'src/core/dhcp/nm-dhcp-options.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-options.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-options.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-options.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-options.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hostname-util.lo: src/libnm-systemd-shared/src/basic/hostname-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hostname-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hostname-util.lo `test -f 'src/libnm-systemd-shared/src/basic/hostname-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/hostname-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/hostname-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hostname-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-options.lo `test -f 'src/core/dhcp/nm-dhcp-options.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-options.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-hostname-util.lo `test -f 'src/libnm-systemd-shared/src/basic/hostname-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/hostname-util.c -src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo: src/core/dhcp/nm-dhcp-systemd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-systemd.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo `test -f 'src/core/dhcp/nm-dhcp-systemd.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-systemd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-systemd.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-systemd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-systemd.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-in-addr-util.lo: src/libnm-systemd-shared/src/basic/in-addr-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-in-addr-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-in-addr-util.lo `test -f 'src/libnm-systemd-shared/src/basic/in-addr-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/in-addr-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/in-addr-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-in-addr-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-systemd.lo `test -f 'src/core/dhcp/nm-dhcp-systemd.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-systemd.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-in-addr-util.lo `test -f 'src/libnm-systemd-shared/src/basic/in-addr-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/in-addr-util.c -src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo: src/core/dhcp/nm-dhcp-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo -MD -MP -MF src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-manager.Tpo -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo `test -f 'src/core/dhcp/nm-dhcp-manager.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-manager.Tpo src/core/dhcp/$(DEPDIR)/libNetworkManagerBase_la-nm-dhcp-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-manager.c' object='src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-io-util.lo: src/libnm-systemd-shared/src/basic/io-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-io-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-io-util.lo `test -f 'src/libnm-systemd-shared/src/basic/io-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/io-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/io-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-io-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/libNetworkManagerBase_la-nm-dhcp-manager.lo `test -f 'src/core/dhcp/nm-dhcp-manager.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-io-util.lo `test -f 'src/libnm-systemd-shared/src/basic/io-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/io-util.c -src/core/libNetworkManagerBase_la-main-utils.lo: src/core/main-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/libNetworkManagerBase_la-main-utils.lo -MD -MP -MF src/core/$(DEPDIR)/libNetworkManagerBase_la-main-utils.Tpo -c -o src/core/libNetworkManagerBase_la-main-utils.lo `test -f 'src/core/main-utils.c' || echo '$(srcdir)/'`src/core/main-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/libNetworkManagerBase_la-main-utils.Tpo src/core/$(DEPDIR)/libNetworkManagerBase_la-main-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/main-utils.c' object='src/core/libNetworkManagerBase_la-main-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-memory-util.lo: src/libnm-systemd-shared/src/basic/memory-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-memory-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-memory-util.lo `test -f 'src/libnm-systemd-shared/src/basic/memory-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/memory-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/memory-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-memory-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/libNetworkManagerBase_la-main-utils.lo `test -f 'src/core/main-utils.c' || echo '$(srcdir)/'`src/core/main-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-memory-util.lo `test -f 'src/libnm-systemd-shared/src/basic/memory-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/memory-util.c -src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-wext.lo: src/core/platform/wifi/nm-wifi-utils-wext.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-wext.lo -MD -MP -MF src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-wext.Tpo -c -o src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-wext.lo `test -f 'src/core/platform/wifi/nm-wifi-utils-wext.c' || echo '$(srcdir)/'`src/core/platform/wifi/nm-wifi-utils-wext.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-wext.Tpo src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-wext.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/wifi/nm-wifi-utils-wext.c' object='src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-wext.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-mempool.lo: src/libnm-systemd-shared/src/basic/mempool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-mempool.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-mempool.lo `test -f 'src/libnm-systemd-shared/src/basic/mempool.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/mempool.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/mempool.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-mempool.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerBase_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/wifi/libNetworkManagerBase_la-nm-wifi-utils-wext.lo `test -f 'src/core/platform/wifi/nm-wifi-utils-wext.c' || echo '$(srcdir)/'`src/core/platform/wifi/nm-wifi-utils-wext.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-mempool.lo `test -f 'src/libnm-systemd-shared/src/basic/mempool.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/mempool.c -src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo: src/core/ndisc/nm-fake-ndisc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo -MD -MP -MF src/core/ndisc/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-ndisc.Tpo -c -o src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo `test -f 'src/core/ndisc/nm-fake-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-fake-ndisc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-ndisc.Tpo src/core/ndisc/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-ndisc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/nm-fake-ndisc.c' object='src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-parse-util.lo: src/libnm-systemd-shared/src/basic/parse-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-parse-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-parse-util.lo `test -f 'src/libnm-systemd-shared/src/basic/parse-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/parse-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/parse-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-parse-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/libNetworkManagerTest_la-nm-fake-ndisc.lo `test -f 'src/core/ndisc/nm-fake-ndisc.c' || echo '$(srcdir)/'`src/core/ndisc/nm-fake-ndisc.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-parse-util.lo `test -f 'src/libnm-systemd-shared/src/basic/parse-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/parse-util.c -src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo: src/core/platform/nm-fake-platform.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo -MD -MP -MF src/core/platform/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-platform.Tpo -c -o src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo `test -f 'src/core/platform/nm-fake-platform.c' || echo '$(srcdir)/'`src/core/platform/nm-fake-platform.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-platform.Tpo src/core/platform/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-platform.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/nm-fake-platform.c' object='src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-path-util.lo: src/libnm-systemd-shared/src/basic/path-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-path-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-path-util.lo `test -f 'src/libnm-systemd-shared/src/basic/path-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/path-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/path-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-path-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/libNetworkManagerTest_la-nm-fake-platform.lo `test -f 'src/core/platform/nm-fake-platform.c' || echo '$(srcdir)/'`src/core/platform/nm-fake-platform.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-path-util.lo `test -f 'src/libnm-systemd-shared/src/basic/path-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/path-util.c -src/core/platform/tests/libNetworkManagerTest_la-test-common.lo: src/core/platform/tests/test-common.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/libNetworkManagerTest_la-test-common.lo -MD -MP -MF src/core/platform/tests/$(DEPDIR)/libNetworkManagerTest_la-test-common.Tpo -c -o src/core/platform/tests/libNetworkManagerTest_la-test-common.lo `test -f 'src/core/platform/tests/test-common.c' || echo '$(srcdir)/'`src/core/platform/tests/test-common.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/libNetworkManagerTest_la-test-common.Tpo src/core/platform/tests/$(DEPDIR)/libNetworkManagerTest_la-test-common.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-common.c' object='src/core/platform/tests/libNetworkManagerTest_la-test-common.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-prioq.lo: src/libnm-systemd-shared/src/basic/prioq.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-prioq.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-prioq.lo `test -f 'src/libnm-systemd-shared/src/basic/prioq.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/prioq.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/prioq.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-prioq.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libNetworkManagerTest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/libNetworkManagerTest_la-test-common.lo `test -f 'src/core/platform/tests/test-common.c' || echo '$(srcdir)/'`src/core/platform/tests/test-common.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-prioq.lo `test -f 'src/libnm-systemd-shared/src/basic/prioq.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/prioq.c -src/core/systemd/libnm_systemd_core_la-nm-sd-utils-core.lo: src/core/systemd/nm-sd-utils-core.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/libnm_systemd_core_la-nm-sd-utils-core.lo -MD -MP -MF src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-core.Tpo -c -o src/core/systemd/libnm_systemd_core_la-nm-sd-utils-core.lo `test -f 'src/core/systemd/nm-sd-utils-core.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd-utils-core.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-core.Tpo src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-core.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/nm-sd-utils-core.c' object='src/core/systemd/libnm_systemd_core_la-nm-sd-utils-core.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-process-util.lo: src/libnm-systemd-shared/src/basic/process-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-process-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-process-util.lo `test -f 'src/libnm-systemd-shared/src/basic/process-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/process-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/process-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-process-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/libnm_systemd_core_la-nm-sd-utils-core.lo `test -f 'src/core/systemd/nm-sd-utils-core.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd-utils-core.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-process-util.lo `test -f 'src/libnm-systemd-shared/src/basic/process-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/process-util.c -src/core/systemd/libnm_systemd_core_la-nm-sd.lo: src/core/systemd/nm-sd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/libnm_systemd_core_la-nm-sd.lo -MD -MP -MF src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd.Tpo -c -o src/core/systemd/libnm_systemd_core_la-nm-sd.lo `test -f 'src/core/systemd/nm-sd.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd.Tpo src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/nm-sd.c' object='src/core/systemd/libnm_systemd_core_la-nm-sd.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-random-util.lo: src/libnm-systemd-shared/src/basic/random-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-random-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-random-util.lo `test -f 'src/libnm-systemd-shared/src/basic/random-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/random-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/random-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-random-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/libnm_systemd_core_la-nm-sd.lo `test -f 'src/core/systemd/nm-sd.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-random-util.lo `test -f 'src/libnm-systemd-shared/src/basic/random-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/random-util.c -src/core/systemd/libnm_systemd_core_la-nm-sd-utils-dhcp.lo: src/core/systemd/nm-sd-utils-dhcp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/libnm_systemd_core_la-nm-sd-utils-dhcp.lo -MD -MP -MF src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-dhcp.Tpo -c -o src/core/systemd/libnm_systemd_core_la-nm-sd-utils-dhcp.lo `test -f 'src/core/systemd/nm-sd-utils-dhcp.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd-utils-dhcp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-dhcp.Tpo src/core/systemd/$(DEPDIR)/libnm_systemd_core_la-nm-sd-utils-dhcp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/nm-sd-utils-dhcp.c' object='src/core/systemd/libnm_systemd_core_la-nm-sd-utils-dhcp.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ratelimit.lo: src/libnm-systemd-shared/src/basic/ratelimit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ratelimit.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ratelimit.lo `test -f 'src/libnm-systemd-shared/src/basic/ratelimit.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/ratelimit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/ratelimit.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ratelimit.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/libnm_systemd_core_la-nm-sd-utils-dhcp.lo `test -f 'src/core/systemd/nm-sd-utils-dhcp.c' || echo '$(srcdir)/'`src/core/systemd/nm-sd-utils-dhcp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-ratelimit.lo `test -f 'src/libnm-systemd-shared/src/basic/ratelimit.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/ratelimit.c -src/core/systemd/sd-adapt-core/libnm_systemd_core_la-nm-sd-adapt-core.lo: src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/sd-adapt-core/libnm_systemd_core_la-nm-sd-adapt-core.lo -MD -MP -MF src/core/systemd/sd-adapt-core/$(DEPDIR)/libnm_systemd_core_la-nm-sd-adapt-core.Tpo -c -o src/core/systemd/sd-adapt-core/libnm_systemd_core_la-nm-sd-adapt-core.lo `test -f 'src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c' || echo '$(srcdir)/'`src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/sd-adapt-core/$(DEPDIR)/libnm_systemd_core_la-nm-sd-adapt-core.Tpo src/core/systemd/sd-adapt-core/$(DEPDIR)/libnm_systemd_core_la-nm-sd-adapt-core.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c' object='src/core/systemd/sd-adapt-core/libnm_systemd_core_la-nm-sd-adapt-core.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-signal-util.lo: src/libnm-systemd-shared/src/basic/signal-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-signal-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-signal-util.lo `test -f 'src/libnm-systemd-shared/src/basic/signal-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/signal-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/signal-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-signal-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/sd-adapt-core/libnm_systemd_core_la-nm-sd-adapt-core.lo `test -f 'src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c' || echo '$(srcdir)/'`src/core/systemd/sd-adapt-core/nm-sd-adapt-core.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-signal-util.lo `test -f 'src/libnm-systemd-shared/src/basic/signal-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/signal-util.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-arp-util.lo: src/core/systemd/src/libsystemd-network/arp-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-arp-util.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-arp-util.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-arp-util.lo `test -f 'src/core/systemd/src/libsystemd-network/arp-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/arp-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-arp-util.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-arp-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/arp-util.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-arp-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-socket-util.lo: src/libnm-systemd-shared/src/basic/socket-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-socket-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-socket-util.lo `test -f 'src/libnm-systemd-shared/src/basic/socket-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/socket-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/socket-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-socket-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-arp-util.lo `test -f 'src/core/systemd/src/libsystemd-network/arp-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/arp-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-socket-util.lo `test -f 'src/libnm-systemd-shared/src/basic/socket-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/socket-util.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-identifier.lo: src/core/systemd/src/libsystemd-network/dhcp-identifier.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-identifier.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-identifier.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-identifier.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-identifier.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-identifier.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-identifier.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-identifier.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp-identifier.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-identifier.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-stat-util.lo: src/libnm-systemd-shared/src/basic/stat-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-stat-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-stat-util.lo `test -f 'src/libnm-systemd-shared/src/basic/stat-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/stat-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/stat-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-stat-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-identifier.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-identifier.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-identifier.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-stat-util.lo `test -f 'src/libnm-systemd-shared/src/basic/stat-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/stat-util.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-network.lo: src/core/systemd/src/libsystemd-network/dhcp-network.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-network.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-network.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-network.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-network.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-network.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-network.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp-network.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-network.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-table.lo: src/libnm-systemd-shared/src/basic/string-table.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-table.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-table.lo `test -f 'src/libnm-systemd-shared/src/basic/string-table.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/string-table.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/string-table.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-table.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-network.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-network.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-table.lo `test -f 'src/libnm-systemd-shared/src/basic/string-table.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/string-table.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-option.lo: src/core/systemd/src/libsystemd-network/dhcp-option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-option.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-option.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-option.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-option.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-option.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-option.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-option.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp-option.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-option.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-util.lo: src/libnm-systemd-shared/src/basic/string-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-util.lo `test -f 'src/libnm-systemd-shared/src/basic/string-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/string-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/string-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-option.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-option.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-option.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-string-util.lo `test -f 'src/libnm-systemd-shared/src/basic/string-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/string-util.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-packet.lo: src/core/systemd/src/libsystemd-network/dhcp-packet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-packet.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-packet.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-packet.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-packet.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-packet.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-packet.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp-packet.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp-packet.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-packet.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strv.lo: src/libnm-systemd-shared/src/basic/strv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strv.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strv.lo `test -f 'src/libnm-systemd-shared/src/basic/strv.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/strv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/strv.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp-packet.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp-packet.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp-packet.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strv.lo `test -f 'src/libnm-systemd-shared/src/basic/strv.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/strv.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-network.lo: src/core/systemd/src/libsystemd-network/dhcp6-network.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-network.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-network.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-network.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp6-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp6-network.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-network.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-network.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp6-network.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-network.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strxcpyx.lo: src/libnm-systemd-shared/src/basic/strxcpyx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strxcpyx.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strxcpyx.lo `test -f 'src/libnm-systemd-shared/src/basic/strxcpyx.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/strxcpyx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/strxcpyx.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strxcpyx.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-network.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp6-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp6-network.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-strxcpyx.lo `test -f 'src/libnm-systemd-shared/src/basic/strxcpyx.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/strxcpyx.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-option.lo: src/core/systemd/src/libsystemd-network/dhcp6-option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-option.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-option.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-option.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp6-option.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp6-option.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-option.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-dhcp6-option.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/dhcp6-option.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-option.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-time-util.lo: src/libnm-systemd-shared/src/basic/time-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-time-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-time-util.lo `test -f 'src/libnm-systemd-shared/src/basic/time-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/time-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/time-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-time-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-dhcp6-option.lo `test -f 'src/core/systemd/src/libsystemd-network/dhcp6-option.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/dhcp6-option.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-time-util.lo `test -f 'src/libnm-systemd-shared/src/basic/time-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/time-util.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-neighbor.lo: src/core/systemd/src/libsystemd-network/lldp-neighbor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-neighbor.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-neighbor.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-neighbor.lo `test -f 'src/core/systemd/src/libsystemd-network/lldp-neighbor.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/lldp-neighbor.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-neighbor.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-neighbor.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/lldp-neighbor.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-neighbor.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-tmpfile-util.lo: src/libnm-systemd-shared/src/basic/tmpfile-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-tmpfile-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-tmpfile-util.lo `test -f 'src/libnm-systemd-shared/src/basic/tmpfile-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/tmpfile-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/tmpfile-util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-tmpfile-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-neighbor.lo `test -f 'src/core/systemd/src/libsystemd-network/lldp-neighbor.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/lldp-neighbor.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-tmpfile-util.lo `test -f 'src/libnm-systemd-shared/src/basic/tmpfile-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/tmpfile-util.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-network.lo: src/core/systemd/src/libsystemd-network/lldp-network.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-network.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-network.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-network.lo `test -f 'src/core/systemd/src/libsystemd-network/lldp-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/lldp-network.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-network.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-lldp-network.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/lldp-network.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-network.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-utf8.lo: src/libnm-systemd-shared/src/basic/utf8.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-utf8.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-utf8.lo `test -f 'src/libnm-systemd-shared/src/basic/utf8.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/utf8.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/utf8.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-utf8.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-lldp-network.lo `test -f 'src/core/systemd/src/libsystemd-network/lldp-network.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/lldp-network.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-utf8.lo `test -f 'src/libnm-systemd-shared/src/basic/utf8.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/utf8.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-network-internal.lo: src/core/systemd/src/libsystemd-network/network-internal.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-network-internal.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-network-internal.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-network-internal.lo `test -f 'src/core/systemd/src/libsystemd-network/network-internal.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/network-internal.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-network-internal.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-network-internal.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/network-internal.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-network-internal.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-util.lo: src/libnm-systemd-shared/src/basic/util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-util.lo -MD -MP -MF src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Tpo -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-util.lo `test -f 'src/libnm-systemd-shared/src/basic/util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Tpo src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/basic/util.c' object='src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-network-internal.lo `test -f 'src/core/systemd/src/libsystemd-network/network-internal.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/network-internal.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/basic/libnm_systemd_shared_la-util.lo `test -f 'src/libnm-systemd-shared/src/basic/util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/basic/util.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-client.lo: src/core/systemd/src/libsystemd-network/sd-dhcp-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-client.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-client.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-client.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp-client.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-client.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-client.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-dhcp-client.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-client.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-dns-domain.lo: src/libnm-systemd-shared/src/shared/dns-domain.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-dns-domain.lo -MD -MP -MF src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Tpo -c -o src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-dns-domain.lo `test -f 'src/libnm-systemd-shared/src/shared/dns-domain.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/shared/dns-domain.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Tpo src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/shared/dns-domain.c' object='src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-dns-domain.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-client.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp-client.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp-client.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-dns-domain.lo `test -f 'src/libnm-systemd-shared/src/shared/dns-domain.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/shared/dns-domain.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-lease.lo: src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-lease.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-lease.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-lease.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-lease.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp-lease.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-lease.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-web-util.lo: src/libnm-systemd-shared/src/shared/web-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-web-util.lo -MD -MP -MF src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Tpo -c -o src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-web-util.lo `test -f 'src/libnm-systemd-shared/src/shared/web-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/shared/web-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Tpo src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-systemd-shared/src/shared/web-util.c' object='src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-web-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp-lease.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp-lease.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_systemd_shared_libnm_systemd_shared_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-systemd-shared/src/shared/libnm_systemd_shared_la-web-util.lo `test -f 'src/libnm-systemd-shared/src/shared/web-util.c' || echo '$(srcdir)/'`src/libnm-systemd-shared/src/shared/web-util.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-client.lo: src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-client.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-client.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-client.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-client.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-client.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-client.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo: src/libnm-udev-aux/nm-udev-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_udev_aux_libnm_udev_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo -MD -MP -MF src/libnm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Tpo -c -o src/libnm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo `test -f 'src/libnm-udev-aux/nm-udev-utils.c' || echo '$(srcdir)/'`src/libnm-udev-aux/nm-udev-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Tpo src/libnm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-udev-aux/nm-udev-utils.c' object='src/libnm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-client.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_udev_aux_libnm_udev_aux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-udev-aux/libnm_udev_aux_la-nm-udev-utils.lo `test -f 'src/libnm-udev-aux/nm-udev-utils.c' || echo '$(srcdir)/'`src/libnm-udev-aux/nm-udev-utils.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-lease.lo: src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-lease.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-lease.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-lease.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-lease.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-dhcp6-lease.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-lease.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnmc-base/libnmc_base_la-nm-client-utils.lo: src/libnmc-base/nm-client-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_base_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmc-base/libnmc_base_la-nm-client-utils.lo -MD -MP -MF src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-client-utils.Tpo -c -o src/libnmc-base/libnmc_base_la-nm-client-utils.lo `test -f 'src/libnmc-base/nm-client-utils.c' || echo '$(srcdir)/'`src/libnmc-base/nm-client-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-client-utils.Tpo src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-client-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmc-base/nm-client-utils.c' object='src/libnmc-base/libnmc_base_la-nm-client-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-dhcp6-lease.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_base_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmc-base/libnmc_base_la-nm-client-utils.lo `test -f 'src/libnmc-base/nm-client-utils.c' || echo '$(srcdir)/'`src/libnmc-base/nm-client-utils.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4acd.lo: src/core/systemd/src/libsystemd-network/sd-ipv4acd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4acd.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4acd.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4acd.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-ipv4acd.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-ipv4acd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4acd.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4acd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-ipv4acd.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4acd.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnmc-base/libnmc_base_la-nm-polkit-listener.lo: src/libnmc-base/nm-polkit-listener.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_base_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmc-base/libnmc_base_la-nm-polkit-listener.lo -MD -MP -MF src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Tpo -c -o src/libnmc-base/libnmc_base_la-nm-polkit-listener.lo `test -f 'src/libnmc-base/nm-polkit-listener.c' || echo '$(srcdir)/'`src/libnmc-base/nm-polkit-listener.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Tpo src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmc-base/nm-polkit-listener.c' object='src/libnmc-base/libnmc_base_la-nm-polkit-listener.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4acd.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-ipv4acd.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-ipv4acd.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_base_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmc-base/libnmc_base_la-nm-polkit-listener.lo `test -f 'src/libnmc-base/nm-polkit-listener.c' || echo '$(srcdir)/'`src/libnmc-base/nm-polkit-listener.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4ll.lo: src/core/systemd/src/libsystemd-network/sd-ipv4ll.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4ll.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4ll.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4ll.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-ipv4ll.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-ipv4ll.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4ll.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-ipv4ll.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-ipv4ll.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4ll.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnmc-base/libnmc_base_la-nm-secret-agent-simple.lo: src/libnmc-base/nm-secret-agent-simple.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_base_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmc-base/libnmc_base_la-nm-secret-agent-simple.lo -MD -MP -MF src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Tpo -c -o src/libnmc-base/libnmc_base_la-nm-secret-agent-simple.lo `test -f 'src/libnmc-base/nm-secret-agent-simple.c' || echo '$(srcdir)/'`src/libnmc-base/nm-secret-agent-simple.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Tpo src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmc-base/nm-secret-agent-simple.c' object='src/libnmc-base/libnmc_base_la-nm-secret-agent-simple.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-ipv4ll.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-ipv4ll.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-ipv4ll.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_base_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmc-base/libnmc_base_la-nm-secret-agent-simple.lo `test -f 'src/libnmc-base/nm-secret-agent-simple.c' || echo '$(srcdir)/'`src/libnmc-base/nm-secret-agent-simple.c -src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-lldp.lo: src/core/systemd/src/libsystemd-network/sd-lldp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-lldp.lo -MD -MP -MF src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-lldp.Tpo -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-lldp.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-lldp.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-lldp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-lldp.Tpo src/core/systemd/src/libsystemd-network/$(DEPDIR)/libnm_systemd_core_la-sd-lldp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd-network/sd-lldp.c' object='src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-lldp.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnmc-base/libnmc_base_la-nm-vpn-helpers.lo: src/libnmc-base/nm-vpn-helpers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_base_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmc-base/libnmc_base_la-nm-vpn-helpers.lo -MD -MP -MF src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Tpo -c -o src/libnmc-base/libnmc_base_la-nm-vpn-helpers.lo `test -f 'src/libnmc-base/nm-vpn-helpers.c' || echo '$(srcdir)/'`src/libnmc-base/nm-vpn-helpers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Tpo src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmc-base/nm-vpn-helpers.c' object='src/libnmc-base/libnmc_base_la-nm-vpn-helpers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd-network/libnm_systemd_core_la-sd-lldp.lo `test -f 'src/core/systemd/src/libsystemd-network/sd-lldp.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd-network/sd-lldp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_base_libnmc_base_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmc-base/libnmc_base_la-nm-vpn-helpers.lo `test -f 'src/libnmc-base/nm-vpn-helpers.c' || echo '$(srcdir)/'`src/libnmc-base/nm-vpn-helpers.c -src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-event-util.lo: src/core/systemd/src/libsystemd/sd-event/event-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-event-util.lo -MD -MP -MF src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-event-util.Tpo -c -o src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-event-util.lo `test -f 'src/core/systemd/src/libsystemd/sd-event/event-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-event/event-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-event-util.Tpo src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-event-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd/sd-event/event-util.c' object='src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-event-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnmc-setting/libnmc_setting_la-nm-meta-setting-access.lo: src/libnmc-setting/nm-meta-setting-access.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_setting_libnmc_setting_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmc-setting/libnmc_setting_la-nm-meta-setting-access.lo -MD -MP -MF src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-access.Tpo -c -o src/libnmc-setting/libnmc_setting_la-nm-meta-setting-access.lo `test -f 'src/libnmc-setting/nm-meta-setting-access.c' || echo '$(srcdir)/'`src/libnmc-setting/nm-meta-setting-access.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-access.Tpo src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-access.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmc-setting/nm-meta-setting-access.c' object='src/libnmc-setting/libnmc_setting_la-nm-meta-setting-access.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-event-util.lo `test -f 'src/core/systemd/src/libsystemd/sd-event/event-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-event/event-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_setting_libnmc_setting_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmc-setting/libnmc_setting_la-nm-meta-setting-access.lo `test -f 'src/libnmc-setting/nm-meta-setting-access.c' || echo '$(srcdir)/'`src/libnmc-setting/nm-meta-setting-access.c -src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-sd-event.lo: src/core/systemd/src/libsystemd/sd-event/sd-event.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-sd-event.lo -MD -MP -MF src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-sd-event.Tpo -c -o src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-sd-event.lo `test -f 'src/core/systemd/src/libsystemd/sd-event/sd-event.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-event/sd-event.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-sd-event.Tpo src/core/systemd/src/libsystemd/sd-event/$(DEPDIR)/libnm_systemd_core_la-sd-event.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd/sd-event/sd-event.c' object='src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-sd-event.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnmc-setting/libnmc_setting_la-nm-meta-setting-base-impl.lo: src/libnmc-setting/nm-meta-setting-base-impl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_setting_libnmc_setting_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmc-setting/libnmc_setting_la-nm-meta-setting-base-impl.lo -MD -MP -MF src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-base-impl.Tpo -c -o src/libnmc-setting/libnmc_setting_la-nm-meta-setting-base-impl.lo `test -f 'src/libnmc-setting/nm-meta-setting-base-impl.c' || echo '$(srcdir)/'`src/libnmc-setting/nm-meta-setting-base-impl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-base-impl.Tpo src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-base-impl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmc-setting/nm-meta-setting-base-impl.c' object='src/libnmc-setting/libnmc_setting_la-nm-meta-setting-base-impl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd/sd-event/libnm_systemd_core_la-sd-event.lo `test -f 'src/core/systemd/src/libsystemd/sd-event/sd-event.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-event/sd-event.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_setting_libnmc_setting_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmc-setting/libnmc_setting_la-nm-meta-setting-base-impl.lo `test -f 'src/libnmc-setting/nm-meta-setting-base-impl.c' || echo '$(srcdir)/'`src/libnmc-setting/nm-meta-setting-base-impl.c -src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-id128-util.lo: src/core/systemd/src/libsystemd/sd-id128/id128-util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-id128-util.lo -MD -MP -MF src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-id128-util.Tpo -c -o src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-id128-util.lo `test -f 'src/core/systemd/src/libsystemd/sd-id128/id128-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-id128/id128-util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-id128-util.Tpo src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-id128-util.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd/sd-id128/id128-util.c' object='src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-id128-util.lo' libtool=yes @AMDEPBACKSLASH@ +src/libnmc-setting/libnmc_setting_la-nm-meta-setting-desc.lo: src/libnmc-setting/nm-meta-setting-desc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_setting_libnmc_setting_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmc-setting/libnmc_setting_la-nm-meta-setting-desc.lo -MD -MP -MF src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-desc.Tpo -c -o src/libnmc-setting/libnmc_setting_la-nm-meta-setting-desc.lo `test -f 'src/libnmc-setting/nm-meta-setting-desc.c' || echo '$(srcdir)/'`src/libnmc-setting/nm-meta-setting-desc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-desc.Tpo src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-desc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmc-setting/nm-meta-setting-desc.c' object='src/libnmc-setting/libnmc_setting_la-nm-meta-setting-desc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-id128-util.lo `test -f 'src/core/systemd/src/libsystemd/sd-id128/id128-util.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-id128/id128-util.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_setting_libnmc_setting_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmc-setting/libnmc_setting_la-nm-meta-setting-desc.lo `test -f 'src/libnmc-setting/nm-meta-setting-desc.c' || echo '$(srcdir)/'`src/libnmc-setting/nm-meta-setting-desc.c -src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-sd-id128.lo: src/core/systemd/src/libsystemd/sd-id128/sd-id128.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-sd-id128.lo -MD -MP -MF src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-sd-id128.Tpo -c -o src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-sd-id128.lo `test -f 'src/core/systemd/src/libsystemd/sd-id128/sd-id128.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-id128/sd-id128.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-sd-id128.Tpo src/core/systemd/src/libsystemd/sd-id128/$(DEPDIR)/libnm_systemd_core_la-sd-id128.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/systemd/src/libsystemd/sd-id128/sd-id128.c' object='src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-sd-id128.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-acd/src/libn_acd_la-n-acd.lo: src/n-acd/src/n-acd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_acd_libn_acd_la_CPPFLAGS) $(CPPFLAGS) $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) -MT src/n-acd/src/libn_acd_la-n-acd.lo -MD -MP -MF src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd.Tpo -c -o src/n-acd/src/libn_acd_la-n-acd.lo `test -f 'src/n-acd/src/n-acd.c' || echo '$(srcdir)/'`src/n-acd/src/n-acd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd.Tpo src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-acd/src/n-acd.c' object='src/n-acd/src/libn_acd_la-n-acd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_libnm_systemd_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/systemd/src/libsystemd/sd-id128/libnm_systemd_core_la-sd-id128.lo `test -f 'src/core/systemd/src/libsystemd/sd-id128/sd-id128.c' || echo '$(srcdir)/'`src/core/systemd/src/libsystemd/sd-id128/sd-id128.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_acd_libn_acd_la_CPPFLAGS) $(CPPFLAGS) $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) -c -o src/n-acd/src/libn_acd_la-n-acd.lo `test -f 'src/n-acd/src/n-acd.c' || echo '$(srcdir)/'`src/n-acd/src/n-acd.c -src/core/ppp/libnm_ppp_plugin_la-nm-ppp-manager.lo: src/core/ppp/nm-ppp-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ppp_libnm_ppp_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ppp/libnm_ppp_plugin_la-nm-ppp-manager.lo -MD -MP -MF src/core/ppp/$(DEPDIR)/libnm_ppp_plugin_la-nm-ppp-manager.Tpo -c -o src/core/ppp/libnm_ppp_plugin_la-nm-ppp-manager.lo `test -f 'src/core/ppp/nm-ppp-manager.c' || echo '$(srcdir)/'`src/core/ppp/nm-ppp-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ppp/$(DEPDIR)/libnm_ppp_plugin_la-nm-ppp-manager.Tpo src/core/ppp/$(DEPDIR)/libnm_ppp_plugin_la-nm-ppp-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ppp/nm-ppp-manager.c' object='src/core/ppp/libnm_ppp_plugin_la-nm-ppp-manager.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-acd/src/libn_acd_la-n-acd-probe.lo: src/n-acd/src/n-acd-probe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_acd_libn_acd_la_CPPFLAGS) $(CPPFLAGS) $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) -MT src/n-acd/src/libn_acd_la-n-acd-probe.lo -MD -MP -MF src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-probe.Tpo -c -o src/n-acd/src/libn_acd_la-n-acd-probe.lo `test -f 'src/n-acd/src/n-acd-probe.c' || echo '$(srcdir)/'`src/n-acd/src/n-acd-probe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-probe.Tpo src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-probe.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-acd/src/n-acd-probe.c' object='src/n-acd/src/libn_acd_la-n-acd-probe.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ppp_libnm_ppp_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ppp/libnm_ppp_plugin_la-nm-ppp-manager.lo `test -f 'src/core/ppp/nm-ppp-manager.c' || echo '$(srcdir)/'`src/core/ppp/nm-ppp-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_acd_libn_acd_la_CPPFLAGS) $(CPPFLAGS) $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) -c -o src/n-acd/src/libn_acd_la-n-acd-probe.lo `test -f 'src/n-acd/src/n-acd-probe.c' || echo '$(srcdir)/'`src/n-acd/src/n-acd-probe.c -src/core/ppp/nm_pppd_plugin_la-nm-pppd-plugin.lo: src/core/ppp/nm-pppd-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ppp_nm_pppd_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ppp/nm_pppd_plugin_la-nm-pppd-plugin.lo -MD -MP -MF src/core/ppp/$(DEPDIR)/nm_pppd_plugin_la-nm-pppd-plugin.Tpo -c -o src/core/ppp/nm_pppd_plugin_la-nm-pppd-plugin.lo `test -f 'src/core/ppp/nm-pppd-plugin.c' || echo '$(srcdir)/'`src/core/ppp/nm-pppd-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ppp/$(DEPDIR)/nm_pppd_plugin_la-nm-pppd-plugin.Tpo src/core/ppp/$(DEPDIR)/nm_pppd_plugin_la-nm-pppd-plugin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ppp/nm-pppd-plugin.c' object='src/core/ppp/nm_pppd_plugin_la-nm-pppd-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-acd/src/util/libn_acd_la-timer.lo: src/n-acd/src/util/timer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_acd_libn_acd_la_CPPFLAGS) $(CPPFLAGS) $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) -MT src/n-acd/src/util/libn_acd_la-timer.lo -MD -MP -MF src/n-acd/src/util/$(DEPDIR)/libn_acd_la-timer.Tpo -c -o src/n-acd/src/util/libn_acd_la-timer.lo `test -f 'src/n-acd/src/util/timer.c' || echo '$(srcdir)/'`src/n-acd/src/util/timer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-acd/src/util/$(DEPDIR)/libn_acd_la-timer.Tpo src/n-acd/src/util/$(DEPDIR)/libn_acd_la-timer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-acd/src/util/timer.c' object='src/n-acd/src/util/libn_acd_la-timer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ppp_nm_pppd_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ppp/nm_pppd_plugin_la-nm-pppd-plugin.lo `test -f 'src/core/ppp/nm-pppd-plugin.c' || echo '$(srcdir)/'`src/core/ppp/nm-pppd-plugin.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_acd_libn_acd_la_CPPFLAGS) $(CPPFLAGS) $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) -c -o src/n-acd/src/util/libn_acd_la-timer.lo `test -f 'src/n-acd/src/util/timer.c' || echo '$(srcdir)/'`src/n-acd/src/util/timer.c -src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.lo: src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c' object='src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-acd/src/libn_acd_la-n-acd-bpf.lo: src/n-acd/src/n-acd-bpf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_acd_libn_acd_la_CPPFLAGS) $(CPPFLAGS) $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) -MT src/n-acd/src/libn_acd_la-n-acd-bpf.lo -MD -MP -MF src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf.Tpo -c -o src/n-acd/src/libn_acd_la-n-acd-bpf.lo `test -f 'src/n-acd/src/n-acd-bpf.c' || echo '$(srcdir)/'`src/n-acd/src/n-acd-bpf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf.Tpo src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-acd/src/n-acd-bpf.c' object='src/n-acd/src/libn_acd_la-n-acd-bpf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-storage.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_acd_libn_acd_la_CPPFLAGS) $(CPPFLAGS) $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) -c -o src/n-acd/src/libn_acd_la-n-acd-bpf.lo `test -f 'src/n-acd/src/n-acd-bpf.c' || echo '$(srcdir)/'`src/n-acd/src/n-acd-bpf.c -src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.lo: src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c' object='src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-acd/src/libn_acd_la-n-acd-bpf-fallback.lo: src/n-acd/src/n-acd-bpf-fallback.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_acd_libn_acd_la_CPPFLAGS) $(CPPFLAGS) $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) -MT src/n-acd/src/libn_acd_la-n-acd-bpf-fallback.lo -MD -MP -MF src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf-fallback.Tpo -c -o src/n-acd/src/libn_acd_la-n-acd-bpf-fallback.lo `test -f 'src/n-acd/src/n-acd-bpf-fallback.c' || echo '$(srcdir)/'`src/n-acd/src/n-acd-bpf-fallback.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf-fallback.Tpo src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf-fallback.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-acd/src/n-acd-bpf-fallback.c' object='src/n-acd/src/libn_acd_la-n-acd-bpf-fallback.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnm_settings_plugin_ifcfg_rh_la-nms-ifcfg-rh-plugin.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_acd_libn_acd_la_CPPFLAGS) $(CPPFLAGS) $(src_n_acd_libn_acd_la_CFLAGS) $(CFLAGS) -c -o src/n-acd/src/libn_acd_la-n-acd-bpf-fallback.lo `test -f 'src/n-acd/src/n-acd-bpf-fallback.c' || echo '$(srcdir)/'`src/n-acd/src/n-acd-bpf-fallback.c -src/core/settings/plugins/ifcfg-rh/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.lo: src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnmdbus_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c' object='src/core/settings/plugins/ifcfg-rh/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-connection.lo: src/n-dhcp4/src/n-dhcp4-c-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -MT src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-connection.lo -MD -MP -MF src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-connection.Tpo -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-connection.lo `test -f 'src/n-dhcp4/src/n-dhcp4-c-connection.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-c-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-connection.Tpo src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-dhcp4/src/n-dhcp4-c-connection.c' object='src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnmdbus_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnmdbus_ifcfg_rh_la-nmdbus-ifcfg-rh.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-connection.lo `test -f 'src/n-dhcp4/src/n-dhcp4-c-connection.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-c-connection.c -src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-shvar.lo: src/core/settings/plugins/ifcfg-rh/shvar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-shvar.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-shvar.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-shvar.lo `test -f 'src/core/settings/plugins/ifcfg-rh/shvar.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/shvar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-shvar.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-shvar.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/shvar.c' object='src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-shvar.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-lease.lo: src/n-dhcp4/src/n-dhcp4-c-lease.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -MT src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-lease.lo -MD -MP -MF src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-lease.Tpo -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-lease.lo `test -f 'src/n-dhcp4/src/n-dhcp4-c-lease.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-c-lease.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-lease.Tpo src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-lease.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-dhcp4/src/n-dhcp4-c-lease.c' object='src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-lease.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-shvar.lo `test -f 'src/core/settings/plugins/ifcfg-rh/shvar.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/shvar.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-lease.lo `test -f 'src/n-dhcp4/src/n-dhcp4-c-lease.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-c-lease.c -src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.lo: src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c' object='src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-probe.lo: src/n-dhcp4/src/n-dhcp4-c-probe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -MT src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-probe.lo -MD -MP -MF src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-probe.Tpo -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-probe.lo `test -f 'src/n-dhcp4/src/n-dhcp4-c-probe.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-c-probe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-probe.Tpo src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-probe.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-dhcp4/src/n-dhcp4-c-probe.c' object='src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-probe.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-utils.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-c-probe.lo `test -f 'src/n-dhcp4/src/n-dhcp4-c-probe.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-c-probe.c -src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.lo: src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c' object='src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-client.lo: src/n-dhcp4/src/n-dhcp4-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -MT src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-client.lo -MD -MP -MF src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-client.Tpo -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-client.lo `test -f 'src/n-dhcp4/src/n-dhcp4-client.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-client.Tpo src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-dhcp4/src/n-dhcp4-client.c' object='src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-client.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-reader.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-client.lo `test -f 'src/n-dhcp4/src/n-dhcp4-client.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-client.c -src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.lo: src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.lo -MD -MP -MF src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.Tpo -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.Tpo src/core/settings/plugins/ifcfg-rh/$(DEPDIR)/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c' object='src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-incoming.lo: src/n-dhcp4/src/n-dhcp4-incoming.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -MT src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-incoming.lo -MD -MP -MF src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-incoming.Tpo -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-incoming.lo `test -f 'src/n-dhcp4/src/n-dhcp4-incoming.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-incoming.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-incoming.Tpo src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-incoming.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-dhcp4/src/n-dhcp4-incoming.c' object='src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-incoming.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/libnms_ifcfg_rh_core_la-nms-ifcfg-rh-writer.lo `test -f 'src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-incoming.lo `test -f 'src/n-dhcp4/src/n-dhcp4-incoming.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-incoming.c -src/core/settings/plugins/ifupdown/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.lo: src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifupdown/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.lo -MD -MP -MF src/core/settings/plugins/ifupdown/$(DEPDIR)/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.Tpo -c -o src/core/settings/plugins/ifupdown/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifupdown/$(DEPDIR)/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.Tpo src/core/settings/plugins/ifupdown/$(DEPDIR)/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c' object='src/core/settings/plugins/ifupdown/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-outgoing.lo: src/n-dhcp4/src/n-dhcp4-outgoing.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -MT src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-outgoing.lo -MD -MP -MF src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-outgoing.Tpo -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-outgoing.lo `test -f 'src/n-dhcp4/src/n-dhcp4-outgoing.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-outgoing.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-outgoing.Tpo src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-outgoing.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-dhcp4/src/n-dhcp4-outgoing.c' object='src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-outgoing.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifupdown/libnm_settings_plugin_ifupdown_la-nms-ifupdown-plugin.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-outgoing.lo `test -f 'src/n-dhcp4/src/n-dhcp4-outgoing.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-outgoing.c -src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.lo: src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.lo -MD -MP -MF src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.Tpo -c -o src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.Tpo src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c' object='src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-socket.lo: src/n-dhcp4/src/n-dhcp4-socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -MT src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-socket.lo -MD -MP -MF src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-socket.Tpo -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-socket.lo `test -f 'src/n-dhcp4/src/n-dhcp4-socket.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-socket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-socket.Tpo src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-socket.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-dhcp4/src/n-dhcp4-socket.c' object='src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-socket.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-interface-parser.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -c -o src/n-dhcp4/src/libn_dhcp4_la-n-dhcp4-socket.lo `test -f 'src/n-dhcp4/src/n-dhcp4-socket.c' || echo '$(srcdir)/'`src/n-dhcp4/src/n-dhcp4-socket.c -src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo: src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo -MD -MP -MF src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-parser.Tpo -c -o src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-parser.Tpo src/core/settings/plugins/ifupdown/$(DEPDIR)/libnms_ifupdown_core_la-nms-ifupdown-parser.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c' object='src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo' libtool=yes @AMDEPBACKSLASH@ +src/n-dhcp4/src/util/libn_dhcp4_la-packet.lo: src/n-dhcp4/src/util/packet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -MT src/n-dhcp4/src/util/libn_dhcp4_la-packet.lo -MD -MP -MF src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-packet.Tpo -c -o src/n-dhcp4/src/util/libn_dhcp4_la-packet.lo `test -f 'src/n-dhcp4/src/util/packet.c' || echo '$(srcdir)/'`src/n-dhcp4/src/util/packet.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-packet.Tpo src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-packet.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-dhcp4/src/util/packet.c' object='src/n-dhcp4/src/util/libn_dhcp4_la-packet.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifupdown/libnms_ifupdown_core_la-nms-ifupdown-parser.lo `test -f 'src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -c -o src/n-dhcp4/src/util/libn_dhcp4_la-packet.lo `test -f 'src/n-dhcp4/src/util/packet.c' || echo '$(srcdir)/'`src/n-dhcp4/src/util/packet.c + +src/n-dhcp4/src/util/libn_dhcp4_la-socket.lo: src/n-dhcp4/src/util/socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -MT src/n-dhcp4/src/util/libn_dhcp4_la-socket.lo -MD -MP -MF src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-socket.Tpo -c -o src/n-dhcp4/src/util/libn_dhcp4_la-socket.lo `test -f 'src/n-dhcp4/src/util/socket.c' || echo '$(srcdir)/'`src/n-dhcp4/src/util/socket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-socket.Tpo src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-socket.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/n-dhcp4/src/util/socket.c' object='src/n-dhcp4/src/util/libn_dhcp4_la-socket.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_n_dhcp4_libn_dhcp4_la_CPPFLAGS) $(CPPFLAGS) $(src_n_dhcp4_libn_dhcp4_la_CFLAGS) $(CFLAGS) -c -o src/n-dhcp4/src/util/libn_dhcp4_la-socket.lo `test -f 'src/n-dhcp4/src/util/socket.c' || echo '$(srcdir)/'`src/n-dhcp4/src/util/socket.c -clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.o: clients/cli/generate-docs-nm-settings-nmcli.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_generate_docs_nm_settings_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.o -MD -MP -MF clients/cli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Tpo -c -o clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.o `test -f 'clients/cli/generate-docs-nm-settings-nmcli.c' || echo '$(srcdir)/'`clients/cli/generate-docs-nm-settings-nmcli.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Tpo clients/cli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/generate-docs-nm-settings-nmcli.c' object='clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.o' libtool=no @AMDEPBACKSLASH@ +src/nm-dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo: src/nm-dispatcher/nm-dispatcher-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_libnm_dispatcher_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo -MD -MP -MF src/nm-dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Tpo -c -o src/nm-dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo `test -f 'src/nm-dispatcher/nm-dispatcher-utils.c' || echo '$(srcdir)/'`src/nm-dispatcher/nm-dispatcher-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Tpo src/nm-dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-dispatcher/nm-dispatcher-utils.c' object='src/nm-dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_generate_docs_nm_settings_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.o `test -f 'clients/cli/generate-docs-nm-settings-nmcli.c' || echo '$(srcdir)/'`clients/cli/generate-docs-nm-settings-nmcli.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_libnm_dispatcher_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-dispatcher/libnm_dispatcher_core_la-nm-dispatcher-utils.lo `test -f 'src/nm-dispatcher/nm-dispatcher-utils.c' || echo '$(srcdir)/'`src/nm-dispatcher/nm-dispatcher-utils.c -clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.obj: clients/cli/generate-docs-nm-settings-nmcli.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_generate_docs_nm_settings_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.obj -MD -MP -MF clients/cli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Tpo -c -o clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.obj `if test -f 'clients/cli/generate-docs-nm-settings-nmcli.c'; then $(CYGPATH_W) 'clients/cli/generate-docs-nm-settings-nmcli.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/generate-docs-nm-settings-nmcli.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Tpo clients/cli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/generate-docs-nm-settings-nmcli.c' object='clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/libnmi_core_la-nmi-cmdline-reader.lo: src/nm-initrd-generator/nmi-cmdline-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/libnmi_core_la-nmi-cmdline-reader.lo -MD -MP -MF src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Tpo -c -o src/nm-initrd-generator/libnmi_core_la-nmi-cmdline-reader.lo `test -f 'src/nm-initrd-generator/nmi-cmdline-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/nmi-cmdline-reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Tpo src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/nmi-cmdline-reader.c' object='src/nm-initrd-generator/libnmi_core_la-nmi-cmdline-reader.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_generate_docs_nm_settings_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.obj `if test -f 'clients/cli/generate-docs-nm-settings-nmcli.c'; then $(CYGPATH_W) 'clients/cli/generate-docs-nm-settings-nmcli.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/generate-docs-nm-settings-nmcli.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/libnmi_core_la-nmi-cmdline-reader.lo `test -f 'src/nm-initrd-generator/nmi-cmdline-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/nmi-cmdline-reader.c -clients/cli/nmcli-common.o: clients/cli/common.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-common.o -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-common.Tpo -c -o clients/cli/nmcli-common.o `test -f 'clients/cli/common.c' || echo '$(srcdir)/'`clients/cli/common.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-common.Tpo clients/cli/$(DEPDIR)/nmcli-common.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/common.c' object='clients/cli/nmcli-common.o' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/libnmi_core_la-nmi-dt-reader.lo: src/nm-initrd-generator/nmi-dt-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/libnmi_core_la-nmi-dt-reader.lo -MD -MP -MF src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Tpo -c -o src/nm-initrd-generator/libnmi_core_la-nmi-dt-reader.lo `test -f 'src/nm-initrd-generator/nmi-dt-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/nmi-dt-reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Tpo src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/nmi-dt-reader.c' object='src/nm-initrd-generator/libnmi_core_la-nmi-dt-reader.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-common.o `test -f 'clients/cli/common.c' || echo '$(srcdir)/'`clients/cli/common.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/libnmi_core_la-nmi-dt-reader.lo `test -f 'src/nm-initrd-generator/nmi-dt-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/nmi-dt-reader.c -clients/cli/nmcli-common.obj: clients/cli/common.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-common.obj -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-common.Tpo -c -o clients/cli/nmcli-common.obj `if test -f 'clients/cli/common.c'; then $(CYGPATH_W) 'clients/cli/common.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/common.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-common.Tpo clients/cli/$(DEPDIR)/nmcli-common.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/common.c' object='clients/cli/nmcli-common.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/libnmi_core_la-nmi-ibft-reader.lo: src/nm-initrd-generator/nmi-ibft-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/libnmi_core_la-nmi-ibft-reader.lo -MD -MP -MF src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Tpo -c -o src/nm-initrd-generator/libnmi_core_la-nmi-ibft-reader.lo `test -f 'src/nm-initrd-generator/nmi-ibft-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/nmi-ibft-reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Tpo src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/nmi-ibft-reader.c' object='src/nm-initrd-generator/libnmi_core_la-nmi-ibft-reader.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-common.obj `if test -f 'clients/cli/common.c'; then $(CYGPATH_W) 'clients/cli/common.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/common.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_libnmi_core_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/libnmi_core_la-nmi-ibft-reader.lo `test -f 'src/nm-initrd-generator/nmi-ibft-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/nmi-ibft-reader.c -clients/cli/nmcli-utils.o: clients/cli/utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-utils.o -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-utils.Tpo -c -o clients/cli/nmcli-utils.o `test -f 'clients/cli/utils.c' || echo '$(srcdir)/'`clients/cli/utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-utils.Tpo clients/cli/$(DEPDIR)/nmcli-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/utils.c' object='clients/cli/nmcli-utils.o' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/add_connection_gdbus-add-connection-gdbus.o: examples/C/glib/add-connection-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/add_connection_gdbus-add-connection-gdbus.o -MD -MP -MF examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Tpo -c -o examples/C/glib/add_connection_gdbus-add-connection-gdbus.o `test -f 'examples/C/glib/add-connection-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/add-connection-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Tpo examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/add-connection-gdbus.c' object='examples/C/glib/add_connection_gdbus-add-connection-gdbus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-utils.o `test -f 'clients/cli/utils.c' || echo '$(srcdir)/'`clients/cli/utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/add_connection_gdbus-add-connection-gdbus.o `test -f 'examples/C/glib/add-connection-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/add-connection-gdbus.c -clients/cli/nmcli-utils.obj: clients/cli/utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-utils.obj -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-utils.Tpo -c -o clients/cli/nmcli-utils.obj `if test -f 'clients/cli/utils.c'; then $(CYGPATH_W) 'clients/cli/utils.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-utils.Tpo clients/cli/$(DEPDIR)/nmcli-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/utils.c' object='clients/cli/nmcli-utils.obj' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/add_connection_gdbus-add-connection-gdbus.obj: examples/C/glib/add-connection-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/add_connection_gdbus-add-connection-gdbus.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Tpo -c -o examples/C/glib/add_connection_gdbus-add-connection-gdbus.obj `if test -f 'examples/C/glib/add-connection-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/add-connection-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/add-connection-gdbus.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Tpo examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/add-connection-gdbus.c' object='examples/C/glib/add_connection_gdbus-add-connection-gdbus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-utils.obj `if test -f 'clients/cli/utils.c'; then $(CYGPATH_W) 'clients/cli/utils.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/utils.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/add_connection_gdbus-add-connection-gdbus.obj `if test -f 'examples/C/glib/add-connection-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/add-connection-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/add-connection-gdbus.c'; fi` -clients/cli/nmcli-agent.o: clients/cli/agent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-agent.o -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-agent.Tpo -c -o clients/cli/nmcli-agent.o `test -f 'clients/cli/agent.c' || echo '$(srcdir)/'`clients/cli/agent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-agent.Tpo clients/cli/$(DEPDIR)/nmcli-agent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/agent.c' object='clients/cli/nmcli-agent.o' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/add_connection_libnm-add-connection-libnm.o: examples/C/glib/add-connection-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/add_connection_libnm-add-connection-libnm.o -MD -MP -MF examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Tpo -c -o examples/C/glib/add_connection_libnm-add-connection-libnm.o `test -f 'examples/C/glib/add-connection-libnm.c' || echo '$(srcdir)/'`examples/C/glib/add-connection-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Tpo examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/add-connection-libnm.c' object='examples/C/glib/add_connection_libnm-add-connection-libnm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-agent.o `test -f 'clients/cli/agent.c' || echo '$(srcdir)/'`clients/cli/agent.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/add_connection_libnm-add-connection-libnm.o `test -f 'examples/C/glib/add-connection-libnm.c' || echo '$(srcdir)/'`examples/C/glib/add-connection-libnm.c -clients/cli/nmcli-agent.obj: clients/cli/agent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-agent.obj -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-agent.Tpo -c -o clients/cli/nmcli-agent.obj `if test -f 'clients/cli/agent.c'; then $(CYGPATH_W) 'clients/cli/agent.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/agent.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-agent.Tpo clients/cli/$(DEPDIR)/nmcli-agent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/agent.c' object='clients/cli/nmcli-agent.obj' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/add_connection_libnm-add-connection-libnm.obj: examples/C/glib/add-connection-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/add_connection_libnm-add-connection-libnm.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Tpo -c -o examples/C/glib/add_connection_libnm-add-connection-libnm.obj `if test -f 'examples/C/glib/add-connection-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/add-connection-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/add-connection-libnm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Tpo examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/add-connection-libnm.c' object='examples/C/glib/add_connection_libnm-add-connection-libnm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-agent.obj `if test -f 'clients/cli/agent.c'; then $(CYGPATH_W) 'clients/cli/agent.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/agent.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/add_connection_libnm-add-connection-libnm.obj `if test -f 'examples/C/glib/add-connection-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/add-connection-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/add-connection-libnm.c'; fi` -clients/cli/nmcli-general.o: clients/cli/general.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-general.o -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-general.Tpo -c -o clients/cli/nmcli-general.o `test -f 'clients/cli/general.c' || echo '$(srcdir)/'`clients/cli/general.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-general.Tpo clients/cli/$(DEPDIR)/nmcli-general.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/general.c' object='clients/cli/nmcli-general.o' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.o: examples/C/glib/get-active-connections-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_active_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.o -MD -MP -MF examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Tpo -c -o examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.o `test -f 'examples/C/glib/get-active-connections-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/get-active-connections-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Tpo examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/get-active-connections-gdbus.c' object='examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-general.o `test -f 'clients/cli/general.c' || echo '$(srcdir)/'`clients/cli/general.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_active_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.o `test -f 'examples/C/glib/get-active-connections-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/get-active-connections-gdbus.c -clients/cli/nmcli-general.obj: clients/cli/general.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-general.obj -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-general.Tpo -c -o clients/cli/nmcli-general.obj `if test -f 'clients/cli/general.c'; then $(CYGPATH_W) 'clients/cli/general.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/general.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-general.Tpo clients/cli/$(DEPDIR)/nmcli-general.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/general.c' object='clients/cli/nmcli-general.obj' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.obj: examples/C/glib/get-active-connections-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_active_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Tpo -c -o examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.obj `if test -f 'examples/C/glib/get-active-connections-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/get-active-connections-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/get-active-connections-gdbus.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Tpo examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/get-active-connections-gdbus.c' object='examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-general.obj `if test -f 'clients/cli/general.c'; then $(CYGPATH_W) 'clients/cli/general.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/general.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_active_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.obj `if test -f 'examples/C/glib/get-active-connections-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/get-active-connections-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/get-active-connections-gdbus.c'; fi` -clients/cli/nmcli-connections.o: clients/cli/connections.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-connections.o -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-connections.Tpo -c -o clients/cli/nmcli-connections.o `test -f 'clients/cli/connections.c' || echo '$(srcdir)/'`clients/cli/connections.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-connections.Tpo clients/cli/$(DEPDIR)/nmcli-connections.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/connections.c' object='clients/cli/nmcli-connections.o' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.o: examples/C/glib/get-ap-info-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_ap_info_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.o -MD -MP -MF examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Tpo -c -o examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.o `test -f 'examples/C/glib/get-ap-info-libnm.c' || echo '$(srcdir)/'`examples/C/glib/get-ap-info-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Tpo examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/get-ap-info-libnm.c' object='examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-connections.o `test -f 'clients/cli/connections.c' || echo '$(srcdir)/'`clients/cli/connections.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_ap_info_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.o `test -f 'examples/C/glib/get-ap-info-libnm.c' || echo '$(srcdir)/'`examples/C/glib/get-ap-info-libnm.c -clients/cli/nmcli-connections.obj: clients/cli/connections.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-connections.obj -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-connections.Tpo -c -o clients/cli/nmcli-connections.obj `if test -f 'clients/cli/connections.c'; then $(CYGPATH_W) 'clients/cli/connections.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/connections.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-connections.Tpo clients/cli/$(DEPDIR)/nmcli-connections.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/connections.c' object='clients/cli/nmcli-connections.obj' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.obj: examples/C/glib/get-ap-info-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_ap_info_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Tpo -c -o examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.obj `if test -f 'examples/C/glib/get-ap-info-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/get-ap-info-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/get-ap-info-libnm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Tpo examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/get-ap-info-libnm.c' object='examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-connections.obj `if test -f 'clients/cli/connections.c'; then $(CYGPATH_W) 'clients/cli/connections.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/connections.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_ap_info_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.obj `if test -f 'examples/C/glib/get-ap-info-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/get-ap-info-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/get-ap-info-libnm.c'; fi` -clients/cli/nmcli-devices.o: clients/cli/devices.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-devices.o -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-devices.Tpo -c -o clients/cli/nmcli-devices.o `test -f 'clients/cli/devices.c' || echo '$(srcdir)/'`clients/cli/devices.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-devices.Tpo clients/cli/$(DEPDIR)/nmcli-devices.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/devices.c' object='clients/cli/nmcli-devices.o' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/list_connections_gdbus-list-connections-gdbus.o: examples/C/glib/list-connections-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/list_connections_gdbus-list-connections-gdbus.o -MD -MP -MF examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Tpo -c -o examples/C/glib/list_connections_gdbus-list-connections-gdbus.o `test -f 'examples/C/glib/list-connections-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/list-connections-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Tpo examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/list-connections-gdbus.c' object='examples/C/glib/list_connections_gdbus-list-connections-gdbus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-devices.o `test -f 'clients/cli/devices.c' || echo '$(srcdir)/'`clients/cli/devices.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/list_connections_gdbus-list-connections-gdbus.o `test -f 'examples/C/glib/list-connections-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/list-connections-gdbus.c -clients/cli/nmcli-devices.obj: clients/cli/devices.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-devices.obj -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-devices.Tpo -c -o clients/cli/nmcli-devices.obj `if test -f 'clients/cli/devices.c'; then $(CYGPATH_W) 'clients/cli/devices.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/devices.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-devices.Tpo clients/cli/$(DEPDIR)/nmcli-devices.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/devices.c' object='clients/cli/nmcli-devices.obj' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/list_connections_gdbus-list-connections-gdbus.obj: examples/C/glib/list-connections-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/list_connections_gdbus-list-connections-gdbus.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Tpo -c -o examples/C/glib/list_connections_gdbus-list-connections-gdbus.obj `if test -f 'examples/C/glib/list-connections-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/list-connections-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/list-connections-gdbus.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Tpo examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/list-connections-gdbus.c' object='examples/C/glib/list_connections_gdbus-list-connections-gdbus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-devices.obj `if test -f 'clients/cli/devices.c'; then $(CYGPATH_W) 'clients/cli/devices.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/devices.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/list_connections_gdbus-list-connections-gdbus.obj `if test -f 'examples/C/glib/list-connections-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/list-connections-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/list-connections-gdbus.c'; fi` -clients/cli/nmcli-settings.o: clients/cli/settings.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-settings.o -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-settings.Tpo -c -o clients/cli/nmcli-settings.o `test -f 'clients/cli/settings.c' || echo '$(srcdir)/'`clients/cli/settings.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-settings.Tpo clients/cli/$(DEPDIR)/nmcli-settings.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/settings.c' object='clients/cli/nmcli-settings.o' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/list_connections_libnm-list-connections-libnm.o: examples/C/glib/list-connections-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/list_connections_libnm-list-connections-libnm.o -MD -MP -MF examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Tpo -c -o examples/C/glib/list_connections_libnm-list-connections-libnm.o `test -f 'examples/C/glib/list-connections-libnm.c' || echo '$(srcdir)/'`examples/C/glib/list-connections-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Tpo examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/list-connections-libnm.c' object='examples/C/glib/list_connections_libnm-list-connections-libnm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-settings.o `test -f 'clients/cli/settings.c' || echo '$(srcdir)/'`clients/cli/settings.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/list_connections_libnm-list-connections-libnm.o `test -f 'examples/C/glib/list-connections-libnm.c' || echo '$(srcdir)/'`examples/C/glib/list-connections-libnm.c -clients/cli/nmcli-settings.obj: clients/cli/settings.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-settings.obj -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-settings.Tpo -c -o clients/cli/nmcli-settings.obj `if test -f 'clients/cli/settings.c'; then $(CYGPATH_W) 'clients/cli/settings.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/settings.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-settings.Tpo clients/cli/$(DEPDIR)/nmcli-settings.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/settings.c' object='clients/cli/nmcli-settings.obj' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/list_connections_libnm-list-connections-libnm.obj: examples/C/glib/list-connections-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/list_connections_libnm-list-connections-libnm.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Tpo -c -o examples/C/glib/list_connections_libnm-list-connections-libnm.obj `if test -f 'examples/C/glib/list-connections-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/list-connections-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/list-connections-libnm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Tpo examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/list-connections-libnm.c' object='examples/C/glib/list_connections_libnm-list-connections-libnm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-settings.obj `if test -f 'clients/cli/settings.c'; then $(CYGPATH_W) 'clients/cli/settings.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/settings.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/list_connections_libnm-list-connections-libnm.obj `if test -f 'examples/C/glib/list-connections-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/list-connections-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/list-connections-libnm.c'; fi` -clients/cli/nmcli-nmcli.o: clients/cli/nmcli.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-nmcli.o -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-nmcli.Tpo -c -o clients/cli/nmcli-nmcli.o `test -f 'clients/cli/nmcli.c' || echo '$(srcdir)/'`clients/cli/nmcli.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-nmcli.Tpo clients/cli/$(DEPDIR)/nmcli-nmcli.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/nmcli.c' object='clients/cli/nmcli-nmcli.o' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.o: examples/C/glib/monitor-nm-running-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_running_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.o -MD -MP -MF examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Tpo -c -o examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.o `test -f 'examples/C/glib/monitor-nm-running-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/monitor-nm-running-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Tpo examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/monitor-nm-running-gdbus.c' object='examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-nmcli.o `test -f 'clients/cli/nmcli.c' || echo '$(srcdir)/'`clients/cli/nmcli.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_running_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.o `test -f 'examples/C/glib/monitor-nm-running-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/monitor-nm-running-gdbus.c -clients/cli/nmcli-nmcli.obj: clients/cli/nmcli.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-nmcli.obj -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-nmcli.Tpo -c -o clients/cli/nmcli-nmcli.obj `if test -f 'clients/cli/nmcli.c'; then $(CYGPATH_W) 'clients/cli/nmcli.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/nmcli.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-nmcli.Tpo clients/cli/$(DEPDIR)/nmcli-nmcli.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/nmcli.c' object='clients/cli/nmcli-nmcli.obj' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.obj: examples/C/glib/monitor-nm-running-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_running_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Tpo -c -o examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.obj `if test -f 'examples/C/glib/monitor-nm-running-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/monitor-nm-running-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/monitor-nm-running-gdbus.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Tpo examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/monitor-nm-running-gdbus.c' object='examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-nmcli.obj `if test -f 'clients/cli/nmcli.c'; then $(CYGPATH_W) 'clients/cli/nmcli.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/nmcli.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_running_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.obj `if test -f 'examples/C/glib/monitor-nm-running-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/monitor-nm-running-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/monitor-nm-running-gdbus.c'; fi` -clients/cli/nmcli-polkit-agent.o: clients/cli/polkit-agent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-polkit-agent.o -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-polkit-agent.Tpo -c -o clients/cli/nmcli-polkit-agent.o `test -f 'clients/cli/polkit-agent.c' || echo '$(srcdir)/'`clients/cli/polkit-agent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-polkit-agent.Tpo clients/cli/$(DEPDIR)/nmcli-polkit-agent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/polkit-agent.c' object='clients/cli/nmcli-polkit-agent.o' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.o: examples/C/glib/monitor-nm-state-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_state_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.o -MD -MP -MF examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Tpo -c -o examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.o `test -f 'examples/C/glib/monitor-nm-state-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/monitor-nm-state-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Tpo examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/monitor-nm-state-gdbus.c' object='examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-polkit-agent.o `test -f 'clients/cli/polkit-agent.c' || echo '$(srcdir)/'`clients/cli/polkit-agent.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_state_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.o `test -f 'examples/C/glib/monitor-nm-state-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/monitor-nm-state-gdbus.c -clients/cli/nmcli-polkit-agent.obj: clients/cli/polkit-agent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cli/nmcli-polkit-agent.obj -MD -MP -MF clients/cli/$(DEPDIR)/nmcli-polkit-agent.Tpo -c -o clients/cli/nmcli-polkit-agent.obj `if test -f 'clients/cli/polkit-agent.c'; then $(CYGPATH_W) 'clients/cli/polkit-agent.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/polkit-agent.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cli/$(DEPDIR)/nmcli-polkit-agent.Tpo clients/cli/$(DEPDIR)/nmcli-polkit-agent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cli/polkit-agent.c' object='clients/cli/nmcli-polkit-agent.obj' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.obj: examples/C/glib/monitor-nm-state-gdbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_state_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Tpo -c -o examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.obj `if test -f 'examples/C/glib/monitor-nm-state-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/monitor-nm-state-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/monitor-nm-state-gdbus.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Tpo examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/monitor-nm-state-gdbus.c' object='examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cli/nmcli-polkit-agent.obj `if test -f 'clients/cli/polkit-agent.c'; then $(CYGPATH_W) 'clients/cli/polkit-agent.c'; else $(CYGPATH_W) '$(srcdir)/clients/cli/polkit-agent.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_state_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.obj `if test -f 'examples/C/glib/monitor-nm-state-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/monitor-nm-state-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/monitor-nm-state-gdbus.c'; fi` -clients/cloud-setup/nm_cloud_setup-main.o: clients/cloud-setup/main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_nm_cloud_setup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/nm_cloud_setup-main.o -MD -MP -MF clients/cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Tpo -c -o clients/cloud-setup/nm_cloud_setup-main.o `test -f 'clients/cloud-setup/main.c' || echo '$(srcdir)/'`clients/cloud-setup/main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Tpo clients/cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/main.c' object='clients/cloud-setup/nm_cloud_setup-main.o' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/vpn_import_libnm-vpn-import-libnm.o: examples/C/glib/vpn-import-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_vpn_import_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/vpn_import_libnm-vpn-import-libnm.o -MD -MP -MF examples/C/glib/$(DEPDIR)/vpn_import_libnm-vpn-import-libnm.Tpo -c -o examples/C/glib/vpn_import_libnm-vpn-import-libnm.o `test -f 'examples/C/glib/vpn-import-libnm.c' || echo '$(srcdir)/'`examples/C/glib/vpn-import-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/vpn_import_libnm-vpn-import-libnm.Tpo examples/C/glib/$(DEPDIR)/vpn_import_libnm-vpn-import-libnm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/vpn-import-libnm.c' object='examples/C/glib/vpn_import_libnm-vpn-import-libnm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_nm_cloud_setup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/nm_cloud_setup-main.o `test -f 'clients/cloud-setup/main.c' || echo '$(srcdir)/'`clients/cloud-setup/main.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_vpn_import_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/vpn_import_libnm-vpn-import-libnm.o `test -f 'examples/C/glib/vpn-import-libnm.c' || echo '$(srcdir)/'`examples/C/glib/vpn-import-libnm.c -clients/cloud-setup/nm_cloud_setup-main.obj: clients/cloud-setup/main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_nm_cloud_setup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/nm_cloud_setup-main.obj -MD -MP -MF clients/cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Tpo -c -o clients/cloud-setup/nm_cloud_setup-main.obj `if test -f 'clients/cloud-setup/main.c'; then $(CYGPATH_W) 'clients/cloud-setup/main.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Tpo clients/cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/main.c' object='clients/cloud-setup/nm_cloud_setup-main.obj' libtool=no @AMDEPBACKSLASH@ +examples/C/glib/vpn_import_libnm-vpn-import-libnm.obj: examples/C/glib/vpn-import-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_vpn_import_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/vpn_import_libnm-vpn-import-libnm.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/vpn_import_libnm-vpn-import-libnm.Tpo -c -o examples/C/glib/vpn_import_libnm-vpn-import-libnm.obj `if test -f 'examples/C/glib/vpn-import-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/vpn-import-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/vpn-import-libnm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/vpn_import_libnm-vpn-import-libnm.Tpo examples/C/glib/$(DEPDIR)/vpn_import_libnm-vpn-import-libnm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/vpn-import-libnm.c' object='examples/C/glib/vpn_import_libnm-vpn-import-libnm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_nm_cloud_setup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/nm_cloud_setup-main.obj `if test -f 'clients/cloud-setup/main.c'; then $(CYGPATH_W) 'clients/cloud-setup/main.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/main.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_vpn_import_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/vpn_import_libnm-vpn-import-libnm.obj `if test -f 'examples/C/glib/vpn-import-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/vpn-import-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/vpn-import-libnm.c'; fi` -clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.o: clients/cloud-setup/tests/test-cloud-setup-general.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.o -MD -MP -MF clients/cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Tpo -c -o clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.o `test -f 'clients/cloud-setup/tests/test-cloud-setup-general.c' || echo '$(srcdir)/'`clients/cloud-setup/tests/test-cloud-setup-general.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Tpo clients/cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/tests/test-cloud-setup-general.c' object='clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.o' libtool=no @AMDEPBACKSLASH@ +src/core/NetworkManager-main.o: src/core/main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/NetworkManager-main.o -MD -MP -MF src/core/$(DEPDIR)/NetworkManager-main.Tpo -c -o src/core/NetworkManager-main.o `test -f 'src/core/main.c' || echo '$(srcdir)/'`src/core/main.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/NetworkManager-main.Tpo src/core/$(DEPDIR)/NetworkManager-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/main.c' object='src/core/NetworkManager-main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.o `test -f 'clients/cloud-setup/tests/test-cloud-setup-general.c' || echo '$(srcdir)/'`clients/cloud-setup/tests/test-cloud-setup-general.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/NetworkManager-main.o `test -f 'src/core/main.c' || echo '$(srcdir)/'`src/core/main.c -clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.obj: clients/cloud-setup/tests/test-cloud-setup-general.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.obj -MD -MP -MF clients/cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Tpo -c -o clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.obj `if test -f 'clients/cloud-setup/tests/test-cloud-setup-general.c'; then $(CYGPATH_W) 'clients/cloud-setup/tests/test-cloud-setup-general.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/tests/test-cloud-setup-general.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Tpo clients/cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/cloud-setup/tests/test-cloud-setup-general.c' object='clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.obj' libtool=no @AMDEPBACKSLASH@ +src/core/NetworkManager-main.obj: src/core/main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/NetworkManager-main.obj -MD -MP -MF src/core/$(DEPDIR)/NetworkManager-main.Tpo -c -o src/core/NetworkManager-main.obj `if test -f 'src/core/main.c'; then $(CYGPATH_W) 'src/core/main.c'; else $(CYGPATH_W) '$(srcdir)/src/core/main.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/NetworkManager-main.Tpo src/core/$(DEPDIR)/NetworkManager-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/main.c' object='src/core/NetworkManager-main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.obj `if test -f 'clients/cloud-setup/tests/test-cloud-setup-general.c'; then $(CYGPATH_W) 'clients/cloud-setup/tests/test-cloud-setup-general.c'; else $(CYGPATH_W) '$(srcdir)/clients/cloud-setup/tests/test-cloud-setup-general.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/NetworkManager-main.obj `if test -f 'src/core/main.c'; then $(CYGPATH_W) 'src/core/main.c'; else $(CYGPATH_W) '$(srcdir)/src/core/main.c'; fi` -clients/common/tests/test_clients_common-test-clients-common.o: clients/common/tests/test-clients-common.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_tests_test_clients_common_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/tests/test_clients_common-test-clients-common.o -MD -MP -MF clients/common/tests/$(DEPDIR)/test_clients_common-test-clients-common.Tpo -c -o clients/common/tests/test_clients_common-test-clients-common.o `test -f 'clients/common/tests/test-clients-common.c' || echo '$(srcdir)/'`clients/common/tests/test-clients-common.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/tests/$(DEPDIR)/test_clients_common-test-clients-common.Tpo clients/common/tests/$(DEPDIR)/test_clients_common-test-clients-common.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/tests/test-clients-common.c' object='clients/common/tests/test_clients_common-test-clients-common.o' libtool=no @AMDEPBACKSLASH@ +src/core/NetworkManager_all_sym-main.o: src/core/main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_all_sym_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/NetworkManager_all_sym-main.o -MD -MP -MF src/core/$(DEPDIR)/NetworkManager_all_sym-main.Tpo -c -o src/core/NetworkManager_all_sym-main.o `test -f 'src/core/main.c' || echo '$(srcdir)/'`src/core/main.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/NetworkManager_all_sym-main.Tpo src/core/$(DEPDIR)/NetworkManager_all_sym-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/main.c' object='src/core/NetworkManager_all_sym-main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_tests_test_clients_common_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/tests/test_clients_common-test-clients-common.o `test -f 'clients/common/tests/test-clients-common.c' || echo '$(srcdir)/'`clients/common/tests/test-clients-common.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_all_sym_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/NetworkManager_all_sym-main.o `test -f 'src/core/main.c' || echo '$(srcdir)/'`src/core/main.c -clients/common/tests/test_clients_common-test-clients-common.obj: clients/common/tests/test-clients-common.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_tests_test_clients_common_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/tests/test_clients_common-test-clients-common.obj -MD -MP -MF clients/common/tests/$(DEPDIR)/test_clients_common-test-clients-common.Tpo -c -o clients/common/tests/test_clients_common-test-clients-common.obj `if test -f 'clients/common/tests/test-clients-common.c'; then $(CYGPATH_W) 'clients/common/tests/test-clients-common.c'; else $(CYGPATH_W) '$(srcdir)/clients/common/tests/test-clients-common.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/tests/$(DEPDIR)/test_clients_common-test-clients-common.Tpo clients/common/tests/$(DEPDIR)/test_clients_common-test-clients-common.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/tests/test-clients-common.c' object='clients/common/tests/test_clients_common-test-clients-common.obj' libtool=no @AMDEPBACKSLASH@ +src/core/NetworkManager_all_sym-main.obj: src/core/main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_all_sym_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/NetworkManager_all_sym-main.obj -MD -MP -MF src/core/$(DEPDIR)/NetworkManager_all_sym-main.Tpo -c -o src/core/NetworkManager_all_sym-main.obj `if test -f 'src/core/main.c'; then $(CYGPATH_W) 'src/core/main.c'; else $(CYGPATH_W) '$(srcdir)/src/core/main.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/NetworkManager_all_sym-main.Tpo src/core/$(DEPDIR)/NetworkManager_all_sym-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/main.c' object='src/core/NetworkManager_all_sym-main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_tests_test_clients_common_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/tests/test_clients_common-test-clients-common.obj `if test -f 'clients/common/tests/test-clients-common.c'; then $(CYGPATH_W) 'clients/common/tests/test-clients-common.c'; else $(CYGPATH_W) '$(srcdir)/clients/common/tests/test-clients-common.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_all_sym_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/NetworkManager_all_sym-main.obj `if test -f 'src/core/main.c'; then $(CYGPATH_W) 'src/core/main.c'; else $(CYGPATH_W) '$(srcdir)/src/core/main.c'; fi` -clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.o: clients/common/tests/test-libnm-core-aux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_tests_test_libnm_core_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.o -MD -MP -MF clients/common/tests/$(DEPDIR)/test_libnm_core_aux-test-libnm-core-aux.Tpo -c -o clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.o `test -f 'clients/common/tests/test-libnm-core-aux.c' || echo '$(srcdir)/'`clients/common/tests/test-libnm-core-aux.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/tests/$(DEPDIR)/test_libnm_core_aux-test-libnm-core-aux.Tpo clients/common/tests/$(DEPDIR)/test_libnm_core_aux-test-libnm-core-aux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/tests/test-libnm-core-aux.c' object='clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.o' libtool=no @AMDEPBACKSLASH@ +src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.o: src/core/devices/bluetooth/tests/nm-bt-test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_tests_nm_bt_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.o -MD -MP -MF src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Tpo -c -o src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.o `test -f 'src/core/devices/bluetooth/tests/nm-bt-test.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/tests/nm-bt-test.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Tpo src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/tests/nm-bt-test.c' object='src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_tests_test_libnm_core_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.o `test -f 'clients/common/tests/test-libnm-core-aux.c' || echo '$(srcdir)/'`clients/common/tests/test-libnm-core-aux.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_tests_nm_bt_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.o `test -f 'src/core/devices/bluetooth/tests/nm-bt-test.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/tests/nm-bt-test.c -clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.obj: clients/common/tests/test-libnm-core-aux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_tests_test_libnm_core_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.obj -MD -MP -MF clients/common/tests/$(DEPDIR)/test_libnm_core_aux-test-libnm-core-aux.Tpo -c -o clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.obj `if test -f 'clients/common/tests/test-libnm-core-aux.c'; then $(CYGPATH_W) 'clients/common/tests/test-libnm-core-aux.c'; else $(CYGPATH_W) '$(srcdir)/clients/common/tests/test-libnm-core-aux.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/common/tests/$(DEPDIR)/test_libnm_core_aux-test-libnm-core-aux.Tpo clients/common/tests/$(DEPDIR)/test_libnm_core_aux-test-libnm-core-aux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/common/tests/test-libnm-core-aux.c' object='clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.obj' libtool=no @AMDEPBACKSLASH@ +src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.obj: src/core/devices/bluetooth/tests/nm-bt-test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_tests_nm_bt_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.obj -MD -MP -MF src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Tpo -c -o src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.obj `if test -f 'src/core/devices/bluetooth/tests/nm-bt-test.c'; then $(CYGPATH_W) 'src/core/devices/bluetooth/tests/nm-bt-test.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/bluetooth/tests/nm-bt-test.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Tpo src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/tests/nm-bt-test.c' object='src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_common_tests_test_libnm_core_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/common/tests/test_libnm_core_aux-test-libnm-core-aux.obj `if test -f 'clients/common/tests/test-libnm-core-aux.c'; then $(CYGPATH_W) 'clients/common/tests/test-libnm-core-aux.c'; else $(CYGPATH_W) '$(srcdir)/clients/common/tests/test-libnm-core-aux.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_tests_nm_bt_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.obj `if test -f 'src/core/devices/bluetooth/tests/nm-bt-test.c'; then $(CYGPATH_W) 'src/core/devices/bluetooth/tests/nm-bt-test.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/bluetooth/tests/nm-bt-test.c'; fi` -clients/nm_online-nm-online.o: clients/nm-online.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_nm_online_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/nm_online-nm-online.o -MD -MP -MF clients/$(DEPDIR)/nm_online-nm-online.Tpo -c -o clients/nm_online-nm-online.o `test -f 'clients/nm-online.c' || echo '$(srcdir)/'`clients/nm-online.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/$(DEPDIR)/nm_online-nm-online.Tpo clients/$(DEPDIR)/nm_online-nm-online.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/nm-online.c' object='clients/nm_online-nm-online.o' libtool=no @AMDEPBACKSLASH@ +src/core/devices/tests/test_acd-test-acd.o: src/core/devices/tests/test-acd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_acd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/tests/test_acd-test-acd.o -MD -MP -MF src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Tpo -c -o src/core/devices/tests/test_acd-test-acd.o `test -f 'src/core/devices/tests/test-acd.c' || echo '$(srcdir)/'`src/core/devices/tests/test-acd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Tpo src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/tests/test-acd.c' object='src/core/devices/tests/test_acd-test-acd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_nm_online_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/nm_online-nm-online.o `test -f 'clients/nm-online.c' || echo '$(srcdir)/'`clients/nm-online.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_acd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/tests/test_acd-test-acd.o `test -f 'src/core/devices/tests/test-acd.c' || echo '$(srcdir)/'`src/core/devices/tests/test-acd.c -clients/nm_online-nm-online.obj: clients/nm-online.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_nm_online_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/nm_online-nm-online.obj -MD -MP -MF clients/$(DEPDIR)/nm_online-nm-online.Tpo -c -o clients/nm_online-nm-online.obj `if test -f 'clients/nm-online.c'; then $(CYGPATH_W) 'clients/nm-online.c'; else $(CYGPATH_W) '$(srcdir)/clients/nm-online.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/$(DEPDIR)/nm_online-nm-online.Tpo clients/$(DEPDIR)/nm_online-nm-online.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/nm-online.c' object='clients/nm_online-nm-online.obj' libtool=no @AMDEPBACKSLASH@ +src/core/devices/tests/test_acd-test-acd.obj: src/core/devices/tests/test-acd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_acd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/tests/test_acd-test-acd.obj -MD -MP -MF src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Tpo -c -o src/core/devices/tests/test_acd-test-acd.obj `if test -f 'src/core/devices/tests/test-acd.c'; then $(CYGPATH_W) 'src/core/devices/tests/test-acd.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/tests/test-acd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Tpo src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/tests/test-acd.c' object='src/core/devices/tests/test_acd-test-acd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_nm_online_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/nm_online-nm-online.obj `if test -f 'clients/nm-online.c'; then $(CYGPATH_W) 'clients/nm-online.c'; else $(CYGPATH_W) '$(srcdir)/clients/nm-online.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_acd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/tests/test_acd-test-acd.obj `if test -f 'src/core/devices/tests/test-acd.c'; then $(CYGPATH_W) 'src/core/devices/tests/test-acd.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/tests/test-acd.c'; fi` -clients/tui/nmtui-nmtui.o: clients/tui/nmtui.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmtui.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmtui.Tpo -c -o clients/tui/nmtui-nmtui.o `test -f 'clients/tui/nmtui.c' || echo '$(srcdir)/'`clients/tui/nmtui.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmtui.Tpo clients/tui/$(DEPDIR)/nmtui-nmtui.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmtui.c' object='clients/tui/nmtui-nmtui.o' libtool=no @AMDEPBACKSLASH@ +src/core/devices/tests/test_lldp-test-lldp.o: src/core/devices/tests/test-lldp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_lldp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/tests/test_lldp-test-lldp.o -MD -MP -MF src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Tpo -c -o src/core/devices/tests/test_lldp-test-lldp.o `test -f 'src/core/devices/tests/test-lldp.c' || echo '$(srcdir)/'`src/core/devices/tests/test-lldp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Tpo src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/tests/test-lldp.c' object='src/core/devices/tests/test_lldp-test-lldp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmtui.o `test -f 'clients/tui/nmtui.c' || echo '$(srcdir)/'`clients/tui/nmtui.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_lldp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/tests/test_lldp-test-lldp.o `test -f 'src/core/devices/tests/test-lldp.c' || echo '$(srcdir)/'`src/core/devices/tests/test-lldp.c -clients/tui/nmtui-nmtui.obj: clients/tui/nmtui.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmtui.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmtui.Tpo -c -o clients/tui/nmtui-nmtui.obj `if test -f 'clients/tui/nmtui.c'; then $(CYGPATH_W) 'clients/tui/nmtui.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmtui.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmtui.Tpo clients/tui/$(DEPDIR)/nmtui-nmtui.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmtui.c' object='clients/tui/nmtui-nmtui.obj' libtool=no @AMDEPBACKSLASH@ +src/core/devices/tests/test_lldp-test-lldp.obj: src/core/devices/tests/test-lldp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_lldp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/tests/test_lldp-test-lldp.obj -MD -MP -MF src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Tpo -c -o src/core/devices/tests/test_lldp-test-lldp.obj `if test -f 'src/core/devices/tests/test-lldp.c'; then $(CYGPATH_W) 'src/core/devices/tests/test-lldp.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/tests/test-lldp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Tpo src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/tests/test-lldp.c' object='src/core/devices/tests/test_lldp-test-lldp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmtui.obj `if test -f 'clients/tui/nmtui.c'; then $(CYGPATH_W) 'clients/tui/nmtui.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmtui.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_lldp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/tests/test_lldp-test-lldp.obj `if test -f 'src/core/devices/tests/test-lldp.c'; then $(CYGPATH_W) 'src/core/devices/tests/test-lldp.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/tests/test-lldp.c'; fi` -clients/tui/nmtui-nmtui-connect.o: clients/tui/nmtui-connect.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmtui-connect.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmtui-connect.Tpo -c -o clients/tui/nmtui-nmtui-connect.o `test -f 'clients/tui/nmtui-connect.c' || echo '$(srcdir)/'`clients/tui/nmtui-connect.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmtui-connect.Tpo clients/tui/$(DEPDIR)/nmtui-nmtui-connect.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmtui-connect.c' object='clients/tui/nmtui-nmtui-connect.o' libtool=no @AMDEPBACKSLASH@ +src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.o: src/core/devices/wifi/tests/test-devices-wifi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_tests_test_devices_wifi_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.o -MD -MP -MF src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Tpo -c -o src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.o `test -f 'src/core/devices/wifi/tests/test-devices-wifi.c' || echo '$(srcdir)/'`src/core/devices/wifi/tests/test-devices-wifi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Tpo src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/tests/test-devices-wifi.c' object='src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmtui-connect.o `test -f 'clients/tui/nmtui-connect.c' || echo '$(srcdir)/'`clients/tui/nmtui-connect.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_tests_test_devices_wifi_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.o `test -f 'src/core/devices/wifi/tests/test-devices-wifi.c' || echo '$(srcdir)/'`src/core/devices/wifi/tests/test-devices-wifi.c -clients/tui/nmtui-nmtui-connect.obj: clients/tui/nmtui-connect.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmtui-connect.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmtui-connect.Tpo -c -o clients/tui/nmtui-nmtui-connect.obj `if test -f 'clients/tui/nmtui-connect.c'; then $(CYGPATH_W) 'clients/tui/nmtui-connect.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmtui-connect.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmtui-connect.Tpo clients/tui/$(DEPDIR)/nmtui-nmtui-connect.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmtui-connect.c' object='clients/tui/nmtui-nmtui-connect.obj' libtool=no @AMDEPBACKSLASH@ +src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.obj: src/core/devices/wifi/tests/test-devices-wifi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_tests_test_devices_wifi_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.obj -MD -MP -MF src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Tpo -c -o src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.obj `if test -f 'src/core/devices/wifi/tests/test-devices-wifi.c'; then $(CYGPATH_W) 'src/core/devices/wifi/tests/test-devices-wifi.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wifi/tests/test-devices-wifi.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Tpo src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/tests/test-devices-wifi.c' object='src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmtui-connect.obj `if test -f 'clients/tui/nmtui-connect.c'; then $(CYGPATH_W) 'clients/tui/nmtui-connect.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmtui-connect.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_tests_test_devices_wifi_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.obj `if test -f 'src/core/devices/wifi/tests/test-devices-wifi.c'; then $(CYGPATH_W) 'src/core/devices/wifi/tests/test-devices-wifi.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wifi/tests/test-devices-wifi.c'; fi` -clients/tui/nmtui-nmtui-edit.o: clients/tui/nmtui-edit.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmtui-edit.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmtui-edit.Tpo -c -o clients/tui/nmtui-nmtui-edit.o `test -f 'clients/tui/nmtui-edit.c' || echo '$(srcdir)/'`clients/tui/nmtui-edit.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmtui-edit.Tpo clients/tui/$(DEPDIR)/nmtui-nmtui-edit.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmtui-edit.c' object='clients/tui/nmtui-nmtui-edit.o' libtool=no @AMDEPBACKSLASH@ +src/core/devices/wwan/tests/test_service_providers-test-service-providers.o: src/core/devices/wwan/tests/test-service-providers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/tests/test_service_providers-test-service-providers.o -MD -MP -MF src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Tpo -c -o src/core/devices/wwan/tests/test_service_providers-test-service-providers.o `test -f 'src/core/devices/wwan/tests/test-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/tests/test-service-providers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Tpo src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/tests/test-service-providers.c' object='src/core/devices/wwan/tests/test_service_providers-test-service-providers.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmtui-edit.o `test -f 'clients/tui/nmtui-edit.c' || echo '$(srcdir)/'`clients/tui/nmtui-edit.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/tests/test_service_providers-test-service-providers.o `test -f 'src/core/devices/wwan/tests/test-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/tests/test-service-providers.c -clients/tui/nmtui-nmtui-edit.obj: clients/tui/nmtui-edit.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmtui-edit.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmtui-edit.Tpo -c -o clients/tui/nmtui-nmtui-edit.obj `if test -f 'clients/tui/nmtui-edit.c'; then $(CYGPATH_W) 'clients/tui/nmtui-edit.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmtui-edit.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmtui-edit.Tpo clients/tui/$(DEPDIR)/nmtui-nmtui-edit.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmtui-edit.c' object='clients/tui/nmtui-nmtui-edit.obj' libtool=no @AMDEPBACKSLASH@ +src/core/devices/wwan/tests/test_service_providers-test-service-providers.obj: src/core/devices/wwan/tests/test-service-providers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/tests/test_service_providers-test-service-providers.obj -MD -MP -MF src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Tpo -c -o src/core/devices/wwan/tests/test_service_providers-test-service-providers.obj `if test -f 'src/core/devices/wwan/tests/test-service-providers.c'; then $(CYGPATH_W) 'src/core/devices/wwan/tests/test-service-providers.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wwan/tests/test-service-providers.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Tpo src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/tests/test-service-providers.c' object='src/core/devices/wwan/tests/test_service_providers-test-service-providers.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmtui-edit.obj `if test -f 'clients/tui/nmtui-edit.c'; then $(CYGPATH_W) 'clients/tui/nmtui-edit.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmtui-edit.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/tests/test_service_providers-test-service-providers.obj `if test -f 'src/core/devices/wwan/tests/test-service-providers.c'; then $(CYGPATH_W) 'src/core/devices/wwan/tests/test-service-providers.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wwan/tests/test-service-providers.c'; fi` -clients/tui/nmtui-nmtui-hostname.o: clients/tui/nmtui-hostname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmtui-hostname.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmtui-hostname.Tpo -c -o clients/tui/nmtui-nmtui-hostname.o `test -f 'clients/tui/nmtui-hostname.c' || echo '$(srcdir)/'`clients/tui/nmtui-hostname.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmtui-hostname.Tpo clients/tui/$(DEPDIR)/nmtui-nmtui-hostname.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmtui-hostname.c' object='clients/tui/nmtui-nmtui-hostname.o' libtool=no @AMDEPBACKSLASH@ +src/core/devices/wwan/tests_test_service_providers-nm-service-providers.o: src/core/devices/wwan/nm-service-providers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/tests_test_service_providers-nm-service-providers.o -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Tpo -c -o src/core/devices/wwan/tests_test_service_providers-nm-service-providers.o `test -f 'src/core/devices/wwan/nm-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-service-providers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Tpo src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-service-providers.c' object='src/core/devices/wwan/tests_test_service_providers-nm-service-providers.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmtui-hostname.o `test -f 'clients/tui/nmtui-hostname.c' || echo '$(srcdir)/'`clients/tui/nmtui-hostname.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/tests_test_service_providers-nm-service-providers.o `test -f 'src/core/devices/wwan/nm-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-service-providers.c -clients/tui/nmtui-nmtui-hostname.obj: clients/tui/nmtui-hostname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmtui-hostname.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmtui-hostname.Tpo -c -o clients/tui/nmtui-nmtui-hostname.obj `if test -f 'clients/tui/nmtui-hostname.c'; then $(CYGPATH_W) 'clients/tui/nmtui-hostname.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmtui-hostname.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmtui-hostname.Tpo clients/tui/$(DEPDIR)/nmtui-nmtui-hostname.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmtui-hostname.c' object='clients/tui/nmtui-nmtui-hostname.obj' libtool=no @AMDEPBACKSLASH@ +src/core/devices/wwan/tests_test_service_providers-nm-service-providers.obj: src/core/devices/wwan/nm-service-providers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/tests_test_service_providers-nm-service-providers.obj -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Tpo -c -o src/core/devices/wwan/tests_test_service_providers-nm-service-providers.obj `if test -f 'src/core/devices/wwan/nm-service-providers.c'; then $(CYGPATH_W) 'src/core/devices/wwan/nm-service-providers.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wwan/nm-service-providers.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Tpo src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-service-providers.c' object='src/core/devices/wwan/tests_test_service_providers-nm-service-providers.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmtui-hostname.obj `if test -f 'clients/tui/nmtui-hostname.c'; then $(CYGPATH_W) 'clients/tui/nmtui-hostname.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmtui-hostname.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/tests_test_service_providers-nm-service-providers.obj `if test -f 'src/core/devices/wwan/nm-service-providers.c'; then $(CYGPATH_W) 'src/core/devices/wwan/nm-service-providers.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wwan/nm-service-providers.c'; fi` -clients/tui/nmtui-nm-editor-bindings.o: clients/tui/nm-editor-bindings.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nm-editor-bindings.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nm-editor-bindings.Tpo -c -o clients/tui/nmtui-nm-editor-bindings.o `test -f 'clients/tui/nm-editor-bindings.c' || echo '$(srcdir)/'`clients/tui/nm-editor-bindings.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nm-editor-bindings.Tpo clients/tui/$(DEPDIR)/nmtui-nm-editor-bindings.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nm-editor-bindings.c' object='clients/tui/nmtui-nm-editor-bindings.o' libtool=no @AMDEPBACKSLASH@ +src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.o: src/core/dhcp/nm-dhcp-helper.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.o -MD -MP -MF src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo -c -o src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.o `test -f 'src/core/dhcp/nm-dhcp-helper.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-helper.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-helper.c' object='src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nm-editor-bindings.o `test -f 'clients/tui/nm-editor-bindings.c' || echo '$(srcdir)/'`clients/tui/nm-editor-bindings.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.o `test -f 'src/core/dhcp/nm-dhcp-helper.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-helper.c -clients/tui/nmtui-nm-editor-bindings.obj: clients/tui/nm-editor-bindings.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nm-editor-bindings.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nm-editor-bindings.Tpo -c -o clients/tui/nmtui-nm-editor-bindings.obj `if test -f 'clients/tui/nm-editor-bindings.c'; then $(CYGPATH_W) 'clients/tui/nm-editor-bindings.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nm-editor-bindings.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nm-editor-bindings.Tpo clients/tui/$(DEPDIR)/nmtui-nm-editor-bindings.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nm-editor-bindings.c' object='clients/tui/nmtui-nm-editor-bindings.obj' libtool=no @AMDEPBACKSLASH@ +src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.obj: src/core/dhcp/nm-dhcp-helper.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.obj -MD -MP -MF src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo -c -o src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.obj `if test -f 'src/core/dhcp/nm-dhcp-helper.c'; then $(CYGPATH_W) 'src/core/dhcp/nm-dhcp-helper.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/nm-dhcp-helper.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-helper.c' object='src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nm-editor-bindings.obj `if test -f 'clients/tui/nm-editor-bindings.c'; then $(CYGPATH_W) 'clients/tui/nm-editor-bindings.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nm-editor-bindings.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.obj `if test -f 'src/core/dhcp/nm-dhcp-helper.c'; then $(CYGPATH_W) 'src/core/dhcp/nm-dhcp-helper.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/nm-dhcp-helper.c'; fi` -clients/tui/nmtui-nm-editor-utils.o: clients/tui/nm-editor-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nm-editor-utils.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nm-editor-utils.Tpo -c -o clients/tui/nmtui-nm-editor-utils.o `test -f 'clients/tui/nm-editor-utils.c' || echo '$(srcdir)/'`clients/tui/nm-editor-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nm-editor-utils.Tpo clients/tui/$(DEPDIR)/nmtui-nm-editor-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nm-editor-utils.c' object='clients/tui/nmtui-nm-editor-utils.o' libtool=no @AMDEPBACKSLASH@ +src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.o: src/core/dhcp/tests/test-dhcp-dhclient.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.o -MD -MP -MF src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo -c -o src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.o `test -f 'src/core/dhcp/tests/test-dhcp-dhclient.c' || echo '$(srcdir)/'`src/core/dhcp/tests/test-dhcp-dhclient.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/tests/test-dhcp-dhclient.c' object='src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nm-editor-utils.o `test -f 'clients/tui/nm-editor-utils.c' || echo '$(srcdir)/'`clients/tui/nm-editor-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.o `test -f 'src/core/dhcp/tests/test-dhcp-dhclient.c' || echo '$(srcdir)/'`src/core/dhcp/tests/test-dhcp-dhclient.c -clients/tui/nmtui-nm-editor-utils.obj: clients/tui/nm-editor-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nm-editor-utils.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nm-editor-utils.Tpo -c -o clients/tui/nmtui-nm-editor-utils.obj `if test -f 'clients/tui/nm-editor-utils.c'; then $(CYGPATH_W) 'clients/tui/nm-editor-utils.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nm-editor-utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nm-editor-utils.Tpo clients/tui/$(DEPDIR)/nmtui-nm-editor-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nm-editor-utils.c' object='clients/tui/nmtui-nm-editor-utils.obj' libtool=no @AMDEPBACKSLASH@ +src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.obj: src/core/dhcp/tests/test-dhcp-dhclient.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.obj -MD -MP -MF src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo -c -o src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.obj `if test -f 'src/core/dhcp/tests/test-dhcp-dhclient.c'; then $(CYGPATH_W) 'src/core/dhcp/tests/test-dhcp-dhclient.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/tests/test-dhcp-dhclient.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/tests/test-dhcp-dhclient.c' object='src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nm-editor-utils.obj `if test -f 'clients/tui/nm-editor-utils.c'; then $(CYGPATH_W) 'clients/tui/nm-editor-utils.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nm-editor-utils.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.obj `if test -f 'src/core/dhcp/tests/test-dhcp-dhclient.c'; then $(CYGPATH_W) 'src/core/dhcp/tests/test-dhcp-dhclient.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/tests/test-dhcp-dhclient.c'; fi` -clients/tui/nmtui-nmt-address-list.o: clients/tui/nmt-address-list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-address-list.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-address-list.Tpo -c -o clients/tui/nmtui-nmt-address-list.o `test -f 'clients/tui/nmt-address-list.c' || echo '$(srcdir)/'`clients/tui/nmt-address-list.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-address-list.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-address-list.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-address-list.c' object='clients/tui/nmtui-nmt-address-list.o' libtool=no @AMDEPBACKSLASH@ +src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.o: src/core/dhcp/tests/test-dhcp-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.o -MD -MP -MF src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Tpo -c -o src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.o `test -f 'src/core/dhcp/tests/test-dhcp-utils.c' || echo '$(srcdir)/'`src/core/dhcp/tests/test-dhcp-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Tpo src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/tests/test-dhcp-utils.c' object='src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-address-list.o `test -f 'clients/tui/nmt-address-list.c' || echo '$(srcdir)/'`clients/tui/nmt-address-list.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.o `test -f 'src/core/dhcp/tests/test-dhcp-utils.c' || echo '$(srcdir)/'`src/core/dhcp/tests/test-dhcp-utils.c -clients/tui/nmtui-nmt-address-list.obj: clients/tui/nmt-address-list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-address-list.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-address-list.Tpo -c -o clients/tui/nmtui-nmt-address-list.obj `if test -f 'clients/tui/nmt-address-list.c'; then $(CYGPATH_W) 'clients/tui/nmt-address-list.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-address-list.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-address-list.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-address-list.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-address-list.c' object='clients/tui/nmtui-nmt-address-list.obj' libtool=no @AMDEPBACKSLASH@ +src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.obj: src/core/dhcp/tests/test-dhcp-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.obj -MD -MP -MF src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Tpo -c -o src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.obj `if test -f 'src/core/dhcp/tests/test-dhcp-utils.c'; then $(CYGPATH_W) 'src/core/dhcp/tests/test-dhcp-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/tests/test-dhcp-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Tpo src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/tests/test-dhcp-utils.c' object='src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-address-list.obj `if test -f 'clients/tui/nmt-address-list.c'; then $(CYGPATH_W) 'clients/tui/nmt-address-list.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-address-list.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.obj `if test -f 'src/core/dhcp/tests/test-dhcp-utils.c'; then $(CYGPATH_W) 'src/core/dhcp/tests/test-dhcp-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/tests/test-dhcp-utils.c'; fi` -clients/tui/nmtui-nmt-connect-connection-list.o: clients/tui/nmt-connect-connection-list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-connect-connection-list.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Tpo -c -o clients/tui/nmtui-nmt-connect-connection-list.o `test -f 'clients/tui/nmt-connect-connection-list.c' || echo '$(srcdir)/'`clients/tui/nmt-connect-connection-list.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-connect-connection-list.c' object='clients/tui/nmtui-nmt-connect-connection-list.o' libtool=no @AMDEPBACKSLASH@ +src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.o: src/core/dnsmasq/tests/test-dnsmasq-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dnsmasq_tests_test_dnsmasq_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.o -MD -MP -MF src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Tpo -c -o src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.o `test -f 'src/core/dnsmasq/tests/test-dnsmasq-utils.c' || echo '$(srcdir)/'`src/core/dnsmasq/tests/test-dnsmasq-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Tpo src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dnsmasq/tests/test-dnsmasq-utils.c' object='src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-connect-connection-list.o `test -f 'clients/tui/nmt-connect-connection-list.c' || echo '$(srcdir)/'`clients/tui/nmt-connect-connection-list.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dnsmasq_tests_test_dnsmasq_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.o `test -f 'src/core/dnsmasq/tests/test-dnsmasq-utils.c' || echo '$(srcdir)/'`src/core/dnsmasq/tests/test-dnsmasq-utils.c -clients/tui/nmtui-nmt-connect-connection-list.obj: clients/tui/nmt-connect-connection-list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-connect-connection-list.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Tpo -c -o clients/tui/nmtui-nmt-connect-connection-list.obj `if test -f 'clients/tui/nmt-connect-connection-list.c'; then $(CYGPATH_W) 'clients/tui/nmt-connect-connection-list.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-connect-connection-list.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-connect-connection-list.c' object='clients/tui/nmtui-nmt-connect-connection-list.obj' libtool=no @AMDEPBACKSLASH@ +src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.obj: src/core/dnsmasq/tests/test-dnsmasq-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dnsmasq_tests_test_dnsmasq_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.obj -MD -MP -MF src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Tpo -c -o src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.obj `if test -f 'src/core/dnsmasq/tests/test-dnsmasq-utils.c'; then $(CYGPATH_W) 'src/core/dnsmasq/tests/test-dnsmasq-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dnsmasq/tests/test-dnsmasq-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Tpo src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dnsmasq/tests/test-dnsmasq-utils.c' object='src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-connect-connection-list.obj `if test -f 'clients/tui/nmt-connect-connection-list.c'; then $(CYGPATH_W) 'clients/tui/nmt-connect-connection-list.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-connect-connection-list.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dnsmasq_tests_test_dnsmasq_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.obj `if test -f 'src/core/dnsmasq/tests/test-dnsmasq-utils.c'; then $(CYGPATH_W) 'src/core/dnsmasq/tests/test-dnsmasq-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dnsmasq/tests/test-dnsmasq-utils.c'; fi` -clients/tui/nmtui-nmt-device-entry.o: clients/tui/nmt-device-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-device-entry.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-device-entry.Tpo -c -o clients/tui/nmtui-nmt-device-entry.o `test -f 'clients/tui/nmt-device-entry.c' || echo '$(srcdir)/'`clients/tui/nmt-device-entry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-device-entry.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-device-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-device-entry.c' object='clients/tui/nmtui-nmt-device-entry.o' libtool=no @AMDEPBACKSLASH@ +src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.o: src/core/ndisc/tests/test-ndisc-fake.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.o -MD -MP -MF src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Tpo -c -o src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.o `test -f 'src/core/ndisc/tests/test-ndisc-fake.c' || echo '$(srcdir)/'`src/core/ndisc/tests/test-ndisc-fake.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Tpo src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/tests/test-ndisc-fake.c' object='src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-device-entry.o `test -f 'clients/tui/nmt-device-entry.c' || echo '$(srcdir)/'`clients/tui/nmt-device-entry.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.o `test -f 'src/core/ndisc/tests/test-ndisc-fake.c' || echo '$(srcdir)/'`src/core/ndisc/tests/test-ndisc-fake.c -clients/tui/nmtui-nmt-device-entry.obj: clients/tui/nmt-device-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-device-entry.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-device-entry.Tpo -c -o clients/tui/nmtui-nmt-device-entry.obj `if test -f 'clients/tui/nmt-device-entry.c'; then $(CYGPATH_W) 'clients/tui/nmt-device-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-device-entry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-device-entry.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-device-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-device-entry.c' object='clients/tui/nmtui-nmt-device-entry.obj' libtool=no @AMDEPBACKSLASH@ +src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.obj: src/core/ndisc/tests/test-ndisc-fake.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.obj -MD -MP -MF src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Tpo -c -o src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.obj `if test -f 'src/core/ndisc/tests/test-ndisc-fake.c'; then $(CYGPATH_W) 'src/core/ndisc/tests/test-ndisc-fake.c'; else $(CYGPATH_W) '$(srcdir)/src/core/ndisc/tests/test-ndisc-fake.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Tpo src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/tests/test-ndisc-fake.c' object='src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-device-entry.obj `if test -f 'clients/tui/nmt-device-entry.c'; then $(CYGPATH_W) 'clients/tui/nmt-device-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-device-entry.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.obj `if test -f 'src/core/ndisc/tests/test-ndisc-fake.c'; then $(CYGPATH_W) 'src/core/ndisc/tests/test-ndisc-fake.c'; else $(CYGPATH_W) '$(srcdir)/src/core/ndisc/tests/test-ndisc-fake.c'; fi` -clients/tui/nmtui-nmt-edit-connection-list.o: clients/tui/nmt-edit-connection-list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-edit-connection-list.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Tpo -c -o clients/tui/nmtui-nmt-edit-connection-list.o `test -f 'clients/tui/nmt-edit-connection-list.c' || echo '$(srcdir)/'`clients/tui/nmt-edit-connection-list.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-edit-connection-list.c' object='clients/tui/nmtui-nmt-edit-connection-list.o' libtool=no @AMDEPBACKSLASH@ +src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.o: src/core/ndisc/tests/test-ndisc-linux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.o -MD -MP -MF src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Tpo -c -o src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.o `test -f 'src/core/ndisc/tests/test-ndisc-linux.c' || echo '$(srcdir)/'`src/core/ndisc/tests/test-ndisc-linux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Tpo src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/tests/test-ndisc-linux.c' object='src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-edit-connection-list.o `test -f 'clients/tui/nmt-edit-connection-list.c' || echo '$(srcdir)/'`clients/tui/nmt-edit-connection-list.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.o `test -f 'src/core/ndisc/tests/test-ndisc-linux.c' || echo '$(srcdir)/'`src/core/ndisc/tests/test-ndisc-linux.c -clients/tui/nmtui-nmt-edit-connection-list.obj: clients/tui/nmt-edit-connection-list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-edit-connection-list.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Tpo -c -o clients/tui/nmtui-nmt-edit-connection-list.obj `if test -f 'clients/tui/nmt-edit-connection-list.c'; then $(CYGPATH_W) 'clients/tui/nmt-edit-connection-list.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-edit-connection-list.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-edit-connection-list.c' object='clients/tui/nmtui-nmt-edit-connection-list.obj' libtool=no @AMDEPBACKSLASH@ +src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.obj: src/core/ndisc/tests/test-ndisc-linux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.obj -MD -MP -MF src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Tpo -c -o src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.obj `if test -f 'src/core/ndisc/tests/test-ndisc-linux.c'; then $(CYGPATH_W) 'src/core/ndisc/tests/test-ndisc-linux.c'; else $(CYGPATH_W) '$(srcdir)/src/core/ndisc/tests/test-ndisc-linux.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Tpo src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/tests/test-ndisc-linux.c' object='src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-edit-connection-list.obj `if test -f 'clients/tui/nmt-edit-connection-list.c'; then $(CYGPATH_W) 'clients/tui/nmt-edit-connection-list.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-edit-connection-list.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.obj `if test -f 'src/core/ndisc/tests/test-ndisc-linux.c'; then $(CYGPATH_W) 'src/core/ndisc/tests/test-ndisc-linux.c'; else $(CYGPATH_W) '$(srcdir)/src/core/ndisc/tests/test-ndisc-linux.c'; fi` -clients/tui/nmtui-nmt-editor-grid.o: clients/tui/nmt-editor-grid.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-editor-grid.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-editor-grid.Tpo -c -o clients/tui/nmtui-nmt-editor-grid.o `test -f 'clients/tui/nmt-editor-grid.c' || echo '$(srcdir)/'`clients/tui/nmt-editor-grid.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-editor-grid.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-editor-grid.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-editor-grid.c' object='clients/tui/nmtui-nmt-editor-grid.o' libtool=no @AMDEPBACKSLASH@ +src/core/nm_iface_helper-nm-iface-helper.o: src/core/nm-iface-helper.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_nm_iface_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/nm_iface_helper-nm-iface-helper.o -MD -MP -MF src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Tpo -c -o src/core/nm_iface_helper-nm-iface-helper.o `test -f 'src/core/nm-iface-helper.c' || echo '$(srcdir)/'`src/core/nm-iface-helper.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Tpo src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-iface-helper.c' object='src/core/nm_iface_helper-nm-iface-helper.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-editor-grid.o `test -f 'clients/tui/nmt-editor-grid.c' || echo '$(srcdir)/'`clients/tui/nmt-editor-grid.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_nm_iface_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/nm_iface_helper-nm-iface-helper.o `test -f 'src/core/nm-iface-helper.c' || echo '$(srcdir)/'`src/core/nm-iface-helper.c -clients/tui/nmtui-nmt-editor-grid.obj: clients/tui/nmt-editor-grid.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-editor-grid.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-editor-grid.Tpo -c -o clients/tui/nmtui-nmt-editor-grid.obj `if test -f 'clients/tui/nmt-editor-grid.c'; then $(CYGPATH_W) 'clients/tui/nmt-editor-grid.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-editor-grid.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-editor-grid.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-editor-grid.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-editor-grid.c' object='clients/tui/nmtui-nmt-editor-grid.obj' libtool=no @AMDEPBACKSLASH@ +src/core/nm_iface_helper-nm-iface-helper.obj: src/core/nm-iface-helper.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_nm_iface_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/nm_iface_helper-nm-iface-helper.obj -MD -MP -MF src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Tpo -c -o src/core/nm_iface_helper-nm-iface-helper.obj `if test -f 'src/core/nm-iface-helper.c'; then $(CYGPATH_W) 'src/core/nm-iface-helper.c'; else $(CYGPATH_W) '$(srcdir)/src/core/nm-iface-helper.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Tpo src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-iface-helper.c' object='src/core/nm_iface_helper-nm-iface-helper.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-editor-grid.obj `if test -f 'clients/tui/nmt-editor-grid.c'; then $(CYGPATH_W) 'clients/tui/nmt-editor-grid.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-editor-grid.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_nm_iface_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/nm_iface_helper-nm-iface-helper.obj `if test -f 'src/core/nm-iface-helper.c'; then $(CYGPATH_W) 'src/core/nm-iface-helper.c'; else $(CYGPATH_W) '$(srcdir)/src/core/nm-iface-helper.c'; fi` -clients/tui/nmtui-nmt-editor-page.o: clients/tui/nmt-editor-page.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-editor-page.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-editor-page.Tpo -c -o clients/tui/nmtui-nmt-editor-page.o `test -f 'clients/tui/nmt-editor-page.c' || echo '$(srcdir)/'`clients/tui/nmt-editor-page.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-editor-page.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-editor-page.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-editor-page.c' object='clients/tui/nmtui-nmt-editor-page.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/monitor-monitor.o: src/core/platform/tests/monitor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/monitor-monitor.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/monitor-monitor.Tpo -c -o src/core/platform/tests/monitor-monitor.o `test -f 'src/core/platform/tests/monitor.c' || echo '$(srcdir)/'`src/core/platform/tests/monitor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/monitor-monitor.Tpo src/core/platform/tests/$(DEPDIR)/monitor-monitor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/monitor.c' object='src/core/platform/tests/monitor-monitor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-editor-page.o `test -f 'clients/tui/nmt-editor-page.c' || echo '$(srcdir)/'`clients/tui/nmt-editor-page.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/monitor-monitor.o `test -f 'src/core/platform/tests/monitor.c' || echo '$(srcdir)/'`src/core/platform/tests/monitor.c -clients/tui/nmtui-nmt-editor-page.obj: clients/tui/nmt-editor-page.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-editor-page.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-editor-page.Tpo -c -o clients/tui/nmtui-nmt-editor-page.obj `if test -f 'clients/tui/nmt-editor-page.c'; then $(CYGPATH_W) 'clients/tui/nmt-editor-page.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-editor-page.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-editor-page.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-editor-page.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-editor-page.c' object='clients/tui/nmtui-nmt-editor-page.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/monitor-monitor.obj: src/core/platform/tests/monitor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/monitor-monitor.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/monitor-monitor.Tpo -c -o src/core/platform/tests/monitor-monitor.obj `if test -f 'src/core/platform/tests/monitor.c'; then $(CYGPATH_W) 'src/core/platform/tests/monitor.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/monitor.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/monitor-monitor.Tpo src/core/platform/tests/$(DEPDIR)/monitor-monitor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/monitor.c' object='src/core/platform/tests/monitor-monitor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-editor-page.obj `if test -f 'clients/tui/nmt-editor-page.c'; then $(CYGPATH_W) 'clients/tui/nmt-editor-page.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-editor-page.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/monitor-monitor.obj `if test -f 'src/core/platform/tests/monitor.c'; then $(CYGPATH_W) 'src/core/platform/tests/monitor.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/monitor.c'; fi` -clients/tui/nmtui-nmt-editor-page-device.o: clients/tui/nmt-editor-page-device.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-editor-page-device.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-editor-page-device.Tpo -c -o clients/tui/nmtui-nmt-editor-page-device.o `test -f 'clients/tui/nmt-editor-page-device.c' || echo '$(srcdir)/'`clients/tui/nmt-editor-page-device.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-editor-page-device.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-editor-page-device.c' object='clients/tui/nmtui-nmt-editor-page-device.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_address_fake-test-address.o: src/core/platform/tests/test-address.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_address_fake-test-address.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Tpo -c -o src/core/platform/tests/test_address_fake-test-address.o `test -f 'src/core/platform/tests/test-address.c' || echo '$(srcdir)/'`src/core/platform/tests/test-address.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Tpo src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-address.c' object='src/core/platform/tests/test_address_fake-test-address.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-editor-page-device.o `test -f 'clients/tui/nmt-editor-page-device.c' || echo '$(srcdir)/'`clients/tui/nmt-editor-page-device.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_address_fake-test-address.o `test -f 'src/core/platform/tests/test-address.c' || echo '$(srcdir)/'`src/core/platform/tests/test-address.c -clients/tui/nmtui-nmt-editor-page-device.obj: clients/tui/nmt-editor-page-device.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-editor-page-device.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-editor-page-device.Tpo -c -o clients/tui/nmtui-nmt-editor-page-device.obj `if test -f 'clients/tui/nmt-editor-page-device.c'; then $(CYGPATH_W) 'clients/tui/nmt-editor-page-device.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-editor-page-device.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-editor-page-device.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-editor-page-device.c' object='clients/tui/nmtui-nmt-editor-page-device.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_address_fake-test-address.obj: src/core/platform/tests/test-address.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_address_fake-test-address.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Tpo -c -o src/core/platform/tests/test_address_fake-test-address.obj `if test -f 'src/core/platform/tests/test-address.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-address.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-address.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Tpo src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-address.c' object='src/core/platform/tests/test_address_fake-test-address.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-editor-page-device.obj `if test -f 'clients/tui/nmt-editor-page-device.c'; then $(CYGPATH_W) 'clients/tui/nmt-editor-page-device.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-editor-page-device.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_address_fake-test-address.obj `if test -f 'src/core/platform/tests/test-address.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-address.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-address.c'; fi` -clients/tui/nmtui-nmt-editor-section.o: clients/tui/nmt-editor-section.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-editor-section.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-editor-section.Tpo -c -o clients/tui/nmtui-nmt-editor-section.o `test -f 'clients/tui/nmt-editor-section.c' || echo '$(srcdir)/'`clients/tui/nmt-editor-section.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-editor-section.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-editor-section.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-editor-section.c' object='clients/tui/nmtui-nmt-editor-section.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_address_linux-test-address.o: src/core/platform/tests/test-address.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_address_linux-test-address.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Tpo -c -o src/core/platform/tests/test_address_linux-test-address.o `test -f 'src/core/platform/tests/test-address.c' || echo '$(srcdir)/'`src/core/platform/tests/test-address.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Tpo src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-address.c' object='src/core/platform/tests/test_address_linux-test-address.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-editor-section.o `test -f 'clients/tui/nmt-editor-section.c' || echo '$(srcdir)/'`clients/tui/nmt-editor-section.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_address_linux-test-address.o `test -f 'src/core/platform/tests/test-address.c' || echo '$(srcdir)/'`src/core/platform/tests/test-address.c -clients/tui/nmtui-nmt-editor-section.obj: clients/tui/nmt-editor-section.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-editor-section.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-editor-section.Tpo -c -o clients/tui/nmtui-nmt-editor-section.obj `if test -f 'clients/tui/nmt-editor-section.c'; then $(CYGPATH_W) 'clients/tui/nmt-editor-section.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-editor-section.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-editor-section.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-editor-section.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-editor-section.c' object='clients/tui/nmtui-nmt-editor-section.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_address_linux-test-address.obj: src/core/platform/tests/test-address.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_address_linux-test-address.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Tpo -c -o src/core/platform/tests/test_address_linux-test-address.obj `if test -f 'src/core/platform/tests/test-address.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-address.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-address.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Tpo src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-address.c' object='src/core/platform/tests/test_address_linux-test-address.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-editor-section.obj `if test -f 'clients/tui/nmt-editor-section.c'; then $(CYGPATH_W) 'clients/tui/nmt-editor-section.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-editor-section.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_address_linux-test-address.obj `if test -f 'src/core/platform/tests/test-address.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-address.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-address.c'; fi` -clients/tui/nmtui-nmt-editor.o: clients/tui/nmt-editor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-editor.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-editor.Tpo -c -o clients/tui/nmtui-nmt-editor.o `test -f 'clients/tui/nmt-editor.c' || echo '$(srcdir)/'`clients/tui/nmt-editor.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-editor.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-editor.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-editor.c' object='clients/tui/nmtui-nmt-editor.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_cleanup_fake-test-cleanup.o: src/core/platform/tests/test-cleanup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_cleanup_fake-test-cleanup.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Tpo -c -o src/core/platform/tests/test_cleanup_fake-test-cleanup.o `test -f 'src/core/platform/tests/test-cleanup.c' || echo '$(srcdir)/'`src/core/platform/tests/test-cleanup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Tpo src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-cleanup.c' object='src/core/platform/tests/test_cleanup_fake-test-cleanup.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-editor.o `test -f 'clients/tui/nmt-editor.c' || echo '$(srcdir)/'`clients/tui/nmt-editor.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_cleanup_fake-test-cleanup.o `test -f 'src/core/platform/tests/test-cleanup.c' || echo '$(srcdir)/'`src/core/platform/tests/test-cleanup.c -clients/tui/nmtui-nmt-editor.obj: clients/tui/nmt-editor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-editor.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-editor.Tpo -c -o clients/tui/nmtui-nmt-editor.obj `if test -f 'clients/tui/nmt-editor.c'; then $(CYGPATH_W) 'clients/tui/nmt-editor.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-editor.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-editor.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-editor.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-editor.c' object='clients/tui/nmtui-nmt-editor.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_cleanup_fake-test-cleanup.obj: src/core/platform/tests/test-cleanup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_cleanup_fake-test-cleanup.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Tpo -c -o src/core/platform/tests/test_cleanup_fake-test-cleanup.obj `if test -f 'src/core/platform/tests/test-cleanup.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-cleanup.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-cleanup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Tpo src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-cleanup.c' object='src/core/platform/tests/test_cleanup_fake-test-cleanup.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-editor.obj `if test -f 'clients/tui/nmt-editor.c'; then $(CYGPATH_W) 'clients/tui/nmt-editor.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-editor.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_cleanup_fake-test-cleanup.obj `if test -f 'src/core/platform/tests/test-cleanup.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-cleanup.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-cleanup.c'; fi` -clients/tui/nmtui-nmt-ip-entry.o: clients/tui/nmt-ip-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-ip-entry.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-ip-entry.Tpo -c -o clients/tui/nmtui-nmt-ip-entry.o `test -f 'clients/tui/nmt-ip-entry.c' || echo '$(srcdir)/'`clients/tui/nmt-ip-entry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-ip-entry.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-ip-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-ip-entry.c' object='clients/tui/nmtui-nmt-ip-entry.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_cleanup_linux-test-cleanup.o: src/core/platform/tests/test-cleanup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_cleanup_linux-test-cleanup.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Tpo -c -o src/core/platform/tests/test_cleanup_linux-test-cleanup.o `test -f 'src/core/platform/tests/test-cleanup.c' || echo '$(srcdir)/'`src/core/platform/tests/test-cleanup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Tpo src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-cleanup.c' object='src/core/platform/tests/test_cleanup_linux-test-cleanup.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-ip-entry.o `test -f 'clients/tui/nmt-ip-entry.c' || echo '$(srcdir)/'`clients/tui/nmt-ip-entry.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_cleanup_linux-test-cleanup.o `test -f 'src/core/platform/tests/test-cleanup.c' || echo '$(srcdir)/'`src/core/platform/tests/test-cleanup.c -clients/tui/nmtui-nmt-ip-entry.obj: clients/tui/nmt-ip-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-ip-entry.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-ip-entry.Tpo -c -o clients/tui/nmtui-nmt-ip-entry.obj `if test -f 'clients/tui/nmt-ip-entry.c'; then $(CYGPATH_W) 'clients/tui/nmt-ip-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-ip-entry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-ip-entry.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-ip-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-ip-entry.c' object='clients/tui/nmtui-nmt-ip-entry.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_cleanup_linux-test-cleanup.obj: src/core/platform/tests/test-cleanup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_cleanup_linux-test-cleanup.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Tpo -c -o src/core/platform/tests/test_cleanup_linux-test-cleanup.obj `if test -f 'src/core/platform/tests/test-cleanup.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-cleanup.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-cleanup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Tpo src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-cleanup.c' object='src/core/platform/tests/test_cleanup_linux-test-cleanup.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-ip-entry.obj `if test -f 'clients/tui/nmt-ip-entry.c'; then $(CYGPATH_W) 'clients/tui/nmt-ip-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-ip-entry.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_cleanup_linux-test-cleanup.obj `if test -f 'src/core/platform/tests/test-cleanup.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-cleanup.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-cleanup.c'; fi` -clients/tui/nmtui-nmt-mac-entry.o: clients/tui/nmt-mac-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-mac-entry.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-mac-entry.Tpo -c -o clients/tui/nmtui-nmt-mac-entry.o `test -f 'clients/tui/nmt-mac-entry.c' || echo '$(srcdir)/'`clients/tui/nmt-mac-entry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-mac-entry.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-mac-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-mac-entry.c' object='clients/tui/nmtui-nmt-mac-entry.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_link_fake-test-link.o: src/core/platform/tests/test-link.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_link_fake-test-link.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Tpo -c -o src/core/platform/tests/test_link_fake-test-link.o `test -f 'src/core/platform/tests/test-link.c' || echo '$(srcdir)/'`src/core/platform/tests/test-link.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Tpo src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-link.c' object='src/core/platform/tests/test_link_fake-test-link.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-mac-entry.o `test -f 'clients/tui/nmt-mac-entry.c' || echo '$(srcdir)/'`clients/tui/nmt-mac-entry.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_link_fake-test-link.o `test -f 'src/core/platform/tests/test-link.c' || echo '$(srcdir)/'`src/core/platform/tests/test-link.c -clients/tui/nmtui-nmt-mac-entry.obj: clients/tui/nmt-mac-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-mac-entry.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-mac-entry.Tpo -c -o clients/tui/nmtui-nmt-mac-entry.obj `if test -f 'clients/tui/nmt-mac-entry.c'; then $(CYGPATH_W) 'clients/tui/nmt-mac-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-mac-entry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-mac-entry.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-mac-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-mac-entry.c' object='clients/tui/nmtui-nmt-mac-entry.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_link_fake-test-link.obj: src/core/platform/tests/test-link.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_link_fake-test-link.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Tpo -c -o src/core/platform/tests/test_link_fake-test-link.obj `if test -f 'src/core/platform/tests/test-link.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-link.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-link.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Tpo src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-link.c' object='src/core/platform/tests/test_link_fake-test-link.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-mac-entry.obj `if test -f 'clients/tui/nmt-mac-entry.c'; then $(CYGPATH_W) 'clients/tui/nmt-mac-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-mac-entry.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_link_fake-test-link.obj `if test -f 'src/core/platform/tests/test-link.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-link.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-link.c'; fi` -clients/tui/nmtui-nmt-mtu-entry.o: clients/tui/nmt-mtu-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-mtu-entry.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-mtu-entry.Tpo -c -o clients/tui/nmtui-nmt-mtu-entry.o `test -f 'clients/tui/nmt-mtu-entry.c' || echo '$(srcdir)/'`clients/tui/nmt-mtu-entry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-mtu-entry.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-mtu-entry.c' object='clients/tui/nmtui-nmt-mtu-entry.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_link_linux-test-link.o: src/core/platform/tests/test-link.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_link_linux-test-link.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Tpo -c -o src/core/platform/tests/test_link_linux-test-link.o `test -f 'src/core/platform/tests/test-link.c' || echo '$(srcdir)/'`src/core/platform/tests/test-link.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Tpo src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-link.c' object='src/core/platform/tests/test_link_linux-test-link.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-mtu-entry.o `test -f 'clients/tui/nmt-mtu-entry.c' || echo '$(srcdir)/'`clients/tui/nmt-mtu-entry.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_link_linux-test-link.o `test -f 'src/core/platform/tests/test-link.c' || echo '$(srcdir)/'`src/core/platform/tests/test-link.c -clients/tui/nmtui-nmt-mtu-entry.obj: clients/tui/nmt-mtu-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-mtu-entry.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-mtu-entry.Tpo -c -o clients/tui/nmtui-nmt-mtu-entry.obj `if test -f 'clients/tui/nmt-mtu-entry.c'; then $(CYGPATH_W) 'clients/tui/nmt-mtu-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-mtu-entry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-mtu-entry.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-mtu-entry.c' object='clients/tui/nmtui-nmt-mtu-entry.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_link_linux-test-link.obj: src/core/platform/tests/test-link.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_link_linux-test-link.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Tpo -c -o src/core/platform/tests/test_link_linux-test-link.obj `if test -f 'src/core/platform/tests/test-link.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-link.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-link.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Tpo src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-link.c' object='src/core/platform/tests/test_link_linux-test-link.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-mtu-entry.obj `if test -f 'clients/tui/nmt-mtu-entry.c'; then $(CYGPATH_W) 'clients/tui/nmt-mtu-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-mtu-entry.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_link_linux-test-link.obj `if test -f 'src/core/platform/tests/test-link.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-link.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-link.c'; fi` -clients/tui/nmtui-nmt-page-bond.o: clients/tui/nmt-page-bond.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-bond.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-bond.Tpo -c -o clients/tui/nmtui-nmt-page-bond.o `test -f 'clients/tui/nmt-page-bond.c' || echo '$(srcdir)/'`clients/tui/nmt-page-bond.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-bond.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-bond.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-bond.c' object='clients/tui/nmtui-nmt-page-bond.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_nmp_object-test-nmp-object.o: src/core/platform/tests/test-nmp-object.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_nmp_object_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_nmp_object-test-nmp-object.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Tpo -c -o src/core/platform/tests/test_nmp_object-test-nmp-object.o `test -f 'src/core/platform/tests/test-nmp-object.c' || echo '$(srcdir)/'`src/core/platform/tests/test-nmp-object.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Tpo src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-nmp-object.c' object='src/core/platform/tests/test_nmp_object-test-nmp-object.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-bond.o `test -f 'clients/tui/nmt-page-bond.c' || echo '$(srcdir)/'`clients/tui/nmt-page-bond.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_nmp_object_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_nmp_object-test-nmp-object.o `test -f 'src/core/platform/tests/test-nmp-object.c' || echo '$(srcdir)/'`src/core/platform/tests/test-nmp-object.c -clients/tui/nmtui-nmt-page-bond.obj: clients/tui/nmt-page-bond.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-bond.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-bond.Tpo -c -o clients/tui/nmtui-nmt-page-bond.obj `if test -f 'clients/tui/nmt-page-bond.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-bond.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-bond.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-bond.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-bond.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-bond.c' object='clients/tui/nmtui-nmt-page-bond.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_nmp_object-test-nmp-object.obj: src/core/platform/tests/test-nmp-object.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_nmp_object_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_nmp_object-test-nmp-object.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Tpo -c -o src/core/platform/tests/test_nmp_object-test-nmp-object.obj `if test -f 'src/core/platform/tests/test-nmp-object.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-nmp-object.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-nmp-object.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Tpo src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-nmp-object.c' object='src/core/platform/tests/test_nmp_object-test-nmp-object.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-bond.obj `if test -f 'clients/tui/nmt-page-bond.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-bond.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-bond.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_nmp_object_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_nmp_object-test-nmp-object.obj `if test -f 'src/core/platform/tests/test-nmp-object.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-nmp-object.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-nmp-object.c'; fi` -clients/tui/nmtui-nmt-page-bridge.o: clients/tui/nmt-page-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-bridge.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge.Tpo -c -o clients/tui/nmtui-nmt-page-bridge.o `test -f 'clients/tui/nmt-page-bridge.c' || echo '$(srcdir)/'`clients/tui/nmt-page-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-bridge.c' object='clients/tui/nmtui-nmt-page-bridge.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_platform_general-test-platform-general.o: src/core/platform/tests/test-platform-general.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_platform_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_platform_general-test-platform-general.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Tpo -c -o src/core/platform/tests/test_platform_general-test-platform-general.o `test -f 'src/core/platform/tests/test-platform-general.c' || echo '$(srcdir)/'`src/core/platform/tests/test-platform-general.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Tpo src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-platform-general.c' object='src/core/platform/tests/test_platform_general-test-platform-general.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-bridge.o `test -f 'clients/tui/nmt-page-bridge.c' || echo '$(srcdir)/'`clients/tui/nmt-page-bridge.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_platform_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_platform_general-test-platform-general.o `test -f 'src/core/platform/tests/test-platform-general.c' || echo '$(srcdir)/'`src/core/platform/tests/test-platform-general.c -clients/tui/nmtui-nmt-page-bridge.obj: clients/tui/nmt-page-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-bridge.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge.Tpo -c -o clients/tui/nmtui-nmt-page-bridge.obj `if test -f 'clients/tui/nmt-page-bridge.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-bridge.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-bridge.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-bridge.c' object='clients/tui/nmtui-nmt-page-bridge.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_platform_general-test-platform-general.obj: src/core/platform/tests/test-platform-general.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_platform_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_platform_general-test-platform-general.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Tpo -c -o src/core/platform/tests/test_platform_general-test-platform-general.obj `if test -f 'src/core/platform/tests/test-platform-general.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-platform-general.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-platform-general.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Tpo src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-platform-general.c' object='src/core/platform/tests/test_platform_general-test-platform-general.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-bridge.obj `if test -f 'clients/tui/nmt-page-bridge.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-bridge.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-bridge.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_platform_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_platform_general-test-platform-general.obj `if test -f 'src/core/platform/tests/test-platform-general.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-platform-general.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-platform-general.c'; fi` -clients/tui/nmtui-nmt-page-bridge-port.o: clients/tui/nmt-page-bridge-port.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-bridge-port.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Tpo -c -o clients/tui/nmtui-nmt-page-bridge-port.o `test -f 'clients/tui/nmt-page-bridge-port.c' || echo '$(srcdir)/'`clients/tui/nmt-page-bridge-port.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-bridge-port.c' object='clients/tui/nmtui-nmt-page-bridge-port.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_route_fake-test-route.o: src/core/platform/tests/test-route.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_route_fake-test-route.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Tpo -c -o src/core/platform/tests/test_route_fake-test-route.o `test -f 'src/core/platform/tests/test-route.c' || echo '$(srcdir)/'`src/core/platform/tests/test-route.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Tpo src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-route.c' object='src/core/platform/tests/test_route_fake-test-route.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-bridge-port.o `test -f 'clients/tui/nmt-page-bridge-port.c' || echo '$(srcdir)/'`clients/tui/nmt-page-bridge-port.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_route_fake-test-route.o `test -f 'src/core/platform/tests/test-route.c' || echo '$(srcdir)/'`src/core/platform/tests/test-route.c -clients/tui/nmtui-nmt-page-bridge-port.obj: clients/tui/nmt-page-bridge-port.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-bridge-port.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Tpo -c -o clients/tui/nmtui-nmt-page-bridge-port.obj `if test -f 'clients/tui/nmt-page-bridge-port.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-bridge-port.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-bridge-port.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-bridge-port.c' object='clients/tui/nmtui-nmt-page-bridge-port.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_route_fake-test-route.obj: src/core/platform/tests/test-route.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_route_fake-test-route.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Tpo -c -o src/core/platform/tests/test_route_fake-test-route.obj `if test -f 'src/core/platform/tests/test-route.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-route.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-route.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Tpo src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-route.c' object='src/core/platform/tests/test_route_fake-test-route.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-bridge-port.obj `if test -f 'clients/tui/nmt-page-bridge-port.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-bridge-port.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-bridge-port.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_route_fake-test-route.obj `if test -f 'src/core/platform/tests/test-route.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-route.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-route.c'; fi` -clients/tui/nmtui-nmt-page-dsl.o: clients/tui/nmt-page-dsl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-dsl.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-dsl.Tpo -c -o clients/tui/nmtui-nmt-page-dsl.o `test -f 'clients/tui/nmt-page-dsl.c' || echo '$(srcdir)/'`clients/tui/nmt-page-dsl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-dsl.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-dsl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-dsl.c' object='clients/tui/nmtui-nmt-page-dsl.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_route_linux-test-route.o: src/core/platform/tests/test-route.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_route_linux-test-route.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Tpo -c -o src/core/platform/tests/test_route_linux-test-route.o `test -f 'src/core/platform/tests/test-route.c' || echo '$(srcdir)/'`src/core/platform/tests/test-route.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Tpo src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-route.c' object='src/core/platform/tests/test_route_linux-test-route.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-dsl.o `test -f 'clients/tui/nmt-page-dsl.c' || echo '$(srcdir)/'`clients/tui/nmt-page-dsl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_route_linux-test-route.o `test -f 'src/core/platform/tests/test-route.c' || echo '$(srcdir)/'`src/core/platform/tests/test-route.c -clients/tui/nmtui-nmt-page-dsl.obj: clients/tui/nmt-page-dsl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-dsl.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-dsl.Tpo -c -o clients/tui/nmtui-nmt-page-dsl.obj `if test -f 'clients/tui/nmt-page-dsl.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-dsl.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-dsl.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-dsl.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-dsl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-dsl.c' object='clients/tui/nmtui-nmt-page-dsl.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_route_linux-test-route.obj: src/core/platform/tests/test-route.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_route_linux-test-route.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Tpo -c -o src/core/platform/tests/test_route_linux-test-route.obj `if test -f 'src/core/platform/tests/test-route.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-route.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-route.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Tpo src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-route.c' object='src/core/platform/tests/test_route_linux-test-route.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-dsl.obj `if test -f 'clients/tui/nmt-page-dsl.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-dsl.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-dsl.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_route_linux-test-route.obj `if test -f 'src/core/platform/tests/test-route.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-route.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-route.c'; fi` -clients/tui/nmtui-nmt-page-ethernet.o: clients/tui/nmt-page-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-ethernet.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-ethernet.Tpo -c -o clients/tui/nmtui-nmt-page-ethernet.o `test -f 'clients/tui/nmt-page-ethernet.c' || echo '$(srcdir)/'`clients/tui/nmt-page-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-ethernet.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-ethernet.c' object='clients/tui/nmtui-nmt-page-ethernet.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_tc_fake-test-tc.o: src/core/platform/tests/test-tc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_tc_fake-test-tc.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Tpo -c -o src/core/platform/tests/test_tc_fake-test-tc.o `test -f 'src/core/platform/tests/test-tc.c' || echo '$(srcdir)/'`src/core/platform/tests/test-tc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Tpo src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-tc.c' object='src/core/platform/tests/test_tc_fake-test-tc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-ethernet.o `test -f 'clients/tui/nmt-page-ethernet.c' || echo '$(srcdir)/'`clients/tui/nmt-page-ethernet.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_tc_fake-test-tc.o `test -f 'src/core/platform/tests/test-tc.c' || echo '$(srcdir)/'`src/core/platform/tests/test-tc.c -clients/tui/nmtui-nmt-page-ethernet.obj: clients/tui/nmt-page-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-ethernet.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-ethernet.Tpo -c -o clients/tui/nmtui-nmt-page-ethernet.obj `if test -f 'clients/tui/nmt-page-ethernet.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-ethernet.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-ethernet.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-ethernet.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-ethernet.c' object='clients/tui/nmtui-nmt-page-ethernet.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_tc_fake-test-tc.obj: src/core/platform/tests/test-tc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_tc_fake-test-tc.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Tpo -c -o src/core/platform/tests/test_tc_fake-test-tc.obj `if test -f 'src/core/platform/tests/test-tc.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-tc.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-tc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Tpo src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-tc.c' object='src/core/platform/tests/test_tc_fake-test-tc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-ethernet.obj `if test -f 'clients/tui/nmt-page-ethernet.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-ethernet.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-ethernet.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_tc_fake-test-tc.obj `if test -f 'src/core/platform/tests/test-tc.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-tc.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-tc.c'; fi` -clients/tui/nmtui-nmt-page-infiniband.o: clients/tui/nmt-page-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-infiniband.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-infiniband.Tpo -c -o clients/tui/nmtui-nmt-page-infiniband.o `test -f 'clients/tui/nmt-page-infiniband.c' || echo '$(srcdir)/'`clients/tui/nmt-page-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-infiniband.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-infiniband.c' object='clients/tui/nmtui-nmt-page-infiniband.o' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_tc_linux-test-tc.o: src/core/platform/tests/test-tc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_tc_linux-test-tc.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Tpo -c -o src/core/platform/tests/test_tc_linux-test-tc.o `test -f 'src/core/platform/tests/test-tc.c' || echo '$(srcdir)/'`src/core/platform/tests/test-tc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Tpo src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-tc.c' object='src/core/platform/tests/test_tc_linux-test-tc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-infiniband.o `test -f 'clients/tui/nmt-page-infiniband.c' || echo '$(srcdir)/'`clients/tui/nmt-page-infiniband.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_tc_linux-test-tc.o `test -f 'src/core/platform/tests/test-tc.c' || echo '$(srcdir)/'`src/core/platform/tests/test-tc.c -clients/tui/nmtui-nmt-page-infiniband.obj: clients/tui/nmt-page-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-infiniband.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-infiniband.Tpo -c -o clients/tui/nmtui-nmt-page-infiniband.obj `if test -f 'clients/tui/nmt-page-infiniband.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-infiniband.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-infiniband.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-infiniband.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-infiniband.c' object='clients/tui/nmtui-nmt-page-infiniband.obj' libtool=no @AMDEPBACKSLASH@ +src/core/platform/tests/test_tc_linux-test-tc.obj: src/core/platform/tests/test-tc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_tc_linux-test-tc.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Tpo -c -o src/core/platform/tests/test_tc_linux-test-tc.obj `if test -f 'src/core/platform/tests/test-tc.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-tc.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-tc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Tpo src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-tc.c' object='src/core/platform/tests/test_tc_linux-test-tc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-infiniband.obj `if test -f 'clients/tui/nmt-page-infiniband.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-infiniband.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-infiniband.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_tc_linux-test-tc.obj `if test -f 'src/core/platform/tests/test-tc.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-tc.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-tc.c'; fi` -clients/tui/nmtui-nmt-page-ip-tunnel.o: clients/tui/nmt-page-ip-tunnel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-ip-tunnel.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Tpo -c -o clients/tui/nmtui-nmt-page-ip-tunnel.o `test -f 'clients/tui/nmt-page-ip-tunnel.c' || echo '$(srcdir)/'`clients/tui/nmt-page-ip-tunnel.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-ip-tunnel.c' object='clients/tui/nmtui-nmt-page-ip-tunnel.o' libtool=no @AMDEPBACKSLASH@ +src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.o: src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.o -MD -MP -MF src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo -c -o src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.o `test -f 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c' object='src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-ip-tunnel.o `test -f 'clients/tui/nmt-page-ip-tunnel.c' || echo '$(srcdir)/'`clients/tui/nmt-page-ip-tunnel.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.o `test -f 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c -clients/tui/nmtui-nmt-page-ip-tunnel.obj: clients/tui/nmt-page-ip-tunnel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-ip-tunnel.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Tpo -c -o clients/tui/nmtui-nmt-page-ip-tunnel.obj `if test -f 'clients/tui/nmt-page-ip-tunnel.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-ip-tunnel.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-ip-tunnel.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-ip-tunnel.c' object='clients/tui/nmtui-nmt-page-ip-tunnel.obj' libtool=no @AMDEPBACKSLASH@ +src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.obj: src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.obj -MD -MP -MF src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo -c -o src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.obj `if test -f 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; then $(CYGPATH_W) 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c' object='src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-ip-tunnel.obj `if test -f 'clients/tui/nmt-page-ip-tunnel.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-ip-tunnel.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-ip-tunnel.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.obj `if test -f 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; then $(CYGPATH_W) 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; fi` -clients/tui/nmtui-nmt-page-ip4.o: clients/tui/nmt-page-ip4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-ip4.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-ip4.Tpo -c -o clients/tui/nmtui-nmt-page-ip4.o `test -f 'clients/tui/nmt-page-ip4.c' || echo '$(srcdir)/'`clients/tui/nmt-page-ip4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-ip4.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-ip4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-ip4.c' object='clients/tui/nmtui-nmt-page-ip4.o' libtool=no @AMDEPBACKSLASH@ +src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.o: src/core/settings/plugins/ifupdown/tests/test-ifupdown.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_tests_test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.o -MD -MP -MF src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Tpo -c -o src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.o `test -f 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/tests/test-ifupdown.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Tpo src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifupdown/tests/test-ifupdown.c' object='src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-ip4.o `test -f 'clients/tui/nmt-page-ip4.c' || echo '$(srcdir)/'`clients/tui/nmt-page-ip4.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_tests_test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.o `test -f 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/tests/test-ifupdown.c -clients/tui/nmtui-nmt-page-ip4.obj: clients/tui/nmt-page-ip4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-ip4.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-ip4.Tpo -c -o clients/tui/nmtui-nmt-page-ip4.obj `if test -f 'clients/tui/nmt-page-ip4.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-ip4.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-ip4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-ip4.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-ip4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-ip4.c' object='clients/tui/nmtui-nmt-page-ip4.obj' libtool=no @AMDEPBACKSLASH@ +src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.obj: src/core/settings/plugins/ifupdown/tests/test-ifupdown.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_tests_test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.obj -MD -MP -MF src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Tpo -c -o src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.obj `if test -f 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; then $(CYGPATH_W) 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Tpo src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifupdown/tests/test-ifupdown.c' object='src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-ip4.obj `if test -f 'clients/tui/nmt-page-ip4.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-ip4.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-ip4.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_tests_test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.obj `if test -f 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; then $(CYGPATH_W) 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; fi` -clients/tui/nmtui-nmt-page-ip6.o: clients/tui/nmt-page-ip6.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-ip6.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-ip6.Tpo -c -o clients/tui/nmtui-nmt-page-ip6.o `test -f 'clients/tui/nmt-page-ip6.c' || echo '$(srcdir)/'`clients/tui/nmt-page-ip6.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-ip6.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-ip6.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-ip6.c' object='clients/tui/nmtui-nmt-page-ip6.o' libtool=no @AMDEPBACKSLASH@ +src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.o: src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.o -MD -MP -MF src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Tpo -c -o src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.o `test -f 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Tpo src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c' object='src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-ip6.o `test -f 'clients/tui/nmt-page-ip6.c' || echo '$(srcdir)/'`clients/tui/nmt-page-ip6.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.o `test -f 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c -clients/tui/nmtui-nmt-page-ip6.obj: clients/tui/nmt-page-ip6.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-ip6.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-ip6.Tpo -c -o clients/tui/nmtui-nmt-page-ip6.obj `if test -f 'clients/tui/nmt-page-ip6.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-ip6.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-ip6.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-ip6.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-ip6.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-ip6.c' object='clients/tui/nmtui-nmt-page-ip6.obj' libtool=no @AMDEPBACKSLASH@ +src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.obj: src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.obj -MD -MP -MF src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Tpo -c -o src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.obj `if test -f 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; then $(CYGPATH_W) 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Tpo src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c' object='src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-ip6.obj `if test -f 'clients/tui/nmt-page-ip6.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-ip6.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-ip6.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.obj `if test -f 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; then $(CYGPATH_W) 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; fi` -clients/tui/nmtui-nmt-page-ppp.o: clients/tui/nmt-page-ppp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-ppp.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-ppp.Tpo -c -o clients/tui/nmtui-nmt-page-ppp.o `test -f 'clients/tui/nmt-page-ppp.c' || echo '$(srcdir)/'`clients/tui/nmt-page-ppp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-ppp.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-ppp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-ppp.c' object='clients/tui/nmtui-nmt-page-ppp.o' libtool=no @AMDEPBACKSLASH@ +src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.o: src/core/supplicant/tests/test-supplicant-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_supplicant_tests_test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.o -MD -MP -MF src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo -c -o src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.o `test -f 'src/core/supplicant/tests/test-supplicant-config.c' || echo '$(srcdir)/'`src/core/supplicant/tests/test-supplicant-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/tests/test-supplicant-config.c' object='src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-ppp.o `test -f 'clients/tui/nmt-page-ppp.c' || echo '$(srcdir)/'`clients/tui/nmt-page-ppp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_supplicant_tests_test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.o `test -f 'src/core/supplicant/tests/test-supplicant-config.c' || echo '$(srcdir)/'`src/core/supplicant/tests/test-supplicant-config.c -clients/tui/nmtui-nmt-page-ppp.obj: clients/tui/nmt-page-ppp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-ppp.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-ppp.Tpo -c -o clients/tui/nmtui-nmt-page-ppp.obj `if test -f 'clients/tui/nmt-page-ppp.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-ppp.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-ppp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-ppp.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-ppp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-ppp.c' object='clients/tui/nmtui-nmt-page-ppp.obj' libtool=no @AMDEPBACKSLASH@ +src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.obj: src/core/supplicant/tests/test-supplicant-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_supplicant_tests_test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.obj -MD -MP -MF src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo -c -o src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.obj `if test -f 'src/core/supplicant/tests/test-supplicant-config.c'; then $(CYGPATH_W) 'src/core/supplicant/tests/test-supplicant-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/supplicant/tests/test-supplicant-config.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/tests/test-supplicant-config.c' object='src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-ppp.obj `if test -f 'clients/tui/nmt-page-ppp.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-ppp.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-ppp.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_supplicant_tests_test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.obj `if test -f 'src/core/supplicant/tests/test-supplicant-config.c'; then $(CYGPATH_W) 'src/core/supplicant/tests/test-supplicant-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/supplicant/tests/test-supplicant-config.c'; fi` -clients/tui/nmtui-nmt-page-team.o: clients/tui/nmt-page-team.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-team.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-team.Tpo -c -o clients/tui/nmtui-nmt-page-team.o `test -f 'clients/tui/nmt-page-team.c' || echo '$(srcdir)/'`clients/tui/nmt-page-team.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-team.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-team.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-team.c' object='clients/tui/nmtui-nmt-page-team.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/config/test_config-nm-test-device.o: src/core/tests/config/nm-test-device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/config/test_config-nm-test-device.o -MD -MP -MF src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Tpo -c -o src/core/tests/config/test_config-nm-test-device.o `test -f 'src/core/tests/config/nm-test-device.c' || echo '$(srcdir)/'`src/core/tests/config/nm-test-device.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Tpo src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/config/nm-test-device.c' object='src/core/tests/config/test_config-nm-test-device.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-team.o `test -f 'clients/tui/nmt-page-team.c' || echo '$(srcdir)/'`clients/tui/nmt-page-team.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/config/test_config-nm-test-device.o `test -f 'src/core/tests/config/nm-test-device.c' || echo '$(srcdir)/'`src/core/tests/config/nm-test-device.c -clients/tui/nmtui-nmt-page-team.obj: clients/tui/nmt-page-team.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-team.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-team.Tpo -c -o clients/tui/nmtui-nmt-page-team.obj `if test -f 'clients/tui/nmt-page-team.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-team.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-team.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-team.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-team.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-team.c' object='clients/tui/nmtui-nmt-page-team.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/config/test_config-nm-test-device.obj: src/core/tests/config/nm-test-device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/config/test_config-nm-test-device.obj -MD -MP -MF src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Tpo -c -o src/core/tests/config/test_config-nm-test-device.obj `if test -f 'src/core/tests/config/nm-test-device.c'; then $(CYGPATH_W) 'src/core/tests/config/nm-test-device.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/config/nm-test-device.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Tpo src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/config/nm-test-device.c' object='src/core/tests/config/test_config-nm-test-device.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-team.obj `if test -f 'clients/tui/nmt-page-team.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-team.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-team.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/config/test_config-nm-test-device.obj `if test -f 'src/core/tests/config/nm-test-device.c'; then $(CYGPATH_W) 'src/core/tests/config/nm-test-device.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/config/nm-test-device.c'; fi` -clients/tui/nmtui-nmt-page-team-port.o: clients/tui/nmt-page-team-port.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-team-port.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-team-port.Tpo -c -o clients/tui/nmtui-nmt-page-team-port.o `test -f 'clients/tui/nmt-page-team-port.c' || echo '$(srcdir)/'`clients/tui/nmt-page-team-port.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-team-port.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-team-port.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-team-port.c' object='clients/tui/nmtui-nmt-page-team-port.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/config/test_config-test-config.o: src/core/tests/config/test-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/config/test_config-test-config.o -MD -MP -MF src/core/tests/config/$(DEPDIR)/test_config-test-config.Tpo -c -o src/core/tests/config/test_config-test-config.o `test -f 'src/core/tests/config/test-config.c' || echo '$(srcdir)/'`src/core/tests/config/test-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/config/$(DEPDIR)/test_config-test-config.Tpo src/core/tests/config/$(DEPDIR)/test_config-test-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/config/test-config.c' object='src/core/tests/config/test_config-test-config.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-team-port.o `test -f 'clients/tui/nmt-page-team-port.c' || echo '$(srcdir)/'`clients/tui/nmt-page-team-port.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/config/test_config-test-config.o `test -f 'src/core/tests/config/test-config.c' || echo '$(srcdir)/'`src/core/tests/config/test-config.c -clients/tui/nmtui-nmt-page-team-port.obj: clients/tui/nmt-page-team-port.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-team-port.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-team-port.Tpo -c -o clients/tui/nmtui-nmt-page-team-port.obj `if test -f 'clients/tui/nmt-page-team-port.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-team-port.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-team-port.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-team-port.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-team-port.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-team-port.c' object='clients/tui/nmtui-nmt-page-team-port.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/config/test_config-test-config.obj: src/core/tests/config/test-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/config/test_config-test-config.obj -MD -MP -MF src/core/tests/config/$(DEPDIR)/test_config-test-config.Tpo -c -o src/core/tests/config/test_config-test-config.obj `if test -f 'src/core/tests/config/test-config.c'; then $(CYGPATH_W) 'src/core/tests/config/test-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/config/test-config.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/config/$(DEPDIR)/test_config-test-config.Tpo src/core/tests/config/$(DEPDIR)/test_config-test-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/config/test-config.c' object='src/core/tests/config/test_config-test-config.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-team-port.obj `if test -f 'clients/tui/nmt-page-team-port.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-team-port.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-team-port.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/config/test_config-test-config.obj `if test -f 'src/core/tests/config/test-config.c'; then $(CYGPATH_W) 'src/core/tests/config/test-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/config/test-config.c'; fi` -clients/tui/nmtui-nmt-page-vlan.o: clients/tui/nmt-page-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-vlan.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-vlan.Tpo -c -o clients/tui/nmtui-nmt-page-vlan.o `test -f 'clients/tui/nmt-page-vlan.c' || echo '$(srcdir)/'`clients/tui/nmt-page-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-vlan.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-vlan.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-vlan.c' object='clients/tui/nmtui-nmt-page-vlan.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_core-test-core.o: src/core/tests/test-core.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_core-test-core.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_core-test-core.Tpo -c -o src/core/tests/test_core-test-core.o `test -f 'src/core/tests/test-core.c' || echo '$(srcdir)/'`src/core/tests/test-core.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_core-test-core.Tpo src/core/tests/$(DEPDIR)/test_core-test-core.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-core.c' object='src/core/tests/test_core-test-core.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-vlan.o `test -f 'clients/tui/nmt-page-vlan.c' || echo '$(srcdir)/'`clients/tui/nmt-page-vlan.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_core-test-core.o `test -f 'src/core/tests/test-core.c' || echo '$(srcdir)/'`src/core/tests/test-core.c -clients/tui/nmtui-nmt-page-vlan.obj: clients/tui/nmt-page-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-vlan.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-vlan.Tpo -c -o clients/tui/nmtui-nmt-page-vlan.obj `if test -f 'clients/tui/nmt-page-vlan.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-vlan.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-vlan.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-vlan.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-vlan.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-vlan.c' object='clients/tui/nmtui-nmt-page-vlan.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_core-test-core.obj: src/core/tests/test-core.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_core-test-core.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_core-test-core.Tpo -c -o src/core/tests/test_core-test-core.obj `if test -f 'src/core/tests/test-core.c'; then $(CYGPATH_W) 'src/core/tests/test-core.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-core.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_core-test-core.Tpo src/core/tests/$(DEPDIR)/test_core-test-core.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-core.c' object='src/core/tests/test_core-test-core.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-vlan.obj `if test -f 'clients/tui/nmt-page-vlan.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-vlan.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-vlan.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_core-test-core.obj `if test -f 'src/core/tests/test-core.c'; then $(CYGPATH_W) 'src/core/tests/test-core.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-core.c'; fi` -clients/tui/nmtui-nmt-page-wifi.o: clients/tui/nmt-page-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-wifi.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-wifi.Tpo -c -o clients/tui/nmtui-nmt-page-wifi.o `test -f 'clients/tui/nmt-page-wifi.c' || echo '$(srcdir)/'`clients/tui/nmt-page-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-wifi.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-wifi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-wifi.c' object='clients/tui/nmtui-nmt-page-wifi.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_core_with_expect-test-core-with-expect.o: src/core/tests/test-core-with-expect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_with_expect_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_core_with_expect-test-core-with-expect.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Tpo -c -o src/core/tests/test_core_with_expect-test-core-with-expect.o `test -f 'src/core/tests/test-core-with-expect.c' || echo '$(srcdir)/'`src/core/tests/test-core-with-expect.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Tpo src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-core-with-expect.c' object='src/core/tests/test_core_with_expect-test-core-with-expect.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-wifi.o `test -f 'clients/tui/nmt-page-wifi.c' || echo '$(srcdir)/'`clients/tui/nmt-page-wifi.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_with_expect_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_core_with_expect-test-core-with-expect.o `test -f 'src/core/tests/test-core-with-expect.c' || echo '$(srcdir)/'`src/core/tests/test-core-with-expect.c -clients/tui/nmtui-nmt-page-wifi.obj: clients/tui/nmt-page-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-page-wifi.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-page-wifi.Tpo -c -o clients/tui/nmtui-nmt-page-wifi.obj `if test -f 'clients/tui/nmt-page-wifi.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-wifi.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-wifi.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-page-wifi.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-page-wifi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-page-wifi.c' object='clients/tui/nmtui-nmt-page-wifi.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_core_with_expect-test-core-with-expect.obj: src/core/tests/test-core-with-expect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_with_expect_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_core_with_expect-test-core-with-expect.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Tpo -c -o src/core/tests/test_core_with_expect-test-core-with-expect.obj `if test -f 'src/core/tests/test-core-with-expect.c'; then $(CYGPATH_W) 'src/core/tests/test-core-with-expect.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-core-with-expect.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Tpo src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-core-with-expect.c' object='src/core/tests/test_core_with_expect-test-core-with-expect.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-page-wifi.obj `if test -f 'clients/tui/nmt-page-wifi.c'; then $(CYGPATH_W) 'clients/tui/nmt-page-wifi.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-page-wifi.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_with_expect_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_core_with_expect-test-core-with-expect.obj `if test -f 'src/core/tests/test-core-with-expect.c'; then $(CYGPATH_W) 'src/core/tests/test-core-with-expect.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-core-with-expect.c'; fi` -clients/tui/nmtui-nmt-password-dialog.o: clients/tui/nmt-password-dialog.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-password-dialog.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-password-dialog.Tpo -c -o clients/tui/nmtui-nmt-password-dialog.o `test -f 'clients/tui/nmt-password-dialog.c' || echo '$(srcdir)/'`clients/tui/nmt-password-dialog.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-password-dialog.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-password-dialog.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-password-dialog.c' object='clients/tui/nmtui-nmt-password-dialog.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_dcb-test-dcb.o: src/core/tests/test-dcb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_dcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_dcb-test-dcb.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Tpo -c -o src/core/tests/test_dcb-test-dcb.o `test -f 'src/core/tests/test-dcb.c' || echo '$(srcdir)/'`src/core/tests/test-dcb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Tpo src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-dcb.c' object='src/core/tests/test_dcb-test-dcb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-password-dialog.o `test -f 'clients/tui/nmt-password-dialog.c' || echo '$(srcdir)/'`clients/tui/nmt-password-dialog.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_dcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_dcb-test-dcb.o `test -f 'src/core/tests/test-dcb.c' || echo '$(srcdir)/'`src/core/tests/test-dcb.c -clients/tui/nmtui-nmt-password-dialog.obj: clients/tui/nmt-password-dialog.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-password-dialog.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-password-dialog.Tpo -c -o clients/tui/nmtui-nmt-password-dialog.obj `if test -f 'clients/tui/nmt-password-dialog.c'; then $(CYGPATH_W) 'clients/tui/nmt-password-dialog.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-password-dialog.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-password-dialog.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-password-dialog.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-password-dialog.c' object='clients/tui/nmtui-nmt-password-dialog.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_dcb-test-dcb.obj: src/core/tests/test-dcb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_dcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_dcb-test-dcb.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Tpo -c -o src/core/tests/test_dcb-test-dcb.obj `if test -f 'src/core/tests/test-dcb.c'; then $(CYGPATH_W) 'src/core/tests/test-dcb.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-dcb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Tpo src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-dcb.c' object='src/core/tests/test_dcb-test-dcb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-password-dialog.obj `if test -f 'clients/tui/nmt-password-dialog.c'; then $(CYGPATH_W) 'clients/tui/nmt-password-dialog.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-password-dialog.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_dcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_dcb-test-dcb.obj `if test -f 'src/core/tests/test-dcb.c'; then $(CYGPATH_W) 'src/core/tests/test-dcb.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-dcb.c'; fi` -clients/tui/nmtui-nmt-password-fields.o: clients/tui/nmt-password-fields.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-password-fields.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-password-fields.Tpo -c -o clients/tui/nmtui-nmt-password-fields.o `test -f 'clients/tui/nmt-password-fields.c' || echo '$(srcdir)/'`clients/tui/nmt-password-fields.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-password-fields.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-password-fields.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-password-fields.c' object='clients/tui/nmtui-nmt-password-fields.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_ip4_config-test-ip4-config.o: src/core/tests/test-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip4_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_ip4_config-test-ip4-config.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Tpo -c -o src/core/tests/test_ip4_config-test-ip4-config.o `test -f 'src/core/tests/test-ip4-config.c' || echo '$(srcdir)/'`src/core/tests/test-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Tpo src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-ip4-config.c' object='src/core/tests/test_ip4_config-test-ip4-config.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-password-fields.o `test -f 'clients/tui/nmt-password-fields.c' || echo '$(srcdir)/'`clients/tui/nmt-password-fields.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip4_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_ip4_config-test-ip4-config.o `test -f 'src/core/tests/test-ip4-config.c' || echo '$(srcdir)/'`src/core/tests/test-ip4-config.c -clients/tui/nmtui-nmt-password-fields.obj: clients/tui/nmt-password-fields.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-password-fields.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-password-fields.Tpo -c -o clients/tui/nmtui-nmt-password-fields.obj `if test -f 'clients/tui/nmt-password-fields.c'; then $(CYGPATH_W) 'clients/tui/nmt-password-fields.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-password-fields.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-password-fields.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-password-fields.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-password-fields.c' object='clients/tui/nmtui-nmt-password-fields.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_ip4_config-test-ip4-config.obj: src/core/tests/test-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip4_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_ip4_config-test-ip4-config.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Tpo -c -o src/core/tests/test_ip4_config-test-ip4-config.obj `if test -f 'src/core/tests/test-ip4-config.c'; then $(CYGPATH_W) 'src/core/tests/test-ip4-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-ip4-config.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Tpo src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-ip4-config.c' object='src/core/tests/test_ip4_config-test-ip4-config.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-password-fields.obj `if test -f 'clients/tui/nmt-password-fields.c'; then $(CYGPATH_W) 'clients/tui/nmt-password-fields.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-password-fields.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip4_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_ip4_config-test-ip4-config.obj `if test -f 'src/core/tests/test-ip4-config.c'; then $(CYGPATH_W) 'src/core/tests/test-ip4-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-ip4-config.c'; fi` -clients/tui/nmtui-nmt-route-editor.o: clients/tui/nmt-route-editor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-route-editor.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-route-editor.Tpo -c -o clients/tui/nmtui-nmt-route-editor.o `test -f 'clients/tui/nmt-route-editor.c' || echo '$(srcdir)/'`clients/tui/nmt-route-editor.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-route-editor.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-route-editor.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-route-editor.c' object='clients/tui/nmtui-nmt-route-editor.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_ip6_config-test-ip6-config.o: src/core/tests/test-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip6_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_ip6_config-test-ip6-config.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Tpo -c -o src/core/tests/test_ip6_config-test-ip6-config.o `test -f 'src/core/tests/test-ip6-config.c' || echo '$(srcdir)/'`src/core/tests/test-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Tpo src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-ip6-config.c' object='src/core/tests/test_ip6_config-test-ip6-config.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-route-editor.o `test -f 'clients/tui/nmt-route-editor.c' || echo '$(srcdir)/'`clients/tui/nmt-route-editor.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip6_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_ip6_config-test-ip6-config.o `test -f 'src/core/tests/test-ip6-config.c' || echo '$(srcdir)/'`src/core/tests/test-ip6-config.c -clients/tui/nmtui-nmt-route-editor.obj: clients/tui/nmt-route-editor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-route-editor.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-route-editor.Tpo -c -o clients/tui/nmtui-nmt-route-editor.obj `if test -f 'clients/tui/nmt-route-editor.c'; then $(CYGPATH_W) 'clients/tui/nmt-route-editor.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-route-editor.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-route-editor.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-route-editor.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-route-editor.c' object='clients/tui/nmtui-nmt-route-editor.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_ip6_config-test-ip6-config.obj: src/core/tests/test-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip6_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_ip6_config-test-ip6-config.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Tpo -c -o src/core/tests/test_ip6_config-test-ip6-config.obj `if test -f 'src/core/tests/test-ip6-config.c'; then $(CYGPATH_W) 'src/core/tests/test-ip6-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-ip6-config.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Tpo src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-ip6-config.c' object='src/core/tests/test_ip6_config-test-ip6-config.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-route-editor.obj `if test -f 'clients/tui/nmt-route-editor.c'; then $(CYGPATH_W) 'clients/tui/nmt-route-editor.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-route-editor.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip6_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_ip6_config-test-ip6-config.obj `if test -f 'src/core/tests/test-ip6-config.c'; then $(CYGPATH_W) 'src/core/tests/test-ip6-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-ip6-config.c'; fi` -clients/tui/nmtui-nmt-route-entry.o: clients/tui/nmt-route-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-route-entry.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-route-entry.Tpo -c -o clients/tui/nmtui-nmt-route-entry.o `test -f 'clients/tui/nmt-route-entry.c' || echo '$(srcdir)/'`clients/tui/nmt-route-entry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-route-entry.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-route-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-route-entry.c' object='clients/tui/nmtui-nmt-route-entry.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_l3cfg-test-l3cfg.o: src/core/tests/test-l3cfg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_l3cfg_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_l3cfg-test-l3cfg.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Tpo -c -o src/core/tests/test_l3cfg-test-l3cfg.o `test -f 'src/core/tests/test-l3cfg.c' || echo '$(srcdir)/'`src/core/tests/test-l3cfg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Tpo src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-l3cfg.c' object='src/core/tests/test_l3cfg-test-l3cfg.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-route-entry.o `test -f 'clients/tui/nmt-route-entry.c' || echo '$(srcdir)/'`clients/tui/nmt-route-entry.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_l3cfg_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_l3cfg-test-l3cfg.o `test -f 'src/core/tests/test-l3cfg.c' || echo '$(srcdir)/'`src/core/tests/test-l3cfg.c -clients/tui/nmtui-nmt-route-entry.obj: clients/tui/nmt-route-entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-route-entry.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-route-entry.Tpo -c -o clients/tui/nmtui-nmt-route-entry.obj `if test -f 'clients/tui/nmt-route-entry.c'; then $(CYGPATH_W) 'clients/tui/nmt-route-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-route-entry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-route-entry.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-route-entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-route-entry.c' object='clients/tui/nmtui-nmt-route-entry.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_l3cfg-test-l3cfg.obj: src/core/tests/test-l3cfg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_l3cfg_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_l3cfg-test-l3cfg.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Tpo -c -o src/core/tests/test_l3cfg-test-l3cfg.obj `if test -f 'src/core/tests/test-l3cfg.c'; then $(CYGPATH_W) 'src/core/tests/test-l3cfg.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-l3cfg.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Tpo src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-l3cfg.c' object='src/core/tests/test_l3cfg-test-l3cfg.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-route-entry.obj `if test -f 'clients/tui/nmt-route-entry.c'; then $(CYGPATH_W) 'clients/tui/nmt-route-entry.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-route-entry.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_l3cfg_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_l3cfg-test-l3cfg.obj `if test -f 'src/core/tests/test-l3cfg.c'; then $(CYGPATH_W) 'src/core/tests/test-l3cfg.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-l3cfg.c'; fi` -clients/tui/nmtui-nmt-route-table.o: clients/tui/nmt-route-table.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-route-table.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-route-table.Tpo -c -o clients/tui/nmtui-nmt-route-table.o `test -f 'clients/tui/nmt-route-table.c' || echo '$(srcdir)/'`clients/tui/nmt-route-table.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-route-table.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-route-table.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-route-table.c' object='clients/tui/nmtui-nmt-route-table.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_systemd-test-systemd.o: src/core/tests/test-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_systemd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_systemd-test-systemd.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Tpo -c -o src/core/tests/test_systemd-test-systemd.o `test -f 'src/core/tests/test-systemd.c' || echo '$(srcdir)/'`src/core/tests/test-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Tpo src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-systemd.c' object='src/core/tests/test_systemd-test-systemd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-route-table.o `test -f 'clients/tui/nmt-route-table.c' || echo '$(srcdir)/'`clients/tui/nmt-route-table.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_systemd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_systemd-test-systemd.o `test -f 'src/core/tests/test-systemd.c' || echo '$(srcdir)/'`src/core/tests/test-systemd.c -clients/tui/nmtui-nmt-route-table.obj: clients/tui/nmt-route-table.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-route-table.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-route-table.Tpo -c -o clients/tui/nmtui-nmt-route-table.obj `if test -f 'clients/tui/nmt-route-table.c'; then $(CYGPATH_W) 'clients/tui/nmt-route-table.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-route-table.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-route-table.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-route-table.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-route-table.c' object='clients/tui/nmtui-nmt-route-table.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_systemd-test-systemd.obj: src/core/tests/test-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_systemd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_systemd-test-systemd.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Tpo -c -o src/core/tests/test_systemd-test-systemd.obj `if test -f 'src/core/tests/test-systemd.c'; then $(CYGPATH_W) 'src/core/tests/test-systemd.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-systemd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Tpo src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-systemd.c' object='src/core/tests/test_systemd-test-systemd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-route-table.obj `if test -f 'clients/tui/nmt-route-table.c'; then $(CYGPATH_W) 'clients/tui/nmt-route-table.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-route-table.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_systemd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_systemd-test-systemd.obj `if test -f 'src/core/tests/test-systemd.c'; then $(CYGPATH_W) 'src/core/tests/test-systemd.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-systemd.c'; fi` -clients/tui/nmtui-nmt-slave-list.o: clients/tui/nmt-slave-list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-slave-list.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-slave-list.Tpo -c -o clients/tui/nmtui-nmt-slave-list.o `test -f 'clients/tui/nmt-slave-list.c' || echo '$(srcdir)/'`clients/tui/nmt-slave-list.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-slave-list.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-slave-list.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-slave-list.c' object='clients/tui/nmtui-nmt-slave-list.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_utils-test-utils.o: src/core/tests/test-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_utils-test-utils.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_utils-test-utils.Tpo -c -o src/core/tests/test_utils-test-utils.o `test -f 'src/core/tests/test-utils.c' || echo '$(srcdir)/'`src/core/tests/test-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_utils-test-utils.Tpo src/core/tests/$(DEPDIR)/test_utils-test-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-utils.c' object='src/core/tests/test_utils-test-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-slave-list.o `test -f 'clients/tui/nmt-slave-list.c' || echo '$(srcdir)/'`clients/tui/nmt-slave-list.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_utils-test-utils.o `test -f 'src/core/tests/test-utils.c' || echo '$(srcdir)/'`src/core/tests/test-utils.c -clients/tui/nmtui-nmt-slave-list.obj: clients/tui/nmt-slave-list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-slave-list.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-slave-list.Tpo -c -o clients/tui/nmtui-nmt-slave-list.obj `if test -f 'clients/tui/nmt-slave-list.c'; then $(CYGPATH_W) 'clients/tui/nmt-slave-list.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-slave-list.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-slave-list.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-slave-list.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-slave-list.c' object='clients/tui/nmtui-nmt-slave-list.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_utils-test-utils.obj: src/core/tests/test-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_utils-test-utils.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_utils-test-utils.Tpo -c -o src/core/tests/test_utils-test-utils.obj `if test -f 'src/core/tests/test-utils.c'; then $(CYGPATH_W) 'src/core/tests/test-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_utils-test-utils.Tpo src/core/tests/$(DEPDIR)/test_utils-test-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-utils.c' object='src/core/tests/test_utils-test-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-slave-list.obj `if test -f 'clients/tui/nmt-slave-list.c'; then $(CYGPATH_W) 'clients/tui/nmt-slave-list.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-slave-list.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_utils-test-utils.obj `if test -f 'src/core/tests/test-utils.c'; then $(CYGPATH_W) 'src/core/tests/test-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-utils.c'; fi` -clients/tui/nmtui-nmt-utils.o: clients/tui/nmt-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-utils.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-utils.Tpo -c -o clients/tui/nmtui-nmt-utils.o `test -f 'clients/tui/nmt-utils.c' || echo '$(srcdir)/'`clients/tui/nmt-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-utils.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-utils.c' object='clients/tui/nmtui-nmt-utils.o' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_wired_defname-test-wired-defname.o: src/core/tests/test-wired-defname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_wired_defname-test-wired-defname.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Tpo -c -o src/core/tests/test_wired_defname-test-wired-defname.o `test -f 'src/core/tests/test-wired-defname.c' || echo '$(srcdir)/'`src/core/tests/test-wired-defname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Tpo src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-wired-defname.c' object='src/core/tests/test_wired_defname-test-wired-defname.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-utils.o `test -f 'clients/tui/nmt-utils.c' || echo '$(srcdir)/'`clients/tui/nmt-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_wired_defname-test-wired-defname.o `test -f 'src/core/tests/test-wired-defname.c' || echo '$(srcdir)/'`src/core/tests/test-wired-defname.c -clients/tui/nmtui-nmt-utils.obj: clients/tui/nmt-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-utils.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-utils.Tpo -c -o clients/tui/nmtui-nmt-utils.obj `if test -f 'clients/tui/nmt-utils.c'; then $(CYGPATH_W) 'clients/tui/nmt-utils.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-utils.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-utils.c' object='clients/tui/nmtui-nmt-utils.obj' libtool=no @AMDEPBACKSLASH@ +src/core/tests/test_wired_defname-test-wired-defname.obj: src/core/tests/test-wired-defname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_wired_defname-test-wired-defname.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Tpo -c -o src/core/tests/test_wired_defname-test-wired-defname.obj `if test -f 'src/core/tests/test-wired-defname.c'; then $(CYGPATH_W) 'src/core/tests/test-wired-defname.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-wired-defname.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Tpo src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-wired-defname.c' object='src/core/tests/test_wired_defname-test-wired-defname.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-utils.obj `if test -f 'clients/tui/nmt-utils.c'; then $(CYGPATH_W) 'clients/tui/nmt-utils.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-utils.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_wired_defname-test-wired-defname.obj `if test -f 'src/core/tests/test-wired-defname.c'; then $(CYGPATH_W) 'src/core/tests/test-wired-defname.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-wired-defname.c'; fi` -clients/tui/nmtui-nmt-widget-list.o: clients/tui/nmt-widget-list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-widget-list.o -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-widget-list.Tpo -c -o clients/tui/nmtui-nmt-widget-list.o `test -f 'clients/tui/nmt-widget-list.c' || echo '$(srcdir)/'`clients/tui/nmt-widget-list.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-widget-list.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-widget-list.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-widget-list.c' object='clients/tui/nmtui-nmt-widget-list.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.o: src/libnm-client-aux-extern/tests/test-libnm-client-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_aux_extern_tests_test_libnm_client_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.o -MD -MP -MF src/libnm-client-aux-extern/tests/$(DEPDIR)/test_libnm_client_aux-test-libnm-client-aux.Tpo -c -o src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.o `test -f 'src/libnm-client-aux-extern/tests/test-libnm-client-aux.c' || echo '$(srcdir)/'`src/libnm-client-aux-extern/tests/test-libnm-client-aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-aux-extern/tests/$(DEPDIR)/test_libnm_client_aux-test-libnm-client-aux.Tpo src/libnm-client-aux-extern/tests/$(DEPDIR)/test_libnm_client_aux-test-libnm-client-aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-aux-extern/tests/test-libnm-client-aux.c' object='src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-widget-list.o `test -f 'clients/tui/nmt-widget-list.c' || echo '$(srcdir)/'`clients/tui/nmt-widget-list.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_aux_extern_tests_test_libnm_client_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.o `test -f 'src/libnm-client-aux-extern/tests/test-libnm-client-aux.c' || echo '$(srcdir)/'`src/libnm-client-aux-extern/tests/test-libnm-client-aux.c -clients/tui/nmtui-nmt-widget-list.obj: clients/tui/nmt-widget-list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clients/tui/nmtui-nmt-widget-list.obj -MD -MP -MF clients/tui/$(DEPDIR)/nmtui-nmt-widget-list.Tpo -c -o clients/tui/nmtui-nmt-widget-list.obj `if test -f 'clients/tui/nmt-widget-list.c'; then $(CYGPATH_W) 'clients/tui/nmt-widget-list.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-widget-list.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) clients/tui/$(DEPDIR)/nmtui-nmt-widget-list.Tpo clients/tui/$(DEPDIR)/nmtui-nmt-widget-list.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clients/tui/nmt-widget-list.c' object='clients/tui/nmtui-nmt-widget-list.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.obj: src/libnm-client-aux-extern/tests/test-libnm-client-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_aux_extern_tests_test_libnm_client_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.obj -MD -MP -MF src/libnm-client-aux-extern/tests/$(DEPDIR)/test_libnm_client_aux-test-libnm-client-aux.Tpo -c -o src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.obj `if test -f 'src/libnm-client-aux-extern/tests/test-libnm-client-aux.c'; then $(CYGPATH_W) 'src/libnm-client-aux-extern/tests/test-libnm-client-aux.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-client-aux-extern/tests/test-libnm-client-aux.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-aux-extern/tests/$(DEPDIR)/test_libnm_client_aux-test-libnm-client-aux.Tpo src/libnm-client-aux-extern/tests/$(DEPDIR)/test_libnm_client_aux-test-libnm-client-aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-aux-extern/tests/test-libnm-client-aux.c' object='src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clients_tui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clients/tui/nmtui-nmt-widget-list.obj `if test -f 'clients/tui/nmt-widget-list.c'; then $(CYGPATH_W) 'clients/tui/nmt-widget-list.c'; else $(CYGPATH_W) '$(srcdir)/clients/tui/nmt-widget-list.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_aux_extern_tests_test_libnm_client_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-aux-extern/tests/test_libnm_client_aux-test-libnm-client-aux.obj `if test -f 'src/libnm-client-aux-extern/tests/test-libnm-client-aux.c'; then $(CYGPATH_W) 'src/libnm-client-aux-extern/tests/test-libnm-client-aux.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-client-aux-extern/tests/test-libnm-client-aux.c'; fi` -dispatcher/nm_dispatcher-nm-dispatcher.o: dispatcher/nm-dispatcher.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_nm_dispatcher_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dispatcher/nm_dispatcher-nm-dispatcher.o -MD -MP -MF dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Tpo -c -o dispatcher/nm_dispatcher-nm-dispatcher.o `test -f 'dispatcher/nm-dispatcher.c' || echo '$(srcdir)/'`dispatcher/nm-dispatcher.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Tpo dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dispatcher/nm-dispatcher.c' object='dispatcher/nm_dispatcher-nm-dispatcher.o' libtool=no @AMDEPBACKSLASH@ +src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.o: src/contrib/nm-compat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.o -MD -MP -MF src/contrib/$(DEPDIR)/libnm_client_impl_tests_test_libnm-nm-compat.Tpo -c -o src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.o `test -f 'src/contrib/nm-compat.c' || echo '$(srcdir)/'`src/contrib/nm-compat.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/contrib/$(DEPDIR)/libnm_client_impl_tests_test_libnm-nm-compat.Tpo src/contrib/$(DEPDIR)/libnm_client_impl_tests_test_libnm-nm-compat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/contrib/nm-compat.c' object='src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_nm_dispatcher_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dispatcher/nm_dispatcher-nm-dispatcher.o `test -f 'dispatcher/nm-dispatcher.c' || echo '$(srcdir)/'`dispatcher/nm-dispatcher.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.o `test -f 'src/contrib/nm-compat.c' || echo '$(srcdir)/'`src/contrib/nm-compat.c -dispatcher/nm_dispatcher-nm-dispatcher.obj: dispatcher/nm-dispatcher.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_nm_dispatcher_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dispatcher/nm_dispatcher-nm-dispatcher.obj -MD -MP -MF dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Tpo -c -o dispatcher/nm_dispatcher-nm-dispatcher.obj `if test -f 'dispatcher/nm-dispatcher.c'; then $(CYGPATH_W) 'dispatcher/nm-dispatcher.c'; else $(CYGPATH_W) '$(srcdir)/dispatcher/nm-dispatcher.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Tpo dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dispatcher/nm-dispatcher.c' object='dispatcher/nm_dispatcher-nm-dispatcher.obj' libtool=no @AMDEPBACKSLASH@ +src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.obj: src/contrib/nm-compat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.obj -MD -MP -MF src/contrib/$(DEPDIR)/libnm_client_impl_tests_test_libnm-nm-compat.Tpo -c -o src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.obj `if test -f 'src/contrib/nm-compat.c'; then $(CYGPATH_W) 'src/contrib/nm-compat.c'; else $(CYGPATH_W) '$(srcdir)/src/contrib/nm-compat.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/contrib/$(DEPDIR)/libnm_client_impl_tests_test_libnm-nm-compat.Tpo src/contrib/$(DEPDIR)/libnm_client_impl_tests_test_libnm-nm-compat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/contrib/nm-compat.c' object='src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_nm_dispatcher_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dispatcher/nm_dispatcher-nm-dispatcher.obj `if test -f 'dispatcher/nm-dispatcher.c'; then $(CYGPATH_W) 'dispatcher/nm-dispatcher.c'; else $(CYGPATH_W) '$(srcdir)/dispatcher/nm-dispatcher.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/contrib/libnm_client_impl_tests_test_libnm-nm-compat.obj `if test -f 'src/contrib/nm-compat.c'; then $(CYGPATH_W) 'src/contrib/nm-compat.c'; else $(CYGPATH_W) '$(srcdir)/src/contrib/nm-compat.c'; fi` -dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.o: dispatcher/tests/test-dispatcher-envp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.o -MD -MP -MF dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo -c -o dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.o `test -f 'dispatcher/tests/test-dispatcher-envp.c' || echo '$(srcdir)/'`dispatcher/tests/test-dispatcher-envp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dispatcher/tests/test-dispatcher-envp.c' object='dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-client-impl/tests/test_libnm-test-libnm.o: src/libnm-client-impl/tests/test-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/tests/test_libnm-test-libnm.o -MD -MP -MF src/libnm-client-impl/tests/$(DEPDIR)/test_libnm-test-libnm.Tpo -c -o src/libnm-client-impl/tests/test_libnm-test-libnm.o `test -f 'src/libnm-client-impl/tests/test-libnm.c' || echo '$(srcdir)/'`src/libnm-client-impl/tests/test-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/tests/$(DEPDIR)/test_libnm-test-libnm.Tpo src/libnm-client-impl/tests/$(DEPDIR)/test_libnm-test-libnm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/tests/test-libnm.c' object='src/libnm-client-impl/tests/test_libnm-test-libnm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.o `test -f 'dispatcher/tests/test-dispatcher-envp.c' || echo '$(srcdir)/'`dispatcher/tests/test-dispatcher-envp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/tests/test_libnm-test-libnm.o `test -f 'src/libnm-client-impl/tests/test-libnm.c' || echo '$(srcdir)/'`src/libnm-client-impl/tests/test-libnm.c -dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.obj: dispatcher/tests/test-dispatcher-envp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.obj -MD -MP -MF dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo -c -o dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.obj `if test -f 'dispatcher/tests/test-dispatcher-envp.c'; then $(CYGPATH_W) 'dispatcher/tests/test-dispatcher-envp.c'; else $(CYGPATH_W) '$(srcdir)/dispatcher/tests/test-dispatcher-envp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dispatcher/tests/test-dispatcher-envp.c' object='dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-client-impl/tests/test_libnm-test-libnm.obj: src/libnm-client-impl/tests/test-libnm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/tests/test_libnm-test-libnm.obj -MD -MP -MF src/libnm-client-impl/tests/$(DEPDIR)/test_libnm-test-libnm.Tpo -c -o src/libnm-client-impl/tests/test_libnm-test-libnm.obj `if test -f 'src/libnm-client-impl/tests/test-libnm.c'; then $(CYGPATH_W) 'src/libnm-client-impl/tests/test-libnm.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-client-impl/tests/test-libnm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/tests/$(DEPDIR)/test_libnm-test-libnm.Tpo src/libnm-client-impl/tests/$(DEPDIR)/test_libnm-test-libnm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/tests/test-libnm.c' object='src/libnm-client-impl/tests/test_libnm-test-libnm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.obj `if test -f 'dispatcher/tests/test-dispatcher-envp.c'; then $(CYGPATH_W) 'dispatcher/tests/test-dispatcher-envp.c'; else $(CYGPATH_W) '$(srcdir)/dispatcher/tests/test-dispatcher-envp.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/tests/test_libnm-test-libnm.obj `if test -f 'src/libnm-client-impl/tests/test-libnm.c'; then $(CYGPATH_W) 'src/libnm-client-impl/tests/test-libnm.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-client-impl/tests/test-libnm.c'; fi` -dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.o: dispatcher/nmdbus-dispatcher.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.o -MD -MP -MF dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Tpo -c -o dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.o `test -f 'dispatcher/nmdbus-dispatcher.c' || echo '$(srcdir)/'`dispatcher/nmdbus-dispatcher.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Tpo dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dispatcher/nmdbus-dispatcher.c' object='dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-client-impl/tests/test_nm_client-test-nm-client.o: src/libnm-client-impl/tests/test-nm-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/tests/test_nm_client-test-nm-client.o -MD -MP -MF src/libnm-client-impl/tests/$(DEPDIR)/test_nm_client-test-nm-client.Tpo -c -o src/libnm-client-impl/tests/test_nm_client-test-nm-client.o `test -f 'src/libnm-client-impl/tests/test-nm-client.c' || echo '$(srcdir)/'`src/libnm-client-impl/tests/test-nm-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/tests/$(DEPDIR)/test_nm_client-test-nm-client.Tpo src/libnm-client-impl/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/tests/test-nm-client.c' object='src/libnm-client-impl/tests/test_nm_client-test-nm-client.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.o `test -f 'dispatcher/nmdbus-dispatcher.c' || echo '$(srcdir)/'`dispatcher/nmdbus-dispatcher.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/tests/test_nm_client-test-nm-client.o `test -f 'src/libnm-client-impl/tests/test-nm-client.c' || echo '$(srcdir)/'`src/libnm-client-impl/tests/test-nm-client.c -dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.obj: dispatcher/nmdbus-dispatcher.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.obj -MD -MP -MF dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Tpo -c -o dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.obj `if test -f 'dispatcher/nmdbus-dispatcher.c'; then $(CYGPATH_W) 'dispatcher/nmdbus-dispatcher.c'; else $(CYGPATH_W) '$(srcdir)/dispatcher/nmdbus-dispatcher.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Tpo dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dispatcher/nmdbus-dispatcher.c' object='dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-client-impl/tests/test_nm_client-test-nm-client.obj: src/libnm-client-impl/tests/test-nm-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/tests/test_nm_client-test-nm-client.obj -MD -MP -MF src/libnm-client-impl/tests/$(DEPDIR)/test_nm_client-test-nm-client.Tpo -c -o src/libnm-client-impl/tests/test_nm_client-test-nm-client.obj `if test -f 'src/libnm-client-impl/tests/test-nm-client.c'; then $(CYGPATH_W) 'src/libnm-client-impl/tests/test-nm-client.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-client-impl/tests/test-nm-client.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/tests/$(DEPDIR)/test_nm_client-test-nm-client.Tpo src/libnm-client-impl/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/tests/test-nm-client.c' object='src/libnm-client-impl/tests/test_nm_client-test-nm-client.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.obj `if test -f 'dispatcher/nmdbus-dispatcher.c'; then $(CYGPATH_W) 'dispatcher/nmdbus-dispatcher.c'; else $(CYGPATH_W) '$(srcdir)/dispatcher/nmdbus-dispatcher.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/tests/test_nm_client-test-nm-client.obj `if test -f 'src/libnm-client-impl/tests/test-nm-client.c'; then $(CYGPATH_W) 'src/libnm-client-impl/tests/test-nm-client.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-client-impl/tests/test-nm-client.c'; fi` -examples/C/glib/add_connection_gdbus-add-connection-gdbus.o: examples/C/glib/add-connection-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/add_connection_gdbus-add-connection-gdbus.o -MD -MP -MF examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Tpo -c -o examples/C/glib/add_connection_gdbus-add-connection-gdbus.o `test -f 'examples/C/glib/add-connection-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/add-connection-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Tpo examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/add-connection-gdbus.c' object='examples/C/glib/add_connection_gdbus-add-connection-gdbus.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.o: src/libnm-client-impl/tests/test-remote-settings-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.o -MD -MP -MF src/libnm-client-impl/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo -c -o src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.o `test -f 'src/libnm-client-impl/tests/test-remote-settings-client.c' || echo '$(srcdir)/'`src/libnm-client-impl/tests/test-remote-settings-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo src/libnm-client-impl/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/tests/test-remote-settings-client.c' object='src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/add_connection_gdbus-add-connection-gdbus.o `test -f 'examples/C/glib/add-connection-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/add-connection-gdbus.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.o `test -f 'src/libnm-client-impl/tests/test-remote-settings-client.c' || echo '$(srcdir)/'`src/libnm-client-impl/tests/test-remote-settings-client.c -examples/C/glib/add_connection_gdbus-add-connection-gdbus.obj: examples/C/glib/add-connection-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/add_connection_gdbus-add-connection-gdbus.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Tpo -c -o examples/C/glib/add_connection_gdbus-add-connection-gdbus.obj `if test -f 'examples/C/glib/add-connection-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/add-connection-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/add-connection-gdbus.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Tpo examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/add-connection-gdbus.c' object='examples/C/glib/add_connection_gdbus-add-connection-gdbus.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.obj: src/libnm-client-impl/tests/test-remote-settings-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.obj -MD -MP -MF src/libnm-client-impl/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo -c -o src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.obj `if test -f 'src/libnm-client-impl/tests/test-remote-settings-client.c'; then $(CYGPATH_W) 'src/libnm-client-impl/tests/test-remote-settings-client.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-client-impl/tests/test-remote-settings-client.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo src/libnm-client-impl/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/tests/test-remote-settings-client.c' object='src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/add_connection_gdbus-add-connection-gdbus.obj `if test -f 'examples/C/glib/add-connection-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/add-connection-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/add-connection-gdbus.c'; fi` - -examples/C/glib/add_connection_libnm-add-connection-libnm.o: examples/C/glib/add-connection-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/add_connection_libnm-add-connection-libnm.o -MD -MP -MF examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Tpo -c -o examples/C/glib/add_connection_libnm-add-connection-libnm.o `test -f 'examples/C/glib/add-connection-libnm.c' || echo '$(srcdir)/'`examples/C/glib/add-connection-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Tpo examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/add-connection-libnm.c' object='examples/C/glib/add_connection_libnm-add-connection-libnm.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/tests/test_remote_settings_client-test-remote-settings-client.obj `if test -f 'src/libnm-client-impl/tests/test-remote-settings-client.c'; then $(CYGPATH_W) 'src/libnm-client-impl/tests/test-remote-settings-client.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-client-impl/tests/test-remote-settings-client.c'; fi` + +src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.o: src/libnm-client-impl/tests/test-secret-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.o -MD -MP -MF src/libnm-client-impl/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Tpo -c -o src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.o `test -f 'src/libnm-client-impl/tests/test-secret-agent.c' || echo '$(srcdir)/'`src/libnm-client-impl/tests/test-secret-agent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Tpo src/libnm-client-impl/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/tests/test-secret-agent.c' object='src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/add_connection_libnm-add-connection-libnm.o `test -f 'examples/C/glib/add-connection-libnm.c' || echo '$(srcdir)/'`examples/C/glib/add-connection-libnm.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.o `test -f 'src/libnm-client-impl/tests/test-secret-agent.c' || echo '$(srcdir)/'`src/libnm-client-impl/tests/test-secret-agent.c -examples/C/glib/add_connection_libnm-add-connection-libnm.obj: examples/C/glib/add-connection-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/add_connection_libnm-add-connection-libnm.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Tpo -c -o examples/C/glib/add_connection_libnm-add-connection-libnm.obj `if test -f 'examples/C/glib/add-connection-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/add-connection-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/add-connection-libnm.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Tpo examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/add-connection-libnm.c' object='examples/C/glib/add_connection_libnm-add-connection-libnm.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.obj: src/libnm-client-impl/tests/test-secret-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.obj -MD -MP -MF src/libnm-client-impl/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Tpo -c -o src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.obj `if test -f 'src/libnm-client-impl/tests/test-secret-agent.c'; then $(CYGPATH_W) 'src/libnm-client-impl/tests/test-secret-agent.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-client-impl/tests/test-secret-agent.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-client-impl/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Tpo src/libnm-client-impl/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-client-impl/tests/test-secret-agent.c' object='src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_add_connection_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/add_connection_libnm-add-connection-libnm.obj `if test -f 'examples/C/glib/add-connection-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/add-connection-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/add-connection-libnm.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_client_impl_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-client-impl/tests/test_secret_agent-test-secret-agent.obj `if test -f 'src/libnm-client-impl/tests/test-secret-agent.c'; then $(CYGPATH_W) 'src/libnm-client-impl/tests/test-secret-agent.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-client-impl/tests/test-secret-agent.c'; fi` -examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.o: examples/C/glib/get-active-connections-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_active_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.o -MD -MP -MF examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Tpo -c -o examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.o `test -f 'examples/C/glib/get-active-connections-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/get-active-connections-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Tpo examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/get-active-connections-gdbus.c' object='examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_compare-test-compare.o: src/libnm-core-impl/tests/test-compare.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_compare_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_compare-test-compare.o -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_compare-test-compare.Tpo -c -o src/libnm-core-impl/tests/test_compare-test-compare.o `test -f 'src/libnm-core-impl/tests/test-compare.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-compare.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_compare-test-compare.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_compare-test-compare.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-compare.c' object='src/libnm-core-impl/tests/test_compare-test-compare.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_active_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.o `test -f 'examples/C/glib/get-active-connections-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/get-active-connections-gdbus.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_compare_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_compare-test-compare.o `test -f 'src/libnm-core-impl/tests/test-compare.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-compare.c -examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.obj: examples/C/glib/get-active-connections-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_active_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Tpo -c -o examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.obj `if test -f 'examples/C/glib/get-active-connections-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/get-active-connections-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/get-active-connections-gdbus.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Tpo examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/get-active-connections-gdbus.c' object='examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_compare-test-compare.obj: src/libnm-core-impl/tests/test-compare.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_compare_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_compare-test-compare.obj -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_compare-test-compare.Tpo -c -o src/libnm-core-impl/tests/test_compare-test-compare.obj `if test -f 'src/libnm-core-impl/tests/test-compare.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-compare.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-compare.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_compare-test-compare.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_compare-test-compare.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-compare.c' object='src/libnm-core-impl/tests/test_compare-test-compare.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_active_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/get_active_connections_gdbus-get-active-connections-gdbus.obj `if test -f 'examples/C/glib/get-active-connections-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/get-active-connections-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/get-active-connections-gdbus.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_compare_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_compare-test-compare.obj `if test -f 'src/libnm-core-impl/tests/test-compare.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-compare.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-compare.c'; fi` -examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.o: examples/C/glib/get-ap-info-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_ap_info_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.o -MD -MP -MF examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Tpo -c -o examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.o `test -f 'examples/C/glib/get-ap-info-libnm.c' || echo '$(srcdir)/'`examples/C/glib/get-ap-info-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Tpo examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/get-ap-info-libnm.c' object='examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_crypto-test-crypto.o: src/libnm-core-impl/tests/test-crypto.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_crypto-test-crypto.o -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_crypto-test-crypto.Tpo -c -o src/libnm-core-impl/tests/test_crypto-test-crypto.o `test -f 'src/libnm-core-impl/tests/test-crypto.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-crypto.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_crypto-test-crypto.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_crypto-test-crypto.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-crypto.c' object='src/libnm-core-impl/tests/test_crypto-test-crypto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_ap_info_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.o `test -f 'examples/C/glib/get-ap-info-libnm.c' || echo '$(srcdir)/'`examples/C/glib/get-ap-info-libnm.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_crypto-test-crypto.o `test -f 'src/libnm-core-impl/tests/test-crypto.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-crypto.c -examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.obj: examples/C/glib/get-ap-info-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_ap_info_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Tpo -c -o examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.obj `if test -f 'examples/C/glib/get-ap-info-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/get-ap-info-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/get-ap-info-libnm.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Tpo examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/get-ap-info-libnm.c' object='examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_crypto-test-crypto.obj: src/libnm-core-impl/tests/test-crypto.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_crypto-test-crypto.obj -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_crypto-test-crypto.Tpo -c -o src/libnm-core-impl/tests/test_crypto-test-crypto.obj `if test -f 'src/libnm-core-impl/tests/test-crypto.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-crypto.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-crypto.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_crypto-test-crypto.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_crypto-test-crypto.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-crypto.c' object='src/libnm-core-impl/tests/test_crypto-test-crypto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_get_ap_info_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/get_ap_info_libnm-get-ap-info-libnm.obj `if test -f 'examples/C/glib/get-ap-info-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/get-ap-info-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/get-ap-info-libnm.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_crypto-test-crypto.obj `if test -f 'src/libnm-core-impl/tests/test-crypto.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-crypto.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-crypto.c'; fi` -examples/C/glib/list_connections_gdbus-list-connections-gdbus.o: examples/C/glib/list-connections-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/list_connections_gdbus-list-connections-gdbus.o -MD -MP -MF examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Tpo -c -o examples/C/glib/list_connections_gdbus-list-connections-gdbus.o `test -f 'examples/C/glib/list-connections-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/list-connections-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Tpo examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/list-connections-gdbus.c' object='examples/C/glib/list_connections_gdbus-list-connections-gdbus.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_general-test-general.o: src/libnm-core-impl/tests/test-general.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_general-test-general.o -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_general-test-general.Tpo -c -o src/libnm-core-impl/tests/test_general-test-general.o `test -f 'src/libnm-core-impl/tests/test-general.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-general.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_general-test-general.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_general-test-general.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-general.c' object='src/libnm-core-impl/tests/test_general-test-general.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/list_connections_gdbus-list-connections-gdbus.o `test -f 'examples/C/glib/list-connections-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/list-connections-gdbus.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_general-test-general.o `test -f 'src/libnm-core-impl/tests/test-general.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-general.c -examples/C/glib/list_connections_gdbus-list-connections-gdbus.obj: examples/C/glib/list-connections-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/list_connections_gdbus-list-connections-gdbus.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Tpo -c -o examples/C/glib/list_connections_gdbus-list-connections-gdbus.obj `if test -f 'examples/C/glib/list-connections-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/list-connections-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/list-connections-gdbus.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Tpo examples/C/glib/$(DEPDIR)/list_connections_gdbus-list-connections-gdbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/list-connections-gdbus.c' object='examples/C/glib/list_connections_gdbus-list-connections-gdbus.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_general-test-general.obj: src/libnm-core-impl/tests/test-general.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_general-test-general.obj -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_general-test-general.Tpo -c -o src/libnm-core-impl/tests/test_general-test-general.obj `if test -f 'src/libnm-core-impl/tests/test-general.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-general.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-general.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_general-test-general.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_general-test-general.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-general.c' object='src/libnm-core-impl/tests/test_general-test-general.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/list_connections_gdbus-list-connections-gdbus.obj `if test -f 'examples/C/glib/list-connections-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/list-connections-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/list-connections-gdbus.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_general-test-general.obj `if test -f 'src/libnm-core-impl/tests/test-general.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-general.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-general.c'; fi` -examples/C/glib/list_connections_libnm-list-connections-libnm.o: examples/C/glib/list-connections-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/list_connections_libnm-list-connections-libnm.o -MD -MP -MF examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Tpo -c -o examples/C/glib/list_connections_libnm-list-connections-libnm.o `test -f 'examples/C/glib/list-connections-libnm.c' || echo '$(srcdir)/'`examples/C/glib/list-connections-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Tpo examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/list-connections-libnm.c' object='examples/C/glib/list_connections_libnm-list-connections-libnm.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.o: src/libnm-core-impl/tests/nm-core-tests-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.o -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Tpo -c -o src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.o `test -f 'src/libnm-core-impl/tests/nm-core-tests-enum-types.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/nm-core-tests-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/nm-core-tests-enum-types.c' object='src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/list_connections_libnm-list-connections-libnm.o `test -f 'examples/C/glib/list-connections-libnm.c' || echo '$(srcdir)/'`examples/C/glib/list-connections-libnm.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.o `test -f 'src/libnm-core-impl/tests/nm-core-tests-enum-types.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/nm-core-tests-enum-types.c -examples/C/glib/list_connections_libnm-list-connections-libnm.obj: examples/C/glib/list-connections-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/list_connections_libnm-list-connections-libnm.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Tpo -c -o examples/C/glib/list_connections_libnm-list-connections-libnm.obj `if test -f 'examples/C/glib/list-connections-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/list-connections-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/list-connections-libnm.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Tpo examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/list-connections-libnm.c' object='examples/C/glib/list_connections_libnm-list-connections-libnm.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.obj: src/libnm-core-impl/tests/nm-core-tests-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.obj -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Tpo -c -o src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.obj `if test -f 'src/libnm-core-impl/tests/nm-core-tests-enum-types.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/nm-core-tests-enum-types.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/nm-core-tests-enum-types.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/nm-core-tests-enum-types.c' object='src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_list_connections_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/list_connections_libnm-list-connections-libnm.obj `if test -f 'examples/C/glib/list-connections-libnm.c'; then $(CYGPATH_W) 'examples/C/glib/list-connections-libnm.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/list-connections-libnm.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_general-nm-core-tests-enum-types.obj `if test -f 'src/libnm-core-impl/tests/nm-core-tests-enum-types.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/nm-core-tests-enum-types.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/nm-core-tests-enum-types.c'; fi` -examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.o: examples/C/glib/monitor-nm-running-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_running_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.o -MD -MP -MF examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Tpo -c -o examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.o `test -f 'examples/C/glib/monitor-nm-running-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/monitor-nm-running-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Tpo examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/monitor-nm-running-gdbus.c' object='examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_keyfile-test-keyfile.o: src/libnm-core-impl/tests/test-keyfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_keyfile-test-keyfile.o -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_keyfile-test-keyfile.Tpo -c -o src/libnm-core-impl/tests/test_keyfile-test-keyfile.o `test -f 'src/libnm-core-impl/tests/test-keyfile.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-keyfile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_keyfile-test-keyfile.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-keyfile.c' object='src/libnm-core-impl/tests/test_keyfile-test-keyfile.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_running_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.o `test -f 'examples/C/glib/monitor-nm-running-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/monitor-nm-running-gdbus.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_keyfile-test-keyfile.o `test -f 'src/libnm-core-impl/tests/test-keyfile.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-keyfile.c -examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.obj: examples/C/glib/monitor-nm-running-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_running_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Tpo -c -o examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.obj `if test -f 'examples/C/glib/monitor-nm-running-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/monitor-nm-running-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/monitor-nm-running-gdbus.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Tpo examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/monitor-nm-running-gdbus.c' object='examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_keyfile-test-keyfile.obj: src/libnm-core-impl/tests/test-keyfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_keyfile-test-keyfile.obj -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_keyfile-test-keyfile.Tpo -c -o src/libnm-core-impl/tests/test_keyfile-test-keyfile.obj `if test -f 'src/libnm-core-impl/tests/test-keyfile.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-keyfile.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-keyfile.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_keyfile-test-keyfile.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-keyfile.c' object='src/libnm-core-impl/tests/test_keyfile-test-keyfile.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_running_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/monitor_nm_running_gdbus-monitor-nm-running-gdbus.obj `if test -f 'examples/C/glib/monitor-nm-running-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/monitor-nm-running-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/monitor-nm-running-gdbus.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_keyfile-test-keyfile.obj `if test -f 'src/libnm-core-impl/tests/test-keyfile.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-keyfile.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-keyfile.c'; fi` -examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.o: examples/C/glib/monitor-nm-state-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_state_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.o -MD -MP -MF examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Tpo -c -o examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.o `test -f 'examples/C/glib/monitor-nm-state-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/monitor-nm-state-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Tpo examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/monitor-nm-state-gdbus.c' object='examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_secrets-test-secrets.o: src/libnm-core-impl/tests/test-secrets.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_secrets_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_secrets-test-secrets.o -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_secrets-test-secrets.Tpo -c -o src/libnm-core-impl/tests/test_secrets-test-secrets.o `test -f 'src/libnm-core-impl/tests/test-secrets.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-secrets.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_secrets-test-secrets.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_secrets-test-secrets.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-secrets.c' object='src/libnm-core-impl/tests/test_secrets-test-secrets.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_state_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.o `test -f 'examples/C/glib/monitor-nm-state-gdbus.c' || echo '$(srcdir)/'`examples/C/glib/monitor-nm-state-gdbus.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_secrets_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_secrets-test-secrets.o `test -f 'src/libnm-core-impl/tests/test-secrets.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-secrets.c -examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.obj: examples/C/glib/monitor-nm-state-gdbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_state_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.obj -MD -MP -MF examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Tpo -c -o examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.obj `if test -f 'examples/C/glib/monitor-nm-state-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/monitor-nm-state-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/monitor-nm-state-gdbus.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Tpo examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='examples/C/glib/monitor-nm-state-gdbus.c' object='examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_secrets-test-secrets.obj: src/libnm-core-impl/tests/test-secrets.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_secrets_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_secrets-test-secrets.obj -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_secrets-test-secrets.Tpo -c -o src/libnm-core-impl/tests/test_secrets-test-secrets.obj `if test -f 'src/libnm-core-impl/tests/test-secrets.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-secrets.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-secrets.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_secrets-test-secrets.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_secrets-test-secrets.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-secrets.c' object='src/libnm-core-impl/tests/test_secrets-test-secrets.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(examples_C_glib_monitor_nm_state_gdbus_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o examples/C/glib/monitor_nm_state_gdbus-monitor-nm-state-gdbus.obj `if test -f 'examples/C/glib/monitor-nm-state-gdbus.c'; then $(CYGPATH_W) 'examples/C/glib/monitor-nm-state-gdbus.c'; else $(CYGPATH_W) '$(srcdir)/examples/C/glib/monitor-nm-state-gdbus.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_secrets_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_secrets-test-secrets.obj `if test -f 'src/libnm-core-impl/tests/test-secrets.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-secrets.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-secrets.c'; fi` -libnm-core/tests/test_compare-test-compare.o: libnm-core/tests/test-compare.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_compare_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_compare-test-compare.o -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_compare-test-compare.Tpo -c -o libnm-core/tests/test_compare-test-compare.o `test -f 'libnm-core/tests/test-compare.c' || echo '$(srcdir)/'`libnm-core/tests/test-compare.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_compare-test-compare.Tpo libnm-core/tests/$(DEPDIR)/test_compare-test-compare.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-compare.c' object='libnm-core/tests/test_compare-test-compare.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_setting-test-setting.o: src/libnm-core-impl/tests/test-setting.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_setting-test-setting.o -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_setting-test-setting.Tpo -c -o src/libnm-core-impl/tests/test_setting-test-setting.o `test -f 'src/libnm-core-impl/tests/test-setting.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-setting.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_setting-test-setting.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_setting-test-setting.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-setting.c' object='src/libnm-core-impl/tests/test_setting-test-setting.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_compare_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_compare-test-compare.o `test -f 'libnm-core/tests/test-compare.c' || echo '$(srcdir)/'`libnm-core/tests/test-compare.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_setting-test-setting.o `test -f 'src/libnm-core-impl/tests/test-setting.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-setting.c -libnm-core/tests/test_compare-test-compare.obj: libnm-core/tests/test-compare.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_compare_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_compare-test-compare.obj -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_compare-test-compare.Tpo -c -o libnm-core/tests/test_compare-test-compare.obj `if test -f 'libnm-core/tests/test-compare.c'; then $(CYGPATH_W) 'libnm-core/tests/test-compare.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-compare.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_compare-test-compare.Tpo libnm-core/tests/$(DEPDIR)/test_compare-test-compare.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-compare.c' object='libnm-core/tests/test_compare-test-compare.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_setting-test-setting.obj: src/libnm-core-impl/tests/test-setting.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_setting-test-setting.obj -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_setting-test-setting.Tpo -c -o src/libnm-core-impl/tests/test_setting-test-setting.obj `if test -f 'src/libnm-core-impl/tests/test-setting.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-setting.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-setting.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_setting-test-setting.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_setting-test-setting.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-setting.c' object='src/libnm-core-impl/tests/test_setting-test-setting.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_compare_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_compare-test-compare.obj `if test -f 'libnm-core/tests/test-compare.c'; then $(CYGPATH_W) 'libnm-core/tests/test-compare.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-compare.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_setting-test-setting.obj `if test -f 'src/libnm-core-impl/tests/test-setting.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-setting.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-setting.c'; fi` -libnm-core/tests/test_crypto-test-crypto.o: libnm-core/tests/test-crypto.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_crypto-test-crypto.o -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_crypto-test-crypto.Tpo -c -o libnm-core/tests/test_crypto-test-crypto.o `test -f 'libnm-core/tests/test-crypto.c' || echo '$(srcdir)/'`libnm-core/tests/test-crypto.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_crypto-test-crypto.Tpo libnm-core/tests/$(DEPDIR)/test_crypto-test-crypto.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-crypto.c' object='libnm-core/tests/test_crypto-test-crypto.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.o: src/libnm-core-impl/tests/test-settings-defaults.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_settings_defaults_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.o -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Tpo -c -o src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.o `test -f 'src/libnm-core-impl/tests/test-settings-defaults.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-settings-defaults.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-settings-defaults.c' object='src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_crypto-test-crypto.o `test -f 'libnm-core/tests/test-crypto.c' || echo '$(srcdir)/'`libnm-core/tests/test-crypto.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_settings_defaults_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.o `test -f 'src/libnm-core-impl/tests/test-settings-defaults.c' || echo '$(srcdir)/'`src/libnm-core-impl/tests/test-settings-defaults.c -libnm-core/tests/test_crypto-test-crypto.obj: libnm-core/tests/test-crypto.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_crypto-test-crypto.obj -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_crypto-test-crypto.Tpo -c -o libnm-core/tests/test_crypto-test-crypto.obj `if test -f 'libnm-core/tests/test-crypto.c'; then $(CYGPATH_W) 'libnm-core/tests/test-crypto.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-crypto.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_crypto-test-crypto.Tpo libnm-core/tests/$(DEPDIR)/test_crypto-test-crypto.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-crypto.c' object='libnm-core/tests/test_crypto-test-crypto.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.obj: src/libnm-core-impl/tests/test-settings-defaults.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_settings_defaults_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.obj -MD -MP -MF src/libnm-core-impl/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Tpo -c -o src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.obj `if test -f 'src/libnm-core-impl/tests/test-settings-defaults.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-settings-defaults.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-settings-defaults.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-core-impl/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Tpo src/libnm-core-impl/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-core-impl/tests/test-settings-defaults.c' object='src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_crypto-test-crypto.obj `if test -f 'libnm-core/tests/test-crypto.c'; then $(CYGPATH_W) 'libnm-core/tests/test-crypto.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-crypto.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_core_impl_tests_test_settings_defaults_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-core-impl/tests/test_settings_defaults-test-settings-defaults.obj `if test -f 'src/libnm-core-impl/tests/test-settings-defaults.c'; then $(CYGPATH_W) 'src/libnm-core-impl/tests/test-settings-defaults.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-core-impl/tests/test-settings-defaults.c'; fi` -libnm-core/tests/test_general-test-general.o: libnm-core/tests/test-general.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_general-test-general.o -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_general-test-general.Tpo -c -o libnm-core/tests/test_general-test-general.o `test -f 'libnm-core/tests/test-general.c' || echo '$(srcdir)/'`libnm-core/tests/test-general.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_general-test-general.Tpo libnm-core/tests/$(DEPDIR)/test_general-test-general.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-general.c' object='libnm-core/tests/test_general-test-general.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-glib-aux/tests/test_json_aux-test-json-aux.o: src/libnm-glib-aux/tests/test-json-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_tests_test_json_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/tests/test_json_aux-test-json-aux.o -MD -MP -MF src/libnm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Tpo -c -o src/libnm-glib-aux/tests/test_json_aux-test-json-aux.o `test -f 'src/libnm-glib-aux/tests/test-json-aux.c' || echo '$(srcdir)/'`src/libnm-glib-aux/tests/test-json-aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Tpo src/libnm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/tests/test-json-aux.c' object='src/libnm-glib-aux/tests/test_json_aux-test-json-aux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_general-test-general.o `test -f 'libnm-core/tests/test-general.c' || echo '$(srcdir)/'`libnm-core/tests/test-general.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_tests_test_json_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/tests/test_json_aux-test-json-aux.o `test -f 'src/libnm-glib-aux/tests/test-json-aux.c' || echo '$(srcdir)/'`src/libnm-glib-aux/tests/test-json-aux.c -libnm-core/tests/test_general-test-general.obj: libnm-core/tests/test-general.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_general-test-general.obj -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_general-test-general.Tpo -c -o libnm-core/tests/test_general-test-general.obj `if test -f 'libnm-core/tests/test-general.c'; then $(CYGPATH_W) 'libnm-core/tests/test-general.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-general.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_general-test-general.Tpo libnm-core/tests/$(DEPDIR)/test_general-test-general.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-general.c' object='libnm-core/tests/test_general-test-general.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-glib-aux/tests/test_json_aux-test-json-aux.obj: src/libnm-glib-aux/tests/test-json-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_tests_test_json_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/tests/test_json_aux-test-json-aux.obj -MD -MP -MF src/libnm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Tpo -c -o src/libnm-glib-aux/tests/test_json_aux-test-json-aux.obj `if test -f 'src/libnm-glib-aux/tests/test-json-aux.c'; then $(CYGPATH_W) 'src/libnm-glib-aux/tests/test-json-aux.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-glib-aux/tests/test-json-aux.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Tpo src/libnm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/tests/test-json-aux.c' object='src/libnm-glib-aux/tests/test_json_aux-test-json-aux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_general-test-general.obj `if test -f 'libnm-core/tests/test-general.c'; then $(CYGPATH_W) 'libnm-core/tests/test-general.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-general.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_tests_test_json_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/tests/test_json_aux-test-json-aux.obj `if test -f 'src/libnm-glib-aux/tests/test-json-aux.c'; then $(CYGPATH_W) 'src/libnm-glib-aux/tests/test-json-aux.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-glib-aux/tests/test-json-aux.c'; fi` -libnm-core/tests/test_general-nm-core-tests-enum-types.o: libnm-core/tests/nm-core-tests-enum-types.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_general-nm-core-tests-enum-types.o -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Tpo -c -o libnm-core/tests/test_general-nm-core-tests-enum-types.o `test -f 'libnm-core/tests/nm-core-tests-enum-types.c' || echo '$(srcdir)/'`libnm-core/tests/nm-core-tests-enum-types.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Tpo libnm-core/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/nm-core-tests-enum-types.c' object='libnm-core/tests/test_general-nm-core-tests-enum-types.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-glib-aux/tests/test_shared_general-test-shared-general.o: src/libnm-glib-aux/tests/test-shared-general.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_tests_test_shared_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/tests/test_shared_general-test-shared-general.o -MD -MP -MF src/libnm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Tpo -c -o src/libnm-glib-aux/tests/test_shared_general-test-shared-general.o `test -f 'src/libnm-glib-aux/tests/test-shared-general.c' || echo '$(srcdir)/'`src/libnm-glib-aux/tests/test-shared-general.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Tpo src/libnm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/tests/test-shared-general.c' object='src/libnm-glib-aux/tests/test_shared_general-test-shared-general.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_general-nm-core-tests-enum-types.o `test -f 'libnm-core/tests/nm-core-tests-enum-types.c' || echo '$(srcdir)/'`libnm-core/tests/nm-core-tests-enum-types.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_tests_test_shared_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/tests/test_shared_general-test-shared-general.o `test -f 'src/libnm-glib-aux/tests/test-shared-general.c' || echo '$(srcdir)/'`src/libnm-glib-aux/tests/test-shared-general.c -libnm-core/tests/test_general-nm-core-tests-enum-types.obj: libnm-core/tests/nm-core-tests-enum-types.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_general-nm-core-tests-enum-types.obj -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Tpo -c -o libnm-core/tests/test_general-nm-core-tests-enum-types.obj `if test -f 'libnm-core/tests/nm-core-tests-enum-types.c'; then $(CYGPATH_W) 'libnm-core/tests/nm-core-tests-enum-types.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/nm-core-tests-enum-types.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Tpo libnm-core/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/nm-core-tests-enum-types.c' object='libnm-core/tests/test_general-nm-core-tests-enum-types.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-glib-aux/tests/test_shared_general-test-shared-general.obj: src/libnm-glib-aux/tests/test-shared-general.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_tests_test_shared_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-glib-aux/tests/test_shared_general-test-shared-general.obj -MD -MP -MF src/libnm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Tpo -c -o src/libnm-glib-aux/tests/test_shared_general-test-shared-general.obj `if test -f 'src/libnm-glib-aux/tests/test-shared-general.c'; then $(CYGPATH_W) 'src/libnm-glib-aux/tests/test-shared-general.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-glib-aux/tests/test-shared-general.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Tpo src/libnm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-glib-aux/tests/test-shared-general.c' object='src/libnm-glib-aux/tests/test_shared_general-test-shared-general.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_general-nm-core-tests-enum-types.obj `if test -f 'libnm-core/tests/nm-core-tests-enum-types.c'; then $(CYGPATH_W) 'libnm-core/tests/nm-core-tests-enum-types.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/nm-core-tests-enum-types.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_glib_aux_tests_test_shared_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-glib-aux/tests/test_shared_general-test-shared-general.obj `if test -f 'src/libnm-glib-aux/tests/test-shared-general.c'; then $(CYGPATH_W) 'src/libnm-glib-aux/tests/test-shared-general.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-glib-aux/tests/test-shared-general.c'; fi` -libnm-core/tests/test_keyfile-test-keyfile.o: libnm-core/tests/test-keyfile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_keyfile-test-keyfile.o -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_keyfile-test-keyfile.Tpo -c -o libnm-core/tests/test_keyfile-test-keyfile.o `test -f 'libnm-core/tests/test-keyfile.c' || echo '$(srcdir)/'`libnm-core/tests/test-keyfile.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_keyfile-test-keyfile.Tpo libnm-core/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-keyfile.c' object='libnm-core/tests/test_keyfile-test-keyfile.o' libtool=no @AMDEPBACKSLASH@ +src/libnm-platform/tests/test_nm_platform-test-nm-platform.o: src/libnm-platform/tests/test-nm-platform.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_tests_test_nm_platform_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/tests/test_nm_platform-test-nm-platform.o -MD -MP -MF src/libnm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Tpo -c -o src/libnm-platform/tests/test_nm_platform-test-nm-platform.o `test -f 'src/libnm-platform/tests/test-nm-platform.c' || echo '$(srcdir)/'`src/libnm-platform/tests/test-nm-platform.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Tpo src/libnm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/tests/test-nm-platform.c' object='src/libnm-platform/tests/test_nm_platform-test-nm-platform.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_keyfile-test-keyfile.o `test -f 'libnm-core/tests/test-keyfile.c' || echo '$(srcdir)/'`libnm-core/tests/test-keyfile.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_tests_test_nm_platform_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/tests/test_nm_platform-test-nm-platform.o `test -f 'src/libnm-platform/tests/test-nm-platform.c' || echo '$(srcdir)/'`src/libnm-platform/tests/test-nm-platform.c -libnm-core/tests/test_keyfile-test-keyfile.obj: libnm-core/tests/test-keyfile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_keyfile-test-keyfile.obj -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_keyfile-test-keyfile.Tpo -c -o libnm-core/tests/test_keyfile-test-keyfile.obj `if test -f 'libnm-core/tests/test-keyfile.c'; then $(CYGPATH_W) 'libnm-core/tests/test-keyfile.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-keyfile.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_keyfile-test-keyfile.Tpo libnm-core/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-keyfile.c' object='libnm-core/tests/test_keyfile-test-keyfile.obj' libtool=no @AMDEPBACKSLASH@ +src/libnm-platform/tests/test_nm_platform-test-nm-platform.obj: src/libnm-platform/tests/test-nm-platform.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_tests_test_nm_platform_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnm-platform/tests/test_nm_platform-test-nm-platform.obj -MD -MP -MF src/libnm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Tpo -c -o src/libnm-platform/tests/test_nm_platform-test-nm-platform.obj `if test -f 'src/libnm-platform/tests/test-nm-platform.c'; then $(CYGPATH_W) 'src/libnm-platform/tests/test-nm-platform.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-platform/tests/test-nm-platform.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Tpo src/libnm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnm-platform/tests/test-nm-platform.c' object='src/libnm-platform/tests/test_nm_platform-test-nm-platform.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_keyfile-test-keyfile.obj `if test -f 'libnm-core/tests/test-keyfile.c'; then $(CYGPATH_W) 'libnm-core/tests/test-keyfile.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-keyfile.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnm_platform_tests_test_nm_platform_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnm-platform/tests/test_nm_platform-test-nm-platform.obj `if test -f 'src/libnm-platform/tests/test-nm-platform.c'; then $(CYGPATH_W) 'src/libnm-platform/tests/test-nm-platform.c'; else $(CYGPATH_W) '$(srcdir)/src/libnm-platform/tests/test-nm-platform.c'; fi` -libnm-core/tests/test_secrets-test-secrets.o: libnm-core/tests/test-secrets.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_secrets_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_secrets-test-secrets.o -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_secrets-test-secrets.Tpo -c -o libnm-core/tests/test_secrets-test-secrets.o `test -f 'libnm-core/tests/test-secrets.c' || echo '$(srcdir)/'`libnm-core/tests/test-secrets.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_secrets-test-secrets.Tpo libnm-core/tests/$(DEPDIR)/test_secrets-test-secrets.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-secrets.c' object='libnm-core/tests/test_secrets-test-secrets.o' libtool=no @AMDEPBACKSLASH@ +src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.o: src/libnmc-setting/tests/test-libnmc-setting.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_setting_tests_test_libnmc_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.o -MD -MP -MF src/libnmc-setting/tests/$(DEPDIR)/test_libnmc_setting-test-libnmc-setting.Tpo -c -o src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.o `test -f 'src/libnmc-setting/tests/test-libnmc-setting.c' || echo '$(srcdir)/'`src/libnmc-setting/tests/test-libnmc-setting.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmc-setting/tests/$(DEPDIR)/test_libnmc_setting-test-libnmc-setting.Tpo src/libnmc-setting/tests/$(DEPDIR)/test_libnmc_setting-test-libnmc-setting.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmc-setting/tests/test-libnmc-setting.c' object='src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_secrets_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_secrets-test-secrets.o `test -f 'libnm-core/tests/test-secrets.c' || echo '$(srcdir)/'`libnm-core/tests/test-secrets.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_setting_tests_test_libnmc_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.o `test -f 'src/libnmc-setting/tests/test-libnmc-setting.c' || echo '$(srcdir)/'`src/libnmc-setting/tests/test-libnmc-setting.c -libnm-core/tests/test_secrets-test-secrets.obj: libnm-core/tests/test-secrets.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_secrets_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_secrets-test-secrets.obj -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_secrets-test-secrets.Tpo -c -o libnm-core/tests/test_secrets-test-secrets.obj `if test -f 'libnm-core/tests/test-secrets.c'; then $(CYGPATH_W) 'libnm-core/tests/test-secrets.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-secrets.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_secrets-test-secrets.Tpo libnm-core/tests/$(DEPDIR)/test_secrets-test-secrets.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-secrets.c' object='libnm-core/tests/test_secrets-test-secrets.obj' libtool=no @AMDEPBACKSLASH@ +src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.obj: src/libnmc-setting/tests/test-libnmc-setting.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_setting_tests_test_libnmc_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.obj -MD -MP -MF src/libnmc-setting/tests/$(DEPDIR)/test_libnmc_setting-test-libnmc-setting.Tpo -c -o src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.obj `if test -f 'src/libnmc-setting/tests/test-libnmc-setting.c'; then $(CYGPATH_W) 'src/libnmc-setting/tests/test-libnmc-setting.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmc-setting/tests/test-libnmc-setting.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libnmc-setting/tests/$(DEPDIR)/test_libnmc_setting-test-libnmc-setting.Tpo src/libnmc-setting/tests/$(DEPDIR)/test_libnmc_setting-test-libnmc-setting.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libnmc-setting/tests/test-libnmc-setting.c' object='src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_secrets_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_secrets-test-secrets.obj `if test -f 'libnm-core/tests/test-secrets.c'; then $(CYGPATH_W) 'libnm-core/tests/test-secrets.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-secrets.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_libnmc_setting_tests_test_libnmc_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libnmc-setting/tests/test_libnmc_setting-test-libnmc-setting.obj `if test -f 'src/libnmc-setting/tests/test-libnmc-setting.c'; then $(CYGPATH_W) 'src/libnmc-setting/tests/test-libnmc-setting.c'; else $(CYGPATH_W) '$(srcdir)/src/libnmc-setting/tests/test-libnmc-setting.c'; fi` -libnm-core/tests/test_setting-test-setting.o: libnm-core/tests/test-setting.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_setting-test-setting.o -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_setting-test-setting.Tpo -c -o libnm-core/tests/test_setting-test-setting.o `test -f 'libnm-core/tests/test-setting.c' || echo '$(srcdir)/'`libnm-core/tests/test-setting.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_setting-test-setting.Tpo libnm-core/tests/$(DEPDIR)/test_setting-test-setting.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-setting.c' object='libnm-core/tests/test_setting-test-setting.o' libtool=no @AMDEPBACKSLASH@ +src/nm-cloud-setup/nm_cloud_setup-main.o: src/nm-cloud-setup/main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_nm_cloud_setup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/nm_cloud_setup-main.o -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Tpo -c -o src/nm-cloud-setup/nm_cloud_setup-main.o `test -f 'src/nm-cloud-setup/main.c' || echo '$(srcdir)/'`src/nm-cloud-setup/main.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Tpo src/nm-cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/main.c' object='src/nm-cloud-setup/nm_cloud_setup-main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_setting-test-setting.o `test -f 'libnm-core/tests/test-setting.c' || echo '$(srcdir)/'`libnm-core/tests/test-setting.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_nm_cloud_setup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/nm_cloud_setup-main.o `test -f 'src/nm-cloud-setup/main.c' || echo '$(srcdir)/'`src/nm-cloud-setup/main.c -libnm-core/tests/test_setting-test-setting.obj: libnm-core/tests/test-setting.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_setting-test-setting.obj -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_setting-test-setting.Tpo -c -o libnm-core/tests/test_setting-test-setting.obj `if test -f 'libnm-core/tests/test-setting.c'; then $(CYGPATH_W) 'libnm-core/tests/test-setting.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-setting.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_setting-test-setting.Tpo libnm-core/tests/$(DEPDIR)/test_setting-test-setting.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-setting.c' object='libnm-core/tests/test_setting-test-setting.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-cloud-setup/nm_cloud_setup-main.obj: src/nm-cloud-setup/main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_nm_cloud_setup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/nm_cloud_setup-main.obj -MD -MP -MF src/nm-cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Tpo -c -o src/nm-cloud-setup/nm_cloud_setup-main.obj `if test -f 'src/nm-cloud-setup/main.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/main.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/main.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Tpo src/nm-cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/main.c' object='src/nm-cloud-setup/nm_cloud_setup-main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_setting_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_setting-test-setting.obj `if test -f 'libnm-core/tests/test-setting.c'; then $(CYGPATH_W) 'libnm-core/tests/test-setting.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-setting.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_nm_cloud_setup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/nm_cloud_setup-main.obj `if test -f 'src/nm-cloud-setup/main.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/main.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/main.c'; fi` -libnm-core/tests/test_settings_defaults-test-settings-defaults.o: libnm-core/tests/test-settings-defaults.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_settings_defaults_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_settings_defaults-test-settings-defaults.o -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Tpo -c -o libnm-core/tests/test_settings_defaults-test-settings-defaults.o `test -f 'libnm-core/tests/test-settings-defaults.c' || echo '$(srcdir)/'`libnm-core/tests/test-settings-defaults.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Tpo libnm-core/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-settings-defaults.c' object='libnm-core/tests/test_settings_defaults-test-settings-defaults.o' libtool=no @AMDEPBACKSLASH@ +src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.o: src/nm-cloud-setup/tests/test-cloud-setup-general.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.o -MD -MP -MF src/nm-cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Tpo -c -o src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.o `test -f 'src/nm-cloud-setup/tests/test-cloud-setup-general.c' || echo '$(srcdir)/'`src/nm-cloud-setup/tests/test-cloud-setup-general.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Tpo src/nm-cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/tests/test-cloud-setup-general.c' object='src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_settings_defaults_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_settings_defaults-test-settings-defaults.o `test -f 'libnm-core/tests/test-settings-defaults.c' || echo '$(srcdir)/'`libnm-core/tests/test-settings-defaults.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.o `test -f 'src/nm-cloud-setup/tests/test-cloud-setup-general.c' || echo '$(srcdir)/'`src/nm-cloud-setup/tests/test-cloud-setup-general.c -libnm-core/tests/test_settings_defaults-test-settings-defaults.obj: libnm-core/tests/test-settings-defaults.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_settings_defaults_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm-core/tests/test_settings_defaults-test-settings-defaults.obj -MD -MP -MF libnm-core/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Tpo -c -o libnm-core/tests/test_settings_defaults-test-settings-defaults.obj `if test -f 'libnm-core/tests/test-settings-defaults.c'; then $(CYGPATH_W) 'libnm-core/tests/test-settings-defaults.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-settings-defaults.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm-core/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Tpo libnm-core/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm-core/tests/test-settings-defaults.c' object='libnm-core/tests/test_settings_defaults-test-settings-defaults.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.obj: src/nm-cloud-setup/tests/test-cloud-setup-general.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.obj -MD -MP -MF src/nm-cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Tpo -c -o src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.obj `if test -f 'src/nm-cloud-setup/tests/test-cloud-setup-general.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/tests/test-cloud-setup-general.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/tests/test-cloud-setup-general.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Tpo src/nm-cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-cloud-setup/tests/test-cloud-setup-general.c' object='src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_core_tests_test_settings_defaults_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm-core/tests/test_settings_defaults-test-settings-defaults.obj `if test -f 'libnm-core/tests/test-settings-defaults.c'; then $(CYGPATH_W) 'libnm-core/tests/test-settings-defaults.c'; else $(CYGPATH_W) '$(srcdir)/libnm-core/tests/test-settings-defaults.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_cloud_setup_tests_test_cloud_setup_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-cloud-setup/tests/test_cloud_setup_general-test-cloud-setup-general.obj `if test -f 'src/nm-cloud-setup/tests/test-cloud-setup-general.c'; then $(CYGPATH_W) 'src/nm-cloud-setup/tests/test-cloud-setup-general.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-cloud-setup/tests/test-cloud-setup-general.c'; fi` -shared/nm-utils/libnm_tests_test_libnm-nm-compat.o: shared/nm-utils/nm-compat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-utils/libnm_tests_test_libnm-nm-compat.o -MD -MP -MF shared/nm-utils/$(DEPDIR)/libnm_tests_test_libnm-nm-compat.Tpo -c -o shared/nm-utils/libnm_tests_test_libnm-nm-compat.o `test -f 'shared/nm-utils/nm-compat.c' || echo '$(srcdir)/'`shared/nm-utils/nm-compat.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-utils/$(DEPDIR)/libnm_tests_test_libnm-nm-compat.Tpo shared/nm-utils/$(DEPDIR)/libnm_tests_test_libnm-nm-compat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-utils/nm-compat.c' object='shared/nm-utils/libnm_tests_test_libnm-nm-compat.o' libtool=no @AMDEPBACKSLASH@ +src/nm-dispatcher/nm_dispatcher-nm-dispatcher.o: src/nm-dispatcher/nm-dispatcher.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_nm_dispatcher_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-dispatcher/nm_dispatcher-nm-dispatcher.o -MD -MP -MF src/nm-dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Tpo -c -o src/nm-dispatcher/nm_dispatcher-nm-dispatcher.o `test -f 'src/nm-dispatcher/nm-dispatcher.c' || echo '$(srcdir)/'`src/nm-dispatcher/nm-dispatcher.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Tpo src/nm-dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-dispatcher/nm-dispatcher.c' object='src/nm-dispatcher/nm_dispatcher-nm-dispatcher.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-utils/libnm_tests_test_libnm-nm-compat.o `test -f 'shared/nm-utils/nm-compat.c' || echo '$(srcdir)/'`shared/nm-utils/nm-compat.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_nm_dispatcher_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-dispatcher/nm_dispatcher-nm-dispatcher.o `test -f 'src/nm-dispatcher/nm-dispatcher.c' || echo '$(srcdir)/'`src/nm-dispatcher/nm-dispatcher.c -shared/nm-utils/libnm_tests_test_libnm-nm-compat.obj: shared/nm-utils/nm-compat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-utils/libnm_tests_test_libnm-nm-compat.obj -MD -MP -MF shared/nm-utils/$(DEPDIR)/libnm_tests_test_libnm-nm-compat.Tpo -c -o shared/nm-utils/libnm_tests_test_libnm-nm-compat.obj `if test -f 'shared/nm-utils/nm-compat.c'; then $(CYGPATH_W) 'shared/nm-utils/nm-compat.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-utils/nm-compat.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-utils/$(DEPDIR)/libnm_tests_test_libnm-nm-compat.Tpo shared/nm-utils/$(DEPDIR)/libnm_tests_test_libnm-nm-compat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-utils/nm-compat.c' object='shared/nm-utils/libnm_tests_test_libnm-nm-compat.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-dispatcher/nm_dispatcher-nm-dispatcher.obj: src/nm-dispatcher/nm-dispatcher.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_nm_dispatcher_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-dispatcher/nm_dispatcher-nm-dispatcher.obj -MD -MP -MF src/nm-dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Tpo -c -o src/nm-dispatcher/nm_dispatcher-nm-dispatcher.obj `if test -f 'src/nm-dispatcher/nm-dispatcher.c'; then $(CYGPATH_W) 'src/nm-dispatcher/nm-dispatcher.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-dispatcher/nm-dispatcher.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Tpo src/nm-dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-dispatcher/nm-dispatcher.c' object='src/nm-dispatcher/nm_dispatcher-nm-dispatcher.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-utils/libnm_tests_test_libnm-nm-compat.obj `if test -f 'shared/nm-utils/nm-compat.c'; then $(CYGPATH_W) 'shared/nm-utils/nm-compat.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-utils/nm-compat.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_nm_dispatcher_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-dispatcher/nm_dispatcher-nm-dispatcher.obj `if test -f 'src/nm-dispatcher/nm-dispatcher.c'; then $(CYGPATH_W) 'src/nm-dispatcher/nm-dispatcher.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-dispatcher/nm-dispatcher.c'; fi` -libnm/tests/test_libnm-test-libnm.o: libnm/tests/test-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/tests/test_libnm-test-libnm.o -MD -MP -MF libnm/tests/$(DEPDIR)/test_libnm-test-libnm.Tpo -c -o libnm/tests/test_libnm-test-libnm.o `test -f 'libnm/tests/test-libnm.c' || echo '$(srcdir)/'`libnm/tests/test-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/tests/$(DEPDIR)/test_libnm-test-libnm.Tpo libnm/tests/$(DEPDIR)/test_libnm-test-libnm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/tests/test-libnm.c' object='libnm/tests/test_libnm-test-libnm.o' libtool=no @AMDEPBACKSLASH@ +src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.o: src/nm-dispatcher/tests/test-dispatcher-envp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.o -MD -MP -MF src/nm-dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo -c -o src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.o `test -f 'src/nm-dispatcher/tests/test-dispatcher-envp.c' || echo '$(srcdir)/'`src/nm-dispatcher/tests/test-dispatcher-envp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo src/nm-dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-dispatcher/tests/test-dispatcher-envp.c' object='src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/tests/test_libnm-test-libnm.o `test -f 'libnm/tests/test-libnm.c' || echo '$(srcdir)/'`libnm/tests/test-libnm.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.o `test -f 'src/nm-dispatcher/tests/test-dispatcher-envp.c' || echo '$(srcdir)/'`src/nm-dispatcher/tests/test-dispatcher-envp.c -libnm/tests/test_libnm-test-libnm.obj: libnm/tests/test-libnm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/tests/test_libnm-test-libnm.obj -MD -MP -MF libnm/tests/$(DEPDIR)/test_libnm-test-libnm.Tpo -c -o libnm/tests/test_libnm-test-libnm.obj `if test -f 'libnm/tests/test-libnm.c'; then $(CYGPATH_W) 'libnm/tests/test-libnm.c'; else $(CYGPATH_W) '$(srcdir)/libnm/tests/test-libnm.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/tests/$(DEPDIR)/test_libnm-test-libnm.Tpo libnm/tests/$(DEPDIR)/test_libnm-test-libnm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/tests/test-libnm.c' object='libnm/tests/test_libnm-test-libnm.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.obj: src/nm-dispatcher/tests/test-dispatcher-envp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.obj -MD -MP -MF src/nm-dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo -c -o src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.obj `if test -f 'src/nm-dispatcher/tests/test-dispatcher-envp.c'; then $(CYGPATH_W) 'src/nm-dispatcher/tests/test-dispatcher-envp.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-dispatcher/tests/test-dispatcher-envp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Tpo src/nm-dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-dispatcher/tests/test-dispatcher-envp.c' object='src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_libnm_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/tests/test_libnm-test-libnm.obj `if test -f 'libnm/tests/test-libnm.c'; then $(CYGPATH_W) 'libnm/tests/test-libnm.c'; else $(CYGPATH_W) '$(srcdir)/libnm/tests/test-libnm.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-dispatcher/tests/test_dispatcher_envp-test-dispatcher-envp.obj `if test -f 'src/nm-dispatcher/tests/test-dispatcher-envp.c'; then $(CYGPATH_W) 'src/nm-dispatcher/tests/test-dispatcher-envp.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-dispatcher/tests/test-dispatcher-envp.c'; fi` -shared/libnm_tests_test_nm_client-nm-test-utils-impl.o: shared/nm-test-utils-impl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/libnm_tests_test_nm_client-nm-test-utils-impl.o -MD -MP -MF shared/$(DEPDIR)/libnm_tests_test_nm_client-nm-test-utils-impl.Tpo -c -o shared/libnm_tests_test_nm_client-nm-test-utils-impl.o `test -f 'shared/nm-test-utils-impl.c' || echo '$(srcdir)/'`shared/nm-test-utils-impl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/$(DEPDIR)/libnm_tests_test_nm_client-nm-test-utils-impl.Tpo shared/$(DEPDIR)/libnm_tests_test_nm_client-nm-test-utils-impl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-test-utils-impl.c' object='shared/libnm_tests_test_nm_client-nm-test-utils-impl.o' libtool=no @AMDEPBACKSLASH@ +src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.o: src/nm-dispatcher/nmdbus-dispatcher.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.o -MD -MP -MF src/nm-dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Tpo -c -o src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.o `test -f 'src/nm-dispatcher/nmdbus-dispatcher.c' || echo '$(srcdir)/'`src/nm-dispatcher/nmdbus-dispatcher.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Tpo src/nm-dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-dispatcher/nmdbus-dispatcher.c' object='src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/libnm_tests_test_nm_client-nm-test-utils-impl.o `test -f 'shared/nm-test-utils-impl.c' || echo '$(srcdir)/'`shared/nm-test-utils-impl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.o `test -f 'src/nm-dispatcher/nmdbus-dispatcher.c' || echo '$(srcdir)/'`src/nm-dispatcher/nmdbus-dispatcher.c -shared/libnm_tests_test_nm_client-nm-test-utils-impl.obj: shared/nm-test-utils-impl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/libnm_tests_test_nm_client-nm-test-utils-impl.obj -MD -MP -MF shared/$(DEPDIR)/libnm_tests_test_nm_client-nm-test-utils-impl.Tpo -c -o shared/libnm_tests_test_nm_client-nm-test-utils-impl.obj `if test -f 'shared/nm-test-utils-impl.c'; then $(CYGPATH_W) 'shared/nm-test-utils-impl.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-test-utils-impl.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/$(DEPDIR)/libnm_tests_test_nm_client-nm-test-utils-impl.Tpo shared/$(DEPDIR)/libnm_tests_test_nm_client-nm-test-utils-impl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-test-utils-impl.c' object='shared/libnm_tests_test_nm_client-nm-test-utils-impl.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.obj: src/nm-dispatcher/nmdbus-dispatcher.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.obj -MD -MP -MF src/nm-dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Tpo -c -o src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.obj `if test -f 'src/nm-dispatcher/nmdbus-dispatcher.c'; then $(CYGPATH_W) 'src/nm-dispatcher/nmdbus-dispatcher.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-dispatcher/nmdbus-dispatcher.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Tpo src/nm-dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-dispatcher/nmdbus-dispatcher.c' object='src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/libnm_tests_test_nm_client-nm-test-utils-impl.obj `if test -f 'shared/nm-test-utils-impl.c'; then $(CYGPATH_W) 'shared/nm-test-utils-impl.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-test-utils-impl.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_dispatcher_tests_test_dispatcher_envp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-dispatcher/tests_test_dispatcher_envp-nmdbus-dispatcher.obj `if test -f 'src/nm-dispatcher/nmdbus-dispatcher.c'; then $(CYGPATH_W) 'src/nm-dispatcher/nmdbus-dispatcher.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-dispatcher/nmdbus-dispatcher.c'; fi` -libnm/tests/test_nm_client-test-nm-client.o: libnm/tests/test-nm-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/tests/test_nm_client-test-nm-client.o -MD -MP -MF libnm/tests/$(DEPDIR)/test_nm_client-test-nm-client.Tpo -c -o libnm/tests/test_nm_client-test-nm-client.o `test -f 'libnm/tests/test-nm-client.c' || echo '$(srcdir)/'`libnm/tests/test-nm-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/tests/$(DEPDIR)/test_nm_client-test-nm-client.Tpo libnm/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/tests/test-nm-client.c' object='libnm/tests/test_nm_client-test-nm-client.o' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.o: src/nm-initrd-generator/nm-initrd-generator.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.o -MD -MP -MF src/nm-initrd-generator/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Tpo -c -o src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.o `test -f 'src/nm-initrd-generator/nm-initrd-generator.c' || echo '$(srcdir)/'`src/nm-initrd-generator/nm-initrd-generator.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Tpo src/nm-initrd-generator/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/nm-initrd-generator.c' object='src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/tests/test_nm_client-test-nm-client.o `test -f 'libnm/tests/test-nm-client.c' || echo '$(srcdir)/'`libnm/tests/test-nm-client.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.o `test -f 'src/nm-initrd-generator/nm-initrd-generator.c' || echo '$(srcdir)/'`src/nm-initrd-generator/nm-initrd-generator.c -libnm/tests/test_nm_client-test-nm-client.obj: libnm/tests/test-nm-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/tests/test_nm_client-test-nm-client.obj -MD -MP -MF libnm/tests/$(DEPDIR)/test_nm_client-test-nm-client.Tpo -c -o libnm/tests/test_nm_client-test-nm-client.obj `if test -f 'libnm/tests/test-nm-client.c'; then $(CYGPATH_W) 'libnm/tests/test-nm-client.c'; else $(CYGPATH_W) '$(srcdir)/libnm/tests/test-nm-client.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/tests/$(DEPDIR)/test_nm_client-test-nm-client.Tpo libnm/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/tests/test-nm-client.c' object='libnm/tests/test_nm_client-test-nm-client.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.obj: src/nm-initrd-generator/nm-initrd-generator.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.obj -MD -MP -MF src/nm-initrd-generator/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Tpo -c -o src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.obj `if test -f 'src/nm-initrd-generator/nm-initrd-generator.c'; then $(CYGPATH_W) 'src/nm-initrd-generator/nm-initrd-generator.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-initrd-generator/nm-initrd-generator.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Tpo src/nm-initrd-generator/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/nm-initrd-generator.c' object='src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_nm_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/tests/test_nm_client-test-nm-client.obj `if test -f 'libnm/tests/test-nm-client.c'; then $(CYGPATH_W) 'libnm/tests/test-nm-client.c'; else $(CYGPATH_W) '$(srcdir)/libnm/tests/test-nm-client.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/nm_initrd_generator-nm-initrd-generator.obj `if test -f 'src/nm-initrd-generator/nm-initrd-generator.c'; then $(CYGPATH_W) 'src/nm-initrd-generator/nm-initrd-generator.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-initrd-generator/nm-initrd-generator.c'; fi` -shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.o: shared/nm-test-utils-impl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.o -MD -MP -MF shared/$(DEPDIR)/libnm_tests_test_remote_settings_client-nm-test-utils-impl.Tpo -c -o shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.o `test -f 'shared/nm-test-utils-impl.c' || echo '$(srcdir)/'`shared/nm-test-utils-impl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/$(DEPDIR)/libnm_tests_test_remote_settings_client-nm-test-utils-impl.Tpo shared/$(DEPDIR)/libnm_tests_test_remote_settings_client-nm-test-utils-impl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-test-utils-impl.c' object='shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.o' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.o: src/nm-initrd-generator/tests/test-cmdline-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_cmdline_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.o -MD -MP -MF src/nm-initrd-generator/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Tpo -c -o src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.o `test -f 'src/nm-initrd-generator/tests/test-cmdline-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/tests/test-cmdline-reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Tpo src/nm-initrd-generator/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/tests/test-cmdline-reader.c' object='src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.o `test -f 'shared/nm-test-utils-impl.c' || echo '$(srcdir)/'`shared/nm-test-utils-impl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_cmdline_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.o `test -f 'src/nm-initrd-generator/tests/test-cmdline-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/tests/test-cmdline-reader.c -shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.obj: shared/nm-test-utils-impl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.obj -MD -MP -MF shared/$(DEPDIR)/libnm_tests_test_remote_settings_client-nm-test-utils-impl.Tpo -c -o shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.obj `if test -f 'shared/nm-test-utils-impl.c'; then $(CYGPATH_W) 'shared/nm-test-utils-impl.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-test-utils-impl.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/$(DEPDIR)/libnm_tests_test_remote_settings_client-nm-test-utils-impl.Tpo shared/$(DEPDIR)/libnm_tests_test_remote_settings_client-nm-test-utils-impl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-test-utils-impl.c' object='shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.obj: src/nm-initrd-generator/tests/test-cmdline-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_cmdline_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.obj -MD -MP -MF src/nm-initrd-generator/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Tpo -c -o src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.obj `if test -f 'src/nm-initrd-generator/tests/test-cmdline-reader.c'; then $(CYGPATH_W) 'src/nm-initrd-generator/tests/test-cmdline-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-initrd-generator/tests/test-cmdline-reader.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Tpo src/nm-initrd-generator/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/tests/test-cmdline-reader.c' object='src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/libnm_tests_test_remote_settings_client-nm-test-utils-impl.obj `if test -f 'shared/nm-test-utils-impl.c'; then $(CYGPATH_W) 'shared/nm-test-utils-impl.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-test-utils-impl.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_cmdline_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/tests/test_cmdline_reader-test-cmdline-reader.obj `if test -f 'src/nm-initrd-generator/tests/test-cmdline-reader.c'; then $(CYGPATH_W) 'src/nm-initrd-generator/tests/test-cmdline-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-initrd-generator/tests/test-cmdline-reader.c'; fi` -libnm/tests/test_remote_settings_client-test-remote-settings-client.o: libnm/tests/test-remote-settings-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/tests/test_remote_settings_client-test-remote-settings-client.o -MD -MP -MF libnm/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo -c -o libnm/tests/test_remote_settings_client-test-remote-settings-client.o `test -f 'libnm/tests/test-remote-settings-client.c' || echo '$(srcdir)/'`libnm/tests/test-remote-settings-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo libnm/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/tests/test-remote-settings-client.c' object='libnm/tests/test_remote_settings_client-test-remote-settings-client.o' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.o: src/nm-initrd-generator/tests/test-dt-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_dt_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.o -MD -MP -MF src/nm-initrd-generator/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Tpo -c -o src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.o `test -f 'src/nm-initrd-generator/tests/test-dt-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/tests/test-dt-reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Tpo src/nm-initrd-generator/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/tests/test-dt-reader.c' object='src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/tests/test_remote_settings_client-test-remote-settings-client.o `test -f 'libnm/tests/test-remote-settings-client.c' || echo '$(srcdir)/'`libnm/tests/test-remote-settings-client.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_dt_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.o `test -f 'src/nm-initrd-generator/tests/test-dt-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/tests/test-dt-reader.c -libnm/tests/test_remote_settings_client-test-remote-settings-client.obj: libnm/tests/test-remote-settings-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/tests/test_remote_settings_client-test-remote-settings-client.obj -MD -MP -MF libnm/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo -c -o libnm/tests/test_remote_settings_client-test-remote-settings-client.obj `if test -f 'libnm/tests/test-remote-settings-client.c'; then $(CYGPATH_W) 'libnm/tests/test-remote-settings-client.c'; else $(CYGPATH_W) '$(srcdir)/libnm/tests/test-remote-settings-client.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo libnm/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/tests/test-remote-settings-client.c' object='libnm/tests/test_remote_settings_client-test-remote-settings-client.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.obj: src/nm-initrd-generator/tests/test-dt-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_dt_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.obj -MD -MP -MF src/nm-initrd-generator/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Tpo -c -o src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.obj `if test -f 'src/nm-initrd-generator/tests/test-dt-reader.c'; then $(CYGPATH_W) 'src/nm-initrd-generator/tests/test-dt-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-initrd-generator/tests/test-dt-reader.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Tpo src/nm-initrd-generator/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/tests/test-dt-reader.c' object='src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/tests/test_remote_settings_client-test-remote-settings-client.obj `if test -f 'libnm/tests/test-remote-settings-client.c'; then $(CYGPATH_W) 'libnm/tests/test-remote-settings-client.c'; else $(CYGPATH_W) '$(srcdir)/libnm/tests/test-remote-settings-client.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_dt_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/tests/test_dt_reader-test-dt-reader.obj `if test -f 'src/nm-initrd-generator/tests/test-dt-reader.c'; then $(CYGPATH_W) 'src/nm-initrd-generator/tests/test-dt-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-initrd-generator/tests/test-dt-reader.c'; fi` -shared/libnm_tests_test_secret_agent-nm-test-utils-impl.o: shared/nm-test-utils-impl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/libnm_tests_test_secret_agent-nm-test-utils-impl.o -MD -MP -MF shared/$(DEPDIR)/libnm_tests_test_secret_agent-nm-test-utils-impl.Tpo -c -o shared/libnm_tests_test_secret_agent-nm-test-utils-impl.o `test -f 'shared/nm-test-utils-impl.c' || echo '$(srcdir)/'`shared/nm-test-utils-impl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/$(DEPDIR)/libnm_tests_test_secret_agent-nm-test-utils-impl.Tpo shared/$(DEPDIR)/libnm_tests_test_secret_agent-nm-test-utils-impl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-test-utils-impl.c' object='shared/libnm_tests_test_secret_agent-nm-test-utils-impl.o' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.o: src/nm-initrd-generator/tests/test-ibft-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_ibft_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.o -MD -MP -MF src/nm-initrd-generator/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Tpo -c -o src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.o `test -f 'src/nm-initrd-generator/tests/test-ibft-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/tests/test-ibft-reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Tpo src/nm-initrd-generator/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/tests/test-ibft-reader.c' object='src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/libnm_tests_test_secret_agent-nm-test-utils-impl.o `test -f 'shared/nm-test-utils-impl.c' || echo '$(srcdir)/'`shared/nm-test-utils-impl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_ibft_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.o `test -f 'src/nm-initrd-generator/tests/test-ibft-reader.c' || echo '$(srcdir)/'`src/nm-initrd-generator/tests/test-ibft-reader.c -shared/libnm_tests_test_secret_agent-nm-test-utils-impl.obj: shared/nm-test-utils-impl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/libnm_tests_test_secret_agent-nm-test-utils-impl.obj -MD -MP -MF shared/$(DEPDIR)/libnm_tests_test_secret_agent-nm-test-utils-impl.Tpo -c -o shared/libnm_tests_test_secret_agent-nm-test-utils-impl.obj `if test -f 'shared/nm-test-utils-impl.c'; then $(CYGPATH_W) 'shared/nm-test-utils-impl.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-test-utils-impl.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/$(DEPDIR)/libnm_tests_test_secret_agent-nm-test-utils-impl.Tpo shared/$(DEPDIR)/libnm_tests_test_secret_agent-nm-test-utils-impl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-test-utils-impl.c' object='shared/libnm_tests_test_secret_agent-nm-test-utils-impl.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.obj: src/nm-initrd-generator/tests/test-ibft-reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_ibft_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.obj -MD -MP -MF src/nm-initrd-generator/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Tpo -c -o src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.obj `if test -f 'src/nm-initrd-generator/tests/test-ibft-reader.c'; then $(CYGPATH_W) 'src/nm-initrd-generator/tests/test-ibft-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-initrd-generator/tests/test-ibft-reader.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-initrd-generator/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Tpo src/nm-initrd-generator/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-initrd-generator/tests/test-ibft-reader.c' object='src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/libnm_tests_test_secret_agent-nm-test-utils-impl.obj `if test -f 'shared/nm-test-utils-impl.c'; then $(CYGPATH_W) 'shared/nm-test-utils-impl.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-test-utils-impl.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_initrd_generator_tests_test_ibft_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-initrd-generator/tests/test_ibft_reader-test-ibft-reader.obj `if test -f 'src/nm-initrd-generator/tests/test-ibft-reader.c'; then $(CYGPATH_W) 'src/nm-initrd-generator/tests/test-ibft-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-initrd-generator/tests/test-ibft-reader.c'; fi` -libnm/tests/test_secret_agent-test-secret-agent.o: libnm/tests/test-secret-agent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/tests/test_secret_agent-test-secret-agent.o -MD -MP -MF libnm/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Tpo -c -o libnm/tests/test_secret_agent-test-secret-agent.o `test -f 'libnm/tests/test-secret-agent.c' || echo '$(srcdir)/'`libnm/tests/test-secret-agent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Tpo libnm/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/tests/test-secret-agent.c' object='libnm/tests/test_secret_agent-test-secret-agent.o' libtool=no @AMDEPBACKSLASH@ +src/nm-online/nm_online-nm-online.o: src/nm-online/nm-online.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_online_nm_online_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-online/nm_online-nm-online.o -MD -MP -MF src/nm-online/$(DEPDIR)/nm_online-nm-online.Tpo -c -o src/nm-online/nm_online-nm-online.o `test -f 'src/nm-online/nm-online.c' || echo '$(srcdir)/'`src/nm-online/nm-online.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-online/$(DEPDIR)/nm_online-nm-online.Tpo src/nm-online/$(DEPDIR)/nm_online-nm-online.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-online/nm-online.c' object='src/nm-online/nm_online-nm-online.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/tests/test_secret_agent-test-secret-agent.o `test -f 'libnm/tests/test-secret-agent.c' || echo '$(srcdir)/'`libnm/tests/test-secret-agent.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_online_nm_online_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-online/nm_online-nm-online.o `test -f 'src/nm-online/nm-online.c' || echo '$(srcdir)/'`src/nm-online/nm-online.c -libnm/tests/test_secret_agent-test-secret-agent.obj: libnm/tests/test-secret-agent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm/tests/test_secret_agent-test-secret-agent.obj -MD -MP -MF libnm/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Tpo -c -o libnm/tests/test_secret_agent-test-secret-agent.obj `if test -f 'libnm/tests/test-secret-agent.c'; then $(CYGPATH_W) 'libnm/tests/test-secret-agent.c'; else $(CYGPATH_W) '$(srcdir)/libnm/tests/test-secret-agent.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libnm/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Tpo libnm/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libnm/tests/test-secret-agent.c' object='libnm/tests/test_secret_agent-test-secret-agent.obj' libtool=no @AMDEPBACKSLASH@ +src/nm-online/nm_online-nm-online.obj: src/nm-online/nm-online.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_online_nm_online_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nm-online/nm_online-nm-online.obj -MD -MP -MF src/nm-online/$(DEPDIR)/nm_online-nm-online.Tpo -c -o src/nm-online/nm_online-nm-online.obj `if test -f 'src/nm-online/nm-online.c'; then $(CYGPATH_W) 'src/nm-online/nm-online.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-online/nm-online.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nm-online/$(DEPDIR)/nm_online-nm-online.Tpo src/nm-online/$(DEPDIR)/nm_online-nm-online.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nm-online/nm-online.c' object='src/nm-online/nm_online-nm-online.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_tests_test_secret_agent_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm/tests/test_secret_agent-test-secret-agent.obj `if test -f 'libnm/tests/test-secret-agent.c'; then $(CYGPATH_W) 'libnm/tests/test-secret-agent.c'; else $(CYGPATH_W) '$(srcdir)/libnm/tests/test-secret-agent.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nm_online_nm_online_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nm-online/nm_online-nm-online.obj `if test -f 'src/nm-online/nm-online.c'; then $(CYGPATH_W) 'src/nm-online/nm-online.c'; else $(CYGPATH_W) '$(srcdir)/src/nm-online/nm-online.c'; fi` -shared/nm-glib-aux/tests/test_json_aux-test-json-aux.o: shared/nm-glib-aux/tests/test-json-aux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_tests_test_json_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/tests/test_json_aux-test-json-aux.o -MD -MP -MF shared/nm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Tpo -c -o shared/nm-glib-aux/tests/test_json_aux-test-json-aux.o `test -f 'shared/nm-glib-aux/tests/test-json-aux.c' || echo '$(srcdir)/'`shared/nm-glib-aux/tests/test-json-aux.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Tpo shared/nm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/tests/test-json-aux.c' object='shared/nm-glib-aux/tests/test_json_aux-test-json-aux.o' libtool=no @AMDEPBACKSLASH@ +src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.o: src/nmcli/generate-docs-nm-settings-nmcli.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_generate_docs_nm_settings_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.o -MD -MP -MF src/nmcli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Tpo -c -o src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.o `test -f 'src/nmcli/generate-docs-nm-settings-nmcli.c' || echo '$(srcdir)/'`src/nmcli/generate-docs-nm-settings-nmcli.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Tpo src/nmcli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/generate-docs-nm-settings-nmcli.c' object='src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_tests_test_json_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/tests/test_json_aux-test-json-aux.o `test -f 'shared/nm-glib-aux/tests/test-json-aux.c' || echo '$(srcdir)/'`shared/nm-glib-aux/tests/test-json-aux.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_generate_docs_nm_settings_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.o `test -f 'src/nmcli/generate-docs-nm-settings-nmcli.c' || echo '$(srcdir)/'`src/nmcli/generate-docs-nm-settings-nmcli.c -shared/nm-glib-aux/tests/test_json_aux-test-json-aux.obj: shared/nm-glib-aux/tests/test-json-aux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_tests_test_json_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/tests/test_json_aux-test-json-aux.obj -MD -MP -MF shared/nm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Tpo -c -o shared/nm-glib-aux/tests/test_json_aux-test-json-aux.obj `if test -f 'shared/nm-glib-aux/tests/test-json-aux.c'; then $(CYGPATH_W) 'shared/nm-glib-aux/tests/test-json-aux.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-glib-aux/tests/test-json-aux.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Tpo shared/nm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/tests/test-json-aux.c' object='shared/nm-glib-aux/tests/test_json_aux-test-json-aux.obj' libtool=no @AMDEPBACKSLASH@ +src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.obj: src/nmcli/generate-docs-nm-settings-nmcli.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_generate_docs_nm_settings_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.obj -MD -MP -MF src/nmcli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Tpo -c -o src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.obj `if test -f 'src/nmcli/generate-docs-nm-settings-nmcli.c'; then $(CYGPATH_W) 'src/nmcli/generate-docs-nm-settings-nmcli.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/generate-docs-nm-settings-nmcli.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Tpo src/nmcli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/generate-docs-nm-settings-nmcli.c' object='src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_tests_test_json_aux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/tests/test_json_aux-test-json-aux.obj `if test -f 'shared/nm-glib-aux/tests/test-json-aux.c'; then $(CYGPATH_W) 'shared/nm-glib-aux/tests/test-json-aux.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-glib-aux/tests/test-json-aux.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_generate_docs_nm_settings_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.obj `if test -f 'src/nmcli/generate-docs-nm-settings-nmcli.c'; then $(CYGPATH_W) 'src/nmcli/generate-docs-nm-settings-nmcli.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/generate-docs-nm-settings-nmcli.c'; fi` -shared/nm-glib-aux/tests/test_shared_general-test-shared-general.o: shared/nm-glib-aux/tests/test-shared-general.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_tests_test_shared_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/tests/test_shared_general-test-shared-general.o -MD -MP -MF shared/nm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Tpo -c -o shared/nm-glib-aux/tests/test_shared_general-test-shared-general.o `test -f 'shared/nm-glib-aux/tests/test-shared-general.c' || echo '$(srcdir)/'`shared/nm-glib-aux/tests/test-shared-general.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Tpo shared/nm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/tests/test-shared-general.c' object='shared/nm-glib-aux/tests/test_shared_general-test-shared-general.o' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-common.o: src/nmcli/common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-common.o -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-common.Tpo -c -o src/nmcli/nmcli-common.o `test -f 'src/nmcli/common.c' || echo '$(srcdir)/'`src/nmcli/common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-common.Tpo src/nmcli/$(DEPDIR)/nmcli-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/common.c' object='src/nmcli/nmcli-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_tests_test_shared_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/tests/test_shared_general-test-shared-general.o `test -f 'shared/nm-glib-aux/tests/test-shared-general.c' || echo '$(srcdir)/'`shared/nm-glib-aux/tests/test-shared-general.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-common.o `test -f 'src/nmcli/common.c' || echo '$(srcdir)/'`src/nmcli/common.c -shared/nm-glib-aux/tests/test_shared_general-test-shared-general.obj: shared/nm-glib-aux/tests/test-shared-general.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_tests_test_shared_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-glib-aux/tests/test_shared_general-test-shared-general.obj -MD -MP -MF shared/nm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Tpo -c -o shared/nm-glib-aux/tests/test_shared_general-test-shared-general.obj `if test -f 'shared/nm-glib-aux/tests/test-shared-general.c'; then $(CYGPATH_W) 'shared/nm-glib-aux/tests/test-shared-general.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-glib-aux/tests/test-shared-general.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Tpo shared/nm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-glib-aux/tests/test-shared-general.c' object='shared/nm-glib-aux/tests/test_shared_general-test-shared-general.obj' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-common.obj: src/nmcli/common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-common.obj -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-common.Tpo -c -o src/nmcli/nmcli-common.obj `if test -f 'src/nmcli/common.c'; then $(CYGPATH_W) 'src/nmcli/common.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-common.Tpo src/nmcli/$(DEPDIR)/nmcli-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/common.c' object='src/nmcli/nmcli-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_glib_aux_tests_test_shared_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-glib-aux/tests/test_shared_general-test-shared-general.obj `if test -f 'shared/nm-glib-aux/tests/test-shared-general.c'; then $(CYGPATH_W) 'shared/nm-glib-aux/tests/test-shared-general.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-glib-aux/tests/test-shared-general.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-common.obj `if test -f 'src/nmcli/common.c'; then $(CYGPATH_W) 'src/nmcli/common.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/common.c'; fi` -shared/nm-platform/tests/test_nm_platform-test-nm-platform.o: shared/nm-platform/tests/test-nm-platform.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_platform_tests_test_nm_platform_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-platform/tests/test_nm_platform-test-nm-platform.o -MD -MP -MF shared/nm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Tpo -c -o shared/nm-platform/tests/test_nm_platform-test-nm-platform.o `test -f 'shared/nm-platform/tests/test-nm-platform.c' || echo '$(srcdir)/'`shared/nm-platform/tests/test-nm-platform.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Tpo shared/nm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-platform/tests/test-nm-platform.c' object='shared/nm-platform/tests/test_nm_platform-test-nm-platform.o' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-utils.o: src/nmcli/utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-utils.o -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-utils.Tpo -c -o src/nmcli/nmcli-utils.o `test -f 'src/nmcli/utils.c' || echo '$(srcdir)/'`src/nmcli/utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-utils.Tpo src/nmcli/$(DEPDIR)/nmcli-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/utils.c' object='src/nmcli/nmcli-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_platform_tests_test_nm_platform_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-platform/tests/test_nm_platform-test-nm-platform.o `test -f 'shared/nm-platform/tests/test-nm-platform.c' || echo '$(srcdir)/'`shared/nm-platform/tests/test-nm-platform.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-utils.o `test -f 'src/nmcli/utils.c' || echo '$(srcdir)/'`src/nmcli/utils.c -shared/nm-platform/tests/test_nm_platform-test-nm-platform.obj: shared/nm-platform/tests/test-nm-platform.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_platform_tests_test_nm_platform_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared/nm-platform/tests/test_nm_platform-test-nm-platform.obj -MD -MP -MF shared/nm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Tpo -c -o shared/nm-platform/tests/test_nm_platform-test-nm-platform.obj `if test -f 'shared/nm-platform/tests/test-nm-platform.c'; then $(CYGPATH_W) 'shared/nm-platform/tests/test-nm-platform.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-platform/tests/test-nm-platform.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) shared/nm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Tpo shared/nm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shared/nm-platform/tests/test-nm-platform.c' object='shared/nm-platform/tests/test_nm_platform-test-nm-platform.obj' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-utils.obj: src/nmcli/utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-utils.obj -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-utils.Tpo -c -o src/nmcli/nmcli-utils.obj `if test -f 'src/nmcli/utils.c'; then $(CYGPATH_W) 'src/nmcli/utils.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-utils.Tpo src/nmcli/$(DEPDIR)/nmcli-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/utils.c' object='src/nmcli/nmcli-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(shared_nm_platform_tests_test_nm_platform_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared/nm-platform/tests/test_nm_platform-test-nm-platform.obj `if test -f 'shared/nm-platform/tests/test-nm-platform.c'; then $(CYGPATH_W) 'shared/nm-platform/tests/test-nm-platform.c'; else $(CYGPATH_W) '$(srcdir)/shared/nm-platform/tests/test-nm-platform.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-utils.obj `if test -f 'src/nmcli/utils.c'; then $(CYGPATH_W) 'src/nmcli/utils.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/utils.c'; fi` -src/core/NetworkManager-main.o: src/core/main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/NetworkManager-main.o -MD -MP -MF src/core/$(DEPDIR)/NetworkManager-main.Tpo -c -o src/core/NetworkManager-main.o `test -f 'src/core/main.c' || echo '$(srcdir)/'`src/core/main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/NetworkManager-main.Tpo src/core/$(DEPDIR)/NetworkManager-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/main.c' object='src/core/NetworkManager-main.o' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-agent.o: src/nmcli/agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-agent.o -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-agent.Tpo -c -o src/nmcli/nmcli-agent.o `test -f 'src/nmcli/agent.c' || echo '$(srcdir)/'`src/nmcli/agent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-agent.Tpo src/nmcli/$(DEPDIR)/nmcli-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/agent.c' object='src/nmcli/nmcli-agent.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/NetworkManager-main.o `test -f 'src/core/main.c' || echo '$(srcdir)/'`src/core/main.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-agent.o `test -f 'src/nmcli/agent.c' || echo '$(srcdir)/'`src/nmcli/agent.c -src/core/NetworkManager-main.obj: src/core/main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/NetworkManager-main.obj -MD -MP -MF src/core/$(DEPDIR)/NetworkManager-main.Tpo -c -o src/core/NetworkManager-main.obj `if test -f 'src/core/main.c'; then $(CYGPATH_W) 'src/core/main.c'; else $(CYGPATH_W) '$(srcdir)/src/core/main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/NetworkManager-main.Tpo src/core/$(DEPDIR)/NetworkManager-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/main.c' object='src/core/NetworkManager-main.obj' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-agent.obj: src/nmcli/agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-agent.obj -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-agent.Tpo -c -o src/nmcli/nmcli-agent.obj `if test -f 'src/nmcli/agent.c'; then $(CYGPATH_W) 'src/nmcli/agent.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/agent.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-agent.Tpo src/nmcli/$(DEPDIR)/nmcli-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/agent.c' object='src/nmcli/nmcli-agent.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/NetworkManager-main.obj `if test -f 'src/core/main.c'; then $(CYGPATH_W) 'src/core/main.c'; else $(CYGPATH_W) '$(srcdir)/src/core/main.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-agent.obj `if test -f 'src/nmcli/agent.c'; then $(CYGPATH_W) 'src/nmcli/agent.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/agent.c'; fi` -src/core/NetworkManager_all_sym-main.o: src/core/main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_all_sym_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/NetworkManager_all_sym-main.o -MD -MP -MF src/core/$(DEPDIR)/NetworkManager_all_sym-main.Tpo -c -o src/core/NetworkManager_all_sym-main.o `test -f 'src/core/main.c' || echo '$(srcdir)/'`src/core/main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/NetworkManager_all_sym-main.Tpo src/core/$(DEPDIR)/NetworkManager_all_sym-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/main.c' object='src/core/NetworkManager_all_sym-main.o' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-general.o: src/nmcli/general.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-general.o -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-general.Tpo -c -o src/nmcli/nmcli-general.o `test -f 'src/nmcli/general.c' || echo '$(srcdir)/'`src/nmcli/general.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-general.Tpo src/nmcli/$(DEPDIR)/nmcli-general.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/general.c' object='src/nmcli/nmcli-general.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_all_sym_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/NetworkManager_all_sym-main.o `test -f 'src/core/main.c' || echo '$(srcdir)/'`src/core/main.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-general.o `test -f 'src/nmcli/general.c' || echo '$(srcdir)/'`src/nmcli/general.c -src/core/NetworkManager_all_sym-main.obj: src/core/main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_all_sym_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/NetworkManager_all_sym-main.obj -MD -MP -MF src/core/$(DEPDIR)/NetworkManager_all_sym-main.Tpo -c -o src/core/NetworkManager_all_sym-main.obj `if test -f 'src/core/main.c'; then $(CYGPATH_W) 'src/core/main.c'; else $(CYGPATH_W) '$(srcdir)/src/core/main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/NetworkManager_all_sym-main.Tpo src/core/$(DEPDIR)/NetworkManager_all_sym-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/main.c' object='src/core/NetworkManager_all_sym-main.obj' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-general.obj: src/nmcli/general.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-general.obj -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-general.Tpo -c -o src/nmcli/nmcli-general.obj `if test -f 'src/nmcli/general.c'; then $(CYGPATH_W) 'src/nmcli/general.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/general.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-general.Tpo src/nmcli/$(DEPDIR)/nmcli-general.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/general.c' object='src/nmcli/nmcli-general.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_NetworkManager_all_sym_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/NetworkManager_all_sym-main.obj `if test -f 'src/core/main.c'; then $(CYGPATH_W) 'src/core/main.c'; else $(CYGPATH_W) '$(srcdir)/src/core/main.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-general.obj `if test -f 'src/nmcli/general.c'; then $(CYGPATH_W) 'src/nmcli/general.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/general.c'; fi` -src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.o: src/core/devices/bluetooth/tests/nm-bt-test.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_tests_nm_bt_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.o -MD -MP -MF src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Tpo -c -o src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.o `test -f 'src/core/devices/bluetooth/tests/nm-bt-test.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/tests/nm-bt-test.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Tpo src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/tests/nm-bt-test.c' object='src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.o' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-connections.o: src/nmcli/connections.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-connections.o -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-connections.Tpo -c -o src/nmcli/nmcli-connections.o `test -f 'src/nmcli/connections.c' || echo '$(srcdir)/'`src/nmcli/connections.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-connections.Tpo src/nmcli/$(DEPDIR)/nmcli-connections.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/connections.c' object='src/nmcli/nmcli-connections.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_tests_nm_bt_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.o `test -f 'src/core/devices/bluetooth/tests/nm-bt-test.c' || echo '$(srcdir)/'`src/core/devices/bluetooth/tests/nm-bt-test.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-connections.o `test -f 'src/nmcli/connections.c' || echo '$(srcdir)/'`src/nmcli/connections.c -src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.obj: src/core/devices/bluetooth/tests/nm-bt-test.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_tests_nm_bt_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.obj -MD -MP -MF src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Tpo -c -o src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.obj `if test -f 'src/core/devices/bluetooth/tests/nm-bt-test.c'; then $(CYGPATH_W) 'src/core/devices/bluetooth/tests/nm-bt-test.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/bluetooth/tests/nm-bt-test.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Tpo src/core/devices/bluetooth/tests/$(DEPDIR)/nm_bt_test-nm-bt-test.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/bluetooth/tests/nm-bt-test.c' object='src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.obj' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-connections.obj: src/nmcli/connections.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-connections.obj -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-connections.Tpo -c -o src/nmcli/nmcli-connections.obj `if test -f 'src/nmcli/connections.c'; then $(CYGPATH_W) 'src/nmcli/connections.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/connections.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-connections.Tpo src/nmcli/$(DEPDIR)/nmcli-connections.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/connections.c' object='src/nmcli/nmcli-connections.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_bluetooth_tests_nm_bt_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/bluetooth/tests/nm_bt_test-nm-bt-test.obj `if test -f 'src/core/devices/bluetooth/tests/nm-bt-test.c'; then $(CYGPATH_W) 'src/core/devices/bluetooth/tests/nm-bt-test.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/bluetooth/tests/nm-bt-test.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-connections.obj `if test -f 'src/nmcli/connections.c'; then $(CYGPATH_W) 'src/nmcli/connections.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/connections.c'; fi` -src/core/devices/tests/test_acd-test-acd.o: src/core/devices/tests/test-acd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_acd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/tests/test_acd-test-acd.o -MD -MP -MF src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Tpo -c -o src/core/devices/tests/test_acd-test-acd.o `test -f 'src/core/devices/tests/test-acd.c' || echo '$(srcdir)/'`src/core/devices/tests/test-acd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Tpo src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/tests/test-acd.c' object='src/core/devices/tests/test_acd-test-acd.o' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-devices.o: src/nmcli/devices.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-devices.o -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-devices.Tpo -c -o src/nmcli/nmcli-devices.o `test -f 'src/nmcli/devices.c' || echo '$(srcdir)/'`src/nmcli/devices.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-devices.Tpo src/nmcli/$(DEPDIR)/nmcli-devices.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/devices.c' object='src/nmcli/nmcli-devices.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_acd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/tests/test_acd-test-acd.o `test -f 'src/core/devices/tests/test-acd.c' || echo '$(srcdir)/'`src/core/devices/tests/test-acd.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-devices.o `test -f 'src/nmcli/devices.c' || echo '$(srcdir)/'`src/nmcli/devices.c -src/core/devices/tests/test_acd-test-acd.obj: src/core/devices/tests/test-acd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_acd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/tests/test_acd-test-acd.obj -MD -MP -MF src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Tpo -c -o src/core/devices/tests/test_acd-test-acd.obj `if test -f 'src/core/devices/tests/test-acd.c'; then $(CYGPATH_W) 'src/core/devices/tests/test-acd.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/tests/test-acd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Tpo src/core/devices/tests/$(DEPDIR)/test_acd-test-acd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/tests/test-acd.c' object='src/core/devices/tests/test_acd-test-acd.obj' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-devices.obj: src/nmcli/devices.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-devices.obj -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-devices.Tpo -c -o src/nmcli/nmcli-devices.obj `if test -f 'src/nmcli/devices.c'; then $(CYGPATH_W) 'src/nmcli/devices.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/devices.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-devices.Tpo src/nmcli/$(DEPDIR)/nmcli-devices.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/devices.c' object='src/nmcli/nmcli-devices.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_acd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/tests/test_acd-test-acd.obj `if test -f 'src/core/devices/tests/test-acd.c'; then $(CYGPATH_W) 'src/core/devices/tests/test-acd.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/tests/test-acd.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-devices.obj `if test -f 'src/nmcli/devices.c'; then $(CYGPATH_W) 'src/nmcli/devices.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/devices.c'; fi` -src/core/devices/tests/test_lldp-test-lldp.o: src/core/devices/tests/test-lldp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_lldp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/tests/test_lldp-test-lldp.o -MD -MP -MF src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Tpo -c -o src/core/devices/tests/test_lldp-test-lldp.o `test -f 'src/core/devices/tests/test-lldp.c' || echo '$(srcdir)/'`src/core/devices/tests/test-lldp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Tpo src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/tests/test-lldp.c' object='src/core/devices/tests/test_lldp-test-lldp.o' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-settings.o: src/nmcli/settings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-settings.o -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-settings.Tpo -c -o src/nmcli/nmcli-settings.o `test -f 'src/nmcli/settings.c' || echo '$(srcdir)/'`src/nmcli/settings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-settings.Tpo src/nmcli/$(DEPDIR)/nmcli-settings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/settings.c' object='src/nmcli/nmcli-settings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_lldp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/tests/test_lldp-test-lldp.o `test -f 'src/core/devices/tests/test-lldp.c' || echo '$(srcdir)/'`src/core/devices/tests/test-lldp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-settings.o `test -f 'src/nmcli/settings.c' || echo '$(srcdir)/'`src/nmcli/settings.c -src/core/devices/tests/test_lldp-test-lldp.obj: src/core/devices/tests/test-lldp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_lldp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/tests/test_lldp-test-lldp.obj -MD -MP -MF src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Tpo -c -o src/core/devices/tests/test_lldp-test-lldp.obj `if test -f 'src/core/devices/tests/test-lldp.c'; then $(CYGPATH_W) 'src/core/devices/tests/test-lldp.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/tests/test-lldp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Tpo src/core/devices/tests/$(DEPDIR)/test_lldp-test-lldp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/tests/test-lldp.c' object='src/core/devices/tests/test_lldp-test-lldp.obj' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-settings.obj: src/nmcli/settings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-settings.obj -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-settings.Tpo -c -o src/nmcli/nmcli-settings.obj `if test -f 'src/nmcli/settings.c'; then $(CYGPATH_W) 'src/nmcli/settings.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/settings.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-settings.Tpo src/nmcli/$(DEPDIR)/nmcli-settings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/settings.c' object='src/nmcli/nmcli-settings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_tests_test_lldp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/tests/test_lldp-test-lldp.obj `if test -f 'src/core/devices/tests/test-lldp.c'; then $(CYGPATH_W) 'src/core/devices/tests/test-lldp.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/tests/test-lldp.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-settings.obj `if test -f 'src/nmcli/settings.c'; then $(CYGPATH_W) 'src/nmcli/settings.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/settings.c'; fi` -src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.o: src/core/devices/wifi/tests/test-devices-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_tests_test_devices_wifi_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.o -MD -MP -MF src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Tpo -c -o src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.o `test -f 'src/core/devices/wifi/tests/test-devices-wifi.c' || echo '$(srcdir)/'`src/core/devices/wifi/tests/test-devices-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Tpo src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/tests/test-devices-wifi.c' object='src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.o' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-nmcli.o: src/nmcli/nmcli.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-nmcli.o -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-nmcli.Tpo -c -o src/nmcli/nmcli-nmcli.o `test -f 'src/nmcli/nmcli.c' || echo '$(srcdir)/'`src/nmcli/nmcli.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-nmcli.Tpo src/nmcli/$(DEPDIR)/nmcli-nmcli.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/nmcli.c' object='src/nmcli/nmcli-nmcli.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_tests_test_devices_wifi_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.o `test -f 'src/core/devices/wifi/tests/test-devices-wifi.c' || echo '$(srcdir)/'`src/core/devices/wifi/tests/test-devices-wifi.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-nmcli.o `test -f 'src/nmcli/nmcli.c' || echo '$(srcdir)/'`src/nmcli/nmcli.c -src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.obj: src/core/devices/wifi/tests/test-devices-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_tests_test_devices_wifi_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.obj -MD -MP -MF src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Tpo -c -o src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.obj `if test -f 'src/core/devices/wifi/tests/test-devices-wifi.c'; then $(CYGPATH_W) 'src/core/devices/wifi/tests/test-devices-wifi.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wifi/tests/test-devices-wifi.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Tpo src/core/devices/wifi/tests/$(DEPDIR)/test_devices_wifi-test-devices-wifi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wifi/tests/test-devices-wifi.c' object='src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.obj' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-nmcli.obj: src/nmcli/nmcli.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-nmcli.obj -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-nmcli.Tpo -c -o src/nmcli/nmcli-nmcli.obj `if test -f 'src/nmcli/nmcli.c'; then $(CYGPATH_W) 'src/nmcli/nmcli.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/nmcli.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-nmcli.Tpo src/nmcli/$(DEPDIR)/nmcli-nmcli.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/nmcli.c' object='src/nmcli/nmcli-nmcli.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wifi_tests_test_devices_wifi_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wifi/tests/test_devices_wifi-test-devices-wifi.obj `if test -f 'src/core/devices/wifi/tests/test-devices-wifi.c'; then $(CYGPATH_W) 'src/core/devices/wifi/tests/test-devices-wifi.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wifi/tests/test-devices-wifi.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-nmcli.obj `if test -f 'src/nmcli/nmcli.c'; then $(CYGPATH_W) 'src/nmcli/nmcli.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/nmcli.c'; fi` -src/core/devices/wwan/tests/test_service_providers-test-service-providers.o: src/core/devices/wwan/tests/test-service-providers.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/tests/test_service_providers-test-service-providers.o -MD -MP -MF src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Tpo -c -o src/core/devices/wwan/tests/test_service_providers-test-service-providers.o `test -f 'src/core/devices/wwan/tests/test-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/tests/test-service-providers.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Tpo src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/tests/test-service-providers.c' object='src/core/devices/wwan/tests/test_service_providers-test-service-providers.o' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-polkit-agent.o: src/nmcli/polkit-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-polkit-agent.o -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-polkit-agent.Tpo -c -o src/nmcli/nmcli-polkit-agent.o `test -f 'src/nmcli/polkit-agent.c' || echo '$(srcdir)/'`src/nmcli/polkit-agent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-polkit-agent.Tpo src/nmcli/$(DEPDIR)/nmcli-polkit-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/polkit-agent.c' object='src/nmcli/nmcli-polkit-agent.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/tests/test_service_providers-test-service-providers.o `test -f 'src/core/devices/wwan/tests/test-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/tests/test-service-providers.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-polkit-agent.o `test -f 'src/nmcli/polkit-agent.c' || echo '$(srcdir)/'`src/nmcli/polkit-agent.c -src/core/devices/wwan/tests/test_service_providers-test-service-providers.obj: src/core/devices/wwan/tests/test-service-providers.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/tests/test_service_providers-test-service-providers.obj -MD -MP -MF src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Tpo -c -o src/core/devices/wwan/tests/test_service_providers-test-service-providers.obj `if test -f 'src/core/devices/wwan/tests/test-service-providers.c'; then $(CYGPATH_W) 'src/core/devices/wwan/tests/test-service-providers.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wwan/tests/test-service-providers.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Tpo src/core/devices/wwan/tests/$(DEPDIR)/test_service_providers-test-service-providers.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/tests/test-service-providers.c' object='src/core/devices/wwan/tests/test_service_providers-test-service-providers.obj' libtool=no @AMDEPBACKSLASH@ +src/nmcli/nmcli-polkit-agent.obj: src/nmcli/polkit-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmcli/nmcli-polkit-agent.obj -MD -MP -MF src/nmcli/$(DEPDIR)/nmcli-polkit-agent.Tpo -c -o src/nmcli/nmcli-polkit-agent.obj `if test -f 'src/nmcli/polkit-agent.c'; then $(CYGPATH_W) 'src/nmcli/polkit-agent.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/polkit-agent.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmcli/$(DEPDIR)/nmcli-polkit-agent.Tpo src/nmcli/$(DEPDIR)/nmcli-polkit-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmcli/polkit-agent.c' object='src/nmcli/nmcli-polkit-agent.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/tests/test_service_providers-test-service-providers.obj `if test -f 'src/core/devices/wwan/tests/test-service-providers.c'; then $(CYGPATH_W) 'src/core/devices/wwan/tests/test-service-providers.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wwan/tests/test-service-providers.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmcli_nmcli_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmcli/nmcli-polkit-agent.obj `if test -f 'src/nmcli/polkit-agent.c'; then $(CYGPATH_W) 'src/nmcli/polkit-agent.c'; else $(CYGPATH_W) '$(srcdir)/src/nmcli/polkit-agent.c'; fi` -src/core/devices/wwan/tests_test_service_providers-nm-service-providers.o: src/core/devices/wwan/nm-service-providers.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/tests_test_service_providers-nm-service-providers.o -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Tpo -c -o src/core/devices/wwan/tests_test_service_providers-nm-service-providers.o `test -f 'src/core/devices/wwan/nm-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-service-providers.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Tpo src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-service-providers.c' object='src/core/devices/wwan/tests_test_service_providers-nm-service-providers.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmtui.o: src/nmtui/nmtui.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmtui.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmtui.Tpo -c -o src/nmtui/nmtui-nmtui.o `test -f 'src/nmtui/nmtui.c' || echo '$(srcdir)/'`src/nmtui/nmtui.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmtui.Tpo src/nmtui/$(DEPDIR)/nmtui-nmtui.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmtui.c' object='src/nmtui/nmtui-nmtui.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/tests_test_service_providers-nm-service-providers.o `test -f 'src/core/devices/wwan/nm-service-providers.c' || echo '$(srcdir)/'`src/core/devices/wwan/nm-service-providers.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmtui.o `test -f 'src/nmtui/nmtui.c' || echo '$(srcdir)/'`src/nmtui/nmtui.c -src/core/devices/wwan/tests_test_service_providers-nm-service-providers.obj: src/core/devices/wwan/nm-service-providers.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/devices/wwan/tests_test_service_providers-nm-service-providers.obj -MD -MP -MF src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Tpo -c -o src/core/devices/wwan/tests_test_service_providers-nm-service-providers.obj `if test -f 'src/core/devices/wwan/nm-service-providers.c'; then $(CYGPATH_W) 'src/core/devices/wwan/nm-service-providers.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wwan/nm-service-providers.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Tpo src/core/devices/wwan/$(DEPDIR)/tests_test_service_providers-nm-service-providers.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/devices/wwan/nm-service-providers.c' object='src/core/devices/wwan/tests_test_service_providers-nm-service-providers.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmtui.obj: src/nmtui/nmtui.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmtui.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmtui.Tpo -c -o src/nmtui/nmtui-nmtui.obj `if test -f 'src/nmtui/nmtui.c'; then $(CYGPATH_W) 'src/nmtui/nmtui.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmtui.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmtui.Tpo src/nmtui/$(DEPDIR)/nmtui-nmtui.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmtui.c' object='src/nmtui/nmtui-nmtui.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_devices_wwan_tests_test_service_providers_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/devices/wwan/tests_test_service_providers-nm-service-providers.obj `if test -f 'src/core/devices/wwan/nm-service-providers.c'; then $(CYGPATH_W) 'src/core/devices/wwan/nm-service-providers.c'; else $(CYGPATH_W) '$(srcdir)/src/core/devices/wwan/nm-service-providers.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmtui.obj `if test -f 'src/nmtui/nmtui.c'; then $(CYGPATH_W) 'src/nmtui/nmtui.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmtui.c'; fi` -src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.o: src/core/dhcp/nm-dhcp-helper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.o -MD -MP -MF src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo -c -o src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.o `test -f 'src/core/dhcp/nm-dhcp-helper.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-helper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-helper.c' object='src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmtui-connect.o: src/nmtui/nmtui-connect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmtui-connect.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmtui-connect.Tpo -c -o src/nmtui/nmtui-nmtui-connect.o `test -f 'src/nmtui/nmtui-connect.c' || echo '$(srcdir)/'`src/nmtui/nmtui-connect.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmtui-connect.Tpo src/nmtui/$(DEPDIR)/nmtui-nmtui-connect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmtui-connect.c' object='src/nmtui/nmtui-nmtui-connect.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.o `test -f 'src/core/dhcp/nm-dhcp-helper.c' || echo '$(srcdir)/'`src/core/dhcp/nm-dhcp-helper.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmtui-connect.o `test -f 'src/nmtui/nmtui-connect.c' || echo '$(srcdir)/'`src/nmtui/nmtui-connect.c -src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.obj: src/core/dhcp/nm-dhcp-helper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.obj -MD -MP -MF src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo -c -o src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.obj `if test -f 'src/core/dhcp/nm-dhcp-helper.c'; then $(CYGPATH_W) 'src/core/dhcp/nm-dhcp-helper.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/nm-dhcp-helper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo src/core/dhcp/$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/nm-dhcp-helper.c' object='src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmtui-connect.obj: src/nmtui/nmtui-connect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmtui-connect.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmtui-connect.Tpo -c -o src/nmtui/nmtui-nmtui-connect.obj `if test -f 'src/nmtui/nmtui-connect.c'; then $(CYGPATH_W) 'src/nmtui/nmtui-connect.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmtui-connect.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmtui-connect.Tpo src/nmtui/$(DEPDIR)/nmtui-nmtui-connect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmtui-connect.c' object='src/nmtui/nmtui-nmtui-connect.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/nm_dhcp_helper-nm-dhcp-helper.obj `if test -f 'src/core/dhcp/nm-dhcp-helper.c'; then $(CYGPATH_W) 'src/core/dhcp/nm-dhcp-helper.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/nm-dhcp-helper.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmtui-connect.obj `if test -f 'src/nmtui/nmtui-connect.c'; then $(CYGPATH_W) 'src/nmtui/nmtui-connect.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmtui-connect.c'; fi` -src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.o: src/core/dhcp/tests/test-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.o -MD -MP -MF src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo -c -o src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.o `test -f 'src/core/dhcp/tests/test-dhcp-dhclient.c' || echo '$(srcdir)/'`src/core/dhcp/tests/test-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/tests/test-dhcp-dhclient.c' object='src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmtui-edit.o: src/nmtui/nmtui-edit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmtui-edit.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmtui-edit.Tpo -c -o src/nmtui/nmtui-nmtui-edit.o `test -f 'src/nmtui/nmtui-edit.c' || echo '$(srcdir)/'`src/nmtui/nmtui-edit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmtui-edit.Tpo src/nmtui/$(DEPDIR)/nmtui-nmtui-edit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmtui-edit.c' object='src/nmtui/nmtui-nmtui-edit.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.o `test -f 'src/core/dhcp/tests/test-dhcp-dhclient.c' || echo '$(srcdir)/'`src/core/dhcp/tests/test-dhcp-dhclient.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmtui-edit.o `test -f 'src/nmtui/nmtui-edit.c' || echo '$(srcdir)/'`src/nmtui/nmtui-edit.c -src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.obj: src/core/dhcp/tests/test-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.obj -MD -MP -MF src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo -c -o src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.obj `if test -f 'src/core/dhcp/tests/test-dhcp-dhclient.c'; then $(CYGPATH_W) 'src/core/dhcp/tests/test-dhcp-dhclient.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/tests/test-dhcp-dhclient.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo src/core/dhcp/tests/$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/tests/test-dhcp-dhclient.c' object='src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmtui-edit.obj: src/nmtui/nmtui-edit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmtui-edit.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmtui-edit.Tpo -c -o src/nmtui/nmtui-nmtui-edit.obj `if test -f 'src/nmtui/nmtui-edit.c'; then $(CYGPATH_W) 'src/nmtui/nmtui-edit.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmtui-edit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmtui-edit.Tpo src/nmtui/$(DEPDIR)/nmtui-nmtui-edit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmtui-edit.c' object='src/nmtui/nmtui-nmtui-edit.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/tests/test_dhcp_dhclient-test-dhcp-dhclient.obj `if test -f 'src/core/dhcp/tests/test-dhcp-dhclient.c'; then $(CYGPATH_W) 'src/core/dhcp/tests/test-dhcp-dhclient.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/tests/test-dhcp-dhclient.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmtui-edit.obj `if test -f 'src/nmtui/nmtui-edit.c'; then $(CYGPATH_W) 'src/nmtui/nmtui-edit.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmtui-edit.c'; fi` -src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.o: src/core/dhcp/tests/test-dhcp-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.o -MD -MP -MF src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Tpo -c -o src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.o `test -f 'src/core/dhcp/tests/test-dhcp-utils.c' || echo '$(srcdir)/'`src/core/dhcp/tests/test-dhcp-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Tpo src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/tests/test-dhcp-utils.c' object='src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmtui-hostname.o: src/nmtui/nmtui-hostname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmtui-hostname.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmtui-hostname.Tpo -c -o src/nmtui/nmtui-nmtui-hostname.o `test -f 'src/nmtui/nmtui-hostname.c' || echo '$(srcdir)/'`src/nmtui/nmtui-hostname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmtui-hostname.Tpo src/nmtui/$(DEPDIR)/nmtui-nmtui-hostname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmtui-hostname.c' object='src/nmtui/nmtui-nmtui-hostname.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.o `test -f 'src/core/dhcp/tests/test-dhcp-utils.c' || echo '$(srcdir)/'`src/core/dhcp/tests/test-dhcp-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmtui-hostname.o `test -f 'src/nmtui/nmtui-hostname.c' || echo '$(srcdir)/'`src/nmtui/nmtui-hostname.c -src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.obj: src/core/dhcp/tests/test-dhcp-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.obj -MD -MP -MF src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Tpo -c -o src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.obj `if test -f 'src/core/dhcp/tests/test-dhcp-utils.c'; then $(CYGPATH_W) 'src/core/dhcp/tests/test-dhcp-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/tests/test-dhcp-utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Tpo src/core/dhcp/tests/$(DEPDIR)/test_dhcp_utils-test-dhcp-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dhcp/tests/test-dhcp-utils.c' object='src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmtui-hostname.obj: src/nmtui/nmtui-hostname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmtui-hostname.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmtui-hostname.Tpo -c -o src/nmtui/nmtui-nmtui-hostname.obj `if test -f 'src/nmtui/nmtui-hostname.c'; then $(CYGPATH_W) 'src/nmtui/nmtui-hostname.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmtui-hostname.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmtui-hostname.Tpo src/nmtui/$(DEPDIR)/nmtui-nmtui-hostname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmtui-hostname.c' object='src/nmtui/nmtui-nmtui-hostname.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dhcp_tests_test_dhcp_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dhcp/tests/test_dhcp_utils-test-dhcp-utils.obj `if test -f 'src/core/dhcp/tests/test-dhcp-utils.c'; then $(CYGPATH_W) 'src/core/dhcp/tests/test-dhcp-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dhcp/tests/test-dhcp-utils.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmtui-hostname.obj `if test -f 'src/nmtui/nmtui-hostname.c'; then $(CYGPATH_W) 'src/nmtui/nmtui-hostname.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmtui-hostname.c'; fi` -src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.o: src/core/dnsmasq/tests/test-dnsmasq-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dnsmasq_tests_test_dnsmasq_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.o -MD -MP -MF src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Tpo -c -o src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.o `test -f 'src/core/dnsmasq/tests/test-dnsmasq-utils.c' || echo '$(srcdir)/'`src/core/dnsmasq/tests/test-dnsmasq-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Tpo src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dnsmasq/tests/test-dnsmasq-utils.c' object='src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nm-editor-bindings.o: src/nmtui/nm-editor-bindings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nm-editor-bindings.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nm-editor-bindings.Tpo -c -o src/nmtui/nmtui-nm-editor-bindings.o `test -f 'src/nmtui/nm-editor-bindings.c' || echo '$(srcdir)/'`src/nmtui/nm-editor-bindings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nm-editor-bindings.Tpo src/nmtui/$(DEPDIR)/nmtui-nm-editor-bindings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nm-editor-bindings.c' object='src/nmtui/nmtui-nm-editor-bindings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dnsmasq_tests_test_dnsmasq_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.o `test -f 'src/core/dnsmasq/tests/test-dnsmasq-utils.c' || echo '$(srcdir)/'`src/core/dnsmasq/tests/test-dnsmasq-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nm-editor-bindings.o `test -f 'src/nmtui/nm-editor-bindings.c' || echo '$(srcdir)/'`src/nmtui/nm-editor-bindings.c -src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.obj: src/core/dnsmasq/tests/test-dnsmasq-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dnsmasq_tests_test_dnsmasq_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.obj -MD -MP -MF src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Tpo -c -o src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.obj `if test -f 'src/core/dnsmasq/tests/test-dnsmasq-utils.c'; then $(CYGPATH_W) 'src/core/dnsmasq/tests/test-dnsmasq-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dnsmasq/tests/test-dnsmasq-utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Tpo src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/dnsmasq/tests/test-dnsmasq-utils.c' object='src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nm-editor-bindings.obj: src/nmtui/nm-editor-bindings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nm-editor-bindings.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nm-editor-bindings.Tpo -c -o src/nmtui/nmtui-nm-editor-bindings.obj `if test -f 'src/nmtui/nm-editor-bindings.c'; then $(CYGPATH_W) 'src/nmtui/nm-editor-bindings.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nm-editor-bindings.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nm-editor-bindings.Tpo src/nmtui/$(DEPDIR)/nmtui-nm-editor-bindings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nm-editor-bindings.c' object='src/nmtui/nmtui-nm-editor-bindings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_dnsmasq_tests_test_dnsmasq_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/dnsmasq/tests/test_dnsmasq_utils-test-dnsmasq-utils.obj `if test -f 'src/core/dnsmasq/tests/test-dnsmasq-utils.c'; then $(CYGPATH_W) 'src/core/dnsmasq/tests/test-dnsmasq-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/dnsmasq/tests/test-dnsmasq-utils.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nm-editor-bindings.obj `if test -f 'src/nmtui/nm-editor-bindings.c'; then $(CYGPATH_W) 'src/nmtui/nm-editor-bindings.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nm-editor-bindings.c'; fi` -src/core/initrd/nm_initrd_generator-nm-initrd-generator.o: src/core/initrd/nm-initrd-generator.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_nm_initrd_generator_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/nm_initrd_generator-nm-initrd-generator.o -MD -MP -MF src/core/initrd/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Tpo -c -o src/core/initrd/nm_initrd_generator-nm-initrd-generator.o `test -f 'src/core/initrd/nm-initrd-generator.c' || echo '$(srcdir)/'`src/core/initrd/nm-initrd-generator.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Tpo src/core/initrd/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/nm-initrd-generator.c' object='src/core/initrd/nm_initrd_generator-nm-initrd-generator.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nm-editor-utils.o: src/nmtui/nm-editor-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nm-editor-utils.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nm-editor-utils.Tpo -c -o src/nmtui/nmtui-nm-editor-utils.o `test -f 'src/nmtui/nm-editor-utils.c' || echo '$(srcdir)/'`src/nmtui/nm-editor-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nm-editor-utils.Tpo src/nmtui/$(DEPDIR)/nmtui-nm-editor-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nm-editor-utils.c' object='src/nmtui/nmtui-nm-editor-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_nm_initrd_generator_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/nm_initrd_generator-nm-initrd-generator.o `test -f 'src/core/initrd/nm-initrd-generator.c' || echo '$(srcdir)/'`src/core/initrd/nm-initrd-generator.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nm-editor-utils.o `test -f 'src/nmtui/nm-editor-utils.c' || echo '$(srcdir)/'`src/nmtui/nm-editor-utils.c -src/core/initrd/nm_initrd_generator-nm-initrd-generator.obj: src/core/initrd/nm-initrd-generator.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_nm_initrd_generator_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/nm_initrd_generator-nm-initrd-generator.obj -MD -MP -MF src/core/initrd/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Tpo -c -o src/core/initrd/nm_initrd_generator-nm-initrd-generator.obj `if test -f 'src/core/initrd/nm-initrd-generator.c'; then $(CYGPATH_W) 'src/core/initrd/nm-initrd-generator.c'; else $(CYGPATH_W) '$(srcdir)/src/core/initrd/nm-initrd-generator.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Tpo src/core/initrd/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/nm-initrd-generator.c' object='src/core/initrd/nm_initrd_generator-nm-initrd-generator.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nm-editor-utils.obj: src/nmtui/nm-editor-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nm-editor-utils.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nm-editor-utils.Tpo -c -o src/nmtui/nmtui-nm-editor-utils.obj `if test -f 'src/nmtui/nm-editor-utils.c'; then $(CYGPATH_W) 'src/nmtui/nm-editor-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nm-editor-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nm-editor-utils.Tpo src/nmtui/$(DEPDIR)/nmtui-nm-editor-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nm-editor-utils.c' object='src/nmtui/nmtui-nm-editor-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_nm_initrd_generator_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/nm_initrd_generator-nm-initrd-generator.obj `if test -f 'src/core/initrd/nm-initrd-generator.c'; then $(CYGPATH_W) 'src/core/initrd/nm-initrd-generator.c'; else $(CYGPATH_W) '$(srcdir)/src/core/initrd/nm-initrd-generator.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nm-editor-utils.obj `if test -f 'src/nmtui/nm-editor-utils.c'; then $(CYGPATH_W) 'src/nmtui/nm-editor-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nm-editor-utils.c'; fi` -src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.o: src/core/initrd/tests/test-cmdline-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_cmdline_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.o -MD -MP -MF src/core/initrd/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Tpo -c -o src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.o `test -f 'src/core/initrd/tests/test-cmdline-reader.c' || echo '$(srcdir)/'`src/core/initrd/tests/test-cmdline-reader.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Tpo src/core/initrd/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/tests/test-cmdline-reader.c' object='src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-address-list.o: src/nmtui/nmt-address-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-address-list.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-address-list.Tpo -c -o src/nmtui/nmtui-nmt-address-list.o `test -f 'src/nmtui/nmt-address-list.c' || echo '$(srcdir)/'`src/nmtui/nmt-address-list.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-address-list.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-address-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-address-list.c' object='src/nmtui/nmtui-nmt-address-list.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_cmdline_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.o `test -f 'src/core/initrd/tests/test-cmdline-reader.c' || echo '$(srcdir)/'`src/core/initrd/tests/test-cmdline-reader.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-address-list.o `test -f 'src/nmtui/nmt-address-list.c' || echo '$(srcdir)/'`src/nmtui/nmt-address-list.c -src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.obj: src/core/initrd/tests/test-cmdline-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_cmdline_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.obj -MD -MP -MF src/core/initrd/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Tpo -c -o src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.obj `if test -f 'src/core/initrd/tests/test-cmdline-reader.c'; then $(CYGPATH_W) 'src/core/initrd/tests/test-cmdline-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/core/initrd/tests/test-cmdline-reader.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Tpo src/core/initrd/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/tests/test-cmdline-reader.c' object='src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-address-list.obj: src/nmtui/nmt-address-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-address-list.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-address-list.Tpo -c -o src/nmtui/nmtui-nmt-address-list.obj `if test -f 'src/nmtui/nmt-address-list.c'; then $(CYGPATH_W) 'src/nmtui/nmt-address-list.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-address-list.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-address-list.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-address-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-address-list.c' object='src/nmtui/nmtui-nmt-address-list.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_cmdline_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/tests/test_cmdline_reader-test-cmdline-reader.obj `if test -f 'src/core/initrd/tests/test-cmdline-reader.c'; then $(CYGPATH_W) 'src/core/initrd/tests/test-cmdline-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/core/initrd/tests/test-cmdline-reader.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-address-list.obj `if test -f 'src/nmtui/nmt-address-list.c'; then $(CYGPATH_W) 'src/nmtui/nmt-address-list.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-address-list.c'; fi` -src/core/initrd/tests/test_dt_reader-test-dt-reader.o: src/core/initrd/tests/test-dt-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_dt_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/tests/test_dt_reader-test-dt-reader.o -MD -MP -MF src/core/initrd/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Tpo -c -o src/core/initrd/tests/test_dt_reader-test-dt-reader.o `test -f 'src/core/initrd/tests/test-dt-reader.c' || echo '$(srcdir)/'`src/core/initrd/tests/test-dt-reader.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Tpo src/core/initrd/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/tests/test-dt-reader.c' object='src/core/initrd/tests/test_dt_reader-test-dt-reader.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-connect-connection-list.o: src/nmtui/nmt-connect-connection-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-connect-connection-list.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Tpo -c -o src/nmtui/nmtui-nmt-connect-connection-list.o `test -f 'src/nmtui/nmt-connect-connection-list.c' || echo '$(srcdir)/'`src/nmtui/nmt-connect-connection-list.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-connect-connection-list.c' object='src/nmtui/nmtui-nmt-connect-connection-list.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_dt_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/tests/test_dt_reader-test-dt-reader.o `test -f 'src/core/initrd/tests/test-dt-reader.c' || echo '$(srcdir)/'`src/core/initrd/tests/test-dt-reader.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-connect-connection-list.o `test -f 'src/nmtui/nmt-connect-connection-list.c' || echo '$(srcdir)/'`src/nmtui/nmt-connect-connection-list.c -src/core/initrd/tests/test_dt_reader-test-dt-reader.obj: src/core/initrd/tests/test-dt-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_dt_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/tests/test_dt_reader-test-dt-reader.obj -MD -MP -MF src/core/initrd/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Tpo -c -o src/core/initrd/tests/test_dt_reader-test-dt-reader.obj `if test -f 'src/core/initrd/tests/test-dt-reader.c'; then $(CYGPATH_W) 'src/core/initrd/tests/test-dt-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/core/initrd/tests/test-dt-reader.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Tpo src/core/initrd/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/tests/test-dt-reader.c' object='src/core/initrd/tests/test_dt_reader-test-dt-reader.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-connect-connection-list.obj: src/nmtui/nmt-connect-connection-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-connect-connection-list.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Tpo -c -o src/nmtui/nmtui-nmt-connect-connection-list.obj `if test -f 'src/nmtui/nmt-connect-connection-list.c'; then $(CYGPATH_W) 'src/nmtui/nmt-connect-connection-list.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-connect-connection-list.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-connect-connection-list.c' object='src/nmtui/nmtui-nmt-connect-connection-list.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_dt_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/tests/test_dt_reader-test-dt-reader.obj `if test -f 'src/core/initrd/tests/test-dt-reader.c'; then $(CYGPATH_W) 'src/core/initrd/tests/test-dt-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/core/initrd/tests/test-dt-reader.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-connect-connection-list.obj `if test -f 'src/nmtui/nmt-connect-connection-list.c'; then $(CYGPATH_W) 'src/nmtui/nmt-connect-connection-list.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-connect-connection-list.c'; fi` -src/core/initrd/tests/test_ibft_reader-test-ibft-reader.o: src/core/initrd/tests/test-ibft-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_ibft_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/tests/test_ibft_reader-test-ibft-reader.o -MD -MP -MF src/core/initrd/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Tpo -c -o src/core/initrd/tests/test_ibft_reader-test-ibft-reader.o `test -f 'src/core/initrd/tests/test-ibft-reader.c' || echo '$(srcdir)/'`src/core/initrd/tests/test-ibft-reader.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Tpo src/core/initrd/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/tests/test-ibft-reader.c' object='src/core/initrd/tests/test_ibft_reader-test-ibft-reader.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-device-entry.o: src/nmtui/nmt-device-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-device-entry.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-device-entry.Tpo -c -o src/nmtui/nmtui-nmt-device-entry.o `test -f 'src/nmtui/nmt-device-entry.c' || echo '$(srcdir)/'`src/nmtui/nmt-device-entry.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-device-entry.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-device-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-device-entry.c' object='src/nmtui/nmtui-nmt-device-entry.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_ibft_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/tests/test_ibft_reader-test-ibft-reader.o `test -f 'src/core/initrd/tests/test-ibft-reader.c' || echo '$(srcdir)/'`src/core/initrd/tests/test-ibft-reader.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-device-entry.o `test -f 'src/nmtui/nmt-device-entry.c' || echo '$(srcdir)/'`src/nmtui/nmt-device-entry.c -src/core/initrd/tests/test_ibft_reader-test-ibft-reader.obj: src/core/initrd/tests/test-ibft-reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_ibft_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/initrd/tests/test_ibft_reader-test-ibft-reader.obj -MD -MP -MF src/core/initrd/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Tpo -c -o src/core/initrd/tests/test_ibft_reader-test-ibft-reader.obj `if test -f 'src/core/initrd/tests/test-ibft-reader.c'; then $(CYGPATH_W) 'src/core/initrd/tests/test-ibft-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/core/initrd/tests/test-ibft-reader.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/initrd/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Tpo src/core/initrd/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/initrd/tests/test-ibft-reader.c' object='src/core/initrd/tests/test_ibft_reader-test-ibft-reader.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-device-entry.obj: src/nmtui/nmt-device-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-device-entry.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-device-entry.Tpo -c -o src/nmtui/nmtui-nmt-device-entry.obj `if test -f 'src/nmtui/nmt-device-entry.c'; then $(CYGPATH_W) 'src/nmtui/nmt-device-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-device-entry.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-device-entry.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-device-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-device-entry.c' object='src/nmtui/nmtui-nmt-device-entry.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_initrd_tests_test_ibft_reader_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/initrd/tests/test_ibft_reader-test-ibft-reader.obj `if test -f 'src/core/initrd/tests/test-ibft-reader.c'; then $(CYGPATH_W) 'src/core/initrd/tests/test-ibft-reader.c'; else $(CYGPATH_W) '$(srcdir)/src/core/initrd/tests/test-ibft-reader.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-device-entry.obj `if test -f 'src/nmtui/nmt-device-entry.c'; then $(CYGPATH_W) 'src/nmtui/nmt-device-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-device-entry.c'; fi` -src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.o: src/core/ndisc/tests/test-ndisc-fake.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.o -MD -MP -MF src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Tpo -c -o src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.o `test -f 'src/core/ndisc/tests/test-ndisc-fake.c' || echo '$(srcdir)/'`src/core/ndisc/tests/test-ndisc-fake.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Tpo src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/tests/test-ndisc-fake.c' object='src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-edit-connection-list.o: src/nmtui/nmt-edit-connection-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-edit-connection-list.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Tpo -c -o src/nmtui/nmtui-nmt-edit-connection-list.o `test -f 'src/nmtui/nmt-edit-connection-list.c' || echo '$(srcdir)/'`src/nmtui/nmt-edit-connection-list.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-edit-connection-list.c' object='src/nmtui/nmtui-nmt-edit-connection-list.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.o `test -f 'src/core/ndisc/tests/test-ndisc-fake.c' || echo '$(srcdir)/'`src/core/ndisc/tests/test-ndisc-fake.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-edit-connection-list.o `test -f 'src/nmtui/nmt-edit-connection-list.c' || echo '$(srcdir)/'`src/nmtui/nmt-edit-connection-list.c -src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.obj: src/core/ndisc/tests/test-ndisc-fake.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.obj -MD -MP -MF src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Tpo -c -o src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.obj `if test -f 'src/core/ndisc/tests/test-ndisc-fake.c'; then $(CYGPATH_W) 'src/core/ndisc/tests/test-ndisc-fake.c'; else $(CYGPATH_W) '$(srcdir)/src/core/ndisc/tests/test-ndisc-fake.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Tpo src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/tests/test-ndisc-fake.c' object='src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-edit-connection-list.obj: src/nmtui/nmt-edit-connection-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-edit-connection-list.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Tpo -c -o src/nmtui/nmtui-nmt-edit-connection-list.obj `if test -f 'src/nmtui/nmt-edit-connection-list.c'; then $(CYGPATH_W) 'src/nmtui/nmt-edit-connection-list.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-edit-connection-list.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-edit-connection-list.c' object='src/nmtui/nmtui-nmt-edit-connection-list.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/tests/test_ndisc_fake-test-ndisc-fake.obj `if test -f 'src/core/ndisc/tests/test-ndisc-fake.c'; then $(CYGPATH_W) 'src/core/ndisc/tests/test-ndisc-fake.c'; else $(CYGPATH_W) '$(srcdir)/src/core/ndisc/tests/test-ndisc-fake.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-edit-connection-list.obj `if test -f 'src/nmtui/nmt-edit-connection-list.c'; then $(CYGPATH_W) 'src/nmtui/nmt-edit-connection-list.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-edit-connection-list.c'; fi` -src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.o: src/core/ndisc/tests/test-ndisc-linux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.o -MD -MP -MF src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Tpo -c -o src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.o `test -f 'src/core/ndisc/tests/test-ndisc-linux.c' || echo '$(srcdir)/'`src/core/ndisc/tests/test-ndisc-linux.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Tpo src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/tests/test-ndisc-linux.c' object='src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-editor-grid.o: src/nmtui/nmt-editor-grid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-editor-grid.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-editor-grid.Tpo -c -o src/nmtui/nmtui-nmt-editor-grid.o `test -f 'src/nmtui/nmt-editor-grid.c' || echo '$(srcdir)/'`src/nmtui/nmt-editor-grid.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-editor-grid.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-editor-grid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-editor-grid.c' object='src/nmtui/nmtui-nmt-editor-grid.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.o `test -f 'src/core/ndisc/tests/test-ndisc-linux.c' || echo '$(srcdir)/'`src/core/ndisc/tests/test-ndisc-linux.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-editor-grid.o `test -f 'src/nmtui/nmt-editor-grid.c' || echo '$(srcdir)/'`src/nmtui/nmt-editor-grid.c -src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.obj: src/core/ndisc/tests/test-ndisc-linux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.obj -MD -MP -MF src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Tpo -c -o src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.obj `if test -f 'src/core/ndisc/tests/test-ndisc-linux.c'; then $(CYGPATH_W) 'src/core/ndisc/tests/test-ndisc-linux.c'; else $(CYGPATH_W) '$(srcdir)/src/core/ndisc/tests/test-ndisc-linux.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Tpo src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/ndisc/tests/test-ndisc-linux.c' object='src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-editor-grid.obj: src/nmtui/nmt-editor-grid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-editor-grid.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-editor-grid.Tpo -c -o src/nmtui/nmtui-nmt-editor-grid.obj `if test -f 'src/nmtui/nmt-editor-grid.c'; then $(CYGPATH_W) 'src/nmtui/nmt-editor-grid.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-editor-grid.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-editor-grid.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-editor-grid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-editor-grid.c' object='src/nmtui/nmtui-nmt-editor-grid.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_ndisc_tests_test_ndisc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/ndisc/tests/test_ndisc_linux-test-ndisc-linux.obj `if test -f 'src/core/ndisc/tests/test-ndisc-linux.c'; then $(CYGPATH_W) 'src/core/ndisc/tests/test-ndisc-linux.c'; else $(CYGPATH_W) '$(srcdir)/src/core/ndisc/tests/test-ndisc-linux.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-editor-grid.obj `if test -f 'src/nmtui/nmt-editor-grid.c'; then $(CYGPATH_W) 'src/nmtui/nmt-editor-grid.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-editor-grid.c'; fi` -src/core/nm_iface_helper-nm-iface-helper.o: src/core/nm-iface-helper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_nm_iface_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/nm_iface_helper-nm-iface-helper.o -MD -MP -MF src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Tpo -c -o src/core/nm_iface_helper-nm-iface-helper.o `test -f 'src/core/nm-iface-helper.c' || echo '$(srcdir)/'`src/core/nm-iface-helper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Tpo src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-iface-helper.c' object='src/core/nm_iface_helper-nm-iface-helper.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-editor-page.o: src/nmtui/nmt-editor-page.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-editor-page.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page.Tpo -c -o src/nmtui/nmtui-nmt-editor-page.o `test -f 'src/nmtui/nmt-editor-page.c' || echo '$(srcdir)/'`src/nmtui/nmt-editor-page.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-editor-page.c' object='src/nmtui/nmtui-nmt-editor-page.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_nm_iface_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/nm_iface_helper-nm-iface-helper.o `test -f 'src/core/nm-iface-helper.c' || echo '$(srcdir)/'`src/core/nm-iface-helper.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-editor-page.o `test -f 'src/nmtui/nmt-editor-page.c' || echo '$(srcdir)/'`src/nmtui/nmt-editor-page.c -src/core/nm_iface_helper-nm-iface-helper.obj: src/core/nm-iface-helper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_nm_iface_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/nm_iface_helper-nm-iface-helper.obj -MD -MP -MF src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Tpo -c -o src/core/nm_iface_helper-nm-iface-helper.obj `if test -f 'src/core/nm-iface-helper.c'; then $(CYGPATH_W) 'src/core/nm-iface-helper.c'; else $(CYGPATH_W) '$(srcdir)/src/core/nm-iface-helper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Tpo src/core/$(DEPDIR)/nm_iface_helper-nm-iface-helper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/nm-iface-helper.c' object='src/core/nm_iface_helper-nm-iface-helper.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-editor-page.obj: src/nmtui/nmt-editor-page.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-editor-page.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page.Tpo -c -o src/nmtui/nmtui-nmt-editor-page.obj `if test -f 'src/nmtui/nmt-editor-page.c'; then $(CYGPATH_W) 'src/nmtui/nmt-editor-page.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-editor-page.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-editor-page.c' object='src/nmtui/nmtui-nmt-editor-page.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_nm_iface_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/nm_iface_helper-nm-iface-helper.obj `if test -f 'src/core/nm-iface-helper.c'; then $(CYGPATH_W) 'src/core/nm-iface-helper.c'; else $(CYGPATH_W) '$(srcdir)/src/core/nm-iface-helper.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-editor-page.obj `if test -f 'src/nmtui/nmt-editor-page.c'; then $(CYGPATH_W) 'src/nmtui/nmt-editor-page.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-editor-page.c'; fi` -src/core/platform/tests/monitor-monitor.o: src/core/platform/tests/monitor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/monitor-monitor.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/monitor-monitor.Tpo -c -o src/core/platform/tests/monitor-monitor.o `test -f 'src/core/platform/tests/monitor.c' || echo '$(srcdir)/'`src/core/platform/tests/monitor.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/monitor-monitor.Tpo src/core/platform/tests/$(DEPDIR)/monitor-monitor.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/monitor.c' object='src/core/platform/tests/monitor-monitor.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-editor-page-device.o: src/nmtui/nmt-editor-page-device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-editor-page-device.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page-device.Tpo -c -o src/nmtui/nmtui-nmt-editor-page-device.o `test -f 'src/nmtui/nmt-editor-page-device.c' || echo '$(srcdir)/'`src/nmtui/nmt-editor-page-device.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page-device.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-editor-page-device.c' object='src/nmtui/nmtui-nmt-editor-page-device.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/monitor-monitor.o `test -f 'src/core/platform/tests/monitor.c' || echo '$(srcdir)/'`src/core/platform/tests/monitor.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-editor-page-device.o `test -f 'src/nmtui/nmt-editor-page-device.c' || echo '$(srcdir)/'`src/nmtui/nmt-editor-page-device.c -src/core/platform/tests/monitor-monitor.obj: src/core/platform/tests/monitor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/monitor-monitor.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/monitor-monitor.Tpo -c -o src/core/platform/tests/monitor-monitor.obj `if test -f 'src/core/platform/tests/monitor.c'; then $(CYGPATH_W) 'src/core/platform/tests/monitor.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/monitor.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/monitor-monitor.Tpo src/core/platform/tests/$(DEPDIR)/monitor-monitor.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/monitor.c' object='src/core/platform/tests/monitor-monitor.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-editor-page-device.obj: src/nmtui/nmt-editor-page-device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-editor-page-device.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page-device.Tpo -c -o src/nmtui/nmtui-nmt-editor-page-device.obj `if test -f 'src/nmtui/nmt-editor-page-device.c'; then $(CYGPATH_W) 'src/nmtui/nmt-editor-page-device.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-editor-page-device.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page-device.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-editor-page-device.c' object='src/nmtui/nmtui-nmt-editor-page-device.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/monitor-monitor.obj `if test -f 'src/core/platform/tests/monitor.c'; then $(CYGPATH_W) 'src/core/platform/tests/monitor.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/monitor.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-editor-page-device.obj `if test -f 'src/nmtui/nmt-editor-page-device.c'; then $(CYGPATH_W) 'src/nmtui/nmt-editor-page-device.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-editor-page-device.c'; fi` -src/core/platform/tests/test_address_fake-test-address.o: src/core/platform/tests/test-address.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_address_fake-test-address.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Tpo -c -o src/core/platform/tests/test_address_fake-test-address.o `test -f 'src/core/platform/tests/test-address.c' || echo '$(srcdir)/'`src/core/platform/tests/test-address.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Tpo src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-address.c' object='src/core/platform/tests/test_address_fake-test-address.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-editor-section.o: src/nmtui/nmt-editor-section.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-editor-section.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-editor-section.Tpo -c -o src/nmtui/nmtui-nmt-editor-section.o `test -f 'src/nmtui/nmt-editor-section.c' || echo '$(srcdir)/'`src/nmtui/nmt-editor-section.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-editor-section.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-editor-section.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-editor-section.c' object='src/nmtui/nmtui-nmt-editor-section.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_address_fake-test-address.o `test -f 'src/core/platform/tests/test-address.c' || echo '$(srcdir)/'`src/core/platform/tests/test-address.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-editor-section.o `test -f 'src/nmtui/nmt-editor-section.c' || echo '$(srcdir)/'`src/nmtui/nmt-editor-section.c -src/core/platform/tests/test_address_fake-test-address.obj: src/core/platform/tests/test-address.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_address_fake-test-address.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Tpo -c -o src/core/platform/tests/test_address_fake-test-address.obj `if test -f 'src/core/platform/tests/test-address.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-address.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-address.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Tpo src/core/platform/tests/$(DEPDIR)/test_address_fake-test-address.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-address.c' object='src/core/platform/tests/test_address_fake-test-address.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-editor-section.obj: src/nmtui/nmt-editor-section.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-editor-section.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-editor-section.Tpo -c -o src/nmtui/nmtui-nmt-editor-section.obj `if test -f 'src/nmtui/nmt-editor-section.c'; then $(CYGPATH_W) 'src/nmtui/nmt-editor-section.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-editor-section.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-editor-section.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-editor-section.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-editor-section.c' object='src/nmtui/nmtui-nmt-editor-section.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_address_fake-test-address.obj `if test -f 'src/core/platform/tests/test-address.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-address.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-address.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-editor-section.obj `if test -f 'src/nmtui/nmt-editor-section.c'; then $(CYGPATH_W) 'src/nmtui/nmt-editor-section.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-editor-section.c'; fi` -src/core/platform/tests/test_address_linux-test-address.o: src/core/platform/tests/test-address.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_address_linux-test-address.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Tpo -c -o src/core/platform/tests/test_address_linux-test-address.o `test -f 'src/core/platform/tests/test-address.c' || echo '$(srcdir)/'`src/core/platform/tests/test-address.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Tpo src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-address.c' object='src/core/platform/tests/test_address_linux-test-address.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-editor.o: src/nmtui/nmt-editor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-editor.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-editor.Tpo -c -o src/nmtui/nmtui-nmt-editor.o `test -f 'src/nmtui/nmt-editor.c' || echo '$(srcdir)/'`src/nmtui/nmt-editor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-editor.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-editor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-editor.c' object='src/nmtui/nmtui-nmt-editor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_address_linux-test-address.o `test -f 'src/core/platform/tests/test-address.c' || echo '$(srcdir)/'`src/core/platform/tests/test-address.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-editor.o `test -f 'src/nmtui/nmt-editor.c' || echo '$(srcdir)/'`src/nmtui/nmt-editor.c -src/core/platform/tests/test_address_linux-test-address.obj: src/core/platform/tests/test-address.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_address_linux-test-address.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Tpo -c -o src/core/platform/tests/test_address_linux-test-address.obj `if test -f 'src/core/platform/tests/test-address.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-address.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-address.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Tpo src/core/platform/tests/$(DEPDIR)/test_address_linux-test-address.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-address.c' object='src/core/platform/tests/test_address_linux-test-address.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-editor.obj: src/nmtui/nmt-editor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-editor.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-editor.Tpo -c -o src/nmtui/nmtui-nmt-editor.obj `if test -f 'src/nmtui/nmt-editor.c'; then $(CYGPATH_W) 'src/nmtui/nmt-editor.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-editor.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-editor.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-editor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-editor.c' object='src/nmtui/nmtui-nmt-editor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_address_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_address_linux-test-address.obj `if test -f 'src/core/platform/tests/test-address.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-address.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-address.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-editor.obj `if test -f 'src/nmtui/nmt-editor.c'; then $(CYGPATH_W) 'src/nmtui/nmt-editor.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-editor.c'; fi` -src/core/platform/tests/test_cleanup_fake-test-cleanup.o: src/core/platform/tests/test-cleanup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_cleanup_fake-test-cleanup.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Tpo -c -o src/core/platform/tests/test_cleanup_fake-test-cleanup.o `test -f 'src/core/platform/tests/test-cleanup.c' || echo '$(srcdir)/'`src/core/platform/tests/test-cleanup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Tpo src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-cleanup.c' object='src/core/platform/tests/test_cleanup_fake-test-cleanup.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-ip-entry.o: src/nmtui/nmt-ip-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-ip-entry.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-ip-entry.Tpo -c -o src/nmtui/nmtui-nmt-ip-entry.o `test -f 'src/nmtui/nmt-ip-entry.c' || echo '$(srcdir)/'`src/nmtui/nmt-ip-entry.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-ip-entry.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-ip-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-ip-entry.c' object='src/nmtui/nmtui-nmt-ip-entry.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_cleanup_fake-test-cleanup.o `test -f 'src/core/platform/tests/test-cleanup.c' || echo '$(srcdir)/'`src/core/platform/tests/test-cleanup.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-ip-entry.o `test -f 'src/nmtui/nmt-ip-entry.c' || echo '$(srcdir)/'`src/nmtui/nmt-ip-entry.c -src/core/platform/tests/test_cleanup_fake-test-cleanup.obj: src/core/platform/tests/test-cleanup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_cleanup_fake-test-cleanup.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Tpo -c -o src/core/platform/tests/test_cleanup_fake-test-cleanup.obj `if test -f 'src/core/platform/tests/test-cleanup.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-cleanup.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-cleanup.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Tpo src/core/platform/tests/$(DEPDIR)/test_cleanup_fake-test-cleanup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-cleanup.c' object='src/core/platform/tests/test_cleanup_fake-test-cleanup.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-ip-entry.obj: src/nmtui/nmt-ip-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-ip-entry.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-ip-entry.Tpo -c -o src/nmtui/nmtui-nmt-ip-entry.obj `if test -f 'src/nmtui/nmt-ip-entry.c'; then $(CYGPATH_W) 'src/nmtui/nmt-ip-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-ip-entry.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-ip-entry.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-ip-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-ip-entry.c' object='src/nmtui/nmtui-nmt-ip-entry.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_cleanup_fake-test-cleanup.obj `if test -f 'src/core/platform/tests/test-cleanup.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-cleanup.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-cleanup.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-ip-entry.obj `if test -f 'src/nmtui/nmt-ip-entry.c'; then $(CYGPATH_W) 'src/nmtui/nmt-ip-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-ip-entry.c'; fi` -src/core/platform/tests/test_cleanup_linux-test-cleanup.o: src/core/platform/tests/test-cleanup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_cleanup_linux-test-cleanup.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Tpo -c -o src/core/platform/tests/test_cleanup_linux-test-cleanup.o `test -f 'src/core/platform/tests/test-cleanup.c' || echo '$(srcdir)/'`src/core/platform/tests/test-cleanup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Tpo src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-cleanup.c' object='src/core/platform/tests/test_cleanup_linux-test-cleanup.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-mac-entry.o: src/nmtui/nmt-mac-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-mac-entry.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-mac-entry.Tpo -c -o src/nmtui/nmtui-nmt-mac-entry.o `test -f 'src/nmtui/nmt-mac-entry.c' || echo '$(srcdir)/'`src/nmtui/nmt-mac-entry.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-mac-entry.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-mac-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-mac-entry.c' object='src/nmtui/nmtui-nmt-mac-entry.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_cleanup_linux-test-cleanup.o `test -f 'src/core/platform/tests/test-cleanup.c' || echo '$(srcdir)/'`src/core/platform/tests/test-cleanup.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-mac-entry.o `test -f 'src/nmtui/nmt-mac-entry.c' || echo '$(srcdir)/'`src/nmtui/nmt-mac-entry.c -src/core/platform/tests/test_cleanup_linux-test-cleanup.obj: src/core/platform/tests/test-cleanup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_cleanup_linux-test-cleanup.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Tpo -c -o src/core/platform/tests/test_cleanup_linux-test-cleanup.obj `if test -f 'src/core/platform/tests/test-cleanup.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-cleanup.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-cleanup.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Tpo src/core/platform/tests/$(DEPDIR)/test_cleanup_linux-test-cleanup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-cleanup.c' object='src/core/platform/tests/test_cleanup_linux-test-cleanup.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-mac-entry.obj: src/nmtui/nmt-mac-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-mac-entry.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-mac-entry.Tpo -c -o src/nmtui/nmtui-nmt-mac-entry.obj `if test -f 'src/nmtui/nmt-mac-entry.c'; then $(CYGPATH_W) 'src/nmtui/nmt-mac-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-mac-entry.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-mac-entry.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-mac-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-mac-entry.c' object='src/nmtui/nmtui-nmt-mac-entry.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_cleanup_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_cleanup_linux-test-cleanup.obj `if test -f 'src/core/platform/tests/test-cleanup.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-cleanup.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-cleanup.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-mac-entry.obj `if test -f 'src/nmtui/nmt-mac-entry.c'; then $(CYGPATH_W) 'src/nmtui/nmt-mac-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-mac-entry.c'; fi` -src/core/platform/tests/test_link_fake-test-link.o: src/core/platform/tests/test-link.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_link_fake-test-link.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Tpo -c -o src/core/platform/tests/test_link_fake-test-link.o `test -f 'src/core/platform/tests/test-link.c' || echo '$(srcdir)/'`src/core/platform/tests/test-link.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Tpo src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-link.c' object='src/core/platform/tests/test_link_fake-test-link.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-mtu-entry.o: src/nmtui/nmt-mtu-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-mtu-entry.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-mtu-entry.Tpo -c -o src/nmtui/nmtui-nmt-mtu-entry.o `test -f 'src/nmtui/nmt-mtu-entry.c' || echo '$(srcdir)/'`src/nmtui/nmt-mtu-entry.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-mtu-entry.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-mtu-entry.c' object='src/nmtui/nmtui-nmt-mtu-entry.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_link_fake-test-link.o `test -f 'src/core/platform/tests/test-link.c' || echo '$(srcdir)/'`src/core/platform/tests/test-link.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-mtu-entry.o `test -f 'src/nmtui/nmt-mtu-entry.c' || echo '$(srcdir)/'`src/nmtui/nmt-mtu-entry.c -src/core/platform/tests/test_link_fake-test-link.obj: src/core/platform/tests/test-link.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_link_fake-test-link.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Tpo -c -o src/core/platform/tests/test_link_fake-test-link.obj `if test -f 'src/core/platform/tests/test-link.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-link.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-link.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Tpo src/core/platform/tests/$(DEPDIR)/test_link_fake-test-link.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-link.c' object='src/core/platform/tests/test_link_fake-test-link.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-mtu-entry.obj: src/nmtui/nmt-mtu-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-mtu-entry.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-mtu-entry.Tpo -c -o src/nmtui/nmtui-nmt-mtu-entry.obj `if test -f 'src/nmtui/nmt-mtu-entry.c'; then $(CYGPATH_W) 'src/nmtui/nmt-mtu-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-mtu-entry.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-mtu-entry.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-mtu-entry.c' object='src/nmtui/nmtui-nmt-mtu-entry.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_link_fake-test-link.obj `if test -f 'src/core/platform/tests/test-link.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-link.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-link.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-mtu-entry.obj `if test -f 'src/nmtui/nmt-mtu-entry.c'; then $(CYGPATH_W) 'src/nmtui/nmt-mtu-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-mtu-entry.c'; fi` -src/core/platform/tests/test_link_linux-test-link.o: src/core/platform/tests/test-link.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_link_linux-test-link.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Tpo -c -o src/core/platform/tests/test_link_linux-test-link.o `test -f 'src/core/platform/tests/test-link.c' || echo '$(srcdir)/'`src/core/platform/tests/test-link.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Tpo src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-link.c' object='src/core/platform/tests/test_link_linux-test-link.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-bond.o: src/nmtui/nmt-page-bond.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-bond.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-bond.Tpo -c -o src/nmtui/nmtui-nmt-page-bond.o `test -f 'src/nmtui/nmt-page-bond.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-bond.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-bond.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-bond.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-bond.c' object='src/nmtui/nmtui-nmt-page-bond.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_link_linux-test-link.o `test -f 'src/core/platform/tests/test-link.c' || echo '$(srcdir)/'`src/core/platform/tests/test-link.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-bond.o `test -f 'src/nmtui/nmt-page-bond.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-bond.c -src/core/platform/tests/test_link_linux-test-link.obj: src/core/platform/tests/test-link.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_link_linux-test-link.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Tpo -c -o src/core/platform/tests/test_link_linux-test-link.obj `if test -f 'src/core/platform/tests/test-link.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-link.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-link.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Tpo src/core/platform/tests/$(DEPDIR)/test_link_linux-test-link.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-link.c' object='src/core/platform/tests/test_link_linux-test-link.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-bond.obj: src/nmtui/nmt-page-bond.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-bond.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-bond.Tpo -c -o src/nmtui/nmtui-nmt-page-bond.obj `if test -f 'src/nmtui/nmt-page-bond.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-bond.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-bond.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-bond.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-bond.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-bond.c' object='src/nmtui/nmtui-nmt-page-bond.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_link_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_link_linux-test-link.obj `if test -f 'src/core/platform/tests/test-link.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-link.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-link.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-bond.obj `if test -f 'src/nmtui/nmt-page-bond.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-bond.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-bond.c'; fi` -src/core/platform/tests/test_nmp_object-test-nmp-object.o: src/core/platform/tests/test-nmp-object.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_nmp_object_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_nmp_object-test-nmp-object.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Tpo -c -o src/core/platform/tests/test_nmp_object-test-nmp-object.o `test -f 'src/core/platform/tests/test-nmp-object.c' || echo '$(srcdir)/'`src/core/platform/tests/test-nmp-object.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Tpo src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-nmp-object.c' object='src/core/platform/tests/test_nmp_object-test-nmp-object.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-bridge.o: src/nmtui/nmt-page-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-bridge.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge.Tpo -c -o src/nmtui/nmtui-nmt-page-bridge.o `test -f 'src/nmtui/nmt-page-bridge.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-bridge.c' object='src/nmtui/nmtui-nmt-page-bridge.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_nmp_object_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_nmp_object-test-nmp-object.o `test -f 'src/core/platform/tests/test-nmp-object.c' || echo '$(srcdir)/'`src/core/platform/tests/test-nmp-object.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-bridge.o `test -f 'src/nmtui/nmt-page-bridge.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-bridge.c -src/core/platform/tests/test_nmp_object-test-nmp-object.obj: src/core/platform/tests/test-nmp-object.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_nmp_object_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_nmp_object-test-nmp-object.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Tpo -c -o src/core/platform/tests/test_nmp_object-test-nmp-object.obj `if test -f 'src/core/platform/tests/test-nmp-object.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-nmp-object.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-nmp-object.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Tpo src/core/platform/tests/$(DEPDIR)/test_nmp_object-test-nmp-object.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-nmp-object.c' object='src/core/platform/tests/test_nmp_object-test-nmp-object.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-bridge.obj: src/nmtui/nmt-page-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-bridge.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge.Tpo -c -o src/nmtui/nmtui-nmt-page-bridge.obj `if test -f 'src/nmtui/nmt-page-bridge.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-bridge.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-bridge.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-bridge.c' object='src/nmtui/nmtui-nmt-page-bridge.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_nmp_object_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_nmp_object-test-nmp-object.obj `if test -f 'src/core/platform/tests/test-nmp-object.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-nmp-object.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-nmp-object.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-bridge.obj `if test -f 'src/nmtui/nmt-page-bridge.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-bridge.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-bridge.c'; fi` -src/core/platform/tests/test_platform_general-test-platform-general.o: src/core/platform/tests/test-platform-general.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_platform_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_platform_general-test-platform-general.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Tpo -c -o src/core/platform/tests/test_platform_general-test-platform-general.o `test -f 'src/core/platform/tests/test-platform-general.c' || echo '$(srcdir)/'`src/core/platform/tests/test-platform-general.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Tpo src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-platform-general.c' object='src/core/platform/tests/test_platform_general-test-platform-general.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-bridge-port.o: src/nmtui/nmt-page-bridge-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-bridge-port.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Tpo -c -o src/nmtui/nmtui-nmt-page-bridge-port.o `test -f 'src/nmtui/nmt-page-bridge-port.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-bridge-port.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-bridge-port.c' object='src/nmtui/nmtui-nmt-page-bridge-port.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_platform_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_platform_general-test-platform-general.o `test -f 'src/core/platform/tests/test-platform-general.c' || echo '$(srcdir)/'`src/core/platform/tests/test-platform-general.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-bridge-port.o `test -f 'src/nmtui/nmt-page-bridge-port.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-bridge-port.c -src/core/platform/tests/test_platform_general-test-platform-general.obj: src/core/platform/tests/test-platform-general.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_platform_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_platform_general-test-platform-general.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Tpo -c -o src/core/platform/tests/test_platform_general-test-platform-general.obj `if test -f 'src/core/platform/tests/test-platform-general.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-platform-general.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-platform-general.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Tpo src/core/platform/tests/$(DEPDIR)/test_platform_general-test-platform-general.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-platform-general.c' object='src/core/platform/tests/test_platform_general-test-platform-general.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-bridge-port.obj: src/nmtui/nmt-page-bridge-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-bridge-port.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Tpo -c -o src/nmtui/nmtui-nmt-page-bridge-port.obj `if test -f 'src/nmtui/nmt-page-bridge-port.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-bridge-port.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-bridge-port.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-bridge-port.c' object='src/nmtui/nmtui-nmt-page-bridge-port.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_platform_general_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_platform_general-test-platform-general.obj `if test -f 'src/core/platform/tests/test-platform-general.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-platform-general.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-platform-general.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-bridge-port.obj `if test -f 'src/nmtui/nmt-page-bridge-port.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-bridge-port.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-bridge-port.c'; fi` -src/core/platform/tests/test_route_fake-test-route.o: src/core/platform/tests/test-route.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_route_fake-test-route.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Tpo -c -o src/core/platform/tests/test_route_fake-test-route.o `test -f 'src/core/platform/tests/test-route.c' || echo '$(srcdir)/'`src/core/platform/tests/test-route.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Tpo src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-route.c' object='src/core/platform/tests/test_route_fake-test-route.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-dsl.o: src/nmtui/nmt-page-dsl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-dsl.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-dsl.Tpo -c -o src/nmtui/nmtui-nmt-page-dsl.o `test -f 'src/nmtui/nmt-page-dsl.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-dsl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-dsl.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-dsl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-dsl.c' object='src/nmtui/nmtui-nmt-page-dsl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_route_fake-test-route.o `test -f 'src/core/platform/tests/test-route.c' || echo '$(srcdir)/'`src/core/platform/tests/test-route.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-dsl.o `test -f 'src/nmtui/nmt-page-dsl.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-dsl.c -src/core/platform/tests/test_route_fake-test-route.obj: src/core/platform/tests/test-route.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_route_fake-test-route.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Tpo -c -o src/core/platform/tests/test_route_fake-test-route.obj `if test -f 'src/core/platform/tests/test-route.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-route.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-route.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Tpo src/core/platform/tests/$(DEPDIR)/test_route_fake-test-route.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-route.c' object='src/core/platform/tests/test_route_fake-test-route.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-dsl.obj: src/nmtui/nmt-page-dsl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-dsl.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-dsl.Tpo -c -o src/nmtui/nmtui-nmt-page-dsl.obj `if test -f 'src/nmtui/nmt-page-dsl.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-dsl.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-dsl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-dsl.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-dsl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-dsl.c' object='src/nmtui/nmtui-nmt-page-dsl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_route_fake-test-route.obj `if test -f 'src/core/platform/tests/test-route.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-route.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-route.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-dsl.obj `if test -f 'src/nmtui/nmt-page-dsl.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-dsl.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-dsl.c'; fi` -src/core/platform/tests/test_route_linux-test-route.o: src/core/platform/tests/test-route.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_route_linux-test-route.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Tpo -c -o src/core/platform/tests/test_route_linux-test-route.o `test -f 'src/core/platform/tests/test-route.c' || echo '$(srcdir)/'`src/core/platform/tests/test-route.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Tpo src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-route.c' object='src/core/platform/tests/test_route_linux-test-route.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-ethernet.o: src/nmtui/nmt-page-ethernet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-ethernet.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-ethernet.Tpo -c -o src/nmtui/nmtui-nmt-page-ethernet.o `test -f 'src/nmtui/nmt-page-ethernet.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-ethernet.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-ethernet.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-ethernet.c' object='src/nmtui/nmtui-nmt-page-ethernet.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_route_linux-test-route.o `test -f 'src/core/platform/tests/test-route.c' || echo '$(srcdir)/'`src/core/platform/tests/test-route.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-ethernet.o `test -f 'src/nmtui/nmt-page-ethernet.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-ethernet.c -src/core/platform/tests/test_route_linux-test-route.obj: src/core/platform/tests/test-route.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_route_linux-test-route.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Tpo -c -o src/core/platform/tests/test_route_linux-test-route.obj `if test -f 'src/core/platform/tests/test-route.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-route.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-route.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Tpo src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-route.c' object='src/core/platform/tests/test_route_linux-test-route.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-ethernet.obj: src/nmtui/nmt-page-ethernet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-ethernet.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-ethernet.Tpo -c -o src/nmtui/nmtui-nmt-page-ethernet.obj `if test -f 'src/nmtui/nmt-page-ethernet.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-ethernet.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-ethernet.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-ethernet.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-ethernet.c' object='src/nmtui/nmtui-nmt-page-ethernet.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_route_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_route_linux-test-route.obj `if test -f 'src/core/platform/tests/test-route.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-route.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-route.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-ethernet.obj `if test -f 'src/nmtui/nmt-page-ethernet.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-ethernet.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-ethernet.c'; fi` -src/core/platform/tests/test_tc_fake-test-tc.o: src/core/platform/tests/test-tc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_tc_fake-test-tc.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Tpo -c -o src/core/platform/tests/test_tc_fake-test-tc.o `test -f 'src/core/platform/tests/test-tc.c' || echo '$(srcdir)/'`src/core/platform/tests/test-tc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Tpo src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-tc.c' object='src/core/platform/tests/test_tc_fake-test-tc.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-infiniband.o: src/nmtui/nmt-page-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-infiniband.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-infiniband.Tpo -c -o src/nmtui/nmtui-nmt-page-infiniband.o `test -f 'src/nmtui/nmt-page-infiniband.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-infiniband.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-infiniband.c' object='src/nmtui/nmtui-nmt-page-infiniband.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_tc_fake-test-tc.o `test -f 'src/core/platform/tests/test-tc.c' || echo '$(srcdir)/'`src/core/platform/tests/test-tc.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-infiniband.o `test -f 'src/nmtui/nmt-page-infiniband.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-infiniband.c -src/core/platform/tests/test_tc_fake-test-tc.obj: src/core/platform/tests/test-tc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_tc_fake-test-tc.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Tpo -c -o src/core/platform/tests/test_tc_fake-test-tc.obj `if test -f 'src/core/platform/tests/test-tc.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-tc.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-tc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Tpo src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-tc.c' object='src/core/platform/tests/test_tc_fake-test-tc.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-infiniband.obj: src/nmtui/nmt-page-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-infiniband.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-infiniband.Tpo -c -o src/nmtui/nmtui-nmt-page-infiniband.obj `if test -f 'src/nmtui/nmt-page-infiniband.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-infiniband.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-infiniband.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-infiniband.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-infiniband.c' object='src/nmtui/nmtui-nmt-page-infiniband.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_fake_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_tc_fake-test-tc.obj `if test -f 'src/core/platform/tests/test-tc.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-tc.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-tc.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-infiniband.obj `if test -f 'src/nmtui/nmt-page-infiniband.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-infiniband.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-infiniband.c'; fi` -src/core/platform/tests/test_tc_linux-test-tc.o: src/core/platform/tests/test-tc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_tc_linux-test-tc.o -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Tpo -c -o src/core/platform/tests/test_tc_linux-test-tc.o `test -f 'src/core/platform/tests/test-tc.c' || echo '$(srcdir)/'`src/core/platform/tests/test-tc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Tpo src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-tc.c' object='src/core/platform/tests/test_tc_linux-test-tc.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-ip-tunnel.o: src/nmtui/nmt-page-ip-tunnel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-ip-tunnel.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Tpo -c -o src/nmtui/nmtui-nmt-page-ip-tunnel.o `test -f 'src/nmtui/nmt-page-ip-tunnel.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-ip-tunnel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-ip-tunnel.c' object='src/nmtui/nmtui-nmt-page-ip-tunnel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_tc_linux-test-tc.o `test -f 'src/core/platform/tests/test-tc.c' || echo '$(srcdir)/'`src/core/platform/tests/test-tc.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-ip-tunnel.o `test -f 'src/nmtui/nmt-page-ip-tunnel.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-ip-tunnel.c -src/core/platform/tests/test_tc_linux-test-tc.obj: src/core/platform/tests/test-tc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/platform/tests/test_tc_linux-test-tc.obj -MD -MP -MF src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Tpo -c -o src/core/platform/tests/test_tc_linux-test-tc.obj `if test -f 'src/core/platform/tests/test-tc.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-tc.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-tc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Tpo src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/platform/tests/test-tc.c' object='src/core/platform/tests/test_tc_linux-test-tc.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-ip-tunnel.obj: src/nmtui/nmt-page-ip-tunnel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-ip-tunnel.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Tpo -c -o src/nmtui/nmtui-nmt-page-ip-tunnel.obj `if test -f 'src/nmtui/nmt-page-ip-tunnel.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-ip-tunnel.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-ip-tunnel.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-ip-tunnel.c' object='src/nmtui/nmtui-nmt-page-ip-tunnel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_platform_tests_test_tc_linux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/platform/tests/test_tc_linux-test-tc.obj `if test -f 'src/core/platform/tests/test-tc.c'; then $(CYGPATH_W) 'src/core/platform/tests/test-tc.c'; else $(CYGPATH_W) '$(srcdir)/src/core/platform/tests/test-tc.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-ip-tunnel.obj `if test -f 'src/nmtui/nmt-page-ip-tunnel.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-ip-tunnel.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-ip-tunnel.c'; fi` -src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.o: src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.o -MD -MP -MF src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo -c -o src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.o `test -f 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c' object='src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-ip4.o: src/nmtui/nmt-page-ip4.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-ip4.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip4.Tpo -c -o src/nmtui/nmtui-nmt-page-ip4.o `test -f 'src/nmtui/nmt-page-ip4.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-ip4.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip4.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip4.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-ip4.c' object='src/nmtui/nmtui-nmt-page-ip4.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.o `test -f 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-ip4.o `test -f 'src/nmtui/nmt-page-ip4.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-ip4.c -src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.obj: src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.obj -MD -MP -MF src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo -c -o src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.obj `if test -f 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; then $(CYGPATH_W) 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo src/core/settings/plugins/ifcfg-rh/tests/$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c' object='src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-ip4.obj: src/nmtui/nmt-page-ip4.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-ip4.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip4.Tpo -c -o src/nmtui/nmtui-nmt-page-ip4.obj `if test -f 'src/nmtui/nmt-page-ip4.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-ip4.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-ip4.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip4.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip4.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-ip4.c' object='src/nmtui/nmtui-nmt-page-ip4.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifcfg-rh/tests/test_ifcfg_rh-test-ifcfg-rh.obj `if test -f 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; then $(CYGPATH_W) 'src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-ip4.obj `if test -f 'src/nmtui/nmt-page-ip4.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-ip4.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-ip4.c'; fi` -src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.o: src/core/settings/plugins/ifupdown/tests/test-ifupdown.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_tests_test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.o -MD -MP -MF src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Tpo -c -o src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.o `test -f 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/tests/test-ifupdown.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Tpo src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifupdown/tests/test-ifupdown.c' object='src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-ip6.o: src/nmtui/nmt-page-ip6.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-ip6.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip6.Tpo -c -o src/nmtui/nmtui-nmt-page-ip6.o `test -f 'src/nmtui/nmt-page-ip6.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-ip6.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip6.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip6.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-ip6.c' object='src/nmtui/nmtui-nmt-page-ip6.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_tests_test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.o `test -f 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c' || echo '$(srcdir)/'`src/core/settings/plugins/ifupdown/tests/test-ifupdown.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-ip6.o `test -f 'src/nmtui/nmt-page-ip6.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-ip6.c -src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.obj: src/core/settings/plugins/ifupdown/tests/test-ifupdown.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_tests_test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.obj -MD -MP -MF src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Tpo -c -o src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.obj `if test -f 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; then $(CYGPATH_W) 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Tpo src/core/settings/plugins/ifupdown/tests/$(DEPDIR)/test_ifupdown-test-ifupdown.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/ifupdown/tests/test-ifupdown.c' object='src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-ip6.obj: src/nmtui/nmt-page-ip6.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-ip6.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip6.Tpo -c -o src/nmtui/nmtui-nmt-page-ip6.obj `if test -f 'src/nmtui/nmt-page-ip6.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-ip6.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-ip6.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip6.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip6.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-ip6.c' object='src/nmtui/nmtui-nmt-page-ip6.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_ifupdown_tests_test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/ifupdown/tests/test_ifupdown-test-ifupdown.obj `if test -f 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; then $(CYGPATH_W) 'src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-ip6.obj `if test -f 'src/nmtui/nmt-page-ip6.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-ip6.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-ip6.c'; fi` -src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.o: src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.o -MD -MP -MF src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Tpo -c -o src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.o `test -f 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Tpo src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c' object='src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-ppp.o: src/nmtui/nmt-page-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-ppp.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-ppp.Tpo -c -o src/nmtui/nmtui-nmt-page-ppp.o `test -f 'src/nmtui/nmt-page-ppp.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-ppp.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-ppp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-ppp.c' object='src/nmtui/nmtui-nmt-page-ppp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.o `test -f 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c' || echo '$(srcdir)/'`src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-ppp.o `test -f 'src/nmtui/nmt-page-ppp.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-ppp.c -src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.obj: src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.obj -MD -MP -MF src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Tpo -c -o src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.obj `if test -f 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; then $(CYGPATH_W) 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Tpo src/core/settings/plugins/keyfile/tests/$(DEPDIR)/test_keyfile_settings-test-keyfile-settings.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c' object='src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-ppp.obj: src/nmtui/nmt-page-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-ppp.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-ppp.Tpo -c -o src/nmtui/nmtui-nmt-page-ppp.obj `if test -f 'src/nmtui/nmt-page-ppp.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-ppp.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-ppp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-ppp.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-ppp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-ppp.c' object='src/nmtui/nmtui-nmt-page-ppp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/settings/plugins/keyfile/tests/test_keyfile_settings-test-keyfile-settings.obj `if test -f 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; then $(CYGPATH_W) 'src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; else $(CYGPATH_W) '$(srcdir)/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-ppp.obj `if test -f 'src/nmtui/nmt-page-ppp.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-ppp.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-ppp.c'; fi` -src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.o: src/core/supplicant/tests/test-supplicant-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_supplicant_tests_test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.o -MD -MP -MF src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo -c -o src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.o `test -f 'src/core/supplicant/tests/test-supplicant-config.c' || echo '$(srcdir)/'`src/core/supplicant/tests/test-supplicant-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/tests/test-supplicant-config.c' object='src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-team.o: src/nmtui/nmt-page-team.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-team.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-team.Tpo -c -o src/nmtui/nmtui-nmt-page-team.o `test -f 'src/nmtui/nmt-page-team.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-team.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-team.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-team.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-team.c' object='src/nmtui/nmtui-nmt-page-team.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_supplicant_tests_test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.o `test -f 'src/core/supplicant/tests/test-supplicant-config.c' || echo '$(srcdir)/'`src/core/supplicant/tests/test-supplicant-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-team.o `test -f 'src/nmtui/nmt-page-team.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-team.c -src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.obj: src/core/supplicant/tests/test-supplicant-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_supplicant_tests_test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.obj -MD -MP -MF src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo -c -o src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.obj `if test -f 'src/core/supplicant/tests/test-supplicant-config.c'; then $(CYGPATH_W) 'src/core/supplicant/tests/test-supplicant-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/supplicant/tests/test-supplicant-config.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Tpo src/core/supplicant/tests/$(DEPDIR)/test_supplicant_config-test-supplicant-config.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/supplicant/tests/test-supplicant-config.c' object='src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-team.obj: src/nmtui/nmt-page-team.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-team.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-team.Tpo -c -o src/nmtui/nmtui-nmt-page-team.obj `if test -f 'src/nmtui/nmt-page-team.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-team.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-team.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-team.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-team.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-team.c' object='src/nmtui/nmtui-nmt-page-team.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_supplicant_tests_test_supplicant_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/supplicant/tests/test_supplicant_config-test-supplicant-config.obj `if test -f 'src/core/supplicant/tests/test-supplicant-config.c'; then $(CYGPATH_W) 'src/core/supplicant/tests/test-supplicant-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/supplicant/tests/test-supplicant-config.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-team.obj `if test -f 'src/nmtui/nmt-page-team.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-team.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-team.c'; fi` -src/core/tests/config/test_config-nm-test-device.o: src/core/tests/config/nm-test-device.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/config/test_config-nm-test-device.o -MD -MP -MF src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Tpo -c -o src/core/tests/config/test_config-nm-test-device.o `test -f 'src/core/tests/config/nm-test-device.c' || echo '$(srcdir)/'`src/core/tests/config/nm-test-device.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Tpo src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/config/nm-test-device.c' object='src/core/tests/config/test_config-nm-test-device.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-team-port.o: src/nmtui/nmt-page-team-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-team-port.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-team-port.Tpo -c -o src/nmtui/nmtui-nmt-page-team-port.o `test -f 'src/nmtui/nmt-page-team-port.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-team-port.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-team-port.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-team-port.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-team-port.c' object='src/nmtui/nmtui-nmt-page-team-port.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/config/test_config-nm-test-device.o `test -f 'src/core/tests/config/nm-test-device.c' || echo '$(srcdir)/'`src/core/tests/config/nm-test-device.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-team-port.o `test -f 'src/nmtui/nmt-page-team-port.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-team-port.c -src/core/tests/config/test_config-nm-test-device.obj: src/core/tests/config/nm-test-device.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/config/test_config-nm-test-device.obj -MD -MP -MF src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Tpo -c -o src/core/tests/config/test_config-nm-test-device.obj `if test -f 'src/core/tests/config/nm-test-device.c'; then $(CYGPATH_W) 'src/core/tests/config/nm-test-device.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/config/nm-test-device.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Tpo src/core/tests/config/$(DEPDIR)/test_config-nm-test-device.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/config/nm-test-device.c' object='src/core/tests/config/test_config-nm-test-device.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-team-port.obj: src/nmtui/nmt-page-team-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-team-port.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-team-port.Tpo -c -o src/nmtui/nmtui-nmt-page-team-port.obj `if test -f 'src/nmtui/nmt-page-team-port.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-team-port.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-team-port.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-team-port.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-team-port.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-team-port.c' object='src/nmtui/nmtui-nmt-page-team-port.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/config/test_config-nm-test-device.obj `if test -f 'src/core/tests/config/nm-test-device.c'; then $(CYGPATH_W) 'src/core/tests/config/nm-test-device.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/config/nm-test-device.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-team-port.obj `if test -f 'src/nmtui/nmt-page-team-port.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-team-port.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-team-port.c'; fi` -src/core/tests/config/test_config-test-config.o: src/core/tests/config/test-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/config/test_config-test-config.o -MD -MP -MF src/core/tests/config/$(DEPDIR)/test_config-test-config.Tpo -c -o src/core/tests/config/test_config-test-config.o `test -f 'src/core/tests/config/test-config.c' || echo '$(srcdir)/'`src/core/tests/config/test-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/config/$(DEPDIR)/test_config-test-config.Tpo src/core/tests/config/$(DEPDIR)/test_config-test-config.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/config/test-config.c' object='src/core/tests/config/test_config-test-config.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-vlan.o: src/nmtui/nmt-page-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-vlan.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-vlan.Tpo -c -o src/nmtui/nmtui-nmt-page-vlan.o `test -f 'src/nmtui/nmt-page-vlan.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-vlan.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-vlan.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-vlan.c' object='src/nmtui/nmtui-nmt-page-vlan.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/config/test_config-test-config.o `test -f 'src/core/tests/config/test-config.c' || echo '$(srcdir)/'`src/core/tests/config/test-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-vlan.o `test -f 'src/nmtui/nmt-page-vlan.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-vlan.c -src/core/tests/config/test_config-test-config.obj: src/core/tests/config/test-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/config/test_config-test-config.obj -MD -MP -MF src/core/tests/config/$(DEPDIR)/test_config-test-config.Tpo -c -o src/core/tests/config/test_config-test-config.obj `if test -f 'src/core/tests/config/test-config.c'; then $(CYGPATH_W) 'src/core/tests/config/test-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/config/test-config.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/config/$(DEPDIR)/test_config-test-config.Tpo src/core/tests/config/$(DEPDIR)/test_config-test-config.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/config/test-config.c' object='src/core/tests/config/test_config-test-config.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-vlan.obj: src/nmtui/nmt-page-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-vlan.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-vlan.Tpo -c -o src/nmtui/nmtui-nmt-page-vlan.obj `if test -f 'src/nmtui/nmt-page-vlan.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-vlan.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-vlan.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-vlan.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-vlan.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-vlan.c' object='src/nmtui/nmtui-nmt-page-vlan.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_config_test_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/config/test_config-test-config.obj `if test -f 'src/core/tests/config/test-config.c'; then $(CYGPATH_W) 'src/core/tests/config/test-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/config/test-config.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-vlan.obj `if test -f 'src/nmtui/nmt-page-vlan.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-vlan.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-vlan.c'; fi` -src/core/tests/test_core-test-core.o: src/core/tests/test-core.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_core-test-core.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_core-test-core.Tpo -c -o src/core/tests/test_core-test-core.o `test -f 'src/core/tests/test-core.c' || echo '$(srcdir)/'`src/core/tests/test-core.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_core-test-core.Tpo src/core/tests/$(DEPDIR)/test_core-test-core.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-core.c' object='src/core/tests/test_core-test-core.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-wifi.o: src/nmtui/nmt-page-wifi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-wifi.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-wifi.Tpo -c -o src/nmtui/nmtui-nmt-page-wifi.o `test -f 'src/nmtui/nmt-page-wifi.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-wifi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-wifi.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-wifi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-wifi.c' object='src/nmtui/nmtui-nmt-page-wifi.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_core-test-core.o `test -f 'src/core/tests/test-core.c' || echo '$(srcdir)/'`src/core/tests/test-core.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-wifi.o `test -f 'src/nmtui/nmt-page-wifi.c' || echo '$(srcdir)/'`src/nmtui/nmt-page-wifi.c -src/core/tests/test_core-test-core.obj: src/core/tests/test-core.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_core-test-core.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_core-test-core.Tpo -c -o src/core/tests/test_core-test-core.obj `if test -f 'src/core/tests/test-core.c'; then $(CYGPATH_W) 'src/core/tests/test-core.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-core.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_core-test-core.Tpo src/core/tests/$(DEPDIR)/test_core-test-core.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-core.c' object='src/core/tests/test_core-test-core.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-page-wifi.obj: src/nmtui/nmt-page-wifi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-page-wifi.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-page-wifi.Tpo -c -o src/nmtui/nmtui-nmt-page-wifi.obj `if test -f 'src/nmtui/nmt-page-wifi.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-wifi.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-wifi.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-page-wifi.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-page-wifi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-page-wifi.c' object='src/nmtui/nmtui-nmt-page-wifi.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_core-test-core.obj `if test -f 'src/core/tests/test-core.c'; then $(CYGPATH_W) 'src/core/tests/test-core.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-core.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-page-wifi.obj `if test -f 'src/nmtui/nmt-page-wifi.c'; then $(CYGPATH_W) 'src/nmtui/nmt-page-wifi.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-page-wifi.c'; fi` -src/core/tests/test_core_with_expect-test-core-with-expect.o: src/core/tests/test-core-with-expect.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_with_expect_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_core_with_expect-test-core-with-expect.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Tpo -c -o src/core/tests/test_core_with_expect-test-core-with-expect.o `test -f 'src/core/tests/test-core-with-expect.c' || echo '$(srcdir)/'`src/core/tests/test-core-with-expect.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Tpo src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-core-with-expect.c' object='src/core/tests/test_core_with_expect-test-core-with-expect.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-password-dialog.o: src/nmtui/nmt-password-dialog.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-password-dialog.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-password-dialog.Tpo -c -o src/nmtui/nmtui-nmt-password-dialog.o `test -f 'src/nmtui/nmt-password-dialog.c' || echo '$(srcdir)/'`src/nmtui/nmt-password-dialog.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-password-dialog.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-password-dialog.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-password-dialog.c' object='src/nmtui/nmtui-nmt-password-dialog.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_with_expect_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_core_with_expect-test-core-with-expect.o `test -f 'src/core/tests/test-core-with-expect.c' || echo '$(srcdir)/'`src/core/tests/test-core-with-expect.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-password-dialog.o `test -f 'src/nmtui/nmt-password-dialog.c' || echo '$(srcdir)/'`src/nmtui/nmt-password-dialog.c -src/core/tests/test_core_with_expect-test-core-with-expect.obj: src/core/tests/test-core-with-expect.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_with_expect_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_core_with_expect-test-core-with-expect.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Tpo -c -o src/core/tests/test_core_with_expect-test-core-with-expect.obj `if test -f 'src/core/tests/test-core-with-expect.c'; then $(CYGPATH_W) 'src/core/tests/test-core-with-expect.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-core-with-expect.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Tpo src/core/tests/$(DEPDIR)/test_core_with_expect-test-core-with-expect.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-core-with-expect.c' object='src/core/tests/test_core_with_expect-test-core-with-expect.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-password-dialog.obj: src/nmtui/nmt-password-dialog.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-password-dialog.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-password-dialog.Tpo -c -o src/nmtui/nmtui-nmt-password-dialog.obj `if test -f 'src/nmtui/nmt-password-dialog.c'; then $(CYGPATH_W) 'src/nmtui/nmt-password-dialog.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-password-dialog.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-password-dialog.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-password-dialog.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-password-dialog.c' object='src/nmtui/nmtui-nmt-password-dialog.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_core_with_expect_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_core_with_expect-test-core-with-expect.obj `if test -f 'src/core/tests/test-core-with-expect.c'; then $(CYGPATH_W) 'src/core/tests/test-core-with-expect.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-core-with-expect.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-password-dialog.obj `if test -f 'src/nmtui/nmt-password-dialog.c'; then $(CYGPATH_W) 'src/nmtui/nmt-password-dialog.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-password-dialog.c'; fi` -src/core/tests/test_dcb-test-dcb.o: src/core/tests/test-dcb.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_dcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_dcb-test-dcb.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Tpo -c -o src/core/tests/test_dcb-test-dcb.o `test -f 'src/core/tests/test-dcb.c' || echo '$(srcdir)/'`src/core/tests/test-dcb.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Tpo src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-dcb.c' object='src/core/tests/test_dcb-test-dcb.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-password-fields.o: src/nmtui/nmt-password-fields.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-password-fields.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-password-fields.Tpo -c -o src/nmtui/nmtui-nmt-password-fields.o `test -f 'src/nmtui/nmt-password-fields.c' || echo '$(srcdir)/'`src/nmtui/nmt-password-fields.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-password-fields.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-password-fields.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-password-fields.c' object='src/nmtui/nmtui-nmt-password-fields.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_dcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_dcb-test-dcb.o `test -f 'src/core/tests/test-dcb.c' || echo '$(srcdir)/'`src/core/tests/test-dcb.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-password-fields.o `test -f 'src/nmtui/nmt-password-fields.c' || echo '$(srcdir)/'`src/nmtui/nmt-password-fields.c -src/core/tests/test_dcb-test-dcb.obj: src/core/tests/test-dcb.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_dcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_dcb-test-dcb.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Tpo -c -o src/core/tests/test_dcb-test-dcb.obj `if test -f 'src/core/tests/test-dcb.c'; then $(CYGPATH_W) 'src/core/tests/test-dcb.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-dcb.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Tpo src/core/tests/$(DEPDIR)/test_dcb-test-dcb.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-dcb.c' object='src/core/tests/test_dcb-test-dcb.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-password-fields.obj: src/nmtui/nmt-password-fields.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-password-fields.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-password-fields.Tpo -c -o src/nmtui/nmtui-nmt-password-fields.obj `if test -f 'src/nmtui/nmt-password-fields.c'; then $(CYGPATH_W) 'src/nmtui/nmt-password-fields.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-password-fields.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-password-fields.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-password-fields.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-password-fields.c' object='src/nmtui/nmtui-nmt-password-fields.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_dcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_dcb-test-dcb.obj `if test -f 'src/core/tests/test-dcb.c'; then $(CYGPATH_W) 'src/core/tests/test-dcb.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-dcb.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-password-fields.obj `if test -f 'src/nmtui/nmt-password-fields.c'; then $(CYGPATH_W) 'src/nmtui/nmt-password-fields.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-password-fields.c'; fi` -src/core/tests/test_ip4_config-test-ip4-config.o: src/core/tests/test-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip4_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_ip4_config-test-ip4-config.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Tpo -c -o src/core/tests/test_ip4_config-test-ip4-config.o `test -f 'src/core/tests/test-ip4-config.c' || echo '$(srcdir)/'`src/core/tests/test-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Tpo src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-ip4-config.c' object='src/core/tests/test_ip4_config-test-ip4-config.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-route-editor.o: src/nmtui/nmt-route-editor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-route-editor.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-route-editor.Tpo -c -o src/nmtui/nmtui-nmt-route-editor.o `test -f 'src/nmtui/nmt-route-editor.c' || echo '$(srcdir)/'`src/nmtui/nmt-route-editor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-route-editor.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-route-editor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-route-editor.c' object='src/nmtui/nmtui-nmt-route-editor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip4_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_ip4_config-test-ip4-config.o `test -f 'src/core/tests/test-ip4-config.c' || echo '$(srcdir)/'`src/core/tests/test-ip4-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-route-editor.o `test -f 'src/nmtui/nmt-route-editor.c' || echo '$(srcdir)/'`src/nmtui/nmt-route-editor.c -src/core/tests/test_ip4_config-test-ip4-config.obj: src/core/tests/test-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip4_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_ip4_config-test-ip4-config.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Tpo -c -o src/core/tests/test_ip4_config-test-ip4-config.obj `if test -f 'src/core/tests/test-ip4-config.c'; then $(CYGPATH_W) 'src/core/tests/test-ip4-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-ip4-config.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Tpo src/core/tests/$(DEPDIR)/test_ip4_config-test-ip4-config.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-ip4-config.c' object='src/core/tests/test_ip4_config-test-ip4-config.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-route-editor.obj: src/nmtui/nmt-route-editor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-route-editor.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-route-editor.Tpo -c -o src/nmtui/nmtui-nmt-route-editor.obj `if test -f 'src/nmtui/nmt-route-editor.c'; then $(CYGPATH_W) 'src/nmtui/nmt-route-editor.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-route-editor.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-route-editor.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-route-editor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-route-editor.c' object='src/nmtui/nmtui-nmt-route-editor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip4_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_ip4_config-test-ip4-config.obj `if test -f 'src/core/tests/test-ip4-config.c'; then $(CYGPATH_W) 'src/core/tests/test-ip4-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-ip4-config.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-route-editor.obj `if test -f 'src/nmtui/nmt-route-editor.c'; then $(CYGPATH_W) 'src/nmtui/nmt-route-editor.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-route-editor.c'; fi` -src/core/tests/test_ip6_config-test-ip6-config.o: src/core/tests/test-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip6_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_ip6_config-test-ip6-config.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Tpo -c -o src/core/tests/test_ip6_config-test-ip6-config.o `test -f 'src/core/tests/test-ip6-config.c' || echo '$(srcdir)/'`src/core/tests/test-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Tpo src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-ip6-config.c' object='src/core/tests/test_ip6_config-test-ip6-config.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-route-entry.o: src/nmtui/nmt-route-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-route-entry.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-route-entry.Tpo -c -o src/nmtui/nmtui-nmt-route-entry.o `test -f 'src/nmtui/nmt-route-entry.c' || echo '$(srcdir)/'`src/nmtui/nmt-route-entry.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-route-entry.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-route-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-route-entry.c' object='src/nmtui/nmtui-nmt-route-entry.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip6_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_ip6_config-test-ip6-config.o `test -f 'src/core/tests/test-ip6-config.c' || echo '$(srcdir)/'`src/core/tests/test-ip6-config.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-route-entry.o `test -f 'src/nmtui/nmt-route-entry.c' || echo '$(srcdir)/'`src/nmtui/nmt-route-entry.c -src/core/tests/test_ip6_config-test-ip6-config.obj: src/core/tests/test-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip6_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_ip6_config-test-ip6-config.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Tpo -c -o src/core/tests/test_ip6_config-test-ip6-config.obj `if test -f 'src/core/tests/test-ip6-config.c'; then $(CYGPATH_W) 'src/core/tests/test-ip6-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-ip6-config.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Tpo src/core/tests/$(DEPDIR)/test_ip6_config-test-ip6-config.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-ip6-config.c' object='src/core/tests/test_ip6_config-test-ip6-config.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-route-entry.obj: src/nmtui/nmt-route-entry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-route-entry.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-route-entry.Tpo -c -o src/nmtui/nmtui-nmt-route-entry.obj `if test -f 'src/nmtui/nmt-route-entry.c'; then $(CYGPATH_W) 'src/nmtui/nmt-route-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-route-entry.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-route-entry.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-route-entry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-route-entry.c' object='src/nmtui/nmtui-nmt-route-entry.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_ip6_config_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_ip6_config-test-ip6-config.obj `if test -f 'src/core/tests/test-ip6-config.c'; then $(CYGPATH_W) 'src/core/tests/test-ip6-config.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-ip6-config.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-route-entry.obj `if test -f 'src/nmtui/nmt-route-entry.c'; then $(CYGPATH_W) 'src/nmtui/nmt-route-entry.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-route-entry.c'; fi` -src/core/tests/test_l3cfg-test-l3cfg.o: src/core/tests/test-l3cfg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_l3cfg_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_l3cfg-test-l3cfg.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Tpo -c -o src/core/tests/test_l3cfg-test-l3cfg.o `test -f 'src/core/tests/test-l3cfg.c' || echo '$(srcdir)/'`src/core/tests/test-l3cfg.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Tpo src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-l3cfg.c' object='src/core/tests/test_l3cfg-test-l3cfg.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-route-table.o: src/nmtui/nmt-route-table.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-route-table.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-route-table.Tpo -c -o src/nmtui/nmtui-nmt-route-table.o `test -f 'src/nmtui/nmt-route-table.c' || echo '$(srcdir)/'`src/nmtui/nmt-route-table.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-route-table.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-route-table.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-route-table.c' object='src/nmtui/nmtui-nmt-route-table.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_l3cfg_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_l3cfg-test-l3cfg.o `test -f 'src/core/tests/test-l3cfg.c' || echo '$(srcdir)/'`src/core/tests/test-l3cfg.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-route-table.o `test -f 'src/nmtui/nmt-route-table.c' || echo '$(srcdir)/'`src/nmtui/nmt-route-table.c -src/core/tests/test_l3cfg-test-l3cfg.obj: src/core/tests/test-l3cfg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_l3cfg_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_l3cfg-test-l3cfg.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Tpo -c -o src/core/tests/test_l3cfg-test-l3cfg.obj `if test -f 'src/core/tests/test-l3cfg.c'; then $(CYGPATH_W) 'src/core/tests/test-l3cfg.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-l3cfg.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Tpo src/core/tests/$(DEPDIR)/test_l3cfg-test-l3cfg.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-l3cfg.c' object='src/core/tests/test_l3cfg-test-l3cfg.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-route-table.obj: src/nmtui/nmt-route-table.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-route-table.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-route-table.Tpo -c -o src/nmtui/nmtui-nmt-route-table.obj `if test -f 'src/nmtui/nmt-route-table.c'; then $(CYGPATH_W) 'src/nmtui/nmt-route-table.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-route-table.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-route-table.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-route-table.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-route-table.c' object='src/nmtui/nmtui-nmt-route-table.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_l3cfg_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_l3cfg-test-l3cfg.obj `if test -f 'src/core/tests/test-l3cfg.c'; then $(CYGPATH_W) 'src/core/tests/test-l3cfg.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-l3cfg.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-route-table.obj `if test -f 'src/nmtui/nmt-route-table.c'; then $(CYGPATH_W) 'src/nmtui/nmt-route-table.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-route-table.c'; fi` -src/core/tests/test_systemd-test-systemd.o: src/core/tests/test-systemd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_systemd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_systemd-test-systemd.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Tpo -c -o src/core/tests/test_systemd-test-systemd.o `test -f 'src/core/tests/test-systemd.c' || echo '$(srcdir)/'`src/core/tests/test-systemd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Tpo src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-systemd.c' object='src/core/tests/test_systemd-test-systemd.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-slave-list.o: src/nmtui/nmt-slave-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-slave-list.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-slave-list.Tpo -c -o src/nmtui/nmtui-nmt-slave-list.o `test -f 'src/nmtui/nmt-slave-list.c' || echo '$(srcdir)/'`src/nmtui/nmt-slave-list.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-slave-list.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-slave-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-slave-list.c' object='src/nmtui/nmtui-nmt-slave-list.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_systemd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_systemd-test-systemd.o `test -f 'src/core/tests/test-systemd.c' || echo '$(srcdir)/'`src/core/tests/test-systemd.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-slave-list.o `test -f 'src/nmtui/nmt-slave-list.c' || echo '$(srcdir)/'`src/nmtui/nmt-slave-list.c -src/core/tests/test_systemd-test-systemd.obj: src/core/tests/test-systemd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_systemd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_systemd-test-systemd.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Tpo -c -o src/core/tests/test_systemd-test-systemd.obj `if test -f 'src/core/tests/test-systemd.c'; then $(CYGPATH_W) 'src/core/tests/test-systemd.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-systemd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Tpo src/core/tests/$(DEPDIR)/test_systemd-test-systemd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-systemd.c' object='src/core/tests/test_systemd-test-systemd.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-slave-list.obj: src/nmtui/nmt-slave-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-slave-list.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-slave-list.Tpo -c -o src/nmtui/nmtui-nmt-slave-list.obj `if test -f 'src/nmtui/nmt-slave-list.c'; then $(CYGPATH_W) 'src/nmtui/nmt-slave-list.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-slave-list.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-slave-list.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-slave-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-slave-list.c' object='src/nmtui/nmtui-nmt-slave-list.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_systemd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_systemd-test-systemd.obj `if test -f 'src/core/tests/test-systemd.c'; then $(CYGPATH_W) 'src/core/tests/test-systemd.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-systemd.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-slave-list.obj `if test -f 'src/nmtui/nmt-slave-list.c'; then $(CYGPATH_W) 'src/nmtui/nmt-slave-list.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-slave-list.c'; fi` -src/core/tests/test_utils-test-utils.o: src/core/tests/test-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_utils-test-utils.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_utils-test-utils.Tpo -c -o src/core/tests/test_utils-test-utils.o `test -f 'src/core/tests/test-utils.c' || echo '$(srcdir)/'`src/core/tests/test-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_utils-test-utils.Tpo src/core/tests/$(DEPDIR)/test_utils-test-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-utils.c' object='src/core/tests/test_utils-test-utils.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-utils.o: src/nmtui/nmt-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-utils.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-utils.Tpo -c -o src/nmtui/nmtui-nmt-utils.o `test -f 'src/nmtui/nmt-utils.c' || echo '$(srcdir)/'`src/nmtui/nmt-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-utils.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-utils.c' object='src/nmtui/nmtui-nmt-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_utils-test-utils.o `test -f 'src/core/tests/test-utils.c' || echo '$(srcdir)/'`src/core/tests/test-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-utils.o `test -f 'src/nmtui/nmt-utils.c' || echo '$(srcdir)/'`src/nmtui/nmt-utils.c -src/core/tests/test_utils-test-utils.obj: src/core/tests/test-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_utils-test-utils.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_utils-test-utils.Tpo -c -o src/core/tests/test_utils-test-utils.obj `if test -f 'src/core/tests/test-utils.c'; then $(CYGPATH_W) 'src/core/tests/test-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_utils-test-utils.Tpo src/core/tests/$(DEPDIR)/test_utils-test-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-utils.c' object='src/core/tests/test_utils-test-utils.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-utils.obj: src/nmtui/nmt-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-utils.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-utils.Tpo -c -o src/nmtui/nmtui-nmt-utils.obj `if test -f 'src/nmtui/nmt-utils.c'; then $(CYGPATH_W) 'src/nmtui/nmt-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-utils.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-utils.c' object='src/nmtui/nmtui-nmt-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_utils-test-utils.obj `if test -f 'src/core/tests/test-utils.c'; then $(CYGPATH_W) 'src/core/tests/test-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-utils.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-utils.obj `if test -f 'src/nmtui/nmt-utils.c'; then $(CYGPATH_W) 'src/nmtui/nmt-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-utils.c'; fi` -src/core/tests/test_wired_defname-test-wired-defname.o: src/core/tests/test-wired-defname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_wired_defname-test-wired-defname.o -MD -MP -MF src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Tpo -c -o src/core/tests/test_wired_defname-test-wired-defname.o `test -f 'src/core/tests/test-wired-defname.c' || echo '$(srcdir)/'`src/core/tests/test-wired-defname.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Tpo src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-wired-defname.c' object='src/core/tests/test_wired_defname-test-wired-defname.o' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-widget-list.o: src/nmtui/nmt-widget-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-widget-list.o -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-widget-list.Tpo -c -o src/nmtui/nmtui-nmt-widget-list.o `test -f 'src/nmtui/nmt-widget-list.c' || echo '$(srcdir)/'`src/nmtui/nmt-widget-list.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-widget-list.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-widget-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-widget-list.c' object='src/nmtui/nmtui-nmt-widget-list.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_wired_defname-test-wired-defname.o `test -f 'src/core/tests/test-wired-defname.c' || echo '$(srcdir)/'`src/core/tests/test-wired-defname.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-widget-list.o `test -f 'src/nmtui/nmt-widget-list.c' || echo '$(srcdir)/'`src/nmtui/nmt-widget-list.c -src/core/tests/test_wired_defname-test-wired-defname.obj: src/core/tests/test-wired-defname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/core/tests/test_wired_defname-test-wired-defname.obj -MD -MP -MF src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Tpo -c -o src/core/tests/test_wired_defname-test-wired-defname.obj `if test -f 'src/core/tests/test-wired-defname.c'; then $(CYGPATH_W) 'src/core/tests/test-wired-defname.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-wired-defname.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Tpo src/core/tests/$(DEPDIR)/test_wired_defname-test-wired-defname.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/core/tests/test-wired-defname.c' object='src/core/tests/test_wired_defname-test-wired-defname.obj' libtool=no @AMDEPBACKSLASH@ +src/nmtui/nmtui-nmt-widget-list.obj: src/nmtui/nmt-widget-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/nmtui/nmtui-nmt-widget-list.obj -MD -MP -MF src/nmtui/$(DEPDIR)/nmtui-nmt-widget-list.Tpo -c -o src/nmtui/nmtui-nmt-widget-list.obj `if test -f 'src/nmtui/nmt-widget-list.c'; then $(CYGPATH_W) 'src/nmtui/nmt-widget-list.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-widget-list.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/nmtui/$(DEPDIR)/nmtui-nmt-widget-list.Tpo src/nmtui/$(DEPDIR)/nmtui-nmt-widget-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/nmtui/nmt-widget-list.c' object='src/nmtui/nmtui-nmt-widget-list.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_core_tests_test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/core/tests/test_wired_defname-test-wired-defname.obj `if test -f 'src/core/tests/test-wired-defname.c'; then $(CYGPATH_W) 'src/core/tests/test-wired-defname.c'; else $(CYGPATH_W) '$(srcdir)/src/core/tests/test-wired-defname.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_nmtui_nmtui_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/nmtui/nmtui-nmt-widget-list.obj `if test -f 'src/nmtui/nmt-widget-list.c'; then $(CYGPATH_W) 'src/nmtui/nmt-widget-list.c'; else $(CYGPATH_W) '$(srcdir)/src/nmtui/nmt-widget-list.c'; fi` .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -17503,44 +17687,15 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs - -rm -rf clients/.libs clients/_libs - -rm -rf clients/cli/.libs clients/cli/_libs - -rm -rf clients/cloud-setup/.libs clients/cloud-setup/_libs - -rm -rf clients/cloud-setup/tests/.libs clients/cloud-setup/tests/_libs - -rm -rf clients/common/.libs clients/common/_libs - -rm -rf clients/common/tests/.libs clients/common/tests/_libs - -rm -rf clients/tui/.libs clients/tui/_libs - -rm -rf dispatcher/.libs dispatcher/_libs - -rm -rf dispatcher/tests/.libs dispatcher/tests/_libs -rm -rf examples/C/glib/.libs examples/C/glib/_libs -rm -rf examples/C/qt/.libs examples/C/qt/_libs -rm -rf introspection/.libs introspection/_libs - -rm -rf libnm/.libs libnm/_libs - -rm -rf libnm-core/.libs libnm-core/_libs - -rm -rf libnm-core/nm-libnm-core-aux/.libs libnm-core/nm-libnm-core-aux/_libs - -rm -rf libnm-core/nm-libnm-core-intern/.libs libnm-core/nm-libnm-core-intern/_libs - -rm -rf libnm-core/tests/.libs libnm-core/tests/_libs - -rm -rf libnm/nm-libnm-aux/.libs libnm/nm-libnm-aux/_libs - -rm -rf libnm/tests/.libs libnm/tests/_libs - -rm -rf shared/.libs shared/_libs - -rm -rf shared/c-rbtree/src/.libs shared/c-rbtree/src/_libs - -rm -rf shared/c-siphash/src/.libs shared/c-siphash/src/_libs - -rm -rf shared/n-acd/src/.libs shared/n-acd/src/_libs - -rm -rf shared/n-acd/src/util/.libs shared/n-acd/src/util/_libs - -rm -rf shared/n-dhcp4/src/.libs shared/n-dhcp4/src/_libs - -rm -rf shared/n-dhcp4/src/util/.libs shared/n-dhcp4/src/util/_libs - -rm -rf shared/nm-base/.libs shared/nm-base/_libs - -rm -rf shared/nm-glib-aux/.libs shared/nm-glib-aux/_libs - -rm -rf shared/nm-glib-aux/tests/.libs shared/nm-glib-aux/tests/_libs - -rm -rf shared/nm-log-core/.libs shared/nm-log-core/_libs - -rm -rf shared/nm-platform/.libs shared/nm-platform/_libs - -rm -rf shared/nm-platform/tests/.libs shared/nm-platform/tests/_libs - -rm -rf shared/nm-std-aux/.libs shared/nm-std-aux/_libs - -rm -rf shared/nm-udev-aux/.libs shared/nm-udev-aux/_libs - -rm -rf shared/nm-utils/.libs shared/nm-utils/_libs - -rm -rf shared/systemd/.libs shared/systemd/_libs - -rm -rf shared/systemd/src/basic/.libs shared/systemd/src/basic/_libs - -rm -rf shared/systemd/src/shared/.libs shared/systemd/src/shared/_libs + -rm -rf src/c-rbtree/.libs src/c-rbtree/_libs + -rm -rf src/c-rbtree/src/.libs src/c-rbtree/src/_libs + -rm -rf src/c-siphash/.libs src/c-siphash/_libs + -rm -rf src/c-siphash/src/.libs src/c-siphash/src/_libs + -rm -rf src/contrib/.libs src/contrib/_libs + -rm -rf src/contrib/tests/.libs src/contrib/tests/_libs -rm -rf src/core/.libs src/core/_libs -rm -rf src/core/devices/.libs src/core/devices/_libs -rm -rf src/core/devices/adsl/.libs src/core/devices/adsl/_libs @@ -17558,14 +17713,10 @@ clean-libtool: -rm -rf src/core/dns/.libs src/core/dns/_libs -rm -rf src/core/dnsmasq/.libs src/core/dnsmasq/_libs -rm -rf src/core/dnsmasq/tests/.libs src/core/dnsmasq/tests/_libs - -rm -rf src/core/initrd/.libs src/core/initrd/_libs - -rm -rf src/core/initrd/tests/.libs src/core/initrd/tests/_libs -rm -rf src/core/ndisc/.libs src/core/ndisc/_libs -rm -rf src/core/ndisc/tests/.libs src/core/ndisc/tests/_libs -rm -rf src/core/platform/.libs src/core/platform/_libs -rm -rf src/core/platform/tests/.libs src/core/platform/tests/_libs - -rm -rf src/core/platform/wifi/.libs src/core/platform/wifi/_libs - -rm -rf src/core/platform/wpan/.libs src/core/platform/wpan/_libs -rm -rf src/core/ppp/.libs src/core/ppp/_libs -rm -rf src/core/settings/.libs src/core/settings/_libs -rm -rf src/core/settings/plugins/ifcfg-rh/.libs src/core/settings/plugins/ifcfg-rh/_libs @@ -17584,6 +17735,49 @@ clean-libtool: -rm -rf src/core/tests/.libs src/core/tests/_libs -rm -rf src/core/tests/config/.libs src/core/tests/config/_libs -rm -rf src/core/vpn/.libs src/core/vpn/_libs + -rm -rf src/libnm-base/.libs src/libnm-base/_libs + -rm -rf src/libnm-client-aux-extern/.libs src/libnm-client-aux-extern/_libs + -rm -rf src/libnm-client-aux-extern/tests/.libs src/libnm-client-aux-extern/tests/_libs + -rm -rf src/libnm-client-impl/.libs src/libnm-client-impl/_libs + -rm -rf src/libnm-client-impl/tests/.libs src/libnm-client-impl/tests/_libs + -rm -rf src/libnm-client-public/.libs src/libnm-client-public/_libs + -rm -rf src/libnm-client-test/.libs src/libnm-client-test/_libs + -rm -rf src/libnm-core-aux-extern/.libs src/libnm-core-aux-extern/_libs + -rm -rf src/libnm-core-aux-intern/.libs src/libnm-core-aux-intern/_libs + -rm -rf src/libnm-core-impl/.libs src/libnm-core-impl/_libs + -rm -rf src/libnm-core-impl/tests/.libs src/libnm-core-impl/tests/_libs + -rm -rf src/libnm-core-public/.libs src/libnm-core-public/_libs + -rm -rf src/libnm-glib-aux/.libs src/libnm-glib-aux/_libs + -rm -rf src/libnm-glib-aux/tests/.libs src/libnm-glib-aux/tests/_libs + -rm -rf src/libnm-log-core/.libs src/libnm-log-core/_libs + -rm -rf src/libnm-log-null/.libs src/libnm-log-null/_libs + -rm -rf src/libnm-platform/.libs src/libnm-platform/_libs + -rm -rf src/libnm-platform/tests/.libs src/libnm-platform/tests/_libs + -rm -rf src/libnm-platform/wifi/.libs src/libnm-platform/wifi/_libs + -rm -rf src/libnm-platform/wpan/.libs src/libnm-platform/wpan/_libs + -rm -rf src/libnm-std-aux/.libs src/libnm-std-aux/_libs + -rm -rf src/libnm-systemd-shared/.libs src/libnm-systemd-shared/_libs + -rm -rf src/libnm-systemd-shared/src/basic/.libs src/libnm-systemd-shared/src/basic/_libs + -rm -rf src/libnm-systemd-shared/src/shared/.libs src/libnm-systemd-shared/src/shared/_libs + -rm -rf src/libnm-udev-aux/.libs src/libnm-udev-aux/_libs + -rm -rf src/libnmc-base/.libs src/libnmc-base/_libs + -rm -rf src/libnmc-setting/.libs src/libnmc-setting/_libs + -rm -rf src/libnmc-setting/tests/.libs src/libnmc-setting/tests/_libs + -rm -rf src/n-acd/.libs src/n-acd/_libs + -rm -rf src/n-acd/src/.libs src/n-acd/src/_libs + -rm -rf src/n-acd/src/util/.libs src/n-acd/src/util/_libs + -rm -rf src/n-dhcp4/.libs src/n-dhcp4/_libs + -rm -rf src/n-dhcp4/src/.libs src/n-dhcp4/src/_libs + -rm -rf src/n-dhcp4/src/util/.libs src/n-dhcp4/src/util/_libs + -rm -rf src/nm-cloud-setup/.libs src/nm-cloud-setup/_libs + -rm -rf src/nm-cloud-setup/tests/.libs src/nm-cloud-setup/tests/_libs + -rm -rf src/nm-dispatcher/.libs src/nm-dispatcher/_libs + -rm -rf src/nm-dispatcher/tests/.libs src/nm-dispatcher/tests/_libs + -rm -rf src/nm-initrd-generator/.libs src/nm-initrd-generator/_libs + -rm -rf src/nm-initrd-generator/tests/.libs src/nm-initrd-generator/tests/_libs + -rm -rf src/nm-online/.libs src/nm-online/_libs + -rm -rf src/nmcli/.libs src/nmcli/_libs + -rm -rf src/nmtui/.libs src/nmtui/_libs distclean-libtool: -rm -f libtool config.lt @@ -18340,121 +18534,128 @@ recheck: all $(check_PROGRAMS) $(check_LTLIBRARIES) am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? -shared/nm-platform/tests/test-nm-platform.log: shared/nm-platform/tests/test-nm-platform$(EXEEXT) - @p='shared/nm-platform/tests/test-nm-platform$(EXEEXT)'; \ - b='shared/nm-platform/tests/test-nm-platform'; \ +src/libnm-platform/tests/test-nm-platform.log: src/libnm-platform/tests/test-nm-platform$(EXEEXT) + @p='src/libnm-platform/tests/test-nm-platform$(EXEEXT)'; \ + b='src/libnm-platform/tests/test-nm-platform'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +src/libnm-client-aux-extern/tests/test-libnm-client-aux.log: src/libnm-client-aux-extern/tests/test-libnm-client-aux$(EXEEXT) + @p='src/libnm-client-aux-extern/tests/test-libnm-client-aux$(EXEEXT)'; \ + b='src/libnm-client-aux-extern/tests/test-libnm-client-aux'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -shared/nm-glib-aux/tests/test-shared-general.log: shared/nm-glib-aux/tests/test-shared-general$(EXEEXT) - @p='shared/nm-glib-aux/tests/test-shared-general$(EXEEXT)'; \ - b='shared/nm-glib-aux/tests/test-shared-general'; \ +src/libnm-glib-aux/tests/test-shared-general.log: src/libnm-glib-aux/tests/test-shared-general$(EXEEXT) + @p='src/libnm-glib-aux/tests/test-shared-general$(EXEEXT)'; \ + b='src/libnm-glib-aux/tests/test-shared-general'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -shared/nm-glib-aux/tests/test-json-aux.log: shared/nm-glib-aux/tests/test-json-aux$(EXEEXT) - @p='shared/nm-glib-aux/tests/test-json-aux$(EXEEXT)'; \ - b='shared/nm-glib-aux/tests/test-json-aux'; \ +src/libnm-glib-aux/tests/test-json-aux.log: src/libnm-glib-aux/tests/test-json-aux$(EXEEXT) + @p='src/libnm-glib-aux/tests/test-json-aux$(EXEEXT)'; \ + b='src/libnm-glib-aux/tests/test-json-aux'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm-core/tests/test-compare.log: libnm-core/tests/test-compare$(EXEEXT) - @p='libnm-core/tests/test-compare$(EXEEXT)'; \ - b='libnm-core/tests/test-compare'; \ +src/libnm-core-impl/tests/test-compare.log: src/libnm-core-impl/tests/test-compare$(EXEEXT) + @p='src/libnm-core-impl/tests/test-compare$(EXEEXT)'; \ + b='src/libnm-core-impl/tests/test-compare'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm-core/tests/test-crypto.log: libnm-core/tests/test-crypto$(EXEEXT) - @p='libnm-core/tests/test-crypto$(EXEEXT)'; \ - b='libnm-core/tests/test-crypto'; \ +src/libnm-core-impl/tests/test-crypto.log: src/libnm-core-impl/tests/test-crypto$(EXEEXT) + @p='src/libnm-core-impl/tests/test-crypto$(EXEEXT)'; \ + b='src/libnm-core-impl/tests/test-crypto'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm-core/tests/test-general.log: libnm-core/tests/test-general$(EXEEXT) - @p='libnm-core/tests/test-general$(EXEEXT)'; \ - b='libnm-core/tests/test-general'; \ +src/libnm-core-impl/tests/test-general.log: src/libnm-core-impl/tests/test-general$(EXEEXT) + @p='src/libnm-core-impl/tests/test-general$(EXEEXT)'; \ + b='src/libnm-core-impl/tests/test-general'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm-core/tests/test-keyfile.log: libnm-core/tests/test-keyfile$(EXEEXT) - @p='libnm-core/tests/test-keyfile$(EXEEXT)'; \ - b='libnm-core/tests/test-keyfile'; \ +src/libnm-core-impl/tests/test-keyfile.log: src/libnm-core-impl/tests/test-keyfile$(EXEEXT) + @p='src/libnm-core-impl/tests/test-keyfile$(EXEEXT)'; \ + b='src/libnm-core-impl/tests/test-keyfile'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm-core/tests/test-secrets.log: libnm-core/tests/test-secrets$(EXEEXT) - @p='libnm-core/tests/test-secrets$(EXEEXT)'; \ - b='libnm-core/tests/test-secrets'; \ +src/libnm-core-impl/tests/test-secrets.log: src/libnm-core-impl/tests/test-secrets$(EXEEXT) + @p='src/libnm-core-impl/tests/test-secrets$(EXEEXT)'; \ + b='src/libnm-core-impl/tests/test-secrets'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm-core/tests/test-setting.log: libnm-core/tests/test-setting$(EXEEXT) - @p='libnm-core/tests/test-setting$(EXEEXT)'; \ - b='libnm-core/tests/test-setting'; \ +src/libnm-core-impl/tests/test-setting.log: src/libnm-core-impl/tests/test-setting$(EXEEXT) + @p='src/libnm-core-impl/tests/test-setting$(EXEEXT)'; \ + b='src/libnm-core-impl/tests/test-setting'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm-core/tests/test-settings-defaults.log: libnm-core/tests/test-settings-defaults$(EXEEXT) - @p='libnm-core/tests/test-settings-defaults$(EXEEXT)'; \ - b='libnm-core/tests/test-settings-defaults'; \ +src/libnm-core-impl/tests/test-settings-defaults.log: src/libnm-core-impl/tests/test-settings-defaults$(EXEEXT) + @p='src/libnm-core-impl/tests/test-settings-defaults$(EXEEXT)'; \ + b='src/libnm-core-impl/tests/test-settings-defaults'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm/tests/test-libnm.log: libnm/tests/test-libnm$(EXEEXT) - @p='libnm/tests/test-libnm$(EXEEXT)'; \ - b='libnm/tests/test-libnm'; \ +src/libnm-client-impl/tests/test-libnm.log: src/libnm-client-impl/tests/test-libnm$(EXEEXT) + @p='src/libnm-client-impl/tests/test-libnm$(EXEEXT)'; \ + b='src/libnm-client-impl/tests/test-libnm'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm/tests/test-nm-client.log: libnm/tests/test-nm-client$(EXEEXT) - @p='libnm/tests/test-nm-client$(EXEEXT)'; \ - b='libnm/tests/test-nm-client'; \ +src/libnm-client-impl/tests/test-nm-client.log: src/libnm-client-impl/tests/test-nm-client$(EXEEXT) + @p='src/libnm-client-impl/tests/test-nm-client$(EXEEXT)'; \ + b='src/libnm-client-impl/tests/test-nm-client'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm/tests/test-remote-settings-client.log: libnm/tests/test-remote-settings-client$(EXEEXT) - @p='libnm/tests/test-remote-settings-client$(EXEEXT)'; \ - b='libnm/tests/test-remote-settings-client'; \ +src/libnm-client-impl/tests/test-remote-settings-client.log: src/libnm-client-impl/tests/test-remote-settings-client$(EXEEXT) + @p='src/libnm-client-impl/tests/test-remote-settings-client$(EXEEXT)'; \ + b='src/libnm-client-impl/tests/test-remote-settings-client'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -libnm/tests/test-secret-agent.log: libnm/tests/test-secret-agent$(EXEEXT) - @p='libnm/tests/test-secret-agent$(EXEEXT)'; \ - b='libnm/tests/test-secret-agent'; \ +src/libnm-client-impl/tests/test-secret-agent.log: src/libnm-client-impl/tests/test-secret-agent$(EXEEXT) + @p='src/libnm-client-impl/tests/test-secret-agent$(EXEEXT)'; \ + b='src/libnm-client-impl/tests/test-secret-agent'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -src/core/initrd/tests/test-dt-reader.log: src/core/initrd/tests/test-dt-reader$(EXEEXT) - @p='src/core/initrd/tests/test-dt-reader$(EXEEXT)'; \ - b='src/core/initrd/tests/test-dt-reader'; \ +src/nm-initrd-generator/tests/test-dt-reader.log: src/nm-initrd-generator/tests/test-dt-reader$(EXEEXT) + @p='src/nm-initrd-generator/tests/test-dt-reader$(EXEEXT)'; \ + b='src/nm-initrd-generator/tests/test-dt-reader'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -src/core/initrd/tests/test-ibft-reader.log: src/core/initrd/tests/test-ibft-reader$(EXEEXT) - @p='src/core/initrd/tests/test-ibft-reader$(EXEEXT)'; \ - b='src/core/initrd/tests/test-ibft-reader'; \ +src/nm-initrd-generator/tests/test-ibft-reader.log: src/nm-initrd-generator/tests/test-ibft-reader$(EXEEXT) + @p='src/nm-initrd-generator/tests/test-ibft-reader$(EXEEXT)'; \ + b='src/nm-initrd-generator/tests/test-ibft-reader'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -src/core/initrd/tests/test-cmdline-reader.log: src/core/initrd/tests/test-cmdline-reader$(EXEEXT) - @p='src/core/initrd/tests/test-cmdline-reader$(EXEEXT)'; \ - b='src/core/initrd/tests/test-cmdline-reader'; \ +src/nm-initrd-generator/tests/test-cmdline-reader.log: src/nm-initrd-generator/tests/test-cmdline-reader$(EXEEXT) + @p='src/nm-initrd-generator/tests/test-cmdline-reader$(EXEEXT)'; \ + b='src/nm-initrd-generator/tests/test-cmdline-reader'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ @@ -18697,30 +18898,23 @@ src/core/tests/test-wired-defname.log: src/core/tests/test-wired-defname$(EXEEXT --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -dispatcher/tests/test-dispatcher-envp.log: dispatcher/tests/test-dispatcher-envp$(EXEEXT) - @p='dispatcher/tests/test-dispatcher-envp$(EXEEXT)'; \ - b='dispatcher/tests/test-dispatcher-envp'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -clients/common/tests/test-clients-common.log: clients/common/tests/test-clients-common$(EXEEXT) - @p='clients/common/tests/test-clients-common$(EXEEXT)'; \ - b='clients/common/tests/test-clients-common'; \ +src/nm-dispatcher/tests/test-dispatcher-envp.log: src/nm-dispatcher/tests/test-dispatcher-envp$(EXEEXT) + @p='src/nm-dispatcher/tests/test-dispatcher-envp$(EXEEXT)'; \ + b='src/nm-dispatcher/tests/test-dispatcher-envp'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -clients/common/tests/test-libnm-core-aux.log: clients/common/tests/test-libnm-core-aux$(EXEEXT) - @p='clients/common/tests/test-libnm-core-aux$(EXEEXT)'; \ - b='clients/common/tests/test-libnm-core-aux'; \ +src/libnmc-setting/tests/test-libnmc-setting.log: src/libnmc-setting/tests/test-libnmc-setting$(EXEEXT) + @p='src/libnmc-setting/tests/test-libnmc-setting$(EXEEXT)'; \ + b='src/libnmc-setting/tests/test-libnmc-setting'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -clients/cloud-setup/tests/test-cloud-setup-general.log: clients/cloud-setup/tests/test-cloud-setup-general$(EXEEXT) - @p='clients/cloud-setup/tests/test-cloud-setup-general$(EXEEXT)'; \ - b='clients/cloud-setup/tests/test-cloud-setup-general'; \ +src/nm-cloud-setup/tests/test-cloud-setup-general.log: src/nm-cloud-setup/tests/test-cloud-setup-general$(EXEEXT) + @p='src/nm-cloud-setup/tests/test-cloud-setup-general$(EXEEXT)'; \ + b='src/nm-cloud-setup/tests/test-cloud-setup-general'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ @@ -18984,84 +19178,21 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f clients/$(DEPDIR)/$(am__dirstamp) - -rm -f clients/$(am__dirstamp) - -rm -f clients/cli/$(DEPDIR)/$(am__dirstamp) - -rm -f clients/cli/$(am__dirstamp) - -rm -f clients/cloud-setup/$(DEPDIR)/$(am__dirstamp) - -rm -f clients/cloud-setup/$(am__dirstamp) - -rm -f clients/cloud-setup/tests/$(DEPDIR)/$(am__dirstamp) - -rm -f clients/cloud-setup/tests/$(am__dirstamp) - -rm -f clients/common/$(DEPDIR)/$(am__dirstamp) - -rm -f clients/common/$(am__dirstamp) - -rm -f clients/common/tests/$(DEPDIR)/$(am__dirstamp) - -rm -f clients/common/tests/$(am__dirstamp) - -rm -f clients/tui/$(DEPDIR)/$(am__dirstamp) - -rm -f clients/tui/$(am__dirstamp) - -rm -f clients/tui/newt/$(DEPDIR)/$(am__dirstamp) - -rm -f clients/tui/newt/$(am__dirstamp) - -rm -f dispatcher/$(DEPDIR)/$(am__dirstamp) - -rm -f dispatcher/$(am__dirstamp) - -rm -f dispatcher/tests/$(DEPDIR)/$(am__dirstamp) - -rm -f dispatcher/tests/$(am__dirstamp) -rm -f examples/C/glib/$(DEPDIR)/$(am__dirstamp) -rm -f examples/C/glib/$(am__dirstamp) -rm -f examples/C/qt/$(DEPDIR)/$(am__dirstamp) -rm -f examples/C/qt/$(am__dirstamp) -rm -f introspection/$(DEPDIR)/$(am__dirstamp) -rm -f introspection/$(am__dirstamp) - -rm -f libnm-core/$(DEPDIR)/$(am__dirstamp) - -rm -f libnm-core/$(am__dirstamp) - -rm -f libnm-core/nm-libnm-core-aux/$(DEPDIR)/$(am__dirstamp) - -rm -f libnm-core/nm-libnm-core-aux/$(am__dirstamp) - -rm -f libnm-core/nm-libnm-core-intern/$(DEPDIR)/$(am__dirstamp) - -rm -f libnm-core/nm-libnm-core-intern/$(am__dirstamp) - -rm -f libnm-core/tests/$(DEPDIR)/$(am__dirstamp) - -rm -f libnm-core/tests/$(am__dirstamp) - -rm -f libnm/$(DEPDIR)/$(am__dirstamp) - -rm -f libnm/$(am__dirstamp) - -rm -f libnm/nm-libnm-aux/$(DEPDIR)/$(am__dirstamp) - -rm -f libnm/nm-libnm-aux/$(am__dirstamp) - -rm -f libnm/tests/$(DEPDIR)/$(am__dirstamp) - -rm -f libnm/tests/$(am__dirstamp) - -rm -f shared/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/$(am__dirstamp) - -rm -f shared/c-rbtree/src/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/c-rbtree/src/$(am__dirstamp) - -rm -f shared/c-siphash/src/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/c-siphash/src/$(am__dirstamp) - -rm -f shared/n-acd/src/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/n-acd/src/$(am__dirstamp) - -rm -f shared/n-acd/src/util/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/n-acd/src/util/$(am__dirstamp) - -rm -f shared/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/n-dhcp4/src/$(am__dirstamp) - -rm -f shared/n-dhcp4/src/util/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/n-dhcp4/src/util/$(am__dirstamp) - -rm -f shared/nm-base/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/nm-base/$(am__dirstamp) - -rm -f shared/nm-glib-aux/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/nm-glib-aux/$(am__dirstamp) - -rm -f shared/nm-glib-aux/tests/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/nm-glib-aux/tests/$(am__dirstamp) - -rm -f shared/nm-log-core/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/nm-log-core/$(am__dirstamp) - -rm -f shared/nm-platform/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/nm-platform/$(am__dirstamp) - -rm -f shared/nm-platform/tests/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/nm-platform/tests/$(am__dirstamp) - -rm -f shared/nm-std-aux/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/nm-std-aux/$(am__dirstamp) - -rm -f shared/nm-udev-aux/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/nm-udev-aux/$(am__dirstamp) - -rm -f shared/nm-utils/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/nm-utils/$(am__dirstamp) - -rm -f shared/systemd/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/systemd/$(am__dirstamp) - -rm -f shared/systemd/src/basic/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/systemd/src/basic/$(am__dirstamp) - -rm -f shared/systemd/src/shared/$(DEPDIR)/$(am__dirstamp) - -rm -f shared/systemd/src/shared/$(am__dirstamp) + -rm -f src/c-rbtree/$(am__dirstamp) + -rm -f src/c-rbtree/src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/c-rbtree/src/$(am__dirstamp) + -rm -f src/c-siphash/$(am__dirstamp) + -rm -f src/c-siphash/src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/c-siphash/src/$(am__dirstamp) + -rm -f src/contrib/$(DEPDIR)/$(am__dirstamp) + -rm -f src/contrib/$(am__dirstamp) + -rm -f src/contrib/tests/$(am__dirstamp) -rm -f src/core/$(DEPDIR)/$(am__dirstamp) -rm -f src/core/$(am__dirstamp) -rm -f src/core/devices/$(DEPDIR)/$(am__dirstamp) @@ -19096,10 +19227,6 @@ distclean-generic: -rm -f src/core/dnsmasq/$(am__dirstamp) -rm -f src/core/dnsmasq/tests/$(DEPDIR)/$(am__dirstamp) -rm -f src/core/dnsmasq/tests/$(am__dirstamp) - -rm -f src/core/initrd/$(DEPDIR)/$(am__dirstamp) - -rm -f src/core/initrd/$(am__dirstamp) - -rm -f src/core/initrd/tests/$(DEPDIR)/$(am__dirstamp) - -rm -f src/core/initrd/tests/$(am__dirstamp) -rm -f src/core/ndisc/$(DEPDIR)/$(am__dirstamp) -rm -f src/core/ndisc/$(am__dirstamp) -rm -f src/core/ndisc/tests/$(DEPDIR)/$(am__dirstamp) @@ -19108,10 +19235,6 @@ distclean-generic: -rm -f src/core/platform/$(am__dirstamp) -rm -f src/core/platform/tests/$(DEPDIR)/$(am__dirstamp) -rm -f src/core/platform/tests/$(am__dirstamp) - -rm -f src/core/platform/wifi/$(DEPDIR)/$(am__dirstamp) - -rm -f src/core/platform/wifi/$(am__dirstamp) - -rm -f src/core/platform/wpan/$(DEPDIR)/$(am__dirstamp) - -rm -f src/core/platform/wpan/$(am__dirstamp) -rm -f src/core/ppp/$(DEPDIR)/$(am__dirstamp) -rm -f src/core/ppp/$(am__dirstamp) -rm -f src/core/settings/$(DEPDIR)/$(am__dirstamp) @@ -19148,6 +19271,92 @@ distclean-generic: -rm -f src/core/tests/config/$(am__dirstamp) -rm -f src/core/vpn/$(DEPDIR)/$(am__dirstamp) -rm -f src/core/vpn/$(am__dirstamp) + -rm -f src/libnm-base/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-base/$(am__dirstamp) + -rm -f src/libnm-client-aux-extern/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-client-aux-extern/$(am__dirstamp) + -rm -f src/libnm-client-aux-extern/tests/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-client-aux-extern/tests/$(am__dirstamp) + -rm -f src/libnm-client-impl/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-client-impl/$(am__dirstamp) + -rm -f src/libnm-client-impl/tests/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-client-impl/tests/$(am__dirstamp) + -rm -f src/libnm-client-public/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-client-public/$(am__dirstamp) + -rm -f src/libnm-client-test/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-client-test/$(am__dirstamp) + -rm -f src/libnm-core-aux-extern/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-core-aux-extern/$(am__dirstamp) + -rm -f src/libnm-core-aux-intern/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-core-aux-intern/$(am__dirstamp) + -rm -f src/libnm-core-impl/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-core-impl/$(am__dirstamp) + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-core-impl/tests/$(am__dirstamp) + -rm -f src/libnm-core-public/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-core-public/$(am__dirstamp) + -rm -f src/libnm-glib-aux/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-glib-aux/$(am__dirstamp) + -rm -f src/libnm-glib-aux/tests/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-glib-aux/tests/$(am__dirstamp) + -rm -f src/libnm-log-core/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-log-core/$(am__dirstamp) + -rm -f src/libnm-log-null/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-log-null/$(am__dirstamp) + -rm -f src/libnm-platform/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-platform/$(am__dirstamp) + -rm -f src/libnm-platform/tests/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-platform/tests/$(am__dirstamp) + -rm -f src/libnm-platform/wifi/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-platform/wifi/$(am__dirstamp) + -rm -f src/libnm-platform/wpan/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-platform/wpan/$(am__dirstamp) + -rm -f src/libnm-std-aux/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-std-aux/$(am__dirstamp) + -rm -f src/libnm-systemd-shared/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-systemd-shared/$(am__dirstamp) + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-systemd-shared/src/basic/$(am__dirstamp) + -rm -f src/libnm-systemd-shared/src/shared/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-systemd-shared/src/shared/$(am__dirstamp) + -rm -f src/libnm-udev-aux/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnm-udev-aux/$(am__dirstamp) + -rm -f src/libnmc-base/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnmc-base/$(am__dirstamp) + -rm -f src/libnmc-setting/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnmc-setting/$(am__dirstamp) + -rm -f src/libnmc-setting/tests/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnmc-setting/tests/$(am__dirstamp) + -rm -f src/libnmt-newt/$(DEPDIR)/$(am__dirstamp) + -rm -f src/libnmt-newt/$(am__dirstamp) + -rm -f src/n-acd/$(am__dirstamp) + -rm -f src/n-acd/src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/n-acd/src/$(am__dirstamp) + -rm -f src/n-acd/src/util/$(DEPDIR)/$(am__dirstamp) + -rm -f src/n-acd/src/util/$(am__dirstamp) + -rm -f src/n-dhcp4/$(am__dirstamp) + -rm -f src/n-dhcp4/src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/n-dhcp4/src/$(am__dirstamp) + -rm -f src/n-dhcp4/src/util/$(DEPDIR)/$(am__dirstamp) + -rm -f src/n-dhcp4/src/util/$(am__dirstamp) + -rm -f src/nm-cloud-setup/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nm-cloud-setup/$(am__dirstamp) + -rm -f src/nm-cloud-setup/tests/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nm-cloud-setup/tests/$(am__dirstamp) + -rm -f src/nm-dispatcher/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nm-dispatcher/$(am__dirstamp) + -rm -f src/nm-dispatcher/tests/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nm-dispatcher/tests/$(am__dirstamp) + -rm -f src/nm-initrd-generator/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nm-initrd-generator/$(am__dirstamp) + -rm -f src/nm-initrd-generator/tests/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nm-initrd-generator/tests/$(am__dirstamp) + -rm -f src/nm-online/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nm-online/$(am__dirstamp) + -rm -f src/nmcli/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nmcli/$(am__dirstamp) + -rm -f src/nmtui/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nmtui/$(am__dirstamp) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @@ -19164,99 +19373,7 @@ clean-am: clean-binPROGRAMS clean-checkLTLIBRARIES clean-checkPROGRAMS \ distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f clients/$(DEPDIR)/nm_online-nm-online.Po - -rm -f clients/cli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-agent.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-common.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-connections.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-devices.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-general.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-nmcli.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-polkit-agent.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-settings.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-utils.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po - -rm -f clients/cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po - -rm -f clients/cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po - -rm -f clients/common/$(DEPDIR)/libnmc_base_la-nm-client-utils.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-access.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-base-impl.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-desc.Plo - -rm -f clients/common/tests/$(DEPDIR)/test_clients_common-test-clients-common.Po - -rm -f clients/common/tests/$(DEPDIR)/test_libnm_core_aux-test-libnm-core-aux.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nm-editor-bindings.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nm-editor-utils.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-address-list.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-device-entry.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-editor-grid.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-editor-page.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-editor-section.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-editor.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-ip-entry.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-mac-entry.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-bond.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-dsl.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-ip4.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-ip6.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-ppp.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-team-port.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-team.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-vlan.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-wifi.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-password-dialog.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-password-fields.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-route-editor.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-route-entry.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-route-table.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-slave-list.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-utils.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-widget-list.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmtui-connect.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmtui-edit.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmtui-hostname.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmtui.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po - -rm -f dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Plo - -rm -f dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po - -rm -f dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po - -rm -f dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po - -rm -f examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po + -rm -f examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po -rm -f examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Po -rm -f examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Po -rm -f examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Po @@ -19264,6 +19381,7 @@ distclean: distclean-recursive -rm -f examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Po -rm -f examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Po -rm -f examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Po + -rm -f examples/C/glib/$(DEPDIR)/vpn_import_libnm-vpn-import-libnm.Po -rm -f examples/C/qt/$(DEPDIR)/add_connection_wired-add-connection-wired.Po -rm -f examples/C/qt/$(DEPDIR)/change_ipv4_addresses-change-ipv4-addresses.Po -rm -f examples/C/qt/$(DEPDIR)/list_connections-list-connections.Po @@ -19316,229 +19434,10 @@ distclean: distclean-recursive -rm -f introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.VPN.Connection.Plo -rm -f introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.VPN.Plugin.Plo -rm -f introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.WifiP2PPeer.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-connection.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-core-enum-types.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-crypto.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-dbus-utils.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-errors.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile-utils.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-meta-setting-base-impl.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-property-compare.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-6lowpan.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-8021x.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-adsl.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bluetooth.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bond.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge-port.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-cdma.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-connection.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dcb.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dummy.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ethtool.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-generic.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-gsm.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-hostname.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-infiniband.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-config.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-tunnel.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip4-config.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip6-config.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macsec.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macvlan.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-match.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-olpc-mesh.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-bridge.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-dpdk.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-external-ids.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-interface.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-patch.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-port.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ppp.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-pppoe.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-proxy.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-serial.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-sriov.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tc-config.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team-port.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tun.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-user.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-veth.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vlan.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vpn.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vrf.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vxlan.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wifi-p2p.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wimax.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wired.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireguard.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless-security.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wpan.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-simple-connection.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-team-utils.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-utils.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-editor-plugin.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-plugin-info.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Plo - -rm -f libnm-core/nm-libnm-core-aux/$(DEPDIR)/libnm_libnm_core_aux_la-nm-libnm-core-aux.Plo - -rm -f libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-auth-subject.Plo - -rm -f libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-libnm-core-utils.Plo - -rm -f libnm-core/tests/$(DEPDIR)/test_compare-test-compare.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_crypto-test-crypto.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_general-test-general.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_secrets-test-secrets.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_setting-test-setting.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-access-point.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-active-connection.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-checkpoint.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-client.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-dbus-helpers.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-6lowpan.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-adsl.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-bond.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-bridge.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-bt.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-dummy.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ethernet.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-generic.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-infiniband.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ip-tunnel.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-macsec.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-macvlan.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-modem.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-olpc-mesh.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-bridge.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-interface.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-port.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ppp.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-team.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-tun.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-veth.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-vlan.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-vrf.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-vxlan.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi-p2p.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-wimax.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-wireguard.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-wpan.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-dhcp-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-dhcp4-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-dhcp6-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-dns-manager.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-enum-types.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-ip-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-ip4-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-ip6-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-libnm-utils.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-object.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-remote-connection.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-secret-agent-old.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-vpn-connection.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-vpn-editor.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-vpn-plugin-old.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-vpn-service-plugin.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-wifi-p2p-peer.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-wimax-nsp.Plo - -rm -f libnm/nm-libnm-aux/$(DEPDIR)/libnm_libnm_aux_la-nm-libnm-aux.Plo - -rm -f libnm/tests/$(DEPDIR)/test_libnm-test-libnm.Po - -rm -f libnm/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po - -rm -f libnm/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po - -rm -f libnm/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po - -rm -f shared/$(DEPDIR)/libnm_tests_test_nm_client-nm-test-utils-impl.Po - -rm -f shared/$(DEPDIR)/libnm_tests_test_remote_settings_client-nm-test-utils-impl.Po - -rm -f shared/$(DEPDIR)/libnm_tests_test_secret_agent-nm-test-utils-impl.Po - -rm -f shared/c-rbtree/src/$(DEPDIR)/libcrbtree_la-c-rbtree.Plo - -rm -f shared/c-siphash/src/$(DEPDIR)/libcsiphash_la-c-siphash.Plo - -rm -f shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf-fallback.Plo - -rm -f shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf.Plo - -rm -f shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-probe.Plo - -rm -f shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd.Plo - -rm -f shared/n-acd/src/util/$(DEPDIR)/libnacd_la-timer.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-connection.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-lease.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-probe.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-client.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-incoming.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-outgoing.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-socket.Plo - -rm -f shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-packet.Plo - -rm -f shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-socket.Plo - -rm -f shared/nm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Plo - -rm -f shared/nm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po - -rm -f shared/nm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po - -rm -f shared/nm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Plo - -rm -f shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Plo - -rm -f shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Plo - -rm -f shared/nm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Plo - -rm -f shared/nm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po - -rm -f shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Plo - -rm -f shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Plo - -rm -f shared/nm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Plo - -rm -f shared/nm-utils/$(DEPDIR)/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Plo - -rm -f shared/nm-utils/$(DEPDIR)/libnm_tests_test_libnm-nm-compat.Po - -rm -f shared/systemd/$(DEPDIR)/libnm_systemd_logging_stub_la-nm-logging-stub.Plo - -rm -f shared/systemd/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Plo - -rm -f shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Plo - -rm -f shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Plo + -rm -f src/c-rbtree/src/$(DEPDIR)/libc_rbtree_la-c-rbtree.Plo + -rm -f src/c-siphash/src/$(DEPDIR)/libc_siphash_la-c-siphash.Plo + -rm -f src/contrib/$(DEPDIR)/libnm_client_impl_tests_test_libnm-nm-compat.Po + -rm -f src/contrib/$(DEPDIR)/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Plo -rm -f src/core/$(DEPDIR)/NetworkManager-main.Po -rm -f src/core/$(DEPDIR)/NetworkManager_all_sym-main.Po -rm -f src/core/$(DEPDIR)/libNetworkManagerBase_la-NetworkManagerUtils.Plo @@ -19659,22 +19558,11 @@ distclean: distclean-recursive -rm -f src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-manager.Plo -rm -f src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-utils.Plo -rm -f src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Po - -rm -f src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Plo - -rm -f src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Plo - -rm -f src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Plo - -rm -f src/core/initrd/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po - -rm -f src/core/initrd/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po - -rm -f src/core/initrd/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po - -rm -f src/core/initrd/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po -rm -f src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-lndp-ndisc.Plo -rm -f src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-ndisc.Plo -rm -f src/core/ndisc/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-ndisc.Plo -rm -f src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Po -rm -f src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Po - -rm -f src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-linux-platform.Plo - -rm -f src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-platform.Plo - -rm -f src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-object.Plo - -rm -f src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-rules-manager.Plo -rm -f src/core/platform/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-platform.Plo -rm -f src/core/platform/tests/$(DEPDIR)/libNetworkManagerTest_la-test-common.Plo -rm -f src/core/platform/tests/$(DEPDIR)/monitor-monitor.Po @@ -19690,10 +19578,6 @@ distclean: distclean-recursive -rm -f src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Po -rm -f src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Po -rm -f src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Po - -rm -f src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-nl80211.Plo - -rm -f src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-wext.Plo - -rm -f src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils.Plo - -rm -f src/core/platform/wpan/$(DEPDIR)/libNetworkManagerBase_la-nm-wpan-utils.Plo -rm -f src/core/ppp/$(DEPDIR)/libNetworkManager_la-nm-ppp-manager-call.Plo -rm -f src/core/ppp/$(DEPDIR)/libnm_ppp_plugin_la-nm-ppp-manager.Plo -rm -f src/core/ppp/$(DEPDIR)/nm_pppd_plugin_la-nm-pppd-plugin.Plo @@ -19765,6 +19649,331 @@ distclean: distclean-recursive -rm -f src/core/tests/config/$(DEPDIR)/test_config-test-config.Po -rm -f src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-connection.Plo -rm -f src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Plo + -rm -f src/libnm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Plo + -rm -f src/libnm-base/$(DEPDIR)/libnm_base_la-nm-net-aux.Plo + -rm -f src/libnm-client-aux-extern/$(DEPDIR)/libnm_client_aux_extern_la-nm-libnm-aux.Plo + -rm -f src/libnm-client-aux-extern/tests/$(DEPDIR)/test_libnm_client_aux-test-libnm-client-aux.Po + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-access-point.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-active-connection.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-checkpoint.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-client.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dbus-helpers.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-6lowpan.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-adsl.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bond.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bridge.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bt.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-dummy.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ethernet.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-generic.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-infiniband.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ip-tunnel.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macsec.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macvlan.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-modem.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-olpc-mesh.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-bridge.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-interface.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-port.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ppp.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-team.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-tun.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-veth.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vlan.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vrf.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vxlan.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi-p2p.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wimax.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wireguard.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wpan.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp4-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp6-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dns-manager.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip4-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip6-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-libnm-utils.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-object.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-remote-connection.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-secret-agent-old.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-connection.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-editor.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-plugin-old.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-service-plugin.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wifi-p2p-peer.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wimax-nsp.Plo + -rm -f src/libnm-client-impl/tests/$(DEPDIR)/test_libnm-test-libnm.Po + -rm -f src/libnm-client-impl/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po + -rm -f src/libnm-client-impl/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po + -rm -f src/libnm-client-impl/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po + -rm -f src/libnm-client-public/$(DEPDIR)/libnm_client_impl_libnm_client_impl_la-nm-enum-types.Plo + -rm -f src/libnm-client-test/$(DEPDIR)/libnm_client_test_la-nm-test-utils-impl.Plo + -rm -f src/libnm-core-aux-extern/$(DEPDIR)/libnm_core_aux_extern_la-nm-libnm-core-aux.Plo + -rm -f src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-auth-subject.Plo + -rm -f src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-libnm-core-utils.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-connection.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-crypto.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-dbus-utils.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-errors.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile-utils.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-meta-setting-base-impl.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-property-compare.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-6lowpan.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-8021x.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-adsl.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bluetooth.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bond.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge-port.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-cdma.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-connection.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dcb.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dummy.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ethtool.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-generic.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-gsm.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-hostname.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-infiniband.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-config.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-tunnel.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip4-config.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip6-config.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macsec.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macvlan.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-match.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-olpc-mesh.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-bridge.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-dpdk.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-external-ids.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-interface.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-patch.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-port.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ppp.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-pppoe.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-proxy.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-serial.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-sriov.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tc-config.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team-port.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tun.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-user.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-veth.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vlan.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vpn.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vrf.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vxlan.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wifi-p2p.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wimax.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wired.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireguard.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless-security.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wpan.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-simple-connection.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-team-utils.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-utils.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-editor-plugin.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-plugin-info.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Plo + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_compare-test-compare.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_crypto-test-crypto.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_general-test-general.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_secrets-test-secrets.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_setting-test-setting.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po + -rm -f src/libnm-core-public/$(DEPDIR)/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Plo + -rm -f src/libnm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po + -rm -f src/libnm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po + -rm -f src/libnm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Plo + -rm -f src/libnm-log-null/$(DEPDIR)/libnm_log_null_la-nm-logging-null.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-linux-platform.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-object.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-rules-manager.Plo + -rm -f src/libnm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po + -rm -f src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-nl80211.Plo + -rm -f src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-wext.Plo + -rm -f src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils.Plo + -rm -f src/libnm-platform/wpan/$(DEPDIR)/libnm_platform_la-nm-wpan-utils.Plo + -rm -f src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Plo + -rm -f src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Plo + -rm -f src/libnm-systemd-shared/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Plo + -rm -f src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Plo + -rm -f src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Plo + -rm -f src/libnm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Plo + -rm -f src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-client-utils.Plo + -rm -f src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Plo + -rm -f src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Plo + -rm -f src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Plo + -rm -f src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-access.Plo + -rm -f src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-base-impl.Plo + -rm -f src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-desc.Plo + -rm -f src/libnmc-setting/tests/$(DEPDIR)/test_libnmc_setting-test-libnmc-setting.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po + -rm -f src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf-fallback.Plo + -rm -f src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf.Plo + -rm -f src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-probe.Plo + -rm -f src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd.Plo + -rm -f src/n-acd/src/util/$(DEPDIR)/libn_acd_la-timer.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-connection.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-lease.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-probe.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-client.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-incoming.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-outgoing.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-socket.Plo + -rm -f src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-packet.Plo + -rm -f src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-socket.Plo + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po + -rm -f src/nm-cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po + -rm -f src/nm-dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Plo + -rm -f src/nm-dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po + -rm -f src/nm-dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po + -rm -f src/nm-dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po + -rm -f src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Plo + -rm -f src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Plo + -rm -f src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Plo + -rm -f src/nm-initrd-generator/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po + -rm -f src/nm-initrd-generator/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po + -rm -f src/nm-initrd-generator/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po + -rm -f src/nm-initrd-generator/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po + -rm -f src/nm-online/$(DEPDIR)/nm_online-nm-online.Po + -rm -f src/nmcli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-agent.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-common.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-connections.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-devices.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-general.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-nmcli.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-polkit-agent.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-settings.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-utils.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nm-editor-bindings.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nm-editor-utils.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-address-list.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-device-entry.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-editor-grid.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-editor-section.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-editor.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-ip-entry.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-mac-entry.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-bond.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-dsl.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip4.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip6.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-ppp.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-team-port.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-team.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-vlan.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-wifi.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-password-dialog.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-password-fields.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-route-editor.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-route-entry.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-route-table.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-slave-list.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-utils.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-widget-list.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmtui-connect.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmtui-edit.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmtui-hostname.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmtui.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags @@ -19824,99 +20033,7 @@ installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -f clients/$(DEPDIR)/nm_online-nm-online.Po - -rm -f clients/cli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-agent.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-common.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-connections.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-devices.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-general.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-nmcli.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-polkit-agent.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-settings.Po - -rm -f clients/cli/$(DEPDIR)/nmcli-utils.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po - -rm -f clients/cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po - -rm -f clients/cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po - -rm -f clients/cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po - -rm -f clients/common/$(DEPDIR)/libnmc_base_la-nm-client-utils.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-access.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-base-impl.Plo - -rm -f clients/common/$(DEPDIR)/libnmc_la-nm-meta-setting-desc.Plo - -rm -f clients/common/tests/$(DEPDIR)/test_clients_common-test-clients-common.Po - -rm -f clients/common/tests/$(DEPDIR)/test_libnm_core_aux-test-libnm-core-aux.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nm-editor-bindings.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nm-editor-utils.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-address-list.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-device-entry.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-editor-grid.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-editor-page.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-editor-section.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-editor.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-ip-entry.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-mac-entry.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-bond.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-bridge.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-dsl.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-ip4.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-ip6.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-ppp.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-team-port.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-team.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-vlan.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-page-wifi.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-password-dialog.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-password-fields.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-route-editor.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-route-entry.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-route-table.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-slave-list.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-utils.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmt-widget-list.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmtui-connect.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmtui-edit.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmtui-hostname.Po - -rm -f clients/tui/$(DEPDIR)/nmtui-nmtui.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po - -rm -f clients/tui/newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po - -rm -f dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Plo - -rm -f dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po - -rm -f dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po - -rm -f dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po - -rm -f examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po + -rm -f examples/C/glib/$(DEPDIR)/add_connection_gdbus-add-connection-gdbus.Po -rm -f examples/C/glib/$(DEPDIR)/add_connection_libnm-add-connection-libnm.Po -rm -f examples/C/glib/$(DEPDIR)/get_active_connections_gdbus-get-active-connections-gdbus.Po -rm -f examples/C/glib/$(DEPDIR)/get_ap_info_libnm-get-ap-info-libnm.Po @@ -19924,6 +20041,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f examples/C/glib/$(DEPDIR)/list_connections_libnm-list-connections-libnm.Po -rm -f examples/C/glib/$(DEPDIR)/monitor_nm_running_gdbus-monitor-nm-running-gdbus.Po -rm -f examples/C/glib/$(DEPDIR)/monitor_nm_state_gdbus-monitor-nm-state-gdbus.Po + -rm -f examples/C/glib/$(DEPDIR)/vpn_import_libnm-vpn-import-libnm.Po -rm -f examples/C/qt/$(DEPDIR)/add_connection_wired-add-connection-wired.Po -rm -f examples/C/qt/$(DEPDIR)/change_ipv4_addresses-change-ipv4-addresses.Po -rm -f examples/C/qt/$(DEPDIR)/list_connections-list-connections.Po @@ -19976,229 +20094,10 @@ maintainer-clean: maintainer-clean-recursive -rm -f introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.VPN.Connection.Plo -rm -f introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.VPN.Plugin.Plo -rm -f introspection/$(DEPDIR)/libnmdbus_la-org.freedesktop.NetworkManager.WifiP2PPeer.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-connection.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-core-enum-types.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-crypto.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-dbus-utils.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-errors.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile-utils.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-keyfile.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-meta-setting-base-impl.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-property-compare.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-6lowpan.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-8021x.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-adsl.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bluetooth.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bond.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge-port.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-bridge.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-cdma.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-connection.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dcb.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-dummy.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ethtool.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-generic.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-gsm.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-hostname.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-infiniband.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-config.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip-tunnel.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip4-config.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ip6-config.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macsec.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-macvlan.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-match.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-olpc-mesh.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-bridge.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-dpdk.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-external-ids.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-interface.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-patch.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ovs-port.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-ppp.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-pppoe.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-proxy.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-serial.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-sriov.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tc-config.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team-port.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-team.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-tun.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-user.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-veth.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vlan.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vpn.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vrf.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-vxlan.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wifi-p2p.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wimax.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wired.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireguard.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless-security.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wireless.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting-wpan.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-setting.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-simple-connection.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-team-utils.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-utils.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-editor-plugin.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_core_la-nm-vpn-plugin-info.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Plo - -rm -f libnm-core/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Plo - -rm -f libnm-core/nm-libnm-core-aux/$(DEPDIR)/libnm_libnm_core_aux_la-nm-libnm-core-aux.Plo - -rm -f libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-auth-subject.Plo - -rm -f libnm-core/nm-libnm-core-intern/$(DEPDIR)/libnm_libnm_core_intern_la-nm-libnm-core-utils.Plo - -rm -f libnm-core/tests/$(DEPDIR)/test_compare-test-compare.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_crypto-test-crypto.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_general-test-general.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_secrets-test-secrets.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_setting-test-setting.Po - -rm -f libnm-core/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-access-point.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-active-connection.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-checkpoint.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-client.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-dbus-helpers.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-6lowpan.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-adsl.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-bond.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-bridge.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-bt.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-dummy.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ethernet.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-generic.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-infiniband.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ip-tunnel.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-macsec.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-macvlan.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-modem.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-olpc-mesh.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-bridge.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-interface.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ovs-port.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-ppp.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-team.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-tun.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-veth.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-vlan.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-vrf.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-vxlan.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi-p2p.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-wifi.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-wimax.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-wireguard.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device-wpan.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-device.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-dhcp-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-dhcp4-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-dhcp6-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-dns-manager.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-enum-types.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-ip-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-ip4-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-ip6-config.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-libnm-utils.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-object.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-remote-connection.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-secret-agent-old.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-vpn-connection.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-vpn-editor.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-vpn-plugin-old.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-vpn-service-plugin.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-wifi-p2p-peer.Plo - -rm -f libnm/$(DEPDIR)/libnm_static_la-nm-wimax-nsp.Plo - -rm -f libnm/nm-libnm-aux/$(DEPDIR)/libnm_libnm_aux_la-nm-libnm-aux.Plo - -rm -f libnm/tests/$(DEPDIR)/test_libnm-test-libnm.Po - -rm -f libnm/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po - -rm -f libnm/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po - -rm -f libnm/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po - -rm -f shared/$(DEPDIR)/libnm_tests_test_nm_client-nm-test-utils-impl.Po - -rm -f shared/$(DEPDIR)/libnm_tests_test_remote_settings_client-nm-test-utils-impl.Po - -rm -f shared/$(DEPDIR)/libnm_tests_test_secret_agent-nm-test-utils-impl.Po - -rm -f shared/c-rbtree/src/$(DEPDIR)/libcrbtree_la-c-rbtree.Plo - -rm -f shared/c-siphash/src/$(DEPDIR)/libcsiphash_la-c-siphash.Plo - -rm -f shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf-fallback.Plo - -rm -f shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-bpf.Plo - -rm -f shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd-probe.Plo - -rm -f shared/n-acd/src/$(DEPDIR)/libnacd_la-n-acd.Plo - -rm -f shared/n-acd/src/util/$(DEPDIR)/libnacd_la-timer.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-connection.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-lease.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-c-probe.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-client.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-incoming.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-outgoing.Plo - -rm -f shared/n-dhcp4/src/$(DEPDIR)/libndhcp4_la-n-dhcp4-socket.Plo - -rm -f shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-packet.Plo - -rm -f shared/n-dhcp4/src/util/$(DEPDIR)/libndhcp4_la-socket.Plo - -rm -f shared/nm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Plo - -rm -f shared/nm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Plo - -rm -f shared/nm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po - -rm -f shared/nm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po - -rm -f shared/nm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Plo - -rm -f shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Plo - -rm -f shared/nm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Plo - -rm -f shared/nm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Plo - -rm -f shared/nm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po - -rm -f shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Plo - -rm -f shared/nm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Plo - -rm -f shared/nm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Plo - -rm -f shared/nm-utils/$(DEPDIR)/libnm_tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Plo - -rm -f shared/nm-utils/$(DEPDIR)/libnm_tests_test_libnm-nm-compat.Po - -rm -f shared/systemd/$(DEPDIR)/libnm_systemd_logging_stub_la-nm-logging-stub.Plo - -rm -f shared/systemd/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Plo - -rm -f shared/systemd/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Plo - -rm -f shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Plo - -rm -f shared/systemd/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Plo + -rm -f src/c-rbtree/src/$(DEPDIR)/libc_rbtree_la-c-rbtree.Plo + -rm -f src/c-siphash/src/$(DEPDIR)/libc_siphash_la-c-siphash.Plo + -rm -f src/contrib/$(DEPDIR)/libnm_client_impl_tests_test_libnm-nm-compat.Po + -rm -f src/contrib/$(DEPDIR)/tests_libnm_vpn_plugin_utils_test_la-nm-vpn-plugin-utils.Plo -rm -f src/core/$(DEPDIR)/NetworkManager-main.Po -rm -f src/core/$(DEPDIR)/NetworkManager_all_sym-main.Po -rm -f src/core/$(DEPDIR)/libNetworkManagerBase_la-NetworkManagerUtils.Plo @@ -20319,22 +20218,11 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-manager.Plo -rm -f src/core/dnsmasq/$(DEPDIR)/libNetworkManager_la-nm-dnsmasq-utils.Plo -rm -f src/core/dnsmasq/tests/$(DEPDIR)/test_dnsmasq_utils-test-dnsmasq-utils.Po - -rm -f src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Plo - -rm -f src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Plo - -rm -f src/core/initrd/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Plo - -rm -f src/core/initrd/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po - -rm -f src/core/initrd/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po - -rm -f src/core/initrd/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po - -rm -f src/core/initrd/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po -rm -f src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-lndp-ndisc.Plo -rm -f src/core/ndisc/$(DEPDIR)/libNetworkManagerBase_la-nm-ndisc.Plo -rm -f src/core/ndisc/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-ndisc.Plo -rm -f src/core/ndisc/tests/$(DEPDIR)/test_ndisc_fake-test-ndisc-fake.Po -rm -f src/core/ndisc/tests/$(DEPDIR)/test_ndisc_linux-test-ndisc-linux.Po - -rm -f src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-linux-platform.Plo - -rm -f src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nm-platform.Plo - -rm -f src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-object.Plo - -rm -f src/core/platform/$(DEPDIR)/libNetworkManagerBase_la-nmp-rules-manager.Plo -rm -f src/core/platform/$(DEPDIR)/libNetworkManagerTest_la-nm-fake-platform.Plo -rm -f src/core/platform/tests/$(DEPDIR)/libNetworkManagerTest_la-test-common.Plo -rm -f src/core/platform/tests/$(DEPDIR)/monitor-monitor.Po @@ -20350,10 +20238,6 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/core/platform/tests/$(DEPDIR)/test_route_linux-test-route.Po -rm -f src/core/platform/tests/$(DEPDIR)/test_tc_fake-test-tc.Po -rm -f src/core/platform/tests/$(DEPDIR)/test_tc_linux-test-tc.Po - -rm -f src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-nl80211.Plo - -rm -f src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils-wext.Plo - -rm -f src/core/platform/wifi/$(DEPDIR)/libNetworkManagerBase_la-nm-wifi-utils.Plo - -rm -f src/core/platform/wpan/$(DEPDIR)/libNetworkManagerBase_la-nm-wpan-utils.Plo -rm -f src/core/ppp/$(DEPDIR)/libNetworkManager_la-nm-ppp-manager-call.Plo -rm -f src/core/ppp/$(DEPDIR)/libnm_ppp_plugin_la-nm-ppp-manager.Plo -rm -f src/core/ppp/$(DEPDIR)/nm_pppd_plugin_la-nm-pppd-plugin.Plo @@ -20425,6 +20309,331 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/core/tests/config/$(DEPDIR)/test_config-test-config.Po -rm -f src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-connection.Plo -rm -f src/core/vpn/$(DEPDIR)/libNetworkManager_la-nm-vpn-manager.Plo + -rm -f src/libnm-base/$(DEPDIR)/libnm_base_la-nm-ethtool-base.Plo + -rm -f src/libnm-base/$(DEPDIR)/libnm_base_la-nm-net-aux.Plo + -rm -f src/libnm-client-aux-extern/$(DEPDIR)/libnm_client_aux_extern_la-nm-libnm-aux.Plo + -rm -f src/libnm-client-aux-extern/tests/$(DEPDIR)/test_libnm_client_aux-test-libnm-client-aux.Po + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-access-point.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-active-connection.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-checkpoint.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-client.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dbus-helpers.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-6lowpan.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-adsl.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bond.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bridge.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-bt.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-dummy.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ethernet.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-generic.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-infiniband.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ip-tunnel.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macsec.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-macvlan.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-modem.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-olpc-mesh.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-bridge.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-interface.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ovs-port.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-ppp.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-team.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-tun.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-veth.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vlan.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vrf.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-vxlan.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi-p2p.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wifi.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wimax.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wireguard.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device-wpan.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-device.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp4-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dhcp6-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-dns-manager.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip4-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-ip6-config.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-libnm-utils.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-object.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-remote-connection.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-secret-agent-old.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-connection.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-editor.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-plugin-old.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-vpn-service-plugin.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wifi-p2p-peer.Plo + -rm -f src/libnm-client-impl/$(DEPDIR)/libnm_client_impl_la-nm-wimax-nsp.Plo + -rm -f src/libnm-client-impl/tests/$(DEPDIR)/test_libnm-test-libnm.Po + -rm -f src/libnm-client-impl/tests/$(DEPDIR)/test_nm_client-test-nm-client.Po + -rm -f src/libnm-client-impl/tests/$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po + -rm -f src/libnm-client-impl/tests/$(DEPDIR)/test_secret_agent-test-secret-agent.Po + -rm -f src/libnm-client-public/$(DEPDIR)/libnm_client_impl_libnm_client_impl_la-nm-enum-types.Plo + -rm -f src/libnm-client-test/$(DEPDIR)/libnm_client_test_la-nm-test-utils-impl.Plo + -rm -f src/libnm-core-aux-extern/$(DEPDIR)/libnm_core_aux_extern_la-nm-libnm-core-aux.Plo + -rm -f src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-auth-subject.Plo + -rm -f src/libnm-core-aux-intern/$(DEPDIR)/libnm_core_aux_intern_la-nm-libnm-core-utils.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-connection.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-crypto.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-dbus-utils.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-errors.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile-utils.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-keyfile.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-meta-setting-base-impl.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-property-compare.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-6lowpan.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-8021x.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-adsl.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bluetooth.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bond.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge-port.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-bridge.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-cdma.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-connection.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dcb.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-dummy.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ethtool.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-generic.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-gsm.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-hostname.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-infiniband.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-config.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip-tunnel.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip4-config.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ip6-config.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macsec.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-macvlan.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-match.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-olpc-mesh.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-bridge.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-dpdk.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-external-ids.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-interface.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-patch.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ovs-port.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-ppp.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-pppoe.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-proxy.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-serial.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-sriov.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tc-config.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team-port.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-team.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-tun.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-user.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-veth.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vlan.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vpn.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vrf.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-vxlan.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wifi-p2p.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wimax.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wired.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireguard.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless-security.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wireless.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting-wpan.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-setting.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-simple-connection.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-team-utils.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-utils.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-editor-plugin.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_core_impl_la-nm-vpn-plugin-info.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_crypto_gnutls_la-nm-crypto-gnutls.Plo + -rm -f src/libnm-core-impl/$(DEPDIR)/libnm_crypto_nss_la-nm-crypto-nss.Plo + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_compare-test-compare.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_crypto-test-crypto.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_general-nm-core-tests-enum-types.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_general-test-general.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_keyfile-test-keyfile.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_secrets-test-secrets.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_setting-test-setting.Po + -rm -f src/libnm-core-impl/tests/$(DEPDIR)/test_settings_defaults-test-settings-defaults.Po + -rm -f src/libnm-core-public/$(DEPDIR)/libnm_core_impl_libnm_core_impl_la-nm-core-enum-types.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dbus-aux.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-dedup-multi.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-enum-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-errno.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-hash-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-io-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-json-aux.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-keyfile-aux.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-logging-base.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-random-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-ref-string.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-secret-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-shared-utils.Plo + -rm -f src/libnm-glib-aux/$(DEPDIR)/libnm_glib_aux_la-nm-time-utils.Plo + -rm -f src/libnm-glib-aux/tests/$(DEPDIR)/test_json_aux-test-json-aux.Po + -rm -f src/libnm-glib-aux/tests/$(DEPDIR)/test_shared_general-test-shared-general.Po + -rm -f src/libnm-log-core/$(DEPDIR)/libnm_log_core_la-nm-logging.Plo + -rm -f src/libnm-log-null/$(DEPDIR)/libnm_log_null_la-nm-logging-null.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-linux-platform.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-netlink.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform-utils.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nm-platform.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-netns.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-object.Plo + -rm -f src/libnm-platform/$(DEPDIR)/libnm_platform_la-nmp-rules-manager.Plo + -rm -f src/libnm-platform/tests/$(DEPDIR)/test_nm_platform-test-nm-platform.Po + -rm -f src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-nl80211.Plo + -rm -f src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils-wext.Plo + -rm -f src/libnm-platform/wifi/$(DEPDIR)/libnm_platform_la-nm-wifi-utils.Plo + -rm -f src/libnm-platform/wpan/$(DEPDIR)/libnm_platform_la-nm-wpan-utils.Plo + -rm -f src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-c-list-util.Plo + -rm -f src/libnm-std-aux/$(DEPDIR)/libnm_std_aux_la-nm-std-utils.Plo + -rm -f src/libnm-systemd-shared/$(DEPDIR)/libnm_systemd_shared_la-nm-sd-utils-shared.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-alloc-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-file.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-env-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-escape.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ether-addr-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-extract-word.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fd-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fileio.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-format-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-fs-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hash-funcs.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hashmap.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hexdecoct.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-hostname-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-in-addr-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-io-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-memory-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-mempool.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-parse-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-path-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-prioq.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-process-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-random-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-ratelimit.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-signal-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-socket-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-stat-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-table.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-string-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strv.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-strxcpyx.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-time-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-tmpfile-util.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-utf8.Plo + -rm -f src/libnm-systemd-shared/src/basic/$(DEPDIR)/libnm_systemd_shared_la-util.Plo + -rm -f src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-dns-domain.Plo + -rm -f src/libnm-systemd-shared/src/shared/$(DEPDIR)/libnm_systemd_shared_la-web-util.Plo + -rm -f src/libnm-udev-aux/$(DEPDIR)/libnm_udev_aux_la-nm-udev-utils.Plo + -rm -f src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-client-utils.Plo + -rm -f src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-polkit-listener.Plo + -rm -f src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-secret-agent-simple.Plo + -rm -f src/libnmc-base/$(DEPDIR)/libnmc_base_la-nm-vpn-helpers.Plo + -rm -f src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-access.Plo + -rm -f src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-base-impl.Plo + -rm -f src/libnmc-setting/$(DEPDIR)/libnmc_setting_la-nm-meta-setting-desc.Plo + -rm -f src/libnmc-setting/tests/$(DEPDIR)/test_libnmc_setting-test-libnmc-setting.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button-box.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-button.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-checkbox.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-component.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-container.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry-numeric.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-entry.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-form.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-grid.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-hacks.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-label.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-listbox.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-popup.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-section.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-separator.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-stack.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-textbox.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-toggle-button.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-utils.Po + -rm -f src/libnmt-newt/$(DEPDIR)/libnmt_newt_a-nmt-newt-widget.Po + -rm -f src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf-fallback.Plo + -rm -f src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-bpf.Plo + -rm -f src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd-probe.Plo + -rm -f src/n-acd/src/$(DEPDIR)/libn_acd_la-n-acd.Plo + -rm -f src/n-acd/src/util/$(DEPDIR)/libn_acd_la-timer.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-connection.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-lease.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-c-probe.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-client.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-incoming.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-outgoing.Plo + -rm -f src/n-dhcp4/src/$(DEPDIR)/libn_dhcp4_la-n-dhcp4-socket.Plo + -rm -f src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-packet.Plo + -rm -f src/n-dhcp4/src/util/$(DEPDIR)/libn_dhcp4_la-socket.Plo + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-cloud-setup-utils.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nm-http-client.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-azure.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-ec2.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider-gcp.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/libnm_cloud_setup_core_a-nmcs-provider.Po + -rm -f src/nm-cloud-setup/$(DEPDIR)/nm_cloud_setup-main.Po + -rm -f src/nm-cloud-setup/tests/$(DEPDIR)/test_cloud_setup_general-test-cloud-setup-general.Po + -rm -f src/nm-dispatcher/$(DEPDIR)/libnm_dispatcher_core_la-nm-dispatcher-utils.Plo + -rm -f src/nm-dispatcher/$(DEPDIR)/nm_dispatcher-nm-dispatcher.Po + -rm -f src/nm-dispatcher/$(DEPDIR)/tests_test_dispatcher_envp-nmdbus-dispatcher.Po + -rm -f src/nm-dispatcher/tests/$(DEPDIR)/test_dispatcher_envp-test-dispatcher-envp.Po + -rm -f src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-cmdline-reader.Plo + -rm -f src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-dt-reader.Plo + -rm -f src/nm-initrd-generator/$(DEPDIR)/libnmi_core_la-nmi-ibft-reader.Plo + -rm -f src/nm-initrd-generator/$(DEPDIR)/nm_initrd_generator-nm-initrd-generator.Po + -rm -f src/nm-initrd-generator/tests/$(DEPDIR)/test_cmdline_reader-test-cmdline-reader.Po + -rm -f src/nm-initrd-generator/tests/$(DEPDIR)/test_dt_reader-test-dt-reader.Po + -rm -f src/nm-initrd-generator/tests/$(DEPDIR)/test_ibft_reader-test-ibft-reader.Po + -rm -f src/nm-online/$(DEPDIR)/nm_online-nm-online.Po + -rm -f src/nmcli/$(DEPDIR)/generate_docs_nm_settings_nmcli-generate-docs-nm-settings-nmcli.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-agent.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-common.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-connections.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-devices.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-general.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-nmcli.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-polkit-agent.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-settings.Po + -rm -f src/nmcli/$(DEPDIR)/nmcli-utils.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nm-editor-bindings.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nm-editor-utils.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-address-list.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-connect-connection-list.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-device-entry.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-edit-connection-list.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-editor-grid.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page-device.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-editor-page.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-editor-section.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-editor.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-ip-entry.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-mac-entry.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-mtu-entry.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-bond.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge-port.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-bridge.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-dsl.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-ethernet.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-infiniband.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip-tunnel.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip4.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-ip6.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-ppp.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-team-port.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-team.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-vlan.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-page-wifi.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-password-dialog.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-password-fields.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-route-editor.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-route-entry.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-route-table.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-slave-list.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-utils.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmt-widget-list.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmtui-connect.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmtui-edit.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmtui-hostname.Po + -rm -f src/nmtui/$(DEPDIR)/nmtui-nmtui.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -20563,20 +20772,27 @@ config-extra.h: config-extra.h.mk config.h config.status echo "#define SYSCONFDIR \"$(sysconfdir)\"" >>$@ && \ true -$(libnm_core_lib_h_pub_mkenums): config-extra.h -libnm-core/.dirstamp: config-extra.h -shared/.dirstamp: config-extra.h -shared/nm-base/.dirstamp: config-extra.h -shared/nm-glib-aux/.dirstamp: config-extra.h -shared/nm-glib-aux/tests/.dirstamp: config-extra.h -shared/nm-platform/.dirstamp: config-extra.h -shared/nm-platform/tests/.dirstamp: config-extra.h -shared/nm-std-aux/.dirstamp: config-extra.h -shared/nm-udev-aux/.dirstamp: config-extra.h -shared/systemd/.dirstamp: config-extra.h -shared/systemd/src/basic/.dirstamp: config-extra.h -shared/systemd/src/shared/.dirstamp: config-extra.h -src/core/dhcp/.dirstamp: config-extra.h +$(src_libnm_core_public_mkenums_h): config-extra.h +$(src_libnm_core_public_mkenums_c): config-extra.h +src/libnm-core-impl/.dirstamp: config-extra.h +src/libnm-core-impl/.dirstamp: config-extra.h +src/libnm-base/.dirstamp: config-extra.h +src/libnm-glib-aux/.dirstamp: config-extra.h +src/libnm-glib-aux/tests/.dirstamp: config-extra.h +src/libnm-log-core/.dirstamp: config-extra.h +src/libnm-log-null/.dirstamp: config-extra.h +src/libnm-platform/.dirstamp: config-extra.h +src/libnm-platform/tests/.dirstamp: config-extra.h +src/libnm-platform/wifi/.dirstamp: config-extra.h +src/libnm-platform/wpan/.dirstamp: config-extra.h +src/libnm-std-aux/.dirstamp: config-extra.h +src/libnm-udev-aux/.dirstamp: config-extra.h +src/libnm-systemd-shared/.dirstamp: config-extra.h +src/libnm-systemd-shared/src/basic/.dirstamp: config-extra.h +src/libnm-systemd-shared/src/shared/.dirstamp: config-extra.h +src/libnm-client-public/.dirstamp: config-extra.h +src/libnm-client-public/.dirstamp: config-extra.h +src/core/dhcp/.dirstamp: config-extra.h dist-configure-check: @echo "*** 'make dist' requires '--enable-gtk-doc --enable-introspection'. ***" @@ -20599,12 +20815,18 @@ install-data-hook-dirs: @INTLTOOL_POLICY_RULE@ -$(libnm_core_nm_libnm_core_intern_libnm_libnm_core_intern_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_libnm_core_aux_intern_libnm_core_aux_intern_la_OBJECTS): $(src_libnm_core_public_mkenums_h) + +$(src_libnm_core_aux_extern_libnm_core_aux_extern_la_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(libnm_core_nm_libnm_core_aux_libnm_libnm_core_aux_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_libnm_client_aux_extern_libnm_client_aux_extern_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_client_aux_extern_libnm_client_aux_extern_la_OBJECTS): $(src_libnm_client_public_mkenums_h) -$(libnm_nm_libnm_aux_libnm_libnm_aux_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_nm_libnm_aux_libnm_libnm_aux_la_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_libnm_client_aux_extern_tests_test_libnm_client_aux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_client_aux_extern_tests_test_libnm_client_aux_OBJECTS): $(src_libnm_client_public_mkenums_h) + +$(src_libnm_client_test_libnm_client_test_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_client_test_libnm_client_test_la_OBJECTS): $(src_libnm_client_public_mkenums_h) introspection/%.c: introspection/%.xml @$(MKDIR_P) introspection/ @@ -20621,136 +20843,142 @@ introspection/%.h: introspection/%.c docs/api/dbus-%.xml: introspection/%.c $() -$(libnm_libnm_static_la_OBJECTS): $(introspection_sources) -$(libnm_libnm_la_OBJECTS): $(introspection_sources) +$(src_libnm_client_impl_libnm_client_impl_la_OBJECTS): $(introspection_sources) +$(src_libnm_client_impl_libnm_la_OBJECTS): $(introspection_sources) check-docs: $(srcdir)/tools/check-docs.sh "$(srcdir)" "$(builddir)" -libnm-core/nm-core-enum-types.h.stamp: libnm-core/.dirstamp -libnm-core/nm-core-enum-types.c.stamp: libnm-core/.dirstamp - -$(dispatcher_libnm_dispatcher_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(dispatcher_nm_dispatcher_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_libnm_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_libnm_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_tests_libnm_vpn_plugin_utils_test_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_NetworkManager_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_adsl_libnm_device_plugin_adsl_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_team_libnm_device_plugin_team_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_wifi_libnm_device_plugin_wifi_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_wwan_libnm_device_plugin_wwan_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_ovs_libnm_device_plugin_ovs_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -libnm-core/nm-vpn-dbus-types.xml: libnm-core/nm-vpn-dbus-interface.h tools/enums-to-docbook.pl - @$(MKDIR_P) libnm-core/ +src/libnm-client-public/nm-enum-types.h.stamp: src/libnm-client-public/.dirstamp +src/libnm-client-public/nm-enum-types.c.stamp: src/libnm-client-public/.dirstamp + +src/libnm-core-public/nm-core-enum-types.h.stamp: src/libnm-core-public/.dirstamp +src/libnm-core-public/nm-core-enum-types.c.stamp: src/libnm-core-public/.dirstamp + +$(src_nm_dispatcher_libnm_dispatcher_core_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_dispatcher_nm_dispatcher_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_libnm_core_impl_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_client_impl_libnm_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_contrib_tests_libnm_vpn_plugin_utils_test_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_NetworkManager_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_adsl_libnm_device_plugin_adsl_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_bluetooth_libnm_device_plugin_bluetooth_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_team_libnm_device_plugin_team_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_wifi_libnm_device_plugin_wifi_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_wwan_libnm_device_plugin_wwan_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_ovs_libnm_device_plugin_ovs_la_OBJECTS): $(src_libnm_core_public_mkenums_h) + +src/libnm-core-public/nm-vpn-dbus-types.xml: src/libnm-core-public/nm-vpn-dbus-interface.h tools/enums-to-docbook.pl + @$(MKDIR_P) src/libnm-core-public/ $(AM_V_GEN) @PERL@ $(srcdir)/tools/enums-to-docbook.pl 'nm-vpn-dbus-types' 'VPN Plugin D-Bus API Types' $< >$@ -libnm-core/nm-dbus-types.xml: libnm-core/nm-dbus-interface.h tools/enums-to-docbook.pl - @$(MKDIR_P) libnm-core/ +src/libnm-core-public/nm-dbus-types.xml: src/libnm-core-public/nm-dbus-interface.h tools/enums-to-docbook.pl + @$(MKDIR_P) src/libnm-core-public/ $(AM_V_GEN) @PERL@ $(srcdir)/tools/enums-to-docbook.pl 'nm-dbus-types' 'NetworkManager D-Bus API Types' $< >$@ -libnm-core/tests/nm-core-tests-enum-types.h.stamp: libnm-core/tests/.dirstamp -libnm-core/tests/nm-core-tests-enum-types.c.stamp: libnm-core/tests/.dirstamp +src/libnm-core-impl/tests/nm-core-tests-enum-types.h.stamp: src/libnm-core-impl/tests/.dirstamp +src/libnm-core-impl/tests/nm-core-tests-enum-types.c.stamp: src/libnm-core-impl/tests/.dirstamp -$(libnm_core_tests_test_general_OBJECTS): libnm-core/tests/nm-core-tests-enum-types.h +$(src_libnm_core_impl_tests_test_general_OBJECTS): src/libnm-core-impl/tests/nm-core-tests-enum-types.h -$(libnm_core_tests_test_compare_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_crypto_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_general_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_keyfile_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_secrets_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_setting_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_core_tests_test_settings_defaults_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_libnm_core_impl_tests_test_compare_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_crypto_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_general_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_keyfile_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_secrets_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_setting_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnm_core_impl_tests_test_settings_defaults_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(libnm_libnm_static_la_OBJECTS) : $(libnm_lib_h_pub_mkenums) -$(libnm_libnm_static_la_OBJECTS) : $(libnm_core_lib_h_pub_mkenums) +$(src_libnm_client_impl_libnm_client_impl_la_OBJECTS) : $(src_libnm_client_public_mkenums_h) +$(src_libnm_client_impl_libnm_client_impl_la_OBJECTS) : $(src_libnm_core_public_mkenums_h) -$(dispatcher_nm_dispatcher_OBJECTS): $(libnm_lib_h_pub_mkenums) -$(dispatcher_libnm_dispatcher_core_la_OBJECTS): $(libnm_lib_h_pub_mkenums) -$(libnm_libnm_la_OBJECTS): $(libnm_lib_h_pub_mkenums) -$(libnm_tests_libnm_vpn_plugin_utils_test_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_nm_dispatcher_nm_dispatcher_OBJECTS): $(src_libnm_client_public_mkenums_h) +$(src_nm_dispatcher_libnm_dispatcher_core_la_OBJECTS): $(src_libnm_client_public_mkenums_h) +$(src_libnm_client_impl_libnm_la_OBJECTS): $(src_libnm_client_public_mkenums_h) +$(src_contrib_tests_libnm_vpn_plugin_utils_test_la_OBJECTS): $(src_libnm_client_public_mkenums_h) -check-local-exports-libnm: libnm/libnm.la - $(srcdir)/tools/check-exports.sh "$(builddir)/libnm/.libs/libnm.so" "$(srcdir)/libnm/libnm.ver" +check-local-exports-libnm: src/libnm-client-impl/libnm.la + $(srcdir)/tools/check-exports.sh "$(builddir)/src/libnm-client-impl/.libs/libnm.so" "$(srcdir)/src/libnm-client-impl/libnm.ver" -@HAVE_INTROSPECTION_TRUE@libnm/NM-1.0.gir: libnm/libnm.la +@HAVE_INTROSPECTION_TRUE@src/libnm-client-impl/NM-1.0.gir: src/libnm-client-impl/libnm.la -@HAVE_INTROSPECTION_TRUE@libnm/libnm.typelib: libnm/libnm.gir -@HAVE_INTROSPECTION_TRUE@ $(INTROSPECTION_COMPILER) --includedir=$(srcdir)/libnm-core --includedir=$(builddir)/libnm-core --includedir=$(srcdir)/libnm --includedir=$(builddir)/libnm $< -o $@ +@HAVE_INTROSPECTION_TRUE@src/libnm-client-impl/libnm.typelib: src/libnm-client-impl/libnm.gir +@HAVE_INTROSPECTION_TRUE@ $(INTROSPECTION_COMPILER) --includedir=$(srcdir)/src/libnm-core-public --includedir=$(builddir)/src/libnm-core-public --includedir=$(srcdir)/libnm-client-public --includedir=$(builddir)/libnm-client-public $< -o $@ -@BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@clients/cli/generate-docs-nm-settings-nmcli.xml: clients/cli/generate-docs-nm-settings-nmcli -@BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) clients/cli/generate-docs-nm-settings-nmcli > "$@" -@BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@check-local-generate-docs-nm-settings-nmcli: clients/cli/generate-docs-nm-settings-nmcli.xml +@BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@src/nmcli/generate-docs-nm-settings-nmcli.xml: src/nmcli/generate-docs-nm-settings-nmcli +@BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) src/nmcli/generate-docs-nm-settings-nmcli > "$@" +@BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@check-local-generate-docs-nm-settings-nmcli: src/nmcli/generate-docs-nm-settings-nmcli.xml @BUILD_DOCS_TRUE@@HAVE_INTROSPECTION_TRUE@ $(srcdir)/tools/check-compare-generated.sh "$(srcdir)" "$(builddir)" "$<" -@BUILD_DOCS_FALSE@@HAVE_INTROSPECTION_TRUE@clients/cli/generate-docs-nm-settings-nmcli.xml: clients/cli/generate-docs-nm-settings-nmcli.xml.in +@BUILD_DOCS_FALSE@@HAVE_INTROSPECTION_TRUE@src/nmcli/generate-docs-nm-settings-nmcli.xml: src/nmcli/generate-docs-nm-settings-nmcli.xml.in @BUILD_DOCS_FALSE@@HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) cp $^ $@ @BUILD_DOCS_FALSE@@HAVE_INTROSPECTION_TRUE@check-local-generate-docs-nm-settings-nmcli: -@HAVE_INTROSPECTION_TRUE@libnm/nm-property-infos-%.xml: tools/generate-docs-nm-property-infos.pl $(libnm_docs_sources) +@HAVE_INTROSPECTION_TRUE@src/libnm-client-impl/nm-property-infos-%.xml: tools/generate-docs-nm-property-infos.pl $(libnm_docs_sources) @HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) $(srcdir)/tools/generate-docs-nm-property-infos.pl $(patsubst nm-property-infos-%.xml,%,$(notdir $@)) $@ $(filter-out $<,$^) -@HAVE_INTROSPECTION_TRUE@libnm/nm-settings-docs-gir.xml: tools/generate-docs-nm-settings-docs-gir.py libnm/NM-1.0.gir libnm/NM-1.0.typelib libnm/libnm.la $(libnm_docs_sources) +@HAVE_INTROSPECTION_TRUE@src/libnm-client-impl/nm-settings-docs-gir.xml: tools/generate-docs-nm-settings-docs-gir.py src/libnm-client-impl/NM-1.0.gir src/libnm-client-impl/NM-1.0.typelib src/libnm-client-impl/libnm.la $(libnm_docs_sources) @HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) \ -@HAVE_INTROSPECTION_TRUE@ export GI_TYPELIB_PATH=$(abs_builddir)/libnm$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \ -@HAVE_INTROSPECTION_TRUE@ export LD_LIBRARY_PATH=$(abs_builddir)/libnm/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \ -@HAVE_INTROSPECTION_TRUE@ $(call set_sanitizer_env,$(abs_builddir)/libnm/.libs/libnm.so); \ +@HAVE_INTROSPECTION_TRUE@ export GI_TYPELIB_PATH=$(abs_builddir)/src/libnm-client-impl$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \ +@HAVE_INTROSPECTION_TRUE@ export LD_LIBRARY_PATH=$(abs_builddir)/src/libnm-client-impl/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \ +@HAVE_INTROSPECTION_TRUE@ $(call set_sanitizer_env,$(abs_builddir)/src/libnm-client-impl/.libs/libnm.so); \ @HAVE_INTROSPECTION_TRUE@ "$(PYTHON)" \ @HAVE_INTROSPECTION_TRUE@ $(srcdir)/tools/generate-docs-nm-settings-docs-gir.py \ -@HAVE_INTROSPECTION_TRUE@ --gir $(builddir)/libnm/NM-1.0.gir \ +@HAVE_INTROSPECTION_TRUE@ --gir $(builddir)/src/libnm-client-impl/NM-1.0.gir \ @HAVE_INTROSPECTION_TRUE@ --output $@ -@HAVE_INTROSPECTION_TRUE@man/nm-settings-docs-nmcli.xml: clients/cli/generate-docs-nm-settings-nmcli.xml libnm/nm-property-infos-nmcli.xml libnm/nm-settings-docs-gir.xml tools/generate-docs-nm-settings-docs-merge.py man/common.ent +@HAVE_INTROSPECTION_TRUE@man/nm-settings-docs-nmcli.xml: src/nmcli/generate-docs-nm-settings-nmcli.xml src/libnm-client-impl/nm-property-infos-nmcli.xml src/libnm-client-impl/nm-settings-docs-gir.xml tools/generate-docs-nm-settings-docs-merge.py man/common.ent @HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) "$(PYTHON)" $(srcdir)/tools/generate-docs-nm-settings-docs-merge.py --only-from-first $@ $(wordlist 1,3,$^) -@HAVE_INTROSPECTION_TRUE@man/nm-settings-docs-%.xml: libnm/nm-property-infos-%.xml libnm/nm-settings-docs-gir.xml tools/generate-docs-nm-settings-docs-merge.py man/common.ent +@HAVE_INTROSPECTION_TRUE@src/libnmc-setting/settings-docs-input.xml: src/libnm-client-impl/nm-property-infos-nmcli.xml src/libnm-client-impl/nm-settings-docs-gir.xml tools/generate-docs-nm-settings-docs-merge.py +@HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) "$(PYTHON)" $(srcdir)/tools/generate-docs-nm-settings-docs-merge.py $@ $(wordlist 1,2,$^) + +@HAVE_INTROSPECTION_TRUE@man/nm-settings-docs-%.xml: src/libnm-client-impl/nm-property-infos-%.xml src/libnm-client-impl/nm-settings-docs-gir.xml tools/generate-docs-nm-settings-docs-merge.py man/common.ent @HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) "$(PYTHON)" $(srcdir)/tools/generate-docs-nm-settings-docs-merge.py $@ $(wordlist 1,2,$^) -$(libnm_tests_test_libnm_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_tests_test_nm_client_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_tests_test_remote_settings_client_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(libnm_tests_test_secret_agent_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_libnm_client_impl_tests_test_libnm_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(src_libnm_client_impl_tests_test_nm_client_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(src_libnm_client_impl_tests_test_remote_settings_client_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(src_libnm_client_impl_tests_test_secret_agent_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) # tools/test-networkmanager-service.py uses libnm's typelib. Ensure it # is built first. -$(libnm_tests_test_nm_client_OBJECTS): $(libnm_NM_1_0_typelib) -$(libnm_tests_test_remote_settings_client_OBJECTS): $(libnm_NM_1_0_typelib) -$(libnm_tests_test_secret_agent_OBJECTS): $(libnm_NM_1_0_typelib) +$(src_libnm_client_impl_tests_test_nm_client_OBJECTS): $(src_libnm_client_impl_NM_1_0_typelib) +$(src_libnm_client_impl_tests_test_remote_settings_client_OBJECTS): $(src_libnm_client_impl_NM_1_0_typelib) +$(src_libnm_client_impl_tests_test_secret_agent_OBJECTS): $(src_libnm_client_impl_NM_1_0_typelib) check-config-options: $(srcdir)/tools/check-config-options.sh "$(srcdir)" -$(src_core_libnm_systemd_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_libnm_systemd_core_la_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(src_core_libNetworkManagerBase_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_libNetworkManagerBase_la_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(src_core_libNetworkManager_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_libNetworkManager_la_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(src_core_libNetworkManagerTest_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_libNetworkManagerTest_la_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(src_core_NetworkManager_all_sym_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_NetworkManager_all_sym_OBJECTS): $(src_libnm_core_public_mkenums_h) src/core/NetworkManager.ver: src/core/NetworkManager-all-sym $(core_plugins) $(AM_V_GEN) NM="$(NM)" "$(srcdir)/tools/create-exports-NetworkManager.sh" --called-from-build "$(srcdir)" -$(src_core_NetworkManager_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_NetworkManager_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(src_core_nm_iface_helper_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_nm_iface_helper_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(src_core_initrd_libnmi_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_initrd_nm_initrd_generator_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_initrd_tests_test_cmdline_reader_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_initrd_tests_test_ibft_reader_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_initrd_tests_test_dt_reader_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_nm_initrd_generator_libnmi_core_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_initrd_generator_nm_initrd_generator_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_initrd_generator_tests_test_cmdline_reader_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_initrd_generator_tests_test_ibft_reader_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_initrd_generator_tests_test_dt_reader_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(src_core_dhcp_tests_test_dhcp_dhclient_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_dhcp_tests_test_dhcp_utils_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_dhcp_tests_test_dhcp_dhclient_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_dhcp_tests_test_dhcp_utils_OBJECTS): $(src_libnm_core_public_mkenums_h) -@WITH_PPP_TRUE@$(src_core_ppp_nm_pppd_plugin_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@WITH_PPP_TRUE@$(src_core_ppp_nm_pppd_plugin_la_OBJECTS): $(src_libnm_core_public_mkenums_h) -@WITH_PPP_TRUE@$(src_core_ppp_libnm_ppp_plugin_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@WITH_PPP_TRUE@$(src_core_ppp_libnm_ppp_plugin_la_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_OBJECTS): $(src_libnm_core_public_mkenums_h) @CONFIG_PLUGIN_IFCFG_RH_TRUE@src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.h: src/core/settings/plugins/ifcfg-rh/nm-ifcfg-rh.xml @CONFIG_PLUGIN_IFCFG_RH_TRUE@ @$(MKDIR_P) src/core/settings/plugins/ifcfg-rh/ @@ -20763,15 +20991,15 @@ $(src_core_settings_plugins_keyfile_tests_test_keyfile_settings_OBJECTS): $(libn @CONFIG_PLUGIN_IFCFG_RH_TRUE@src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.c: src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.h @CONFIG_PLUGIN_IFCFG_RH_TRUE@ @true -@CONFIG_PLUGIN_IFCFG_RH_TRUE@$(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@CONFIG_PLUGIN_IFCFG_RH_TRUE@$(src_core_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_OBJECTS): $(src_libnm_core_public_mkenums_h) @CONFIG_PLUGIN_IFCFG_RH_TRUE@$(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_OBJECTS): src/core/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.h -@CONFIG_PLUGIN_IFCFG_RH_TRUE@$(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@CONFIG_PLUGIN_IFCFG_RH_TRUE@$(src_core_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_OBJECTS): $(src_libnm_core_public_mkenums_h) @CONFIG_PLUGIN_IFCFG_RH_TRUE@check-local-symbols-settings-ifcfg-rh: src/core/settings/plugins/ifcfg-rh/libnm-settings-plugin-ifcfg-rh.la @CONFIG_PLUGIN_IFCFG_RH_TRUE@ $(call check_so_symbols,$(builddir)/src/core/settings/plugins/ifcfg-rh/.libs/libnm-settings-plugin-ifcfg-rh.so) -@CONFIG_PLUGIN_IFCFG_RH_TRUE@$(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@CONFIG_PLUGIN_IFCFG_RH_TRUE@$(src_core_settings_plugins_ifcfg_rh_tests_test_ifcfg_rh_OBJECTS): $(src_libnm_core_public_mkenums_h) @CONFIG_PLUGIN_IFCFG_RH_TRUE@install-data-hook-ifcfg-rh: @CONFIG_PLUGIN_IFCFG_RH_TRUE@ $(mkinstalldirs) -m 0755 $(DESTDIR)$(sysconfdir)/sysconfig/network-scripts @@ -20781,19 +21009,19 @@ dist-hook-settings-ifcfg-rh-alias-files: cp $(abs_srcdir)/$$f $(distdir)/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/; \ done -@CONFIG_PLUGIN_IFUPDOWN_TRUE@$(src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -@CONFIG_PLUGIN_IFUPDOWN_TRUE@$(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@CONFIG_PLUGIN_IFUPDOWN_TRUE@$(src_core_settings_plugins_ifupdown_libnm_settings_plugin_ifupdown_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +@CONFIG_PLUGIN_IFUPDOWN_TRUE@$(src_core_settings_plugins_ifupdown_libnms_ifupdown_core_la_OBJECTS): $(src_libnm_core_public_mkenums_h) @CONFIG_PLUGIN_IFUPDOWN_TRUE@check-local-symbols-settings-ifupdown: src/core/settings/plugins/ifupdown/libnm-settings-plugin-ifupdown.la @CONFIG_PLUGIN_IFUPDOWN_TRUE@ $(call check_so_symbols,$(builddir)/src/core/settings/plugins/ifupdown/.libs/libnm-settings-plugin-ifupdown.so) -@CONFIG_PLUGIN_IFUPDOWN_TRUE@$(src_core_settings_plugins_ifupdown_tests_test_ifupdown_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@CONFIG_PLUGIN_IFUPDOWN_TRUE@$(src_core_settings_plugins_ifupdown_tests_test_ifupdown_OBJECTS): $(src_libnm_core_public_mkenums_h) check-local-devices-adsl: src/core/devices/adsl/libnm-device-plugin-adsl.la $(srcdir)/tools/check-exports.sh $(builddir)/src/core/devices/adsl/.libs/libnm-device-plugin-adsl.so "$(srcdir)/linker-script-devices.ver" $(call check_so_symbols,$(builddir)/src/core/devices/adsl/.libs/libnm-device-plugin-adsl.so) -@WITH_MODEM_MANAGER_1_TRUE@$(src_core_devices_wwan_libnm_wwan_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@WITH_MODEM_MANAGER_1_TRUE@$(src_core_devices_wwan_libnm_wwan_la_OBJECTS): $(src_libnm_core_public_mkenums_h) @WITH_MODEM_MANAGER_1_TRUE@check-local-devices-wwan: src/core/devices/wwan/libnm-device-plugin-wwan.la src/core/devices/wwan/libnm-wwan.la @WITH_MODEM_MANAGER_1_TRUE@ $(srcdir)/tools/check-exports.sh $(builddir)/src/core/devices/wwan/.libs/libnm-device-plugin-wwan.so "$(srcdir)/linker-script-devices.ver" @@ -20801,11 +21029,11 @@ check-local-devices-adsl: src/core/devices/adsl/libnm-device-plugin-adsl.la @WITH_MODEM_MANAGER_1_TRUE@ $(srcdir)/tools/check-exports.sh $(builddir)/src/core/devices/wwan/.libs/libnm-wwan.so "$(srcdir)/src/core/devices/wwan/libnm-wwan.ver" @WITH_MODEM_MANAGER_1_TRUE@ $(call check_so_symbols,$(builddir)/src/core/devices/wwan/.libs/libnm-wwan.so) -@WITH_MODEM_MANAGER_1_TRUE@$(src_core_devices_wwan_tests_test_service_providers_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@WITH_MODEM_MANAGER_1_TRUE@$(src_core_devices_wwan_tests_test_service_providers_OBJECTS): $(src_libnm_core_public_mkenums_h) -@WITH_MODEM_MANAGER_1_TRUE@$(src_core_devices_bluetooth_libnm_bluetooth_utils_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@WITH_MODEM_MANAGER_1_TRUE@$(src_core_devices_bluetooth_libnm_bluetooth_utils_la_OBJECTS): $(src_libnm_core_public_mkenums_h) -@WITH_MODEM_MANAGER_1_TRUE@$(src_core_devices_bluetooth_tests_nm_bt_test_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@WITH_MODEM_MANAGER_1_TRUE@$(src_core_devices_bluetooth_tests_nm_bt_test_OBJECTS): $(src_libnm_core_public_mkenums_h) ############################################################################### @@ -20813,13 +21041,13 @@ check-local-devices-adsl: src/core/devices/adsl/libnm-device-plugin-adsl.la @WITH_MODEM_MANAGER_1_TRUE@ $(srcdir)/tools/check-exports.sh $(builddir)/src/core/devices/bluetooth/.libs/libnm-device-plugin-bluetooth.so "$(srcdir)/linker-script-devices.ver" @WITH_MODEM_MANAGER_1_TRUE@ $(call check_so_symbols,$(builddir)/src/core/devices/bluetooth/.libs/libnm-device-plugin-bluetooth.so) -@WITH_WIFI_TRUE@$(src_core_devices_wifi_libnm_wifi_base_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@WITH_WIFI_TRUE@$(src_core_devices_wifi_libnm_wifi_base_la_OBJECTS): $(src_libnm_core_public_mkenums_h) @WITH_WIFI_TRUE@check-local-devices-wifi: src/core/devices/wifi/libnm-device-plugin-wifi.la @WITH_WIFI_TRUE@ $(srcdir)/tools/check-exports.sh $(builddir)/src/core/devices/wifi/.libs/libnm-device-plugin-wifi.so "$(srcdir)/linker-script-devices.ver" @WITH_WIFI_TRUE@ $(call check_so_symbols,$(builddir)/src/core/devices/wifi/.libs/libnm-device-plugin-wifi.so) -@WITH_WIFI_TRUE@$(src_core_devices_wifi_tests_test_devices_wifi_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@WITH_WIFI_TRUE@$(src_core_devices_wifi_tests_test_devices_wifi_OBJECTS): $(src_libnm_core_public_mkenums_h) @WITH_TEAMDCTL_TRUE@check-local-devices-team: src/core/devices/team/libnm-device-plugin-team.la @WITH_TEAMDCTL_TRUE@ $(srcdir)/tools/check-exports.sh $(builddir)/src/core/devices/team/.libs/libnm-device-plugin-team.so "$(srcdir)/linker-script-devices.ver" @@ -20829,54 +21057,54 @@ check-local-devices-adsl: src/core/devices/adsl/libnm-device-plugin-adsl.la @WITH_OPENVSWITCH_TRUE@ $(srcdir)/tools/check-exports.sh $(builddir)/src/core/devices/ovs/.libs/libnm-device-plugin-ovs.so "$(srcdir)/linker-script-devices.ver" @WITH_OPENVSWITCH_TRUE@ $(call check_so_symbols,$(builddir)/src/core/devices/ovs/.libs/libnm-device-plugin-ovs.so) -$(src_core_dnsmasq_tests_test_dnsmasq_utils_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -$(src_core_platform_tests_monitor_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_address_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_address_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_cleanup_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_cleanup_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_link_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_link_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_nmp_object_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_platform_general_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_route_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_route_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_tc_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_platform_tests_test_tc_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -$(src_core_devices_tests_test_lldp_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_devices_tests_test_acd_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -$(src_core_ndisc_tests_test_ndisc_linux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_ndisc_tests_test_ndisc_fake_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -$(src_core_supplicant_tests_test_supplicant_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -$(src_core_tests_config_test_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -$(src_core_tests_test_core_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_core_with_expect_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_dcb_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_ip4_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_ip6_config_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_l3cfg_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_utils_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(src_core_tests_test_wired_defname_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -$(src_core_tests_test_systemd_OBJECTS): $(libnm_core_lib_h_pub_mkenums) - -dispatcher/nmdbus-dispatcher.h: dispatcher/nm-dispatcher.xml - @$(MKDIR_P) dispatcher/ +$(src_core_dnsmasq_tests_test_dnsmasq_utils_OBJECTS): $(src_libnm_core_public_mkenums_h) + +$(src_core_platform_tests_monitor_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_address_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_address_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_cleanup_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_cleanup_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_link_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_link_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_nmp_object_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_platform_general_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_route_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_route_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_tc_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_platform_tests_test_tc_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) + +$(src_core_devices_tests_test_lldp_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_devices_tests_test_acd_OBJECTS): $(src_libnm_core_public_mkenums_h) + +$(src_core_ndisc_tests_test_ndisc_linux_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_ndisc_tests_test_ndisc_fake_OBJECTS): $(src_libnm_core_public_mkenums_h) + +$(src_core_supplicant_tests_test_supplicant_config_OBJECTS): $(src_libnm_core_public_mkenums_h) + +$(src_core_tests_config_test_config_OBJECTS): $(src_libnm_core_public_mkenums_h) + +$(src_core_tests_test_core_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_core_with_expect_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_dcb_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_ip4_config_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_ip6_config_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_l3cfg_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_utils_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_core_tests_test_wired_defname_OBJECTS): $(src_libnm_core_public_mkenums_h) + +$(src_core_tests_test_systemd_OBJECTS): $(src_libnm_core_public_mkenums_h) + +src/nm-dispatcher/nmdbus-dispatcher.h: src/nm-dispatcher/nm-dispatcher.xml + @$(MKDIR_P) src/nm-dispatcher/ $(AM_V_GEN) gdbus-codegen \ --generate-c-code $(basename $@) \ --c-namespace NMDBus \ --interface-prefix org.freedesktop \ $< -dispatcher/nmdbus-dispatcher.c: dispatcher/nmdbus-dispatcher.h +src/nm-dispatcher/nmdbus-dispatcher.c: src/nm-dispatcher/nmdbus-dispatcher.h -dispatcher/org.freedesktop.nm_dispatcher.service: $(srcdir)/dispatcher/org.freedesktop.nm_dispatcher.service.in +src/nm-dispatcher/org.freedesktop.nm_dispatcher.service: $(srcdir)/src/nm-dispatcher/org.freedesktop.nm_dispatcher.service.in @sed \ -e 's|@sbindir[@]|$(sbindir)|g' \ -e 's|@sysconfdir[@]|$(sysconfdir)|g' \ @@ -20894,49 +21122,51 @@ install-data-hook-dispatcher: $(mkinstalldirs) -m 0755 $(DESTDIR)$(nmlibdir)/dispatcher.d/pre-up.d $(mkinstalldirs) -m 0755 $(DESTDIR)$(nmlibdir)/dispatcher.d/no-wait.d -$(dispatcher_tests_test_dispatcher_envp_OBJECTS): $(dispatcher_nmdbus_dispatcher_sources) +$(src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS): $(dispatcher_nmdbus_dispatcher_sources) +$(src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS): $(src_libnm_client_public_mkenums_h) -$(dispatcher_tests_test_dispatcher_envp_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_nm_dispatcher_tests_test_dispatcher_envp_OBJECTS): $(src_libnm_core_public_mkenums_h) -$(clients_nm_online_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_nm_online_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_nm_online_nm_online_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nm_online_nm_online_OBJECTS): $(src_libnm_client_public_mkenums_h) -$(clients_common_libnmc_base_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_common_libnmc_base_la_OBJECTS): $(libnm_lib_h_pub_mkenums) -$(clients_common_libnmc_base_la_OBJECTS): clients/common/.dirstamp -@BUILD_DOCS_TRUE@$(clients_common_settings_doc_h): clients/common/settings-docs.xsl libnm/nm-settings-docs-gir.xml clients/common/.dirstamp +$(src_libnmc_base_libnmc_base_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnmc_base_libnmc_base_la_OBJECTS): $(src_libnm_client_public_mkenums_h) +@BUILD_DOCS_TRUE@$(libnmc_setting_settings_doc_h): src/libnmc-setting/settings-docs.xsl src/libnmc-setting/settings-docs-input.xml src/libnmc-setting/.dirstamp @BUILD_DOCS_TRUE@ $(AM_V_GEN) $(XSLTPROC) --output $@ $< $(word 2,$^) -@BUILD_DOCS_TRUE@check-local-settings-docs: $(clients_common_settings_doc_h) -@BUILD_DOCS_TRUE@ $(srcdir)/tools/check-compare-generated.sh "$(srcdir)" "$(builddir)" "$(clients_common_settings_doc_h)" -@BUILD_DOCS_FALSE@$(clients_common_settings_doc_h): $(clients_common_settings_doc_h).in clients/common/.dirstamp -@BUILD_DOCS_FALSE@ $(AM_V_GEN) cp "$(srcdir)/$(clients_common_settings_doc_h).in" "$(builddir)/$(clients_common_settings_doc_h)" +@BUILD_DOCS_TRUE@check-local-settings-docs: $(libnmc_setting_settings_doc_h) +@BUILD_DOCS_TRUE@ $(srcdir)/tools/check-compare-generated.sh "$(srcdir)" "$(builddir)" "$(libnmc_setting_settings_doc_h)" +@BUILD_DOCS_FALSE@$(libnmc_setting_settings_doc_h): $(libnmc_setting_settings_doc_h).in src/libnmc-setting/.dirstamp +@BUILD_DOCS_FALSE@ $(AM_V_GEN) cp "$(srcdir)/$(libnmc_setting_settings_doc_h).in" "$(builddir)/$(libnmc_setting_settings_doc_h)" @BUILD_DOCS_FALSE@check-local-settings-docs: -$(clients_common_libnmc_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_common_libnmc_la_OBJECTS): $(clients_common_settings_doc_h) -$(clients_common_libnmc_la_OBJECTS): clients/common/.dirstamp - -$(clients_common_tests_test_clients_common_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +$(src_libnmc_setting_libnmc_setting_la_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnmc_setting_libnmc_setting_la_OBJECTS): $(src_libnm_client_public_mkenums_h) +$(src_libnmc_setting_libnmc_setting_la_OBJECTS): $(libnmc_setting_settings_doc_h) +$(src_libnmc_setting_libnmc_setting_la_OBJECTS): src/libnmc-setting/.dirstamp -$(clients_common_tests_test_libnm_core_aux_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_common_tests_test_libnm_core_aux_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_libnmc_setting_tests_test_libnmc_setting_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_libnmc_setting_tests_test_libnmc_setting_OBJECTS): $(src_libnm_client_public_mkenums_h) -@BUILD_NMCLI_TRUE@$(clients_cli_nmcli_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -@BUILD_NMCLI_TRUE@$(clients_cli_nmcli_OBJECTS): $(libnm_lib_h_pub_mkenums) +@BUILD_NMCLI_TRUE@$(src_nmcli_nmcli_OBJECTS): $(src_libnm_core_public_mkenums_h) +@BUILD_NMCLI_TRUE@$(src_nmcli_nmcli_OBJECTS): $(src_libnm_client_public_mkenums_h) @BUILD_NMCLI_TRUE@install-data-hook-nmcli: @BUILD_NMCLI_TRUE@ $(mkinstalldirs) $(DESTDIR)$(completiondir) -@BUILD_NMCLI_TRUE@ $(INSTALL_DATA) $(srcdir)/clients/cli/nmcli-completion $(DESTDIR)$(completiondir)/nmcli +@BUILD_NMCLI_TRUE@ $(INSTALL_DATA) $(srcdir)/src/nmcli/nmcli-completion $(DESTDIR)$(completiondir)/nmcli @BUILD_NMCLI_TRUE@uninstall-hook-nmcli: @BUILD_NMCLI_TRUE@ rm -f $(DESTDIR)$(completiondir)/nmcli -$(clients_cli_generate_docs_nm_settings_nmcli_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(clients_cli_generate_docs_nm_settings_nmcli_OBJECTS): $(libnm_lib_h_pub_mkenums) +$(src_nmcli_generate_docs_nm_settings_nmcli_OBJECTS): $(src_libnm_core_public_mkenums_h) +$(src_nmcli_generate_docs_nm_settings_nmcli_OBJECTS): $(src_libnm_client_public_mkenums_h) -@BUILD_NMTUI_TRUE@$(clients_tui_newt_libnmt_newt_a_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@BUILD_NMTUI_TRUE@$(src_libnmt_newt_libnmt_newt_a_OBJECTS): $(src_libnm_core_public_mkenums_h) +@BUILD_NMTUI_TRUE@$(src_libnmt_newt_libnmt_newt_a_OBJECTS): $(src_libnm_client_public_mkenums_h) -@BUILD_NMTUI_TRUE@$(clients_tui_nmtui_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@BUILD_NMTUI_TRUE@$(src_nmtui_nmtui_OBJECTS): $(src_libnm_core_public_mkenums_h) +@BUILD_NMTUI_TRUE@$(src_nmtui_nmtui_OBJECTS): $(src_libnm_client_public_mkenums_h) @BUILD_NMTUI_TRUE@install-exec-hook-nmtui: @BUILD_NMTUI_TRUE@ for link in $(nmtui_links); do \ @@ -20948,41 +21178,34 @@ $(clients_cli_generate_docs_nm_settings_nmcli_OBJECTS): $(libnm_lib_h_pub_mkenum @BUILD_NMTUI_TRUE@ rm -f "$(DESTDIR)$(bindir)/$$link"; \ @BUILD_NMTUI_TRUE@ done -@BUILD_NM_CLOUD_SETUP_TRUE@$(clients_cloud_setup_libnm_cloud_setup_core_a_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -@BUILD_NM_CLOUD_SETUP_TRUE@$(clients_cloud_setup_libnm_cloud_setup_core_a_OBJECTS): $(libnm_lib_h_pub_mkenums) +@BUILD_NM_CLOUD_SETUP_TRUE@$(src_nm_cloud_setup_libnm_cloud_setup_core_a_OBJECTS): $(src_libnm_core_public_mkenums_h) +@BUILD_NM_CLOUD_SETUP_TRUE@$(src_nm_cloud_setup_libnm_cloud_setup_core_a_OBJECTS): $(src_libnm_client_public_mkenums_h) -@BUILD_NM_CLOUD_SETUP_TRUE@$(clients_cloud_setup_nm_cloud_setup_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -@BUILD_NM_CLOUD_SETUP_TRUE@$(clients_cloud_setup_nm_cloud_setup_OBJECTS): $(libnm_lib_h_pub_mkenums) +@BUILD_NM_CLOUD_SETUP_TRUE@$(src_nm_cloud_setup_nm_cloud_setup_OBJECTS): $(src_libnm_core_public_mkenums_h) +@BUILD_NM_CLOUD_SETUP_TRUE@$(src_nm_cloud_setup_nm_cloud_setup_OBJECTS): $(src_libnm_client_public_mkenums_h) -@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@clients/cloud-setup/nm-cloud-setup.service: $(srcdir)/clients/cloud-setup/nm-cloud-setup.service.in +@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@src/nm-cloud-setup/nm-cloud-setup.service: $(srcdir)/src/nm-cloud-setup/nm-cloud-setup.service.in @BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ $(AM_V_GEN) $(data_edit) $< >$@ @BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@install-data-hook-cloud-setup: install-data-hook-dispatcher -@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ $(INSTALL_SCRIPT) "$(srcdir)/clients/cloud-setup/90-nm-cloud-setup.sh" "$(DESTDIR)$(nmlibdir)/dispatcher.d/no-wait.d/" +@BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ $(INSTALL_SCRIPT) "$(srcdir)/src/nm-cloud-setup/90-nm-cloud-setup.sh" "$(DESTDIR)$(nmlibdir)/dispatcher.d/no-wait.d/" @BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ ln -fs no-wait.d/90-nm-cloud-setup.sh "$(DESTDIR)$(nmlibdir)/dispatcher.d/90-nm-cloud-setup.sh" @BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@uninstall-hook-cloud-setup: @BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ rm -f "$(DESTDIR)$(nmlibdir)/dispatcher.d/no-wait.d/90-nm-cloud-setup.sh" @BUILD_NM_CLOUD_SETUP_TRUE@@HAVE_SYSTEMD_TRUE@ rm -f "$(DESTDIR)$(nmlibdir)/dispatcher.d/90-nm-cloud-setup.sh" -@BUILD_NM_CLOUD_SETUP_TRUE@$(clients_cloud_setup_tests_test_cloud_setup_general_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -@BUILD_NM_CLOUD_SETUP_TRUE@$(clients_cloud_setup_tests_test_cloud_setup_general_OBJECTS): $(libnm_lib_h_pub_mkenums) +@BUILD_NM_CLOUD_SETUP_TRUE@$(src_nm_cloud_setup_tests_test_cloud_setup_general_OBJECTS): $(src_libnm_core_public_mkenums_h) +@BUILD_NM_CLOUD_SETUP_TRUE@$(src_nm_cloud_setup_tests_test_cloud_setup_general_OBJECTS): $(src_libnm_client_public_mkenums_h) ############################################################################### -# clients/tests +# src/tests/client ############################################################################### -check-local-clients-tests-test-client: clients/cli/nmcli clients/tests/test-client.py - mkdir -p "$(builddir)/clients/tests/" - "$(builddir)/clients/cli/nmcli" --version - GI_TYPELIB_PATH="$(abs_builddir)/libnm$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}" \ - LD_LIBRARY_PATH="$(abs_builddir)/libnm/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}" \ - NM_TEST_CLIENT_BUILDDIR="$(abs_builddir)" \ - NM_TEST_CLIENT_NMCLI_PATH=clients/cli/nmcli \ - "$(PYTHON)" \ - $(srcdir)/clients/tests/test-client.py -v &> "$(builddir)/clients/tests/test-client.log" && r=ok; \ - cat "$(builddir)/clients/tests/test-client.log"; \ - test "$$r" = ok +check-local-tests-client: src/nmcli/nmcli src/tests/client/test-client.py + "$(srcdir)/src/tests/client/test-client.sh" "$(builddir)" "$(srcdir)" "$(PYTHON)" + +############################################################################### check-local-gitlab-ci: "$(srcdir)/tools/check-gitlab-ci.sh" "$(srcdir)" @@ -21016,9 +21239,9 @@ man/common.ent: man/common.ent.in @HAVE_INTROSPECTION_TRUE@man/nm-settings-%.xml: man/nm-settings-%.xsl man/nm-settings-docs-%.xml man/common.ent @HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) $(XSLTPROC) --output $@ $(xsltproc_flags) $< $(word 2,$^) -@HAVE_INTROSPECTION_TRUE@man/nm-settings-keyfile.xml: man/nm-settings-keyfile.xsl libnm/nm-property-infos-keyfile.xml man/common.ent +@HAVE_INTROSPECTION_TRUE@man/nm-settings-keyfile.xml: man/nm-settings-keyfile.xsl src/libnm-client-impl/nm-property-infos-keyfile.xml man/common.ent @HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) $(XSLTPROC) --output $@ $(xsltproc_flags) $< $(word 2,$^) -@HAVE_INTROSPECTION_TRUE@man/nm-settings-ifcfg-rh.xml: man/nm-settings-ifcfg-rh.xsl libnm/nm-property-infos-ifcfg-rh.xml man/common.ent +@HAVE_INTROSPECTION_TRUE@man/nm-settings-ifcfg-rh.xml: man/nm-settings-ifcfg-rh.xsl src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml man/common.ent @HAVE_INTROSPECTION_TRUE@ $(AM_V_GEN) $(XSLTPROC) --output $@ $(xsltproc_flags) $< $(word 2,$^) @HAVE_DOCS_TRUE@install-data-hook-man: @@ -21035,12 +21258,13 @@ man/common.ent: man/common.ent.in @HAVE_DOCS_TRUE@ rm -f $(DESTDIR)$(mandir)/man5/nm-system-settings.conf.5; \ @HAVE_DOCS_TRUE@ rm -f $(DESTDIR)$(mandir)/man5/nm-settings.5; -@ENABLE_VAPIGEN_TRUE@vapi/libnm.vapi: $(builddir)/libnm/NM-1.0.gir vapi/libnm.deps vapi/NM-1.0.metadata -$(examples_C_glib_add_connection_gdbus_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(examples_C_glib_add_connection_libnm_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(examples_C_glib_get_active_connections_gdbus_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(examples_C_glib_get_ap_info_libnm_OBJECTS): $(libnm_core_lib_h_pub_mkenums) -$(examples_C_glib_list_connections_libnm_OBJECTS): $(libnm_core_lib_h_pub_mkenums) +@ENABLE_VAPIGEN_TRUE@vapi/libnm.vapi: $(builddir)/src/libnm-client-impl/NM-1.0.gir vapi/libnm.deps vapi/NM-1.0.metadata +$(examples_C_glib_add_connection_gdbus_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(examples_C_glib_add_connection_libnm_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(examples_C_glib_get_active_connections_gdbus_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(examples_C_glib_get_ap_info_libnm_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(examples_C_glib_list_connections_libnm_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) +$(examples_C_glib_vpn_import_libnm_OBJECTS): $(src_libnm_core_public_mkenums_h) $(src_libnm_client_public_mkenums_h) @WITH_QT_TRUE@examples/C/qt/monitor-nm-running.moc: examples/C/qt/monitor-nm-running.cpp @WITH_QT_TRUE@ $(AM_V_GEN) $(MOC) -i $< -o $@ @@ -21084,7 +21308,7 @@ uninstall-hook: $(uninstall_hook) ############################################################################### cscope: - cscope -b -q -R -sshared -ssrc -slibnm-core -slibnm -sclients; + cscope -b -q -R -sshared -ssrc -slibnm -sclients; ############################################################################### diff --git a/NEWS b/NEWS index f65738e..4d54d11 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,14 @@ ============================================= +NetworkManager-1.32 +Overview of changes since NetworkManager-1.30 +============================================= + +This is a snapshot of NetworkManager 1.30 development series. +The API is subject to change and not guaranteed to be compatible +with the later release. +USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE! + +============================================= NetworkManager-1.30 Overview of changes since NetworkManager-1.28 ============================================= diff --git a/configure b/configure index 591ee48..b39c9cd 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for NetworkManager 1.30.0. +# Generated by GNU Autoconf 2.69 for NetworkManager 1.31.2. # # Report bugs to . # @@ -591,8 +591,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='NetworkManager' PACKAGE_TARNAME='NetworkManager' -PACKAGE_VERSION='1.30.0' -PACKAGE_STRING='NetworkManager 1.30.0' +PACKAGE_VERSION='1.31.2' +PACKAGE_STRING='NetworkManager 1.31.2' PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=NetworkManager' PACKAGE_URL='' @@ -1723,7 +1723,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures NetworkManager 1.30.0 to adapt to many kinds of systems. +\`configure' configures NetworkManager 1.31.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1793,7 +1793,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of NetworkManager 1.30.0:";; + short | recursive ) echo "Configuration of NetworkManager 1.31.2:";; esac cat <<\_ACEOF @@ -2138,7 +2138,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -NetworkManager configure 1.30.0 +NetworkManager configure 1.31.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2911,7 +2911,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by NetworkManager $as_me 1.30.0, which was +It was created by NetworkManager $as_me 1.31.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3781,7 +3781,7 @@ fi # Define the identity of the package. PACKAGE='NetworkManager' - VERSION='1.30.0' + VERSION='1.31.2' cat >>confdefs.h <<_ACEOF @@ -17964,9 +17964,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu NM_MAJOR_VERSION=1 -NM_MINOR_VERSION=30 -NM_MICRO_VERSION=0 -NM_VERSION=1.30.0 +NM_MINOR_VERSION=31 +NM_MICRO_VERSION=2 +NM_VERSION=1.31.2 @@ -17974,7 +17974,7 @@ NM_VERSION=1.30.0 -NM_GIT_SHA=fc29a96097e0f11ab963c27036b6b8b3e1f3d42b +NM_GIT_SHA=80f63ae01a272d4df7a4daf609825d6ad46461ab if test """" != "no-config-h" ; then @@ -27235,7 +27235,7 @@ fi $as_echo_n "checking CC support C11 _Generic()... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int foo(void); int foo() { int a = 0; int b = _Generic (a, int: 4); return b + a; } +int foo(void); static const char *const buf[1] = { "a" }; int foo() { int a = 0; int b = _Generic (a, int: 4) + _Generic(buf, const char *const*: 5); return b + a; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cc_support_generic=1 @@ -27629,6 +27629,215 @@ fi NM_LOG_COMPILER='LOG_COMPILER = "$(top_srcdir)/tools/run-nm-test.sh" --called-from-make "$(abs_top_builddir)" "$(LIBTOOL)" "$(with_valgrind)" "'"$with_valgrind_suppressions"'" --launch-dbus=auto' +if test -n "$PYTHON" ; then + + + + + + + # Find any Python interpreter. + if test -z "$PYTHON"; then + for ac_prog in python python2 python3 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PYTHON+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PYTHON in + [\\/]* | ?:[\\/]*) + ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PYTHON=$ac_cv_path_PYTHON +if test -n "$PYTHON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 +$as_echo "$PYTHON" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PYTHON" && break +done +test -n "$PYTHON" || PYTHON=":" + + fi + am_display_PYTHON=python + + + if test "$PYTHON" = :; then + as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5 + else + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 +$as_echo_n "checking for $am_display_PYTHON version... " >&6; } +if ${am_cv_python_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 +$as_echo "$am_cv_python_version" >&6; } + PYTHON_VERSION=$am_cv_python_version + + + + PYTHON_PREFIX='${prefix}' + + PYTHON_EXEC_PREFIX='${exec_prefix}' + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 +$as_echo_n "checking for $am_display_PYTHON platform... " >&6; } +if ${am_cv_python_platform+:} false; then : + $as_echo_n "(cached) " >&6 +else + am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 +$as_echo "$am_cv_python_platform" >&6; } + PYTHON_PLATFORM=$am_cv_python_platform + + + # Just factor out some code duplication. + am_python_setup_sysconfig="\ +import sys +# Prefer sysconfig over distutils.sysconfig, for better compatibility +# with python 3.x. See automake bug#10227. +try: + import sysconfig +except ImportError: + can_use_sysconfig = 0 +else: + can_use_sysconfig = 1 +# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: +# +try: + from platform import python_implementation + if python_implementation() == 'CPython' and sys.version[:3] == '2.7': + can_use_sysconfig = 0 +except ImportError: + pass" + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5 +$as_echo_n "checking for $am_display_PYTHON script directory... " >&6; } +if ${am_cv_python_pythondir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$prefix" = xNONE + then + am_py_prefix=$ac_default_prefix + else + am_py_prefix=$prefix + fi + am_cv_python_pythondir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') +sys.stdout.write(sitedir)"` + case $am_cv_python_pythondir in + $am_py_prefix*) + am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` + am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` + ;; + *) + case $am_py_prefix in + /usr|/System*) ;; + *) + am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 +$as_echo "$am_cv_python_pythondir" >&6; } + pythondir=$am_cv_python_pythondir + + + + pkgpythondir=\${pythondir}/$PACKAGE + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5 +$as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; } +if ${am_cv_python_pyexecdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$exec_prefix" = xNONE + then + am_py_exec_prefix=$am_py_prefix + else + am_py_exec_prefix=$exec_prefix + fi + am_cv_python_pyexecdir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') +sys.stdout.write(sitedir)"` + case $am_cv_python_pyexecdir in + $am_py_exec_prefix*) + am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` + am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` + ;; + *) + case $am_py_exec_prefix in + /usr|/System*) ;; + *) + am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 +$as_echo "$am_cv_python_pyexecdir" >&6; } + pyexecdir=$am_cv_python_pyexecdir + + + + pkgpyexecdir=\${pyexecdir}/$PACKAGE + + + + fi + + +else @@ -27890,7 +28099,7 @@ $as_echo "$am_cv_python_pyexecdir" >&6; } fi -if test -z "$PYTHON"; then + if test -z "$PYTHON"; then @@ -27950,7 +28159,7 @@ test -n "$PYTHON" || PYTHON=":" if test "$PYTHON" = :; then - PYTHON=python + as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5 else @@ -28098,6 +28307,7 @@ $as_echo "$am_cv_python_pyexecdir" >&6; } fi + fi fi PYTHON=$PYTHON @@ -28640,6 +28850,7 @@ fi use_pregen_docs=no if test "$build_docs" != "yes" -a \ -f "$srcdir"/man/NetworkManager.8 -a \ + -f "$srcdir"/man/NetworkManager-dispatcher.8 -a \ -f "$srcdir"/man/NetworkManager.conf.5 -a \ -f "$srcdir"/man/nm-online.1 -a \ -f "$srcdir"/man/nmcli-examples.7 -a \ @@ -28681,7 +28892,7 @@ fi -ac_config_files="$ac_config_files Makefile libnm-core/nm-version-macros.h libnm/libnm.pc po/Makefile.in data/org.freedesktop.NetworkManager.policy.in docs/api/Makefile docs/api/version.xml docs/libnm/Makefile docs/libnm/version.xml NetworkManager.pc" +ac_config_files="$ac_config_files Makefile po/Makefile.in data/org.freedesktop.NetworkManager.policy.in docs/api/Makefile docs/api/version.xml docs/libnm/Makefile docs/libnm/version.xml NetworkManager.pc src/libnm-client-impl/libnm.pc src/libnm-core-public/nm-version-macros.h" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -29389,7 +29600,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by NetworkManager $as_me 1.30.0, which was +This file was extended by NetworkManager $as_me 1.31.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -29455,7 +29666,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -NetworkManager config.status 1.30.0 +NetworkManager config.status 1.31.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -29978,8 +30189,6 @@ do "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; "vapi") CONFIG_COMMANDS="$CONFIG_COMMANDS vapi" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "libnm-core/nm-version-macros.h") CONFIG_FILES="$CONFIG_FILES libnm-core/nm-version-macros.h" ;; - "libnm/libnm.pc") CONFIG_FILES="$CONFIG_FILES libnm/libnm.pc" ;; "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; "data/org.freedesktop.NetworkManager.policy.in") CONFIG_FILES="$CONFIG_FILES data/org.freedesktop.NetworkManager.policy.in" ;; "docs/api/Makefile") CONFIG_FILES="$CONFIG_FILES docs/api/Makefile" ;; @@ -29987,6 +30196,8 @@ do "docs/libnm/Makefile") CONFIG_FILES="$CONFIG_FILES docs/libnm/Makefile" ;; "docs/libnm/version.xml") CONFIG_FILES="$CONFIG_FILES docs/libnm/version.xml" ;; "NetworkManager.pc") CONFIG_FILES="$CONFIG_FILES NetworkManager.pc" ;; + "src/libnm-client-impl/libnm.pc") CONFIG_FILES="$CONFIG_FILES src/libnm-client-impl/libnm.pc" ;; + "src/libnm-core-public/nm-version-macros.h") CONFIG_FILES="$CONFIG_FILES src/libnm-core-public/nm-version-macros.h" ;; "po/stamp-it") CONFIG_COMMANDS="$CONFIG_COMMANDS po/stamp-it" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; diff --git a/configure.ac b/configure.ac index 3e660ff..5126ed2 100644 --- a/configure.ac +++ b/configure.ac @@ -7,8 +7,8 @@ dnl - add corresponding NM_VERSION_x_y_z macros in dnl "shared/nm-version-macros.h.in" dnl - update number in meson.build m4_define([nm_major_version], [1]) -m4_define([nm_minor_version], [30]) -m4_define([nm_micro_version], [0]) +m4_define([nm_minor_version], [31]) +m4_define([nm_micro_version], [2]) m4_define([nm_version], [nm_major_version.nm_minor_version.nm_micro_version]) @@ -1177,7 +1177,7 @@ if test -n "$sanitizers"; then fi AC_MSG_CHECKING([CC support C11 _Generic()]) -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int foo(void); int foo() { int a = 0; int b = _Generic (a, int: 4); return b + a; }]], +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int foo(void); static const char *const buf[1] = { "a" }; int foo() { int a = 0; int b = _Generic (a, int: 4) + _Generic(buf, const char *const*: 5); return b + a; }]], [[foo();]])], [cc_support_generic=1], [cc_support_generic=0]) @@ -1229,9 +1229,13 @@ else fi AC_SUBST(NM_LOG_COMPILER, 'LOG_COMPILER = "$(top_srcdir)/tools/run-nm-test.sh" --called-from-make "$(abs_top_builddir)" "$(LIBTOOL)" "$(with_valgrind)" "'"$with_valgrind_suppressions"'" --launch-dbus=auto') -AM_PATH_PYTHON([3], [], [PYTHON=]) -if test -z "$PYTHON"; then - AM_PATH_PYTHON([], [], [PYTHON=python]) +if test -n "$PYTHON" ; then + AM_PATH_PYTHON([], [], []) +else + AM_PATH_PYTHON([3], [], [PYTHON=]) + if test -z "$PYTHON"; then + AM_PATH_PYTHON([], [], []) + fi fi AC_SUBST(PYTHON, [$PYTHON]) AC_DEFINE_UNQUOTED(TEST_NM_PYTHON, "$PYTHON", [Define python path for test binary]) @@ -1276,6 +1280,7 @@ AM_CONDITIONAL(WITH_PYTHON_BLACK, test "${BLACK}" != "") use_pregen_docs=no if test "$build_docs" != "yes" -a \ -f "$srcdir"/man/NetworkManager.8 -a \ + -f "$srcdir"/man/NetworkManager-dispatcher.8 -a \ -f "$srcdir"/man/NetworkManager.conf.5 -a \ -f "$srcdir"/man/nm-online.1 -a \ -f "$srcdir"/man/nmcli-examples.7 -a \ @@ -1305,8 +1310,6 @@ AC_SUBST(AM_CFLAGS) AC_CONFIG_FILES([ Makefile -libnm-core/nm-version-macros.h -libnm/libnm.pc po/Makefile.in data/org.freedesktop.NetworkManager.policy.in docs/api/Makefile @@ -1314,6 +1317,8 @@ docs/api/version.xml docs/libnm/Makefile docs/libnm/version.xml NetworkManager.pc +src/libnm-client-impl/libnm.pc +src/libnm-core-public/nm-version-macros.h ]) AC_OUTPUT diff --git a/data/NetworkManager.service.in b/data/NetworkManager.service.in index 91ebd9a..e23b3a5 100644 --- a/data/NetworkManager.service.in +++ b/data/NetworkManager.service.in @@ -14,11 +14,17 @@ ExecStart=@sbindir@/NetworkManager --no-daemon Restart=on-failure # NM doesn't want systemd to kill its children for it KillMode=process + +# CAP_DAC_OVERRIDE: required to open /run/openvswitch/db.sock socket. CapabilityBoundingSet=CAP_NET_ADMIN CAP_DAC_OVERRIDE CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_MODULE CAP_AUDIT_WRITE CAP_KILL CAP_SYS_CHROOT ProtectSystem=true ProtectHome=read-only +# We require file descriptors for DHCP etc. When activating many interfaces, +# the default limit of 1024 is easily reached. +LimitNOFILE=65536 + [Install] WantedBy=multi-user.target Also=NetworkManager-dispatcher.service diff --git a/data/org.freedesktop.NetworkManager.policy.in.in b/data/org.freedesktop.NetworkManager.policy.in.in index 8b6ea51..8d46dac 100644 --- a/data/org.freedesktop.NetworkManager.policy.in.in +++ b/data/org.freedesktop.NetworkManager.policy.in.in @@ -6,7 +6,7 @@ NetworkManager - http://www.gnome.org/projects/NetworkManager + https://networkmanager.dev/ nm-icon diff --git a/docs/api/Makefile.am b/docs/api/Makefile.am index 65eed1a..fd98aa2 100644 --- a/docs/api/Makefile.am +++ b/docs/api/Makefile.am @@ -79,13 +79,14 @@ content_files = \ dbus-org.freedesktop.NetworkManager.VPN.Connection.xml \ dbus-org.freedesktop.NetworkManager.VPN.Plugin.xml \ dbus-org.freedesktop.NetworkManager.xml \ - $(top_builddir)/libnm-core/nm-dbus-types.xml \ - $(top_builddir)/libnm-core/nm-vpn-dbus-types.xml \ + $(top_builddir)/src/libnm-core-public/nm-dbus-types.xml \ + $(top_builddir)/src/libnm-core-public/nm-vpn-dbus-types.xml \ $(top_builddir)/man/nmcli.xml \ $(top_builddir)/man/nmtui.xml \ $(top_builddir)/man/nm-online.xml \ $(top_builddir)/man/nm-initrd-generator.xml \ $(top_builddir)/man/NetworkManager.xml \ + $(top_builddir)/man/NetworkManager-dispatcher.xml \ $(top_builddir)/man/NetworkManager.conf.xml \ $(top_builddir)/man/nmcli-examples.xml \ $(top_builddir)/man/nm-settings-dbus.xml \ diff --git a/docs/api/Makefile.in b/docs/api/Makefile.in index 1d29637..e2065fa 100644 --- a/docs/api/Makefile.in +++ b/docs/api/Makefile.in @@ -511,12 +511,13 @@ content_files = $(GENERATED_FILES) \ dbus-org.freedesktop.NetworkManager.VPN.Connection.xml \ dbus-org.freedesktop.NetworkManager.VPN.Plugin.xml \ dbus-org.freedesktop.NetworkManager.xml \ - $(top_builddir)/libnm-core/nm-dbus-types.xml \ - $(top_builddir)/libnm-core/nm-vpn-dbus-types.xml \ + $(top_builddir)/src/libnm-core-public/nm-dbus-types.xml \ + $(top_builddir)/src/libnm-core-public/nm-vpn-dbus-types.xml \ $(top_builddir)/man/nmcli.xml $(top_builddir)/man/nmtui.xml \ $(top_builddir)/man/nm-online.xml \ $(top_builddir)/man/nm-initrd-generator.xml \ $(top_builddir)/man/NetworkManager.xml \ + $(top_builddir)/man/NetworkManager-dispatcher.xml \ $(top_builddir)/man/NetworkManager.conf.xml \ $(top_builddir)/man/nmcli-examples.xml \ $(top_builddir)/man/nm-settings-dbus.xml \ @@ -553,7 +554,6 @@ DOC_STAMPS = setup-build.stamp scan-build.stamp sgml-build.stamp \ sgml.stamp html.stamp pdf.stamp SCANOBJ_FILES = \ - $(DOC_MODULE).actions \ $(DOC_MODULE).args \ $(DOC_MODULE).hierarchy \ $(DOC_MODULE).interfaces \ diff --git a/docs/api/html/NetworkManager-dispatcher.html b/docs/api/html/NetworkManager-dispatcher.html new file mode 100644 index 0000000..c7a56fe --- /dev/null +++ b/docs/api/html/NetworkManager-dispatcher.html @@ -0,0 +1,330 @@ + + + + +NetworkManager-dispatcher: NetworkManager Reference Manual + + + + + + + + + + + + + + + + +
+
+
+ + +
+

NetworkManager-dispatcher

+

NetworkManager-dispatcher — Dispatch user scripts for NetworkManager

+
+
+

Synopsis

+

NetworkManager [OPTIONS...]

+
+
+

Description

+

+ NetworkManager-dispatcher service is a D-Bus activated service that + runs user provided scripts upon certain changes in NetworkManager. +

+

+ NetworkManager-dispatcher will execute scripts in the + /{etc,usr/lib}/NetworkManager/dispatcher.d + directory or subdirectories in + alphabetical order in response to network events. Each script should + be a regular executable file owned by root. Furthermore, it must not be + writable by group or other, and not setuid. +

+

+ Each script receives two arguments, the first being the interface name of the + device an operation just happened on, and second the action. For device actions, + the interface is the name of the kernel interface suitable for IP configuration. + Thus it is either VPN_IP_IFACE, DEVICE_IP_IFACE, or DEVICE_IFACE, as applicable. + For the hostname action the device name is always "none" + and for connectivity-change it is empty. +

+

The actions are:

+
++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

pre-up

The interface is connected to the network but is not + yet fully activated. Scripts acting on this event must be placed or + symlinked into the /etc/NetworkManager/dispatcher.d/pre-up.d + directory, and NetworkManager will wait for script execution to complete before + indicating to applications that the interface is fully activated. +

up

The interface has been activated.

pre-down

The interface will be deactivated but has not yet been + disconnected from the network. Scripts acting on this event must be + placed or symlinked into the /etc/NetworkManager/dispatcher.d/pre-down.d + directory, and NetworkManager will wait for script execution to complete + before disconnecting the interface from its network. Note that this + event is not emitted for forced disconnections, like when carrier is + lost or a wireless signal fades. It is only emitted when there is + an opportunity to cleanly handle a network disconnection event. +

down

+ The interface has been deactivated. +

vpn-pre-up

The VPN is connected to the network but is not yet + fully activated. Scripts acting on this event must be placed or + symlinked into the /etc/NetworkManager/dispatcher.d/pre-up.d + directory, and NetworkManager will wait for script execution to complete before + indicating to applications that the VPN is fully activated. +

vpn-up

+ A VPN connection has been activated. +

vpn-pre-down

The VPN will be deactivated but has not yet been + disconnected from the network. Scripts acting on this event must be + placed or symlinked into the /etc/NetworkManager/dispatcher.d/pre-down.d + directory, and NetworkManager will wait for script execution to complete + before disconnecting the VPN from its network. Note that this + event is not emitted for forced disconnections, like when the VPN + terminates unexpectedly or general connectivity is lost. It is only + emitted when there is an opportunity to cleanly handle a VPN + disconnection event. +

vpn-down

+ A VPN connection has been deactivated. +

hostname

+ The system hostname has been updated. Use gethostname(2) to retrieve it. + The interface name (first argument) is empty and no environment variable is + set for this action. +

dhcp4-change

+ The DHCPv4 lease has changed (renewed, rebound, etc). +

dhcp6-change

+ The DHCPv6 lease has changed (renewed, rebound, etc). +

connectivity-change

+ The network connectivity state has changed (no connectivity, went online, etc). +

+

+ The environment contains more information about the interface and the connection. + The following variables are available for the use in the dispatcher scripts: +

+
++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

NM_DISPATCHER_ACTION

+ The dispatcher action like "up" or "dhcp4-change", identical to the first + command line argument. Since NetworkManager 1.12.0. +

CONNECTION_UUID

+ The UUID of the connection profile. +

CONNECTION_ID

+ The name (ID) of the connection profile. +

CONNECTION_DBUS_PATH

+ The NetworkManager D-Bus path of the connection. +

CONNECTION_FILENAME

+ The backing file name of the connection profile (if any). +

CONNECTION_EXTERNAL

+ If "1", this indicates that the connection describes a + network configuration created outside of NetworkManager. +

DEVICE_IFACE

+ The interface name of the control interface of the device. + Depending on the device type, this differs from + DEVICE_IP_IFACE. For example for + ADSL devices, this could be 'atm0' or for WWAN devices + it might be 'ttyUSB0'. +

DEVICE_IP_IFACE

+ The IP interface name of the device. This is the network + interface on which IP addresses and routes will be configured. +

IP4_ADDRESS_N

+ The IPv4 address in the format "address/prefix gateway", where N is a number + from 0 to (# IPv4 addresses - 1). gateway item in this variable is deprecated, + use IP4_GATEWAY instead. +

IP4_NUM_ADDRESSES

+ The variable contains the number of IPv4 addresses the script may expect. +

IP4_GATEWAY

+ The gateway IPv4 address in traditional numbers-and-dots notation. +

IP4_ROUTE_N

+ The IPv4 route in the format "address/prefix next-hop metric", where N is a number + from 0 to (# IPv4 routes - 1). +

IP4_NUM_ROUTES

+ The variable contains the number of IPv4 routes the script may expect. +

IP4_NAMESERVERS

+ The variable contains a space-separated list of the DNS servers. +

IP4_DOMAINS

+ The variable contains a space-separated list of the search domains. +

DHCP4_<dhcp-option-name>

+ If the connection used DHCP for address configuration, the received DHCP + configuration is passed in the environment using standard DHCP + option names, prefixed with "DHCP4_", like "DHCP4_HOST_NAME=foobar". +

IP6_<name> and DHCP6_<name>

+ The same variables as for IPv4 are available for IPv6, but the prefixes are IP6_ + and DHCP6_ instead. +

CONNECTIVITY_STATE

The network connectivity state, which can + take the values defined by the NMConnectivityState type, + from the org.freedesktop.NetworkManager D-Bus API: unknown, + none, portal, limited or full. Note: this variable will only + be set for connectivity-change actions. +

+

+

+

+ In case of VPN, VPN_IP_IFACE is set, and IP4_*, IP6_* variables with VPN prefix are + exported too, like VPN_IP4_ADDRESS_0, VPN_IP4_NUM_ADDRESSES. +

+

+ Dispatcher scripts are run one at a time, but asynchronously from the main + NetworkManager process, and will be killed if they run for too long. If your script + might take arbitrarily long to complete, you should spawn a child process and have the + parent return immediately. Scripts that are symbolic links pointing inside the + /etc/NetworkManager/dispatcher.d/no-wait.d/ + directory are run immediately, without + waiting for the termination of previous scripts, and in parallel. Also beware that + once a script is queued, it will always be run, even if a later event renders it + obsolete. (Eg, if an interface goes up, and then back down again quickly, it is + possible that one or more "up" scripts will be run after the interface has gone down.) +

+
+
+

Bugs

+

+ Please report any bugs you find in NetworkManager at the + NetworkManager issue tracker. +

+
+ +
+ + + \ No newline at end of file diff --git a/docs/api/html/NetworkManager.conf.html b/docs/api/html/NetworkManager.conf.html index 05250d1..035fd48 100644 --- a/docs/api/html/NetworkManager.conf.html +++ b/docs/api/html/NetworkManager.conf.html @@ -7,8 +7,8 @@ - - + + @@ -17,7 +17,7 @@ Home Up Prev -Next +Next
@@ -456,6 +456,25 @@ no-auto-default=* index).

+ +

iwd-config-path

+ +

+ If the value points to an existing directory, Network + Manager will attempt to write copies of new or modified + Wi-Fi connection profiles, converted into the IWD + format, into this directory thus making IWD connection + properties editable. This will only happen if the IWD + backend is active meaning that at least one Wi-Fi device + must exist. +

+

+ This allows editing connection profile settings such as + the 802.1x configuration using Network Manager clients. + Without it such changes have no effect in IWD. +

+ +
@@ -489,21 +508,30 @@ no-auto-default=*

unmanaged-devices

-

Set devices that should be ignored by - NetworkManager. -

-

See the section called “Device List Format” for the syntax on how to - specify a device. -

+

Set devices that should be ignored by NetworkManager. +

- Example: + A device unmanaged due to this option is strictly + unmanaged and cannot be overruled by using the API like + nmcli device set $IFNAME managed yes. + Also, a device that is unmanaged for other reasons, like + an udev rule, cannot be made managed with this option (e.g. by + using an except: specifier). + These two points make it different from the device*.managed + option which for that reason may be a better choice. +

+

See the section called “Device List Format” for the syntax on how to + specify a device.

+

+ Example: +

 unmanaged-devices=interface-name:em4
 unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth2
 

-

+

@@ -1005,19 +1033,32 @@ managed=1

carrier-wait-timeout

-

+ +

Specify the timeout for waiting for carrier in milliseconds. + The default is 5000 milliseconds. + This setting exists because certain drivers/hardware can take + a long time to detect whether the cable is plugged in. +

+

When the device loses carrier, NetworkManager does not react immediately. Instead, it waits for this timeout before considering - the link lost. Also, on startup, NetworkManager considers the + the link lost. +

+

+ Also, on startup, NetworkManager considers the device as busy for this time, as long as the device has no carrier. This delays startup-complete signal and NetworkManager-wait-online. Configuring this too high means to block NetworkManager-wait-online - longer then necessary. Configuring it too low, means that NetworkManager - will declare startup-complete, although carrier is about to come - and auto-activation to kick in. - The default is 5000 milliseconds. -

+ longer than necessary when booting with cable unplugged. Configuring + it too low, means that NetworkManager will declare startup-complete too + soon, although carrier is about to come and auto-activation to kick in. + Note that if a profile only has static IP configuration or Layer 3 configuration + disabled, then it can already autoconnect without carrier on the device. + Once such a profile reaches full activated state, startup-complete + is considered as reached even if the device has no carrier yet. +

+

ignore-carrier

@@ -1588,6 +1629,6 @@ interface-name:vboxnet*,except:interface-name:vboxnet2 +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/NetworkManager.devhelp2 b/docs/api/html/NetworkManager.devhelp2 index 6c7e5d6..c0496f3 100644 --- a/docs/api/html/NetworkManager.devhelp2 +++ b/docs/api/html/NetworkManager.devhelp2 @@ -4,6 +4,7 @@ + diff --git a/docs/api/html/NetworkManager.html b/docs/api/html/NetworkManager.html index ff497a1..ef26864 100644 --- a/docs/api/html/NetworkManager.html +++ b/docs/api/html/NetworkManager.html @@ -8,7 +8,7 @@ - + @@ -50,274 +50,9 @@

Dispatcher scripts

- NetworkManager will execute scripts in the - /etc/NetworkManager/dispatcher.d - directory or subdirectories in - alphabetical order in response to network events. Each script should - be a regular executable file owned by root. Furthermore, it must not be - writable by group or other, and not setuid. -

-

- Each script receives two arguments, the first being the interface name of the - device an operation just happened on, and second the action. For device actions, - the interface is the name of the kernel interface suitable for IP configuration. - Thus it is either VPN_IP_IFACE, DEVICE_IP_IFACE, or DEVICE_IFACE, as applicable. - For the hostname action the device name is always "none" - and for connectivity-change it is empty. -

-

The actions are:

-
---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

pre-up

The interface is connected to the network but is not - yet fully activated. Scripts acting on this event must be placed or - symlinked into the /etc/NetworkManager/dispatcher.d/pre-up.d - directory, and NetworkManager will wait for script execution to complete before - indicating to applications that the interface is fully activated. -

up

The interface has been activated.

pre-down

The interface will be deactivated but has not yet been - disconnected from the network. Scripts acting on this event must be - placed or symlinked into the /etc/NetworkManager/dispatcher.d/pre-down.d - directory, and NetworkManager will wait for script execution to complete - before disconnecting the interface from its network. Note that this - event is not emitted for forced disconnections, like when carrier is - lost or a wireless signal fades. It is only emitted when there is - an opportunity to cleanly handle a network disconnection event. -

down

- The interface has been deactivated. -

vpn-pre-up

The VPN is connected to the network but is not yet - fully activated. Scripts acting on this event must be placed or - symlinked into the /etc/NetworkManager/dispatcher.d/pre-up.d - directory, and NetworkManager will wait for script execution to complete before - indicating to applications that the VPN is fully activated. -

vpn-up

- A VPN connection has been activated. -

vpn-pre-down

The VPN will be deactivated but has not yet been - disconnected from the network. Scripts acting on this event must be - placed or symlinked into the /etc/NetworkManager/dispatcher.d/pre-down.d - directory, and NetworkManager will wait for script execution to complete - before disconnecting the VPN from its network. Note that this - event is not emitted for forced disconnections, like when the VPN - terminates unexpectedly or general connectivity is lost. It is only - emitted when there is an opportunity to cleanly handle a VPN - disconnection event. -

vpn-down

- A VPN connection has been deactivated. -

hostname

- The system hostname has been updated. Use gethostname(2) to retrieve it. - The interface name (first argument) is empty and no environment variable is - set for this action. -

dhcp4-change

- The DHCPv4 lease has changed (renewed, rebound, etc). -

dhcp6-change

- The DHCPv6 lease has changed (renewed, rebound, etc). -

connectivity-change

- The network connectivity state has changed (no connectivity, went online, etc). -

-

- The environment contains more information about the interface and the connection. - The following variables are available for the use in the dispatcher scripts: -

-
---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

NM_DISPATCHER_ACTION

- The dispatcher action like "up" or "dhcp4-change", identical to the first - command line argument. Since NetworkManager 1.12.0. -

CONNECTION_UUID

- The UUID of the connection profile. -

CONNECTION_ID

- The name (ID) of the connection profile. -

CONNECTION_DBUS_PATH

- The NetworkManager D-Bus path of the connection. -

CONNECTION_FILENAME

- The backing file name of the connection profile (if any). -

CONNECTION_EXTERNAL

- If "1", this indicates that the connection describes a - network configuration created outside of NetworkManager. -

DEVICE_IFACE

- The interface name of the control interface of the device. - Depending on the device type, this differs from - DEVICE_IP_IFACE. For example for - ADSL devices, this could be 'atm0' or for WWAN devices - it might be 'ttyUSB0'. -

DEVICE_IP_IFACE

- The IP interface name of the device. This is the network - interface on which IP addresses and routes will be configured. -

IP4_ADDRESS_N

- The IPv4 address in the format "address/prefix gateway", where N is a number - from 0 to (# IPv4 addresses - 1). gateway item in this variable is deprecated, - use IP4_GATEWAY instead. -

IP4_NUM_ADDRESSES

- The variable contains the number of IPv4 addresses the script may expect. -

IP4_GATEWAY

- The gateway IPv4 address in traditional numbers-and-dots notation. -

IP4_ROUTE_N

- The IPv4 route in the format "address/prefix next-hop metric", where N is a number - from 0 to (# IPv4 routes - 1). -

IP4_NUM_ROUTES

- The variable contains the number of IPv4 routes the script may expect. -

IP4_NAMESERVERS

- The variable contains a space-separated list of the DNS servers. -

IP4_DOMAINS

- The variable contains a space-separated list of the search domains. -

DHCP4_<dhcp-option-name>

- If the connection used DHCP for address configuration, the received DHCP - configuration is passed in the environment using standard DHCP - option names, prefixed with "DHCP4_", like "DHCP4_HOST_NAME=foobar". -

IP6_<name> and DHCP6_<name>

- The same variables as for IPv4 are available for IPv6, but the prefixes are IP6_ - and DHCP6_ instead. -

CONNECTIVITY_STATE

The network connectivity state, which can - take the values defined by the NMConnectivityState type, - from the org.freedesktop.NetworkManager D-Bus API: unknown, - none, portal, limited or full. Note: this variable will only - be set for connectivity-change actions. -

-

-

-

- In case of VPN, VPN_IP_IFACE is set, and IP4_*, IP6_* variables with VPN prefix are - exported too, like VPN_IP4_ADDRESS_0, VPN_IP4_NUM_ADDRESSES. -

-

- Dispatcher scripts are run one at a time, but asynchronously from the main - NetworkManager process, and will be killed if they run for too long. If your script - might take arbitrarily long to complete, you should spawn a child process and have the - parent return immediately. Scripts that are symbolic links pointing inside the - /etc/NetworkManager/dispatcher.d/no-wait.d/ - directory are run immediately, without - waiting for the termination of previous scripts, and in parallel. Also beware that - once a script is queued, it will always be run, even if a later event renders it - obsolete. (Eg, if an interface goes up, and then back down again quickly, it is - possible that one or more "up" scripts will be run after the interface has gone down.) + NetworkManager-dispatcher service can execute scripts for the user + in response to network events. See + NetworkManager-dispatcher(8) manual.

+
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ch01.html b/docs/api/html/ch01.html index 0715709..4cbe2f6 100644 --- a/docs/api/html/ch01.html +++ b/docs/api/html/ch01.html @@ -8,7 +8,7 @@ - + @@ -179,6 +179,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/dbus-secret-agent.html b/docs/api/html/dbus-secret-agent.html index 71d7ea5..b8a0c99 100644 --- a/docs/api/html/dbus-secret-agent.html +++ b/docs/api/html/dbus-secret-agent.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/dbus-types.html b/docs/api/html/dbus-types.html index b5eb97f..cfdccb5 100644 --- a/docs/api/html/dbus-types.html +++ b/docs/api/html/dbus-types.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/dbus-vpn-plugin.html b/docs/api/html/dbus-vpn-plugin.html index 7bec382..1c6124e 100644 --- a/docs/api/html/dbus-vpn-plugin.html +++ b/docs/api/html/dbus-vpn-plugin.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/dbus-vpn-types.html b/docs/api/html/dbus-vpn-types.html index bb2edb3..a6c5d51 100644 --- a/docs/api/html/dbus-vpn-types.html +++ b/docs/api/html/dbus-vpn-types.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.AccessPoint.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.AccessPoint.html index 550a116..4b3f1a1 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.AccessPoint.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.AccessPoint.html @@ -8,7 +8,7 @@ - + @@ -186,6 +186,6 @@ LastSeen readable i +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.AgentManager.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.AgentManager.html index a237c1b..4a2591b 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.AgentManager.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.AgentManager.html @@ -8,7 +8,7 @@ - + @@ -105,6 +105,6 @@ Unregister (); +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Checkpoint.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Checkpoint.html index 8f4f7b2..fd78205 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Checkpoint.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Checkpoint.html @@ -8,7 +8,7 @@ - + @@ -105,6 +105,6 @@ RollbackTimeout readable u +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Connection.Active.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Connection.Active.html index 63e4612..ee122d8 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Connection.Active.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Connection.Active.html @@ -8,7 +8,7 @@ - + @@ -297,6 +297,6 @@ Master readable o +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.DHCP4Config.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.DHCP4Config.html index 96238c2..f33cfc0 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.DHCP4Config.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.DHCP4Config.html @@ -8,7 +8,7 @@ - + @@ -84,6 +84,6 @@ Options readable a{sv} +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.DHCP6Config.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.DHCP6Config.html index f26712a..e0b70ca 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.DHCP6Config.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.DHCP6Config.html @@ -8,7 +8,7 @@ - + @@ -84,6 +84,6 @@ Options readable a{sv} +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Adsl.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Adsl.html index f886c18..623a76b 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Adsl.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Adsl.html @@ -8,7 +8,7 @@ - + @@ -86,6 +86,6 @@ Carrier readable b +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bluetooth.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bluetooth.html index bcd45b4..a138c19 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bluetooth.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bluetooth.html @@ -8,7 +8,7 @@ - + @@ -107,6 +107,6 @@ BtCapabilities readable u +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bond.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bond.html index a7e9cf2..f670573 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bond.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bond.html @@ -8,7 +8,7 @@ - + @@ -110,6 +110,6 @@ Slaves readable ao +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bridge.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bridge.html index b820333..34785c0 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bridge.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Bridge.html @@ -8,7 +8,7 @@ - + @@ -110,6 +110,6 @@ Slaves readable ao +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Dummy.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Dummy.html index a11a705..fa9e6dc 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Dummy.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Dummy.html @@ -8,7 +8,7 @@ - + @@ -85,6 +85,6 @@ n +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Generic.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Generic.html index 477eb58..1894866 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Generic.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Generic.html @@ -8,7 +8,7 @@ - + @@ -95,6 +95,6 @@ TypeDescription readable s +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.IPTunnel.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.IPTunnel.html index 2a00c9e..b0da4a5 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.IPTunnel.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.IPTunnel.html @@ -8,7 +8,7 @@ - + @@ -197,6 +197,6 @@ Flags readable u +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Infiniband.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Infiniband.html index 84668e7..d81e12f 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Infiniband.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Infiniband.html @@ -8,7 +8,7 @@ - + @@ -99,6 +99,6 @@ Carrier readable b +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Lowpan.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Lowpan.html index c6182a6..b45c0fb 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Lowpan.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Lowpan.html @@ -8,7 +8,7 @@ - + @@ -67,6 +67,6 @@ Parent readable o +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Macsec.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Macsec.html index 11ec7cc..c248f9f 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Macsec.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Macsec.html @@ -8,7 +8,7 @@ - + @@ -209,6 +209,6 @@ ReplayProtect readable b +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Macvlan.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Macvlan.html index 62daf00..a227ff1 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Macvlan.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Macvlan.html @@ -8,7 +8,7 @@ - + @@ -113,6 +113,6 @@ Tap readable b +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Modem.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Modem.html index fbe9a32..ae6a3a3 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Modem.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Modem.html @@ -8,7 +8,7 @@ - + @@ -140,6 +140,6 @@ Apn readable s +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OlpcMesh.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OlpcMesh.html index 3f6eef5..ec2a78c 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OlpcMesh.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OlpcMesh.html @@ -8,7 +8,7 @@ - + @@ -105,6 +105,6 @@ ActiveChannel readable u +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsBridge.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsBridge.html index 6bb2c8b..04c5215 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsBridge.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsBridge.html @@ -8,7 +8,7 @@ - + @@ -86,6 +86,6 @@ Slaves readable ao +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsInterface.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsInterface.html index 473cafc..87c76b5 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsInterface.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsInterface.html @@ -8,7 +8,7 @@ - + @@ -65,6 +65,6 @@ PropertiesChanged (a{sv} properties); +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsPort.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsPort.html index 78517f5..4f6d8df 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsPort.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.OvsPort.html @@ -8,7 +8,7 @@ - + @@ -86,6 +86,6 @@ Slaves readable ao +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Ppp.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Ppp.html index a0af822..31e153b 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Ppp.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Ppp.html @@ -8,7 +8,7 @@ - + @@ -65,6 +65,6 @@ PropertiesChanged (a{sv} properties); +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Statistics.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Statistics.html index e5fc091..ea3eca7 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Statistics.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Statistics.html @@ -8,7 +8,7 @@ - + @@ -106,6 +106,6 @@ RxBytes readable t +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Team.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Team.html index 2b52be6..208f5a5 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Team.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Team.html @@ -8,7 +8,7 @@ - + @@ -120,6 +120,6 @@ Config readable s +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Tun.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Tun.html index 39f4c6b..314b17d 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Tun.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Tun.html @@ -8,7 +8,7 @@ - + @@ -148,6 +148,6 @@ n +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Veth.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Veth.html index 6dd7273..3913dae 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Veth.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Veth.html @@ -8,7 +8,7 @@ - + @@ -83,6 +83,6 @@ Peer readable o +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vlan.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vlan.html index 3b5d09f..8220f53 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vlan.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vlan.html @@ -8,7 +8,7 @@ - + @@ -119,6 +119,6 @@ VlanId readable u +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vrf.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vrf.html index 3e9572d..afd573f 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vrf.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vrf.html @@ -8,7 +8,7 @@ - + @@ -55,6 +55,6 @@ Table readable u +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vxlan.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vxlan.html index 587feaf..2a1067b 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vxlan.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Vxlan.html @@ -8,7 +8,7 @@ - + @@ -252,6 +252,6 @@ L3miss readable b +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.WifiP2P.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.WifiP2P.html index 91dd84a..b426b89 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.WifiP2P.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.WifiP2P.html @@ -8,7 +8,7 @@ - + @@ -168,6 +168,6 @@ Peers readable ao +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.WireGuard.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.WireGuard.html index f07fb94..5bb89c9 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.WireGuard.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.WireGuard.html @@ -8,7 +8,7 @@ - + @@ -76,6 +76,6 @@ FwMark readable u +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wired.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wired.html index 6a65cbf..46f84e3 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wired.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wired.html @@ -8,7 +8,7 @@ - + @@ -129,6 +129,6 @@ Carrier readable b +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wireless.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wireless.html index 022e2ae..98d8160 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wireless.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wireless.html @@ -8,7 +8,7 @@ - + @@ -274,6 +274,6 @@ LastScan readable x +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wpan.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wpan.html index f894cc0..0b20a21 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wpan.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.Wpan.html @@ -8,7 +8,7 @@ - + @@ -57,6 +57,6 @@ HwAddress readable s +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.html index 0bb8e85..058b5b5 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.html @@ -8,7 +8,7 @@ - + @@ -605,6 +605,6 @@ HwAddress readable s +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.DnsManager.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.DnsManager.html index f6091bf..fa0bd56 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.DnsManager.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.DnsManager.html @@ -8,7 +8,7 @@ - + @@ -82,6 +82,6 @@ Configuration readable aa{sv} +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.IP4Config.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.IP4Config.html index 4a891b9..c941c60 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.IP4Config.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.IP4Config.html @@ -8,7 +8,7 @@ - + @@ -220,6 +220,6 @@ WinsServerData readable as +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.IP6Config.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.IP6Config.html index 82db2ff..e046dfe 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.IP6Config.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.IP6Config.html @@ -8,7 +8,7 @@ - + @@ -179,6 +179,6 @@ DnsPriority readable i +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.PPP.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.PPP.html index 4670db2..c8b3d2f 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.PPP.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.PPP.html @@ -8,7 +8,7 @@ - + @@ -147,6 +147,6 @@ SetIfindex (IN i ifindex); +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.SecretAgent.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.SecretAgent.html index c8d1d6b..a141eb1 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.SecretAgent.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.SecretAgent.html @@ -8,7 +8,7 @@ - + @@ -197,6 +197,6 @@ DeleteSecrets (IN a{sa{sv}} connection, +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Settings.Connection.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Settings.Connection.html index 478de12..8149cdb 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Settings.Connection.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Settings.Connection.html @@ -8,7 +8,7 @@ - + @@ -355,6 +355,6 @@ Filename readable s +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Settings.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Settings.html index da39bc0..4fa9a5e 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Settings.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Settings.html @@ -8,7 +8,7 @@ - + @@ -423,6 +423,6 @@ CanModify readable b +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.VPN.Connection.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.VPN.Connection.html index b19d4c5..b8945e0 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.VPN.Connection.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.VPN.Connection.html @@ -8,7 +8,7 @@ - + @@ -124,6 +124,6 @@ Banner readable s +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.VPN.Plugin.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.VPN.Plugin.html index b63ea74..1eb6ca2 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.VPN.Plugin.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.VPN.Plugin.html @@ -8,7 +8,7 @@ - + @@ -415,6 +415,6 @@ State readable u +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.WifiP2PPeer.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.WifiP2PPeer.html index 478368a..12ef5c7 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.WifiP2PPeer.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.WifiP2PPeer.html @@ -8,7 +8,7 @@ - + @@ -170,6 +170,6 @@ LastSeen readable i +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.html index a3993d5..8843c3a 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.html @@ -8,7 +8,7 @@ - + @@ -1039,6 +1039,6 @@ GlobalDnsConfiguration readwrite a{sv} +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/index.html b/docs/api/html/index.html index fa7c206..9e4b3b8 100644 --- a/docs/api/html/index.html +++ b/docs/api/html/index.html @@ -7,7 +7,7 @@ - + @@ -16,7 +16,7 @@

- for NetworkManager 1.30.0 + for NetworkManager 1.31.2 The latest version of this documentation can be found on-line at https://developer.gnome.org/NetworkManager/stable/. @@ -76,6 +76,9 @@ NetworkManager.conf — NetworkManager configuration file

+NetworkManager-dispatcher — Dispatch user scripts for NetworkManager +
+
nmcli — command-line tool for controlling NetworkManager
@@ -452,6 +455,6 @@
+
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ix01.html b/docs/api/html/ix01.html index ce92743..287d63f 100644 --- a/docs/api/html/ix01.html +++ b/docs/api/html/ix01.html @@ -8,7 +8,7 @@ - + @@ -26,1694 +26,1694 @@

Symbols

-
org.freedesktop.NetworkManager.AccessPoint, org.freedesktop.NetworkManager.AccessPoint +
org.freedesktop.NetworkManager.AccessPoint, org.freedesktop.NetworkManager.AccessPoint
-
org.freedesktop.NetworkManager.AccessPoint::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.AccessPoint::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.AccessPoint:Flags, The "Flags" property +
org.freedesktop.NetworkManager.AccessPoint:Flags, The "Flags" property
-
org.freedesktop.NetworkManager.AccessPoint:Frequency, The "Frequency" property +
org.freedesktop.NetworkManager.AccessPoint:Frequency, The "Frequency" property
-
org.freedesktop.NetworkManager.AccessPoint:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.AccessPoint:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.AccessPoint:LastSeen, The "LastSeen" property +
org.freedesktop.NetworkManager.AccessPoint:LastSeen, The "LastSeen" property
-
org.freedesktop.NetworkManager.AccessPoint:MaxBitrate, The "MaxBitrate" property +
org.freedesktop.NetworkManager.AccessPoint:MaxBitrate, The "MaxBitrate" property
-
org.freedesktop.NetworkManager.AccessPoint:Mode, The "Mode" property +
org.freedesktop.NetworkManager.AccessPoint:Mode, The "Mode" property
-
org.freedesktop.NetworkManager.AccessPoint:RsnFlags, The "RsnFlags" property +
org.freedesktop.NetworkManager.AccessPoint:RsnFlags, The "RsnFlags" property
-
org.freedesktop.NetworkManager.AccessPoint:Ssid, The "Ssid" property +
org.freedesktop.NetworkManager.AccessPoint:Ssid, The "Ssid" property
-
org.freedesktop.NetworkManager.AccessPoint:Strength, The "Strength" property +
org.freedesktop.NetworkManager.AccessPoint:Strength, The "Strength" property
-
org.freedesktop.NetworkManager.AccessPoint:WpaFlags, The "WpaFlags" property +
org.freedesktop.NetworkManager.AccessPoint:WpaFlags, The "WpaFlags" property
-
org.freedesktop.NetworkManager.AgentManager, org.freedesktop.NetworkManager.AgentManager +
org.freedesktop.NetworkManager.AgentManager, org.freedesktop.NetworkManager.AgentManager
-
org.freedesktop.NetworkManager.AgentManager.Register(), The Register() method +
org.freedesktop.NetworkManager.AgentManager.Register(), The Register() method
-
org.freedesktop.NetworkManager.AgentManager.RegisterWithCapabilities(), The RegisterWithCapabilities() method +
org.freedesktop.NetworkManager.AgentManager.RegisterWithCapabilities(), The RegisterWithCapabilities() method
-
org.freedesktop.NetworkManager.AgentManager.Unregister(), The Unregister() method +
org.freedesktop.NetworkManager.AgentManager.Unregister(), The Unregister() method
-
org.freedesktop.NetworkManager.Device, org.freedesktop.NetworkManager.Device +
org.freedesktop.NetworkManager.Device, org.freedesktop.NetworkManager.Device
-
org.freedesktop.NetworkManager.Device.Adsl, org.freedesktop.NetworkManager.Device.Adsl +
org.freedesktop.NetworkManager.Device.Adsl, org.freedesktop.NetworkManager.Device.Adsl
-
org.freedesktop.NetworkManager.Device.Adsl::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Adsl::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Adsl:Carrier, The "Carrier" property +
org.freedesktop.NetworkManager.Device.Adsl:Carrier, The "Carrier" property
-
org.freedesktop.NetworkManager.Device.Bluetooth, org.freedesktop.NetworkManager.Device.Bluetooth +
org.freedesktop.NetworkManager.Device.Bluetooth, org.freedesktop.NetworkManager.Device.Bluetooth
-
org.freedesktop.NetworkManager.Device.Bluetooth::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Bluetooth::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Bluetooth:BtCapabilities, The "BtCapabilities" property +
org.freedesktop.NetworkManager.Device.Bluetooth:BtCapabilities, The "BtCapabilities" property
-
org.freedesktop.NetworkManager.Device.Bluetooth:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Bluetooth:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Bluetooth:Name, The "Name" property +
org.freedesktop.NetworkManager.Device.Bluetooth:Name, The "Name" property
-
org.freedesktop.NetworkManager.Device.Bond, org.freedesktop.NetworkManager.Device.Bond +
org.freedesktop.NetworkManager.Device.Bond, org.freedesktop.NetworkManager.Device.Bond
-
org.freedesktop.NetworkManager.Device.Bond::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Bond::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Bond:Carrier, The "Carrier" property +
org.freedesktop.NetworkManager.Device.Bond:Carrier, The "Carrier" property
-
org.freedesktop.NetworkManager.Device.Bond:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Bond:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Bond:Slaves, The "Slaves" property +
org.freedesktop.NetworkManager.Device.Bond:Slaves, The "Slaves" property
-
org.freedesktop.NetworkManager.Device.Bridge, org.freedesktop.NetworkManager.Device.Bridge +
org.freedesktop.NetworkManager.Device.Bridge, org.freedesktop.NetworkManager.Device.Bridge
-
org.freedesktop.NetworkManager.Device.Bridge::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Bridge::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Bridge:Carrier, The "Carrier" property +
org.freedesktop.NetworkManager.Device.Bridge:Carrier, The "Carrier" property
-
org.freedesktop.NetworkManager.Device.Bridge:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Bridge:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Bridge:Slaves, The "Slaves" property +
org.freedesktop.NetworkManager.Device.Bridge:Slaves, The "Slaves" property
-
org.freedesktop.NetworkManager.Device.Delete(), The Delete() method +
org.freedesktop.NetworkManager.Device.Delete(), The Delete() method
-
org.freedesktop.NetworkManager.Device.Disconnect(), The Disconnect() method +
org.freedesktop.NetworkManager.Device.Disconnect(), The Disconnect() method
-
org.freedesktop.NetworkManager.Device.Dummy, org.freedesktop.NetworkManager.Device.Dummy +
org.freedesktop.NetworkManager.Device.Dummy, org.freedesktop.NetworkManager.Device.Dummy
-
org.freedesktop.NetworkManager.Device.Dummy::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Dummy::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Dummy:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Dummy:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Generic, org.freedesktop.NetworkManager.Device.Generic +
org.freedesktop.NetworkManager.Device.Generic, org.freedesktop.NetworkManager.Device.Generic
-
org.freedesktop.NetworkManager.Device.Generic::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Generic::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Generic:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Generic:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Generic:TypeDescription, The "TypeDescription" property +
org.freedesktop.NetworkManager.Device.Generic:TypeDescription, The "TypeDescription" property
-
org.freedesktop.NetworkManager.Device.GetAppliedConnection(), The GetAppliedConnection() method +
org.freedesktop.NetworkManager.Device.GetAppliedConnection(), The GetAppliedConnection() method
-
org.freedesktop.NetworkManager.Device.Infiniband, org.freedesktop.NetworkManager.Device.Infiniband +
org.freedesktop.NetworkManager.Device.Infiniband, org.freedesktop.NetworkManager.Device.Infiniband
-
org.freedesktop.NetworkManager.Device.Infiniband::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Infiniband::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Infiniband:Carrier, The "Carrier" property +
org.freedesktop.NetworkManager.Device.Infiniband:Carrier, The "Carrier" property
-
org.freedesktop.NetworkManager.Device.Infiniband:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Infiniband:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.IPTunnel, org.freedesktop.NetworkManager.Device.IPTunnel +
org.freedesktop.NetworkManager.Device.IPTunnel, org.freedesktop.NetworkManager.Device.IPTunnel
-
org.freedesktop.NetworkManager.Device.IPTunnel::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.IPTunnel::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.IPTunnel:EncapsulationLimit, The "EncapsulationLimit" property +
org.freedesktop.NetworkManager.Device.IPTunnel:EncapsulationLimit, The "EncapsulationLimit" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:Flags, The "Flags" property +
org.freedesktop.NetworkManager.Device.IPTunnel:Flags, The "Flags" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:FlowLabel, The "FlowLabel" property +
org.freedesktop.NetworkManager.Device.IPTunnel:FlowLabel, The "FlowLabel" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:InputKey, The "InputKey" property +
org.freedesktop.NetworkManager.Device.IPTunnel:InputKey, The "InputKey" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:Local, The "Local" property +
org.freedesktop.NetworkManager.Device.IPTunnel:Local, The "Local" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:Mode, The "Mode" property +
org.freedesktop.NetworkManager.Device.IPTunnel:Mode, The "Mode" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:OutputKey, The "OutputKey" property +
org.freedesktop.NetworkManager.Device.IPTunnel:OutputKey, The "OutputKey" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:Parent, The "Parent" property +
org.freedesktop.NetworkManager.Device.IPTunnel:Parent, The "Parent" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:PathMtuDiscovery, The "PathMtuDiscovery" property +
org.freedesktop.NetworkManager.Device.IPTunnel:PathMtuDiscovery, The "PathMtuDiscovery" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:Remote, The "Remote" property +
org.freedesktop.NetworkManager.Device.IPTunnel:Remote, The "Remote" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:Tos, The "Tos" property +
org.freedesktop.NetworkManager.Device.IPTunnel:Tos, The "Tos" property
-
org.freedesktop.NetworkManager.Device.IPTunnel:Ttl, The "Ttl" property +
org.freedesktop.NetworkManager.Device.IPTunnel:Ttl, The "Ttl" property
-
org.freedesktop.NetworkManager.Device.Lowpan, org.freedesktop.NetworkManager.Device.Lowpan +
org.freedesktop.NetworkManager.Device.Lowpan, org.freedesktop.NetworkManager.Device.Lowpan
-
org.freedesktop.NetworkManager.Device.Lowpan:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Lowpan:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Lowpan:Parent, The "Parent" property +
org.freedesktop.NetworkManager.Device.Lowpan:Parent, The "Parent" property
-
org.freedesktop.NetworkManager.Device.Macsec, org.freedesktop.NetworkManager.Device.Macsec +
org.freedesktop.NetworkManager.Device.Macsec, org.freedesktop.NetworkManager.Device.Macsec
-
org.freedesktop.NetworkManager.Device.Macsec::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Macsec::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Macsec:CipherSuite, The "CipherSuite" property +
org.freedesktop.NetworkManager.Device.Macsec:CipherSuite, The "CipherSuite" property
-
org.freedesktop.NetworkManager.Device.Macsec:EncodingSa, The "EncodingSa" property +
org.freedesktop.NetworkManager.Device.Macsec:EncodingSa, The "EncodingSa" property
-
org.freedesktop.NetworkManager.Device.Macsec:Encrypt, The "Encrypt" property +
org.freedesktop.NetworkManager.Device.Macsec:Encrypt, The "Encrypt" property
-
org.freedesktop.NetworkManager.Device.Macsec:Es, The "Es" property +
org.freedesktop.NetworkManager.Device.Macsec:Es, The "Es" property
-
org.freedesktop.NetworkManager.Device.Macsec:IcvLength, The "IcvLength" property +
org.freedesktop.NetworkManager.Device.Macsec:IcvLength, The "IcvLength" property
-
org.freedesktop.NetworkManager.Device.Macsec:IncludeSci, The "IncludeSci" property +
org.freedesktop.NetworkManager.Device.Macsec:IncludeSci, The "IncludeSci" property
-
org.freedesktop.NetworkManager.Device.Macsec:Parent, The "Parent" property +
org.freedesktop.NetworkManager.Device.Macsec:Parent, The "Parent" property
-
org.freedesktop.NetworkManager.Device.Macsec:Protect, The "Protect" property +
org.freedesktop.NetworkManager.Device.Macsec:Protect, The "Protect" property
-
org.freedesktop.NetworkManager.Device.Macsec:ReplayProtect, The "ReplayProtect" property +
org.freedesktop.NetworkManager.Device.Macsec:ReplayProtect, The "ReplayProtect" property
-
org.freedesktop.NetworkManager.Device.Macsec:Scb, The "Scb" property +
org.freedesktop.NetworkManager.Device.Macsec:Scb, The "Scb" property
-
org.freedesktop.NetworkManager.Device.Macsec:Sci, The "Sci" property +
org.freedesktop.NetworkManager.Device.Macsec:Sci, The "Sci" property
-
org.freedesktop.NetworkManager.Device.Macsec:Validation, The "Validation" property +
org.freedesktop.NetworkManager.Device.Macsec:Validation, The "Validation" property
-
org.freedesktop.NetworkManager.Device.Macsec:Window, The "Window" property +
org.freedesktop.NetworkManager.Device.Macsec:Window, The "Window" property
-
org.freedesktop.NetworkManager.Device.Macvlan, org.freedesktop.NetworkManager.Device.Macvlan +
org.freedesktop.NetworkManager.Device.Macvlan, org.freedesktop.NetworkManager.Device.Macvlan
-
org.freedesktop.NetworkManager.Device.Macvlan::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Macvlan::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Macvlan:Mode, The "Mode" property +
org.freedesktop.NetworkManager.Device.Macvlan:Mode, The "Mode" property
-
org.freedesktop.NetworkManager.Device.Macvlan:NoPromisc, The "NoPromisc" property +
org.freedesktop.NetworkManager.Device.Macvlan:NoPromisc, The "NoPromisc" property
-
org.freedesktop.NetworkManager.Device.Macvlan:Parent, The "Parent" property +
org.freedesktop.NetworkManager.Device.Macvlan:Parent, The "Parent" property
-
org.freedesktop.NetworkManager.Device.Macvlan:Tap, The "Tap" property +
org.freedesktop.NetworkManager.Device.Macvlan:Tap, The "Tap" property
-
org.freedesktop.NetworkManager.Device.Modem, org.freedesktop.NetworkManager.Device.Modem +
org.freedesktop.NetworkManager.Device.Modem, org.freedesktop.NetworkManager.Device.Modem
-
org.freedesktop.NetworkManager.Device.Modem::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Modem::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Modem:Apn, The "Apn" property +
org.freedesktop.NetworkManager.Device.Modem:Apn, The "Apn" property
-
org.freedesktop.NetworkManager.Device.Modem:CurrentCapabilities, The "CurrentCapabilities" property +
org.freedesktop.NetworkManager.Device.Modem:CurrentCapabilities, The "CurrentCapabilities" property
-
org.freedesktop.NetworkManager.Device.Modem:DeviceId, The "DeviceId" property +
org.freedesktop.NetworkManager.Device.Modem:DeviceId, The "DeviceId" property
-
org.freedesktop.NetworkManager.Device.Modem:ModemCapabilities, The "ModemCapabilities" property +
org.freedesktop.NetworkManager.Device.Modem:ModemCapabilities, The "ModemCapabilities" property
-
org.freedesktop.NetworkManager.Device.Modem:OperatorCode, The "OperatorCode" property +
org.freedesktop.NetworkManager.Device.Modem:OperatorCode, The "OperatorCode" property
-
org.freedesktop.NetworkManager.Device.OlpcMesh, org.freedesktop.NetworkManager.Device.OlpcMesh +
org.freedesktop.NetworkManager.Device.OlpcMesh, org.freedesktop.NetworkManager.Device.OlpcMesh
-
org.freedesktop.NetworkManager.Device.OlpcMesh::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.OlpcMesh::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.OlpcMesh:ActiveChannel, The "ActiveChannel" property +
org.freedesktop.NetworkManager.Device.OlpcMesh:ActiveChannel, The "ActiveChannel" property
-
org.freedesktop.NetworkManager.Device.OlpcMesh:Companion, The "Companion" property +
org.freedesktop.NetworkManager.Device.OlpcMesh:Companion, The "Companion" property
-
org.freedesktop.NetworkManager.Device.OlpcMesh:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.OlpcMesh:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.OvsBridge, org.freedesktop.NetworkManager.Device.OvsBridge +
org.freedesktop.NetworkManager.Device.OvsBridge, org.freedesktop.NetworkManager.Device.OvsBridge
-
org.freedesktop.NetworkManager.Device.OvsBridge::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.OvsBridge::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.OvsBridge:Slaves, The "Slaves" property +
org.freedesktop.NetworkManager.Device.OvsBridge:Slaves, The "Slaves" property
-
org.freedesktop.NetworkManager.Device.OvsInterface, org.freedesktop.NetworkManager.Device.OvsInterface +
org.freedesktop.NetworkManager.Device.OvsInterface, org.freedesktop.NetworkManager.Device.OvsInterface
-
org.freedesktop.NetworkManager.Device.OvsInterface::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.OvsInterface::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.OvsPort, org.freedesktop.NetworkManager.Device.OvsPort +
org.freedesktop.NetworkManager.Device.OvsPort, org.freedesktop.NetworkManager.Device.OvsPort
-
org.freedesktop.NetworkManager.Device.OvsPort::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.OvsPort::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.OvsPort:Slaves, The "Slaves" property +
org.freedesktop.NetworkManager.Device.OvsPort:Slaves, The "Slaves" property
-
org.freedesktop.NetworkManager.Device.Ppp, org.freedesktop.NetworkManager.Device.Ppp +
org.freedesktop.NetworkManager.Device.Ppp, org.freedesktop.NetworkManager.Device.Ppp
-
org.freedesktop.NetworkManager.Device.Ppp::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Ppp::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Reapply(), The Reapply() method +
org.freedesktop.NetworkManager.Device.Reapply(), The Reapply() method
-
org.freedesktop.NetworkManager.Device.Statistics, org.freedesktop.NetworkManager.Device.Statistics +
org.freedesktop.NetworkManager.Device.Statistics, org.freedesktop.NetworkManager.Device.Statistics
-
org.freedesktop.NetworkManager.Device.Statistics::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Statistics::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Statistics:RefreshRateMs, The "RefreshRateMs" property +
org.freedesktop.NetworkManager.Device.Statistics:RefreshRateMs, The "RefreshRateMs" property
-
org.freedesktop.NetworkManager.Device.Statistics:RxBytes, The "RxBytes" property +
org.freedesktop.NetworkManager.Device.Statistics:RxBytes, The "RxBytes" property
-
org.freedesktop.NetworkManager.Device.Statistics:TxBytes, The "TxBytes" property +
org.freedesktop.NetworkManager.Device.Statistics:TxBytes, The "TxBytes" property
-
org.freedesktop.NetworkManager.Device.Team, org.freedesktop.NetworkManager.Device.Team +
org.freedesktop.NetworkManager.Device.Team, org.freedesktop.NetworkManager.Device.Team
-
org.freedesktop.NetworkManager.Device.Team::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Team::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Team:Carrier, The "Carrier" property +
org.freedesktop.NetworkManager.Device.Team:Carrier, The "Carrier" property
-
org.freedesktop.NetworkManager.Device.Team:Config, The "Config" property +
org.freedesktop.NetworkManager.Device.Team:Config, The "Config" property
-
org.freedesktop.NetworkManager.Device.Team:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Team:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Team:Slaves, The "Slaves" property +
org.freedesktop.NetworkManager.Device.Team:Slaves, The "Slaves" property
-
org.freedesktop.NetworkManager.Device.Tun, org.freedesktop.NetworkManager.Device.Tun +
org.freedesktop.NetworkManager.Device.Tun, org.freedesktop.NetworkManager.Device.Tun
-
org.freedesktop.NetworkManager.Device.Tun::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Tun::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Tun:Group, The "Group" property +
org.freedesktop.NetworkManager.Device.Tun:Group, The "Group" property
-
org.freedesktop.NetworkManager.Device.Tun:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Tun:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Tun:Mode, The "Mode" property +
org.freedesktop.NetworkManager.Device.Tun:Mode, The "Mode" property
-
org.freedesktop.NetworkManager.Device.Tun:MultiQueue, The "MultiQueue" property +
org.freedesktop.NetworkManager.Device.Tun:MultiQueue, The "MultiQueue" property
-
org.freedesktop.NetworkManager.Device.Tun:NoPi, The "NoPi" property +
org.freedesktop.NetworkManager.Device.Tun:NoPi, The "NoPi" property
-
org.freedesktop.NetworkManager.Device.Tun:Owner, The "Owner" property +
org.freedesktop.NetworkManager.Device.Tun:Owner, The "Owner" property
-
org.freedesktop.NetworkManager.Device.Tun:VnetHdr, The "VnetHdr" property +
org.freedesktop.NetworkManager.Device.Tun:VnetHdr, The "VnetHdr" property
-
org.freedesktop.NetworkManager.Device.Veth, org.freedesktop.NetworkManager.Device.Veth +
org.freedesktop.NetworkManager.Device.Veth, org.freedesktop.NetworkManager.Device.Veth
-
org.freedesktop.NetworkManager.Device.Veth::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Veth::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Veth:Peer, The "Peer" property +
org.freedesktop.NetworkManager.Device.Veth:Peer, The "Peer" property
-
org.freedesktop.NetworkManager.Device.Vlan, org.freedesktop.NetworkManager.Device.Vlan +
org.freedesktop.NetworkManager.Device.Vlan, org.freedesktop.NetworkManager.Device.Vlan
-
org.freedesktop.NetworkManager.Device.Vlan::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Vlan::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Vlan:Carrier, The "Carrier" property +
org.freedesktop.NetworkManager.Device.Vlan:Carrier, The "Carrier" property
-
org.freedesktop.NetworkManager.Device.Vlan:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Vlan:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Vlan:Parent, The "Parent" property +
org.freedesktop.NetworkManager.Device.Vlan:Parent, The "Parent" property
-
org.freedesktop.NetworkManager.Device.Vlan:VlanId, The "VlanId" property +
org.freedesktop.NetworkManager.Device.Vlan:VlanId, The "VlanId" property
-
org.freedesktop.NetworkManager.Device.Vrf, org.freedesktop.NetworkManager.Device.Vrf +
org.freedesktop.NetworkManager.Device.Vrf, org.freedesktop.NetworkManager.Device.Vrf
-
org.freedesktop.NetworkManager.Device.Vrf:Table, The "Table" property +
org.freedesktop.NetworkManager.Device.Vrf:Table, The "Table" property
-
org.freedesktop.NetworkManager.Device.Vxlan, org.freedesktop.NetworkManager.Device.Vxlan +
org.freedesktop.NetworkManager.Device.Vxlan, org.freedesktop.NetworkManager.Device.Vxlan
-
org.freedesktop.NetworkManager.Device.Vxlan::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Vxlan::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Vxlan:Ageing, The "Ageing" property +
org.freedesktop.NetworkManager.Device.Vxlan:Ageing, The "Ageing" property
-
org.freedesktop.NetworkManager.Device.Vxlan:DstPort, The "DstPort" property +
org.freedesktop.NetworkManager.Device.Vxlan:DstPort, The "DstPort" property
-
org.freedesktop.NetworkManager.Device.Vxlan:Group, The "Group" property +
org.freedesktop.NetworkManager.Device.Vxlan:Group, The "Group" property
-
org.freedesktop.NetworkManager.Device.Vxlan:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Vxlan:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Vxlan:Id, The "Id" property +
org.freedesktop.NetworkManager.Device.Vxlan:Id, The "Id" property
-
org.freedesktop.NetworkManager.Device.Vxlan:L2miss, The "L2miss" property +
org.freedesktop.NetworkManager.Device.Vxlan:L2miss, The "L2miss" property
-
org.freedesktop.NetworkManager.Device.Vxlan:L3miss, The "L3miss" property +
org.freedesktop.NetworkManager.Device.Vxlan:L3miss, The "L3miss" property
-
org.freedesktop.NetworkManager.Device.Vxlan:Learning, The "Learning" property +
org.freedesktop.NetworkManager.Device.Vxlan:Learning, The "Learning" property
-
org.freedesktop.NetworkManager.Device.Vxlan:Limit, The "Limit" property +
org.freedesktop.NetworkManager.Device.Vxlan:Limit, The "Limit" property
-
org.freedesktop.NetworkManager.Device.Vxlan:Local, The "Local" property +
org.freedesktop.NetworkManager.Device.Vxlan:Local, The "Local" property
-
org.freedesktop.NetworkManager.Device.Vxlan:Parent, The "Parent" property +
org.freedesktop.NetworkManager.Device.Vxlan:Parent, The "Parent" property
-
org.freedesktop.NetworkManager.Device.Vxlan:Proxy, The "Proxy" property +
org.freedesktop.NetworkManager.Device.Vxlan:Proxy, The "Proxy" property
-
org.freedesktop.NetworkManager.Device.Vxlan:Rsc, The "Rsc" property +
org.freedesktop.NetworkManager.Device.Vxlan:Rsc, The "Rsc" property
-
org.freedesktop.NetworkManager.Device.Vxlan:SrcPortMax, The "SrcPortMax" property +
org.freedesktop.NetworkManager.Device.Vxlan:SrcPortMax, The "SrcPortMax" property
-
org.freedesktop.NetworkManager.Device.Vxlan:SrcPortMin, The "SrcPortMin" property +
org.freedesktop.NetworkManager.Device.Vxlan:SrcPortMin, The "SrcPortMin" property
-
org.freedesktop.NetworkManager.Device.Vxlan:Tos, The "Tos" property +
org.freedesktop.NetworkManager.Device.Vxlan:Tos, The "Tos" property
-
org.freedesktop.NetworkManager.Device.Vxlan:Ttl, The "Ttl" property +
org.freedesktop.NetworkManager.Device.Vxlan:Ttl, The "Ttl" property
-
org.freedesktop.NetworkManager.Device.WireGuard, org.freedesktop.NetworkManager.Device.WireGuard +
org.freedesktop.NetworkManager.Device.WireGuard, org.freedesktop.NetworkManager.Device.WireGuard
-
org.freedesktop.NetworkManager.Device.WireGuard:FwMark, The "FwMark" property +
org.freedesktop.NetworkManager.Device.WireGuard:FwMark, The "FwMark" property
-
org.freedesktop.NetworkManager.Device.WireGuard:ListenPort, The "ListenPort" property +
org.freedesktop.NetworkManager.Device.WireGuard:ListenPort, The "ListenPort" property
-
org.freedesktop.NetworkManager.Device.WireGuard:PublicKey, The "PublicKey" property +
org.freedesktop.NetworkManager.Device.WireGuard:PublicKey, The "PublicKey" property
-
org.freedesktop.NetworkManager.Device.Wpan, org.freedesktop.NetworkManager.Device.Wpan +
org.freedesktop.NetworkManager.Device.Wpan, org.freedesktop.NetworkManager.Device.Wpan
-
org.freedesktop.NetworkManager.Device.Wpan:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Wpan:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device::StateChanged, The "StateChanged" signal +
org.freedesktop.NetworkManager.Device::StateChanged, The "StateChanged" signal
-
org.freedesktop.NetworkManager.Device:ActiveConnection, The "ActiveConnection" property +
org.freedesktop.NetworkManager.Device:ActiveConnection, The "ActiveConnection" property
-
org.freedesktop.NetworkManager.Device:Autoconnect, The "Autoconnect" property +
org.freedesktop.NetworkManager.Device:Autoconnect, The "Autoconnect" property
-
org.freedesktop.NetworkManager.Device:AvailableConnections, The "AvailableConnections" property +
org.freedesktop.NetworkManager.Device:AvailableConnections, The "AvailableConnections" property
-
org.freedesktop.NetworkManager.Device:Capabilities, The "Capabilities" property +
org.freedesktop.NetworkManager.Device:Capabilities, The "Capabilities" property
-
org.freedesktop.NetworkManager.Device:DeviceType, The "DeviceType" property +
org.freedesktop.NetworkManager.Device:DeviceType, The "DeviceType" property
-
org.freedesktop.NetworkManager.Device:Dhcp4Config, The "Dhcp4Config" property +
org.freedesktop.NetworkManager.Device:Dhcp4Config, The "Dhcp4Config" property
-
org.freedesktop.NetworkManager.Device:Dhcp6Config, The "Dhcp6Config" property +
org.freedesktop.NetworkManager.Device:Dhcp6Config, The "Dhcp6Config" property
-
org.freedesktop.NetworkManager.Device:Driver, The "Driver" property +
org.freedesktop.NetworkManager.Device:Driver, The "Driver" property
-
org.freedesktop.NetworkManager.Device:DriverVersion, The "DriverVersion" property +
org.freedesktop.NetworkManager.Device:DriverVersion, The "DriverVersion" property
-
org.freedesktop.NetworkManager.Device:FirmwareMissing, The "FirmwareMissing" property +
org.freedesktop.NetworkManager.Device:FirmwareMissing, The "FirmwareMissing" property
-
org.freedesktop.NetworkManager.Device:FirmwareVersion, The "FirmwareVersion" property +
org.freedesktop.NetworkManager.Device:FirmwareVersion, The "FirmwareVersion" property
-
org.freedesktop.NetworkManager.Device:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device:Interface, The "Interface" property +
org.freedesktop.NetworkManager.Device:Interface, The "Interface" property
-
org.freedesktop.NetworkManager.Device:InterfaceFlags, The "InterfaceFlags" property +
org.freedesktop.NetworkManager.Device:InterfaceFlags, The "InterfaceFlags" property
-
org.freedesktop.NetworkManager.Device:Ip4Address, The "Ip4Address" property +
org.freedesktop.NetworkManager.Device:Ip4Address, The "Ip4Address" property
-
org.freedesktop.NetworkManager.Device:Ip4Config, The "Ip4Config" property +
org.freedesktop.NetworkManager.Device:Ip4Config, The "Ip4Config" property
-
org.freedesktop.NetworkManager.Device:Ip4Connectivity, The "Ip4Connectivity" property +
org.freedesktop.NetworkManager.Device:Ip4Connectivity, The "Ip4Connectivity" property
-
org.freedesktop.NetworkManager.Device:Ip6Config, The "Ip6Config" property +
org.freedesktop.NetworkManager.Device:Ip6Config, The "Ip6Config" property
-
org.freedesktop.NetworkManager.Device:Ip6Connectivity, The "Ip6Connectivity" property +
org.freedesktop.NetworkManager.Device:Ip6Connectivity, The "Ip6Connectivity" property
-
org.freedesktop.NetworkManager.Device:IpInterface, The "IpInterface" property +
org.freedesktop.NetworkManager.Device:IpInterface, The "IpInterface" property
-
org.freedesktop.NetworkManager.Device:LldpNeighbors, The "LldpNeighbors" property +
org.freedesktop.NetworkManager.Device:LldpNeighbors, The "LldpNeighbors" property
-
org.freedesktop.NetworkManager.Device:Managed, The "Managed" property +
org.freedesktop.NetworkManager.Device:Managed, The "Managed" property
-
org.freedesktop.NetworkManager.Device:Metered, The "Metered" property +
org.freedesktop.NetworkManager.Device:Metered, The "Metered" property
-
org.freedesktop.NetworkManager.Device:Mtu, The "Mtu" property +
org.freedesktop.NetworkManager.Device:Mtu, The "Mtu" property
-
org.freedesktop.NetworkManager.Device:NmPluginMissing, The "NmPluginMissing" property +
org.freedesktop.NetworkManager.Device:NmPluginMissing, The "NmPluginMissing" property
-
org.freedesktop.NetworkManager.Device:Path, The "Path" property +
org.freedesktop.NetworkManager.Device:Path, The "Path" property
-
org.freedesktop.NetworkManager.Device:PhysicalPortId, The "PhysicalPortId" property +
org.freedesktop.NetworkManager.Device:PhysicalPortId, The "PhysicalPortId" property
-
org.freedesktop.NetworkManager.Device:Real, The "Real" property +
org.freedesktop.NetworkManager.Device:Real, The "Real" property
-
org.freedesktop.NetworkManager.Device:State, The "State" property +
org.freedesktop.NetworkManager.Device:State, The "State" property
-
org.freedesktop.NetworkManager.Device:StateReason, The "StateReason" property +
org.freedesktop.NetworkManager.Device:StateReason, The "StateReason" property
-
org.freedesktop.NetworkManager.Device:Udi, The "Udi" property +
org.freedesktop.NetworkManager.Device:Udi, The "Udi" property
-
org.freedesktop.NetworkManager.DnsManager, org.freedesktop.NetworkManager.DnsManager +
org.freedesktop.NetworkManager.DnsManager, org.freedesktop.NetworkManager.DnsManager
-
org.freedesktop.NetworkManager.DnsManager:Configuration, The "Configuration" property +
org.freedesktop.NetworkManager.DnsManager:Configuration, The "Configuration" property
-
org.freedesktop.NetworkManager.DnsManager:Mode, The "Mode" property +
org.freedesktop.NetworkManager.DnsManager:Mode, The "Mode" property
-
org.freedesktop.NetworkManager.DnsManager:RcManager, The "RcManager" property +
org.freedesktop.NetworkManager.DnsManager:RcManager, The "RcManager" property
-
org.freedesktop.NetworkManager.IP4Config, org.freedesktop.NetworkManager.IP4Config +
org.freedesktop.NetworkManager.IP4Config, org.freedesktop.NetworkManager.IP4Config
-
org.freedesktop.NetworkManager.IP4Config::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.IP4Config::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.IP4Config:AddressData, The "AddressData" property +
org.freedesktop.NetworkManager.IP4Config:AddressData, The "AddressData" property
-
org.freedesktop.NetworkManager.IP4Config:Addresses, The "Addresses" property +
org.freedesktop.NetworkManager.IP4Config:Addresses, The "Addresses" property
-
org.freedesktop.NetworkManager.IP4Config:DnsOptions, The "DnsOptions" property +
org.freedesktop.NetworkManager.IP4Config:DnsOptions, The "DnsOptions" property
-
org.freedesktop.NetworkManager.IP4Config:DnsPriority, The "DnsPriority" property +
org.freedesktop.NetworkManager.IP4Config:DnsPriority, The "DnsPriority" property
-
org.freedesktop.NetworkManager.IP4Config:Domains, The "Domains" property +
org.freedesktop.NetworkManager.IP4Config:Domains, The "Domains" property
-
org.freedesktop.NetworkManager.IP4Config:Gateway, The "Gateway" property +
org.freedesktop.NetworkManager.IP4Config:Gateway, The "Gateway" property
-
org.freedesktop.NetworkManager.IP4Config:NameserverData, The "NameserverData" property +
org.freedesktop.NetworkManager.IP4Config:NameserverData, The "NameserverData" property
-
org.freedesktop.NetworkManager.IP4Config:Nameservers, The "Nameservers" property +
org.freedesktop.NetworkManager.IP4Config:Nameservers, The "Nameservers" property
-
org.freedesktop.NetworkManager.IP4Config:RouteData, The "RouteData" property +
org.freedesktop.NetworkManager.IP4Config:RouteData, The "RouteData" property
-
org.freedesktop.NetworkManager.IP4Config:Routes, The "Routes" property +
org.freedesktop.NetworkManager.IP4Config:Routes, The "Routes" property
-
org.freedesktop.NetworkManager.IP4Config:Searches, The "Searches" property +
org.freedesktop.NetworkManager.IP4Config:Searches, The "Searches" property
-
org.freedesktop.NetworkManager.IP4Config:WinsServerData, The "WinsServerData" property +
org.freedesktop.NetworkManager.IP4Config:WinsServerData, The "WinsServerData" property
-
org.freedesktop.NetworkManager.IP4Config:WinsServers, The "WinsServers" property +
org.freedesktop.NetworkManager.IP4Config:WinsServers, The "WinsServers" property
-
org.freedesktop.NetworkManager.IP6Config, org.freedesktop.NetworkManager.IP6Config +
org.freedesktop.NetworkManager.IP6Config, org.freedesktop.NetworkManager.IP6Config
-
org.freedesktop.NetworkManager.IP6Config::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.IP6Config::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.IP6Config:AddressData, The "AddressData" property +
org.freedesktop.NetworkManager.IP6Config:AddressData, The "AddressData" property
-
org.freedesktop.NetworkManager.IP6Config:Addresses, The "Addresses" property +
org.freedesktop.NetworkManager.IP6Config:Addresses, The "Addresses" property
-
org.freedesktop.NetworkManager.IP6Config:DnsOptions, The "DnsOptions" property +
org.freedesktop.NetworkManager.IP6Config:DnsOptions, The "DnsOptions" property
-
org.freedesktop.NetworkManager.IP6Config:DnsPriority, The "DnsPriority" property +
org.freedesktop.NetworkManager.IP6Config:DnsPriority, The "DnsPriority" property
-
org.freedesktop.NetworkManager.IP6Config:Domains, The "Domains" property +
org.freedesktop.NetworkManager.IP6Config:Domains, The "Domains" property
-
org.freedesktop.NetworkManager.IP6Config:Gateway, The "Gateway" property +
org.freedesktop.NetworkManager.IP6Config:Gateway, The "Gateway" property
-
org.freedesktop.NetworkManager.IP6Config:Nameservers, The "Nameservers" property +
org.freedesktop.NetworkManager.IP6Config:Nameservers, The "Nameservers" property
-
org.freedesktop.NetworkManager.IP6Config:RouteData, The "RouteData" property +
org.freedesktop.NetworkManager.IP6Config:RouteData, The "RouteData" property
-
org.freedesktop.NetworkManager.IP6Config:Routes, The "Routes" property +
org.freedesktop.NetworkManager.IP6Config:Routes, The "Routes" property
-
org.freedesktop.NetworkManager.IP6Config:Searches, The "Searches" property +
org.freedesktop.NetworkManager.IP6Config:Searches, The "Searches" property
-
org.freedesktop.NetworkManager.SecretAgent, org.freedesktop.NetworkManager.SecretAgent +
org.freedesktop.NetworkManager.SecretAgent, org.freedesktop.NetworkManager.SecretAgent
-
org.freedesktop.NetworkManager.SecretAgent.CancelGetSecrets(), The CancelGetSecrets() method +
org.freedesktop.NetworkManager.SecretAgent.CancelGetSecrets(), The CancelGetSecrets() method
-
org.freedesktop.NetworkManager.SecretAgent.DeleteSecrets(), The DeleteSecrets() method +
org.freedesktop.NetworkManager.SecretAgent.DeleteSecrets(), The DeleteSecrets() method
-
org.freedesktop.NetworkManager.SecretAgent.GetSecrets(), The GetSecrets() method +
org.freedesktop.NetworkManager.SecretAgent.GetSecrets(), The GetSecrets() method
-
org.freedesktop.NetworkManager.SecretAgent.SaveSecrets(), The SaveSecrets() method +
org.freedesktop.NetworkManager.SecretAgent.SaveSecrets(), The SaveSecrets() method
-
org.freedesktop.NetworkManager.Settings, org.freedesktop.NetworkManager.Settings +
org.freedesktop.NetworkManager.Settings, org.freedesktop.NetworkManager.Settings
-
org.freedesktop.NetworkManager.Settings.AddConnection(), The AddConnection() method +
org.freedesktop.NetworkManager.Settings.AddConnection(), The AddConnection() method
-
org.freedesktop.NetworkManager.Settings.AddConnection2(), The AddConnection2() method +
org.freedesktop.NetworkManager.Settings.AddConnection2(), The AddConnection2() method
-
org.freedesktop.NetworkManager.Settings.AddConnectionUnsaved(), The AddConnectionUnsaved() method +
org.freedesktop.NetworkManager.Settings.AddConnectionUnsaved(), The AddConnectionUnsaved() method
-
org.freedesktop.NetworkManager.Settings.Connection, org.freedesktop.NetworkManager.Settings.Connection +
org.freedesktop.NetworkManager.Settings.Connection, org.freedesktop.NetworkManager.Settings.Connection
-
org.freedesktop.NetworkManager.Settings.Connection.ClearSecrets(), The ClearSecrets() method +
org.freedesktop.NetworkManager.Settings.Connection.ClearSecrets(), The ClearSecrets() method
-
org.freedesktop.NetworkManager.Settings.Connection.Delete(), The Delete() method +
org.freedesktop.NetworkManager.Settings.Connection.Delete(), The Delete() method
-
org.freedesktop.NetworkManager.Settings.Connection.GetSecrets(), The GetSecrets() method +
org.freedesktop.NetworkManager.Settings.Connection.GetSecrets(), The GetSecrets() method
-
org.freedesktop.NetworkManager.Settings.Connection.GetSettings(), The GetSettings() method +
org.freedesktop.NetworkManager.Settings.Connection.GetSettings(), The GetSettings() method
-
org.freedesktop.NetworkManager.Settings.Connection.Save(), The Save() method +
org.freedesktop.NetworkManager.Settings.Connection.Save(), The Save() method
-
org.freedesktop.NetworkManager.Settings.Connection.Update(), The Update() method +
org.freedesktop.NetworkManager.Settings.Connection.Update(), The Update() method
-
org.freedesktop.NetworkManager.Settings.Connection.Update2(), The Update2() method +
org.freedesktop.NetworkManager.Settings.Connection.Update2(), The Update2() method
-
org.freedesktop.NetworkManager.Settings.Connection.UpdateUnsaved(), The UpdateUnsaved() method +
org.freedesktop.NetworkManager.Settings.Connection.UpdateUnsaved(), The UpdateUnsaved() method
-
org.freedesktop.NetworkManager.Settings.Connection::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Settings.Connection::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Settings.Connection::Removed, The "Removed" signal +
org.freedesktop.NetworkManager.Settings.Connection::Removed, The "Removed" signal
-
org.freedesktop.NetworkManager.Settings.Connection::Updated, The "Updated" signal +
org.freedesktop.NetworkManager.Settings.Connection::Updated, The "Updated" signal
-
org.freedesktop.NetworkManager.Settings.Connection:Filename, The "Filename" property +
org.freedesktop.NetworkManager.Settings.Connection:Filename, The "Filename" property
-
org.freedesktop.NetworkManager.Settings.Connection:Flags, The "Flags" property +
org.freedesktop.NetworkManager.Settings.Connection:Flags, The "Flags" property
-
org.freedesktop.NetworkManager.Settings.Connection:Unsaved, The "Unsaved" property +
org.freedesktop.NetworkManager.Settings.Connection:Unsaved, The "Unsaved" property
-
org.freedesktop.NetworkManager.Settings.GetConnectionByUuid(), The GetConnectionByUuid() method +
org.freedesktop.NetworkManager.Settings.GetConnectionByUuid(), The GetConnectionByUuid() method
-
org.freedesktop.NetworkManager.Settings.ListConnections(), The ListConnections() method +
org.freedesktop.NetworkManager.Settings.ListConnections(), The ListConnections() method
-
org.freedesktop.NetworkManager.Settings.LoadConnections(), The LoadConnections() method +
org.freedesktop.NetworkManager.Settings.LoadConnections(), The LoadConnections() method
-
org.freedesktop.NetworkManager.Settings.ReloadConnections(), The ReloadConnections() method +
org.freedesktop.NetworkManager.Settings.ReloadConnections(), The ReloadConnections() method
-
org.freedesktop.NetworkManager.Settings.SaveHostname(), The SaveHostname() method +
org.freedesktop.NetworkManager.Settings.SaveHostname(), The SaveHostname() method
-
org.freedesktop.NetworkManager.Settings::ConnectionRemoved, The "ConnectionRemoved" signal +
org.freedesktop.NetworkManager.Settings::ConnectionRemoved, The "ConnectionRemoved" signal
-
org.freedesktop.NetworkManager.Settings::NewConnection, The "NewConnection" signal +
org.freedesktop.NetworkManager.Settings::NewConnection, The "NewConnection" signal
-
org.freedesktop.NetworkManager.Settings::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Settings::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Settings:CanModify, The "CanModify" property +
org.freedesktop.NetworkManager.Settings:CanModify, The "CanModify" property
-
org.freedesktop.NetworkManager.Settings:Connections, The "Connections" property +
org.freedesktop.NetworkManager.Settings:Connections, The "Connections" property
-
org.freedesktop.NetworkManager.Settings:Hostname, The "Hostname" property +
org.freedesktop.NetworkManager.Settings:Hostname, The "Hostname" property

A

-
org.freedesktop.NetworkManager.Connection.Active, org.freedesktop.NetworkManager.Connection.Active +
org.freedesktop.NetworkManager.Connection.Active, org.freedesktop.NetworkManager.Connection.Active
-
org.freedesktop.NetworkManager.Connection.Active::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Connection.Active::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Connection.Active::StateChanged, The "StateChanged" signal +
org.freedesktop.NetworkManager.Connection.Active::StateChanged, The "StateChanged" signal
-
org.freedesktop.NetworkManager.Connection.Active:Connection, The "Connection" property +
org.freedesktop.NetworkManager.Connection.Active:Connection, The "Connection" property
-
org.freedesktop.NetworkManager.Connection.Active:Default, The "Default" property +
org.freedesktop.NetworkManager.Connection.Active:Default, The "Default" property
-
org.freedesktop.NetworkManager.Connection.Active:Default6, The "Default6" property +
org.freedesktop.NetworkManager.Connection.Active:Default6, The "Default6" property
-
org.freedesktop.NetworkManager.Connection.Active:Devices, The "Devices" property +
org.freedesktop.NetworkManager.Connection.Active:Devices, The "Devices" property
-
org.freedesktop.NetworkManager.Connection.Active:Dhcp4Config, The "Dhcp4Config" property +
org.freedesktop.NetworkManager.Connection.Active:Dhcp4Config, The "Dhcp4Config" property
-
org.freedesktop.NetworkManager.Connection.Active:Dhcp6Config, The "Dhcp6Config" property +
org.freedesktop.NetworkManager.Connection.Active:Dhcp6Config, The "Dhcp6Config" property
-
org.freedesktop.NetworkManager.Connection.Active:Id, The "Id" property +
org.freedesktop.NetworkManager.Connection.Active:Id, The "Id" property
-
org.freedesktop.NetworkManager.Connection.Active:Ip4Config, The "Ip4Config" property +
org.freedesktop.NetworkManager.Connection.Active:Ip4Config, The "Ip4Config" property
-
org.freedesktop.NetworkManager.Connection.Active:Ip6Config, The "Ip6Config" property +
org.freedesktop.NetworkManager.Connection.Active:Ip6Config, The "Ip6Config" property
-
org.freedesktop.NetworkManager.Connection.Active:Master, The "Master" property +
org.freedesktop.NetworkManager.Connection.Active:Master, The "Master" property
-
org.freedesktop.NetworkManager.Connection.Active:SpecificObject, The "SpecificObject" property +
org.freedesktop.NetworkManager.Connection.Active:SpecificObject, The "SpecificObject" property
-
org.freedesktop.NetworkManager.Connection.Active:State, The "State" property +
org.freedesktop.NetworkManager.Connection.Active:State, The "State" property
-
org.freedesktop.NetworkManager.Connection.Active:StateFlags, The "StateFlags" property +
org.freedesktop.NetworkManager.Connection.Active:StateFlags, The "StateFlags" property
-
org.freedesktop.NetworkManager.Connection.Active:Type, The "Type" property +
org.freedesktop.NetworkManager.Connection.Active:Type, The "Type" property
-
org.freedesktop.NetworkManager.Connection.Active:Uuid, The "Uuid" property +
org.freedesktop.NetworkManager.Connection.Active:Uuid, The "Uuid" property
-
org.freedesktop.NetworkManager.Connection.Active:Vpn, The "Vpn" property +
org.freedesktop.NetworkManager.Connection.Active:Vpn, The "Vpn" property
-
addr-gen-mode, ipv6 +
addr-gen-mode, ipv6
-
address-data, ipv4, ipv6 +
address-data, ipv4, ipv6
-
addresses, ipv4, ipv6 +
addresses, ipv4, ipv6
-
ageing, vxlan +
ageing, vxlan
-
ageing-time, bridge +
ageing-time, bridge
-
altsubject-matches, 802-1x +
altsubject-matches, 802-1x
-
anonymous-identity, 802-1x +
anonymous-identity, 802-1x
-
ap-isolation, 802-11-wireless +
ap-isolation, 802-11-wireless
-
apn, gsm +
apn, gsm
-
app-fcoe-flags, dcb +
app-fcoe-flags, dcb
-
app-fcoe-mode, dcb +
app-fcoe-mode, dcb
-
app-fcoe-priority, dcb +
app-fcoe-priority, dcb
-
app-fip-flags, dcb +
app-fip-flags, dcb
-
app-fip-priority, dcb +
app-fip-priority, dcb
-
app-iscsi-flags, dcb +
app-iscsi-flags, dcb
-
app-iscsi-priority, dcb +
app-iscsi-priority, dcb
-
assigned-mac-address, 802-3-ethernet, 802-11-wireless +
assigned-mac-address, 802-3-ethernet, 802-11-wireless
-
auth-alg, 802-11-wireless-security +
auth-alg, 802-11-wireless-security
-
auth-retries, connection +
auth-retries, connection
-
auth-timeout, 802-1x +
auth-timeout, 802-1x
-
auto-config, gsm +
auto-config, gsm
-
auto-negotiate, 802-3-ethernet +
auto-negotiate, 802-3-ethernet
-
autoconnect, connection +
autoconnect, connection
-
autoconnect-priority, connection +
autoconnect-priority, connection
-
autoconnect-retries, connection +
autoconnect-retries, connection
-
autoconnect-slaves, connection +
autoconnect-slaves, connection
-
autoprobe-drivers, sriov +
autoprobe-drivers, sriov

B

-
band, 802-11-wireless +
band, 802-11-wireless
-
baud, ppp, serial +
baud, ppp, serial
-
bdaddr, bluetooth +
bdaddr, bluetooth
-
bits, serial +
bits, serial
-
bond-downdelay, ovs-port +
bond-downdelay, ovs-port
-
bond-mode, ovs-port +
bond-mode, ovs-port
-
bond-updelay, ovs-port +
bond-updelay, ovs-port
-
browser-only, proxy +
browser-only, proxy
-
bssid, 802-11-wireless +
bssid, 802-11-wireless

C

-
ca-cert, 802-1x +
ca-cert, 802-1x
-
ca-cert-password, 802-1x +
ca-cert-password, 802-1x
-
ca-cert-password-flags, 802-1x +
ca-cert-password-flags, 802-1x
-
ca-path, 802-1x +
ca-path, 802-1x
-
channel, 802-11-olpc-mesh, 802-11-wireless, wpan +
channel, 802-11-olpc-mesh, 802-11-wireless, wpan
-
org.freedesktop.NetworkManager.Checkpoint, org.freedesktop.NetworkManager.Checkpoint +
org.freedesktop.NetworkManager.Checkpoint, org.freedesktop.NetworkManager.Checkpoint
-
org.freedesktop.NetworkManager.Checkpoint::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Checkpoint::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Checkpoint:Created, The "Created" property +
org.freedesktop.NetworkManager.Checkpoint:Created, The "Created" property
-
org.freedesktop.NetworkManager.Checkpoint:Devices, The "Devices" property +
org.freedesktop.NetworkManager.Checkpoint:Devices, The "Devices" property
-
org.freedesktop.NetworkManager.Checkpoint:RollbackTimeout, The "RollbackTimeout" property +
org.freedesktop.NetworkManager.Checkpoint:RollbackTimeout, The "RollbackTimeout" property
-
client-cert, 802-1x +
client-cert, 802-1x
-
client-cert-password, 802-1x +
client-cert-password, 802-1x
-
client-cert-password-flags, 802-1x +
client-cert-password-flags, 802-1x
-
cloned-mac-address, 802-3-ethernet, 802-11-wireless +
cloned-mac-address, 802-3-ethernet, 802-11-wireless
-
config, team, team-port +
config, team, team-port
-
crtscts, ppp +
crtscts, ppp

D

-
dad-timeout, ipv4, ipv6 +
dad-timeout, ipv4, ipv6
-
data, user, vpn, ovs-external-ids +
data, user, vpn, ovs-external-ids
-
datapath-type, ovs-bridge +
datapath-type, ovs-bridge
-
destination-port, vxlan +
destination-port, vxlan
-
devargs, ovs-dpdk +
devargs, ovs-dpdk
-
device-id, gsm +
device-id, gsm
-
org.freedesktop.NetworkManager.Device.Wired, org.freedesktop.NetworkManager.Device.Wired +
org.freedesktop.NetworkManager.Device.Wired, org.freedesktop.NetworkManager.Device.Wired
-
org.freedesktop.NetworkManager.Device.Wired::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Wired::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Wired:Carrier, The "Carrier" property +
org.freedesktop.NetworkManager.Device.Wired:Carrier, The "Carrier" property
-
org.freedesktop.NetworkManager.Device.Wired:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Wired:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Wired:PermHwAddress, The "PermHwAddress" property +
org.freedesktop.NetworkManager.Device.Wired:PermHwAddress, The "PermHwAddress" property
-
org.freedesktop.NetworkManager.Device.Wired:S390Subchannels, The "S390Subchannels" property +
org.freedesktop.NetworkManager.Device.Wired:S390Subchannels, The "S390Subchannels" property
-
org.freedesktop.NetworkManager.Device.Wired:Speed, The "Speed" property +
org.freedesktop.NetworkManager.Device.Wired:Speed, The "Speed" property
-
org.freedesktop.NetworkManager.Device.Wireless, org.freedesktop.NetworkManager.Device.Wireless +
org.freedesktop.NetworkManager.Device.Wireless, org.freedesktop.NetworkManager.Device.Wireless
-
org.freedesktop.NetworkManager.Device.Wireless.GetAccessPoints(), The GetAccessPoints() method +
org.freedesktop.NetworkManager.Device.Wireless.GetAccessPoints(), The GetAccessPoints() method
-
org.freedesktop.NetworkManager.Device.Wireless.GetAllAccessPoints(), The GetAllAccessPoints() method +
org.freedesktop.NetworkManager.Device.Wireless.GetAllAccessPoints(), The GetAllAccessPoints() method
-
org.freedesktop.NetworkManager.Device.Wireless.RequestScan(), The RequestScan() method +
org.freedesktop.NetworkManager.Device.Wireless.RequestScan(), The RequestScan() method
-
org.freedesktop.NetworkManager.Device.Wireless::AccessPointAdded, The "AccessPointAdded" signal +
org.freedesktop.NetworkManager.Device.Wireless::AccessPointAdded, The "AccessPointAdded" signal
-
org.freedesktop.NetworkManager.Device.Wireless::AccessPointRemoved, The "AccessPointRemoved" signal +
org.freedesktop.NetworkManager.Device.Wireless::AccessPointRemoved, The "AccessPointRemoved" signal
-
org.freedesktop.NetworkManager.Device.Wireless::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.Device.Wireless::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.Device.Wireless:AccessPoints, The "AccessPoints" property +
org.freedesktop.NetworkManager.Device.Wireless:AccessPoints, The "AccessPoints" property
-
org.freedesktop.NetworkManager.Device.Wireless:ActiveAccessPoint, The "ActiveAccessPoint" property +
org.freedesktop.NetworkManager.Device.Wireless:ActiveAccessPoint, The "ActiveAccessPoint" property
-
org.freedesktop.NetworkManager.Device.Wireless:Bitrate, The "Bitrate" property +
org.freedesktop.NetworkManager.Device.Wireless:Bitrate, The "Bitrate" property
-
org.freedesktop.NetworkManager.Device.Wireless:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.Wireless:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.Wireless:LastScan, The "LastScan" property +
org.freedesktop.NetworkManager.Device.Wireless:LastScan, The "LastScan" property
-
org.freedesktop.NetworkManager.Device.Wireless:Mode, The "Mode" property +
org.freedesktop.NetworkManager.Device.Wireless:Mode, The "Mode" property
-
org.freedesktop.NetworkManager.Device.Wireless:PermHwAddress, The "PermHwAddress" property +
org.freedesktop.NetworkManager.Device.Wireless:PermHwAddress, The "PermHwAddress" property
-
org.freedesktop.NetworkManager.Device.Wireless:WirelessCapabilities, The "WirelessCapabilities" property +
org.freedesktop.NetworkManager.Device.Wireless:WirelessCapabilities, The "WirelessCapabilities" property
-
org.freedesktop.NetworkManager.Device.WifiP2P, org.freedesktop.NetworkManager.Device.WifiP2P +
org.freedesktop.NetworkManager.Device.WifiP2P, org.freedesktop.NetworkManager.Device.WifiP2P
-
org.freedesktop.NetworkManager.Device.WifiP2P.StartFind(), The StartFind() method +
org.freedesktop.NetworkManager.Device.WifiP2P.StartFind(), The StartFind() method
-
org.freedesktop.NetworkManager.Device.WifiP2P.StopFind(), The StopFind() method +
org.freedesktop.NetworkManager.Device.WifiP2P.StopFind(), The StopFind() method
-
org.freedesktop.NetworkManager.Device.WifiP2P::PeerAdded, The "PeerAdded" signal +
org.freedesktop.NetworkManager.Device.WifiP2P::PeerAdded, The "PeerAdded" signal
-
org.freedesktop.NetworkManager.Device.WifiP2P::PeerRemoved, The "PeerRemoved" signal +
org.freedesktop.NetworkManager.Device.WifiP2P::PeerRemoved, The "PeerRemoved" signal
-
org.freedesktop.NetworkManager.Device.WifiP2P:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.Device.WifiP2P:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.Device.WifiP2P:Peers, The "Peers" property +
org.freedesktop.NetworkManager.Device.WifiP2P:Peers, The "Peers" property
-
dhcp-anycast-address, 802-11-olpc-mesh +
dhcp-anycast-address, 802-11-olpc-mesh
-
dhcp-client-id, ipv4 +
dhcp-client-id, ipv4
-
dhcp-duid, ipv6 +
dhcp-duid, ipv6
-
dhcp-fqdn, ipv4 +
dhcp-fqdn, ipv4
-
dhcp-hostname, ipv4, ipv6 +
dhcp-hostname, ipv4, ipv6
-
dhcp-hostname-flags, ipv4, ipv6 +
dhcp-hostname-flags, ipv4, ipv6
-
dhcp-iaid, ipv4, ipv6 +
dhcp-iaid, ipv4, ipv6
-
dhcp-reject-servers, ipv4, ipv6 +
dhcp-reject-servers, ipv4, ipv6
-
dhcp-send-hostname, ipv4, ipv6 +
dhcp-send-hostname, ipv4, ipv6
-
dhcp-timeout, ipv4, ipv6 +
dhcp-timeout, ipv4, ipv6
-
dhcp-vendor-class-identifier, ipv4 +
dhcp-vendor-class-identifier, ipv4
-
org.freedesktop.NetworkManager.DHCP4Config, org.freedesktop.NetworkManager.DHCP4Config +
org.freedesktop.NetworkManager.DHCP4Config, org.freedesktop.NetworkManager.DHCP4Config
-
org.freedesktop.NetworkManager.DHCP4Config::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.DHCP4Config::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.DHCP4Config:Options, The "Options" property +
org.freedesktop.NetworkManager.DHCP4Config:Options, The "Options" property
-
org.freedesktop.NetworkManager.DHCP6Config, org.freedesktop.NetworkManager.DHCP6Config +
org.freedesktop.NetworkManager.DHCP6Config, org.freedesktop.NetworkManager.DHCP6Config
-
org.freedesktop.NetworkManager.DHCP6Config::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.DHCP6Config::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.DHCP6Config:Options, The "Options" property +
org.freedesktop.NetworkManager.DHCP6Config:Options, The "Options" property
-
dns, ipv4, ipv6 +
dns, ipv4, ipv6
-
dns-options, ipv4, ipv6 +
dns-options, ipv4, ipv6
-
dns-priority, ipv4, ipv6 +
dns-priority, ipv4, ipv6
-
dns-search, ipv4, ipv6 +
dns-search, ipv4, ipv6
-
domain-match, 802-1x +
domain-match, 802-1x
-
domain-suffix-match, 802-1x +
domain-suffix-match, 802-1x
-
driver, match +
driver, match
-
duplex, 802-3-ethernet +
duplex, 802-3-ethernet

E

-
eap, 802-1x +
eap, 802-1x
-
egress-priority-map, vlan +
egress-priority-map, vlan
-
encapsulation, adsl +
encapsulation, adsl
-
encapsulation-limit, ip-tunnel +
encapsulation-limit, ip-tunnel
-
encrypt, macsec +
encrypt, macsec

F

-
fail-mode, ovs-bridge +
fail-mode, ovs-bridge
-
fils, 802-11-wireless-security +
fils, 802-11-wireless-security
-
flags, ip-tunnel, vlan +
flags, ip-tunnel, vlan
-
flow-label, ip-tunnel +
flow-label, ip-tunnel
-
forward-delay, bridge +
forward-delay, bridge
-
from-dhcp, hostname +
from-dhcp, hostname
-
from-dns-lookup, hostname +
from-dns-lookup, hostname
-
fwmark, wireguard +
fwmark, wireguard

G

-
gateway, ipv4, ipv6 +
gateway, ipv4, ipv6
-
gateway-ping-timeout, connection +
gateway-ping-timeout, connection
-
generate-mac-address-mask, 802-3-ethernet, 802-11-wireless +
generate-mac-address-mask, 802-3-ethernet, 802-11-wireless
-
group, tun, 802-11-wireless-security +
group, tun, 802-11-wireless-security
-
group-address, bridge +
group-address, bridge
-
group-forward-mask, bridge +
group-forward-mask, bridge

H

-
hairpin-mode, bridge-port +
hairpin-mode, bridge-port
-
hello-time, bridge +
hello-time, bridge
-
hidden, 802-11-wireless +
hidden, 802-11-wireless
-
home-only, gsm +
home-only, gsm

I

-
id, connection, vlan, vxlan +
id, connection, vlan, vxlan
-
identity, 802-1x +
identity, 802-1x
-
ignore-auto-dns, ipv4, ipv6 +
ignore-auto-dns, ipv4, ipv6
-
ignore-auto-routes, ipv4, ipv6 +
ignore-auto-routes, ipv4, ipv6
-
ingress-priority-map, vlan +
ingress-priority-map, vlan
-
input-key, ip-tunnel +
input-key, ip-tunnel
-
interface-name, connection, bond, bridge, match, team, vlan +
interface-name, connection, bond, bridge, match, team, vlan
-
ip4-auto-default-route, wireguard +
ip4-auto-default-route, wireguard
-
ip6-auto-default-route, wireguard +
ip6-auto-default-route, wireguard
-
ip6-privacy, ipv6 +
ip6-privacy, ipv6

K

-
kernel-command-line, match +
kernel-command-line, match
-
key-mgmt, 802-11-wireless-security +
key-mgmt, 802-11-wireless-security

L

-
l2-miss, vxlan +
l2-miss, vxlan
-
l3-miss, vxlan +
l3-miss, vxlan
-
lacp, ovs-port +
lacp, ovs-port
-
lacp-key, team-port +
lacp-key, team-port
-
lacp-prio, team-port +
lacp-prio, team-port
-
lcp-echo-failure, ppp +
lcp-echo-failure, ppp
-
lcp-echo-interval, ppp +
lcp-echo-interval, ppp
-
leap-password, 802-11-wireless-security +
leap-password, 802-11-wireless-security
-
leap-password-flags, 802-11-wireless-security +
leap-password-flags, 802-11-wireless-security
-
leap-username, 802-11-wireless-security +
leap-username, 802-11-wireless-security
-
learning, vxlan +
learning, vxlan
-
limit, vxlan +
limit, vxlan
-
link-watchers, team, team-port +
link-watchers, team, team-port
-
listen-port, wireguard +
listen-port, wireguard
-
lldp, connection +
lldp, connection
-
llmnr, connection +
llmnr, connection
-
local, ip-tunnel, vxlan +
local, ip-tunnel, vxlan

M

-
mac-address, bridge, infiniband, wimax, 802-3-ethernet, 802-11-wireless, wpan +
mac-address, bridge, infiniband, wimax, 802-3-ethernet, 802-11-wireless, wpan
-
mac-address-blacklist, 802-3-ethernet, 802-11-wireless +
mac-address-blacklist, 802-3-ethernet, 802-11-wireless
-
mac-address-randomization, 802-11-wireless +
mac-address-randomization, 802-11-wireless
-
org.freedesktop.NetworkManager, org.freedesktop.NetworkManager +
org.freedesktop.NetworkManager, org.freedesktop.NetworkManager
-
org.freedesktop.NetworkManager.ActivateConnection(), The ActivateConnection() method +
org.freedesktop.NetworkManager.ActivateConnection(), The ActivateConnection() method
-
org.freedesktop.NetworkManager.AddAndActivateConnection(), The AddAndActivateConnection() method +
org.freedesktop.NetworkManager.AddAndActivateConnection(), The AddAndActivateConnection() method
-
org.freedesktop.NetworkManager.AddAndActivateConnection2(), The AddAndActivateConnection2() method +
org.freedesktop.NetworkManager.AddAndActivateConnection2(), The AddAndActivateConnection2() method
-
org.freedesktop.NetworkManager.CheckConnectivity(), The CheckConnectivity() method +
org.freedesktop.NetworkManager.CheckConnectivity(), The CheckConnectivity() method
-
org.freedesktop.NetworkManager.CheckpointAdjustRollbackTimeout(), The CheckpointAdjustRollbackTimeout() method +
org.freedesktop.NetworkManager.CheckpointAdjustRollbackTimeout(), The CheckpointAdjustRollbackTimeout() method
-
org.freedesktop.NetworkManager.CheckpointCreate(), The CheckpointCreate() method +
org.freedesktop.NetworkManager.CheckpointCreate(), The CheckpointCreate() method
-
org.freedesktop.NetworkManager.CheckpointDestroy(), The CheckpointDestroy() method +
org.freedesktop.NetworkManager.CheckpointDestroy(), The CheckpointDestroy() method
-
org.freedesktop.NetworkManager.CheckpointRollback(), The CheckpointRollback() method +
org.freedesktop.NetworkManager.CheckpointRollback(), The CheckpointRollback() method
-
org.freedesktop.NetworkManager.DeactivateConnection(), The DeactivateConnection() method +
org.freedesktop.NetworkManager.DeactivateConnection(), The DeactivateConnection() method
-
org.freedesktop.NetworkManager.Enable(), The Enable() method +
org.freedesktop.NetworkManager.Enable(), The Enable() method
-
org.freedesktop.NetworkManager.GetAllDevices(), The GetAllDevices() method +
org.freedesktop.NetworkManager.GetAllDevices(), The GetAllDevices() method
-
org.freedesktop.NetworkManager.GetDeviceByIpIface(), The GetDeviceByIpIface() method +
org.freedesktop.NetworkManager.GetDeviceByIpIface(), The GetDeviceByIpIface() method
-
org.freedesktop.NetworkManager.GetDevices(), The GetDevices() method +
org.freedesktop.NetworkManager.GetDevices(), The GetDevices() method
-
org.freedesktop.NetworkManager.GetLogging(), The GetLogging() method +
org.freedesktop.NetworkManager.GetLogging(), The GetLogging() method
-
org.freedesktop.NetworkManager.GetPermissions(), The GetPermissions() method +
org.freedesktop.NetworkManager.GetPermissions(), The GetPermissions() method
-
org.freedesktop.NetworkManager.Reload(), The Reload() method +
org.freedesktop.NetworkManager.Reload(), The Reload() method
-
org.freedesktop.NetworkManager.SetLogging(), The SetLogging() method +
org.freedesktop.NetworkManager.SetLogging(), The SetLogging() method
-
org.freedesktop.NetworkManager.Sleep(), The Sleep() method +
org.freedesktop.NetworkManager.Sleep(), The Sleep() method
-
org.freedesktop.NetworkManager.state(), The state() method +
org.freedesktop.NetworkManager.state(), The state() method
-
org.freedesktop.NetworkManager::CheckPermissions, The "CheckPermissions" signal +
org.freedesktop.NetworkManager::CheckPermissions, The "CheckPermissions" signal
-
org.freedesktop.NetworkManager::DeviceAdded, The "DeviceAdded" signal +
org.freedesktop.NetworkManager::DeviceAdded, The "DeviceAdded" signal
-
org.freedesktop.NetworkManager::DeviceRemoved, The "DeviceRemoved" signal +
org.freedesktop.NetworkManager::DeviceRemoved, The "DeviceRemoved" signal
-
org.freedesktop.NetworkManager::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager::StateChanged, The "StateChanged" signal +
org.freedesktop.NetworkManager::StateChanged, The "StateChanged" signal
-
org.freedesktop.NetworkManager:ActivatingConnection, The "ActivatingConnection" property +
org.freedesktop.NetworkManager:ActivatingConnection, The "ActivatingConnection" property
-
org.freedesktop.NetworkManager:ActiveConnections, The "ActiveConnections" property +
org.freedesktop.NetworkManager:ActiveConnections, The "ActiveConnections" property
-
org.freedesktop.NetworkManager:AllDevices, The "AllDevices" property +
org.freedesktop.NetworkManager:AllDevices, The "AllDevices" property
-
org.freedesktop.NetworkManager:Capabilities, The "Capabilities" property +
org.freedesktop.NetworkManager:Capabilities, The "Capabilities" property
-
org.freedesktop.NetworkManager:Checkpoints, The "Checkpoints" property +
org.freedesktop.NetworkManager:Checkpoints, The "Checkpoints" property
-
org.freedesktop.NetworkManager:Connectivity, The "Connectivity" property +
org.freedesktop.NetworkManager:Connectivity, The "Connectivity" property
-
org.freedesktop.NetworkManager:ConnectivityCheckAvailable, The "ConnectivityCheckAvailable" property +
org.freedesktop.NetworkManager:ConnectivityCheckAvailable, The "ConnectivityCheckAvailable" property
-
org.freedesktop.NetworkManager:ConnectivityCheckEnabled, The "ConnectivityCheckEnabled" property +
org.freedesktop.NetworkManager:ConnectivityCheckEnabled, The "ConnectivityCheckEnabled" property
-
org.freedesktop.NetworkManager:ConnectivityCheckUri, The "ConnectivityCheckUri" property +
org.freedesktop.NetworkManager:ConnectivityCheckUri, The "ConnectivityCheckUri" property
-
org.freedesktop.NetworkManager:Devices, The "Devices" property +
org.freedesktop.NetworkManager:Devices, The "Devices" property
-
org.freedesktop.NetworkManager:GlobalDnsConfiguration, The "GlobalDnsConfiguration" property +
org.freedesktop.NetworkManager:GlobalDnsConfiguration, The "GlobalDnsConfiguration" property
-
org.freedesktop.NetworkManager:Metered, The "Metered" property +
org.freedesktop.NetworkManager:Metered, The "Metered" property
-
org.freedesktop.NetworkManager:NetworkingEnabled, The "NetworkingEnabled" property +
org.freedesktop.NetworkManager:NetworkingEnabled, The "NetworkingEnabled" property
-
org.freedesktop.NetworkManager:PrimaryConnection, The "PrimaryConnection" property +
org.freedesktop.NetworkManager:PrimaryConnection, The "PrimaryConnection" property
-
org.freedesktop.NetworkManager:PrimaryConnectionType, The "PrimaryConnectionType" property +
org.freedesktop.NetworkManager:PrimaryConnectionType, The "PrimaryConnectionType" property
-
org.freedesktop.NetworkManager:Startup, The "Startup" property +
org.freedesktop.NetworkManager:Startup, The "Startup" property
-
org.freedesktop.NetworkManager:State, The "State" property +
org.freedesktop.NetworkManager:State, The "State" property
-
org.freedesktop.NetworkManager:Version, The "Version" property +
org.freedesktop.NetworkManager:Version, The "Version" property
-
org.freedesktop.NetworkManager:WimaxEnabled, The "WimaxEnabled" property +
org.freedesktop.NetworkManager:WimaxEnabled, The "WimaxEnabled" property
-
org.freedesktop.NetworkManager:WimaxHardwareEnabled, The "WimaxHardwareEnabled" property +
org.freedesktop.NetworkManager:WimaxHardwareEnabled, The "WimaxHardwareEnabled" property
-
org.freedesktop.NetworkManager:WirelessEnabled, The "WirelessEnabled" property +
org.freedesktop.NetworkManager:WirelessEnabled, The "WirelessEnabled" property
-
org.freedesktop.NetworkManager:WirelessHardwareEnabled, The "WirelessHardwareEnabled" property +
org.freedesktop.NetworkManager:WirelessHardwareEnabled, The "WirelessHardwareEnabled" property
-
org.freedesktop.NetworkManager:WwanEnabled, The "WwanEnabled" property +
org.freedesktop.NetworkManager:WwanEnabled, The "WwanEnabled" property
-
org.freedesktop.NetworkManager:WwanHardwareEnabled, The "WwanHardwareEnabled" property +
org.freedesktop.NetworkManager:WwanHardwareEnabled, The "WwanHardwareEnabled" property
-
master, connection +
master, connection
-
max-age, bridge +
max-age, bridge
-
may-fail, ipv4, ipv6 +
may-fail, ipv4, ipv6
-
mcast-rejoin-count, team +
mcast-rejoin-count, team
-
mcast-rejoin-interval, team +
mcast-rejoin-interval, team
-
mcast-snooping-enable, ovs-bridge +
mcast-snooping-enable, ovs-bridge
-
mdns, connection +
mdns, connection
-
metered, connection +
metered, connection
-
method, ipv4, ipv6, proxy +
method, ipv4, ipv6, proxy
-
mka-cak, macsec +
mka-cak, macsec
-
mka-cak-flags, macsec +
mka-cak-flags, macsec
-
mka-ckn, macsec +
mka-ckn, macsec
-
mode, ip-tunnel, macsec, macvlan, tun, 802-11-wireless +
mode, ip-tunnel, macsec, macvlan, tun, 802-11-wireless
-
mppe-stateful, ppp +
mppe-stateful, ppp
-
mru, ppp +
mru, ppp
-
mtu, cdma, gsm, infiniband, ip-tunnel, ppp, 802-3-ethernet, wireguard, 802-11-wireless +
mtu, cdma, gsm, infiniband, ip-tunnel, ppp, 802-3-ethernet, wireguard, 802-11-wireless
-
mud-url, connection +
mud-url, connection
-
multi-connect, connection +
multi-connect, connection
-
multi-queue, tun +
multi-queue, tun
-
multicast-hash-max, bridge +
multicast-hash-max, bridge
-
multicast-last-member-count, bridge +
multicast-last-member-count, bridge
-
multicast-last-member-interval, bridge +
multicast-last-member-interval, bridge
-
multicast-membership-interval, bridge +
multicast-membership-interval, bridge
-
multicast-querier, bridge +
multicast-querier, bridge
-
multicast-querier-interval, bridge +
multicast-querier-interval, bridge
-
multicast-query-interval, bridge +
multicast-query-interval, bridge
-
multicast-query-response-interval, bridge +
multicast-query-response-interval, bridge
-
multicast-query-use-ifaddr, bridge +
multicast-query-use-ifaddr, bridge
-
multicast-router, bridge +
multicast-router, bridge
-
multicast-snooping, bridge +
multicast-snooping, bridge
-
multicast-startup-query-count, bridge +
multicast-startup-query-count, bridge
-
multicast-startup-query-interval, bridge +
multicast-startup-query-interval, bridge

N

-
network-id, gsm +
network-id, gsm
-
network-name, wimax +
network-name, wimax
-
never-default, ipv4, ipv6 +
never-default, ipv4, ipv6
-
NM80211ApFlags, enum NM80211ApFlags +
NM80211ApFlags, enum NM80211ApFlags
-
NM80211ApSecurityFlags, enum NM80211ApSecurityFlags +
NM80211ApSecurityFlags, enum NM80211ApSecurityFlags
-
NM80211Mode, enum NM80211Mode +
NM80211Mode, enum NM80211Mode
-
NMActivationStateFlags, enum NMActivationStateFlags +
NMActivationStateFlags, enum NMActivationStateFlags
-
NMActiveConnectionState, enum NMActiveConnectionState +
NMActiveConnectionState, enum NMActiveConnectionState
-
NMActiveConnectionStateReason, enum NMActiveConnectionStateReason +
NMActiveConnectionStateReason, enum NMActiveConnectionStateReason
-
NMBluetoothCapabilities, enum NMBluetoothCapabilities +
NMBluetoothCapabilities, enum NMBluetoothCapabilities
-
NMCapability, enum NMCapability +
NMCapability, enum NMCapability
-
NMCheckpointCreateFlags, enum NMCheckpointCreateFlags +
NMCheckpointCreateFlags, enum NMCheckpointCreateFlags
-
NMClientPermission, enum NMClientPermission +
NMClientPermission, enum NMClientPermission
-
NMClientPermissionResult, enum NMClientPermissionResult +
NMClientPermissionResult, enum NMClientPermissionResult
-
NMConnectionMultiConnect, enum NMConnectionMultiConnect +
NMConnectionMultiConnect, enum NMConnectionMultiConnect
-
NMConnectivityState, enum NMConnectivityState +
NMConnectivityState, enum NMConnectivityState
-
NMDeviceCapabilities, enum NMDeviceCapabilities +
NMDeviceCapabilities, enum NMDeviceCapabilities
-
NMDeviceInterfaceFlags, enum NMDeviceInterfaceFlags +
NMDeviceInterfaceFlags, enum NMDeviceInterfaceFlags
-
NMDeviceModemCapabilities, enum NMDeviceModemCapabilities +
NMDeviceModemCapabilities, enum NMDeviceModemCapabilities
-
NMDeviceState, enum NMDeviceState +
NMDeviceState, enum NMDeviceState
-
NMDeviceStateReason, enum NMDeviceStateReason +
NMDeviceStateReason, enum NMDeviceStateReason
-
NMDeviceType, enum NMDeviceType +
NMDeviceType, enum NMDeviceType
-
NMDeviceWifiCapabilities, enum NMDeviceWifiCapabilities +
NMDeviceWifiCapabilities, enum NMDeviceWifiCapabilities
-
NMIPTunnelMode, enum NMIPTunnelMode +
NMIPTunnelMode, enum NMIPTunnelMode
-
NMManagerReloadFlags, enum NMManagerReloadFlags +
NMManagerReloadFlags, enum NMManagerReloadFlags
-
NMMetered, enum NMMetered +
NMMetered, enum NMMetered
-
NMRollbackResult, enum NMRollbackResult +
NMRollbackResult, enum NMRollbackResult
-
NMSecretAgentCapabilities, enum NMSecretAgentCapabilities +
NMSecretAgentCapabilities, enum NMSecretAgentCapabilities
-
NMSecretAgentGetSecretsFlags, enum NMSecretAgentGetSecretsFlags +
NMSecretAgentGetSecretsFlags, enum NMSecretAgentGetSecretsFlags
-
NMSettingsAddConnection2Flags, enum NMSettingsAddConnection2Flags +
NMSettingsAddConnection2Flags, enum NMSettingsAddConnection2Flags
-
NMSettingsConnectionFlags, enum NMSettingsConnectionFlags +
NMSettingsConnectionFlags, enum NMSettingsConnectionFlags
-
NMSettingsUpdate2Flags, enum NMSettingsUpdate2Flags +
NMSettingsUpdate2Flags, enum NMSettingsUpdate2Flags
-
NMState, enum NMState +
NMState, enum NMState
-
NMTernary, enum NMTernary +
NMTernary, enum NMTernary
-
NMVpnConnectionState, enum NMVpnConnectionState +
NMVpnConnectionState, enum NMVpnConnectionState
-
NMVpnConnectionStateReason, enum NMVpnConnectionStateReason +
NMVpnConnectionStateReason, enum NMVpnConnectionStateReason
-
NMVpnPluginFailure, enum NMVpnPluginFailure +
NMVpnPluginFailure, enum NMVpnPluginFailure
-
NMVpnServiceState, enum NMVpnServiceState +
NMVpnServiceState, enum NMVpnServiceState
-
NMWimaxNspNetworkType, enum NMWimaxNspNetworkType +
NMWimaxNspNetworkType, enum NMWimaxNspNetworkType
-
no-vj-comp, ppp +
no-vj-comp, ppp
-
noauth, ppp +
noauth, ppp
-
nobsdcomp, ppp +
nobsdcomp, ppp
-
nodeflate, ppp +
nodeflate, ppp
-
notify-peers-count, team +
notify-peers-count, team
-
notify-peers-interval, team +
notify-peers-interval, team
-
number, cdma, gsm +
number, cdma, gsm

O

-
only-from-default, hostname +
only-from-default, hostname
-
optional, 802-1x +
optional, 802-1x
-
options, bond +
options, bond
-
output-key, ip-tunnel +
output-key, ip-tunnel
-
owner, tun +
owner, tun

P

-
p-key, infiniband +
p-key, infiniband
-
pac-file, 802-1x +
pac-file, 802-1x
-
pac-script, proxy +
pac-script, proxy
-
pac-url, proxy +
pac-url, proxy
-
page, wpan +
page, wpan
-
pairwise, 802-11-wireless-security +
pairwise, 802-11-wireless-security
-
pan-id, wpan +
pan-id, wpan
-
parent, 6lowpan, infiniband, ip-tunnel, macsec, macvlan, pppoe, vlan, vxlan +
parent, 6lowpan, infiniband, ip-tunnel, macsec, macvlan, pppoe, vlan, vxlan
-
parity, serial +
parity, serial
-
password, 802-1x, adsl, cdma, gsm, pppoe +
password, 802-1x, adsl, cdma, gsm, pppoe
-
password-flags, 802-1x, adsl, cdma, gsm, pppoe +
password-flags, 802-1x, adsl, cdma, gsm, pppoe
-
password-raw, 802-1x +
password-raw, 802-1x
-
password-raw-flags, 802-1x +
password-raw-flags, 802-1x
-
path, match +
path, match
-
path-cost, bridge-port +
path-cost, bridge-port
-
path-mtu-discovery, ip-tunnel +
path-mtu-discovery, ip-tunnel
-
peer, ovs-patch, wifi-p2p, veth +
peer, ovs-patch, wifi-p2p, veth
-
peer-routes, wireguard +
peer-routes, wireguard
-
peers, wireguard +
peers, wireguard
-
permissions, connection +
permissions, connection
-
persistent, vpn +
persistent, vpn
-
phase1-auth-flags, 802-1x +
phase1-auth-flags, 802-1x
-
phase1-fast-provisioning, 802-1x +
phase1-fast-provisioning, 802-1x
-
phase1-peaplabel, 802-1x +
phase1-peaplabel, 802-1x
-
phase1-peapver, 802-1x +
phase1-peapver, 802-1x
-
phase2-altsubject-matches, 802-1x +
phase2-altsubject-matches, 802-1x
-
phase2-auth, 802-1x +
phase2-auth, 802-1x
-
phase2-autheap, 802-1x +
phase2-autheap, 802-1x
-
phase2-ca-cert, 802-1x +
phase2-ca-cert, 802-1x
-
phase2-ca-cert-password, 802-1x +
phase2-ca-cert-password, 802-1x
-
phase2-ca-cert-password-flags, 802-1x +
phase2-ca-cert-password-flags, 802-1x
-
phase2-ca-path, 802-1x +
phase2-ca-path, 802-1x
-
phase2-client-cert, 802-1x +
phase2-client-cert, 802-1x
-
phase2-client-cert-password, 802-1x +
phase2-client-cert-password, 802-1x
-
phase2-client-cert-password-flags, 802-1x +
phase2-client-cert-password-flags, 802-1x
-
phase2-domain-match, 802-1x +
phase2-domain-match, 802-1x
-
phase2-domain-suffix-match, 802-1x +
phase2-domain-suffix-match, 802-1x
-
phase2-private-key, 802-1x +
phase2-private-key, 802-1x
-
phase2-private-key-password, 802-1x +
phase2-private-key-password, 802-1x
-
phase2-private-key-password-flags, 802-1x +
phase2-private-key-password-flags, 802-1x
-
phase2-subject-match, 802-1x +
phase2-subject-match, 802-1x
-
pi, tun +
pi, tun
-
pin, 802-1x, gsm +
pin, 802-1x, gsm
-
pin-flags, 802-1x, gsm +
pin-flags, 802-1x, gsm
-
pmf, 802-11-wireless-security +
pmf, 802-11-wireless-security
-
port, macsec, 802-3-ethernet +
port, macsec, 802-3-ethernet
-
powersave, 802-11-wireless +
powersave, 802-11-wireless
-
org.freedesktop.NetworkManager.PPP, org.freedesktop.NetworkManager.PPP +
org.freedesktop.NetworkManager.PPP, org.freedesktop.NetworkManager.PPP
-
org.freedesktop.NetworkManager.PPP.NeedSecrets(), The NeedSecrets() method +
org.freedesktop.NetworkManager.PPP.NeedSecrets(), The NeedSecrets() method
-
org.freedesktop.NetworkManager.PPP.SetIfindex(), The SetIfindex() method +
org.freedesktop.NetworkManager.PPP.SetIfindex(), The SetIfindex() method
-
org.freedesktop.NetworkManager.PPP.SetIp4Config(), The SetIp4Config() method +
org.freedesktop.NetworkManager.PPP.SetIp4Config(), The SetIp4Config() method
-
org.freedesktop.NetworkManager.PPP.SetIp6Config(), The SetIp6Config() method +
org.freedesktop.NetworkManager.PPP.SetIp6Config(), The SetIp6Config() method
-
org.freedesktop.NetworkManager.PPP.SetState(), The SetState() method +
org.freedesktop.NetworkManager.PPP.SetState(), The SetState() method
-
prio, team-port +
prio, team-port
-
priority, bridge, bridge-port, hostname +
priority, bridge, bridge-port, hostname
-
priority-bandwidth, dcb +
priority-bandwidth, dcb
-
priority-flow-control, dcb +
priority-flow-control, dcb
-
priority-flow-control-flags, dcb +
priority-flow-control-flags, dcb
-
priority-group-bandwidth, dcb +
priority-group-bandwidth, dcb
-
priority-group-flags, dcb +
priority-group-flags, dcb
-
priority-group-id, dcb +
priority-group-id, dcb
-
priority-strict-bandwidth, dcb +
priority-strict-bandwidth, dcb
-
priority-traffic-class, dcb +
priority-traffic-class, dcb
-
private-key, 802-1x, wireguard +
private-key, 802-1x, wireguard
-
private-key-flags, wireguard +
private-key-flags, wireguard
-
private-key-password, 802-1x +
private-key-password, 802-1x
-
private-key-password-flags, 802-1x +
private-key-password-flags, 802-1x
-
promiscuous, macvlan +
promiscuous, macvlan
-
proto, 802-11-wireless-security +
proto, 802-11-wireless-security
-
protocol, adsl +
protocol, adsl
-
proxy, vxlan +
proxy, vxlan
-
psk, 802-11-wireless-security +
psk, 802-11-wireless-security
-
psk-flags, 802-11-wireless-security +
psk-flags, 802-11-wireless-security

Q

-
qdiscs, tc +
qdiscs, tc
-
queue-id, team-port +
queue-id, team-port

R

-
ra-timeout, ipv6 +
ra-timeout, ipv6
-
rate, 802-11-wireless +
rate, 802-11-wireless
-
read-only, connection +
read-only, connection
-
refuse-chap, ppp +
refuse-chap, ppp
-
refuse-eap, ppp +
refuse-eap, ppp
-
refuse-mschap, ppp +
refuse-mschap, ppp
-
refuse-mschapv2, ppp +
refuse-mschapv2, ppp
-
refuse-pap, ppp +
refuse-pap, ppp
-
remote, ip-tunnel, vxlan +
remote, ip-tunnel, vxlan
-
require-mppe, ppp +
require-mppe, ppp
-
require-mppe-128, ppp +
require-mppe-128, ppp
-
route-data, ipv4, ipv6 +
route-data, ipv4, ipv6
-
route-metric, ipv4, ipv6 +
route-metric, ipv4, ipv6
-
route-table, ipv4, ipv6 +
route-table, ipv4, ipv6
-
routes, ipv4, ipv6 +
routes, ipv4, ipv6
-
rsc, vxlan +
rsc, vxlan
-
rstp-enable, ovs-bridge +
rstp-enable, ovs-bridge
-
runner, team +
runner, team
-
runner-active, team +
runner-active, team
-
runner-agg-select-policy, team +
runner-agg-select-policy, team
-
runner-fast-rate, team +
runner-fast-rate, team
-
runner-hwaddr-policy, team +
runner-hwaddr-policy, team
-
runner-min-ports, team +
runner-min-ports, team
-
runner-sys-prio, team +
runner-sys-prio, team
-
runner-tx-balancer, team +
runner-tx-balancer, team
-
runner-tx-balancer-interval, team +
runner-tx-balancer-interval, team
-
runner-tx-hash, team +
runner-tx-hash, team

S

-
s390-nettype, 802-3-ethernet +
s390-nettype, 802-3-ethernet
-
s390-options, 802-3-ethernet +
s390-options, 802-3-ethernet
-
s390-subchannels, 802-3-ethernet +
s390-subchannels, 802-3-ethernet
-
secondaries, connection +
secondaries, connection
-
secrets, vpn +
secrets, vpn
-
security, 802-11-wireless +
security, 802-11-wireless
-
seen-bssids, 802-11-wireless +
seen-bssids, 802-11-wireless
-
send-delay, serial +
send-delay, serial
-
send-sci, macsec +
send-sci, macsec
-
service, pppoe +
service, pppoe
-
service-type, vpn +
service-type, vpn
-
short-address, wpan +
short-address, wpan
-
sim-id, gsm +
sim-id, gsm
-
sim-operator-id, gsm +
sim-operator-id, gsm
-
slave-type, connection +
slave-type, connection
-
source-port-max, vxlan +
source-port-max, vxlan
-
source-port-min, vxlan +
source-port-min, vxlan
-
speed, 802-3-ethernet +
speed, 802-3-ethernet
-
ssid, 802-11-olpc-mesh, 802-11-wireless +
ssid, 802-11-olpc-mesh, 802-11-wireless
-
stable-id, connection +
stable-id, connection
-
sticky, team-port +
sticky, team-port
-
stopbits, serial +
stopbits, serial
-
stp, bridge +
stp, bridge
-
stp-enable, ovs-bridge +
stp-enable, ovs-bridge
-
subject-match, 802-1x +
subject-match, 802-1x
-
system-ca-certs, 802-1x +
system-ca-certs, 802-1x

T

-
table, vrf +
table, vrf
-
tag, ovs-port +
tag, ovs-port
-
tap, macvlan +
tap, macvlan
-
tfilters, tc +
tfilters, tc
-
timeout, vpn +
timeout, vpn
-
timestamp, connection +
timestamp, connection
-
token, ipv6 +
token, ipv6
-
tos, ip-tunnel, vxlan +
tos, ip-tunnel, vxlan
-
total-vfs, sriov +
total-vfs, sriov
-
transport-mode, infiniband +
transport-mode, infiniband
-
ttl, ip-tunnel, vxlan +
ttl, ip-tunnel, vxlan
-
tx-power, 802-11-wireless +
tx-power, 802-11-wireless
-
type, connection, bluetooth, ovs-interface +
type, connection, bluetooth, ovs-interface

U

-
user-name, vpn +
user-name, vpn
-
username, adsl, cdma, gsm, pppoe +
username, adsl, cdma, gsm, pppoe
-
uuid, connection +
uuid, connection

V

-
validation, macsec +
validation, macsec
-
vci, adsl +
vci, adsl
-
vfs, sriov +
vfs, sriov
-
vlan-default-pvid, bridge +
vlan-default-pvid, bridge
-
vlan-filtering, bridge +
vlan-filtering, bridge
-
vlan-mode, ovs-port +
vlan-mode, ovs-port
-
vlan-protocol, bridge +
vlan-protocol, bridge
-
vlan-stats-enabled, bridge +
vlan-stats-enabled, bridge
-
vlans, bridge, bridge-port +
vlans, bridge, bridge-port
-
vnet-hdr, tun +
vnet-hdr, tun
-
vpi, adsl +
vpi, adsl
-
org.freedesktop.NetworkManager.VPN.Connection, org.freedesktop.NetworkManager.VPN.Connection +
org.freedesktop.NetworkManager.VPN.Connection, org.freedesktop.NetworkManager.VPN.Connection
-
org.freedesktop.NetworkManager.VPN.Connection::PropertiesChanged, The "PropertiesChanged" signal +
org.freedesktop.NetworkManager.VPN.Connection::PropertiesChanged, The "PropertiesChanged" signal
-
org.freedesktop.NetworkManager.VPN.Connection::VpnStateChanged, The "VpnStateChanged" signal +
org.freedesktop.NetworkManager.VPN.Connection::VpnStateChanged, The "VpnStateChanged" signal
-
org.freedesktop.NetworkManager.VPN.Connection:Banner, The "Banner" property +
org.freedesktop.NetworkManager.VPN.Connection:Banner, The "Banner" property
-
org.freedesktop.NetworkManager.VPN.Connection:VpnState, The "VpnState" property +
org.freedesktop.NetworkManager.VPN.Connection:VpnState, The "VpnState" property
-
org.freedesktop.NetworkManager.VPN.Plugin, org.freedesktop.NetworkManager.VPN.Plugin +
org.freedesktop.NetworkManager.VPN.Plugin, org.freedesktop.NetworkManager.VPN.Plugin
-
org.freedesktop.NetworkManager.VPN.Plugin.Connect(), The Connect() method +
org.freedesktop.NetworkManager.VPN.Plugin.Connect(), The Connect() method
-
org.freedesktop.NetworkManager.VPN.Plugin.ConnectInteractive(), The ConnectInteractive() method +
org.freedesktop.NetworkManager.VPN.Plugin.ConnectInteractive(), The ConnectInteractive() method
-
org.freedesktop.NetworkManager.VPN.Plugin.Disconnect(), The Disconnect() method +
org.freedesktop.NetworkManager.VPN.Plugin.Disconnect(), The Disconnect() method
-
org.freedesktop.NetworkManager.VPN.Plugin.NeedSecrets(), The NeedSecrets() method +
org.freedesktop.NetworkManager.VPN.Plugin.NeedSecrets(), The NeedSecrets() method
-
org.freedesktop.NetworkManager.VPN.Plugin.NewSecrets(), The NewSecrets() method +
org.freedesktop.NetworkManager.VPN.Plugin.NewSecrets(), The NewSecrets() method
-
org.freedesktop.NetworkManager.VPN.Plugin.SetConfig(), The SetConfig() method +
org.freedesktop.NetworkManager.VPN.Plugin.SetConfig(), The SetConfig() method
-
org.freedesktop.NetworkManager.VPN.Plugin.SetFailure(), The SetFailure() method +
org.freedesktop.NetworkManager.VPN.Plugin.SetFailure(), The SetFailure() method
-
org.freedesktop.NetworkManager.VPN.Plugin.SetIp4Config(), The SetIp4Config() method +
org.freedesktop.NetworkManager.VPN.Plugin.SetIp4Config(), The SetIp4Config() method
-
org.freedesktop.NetworkManager.VPN.Plugin.SetIp6Config(), The SetIp6Config() method +
org.freedesktop.NetworkManager.VPN.Plugin.SetIp6Config(), The SetIp6Config() method
-
org.freedesktop.NetworkManager.VPN.Plugin::Config, The "Config" signal +
org.freedesktop.NetworkManager.VPN.Plugin::Config, The "Config" signal
-
org.freedesktop.NetworkManager.VPN.Plugin::Failure, The "Failure" signal +
org.freedesktop.NetworkManager.VPN.Plugin::Failure, The "Failure" signal
-
org.freedesktop.NetworkManager.VPN.Plugin::Ip4Config, The "Ip4Config" signal +
org.freedesktop.NetworkManager.VPN.Plugin::Ip4Config, The "Ip4Config" signal
-
org.freedesktop.NetworkManager.VPN.Plugin::Ip6Config, The "Ip6Config" signal +
org.freedesktop.NetworkManager.VPN.Plugin::Ip6Config, The "Ip6Config" signal
-
org.freedesktop.NetworkManager.VPN.Plugin::LoginBanner, The "LoginBanner" signal +
org.freedesktop.NetworkManager.VPN.Plugin::LoginBanner, The "LoginBanner" signal
-
org.freedesktop.NetworkManager.VPN.Plugin::SecretsRequired, The "SecretsRequired" signal +
org.freedesktop.NetworkManager.VPN.Plugin::SecretsRequired, The "SecretsRequired" signal
-
org.freedesktop.NetworkManager.VPN.Plugin::StateChanged, The "StateChanged" signal +
org.freedesktop.NetworkManager.VPN.Plugin::StateChanged, The "StateChanged" signal
-
org.freedesktop.NetworkManager.VPN.Plugin:State, The "State" property +
org.freedesktop.NetworkManager.VPN.Plugin:State, The "State" property

W

-
wait-device-timeout, connection +
wait-device-timeout, connection
-
wake-on-lan, 802-3-ethernet +
wake-on-lan, 802-3-ethernet
-
wake-on-lan-password, 802-3-ethernet +
wake-on-lan-password, 802-3-ethernet
-
wake-on-wlan, 802-11-wireless +
wake-on-wlan, 802-11-wireless
-
wep-key-flags, 802-11-wireless-security +
wep-key-flags, 802-11-wireless-security
-
wep-key-type, 802-11-wireless-security +
wep-key-type, 802-11-wireless-security
-
wep-key0, 802-11-wireless-security +
wep-key0, 802-11-wireless-security
-
wep-key1, 802-11-wireless-security +
wep-key1, 802-11-wireless-security
-
wep-key2, 802-11-wireless-security +
wep-key2, 802-11-wireless-security
-
wep-key3, 802-11-wireless-security +
wep-key3, 802-11-wireless-security
-
wep-tx-keyidx, 802-11-wireless-security +
wep-tx-keyidx, 802-11-wireless-security
-
wfd-ies, wifi-p2p +
wfd-ies, wifi-p2p
-
org.freedesktop.NetworkManager.WifiP2PPeer, org.freedesktop.NetworkManager.WifiP2PPeer +
org.freedesktop.NetworkManager.WifiP2PPeer, org.freedesktop.NetworkManager.WifiP2PPeer
-
org.freedesktop.NetworkManager.WifiP2PPeer:Flags, The "Flags" property +
org.freedesktop.NetworkManager.WifiP2PPeer:Flags, The "Flags" property
-
org.freedesktop.NetworkManager.WifiP2PPeer:HwAddress, The "HwAddress" property +
org.freedesktop.NetworkManager.WifiP2PPeer:HwAddress, The "HwAddress" property
-
org.freedesktop.NetworkManager.WifiP2PPeer:LastSeen, The "LastSeen" property +
org.freedesktop.NetworkManager.WifiP2PPeer:LastSeen, The "LastSeen" property
-
org.freedesktop.NetworkManager.WifiP2PPeer:Manufacturer, The "Manufacturer" property +
org.freedesktop.NetworkManager.WifiP2PPeer:Manufacturer, The "Manufacturer" property
-
org.freedesktop.NetworkManager.WifiP2PPeer:Model, The "Model" property +
org.freedesktop.NetworkManager.WifiP2PPeer:Model, The "Model" property
-
org.freedesktop.NetworkManager.WifiP2PPeer:ModelNumber, The "ModelNumber" property +
org.freedesktop.NetworkManager.WifiP2PPeer:ModelNumber, The "ModelNumber" property
-
org.freedesktop.NetworkManager.WifiP2PPeer:Name, The "Name" property +
org.freedesktop.NetworkManager.WifiP2PPeer:Name, The "Name" property
-
org.freedesktop.NetworkManager.WifiP2PPeer:Serial, The "Serial" property +
org.freedesktop.NetworkManager.WifiP2PPeer:Serial, The "Serial" property
-
org.freedesktop.NetworkManager.WifiP2PPeer:Strength, The "Strength" property +
org.freedesktop.NetworkManager.WifiP2PPeer:Strength, The "Strength" property
-
org.freedesktop.NetworkManager.WifiP2PPeer:WfdIEs, The "WfdIEs" property +
org.freedesktop.NetworkManager.WifiP2PPeer:WfdIEs, The "WfdIEs" property
-
wps-method, wifi-p2p, 802-11-wireless-security +
wps-method, wifi-p2p, 802-11-wireless-security

Z

-
zone, connection +
zone, connection
+
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/license.html b/docs/api/html/license.html index e1b6848..45ca298 100644 --- a/docs/api/html/license.html +++ b/docs/api/html/license.html @@ -7,7 +7,7 @@ - + @@ -55,6 +55,6 @@

+
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/manpages.html b/docs/api/html/manpages.html index 64c083b..d12ec76 100644 --- a/docs/api/html/manpages.html +++ b/docs/api/html/manpages.html @@ -8,7 +8,7 @@ - + @@ -32,6 +32,9 @@ NetworkManager.conf — NetworkManager configuration file
+NetworkManager-dispatcher — Dispatch user scripts for NetworkManager +
+
nmcli — command-line tool for controlling NetworkManager
@@ -68,6 +71,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/nm-cloud-setup.html b/docs/api/html/nm-cloud-setup.html index 13bc2d7..9db3eb3 100644 --- a/docs/api/html/nm-cloud-setup.html +++ b/docs/api/html/nm-cloud-setup.html @@ -8,7 +8,7 @@ - + @@ -29,7 +29,7 @@
-

Overview

+

Overview

When running a virtual machine in a public cloud environment, it is desirable to automatically configure the network of that VM. In simple setups, the VM only has one network interface and the public @@ -44,7 +44,7 @@

Multiple cloud providers are supported. See the section called “Supported Cloud Providers”.

-

Use

+

Use

The goal of nm-cloud-setup is to be configuration-less and work automatically. All you need is to opt-in to the desired cloud providers (see the section called “Environment Variables”) and run /usr/libexec/nm-cloud-setup.

@@ -53,7 +53,7 @@ and a NetworkManager dispatcher script.

-

Details

+

Details

nm-cloud-setup configures the network by fetching the configuration from the well-known meta data server of the cloud provider. That means, it already @@ -74,7 +74,7 @@ With this approach, the configuration is not persisted and only preserved until the device disconnects.

-

/usr/libexec/nm-cloud-setup

+

/usr/libexec/nm-cloud-setup

The binary /usr/libexec/nm-cloud-setup does most of the work. It supports no command line arguments but can be configured via environment variables. @@ -94,7 +94,7 @@


-

nm-cloud-setup.service systemd unit

+

nm-cloud-setup.service systemd unit

Usually /usr/libexec/nm-cloud-setup is not run directly, but only by systemctl restart nm-cloud-setup.service. This ensures that the tool only runs once at any time. It also allows to integrate @@ -105,7 +105,7 @@


-

nm-cloud-setup.timer systemd timer

+

nm-cloud-setup.timer systemd timer

/usr/libexec/nm-cloud-setup is intended to run whenever an update is necessary. For example, during boot when when changing the network configuration of the virtual machine via the cloud @@ -115,7 +115,7 @@


-

/usr/lib/NetworkManager/dispatcher.d/90-nm-cloud-setup.sh

+

/usr/lib/NetworkManager/dispatcher.d/90-nm-cloud-setup.sh

There is also a NetworkManager dispatcher script that will run for example when an interface is activated by NetworkManager. Together with the nm-cloud-setup.timer systemd timer this @@ -149,7 +149,7 @@

Supported Cloud Providers

-

Amazon EC2 (AWS)

+

Amazon EC2 (AWS)

For AWS, the tools tries to fetch configuration from http://169.254.169.254/. Currently, it only configures IPv4 and does nothing about IPv6. It will do the following.

    @@ -192,7 +192,7 @@

-

Google Cloud Platform (GCP)

+

Google Cloud Platform (GCP)

For GCP, the meta data is fetched from URIs starting with http://metadata.google.internal/computeMetadata/v1/ with a HTTP header "Metadata-Flavor: Google". @@ -220,7 +220,7 @@


-

Microsoft Azure

+

Microsoft Azure

For Azure, the meta data is fetched from URIs starting with http://169.254.169.254/metadata/instance with a URL parameter "?format=text&api-version=2017-04-02" and a HTTP header "Metadata:true". @@ -256,7 +256,7 @@

-

See Also

+

See Also

NetworkManager(8) nmcli(1) @@ -264,6 +264,6 @@

+
Generated by GTK-Doc V1.33.0
\ No newline at end of file diff --git a/docs/api/html/nm-dbus-types.html b/docs/api/html/nm-dbus-types.html index ceff810..af1ee6c 100644 --- a/docs/api/html/nm-dbus-types.html +++ b/docs/api/html/nm-dbus-types.html @@ -8,7 +8,7 @@ - + @@ -5196,6 +5196,6 @@
+
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/nm-initrd-generator.html b/docs/api/html/nm-initrd-generator.html index 515ba4d..bef22dc 100644 --- a/docs/api/html/nm-initrd-generator.html +++ b/docs/api/html/nm-initrd-generator.html @@ -8,7 +8,7 @@ - + @@ -138,6 +138,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/nm-online.html b/docs/api/html/nm-online.html index ab6a6a6..84fef32 100644 --- a/docs/api/html/nm-online.html +++ b/docs/api/html/nm-online.html @@ -8,7 +8,7 @@ - + @@ -149,6 +149,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/nm-openvswitch.html b/docs/api/html/nm-openvswitch.html index 39878e9..3718e83 100644 --- a/docs/api/html/nm-openvswitch.html +++ b/docs/api/html/nm-openvswitch.html @@ -8,7 +8,7 @@ - + @@ -29,7 +29,7 @@
-

Overview

+

Overview

NetworkManager includes basic Open vSwitch support, good enough to be capable of setting up simple Open vSwitch configurations. It is not extensive and does not expose all functionality of Open vSwitch provides. @@ -64,7 +64,7 @@

-

Bridges

+

Bridges

Bridges are represented by connections of ovs-bridge type. Due to the limitations of OVSDB, "empty" Bridges (with no Ports) can't exist. @@ -74,7 +74,7 @@


-

Ports

+

Ports

Ports are represented by connections of ovs-port type. Due to the limitations of OVSDB, "empty" Ports (with no Interfaces) can't @@ -84,7 +84,7 @@


-

Interfaces

+

Interfaces

Interfaces are represented by a connections enslaved to a Port. The system interfaces (that have a corresponding Linux link) have a respective connection.type @@ -94,9 +94,9 @@

-

Examples

+

Examples

-

Example 18. Creating a Bridge with a single internal Interface

+

Example 18. Creating a Bridge with a single internal Interface

$ nmcli conn add type ovs-bridge conn.interface bridge0
 Connection 'ovs-bridge-bridge0' (d10fc64d-1d48-4394-a1b8-e1aea72f27d5) successfully added.
@@ -113,7 +113,7 @@ Connection 'ovs-interface-iface0' (3640d2a1-a2fd-4718-92f1-cffadb5b6cdc) success
 

-

Example 19. Adding a Linux interface to a Bridge

+

Example 19. Adding a Linux interface to a Bridge

$ nmcli conn add type ovs-port conn.interface port1 master bridge0
 Connection 'ovs-port-port1' (67d041eb-8e7b-4458-afee-a1d07c9c4552) successfully added.
@@ -124,7 +124,7 @@ Connection 'ovs-slave-eth0' (d459c45c-cf78-4c1c-b4b7-505e71379624) successfully 
 

-

Example 20. Creating a VLAN

+

Example 20. Creating a VLAN

$ nmcli conn add type ovs-port conn.interface port2 master bridge0 ovs-port.tag 120
 Connection 'ovs-port-port2' (3994c093-4ef7-4549-a4fd-627b831c3cb8) successfully added.
@@ -135,7 +135,7 @@ Connection 'ovs-slave-eth1' (099be06e-71ad-484d-8d5a-fcadc5f207f5) successfully 
 

-

Example 21. Creating a Bond

+

Example 21. Creating a Bond

$ nmcli conn add type ovs-port conn.interface bond0 master bridge0
 Connection 'ovs-port-bond0' (d154ebf9-e999-4e1b-a084-a3de53d25d8a) successfully added.
@@ -153,7 +153,7 @@ Connection 'ovs-slave-eth3' (8dedeecb-ed12-482b-b77a-24a4fb835136) successfully 
 
-

Bugs

+

Bugs

  • Not all Open vSwitch capabilities are supported.

  • Open vSwitch devices don't expose many useful properties on D-Bus.

  • @@ -161,7 +161,7 @@ Connection 'ovs-slave-eth3' (8dedeecb-ed12-482b-b77a-24a4fb835136) successfully

    Probably many more.

-

See Also

+

See Also

RFC 7047: The Open vSwitch Database Management Protocol, ovs-vsctl(8), @@ -172,6 +172,6 @@ Connection 'ovs-slave-eth3' (8dedeecb-ed12-482b-b77a-24a4fb835136) successfully

+
Generated by GTK-Doc V1.33.0
\ No newline at end of file diff --git a/docs/api/html/nm-settings-dbus.html b/docs/api/html/nm-settings-dbus.html index 85f77f2..88901da 100644 --- a/docs/api/html/nm-settings-dbus.html +++ b/docs/api/html/nm-settings-dbus.html @@ -8,7 +8,7 @@ - + @@ -94,7 +94,7 @@
-

connection setting

+

connection setting

General Connection Profile Settings.

@@ -290,7 +290,7 @@
-

6lowpan setting

+

6lowpan setting

6LoWPAN Settings.

@@ -316,7 +316,7 @@
-

802-1x setting

+

802-1x setting

IEEE 802.1x Authentication Settings.

@@ -666,7 +666,7 @@
-

adsl setting

+

adsl setting

ADSL Settings.

@@ -736,7 +736,7 @@
-

bluetooth setting

+

bluetooth setting

Bluetooth Settings.

@@ -771,7 +771,7 @@
-

bond setting

+

bond setting

Bonding Settings.

@@ -806,7 +806,7 @@
-

bridge setting

+

bridge setting

Bridging Settings.

@@ -1023,7 +1023,7 @@
-

bridge-port setting

+

bridge-port setting

Bridge Port Settings.

@@ -1072,7 +1072,7 @@
-

cdma setting

+

cdma setting

CDMA-based Mobile Broadband Settings.

@@ -1128,7 +1128,7 @@
-

dcb setting

+

dcb setting

Data Center Bridging Settings.

@@ -1254,7 +1254,7 @@
-

dummy setting

+

dummy setting

Dummy Link Settings.

@@ -1274,7 +1274,7 @@
-

ethtool setting

+

ethtool setting

Ethtool Ethernet Settings.

@@ -1294,7 +1294,7 @@
-

generic setting

+

generic setting

Generic Link Settings.

@@ -1314,7 +1314,7 @@
-

gsm setting

+

gsm setting

GSM-based Mobile Broadband Settings.

@@ -1433,7 +1433,7 @@
-

infiniband setting

+

infiniband setting

Infiniband Settings.

@@ -1489,7 +1489,7 @@
-

ipv4 setting

+

ipv4 setting

IPv4 Settings.

@@ -1692,7 +1692,7 @@
-

ipv6 setting

+

ipv6 setting

IPv6 Settings.

@@ -1909,7 +1909,7 @@
-

ip-tunnel setting

+

ip-tunnel setting

IP Tunneling Settings.

@@ -2021,7 +2021,7 @@
-

macsec setting

+

macsec setting

MACSec Settings.

@@ -2105,7 +2105,7 @@
-

macvlan setting

+

macvlan setting

MAC VLAN Settings.

@@ -2154,7 +2154,7 @@
-

match setting

+

match setting

Match settings.

@@ -2189,7 +2189,7 @@ kernel-command-line - + - + @@ -84,6 +84,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ovs-bridge.html b/docs/api/html/settings-ovs-bridge.html index a30bc7e..29239f4 100644 --- a/docs/api/html/settings-ovs-bridge.html +++ b/docs/api/html/settings-ovs-bridge.html @@ -8,7 +8,7 @@ - + @@ -90,6 +90,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ovs-dpdk.html b/docs/api/html/settings-ovs-dpdk.html index 00c5882..a40d5fd 100644 --- a/docs/api/html/settings-ovs-dpdk.html +++ b/docs/api/html/settings-ovs-dpdk.html @@ -8,7 +8,7 @@ - + @@ -64,6 +64,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ovs-external-ids.html b/docs/api/html/settings-ovs-external-ids.html index feaafcb..0ec0c4e 100644 --- a/docs/api/html/settings-ovs-external-ids.html +++ b/docs/api/html/settings-ovs-external-ids.html @@ -8,7 +8,7 @@ - + @@ -64,6 +64,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ovs-interface.html b/docs/api/html/settings-ovs-interface.html index 8c842ab..71aff77 100644 --- a/docs/api/html/settings-ovs-interface.html +++ b/docs/api/html/settings-ovs-interface.html @@ -8,7 +8,7 @@ - + @@ -64,6 +64,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ovs-patch.html b/docs/api/html/settings-ovs-patch.html index 3dddfa9..9fb817b 100644 --- a/docs/api/html/settings-ovs-patch.html +++ b/docs/api/html/settings-ovs-patch.html @@ -8,7 +8,7 @@ - + @@ -64,6 +64,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ovs-port.html b/docs/api/html/settings-ovs-port.html index 7eac441..56f4583 100644 --- a/docs/api/html/settings-ovs-port.html +++ b/docs/api/html/settings-ovs-port.html @@ -8,7 +8,7 @@ - + @@ -96,6 +96,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ppp.html b/docs/api/html/settings-ppp.html index 30b845b..faff1d8 100644 --- a/docs/api/html/settings-ppp.html +++ b/docs/api/html/settings-ppp.html @@ -8,7 +8,7 @@ - + @@ -168,6 +168,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-pppoe.html b/docs/api/html/settings-pppoe.html index f8ba530..339e0aa 100644 --- a/docs/api/html/settings-pppoe.html +++ b/docs/api/html/settings-pppoe.html @@ -8,7 +8,7 @@ - + @@ -90,6 +90,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-proxy.html b/docs/api/html/settings-proxy.html index cb591d1..3cfe06f 100644 --- a/docs/api/html/settings-proxy.html +++ b/docs/api/html/settings-proxy.html @@ -8,7 +8,7 @@ - + @@ -84,6 +84,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-serial.html b/docs/api/html/settings-serial.html index 50f3877..5caaa48 100644 --- a/docs/api/html/settings-serial.html +++ b/docs/api/html/settings-serial.html @@ -8,7 +8,7 @@ - + @@ -90,6 +90,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-sriov.html b/docs/api/html/settings-sriov.html index 34dc54b..0317c77 100644 --- a/docs/api/html/settings-sriov.html +++ b/docs/api/html/settings-sriov.html @@ -8,7 +8,7 @@ - + @@ -78,6 +78,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-tc.html b/docs/api/html/settings-tc.html index e57f62a..1edc8ed 100644 --- a/docs/api/html/settings-tc.html +++ b/docs/api/html/settings-tc.html @@ -8,7 +8,7 @@ - + @@ -72,6 +72,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-team-port.html b/docs/api/html/settings-team-port.html index 0bc1023..e493d42 100644 --- a/docs/api/html/settings-team-port.html +++ b/docs/api/html/settings-team-port.html @@ -8,7 +8,7 @@ - + @@ -102,6 +102,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-team.html b/docs/api/html/settings-team.html index 3b9e94b..c4ae06b 100644 --- a/docs/api/html/settings-team.html +++ b/docs/api/html/settings-team.html @@ -8,7 +8,7 @@ - + @@ -162,6 +162,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-tun.html b/docs/api/html/settings-tun.html index 1b4cfd6..20af929 100644 --- a/docs/api/html/settings-tun.html +++ b/docs/api/html/settings-tun.html @@ -8,7 +8,7 @@ - + @@ -96,6 +96,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-user.html b/docs/api/html/settings-user.html index 39d7be2..a00fac4 100644 --- a/docs/api/html/settings-user.html +++ b/docs/api/html/settings-user.html @@ -8,7 +8,7 @@ - + @@ -64,6 +64,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-veth.html b/docs/api/html/settings-veth.html index f0f7c5a..761b4f7 100644 --- a/docs/api/html/settings-veth.html +++ b/docs/api/html/settings-veth.html @@ -8,7 +8,7 @@ - + @@ -64,6 +64,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-vlan.html b/docs/api/html/settings-vlan.html index 82296a4..33787e8 100644 --- a/docs/api/html/settings-vlan.html +++ b/docs/api/html/settings-vlan.html @@ -8,7 +8,7 @@ - + @@ -96,6 +96,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-vpn.html b/docs/api/html/settings-vpn.html index bad0a84..db05951 100644 --- a/docs/api/html/settings-vpn.html +++ b/docs/api/html/settings-vpn.html @@ -8,7 +8,7 @@ - + @@ -96,6 +96,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-vrf.html b/docs/api/html/settings-vrf.html index f909e88..839bf8c 100644 --- a/docs/api/html/settings-vrf.html +++ b/docs/api/html/settings-vrf.html @@ -8,7 +8,7 @@ - + @@ -64,6 +64,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-vxlan.html b/docs/api/html/settings-vxlan.html index 9195620..6da8eb5 100644 --- a/docs/api/html/settings-vxlan.html +++ b/docs/api/html/settings-vxlan.html @@ -8,7 +8,7 @@ - + @@ -156,6 +156,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-wifi-p2p.html b/docs/api/html/settings-wifi-p2p.html index e1a0578..dc9c259 100644 --- a/docs/api/html/settings-wifi-p2p.html +++ b/docs/api/html/settings-wifi-p2p.html @@ -8,7 +8,7 @@ - + @@ -78,6 +78,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-wimax.html b/docs/api/html/settings-wimax.html index 993ca96..ee0f111 100644 --- a/docs/api/html/settings-wimax.html +++ b/docs/api/html/settings-wimax.html @@ -8,7 +8,7 @@ - + @@ -72,6 +72,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-wireguard.html b/docs/api/html/settings-wireguard.html index 01f20f6..e632ffd 100644 --- a/docs/api/html/settings-wireguard.html +++ b/docs/api/html/settings-wireguard.html @@ -8,7 +8,7 @@ - + @@ -114,6 +114,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-wpan.html b/docs/api/html/settings-wpan.html index 6475e04..6fdbaa2 100644 --- a/docs/api/html/settings-wpan.html +++ b/docs/api/html/settings-wpan.html @@ -8,7 +8,7 @@ - + @@ -90,6 +90,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/spec.html b/docs/api/html/spec.html index 05d19ae..4138e61 100644 --- a/docs/api/html/spec.html +++ b/docs/api/html/spec.html @@ -8,7 +8,7 @@ - + @@ -190,6 +190,6 @@

+
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/vpn-plugins.html b/docs/api/html/vpn-plugins.html index f38251c..76cfc09 100644 --- a/docs/api/html/vpn-plugins.html +++ b/docs/api/html/vpn-plugins.html @@ -8,7 +8,7 @@ - + @@ -37,6 +37,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/network-manager-docs.xml b/docs/api/network-manager-docs.xml index 7a57582..a2fc76d 100644 --- a/docs/api/network-manager-docs.xml +++ b/docs/api/network-manager-docs.xml @@ -70,6 +70,7 @@ Manual Pages + @@ -265,7 +266,7 @@ Types - + @@ -289,7 +290,7 @@ Types - + diff --git a/docs/api/settings-spec.xml b/docs/api/settings-spec.xml index c615558..4b1240e 100644 --- a/docs/api/settings-spec.xml +++ b/docs/api/settings-spec.xml @@ -42,7 +42,7 @@ Properties
array of string  A list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or if prefixed with the exclamation mark unset). The argument must either be a single word, or an assignment (i.e. two words, separated "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.A list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or unset, if prefixed with the exclamation mark). The argument must either be a single word, or an assignment (i.e. two words, joined by "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. Wildcard patterns are not supported. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the match.
@@ -2203,7 +2203,7 @@
-

802-11-olpc-mesh setting

+

802-11-olpc-mesh setting

OLPC Wireless Mesh Settings.

@@ -2245,7 +2245,7 @@
-

ovs-bridge setting

+

ovs-bridge setting

OvsBridge Link Settings.

@@ -2301,7 +2301,7 @@
-

ovs-dpdk setting

+

ovs-dpdk setting

OvsDpdk Link Settings.

@@ -2327,7 +2327,7 @@
-

ovs-interface setting

+

ovs-interface setting

Open vSwitch Interface Settings.

@@ -2353,7 +2353,7 @@
-

ovs-patch setting

+

ovs-patch setting

OvsPatch Link Settings.

@@ -2379,7 +2379,7 @@
-

ovs-port setting

+

ovs-port setting

OvsPort Link Settings.

@@ -2442,7 +2442,7 @@
-

ppp setting

+

ppp setting

Point-to-Point Protocol Settings.

@@ -2589,7 +2589,7 @@
-

pppoe setting

+

pppoe setting

PPP-over-Ethernet Settings.

@@ -2645,7 +2645,7 @@
-

proxy setting

+

proxy setting

WWW Proxy Settings.

@@ -2694,7 +2694,7 @@
-

serial setting

+

serial setting

Serial Link Settings.

@@ -2750,7 +2750,7 @@
-

sriov setting

+

sriov setting

SR-IOV settings.

@@ -2792,7 +2792,7 @@
-

tc setting

+

tc setting

Linux Traffic Control Settings.

@@ -2827,7 +2827,7 @@
-

team setting

+

team setting

Teaming Settings.

@@ -2967,7 +2967,7 @@
-

team-port setting

+

team-port setting

Team Port Settings.

@@ -3037,7 +3037,7 @@
-

tun setting

+

tun setting

Tunnel Settings.

@@ -3100,7 +3100,7 @@
-

user setting

+

user setting

General User Profile Settings.

@@ -3126,7 +3126,7 @@
-

vlan setting

+

vlan setting

VLAN Settings.

@@ -3189,7 +3189,7 @@
-

vpn setting

+

vpn setting

VPN Settings.

@@ -3252,7 +3252,7 @@
-

vrf setting

+

vrf setting

VRF settings.

@@ -3278,7 +3278,7 @@
-

vxlan setting

+

vxlan setting

VXLAN Settings.

@@ -3411,7 +3411,7 @@
-

wifi-p2p setting

+

wifi-p2p setting

Wi-Fi P2P Settings.

@@ -3453,7 +3453,7 @@
-

wimax setting

+

wimax setting

WiMax Settings.

@@ -3488,7 +3488,7 @@
-

802-3-ethernet setting

+

802-3-ethernet setting

Wired Ethernet Settings.

@@ -3614,7 +3614,7 @@
-

wireguard setting

+

wireguard setting

WireGuard Settings.

@@ -3698,7 +3698,7 @@
-

802-11-wireless setting

+

802-11-wireless setting

Wi-Fi Settings.

@@ -3859,7 +3859,7 @@
-

802-11-wireless-security setting

+

802-11-wireless-security setting

Wi-Fi Security Settings.

@@ -4020,7 +4020,7 @@
-

wpan setting

+

wpan setting

IEEE 802.15.4 (WPAN) MAC Settings.

@@ -4076,7 +4076,7 @@
-

hostname setting

+

hostname setting

Hostname settings.

@@ -4125,7 +4125,7 @@
-

ovs-external-ids setting

+

ovs-external-ids setting

OVS External IDs Settings.

@@ -4151,7 +4151,7 @@
-

veth setting

+

veth setting

Veth Settings.

@@ -4215,6 +4215,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/nm-settings-ifcfg-rh.html b/docs/api/html/nm-settings-ifcfg-rh.html index 8b57a58..b16f21f 100644 --- a/docs/api/html/nm-settings-ifcfg-rh.html +++ b/docs/api/html/nm-settings-ifcfg-rh.html @@ -8,7 +8,7 @@ - + @@ -209,10 +209,10 @@ DEVICETYPE=TeamPort

- + @@ -251,7 +256,7 @@ DEVICETYPE=TeamPort are NetworkManager specific extensions not understood by traditional initscripts.

-

Table 11. 6lowpan setting

+

Table 11. 6lowpan setting

Semantic change of variables

Semantic change of variables and differences

- NetworkManager had to slightly change the semantic for a few variables. + NetworkManager changes the semantics for a few variables and there are other behavioral differences.

  • PEERDNS - @@ -234,6 +234,11 @@ DEVICETYPE=TeamPort

  • HWADDR - initscripts compare the currently set hardware address of a device, while NetworkManager considers the permanent one.

  • +
  • NOZEROCONF - + initscripts add an on-link route to 169.254.0.0/16 for ethernet profiles that don't + explicitly opt-out by setting NOZEROCONF variable. NetworkManager does + not do that. Instead a static, manual route with scope=253 (link) should be added to get + that behavior.

@@ -269,7 +274,7 @@ DEVICETYPE=TeamPort

-

Table 12. 802-1x setting

+

Table 12. 802-1x setting

@@ -597,7 +602,7 @@ Example: IEEE_8021X_PRIVATE_KEY=/home/joe/mykey.p12

-

Table 13. bond setting

+

Table 13. bond setting

@@ -622,7 +627,7 @@ Example: BONDING_OPTS="miimon=100 mode=broadcast"

-

Table 14. bridge-port setting

+

Table 14. bridge-port setting

@@ -671,7 +676,7 @@ Example: BRIDGE_PORT_VLANS="1 pvid untagged,20,300-400 untagged"

-

Table 15. bridge setting

+

Table 15. bridge setting

@@ -910,7 +915,7 @@ Example: BRIDGING_OPTS="multicast_startup_query_interval=4000"
-

Table 16. connection setting

+

Table 16. connection setting

@@ -1128,7 +1133,7 @@ Allowed values: a valid URL that points to recommended policy fo

-

Table 17. dcb setting

+

Table 17. dcb setting

@@ -1263,7 +1268,7 @@ Example: DCB_PG_UP2TC=01623701 used explicitly to enable DCB so that the rest of the DCB_* variables can apply.

-

Table 18. ethtool setting

+

Table 18. ethtool setting

@@ -1281,7 +1286,7 @@ Example: DCB_PG_UP2TC=01623701

-

Table 19. hostname setting

+

Table 19. hostname setting

@@ -1336,7 +1341,7 @@ Example: HOSTNAME_ONLY_FROM_DEFAULT=0,1

-

Table 20. infiniband setting

+

Table 20. infiniband setting

@@ -1391,7 +1396,7 @@ Example: PHYSDEV=ib0

-

Table 21. ipv4 setting

+

Table 21. ipv4 setting

@@ -1568,7 +1573,7 @@ Example: DHCP_VENDOR_CLASS_IDENTIFIER=foo

-

Table 22. ipv6 setting

+

Table 22. ipv6 setting

@@ -1751,7 +1756,7 @@ Example: DHCPV6_DUID=LL; DHCPV6_DUID=0301deadbeef0001; DHCPV6_DU

-

Table 23. match setting

+

Table 23. match setting

@@ -1776,7 +1781,7 @@ Example: MATCH_PATH="pci-0000:01:00.0 pci-0000:0c:00.0"

-

Table 24. ovs-bridge setting

+

Table 24. ovs-bridge setting

@@ -1794,7 +1799,7 @@ Example: MATCH_PATH="pci-0000:01:00.0 pci-0000:0c:00.0"

-

Table 25. ovs-dpdk setting

+

Table 25. ovs-dpdk setting

@@ -1812,7 +1817,7 @@ Example: MATCH_PATH="pci-0000:01:00.0 pci-0000:0c:00.0"

-

Table 26. ovs-external-ids setting

+

Table 26. ovs-external-ids setting

@@ -1830,7 +1835,7 @@ Example: MATCH_PATH="pci-0000:01:00.0 pci-0000:0c:00.0"

-

Table 27. ovs-interface setting

+

Table 27. ovs-interface setting

@@ -1848,7 +1853,7 @@ Example: MATCH_PATH="pci-0000:01:00.0 pci-0000:0c:00.0"

-

Table 28. ovs-patch setting

+

Table 28. ovs-patch setting

@@ -1866,7 +1871,7 @@ Example: MATCH_PATH="pci-0000:01:00.0 pci-0000:0c:00.0"

-

Table 29. ovs-port setting

+

Table 29. ovs-port setting

@@ -1884,7 +1889,7 @@ Example: MATCH_PATH="pci-0000:01:00.0 pci-0000:0c:00.0"

-

Table 30. proxy setting

+

Table 30. proxy setting

@@ -1937,7 +1942,7 @@ Example: PAC_SCRIPT=/home/joe/proxy.pac

-

Table 31. sriov setting

+

Table 31. sriov setting

@@ -1982,7 +1987,7 @@ Example: SRIOV_AUTOPROBE_DRIVERS=0,1

-

Table 32. tc setting

+

Table 32. tc setting

@@ -2017,7 +2022,7 @@ Example: FILTER1="parent ffff: matchall action simple sdata Inpu

-

Table 33. team-port setting

+

Table 33. team-port setting

@@ -2040,7 +2045,7 @@ Example: FILTER1="parent ffff: matchall action simple sdata Inpu

-

Table 34. team setting

+

Table 34. team setting

@@ -2063,7 +2068,7 @@ Example: FILTER1="parent ffff: matchall action simple sdata Inpu

-

Table 35. user setting

+

Table 35. user setting

@@ -2088,7 +2093,7 @@ Example: NM_USER_FOO__BAR=something

-

Table 36. veth setting

+

Table 36. veth setting

@@ -2106,7 +2111,7 @@ Example: NM_USER_FOO__BAR=something

-

Table 37. vlan setting

+

Table 37. vlan setting

@@ -2169,7 +2174,7 @@ Example: PHYSDEV=eth0, VLAN_ID=12; or DEVICE=eth0.12

-

Table 38. vrf setting

+

Table 38. vrf setting

@@ -2187,7 +2192,7 @@ Example: PHYSDEV=eth0, VLAN_ID=12; or DEVICE=eth0.12

-

Table 39. wifi-p2p setting

+

Table 39. wifi-p2p setting

@@ -2205,7 +2210,7 @@ Example: PHYSDEV=eth0, VLAN_ID=12; or DEVICE=eth0.12

-

Table 40. 802-3-ethernet setting

+

Table 40. 802-3-ethernet setting

@@ -2302,11 +2307,25 @@ Allowed values: "qeth", "lcs" or "ctc" + + + + + + + + + + + +
  S390 device options. All options go to OPTIONS, except for "portname" and "ctcprot" that have their own variables.
wake-on-lanETHTOOL_OPTS, ETHTOOL_WAKE_ON_LAN Wake on Lan mode for ethernet. The setting "ignore" is expressed with "ETHTOOL_WAKE_ON_LAN=ignore". Otherwise, the "ETHTOOL_OPTS" variable is set with the value "wol" and several of the characters "p|u|m|b|a|g|s|f|d" as explained in the ethtool manual page.
wake-on-lan-passwordETHTOOL_OPTS Password for secure-on based Wake-on-Lan. It is added as "sopass" parameter in the ETHTOOL_OPTS variable. + +Example: ETHTOOL_OPTS="wol gs sopass 00:11:22:33:44:55"

-

Table 41. wireguard setting

+

Table 41. wireguard setting

@@ -2324,7 +2343,7 @@ Allowed values: "qeth", "lcs" or "ctc"

-

Table 42. 802-11-wireless-security setting

+

Table 42. 802-11-wireless-security setting

@@ -2506,7 +2525,7 @@ Allowed values: default, disable, optional, required

-

Table 43. 802-11-wireless setting

+

Table 43. 802-11-wireless setting

@@ -2663,7 +2682,7 @@ Allowed values: "yes", "no"

-

Table 44. wpan setting

+

Table 44. wpan setting

@@ -2722,6 +2741,6 @@ Allowed values: "yes", "no" +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/nm-settings-keyfile.html b/docs/api/html/nm-settings-keyfile.html index d635adf..67754ad 100644 --- a/docs/api/html/nm-settings-keyfile.html +++ b/docs/api/html/nm-settings-keyfile.html @@ -8,7 +8,7 @@ - + @@ -189,7 +189,7 @@ id=4
802-11-wireless-security = wifi-security
-

Table 1. bridge setting (section)

+

Table 1. bridge setting (section)

@@ -214,7 +214,7 @@ Example: mac-address=00:22:68:12:79:A2 mac-address=0;34;104;18;1

-

Table 2. infiniband setting (section)

+

Table 2. infiniband setting (section)

@@ -239,7 +239,7 @@ Example: mac-address= 80:00:00:6d:fe:80:00:00:00:00:00:00:00:02:

-

Table 3. ipv4 setting (section)

+

Table 3. ipv4 setting (section)

@@ -290,7 +290,7 @@ Example: route1=8.8.8.0/24,10.1.1.1,77 route2=7.7.0.0/16

-

Table 4. ipv6 setting (section)

+

Table 4. ipv6 setting (section)

@@ -341,7 +341,7 @@ Example: route1=2001:4860:4860::/64,2620:52:0:2219:222:68ff:fe11

-

Table 5. serial setting (section)

+

Table 5. serial setting (section)

@@ -366,7 +366,7 @@ Example: parity=n

-

Table 6. vpn setting (section)

+

Table 6. vpn setting (section)

@@ -401,7 +401,7 @@ Example: password=Popocatepetl

-

Table 7. wifi-p2p setting (section)

+

Table 7. wifi-p2p setting (section)

@@ -424,7 +424,7 @@ Example: password=Popocatepetl

-

Table 8. 802-3-ethernet setting (section)

+

Table 8. 802-3-ethernet setting (section)

@@ -463,7 +463,7 @@ Example: mac-address-blacklist= 00:22:68:12:79:A6;00:22:68:12:79

-

Table 9. 802-11-wireless setting (section)

+

Table 9. 802-11-wireless setting (section)

@@ -510,7 +510,7 @@ Example: mac-address-blacklist= 00:22:68:12:79:A6;00:22:68:12:79

-

Table 10. wpan setting (section)

+

Table 10. wpan setting (section)

@@ -567,6 +567,6 @@ Example: mac-address-blacklist= 00:22:68:12:79:A6;00:22:68:12:79 +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/nm-settings-nmcli.html b/docs/api/html/nm-settings-nmcli.html index e59968a..f8bc105 100644 --- a/docs/api/html/nm-settings-nmcli.html +++ b/docs/api/html/nm-settings-nmcli.html @@ -8,7 +8,7 @@ - + @@ -67,7 +67,7 @@ property.

-

connection setting

+

connection setting

General Connection Profile Settings.

Properties: @@ -295,7 +295,7 @@


-

6lowpan setting

+

6lowpan setting

6LoWPAN Settings.

Properties: @@ -319,7 +319,7 @@


-

802-1x setting

+

802-1x setting

IEEE 802.1x Authentication Settings.

Properties: @@ -729,7 +729,7 @@


-

adsl setting

+

adsl setting

ADSL Settings.

Properties: @@ -811,7 +811,7 @@


-

bluetooth setting

+

bluetooth setting

Bluetooth Settings.

Properties: @@ -847,7 +847,7 @@


-

bond setting

+

bond setting

Bonding Settings.

Properties: @@ -869,7 +869,7 @@


-

bridge setting

+

bridge setting

Bridging Settings.

Properties: @@ -1119,7 +1119,7 @@


-

bridge-port setting

+

bridge-port setting

Bridge Port Settings.

Properties: @@ -1173,7 +1173,7 @@


-

cdma setting

+

cdma setting

CDMA-based Mobile Broadband Settings.

Properties: @@ -1235,7 +1235,7 @@


-

dcb setting

+

dcb setting

Data Center Bridging Settings.

Properties: @@ -1371,7 +1371,7 @@


-

ethtool setting

+

ethtool setting

Ethtool Ethernet Settings.

Properties: @@ -1723,7 +1723,7 @@


-

gsm setting

+

gsm setting

GSM-based Mobile Broadband Settings.

Properties: @@ -1861,7 +1861,7 @@


-

infiniband setting

+

infiniband setting

Infiniband Settings.

Properties: @@ -1927,7 +1927,7 @@


-

ipv4 setting

+

ipv4 setting

IPv4 Settings.

Properties: @@ -1943,9 +1943,9 @@

@@ -2129,9 +2129,9 @@ @@ -2143,7 +2143,7 @@
-

ipv6 setting

+

ipv6 setting

IPv6 Settings.

Properties: @@ -2359,7 +2359,7 @@


-

ip-tunnel setting

+

ip-tunnel setting

IP Tunneling Settings.

Properties: @@ -2487,7 +2487,7 @@


-

macsec setting

+

macsec setting

MACSec Settings.

Properties: @@ -2589,7 +2589,7 @@


-

macvlan setting

+

macvlan setting

MAC VLAN Settings.

Properties: @@ -2643,7 +2643,7 @@


-

match setting

+

match setting

Match settings.

Properties: @@ -2673,7 +2673,7 @@

@@ -2691,7 +2691,7 @@
-

802-11-olpc-mesh setting

+

802-11-olpc-mesh setting

Alias: olpc-mesh

OLPC Wireless Mesh Settings.

@@ -2739,7 +2739,7 @@

-

ovs-bridge setting

+

ovs-bridge setting

OvsBridge Link Settings.

Properties: @@ -2795,7 +2795,7 @@


-

ovs-dpdk setting

+

ovs-dpdk setting

OvsDpdk Link Settings.

Properties: @@ -2817,7 +2817,7 @@


-

ovs-interface setting

+

ovs-interface setting

Open vSwitch Interface Settings.

Properties: @@ -2839,7 +2839,7 @@


-

ovs-patch setting

+

ovs-patch setting

OvsPatch Link Settings.

Properties: @@ -2861,7 +2861,7 @@


-

ovs-port setting

+

ovs-port setting

OvsPort Link Settings.

Properties: @@ -2925,7 +2925,7 @@


-

ppp setting

+

ppp setting

Point-to-Point Protocol Settings.

Properties: @@ -3085,7 +3085,7 @@


-

pppoe setting

+

pppoe setting

PPP-over-Ethernet Settings.

Properties: @@ -3151,7 +3151,7 @@


-

proxy setting

+

proxy setting

WWW Proxy Settings.

Properties: @@ -3207,7 +3207,7 @@


-

serial setting

+

serial setting

Serial Link Settings.

Properties: @@ -3263,7 +3263,7 @@


-

sriov setting

+

sriov setting

SR-IOV settings.

Properties: @@ -3303,7 +3303,7 @@


-

tc setting

+

tc setting

Linux Traffic Control Settings.

Properties: @@ -3335,7 +3335,7 @@


-

team setting

+

team setting

Teaming Settings.

Properties: @@ -3481,7 +3481,7 @@


-

team-port setting

+

team-port setting

Team Port Settings.

Properties: @@ -3555,7 +3555,7 @@


-

tun setting

+

tun setting

Tunnel Settings.

Properties: @@ -3631,7 +3631,7 @@


-

vlan setting

+

vlan setting

VLAN Settings.

Properties: @@ -3697,7 +3697,7 @@


-

vpn setting

+

vpn setting

VPN Settings.

Properties: @@ -3765,7 +3765,7 @@


-

vrf setting

+

vrf setting

VRF settings.

Properties: @@ -3789,7 +3789,7 @@


-

vxlan setting

+

vxlan setting

VXLAN Settings.

Properties: @@ -3947,7 +3947,7 @@


-

wifi-p2p setting

+

wifi-p2p setting

Wi-Fi P2P Settings.

Properties: @@ -3989,7 +3989,7 @@


-

wimax setting

+

wimax setting

WiMax Settings.

Properties: @@ -4025,7 +4025,7 @@


-

802-3-ethernet setting

+

802-3-ethernet setting

Alias: ethernet

Wired Ethernet Settings.

@@ -4161,7 +4161,7 @@

-

wireguard setting

+

wireguard setting

WireGuard Settings.

Properties: @@ -4243,7 +4243,7 @@


-

802-11-wireless setting

+

802-11-wireless setting

Alias: wifi

Wi-Fi Settings.

@@ -4415,7 +4415,7 @@

-

802-11-wireless-security setting

+

802-11-wireless-security setting

Alias: wifi-sec

Wi-Fi Security Settings.

@@ -4599,7 +4599,7 @@

-

wpan setting

+

wpan setting

IEEE 802.15.4 (WPAN) MAC Settings.

Properties: @@ -4665,7 +4665,7 @@


-

hostname setting

+

hostname setting

Hostname settings.

Properties: @@ -4713,7 +4713,7 @@


-

veth setting

+

veth setting

Veth Settings.

Properties: @@ -4775,6 +4775,6 @@

+
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/nm-vpn-dbus-types.html b/docs/api/html/nm-vpn-dbus-types.html index 31c1d32..7673b32 100644 --- a/docs/api/html/nm-vpn-dbus-types.html +++ b/docs/api/html/nm-vpn-dbus-types.html @@ -8,7 +8,7 @@ - + @@ -555,6 +555,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/nmcli-examples.html b/docs/api/html/nmcli-examples.html index 8b15995..1ea0c02 100644 --- a/docs/api/html/nmcli-examples.html +++ b/docs/api/html/nmcli-examples.html @@ -8,7 +8,7 @@ - + @@ -33,7 +33,7 @@

nmcli [OPTIONS...]

-

Description

+

Description

nmcli is a command-line client for NetworkManager. It allows controlling NetworkManager and reporting its status. For more information @@ -46,9 +46,9 @@

-

Examples

+

Examples

-

Example 1. Listing available Wi-Fi APs

+

Example 1. Listing available Wi-Fi APs

$ nmcli device wifi list
 *  SSID               MODE    CHAN  RATE       SIGNAL  BARS  SECURITY
@@ -71,14 +71,14 @@
 

-

Example 2. Connect to a password-protected wifi network

+

Example 2. Connect to a password-protected wifi network

$ nmcli device wifi connect "$SSID" password "$PASSWORD"
$ nmcli --ask device wifi connect "$SSID"

-

Example 3. Showing general information and properties for a Wi-Fi interface

+

Example 3. Showing general information and properties for a Wi-Fi interface

$ nmcli -p -f general,wifi-properties device show wlan0
 ===========================================================================
@@ -120,7 +120,7 @@ WIFI-PROPERTIES.ADHOC:    yes
 

-

Example 4. Listing NetworkManager polkit permissions

+

Example 4. Listing NetworkManager polkit permissions

$ nmcli general permissions
 PERMISSION                                                VALUE
@@ -153,7 +153,7 @@ org.freedesktop.NetworkManager.reload                     auth

-

Example 5. Listing NetworkManager log level and domains

+

Example 5. Listing NetworkManager log level and domains

$ nmcli general logging
 LEVEL  DOMAINS
@@ -167,7 +167,7 @@ B,DISPATCH

-

Example 6. Changing NetworkManager logging

+

Example 6. Changing NetworkManager logging

$ nmcli g log level DEBUG domains CORE,ETHER,IP
 $ nmcli g log level INFO domains DEFAULT
@@ -180,7 +180,7 @@ B,DISPATCH

-

Example 7. Activating a VPN connection profile requiring interactive password input

+

Example 7. Activating a VPN connection profile requiring interactive password input

$ nmcli --ask con up my-vpn-con

@@ -195,7 +195,7 @@ B,DISPATCH


-

Example 8. Adding a bonding master and two slave connection profiles

+

Example 8. Adding a bonding master and two slave connection profiles

$ nmcli con add type bond ifname mybond0 mode active-backup
 $ nmcli con add type ethernet ifname eth1 master mybond0
@@ -211,7 +211,7 @@ B,DISPATCH

-

Example 9. Adding a team master and two slave connection profiles

+

Example 9. Adding a team master and two slave connection profiles

$ nmcli con add type team con-name Team1 ifname Team1 config team1-master-json.conf
 $ nmcli con add type ethernet con-name Team1-slave1 ifname em1 master Team1
@@ -239,7 +239,7 @@ B,DISPATCH

-

Example 10. Adding a bridge and two slave profiles

+

Example 10. Adding a bridge and two slave profiles

$ nmcli con add type bridge con-name TowerBridge ifname TowerBridge
 $ nmcli con add type ethernet con-name br-slave-1 ifname ens3 master TowerBridge
@@ -258,7 +258,7 @@ B,DISPATCH

-

Example 11. Adding an ethernet connection profile with manual IP configuration

+

Example 11. Adding an ethernet connection profile with manual IP configuration

$ nmcli con add con-name my-con-em1 ifname em1 type ethernet \
   ip4 192.168.100.100/24 gw4 192.168.100.1 ip4 1.2.3.4 ip6 abbe::cafe
@@ -281,7 +281,7 @@ B,DISPATCH

-

Example 12. Convenient field values retrieval for scripting

+

Example 12. Convenient field values retrieval for scripting

$ nmcli -g ip4.address connection show my-con-eth0
 192.168.1.12/24
@@ -301,7 +301,7 @@ IP4:192.168.1.12/24:192.168.1.1::192.168.1.1::

-

Example 13. Adding an Ethernet connection and configuring SR-IOV VFs

+

Example 13. Adding an Ethernet connection and configuring SR-IOV VFs

$ nmcli con add type ethernet con-name EthernetPF ifname em1
 $ nmcli con modify EthernetPF sriov.total-vfs 3 sriov.autoprobe-drivers false
@@ -321,7 +321,7 @@ IP4:192.168.1.12/24:192.168.1.1::192.168.1.1::

-

Example 14. Escaping colon characters in tabular mode

+

Example 14. Escaping colon characters in tabular mode

$ nmcli -t -f general -e yes -m tab dev show eth0
 GENERAL:eth0:ethernet:Intel Corporation:82567LM Gigabit Network Connection:
@@ -336,7 +336,7 @@ nager/ActiveConnection/9

-

Example 15. nmcli usage in a NetworkManager dispatcher script to make Ethernet and Wi-Fi mutually exclusive

+

Example 15. nmcli usage in a NetworkManager dispatcher script to make Ethernet and Wi-Fi mutually exclusive

 #!/bin/bash
@@ -374,7 +374,7 @@ fi
 

Example sessions of interactive connection editor

-

Example 16. Adding an ethernet connection profile in interactive editor (a)

+

Example 16. Adding an ethernet connection profile in interactive editor (a)

$ nmcli connection edit type ethernet
 
@@ -610,7 +610,7 @@ Connection 'ethernet-4' (de89cdeb-a3e1-4d53-8fa0-c22546c775f4) successfully
 

-

Example 17. Bluetooth connection profiles

+

Example 17. Bluetooth connection profiles

NetworkManger supports both connecting to NAP and DUN devices as a client. It also supports sharing the network via a NAP server. @@ -636,7 +636,7 @@ Connection 'ethernet-4' (de89cdeb-a3e1-4d53-8fa0-c22546c775f4) successfully

-

See Also

+

See Also

nmcli(1), NetworkManager(8), @@ -649,6 +649,6 @@ Connection 'ethernet-4' (de89cdeb-a3e1-4d53-8fa0-c22546c775f4) successfully

+
Generated by GTK-Doc V1.33.0
\ No newline at end of file diff --git a/docs/api/html/nmcli.html b/docs/api/html/nmcli.html index bcb6657..4bb58f2 100644 --- a/docs/api/html/nmcli.html +++ b/docs/api/html/nmcli.html @@ -6,9 +6,9 @@ - + - + @@ -16,7 +16,7 @@
- +

Alias: ip4

-

Array of IP addresses.

+

A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example "192.168.1.5/24, 10.1.0.5/24".

- Format: array of array of uint32

+ Format: a comma separated list of addresses

routes

-

Array of IP routes.

+

A list of IPv4 destination addresses, prefix length, optional IPv4 next hop addresses, optional route metric, optional attribute. The valid syntax is: "ip[/prefix] [next-hop] [metric] [attribute=val]...[,ip[/prefix]...]". For example "192.0.2.0/24 10.1.1.1 77, 198.51.100.0/24".

- Format: array of array of uint32

+ Format: a comma separated list of routes

kernel-command-line

-

A list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or if prefixed with the exclamation mark unset). The argument must either be a single word, or an assignment (i.e. two words, separated "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\' are used for optional and mandatory matches and inverting the pattern.

+

A list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or unset, if prefixed with the exclamation mark). The argument must either be a single word, or an assignment (i.e. two words, joined by "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. Wildcard patterns are not supported. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\' are used for optional and mandatory matches and inverting the match.

Format: array of string

Home UpPrevPrev Next
@@ -1716,6 +1716,6 @@
+
Generated by GTK-Doc V1.33.0
\ No newline at end of file diff --git a/docs/api/html/nmtui.html b/docs/api/html/nmtui.html index ee9ab9f..edf90ab 100644 --- a/docs/api/html/nmtui.html +++ b/docs/api/html/nmtui.html @@ -8,7 +8,7 @@ - + @@ -83,6 +83,6 @@
+
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-access-points.html b/docs/api/html/ref-dbus-access-points.html index f59402c..0b4bb69 100644 --- a/docs/api/html/ref-dbus-access-points.html +++ b/docs/api/html/ref-dbus-access-points.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-active-connections.html b/docs/api/html/ref-dbus-active-connections.html index a46f4dd..4c2cd24 100644 --- a/docs/api/html/ref-dbus-active-connections.html +++ b/docs/api/html/ref-dbus-active-connections.html @@ -8,7 +8,7 @@ - + @@ -32,6 +32,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-agent-manager.html b/docs/api/html/ref-dbus-agent-manager.html index a64f484..eccc57b 100644 --- a/docs/api/html/ref-dbus-agent-manager.html +++ b/docs/api/html/ref-dbus-agent-manager.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-checkpoint.html b/docs/api/html/ref-dbus-checkpoint.html index 59f7aae..1795082 100644 --- a/docs/api/html/ref-dbus-checkpoint.html +++ b/docs/api/html/ref-dbus-checkpoint.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-devices.html b/docs/api/html/ref-dbus-devices.html index 8abca65..6537de2 100644 --- a/docs/api/html/ref-dbus-devices.html +++ b/docs/api/html/ref-dbus-devices.html @@ -8,7 +8,7 @@ - + @@ -119,6 +119,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-dhcp4-configs.html b/docs/api/html/ref-dbus-dhcp4-configs.html index 9c77a26..1f222e0 100644 --- a/docs/api/html/ref-dbus-dhcp4-configs.html +++ b/docs/api/html/ref-dbus-dhcp4-configs.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-dhcp6-configs.html b/docs/api/html/ref-dbus-dhcp6-configs.html index b318d44..0845bf0 100644 --- a/docs/api/html/ref-dbus-dhcp6-configs.html +++ b/docs/api/html/ref-dbus-dhcp6-configs.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-dns-manager.html b/docs/api/html/ref-dbus-dns-manager.html index ba431bc..1ab7f8a 100644 --- a/docs/api/html/ref-dbus-dns-manager.html +++ b/docs/api/html/ref-dbus-dns-manager.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-ip4-configs.html b/docs/api/html/ref-dbus-ip4-configs.html index b9c03bd..2bc3e16 100644 --- a/docs/api/html/ref-dbus-ip4-configs.html +++ b/docs/api/html/ref-dbus-ip4-configs.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-ip6-configs.html b/docs/api/html/ref-dbus-ip6-configs.html index b301432..befd32e 100644 --- a/docs/api/html/ref-dbus-ip6-configs.html +++ b/docs/api/html/ref-dbus-ip6-configs.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-manager.html b/docs/api/html/ref-dbus-manager.html index 28b4399..ba94fe4 100644 --- a/docs/api/html/ref-dbus-manager.html +++ b/docs/api/html/ref-dbus-manager.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-settings-manager.html b/docs/api/html/ref-dbus-settings-manager.html index b31916f..d122fcc 100644 --- a/docs/api/html/ref-dbus-settings-manager.html +++ b/docs/api/html/ref-dbus-settings-manager.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-settings.html b/docs/api/html/ref-dbus-settings.html index ace2d15..d1d5c70 100644 --- a/docs/api/html/ref-dbus-settings.html +++ b/docs/api/html/ref-dbus-settings.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-dbus-wifi-p2p-peers.html b/docs/api/html/ref-dbus-wifi-p2p-peers.html index 5299114..99d0470 100644 --- a/docs/api/html/ref-dbus-wifi-p2p-peers.html +++ b/docs/api/html/ref-dbus-wifi-p2p-peers.html @@ -8,7 +8,7 @@ - + @@ -27,6 +27,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/ref-settings.html b/docs/api/html/ref-settings.html index feefbec..e09dc7b 100644 --- a/docs/api/html/ref-settings.html +++ b/docs/api/html/ref-settings.html @@ -8,7 +8,7 @@ - + @@ -193,6 +193,6 @@

+
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/secret-agents.html b/docs/api/html/secret-agents.html index 72c0696..b3df856 100644 --- a/docs/api/html/secret-agents.html +++ b/docs/api/html/secret-agents.html @@ -8,7 +8,7 @@ - + @@ -33,6 +33,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/secrets-flags.html b/docs/api/html/secrets-flags.html index 66c07ce..1d59a93 100644 --- a/docs/api/html/secrets-flags.html +++ b/docs/api/html/secrets-flags.html @@ -8,7 +8,7 @@ - + @@ -58,6 +58,6 @@

+
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-6lowpan.html b/docs/api/html/settings-6lowpan.html index 29f8401..9c89ffd 100644 --- a/docs/api/html/settings-6lowpan.html +++ b/docs/api/html/settings-6lowpan.html @@ -8,7 +8,7 @@ - + @@ -64,6 +64,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-802-11-olpc-mesh.html b/docs/api/html/settings-802-11-olpc-mesh.html index a9d9818..7ff80ef 100644 --- a/docs/api/html/settings-802-11-olpc-mesh.html +++ b/docs/api/html/settings-802-11-olpc-mesh.html @@ -8,7 +8,7 @@ - + @@ -78,6 +78,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-802-11-wireless-security.html b/docs/api/html/settings-802-11-wireless-security.html index 48cddf4..7e915e4 100644 --- a/docs/api/html/settings-802-11-wireless-security.html +++ b/docs/api/html/settings-802-11-wireless-security.html @@ -8,7 +8,7 @@ - + @@ -180,6 +180,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-802-11-wireless.html b/docs/api/html/settings-802-11-wireless.html index b718430..71cafdf 100644 --- a/docs/api/html/settings-802-11-wireless.html +++ b/docs/api/html/settings-802-11-wireless.html @@ -8,7 +8,7 @@ - + @@ -180,6 +180,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-802-1x.html b/docs/api/html/settings-802-1x.html index 146bd35..9747c48 100644 --- a/docs/api/html/settings-802-1x.html +++ b/docs/api/html/settings-802-1x.html @@ -8,7 +8,7 @@ - + @@ -342,6 +342,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-802-3-ethernet.html b/docs/api/html/settings-802-3-ethernet.html index fb828bf..1533c60 100644 --- a/docs/api/html/settings-802-3-ethernet.html +++ b/docs/api/html/settings-802-3-ethernet.html @@ -8,7 +8,7 @@ - + @@ -150,6 +150,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-adsl.html b/docs/api/html/settings-adsl.html index a861bf9..1eb087d 100644 --- a/docs/api/html/settings-adsl.html +++ b/docs/api/html/settings-adsl.html @@ -8,7 +8,7 @@ - + @@ -102,6 +102,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-bluetooth.html b/docs/api/html/settings-bluetooth.html index 02dc2e1..e7ceaf7 100644 --- a/docs/api/html/settings-bluetooth.html +++ b/docs/api/html/settings-bluetooth.html @@ -8,7 +8,7 @@ - + @@ -72,6 +72,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-bond.html b/docs/api/html/settings-bond.html index 6c5bc7d..268ae38 100644 --- a/docs/api/html/settings-bond.html +++ b/docs/api/html/settings-bond.html @@ -8,7 +8,7 @@ - + @@ -72,6 +72,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-bridge-port.html b/docs/api/html/settings-bridge-port.html index 7842fdb..6eb7d93 100644 --- a/docs/api/html/settings-bridge-port.html +++ b/docs/api/html/settings-bridge-port.html @@ -8,7 +8,7 @@ - + @@ -84,6 +84,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-bridge.html b/docs/api/html/settings-bridge.html index 92e1dec..5cee3c1 100644 --- a/docs/api/html/settings-bridge.html +++ b/docs/api/html/settings-bridge.html @@ -8,7 +8,7 @@ - + @@ -228,6 +228,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-cdma.html b/docs/api/html/settings-cdma.html index 2c66448..a32fa53 100644 --- a/docs/api/html/settings-cdma.html +++ b/docs/api/html/settings-cdma.html @@ -8,7 +8,7 @@ - + @@ -90,6 +90,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-connection.html b/docs/api/html/settings-connection.html index 3c57ca0..79025e4 100644 --- a/docs/api/html/settings-connection.html +++ b/docs/api/html/settings-connection.html @@ -8,7 +8,7 @@ - + @@ -210,6 +210,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-dcb.html b/docs/api/html/settings-dcb.html index b7319d6..d3274cf 100644 --- a/docs/api/html/settings-dcb.html +++ b/docs/api/html/settings-dcb.html @@ -8,7 +8,7 @@ - + @@ -150,6 +150,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-dummy.html b/docs/api/html/settings-dummy.html index 403c68b..6bc0ab4 100644 --- a/docs/api/html/settings-dummy.html +++ b/docs/api/html/settings-dummy.html @@ -8,7 +8,7 @@ - + @@ -59,6 +59,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ethtool.html b/docs/api/html/settings-ethtool.html index 0a6033b..adf9071 100644 --- a/docs/api/html/settings-ethtool.html +++ b/docs/api/html/settings-ethtool.html @@ -8,7 +8,7 @@ - + @@ -59,6 +59,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-generic.html b/docs/api/html/settings-generic.html index ad8cd08..cdc71b1 100644 --- a/docs/api/html/settings-generic.html +++ b/docs/api/html/settings-generic.html @@ -8,7 +8,7 @@ - + @@ -59,6 +59,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-gsm.html b/docs/api/html/settings-gsm.html index 8e97b6e..a48daf4 100644 --- a/docs/api/html/settings-gsm.html +++ b/docs/api/html/settings-gsm.html @@ -8,7 +8,7 @@ - + @@ -144,6 +144,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-hostname.html b/docs/api/html/settings-hostname.html index 0a4eddc..0caf2ce 100644 --- a/docs/api/html/settings-hostname.html +++ b/docs/api/html/settings-hostname.html @@ -8,7 +8,7 @@ - + @@ -84,6 +84,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-infiniband.html b/docs/api/html/settings-infiniband.html index 39a5004..702d1bf 100644 --- a/docs/api/html/settings-infiniband.html +++ b/docs/api/html/settings-infiniband.html @@ -8,7 +8,7 @@ - + @@ -90,6 +90,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ip-tunnel.html b/docs/api/html/settings-ip-tunnel.html index e092220..929ffa4 100644 --- a/docs/api/html/settings-ip-tunnel.html +++ b/docs/api/html/settings-ip-tunnel.html @@ -8,7 +8,7 @@ - + @@ -138,6 +138,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ipv4.html b/docs/api/html/settings-ipv4.html index 63ef91f..2152a9e 100644 --- a/docs/api/html/settings-ipv4.html +++ b/docs/api/html/settings-ipv4.html @@ -8,7 +8,7 @@ - + @@ -216,6 +216,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-ipv6.html b/docs/api/html/settings-ipv6.html index 3c11795..1680a5a 100644 --- a/docs/api/html/settings-ipv6.html +++ b/docs/api/html/settings-ipv6.html @@ -8,7 +8,7 @@ - + @@ -228,6 +228,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-macsec.html b/docs/api/html/settings-macsec.html index 3baaf03..ecc6f69 100644 --- a/docs/api/html/settings-macsec.html +++ b/docs/api/html/settings-macsec.html @@ -8,7 +8,7 @@ - + @@ -114,6 +114,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-macvlan.html b/docs/api/html/settings-macvlan.html index cf6f9f8..3cf2fc0 100644 --- a/docs/api/html/settings-macvlan.html +++ b/docs/api/html/settings-macvlan.html @@ -8,7 +8,7 @@ - + @@ -84,6 +84,6 @@ +
Generated by GTK-Doc V1.33.0 \ No newline at end of file diff --git a/docs/api/html/settings-match.html b/docs/api/html/settings-match.html index 3c79f2a..2a326ed 100644 --- a/docs/api/html/settings-match.html +++ b/docs/api/html/settings-match.html @@ -8,7 +8,7 @@ - + @@ -69,7 +69,7 @@
kernel-command-line
array of string
A list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or if prefixed with the exclamation mark unset). The argument must either be a single word, or an assignment (i.e. two words, separated "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.A list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or unset, if prefixed with the exclamation mark). The argument must either be a single word, or an assignment (i.e. two words, joined by "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. Wildcard patterns are not supported. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the match.
path
Key NameValue TypeDefault ValueValue Descriptionmodemodeuint320The macvlan mode, which specifies the communication mechanism between multiple macvlans on the same lower device.parentparentstringIf given, specifies the parent interface name or parent connection UUID from which this MAC-VLAN interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property.promiscuouspromiscuousbooleanTRUEWhether the interface should be put in promiscuous mode.taptapbooleanFALSEWhether the interface should be a MACVTAP.
matchMatch settings Properties - Key NameValue TypeDefault ValueValue Descriptiondriverdriverarray of stringA list of driver names to match. Each element is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.interface-nameinterface-namearray of stringA list of interface names to match. Each element is a shell wildcard pattern. An element can be prefixed with a pipe symbol (|) or an ampersand (&). The former means that the element is optional and the latter means that it is mandatory. If there are any optional elements, than the match evaluates to true if at least one of the optional element matches (logical OR). If there are any mandatory elements, then they all must match (logical AND). By default, an element is optional. This means that an element "foo" behaves the same as "|foo". An element can also be inverted with exclamation mark (!) between the pipe symbol (or the ampersand) and before the pattern. Note that "!foo" is a shortcut for the mandatory match "&!foo". Finally, a backslash can be used at the beginning of the element (after the optional special characters) to escape the start of the pattern. For example, "&\\!a" is an mandatory match for literally "!a".kernel-command-linekernel-command-linearray of stringA list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or if prefixed with the exclamation mark unset). The argument must either be a single word, or an assignment (i.e. two words, separated "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.pathpatharray of stringA list of paths to match against the ID_PATH udev property of devices. ID_PATH represents the topological persistent path of a device. It typically contains a subsystem string (pci, usb, platform, etc.) and a subsystem-specific identifier. For PCI devices the path has the form "pci-$domain:$bus:$device.$function", where each variable is an hexadecimal value; for example "pci-0000:0a:00.0". The path of a device can be obtained with "udevadm info /sys/class/net/$dev | grep ID_PATH=" or by looking at the "path" property exported by NetworkManager ("nmcli -f general.path device show $dev"). Each element of the list is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.
802-11-olpc-meshOLPC Wireless Mesh Settings + Key NameValue TypeDefault ValueValue Descriptiondriverdriverarray of stringA list of driver names to match. Each element is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.interface-nameinterface-namearray of stringA list of interface names to match. Each element is a shell wildcard pattern. An element can be prefixed with a pipe symbol (|) or an ampersand (&). The former means that the element is optional and the latter means that it is mandatory. If there are any optional elements, than the match evaluates to true if at least one of the optional element matches (logical OR). If there are any mandatory elements, then they all must match (logical AND). By default, an element is optional. This means that an element "foo" behaves the same as "|foo". An element can also be inverted with exclamation mark (!) between the pipe symbol (or the ampersand) and before the pattern. Note that "!foo" is a shortcut for the mandatory match "&!foo". Finally, a backslash can be used at the beginning of the element (after the optional special characters) to escape the start of the pattern. For example, "&\\!a" is an mandatory match for literally "!a".kernel-command-linekernel-command-linearray of stringA list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or unset, if prefixed with the exclamation mark). The argument must either be a single word, or an assignment (i.e. two words, joined by "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. Wildcard patterns are not supported. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the match.pathpatharray of stringA list of paths to match against the ID_PATH udev property of devices. ID_PATH represents the topological persistent path of a device. It typically contains a subsystem string (pci, usb, platform, etc.) and a subsystem-specific identifier. For PCI devices the path has the form "pci-$domain:$bus:$device.$function", where each variable is an hexadecimal value; for example "pci-0000:0a:00.0". The path of a device can be obtained with "udevadm info /sys/class/net/$dev | grep ID_PATH=" or by looking at the "path" property exported by NetworkManager ("nmcli -f general.path device show $dev"). Each element of the list is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.
802-11-olpc-meshOLPC Wireless Mesh Settings Properties Key NameValue TypeDefault ValueValue Descriptionchannelchanneluint320Channel on which the mesh network to join is located.dhcp-anycast-addressdhcp-anycast-addressbyte arrayAnycast DHCP MAC address used when requesting an IP address via DHCP. The specific anycast address used determines which DHCP server class answers the request.ssidssidbyte arraySSID of the mesh network to join.
ovs-bridgeOvsBridge Link Settings Properties diff --git a/docs/api/version.xml b/docs/api/version.xml index 034552a..3492b09 100644 --- a/docs/api/version.xml +++ b/docs/api/version.xml @@ -1 +1 @@ -1.30.0 +1.31.2 diff --git a/docs/libnm/Makefile.am b/docs/libnm/Makefile.am index ae61d85..17244c1 100644 --- a/docs/libnm/Makefile.am +++ b/docs/libnm/Makefile.am @@ -13,10 +13,15 @@ DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml # gtk-doc will search all .c & .h files beneath here for inline comments # documenting functions and macros. DOC_SOURCE_DIR= \ - $(top_srcdir)/libnm-core \ - $(top_builddir)/libnm-core \ - $(top_srcdir)/libnm \ - $(top_builddir)/libnm + $(top_builddir)/src/libnm-core-public \ + $(top_srcdir)/src/libnm-core-public \ + $(top_builddir)/src/libnm-core-impl \ + $(top_srcdir)/src/libnm-core-impl \ + $(top_srcdir)/src/libnm-client-public \ + $(top_builddir)/src/libnm-client-public \ + $(top_srcdir)/src/libnm-client-impl \ + $(top_builddir)/src/libnm-client-impl \ + $(NULL) # Extra options to supply to gtkdoc-scan. SCAN_OPTIONS=--rebuild-types --rebuild-sections --ignore-decorators="NM_AVAILABLE_IN_\d_\d\d?|NM_DEPRECATED_IN_\d_\d\d?" @@ -28,15 +33,14 @@ MKDB_OPTIONS=--sgml-mode --output-format=xml FIXXREF_OPTIONS= # Used for dependencies. -HFILE_GLOB=$(top_srcdir)/libnm-core/*.h $(top_srcdir)/libnm/*.h -CFILE_GLOB=$(top_srcdir)/libnm-core/*.c $(top_srcdir)/libnm/*.c +HFILE_GLOB=$(top_srcdir)/src/libnm-core-public/*.h $(top_srcdir)/src/libnm-client-public/*.h +CFILE_GLOB=$(top_srcdir)/src/libnm-core-impl/*.c $(top_srcdir)/src/libnm-client-impl/*.c # Header files to ignore when scanning. IGNORE_HFILES= \ common.h \ nm-core-internal.h \ nm-core-tests-enum-types.h \ - nm-core-types-internal.h \ nm-crypto-impl.h \ nm-crypto.h \ nm-dbus-helpers.h \ @@ -84,16 +88,16 @@ extra_files = libnm.png # CFLAGS and LDFLAGS for compiling scan program. Only needed # if $(DOC_MODULE).types is non-empty. GTKDOC_CFLAGS = \ - -I$(top_srcdir)/libnm-core \ - -I$(top_builddir)/libnm-core \ - -I$(top_srcdir)/libnm \ - -I$(top_builddir)/libnm \ + -I$(top_builddir)/src/libnm-core-public \ + -I$(top_srcdir)/src/libnm-core-public \ + -I$(top_srcdir)/src/libnm-client-public \ + -I$(top_builddir)/src/libnm-client-public \ -DNM_VERSION_MIN_REQUIRED=NM_VERSION_0_9_8 \ $(GLIB_CFLAGS) \ $(SANITIZER_EXEC_CFLAGS) GTKDOC_LIBS = \ - $(top_builddir)/libnm/libnm.la \ + $(top_builddir)/src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(SANITIZER_EXEC_LDFLAGS) diff --git a/docs/libnm/Makefile.in b/docs/libnm/Makefile.in index 7ec2bc9..0b87aa1 100644 --- a/docs/libnm/Makefile.in +++ b/docs/libnm/Makefile.in @@ -459,10 +459,15 @@ DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml # gtk-doc will search all .c & .h files beneath here for inline comments # documenting functions and macros. DOC_SOURCE_DIR = \ - $(top_srcdir)/libnm-core \ - $(top_builddir)/libnm-core \ - $(top_srcdir)/libnm \ - $(top_builddir)/libnm + $(top_builddir)/src/libnm-core-public \ + $(top_srcdir)/src/libnm-core-public \ + $(top_builddir)/src/libnm-core-impl \ + $(top_srcdir)/src/libnm-core-impl \ + $(top_srcdir)/src/libnm-client-public \ + $(top_builddir)/src/libnm-client-public \ + $(top_srcdir)/src/libnm-client-impl \ + $(top_builddir)/src/libnm-client-impl \ + $(NULL) # Extra options to supply to gtkdoc-scan. @@ -475,15 +480,14 @@ MKDB_OPTIONS = --sgml-mode --output-format=xml FIXXREF_OPTIONS = # Used for dependencies. -HFILE_GLOB = $(top_srcdir)/libnm-core/*.h $(top_srcdir)/libnm/*.h -CFILE_GLOB = $(top_srcdir)/libnm-core/*.c $(top_srcdir)/libnm/*.c +HFILE_GLOB = $(top_srcdir)/src/libnm-core-public/*.h $(top_srcdir)/src/libnm-client-public/*.h +CFILE_GLOB = $(top_srcdir)/src/libnm-core-impl/*.c $(top_srcdir)/src/libnm-client-impl/*.c # Header files to ignore when scanning. IGNORE_HFILES = \ common.h \ nm-core-internal.h \ nm-core-tests-enum-types.h \ - nm-core-types-internal.h \ nm-crypto-impl.h \ nm-crypto.h \ nm-dbus-helpers.h \ @@ -531,16 +535,16 @@ extra_files = libnm.png # CFLAGS and LDFLAGS for compiling scan program. Only needed # if $(DOC_MODULE).types is non-empty. GTKDOC_CFLAGS = \ - -I$(top_srcdir)/libnm-core \ - -I$(top_builddir)/libnm-core \ - -I$(top_srcdir)/libnm \ - -I$(top_builddir)/libnm \ + -I$(top_builddir)/src/libnm-core-public \ + -I$(top_srcdir)/src/libnm-core-public \ + -I$(top_srcdir)/src/libnm-client-public \ + -I$(top_builddir)/src/libnm-client-public \ -DNM_VERSION_MIN_REQUIRED=NM_VERSION_0_9_8 \ $(GLIB_CFLAGS) \ $(SANITIZER_EXEC_CFLAGS) GTKDOC_LIBS = \ - $(top_builddir)/libnm/libnm.la \ + $(top_builddir)/src/libnm-client-impl/libnm.la \ $(GLIB_LIBS) \ $(SANITIZER_EXEC_LDFLAGS) @@ -574,7 +578,6 @@ DOC_STAMPS = setup-build.stamp scan-build.stamp sgml-build.stamp \ sgml.stamp html.stamp pdf.stamp SCANOBJ_FILES = \ - $(DOC_MODULE).actions \ $(DOC_MODULE).args \ $(DOC_MODULE).hierarchy \ $(DOC_MODULE).interfaces \ diff --git a/docs/libnm/html/NMAccessPoint.html b/docs/libnm/html/NMAccessPoint.html index e12e1c6..e587fdf 100644 --- a/docs/libnm/html/NMAccessPoint.html +++ b/docs/libnm/html/NMAccessPoint.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMVpnConnection.html" title="NMVpnConnection"> <link rel="next" href="NMWifiP2PPeer.html" title="NMWifiP2PPeer"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -300,7 +300,7 @@ nm_access_point_get_ssid (<em class="parameter"><code><a class="link" href="NMAc <a name="nm-access-point-get-ssid.returns"></a><h4>Returns</h4> <p>the <a href="https://developer.gnome.org/glib/unstable/glib-Byte-Arrays.html#GBytes"><span class="type">GBytes</span></a> containing the SSID, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the SSID is unknown. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -494,7 +494,7 @@ with this function.</p> </tr> <tr> <td class="parameter_name"><p>connections</p></td> -<td class="parameter_description"><p>an array of <a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-struct"><span class="type">NMConnections</span></a> to +<td class="parameter_description"><p>an array of <span class="type">NMConnections</span> to filter. </p></td> <td class="parameter_annotations"><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></td> </tr> @@ -504,13 +504,13 @@ filter. </p></td> <div class="refsect3"> <a name="nm-access-point-filter-connections.returns"></a><h4>Returns</h4> <p>an array of -<a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-struct"><span class="type">NMConnections</span></a> that could be activated with the given <em class="parameter"><code>ap</code></em> +<span class="type">NMConnections</span> that could be activated with the given <em class="parameter"><code>ap</code></em> . The array should be freed with <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#g-ptr-array-unref"><code class="function">g_ptr_array_unref()</code></a> when it is no longer required.</p> <p>WARNING: the transfer annotation for this function may not work correctly with bindings. See https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/305. You can filter the list yourself with <a class="link" href="NMAccessPoint.html#nm-access-point-connection-valid" title="nm_access_point_connection_valid ()"><code class="function">nm_access_point_connection_valid()</code></a>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></p> </div> </div> <hr> @@ -625,6 +625,6 @@ against</p></td> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMActiveConnection.html b/docs/libnm/html/NMActiveConnection.html index b385dc6..4bbd147 100644 --- a/docs/libnm/html/NMActiveConnection.html +++ b/docs/libnm/html/NMActiveConnection.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceWpan.html" title="NMDeviceWpan"> <link rel="next" href="NMVpnConnection.html" title="NMVpnConnection"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -278,7 +278,7 @@ nm_active_connection_get_connection (<em class="parameter"><code><a class="link" <a name="nm-active-connection-get-connection.returns"></a><h4>Returns</h4> <p>the <a class="link" href="NMRemoteConnection.html" title="NMRemoteConnection"><span class="type">NMRemoteConnection</span></a> which this <a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> is an active instance of. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -529,7 +529,7 @@ nm_active_connection_get_master (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-active-connection-get-master.returns"></a><h4>Returns</h4> <p>the master <a class="link" href="NMDevice.html" title="NMDevice"><span class="type">NMDevice</span></a> of the <a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -584,7 +584,7 @@ nm_active_connection_get_ip4_config (<em class="parameter"><code><a class="link" <a name="nm-active-connection-get-ip4-config.returns"></a><h4>Returns</h4> <p>the IPv4 <a class="link" href="NMIPConfig.html" title="NMIPConfig"><span class="type">NMIPConfig</span></a>, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the connection is not in the <a class="link" href="libnm-nm-dbus-interface.html#NM-ACTIVE-CONNECTION-STATE-ACTIVATED:CAPS"><code class="literal">NM_ACTIVE_CONNECTION_STATE_ACTIVATED</code></a> state. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -614,7 +614,7 @@ nm_active_connection_get_dhcp4_config (<em class="parameter"><code><a class="lin <p>the IPv4 <a class="link" href="NMDhcpConfig.html" title="NMDhcpConfig"><span class="type">NMDhcpConfig</span></a>, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the connection does not use DHCP, or is not in the <a class="link" href="libnm-nm-dbus-interface.html#NM-ACTIVE-CONNECTION-STATE-ACTIVATED:CAPS"><code class="literal">NM_ACTIVE_CONNECTION_STATE_ACTIVATED</code></a> state. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -669,7 +669,7 @@ nm_active_connection_get_ip6_config (<em class="parameter"><code><a class="link" <a name="nm-active-connection-get-ip6-config.returns"></a><h4>Returns</h4> <p>the IPv6 <a class="link" href="NMIPConfig.html" title="NMIPConfig"><span class="type">NMIPConfig</span></a>, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the connection is not in the <a class="link" href="libnm-nm-dbus-interface.html#NM-ACTIVE-CONNECTION-STATE-ACTIVATED:CAPS"><code class="literal">NM_ACTIVE_CONNECTION_STATE_ACTIVATED</code></a> state. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -699,7 +699,7 @@ nm_active_connection_get_dhcp6_config (<em class="parameter"><code><a class="lin <p>the IPv6 <a class="link" href="NMDhcpConfig.html" title="NMDhcpConfig"><span class="type">NMDhcpConfig</span></a>, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the connection does not use DHCPv6, or is not in the <a class="link" href="libnm-nm-dbus-interface.html#NM-ACTIVE-CONNECTION-STATE-ACTIVATED:CAPS"><code class="literal">NM_ACTIVE_CONNECTION_STATE_ACTIVATED</code></a> state. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -829,6 +829,6 @@ nm_active_connection_get_vpn (<em class="parameter"><code><a class="link" href=" </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMCheckpoint.html b/docs/libnm/html/NMCheckpoint.html index 87f2a9c..c9283c0 100644 --- a/docs/libnm/html/NMCheckpoint.html +++ b/docs/libnm/html/NMCheckpoint.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDhcpConfig.html" title="NMDhcpConfig"> <link rel="next" href="ch05.html" title="Utility API Reference"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -199,6 +199,6 @@ nm_checkpoint_get_rollback_timeout (<em class="parameter"><code><a class="link" </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMClient.html b/docs/libnm/html/NMClient.html index 7e7c131..6338076 100644 --- a/docs/libnm/html/NMClient.html +++ b/docs/libnm/html/NMClient.html @@ -8,7 +8,7 @@ <link rel="up" href="ch02.html" title="Client Object API Reference"> <link rel="prev" href="ch02.html" title="Client Object API Reference"> <link rel="next" href="NMSecretAgentOld.html" title="NMSecretAgentOld"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -1068,7 +1068,7 @@ nm_dns_entry_get_interface (<em class="parameter"><code><a class="link" href="NM <div class="refsect3"> <a name="nm-dns-entry-get-interface.returns"></a><h4>Returns</h4> <p>the interface name. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.6</p> </div> @@ -1096,7 +1096,7 @@ nm_dns_entry_get_nameservers (<em class="parameter"><code><a class="link" href=" <div class="refsect3"> <a name="nm-dns-entry-get-nameservers.returns"></a><h4>Returns</h4> <p>the list of name servers. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.6</p> </div> @@ -1124,7 +1124,7 @@ nm_dns_entry_get_domains (<em class="parameter"><code><a class="link" href="NMCl <div class="refsect3"> <a name="nm-dns-entry-get-domains.returns"></a><h4>Returns</h4> <p>the list of DNS domains. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.6</p> </div> @@ -1346,7 +1346,7 @@ automatically initialized during async/sync init.</p> <div class="refsect3"> <a name="nm-client-get-dbus-connection.returns"></a><h4>Returns</h4> <p>the D-Bus connection of the client, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if none is set. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.22</p> </div> @@ -1381,7 +1381,7 @@ the <a class="link" href="NMClient.html#nm-client-get-context-busy-watcher" titl <div class="refsect3"> <a name="nm-client-get-main-context.returns"></a><h4>Returns</h4> <p>the <a href="https://developer.gnome.org/glib/unstable/glib-The-Main-Event-Loop.html#GMainContext"><span class="type">GMainContext</span></a> of the client. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.22</p> </div> @@ -1424,7 +1424,7 @@ iterating the main context until the object got unreferenced.</p> <p>Note that after the NMClient instance gets destroyed, the remaining callbacks will be invoked right away. That means, the user won't have to iterate the main context much longer. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.22</p> </div> @@ -1451,7 +1451,7 @@ nm_client_get_dbus_name_owner (<em class="parameter"><code><a class="link" href= <div class="refsect3"> <a name="nm-client-get-dbus-name-owner.returns"></a><h4>Returns</h4> <p>the current name owner of the D-Bus service of NetworkManager. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.22</p> </div> @@ -1593,7 +1593,7 @@ nm_client_get_object_by_path (<em class="parameter"><code><a class="link" href=" <p>the <a class="link" href="NMObject.html" title="NMObject"><span class="type">NMObject</span></a> instance that is cached under <em class="parameter"><code>dbus_path</code></em> , or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if no such object exists. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.24</p> </div> @@ -1686,7 +1686,7 @@ The numeric values correspond to <a class="link" href="libnm-nm-dbus-interface.h The array is terminated by a numeric zero sentinel at position <em class="parameter"><code>length</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> </div> <p class="since">Since: 1.24</p> </div> @@ -2128,7 +2128,7 @@ connectivity.</p> <div class="refsect3"> <a name="nm-client-connectivity-check-get-uri.returns"></a><h4>Returns</h4> <p>the connectivity URI in use. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.20</p> </div> @@ -2640,7 +2640,7 @@ methods such as <a class="link" href="NMDeviceEthernet.html#nm-device-ethernet-g <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> containing all the <span class="type">NMDevices</span>. The returned array is owned by the <a class="link" href="NMClient.html" title="NMClient"><span class="type">NMClient</span></a> object and should not be modified. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMDevice]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMDevice]</span></p> </div> </div> <hr> @@ -2676,7 +2676,7 @@ use device-specific methods such as <a class="link" href="NMDeviceEthernet.html# <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> containing all the <span class="type">NMDevices</span>. The returned array is owned by the <a class="link" href="NMClient.html" title="NMClient"><span class="type">NMClient</span></a> object and should not be modified. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMDevice]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMDevice]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -2713,7 +2713,7 @@ nm_client_get_device_by_path (<em class="parameter"><code><a class="link" href=" <a name="nm-client-get-device-by-path.returns"></a><h4>Returns</h4> <p>the <a class="link" href="NMDevice.html" title="NMDevice"><span class="type">NMDevice</span></a> for the given <em class="parameter"><code>object_path</code></em> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if none is found. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2749,7 +2749,7 @@ nm_client_get_device_by_iface (<em class="parameter"><code><a class="link" href= <a name="nm-client-get-device-by-iface.returns"></a><h4>Returns</h4> <p>the <a class="link" href="NMDevice.html" title="NMDevice"><span class="type">NMDevice</span></a> for the given <em class="parameter"><code>iface</code></em> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if none is found. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2778,7 +2778,7 @@ nm_client_get_active_connections (<em class="parameter"><code><a class="link" hr <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> containing all the active <span class="type">NMActiveConnections</span>. The returned array is owned by the client and should not be modified. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMActiveConnection]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMActiveConnection]</span></p> </div> </div> <hr> @@ -2814,7 +2814,7 @@ non-NetworkManager-recognized device, this will return <a href="https://develope <a name="nm-client-get-primary-connection.returns"></a><h4>Returns</h4> <p>the appropriate <a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a>, if any. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2824,7 +2824,7 @@ any. </p> nm_client_get_activating_connection (<em class="parameter"><code><a class="link" href="NMClient.html" title="NMClient"><span class="type">NMClient</span></a> *client</code></em>);</pre> <p>Gets the <a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> corresponding to a currently-activating connection that is expected to become the new -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--primary-connection"><span class="type">“primary-connection”</span></a> upon successful activation.</p> +<span class="type">“primary-connection”</span> upon successful activation.</p> <div class="refsect3"> <a name="nm-client-get-activating-connection.parameters"></a><h4>Parameters</h4> <div class="informaltable"><table class="informaltable" width="100%" border="0"> @@ -2844,7 +2844,7 @@ currently-activating connection that is expected to become the new <a name="nm-client-get-activating-connection.returns"></a><h4>Returns</h4> <p>the appropriate <a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a>, if any. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2874,7 +2874,7 @@ in <em class="parameter"><code>connection</code></em> picks the best available connection for the device and activates it.</p> <p>Note that the callback is invoked when NetworkManager has started activating the new connection, not when it finishes. You can use the returned -<a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> object (in particular, <a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--state"><span class="type">“state”</span></a>) to +<a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> object (in particular, <span class="type">“state”</span>) to track the activation to its completion.</p> <div class="refsect3"> <a name="nm-client-activate-connection-async.parameters"></a><h4>Parameters</h4> @@ -2972,7 +2972,7 @@ nm_client_activate_connection_finish (<em class="parameter"><code><a class="link <p>the new <a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> on success, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on failure, in which case <em class="parameter"><code>error</code></em> will be set. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2994,7 +2994,7 @@ activated as with <a class="link" href="NMClient.html#nm-client-activate-connect VPN connections at this time.</p> <p>Note that the callback is invoked when NetworkManager has started activating the new connection, not when it finishes. You can used the returned -<a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> object (in particular, <a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--state"><span class="type">“state”</span></a>) to +<a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> object (in particular, <span class="type">“state”</span>) to track the activation to its completion.</p> <div class="refsect3"> <a name="nm-client-add-and-activate-connection-async.parameters"></a><h4>Parameters</h4> @@ -3100,7 +3100,7 @@ nm_client_add_and_activate_connection_finish <p>the new <a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> on success, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on failure, in which case <em class="parameter"><code>error</code></em> will be set. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -3123,7 +3123,7 @@ activated as with <a class="link" href="NMClient.html#nm-client-activate-connect VPN connections at this time.</p> <p>Note that the callback is invoked when NetworkManager has started activating the new connection, not when it finishes. You can used the returned -<a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> object (in particular, <a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--state"><span class="type">“state”</span></a>) to +<a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> object (in particular, <span class="type">“state”</span>) to track the activation to its completion.</p> <p>This is identical to <a class="link" href="NMClient.html#nm-client-add-and-activate-connection-async" title="nm_client_add_and_activate_connection_async ()"><code class="function">nm_client_add_and_activate_connection_async()</code></a> but takes a further <em class="parameter"><code>options</code></em> @@ -3245,7 +3245,7 @@ nm_client_add_and_activate_connection2_finish <td class="parameter_description"><p>the output result of type "a{sv}" returned by D-Bus' AddAndActivate2 call. Currently, no output is implemented yet. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -3255,7 +3255,7 @@ output is implemented yet. </p></td> <p>the new <a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> on success, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on failure, in which case <em class="parameter"><code>error</code></em> will be set. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -3425,7 +3425,7 @@ containing all connections provided by the remote settings service. The returned array is owned by the <a class="link" href="NMClient.html" title="NMClient"><span class="type">NMClient</span></a> object and should not be modified.</p> <p>The connections are as received from D-Bus and might not validate according to <a class="link" href="NMConnection.html#nm-connection-verify" title="nm_connection_verify ()"><code class="function">nm_connection_verify()</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMRemoteConnection]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMRemoteConnection]</span></p> </div> </div> <hr> @@ -3464,7 +3464,7 @@ nm_client_get_connection_by_id (<em class="parameter"><code><a class="link" href matching object was found.</p> <p>The connection is as received from D-Bus and might not validate according to <a class="link" href="NMConnection.html#nm-connection-verify" title="nm_connection_verify ()"><code class="function">nm_connection_verify()</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -3503,7 +3503,7 @@ nm_client_get_connection_by_path (<em class="parameter"><code><a class="link" hr not known</p> <p>The connection is as received from D-Bus and might not validate according to <a class="link" href="NMConnection.html#nm-connection-verify" title="nm_connection_verify ()"><code class="function">nm_connection_verify()</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -3542,7 +3542,7 @@ nm_client_get_connection_by_uuid (<em class="parameter"><code><a class="link" hr not known</p> <p>The connection is as received from D-Bus and might not validate according to <a class="link" href="NMConnection.html#nm-connection-verify" title="nm_connection_verify ()"><code class="function">nm_connection_verify()</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -3657,7 +3657,7 @@ nm_client_add_connection_finish (<em class="parameter"><code><a class="link" hre <p>the new <a class="link" href="NMRemoteConnection.html" title="NMRemoteConnection"><span class="type">NMRemoteConnection</span></a> on success, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on failure, in which case <em class="parameter"><code>error</code></em> will be set. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -3768,7 +3768,7 @@ nm_client_add_connection2_finish (<em class="parameter"><code><a class="link" hr from <code class="function">AddConnection2()</code>. If you care about the output result, then the "ignore_out_result" parameter of <a class="link" href="NMClient.html#nm-client-add-connection2" title="nm_client_add_connection2 ()"><code class="function">nm_client_add_connection2()</code></a> must not be set to <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>error</p></td> @@ -3782,7 +3782,7 @@ parameter of <a class="link" href="NMClient.html#nm-client-add-connection2" titl <a name="nm-client-add-connection2-finish.returns"></a><h4>Returns</h4> <p>on success, a pointer to the added <a class="link" href="NMRemoteConnection.html" title="NMRemoteConnection"><span class="type">NMRemoteConnection</span></a>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.20</p> </div> @@ -3834,7 +3834,7 @@ filenames that failed to load.</p> <td class="parameter_name"><p>failures</p></td> <td class="parameter_description"><p>on return, a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of filenames that failed to load. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>cancellable</p></td> @@ -3945,7 +3945,7 @@ nm_client_load_connections_finish (<em class="parameter"><code><a class="link" h <td class="parameter_name"><p>failures</p></td> <td class="parameter_description"><p>on return, a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of filenames that failed to load. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> zero-terminated=1]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> zero-terminated=1]</span></td> </tr> <tr> <td class="parameter_name"><p>result</p></td> @@ -4181,7 +4181,7 @@ nm_client_get_dns_configuration (<em class="parameter"><code><a class="link" hre containing <a class="link" href="NMClient.html#NMDnsEntry"><span class="type">NMDnsEntry</span></a> elements or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> in case the value is not available. The returned array is owned by the <a class="link" href="NMClient.html" title="NMClient"><span class="type">NMClient</span></a> object and should not be modified. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMDnsEntry]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMDnsEntry]</span></p> </div> <p class="since">Since: 1.6</p> </div> @@ -4211,7 +4211,7 @@ nm_client_get_checkpoints (<em class="parameter"><code><a class="link" href="NMC <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> containing all the <a class="link" href="NMCheckpoint.html" title="NMCheckpoint"><span class="type">NMCheckpoint</span></a>. The returned array is owned by the <a class="link" href="NMClient.html" title="NMClient"><span class="type">NMClient</span></a> object and should not be modified. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMCheckpoint]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMCheckpoint]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -4323,7 +4323,7 @@ nm_client_checkpoint_create_finish (<em class="parameter"><code><a class="link" <p>the new <a class="link" href="NMCheckpoint.html" title="NMCheckpoint"><span class="type">NMCheckpoint</span></a> on success, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on failure, in which case <em class="parameter"><code>error</code></em> will be set. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -4510,7 +4510,7 @@ nm_client_checkpoint_rollback_finish (<em class="parameter"><code><a class="link <p>an hash table of devices and results. Devices are represented by their original D-Bus path; each result is a <a class="link" href="libnm-nm-dbus-interface.html#NMRollbackResult" title="enum NMRollbackResult"><span class="type">NMRollbackResult</span></a>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8 guint32]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8 guint32]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -4842,7 +4842,7 @@ nm_client_dbus_call_finish (<em class="parameter"><code><a class="link" href="NM <div class="refsect3"> <a name="nm-client-dbus-call-finish.returns"></a><h4>Returns</h4> <p>the result <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.24</p> </div> @@ -5352,6 +5352,6 @@ operation succeeded, but the object that was allegedly created (eg, </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMConnection.html b/docs/libnm/html/NMConnection.html index 44e1f9b..c652965 100644 --- a/docs/libnm/html/NMConnection.html +++ b/docs/libnm/html/NMConnection.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="ch03.html" title="Connection and Setting API Reference"> <link rel="next" href="NMSimpleConnection.html" title="NMSimpleConnection"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -660,7 +660,7 @@ the setting object's reference count.</p> <tr> <td class="parameter_name"><p>setting</p></td> <td class="parameter_description"><p>the <a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> to add to the connection object. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -731,7 +731,7 @@ to the <a class="link" href="NMConnection.html" title="NMConnection"><span class <a name="nm-connection-get-setting.returns"></a><h4>Returns</h4> <p>the <a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a>, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if no setting of that type was previously added to the <a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -768,7 +768,7 @@ the <a class="link" href="NMConnection.html" title="NMConnection"><span class="t <a name="nm-connection-get-setting-by-name.returns"></a><h4>Returns</h4> <p>the <a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a>, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if no setting with that name was previously added to the <a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -806,7 +806,7 @@ marshalling over D-Bus or otherwise serializing.</p> <a name="nm-connection-to-dbus.returns"></a><h4>Returns</h4> <p>a new floating <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> describing the connection, its settings, and each setting's properties. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1178,7 +1178,7 @@ return points to an allocated <a href="https://developer.gnome.org/glib/unstable secrets of the <a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> which may be required; the caller owns the array and must free the array itself with <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#g-ptr-array-free"><code class="function">g_ptr_array_free()</code></a>, but not free its elements. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The caller owns the data container, but not the data inside it."><span class="acronym">transfer container</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Free data container after the code is done."><span class="acronym">transfer container</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -1314,7 +1314,7 @@ failed (tried to update secrets for a setting that doesn't exist, etc)</p> nm_connection_set_path (<em class="parameter"><code><a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> *connection</code></em>, <em class="parameter"><code>const <span class="type">char</span> *path</code></em>);</pre> <p>Sets the D-Bus path of the connection. This property is not serialized, and -is only for the reference of the caller. Sets the <a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection--path"><span class="type">“path”</span></a> +is only for the reference of the caller. Sets the <span class="type">“path”</span> property.</p> <div class="refsect3"> <a name="nm-connection-set-path.parameters"></a><h4>Parameters</h4> @@ -1513,7 +1513,7 @@ nm_connection_get_settings (<em class="parameter"><code><a class="link" href="NM <em class="parameter"><code>connection</code></em> . If the connection has no settings, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> is returned. </p> -<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_length][<acronym title="The caller owns the data container, but not the data inside it."><span class="acronym">transfer container</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_length][<acronym title="Free data container after the code is done."><span class="acronym">transfer container</span></acronym>]</span></p> </div> <p class="since">Since: 1.10</p> </div> @@ -1680,7 +1680,7 @@ Eg, "VLAN (eth1.1)".</p> 's device, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if <em class="parameter"><code>connection</code></em> is not a virtual connection type. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -1707,7 +1707,7 @@ nm_connection_get_setting_802_1x (<em class="parameter"><code><a class="link" hr <div class="refsect3"> <a name="nm-connection-get-setting-802-1x.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSetting8021x.html" title="NMSetting8021x"><span class="type">NMSetting8021x</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1734,7 +1734,7 @@ nm_connection_get_setting_bluetooth (<em class="parameter"><code><a class="link" <div class="refsect3"> <a name="nm-connection-get-setting-bluetooth.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingBluetooth.html" title="NMSettingBluetooth"><span class="type">NMSettingBluetooth</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1761,7 +1761,7 @@ nm_connection_get_setting_bond (<em class="parameter"><code><a class="link" href <div class="refsect3"> <a name="nm-connection-get-setting-bond.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingBond.html" title="NMSettingBond"><span class="type">NMSettingBond</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1788,7 +1788,7 @@ nm_connection_get_setting_team (<em class="parameter"><code><a class="link" href <div class="refsect3"> <a name="nm-connection-get-setting-team.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingTeam.html" title="NMSettingTeam"><span class="type">NMSettingTeam</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1815,7 +1815,7 @@ nm_connection_get_setting_team_port (<em class="parameter"><code><a class="link" <div class="refsect3"> <a name="nm-connection-get-setting-team-port.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingTeamPort.html" title="NMSettingTeamPort"><span class="type">NMSettingTeamPort</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1842,7 +1842,7 @@ nm_connection_get_setting_bridge (<em class="parameter"><code><a class="link" hr <div class="refsect3"> <a name="nm-connection-get-setting-bridge.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingBridge.html" title="NMSettingBridge"><span class="type">NMSettingBridge</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1869,7 +1869,7 @@ nm_connection_get_setting_bridge_port (<em class="parameter"><code><a class="lin <div class="refsect3"> <a name="nm-connection-get-setting-bridge-port.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingBridgePort.html" title="NMSettingBridgePort"><span class="type">NMSettingBridgePort</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1896,7 +1896,7 @@ nm_connection_get_setting_cdma (<em class="parameter"><code><a class="link" href <div class="refsect3"> <a name="nm-connection-get-setting-cdma.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingCdma.html" title="NMSettingCdma"><span class="type">NMSettingCdma</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1923,7 +1923,7 @@ nm_connection_get_setting_connection (<em class="parameter"><code><a class="link <div class="refsect3"> <a name="nm-connection-get-setting-connection.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingConnection.html" title="NMSettingConnection"><span class="type">NMSettingConnection</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1950,7 +1950,7 @@ nm_connection_get_setting_dcb (<em class="parameter"><code><a class="link" href= <div class="refsect3"> <a name="nm-connection-get-setting-dcb.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingDcb.html" title="NMSettingDcb"><span class="type">NMSettingDcb</span></a> if the connection contains one, otherwise NULL. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1977,7 +1977,7 @@ nm_connection_get_setting_dummy (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-connection-get-setting-dummy.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingDummy.html" title="NMSettingDummy"><span class="type">NMSettingDummy</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.8</p> </div> @@ -2005,7 +2005,7 @@ nm_connection_get_setting_generic (<em class="parameter"><code><a class="link" h <div class="refsect3"> <a name="nm-connection-get-setting-generic.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingGeneric.html" title="NMSettingGeneric"><span class="type">NMSettingGeneric</span></a> if the connection contains one, otherwise NULL. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2032,7 +2032,7 @@ nm_connection_get_setting_gsm (<em class="parameter"><code><a class="link" href= <div class="refsect3"> <a name="nm-connection-get-setting-gsm.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingGsm.html" title="NMSettingGsm"><span class="type">NMSettingGsm</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2059,7 +2059,7 @@ nm_connection_get_setting_infiniband (<em class="parameter"><code><a class="link <div class="refsect3"> <a name="nm-connection-get-setting-infiniband.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingInfiniband.html" title="NMSettingInfiniband"><span class="type">NMSettingInfiniband</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2086,7 +2086,7 @@ nm_connection_get_setting_ip_tunnel (<em class="parameter"><code><a class="link" <div class="refsect3"> <a name="nm-connection-get-setting-ip-tunnel.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingIPTunnel.html" title="NMSettingIPTunnel"><span class="type">NMSettingIPTunnel</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -2118,7 +2118,7 @@ majority of IPv4-setting-related methods are on that type, not <a name="nm-connection-get-setting-ip4-config.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingIP4Config.html" title="NMSettingIP4Config"><span class="type">NMSettingIP4Config</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="Override the parsed C type with given type."><span class="acronym">type</span></acronym> NMSettingIP4Config][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Override the parsed C type with given type."><span class="acronym">type</span></acronym> NMSettingIP4Config][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2149,7 +2149,7 @@ majority of IPv6-setting-related methods are on that type, not <a name="nm-connection-get-setting-ip6-config.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingIP6Config.html" title="NMSettingIP6Config"><span class="type">NMSettingIP6Config</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="Override the parsed C type with given type."><span class="acronym">type</span></acronym> NMSettingIP6Config][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Override the parsed C type with given type."><span class="acronym">type</span></acronym> NMSettingIP6Config][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2176,7 +2176,7 @@ nm_connection_get_setting_macsec (<em class="parameter"><code><a class="link" hr <div class="refsect3"> <a name="nm-connection-get-setting-macsec.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingMacsec.html" title="NMSettingMacsec"><span class="type">NMSettingMacsec</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.6</p> </div> @@ -2204,7 +2204,7 @@ nm_connection_get_setting_macvlan (<em class="parameter"><code><a class="link" h <div class="refsect3"> <a name="nm-connection-get-setting-macvlan.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingMacvlan.html" title="NMSettingMacvlan"><span class="type">NMSettingMacvlan</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -2232,7 +2232,7 @@ nm_connection_get_setting_olpc_mesh (<em class="parameter"><code><a class="link" <div class="refsect3"> <a name="nm-connection-get-setting-olpc-mesh.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingOlpcMesh.html" title="NMSettingOlpcMesh"><span class="type">NMSettingOlpcMesh</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2259,7 +2259,7 @@ nm_connection_get_setting_ovs_bridge (<em class="parameter"><code><a class="link <div class="refsect3"> <a name="nm-connection-get-setting-ovs-bridge.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingOvsBridge.html" title="NMSettingOvsBridge"><span class="type">NMSettingOvsBridge</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.10</p> </div> @@ -2288,7 +2288,7 @@ nm_connection_get_setting_ovs_interface <div class="refsect3"> <a name="nm-connection-get-setting-ovs-interface.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingOvsInterface.html" title="NMSettingOvsInterface"><span class="type">NMSettingOvsInterface</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.10</p> </div> @@ -2316,7 +2316,7 @@ nm_connection_get_setting_ovs_patch (<em class="parameter"><code><a class="link" <div class="refsect3"> <a name="nm-connection-get-setting-ovs-patch.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingOvsPatch.html" title="NMSettingOvsPatch"><span class="type">NMSettingOvsPatch</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.10</p> </div> @@ -2344,7 +2344,7 @@ nm_connection_get_setting_ovs_port (<em class="parameter"><code><a class="link" <div class="refsect3"> <a name="nm-connection-get-setting-ovs-port.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingOvsPort.html" title="NMSettingOvsPort"><span class="type">NMSettingOvsPort</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.10</p> </div> @@ -2372,7 +2372,7 @@ nm_connection_get_setting_ppp (<em class="parameter"><code><a class="link" href= <div class="refsect3"> <a name="nm-connection-get-setting-ppp.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingPpp.html" title="NMSettingPpp"><span class="type">NMSettingPpp</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2399,7 +2399,7 @@ nm_connection_get_setting_pppoe (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-connection-get-setting-pppoe.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingPppoe.html" title="NMSettingPppoe"><span class="type">NMSettingPppoe</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2426,7 +2426,7 @@ nm_connection_get_setting_proxy (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-connection-get-setting-proxy.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingProxy.html" title="NMSettingProxy"><span class="type">NMSettingProxy</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.6</p> </div> @@ -2454,7 +2454,7 @@ nm_connection_get_setting_serial (<em class="parameter"><code><a class="link" hr <div class="refsect3"> <a name="nm-connection-get-setting-serial.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingSerial.html" title="NMSettingSerial"><span class="type">NMSettingSerial</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2481,7 +2481,7 @@ nm_connection_get_setting_tc_config (<em class="parameter"><code><a class="link" <div class="refsect3"> <a name="nm-connection-get-setting-tc-config.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingTCConfig.html" title="NMSettingTCConfig"><span class="type">NMSettingTCConfig</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -2509,7 +2509,7 @@ nm_connection_get_setting_tun (<em class="parameter"><code><a class="link" href= <div class="refsect3"> <a name="nm-connection-get-setting-tun.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingTun.html" title="NMSettingTun"><span class="type">NMSettingTun</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -2537,7 +2537,7 @@ nm_connection_get_setting_vpn (<em class="parameter"><code><a class="link" href= <div class="refsect3"> <a name="nm-connection-get-setting-vpn.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingVpn.html" title="NMSettingVpn"><span class="type">NMSettingVpn</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2564,7 +2564,7 @@ nm_connection_get_setting_wimax (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-connection-get-setting-wimax.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingWimax.html" title="NMSettingWimax"><span class="type">NMSettingWimax</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2591,7 +2591,7 @@ nm_connection_get_setting_adsl (<em class="parameter"><code><a class="link" href <div class="refsect3"> <a name="nm-connection-get-setting-adsl.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingAdsl.html" title="NMSettingAdsl"><span class="type">NMSettingAdsl</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2618,7 +2618,7 @@ nm_connection_get_setting_wired (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-connection-get-setting-wired.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingWired.html" title="NMSettingWired"><span class="type">NMSettingWired</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2645,7 +2645,7 @@ nm_connection_get_setting_wireless (<em class="parameter"><code><a class="link" <div class="refsect3"> <a name="nm-connection-get-setting-wireless.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingWireless.html" title="NMSettingWireless"><span class="type">NMSettingWireless</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2673,7 +2673,7 @@ nm_connection_get_setting_wireless_security <div class="refsect3"> <a name="nm-connection-get-setting-wireless-security.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingWirelessSecurity.html" title="NMSettingWirelessSecurity"><span class="type">NMSettingWirelessSecurity</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2700,7 +2700,7 @@ nm_connection_get_setting_vlan (<em class="parameter"><code><a class="link" href <div class="refsect3"> <a name="nm-connection-get-setting-vlan.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingVlan.html" title="NMSettingVlan"><span class="type">NMSettingVlan</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2727,7 +2727,7 @@ nm_connection_get_setting_vxlan (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-connection-get-setting-vxlan.returns"></a><h4>Returns</h4> <p>an <a class="link" href="NMSettingVxlan.html" title="NMSettingVxlan"><span class="type">NMSettingVxlan</span></a> if the connection contains one, otherwise <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -2861,6 +2861,6 @@ are agent owned will be serialized. Since: 1.20.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDevice.html b/docs/libnm/html/NMDevice.html index c1d5d86..c68cbeb 100644 --- a/docs/libnm/html/NMDevice.html +++ b/docs/libnm/html/NMDevice.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="next" href="NMDevice6Lowpan.html" title="NMDevice6Lowpan"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -452,10 +452,10 @@ </tr> <tr> <td class="function_type"> -<a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="returnvalue">NMLldpNeighbor</span></a> * +<span class="returnvalue">void</span> </td> <td class="function_name"> -<a class="link" href="NMDevice.html#nm-lldp-neighbor-new" title="nm_lldp_neighbor_new ()">nm_lldp_neighbor_new</a> <span class="c_punctuation">()</span> +<a class="link" href="NMDevice.html#nm-lldp-neighbor-ref" title="nm_lldp_neighbor_ref ()">nm_lldp_neighbor_ref</a> <span class="c_punctuation">()</span> </td> </tr> <tr> @@ -463,31 +463,31 @@ <span class="returnvalue">void</span> </td> <td class="function_name"> -<a class="link" href="NMDevice.html#nm-lldp-neighbor-ref" title="nm_lldp_neighbor_ref ()">nm_lldp_neighbor_ref</a> <span class="c_punctuation">()</span> +<a class="link" href="NMDevice.html#nm-lldp-neighbor-unref" title="nm_lldp_neighbor_unref ()">nm_lldp_neighbor_unref</a> <span class="c_punctuation">()</span> </td> </tr> <tr> <td class="function_type"> -<span class="returnvalue">void</span> +<span class="returnvalue">char</span> ** </td> <td class="function_name"> -<a class="link" href="NMDevice.html#nm-lldp-neighbor-unref" title="nm_lldp_neighbor_unref ()">nm_lldp_neighbor_unref</a> <span class="c_punctuation">()</span> +<a class="link" href="NMDevice.html#nm-lldp-neighbor-get-attr-names" title="nm_lldp_neighbor_get_attr_names ()">nm_lldp_neighbor_get_attr_names</a> <span class="c_punctuation">()</span> </td> </tr> <tr> <td class="function_type"> -<span class="returnvalue">char</span> ** +<a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="returnvalue">GVariant</span></a> * </td> <td class="function_name"> -<a class="link" href="NMDevice.html#nm-lldp-neighbor-get-attr-names" title="nm_lldp_neighbor_get_attr_names ()">nm_lldp_neighbor_get_attr_names</a> <span class="c_punctuation">()</span> +<a class="link" href="NMDevice.html#nm-lldp-neighbor-get-attr-value" title="nm_lldp_neighbor_get_attr_value ()">nm_lldp_neighbor_get_attr_value</a> <span class="c_punctuation">()</span> </td> </tr> <tr> <td class="function_type"> -<a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a> +<a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="returnvalue">NMLldpNeighbor</span></a> * </td> <td class="function_name"> -<a class="link" href="NMDevice.html#nm-lldp-neighbor-get-attr-string-value" title="nm_lldp_neighbor_get_attr_string_value ()">nm_lldp_neighbor_get_attr_string_value</a> <span class="c_punctuation">()</span> +<a class="link" href="NMDevice.html#nm-lldp-neighbor-new" title="nm_lldp_neighbor_new ()">nm_lldp_neighbor_new</a> <span class="c_punctuation">()</span> </td> </tr> <tr> @@ -495,22 +495,22 @@ <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a> </td> <td class="function_name"> -<a class="link" href="NMDevice.html#nm-lldp-neighbor-get-attr-uint-value" title="nm_lldp_neighbor_get_attr_uint_value ()">nm_lldp_neighbor_get_attr_uint_value</a> <span class="c_punctuation">()</span> +<a class="link" href="NMDevice.html#nm-lldp-neighbor-get-attr-string-value" title="nm_lldp_neighbor_get_attr_string_value ()">nm_lldp_neighbor_get_attr_string_value</a> <span class="c_punctuation">()</span> </td> </tr> <tr> -<td class="function_type">const <a href="https://developer.gnome.org/glib/unstable/glib-GVariantType.html#GVariantType"><span class="returnvalue">GVariantType</span></a> * +<td class="function_type"> +<a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a> </td> <td class="function_name"> -<a class="link" href="NMDevice.html#nm-lldp-neighbor-get-attr-type" title="nm_lldp_neighbor_get_attr_type ()">nm_lldp_neighbor_get_attr_type</a> <span class="c_punctuation">()</span> +<a class="link" href="NMDevice.html#nm-lldp-neighbor-get-attr-uint-value" title="nm_lldp_neighbor_get_attr_uint_value ()">nm_lldp_neighbor_get_attr_uint_value</a> <span class="c_punctuation">()</span> </td> </tr> <tr> -<td class="function_type"> -<a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="returnvalue">GVariant</span></a> * +<td class="function_type">const <a href="https://developer.gnome.org/glib/unstable/glib-GVariantType.html#GVariantType"><span class="returnvalue">GVariantType</span></a> * </td> <td class="function_name"> -<a class="link" href="NMDevice.html#nm-lldp-neighbor-get-attr-value" title="nm_lldp_neighbor_get_attr_value ()">nm_lldp_neighbor_get_attr_value</a> <span class="c_punctuation">()</span> +<a class="link" href="NMDevice.html#nm-lldp-neighbor-get-attr-type" title="nm_lldp_neighbor_get_attr_type ()">nm_lldp_neighbor_get_attr_type</a> <span class="c_punctuation">()</span> </td> </tr> </tbody> @@ -652,6 +652,10 @@ <td class="define_keyword">#define</td> <td class="function_name"><a class="link" href="NMDevice.html#NM-DEVICE-HW-ADDRESS:CAPS" title="NM_DEVICE_HW_ADDRESS">NM_DEVICE_HW_ADDRESS</a></td> </tr> +<tr> +<td class="datatype_keyword"> </td> +<td class="function_name"><a class="link" href="NMDevice.html#NMLldpNeighbor-struct" title="NMLldpNeighbor">NMLldpNeighbor</a></td> +</tr> </tbody> </table></div> </div> @@ -1178,7 +1182,7 @@ works with VPN connections.</p> <a name="nm-device-get-ip4-config.returns"></a><h4>Returns</h4> <p>the IPv4 <a class="link" href="NMIPConfig.html" title="NMIPConfig"><span class="type">NMIPConfig</span></a>, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the device is not activated. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1208,7 +1212,7 @@ works with VPN connections.</p> <a name="nm-device-get-dhcp4-config.returns"></a><h4>Returns</h4> <p>the IPv4 <a class="link" href="NMDhcpConfig.html" title="NMDhcpConfig"><span class="type">NMDhcpConfig</span></a>, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the device is not activated or not using DHCP. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1237,7 +1241,7 @@ works with VPN connections.</p> <div class="refsect3"> <a name="nm-device-get-ip6-config.returns"></a><h4>Returns</h4> <p>the IPv6 <a class="link" href="NMIPConfig.html" title="NMIPConfig"><span class="type">NMIPConfig</span></a> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the device is not activated. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1267,7 +1271,7 @@ works with VPN connections.</p> <a name="nm-device-get-dhcp6-config.returns"></a><h4>Returns</h4> <p>the IPv6 <a class="link" href="NMDhcpConfig.html" title="NMDhcpConfig"><span class="type">NMDhcpConfig</span></a>, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the device is not activated or not using DHCPv6. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1384,7 +1388,7 @@ nm_device_get_active_connection (<em class="parameter"><code><a class="link" hre <a name="nm-device-get-active-connection.returns"></a><h4>Returns</h4> <p>the <a class="link" href="NMActiveConnection.html" title="NMActiveConnection"><span class="type">NMActiveConnection</span></a> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the device is not part of an active connection. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1499,7 +1503,7 @@ nm_device_is_real (<em class="parameter"><code><a class="link" href="NMDevice.ht <a name="nm-device-is-real.returns"></a><h4>Returns</h4> <p> <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the device exists, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> if it is a placeholder device that could be automatically created by NetworkManager if one of its -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--available-connections"><span class="type">“available-connections”</span></a> was activated.</p> +<span class="type">“available-connections”</span> was activated.</p> </div> <p class="since">Since: 1.2</p> </div> @@ -1671,7 +1675,7 @@ nm_device_get_lldp_neighbors (<em class="parameter"><code><a class="link" href=" containing <a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a>s. This is the internal copy used by the device and must not be modified. The library never modifies the returned array and thus it is safe for callers to reference and keep using it. </p> -<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMLldpNeighbor][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMLldpNeighbor][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -1737,7 +1741,7 @@ devices in <em class="parameter"><code>devices</code></em> <div class="refsect3"> <a name="nm-device-disambiguate-names.returns"></a><h4>Returns</h4> <p>the device names. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> zero-terminated=1]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> zero-terminated=1]</span></p> </div> </div> <hr> @@ -1975,7 +1979,7 @@ the applied connection. </p></td> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error.</p> <p>The connection is as received from D-Bus and might not validate according to <a class="link" href="NMConnection.html#nm-connection-verify" title="nm_connection_verify ()"><code class="function">nm_connection_verify()</code></a>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -2079,7 +2083,7 @@ connection. </p></td> of error.</p> <p>The connection is as received from D-Bus and might not validate according to <a class="link" href="NMConnection.html#nm-connection-verify" title="nm_connection_verify ()"><code class="function">nm_connection_verify()</code></a>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -2378,7 +2382,7 @@ incompatible with the device. To get the full list of connections see </tr> <tr> <td class="parameter_name"><p>connections</p></td> -<td class="parameter_description"><p>an array of <a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-struct"><span class="type">NMConnections</span></a> to filter. </p></td> +<td class="parameter_description"><p>an array of <span class="type">NMConnections</span> to filter. </p></td> <td class="parameter_annotations"><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></td> </tr> </tbody> @@ -2387,13 +2391,13 @@ incompatible with the device. To get the full list of connections see <div class="refsect3"> <a name="nm-device-filter-connections.returns"></a><h4>Returns</h4> <p>an array of -<a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-struct"><span class="type">NMConnections</span></a> that could be activated with the given <em class="parameter"><code>device</code></em> +<span class="type">NMConnections</span> that could be activated with the given <em class="parameter"><code>device</code></em> . The array should be freed with <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#g-ptr-array-unref"><code class="function">g_ptr_array_unref()</code></a> when it is no longer required.</p> <p>WARNING: the transfer annotation for this function may not work correctly with bindings. See https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/305. You can filter the list yourself with <a class="link" href="NMDevice.html#nm-device-connection-valid" title="nm_device_connection_valid ()"><code class="function">nm_device_connection_valid()</code></a>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></p> </div> </div> <hr> @@ -2524,23 +2528,11 @@ that can be used on <em class="parameter"><code>device</code></em> </div> <hr> <div class="refsect2"> -<a name="nm-lldp-neighbor-new"></a><h3>nm_lldp_neighbor_new ()</h3> -<pre class="programlisting"><a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="returnvalue">NMLldpNeighbor</span></a> * -nm_lldp_neighbor_new (<em class="parameter"><code><span class="type">void</span></code></em>);</pre> -<p>Creates a new <a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> object.</p> -<div class="refsect3"> -<a name="nm-lldp-neighbor-new.returns"></a><h4>Returns</h4> -<p>the new <a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> -</div> -<p class="since">Since: 1.2</p> -</div> -<hr> -<div class="refsect2"> <a name="nm-lldp-neighbor-ref"></a><h3>nm_lldp_neighbor_ref ()</h3> <pre class="programlisting"><span class="returnvalue">void</span> nm_lldp_neighbor_ref (<em class="parameter"><code><a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> *neighbor</code></em>);</pre> <p>Increases the reference count of the object.</p> +<p>Since 1.32, ref-counting of <a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> is thread-safe.</p> <div class="refsect3"> <a name="nm-lldp-neighbor-ref.parameters"></a><h4>Parameters</h4> <div class="informaltable"><table class="informaltable" width="100%" border="0"> @@ -2565,6 +2557,7 @@ nm_lldp_neighbor_ref (<em class="parameter"><code><a class="link" href="NMDevice nm_lldp_neighbor_unref (<em class="parameter"><code><a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> *neighbor</code></em>);</pre> <p>Decreases the reference count of the object. If the reference count reaches zero, the object will be destroyed.</p> +<p>Since 1.32, ref-counting of <a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> is thread-safe.</p> <div class="refsect3"> <a name="nm-lldp-neighbor-unref.parameters"></a><h4>Parameters</h4> <div class="informaltable"><table class="informaltable" width="100%" border="0"> @@ -2607,7 +2600,66 @@ nm_lldp_neighbor_get_attr_names (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-lldp-neighbor-get-attr-names.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of attribute names. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> +</div> +<p class="since">Since: 1.2</p> +</div> +<hr> +<div class="refsect2"> +<a name="nm-lldp-neighbor-get-attr-value"></a><h3>nm_lldp_neighbor_get_attr_value ()</h3> +<pre class="programlisting"><a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="returnvalue">GVariant</span></a> * +nm_lldp_neighbor_get_attr_value (<em class="parameter"><code><a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> *neighbor</code></em>, + <em class="parameter"><code>const <span class="type">char</span> *name</code></em>);</pre> +<p>Gets the value (as a GVariant) of attribute with name <em class="parameter"><code>name</code></em> + on <em class="parameter"><code>neighbor</code></em> +</p> +<div class="refsect3"> +<a name="nm-lldp-neighbor-get-attr-value.parameters"></a><h4>Parameters</h4> +<div class="informaltable"><table class="informaltable" width="100%" border="0"> +<colgroup> +<col width="150px" class="parameters_name"> +<col class="parameters_description"> +<col width="200px" class="parameters_annotations"> +</colgroup> +<tbody> +<tr> +<td class="parameter_name"><p>neighbor</p></td> +<td class="parameter_description"><p>the <a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a></p></td> +<td class="parameter_annotations"> </td> +</tr> +<tr> +<td class="parameter_name"><p>name</p></td> +<td class="parameter_description"><p>the attribute name</p></td> +<td class="parameter_annotations"> </td> +</tr> +</tbody> +</table></div> +</div> +<div class="refsect3"> +<a name="nm-lldp-neighbor-get-attr-value.returns"></a><h4>Returns</h4> +<p>the value or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the attribute with <em class="parameter"><code>name</code></em> +was +not found. </p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> +</div> +<p class="since">Since: 1.18</p> +</div> +<hr> +<div class="refsect2"> +<a name="nm-lldp-neighbor-new"></a><h3>nm_lldp_neighbor_new ()</h3> +<pre class="programlisting"><a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="returnvalue">NMLldpNeighbor</span></a> * +nm_lldp_neighbor_new (<em class="parameter"><code><span class="type">void</span></code></em>);</pre> +<p>Creates a new <a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> object.</p> +<p>Note that <a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> has no public API for mutating +an instance. Also, libnm will not internally mutate a +once exposed object. They are guaranteed to be immutable. +Since 1.32, ref-counting is thread-safe.</p> +<p>This function is not useful, as there is no public API to +actually modify the (empty) instance.</p> +<div class="refsect3"> +<a name="nm-lldp-neighbor-new.returns"></a><h4>Returns</h4> +<p>the new <a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> object. </p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -2644,7 +2696,7 @@ nm_lldp_neighbor_get_attr_string_value <tr> <td class="parameter_name"><p>out_value</p></td> <td class="parameter_description"><p>on return, the attribute value. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -2663,7 +2715,7 @@ was found, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macr nm_lldp_neighbor_get_attr_uint_value (<em class="parameter"><code><a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> *neighbor</code></em>, <em class="parameter"><code>const <span class="type">char</span> *name</code></em>, <em class="parameter"><code><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a> *out_value</code></em>);</pre> -<p>Gets the uint value of attribute with name <em class="parameter"><code>name</code></em> +<p>Gets the uint32 value of attribute with name <em class="parameter"><code>name</code></em> on <em class="parameter"><code>neighbor</code></em> </p> <div class="refsect3"> @@ -2695,7 +2747,7 @@ nm_lldp_neighbor_get_attr_uint_value (<em class="parameter"><code><a class="link </div> <div class="refsect3"> <a name="nm-lldp-neighbor-get-attr-uint-value.returns"></a><h4>Returns</h4> -<p> <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if a uint attribute with name <em class="parameter"><code>name</code></em> +<p> <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if a uint32 attribute with name <em class="parameter"><code>name</code></em> was found, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> otherwise</p> </div> <p class="since">Since: 1.2</p> @@ -2736,46 +2788,6 @@ nm_lldp_neighbor_get_attr_type (<em class="parameter"><code><a class="link" href </div> <p class="since">Since: 1.2</p> </div> -<hr> -<div class="refsect2"> -<a name="nm-lldp-neighbor-get-attr-value"></a><h3>nm_lldp_neighbor_get_attr_value ()</h3> -<pre class="programlisting"><a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="returnvalue">GVariant</span></a> * -nm_lldp_neighbor_get_attr_value (<em class="parameter"><code><a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a> *neighbor</code></em>, - <em class="parameter"><code>const <span class="type">char</span> *name</code></em>);</pre> -<p>Gets the value (as a GVariant) of attribute with name <em class="parameter"><code>name</code></em> - on <em class="parameter"><code>neighbor</code></em> -</p> -<div class="refsect3"> -<a name="nm-lldp-neighbor-get-attr-value.parameters"></a><h4>Parameters</h4> -<div class="informaltable"><table class="informaltable" width="100%" border="0"> -<colgroup> -<col width="150px" class="parameters_name"> -<col class="parameters_description"> -<col width="200px" class="parameters_annotations"> -</colgroup> -<tbody> -<tr> -<td class="parameter_name"><p>neighbor</p></td> -<td class="parameter_description"><p>the <a class="link" href="NMDevice.html#NMLldpNeighbor"><span class="type">NMLldpNeighbor</span></a></p></td> -<td class="parameter_annotations"> </td> -</tr> -<tr> -<td class="parameter_name"><p>name</p></td> -<td class="parameter_description"><p>the attribute name</p></td> -<td class="parameter_annotations"> </td> -</tr> -</tbody> -</table></div> -</div> -<div class="refsect3"> -<a name="nm-lldp-neighbor-get-attr-value.returns"></a><h4>Returns</h4> -<p>the value or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the attribute with <em class="parameter"><code>name</code></em> -was -not found. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> -</div> -<p class="since">Since: 1.18</p> -</div> </div> <div class="refsect1"> <a name="NMDevice.other_details"></a><h2>Types and Values</h2> @@ -2971,9 +2983,86 @@ not found. </p> <pre class="programlisting">#define NM_DEVICE_HW_ADDRESS "hw-address" </pre> </div> +<hr> +<div class="refsect2"> +<a name="NMLldpNeighbor-struct"></a><h3>NMLldpNeighbor</h3> +<pre class="programlisting">typedef struct _NMLldpNeighbor NMLldpNeighbor;</pre> +<p>Supported attributes are:</p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-CHASSIS-ID-TYPE:CAPS" title="NM_LLDP_ATTR_CHASSIS_ID_TYPE"><span class="type">NM_LLDP_ATTR_CHASSIS_ID_TYPE</span></a> (type: 'u')</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-CHASSIS-ID:CAPS" title="NM_LLDP_ATTR_CHASSIS_ID"><span class="type">NM_LLDP_ATTR_CHASSIS_ID</span></a> (type: 's')</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-DESTINATION:CAPS" title="NM_LLDP_ATTR_DESTINATION"><span class="type">NM_LLDP_ATTR_DESTINATION</span></a> (type: 's')</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-IEEE-802-1-PPVID:CAPS" title="NM_LLDP_ATTR_IEEE_802_1_PPVID"><span class="type">NM_LLDP_ATTR_IEEE_802_1_PPVID</span></a> (type: 'u'). This attribute only reports the first PPVID +and therefore it is deprecated in favor of NM_LLDP_ATTR_IEEE_802_1_PPVIDS which reports +all the PPVID.</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-IEEE-802-1-PPVID-FLAGS:CAPS" title="NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS"><span class="type">NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS</span></a> (type: 'u'). This attribute only reports the first PPVID +and therefore it is deprecated in favor of NM_LLDP_ATTR_IEEE_802_1_PPVIDS which reports +all the PPVID.</p></li> +<li class="listitem"> +<p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-IEEE-802-1-PPVIDS:CAPS" title="NM_LLDP_ATTR_IEEE_802_1_PPVIDS"><span class="type">NM_LLDP_ATTR_IEEE_802_1_PPVIDS</span></a> (type: 'aa{sv}')</p> +<p>An array of dictionaries where each element has keys:</p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "> +<li class="listitem"><p>flags (type: 'u')</p></li> +<li class="listitem"><p>ppvid (type: 'u')</p></li> +</ul></div> +</li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-IEEE-802-1-PVID:CAPS" title="NM_LLDP_ATTR_IEEE_802_1_PVID"><span class="type">NM_LLDP_ATTR_IEEE_802_1_PVID</span></a> (type: 'u')</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-IEEE-802-1-VID:CAPS" title="NM_LLDP_ATTR_IEEE_802_1_VID"><span class="type">NM_LLDP_ATTR_IEEE_802_1_VID</span></a> (type: 'u'). This attribute only reports the first VLAN +and therefore it is deprecated in favor of NM_LLDP_ATTR_IEEE_802_1_VLANS which reports +all the VLANs.</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-IEEE-802-1-VLAN-NAME:CAPS" title="NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME"><span class="type">NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME</span></a> (type: 's'). This attribute only reports the first VLAN +and therefore it is deprecated in favor of NM_LLDP_ATTR_IEEE_802_1_VLANS which reports +all the VLANs.</p></li> +<li class="listitem"> +<p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-IEEE-802-1-VLANS:CAPS" title="NM_LLDP_ATTR_IEEE_802_1_VLANS"><span class="type">NM_LLDP_ATTR_IEEE_802_1_VLANS</span></a> (type: 'aa{sv}')</p> +<p>An array of dictionaries where each element has keys:</p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "> +<li class="listitem"><p>name (type: 's')</p></li> +<li class="listitem"><p>vid (type: 'u')</p></li> +</ul></div> +</li> +<li class="listitem"> +<p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-IEEE-802-3-MAC-PHY-CONF:CAPS" title="NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF"><span class="type">NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF</span></a> (type: 'a{sv}')</p> +<p>Dictionary where each element has keys:</p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "> +<li class="listitem"><p>autoneg (type: 'u')</p></li> +<li class="listitem"><p>operational-mau-type (type: 'u')</p></li> +<li class="listitem"><p>pmd-autoneg-cap (type: 'u')</p></li> +</ul></div> +</li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-IEEE-802-3-MAX-FRAME-SIZE:CAPS" title="NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE"><span class="type">NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE</span></a> (type: 'u')</p></li> +<li class="listitem"> +<p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-IEEE-802-3-POWER-VIA-MDI:CAPS" title="NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI"><span class="type">NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI</span></a> (type: 'a{sv}')</p> +<p>Dictionary where each element has keys:</p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "> +<li class="listitem"><p>mdi-power-support (type: 'u')</p></li> +<li class="listitem"><p>power-class (type: 'u')</p></li> +<li class="listitem"><p>pse-power-pair (type: 'u')</p></li> +</ul></div> +</li> +<li class="listitem"> +<p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-MANAGEMENT-ADDRESSES:CAPS" title="NM_LLDP_ATTR_MANAGEMENT_ADDRESSES"><span class="type">NM_LLDP_ATTR_MANAGEMENT_ADDRESSES</span></a> (type: 'aa{sv}')</p> +<p>An array of dictionaries where each element has keys:</p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "> +<li class="listitem"><p>address (type: 'ay')</p></li> +<li class="listitem"><p>address-subtype (type: 'u')</p></li> +<li class="listitem"><p>interface-number (type: 'u')</p></li> +<li class="listitem"><p>interface-number-subtype (type: 'u')</p></li> +<li class="listitem"><p>object-id (type: 'ay')</p></li> +</ul></div> +</li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-PORT-DESCRIPTION:CAPS" title="NM_LLDP_ATTR_PORT_DESCRIPTION"><span class="type">NM_LLDP_ATTR_PORT_DESCRIPTION</span></a> (type: 's')</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-PORT-ID-TYPE:CAPS" title="NM_LLDP_ATTR_PORT_ID_TYPE"><span class="type">NM_LLDP_ATTR_PORT_ID_TYPE</span></a> (type: 'u')</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-PORT-ID:CAPS" title="NM_LLDP_ATTR_PORT_ID"><span class="type">NM_LLDP_ATTR_PORT_ID</span></a> (type: 's')</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-RAW:CAPS" title="NM_LLDP_ATTR_RAW"><span class="type">NM_LLDP_ATTR_RAW</span></a> (type: 'ay')</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-SYSTEM-CAPABILITIES:CAPS" title="NM_LLDP_ATTR_SYSTEM_CAPABILITIES"><span class="type">NM_LLDP_ATTR_SYSTEM_CAPABILITIES</span></a> (type: 'u')</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-SYSTEM-DESCRIPTION:CAPS" title="NM_LLDP_ATTR_SYSTEM_DESCRIPTION"><span class="type">NM_LLDP_ATTR_SYSTEM_DESCRIPTION</span></a> (type: 's')</p></li> +<li class="listitem"><p><a class="link" href="libnm-nm-dbus-interface.html#NM-LLDP-ATTR-SYSTEM-NAME:CAPS" title="NM_LLDP_ATTR_SYSTEM_NAME"><span class="type">NM_LLDP_ATTR_SYSTEM_NAME</span></a> (type: 's')</p></li> +</ul></div> +</div> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDevice6Lowpan.html b/docs/libnm/html/NMDevice6Lowpan.html index e111db8..d5d3772 100644 --- a/docs/libnm/html/NMDevice6Lowpan.html +++ b/docs/libnm/html/NMDevice6Lowpan.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDevice.html" title="NMDevice"> <link rel="next" href="NMDeviceAdsl.html" title="NMDeviceAdsl"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -104,7 +104,7 @@ nm_device_6lowpan_get_parent (<em class="parameter"><code><a class="link" href=" <div class="refsect3"> <a name="nm-device-6lowpan-get-parent.returns"></a><h4>Returns</h4> <p>the device's parent device. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -132,6 +132,6 @@ NM_DEPRECATED_IN_1_24_FOR ();</pre> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceAdsl.html b/docs/libnm/html/NMDeviceAdsl.html index b314c32..0e8a73a 100644 --- a/docs/libnm/html/NMDeviceAdsl.html +++ b/docs/libnm/html/NMDeviceAdsl.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDevice6Lowpan.html" title="NMDevice6Lowpan"> <link rel="next" href="NMDeviceBond.html" title="NMDeviceBond"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -102,6 +102,6 @@ nm_device_adsl_get_carrier (<em class="parameter"><code><a class="link" href="NM </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceBond.html b/docs/libnm/html/NMDeviceBond.html index fd2f4d3..bfff1b9 100644 --- a/docs/libnm/html/NMDeviceBond.html +++ b/docs/libnm/html/NMDeviceBond.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceAdsl.html" title="NMDeviceAdsl"> <link rel="next" href="NMDeviceBridge.html" title="NMDeviceBridge"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -203,6 +203,6 @@ copy used by the device, and must not be modified. </p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceBridge.html b/docs/libnm/html/NMDeviceBridge.html index dc35f55..53948c1 100644 --- a/docs/libnm/html/NMDeviceBridge.html +++ b/docs/libnm/html/NMDeviceBridge.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceBond.html" title="NMDeviceBond"> <link rel="next" href="NMDeviceBt.html" title="NMDeviceBt"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -203,6 +203,6 @@ copy used by the device, and must not be modified. </p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceBt.html b/docs/libnm/html/NMDeviceBt.html index 203f66f..576f152 100644 --- a/docs/libnm/html/NMDeviceBt.html +++ b/docs/libnm/html/NMDeviceBt.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceBridge.html" title="NMDeviceBridge"> <link rel="next" href="NMDeviceDummy.html" title="NMDeviceDummy"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -198,6 +198,6 @@ nm_device_bt_get_capabilities (<em class="parameter"><code><a class="link" href= </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceDummy.html b/docs/libnm/html/NMDeviceDummy.html index 0ec953c..6b20f59 100644 --- a/docs/libnm/html/NMDeviceDummy.html +++ b/docs/libnm/html/NMDeviceDummy.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceBt.html" title="NMDeviceBt"> <link rel="next" href="NMDeviceEthernet.html" title="NMDeviceEthernet"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -83,6 +83,6 @@ NM_DEPRECATED_IN_1_24_FOR ();</pre> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceEthernet.html b/docs/libnm/html/NMDeviceEthernet.html index 8d4f2af..69c6b37 100644 --- a/docs/libnm/html/NMDeviceEthernet.html +++ b/docs/libnm/html/NMDeviceEthernet.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceDummy.html" title="NMDeviceDummy"> <link rel="next" href="NMDeviceGeneric.html" title="NMDeviceGeneric"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -252,7 +252,7 @@ nm_device_ethernet_get_s390_subchannels <a name="nm-device-ethernet-get-s390-subchannels.returns"></a><h4>Returns</h4> <p>array of strings, each specifying one subchannel the s390 device uses to communicate to the host. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -291,6 +291,6 @@ one subchannel the s390 device uses to communicate to the host. </p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceGeneric.html b/docs/libnm/html/NMDeviceGeneric.html index 3adb441..ad57f2b 100644 --- a/docs/libnm/html/NMDeviceGeneric.html +++ b/docs/libnm/html/NMDeviceGeneric.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceEthernet.html" title="NMDeviceEthernet"> <link rel="next" href="NMDeviceInfiniband.html" title="NMDeviceInfiniband"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -119,6 +119,6 @@ device, and must not be modified.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceIPTunnel.html b/docs/libnm/html/NMDeviceIPTunnel.html index fcc97c2..b4fa295 100644 --- a/docs/libnm/html/NMDeviceIPTunnel.html +++ b/docs/libnm/html/NMDeviceIPTunnel.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceInfiniband.html" title="NMDeviceInfiniband"> <link rel="next" href="NMDeviceMacsec.html" title="NMDeviceMacsec"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -220,7 +220,7 @@ nm_device_ip_tunnel_get_parent (<em class="parameter"><code><a class="link" href <div class="refsect3"> <a name="nm-device-ip-tunnel-get-parent.returns"></a><h4>Returns</h4> <p>the device's parent device. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -590,6 +590,6 @@ nm_device_ip_tunnel_get_flags (<em class="parameter"><code><a class="link" href= </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceInfiniband.html b/docs/libnm/html/NMDeviceInfiniband.html index 2be02c0..6e035cc 100644 --- a/docs/libnm/html/NMDeviceInfiniband.html +++ b/docs/libnm/html/NMDeviceInfiniband.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceGeneric.html" title="NMDeviceGeneric"> <link rel="next" href="NMDeviceIPTunnel.html" title="NMDeviceIPTunnel"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -155,6 +155,6 @@ nm_device_infiniband_get_carrier (<em class="parameter"><code><a class="link" hr </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceMacsec.html b/docs/libnm/html/NMDeviceMacsec.html index b5bc353..e8b49b9 100644 --- a/docs/libnm/html/NMDeviceMacsec.html +++ b/docs/libnm/html/NMDeviceMacsec.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceIPTunnel.html" title="NMDeviceIPTunnel"> <link rel="next" href="NMDeviceMacvlan.html" title="NMDeviceMacvlan"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -247,7 +247,7 @@ nm_device_macsec_get_parent (<em class="parameter"><code><a class="link" href="N <div class="refsect3"> <a name="nm-device-macsec-get-parent.returns"></a><h4>Returns</h4> <p>the device's parent device. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.6</p> </div> @@ -676,6 +676,6 @@ nm_device_macsec_get_replay_protect (<em class="parameter"><code><a class="link" </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceMacvlan.html b/docs/libnm/html/NMDeviceMacvlan.html index 70be76f..21dd5f5 100644 --- a/docs/libnm/html/NMDeviceMacvlan.html +++ b/docs/libnm/html/NMDeviceMacvlan.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceMacsec.html" title="NMDeviceMacsec"> <link rel="next" href="NMDeviceModem.html" title="NMDeviceModem"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -139,7 +139,7 @@ nm_device_macvlan_get_parent (<em class="parameter"><code><a class="link" href=" <div class="refsect3"> <a name="nm-device-macvlan-get-parent.returns"></a><h4>Returns</h4> <p>the device's parent device. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -267,6 +267,6 @@ NM_DEPRECATED_IN_1_24_FOR ();</pre> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceModem.html b/docs/libnm/html/NMDeviceModem.html index 3bc2f5c..af31343 100644 --- a/docs/libnm/html/NMDeviceModem.html +++ b/docs/libnm/html/NMDeviceModem.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceMacvlan.html" title="NMDeviceMacvlan"> <link rel="next" href="NMDeviceOlpcMesh.html" title="NMDeviceOlpcMesh"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -291,6 +291,6 @@ nm_device_modem_get_apn (<em class="parameter"><code><a class="link" href="NMDev </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceOlpcMesh.html b/docs/libnm/html/NMDeviceOlpcMesh.html index e005a5b..d1c9e9e 100644 --- a/docs/libnm/html/NMDeviceOlpcMesh.html +++ b/docs/libnm/html/NMDeviceOlpcMesh.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceModem.html" title="NMDeviceModem"> <link rel="next" href="NMDeviceOvsBridge.html" title="NMDeviceOvsBridge"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -148,7 +148,7 @@ nm_device_olpc_mesh_get_companion (<em class="parameter"><code><a class="link" h <div class="refsect3"> <a name="nm-device-olpc-mesh-get-companion.returns"></a><h4>Returns</h4> <p>the companion of the device of <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -201,6 +201,6 @@ nm_device_olpc_mesh_get_active_channel </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceOvsBridge.html b/docs/libnm/html/NMDeviceOvsBridge.html index 3c5cbc5..3ac38e0 100644 --- a/docs/libnm/html/NMDeviceOvsBridge.html +++ b/docs/libnm/html/NMDeviceOvsBridge.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceOlpcMesh.html" title="NMDeviceOlpcMesh"> <link rel="next" href="NMDeviceOvsInterface.html" title="NMDeviceOvsInterface"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -107,6 +107,6 @@ copy used by the device, and must not be modified. </p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceOvsInterface.html b/docs/libnm/html/NMDeviceOvsInterface.html index e629de3..407048f 100644 --- a/docs/libnm/html/NMDeviceOvsInterface.html +++ b/docs/libnm/html/NMDeviceOvsInterface.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceOvsBridge.html" title="NMDeviceOvsBridge"> <link rel="next" href="NMDeviceOvsPort.html" title="NMDeviceOvsPort"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -40,6 +40,6 @@ </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceOvsPort.html b/docs/libnm/html/NMDeviceOvsPort.html index 5b479ca..bf62db1 100644 --- a/docs/libnm/html/NMDeviceOvsPort.html +++ b/docs/libnm/html/NMDeviceOvsPort.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceOvsInterface.html" title="NMDeviceOvsInterface"> <link rel="next" href="NMDevicePpp.html" title="NMDevicePpp"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -107,6 +107,6 @@ copy used by the device, and must not be modified. </p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDevicePpp.html b/docs/libnm/html/NMDevicePpp.html index 0dfb007..8485b5d 100644 --- a/docs/libnm/html/NMDevicePpp.html +++ b/docs/libnm/html/NMDevicePpp.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceOvsPort.html" title="NMDeviceOvsPort"> <link rel="next" href="NMDeviceTeam.html" title="NMDeviceTeam"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -40,6 +40,6 @@ </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceTeam.html b/docs/libnm/html/NMDeviceTeam.html index 79c161e..84a600b 100644 --- a/docs/libnm/html/NMDeviceTeam.html +++ b/docs/libnm/html/NMDeviceTeam.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDevicePpp.html" title="NMDevicePpp"> <link rel="next" href="NMDeviceTun.html" title="NMDeviceTun"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -248,6 +248,6 @@ device, and must not be modified.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceTun.html b/docs/libnm/html/NMDeviceTun.html index 9d41ed9..2cd9edc 100644 --- a/docs/libnm/html/NMDeviceTun.html +++ b/docs/libnm/html/NMDeviceTun.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceTeam.html" title="NMDeviceTeam"> <link rel="next" href="NMDeviceVeth.html" title="NMDeviceVeth"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -335,6 +335,6 @@ nm_device_tun_get_multi_queue (<em class="parameter"><code><a class="link" href= </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceVeth.html b/docs/libnm/html/NMDeviceVeth.html index dd03515..d972fb7 100644 --- a/docs/libnm/html/NMDeviceVeth.html +++ b/docs/libnm/html/NMDeviceVeth.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceTun.html" title="NMDeviceTun"> <link rel="next" href="NMDeviceVlan.html" title="NMDeviceVlan"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -88,7 +88,7 @@ nm_device_veth_get_peer (<em class="parameter"><code><a class="link" href="NMDev <div class="refsect3"> <a name="nm-device-veth-get-peer.returns"></a><h4>Returns</h4> <p>the device's peer device. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.30</p> </div> @@ -103,6 +103,6 @@ nm_device_veth_get_peer (<em class="parameter"><code><a class="link" href="NMDev </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceVlan.html b/docs/libnm/html/NMDeviceVlan.html index 463b421..301fc98 100644 --- a/docs/libnm/html/NMDeviceVlan.html +++ b/docs/libnm/html/NMDeviceVlan.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceVeth.html" title="NMDeviceVeth"> <link rel="next" href="NMDeviceVrf.html" title="NMDeviceVrf"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -185,7 +185,7 @@ nm_device_vlan_get_parent (<em class="parameter"><code><a class="link" href="NMD <div class="refsect3"> <a name="nm-device-vlan-get-parent.returns"></a><h4>Returns</h4> <p>the device's parent device. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -242,6 +242,6 @@ nm_device_vlan_get_vlan_id (<em class="parameter"><code><a class="link" href="NM </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceVrf.html b/docs/libnm/html/NMDeviceVrf.html index 8eef1ea..8681e7f 100644 --- a/docs/libnm/html/NMDeviceVrf.html +++ b/docs/libnm/html/NMDeviceVrf.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceVlan.html" title="NMDeviceVlan"> <link rel="next" href="NMDeviceVxlan.html" title="NMDeviceVxlan"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -102,6 +102,6 @@ nm_device_vrf_get_table (<em class="parameter"><code><a class="link" href="NMDev </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceVxlan.html b/docs/libnm/html/NMDeviceVxlan.html index 745d07a..62c1fba 100644 --- a/docs/libnm/html/NMDeviceVxlan.html +++ b/docs/libnm/html/NMDeviceVxlan.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceVrf.html" title="NMDeviceVrf"> <link rel="next" href="NMDeviceWifiP2P.html" title="NMDeviceWifiP2P"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -328,7 +328,7 @@ nm_device_vxlan_get_parent (<em class="parameter"><code><a class="link" href="NM <div class="refsect3"> <a name="nm-device-vxlan-get-parent.returns"></a><h4>Returns</h4> <p>the device's parent device. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -837,6 +837,6 @@ nm_device_vxlan_get_l3miss (<em class="parameter"><code><a class="link" href="NM </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceWifi.html b/docs/libnm/html/NMDeviceWifi.html index b889034..3965254 100644 --- a/docs/libnm/html/NMDeviceWifi.html +++ b/docs/libnm/html/NMDeviceWifi.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceWifiP2P.html" title="NMDeviceWifiP2P"> <link rel="next" href="NMDeviceWimax.html" title="NMDeviceWimax"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -361,7 +361,7 @@ nm_device_wifi_get_active_access_point <div class="refsect3"> <a name="nm-device-wifi-get-active-access-point.returns"></a><h4>Returns</h4> <p>the access point or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if none is active. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -397,7 +397,7 @@ nm_device_wifi_get_access_point_by_path <div class="refsect3"> <a name="nm-device-wifi-get-access-point-by-path.returns"></a><h4>Returns</h4> <p>the access point or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if none is found. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -775,6 +775,6 @@ set.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceWifiP2P.html b/docs/libnm/html/NMDeviceWifiP2P.html index e40f069..3ccd1f7 100644 --- a/docs/libnm/html/NMDeviceWifiP2P.html +++ b/docs/libnm/html/NMDeviceWifiP2P.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceVxlan.html" title="NMDeviceVxlan"> <link rel="next" href="NMDeviceWifi.html" title="NMDeviceWifi"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -163,7 +163,7 @@ nm_device_wifi_p2p_get_peer_by_path (<em class="parameter"><code><a class="link" <div class="refsect3"> <a name="nm-device-wifi-p2p-get-peer-by-path.returns"></a><h4>Returns</h4> <p>the peer or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if none is found. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -402,6 +402,6 @@ nm_device_wifi_p2p_stop_find_finish (<em class="parameter"><code><a class="link" </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceWimax.html b/docs/libnm/html/NMDeviceWimax.html index dea41ff..7104429 100644 --- a/docs/libnm/html/NMDeviceWimax.html +++ b/docs/libnm/html/NMDeviceWimax.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceWifi.html" title="NMDeviceWifi"> <link rel="next" href="NMDeviceWireGuard.html" title="NMDeviceWireGuard"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -217,7 +217,7 @@ nm_device_wimax_get_active_nsp (<em class="parameter"><code><a class="link" href <div class="refsect3"> <a name="nm-device-wimax-get-active-nsp.returns"></a><h4>Returns</h4> <p>the access point or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if none is active. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -256,7 +256,7 @@ nm_device_wimax_get_nsp_by_path (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-device-wimax-get-nsp-by-path.returns"></a><h4>Returns</h4> <p>the access point or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if none is found. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -504,6 +504,6 @@ nm_device_wimax_get_bsid (<em class="parameter"><code><a class="link" href="NMDe </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceWireGuard.html b/docs/libnm/html/NMDeviceWireGuard.html index f31103f..8e87bc7 100644 --- a/docs/libnm/html/NMDeviceWireGuard.html +++ b/docs/libnm/html/NMDeviceWireGuard.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceWimax.html" title="NMDeviceWimax"> <link rel="next" href="NMDeviceWpan.html" title="NMDeviceWpan"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -117,7 +117,7 @@ nm_device_wireguard_get_public_key (<em class="parameter"><code><a class="link" <div class="refsect3"> <a name="nm-device-wireguard-get-public-key.returns"></a><h4>Returns</h4> <p>the <a href="https://developer.gnome.org/glib/unstable/glib-Byte-Arrays.html#GBytes"><span class="type">GBytes</span></a> containing the 32-byte public key. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -200,6 +200,6 @@ See: ip-rule(8)</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDeviceWpan.html b/docs/libnm/html/NMDeviceWpan.html index 5455ddf..080a6dd 100644 --- a/docs/libnm/html/NMDeviceWpan.html +++ b/docs/libnm/html/NMDeviceWpan.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMDeviceWireGuard.html" title="NMDeviceWireGuard"> <link rel="next" href="NMActiveConnection.html" title="NMActiveConnection"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -83,6 +83,6 @@ NM_DEPRECATED_IN_1_24_FOR ();</pre> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMDhcpConfig.html b/docs/libnm/html/NMDhcpConfig.html index d0b5774..f4cc1bd 100644 --- a/docs/libnm/html/NMDhcpConfig.html +++ b/docs/libnm/html/NMDhcpConfig.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMIPConfig.html" title="NMIPConfig"> <link rel="next" href="NMCheckpoint.html" title="NMCheckpoint"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -141,7 +141,7 @@ nm_dhcp_config_get_options (<em class="parameter"><code><a class="link" href="NM <p>the <a href="https://developer.gnome.org/glib/unstable/glib-Hash-Tables.html#GHashTable"><span class="type">GHashTable</span></a> containing strings for keys and values. This is the internal copy used by the configuration, and must not be modified. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8 utf8]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8 utf8]</span></p> </div> </div> <hr> @@ -196,6 +196,6 @@ configuration, and must not be modified.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMIPConfig.html b/docs/libnm/html/NMIPConfig.html index 2c9c22b..b3d4adb 100644 --- a/docs/libnm/html/NMIPConfig.html +++ b/docs/libnm/html/NMIPConfig.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMWimaxNsp.html" title="NMWimaxNsp"> <link rel="next" href="NMDhcpConfig.html" title="NMDhcpConfig"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -199,7 +199,7 @@ nm_ip_config_get_gateway (<em class="parameter"><code><a class="link" href="NMIP <div class="refsect3"> <a name="nm-ip-config-get-gateway.returns"></a><h4>Returns</h4> <p>the IP address of the gateway. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -229,7 +229,7 @@ nm_ip_config_get_addresses (<em class="parameter"><code><a class="link" href="NM containing <a class="link" href="NMSettingIPConfig.html#NMIPAddress"><span class="type">NMIPAddress</span></a>es. This is the internal copy used by the configuration and must not be modified. The library never modifies the returned array and thus it is safe for callers to reference and keep using it. </p> -<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPAddress][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPAddress][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -259,7 +259,7 @@ nm_ip_config_get_routes (<em class="parameter"><code><a class="link" href="NMIPC <a class="link" href="NMSettingIPConfig.html#NMIPRoute"><span class="type">NMIPRoute</span></a>s. This is the internal copy used by the configuration, and must not be modified. The library never modifies the returned array and thus it is safe for callers to reference and keep using it. </p> -<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPRoute][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPRoute][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -286,7 +286,7 @@ nm_ip_config_get_nameservers (<em class="parameter"><code><a class="link" href=" <div class="refsect3"> <a name="nm-ip-config-get-nameservers.returns"></a><h4>Returns</h4> <p>the array of nameserver IP addresses. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -314,7 +314,7 @@ nm_ip_config_get_domains (<em class="parameter"><code><a class="link" href="NMIP <a name="nm-ip-config-get-domains.returns"></a><h4>Returns</h4> <p>the array of domains. (This is never <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, though it may be 0-length). </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -342,7 +342,7 @@ nm_ip_config_get_searches (<em class="parameter"><code><a class="link" href="NMI <a name="nm-ip-config-get-searches.returns"></a><h4>Returns</h4> <p>the array of DNS search strings. (This is never <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, though it may be 0-length). </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -370,7 +370,7 @@ nm_ip_config_get_wins_servers (<em class="parameter"><code><a class="link" href= <a name="nm-ip-config-get-wins-servers.returns"></a><h4>Returns</h4> <p>the arry of WINS server IP address strings. (This is never <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, though it may be 0-length.). </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> </div> @@ -426,6 +426,6 @@ nm_ip_config_get_wins_servers (<em class="parameter"><code><a class="link" href= </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMObject.html b/docs/libnm/html/NMObject.html index b022de3..32699b7 100644 --- a/docs/libnm/html/NMObject.html +++ b/docs/libnm/html/NMObject.html @@ -8,7 +8,7 @@ <link rel="up" href="ch02.html" title="Client Object API Reference"> <link rel="prev" href="NMSecretAgentOld.html" title="NMSecretAgentOld"> <link rel="next" href="libnm-nm-errors.html" title="nm-errors"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -133,7 +133,7 @@ object is still alive.</p> <p>the <a class="link" href="NMClient.html" title="NMClient"><span class="type">NMClient</span></a> cache in which the object can be found, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the object is no longer cached. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.24</p> </div> @@ -148,6 +148,6 @@ cached. </p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMRemoteConnection.html b/docs/libnm/html/NMRemoteConnection.html index f589f9e..84980e9 100644 --- a/docs/libnm/html/NMRemoteConnection.html +++ b/docs/libnm/html/NMRemoteConnection.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSimpleConnection.html" title="NMSimpleConnection"> <link rel="next" href="NMSetting.html" title="NMSetting"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -327,7 +327,7 @@ nm_remote_connection_update2_finish (<em class="parameter"><code><a class="link" <a name="nm-remote-connection-update2-finish.returns"></a><h4>Returns</h4> <p>on success, a <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> of type "a{sv}" with the result. On failure, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -793,7 +793,7 @@ not a simple property accessor.</p> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> of type <code class="literal">NM_VARIANT_TYPE_CONNECTION</code> containing <em class="parameter"><code>connection</code></em> 's secrets, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -887,7 +887,7 @@ nm_remote_connection_get_secrets_finish <p>a <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> of type <code class="literal">NM_VARIANT_TYPE_CONNECTION</code> containing <em class="parameter"><code>connection</code></em> 's secrets, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -1044,6 +1044,6 @@ user, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.ht </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSecretAgentOld.html b/docs/libnm/html/NMSecretAgentOld.html index 7ca3840..e5405a7 100644 --- a/docs/libnm/html/NMSecretAgentOld.html +++ b/docs/libnm/html/NMSecretAgentOld.html @@ -8,7 +8,7 @@ <link rel="up" href="ch02.html" title="Client Object API Reference"> <link rel="prev" href="NMClient.html" title="NMClient"> <link rel="next" href="NMObject.html" title="NMObject"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -365,7 +365,7 @@ something like this:</p> note that this object will be unrefed after the callback has returned, use <a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#g-object-ref"><code class="function">g_object_ref()</code></a>/<a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#g-object-unref"><code class="function">g_object_unref()</code></a> if you want to use this object after the callback has returned. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>secrets</p></td> @@ -422,7 +422,7 @@ should be called.</p> note that this object will be unrefed after the callback has returned, use <a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#g-object-ref"><code class="function">g_object_ref()</code></a>/<a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#g-object-unref"><code class="function">g_object_unref()</code></a> if you want to use this object after the callback has returned. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>error</p></td> @@ -469,7 +469,7 @@ should be called.</p> note that this object will be unrefed after the callback has returned, use <a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#g-object-ref"><code class="function">g_object_ref()</code></a>/<a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#g-object-unref"><code class="function">g_object_unref()</code></a> if you want to use this object after the callback has returned. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>error</p></td> @@ -511,7 +511,7 @@ nm_secret_agent_old_get_dbus_connection <p>the <a href="https://developer.gnome.org/gio/unstable/GDBusConnection.html#GDBusConnection-struct"><span class="type">GDBusConnection</span></a> used by the secret agent. You may either set this as construct property <a class="link" href="NMSecretAgentOld.html#NM-SECRET-AGENT-OLD-DBUS-CONNECTION:CAPS" title="NM_SECRET_AGENT_OLD_DBUS_CONNECTION"><code class="literal">NM_SECRET_AGENT_OLD_DBUS_CONNECTION</code></a>, or it will automatically set during initialization. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.24</p> </div> @@ -540,7 +540,7 @@ nm_secret_agent_old_get_main_context (<em class="parameter"><code><a class="link <p>the <a href="https://developer.gnome.org/glib/unstable/glib-The-Main-Event-Loop.html#GMainContext"><span class="type">GMainContext</span></a> instance associate with the instance. This is the <a href="https://developer.gnome.org/glib/unstable/glib-The-Main-Event-Loop.html#g-main-context-get-thread-default"><code class="function">g_main_context_get_thread_default()</code></a> at the time when creating the instance. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.24</p> </div> @@ -579,7 +579,7 @@ that all remains are cleaned up.</p> <p>a <a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#GObject-struct"><span class="type">GObject</span></a> that you may register a weak pointer to know that the <a href="https://developer.gnome.org/glib/unstable/glib-The-Main-Event-Loop.html#GMainContext"><span class="type">GMainContext</span></a> is still kept busy by <em class="parameter"><code>self</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.24</p> </div> @@ -1152,6 +1152,6 @@ of 3 characters. An example valid identifier is 'org.gnome.nm-applet' </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSetting.html b/docs/libnm/html/NMSetting.html index 5c00d03..3ca80cc 100644 --- a/docs/libnm/html/NMSetting.html +++ b/docs/libnm/html/NMSetting.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMRemoteConnection.html" title="NMRemoteConnection"> <link rel="next" href="NMSettingConnection.html" title="NMSettingConnection"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -513,7 +513,7 @@ nm_setting_duplicate (<em class="parameter"><code><a class="link" href="NMSettin <a name="nm-setting-duplicate.returns"></a><h4>Returns</h4> <p>a new <a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> containing the same properties and values as the source <a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -732,7 +732,7 @@ settings differ, on return a hash table mapping the differing keys to one or more <a class="link" href="NMSetting.html#NMSettingDiffResult" title="enum NMSettingDiffResult"><code class="literal">NMSettingDiffResult</code></a> values OR-ed together. If the settings do not differ, any hash table passed in is unmodified. If no hash table is passed in and the settings differ, a new one is created and returned. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8 guint32]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8 guint32]</span></td> </tr> </tbody> </table></div> @@ -939,7 +939,7 @@ nm_setting_option_get (<em class="parameter"><code><a class="link" href="NMSetti <a name="nm-setting-option-get.returns"></a><h4>Returns</h4> <p>the <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the option is not set. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.26.</p> </div> @@ -1170,7 +1170,7 @@ nm_setting_option_get_all_names (<em class="parameter"><code><a class="link" hre <p>A <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated array of key names. If no names are present, this returns <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. The returned array and the names are owned by <a class="link" href="NMSetting.html" title="NMSetting"><code class="literal">NMSetting</code></a> and might be invalidated by the next operation. </p> -<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_len zero-terminated=1][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_len zero-terminated=1][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.26</p> </div> @@ -1551,6 +1551,6 @@ example "ppp" or "802-11-wireless" or "802-3-ethernet".</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSetting6Lowpan.html b/docs/libnm/html/NMSetting6Lowpan.html index f179af2..a00b307 100644 --- a/docs/libnm/html/NMSetting6Lowpan.html +++ b/docs/libnm/html/NMSetting6Lowpan.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingConnection.html" title="NMSettingConnection"> <link rel="next" href="NMSetting8021x.html" title="NMSetting8021x"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -91,7 +91,7 @@ nm_setting_6lowpan_new (<em class="parameter"><code><span class="type">void</spa <div class="refsect3"> <a name="nm-setting-6lowpan-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSetting6Lowpan.html" title="NMSetting6Lowpan"><span class="type">NMSetting6Lowpan</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -138,6 +138,6 @@ nm_setting_6lowpan_get_parent (<em class="parameter"><code><a class="link" href= </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSetting8021x.html b/docs/libnm/html/NMSetting8021x.html index 9f3fbf5..8917e7b 100644 --- a/docs/libnm/html/NMSetting8021x.html +++ b/docs/libnm/html/NMSetting8021x.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSetting6Lowpan.html" title="NMSetting6Lowpan"> <link rel="next" href="NMSettingAdsl.html" title="NMSettingAdsl"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -1742,7 +1742,7 @@ of the network cannot be confirmed by the client.</p> <div class="refsect3"> <a name="nm-setting-802-1x-get-ca-cert-blob.returns"></a><h4>Returns</h4> <p>the CA certificate data. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2257,7 +2257,7 @@ authentication method.</p> <div class="refsect3"> <a name="nm-setting-802-1x-get-client-cert-blob.returns"></a><h4>Returns</h4> <p>the client certificate data. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2640,7 +2640,7 @@ of the network cannot be confirmed by the client.</p> <div class="refsect3"> <a name="nm-setting-802-1x-get-phase2-ca-cert-blob.returns"></a><h4>Returns</h4> <p>the "phase 2" CA certificate data. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -3163,7 +3163,7 @@ authentication method.</p> <div class="refsect3"> <a name="nm-setting-802-1x-get-phase2-client-cert-blob.returns"></a><h4>Returns</h4> <p>the "phase 2" client certificate data. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -3426,7 +3426,7 @@ nm_setting_802_1x_get_password_raw (<em class="parameter"><code><a class="link" <p>the password used by the authentication method as a UTF-8-encoded array of bytes, as specified by the <a class="link" href="NMSetting8021x.html#NMSetting8021x--password-raw" title="The “password-raw” property"><span class="type">“password-raw”</span></a> property. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -3571,7 +3571,7 @@ keys should always be encrypted with a private key password.</p> <div class="refsect3"> <a name="nm-setting-802-1x-get-private-key-blob.returns"></a><h4>Returns</h4> <p>the private key data. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -3867,7 +3867,7 @@ keys should always be encrypted with a private key password.</p> <div class="refsect3"> <a name="nm-setting-802-1x-get-phase2-private-key-blob.returns"></a><h4>Returns</h4> <p>the "phase 2" private key data. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -5288,6 +5288,6 @@ properties instead (sets ca_cert/ca_cert2 options for wpa_supplicant).</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingAdsl.html b/docs/libnm/html/NMSettingAdsl.html index 32f07ac..b2efd9e 100644 --- a/docs/libnm/html/NMSettingAdsl.html +++ b/docs/libnm/html/NMSettingAdsl.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSetting8021x.html" title="NMSetting8021x"> <link rel="next" href="NMSettingBluetooth.html" title="NMSettingBluetooth"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -576,6 +576,6 @@ nm_setting_adsl_get_password_flags (<em class="parameter"><code><a class="link" </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingBluetooth.html b/docs/libnm/html/NMSettingBluetooth.html index 5ef3cc4..234dd5b 100644 --- a/docs/libnm/html/NMSettingBluetooth.html +++ b/docs/libnm/html/NMSettingBluetooth.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingAdsl.html" title="NMSettingAdsl"> <link rel="next" href="NMSettingBond.html" title="NMSettingBond"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -153,7 +153,7 @@ nm_setting_bluetooth_new (<em class="parameter"><code><span class="type">void</s <div class="refsect3"> <a name="nm-setting-bluetooth-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingBluetooth.html" title="NMSettingBluetooth"><span class="type">NMSettingBluetooth</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -286,6 +286,6 @@ Area Networking connections to devices supporting the NAP profile.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingBond.html b/docs/libnm/html/NMSettingBond.html index 7dcaa60..980f930 100644 --- a/docs/libnm/html/NMSettingBond.html +++ b/docs/libnm/html/NMSettingBond.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingBluetooth.html" title="NMSettingBluetooth"> <link rel="next" href="NMSettingBridgePort.html" title="NMSettingBridgePort"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -289,7 +289,7 @@ nm_setting_bond_new (<em class="parameter"><code><span class="type">void</span>< <div class="refsect3"> <a name="nm-setting-bond-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingBond.html" title="NMSettingBond"><span class="type">NMSettingBond</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -357,14 +357,14 @@ such as during option iteration.</p> <td class="parameter_name"><p>out_name</p></td> <td class="parameter_description"><p>on return, the name of the bonding option; this value is owned by the setting and should not be modified. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>out_value</p></td> <td class="parameter_description"><p>on return, the value of the name of the bonding option; this value is owned by the setting and should not be modified. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -568,7 +568,7 @@ nm_setting_bond_get_valid_options (<em class="parameter"><code><a class="link" h <div class="refsect3"> <a name="nm-setting-bond-get-valid-options.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of strings of valid bond options. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -835,6 +835,6 @@ to the connection.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingBridge.html b/docs/libnm/html/NMSettingBridge.html index 3171089..645a338 100644 --- a/docs/libnm/html/NMSettingBridge.html +++ b/docs/libnm/html/NMSettingBridge.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingBridgePort.html" title="NMSettingBridgePort"> <link rel="next" href="NMSettingCdma.html" title="NMSettingCdma"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -567,7 +567,7 @@ nm_setting_bridge_new (<em class="parameter"><code><span class="type">void</span <div class="refsect3"> <a name="nm-setting-bridge-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingBridge.html" title="NMSettingBridge"><span class="type">NMSettingBridge</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -592,7 +592,7 @@ nm_setting_bridge_get_mac_address (<em class="parameter"><code><a class="link" h </div> <div class="refsect3"> <a name="nm-setting-bridge-get-mac-address.returns"></a><h4>Returns</h4> -<p> the <a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--mac-address"><span class="type">“mac-address”</span></a> property of the setting</p> +<p> the <span class="type">“mac-address”</span> property of the setting</p> </div> </div> <hr> @@ -617,7 +617,7 @@ nm_setting_bridge_get_stp (<em class="parameter"><code><a class="link" href="NMS </div> <div class="refsect3"> <a name="nm-setting-bridge-get-stp.returns"></a><h4>Returns</h4> -<p> the <a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--stp"><span class="type">“stp”</span></a> property of the setting</p> +<p> the <span class="type">“stp”</span> property of the setting</p> </div> </div> <hr> @@ -642,7 +642,7 @@ nm_setting_bridge_get_priority (<em class="parameter"><code><a class="link" href </div> <div class="refsect3"> <a name="nm-setting-bridge-get-priority.returns"></a><h4>Returns</h4> -<p> the <a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--priority"><span class="type">“priority”</span></a> property of the setting</p> +<p> the <span class="type">“priority”</span> property of the setting</p> </div> </div> <hr> @@ -667,7 +667,7 @@ nm_setting_bridge_get_forward_delay (<em class="parameter"><code><a class="link" </div> <div class="refsect3"> <a name="nm-setting-bridge-get-forward-delay.returns"></a><h4>Returns</h4> -<p> the <a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--forward-delay"><span class="type">“forward-delay”</span></a> property of the setting</p> +<p> the <span class="type">“forward-delay”</span> property of the setting</p> </div> </div> <hr> @@ -692,7 +692,7 @@ nm_setting_bridge_get_hello_time (<em class="parameter"><code><a class="link" hr </div> <div class="refsect3"> <a name="nm-setting-bridge-get-hello-time.returns"></a><h4>Returns</h4> -<p> the <a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--hello-time"><span class="type">“hello-time”</span></a> property of the setting</p> +<p> the <span class="type">“hello-time”</span> property of the setting</p> </div> </div> <hr> @@ -717,7 +717,7 @@ nm_setting_bridge_get_max_age (<em class="parameter"><code><a class="link" href= </div> <div class="refsect3"> <a name="nm-setting-bridge-get-max-age.returns"></a><h4>Returns</h4> -<p> the <a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--max-age"><span class="type">“max-age”</span></a> property of the setting</p> +<p> the <span class="type">“max-age”</span> property of the setting</p> </div> </div> <hr> @@ -742,7 +742,7 @@ nm_setting_bridge_get_ageing_time (<em class="parameter"><code><a class="link" h </div> <div class="refsect3"> <a name="nm-setting-bridge-get-ageing-time.returns"></a><h4>Returns</h4> -<p> the <a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--ageing-time"><span class="type">“ageing-time”</span></a> property of the setting</p> +<p> the <span class="type">“ageing-time”</span> property of the setting</p> </div> </div> <hr> @@ -942,7 +942,7 @@ nm_setting_bridge_get_vlan (<em class="parameter"><code><a class="link" href="NM <a name="nm-setting-bridge-get-vlan.returns"></a><h4>Returns</h4> <p>the VLAN at index <em class="parameter"><code>idx</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -1086,7 +1086,7 @@ and 4094.</p></td> <div class="refsect3"> <a name="nm-bridge-vlan-new.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingBridge.html#NMBridgeVlan"><span class="type">NMBridgeVlan</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -1167,7 +1167,7 @@ nm_bridge_vlan_new_clone (<em class="parameter"><code>const <a class="link" href <p>a clone of <em class="parameter"><code>vlan</code></em> . This instance is always unsealed. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -2081,6 +2081,6 @@ nm_setting_bridge_get_multicast_startup_query_interval </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingBridgePort.html b/docs/libnm/html/NMSettingBridgePort.html index 5e13ff1..dc7d9e7 100644 --- a/docs/libnm/html/NMSettingBridgePort.html +++ b/docs/libnm/html/NMSettingBridgePort.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingBond.html" title="NMSettingBond"> <link rel="next" href="NMSettingBridge.html" title="NMSettingBridge"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -214,7 +214,7 @@ nm_setting_bridge_port_new (<em class="parameter"><code><span class="type">void< <div class="refsect3"> <a name="nm-setting-bridge-port-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingBridgePort.html" title="NMSettingBridgePort"><span class="type">NMSettingBridgePort</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -383,7 +383,7 @@ nm_setting_bridge_port_get_vlan (<em class="parameter"><code><a class="link" hre <a name="nm-setting-bridge-port-get-vlan.returns"></a><h4>Returns</h4> <p>the VLAN at index <em class="parameter"><code>idx</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -583,6 +583,6 @@ range, represented as a couple of ids separated by a dash.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingCdma.html b/docs/libnm/html/NMSettingCdma.html index 29dc840..1b846de 100644 --- a/docs/libnm/html/NMSettingCdma.html +++ b/docs/libnm/html/NMSettingCdma.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingBridge.html" title="NMSettingBridge"> <link rel="next" href="NMSettingDcb.html" title="NMSettingDcb"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -420,6 +420,6 @@ username is required, it is specified here.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingConnection.html b/docs/libnm/html/NMSettingConnection.html index 35d8afb..9a77adb 100644 --- a/docs/libnm/html/NMSettingConnection.html +++ b/docs/libnm/html/NMSettingConnection.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSetting.html" title="NMSetting"> <link rel="next" href="NMSetting6Lowpan.html" title="NMSetting6Lowpan"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -2414,7 +2414,7 @@ provider, or <a class="link" href="NMSettingConnection.html#NMSettingConnection- <p>The UUID must be in the format "2815492f-7e56-435e-b2e9-246bd7cdc664" (ie, contains only hexadecimal characters and "-"). A suitable UUID may be generated by <a class="link" href="libnm-nm-utils.html#nm-utils-uuid-generate" title="nm_utils_uuid_generate ()"><code class="function">nm_utils_uuid_generate()</code></a> or -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-nm-utils.html#nm-utils-uuid-generate-from-string"><code class="function">nm_utils_uuid_generate_from_string()</code></a>.</p> +<code class="function">nm_utils_uuid_generate_from_string()</code>.</p> <p>Owner: NMSettingConnection</p> <p>Flags: Read / Write</p> <p>Default value: NULL</p> @@ -2454,6 +2454,6 @@ the change takes effect immediately.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingDcb.html b/docs/libnm/html/NMSettingDcb.html index e2facee..1f045b1 100644 --- a/docs/libnm/html/NMSettingDcb.html +++ b/docs/libnm/html/NMSettingDcb.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingCdma.html" title="NMSettingCdma"> <link rel="next" href="NMSettingDummy.html" title="NMSettingDummy"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -431,7 +431,7 @@ nm_setting_dcb_new (<em class="parameter"><code><span class="type">void</span></ <div class="refsect3"> <a name="nm-setting-dcb-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingDcb.html" title="NMSettingDcb"><span class="type">NMSettingDcb</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -1418,6 +1418,6 @@ which the priority is mapped.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingDummy.html b/docs/libnm/html/NMSettingDummy.html index 49d0609..7e66dd4 100644 --- a/docs/libnm/html/NMSettingDummy.html +++ b/docs/libnm/html/NMSettingDummy.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingDcb.html" title="NMSettingDcb"> <link rel="next" href="NMSettingEthtool.html" title="NMSettingEthtool"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -90,7 +90,7 @@ nm_setting_dummy_new (<em class="parameter"><code><span class="type">void</span> <div class="refsect3"> <a name="nm-setting-dummy-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingDummy.html" title="NMSettingDummy"><span class="type">NMSettingDummy</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.8</p> </div> @@ -111,6 +111,6 @@ nm_setting_dummy_new (<em class="parameter"><code><span class="type">void</span> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingEthtool.html b/docs/libnm/html/NMSettingEthtool.html index 0651e06..c59f299 100644 --- a/docs/libnm/html/NMSettingEthtool.html +++ b/docs/libnm/html/NMSettingEthtool.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingDummy.html" title="NMSettingDummy"> <link rel="next" href="NMSettingGeneric.html" title="NMSettingGeneric"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -211,7 +211,7 @@ nm_setting_ethtool_new (<em class="parameter"><code><span class="type">void</spa <div class="refsect3"> <a name="nm-setting-ethtool-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingEthtool.html" title="NMSettingEthtool"><span class="type">NMSettingEthtool</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -226,7 +226,7 @@ nm_setting_ethtool_get_optnames (<em class="parameter"><code><a class="link" hre <p>use <a class="link" href="NMSetting.html#nm-setting-option-get-all-names" title="nm_setting_option_get_all_names ()"><code class="function">nm_setting_option_get_all_names()</code></a> instead.</p> </div> <p>This returns all options names that are set. This includes the feature names -like <code class="literal">NM_ETHTOOL_OPTNAME_FEATURE_GRO</code>. See <a class="link" href="NMSettingEthtool.html#nm-ethtool-optname-is-feature" title="nm_ethtool_optname_is_feature ()"><code class="function">nm_ethtool_optname_is_feature()</code></a> to +like <a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-GRO:CAPS"><code class="literal">NM_ETHTOOL_OPTNAME_FEATURE_GRO</code></a>. See <a class="link" href="NMSettingEthtool.html#nm-ethtool-optname-is-feature" title="nm_ethtool_optname_is_feature ()"><code class="function">nm_ethtool_optname_is_feature()</code></a> to check whether the option name is valid for offload features.</p> <div class="refsect3"> <a name="nm-setting-ethtool-get-optnames.parameters"></a><h4>Parameters</h4> @@ -257,7 +257,7 @@ names or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros <em class="parameter"><code>setting</code></em> and may get invalidated when <em class="parameter"><code>setting</code></em> gets modified. </p> -<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> zero-terminated=1][<acronym title="The caller owns the data container, but not the data inside it."><span class="acronym">transfer container</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> zero-terminated=1][<acronym title="Free data container after the code is done."><span class="acronym">transfer container</span></acronym>]</span></p> </div> <p class="since">Since: 1.20</p> </div> @@ -388,6 +388,6 @@ nm_setting_ethtool_clear_features (<em class="parameter"><code><a class="link" h </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingGeneric.html b/docs/libnm/html/NMSettingGeneric.html index c0c4d7f..17224ab 100644 --- a/docs/libnm/html/NMSettingGeneric.html +++ b/docs/libnm/html/NMSettingGeneric.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingEthtool.html" title="NMSettingEthtool"> <link rel="next" href="NMSettingGsm.html" title="NMSettingGsm"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -81,7 +81,7 @@ optional properties that apply to "generic" devices (ie, devices that NetworkManager does not specifically recognize).</p> <p>There are currently no properties on this object; it exists only to be -the "connection type" setting on <a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-struct"><span class="type">NMConnections</span></a> for generic devices.</p> +the "connection type" setting on <span class="type">NMConnections</span> for generic devices.</p> </div> <div class="refsect1"> <a name="NMSettingGeneric.functions_details"></a><h2>Functions</h2> @@ -93,7 +93,7 @@ nm_setting_generic_new (<em class="parameter"><code><span class="type">void</spa <div class="refsect3"> <a name="nm-setting-generic-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingGeneric.html" title="NMSettingGeneric"><span class="type">NMSettingGeneric</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> </div> @@ -113,6 +113,6 @@ nm_setting_generic_new (<em class="parameter"><code><span class="type">void</spa </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingGsm.html b/docs/libnm/html/NMSettingGsm.html index ae3c093..652b6a4 100644 --- a/docs/libnm/html/NMSettingGsm.html +++ b/docs/libnm/html/NMSettingGsm.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingGeneric.html" title="NMSettingGeneric"> <link rel="next" href="NMSettingHostname.html" title="NMSettingHostname"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -971,6 +971,6 @@ username is required, it is specified here.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingHostname.html b/docs/libnm/html/NMSettingHostname.html index 5ad796a..9a660e9 100644 --- a/docs/libnm/html/NMSettingHostname.html +++ b/docs/libnm/html/NMSettingHostname.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingGsm.html" title="NMSettingGsm"> <link rel="next" href="NMSettingInfiniband.html" title="NMSettingInfiniband"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -131,7 +131,7 @@ nm_setting_hostname_new (<em class="parameter"><code><span class="type">void</sp <div class="refsect3"> <a name="nm-setting-hostname-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingHostname.html" title="NMSettingHostname"><span class="type">NMSettingHostname</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.30</p> </div> @@ -284,6 +284,6 @@ property.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingIP4Config.html b/docs/libnm/html/NMSettingIP4Config.html index 491abbf..328d05b 100644 --- a/docs/libnm/html/NMSettingIP4Config.html +++ b/docs/libnm/html/NMSettingIP4Config.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingInfiniband.html" title="NMSettingInfiniband"> <link rel="next" href="NMSettingIP6Config.html" title="NMSettingIP6Config"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -191,7 +191,7 @@ nm_setting_ip4_config_new (<em class="parameter"><code><span class="type">void</ <div class="refsect3"> <a name="nm-setting-ip4-config-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingIP4Config.html" title="NMSettingIP4Config"><span class="type">NMSettingIP4Config</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -421,6 +421,6 @@ If still unspecified, the DHCP option is not sent to the server.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingIP6Config.html b/docs/libnm/html/NMSettingIP6Config.html index 95fa1a7..b343cb7 100644 --- a/docs/libnm/html/NMSettingIP6Config.html +++ b/docs/libnm/html/NMSettingIP6Config.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingIP4Config.html" title="NMSettingIP4Config"> <link rel="next" href="NMSettingIPConfig.html" title="NMSettingIPConfig"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -243,7 +243,7 @@ nm_setting_ip6_config_new (<em class="parameter"><code><span class="type">void</ <div class="refsect3"> <a name="nm-setting-ip6-config-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingIP6Config.html" title="NMSettingIP6Config"><span class="type">NMSettingIP6Config</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -694,6 +694,6 @@ IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingIPConfig.html b/docs/libnm/html/NMSettingIPConfig.html index b2b0b8e..cb6465b 100644 --- a/docs/libnm/html/NMSettingIPConfig.html +++ b/docs/libnm/html/NMSettingIPConfig.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingIP6Config.html" title="NMSettingIP6Config"> <link rel="next" href="NMSettingIPTunnel.html" title="NMSettingIPTunnel"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -692,6 +692,22 @@ addressing, routing, and name service properties</p> </tr> <tr> <td class="function_type"> +<a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a> +</td> +<td class="function_name"> +<a class="link" href="NMSettingIPConfig.html#nm-ip-routing-rule-get-uid-range" title="nm_ip_routing_rule_get_uid_range ()">nm_ip_routing_rule_get_uid_range</a> <span class="c_punctuation">()</span> +</td> +</tr> +<tr> +<td class="function_type"> +<span class="returnvalue">void</span> +</td> +<td class="function_name"> +<a class="link" href="NMSettingIPConfig.html#nm-ip-routing-rule-set-uid-range" title="nm_ip_routing_rule_set_uid_range ()">nm_ip_routing_rule_set_uid_range</a> <span class="c_punctuation">()</span> +</td> +</tr> +<tr> +<td class="function_type"> <span class="returnvalue">int</span> </td> <td class="function_name"> @@ -1613,7 +1629,7 @@ nm_ip_address_new (<em class="parameter"><code><span class="type">int</span> fam <div class="refsect3"> <a name="nm-ip-address-new.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingIPConfig.html#NMIPAddress"><span class="type">NMIPAddress</span></a> object, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -1664,7 +1680,7 @@ correct size for <em class="parameter"><code>family</code></em> <div class="refsect3"> <a name="nm-ip-address-new-binary.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingIPConfig.html#NMIPAddress"><span class="type">NMIPAddress</span></a> object, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -1820,7 +1836,7 @@ nm_ip_address_dup (<em class="parameter"><code><a class="link" href="NMSettingIP <a name="nm-ip-address-dup.returns"></a><h4>Returns</h4> <p>a copy of <em class="parameter"><code>address</code></em> . </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2060,7 +2076,7 @@ nm_ip_address_get_attribute_names (<em class="parameter"><code><a class="link" h <div class="refsect3"> <a name="nm-ip-address-get-attribute-names.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of attribute names,. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2101,7 +2117,7 @@ on <em class="parameter"><code>address</code></em> , or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if <em class="parameter"><code>address</code></em> has no such attribute. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2135,7 +2151,7 @@ nm_ip_address_set_attribute (<em class="parameter"><code><a class="link" href="N <tr> <td class="parameter_name"><p>value</p></td> <td class="parameter_description"><p>the value. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -2198,7 +2214,7 @@ nm_ip_route_new (<em class="parameter"><code><span class="type">int</span> famil <div class="refsect3"> <a name="nm-ip-route-new.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingIPConfig.html#NMIPRoute"><span class="type">NMIPRoute</span></a> object, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2262,7 +2278,7 @@ point to buffers of the correct size for <em class="parameter"><code>family</cod <div class="refsect3"> <a name="nm-ip-route-new-binary.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingIPConfig.html#NMIPRoute"><span class="type">NMIPRoute</span></a> object, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2417,7 +2433,7 @@ nm_ip_route_dup (<em class="parameter"><code><a class="link" href="NMSettingIPCo <a name="nm-ip-route-dup.returns"></a><h4>Returns</h4> <p>a copy of <em class="parameter"><code>route</code></em> . </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2852,7 +2868,7 @@ nm_ip_route_get_attribute_names (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-ip-route-get-attribute-names.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of attribute names. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2893,7 +2909,7 @@ on <em class="parameter"><code>route</code></em> , or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if <em class="parameter"><code>route</code></em> has no such attribute. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2927,7 +2943,7 @@ nm_ip_route_set_attribute (<em class="parameter"><code><a class="link" href="NMS <tr> <td class="parameter_name"><p>value</p></td> <td class="parameter_description"><p>the value. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -3024,7 +3040,7 @@ nm_ip_routing_rule_new (<em class="parameter"><code><span class="type">int</span <a name="nm-ip-routing-rule-new.returns"></a><h4>Returns</h4> <p>a newly created rule instance with the provided address family. The instance is unsealed. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -3054,7 +3070,7 @@ nm_ip_routing_rule_new_clone (<em class="parameter"><code>const <a class="link" the same settings as <em class="parameter"><code>rule</code></em> . Note that the instance will always be unsealred. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -3085,7 +3101,7 @@ This is not thread-safe.</p> <p>the <em class="parameter"><code>self</code></em> argument with incremented reference count. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -3741,7 +3757,7 @@ nm_ip_routing_rule_get_from (<em class="parameter"><code>const <a class="link" h <a name="nm-ip-routing-rule-get-from.returns"></a><h4>Returns</h4> <p>the set from/src parameter or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, if no value is set. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -3834,7 +3850,7 @@ nm_ip_routing_rule_get_to (<em class="parameter"><code>const <a class="link" hre <a name="nm-ip-routing-rule-get-to.returns"></a><h4>Returns</h4> <p>the set to/dst parameter or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, if no value is set. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -3902,7 +3918,7 @@ nm_ip_routing_rule_get_iifname (<em class="parameter"><code>const <a class="link <div class="refsect3"> <a name="nm-ip-routing-rule-get-iifname.returns"></a><h4>Returns</h4> <p>the set iifname or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if unset. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -3963,7 +3979,7 @@ nm_ip_routing_rule_get_oifname (<em class="parameter"><code>const <a class="link <div class="refsect3"> <a name="nm-ip-routing-rule-get-oifname.returns"></a><h4>Returns</h4> <p>the set oifname or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if unset. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -4176,6 +4192,86 @@ unset.</p></td> </div> <hr> <div class="refsect2"> +<a name="nm-ip-routing-rule-get-uid-range"></a><h3>nm_ip_routing_rule_get_uid_range ()</h3> +<pre class="programlisting"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a> +nm_ip_routing_rule_get_uid_range (<em class="parameter"><code>const <a class="link" href="NMSettingIPConfig.html#NMIPRoutingRule"><span class="type">NMIPRoutingRule</span></a> *self</code></em>, + <em class="parameter"><code><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint32"><span class="type">guint32</span></a> *out_range_start</code></em>, + <em class="parameter"><code><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint32"><span class="type">guint32</span></a> *out_range_end</code></em>);</pre> +<div class="refsect3"> +<a name="nm-ip-routing-rule-get-uid-range.parameters"></a><h4>Parameters</h4> +<div class="informaltable"><table class="informaltable" width="100%" border="0"> +<colgroup> +<col width="150px" class="parameters_name"> +<col class="parameters_description"> +<col width="200px" class="parameters_annotations"> +</colgroup> +<tbody> +<tr> +<td class="parameter_name"><p>self</p></td> +<td class="parameter_description"><p>the <a class="link" href="NMSettingIPConfig.html#NMIPRoutingRule"><span class="type">NMIPRoutingRule</span></a> instance</p></td> +<td class="parameter_annotations"> </td> +</tr> +<tr> +<td class="parameter_name"><p>out_range_start</p></td> +<td class="parameter_description"><p>returns the start of the range +or 0 if the range is not set. </p></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> +</tr> +<tr> +<td class="parameter_name"><p>out_range_end</p></td> +<td class="parameter_description"><p>returns the end of the range +or 0 if the range is not set. </p></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> +</tr> +</tbody> +</table></div> +</div> +<div class="refsect3"> +<a name="nm-ip-routing-rule-get-uid-range.returns"></a><h4>Returns</h4> +<p> <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if a uid range is set.</p> +</div> +<p class="since">Since: 1.32</p> +</div> +<hr> +<div class="refsect2"> +<a name="nm-ip-routing-rule-set-uid-range"></a><h3>nm_ip_routing_rule_set_uid_range ()</h3> +<pre class="programlisting"><span class="returnvalue">void</span> +nm_ip_routing_rule_set_uid_range (<em class="parameter"><code><a class="link" href="NMSettingIPConfig.html#NMIPRoutingRule"><span class="type">NMIPRoutingRule</span></a> *self</code></em>, + <em class="parameter"><code><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint32"><span class="type">guint32</span></a> uid_range_start</code></em>, + <em class="parameter"><code><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint32"><span class="type">guint32</span></a> uid_range_end</code></em>);</pre> +<p>For a valid range, start must be less or equal to end. +If set to an invalid range, the range gets unset.</p> +<div class="refsect3"> +<a name="nm-ip-routing-rule-set-uid-range.parameters"></a><h4>Parameters</h4> +<div class="informaltable"><table class="informaltable" width="100%" border="0"> +<colgroup> +<col width="150px" class="parameters_name"> +<col class="parameters_description"> +<col width="200px" class="parameters_annotations"> +</colgroup> +<tbody> +<tr> +<td class="parameter_name"><p>self</p></td> +<td class="parameter_description"><p>the <a class="link" href="NMSettingIPConfig.html#NMIPRoutingRule"><span class="type">NMIPRoutingRule</span></a> instance</p></td> +<td class="parameter_annotations"> </td> +</tr> +<tr> +<td class="parameter_name"><p>uid_range_start</p></td> +<td class="parameter_description"><p>the uid_range start to set.</p></td> +<td class="parameter_annotations"> </td> +</tr> +<tr> +<td class="parameter_name"><p>uid_range_end</p></td> +<td class="parameter_description"><p>the uid_range start to set.</p></td> +<td class="parameter_annotations"> </td> +</tr> +</tbody> +</table></div> +</div> +<p class="since">Since: 1.32</p> +</div> +<hr> +<div class="refsect2"> <a name="nm-ip-routing-rule-cmp"></a><h3>nm_ip_routing_rule_cmp ()</h3> <pre class="programlisting"><span class="returnvalue">int</span> nm_ip_routing_rule_cmp (<em class="parameter"><code>const <a class="link" href="NMSettingIPConfig.html#NMIPRoutingRule"><span class="type">NMIPRoutingRule</span></a> *rule</code></em>, @@ -4288,7 +4384,7 @@ conversion. Currently, not extra arguments are supported. </p></td> <div class="refsect3"> <a name="nm-ip-routing-rule-from-string.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingIPConfig.html#NMIPRoutingRule"><span class="type">NMIPRoutingRule</span></a> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -4337,7 +4433,7 @@ conversion. Currently, not extra arguments are supported. </p></td> <div class="refsect3"> <a name="nm-ip-routing-rule-to-string.returns"></a><h4>Returns</h4> <p>the string representation or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -5051,7 +5147,7 @@ nm_setting_ip_config_get_address (<em class="parameter"><code><a class="link" hr <a name="nm-setting-ip-config-get-address.returns"></a><h4>Returns</h4> <p>the address at index <em class="parameter"><code>idx</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -5262,7 +5358,7 @@ nm_setting_ip_config_get_route (<em class="parameter"><code><a class="link" href <a name="nm-setting-ip-config-get-route.returns"></a><h4>Returns</h4> <p>the route at index <em class="parameter"><code>idx</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -5512,7 +5608,7 @@ nm_setting_ip_config_get_routing_rule (<em class="parameter"><code><a class="lin <a name="nm-setting-ip-config-get-routing-rule.returns"></a><h4>Returns</h4> <p>the routing rule at index <em class="parameter"><code>idx</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -5926,7 +6022,7 @@ nm_setting_ip_config_get_dhcp_reject_servers <a name="nm-setting-ip-config-get-dhcp-reject-servers.returns"></a><h4>Returns</h4> <p>A <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated array of DHCP reject servers. Even if no reject servers are configured, this always returns a non <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> value. </p> -<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_len zero-terminated=1][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_len zero-terminated=1][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.28</p> </div> @@ -6895,6 +6991,6 @@ of NetworkManager.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingIPTunnel.html b/docs/libnm/html/NMSettingIPTunnel.html index b81a7a3..6093e7d 100644 --- a/docs/libnm/html/NMSettingIPTunnel.html +++ b/docs/libnm/html/NMSettingIPTunnel.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingIPConfig.html" title="NMSettingIPConfig"> <link rel="next" href="NMSettingMacsec.html" title="NMSettingMacsec"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -330,7 +330,7 @@ nm_setting_ip_tunnel_new (<em class="parameter"><code><span class="type">void</s <div class="refsect3"> <a name="nm-setting-ip-tunnel-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingIPTunnel.html" title="NMSettingIPTunnel"><span class="type">NMSettingIPTunnel</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -964,6 +964,6 @@ packets inherit the TTL value.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingInfiniband.html b/docs/libnm/html/NMSettingInfiniband.html index 576342e..3df145c 100644 --- a/docs/libnm/html/NMSettingInfiniband.html +++ b/docs/libnm/html/NMSettingInfiniband.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingHostname.html" title="NMSettingHostname"> <link rel="next" href="NMSettingIP4Config.html" title="NMSettingIP4Config"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -197,7 +197,7 @@ nm_setting_infiniband_new (<em class="parameter"><code><span class="type">void</ <div class="refsect3"> <a name="nm-setting-infiniband-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingInfiniband.html" title="NMSettingInfiniband"><span class="type">NMSettingInfiniband</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -466,6 +466,6 @@ specify the base device by setting either this property or </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingMacsec.html b/docs/libnm/html/NMSettingMacsec.html index 66325c6..0091396 100644 --- a/docs/libnm/html/NMSettingMacsec.html +++ b/docs/libnm/html/NMSettingMacsec.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingIPTunnel.html" title="NMSettingIPTunnel"> <link rel="next" href="NMSettingMacvlan.html" title="NMSettingMacvlan"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -277,7 +277,7 @@ nm_setting_macsec_new (<em class="parameter"><code><span class="type">void</span <div class="refsect3"> <a name="nm-setting-macsec-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingMacsec.html" title="NMSettingMacsec"><span class="type">NMSettingMacsec</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.6</p> </div> @@ -773,6 +773,6 @@ in every packet.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingMacvlan.html b/docs/libnm/html/NMSettingMacvlan.html index 8659048..9821d08 100644 --- a/docs/libnm/html/NMSettingMacvlan.html +++ b/docs/libnm/html/NMSettingMacvlan.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingMacsec.html" title="NMSettingMacsec"> <link rel="next" href="NMSettingMatch.html" title="NMSettingMatch"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -179,7 +179,7 @@ nm_setting_macvlan_new (<em class="parameter"><code><span class="type">void</spa <div class="refsect3"> <a name="nm-setting-macvlan-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingMacvlan.html" title="NMSettingMacvlan"><span class="type">NMSettingMacvlan</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -442,6 +442,6 @@ with a <a class="link" href="NMSettingWired.html#NMSettingWired--mac-address" ti </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingMatch.html b/docs/libnm/html/NMSettingMatch.html index 5fe5160..8a6e33a 100644 --- a/docs/libnm/html/NMSettingMatch.html +++ b/docs/libnm/html/NMSettingMatch.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingMacvlan.html" title="NMSettingMacvlan"> <link rel="next" href="NMSettingOlpcMesh.html" title="NMSettingOlpcMesh"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -314,10 +314,14 @@ nm_setting_match_new (<em class="parameter"><code><span class="type">void</span> <p>Creates a new <a class="link" href="NMSettingMatch.html" title="NMSettingMatch"><span class="type">NMSettingMatch</span></a> object with default values.</p> <div class="refsect3"> <a name="nm-setting-match-new.returns"></a><h4>Returns</h4> -<p>the new empty <a class="link" href="NMSettingMatch.html" title="NMSettingMatch"><span class="type">NMSettingMatch</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p>the new empty <a class="link" href="NMSettingMatch.html" title="NMSettingMatch"><span class="type">NMSettingMatch</span></a> object</p> +<p>Note that this function was present in header files since version 1.14. +But due to a bug the symbol is only exposed and usable since version 1.32. +As workaround, use g_object_new(NM_TYPE_SETTING_MATCH) which works with all +versions since 1.14. </p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> -<p class="since">Since: 1.14</p> +<p class="since">Since: 1.32</p> </div> <hr> <div class="refsect2"> @@ -540,7 +544,7 @@ nm_setting_match_get_interface_names (<em class="parameter"><code><a class="link <p>the NULL terminated list of configured interface names.</p> <p>Before 1.26, the returned array was not <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated and you MUST provide a length. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -766,7 +770,7 @@ nm_setting_match_get_kernel_command_lines <div class="refsect3"> <a name="nm-setting-match-get-kernel-command-lines.returns"></a><h4>Returns</h4> <p>the configured interface names. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> </div> <p class="since">Since: 1.26</p> </div> @@ -986,7 +990,7 @@ nm_setting_match_get_drivers (<em class="parameter"><code><a class="link" href=" <div class="refsect3"> <a name="nm-setting-match-get-drivers.returns"></a><h4>Returns</h4> <p>the configured drivers. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> </div> <p class="since">Since: 1.26</p> </div> @@ -1205,7 +1209,7 @@ nm_setting_match_get_paths (<em class="parameter"><code><a class="link" href="NM <div class="refsect3"> <a name="nm-setting-match-get-paths.returns"></a><h4>Returns</h4> <p>the configured paths. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> </div> <p class="since">Since: 1.26</p> </div> @@ -1244,6 +1248,6 @@ nm_setting_match_get_paths (<em class="parameter"><code><a class="link" href="NM </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingOlpcMesh.html b/docs/libnm/html/NMSettingOlpcMesh.html index a129051..4e383fc 100644 --- a/docs/libnm/html/NMSettingOlpcMesh.html +++ b/docs/libnm/html/NMSettingOlpcMesh.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingMatch.html" title="NMSettingMatch"> <link rel="next" href="NMSettingOvsBridge.html" title="NMSettingOvsBridge"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -182,7 +182,7 @@ nm_setting_olpc_mesh_get_ssid (<em class="parameter"><code><a class="link" href= <div class="refsect3"> <a name="nm-setting-olpc-mesh-get-ssid.returns"></a><h4>Returns</h4> <p>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -263,6 +263,6 @@ answers the request.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingOvsBridge.html b/docs/libnm/html/NMSettingOvsBridge.html index 8064160..1533db0 100644 --- a/docs/libnm/html/NMSettingOvsBridge.html +++ b/docs/libnm/html/NMSettingOvsBridge.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingOlpcMesh.html" title="NMSettingOlpcMesh"> <link rel="next" href="NMSettingOvsInterface.html" title="NMSettingOvsInterface"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -138,7 +138,7 @@ nm_setting_ovs_bridge_new (<em class="parameter"><code><span class="type">void</ <div class="refsect3"> <a name="nm-setting-ovs-bridge-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingOvsBridge.html" title="NMSettingOvsBridge"><span class="type">NMSettingOvsBridge</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.10</p> </div> @@ -315,6 +315,6 @@ nm_setting_ovs_bridge_get_datapath_type </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingOvsDpdk.html b/docs/libnm/html/NMSettingOvsDpdk.html index 0051798..8ec3b30 100644 --- a/docs/libnm/html/NMSettingOvsDpdk.html +++ b/docs/libnm/html/NMSettingOvsDpdk.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingOvsInterface.html" title="NMSettingOvsInterface"> <link rel="next" href="NMSettingOvsPatch.html" title="NMSettingOvsPatch"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -91,7 +91,7 @@ nm_setting_ovs_dpdk_new (<em class="parameter"><code><span class="type">void</sp <div class="refsect3"> <a name="nm-setting-ovs-dpdk-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingOvsDpdk.html" title="NMSettingOvsDpdk"><span class="type">NMSettingOvsDpdk</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.20</p> </div> @@ -138,6 +138,6 @@ nm_setting_ovs_dpdk_get_devargs (<em class="parameter"><code><a class="link" hre </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingOvsExternalIDs.html b/docs/libnm/html/NMSettingOvsExternalIDs.html index 9a04d3d..de9579f 100644 --- a/docs/libnm/html/NMSettingOvsExternalIDs.html +++ b/docs/libnm/html/NMSettingOvsExternalIDs.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingOvsPort.html" title="NMSettingOvsPort"> <link rel="next" href="NMSettingPpp.html" title="NMSettingPpp"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -123,7 +123,7 @@ nm_setting_ovs_external_ids_new (<em class="parameter"><code><span class="type"> <a name="nm-setting-ovs-external-ids-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingOvsExternalIDs.html" title="NMSettingOvsExternalIDs"><span class="type">NMSettingOvsExternalIDs</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Override the parsed C type with given type."><span class="acronym">type</span></acronym> NMSettingOvsExternalIDs]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Override the parsed C type with given type."><span class="acronym">type</span></acronym> NMSettingOvsExternalIDs]</span></p> </div> <p class="since">Since: 1.30</p> </div> @@ -160,7 +160,7 @@ nm_setting_ovs_external_ids_get_data_keys <a name="nm-setting-ovs-external-ids-get-data-keys.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array containing each key from the table. </p> -<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_len][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_len][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -196,7 +196,7 @@ nm_setting_ovs_external_ids_get_data (<em class="parameter"><code><a class="link <p>the value associated with <em class="parameter"><code>key</code></em> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if no such value exists. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.30</p> </div> @@ -331,6 +331,6 @@ is a valid user data value.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingOvsInterface.html b/docs/libnm/html/NMSettingOvsInterface.html index 6499cf9..6b673a0 100644 --- a/docs/libnm/html/NMSettingOvsInterface.html +++ b/docs/libnm/html/NMSettingOvsInterface.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingOvsBridge.html" title="NMSettingOvsBridge"> <link rel="next" href="NMSettingOvsDpdk.html" title="NMSettingOvsDpdk"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -91,7 +91,7 @@ nm_setting_ovs_interface_new (<em class="parameter"><code><span class="type">voi <div class="refsect3"> <a name="nm-setting-ovs-interface-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingOvsInterface.html" title="NMSettingOvsInterface"><span class="type">NMSettingOvsInterface</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.10</p> </div> @@ -139,6 +139,6 @@ nm_setting_ovs_interface_get_interface_type </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingOvsPatch.html b/docs/libnm/html/NMSettingOvsPatch.html index 5ed7cc1..3bdab4a 100644 --- a/docs/libnm/html/NMSettingOvsPatch.html +++ b/docs/libnm/html/NMSettingOvsPatch.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingOvsDpdk.html" title="NMSettingOvsDpdk"> <link rel="next" href="NMSettingOvsPort.html" title="NMSettingOvsPort"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -91,7 +91,7 @@ nm_setting_ovs_patch_new (<em class="parameter"><code><span class="type">void</s <div class="refsect3"> <a name="nm-setting-ovs-patch-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingOvsPatch.html" title="NMSettingOvsPatch"><span class="type">NMSettingOvsPatch</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.10</p> </div> @@ -138,6 +138,6 @@ nm_setting_ovs_patch_get_peer (<em class="parameter"><code><a class="link" href= </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingOvsPort.html b/docs/libnm/html/NMSettingOvsPort.html index b3784ac..ea6dcae 100644 --- a/docs/libnm/html/NMSettingOvsPort.html +++ b/docs/libnm/html/NMSettingOvsPort.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingOvsPatch.html" title="NMSettingOvsPatch"> <link rel="next" href="NMSettingOvsExternalIDs.html" title="NMSettingOvsExternalIDs"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -149,7 +149,7 @@ nm_setting_ovs_port_new (<em class="parameter"><code><span class="type">void</sp <div class="refsect3"> <a name="nm-setting-ovs-port-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingOvsPort.html" title="NMSettingOvsPort"><span class="type">NMSettingOvsPort</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.10</p> </div> @@ -357,6 +357,6 @@ nm_setting_ovs_port_get_bond_downdelay </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingPpp.html b/docs/libnm/html/NMSettingPpp.html index 64fe6bb..614a4c7 100644 --- a/docs/libnm/html/NMSettingPpp.html +++ b/docs/libnm/html/NMSettingPpp.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingOvsExternalIDs.html" title="NMSettingOvsExternalIDs"> <link rel="next" href="NMSettingPppoe.html" title="NMSettingPppoe"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -413,7 +413,7 @@ nm_setting_ppp_new (<em class="parameter"><code><span class="type">void</span></ <div class="refsect3"> <a name="nm-setting-ppp-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingPpp.html" title="NMSettingPpp"><span class="type">NMSettingPpp</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -1177,6 +1177,6 @@ be set to <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macro </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingPppoe.html b/docs/libnm/html/NMSettingPppoe.html index 174f491..28e9a59 100644 --- a/docs/libnm/html/NMSettingPppoe.html +++ b/docs/libnm/html/NMSettingPppoe.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingPpp.html" title="NMSettingPpp"> <link rel="next" href="NMSettingProxy.html" title="NMSettingProxy"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -191,7 +191,7 @@ nm_setting_pppoe_new (<em class="parameter"><code><span class="type">void</span> <div class="refsect3"> <a name="nm-setting-pppoe-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingPppoe.html" title="NMSettingPppoe"><span class="type">NMSettingPppoe</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -420,6 +420,6 @@ access concentrators or a specific service is known to be required.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingProxy.html b/docs/libnm/html/NMSettingProxy.html index 9869929..9191af7 100644 --- a/docs/libnm/html/NMSettingProxy.html +++ b/docs/libnm/html/NMSettingProxy.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingPppoe.html" title="NMSettingPppoe"> <link rel="next" href="NMSettingSerial.html" title="NMSettingSerial"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -410,6 +410,6 @@ nm_setting_proxy_get_pac_script (<em class="parameter"><code><a class="link" hre </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingSerial.html b/docs/libnm/html/NMSettingSerial.html index 4b28f16..26d5c5b 100644 --- a/docs/libnm/html/NMSettingSerial.html +++ b/docs/libnm/html/NMSettingSerial.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingProxy.html" title="NMSettingProxy"> <link rel="next" href="NMSettingSriov.html" title="NMSettingSriov"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -198,7 +198,7 @@ nm_setting_serial_new (<em class="parameter"><code><span class="type">void</span <div class="refsect3"> <a name="nm-setting-serial-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingSerial.html" title="NMSettingSerial"><span class="type">NMSettingSerial</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -463,6 +463,6 @@ The 1 in "8n1" for example.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingSriov.html b/docs/libnm/html/NMSettingSriov.html index 1884421..10be809 100644 --- a/docs/libnm/html/NMSettingSriov.html +++ b/docs/libnm/html/NMSettingSriov.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingSerial.html" title="NMSettingSerial"> <link rel="next" href="NMSettingTCConfig.html" title="NMSettingTCConfig"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -326,7 +326,7 @@ nm_setting_sriov_new (<em class="parameter"><code><span class="type">void</span> <div class="refsect3"> <a name="nm-setting-sriov-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingSriov.html" title="NMSettingSriov"><span class="type">NMSettingSriov</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -416,7 +416,7 @@ nm_setting_sriov_get_vf (<em class="parameter"><code><a class="link" href="NMSet <a name="nm-setting-sriov-get-vf.returns"></a><h4>Returns</h4> <p>the VF at index <em class="parameter"><code>idx</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -675,7 +675,7 @@ nm_sriov_vf_get_vlan_ids (<em class="parameter"><code>const <a class="link" href <div class="refsect3"> <a name="nm-sriov-vf-get-vlan-ids.returns"></a><h4>Returns</h4> <p>a list of VLAN ids configured on the VF. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -819,7 +819,7 @@ nm_sriov_vf_new (<em class="parameter"><code><a href="https://developer.gnome.or <div class="refsect3"> <a name="nm-sriov-vf-new.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingSriov.html#NMSriovVF"><span class="type">NMSriovVF</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -934,7 +934,7 @@ nm_sriov_vf_dup (<em class="parameter"><code>const <a class="link" href="NMSetti <a name="nm-sriov-vf-dup.returns"></a><h4>Returns</h4> <p>a copy of <em class="parameter"><code>vf</code></em> . </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -996,7 +996,7 @@ nm_sriov_vf_set_attribute (<em class="parameter"><code><a class="link" href="NMS <tr> <td class="parameter_name"><p>value</p></td> <td class="parameter_description"><p>the value. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -1028,7 +1028,7 @@ nm_sriov_vf_get_attribute_names (<em class="parameter"><code>const <a class="lin <div class="refsect3"> <a name="nm-sriov-vf-get-attribute-names.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of attribute names. </p> -<p><span class="annotation">[<acronym title="The caller owns the data container, but not the data inside it."><span class="acronym">transfer container</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data container after the code is done."><span class="acronym">transfer container</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -1070,7 +1070,7 @@ on <em class="parameter"><code>vf</code></em> , or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if <em class="parameter"><code>vf</code></em> has no such attribute. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -1213,6 +1213,6 @@ the value is of the correct type and well-formed.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingTCConfig.html b/docs/libnm/html/NMSettingTCConfig.html index 50bebca..5e82df0 100644 --- a/docs/libnm/html/NMSettingTCConfig.html +++ b/docs/libnm/html/NMSettingTCConfig.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingSriov.html" title="NMSettingSriov"> <link rel="next" href="NMSettingTeamPort.html" title="NMSettingTeamPort"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -477,7 +477,7 @@ nm_tc_qdisc_new (<em class="parameter"><code>const <span class="type">char</span <div class="refsect3"> <a name="nm-tc-qdisc-new.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingTCConfig.html#NMTCQdisc"><span class="type">NMTCQdisc</span></a> object, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -591,7 +591,7 @@ nm_tc_qdisc_dup (<em class="parameter"><code><a class="link" href="NMSettingTCCo <a name="nm-tc-qdisc-dup.returns"></a><h4>Returns</h4> <p>a copy of <em class="parameter"><code>qdisc</code></em> . </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -726,7 +726,7 @@ nm_tc_qdisc_get_attribute_names (<em class="parameter"><code><a class="link" hre <a name="nm-tc-qdisc-get-attribute-names.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of attribute names or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if no attributes are set. </p> -<p><span class="annotation">[<acronym title="The caller owns the data container, but not the data inside it."><span class="acronym">transfer container</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data container after the code is done."><span class="acronym">transfer container</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -768,7 +768,7 @@ on <em class="parameter"><code>qdisc</code></em> , or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if <em class="parameter"><code>qdisc</code></em> has no such attribute. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.18</p> </div> @@ -803,7 +803,7 @@ nm_tc_qdisc_set_attribute (<em class="parameter"><code><a class="link" href="NMS <tr> <td class="parameter_name"><p>value</p></td> <td class="parameter_description"><p>the value. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -842,7 +842,7 @@ nm_tc_action_new (<em class="parameter"><code>const <span class="type">char</spa <div class="refsect3"> <a name="nm-tc-action-new.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingTCConfig.html#NMTCAction"><span class="type">NMTCAction</span></a> object, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -956,7 +956,7 @@ nm_tc_action_dup (<em class="parameter"><code><a class="link" href="NMSettingTCC <a name="nm-tc-action-dup.returns"></a><h4>Returns</h4> <p>a copy of <em class="parameter"><code>action</code></em> . </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -1007,7 +1007,7 @@ nm_tc_action_get_attribute_names (<em class="parameter"><code><a class="link" hr <div class="refsect3"> <a name="nm-tc-action-get-attribute-names.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of attribute names,. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -1049,7 +1049,7 @@ on <em class="parameter"><code>action</code></em> , or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if <em class="parameter"><code>action</code></em> has no such attribute. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -1084,7 +1084,7 @@ nm_tc_action_set_attribute (<em class="parameter"><code><a class="link" href="NM <tr> <td class="parameter_name"><p>value</p></td> <td class="parameter_description"><p>the value. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -1129,7 +1129,7 @@ nm_tc_tfilter_new (<em class="parameter"><code>const <span class="type">char</sp <div class="refsect3"> <a name="nm-tc-tfilter-new.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingTCConfig.html#NMTCTfilter"><span class="type">NMTCTfilter</span></a> object, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -1243,7 +1243,7 @@ nm_tc_tfilter_dup (<em class="parameter"><code><a class="link" href="NMSettingTC <a name="nm-tc-tfilter-dup.returns"></a><h4>Returns</h4> <p>a copy of <em class="parameter"><code>tfilter</code></em> . </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -1418,7 +1418,7 @@ nm_setting_tc_config_new (<em class="parameter"><code><span class="type">void</s <div class="refsect3"> <a name="nm-setting-tc-config-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingTCConfig.html" title="NMSettingTCConfig"><span class="type">NMSettingTCConfig</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -1480,7 +1480,7 @@ nm_setting_tc_config_get_qdisc (<em class="parameter"><code><a class="link" href <a name="nm-setting-tc-config-get-qdisc.returns"></a><h4>Returns</h4> <p>the qdisc at index <em class="parameter"><code>idx</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -1672,7 +1672,7 @@ nm_setting_tc_config_get_tfilter (<em class="parameter"><code><a class="link" hr <a name="nm-setting-tc-config-get-tfilter.returns"></a><h4>Returns</h4> <p>the tfilter at index <em class="parameter"><code>idx</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -1829,6 +1829,6 @@ nm_setting_tc_config_clear_tfilters (<em class="parameter"><code><a class="link" </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingTeam.html b/docs/libnm/html/NMSettingTeam.html index fe3b44c..0faf7bf 100644 --- a/docs/libnm/html/NMSettingTeam.html +++ b/docs/libnm/html/NMSettingTeam.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingTeamPort.html" title="NMSettingTeamPort"> <link rel="next" href="NMSettingTun.html" title="NMSettingTun"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -724,7 +724,7 @@ consistency with the link_watcher constructors of other type</p></td> <div class="refsect3"> <a name="nm-team-link-watcher-new-ethtool.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingTeam.html#NMTeamLinkWatcher"><span class="type">NMTeamLinkWatcher</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -779,7 +779,7 @@ target address in the NS packet</p></td> <div class="refsect3"> <a name="nm-team-link-watcher-new-nsna-ping.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingTeam.html#NMTeamLinkWatcher"><span class="type">NMTeamLinkWatcher</span></a> object, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -847,7 +847,7 @@ address in the arp request</p></td> <div class="refsect3"> <a name="nm-team-link-watcher-new-arp-ping.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingTeam.html#NMTeamLinkWatcher"><span class="type">NMTeamLinkWatcher</span></a> object, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -921,7 +921,7 @@ address in the arp request</p></td> <div class="refsect3"> <a name="nm-team-link-watcher-new-arp-ping2.returns"></a><h4>Returns</h4> <p>the new <a class="link" href="NMSettingTeam.html#NMTeamLinkWatcher"><span class="type">NMTeamLinkWatcher</span></a> object, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -1035,7 +1035,7 @@ nm_team_link_watcher_dup (<em class="parameter"><code>const <a class="link" href <a name="nm-team-link-watcher-dup.returns"></a><h4>Returns</h4> <p>a copy of <em class="parameter"><code>watcher</code></em> . </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -1283,7 +1283,7 @@ nm_setting_team_new (<em class="parameter"><code><span class="type">void</span>< <div class="refsect3"> <a name="nm-setting-team-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingTeam.html" title="NMSettingTeam"><span class="type">NMSettingTeam</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -1881,7 +1881,7 @@ nm_setting_team_get_link_watcher (<em class="parameter"><code><a class="link" hr <a name="nm-setting-team-get-link-watcher.returns"></a><h4>Returns</h4> <p>the link watcher at index <em class="parameter"><code>idx</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -2488,6 +2488,6 @@ Permitted values are: "roundrobin", "broadcast", "activebackup", </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingTeamPort.html b/docs/libnm/html/NMSettingTeamPort.html index 5ec9a74..be73107 100644 --- a/docs/libnm/html/NMSettingTeamPort.html +++ b/docs/libnm/html/NMSettingTeamPort.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingTCConfig.html" title="NMSettingTCConfig"> <link rel="next" href="NMSettingTeam.html" title="NMSettingTeam"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -273,7 +273,7 @@ nm_setting_team_port_new (<em class="parameter"><code><span class="type">void</s <div class="refsect3"> <a name="nm-setting-team-port-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingTeamPort.html" title="NMSettingTeamPort"><span class="type">NMSettingTeamPort</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -490,7 +490,7 @@ nm_setting_team_port_get_link_watcher (<em class="parameter"><code><a class="lin <a name="nm-setting-team-port-get-link-watcher.returns"></a><h4>Returns</h4> <p>the link watcher at index <em class="parameter"><code>idx</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -775,6 +775,6 @@ When set to -1 means the parameter is skipped from the json config.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingTun.html b/docs/libnm/html/NMSettingTun.html index 5a31dea..71ee6d3 100644 --- a/docs/libnm/html/NMSettingTun.html +++ b/docs/libnm/html/NMSettingTun.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingTeam.html" title="NMSettingTeam"> <link rel="next" href="NMSettingUser.html" title="NMSettingUser"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -213,7 +213,7 @@ nm_setting_tun_new (<em class="parameter"><code><span class="type">void</span></ <div class="refsect3"> <a name="nm-setting-tun-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingTun.html" title="NMSettingTun"><span class="type">NMSettingTun</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -536,6 +536,6 @@ network header.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingUser.html b/docs/libnm/html/NMSettingUser.html index d268e29..432fbce 100644 --- a/docs/libnm/html/NMSettingUser.html +++ b/docs/libnm/html/NMSettingUser.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingTun.html" title="NMSettingTun"> <link rel="next" href="NMSettingVeth.html" title="NMSettingVeth"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -156,7 +156,7 @@ nm_setting_user_get_keys (<em class="parameter"><code><a class="link" href="NMSe <a name="nm-setting-user-get-keys.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array containing each key from the table. </p> -<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_len][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_len][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -192,7 +192,7 @@ nm_setting_user_get_data (<em class="parameter"><code><a class="link" href="NMSe <p>the value associated with <em class="parameter"><code>key</code></em> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if no such value exists. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.8</p> </div> @@ -342,6 +342,6 @@ is a valid user data value.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingVeth.html b/docs/libnm/html/NMSettingVeth.html index dee004a..405f5e9 100644 --- a/docs/libnm/html/NMSettingVeth.html +++ b/docs/libnm/html/NMSettingVeth.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingUser.html" title="NMSettingUser"> <link rel="next" href="NMSettingVlan.html" title="NMSettingVlan"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -91,7 +91,7 @@ nm_setting_veth_new (<em class="parameter"><code><span class="type">void</span>< <div class="refsect3"> <a name="nm-setting-veth-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingVeth.html" title="NMSettingVeth"><span class="type">NMSettingVeth</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.30</p> </div> @@ -138,6 +138,6 @@ nm_setting_veth_get_peer (<em class="parameter"><code><a class="link" href="NMSe </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingVlan.html b/docs/libnm/html/NMSettingVlan.html index f5966c2..3f32377 100644 --- a/docs/libnm/html/NMSettingVlan.html +++ b/docs/libnm/html/NMSettingVlan.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingVeth.html" title="NMSettingVeth"> <link rel="next" href="NMSettingVpn.html" title="NMSettingVpn"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -254,7 +254,7 @@ nm_setting_vlan_new (<em class="parameter"><code><span class="type">void</span>< <div class="refsect3"> <a name="nm-setting-vlan-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingVlan.html" title="NMSettingVlan"><span class="type">NMSettingVlan</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -895,6 +895,6 @@ with a <a class="link" href="NMSettingWired.html#NMSettingWired--mac-address" ti </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingVpn.html b/docs/libnm/html/NMSettingVpn.html index 7891c7a..0e4be1f 100644 --- a/docs/libnm/html/NMSettingVpn.html +++ b/docs/libnm/html/NMSettingVpn.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingVlan.html" title="NMSettingVlan"> <link rel="next" href="NMSettingVrf.html" title="NMSettingVrf"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -334,7 +334,7 @@ nm_setting_vpn_new (<em class="parameter"><code><span class="type">void</span></ <div class="refsect3"> <a name="nm-setting-vpn-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingVpn.html" title="NMSettingVpn"><span class="type">NMSettingVpn</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -633,7 +633,7 @@ nm_setting_vpn_get_data_keys (<em class="parameter"><code><a class="link" href=" <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array containing each data key or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if there are no data items. </p> -<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_length][<acronym title="The caller owns the data container, but not the data inside it."><span class="acronym">transfer container</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_length][<acronym title="Free data container after the code is done."><span class="acronym">transfer container</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -855,7 +855,7 @@ nm_setting_vpn_get_secret_keys (<em class="parameter"><code><a class="link" href <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array containing each secret key or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if there are no secrets. </p> -<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_length][<acronym title="The caller owns the data container, but not the data inside it."><span class="acronym">transfer container</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=out_length][<acronym title="Free data container after the code is done."><span class="acronym">transfer container</span></acronym>]</span></p> </div> <p class="since">Since: 1.12</p> </div> @@ -1004,6 +1004,6 @@ VPN connection.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingVrf.html b/docs/libnm/html/NMSettingVrf.html index 2a129b7..835923c 100644 --- a/docs/libnm/html/NMSettingVrf.html +++ b/docs/libnm/html/NMSettingVrf.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingVpn.html" title="NMSettingVpn"> <link rel="next" href="NMSettingVxlan.html" title="NMSettingVxlan"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -92,7 +92,7 @@ nm_setting_vrf_new (<em class="parameter"><code><span class="type">void</span></ <div class="refsect3"> <a name="nm-setting-vrf-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingVrf.html" title="NMSettingVrf"><span class="type">NMSettingVrf</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.24</p> </div> @@ -139,6 +139,6 @@ nm_setting_vrf_get_table (<em class="parameter"><code><a class="link" href="NMSe </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingVxlan.html b/docs/libnm/html/NMSettingVxlan.html index 4660c43..b722e1f 100644 --- a/docs/libnm/html/NMSettingVxlan.html +++ b/docs/libnm/html/NMSettingVxlan.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingVrf.html" title="NMSettingVrf"> <link rel="next" href="NMSettingWifiP2P.html" title="NMSettingWifiP2P"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -377,7 +377,7 @@ nm_setting_vxlan_new (<em class="parameter"><code><span class="type">void</span> <div class="refsect3"> <a name="nm-setting-vxlan-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingVxlan.html" title="NMSettingVxlan"><span class="type">NMSettingVxlan</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -1086,6 +1086,6 @@ tunnel endpoint.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingWifiP2P.html b/docs/libnm/html/NMSettingWifiP2P.html index 8cd438e..2a00b2c 100644 --- a/docs/libnm/html/NMSettingWifiP2P.html +++ b/docs/libnm/html/NMSettingWifiP2P.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingVxlan.html" title="NMSettingVxlan"> <link rel="next" href="NMSettingWimax.html" title="NMSettingWimax"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -115,7 +115,7 @@ nm_setting_wifi_p2p_new (<em class="parameter"><code><span class="type">void</sp <div class="refsect3"> <a name="nm-setting-wifi-p2p-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingWifiP2P.html" title="NMSettingWifiP2P"><span class="type">NMSettingWifiP2P</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -194,7 +194,7 @@ nm_setting_wifi_p2p_get_wfd_ies (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-setting-wifi-p2p-get-wfd-ies.returns"></a><h4>Returns</h4> <p>the <span class="type">“wfd-ies”</span> property of the setting. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -228,6 +228,6 @@ nm_setting_wifi_p2p_get_wfd_ies (<em class="parameter"><code><a class="link" hre </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingWimax.html b/docs/libnm/html/NMSettingWimax.html index 3832fb7..20eeb57 100644 --- a/docs/libnm/html/NMSettingWimax.html +++ b/docs/libnm/html/NMSettingWimax.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingWifiP2P.html" title="NMSettingWifiP2P"> <link rel="next" href="NMSettingWired.html" title="NMSettingWired"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -270,6 +270,6 @@ should use.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingWireGuard.html b/docs/libnm/html/NMSettingWireGuard.html index d143b1b..167bfeb 100644 --- a/docs/libnm/html/NMSettingWireGuard.html +++ b/docs/libnm/html/NMSettingWireGuard.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingWired.html" title="NMSettingWired"> <link rel="next" href="NMSettingWirelessSecurity.html" title="NMSettingWirelessSecurity"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -453,7 +453,7 @@ nm_wireguard_peer_new (<em class="parameter"><code><span class="type">void</span <div class="refsect3"> <a name="nm-wireguard-peer-new.returns"></a><h4>Returns</h4> <p>a new, default, unsealed <a class="link" href="NMSettingWireGuard.html#NMWireGuardPeer"><span class="type">NMWireGuardPeer</span></a> instance. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -491,7 +491,7 @@ as well. Otherwise, they will be removed.</p></td> <p>a clone of <em class="parameter"><code>self</code></em> . This instance is always unsealed. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -626,7 +626,7 @@ nm_wireguard_peer_get_public_key (<em class="parameter"><code>const <a class="li <div class="refsect3"> <a name="nm-wireguard-peer-get-public-key.returns"></a><h4>Returns</h4> <p>the public key or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if unset. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -658,7 +658,7 @@ will be normalized (which may or may not modify the set value).</p> <td class="parameter_name"><p>public_key</p></td> <td class="parameter_description"><p>the new public key or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> to clear the public key. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>accept_invalid</p></td> @@ -701,7 +701,7 @@ nm_wireguard_peer_get_preshared_key (<em class="parameter"><code>const <a class= <div class="refsect3"> <a name="nm-wireguard-peer-get-preshared-key.returns"></a><h4>Returns</h4> <p>the preshared key or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if unset. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -738,7 +738,7 @@ be accepted.</p> <td class="parameter_name"><p>preshared_key</p></td> <td class="parameter_description"><p>the new preshared key or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> to clear the preshared key. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>accept_invalid</p></td> @@ -903,7 +903,7 @@ nm_wireguard_peer_get_endpoint (<em class="parameter"><code>const <a class="link <div class="refsect3"> <a name="nm-wireguard-peer-get-endpoint.returns"></a><h4>Returns</h4> <p>the endpoint or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if none was set. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -1012,7 +1012,10 @@ retrieve.</p></td> <tr> <td class="parameter_name"><p>out_is_valid</p></td> <td class="parameter_description"><p><a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the returned value is a valid allowed-ip -setting. </p></td> +setting. +This parameter is wrongly not marked as (out) argument, it is +thus not accessible via introspection. This cannot be fixed without +breaking API for introspection users. </p></td> <td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td> </tr> </tbody> @@ -1024,7 +1027,7 @@ setting. </p></td> . If <em class="parameter"><code>idx</code></em> is out of range, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> will be returned. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -1250,7 +1253,7 @@ nm_setting_wireguard_new (<em class="parameter"><code><span class="type">void</s <div class="refsect3"> <a name="nm-setting-wireguard-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingWireGuard.html" title="NMSettingWireGuard"><span class="type">NMSettingWireGuard</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -1277,7 +1280,7 @@ nm_setting_wireguard_get_private_key (<em class="parameter"><code><a class="link <div class="refsect3"> <a name="nm-setting-wireguard-get-private-key.returns"></a><h4>Returns</h4> <p>the set private-key or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -1419,7 +1422,7 @@ nm_setting_wireguard_get_peer (<em class="parameter"><code><a class="link" href= <p>the <a class="link" href="NMSettingWireGuard.html#NMWireGuardPeer"><span class="type">NMWireGuardPeer</span></a> entry at index <em class="parameter"><code>idx</code></em> . If the index is out of range, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> is returned. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -1465,7 +1468,7 @@ this is set to the <a class="link" href="NMSettingWireGuard.html#nm-setting-wire <a name="nm-setting-wireguard-get-peer-by-public-key.returns"></a><h4>Returns</h4> <p>the <a class="link" href="NMSettingWireGuard.html#NMWireGuardPeer"><span class="type">NMWireGuardPeer</span></a> instance with a matching public key. If no such peer exists, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> is returned. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -1828,6 +1831,6 @@ nm_setting_wireguard_get_ip6_auto_default_route </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingWired.html b/docs/libnm/html/NMSettingWired.html index d0be426..8f2fc84 100644 --- a/docs/libnm/html/NMSettingWired.html +++ b/docs/libnm/html/NMSettingWired.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingWimax.html" title="NMSettingWimax"> <link rel="next" href="NMSettingWireGuard.html" title="NMSettingWireGuard"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -433,7 +433,7 @@ nm_setting_wired_new (<em class="parameter"><code><span class="type">void</span> <div class="refsect3"> <a name="nm-setting-wired-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingWired.html" title="NMSettingWired"><span class="type">NMSettingWired</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -882,7 +882,7 @@ conjunction with that device.</p> <a name="nm-setting-wired-get-s390-subchannels.returns"></a><h4>Returns</h4> <p>array of strings, each specifying one subchannel the s390 device uses to communicate to the host. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8]</span></p> </div> </div> <hr> @@ -977,14 +977,14 @@ such as during option iteration.</p> <td class="parameter_name"><p>out_key</p></td> <td class="parameter_description"><p>on return, the key name of the s390 specific option; this value is owned by the setting and should not be modified. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>out_value</p></td> <td class="parameter_description"><p>on return, the value of the key of the s390 specific option; this value is owned by the setting and should not be modified. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -1041,10 +1041,10 @@ setting; the value is owned by the setting and must not be modified</p> nm_setting_wired_add_s390_option (<em class="parameter"><code><a class="link" href="NMSettingWired.html" title="NMSettingWired"><span class="type">NMSettingWired</span></a> *setting</code></em>, <em class="parameter"><code>const <span class="type">char</span> *key</code></em>, <em class="parameter"><code>const <span class="type">char</span> *value</code></em>);</pre> -<p>Add an option to the table. The option is compared to an internal list -of allowed options. Key names may contain only alphanumeric characters -(ie [a-zA-Z0-9]). Adding a new key replaces any existing key/value pair that -may already exist.</p> +<p>Add an option to the table. If the key already exists, the value gets +replaced.</p> +<p>Before 1.32, the function would assert that the key is valid. Since then, +an invalid key gets silently added but renders the profile as invalid.</p> <div class="refsect3"> <a name="nm-setting-wired-add-s390-option.parameters"></a><h4>Parameters</h4> <div class="informaltable"><table class="informaltable" width="100%" border="0"> @@ -1074,8 +1074,7 @@ may already exist.</p> </div> <div class="refsect3"> <a name="nm-setting-wired-add-s390-option.returns"></a><h4>Returns</h4> -<p> <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the option was valid and was added to the internal option -list, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> if it was not.</p> +<p> since 1.32 this always returns <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>.</p> </div> </div> <hr> @@ -1143,7 +1142,7 @@ and you may pass <a href="https://developer.gnome.org/glib/unstable/glib-Standar <div class="refsect3"> <a name="nm-setting-wired-get-valid-s390-options.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of strings of valid s390 options. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1622,6 +1621,6 @@ no password will be required.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingWireless.html b/docs/libnm/html/NMSettingWireless.html index 25462c1..0ce428a 100644 --- a/docs/libnm/html/NMSettingWireless.html +++ b/docs/libnm/html/NMSettingWireless.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingWirelessSecurity.html" title="NMSettingWirelessSecurity"> <link rel="next" href="NMSettingWpan.html" title="NMSettingWpan"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -509,7 +509,7 @@ nm_setting_wireless_new (<em class="parameter"><code><span class="type">void</sp <div class="refsect3"> <a name="nm-setting-wireless-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingWireless.html" title="NMSettingWireless"><span class="type">NMSettingWireless</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -535,7 +535,7 @@ nm_setting_wireless_get_ssid (<em class="parameter"><code><a class="link" href=" <div class="refsect3"> <a name="nm-setting-wireless-get-ssid.returns"></a><h4>Returns</h4> <p>the <a class="link" href="NMSettingWireless.html#NMSettingWireless--ssid" title="The “ssid” property"><span class="type">“ssid”</span></a> property of the setting. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1901,6 +1901,6 @@ NetworkManager).</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingWirelessSecurity.html b/docs/libnm/html/NMSettingWirelessSecurity.html index b15b246..4e1e517 100644 --- a/docs/libnm/html/NMSettingWirelessSecurity.html +++ b/docs/libnm/html/NMSettingWirelessSecurity.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingWireGuard.html" title="NMSettingWireGuard"> <link rel="next" href="NMSettingWireless.html" title="NMSettingWireless"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -582,7 +582,7 @@ nm_setting_wireless_security_new (<em class="parameter"><code><span class="type" <div class="refsect3"> <a name="nm-setting-wireless-security-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingWirelessSecurity.html" title="NMSettingWirelessSecurity"><span class="type">NMSettingWirelessSecurity</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2143,6 +2143,6 @@ the Access Point capabilities.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSettingWpan.html b/docs/libnm/html/NMSettingWpan.html index 3c13f38..23ebdac 100644 --- a/docs/libnm/html/NMSettingWpan.html +++ b/docs/libnm/html/NMSettingWpan.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMSettingWireless.html" title="NMSettingWireless"> <link rel="next" href="ch04.html" title="Device and Runtime Configuration API Reference"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -147,7 +147,7 @@ nm_setting_wpan_new (<em class="parameter"><code><span class="type">void</span>< <div class="refsect3"> <a name="nm-setting-wpan-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMSettingWpan.html" title="NMSettingWpan"><span class="type">NMSettingWpan</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -334,6 +334,6 @@ nm_setting_wpan_get_channel (<em class="parameter"><code><a class="link" href="N </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMSimpleConnection.html b/docs/libnm/html/NMSimpleConnection.html index 2f07195..a44a69d 100644 --- a/docs/libnm/html/NMSimpleConnection.html +++ b/docs/libnm/html/NMSimpleConnection.html @@ -8,7 +8,7 @@ <link rel="up" href="ch03.html" title="Connection and Setting API Reference"> <link rel="prev" href="NMConnection.html" title="NMConnection"> <link rel="next" href="NMRemoteConnection.html" title="NMRemoteConnection"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -108,7 +108,7 @@ nm_simple_connection_new (<em class="parameter"><code><span class="type">void</s <div class="refsect3"> <a name="nm-simple-connection-new.returns"></a><h4>Returns</h4> <p>the new empty <a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -147,7 +147,7 @@ description of the expected hash table.</p> <p>the new <a class="link" href="NMSimpleConnection.html" title="NMSimpleConnection"><span class="type">NMSimpleConnection</span></a> object, populated with settings created from the values in the hash table, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if the connection failed to normalize. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -175,7 +175,7 @@ nm_simple_connection_new_clone (<em class="parameter"><code><a class="link" href <a name="nm-simple-connection-new-clone.returns"></a><h4>Returns</h4> <p>a new <a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a> containing the same settings and properties as the source <a class="link" href="NMConnection.html" title="NMConnection"><span class="type">NMConnection</span></a>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> </div> @@ -188,6 +188,6 @@ and properties as the source <a class="link" href="NMConnection.html" title="NMC </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMVpnConnection.html b/docs/libnm/html/NMVpnConnection.html index 812ce21..7f7a18b 100644 --- a/docs/libnm/html/NMVpnConnection.html +++ b/docs/libnm/html/NMVpnConnection.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMActiveConnection.html" title="NMActiveConnection"> <link rel="next" href="NMAccessPoint.html" title="NMAccessPoint"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -150,6 +150,6 @@ string used by the connection, and must not be modified.</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMVpnEditor.html b/docs/libnm/html/NMVpnEditor.html index ce6d9da..e90577b 100644 --- a/docs/libnm/html/NMVpnEditor.html +++ b/docs/libnm/html/NMVpnEditor.html @@ -8,7 +8,7 @@ <link rel="up" href="ch06.html" title="VPN Plugin API Reference"> <link rel="prev" href="NMVpnPluginInfo.html" title="NMVpnPluginInfo"> <link rel="next" href="NMVpnEditorPlugin.html" title="NMVpnEditorPlugin"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -98,7 +98,7 @@ nm_vpn_editor_get_widget (<em class="parameter"><code><a class="link" href="NMVp <div class="refsect3"> <a name="nm-vpn-editor-get-widget.returns"></a><h4>Returns</h4> <p>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -173,6 +173,6 @@ to write values to the connection.</p></td> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMVpnEditorPlugin.html b/docs/libnm/html/NMVpnEditorPlugin.html index cd12816..a3269b8 100644 --- a/docs/libnm/html/NMVpnEditorPlugin.html +++ b/docs/libnm/html/NMVpnEditorPlugin.html @@ -8,7 +8,7 @@ <link rel="up" href="ch06.html" title="VPN Plugin API Reference"> <link rel="prev" href="NMVpnEditor.html" title="NMVpnEditor"> <link rel="next" href="NMVpnPluginOld.html" title="NMVpnPluginOld"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -325,7 +325,7 @@ nm_vpn_editor_plugin_get_editor (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-vpn-editor-plugin-get-editor.returns"></a><h4>Returns</h4> <p>a new <a class="link" href="NMVpnEditor.html" title="NMVpnEditor"><span class="type">NMVpnEditor</span></a> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -421,7 +421,7 @@ nm_vpn_editor_plugin_import (<em class="parameter"><code><a class="link" href="N , or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error or if the file at <em class="parameter"><code>path</code></em> was not recognized by this plugin. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -515,7 +515,7 @@ loading the shared library. </p></td> <div class="refsect3"> <a name="nm-vpn-editor-plugin-load-from-file.returns"></a><h4>Returns</h4> <p>a new plugin instance or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -567,7 +567,7 @@ the given service.</p></td> <div class="refsect3"> <a name="nm-vpn-editor-plugin-load.returns"></a><h4>Returns</h4> <p>a new plugin instance or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.4</p> </div> @@ -594,7 +594,7 @@ nm_vpn_editor_plugin_get_plugin_info (<em class="parameter"><code><a class="link <div class="refsect3"> <a name="nm-vpn-editor-plugin-get-plugin-info.returns"></a><h4>Returns</h4> <p>if set, return the <a class="link" href="NMVpnPluginInfo.html" title="NMVpnPluginInfo"><span class="type">NMVpnPluginInfo</span></a> instance. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.4</p> </div> @@ -875,6 +875,6 @@ user_function (<a class="link" href="NMVpnEditor.html" title="NMVpnEditor"><span </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMVpnPluginInfo.html b/docs/libnm/html/NMVpnPluginInfo.html index 45880d1..65214da 100644 --- a/docs/libnm/html/NMVpnPluginInfo.html +++ b/docs/libnm/html/NMVpnPluginInfo.html @@ -8,7 +8,7 @@ <link rel="up" href="ch06.html" title="VPN Plugin API Reference"> <link rel="prev" href="NMVpnServicePlugin.html" title="NMVpnServicePlugin"> <link rel="next" href="NMVpnEditor.html" title="NMVpnEditor"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -398,7 +398,7 @@ must be present. </p></td> <a name="nm-vpn-plugin-info-new-search-file.returns"></a><h4>Returns</h4> <p>a newly created instance of plugin info or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if no matching value was found. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.4</p> </div> @@ -425,7 +425,7 @@ nm_vpn_plugin_info_get_name (<em class="parameter"><code><a class="link" href="N <div class="refsect3"> <a name="nm-vpn-plugin-info-get-name.returns"></a><h4>Returns</h4> <p>the name. Cannot be <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -452,7 +452,7 @@ nm_vpn_plugin_info_get_filename (<em class="parameter"><code><a class="link" hre <div class="refsect3"> <a name="nm-vpn-plugin-info-get-filename.returns"></a><h4>Returns</h4> <p>the filename. Can be <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -479,7 +479,7 @@ nm_vpn_plugin_info_get_service (<em class="parameter"><code><a class="link" href <div class="refsect3"> <a name="nm-vpn-plugin-info-get-service.returns"></a><h4>Returns</h4> <p>the service. Cannot be <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.4</p> </div> @@ -506,7 +506,7 @@ nm_vpn_plugin_info_get_plugin (<em class="parameter"><code><a class="link" href= <div class="refsect3"> <a name="nm-vpn-plugin-info-get-plugin.returns"></a><h4>Returns</h4> <p>the plugin. Can be <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -533,7 +533,7 @@ nm_vpn_plugin_info_get_program (<em class="parameter"><code><a class="link" href <div class="refsect3"> <a name="nm-vpn-plugin-info-get-program.returns"></a><h4>Returns</h4> <p>the program. Can be <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -638,7 +638,7 @@ nm_vpn_plugin_info_get_aliases (<em class="parameter"><code><a class="link" href <div class="refsect3"> <a name="nm-vpn-plugin-info-get-aliases.returns"></a><h4>Returns</h4> <p>the aliases from the name-file. </p> -<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> zero-terminated=1][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> zero-terminated=1][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.4</p> </div> @@ -680,7 +680,7 @@ nm_vpn_plugin_info_lookup_property (<em class="parameter"><code><a class="link" <a name="nm-vpn-plugin-info-lookup-property.returns"></a><h4>Returns</h4> <p><a class="link" href="NMVpnPluginInfo.html" title="NMVpnPluginInfo"><span class="type">NMVpnPluginInfo</span></a> is internally a <a href="https://developer.gnome.org/glib/unstable/glib-Key-value-file-parser.html#GKeyFile"><span class="type">GKeyFile</span></a>. Returns the matching property. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -719,7 +719,7 @@ nm_vpn_plugin_info_list_load (<em class="parameter"><code><span class="type">voi <a name="nm-vpn-plugin-info-list-load.returns"></a><h4>Returns</h4> <p>list of plugins loaded from the default directories rejecting duplicates. </p> -<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMVpnPluginInfo][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMVpnPluginInfo][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -836,7 +836,7 @@ nm_vpn_plugin_info_list_find_by_name (<em class="parameter"><code><a href="https <a name="nm-vpn-plugin-info-list-find-by-name.returns"></a><h4>Returns</h4> <p>the first plugin with a matching <em class="parameter"><code>name</code></em> (or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>). </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -873,7 +873,7 @@ nm_vpn_plugin_info_list_find_by_filename <a name="nm-vpn-plugin-info-list-find-by-filename.returns"></a><h4>Returns</h4> <p>the first plugin with a matching <em class="parameter"><code>filename</code></em> (or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>). </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -911,7 +911,7 @@ or one of the provided aliases.</p></td> <a name="nm-vpn-plugin-info-list-find-by-service.returns"></a><h4>Returns</h4> <p>the first plugin with a matching <em class="parameter"><code>service</code></em> (or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>). </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -957,7 +957,7 @@ but it could be retrieved via <a class="link" href="NMVpnPluginInfo.html#nm-vpn- <div class="refsect3"> <a name="nm-vpn-plugin-info-list-find-service-type.returns"></a><h4>Returns</h4> <p>the resolved service-type or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on failure. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.4</p> </div> @@ -1005,7 +1005,7 @@ with <a class="link" href="NMVpnPluginInfo.html#nm-vpn-plugin-info-list-find-ser <a name="nm-vpn-plugin-info-list-get-service-types.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated strv list of strings. The list itself and the values must be freed with <a href="https://developer.gnome.org/glib/unstable/glib-String-Utility-Functions.html#g-strfreev"><code class="function">g_strfreev()</code></a>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.4</p> </div> @@ -1032,7 +1032,7 @@ nm_vpn_plugin_info_get_editor_plugin (<em class="parameter"><code><a class="link <div class="refsect3"> <a name="nm-vpn-plugin-info-get-editor-plugin.returns"></a><h4>Returns</h4> <p>the cached <a class="link" href="NMVpnEditorPlugin.html" title="NMVpnEditorPlugin"><span class="type">NMVpnEditorPlugin</span></a> instance. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -1103,7 +1103,7 @@ and can be later retrieved again via <a class="link" href="NMVpnPluginInfo.html#nm-vpn-plugin-info-get-editor-plugin" title="nm_vpn_plugin_info_get_editor_plugin ()"><code class="function">nm_vpn_plugin_info_get_editor_plugin()</code></a>. You can load the plugin only once, unless you reset the state via <a class="link" href="NMVpnPluginInfo.html#nm-vpn-plugin-info-set-editor-plugin" title="nm_vpn_plugin_info_set_editor_plugin ()"><code class="function">nm_vpn_plugin_info_set_editor_plugin()</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -1148,6 +1148,6 @@ plugin only once, unless you reset the state via </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMVpnPluginOld.html b/docs/libnm/html/NMVpnPluginOld.html index 07669e2..3b8fed7 100644 --- a/docs/libnm/html/NMVpnPluginOld.html +++ b/docs/libnm/html/NMVpnPluginOld.html @@ -8,7 +8,7 @@ <link rel="up" href="ch06.html" title="VPN Plugin API Reference"> <link rel="prev" href="NMVpnEditorPlugin.html" title="NMVpnEditorPlugin"> <link rel="next" href="object-tree.html" title="Object Hierarchy"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -268,7 +268,7 @@ nm_vpn_plugin_old_get_connection (<em class="parameter"><code><a class="link" hr <div class="refsect3"> <a name="nm-vpn-plugin-old-get-connection.returns"></a><h4>Returns</h4> <p>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -433,13 +433,13 @@ an applet when the applet calls the authentication dialog of the VPN plugin.</p> <td class="parameter_name"><p>out_data</p></td> <td class="parameter_description"><p>on successful return, a hash table (mapping char*:char*) containing the key/value pairs of VPN data items. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>out_secrets</p></td> <td class="parameter_description"><p>on successful return, a hash table (mapping char*:char*) containing the key/value pairsof VPN secrets. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -623,6 +623,6 @@ user_function (<a class="link" href="NMVpnPluginOld.html" title="NMVpnPluginOld" </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMVpnServicePlugin.html b/docs/libnm/html/NMVpnServicePlugin.html index 965727a..a016cd5 100644 --- a/docs/libnm/html/NMVpnServicePlugin.html +++ b/docs/libnm/html/NMVpnServicePlugin.html @@ -8,7 +8,7 @@ <link rel="up" href="ch06.html" title="VPN Plugin API Reference"> <link rel="prev" href="ch06.html" title="VPN Plugin API Reference"> <link rel="next" href="NMVpnPluginInfo.html" title="NMVpnPluginInfo"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -265,7 +265,7 @@ nm_vpn_service_plugin_get_connection (<em class="parameter"><code><a class="link <div class="refsect3"> <a name="nm-vpn-service-plugin-get-connection.returns"></a><h4>Returns</h4> <p>. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -411,13 +411,13 @@ an applet when the applet calls the authentication dialog of the VPN plugin.</p> <td class="parameter_name"><p>out_data</p></td> <td class="parameter_description"><p>on successful return, a hash table (mapping char*:char*) containing the key/value pairs of VPN data items. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>out_secrets</p></td> <td class="parameter_description"><p>on successful return, a hash table (mapping char*:char*) containing the key/value pairsof VPN secrets. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -609,6 +609,6 @@ user_function (<a class="link" href="NMVpnServicePlugin.html" title="NMVpnServic </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMWifiP2PPeer.html b/docs/libnm/html/NMWifiP2PPeer.html index aa6dbc4..b4ddd6e 100644 --- a/docs/libnm/html/NMWifiP2PPeer.html +++ b/docs/libnm/html/NMWifiP2PPeer.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMAccessPoint.html" title="NMAccessPoint"> <link rel="next" href="NMWimaxNsp.html" title="NMWimaxNsp"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -373,7 +373,7 @@ nm_wifi_p2p_peer_get_wfd_ies (<em class="parameter"><code><a class="link" href=" <div class="refsect3"> <a name="nm-wifi-p2p-peer-get-wfd-ies.returns"></a><h4>Returns</h4> <p>the <a href="https://developer.gnome.org/glib/unstable/glib-Byte-Arrays.html#GBytes"><span class="type">GBytes</span></a> containing the WFD IEs, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -490,7 +490,7 @@ with this function.</p> </tr> <tr> <td class="parameter_name"><p>connections</p></td> -<td class="parameter_description"><p>an array of <a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-struct"><span class="type">NMConnections</span></a> to +<td class="parameter_description"><p>an array of <span class="type">NMConnections</span> to filter. </p></td> <td class="parameter_annotations"><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></td> </tr> @@ -500,10 +500,10 @@ filter. </p></td> <div class="refsect3"> <a name="nm-wifi-p2p-peer-filter-connections.returns"></a><h4>Returns</h4> <p>an array of -<a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-struct"><span class="type">NMConnections</span></a> that could be activated with the given <em class="parameter"><code>peer</code></em> +<span class="type">NMConnections</span> that could be activated with the given <em class="parameter"><code>peer</code></em> . The array should be freed with <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#g-ptr-array-unref"><code class="function">g_ptr_array_unref()</code></a> when it is no longer required. </p> -<p><span class="annotation">[<acronym title="The caller owns the data container, but not the data inside it."><span class="acronym">transfer container</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></p> +<p><span class="annotation">[<acronym title="Free data container after the code is done."><span class="acronym">transfer container</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></p> </div> <p class="since">Since: 1.16</p> </div> @@ -613,6 +613,6 @@ against</p></td> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/NMWimaxNsp.html b/docs/libnm/html/NMWimaxNsp.html index ed16e0f..c055698 100644 --- a/docs/libnm/html/NMWimaxNsp.html +++ b/docs/libnm/html/NMWimaxNsp.html @@ -8,7 +8,7 @@ <link rel="up" href="ch04.html" title="Device and Runtime Configuration API Reference"> <link rel="prev" href="NMWifiP2PPeer.html" title="NMWifiP2PPeer"> <link rel="next" href="NMIPConfig.html" title="NMIPConfig"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -228,7 +228,7 @@ connections will match the <em class="parameter"><code>nsp</code></em> </tr> <tr> <td class="parameter_name"><p>connections</p></td> -<td class="parameter_description"><p>an array of <a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-struct"><span class="type">NMConnections</span></a> to +<td class="parameter_description"><p>an array of <span class="type">NMConnections</span> to filter. </p></td> <td class="parameter_annotations"><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></td> </tr> @@ -238,10 +238,10 @@ filter. </p></td> <div class="refsect3"> <a name="nm-wimax-nsp-filter-connections.returns"></a><h4>Returns</h4> <p>an array of -<a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-struct"><span class="type">NMConnections</span></a> that could be activated with the given <em class="parameter"><code>nsp</code></em> +<span class="type">NMConnections</span> that could be activated with the given <em class="parameter"><code>nsp</code></em> . The array should be freed with <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#g-ptr-array-unref"><code class="function">g_ptr_array_unref()</code></a> when it is no longer required. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMConnection]</span></p> </div> </div> <hr> @@ -311,6 +311,6 @@ against</p></td> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/annotation-glossary.html b/docs/libnm/html/annotation-glossary.html index 3b043d1..9591c45 100644 --- a/docs/libnm/html/annotation-glossary.html +++ b/docs/libnm/html/annotation-glossary.html @@ -8,7 +8,7 @@ <link rel="up" href="index.html" title="libnm Reference Manual"> <link rel="prev" href="api-index-full.html" title="API Index"> <link rel="next" href="license.html" title="Appendix A. License"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -49,7 +49,7 @@ <dd class="glossdef"><p>Generics and defining elements of containers and arrays.</p></dd> <a name="glsI"></a><h3 class="title">I</h3> <dt><span class="glossterm"><a name="annotation-glossterm-inout"></a>inout</span></dt> -<dd class="glossdef"><p>Parameter for input and for returning results. Default is <acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>.</p></dd> +<dd class="glossdef"><p>Parameter for input and for returning results. Default is <acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>.</p></dd> <a name="glsN"></a><h3 class="title">N</h3> <dt><span class="glossterm"><a name="annotation-glossterm-nullable"></a>nullable</span></dt> <dd class="glossdef"><p>NULL may be passed as the value in, out, in-out; or as a return value.</p></dd> @@ -57,7 +57,7 @@ <dt><span class="glossterm"><a name="annotation-glossterm-optional"></a>optional</span></dt> <dd class="glossdef"><p>NULL may be passed instead of a pointer to a location.</p></dd> <dt><span class="glossterm"><a name="annotation-glossterm-out"></a>out</span></dt> -<dd class="glossdef"><p>Parameter for returning results. Default is <acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>.</p></dd> +<dd class="glossdef"><p>Parameter for returning results. Default is <acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>.</p></dd> <a name="glsS"></a><h3 class="title">S</h3> <dt><span class="glossterm"><a name="annotation-glossterm-scope%20async"></a>scope async</span></dt> <dd class="glossdef"><p>The callback is valid until first called.</p></dd> @@ -67,15 +67,15 @@ <dd class="glossdef"><p>Exposed in C code, not necessarily available in other languages.</p></dd> <a name="glsT"></a><h3 class="title">T</h3> <dt><span class="glossterm"><a name="annotation-glossterm-transfer%20container"></a>transfer container</span></dt> -<dd class="glossdef"><p>The caller owns the data container, but not the data inside it.</p></dd> +<dd class="glossdef"><p>Free data container after the code is done.</p></dd> <dt><span class="glossterm"><a name="annotation-glossterm-transfer%20full"></a>transfer full</span></dt> -<dd class="glossdef"><p>The caller owns the data, and is responsible for free it.</p></dd> +<dd class="glossdef"><p>Free data after the code is done.</p></dd> <dt><span class="glossterm"><a name="annotation-glossterm-transfer%20none"></a>transfer none</span></dt> -<dd class="glossdef"><p>The data is owned by the callee, which is responsible of freeing it.</p></dd> +<dd class="glossdef"><p>Don't free data after the code is done.</p></dd> <dt><span class="glossterm"><a name="annotation-glossterm-type"></a>type</span></dt> <dd class="glossdef"><p>Override the parsed C type with given type.</p></dd> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/api-index-full.html b/docs/libnm/html/api-index-full.html index 0a6143b..dacb1ae 100644 --- a/docs/libnm/html/api-index-full.html +++ b/docs/libnm/html/api-index-full.html @@ -8,7 +8,7 @@ <link rel="up" href="index.html" title="libnm Reference Manual"> <link rel="prev" href="object-tree.html" title="Object Hierarchy"> <link rel="next" href="annotation-glossary.html" title="Annotation Glossary"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -53,47 +53,47 @@ NMAccessPoint, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--bssid">NMAccessPoint:bssid</a>, object property in NMDeviceOvs +NMAccessPoint:bssid, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--flags">NMAccessPoint:flags</a>, object property in NMDeviceOvs +NMAccessPoint:flags, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--frequency">NMAccessPoint:frequency</a>, object property in NMDeviceOvs +NMAccessPoint:frequency, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--hw-address">NMAccessPoint:hw-address</a>, object property in NMDeviceOvs +NMAccessPoint:hw-address, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--last-seen">NMAccessPoint:last-seen</a>, object property in NMDeviceOvs +NMAccessPoint:last-seen, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--max-bitrate">NMAccessPoint:max-bitrate</a>, object property in NMDeviceOvs +NMAccessPoint:max-bitrate, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--mode">NMAccessPoint:mode</a>, object property in NMDeviceOvs +NMAccessPoint:mode, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--rsn-flags">NMAccessPoint:rsn-flags</a>, object property in NMDeviceOvs +NMAccessPoint:rsn-flags, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--ssid">NMAccessPoint:ssid</a>, object property in NMDeviceOvs +NMAccessPoint:ssid, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--strength">NMAccessPoint:strength</a>, object property in NMDeviceOvs +NMAccessPoint:strength, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMAccessPoint.html#NMAccessPoint--wpa-flags">NMAccessPoint:wpa-flags</a>, object property in NMDeviceOvs +NMAccessPoint:wpa-flags, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -109,43 +109,43 @@ NMActiveConnection::state-changed, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--connection">NMActiveConnection:connection</a>, object property in NMDeviceOvs +NMActiveConnection:connection, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--default">NMActiveConnection:default</a>, object property in NMDeviceOvs +NMActiveConnection:default, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--default6">NMActiveConnection:default6</a>, object property in NMDeviceOvs +NMActiveConnection:default6, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--devices">NMActiveConnection:devices</a>, object property in NMDeviceOvs +NMActiveConnection:devices, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--dhcp4-config">NMActiveConnection:dhcp4-config</a>, object property in NMDeviceOvs +NMActiveConnection:dhcp4-config, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--dhcp6-config">NMActiveConnection:dhcp6-config</a>, object property in NMDeviceOvs +NMActiveConnection:dhcp6-config, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--id">NMActiveConnection:id</a>, object property in NMDeviceOvs +NMActiveConnection:id, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--ip4-config">NMActiveConnection:ip4-config</a>, object property in NMDeviceOvs +NMActiveConnection:ip4-config, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--ip6-config">NMActiveConnection:ip6-config</a>, object property in NMDeviceOvs +NMActiveConnection:ip6-config, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--master">NMActiveConnection:master</a>, object property in NMDeviceOvs +NMActiveConnection:master, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -153,7 +153,7 @@ NMActiveConnection:specific-object-path, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--state">NMActiveConnection:state</a>, object property in NMDeviceOvs +NMActiveConnection:state, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -161,15 +161,15 @@ NMActiveConnection:state-flags, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--type">NMActiveConnection:type</a>, object property in NMDeviceOvs +NMActiveConnection:type, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--uuid">NMActiveConnection:uuid</a>, object property in NMDeviceOvs +NMActiveConnection:uuid, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMActiveConnection.html#NMActiveConnection--vpn">NMActiveConnection:vpn</a>, object property in NMDeviceOvs +NMActiveConnection:vpn, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -229,11 +229,11 @@ NMClient::active-connection-removed, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient-any-device-added">NMClient::any-device-added</a>, object signal in NMDeviceOvs +NMClient::any-device-added, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient-any-device-removed">NMClient::any-device-removed</a>, object signal in NMDeviceOvs +NMClient::any-device-removed, object signal in NMDeviceOvs </dt> <dd></dd> <dt> @@ -245,27 +245,27 @@ NMClient::connection-removed, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient-device-added">NMClient::device-added</a>, object signal in NMDeviceOvs +NMClient::device-added, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient-device-removed">NMClient::device-removed</a>, object signal in NMDeviceOvs +NMClient::device-removed, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient-permission-changed">NMClient::permission-changed</a>, object signal in NMDeviceOvs +NMClient::permission-changed, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--activating-connection">NMClient:activating-connection</a>, object property in NMDeviceOvs +NMClient:activating-connection, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--active-connections">NMClient:active-connections</a>, object property in NMDeviceOvs +NMClient:active-connections, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--all-devices">NMClient:all-devices</a>, object property in NMDeviceOvs +NMClient:all-devices, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -285,7 +285,7 @@ NMClient:connections, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--connectivity">NMClient:connectivity</a>, object property in NMDeviceOvs +NMClient:connectivity, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -309,7 +309,7 @@ NMClient:dbus-name-owner, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--devices">NMClient:devices</a>, object property in NMDeviceOvs +NMClient:devices, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -337,7 +337,7 @@ NMClient:metered, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--networking-enabled">NMClient:networking-enabled</a>, object property in NMDeviceOvs +NMClient:networking-enabled, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -349,43 +349,43 @@ NMClient:permissions-state, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--primary-connection">NMClient:primary-connection</a>, object property in NMDeviceOvs +NMClient:primary-connection, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--startup">NMClient:startup</a>, object property in NMDeviceOvs +NMClient:startup, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--state">NMClient:state</a>, object property in NMDeviceOvs +NMClient:state, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--version">NMClient:version</a>, object property in NMDeviceOvs +NMClient:version, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--wimax-enabled">NMClient:wimax-enabled</a>, object property in NMDeviceOvs +NMClient:wimax-enabled, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--wimax-hardware-enabled">NMClient:wimax-hardware-enabled</a>, object property in NMDeviceOvs +NMClient:wimax-hardware-enabled, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--wireless-enabled">NMClient:wireless-enabled</a>, object property in NMDeviceOvs +NMClient:wireless-enabled, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--wireless-hardware-enabled">NMClient:wireless-hardware-enabled</a>, object property in NMDeviceOvs +NMClient:wireless-hardware-enabled, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--wwan-enabled">NMClient:wwan-enabled</a>, object property in NMDeviceOvs +NMClient:wwan-enabled, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#NMClient--wwan-hardware-enabled">NMClient:wwan-hardware-enabled</a>, object property in NMDeviceOvs +NMClient:wwan-hardware-enabled, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -421,19 +421,19 @@ NMClientNotifyEventWithPtrCb, user_function in <a class="link" href="NMIPConfig. </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-struct">NMConnection</a>, struct in NMSettingOvs +NMConnection, struct in NMSettingOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-changed">NMConnection::changed</a>, object signal in NMSettingOvs +NMConnection::changed, object signal in NMSettingOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-secrets-cleared">NMConnection::secrets-cleared</a>, object signal in NMSettingOvs +NMConnection::secrets-cleared, object signal in NMSettingOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMConnection.html#NMConnection-secrets-updated">NMConnection::secrets-updated</a>, object signal in NMSettingOvs +NMConnection::secrets-updated, object signal in NMSettingOvs </dt> <dd></dd> <dt> @@ -477,51 +477,51 @@ NMDevice6Lowpan:parent, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice-state-changed">NMDevice::state-changed</a>, object signal in NMDeviceOvs +NMDevice::state-changed, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--active-connection">NMDevice:active-connection</a>, object property in NMDeviceOvs +NMDevice:active-connection, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--autoconnect">NMDevice:autoconnect</a>, object property in NMDeviceOvs +NMDevice:autoconnect, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--available-connections">NMDevice:available-connections</a>, object property in NMDeviceOvs +NMDevice:available-connections, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--capabilities">NMDevice:capabilities</a>, object property in NMDeviceOvs +NMDevice:capabilities, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--device-type">NMDevice:device-type</a>, object property in NMDeviceOvs +NMDevice:device-type, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--dhcp4-config">NMDevice:dhcp4-config</a>, object property in NMDeviceOvs +NMDevice:dhcp4-config, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--dhcp6-config">NMDevice:dhcp6-config</a>, object property in NMDeviceOvs +NMDevice:dhcp6-config, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--driver">NMDevice:driver</a>, object property in NMDeviceOvs +NMDevice:driver, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--driver-version">NMDevice:driver-version</a>, object property in NMDeviceOvs +NMDevice:driver-version, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--firmware-missing">NMDevice:firmware-missing</a>, object property in NMDeviceOvs +NMDevice:firmware-missing, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--firmware-version">NMDevice:firmware-version</a>, object property in NMDeviceOvs +NMDevice:firmware-version, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -529,7 +529,7 @@ NMDevice:hw-address, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--interface">NMDevice:interface</a>, object property in NMDeviceOvs +NMDevice:interface, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -537,11 +537,11 @@ NMDevice:interface-flags, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--ip-interface">NMDevice:ip-interface</a>, object property in NMDeviceOvs +NMDevice:ip-interface, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--ip4-config">NMDevice:ip4-config</a>, object property in NMDeviceOvs +NMDevice:ip4-config, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -549,7 +549,7 @@ NMDevice:ip4-connectivity, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--ip6-config">NMDevice:ip6-config</a>, object property in NMDeviceOvs +NMDevice:ip6-config, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -561,7 +561,7 @@ NMDevice:lldp-neighbors, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--managed">NMDevice:managed</a>, object property in NMDeviceOvs +NMDevice:managed, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -569,7 +569,7 @@ NMDevice:metered, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--mtu">NMDevice:mtu</a>, object property in NMDeviceOvs +NMDevice:mtu, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -581,31 +581,31 @@ NMDevice:path, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--physical-port-id">NMDevice:physical-port-id</a>, object property in NMDeviceOvs +NMDevice:physical-port-id, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--product">NMDevice:product</a>, object property in NMDeviceOvs +NMDevice:product, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--real">NMDevice:real</a>, object property in NMDeviceOvs +NMDevice:real, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--state">NMDevice:state</a>, object property in NMDeviceOvs +NMDevice:state, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--state-reason">NMDevice:state-reason</a>, object property in NMDeviceOvs +NMDevice:state-reason, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--udi">NMDevice:udi</a>, object property in NMDeviceOvs +NMDevice:udi, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDevice.html#NMDevice--vendor">NMDevice:vendor</a>, object property in NMDeviceOvs +NMDevice:vendor, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -613,7 +613,7 @@ NMDeviceAdsl, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceAdsl.html#NMDeviceAdsl--carrier">NMDeviceAdsl:carrier</a>, object property in NMDeviceOvs +NMDeviceAdsl:carrier, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -621,11 +621,11 @@ NMDeviceBond, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceBond.html#NMDeviceBond--carrier">NMDeviceBond:carrier</a>, object property in NMDeviceOvs +NMDeviceBond:carrier, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceBond.html#NMDeviceBond--slaves">NMDeviceBond:slaves</a>, object property in NMDeviceOvs +NMDeviceBond:slaves, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -633,11 +633,11 @@ NMDeviceBridge, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceBridge.html#NMDeviceBridge--carrier">NMDeviceBridge:carrier</a>, object property in NMDeviceOvs +NMDeviceBridge:carrier, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceBridge.html#NMDeviceBridge--slaves">NMDeviceBridge:slaves</a>, object property in NMDeviceOvs +NMDeviceBridge:slaves, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -645,11 +645,11 @@ NMDeviceBt, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceBt.html#NMDeviceBt--bt-capabilities">NMDeviceBt:bt-capabilities</a>, object property in NMDeviceOvs +NMDeviceBt:bt-capabilities, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceBt.html#NMDeviceBt--name">NMDeviceBt:name</a>, object property in NMDeviceOvs +NMDeviceBt:name, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -673,11 +673,11 @@ NMDeviceEthernet, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceEthernet.html#NMDeviceEthernet--carrier">NMDeviceEthernet:carrier</a>, object property in NMDeviceOvs +NMDeviceEthernet:carrier, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceEthernet.html#NMDeviceEthernet--perm-hw-address">NMDeviceEthernet:perm-hw-address</a>, object property in NMDeviceOvs +NMDeviceEthernet:perm-hw-address, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -685,7 +685,7 @@ NMDeviceEthernet:s390-subchannels, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceEthernet.html#NMDeviceEthernet--speed">NMDeviceEthernet:speed</a>, object property in NMDeviceOvs +NMDeviceEthernet:speed, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -697,7 +697,7 @@ NMDeviceGeneric, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceGeneric.html#NMDeviceGeneric--type-description">NMDeviceGeneric:type-description</a>, object property in NMDeviceOvs +NMDeviceGeneric:type-description, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -705,7 +705,7 @@ NMDeviceInfiniband, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceInfiniband.html#NMDeviceInfiniband--carrier">NMDeviceInfiniband:carrier</a>, object property in NMDeviceOvs +NMDeviceInfiniband:carrier, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -849,7 +849,7 @@ NMDeviceModem:apn, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceModem.html#NMDeviceModem--current-capabilities">NMDeviceModem:current-capabilities</a>, object property in NMDeviceOvs +NMDeviceModem:current-capabilities, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -857,7 +857,7 @@ NMDeviceModem:device-id, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceModem.html#NMDeviceModem--modem-capabilities">NMDeviceModem:modem-capabilities</a>, object property in NMDeviceOvs +NMDeviceModem:modem-capabilities, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -873,11 +873,11 @@ NMDeviceOlpcMesh, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceOlpcMesh.html#NMDeviceOlpcMesh--active-channel">NMDeviceOlpcMesh:active-channel</a>, object property in NMDeviceOvs +NMDeviceOlpcMesh:active-channel, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceOlpcMesh.html#NMDeviceOlpcMesh--companion">NMDeviceOlpcMesh:companion</a>, object property in NMDeviceOvs +NMDeviceOlpcMesh:companion, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -917,7 +917,7 @@ NMDeviceTeam, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceTeam.html#NMDeviceTeam--carrier">NMDeviceTeam:carrier</a>, object property in NMDeviceOvs +NMDeviceTeam:carrier, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -925,7 +925,7 @@ NMDeviceTeam:config, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceTeam.html#NMDeviceTeam--slaves">NMDeviceTeam:slaves</a>, object property in NMDeviceOvs +NMDeviceTeam:slaves, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -973,15 +973,15 @@ NMDeviceVlan, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceVlan.html#NMDeviceVlan--carrier">NMDeviceVlan:carrier</a>, object property in NMDeviceOvs +NMDeviceVlan:carrier, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceVlan.html#NMDeviceVlan--parent">NMDeviceVlan:parent</a>, object property in NMDeviceOvs +NMDeviceVlan:parent, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceVlan.html#NMDeviceVlan--vlan-id">NMDeviceVlan:vlan-id</a>, object property in NMDeviceOvs +NMDeviceVlan:vlan-id, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -1069,23 +1069,23 @@ NMDeviceWifi, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWifi.html#NMDeviceWifi-access-point-added">NMDeviceWifi::access-point-added</a>, object signal in NMDeviceOvs +NMDeviceWifi::access-point-added, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWifi.html#NMDeviceWifi-access-point-removed">NMDeviceWifi::access-point-removed</a>, object signal in NMDeviceOvs +NMDeviceWifi::access-point-removed, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWifi.html#NMDeviceWifi--access-points">NMDeviceWifi:access-points</a>, object property in NMDeviceOvs +NMDeviceWifi:access-points, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWifi.html#NMDeviceWifi--active-access-point">NMDeviceWifi:active-access-point</a>, object property in NMDeviceOvs +NMDeviceWifi:active-access-point, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWifi.html#NMDeviceWifi--bitrate">NMDeviceWifi:bitrate</a>, object property in NMDeviceOvs +NMDeviceWifi:bitrate, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -1093,15 +1093,15 @@ NMDeviceWifi:last-scan, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWifi.html#NMDeviceWifi--mode">NMDeviceWifi:mode</a>, object property in NMDeviceOvs +NMDeviceWifi:mode, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWifi.html#NMDeviceWifi--perm-hw-address">NMDeviceWifi:perm-hw-address</a>, object property in NMDeviceOvs +NMDeviceWifi:perm-hw-address, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWifi.html#NMDeviceWifi--wireless-capabilities">NMDeviceWifi:wireless-capabilities</a>, object property in NMDeviceOvs +NMDeviceWifi:wireless-capabilities, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -1129,43 +1129,43 @@ NMDeviceWimax, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWimax.html#NMDeviceWimax-nsp-added">NMDeviceWimax::nsp-added</a>, object signal in NMDeviceOvs +NMDeviceWimax::nsp-added, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWimax.html#NMDeviceWimax-nsp-removed">NMDeviceWimax::nsp-removed</a>, object signal in NMDeviceOvs +NMDeviceWimax::nsp-removed, object signal in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWimax.html#NMDeviceWimax--active-nsp">NMDeviceWimax:active-nsp</a>, object property in NMDeviceOvs +NMDeviceWimax:active-nsp, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWimax.html#NMDeviceWimax--bsid">NMDeviceWimax:bsid</a>, object property in NMDeviceOvs +NMDeviceWimax:bsid, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWimax.html#NMDeviceWimax--center-frequency">NMDeviceWimax:center-frequency</a>, object property in NMDeviceOvs +NMDeviceWimax:center-frequency, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWimax.html#NMDeviceWimax--cinr">NMDeviceWimax:cinr</a>, object property in NMDeviceOvs +NMDeviceWimax:cinr, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWimax.html#NMDeviceWimax--hw-address">NMDeviceWimax:hw-address</a>, object property in NMDeviceOvs +NMDeviceWimax:hw-address, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWimax.html#NMDeviceWimax--nsps">NMDeviceWimax:nsps</a>, object property in NMDeviceOvs +NMDeviceWimax:nsps, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWimax.html#NMDeviceWimax--rssi">NMDeviceWimax:rssi</a>, object property in NMDeviceOvs +NMDeviceWimax:rssi, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMDeviceWimax.html#NMDeviceWimax--tx-power">NMDeviceWimax:tx-power</a>, object property in NMDeviceOvs +NMDeviceWimax:tx-power, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -1341,6 +1341,10 @@ NMLInitData, struct in <a class="link" href="NMIPConfig.html" title="NMIPConfig" </dt> <dd></dd> <dt> +<a class="link" href="NMDevice.html#NMLldpNeighbor-struct" title="NMLldpNeighbor">NMLldpNeighbor</a>, struct in <a class="link" href="NMDevice.html" title="NMDevice">NMDevice</a> +</dt> +<dd></dd> +<dt> nml_cleanup_context_busy_watcher_on_idle, function in <a class="link" href="NMIPConfig.html" title="NMIPConfig">NMIPConfig</a> </dt> <dd></dd> @@ -1561,18 +1565,6 @@ NML_NMCLIENT_LOG_W, macro in <a class="link" href="NMIPConfig.html" title="NMIPC </dt> <dd></dd> <dt> -NMMetaSettingInfo, typedef in nm-meta-setting-base-impl -</dt> -<dd></dd> -<dt> -NMMetaSettingInfo_Alias, struct in nm-meta-setting-base-impl -</dt> -<dd></dd> -<dt> -NMMetaSettingType, enum in nm-meta-setting-base-impl -</dt> -<dd></dd> -<dt> <a class="link" href="libnm-nm-dbus-interface.html#NMMetered" title="enum NMMetered">NMMetered</a>, enum in <a class="link" href="libnm-nm-dbus-interface.html" title="nm-dbus-interface">nm-dbus-interface</a> </dt> <dd></dd> @@ -1613,7 +1605,7 @@ NMRemoteConnection:flags, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMRemoteConnection.html#NMRemoteConnection--unsaved">NMRemoteConnection:unsaved</a>, object property in NMDeviceOvs +NMRemoteConnection:unsaved, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -1889,14 +1881,6 @@ NMSetting6Lowpan:parent, object property in NMSettingOvs </dt> <dd></dd> <dt> -NMSetting8021xSchemeType, enum in nm-meta-setting-base-impl -</dt> -<dd></dd> -<dt> -NMSetting8021xSchemeVtable, struct in nm-meta-setting-base-impl -</dt> -<dd></dd> -<dt> <a class="link" href="NMSetting.html#NMSetting--name" title="The “name” property">NMSetting:name</a>, object property in <a class="link" href="NMSetting.html" title="NMSetting">NMSetting</a> </dt> <dd></dd> @@ -1957,11 +1941,11 @@ NMSettingBridge, struct in NMSettingOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--ageing-time">NMSettingBridge:ageing-time</a>, object property in NMSettingOvs +NMSettingBridge:ageing-time, object property in NMSettingOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--forward-delay">NMSettingBridge:forward-delay</a>, object property in NMSettingOvs +NMSettingBridge:forward-delay, object property in NMSettingOvs </dt> <dd></dd> <dt> @@ -1973,15 +1957,15 @@ NMSettingBridge:group-forward-mask, object property in NMSettingOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--hello-time">NMSettingBridge:hello-time</a>, object property in NMSettingOvs +NMSettingBridge:hello-time, object property in NMSettingOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--mac-address">NMSettingBridge:mac-address</a>, object property in NMSettingOvs +NMSettingBridge:mac-address, object property in NMSettingOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--max-age">NMSettingBridge:max-age</a>, object property in NMSettingOvs +NMSettingBridge:max-age, object property in NMSettingOvs </dt> <dd></dd> <dt> @@ -2037,11 +2021,11 @@ NMSettingBridge:multicast-startup-query-interval, object property in NMSettingOv </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--priority">NMSettingBridge:priority</a>, object property in NMSettingOvs +NMSettingBridge:priority, object property in NMSettingOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/NMSettingBridge.html#NMSettingBridge--stp">NMSettingBridge:stp</a>, object property in NMSettingOvs +NMSettingBridge:stp, object property in NMSettingOvs </dt> <dd></dd> <dt> @@ -2913,10 +2897,6 @@ NMSettingOvsPort:vlan-mode, object property in NMSettingOvs </dt> <dd></dd> <dt> -NMSettingPriority, enum in nm-meta-setting-base-impl -</dt> -<dd></dd> -<dt> <a class="link" href="NMSettingProxy.html#NMSettingProxy-struct" title="NMSettingProxy">NMSettingProxy</a>, struct in <a class="link" href="NMSettingProxy.html" title="NMSettingProxy">NMSettingProxy</a> </dt> <dd></dd> @@ -3933,15 +3913,15 @@ NMWimaxNsp, struct in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMWimaxNsp.html#NMWimaxNsp--name">NMWimaxNsp:name</a>, object property in NMDeviceOvs +NMWimaxNsp:name, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMWimaxNsp.html#NMWimaxNsp--network-type">NMWimaxNsp:network-type</a>, object property in NMDeviceOvs +NMWimaxNsp:network-type, object property in NMDeviceOvs </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-glib/NMWimaxNsp.html#NMWimaxNsp--signal-quality">NMWimaxNsp:signal-quality</a>, object property in NMDeviceOvs +NMWimaxNsp:signal-quality, object property in NMDeviceOvs </dt> <dd></dd> <dt> @@ -4249,6 +4229,10 @@ nm_auto_unref_nml_dbusobj, macro in <a class="link" href="NMIPConfig.html" title </dt> <dd></dd> <dt> +<a class="link" href="libnm-nm-version.html#NM-AVAILABLE-IN-1-32:CAPS" title="NM_AVAILABLE_IN_1_32">NM_AVAILABLE_IN_1_32</a>, macro in <a class="link" href="libnm-nm-version.html" title="nm-version">nm-version</a> +</dt> +<dd></dd> +<dt> <a class="link" href="libnm-nm-version.html#NM-AVAILABLE-IN-1-4:CAPS" title="NM_AVAILABLE_IN_1_4">NM_AVAILABLE_IN_1_4</a>, macro in <a class="link" href="libnm-nm-version.html" title="nm-version">nm-version</a> </dt> <dd></dd> @@ -5393,11 +5377,11 @@ nm_context_busy_watcher_quark, function in <a class="link" href="NMIPConfig.html </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-INTERFACE-VPN:CAPS">NM_DBUS_INTERFACE_VPN</a>, macro in nm-vpn-dbus-interface +NM_DBUS_INTERFACE_VPN, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-INTERFACE-VPN-CONNECTION:CAPS">NM_DBUS_INTERFACE_VPN_CONNECTION</a>, macro in nm-vpn-dbus-interface +NM_DBUS_INTERFACE_VPN_CONNECTION, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> @@ -5409,15 +5393,15 @@ nm_context_busy_watcher_quark, function in <a class="link" href="NMIPConfig.html </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-INVALID-VPN-CONNECTION:CAPS">NM_DBUS_INVALID_VPN_CONNECTION</a>, macro in nm-vpn-dbus-interface +NM_DBUS_INVALID_VPN_CONNECTION, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-NO-ACTIVE-VPN-CONNECTION:CAPS">NM_DBUS_NO_ACTIVE_VPN_CONNECTION</a>, macro in nm-vpn-dbus-interface +NM_DBUS_NO_ACTIVE_VPN_CONNECTION, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-NO-VPN-CONNECTIONS:CAPS">NM_DBUS_NO_VPN_CONNECTIONS</a>, macro in nm-vpn-dbus-interface +NM_DBUS_NO_VPN_CONNECTIONS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> @@ -5453,11 +5437,11 @@ nm_dbus_path_not_empty, function in <a class="link" href="NMIPConfig.html" title </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-PATH-VPN:CAPS">NM_DBUS_PATH_VPN</a>, macro in nm-vpn-dbus-interface +NM_DBUS_PATH_VPN, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-PATH-VPN-CONNECTION:CAPS">NM_DBUS_PATH_VPN_CONNECTION</a>, macro in nm-vpn-dbus-interface +NM_DBUS_PATH_VPN_CONNECTION, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> @@ -5473,67 +5457,67 @@ nm_dbus_path_not_empty, function in <a class="link" href="NMIPConfig.html" title </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-ALREADY-STARTED:CAPS">NM_DBUS_VPN_ALREADY_STARTED</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_ALREADY_STARTED, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-ALREADY-STOPPED:CAPS">NM_DBUS_VPN_ALREADY_STOPPED</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_ALREADY_STOPPED, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-BAD-ARGUMENTS:CAPS">NM_DBUS_VPN_BAD_ARGUMENTS</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_BAD_ARGUMENTS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-ERROR-PREFIX:CAPS">NM_DBUS_VPN_ERROR_PREFIX</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_ERROR_PREFIX, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-INTERACTIVE-NOT-SUPPORTED:CAPS">NM_DBUS_VPN_INTERACTIVE_NOT_SUPPORTED</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_INTERACTIVE_NOT_SUPPORTED, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-SIGNAL-CONNECT-FAILED:CAPS">NM_DBUS_VPN_SIGNAL_CONNECT_FAILED</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_SIGNAL_CONNECT_FAILED, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-SIGNAL-IP4-CONFIG:CAPS">NM_DBUS_VPN_SIGNAL_IP4_CONFIG</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_SIGNAL_IP4_CONFIG, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-SIGNAL-IP-CONFIG-BAD:CAPS">NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-SIGNAL-LAUNCH-FAILED:CAPS">NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-SIGNAL-LOGIN-BANNER:CAPS">NM_DBUS_VPN_SIGNAL_LOGIN_BANNER</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_SIGNAL_LOGIN_BANNER, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-SIGNAL-LOGIN-FAILED:CAPS">NM_DBUS_VPN_SIGNAL_LOGIN_FAILED</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_SIGNAL_LOGIN_FAILED, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-SIGNAL-STATE-CHANGE:CAPS">NM_DBUS_VPN_SIGNAL_STATE_CHANGE</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_SIGNAL_STATE_CHANGE, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-SIGNAL-VPN-CONFIG-BAD:CAPS">NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-STARTING-IN-PROGRESS:CAPS">NM_DBUS_VPN_STARTING_IN_PROGRESS</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_STARTING_IN_PROGRESS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-STOPPING-IN-PROGRESS:CAPS">NM_DBUS_VPN_STOPPING_IN_PROGRESS</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_STOPPING_IN_PROGRESS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-DBUS-VPN-WRONG-STATE:CAPS">NM_DBUS_VPN_WRONG_STATE</a>, macro in nm-vpn-dbus-interface +NM_DBUS_VPN_WRONG_STATE, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> @@ -5649,6 +5633,14 @@ nm_dbus_path_not_empty, function in <a class="link" href="NMIPConfig.html" title </dt> <dd></dd> <dt> +<a class="link" href="libnm-nm-version.html#NM-DEPRECATED-IN-1-32:CAPS" title="NM_DEPRECATED_IN_1_32">NM_DEPRECATED_IN_1_32</a>, macro in <a class="link" href="libnm-nm-version.html" title="nm-version">nm-version</a> +</dt> +<dd></dd> +<dt> +<a class="link" href="libnm-nm-version.html#NM-DEPRECATED-IN-1-32-FOR:CAPS" title="NM_DEPRECATED_IN_1_32_FOR()">NM_DEPRECATED_IN_1_32_FOR</a>, macro in <a class="link" href="libnm-nm-version.html" title="nm-version">nm-version</a> +</dt> +<dd></dd> +<dt> <a class="link" href="libnm-nm-version.html#NM-DEPRECATED-IN-1-4:CAPS" title="NM_DEPRECATED_IN_1_4">NM_DEPRECATED_IN_1_4</a>, macro in <a class="link" href="libnm-nm-version.html" title="nm-version">nm-version</a> </dt> <dd></dd> @@ -7045,131 +7037,131 @@ NM_ENCODE_VERSION, macro in nm-version-macros </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_ADAPTIVE_RX, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-ADAPTIVE-RX:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_ADAPTIVE_RX</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_ADAPTIVE_TX, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-ADAPTIVE-TX:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_ADAPTIVE_TX</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_PKT_RATE_HIGH, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-PKT-RATE-HIGH:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_PKT_RATE_HIGH</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_PKT_RATE_LOW, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-PKT-RATE-LOW:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_PKT_RATE_LOW</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-RX-FRAMES:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_HIGH, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-RX-FRAMES-HIGH:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_HIGH</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_IRQ, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-RX-FRAMES-IRQ:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_IRQ</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_LOW, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-RX-FRAMES-LOW:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_LOW</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-RX-USECS:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_HIGH, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-RX-USECS-HIGH:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_HIGH</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_IRQ, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-RX-USECS-IRQ:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_IRQ</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_LOW, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-RX-USECS-LOW:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_LOW</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_SAMPLE_INTERVAL, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-SAMPLE-INTERVAL:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_SAMPLE_INTERVAL</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_STATS_BLOCK_USECS, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-STATS-BLOCK-USECS:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_STATS_BLOCK_USECS</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-TX-FRAMES:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_HIGH, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-TX-FRAMES-HIGH:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_HIGH</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_IRQ, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-TX-FRAMES-IRQ:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_IRQ</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_LOW, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-TX-FRAMES-LOW:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_LOW</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-TX-USECS:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_HIGH, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-TX-USECS-HIGH:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_HIGH</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_IRQ, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-TX-USECS-IRQ:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_IRQ</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_LOW, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-COALESCE-TX-USECS-LOW:CAPS">NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_LOW</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_ESP_HW_OFFLOAD, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-ESP-HW-OFFLOAD:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_ESP_HW_OFFLOAD</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-ESP-TX-CSUM-HW-OFFLOAD:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_ESP_TX_CSUM_HW_OFFLOAD</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_FCOE_MTU, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-FCOE-MTU:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_FCOE_MTU</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_GRO, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-GRO:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_GRO</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_GSO, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-GSO:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_GSO</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_HIGHDMA, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-HIGHDMA:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_HIGHDMA</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_HW_TC_OFFLOAD, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-HW-TC-OFFLOAD:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_HW_TC_OFFLOAD</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_L2_FWD_OFFLOAD, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-L2-FWD-OFFLOAD:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_L2_FWD_OFFLOAD</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_LOOPBACK, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-LOOPBACK:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_LOOPBACK</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_LRO, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-LRO:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_LRO</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> @@ -7177,31 +7169,31 @@ NM_ETHTOOL_OPTNAME_FEATURE_MACSEC_HW_OFFLOAD, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_NTUPLE, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-NTUPLE:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_NTUPLE</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_RX, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-RX:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_RX</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_RXHASH, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-RXHASH:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_RXHASH</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-RXVLAN:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_RX_ALL, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-RX-ALL:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_RX_ALL</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_RX_FCS, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-RX-FCS:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_RX_FCS</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_RX_GRO_HW, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-RX-GRO-HW:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_RX_GRO_HW</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> @@ -7213,27 +7205,27 @@ NM_ETHTOOL_OPTNAME_FEATURE_RX_UDP_GRO_FORWARDING, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-RX-UDP-TUNNEL-PORT-OFFLOAD:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_FILTER, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-RX-VLAN-FILTER:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_FILTER</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_STAG_FILTER, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-RX-VLAN-STAG-FILTER:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_STAG_FILTER</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_STAG_HW_PARSE, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-RX-VLAN-STAG-HW-PARSE:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_STAG_HW_PARSE</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_SG, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-SG:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_SG</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_RECORD, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TLS-HW-RECORD:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_RECORD</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> @@ -7241,55 +7233,55 @@ NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_RX_OFFLOAD, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_TX_OFFLOAD, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TLS-HW-TX-OFFLOAD:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_TX_OFFLOAD</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TSO, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TSO:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TSO</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TXVLAN:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_FCOE_CRC, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-CHECKSUM-FCOE-CRC:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_FCOE_CRC</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IPV4, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-CHECKSUM-IPV4:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IPV4</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IPV6, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-CHECKSUM-IPV6:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IPV6</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IP_GENERIC, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-CHECKSUM-IP-GENERIC:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IP_GENERIC</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_SCTP, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-CHECKSUM-SCTP:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_SCTP</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_ESP_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-ESP-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_ESP_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_FCOE_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-FCOE-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_FCOE_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_GRE_CSUM_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-GRE-CSUM-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_GRE_CSUM_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_GRE_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-GRE-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_GRE_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> @@ -7297,51 +7289,51 @@ NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_LIST, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_PARTIAL, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-GSO-PARTIAL:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_PARTIAL</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_ROBUST, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-GSO-ROBUST:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_ROBUST</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_IPXIP4_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-IPXIP4-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_IPXIP4_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_IPXIP6_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-IPXIP6-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_IPXIP6_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_NOCACHE_COPY, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-NOCACHE-COPY:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_NOCACHE_COPY</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_SCATTER_GATHER, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-SCATTER-GATHER:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_SCATTER_GATHER</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_SCATTER_GATHER_FRAGLIST, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-SCATTER-GATHER-FRAGLIST:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_SCATTER_GATHER_FRAGLIST</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_SCTP_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-SCTP-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_SCTP_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP6_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-TCP6-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP6_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_ECN_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-TCP-ECN-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_ECN_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-TCP-MANGLEID-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_MANGLEID_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-TCP-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> @@ -7349,19 +7341,19 @@ NM_ETHTOOL_OPTNAME_FEATURE_TX_TUNNEL_REMCSUM_SEGMENTATION, macro in nm-ethtool-u </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-UDP-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-UDP-TNL-CSUM-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_TNL_SEGMENTATION, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-UDP-TNL-SEGMENTATION:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_TNL_SEGMENTATION</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_FEATURE_TX_VLAN_STAG_HW_INSERT, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-FEATURE-TX-VLAN-STAG-HW-INSERT:CAPS">NM_ETHTOOL_OPTNAME_FEATURE_TX_VLAN_STAG_HW_INSERT</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> @@ -7377,19 +7369,19 @@ NM_ETHTOOL_OPTNAME_FEATURE_TX_VLAN_STAG_HW_INSERT, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_RING_RX, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-RING-RX:CAPS">NM_ETHTOOL_OPTNAME_RING_RX</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-RING-RX-JUMBO:CAPS">NM_ETHTOOL_OPTNAME_RING_RX_JUMBO</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_RING_RX_MINI, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-RING-RX-MINI:CAPS">NM_ETHTOOL_OPTNAME_RING_RX_MINI</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> -NM_ETHTOOL_OPTNAME_RING_TX, macro in nm-ethtool-utils +<a href="NMSettingEthtool.html#NM-ETHTOOL-OPTNAME-RING-TX:CAPS">NM_ETHTOOL_OPTNAME_RING_TX</a>, macro in nm-ethtool-utils </dt> <dd></dd> <dt> @@ -7785,6 +7777,10 @@ NM_ETHTOOL_OPTNAME_RING_TX, macro in nm-ethtool-utils </dt> <dd></dd> <dt> +<a class="link" href="NMSettingIPConfig.html#nm-ip-routing-rule-get-uid-range" title="nm_ip_routing_rule_get_uid_range ()">nm_ip_routing_rule_get_uid_range</a>, function in <a class="link" href="NMSettingIPConfig.html" title="NMSettingIPConfig">NMSettingIPConfig</a> +</dt> +<dd></dd> +<dt> <a class="link" href="NMSettingIPConfig.html#nm-ip-routing-rule-is-sealed" title="nm_ip_routing_rule_is_sealed ()">nm_ip_routing_rule_is_sealed</a>, function in <a class="link" href="NMSettingIPConfig.html" title="NMSettingIPConfig">NMSettingIPConfig</a> </dt> <dd></dd> @@ -7861,6 +7857,10 @@ NM_ETHTOOL_OPTNAME_RING_TX, macro in nm-ethtool-utils </dt> <dd></dd> <dt> +<a class="link" href="NMSettingIPConfig.html#nm-ip-routing-rule-set-uid-range" title="nm_ip_routing_rule_set_uid_range ()">nm_ip_routing_rule_set_uid_range</a>, function in <a class="link" href="NMSettingIPConfig.html" title="NMSettingIPConfig">NMSettingIPConfig</a> +</dt> +<dd></dd> +<dt> <a class="link" href="NMSettingIPConfig.html#nm-ip-routing-rule-to-string" title="nm_ip_routing_rule_to_string ()">nm_ip_routing_rule_to_string</a>, function in <a class="link" href="NMSettingIPConfig.html" title="NMSettingIPConfig">NMSettingIPConfig</a> </dt> <dd></dd> @@ -8037,18 +8037,6 @@ NM_MAJOR_VERSION, macro in nm-version-macros </dt> <dd></dd> <dt> -nm_meta_setting_infos_by_gtype, function in nm-meta-setting-base-impl -</dt> -<dd></dd> -<dt> -nm_meta_setting_infos_by_name, function in nm-meta-setting-base-impl -</dt> -<dd></dd> -<dt> -nm_meta_setting_info_get_base_type_priority, function in nm-meta-setting-base-impl -</dt> -<dd></dd> -<dt> NM_MICRO_VERSION, macro in nm-version-macros </dt> <dd></dd> @@ -14137,6 +14125,10 @@ NM_VERSION_1_30, macro in nm-version-macros </dt> <dd></dd> <dt> +NM_VERSION_1_32, macro in nm-version-macros +</dt> +<dd></dd> +<dt> NM_VERSION_1_4, macro in nm-version-macros </dt> <dd></dd> @@ -14185,11 +14177,11 @@ NM_VERSION_NEXT_STABLE, macro in nm-version-macros </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-DBUS-PLUGIN-INTERFACE:CAPS">NM_VPN_DBUS_PLUGIN_INTERFACE</a>, macro in nm-vpn-dbus-interface +NM_VPN_DBUS_PLUGIN_INTERFACE, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-DBUS-PLUGIN-PATH:CAPS">NM_VPN_DBUS_PLUGIN_PATH</a>, macro in nm-vpn-dbus-interface +NM_VPN_DBUS_PLUGIN_PATH, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> @@ -14257,27 +14249,27 @@ NM_VERSION_NEXT_STABLE, macro in nm-version-macros </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-CAN-PERSIST:CAPS">NM_VPN_PLUGIN_CAN_PERSIST</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_CAN_PERSIST, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-CONFIG-BANNER:CAPS">NM_VPN_PLUGIN_CONFIG_BANNER</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_CONFIG_BANNER, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-CONFIG-EXT-GATEWAY:CAPS">NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-CONFIG-HAS-IP4:CAPS">NM_VPN_PLUGIN_CONFIG_HAS_IP4</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_CONFIG_HAS_IP4, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-CONFIG-HAS-IP6:CAPS">NM_VPN_PLUGIN_CONFIG_HAS_IP6</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_CONFIG_HAS_IP6, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-CONFIG-MTU:CAPS">NM_VPN_PLUGIN_CONFIG_MTU</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_CONFIG_MTU, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> @@ -14285,7 +14277,7 @@ NM_VPN_PLUGIN_CONFIG_PROXY_PAC, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-CONFIG-TUNDEV:CAPS">NM_VPN_PLUGIN_CONFIG_TUNDEV</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_CONFIG_TUNDEV, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> @@ -14421,55 +14413,55 @@ NM_VPN_PLUGIN_CONFIG_PROXY_PAC, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-ADDRESS:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-BANNER:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_BANNER</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_BANNER, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-DNS:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_DNS</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_DNS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-DOMAIN:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-DOMAINS:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-EXT-GATEWAY:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-GATEWAY:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-INT-GATEWAY:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-MSS:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_MSS</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_MSS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-MTU:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_MTU</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_MTU, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-NBNS:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_NBNS</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_NBNS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-NEVER-DEFAULT:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-PREFIX:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_PREFIX</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> @@ -14477,47 +14469,47 @@ NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-PTP:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_PTP</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_PTP, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-ROUTES:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_ROUTES</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP4-CONFIG-TUNDEV:CAPS">NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP6-CONFIG-ADDRESS:CAPS">NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP6-CONFIG-DNS:CAPS">NM_VPN_PLUGIN_IP6_CONFIG_DNS</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP6_CONFIG_DNS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP6-CONFIG-DOMAIN:CAPS">NM_VPN_PLUGIN_IP6_CONFIG_DOMAIN</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP6_CONFIG_DOMAIN, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP6-CONFIG-DOMAINS:CAPS">NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP6-CONFIG-INT-GATEWAY:CAPS">NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP6-CONFIG-MSS:CAPS">NM_VPN_PLUGIN_IP6_CONFIG_MSS</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP6_CONFIG_MSS, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP6-CONFIG-NEVER-DEFAULT:CAPS">NM_VPN_PLUGIN_IP6_CONFIG_NEVER_DEFAULT</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP6_CONFIG_NEVER_DEFAULT, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP6-CONFIG-PREFIX:CAPS">NM_VPN_PLUGIN_IP6_CONFIG_PREFIX</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP6_CONFIG_PREFIX, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> @@ -14525,11 +14517,11 @@ NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP6-CONFIG-PTP:CAPS">NM_VPN_PLUGIN_IP6_CONFIG_PTP</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP6_CONFIG_PTP, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> -<a href="/usr/share/gtk-doc/html/libnm-util/libnm-util-NetworkManagerVPN.html#NM-VPN-PLUGIN-IP6-CONFIG-ROUTES:CAPS">NM_VPN_PLUGIN_IP6_CONFIG_ROUTES</a>, macro in nm-vpn-dbus-interface +NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, macro in nm-vpn-dbus-interface </dt> <dd></dd> <dt> @@ -14895,6 +14887,6 @@ NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES, macro in nm-vpn-dbus-interface <dd></dd> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/ch02.html b/docs/libnm/html/ch02.html index 47a7dab..bd869fe 100644 --- a/docs/libnm/html/ch02.html +++ b/docs/libnm/html/ch02.html @@ -8,7 +8,7 @@ <link rel="up" href="index.html" title="libnm Reference Manual"> <link rel="prev" href="usage.html" title="Using libnm"> <link rel="next" href="NMClient.html" title="NMClient"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -41,6 +41,6 @@ </dl></div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/ch03.html b/docs/libnm/html/ch03.html index 90068a2..e6b5dbe 100644 --- a/docs/libnm/html/ch03.html +++ b/docs/libnm/html/ch03.html @@ -8,7 +8,7 @@ <link rel="up" href="index.html" title="libnm Reference Manual"> <link rel="prev" href="libnm-nm-dbus-interface.html" title="nm-dbus-interface"> <link rel="next" href="NMConnection.html" title="NMConnection"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -198,6 +198,6 @@ use WEP, LEAP, WPA or WPA2/RSN security</span> </dl></div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/ch04.html b/docs/libnm/html/ch04.html index bc92ddc..6667285 100644 --- a/docs/libnm/html/ch04.html +++ b/docs/libnm/html/ch04.html @@ -8,7 +8,7 @@ <link rel="up" href="index.html" title="libnm Reference Manual"> <link rel="prev" href="NMSettingWpan.html" title="NMSettingWpan"> <link rel="next" href="NMDevice.html" title="NMDevice"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -140,6 +140,6 @@ </dl></div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/ch05.html b/docs/libnm/html/ch05.html index 1fabc6f..68c1a7f 100644 --- a/docs/libnm/html/ch05.html +++ b/docs/libnm/html/ch05.html @@ -8,7 +8,7 @@ <link rel="up" href="index.html" title="libnm Reference Manual"> <link rel="prev" href="NMCheckpoint.html" title="NMCheckpoint"> <link rel="next" href="libnm-nm-keyfile.html" title="nm-keyfile"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -35,6 +35,6 @@ </dl></div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/ch06.html b/docs/libnm/html/ch06.html index b8bcee8..5ba9000 100644 --- a/docs/libnm/html/ch06.html +++ b/docs/libnm/html/ch06.html @@ -8,7 +8,7 @@ <link rel="up" href="index.html" title="libnm Reference Manual"> <link rel="prev" href="libnm-nm-version.html" title="nm-version"> <link rel="next" href="NMVpnServicePlugin.html" title="NMVpnServicePlugin"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -41,6 +41,6 @@ </dl></div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/index.html b/docs/libnm/html/index.html index 87013ed..f725d8a 100644 --- a/docs/libnm/html/index.html +++ b/docs/libnm/html/index.html @@ -6,7 +6,7 @@ <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot"> <link rel="home" href="index.html" title="libnm Reference Manual"> <link rel="next" href="ref-overview.html" title="Overview"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -15,7 +15,7 @@ <div> <div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">libnm Reference Manual</p></th></tr></table></div> <div><p class="releaseinfo"> - for libnm 1.30.0 + for libnm 1.31.2 The latest version of this documentation can be found on-line at <a class="ulink" href="https://developer.gnome.org/libnm/stable/" target="_top">https://developer.gnome.org/libnm/stable/</a>. @@ -399,6 +399,6 @@ use WEP, LEAP, WPA or WPA2/RSN security</span> </dl></div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/libnm-nm-dbus-interface.html b/docs/libnm/html/libnm-nm-dbus-interface.html index 4a8561d..aeeb13e 100644 --- a/docs/libnm/html/libnm-nm-dbus-interface.html +++ b/docs/libnm/html/libnm-nm-dbus-interface.html @@ -8,7 +8,7 @@ <link rel="up" href="ch02.html" title="Client Object API Reference"> <link rel="prev" href="libnm-nm-errors.html" title="nm-errors"> <link rel="next" href="ch03.html" title="Connection and Setting API Reference"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -4007,6 +4007,6 @@ denied by system policy</p> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/libnm-nm-errors.html b/docs/libnm/html/libnm-nm-errors.html index 4757417..2977a95 100644 --- a/docs/libnm/html/libnm-nm-errors.html +++ b/docs/libnm/html/libnm-nm-errors.html @@ -8,7 +8,7 @@ <link rel="up" href="ch02.html" title="Client Object API Reference"> <link rel="prev" href="NMObject.html" title="NMObject"> <link rel="next" href="libnm-nm-dbus-interface.html" title="nm-dbus-interface"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -254,7 +254,7 @@ nm_vpn_plugin_error_quark (<em class="parameter"><code><span class="type">void</ <a name="NMAgentManagerError"></a><h3>enum NMAgentManagerError</h3> <p>Errors returned from the secret-agent manager.</p> <p>These errors may be returned from operations that could cause secrets to be -requested (such as <a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#nm-client-activate-connection"><code class="function">nm_client_activate_connection()</code></a>), and correspond to D-Bus +requested (such as <code class="function">nm_client_activate_connection()</code>), and correspond to D-Bus errors in the "org.freedesktop.NetworkManager.AgentManager" namespace.</p> <div class="refsect3"> <a name="NMAgentManagerError.members"></a><h4>Members</h4> @@ -737,7 +737,7 @@ activation but is not available.</p> when they encounter problems retrieving secrets on behalf of NM. They correspond to errors in the "org.freedesktop.NetworkManager.SecretManager" namespace.</p> -<p>Client APIs such as <a href="/usr/share/gtk-doc/html/libnm-glib/NMClient.html#nm-client-activate-connection"><code class="function">nm_client_activate_connection()</code></a> will not see these error +<p>Client APIs such as <code class="function">nm_client_activate_connection()</code> will not see these error codes; instead, the secret agent manager will translate them to the corresponding <a class="link" href="libnm-nm-errors.html#NMAgentManagerError" title="enum NMAgentManagerError"><span class="type">NMAgentManagerError</span></a> codes.</p> <div class="refsect3"> @@ -998,6 +998,6 @@ performed as the plugin does not support interactive operations, such as </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/libnm-nm-keyfile.html b/docs/libnm/html/libnm-nm-keyfile.html index ddd85e1..21a6d7d 100644 --- a/docs/libnm/html/libnm-nm-keyfile.html +++ b/docs/libnm/html/libnm-nm-keyfile.html @@ -8,7 +8,7 @@ <link rel="up" href="ch05.html" title="Utility API Reference"> <link rel="prev" href="ch05.html" title="Utility API Reference"> <link rel="next" href="libnm-nm-utils.html" title="nm-utils"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -259,7 +259,7 @@ be an absolute path.</p></td> <div class="refsect3"> <a name="nm-keyfile-read.returns"></a><h4>Returns</h4> <p>on success, returns the created connection. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.30</p> </div> @@ -384,7 +384,7 @@ to override the default behavior. </p></td> <div class="refsect3"> <a name="nm-keyfile-write.returns"></a><h4>Returns</h4> <p>a new <a href="https://developer.gnome.org/glib/unstable/glib-Key-value-file-parser.html#GKeyFile"><span class="type">GKeyFile</span></a> or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.30</p> </div> @@ -420,7 +420,7 @@ after calling this function on it.</p> <tr> <td class="parameter_name"><p>src</p></td> <td class="parameter_description"><p>error to move into the return location. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -456,24 +456,24 @@ on all events, but the context information may be unset.</p> <td class="parameter_name"><p>out_kf_group_name</p></td> <td class="parameter_description"><p>if the event is in the context of a keyfile group, the group name. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>out_kf_key_name</p></td> <td class="parameter_description"><p>if the event is in the context of a keyfile value, the key name. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>out_cur_setting</p></td> <td class="parameter_description"><p>if the event happens while handling a particular <a class="link" href="NMSetting.html" title="NMSetting"><span class="type">NMSetting</span></a> instance. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>out_cur_property_name</p></td> <td class="parameter_description"><p>the property name if applicable. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -505,7 +505,7 @@ event.</p></td> <tr> <td class="parameter_name"><p>out_message</p></td> <td class="parameter_description"><p>the warning message. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td> </tr> <tr> <td class="parameter_name"><p>out_severity</p></td> @@ -634,6 +634,6 @@ depends on the <a class="link" href="libnm-nm-keyfile.html#NMKeyfileHandlerType" </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/libnm-nm-utils.html b/docs/libnm/html/libnm-nm-utils.html index b4e0e2b..a76610a 100644 --- a/docs/libnm/html/libnm-nm-utils.html +++ b/docs/libnm/html/libnm-nm-utils.html @@ -8,7 +8,7 @@ <link rel="up" href="ch05.html" title="Utility API Reference"> <link rel="prev" href="libnm-nm-keyfile.html" title="nm-keyfile"> <link rel="next" href="libnm-nm-version.html" title="nm-version"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -877,7 +877,7 @@ _only_.</p> <p>an allocated string containing a UTF-8 representation of the SSID, which must be freed by the caller using <a href="https://developer.gnome.org/glib/unstable/glib-Memory-Allocation.html#g-free"><code class="function">g_free()</code></a>. Returns <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on errors. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -1124,7 +1124,7 @@ type 'au' representing an array of IPv4 addresses.</p> <a name="nm-utils-ip4-dns-to-variant.returns"></a><h4>Returns</h4> <p>a new floating <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> representing <em class="parameter"><code>dns</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1152,7 +1152,7 @@ IPv4 addresses into an array of IP address strings.</p> <div class="refsect3"> <a name="nm-utils-ip4-dns-from-variant.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of IP address strings. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Override the parsed C type with given type."><span class="acronym">type</span></acronym> utf8]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Override the parsed C type with given type."><span class="acronym">type</span></acronym> utf8]</span></p> </div> </div> <hr> @@ -1193,7 +1193,7 @@ gateway). The "gateway" field of the first address will get the value of <a name="nm-utils-ip4-addresses-to-variant.returns"></a><h4>Returns</h4> <p>a new floating <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> representing <em class="parameter"><code>addresses</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1225,7 +1225,7 @@ of the other addresses are ignored.</p> <tr> <td class="parameter_name"><p>out_gateway</p></td> <td class="parameter_description"><p>on return, will contain the IP gateway. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -1234,7 +1234,7 @@ of the other addresses are ignored.</p> <a name="nm-utils-ip4-addresses-from-variant.returns"></a><h4>Returns</h4> <p>a newly allocated <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> of <a class="link" href="NMSettingIPConfig.html#NMIPAddress"><span class="type">NMIPAddress</span></a> objects. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPAddress]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPAddress]</span></p> </div> </div> <hr> @@ -1265,7 +1265,7 @@ metric).</p> <a name="nm-utils-ip4-routes-to-variant.returns"></a><h4>Returns</h4> <p>a new floating <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> representing <em class="parameter"><code>routes</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1295,7 +1295,7 @@ and metric) into a <a href="https://developer.gnome.org/glib/unstable/glib-Point <a name="nm-utils-ip4-routes-from-variant.returns"></a><h4>Returns</h4> <p>a newly allocated <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> of <a class="link" href="NMSettingIPConfig.html#NMIPRoute"><span class="type">NMIPRoute</span></a> objects. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPRoute]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPRoute]</span></p> </div> </div> <hr> @@ -1404,7 +1404,7 @@ type 'aay' representing an array of IPv6 addresses.</p> <a name="nm-utils-ip6-dns-to-variant.returns"></a><h4>Returns</h4> <p>a new floating <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> representing <em class="parameter"><code>dns</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1434,7 +1434,7 @@ ignored.</p> <div class="refsect3"> <a name="nm-utils-ip6-dns-from-variant.returns"></a><h4>Returns</h4> <p>a <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of IP address strings. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Override the parsed C type with given type."><span class="acronym">type</span></acronym> utf8]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Override the parsed C type with given type."><span class="acronym">type</span></acronym> utf8]</span></p> </div> </div> <hr> @@ -1476,7 +1476,7 @@ all 0s.</p> <a name="nm-utils-ip6-addresses-to-variant.returns"></a><h4>Returns</h4> <p>a new floating <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> representing <em class="parameter"><code>addresses</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1508,7 +1508,7 @@ fields of the other addresses are ignored.</p> <tr> <td class="parameter_name"><p>out_gateway</p></td> <td class="parameter_description"><p>on return, will contain the IP gateway. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -1517,7 +1517,7 @@ fields of the other addresses are ignored.</p> <a name="nm-utils-ip6-addresses-from-variant.returns"></a><h4>Returns</h4> <p>a newly allocated <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> of <a class="link" href="NMSettingIPConfig.html#NMIPAddress"><span class="type">NMIPAddress</span></a> objects. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPAddress]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPAddress]</span></p> </div> </div> <hr> @@ -1548,7 +1548,7 @@ metric).</p> <a name="nm-utils-ip6-routes-to-variant.returns"></a><h4>Returns</h4> <p>a new floating <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> representing <em class="parameter"><code>routes</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1578,7 +1578,7 @@ hop, and metric) into a <a href="https://developer.gnome.org/glib/unstable/glib- <a name="nm-utils-ip6-routes-from-variant.returns"></a><h4>Returns</h4> <p>a newly allocated <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> of <a class="link" href="NMSettingIPConfig.html#NMIPRoute"><span class="type">NMIPRoute</span></a> objects. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPRoute]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPRoute]</span></p> </div> </div> <hr> @@ -1610,7 +1610,7 @@ include additional attributes.</p> <a name="nm-utils-ip-addresses-to-variant.returns"></a><h4>Returns</h4> <p>a new floating <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> representing <em class="parameter"><code>addresses</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1649,7 +1649,7 @@ objects.</p> <a name="nm-utils-ip-addresses-from-variant.returns"></a><h4>Returns</h4> <p>a newly allocated <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> of <a class="link" href="NMSettingIPConfig.html#NMIPAddress"><span class="type">NMIPAddress</span></a> objects. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPAddress]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPAddress]</span></p> </div> </div> <hr> @@ -1680,7 +1680,7 @@ prefix, next hop, metric, and additional attributes).</p> <a name="nm-utils-ip-routes-to-variant.returns"></a><h4>Returns</h4> <p>a new floating <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> representing <em class="parameter"><code>routes</code></em> . </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -1719,7 +1719,7 @@ prefix, next hop, metric, and additional attributes) into a <a href="https://dev <a name="nm-utils-ip-routes-from-variant.returns"></a><h4>Returns</h4> <p>a newly allocated <a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> of <a class="link" href="NMSettingIPConfig.html#NMIPRoute"><span class="type">NMIPRoute</span></a> objects. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPRoute]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> NMIPRoute]</span></p> </div> </div> <hr> @@ -1920,7 +1920,7 @@ function. </p></td> <p>the full path to the helper, if found, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if not found. The returned string is not owned by the caller, but later invocations of the function might overwrite it. </p> -<p><span class="annotation">[<acronym title="The data is owned by the callee, which is responsible of freeing it."><span class="acronym">transfer none</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p> </div> </div> <hr> @@ -2180,7 +2180,7 @@ nm_utils_hwaddr_ntoa (<em class="parameter"><code><a href="https://developer.gno <a name="nm-utils-hwaddr-ntoa.returns"></a><h4>Returns</h4> <p>the textual form of <em class="parameter"><code>addr</code></em> . </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2219,7 +2219,7 @@ nm_utils_hwaddr_atoba (<em class="parameter"><code>const <span class="type">char <p>a new <a href="https://developer.gnome.org/glib/unstable/glib-Byte-Arrays.html#GByteArray"><span class="type">GByteArray</span></a>, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if <em class="parameter"><code>asc</code></em> couldn't be parsed. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2350,7 +2350,7 @@ is expected to convert to <p>the canonicalized address if <em class="parameter"><code>asc</code></em> appears to be a valid hardware address of the indicated length, <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if not. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2480,7 +2480,7 @@ array</p></td> <a name="nm-utils-bin2hexstr.returns"></a><h4>Returns</h4> <p>the textual form of <em class="parameter"><code>bytes</code></em> . </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2513,7 +2513,7 @@ may not start or end with ':'.</p> <div class="refsect3"> <a name="nm-utils-hexstr2bin.returns"></a><h4>Returns</h4> <p>the converted bytes, or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> </div> <hr> @@ -2945,7 +2945,7 @@ containing the unrecognized token in <em class="parameter"><code>err_token</code <tr> <td class="parameter_name"><p>err_token</p></td> <td class="parameter_description"><p>location to store the first unrecognized token. </p></td> -<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></td> +<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td> </tr> </tbody> </table></div> @@ -2995,7 +2995,7 @@ nm_utils_enum_get_values (<em class="parameter"><code><a href="https://developer <a name="nm-utils-enum-get-values.returns"></a><h4>Returns</h4> <p>a NULL-terminated dynamically-allocated array of static strings or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> on error. </p> -<p><span class="annotation">[<acronym title="The caller owns the data container, but not the data inside it."><span class="acronym">transfer container</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data container after the code is done."><span class="acronym">transfer container</span></acronym>]</span></p> </div> <p class="since">Since: 1.2</p> </div> @@ -3070,7 +3070,7 @@ nm_utils_parse_variant_attributes (<em class="parameter"><code>const <span class attribute names to <a href="https://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariant"><span class="type">GVariant</span></a> values. Warning: the variant are still floating references, owned by the hash table. If you take a reference, ensure to sink the one of the hash table first. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8 GVariant]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> utf8 GVariant]</span></p> </div> <p class="since">Since: 1.8</p> </div> @@ -3371,7 +3371,7 @@ nm_utils_sriov_vf_from_str (<em class="parameter"><code>const <span class="type" <div class="refsect3"> <a name="nm-utils-sriov-vf-from-str.returns"></a><h4>Returns</h4> <p>the virtual function object. </p> -<p><span class="annotation">[<acronym title="The caller owns the data, and is responsible for free it."><span class="acronym">transfer full</span></acronym>]</span></p> +<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p> </div> <p class="since">Since: 1.14</p> </div> @@ -3568,6 +3568,6 @@ for both <a class="link" href="libnm-nm-utils.html#nm-utils-inet4-ntop" title="n </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/libnm-nm-version.html b/docs/libnm/html/libnm-nm-version.html index 3c12ebe..86e1fb2 100644 --- a/docs/libnm/html/libnm-nm-version.html +++ b/docs/libnm/html/libnm-nm-version.html @@ -8,7 +8,7 @@ <link rel="up" href="ch05.html" title="Utility API Reference"> <link rel="prev" href="libnm-nm-utils.html" title="nm-utils"> <link rel="next" href="ch06.html" title="VPN Plugin API Reference"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -143,6 +143,12 @@ <a class="link" href="libnm-nm-version.html#NM-DEPRECATED-IN-1-30-FOR:CAPS" title="NM_DEPRECATED_IN_1_30_FOR()">NM_DEPRECATED_IN_1_30_FOR</a><span class="c_punctuation">()</span> </td> </tr> +<tr> +<td class="define_keyword">#define</td> +<td class="function_name"> +<a class="link" href="libnm-nm-version.html#NM-DEPRECATED-IN-1-32-FOR:CAPS" title="NM_DEPRECATED_IN_1_32_FOR()">NM_DEPRECATED_IN_1_32_FOR</a><span class="c_punctuation">()</span> +</td> +</tr> </tbody> </table></div> </div> @@ -298,6 +304,14 @@ <td class="define_keyword">#define</td> <td class="function_name"><a class="link" href="libnm-nm-version.html#NM-AVAILABLE-IN-1-30:CAPS" title="NM_AVAILABLE_IN_1_30">NM_AVAILABLE_IN_1_30</a></td> </tr> +<tr> +<td class="define_keyword">#define</td> +<td class="function_name"><a class="link" href="libnm-nm-version.html#NM-DEPRECATED-IN-1-32:CAPS" title="NM_DEPRECATED_IN_1_32">NM_DEPRECATED_IN_1_32</a></td> +</tr> +<tr> +<td class="define_keyword">#define</td> +<td class="function_name"><a class="link" href="libnm-nm-version.html#NM-AVAILABLE-IN-1-32:CAPS" title="NM_AVAILABLE_IN_1_32">NM_AVAILABLE_IN_1_32</a></td> +</tr> </tbody> </table></div> </div> @@ -407,6 +421,12 @@ NM_DEPRECATED_IN_1_24_FOR ();</pre> <pre class="programlisting"> #define NM_DEPRECATED_IN_1_30_FOR(f) G_DEPRECATED_FOR(f) </pre> </div> +<hr> +<div class="refsect2"> +<a name="NM-DEPRECATED-IN-1-32-FOR:CAPS"></a><h3>NM_DEPRECATED_IN_1_32_FOR()</h3> +<pre class="programlisting"> #define NM_DEPRECATED_IN_1_32_FOR(f) G_DEPRECATED_FOR(f) +</pre> +</div> </div> <div class="refsect1"> <a name="libnm-nm-version.other_details"></a><h2>Types and Values</h2> @@ -623,9 +643,21 @@ NM_DEPRECATED_IN_1_24_FOR ();</pre> <pre class="programlisting"> #define NM_AVAILABLE_IN_1_30 G_UNAVAILABLE(1, 30) </pre> </div> +<hr> +<div class="refsect2"> +<a name="NM-DEPRECATED-IN-1-32:CAPS"></a><h3>NM_DEPRECATED_IN_1_32</h3> +<pre class="programlisting"> #define NM_DEPRECATED_IN_1_32 G_DEPRECATED +</pre> +</div> +<hr> +<div class="refsect2"> +<a name="NM-AVAILABLE-IN-1-32:CAPS"></a><h3>NM_AVAILABLE_IN_1_32</h3> +<pre class="programlisting"> #define NM_AVAILABLE_IN_1_32 G_UNAVAILABLE(1, 32) +</pre> +</div> </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/libnm.devhelp2 b/docs/libnm/html/libnm.devhelp2 index 3962206..acaefbd 100644 --- a/docs/libnm/html/libnm.devhelp2 +++ b/docs/libnm/html/libnm.devhelp2 @@ -1338,6 +1338,8 @@ <keyword type="function" name="nm_ip_routing_rule_set_table ()" link="NMSettingIPConfig.html#nm-ip-routing-rule-set-table" since="1.18"/> <keyword type="function" name="nm_ip_routing_rule_get_suppress_prefixlength ()" link="NMSettingIPConfig.html#nm-ip-routing-rule-get-suppress-prefixlength" since="1.20"/> <keyword type="function" name="nm_ip_routing_rule_set_suppress_prefixlength ()" link="NMSettingIPConfig.html#nm-ip-routing-rule-set-suppress-prefixlength" since="1.20"/> + <keyword type="function" name="nm_ip_routing_rule_get_uid_range ()" link="NMSettingIPConfig.html#nm-ip-routing-rule-get-uid-range" since="1.32"/> + <keyword type="function" name="nm_ip_routing_rule_set_uid_range ()" link="NMSettingIPConfig.html#nm-ip-routing-rule-set-uid-range" since="1.32"/> <keyword type="function" name="nm_ip_routing_rule_cmp ()" link="NMSettingIPConfig.html#nm-ip-routing-rule-cmp" since="1.18"/> <keyword type="function" name="nm_ip_routing_rule_validate ()" link="NMSettingIPConfig.html#nm-ip-routing-rule-validate" since="1.18"/> <keyword type="function" name="nm_ip_routing_rule_from_string ()" link="NMSettingIPConfig.html#nm-ip-routing-rule-from-string" since="1.18"/> @@ -1573,7 +1575,7 @@ <keyword type="property" name="The “parent” property" link="NMSettingMacvlan.html#NMSettingMacvlan--parent"/> <keyword type="property" name="The “promiscuous” property" link="NMSettingMacvlan.html#NMSettingMacvlan--promiscuous"/> <keyword type="property" name="The “tap” property" link="NMSettingMacvlan.html#NMSettingMacvlan--tap"/> - <keyword type="function" name="nm_setting_match_new ()" link="NMSettingMatch.html#nm-setting-match-new" since="1.14"/> + <keyword type="function" name="nm_setting_match_new ()" link="NMSettingMatch.html#nm-setting-match-new" since="1.32"/> <keyword type="function" name="nm_setting_match_get_num_interface_names ()" link="NMSettingMatch.html#nm-setting-match-get-num-interface-names" since="1.14"/> <keyword type="function" name="nm_setting_match_get_interface_name ()" link="NMSettingMatch.html#nm-setting-match-get-interface-name" since="1.14"/> <keyword type="function" name="nm_setting_match_remove_interface_name ()" link="NMSettingMatch.html#nm-setting-match-remove-interface-name" since="1.14"/> @@ -2491,14 +2493,14 @@ <keyword type="function" name="nm_device_connection_valid ()" link="NMDevice.html#nm-device-connection-valid"/> <keyword type="function" name="nm_device_connection_compatible ()" link="NMDevice.html#nm-device-connection-compatible"/> <keyword type="function" name="nm_device_get_setting_type ()" link="NMDevice.html#nm-device-get-setting-type"/> - <keyword type="function" name="nm_lldp_neighbor_new ()" link="NMDevice.html#nm-lldp-neighbor-new" since="1.2"/> <keyword type="function" name="nm_lldp_neighbor_ref ()" link="NMDevice.html#nm-lldp-neighbor-ref" since="1.2"/> <keyword type="function" name="nm_lldp_neighbor_unref ()" link="NMDevice.html#nm-lldp-neighbor-unref" since="1.2"/> <keyword type="function" name="nm_lldp_neighbor_get_attr_names ()" link="NMDevice.html#nm-lldp-neighbor-get-attr-names" since="1.2"/> + <keyword type="function" name="nm_lldp_neighbor_get_attr_value ()" link="NMDevice.html#nm-lldp-neighbor-get-attr-value" since="1.18"/> + <keyword type="function" name="nm_lldp_neighbor_new ()" link="NMDevice.html#nm-lldp-neighbor-new" since="1.2"/> <keyword type="function" name="nm_lldp_neighbor_get_attr_string_value ()" link="NMDevice.html#nm-lldp-neighbor-get-attr-string-value" since="1.2"/> <keyword type="function" name="nm_lldp_neighbor_get_attr_uint_value ()" link="NMDevice.html#nm-lldp-neighbor-get-attr-uint-value" since="1.2"/> <keyword type="function" name="nm_lldp_neighbor_get_attr_type ()" link="NMDevice.html#nm-lldp-neighbor-get-attr-type" since="1.2"/> - <keyword type="function" name="nm_lldp_neighbor_get_attr_value ()" link="NMDevice.html#nm-lldp-neighbor-get-attr-value" since="1.18"/> <keyword type="macro" name="NM_DEVICE_DEVICE_TYPE" link="NMDevice.html#NM-DEVICE-DEVICE-TYPE:CAPS"/> <keyword type="macro" name="NM_DEVICE_UDI" link="NMDevice.html#NM-DEVICE-UDI:CAPS"/> <keyword type="macro" name="NM_DEVICE_PATH" link="NMDevice.html#NM-DEVICE-PATH:CAPS"/> @@ -2531,6 +2533,7 @@ <keyword type="macro" name="NM_DEVICE_IP6_CONNECTIVITY" link="NMDevice.html#NM-DEVICE-IP6-CONNECTIVITY:CAPS"/> <keyword type="macro" name="NM_DEVICE_INTERFACE_FLAGS" link="NMDevice.html#NM-DEVICE-INTERFACE-FLAGS:CAPS"/> <keyword type="macro" name="NM_DEVICE_HW_ADDRESS" link="NMDevice.html#NM-DEVICE-HW-ADDRESS:CAPS"/> + <keyword type="struct" name="NMLldpNeighbor" link="NMDevice.html#NMLldpNeighbor-struct"/> <keyword type="function" name="nm_device_6lowpan_get_parent ()" link="NMDevice6Lowpan.html#nm-device-6lowpan-get-parent" since="1.14"/> <keyword type="function" name="NM_DEPRECATED_IN_1_24_FOR ()" link="NMDevice6Lowpan.html#NM-DEPRECATED-IN-1-24-FOR:CAPS" deprecated=""/> <keyword type="macro" name="NM_DEVICE_6LOWPAN_PARENT" link="NMDevice6Lowpan.html#NM-DEVICE-6LOWPAN-PARENT:CAPS"/> @@ -3010,6 +3013,7 @@ <keyword type="macro" name="NM_DEPRECATED_IN_1_26_FOR()" link="libnm-nm-version.html#NM-DEPRECATED-IN-1-26-FOR:CAPS"/> <keyword type="macro" name="NM_DEPRECATED_IN_1_28_FOR()" link="libnm-nm-version.html#NM-DEPRECATED-IN-1-28-FOR:CAPS"/> <keyword type="macro" name="NM_DEPRECATED_IN_1_30_FOR()" link="libnm-nm-version.html#NM-DEPRECATED-IN-1-30-FOR:CAPS"/> + <keyword type="macro" name="NM_DEPRECATED_IN_1_32_FOR()" link="libnm-nm-version.html#NM-DEPRECATED-IN-1-32-FOR:CAPS"/> <keyword type="macro" name="NM_VERSION_MIN_REQUIRED" link="libnm-nm-version.html#NM-VERSION-MIN-REQUIRED:CAPS"/> <keyword type="macro" name="NM_VERSION_MAX_ALLOWED" link="libnm-nm-version.html#NM-VERSION-MAX-ALLOWED:CAPS"/> <keyword type="macro" name="NM_DEPRECATED_IN_0_9_10" link="libnm-nm-version.html#NM-DEPRECATED-IN-0-9-10:CAPS"/> @@ -3046,6 +3050,8 @@ <keyword type="macro" name="NM_AVAILABLE_IN_1_28" link="libnm-nm-version.html#NM-AVAILABLE-IN-1-28:CAPS"/> <keyword type="macro" name="NM_DEPRECATED_IN_1_30" link="libnm-nm-version.html#NM-DEPRECATED-IN-1-30:CAPS"/> <keyword type="macro" name="NM_AVAILABLE_IN_1_30" link="libnm-nm-version.html#NM-AVAILABLE-IN-1-30:CAPS"/> + <keyword type="macro" name="NM_DEPRECATED_IN_1_32" link="libnm-nm-version.html#NM-DEPRECATED-IN-1-32:CAPS"/> + <keyword type="macro" name="NM_AVAILABLE_IN_1_32" link="libnm-nm-version.html#NM-AVAILABLE-IN-1-32:CAPS"/> <keyword type="function" name="nm_vpn_service_plugin_get_connection ()" link="NMVpnServicePlugin.html#nm-vpn-service-plugin-get-connection" since="1.2"/> <keyword type="function" name="nm_vpn_service_plugin_secrets_required ()" link="NMVpnServicePlugin.html#nm-vpn-service-plugin-secrets-required" since="1.2"/> <keyword type="function" name="nm_vpn_service_plugin_set_login_banner ()" link="NMVpnServicePlugin.html#nm-vpn-service-plugin-set-login-banner"/> diff --git a/docs/libnm/html/license.html b/docs/libnm/html/license.html index 207a9d4..490c941 100644 --- a/docs/libnm/html/license.html +++ b/docs/libnm/html/license.html @@ -7,7 +7,7 @@ <link rel="home" href="index.html" title="libnm Reference Manual"> <link rel="up" href="index.html" title="libnm Reference Manual"> <link rel="prev" href="annotation-glossary.html" title="Annotation Glossary"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -55,6 +55,6 @@ </p> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/object-tree.html b/docs/libnm/html/object-tree.html index f282d72..8a54c5a 100644 --- a/docs/libnm/html/object-tree.html +++ b/docs/libnm/html/object-tree.html @@ -8,7 +8,7 @@ <link rel="up" href="index.html" title="libnm Reference Manual"> <link rel="prev" href="NMVpnPluginOld.html" title="NMVpnPluginOld"> <link rel="next" href="api-index-full.html" title="API Index"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -231,6 +231,6 @@ </pre> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/ref-overview.html b/docs/libnm/html/ref-overview.html index 9e1af21..675649f 100644 --- a/docs/libnm/html/ref-overview.html +++ b/docs/libnm/html/ref-overview.html @@ -8,7 +8,7 @@ <link rel="up" href="index.html" title="libnm Reference Manual"> <link rel="prev" href="index.html" title="libnm Reference Manual"> <link rel="next" href="usage.html" title="Using libnm"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -62,6 +62,6 @@ </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/html/usage.html b/docs/libnm/html/usage.html index 98add49..c74188d 100644 --- a/docs/libnm/html/usage.html +++ b/docs/libnm/html/usage.html @@ -8,7 +8,7 @@ <link rel="up" href="ref-overview.html" title="Overview"> <link rel="prev" href="ref-overview.html" title="Overview"> <link rel="next" href="ch02.html" title="Client Object API Reference"> -<meta name="generator" content="GTK-Doc V1.33.1 (XML mode)"> +<meta name="generator" content="GTK-Doc V1.33.0 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> @@ -96,7 +96,7 @@ </p> <pre class="screen"><code class="prompt">$ </code><strong class="userinput"><code>cc $(pkg-config --libs --cflags libnm) -o hello-nm hello-nm.c</code></strong> <code class="prompt">$ </code><strong class="userinput"><code>./hello-nm</code></strong> - NetworkManager version: 1.30.0 + NetworkManager version: 1.31.2 <code class="prompt">$ </code></pre> <p> @@ -271,6 +271,6 @@ </div> </div> <div class="footer"> -<hr>Generated by GTK-Doc V1.33.1</div> +<hr>Generated by GTK-Doc V1.33.0</div> </body> </html> \ No newline at end of file diff --git a/docs/libnm/libnm-sections.txt b/docs/libnm/libnm-sections.txt index 35b3c8c..020c45c 100644 --- a/docs/libnm/libnm-sections.txt +++ b/docs/libnm/libnm-sections.txt @@ -706,11 +706,6 @@ NMClientPermissionResult </SECTION> <SECTION> -<FILE>nm-default-client</FILE> -NETWORKMANAGER_COMPILATION -</SECTION> - -<SECTION> <FILE>nm-default-libnm</FILE> NETWORKMANAGER_COMPILATION </SECTION> @@ -803,17 +798,17 @@ nm_device_filter_connections nm_device_connection_valid nm_device_connection_compatible nm_device_get_setting_type -nm_lldp_neighbor_new nm_lldp_neighbor_ref nm_lldp_neighbor_unref nm_lldp_neighbor_get_attr_names +nm_lldp_neighbor_get_attr_value +nm_lldp_neighbor_new nm_lldp_neighbor_get_attr_string_value nm_lldp_neighbor_get_attr_uint_value nm_lldp_neighbor_get_attr_type -nm_lldp_neighbor_get_attr_value +NMLldpNeighbor <SUBSECTION Standard> NMDeviceClass -NMLldpNeighbor NM_DEVICE NM_DEVICE_CLASS NM_DEVICE_GET_CLASS @@ -1776,24 +1771,6 @@ NML_IS_DBUS_OBJECT </SECTION> <SECTION> -<FILE>nm-meta-setting-base</FILE> - -</SECTION> - -<SECTION> -<FILE>nm-meta-setting-base-impl</FILE> -NMSettingPriority -NMSetting8021xSchemeType -NMSetting8021xSchemeVtable -NMMetaSettingType -NMMetaSettingInfo_Alias -NMMetaSettingInfo -nm_meta_setting_infos_by_name -nm_meta_setting_infos_by_gtype -nm_meta_setting_info_get_base_type_priority -</SECTION> - -<SECTION> <FILE>nm-object</FILE> <TITLE>NMObject NM_OBJECT_PATH @@ -2771,6 +2748,8 @@ nm_ip_routing_rule_get_table nm_ip_routing_rule_set_table nm_ip_routing_rule_get_suppress_prefixlength nm_ip_routing_rule_set_suppress_prefixlength +nm_ip_routing_rule_get_uid_range +nm_ip_routing_rule_set_uid_range nm_ip_routing_rule_cmp nm_ip_routing_rule_validate NMIPRoutingRuleAsStringFlags @@ -4457,6 +4436,9 @@ NM_AVAILABLE_IN_1_28 NM_DEPRECATED_IN_1_30 NM_DEPRECATED_IN_1_30_FOR NM_AVAILABLE_IN_1_30 +NM_DEPRECATED_IN_1_32 +NM_DEPRECATED_IN_1_32_FOR +NM_AVAILABLE_IN_1_32
@@ -4484,6 +4466,7 @@ NM_VERSION_1_24 NM_VERSION_1_26 NM_VERSION_1_28 NM_VERSION_1_30 +NM_VERSION_1_32 NM_API_VERSION NM_VERSION_CUR_STABLE NM_VERSION_NEXT_STABLE diff --git a/docs/libnm/meson.build b/docs/libnm/meson.build index 1020098..5a87b62 100644 --- a/docs/libnm/meson.build +++ b/docs/libnm/meson.build @@ -1,15 +1,9 @@ # SPDX-License-Identifier: LGPL-2.1-or-later -src_dirs = [ - libnm_core_inc, - libnm_inc, -] - private_headers = [ 'common.h', 'nm-core-internal.h', 'nm-core-tests-enum-types.h', - 'nm-core-types-internal.h', 'nm-crypto-impl.h', 'nm-crypto.h', 'nm-dbus-helpers.h', @@ -57,7 +51,10 @@ version_xml = configure_file( gnome.gtkdoc( libnm_name, main_xml: libnm_name + '-docs.xml', - src_dir: src_dirs, + src_dir: [ + libnm_core_public_inc, + libnm_client_public_inc, + ], dependencies: libnm_dep, scan_args: scan_args, scanobjs_args: '--type-init-func="g_type_init();"', diff --git a/docs/libnm/version.xml b/docs/libnm/version.xml index 034552a..3492b09 100644 --- a/docs/libnm/version.xml +++ b/docs/libnm/version.xml @@ -1 +1 @@ -1.30.0 +1.31.2 diff --git a/examples/C/glib/meson.build b/examples/C/glib/meson.build index 41c46ca..8899a90 100644 --- a/examples/C/glib/meson.build +++ b/examples/C/glib/meson.build @@ -1,20 +1,23 @@ # SPDX-License-Identifier: LGPL-2.1-or-later examples = [ - ['add-connection-gdbus', [libnm_enum_sources[1]], [uuid_dep]], - ['add-connection-libnm', [], [libnm_dep]], - ['get-active-connections-gdbus', [libnm_enum_sources[1]], []], - ['get-ap-info-libnm', [], [libnm_dep]], - ['list-connections-gdbus', [], []], - ['list-connections-libnm', [], [libnm_dep]], - ['monitor-nm-running-gdbus', [], []], - ['monitor-nm-state-gdbus', [], []], + ['add-connection-gdbus', [uuid_dep]], + ['add-connection-libnm', []], + ['get-active-connections-gdbus', []], + ['get-ap-info-libnm', []], + ['list-connections-gdbus', []], + ['list-connections-libnm', []], + ['monitor-nm-running-gdbus', []], + ['monitor-nm-state-gdbus', []], + ['vpn-import-libnm', []], ] foreach example: examples executable( example[0], - [example[0] + '.c'] + example[1], - dependencies: [libnm_nm_default_dep] + example[2], + [example[0] + '.c'], + dependencies: [ + libnm_dep, + ] + example[1], ) endforeach diff --git a/examples/C/glib/vpn-import-libnm.c b/examples/C/glib/vpn-import-libnm.c new file mode 100644 index 0000000..6a563ba --- /dev/null +++ b/examples/C/glib/vpn-import-libnm.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * The example shows how to import VPN connection from a file. + * @author: Jagadeesh Kotra + * + * Compile with: + * gcc -Wall vpn-import-libnm.c -o vpn-import-libnm `pkg-config --cflags --libs libnm` + */ + +#include +#include +#include + +static void +add_cb(NMClient *client, GAsyncResult *result, GMainLoop *loop) +{ + GError *err = NULL; + nm_client_add_connection_finish(client, result, &err); + if (err != NULL) { + g_print("Error: %s\n", err->message); + } else { + g_print("Connection Added.\n"); + } + + g_main_loop_quit(loop); +} + +int +main(int argc, char **argv) +{ + GMainLoop * loop = g_main_loop_new(NULL, FALSE); + GSList * plugins; + GSList * iter; + NMVpnEditorPlugin *editor; + NMClient * client; + GError * err = NULL; + NMConnection * conn = NULL; + + if (argc < 2) { + g_print("program takes exactly one(1) argument.\n"); + exit(1); + } + + plugins = nm_vpn_plugin_info_list_load(); + g_assert(plugins != NULL); + + for (iter = plugins; iter; iter = iter->next) { + const char *plugin_name = nm_vpn_plugin_info_get_name(iter->data); + g_print("Trying Plugin: %s\n", plugin_name); + + //try to load plugin + editor = nm_vpn_plugin_info_load_editor_plugin(iter->data, NULL); + + conn = nm_vpn_editor_plugin_import(editor, argv[1], &err); + if (err != NULL) { + g_print("Error: %s\n", err->message); + g_error_free(err); + err = NULL; + } else { + g_print("%s imported with %s plugin.\n", argv[1], plugin_name); + break; + } + } + + g_slist_free_full(plugins, g_object_unref); + g_assert(conn != NULL); + + client = nm_client_new(NULL, NULL); + + nm_client_add_connection_async(client, conn, TRUE, NULL, (GAsyncReadyCallback) add_cb, loop); + g_main_loop_run(loop); + + return 0; +} diff --git a/examples/C/qt/meson.build b/examples/C/qt/meson.build index 7e4e127..8b905bd 100644 --- a/examples/C/qt/meson.build +++ b/examples/C/qt/meson.build @@ -6,13 +6,6 @@ examples = [ ['change-ipv4-addresses', []], ] -deps = [ - dbus_dep, - qt_core_dep, - qt_dbus_dep, - qt_network_dep, -] - moc = find_program('moc-qt4', required: false) if not moc.found() moc = qt_core_dep.get_pkgconfig_variable('moc_location') @@ -34,8 +27,13 @@ foreach example: examples executable( example[0], example[0] + '.cpp', - include_directories: libnm_core_inc, - dependencies: deps, + include_directories: libnm_core_public_inc, + dependencies: [ + dbus_dep, + qt_core_dep, + qt_dbus_dep, + qt_network_dep, + ], link_depends: example[1], ) endforeach diff --git a/gtk-doc.make b/gtk-doc.make index c673175..7d9a27f 100644 --- a/gtk-doc.make +++ b/gtk-doc.make @@ -57,7 +57,6 @@ DOC_STAMPS=setup-build.stamp scan-build.stamp sgml-build.stamp \ sgml.stamp html.stamp pdf.stamp SCANOBJ_FILES = \ - $(DOC_MODULE).actions \ $(DOC_MODULE).args \ $(DOC_MODULE).hierarchy \ $(DOC_MODULE).interfaces \ diff --git a/introspection/meson.build b/introspection/meson.build index 82c1dd6..7d495f7 100644 --- a/introspection/meson.build +++ b/introspection/meson.build @@ -57,8 +57,6 @@ sources = [] introspection_files = [] headers = [] -# FIXME?: DBUS_INTERFACE_DOCS/docbook files are generated in -# "meson.current_build_dir()" instead of "meson.source_root()/docs/api" foreach iface: ifaces iface_xml = iface + '.xml' ifaces_xmls += files(iface_xml) @@ -99,12 +97,12 @@ libnmdbus = static_library( 'nmdbus', sources: sources, include_directories: top_inc, - dependencies: glib_dep, c_args: introspection_extra_cflags, + dependencies: glib_dep, ) libnmdbus_dep = declare_dependency( sources: headers, - include_directories: include_directories('.'), - link_with: libnmdbus, + include_directories: top_inc, + dependencies: glib_dep, ) diff --git a/man/NetworkManager-dispatcher.8 b/man/NetworkManager-dispatcher.8 new file mode 100644 index 0000000..164f658 --- /dev/null +++ b/man/NetworkManager-dispatcher.8 @@ -0,0 +1,237 @@ +'\" t +.\" Title: NetworkManager-dispatcher +.\" Author: +.\" Generator: DocBook XSL Stylesheets vsnapshot +.\" Date: 03/24/2021 +.\" Manual: Network management daemons +.\" Source: NetworkManager-dispatcher 1.31.2 +.\" Language: English +.\" +.TH "NETWORKMANAGER\-DISPATCHER" "8" "" "NetworkManager\-dispatcher 1\&" "Network management daemons" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +NetworkManager-dispatcher \- Dispatch user scripts for NetworkManager +.SH "SYNOPSIS" +.HP \w'\fBNetworkManager\ \fR\fB[OPTIONS...]\fR\ 'u +\fBNetworkManager \fR\fB[OPTIONS...]\fR +.SH "DESCRIPTION" +.PP +NetworkManager\-dispatcher service is a D\-Bus activated service that runs user provided scripts upon certain changes in NetworkManager\&. +.PP +NetworkManager\-dispatcher will execute scripts in the +/{etc,usr/lib}/NetworkManager/dispatcher\&.d +directory or subdirectories in alphabetical order in response to network events\&. Each script should be a regular executable file owned by root\&. Furthermore, it must not be writable by group or other, and not setuid\&. +.PP +Each script receives two arguments, the first being the interface name of the device an operation just happened on, and second the action\&. For device actions, the interface is the name of the kernel interface suitable for IP configuration\&. Thus it is either VPN_IP_IFACE, DEVICE_IP_IFACE, or DEVICE_IFACE, as applicable\&. For the +\fIhostname\fR +action the device name is always +"none" +and for +\fIconnectivity\-change\fR +it is empty\&. +.PP +The actions are: +.PP +\fIpre\-up\fR +.RS 4 +The interface is connected to the network but is not yet fully activated\&. Scripts acting on this event must be placed or symlinked into the +/etc/NetworkManager/dispatcher\&.d/pre\-up\&.d +directory, and NetworkManager will wait for script execution to complete before indicating to applications that the interface is fully activated\&. +.RE +.PP +\fIup\fR +.RS 4 +The interface has been activated\&. +.RE +.PP +\fIpre\-down\fR +.RS 4 +The interface will be deactivated but has not yet been disconnected from the network\&. Scripts acting on this event must be placed or symlinked into the +/etc/NetworkManager/dispatcher\&.d/pre\-down\&.d +directory, and NetworkManager will wait for script execution to complete before disconnecting the interface from its network\&. Note that this event is not emitted for forced disconnections, like when carrier is lost or a wireless signal fades\&. It is only emitted when there is an opportunity to cleanly handle a network disconnection event\&. +.RE +.PP +\fIdown\fR +.RS 4 +The interface has been deactivated\&. +.RE +.PP +\fIvpn\-pre\-up\fR +.RS 4 +The VPN is connected to the network but is not yet fully activated\&. Scripts acting on this event must be placed or symlinked into the +/etc/NetworkManager/dispatcher\&.d/pre\-up\&.d +directory, and NetworkManager will wait for script execution to complete before indicating to applications that the VPN is fully activated\&. +.RE +.PP +\fIvpn\-up\fR +.RS 4 +A VPN connection has been activated\&. +.RE +.PP +\fIvpn\-pre\-down\fR +.RS 4 +The VPN will be deactivated but has not yet been disconnected from the network\&. Scripts acting on this event must be placed or symlinked into the +/etc/NetworkManager/dispatcher\&.d/pre\-down\&.d +directory, and NetworkManager will wait for script execution to complete before disconnecting the VPN from its network\&. Note that this event is not emitted for forced disconnections, like when the VPN terminates unexpectedly or general connectivity is lost\&. It is only emitted when there is an opportunity to cleanly handle a VPN disconnection event\&. +.RE +.PP +\fIvpn\-down\fR +.RS 4 +A VPN connection has been deactivated\&. +.RE +.PP +\fIhostname\fR +.RS 4 +The system hostname has been updated\&. Use gethostname(2) to retrieve it\&. The interface name (first argument) is empty and no environment variable is set for this action\&. +.RE +.PP +\fIdhcp4\-change\fR +.RS 4 +The DHCPv4 lease has changed (renewed, rebound, etc)\&. +.RE +.PP +\fIdhcp6\-change\fR +.RS 4 +The DHCPv6 lease has changed (renewed, rebound, etc)\&. +.RE +.PP +\fIconnectivity\-change\fR +.RS 4 +The network connectivity state has changed (no connectivity, went online, etc)\&. +.RE +.PP +The environment contains more information about the interface and the connection\&. The following variables are available for the use in the dispatcher scripts: +.PP +\fINM_DISPATCHER_ACTION\fR +.RS 4 +The dispatcher action like "up" or "dhcp4\-change", identical to the first command line argument\&. Since NetworkManager 1\&.12\&.0\&. +.RE +.PP +\fICONNECTION_UUID\fR +.RS 4 +The UUID of the connection profile\&. +.RE +.PP +\fICONNECTION_ID\fR +.RS 4 +The name (ID) of the connection profile\&. +.RE +.PP +\fICONNECTION_DBUS_PATH\fR +.RS 4 +The NetworkManager D\-Bus path of the connection\&. +.RE +.PP +\fICONNECTION_FILENAME\fR +.RS 4 +The backing file name of the connection profile (if any)\&. +.RE +.PP +\fICONNECTION_EXTERNAL\fR +.RS 4 +If "1", this indicates that the connection describes a network configuration created outside of NetworkManager\&. +.RE +.PP +\fIDEVICE_IFACE\fR +.RS 4 +The interface name of the control interface of the device\&. Depending on the device type, this differs from +\fIDEVICE_IP_IFACE\fR\&. For example for ADSL devices, this could be \*(Aqatm0\*(Aq or for WWAN devices it might be \*(AqttyUSB0\*(Aq\&. +.RE +.PP +\fIDEVICE_IP_IFACE\fR +.RS 4 +The IP interface name of the device\&. This is the network interface on which IP addresses and routes will be configured\&. +.RE +.PP +\fIIP4_ADDRESS_N\fR +.RS 4 +The IPv4 address in the format "address/prefix gateway", where N is a number from 0 to (# IPv4 addresses \- 1)\&. gateway item in this variable is deprecated, use IP4_GATEWAY instead\&. +.RE +.PP +\fIIP4_NUM_ADDRESSES\fR +.RS 4 +The variable contains the number of IPv4 addresses the script may expect\&. +.RE +.PP +\fIIP4_GATEWAY\fR +.RS 4 +The gateway IPv4 address in traditional numbers\-and\-dots notation\&. +.RE +.PP +\fIIP4_ROUTE_N\fR +.RS 4 +The IPv4 route in the format "address/prefix next\-hop metric", where N is a number from 0 to (# IPv4 routes \- 1)\&. +.RE +.PP +\fIIP4_NUM_ROUTES\fR +.RS 4 +The variable contains the number of IPv4 routes the script may expect\&. +.RE +.PP +\fIIP4_NAMESERVERS\fR +.RS 4 +The variable contains a space\-separated list of the DNS servers\&. +.RE +.PP +\fIIP4_DOMAINS\fR +.RS 4 +The variable contains a space\-separated list of the search domains\&. +.RE +.PP +\fIDHCP4_\fR +.RS 4 +If the connection used DHCP for address configuration, the received DHCP configuration is passed in the environment using standard DHCP option names, prefixed with "DHCP4_", like "DHCP4_HOST_NAME=foobar"\&. +.RE +.PP +\fIIP6_ and DHCP6_\fR +.RS 4 +The same variables as for IPv4 are available for IPv6, but the prefixes are IP6_ and DHCP6_ instead\&. +.RE +.PP +\fICONNECTIVITY_STATE\fR +.RS 4 +The network connectivity state, which can take the values defined by the NMConnectivityState type, from the org\&.freedesktop\&.NetworkManager D\-Bus API: unknown, none, portal, limited or full\&. Note: this variable will only be set for connectivity\-change actions\&. +.RE +.PP +In case of VPN, VPN_IP_IFACE is set, and IP4_*, IP6_* variables with VPN prefix are exported too, like VPN_IP4_ADDRESS_0, VPN_IP4_NUM_ADDRESSES\&. +.PP +Dispatcher scripts are run one at a time, but asynchronously from the main NetworkManager process, and will be killed if they run for too long\&. If your script might take arbitrarily long to complete, you should spawn a child process and have the parent return immediately\&. Scripts that are symbolic links pointing inside the +/etc/NetworkManager/dispatcher\&.d/no\-wait\&.d/ +directory are run immediately, without waiting for the termination of previous scripts, and in parallel\&. Also beware that once a script is queued, it will always be run, even if a later event renders it obsolete\&. (Eg, if an interface goes up, and then back down again quickly, it is possible that one or more "up" scripts will be run after the interface has gone down\&.) +.SH "BUGS" +.PP +Please report any bugs you find in NetworkManager at the +\m[blue]\fBNetworkManager issue tracker\fR\m[]\&\s-2\u[1]\d\s+2\&. +.SH "SEE ALSO" +.PP +\m[blue]\fBNetworkManager home page\fR\m[]\&\s-2\u[2]\d\s+2, +\fBNetworkManager\fR(8), +.SH "NOTES" +.IP " 1." 4 +NetworkManager issue tracker +.RS 4 +\%https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues +.RE +.IP " 2." 4 +NetworkManager home page +.RS 4 +\%https://wiki.gnome.org/Projects/NetworkManager +.RE diff --git a/man/NetworkManager-dispatcher.xml b/man/NetworkManager-dispatcher.xml new file mode 100644 index 0000000..2d9a270 --- /dev/null +++ b/man/NetworkManager-dispatcher.xml @@ -0,0 +1,331 @@ + + + +%entities; +]> + + + + + + NetworkManager-dispatcher + NetworkManager developers + + + NetworkManager-dispatcher + 8 + NetworkManager-dispatcher + Network management daemons + &NM_VERSION; + + + + NetworkManager-dispatcher + Dispatch user scripts for NetworkManager + + + + + NetworkManager OPTIONS + + + + + Description + + NetworkManager-dispatcher service is a D-Bus activated service that + runs user provided scripts upon certain changes in NetworkManager. + + + NetworkManager-dispatcher will execute scripts in the + /{etc,usr/lib}/NetworkManager/dispatcher.d + directory or subdirectories in + alphabetical order in response to network events. Each script should + be a regular executable file owned by root. Furthermore, it must not be + writable by group or other, and not setuid. + + + Each script receives two arguments, the first being the interface name of the + device an operation just happened on, and second the action. For device actions, + the interface is the name of the kernel interface suitable for IP configuration. + Thus it is either VPN_IP_IFACE, DEVICE_IP_IFACE, or DEVICE_IFACE, as applicable. + For the hostname action the device name is always "none" + and for connectivity-change it is empty. + + The actions are: + + + pre-up + The interface is connected to the network but is not + yet fully activated. Scripts acting on this event must be placed or + symlinked into the /etc/NetworkManager/dispatcher.d/pre-up.d + directory, and NetworkManager will wait for script execution to complete before + indicating to applications that the interface is fully activated. + + + + up + The interface has been activated. + + + pre-down + The interface will be deactivated but has not yet been + disconnected from the network. Scripts acting on this event must be + placed or symlinked into the /etc/NetworkManager/dispatcher.d/pre-down.d + directory, and NetworkManager will wait for script execution to complete + before disconnecting the interface from its network. Note that this + event is not emitted for forced disconnections, like when carrier is + lost or a wireless signal fades. It is only emitted when there is + an opportunity to cleanly handle a network disconnection event. + + + + down + + The interface has been deactivated. + + + + vpn-pre-up + The VPN is connected to the network but is not yet + fully activated. Scripts acting on this event must be placed or + symlinked into the /etc/NetworkManager/dispatcher.d/pre-up.d + directory, and NetworkManager will wait for script execution to complete before + indicating to applications that the VPN is fully activated. + + + + vpn-up + + A VPN connection has been activated. + + + + vpn-pre-down + The VPN will be deactivated but has not yet been + disconnected from the network. Scripts acting on this event must be + placed or symlinked into the /etc/NetworkManager/dispatcher.d/pre-down.d + directory, and NetworkManager will wait for script execution to complete + before disconnecting the VPN from its network. Note that this + event is not emitted for forced disconnections, like when the VPN + terminates unexpectedly or general connectivity is lost. It is only + emitted when there is an opportunity to cleanly handle a VPN + disconnection event. + + + + vpn-down + + A VPN connection has been deactivated. + + + + hostname + + The system hostname has been updated. Use gethostname(2) to retrieve it. + The interface name (first argument) is empty and no environment variable is + set for this action. + + + + dhcp4-change + + The DHCPv4 lease has changed (renewed, rebound, etc). + + + + dhcp6-change + + The DHCPv6 lease has changed (renewed, rebound, etc). + + + + connectivity-change + + The network connectivity state has changed (no connectivity, went online, etc). + + + + + The environment contains more information about the interface and the connection. + The following variables are available for the use in the dispatcher scripts: + + + NM_DISPATCHER_ACTION + + The dispatcher action like "up" or "dhcp4-change", identical to the first + command line argument. Since NetworkManager 1.12.0. + + + + CONNECTION_UUID + + The UUID of the connection profile. + + + + CONNECTION_ID + + The name (ID) of the connection profile. + + + + CONNECTION_DBUS_PATH + + The NetworkManager D-Bus path of the connection. + + + + CONNECTION_FILENAME + + The backing file name of the connection profile (if any). + + + + CONNECTION_EXTERNAL + + If "1", this indicates that the connection describes a + network configuration created outside of NetworkManager. + + + + DEVICE_IFACE + + The interface name of the control interface of the device. + Depending on the device type, this differs from + DEVICE_IP_IFACE. For example for + ADSL devices, this could be 'atm0' or for WWAN devices + it might be 'ttyUSB0'. + + + + DEVICE_IP_IFACE + + The IP interface name of the device. This is the network + interface on which IP addresses and routes will be configured. + + + + IP4_ADDRESS_N + + The IPv4 address in the format "address/prefix gateway", where N is a number + from 0 to (# IPv4 addresses - 1). gateway item in this variable is deprecated, + use IP4_GATEWAY instead. + + + + IP4_NUM_ADDRESSES + + The variable contains the number of IPv4 addresses the script may expect. + + + + IP4_GATEWAY + + The gateway IPv4 address in traditional numbers-and-dots notation. + + + + IP4_ROUTE_N + + The IPv4 route in the format "address/prefix next-hop metric", where N is a number + from 0 to (# IPv4 routes - 1). + + + + IP4_NUM_ROUTES + + The variable contains the number of IPv4 routes the script may expect. + + + + IP4_NAMESERVERS + + The variable contains a space-separated list of the DNS servers. + + + + IP4_DOMAINS + + The variable contains a space-separated list of the search domains. + + + + DHCP4_<dhcp-option-name> + + If the connection used DHCP for address configuration, the received DHCP + configuration is passed in the environment using standard DHCP + option names, prefixed with "DHCP4_", like "DHCP4_HOST_NAME=foobar". + + + + IP6_<name> and DHCP6_<name> + + The same variables as for IPv4 are available for IPv6, but the prefixes are IP6_ + and DHCP6_ instead. + + + + CONNECTIVITY_STATE + The network connectivity state, which can + take the values defined by the NMConnectivityState type, + from the org.freedesktop.NetworkManager D-Bus API: unknown, + none, portal, limited or full. Note: this variable will only + be set for connectivity-change actions. + + + + + + In case of VPN, VPN_IP_IFACE is set, and IP4_*, IP6_* variables with VPN prefix are + exported too, like VPN_IP4_ADDRESS_0, VPN_IP4_NUM_ADDRESSES. + + + Dispatcher scripts are run one at a time, but asynchronously from the main + NetworkManager process, and will be killed if they run for too long. If your script + might take arbitrarily long to complete, you should spawn a child process and have the + parent return immediately. Scripts that are symbolic links pointing inside the + /etc/NetworkManager/dispatcher.d/no-wait.d/ + directory are run immediately, without + waiting for the termination of previous scripts, and in parallel. Also beware that + once a script is queued, it will always be run, even if a later event renders it + obsolete. (Eg, if an interface goes up, and then back down again quickly, it is + possible that one or more "up" scripts will be run after the interface has gone down.) + + + + + Bugs + + Please report any bugs you find in NetworkManager at the + NetworkManager issue tracker. + + + + + See Also + + NetworkManager home page, + NetworkManager8, + + + diff --git a/man/NetworkManager.8 b/man/NetworkManager.8 index 42f88c8..2619d96 100644 --- a/man/NetworkManager.8 +++ b/man/NetworkManager.8 @@ -2,12 +2,12 @@ .\" Title: NetworkManager .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: Network management daemons -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NETWORKMANAGER" "8" "" "NetworkManager 1\&.30\&.0" "Network management daemons" +.TH "NETWORKMANAGER" "8" "" "NetworkManager 1\&.31\&.2" "Network management daemons" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -37,186 +37,9 @@ NetworkManager \- network management daemon The NetworkManager daemon attempts to make networking configuration and operation as painless and automatic as possible by managing the primary network connection and other network interfaces, like Ethernet, Wi\-Fi, and Mobile Broadband devices\&. NetworkManager will connect any network device when a connection for that device becomes available, unless that behavior is disabled\&. Information about networking is exported via a D\-Bus interface to any interested application, providing a rich API with which to inspect and control network settings and operation\&. .SH "DISPATCHER SCRIPTS" .PP -NetworkManager will execute scripts in the -/etc/NetworkManager/dispatcher\&.d -directory or subdirectories in alphabetical order in response to network events\&. Each script should be a regular executable file owned by root\&. Furthermore, it must not be writable by group or other, and not setuid\&. -.PP -Each script receives two arguments, the first being the interface name of the device an operation just happened on, and second the action\&. For device actions, the interface is the name of the kernel interface suitable for IP configuration\&. Thus it is either VPN_IP_IFACE, DEVICE_IP_IFACE, or DEVICE_IFACE, as applicable\&. For the -\fIhostname\fR -action the device name is always -"none" -and for -\fIconnectivity\-change\fR -it is empty\&. -.PP -The actions are: -.PP -\fIpre\-up\fR -.RS 4 -The interface is connected to the network but is not yet fully activated\&. Scripts acting on this event must be placed or symlinked into the -/etc/NetworkManager/dispatcher\&.d/pre\-up\&.d -directory, and NetworkManager will wait for script execution to complete before indicating to applications that the interface is fully activated\&. -.RE -.PP -\fIup\fR -.RS 4 -The interface has been activated\&. -.RE -.PP -\fIpre\-down\fR -.RS 4 -The interface will be deactivated but has not yet been disconnected from the network\&. Scripts acting on this event must be placed or symlinked into the -/etc/NetworkManager/dispatcher\&.d/pre\-down\&.d -directory, and NetworkManager will wait for script execution to complete before disconnecting the interface from its network\&. Note that this event is not emitted for forced disconnections, like when carrier is lost or a wireless signal fades\&. It is only emitted when there is an opportunity to cleanly handle a network disconnection event\&. -.RE -.PP -\fIdown\fR -.RS 4 -The interface has been deactivated\&. -.RE -.PP -\fIvpn\-pre\-up\fR -.RS 4 -The VPN is connected to the network but is not yet fully activated\&. Scripts acting on this event must be placed or symlinked into the -/etc/NetworkManager/dispatcher\&.d/pre\-up\&.d -directory, and NetworkManager will wait for script execution to complete before indicating to applications that the VPN is fully activated\&. -.RE -.PP -\fIvpn\-up\fR -.RS 4 -A VPN connection has been activated\&. -.RE -.PP -\fIvpn\-pre\-down\fR -.RS 4 -The VPN will be deactivated but has not yet been disconnected from the network\&. Scripts acting on this event must be placed or symlinked into the -/etc/NetworkManager/dispatcher\&.d/pre\-down\&.d -directory, and NetworkManager will wait for script execution to complete before disconnecting the VPN from its network\&. Note that this event is not emitted for forced disconnections, like when the VPN terminates unexpectedly or general connectivity is lost\&. It is only emitted when there is an opportunity to cleanly handle a VPN disconnection event\&. -.RE -.PP -\fIvpn\-down\fR -.RS 4 -A VPN connection has been deactivated\&. -.RE -.PP -\fIhostname\fR -.RS 4 -The system hostname has been updated\&. Use gethostname(2) to retrieve it\&. The interface name (first argument) is empty and no environment variable is set for this action\&. -.RE -.PP -\fIdhcp4\-change\fR -.RS 4 -The DHCPv4 lease has changed (renewed, rebound, etc)\&. -.RE -.PP -\fIdhcp6\-change\fR -.RS 4 -The DHCPv6 lease has changed (renewed, rebound, etc)\&. -.RE -.PP -\fIconnectivity\-change\fR -.RS 4 -The network connectivity state has changed (no connectivity, went online, etc)\&. -.RE -.PP -The environment contains more information about the interface and the connection\&. The following variables are available for the use in the dispatcher scripts: -.PP -\fINM_DISPATCHER_ACTION\fR -.RS 4 -The dispatcher action like "up" or "dhcp4\-change", identical to the first command line argument\&. Since NetworkManager 1\&.12\&.0\&. -.RE -.PP -\fICONNECTION_UUID\fR -.RS 4 -The UUID of the connection profile\&. -.RE -.PP -\fICONNECTION_ID\fR -.RS 4 -The name (ID) of the connection profile\&. -.RE -.PP -\fICONNECTION_DBUS_PATH\fR -.RS 4 -The NetworkManager D\-Bus path of the connection\&. -.RE -.PP -\fICONNECTION_FILENAME\fR -.RS 4 -The backing file name of the connection profile (if any)\&. -.RE -.PP -\fICONNECTION_EXTERNAL\fR -.RS 4 -If "1", this indicates that the connection describes a network configuration created outside of NetworkManager\&. -.RE -.PP -\fIDEVICE_IFACE\fR -.RS 4 -The interface name of the control interface of the device\&. Depending on the device type, this differs from -\fIDEVICE_IP_IFACE\fR\&. For example for ADSL devices, this could be \*(Aqatm0\*(Aq or for WWAN devices it might be \*(AqttyUSB0\*(Aq\&. -.RE -.PP -\fIDEVICE_IP_IFACE\fR -.RS 4 -The IP interface name of the device\&. This is the network interface on which IP addresses and routes will be configured\&. -.RE -.PP -\fIIP4_ADDRESS_N\fR -.RS 4 -The IPv4 address in the format "address/prefix gateway", where N is a number from 0 to (# IPv4 addresses \- 1)\&. gateway item in this variable is deprecated, use IP4_GATEWAY instead\&. -.RE -.PP -\fIIP4_NUM_ADDRESSES\fR -.RS 4 -The variable contains the number of IPv4 addresses the script may expect\&. -.RE -.PP -\fIIP4_GATEWAY\fR -.RS 4 -The gateway IPv4 address in traditional numbers\-and\-dots notation\&. -.RE -.PP -\fIIP4_ROUTE_N\fR -.RS 4 -The IPv4 route in the format "address/prefix next\-hop metric", where N is a number from 0 to (# IPv4 routes \- 1)\&. -.RE -.PP -\fIIP4_NUM_ROUTES\fR -.RS 4 -The variable contains the number of IPv4 routes the script may expect\&. -.RE -.PP -\fIIP4_NAMESERVERS\fR -.RS 4 -The variable contains a space\-separated list of the DNS servers\&. -.RE -.PP -\fIIP4_DOMAINS\fR -.RS 4 -The variable contains a space\-separated list of the search domains\&. -.RE -.PP -\fIDHCP4_\fR -.RS 4 -If the connection used DHCP for address configuration, the received DHCP configuration is passed in the environment using standard DHCP option names, prefixed with "DHCP4_", like "DHCP4_HOST_NAME=foobar"\&. -.RE -.PP -\fIIP6_ and DHCP6_\fR -.RS 4 -The same variables as for IPv4 are available for IPv6, but the prefixes are IP6_ and DHCP6_ instead\&. -.RE -.PP -\fICONNECTIVITY_STATE\fR -.RS 4 -The network connectivity state, which can take the values defined by the NMConnectivityState type, from the org\&.freedesktop\&.NetworkManager D\-Bus API: unknown, none, portal, limited or full\&. Note: this variable will only be set for connectivity\-change actions\&. -.RE -.PP -In case of VPN, VPN_IP_IFACE is set, and IP4_*, IP6_* variables with VPN prefix are exported too, like VPN_IP4_ADDRESS_0, VPN_IP4_NUM_ADDRESSES\&. -.PP -Dispatcher scripts are run one at a time, but asynchronously from the main NetworkManager process, and will be killed if they run for too long\&. If your script might take arbitrarily long to complete, you should spawn a child process and have the parent return immediately\&. Scripts that are symbolic links pointing inside the -/etc/NetworkManager/dispatcher\&.d/no\-wait\&.d/ -directory are run immediately, without waiting for the termination of previous scripts, and in parallel\&. Also beware that once a script is queued, it will always be run, even if a later event renders it obsolete\&. (Eg, if an interface goes up, and then back down again quickly, it is possible that one or more "up" scripts will be run after the interface has gone down\&.) +NetworkManager\-dispatcher service can execute scripts for the user in response to network events\&. See +\fBNetworkManager-dispatcher\fR(8) +manual\&. .SH "OPTIONS" .PP The following options are understood: @@ -407,6 +230,7 @@ Please report any bugs you find in NetworkManager at the .PP \m[blue]\fBNetworkManager home page\fR\m[]\&\s-2\u[2]\d\s+2, \fBNetworkManager.conf\fR(5), +\fBNetworkManager-dispatcher\fR(8), \fBnmcli\fR(1), \fBnmcli-examples\fR(7), \fBnm-online\fR(1), diff --git a/man/NetworkManager.conf.5 b/man/NetworkManager.conf.5 index 1817cca..cf94846 100644 --- a/man/NetworkManager.conf.5 +++ b/man/NetworkManager.conf.5 @@ -2,12 +2,12 @@ .\" Title: NetworkManager.conf .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: Configuration -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NETWORKMANAGER\&.CONF" "5" "" "NetworkManager 1\&.30\&.0" "Configuration" +.TH "NETWORKMANAGER\&.CONF" "5" "" "NetworkManager 1\&.31\&.2" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -381,6 +381,13 @@ name index (order slaves by their kernel index)\&. .RE +.PP +\fIiwd\-config\-path\fR +.RS 4 +If the value points to an existing directory, Network Manager will attempt to write copies of new or modified Wi\-Fi connection profiles, converted into the IWD format, into this directory thus making IWD connection properties editable\&. This will only happen if the IWD backend is active meaning that at least one Wi\-Fi device must exist\&. +.sp +This allows editing connection profile settings such as the 802\&.1x configuration using Network Manager clients\&. Without it such changes have no effect in IWD\&. +.RE .SH "KEYFILE SECTION" .PP This section contains keyfile\-plugin\-specific options, and is normally only used when you are not using any other distro\-specific plugin\&. @@ -402,6 +409,13 @@ The location where keyfiles are read and stored\&. This defaults to "/etc/Networ .RS 4 Set devices that should be ignored by NetworkManager\&. .sp +A device unmanaged due to this option is strictly unmanaged and cannot be overruled by using the API like +\fBnmcli device set $IFNAME managed yes\fR\&. Also, a device that is unmanaged for other reasons, like an udev rule, cannot be made managed with this option (e\&.g\&. by using an +except: +specifier)\&. These two points make it different from the +device*\&.managed +option which for that reason may be a better choice\&. +.sp See the section called \(lqDevice List Format\(rq for the syntax on how to specify a device\&. @@ -994,7 +1008,11 @@ Whether the device is managed or not\&. A device can be marked as managed via ud .PP \fIcarrier\-wait\-timeout\fR .RS 4 -Specify the timeout for waiting for carrier in milliseconds\&. When the device loses carrier, NetworkManager does not react immediately\&. Instead, it waits for this timeout before considering the link lost\&. Also, on startup, NetworkManager considers the device as busy for this time, as long as the device has no carrier\&. This delays startup\-complete signal and NetworkManager\-wait\-online\&. Configuring this too high means to block NetworkManager\-wait\-online longer then necessary\&. Configuring it too low, means that NetworkManager will declare startup\-complete, although carrier is about to come and auto\-activation to kick in\&. The default is 5000 milliseconds\&. +Specify the timeout for waiting for carrier in milliseconds\&. The default is 5000 milliseconds\&. This setting exists because certain drivers/hardware can take a long time to detect whether the cable is plugged in\&. +.sp +When the device loses carrier, NetworkManager does not react immediately\&. Instead, it waits for this timeout before considering the link lost\&. +.sp +Also, on startup, NetworkManager considers the device as busy for this time, as long as the device has no carrier\&. This delays startup\-complete signal and NetworkManager\-wait\-online\&. Configuring this too high means to block NetworkManager\-wait\-online longer than necessary when booting with cable unplugged\&. Configuring it too low, means that NetworkManager will declare startup\-complete too soon, although carrier is about to come and auto\-activation to kick in\&. Note that if a profile only has static IP configuration or Layer 3 configuration disabled, then it can already autoconnect without carrier on the device\&. Once such a profile reaches full activated state, startup\-complete is considered as reached even if the device has no carrier yet\&. .RE .PP \fIignore\-carrier\fR diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index 79f18e4..f55fcec 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -474,6 +474,26 @@ no-auto-default=* + + + iwd-config-path + + + If the value points to an existing directory, Network + Manager will attempt to write copies of new or modified + Wi-Fi connection profiles, converted into the IWD + format, into this directory thus making IWD connection + properties editable. This will only happen if the IWD + backend is active meaning that at least one Wi-Fi device + must exist. + + + This allows editing connection profile settings such as + the 802.1x configuration using Network Manager clients. + Without it such changes have no effect in IWD. + + + @@ -502,19 +522,29 @@ no-auto-default=* unmanaged-devices - Set devices that should be ignored by - NetworkManager. - - See for the syntax on how to - specify a device. - - - Example: - + + Set devices that should be ignored by NetworkManager. + + + A device unmanaged due to this option is strictly + unmanaged and cannot be overruled by using the API like + nmcli device set $IFNAME managed yes. + Also, a device that is unmanaged for other reasons, like + an udev rule, cannot be made managed with this option (e.g. by + using an except: specifier). + These two points make it different from the device*.managed + option which for that reason may be a better choice. + + See for the syntax on how to + specify a device. + + + Example: + unmanaged-devices=interface-name:em4 unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth2 - + @@ -1016,16 +1046,27 @@ managed=1 Specify the timeout for waiting for carrier in milliseconds. + The default is 5000 milliseconds. + This setting exists because certain drivers/hardware can take + a long time to detect whether the cable is plugged in. + + When the device loses carrier, NetworkManager does not react immediately. Instead, it waits for this timeout before considering - the link lost. Also, on startup, NetworkManager considers the + the link lost. + + + Also, on startup, NetworkManager considers the device as busy for this time, as long as the device has no carrier. This delays startup-complete signal and NetworkManager-wait-online. Configuring this too high means to block NetworkManager-wait-online - longer then necessary. Configuring it too low, means that NetworkManager - will declare startup-complete, although carrier is about to come - and auto-activation to kick in. - The default is 5000 milliseconds. + longer than necessary when booting with cable unplugged. Configuring + it too low, means that NetworkManager will declare startup-complete too + soon, although carrier is about to come and auto-activation to kick in. + Note that if a profile only has static IP configuration or Layer 3 configuration + disabled, then it can already autoconnect without carrier on the device. + Once such a profile reaches full activated state, startup-complete + is considered as reached even if the device has no carrier yet. diff --git a/man/NetworkManager.xml b/man/NetworkManager.xml index e2ac825..8977ae4 100644 --- a/man/NetworkManager.xml +++ b/man/NetworkManager.xml @@ -68,260 +68,9 @@ Dispatcher scripts - NetworkManager will execute scripts in the - /etc/NetworkManager/dispatcher.d - directory or subdirectories in - alphabetical order in response to network events. Each script should - be a regular executable file owned by root. Furthermore, it must not be - writable by group or other, and not setuid. - - - Each script receives two arguments, the first being the interface name of the - device an operation just happened on, and second the action. For device actions, - the interface is the name of the kernel interface suitable for IP configuration. - Thus it is either VPN_IP_IFACE, DEVICE_IP_IFACE, or DEVICE_IFACE, as applicable. - For the hostname action the device name is always "none" - and for connectivity-change it is empty. - - The actions are: - - - pre-up - The interface is connected to the network but is not - yet fully activated. Scripts acting on this event must be placed or - symlinked into the /etc/NetworkManager/dispatcher.d/pre-up.d - directory, and NetworkManager will wait for script execution to complete before - indicating to applications that the interface is fully activated. - - - - up - The interface has been activated. - - - pre-down - The interface will be deactivated but has not yet been - disconnected from the network. Scripts acting on this event must be - placed or symlinked into the /etc/NetworkManager/dispatcher.d/pre-down.d - directory, and NetworkManager will wait for script execution to complete - before disconnecting the interface from its network. Note that this - event is not emitted for forced disconnections, like when carrier is - lost or a wireless signal fades. It is only emitted when there is - an opportunity to cleanly handle a network disconnection event. - - - - down - - The interface has been deactivated. - - - - vpn-pre-up - The VPN is connected to the network but is not yet - fully activated. Scripts acting on this event must be placed or - symlinked into the /etc/NetworkManager/dispatcher.d/pre-up.d - directory, and NetworkManager will wait for script execution to complete before - indicating to applications that the VPN is fully activated. - - - - vpn-up - - A VPN connection has been activated. - - - - vpn-pre-down - The VPN will be deactivated but has not yet been - disconnected from the network. Scripts acting on this event must be - placed or symlinked into the /etc/NetworkManager/dispatcher.d/pre-down.d - directory, and NetworkManager will wait for script execution to complete - before disconnecting the VPN from its network. Note that this - event is not emitted for forced disconnections, like when the VPN - terminates unexpectedly or general connectivity is lost. It is only - emitted when there is an opportunity to cleanly handle a VPN - disconnection event. - - - - vpn-down - - A VPN connection has been deactivated. - - - - hostname - - The system hostname has been updated. Use gethostname(2) to retrieve it. - The interface name (first argument) is empty and no environment variable is - set for this action. - - - - dhcp4-change - - The DHCPv4 lease has changed (renewed, rebound, etc). - - - - dhcp6-change - - The DHCPv6 lease has changed (renewed, rebound, etc). - - - - connectivity-change - - The network connectivity state has changed (no connectivity, went online, etc). - - - - - The environment contains more information about the interface and the connection. - The following variables are available for the use in the dispatcher scripts: - - - NM_DISPATCHER_ACTION - - The dispatcher action like "up" or "dhcp4-change", identical to the first - command line argument. Since NetworkManager 1.12.0. - - - - CONNECTION_UUID - - The UUID of the connection profile. - - - - CONNECTION_ID - - The name (ID) of the connection profile. - - - - CONNECTION_DBUS_PATH - - The NetworkManager D-Bus path of the connection. - - - - CONNECTION_FILENAME - - The backing file name of the connection profile (if any). - - - - CONNECTION_EXTERNAL - - If "1", this indicates that the connection describes a - network configuration created outside of NetworkManager. - - - - DEVICE_IFACE - - The interface name of the control interface of the device. - Depending on the device type, this differs from - DEVICE_IP_IFACE. For example for - ADSL devices, this could be 'atm0' or for WWAN devices - it might be 'ttyUSB0'. - - - - DEVICE_IP_IFACE - - The IP interface name of the device. This is the network - interface on which IP addresses and routes will be configured. - - - - IP4_ADDRESS_N - - The IPv4 address in the format "address/prefix gateway", where N is a number - from 0 to (# IPv4 addresses - 1). gateway item in this variable is deprecated, - use IP4_GATEWAY instead. - - - - IP4_NUM_ADDRESSES - - The variable contains the number of IPv4 addresses the script may expect. - - - - IP4_GATEWAY - - The gateway IPv4 address in traditional numbers-and-dots notation. - - - - IP4_ROUTE_N - - The IPv4 route in the format "address/prefix next-hop metric", where N is a number - from 0 to (# IPv4 routes - 1). - - - - IP4_NUM_ROUTES - - The variable contains the number of IPv4 routes the script may expect. - - - - IP4_NAMESERVERS - - The variable contains a space-separated list of the DNS servers. - - - - IP4_DOMAINS - - The variable contains a space-separated list of the search domains. - - - - DHCP4_<dhcp-option-name> - - If the connection used DHCP for address configuration, the received DHCP - configuration is passed in the environment using standard DHCP - option names, prefixed with "DHCP4_", like "DHCP4_HOST_NAME=foobar". - - - - IP6_<name> and DHCP6_<name> - - The same variables as for IPv4 are available for IPv6, but the prefixes are IP6_ - and DHCP6_ instead. - - - - CONNECTIVITY_STATE - The network connectivity state, which can - take the values defined by the NMConnectivityState type, - from the org.freedesktop.NetworkManager D-Bus API: unknown, - none, portal, limited or full. Note: this variable will only - be set for connectivity-change actions. - - - - - - In case of VPN, VPN_IP_IFACE is set, and IP4_*, IP6_* variables with VPN prefix are - exported too, like VPN_IP4_ADDRESS_0, VPN_IP4_NUM_ADDRESSES. - - - Dispatcher scripts are run one at a time, but asynchronously from the main - NetworkManager process, and will be killed if they run for too long. If your script - might take arbitrarily long to complete, you should spawn a child process and have the - parent return immediately. Scripts that are symbolic links pointing inside the - /etc/NetworkManager/dispatcher.d/no-wait.d/ - directory are run immediately, without - waiting for the termination of previous scripts, and in parallel. Also beware that - once a script is queued, it will always be run, even if a later event renders it - obsolete. (Eg, if an interface goes up, and then back down again quickly, it is - possible that one or more "up" scripts will be run after the interface has gone down.) + NetworkManager-dispatcher service can execute scripts for the user + in response to network events. See + NetworkManager-dispatcher8 manual. @@ -582,6 +331,7 @@ NetworkManager home page, NetworkManager.conf5, + NetworkManager-dispatcher8, nmcli1, nmcli-examples7, nm-online1, diff --git a/man/meson.build b/man/meson.build index a2e3bcd..fea0b9d 100644 --- a/man/meson.build +++ b/man/meson.build @@ -26,6 +26,7 @@ mans_xmls = [] mans = [ ['NetworkManager', '8'], + ['NetworkManager-dispatcher', '8'], ['NetworkManager.conf', '5'], ['nm-online', '1'], ['nmcli-examples', '7'], diff --git a/man/nm-cloud-setup.8 b/man/nm-cloud-setup.8 index 68fadde..e887dcf 100644 --- a/man/nm-cloud-setup.8 +++ b/man/nm-cloud-setup.8 @@ -2,12 +2,12 @@ .\" Title: nm-cloud-setup .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: Automatic Network Configuration in Cloud with NetworkManager -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NM\-CLOUD\-SETUP" "8" "" "NetworkManager 1\&.30\&.0" "Automatic Network Configuratio" +.TH "NM\-CLOUD\-SETUP" "8" "" "NetworkManager 1\&.31\&.2" "Automatic Network Configuratio" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-initrd-generator.8 b/man/nm-initrd-generator.8 index 00053b2..552436c 100644 --- a/man/nm-initrd-generator.8 +++ b/man/nm-initrd-generator.8 @@ -2,12 +2,12 @@ .\" Title: nm-initrd-generator .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: System Administration -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NM\-INITRD\-GENERATOR" "8" "" "NetworkManager 1\&.30\&.0" "System Administration" +.TH "NM\-INITRD\-GENERATOR" "8" "" "NetworkManager 1\&.31\&.2" "System Administration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-online.1 b/man/nm-online.1 index 6254c6a..91bcf04 100644 --- a/man/nm-online.1 +++ b/man/nm-online.1 @@ -2,12 +2,12 @@ .\" Title: nm-online .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: General Commands Manual -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NM\-ONLINE" "1" "" "NetworkManager 1\&.30\&.0" "General Commands Manual" +.TH "NM\-ONLINE" "1" "" "NetworkManager 1\&.31\&.2" "General Commands Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-openvswitch.7 b/man/nm-openvswitch.7 index 5c50bfa..e8676bb 100644 --- a/man/nm-openvswitch.7 +++ b/man/nm-openvswitch.7 @@ -2,12 +2,12 @@ .\" Title: nm-openvswitch .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: Open vSwitch support overview -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NM\-OPENVSWITCH" "7" "" "NetworkManager 1\&.30\&.0" "Open vSwitch support overview" +.TH "NM\-OPENVSWITCH" "7" "" "NetworkManager 1\&.31\&.2" "Open vSwitch support overview" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-settings-dbus.5 b/man/nm-settings-dbus.5 index a2b365e..6a444cb 100644 --- a/man/nm-settings-dbus.5 +++ b/man/nm-settings-dbus.5 @@ -2,12 +2,12 @@ .\" Title: nm-settings-dbus .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: Configuration -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NM\-SETTINGS\-DBUS" "5" "" "NetworkManager 1\&.30\&.0" "Configuration" +.TH "NM\-SETTINGS\-DBUS" "5" "" "NetworkManager 1\&.31\&.2" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -2816,7 +2816,7 @@ array of string T}:T{ \ \& T}:T{ -A list of kernel command line arguments to match\&. This may be used to check whether a specific kernel command line option is set (or if prefixed with the exclamation mark unset)\&. The argument must either be a single word, or an assignment (i\&.e\&. two words, separated "=")\&. In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment\&. In the latter case, the exact assignment is looked for with right and left hand side matching\&. See NMSettingMatch:interface\-name for how special characters \*(Aq|\*(Aq, \*(Aq&\*(Aq, \*(Aq!\*(Aq and \*(Aq\e\e\*(Aq are used for optional and mandatory matches and inverting the pattern\&. +A list of kernel command line arguments to match\&. This may be used to check whether a specific kernel command line option is set (or unset, if prefixed with the exclamation mark)\&. The argument must either be a single word, or an assignment (i\&.e\&. two words, joined by "=")\&. In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment\&. In the latter case, the exact assignment is looked for with right and left hand side matching\&. Wildcard patterns are not supported\&. See NMSettingMatch:interface\-name for how special characters \*(Aq|\*(Aq, \*(Aq&\*(Aq, \*(Aq!\*(Aq and \*(Aq\e\e\*(Aq are used for optional and mandatory matches and inverting the match\&. T} T{ path diff --git a/man/nm-settings-dbus.xml b/man/nm-settings-dbus.xml index 2b42a21..4729209 100644 --- a/man/nm-settings-dbus.xml +++ b/man/nm-settings-dbus.xml @@ -1,6 +1,6 @@ -nm-settings-dbusNetworkManager developersnm-settings-dbus5NetworkManagerConfiguration1.30.0nm-settings-dbusDescription of settings and properties of NetworkManager connection profiles on the D-Bus APIDescription +nm-settings-dbusNetworkManager developersnm-settings-dbus5NetworkManagerConfiguration1.31.2nm-settings-dbusDescription of settings and properties of NetworkManager connection profiles on the D-Bus APIDescription NetworkManager is based on a concept of connection profiles, sometimes referred to as connections only. These connection profiles contain a network configuration. When NetworkManager activates a connection profile on a network device the configuration will @@ -32,7 +32,7 @@ profile type. nmcli connection editor has also a built-in describe command that can display description of particular settings and properties of this page. - connection settingGeneral Connection Profile Settings.Key NameValue TypeDefault ValueValue Descriptionauth-retriesint32-1The number of retries for the authentication. Zero means to try indefinitely; -1 means to use a global default. If the global default is not set, the authentication retries for 3 times before failing the connection. Currently, this only applies to 802-1x authentication.autoconnectbooleanTRUEWhether or not the connection should be automatically connected by NetworkManager when the resources for the connection are available. TRUE to automatically activate the connection, FALSE to require manual intervention to activate the connection. Note that autoconnect is not implemented for VPN profiles. See "secondaries" as an alternative to automatically connect VPN profiles.autoconnect-priorityint320The autoconnect priority. If the connection is set to autoconnect, connections with higher priority will be preferred. Defaults to 0. The higher number means higher priority.autoconnect-retriesint32-1The number of times a connection should be tried when autoactivating before giving up. Zero means forever, -1 means the global default (4 times if not overridden). Setting this to 1 means to try activation only once before blocking autoconnect. Note that after a timeout, NetworkManager will try to autoconnect again.autoconnect-slavesNMSettingConnectionAutoconnectSlaves (int32)Whether or not slaves of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for master connections. The properties "autoconnect", "autoconnect-priority" and "autoconnect-retries" are unrelated to this setting. The permitted values are: 0: leave slave connections untouched, 1: activate all the slave connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-slaves is read to determine the real value. If it is default as well, this fallbacks to 0.gateway-ping-timeoutuint320If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping.idstringA human readable unique identifier for the connection, like "Work Wi-Fi" or "T-Mobile 3G".interface-namestringThe name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface.lldpint32-1Whether LLDP is enabled for the connection.llmnrint32-1Whether Link-Local Multicast Name Resolution (LLMNR) is enabled for the connection. LLMNR is a protocol based on the Domain Name System (DNS) packet format that allows both IPv4 and IPv6 hosts to perform name resolution for hosts on the same local link. The permitted values are: "yes" (2) register hostname and resolving for the connection, "no" (0) disable LLMNR for the interface, "resolve" (1) do not register hostname but allow resolving of LLMNR host names If unspecified, "default" ultimately depends on the DNS plugin (which for systemd-resolved currently means "yes"). This feature requires a plugin which supports LLMNR. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved.masterstringInterface name of the master device or UUID of the master connection.mdnsint32-1Whether mDNS is enabled for the connection. The permitted values are: "yes" (2) register hostname and resolving for the connection, "no" (0) disable mDNS for the interface, "resolve" (1) do not register hostname but allow resolving of mDNS host names and "default" (-1) to allow lookup of a global default in NetworkManager.conf. If unspecified, "default" ultimately depends on the DNS plugin (which for systemd-resolved currently means "no"). This feature requires a plugin which supports mDNS. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved.meteredNMMetered (int32)Whether the connection is metered. When updating this property on a currently activated connection, the change takes effect immediately.mud-urlstringIf configured, set to a Manufacturer Usage Description (MUD) URL that points to manufacturer-recommended network policies for IoT devices. It is transmitted as a DHCPv4 or DHCPv6 option. The value must be a valid URL starting with "https://". The special value "none" is allowed to indicate that no MUD URL is used. If the per-profile value is unspecified (the default), a global connection default gets consulted. If still unspecified, the ultimate default is "none".multi-connectint320Specifies whether the profile can be active multiple times at a particular moment. The value is of type NMConnectionMultiConnect.permissionsarray of stringAn array of strings defining what access a given user has to this connection. If this is NULL or empty, all users are allowed to access this connection; otherwise users are allowed if and only if they are in this list. When this is not empty, the connection can be active only when one of the specified users is logged into an active session. Each entry is of the form "[type]:[id]:[reserved]"; for example, "user:dcbw:blah". At this time only the "user" [type] is allowed. Any other values are ignored and reserved for future use. [id] is the username that this permission refers to, which may not contain the ":" character. Any [reserved] information present must be ignored and is reserved for future use. All of [type], [id], and [reserved] must be valid UTF-8.read-onlybooleanFALSEFALSE if the connection can be modified using the provided settings service's D-Bus interface with the right privileges, or TRUE if the connection is read-only and cannot be modified.secondariesarray of stringList of connection UUIDs that should be activated when the base connection itself is activated. Currently, only VPN connections are supported.slave-typestringSetting name of the device type of this slave's master connection (eg, "bond"), or NULL if this connection is not a slave.stable-idstringThis represents the identity of the connection used for various purposes. It allows to configure multiple profiles to share the identity. Also, the stable-id can contain placeholders that are substituted dynamically and deterministically depending on the context. The stable-id is used for generating IPv6 stable private addresses with ipv6.addr-gen-mode=stable-privacy. It is also used to seed the generated cloned MAC address for ethernet.cloned-mac-address=stable and wifi.cloned-mac-address=stable. It is also used as DHCP client identifier with ipv4.dhcp-client-id=stable and to derive the DHCP DUID with ipv6.dhcp-duid=stable-[llt,ll,uuid]. Note that depending on the context where it is used, other parameters are also seeded into the generation algorithm. For example, a per-host key is commonly also included, so that different systems end up generating different IDs. Or with ipv6.addr-gen-mode=stable-privacy, also the device's name is included, so that different interfaces yield different addresses. The per-host key is the identity of your machine and stored in /var/lib/NetworkManager/secret-key. The '$' character is treated special to perform dynamic substitutions at runtime. Currently, supported are "${CONNECTION}", "${DEVICE}", "${MAC}", "${BOOT}", "${RANDOM}". These effectively create unique IDs per-connection, per-device, per-boot, or every time. Note that "${DEVICE}" corresponds to the interface name of the device and "${MAC}" is the permanent MAC address of the device. Any unrecognized patterns following '$' are treated verbatim, however are reserved for future use. You are thus advised to avoid '$' or escape it as "$$". For example, set it to "${CONNECTION}-${BOOT}-${DEVICE}" to create a unique id for this connection that changes with every reboot and differs depending on the interface where the profile activates. If the value is unset, a global connection default is consulted. If the value is still unset, the default is similar to "${CONNECTION}" and uses a unique, fixed ID for the connection.timestampuint640The time, in seconds since the Unix Epoch, that the connection was last _successfully_ fully activated. NetworkManager updates the connection timestamp periodically when the connection is active to ensure that an active connection has the latest timestamp. The property is only meant for reading (changes to this property will not be preserved).typestringBase type of the connection. For hardware-dependent connections, should contain the setting name of the hardware-type specific setting (ie, "802-3-ethernet" or "802-11-wireless" or "bluetooth", etc), and for non-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, "vpn" or "bridge", etc).uuidstringA universally unique identifier for the connection, for example generated with libuuid. It should be assigned when the connection is created, and never changed as long as the connection still applies to the same network. For example, it should not be changed when the "id" property or NMSettingIP4Config changes, but might need to be re-created when the Wi-Fi SSID, mobile broadband network provider, or "type" property changes. The UUID must be in the format "2815492f-7e56-435e-b2e9-246bd7cdc664" (ie, contains only hexadecimal characters and "-").wait-device-timeoutint32-1Timeout in milliseconds to wait for device at startup. During boot, devices may take a while to be detected by the driver. This property will cause to delay NetworkManager-wait-online.service and nm-online to give the device a chance to appear. This works by waiting for the given timeout until a compatible device for the profile is available and managed. The value 0 means no wait time. The default value is -1, which currently has the same meaning as no wait time.zonestringThe trust level of a the connection. Free form case-insensitive string (for example "Home", "Work", "Public"). NULL or unspecified zone means the connection will be placed in the default zone as defined by the firewall. When updating this property on a currently activated connection, the change takes effect immediately.6lowpan setting6LoWPAN Settings.Key NameValue TypeDefault ValueValue DescriptionparentstringIf given, specifies the parent interface name or parent connection UUID from which this 6LowPAN interface should be created.802-1x settingIEEE 802.1x Authentication Settings.Key NameValue TypeDefault ValueValue Descriptionaltsubject-matchesarray of stringList of strings to be matched against the altSubjectName of the certificate presented by the authentication server. If the list is empty, no verification of the server certificate's altSubjectName is performed.anonymous-identitystringAnonymous identity string for EAP authentication methods. Used as the unencrypted identity with EAP types that support different tunneled identity like EAP-TTLS.auth-timeoutint320A timeout for the authentication. Zero means the global default; if the global default is not set, the authentication timeout is 25 seconds.ca-certbyte arrayContains the CA certificate if used by the EAP method specified in the "eap" property. Certificate data is specified using a "scheme"; three are currently supported: blob, path and pkcs#11 URL. When using the blob scheme this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended. Note that enabling NMSetting8021x:system-ca-certs will override this setting to use the built-in path, if the built-in path is not a directory.ca-cert-passwordstringThe password used to access the CA certificate stored in "ca-cert" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.ca-cert-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "ca-cert-password" property. (see for flag values)ca-pathstringUTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "ca-cert" property. If NMSetting8021x:system-ca-certs is enabled and the built-in CA path is an existing directory, then this setting is ignored.client-certbyte arrayContains the client certificate if used by the EAP method specified in the "eap" property. Certificate data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte.client-cert-passwordstringThe password used to access the client certificate stored in "client-cert" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.client-cert-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "client-cert-password" property. (see for flag values)domain-matchstringConstraint for server domain name. If set, this list of FQDNs is used as a match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using the same comparison. Multiple valid FQDNs can be passed as a ";" delimited list.domain-suffix-matchstringConstraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison. Since version 1.24, multiple valid FQDNs can be passed as a ";" delimited list.eaparray of stringThe allowed EAP method to be used when authenticating to the network with 802.1x. Valid methods are: "leap", "md5", "tls", "peap", "ttls", "pwd", and "fast". Each method requires different configuration using the properties of this setting; refer to wpa_supplicant documentation for the allowed combinations.identitystringIdentity string for EAP authentication methods. Often the user's user or login name.optionalbooleanFALSEWhether the 802.1X authentication is optional. If TRUE, the activation will continue even after a timeout or an authentication failure. Setting the property to TRUE is currently allowed only for Ethernet connections. If set to FALSE, the activation can continue only after a successful authentication.pac-filestringUTF-8 encoded file path containing PAC for EAP-FAST.passwordstringUTF-8 encoded password used for EAP authentication methods. If both the "password" property and the "password-raw" property are specified, "password" is preferred.password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values)password-rawbyte arrayPassword used for EAP authentication methods, given as a byte array to allow passwords in other encodings than UTF-8 to be used. If both the "password" property and the "password-raw" property are specified, "password" is preferred.password-raw-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password-raw" property. (see for flag values)phase1-auth-flagsuint320Specifies authentication flags to use in "phase 1" outer authentication using NMSetting8021xAuthFlags options. The individual TLS versions can be explicitly disabled. If a certain TLS disable flag is not set, it is up to the supplicant to allow or forbid it. The TLS options map to tls_disable_tlsv1_x settings. See the wpa_supplicant documentation for more details.phase1-fast-provisioningstringEnables or disables in-line provisioning of EAP-FAST credentials when FAST is specified as the EAP method in the "eap" property. Recognized values are "0" (disabled), "1" (allow unauthenticated provisioning), "2" (allow authenticated provisioning), and "3" (allow both authenticated and unauthenticated provisioning). See the wpa_supplicant documentation for more details.phase1-peaplabelstringForces use of the new PEAP label during key derivation. Some RADIUS servers may require forcing the new PEAP label to interoperate with PEAPv1. Set to "1" to force use of the new PEAP label. See the wpa_supplicant documentation for more details.phase1-peapverstringForces which PEAP version is used when PEAP is set as the EAP method in the "eap" property. When unset, the version reported by the server will be used. Sometimes when using older RADIUS servers, it is necessary to force the client to use a particular PEAP version. To do so, this property may be set to "0" or "1" to force that specific PEAP version.phase2-altsubject-matchesarray of stringList of strings to be matched against the altSubjectName of the certificate presented by the authentication server during the inner "phase 2" authentication. If the list is empty, no verification of the server certificate's altSubjectName is performed.phase2-authstringSpecifies the allowed "phase 2" inner authentication method when an EAP method that uses an inner TLS tunnel is specified in the "eap" property. For TTLS this property selects one of the supported non-EAP inner methods: "pap", "chap", "mschap", "mschapv2" while "phase2-autheap" selects an EAP inner method. For PEAP this selects an inner EAP method, one of: "gtc", "otp", "md5" and "tls". Each "phase 2" inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details. Both "phase2-auth" and "phase2-autheap" cannot be specified.phase2-autheapstringSpecifies the allowed "phase 2" inner EAP-based authentication method when TTLS is specified in the "eap" property. Recognized EAP-based "phase 2" methods are "md5", "mschapv2", "otp", "gtc", and "tls". Each "phase 2" inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details.phase2-ca-certbyte arrayContains the "phase 2" CA certificate if used by the EAP method specified in the "phase2-auth" or "phase2-autheap" properties. Certificate data is specified using a "scheme"; three are currently supported: blob, path and pkcs#11 URL. When using the blob scheme this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended. Note that enabling NMSetting8021x:system-ca-certs will override this setting to use the built-in path, if the built-in path is not a directory.phase2-ca-cert-passwordstringThe password used to access the "phase2" CA certificate stored in "phase2-ca-cert" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.phase2-ca-cert-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "phase2-ca-cert-password" property. (see for flag values)phase2-ca-pathstringUTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "phase2-ca-cert" property. If NMSetting8021x:system-ca-certs is enabled and the built-in CA path is an existing directory, then this setting is ignored.phase2-client-certbyte arrayContains the "phase 2" client certificate if used by the EAP method specified in the "phase2-auth" or "phase2-autheap" properties. Certificate data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended.phase2-client-cert-passwordstringThe password used to access the "phase2" client certificate stored in "phase2-client-cert" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.phase2-client-cert-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "phase2-client-cert-password" property. (see for flag values)phase2-domain-matchstringConstraint for server domain name. If set, this list of FQDNs is used as a match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner "phase 2" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using the same comparison. Multiple valid FQDNs can be passed as a ";" delimited list.phase2-domain-suffix-matchstringConstraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner "phase 2" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison. Since version 1.24, multiple valid FQDNs can be passed as a ";" delimited list.phase2-private-keybyte arrayContains the "phase 2" inner private key when the "phase2-auth" or "phase2-autheap" property is set to "tls". Key data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the "phase2-private-key-password" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte, and as with the blob scheme the "phase2-private-key-password" property must be set to the password used to decode the PKCS#12 private key and certificate.phase2-private-key-passwordstringThe password used to decrypt the "phase 2" private key specified in the "phase2-private-key" property when the private key either uses the path scheme, or is a PKCS#12 format key.phase2-private-key-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "phase2-private-key-password" property. (see for flag values)phase2-subject-matchstringSubstring to be matched against the subject of the certificate presented by the authentication server during the inner "phase 2" authentication. When unset, no verification of the authentication server certificate's subject is performed. This property provides little security, if any, and its use is deprecated in favor of NMSetting8021x:phase2-domain-suffix-match.pinstringPIN used for EAP authentication methods.pin-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "pin" property. (see for flag values)private-keybyte arrayContains the private key when the "eap" property is set to "tls". Key data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the "private-key-password" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte, and as with the blob scheme the "private-key-password" property must be set to the password used to decode the PKCS#12 private key and certificate. WARNING: "private-key" is not a "secret" property, and thus unencrypted private key data using the BLOB scheme may be readable by unprivileged users. Private keys should always be encrypted with a private key password to prevent unauthorized access to unencrypted private key data.private-key-passwordstringThe password used to decrypt the private key specified in the "private-key" property when the private key either uses the path scheme, or if the private key is a PKCS#12 format key.private-key-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "private-key-password" property. (see for flag values)subject-matchstringSubstring to be matched against the subject of the certificate presented by the authentication server. When unset, no verification of the authentication server certificate's subject is performed. This property provides little security, if any, and its use is deprecated in favor of NMSetting8021x:domain-suffix-match.system-ca-certsbooleanFALSEWhen TRUE, overrides the "ca-path" and "phase2-ca-path" properties using the system CA directory specified at configure time with the --system-ca-path switch. The certificates in this directory are added to the verification chain in addition to any certificates specified by the "ca-cert" and "phase2-ca-cert" properties. If the path provided with --system-ca-path is rather a file name (bundle of trusted CA certificates), it overrides "ca-cert" and "phase2-ca-cert" properties instead (sets ca_cert/ca_cert2 options for wpa_supplicant).adsl settingADSL Settings.Key NameValue TypeDefault ValueValue DescriptionencapsulationstringEncapsulation of ADSL connection. Can be "vcmux" or "llc".passwordstringPassword used to authenticate with the ADSL service.password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values)protocolstringADSL connection protocol. Can be "pppoa", "pppoe" or "ipoatm".usernamestringUsername used to authenticate with the ADSL service.vciuint320VCI of ADSL connectionvpiuint320VPI of ADSL connectionbluetooth settingBluetooth Settings.Key NameValue TypeDefault ValueValue Descriptionbdaddrbyte arrayThe Bluetooth address of the device.typestringEither "dun" for Dial-Up Networking connections or "panu" for Personal Area Networking connections to devices supporting the NAP profile.bond settingBonding Settings.Key NameValue TypeDefault ValueValue Descriptioninterface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the bond's interface name.optionsdict of string to string{'mode': 'balance-rr'}Dictionary of key/value pairs of bonding options. Both keys and values must be strings. Option names must contain only alphanumeric characters (ie, [a-zA-Z0-9]).bridge settingBridging Settings.Key NameValue TypeDefault ValueValue Descriptionageing-timeuint32300The Ethernet MAC address aging time, in seconds.forward-delayuint3215The Spanning Tree Protocol (STP) forwarding delay, in seconds.group-addressbyte arrayIf specified, The MAC address of the multicast group this bridge uses for STP. The address must be a link-local address in standard Ethernet MAC address format, ie an address of the form 01:80:C2:00:00:0X, with X in [0, 4..F]. If not specified the default value is 01:80:C2:00:00:00.group-forward-maskuint320A mask of group addresses to forward. Usually, group addresses in the range from 01:80:C2:00:00:00 to 01:80:C2:00:00:0F are not forwarded according to standards. This property is a mask of 16 bits, each corresponding to a group address in that range that must be forwarded. The mask can't have bits 0, 1 or 2 set because they are used for STP, MAC pause frames and LACP.hello-timeuint322The Spanning Tree Protocol (STP) hello time, in seconds.interface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the bridge's interface name.mac-addressbyte arrayIf specified, the MAC address of bridge. When creating a new bridge, this MAC address will be set. If this field is left unspecified, the "ethernet.cloned-mac-address" is referred instead to generate the initial MAC address. Note that setting "ethernet.cloned-mac-address" anyway overwrites the MAC address of the bridge later while activating the bridge. Hence, this property is deprecated. Deprecated: 1max-ageuint3220The Spanning Tree Protocol (STP) maximum message age, in seconds.multicast-hash-maxuint324096Set maximum size of multicast hash table (value must be a power of 2).multicast-last-member-countuint322Set the number of queries the bridge will send before stopping forwarding a multicast group after a "leave" message has been received.multicast-last-member-intervaluint64100Set interval (in deciseconds) between queries to find remaining members of a group, after a "leave" message is received.multicast-membership-intervaluint6426000Set delay (in deciseconds) after which the bridge will leave a group, if no membership reports for this group are received.multicast-querierbooleanFALSEEnable or disable sending of multicast queries by the bridge. If not specified the option is disabled.multicast-querier-intervaluint6425500If no queries are seen after this delay (in deciseconds) has passed, the bridge will start to send its own queries.multicast-query-intervaluint6412500Interval (in deciseconds) between queries sent by the bridge after the end of the startup phase.multicast-query-response-intervaluint641000Set the Max Response Time/Max Response Delay (in deciseconds) for IGMP/MLD queries sent by the bridge.multicast-query-use-ifaddrbooleanFALSEIf enabled the bridge's own IP address is used as the source address for IGMP queries otherwise the default of 0.0.0.0 is used.multicast-routerstringSets bridge's multicast router. Multicast-snooping must be enabled for this option to work. Supported values are: 'auto', 'disabled', 'enabled' to which kernel assigns the numbers 1, 0, and 2, respectively. If not specified the default value is 'auto' (1).multicast-snoopingbooleanTRUEControls whether IGMP snooping is enabled for this bridge. Note that if snooping was automatically disabled due to hash collisions, the system may refuse to enable the feature until the collisions are resolved.multicast-startup-query-countuint322Set the number of IGMP queries to send during startup phase.multicast-startup-query-intervaluint643125Sets the time (in deciseconds) between queries sent out at startup to determine membership information.priorityuint3232768Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower values are "better"; the lowest priority bridge will be elected the root bridge.stpbooleanTRUEControls whether Spanning Tree Protocol (STP) is enabled for this bridge.vlan-default-pviduint321The default PVID for the ports of the bridge, that is the VLAN id assigned to incoming untagged frames.vlan-filteringbooleanFALSEControl whether VLAN filtering is enabled on the bridge.vlan-protocolstringIf specified, the protocol used for VLAN filtering. Supported values are: '802.1Q', '802.1ad'. If not specified the default value is '802.1Q'.vlan-stats-enabledbooleanFALSEControls whether per-VLAN stats accounting is enabled.vlansarray of vardictArray of bridge VLAN objects. In addition to the VLANs specified here, the bridge will also have the default-pvid VLAN configured by the bridge.vlan-default-pvid property. In nmcli the VLAN list can be specified with the following syntax: $vid [pvid] [untagged] [, $vid [pvid] [untagged]]... where $vid is either a single id between 1 and 4094 or a range, represented as a couple of ids separated by a dash.bridge-port settingBridge Port Settings.Key NameValue TypeDefault ValueValue Descriptionhairpin-modebooleanFALSEEnables or disables "hairpin mode" for the port, which allows frames to be sent back out through the port the frame was received on.path-costuint32100The Spanning Tree Protocol (STP) port cost for destinations via this port.priorityuint3232The Spanning Tree Protocol (STP) priority of this bridge port.vlansarray of vardictArray of bridge VLAN objects. In addition to the VLANs specified here, the port will also have the default-pvid VLAN configured on the bridge by the bridge.vlan-default-pvid property. In nmcli the VLAN list can be specified with the following syntax: $vid [pvid] [untagged] [, $vid [pvid] [untagged]]... where $vid is either a single id between 1 and 4094 or a range, represented as a couple of ids separated by a dash.cdma settingCDMA-based Mobile Broadband Settings.Key NameValue TypeDefault ValueValue Descriptionmtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.numberstringThe number to dial to establish the connection to the CDMA-based mobile broadband network, if any. If not specified, the default number (#777) is used when required.passwordstringThe password used to authenticate with the network, if required. Many providers do not require a password, or accept any password. But if a password is required, it is specified here.password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values)usernamestringThe username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.dcb settingData Center Bridging Settings.Key NameValue TypeDefault ValueValue Descriptionapp-fcoe-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for the DCB FCoE application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).app-fcoe-modestring"fabric"The FCoE controller mode; either "fabric" (default) or "vn2vn".app-fcoe-priorityint32-1The highest User Priority (0 - 7) which FCoE frames should use, or -1 for default priority. Only used when the "app-fcoe-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag.app-fip-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for the DCB FIP application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).app-fip-priorityint32-1The highest User Priority (0 - 7) which FIP frames should use, or -1 for default priority. Only used when the "app-fip-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag.app-iscsi-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for the DCB iSCSI application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).app-iscsi-priorityint32-1The highest User Priority (0 - 7) which iSCSI frames should use, or -1 for default priority. Only used when the "app-iscsi-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag.priority-bandwidtharray of uint32An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the percentage of bandwidth of the priority's assigned group that the priority may use. The sum of all percentages for priorities which belong to the same group must total 100 percents.priority-flow-controlarray of uint32An array of 8 boolean values, where the array index corresponds to the User Priority (0 - 7) and the value indicates whether or not the corresponding priority should transmit priority pause.priority-flow-control-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for DCB Priority Flow Control (PFC). Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).priority-group-bandwidtharray of uint32An array of 8 uint values, where the array index corresponds to the Priority Group ID (0 - 7) and the value indicates the percentage of link bandwidth allocated to that group. Allowed values are 0 - 100, and the sum of all values must total 100 percents.priority-group-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for DCB Priority Groups. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).priority-group-idarray of uint32An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the Priority Group ID. Allowed Priority Group ID values are 0 - 7 or 15 for the unrestricted group.priority-strict-bandwidtharray of uint32An array of 8 boolean values, where the array index corresponds to the User Priority (0 - 7) and the value indicates whether or not the priority may use all of the bandwidth allocated to its assigned group.priority-traffic-classarray of uint32An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the traffic class (0 - 7) to which the priority is mapped.dummy settingDummy Link Settings.Key NameValue TypeDefault ValueValue Descriptionethtool settingEthtool Ethernet Settings.Key NameValue TypeDefault ValueValue Descriptiongeneric settingGeneric Link Settings.Key NameValue TypeDefault ValueValue Descriptiongsm settingGSM-based Mobile Broadband Settings.Key NameValue TypeDefault ValueValue DescriptionapnstringThe GPRS Access Point Name specifying the APN used when establishing a data session with the GSM-based network. The APN often determines how the user will be billed for their network usage and whether the user has access to the Internet or just a provider-specific walled-garden, so it is important to use the correct APN for the user's mobile broadband plan. The APN may only be composed of the characters a-z, 0-9, ., and - per GSM 03.60 Section 14.9.auto-configbooleanFALSEWhen TRUE, the settings such as APN, username, or password will default to values that match the network the modem will register to in the Mobile Broadband Provider database.device-idstringThe device unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will only apply to the specified device.home-onlybooleanFALSEWhen TRUE, only connections to the home network will be allowed. Connections to roaming networks will not be made.mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.network-idstringThe Network ID (GSM LAI format, ie MCC-MNC) to force specific network registration. If the Network ID is specified, NetworkManager will attempt to force the device to register only on the specified network. This can be used to ensure that the device does not roam when direct roaming control of the device is not otherwise possible.numberstringLegacy setting that used to help establishing PPP data sessions for GSM-based modems. Deprecated: 1passwordstringThe password used to authenticate with the network, if required. Many providers do not require a password, or accept any password. But if a password is required, it is specified here.password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values)pinstringIf the SIM is locked with a PIN it must be unlocked before any other operations are requested. Specify the PIN here to allow operation of the device.pin-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "pin" property. (see for flag values)sim-idstringThe SIM card unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will apply to any device also allowed by "device-id" which contains a SIM card matching the given identifier.sim-operator-idstringA MCC/MNC string like "310260" or "21601" identifying the specific mobile network operator which this connection applies to. If given, the connection will apply to any device also allowed by "device-id" and "sim-id" which contains a SIM card provisioned by the given operator.usernamestringThe username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.infiniband settingInfiniband Settings.Key NameValue TypeDefault ValueValue Descriptionmac-addressbyte arrayIf specified, this connection will only apply to the IPoIB device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.p-keyint32-1The InfiniBand P_Key to use for this device. A value of -1 means to use the default P_Key (aka "the P_Key at index 0"). Otherwise, it is a 16-bit unsigned integer, whose high bit is set if it is a "full membership" P_Key.parentstringThe interface name of the parent device of this device. Normally NULL, but if the "p_key" property is set, then you must specify the base device by setting either this property or "mac-address".transport-modestringThe IP-over-InfiniBand transport mode. Either "datagram" or "connected".ipv4 settingIPv4 Settings.Key NameValue TypeDefault ValueValue Descriptionaddress-dataarray of vardictArray of IPv4 addresses. Each address dictionary contains at least 'address' and 'prefix' entries, containing the IP address as a string, and the prefix length as a uint32. Additional attributes may also exist on some addresses.addressesarray of array of uint32Deprecated in favor of the 'address-data' and 'gateway' properties, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'address-data' and 'gateway'. Array of IPv4 address structures. Each IPv4 address structure is composed of 3 32-bit values; the first being the IPv4 address (network byte order), the second the prefix (1 - 32), and last the IPv4 gateway (network byte order). The gateway may be left as 0 if no gateway exists for that subnet.dad-timeoutint32-1Timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4.dhcp-client-idstringA string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values "mac" and "perm-mac" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value "ipv6-duid" uses the DUID from "ipv6.dhcp-duid" property as an RFC4361-compliant client identifier. As IAID it uses "ipv4.dhcp-iaid" and falls back to "ipv6.dhcp-iaid" if unset. The special value "duid" generates a RFC4361-compliant client identifier based on "ipv4.dhcp-iaid" and uses a DUID generated by hashing /etc/machine-id. The special value "stable" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the "${DEVICE}" or "${MAC}" specifier to get a per-device key. If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin.dhcp-fqdnstringIf the "dhcp-send-hostname" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and "dhcp-hostname" are mutually exclusive and cannot be set at the same time.dhcp-hostnamestringIf the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time.dhcp-hostname-flagsuint320Flags for the DHCP hostname and FQDN. Currently, this property only includes flags to control the FQDN flags set in the DHCP FQDN option. Supported FQDN flags are NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) and NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE (0x4). When no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is set, the DHCP FQDN option will contain no flag. Otherwise, if no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is not set, the standard FQDN flags are set in the request: NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) for IPv4 and NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1) for IPv6. When this property is set to the default value NM_DHCP_HOSTNAME_FLAG_NONE (0x0), a global default is looked up in NetworkManager configuration. If that value is unset or also NM_DHCP_HOSTNAME_FLAG_NONE (0x0), then the standard FQDN flags described above are sent in the DHCP requests.dhcp-iaidstringA string containing the "Identity Association Identifier" (IAID) used by the DHCP client. The property is a 32-bit decimal value or a special value among "mac", "perm-mac", "ifname" and "stable". When set to "mac" (or "perm-mac"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to "ifname", the IAID is computed by hashing the interface name. The special value "stable" can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be "ifname". Note that at the moment this property is ignored for IPv6 by dhclient, which always derives the IAID from the MAC address.dhcp-reject-serversarray of stringArray of servers from which DHCP offers must be rejected. This property is useful to avoid getting a lease from misconfigured or rogue servers. For DHCPv4, each element must be an IPv4 address, optionally followed by a slash and a prefix length (e.g. "192.168.122.0/24"). This property is currently not implemented for DHCPv6.dhcp-send-hostnamebooleanTRUEIf TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.dhcp-timeoutint320A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.dhcp-vendor-class-identifierstringThe Vendor Class Identifier DHCP option (60). Special characters in the data string may be escaped using C-style escapes, nevertheless this property cannot contain nul bytes. If the per-profile value is unspecified (the default), a global connection default gets consulted. If still unspecified, the DHCP option is not sent to the server. Since 1.28dnsarray of uint32Array of IP addresses of DNS servers (as network-byte-order integers)dns-optionsarray of stringArray of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are "attempts", "debug", "edns0", "inet6", "ip6-bytestring", "ip6-dotint", "ndots", "no-check-names", "no-ip6-dotint", "no-reload", "no-tld-query", "rotate", "single-request", "single-request-reopen", "timeout", "trust-ad", "use-vc". The "trust-ad" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have "trust-ad" enabled. When using a caching DNS plugin (dnsmasq or systemd-resolved in NetworkManager.conf) then "edns0" and "trust-ad" are automatically added.dns-priorityint320DNS servers priority. The relative priority for DNS servers specified by this setting. A lower numerical value is better (higher priority). Negative values have the special effect of excluding other configurations with a greater numerical priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. To avoid all DNS leaks, set the priority of the profile that should be used to the most negative value of all active connections profiles. Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. Note that commonly the resolver tries name servers in /etc/resolv.conf in the order listed, proceeding with the next server in the list on failure. See for example the "rotate" option of the dns-options setting. If there are any negative DNS priorities, then only name servers from the devices with that lowest priority will be considered. When using a DNS resolver that supports Conditional Forwarding or Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection is used to query domains in its search list. The search domains determine which name servers to ask, and the DNS priority is used to prioritize name servers based on the domain. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the best priority (lowest numerical value) wins. If a sub domain is configured on another interface it will be accepted regardless the priority, unless parent domain on the other interface has a negative priority, which causes the sub domain to be shadowed. With Split DNS one can avoid undesired DNS leaks by properly configuring DNS priorities and the search domains, so that only name servers of the desired interface are configured.dns-searcharray of stringArray of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names. When using a DNS plugin that supports Conditional Forwarding or Split DNS, then the search domains specify which name servers to query. This makes the behavior different from running with plain /etc/resolv.conf. For more information see also the dns-priority setting.gatewaystringThe gateway associated with this configuration. This is only meaningful if "addresses" is also set. The gateway's main purpose is to control the next hop of the standard default route on the device. Hence, the gateway property conflicts with "never-default" and will be automatically dropped if the IP configuration is set to never-default. As an alternative to set the gateway, configure a static default route with /0 as prefix length.ignore-auto-dnsbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured name servers and search domains are ignored and only name servers and search domains specified in the "dns" and "dns-search" properties, if any, are used.ignore-auto-routesbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used.may-failbooleanTRUEIf TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully.methodstringIP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "disabled", "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty. For IPv4 method "shared", the IP subnet can be configured by adding one manual IPv4 address or otherwise 10.42.x.0/24 is chosen. Note that the shared method must be configured on the interface which shares the internet to a subnet, not on the uplink which is shared.never-defaultbooleanFALSEIf TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager.route-dataarray of vardictArray of IPv4 routes. Each route dictionary contains at least 'dest' and 'prefix' entries, containing the destination IP address as a string, and the prefix length as a uint32. Most routes will also have a 'next-hop' entry, containing the next hop IP address as a string. If the route has a 'metric' entry (containing a uint32), that will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device). Additional attributes may also exist on some routes.route-metricint64-1The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric.route-tableuint320Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.routesarray of array of uint32Deprecated in favor of the 'route-data' property, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'route-data'. Array of IPv4 route structures. Each IPv4 route structure is composed of 4 32-bit values; the first being the destination IPv4 network or address (network byte order), the second the destination network or address prefix (1 - 32), the third being the next-hop (network byte order) if any, and the fourth being the route metric. If the metric is 0, NM will choose an appropriate default metric for the device. (There is no way to explicitly specify an actual metric of 0 with this property.)ipv6 settingIPv6 Settings.Key NameValue TypeDefault ValueValue Descriptionaddr-gen-modeint321Configure method for creating the address for use with RFC4862 IPv6 Stateless Address Autoconfiguration. The permitted values are: NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 (0) or NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY (1). If the property is set to EUI64, the addresses will be generated using the interface tokens derived from hardware address. This makes the host part of the address to stay constant, making it possible to track host's presence when it changes networks. The address changes when the interface hardware is replaced. The value of stable-privacy enables use of cryptographically secure hash of a secret host-specific key along with the connection's stable-id and the network address as specified by RFC7217. This makes it impossible to use the address track host's presence, and makes the address stable when the network interface hardware is replaced. On D-Bus, the absence of an addr-gen-mode setting equals enabling stable-privacy. For keyfile plugin, the absence of the setting on disk means EUI64 so that the property doesn't change on upgrade from older versions. Note that this setting is distinct from the Privacy Extensions as configured by "ip6-privacy" property and it does not affect the temporary addresses configured with this option.address-dataarray of vardictArray of IPv6 addresses. Each address dictionary contains at least 'address' and 'prefix' entries, containing the IP address as a string, and the prefix length as a uint32. Additional attributes may also exist on some addresses.addressesarray of legacy IPv6 address struct (a(ayuay))Deprecated in favor of the 'address-data' and 'gateway' properties, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'address-data' and 'gateway'. Array of IPv6 address structures. Each IPv6 address structure is composed of an IPv6 address, a prefix length (1 - 128), and an IPv6 gateway address. The gateway may be zeroed out if no gateway exists for that subnet.dad-timeoutint32-1Timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4.dhcp-duidstringA string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp client to identify itself to DHCPv6 servers (RFC 3315). The DUID is carried in the Client Identifier option. If the property is a hex string ('aa:bb:cc') it is interpreted as a binary DUID and filled as an opaque value in the Client Identifier option. The special value "lease" will retrieve the DUID previously used from the lease file belonging to the connection. If no DUID is found and "dhclient" is the configured dhcp client, the DUID is searched in the system-wide dhclient lease file. If still no DUID is found, or another dhcp client is used, a global and permanent DUID-UUID (RFC 6355) will be generated based on the machine-id. The special values "llt" and "ll" will generate a DUID of type LLT or LL (see RFC 3315) based on the current MAC address of the device. In order to try providing a stable DUID-LLT, the time field will contain a constant timestamp that is used globally (for all profiles) and persisted to disk. The special values "stable-llt", "stable-ll" and "stable-uuid" will generate a DUID of the corresponding type, derived from the connection's stable-id and a per-host unique key. You may want to include the "${DEVICE}" or "${MAC}" specifier in the stable-id, in case this profile gets activated on multiple devices. So, the link-layer address of "stable-ll" and "stable-llt" will be a generated address derived from the stable id. The DUID-LLT time value in the "stable-llt" option will be picked among a static timespan of three years (the upper bound of the interval is the same constant timestamp used in "llt"). When the property is unset, the global value provided for "ipv6.dhcp-duid" is used. If no global value is provided, the default "lease" value is assumed.dhcp-hostnamestringIf the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time.dhcp-hostname-flagsuint320Flags for the DHCP hostname and FQDN. Currently, this property only includes flags to control the FQDN flags set in the DHCP FQDN option. Supported FQDN flags are NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) and NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE (0x4). When no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is set, the DHCP FQDN option will contain no flag. Otherwise, if no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is not set, the standard FQDN flags are set in the request: NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) for IPv4 and NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1) for IPv6. When this property is set to the default value NM_DHCP_HOSTNAME_FLAG_NONE (0x0), a global default is looked up in NetworkManager configuration. If that value is unset or also NM_DHCP_HOSTNAME_FLAG_NONE (0x0), then the standard FQDN flags described above are sent in the DHCP requests.dhcp-iaidstringA string containing the "Identity Association Identifier" (IAID) used by the DHCP client. The property is a 32-bit decimal value or a special value among "mac", "perm-mac", "ifname" and "stable". When set to "mac" (or "perm-mac"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to "ifname", the IAID is computed by hashing the interface name. The special value "stable" can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be "ifname". Note that at the moment this property is ignored for IPv6 by dhclient, which always derives the IAID from the MAC address.dhcp-reject-serversarray of stringArray of servers from which DHCP offers must be rejected. This property is useful to avoid getting a lease from misconfigured or rogue servers. For DHCPv4, each element must be an IPv4 address, optionally followed by a slash and a prefix length (e.g. "192.168.122.0/24"). This property is currently not implemented for DHCPv6.dhcp-send-hostnamebooleanTRUEIf TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.dhcp-timeoutint320A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.dnsarray of byte arrayArray of IP addresses of DNS servers (in network byte order)dns-optionsarray of stringArray of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are "attempts", "debug", "edns0", "inet6", "ip6-bytestring", "ip6-dotint", "ndots", "no-check-names", "no-ip6-dotint", "no-reload", "no-tld-query", "rotate", "single-request", "single-request-reopen", "timeout", "trust-ad", "use-vc". The "trust-ad" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have "trust-ad" enabled. When using a caching DNS plugin (dnsmasq or systemd-resolved in NetworkManager.conf) then "edns0" and "trust-ad" are automatically added.dns-priorityint320DNS servers priority. The relative priority for DNS servers specified by this setting. A lower numerical value is better (higher priority). Negative values have the special effect of excluding other configurations with a greater numerical priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. To avoid all DNS leaks, set the priority of the profile that should be used to the most negative value of all active connections profiles. Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. Note that commonly the resolver tries name servers in /etc/resolv.conf in the order listed, proceeding with the next server in the list on failure. See for example the "rotate" option of the dns-options setting. If there are any negative DNS priorities, then only name servers from the devices with that lowest priority will be considered. When using a DNS resolver that supports Conditional Forwarding or Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection is used to query domains in its search list. The search domains determine which name servers to ask, and the DNS priority is used to prioritize name servers based on the domain. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the best priority (lowest numerical value) wins. If a sub domain is configured on another interface it will be accepted regardless the priority, unless parent domain on the other interface has a negative priority, which causes the sub domain to be shadowed. With Split DNS one can avoid undesired DNS leaks by properly configuring DNS priorities and the search domains, so that only name servers of the desired interface are configured.dns-searcharray of stringArray of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names. When using a DNS plugin that supports Conditional Forwarding or Split DNS, then the search domains specify which name servers to query. This makes the behavior different from running with plain /etc/resolv.conf. For more information see also the dns-priority setting.gatewaystringThe gateway associated with this configuration. This is only meaningful if "addresses" is also set. The gateway's main purpose is to control the next hop of the standard default route on the device. Hence, the gateway property conflicts with "never-default" and will be automatically dropped if the IP configuration is set to never-default. As an alternative to set the gateway, configure a static default route with /0 as prefix length.ignore-auto-dnsbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured name servers and search domains are ignored and only name servers and search domains specified in the "dns" and "dns-search" properties, if any, are used.ignore-auto-routesbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used.ip6-privacyNMSettingIP6ConfigPrivacy (int32)Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI-64. This enhances privacy, but could cause problems in some applications, on the other hand. The permitted values are: -1: unknown, 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses). Having a per-connection setting set to "-1" (unknown) means fallback to global configuration "ipv6.ip6-privacy". If also global configuration is unspecified or set to "-1", fallback to read "/proc/sys/net/ipv6/conf/default/use_tempaddr". Note that this setting is distinct from the Stable Privacy addresses that can be enabled with the "addr-gen-mode" property's "stable-privacy" setting as another way of avoiding host tracking with IPv6 addresses.may-failbooleanTRUEIf TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully.methodstringIP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "disabled", "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty. For IPv4 method "shared", the IP subnet can be configured by adding one manual IPv4 address or otherwise 10.42.x.0/24 is chosen. Note that the shared method must be configured on the interface which shares the internet to a subnet, not on the uplink which is shared.never-defaultbooleanFALSEIf TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager.ra-timeoutint320A timeout for waiting Router Advertisements in seconds. If zero (the default), a globally configured default is used. If still unspecified, the timeout depends on the sysctl settings of the device. Set to 2147483647 (MAXINT32) for infinity.route-dataarray of vardictArray of IPv6 routes. Each route dictionary contains at least 'dest' and 'prefix' entries, containing the destination IP address as a string, and the prefix length as a uint32. Most routes will also have a 'next-hop' entry, containing the next hop IP address as a string. If the route has a 'metric' entry (containing a uint32), that will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device). Additional attributes may also exist on some routes.route-metricint64-1The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric.route-tableuint320Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.routesarray of legacy IPv6 route struct (a(ayuayu))Deprecated in favor of the 'route-data' property, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'route-data'. Array of IPv6 route structures. Each IPv6 route structure is composed of an IPv6 address, a prefix length (1 - 128), an IPv6 next hop address (which may be zeroed out if there is no next hop), and a metric. If the metric is 0, NM will choose an appropriate default metric for the device.tokenstringConfigure the token for draft-chown-6man-tokenised-ipv6-identifiers-02 IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode.ip-tunnel settingIP Tunneling Settings.Key NameValue TypeDefault ValueValue Descriptionencapsulation-limituint320How many additional levels of encapsulation are permitted to be prepended to packets. This property applies only to IPv6 tunnels.flagsuint320Tunnel flags. Currently, the following values are supported: NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT (0x1), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS (0x2), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL (0x4), NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV (0x8), NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY (0x10), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK (0x20). They are valid only for IPv6 tunnels.flow-labeluint320The flow label to assign to tunnel packets. This property applies only to IPv6 tunnels.input-keystringThe key used for tunnel input packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used.localstringThe local endpoint of the tunnel; the value can be empty, otherwise it must contain an IPv4 or IPv6 address.modeuint320The tunneling mode, for example NM_IP_TUNNEL_MODE_IPIP (1) or NM_IP_TUNNEL_MODE_GRE (2).mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments.output-keystringThe key used for tunnel output packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used.parentstringIf given, specifies the parent interface name or parent connection UUID the new device will be bound to so that tunneled packets will only be routed via that interface.path-mtu-discoverybooleanTRUEWhether to enable Path MTU Discovery on this tunnel.remotestringThe remote endpoint of the tunnel; the value must contain an IPv4 or IPv6 address.tosuint320The type of service (IPv4) or traffic class (IPv6) field to be set on tunneled packets.ttluint320The TTL to assign to tunneled packets. 0 is a special value meaning that packets inherit the TTL value.macsec settingMACSec Settings.Key NameValue TypeDefault ValueValue DescriptionencryptbooleanTRUEWhether the transmitted traffic must be encrypted.mka-cakstringThe pre-shared CAK (Connectivity Association Key) for MACsec Key Agreement.mka-cak-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "mka-cak" property. (see for flag values)mka-cknstringThe pre-shared CKN (Connectivity-association Key Name) for MACsec Key Agreement.modeint320Specifies how the CAK (Connectivity Association Key) for MKA (MACsec Key Agreement) is obtained.parentstringIf given, specifies the parent interface name or parent connection UUID from which this MACSEC interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property.portint321The port component of the SCI (Secure Channel Identifier), between 1 and 65534.send-scibooleanTRUESpecifies whether the SCI (Secure Channel Identifier) is included in every packet.validationint322Specifies the validation mode for incoming frames.macvlan settingMAC VLAN Settings.Key NameValue TypeDefault ValueValue Descriptionmodeuint320The macvlan mode, which specifies the communication mechanism between multiple macvlans on the same lower device.parentstringIf given, specifies the parent interface name or parent connection UUID from which this MAC-VLAN interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property.promiscuousbooleanTRUEWhether the interface should be put in promiscuous mode.tapbooleanFALSEWhether the interface should be a MACVTAP.match settingMatch settings.Key NameValue TypeDefault ValueValue Descriptiondriverarray of stringA list of driver names to match. Each element is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.interface-namearray of stringA list of interface names to match. Each element is a shell wildcard pattern. An element can be prefixed with a pipe symbol (|) or an ampersand (&). The former means that the element is optional and the latter means that it is mandatory. If there are any optional elements, than the match evaluates to true if at least one of the optional element matches (logical OR). If there are any mandatory elements, then they all must match (logical AND). By default, an element is optional. This means that an element "foo" behaves the same as "|foo". An element can also be inverted with exclamation mark (!) between the pipe symbol (or the ampersand) and before the pattern. Note that "!foo" is a shortcut for the mandatory match "&!foo". Finally, a backslash can be used at the beginning of the element (after the optional special characters) to escape the start of the pattern. For example, "&\\!a" is an mandatory match for literally "!a".kernel-command-linearray of stringA list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or if prefixed with the exclamation mark unset). The argument must either be a single word, or an assignment (i.e. two words, separated "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.patharray of stringA list of paths to match against the ID_PATH udev property of devices. ID_PATH represents the topological persistent path of a device. It typically contains a subsystem string (pci, usb, platform, etc.) and a subsystem-specific identifier. For PCI devices the path has the form "pci-$domain:$bus:$device.$function", where each variable is an hexadecimal value; for example "pci-0000:0a:00.0". The path of a device can be obtained with "udevadm info /sys/class/net/$dev | grep ID_PATH=" or by looking at the "path" property exported by NetworkManager ("nmcli -f general.path device show $dev"). Each element of the list is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.802-11-olpc-mesh settingOLPC Wireless Mesh Settings.Key NameValue TypeDefault ValueValue Descriptionchanneluint320Channel on which the mesh network to join is located.dhcp-anycast-addressbyte arrayAnycast DHCP MAC address used when requesting an IP address via DHCP. The specific anycast address used determines which DHCP server class answers the request.ssidbyte arraySSID of the mesh network to join.ovs-bridge settingOvsBridge Link Settings.Key NameValue TypeDefault ValueValue Descriptiondatapath-typestringThe data path type. One of "system", "netdev" or empty.fail-modestringThe bridge failure mode. One of "secure", "standalone" or empty.mcast-snooping-enablebooleanFALSEEnable or disable multicast snooping.rstp-enablebooleanFALSEEnable or disable RSTP.stp-enablebooleanFALSEEnable or disable STP.ovs-dpdk settingOvsDpdk Link Settings.Key NameValue TypeDefault ValueValue DescriptiondevargsstringOpen vSwitch DPDK device arguments.ovs-interface settingOpen vSwitch Interface Settings.Key NameValue TypeDefault ValueValue DescriptiontypestringThe interface type. Either "internal", "system", "patch", "dpdk", or empty.ovs-patch settingOvsPatch Link Settings.Key NameValue TypeDefault ValueValue DescriptionpeerstringSpecifies the name of the interface for the other side of the patch. The patch on the other side must also set this interface as peer.ovs-port settingOvsPort Link Settings.Key NameValue TypeDefault ValueValue Descriptionbond-downdelayuint320The time port must be inactive in order to be considered down.bond-modestringBonding mode. One of "active-backup", "balance-slb", or "balance-tcp".bond-updelayuint320The time port must be active before it starts forwarding traffic.lacpstringLACP mode. One of "active", "off", or "passive".taguint320The VLAN tag in the range 0-4095.vlan-modestringThe VLAN mode. One of "access", "native-tagged", "native-untagged", "trunk" or unset.ppp settingPoint-to-Point Protocol Settings.Key NameValue TypeDefault ValueValue Descriptionbauduint320If non-zero, instruct pppd to set the serial port to the specified baudrate. This value should normally be left as 0 to automatically choose the speed.crtsctsbooleanFALSEIf TRUE, specify that pppd should set the serial port to use hardware flow control with RTS and CTS signals. This value should normally be set to FALSE.lcp-echo-failureuint320If non-zero, instruct pppd to presume the connection to the peer has failed if the specified number of LCP echo-requests go unanswered by the peer. The "lcp-echo-interval" property must also be set to a non-zero value if this property is used.lcp-echo-intervaluint320If non-zero, instruct pppd to send an LCP echo-request frame to the peer every n seconds (where n is the specified value). Note that some PPP peers will respond to echo requests and some will not, and it is not possible to autodetect this.mppe-statefulbooleanFALSEIf TRUE, stateful MPPE is used. See pppd documentation for more information on stateful MPPE.mruuint320If non-zero, instruct pppd to request that the peer send packets no larger than the specified size. If non-zero, the MRU should be between 128 and 16384.mtuuint320If non-zero, instruct pppd to send packets no larger than the specified size.no-vj-compbooleanFALSEIf TRUE, Van Jacobsen TCP header compression will not be requested.noauthbooleanTRUEIf TRUE, do not require the other side (usually the PPP server) to authenticate itself to the client. If FALSE, require authentication from the remote side. In almost all cases, this should be TRUE.nobsdcompbooleanFALSEIf TRUE, BSD compression will not be requested.nodeflatebooleanFALSEIf TRUE, "deflate" compression will not be requested.refuse-chapbooleanFALSEIf TRUE, the CHAP authentication method will not be used.refuse-eapbooleanFALSEIf TRUE, the EAP authentication method will not be used.refuse-mschapbooleanFALSEIf TRUE, the MSCHAP authentication method will not be used.refuse-mschapv2booleanFALSEIf TRUE, the MSCHAPv2 authentication method will not be used.refuse-papbooleanFALSEIf TRUE, the PAP authentication method will not be used.require-mppebooleanFALSEIf TRUE, MPPE (Microsoft Point-to-Point Encryption) will be required for the PPP session. If either 64-bit or 128-bit MPPE is not available the session will fail. Note that MPPE is not used on mobile broadband connections.require-mppe-128booleanFALSEIf TRUE, 128-bit MPPE (Microsoft Point-to-Point Encryption) will be required for the PPP session, and the "require-mppe" property must also be set to TRUE. If 128-bit MPPE is not available the session will fail.pppoe settingPPP-over-Ethernet Settings.Key NameValue TypeDefault ValueValue DescriptionparentstringIf given, specifies the parent interface name on which this PPPoE connection should be created. If this property is not specified, the connection is activated on the interface specified in "interface-name" of NMSettingConnection.passwordstringPassword used to authenticate with the PPPoE service.password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values)servicestringIf specified, instruct PPPoE to only initiate sessions with access concentrators that provide the specified service. For most providers, this should be left blank. It is only required if there are multiple access concentrators or a specific service is known to be required.usernamestringUsername used to authenticate with the PPPoE service.proxy settingWWW Proxy Settings.Key NameValue TypeDefault ValueValue Descriptionbrowser-onlybooleanFALSEWhether the proxy configuration is for browser only.methodint320Method for proxy configuration, Default is NM_SETTING_PROXY_METHOD_NONE (0)pac-scriptstringPAC script for the connection.pac-urlstringPAC URL for obtaining PAC file.serial settingSerial Link Settings.Key NameValue TypeDefault ValueValue Descriptionbauduint3257600Speed to use for communication over the serial port. Note that this value usually has no effect for mobile broadband modems as they generally ignore speed settings and use the highest available speed.bitsuint328Byte-width of the serial communication. The 8 in "8n1" for example.paritybyteThe connection parity: 69 (ASCII 'E') for even parity, 111 (ASCII 'o') for odd, 110 (ASCII 'n') for none.send-delayuint640Time to delay between each byte sent to the modem, in microseconds.stopbitsuint321Number of stop bits for communication on the serial port. Either 1 or 2. The 1 in "8n1" for example.sriov settingSR-IOV settings.Key NameValue TypeDefault ValueValue Descriptionautoprobe-driversNMTernary (int32)Whether to autoprobe virtual functions by a compatible driver. If set to NM_TERNARY_TRUE (1), the kernel will try to bind VFs to a compatible driver and if this succeeds a new network interface will be instantiated for each VF. If set to NM_TERNARY_FALSE (0), VFs will not be claimed and no network interfaces will be created for them. When set to NM_TERNARY_DEFAULT (-1), the global default is used; in case the global default is unspecified it is assumed to be NM_TERNARY_TRUE (1).total-vfsuint320The total number of virtual functions to create. Note that when the sriov setting is present NetworkManager enforces the number of virtual functions on the interface (also when it is zero) during activation and resets it upon deactivation. To prevent any changes to SR-IOV parameters don't add a sriov setting to the connection.vfsarray of vardictArray of virtual function descriptors. Each VF descriptor is a dictionary mapping attribute names to GVariant values. The 'index' entry is mandatory for each VF. When represented as string a VF is in the form: "INDEX [ATTR=VALUE[ ATTR=VALUE]...]". for example: "2 mac=00:11:22:33:44:55 spoof-check=true". Multiple VFs can be specified using a comma as separator. Currently, the following attributes are supported: mac, spoof-check, trust, min-tx-rate, max-tx-rate, vlans. The "vlans" attribute is represented as a semicolon-separated list of VLAN descriptors, where each descriptor has the form "ID[.PRIORITY[.PROTO]]". PROTO can be either 'q' for 802.1Q (the default) or 'ad' for 802.1ad.tc settingLinux Traffic Control Settings.Key NameValue TypeDefault ValueValue Descriptionqdiscsarray of vardictArray of TC queueing disciplines.tfiltersarray of vardictArray of TC traffic filters.team settingTeaming Settings.Key NameValue TypeDefault ValueValue DescriptionconfigstringThe JSON configuration for the team network interface. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.interface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the team's interface name.link-watchersarray of vardictLink watchers configuration for the connection: each link watcher is defined by a dictionary, whose keys depend upon the selected link watcher. Available link watchers are 'ethtool', 'nsna_ping' and 'arp_ping' and it is specified in the dictionary with the key 'name'. Available keys are: ethtool: 'delay-up', 'delay-down', 'init-wait'; nsna_ping: 'init-wait', 'interval', 'missed-max', 'target-host'; arp_ping: all the ones in nsna_ping and 'source-host', 'validate-active', 'validate-inactive', 'send-always'. See teamd.conf man for more details.mcast-rejoin-countint32-1Corresponds to the teamd mcast_rejoin.count.mcast-rejoin-intervalint32-1Corresponds to the teamd mcast_rejoin.interval.notify-peers-countint32-1Corresponds to the teamd notify_peers.count.notify-peers-intervalint32-1Corresponds to the teamd notify_peers.interval.runnerstringCorresponds to the teamd runner.name. Permitted values are: "roundrobin", "broadcast", "activebackup", "loadbalance", "lacp", "random".runner-activebooleanTRUECorresponds to the teamd runner.active.runner-agg-select-policystringCorresponds to the teamd runner.agg_select_policy.runner-fast-ratebooleanFALSECorresponds to the teamd runner.fast_rate.runner-hwaddr-policystringCorresponds to the teamd runner.hwaddr_policy.runner-min-portsint32-1Corresponds to the teamd runner.min_ports.runner-sys-prioint32-1Corresponds to the teamd runner.sys_prio.runner-tx-balancerstringCorresponds to the teamd runner.tx_balancer.name.runner-tx-balancer-intervalint32-1Corresponds to the teamd runner.tx_balancer.interval.runner-tx-hasharray of stringCorresponds to the teamd runner.tx_hash.team-port settingTeam Port Settings.Key NameValue TypeDefault ValueValue DescriptionconfigstringThe JSON configuration for the team port. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.lacp-keyint32-1Corresponds to the teamd ports.PORTIFNAME.lacp_key.lacp-prioint32-1Corresponds to the teamd ports.PORTIFNAME.lacp_prio.link-watchersarray of vardictLink watchers configuration for the connection: each link watcher is defined by a dictionary, whose keys depend upon the selected link watcher. Available link watchers are 'ethtool', 'nsna_ping' and 'arp_ping' and it is specified in the dictionary with the key 'name'. Available keys are: ethtool: 'delay-up', 'delay-down', 'init-wait'; nsna_ping: 'init-wait', 'interval', 'missed-max', 'target-host'; arp_ping: all the ones in nsna_ping and 'source-host', 'validate-active', 'validate-inactive', 'send-always'. See teamd.conf man for more details.prioint320Corresponds to the teamd ports.PORTIFNAME.prio.queue-idint32-1Corresponds to the teamd ports.PORTIFNAME.queue_id. When set to -1 means the parameter is skipped from the json config.stickybooleanFALSECorresponds to the teamd ports.PORTIFNAME.sticky.tun settingTunnel Settings.Key NameValue TypeDefault ValueValue DescriptiongroupstringThe group ID which will own the device. If set to NULL everyone will be able to use the device.modeuint321The operating mode of the virtual device. Allowed values are NM_SETTING_TUN_MODE_TUN (1) to create a layer 3 device and NM_SETTING_TUN_MODE_TAP (2) to create an Ethernet-like layer 2 one.multi-queuebooleanFALSEIf the property is set to TRUE, the interface will support multiple file descriptors (queues) to parallelize packet sending or receiving. Otherwise, the interface will only support a single queue.ownerstringThe user ID which will own the device. If set to NULL everyone will be able to use the device.pibooleanFALSEIf TRUE the interface will prepend a 4 byte header describing the physical interface to the packets.vnet-hdrbooleanFALSEIf TRUE the IFF_VNET_HDR the tunnel packets will include a virtio network header.user settingGeneral User Profile Settings.Key NameValue TypeDefault ValueValue Descriptiondatadict of string to string{}A dictionary of key/value pairs with user data. This data is ignored by NetworkManager and can be used at the users discretion. The keys only support a strict ascii format, but the values can be arbitrary UTF8 strings up to a certain length.vlan settingVLAN Settings.Key NameValue TypeDefault ValueValue Descriptionegress-priority-maparray of stringFor outgoing packets, a list of mappings from Linux SKB priorities to 802.1p priorities. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3".flagsNMVlanFlags (uint32)One or more flags which control the behavior and features of the VLAN interface. Flags include NM_VLAN_FLAG_REORDER_HEADERS (0x1) (reordering of output packet headers), NM_VLAN_FLAG_GVRP (0x2) (use of the GVRP protocol), and NM_VLAN_FLAG_LOOSE_BINDING (0x4) (loose binding of the interface to its master device's operating state). NM_VLAN_FLAG_MVRP (0x8) (use of the MVRP protocol). The default value of this property is NM_VLAN_FLAG_REORDER_HEADERS, but it used to be 0. To preserve backward compatibility, the default-value in the D-Bus API continues to be 0 and a missing property on D-Bus is still considered as 0.iduint320The VLAN identifier that the interface created by this connection should be assigned. The valid range is from 0 to 4094, without the reserved id 4095.ingress-priority-maparray of stringFor incoming packets, a list of mappings from 802.1p priorities to Linux SKB priorities. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3".interface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the vlan's interface name.parentstringIf given, specifies the parent interface name or parent connection UUID from which this VLAN interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property.vpn settingVPN Settings.Key NameValue TypeDefault ValueValue Descriptiondatadict of string to string{}Dictionary of key/value pairs of VPN plugin specific data. Both keys and values must be strings.persistentbooleanFALSEIf the VPN service supports persistence, and this property is TRUE, the VPN will attempt to stay connected across link changes and outages, until explicitly disconnected.secretsdict of string to string{}Dictionary of key/value pairs of VPN plugin specific secrets like passwords or private keys. Both keys and values must be strings.service-typestringD-Bus service name of the VPN plugin that this setting uses to connect to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc plugin.timeoutuint320Timeout for the VPN service to establish the connection. Some services may take quite a long time to connect. Value of 0 means a default timeout, which is 60 seconds (unless overridden by vpn.timeout in configuration file). Values greater than zero mean timeout in seconds.user-namestringIf the VPN connection requires a user name for authentication, that name should be provided here. If the connection is available to more than one user, and the VPN requires each user to supply a different name, then leave this property empty. If this property is empty, NetworkManager will automatically supply the username of the user which requested the VPN connection.vrf settingVRF settings.Key NameValue TypeDefault ValueValue Descriptiontableuint320The routing table for this VRF.vxlan settingVXLAN Settings.Key NameValue TypeDefault ValueValue Descriptionageinguint32300Specifies the lifetime in seconds of FDB entries learnt by the kernel.destination-portuint328472Specifies the UDP destination port to communicate to the remote VXLAN tunnel endpoint.iduint320Specifies the VXLAN Network Identifier (or VXLAN Segment Identifier) to use.l2-missbooleanFALSESpecifies whether netlink LL ADDR miss notifications are generated.l3-missbooleanFALSESpecifies whether netlink IP ADDR miss notifications are generated.learningbooleanTRUESpecifies whether unknown source link layer addresses and IP addresses are entered into the VXLAN device forwarding database.limituint320Specifies the maximum number of FDB entries. A value of zero means that the kernel will store unlimited entries.localstringIf given, specifies the source IP address to use in outgoing packets.parentstringIf given, specifies the parent interface name or parent connection UUID.proxybooleanFALSESpecifies whether ARP proxy is turned on.remotestringSpecifies the unicast destination IP address to use in outgoing packets when the destination link layer address is not known in the VXLAN device forwarding database, or the multicast IP address to join.rscbooleanFALSESpecifies whether route short circuit is turned on.source-port-maxuint320Specifies the maximum UDP source port to communicate to the remote VXLAN tunnel endpoint.source-port-minuint320Specifies the minimum UDP source port to communicate to the remote VXLAN tunnel endpoint.tosuint320Specifies the TOS value to use in outgoing packets.ttluint320Specifies the time-to-live value to use in outgoing packets.wifi-p2p settingWi-Fi P2P Settings.Key NameValue TypeDefault ValueValue DescriptionpeerstringThe P2P device that should be connected to. Currently, this is the only way to create or join a group.wfd-iesbyte arrayThe Wi-Fi Display (WFD) Information Elements (IEs) to set. Wi-Fi Display requires a protocol specific information element to be set in certain Wi-Fi frames. These can be specified here for the purpose of establishing a connection. This setting is only useful when implementing a Wi-Fi Display client.wps-methoduint320Flags indicating which mode of WPS is to be used. There's little point in changing the default setting as NetworkManager will automatically determine the best method to use.wimax settingWiMax Settings.Key NameValue TypeDefault ValueValue Descriptionmac-addressbyte arrayIf specified, this connection will only apply to the WiMAX device whose MAC address matches. This property does not change the MAC address of the device (known as MAC spoofing). Deprecated: 1network-namestringNetwork Service Provider (NSP) name of the WiMAX network this connection should use. Deprecated: 1802-3-ethernet settingWired Ethernet Settings.Key NameValue TypeDefault ValueValue Descriptionassigned-mac-addressstringThe new field for the cloned MAC address. It can be either a hardware address in ASCII representation, or one of the special values "preserve", "permanent", "random" or "stable". This field replaces the deprecated "cloned-mac-address" on D-Bus, which can only contain explicit hardware addresses. Note that this property only exists in D-Bus API. libnm and nmcli continue to call this property "cloned-mac-address".auto-negotiatebooleanFALSEWhen TRUE, enforce auto-negotiation of speed and duplex mode. If "speed" and "duplex" properties are both specified, only that single mode will be advertised and accepted during the link auto-negotiation process: this works only for BASE-T 802.3 specifications and is useful for enforcing gigabits modes, as in these cases link negotiation is mandatory. When FALSE, "speed" and "duplex" properties should be both set or link configuration will be skipped.cloned-mac-addressbyte arrayThis D-Bus field is deprecated in favor of "assigned-mac-address" which is more flexible and allows specifying special variants like "random". For libnm and nmcli, this field is called "cloned-mac-address".duplexstringWhen a value is set, either "half" or "full", configures the device to use the specified duplex mode. If "auto-negotiate" is "yes" the specified duplex mode will be the only one advertised during link negotiation: this works only for BASE-T 802.3 specifications and is useful for enforcing gigabits modes, as in these cases link negotiation is mandatory. If the value is unset (the default), the link configuration will be either skipped (if "auto-negotiate" is "no", the default) or will be auto-negotiated (if "auto-negotiate" is "yes") and the local device will advertise all the supported duplex modes. Must be set together with the "speed" property if specified. Before specifying a duplex mode be sure your device supports it.generate-mac-address-maskstringWith "cloned-mac-address" setting "random" or "stable", by default all bits of the MAC address are scrambled and a locally-administered, unicast MAC address is created. This property allows to specify that certain bits are fixed. Note that the least significant bit of the first MAC address will always be unset to create a unicast MAC address. If the property is NULL, it is eligible to be overwritten by a default connection setting. If the value is still NULL or an empty string, the default is to create a locally-administered, unicast MAC address. If the value contains one MAC address, this address is used as mask. The set bits of the mask are to be filled with the current MAC address of the device, while the unset bits are subject to randomization. Setting "FE:FF:FF:00:00:00" means to preserve the OUI of the current MAC address and only randomize the lower 3 bytes using the "random" or "stable" algorithm. If the value contains one additional MAC address after the mask, this address is used instead of the current MAC address to fill the bits that shall not be randomized. For example, a value of "FE:FF:FF:00:00:00 68:F7:28:00:00:00" will set the OUI of the MAC address to 68:F7:28, while the lower bits are randomized. A value of "02:00:00:00:00:00 00:00:00:00:00:00" will create a fully scrambled globally-administered, burned-in MAC address. If the value contains more than one additional MAC addresses, one of them is chosen randomly. For example, "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00" will create a fully scrambled MAC address, randomly locally or globally administered.mac-addressbyte arrayIf specified, this connection will only apply to the Ethernet device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).mac-address-blacklistarray of stringIf specified, this connection will never apply to the Ethernet device whose permanent MAC address matches an address in the list. Each MAC address is in the standard hex-digits-and-colons notation (00:11:22:33:44:55).mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames.portstringSpecific port type to use if the device supports multiple attachment methods. One of "tp" (Twisted Pair), "aui" (Attachment Unit Interface), "bnc" (Thin Ethernet) or "mii" (Media Independent Interface). If the device supports only one port type, this setting is ignored.s390-nettypestrings390 network device type; one of "qeth", "lcs", or "ctc", representing the different types of virtual network devices available on s390 systems.s390-optionsdict of string to string{}Dictionary of key/value pairs of s390-specific device options. Both keys and values must be strings. Allowed keys include "portno", "layer2", "portname", "protocol", among others. Key names must contain only alphanumeric characters (ie, [a-zA-Z0-9]).s390-subchannelsarray of stringIdentifies specific subchannels that this network device uses for communication with z/VM or s390 host. Like the "mac-address" property for non-z/VM devices, this property can be used to ensure this connection only applies to the network device that uses these subchannels. The list should contain exactly 3 strings, and each string may only be composed of hexadecimal characters and the period (.) character.speeduint320When a value greater than 0 is set, configures the device to use the specified speed. If "auto-negotiate" is "yes" the specified speed will be the only one advertised during link negotiation: this works only for BASE-T 802.3 specifications and is useful for enforcing gigabit speeds, as in this case link negotiation is mandatory. If the value is unset (0, the default), the link configuration will be either skipped (if "auto-negotiate" is "no", the default) or will be auto-negotiated (if "auto-negotiate" is "yes") and the local device will advertise all the supported speeds. In Mbit/s, ie 100 == 100Mbit/s. Must be set together with the "duplex" property when non-zero. Before specifying a speed value be sure your device supports it.wake-on-lanuint321The NMSettingWiredWakeOnLan options to enable. Not all devices support all options. May be any combination of NM_SETTING_WIRED_WAKE_ON_LAN_PHY (0x2), NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST (0x4), NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST (0x8), NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST (0x10), NM_SETTING_WIRED_WAKE_ON_LAN_ARP (0x20), NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC (0x40) or the special values NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT (0x1) (to use global settings) and NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE (0x8000) (to disable management of Wake-on-LAN in NetworkManager).wake-on-lan-passwordstringIf specified, the password used with magic-packet-based Wake-on-LAN, represented as an Ethernet MAC address. If NULL, no password will be required.wireguard settingWireGuard Settings.Key NameValue TypeDefault ValueValue Descriptionfwmarkuint320The use of fwmark is optional and is by default off. Setting it to 0 disables it. Otherwise, it is a 32-bit fwmark for outgoing packets. Note that "ip4-auto-default-route" or "ip6-auto-default-route" enabled, implies to automatically choose a fwmark.ip4-auto-default-routeNMTernary (int32)Whether to enable special handling of the IPv4 default route. If enabled, the IPv4 default route from wireguard.peer-routes will be placed to a dedicated routing-table and two policy routing rules will be added. The fwmark number is also used as routing-table for the default-route, and if fwmark is zero, an unused fwmark/table is chosen automatically. This corresponds to what wg-quick does with Table=auto and what WireGuard calls "Improved Rule-based Routing". Note that for this automatism to work, you usually don't want to set ipv4.gateway, because that will result in a conflicting default route. Leaving this at the default will enable this option automatically if ipv4.never-default is not set and there are any peers that use a default-route as allowed-ips.ip6-auto-default-routeNMTernary (int32)Like ip4-auto-default-route, but for the IPv6 default route.listen-portuint320The listen-port. If listen-port is not specified, the port will be chosen randomly when the interface comes up.mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments. If zero a default MTU is used. Note that contrary to wg-quick's MTU setting, this does not take into account the current routes at the time of activation.peer-routesbooleanTRUEWhether to automatically add routes for the AllowedIPs ranges of the peers. If TRUE (the default), NetworkManager will automatically add routes in the routing tables according to ipv4.route-table and ipv6.route-table. Usually you want this automatism enabled. If FALSE, no such routes are added automatically. In this case, the user may want to configure static routes in ipv4.routes and ipv6.routes, respectively. Note that if the peer's AllowedIPs is "0.0.0.0/0" or "::/0" and the profile's ipv4.never-default or ipv6.never-default setting is enabled, the peer route for this peer won't be added automatically.peersarray of 'a{sv}'Array of dictionaries for the WireGuard peers.private-keystringThe 256 bit private-key in base64 encoding.private-key-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "private-key" property. (see for flag values)802-11-wireless settingWi-Fi Settings.Key NameValue TypeDefault ValueValue Descriptionap-isolationNMTernary (int32)Configures AP isolation, which prevents communication between wireless devices connected to this AP. This property can be set to a value different from NM_TERNARY_DEFAULT (-1) only when the interface is configured in AP mode. If set to NM_TERNARY_TRUE (1), devices are not able to communicate with each other. This increases security because it protects devices against attacks from other clients in the network. At the same time, it prevents devices to access resources on the same wireless networks as file shares, printers, etc. If set to NM_TERNARY_FALSE (0), devices can talk to each other. When set to NM_TERNARY_DEFAULT (-1), the global default is used; in case the global default is unspecified it is assumed to be NM_TERNARY_FALSE (0).assigned-mac-addressstringThe new field for the cloned MAC address. It can be either a hardware address in ASCII representation, or one of the special values "preserve", "permanent", "random" or "stable". This field replaces the deprecated "cloned-mac-address" on D-Bus, which can only contain explicit hardware addresses. Note that this property only exists in D-Bus API. libnm and nmcli continue to call this property "cloned-mac-address".bandstring802.11 frequency band of the network. One of "a" for 5GHz 802.11a or "bg" for 2.4GHz 802.11. This will lock associations to the Wi-Fi network to the specific band, i.e. if "a" is specified, the device will not associate with the same network in the 2.4GHz band even if the network's settings are compatible. This setting depends on specific driver capability and may not work with all drivers.bssidbyte arrayIf specified, directs the device to only associate with the given access point. This capability is highly driver dependent and not supported by all devices. Note: this property does not control the BSSID used when creating an Ad-Hoc network and is unlikely to in the future.channeluint320Wireless channel to use for the Wi-Fi connection. The device will only join (or create for Ad-Hoc networks) a Wi-Fi network on the specified channel. Because channel numbers overlap between bands, this property also requires the "band" property to be set.cloned-mac-addressbyte arrayThis D-Bus field is deprecated in favor of "assigned-mac-address" which is more flexible and allows specifying special variants like "random". For libnm and nmcli, this field is called "cloned-mac-address".generate-mac-address-maskstringWith "cloned-mac-address" setting "random" or "stable", by default all bits of the MAC address are scrambled and a locally-administered, unicast MAC address is created. This property allows to specify that certain bits are fixed. Note that the least significant bit of the first MAC address will always be unset to create a unicast MAC address. If the property is NULL, it is eligible to be overwritten by a default connection setting. If the value is still NULL or an empty string, the default is to create a locally-administered, unicast MAC address. If the value contains one MAC address, this address is used as mask. The set bits of the mask are to be filled with the current MAC address of the device, while the unset bits are subject to randomization. Setting "FE:FF:FF:00:00:00" means to preserve the OUI of the current MAC address and only randomize the lower 3 bytes using the "random" or "stable" algorithm. If the value contains one additional MAC address after the mask, this address is used instead of the current MAC address to fill the bits that shall not be randomized. For example, a value of "FE:FF:FF:00:00:00 68:F7:28:00:00:00" will set the OUI of the MAC address to 68:F7:28, while the lower bits are randomized. A value of "02:00:00:00:00:00 00:00:00:00:00:00" will create a fully scrambled globally-administered, burned-in MAC address. If the value contains more than one additional MAC addresses, one of them is chosen randomly. For example, "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00" will create a fully scrambled MAC address, randomly locally or globally administered.hiddenbooleanFALSEIf TRUE, indicates that the network is a non-broadcasting network that hides its SSID. This works both in infrastructure and AP mode. In infrastructure mode, various workarounds are used for a more reliable discovery of hidden networks, such as probe-scanning the SSID. However, these workarounds expose inherent insecurities with hidden SSID networks, and thus hidden SSID networks should be used with caution. In AP mode, the created network does not broadcast its SSID. Note that marking the network as hidden may be a privacy issue for you (in infrastructure mode) or client stations (in AP mode), as the explicit probe-scans are distinctly recognizable on the air.mac-addressbyte arrayIf specified, this connection will only apply to the Wi-Fi device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).mac-address-blacklistarray of stringA list of permanent MAC addresses of Wi-Fi devices to which this connection should never apply. Each MAC address should be given in the standard hex-digits-and-colons notation (eg "00:11:22:33:44:55").mac-address-randomizationuint320One of NM_SETTING_MAC_RANDOMIZATION_DEFAULT (0) (never randomize unless the user has set a global default to randomize and the supplicant supports randomization), NM_SETTING_MAC_RANDOMIZATION_NEVER (1) (never randomize the MAC address), or NM_SETTING_MAC_RANDOMIZATION_ALWAYS (2) (always randomize the MAC address). This property is deprecated for 'cloned-mac-address'. Deprecated: 1modestringWi-Fi network mode; one of "infrastructure", "mesh", "adhoc" or "ap". If blank, infrastructure is assumed.mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames.powersaveuint320One of NM_SETTING_WIRELESS_POWERSAVE_DISABLE (2) (disable Wi-Fi power saving), NM_SETTING_WIRELESS_POWERSAVE_ENABLE (3) (enable Wi-Fi power saving), NM_SETTING_WIRELESS_POWERSAVE_IGNORE (1) (don't touch currently configure setting) or NM_SETTING_WIRELESS_POWERSAVE_DEFAULT (0) (use the globally configured value). All other values are reserved.rateuint320If non-zero, directs the device to only use the specified bitrate for communication with the access point. Units are in Kb/s, ie 5500 = 5.5 Mbit/s. This property is highly driver dependent and not all devices support setting a static bitrate.securityThis property is deprecated, but can be set to the value '802-11-wireless-security' when a wireless security setting is also present in the connection dictionary, for compatibility with very old NetworkManager daemons.seen-bssidsarray of stringA list of BSSIDs (each BSSID formatted as a MAC address like "00:11:22:33:44:55") that have been detected as part of the Wi-Fi network. NetworkManager internally tracks previously seen BSSIDs. The property is only meant for reading and reflects the BSSID list of NetworkManager. The changes you make to this property will not be preserved.ssidbyte arraySSID of the Wi-Fi network. Must be specified.tx-poweruint320If non-zero, directs the device to use the specified transmit power. Units are dBm. This property is highly driver dependent and not all devices support setting a static transmit power.wake-on-wlanuint321The NMSettingWirelessWakeOnWLan options to enable. Not all devices support all options. May be any combination of NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY (0x2), NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT (0x4), NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC (0x8), NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE (0x10), NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST (0x20), NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE (0x40), NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE (0x80), NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP (0x100) or the special values NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT (0x1) (to use global settings) and NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE (0x8000) (to disable management of Wake-on-LAN in NetworkManager).802-11-wireless-security settingWi-Fi Security Settings.Key NameValue TypeDefault ValueValue Descriptionauth-algstringWhen WEP is used (ie, key-mgmt = "none" or "ieee8021x") indicate the 802.11 authentication algorithm required by the AP here. One of "open" for Open System, "shared" for Shared Key, or "leap" for Cisco LEAP. When using Cisco LEAP (ie, key-mgmt = "ieee8021x" and auth-alg = "leap") the "leap-username" and "leap-password" properties must be specified.filsint320Indicates whether Fast Initial Link Setup (802.11ai) must be enabled for the connection. One of NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (0) (use global default value), NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE (1) (disable FILS), NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL (2) (enable FILS if the supplicant and the access point support it) or NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED (3) (enable FILS and fail if not supported). When set to NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (0) and no global default is set, FILS will be optionally enabled.grouparray of stringA list of group/broadcast encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of "wep40", "wep104", "tkip", or "ccmp".key-mgmtstringKey management used for the connection. One of "none" (WEP), "ieee8021x" (Dynamic WEP), "wpa-psk" (infrastructure WPA-PSK), "sae" (SAE), "owe" (Opportunistic Wireless Encryption), "wpa-eap" (WPA-Enterprise) or "wpa-eap-suite-b-192" (WPA3-Enterprise Suite B). This property must be set for any Wi-Fi connection that uses security.leap-passwordstringThe login password for legacy LEAP connections (ie, key-mgmt = "ieee8021x" and auth-alg = "leap").leap-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "leap-password" property. (see for flag values)leap-usernamestringThe login username for legacy LEAP connections (ie, key-mgmt = "ieee8021x" and auth-alg = "leap").pairwisearray of stringA list of pairwise encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of "tkip" or "ccmp".pmfint320Indicates whether Protected Management Frames (802.11w) must be enabled for the connection. One of NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT (0) (use global default value), NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE (1) (disable PMF), NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL (2) (enable PMF if the supplicant and the access point support it) or NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED (3) (enable PMF and fail if not supported). When set to NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT (0) and no global default is set, PMF will be optionally enabled.protoarray of stringList of strings specifying the allowed WPA protocol versions to use. Each element may be one "wpa" (allow WPA) or "rsn" (allow WPA2/RSN). If not specified, both WPA and RSN connections are allowed.pskstringPre-Shared-Key for WPA networks. For WPA-PSK, it's either an ASCII passphrase of 8 to 63 characters that is (as specified in the 802.11i standard) hashed to derive the actual key, or the key in form of 64 hexadecimal character. The WPA3-Personal networks use a passphrase of any length for SAE authentication.psk-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "psk" property. (see for flag values)wep-key-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "wep-key0", "wep-key1", "wep-key2", and "wep-key3" properties. (see for flag values)wep-key-typeNMWepKeyType (uint32)Controls the interpretation of WEP keys. Allowed values are NM_WEP_KEY_TYPE_KEY (1), in which case the key is either a 10- or 26-character hexadecimal string, or a 5- or 13-character ASCII password; or NM_WEP_KEY_TYPE_PASSPHRASE (2), in which case the passphrase is provided as a string and will be hashed using the de-facto MD5 method to derive the actual WEP key.wep-key0stringIndex 0 WEP key. This is the WEP key used in most networks. See the "wep-key-type" property for a description of how this key is interpreted.wep-key1stringIndex 1 WEP key. This WEP index is not used by most networks. See the "wep-key-type" property for a description of how this key is interpreted.wep-key2stringIndex 2 WEP key. This WEP index is not used by most networks. See the "wep-key-type" property for a description of how this key is interpreted.wep-key3stringIndex 3 WEP key. This WEP index is not used by most networks. See the "wep-key-type" property for a description of how this key is interpreted.wep-tx-keyidxuint320When static WEP is used (ie, key-mgmt = "none") and a non-default WEP key index is used by the AP, put that WEP key index here. Valid values are 0 (default key) through 3. Note that some consumer access points (like the Linksys WRT54G) number the keys 1 - 4.wps-methoduint320Flags indicating which mode of WPS is to be used if any. There's little point in changing the default setting as NetworkManager will automatically determine whether it's feasible to start WPS enrollment from the Access Point capabilities. WPS can be disabled by setting this property to a value of 1.wpan settingIEEE 802.15.4 (WPAN) MAC Settings.Key NameValue TypeDefault ValueValue Descriptionchannelint32-1IEEE 802.15.4 channel. A positive integer or -1, meaning "do not set, use whatever the device is already set to".mac-addressstringIf specified, this connection will only apply to the IEEE 802.15.4 (WPAN) MAC layer device whose permanent MAC address matches.pageint32-1IEEE 802.15.4 channel page. A positive integer or -1, meaning "do not set, use whatever the device is already set to".pan-iduint3265535IEEE 802.15.4 Personal Area Network (PAN) identifier.short-addressuint3265535Short IEEE 802.15.4 address to be used within a restricted environment.hostname settingHostname settings.Key NameValue TypeDefault ValueValue Descriptionfrom-dhcpNMTernary (int32)Whether the system hostname can be determined from DHCP on this connection. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).from-dns-lookupNMTernary (int32)Whether the system hostname can be determined from reverse DNS lookup of addresses on this device. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).only-from-defaultNMTernary (int32)If set to NM_TERNARY_TRUE (1), NetworkManager attempts to get the hostname via DHCPv4/DHCPv6 or reverse DNS lookup on this device only when the device has the default route for the given address family (IPv4/IPv6). If set to NM_TERNARY_FALSE (0), the hostname can be set from this device even if it doesn't have the default route. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_FALSE (0).priorityint320The relative priority of this connection to determine the system hostname. A lower numerical value is better (higher priority). A connection with higher priority is considered before connections with lower priority. If the value is zero, it can be overridden by a global value from NetworkManager configuration. If the property doesn't have a value in the global configuration, the value is assumed to be 100. Negative values have the special effect of excluding other connections with a greater numerical priority value; so in presence of at least one negative priority, only connections with the lowest priority value will be used to determine the hostname.ovs-external-ids settingOVS External IDs Settings.Key NameValue TypeDefault ValueValue Descriptiondatadict of string to string{}A dictionary of key/value pairs with exernal-ids for OVS.veth settingVeth Settings.Key NameValue TypeDefault ValueValue DescriptionpeerstringThis property specifies the peer interface name of the veth. This property is mandatory.Secret flag types: + connection settingGeneral Connection Profile Settings.Key NameValue TypeDefault ValueValue Descriptionauth-retriesint32-1The number of retries for the authentication. Zero means to try indefinitely; -1 means to use a global default. If the global default is not set, the authentication retries for 3 times before failing the connection. Currently, this only applies to 802-1x authentication.autoconnectbooleanTRUEWhether or not the connection should be automatically connected by NetworkManager when the resources for the connection are available. TRUE to automatically activate the connection, FALSE to require manual intervention to activate the connection. Note that autoconnect is not implemented for VPN profiles. See "secondaries" as an alternative to automatically connect VPN profiles.autoconnect-priorityint320The autoconnect priority. If the connection is set to autoconnect, connections with higher priority will be preferred. Defaults to 0. The higher number means higher priority.autoconnect-retriesint32-1The number of times a connection should be tried when autoactivating before giving up. Zero means forever, -1 means the global default (4 times if not overridden). Setting this to 1 means to try activation only once before blocking autoconnect. Note that after a timeout, NetworkManager will try to autoconnect again.autoconnect-slavesNMSettingConnectionAutoconnectSlaves (int32)Whether or not slaves of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for master connections. The properties "autoconnect", "autoconnect-priority" and "autoconnect-retries" are unrelated to this setting. The permitted values are: 0: leave slave connections untouched, 1: activate all the slave connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-slaves is read to determine the real value. If it is default as well, this fallbacks to 0.gateway-ping-timeoutuint320If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping.idstringA human readable unique identifier for the connection, like "Work Wi-Fi" or "T-Mobile 3G".interface-namestringThe name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface.lldpint32-1Whether LLDP is enabled for the connection.llmnrint32-1Whether Link-Local Multicast Name Resolution (LLMNR) is enabled for the connection. LLMNR is a protocol based on the Domain Name System (DNS) packet format that allows both IPv4 and IPv6 hosts to perform name resolution for hosts on the same local link. The permitted values are: "yes" (2) register hostname and resolving for the connection, "no" (0) disable LLMNR for the interface, "resolve" (1) do not register hostname but allow resolving of LLMNR host names If unspecified, "default" ultimately depends on the DNS plugin (which for systemd-resolved currently means "yes"). This feature requires a plugin which supports LLMNR. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved.masterstringInterface name of the master device or UUID of the master connection.mdnsint32-1Whether mDNS is enabled for the connection. The permitted values are: "yes" (2) register hostname and resolving for the connection, "no" (0) disable mDNS for the interface, "resolve" (1) do not register hostname but allow resolving of mDNS host names and "default" (-1) to allow lookup of a global default in NetworkManager.conf. If unspecified, "default" ultimately depends on the DNS plugin (which for systemd-resolved currently means "no"). This feature requires a plugin which supports mDNS. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved.meteredNMMetered (int32)Whether the connection is metered. When updating this property on a currently activated connection, the change takes effect immediately.mud-urlstringIf configured, set to a Manufacturer Usage Description (MUD) URL that points to manufacturer-recommended network policies for IoT devices. It is transmitted as a DHCPv4 or DHCPv6 option. The value must be a valid URL starting with "https://". The special value "none" is allowed to indicate that no MUD URL is used. If the per-profile value is unspecified (the default), a global connection default gets consulted. If still unspecified, the ultimate default is "none".multi-connectint320Specifies whether the profile can be active multiple times at a particular moment. The value is of type NMConnectionMultiConnect.permissionsarray of stringAn array of strings defining what access a given user has to this connection. If this is NULL or empty, all users are allowed to access this connection; otherwise users are allowed if and only if they are in this list. When this is not empty, the connection can be active only when one of the specified users is logged into an active session. Each entry is of the form "[type]:[id]:[reserved]"; for example, "user:dcbw:blah". At this time only the "user" [type] is allowed. Any other values are ignored and reserved for future use. [id] is the username that this permission refers to, which may not contain the ":" character. Any [reserved] information present must be ignored and is reserved for future use. All of [type], [id], and [reserved] must be valid UTF-8.read-onlybooleanFALSEFALSE if the connection can be modified using the provided settings service's D-Bus interface with the right privileges, or TRUE if the connection is read-only and cannot be modified.secondariesarray of stringList of connection UUIDs that should be activated when the base connection itself is activated. Currently, only VPN connections are supported.slave-typestringSetting name of the device type of this slave's master connection (eg, "bond"), or NULL if this connection is not a slave.stable-idstringThis represents the identity of the connection used for various purposes. It allows to configure multiple profiles to share the identity. Also, the stable-id can contain placeholders that are substituted dynamically and deterministically depending on the context. The stable-id is used for generating IPv6 stable private addresses with ipv6.addr-gen-mode=stable-privacy. It is also used to seed the generated cloned MAC address for ethernet.cloned-mac-address=stable and wifi.cloned-mac-address=stable. It is also used as DHCP client identifier with ipv4.dhcp-client-id=stable and to derive the DHCP DUID with ipv6.dhcp-duid=stable-[llt,ll,uuid]. Note that depending on the context where it is used, other parameters are also seeded into the generation algorithm. For example, a per-host key is commonly also included, so that different systems end up generating different IDs. Or with ipv6.addr-gen-mode=stable-privacy, also the device's name is included, so that different interfaces yield different addresses. The per-host key is the identity of your machine and stored in /var/lib/NetworkManager/secret-key. The '$' character is treated special to perform dynamic substitutions at runtime. Currently, supported are "${CONNECTION}", "${DEVICE}", "${MAC}", "${BOOT}", "${RANDOM}". These effectively create unique IDs per-connection, per-device, per-boot, or every time. Note that "${DEVICE}" corresponds to the interface name of the device and "${MAC}" is the permanent MAC address of the device. Any unrecognized patterns following '$' are treated verbatim, however are reserved for future use. You are thus advised to avoid '$' or escape it as "$$". For example, set it to "${CONNECTION}-${BOOT}-${DEVICE}" to create a unique id for this connection that changes with every reboot and differs depending on the interface where the profile activates. If the value is unset, a global connection default is consulted. If the value is still unset, the default is similar to "${CONNECTION}" and uses a unique, fixed ID for the connection.timestampuint640The time, in seconds since the Unix Epoch, that the connection was last _successfully_ fully activated. NetworkManager updates the connection timestamp periodically when the connection is active to ensure that an active connection has the latest timestamp. The property is only meant for reading (changes to this property will not be preserved).typestringBase type of the connection. For hardware-dependent connections, should contain the setting name of the hardware-type specific setting (ie, "802-3-ethernet" or "802-11-wireless" or "bluetooth", etc), and for non-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, "vpn" or "bridge", etc).uuidstringA universally unique identifier for the connection, for example generated with libuuid. It should be assigned when the connection is created, and never changed as long as the connection still applies to the same network. For example, it should not be changed when the "id" property or NMSettingIP4Config changes, but might need to be re-created when the Wi-Fi SSID, mobile broadband network provider, or "type" property changes. The UUID must be in the format "2815492f-7e56-435e-b2e9-246bd7cdc664" (ie, contains only hexadecimal characters and "-").wait-device-timeoutint32-1Timeout in milliseconds to wait for device at startup. During boot, devices may take a while to be detected by the driver. This property will cause to delay NetworkManager-wait-online.service and nm-online to give the device a chance to appear. This works by waiting for the given timeout until a compatible device for the profile is available and managed. The value 0 means no wait time. The default value is -1, which currently has the same meaning as no wait time.zonestringThe trust level of a the connection. Free form case-insensitive string (for example "Home", "Work", "Public"). NULL or unspecified zone means the connection will be placed in the default zone as defined by the firewall. When updating this property on a currently activated connection, the change takes effect immediately.6lowpan setting6LoWPAN Settings.Key NameValue TypeDefault ValueValue DescriptionparentstringIf given, specifies the parent interface name or parent connection UUID from which this 6LowPAN interface should be created.802-1x settingIEEE 802.1x Authentication Settings.Key NameValue TypeDefault ValueValue Descriptionaltsubject-matchesarray of stringList of strings to be matched against the altSubjectName of the certificate presented by the authentication server. If the list is empty, no verification of the server certificate's altSubjectName is performed.anonymous-identitystringAnonymous identity string for EAP authentication methods. Used as the unencrypted identity with EAP types that support different tunneled identity like EAP-TTLS.auth-timeoutint320A timeout for the authentication. Zero means the global default; if the global default is not set, the authentication timeout is 25 seconds.ca-certbyte arrayContains the CA certificate if used by the EAP method specified in the "eap" property. Certificate data is specified using a "scheme"; three are currently supported: blob, path and pkcs#11 URL. When using the blob scheme this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended. Note that enabling NMSetting8021x:system-ca-certs will override this setting to use the built-in path, if the built-in path is not a directory.ca-cert-passwordstringThe password used to access the CA certificate stored in "ca-cert" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.ca-cert-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "ca-cert-password" property. (see for flag values)ca-pathstringUTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "ca-cert" property. If NMSetting8021x:system-ca-certs is enabled and the built-in CA path is an existing directory, then this setting is ignored.client-certbyte arrayContains the client certificate if used by the EAP method specified in the "eap" property. Certificate data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte.client-cert-passwordstringThe password used to access the client certificate stored in "client-cert" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.client-cert-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "client-cert-password" property. (see for flag values)domain-matchstringConstraint for server domain name. If set, this list of FQDNs is used as a match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using the same comparison. Multiple valid FQDNs can be passed as a ";" delimited list.domain-suffix-matchstringConstraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison. Since version 1.24, multiple valid FQDNs can be passed as a ";" delimited list.eaparray of stringThe allowed EAP method to be used when authenticating to the network with 802.1x. Valid methods are: "leap", "md5", "tls", "peap", "ttls", "pwd", and "fast". Each method requires different configuration using the properties of this setting; refer to wpa_supplicant documentation for the allowed combinations.identitystringIdentity string for EAP authentication methods. Often the user's user or login name.optionalbooleanFALSEWhether the 802.1X authentication is optional. If TRUE, the activation will continue even after a timeout or an authentication failure. Setting the property to TRUE is currently allowed only for Ethernet connections. If set to FALSE, the activation can continue only after a successful authentication.pac-filestringUTF-8 encoded file path containing PAC for EAP-FAST.passwordstringUTF-8 encoded password used for EAP authentication methods. If both the "password" property and the "password-raw" property are specified, "password" is preferred.password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values)password-rawbyte arrayPassword used for EAP authentication methods, given as a byte array to allow passwords in other encodings than UTF-8 to be used. If both the "password" property and the "password-raw" property are specified, "password" is preferred.password-raw-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password-raw" property. (see for flag values)phase1-auth-flagsuint320Specifies authentication flags to use in "phase 1" outer authentication using NMSetting8021xAuthFlags options. The individual TLS versions can be explicitly disabled. If a certain TLS disable flag is not set, it is up to the supplicant to allow or forbid it. The TLS options map to tls_disable_tlsv1_x settings. See the wpa_supplicant documentation for more details.phase1-fast-provisioningstringEnables or disables in-line provisioning of EAP-FAST credentials when FAST is specified as the EAP method in the "eap" property. Recognized values are "0" (disabled), "1" (allow unauthenticated provisioning), "2" (allow authenticated provisioning), and "3" (allow both authenticated and unauthenticated provisioning). See the wpa_supplicant documentation for more details.phase1-peaplabelstringForces use of the new PEAP label during key derivation. Some RADIUS servers may require forcing the new PEAP label to interoperate with PEAPv1. Set to "1" to force use of the new PEAP label. See the wpa_supplicant documentation for more details.phase1-peapverstringForces which PEAP version is used when PEAP is set as the EAP method in the "eap" property. When unset, the version reported by the server will be used. Sometimes when using older RADIUS servers, it is necessary to force the client to use a particular PEAP version. To do so, this property may be set to "0" or "1" to force that specific PEAP version.phase2-altsubject-matchesarray of stringList of strings to be matched against the altSubjectName of the certificate presented by the authentication server during the inner "phase 2" authentication. If the list is empty, no verification of the server certificate's altSubjectName is performed.phase2-authstringSpecifies the allowed "phase 2" inner authentication method when an EAP method that uses an inner TLS tunnel is specified in the "eap" property. For TTLS this property selects one of the supported non-EAP inner methods: "pap", "chap", "mschap", "mschapv2" while "phase2-autheap" selects an EAP inner method. For PEAP this selects an inner EAP method, one of: "gtc", "otp", "md5" and "tls". Each "phase 2" inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details. Both "phase2-auth" and "phase2-autheap" cannot be specified.phase2-autheapstringSpecifies the allowed "phase 2" inner EAP-based authentication method when TTLS is specified in the "eap" property. Recognized EAP-based "phase 2" methods are "md5", "mschapv2", "otp", "gtc", and "tls". Each "phase 2" inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details.phase2-ca-certbyte arrayContains the "phase 2" CA certificate if used by the EAP method specified in the "phase2-auth" or "phase2-autheap" properties. Certificate data is specified using a "scheme"; three are currently supported: blob, path and pkcs#11 URL. When using the blob scheme this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended. Note that enabling NMSetting8021x:system-ca-certs will override this setting to use the built-in path, if the built-in path is not a directory.phase2-ca-cert-passwordstringThe password used to access the "phase2" CA certificate stored in "phase2-ca-cert" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.phase2-ca-cert-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "phase2-ca-cert-password" property. (see for flag values)phase2-ca-pathstringUTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "phase2-ca-cert" property. If NMSetting8021x:system-ca-certs is enabled and the built-in CA path is an existing directory, then this setting is ignored.phase2-client-certbyte arrayContains the "phase 2" client certificate if used by the EAP method specified in the "phase2-auth" or "phase2-autheap" properties. Certificate data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended.phase2-client-cert-passwordstringThe password used to access the "phase2" client certificate stored in "phase2-client-cert" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.phase2-client-cert-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "phase2-client-cert-password" property. (see for flag values)phase2-domain-matchstringConstraint for server domain name. If set, this list of FQDNs is used as a match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner "phase 2" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using the same comparison. Multiple valid FQDNs can be passed as a ";" delimited list.phase2-domain-suffix-matchstringConstraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner "phase 2" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison. Since version 1.24, multiple valid FQDNs can be passed as a ";" delimited list.phase2-private-keybyte arrayContains the "phase 2" inner private key when the "phase2-auth" or "phase2-autheap" property is set to "tls". Key data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the "phase2-private-key-password" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte, and as with the blob scheme the "phase2-private-key-password" property must be set to the password used to decode the PKCS#12 private key and certificate.phase2-private-key-passwordstringThe password used to decrypt the "phase 2" private key specified in the "phase2-private-key" property when the private key either uses the path scheme, or is a PKCS#12 format key.phase2-private-key-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "phase2-private-key-password" property. (see for flag values)phase2-subject-matchstringSubstring to be matched against the subject of the certificate presented by the authentication server during the inner "phase 2" authentication. When unset, no verification of the authentication server certificate's subject is performed. This property provides little security, if any, and its use is deprecated in favor of NMSetting8021x:phase2-domain-suffix-match.pinstringPIN used for EAP authentication methods.pin-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "pin" property. (see for flag values)private-keybyte arrayContains the private key when the "eap" property is set to "tls". Key data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the "private-key-password" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte, and as with the blob scheme the "private-key-password" property must be set to the password used to decode the PKCS#12 private key and certificate. WARNING: "private-key" is not a "secret" property, and thus unencrypted private key data using the BLOB scheme may be readable by unprivileged users. Private keys should always be encrypted with a private key password to prevent unauthorized access to unencrypted private key data.private-key-passwordstringThe password used to decrypt the private key specified in the "private-key" property when the private key either uses the path scheme, or if the private key is a PKCS#12 format key.private-key-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "private-key-password" property. (see for flag values)subject-matchstringSubstring to be matched against the subject of the certificate presented by the authentication server. When unset, no verification of the authentication server certificate's subject is performed. This property provides little security, if any, and its use is deprecated in favor of NMSetting8021x:domain-suffix-match.system-ca-certsbooleanFALSEWhen TRUE, overrides the "ca-path" and "phase2-ca-path" properties using the system CA directory specified at configure time with the --system-ca-path switch. The certificates in this directory are added to the verification chain in addition to any certificates specified by the "ca-cert" and "phase2-ca-cert" properties. If the path provided with --system-ca-path is rather a file name (bundle of trusted CA certificates), it overrides "ca-cert" and "phase2-ca-cert" properties instead (sets ca_cert/ca_cert2 options for wpa_supplicant).adsl settingADSL Settings.Key NameValue TypeDefault ValueValue DescriptionencapsulationstringEncapsulation of ADSL connection. Can be "vcmux" or "llc".passwordstringPassword used to authenticate with the ADSL service.password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values)protocolstringADSL connection protocol. Can be "pppoa", "pppoe" or "ipoatm".usernamestringUsername used to authenticate with the ADSL service.vciuint320VCI of ADSL connectionvpiuint320VPI of ADSL connectionbluetooth settingBluetooth Settings.Key NameValue TypeDefault ValueValue Descriptionbdaddrbyte arrayThe Bluetooth address of the device.typestringEither "dun" for Dial-Up Networking connections or "panu" for Personal Area Networking connections to devices supporting the NAP profile.bond settingBonding Settings.Key NameValue TypeDefault ValueValue Descriptioninterface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the bond's interface name.optionsdict of string to string{'mode': 'balance-rr'}Dictionary of key/value pairs of bonding options. Both keys and values must be strings. Option names must contain only alphanumeric characters (ie, [a-zA-Z0-9]).bridge settingBridging Settings.Key NameValue TypeDefault ValueValue Descriptionageing-timeuint32300The Ethernet MAC address aging time, in seconds.forward-delayuint3215The Spanning Tree Protocol (STP) forwarding delay, in seconds.group-addressbyte arrayIf specified, The MAC address of the multicast group this bridge uses for STP. The address must be a link-local address in standard Ethernet MAC address format, ie an address of the form 01:80:C2:00:00:0X, with X in [0, 4..F]. If not specified the default value is 01:80:C2:00:00:00.group-forward-maskuint320A mask of group addresses to forward. Usually, group addresses in the range from 01:80:C2:00:00:00 to 01:80:C2:00:00:0F are not forwarded according to standards. This property is a mask of 16 bits, each corresponding to a group address in that range that must be forwarded. The mask can't have bits 0, 1 or 2 set because they are used for STP, MAC pause frames and LACP.hello-timeuint322The Spanning Tree Protocol (STP) hello time, in seconds.interface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the bridge's interface name.mac-addressbyte arrayIf specified, the MAC address of bridge. When creating a new bridge, this MAC address will be set. If this field is left unspecified, the "ethernet.cloned-mac-address" is referred instead to generate the initial MAC address. Note that setting "ethernet.cloned-mac-address" anyway overwrites the MAC address of the bridge later while activating the bridge. Hence, this property is deprecated. Deprecated: 1max-ageuint3220The Spanning Tree Protocol (STP) maximum message age, in seconds.multicast-hash-maxuint324096Set maximum size of multicast hash table (value must be a power of 2).multicast-last-member-countuint322Set the number of queries the bridge will send before stopping forwarding a multicast group after a "leave" message has been received.multicast-last-member-intervaluint64100Set interval (in deciseconds) between queries to find remaining members of a group, after a "leave" message is received.multicast-membership-intervaluint6426000Set delay (in deciseconds) after which the bridge will leave a group, if no membership reports for this group are received.multicast-querierbooleanFALSEEnable or disable sending of multicast queries by the bridge. If not specified the option is disabled.multicast-querier-intervaluint6425500If no queries are seen after this delay (in deciseconds) has passed, the bridge will start to send its own queries.multicast-query-intervaluint6412500Interval (in deciseconds) between queries sent by the bridge after the end of the startup phase.multicast-query-response-intervaluint641000Set the Max Response Time/Max Response Delay (in deciseconds) for IGMP/MLD queries sent by the bridge.multicast-query-use-ifaddrbooleanFALSEIf enabled the bridge's own IP address is used as the source address for IGMP queries otherwise the default of 0.0.0.0 is used.multicast-routerstringSets bridge's multicast router. Multicast-snooping must be enabled for this option to work. Supported values are: 'auto', 'disabled', 'enabled' to which kernel assigns the numbers 1, 0, and 2, respectively. If not specified the default value is 'auto' (1).multicast-snoopingbooleanTRUEControls whether IGMP snooping is enabled for this bridge. Note that if snooping was automatically disabled due to hash collisions, the system may refuse to enable the feature until the collisions are resolved.multicast-startup-query-countuint322Set the number of IGMP queries to send during startup phase.multicast-startup-query-intervaluint643125Sets the time (in deciseconds) between queries sent out at startup to determine membership information.priorityuint3232768Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower values are "better"; the lowest priority bridge will be elected the root bridge.stpbooleanTRUEControls whether Spanning Tree Protocol (STP) is enabled for this bridge.vlan-default-pviduint321The default PVID for the ports of the bridge, that is the VLAN id assigned to incoming untagged frames.vlan-filteringbooleanFALSEControl whether VLAN filtering is enabled on the bridge.vlan-protocolstringIf specified, the protocol used for VLAN filtering. Supported values are: '802.1Q', '802.1ad'. If not specified the default value is '802.1Q'.vlan-stats-enabledbooleanFALSEControls whether per-VLAN stats accounting is enabled.vlansarray of vardictArray of bridge VLAN objects. In addition to the VLANs specified here, the bridge will also have the default-pvid VLAN configured by the bridge.vlan-default-pvid property. In nmcli the VLAN list can be specified with the following syntax: $vid [pvid] [untagged] [, $vid [pvid] [untagged]]... where $vid is either a single id between 1 and 4094 or a range, represented as a couple of ids separated by a dash.bridge-port settingBridge Port Settings.Key NameValue TypeDefault ValueValue Descriptionhairpin-modebooleanFALSEEnables or disables "hairpin mode" for the port, which allows frames to be sent back out through the port the frame was received on.path-costuint32100The Spanning Tree Protocol (STP) port cost for destinations via this port.priorityuint3232The Spanning Tree Protocol (STP) priority of this bridge port.vlansarray of vardictArray of bridge VLAN objects. In addition to the VLANs specified here, the port will also have the default-pvid VLAN configured on the bridge by the bridge.vlan-default-pvid property. In nmcli the VLAN list can be specified with the following syntax: $vid [pvid] [untagged] [, $vid [pvid] [untagged]]... where $vid is either a single id between 1 and 4094 or a range, represented as a couple of ids separated by a dash.cdma settingCDMA-based Mobile Broadband Settings.Key NameValue TypeDefault ValueValue Descriptionmtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.numberstringThe number to dial to establish the connection to the CDMA-based mobile broadband network, if any. If not specified, the default number (#777) is used when required.passwordstringThe password used to authenticate with the network, if required. Many providers do not require a password, or accept any password. But if a password is required, it is specified here.password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values)usernamestringThe username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.dcb settingData Center Bridging Settings.Key NameValue TypeDefault ValueValue Descriptionapp-fcoe-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for the DCB FCoE application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).app-fcoe-modestring"fabric"The FCoE controller mode; either "fabric" (default) or "vn2vn".app-fcoe-priorityint32-1The highest User Priority (0 - 7) which FCoE frames should use, or -1 for default priority. Only used when the "app-fcoe-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag.app-fip-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for the DCB FIP application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).app-fip-priorityint32-1The highest User Priority (0 - 7) which FIP frames should use, or -1 for default priority. Only used when the "app-fip-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag.app-iscsi-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for the DCB iSCSI application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).app-iscsi-priorityint32-1The highest User Priority (0 - 7) which iSCSI frames should use, or -1 for default priority. Only used when the "app-iscsi-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag.priority-bandwidtharray of uint32An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the percentage of bandwidth of the priority's assigned group that the priority may use. The sum of all percentages for priorities which belong to the same group must total 100 percents.priority-flow-controlarray of uint32An array of 8 boolean values, where the array index corresponds to the User Priority (0 - 7) and the value indicates whether or not the corresponding priority should transmit priority pause.priority-flow-control-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for DCB Priority Flow Control (PFC). Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).priority-group-bandwidtharray of uint32An array of 8 uint values, where the array index corresponds to the Priority Group ID (0 - 7) and the value indicates the percentage of link bandwidth allocated to that group. Allowed values are 0 - 100, and the sum of all values must total 100 percents.priority-group-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for DCB Priority Groups. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).priority-group-idarray of uint32An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the Priority Group ID. Allowed Priority Group ID values are 0 - 7 or 15 for the unrestricted group.priority-strict-bandwidtharray of uint32An array of 8 boolean values, where the array index corresponds to the User Priority (0 - 7) and the value indicates whether or not the priority may use all of the bandwidth allocated to its assigned group.priority-traffic-classarray of uint32An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the traffic class (0 - 7) to which the priority is mapped.dummy settingDummy Link Settings.Key NameValue TypeDefault ValueValue Descriptionethtool settingEthtool Ethernet Settings.Key NameValue TypeDefault ValueValue Descriptiongeneric settingGeneric Link Settings.Key NameValue TypeDefault ValueValue Descriptiongsm settingGSM-based Mobile Broadband Settings.Key NameValue TypeDefault ValueValue DescriptionapnstringThe GPRS Access Point Name specifying the APN used when establishing a data session with the GSM-based network. The APN often determines how the user will be billed for their network usage and whether the user has access to the Internet or just a provider-specific walled-garden, so it is important to use the correct APN for the user's mobile broadband plan. The APN may only be composed of the characters a-z, 0-9, ., and - per GSM 03.60 Section 14.9.auto-configbooleanFALSEWhen TRUE, the settings such as APN, username, or password will default to values that match the network the modem will register to in the Mobile Broadband Provider database.device-idstringThe device unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will only apply to the specified device.home-onlybooleanFALSEWhen TRUE, only connections to the home network will be allowed. Connections to roaming networks will not be made.mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.network-idstringThe Network ID (GSM LAI format, ie MCC-MNC) to force specific network registration. If the Network ID is specified, NetworkManager will attempt to force the device to register only on the specified network. This can be used to ensure that the device does not roam when direct roaming control of the device is not otherwise possible.numberstringLegacy setting that used to help establishing PPP data sessions for GSM-based modems. Deprecated: 1passwordstringThe password used to authenticate with the network, if required. Many providers do not require a password, or accept any password. But if a password is required, it is specified here.password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values)pinstringIf the SIM is locked with a PIN it must be unlocked before any other operations are requested. Specify the PIN here to allow operation of the device.pin-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "pin" property. (see for flag values)sim-idstringThe SIM card unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will apply to any device also allowed by "device-id" which contains a SIM card matching the given identifier.sim-operator-idstringA MCC/MNC string like "310260" or "21601" identifying the specific mobile network operator which this connection applies to. If given, the connection will apply to any device also allowed by "device-id" and "sim-id" which contains a SIM card provisioned by the given operator.usernamestringThe username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.infiniband settingInfiniband Settings.Key NameValue TypeDefault ValueValue Descriptionmac-addressbyte arrayIf specified, this connection will only apply to the IPoIB device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.p-keyint32-1The InfiniBand P_Key to use for this device. A value of -1 means to use the default P_Key (aka "the P_Key at index 0"). Otherwise, it is a 16-bit unsigned integer, whose high bit is set if it is a "full membership" P_Key.parentstringThe interface name of the parent device of this device. Normally NULL, but if the "p_key" property is set, then you must specify the base device by setting either this property or "mac-address".transport-modestringThe IP-over-InfiniBand transport mode. Either "datagram" or "connected".ipv4 settingIPv4 Settings.Key NameValue TypeDefault ValueValue Descriptionaddress-dataarray of vardictArray of IPv4 addresses. Each address dictionary contains at least 'address' and 'prefix' entries, containing the IP address as a string, and the prefix length as a uint32. Additional attributes may also exist on some addresses.addressesarray of array of uint32Deprecated in favor of the 'address-data' and 'gateway' properties, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'address-data' and 'gateway'. Array of IPv4 address structures. Each IPv4 address structure is composed of 3 32-bit values; the first being the IPv4 address (network byte order), the second the prefix (1 - 32), and last the IPv4 gateway (network byte order). The gateway may be left as 0 if no gateway exists for that subnet.dad-timeoutint32-1Timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4.dhcp-client-idstringA string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values "mac" and "perm-mac" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value "ipv6-duid" uses the DUID from "ipv6.dhcp-duid" property as an RFC4361-compliant client identifier. As IAID it uses "ipv4.dhcp-iaid" and falls back to "ipv6.dhcp-iaid" if unset. The special value "duid" generates a RFC4361-compliant client identifier based on "ipv4.dhcp-iaid" and uses a DUID generated by hashing /etc/machine-id. The special value "stable" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the "${DEVICE}" or "${MAC}" specifier to get a per-device key. If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin.dhcp-fqdnstringIf the "dhcp-send-hostname" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and "dhcp-hostname" are mutually exclusive and cannot be set at the same time.dhcp-hostnamestringIf the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time.dhcp-hostname-flagsuint320Flags for the DHCP hostname and FQDN. Currently, this property only includes flags to control the FQDN flags set in the DHCP FQDN option. Supported FQDN flags are NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) and NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE (0x4). When no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is set, the DHCP FQDN option will contain no flag. Otherwise, if no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is not set, the standard FQDN flags are set in the request: NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) for IPv4 and NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1) for IPv6. When this property is set to the default value NM_DHCP_HOSTNAME_FLAG_NONE (0x0), a global default is looked up in NetworkManager configuration. If that value is unset or also NM_DHCP_HOSTNAME_FLAG_NONE (0x0), then the standard FQDN flags described above are sent in the DHCP requests.dhcp-iaidstringA string containing the "Identity Association Identifier" (IAID) used by the DHCP client. The property is a 32-bit decimal value or a special value among "mac", "perm-mac", "ifname" and "stable". When set to "mac" (or "perm-mac"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to "ifname", the IAID is computed by hashing the interface name. The special value "stable" can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be "ifname". Note that at the moment this property is ignored for IPv6 by dhclient, which always derives the IAID from the MAC address.dhcp-reject-serversarray of stringArray of servers from which DHCP offers must be rejected. This property is useful to avoid getting a lease from misconfigured or rogue servers. For DHCPv4, each element must be an IPv4 address, optionally followed by a slash and a prefix length (e.g. "192.168.122.0/24"). This property is currently not implemented for DHCPv6.dhcp-send-hostnamebooleanTRUEIf TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.dhcp-timeoutint320A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.dhcp-vendor-class-identifierstringThe Vendor Class Identifier DHCP option (60). Special characters in the data string may be escaped using C-style escapes, nevertheless this property cannot contain nul bytes. If the per-profile value is unspecified (the default), a global connection default gets consulted. If still unspecified, the DHCP option is not sent to the server. Since 1.28dnsarray of uint32Array of IP addresses of DNS servers (as network-byte-order integers)dns-optionsarray of stringArray of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are "attempts", "debug", "edns0", "inet6", "ip6-bytestring", "ip6-dotint", "ndots", "no-check-names", "no-ip6-dotint", "no-reload", "no-tld-query", "rotate", "single-request", "single-request-reopen", "timeout", "trust-ad", "use-vc". The "trust-ad" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have "trust-ad" enabled. When using a caching DNS plugin (dnsmasq or systemd-resolved in NetworkManager.conf) then "edns0" and "trust-ad" are automatically added.dns-priorityint320DNS servers priority. The relative priority for DNS servers specified by this setting. A lower numerical value is better (higher priority). Negative values have the special effect of excluding other configurations with a greater numerical priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. To avoid all DNS leaks, set the priority of the profile that should be used to the most negative value of all active connections profiles. Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. Note that commonly the resolver tries name servers in /etc/resolv.conf in the order listed, proceeding with the next server in the list on failure. See for example the "rotate" option of the dns-options setting. If there are any negative DNS priorities, then only name servers from the devices with that lowest priority will be considered. When using a DNS resolver that supports Conditional Forwarding or Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection is used to query domains in its search list. The search domains determine which name servers to ask, and the DNS priority is used to prioritize name servers based on the domain. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the best priority (lowest numerical value) wins. If a sub domain is configured on another interface it will be accepted regardless the priority, unless parent domain on the other interface has a negative priority, which causes the sub domain to be shadowed. With Split DNS one can avoid undesired DNS leaks by properly configuring DNS priorities and the search domains, so that only name servers of the desired interface are configured.dns-searcharray of stringArray of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names. When using a DNS plugin that supports Conditional Forwarding or Split DNS, then the search domains specify which name servers to query. This makes the behavior different from running with plain /etc/resolv.conf. For more information see also the dns-priority setting.gatewaystringThe gateway associated with this configuration. This is only meaningful if "addresses" is also set. The gateway's main purpose is to control the next hop of the standard default route on the device. Hence, the gateway property conflicts with "never-default" and will be automatically dropped if the IP configuration is set to never-default. As an alternative to set the gateway, configure a static default route with /0 as prefix length.ignore-auto-dnsbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured name servers and search domains are ignored and only name servers and search domains specified in the "dns" and "dns-search" properties, if any, are used.ignore-auto-routesbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used.may-failbooleanTRUEIf TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully.methodstringIP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "disabled", "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty. For IPv4 method "shared", the IP subnet can be configured by adding one manual IPv4 address or otherwise 10.42.x.0/24 is chosen. Note that the shared method must be configured on the interface which shares the internet to a subnet, not on the uplink which is shared.never-defaultbooleanFALSEIf TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager.route-dataarray of vardictArray of IPv4 routes. Each route dictionary contains at least 'dest' and 'prefix' entries, containing the destination IP address as a string, and the prefix length as a uint32. Most routes will also have a 'next-hop' entry, containing the next hop IP address as a string. If the route has a 'metric' entry (containing a uint32), that will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device). Additional attributes may also exist on some routes.route-metricint64-1The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric.route-tableuint320Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.routesarray of array of uint32Deprecated in favor of the 'route-data' property, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'route-data'. Array of IPv4 route structures. Each IPv4 route structure is composed of 4 32-bit values; the first being the destination IPv4 network or address (network byte order), the second the destination network or address prefix (1 - 32), the third being the next-hop (network byte order) if any, and the fourth being the route metric. If the metric is 0, NM will choose an appropriate default metric for the device. (There is no way to explicitly specify an actual metric of 0 with this property.)ipv6 settingIPv6 Settings.Key NameValue TypeDefault ValueValue Descriptionaddr-gen-modeint321Configure method for creating the address for use with RFC4862 IPv6 Stateless Address Autoconfiguration. The permitted values are: NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 (0) or NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY (1). If the property is set to EUI64, the addresses will be generated using the interface tokens derived from hardware address. This makes the host part of the address to stay constant, making it possible to track host's presence when it changes networks. The address changes when the interface hardware is replaced. The value of stable-privacy enables use of cryptographically secure hash of a secret host-specific key along with the connection's stable-id and the network address as specified by RFC7217. This makes it impossible to use the address track host's presence, and makes the address stable when the network interface hardware is replaced. On D-Bus, the absence of an addr-gen-mode setting equals enabling stable-privacy. For keyfile plugin, the absence of the setting on disk means EUI64 so that the property doesn't change on upgrade from older versions. Note that this setting is distinct from the Privacy Extensions as configured by "ip6-privacy" property and it does not affect the temporary addresses configured with this option.address-dataarray of vardictArray of IPv6 addresses. Each address dictionary contains at least 'address' and 'prefix' entries, containing the IP address as a string, and the prefix length as a uint32. Additional attributes may also exist on some addresses.addressesarray of legacy IPv6 address struct (a(ayuay))Deprecated in favor of the 'address-data' and 'gateway' properties, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'address-data' and 'gateway'. Array of IPv6 address structures. Each IPv6 address structure is composed of an IPv6 address, a prefix length (1 - 128), and an IPv6 gateway address. The gateway may be zeroed out if no gateway exists for that subnet.dad-timeoutint32-1Timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4.dhcp-duidstringA string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp client to identify itself to DHCPv6 servers (RFC 3315). The DUID is carried in the Client Identifier option. If the property is a hex string ('aa:bb:cc') it is interpreted as a binary DUID and filled as an opaque value in the Client Identifier option. The special value "lease" will retrieve the DUID previously used from the lease file belonging to the connection. If no DUID is found and "dhclient" is the configured dhcp client, the DUID is searched in the system-wide dhclient lease file. If still no DUID is found, or another dhcp client is used, a global and permanent DUID-UUID (RFC 6355) will be generated based on the machine-id. The special values "llt" and "ll" will generate a DUID of type LLT or LL (see RFC 3315) based on the current MAC address of the device. In order to try providing a stable DUID-LLT, the time field will contain a constant timestamp that is used globally (for all profiles) and persisted to disk. The special values "stable-llt", "stable-ll" and "stable-uuid" will generate a DUID of the corresponding type, derived from the connection's stable-id and a per-host unique key. You may want to include the "${DEVICE}" or "${MAC}" specifier in the stable-id, in case this profile gets activated on multiple devices. So, the link-layer address of "stable-ll" and "stable-llt" will be a generated address derived from the stable id. The DUID-LLT time value in the "stable-llt" option will be picked among a static timespan of three years (the upper bound of the interval is the same constant timestamp used in "llt"). When the property is unset, the global value provided for "ipv6.dhcp-duid" is used. If no global value is provided, the default "lease" value is assumed.dhcp-hostnamestringIf the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time.dhcp-hostname-flagsuint320Flags for the DHCP hostname and FQDN. Currently, this property only includes flags to control the FQDN flags set in the DHCP FQDN option. Supported FQDN flags are NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) and NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE (0x4). When no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is set, the DHCP FQDN option will contain no flag. Otherwise, if no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is not set, the standard FQDN flags are set in the request: NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) for IPv4 and NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1) for IPv6. When this property is set to the default value NM_DHCP_HOSTNAME_FLAG_NONE (0x0), a global default is looked up in NetworkManager configuration. If that value is unset or also NM_DHCP_HOSTNAME_FLAG_NONE (0x0), then the standard FQDN flags described above are sent in the DHCP requests.dhcp-iaidstringA string containing the "Identity Association Identifier" (IAID) used by the DHCP client. The property is a 32-bit decimal value or a special value among "mac", "perm-mac", "ifname" and "stable". When set to "mac" (or "perm-mac"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to "ifname", the IAID is computed by hashing the interface name. The special value "stable" can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be "ifname". Note that at the moment this property is ignored for IPv6 by dhclient, which always derives the IAID from the MAC address.dhcp-reject-serversarray of stringArray of servers from which DHCP offers must be rejected. This property is useful to avoid getting a lease from misconfigured or rogue servers. For DHCPv4, each element must be an IPv4 address, optionally followed by a slash and a prefix length (e.g. "192.168.122.0/24"). This property is currently not implemented for DHCPv6.dhcp-send-hostnamebooleanTRUEIf TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.dhcp-timeoutint320A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.dnsarray of byte arrayArray of IP addresses of DNS servers (in network byte order)dns-optionsarray of stringArray of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are "attempts", "debug", "edns0", "inet6", "ip6-bytestring", "ip6-dotint", "ndots", "no-check-names", "no-ip6-dotint", "no-reload", "no-tld-query", "rotate", "single-request", "single-request-reopen", "timeout", "trust-ad", "use-vc". The "trust-ad" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have "trust-ad" enabled. When using a caching DNS plugin (dnsmasq or systemd-resolved in NetworkManager.conf) then "edns0" and "trust-ad" are automatically added.dns-priorityint320DNS servers priority. The relative priority for DNS servers specified by this setting. A lower numerical value is better (higher priority). Negative values have the special effect of excluding other configurations with a greater numerical priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. To avoid all DNS leaks, set the priority of the profile that should be used to the most negative value of all active connections profiles. Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. Note that commonly the resolver tries name servers in /etc/resolv.conf in the order listed, proceeding with the next server in the list on failure. See for example the "rotate" option of the dns-options setting. If there are any negative DNS priorities, then only name servers from the devices with that lowest priority will be considered. When using a DNS resolver that supports Conditional Forwarding or Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection is used to query domains in its search list. The search domains determine which name servers to ask, and the DNS priority is used to prioritize name servers based on the domain. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the best priority (lowest numerical value) wins. If a sub domain is configured on another interface it will be accepted regardless the priority, unless parent domain on the other interface has a negative priority, which causes the sub domain to be shadowed. With Split DNS one can avoid undesired DNS leaks by properly configuring DNS priorities and the search domains, so that only name servers of the desired interface are configured.dns-searcharray of stringArray of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names. When using a DNS plugin that supports Conditional Forwarding or Split DNS, then the search domains specify which name servers to query. This makes the behavior different from running with plain /etc/resolv.conf. For more information see also the dns-priority setting.gatewaystringThe gateway associated with this configuration. This is only meaningful if "addresses" is also set. The gateway's main purpose is to control the next hop of the standard default route on the device. Hence, the gateway property conflicts with "never-default" and will be automatically dropped if the IP configuration is set to never-default. As an alternative to set the gateway, configure a static default route with /0 as prefix length.ignore-auto-dnsbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured name servers and search domains are ignored and only name servers and search domains specified in the "dns" and "dns-search" properties, if any, are used.ignore-auto-routesbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used.ip6-privacyNMSettingIP6ConfigPrivacy (int32)Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI-64. This enhances privacy, but could cause problems in some applications, on the other hand. The permitted values are: -1: unknown, 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses). Having a per-connection setting set to "-1" (unknown) means fallback to global configuration "ipv6.ip6-privacy". If also global configuration is unspecified or set to "-1", fallback to read "/proc/sys/net/ipv6/conf/default/use_tempaddr". Note that this setting is distinct from the Stable Privacy addresses that can be enabled with the "addr-gen-mode" property's "stable-privacy" setting as another way of avoiding host tracking with IPv6 addresses.may-failbooleanTRUEIf TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully.methodstringIP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "disabled", "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty. For IPv4 method "shared", the IP subnet can be configured by adding one manual IPv4 address or otherwise 10.42.x.0/24 is chosen. Note that the shared method must be configured on the interface which shares the internet to a subnet, not on the uplink which is shared.never-defaultbooleanFALSEIf TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager.ra-timeoutint320A timeout for waiting Router Advertisements in seconds. If zero (the default), a globally configured default is used. If still unspecified, the timeout depends on the sysctl settings of the device. Set to 2147483647 (MAXINT32) for infinity.route-dataarray of vardictArray of IPv6 routes. Each route dictionary contains at least 'dest' and 'prefix' entries, containing the destination IP address as a string, and the prefix length as a uint32. Most routes will also have a 'next-hop' entry, containing the next hop IP address as a string. If the route has a 'metric' entry (containing a uint32), that will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device). Additional attributes may also exist on some routes.route-metricint64-1The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric.route-tableuint320Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.routesarray of legacy IPv6 route struct (a(ayuayu))Deprecated in favor of the 'route-data' property, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'route-data'. Array of IPv6 route structures. Each IPv6 route structure is composed of an IPv6 address, a prefix length (1 - 128), an IPv6 next hop address (which may be zeroed out if there is no next hop), and a metric. If the metric is 0, NM will choose an appropriate default metric for the device.tokenstringConfigure the token for draft-chown-6man-tokenised-ipv6-identifiers-02 IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode.ip-tunnel settingIP Tunneling Settings.Key NameValue TypeDefault ValueValue Descriptionencapsulation-limituint320How many additional levels of encapsulation are permitted to be prepended to packets. This property applies only to IPv6 tunnels.flagsuint320Tunnel flags. Currently, the following values are supported: NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT (0x1), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS (0x2), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL (0x4), NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV (0x8), NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY (0x10), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK (0x20). They are valid only for IPv6 tunnels.flow-labeluint320The flow label to assign to tunnel packets. This property applies only to IPv6 tunnels.input-keystringThe key used for tunnel input packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used.localstringThe local endpoint of the tunnel; the value can be empty, otherwise it must contain an IPv4 or IPv6 address.modeuint320The tunneling mode, for example NM_IP_TUNNEL_MODE_IPIP (1) or NM_IP_TUNNEL_MODE_GRE (2).mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments.output-keystringThe key used for tunnel output packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used.parentstringIf given, specifies the parent interface name or parent connection UUID the new device will be bound to so that tunneled packets will only be routed via that interface.path-mtu-discoverybooleanTRUEWhether to enable Path MTU Discovery on this tunnel.remotestringThe remote endpoint of the tunnel; the value must contain an IPv4 or IPv6 address.tosuint320The type of service (IPv4) or traffic class (IPv6) field to be set on tunneled packets.ttluint320The TTL to assign to tunneled packets. 0 is a special value meaning that packets inherit the TTL value.macsec settingMACSec Settings.Key NameValue TypeDefault ValueValue DescriptionencryptbooleanTRUEWhether the transmitted traffic must be encrypted.mka-cakstringThe pre-shared CAK (Connectivity Association Key) for MACsec Key Agreement.mka-cak-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "mka-cak" property. (see for flag values)mka-cknstringThe pre-shared CKN (Connectivity-association Key Name) for MACsec Key Agreement.modeint320Specifies how the CAK (Connectivity Association Key) for MKA (MACsec Key Agreement) is obtained.parentstringIf given, specifies the parent interface name or parent connection UUID from which this MACSEC interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property.portint321The port component of the SCI (Secure Channel Identifier), between 1 and 65534.send-scibooleanTRUESpecifies whether the SCI (Secure Channel Identifier) is included in every packet.validationint322Specifies the validation mode for incoming frames.macvlan settingMAC VLAN Settings.Key NameValue TypeDefault ValueValue Descriptionmodeuint320The macvlan mode, which specifies the communication mechanism between multiple macvlans on the same lower device.parentstringIf given, specifies the parent interface name or parent connection UUID from which this MAC-VLAN interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property.promiscuousbooleanTRUEWhether the interface should be put in promiscuous mode.tapbooleanFALSEWhether the interface should be a MACVTAP.match settingMatch settings.Key NameValue TypeDefault ValueValue Descriptiondriverarray of stringA list of driver names to match. Each element is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.interface-namearray of stringA list of interface names to match. Each element is a shell wildcard pattern. An element can be prefixed with a pipe symbol (|) or an ampersand (&). The former means that the element is optional and the latter means that it is mandatory. If there are any optional elements, than the match evaluates to true if at least one of the optional element matches (logical OR). If there are any mandatory elements, then they all must match (logical AND). By default, an element is optional. This means that an element "foo" behaves the same as "|foo". An element can also be inverted with exclamation mark (!) between the pipe symbol (or the ampersand) and before the pattern. Note that "!foo" is a shortcut for the mandatory match "&!foo". Finally, a backslash can be used at the beginning of the element (after the optional special characters) to escape the start of the pattern. For example, "&\\!a" is an mandatory match for literally "!a".kernel-command-linearray of stringA list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or unset, if prefixed with the exclamation mark). The argument must either be a single word, or an assignment (i.e. two words, joined by "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. Wildcard patterns are not supported. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the match.patharray of stringA list of paths to match against the ID_PATH udev property of devices. ID_PATH represents the topological persistent path of a device. It typically contains a subsystem string (pci, usb, platform, etc.) and a subsystem-specific identifier. For PCI devices the path has the form "pci-$domain:$bus:$device.$function", where each variable is an hexadecimal value; for example "pci-0000:0a:00.0". The path of a device can be obtained with "udevadm info /sys/class/net/$dev | grep ID_PATH=" or by looking at the "path" property exported by NetworkManager ("nmcli -f general.path device show $dev"). Each element of the list is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.802-11-olpc-mesh settingOLPC Wireless Mesh Settings.Key NameValue TypeDefault ValueValue Descriptionchanneluint320Channel on which the mesh network to join is located.dhcp-anycast-addressbyte arrayAnycast DHCP MAC address used when requesting an IP address via DHCP. The specific anycast address used determines which DHCP server class answers the request.ssidbyte arraySSID of the mesh network to join.ovs-bridge settingOvsBridge Link Settings.Key NameValue TypeDefault ValueValue Descriptiondatapath-typestringThe data path type. One of "system", "netdev" or empty.fail-modestringThe bridge failure mode. One of "secure", "standalone" or empty.mcast-snooping-enablebooleanFALSEEnable or disable multicast snooping.rstp-enablebooleanFALSEEnable or disable RSTP.stp-enablebooleanFALSEEnable or disable STP.ovs-dpdk settingOvsDpdk Link Settings.Key NameValue TypeDefault ValueValue DescriptiondevargsstringOpen vSwitch DPDK device arguments.ovs-interface settingOpen vSwitch Interface Settings.Key NameValue TypeDefault ValueValue DescriptiontypestringThe interface type. Either "internal", "system", "patch", "dpdk", or empty.ovs-patch settingOvsPatch Link Settings.Key NameValue TypeDefault ValueValue DescriptionpeerstringSpecifies the name of the interface for the other side of the patch. The patch on the other side must also set this interface as peer.ovs-port settingOvsPort Link Settings.Key NameValue TypeDefault ValueValue Descriptionbond-downdelayuint320The time port must be inactive in order to be considered down.bond-modestringBonding mode. One of "active-backup", "balance-slb", or "balance-tcp".bond-updelayuint320The time port must be active before it starts forwarding traffic.lacpstringLACP mode. One of "active", "off", or "passive".taguint320The VLAN tag in the range 0-4095.vlan-modestringThe VLAN mode. One of "access", "native-tagged", "native-untagged", "trunk" or unset.ppp settingPoint-to-Point Protocol Settings.Key NameValue TypeDefault ValueValue Descriptionbauduint320If non-zero, instruct pppd to set the serial port to the specified baudrate. This value should normally be left as 0 to automatically choose the speed.crtsctsbooleanFALSEIf TRUE, specify that pppd should set the serial port to use hardware flow control with RTS and CTS signals. This value should normally be set to FALSE.lcp-echo-failureuint320If non-zero, instruct pppd to presume the connection to the peer has failed if the specified number of LCP echo-requests go unanswered by the peer. The "lcp-echo-interval" property must also be set to a non-zero value if this property is used.lcp-echo-intervaluint320If non-zero, instruct pppd to send an LCP echo-request frame to the peer every n seconds (where n is the specified value). Note that some PPP peers will respond to echo requests and some will not, and it is not possible to autodetect this.mppe-statefulbooleanFALSEIf TRUE, stateful MPPE is used. See pppd documentation for more information on stateful MPPE.mruuint320If non-zero, instruct pppd to request that the peer send packets no larger than the specified size. If non-zero, the MRU should be between 128 and 16384.mtuuint320If non-zero, instruct pppd to send packets no larger than the specified size.no-vj-compbooleanFALSEIf TRUE, Van Jacobsen TCP header compression will not be requested.noauthbooleanTRUEIf TRUE, do not require the other side (usually the PPP server) to authenticate itself to the client. If FALSE, require authentication from the remote side. In almost all cases, this should be TRUE.nobsdcompbooleanFALSEIf TRUE, BSD compression will not be requested.nodeflatebooleanFALSEIf TRUE, "deflate" compression will not be requested.refuse-chapbooleanFALSEIf TRUE, the CHAP authentication method will not be used.refuse-eapbooleanFALSEIf TRUE, the EAP authentication method will not be used.refuse-mschapbooleanFALSEIf TRUE, the MSCHAP authentication method will not be used.refuse-mschapv2booleanFALSEIf TRUE, the MSCHAPv2 authentication method will not be used.refuse-papbooleanFALSEIf TRUE, the PAP authentication method will not be used.require-mppebooleanFALSEIf TRUE, MPPE (Microsoft Point-to-Point Encryption) will be required for the PPP session. If either 64-bit or 128-bit MPPE is not available the session will fail. Note that MPPE is not used on mobile broadband connections.require-mppe-128booleanFALSEIf TRUE, 128-bit MPPE (Microsoft Point-to-Point Encryption) will be required for the PPP session, and the "require-mppe" property must also be set to TRUE. If 128-bit MPPE is not available the session will fail.pppoe settingPPP-over-Ethernet Settings.Key NameValue TypeDefault ValueValue DescriptionparentstringIf given, specifies the parent interface name on which this PPPoE connection should be created. If this property is not specified, the connection is activated on the interface specified in "interface-name" of NMSettingConnection.passwordstringPassword used to authenticate with the PPPoE service.password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values)servicestringIf specified, instruct PPPoE to only initiate sessions with access concentrators that provide the specified service. For most providers, this should be left blank. It is only required if there are multiple access concentrators or a specific service is known to be required.usernamestringUsername used to authenticate with the PPPoE service.proxy settingWWW Proxy Settings.Key NameValue TypeDefault ValueValue Descriptionbrowser-onlybooleanFALSEWhether the proxy configuration is for browser only.methodint320Method for proxy configuration, Default is NM_SETTING_PROXY_METHOD_NONE (0)pac-scriptstringPAC script for the connection.pac-urlstringPAC URL for obtaining PAC file.serial settingSerial Link Settings.Key NameValue TypeDefault ValueValue Descriptionbauduint3257600Speed to use for communication over the serial port. Note that this value usually has no effect for mobile broadband modems as they generally ignore speed settings and use the highest available speed.bitsuint328Byte-width of the serial communication. The 8 in "8n1" for example.paritybyteThe connection parity: 69 (ASCII 'E') for even parity, 111 (ASCII 'o') for odd, 110 (ASCII 'n') for none.send-delayuint640Time to delay between each byte sent to the modem, in microseconds.stopbitsuint321Number of stop bits for communication on the serial port. Either 1 or 2. The 1 in "8n1" for example.sriov settingSR-IOV settings.Key NameValue TypeDefault ValueValue Descriptionautoprobe-driversNMTernary (int32)Whether to autoprobe virtual functions by a compatible driver. If set to NM_TERNARY_TRUE (1), the kernel will try to bind VFs to a compatible driver and if this succeeds a new network interface will be instantiated for each VF. If set to NM_TERNARY_FALSE (0), VFs will not be claimed and no network interfaces will be created for them. When set to NM_TERNARY_DEFAULT (-1), the global default is used; in case the global default is unspecified it is assumed to be NM_TERNARY_TRUE (1).total-vfsuint320The total number of virtual functions to create. Note that when the sriov setting is present NetworkManager enforces the number of virtual functions on the interface (also when it is zero) during activation and resets it upon deactivation. To prevent any changes to SR-IOV parameters don't add a sriov setting to the connection.vfsarray of vardictArray of virtual function descriptors. Each VF descriptor is a dictionary mapping attribute names to GVariant values. The 'index' entry is mandatory for each VF. When represented as string a VF is in the form: "INDEX [ATTR=VALUE[ ATTR=VALUE]...]". for example: "2 mac=00:11:22:33:44:55 spoof-check=true". Multiple VFs can be specified using a comma as separator. Currently, the following attributes are supported: mac, spoof-check, trust, min-tx-rate, max-tx-rate, vlans. The "vlans" attribute is represented as a semicolon-separated list of VLAN descriptors, where each descriptor has the form "ID[.PRIORITY[.PROTO]]". PROTO can be either 'q' for 802.1Q (the default) or 'ad' for 802.1ad.tc settingLinux Traffic Control Settings.Key NameValue TypeDefault ValueValue Descriptionqdiscsarray of vardictArray of TC queueing disciplines.tfiltersarray of vardictArray of TC traffic filters.team settingTeaming Settings.Key NameValue TypeDefault ValueValue DescriptionconfigstringThe JSON configuration for the team network interface. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.interface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the team's interface name.link-watchersarray of vardictLink watchers configuration for the connection: each link watcher is defined by a dictionary, whose keys depend upon the selected link watcher. Available link watchers are 'ethtool', 'nsna_ping' and 'arp_ping' and it is specified in the dictionary with the key 'name'. Available keys are: ethtool: 'delay-up', 'delay-down', 'init-wait'; nsna_ping: 'init-wait', 'interval', 'missed-max', 'target-host'; arp_ping: all the ones in nsna_ping and 'source-host', 'validate-active', 'validate-inactive', 'send-always'. See teamd.conf man for more details.mcast-rejoin-countint32-1Corresponds to the teamd mcast_rejoin.count.mcast-rejoin-intervalint32-1Corresponds to the teamd mcast_rejoin.interval.notify-peers-countint32-1Corresponds to the teamd notify_peers.count.notify-peers-intervalint32-1Corresponds to the teamd notify_peers.interval.runnerstringCorresponds to the teamd runner.name. Permitted values are: "roundrobin", "broadcast", "activebackup", "loadbalance", "lacp", "random".runner-activebooleanTRUECorresponds to the teamd runner.active.runner-agg-select-policystringCorresponds to the teamd runner.agg_select_policy.runner-fast-ratebooleanFALSECorresponds to the teamd runner.fast_rate.runner-hwaddr-policystringCorresponds to the teamd runner.hwaddr_policy.runner-min-portsint32-1Corresponds to the teamd runner.min_ports.runner-sys-prioint32-1Corresponds to the teamd runner.sys_prio.runner-tx-balancerstringCorresponds to the teamd runner.tx_balancer.name.runner-tx-balancer-intervalint32-1Corresponds to the teamd runner.tx_balancer.interval.runner-tx-hasharray of stringCorresponds to the teamd runner.tx_hash.team-port settingTeam Port Settings.Key NameValue TypeDefault ValueValue DescriptionconfigstringThe JSON configuration for the team port. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.lacp-keyint32-1Corresponds to the teamd ports.PORTIFNAME.lacp_key.lacp-prioint32-1Corresponds to the teamd ports.PORTIFNAME.lacp_prio.link-watchersarray of vardictLink watchers configuration for the connection: each link watcher is defined by a dictionary, whose keys depend upon the selected link watcher. Available link watchers are 'ethtool', 'nsna_ping' and 'arp_ping' and it is specified in the dictionary with the key 'name'. Available keys are: ethtool: 'delay-up', 'delay-down', 'init-wait'; nsna_ping: 'init-wait', 'interval', 'missed-max', 'target-host'; arp_ping: all the ones in nsna_ping and 'source-host', 'validate-active', 'validate-inactive', 'send-always'. See teamd.conf man for more details.prioint320Corresponds to the teamd ports.PORTIFNAME.prio.queue-idint32-1Corresponds to the teamd ports.PORTIFNAME.queue_id. When set to -1 means the parameter is skipped from the json config.stickybooleanFALSECorresponds to the teamd ports.PORTIFNAME.sticky.tun settingTunnel Settings.Key NameValue TypeDefault ValueValue DescriptiongroupstringThe group ID which will own the device. If set to NULL everyone will be able to use the device.modeuint321The operating mode of the virtual device. Allowed values are NM_SETTING_TUN_MODE_TUN (1) to create a layer 3 device and NM_SETTING_TUN_MODE_TAP (2) to create an Ethernet-like layer 2 one.multi-queuebooleanFALSEIf the property is set to TRUE, the interface will support multiple file descriptors (queues) to parallelize packet sending or receiving. Otherwise, the interface will only support a single queue.ownerstringThe user ID which will own the device. If set to NULL everyone will be able to use the device.pibooleanFALSEIf TRUE the interface will prepend a 4 byte header describing the physical interface to the packets.vnet-hdrbooleanFALSEIf TRUE the IFF_VNET_HDR the tunnel packets will include a virtio network header.user settingGeneral User Profile Settings.Key NameValue TypeDefault ValueValue Descriptiondatadict of string to string{}A dictionary of key/value pairs with user data. This data is ignored by NetworkManager and can be used at the users discretion. The keys only support a strict ascii format, but the values can be arbitrary UTF8 strings up to a certain length.vlan settingVLAN Settings.Key NameValue TypeDefault ValueValue Descriptionegress-priority-maparray of stringFor outgoing packets, a list of mappings from Linux SKB priorities to 802.1p priorities. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3".flagsNMVlanFlags (uint32)One or more flags which control the behavior and features of the VLAN interface. Flags include NM_VLAN_FLAG_REORDER_HEADERS (0x1) (reordering of output packet headers), NM_VLAN_FLAG_GVRP (0x2) (use of the GVRP protocol), and NM_VLAN_FLAG_LOOSE_BINDING (0x4) (loose binding of the interface to its master device's operating state). NM_VLAN_FLAG_MVRP (0x8) (use of the MVRP protocol). The default value of this property is NM_VLAN_FLAG_REORDER_HEADERS, but it used to be 0. To preserve backward compatibility, the default-value in the D-Bus API continues to be 0 and a missing property on D-Bus is still considered as 0.iduint320The VLAN identifier that the interface created by this connection should be assigned. The valid range is from 0 to 4094, without the reserved id 4095.ingress-priority-maparray of stringFor incoming packets, a list of mappings from 802.1p priorities to Linux SKB priorities. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3".interface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the vlan's interface name.parentstringIf given, specifies the parent interface name or parent connection UUID from which this VLAN interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property.vpn settingVPN Settings.Key NameValue TypeDefault ValueValue Descriptiondatadict of string to string{}Dictionary of key/value pairs of VPN plugin specific data. Both keys and values must be strings.persistentbooleanFALSEIf the VPN service supports persistence, and this property is TRUE, the VPN will attempt to stay connected across link changes and outages, until explicitly disconnected.secretsdict of string to string{}Dictionary of key/value pairs of VPN plugin specific secrets like passwords or private keys. Both keys and values must be strings.service-typestringD-Bus service name of the VPN plugin that this setting uses to connect to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc plugin.timeoutuint320Timeout for the VPN service to establish the connection. Some services may take quite a long time to connect. Value of 0 means a default timeout, which is 60 seconds (unless overridden by vpn.timeout in configuration file). Values greater than zero mean timeout in seconds.user-namestringIf the VPN connection requires a user name for authentication, that name should be provided here. If the connection is available to more than one user, and the VPN requires each user to supply a different name, then leave this property empty. If this property is empty, NetworkManager will automatically supply the username of the user which requested the VPN connection.vrf settingVRF settings.Key NameValue TypeDefault ValueValue Descriptiontableuint320The routing table for this VRF.vxlan settingVXLAN Settings.Key NameValue TypeDefault ValueValue Descriptionageinguint32300Specifies the lifetime in seconds of FDB entries learnt by the kernel.destination-portuint328472Specifies the UDP destination port to communicate to the remote VXLAN tunnel endpoint.iduint320Specifies the VXLAN Network Identifier (or VXLAN Segment Identifier) to use.l2-missbooleanFALSESpecifies whether netlink LL ADDR miss notifications are generated.l3-missbooleanFALSESpecifies whether netlink IP ADDR miss notifications are generated.learningbooleanTRUESpecifies whether unknown source link layer addresses and IP addresses are entered into the VXLAN device forwarding database.limituint320Specifies the maximum number of FDB entries. A value of zero means that the kernel will store unlimited entries.localstringIf given, specifies the source IP address to use in outgoing packets.parentstringIf given, specifies the parent interface name or parent connection UUID.proxybooleanFALSESpecifies whether ARP proxy is turned on.remotestringSpecifies the unicast destination IP address to use in outgoing packets when the destination link layer address is not known in the VXLAN device forwarding database, or the multicast IP address to join.rscbooleanFALSESpecifies whether route short circuit is turned on.source-port-maxuint320Specifies the maximum UDP source port to communicate to the remote VXLAN tunnel endpoint.source-port-minuint320Specifies the minimum UDP source port to communicate to the remote VXLAN tunnel endpoint.tosuint320Specifies the TOS value to use in outgoing packets.ttluint320Specifies the time-to-live value to use in outgoing packets.wifi-p2p settingWi-Fi P2P Settings.Key NameValue TypeDefault ValueValue DescriptionpeerstringThe P2P device that should be connected to. Currently, this is the only way to create or join a group.wfd-iesbyte arrayThe Wi-Fi Display (WFD) Information Elements (IEs) to set. Wi-Fi Display requires a protocol specific information element to be set in certain Wi-Fi frames. These can be specified here for the purpose of establishing a connection. This setting is only useful when implementing a Wi-Fi Display client.wps-methoduint320Flags indicating which mode of WPS is to be used. There's little point in changing the default setting as NetworkManager will automatically determine the best method to use.wimax settingWiMax Settings.Key NameValue TypeDefault ValueValue Descriptionmac-addressbyte arrayIf specified, this connection will only apply to the WiMAX device whose MAC address matches. This property does not change the MAC address of the device (known as MAC spoofing). Deprecated: 1network-namestringNetwork Service Provider (NSP) name of the WiMAX network this connection should use. Deprecated: 1802-3-ethernet settingWired Ethernet Settings.Key NameValue TypeDefault ValueValue Descriptionassigned-mac-addressstringThe new field for the cloned MAC address. It can be either a hardware address in ASCII representation, or one of the special values "preserve", "permanent", "random" or "stable". This field replaces the deprecated "cloned-mac-address" on D-Bus, which can only contain explicit hardware addresses. Note that this property only exists in D-Bus API. libnm and nmcli continue to call this property "cloned-mac-address".auto-negotiatebooleanFALSEWhen TRUE, enforce auto-negotiation of speed and duplex mode. If "speed" and "duplex" properties are both specified, only that single mode will be advertised and accepted during the link auto-negotiation process: this works only for BASE-T 802.3 specifications and is useful for enforcing gigabits modes, as in these cases link negotiation is mandatory. When FALSE, "speed" and "duplex" properties should be both set or link configuration will be skipped.cloned-mac-addressbyte arrayThis D-Bus field is deprecated in favor of "assigned-mac-address" which is more flexible and allows specifying special variants like "random". For libnm and nmcli, this field is called "cloned-mac-address".duplexstringWhen a value is set, either "half" or "full", configures the device to use the specified duplex mode. If "auto-negotiate" is "yes" the specified duplex mode will be the only one advertised during link negotiation: this works only for BASE-T 802.3 specifications and is useful for enforcing gigabits modes, as in these cases link negotiation is mandatory. If the value is unset (the default), the link configuration will be either skipped (if "auto-negotiate" is "no", the default) or will be auto-negotiated (if "auto-negotiate" is "yes") and the local device will advertise all the supported duplex modes. Must be set together with the "speed" property if specified. Before specifying a duplex mode be sure your device supports it.generate-mac-address-maskstringWith "cloned-mac-address" setting "random" or "stable", by default all bits of the MAC address are scrambled and a locally-administered, unicast MAC address is created. This property allows to specify that certain bits are fixed. Note that the least significant bit of the first MAC address will always be unset to create a unicast MAC address. If the property is NULL, it is eligible to be overwritten by a default connection setting. If the value is still NULL or an empty string, the default is to create a locally-administered, unicast MAC address. If the value contains one MAC address, this address is used as mask. The set bits of the mask are to be filled with the current MAC address of the device, while the unset bits are subject to randomization. Setting "FE:FF:FF:00:00:00" means to preserve the OUI of the current MAC address and only randomize the lower 3 bytes using the "random" or "stable" algorithm. If the value contains one additional MAC address after the mask, this address is used instead of the current MAC address to fill the bits that shall not be randomized. For example, a value of "FE:FF:FF:00:00:00 68:F7:28:00:00:00" will set the OUI of the MAC address to 68:F7:28, while the lower bits are randomized. A value of "02:00:00:00:00:00 00:00:00:00:00:00" will create a fully scrambled globally-administered, burned-in MAC address. If the value contains more than one additional MAC addresses, one of them is chosen randomly. For example, "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00" will create a fully scrambled MAC address, randomly locally or globally administered.mac-addressbyte arrayIf specified, this connection will only apply to the Ethernet device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).mac-address-blacklistarray of stringIf specified, this connection will never apply to the Ethernet device whose permanent MAC address matches an address in the list. Each MAC address is in the standard hex-digits-and-colons notation (00:11:22:33:44:55).mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames.portstringSpecific port type to use if the device supports multiple attachment methods. One of "tp" (Twisted Pair), "aui" (Attachment Unit Interface), "bnc" (Thin Ethernet) or "mii" (Media Independent Interface). If the device supports only one port type, this setting is ignored.s390-nettypestrings390 network device type; one of "qeth", "lcs", or "ctc", representing the different types of virtual network devices available on s390 systems.s390-optionsdict of string to string{}Dictionary of key/value pairs of s390-specific device options. Both keys and values must be strings. Allowed keys include "portno", "layer2", "portname", "protocol", among others. Key names must contain only alphanumeric characters (ie, [a-zA-Z0-9]).s390-subchannelsarray of stringIdentifies specific subchannels that this network device uses for communication with z/VM or s390 host. Like the "mac-address" property for non-z/VM devices, this property can be used to ensure this connection only applies to the network device that uses these subchannels. The list should contain exactly 3 strings, and each string may only be composed of hexadecimal characters and the period (.) character.speeduint320When a value greater than 0 is set, configures the device to use the specified speed. If "auto-negotiate" is "yes" the specified speed will be the only one advertised during link negotiation: this works only for BASE-T 802.3 specifications and is useful for enforcing gigabit speeds, as in this case link negotiation is mandatory. If the value is unset (0, the default), the link configuration will be either skipped (if "auto-negotiate" is "no", the default) or will be auto-negotiated (if "auto-negotiate" is "yes") and the local device will advertise all the supported speeds. In Mbit/s, ie 100 == 100Mbit/s. Must be set together with the "duplex" property when non-zero. Before specifying a speed value be sure your device supports it.wake-on-lanuint321The NMSettingWiredWakeOnLan options to enable. Not all devices support all options. May be any combination of NM_SETTING_WIRED_WAKE_ON_LAN_PHY (0x2), NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST (0x4), NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST (0x8), NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST (0x10), NM_SETTING_WIRED_WAKE_ON_LAN_ARP (0x20), NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC (0x40) or the special values NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT (0x1) (to use global settings) and NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE (0x8000) (to disable management of Wake-on-LAN in NetworkManager).wake-on-lan-passwordstringIf specified, the password used with magic-packet-based Wake-on-LAN, represented as an Ethernet MAC address. If NULL, no password will be required.wireguard settingWireGuard Settings.Key NameValue TypeDefault ValueValue Descriptionfwmarkuint320The use of fwmark is optional and is by default off. Setting it to 0 disables it. Otherwise, it is a 32-bit fwmark for outgoing packets. Note that "ip4-auto-default-route" or "ip6-auto-default-route" enabled, implies to automatically choose a fwmark.ip4-auto-default-routeNMTernary (int32)Whether to enable special handling of the IPv4 default route. If enabled, the IPv4 default route from wireguard.peer-routes will be placed to a dedicated routing-table and two policy routing rules will be added. The fwmark number is also used as routing-table for the default-route, and if fwmark is zero, an unused fwmark/table is chosen automatically. This corresponds to what wg-quick does with Table=auto and what WireGuard calls "Improved Rule-based Routing". Note that for this automatism to work, you usually don't want to set ipv4.gateway, because that will result in a conflicting default route. Leaving this at the default will enable this option automatically if ipv4.never-default is not set and there are any peers that use a default-route as allowed-ips.ip6-auto-default-routeNMTernary (int32)Like ip4-auto-default-route, but for the IPv6 default route.listen-portuint320The listen-port. If listen-port is not specified, the port will be chosen randomly when the interface comes up.mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments. If zero a default MTU is used. Note that contrary to wg-quick's MTU setting, this does not take into account the current routes at the time of activation.peer-routesbooleanTRUEWhether to automatically add routes for the AllowedIPs ranges of the peers. If TRUE (the default), NetworkManager will automatically add routes in the routing tables according to ipv4.route-table and ipv6.route-table. Usually you want this automatism enabled. If FALSE, no such routes are added automatically. In this case, the user may want to configure static routes in ipv4.routes and ipv6.routes, respectively. Note that if the peer's AllowedIPs is "0.0.0.0/0" or "::/0" and the profile's ipv4.never-default or ipv6.never-default setting is enabled, the peer route for this peer won't be added automatically.peersarray of 'a{sv}'Array of dictionaries for the WireGuard peers.private-keystringThe 256 bit private-key in base64 encoding.private-key-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "private-key" property. (see for flag values)802-11-wireless settingWi-Fi Settings.Key NameValue TypeDefault ValueValue Descriptionap-isolationNMTernary (int32)Configures AP isolation, which prevents communication between wireless devices connected to this AP. This property can be set to a value different from NM_TERNARY_DEFAULT (-1) only when the interface is configured in AP mode. If set to NM_TERNARY_TRUE (1), devices are not able to communicate with each other. This increases security because it protects devices against attacks from other clients in the network. At the same time, it prevents devices to access resources on the same wireless networks as file shares, printers, etc. If set to NM_TERNARY_FALSE (0), devices can talk to each other. When set to NM_TERNARY_DEFAULT (-1), the global default is used; in case the global default is unspecified it is assumed to be NM_TERNARY_FALSE (0).assigned-mac-addressstringThe new field for the cloned MAC address. It can be either a hardware address in ASCII representation, or one of the special values "preserve", "permanent", "random" or "stable". This field replaces the deprecated "cloned-mac-address" on D-Bus, which can only contain explicit hardware addresses. Note that this property only exists in D-Bus API. libnm and nmcli continue to call this property "cloned-mac-address".bandstring802.11 frequency band of the network. One of "a" for 5GHz 802.11a or "bg" for 2.4GHz 802.11. This will lock associations to the Wi-Fi network to the specific band, i.e. if "a" is specified, the device will not associate with the same network in the 2.4GHz band even if the network's settings are compatible. This setting depends on specific driver capability and may not work with all drivers.bssidbyte arrayIf specified, directs the device to only associate with the given access point. This capability is highly driver dependent and not supported by all devices. Note: this property does not control the BSSID used when creating an Ad-Hoc network and is unlikely to in the future.channeluint320Wireless channel to use for the Wi-Fi connection. The device will only join (or create for Ad-Hoc networks) a Wi-Fi network on the specified channel. Because channel numbers overlap between bands, this property also requires the "band" property to be set.cloned-mac-addressbyte arrayThis D-Bus field is deprecated in favor of "assigned-mac-address" which is more flexible and allows specifying special variants like "random". For libnm and nmcli, this field is called "cloned-mac-address".generate-mac-address-maskstringWith "cloned-mac-address" setting "random" or "stable", by default all bits of the MAC address are scrambled and a locally-administered, unicast MAC address is created. This property allows to specify that certain bits are fixed. Note that the least significant bit of the first MAC address will always be unset to create a unicast MAC address. If the property is NULL, it is eligible to be overwritten by a default connection setting. If the value is still NULL or an empty string, the default is to create a locally-administered, unicast MAC address. If the value contains one MAC address, this address is used as mask. The set bits of the mask are to be filled with the current MAC address of the device, while the unset bits are subject to randomization. Setting "FE:FF:FF:00:00:00" means to preserve the OUI of the current MAC address and only randomize the lower 3 bytes using the "random" or "stable" algorithm. If the value contains one additional MAC address after the mask, this address is used instead of the current MAC address to fill the bits that shall not be randomized. For example, a value of "FE:FF:FF:00:00:00 68:F7:28:00:00:00" will set the OUI of the MAC address to 68:F7:28, while the lower bits are randomized. A value of "02:00:00:00:00:00 00:00:00:00:00:00" will create a fully scrambled globally-administered, burned-in MAC address. If the value contains more than one additional MAC addresses, one of them is chosen randomly. For example, "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00" will create a fully scrambled MAC address, randomly locally or globally administered.hiddenbooleanFALSEIf TRUE, indicates that the network is a non-broadcasting network that hides its SSID. This works both in infrastructure and AP mode. In infrastructure mode, various workarounds are used for a more reliable discovery of hidden networks, such as probe-scanning the SSID. However, these workarounds expose inherent insecurities with hidden SSID networks, and thus hidden SSID networks should be used with caution. In AP mode, the created network does not broadcast its SSID. Note that marking the network as hidden may be a privacy issue for you (in infrastructure mode) or client stations (in AP mode), as the explicit probe-scans are distinctly recognizable on the air.mac-addressbyte arrayIf specified, this connection will only apply to the Wi-Fi device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).mac-address-blacklistarray of stringA list of permanent MAC addresses of Wi-Fi devices to which this connection should never apply. Each MAC address should be given in the standard hex-digits-and-colons notation (eg "00:11:22:33:44:55").mac-address-randomizationuint320One of NM_SETTING_MAC_RANDOMIZATION_DEFAULT (0) (never randomize unless the user has set a global default to randomize and the supplicant supports randomization), NM_SETTING_MAC_RANDOMIZATION_NEVER (1) (never randomize the MAC address), or NM_SETTING_MAC_RANDOMIZATION_ALWAYS (2) (always randomize the MAC address). This property is deprecated for 'cloned-mac-address'. Deprecated: 1modestringWi-Fi network mode; one of "infrastructure", "mesh", "adhoc" or "ap". If blank, infrastructure is assumed.mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames.powersaveuint320One of NM_SETTING_WIRELESS_POWERSAVE_DISABLE (2) (disable Wi-Fi power saving), NM_SETTING_WIRELESS_POWERSAVE_ENABLE (3) (enable Wi-Fi power saving), NM_SETTING_WIRELESS_POWERSAVE_IGNORE (1) (don't touch currently configure setting) or NM_SETTING_WIRELESS_POWERSAVE_DEFAULT (0) (use the globally configured value). All other values are reserved.rateuint320If non-zero, directs the device to only use the specified bitrate for communication with the access point. Units are in Kb/s, ie 5500 = 5.5 Mbit/s. This property is highly driver dependent and not all devices support setting a static bitrate.securityThis property is deprecated, but can be set to the value '802-11-wireless-security' when a wireless security setting is also present in the connection dictionary, for compatibility with very old NetworkManager daemons.seen-bssidsarray of stringA list of BSSIDs (each BSSID formatted as a MAC address like "00:11:22:33:44:55") that have been detected as part of the Wi-Fi network. NetworkManager internally tracks previously seen BSSIDs. The property is only meant for reading and reflects the BSSID list of NetworkManager. The changes you make to this property will not be preserved.ssidbyte arraySSID of the Wi-Fi network. Must be specified.tx-poweruint320If non-zero, directs the device to use the specified transmit power. Units are dBm. This property is highly driver dependent and not all devices support setting a static transmit power.wake-on-wlanuint321The NMSettingWirelessWakeOnWLan options to enable. Not all devices support all options. May be any combination of NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY (0x2), NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT (0x4), NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC (0x8), NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE (0x10), NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST (0x20), NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE (0x40), NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE (0x80), NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP (0x100) or the special values NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT (0x1) (to use global settings) and NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE (0x8000) (to disable management of Wake-on-LAN in NetworkManager).802-11-wireless-security settingWi-Fi Security Settings.Key NameValue TypeDefault ValueValue Descriptionauth-algstringWhen WEP is used (ie, key-mgmt = "none" or "ieee8021x") indicate the 802.11 authentication algorithm required by the AP here. One of "open" for Open System, "shared" for Shared Key, or "leap" for Cisco LEAP. When using Cisco LEAP (ie, key-mgmt = "ieee8021x" and auth-alg = "leap") the "leap-username" and "leap-password" properties must be specified.filsint320Indicates whether Fast Initial Link Setup (802.11ai) must be enabled for the connection. One of NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (0) (use global default value), NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE (1) (disable FILS), NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL (2) (enable FILS if the supplicant and the access point support it) or NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED (3) (enable FILS and fail if not supported). When set to NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (0) and no global default is set, FILS will be optionally enabled.grouparray of stringA list of group/broadcast encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of "wep40", "wep104", "tkip", or "ccmp".key-mgmtstringKey management used for the connection. One of "none" (WEP), "ieee8021x" (Dynamic WEP), "wpa-psk" (infrastructure WPA-PSK), "sae" (SAE), "owe" (Opportunistic Wireless Encryption), "wpa-eap" (WPA-Enterprise) or "wpa-eap-suite-b-192" (WPA3-Enterprise Suite B). This property must be set for any Wi-Fi connection that uses security.leap-passwordstringThe login password for legacy LEAP connections (ie, key-mgmt = "ieee8021x" and auth-alg = "leap").leap-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "leap-password" property. (see for flag values)leap-usernamestringThe login username for legacy LEAP connections (ie, key-mgmt = "ieee8021x" and auth-alg = "leap").pairwisearray of stringA list of pairwise encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of "tkip" or "ccmp".pmfint320Indicates whether Protected Management Frames (802.11w) must be enabled for the connection. One of NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT (0) (use global default value), NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE (1) (disable PMF), NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL (2) (enable PMF if the supplicant and the access point support it) or NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED (3) (enable PMF and fail if not supported). When set to NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT (0) and no global default is set, PMF will be optionally enabled.protoarray of stringList of strings specifying the allowed WPA protocol versions to use. Each element may be one "wpa" (allow WPA) or "rsn" (allow WPA2/RSN). If not specified, both WPA and RSN connections are allowed.pskstringPre-Shared-Key for WPA networks. For WPA-PSK, it's either an ASCII passphrase of 8 to 63 characters that is (as specified in the 802.11i standard) hashed to derive the actual key, or the key in form of 64 hexadecimal character. The WPA3-Personal networks use a passphrase of any length for SAE authentication.psk-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "psk" property. (see for flag values)wep-key-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "wep-key0", "wep-key1", "wep-key2", and "wep-key3" properties. (see for flag values)wep-key-typeNMWepKeyType (uint32)Controls the interpretation of WEP keys. Allowed values are NM_WEP_KEY_TYPE_KEY (1), in which case the key is either a 10- or 26-character hexadecimal string, or a 5- or 13-character ASCII password; or NM_WEP_KEY_TYPE_PASSPHRASE (2), in which case the passphrase is provided as a string and will be hashed using the de-facto MD5 method to derive the actual WEP key.wep-key0stringIndex 0 WEP key. This is the WEP key used in most networks. See the "wep-key-type" property for a description of how this key is interpreted.wep-key1stringIndex 1 WEP key. This WEP index is not used by most networks. See the "wep-key-type" property for a description of how this key is interpreted.wep-key2stringIndex 2 WEP key. This WEP index is not used by most networks. See the "wep-key-type" property for a description of how this key is interpreted.wep-key3stringIndex 3 WEP key. This WEP index is not used by most networks. See the "wep-key-type" property for a description of how this key is interpreted.wep-tx-keyidxuint320When static WEP is used (ie, key-mgmt = "none") and a non-default WEP key index is used by the AP, put that WEP key index here. Valid values are 0 (default key) through 3. Note that some consumer access points (like the Linksys WRT54G) number the keys 1 - 4.wps-methoduint320Flags indicating which mode of WPS is to be used if any. There's little point in changing the default setting as NetworkManager will automatically determine whether it's feasible to start WPS enrollment from the Access Point capabilities. WPS can be disabled by setting this property to a value of 1.wpan settingIEEE 802.15.4 (WPAN) MAC Settings.Key NameValue TypeDefault ValueValue Descriptionchannelint32-1IEEE 802.15.4 channel. A positive integer or -1, meaning "do not set, use whatever the device is already set to".mac-addressstringIf specified, this connection will only apply to the IEEE 802.15.4 (WPAN) MAC layer device whose permanent MAC address matches.pageint32-1IEEE 802.15.4 channel page. A positive integer or -1, meaning "do not set, use whatever the device is already set to".pan-iduint3265535IEEE 802.15.4 Personal Area Network (PAN) identifier.short-addressuint3265535Short IEEE 802.15.4 address to be used within a restricted environment.hostname settingHostname settings.Key NameValue TypeDefault ValueValue Descriptionfrom-dhcpNMTernary (int32)Whether the system hostname can be determined from DHCP on this connection. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).from-dns-lookupNMTernary (int32)Whether the system hostname can be determined from reverse DNS lookup of addresses on this device. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).only-from-defaultNMTernary (int32)If set to NM_TERNARY_TRUE (1), NetworkManager attempts to get the hostname via DHCPv4/DHCPv6 or reverse DNS lookup on this device only when the device has the default route for the given address family (IPv4/IPv6). If set to NM_TERNARY_FALSE (0), the hostname can be set from this device even if it doesn't have the default route. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_FALSE (0).priorityint320The relative priority of this connection to determine the system hostname. A lower numerical value is better (higher priority). A connection with higher priority is considered before connections with lower priority. If the value is zero, it can be overridden by a global value from NetworkManager configuration. If the property doesn't have a value in the global configuration, the value is assumed to be 100. Negative values have the special effect of excluding other connections with a greater numerical priority value; so in presence of at least one negative priority, only connections with the lowest priority value will be used to determine the hostname.ovs-external-ids settingOVS External IDs Settings.Key NameValue TypeDefault ValueValue Descriptiondatadict of string to string{}A dictionary of key/value pairs with exernal-ids for OVS.veth settingVeth Settings.Key NameValue TypeDefault ValueValue DescriptionpeerstringThis property specifies the peer interface name of the veth. This property is mandatory.Secret flag types: Each password or secret property in a setting has an associated flags property that describes how to handle that secret. The flags property is a bitfield that contains zero or more of the following values logically OR-ed together. diff --git a/man/nm-settings-docs-dbus.xml b/man/nm-settings-docs-dbus.xml index 84846fa..2491d8a 100644 --- a/man/nm-settings-docs-dbus.xml +++ b/man/nm-settings-docs-dbus.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/man/nm-settings-docs-nmcli.xml b/man/nm-settings-docs-nmcli.xml index c2c80db..c1d0430 100644 --- a/man/nm-settings-docs-nmcli.xml +++ b/man/nm-settings-docs-nmcli.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/man/nm-settings-ifcfg-rh.5 b/man/nm-settings-ifcfg-rh.5 index 2450760..60c50de 100644 --- a/man/nm-settings-ifcfg-rh.5 +++ b/man/nm-settings-ifcfg-rh.5 @@ -2,12 +2,12 @@ .\" Title: nm-settings-ifcfg-rh .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: Configuration -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NM\-SETTINGS\-IFCFG\-RH" "5" "" "NetworkManager 1\&.30\&.0" "Configuration" +.TH "NM\-SETTINGS\-IFCFG\-RH" "5" "" "NetworkManager 1\&.31\&.2" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -257,9 +257,9 @@ files for a single device, NM_CONTROLLED=no in one of the files will cause the d NetworkManager has introduced some new variable, not present in initscripts, to be able to store data for its new features\&. The variables are marked as extensions in the tables below\&. .RE .PP -\fBSemantic change of variables\fR +\fBSemantic change of variables and differences\fR .RS 4 -NetworkManager had to slightly change the semantic for a few variables\&. +NetworkManager changes the semantics for a few variables and there are other behavioral differences\&. .sp .RS 4 .ie n \{\ @@ -317,6 +317,20 @@ is used, NetworkManager assigns the interface 10\&.42\&.0\&.1, or it uses the fi HWADDR \- initscripts compare the currently set hardware address of a device, while NetworkManager considers the permanent one\&. .RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +NOZEROCONF +\- initscripts add an on\-link route to 169\&.254\&.0\&.0/16 for ethernet profiles that don\*(Aqt explicitly opt\-out by setting +NOZEROCONF +variable\&. NetworkManager does not do that\&. Instead a static, manual route with scope=253 (link) should be added to get that behavior\&. +.RE .RE .PP See the next section for detailed mapping of NetworkManager properties and @@ -3008,6 +3022,8 @@ l l l l l l l l l l l l l l l l +l l l l +l l l l l l l l. T{ port @@ -3125,6 +3141,26 @@ T}:T{ T}:T{ S390 device options\&. All options go to OPTIONS, except for "portname" and "ctcprot" that have their own variables\&. T} +T{ +wake\-on\-lan +T}:T{ +ETHTOOL_OPTS, ETHTOOL_WAKE_ON_LAN +T}:T{ +\ \& +T}:T{ +Wake on Lan mode for ethernet\&. The setting "ignore" is expressed with "ETHTOOL_WAKE_ON_LAN=ignore"\&. Otherwise, the "ETHTOOL_OPTS" variable is set with the value "wol" and several of the characters "p|u|m|b|a|g|s|f|d" as explained in the ethtool manual page\&. +T} +T{ +wake\-on\-lan\-password +T}:T{ +ETHTOOL_OPTS +T}:T{ +\ \& +T}:T{ +Password for secure\-on based Wake\-on\-Lan\&. It is added as "sopass" parameter in the ETHTOOL_OPTS variable\&.\fB + +Example: \fRETHTOOL_OPTS="wol gs sopass 00:11:22:33:44:55" +T} .TE .sp 1 .sp diff --git a/man/nm-settings-ifcfg-rh.xml b/man/nm-settings-ifcfg-rh.xml index 85c32da..1ed2cec 100644 --- a/man/nm-settings-ifcfg-rh.xml +++ b/man/nm-settings-ifcfg-rh.xml @@ -1,6 +1,6 @@ -nm-settings-ifcfg-rhNetworkManager developersnm-settings-ifcfg-rh5NetworkManagerConfiguration1.30.0nm-settings-ifcfg-rhDescription of ifcfg-rh settings pluginDescription +nm-settings-ifcfg-rhNetworkManager developersnm-settings-ifcfg-rh5NetworkManagerConfiguration1.31.2nm-settings-ifcfg-rhDescription of ifcfg-rh settings pluginDescription NetworkManager is based on the concept of connection profiles that contain network configuration (see nm-settings5 for details). The profiles can be stored in various formats. NetworkManager uses plugins for reading and writing @@ -145,8 +145,8 @@ DEVICETYPE=TeamPort NetworkManager has introduced some new variable, not present in initscripts, to be able to store data for its new features. The variables are marked as extensions in the tables below. - Semantic change of variables - NetworkManager had to slightly change the semantic for a few variables. + Semantic change of variables and differences + NetworkManager changes the semantics for a few variables and there are other behavioral differences. PEERDNS - initscripts interpret PEERDNS=no to mean "never touch resolv.conf". NetworkManager interprets it to say "never add automatic (DHCP, PPP, VPN, etc.) @@ -162,7 +162,11 @@ DEVICETYPE=TeamPort assigns the interface 10.42.0.1, or it uses the first static address, if configured.HWADDR - initscripts compare the currently set hardware address of a device, while - NetworkManager considers the permanent one. + NetworkManager considers the permanent one.NOZEROCONF - + initscripts add an on-link route to 169.254.0.0/16 for ethernet profiles that don't + explicitly opt-out by setting NOZEROCONF variable. NetworkManager does + not do that. Instead a static, manual route with scope=253 (link) should be added to get + that behavior. See the next section for detailed mapping of NetworkManager properties and ifcfg-rh variables. Variable names, format and usage differences in NetworkManager and initscripts are documented in the tables below. @@ -437,7 +441,9 @@ Example: SUBCHANNELS=0.0.b00a,0.0.b00b,0.0.b00cNETTYPE=qeth -Allowed values: "qeth", "lcs" or "ctc"s390-optionsOPTIONS and PORTNAME, CTCPROTO,S390 device options. All options go to OPTIONS, except for "portname" and "ctcprot" that have their own variables.wireguard settingPropertyIfcfg-rh VariableDefaultDescription
802-11-wireless-security settingPropertyIfcfg-rh VariableDefaultDescriptionkey-mgmtKEY_MGMT(+)Key management menthod. +Allowed values: "qeth", "lcs" or "ctc"s390-optionsOPTIONS and PORTNAME, CTCPROTO,S390 device options. All options go to OPTIONS, except for "portname" and "ctcprot" that have their own variables.wake-on-lanETHTOOL_OPTS, ETHTOOL_WAKE_ON_LANWake on Lan mode for ethernet. The setting "ignore" is expressed with "ETHTOOL_WAKE_ON_LAN=ignore". Otherwise, the "ETHTOOL_OPTS" variable is set with the value "wol" and several of the characters "p|u|m|b|a|g|s|f|d" as explained in the ethtool manual page.wake-on-lan-passwordETHTOOL_OPTSPassword for secure-on based Wake-on-Lan. It is added as "sopass" parameter in the ETHTOOL_OPTS variable. + +Example: ETHTOOL_OPTS="wol gs sopass 00:11:22:33:44:55"
wireguard settingPropertyIfcfg-rh VariableDefaultDescription
802-11-wireless-security settingPropertyIfcfg-rh VariableDefaultDescriptionkey-mgmtKEY_MGMT(+)Key management menthod. Allowed values: IEEE8021X, WPA-PSK, WPA-EAP, WPA-EAP-SUITE-B-192wep-tx-keyidxDEFAULTKEY1Index of active WEP key. diff --git a/man/nm-settings-ifcfg-rh.xsl b/man/nm-settings-ifcfg-rh.xsl index 13f4ad6..e11edab 100644 --- a/man/nm-settings-ifcfg-rh.xsl +++ b/man/nm-settings-ifcfg-rh.xsl @@ -228,9 +228,10 @@ DEVICETYPE=TeamPort - Semantic change of variables - - NetworkManager had to slightly change the semantic for a few variables. + Semantic change of variables and differences + + + NetworkManager changes the semantics for a few variables and there are other behavioral differences. PEERDNS - @@ -253,14 +254,22 @@ DEVICETYPE=TeamPort connection sharing. When shared is used, NetworkManager assigns the interface 10.42.0.1, or it uses the first static address, if configured. - + HWADDR - initscripts compare the currently set hardware address of a device, while NetworkManager considers the permanent one. + + NOZEROCONF - + initscripts add an on-link route to 169.254.0.0/16 for ethernet profiles that don't + explicitly opt-out by setting NOZEROCONF variable. NetworkManager does + not do that. Instead a static, manual route with scope=253 (link) should be added to get + that behavior. + - + + diff --git a/man/nm-settings-keyfile.5 b/man/nm-settings-keyfile.5 index 68638d4..73186e2 100644 --- a/man/nm-settings-keyfile.5 +++ b/man/nm-settings-keyfile.5 @@ -2,12 +2,12 @@ .\" Title: nm-settings-keyfile .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: Configuration -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NM\-SETTINGS\-KEYFILE" "5" "" "NetworkManager 1\&.30\&.0" "Configuration" +.TH "NM\-SETTINGS\-KEYFILE" "5" "" "NetworkManager 1\&.31\&.2" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-settings-keyfile.xml b/man/nm-settings-keyfile.xml index 0f41ea9..2b141b0 100644 --- a/man/nm-settings-keyfile.xml +++ b/man/nm-settings-keyfile.xml @@ -1,6 +1,6 @@ -nm-settings-keyfileNetworkManager developersnm-settings-keyfile5NetworkManagerConfiguration1.30.0nm-settings-keyfileDescription of keyfile settings pluginDescription +nm-settings-keyfileNetworkManager developersnm-settings-keyfile5NetworkManagerConfiguration1.31.2nm-settings-keyfileDescription of keyfile settings pluginDescription NetworkManager is based on the concept of connection profiles that contain network configuration (see nm-settings5 for details). The profiles can be stored in various formats. NetworkManager uses plugins for reading and writing diff --git a/man/nm-settings-nmcli.5 b/man/nm-settings-nmcli.5 index 89a61fa..2ff4088 100644 --- a/man/nm-settings-nmcli.5 +++ b/man/nm-settings-nmcli.5 @@ -2,12 +2,12 @@ .\" Title: nm-settings-nmcli .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: Configuration -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NM\-SETTINGS\-NMCLI" "5" "" "NetworkManager 1\&.30\&.0" "Configuration" +.TH "NM\-SETTINGS\-NMCLI" "5" "" "NetworkManager 1\&.31\&.2" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -1640,9 +1640,9 @@ Properties: .RS 4 Alias: ip4 .sp -Array of IP addresses\&. +A list of IPv4 addresses and their prefix length\&. Multiple addresses can be separated by comma\&. For example "192\&.168\&.1\&.5/24, 10\&.1\&.0\&.5/24"\&. .sp -Format: array of array of uint32 +Format: a comma separated list of addresses .RE .PP \fBdad\-timeout\fR @@ -1803,9 +1803,9 @@ Format: uint32 .PP \fBroutes\fR .RS 4 -Array of IP routes\&. +A list of IPv4 destination addresses, prefix length, optional IPv4 next hop addresses, optional route metric, optional attribute\&. The valid syntax is: "ip[/prefix] [next\-hop] [metric] [attribute=val]\&.\&.\&.[,ip[/prefix]\&.\&.\&.]"\&. For example "192\&.0\&.2\&.0/24 10\&.1\&.1\&.1 77, 198\&.51\&.100\&.0/24"\&. .sp -Format: array of array of uint32 +Format: a comma separated list of routes .RE .PP \fBrouting\-rules\fR @@ -2239,7 +2239,7 @@ Format: array of string .PP \fBkernel\-command\-line\fR .RS 4 -A list of kernel command line arguments to match\&. This may be used to check whether a specific kernel command line option is set (or if prefixed with the exclamation mark unset)\&. The argument must either be a single word, or an assignment (i\&.e\&. two words, separated "=")\&. In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment\&. In the latter case, the exact assignment is looked for with right and left hand side matching\&. See NMSettingMatch:interface\-name for how special characters \*(Aq|\*(Aq, \*(Aq&\*(Aq, \*(Aq!\*(Aq and \*(Aq\e\*(Aq are used for optional and mandatory matches and inverting the pattern\&. +A list of kernel command line arguments to match\&. This may be used to check whether a specific kernel command line option is set (or unset, if prefixed with the exclamation mark)\&. The argument must either be a single word, or an assignment (i\&.e\&. two words, joined by "=")\&. In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment\&. In the latter case, the exact assignment is looked for with right and left hand side matching\&. Wildcard patterns are not supported\&. See NMSettingMatch:interface\-name for how special characters \*(Aq|\*(Aq, \*(Aq&\*(Aq, \*(Aq!\*(Aq and \*(Aq\e\*(Aq are used for optional and mandatory matches and inverting the match\&. .sp Format: array of string .RE diff --git a/man/nm-settings-nmcli.xml b/man/nm-settings-nmcli.xml index 4cbdf0e..d61fa7e 100644 --- a/man/nm-settings-nmcli.xml +++ b/man/nm-settings-nmcli.xml @@ -1,6 +1,6 @@ -nm-settings-nmcliNetworkManager developersnm-settings-nmcli5NetworkManagerConfiguration1.30.0nm-settings-nmcliDescription of settings and properties of NetworkManager connection profiles for nmcliDescription +nm-settings-nmcliNetworkManager developersnm-settings-nmcli5NetworkManagerConfiguration1.31.2nm-settings-nmcliDescription of settings and properties of NetworkManager connection profiles for nmcliDescription NetworkManager is based on a concept of connection profiles, sometimes referred to as connections only. These connection profiles contain a network configuration. When NetworkManager activates a connection profile on a network device the configuration will @@ -274,8 +274,8 @@ Format: stringipv4 settingIPv4 Settings. Properties: - Alias: ip4Array of IP addresses. - Format: array of array of uint32Timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4. + Alias: ip4A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example "192.168.1.5/24, 10.1.0.5/24". + Format: a comma separated list of addressesTimeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4. Format: int32A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values "mac" and "perm-mac" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value "ipv6-duid" uses the DUID from "ipv6.dhcp-duid" property as an RFC4361-compliant client identifier. As IAID it uses "ipv4.dhcp-iaid" and falls back to "ipv6.dhcp-iaid" if unset. The special value "duid" generates a RFC4361-compliant client identifier based on "ipv4.dhcp-iaid" and uses a DUID generated by hashing /etc/machine-id. The special value "stable" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the "${DEVICE}" or "${MAC}" specifier to get a per-device key. If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin. Format: stringIf the "dhcp-send-hostname" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and "dhcp-hostname" are mutually exclusive and cannot be set at the same time. Format: stringIf the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time. @@ -298,8 +298,8 @@ Format: stringIf TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager. Format: booleanThe default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric. Format: int64Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager. - Format: uint32Array of IP routes. - Format: array of array of uint32ipv6 settingIPv6 Settings. + Format: uint32A list of IPv4 destination addresses, prefix length, optional IPv4 next hop addresses, optional route metric, optional attribute. The valid syntax is: "ip[/prefix] [next-hop] [metric] [attribute=val]...[,ip[/prefix]...]". For example "192.0.2.0/24 10.1.1.1 77, 198.51.100.0/24". + Format: a comma separated list of routesipv6 settingIPv6 Settings. Properties: Configure method for creating the address for use with RFC4862 IPv6 Stateless Address Autoconfiguration. The permitted values are: NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 (0) or NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY (1). If the property is set to EUI64, the addresses will be generated using the interface tokens derived from hardware address. This makes the host part of the address to stay constant, making it possible to track host's presence when it changes networks. The address changes when the interface hardware is replaced. The value of stable-privacy enables use of cryptographically secure hash of a secret host-specific key along with the connection's stable-id and the network address as specified by RFC7217. This makes it impossible to use the address track host's presence, and makes the address stable when the network interface hardware is replaced. On D-Bus, the absence of an addr-gen-mode setting equals enabling stable-privacy. For keyfile plugin, the absence of the setting on disk means EUI64 so that the property doesn't change on upgrade from older versions. Note that this setting is distinct from the Privacy Extensions as configured by "ip6-privacy" property and it does not affect the temporary addresses configured with this option. Format: int32 @@ -378,7 +378,7 @@ Properties: A list of driver names to match. Each element is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\' are used for optional and mandatory matches and inverting the pattern. Format: array of stringA list of interface names to match. Each element is a shell wildcard pattern. An element can be prefixed with a pipe symbol (|) or an ampersand (&). The former means that the element is optional and the latter means that it is mandatory. If there are any optional elements, than the match evaluates to true if at least one of the optional element matches (logical OR). If there are any mandatory elements, then they all must match (logical AND). By default, an element is optional. This means that an element "foo" behaves the same as "|foo". An element can also be inverted with exclamation mark (!) between the pipe symbol (or the ampersand) and before the pattern. Note that "!foo" is a shortcut for the mandatory match "&!foo". Finally, a backslash can be used at the beginning of the element (after the optional special characters) to escape the start of the pattern. For example, "&\!a" is an mandatory match for literally "!a". - Format: array of stringA list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or if prefixed with the exclamation mark unset). The argument must either be a single word, or an assignment (i.e. two words, separated "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\' are used for optional and mandatory matches and inverting the pattern. + Format: array of stringA list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or unset, if prefixed with the exclamation mark). The argument must either be a single word, or an assignment (i.e. two words, joined by "="). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. Wildcard patterns are not supported. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\' are used for optional and mandatory matches and inverting the match. Format: array of stringA list of paths to match against the ID_PATH udev property of devices. ID_PATH represents the topological persistent path of a device. It typically contains a subsystem string (pci, usb, platform, etc.) and a subsystem-specific identifier. For PCI devices the path has the form "pci-$domain:$bus:$device.$function", where each variable is an hexadecimal value; for example "pci-0000:0a:00.0". The path of a device can be obtained with "udevadm info /sys/class/net/$dev | grep ID_PATH=" or by looking at the "path" property exported by NetworkManager ("nmcli -f general.path device show $dev"). Each element of the list is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\' are used for optional and mandatory matches and inverting the pattern. Format: array of string802-11-olpc-mesh setting Alias: olpc-meshOLPC Wireless Mesh Settings. diff --git a/man/nmcli-examples.7 b/man/nmcli-examples.7 index 2a6ee8f..fb2946a 100644 --- a/man/nmcli-examples.7 +++ b/man/nmcli-examples.7 @@ -2,12 +2,12 @@ .\" Title: nmcli-examples .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: Examples -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NMCLI\-EXAMPLES" "7" "" "NetworkManager 1\&.30\&.0" "Examples" +.TH "NMCLI\-EXAMPLES" "7" "" "NetworkManager 1\&.31\&.2" "Examples" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nmcli.1 b/man/nmcli.1 index d7a01bc..087e561 100644 --- a/man/nmcli.1 +++ b/man/nmcli.1 @@ -2,12 +2,12 @@ .\" Title: nmcli .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: General Commands Manual -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NMCLI" "1" "" "NetworkManager 1\&.30\&.0" "General Commands Manual" +.TH "NMCLI" "1" "" "NetworkManager 1\&.31\&.2" "General Commands Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nmtui.1 b/man/nmtui.1 index 98db2b2..559373e 100644 --- a/man/nmtui.1 +++ b/man/nmtui.1 @@ -2,12 +2,12 @@ .\" Title: nmtui .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/18/2021 +.\" Date: 03/24/2021 .\" Manual: General Commands Manual -.\" Source: NetworkManager 1.30.0 +.\" Source: NetworkManager 1.31.2 .\" Language: English .\" -.TH "NMTUI" "1" "" "NetworkManager 1\&.30\&.0" "General Commands Manual" +.TH "NMTUI" "1" "" "NetworkManager 1\&.31\&.2" "General Commands Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/meson.build b/meson.build index 9fcb2f6..0b9a4be 100644 --- a/meson.build +++ b/meson.build @@ -4,9 +4,9 @@ project( 'NetworkManager', 'c', # NOTE: When incrementing version also: # - add corresponding NM_VERSION_x_y_z macros in -# "shared/nm-version-macros.h.in" +# "src/libnm-core-public/nm-version-macros.h.in" # - update number in configure.ac - version: '1.30.0', + version: '1.31.2', license: 'GPL2+', default_options: [ 'buildtype=debugoptimized', @@ -530,20 +530,23 @@ if polkit_agent_helper_1_path[0] != '/' endif config_h.set_quoted('POLKIT_AGENT_HELPER_1_PATH', polkit_agent_helper_1_path) - +crypto_nss_dep = dependency( + 'nss', + required: false, +) +crypto_gnutls_dep = dependency( + 'gnutls', + version: '>= 2.12', + required: false, +) crypto = get_option('crypto') if crypto == 'nss' - crypto_dep = dependency('nss', required: false) - assert(crypto_dep.found(), 'Requires nss crypto support') -elif crypto == 'gnutls' - crypto_dep = dependency( - 'gnutls', - version: '>= 2.12', - required: false, - ) - assert(crypto_dep.found(), 'Requires gnutls crypto support') + assert(crypto_nss_dep.found(), 'Requires nss crypto support') + crypto_dep = crypto_nss_dep else - error('bug') + assert(crypto == 'gnutls', 'Unexpected setting "crypto=' + crypto + '"') + assert(crypto_gnutls_dep.found(), 'Requires gnutls crypto support') + crypto_dep = crypto_gnutls_dep endif dbus_conf_dir = get_option('dbus_conf_dir') @@ -782,11 +785,17 @@ config_h.set('NM_MORE_ASSERTS', more_asserts) more_logging = get_option('more_logging') config_h.set10('NM_MORE_LOGGING', more_logging) -generic_support_src = 'int main() { int a = 0; int b = _Generic (a, int: 4); return b + a; };' -config_h.set10('_NM_CC_SUPPORT_GENERIC', cc.compiles(generic_support_src)) +config_h.set10('_NM_CC_SUPPORT_GENERIC', + cc.compiles( + 'int foo(void); static const char *const buf[1] = { "a" }; int foo() { int a = 0; int b = _Generic (a, int: 4) + _Generic(buf, const char *const*: 5); return b + a; }' + ) +) -auto_support_src = 'int main() { int a = 0; __auto_type b = a; return b + a; };' -config_h.set10('_NM_CC_SUPPORT_AUTO_TYPE', cc.compiles(auto_support_src)) +config_h.set10('_NM_CC_SUPPORT_AUTO_TYPE', + cc.compiles( + 'int main() { int a = 0; __auto_type b = a; return b + a; };' + ) +) # Vala bindings vapi_opt = get_option('vapi') @@ -916,12 +925,7 @@ fi content_files = [] subdir('introspection') -subdir('shared') -subdir('libnm-core') -subdir('src/core') -subdir('libnm') -subdir('dispatcher') -subdir('clients') +subdir('src') subdir('data') subdir('po') diff --git a/po/POTFILES.in b/po/POTFILES.in index 21507ee..ac1bd52 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,160 +1,8 @@ [encoding: UTF-8] # List of source files containing translatable strings. # Please keep this file sorted alphabetically. -clients/cli/agent.c -clients/cli/common.c -clients/cli/connections.c -clients/cli/devices.c -clients/cli/general.c -clients/cli/nmcli.c -clients/cli/polkit-agent.c -clients/cli/settings.c -clients/cli/utils.c -clients/cli/utils.h -clients/common/nm-client-utils.c -clients/common/nm-meta-setting-access.c -clients/common/nm-meta-setting-desc.c -clients/common/nm-polkit-listener.c -clients/common/nm-secret-agent-simple.c -clients/common/nm-vpn-helpers.c -clients/common/settings-docs.h.in -clients/nm-online.c -clients/tui/newt/nmt-newt-utils.c -clients/tui/nm-editor-utils.c -clients/tui/nmt-connect-connection-list.c -clients/tui/nmt-device-entry.c -clients/tui/nmt-edit-connection-list.c -clients/tui/nmt-editor-section.c -clients/tui/nmt-editor.c -clients/tui/nmt-mtu-entry.c -clients/tui/nmt-page-bond.c -clients/tui/nmt-page-bridge-port.c -clients/tui/nmt-page-bridge.c -clients/tui/nmt-page-dsl.c -clients/tui/nmt-page-ethernet.c -clients/tui/nmt-page-infiniband.c -clients/tui/nmt-page-ip4.c -clients/tui/nmt-page-ip6.c -clients/tui/nmt-page-ip-tunnel.c -clients/tui/nmt-page-ppp.c -clients/tui/nmt-page-team-port.c -clients/tui/nmt-page-team.c -clients/tui/nmt-page-vlan.c -clients/tui/nmt-page-wifi.c -clients/tui/nmt-password-dialog.c -clients/tui/nmt-password-fields.c -clients/tui/nmt-route-editor.c -clients/tui/nmt-route-table.c -clients/tui/nmt-slave-list.c -clients/tui/nmt-widget-list.c -clients/tui/nmtui-connect.c -clients/tui/nmtui-edit.c -clients/tui/nmtui-hostname.c -clients/tui/nmtui.c -libnm-core/nm-crypto.c -libnm-core/nm-crypto-gnutls.c -libnm-core/nm-crypto-nss.c -libnm-core/nm-connection.c -libnm-core/nm-dbus-utils.c -libnm-core/nm-keyfile-utils.c -libnm-core/nm-keyfile.c -libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c -libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c -libnm-core/nm-setting-6lowpan.c -libnm-core/nm-setting-8021x.c -libnm-core/nm-setting-adsl.c -libnm-core/nm-setting-bluetooth.c -libnm-core/nm-setting-bond.c -libnm-core/nm-setting-bridge-port.c -libnm-core/nm-setting-bridge.c -libnm-core/nm-setting-cdma.c -libnm-core/nm-setting-connection.c -libnm-core/nm-setting-dcb.c -libnm-core/nm-setting-ethtool.c -libnm-core/nm-setting-gsm.c -libnm-core/nm-setting-infiniband.c -libnm-core/nm-setting-ip-config.c -libnm-core/nm-setting-ip-tunnel.c -libnm-core/nm-setting-ip4-config.c -libnm-core/nm-setting-ip6-config.c -libnm-core/nm-setting-macsec.c -libnm-core/nm-setting-macvlan.c -libnm-core/nm-setting-match.c -libnm-core/nm-setting-olpc-mesh.c -libnm-core/nm-setting-ovs-bridge.c -libnm-core/nm-setting-ovs-external-ids.c -libnm-core/nm-setting-ovs-interface.c -libnm-core/nm-setting-ovs-patch.c -libnm-core/nm-setting-ovs-port.c -libnm-core/nm-setting-ppp.c -libnm-core/nm-setting-pppoe.c -libnm-core/nm-setting-proxy.c -libnm-core/nm-setting-sriov.c -libnm-core/nm-setting-tc-config.c -libnm-core/nm-setting-team-port.c -libnm-core/nm-setting-team.c -libnm-core/nm-setting-tun.c -libnm-core/nm-setting-user.c -libnm-core/nm-setting-veth.c -libnm-core/nm-setting-vlan.c -libnm-core/nm-setting-vrf.c -libnm-core/nm-setting-vpn.c -libnm-core/nm-setting-vxlan.c -libnm-core/nm-setting-wifi-p2p.c -libnm-core/nm-setting-wimax.c -libnm-core/nm-setting-wired.c -libnm-core/nm-setting-wireguard.c -libnm-core/nm-setting-wireless-security.c -libnm-core/nm-setting-wireless.c -libnm-core/nm-setting-wpan.c -libnm-core/nm-setting.c -libnm-core/nm-team-utils.c -libnm-core/nm-utils.c -libnm-core/nm-vpn-editor-plugin.c -libnm-core/nm-vpn-plugin-info.c -libnm/nm-client.c -libnm/nm-device-6lowpan.c -libnm/nm-device-adsl.c -libnm/nm-device-bond.c -libnm/nm-device-bridge.c -libnm/nm-device-bt.c -libnm/nm-device-dummy.c -libnm/nm-device-ethernet.c -libnm/nm-device-generic.c -libnm/nm-device-infiniband.c -libnm/nm-device-ip-tunnel.c -libnm/nm-device-macvlan.c -libnm/nm-device-modem.c -libnm/nm-device-olpc-mesh.c -libnm/nm-device-ovs-bridge.c -libnm/nm-device-ovs-interface.c -libnm/nm-device-ovs-port.c -libnm/nm-device-team.c -libnm/nm-device-tun.c -libnm/nm-device-veth.c -libnm/nm-device-vlan.c -libnm/nm-device-vrf.c -libnm/nm-device-vxlan.c -libnm/nm-device-wifi-p2p.c -libnm/nm-device-wifi.c -libnm/nm-device-wimax.c -libnm/nm-device-wpan.c -libnm/nm-device.c -libnm/nm-object.c -libnm/nm-remote-connection.c -libnm/nm-secret-agent-old.c -libnm/nm-vpn-plugin-old.c -libnm/nm-vpn-service-plugin.c data/org.freedesktop.NetworkManager.policy.in.in -shared/nm-glib-aux/nm-shared-utils.c -shared/nm-log-core/nm-logging.c src/core/NetworkManagerUtils.c -src/core/main.c -src/core/main-utils.c -src/core/dhcp/nm-dhcp-dhclient.c -src/core/dhcp/nm-dhcp-dhclient-utils.c -src/core/dhcp/nm-dhcp-manager.c -src/core/dns/nm-dns-manager.c src/core/devices/adsl/nm-device-adsl.c src/core/devices/bluetooth/nm-bluez-manager.c src/core/devices/bluetooth/nm-device-bt.c @@ -162,8 +10,8 @@ src/core/devices/nm-device-6lowpan.c src/core/devices/nm-device-bond.c src/core/devices/nm-device-bridge.c src/core/devices/nm-device-dummy.c -src/core/devices/nm-device-ethernet.c src/core/devices/nm-device-ethernet-utils.c +src/core/devices/nm-device-ethernet.c src/core/devices/nm-device-infiniband.c src/core/devices/nm-device-ip-tunnel.c src/core/devices/nm-device-macvlan.c @@ -178,8 +26,160 @@ src/core/devices/wifi/nm-device-olpc-mesh.c src/core/devices/wifi/nm-device-wifi.c src/core/devices/wifi/nm-wifi-utils.c src/core/devices/wwan/nm-modem-broadband.c +src/core/dhcp/nm-dhcp-dhclient-utils.c +src/core/dhcp/nm-dhcp-dhclient.c +src/core/dhcp/nm-dhcp-manager.c +src/core/dns/nm-dns-manager.c +src/core/main-utils.c +src/core/main.c src/core/nm-config.c src/core/nm-iface-helper.c src/core/nm-manager.c src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +src/libnm-client-impl/nm-client.c +src/libnm-client-impl/nm-device-6lowpan.c +src/libnm-client-impl/nm-device-adsl.c +src/libnm-client-impl/nm-device-bond.c +src/libnm-client-impl/nm-device-bridge.c +src/libnm-client-impl/nm-device-bt.c +src/libnm-client-impl/nm-device-dummy.c +src/libnm-client-impl/nm-device-ethernet.c +src/libnm-client-impl/nm-device-generic.c +src/libnm-client-impl/nm-device-infiniband.c +src/libnm-client-impl/nm-device-ip-tunnel.c +src/libnm-client-impl/nm-device-macvlan.c +src/libnm-client-impl/nm-device-modem.c +src/libnm-client-impl/nm-device-olpc-mesh.c +src/libnm-client-impl/nm-device-ovs-bridge.c +src/libnm-client-impl/nm-device-ovs-interface.c +src/libnm-client-impl/nm-device-ovs-port.c +src/libnm-client-impl/nm-device-team.c +src/libnm-client-impl/nm-device-tun.c +src/libnm-client-impl/nm-device-veth.c +src/libnm-client-impl/nm-device-vlan.c +src/libnm-client-impl/nm-device-vrf.c +src/libnm-client-impl/nm-device-vxlan.c +src/libnm-client-impl/nm-device-wifi-p2p.c +src/libnm-client-impl/nm-device-wifi.c +src/libnm-client-impl/nm-device-wimax.c +src/libnm-client-impl/nm-device-wpan.c +src/libnm-client-impl/nm-device.c +src/libnm-client-impl/nm-object.c +src/libnm-client-impl/nm-remote-connection.c +src/libnm-client-impl/nm-secret-agent-old.c +src/libnm-client-impl/nm-vpn-plugin-old.c +src/libnm-client-impl/nm-vpn-service-plugin.c +src/libnm-core-aux-extern/nm-libnm-core-aux.c +src/libnm-core-aux-intern/nm-libnm-core-utils.c +src/libnm-core-impl/nm-connection.c +src/libnm-core-impl/nm-crypto-gnutls.c +src/libnm-core-impl/nm-crypto-nss.c +src/libnm-core-impl/nm-crypto.c +src/libnm-core-impl/nm-dbus-utils.c +src/libnm-core-impl/nm-keyfile-utils.c +src/libnm-core-impl/nm-keyfile.c +src/libnm-core-impl/nm-setting-6lowpan.c +src/libnm-core-impl/nm-setting-8021x.c +src/libnm-core-impl/nm-setting-adsl.c +src/libnm-core-impl/nm-setting-bluetooth.c +src/libnm-core-impl/nm-setting-bond.c +src/libnm-core-impl/nm-setting-bridge-port.c +src/libnm-core-impl/nm-setting-bridge.c +src/libnm-core-impl/nm-setting-cdma.c +src/libnm-core-impl/nm-setting-connection.c +src/libnm-core-impl/nm-setting-dcb.c +src/libnm-core-impl/nm-setting-ethtool.c +src/libnm-core-impl/nm-setting-gsm.c +src/libnm-core-impl/nm-setting-infiniband.c +src/libnm-core-impl/nm-setting-ip-config.c +src/libnm-core-impl/nm-setting-ip-tunnel.c +src/libnm-core-impl/nm-setting-ip4-config.c +src/libnm-core-impl/nm-setting-ip6-config.c +src/libnm-core-impl/nm-setting-macsec.c +src/libnm-core-impl/nm-setting-macvlan.c +src/libnm-core-impl/nm-setting-match.c +src/libnm-core-impl/nm-setting-olpc-mesh.c +src/libnm-core-impl/nm-setting-ovs-bridge.c +src/libnm-core-impl/nm-setting-ovs-external-ids.c +src/libnm-core-impl/nm-setting-ovs-interface.c +src/libnm-core-impl/nm-setting-ovs-patch.c +src/libnm-core-impl/nm-setting-ovs-port.c +src/libnm-core-impl/nm-setting-ppp.c +src/libnm-core-impl/nm-setting-pppoe.c +src/libnm-core-impl/nm-setting-proxy.c +src/libnm-core-impl/nm-setting-sriov.c +src/libnm-core-impl/nm-setting-tc-config.c +src/libnm-core-impl/nm-setting-team-port.c +src/libnm-core-impl/nm-setting-team.c +src/libnm-core-impl/nm-setting-tun.c +src/libnm-core-impl/nm-setting-user.c +src/libnm-core-impl/nm-setting-veth.c +src/libnm-core-impl/nm-setting-vlan.c +src/libnm-core-impl/nm-setting-vpn.c +src/libnm-core-impl/nm-setting-vrf.c +src/libnm-core-impl/nm-setting-vxlan.c +src/libnm-core-impl/nm-setting-wifi-p2p.c +src/libnm-core-impl/nm-setting-wimax.c +src/libnm-core-impl/nm-setting-wired.c +src/libnm-core-impl/nm-setting-wireguard.c +src/libnm-core-impl/nm-setting-wireless-security.c +src/libnm-core-impl/nm-setting-wireless.c +src/libnm-core-impl/nm-setting-wpan.c +src/libnm-core-impl/nm-setting.c +src/libnm-core-impl/nm-team-utils.c +src/libnm-core-impl/nm-utils.c +src/libnm-core-impl/nm-vpn-editor-plugin.c +src/libnm-core-impl/nm-vpn-plugin-info.c +src/libnm-glib-aux/nm-shared-utils.c +src/libnm-log-core/nm-logging.c +src/libnmc-base/nm-client-utils.c +src/libnmc-base/nm-polkit-listener.c +src/libnmc-base/nm-secret-agent-simple.c +src/libnmc-base/nm-vpn-helpers.c +src/libnmc-setting/nm-meta-setting-access.c +src/libnmc-setting/nm-meta-setting-desc.c +src/libnmc-setting/settings-docs.h.in +src/libnmt-newt/nmt-newt-utils.c +src/nm-online/nm-online.c +src/nmcli/agent.c +src/nmcli/common.c +src/nmcli/connections.c +src/nmcli/devices.c +src/nmcli/general.c +src/nmcli/nmcli.c +src/nmcli/polkit-agent.c +src/nmcli/settings.c +src/nmcli/utils.c +src/nmcli/utils.h +src/nmtui/nm-editor-utils.c +src/nmtui/nmt-connect-connection-list.c +src/nmtui/nmt-device-entry.c +src/nmtui/nmt-edit-connection-list.c +src/nmtui/nmt-editor-section.c +src/nmtui/nmt-editor.c +src/nmtui/nmt-mtu-entry.c +src/nmtui/nmt-page-bond.c +src/nmtui/nmt-page-bridge-port.c +src/nmtui/nmt-page-bridge.c +src/nmtui/nmt-page-dsl.c +src/nmtui/nmt-page-ethernet.c +src/nmtui/nmt-page-infiniband.c +src/nmtui/nmt-page-ip-tunnel.c +src/nmtui/nmt-page-ip4.c +src/nmtui/nmt-page-ip6.c +src/nmtui/nmt-page-ppp.c +src/nmtui/nmt-page-team-port.c +src/nmtui/nmt-page-team.c +src/nmtui/nmt-page-vlan.c +src/nmtui/nmt-page-wifi.c +src/nmtui/nmt-password-dialog.c +src/nmtui/nmt-password-fields.c +src/nmtui/nmt-route-editor.c +src/nmtui/nmt-route-table.c +src/nmtui/nmt-slave-list.c +src/nmtui/nmt-widget-list.c +src/nmtui/nmtui-connect.c +src/nmtui/nmtui-edit.c +src/nmtui/nmtui-hostname.c +src/nmtui/nmtui.c diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 425b100..692aa74 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -1,12 +1,12 @@ -clients/cloud-setup/nm-cloud-setup.service.in contrib/fedora/rpm/ data/NetworkManager-wait-online.service.in data/NetworkManager.service.in data/org.freedesktop.NetworkManager.policy.in examples/python/NetworkManager.py examples/python/systray/eggtrayicon.c -shared/nm-utils/nm-vpn-editor-plugin-call.h -shared/nm-utils/nm-vpn-plugin-utils.c +src/contrib/nm-vpn-editor-plugin-call.h +src/contrib/nm-vpn-plugin-utils.c +src/nm-cloud-setup/nm-cloud-setup.service.in vpn-daemons/openvpn vpn-daemons/pptp vpn-daemons/vpnc diff --git a/po/uk.po b/po/uk.po index f5713db..ecd85d8 100644 --- a/po/uk.po +++ b/po/uk.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues\n" -"POT-Creation-Date: 2021-02-10 03:28+0000\n" -"PO-Revision-Date: 2021-02-10 11:26+0200\n" +"POT-Creation-Date: 2021-02-24 03:27+0000\n" +"PO-Revision-Date: 2021-02-24 09:39+0200\n" "Last-Translator: Yuri Chornoivan \n" "Language-Team: Ukrainian \n" "Language: uk\n" @@ -4774,7 +4774,7 @@ msgid "invalid option '%s', use a combination of [%s]" msgstr "некоректний параметр «%s», скористайтеся комбінацією [%s]" #: ../clients/common/nm-meta-setting-desc.c:1623 -#: ../libnm-core/nm-keyfile.c:1103 +#: ../src/libnm-core-impl/nm-keyfile.c:1103 #, c-format msgid "invalid option '%s', use one of [%s]" msgstr "" @@ -4855,8 +4855,8 @@ msgstr "" "номерів)" #: ../clients/common/nm-meta-setting-desc.c:2107 -#: ../clients/common/nm-meta-setting-desc.c:4103 -#: ../libnm-core/nm-setting-ovs-bridge.c:187 ../src/core/nm-config.c:548 +#: ../clients/common/nm-meta-setting-desc.c:4103 ../src/core/nm-config.c:548 +#: ../src/libnm-core-impl/nm-setting-ovs-bridge.c:187 #, c-format msgid "'%s' is not valid" msgstr "«%s» не є коректним" @@ -5066,10 +5066,13 @@ msgid "'%ld' is not a valid channel" msgstr "«%ld» не є коректним каналом" #: ../clients/common/nm-meta-setting-desc.c:4053 -#: ../libnm-core/nm-setting-sriov.c:424 ../libnm-core/nm-setting-wired.c:753 -#: ../libnm-core/nm-setting-wired.c:769 ../libnm-core/nm-setting-wired.c:833 -#: ../libnm-core/nm-setting-wired.c:891 ../libnm-core/nm-setting-wireless.c:944 -#: ../libnm-core/nm-setting-wireless.c:963 +#: ../src/libnm-core-impl/nm-setting-sriov.c:424 +#: ../src/libnm-core-impl/nm-setting-wired.c:753 +#: ../src/libnm-core-impl/nm-setting-wired.c:769 +#: ../src/libnm-core-impl/nm-setting-wired.c:833 +#: ../src/libnm-core-impl/nm-setting-wired.c:891 +#: ../src/libnm-core-impl/nm-setting-wireless.c:944 +#: ../src/libnm-core-impl/nm-setting-wireless.c:963 #, c-format msgid "'%s' is not a valid MAC address" msgstr "%s не є припустимою MAC-адресою" @@ -7118,13 +7121,15 @@ msgid "" "wpa_supplicant documentation for more details. Both \"phase2-auth\" and " "\"phase2-autheap\" cannot be specified." msgstr "" -"Визначає дозволені способи внутрішнього розпізнавання, " -"якщо у властивості «eap» вказано спосіб EAP, який використовує внутрішній " -"тунель TLS. Для TLS ця властивість вибирає один із не пов'язаних із EAP методів «phase 2» є «pap», «chap», " -"«mschap», «mschapv2», а «phase2-autheap» вибирає внутрішній метод EAP. Для PEAP цей параметр вибирає внутрішній метод EAP, один із таких варіантів: «gtc», «otp», «md5» і «tls». Для успішного " -"розпізнавання для кожного з внутрішніх способів «phase 2» слід вказати " -"специфічні параметри. Докладніший опис параметрів можна знайти у " -"документації з wpa_supplicant. Не можна одночасно вказувати «phase2-auth» і «phase2-autheap»." +"Визначає дозволені способи внутрішнього розпізнавання, якщо у властивості " +"«eap» вказано спосіб EAP, який використовує внутрішній тунель TLS. Для TLS " +"ця властивість вибирає один із не пов'язаних із EAP методів «phase 2» є " +"«pap», «chap», «mschap», «mschapv2», а «phase2-autheap» вибирає внутрішній " +"метод EAP. Для PEAP цей параметр вибирає внутрішній метод EAP, один із таких " +"варіантів: «gtc», «otp», «md5» і «tls». Для успішного розпізнавання для " +"кожного з внутрішніх способів «phase 2» слід вказати специфічні параметри. " +"Докладніший опис параметрів можна знайти у документації з wpa_supplicant. Не " +"можна одночасно вказувати «phase2-auth» і «phase2-autheap»." #: ../clients/common/settings-docs.h.in:71 msgid "" @@ -7135,10 +7140,11 @@ msgid "" "authentication; see the wpa_supplicant documentation for more details." msgstr "" "Визначає дозволені способи внутрішнього розпізнавання на основі EAP, якщо у " -"властивості «eap» вказано TTLS. Відомими програмі способами «phase 2» на основі EAP є «md5», " -"«mschapv2», «otp», «gtc» і «tls». Для успішного розпізнавання для кожного з " -"внутрішніх способів «phase 2» слід вказати специфічні параметри. Докладніший " -"опис параметрів можна знайти у документації з wpa_supplicant." +"властивості «eap» вказано TTLS. Відомими програмі способами «phase 2» на " +"основі EAP є «md5», «mschapv2», «otp», «gtc» і «tls». Для успішного " +"розпізнавання для кожного з внутрішніх способів «phase 2» слід вказати " +"специфічні параметри. Докладніший опис параметрів можна знайти у " +"документації з wpa_supplicant." #: ../clients/common/settings-docs.h.in:72 msgid "" @@ -8923,9 +8929,11 @@ msgstr "" "значення, яке означає, що пакети успадковують значення TTL." #: ../clients/common/settings-docs.h.in:228 -#: ../clients/common/settings-docs.h.in:253 -msgid "Array of IP addresses." -msgstr "Масив IP-адрес." +msgid "" +"A list of IPv4 addresses and their prefix length. Multiple addresses can be " +"separated by comma. For example \"192.168.1.5/24, 10.1.0.5/24\"." +msgstr "" +"Список адрес IPv4 та їхніх довжин префікса. Декілька адрес можна відокремлювати комами. Приклад: \"192.168.1.5/24, 10.1.0.5/24\"." #: ../clients/common/settings-docs.h.in:229 #: ../clients/common/settings-docs.h.in:254 @@ -9176,7 +9184,9 @@ msgstr "" "reload», «no-tld-query», «rotate», «single-request», «single-request-" "reopen», «timeout», «trust-ad», «use-vc». Варіант «trust-ad» буде взято до " "уваги, лише якщо профіль вказує сервери назв у resolv.conf і для всіх " -"відповідних профілів увімкнено «trust-ad». Якщо використано додаток DNS із кешуванням (dnsmasq або systemd-resolved у NetworkManager.conf), «edns0» і «trust-ad» буде додано автоматично." +"відповідних профілів увімкнено «trust-ad». Якщо використано додаток DNS із " +"кешуванням (dnsmasq або systemd-resolved у NetworkManager.conf), «edns0» і " +"«trust-ad» буде додано автоматично." #: ../clients/common/settings-docs.h.in:241 #: ../clients/common/settings-docs.h.in:264 @@ -9436,9 +9446,14 @@ msgstr "" "які змінюють таблиці маршрутизації з-поза меж NetworkManager." #: ../clients/common/settings-docs.h.in:251 -#: ../clients/common/settings-docs.h.in:276 -msgid "Array of IP routes." -msgstr "Масив IP-маршрутів." +msgid "" +"A list of IPv4 destination addresses, prefix length, optional IPv4 next hop " +"addresses, optional route metric, optional attribute. The valid syntax is: " +"\"ip[/prefix] [next-hop] [metric] [attribute=val]...[,ip[/prefix]...]\". For " +"example \"192.0.2.0/24 10.1.1.1 77, 198.51.100.0/24\"." +msgstr "" +"Список адрес призначення IPv4, довжин префіксів, додаткових адрес IPv4 наступного переходу, додаткових даних метрики маршруту, додаткових атрибутів. Коректний синтаксис: " +"\"ip[/префікс] [наступний-перехід] [метрика] [атрибут=значення]...[,ip[/префікс]...]\". Приклад: \"192.0.2.0/24 10.1.1.1 77, 198.51.100.0/24\"." #: ../clients/common/settings-docs.h.in:252 msgid "" @@ -9481,6 +9496,10 @@ msgstr "" "конфіденційності, які налаштовуються властивістю «ip6-privacy», і не впливає " "на тимчасові адреси, які налаштовано за допомогою відповідної властивості." +#: ../clients/common/settings-docs.h.in:253 +msgid "Array of IP addresses." +msgstr "Масив IP-адрес." + #: ../clients/common/settings-docs.h.in:255 msgid "" "A string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp " @@ -9582,6 +9601,10 @@ msgstr "" "залежатиме від параметрів sysctl пристрою. Встановіть значення 2147483647 " "(MAXINT32), якщо час очікування має бути необмеженим." +#: ../clients/common/settings-docs.h.in:276 +msgid "Array of IP routes." +msgstr "Масив IP-маршрутів." + #: ../clients/common/settings-docs.h.in:277 msgid "" "Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02 IPv6 " @@ -10866,8 +10889,8 @@ msgstr "Wi-Fi" msgid "Wi-Fi connection %d" msgstr "З'єднання Wi-Fi %d" -#: ../clients/tui/nm-editor-utils.c:153 ../libnm-core/nm-connection.c:2704 -#: ../libnm/nm-device.c:1673 +#: ../clients/tui/nm-editor-utils.c:153 ../libnm/nm-device.c:1673 +#: ../src/libnm-core-impl/nm-connection.c:2704 msgid "InfiniBand" msgstr "InfiniBand" @@ -10894,9 +10917,9 @@ msgstr "DSL" msgid "DSL connection %d" msgstr "З'єднання DSL %d" -#: ../clients/tui/nm-editor-utils.c:180 ../libnm-core/nm-connection.c:2696 -#: ../libnm/nm-device.c:1675 +#: ../clients/tui/nm-editor-utils.c:180 ../libnm/nm-device.c:1675 #: ../src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c:5467 +#: ../src/libnm-core-impl/nm-connection.c:2696 msgid "Bond" msgstr "Прив'язка" @@ -10905,9 +10928,9 @@ msgstr "Прив'язка" msgid "Bond connection %d" msgstr "Прив'язане з'єднання %d" -#: ../clients/tui/nm-editor-utils.c:189 ../libnm-core/nm-connection.c:2700 -#: ../libnm/nm-device.c:1679 +#: ../clients/tui/nm-editor-utils.c:189 ../libnm/nm-device.c:1679 #: ../src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c:5875 +#: ../src/libnm-core-impl/nm-connection.c:2700 msgid "Bridge" msgstr "Місток" @@ -10916,9 +10939,9 @@ msgstr "Місток" msgid "Bridge connection %d" msgstr "З'єднання містка %d" -#: ../clients/tui/nm-editor-utils.c:198 ../libnm-core/nm-connection.c:2698 -#: ../libnm/nm-device.c:1677 +#: ../clients/tui/nm-editor-utils.c:198 ../libnm/nm-device.c:1677 #: ../src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c:5538 +#: ../src/libnm-core-impl/nm-connection.c:2698 msgid "Team" msgstr "Команда" @@ -10928,7 +10951,7 @@ msgid "Team connection %d" msgstr "Командне з'єднання %d" #: ../clients/tui/nm-editor-utils.c:207 ../clients/tui/nmt-page-vlan.c:64 -#: ../libnm-core/nm-connection.c:2702 ../libnm/nm-device.c:1681 +#: ../libnm/nm-device.c:1681 ../src/libnm-core-impl/nm-connection.c:2702 msgid "VLAN" msgstr "VLAN" @@ -11204,6 +11227,63 @@ msgstr "INFINIBAND" msgid "Transport mode" msgstr "Режим передавання" +#. The order must match the NM_IP_TUNNEL_MODE_* enum +#: ../clients/tui/nmt-page-ip-tunnel.c:64 +msgid "IPIP" +msgstr "IPIP" + +#: ../clients/tui/nmt-page-ip-tunnel.c:65 +msgid "GRE" +msgstr "GRE" + +#: ../clients/tui/nmt-page-ip-tunnel.c:66 +msgid "SIT" +msgstr "SIT" + +#: ../clients/tui/nmt-page-ip-tunnel.c:67 +msgid "ISATAP" +msgstr "ISATAP" + +#: ../clients/tui/nmt-page-ip-tunnel.c:68 +msgid "VTI" +msgstr "VTI" + +#: ../clients/tui/nmt-page-ip-tunnel.c:69 +msgid "IP6IP6" +msgstr "IP6IP6" + +#: ../clients/tui/nmt-page-ip-tunnel.c:70 +msgid "IPIP6" +msgstr "IPIP6" + +#: ../clients/tui/nmt-page-ip-tunnel.c:71 +msgid "IP6GRE" +msgstr "IP6GRE" + +#: ../clients/tui/nmt-page-ip-tunnel.c:72 +msgid "VTI6" +msgstr "VTI6" + +#: ../clients/tui/nmt-page-ip-tunnel.c:133 ../clients/tui/nmt-page-vlan.c:69 +msgid "Parent" +msgstr "Батьківський" + +#: ../clients/tui/nmt-page-ip-tunnel.c:142 +msgid "Local IP" +msgstr "Локальна адреса IP" + +#: ../clients/tui/nmt-page-ip-tunnel.c:150 +msgid "Remote IP" +msgstr "Віддалений IP" + +#: ../clients/tui/nmt-page-ip-tunnel.c:158 +msgid "Input key" +msgstr "Вхідний ключ" + +#: ../clients/tui/nmt-page-ip-tunnel.c:167 +msgid "Output key" +msgstr "Вихідний ключ" + #: ../clients/tui/nmt-page-ip4.c:25 ../clients/tui/nmt-page-ip6.c:30 msgid "Disabled" msgstr "Вимкнено" @@ -11289,63 +11369,6 @@ msgstr "НАЛАШТУВАННЯ IPv6" msgid "Require IPv6 addressing for this connection" msgstr "Для цього з'єднання потрібне адресування IPv6" -#. The order must match the NM_IP_TUNNEL_MODE_* enum -#: ../clients/tui/nmt-page-ip-tunnel.c:64 -msgid "IPIP" -msgstr "IPIP" - -#: ../clients/tui/nmt-page-ip-tunnel.c:65 -msgid "GRE" -msgstr "GRE" - -#: ../clients/tui/nmt-page-ip-tunnel.c:66 -msgid "SIT" -msgstr "SIT" - -#: ../clients/tui/nmt-page-ip-tunnel.c:67 -msgid "ISATAP" -msgstr "ISATAP" - -#: ../clients/tui/nmt-page-ip-tunnel.c:68 -msgid "VTI" -msgstr "VTI" - -#: ../clients/tui/nmt-page-ip-tunnel.c:69 -msgid "IP6IP6" -msgstr "IP6IP6" - -#: ../clients/tui/nmt-page-ip-tunnel.c:70 -msgid "IPIP6" -msgstr "IPIP6" - -#: ../clients/tui/nmt-page-ip-tunnel.c:71 -msgid "IP6GRE" -msgstr "IP6GRE" - -#: ../clients/tui/nmt-page-ip-tunnel.c:72 -msgid "VTI6" -msgstr "VTI6" - -#: ../clients/tui/nmt-page-ip-tunnel.c:133 ../clients/tui/nmt-page-vlan.c:69 -msgid "Parent" -msgstr "Батьківський" - -#: ../clients/tui/nmt-page-ip-tunnel.c:142 -msgid "Local IP" -msgstr "Локальна адреса IP" - -#: ../clients/tui/nmt-page-ip-tunnel.c:150 -msgid "Remote IP" -msgstr "Віддалений IP" - -#: ../clients/tui/nmt-page-ip-tunnel.c:158 -msgid "Input key" -msgstr "Вхідний ключ" - -#: ../clients/tui/nmt-page-ip-tunnel.c:167 -msgid "Output key" -msgstr "Вихідний ключ" - #: ../clients/tui/nmt-page-ppp.c:116 msgid "PPP CONFIGURATION" msgstr "НАЛАШТУВАННЯ PPP" @@ -11747,3720 +11770,3784 @@ msgstr "Не вдалося обробити ПАРАМЕТРИ" msgid "Could not contact NetworkManager: %s.\n" msgstr "Не вдалося зв'язатися із NetworkManager: %s.\n" -#: ../libnm-core/nm-crypto.c:208 -#, c-format -msgid "PEM key file had no start tag" -msgstr "У файлі ключа PEM не міститься початкового теґу" - -#: ../libnm-core/nm-crypto.c:217 -#, c-format -msgid "PEM key file had no end tag '%s'." -msgstr "У файлі ключа PEM не міститься завершального теґу «%s»." - -#: ../libnm-core/nm-crypto.c:245 -#, c-format -msgid "Malformed PEM file: Proc-Type was not first tag." -msgstr "Помилкове форматування PEM: Proc-Type не є першим теґом." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:1 +msgid "Enable or disable system networking" +msgstr "Увімкнути або вимкнути системну роботу у мережі" -#: ../libnm-core/nm-crypto.c:254 -#, c-format -msgid "Malformed PEM file: unknown Proc-Type tag '%s'." -msgstr "Помилкове форматування PEM: невідомий теґ Proc-Type «%s»." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:2 +msgid "System policy prevents enabling or disabling system networking" +msgstr "" +"Правила системи забороняють вмикання або вимикання з'єднань з мережею на " +"системному рівні" -#: ../libnm-core/nm-crypto.c:267 -#, c-format -msgid "Malformed PEM file: DEK-Info was not the second tag." -msgstr "Помилкове форматування PEM: DEK-Info не є другим теґом." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:3 +msgid "Reload NetworkManager configuration" +msgstr "Перезавантажити налаштування NetworkManager" -#: ../libnm-core/nm-crypto.c:279 -#, c-format -msgid "Malformed PEM file: no IV found in DEK-Info tag." -msgstr "Помилкове форматування файла PEM: не знайдено теґу DEK-Info у ВІ." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:4 +msgid "System policy prevents reloading NetworkManager" +msgstr "Правила системи запобігають перезавантаженню NetworkManager" -#: ../libnm-core/nm-crypto.c:288 -#, c-format -msgid "Malformed PEM file: invalid format of IV in DEK-Info tag." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:5 +msgid "" +"Put NetworkManager to sleep or wake it up (should only be used by system " +"power management)" msgstr "" -"Помилкове форматування файла PEM: некоректне форматування ВІ у тезі DEK-Info." +"Призупинити або поновити роботу NetworkManager (має використовуватися лише " +"інструментами керування живленням системи)" -#: ../libnm-core/nm-crypto.c:300 -#, c-format -msgid "Malformed PEM file: unknown private key cipher '%s'." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:6 +msgid "System policy prevents putting NetworkManager to sleep or waking it up" msgstr "" -"Помилкове форматування файла PEM: невідоме шифрування закритого ключа «%s»." +"Правила системи забороняють присипляння та поновлення роботи NetworkManager" -#: ../libnm-core/nm-crypto.c:323 -#, c-format -msgid "Could not decode private key." -msgstr "Не вдалося декодувати закритий ключ." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:7 +msgid "Enable or disable Wi-Fi devices" +msgstr "Увімкнути або вимкнути пристрої Wi-Fi" -#: ../libnm-core/nm-crypto.c:365 -msgid "Failed to find expected PKCS#8 start tag." -msgstr "Не вдалося знайти очікуваний початковий теґ PKCS#8." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:8 +msgid "System policy prevents enabling or disabling Wi-Fi devices" +msgstr "Правила системи забороняють вмикання або вимикання пристроїв Wi-Fi" -#: ../libnm-core/nm-crypto.c:374 -#, c-format -msgid "Failed to find expected PKCS#8 end tag '%s'." -msgstr "Не вдалося знайти очікуваний завершальний теґ PKCS#8 «%s»." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:9 +msgid "Enable or disable mobile broadband devices" +msgstr "Увімкнути або вимкнути пристрої широкосмугових мобільних мереж" -#: ../libnm-core/nm-crypto.c:387 -msgid "Failed to decode PKCS#8 private key." -msgstr "Не вдалося декодувати закритий ключ PKCS#8." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:10 +msgid "System policy prevents enabling or disabling mobile broadband devices" +msgstr "" +"Правила системи забороняють вмикання або вимикання пристроїв широкосмугових " +"мобільних мереж" -#: ../libnm-core/nm-crypto.c:417 -msgid "Failed to find expected TSS start tag." -msgstr "Не вдалося знайти очікуваний початковий теґ TSS." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:11 +msgid "Enable or disable WiMAX mobile broadband devices" +msgstr "Увімкнути або вимкнути пристрої широкосмугових мобільних мереж WiMAX" -#: ../libnm-core/nm-crypto.c:426 -#, c-format -msgid "Failed to find expected TSS end tag '%s'." -msgstr "Не вдалося знайти очікуваний завершальний теґ TSS «%s»." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:12 +msgid "" +"System policy prevents enabling or disabling WiMAX mobile broadband devices" +msgstr "" +"Правила системи забороняють вмикання або вимикання пристроїв широкосмугових " +"мобільних мереж WiMAX" -#: ../libnm-core/nm-crypto.c:481 -#, c-format -msgid "IV must be an even number of bytes in length." -msgstr "Довжина ВІ має дорівнювати парній кількості байтів." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:13 +msgid "Allow control of network connections" +msgstr "Дозволити керування з'єднаннями мережею" -#: ../libnm-core/nm-crypto.c:498 -#, c-format -msgid "IV contains non-hexadecimal digits." -msgstr "ВІ містить не шістнадцяткові цифри." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:14 +msgid "System policy prevents control of network connections" +msgstr "Правила системи забороняють керування з'єднаннями" -#: ../libnm-core/nm-crypto.c:574 -#, c-format -msgid "IV must contain at least 8 characters" -msgstr "IV має складатися із принаймні 8 символів" +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:15 +msgid "Allow control of Wi-Fi scans" +msgstr "Дозволити керування скануваннями Wi-Fi" -#: ../libnm-core/nm-crypto.c:624 -#, c-format -msgid "Unable to determine private key type." -msgstr "Не вдалося визначити тип закритого ключа." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:16 +msgid "System policy prevents Wi-Fi scans" +msgstr "Правила системи забороняють сканування Wi-Fi" -#: ../libnm-core/nm-crypto.c:637 -#, c-format -msgid "Password provided, but key was not encrypted." -msgstr "Надано пароль, але ключ не зашифровано." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:17 +msgid "Connection sharing via a protected Wi-Fi network" +msgstr "Спільне використання з'єднання на основі захищеної мережі Wi-Fi" -#: ../libnm-core/nm-crypto.c:693 -#, c-format -msgid "PEM certificate had no start tag '%s'." -msgstr "Сертифікат PEM не містить початкового теґу «%s»." - -#: ../libnm-core/nm-crypto.c:703 -#, c-format -msgid "PEM certificate had no end tag '%s'." -msgstr "Сертифікат PEM не містить завершального теґу «%s»." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:18 +msgid "" +"System policy prevents sharing connections via a protected Wi-Fi network" +msgstr "" +"Правила системи забороняють спільне використання з'єднань за допомогою " +"захищеної мережі Wi-Fi" -#: ../libnm-core/nm-crypto.c:716 -#, c-format -msgid "Failed to decode certificate." -msgstr "Не вдалося декодувати сертифікат." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:19 +msgid "Connection sharing via an open Wi-Fi network" +msgstr "Спільне використання з'єднання на основі відкритої мережі Wi-Fi" -#: ../libnm-core/nm-crypto.c:745 ../libnm-core/nm-crypto.c:796 -#, c-format -msgid "Certificate file is empty" -msgstr "Файл сертифіката є порожнім" +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:20 +msgid "System policy prevents sharing connections via an open Wi-Fi network" +msgstr "" +"Правила системи забороняють спільне використання з'єднань за допомогою " +"відкритої мережі Wi-Fi" -#: ../libnm-core/nm-crypto.c:778 -#, c-format -msgid "Failed to recognize certificate" -msgstr "Не вдалося розпізнати сертифікат" +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:21 +msgid "Modify personal network connections" +msgstr "Змінити параметри особистих з'єднань з мережею" -#: ../libnm-core/nm-crypto.c:886 -#, c-format -msgid "not a valid private key" -msgstr "не є коректним закритим ключем" +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:22 +msgid "System policy prevents modification of personal network settings" +msgstr "" +"Правила системи забороняють внесення змін до особистих параметрів мережі" -#: ../libnm-core/nm-crypto-gnutls.c:59 -msgid "Failed to initialize the crypto engine." -msgstr "Не вдалося ініціалізувати рушій шифрування." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:23 +msgid "Modify network connections for all users" +msgstr "Внести зміни до мережевих з'єднань всіх користувачів" -#: ../libnm-core/nm-crypto-gnutls.c:92 ../libnm-core/nm-crypto-nss.c:118 -#, c-format -msgid "Unsupported key cipher for decryption" -msgstr "Непідтримуване шифрування ключем для розшифровування" +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:24 +msgid "System policy prevents modification of network settings for all users" +msgstr "" +"Правила системи забороняють внесення змін до параметрів мережі для всіх " +"користувачів" -#: ../libnm-core/nm-crypto-gnutls.c:103 ../libnm-core/nm-crypto-nss.c:126 -#, c-format -msgid "Invalid IV length (must be at least %u)." -msgstr "Некоректна довжина ВІ (має бути принаймні %u)." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:25 +msgid "Modify persistent system hostname" +msgstr "Змінити постійну назву вузла у мережі" -#: ../libnm-core/nm-crypto-gnutls.c:121 -#, c-format -msgid "Failed to initialize the decryption cipher context: %s (%s)" -msgstr "Не вдалося ініціалізувати контекст шифру декодування: %s (%s)." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:26 +msgid "System policy prevents modification of the persistent system hostname" +msgstr "" +"Правила системи забороняють внесення змін до постійної назви вузла у мережі" -#: ../libnm-core/nm-crypto-gnutls.c:135 -#, c-format -msgid "Failed to decrypt the private key: %s (%s)" -msgstr "Не вдалося розшифрувати закритий ключ: %s (%s)." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:27 +msgid "Modify persistent global DNS configuration" +msgstr "Змінити постійні загальні налаштування DNS" -#: ../libnm-core/nm-crypto-gnutls.c:148 ../libnm-core/nm-crypto-nss.c:221 -#, c-format -msgid "Failed to decrypt the private key: unexpected padding length." -msgstr "Не вдалося розшифрувати закритий ключ: неочікувана довжина доповнення." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:28 +msgid "" +"System policy prevents modification of the persistent global DNS " +"configuration" +msgstr "" +"Правила системи забороняють внесення змін до постійних загальних налаштувань " +"DNS" -#: ../libnm-core/nm-crypto-gnutls.c:160 ../libnm-core/nm-crypto-nss.c:233 -#, c-format -msgid "Failed to decrypt the private key." -msgstr "Не вдалося розшифрувати закритий ключ." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:29 +msgid "Perform a checkpoint or rollback of interfaces configuration" +msgstr "Виконати перевірку або повернення до попередніх налаштувань інтерфейсу" -#: ../libnm-core/nm-crypto-gnutls.c:194 ../libnm-core/nm-crypto-nss.c:288 -#, c-format -msgid "Unsupported key cipher for encryption" -msgstr "Непідтримуване шифрування ключем для шифрування" +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:30 +msgid "System policy prevents the creation of a checkpoint or its rollback" +msgstr "" +"Правила системи забороняють створення точки перевірки або повернення до " +"стану такої точки" -#: ../libnm-core/nm-crypto-gnutls.c:211 -#, c-format -msgid "Failed to initialize the encryption cipher context: %s (%s)" -msgstr "Не вдалося ініціалізувати контекст шифру кодування: %s (%s)." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:31 +msgid "Enable or disable device statistics" +msgstr "Увімкнути або вимкнути обчислення статистичних даних пристрою" -#: ../libnm-core/nm-crypto-gnutls.c:239 -#, c-format -msgid "Failed to encrypt the data: %s (%s)" -msgstr "Не вдалося зашифрувати дані: %s (%s)." +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:32 +msgid "System policy prevents enabling or disabling device statistics" +msgstr "" +"Правила системи забороняють вмикання або вимикання збирання статистичних " +"даних пристрою" -#: ../libnm-core/nm-crypto-gnutls.c:264 -#, c-format -msgid "Error initializing certificate data: %s" -msgstr "Помилка під час спроби ініціалізації даних сертифіката: %s" +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:33 +msgid "Enable or disable connectivity checking" +msgstr "Увімкнути або вимкнути перевірку придатності до з'єднання" -#: ../libnm-core/nm-crypto-gnutls.c:287 -#, c-format -msgid "Couldn't decode certificate: %s" -msgstr "Не вдалося декодувати сертифікат: %s" +#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:34 +msgid "System policy prevents enabling or disabling connectivity checking" +msgstr "" +"Правила системи забороняють вмикання або вимикання перевірки придатності до " +"з'єднання" -#: ../libnm-core/nm-crypto-gnutls.c:312 +#: ../libnm/nm-client.c:3773 #, c-format -msgid "Couldn't initialize PKCS#12 decoder: %s" -msgstr "Не вдалося ініціалізувати інструмент розшифрування PKCS#12: %s" +msgid "request succeeded with %s but object is in an unsuitable state" +msgstr "запит успішно виконано (%s), але об'єкт перебуває у непридатному стані" -#: ../libnm-core/nm-crypto-gnutls.c:326 +#: ../libnm/nm-client.c:3865 #, c-format -msgid "Couldn't decode PKCS#12 file: %s" -msgstr "Не вдалося розшифрувати файл PKCS#12: %s" +msgid "operation succeeded but object %s does not exist" +msgstr "дію успішно виконано, але об'єкта %s не існує" -#: ../libnm-core/nm-crypto-gnutls.c:341 -#, c-format -msgid "Couldn't verify PKCS#12 file: %s" -msgstr "Не вдалося перевірити файл PKCS#12: %s" +#: ../libnm/nm-device-adsl.c:66 +msgid "The connection was not an ADSL connection." +msgstr "З'єднання не є з'єднанням ADSL." -#: ../libnm-core/nm-crypto-gnutls.c:370 -#, c-format -msgid "Couldn't initialize PKCS#8 decoder: %s" -msgstr "Не вдалося ініціалізувати інструмент розшифрування PKCS#8: %s" +#: ../libnm/nm-device-bond.c:106 +msgid "The connection was not a bond connection." +msgstr "З'єднання не є з'єднанням зв'язку." -#: ../libnm-core/nm-crypto-gnutls.c:398 -#, c-format -msgid "Couldn't decode PKCS#8 file: %s" -msgstr "Не вдалося розшифрувати файл PKCS#8: %s" +#: ../libnm/nm-device-bridge.c:109 +msgid "The connection was not a bridge connection." +msgstr "З'єднання не є з'єднанням містка." -#: ../libnm-core/nm-crypto-nss.c:70 +#: ../libnm/nm-device-bt.c:133 #, c-format -msgid "Failed to initialize the crypto engine: %d." -msgstr "Не вдалося ініціалізувати рушій шифрування: %d." +msgid "The connection was not a Bluetooth connection." +msgstr "З'єднання не є з'єднанням Bluetooth." -#: ../libnm-core/nm-crypto-nss.c:139 +#: ../libnm/nm-device-bt.c:141 #, c-format -msgid "Failed to initialize the decryption cipher slot." -msgstr "Не вдалося ініціалізувати слот шифру декодування." +msgid "The connection is of Bluetooth NAP type." +msgstr "З'єднання належить до типу NAP Bluetooth." -#: ../libnm-core/nm-crypto-nss.c:150 -#, c-format -msgid "Failed to set symmetric key for decryption." -msgstr "Не вдалося встановити симетричний ключ для розшифрування." +#: ../libnm/nm-device-bt.c:152 +msgid "Invalid device Bluetooth address." +msgstr "Некоректна адреса Bluetooth пристрою." -#: ../libnm-core/nm-crypto-nss.c:161 -#, c-format -msgid "Failed to set IV for decryption." -msgstr "Не вдалося встановити ВІ для розшифрування." +#: ../libnm/nm-device-bt.c:161 +msgid "The Bluetooth addresses of the device and the connection didn't match." +msgstr "Адреси Bluetooth пристрою і з'єднання не збігаються." -#: ../libnm-core/nm-crypto-nss.c:170 -#, c-format -msgid "Failed to initialize the decryption context." -msgstr "Не вдалося ініціалізувати контекст розшифрування." +#: ../libnm/nm-device-bt.c:173 +msgid "" +"The device is lacking Bluetooth capabilities required by the connection." +msgstr "У пристрою немає можливостей Bluetooth, потрібних з'єднанню." -#: ../libnm-core/nm-crypto-nss.c:187 -#, c-format -msgid "Failed to decrypt the private key: %d." -msgstr "Не вдалося розшифрувати закритий ключ: %d." +#: ../libnm/nm-device-dummy.c:65 +msgid "The connection was not a dummy connection." +msgstr "З'єднання не є фіктивним з'єднанням." -#: ../libnm-core/nm-crypto-nss.c:196 -#, c-format -msgid "Failed to decrypt the private key: decrypted data too large." -msgstr "" -"Не вдалося розшифрувати закритий ключ: розшифровані дані є занадто об'ємними." +#: ../libnm/nm-device-dummy.c:74 ../libnm/nm-device-generic.c:89 +#: ../libnm/nm-device-ovs-bridge.c:89 ../libnm/nm-device-ovs-interface.c:57 +#: ../libnm/nm-device-ovs-port.c:89 +msgid "The connection did not specify an interface name." +msgstr "У записі з'єднання не вказано назви інтерфейсу." -#: ../libnm-core/nm-crypto-nss.c:208 -#, c-format -msgid "Failed to finalize decryption of the private key: %d." -msgstr "Не вдалося завершити розшифрування закритого ключа: %d." +#: ../libnm/nm-device-ethernet.c:189 +msgid "The connection was not an Ethernet or PPPoE connection." +msgstr "З'єднання не є з'єднанням Ethernet або PPPoE." -#: ../libnm-core/nm-crypto-nss.c:300 -#, c-format -msgid "Failed to initialize the encryption cipher slot." -msgstr "Не вдалося ініціалізувати слот шифру розкодування." +#: ../libnm/nm-device-ethernet.c:206 +msgid "The connection and device differ in S390 subchannels." +msgstr "У підканалах S390 виявлено відмінність з'єднання і пристрою." -#: ../libnm-core/nm-crypto-nss.c:309 +#: ../libnm/nm-device-ethernet.c:223 #, c-format -msgid "Failed to set symmetric key for encryption." -msgstr "Не вдалося встановити симетричний ключ для шифрування." +msgid "Invalid device MAC address %s." +msgstr "Некоректна MAC-адреса пристрою, %s." -#: ../libnm-core/nm-crypto-nss.c:318 -#, c-format -msgid "Failed to set IV for encryption." -msgstr "Не вдалося встановити вектор ініціалізації для шифрування." +#: ../libnm/nm-device-ethernet.c:231 +msgid "The MACs of the device and the connection do not match." +msgstr "Адреси MAC пристрою і з'єднання не збігаються." -#: ../libnm-core/nm-crypto-nss.c:327 +#: ../libnm/nm-device-ethernet.c:243 #, c-format -msgid "Failed to initialize the encryption context." -msgstr "Не вдалося ініціалізувати контекст шифрування." +msgid "Invalid MAC in the blacklist: %s." +msgstr "Некоректний запис MAC у «чорному» списку: %s." -#: ../libnm-core/nm-crypto-nss.c:352 +#: ../libnm/nm-device-ethernet.c:252 #, c-format -msgid "Failed to encrypt: %d." -msgstr "Не вдалося зашифрувати: %d." +msgid "Device MAC (%s) is blacklisted by the connection." +msgstr "MAC пристрою (%s) додано до «чорного» списку з'єднання." -#: ../libnm-core/nm-crypto-nss.c:361 -#, c-format -msgid "Unexpected amount of data after encrypting." -msgstr "Неочікуваний об'єм даних після шифрування." +#: ../libnm/nm-device-generic.c:80 +msgid "The connection was not a generic connection." +msgstr "З'єднання не є загальним з'єднанням." -#: ../libnm-core/nm-crypto-nss.c:398 -#, c-format -msgid "Couldn't decode certificate: %d" -msgstr "Не вдалося розшифрувати сертифікат: %d" +#: ../libnm/nm-device-infiniband.c:90 +msgid "The connection was not an InfiniBand connection." +msgstr "З'єднання не є з'єднанням InfiniBand." -#: ../libnm-core/nm-crypto-nss.c:443 -#, c-format -msgid "Password must be UTF-8" -msgstr "Пароль має бути вказано у кодуванні UTF-8" +#: ../libnm/nm-device-infiniband.c:100 ../libnm/nm-device-wifi.c:481 +msgid "Invalid device MAC address." +msgstr "Некоректна MAC-адреса пристрою." -#: ../libnm-core/nm-crypto-nss.c:464 -#, c-format -msgid "Couldn't initialize slot" -msgstr "Не вдалося ініціалізувати слот" +#: ../libnm/nm-device-infiniband.c:110 ../libnm/nm-device-wifi.c:490 +msgid "The MACs of the device and the connection didn't match." +msgstr "Адреси MAC пристрою і з'єднання не збігаються." -#: ../libnm-core/nm-crypto-nss.c:473 -#, c-format -msgid "Couldn't initialize PKCS#12 decoder: %d" -msgstr "Не вдалося ініціалізувати інструмент розшифрування PKCS#12: %d" +#: ../libnm/nm-device-ip-tunnel.c:266 +msgid "The connection was not an IP tunnel connection." +msgstr "З'єднання не є тунельованим IP-з'єднанням." -#: ../libnm-core/nm-crypto-nss.c:483 -#, c-format -msgid "Couldn't decode PKCS#12 file: %d" -msgstr "Не вдалося розшифрувати файл PKCS#12: %d" - -#: ../libnm-core/nm-crypto-nss.c:493 -#, c-format -msgid "Couldn't verify PKCS#12 file: %d" -msgstr "Не вдалося перевірити файл PKCS#12: %d" - -#: ../libnm-core/nm-crypto-nss.c:544 -msgid "Could not generate random data." -msgstr "Не вдалося створити псевдовипадкові дані." - -#: ../libnm-core/nm-connection.c:299 -msgid "wrong type; should be a list of strings." -msgstr "помилковий тип; має бути список рядків." - -#: ../libnm-core/nm-connection.c:373 -msgid "unknown setting name" -msgstr "невідома назва параметра" - -#: ../libnm-core/nm-connection.c:385 -msgid "duplicate setting name" -msgstr "дублювання назви параметра" - -#: ../libnm-core/nm-connection.c:1422 -msgid "setting not found" -msgstr "параметра не знайдено" - -#: ../libnm-core/nm-connection.c:1475 ../libnm-core/nm-connection.c:1500 -#: ../libnm-core/nm-connection.c:1525 -msgid "setting is required for non-slave connections" -msgstr "для непідлеглих з'єднань потрібен параметр" - -#: ../libnm-core/nm-connection.c:1488 ../libnm-core/nm-connection.c:1513 -#: ../libnm-core/nm-connection.c:1538 -msgid "setting not allowed in slave connection" -msgstr "параметр не можна використовувати у підлеглому з'єднанні" - -#: ../libnm-core/nm-connection.c:1643 -msgid "Unexpected failure to normalize the connection" -msgstr "Неочікувана помилка під час спроби нормалізувати з'єднання" - -#: ../libnm-core/nm-connection.c:1704 -msgid "Unexpected failure to verify the connection" -msgstr "Неочікувана помилка під час спроби перевірити з'єднання" - -#: ../libnm-core/nm-connection.c:1741 -#, c-format -msgid "unexpected uuid %s instead of %s" -msgstr "неочікуваний UUID %s замість %s" - -#: ../libnm-core/nm-connection.c:2555 ../libnm-core/nm-setting-8021x.c:2618 -#: ../libnm-core/nm-setting-8021x.c:2641 ../libnm-core/nm-setting-8021x.c:2681 -#: ../libnm-core/nm-setting-8021x.c:2704 ../libnm-core/nm-setting-8021x.c:2755 -#: ../libnm-core/nm-setting-8021x.c:2773 ../libnm-core/nm-setting-8021x.c:2797 -#: ../libnm-core/nm-setting-8021x.c:2815 ../libnm-core/nm-setting-8021x.c:2845 -#: ../libnm-core/nm-setting-8021x.c:2945 ../libnm-core/nm-setting-adsl.c:157 -#: ../libnm-core/nm-setting-bluetooth.c:110 -#: ../libnm-core/nm-setting-bluetooth.c:174 -#: ../libnm-core/nm-setting-bluetooth.c:191 ../libnm-core/nm-setting-cdma.c:127 -#: ../libnm-core/nm-setting-connection.c:1073 -#: ../libnm-core/nm-setting-connection.c:1111 -#: ../libnm-core/nm-setting-connection.c:1383 -#: ../libnm-core/nm-setting-ip-config.c:5120 -#: ../libnm-core/nm-setting-ip-tunnel.c:371 -#: ../libnm-core/nm-setting-olpc-mesh.c:83 -#: ../libnm-core/nm-setting-ovs-patch.c:75 ../libnm-core/nm-setting-pppoe.c:129 -#: ../libnm-core/nm-setting-vpn.c:532 ../libnm-core/nm-setting-wifi-p2p.c:120 -#: ../libnm-core/nm-setting-wimax.c:92 -#: ../libnm-core/nm-setting-wireless-security.c:899 -#: ../libnm-core/nm-setting-wireless.c:788 -msgid "property is missing" -msgstr "не вказано властивості" - -#: ../libnm-core/nm-connection.c:2708 -msgid "IP Tunnel" -msgstr "IP-тунель" +#: ../libnm/nm-device-macvlan.c:151 +msgid "The connection was not a MAC-VLAN connection." +msgstr "З'єднання не є з'єднанням MAC-VLAN." -#: ../libnm-core/nm-dbus-utils.c:181 -#, c-format -msgid "Method returned type '%s', but expected '%s'" -msgstr "Методом повернуто тип «%s», хоча мав бути «%s»" +#: ../libnm/nm-device-modem.c:177 +msgid "The connection was not a modem connection." +msgstr "З'єднання не є модемним з'єднанням." -#: ../libnm-core/nm-keyfile-utils.c:174 -#, c-format -msgid "Value cannot be interpreted as a list of numbers." -msgstr "Значення не може бути оброблено як список чисел." +#: ../libnm/nm-device-modem.c:187 +msgid "The connection was not a valid modem connection." +msgstr "З'єднання не є коректним модемним з'єднанням." -#: ../libnm-core/nm-keyfile-utils.c:303 -#, c-format -msgid "value is not an integer in range [%lld, %lld]" -msgstr "значення не є цілим числом у діапазоні [%lld, %lld]" +#: ../libnm/nm-device-modem.c:196 +msgid "The device is lacking capabilities required by the connection." +msgstr "У пристрою немає можливостей, потрібних з'єднанню." -#: ../libnm-core/nm-keyfile.c:269 -msgid "ignoring missing number" -msgstr "ігноруємо пропущене число" +#: ../libnm/nm-device-olpc-mesh.c:102 +msgid "The connection was not an OLPC Mesh connection." +msgstr "З'єднання не є з'єднанням OLPC Mesh." -#: ../libnm-core/nm-keyfile.c:281 -#, c-format -msgid "ignoring invalid number '%s'" -msgstr "ігноруємо некоректне число «%s»" +#: ../libnm/nm-device-ovs-bridge.c:80 +msgid "The connection was not a ovs_bridge connection." +msgstr "З'єднання не було з'єднанням ovs_bridge." -#: ../libnm-core/nm-keyfile.c:310 -#, c-format -msgid "ignoring invalid %s address: %s" -msgstr "ігноруємо некоректну адресу %s: %s" +#: ../libnm/nm-device-ovs-interface.c:48 +msgid "The connection was not a ovs_interface connection." +msgstr "З'єднання не було з'єднанням ovs_interface." -#: ../libnm-core/nm-keyfile.c:356 -#, c-format -msgid "ignoring invalid gateway '%s' for %s route" -msgstr "ігноруємо некоректний шлюз «%s» для маршруту %s" +#: ../libnm/nm-device-ovs-port.c:80 +msgid "The connection was not a ovs_port connection." +msgstr "З'єднання не є з'єднанням ovs_port." -#: ../libnm-core/nm-keyfile.c:378 -#, c-format -msgid "ignoring invalid %s route: %s" -msgstr "ігноруємо некоректний маршрут %s: %s" +#: ../libnm/nm-device-team.c:125 +msgid "The connection was not a team connection." +msgstr "З'єднання не є командним з'єднанням." -#: ../libnm-core/nm-keyfile.c:556 -#, c-format -msgid "unexpected character '%c' for address %s: '%s' (position %td)" -msgstr "неочікуваний символ «%c» для адреси %s: «%s» (позиція %td)" +#: ../libnm/nm-device-tun.c:204 +msgid "The connection was not a tun connection." +msgstr "З'єднання не належить до типу tun." -#: ../libnm-core/nm-keyfile.c:572 -#, c-format -msgid "unexpected character '%c' for %s: '%s' (position %td)" -msgstr "неочікуваний символ «%c» для %s: «%s» (позиція %td)" +#: ../libnm/nm-device-tun.c:215 +msgid "The mode of the device and the connection didn't match" +msgstr "Режими роботи пристрою і з'єднання не збігаються" -#: ../libnm-core/nm-keyfile.c:587 -#, c-format -msgid "unexpected character '%c' in prefix length for %s: '%s' (position %td)" -msgstr "неочікуваний символ «%c» у префіксі довжини для %s: «%s» (позиція %td)" +#: ../libnm/nm-device-vlan.c:121 +msgid "The connection was not a VLAN connection." +msgstr "З'єднання не є з'єднанням VLAN." -#: ../libnm-core/nm-keyfile.c:604 -#, c-format -msgid "garbage at the end of value %s: '%s'" -msgstr "зайві дані наприкінці значення %s: «%s»" +#: ../libnm/nm-device-vlan.c:131 +msgid "The VLAN identifiers of the device and the connection didn't match." +msgstr "Ідентифікатори VLAN пристрою і з'єднання не збігаються." -#: ../libnm-core/nm-keyfile.c:614 -#, c-format -msgid "deprecated semicolon at the end of value %s: '%s'" -msgstr "застаріла крапка з комою наприкінці значення %s: «%s»" +#: ../libnm/nm-device-vlan.c:148 +msgid "The hardware address of the device and the connection didn't match." +msgstr "Апаратні адреси пристрою і з'єднання не збігаються." -#: ../libnm-core/nm-keyfile.c:633 -#, c-format -msgid "invalid prefix length for %s '%s', defaulting to %d" -msgstr "некоректний префікс довжини для %s «%s», повертаємося до типового, %d" +#: ../libnm/nm-device-vrf.c:65 +msgid "The connection was not a VRF connection." +msgstr "З'єднання не є з'єднанням VRF." -#: ../libnm-core/nm-keyfile.c:645 -#, c-format -msgid "missing prefix length for %s '%s', defaulting to %d" -msgstr "пропущено префікс довжини для %s «%s», повертаємося до типового, %d" +#: ../libnm/nm-device-vrf.c:74 +msgid "The VRF table of the device and the connection didn't match." +msgstr "Таблиці VRF пристрою і з'єднання не збігаються" -#: ../libnm-core/nm-keyfile.c:988 -#: ../libnm-core/nm-setting-ovs-external-ids.c:320 -#: ../libnm-core/nm-setting-user.c:372 -#, c-format -msgid "invalid value for \"%s\": %s" -msgstr "некоректне значення для «%s»: %s" +#: ../libnm/nm-device-vxlan.c:383 +msgid "The connection was not a VXLAN connection." +msgstr "З'єднання не є з'єднанням VXLAN." -#: ../libnm-core/nm-keyfile.c:1066 -#, c-format -msgid "ignoring invalid DNS server IPv%c address '%s'" -msgstr "ігноруємо некоректну адресу IPv%c сервера DNS «%s»" +#: ../libnm/nm-device-vxlan.c:393 +msgid "The VXLAN identifiers of the device and the connection didn't match." +msgstr "Ідентифікатори VXLAN пристрою і з'єднання не збігаються." -#: ../libnm-core/nm-keyfile.c:1161 -msgid "ignoring invalid MAC address" -msgstr "ігноруємо некоректну MAC-адресу" +#: ../libnm/nm-device-wifi-p2p.c:266 +msgid "The connection was not a Wi-Fi P2P connection." +msgstr "З'єднання не є з'єднанням P2P Wi-Fi." -#: ../libnm-core/nm-keyfile.c:1237 -#, c-format -msgid "ignoring invalid bond option %s%s%s = %s%s%s: %s" -msgstr "ігноруємо некоректний параметр bond %s%s%s = %s%s%s: %s" +#: ../libnm/nm-device-wifi.c:470 +msgid "The connection was not a Wi-Fi connection." +msgstr "З'єднання не є з'єднанням Wi-Fi." -#: ../libnm-core/nm-keyfile.c:1427 -msgid "ignoring invalid SSID" -msgstr "ігноруємо некоректний SSID" +#: ../libnm/nm-device-wifi.c:511 +msgid "The device is lacking WPA capabilities required by the connection." +msgstr "У пристрою немає можливостей WPA, потрібних з'єднанню." -#: ../libnm-core/nm-keyfile.c:1445 -msgid "ignoring invalid raw password" -msgstr "ігноруємо некоректний необроблений пароль" +#: ../libnm/nm-device-wifi.c:521 +msgid "The device is lacking WPA2/RSN capabilities required by the connection." +msgstr "У пристрою немає можливостей WPA2/RSN, потрібних з'єднанню." -#: ../libnm-core/nm-keyfile.c:1586 -msgid "invalid key/cert value" -msgstr "некоректне значення ключа/сертифіката" +#: ../libnm/nm-device-wpan.c:57 +msgid "The connection was not a wpan connection." +msgstr "З'єднання не належить до типу wpan." -#: ../libnm-core/nm-keyfile.c:1601 -#, c-format -msgid "invalid key/cert value path \"%s\"" -msgstr "некоректний шлях до ключа/сертифіката, «%s»" +#: ../libnm/nm-device.c:1659 +msgid "Bluetooth" +msgstr "Bluetooth" -#: ../libnm-core/nm-keyfile.c:1626 ../libnm-core/nm-keyfile.c:1723 -#, c-format -msgid "certificate or key file '%s' does not exist" -msgstr "файла сертифіката або ключа «%s» не існує" +#: ../libnm/nm-device.c:1661 +msgid "OLPC Mesh" +msgstr "Сітка OLPC" -#: ../libnm-core/nm-keyfile.c:1639 -#, c-format -msgid "invalid PKCS#11 URI \"%s\"" -msgstr "некоректна адреса PKCS#11 «%s»" +#: ../libnm/nm-device.c:1663 +msgid "Open vSwitch Interface" +msgstr "Інтерфейс Open vSwitch" -#: ../libnm-core/nm-keyfile.c:1685 -msgid "invalid key/cert value data:;base64, is not base64" -msgstr "некоректні дані значення ключа/сертифіката data:;base64, не є base64" +#: ../libnm/nm-device.c:1665 +msgid "Open vSwitch Port" +msgstr "Порт Open vSwitch" -#: ../libnm-core/nm-keyfile.c:1698 -msgid "invalid key/cert value data:;base64,file://" -msgstr "некоректне значення ключа/сертифіката data:;base64,file://" +#: ../libnm/nm-device.c:1667 +msgid "Open vSwitch Bridge" +msgstr "Місток Open vSwitch" -#: ../libnm-core/nm-keyfile.c:1739 -msgid "invalid key/cert value is not a valid blob" -msgstr "" -"некоректне значення ключа/сертифіката, не є коректним значення «%s» не є " -"коректним великим бінарним об'єктом" +#: ../libnm/nm-device.c:1669 +msgid "WiMAX" +msgstr "WiMAX" -#: ../libnm-core/nm-keyfile.c:1841 -#, c-format -msgid "invalid parity value '%s'" -msgstr "некоректне значення парності, «%s»" +#: ../libnm/nm-device.c:1683 +msgid "ADSL" +msgstr "ADSL" -#: ../libnm-core/nm-keyfile.c:1863 ../libnm-core/nm-keyfile.c:3336 -#, c-format -msgid "invalid setting: %s" -msgstr "некоректний параметр: %s" +#: ../libnm/nm-device.c:1685 +msgid "MACVLAN" +msgstr "MACVLAN" -#: ../libnm-core/nm-keyfile.c:1883 -#, c-format -msgid "ignoring invalid team configuration: %s" -msgstr "ігноруємо некоректне налаштування команди: %s" +#: ../libnm/nm-device.c:1687 +msgid "VXLAN" +msgstr "VXLAN" -#: ../libnm-core/nm-keyfile.c:1966 -#, c-format -msgid "invalid qdisc: %s" -msgstr "некоректний qdisc: %s" +#: ../libnm/nm-device.c:1689 +msgid "IPTunnel" +msgstr "IPTunnel" -#: ../libnm-core/nm-keyfile.c:2016 -#, c-format -msgid "invalid tfilter: %s" -msgstr "некоректний tfilter: %s" +#: ../libnm/nm-device.c:1691 +msgid "Tun" +msgstr "TUN" -#: ../libnm-core/nm-keyfile.c:3161 -#, c-format -msgid "error loading setting value: %s" -msgstr "помилка під час завантаження значення параметра: %s" +#: ../libnm/nm-device.c:1695 +msgid "MACsec" +msgstr "MACsec" -#: ../libnm-core/nm-keyfile.c:3192 ../libnm-core/nm-keyfile.c:3204 -#: ../libnm-core/nm-keyfile.c:3223 ../libnm-core/nm-keyfile.c:3235 -#: ../libnm-core/nm-keyfile.c:3247 ../libnm-core/nm-keyfile.c:3309 -#: ../libnm-core/nm-keyfile.c:3321 -msgid "value cannot be interpreted as integer" -msgstr "значення не може бути оброблено як ціле число" +#: ../libnm/nm-device.c:1697 +msgid "Dummy" +msgstr "Фіктивний" -#: ../libnm-core/nm-keyfile.c:3277 -#, c-format -msgid "ignoring invalid byte element '%u' (not between 0 and 255 inclusive)" -msgstr "" -"ігноруємо некоректний байтовий елемент «%u» (не у діапазоні від 0 до 255, " -"включно)" +#: ../libnm/nm-device.c:1699 +msgid "PPP" +msgstr "PPP" -#: ../libnm-core/nm-keyfile.c:3361 -#, c-format -msgid "invalid setting name '%s'" -msgstr "некоректна назва параметра, «%s»" +#: ../libnm/nm-device.c:1701 +msgid "IEEE 802.15.4" +msgstr "IEEE 802.15.4" -#: ../libnm-core/nm-keyfile.c:3408 -#, c-format -msgid "invalid key '%s.%s'" -msgstr "некоректний ключ «%s.%s»" +#: ../libnm/nm-device.c:1703 +msgid "6LoWPAN" +msgstr "6LoWPAN" -#: ../libnm-core/nm-keyfile.c:3424 -#, c-format -msgid "key '%s.%s' is not boolean" -msgstr "ключ «%s.%s» не є булевим значенням" +#: ../libnm/nm-device.c:1705 +msgid "WireGuard" +msgstr "WireGuard" -#: ../libnm-core/nm-keyfile.c:3441 -#, c-format -msgid "key '%s.%s' is not a uint32" -msgstr "ключ «%s.%s» не є значенням uint32" +#: ../libnm/nm-device.c:1707 +msgid "Wi-Fi P2P" +msgstr "P2P Wi-Fi" -#: ../libnm-core/nm-keyfile.c:3498 -#, c-format -msgid "invalid peer public key in section '%s'" -msgstr "некоректний відкритий ключ вузла у розділі «%s»" +#: ../libnm/nm-device.c:1709 +msgid "VRF" +msgstr "VRF" -#: ../libnm-core/nm-keyfile.c:3513 -#, c-format -msgid "key '%s.%s' is not a valid 256 bit key in base64 encoding" -msgstr "ключ «%s.%s» не є коректним 256-бітовим ключем у кодуванні base64" +#: ../libnm/nm-device.c:1741 +msgid "Wired" +msgstr "Дротове" -#: ../libnm-core/nm-keyfile.c:3536 -#, c-format -msgid "key '%s.%s' is not a valid secret flag" -msgstr "ключ «%s.%s» не є коректним прапорцем реєстраційних даних" +#: ../libnm/nm-device.c:1773 +msgid "PCI" +msgstr "PCI" -#: ../libnm-core/nm-keyfile.c:3559 -#, c-format -msgid "key '%s.%s' is not a integer in range 0 to 2^32" -msgstr "ключ «%s.%s» не є цілими числом у діапазоні від 0 до 2^32" +#: ../libnm/nm-device.c:1775 +msgid "USB" +msgstr "USB" -#: ../libnm-core/nm-keyfile.c:3575 +#. TRANSLATORS: the first %s is a bus name (eg, "USB") or +#. * product name, the second is a device type (eg, +#. * "Ethernet"). You can change this to something like +#. * "%2$s (%1$s)" if there's no grammatical way to combine +#. * the strings otherwise. +#. +#: ../libnm/nm-device.c:2074 ../libnm/nm-device.c:2093 #, c-format -msgid "key '%s.%s' is not a valid endpoint" -msgstr "ключ «%s.%s» не є коректною кінцевою точкою" +msgctxt "long device name" +msgid "%s %s" +msgstr "%s %s" -#: ../libnm-core/nm-keyfile.c:3601 +#: ../libnm/nm-device.c:2753 #, c-format -msgid "key '%s.%s' has invalid allowed-ips" -msgstr "для ключа «%s.%s» вказано некоректне значення allowed-ips" +msgid "The connection was not valid: %s" +msgstr "З'єднання не є коректним: %s" -#: ../libnm-core/nm-keyfile.c:3616 +#: ../libnm/nm-device.c:2765 #, c-format -msgid "peer '%s' is invalid: %s" -msgstr "вузол «%s» є некоректним: %s" +msgid "The interface names of the device and the connection didn't match." +msgstr "Назви інтерфейсу пристрою і з'єднання не збігаються." -#: ../libnm-core/nm-keyfile.c:4107 -#, c-format -msgid "the profile is not valid: %s" -msgstr "профіль є некоректним: %s" +#: ../libnm/nm-secret-agent-old.c:1384 +msgid "registration failed" +msgstr "не вдалося пройти реєстрацію" -#: ../libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c:286 -#, c-format -msgid "'%s' is not valid: properties should be specified as 'key=value'" -msgstr "" -"«%s» є некоректним: властивості має бути вказано у форматі «ключ=значення»" +#: ../libnm/nm-vpn-plugin-old.c:819 ../libnm/nm-vpn-service-plugin.c:1014 +msgid "No service name specified" +msgstr "Не вказано назви служби" -#: ../libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c:300 +#: ../shared/nm-glib-aux/nm-shared-utils.c:2352 #, c-format -msgid "'%s' is not a valid key" -msgstr "«%s» не є коректним ключем" +msgid "object class '%s' has no property named '%s'" +msgstr "у класі об'єктів «%s» немає властивості із назвою «%s»" -#: ../libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c:305 +#: ../shared/nm-glib-aux/nm-shared-utils.c:2361 #, c-format -msgid "duplicate key '%s'" -msgstr "дублікат ключа «%s»" +msgid "property '%s' of object class '%s' is not writable" +msgstr "властивість «%s» класу об'єктів «%s» є непридатною до запису" -#: ../libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c:319 +#: ../shared/nm-glib-aux/nm-shared-utils.c:2370 #, c-format -msgid "number for '%s' is out of range" -msgstr "число для «%s» лежить поза припустимим діапазоном" +msgid "" +"construct property \"%s\" for object '%s' can't be set after construction" +msgstr "" +"властивість construct «%s» об'єкта «%s» не можна встановлювати після побудови" -#: ../libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c:324 +#: ../shared/nm-glib-aux/nm-shared-utils.c:2381 #, c-format -msgid "value for '%s' must be a number" -msgstr "значення «%s» має бути числом" +msgid "'%s::%s' is not a valid property name; '%s' is not a GObject subtype" +msgstr "«%s::%s» не є коректною назвою властивості; «%s» не є підтипом GObject" -#: ../libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c:337 +#: ../shared/nm-glib-aux/nm-shared-utils.c:2394 #, c-format -msgid "value for '%s' must be a boolean" -msgstr "значення «%s» має бути булевим" - -#: ../libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c:346 -msgid "missing 'name' attribute" -msgstr "пропущено атрибут «name»" +msgid "unable to set property '%s' of type '%s' from value of type '%s'" +msgstr "" +"не вдалося встановити значення властивості «%s» типу «%s» на основі значення " +"типу «%s»" -#: ../libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c:355 +#: ../shared/nm-glib-aux/nm-shared-utils.c:2406 #, c-format -msgid "invalid 'name' \"%s\"" -msgstr "некоректне значення «name» — «%s»" +msgid "" +"value \"%s\" of type '%s' is invalid or out of range for property '%s' of " +"type '%s'" +msgstr "" +"значення «%s» типу «%s» є некоректним для властивості «%s» типу «%s» або не " +"належить до припустимого діапазону значень" -#: ../libnm-core/nm-libnm-core-aux/nm-libnm-core-aux.c:368 -#, c-format -msgid "attribute '%s' is invalid for \"%s\"" -msgstr "атрибут «%s» є некоректним для «%s»" +#: ../shared/nm-glib-aux/nm-shared-utils.c:5204 +msgid "interface name is missing" +msgstr "пропущено назву інтерфейсу" -#: ../libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c:321 -msgid "property cannot be an empty string" -msgstr "властивість не може бути порожнім рядком" +#: ../shared/nm-glib-aux/nm-shared-utils.c:5212 +msgid "interface name is too short" +msgstr "назва інтерфейсу є надто короткою" -#: ../libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c:338 -msgid "property cannot be longer than 255 bytes" -msgstr "значення властивості не може бути довшим за 255 байтів" +#: ../shared/nm-glib-aux/nm-shared-utils.c:5220 +msgid "interface name is reserved" +msgstr "таку назву інтерфейсу зарезервовано" -#: ../libnm-core/nm-libnm-core-intern/nm-libnm-core-utils.c:349 -msgid "property cannot contain any nul bytes" -msgstr "значення властивості не може містити нульових байтів" +#: ../shared/nm-glib-aux/nm-shared-utils.c:5233 +msgid "interface name contains an invalid character" +msgstr "назва інтерфейсу містить некоректний символ" -#: ../libnm-core/nm-setting-6lowpan.c:78 ../libnm-core/nm-setting-veth.c:80 -#, c-format -msgid "property is not specified" -msgstr "властивість не вказано" +#: ../shared/nm-glib-aux/nm-shared-utils.c:5241 +msgid "interface name is longer than 15 characters" +msgstr "назва інтерфейсу є довшою за 15 символів" -#: ../libnm-core/nm-setting-6lowpan.c:101 ../libnm-core/nm-setting-macsec.c:285 -#: ../libnm-core/nm-setting-vlan.c:592 +#: ../shared/nm-glib-aux/nm-shared-utils.c:5266 #, c-format -msgid "'%s' value doesn't match '%s=%s'" -msgstr "значення «%s» не відповідає «%s=%s»" +msgid "'%%' is not allowed in interface names" +msgstr "«%%» не можна використовувати у назвах інтерфейсів" -#: ../libnm-core/nm-setting-6lowpan.c:117 -#: ../libnm-core/nm-setting-ip-tunnel.c:344 -#: ../libnm-core/nm-setting-macsec.c:301 ../libnm-core/nm-setting-macvlan.c:122 -#: ../libnm-core/nm-setting-vlan.c:608 ../libnm-core/nm-setting-vxlan.c:352 +#: ../shared/nm-glib-aux/nm-shared-utils.c:5278 #, c-format -msgid "'%s' is neither an UUID nor an interface name" -msgstr "«%s» не є ні UUID, ні назвою інтерфейсу" - -#: ../libnm-core/nm-setting-8021x.c:218 -msgid "binary data missing" -msgstr "не вистачає двійкових даних" +msgid "'%s' is not allowed as interface name" +msgstr "«%s» не можна використовувати як назву інтерфейсу" -#: ../libnm-core/nm-setting-8021x.c:250 -msgid "URI not NUL terminated" -msgstr "Адресу не завершено символом NUL" +#: ../shared/nm-glib-aux/nm-shared-utils.c:5300 +msgid "" +"interface name must be alphanumerical with no forward or backward slashes" +msgstr "" +"назва інтерфейсу має складатися з літер і цифр без початкового і " +"завершального символів похилої риски" -#: ../libnm-core/nm-setting-8021x.c:259 -msgid "URI is empty" -msgstr "Адреса є порожньою" +#: ../shared/nm-glib-aux/nm-shared-utils.c:5317 +msgid "interface name must not be empty" +msgstr "назва інтерфейсу не може бути порожньою" -#: ../libnm-core/nm-setting-8021x.c:267 -msgid "URI is not valid UTF-8" -msgstr "Адресу не є коректним рядком у кодуванні UTF-8" +#: ../shared/nm-glib-aux/nm-shared-utils.c:5325 +msgid "interface name must be UTF-8 encoded" +msgstr "назва інтерфейсу має бути набором символів у кодуванні UTF-8" -#: ../libnm-core/nm-setting-8021x.c:285 -msgid "data missing" -msgstr "пропущено дані" +#: ../shared/nm-log-core/nm-logging.c:251 +#, c-format +msgid "Unknown log level '%s'" +msgstr "Невідомий рівень ведення журналу, «%s»" -#: ../libnm-core/nm-setting-8021x.c:306 ../libnm-core/nm-setting-8021x.c:674 +#: ../shared/nm-log-core/nm-logging.c:359 #, c-format -msgid "certificate is invalid: %s" -msgstr "некоректний сертифікат: %s" +msgid "Unknown log domain '%s'" +msgstr "Невідомий домен ведення журналу, «%s»" -#: ../libnm-core/nm-setting-8021x.c:315 +#. TRANSLATORS: the first %s is a prefix for the connection id, such +#. * as "Wired Connection" or "VPN Connection". The %d is a number +#. * that is combined with the first argument to create a unique +#. * connection id. +#: ../src/core/NetworkManagerUtils.c:109 #, c-format -msgid "certificate detected as invalid scheme" -msgstr "сертифікат виявлено як некоректні дані" +msgctxt "connection id fallback" +msgid "%s %u" +msgstr "%s %u" -#: ../libnm-core/nm-setting-8021x.c:541 -msgid "CA certificate must be in X.509 format" -msgstr "Форматом сертифіката CA має бути X.509" +#: ../src/core/devices/bluetooth/nm-bluez-manager.c:1325 +#, c-format +msgid "%s Network" +msgstr "Мережа %s" -#: ../libnm-core/nm-setting-8021x.c:553 -msgid "invalid certificate format" -msgstr "некоректний формат сертифіката" +#: ../src/core/devices/bluetooth/nm-device-bt.c:301 +msgid "PAN requested, but Bluetooth device does not support NAP" +msgstr "" +"Надіслано запит щодо PAN, але у пристрої Bluetooth не передбачено підтримки " +"NAP" -#: ../libnm-core/nm-setting-8021x.c:685 -#, c-format -msgid "password is not supported when certificate is not on a PKCS#11 token" +#: ../src/core/devices/bluetooth/nm-device-bt.c:314 +msgid "PAN connections cannot specify GSM, CDMA, or serial settings" msgstr "" -"підтримки паролів не передбачено, якщо сертифікат не міститься у ключі " -"PKCS#11" +"Записи з'єднання PAN не можуть вказувати параметрів GSM, CDMA або " +"послідовного пристрою" -#: ../libnm-core/nm-setting-8021x.c:2628 ../libnm-core/nm-setting-8021x.c:2651 -#: ../libnm-core/nm-setting-8021x.c:2691 ../libnm-core/nm-setting-8021x.c:2714 -#: ../libnm-core/nm-setting-8021x.c:2764 ../libnm-core/nm-setting-8021x.c:2782 -#: ../libnm-core/nm-setting-8021x.c:2806 ../libnm-core/nm-setting-8021x.c:2824 -#: ../libnm-core/nm-setting-8021x.c:2855 ../libnm-core/nm-setting-adsl.c:165 -#: ../libnm-core/nm-setting-cdma.c:134 ../libnm-core/nm-setting-cdma.c:143 -#: ../libnm-core/nm-setting-connection.c:1083 -#: ../libnm-core/nm-setting-connection.c:1126 -#: ../libnm-core/nm-setting-connection.c:1321 -#: ../libnm-core/nm-setting-gsm.c:282 ../libnm-core/nm-setting-gsm.c:337 -#: ../libnm-core/nm-setting-gsm.c:380 ../libnm-core/nm-setting-gsm.c:389 -#: ../libnm-core/nm-setting-ip-config.c:5129 -#: ../libnm-core/nm-setting-ip4-config.c:206 -#: ../libnm-core/nm-setting-ip4-config.c:218 -#: ../libnm-core/nm-setting-pppoe.c:136 ../libnm-core/nm-setting-pppoe.c:145 -#: ../libnm-core/nm-setting-vpn.c:540 ../libnm-core/nm-setting-vpn.c:550 -#: ../libnm-core/nm-setting-wimax.c:104 -#: ../libnm-core/nm-setting-wireless-security.c:956 -#: ../libnm-core/nm-setting-wireless-security.c:984 -#: ../libnm-core/nm-setting.c:1240 -msgid "property is empty" -msgstr "властивість є порожньою" +#: ../src/core/devices/bluetooth/nm-device-bt.c:329 +msgid "PAN connection" +msgstr "З'єднання PAN" -#: ../libnm-core/nm-setting-8021x.c:2667 ../libnm-core/nm-setting-8021x.c:2730 -#, c-format -msgid "has to match '%s' property for PKCS#12" -msgstr "має відповідати властивості «%s» для PKCS#12" +#: ../src/core/devices/bluetooth/nm-device-bt.c:336 +msgid "DUN requested, but Bluetooth device does not support DUN" +msgstr "" +"Надіслано запит щодо DUN, але у пристрої Bluetooth не передбачено підтримки " +"DUN" -#: ../libnm-core/nm-setting-8021x.c:2933 -msgid "can be enabled only on Ethernet connections" -msgstr "можна вмикати лише для з'єднань Ethernet" +#: ../src/core/devices/bluetooth/nm-device-bt.c:349 +msgid "DUN connection must include a GSM or CDMA setting" +msgstr "З'єднання DUN має включати параметр GSM або CDMA" -#: ../libnm-core/nm-setting-8021x.c:2954 -#: ../libnm-core/nm-setting-bluetooth.c:92 -#: ../libnm-core/nm-setting-infiniband.c:163 -#: ../libnm-core/nm-setting-infiniband.c:175 -#: ../libnm-core/nm-setting-ip4-config.c:194 -#: ../libnm-core/nm-setting-ip6-config.c:243 -#: ../libnm-core/nm-setting-ip6-config.c:257 -#: ../libnm-core/nm-setting-olpc-mesh.c:121 -#: ../libnm-core/nm-setting-wifi-p2p.c:132 ../libnm-core/nm-setting-wimax.c:116 -#: ../libnm-core/nm-setting-wired.c:786 ../libnm-core/nm-setting-wired.c:799 -#: ../libnm-core/nm-setting-wireless-security.c:1009 -#: ../libnm-core/nm-setting-wireless-security.c:1021 -#: ../libnm-core/nm-setting-wireless-security.c:1033 -#: ../libnm-core/nm-setting-wireless-security.c:1046 -#: ../libnm-core/nm-setting-wireless-security.c:1059 -#: ../libnm-core/nm-setting-wireless-security.c:1090 -#: ../libnm-core/nm-setting-wireless-security.c:1141 -#: ../libnm-core/nm-setting-wireless-security.c:1190 -#: ../libnm-core/nm-setting-wireless.c:884 -#: ../libnm-core/nm-setting-wireless.c:896 -#: ../libnm-core/nm-setting-wireless.c:909 ../libnm-core/nm-setting-wpan.c:161 -#: ../libnm-core/nm-utils.c:4532 -msgid "property is invalid" -msgstr "властивість є некоректною" +#: ../src/core/devices/bluetooth/nm-device-bt.c:360 +#: ../src/core/devices/wwan/nm-modem-broadband.c:821 +msgid "GSM connection" +msgstr "З'єднання GSM" -#: ../libnm-core/nm-setting-8021x.c:2979 ../libnm-core/nm-setting-8021x.c:2992 -#: ../libnm-core/nm-setting-8021x.c:3005 ../libnm-core/nm-setting-8021x.c:3039 -#: ../libnm-core/nm-setting-8021x.c:3052 ../libnm-core/nm-setting-adsl.c:177 -#: ../libnm-core/nm-setting-adsl.c:190 ../libnm-core/nm-setting-bluetooth.c:127 -#: ../libnm-core/nm-setting-wireless-security.c:926 -#, c-format -msgid "'%s' is not a valid value for the property" -msgstr "«%s» не є коректним значенням властивості" +#: ../src/core/devices/bluetooth/nm-device-bt.c:362 +#: ../src/core/devices/wwan/nm-modem-broadband.c:846 +msgid "CDMA connection" +msgstr "З'єднання CDMA" -#: ../libnm-core/nm-setting-8021x.c:3018 -msgid "invalid auth flags" -msgstr "некоректні прапорці розпізнавання" +#: ../src/core/devices/bluetooth/nm-device-bt.c:370 +msgid "Unknown/unhandled Bluetooth connection type" +msgstr "Невідомий або непридатний тип з'єднання Bluetooth" -#: ../libnm-core/nm-setting-bluetooth.c:151 -#, c-format -msgid "'%s' connection requires '%s' or '%s' setting" -msgstr "з'єднання «%s» потребує параметра «%s» або «%s»" +#: ../src/core/devices/bluetooth/nm-device-bt.c:395 +msgid "connection does not match device" +msgstr "з'єднання не відповідає пристрою" -#: ../libnm-core/nm-setting-bluetooth.c:203 -#, c-format -msgid "'%s' connection requires '%s' setting" -msgstr "з'єднання «%s» потребує параметра «%s»" +#: ../src/core/devices/nm-device-6lowpan.c:190 +msgid "6LOWPAN connection" +msgstr "З'єднання 6LOWPAN" -#: ../libnm-core/nm-setting-bond.c:495 -#, c-format -msgid "'%s' option is empty" -msgstr "параметр «%s» є порожнім" +#: ../src/core/devices/nm-device-bond.c:89 +msgid "Bond connection" +msgstr "Прив'язане з'єднання" -#: ../libnm-core/nm-setting-bond.c:504 -#, c-format -msgid "'%s' is not a valid IPv4 address for '%s' option" -msgstr "«%s» не є припустимою адресою IPv4 для параметра «%s»" +#: ../src/core/devices/nm-device-bridge.c:155 +msgid "Bridge connection" +msgstr "З'єднання містка" -#: ../libnm-core/nm-setting-bond.c:531 -#, c-format -msgid "missing option name" -msgstr "не вказано назви параметра" +#: ../src/core/devices/nm-device-dummy.c:58 +msgid "Dummy connection" +msgstr "Фіктивне з'єднання" -#: ../libnm-core/nm-setting-bond.c:536 +#: ../src/core/devices/nm-device-ethernet-utils.c:20 #, c-format -msgid "invalid option '%s'" -msgstr "некоректний параметр «%s»" +msgid "Wired connection %d" +msgstr "Дротове з'єднання %d" -#: ../libnm-core/nm-setting-bond.c:572 -#, c-format -msgid "invalid value '%s' for option '%s'" -msgstr "некоректне значення «%s» для параметра «%s»" +#: ../src/core/devices/nm-device-ethernet.c:1677 +msgid "PPPoE connection" +msgstr "З'єднання PPPoE" -#: ../libnm-core/nm-setting-bond.c:814 -#, c-format -msgid "mandatory option '%s' is missing" -msgstr "пропущено обов'язковий параметр «%s»" +#: ../src/core/devices/nm-device-ethernet.c:1677 +msgid "Wired connection" +msgstr "Дротове з'єднання" + +#: ../src/core/devices/nm-device-ip-tunnel.c:399 +msgid "IP tunnel connection" +msgstr "З'єднання IP-тунель" -#: ../libnm-core/nm-setting-bond.c:824 -#, c-format -msgid "'%s' is not a valid value for '%s'" -msgstr "«%s» не є коректним значенням «%s»" +#: ../src/core/devices/nm-device-macvlan.c:389 +msgid "MACVLAN connection" +msgstr "З'єднання MACVLAN" -#: ../libnm-core/nm-setting-bond.c:837 -#, c-format -msgid "'%s=%s' is incompatible with '%s > 0'" -msgstr "«%s=%s» є несумісним з «%s > 0»" +#: ../src/core/devices/nm-device-tun.c:144 +msgid "TUN connection" +msgstr "З'єднання TUN" -#: ../libnm-core/nm-setting-bond.c:854 -#, c-format -msgid "'%s' is not valid for the '%s' option: %s" -msgstr "«%s» є некоректним для параметра «%s»: %s" +#: ../src/core/devices/nm-device-wpan.c:54 +msgid "WPAN connection" +msgstr "З'єднання WPAN" -#: ../libnm-core/nm-setting-bond.c:866 -#, c-format -msgid "'%s' option is only valid for '%s=%s'" -msgstr "параметр «%s» можна використовувати, лише якщо «%s=%s»" +#: ../src/core/devices/team/nm-device-team.c:88 +msgid "Team connection" +msgstr "Командне з'єднання" -#: ../libnm-core/nm-setting-bond.c:879 +#: ../src/core/devices/wifi/nm-wifi-utils.c:28 #, c-format -msgid "'%s=%s' is not a valid configuration for '%s'" -msgstr "«%s=%s» не є коректним налаштуванням для «%s»" +msgid "%s is incompatible with static WEP keys" +msgstr "%s є несумісним зі статичними ключами WEP" -#: ../libnm-core/nm-setting-bond.c:894 ../libnm-core/nm-setting-bond.c:905 -#, c-format -msgid "'%s' option requires '%s' option to be enabled" -msgstr "використання параметра «%s» вимагає вмикання параметра «%s»" +#: ../src/core/devices/wifi/nm-wifi-utils.c:63 +msgid "LEAP authentication requires a LEAP username" +msgstr "Для розпізнавання LEAP потрібне ім'я користувача LEAP" -#: ../libnm-core/nm-setting-bond.c:922 ../libnm-core/nm-setting-bond.c:933 -#, c-format -msgid "'%s' option requires '%s' option to be set" -msgstr "використання параметра «%s» вимагає встановлення параметра «%s»" +#: ../src/core/devices/wifi/nm-wifi-utils.c:75 +msgid "LEAP username requires 'leap' authentication" +msgstr "Ім'я користувача LEAP потребує розпізнавання «leap»" -#: ../libnm-core/nm-setting-bond.c:946 -#, c-format -msgid "'%s' option is only valid with mode '%s'" -msgstr "параметр «%s» є коректним лише у режимі «%s»" +#: ../src/core/devices/wifi/nm-wifi-utils.c:90 +msgid "LEAP authentication requires IEEE 802.1x key management" +msgstr "Розпізнавання LEAP потребує керування ключами IEEE 802.1x" -#: ../libnm-core/nm-setting-bond.c:959 -#, c-format -msgid "'%s' and '%s' cannot have different values" -msgstr "Значення «%s» і «%s» не можуть бути різними" +#: ../src/core/devices/wifi/nm-wifi-utils.c:112 +msgid "LEAP authentication is incompatible with Ad-Hoc mode" +msgstr "Розпізнавання LEAP є несумісним зі спеціальним (Ad-Hoc) режимом" -#: ../libnm-core/nm-setting-bond.c:982 -#, c-format -msgid "'%s' option should be string" -msgstr "параметр «%s» має бути рядком" +#: ../src/core/devices/wifi/nm-wifi-utils.c:124 +msgid "LEAP authentication is incompatible with 802.1x setting" +msgstr "Розпізнавання LEAP є несумісним із встановленням 802.1x" -#: ../libnm-core/nm-setting-bond.c:995 +#: ../src/core/devices/wifi/nm-wifi-utils.c:144 #, c-format -msgid "'%s' option is not valid with mode '%s'" -msgstr "параметр «%s» є коректним з режимом «%s»" +msgid "a connection using '%s' authentication cannot use WPA key management" +msgstr "" +"з'єднання, де використовується розпізнавання «%s», не може використовувати " +"керування ключами WPA" -#: ../libnm-core/nm-setting-bridge-port.c:302 -#: ../libnm-core/nm-setting-ovs-bridge.c:151 -#: ../libnm-core/nm-setting-ovs-interface.c:289 -#: ../libnm-core/nm-setting-ovs-port.c:170 -#: ../libnm-core/nm-setting-team-port.c:307 +#: ../src/core/devices/wifi/nm-wifi-utils.c:157 #, c-format -msgid "missing setting" -msgstr "пропущено параметр" +msgid "a connection using '%s' authentication cannot specify WPA protocols" +msgstr "" +"з'єднання, де використовується розпізнавання «%s», не може використовувати " +"специфічні протоколи WPA" -#: ../libnm-core/nm-setting-bridge-port.c:312 -#: ../libnm-core/nm-setting-ovs-interface.c:312 -#: ../libnm-core/nm-setting-ovs-port.c:193 -#: ../libnm-core/nm-setting-team-port.c:317 +#: ../src/core/devices/wifi/nm-wifi-utils.c:175 +#: ../src/core/devices/wifi/nm-wifi-utils.c:194 #, c-format -msgid "" -"A connection with a '%s' setting must have the slave-type set to '%s'. " -"Instead it is '%s'" +msgid "a connection using '%s' authentication cannot specify WPA ciphers" msgstr "" -"Для з'єднання з параметром «%s» має бути встановлено тип підлеглості «%s». " -"Замість цього маємо «%s»." +"з'єднання, де використовується розпізнавання «%s», не може використовувати " +"специфічні шифри WPA" -#: ../libnm-core/nm-setting-bridge.c:1165 +#: ../src/core/devices/wifi/nm-wifi-utils.c:208 #, c-format -msgid "value '%d' is out of range <%d-%d>" -msgstr "значення «%d» лежить поза діапазоном <%d-%d>" - -#: ../libnm-core/nm-setting-bridge.c:1184 -msgid "is not a valid MAC address" -msgstr "не є коректною MAC-адресою" +msgid "a connection using '%s' authentication cannot specify a WPA password" +msgstr "" +"з'єднання, де використовується розпізнавання «%s», не може використовувати " +"специфічний пароль WPA" -#: ../libnm-core/nm-setting-bridge.c:1228 -msgid "the mask can't contain bits 0 (STP), 1 (MAC) or 2 (LACP)" -msgstr "маска не може містити біти 0 (STP), 1 (MAC) і 2 (LACP)" +#: ../src/core/devices/wifi/nm-wifi-utils.c:241 +msgid "Dynamic WEP requires an 802.1x setting" +msgstr "Динамічний WEP потребує встановлення параметра 802.1x" -#: ../libnm-core/nm-setting-bridge.c:1250 -msgid "is not a valid link local MAC address" -msgstr "не є коректною MAC-адресою для локальних з'єднань" +#: ../src/core/devices/wifi/nm-wifi-utils.c:251 +#: ../src/core/devices/wifi/nm-wifi-utils.c:283 +msgid "Dynamic WEP requires 'open' authentication" +msgstr "Динамічний WEP потребує розпізнавання «open»" -#: ../libnm-core/nm-setting-bridge.c:1262 -msgid "is not a valid VLAN filtering protocol" -msgstr "не є коректним протоколом фільтрування VLAN" +#: ../src/core/devices/wifi/nm-wifi-utils.c:268 +msgid "Dynamic WEP requires 'ieee8021x' key management" +msgstr "Динамічний WEP потребує керування ключами «ieee8021x»" -#: ../libnm-core/nm-setting-bridge.c:1274 -msgid "is not a valid option" -msgstr "не є коректним параметром" +#: ../src/core/devices/wifi/nm-wifi-utils.c:319 +msgid "WPA-PSK authentication is incompatible with 802.1x" +msgstr "Розпізнавання за допомогою WPA-PSK є несумісним з 802.1x" -#: ../libnm-core/nm-setting-bridge.c:1286 -#, c-format -msgid "'%s' option must be a power of 2" -msgstr "Значенням параметра «%s» має бути степінь 2" +#: ../src/core/devices/wifi/nm-wifi-utils.c:329 +msgid "WPA-PSK requires 'open' authentication" +msgstr "WPA-PSK потребує розпізнавання «open»" -#: ../libnm-core/nm-setting-connection.c:967 -#, c-format -msgid "setting required for connection of type '%s'" -msgstr "для з'єднання типу «%s» потрібен параметр" +#: ../src/core/devices/wifi/nm-wifi-utils.c:343 +msgid "Access point does not support PSK but setting requires it" +msgstr "" +"У точці доступу не передбачено підтримки PSK, але параметром передбачено " +"таку підтримку" -#: ../libnm-core/nm-setting-connection.c:998 -#, c-format -msgid "Unknown slave type '%s'" -msgstr "Невідомий тип підлеглого «%s»" +#: ../src/core/devices/wifi/nm-wifi-utils.c:358 +msgid "WPA Ad-Hoc authentication requires 'rsn' protocol" +msgstr "Розпізнавання за спеціальним WPA потребує протоколу «rsn»" -#: ../libnm-core/nm-setting-connection.c:1013 -#, c-format -msgid "Slave connections need a valid '%s' property" -msgstr "Для підлеглих з'єднань потрібна коректна властивість «%s»" +#: ../src/core/devices/wifi/nm-wifi-utils.c:371 +msgid "WPA Ad-Hoc authentication requires 'ccmp' pairwise cipher" +msgstr "Розпізнавання за спеціальним WPA потребує парного шифру «ccmp»" -#: ../libnm-core/nm-setting-connection.c:1037 -#, c-format -msgid "Cannot set '%s' without '%s'" -msgstr "Не можна встановити «%s» без «%s»" +#: ../src/core/devices/wifi/nm-wifi-utils.c:384 +msgid "WPA Ad-Hoc requires 'ccmp' group cipher" +msgstr "Спеціальний (Ad-Hoc) режим WPA потребує групового шифрування «ccmp»" -#: ../libnm-core/nm-setting-connection.c:1095 -#, c-format -msgid "'%s' is not a valid UUID" -msgstr "«%s» не є коректним UUID" +#: ../src/core/devices/wifi/nm-wifi-utils.c:415 +msgid "WPA-EAP authentication requires an 802.1x setting" +msgstr "Розпізнавання WPA-EAP потребує параметра 802.1x" -#: ../libnm-core/nm-setting-connection.c:1140 -#, c-format -msgid "connection type '%s' is not valid" -msgstr "тип з'єднання «%s» є некоректним" +#: ../src/core/devices/wifi/nm-wifi-utils.c:425 +msgid "WPA-EAP requires 'open' authentication" +msgstr "WPA-EAP потребує розпізнавання «open»" -#: ../libnm-core/nm-setting-connection.c:1246 -#, c-format -msgid "'%s' connections must be enslaved to '%s', not '%s'" -msgstr "з'єднання «%s» мають підпорядковуватися «%s», а не «%s»" +#: ../src/core/devices/wifi/nm-wifi-utils.c:438 +msgid "802.1x setting requires 'wpa-eap' key management" +msgstr "Параметр 802.1x потребує керування ключами «wpa-eap»" -#: ../libnm-core/nm-setting-connection.c:1262 -#, c-format -msgid "metered value %d is not valid" -msgstr "лічильне значення %d є некоректним" +#: ../src/core/devices/wifi/nm-wifi-utils.c:452 +msgid "Access point does not support 802.1x but setting requires it" +msgstr "" +"У точці доступу не передбачено підтримки 802.1x, але параметром передбачено " +"таку підтримку" -#: ../libnm-core/nm-setting-connection.c:1276 -#: ../libnm-core/nm-setting-connection.c:1290 -#: ../libnm-core/nm-setting-connection.c:1307 -#, c-format -msgid "value %d is not valid" -msgstr "значення %d є некоректним" +#: ../src/core/devices/wifi/nm-wifi-utils.c:482 +msgid "Ad-Hoc mode requires 'none' or 'wpa-psk' key management" +msgstr "" +"Для ситуативного режиму слід використовувати керування ключами «none» або " +"«wpa-psk»" -#: ../libnm-core/nm-setting-connection.c:1335 -msgid "DHCP option cannot be longer than 255 characters" -msgstr "Довжина параметра DHCP не може перевищувати 255 символів" +#: ../src/core/devices/wifi/nm-wifi-utils.c:494 +msgid "Ad-Hoc mode is incompatible with 802.1x security" +msgstr "Спеціальний (Ad-Hoc) режим є несумісним із захистом 802.1x" -#: ../libnm-core/nm-setting-connection.c:1346 -msgid "MUD URL is not a valid URL" -msgstr "Адреса MUD не є коректною адресою" +#: ../src/core/devices/wifi/nm-wifi-utils.c:503 +msgid "Ad-Hoc mode is incompatible with LEAP security" +msgstr "Спеціальний (Ad-Hoc) режим є несумісним із захистом LEAP" -#: ../libnm-core/nm-setting-connection.c:1366 -msgid "invalid permissions not in format \"user:$UNAME[:]\"" -msgstr "некоректний запис прав доступу, не у форматі «користувач:$UNAME[:]»" +#: ../src/core/devices/wifi/nm-wifi-utils.c:515 +msgid "Ad-Hoc mode requires 'open' authentication" +msgstr "Для спеціального (Ad-Hoc) режиму потрібне розпізнавання «open»" -#: ../libnm-core/nm-setting-connection.c:1395 +#: ../src/core/devices/wifi/nm-wifi-utils.c:559 +#: ../src/core/devices/wifi/nm-wifi-utils.c:594 #, c-format -msgid "property type should be set to '%s'" -msgstr "тип властивості має бути встановлено у значення «%s»" +msgid "connection does not match access point" +msgstr "з'єднання не відповідає точці доступу" -#: ../libnm-core/nm-setting-connection.c:1413 +#: ../src/core/devices/wifi/nm-wifi-utils.c:648 #, c-format -msgid "slave-type '%s' requires a '%s' setting in the connection" -msgstr "тип підлеглого з'єднання «%s» потребує параметра «%s» у з'єднанні" +msgid "connection does not match mesh point" +msgstr "з'єднання не відповідає точці сітки" -#: ../libnm-core/nm-setting-connection.c:1424 -#, c-format -msgid "" -"Detect a slave connection with '%s' set and a port type '%s'. '%s' should be " -"set to '%s'" +#: ../src/core/devices/wifi/nm-wifi-utils.c:667 +msgid "Access point is unencrypted but setting specifies security" msgstr "" -"Визначити підлегле з'єднання зі встановленим «%s» і типом порту «%s». «%s» " -"слід встановити у значення «%s»" +"Обмін даними із точкою доступу є незашифрованим, але запис вказує за " +"захищене з'єднання" -#: ../libnm-core/nm-setting-connection.c:1450 -#, c-format -msgid "A slave connection with '%s' set to '%s' cannot have a '%s' setting" +#: ../src/core/devices/wifi/nm-wifi-utils.c:758 +msgid "" +"WPA authentication is incompatible with non-EAP (original) LEAP or Dynamic " +"WEP" msgstr "" -"Підлегле з'єднання з «%s», переведене у режим «%s», не може мати параметра " -"«%s»" - -#: ../libnm-core/nm-setting-dcb.c:483 -msgid "flags invalid" -msgstr "некоректні прапорці" - -#: ../libnm-core/nm-setting-dcb.c:492 -msgid "flags invalid - disabled" -msgstr "некоректні прапорці — вимкнено" - -#: ../libnm-core/nm-setting-dcb.c:518 ../libnm-core/nm-setting-dcb.c:564 -msgid "property invalid (not enabled)" -msgstr "властивість є некоректною (не увімкнено)" - -#: ../libnm-core/nm-setting-dcb.c:527 -msgid "element invalid" -msgstr "некоректний елемент" +"Розпізнавання за допомогою WPA є несумісним з LEAP без EAP (оригінальним) " +"або динамічним WEP" -#: ../libnm-core/nm-setting-dcb.c:542 -msgid "sum not 100%" -msgstr "сума не дорівнює 100%" +#: ../src/core/devices/wifi/nm-wifi-utils.c:771 +msgid "WPA authentication is incompatible with Shared Key authentication" +msgstr "" +"Розпізнавання за допомогою WPA є несумісним із розпізнаванням за допомогою " +"розповсюдженого ключа" -#: ../libnm-core/nm-setting-dcb.c:573 ../libnm-core/nm-setting-dcb.c:608 -msgid "property invalid" -msgstr "некоректна властивість" +#: ../src/core/devices/wifi/nm-wifi-utils.c:854 +msgid "Failed to determine AP security information" +msgstr "Не вдалося визначити дані щодо захисту точки доступу" -#: ../libnm-core/nm-setting-dcb.c:598 -msgid "property missing" -msgstr "пропущено властивість" +#: ../src/core/dhcp/nm-dhcp-dhclient-utils.c:316 +msgid "# Created by NetworkManager\n" +msgstr "# Створено за допомогою NetworkManager\n" -#: ../libnm-core/nm-setting-ethtool.c:291 -msgid "unsupported ethtool setting" -msgstr "непідтримуваний параметр ethtool" +#: ../src/core/dhcp/nm-dhcp-dhclient-utils.c:329 +#, c-format +msgid "" +"# Merged from %s\n" +"\n" +msgstr "" +"# Об'єднано з %s\n" +"\n" -#: ../libnm-core/nm-setting-ethtool.c:300 -msgid "setting has invalid variant type" -msgstr "для параметра вказано некоректний тип варіанта" +#: ../src/core/main-utils.c:87 +#, c-format +msgid "Opening %s failed: %s\n" +msgstr "Помилка під час спроби відкрити %s: %s\n" -#: ../libnm-core/nm-setting-ethtool.c:312 -msgid "coalesce option must be either 0 or 1" -msgstr "значенням параметра coalesce має бути 0 або 1" +#: ../src/core/main-utils.c:94 +#, c-format +msgid "Writing to %s failed: %s\n" +msgstr "Помилка під час спроби запису даних до %s: %s\n" -#: ../libnm-core/nm-setting-ethtool.c:335 +#: ../src/core/main-utils.c:100 #, c-format -msgid "unknown ethtool option '%s'" -msgstr "невідомий параметр ethtool «%s»" +msgid "Closing %s failed: %s\n" +msgstr "Не вдалося завершити роботу %s: %s\n" -#: ../libnm-core/nm-setting-gsm.c:295 +#: ../src/core/main-utils.c:140 ../src/core/main-utils.c:152 #, c-format -msgid "property value '%s' is empty or too long (>64)" -msgstr "значення властивості, «%s», є порожнім або надто довгим (>64)" +msgid "Cannot create '%s': %s" +msgstr "Не вдалося створити «%s»: %s" -#: ../libnm-core/nm-setting-gsm.c:325 +#: ../src/core/main-utils.c:207 #, c-format -msgid "'%s' contains invalid char(s) (use [A-Za-z._-])" -msgstr "«%s» містить некоректні символи (слід використовувати [A-Za-z._-])" +msgid "%s is already running (pid %ld)\n" +msgstr "%s вже працює (pid %ld)\n" -#: ../libnm-core/nm-setting-gsm.c:351 +#: ../src/core/main-utils.c:217 #, c-format -msgid "'%s' length is invalid (should be 5 or 6 digits)" -msgstr "довжина «%s» є некоректною (має бути 5 або 6 цифр)" +msgid "You must be root to run %s!\n" +msgstr "Для виконання %s потрібно перейти у режим root!\n" -#: ../libnm-core/nm-setting-gsm.c:365 +#: ../src/core/main-utils.c:284 ../src/core/main.c:374 +#: ../src/core/nm-iface-helper.c:585 #, c-format -msgid "'%s' is not a number" -msgstr "«%s» не є числом" +msgid "%s. Please use --help to see a list of valid options.\n" +msgstr "" +"%s. Щоб ознайомитися зі списком параметрів, скористайтеся параметром --" +"help.\n" -#: ../libnm-core/nm-setting-gsm.c:402 -msgid "property is empty or wrong size" -msgstr "властивість є порожньою або має помилковий розмір" +#: ../src/core/main.c:163 ../src/core/main.c:384 +#, c-format +msgid "Failed to read configuration: %s\n" +msgstr "Не вдалося прочитати налаштування: %s\n" -#: ../libnm-core/nm-setting-gsm.c:415 -msgid "property must contain only digits" -msgstr "властивість має містити лише цифри" +#: ../src/core/main.c:190 ../src/core/nm-iface-helper.c:406 +msgid "Print NetworkManager version and exit" +msgstr "Вивести дані щодо версії NetworkManager і завершити роботу" -#: ../libnm-core/nm-setting-gsm.c:429 -msgid "can't be enabled when manual configuration is present" -msgstr "не можна вмикати, якщо є налаштування вручну" +#: ../src/core/main.c:197 ../src/core/nm-iface-helper.c:413 +msgid "Don't become a daemon" +msgstr "Не переходити у стан фонової служби" -#: ../libnm-core/nm-setting-infiniband.c:201 -msgid "Must specify a P_Key if specifying parent" -msgstr "Якщо вказано параметр parent, слід вказати і P_Key" +#: ../src/core/main.c:204 ../src/core/nm-iface-helper.c:427 +#, c-format +msgid "Log level: one of [%s]" +msgstr "Рівень докладності журналу: одне з таких значень: [%s]" -#: ../libnm-core/nm-setting-infiniband.c:212 -msgid "InfiniBand P_Key connection did not specify parent interface name" +#: ../src/core/main.c:211 ../src/core/nm-iface-helper.c:434 +#, c-format +msgid "Log domains separated by ',': any combination of [%s]" msgstr "" -"У записі з'єднання закритого ключа InfiniBand не вказано назви батьківського " -"інтерфейсу" +"Список доменів для ведення журналу, відокремлених символом «,»: будь-яка " +"комбінація з [%s]" -#: ../libnm-core/nm-setting-infiniband.c:234 -#, c-format +#: ../src/core/main.c:218 ../src/core/nm-iface-helper.c:441 +msgid "Make all warnings fatal" +msgstr "Вважати всі попередження помилками" + +#: ../src/core/main.c:225 +msgid "Specify the location of a PID file" +msgstr "Вказати розташування файла ідентифікатора процесу (PID)" + +#: ../src/core/main.c:239 +msgid "Print NetworkManager configuration and exit" +msgstr "Вивести дані щодо налаштувань NetworkManager і завершити роботу" + +#: ../src/core/main.c:250 msgid "" -"interface name of software infiniband device must be '%s' or unset (instead " -"it is '%s')" +"NetworkManager monitors all network connections and automatically\n" +"chooses the best connection to use. It also allows the user to\n" +"specify wireless access points which wireless cards in the computer\n" +"should associate with." msgstr "" -"назвою інтерфейсу програмного пристрою infiniband має бути «%s» або назву " -"має бути не встановлено (замість неї має бути «%s»)" +"NetworkManager виконує стеження за всіма з'єднаннями і автоматично\n" +"вибирає з них найкраще для використання. Крім того, програма\n" +"надає користувачеві змогу вказати точки бездротового доступу,\n" +"з якими слід пов'язувати картки бездротового доступу на вашому\n" +"комп'ютері." -#: ../libnm-core/nm-setting-infiniband.c:262 +#: ../src/core/main.c:407 ../src/core/nm-iface-helper.c:599 #, c-format -msgid "mtu can be at most %u but it is %u" -msgstr "mtu не може перевищувати %u, але маємо %u" +msgid "Could not daemonize: %s [error %u]\n" +msgstr "Не вдалося створити фонову службу: %s [помилка %u]\n" -#: ../libnm-core/nm-setting-ip-config.c:111 +#: ../src/core/nm-config.c:567 #, c-format -msgid "Missing IPv4 address" -msgstr "Не вказано адреси IPv4" +msgid "Bad '%s' option: " +msgstr "Помилковий параметр «%s»: " -#: ../libnm-core/nm-setting-ip-config.c:111 -#, c-format -msgid "Missing IPv6 address" -msgstr "Не вказано адреси IPv6" +#: ../src/core/nm-config.c:584 +msgid "Config file location" +msgstr "Розташування файла налаштувань" -#: ../libnm-core/nm-setting-ip-config.c:118 -#, c-format -msgid "Invalid IPv4 address '%s'" -msgstr "Некоректна адреса IPv4, «%s»" +#: ../src/core/nm-config.c:591 +msgid "Config directory location" +msgstr "Розташування каталогу налаштувань" -#: ../libnm-core/nm-setting-ip-config.c:119 -#, c-format -msgid "Invalid IPv6 address '%s'" -msgstr "Некоректна адреса IPv6, «%s»" +#: ../src/core/nm-config.c:598 +msgid "System config directory location" +msgstr "Розташування загальносистемного каталогу налаштувань" -#: ../libnm-core/nm-setting-ip-config.c:135 -#, c-format -msgid "Invalid IPv4 address prefix '%u'" -msgstr "Некоректний префікс адреси IPv4, «%u»" +#: ../src/core/nm-config.c:605 +msgid "Internal config file location" +msgstr "Розташування внутрішнього файла налаштувань" -#: ../libnm-core/nm-setting-ip-config.c:136 -#, c-format -msgid "Invalid IPv6 address prefix '%u'" -msgstr "Некоректний префікс адреси IPv6, «%u»" +#: ../src/core/nm-config.c:612 +msgid "State file location" +msgstr "Розташування файла стану" -#: ../libnm-core/nm-setting-ip-config.c:153 -#, c-format -msgid "Invalid routing metric '%s'" -msgstr "Некоректна метрика маршрутизації, «%s»" +#: ../src/core/nm-config.c:619 +msgid "State file for no-auto-default devices" +msgstr "" +"Файл станів для пристроїв без автоматичних типових параметрів (no-auto-" +"default)" -#: ../libnm-core/nm-setting-ip-config.c:1317 -#: ../libnm-core/nm-setting-sriov.c:399 -msgid "unknown attribute" -msgstr "невідомий атрибут" +#: ../src/core/nm-config.c:626 +msgid "List of plugins separated by ','" +msgstr "Список додатків, відокремлених комами («,»)" -#: ../libnm-core/nm-setting-ip-config.c:1327 -#: ../libnm-core/nm-setting-sriov.c:409 -#, c-format -msgid "invalid attribute type '%s'" -msgstr "некоректний тип атрибута «%s»" +#: ../src/core/nm-config.c:633 +msgid "Quit after initial configuration" +msgstr "Вийти після початкового налаштовування" -#: ../libnm-core/nm-setting-ip-config.c:1336 -#, c-format -msgid "attribute is not valid for a IPv4 route" -msgstr "атрибут не є коректним для маршрутизації IPv4" +#: ../src/core/nm-config.c:640 ../src/core/nm-iface-helper.c:420 +msgid "Don't become a daemon, and log to stderr" +msgstr "" +"Не переходити у стан фонової служби і записувати повідомлення журналу до " +"stderr" -#: ../libnm-core/nm-setting-ip-config.c:1337 -#, c-format -msgid "attribute is not valid for a IPv6 route" -msgstr "атрибут не є коректним для маршрутизації IPv6" +#: ../src/core/nm-config.c:649 +msgid "An http(s) address for checking internet connectivity" +msgstr "Адреса http(s) для спроб перевірки можливості встановлення з'єднання" -#: ../libnm-core/nm-setting-ip-config.c:1350 -#: ../libnm-core/nm-setting-ip-config.c:1380 -#, c-format -msgid "'%s' is not a valid IPv4 address" -msgstr "«%s» не є коректною адресою IPv4" +#: ../src/core/nm-config.c:656 +msgid "The interval between connectivity checks (in seconds)" +msgstr "Інтервал між перевірками можливості з'єднання (у секундах)" -#: ../libnm-core/nm-setting-ip-config.c:1351 -#: ../libnm-core/nm-setting-ip-config.c:1381 -#, c-format -msgid "'%s' is not a valid IPv6 address" -msgstr "«%s» не є коректною адресою IPv6" +#: ../src/core/nm-config.c:663 +msgid "The expected start of the response" +msgstr "Очікуваний початок відповіді" -#: ../libnm-core/nm-setting-ip-config.c:1371 -#, c-format -msgid "invalid prefix %s" -msgstr "некоректний префікс %s" +#: ../src/core/nm-config.c:672 +msgid "NetworkManager options" +msgstr "Параметри NetworkManager" -#: ../libnm-core/nm-setting-ip-config.c:1392 -#, c-format -msgid "%s is not a valid route type" -msgstr "%s не є коректним типом маршруту" +#: ../src/core/nm-config.c:673 +msgid "Show NetworkManager options" +msgstr "Показати параметри NetworkManager" -#: ../libnm-core/nm-setting-ip-config.c:1447 -#, c-format -msgid "route scope is invalid" -msgstr "область маршрутів є некоректною" +#: ../src/core/nm-iface-helper.c:292 +msgid "The interface to manage" +msgstr "Інтерфейс для керування" -#: ../libnm-core/nm-setting-ip-config.c:2558 -msgid "invalid priority" -msgstr "некоректна пріоритетність" +#: ../src/core/nm-iface-helper.c:299 +msgid "Connection UUID" +msgstr "UUID з'єднання" -#: ../libnm-core/nm-setting-ip-config.c:2571 -msgid "missing table" -msgstr "не вказано таблиці" +#: ../src/core/nm-iface-helper.c:306 +msgid "Connection Token for Stable IDs" +msgstr "Жетон з'єднання для стабільних ідентифікаторів" -#: ../libnm-core/nm-setting-ip-config.c:2579 -msgid "invalid action" -msgstr "некоректна дія" +#: ../src/core/nm-iface-helper.c:313 +msgid "Whether to manage IPv6 SLAAC" +msgstr "Чи слід керувати SLAAC IPv6" -#: ../libnm-core/nm-setting-ip-config.c:2588 -msgid "has from/src but the prefix-length is zero" -msgstr "" -"містить from/src, але значення довжини префікса (prefix-length) є нульовим" +#: ../src/core/nm-iface-helper.c:320 +msgid "Whether SLAAC must be successful" +msgstr "Чи має бути SLAAC успішним" -#: ../libnm-core/nm-setting-ip-config.c:2596 -msgid "missing from/src for a non zero prefix-length" -msgstr "пропущено from/src для ненульового значення довжини префікса" +#: ../src/core/nm-iface-helper.c:327 +msgid "Use an IPv6 temporary privacy address" +msgstr "Використовувати тимчасову приватну адресу IPv6" -#: ../libnm-core/nm-setting-ip-config.c:2603 -msgid "invalid from/src" -msgstr "некоректне значення from/src" +#: ../src/core/nm-iface-helper.c:334 +msgid "Current DHCPv4 address" +msgstr "Поточна адреса DHCPv4" -#: ../libnm-core/nm-setting-ip-config.c:2610 -msgid "invalid prefix length for from/src" -msgstr "некоректна довжина префікса для from/src" +#: ../src/core/nm-iface-helper.c:341 +msgid "Whether DHCPv4 must be successful" +msgstr "Чи має DHCPv4 бути успішним" + +#: ../src/core/nm-iface-helper.c:348 +msgid "Hex-encoded DHCPv4 client ID" +msgstr "Закодований у шістнадцяткову форму ідентифікатор клієнта DHCPv4" + +#: ../src/core/nm-iface-helper.c:355 +msgid "Hostname to send to DHCP server" +msgstr "Назва вузла для надсилання на сервер DHCP" + +#: ../src/core/nm-iface-helper.c:356 +msgid "barbar" +msgstr "щосьщось" -#: ../libnm-core/nm-setting-ip-config.c:2619 -msgid "has to/dst but the prefix-length is zero" -msgstr "" -"містить to/dst, але значення довжини префікса (prefix-length) є нульовим" +#: ../src/core/nm-iface-helper.c:362 +msgid "FQDN to send to DHCP server" +msgstr "Повна назва вузла (FQDN) для надсилання на сервер DHCP" -#: ../libnm-core/nm-setting-ip-config.c:2627 -msgid "missing to/dst for a non zero prefix-length" -msgstr "пропущено to/dst для ненульового значення довжини префікса" +#: ../src/core/nm-iface-helper.c:363 +msgid "host.domain.org" +msgstr "вузол.домен.org" -#: ../libnm-core/nm-setting-ip-config.c:2634 -msgid "invalid to/dst" -msgstr "некоректне значення to/dst" +#: ../src/core/nm-iface-helper.c:369 +msgid "Route priority for IPv4" +msgstr "Пріоритет маршруту для IPv4" -#: ../libnm-core/nm-setting-ip-config.c:2641 -msgid "invalid prefix length for to/dst" -msgstr "некоректна довжина префікса для to/dst" +#: ../src/core/nm-iface-helper.c:370 +msgid "0" +msgstr "0" -#: ../libnm-core/nm-setting-ip-config.c:2651 -msgid "invalid iifname" -msgstr "некоректна назва інтерфейсу" +#: ../src/core/nm-iface-helper.c:376 +msgid "Route priority for IPv6" +msgstr "Пріоритет маршруту для IPv6" -#: ../libnm-core/nm-setting-ip-config.c:2661 -msgid "invalid oifname" -msgstr "некоректна назва інтерфейсу (oifname)" +#: ../src/core/nm-iface-helper.c:377 +msgid "1024" +msgstr "1024" -#: ../libnm-core/nm-setting-ip-config.c:2669 -msgid "invalid source port range" -msgstr "некоректний діапазон номерів порту джерела" +#: ../src/core/nm-iface-helper.c:383 +msgid "Hex-encoded Interface Identifier" +msgstr "Закодований у шістнадцяткове число ідентифікатор інтерфейсу" -#: ../libnm-core/nm-setting-ip-config.c:2677 -msgid "invalid destination port range" -msgstr "некоректний діапазон номерів порту призначення" +#: ../src/core/nm-iface-helper.c:390 +msgid "IPv6 SLAAC address generation mode" +msgstr "Режим створення адреси SLAAC IPv6" -#: ../libnm-core/nm-setting-ip-config.c:2687 -msgid "suppress_prefixlength out of range" -msgstr "suppress_prefixlength поза припустимим діапазоном" +#: ../src/core/nm-iface-helper.c:397 +msgid "" +"The logging backend configuration value. See logging.backend in " +"NetworkManager.conf" +msgstr "" +"Значення налаштування модуля ведення журналу. Див. logging.backend у " +"NetworkManager.conf" -#: ../libnm-core/nm-setting-ip-config.c:2695 -msgid "suppress_prefixlength is only allowed with the to-table action" +#: ../src/core/nm-iface-helper.c:451 +msgid "" +"nm-iface-helper is a small, standalone process that manages a single network " +"interface." msgstr "" -"suppress_prefixlength можна використовувати лише разом із дією to-table" +"nm-iface-helper — малий окремий процес, який керує окремим інтерфейсом " +"мережі." -#: ../libnm-core/nm-setting-ip-config.c:2808 +#: ../src/core/nm-iface-helper.c:562 #, c-format -msgid "duplicate key %s" -msgstr "дублікат ключа %s" +msgid "An interface name and UUID are required\n" +msgstr "Потрібні назва і UUID інтерфейсу\n" -#: ../libnm-core/nm-setting-ip-config.c:2823 +#: ../src/core/nm-iface-helper.c:570 #, c-format -msgid "invalid key \"%s\"" -msgstr "некоректний ключ «%s»" +msgid "Failed to find interface index for %s (%s)\n" +msgstr "Не вдалося знайти покажчик інтерфейсу для %s (%s)\n" -#: ../libnm-core/nm-setting-ip-config.c:2836 +#: ../src/core/nm-iface-helper.c:590 #, c-format -msgid "invalid variant type '%s' for \"%s\"" -msgstr "некоректний тип варіанта «%s» для «%s»" +msgid "Ignoring unrecognized log domain(s) '%s' passed on command line.\n" +msgstr "" +"Ігноруємо нерозпізнані домени журналювання, «%s», передані за допомогою " +"командного рядка.\n" -#: ../libnm-core/nm-setting-ip-config.c:2847 -msgid "missing \"" -msgstr "не вистачає \"" +#: ../src/core/nm-iface-helper.c:636 +#, c-format +msgid "(%s): Invalid IID %s\n" +msgstr "(%s): некоректний IID %s\n" -#: ../libnm-core/nm-setting-ip-config.c:2855 -msgid "invalid \"" -msgstr "некоректна \"" +#: ../src/core/nm-iface-helper.c:648 +#, c-format +msgid "(%s): Invalid DHCP client-id %s\n" +msgstr "(%s): некоректний ідентифікатор клієнта DHCP %s\n" -#: ../libnm-core/nm-setting-ip-config.c:3069 -msgid "Unsupported to-string-flags argument" -msgstr "Непідтримуваний аргумент to-string-flags" +#: ../src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c:9941 +#: ../src/libnm-core-impl/nm-team-utils.c:2396 +#, c-format +msgid "invalid json" +msgstr "некоректний код JSON" -#: ../libnm-core/nm-setting-ip-config.c:3077 -msgid "Unsupported extra-argument" -msgstr "Непідтримуваний додатковий аргумент" +#: ../src/libnm-core-aux-extern/nm-libnm-core-aux.c:286 +#, c-format +msgid "'%s' is not valid: properties should be specified as 'key=value'" +msgstr "" +"«%s» є некоректним: властивості має бути вказано у форматі «ключ=значення»" -#: ../libnm-core/nm-setting-ip-config.c:3339 +#: ../src/libnm-core-aux-extern/nm-libnm-core-aux.c:300 #, c-format -msgid "unsupported key \"%s\"" -msgstr "непідтримуваний ключ «%s»" +msgid "'%s' is not a valid key" +msgstr "«%s» не є коректним ключем" -#: ../libnm-core/nm-setting-ip-config.c:3346 +#: ../src/libnm-core-aux-extern/nm-libnm-core-aux.c:305 #, c-format -msgid "duplicate key \"%s\"" +msgid "duplicate key '%s'" msgstr "дублікат ключа «%s»" -#: ../libnm-core/nm-setting-ip-config.c:3353 +#: ../src/libnm-core-aux-extern/nm-libnm-core-aux.c:319 #, c-format -msgid "invalid value for \"%s\"" -msgstr "некоректне значення «%s»" - -#: ../libnm-core/nm-setting-ip-config.c:3365 -msgid "empty text does not describe a rule" -msgstr "порожній текст не описує правило" +msgid "number for '%s' is out of range" +msgstr "число для «%s» лежить поза припустимим діапазоном" -#: ../libnm-core/nm-setting-ip-config.c:3373 +#: ../src/libnm-core-aux-extern/nm-libnm-core-aux.c:324 #, c-format -msgid "missing argument for \"%s\"" -msgstr "пропущено аргумент «%s»" +msgid "value for '%s' must be a number" +msgstr "значення «%s» має бути числом" -#: ../libnm-core/nm-setting-ip-config.c:3387 -msgid "invalid \"from\" part" -msgstr "некоректна частина «from»" +#: ../src/libnm-core-aux-extern/nm-libnm-core-aux.c:337 +#, c-format +msgid "value for '%s' must be a boolean" +msgstr "значення «%s» має бути булевим" -#: ../libnm-core/nm-setting-ip-config.c:3403 -msgid "invalid \"to\" part" -msgstr "некоректна частина «to»" +#: ../src/libnm-core-aux-extern/nm-libnm-core-aux.c:346 +msgid "missing 'name' attribute" +msgstr "пропущено атрибут «name»" -#: ../libnm-core/nm-setting-ip-config.c:3414 +#: ../src/libnm-core-aux-extern/nm-libnm-core-aux.c:355 #, c-format -msgid "cannot detect address family for rule" -msgstr "не вдалося визначити сімейство адрес для правила" +msgid "invalid 'name' \"%s\"" +msgstr "некоректне значення «name» — «%s»" -#: ../libnm-core/nm-setting-ip-config.c:3468 -#: ../libnm-core/nm-setting-ip-config.c:3558 +#: ../src/libnm-core-aux-extern/nm-libnm-core-aux.c:368 #, c-format -msgid "rule is invalid: %s" -msgstr "правило є некоректним: %s" +msgid "attribute '%s' is invalid for \"%s\"" +msgstr "атрибут «%s» є некоректним для «%s»" -#: ../libnm-core/nm-setting-ip-config.c:3539 -msgid "invalid address family" -msgstr "некоректне сімейство адрес" +#: ../src/libnm-core-aux-intern/nm-libnm-core-utils.c:321 +msgid "property cannot be an empty string" +msgstr "властивість не може бути порожнім рядком" -#: ../libnm-core/nm-setting-ip-config.c:4797 -#, c-format -msgid "rule #%u is invalid: %s" -msgstr "правило %u є некоректним: %s" +#: ../src/libnm-core-aux-intern/nm-libnm-core-utils.c:338 +msgid "property cannot be longer than 255 bytes" +msgstr "значення властивості не може бути довшим за 255 байтів" -#: ../libnm-core/nm-setting-ip-config.c:5145 -#, c-format -msgid "%d. DNS server address is invalid" -msgstr "%d. Адреса сервера DNS є некоректною." +#: ../src/libnm-core-aux-intern/nm-libnm-core-utils.c:349 +msgid "property cannot contain any nul bytes" +msgstr "значення властивості не може містити нульових байтів" -#: ../libnm-core/nm-setting-ip-config.c:5164 -#, c-format -msgid "%d. IP address is invalid" -msgstr "%d. IP-адреса є некоректною." +#: ../src/libnm-core-impl/nm-connection.c:299 +msgid "wrong type; should be a list of strings." +msgstr "помилковий тип; має бути список рядків." -#: ../libnm-core/nm-setting-ip-config.c:5179 -#, c-format -msgid "%d. IP address has 'label' property with invalid type" -msgstr "%d. IP-адреса має властивість «label» некоректного типу" +#: ../src/libnm-core-impl/nm-connection.c:373 +msgid "unknown setting name" +msgstr "невідома назва параметра" + +#: ../src/libnm-core-impl/nm-connection.c:385 +msgid "duplicate setting name" +msgstr "дублювання назви параметра" + +#: ../src/libnm-core-impl/nm-connection.c:1422 +msgid "setting not found" +msgstr "параметра не знайдено" + +#: ../src/libnm-core-impl/nm-connection.c:1475 +#: ../src/libnm-core-impl/nm-connection.c:1500 +#: ../src/libnm-core-impl/nm-connection.c:1525 +msgid "setting is required for non-slave connections" +msgstr "для непідлеглих з'єднань потрібен параметр" + +#: ../src/libnm-core-impl/nm-connection.c:1488 +#: ../src/libnm-core-impl/nm-connection.c:1513 +#: ../src/libnm-core-impl/nm-connection.c:1538 +msgid "setting not allowed in slave connection" +msgstr "параметр не можна використовувати у підлеглому з'єднанні" + +#: ../src/libnm-core-impl/nm-connection.c:1643 +msgid "Unexpected failure to normalize the connection" +msgstr "Неочікувана помилка під час спроби нормалізувати з'єднання" + +#: ../src/libnm-core-impl/nm-connection.c:1704 +msgid "Unexpected failure to verify the connection" +msgstr "Неочікувана помилка під час спроби перевірити з'єднання" -#: ../libnm-core/nm-setting-ip-config.c:5191 +#: ../src/libnm-core-impl/nm-connection.c:1741 #, c-format -msgid "%d. IP address has invalid label '%s'" -msgstr "%d. IP-адреса має некоректну мітку, «%s»" +msgid "unexpected uuid %s instead of %s" +msgstr "неочікуваний UUID %s замість %s" -#: ../libnm-core/nm-setting-ip-config.c:5209 -msgid "gateway cannot be set if there are no addresses configured" -msgstr "шлюз не може бути встановлено, якщо не налаштовано адрес" +#: ../src/libnm-core-impl/nm-connection.c:2555 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2618 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2641 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2681 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2704 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2755 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2773 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2797 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2815 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2845 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2945 +#: ../src/libnm-core-impl/nm-setting-adsl.c:157 +#: ../src/libnm-core-impl/nm-setting-bluetooth.c:110 +#: ../src/libnm-core-impl/nm-setting-bluetooth.c:174 +#: ../src/libnm-core-impl/nm-setting-bluetooth.c:191 +#: ../src/libnm-core-impl/nm-setting-cdma.c:127 +#: ../src/libnm-core-impl/nm-setting-connection.c:1073 +#: ../src/libnm-core-impl/nm-setting-connection.c:1111 +#: ../src/libnm-core-impl/nm-setting-connection.c:1383 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5120 +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:371 +#: ../src/libnm-core-impl/nm-setting-olpc-mesh.c:83 +#: ../src/libnm-core-impl/nm-setting-ovs-patch.c:75 +#: ../src/libnm-core-impl/nm-setting-pppoe.c:129 +#: ../src/libnm-core-impl/nm-setting-vpn.c:532 +#: ../src/libnm-core-impl/nm-setting-wifi-p2p.c:120 +#: ../src/libnm-core-impl/nm-setting-wimax.c:92 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:899 +#: ../src/libnm-core-impl/nm-setting-wireless.c:788 +msgid "property is missing" +msgstr "не вказано властивості" -#: ../libnm-core/nm-setting-ip-config.c:5221 -msgid "gateway is invalid" -msgstr "шлюз є некоректним" +#: ../src/libnm-core-impl/nm-connection.c:2708 +msgid "IP Tunnel" +msgstr "IP-тунель" -#: ../libnm-core/nm-setting-ip-config.c:5239 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:59 +msgid "Failed to initialize the crypto engine." +msgstr "Не вдалося ініціалізувати рушій шифрування." + +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:92 +#: ../src/libnm-core-impl/nm-crypto-nss.c:118 #, c-format -msgid "%d. route is invalid" -msgstr "%d. Некоректний маршрут" +msgid "Unsupported key cipher for decryption" +msgstr "Непідтримуване шифрування ключем для розшифровування" -#: ../libnm-core/nm-setting-ip-config.c:5252 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:103 +#: ../src/libnm-core-impl/nm-crypto-nss.c:126 #, c-format -msgid "invalid attribute: %s" -msgstr "некоректний атрибут: %s" +msgid "Invalid IV length (must be at least %u)." +msgstr "Некоректна довжина ВІ (має бути принаймні %u)." -#: ../libnm-core/nm-setting-ip-config.c:5272 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:121 #, c-format -msgid "%u. rule has wrong address-family" -msgstr "%u. у правилі вказано помилкове сімейство адрес" +msgid "Failed to initialize the decryption cipher context: %s (%s)" +msgstr "Не вдалося ініціалізувати контекст шифру декодування: %s (%s)." -#: ../libnm-core/nm-setting-ip-config.c:5284 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:135 #, c-format -msgid "%u. rule is invalid: %s" -msgstr "%u. правило є некоректним: %s" +msgid "Failed to decrypt the private key: %s (%s)" +msgstr "Не вдалося розшифрувати закритий ключ: %s (%s)." -#: ../libnm-core/nm-setting-ip-config.c:5300 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:148 +#: ../src/libnm-core-impl/nm-crypto-nss.c:221 #, c-format -msgid "'%s' is not a valid IAID" -msgstr "«%s» не є коректним IAID" +msgid "Failed to decrypt the private key: unexpected padding length." +msgstr "Не вдалося розшифрувати закритий ключ: неочікувана довжина доповнення." -#: ../libnm-core/nm-setting-ip-config.c:5314 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:160 +#: ../src/libnm-core-impl/nm-crypto-nss.c:233 #, c-format -msgid "the property cannot be set when '%s' is disabled" -msgstr "властивість не можна встановлювати, якщо вимкнено «%s»" +msgid "Failed to decrypt the private key." +msgstr "Не вдалося розшифрувати закритий ключ." -#: ../libnm-core/nm-setting-ip-config.c:5339 -msgid "the property is currently supported only for DHCPv4" -msgstr "у поточній версії підтримку властивості передбачено лише для DHCPv4" +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:194 +#: ../src/libnm-core-impl/nm-crypto-nss.c:288 +#, c-format +msgid "Unsupported key cipher for encryption" +msgstr "Непідтримуване шифрування ключем для шифрування" -#: ../libnm-core/nm-setting-ip-config.c:5356 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:211 #, c-format -msgid "'%s' is not a valid IP or subnet" -msgstr "«%s» є некоректною IP-адресою або підмережею" +msgid "Failed to initialize the encryption cipher context: %s (%s)" +msgstr "Не вдалося ініціалізувати контекст шифру кодування: %s (%s)." -#: ../libnm-core/nm-setting-ip-config.c:5372 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:239 #, c-format -msgid "a gateway is incompatible with '%s'" -msgstr "шлюз є несумісним з «%s»" +msgid "Failed to encrypt the data: %s (%s)" +msgstr "Не вдалося зашифрувати дані: %s (%s)." -#: ../libnm-core/nm-setting-ip-tunnel.c:330 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:264 #, c-format -msgid "'%d' is not a valid tunnel mode" -msgstr "«%d» не є коректним режимом тунелювання" +msgid "Error initializing certificate data: %s" +msgstr "Помилка під час спроби ініціалізації даних сертифіката: %s" -#: ../libnm-core/nm-setting-ip-tunnel.c:357 -#: ../libnm-core/nm-setting-ip-tunnel.c:383 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:287 #, c-format -msgid "'%s' is not a valid IPv%c address" -msgstr "«%s» не є коректною адресою у форматі IPv%c" +msgid "Couldn't decode certificate: %s" +msgstr "Не вдалося декодувати сертифікат: %s" -#: ../libnm-core/nm-setting-ip-tunnel.c:402 -msgid "tunnel keys can only be specified for GRE tunnels" -msgstr "ключі тунелювання можна задавати лише для тунелів GRE" +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:312 +#, c-format +msgid "Couldn't initialize PKCS#12 decoder: %s" +msgstr "Не вдалося ініціалізувати інструмент розшифрування PKCS#12: %s" -#: ../libnm-core/nm-setting-ip-tunnel.c:415 -#: ../libnm-core/nm-setting-ip-tunnel.c:433 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:326 #, c-format -msgid "'%s' is not a valid tunnel key" -msgstr "«%s» не є коректним ключем тунелю" +msgid "Couldn't decode PKCS#12 file: %s" +msgstr "Не вдалося розшифрувати файл PKCS#12: %s" -#: ../libnm-core/nm-setting-ip-tunnel.c:447 -msgid "a fixed TTL is allowed only when path MTU discovery is enabled" -msgstr "" -"фіксований TTL можна використовувати, лише якщо увімкнено виявлення MTU " -"шляхів" +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:341 +#, c-format +msgid "Couldn't verify PKCS#12 file: %s" +msgstr "Не вдалося перевірити файл PKCS#12: %s" -#: ../libnm-core/nm-setting-ip-tunnel.c:462 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:370 #, c-format -msgid "some flags are invalid for the select mode: %s" -msgstr "деякі з прапорців для режиму вибору є некоректними: %s" +msgid "Couldn't initialize PKCS#8 decoder: %s" +msgstr "Не вдалося ініціалізувати інструмент розшифрування PKCS#8: %s" -#: ../libnm-core/nm-setting-ip-tunnel.c:475 +#: ../src/libnm-core-impl/nm-crypto-gnutls.c:398 #, c-format -msgid "wired setting not allowed for mode %s" -msgstr "встановлення параметрів дротового зв'язку для режиму %s неможливе" +msgid "Couldn't decode PKCS#8 file: %s" +msgstr "Не вдалося розшифрувати файл PKCS#8: %s" -#: ../libnm-core/nm-setting-ip4-config.c:132 -#: ../libnm-core/nm-setting-ip6-config.c:177 +#: ../src/libnm-core-impl/nm-crypto-nss.c:70 #, c-format -msgid "this property cannot be empty for '%s=%s'" -msgstr "ця властивість не може бути порожньою, якщо «%s=%s»" +msgid "Failed to initialize the crypto engine: %d." +msgstr "Не вдалося ініціалізувати рушій шифрування: %d." -#: ../libnm-core/nm-setting-ip4-config.c:148 -#: ../libnm-core/nm-setting-ip4-config.c:162 -#: ../libnm-core/nm-setting-ip4-config.c:178 -#: ../libnm-core/nm-setting-ip6-config.c:197 -#: ../libnm-core/nm-setting-ip6-config.c:211 -#: ../libnm-core/nm-setting-ip6-config.c:225 +#: ../src/libnm-core-impl/nm-crypto-nss.c:139 #, c-format -msgid "this property is not allowed for '%s=%s'" -msgstr "цю властивість не можна застосовувати до «%s=%s»" +msgid "Failed to initialize the decryption cipher slot." +msgstr "Не вдалося ініціалізувати слот шифру декодування." -#: ../libnm-core/nm-setting-ip4-config.c:230 +#: ../src/libnm-core-impl/nm-crypto-nss.c:150 #, c-format -msgid "'%s' is not a valid FQDN" -msgstr "«%s» не є коректною повною назвою вузла (FQDN)" +msgid "Failed to set symmetric key for decryption." +msgstr "Не вдалося встановити симетричний ключ для розшифрування." -#: ../libnm-core/nm-setting-ip4-config.c:243 -msgid "property cannot be set when dhcp-hostname is also set" -msgstr "властивість не можна задавати, якщо встановлено dhcp-hostname" +#: ../src/libnm-core-impl/nm-crypto-nss.c:161 +#, c-format +msgid "Failed to set IV for decryption." +msgstr "Не вдалося встановити ВІ для розшифрування." -#: ../libnm-core/nm-setting-ip4-config.c:258 -msgid "FQDN flags requires a FQDN set" -msgstr "для прапорців FQDN потрібен набір FQDN" +#: ../src/libnm-core-impl/nm-crypto-nss.c:170 +#, c-format +msgid "Failed to initialize the decryption context." +msgstr "Не вдалося ініціалізувати контекст розшифрування." -#: ../libnm-core/nm-setting-ip4-config.c:277 +#: ../src/libnm-core-impl/nm-crypto-nss.c:187 #, c-format -msgid "multiple addresses are not allowed for '%s=%s'" -msgstr "не можна вказувати декілька адрес у «%s=%s»" +msgid "Failed to decrypt the private key: %d." +msgstr "Не вдалося розшифрувати закритий ключ: %d." -#: ../libnm-core/nm-setting-ip4-config.c:294 -msgid "property should be TRUE when method is set to disabled" +#: ../src/libnm-core-impl/nm-crypto-nss.c:196 +#, c-format +msgid "Failed to decrypt the private key: decrypted data too large." msgstr "" -"властивість повинна мати значення TRUE, якщо встановлено метод «disabled»" +"Не вдалося розшифрувати закритий ключ: розшифровані дані є занадто об'ємними." -#: ../libnm-core/nm-setting-ip6-config.c:275 -msgid "value is not a valid token" -msgstr "значення не є коректним жетоном" +#: ../src/libnm-core-impl/nm-crypto-nss.c:208 +#, c-format +msgid "Failed to finalize decryption of the private key: %d." +msgstr "Не вдалося завершити розшифрування закритого ключа: %d." -#: ../libnm-core/nm-setting-ip6-config.c:289 -msgid "only makes sense with EUI64 address generation mode" -msgstr "має сенс лише з режимом створення адрес EUI64" +#: ../src/libnm-core-impl/nm-crypto-nss.c:300 +#, c-format +msgid "Failed to initialize the encryption cipher slot." +msgstr "Не вдалося ініціалізувати слот шифру розкодування." -#: ../libnm-core/nm-setting-ip6-config.c:303 -msgid "invalid DUID" -msgstr "некоректний DUID" +#: ../src/libnm-core-impl/nm-crypto-nss.c:309 +#, c-format +msgid "Failed to set symmetric key for encryption." +msgstr "Не вдалося встановити симетричний ключ для шифрування." -#: ../libnm-core/nm-setting-ip6-config.c:318 -msgid "token is not in canonical form" -msgstr "жетон вказано не у канонічній формі" +#: ../src/libnm-core-impl/nm-crypto-nss.c:318 +#, c-format +msgid "Failed to set IV for encryption." +msgstr "Не вдалося встановити вектор ініціалізації для шифрування." -#: ../libnm-core/nm-setting-ip6-config.c:335 -msgid "property should be TRUE when method is set to ignore or disabled" -msgstr "" -"властивість повинна мати значення TRUE, якщо встановлено метод «ignore» або " -"«disabled»" +#: ../src/libnm-core-impl/nm-crypto-nss.c:327 +#, c-format +msgid "Failed to initialize the encryption context." +msgstr "Не вдалося ініціалізувати контекст шифрування." -#: ../libnm-core/nm-setting-macsec.c:230 -msgid "the key is empty" -msgstr "ключ є порожнім" +#: ../src/libnm-core-impl/nm-crypto-nss.c:352 +#, c-format +msgid "Failed to encrypt: %d." +msgstr "Не вдалося зашифрувати: %d." -#: ../libnm-core/nm-setting-macsec.c:239 +#: ../src/libnm-core-impl/nm-crypto-nss.c:361 #, c-format -msgid "the key must be %d characters" -msgstr "ключ має складатися з %d символів" +msgid "Unexpected amount of data after encrypting." +msgstr "Неочікуваний об'єм даних після шифрування." -#: ../libnm-core/nm-setting-macsec.c:248 -msgid "the key contains non-hexadecimal characters" -msgstr "ключ містить нешістнадцяткові цифри" +#: ../src/libnm-core-impl/nm-crypto-nss.c:398 +#, c-format +msgid "Couldn't decode certificate: %d" +msgstr "Не вдалося розшифрувати сертифікат: %d" -#: ../libnm-core/nm-setting-macsec.c:317 ../libnm-core/nm-setting-macvlan.c:138 -#: ../libnm-core/nm-setting-vlan.c:621 +#: ../src/libnm-core-impl/nm-crypto-nss.c:443 #, c-format -msgid "property is not specified and neither is '%s:%s'" -msgstr "властивість не вказано і не визначено «%s:%s»" +msgid "Password must be UTF-8" +msgstr "Пароль має бути вказано у кодуванні UTF-8" -#: ../libnm-core/nm-setting-macsec.c:348 +#: ../src/libnm-core-impl/nm-crypto-nss.c:464 #, c-format -msgid "EAP key management requires '%s' setting presence" -msgstr "Керування ключами за допомогою EAP потребує додавання параметра «%s»" +msgid "Couldn't initialize slot" +msgstr "Не вдалося ініціалізувати слот" -#: ../libnm-core/nm-setting-macsec.c:357 -msgid "must be either psk (0) or eap (1)" -msgstr "має бути або psk (0), або eap (1)" +#: ../src/libnm-core-impl/nm-crypto-nss.c:473 +#, c-format +msgid "Couldn't initialize PKCS#12 decoder: %d" +msgstr "Не вдалося ініціалізувати інструмент розшифрування PKCS#12: %d" -#: ../libnm-core/nm-setting-macsec.c:366 +#: ../src/libnm-core-impl/nm-crypto-nss.c:483 #, c-format -msgid "invalid port %d" -msgstr "некоректний порт %d" +msgid "Couldn't decode PKCS#12 file: %d" +msgstr "Не вдалося розшифрувати файл PKCS#12: %d" -#: ../libnm-core/nm-setting-macsec.c:376 -msgid "only valid for psk mode" -msgstr "можна використовувати лише у режимі psk" +#: ../src/libnm-core-impl/nm-crypto-nss.c:493 +#, c-format +msgid "Couldn't verify PKCS#12 file: %d" +msgstr "Не вдалося перевірити файл PKCS#12: %d" -#: ../libnm-core/nm-setting-macvlan.c:153 -msgid "non promiscuous operation is allowed only in passthru mode" -msgstr "розбірливі дії можливі лише у режимі передавання (passthru)" +#: ../src/libnm-core-impl/nm-crypto-nss.c:544 +msgid "Could not generate random data." +msgstr "Не вдалося створити псевдовипадкові дані." -#: ../libnm-core/nm-setting-match.c:701 ../libnm-core/nm-setting-match.c:717 -#: ../libnm-core/nm-setting-match.c:733 ../libnm-core/nm-setting-match.c:749 +#: ../src/libnm-core-impl/nm-crypto.c:208 #, c-format -msgid "is empty" -msgstr "є порожнім" +msgid "PEM key file had no start tag" +msgstr "У файлі ключа PEM не міститься початкового теґу" -#: ../libnm-core/nm-setting-olpc-mesh.c:96 -#: ../libnm-core/nm-setting-wireless.c:801 -msgid "SSID length is out of range <1-32> bytes" -msgstr "Довжина SSID лежить поза діапазоном у <1-32> байтів" +#: ../src/libnm-core-impl/nm-crypto.c:217 +#, c-format +msgid "PEM key file had no end tag '%s'." +msgstr "У файлі ключа PEM не міститься завершального теґу «%s»." -#: ../libnm-core/nm-setting-olpc-mesh.c:108 -#: ../libnm-core/nm-setting-wireless.c:854 +#: ../src/libnm-core-impl/nm-crypto.c:245 #, c-format -msgid "'%d' is not a valid channel" -msgstr "«%d» не є коректним каналом" +msgid "Malformed PEM file: Proc-Type was not first tag." +msgstr "Помилкове форматування PEM: Proc-Type не є першим теґом." -#: ../libnm-core/nm-setting-ovs-bridge.c:160 +#: ../src/libnm-core-impl/nm-crypto.c:254 #, c-format -msgid "A connection with a '%s' setting must not have a master." -msgstr "З'єднання з параметром «%s» не повинне мати основне." +msgid "Malformed PEM file: unknown Proc-Type tag '%s'." +msgstr "Помилкове форматування PEM: невідомий теґ Proc-Type «%s»." -#: ../libnm-core/nm-setting-ovs-bridge.c:174 +#: ../src/libnm-core-impl/nm-crypto.c:267 #, c-format -msgid "'%s' is not allowed in fail_mode" -msgstr "«%s» не можна використовувати у режимі fail_mode" +msgid "Malformed PEM file: DEK-Info was not the second tag." +msgstr "Помилкове форматування PEM: DEK-Info не є другим теґом." -#: ../libnm-core/nm-setting-ovs-external-ids.c:90 -#: ../libnm-core/nm-setting-user.c:91 -msgid "missing key" -msgstr "не вказано ключ" +#: ../src/libnm-core-impl/nm-crypto.c:279 +#, c-format +msgid "Malformed PEM file: no IV found in DEK-Info tag." +msgstr "Помилкове форматування файла PEM: не знайдено теґу DEK-Info у ВІ." -#: ../libnm-core/nm-setting-ovs-external-ids.c:98 -#: ../libnm-core/nm-setting-user.c:99 -msgid "key is too long" -msgstr "ключ є надто довгим" +#: ../src/libnm-core-impl/nm-crypto.c:288 +#, c-format +msgid "Malformed PEM file: invalid format of IV in DEK-Info tag." +msgstr "" +"Помилкове форматування файла PEM: некоректне форматування ВІ у тезі DEK-Info." -#: ../libnm-core/nm-setting-ovs-external-ids.c:105 -#: ../libnm-core/nm-setting-user.c:106 -msgid "key must be UTF8" -msgstr "ключ має зберігатися у кодуванні UTF8" +#: ../src/libnm-core-impl/nm-crypto.c:300 +#, c-format +msgid "Malformed PEM file: unknown private key cipher '%s'." +msgstr "" +"Помилкове форматування файла PEM: невідоме шифрування закритого ключа «%s»." -#: ../libnm-core/nm-setting-ovs-external-ids.c:114 -#: ../libnm-core/nm-setting-user.c:153 -msgid "key contains invalid characters" -msgstr "ключ містить некоректний символ" +#: ../src/libnm-core-impl/nm-crypto.c:323 +#, c-format +msgid "Could not decode private key." +msgstr "Не вдалося декодувати закритий ключ." -#: ../libnm-core/nm-setting-ovs-external-ids.c:123 -msgid "key cannot start with \"NM.\"" -msgstr "запис ключа не починається з «NM.»" +#: ../src/libnm-core-impl/nm-crypto.c:365 +msgid "Failed to find expected PKCS#8 start tag." +msgstr "Не вдалося знайти очікуваний початковий теґ PKCS#8." -#: ../libnm-core/nm-setting-ovs-external-ids.c:153 -#: ../libnm-core/nm-setting-user.c:180 -msgid "value is missing" -msgstr "не вказано значення" +#: ../src/libnm-core-impl/nm-crypto.c:374 +#, c-format +msgid "Failed to find expected PKCS#8 end tag '%s'." +msgstr "Не вдалося знайти очікуваний завершальний теґ PKCS#8 «%s»." -#: ../libnm-core/nm-setting-ovs-external-ids.c:162 -#: ../libnm-core/nm-setting-user.c:189 -msgid "value is too large" -msgstr "значення є надто великим" +#: ../src/libnm-core-impl/nm-crypto.c:387 +msgid "Failed to decode PKCS#8 private key." +msgstr "Не вдалося декодувати закритий ключ PKCS#8." -#: ../libnm-core/nm-setting-ovs-external-ids.c:170 -#: ../libnm-core/nm-setting-user.c:197 -msgid "value is not valid UTF8" -msgstr "значення не записано у коректному кодуванні UTF8" +#: ../src/libnm-core-impl/nm-crypto.c:417 +msgid "Failed to find expected TSS start tag." +msgstr "Не вдалося знайти очікуваний початковий теґ TSS." -#: ../libnm-core/nm-setting-ovs-external-ids.c:313 -#: ../libnm-core/nm-setting-user.c:365 +#: ../src/libnm-core-impl/nm-crypto.c:426 #, c-format -msgid "invalid key \"%s\": %s" -msgstr "некоректний ключ «%s»: %s" +msgid "Failed to find expected TSS end tag '%s'." +msgstr "Не вдалося знайти очікуваний завершальний теґ TSS «%s»." -#: ../libnm-core/nm-setting-ovs-external-ids.c:337 -#: ../libnm-core/nm-setting-user.c:389 +#: ../src/libnm-core-impl/nm-crypto.c:481 #, c-format -msgid "maximum number of user data entries reached (%u instead of %u)" -msgstr "" -"досягнуто максимальної кількості записів даних користувача (%u замість %u)" - -#: ../libnm-core/nm-setting-ovs-external-ids.c:380 -msgid "" -"OVS external IDs can only be added to a profile of type OVS bridge/port/" -"interface or to OVS system interface" -msgstr "" -"Зовнішні ідентифікатори OVS можна додавати лише до профілів типу місток, " -"порт або інтерфейс OVS або до загальносистемного інтерфейсу OVS" +msgid "IV must be an even number of bytes in length." +msgstr "Довжина ВІ має дорівнювати парній кількості байтів." -#: ../libnm-core/nm-setting-ovs-interface.c:93 +#: ../src/libnm-core-impl/nm-crypto.c:498 #, c-format -msgid "'%s' is not a valid interface type" -msgstr "«%s» не є коректним типом інтерфейсу" +msgid "IV contains non-hexadecimal digits." +msgstr "ВІ містить не шістнадцяткові цифри." -#: ../libnm-core/nm-setting-ovs-interface.c:120 +#: ../src/libnm-core-impl/nm-crypto.c:574 #, c-format -msgid "A connection with a '%s' setting needs connection.type explicitly set" -msgstr "Для з'єднання з параметром «%s» слід явно вказати connection.type" +msgid "IV must contain at least 8 characters" +msgstr "IV має складатися із принаймні 8 символів" -#: ../libnm-core/nm-setting-ovs-interface.c:134 +#: ../src/libnm-core-impl/nm-crypto.c:624 #, c-format -msgid "A connection of type '%s' cannot have ovs-interface.type \"system\"" -msgstr "" -"З'єднання типу «%s» не може мати значення «system» для параметра ovs-" -"interface.type" +msgid "Unable to determine private key type." +msgstr "Не вдалося визначити тип закритого ключа." -#: ../libnm-core/nm-setting-ovs-interface.c:148 +#: ../src/libnm-core-impl/nm-crypto.c:637 #, c-format -msgid "A connection of type '%s' cannot have an ovs-interface.type \"%s\"" -msgstr "" -"З'єднання типу «%s» не може мати значення «%s» для параметра ovs-interface." -"type" +msgid "Password provided, but key was not encrypted." +msgstr "Надано пароль, але ключ не зашифровано." -#: ../libnm-core/nm-setting-ovs-interface.c:170 +#: ../src/libnm-core-impl/nm-crypto.c:693 #, c-format -msgid "A connection can not have both '%s' and '%s' settings at the same time" -msgstr "Для з'єднання не може бути одночасно встановлено «%s» і «%s»" +msgid "PEM certificate had no start tag '%s'." +msgstr "Сертифікат PEM не містить початкового теґу «%s»." -#: ../libnm-core/nm-setting-ovs-interface.c:184 +#: ../src/libnm-core-impl/nm-crypto.c:703 #, c-format -msgid "" -"A connection with '%s' setting must be of connection.type \"ovs-interface\" " -"but is \"%s\"" -msgstr "" -"З'єднання з параметром «%s» має належати до типу «ovs-interface»; втім, воно " -"належить до типу «%s»" +msgid "PEM certificate had no end tag '%s'." +msgstr "Сертифікат PEM не містить завершального теґу «%s»." -#: ../libnm-core/nm-setting-ovs-interface.c:200 +#: ../src/libnm-core-impl/nm-crypto.c:716 #, c-format -msgid "" -"A connection with '%s' setting needs to be of '%s' interface type, not '%s'" -msgstr "" -"З'єднання з параметром «%s» повинне мати тип інтерфейсу «%s», а не «%s»" +msgid "Failed to decode certificate." +msgstr "Не вдалося декодувати сертифікат." -#: ../libnm-core/nm-setting-ovs-interface.c:222 +#: ../src/libnm-core-impl/nm-crypto.c:745 +#: ../src/libnm-core-impl/nm-crypto.c:796 #, c-format -msgid "A connection with ovs-interface.type '%s' setting a 'ovs-patch' setting" -msgstr "" -"З'єднання з типом «%s» ovs-interface.type встановлює параметр «ovs-patch»" +msgid "Certificate file is empty" +msgstr "Файл сертифіката є порожнім" -#: ../libnm-core/nm-setting-ovs-interface.c:250 +#: ../src/libnm-core-impl/nm-crypto.c:778 #, c-format -msgid "Missing ovs interface setting" -msgstr "Пропущено параметр інтерфейсу ovs" +msgid "Failed to recognize certificate" +msgstr "Не вдалося розпізнати сертифікат" -#: ../libnm-core/nm-setting-ovs-interface.c:256 +#: ../src/libnm-core-impl/nm-crypto.c:886 #, c-format -msgid "Missing ovs interface type" -msgstr "Не вказано тип інтерфейсу ovs" +msgid "not a valid private key" +msgstr "не є коректним закритим ключем" -#: ../libnm-core/nm-setting-ovs-interface.c:298 -#: ../libnm-core/nm-setting-ovs-port.c:179 +#: ../src/libnm-core-impl/nm-dbus-utils.c:181 #, c-format -msgid "A connection with a '%s' setting must have a master." -msgstr "З'єднання з параметром «%s» повинне мати основне." +msgid "Method returned type '%s', but expected '%s'" +msgstr "Методом повернуто тип «%s», хоча мав бути «%s»" -#: ../libnm-core/nm-setting-ovs-port.c:215 +#: ../src/libnm-core-impl/nm-keyfile-utils.c:174 #, c-format -msgid "'%s' is not allowed in vlan_mode" -msgstr "«%s» не можна використовувати у режимі vlan_mode" +msgid "Value cannot be interpreted as a list of numbers." +msgstr "Значення не може бути оброблено як список чисел." -#: ../libnm-core/nm-setting-ovs-port.c:228 +#: ../src/libnm-core-impl/nm-keyfile-utils.c:303 #, c-format -msgid "the tag id must be in range 0-4094 but is %u" -msgstr "" -"ідентифікатором tag має бути число у діапазоні від 0 до 4094, втім, маємо %u" +msgid "value is not an integer in range [%lld, %lld]" +msgstr "значення не є цілим числом у діапазоні [%lld, %lld]" + +#: ../src/libnm-core-impl/nm-keyfile.c:269 +msgid "ignoring missing number" +msgstr "ігноруємо пропущене число" -#: ../libnm-core/nm-setting-ovs-port.c:238 +#: ../src/libnm-core-impl/nm-keyfile.c:281 #, c-format -msgid "'%s' is not allowed in lacp" -msgstr "«%s» не можна використовувати у lacp" +msgid "ignoring invalid number '%s'" +msgstr "ігноруємо некоректне число «%s»" -#: ../libnm-core/nm-setting-ovs-port.c:251 +#: ../src/libnm-core-impl/nm-keyfile.c:310 #, c-format -msgid "'%s' is not allowed in bond_mode" -msgstr "«%s» не можна використовувати у режимі bond_mode" +msgid "ignoring invalid %s address: %s" +msgstr "ігноруємо некоректну адресу %s: %s" -#: ../libnm-core/nm-setting-ppp.c:335 +#: ../src/libnm-core-impl/nm-keyfile.c:356 #, c-format -msgid "'%d' is out of valid range <128-16384>" -msgstr "«%d» не належить до коректного діапазону <128-16384>" +msgid "ignoring invalid gateway '%s' for %s route" +msgstr "ігноруємо некоректний шлюз «%s» для маршруту %s" -#: ../libnm-core/nm-setting-ppp.c:348 +#: ../src/libnm-core-impl/nm-keyfile.c:378 #, c-format -msgid "setting this property requires non-zero '%s' property" -msgstr "" -"встановлення цієї властивості вимагає ненульового значення властивості «%s»" +msgid "ignoring invalid %s route: %s" +msgstr "ігноруємо некоректний маршрут %s: %s" -#: ../libnm-core/nm-setting-proxy.c:123 +#: ../src/libnm-core-impl/nm-keyfile.c:556 #, c-format -msgid "invalid proxy method" -msgstr "некоректний метод проксіювання" +msgid "unexpected character '%c' for address %s: '%s' (position %td)" +msgstr "неочікуваний символ «%c» для адреси %s: «%s» (позиція %td)" -#: ../libnm-core/nm-setting-proxy.c:133 ../libnm-core/nm-setting-proxy.c:145 +#: ../src/libnm-core-impl/nm-keyfile.c:572 #, c-format -msgid "this property is not allowed for method none" -msgstr "цю властивість не можна використовувати для методу none" +msgid "unexpected character '%c' for %s: '%s' (position %td)" +msgstr "неочікуваний символ «%c» для %s: «%s» (позиція %td)" -#: ../libnm-core/nm-setting-proxy.c:159 +#: ../src/libnm-core-impl/nm-keyfile.c:587 #, c-format -msgid "the script is too large" -msgstr "скрипт є надто великим" +msgid "unexpected character '%c' in prefix length for %s: '%s' (position %td)" +msgstr "неочікуваний символ «%c» у префіксі довжини для %s: «%s» (позиція %td)" -#: ../libnm-core/nm-setting-proxy.c:170 +#: ../src/libnm-core-impl/nm-keyfile.c:604 #, c-format -msgid "the script is not valid utf8" -msgstr "скрипт не є коректним текстом у кодуванні utf8" +msgid "garbage at the end of value %s: '%s'" +msgstr "зайві дані наприкінці значення %s: «%s»" -#: ../libnm-core/nm-setting-proxy.c:181 +#: ../src/libnm-core-impl/nm-keyfile.c:614 #, c-format -msgid "the script lacks FindProxyForURL function" -msgstr "скрипт не містить функції FindProxyForURL" +msgid "deprecated semicolon at the end of value %s: '%s'" +msgstr "застаріла крапка з комою наприкінці значення %s: «%s»" -#: ../libnm-core/nm-setting-sriov.c:1054 +#: ../src/libnm-core-impl/nm-keyfile.c:633 #, c-format -msgid "VF with index %u, but the total number of VFs is %u" -msgstr "маємо VF з індексом %u, але загальна кількість VF дорівнює %u" +msgid "invalid prefix length for %s '%s', defaulting to %d" +msgstr "некоректний префікс довжини для %s «%s», повертаємося до типового, %d" -#: ../libnm-core/nm-setting-sriov.c:1068 +#: ../src/libnm-core-impl/nm-keyfile.c:645 #, c-format -msgid "invalid VF %u: %s" -msgstr "некоректна VF %u: %s" +msgid "missing prefix length for %s '%s', defaulting to %d" +msgstr "пропущено префікс довжини для %s «%s», повертаємося до типового, %d" -#: ../libnm-core/nm-setting-sriov.c:1082 +#: ../src/libnm-core-impl/nm-keyfile.c:988 +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:320 +#: ../src/libnm-core-impl/nm-setting-user.c:372 #, c-format -msgid "duplicate VF index %u" -msgstr "дублювання індексу VF %u" +msgid "invalid value for \"%s\": %s" +msgstr "некоректне значення для «%s»: %s" -#: ../libnm-core/nm-setting-sriov.c:1106 +#: ../src/libnm-core-impl/nm-keyfile.c:1066 #, c-format -msgid "VFs %d and %d are not sorted by ascending index" -msgstr "VF %d і %d не упорядковано за зростанням" +msgid "ignoring invalid DNS server IPv%c address '%s'" +msgstr "ігноруємо некоректну адресу IPv%c сервера DNS «%s»" -#: ../libnm-core/nm-setting-tc-config.c:54 -#: ../libnm-core/nm-setting-tc-config.c:420 -#: ../libnm-core/nm-setting-tc-config.c:697 -#, c-format -msgid "kind is missing" -msgstr "пропущено тип" +#: ../src/libnm-core-impl/nm-keyfile.c:1161 +msgid "ignoring invalid MAC address" +msgstr "ігноруємо некоректну MAC-адресу" -#: ../libnm-core/nm-setting-tc-config.c:62 -#: ../libnm-core/nm-setting-tc-config.c:428 -#: ../libnm-core/nm-setting-tc-config.c:705 +#: ../src/libnm-core-impl/nm-keyfile.c:1237 #, c-format -msgid "'%s' is not a valid kind" -msgstr "«%s» не є коректним типом" +msgid "ignoring invalid bond option %s%s%s = %s%s%s: %s" +msgstr "ігноруємо некоректний параметр bond %s%s%s = %s%s%s: %s" -#: ../libnm-core/nm-setting-tc-config.c:71 -#: ../libnm-core/nm-setting-tc-config.c:714 -msgid "parent handle missing" -msgstr "не вказано батьківського дескриптора" +#: ../src/libnm-core-impl/nm-keyfile.c:1427 +msgid "ignoring invalid SSID" +msgstr "ігноруємо некоректний SSID" -#: ../libnm-core/nm-setting-tc-config.c:1284 -msgid "there are duplicate TC qdiscs" -msgstr "маємо дублювання q-дисків TC" +#: ../src/libnm-core-impl/nm-keyfile.c:1445 +msgid "ignoring invalid raw password" +msgstr "ігноруємо некоректний необроблений пароль" -#: ../libnm-core/nm-setting-tc-config.c:1303 -msgid "there are duplicate TC filters" -msgstr "маємо дублювання фільтрів TC" +#: ../src/libnm-core-impl/nm-keyfile.c:1586 +msgid "invalid key/cert value" +msgstr "некоректне значення ключа/сертифіката" -#: ../libnm-core/nm-setting-team.c:119 ../libnm-core/nm-setting-team.c:193 -#: ../libnm-core/nm-setting-team.c:325 +#: ../src/libnm-core-impl/nm-keyfile.c:1601 #, c-format -msgid "%s is out of range [0, %d]" -msgstr "%s не належить до діапазону [0, %d]" +msgid "invalid key/cert value path \"%s\"" +msgstr "некоректний шлях до ключа/сертифіката, «%s»" -#: ../libnm-core/nm-setting-team.c:170 +#: ../src/libnm-core-impl/nm-keyfile.c:1626 +#: ../src/libnm-core-impl/nm-keyfile.c:1723 #, c-format -msgid "Missing target-host in nsna_ping link watcher" -msgstr "" -"Пропущено вузол призначення у налаштуваннях засобу спостереження за зв'язком " -"nsna_ping" +msgid "certificate or key file '%s' does not exist" +msgstr "файла сертифіката або ключа «%s» не існує" -#: ../libnm-core/nm-setting-team.c:178 ../libnm-core/nm-setting-team.c:301 +#: ../src/libnm-core-impl/nm-keyfile.c:1639 #, c-format -msgid "target-host '%s' contains invalid characters" -msgstr "назва вузла призначення, «%s», містить некоректні символи" +msgid "invalid PKCS#11 URI \"%s\"" +msgstr "некоректна адреса PKCS#11 «%s»" -#: ../libnm-core/nm-setting-team.c:292 -#, c-format -msgid "Missing %s in arp_ping link watcher" -msgstr "" -"Не вказано %s у налаштуваннях засобу спостереження за зв'язком arp_ping" +#: ../src/libnm-core-impl/nm-keyfile.c:1685 +msgid "invalid key/cert value data:;base64, is not base64" +msgstr "некоректні дані значення ключа/сертифіката data:;base64, не є base64" -#: ../libnm-core/nm-setting-team.c:310 -#, c-format -msgid "source-host '%s' contains invalid characters" -msgstr "назва вузла джерела, «%s», містить некоректні символи" +#: ../src/libnm-core-impl/nm-keyfile.c:1698 +msgid "invalid key/cert value data:;base64,file://" +msgstr "некоректне значення ключа/сертифіката data:;base64,file://" -#: ../libnm-core/nm-setting-team.c:335 -msgid "vlanid is out of range [-1, 4094]" -msgstr "vlanid не належить до діапазону [-1, 4094]" +#: ../src/libnm-core-impl/nm-keyfile.c:1739 +msgid "invalid key/cert value is not a valid blob" +msgstr "" +"некоректне значення ключа/сертифіката, не є коректним значення «%s» не є " +"коректним великим бінарним об'єктом" -#: ../libnm-core/nm-setting-tun.c:149 +#: ../src/libnm-core-impl/nm-keyfile.c:1841 #, c-format -msgid "'%u': invalid mode" -msgstr "«%u»: некоректний режим" +msgid "invalid parity value '%s'" +msgstr "некоректне значення парності, «%s»" -#: ../libnm-core/nm-setting-tun.c:160 +#: ../src/libnm-core-impl/nm-keyfile.c:1863 +#: ../src/libnm-core-impl/nm-keyfile.c:3336 #, c-format -msgid "'%s': invalid user ID" -msgstr "«%s»: некоректний ідентифікатор користувача" +msgid "invalid setting: %s" +msgstr "некоректний параметр: %s" -#: ../libnm-core/nm-setting-tun.c:172 +#: ../src/libnm-core-impl/nm-keyfile.c:1883 #, c-format -msgid "'%s': invalid group ID" -msgstr "«%s»: некоректний ідентифікатор групи" - -#: ../libnm-core/nm-setting-user.c:131 -msgid "key requires a '.' for a namespace" -msgstr "для визначення простору назв у ключі має бути «.»" - -#: ../libnm-core/nm-setting-user.c:146 -msgid "key cannot contain \"..\"" -msgstr "у записі ключа не може міститися «..»" - -#: ../libnm-core/nm-setting-user.c:322 -msgid "maximum number of user data entries reached" -msgstr "досягнуто максимальної кількості записів даних користувача" +msgid "ignoring invalid team configuration: %s" +msgstr "ігноруємо некоректне налаштування команди: %s" -#: ../libnm-core/nm-setting-veth.c:89 +#: ../src/libnm-core-impl/nm-keyfile.c:1966 #, c-format -msgid "'%s' is not a valid interface name" -msgstr "«%s» не є коректною назвою інтерфейсу" +msgid "invalid qdisc: %s" +msgstr "некоректний qdisc: %s" -#: ../libnm-core/nm-setting-vlan.c:633 +#: ../src/libnm-core-impl/nm-keyfile.c:2016 #, c-format -msgid "the vlan id must be in range 0-4094 but is %u" -msgstr "" -"ідентифікатором vlan має бути число у діапазоні від 0 до 4094, втім, маємо %u" - -#: ../libnm-core/nm-setting-vlan.c:643 -msgid "flags are invalid" -msgstr "прапорці є некоректними" +msgid "invalid tfilter: %s" +msgstr "некоректний tfilter: %s" -#: ../libnm-core/nm-setting-vlan.c:655 -msgid "vlan setting should have a ethernet setting as well" -msgstr "параметр vlan має супроводжуватися параметром ethernet" +#: ../src/libnm-core-impl/nm-keyfile.c:3161 +#, c-format +msgid "error loading setting value: %s" +msgstr "помилка під час завантаження значення параметра: %s" -#: ../libnm-core/nm-setting-vrf.c:73 -msgid "table cannot be zero" -msgstr "таблиця не може бути нульовою" +#: ../src/libnm-core-impl/nm-keyfile.c:3192 +#: ../src/libnm-core-impl/nm-keyfile.c:3204 +#: ../src/libnm-core-impl/nm-keyfile.c:3223 +#: ../src/libnm-core-impl/nm-keyfile.c:3235 +#: ../src/libnm-core-impl/nm-keyfile.c:3247 +#: ../src/libnm-core-impl/nm-keyfile.c:3309 +#: ../src/libnm-core-impl/nm-keyfile.c:3321 +msgid "value cannot be interpreted as integer" +msgstr "значення не може бути оброблено як ціле число" -#: ../libnm-core/nm-setting-vpn.c:560 -msgid "cannot set connection.multi-connect for VPN setting" -msgstr "не можна встановлювати connection.multi-connect для VPN" +#: ../src/libnm-core-impl/nm-keyfile.c:3277 +#, c-format +msgid "ignoring invalid byte element '%u' (not between 0 and 255 inclusive)" +msgstr "" +"ігноруємо некоректний байтовий елемент «%u» (не у діапазоні від 0 до 255, " +"включно)" -#: ../libnm-core/nm-setting-vpn.c:599 -msgid "setting contained a secret with an empty name" -msgstr "параметри містив пароль з порожньою назвою" +#: ../src/libnm-core-impl/nm-keyfile.c:3361 +#, c-format +msgid "invalid setting name '%s'" +msgstr "некоректна назва параметра, «%s»" -#: ../libnm-core/nm-setting-vpn.c:638 ../libnm-core/nm-setting.c:2126 -msgid "not a secret property" -msgstr "не є властивістю пароля" +#: ../src/libnm-core-impl/nm-keyfile.c:3408 +#, c-format +msgid "invalid key '%s.%s'" +msgstr "некоректний ключ «%s.%s»" -#: ../libnm-core/nm-setting-vpn.c:646 -msgid "secret is not of correct type" -msgstr "пароль не належить до коректного типу" +#: ../src/libnm-core-impl/nm-keyfile.c:3424 +#, c-format +msgid "key '%s.%s' is not boolean" +msgstr "ключ «%s.%s» не є булевим значенням" -#: ../libnm-core/nm-setting-vpn.c:728 ../libnm-core/nm-setting-vpn.c:778 +#: ../src/libnm-core-impl/nm-keyfile.c:3441 #, c-format -msgid "secret name cannot be empty" -msgstr "назва реєстраційного запису не може бути порожньою" +msgid "key '%s.%s' is not a uint32" +msgstr "ключ «%s.%s» не є значенням uint32" -#: ../libnm-core/nm-setting-vpn.c:744 -msgid "secret flags property not found" -msgstr "властивість прапорців паролів не знайдено" +#: ../src/libnm-core-impl/nm-keyfile.c:3498 +#, c-format +msgid "invalid peer public key in section '%s'" +msgstr "некоректний відкритий ключ вузла у розділі «%s»" -#: ../libnm-core/nm-setting-vxlan.c:329 ../libnm-core/nm-setting-vxlan.c:340 +#: ../src/libnm-core-impl/nm-keyfile.c:3513 #, c-format -msgid "'%s' is not a valid IP%s address" -msgstr "«%s» є некоректною IP-адресою у форматі IP%s" +msgid "key '%s.%s' is not a valid 256 bit key in base64 encoding" +msgstr "ключ «%s.%s» не є коректним 256-бітовим ключем у кодуванні base64" -#: ../libnm-core/nm-setting-vxlan.c:363 +#: ../src/libnm-core-impl/nm-keyfile.c:3536 #, c-format -msgid "%d is greater than local port max %d" -msgstr "%d перевищує максимальний припустимий номер локального порту, %d" +msgid "key '%s.%s' is not a valid secret flag" +msgstr "ключ «%s.%s» не є коректним прапорцем реєстраційних даних" -#: ../libnm-core/nm-setting-wired.c:733 +#: ../src/libnm-core-impl/nm-keyfile.c:3559 #, c-format -msgid "'%s' is not a valid Ethernet port value" -msgstr "«%s» не є коректним значенням номера порту Ethernet" +msgid "key '%s.%s' is not a integer in range 0 to 2^32" +msgstr "ключ «%s.%s» не є цілими числом у діапазоні від 0 до 2^32" -#: ../libnm-core/nm-setting-wired.c:743 +#: ../src/libnm-core-impl/nm-keyfile.c:3575 #, c-format -msgid "'%s' is not a valid duplex value" -msgstr "«%s» не є коректним значенням дуплексного режиму" +msgid "key '%s.%s' is not a valid endpoint" +msgstr "ключ «%s.%s» не є коректною кінцевою точкою" -#: ../libnm-core/nm-setting-wired.c:817 +#: ../src/libnm-core-impl/nm-keyfile.c:3601 #, c-format -msgid "invalid '%s' or its value '%s'" -msgstr "некоректний «%s» або його значення «%s»" +msgid "key '%s.%s' has invalid allowed-ips" +msgstr "для ключа «%s.%s» вказано некоректне значення allowed-ips" -#: ../libnm-core/nm-setting-wired.c:867 -msgid "Wake-on-LAN mode 'default' and 'ignore' are exclusive flags" -msgstr "" -"Прапорці режиму Wake-on-LAN «default» і «ignore» не можна використовувати " -"одночасно" +#: ../src/libnm-core-impl/nm-keyfile.c:3616 +#, c-format +msgid "peer '%s' is invalid: %s" +msgstr "вузол «%s» є некоректним: %s" -#: ../libnm-core/nm-setting-wired.c:879 -msgid "Wake-on-LAN password can only be used with magic packet mode" -msgstr "" -"Пароль до Wake-on-LAN можна використовувати лише у режимі магічних пакетів" +#: ../src/libnm-core-impl/nm-keyfile.c:4107 +#, c-format +msgid "the profile is not valid: %s" +msgstr "профіль є некоректним: %s" -#: ../libnm-core/nm-setting-wired.c:910 -msgid "both speed and duplex should have a valid value or both should be unset" -msgstr "" -"параметри швидкості і двобічного режиму повинні обидва мати коректні " -"значення або обидва параметри має бути не встановлено" +#: ../src/libnm-core-impl/nm-setting-6lowpan.c:78 +#: ../src/libnm-core-impl/nm-setting-veth.c:80 +#, c-format +msgid "property is not specified" +msgstr "властивість не вказано" -#: ../libnm-core/nm-setting-wired.c:911 -msgid "both speed and duplex are required for static link configuration" -msgstr "для статичного налаштування зв'язку слід вказати speed і duplex" +#: ../src/libnm-core-impl/nm-setting-6lowpan.c:101 +#: ../src/libnm-core-impl/nm-setting-macsec.c:285 +#: ../src/libnm-core-impl/nm-setting-vlan.c:592 +#, c-format +msgid "'%s' value doesn't match '%s=%s'" +msgstr "значення «%s» не відповідає «%s=%s»" -#: ../libnm-core/nm-setting-wireguard.c:745 -msgid "missing public-key for peer" -msgstr "пропущено відкритий ключ для вузла" +#: ../src/libnm-core-impl/nm-setting-6lowpan.c:117 +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:344 +#: ../src/libnm-core-impl/nm-setting-macsec.c:301 +#: ../src/libnm-core-impl/nm-setting-macvlan.c:122 +#: ../src/libnm-core-impl/nm-setting-vlan.c:608 +#: ../src/libnm-core-impl/nm-setting-vxlan.c:352 +#, c-format +msgid "'%s' is neither an UUID nor an interface name" +msgstr "«%s» не є ні UUID, ні назвою інтерфейсу" -#: ../libnm-core/nm-setting-wireguard.c:751 -msgid "invalid public-key for peer" -msgstr "некоректний відкритий ключ для вузла" +#: ../src/libnm-core-impl/nm-setting-8021x.c:218 +msgid "binary data missing" +msgstr "не вистачає двійкових даних" -#: ../libnm-core/nm-setting-wireguard.c:761 -msgid "invalid preshared-key for peer" -msgstr "некоректне значення preshared-key для вузла" +#: ../src/libnm-core-impl/nm-setting-8021x.c:250 +msgid "URI not NUL terminated" +msgstr "Адресу не завершено символом NUL" -#: ../libnm-core/nm-setting-wireguard.c:780 -msgid "invalid endpoint for peer" -msgstr "некоректна кінцева точка для вузла" +#: ../src/libnm-core-impl/nm-setting-8021x.c:259 +msgid "URI is empty" +msgstr "Адреса є порожньою" -#: ../libnm-core/nm-setting-wireguard.c:792 -#, c-format -msgid "invalid IP address \"%s\" for allowed-ip of peer" -msgstr "некоректна IP-адреса «%s» для allowed-ip вузла" +#: ../src/libnm-core-impl/nm-setting-8021x.c:267 +msgid "URI is not valid UTF-8" +msgstr "Адресу не є коректним рядком у кодуванні UTF-8" -#: ../libnm-core/nm-setting-wireguard.c:803 -msgid "invalid preshared-key-flags for peer" -msgstr "некоректне значення preshared-key-flags для вузла" +#: ../src/libnm-core-impl/nm-setting-8021x.c:285 +msgid "data missing" +msgstr "пропущено дані" -#: ../libnm-core/nm-setting-wireguard.c:1585 +#: ../src/libnm-core-impl/nm-setting-8021x.c:306 +#: ../src/libnm-core-impl/nm-setting-8021x.c:674 #, c-format -msgid "peer #%u has no public-key" -msgstr "для вузла %u не вказано відкритого ключа" +msgid "certificate is invalid: %s" +msgstr "некоректний сертифікат: %s" -#: ../libnm-core/nm-setting-wireguard.c:1598 +#: ../src/libnm-core-impl/nm-setting-8021x.c:315 #, c-format -msgid "peer #%u has invalid public-key" -msgstr "вузол %u має некоректний відкритий ключ" +msgid "certificate detected as invalid scheme" +msgstr "сертифікат виявлено як некоректні дані" -#: ../libnm-core/nm-setting-wireguard.c:1614 -#, c-format -msgid "peer #%u has invalid endpoint" -msgstr "вузол %u має некоректну кінцеву точку" +#: ../src/libnm-core-impl/nm-setting-8021x.c:541 +msgid "CA certificate must be in X.509 format" +msgstr "Форматом сертифіката CA має бути X.509" -#: ../libnm-core/nm-setting-wireguard.c:1646 -#, c-format -msgid "peer #%u has invalid allowed-ips setting" -msgstr "для вузла %u визначено некоректний параметр allowed-ips" +#: ../src/libnm-core-impl/nm-setting-8021x.c:553 +msgid "invalid certificate format" +msgstr "некоректний формат сертифіката" -#: ../libnm-core/nm-setting-wireguard.c:1660 +#: ../src/libnm-core-impl/nm-setting-8021x.c:685 #, c-format -msgid "peer #%u is invalid: %s" -msgstr "вузол %u є некоректним: %s" +msgid "password is not supported when certificate is not on a PKCS#11 token" +msgstr "" +"підтримки паролів не передбачено, якщо сертифікат не міститься у ключі " +"PKCS#11" + +#: ../src/libnm-core-impl/nm-setting-8021x.c:2628 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2651 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2691 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2714 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2764 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2782 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2806 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2824 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2855 +#: ../src/libnm-core-impl/nm-setting-adsl.c:165 +#: ../src/libnm-core-impl/nm-setting-cdma.c:134 +#: ../src/libnm-core-impl/nm-setting-cdma.c:143 +#: ../src/libnm-core-impl/nm-setting-connection.c:1083 +#: ../src/libnm-core-impl/nm-setting-connection.c:1126 +#: ../src/libnm-core-impl/nm-setting-connection.c:1321 +#: ../src/libnm-core-impl/nm-setting-gsm.c:282 +#: ../src/libnm-core-impl/nm-setting-gsm.c:337 +#: ../src/libnm-core-impl/nm-setting-gsm.c:380 +#: ../src/libnm-core-impl/nm-setting-gsm.c:389 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5129 +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:206 +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:218 +#: ../src/libnm-core-impl/nm-setting-pppoe.c:136 +#: ../src/libnm-core-impl/nm-setting-pppoe.c:145 +#: ../src/libnm-core-impl/nm-setting-vpn.c:540 +#: ../src/libnm-core-impl/nm-setting-vpn.c:550 +#: ../src/libnm-core-impl/nm-setting-wimax.c:104 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:956 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:984 +#: ../src/libnm-core-impl/nm-setting.c:1240 +msgid "property is empty" +msgstr "властивість є порожньою" -#: ../libnm-core/nm-setting-wireguard.c:1731 -#: ../libnm-core/nm-setting-wireguard.c:1750 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2667 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2730 #, c-format -msgid "method \"%s\" is not supported for WireGuard" -msgstr "підтримки методу «%s» для WireGuard не передбачено" +msgid "has to match '%s' property for PKCS#12" +msgstr "має відповідати властивості «%s» для PKCS#12" -#: ../libnm-core/nm-setting-wireguard.c:1774 -msgid "key must be 32 bytes base64 encoded" -msgstr "ключ має складатися з 32 байтів у кодуванні base64" +#: ../src/libnm-core-impl/nm-setting-8021x.c:2933 +msgid "can be enabled only on Ethernet connections" +msgstr "можна вмикати лише для з'єднань Ethernet" -#: ../libnm-core/nm-setting-wireguard.c:1904 -msgid "invalid peer secrets" -msgstr "некоректні реєстраційні дані до вузла" +#: ../src/libnm-core-impl/nm-setting-8021x.c:2954 +#: ../src/libnm-core-impl/nm-setting-bluetooth.c:92 +#: ../src/libnm-core-impl/nm-setting-infiniband.c:163 +#: ../src/libnm-core-impl/nm-setting-infiniband.c:175 +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:194 +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:243 +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:257 +#: ../src/libnm-core-impl/nm-setting-olpc-mesh.c:121 +#: ../src/libnm-core-impl/nm-setting-wifi-p2p.c:132 +#: ../src/libnm-core-impl/nm-setting-wimax.c:116 +#: ../src/libnm-core-impl/nm-setting-wired.c:786 +#: ../src/libnm-core-impl/nm-setting-wired.c:799 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:1009 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:1021 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:1033 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:1046 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:1059 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:1090 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:1141 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:1190 +#: ../src/libnm-core-impl/nm-setting-wireless.c:884 +#: ../src/libnm-core-impl/nm-setting-wireless.c:896 +#: ../src/libnm-core-impl/nm-setting-wireless.c:909 +#: ../src/libnm-core-impl/nm-setting-wpan.c:161 +#: ../src/libnm-core-impl/nm-utils.c:4533 +msgid "property is invalid" +msgstr "властивість є некоректною" -#: ../libnm-core/nm-setting-wireguard.c:1930 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2979 +#: ../src/libnm-core-impl/nm-setting-8021x.c:2992 +#: ../src/libnm-core-impl/nm-setting-8021x.c:3005 +#: ../src/libnm-core-impl/nm-setting-8021x.c:3039 +#: ../src/libnm-core-impl/nm-setting-8021x.c:3052 +#: ../src/libnm-core-impl/nm-setting-adsl.c:177 +#: ../src/libnm-core-impl/nm-setting-adsl.c:190 +#: ../src/libnm-core-impl/nm-setting-bluetooth.c:127 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:926 #, c-format -msgid "peer #%u lacks public-key" -msgstr "для вузла %u не вказано відкритого ключа" +msgid "'%s' is not a valid value for the property" +msgstr "«%s» не є коректним значенням властивості" -#: ../libnm-core/nm-setting-wireguard.c:1947 -#, c-format -msgid "non-existing peer '%s'" -msgstr "вузол «%s», якого не існує" +#: ../src/libnm-core-impl/nm-setting-8021x.c:3018 +msgid "invalid auth flags" +msgstr "некоректні прапорці розпізнавання" -#: ../libnm-core/nm-setting-wireless-security.c:912 +#: ../src/libnm-core-impl/nm-setting-bluetooth.c:151 #, c-format -msgid "'%s' is not a valid value for '%s' mode connections" -msgstr "«%s» не є коректним значенням режиму з'єднань «%s»" +msgid "'%s' connection requires '%s' or '%s' setting" +msgstr "з'єднання «%s» потребує параметра «%s» або «%s»" -#: ../libnm-core/nm-setting-wireless-security.c:942 +#: ../src/libnm-core-impl/nm-setting-bluetooth.c:203 #, c-format -msgid "'%s' security requires '%s=%s'" -msgstr "для захисту «%s» слід вказати «%s=%s»" +msgid "'%s' connection requires '%s' setting" +msgstr "з'єднання «%s» потребує параметра «%s»" -#: ../libnm-core/nm-setting-wireless-security.c:971 +#: ../src/libnm-core-impl/nm-setting-bond.c:495 #, c-format -msgid "'%s' security requires '%s' setting presence" -msgstr "захист «%s» вимагає використання параметра «%s»" +msgid "'%s' option is empty" +msgstr "параметр «%s» є порожнім" -#: ../libnm-core/nm-setting-wireless-security.c:996 +#: ../src/libnm-core-impl/nm-setting-bond.c:504 #, c-format -msgid "'%d' value is out of range <0-3>" -msgstr "значення «%d» лежить поза діапазоном <0-3>" +msgid "'%s' is not a valid IPv4 address for '%s' option" +msgstr "«%s» не є припустимою адресою IPv4 для параметра «%s»" -#: ../libnm-core/nm-setting-wireless-security.c:1073 +#: ../src/libnm-core-impl/nm-setting-bond.c:531 #, c-format -msgid "'%s' can only be used with '%s=%s' (WEP)" -msgstr "«%s» можна використовувати лише з «%s=%s» (WEP)" +msgid "missing option name" +msgstr "не вказано назви параметра" -#: ../libnm-core/nm-setting-wireless-security.c:1111 +#: ../src/libnm-core-impl/nm-setting-bond.c:536 #, c-format -msgid "" -"'%s' can only be used with 'wpa-eap', 'wpa-eap-suite-b-192', 'wpa-psk' or " -"'sae' key management " -msgstr "" -"«%s» можна використовувати лише з керуванням ключами «wpa-eap», «wpa-eap-" -"suite-b-192», «wpa-psk» або «sae»" +msgid "invalid option '%s'" +msgstr "некоректний параметр «%s»" -#: ../libnm-core/nm-setting-wireless.c:813 +#: ../src/libnm-core-impl/nm-setting-bond.c:572 #, c-format -msgid "'%s' is not a valid Wi-Fi mode" -msgstr "«%s» не є коректним режимом Wi-Fi" +msgid "invalid value '%s' for option '%s'" +msgstr "некоректне значення «%s» для параметра «%s»" -#: ../libnm-core/nm-setting-wireless.c:826 +#: ../src/libnm-core-impl/nm-setting-bond.c:814 #, c-format -msgid "'%s' is not a valid band" -msgstr "«%s» не є коректним значенням смуги" +msgid "mandatory option '%s' is missing" +msgstr "пропущено обов'язковий параметр «%s»" -#: ../libnm-core/nm-setting-wireless.c:839 +#: ../src/libnm-core-impl/nm-setting-bond.c:824 #, c-format -msgid "'%s' requires setting '%s' property" -msgstr "«%s» потребує встановлення властивості «%s»" +msgid "'%s' is not a valid value for '%s'" +msgstr "«%s» не є коректним значенням «%s»" -#: ../libnm-core/nm-setting-wireless.c:869 +#: ../src/libnm-core-impl/nm-setting-bond.c:837 #, c-format -msgid "'%s' requires '%s' and '%s' property" -msgstr "«%s» потребує «%s» і властивості «%s»" +msgid "'%s=%s' is incompatible with '%s > 0'" +msgstr "«%s=%s» є несумісним з «%s > 0»" -#: ../libnm-core/nm-setting-wireless.c:981 ../libnm-core/nm-team-utils.c:2253 +#: ../src/libnm-core-impl/nm-setting-bond.c:854 #, c-format -msgid "invalid value" -msgstr "некоректне значення" - -#: ../libnm-core/nm-setting-wireless.c:994 -msgid "Wake-on-WLAN mode 'default' and 'ignore' are exclusive flags" -msgstr "" -"Прапорці режиму Wake-on-WLAN «default» і «ignore» не можна використовувати " -"одночасно" +msgid "'%s' is not valid for the '%s' option: %s" +msgstr "«%s» є некоректним для параметра «%s»: %s" -#: ../libnm-core/nm-setting-wireless.c:1005 -msgid "Wake-on-WLAN trying to set unknown flag" -msgstr "Wake-on-WLAN намагається встановити невідомий прапорець" +#: ../src/libnm-core-impl/nm-setting-bond.c:866 +#, c-format +msgid "'%s' option is only valid for '%s=%s'" +msgstr "параметр «%s» можна використовувати, лише якщо «%s=%s»" -#: ../libnm-core/nm-setting-wireless.c:1018 -msgid "AP isolation can be set only in AP mode" -msgstr "Ізоляцію точки доступу можна встановлювати лише у режимі точки доступу" +#: ../src/libnm-core-impl/nm-setting-bond.c:879 +#, c-format +msgid "'%s=%s' is not a valid configuration for '%s'" +msgstr "«%s=%s» не є коректним налаштуванням для «%s»" -#: ../libnm-core/nm-setting-wireless.c:1042 +#: ../src/libnm-core-impl/nm-setting-bond.c:894 +#: ../src/libnm-core-impl/nm-setting-bond.c:905 #, c-format -msgid "conflicting value of mac-address-randomization and cloned-mac-address" -msgstr "конфлікт значень mac-address-randomization і cloned-mac-address" +msgid "'%s' option requires '%s' option to be enabled" +msgstr "використання параметра «%s» вимагає вмикання параметра «%s»" -#: ../libnm-core/nm-setting-wpan.c:171 -msgid "page must be defined along with a channel" -msgstr "сторінку слід вказувати разом із каналом" +#: ../src/libnm-core-impl/nm-setting-bond.c:922 +#: ../src/libnm-core-impl/nm-setting-bond.c:933 +#, c-format +msgid "'%s' option requires '%s' option to be set" +msgstr "використання параметра «%s» вимагає встановлення параметра «%s»" -#: ../libnm-core/nm-setting-wpan.c:180 +#: ../src/libnm-core-impl/nm-setting-bond.c:946 #, c-format -msgid "page must be between %d and %d" -msgstr "сторінку має бути вказано числом від %d до %d" +msgid "'%s' option is only valid with mode '%s'" +msgstr "параметр «%s» є коректним лише у режимі «%s»" -#: ../libnm-core/nm-setting-wpan.c:191 +#: ../src/libnm-core-impl/nm-setting-bond.c:959 #, c-format -msgid "channel must not be between %d and %d" -msgstr "канал має бути вказано числом від %d до %d" +msgid "'%s' and '%s' cannot have different values" +msgstr "Значення «%s» і «%s» не можуть бути різними" -#: ../libnm-core/nm-setting.c:795 +#: ../src/libnm-core-impl/nm-setting-bond.c:982 #, c-format -msgid "duplicate property" -msgstr "дублювання властивості" +msgid "'%s' option should be string" +msgstr "параметр «%s» має бути рядком" -#: ../libnm-core/nm-setting.c:815 +#: ../src/libnm-core-impl/nm-setting-bond.c:995 #, c-format -msgid "unknown property" -msgstr "невідома властивість" +msgid "'%s' option is not valid with mode '%s'" +msgstr "параметр «%s» є коректним з режимом «%s»" -#: ../libnm-core/nm-setting.c:896 ../libnm-core/nm-setting.c:950 +#: ../src/libnm-core-impl/nm-setting-bridge-port.c:302 +#: ../src/libnm-core-impl/nm-setting-ovs-bridge.c:151 +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:289 +#: ../src/libnm-core-impl/nm-setting-ovs-port.c:170 +#: ../src/libnm-core-impl/nm-setting-team-port.c:307 #, c-format -msgid "can't set property of type '%s' from value of type '%s'" -msgstr "не вдалося встановити властивість типу «%s» зі значення типу «%s»" +msgid "missing setting" +msgstr "пропущено параметр" -#: ../libnm-core/nm-setting.c:917 ../libnm-core/nm-setting.c:933 +#: ../src/libnm-core-impl/nm-setting-bridge-port.c:312 +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:312 +#: ../src/libnm-core-impl/nm-setting-ovs-port.c:193 +#: ../src/libnm-core-impl/nm-setting-team-port.c:317 #, c-format -msgid "failed to set property: %s" -msgstr "не вдалося встановити значення властивості: %s" +msgid "" +"A connection with a '%s' setting must have the slave-type set to '%s'. " +"Instead it is '%s'" +msgstr "" +"Для з'єднання з параметром «%s» має бути встановлено тип підлеглості «%s». " +"Замість цього маємо «%s»." -#: ../libnm-core/nm-setting.c:970 +#: ../src/libnm-core-impl/nm-setting-bridge.c:1165 #, c-format -msgid "can not set property: %s" -msgstr "не вдалося встановити значення властивості: %s" +msgid "value '%d' is out of range <%d-%d>" +msgstr "значення «%d» лежить поза діапазоном <%d-%d>" -#: ../libnm-core/nm-setting.c:2016 -msgid "secret not found" -msgstr "не знайдено ключа" +#: ../src/libnm-core-impl/nm-setting-bridge.c:1184 +msgid "is not a valid MAC address" +msgstr "не є коректною MAC-адресою" -#: ../libnm-core/nm-team-utils.c:1531 ../libnm-core/nm-team-utils.c:1548 -#, c-format -msgid "invalid D-Bus property \"%s\"" -msgstr "некоректна властивість D-Bus «%s»" +#: ../src/libnm-core-impl/nm-setting-bridge.c:1228 +msgid "the mask can't contain bits 0 (STP), 1 (MAC) or 2 (LACP)" +msgstr "маска не може містити біти 0 (STP), 1 (MAC) і 2 (LACP)" -#: ../libnm-core/nm-team-utils.c:1560 -#, c-format -msgid "duplicate D-Bus property \"%s\"" -msgstr "дублювання властивості D-Bus «%s»" +#: ../src/libnm-core-impl/nm-setting-bridge.c:1250 +msgid "is not a valid link local MAC address" +msgstr "не є коректною MAC-адресою для локальних з'єднань" -#: ../libnm-core/nm-team-utils.c:1580 -#, c-format -msgid "invalid D-Bus property \"%s\" for \"%s\"" -msgstr "некоректна властивість D-Bus «%s» для «%s»" +#: ../src/libnm-core-impl/nm-setting-bridge.c:1262 +msgid "is not a valid VLAN filtering protocol" +msgstr "не є коректним протоколом фільтрування VLAN" -#: ../libnm-core/nm-team-utils.c:1652 -#, c-format -msgid "unknown link-watcher name \"%s\"" -msgstr "некоректна назва засобу спостереження за зв'язком, «%s»" +#: ../src/libnm-core-impl/nm-setting-bridge.c:1274 +msgid "is not a valid option" +msgstr "не є коректним параметром" -#: ../libnm-core/nm-team-utils.c:2239 +#: ../src/libnm-core-impl/nm-setting-bridge.c:1286 #, c-format -msgid "value out or range" -msgstr "значення поза припустимим діапазоном" +msgid "'%s' option must be a power of 2" +msgstr "Значенням параметра «%s» має бути степінь 2" -#: ../libnm-core/nm-team-utils.c:2274 +#: ../src/libnm-core-impl/nm-setting-connection.c:967 #, c-format -msgid "invalid runner-tx-hash" -msgstr "некоректне значення runner-tx-hash" +msgid "setting required for connection of type '%s'" +msgstr "для з'єднання типу «%s» потрібен параметр" -#: ../libnm-core/nm-team-utils.c:2303 +#: ../src/libnm-core-impl/nm-setting-connection.c:998 #, c-format -msgid "%s is only allowed for runner %s" -msgstr "%s можна використовувати лише для засобу запуску %s" +msgid "Unknown slave type '%s'" +msgstr "Невідомий тип підлеглого «%s»" -#: ../libnm-core/nm-team-utils.c:2313 +#: ../src/libnm-core-impl/nm-setting-connection.c:1013 #, c-format -msgid "%s is only allowed for runners %s" -msgstr "%s можна використовувати лише для засобів запуску %s" +msgid "Slave connections need a valid '%s' property" +msgstr "Для підлеглих з'єднань потрібна коректна властивість «%s»" -#: ../libnm-core/nm-team-utils.c:2334 +#: ../src/libnm-core-impl/nm-setting-connection.c:1037 #, c-format -msgid "cannot set parameters for lacp and activebackup runners together" -msgstr "" -"не можна встановлювати параметри для засобів запуску lacp і activebackup " -"одночасно" +msgid "Cannot set '%s' without '%s'" +msgstr "Не можна встановити «%s» без «%s»" -#: ../libnm-core/nm-team-utils.c:2348 +#: ../src/libnm-core-impl/nm-setting-connection.c:1095 #, c-format -msgid "missing link watcher" -msgstr "не вказано засобу спостереження за зв'язком" +msgid "'%s' is not a valid UUID" +msgstr "«%s» не є коректним UUID" -#: ../libnm-core/nm-team-utils.c:2374 +#: ../src/libnm-core-impl/nm-setting-connection.c:1140 #, c-format -msgid "team config exceeds size limit" -msgstr "налаштування команди порушують обмеження щодо розміру" +msgid "connection type '%s' is not valid" +msgstr "тип з'єднання «%s» є некоректним" -#: ../libnm-core/nm-team-utils.c:2385 +#: ../src/libnm-core-impl/nm-setting-connection.c:1246 #, c-format -msgid "team config is not valid UTF-8" -msgstr "файл налаштувань team не є коректними даними у кодуванні UTF-8" +msgid "'%s' connections must be enslaved to '%s', not '%s'" +msgstr "з'єднання «%s» мають підпорядковуватися «%s», а не «%s»" -#: ../libnm-core/nm-team-utils.c:2396 -#: ../src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c:9941 +#: ../src/libnm-core-impl/nm-setting-connection.c:1262 #, c-format -msgid "invalid json" -msgstr "некоректний код JSON" +msgid "metered value %d is not valid" +msgstr "лічильне значення %d є некоректним" -#: ../libnm-core/nm-team-utils.c:2560 +#: ../src/libnm-core-impl/nm-setting-connection.c:1276 +#: ../src/libnm-core-impl/nm-setting-connection.c:1290 +#: ../src/libnm-core-impl/nm-setting-connection.c:1307 #, c-format -msgid "invalid D-Bus type \"%s\"" -msgstr "некоректний тип D-Bus «%s»" +msgid "value %d is not valid" +msgstr "значення %d є некоректним" -#: ../libnm-core/nm-team-utils.c:2599 -#, c-format -msgid "invalid link-watchers: %s" -msgstr "некоректне значення link-watchers: %s" +#: ../src/libnm-core-impl/nm-setting-connection.c:1335 +msgid "DHCP option cannot be longer than 255 characters" +msgstr "Довжина параметра DHCP не може перевищувати 255 символів" -#: ../libnm-core/nm-utils.c:2312 -#, c-format -msgid "'%s' is not a valid handle." -msgstr "«%s» не є коректним дескриптором." +#: ../src/libnm-core-impl/nm-setting-connection.c:1346 +msgid "MUD URL is not a valid URL" +msgstr "Адреса MUD не є коректною адресою" + +#: ../src/libnm-core-impl/nm-setting-connection.c:1366 +msgid "invalid permissions not in format \"user:$UNAME[:]\"" +msgstr "некоректний запис прав доступу, не у форматі «користувач:$UNAME[:]»" -#: ../libnm-core/nm-utils.c:2460 +#: ../src/libnm-core-impl/nm-setting-connection.c:1395 #, c-format -msgid "'%s' unexpected: parent already specified." -msgstr "Неочікуване «%s»: батьківський запис вже вказано." +msgid "property type should be set to '%s'" +msgstr "тип властивості має бути встановлено у значення «%s»" -#: ../libnm-core/nm-utils.c:2478 +#: ../src/libnm-core-impl/nm-setting-connection.c:1413 #, c-format -msgid "invalid handle: '%s'" -msgstr "некоректний дескриптор: «%s»" +msgid "slave-type '%s' requires a '%s' setting in the connection" +msgstr "тип підлеглого з'єднання «%s» потребує параметра «%s» у з'єднанні" -#: ../libnm-core/nm-utils.c:2500 -msgid "parent not specified." -msgstr "не вказано батьківський запис." +#: ../src/libnm-core-impl/nm-setting-connection.c:1424 +#, c-format +msgid "" +"Detect a slave connection with '%s' set and a port type '%s'. '%s' should be " +"set to '%s'" +msgstr "" +"Визначити підлегле з'єднання зі встановленим «%s» і типом порту «%s». «%s» " +"слід встановити у значення «%s»" -#: ../libnm-core/nm-utils.c:2564 +#: ../src/libnm-core-impl/nm-setting-connection.c:1450 #, c-format -msgid "unsupported qdisc option: '%s'." -msgstr "непідтримуваний параметр qdisc: «%s»." +msgid "A slave connection with '%s' set to '%s' cannot have a '%s' setting" +msgstr "" +"Підлегле з'єднання з «%s», переведене у режим «%s», не може мати параметра " +"«%s»" -#: ../libnm-core/nm-utils.c:2694 -msgid "action name missing." -msgstr "не вказано назви дії." +#: ../src/libnm-core-impl/nm-setting-dcb.c:483 +msgid "flags invalid" +msgstr "некоректні прапорці" -#: ../libnm-core/nm-utils.c:2720 -#, c-format -msgid "unsupported action option: '%s'." -msgstr "непідтримуваний параметр дії: «%s»." +#: ../src/libnm-core-impl/nm-setting-dcb.c:492 +msgid "flags invalid - disabled" +msgstr "некоректні прапорці — вимкнено" -#: ../libnm-core/nm-utils.c:2859 -msgid "invalid action: " -msgstr "некоректна дія: " +#: ../src/libnm-core-impl/nm-setting-dcb.c:518 +#: ../src/libnm-core-impl/nm-setting-dcb.c:564 +msgid "property invalid (not enabled)" +msgstr "властивість є некоректною (не увімкнено)" -#: ../libnm-core/nm-utils.c:2863 -#, c-format -msgid "unsupported tfilter option: '%s'." -msgstr "непідтримуваний параметр tfilter: «%s»." +#: ../src/libnm-core-impl/nm-setting-dcb.c:527 +msgid "element invalid" +msgstr "некоректний елемент" + +#: ../src/libnm-core-impl/nm-setting-dcb.c:542 +msgid "sum not 100%" +msgstr "сума не дорівнює 100%" -#: ../libnm-core/nm-utils.c:3464 -#, c-format -msgid "failed stat file %s: %s" -msgstr "не вдалося отримати статистичні дані щодо файла %s: %s" +#: ../src/libnm-core-impl/nm-setting-dcb.c:573 +#: ../src/libnm-core-impl/nm-setting-dcb.c:608 +msgid "property invalid" +msgstr "некоректна властивість" -#: ../libnm-core/nm-utils.c:3475 -#, c-format -msgid "not a file (%s)" -msgstr "не є файлом (%s)" +#: ../src/libnm-core-impl/nm-setting-dcb.c:598 +msgid "property missing" +msgstr "пропущено властивість" -#: ../libnm-core/nm-utils.c:3486 -#, c-format -msgid "invalid file owner %d for %s" -msgstr "некоректний власник файла, %d, %s" +#: ../src/libnm-core-impl/nm-setting-ethtool.c:291 +msgid "unsupported ethtool setting" +msgstr "непідтримуваний параметр ethtool" -#: ../libnm-core/nm-utils.c:3498 -#, c-format -msgid "file permissions for %s" -msgstr "файлові права доступу до %s" +#: ../src/libnm-core-impl/nm-setting-ethtool.c:300 +msgid "setting has invalid variant type" +msgstr "для параметра вказано некоректний тип варіанта" -#: ../libnm-core/nm-utils.c:3508 -#, c-format -msgid "reject %s" -msgstr "відмовити %s" +#: ../src/libnm-core-impl/nm-setting-ethtool.c:312 +msgid "coalesce option must be either 0 or 1" +msgstr "значенням параметра coalesce має бути 0 або 1" -#: ../libnm-core/nm-utils.c:3528 +#: ../src/libnm-core-impl/nm-setting-ethtool.c:335 #, c-format -msgid "path is not absolute (%s)" -msgstr "шлях не є абсолютним (%s)" +msgid "unknown ethtool option '%s'" +msgstr "невідомий параметр ethtool «%s»" -#: ../libnm-core/nm-utils.c:3543 +#: ../src/libnm-core-impl/nm-setting-gsm.c:295 #, c-format -msgid "Plugin file does not exist (%s)" -msgstr "Файла додатка не існує (%s)" +msgid "property value '%s' is empty or too long (>64)" +msgstr "значення властивості, «%s», є порожнім або надто довгим (>64)" -#: ../libnm-core/nm-utils.c:3552 +#: ../src/libnm-core-impl/nm-setting-gsm.c:325 #, c-format -msgid "Plugin is not a valid file (%s)" -msgstr "Додаток не є коректним файлом (%s)" +msgid "'%s' contains invalid char(s) (use [A-Za-z._-])" +msgstr "«%s» містить некоректні символи (слід використовувати [A-Za-z._-])" -#: ../libnm-core/nm-utils.c:3563 +#: ../src/libnm-core-impl/nm-setting-gsm.c:351 #, c-format -msgid "libtool archives are not supported (%s)" -msgstr "Підтримки архівів libtool не передбачено (%s)" +msgid "'%s' length is invalid (should be 5 or 6 digits)" +msgstr "довжина «%s» є некоректною (має бути 5 або 6 цифр)" -#: ../libnm-core/nm-utils.c:3639 +#: ../src/libnm-core-impl/nm-setting-gsm.c:365 #, c-format -msgid "Could not find \"%s\" binary" -msgstr "Не вдалося знайти виконуваний файл «%s»" - -#: ../libnm-core/nm-utils.c:4483 -msgid "unknown secret flags" -msgstr "невідомі прапорці реєстраційних даних" +msgid "'%s' is not a number" +msgstr "«%s» не є числом" -#: ../libnm-core/nm-utils.c:4493 -msgid "conflicting secret flags" -msgstr "конфлікт прапорців реєстраційних даних" +#: ../src/libnm-core-impl/nm-setting-gsm.c:402 +msgid "property is empty or wrong size" +msgstr "властивість є порожньою або має помилковий розмір" -#: ../libnm-core/nm-utils.c:4504 -msgid "secret flags must not be \"not-required\"" -msgstr "прапорці реєстраційних даних не можуть бути «not-required»" +#: ../src/libnm-core-impl/nm-setting-gsm.c:415 +msgid "property must contain only digits" +msgstr "властивість має містити лише цифри" -#: ../libnm-core/nm-utils.c:4512 -msgid "unsupported secret flags" -msgstr "непідтримувані прапорці реєстраційних даних" +#: ../src/libnm-core-impl/nm-setting-gsm.c:429 +msgid "can't be enabled when manual configuration is present" +msgstr "не можна вмикати, якщо є налаштування вручну" -#: ../libnm-core/nm-utils.c:4542 -msgid "can't be simultaneously disabled and enabled" -msgstr "не може бути одночасно вимкнено і увімкнено" +#: ../src/libnm-core-impl/nm-setting-infiniband.c:201 +msgid "Must specify a P_Key if specifying parent" +msgstr "Якщо вказано параметр parent, слід вказати і P_Key" -#: ../libnm-core/nm-utils.c:4550 -msgid "WPS is required" -msgstr "Потрібна WPS" +#: ../src/libnm-core-impl/nm-setting-infiniband.c:212 +msgid "InfiniBand P_Key connection did not specify parent interface name" +msgstr "" +"У записі з'єднання закритого ключа InfiniBand не вказано назви батьківського " +"інтерфейсу" -#: ../libnm-core/nm-utils.c:4618 +#: ../src/libnm-core-impl/nm-setting-infiniband.c:234 #, c-format -msgid "not a valid ethernet MAC address for mask at position %lld" -msgstr "некоректна адреса MAC ethernet для маски у позиції %lld" +msgid "" +"interface name of software infiniband device must be '%s' or unset (instead " +"it is '%s')" +msgstr "" +"назвою інтерфейсу програмного пристрою infiniband має бути «%s» або назву " +"має бути не встановлено (замість неї має бути «%s»)" -#: ../libnm-core/nm-utils.c:4637 +#: ../src/libnm-core-impl/nm-setting-infiniband.c:262 #, c-format -msgid "not a valid ethernet MAC address #%u at position %lld" -msgstr "некоректна адреса MAC ethernet #%u у позиції %lld" - -#: ../libnm-core/nm-utils.c:5292 -msgid "not valid utf-8" -msgstr "некоректні дані UTF-8" - -#: ../libnm-core/nm-utils.c:5313 ../libnm-core/nm-utils.c:5366 -msgid "is not a JSON object" -msgstr "не є об'єктом JSON" - -#: ../libnm-core/nm-utils.c:5342 -msgid "value is NULL" -msgstr "значенням є NULL" +msgid "mtu can be at most %u but it is %u" +msgstr "mtu не може перевищувати %u, але маємо %u" -#: ../libnm-core/nm-utils.c:5342 -msgid "value is empty" -msgstr "порожнє значення" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:111 +#, c-format +msgid "Missing IPv4 address" +msgstr "Не вказано адреси IPv4" -#: ../libnm-core/nm-utils.c:5354 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:111 #, c-format -msgid "invalid JSON at position %d (%s)" -msgstr "некоректний код JSON на позиції %d (%s)" +msgid "Missing IPv6 address" +msgstr "Не вказано адреси IPv6" -#: ../libnm-core/nm-utils.c:5484 ../libnm-core/nm-utils.c:5504 -msgid "unterminated escape sequence" -msgstr "незавершена екранована послідовність" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:118 +#, c-format +msgid "Invalid IPv4 address '%s'" +msgstr "Некоректна адреса IPv4, «%s»" -#: ../libnm-core/nm-utils.c:5530 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:119 #, c-format -msgid "unknown attribute '%s'" -msgstr "невідомий атрибут «%s»" +msgid "Invalid IPv6 address '%s'" +msgstr "Некоректна адреса IPv6, «%s»" -#: ../libnm-core/nm-utils.c:5548 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:135 #, c-format -msgid "missing key-value separator '%c' after '%s'" -msgstr "пропущено роздільник пар ключ-значення «%c» після «%s»" +msgid "Invalid IPv4 address prefix '%u'" +msgstr "Некоректний префікс адреси IPv4, «%u»" -#: ../libnm-core/nm-utils.c:5568 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:136 #, c-format -msgid "invalid uint32 value '%s' for attribute '%s'" -msgstr "некоректне значення uint32 «%s» атрибута «%s»" +msgid "Invalid IPv6 address prefix '%u'" +msgstr "Некоректний префікс адреси IPv6, «%u»" -#: ../libnm-core/nm-utils.c:5582 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:153 #, c-format -msgid "invalid int32 value '%s' for attribute '%s'" -msgstr "некоректне значення int32 «%s» атрибута «%s»" +msgid "Invalid routing metric '%s'" +msgstr "Некоректна метрика маршрутизації, «%s»" + +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1317 +#: ../src/libnm-core-impl/nm-setting-sriov.c:399 +msgid "unknown attribute" +msgstr "невідомий атрибут" -#: ../libnm-core/nm-utils.c:5595 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1327 +#: ../src/libnm-core-impl/nm-setting-sriov.c:409 #, c-format -msgid "invalid uint64 value '%s' for attribute '%s'" -msgstr "некоректне значення uint64 «%s» атрибута «%s»" +msgid "invalid attribute type '%s'" +msgstr "некоректний тип атрибута «%s»" -#: ../libnm-core/nm-utils.c:5608 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1336 #, c-format -msgid "invalid uint8 value '%s' for attribute '%s'" -msgstr "некоректне значення uint8 «%s» атрибута «%s»" +msgid "attribute is not valid for a IPv4 route" +msgstr "атрибут не є коректним для маршрутизації IPv4" -#: ../libnm-core/nm-utils.c:5622 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1337 #, c-format -msgid "invalid boolean value '%s' for attribute '%s'" -msgstr "некоректне булеве значення «%s» атрибута «%s»" +msgid "attribute is not valid for a IPv6 route" +msgstr "атрибут не є коректним для маршрутизації IPv6" -#: ../libnm-core/nm-utils.c:5636 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1350 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1380 #, c-format -msgid "unsupported attribute '%s' of type '%s'" -msgstr "непідтримуваний атрибут «%s» типу «%s»" +msgid "'%s' is not a valid IPv4 address" +msgstr "«%s» не є коректною адресою IPv4" -#: ../libnm-core/nm-utils.c:5938 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1351 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1381 #, c-format -msgid "Bridge VLANs %d and %d are not sorted by ascending vid" -msgstr "VLAN містка %d і %d не упорядковано за зростанням vid" +msgid "'%s' is not a valid IPv6 address" +msgstr "«%s» не є коректною адресою IPv6" -#: ../libnm-core/nm-utils.c:5962 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1371 #, c-format -msgid "duplicate bridge VLAN vid %u" -msgstr "дублікат містка vid VLAN %u" +msgid "invalid prefix %s" +msgstr "некоректний префікс %s" -#: ../libnm-core/nm-utils.c:5974 -msgid "only one VLAN can be the PVID" -msgstr "лише одна з VLAN може бути PVID" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1392 +#, c-format +msgid "%s is not a valid route type" +msgstr "%s не є коректним типом маршруту" -#: ../libnm-core/nm-utils.c:6019 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:1447 #, c-format -msgid "unknown flags 0x%x" -msgstr "невідомі прапорці 0x%x" +msgid "route scope is invalid" +msgstr "область маршрутів є некоректною" -#: ../libnm-core/nm-utils.c:6031 -msgid "" -"'fqdn-no-update' and 'fqdn-serv-update' flags cannot be set at the same time" -msgstr "" -"не можна одночасно встановлювати прапорці «fqdn-no-update» і «fqdn-serv-" -"update»" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2558 +msgid "invalid priority" +msgstr "некоректна пріоритетність" -#: ../libnm-core/nm-utils.c:6042 -msgid "'fqdn-clear-flags' flag is incompatible with other FQDN flags" -msgstr "прапорець «fqdn-clear-flags» є несумісним із іншими прапорцями FQDN" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2571 +msgid "missing table" +msgstr "не вказано таблиці" -#: ../libnm-core/nm-utils.c:6050 -msgid "DHCPv6 does not support the E (encoded) FQDN flag" -msgstr "у DHCPv6 не передбачено підтримки прапорця E (закодовано) FQDN" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2579 +msgid "invalid action" +msgstr "некоректна дія" -#: ../libnm-core/nm-vpn-editor-plugin.c:284 -#, c-format -msgid "cannot load plugin \"%s\": %s" -msgstr "не вдалося завантажити додаток «%s»: %s" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2588 +msgid "has from/src but the prefix-length is zero" +msgstr "" +"містить from/src, але значення довжини префікса (prefix-length) є нульовим" -#: ../libnm-core/nm-vpn-editor-plugin.c:295 -#, c-format -msgid "failed to load nm_vpn_editor_plugin_factory() from %s (%s)" -msgstr "не вдалося завантажити nm_vpn_editor_plugin_factory() з %s (%s)" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2596 +msgid "missing from/src for a non zero prefix-length" +msgstr "пропущено from/src для ненульового значення довжини префікса" -#: ../libnm-core/nm-vpn-editor-plugin.c:321 -#, c-format -msgid "unknown error initializing plugin %s" -msgstr "невідома помилка під час спроби ініціалізації додатка %s" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2603 +msgid "invalid from/src" +msgstr "некоректне значення from/src" -#: ../libnm-core/nm-vpn-editor-plugin.c:341 -#, c-format -msgid "cannot load VPN plugin in '%s': missing plugin name" -msgstr "не вдалося завантажити додаток VPN у «%s»: не вказано назви додатка" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2610 +msgid "invalid prefix length for from/src" +msgstr "некоректна довжина префікса для from/src" -#: ../libnm-core/nm-vpn-editor-plugin.c:349 -#, c-format -msgid "cannot load VPN plugin in '%s': invalid service name" -msgstr "не вдалося завантажити додаток VPN у «%s»: некоректна назва служби" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2619 +msgid "has to/dst but the prefix-length is zero" +msgstr "" +"містить to/dst, але значення довжини префікса (prefix-length) є нульовим" -#: ../libnm-core/nm-vpn-editor-plugin.c:481 -#, c-format -msgid "the plugin does not support import capability" -msgstr "у додатку не передбачено можливостей імпортування" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2627 +msgid "missing to/dst for a non zero prefix-length" +msgstr "пропущено to/dst для ненульового значення довжини префікса" -#: ../libnm-core/nm-vpn-editor-plugin.c:505 -#, c-format -msgid "the plugin does not support export capability" -msgstr "у додатку не передбачено можливостей експортування" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2634 +msgid "invalid to/dst" +msgstr "некоректне значення to/dst" -#: ../libnm-core/nm-vpn-plugin-info.c:109 -#, c-format -msgid "missing filename" -msgstr "не вказано назви файла" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2641 +msgid "invalid prefix length for to/dst" +msgstr "некоректна довжина префікса для to/dst" -#: ../libnm-core/nm-vpn-plugin-info.c:117 -#, c-format -msgid "filename must be an absolute path (%s)" -msgstr "назву файла має бути вказано у форматі абсолютного шляху (%s)" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2651 +msgid "invalid iifname" +msgstr "некоректна назва інтерфейсу" -#: ../libnm-core/nm-vpn-plugin-info.c:126 -#, c-format -msgid "filename has invalid format (%s)" -msgstr "назву файла вказано у некоректному форматі (%s)" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2661 +msgid "invalid oifname" +msgstr "некоректна назва інтерфейсу (oifname)" -#: ../libnm-core/nm-vpn-plugin-info.c:419 -#, c-format -msgid "there exists a conflicting plugin (%s) that has the same %s.%s value" -msgstr "виявлено конфліктний додаток (%s), який має те саме значення %s.%s" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2669 +msgid "invalid source port range" +msgstr "некоректний діапазон номерів порту джерела" -#: ../libnm-core/nm-vpn-plugin-info.c:458 -#, c-format -msgid "there exists a conflicting plugin with the same name (%s)" -msgstr "виявлено конфліктний додаток із тією самою назвою (%s)" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2677 +msgid "invalid destination port range" +msgstr "некоректний діапазон номерів порту призначення" -#: ../libnm-core/nm-vpn-plugin-info.c:1050 -#, c-format -msgid "missing \"plugin\" setting" -msgstr "не вказано параметр «plugin»" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2687 +msgid "suppress_prefixlength out of range" +msgstr "suppress_prefixlength поза припустимим діапазоном" -#: ../libnm-core/nm-vpn-plugin-info.c:1060 -#, c-format -msgid "%s: don't retry loading plugin which already failed previously" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2695 +msgid "suppress_prefixlength is only allowed with the to-table action" msgstr "" -"%s: не намагатися повторно завантажити додаток, спроба завантаження якого " -"вже завершилася помилкою" - -#: ../libnm-core/nm-vpn-plugin-info.c:1134 -msgid "missing filename to load VPN plugin info" -msgstr "не вказано назви файла для завантаження даних щодо додатка VPN" - -#: ../libnm-core/nm-vpn-plugin-info.c:1149 -msgid "missing name for VPN plugin info" -msgstr "не вказано назви для даних щодо додатка VPN" +"suppress_prefixlength можна використовувати лише разом із дією to-table" -#: ../libnm-core/nm-vpn-plugin-info.c:1163 -msgid "missing service for VPN plugin info" -msgstr "не вказано служби для даних щодо додатка VPN" +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2808 +#, c-format +msgid "duplicate key %s" +msgstr "дублікат ключа %s" -#: ../libnm/nm-client.c:3765 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2823 #, c-format -msgid "request succeeded with %s but object is in an unsuitable state" -msgstr "запит успішно виконано (%s), але об'єкт перебуває у непридатному стані" +msgid "invalid key \"%s\"" +msgstr "некоректний ключ «%s»" -#: ../libnm/nm-client.c:3857 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2836 #, c-format -msgid "operation succeeded but object %s does not exist" -msgstr "дію успішно виконано, але об'єкта %s не існує" +msgid "invalid variant type '%s' for \"%s\"" +msgstr "некоректний тип варіанта «%s» для «%s»" -#: ../libnm/nm-device-adsl.c:66 -msgid "The connection was not an ADSL connection." -msgstr "З'єднання не є з'єднанням ADSL." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2847 +msgid "missing \"" +msgstr "не вистачає \"" -#: ../libnm/nm-device-bond.c:106 -msgid "The connection was not a bond connection." -msgstr "З'єднання не є з'єднанням зв'язку." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:2855 +msgid "invalid \"" +msgstr "некоректна \"" -#: ../libnm/nm-device-bridge.c:109 -msgid "The connection was not a bridge connection." -msgstr "З'єднання не є з'єднанням містка." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3069 +msgid "Unsupported to-string-flags argument" +msgstr "Непідтримуваний аргумент to-string-flags" -#: ../libnm/nm-device-bt.c:133 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3077 +msgid "Unsupported extra-argument" +msgstr "Непідтримуваний додатковий аргумент" + +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3339 #, c-format -msgid "The connection was not a Bluetooth connection." -msgstr "З'єднання не є з'єднанням Bluetooth." +msgid "unsupported key \"%s\"" +msgstr "непідтримуваний ключ «%s»" -#: ../libnm/nm-device-bt.c:141 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3346 #, c-format -msgid "The connection is of Bluetooth NAP type." -msgstr "З'єднання належить до типу NAP Bluetooth." +msgid "duplicate key \"%s\"" +msgstr "дублікат ключа «%s»" -#: ../libnm/nm-device-bt.c:152 -msgid "Invalid device Bluetooth address." -msgstr "Некоректна адреса Bluetooth пристрою." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3353 +#, c-format +msgid "invalid value for \"%s\"" +msgstr "некоректне значення «%s»" -#: ../libnm/nm-device-bt.c:161 -msgid "The Bluetooth addresses of the device and the connection didn't match." -msgstr "Адреси Bluetooth пристрою і з'єднання не збігаються." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3365 +msgid "empty text does not describe a rule" +msgstr "порожній текст не описує правило" -#: ../libnm/nm-device-bt.c:173 -msgid "" -"The device is lacking Bluetooth capabilities required by the connection." -msgstr "У пристрою немає можливостей Bluetooth, потрібних з'єднанню." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3373 +#, c-format +msgid "missing argument for \"%s\"" +msgstr "пропущено аргумент «%s»" -#: ../libnm/nm-device-dummy.c:65 -msgid "The connection was not a dummy connection." -msgstr "З'єднання не є фіктивним з'єднанням." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3387 +msgid "invalid \"from\" part" +msgstr "некоректна частина «from»" -#: ../libnm/nm-device-dummy.c:74 ../libnm/nm-device-generic.c:89 -#: ../libnm/nm-device-ovs-bridge.c:89 ../libnm/nm-device-ovs-interface.c:57 -#: ../libnm/nm-device-ovs-port.c:89 -msgid "The connection did not specify an interface name." -msgstr "У записі з'єднання не вказано назви інтерфейсу." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3403 +msgid "invalid \"to\" part" +msgstr "некоректна частина «to»" -#: ../libnm/nm-device-ethernet.c:189 -msgid "The connection was not an Ethernet or PPPoE connection." -msgstr "З'єднання не є з'єднанням Ethernet або PPPoE." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3414 +#, c-format +msgid "cannot detect address family for rule" +msgstr "не вдалося визначити сімейство адрес для правила" -#: ../libnm/nm-device-ethernet.c:206 -msgid "The connection and device differ in S390 subchannels." -msgstr "У підканалах S390 виявлено відмінність з'єднання і пристрою." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3468 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3558 +#, c-format +msgid "rule is invalid: %s" +msgstr "правило є некоректним: %s" -#: ../libnm/nm-device-ethernet.c:223 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:3539 +msgid "invalid address family" +msgstr "некоректне сімейство адрес" + +#: ../src/libnm-core-impl/nm-setting-ip-config.c:4797 #, c-format -msgid "Invalid device MAC address %s." -msgstr "Некоректна MAC-адреса пристрою, %s." +msgid "rule #%u is invalid: %s" +msgstr "правило %u є некоректним: %s" -#: ../libnm/nm-device-ethernet.c:231 -msgid "The MACs of the device and the connection do not match." -msgstr "Адреси MAC пристрою і з'єднання не збігаються." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5145 +#, c-format +msgid "%d. DNS server address is invalid" +msgstr "%d. Адреса сервера DNS є некоректною." -#: ../libnm/nm-device-ethernet.c:243 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5164 #, c-format -msgid "Invalid MAC in the blacklist: %s." -msgstr "Некоректний запис MAC у «чорному» списку: %s." +msgid "%d. IP address is invalid" +msgstr "%d. IP-адреса є некоректною." -#: ../libnm/nm-device-ethernet.c:252 +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5179 #, c-format -msgid "Device MAC (%s) is blacklisted by the connection." -msgstr "MAC пристрою (%s) додано до «чорного» списку з'єднання." +msgid "%d. IP address has 'label' property with invalid type" +msgstr "%d. IP-адреса має властивість «label» некоректного типу" -#: ../libnm/nm-device-generic.c:80 -msgid "The connection was not a generic connection." -msgstr "З'єднання не є загальним з'єднанням." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5191 +#, c-format +msgid "%d. IP address has invalid label '%s'" +msgstr "%d. IP-адреса має некоректну мітку, «%s»" -#: ../libnm/nm-device-infiniband.c:90 -msgid "The connection was not an InfiniBand connection." -msgstr "З'єднання не є з'єднанням InfiniBand." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5209 +msgid "gateway cannot be set if there are no addresses configured" +msgstr "шлюз не може бути встановлено, якщо не налаштовано адрес" -#: ../libnm/nm-device-infiniband.c:100 ../libnm/nm-device-wifi.c:481 -msgid "Invalid device MAC address." -msgstr "Некоректна MAC-адреса пристрою." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5221 +msgid "gateway is invalid" +msgstr "шлюз є некоректним" -#: ../libnm/nm-device-infiniband.c:110 ../libnm/nm-device-wifi.c:490 -msgid "The MACs of the device and the connection didn't match." -msgstr "Адреси MAC пристрою і з'єднання не збігаються." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5239 +#, c-format +msgid "%d. route is invalid" +msgstr "%d. Некоректний маршрут" -#: ../libnm/nm-device-ip-tunnel.c:266 -msgid "The connection was not an IP tunnel connection." -msgstr "З'єднання не є тунельованим IP-з'єднанням." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5252 +#, c-format +msgid "invalid attribute: %s" +msgstr "некоректний атрибут: %s" -#: ../libnm/nm-device-macvlan.c:151 -msgid "The connection was not a MAC-VLAN connection." -msgstr "З'єднання не є з'єднанням MAC-VLAN." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5272 +#, c-format +msgid "%u. rule has wrong address-family" +msgstr "%u. у правилі вказано помилкове сімейство адрес" -#: ../libnm/nm-device-modem.c:177 -msgid "The connection was not a modem connection." -msgstr "З'єднання не є модемним з'єднанням." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5284 +#, c-format +msgid "%u. rule is invalid: %s" +msgstr "%u. правило є некоректним: %s" -#: ../libnm/nm-device-modem.c:187 -msgid "The connection was not a valid modem connection." -msgstr "З'єднання не є коректним модемним з'єднанням." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5300 +#, c-format +msgid "'%s' is not a valid IAID" +msgstr "«%s» не є коректним IAID" -#: ../libnm/nm-device-modem.c:196 -msgid "The device is lacking capabilities required by the connection." -msgstr "У пристрою немає можливостей, потрібних з'єднанню." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5314 +#, c-format +msgid "the property cannot be set when '%s' is disabled" +msgstr "властивість не можна встановлювати, якщо вимкнено «%s»" -#: ../libnm/nm-device-olpc-mesh.c:102 -msgid "The connection was not an OLPC Mesh connection." -msgstr "З'єднання не є з'єднанням OLPC Mesh." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5339 +msgid "the property is currently supported only for DHCPv4" +msgstr "у поточній версії підтримку властивості передбачено лише для DHCPv4" -#: ../libnm/nm-device-ovs-bridge.c:80 -msgid "The connection was not a ovs_bridge connection." -msgstr "З'єднання не було з'єднанням ovs_bridge." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5356 +#, c-format +msgid "'%s' is not a valid IP or subnet" +msgstr "«%s» є некоректною IP-адресою або підмережею" -#: ../libnm/nm-device-ovs-interface.c:48 -msgid "The connection was not a ovs_interface connection." -msgstr "З'єднання не було з'єднанням ovs_interface." +#: ../src/libnm-core-impl/nm-setting-ip-config.c:5372 +#, c-format +msgid "a gateway is incompatible with '%s'" +msgstr "шлюз є несумісним з «%s»" -#: ../libnm/nm-device-ovs-port.c:80 -msgid "The connection was not a ovs_port connection." -msgstr "З'єднання не є з'єднанням ovs_port." +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:330 +#, c-format +msgid "'%d' is not a valid tunnel mode" +msgstr "«%d» не є коректним режимом тунелювання" -#: ../libnm/nm-device-team.c:125 -msgid "The connection was not a team connection." -msgstr "З'єднання не є командним з'єднанням." +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:357 +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:383 +#, c-format +msgid "'%s' is not a valid IPv%c address" +msgstr "«%s» не є коректною адресою у форматі IPv%c" -#: ../libnm/nm-device-tun.c:204 -msgid "The connection was not a tun connection." -msgstr "З'єднання не належить до типу tun." +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:402 +msgid "tunnel keys can only be specified for GRE tunnels" +msgstr "ключі тунелювання можна задавати лише для тунелів GRE" -#: ../libnm/nm-device-tun.c:215 -msgid "The mode of the device and the connection didn't match" -msgstr "Режими роботи пристрою і з'єднання не збігаються" +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:415 +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:433 +#, c-format +msgid "'%s' is not a valid tunnel key" +msgstr "«%s» не є коректним ключем тунелю" -#: ../libnm/nm-device-vlan.c:121 -msgid "The connection was not a VLAN connection." -msgstr "З'єднання не є з'єднанням VLAN." +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:447 +msgid "a fixed TTL is allowed only when path MTU discovery is enabled" +msgstr "" +"фіксований TTL можна використовувати, лише якщо увімкнено виявлення MTU " +"шляхів" -#: ../libnm/nm-device-vlan.c:131 -msgid "The VLAN identifiers of the device and the connection didn't match." -msgstr "Ідентифікатори VLAN пристрою і з'єднання не збігаються." +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:462 +#, c-format +msgid "some flags are invalid for the select mode: %s" +msgstr "деякі з прапорців для режиму вибору є некоректними: %s" -#: ../libnm/nm-device-vlan.c:148 -msgid "The hardware address of the device and the connection didn't match." -msgstr "Апаратні адреси пристрою і з'єднання не збігаються." +#: ../src/libnm-core-impl/nm-setting-ip-tunnel.c:475 +#, c-format +msgid "wired setting not allowed for mode %s" +msgstr "встановлення параметрів дротового зв'язку для режиму %s неможливе" -#: ../libnm/nm-device-vrf.c:65 -msgid "The connection was not a VRF connection." -msgstr "З'єднання не є з'єднанням VRF." +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:132 +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:177 +#, c-format +msgid "this property cannot be empty for '%s=%s'" +msgstr "ця властивість не може бути порожньою, якщо «%s=%s»" -#: ../libnm/nm-device-vrf.c:74 -msgid "The VRF table of the device and the connection didn't match." -msgstr "Таблиці VRF пристрою і з'єднання не збігаються" +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:148 +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:162 +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:178 +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:197 +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:211 +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:225 +#, c-format +msgid "this property is not allowed for '%s=%s'" +msgstr "цю властивість не можна застосовувати до «%s=%s»" -#: ../libnm/nm-device-vxlan.c:383 -msgid "The connection was not a VXLAN connection." -msgstr "З'єднання не є з'єднанням VXLAN." +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:230 +#, c-format +msgid "'%s' is not a valid FQDN" +msgstr "«%s» не є коректною повною назвою вузла (FQDN)" -#: ../libnm/nm-device-vxlan.c:393 -msgid "The VXLAN identifiers of the device and the connection didn't match." -msgstr "Ідентифікатори VXLAN пристрою і з'єднання не збігаються." +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:243 +msgid "property cannot be set when dhcp-hostname is also set" +msgstr "властивість не можна задавати, якщо встановлено dhcp-hostname" -#: ../libnm/nm-device-wifi-p2p.c:266 -msgid "The connection was not a Wi-Fi P2P connection." -msgstr "З'єднання не є з'єднанням P2P Wi-Fi." +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:258 +msgid "FQDN flags requires a FQDN set" +msgstr "для прапорців FQDN потрібен набір FQDN" -#: ../libnm/nm-device-wifi.c:470 -msgid "The connection was not a Wi-Fi connection." -msgstr "З'єднання не є з'єднанням Wi-Fi." +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:277 +#, c-format +msgid "multiple addresses are not allowed for '%s=%s'" +msgstr "не можна вказувати декілька адрес у «%s=%s»" + +#: ../src/libnm-core-impl/nm-setting-ip4-config.c:294 +msgid "property should be TRUE when method is set to disabled" +msgstr "" +"властивість повинна мати значення TRUE, якщо встановлено метод «disabled»" + +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:275 +msgid "value is not a valid token" +msgstr "значення не є коректним жетоном" -#: ../libnm/nm-device-wifi.c:511 -msgid "The device is lacking WPA capabilities required by the connection." -msgstr "У пристрою немає можливостей WPA, потрібних з'єднанню." +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:289 +msgid "only makes sense with EUI64 address generation mode" +msgstr "має сенс лише з режимом створення адрес EUI64" -#: ../libnm/nm-device-wifi.c:521 -msgid "The device is lacking WPA2/RSN capabilities required by the connection." -msgstr "У пристрою немає можливостей WPA2/RSN, потрібних з'єднанню." +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:303 +msgid "invalid DUID" +msgstr "некоректний DUID" -#: ../libnm/nm-device-wpan.c:57 -msgid "The connection was not a wpan connection." -msgstr "З'єднання не належить до типу wpan." +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:318 +msgid "token is not in canonical form" +msgstr "жетон вказано не у канонічній формі" -#: ../libnm/nm-device.c:1659 -msgid "Bluetooth" -msgstr "Bluetooth" +#: ../src/libnm-core-impl/nm-setting-ip6-config.c:335 +msgid "property should be TRUE when method is set to ignore or disabled" +msgstr "" +"властивість повинна мати значення TRUE, якщо встановлено метод «ignore» або " +"«disabled»" -#: ../libnm/nm-device.c:1661 -msgid "OLPC Mesh" -msgstr "Сітка OLPC" +#: ../src/libnm-core-impl/nm-setting-macsec.c:230 +msgid "the key is empty" +msgstr "ключ є порожнім" -#: ../libnm/nm-device.c:1663 -msgid "Open vSwitch Interface" -msgstr "Інтерфейс Open vSwitch" +#: ../src/libnm-core-impl/nm-setting-macsec.c:239 +#, c-format +msgid "the key must be %d characters" +msgstr "ключ має складатися з %d символів" -#: ../libnm/nm-device.c:1665 -msgid "Open vSwitch Port" -msgstr "Порт Open vSwitch" +#: ../src/libnm-core-impl/nm-setting-macsec.c:248 +msgid "the key contains non-hexadecimal characters" +msgstr "ключ містить нешістнадцяткові цифри" -#: ../libnm/nm-device.c:1667 -msgid "Open vSwitch Bridge" -msgstr "Місток Open vSwitch" +#: ../src/libnm-core-impl/nm-setting-macsec.c:317 +#: ../src/libnm-core-impl/nm-setting-macvlan.c:138 +#: ../src/libnm-core-impl/nm-setting-vlan.c:621 +#, c-format +msgid "property is not specified and neither is '%s:%s'" +msgstr "властивість не вказано і не визначено «%s:%s»" -#: ../libnm/nm-device.c:1669 -msgid "WiMAX" -msgstr "WiMAX" +#: ../src/libnm-core-impl/nm-setting-macsec.c:348 +#, c-format +msgid "EAP key management requires '%s' setting presence" +msgstr "Керування ключами за допомогою EAP потребує додавання параметра «%s»" -#: ../libnm/nm-device.c:1683 -msgid "ADSL" -msgstr "ADSL" +#: ../src/libnm-core-impl/nm-setting-macsec.c:357 +msgid "must be either psk (0) or eap (1)" +msgstr "має бути або psk (0), або eap (1)" -#: ../libnm/nm-device.c:1685 -msgid "MACVLAN" -msgstr "MACVLAN" +#: ../src/libnm-core-impl/nm-setting-macsec.c:366 +#, c-format +msgid "invalid port %d" +msgstr "некоректний порт %d" -#: ../libnm/nm-device.c:1687 -msgid "VXLAN" -msgstr "VXLAN" +#: ../src/libnm-core-impl/nm-setting-macsec.c:376 +msgid "only valid for psk mode" +msgstr "можна використовувати лише у режимі psk" -#: ../libnm/nm-device.c:1689 -msgid "IPTunnel" -msgstr "IPTunnel" +#: ../src/libnm-core-impl/nm-setting-macvlan.c:153 +msgid "non promiscuous operation is allowed only in passthru mode" +msgstr "розбірливі дії можливі лише у режимі передавання (passthru)" -#: ../libnm/nm-device.c:1691 -msgid "Tun" -msgstr "TUN" +#: ../src/libnm-core-impl/nm-setting-match.c:701 +#: ../src/libnm-core-impl/nm-setting-match.c:717 +#: ../src/libnm-core-impl/nm-setting-match.c:733 +#: ../src/libnm-core-impl/nm-setting-match.c:749 +#, c-format +msgid "is empty" +msgstr "є порожнім" -#: ../libnm/nm-device.c:1695 -msgid "MACsec" -msgstr "MACsec" +#: ../src/libnm-core-impl/nm-setting-olpc-mesh.c:96 +#: ../src/libnm-core-impl/nm-setting-wireless.c:801 +msgid "SSID length is out of range <1-32> bytes" +msgstr "Довжина SSID лежить поза діапазоном у <1-32> байтів" -#: ../libnm/nm-device.c:1697 -msgid "Dummy" -msgstr "Фіктивний" +#: ../src/libnm-core-impl/nm-setting-olpc-mesh.c:108 +#: ../src/libnm-core-impl/nm-setting-wireless.c:854 +#, c-format +msgid "'%d' is not a valid channel" +msgstr "«%d» не є коректним каналом" -#: ../libnm/nm-device.c:1699 -msgid "PPP" -msgstr "PPP" +#: ../src/libnm-core-impl/nm-setting-ovs-bridge.c:160 +#, c-format +msgid "A connection with a '%s' setting must not have a master." +msgstr "З'єднання з параметром «%s» не повинне мати основне." -#: ../libnm/nm-device.c:1701 -msgid "IEEE 802.15.4" -msgstr "IEEE 802.15.4" +#: ../src/libnm-core-impl/nm-setting-ovs-bridge.c:174 +#, c-format +msgid "'%s' is not allowed in fail_mode" +msgstr "«%s» не можна використовувати у режимі fail_mode" -#: ../libnm/nm-device.c:1703 -msgid "6LoWPAN" -msgstr "6LoWPAN" +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:90 +#: ../src/libnm-core-impl/nm-setting-user.c:91 +msgid "missing key" +msgstr "не вказано ключ" -#: ../libnm/nm-device.c:1705 -msgid "WireGuard" -msgstr "WireGuard" +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:98 +#: ../src/libnm-core-impl/nm-setting-user.c:99 +msgid "key is too long" +msgstr "ключ є надто довгим" -#: ../libnm/nm-device.c:1707 -msgid "Wi-Fi P2P" -msgstr "P2P Wi-Fi" +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:105 +#: ../src/libnm-core-impl/nm-setting-user.c:106 +msgid "key must be UTF8" +msgstr "ключ має зберігатися у кодуванні UTF8" -#: ../libnm/nm-device.c:1709 -msgid "VRF" -msgstr "VRF" +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:114 +#: ../src/libnm-core-impl/nm-setting-user.c:153 +msgid "key contains invalid characters" +msgstr "ключ містить некоректний символ" -#: ../libnm/nm-device.c:1741 -msgid "Wired" -msgstr "Дротове" +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:123 +msgid "key cannot start with \"NM.\"" +msgstr "запис ключа не починається з «NM.»" -#: ../libnm/nm-device.c:1773 -msgid "PCI" -msgstr "PCI" +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:153 +#: ../src/libnm-core-impl/nm-setting-user.c:180 +msgid "value is missing" +msgstr "не вказано значення" -#: ../libnm/nm-device.c:1775 -msgid "USB" -msgstr "USB" +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:162 +#: ../src/libnm-core-impl/nm-setting-user.c:189 +msgid "value is too large" +msgstr "значення є надто великим" -#. TRANSLATORS: the first %s is a bus name (eg, "USB") or -#. * product name, the second is a device type (eg, -#. * "Ethernet"). You can change this to something like -#. * "%2$s (%1$s)" if there's no grammatical way to combine -#. * the strings otherwise. -#. -#: ../libnm/nm-device.c:2074 ../libnm/nm-device.c:2093 -#, c-format -msgctxt "long device name" -msgid "%s %s" -msgstr "%s %s" +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:170 +#: ../src/libnm-core-impl/nm-setting-user.c:197 +msgid "value is not valid UTF8" +msgstr "значення не записано у коректному кодуванні UTF8" -#: ../libnm/nm-device.c:2753 +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:313 +#: ../src/libnm-core-impl/nm-setting-user.c:365 #, c-format -msgid "The connection was not valid: %s" -msgstr "З'єднання не є коректним: %s" +msgid "invalid key \"%s\": %s" +msgstr "некоректний ключ «%s»: %s" -#: ../libnm/nm-device.c:2765 +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:337 +#: ../src/libnm-core-impl/nm-setting-user.c:389 #, c-format -msgid "The interface names of the device and the connection didn't match." -msgstr "Назви інтерфейсу пристрою і з'єднання не збігаються." +msgid "maximum number of user data entries reached (%u instead of %u)" +msgstr "" +"досягнуто максимальної кількості записів даних користувача (%u замість %u)" -#: ../libnm/nm-secret-agent-old.c:1384 -msgid "registration failed" -msgstr "не вдалося пройти реєстрацію" +#: ../src/libnm-core-impl/nm-setting-ovs-external-ids.c:380 +msgid "" +"OVS external IDs can only be added to a profile of type OVS bridge/port/" +"interface or to OVS system interface" +msgstr "" +"Зовнішні ідентифікатори OVS можна додавати лише до профілів типу місток, " +"порт або інтерфейс OVS або до загальносистемного інтерфейсу OVS" -#: ../libnm/nm-vpn-plugin-old.c:819 ../libnm/nm-vpn-service-plugin.c:1014 -msgid "No service name specified" -msgstr "Не вказано назви служби" +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:93 +#, c-format +msgid "'%s' is not a valid interface type" +msgstr "«%s» не є коректним типом інтерфейсу" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:1 -msgid "Enable or disable system networking" -msgstr "Увімкнути або вимкнути системну роботу у мережі" +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:120 +#, c-format +msgid "A connection with a '%s' setting needs connection.type explicitly set" +msgstr "Для з'єднання з параметром «%s» слід явно вказати connection.type" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:2 -msgid "System policy prevents enabling or disabling system networking" +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:134 +#, c-format +msgid "A connection of type '%s' cannot have ovs-interface.type \"system\"" msgstr "" -"Правила системи забороняють вмикання або вимикання з'єднань з мережею на " -"системному рівні" +"З'єднання типу «%s» не може мати значення «system» для параметра ovs-" +"interface.type" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:3 -msgid "Reload NetworkManager configuration" -msgstr "Перезавантажити налаштування NetworkManager" +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:148 +#, c-format +msgid "A connection of type '%s' cannot have an ovs-interface.type \"%s\"" +msgstr "" +"З'єднання типу «%s» не може мати значення «%s» для параметра ovs-interface." +"type" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:4 -msgid "System policy prevents reloading NetworkManager" -msgstr "Правила системи запобігають перезавантаженню NetworkManager" +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:170 +#, c-format +msgid "A connection can not have both '%s' and '%s' settings at the same time" +msgstr "Для з'єднання не може бути одночасно встановлено «%s» і «%s»" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:5 +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:184 +#, c-format msgid "" -"Put NetworkManager to sleep or wake it up (should only be used by system " -"power management)" +"A connection with '%s' setting must be of connection.type \"ovs-interface\" " +"but is \"%s\"" msgstr "" -"Призупинити або поновити роботу NetworkManager (має використовуватися лише " -"інструментами керування живленням системи)" +"З'єднання з параметром «%s» має належати до типу «ovs-interface»; втім, воно " +"належить до типу «%s»" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:6 -msgid "System policy prevents putting NetworkManager to sleep or waking it up" +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:200 +#, c-format +msgid "" +"A connection with '%s' setting needs to be of '%s' interface type, not '%s'" msgstr "" -"Правила системи забороняють присипляння та поновлення роботи NetworkManager" - -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:7 -msgid "Enable or disable Wi-Fi devices" -msgstr "Увімкнути або вимкнути пристрої Wi-Fi" +"З'єднання з параметром «%s» повинне мати тип інтерфейсу «%s», а не «%s»" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:8 -msgid "System policy prevents enabling or disabling Wi-Fi devices" -msgstr "Правила системи забороняють вмикання або вимикання пристроїв Wi-Fi" +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:222 +#, c-format +msgid "A connection with ovs-interface.type '%s' setting a 'ovs-patch' setting" +msgstr "" +"З'єднання з типом «%s» ovs-interface.type встановлює параметр «ovs-patch»" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:9 -msgid "Enable or disable mobile broadband devices" -msgstr "Увімкнути або вимкнути пристрої широкосмугових мобільних мереж" +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:250 +#, c-format +msgid "Missing ovs interface setting" +msgstr "Пропущено параметр інтерфейсу ovs" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:10 -msgid "System policy prevents enabling or disabling mobile broadband devices" -msgstr "" -"Правила системи забороняють вмикання або вимикання пристроїв широкосмугових " -"мобільних мереж" +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:256 +#, c-format +msgid "Missing ovs interface type" +msgstr "Не вказано тип інтерфейсу ovs" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:11 -msgid "Enable or disable WiMAX mobile broadband devices" -msgstr "Увімкнути або вимкнути пристрої широкосмугових мобільних мереж WiMAX" +#: ../src/libnm-core-impl/nm-setting-ovs-interface.c:298 +#: ../src/libnm-core-impl/nm-setting-ovs-port.c:179 +#, c-format +msgid "A connection with a '%s' setting must have a master." +msgstr "З'єднання з параметром «%s» повинне мати основне." -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:12 -msgid "" -"System policy prevents enabling or disabling WiMAX mobile broadband devices" +#: ../src/libnm-core-impl/nm-setting-ovs-port.c:215 +#, c-format +msgid "'%s' is not allowed in vlan_mode" +msgstr "«%s» не можна використовувати у режимі vlan_mode" + +#: ../src/libnm-core-impl/nm-setting-ovs-port.c:228 +#, c-format +msgid "the tag id must be in range 0-4094 but is %u" msgstr "" -"Правила системи забороняють вмикання або вимикання пристроїв широкосмугових " -"мобільних мереж WiMAX" +"ідентифікатором tag має бути число у діапазоні від 0 до 4094, втім, маємо %u" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:13 -msgid "Allow control of network connections" -msgstr "Дозволити керування з'єднаннями мережею" +#: ../src/libnm-core-impl/nm-setting-ovs-port.c:238 +#, c-format +msgid "'%s' is not allowed in lacp" +msgstr "«%s» не можна використовувати у lacp" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:14 -msgid "System policy prevents control of network connections" -msgstr "Правила системи забороняють керування з'єднаннями" +#: ../src/libnm-core-impl/nm-setting-ovs-port.c:251 +#, c-format +msgid "'%s' is not allowed in bond_mode" +msgstr "«%s» не можна використовувати у режимі bond_mode" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:15 -msgid "Allow control of Wi-Fi scans" -msgstr "Дозволити керування скануваннями Wi-Fi" +#: ../src/libnm-core-impl/nm-setting-ppp.c:335 +#, c-format +msgid "'%d' is out of valid range <128-16384>" +msgstr "«%d» не належить до коректного діапазону <128-16384>" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:16 -msgid "System policy prevents Wi-Fi scans" -msgstr "Правила системи забороняють сканування Wi-Fi" +#: ../src/libnm-core-impl/nm-setting-ppp.c:348 +#, c-format +msgid "setting this property requires non-zero '%s' property" +msgstr "" +"встановлення цієї властивості вимагає ненульового значення властивості «%s»" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:17 -msgid "Connection sharing via a protected Wi-Fi network" -msgstr "Спільне використання з'єднання на основі захищеної мережі Wi-Fi" +#: ../src/libnm-core-impl/nm-setting-proxy.c:123 +#, c-format +msgid "invalid proxy method" +msgstr "некоректний метод проксіювання" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:18 -msgid "" -"System policy prevents sharing connections via a protected Wi-Fi network" -msgstr "" -"Правила системи забороняють спільне використання з'єднань за допомогою " -"захищеної мережі Wi-Fi" +#: ../src/libnm-core-impl/nm-setting-proxy.c:133 +#: ../src/libnm-core-impl/nm-setting-proxy.c:145 +#, c-format +msgid "this property is not allowed for method none" +msgstr "цю властивість не можна використовувати для методу none" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:19 -msgid "Connection sharing via an open Wi-Fi network" -msgstr "Спільне використання з'єднання на основі відкритої мережі Wi-Fi" +#: ../src/libnm-core-impl/nm-setting-proxy.c:159 +#, c-format +msgid "the script is too large" +msgstr "скрипт є надто великим" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:20 -msgid "System policy prevents sharing connections via an open Wi-Fi network" -msgstr "" -"Правила системи забороняють спільне використання з'єднань за допомогою " -"відкритої мережі Wi-Fi" +#: ../src/libnm-core-impl/nm-setting-proxy.c:170 +#, c-format +msgid "the script is not valid utf8" +msgstr "скрипт не є коректним текстом у кодуванні utf8" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:21 -msgid "Modify personal network connections" -msgstr "Змінити параметри особистих з'єднань з мережею" +#: ../src/libnm-core-impl/nm-setting-proxy.c:181 +#, c-format +msgid "the script lacks FindProxyForURL function" +msgstr "скрипт не містить функції FindProxyForURL" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:22 -msgid "System policy prevents modification of personal network settings" -msgstr "" -"Правила системи забороняють внесення змін до особистих параметрів мережі" +#: ../src/libnm-core-impl/nm-setting-sriov.c:1054 +#, c-format +msgid "VF with index %u, but the total number of VFs is %u" +msgstr "маємо VF з індексом %u, але загальна кількість VF дорівнює %u" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:23 -msgid "Modify network connections for all users" -msgstr "Внести зміни до мережевих з'єднань всіх користувачів" +#: ../src/libnm-core-impl/nm-setting-sriov.c:1068 +#, c-format +msgid "invalid VF %u: %s" +msgstr "некоректна VF %u: %s" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:24 -msgid "System policy prevents modification of network settings for all users" -msgstr "" -"Правила системи забороняють внесення змін до параметрів мережі для всіх " -"користувачів" +#: ../src/libnm-core-impl/nm-setting-sriov.c:1082 +#, c-format +msgid "duplicate VF index %u" +msgstr "дублювання індексу VF %u" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:25 -msgid "Modify persistent system hostname" -msgstr "Змінити постійну назву вузла у мережі" +#: ../src/libnm-core-impl/nm-setting-sriov.c:1106 +#, c-format +msgid "VFs %d and %d are not sorted by ascending index" +msgstr "VF %d і %d не упорядковано за зростанням" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:26 -msgid "System policy prevents modification of the persistent system hostname" -msgstr "" -"Правила системи забороняють внесення змін до постійної назви вузла у мережі" +#: ../src/libnm-core-impl/nm-setting-tc-config.c:54 +#: ../src/libnm-core-impl/nm-setting-tc-config.c:420 +#: ../src/libnm-core-impl/nm-setting-tc-config.c:697 +#, c-format +msgid "kind is missing" +msgstr "пропущено тип" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:27 -msgid "Modify persistent global DNS configuration" -msgstr "Змінити постійні загальні налаштування DNS" +#: ../src/libnm-core-impl/nm-setting-tc-config.c:62 +#: ../src/libnm-core-impl/nm-setting-tc-config.c:428 +#: ../src/libnm-core-impl/nm-setting-tc-config.c:705 +#, c-format +msgid "'%s' is not a valid kind" +msgstr "«%s» не є коректним типом" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:28 -msgid "" -"System policy prevents modification of the persistent global DNS " -"configuration" -msgstr "" -"Правила системи забороняють внесення змін до постійних загальних налаштувань " -"DNS" +#: ../src/libnm-core-impl/nm-setting-tc-config.c:71 +#: ../src/libnm-core-impl/nm-setting-tc-config.c:714 +msgid "parent handle missing" +msgstr "не вказано батьківського дескриптора" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:29 -msgid "Perform a checkpoint or rollback of interfaces configuration" -msgstr "Виконати перевірку або повернення до попередніх налаштувань інтерфейсу" +#: ../src/libnm-core-impl/nm-setting-tc-config.c:1284 +msgid "there are duplicate TC qdiscs" +msgstr "маємо дублювання q-дисків TC" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:30 -msgid "System policy prevents the creation of a checkpoint or its rollback" -msgstr "" -"Правила системи забороняють створення точки перевірки або повернення до " -"стану такої точки" +#: ../src/libnm-core-impl/nm-setting-tc-config.c:1303 +msgid "there are duplicate TC filters" +msgstr "маємо дублювання фільтрів TC" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:31 -msgid "Enable or disable device statistics" -msgstr "Увімкнути або вимкнути обчислення статистичних даних пристрою" +#: ../src/libnm-core-impl/nm-setting-team.c:119 +#: ../src/libnm-core-impl/nm-setting-team.c:193 +#: ../src/libnm-core-impl/nm-setting-team.c:325 +#, c-format +msgid "%s is out of range [0, %d]" +msgstr "%s не належить до діапазону [0, %d]" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:32 -msgid "System policy prevents enabling or disabling device statistics" +#: ../src/libnm-core-impl/nm-setting-team.c:170 +#, c-format +msgid "Missing target-host in nsna_ping link watcher" msgstr "" -"Правила системи забороняють вмикання або вимикання збирання статистичних " -"даних пристрою" +"Пропущено вузол призначення у налаштуваннях засобу спостереження за зв'язком " +"nsna_ping" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:33 -msgid "Enable or disable connectivity checking" -msgstr "Увімкнути або вимкнути перевірку придатності до з'єднання" +#: ../src/libnm-core-impl/nm-setting-team.c:178 +#: ../src/libnm-core-impl/nm-setting-team.c:301 +#, c-format +msgid "target-host '%s' contains invalid characters" +msgstr "назва вузла призначення, «%s», містить некоректні символи" -#: ../data/org.freedesktop.NetworkManager.policy.in.in.h:34 -msgid "System policy prevents enabling or disabling connectivity checking" +#: ../src/libnm-core-impl/nm-setting-team.c:292 +#, c-format +msgid "Missing %s in arp_ping link watcher" msgstr "" -"Правила системи забороняють вмикання або вимикання перевірки придатності до " -"з'єднання" +"Не вказано %s у налаштуваннях засобу спостереження за зв'язком arp_ping" -#: ../shared/nm-glib-aux/nm-shared-utils.c:2352 +#: ../src/libnm-core-impl/nm-setting-team.c:310 #, c-format -msgid "object class '%s' has no property named '%s'" -msgstr "у класі об'єктів «%s» немає властивості із назвою «%s»" +msgid "source-host '%s' contains invalid characters" +msgstr "назва вузла джерела, «%s», містить некоректні символи" -#: ../shared/nm-glib-aux/nm-shared-utils.c:2361 +#: ../src/libnm-core-impl/nm-setting-team.c:335 +msgid "vlanid is out of range [-1, 4094]" +msgstr "vlanid не належить до діапазону [-1, 4094]" + +#: ../src/libnm-core-impl/nm-setting-tun.c:149 #, c-format -msgid "property '%s' of object class '%s' is not writable" -msgstr "властивість «%s» класу об'єктів «%s» є непридатною до запису" +msgid "'%u': invalid mode" +msgstr "«%u»: некоректний режим" -#: ../shared/nm-glib-aux/nm-shared-utils.c:2370 +#: ../src/libnm-core-impl/nm-setting-tun.c:160 #, c-format -msgid "" -"construct property \"%s\" for object '%s' can't be set after construction" -msgstr "" -"властивість construct «%s» об'єкта «%s» не можна встановлювати після побудови" +msgid "'%s': invalid user ID" +msgstr "«%s»: некоректний ідентифікатор користувача" -#: ../shared/nm-glib-aux/nm-shared-utils.c:2381 +#: ../src/libnm-core-impl/nm-setting-tun.c:172 #, c-format -msgid "'%s::%s' is not a valid property name; '%s' is not a GObject subtype" -msgstr "«%s::%s» не є коректною назвою властивості; «%s» не є підтипом GObject" +msgid "'%s': invalid group ID" +msgstr "«%s»: некоректний ідентифікатор групи" -#: ../shared/nm-glib-aux/nm-shared-utils.c:2394 +#: ../src/libnm-core-impl/nm-setting-user.c:131 +msgid "key requires a '.' for a namespace" +msgstr "для визначення простору назв у ключі має бути «.»" + +#: ../src/libnm-core-impl/nm-setting-user.c:146 +msgid "key cannot contain \"..\"" +msgstr "у записі ключа не може міститися «..»" + +#: ../src/libnm-core-impl/nm-setting-user.c:322 +msgid "maximum number of user data entries reached" +msgstr "досягнуто максимальної кількості записів даних користувача" + +#: ../src/libnm-core-impl/nm-setting-veth.c:89 #, c-format -msgid "unable to set property '%s' of type '%s' from value of type '%s'" -msgstr "" -"не вдалося встановити значення властивості «%s» типу «%s» на основі значення " -"типу «%s»" +msgid "'%s' is not a valid interface name" +msgstr "«%s» не є коректною назвою інтерфейсу" -#: ../shared/nm-glib-aux/nm-shared-utils.c:2406 +#: ../src/libnm-core-impl/nm-setting-vlan.c:633 #, c-format -msgid "" -"value \"%s\" of type '%s' is invalid or out of range for property '%s' of " -"type '%s'" +msgid "the vlan id must be in range 0-4094 but is %u" msgstr "" -"значення «%s» типу «%s» є некоректним для властивості «%s» типу «%s» або не " -"належить до припустимого діапазону значень" +"ідентифікатором vlan має бути число у діапазоні від 0 до 4094, втім, маємо %u" -#: ../shared/nm-glib-aux/nm-shared-utils.c:5204 -msgid "interface name is missing" -msgstr "пропущено назву інтерфейсу" +#: ../src/libnm-core-impl/nm-setting-vlan.c:643 +msgid "flags are invalid" +msgstr "прапорці є некоректними" -#: ../shared/nm-glib-aux/nm-shared-utils.c:5212 -msgid "interface name is too short" -msgstr "назва інтерфейсу є надто короткою" +#: ../src/libnm-core-impl/nm-setting-vlan.c:655 +msgid "vlan setting should have a ethernet setting as well" +msgstr "параметр vlan має супроводжуватися параметром ethernet" -#: ../shared/nm-glib-aux/nm-shared-utils.c:5220 -msgid "interface name is reserved" -msgstr "таку назву інтерфейсу зарезервовано" +#: ../src/libnm-core-impl/nm-setting-vpn.c:560 +msgid "cannot set connection.multi-connect for VPN setting" +msgstr "не можна встановлювати connection.multi-connect для VPN" -#: ../shared/nm-glib-aux/nm-shared-utils.c:5233 -msgid "interface name contains an invalid character" -msgstr "назва інтерфейсу містить некоректний символ" +#: ../src/libnm-core-impl/nm-setting-vpn.c:599 +msgid "setting contained a secret with an empty name" +msgstr "параметри містив пароль з порожньою назвою" -#: ../shared/nm-glib-aux/nm-shared-utils.c:5241 -msgid "interface name is longer than 15 characters" -msgstr "назва інтерфейсу є довшою за 15 символів" +#: ../src/libnm-core-impl/nm-setting-vpn.c:638 +#: ../src/libnm-core-impl/nm-setting.c:2126 +msgid "not a secret property" +msgstr "не є властивістю пароля" -#: ../shared/nm-glib-aux/nm-shared-utils.c:5266 -#, c-format -msgid "'%%' is not allowed in interface names" -msgstr "«%%» не можна використовувати у назвах інтерфейсів" +#: ../src/libnm-core-impl/nm-setting-vpn.c:646 +msgid "secret is not of correct type" +msgstr "пароль не належить до коректного типу" -#: ../shared/nm-glib-aux/nm-shared-utils.c:5278 +#: ../src/libnm-core-impl/nm-setting-vpn.c:728 +#: ../src/libnm-core-impl/nm-setting-vpn.c:778 #, c-format -msgid "'%s' is not allowed as interface name" -msgstr "«%s» не можна використовувати як назву інтерфейсу" - -#: ../shared/nm-glib-aux/nm-shared-utils.c:5300 -msgid "" -"interface name must be alphanumerical with no forward or backward slashes" -msgstr "" -"назва інтерфейсу має складатися з літер і цифр без початкового і " -"завершального символів похилої риски" +msgid "secret name cannot be empty" +msgstr "назва реєстраційного запису не може бути порожньою" -#: ../shared/nm-glib-aux/nm-shared-utils.c:5317 -msgid "interface name must not be empty" -msgstr "назва інтерфейсу не може бути порожньою" +#: ../src/libnm-core-impl/nm-setting-vpn.c:744 +msgid "secret flags property not found" +msgstr "властивість прапорців паролів не знайдено" -#: ../shared/nm-glib-aux/nm-shared-utils.c:5325 -msgid "interface name must be UTF-8 encoded" -msgstr "назва інтерфейсу має бути набором символів у кодуванні UTF-8" +#: ../src/libnm-core-impl/nm-setting-vrf.c:73 +msgid "table cannot be zero" +msgstr "таблиця не може бути нульовою" -#: ../shared/nm-log-core/nm-logging.c:251 +#: ../src/libnm-core-impl/nm-setting-vxlan.c:329 +#: ../src/libnm-core-impl/nm-setting-vxlan.c:340 #, c-format -msgid "Unknown log level '%s'" -msgstr "Невідомий рівень ведення журналу, «%s»" +msgid "'%s' is not a valid IP%s address" +msgstr "«%s» є некоректною IP-адресою у форматі IP%s" -#: ../shared/nm-log-core/nm-logging.c:359 +#: ../src/libnm-core-impl/nm-setting-vxlan.c:363 #, c-format -msgid "Unknown log domain '%s'" -msgstr "Невідомий домен ведення журналу, «%s»" +msgid "%d is greater than local port max %d" +msgstr "%d перевищує максимальний припустимий номер локального порту, %d" -#. TRANSLATORS: the first %s is a prefix for the connection id, such -#. * as "Wired Connection" or "VPN Connection". The %d is a number -#. * that is combined with the first argument to create a unique -#. * connection id. -#: ../src/core/NetworkManagerUtils.c:109 +#: ../src/libnm-core-impl/nm-setting-wired.c:733 #, c-format -msgctxt "connection id fallback" -msgid "%s %u" -msgstr "%s %u" +msgid "'%s' is not a valid Ethernet port value" +msgstr "«%s» не є коректним значенням номера порту Ethernet" -#: ../src/core/main.c:163 ../src/core/main.c:384 +#: ../src/libnm-core-impl/nm-setting-wired.c:743 #, c-format -msgid "Failed to read configuration: %s\n" -msgstr "Не вдалося прочитати налаштування: %s\n" +msgid "'%s' is not a valid duplex value" +msgstr "«%s» не є коректним значенням дуплексного режиму" -#: ../src/core/main.c:190 ../src/core/nm-iface-helper.c:406 -msgid "Print NetworkManager version and exit" -msgstr "Вивести дані щодо версії NetworkManager і завершити роботу" +#: ../src/libnm-core-impl/nm-setting-wired.c:817 +#, c-format +msgid "invalid '%s' or its value '%s'" +msgstr "некоректний «%s» або його значення «%s»" -#: ../src/core/main.c:197 ../src/core/nm-iface-helper.c:413 -msgid "Don't become a daemon" -msgstr "Не переходити у стан фонової служби" +#: ../src/libnm-core-impl/nm-setting-wired.c:867 +msgid "Wake-on-LAN mode 'default' and 'ignore' are exclusive flags" +msgstr "" +"Прапорці режиму Wake-on-LAN «default» і «ignore» не можна використовувати " +"одночасно" -#: ../src/core/main.c:204 ../src/core/nm-iface-helper.c:427 -#, c-format -msgid "Log level: one of [%s]" -msgstr "Рівень докладності журналу: одне з таких значень: [%s]" +#: ../src/libnm-core-impl/nm-setting-wired.c:879 +msgid "Wake-on-LAN password can only be used with magic packet mode" +msgstr "" +"Пароль до Wake-on-LAN можна використовувати лише у режимі магічних пакетів" -#: ../src/core/main.c:211 ../src/core/nm-iface-helper.c:434 -#, c-format -msgid "Log domains separated by ',': any combination of [%s]" +#: ../src/libnm-core-impl/nm-setting-wired.c:910 +msgid "both speed and duplex should have a valid value or both should be unset" msgstr "" -"Список доменів для ведення журналу, відокремлених символом «,»: будь-яка " -"комбінація з [%s]" +"параметри швидкості і двобічного режиму повинні обидва мати коректні " +"значення або обидва параметри має бути не встановлено" -#: ../src/core/main.c:218 ../src/core/nm-iface-helper.c:441 -msgid "Make all warnings fatal" -msgstr "Вважати всі попередження помилками" +#: ../src/libnm-core-impl/nm-setting-wired.c:911 +msgid "both speed and duplex are required for static link configuration" +msgstr "для статичного налаштування зв'язку слід вказати speed і duplex" -#: ../src/core/main.c:225 -msgid "Specify the location of a PID file" -msgstr "Вказати розташування файла ідентифікатора процесу (PID)" +#: ../src/libnm-core-impl/nm-setting-wireguard.c:745 +msgid "missing public-key for peer" +msgstr "пропущено відкритий ключ для вузла" -#: ../src/core/main.c:239 -msgid "Print NetworkManager configuration and exit" -msgstr "Вивести дані щодо налаштувань NetworkManager і завершити роботу" +#: ../src/libnm-core-impl/nm-setting-wireguard.c:751 +msgid "invalid public-key for peer" +msgstr "некоректний відкритий ключ для вузла" -#: ../src/core/main.c:250 -msgid "" -"NetworkManager monitors all network connections and automatically\n" -"chooses the best connection to use. It also allows the user to\n" -"specify wireless access points which wireless cards in the computer\n" -"should associate with." -msgstr "" -"NetworkManager виконує стеження за всіма з'єднаннями і автоматично\n" -"вибирає з них найкраще для використання. Крім того, програма\n" -"надає користувачеві змогу вказати точки бездротового доступу,\n" -"з якими слід пов'язувати картки бездротового доступу на вашому\n" -"комп'ютері." +#: ../src/libnm-core-impl/nm-setting-wireguard.c:761 +msgid "invalid preshared-key for peer" +msgstr "некоректне значення preshared-key для вузла" -#: ../src/core/main.c:374 ../src/core/main-utils.c:284 -#: ../src/core/nm-iface-helper.c:585 +#: ../src/libnm-core-impl/nm-setting-wireguard.c:780 +msgid "invalid endpoint for peer" +msgstr "некоректна кінцева точка для вузла" + +#: ../src/libnm-core-impl/nm-setting-wireguard.c:792 #, c-format -msgid "%s. Please use --help to see a list of valid options.\n" -msgstr "" -"%s. Щоб ознайомитися зі списком параметрів, скористайтеся параметром --" -"help.\n" +msgid "invalid IP address \"%s\" for allowed-ip of peer" +msgstr "некоректна IP-адреса «%s» для allowed-ip вузла" -#: ../src/core/main.c:407 ../src/core/nm-iface-helper.c:599 +#: ../src/libnm-core-impl/nm-setting-wireguard.c:803 +msgid "invalid preshared-key-flags for peer" +msgstr "некоректне значення preshared-key-flags для вузла" + +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1585 #, c-format -msgid "Could not daemonize: %s [error %u]\n" -msgstr "Не вдалося створити фонову службу: %s [помилка %u]\n" +msgid "peer #%u has no public-key" +msgstr "для вузла %u не вказано відкритого ключа" -#: ../src/core/main-utils.c:87 +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1598 #, c-format -msgid "Opening %s failed: %s\n" -msgstr "Помилка під час спроби відкрити %s: %s\n" +msgid "peer #%u has invalid public-key" +msgstr "вузол %u має некоректний відкритий ключ" -#: ../src/core/main-utils.c:94 +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1614 #, c-format -msgid "Writing to %s failed: %s\n" -msgstr "Помилка під час спроби запису даних до %s: %s\n" +msgid "peer #%u has invalid endpoint" +msgstr "вузол %u має некоректну кінцеву точку" -#: ../src/core/main-utils.c:100 +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1646 #, c-format -msgid "Closing %s failed: %s\n" -msgstr "Не вдалося завершити роботу %s: %s\n" +msgid "peer #%u has invalid allowed-ips setting" +msgstr "для вузла %u визначено некоректний параметр allowed-ips" -#: ../src/core/main-utils.c:140 ../src/core/main-utils.c:152 +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1660 #, c-format -msgid "Cannot create '%s': %s" -msgstr "Не вдалося створити «%s»: %s" +msgid "peer #%u is invalid: %s" +msgstr "вузол %u є некоректним: %s" -#: ../src/core/main-utils.c:207 +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1731 +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1750 #, c-format -msgid "%s is already running (pid %ld)\n" -msgstr "%s вже працює (pid %ld)\n" +msgid "method \"%s\" is not supported for WireGuard" +msgstr "підтримки методу «%s» для WireGuard не передбачено" -#: ../src/core/main-utils.c:217 +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1774 +msgid "key must be 32 bytes base64 encoded" +msgstr "ключ має складатися з 32 байтів у кодуванні base64" + +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1904 +msgid "invalid peer secrets" +msgstr "некоректні реєстраційні дані до вузла" + +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1930 #, c-format -msgid "You must be root to run %s!\n" -msgstr "Для виконання %s потрібно перейти у режим root!\n" +msgid "peer #%u lacks public-key" +msgstr "для вузла %u не вказано відкритого ключа" -#: ../src/core/dhcp/nm-dhcp-dhclient-utils.c:316 -msgid "# Created by NetworkManager\n" -msgstr "# Створено за допомогою NetworkManager\n" +#: ../src/libnm-core-impl/nm-setting-wireguard.c:1947 +#, c-format +msgid "non-existing peer '%s'" +msgstr "вузол «%s», якого не існує" -#: ../src/core/dhcp/nm-dhcp-dhclient-utils.c:329 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:912 #, c-format -msgid "" -"# Merged from %s\n" -"\n" -msgstr "" -"# Об'єднано з %s\n" -"\n" +msgid "'%s' is not a valid value for '%s' mode connections" +msgstr "«%s» не є коректним значенням режиму з'єднань «%s»" -#: ../src/core/devices/bluetooth/nm-bluez-manager.c:1325 +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:942 #, c-format -msgid "%s Network" -msgstr "Мережа %s" +msgid "'%s' security requires '%s=%s'" +msgstr "для захисту «%s» слід вказати «%s=%s»" -#: ../src/core/devices/bluetooth/nm-device-bt.c:301 -msgid "PAN requested, but Bluetooth device does not support NAP" -msgstr "" -"Надіслано запит щодо PAN, але у пристрої Bluetooth не передбачено підтримки " -"NAP" +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:971 +#, c-format +msgid "'%s' security requires '%s' setting presence" +msgstr "захист «%s» вимагає використання параметра «%s»" -#: ../src/core/devices/bluetooth/nm-device-bt.c:314 -msgid "PAN connections cannot specify GSM, CDMA, or serial settings" -msgstr "" -"Записи з'єднання PAN не можуть вказувати параметрів GSM, CDMA або " -"послідовного пристрою" +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:996 +#, c-format +msgid "'%d' value is out of range <0-3>" +msgstr "значення «%d» лежить поза діапазоном <0-3>" -#: ../src/core/devices/bluetooth/nm-device-bt.c:329 -msgid "PAN connection" -msgstr "З'єднання PAN" +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:1073 +#, c-format +msgid "'%s' can only be used with '%s=%s' (WEP)" +msgstr "«%s» можна використовувати лише з «%s=%s» (WEP)" -#: ../src/core/devices/bluetooth/nm-device-bt.c:336 -msgid "DUN requested, but Bluetooth device does not support DUN" +#: ../src/libnm-core-impl/nm-setting-wireless-security.c:1111 +#, c-format +msgid "" +"'%s' can only be used with 'wpa-eap', 'wpa-eap-suite-b-192', 'wpa-psk' or " +"'sae' key management " msgstr "" -"Надіслано запит щодо DUN, але у пристрої Bluetooth не передбачено підтримки " -"DUN" +"«%s» можна використовувати лише з керуванням ключами «wpa-eap», «wpa-eap-" +"suite-b-192», «wpa-psk» або «sae»" -#: ../src/core/devices/bluetooth/nm-device-bt.c:349 -msgid "DUN connection must include a GSM or CDMA setting" -msgstr "З'єднання DUN має включати параметр GSM або CDMA" +#: ../src/libnm-core-impl/nm-setting-wireless.c:813 +#, c-format +msgid "'%s' is not a valid Wi-Fi mode" +msgstr "«%s» не є коректним режимом Wi-Fi" -#: ../src/core/devices/bluetooth/nm-device-bt.c:360 -#: ../src/core/devices/wwan/nm-modem-broadband.c:821 -msgid "GSM connection" -msgstr "З'єднання GSM" +#: ../src/libnm-core-impl/nm-setting-wireless.c:826 +#, c-format +msgid "'%s' is not a valid band" +msgstr "«%s» не є коректним значенням смуги" -#: ../src/core/devices/bluetooth/nm-device-bt.c:362 -#: ../src/core/devices/wwan/nm-modem-broadband.c:846 -msgid "CDMA connection" -msgstr "З'єднання CDMA" +#: ../src/libnm-core-impl/nm-setting-wireless.c:839 +#, c-format +msgid "'%s' requires setting '%s' property" +msgstr "«%s» потребує встановлення властивості «%s»" -#: ../src/core/devices/bluetooth/nm-device-bt.c:370 -msgid "Unknown/unhandled Bluetooth connection type" -msgstr "Невідомий або непридатний тип з'єднання Bluetooth" +#: ../src/libnm-core-impl/nm-setting-wireless.c:869 +#, c-format +msgid "'%s' requires '%s' and '%s' property" +msgstr "«%s» потребує «%s» і властивості «%s»" -#: ../src/core/devices/bluetooth/nm-device-bt.c:395 -msgid "connection does not match device" -msgstr "з'єднання не відповідає пристрою" +#: ../src/libnm-core-impl/nm-setting-wireless.c:981 +#: ../src/libnm-core-impl/nm-team-utils.c:2253 +#, c-format +msgid "invalid value" +msgstr "некоректне значення" -#: ../src/core/devices/nm-device-6lowpan.c:190 -msgid "6LOWPAN connection" -msgstr "З'єднання 6LOWPAN" +#: ../src/libnm-core-impl/nm-setting-wireless.c:994 +msgid "Wake-on-WLAN mode 'default' and 'ignore' are exclusive flags" +msgstr "" +"Прапорці режиму Wake-on-WLAN «default» і «ignore» не можна використовувати " +"одночасно" -#: ../src/core/devices/nm-device-bond.c:89 -msgid "Bond connection" -msgstr "Прив'язане з'єднання" +#: ../src/libnm-core-impl/nm-setting-wireless.c:1005 +msgid "Wake-on-WLAN trying to set unknown flag" +msgstr "Wake-on-WLAN намагається встановити невідомий прапорець" -#: ../src/core/devices/nm-device-bridge.c:155 -msgid "Bridge connection" -msgstr "З'єднання містка" +#: ../src/libnm-core-impl/nm-setting-wireless.c:1018 +msgid "AP isolation can be set only in AP mode" +msgstr "Ізоляцію точки доступу можна встановлювати лише у режимі точки доступу" -#: ../src/core/devices/nm-device-dummy.c:58 -msgid "Dummy connection" -msgstr "Фіктивне з'єднання" +#: ../src/libnm-core-impl/nm-setting-wireless.c:1042 +#, c-format +msgid "conflicting value of mac-address-randomization and cloned-mac-address" +msgstr "конфлікт значень mac-address-randomization і cloned-mac-address" -#: ../src/core/devices/nm-device-ethernet.c:1677 -msgid "PPPoE connection" -msgstr "З'єднання PPPoE" +#: ../src/libnm-core-impl/nm-setting-wpan.c:171 +msgid "page must be defined along with a channel" +msgstr "сторінку слід вказувати разом із каналом" + +#: ../src/libnm-core-impl/nm-setting-wpan.c:180 +#, c-format +msgid "page must be between %d and %d" +msgstr "сторінку має бути вказано числом від %d до %d" + +#: ../src/libnm-core-impl/nm-setting-wpan.c:191 +#, c-format +msgid "channel must not be between %d and %d" +msgstr "канал має бути вказано числом від %d до %d" -#: ../src/core/devices/nm-device-ethernet.c:1677 -msgid "Wired connection" -msgstr "Дротове з'єднання" +#: ../src/libnm-core-impl/nm-setting.c:795 +#, c-format +msgid "duplicate property" +msgstr "дублювання властивості" -#: ../src/core/devices/nm-device-ethernet-utils.c:20 +#: ../src/libnm-core-impl/nm-setting.c:815 #, c-format -msgid "Wired connection %d" -msgstr "Дротове з'єднання %d" +msgid "unknown property" +msgstr "невідома властивість" -#: ../src/core/devices/nm-device-ip-tunnel.c:399 -msgid "IP tunnel connection" -msgstr "З'єднання IP-тунель" +#: ../src/libnm-core-impl/nm-setting.c:896 +#: ../src/libnm-core-impl/nm-setting.c:950 +#, c-format +msgid "can't set property of type '%s' from value of type '%s'" +msgstr "не вдалося встановити властивість типу «%s» зі значення типу «%s»" -#: ../src/core/devices/nm-device-macvlan.c:389 -msgid "MACVLAN connection" -msgstr "З'єднання MACVLAN" +#: ../src/libnm-core-impl/nm-setting.c:917 +#: ../src/libnm-core-impl/nm-setting.c:933 +#, c-format +msgid "failed to set property: %s" +msgstr "не вдалося встановити значення властивості: %s" -#: ../src/core/devices/nm-device-tun.c:144 -msgid "TUN connection" -msgstr "З'єднання TUN" +#: ../src/libnm-core-impl/nm-setting.c:970 +#, c-format +msgid "can not set property: %s" +msgstr "не вдалося встановити значення властивості: %s" -#: ../src/core/devices/nm-device-wpan.c:54 -msgid "WPAN connection" -msgstr "З'єднання WPAN" +#: ../src/libnm-core-impl/nm-setting.c:2016 +msgid "secret not found" +msgstr "не знайдено ключа" -#: ../src/core/devices/team/nm-device-team.c:88 -msgid "Team connection" -msgstr "Командне з'єднання" +#: ../src/libnm-core-impl/nm-team-utils.c:1531 +#: ../src/libnm-core-impl/nm-team-utils.c:1548 +#, c-format +msgid "invalid D-Bus property \"%s\"" +msgstr "некоректна властивість D-Bus «%s»" -#: ../src/core/devices/wifi/nm-wifi-utils.c:28 +#: ../src/libnm-core-impl/nm-team-utils.c:1560 #, c-format -msgid "%s is incompatible with static WEP keys" -msgstr "%s є несумісним зі статичними ключами WEP" +msgid "duplicate D-Bus property \"%s\"" +msgstr "дублювання властивості D-Bus «%s»" -#: ../src/core/devices/wifi/nm-wifi-utils.c:63 -msgid "LEAP authentication requires a LEAP username" -msgstr "Для розпізнавання LEAP потрібне ім'я користувача LEAP" +#: ../src/libnm-core-impl/nm-team-utils.c:1580 +#, c-format +msgid "invalid D-Bus property \"%s\" for \"%s\"" +msgstr "некоректна властивість D-Bus «%s» для «%s»" -#: ../src/core/devices/wifi/nm-wifi-utils.c:75 -msgid "LEAP username requires 'leap' authentication" -msgstr "Ім'я користувача LEAP потребує розпізнавання «leap»" +#: ../src/libnm-core-impl/nm-team-utils.c:1652 +#, c-format +msgid "unknown link-watcher name \"%s\"" +msgstr "некоректна назва засобу спостереження за зв'язком, «%s»" -#: ../src/core/devices/wifi/nm-wifi-utils.c:90 -msgid "LEAP authentication requires IEEE 802.1x key management" -msgstr "Розпізнавання LEAP потребує керування ключами IEEE 802.1x" +#: ../src/libnm-core-impl/nm-team-utils.c:2239 +#, c-format +msgid "value out or range" +msgstr "значення поза припустимим діапазоном" -#: ../src/core/devices/wifi/nm-wifi-utils.c:112 -msgid "LEAP authentication is incompatible with Ad-Hoc mode" -msgstr "Розпізнавання LEAP є несумісним зі спеціальним (Ad-Hoc) режимом" +#: ../src/libnm-core-impl/nm-team-utils.c:2274 +#, c-format +msgid "invalid runner-tx-hash" +msgstr "некоректне значення runner-tx-hash" -#: ../src/core/devices/wifi/nm-wifi-utils.c:124 -msgid "LEAP authentication is incompatible with 802.1x setting" -msgstr "Розпізнавання LEAP є несумісним із встановленням 802.1x" +#: ../src/libnm-core-impl/nm-team-utils.c:2303 +#, c-format +msgid "%s is only allowed for runner %s" +msgstr "%s можна використовувати лише для засобу запуску %s" -#: ../src/core/devices/wifi/nm-wifi-utils.c:144 +#: ../src/libnm-core-impl/nm-team-utils.c:2313 #, c-format -msgid "a connection using '%s' authentication cannot use WPA key management" -msgstr "" -"з'єднання, де використовується розпізнавання «%s», не може використовувати " -"керування ключами WPA" +msgid "%s is only allowed for runners %s" +msgstr "%s можна використовувати лише для засобів запуску %s" -#: ../src/core/devices/wifi/nm-wifi-utils.c:157 +#: ../src/libnm-core-impl/nm-team-utils.c:2334 #, c-format -msgid "a connection using '%s' authentication cannot specify WPA protocols" +msgid "cannot set parameters for lacp and activebackup runners together" msgstr "" -"з'єднання, де використовується розпізнавання «%s», не може використовувати " -"специфічні протоколи WPA" +"не можна встановлювати параметри для засобів запуску lacp і activebackup " +"одночасно" -#: ../src/core/devices/wifi/nm-wifi-utils.c:175 -#: ../src/core/devices/wifi/nm-wifi-utils.c:194 +#: ../src/libnm-core-impl/nm-team-utils.c:2348 #, c-format -msgid "a connection using '%s' authentication cannot specify WPA ciphers" -msgstr "" -"з'єднання, де використовується розпізнавання «%s», не може використовувати " -"специфічні шифри WPA" +msgid "missing link watcher" +msgstr "не вказано засобу спостереження за зв'язком" -#: ../src/core/devices/wifi/nm-wifi-utils.c:208 +#: ../src/libnm-core-impl/nm-team-utils.c:2374 #, c-format -msgid "a connection using '%s' authentication cannot specify a WPA password" -msgstr "" -"з'єднання, де використовується розпізнавання «%s», не може використовувати " -"специфічний пароль WPA" +msgid "team config exceeds size limit" +msgstr "налаштування команди порушують обмеження щодо розміру" -#: ../src/core/devices/wifi/nm-wifi-utils.c:241 -msgid "Dynamic WEP requires an 802.1x setting" -msgstr "Динамічний WEP потребує встановлення параметра 802.1x" +#: ../src/libnm-core-impl/nm-team-utils.c:2385 +#, c-format +msgid "team config is not valid UTF-8" +msgstr "файл налаштувань team не є коректними даними у кодуванні UTF-8" -#: ../src/core/devices/wifi/nm-wifi-utils.c:251 -#: ../src/core/devices/wifi/nm-wifi-utils.c:283 -msgid "Dynamic WEP requires 'open' authentication" -msgstr "Динамічний WEP потребує розпізнавання «open»" +#: ../src/libnm-core-impl/nm-team-utils.c:2560 +#, c-format +msgid "invalid D-Bus type \"%s\"" +msgstr "некоректний тип D-Bus «%s»" -#: ../src/core/devices/wifi/nm-wifi-utils.c:268 -msgid "Dynamic WEP requires 'ieee8021x' key management" -msgstr "Динамічний WEP потребує керування ключами «ieee8021x»" +#: ../src/libnm-core-impl/nm-team-utils.c:2599 +#, c-format +msgid "invalid link-watchers: %s" +msgstr "некоректне значення link-watchers: %s" -#: ../src/core/devices/wifi/nm-wifi-utils.c:319 -msgid "WPA-PSK authentication is incompatible with 802.1x" -msgstr "Розпізнавання за допомогою WPA-PSK є несумісним з 802.1x" +#: ../src/libnm-core-impl/nm-utils.c:2312 +#, c-format +msgid "'%s' is not a valid handle." +msgstr "«%s» не є коректним дескриптором." -#: ../src/core/devices/wifi/nm-wifi-utils.c:329 -msgid "WPA-PSK requires 'open' authentication" -msgstr "WPA-PSK потребує розпізнавання «open»" +#: ../src/libnm-core-impl/nm-utils.c:2460 +#, c-format +msgid "'%s' unexpected: parent already specified." +msgstr "Неочікуване «%s»: батьківський запис вже вказано." -#: ../src/core/devices/wifi/nm-wifi-utils.c:343 -msgid "Access point does not support PSK but setting requires it" -msgstr "" -"У точці доступу не передбачено підтримки PSK, але параметром передбачено " -"таку підтримку" +#: ../src/libnm-core-impl/nm-utils.c:2478 +#, c-format +msgid "invalid handle: '%s'" +msgstr "некоректний дескриптор: «%s»" -#: ../src/core/devices/wifi/nm-wifi-utils.c:358 -msgid "WPA Ad-Hoc authentication requires 'rsn' protocol" -msgstr "Розпізнавання за спеціальним WPA потребує протоколу «rsn»" +#: ../src/libnm-core-impl/nm-utils.c:2500 +msgid "parent not specified." +msgstr "не вказано батьківський запис." -#: ../src/core/devices/wifi/nm-wifi-utils.c:371 -msgid "WPA Ad-Hoc authentication requires 'ccmp' pairwise cipher" -msgstr "Розпізнавання за спеціальним WPA потребує парного шифру «ccmp»" +#: ../src/libnm-core-impl/nm-utils.c:2564 +#, c-format +msgid "unsupported qdisc option: '%s'." +msgstr "непідтримуваний параметр qdisc: «%s»." -#: ../src/core/devices/wifi/nm-wifi-utils.c:384 -msgid "WPA Ad-Hoc requires 'ccmp' group cipher" -msgstr "Спеціальний (Ad-Hoc) режим WPA потребує групового шифрування «ccmp»" +#: ../src/libnm-core-impl/nm-utils.c:2694 +msgid "action name missing." +msgstr "не вказано назви дії." -#: ../src/core/devices/wifi/nm-wifi-utils.c:415 -msgid "WPA-EAP authentication requires an 802.1x setting" -msgstr "Розпізнавання WPA-EAP потребує параметра 802.1x" +#: ../src/libnm-core-impl/nm-utils.c:2720 +#, c-format +msgid "unsupported action option: '%s'." +msgstr "непідтримуваний параметр дії: «%s»." -#: ../src/core/devices/wifi/nm-wifi-utils.c:425 -msgid "WPA-EAP requires 'open' authentication" -msgstr "WPA-EAP потребує розпізнавання «open»" +#: ../src/libnm-core-impl/nm-utils.c:2859 +msgid "invalid action: " +msgstr "некоректна дія: " -#: ../src/core/devices/wifi/nm-wifi-utils.c:438 -msgid "802.1x setting requires 'wpa-eap' key management" -msgstr "Параметр 802.1x потребує керування ключами «wpa-eap»" +#: ../src/libnm-core-impl/nm-utils.c:2863 +#, c-format +msgid "unsupported tfilter option: '%s'." +msgstr "непідтримуваний параметр tfilter: «%s»." -#: ../src/core/devices/wifi/nm-wifi-utils.c:452 -msgid "Access point does not support 802.1x but setting requires it" -msgstr "" -"У точці доступу не передбачено підтримки 802.1x, але параметром передбачено " -"таку підтримку" +#: ../src/libnm-core-impl/nm-utils.c:3464 +#, c-format +msgid "failed stat file %s: %s" +msgstr "не вдалося отримати статистичні дані щодо файла %s: %s" -#: ../src/core/devices/wifi/nm-wifi-utils.c:482 -msgid "Ad-Hoc mode requires 'none' or 'wpa-psk' key management" -msgstr "" -"Для ситуативного режиму слід використовувати керування ключами «none» або " -"«wpa-psk»" +#: ../src/libnm-core-impl/nm-utils.c:3475 +#, c-format +msgid "not a file (%s)" +msgstr "не є файлом (%s)" -#: ../src/core/devices/wifi/nm-wifi-utils.c:494 -msgid "Ad-Hoc mode is incompatible with 802.1x security" -msgstr "Спеціальний (Ad-Hoc) режим є несумісним із захистом 802.1x" +#: ../src/libnm-core-impl/nm-utils.c:3486 +#, c-format +msgid "invalid file owner %d for %s" +msgstr "некоректний власник файла, %d, %s" -#: ../src/core/devices/wifi/nm-wifi-utils.c:503 -msgid "Ad-Hoc mode is incompatible with LEAP security" -msgstr "Спеціальний (Ad-Hoc) режим є несумісним із захистом LEAP" +#: ../src/libnm-core-impl/nm-utils.c:3498 +#, c-format +msgid "file permissions for %s" +msgstr "файлові права доступу до %s" -#: ../src/core/devices/wifi/nm-wifi-utils.c:515 -msgid "Ad-Hoc mode requires 'open' authentication" -msgstr "Для спеціального (Ad-Hoc) режиму потрібне розпізнавання «open»" +#: ../src/libnm-core-impl/nm-utils.c:3508 +#, c-format +msgid "reject %s" +msgstr "відмовити %s" -#: ../src/core/devices/wifi/nm-wifi-utils.c:559 -#: ../src/core/devices/wifi/nm-wifi-utils.c:594 +#: ../src/libnm-core-impl/nm-utils.c:3528 #, c-format -msgid "connection does not match access point" -msgstr "з'єднання не відповідає точці доступу" +msgid "path is not absolute (%s)" +msgstr "шлях не є абсолютним (%s)" -#: ../src/core/devices/wifi/nm-wifi-utils.c:648 +#: ../src/libnm-core-impl/nm-utils.c:3543 #, c-format -msgid "connection does not match mesh point" -msgstr "з'єднання не відповідає точці сітки" +msgid "Plugin file does not exist (%s)" +msgstr "Файла додатка не існує (%s)" -#: ../src/core/devices/wifi/nm-wifi-utils.c:667 -msgid "Access point is unencrypted but setting specifies security" -msgstr "" -"Обмін даними із точкою доступу є незашифрованим, але запис вказує за " -"захищене з'єднання" +#: ../src/libnm-core-impl/nm-utils.c:3552 +#, c-format +msgid "Plugin is not a valid file (%s)" +msgstr "Додаток не є коректним файлом (%s)" -#: ../src/core/devices/wifi/nm-wifi-utils.c:758 -msgid "" -"WPA authentication is incompatible with non-EAP (original) LEAP or Dynamic " -"WEP" -msgstr "" -"Розпізнавання за допомогою WPA є несумісним з LEAP без EAP (оригінальним) " -"або динамічним WEP" +#: ../src/libnm-core-impl/nm-utils.c:3563 +#, c-format +msgid "libtool archives are not supported (%s)" +msgstr "Підтримки архівів libtool не передбачено (%s)" -#: ../src/core/devices/wifi/nm-wifi-utils.c:771 -msgid "WPA authentication is incompatible with Shared Key authentication" -msgstr "" -"Розпізнавання за допомогою WPA є несумісним із розпізнаванням за допомогою " -"розповсюдженого ключа" +#: ../src/libnm-core-impl/nm-utils.c:3640 +#, c-format +msgid "Could not find \"%s\" binary" +msgstr "Не вдалося знайти виконуваний файл «%s»" -#: ../src/core/devices/wifi/nm-wifi-utils.c:854 -msgid "Failed to determine AP security information" -msgstr "Не вдалося визначити дані щодо захисту точки доступу" +#: ../src/libnm-core-impl/nm-utils.c:4484 +msgid "unknown secret flags" +msgstr "невідомі прапорці реєстраційних даних" -#: ../src/core/nm-config.c:567 -#, c-format -msgid "Bad '%s' option: " -msgstr "Помилковий параметр «%s»: " +#: ../src/libnm-core-impl/nm-utils.c:4494 +msgid "conflicting secret flags" +msgstr "конфлікт прапорців реєстраційних даних" -#: ../src/core/nm-config.c:584 -msgid "Config file location" -msgstr "Розташування файла налаштувань" +#: ../src/libnm-core-impl/nm-utils.c:4505 +msgid "secret flags must not be \"not-required\"" +msgstr "прапорці реєстраційних даних не можуть бути «not-required»" -#: ../src/core/nm-config.c:591 -msgid "Config directory location" -msgstr "Розташування каталогу налаштувань" +#: ../src/libnm-core-impl/nm-utils.c:4513 +msgid "unsupported secret flags" +msgstr "непідтримувані прапорці реєстраційних даних" -#: ../src/core/nm-config.c:598 -msgid "System config directory location" -msgstr "Розташування загальносистемного каталогу налаштувань" +#: ../src/libnm-core-impl/nm-utils.c:4543 +msgid "can't be simultaneously disabled and enabled" +msgstr "не може бути одночасно вимкнено і увімкнено" -#: ../src/core/nm-config.c:605 -msgid "Internal config file location" -msgstr "Розташування внутрішнього файла налаштувань" +#: ../src/libnm-core-impl/nm-utils.c:4551 +msgid "WPS is required" +msgstr "Потрібна WPS" -#: ../src/core/nm-config.c:612 -msgid "State file location" -msgstr "Розташування файла стану" +#: ../src/libnm-core-impl/nm-utils.c:4619 +#, c-format +msgid "not a valid ethernet MAC address for mask at position %lld" +msgstr "некоректна адреса MAC ethernet для маски у позиції %lld" -#: ../src/core/nm-config.c:619 -msgid "State file for no-auto-default devices" -msgstr "" -"Файл станів для пристроїв без автоматичних типових параметрів (no-auto-" -"default)" +#: ../src/libnm-core-impl/nm-utils.c:4638 +#, c-format +msgid "not a valid ethernet MAC address #%u at position %lld" +msgstr "некоректна адреса MAC ethernet #%u у позиції %lld" -#: ../src/core/nm-config.c:626 -msgid "List of plugins separated by ','" -msgstr "Список додатків, відокремлених комами («,»)" +#: ../src/libnm-core-impl/nm-utils.c:5293 +msgid "not valid utf-8" +msgstr "некоректні дані UTF-8" -#: ../src/core/nm-config.c:633 -msgid "Quit after initial configuration" -msgstr "Вийти після початкового налаштовування" +#: ../src/libnm-core-impl/nm-utils.c:5314 +#: ../src/libnm-core-impl/nm-utils.c:5367 +msgid "is not a JSON object" +msgstr "не є об'єктом JSON" -#: ../src/core/nm-config.c:640 ../src/core/nm-iface-helper.c:420 -msgid "Don't become a daemon, and log to stderr" -msgstr "" -"Не переходити у стан фонової служби і записувати повідомлення журналу до " -"stderr" +#: ../src/libnm-core-impl/nm-utils.c:5343 +msgid "value is NULL" +msgstr "значенням є NULL" -#: ../src/core/nm-config.c:649 -msgid "An http(s) address for checking internet connectivity" -msgstr "Адреса http(s) для спроб перевірки можливості встановлення з'єднання" +#: ../src/libnm-core-impl/nm-utils.c:5343 +msgid "value is empty" +msgstr "порожнє значення" -#: ../src/core/nm-config.c:656 -msgid "The interval between connectivity checks (in seconds)" -msgstr "Інтервал між перевірками можливості з'єднання (у секундах)" +#: ../src/libnm-core-impl/nm-utils.c:5355 +#, c-format +msgid "invalid JSON at position %d (%s)" +msgstr "некоректний код JSON на позиції %d (%s)" -#: ../src/core/nm-config.c:663 -msgid "The expected start of the response" -msgstr "Очікуваний початок відповіді" +#: ../src/libnm-core-impl/nm-utils.c:5485 +#: ../src/libnm-core-impl/nm-utils.c:5505 +msgid "unterminated escape sequence" +msgstr "незавершена екранована послідовність" -#: ../src/core/nm-config.c:672 -msgid "NetworkManager options" -msgstr "Параметри NetworkManager" +#: ../src/libnm-core-impl/nm-utils.c:5531 +#, c-format +msgid "unknown attribute '%s'" +msgstr "невідомий атрибут «%s»" -#: ../src/core/nm-config.c:673 -msgid "Show NetworkManager options" -msgstr "Показати параметри NetworkManager" +#: ../src/libnm-core-impl/nm-utils.c:5549 +#, c-format +msgid "missing key-value separator '%c' after '%s'" +msgstr "пропущено роздільник пар ключ-значення «%c» після «%s»" -#: ../src/core/nm-iface-helper.c:292 -msgid "The interface to manage" -msgstr "Інтерфейс для керування" +#: ../src/libnm-core-impl/nm-utils.c:5569 +#, c-format +msgid "invalid uint32 value '%s' for attribute '%s'" +msgstr "некоректне значення uint32 «%s» атрибута «%s»" -#: ../src/core/nm-iface-helper.c:299 -msgid "Connection UUID" -msgstr "UUID з'єднання" +#: ../src/libnm-core-impl/nm-utils.c:5583 +#, c-format +msgid "invalid int32 value '%s' for attribute '%s'" +msgstr "некоректне значення int32 «%s» атрибута «%s»" -#: ../src/core/nm-iface-helper.c:306 -msgid "Connection Token for Stable IDs" -msgstr "Жетон з'єднання для стабільних ідентифікаторів" +#: ../src/libnm-core-impl/nm-utils.c:5596 +#, c-format +msgid "invalid uint64 value '%s' for attribute '%s'" +msgstr "некоректне значення uint64 «%s» атрибута «%s»" -#: ../src/core/nm-iface-helper.c:313 -msgid "Whether to manage IPv6 SLAAC" -msgstr "Чи слід керувати SLAAC IPv6" +#: ../src/libnm-core-impl/nm-utils.c:5609 +#, c-format +msgid "invalid uint8 value '%s' for attribute '%s'" +msgstr "некоректне значення uint8 «%s» атрибута «%s»" -#: ../src/core/nm-iface-helper.c:320 -msgid "Whether SLAAC must be successful" -msgstr "Чи має бути SLAAC успішним" +#: ../src/libnm-core-impl/nm-utils.c:5623 +#, c-format +msgid "invalid boolean value '%s' for attribute '%s'" +msgstr "некоректне булеве значення «%s» атрибута «%s»" -#: ../src/core/nm-iface-helper.c:327 -msgid "Use an IPv6 temporary privacy address" -msgstr "Використовувати тимчасову приватну адресу IPv6" +#: ../src/libnm-core-impl/nm-utils.c:5637 +#, c-format +msgid "unsupported attribute '%s' of type '%s'" +msgstr "непідтримуваний атрибут «%s» типу «%s»" -#: ../src/core/nm-iface-helper.c:334 -msgid "Current DHCPv4 address" -msgstr "Поточна адреса DHCPv4" +#: ../src/libnm-core-impl/nm-utils.c:5939 +#, c-format +msgid "Bridge VLANs %d and %d are not sorted by ascending vid" +msgstr "VLAN містка %d і %d не упорядковано за зростанням vid" -#: ../src/core/nm-iface-helper.c:341 -msgid "Whether DHCPv4 must be successful" -msgstr "Чи має DHCPv4 бути успішним" +#: ../src/libnm-core-impl/nm-utils.c:5963 +#, c-format +msgid "duplicate bridge VLAN vid %u" +msgstr "дублікат містка vid VLAN %u" -#: ../src/core/nm-iface-helper.c:348 -msgid "Hex-encoded DHCPv4 client ID" -msgstr "Закодований у шістнадцяткову форму ідентифікатор клієнта DHCPv4" +#: ../src/libnm-core-impl/nm-utils.c:5975 +msgid "only one VLAN can be the PVID" +msgstr "лише одна з VLAN може бути PVID" -#: ../src/core/nm-iface-helper.c:355 -msgid "Hostname to send to DHCP server" -msgstr "Назва вузла для надсилання на сервер DHCP" +#: ../src/libnm-core-impl/nm-utils.c:6020 +#, c-format +msgid "unknown flags 0x%x" +msgstr "невідомі прапорці 0x%x" -#: ../src/core/nm-iface-helper.c:356 -msgid "barbar" -msgstr "щосьщось" +#: ../src/libnm-core-impl/nm-utils.c:6032 +msgid "" +"'fqdn-no-update' and 'fqdn-serv-update' flags cannot be set at the same time" +msgstr "" +"не можна одночасно встановлювати прапорці «fqdn-no-update» і «fqdn-serv-" +"update»" -#: ../src/core/nm-iface-helper.c:362 -msgid "FQDN to send to DHCP server" -msgstr "Повна назва вузла (FQDN) для надсилання на сервер DHCP" +#: ../src/libnm-core-impl/nm-utils.c:6043 +msgid "'fqdn-clear-flags' flag is incompatible with other FQDN flags" +msgstr "прапорець «fqdn-clear-flags» є несумісним із іншими прапорцями FQDN" -#: ../src/core/nm-iface-helper.c:363 -msgid "host.domain.org" -msgstr "вузол.домен.org" +#: ../src/libnm-core-impl/nm-utils.c:6051 +msgid "DHCPv6 does not support the E (encoded) FQDN flag" +msgstr "у DHCPv6 не передбачено підтримки прапорця E (закодовано) FQDN" -#: ../src/core/nm-iface-helper.c:369 -msgid "Route priority for IPv4" -msgstr "Пріоритет маршруту для IPv4" +#: ../src/libnm-core-impl/nm-vpn-editor-plugin.c:284 +#, c-format +msgid "cannot load plugin \"%s\": %s" +msgstr "не вдалося завантажити додаток «%s»: %s" -#: ../src/core/nm-iface-helper.c:370 -msgid "0" -msgstr "0" +#: ../src/libnm-core-impl/nm-vpn-editor-plugin.c:295 +#, c-format +msgid "failed to load nm_vpn_editor_plugin_factory() from %s (%s)" +msgstr "не вдалося завантажити nm_vpn_editor_plugin_factory() з %s (%s)" -#: ../src/core/nm-iface-helper.c:376 -msgid "Route priority for IPv6" -msgstr "Пріоритет маршруту для IPv6" +#: ../src/libnm-core-impl/nm-vpn-editor-plugin.c:321 +#, c-format +msgid "unknown error initializing plugin %s" +msgstr "невідома помилка під час спроби ініціалізації додатка %s" -#: ../src/core/nm-iface-helper.c:377 -msgid "1024" -msgstr "1024" +#: ../src/libnm-core-impl/nm-vpn-editor-plugin.c:341 +#, c-format +msgid "cannot load VPN plugin in '%s': missing plugin name" +msgstr "не вдалося завантажити додаток VPN у «%s»: не вказано назви додатка" -#: ../src/core/nm-iface-helper.c:383 -msgid "Hex-encoded Interface Identifier" -msgstr "Закодований у шістнадцяткове число ідентифікатор інтерфейсу" +#: ../src/libnm-core-impl/nm-vpn-editor-plugin.c:349 +#, c-format +msgid "cannot load VPN plugin in '%s': invalid service name" +msgstr "не вдалося завантажити додаток VPN у «%s»: некоректна назва служби" -#: ../src/core/nm-iface-helper.c:390 -msgid "IPv6 SLAAC address generation mode" -msgstr "Режим створення адреси SLAAC IPv6" +#: ../src/libnm-core-impl/nm-vpn-editor-plugin.c:481 +#, c-format +msgid "the plugin does not support import capability" +msgstr "у додатку не передбачено можливостей імпортування" -#: ../src/core/nm-iface-helper.c:397 -msgid "" -"The logging backend configuration value. See logging.backend in " -"NetworkManager.conf" -msgstr "" -"Значення налаштування модуля ведення журналу. Див. logging.backend у " -"NetworkManager.conf" +#: ../src/libnm-core-impl/nm-vpn-editor-plugin.c:505 +#, c-format +msgid "the plugin does not support export capability" +msgstr "у додатку не передбачено можливостей експортування" -#: ../src/core/nm-iface-helper.c:451 -msgid "" -"nm-iface-helper is a small, standalone process that manages a single network " -"interface." -msgstr "" -"nm-iface-helper — малий окремий процес, який керує окремим інтерфейсом " -"мережі." +#: ../src/libnm-core-impl/nm-vpn-plugin-info.c:109 +#, c-format +msgid "missing filename" +msgstr "не вказано назви файла" -#: ../src/core/nm-iface-helper.c:562 +#: ../src/libnm-core-impl/nm-vpn-plugin-info.c:117 #, c-format -msgid "An interface name and UUID are required\n" -msgstr "Потрібні назва і UUID інтерфейсу\n" +msgid "filename must be an absolute path (%s)" +msgstr "назву файла має бути вказано у форматі абсолютного шляху (%s)" -#: ../src/core/nm-iface-helper.c:570 +#: ../src/libnm-core-impl/nm-vpn-plugin-info.c:126 #, c-format -msgid "Failed to find interface index for %s (%s)\n" -msgstr "Не вдалося знайти покажчик інтерфейсу для %s (%s)\n" +msgid "filename has invalid format (%s)" +msgstr "назву файла вказано у некоректному форматі (%s)" -#: ../src/core/nm-iface-helper.c:590 +#: ../src/libnm-core-impl/nm-vpn-plugin-info.c:419 #, c-format -msgid "Ignoring unrecognized log domain(s) '%s' passed on command line.\n" -msgstr "" -"Ігноруємо нерозпізнані домени журналювання, «%s», передані за допомогою " -"командного рядка.\n" +msgid "there exists a conflicting plugin (%s) that has the same %s.%s value" +msgstr "виявлено конфліктний додаток (%s), який має те саме значення %s.%s" -#: ../src/core/nm-iface-helper.c:636 +#: ../src/libnm-core-impl/nm-vpn-plugin-info.c:458 #, c-format -msgid "(%s): Invalid IID %s\n" -msgstr "(%s): некоректний IID %s\n" +msgid "there exists a conflicting plugin with the same name (%s)" +msgstr "виявлено конфліктний додаток із тією самою назвою (%s)" -#: ../src/core/nm-iface-helper.c:648 +#: ../src/libnm-core-impl/nm-vpn-plugin-info.c:1050 #, c-format -msgid "(%s): Invalid DHCP client-id %s\n" -msgstr "(%s): некоректний ідентифікатор клієнта DHCP %s\n" +msgid "missing \"plugin\" setting" +msgstr "не вказано параметр «plugin»" + +#: ../src/libnm-core-impl/nm-vpn-plugin-info.c:1060 +#, c-format +msgid "%s: don't retry loading plugin which already failed previously" +msgstr "" +"%s: не намагатися повторно завантажити додаток, спроба завантаження якого " +"вже завершилася помилкою" + +#: ../src/libnm-core-impl/nm-vpn-plugin-info.c:1134 +msgid "missing filename to load VPN plugin info" +msgstr "не вказано назви файла для завантаження даних щодо додатка VPN" + +#: ../src/libnm-core-impl/nm-vpn-plugin-info.c:1149 +msgid "missing name for VPN plugin info" +msgstr "не вказано назви для даних щодо додатка VPN" + +#: ../src/libnm-core-impl/nm-vpn-plugin-info.c:1163 +msgid "missing service for VPN plugin info" +msgstr "не вказано служби для даних щодо додатка VPN" diff --git a/src/c-list/src/c-list.h b/src/c-list/src/c-list.h new file mode 100644 index 0000000..c92aa6f --- /dev/null +++ b/src/c-list/src/c-list.h @@ -0,0 +1,443 @@ +#pragma once + +/* + * Circular Intrusive Double Linked List Collection in ISO-C11 + * + * This implements a generic circular double linked list. List entries must + * embed the CList object, which provides pointers to the next and previous + * element. Insertion and removal can be done in O(1) due to the double links. + * Furthermore, the list is circular, thus allows access to front/tail in O(1) + * as well, even if you only have a single head pointer (which is not how the + * list is usually operated, though). + * + * Note that you are free to use the list implementation without a head + * pointer. However, usual operation uses a single CList object as head, which + * is itself linked in the list and as such must be identified as list head. + * This allows very simply list operations and avoids a lot of special cases. + * Most importantly, you can unlink entries without requiring a head pointer. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef struct CList CList; + +/** + * struct CList - Entry of a circular double linked list + * @next: next entry + * @prev: previous entry + * + * Each entry in a list must embed a CList object. This object contains + * pointers to its next and previous elements, which can be freely accessed by + * the API user at any time. Note that the list is circular, and the list head + * is linked in the list as well. + * + * The list head must be initialized via C_LIST_INIT before use. There is no + * reason to initialize entry objects before linking them. However, if you need + * a boolean state that tells you whether the entry is linked or not, you should + * initialize the entry via C_LIST_INIT as well. + */ +struct CList { + CList *next; + CList *prev; +}; + +#define C_LIST_INIT(_var) { .next = &(_var), .prev = &(_var) } + +/** + * c_list_init() - initialize list entry + * @what: list entry to initialize + */ +static inline void c_list_init(CList *what) { + *what = (CList)C_LIST_INIT(*what); +} + +/** + * c_list_entry() - get parent container of list entry + * @_what: list entry, or NULL + * @_t: type of parent container + * @_m: member name of list entry in @_t + * + * If the list entry @_what is embedded into a surrounding structure, this will + * turn the list entry pointer @_what into a pointer to the parent container + * (using offsetof(3), or sometimes called container_of(3)). + * + * If @_what is NULL, this will also return NULL. + * + * Return: Pointer to parent container, or NULL. + */ +#define c_list_entry(_what, _t, _m) \ + ((_t *)(void *)(((unsigned long)(void *)(_what) ?: \ + offsetof(_t, _m)) - offsetof(_t, _m))) + +/** + * c_list_is_linked() - check whether an entry is linked + * @what: entry to check, or NULL + * + * Return: True if @what is linked in a list, false if not. + */ +static inline _Bool c_list_is_linked(const CList *what) { + return what && what->next != what; +} + +/** + * c_list_is_empty() - check whether a list is empty + * @list: list to check, or NULL + * + * This is the same as !c_list_is_linked(). + * + * Return: True if @list is empty, false if not. + */ +static inline _Bool c_list_is_empty(const CList *list) { + return !c_list_is_linked(list); +} + +/** + * c_list_link_before() - link entry into list + * @where: linked list entry used as anchor + * @what: entry to link + * + * This links @what directly in front of @where. @where can either be a list + * head or any entry in the list. + * + * If @where points to the list head, this effectively links @what as new tail + * element. Hence, the macro c_list_link_tail() is an alias to this. + * + * @what is not inspected prior to being linked. Hence, it better not be linked + * into another list, or the other list will be corrupted. + */ +static inline void c_list_link_before(CList *where, CList *what) { + CList *prev = where->prev, *next = where; + + next->prev = what; + what->next = next; + what->prev = prev; + prev->next = what; +} +#define c_list_link_tail(_list, _what) c_list_link_before((_list), (_what)) + +/** + * c_list_link_after() - link entry into list + * @where: linked list entry used as anchor + * @what: entry to link + * + * This links @what directly after @where. @where can either be a list head or + * any entry in the list. + * + * If @where points to the list head, this effectively links @what as new front + * element. Hence, the macro c_list_link_front() is an alias to this. + * + * @what is not inspected prior to being linked. Hence, it better not be linked + * into another list, or the other list will be corrupted. + */ +static inline void c_list_link_after(CList *where, CList *what) { + CList *prev = where, *next = where->next; + + next->prev = what; + what->next = next; + what->prev = prev; + prev->next = what; +} +#define c_list_link_front(_list, _what) c_list_link_after((_list), (_what)) + +/** + * c_list_unlink_stale() - unlink element from list + * @what: element to unlink + * + * This unlinks @what. If @what was initialized via C_LIST_INIT(), it has no + * effect. If @what was never linked, nor initialized, behavior is undefined. + * + * Note that this does not modify @what. It just modifies the previous and next + * elements in the list to no longer reference @what. If you want to make sure + * @what is re-initialized after removal, use c_list_unlink(). + */ +static inline void c_list_unlink_stale(CList *what) { + CList *prev = what->prev, *next = what->next; + + next->prev = prev; + prev->next = next; +} + +/** + * c_list_unlink() - unlink element from list and re-initialize + * @what: element to unlink + * + * This is like c_list_unlink_stale() but re-initializes @what after removal. + */ +static inline void c_list_unlink(CList *what) { + /* condition is not needed, but avoids STOREs in fast-path */ + if (c_list_is_linked(what)) { + c_list_unlink_stale(what); + *what = (CList)C_LIST_INIT(*what); + } +} + +/** + * c_list_swap() - exchange the contents of two lists + * @list1: the list to operate on + * @list2: the list to operate on + * + * This replaces the contents of the list @list1 with the contents + * of @list2, and vice versa. + */ +static inline void c_list_swap(CList *list1, CList *list2) { + CList t; + + /* make neighbors of list1 point to list2, and vice versa */ + t = *list1; + t.next->prev = list2; + t.prev->next = list2; + t = *list2; + t.next->prev = list1; + t.prev->next = list1; + + /* swap list1 and list2 now that their neighbors were fixed up */ + t = *list1; + *list1 = *list2; + *list2 = t; +} + +/** + * c_list_splice() - splice one list into another + * @target: the list to splice into + * @source: the list to splice + * + * This removes all the entries from @source and splice them into @target. + * The order of the two lists is preserved and the source is appended + * to the end of target. + * + * On return, the source list will be empty. + */ +static inline void c_list_splice(CList *target, CList *source) { + if (!c_list_is_empty(source)) { + /* attach the front of @source to the tail of @target */ + source->next->prev = target->prev; + target->prev->next = source->next; + + /* attach the tail of @source to the front of @target */ + source->prev->next = target; + target->prev = source->prev; + + /* clear source */ + *source = (CList)C_LIST_INIT(*source); + } +} + +/** + * c_list_first() - return pointer to first element, or NULL if empty + * @list: list to operate on, or NULL + * + * This returns a pointer to the first element, or NULL if empty. This never + * returns a pointer to the list head. + * + * Return: Pointer to first list element, or NULL if empty. + */ +static inline CList *c_list_first(CList *list) { + return c_list_is_empty(list) ? NULL : list->next; +} + +/** + * c_list_last() - return pointer to last element, or NULL if empty + * @list: list to operate on, or NULL + * + * This returns a pointer to the last element, or NULL if empty. This never + * returns a pointer to the list head. + * + * Return: Pointer to last list element, or NULL if empty. + */ +static inline CList *c_list_last(CList *list) { + return c_list_is_empty(list) ? NULL : list->prev; +} + +/** + * c_list_first_entry() - return pointer to first entry, or NULL if empty + * @_list: list to operate on, or NULL + * @_t: type of list entries + * @_m: name of CList member in @_t + * + * This is like c_list_first(), but also applies c_list_entry() on the result. + * + * Return: Pointer to first list entry, or NULL if empty. + */ +#define c_list_first_entry(_list, _t, _m) \ + c_list_entry(c_list_first(_list), _t, _m) + +/** + * c_list_last_entry() - return pointer to last entry, or NULL if empty + * @_list: list to operate on, or NULL + * @_t: type of list entries + * @_m: name of CList member in @_t + * + * This is like c_list_last(), but also applies c_list_entry() on the result. + * + * Return: Pointer to last list entry, or NULL if empty. + */ +#define c_list_last_entry(_list, _t, _m) \ + c_list_entry(c_list_last(_list), _t, _m) + +/** + * c_list_for_each*() - iterators + * + * The c_list_for_each*() macros provide simple for-loop wrappers to iterate + * a linked list. They come in a set of flavours: + * + * - "entry": This combines c_list_entry() with the loop iterator, so the + * iterator always has the type of the surrounding object, rather + * than CList. + * + * - "safe": The loop iterator always keeps track of the next element to + * visit. This means, you can safely modify the current element, + * while retaining loop-integrity. + * You still must not touch any other entry of the list. Otherwise, + * the loop-iterator will be corrupted. + * + * - "continue": Rather than starting the iteration at the front of the list, + * use the current value of the iterator as starting position. + * Note that the first loop iteration will be the following + * element, not the given element. + * + * - "unlink": This unlinks the current element from the list before the loop + * code is run. Note that this only does a partial unlink, since + * it assumes the entire list will be unlinked. You must not + * break out of the loop, or the list will be in an inconsistent + * state. + */ + +#define c_list_for_each(_iter, _list) \ + for (_iter = (_list)->next; \ + (_iter) != (_list); \ + _iter = (_iter)->next) + +#define c_list_for_each_entry(_iter, _list, _m) \ + for (_iter = c_list_entry((_list)->next, __typeof__(*_iter), _m); \ + &(_iter)->_m != (_list); \ + _iter = c_list_entry((_iter)->_m.next, __typeof__(*_iter), _m)) + +#define c_list_for_each_safe(_iter, _safe, _list) \ + for (_iter = (_list)->next, _safe = (_iter)->next; \ + (_iter) != (_list); \ + _iter = (_safe), _safe = (_safe)->next) + +#define c_list_for_each_entry_safe(_iter, _safe, _list, _m) \ + for (_iter = c_list_entry((_list)->next, __typeof__(*_iter), _m), \ + _safe = c_list_entry((_iter)->_m.next, __typeof__(*_iter), _m); \ + &(_iter)->_m != (_list); \ + _iter = (_safe), \ + _safe = c_list_entry((_safe)->_m.next, __typeof__(*_iter), _m)) \ + +#define c_list_for_each_continue(_iter, _list) \ + for (_iter = (_iter) ? (_iter)->next : (_list)->next; \ + (_iter) != (_list); \ + _iter = (_iter)->next) + +#define c_list_for_each_entry_continue(_iter, _list, _m) \ + for (_iter = c_list_entry((_iter) ? (_iter)->_m.next : (_list)->next, \ + __typeof__(*_iter), \ + _m); \ + &(_iter)->_m != (_list); \ + _iter = c_list_entry((_iter)->_m.next, __typeof__(*_iter), _m)) + +#define c_list_for_each_safe_continue(_iter, _safe, _list) \ + for (_iter = (_iter) ? (_iter)->next : (_list)->next, \ + _safe = (_iter)->next; \ + (_iter) != (_list); \ + _iter = (_safe), _safe = (_safe)->next) + +#define c_list_for_each_entry_safe_continue(_iter, _safe, _list, _m) \ + for (_iter = c_list_entry((_iter) ? (_iter)->_m.next : (_list)->next, \ + __typeof__(*_iter), \ + _m), \ + _safe = c_list_entry((_iter)->_m.next, __typeof__(*_iter), _m); \ + &(_iter)->_m != (_list); \ + _iter = (_safe), \ + _safe = c_list_entry((_safe)->_m.next, __typeof__(*_iter), _m)) \ + +#define c_list_for_each_safe_unlink(_iter, _safe, _list) \ + for (_iter = (_list)->next, _safe = (_iter)->next; \ + ((*_iter = (CList)C_LIST_INIT(*_iter)), (_iter) != (_list)); \ + _iter = (_safe), _safe = (_safe)->next) + +#define c_list_for_each_entry_safe_unlink(_iter, _safe, _list, _m) \ + for (_iter = c_list_entry((_list)->next, __typeof__(*_iter), _m), \ + _safe = c_list_entry((_iter)->_m.next, __typeof__(*_iter), _m); \ + (((_iter)->_m = (CList)C_LIST_INIT((_iter)->_m)), \ + &(_iter)->_m != (_list)); \ + _iter = (_safe), \ + _safe = c_list_entry((_safe)->_m.next, __typeof__(*_iter), _m)) \ + +/** + * c_list_flush() - flush all entries from a list + * @list: list to flush + * + * This unlinks all entries from the given list @list and reinitializes their + * link-nodes via C_LIST_INIT(). + * + * Note that the entries are not modified in any other way, nor is their memory + * released. This function just unlinks them and resets all the list nodes. It + * is particularly useful with temporary lists on the stack in combination with + * the GCC-extension __attribute__((__cleanup__(arg))). + */ +static inline void c_list_flush(CList *list) { + CList *iter, *safe; + + c_list_for_each_safe_unlink(iter, safe, list) + /* empty */ ; +} + +/** + * c_list_length() - return number of linked entries, excluding the head + * @list: list to operate on + * + * Returns the number of entries in the list, excluding the list head @list. + * That is, for a list that is empty according to c_list_is_empty(), the + * returned length is 0. This requires to iterate the list and has thus O(n) + * runtime. + * + * Note that this function is meant for debugging purposes only. If you need + * the list size during normal operation, you should maintain a counter + * separately. + * + * Return: Number of items in @list. + */ +static inline unsigned long c_list_length(const CList *list) { + unsigned long n = 0; + const CList *iter; + + c_list_for_each(iter, list) + ++n; + + return n; +} + +/** + * c_list_contains() - check whether an entry is linked in a certain list + * @list: list to operate on + * @what: entry to look for + * + * This checks whether @what is linked into @list. This requires a linear + * search through the list, as such runs in O(n). Note that the list-head is + * considered part of the list, and hence this returns true if @what equals + * @list. + * + * Note that this function is meant for debugging purposes, and consistency + * checks. You should always be aware whether your objects are linked in a + * specific list. + * + * Return: True if @what is in @list, false otherwise. + */ +static inline _Bool c_list_contains(const CList *list, const CList *what) { + const CList *iter; + + c_list_for_each(iter, list) + if (what == iter) + return 1; + + return what == list; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/c-rbtree/src/c-rbtree-private.h b/src/c-rbtree/src/c-rbtree-private.h new file mode 100644 index 0000000..c9befbf --- /dev/null +++ b/src/c-rbtree/src/c-rbtree-private.h @@ -0,0 +1,35 @@ +#pragma once + +/* + * Private definitions + * This file contains private definitions for the RB-Tree implementation, but + * which are used by our test-suite. + */ + +#include +#include +#include "c-rbtree.h" + +/* + * Nodes + */ + +static inline void *c_rbnode_raw(CRBNode *n) { + return (void *)(n->__parent_and_flags & ~C_RBNODE_FLAG_MASK); +} + +static inline unsigned long c_rbnode_flags(CRBNode *n) { + return n->__parent_and_flags & C_RBNODE_FLAG_MASK; +} + +static inline _Bool c_rbnode_is_red(CRBNode *n) { + return c_rbnode_flags(n) & C_RBNODE_RED; +} + +static inline _Bool c_rbnode_is_black(CRBNode *n) { + return !(c_rbnode_flags(n) & C_RBNODE_RED); +} + +static inline _Bool c_rbnode_is_root(CRBNode *n) { + return c_rbnode_flags(n) & C_RBNODE_ROOT; +} diff --git a/src/c-rbtree/src/c-rbtree.c b/src/c-rbtree/src/c-rbtree.c new file mode 100644 index 0000000..2f0e608 --- /dev/null +++ b/src/c-rbtree/src/c-rbtree.c @@ -0,0 +1,1120 @@ +/* + * RB-Tree Implementation + * This implements the insertion/removal of elements in RB-Trees. You're highly + * recommended to have an RB-Tree documentation at hand when reading this. Both + * insertion and removal can be split into a handful of situations that can + * occur. Those situations are enumerated as "Case 1" to "Case n" here, and + * follow closely the cases described in most RB-Tree documentations. This file + * does not explain why it is enough to handle just those cases, nor does it + * provide a proof of correctness. Dig out your algorithm 101 handbook if + * you're interested. + * + * This implementation is *not* straightforward. Usually, a handful of + * rotation, reparent, swap and link helpers can be used to implement the + * rebalance operations. However, those often perform unnecessary writes. + * Therefore, this implementation hard-codes all the operations. You're highly + * recommended to look at the two basic helpers before reading the code: + * c_rbnode_swap_child() + * c_rbnode_set_parent_and_flags() + * Those are the only helpers used, hence, you should really know what they do + * before digging into the code. + * + * For a highlevel documentation of the API, see the header file and docbook + * comments. + */ + +#include +#include +#include +#include +#include "c-rbtree.h" +#include "c-rbtree-private.h" + +/* + * We use the lower 2 bits of CRBNode pointers to store flags. Make sure + * CRBNode is 4-byte aligned, so the lower 2 bits are actually unused. We also + * sometimes store a pointer to the root-node, so make sure this one is also 4 + * byte aligned. + * Note that there are actually some architectures where `max_align_t` is 4, so + * we do not have much wiggle-room to extend this flag-set. + */ +static_assert(alignof(CRBNode) <= alignof(max_align_t), "Invalid RBNode alignment"); +static_assert(alignof(CRBNode) >= 4, "Invalid CRBNode alignment"); +static_assert(alignof(CRBTree) <= alignof(max_align_t), "Invalid RBTree alignment"); +static_assert(alignof(CRBTree) >= 4, "Invalid CRBTree alignment"); + +/** + * c_rbnode_leftmost() - return leftmost child + * @n: current node, or NULL + * + * This returns the leftmost child of @n. If @n is NULL, this will return NULL. + * In all other cases, this function returns a valid pointer. That is, if @n + * does not have any left children, this returns @n. + * + * Worst case runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to leftmost child, or NULL. + */ +_c_public_ CRBNode *c_rbnode_leftmost(CRBNode *n) { + if (n) + while (n->left) + n = n->left; + return n; +} + +/** + * c_rbnode_rightmost() - return rightmost child + * @n: current node, or NULL + * + * This returns the rightmost child of @n. If @n is NULL, this will return + * NULL. In all other cases, this function returns a valid pointer. That is, if + * @n does not have any right children, this returns @n. + * + * Worst case runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to rightmost child, or NULL. + */ +_c_public_ CRBNode *c_rbnode_rightmost(CRBNode *n) { + if (n) + while (n->right) + n = n->right; + return n; +} + +/** + * c_rbnode_leftdeepest() - return left-deepest child + * @n: current node, or NULL + * + * This returns the left-deepest child of @n. If @n is NULL, this will return + * NULL. In all other cases, this function returns a valid pointer. That is, if + * @n does not have any children, this returns @n. + * + * The left-deepest child is defined as the deepest child without any left + * (grand-...)siblings. + * + * Worst case runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to left-deepest child, or NULL. + */ +_c_public_ CRBNode *c_rbnode_leftdeepest(CRBNode *n) { + if (n) { + for (;;) { + if (n->left) + n = n->left; + else if (n->right) + n = n->right; + else + break; + } + } + return n; +} + +/** + * c_rbnode_rightdeepest() - return right-deepest child + * @n: current node, or NULL + * + * This returns the right-deepest child of @n. If @n is NULL, this will return + * NULL. In all other cases, this function returns a valid pointer. That is, if + * @n does not have any children, this returns @n. + * + * The right-deepest child is defined as the deepest child without any right + * (grand-...)siblings. + * + * Worst case runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to right-deepest child, or NULL. + */ +_c_public_ CRBNode *c_rbnode_rightdeepest(CRBNode *n) { + if (n) { + for (;;) { + if (n->right) + n = n->right; + else if (n->left) + n = n->left; + else + break; + } + } + return n; +} + +/** + * c_rbnode_next() - return next node + * @n: current node, or NULL + * + * An RB-Tree always defines a linear order of its elements. This function + * returns the logically next node to @n. If @n is NULL, the last node or + * unlinked, this returns NULL. + * + * Worst case runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to next node, or NULL. + */ +_c_public_ CRBNode *c_rbnode_next(CRBNode *n) { + CRBNode *p; + + if (!c_rbnode_is_linked(n)) + return NULL; + if (n->right) + return c_rbnode_leftmost(n->right); + + while ((p = c_rbnode_parent(n)) && n == p->right) + n = p; + + return p; +} + +/** + * c_rbnode_prev() - return previous node + * @n: current node, or NULL + * + * An RB-Tree always defines a linear order of its elements. This function + * returns the logically previous node to @n. If @n is NULL, the first node or + * unlinked, this returns NULL. + * + * Worst case runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to previous node, or NULL. + */ +_c_public_ CRBNode *c_rbnode_prev(CRBNode *n) { + CRBNode *p; + + if (!c_rbnode_is_linked(n)) + return NULL; + if (n->left) + return c_rbnode_rightmost(n->left); + + while ((p = c_rbnode_parent(n)) && n == p->left) + n = p; + + return p; +} + +/** + * c_rbnode_next_postorder() - return next node in post-order + * @n: current node, or NULL + * + * This returns the next node to @n, based on a left-to-right post-order + * traversal. If @n is NULL, the root node, or unlinked, this returns NULL. + * + * This implements a left-to-right post-order traversal: First visit the left + * child of a node, then the right, and lastly the node itself. Children are + * traversed recursively. + * + * This function can be used to implement a left-to-right post-order traversal: + * + * for (n = c_rbtree_first_postorder(t); n; n = c_rbnode_next_postorder(n)) + * visit(n); + * + * Worst case runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to next node, or NULL. + */ +_c_public_ CRBNode *c_rbnode_next_postorder(CRBNode *n) { + CRBNode *p; + + if (!c_rbnode_is_linked(n)) + return NULL; + + p = c_rbnode_parent(n); + if (p && n == p->left && p->right) + return c_rbnode_leftdeepest(p->right); + + return p; +} + +/** + * c_rbnode_prev_postorder() - return previous node in post-order + * @n: current node, or NULL + * + * This returns the previous node to @n, based on a left-to-right post-order + * traversal. That is, it is the inverse operation to c_rbnode_next_postorder(). + * If @n is NULL, the left-deepest node, or unlinked, this returns NULL. + * + * This function returns the logical previous node in a directed post-order + * traversal. That is, it effectively does a pre-order traversal (since a + * reverse post-order traversal is a pre-order traversal). This function does + * NOT do a right-to-left post-order traversal! In other words, the following + * invariant is guaranteed, if c_rbnode_next_postorder(n) is non-NULL: + * + * n == c_rbnode_prev_postorder(c_rbnode_next_postorder(n)) + * + * This function can be used to implement a right-to-left pre-order traversal, + * using the fact that a reverse post-order traversal is also a valid pre-order + * traversal: + * + * for (n = c_rbtree_last_postorder(t); n; n = c_rbnode_prev_postorder(n)) + * visit(n); + * + * This would effectively perform a right-to-left pre-order traversal: first + * visit a parent, then its right child, then its left child. Both children are + * traversed recursively. + * + * Worst case runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to previous node in post-order, or NULL. + */ +_c_public_ CRBNode *c_rbnode_prev_postorder(CRBNode *n) { + CRBNode *p; + + if (!c_rbnode_is_linked(n)) + return NULL; + if (n->right) + return n->right; + if (n->left) + return n->left; + + while ((p = c_rbnode_parent(n))) { + if (p->left && n != p->left) + return p->left; + n = p; + } + + return NULL; +} + +/** + * c_rbtree_first() - return first node + * @t: tree to operate on + * + * An RB-Tree always defines a linear order of its elements. This function + * returns the logically first node in @t. If @t is empty, NULL is returned. + * + * Fixed runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to first node, or NULL. + */ +_c_public_ CRBNode *c_rbtree_first(CRBTree *t) { + c_assert(t); + return c_rbnode_leftmost(t->root); +} + +/** + * c_rbtree_last() - return last node + * @t: tree to operate on + * + * An RB-Tree always defines a linear order of its elements. This function + * returns the logically last node in @t. If @t is empty, NULL is returned. + * + * Fixed runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to last node, or NULL. + */ +_c_public_ CRBNode *c_rbtree_last(CRBTree *t) { + c_assert(t); + return c_rbnode_rightmost(t->root); +} + +/** + * c_rbtree_first_postorder() - return first node in post-order + * @t: tree to operate on + * + * This returns the first node of a left-to-right post-order traversal. That + * is, it returns the left-deepest leaf. If the tree is empty, this returns + * NULL. + * + * This can also be interpreted as the last node of a right-to-left pre-order + * traversal. + * + * Fixed runtime (n: number of elements in tree): O(log(n)) + * + * Return: Pointer to first node in post-order, or NULL. + */ +_c_public_ CRBNode *c_rbtree_first_postorder(CRBTree *t) { + c_assert(t); + return c_rbnode_leftdeepest(t->root); +} + +/** + * c_rbtree_last_postorder() - return last node in post-order + * @t: tree to operate on + * + * This returns the last node of a left-to-right post-order traversal. That is, + * it always returns the root node, or NULL if the tree is empty. + * + * This can also be interpreted as the first node of a right-to-left pre-order + * traversal. + * + * Fixed runtime (n: number of elements in tree): O(1) + * + * Return: Pointer to last node in post-order, or NULL. + */ +_c_public_ CRBNode *c_rbtree_last_postorder(CRBTree *t) { + c_assert(t); + return t->root; +} + +static inline void c_rbtree_store(CRBNode **ptr, CRBNode *addr) { + /* + * We use volatile accesses whenever we STORE @left or @right members + * of a node. This guarantees that any parallel, lockless lookup gets + * to see those stores in the correct order, which itself guarantees + * that there're no temporary loops during tree rotation. + * Note that you still need to properly synchronize your accesses via + * seqlocks, rcu, whatever. We just guarantee that you get *some* + * result on a lockless traversal and never run into endless loops, or + * undefined behavior. + */ + *(volatile CRBNode **)ptr = addr; +} + +/* + * Set the flags and parent of a node. This should be treated as a simple + * assignment of the 'flags' and 'parent' fields of the node. No other magic is + * applied. But since both fields share its backing memory, this helper + * function is provided. + */ +static inline void c_rbnode_set_parent_and_flags(CRBNode *n, CRBNode *p, unsigned long flags) { + n->__parent_and_flags = (unsigned long)p | flags; +} + +/* + * Nodes in the tree do not separately store a point to the tree root. That is, + * there is no way to access the tree-root in O(1) given an arbitrary node. + * Fortunately, this is usually not required. The only situation where this is + * needed is when rotating the root-node itself. + * + * In case of the root node, c_rbnode_parent() returns NULL. We use this fact + * to re-use the parent-pointer storage of the root node to point to the + * CRBTree root. This way, we can rotate the root-node (or add/remove it) + * without requiring a separate tree-root pointer. + * + * However, to keep the tree-modification functions simple, we hide this detail + * whenever possible. This means, c_rbnode_parent() will continue to return + * NULL, and tree modifications will boldly reset the pointer to NULL on + * rotation. Hence, the only way to retain this pointer is to call + * c_rbnode_pop_root() on a possible root-node before rotating. This returns + * NULL if the node in question is not the root node. Otherwise, it returns the + * tree-root, and clears the pointer/flag from the node in question. This way, + * you can perform tree operations as usual. Afterwards, use + * c_rbnode_push_root() to restore the root-pointer on any possible new root. + */ +static inline CRBTree *c_rbnode_pop_root(CRBNode *n) { + CRBTree *t = NULL; + + if (c_rbnode_is_root(n)) { + t = c_rbnode_raw(n); + n->__parent_and_flags = c_rbnode_flags(n) & ~C_RBNODE_ROOT; + } + + return t; +} + +/* counter-part to c_rbnode_pop_root() */ +static inline CRBTree *c_rbnode_push_root(CRBNode *n, CRBTree *t) { + if (t) { + if (n) + n->__parent_and_flags = (unsigned long)t + | c_rbnode_flags(n) + | C_RBNODE_ROOT; + c_rbtree_store(&t->root, n); + } + + return NULL; +} + +/* + * This function partially swaps a child node with another one. That is, this + * function changes the parent of @old to point to @new. That is, you use it + * when swapping @old with @new, to update the parent's left/right pointer. + * This function does *NOT* perform a full swap, nor does it touch any 'parent' + * pointer. + * + * The sole purpose of this function is to shortcut left/right conditionals + * like this: + * + * if (old == old->parent->left) + * old->parent->left = new; + * else + * old->parent->right = new; + * + * That's it! If @old is the root node, this will do nothing. The caller must + * employ c_rbnode_pop_root() and c_rbnode_push_root(). + */ +static inline void c_rbnode_swap_child(CRBNode *old, CRBNode *new) { + CRBNode *p = c_rbnode_parent(old); + + if (p) { + if (p->left == old) + c_rbtree_store(&p->left, new); + else + c_rbtree_store(&p->right, new); + } +} + +/** + * c_rbtree_move() - move tree + * @to: destination tree + * @from: source tree + * + * This imports the entire tree from @from into @to. @to must be empty! @from + * will be empty afterwards. + * + * Note that this operates in O(1) time. Only the root-entry is updated to + * point to the new tree-root. + */ +_c_public_ void c_rbtree_move(CRBTree *to, CRBTree *from) { + CRBTree *t; + + c_assert(!to->root); + + if (from->root) { + t = c_rbnode_pop_root(from->root); + c_assert(t == from); + + to->root = from->root; + from->root = NULL; + + c_rbnode_push_root(to->root, to); + } +} + +static inline void c_rbtree_paint_terminal(CRBNode *n) { + CRBNode *p, *g, *gg, *x; + CRBTree *t; + + /* + * Case 4: + * This path assumes @n is red, @p is red, but the uncle is unset or + * black. This implies @g exists and is black. + * + * This case requires up to 2 rotations to restore the tree invariants. + * That is, it runs in O(1) time and fully restores the RB-Tree + * invariants, all at the cost of performing at mots 2 rotations. + */ + + p = c_rbnode_parent(n); + g = c_rbnode_parent(p); + gg = c_rbnode_parent(g); + + c_assert(c_rbnode_is_red(p)); + c_assert(c_rbnode_is_black(g)); + c_assert(p == g->left || !g->left || c_rbnode_is_black(g->left)); + c_assert(p == g->right || !g->right || c_rbnode_is_black(g->right)); + + if (p == g->left) { + if (n == p->right) { + /* + * We're the right red child of a red parent, which is + * a left child. Rotate on parent and consider us to be + * the old parent and the old parent to be us, making us + * the left child instead of the right child so we can + * handle it the same as below. Rotating two red nodes + * changes none of the invariants. + */ + x = n->left; + c_rbtree_store(&p->right, x); + c_rbtree_store(&n->left, p); + if (x) + c_rbnode_set_parent_and_flags(x, p, c_rbnode_flags(x)); + c_rbnode_set_parent_and_flags(p, n, c_rbnode_flags(p)); + p = n; + } + + /* 'n' is invalid from here on! */ + + /* + * We're the red left child of a red parent, black grandparent + * and uncle. Rotate parent on grandparent and switch their + * colors, making the parent black and the grandparent red. The + * root of this subtree was changed from the grandparent to the + * parent, but the color remained black, so the number of black + * nodes on each path stays the same. However, we got rid of + * the double red path as we are still the (red) child of the + * parent, which has now turned black. Note that had we been + * the right child, rather than the left child, we would now be + * the left child of the old grandparent, and we would still + * have a double red path. As the new grandparent remains + * black, we're done. + */ + x = p->right; + t = c_rbnode_pop_root(g); + c_rbtree_store(&g->left, x); + c_rbtree_store(&p->right, g); + c_rbnode_swap_child(g, p); + if (x) + c_rbnode_set_parent_and_flags(x, g, c_rbnode_flags(x) & ~C_RBNODE_RED); + c_rbnode_set_parent_and_flags(p, gg, c_rbnode_flags(p) & ~C_RBNODE_RED); + c_rbnode_set_parent_and_flags(g, p, c_rbnode_flags(g) | C_RBNODE_RED); + c_rbnode_push_root(p, t); + } else /* if (p == g->right) */ { /* same as above, but mirrored */ + if (n == p->left) { + x = n->right; + c_rbtree_store(&p->left, n->right); + c_rbtree_store(&n->right, p); + if (x) + c_rbnode_set_parent_and_flags(x, p, c_rbnode_flags(x)); + c_rbnode_set_parent_and_flags(p, n, c_rbnode_flags(p)); + p = n; + } + + x = p->left; + t = c_rbnode_pop_root(g); + c_rbtree_store(&g->right, x); + c_rbtree_store(&p->left, g); + c_rbnode_swap_child(g, p); + if (x) + c_rbnode_set_parent_and_flags(x, g, c_rbnode_flags(x) & ~C_RBNODE_RED); + c_rbnode_set_parent_and_flags(p, gg, c_rbnode_flags(p) & ~C_RBNODE_RED); + c_rbnode_set_parent_and_flags(g, p, c_rbnode_flags(g) | C_RBNODE_RED); + c_rbnode_push_root(p, t); + } +} + +static inline CRBNode *c_rbtree_paint_path(CRBNode *n) { + CRBNode *p, *g, *u; + + for (;;) { + p = c_rbnode_parent(n); + if (!p) { + /* + * Case 1: + * We reached the root. Mark it black and be done. As + * all leaf-paths share the root, the ratio of black + * nodes on each path stays the same. + */ + c_rbnode_set_parent_and_flags(n, c_rbnode_raw(n), c_rbnode_flags(n) & ~C_RBNODE_RED); + return NULL; + } else if (c_rbnode_is_black(p)) { + /* + * Case 2: + * The parent is already black. As our node is red, we + * did not change the number of black nodes on any + * path, nor do we have multiple consecutive red nodes. + * There is nothing to be done. + */ + return NULL; + } + + g = c_rbnode_parent(p); + u = (p == g->left) ? g->right : g->left; + if (!u || !c_rbnode_is_red(u)) { + /* + * Case 4: + * The parent is red, but its uncle is black. By + * rotating the parent above the uncle, we distribute + * the red nodes and thus restore the tree invariants. + * No recursive fixup will be needed afterwards. Hence, + * just let the caller know about @n and make them do + * the rotations. + */ + return n; + } + + /* + * Case 3: + * Parent and uncle are both red, and grandparent is black. + * Repaint parent and uncle black, the grandparent red and + * recurse into the grandparent. Note that this is the only + * recursive case. That is, this step restores the tree + * invariants for the sub-tree below @p (including @n), but + * needs to continue the re-coloring two levels up. + */ + c_rbnode_set_parent_and_flags(p, g, c_rbnode_flags(p) & ~C_RBNODE_RED); + c_rbnode_set_parent_and_flags(u, g, c_rbnode_flags(u) & ~C_RBNODE_RED); + c_rbnode_set_parent_and_flags(g, c_rbnode_raw(g), c_rbnode_flags(g) | C_RBNODE_RED); + n = g; + } +} + +static inline void c_rbtree_paint(CRBNode *n) { + /* + * When a new node is inserted into an RB-Tree, we always link it as a + * tail-node and paint it red. This way, the node will not violate the + * rb-tree invariants regarding the number of black nodes on all paths. + * + * However, a red node must never have another bordering red-node (ie., + * child or parent). Since the node is newly linked, it does not have + * any children. Therefore, all we need to do is fix the path upwards + * through all parents until we hit a black parent or can otherwise fix + * the coloring. + * + * This function first walks up the path from @n towards the tree root + * (done in c_rbtree_paint_path()). This recolors its parent/uncle, if + * possible, until it hits a sub-tree that cannot be fixed via + * re-coloring. After c_rbtree_paint_path() returns, there are two + * possible outcomes: + * + * 1) @n is NULL, in which case the tree invariants were + * restored by mere recoloring. Nothing is to be done. + * + * 2) @n is non-NULL, but points to a red ancestor of the + * original node. In this case we need to restore the tree + * invariants via a simple left or right rotation. This will + * be done by c_rbtree_paint_terminal(). + * + * As a summary, this function runs O(log(n)) re-coloring operations in + * the worst case, followed by O(1) rotations as final restoration. The + * amortized cost, however, is O(1), since re-coloring only recurses + * upwards if it hits a red uncle (which can only happen if a previous + * operation terminated its operation on that layer). + * While amortized painting of inserted nodes is O(1), finding the + * correct spot to link the node (before painting it) still requires a + * search in the binary tree in O(log(n)). + */ + n = c_rbtree_paint_path(n); + if (n) + c_rbtree_paint_terminal(n); +} + +/** + * c_rbnode_link() - link node into tree + * @p: parent node to link under + * @l: left/right slot of @p to link at + * @n: node to add + * + * This links @n into an tree underneath another node. The caller must provide + * the exact spot where to link the node. That is, the caller must traverse the + * tree based on their search order. Once they hit a leaf where to insert the + * node, call this function to link it and rebalance the tree. + * + * For this to work, the caller must provide a pointer to the parent node. If + * the tree might be empty, you must resort to c_rbtree_add(). + * + * In most cases you are better off using c_rbtree_add(). See there for details + * how tree-insertion works. + */ +_c_public_ void c_rbnode_link(CRBNode *p, CRBNode **l, CRBNode *n) { + c_assert(p); + c_assert(l); + c_assert(n); + c_assert(l == &p->left || l == &p->right); + + c_rbnode_set_parent_and_flags(n, p, C_RBNODE_RED); + c_rbtree_store(&n->left, NULL); + c_rbtree_store(&n->right, NULL); + c_rbtree_store(l, n); + + c_rbtree_paint(n); +} + +/** + * c_rbtree_add() - add node to tree + * @t: tree to operate one + * @p: parent node to link under, or NULL + * @l: left/right slot of @p (or root) to link at + * @n: node to add + * + * This links @n into the tree given as @t. The caller must provide the exact + * spot where to link the node. That is, the caller must traverse the tree + * based on their search order. Once they hit a leaf where to insert the node, + * call this function to link it and rebalance the tree. + * + * A typical insertion would look like this (@t is your tree, @n is your node): + * + * CRBNode **i, *p; + * + * i = &t->root; + * p = NULL; + * while (*i) { + * p = *i; + * if (compare(n, *i) < 0) + * i = &(*i)->left; + * else + * i = &(*i)->right; + * } + * + * c_rbtree_add(t, p, i, n); + * + * Once the node is linked into the tree, a simple lookup on the same tree can + * be coded like this: + * + * CRBNode *i; + * + * i = t->root; + * while (i) { + * int v = compare(n, i); + * if (v < 0) + * i = (*i)->left; + * else if (v > 0) + * i = (*i)->right; + * else + * break; + * } + * + * When you add nodes to a tree, the memory contents of the node do not matter. + * That is, there is no need to initialize the node via c_rbnode_init(). + * However, if you relink nodes multiple times during their lifetime, it is + * usually very convenient to use c_rbnode_init() and c_rbnode_unlink() (rather + * than c_rbnode_unlink_stale()). In those cases, you should validate that a + * node is unlinked before you call c_rbtree_add(). + */ +_c_public_ void c_rbtree_add(CRBTree *t, CRBNode *p, CRBNode **l, CRBNode *n) { + c_assert(t); + c_assert(l); + c_assert(n); + c_assert(!p || l == &p->left || l == &p->right); + c_assert(p || l == &t->root); + + c_rbnode_set_parent_and_flags(n, p, C_RBNODE_RED); + c_rbtree_store(&n->left, NULL); + c_rbtree_store(&n->right, NULL); + + if (p) + c_rbtree_store(l, n); + else + c_rbnode_push_root(n, t); + + c_rbtree_paint(n); +} + +static inline void c_rbnode_rebalance_terminal(CRBNode *p, CRBNode *previous) { + CRBNode *s, *x, *y, *g; + CRBTree *t; + + if (previous == p->left) { + s = p->right; + if (c_rbnode_is_red(s)) { + /* + * Case 2: + * We have a red node as sibling. Rotate it onto our + * side so we can later on turn it black. This way, we + * gain the additional black node in our path. + */ + t = c_rbnode_pop_root(p); + g = c_rbnode_parent(p); + x = s->left; + c_rbtree_store(&p->right, x); + c_rbtree_store(&s->left, p); + c_rbnode_swap_child(p, s); + c_rbnode_set_parent_and_flags(x, p, c_rbnode_flags(x) & ~C_RBNODE_RED); + c_rbnode_set_parent_and_flags(s, g, c_rbnode_flags(s) & ~C_RBNODE_RED); + c_rbnode_set_parent_and_flags(p, s, c_rbnode_flags(p) | C_RBNODE_RED); + c_rbnode_push_root(s, t); + s = x; + } + + x = s->right; + if (!x || c_rbnode_is_black(x)) { + y = s->left; + if (!y || c_rbnode_is_black(y)) { + /* + * Case 3+4: + * Our sibling is black and has only black + * children. Flip it red and turn parent black. + * This way we gained a black node in our path. + * Note that the parent must be red, otherwise + * it must have been handled by our caller. + */ + c_assert(c_rbnode_is_red(p)); + c_rbnode_set_parent_and_flags(s, p, c_rbnode_flags(s) | C_RBNODE_RED); + c_rbnode_set_parent_and_flags(p, c_rbnode_parent(p), c_rbnode_flags(p) & ~C_RBNODE_RED); + return; + } + + /* + * Case 5: + * Left child of our sibling is red, right one is black. + * Rotate on parent so the right child of our sibling is + * now red, and we can fall through to case 6. + */ + x = y->right; + c_rbtree_store(&s->left, y->right); + c_rbtree_store(&y->right, s); + c_rbtree_store(&p->right, y); + if (x) + c_rbnode_set_parent_and_flags(x, s, c_rbnode_flags(x) & ~C_RBNODE_RED); + x = s; + s = y; + } + + /* + * Case 6: + * The right child of our sibling is red. Rotate left and flip + * colors, which gains us an additional black node in our path, + * that was previously on our sibling. + */ + t = c_rbnode_pop_root(p); + g = c_rbnode_parent(p); + y = s->left; + c_rbtree_store(&p->right, y); + c_rbtree_store(&s->left, p); + c_rbnode_swap_child(p, s); + c_rbnode_set_parent_and_flags(x, s, c_rbnode_flags(x) & ~C_RBNODE_RED); + if (y) + c_rbnode_set_parent_and_flags(y, p, c_rbnode_flags(y)); + c_rbnode_set_parent_and_flags(s, g, c_rbnode_flags(p)); + c_rbnode_set_parent_and_flags(p, s, c_rbnode_flags(p) & ~C_RBNODE_RED); + c_rbnode_push_root(s, t); + } else /* if (previous == p->right) */ { /* same as above, but mirrored */ + s = p->left; + if (c_rbnode_is_red(s)) { + t = c_rbnode_pop_root(p); + g = c_rbnode_parent(p); + x = s->right; + c_rbtree_store(&p->left, x); + c_rbtree_store(&s->right, p); + c_rbnode_swap_child(p, s); + c_rbnode_set_parent_and_flags(x, p, c_rbnode_flags(x) & ~C_RBNODE_RED); + c_rbnode_set_parent_and_flags(s, g, c_rbnode_flags(s) & ~C_RBNODE_RED); + c_rbnode_set_parent_and_flags(p, s, c_rbnode_flags(p) | C_RBNODE_RED); + c_rbnode_push_root(s, t); + s = x; + } + + x = s->left; + if (!x || c_rbnode_is_black(x)) { + y = s->right; + if (!y || c_rbnode_is_black(y)) { + c_assert(c_rbnode_is_red(p)); + c_rbnode_set_parent_and_flags(s, p, c_rbnode_flags(s) | C_RBNODE_RED); + c_rbnode_set_parent_and_flags(p, c_rbnode_parent(p), c_rbnode_flags(p) & ~C_RBNODE_RED); + return; + } + + x = y->left; + c_rbtree_store(&s->right, y->left); + c_rbtree_store(&y->left, s); + c_rbtree_store(&p->left, y); + if (x) + c_rbnode_set_parent_and_flags(x, s, c_rbnode_flags(x) & ~C_RBNODE_RED); + x = s; + s = y; + } + + t = c_rbnode_pop_root(p); + g = c_rbnode_parent(p); + y = s->right; + c_rbtree_store(&p->left, y); + c_rbtree_store(&s->right, p); + c_rbnode_swap_child(p, s); + c_rbnode_set_parent_and_flags(x, s, c_rbnode_flags(x) & ~C_RBNODE_RED); + if (y) + c_rbnode_set_parent_and_flags(y, p, c_rbnode_flags(y)); + c_rbnode_set_parent_and_flags(s, g, c_rbnode_flags(p)); + c_rbnode_set_parent_and_flags(p, s, c_rbnode_flags(p) & ~C_RBNODE_RED); + c_rbnode_push_root(s, t); + } +} + +static inline CRBNode *c_rbnode_rebalance_path(CRBNode *p, CRBNode **previous) { + CRBNode *s, *nl, *nr; + + while (p) { + s = (*previous == p->left) ? p->right : p->left; + nl = s->left; + nr = s->right; + + /* + * If the sibling under @p is black and exclusively has black + * children itself (i.e., nephews/nieces in @nl/@nr), then we + * can easily re-color to fix this sub-tree, and continue one + * layer up. However, if that's not the case, we have tree + * rotations at our hands to move one of the black nodes into + * our path, then turning the red node black to fully restore + * the RB-Tree invariants again. This fixup will be done by the + * caller, so we just let them know where to do that. + */ + if (c_rbnode_is_red(s) || + (nl && c_rbnode_is_red(nl)) || + (nr && c_rbnode_is_red(nr))) + return p; + + /* + * Case 3+4: + * Sibling is black, and all nephews/nieces are black. Flip + * sibling red. This way the sibling lost a black node in its + * path, thus getting even with our path. However, paths not + * going through @p haven't been fixed up, hence we proceed + * recursively one layer up. + * Before we continue one layer up, there are two possible + * terminations: If the parent is red, we can turn it black. + * This terminates the rebalancing, since the entire point of + * rebalancing is that everything below @p has one black node + * less than everything else. Lastly, if there is no layer + * above, we hit the tree root and nothing is left to be done. + */ + c_rbnode_set_parent_and_flags(s, p, c_rbnode_flags(s) | C_RBNODE_RED); + if (c_rbnode_is_red(p)) { + c_rbnode_set_parent_and_flags(p, c_rbnode_parent(p), c_rbnode_flags(p) & ~C_RBNODE_RED); + return NULL; + } + + *previous = p; + p = c_rbnode_parent(p); + } + + return NULL; +} + +static inline void c_rbnode_rebalance(CRBNode *n) { + CRBNode *previous = NULL; + + /* + * Rebalance a tree after a node was removed. This function must be + * called on the parent of the leaf that was removed. It will first + * perform a recursive re-coloring on the parents of @n, until it + * either hits the tree-root, or a condition where a tree-rotation is + * needed to restore the RB-Tree invariants. + */ + + n = c_rbnode_rebalance_path(n, &previous); + if (n) + c_rbnode_rebalance_terminal(n, previous); +} + +/** + * c_rbnode_unlink_stale() - remove node from tree + * @n: node to remove + * + * This removes the given node from its tree. Once unlinked, the tree is + * rebalanced. + * + * This does *NOT* reset @n to being unlinked. If you need this, use + * c_rbtree_unlink(). + */ +_c_public_ void c_rbnode_unlink_stale(CRBNode *n) { + CRBTree *t; + + c_assert(n); + c_assert(c_rbnode_is_linked(n)); + + /* + * There are three distinct cases during node removal of a tree: + * * The node has no children, in which case it can simply be removed. + * * The node has exactly one child, in which case the child displaces + * its parent. + * * The node has two children, in which case there is guaranteed to + * be a successor to the node (successor being the node ordered + * directly after it). This successor is the leftmost descendant of + * the node's right child, so it cannot have a left child of its own. + * Therefore, we can simply swap the node with its successor (including + * color) and remove the node from its new place, which will be one of + * the first two cases. + * + * Whenever the node we removed was black, we have to rebalance the + * tree. Note that this affects the actual node we _remove_, not @n (in + * case we swap it). + */ + + if (!n->left && !n->right) { + /* + * Case 1.0 + * The node has no children, it is a leaf-node and we + * can simply unlink it. If it was also black, we have + * to rebalance. + */ + t = c_rbnode_pop_root(n); + c_rbnode_swap_child(n, NULL); + c_rbnode_push_root(NULL, t); + + if (c_rbnode_is_black(n)) + c_rbnode_rebalance(c_rbnode_parent(n)); + } else if (!n->left && n->right) { + /* + * Case 1.1: + * The node has exactly one child, and it is on the + * right. The child *must* be red (otherwise, the right + * path has more black nodes than the non-existing left + * path), and the node to be removed must hence be + * black. We simply replace the node with its child, + * turning the red child black, and thus no rebalancing + * is required. + */ + t = c_rbnode_pop_root(n); + c_rbnode_swap_child(n, n->right); + c_rbnode_set_parent_and_flags(n->right, c_rbnode_parent(n), c_rbnode_flags(n->right) & ~C_RBNODE_RED); + c_rbnode_push_root(n->right, t); + } else if (n->left && !n->right) { + /* + * Case 1.2: + * The node has exactly one child, and it is on the left. Treat + * it as mirrored case of Case 1.1 (i.e., replace the node by + * its child). + */ + t = c_rbnode_pop_root(n); + c_rbnode_swap_child(n, n->left); + c_rbnode_set_parent_and_flags(n->left, c_rbnode_parent(n), c_rbnode_flags(n->left) & ~C_RBNODE_RED); + c_rbnode_push_root(n->left, t); + } else /* if (n->left && n->right) */ { + CRBNode *s, *p, *c, *next = NULL; + + /* Cache possible tree-root during tree-rotations. */ + t = c_rbnode_pop_root(n); + + /* + * Case 1.3: + * We are dealing with a full interior node with a child on + * both sides. We want to find its successor and swap it, + * then remove the node similar to Case 1. For performance + * reasons we don't perform the full swap, but skip links + * that are about to be removed, anyway. + * + * First locate the successor, remember its child and the + * parent the original node should have been linked on, + * before being removed. Then link up both the successor's + * new children and old child. + * + * s: successor + * p: parent + * c: right (and only potential) child of successor + * next: next node to rebalance on + */ + s = n->right; + if (!s->left) { + /* + * The immediate right child is the successor, + * the successor's right child remains linked + * as before. + */ + p = s; + c = s->right; + } else { + s = c_rbnode_leftmost(s); + p = c_rbnode_parent(s); + c = s->right; + + /* + * The new parent pointer of the successor's + * child is set below. + */ + c_rbtree_store(&p->left, c); + + c_rbtree_store(&s->right, n->right); + c_rbnode_set_parent_and_flags(n->right, s, c_rbnode_flags(n->right)); + } + + /* + * In both the above cases, the successor's left child + * needs to be replaced with the left child of the node + * that is being removed. + */ + c_rbtree_store(&s->left, n->left); + c_rbnode_set_parent_and_flags(n->left, s, c_rbnode_flags(n->left)); + + /* + * As in cases 1.1 and 1.0 above, if successor was a + * black leaf, we need to rebalance the tree, otherwise + * it must have a red child, so simply recolor that black + * and continue. Note that @next must be stored here, as + * the original color of the successor is forgotten below. + */ + if (c) + c_rbnode_set_parent_and_flags(c, p, c_rbnode_flags(c) & ~C_RBNODE_RED); + else + next = c_rbnode_is_black(s) ? p : NULL; + + /* + * Update the successor, to inherit the parent and color + * from the node being removed. + */ + if (c_rbnode_is_red(n)) + c_rbnode_set_parent_and_flags(s, c_rbnode_parent(n), c_rbnode_flags(s) | C_RBNODE_RED); + else + c_rbnode_set_parent_and_flags(s, c_rbnode_parent(n), c_rbnode_flags(s) & ~C_RBNODE_RED); + + /* + * Update the parent of the node being removed. Note that this + * needs to happen after the parent of the successor is set + * above, as that call would clear the root pointer, if set. + */ + c_rbnode_swap_child(n, s); + + /* Possibly restore saved tree-root. */ + c_rbnode_push_root(s, t); + + if (next) + c_rbnode_rebalance(next); + } +} diff --git a/src/c-rbtree/src/c-rbtree.h b/src/c-rbtree/src/c-rbtree.h new file mode 100644 index 0000000..d4d0fe4 --- /dev/null +++ b/src/c-rbtree/src/c-rbtree.h @@ -0,0 +1,437 @@ +#pragma once + +/** + * Standalone Red-Black-Tree Implementation in Standard ISO-C11 + * + * This library provides an RB-Tree API, that is fully implemented in ISO-C11 + * and has no external dependencies. Furthermore, tree traversal, memory + * allocations, and key comparisons are completely controlled by the API user. + * The implementation only provides the RB-Tree specific rebalancing and + * coloring. + * + * A tree is represented by the "CRBTree" structure. It contains a *single* + * field, which is a pointer to the root node. If NULL, the tree is empty. If + * non-NULL, there is at least a single element in the tree. + * + * Each node of the tree is represented by the "CRBNode" structure. It has + * three fields. The @left and @right members can be accessed by the API user + * directly to traverse the tree. The third member is a combination of the + * parent pointer and a set of flags. + * API users are required to embed the CRBNode object into their own objects + * and then use offsetof() (i.e., container_of() and friends) to turn CRBNode + * pointers into pointers to their own structure. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +typedef struct CRBNode CRBNode; +typedef struct CRBTree CRBTree; + +/* implementation detail */ +#define C_RBNODE_RED (0x1UL) +#define C_RBNODE_ROOT (0x2UL) +#define C_RBNODE_FLAG_MASK (0x3UL) + +/** + * struct CRBNode - Node of a Red-Black Tree + * @__parent_and_flags: internal state + * @left: left child, or NULL + * @right: right child, or NULL + * + * Each node in an RB-Tree must embed a CRBNode object. This object contains + * pointers to its left and right child, which can be freely accessed by the + * API user at any time. They are NULL, if the node does not have a left/right + * child. + * + * The @__parent_and_flags field must never be accessed directly. It encodes + * the pointer to the parent node, and the color of the node. Use the accessor + * functions instead. + * + * There is no reason to initialize a CRBNode object before linking it. + * However, if you need a boolean state that tells you whether the node is + * linked or not, you should initialize the node via c_rbnode_init() or + * C_RBNODE_INIT. + */ +struct CRBNode { + union { + unsigned long __parent_and_flags; + /* enforce >=4-byte alignment for @__parent_and_flags */ + alignas(4) unsigned char __align_dummy; + }; + CRBNode *left; + CRBNode *right; +}; + +#define C_RBNODE_INIT(_var) { .__parent_and_flags = (unsigned long)&(_var) } + +CRBNode *c_rbnode_leftmost(CRBNode *n); +CRBNode *c_rbnode_rightmost(CRBNode *n); +CRBNode *c_rbnode_leftdeepest(CRBNode *n); +CRBNode *c_rbnode_rightdeepest(CRBNode *n); +CRBNode *c_rbnode_next(CRBNode *n); +CRBNode *c_rbnode_prev(CRBNode *n); +CRBNode *c_rbnode_next_postorder(CRBNode *n); +CRBNode *c_rbnode_prev_postorder(CRBNode *n); + +void c_rbnode_link(CRBNode *p, CRBNode **l, CRBNode *n); +void c_rbnode_unlink_stale(CRBNode *n); + +/** + * struct CRBTree - Red-Black Tree + * @root: pointer to the root node, or NULL + * + * Each Red-Black Tree is rooted in an CRBTree object. This object contains a + * pointer to the root node of the tree. The API user is free to access the + * @root member at any time, and use it to traverse the tree. + * + * To initialize an RB-Tree, set it to NULL / all zero. + */ +struct CRBTree { + union { + CRBNode *root; + /* enforce >=4-byte alignment for @root */ + alignas(4) unsigned char __align_dummy; + }; +}; + +#define C_RBTREE_INIT {} + +CRBNode *c_rbtree_first(CRBTree *t); +CRBNode *c_rbtree_last(CRBTree *t); +CRBNode *c_rbtree_first_postorder(CRBTree *t); +CRBNode *c_rbtree_last_postorder(CRBTree *t); + +void c_rbtree_move(CRBTree *to, CRBTree *from); +void c_rbtree_add(CRBTree *t, CRBNode *p, CRBNode **l, CRBNode *n); + +/** + * c_rbnode_init() - mark a node as unlinked + * @n: node to operate on + * + * This marks the node @n as unlinked. The node will be set to a valid state + * that can never happen if the node is linked in a tree. Furthermore, this + * state is fully known to the implementation, and as such handled gracefully + * in all cases. + * + * You are *NOT* required to call this on your node. c_rbtree_add() can handle + * uninitialized nodes just fine. However, calling this allows to use + * c_rbnode_is_linked() to check for the state of a node. Furthermore, + * iterators and accessors can be called on initialized (yet unlinked) nodes. + * + * Use the C_RBNODE_INIT macro if you want to initialize static variables. + */ +static inline void c_rbnode_init(CRBNode *n) { + *n = (CRBNode)C_RBNODE_INIT(*n); +} + +/** + * c_rbnode_entry() - get parent container of tree node + * @_what: tree node, or NULL + * @_t: type of parent container + * @_m: member name of tree node in @_t + * + * If the tree node @_what is embedded into a surrounding structure, this will + * turn the tree node pointer @_what into a pointer to the parent container + * (using offsetof(3), or sometimes called container_of(3)). + * + * If @_what is NULL, this will also return NULL. + * + * Return: Pointer to parent container, or NULL. + */ +#define c_rbnode_entry(_what, _t, _m) \ + ((_t *)(void *)(((unsigned long)(void *)(_what) ?: \ + offsetof(_t, _m)) - offsetof(_t, _m))) + +/** + * c_rbnode_parent() - return parent pointer + * @n node to access + * + * This returns a pointer to the parent of the given node @n. If @n does not + * have a parent, NULL is returned. If @n is not linked, @n itself is returned. + * + * You should not call this on unlinked or uninitialized nodes! If you do, you + * better know its semantics. + * + * Return: Pointer to parent. + */ +static inline CRBNode *c_rbnode_parent(CRBNode *n) { + return (n->__parent_and_flags & C_RBNODE_ROOT) ? + NULL : + (void *)(n->__parent_and_flags & ~C_RBNODE_FLAG_MASK); +} + +/** + * c_rbnode_is_linked() - check whether a node is linked + * @n: node to check, or NULL + * + * This checks whether the passed node is linked. If you pass NULL, or if the + * node is not linked into a tree, this will return false. Otherwise, this + * returns true. + * + * Note that you must have either linked the node or initialized it, before + * calling this function. Never call this function on uninitialized nodes. + * Furthermore, removing a node via c_rbnode_unlink_stale() does *NOT* mark the + * node as unlinked. You have to call c_rbnode_init() yourself after removal, or + * use the c_rbnode_unlink() helper. + * + * Return: true if the node is linked, false if not. + */ +static inline _Bool c_rbnode_is_linked(CRBNode *n) { + return n && c_rbnode_parent(n) != n; +} + +/** + * c_rbnode_unlink() - safely remove node from tree and reinitialize it + * @n: node to remove, or NULL + * + * This is almost the same as c_rbnode_unlink_stale(), but extends it slightly, to be + * more convenient to use in many cases: + * - if @n is unlinked or NULL, this is a no-op + * - @n is reinitialized after being removed + */ +static inline void c_rbnode_unlink(CRBNode *n) { + if (c_rbnode_is_linked(n)) { + c_rbnode_unlink_stale(n); + c_rbnode_init(n); + } +} + +/** + * c_rbtree_init() - initialize a new RB-Tree + * @t: tree to operate on + * + * This initializes a new, empty RB-Tree. An RB-Tree must be initialized before + * any other functions are called on it. Alternatively, you can zero its memory + * or assign C_RBTREE_INIT. + */ +static inline void c_rbtree_init(CRBTree *t) { + *t = (CRBTree)C_RBTREE_INIT; +} + +/** + * c_rbtree_is_empty() - check whether an RB-tree is empty + * @t: tree to operate on + * + * This checks whether the passed RB-Tree is empty. + * + * Return: True if tree is empty, false otherwise. + */ +static inline _Bool c_rbtree_is_empty(CRBTree *t) { + return !t->root; +} + +/** + * CRBCompareFunc - compare a node to a key + * @t: tree where the node is linked to + * @k: key to compare + * @n: node to compare + * + * If you use the tree-traversal helpers (which are optional), you need to + * provide this callback so they can compare nodes in a tree to the key you + * look for. + * + * The tree @t is provided as optional context to this callback. The key you + * look for is provided as @k, the current node that should be compared to is + * provided as @n. This function should work like strcmp(), that is, return <0 + * if @key orders before @n, 0 if both compare equal, and >0 if it orders after + * @n. + */ +typedef int (*CRBCompareFunc) (CRBTree *t, void *k, CRBNode *n); + +/** + * c_rbtree_find_node() - find node + * @t: tree to search through + * @f: comparison function + * @k: key to search for + * + * This searches through @t for a node that compares equal to @k. The function + * @f must be provided by the caller, which is used to compare nodes to @k. See + * the documentation of CRBCompareFunc for details. + * + * If there are multiple entries that compare equal to @k, this will return a + * pseudo-randomly picked node. If you need stable lookup functions for trees + * where duplicate entries are allowed, you better code your own lookup. + * + * Return: Pointer to matching node, or NULL. + */ +static inline CRBNode *c_rbtree_find_node(CRBTree *t, CRBCompareFunc f, const void *k) { + CRBNode *i; + + assert(t); + assert(f); + + i = t->root; + while (i) { + int v = f(t, (void *)k, i); + if (v < 0) + i = i->left; + else if (v > 0) + i = i->right; + else + return i; + } + + return NULL; +} + +/** + * c_rbtree_find_entry() - find entry + * @_t: tree to search through + * @_f: comparison function + * @_k: key to search for + * @_s: type of the structure that embeds the nodes + * @_m: name of the node-member in type @_t + * + * This is very similar to c_rbtree_find_node(), but instead of returning a + * pointer to the CRBNode, it returns a pointer to the surrounding object. This + * object must embed the CRBNode object. The type of the surrounding object + * must be given as @_s, and the name of the embedded CRBNode member as @_m. + * + * See c_rbtree_find_node() and c_rbnode_entry() for more details. + * + * Return: Pointer to found entry, NULL if not found. + */ +#define c_rbtree_find_entry(_t, _f, _k, _s, _m) \ + c_rbnode_entry(c_rbtree_find_node((_t), (_f), (_k)), _s, _m) + +/** + * c_rbtree_find_slot() - find slot to insert new node + * @t: tree to search through + * @f: comparison function + * @k: key to search for + * @p: output storage for parent pointer + * + * This searches through @t just like c_rbtree_find_node() does. However, + * instead of returning a pointer to a node that compares equal to @k, this + * searches for a slot to insert a node with key @k. A pointer to the slot is + * returned, and a pointer to the parent of the slot is stored in @p. Both + * can be passed directly to c_rbtree_add(), together with your node to insert. + * + * If there already is a node in the tree, that compares equal to @k, this will + * return NULL and store the conflicting node in @p. In all other cases, + * this will return a pointer (non-NULL) to the empty slot to insert the node + * at. @p will point to the parent node of that slot. + * + * If you want trees that allow duplicate nodes, you better code your own + * insertion function. + * + * Return: Pointer to slot to insert node, or NULL on conflicts. + */ +static inline CRBNode **c_rbtree_find_slot(CRBTree *t, CRBCompareFunc f, const void *k, CRBNode **p) { + CRBNode **i; + + assert(t); + assert(f); + assert(p); + + i = &t->root; + *p = NULL; + while (*i) { + int v = f(t, (void *)k, *i); + *p = *i; + if (v < 0) + i = &(*i)->left; + else if (v > 0) + i = &(*i)->right; + else + return NULL; + } + + return i; +} + +/** + * c_rbtree_for_each*() - iterators + * + * The c_rbtree_for_each*() macros provide simple for-loop wrappers to iterate + * an RB-Tree. They come in a set of flavours: + * + * - "entry": This combines c_rbnode_entry() with the loop iterator, so the + * iterator always has the type of the surrounding object, rather + * than CRBNode. + * + * - "safe": The loop iterator always keeps track of the next element to + * visit. This means, you can safely modify the current element, + * while retaining loop-integrity. + * You still must not touch any other entry of the tree. Otherwise, + * the loop-iterator will be corrupted. Also remember to only + * modify the tree in a way compatible with your iterator-order. + * That is, if you use in-order iteration (default), you can unlink + * your current object, including re-balancing the tree. However, + * if you use post-order, you must not trigger a tree rebalance + * operation, since it is not an invariant of post-order iteration. + * + * - "postorder": Rather than the default in-order iteration, this iterates + * the tree in post-order. + * + * - "unlink": This unlinks the current element from the tree before the loop + * code is run. Note that the tree is not rebalanced. That is, + * you must never break out of the loop. If you do so, the tree + * is corrupted. + */ + +#define c_rbtree_for_each(_iter, _tree) \ + for (_iter = c_rbtree_first(_tree); \ + _iter; \ + _iter = c_rbnode_next(_iter)) + +#define c_rbtree_for_each_entry(_iter, _tree, _m) \ + for (_iter = c_rbnode_entry(c_rbtree_first(_tree), __typeof__(*_iter), _m); \ + _iter; \ + _iter = c_rbnode_entry(c_rbnode_next(&_iter->_m), __typeof__(*_iter), _m)) + +#define c_rbtree_for_each_safe(_iter, _safe, _tree) \ + for (_iter = c_rbtree_first(_tree), _safe = c_rbnode_next(_iter); \ + _iter; \ + _iter = _safe, _safe = c_rbnode_next(_safe)) + +#define c_rbtree_for_each_entry_safe(_iter, _safe, _tree, _m) \ + for (_iter = c_rbnode_entry(c_rbtree_first(_tree), __typeof__(*_iter), _m), \ + _safe = _iter ? c_rbnode_entry(c_rbnode_next(&_iter->_m), __typeof__(*_iter), _m) : NULL; \ + _iter; \ + _iter = _safe, \ + _safe = _safe ? c_rbnode_entry(c_rbnode_next(&_safe->_m), __typeof__(*_iter), _m) : NULL) + +#define c_rbtree_for_each_postorder(_iter, _tree) \ + for (_iter = c_rbtree_first_postorder(_tree); \ + _iter; \ + _iter = c_rbnode_next_postorder(_iter)) \ + +#define c_rbtree_for_each_entry_postorder(_iter, _tree, _m) \ + for (_iter = c_rbnode_entry(c_rbtree_first_postorder(_tree), __typeof__(*_iter), _m); \ + _iter; \ + _iter = c_rbnode_entry(c_rbnode_next_postorder(&_iter->_m), __typeof__(*_iter), _m)) + +#define c_rbtree_for_each_safe_postorder(_iter, _safe, _tree) \ + for (_iter = c_rbtree_first_postorder(_tree), _safe = c_rbnode_next_postorder(_iter); \ + _iter; \ + _iter = _safe, _safe = c_rbnode_next_postorder(_safe)) + +#define c_rbtree_for_each_entry_safe_postorder(_iter, _safe, _tree, _m) \ + for (_iter = c_rbnode_entry(c_rbtree_first_postorder(_tree), __typeof__(*_iter), _m), \ + _safe = _iter ? c_rbnode_entry(c_rbnode_next_postorder(&_iter->_m), __typeof__(*_iter), _m) : NULL; \ + _iter; \ + _iter = _safe, \ + _safe = _safe ? c_rbnode_entry(c_rbnode_next_postorder(&_safe->_m), __typeof__(*_iter), _m) : NULL) + +#define c_rbtree_for_each_safe_postorder_unlink(_iter, _safe, _tree) \ + for (_iter = c_rbtree_first_postorder(_tree), _safe = c_rbnode_next_postorder(_iter); \ + _iter ? ((*_iter = (CRBNode)C_RBNODE_INIT(*_iter)), 1) : (((_tree)->root = NULL), 0); \ + _iter = _safe, _safe = c_rbnode_next_postorder(_safe)) \ + +#define c_rbtree_for_each_entry_safe_postorder_unlink(_iter, _safe, _tree, _m) \ + for (_iter = c_rbnode_entry(c_rbtree_first_postorder(_tree), __typeof__(*_iter), _m), \ + _safe = _iter ? c_rbnode_entry(c_rbnode_next_postorder(&_iter->_m), __typeof__(*_iter), _m) : NULL; \ + _iter ? ((_iter->_m = (CRBNode)C_RBNODE_INIT(_iter->_m)), 1) : (((_tree)->root = NULL), 0); \ + _iter = _safe, \ + _safe = _safe ? c_rbnode_entry(c_rbnode_next_postorder(&_safe->_m), __typeof__(*_iter), _m) : NULL) + +#ifdef __cplusplus +} +#endif diff --git a/src/c-siphash/src/c-siphash.c b/src/c-siphash/src/c-siphash.c new file mode 100644 index 0000000..720e403 --- /dev/null +++ b/src/c-siphash/src/c-siphash.c @@ -0,0 +1,245 @@ +/* + * SipHash Implementation + * + * For highlevel documentation of the API see the header file and the docbook + * comments. This implementation is based on the reference implementation of + * SipHash, written by Jean-Philippe Aumasson and Daniel J. Bernstein, and + * released to the Public Domain. + * + * So far, only SipHash24 is implemented, since there was no need for other + * parameters. However, adjusted c_siphash_append_X() and + * C_siphash_finalize_Y() can be easily provided, if required. + */ + +#include +#include +#include +#include "c-siphash.h" + +static inline uint64_t c_siphash_read_le64(const uint8_t bytes[8]) { + return ((uint64_t) bytes[0]) | + (((uint64_t) bytes[1]) << 8) | + (((uint64_t) bytes[2]) << 16) | + (((uint64_t) bytes[3]) << 24) | + (((uint64_t) bytes[4]) << 32) | + (((uint64_t) bytes[5]) << 40) | + (((uint64_t) bytes[6]) << 48) | + (((uint64_t) bytes[7]) << 56); +} + +static inline uint64_t c_siphash_rotate_left(uint64_t x, uint8_t b) { + return (x << b) | (x >> (64 - b)); +} + +static inline void c_siphash_sipround(CSipHash *state) { + state->v0 += state->v1; + state->v1 = c_siphash_rotate_left(state->v1, 13); + state->v1 ^= state->v0; + state->v0 = c_siphash_rotate_left(state->v0, 32); + state->v2 += state->v3; + state->v3 = c_siphash_rotate_left(state->v3, 16); + state->v3 ^= state->v2; + state->v0 += state->v3; + state->v3 = c_siphash_rotate_left(state->v3, 21); + state->v3 ^= state->v0; + state->v2 += state->v1; + state->v1 = c_siphash_rotate_left(state->v1, 17); + state->v1 ^= state->v2; + state->v2 = c_siphash_rotate_left(state->v2, 32); +} + +/** + * c_siphash_init() - initialize siphash context + * @state: context object + * @seed: 128bit seed + * + * This initializes the siphash state context. Once initialized, it can be used + * to hash arbitrary input. To feed data into it, use c_siphash_append(). To get + * the final hash, use c_siphash_finalize(). + * + * Note that the siphash context does not allocate state. There is no need to + * deserialize it before releasing its backing memory. + * + * The hashes generated by this context change depending on the seed. Every + * user is highly inclined to provide their unique seed. If no stable hashes + * are needed, a random seed will do fine. + * + * Right now, only SipHash24 is supported. Other SipHash parameters can be + * easily added if required. + */ +_c_public_ void c_siphash_init(CSipHash *state, const uint8_t seed[16]) { + uint64_t k0, k1; + + k0 = c_siphash_read_le64(seed); + k1 = c_siphash_read_le64(seed + 8); + + *state = (CSipHash) { + /* + * Default seed is taken from the reference implementation + * of SipHash24 ("somepseudorandomlygeneratedbytes"). Callers + * are still recommended to provide proper seeds themselves. + */ + .v0 = 0x736f6d6570736575ULL ^ k0, + .v1 = 0x646f72616e646f6dULL ^ k1, + .v2 = 0x6c7967656e657261ULL ^ k0, + .v3 = 0x7465646279746573ULL ^ k1, + .padding = 0, + .n_bytes = 0, + }; +} + +/** + * c_siphash_append() - hash stream of data + * @state: context object + * @bytes: array of input bytes + * @n_bytes: number of input bytes + * + * This feeds an array of bytes into the SipHash state machine. This is a + * streaming-capable API. That is, the resulting hash is the same, regardless + * of the way you chunk the input. + * This function simply feeds the given bytes into the SipHash state machine. + * It does not produce a final hash. You can call this function many times to + * append more data. To retrieve the final hash, call c_siphash_finalize(). + * + * Note that this implementation works best when used with chunk-sizes of + * multiples of 64bit (8-bytes). This is not a requirement, though. + */ +_c_public_ void c_siphash_append(CSipHash *state, const uint8_t *bytes, size_t n_bytes) { + const uint8_t *end = bytes + n_bytes; + size_t left = state->n_bytes & 7; + uint64_t m; + + state->n_bytes += n_bytes; + + /* + * SipHash operates on 64bit chunks. If the previous blob was not a + * multiple of 64bit in length, we must operate on single bytes. + */ + if (left > 0) { + for ( ; bytes < end && left < 8; ++bytes, ++left) + state->padding |= ((uint64_t) *bytes) << (left * 8); + + if (bytes == end && left < 8) + return; + + state->v3 ^= state->padding; + c_siphash_sipround(state); + c_siphash_sipround(state); + state->v0 ^= state->padding; + + state->padding = 0; + } + + end -= (state->n_bytes % sizeof(uint64_t)); + + /* + * We are now guaranteed to be at a 64bit state boundary. Hence, we can + * operate in 64bit chunks on all input. This is much faster than the + * one-byte-at-a-time loop. + */ + for ( ; bytes < end; bytes += 8) { + m = c_siphash_read_le64(bytes); + + state->v3 ^= m; + c_siphash_sipround(state); + c_siphash_sipround(state); + state->v0 ^= m; + } + + /* + * Now that we hashed as much 64bit chunks as possible, we need to + * remember the remaining trailing bytes. Keep them in @padding so the + * next round (or the finalizer) get access to them. + */ + left = state->n_bytes & 7; + switch (left) { + case 7: + state->padding |= ((uint64_t) bytes[6]) << 48; + /* fallthrough */ + case 6: + state->padding |= ((uint64_t) bytes[5]) << 40; + /* fallthrough */ + case 5: + state->padding |= ((uint64_t) bytes[4]) << 32; + /* fallthrough */ + case 4: + state->padding |= ((uint64_t) bytes[3]) << 24; + /* fallthrough */ + case 3: + state->padding |= ((uint64_t) bytes[2]) << 16; + /* fallthrough */ + case 2: + state->padding |= ((uint64_t) bytes[1]) << 8; + /* fallthrough */ + case 1: + state->padding |= ((uint64_t) bytes[0]); + /* fallthrough */ + case 0: + break; + } +} + +/** + * c_siphash_finalize() - finalize hash + * @state: context object + * + * This produces the final SipHash24 hash value for the given SipHash state. + * That is, it produces a hash value corresponding to the SipHash24 hash value + * of the concatenated byte-array passed into @state via c_siphash_append(). + * + * Note that @state has an invalid state after this function returns. To reuse + * it for another hash, you must call c_siphash_init() again. If you don't need + * the object, anymore, you can release it any time. There is no need to + * destroy the object explicitly. + * + * Return: 64bit hash value + */ +_c_public_ uint64_t c_siphash_finalize(CSipHash *state) { + uint64_t b; + + b = state->padding | (((uint64_t) state->n_bytes) << 56); + + state->v3 ^= b; + c_siphash_sipround(state); + c_siphash_sipround(state); + state->v0 ^= b; + + state->v2 ^= 0xff; + + c_siphash_sipround(state); + c_siphash_sipround(state); + c_siphash_sipround(state); + c_siphash_sipround(state); + + return state->v0 ^ state->v1 ^ state->v2 ^ state->v3; +} + +/** + * c_siphash_hash() - hash data blob + * @seed: 128bit seed + * @bytes: byte array to hash + * @n_bytes: number of bytes to hash + * + * This produces the SipHash24 hash value for the input @bytes / @n_bytes, + * using the seed provided as @seed. + * + * This is functionally equivalent to: + * + * CSipHash state; + * c_siphash_init(&state, seed); + * c_siphash_append(&state, bytes, n_bytes); + * return c_siphash_finalize(&state); + * + * Unlike the streaming API, this is a one-shot call suitable for any data that + * is available in-memory at the same time. + * + * Return: 64bit hash value + */ +_c_public_ uint64_t c_siphash_hash(const uint8_t seed[16], const uint8_t *bytes, size_t n_bytes) { + CSipHash state; + + c_siphash_init(&state, seed); + c_siphash_append(&state, bytes, n_bytes); + + return c_siphash_finalize(&state); +} diff --git a/src/c-siphash/src/c-siphash.h b/src/c-siphash/src/c-siphash.h new file mode 100644 index 0000000..c0cfc1e --- /dev/null +++ b/src/c-siphash/src/c-siphash.h @@ -0,0 +1,60 @@ +#pragma once + +/** + * Streaming-capable SipHash Implementation + * + * This library provides a SipHash API, that is fully implemented in ISO-C11 + * and has no external dependencies. The library performs no memory allocation, + * and provides a streaming API where data to be hashed can be appended + * piecemeal. + * + * A streaming-capable hash state is represented by the "CSipHash" structure, + * which should be initialized with a unique seed before use. If streaming + * capabilities are not required, c_siphash_hash() provides a simple one-shot + * API. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef struct CSipHash CSipHash; + +/** + * struct CSipHash - SipHash state object + * @v0-@v3: internal state + * @padding: pending bytes that were not a multiple of 8 + * @n_bytes: number of hashed bytes + * + * The state of an inflight hash is represenetd by a CSipHash object. Before + * hashing, it must be initialized with c_siphash_init(), providing a unique + * random hash seed. Data is hashed by appending it to the state object, using + * c_siphash_append(). Finally, the hash is read out by calling + * c_siphash_finalize(). + * + * This state object has no allocated resources. It is safe to release its + * backing memory without any further action. + */ +struct CSipHash { + uint64_t v0; + uint64_t v1; + uint64_t v2; + uint64_t v3; + uint64_t padding; + size_t n_bytes; +}; + +#define C_SIPHASH_NULL {} + +void c_siphash_init(CSipHash *state, const uint8_t seed[16]); +void c_siphash_append(CSipHash *state, const uint8_t *bytes, size_t n_bytes); +uint64_t c_siphash_finalize(CSipHash *state); + +uint64_t c_siphash_hash(const uint8_t seed[16], const uint8_t *bytes, size_t n_bytes); + +#ifdef __cplusplus +} +#endif diff --git a/src/c-stdaux/src/c-stdaux.h b/src/c-stdaux/src/c-stdaux.h new file mode 100644 index 0000000..1cdbbbc --- /dev/null +++ b/src/c-stdaux/src/c-stdaux.h @@ -0,0 +1,550 @@ +#pragma once + +/* + * Auxiliary macros and functions for the C standard library + * + * The `c-stdaux.h` header contains a collection of auxiliary macros and helper + * functions around the functionality provided by the different C standard + * library implementations, as well as other specifications implemented by + * them. + * + * Most of the helpers provided here provide aliases for common library and + * compiler features. Furthermore, several helpers simply provide other calling + * conventions than their standard counterparts (e.g., they allow for NULL to + * be passed with an object length of 0 where it makes sense to accept empty + * input). + * + * The namespace used by this project is: + * + * * `c_*` for all common C symbols or definitions that behave like proper C + * entities (e.g., macros that protect against double-evaluation would use + * lower-case names) + * + * * `C_*` for all constants, as well as macros that may not be safe against + * double evaluation. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#if 0 /* NM_IGNORED */ +#include +#endif /* NM_IGNORED */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Shortcuts for gcc attributes. See GCC manual for details. They're 1-to-1 + * mappings to the GCC equivalents. No additional magic here. They are + * supported by other compilers as well. + */ +#define _c_cleanup_(_x) __attribute__((__cleanup__(_x))) +#define _c_const_ __attribute__((__const__)) +#define _c_deprecated_ __attribute__((__deprecated__)) +#define _c_hidden_ __attribute__((__visibility__("hidden"))) +#define _c_likely_(_x) (__builtin_expect(!!(_x), 1)) +#define _c_packed_ __attribute__((__packed__)) +#define _c_printf_(_a, _b) __attribute__((__format__(printf, _a, _b))) +#define _c_public_ __attribute__((__visibility__("default"))) +#define _c_pure_ __attribute__((__pure__)) +#define _c_sentinel_ __attribute__((__sentinel__)) +#define _c_unlikely_(_x) (__builtin_expect(!!(_x), 0)) +#define _c_unused_ __attribute__((__unused__)) + +/** + * C_EXPR_ASSERT() - create expression with assertion + * @_expr: expression to evaluate to + * @_assertion: arbitrary assertion + * @_message: message associated with the assertion + * + * This macro simply evaluates to @_expr. That is, it can be used in any + * context that expects an expression like @_expr. Additionally, it takes an + * assertion as @_assertion and evaluates it through _Static_assert(), using + * @_message as debug message. + * + * The _Static_assert() builtin of C11 is defined as statement and thus cannot + * be used in expressions. This macro circumvents this restriction. + * + * Return: Evaluates to @_expr. + */ +#if defined(__COVERITY__) // Coverity cannot const-fold __builtin_choose_expr() +# define C_EXPR_ASSERT(_expr, _assertion, _message) (_expr) +#else +# define C_EXPR_ASSERT(_expr, _assertion, _message) \ + /* indentation and line-split to get better diagnostics */ \ + (__builtin_choose_expr( \ + !!(1 + 0 * sizeof( \ + struct { \ +_Static_assert(_assertion, _message); \ + } \ + )), \ + (_expr), \ + ((void)0) \ + )) +#endif + +/** + * C_STRINGIFY() - stringify a token, but evaluate it first + * @_x: token to evaluate and stringify + * + * Return: Evaluates to a constant string literal + */ +#define C_STRINGIFY(_x) C_INTERNAL_STRINGIFY(_x) +#define C_INTERNAL_STRINGIFY(_x) #_x + +/** + * C_CONCATENATE() - concatenate two tokens, but evaluate them first + * @_x: first token + * @_y: second token + * + * Return: Evaluates to a constant identifier + */ +#define C_CONCATENATE(_x, _y) C_INTERNAL_CONCATENATE(_x, _y) +#define C_INTERNAL_CONCATENATE(_x, _y) _x ## _y + +/** + * C_EXPAND() - expand a tuple to a series of its values + * @_x: tuple to expand + * + * Return: Evaluates to the expanded tuple + */ +#define C_EXPAND(_x) C_INTERNAL_EXPAND _x +#define C_INTERNAL_EXPAND(...) __VA_ARGS__ + +/** + * C_VAR() - generate unique variable name + * @_x: name of variable, optional + * @_uniq: unique prefix, usually provided by __COUNTER__, optional + * + * This macro shall be used to generate unique variable names, that will not be + * shadowed by recursive macro invocations. It is effectively a + * C_CONCATENATE of both arguments, but also provides a globally separated + * prefix and makes the code better readable. + * + * The second argument is optional. If not given, __LINE__ is implied, and as + * such the macro will generate the same identifier if used multiple times on + * the same code-line (or within a macro). This should be used if recursive + * calls into the macro are not expected. In fact, no argument is necessary in + * this case, as a mere `C_VAR` will evaluate to a valid variable name. + * + * This helper may be used by macro implementations that might reasonable well + * be called in a stacked fasion, like: + * + * c_max(foo, c_max(bar, baz)) + * + * Such a stacked call of c_max() might cause compiler warnings of shadowed + * variables in the definition of c_max(). By using C_VAR(), such warnings + * can be silenced as each evaluation of c_max() uses unique variable names. + * + * Return: This evaluates to a constant identifier. + */ +#define C_VAR(...) C_INTERNAL_VAR(__VA_ARGS__, 2, 1) +#define C_INTERNAL_VAR(_x, _uniq, _num, ...) C_VAR ## _num (_x, _uniq) +#define C_VAR1(_x, _unused) C_VAR2(_x, C_CONCATENATE(line, __LINE__)) +#define C_VAR2(_x, _uniq) C_CONCATENATE(c_internal_var_unique_, C_CONCATENATE(_uniq, _x)) + +/** + * C_CC_MACRO1() - provide safe environment to a macro + * @_call: macro to call + * @_x1: first argument + * @...: further arguments to forward unmodified to @_call + * + * This function simplifies the implementation of macros. Whenever you + * implement a macro, provide the internal macro name as @_call and its + * argument as @_x1. Inside of your internal macro, you... + * + * - ...are safe against multiple evaluation errors, since C_CC_MACRO1 will + * store the initial parameters in temporary variables. + * + * - ...support constant folding, as C_CC_MACRO1 takes care to invoke your + * macro with the original values, if they are compile-time constant. + * + * - ...have unique variable names for recursive callers and will not run into + * variable-shadowing-warnings accidentally. + * + * - ...have properly typed arguments as C_CC_MACRO1 stores the original + * arguments in an `__auto_type` temporary variable. + * + * Return: Result of @_call is returned. + */ +#define C_CC_MACRO1(_call, _x1, ...) C_INTERNAL_CC_MACRO1(_call, __COUNTER__, (_x1), ## __VA_ARGS__) +#define C_INTERNAL_CC_MACRO1(_call, _x1q, _x1, ...) \ + __builtin_choose_expr( \ + __builtin_constant_p(_x1), \ + _call(_x1, ## __VA_ARGS__), \ + __extension__ ({ \ + const __auto_type C_VAR(X1, _x1q) = (_x1); \ + _call(C_VAR(X1, _x1q), ## __VA_ARGS__); \ + })) + +/** + * C_CC_MACRO2() - provide safe environment to a macro + * @_call: macro to call + * @_x1: first argument + * @_x2: second argument + * @...: further arguments to forward unmodified to @_call + * + * This is the 2-argument equivalent of C_CC_MACRO1(). + * + * Return: Result of @_call is returned. + */ +#define C_CC_MACRO2(_call, _x1, _x2, ...) C_INTERNAL_CC_MACRO2(_call, __COUNTER__, (_x1), __COUNTER__, (_x2), ## __VA_ARGS__) +#define C_INTERNAL_CC_MACRO2(_call, _x1q, _x1, _x2q, _x2, ...) \ + __builtin_choose_expr( \ + (__builtin_constant_p(_x1) && __builtin_constant_p(_x2)), \ + _call((_x1), (_x2), ## __VA_ARGS__), \ + __extension__ ({ \ + const __auto_type C_VAR(X1, _x1q) = (_x1); \ + const __auto_type C_VAR(X2, _x2q) = (_x2); \ + _call(C_VAR(X1, _x1q), C_VAR(X2, _x2q), ## __VA_ARGS__); \ + })) + +/** + * C_CC_MACRO3() - provide safe environment to a macro + * @_call: macro to call + * @_x1: first argument + * @_x2: second argument + * @_x3: third argument + * @...: further arguments to forward unmodified to @_call + * + * This is the 3-argument equivalent of C_CC_MACRO1(). + * + * Return: Result of @_call is returned. + */ +#define C_CC_MACRO3(_call, _x1, _x2, _x3, ...) C_INTERNAL_CC_MACRO3(_call, __COUNTER__, (_x1), __COUNTER__, (_x2), __COUNTER__, (_x3), ## __VA_ARGS__) +#define C_INTERNAL_CC_MACRO3(_call, _x1q, _x1, _x2q, _x2, _x3q, _x3, ...) \ + __builtin_choose_expr( \ + (__builtin_constant_p(_x1) && __builtin_constant_p(_x2) && __builtin_constant_p(_x3)), \ + _call((_x1), (_x2), (_x3), ## __VA_ARGS__), \ + __extension__ ({ \ + const __auto_type C_VAR(X1, _x1q) = (_x1); \ + const __auto_type C_VAR(X2, _x2q) = (_x2); \ + const __auto_type C_VAR(X3, _x3q) = (_x3); \ + _call(C_VAR(X1, _x1q), C_VAR(X2, _x2q), C_VAR(X3, _x3q), ## __VA_ARGS__); \ + })) + +/** + * C_ARRAY_SIZE() - calculate number of array elements at compile time + * @_x: array to calculate size of + * + * Return: Evaluates to a constant integer expression. + */ +#define C_ARRAY_SIZE(_x) \ + C_EXPR_ASSERT(sizeof(_x) / sizeof((_x)[0]), \ + /* \ + * Verify that `_x' is an array, not a pointer. Rely on \ + * `&_x[0]' degrading arrays to pointers. \ + */ \ + !__builtin_types_compatible_p( \ + __typeof__(_x), \ + __typeof__(&(*(__typeof__(_x)*)0)[0]) \ + ), \ + "C_ARRAY_SIZE() called with non-array argument" \ + ) + +/** + * C_DECIMAL_MAX() - calculate maximum length of the decimal + * representation of an integer + * @_type: integer variable/type + * + * This calculates the bytes required for the decimal representation of an + * integer of the given type. It accounts for a possible +/- prefix, but it + * does *NOT* include the trailing terminating zero byte. + * + * Return: Evaluates to a constant integer expression + */ +#define C_DECIMAL_MAX(_arg) \ + (_Generic((__typeof__(_arg)){ 0 }, \ + char: C_INTERNAL_DECIMAL_MAX(sizeof(char)), \ + signed char: C_INTERNAL_DECIMAL_MAX(sizeof(signed char)), \ + unsigned char: C_INTERNAL_DECIMAL_MAX(sizeof(unsigned char)), \ + signed short: C_INTERNAL_DECIMAL_MAX(sizeof(signed short)), \ + unsigned short: C_INTERNAL_DECIMAL_MAX(sizeof(unsigned short)), \ + signed int: C_INTERNAL_DECIMAL_MAX(sizeof(signed int)), \ + unsigned int: C_INTERNAL_DECIMAL_MAX(sizeof(unsigned int)), \ + signed long: C_INTERNAL_DECIMAL_MAX(sizeof(signed long)), \ + unsigned long: C_INTERNAL_DECIMAL_MAX(sizeof(unsigned long)), \ + signed long long: C_INTERNAL_DECIMAL_MAX(sizeof(signed long long)), \ + unsigned long long: C_INTERNAL_DECIMAL_MAX(sizeof(unsigned long long)))) +#define C_INTERNAL_DECIMAL_MAX(_bytes) \ + C_EXPR_ASSERT( \ + 1 + ((_bytes) <= 1 ? 3 : \ + (_bytes) <= 2 ? 5 : \ + (_bytes) <= 4 ? 10 : \ + 20), \ + (_bytes) <= 8, \ + "Invalid use of C_INTERNAL_DECIMAL_MAX()" \ + ) + +/** + * c_container_of() - cast a member of a structure out to the containing structure + * @_ptr: pointer to the member or NULL + * @_type: type of the container struct this is embedded in + * @_member: name of the member within the struct + * + * This uses `offsetof(3)` to turn a pointer to a structure-member into a + * pointer to the surrounding structure. + * + * Return: Pointer to the surrounding object. + */ +#define c_container_of(_ptr, _type, _member) C_CC_MACRO1(C_CONTAINER_OF, (_ptr), _type, _member) +#define C_CONTAINER_OF(_ptr, _type, _member) \ + __extension__ ({ \ + /* trigger warning if types do not match */ \ + (void)(&((_type *)0)->_member == (_ptr)); \ + _ptr ? (_type*)( (char*)_ptr - offsetof(_type, _member) ) : NULL; \ + }) + +/** + * c_max() - compute maximum of two values + * @_a: value A + * @_b: value B + * + * Calculate the maximum of both passed values. Both arguments are evaluated + * exactly once, under all circumstances. Furthermore, if both values are + * constant expressions, the result will be constant as well. + * + * The comparison of their values is performed with the types given by the + * caller. It is the caller's responsibility to convert them to suitable types + * if necessary. + * + * Return: Maximum of both values is returned. + */ +#define c_max(_a, _b) C_CC_MACRO2(C_MAX, (_a), (_b)) +#define C_MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) + +/** + * c_min() - compute minimum of two values + * @_a: value A + * @_b: value B + * + * Calculate the minimum of both passed values. Both arguments are evaluated + * exactly once, under all circumstances. Furthermore, if both values are + * constant expressions, the result will be constant as well. + * + * The comparison of their values is performed with the types given by the + * caller. It is the caller's responsibility to convert them to suitable types + * if necessary. + * + * Return: Minimum of both values is returned. + */ +#define c_min(_a, _b) C_CC_MACRO2(C_MIN, (_a), (_b)) +#define C_MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) + +/** + * c_less_by() - calculate clamped difference of two values + * @_a: minuend + * @_b: subtrahend + * + * Calculate [_a - _b], but clamp the result to 0. Both arguments are evaluated + * exactly once, under all circumstances. Furthermore, if both values are + * constant expressions, the result will be constant as well. + * + * The comparison of their values is performed with the types given by the + * caller. It is the caller's responsibility to convert them to suitable types + * if necessary. + * + * Return: This computes [_a - _b], if [_a > _b]. Otherwise, 0 is returned. + */ +#define c_less_by(_a, _b) C_CC_MACRO2(C_LESS_BY, (_a), (_b)) +#define C_LESS_BY(_a, _b) ((_a) > (_b) ? (_a) - (_b) : 0) + +/** + * c_clamp() - clamp value to lower and upper boundary + * @_x: value to clamp + * @_low: lower boundary + * @_high: higher boundary + * + * This clamps @_x to the lower and higher bounds given as @_low and @_high. + * All arguments are evaluated exactly once, and yield a constant expression if + * all arguments are constant as well. + * + * The comparison of their values is performed with the types given by the + * caller. It is the caller's responsibility to convert them to suitable types + * if necessary. + * + * Return: Clamped integer value. + */ +#define c_clamp(_x, _low, _high) C_CC_MACRO3(C_CLAMP, (_x), (_low), (_high)) +#define C_CLAMP(_x, _low, _high) ((_x) > (_high) ? (_high) : (_x) < (_low) ? (_low) : (_x)) + +/** + * c_div_round_up() - calculate integer quotient but round up + * @_x: dividend + * @_y: divisor + * + * Calculates [x / y] but rounds up the result to the next integer. All + * arguments are evaluated exactly once, and yield a constant expression if all + * arguments are constant. + * + * Note: + * [(x + y - 1) / y] suffers from an integer overflow, even though the + * computation should be possible in the given type. Therefore, we use + * [x / y + !!(x % y)]. Note that on most CPUs a division returns both the + * quotient and the remainder, so both should be equally fast. Furthermore, if + * the divisor is a power of two, the compiler will optimize it, anyway. + * + * The operationsare performed with the types given by the caller. It is the + * caller's responsibility to convert the arguments to suitable types if + * necessary. + * + * Return: The quotient is returned. + */ +#define c_div_round_up(_x, _y) C_CC_MACRO2(C_DIV_ROUND_UP, (_x), (_y)) +#define C_DIV_ROUND_UP(_x, _y) ((_x) / (_y) + !!((_x) % (_y))) + +/** + * c_align_to() - align value to a multiple + * @_val: value to align + * @_to: align to multiple of this + * + * This aligns @_val to a multiple of @_to. If @_val is already a multiple of + * @_to, @_val is returned unchanged. This function operates within the + * boundaries of the type of @_val and @_to. Make sure to cast them if needed. + * + * The arguments of this macro are evaluated exactly once. If both arguments + * are a constant expression, this also yields a constant return value. + * + * Note that @_to must be a power of 2, otherwise the behavior will not match + * expectations. + * + * Return: @_val aligned to a multiple of @_to + */ +#define c_align_to(_val, _to) C_CC_MACRO2(C_ALIGN_TO, (_val), (_to)) +#define C_ALIGN_TO(_val, _to) (((_val) + (_to) - 1) & ~((_to) - 1)) + +/** + * c_assert() - runtime assertions + * @expr_result: result of an expression + * + * This function behaves like the standard `assert(3)` macro. That is, if + * `NDEBUG` is defined, it is a no-op. In all other cases it will assert that + * the result of the passed expression is true. + * + * Unlike the standard `assert(3)` macro, this function always evaluates its + * argument. This means side-effects will always be evaluated! However, if the + * macro is used with constant expressions, the compiler will be able to + * optimize it away. + */ +#define c_assert(_x) ({ \ + const _c_unused_ bool c_assert_result = (_x); \ + assert(c_assert_result && #_x); \ + }) + +/** + * c_errno() - return valid errno + * + * This helper should be used to shut up gcc if you know 'errno' is valid (ie., + * errno is > 0). Instead of "return -errno;", use + * "return -c_errno();" It will suppress bogus gcc warnings in case it assumes + * 'errno' might be 0 (or <0) and thus the caller's error-handling might not be + * triggered. + * + * This helper should be avoided whenever possible. However, occasionally we + * really want to shut up gcc (especially with static/inline functions). In + * those cases, gcc usually cannot deduce that some error paths are guaranteed + * to be taken. Hence, making the return value explicit allows gcc to better + * optimize the code. + * + * Note that you really should never use this helper to work around broken libc + * calls or syscalls, not setting 'errno' correctly. + * + * Return: Positive error code is returned. + */ +static inline int c_errno(void) { + return _c_likely_(errno > 0) ? errno : ENOTRECOVERABLE; +} + +/* + * Common Destructors + * + * Followingly, there're a bunch of common 'static inline' destructors, which + * simply call the function that they're named after, but return "INVALID" + * instead of "void". This allows direct assignment to any member-field and/or + * variable they're defined in, like: + * + * foo = c_free(foo); + * + * or + * + * foo->bar = c_close(foo->bar); + * + * Furthermore, all those destructors can be safely called with the "INVALID" + * value as argument, and they will be a no-op. + */ + +static inline void *c_free(void *p) { + free(p); + return NULL; +} + +static inline int c_close(int fd) { + if (fd >= 0) + close(fd); + return -1; +} + +static inline FILE *c_fclose(FILE *f) { + if (f) + fclose(f); + return NULL; +} + +static inline DIR *c_closedir(DIR *d) { + if (d) + closedir(d); + return NULL; +} + +/* + * Common Cleanup Helpers + * + * A bunch of _c_cleanup_(foobarp) helpers that are used all over the place. + * Note that all of those have the "if (IS_INVALID(foobar))" check inline, so + * compilers can optimize most of the cleanup-paths in a function. However, if + * the function they call already does this _inline_, then it might be skipped. + */ + +#define C_DEFINE_CLEANUP(_type, _func) \ + static inline void _func ## p(_type *p) { \ + if (*p) \ + _func(*p); \ + } struct c_internal_trailing_semicolon + +#define C_DEFINE_DIRECT_CLEANUP(_type, _func) \ + static inline void _func ## p(_type *p) { \ + _func(*p); \ + } struct c_internal_trailing_semicolon + +static inline void c_freep(void *p) { + /* + * `foobar **` does not coerce to `void **`, so we need `void *` as + * argument type, and then we dereference manually. + */ + c_free(*(void **)p); +} + +C_DEFINE_DIRECT_CLEANUP(int, c_close); +C_DEFINE_CLEANUP(FILE *, c_fclose); +C_DEFINE_CLEANUP(DIR *, c_closedir); + +#ifdef __cplusplus +} +#endif diff --git a/src/contrib/meson.build b/src/contrib/meson.build new file mode 100644 index 0000000..2745087 --- /dev/null +++ b/src/contrib/meson.build @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +nm_vpn_plugin_utils_source = files('nm-vpn-plugin-utils.c') + +src_contrib_nm_compat_source = files('nm-compat.c') diff --git a/src/contrib/nm-compat.c b/src/contrib/nm-compat.c new file mode 100644 index 0000000..f15c29c --- /dev/null +++ b/src/contrib/nm-compat.c @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-compat.h" + +/*****************************************************************************/ + +static void +_get_keys_cb(const char *key, const char *val, gpointer user_data) +{ + GPtrArray *a = user_data; + + g_ptr_array_add(a, g_strdup(key)); +} + +static const char ** +_get_keys(NMSettingVpn *setting, gboolean is_secrets, guint *out_length) +{ + guint len; + const char **keys = NULL; + GPtrArray * a; + + nm_assert(NM_IS_SETTING_VPN(setting)); + + if (is_secrets) + len = nm_setting_vpn_get_num_secrets(setting); + else + len = nm_setting_vpn_get_num_data_items(setting); + + a = g_ptr_array_sized_new(len + 1); + + if (is_secrets) + nm_setting_vpn_foreach_secret(setting, _get_keys_cb, a); + else + nm_setting_vpn_foreach_data_item(setting, _get_keys_cb, a); + + len = a->len; + if (len) { + g_ptr_array_sort(a, nm_strcmp_p); + g_ptr_array_add(a, NULL); + keys = g_malloc(a->len * sizeof(gpointer)); + memcpy(keys, a->pdata, a->len * sizeof(gpointer)); + + /* we need to cache the keys *somewhere*. */ + g_object_set_qdata_full(G_OBJECT(setting), + is_secrets + ? NM_CACHED_QUARK("libnm._nm_setting_vpn_get_secret_keys") + : NM_CACHED_QUARK("libnm._nm_setting_vpn_get_data_keys"), + g_ptr_array_free(a, FALSE), + (GDestroyNotify) g_strfreev); + } else + g_ptr_array_free(a, TRUE); + + NM_SET_OUT(out_length, len); + return keys; +} + +const char ** +_nm_setting_vpn_get_data_keys(NMSettingVpn *setting, guint *out_length) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), NULL); + + return _get_keys(setting, FALSE, out_length); +} + +const char ** +_nm_setting_vpn_get_secret_keys(NMSettingVpn *setting, guint *out_length) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), NULL); + + return _get_keys(setting, TRUE, out_length); +} diff --git a/src/contrib/nm-compat.h b/src/contrib/nm-compat.h new file mode 100644 index 0000000..33eaec1 --- /dev/null +++ b/src/contrib/nm-compat.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_COMPAT_H__ +#define __NM_COMPAT_H__ + +#include "nm-setting-vpn.h" + +/*****************************************************************************/ + +const char **_nm_setting_vpn_get_data_keys(NMSettingVpn *setting, guint *out_length); + +const char **_nm_setting_vpn_get_secret_keys(NMSettingVpn *setting, guint *out_length); + +#if NM_CHECK_VERSION(1, 11, 0) + #define nm_setting_vpn_get_data_keys(setting, out_length) \ + ({ \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + nm_setting_vpn_get_data_keys(setting, out_length); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + }) + #define nm_setting_vpn_get_secret_keys(setting, out_length) \ + ({ \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + nm_setting_vpn_get_secret_keys(setting, out_length); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + }) +#else + #define nm_setting_vpn_get_data_keys(setting, out_length) \ + _nm_setting_vpn_get_data_keys(setting, out_length) + #define nm_setting_vpn_get_secret_keys(setting, out_length) \ + _nm_setting_vpn_get_secret_keys(setting, out_length) +#endif + +/*****************************************************************************/ + +/* possibly missing defines from newer libnm API. */ + +#ifndef NM_VPN_PLUGIN_CONFIG_PROXY_PAC + #define NM_VPN_PLUGIN_CONFIG_PROXY_PAC "pac" +#endif + +#ifndef NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES + #define NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES "preserve-routes" +#endif + +#ifndef NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES + #define NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES "preserve-routes" +#endif + +/*****************************************************************************/ + +#endif /* __NM_COMPAT_H__ */ diff --git a/src/contrib/nm-vpn-editor-plugin-call.h b/src/contrib/nm-vpn-editor-plugin-call.h new file mode 100644 index 0000000..be0a677 --- /dev/null +++ b/src/contrib/nm-vpn-editor-plugin-call.h @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#ifndef __NM_VPN_EDITOR_PLUGIN_CALL_H__ +#define __NM_VPN_EDITOR_PLUGIN_CALL_H__ + +/* This header is an internal, header-only file that can be copied to + * other projects to call well-known service functions on VPN plugins. + * + * This uses the NMVpnEditorPluginVT and allows a user (nm-applet) + * to directly communicate with a VPN plugin using API that is newer + * then the current libnm version. That is, it allows to call to a VPN + * plugin bypassing libnm. */ + +#include + +/* we make use of other internal header files, you need those too. */ +#include "libnm-glib-aux/nm-macros-internal.h" + +/*****************************************************************************/ + +/** + * NMVpnEditorPluginServiceFlags: + * @NM_VPN_EDITOR_PLUGIN_SERVICE_FLAGS_NONE: no flags + * @NM_VPN_EDITOR_PLUGIN_SERVICE_FLAGS_CAN_ADD: whether the plugin can + * add a new connection for the given service-type. + **/ +typedef enum { /*< skip >*/ + NM_VPN_EDITOR_PLUGIN_SERVICE_FLAGS_NONE = 0x00, + NM_VPN_EDITOR_PLUGIN_SERVICE_FLAGS_CAN_ADD = 0x01, +} NMVpnEditorPluginServiceFlags; + +struct _NMVpnEditorPluginVT { + gboolean (*fcn_get_service_info)(NMVpnEditorPlugin * plugin, + const char * service_type, + char ** out_short_name, + char ** out_pretty_name, + char ** out_description, + NMVpnEditorPluginServiceFlags *out_flags); + char **(*fcn_get_service_add_details)(NMVpnEditorPlugin *plugin, const char *service_name); + gboolean (*fcn_get_service_add_detail)(NMVpnEditorPlugin *plugin, + const char * service_type, + const char * add_detail, + char ** out_pretty_name, + char ** out_description, + char ** out_add_detail_key, + char ** out_add_detail_val, + guint * out_flags); +}; + +/***************************************************************************** + * Call + * + * The following wrap the calling of generic functions for a VPN plugin. + * They are used by callers (for example nm-connection-editor). + *****************************************************************************/ + +static inline gboolean +nm_vpn_editor_plugin_get_service_info(NMVpnEditorPlugin * plugin, + const char * service_type, + char ** out_short_name, + char ** out_pretty_name, + char ** out_description, + NMVpnEditorPluginServiceFlags *out_flags) +{ + NMVpnEditorPluginVT vt; + gs_free char * short_name_local = NULL; + gs_free char * pretty_name_local = NULL; + gs_free char * description_local = NULL; + guint flags_local = 0; + + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), FALSE); + g_return_val_if_fail(service_type, FALSE); + + nm_vpn_editor_plugin_get_vt(plugin, &vt, sizeof(vt)); + if (!vt.fcn_get_service_info + || !vt.fcn_get_service_info(plugin, + service_type, + out_short_name ? &short_name_local : NULL, + out_pretty_name ? &pretty_name_local : NULL, + out_description ? &description_local : NULL, + out_flags ? &flags_local : NULL)) + return FALSE; + NM_SET_OUT(out_short_name, g_steal_pointer(&short_name_local)); + NM_SET_OUT(out_pretty_name, g_steal_pointer(&pretty_name_local)); + NM_SET_OUT(out_description, g_steal_pointer(&description_local)); + NM_SET_OUT(out_flags, flags_local); + return TRUE; +} + +static inline char ** +nm_vpn_editor_plugin_get_service_add_details(NMVpnEditorPlugin *plugin, const char *service_name) +{ + NMVpnEditorPluginVT vt; + char ** details = NULL; + + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), NULL); + g_return_val_if_fail(service_name, NULL); + + nm_vpn_editor_plugin_get_vt(plugin, &vt, sizeof(vt)); + if (vt.fcn_get_service_add_details) + details = vt.fcn_get_service_add_details(plugin, service_name); + if (!details) + return g_new0(char *, 1); + return details; +} + +static inline gboolean +nm_vpn_editor_plugin_get_service_add_detail(NMVpnEditorPlugin *plugin, + const char * service_type, + const char * add_detail, + char ** out_pretty_name, + char ** out_description, + char ** out_add_detail_key, + char ** out_add_detail_val, + guint * out_flags) +{ + NMVpnEditorPluginVT vt; + gs_free char * pretty_name_local = NULL; + gs_free char * description_local = NULL; + gs_free char * add_detail_key_local = NULL; + gs_free char * add_detail_val_local = NULL; + guint flags_local = 0; + + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), FALSE); + g_return_val_if_fail(service_type, FALSE); + g_return_val_if_fail(add_detail, FALSE); + + nm_vpn_editor_plugin_get_vt(plugin, &vt, sizeof(vt)); + if (!vt.fcn_get_service_add_detail + || !vt.fcn_get_service_add_detail(plugin, + service_type, + add_detail, + out_pretty_name ? &pretty_name_local : NULL, + out_description ? &description_local : NULL, + out_add_detail_key ? &add_detail_key_local : NULL, + out_add_detail_val ? &add_detail_val_local : NULL, + out_flags ? &flags_local : NULL)) + return FALSE; + NM_SET_OUT(out_pretty_name, g_steal_pointer(&pretty_name_local)); + NM_SET_OUT(out_description, g_steal_pointer(&description_local)); + NM_SET_OUT(out_add_detail_key, g_steal_pointer(&add_detail_key_local)); + NM_SET_OUT(out_add_detail_val, g_steal_pointer(&add_detail_val_local)); + NM_SET_OUT(out_flags, flags_local); + return TRUE; +} + +/***************************************************************************** + * Implementation + * + * The following glue code can be used to implement calls in a VPN plugin. + *****************************************************************************/ + +#define NM_VPN_EDITOR_PLUGIN_VT_DEFINE(vt_name, get_vt, ...) \ + static const NMVpnEditorPluginVT vt_name = {__VA_ARGS__}; \ + static const NMVpnEditorPluginVT *get_vt(NMVpnEditorPlugin *plugin, gsize *out_vt_size) \ + { \ + nm_assert(NM_IS_VPN_EDITOR_PLUGIN(plugin)); \ + nm_assert(out_vt_size); \ + \ + *out_vt_size = sizeof(vt_name); \ + return &vt_name; \ + } + +#endif /* __NM_VPN_EDITOR_PLUGIN_CALL_H__ */ diff --git a/src/contrib/nm-vpn-plugin-utils.c b/src/contrib/nm-vpn-plugin-utils.c new file mode 100644 index 0000000..b10695b --- /dev/null +++ b/src/contrib/nm-vpn-plugin-utils.c @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016, 2018 Red Hat, Inc. + */ + +#include "libnm-client-aux-extern/nm-default-client.h" + +#include "nm-vpn-plugin-utils.h" + +#include + +/*****************************************************************************/ + +NMVpnEditor * +nm_vpn_plugin_utils_load_editor(const char * module_name, + const char * factory_name, + NMVpnPluginUtilsEditorFactory editor_factory, + NMVpnEditorPlugin * editor_plugin, + NMConnection * connection, + gpointer user_data, + GError ** error) + +{ + static struct { + gpointer factory; + void * dl_module; + char * module_name; + char * factory_name; + } cached = {0}; + NMVpnEditor * editor; + gs_free char *module_path = NULL; + gs_free char *dirname = NULL; + Dl_info plugin_info; + + g_return_val_if_fail(module_name, NULL); + g_return_val_if_fail(factory_name && factory_name[0], NULL); + g_return_val_if_fail(editor_factory, NULL); + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(editor_plugin), NULL); + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + g_return_val_if_fail(!error || !*error, NULL); + + if (!g_path_is_absolute(module_name)) { + /* + * Load an editor from the same directory this plugin is in. + * Ideally, we'd get our .so name from the NMVpnEditorPlugin if it + * would just have a property with it... + */ + if (!dladdr(nm_vpn_plugin_utils_load_editor, &plugin_info)) { + /* Really a "can not happen" scenario. */ + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("unable to get editor plugin name: %s"), + dlerror()); + } + + dirname = g_path_get_dirname(plugin_info.dli_fname); + module_path = g_build_filename(dirname, module_name, NULL); + } else { + module_path = g_strdup(module_name); + } + + /* we really expect this function to be called with unchanging @module_name + * and @factory_name. And we only want to load the module once, hence it would + * be more complicated to accept changing @module_name/@factory_name arguments. + * + * The reason for only loading once is that due to glib types, we cannot create a + * certain type-name more then once, so loading the same module or another version + * of the same module will fail horribly as both try to create a GType with the same + * name. + * + * Only support loading once, any future calls will reuse the handle. To simplify + * that, we enforce that the @factory_name and @module_name is the same. */ + if (cached.factory) { + g_return_val_if_fail(cached.dl_module, NULL); + g_return_val_if_fail(cached.factory_name && nm_streq0(cached.factory_name, factory_name), + NULL); + g_return_val_if_fail(cached.module_name && nm_streq0(cached.module_name, module_name), + NULL); + } else { + gpointer factory; + void * dl_module; + + dl_module = dlopen(module_path, RTLD_LAZY | RTLD_LOCAL); + if (!dl_module) { + if (!g_file_test(module_path, G_FILE_TEST_EXISTS)) { + g_set_error(error, + G_FILE_ERROR, + G_FILE_ERROR_NOENT, + _("missing plugin file \"%s\""), + module_path); + return NULL; + } + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("cannot load editor plugin: %s"), + dlerror()); + return NULL; + } + + factory = dlsym(dl_module, factory_name); + if (!factory) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("cannot load factory %s from plugin: %s"), + factory_name, + dlerror()); + dlclose(dl_module); + return NULL; + } + + /* we cannot ever unload the module because it creates glib types, which + * cannot be unregistered. + * + * Thus we just leak the dl_module handle indefinitely. */ + cached.factory = factory; + cached.dl_module = dl_module; + cached.module_name = g_strdup(module_name); + cached.factory_name = g_strdup(factory_name); + } + + editor = editor_factory(cached.factory, editor_plugin, connection, user_data, error); + if (!editor) { + if (error && !*error) { + g_set_error_literal(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("unknown error creating editor instance")); + g_return_val_if_reached(NULL); + } + return NULL; + } + + g_return_val_if_fail(NM_IS_VPN_EDITOR(editor), NULL); + return editor; +} diff --git a/src/contrib/nm-vpn-plugin-utils.h b/src/contrib/nm-vpn-plugin-utils.h new file mode 100644 index 0000000..881a368 --- /dev/null +++ b/src/contrib/nm-vpn-plugin-utils.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#ifndef __NM_VPN_PLUGIN_UTILS_H__ +#define __NM_VPN_PLUGIN_UTILS_H__ + +#include + +typedef NMVpnEditor *(NMVpnPluginUtilsEditorFactory)(gpointer factory, + NMVpnEditorPlugin *editor_plugin, + NMConnection * connection, + gpointer user_data, + GError ** error); + +NMVpnEditor *nm_vpn_plugin_utils_load_editor(const char * module_name, + const char * factory_name, + NMVpnPluginUtilsEditorFactory editor_factory, + NMVpnEditorPlugin * editor_plugin, + NMConnection * connection, + gpointer user_data, + GError ** error); + +#endif /* __NM_VPN_PLUGIN_UTILS_H__ */ diff --git a/src/contrib/tests/meson.build b/src/contrib/tests/meson.build new file mode 100644 index 0000000..b9b22ca --- /dev/null +++ b/src/contrib/tests/meson.build @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +# just test, that we can build "nm-vpn-plugin-utils.c" +static_library( + 'nm-vpn-plugin-utils-test', + sources: nm_vpn_plugin_utils_source, + dependencies: [ + libnm_dep, + glib_dep, + ], +) diff --git a/src/core/NetworkManagerUtils.c b/src/core/NetworkManagerUtils.c index 5407221..59a65b0 100644 --- a/src/core/NetworkManagerUtils.c +++ b/src/core/NetworkManagerUtils.c @@ -12,19 +12,21 @@ #include #include -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-c-list.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-base/nm-net-aux.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-utils.h" #include "nm-setting-connection.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" -#include "nm-core-internal.h" -#include "platform/nmp-object.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nmp-object.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-linux-platform.h" #include "nm-auth-utils.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" /*****************************************************************************/ @@ -902,10 +904,16 @@ nm_match_spec_device_by_pllink(const NMPlatformLink *pllink, NMPlatformRoutingRule * nm_ip_routing_rule_to_platform(const NMIPRoutingRule *rule, NMPlatformRoutingRule *out_pl) { + gboolean uid_range_has; + guint32 uid_range_start = 0; + guint32 uid_range_end = 0; + nm_assert(rule); nm_assert(nm_ip_routing_rule_validate(rule, NULL)); nm_assert(out_pl); + uid_range_has = nm_ip_routing_rule_get_uid_range(rule, &uid_range_start, &uid_range_end); + *out_pl = (NMPlatformRoutingRule){ .addr_family = nm_ip_routing_rule_get_addr_family(rule), .flags = (nm_ip_routing_rule_get_invert(rule) ? FIB_RULE_INVERT : 0), @@ -932,6 +940,12 @@ nm_ip_routing_rule_to_platform(const NMIPRoutingRule *rule, NMPlatformRoutingRul .table = nm_ip_routing_rule_get_table(rule), .suppress_prefixlen_inverse = ~((guint32) nm_ip_routing_rule_get_suppress_prefixlength(rule)), + .uid_range_has = uid_range_has, + .uid_range = + { + .start = uid_range_start, + .end = uid_range_end, + }, }; nm_ip_routing_rule_get_xifname_bin(rule, TRUE, out_pl->iifname); @@ -1293,9 +1307,9 @@ nm_utils_ip_route_attribute_to_platform(int addr_family, if ((variant = nm_ip_route_get_attribute(s_route, NM_IP_ROUTE_ATTRIBUTE_TYPE)) && g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) { - guint8 type; + int type; - type = nm_utils_route_type_by_name(g_variant_get_string(variant, NULL)); + type = nm_net_aux_rtnl_rtntype_a2n(g_variant_get_string(variant, NULL)); nm_assert(NM_IN_SET(type, RTN_UNICAST, RTN_LOCAL)); r->type_coerced = nm_platform_route_type_coerce(type); @@ -1829,3 +1843,63 @@ nm_utils_share_rules_add_all_rules(NMUtilsShareRules *self, "INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT", ip_iface); } + +/*****************************************************************************/ + +/* Singleton NMPlatform subclass instance and cached class object */ +NM_DEFINE_SINGLETON_INSTANCE(NMPlatform); + +NM_DEFINE_SINGLETON_REGISTER(NMPlatform); + +/** + * nm_platform_setup: + * @instance: the #NMPlatform instance + * + * Failing to set up #NMPlatform singleton results in a fatal error, + * as well as trying to initialize it multiple times without freeing + * it. + * + * NetworkManager will typically use only one platform object during + * its run. Test programs might want to switch platform implementations, + * though. + */ +void +nm_platform_setup(NMPlatform *instance) +{ + g_return_if_fail(NM_IS_PLATFORM(instance)); + g_return_if_fail(!singleton_instance); + + singleton_instance = instance; + + nm_singleton_instance_register(); + + nm_log_dbg(LOGD_CORE, + "setup %s singleton (" NM_HASH_OBFUSCATE_PTR_FMT ")", + "NMPlatform", + NM_HASH_OBFUSCATE_PTR(instance)); +} + +/** + * nm_platform_get: + * @self: platform instance + * + * Retrieve #NMPlatform singleton. Use this whenever you want to connect to + * #NMPlatform signals. It is an error to call it before nm_platform_setup(). + * + * Returns: (transfer none): The #NMPlatform singleton reference. + */ +NMPlatform * +nm_platform_get() +{ + g_assert(singleton_instance); + + return singleton_instance; +} + +/*****************************************************************************/ + +void +nm_linux_platform_setup(void) +{ + nm_platform_setup(nm_linux_platform_new(FALSE, FALSE)); +} diff --git a/src/core/NetworkManagerUtils.h b/src/core/NetworkManagerUtils.h index 2afb5a3..a004dbb 100644 --- a/src/core/NetworkManagerUtils.h +++ b/src/core/NetworkManagerUtils.h @@ -8,10 +8,10 @@ #define __NETWORKMANAGER_UTILS_H__ #include "nm-core-utils.h" -#include "nm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-dedup-multi.h" #include "nm-setting-ip-config.h" #include "nm-setting-ip6-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" /*****************************************************************************/ @@ -251,4 +251,13 @@ void nm_utils_share_rules_apply(NMUtilsShareRules *self, gboolean shared); /*****************************************************************************/ +void nm_platform_setup(NMPlatform *instance); +NMPlatform *nm_platform_get(void); + +#define NM_PLATFORM_GET (nm_platform_get()) + +void nm_linux_platform_setup(void); + +/*****************************************************************************/ + #endif /* __NETWORKMANAGER_UTILS_H__ */ diff --git a/src/core/devices/adsl/meson.build b/src/core/devices/adsl/meson.build index 95f61d9..ef87c6e 100644 --- a/src/core/devices/adsl/meson.build +++ b/src/core/devices/adsl/meson.build @@ -7,7 +7,6 @@ libnm_device_plugin_adsl = shared_module( 'nm-device-adsl.c', ), dependencies: core_plugin_dep, - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/adsl/nm-atm-manager.c b/src/core/devices/adsl/nm-atm-manager.c index 9be9b5c..bd9ed8c 100644 --- a/src/core/devices/adsl/nm-atm-manager.c +++ b/src/core/devices/adsl/nm-atm-manager.c @@ -11,8 +11,8 @@ #include "nm-setting-adsl.h" #include "nm-device-adsl.h" #include "devices/nm-device-factory.h" -#include "platform/nm-platform.h" -#include "nm-udev-aux/nm-udev-utils.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-udev-aux/nm-udev-utils.h" /*****************************************************************************/ diff --git a/src/core/devices/adsl/nm-device-adsl.c b/src/core/devices/adsl/nm-device-adsl.c index 34c062a..01a1b39 100644 --- a/src/core/devices/adsl/nm-device-adsl.c +++ b/src/core/devices/adsl/nm-device-adsl.c @@ -17,7 +17,7 @@ #include "nm-ip4-config.h" #include "devices/nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "ppp/nm-ppp-manager-call.h" #include "ppp/nm-ppp-status.h" #include "nm-setting-adsl.h" diff --git a/src/core/devices/bluetooth/meson.build b/src/core/devices/bluetooth/meson.build index d5f2606..5b196d0 100644 --- a/src/core/devices/bluetooth/meson.build +++ b/src/core/devices/bluetooth/meson.build @@ -8,11 +8,11 @@ libnm_device_plugin_bluetooth_static = static_library( 'nm-device-bt.c', ) + (enable_bluez5_dun ? files('nm-bluez5-dun.c') : files()), dependencies: [ + libnm_core_public_dep, core_default_dep, libnm_wwan_dep, bluez5_dep, ], - c_args: daemon_c_flags, ) libnm_device_plugin_bluetooth_static_dep = declare_dependency( diff --git a/src/core/devices/bluetooth/nm-bluez-manager.c b/src/core/devices/bluetooth/nm-bluez-manager.c index dd998d2..a16a22a 100644 --- a/src/core/devices/bluetooth/nm-bluez-manager.c +++ b/src/core/devices/bluetooth/nm-bluez-manager.c @@ -12,8 +12,8 @@ #include #include -#include "nm-glib-aux/nm-dbus-aux.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-dbus-manager.h" #include "devices/nm-device-factory.h" #include "devices/nm-device-bridge.h" @@ -23,9 +23,9 @@ #include "nm-device-bt.h" #include "nm-manager.h" #include "nm-bluez5-dun.h" -#include "nm-core-internal.h" -#include "platform/nm-platform.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-std-aux/nm-dbus-compat.h" /*****************************************************************************/ diff --git a/src/core/devices/bluetooth/nm-device-bt.c b/src/core/devices/bluetooth/nm-device-bt.c index c07be2d..c7f76a5 100644 --- a/src/core/devices/bluetooth/nm-device-bt.c +++ b/src/core/devices/bluetooth/nm-device-bt.c @@ -10,7 +10,7 @@ #include #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-bluez-common.h" #include "nm-bluez-manager.h" #include "devices/nm-device-private.h" @@ -26,7 +26,7 @@ #include "nm-utils.h" #include "nm-bt-error.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "devices/wwan/nm-modem-manager.h" #include "devices/wwan/nm-modem.h" diff --git a/src/core/devices/nm-acd-manager.c b/src/core/devices/nm-acd-manager.c index b95f90f..995abac 100644 --- a/src/core/devices/nm-acd-manager.c +++ b/src/core/devices/nm-acd-manager.c @@ -12,7 +12,7 @@ #include #include -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" #include "NetworkManagerUtils.h" #include "n-acd/src/n-acd.h" diff --git a/src/core/devices/nm-device-6lowpan.c b/src/core/devices/nm-device-6lowpan.c index fe116dd..9621865 100644 --- a/src/core/devices/nm-device-6lowpan.c +++ b/src/core/devices/nm-device-6lowpan.c @@ -9,7 +9,7 @@ #include "nm-device-private.h" #include "settings/nm-settings.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-6lowpan.h" #include "nm-utils.h" diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c index f68c080..29d3abb 100644 --- a/src/core/devices/nm-device-bond.c +++ b/src/core/devices/nm-device-bond.c @@ -12,9 +12,9 @@ #include "NetworkManagerUtils.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-ip4-config.h" #define _NMLOG_DEVICE_TYPE NMDeviceBond @@ -109,6 +109,24 @@ _set_bond_attr(NMDevice *device, const char *attr, const char *value) int ifindex = nm_device_get_ifindex(device); gboolean ret; + nm_assert(attr && attr[0]); + nm_assert(value); + + if (nm_streq(value, NM_BOND_AD_ACTOR_SYSTEM_DEFAULT) + && nm_streq(attr, NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM)) { + gs_free char *cur_val = NULL; + + /* kernel does not allow setting ad_actor_system to "00:00:00:00:00:00". We would thus + * log an EINVAL error. Avoid that... at least, if the value is already "00:00:00:00:00:00". */ + cur_val = + nm_platform_sysctl_master_get_option(nm_device_get_platform(device), ifindex, attr); + if (nm_streq0(cur_val, NM_BOND_AD_ACTOR_SYSTEM_DEFAULT)) + return TRUE; + + /* OK, the current value is different, and we will proceed setting "00:00:00:00:00:00". + * That will fail, and we will log a warning. There is nothing else to do. */ + } + ret = nm_platform_sysctl_master_set_option(nm_device_get_platform(device), ifindex, attr, value); if (!ret) @@ -426,9 +444,10 @@ release_slave(NMDevice *device, NMDevice *slave, gboolean configure) _LOGD(LOGD_BOND, "bond slave %s is already released", nm_device_get_ip_iface(slave)); if (configure) { - /* When the last slave is released the bond MAC will be set to a random - * value by kernel; remember the current one and restore it afterwards. - */ + NMConnection * applied; + NMSettingWired *s_wired; + const char * cloned_mac; + address = g_strdup(nm_device_get_hw_address(device)); if (ifindex_slave > 0) { @@ -443,9 +462,16 @@ release_slave(NMDevice *device, NMDevice *slave, gboolean configure) } } - nm_platform_process_events(nm_device_get_platform(device)); - if (nm_device_update_hw_address(device)) - nm_device_hw_addr_set(device, address, "restore", FALSE); + if ((applied = nm_device_get_applied_connection(device)) + && ((s_wired = nm_connection_get_setting_wired(applied))) + && ((cloned_mac = nm_setting_wired_get_cloned_mac_address(s_wired)))) { + /* When the last slave is released the bond MAC will be set to a random + * value by kernel; if we have set a cloned-mac-address, we need to + * restore it to the previous value. */ + nm_platform_process_events(nm_device_get_platform(device)); + if (nm_device_update_hw_address(device)) + nm_device_hw_addr_set(device, address, "restore", FALSE); + } /* Kernel bonding code "closes" the slave when releasing it, (which clears * IFF_UP), so we must bring it back up here to ensure carrier changes and diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c index c919d85..8bed783 100644 --- a/src/core/devices/nm-device-bridge.c +++ b/src/core/devices/nm-device-bridge.c @@ -12,9 +12,9 @@ #include "NetworkManagerUtils.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceBridge #include "nm-device-logging.h" @@ -1033,7 +1033,7 @@ create_and_realize(NMDevice * device, const char * iface = nm_device_get_iface(device); const char * hwaddr; gs_free char * hwaddr_cloned = NULL; - guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX]; + guint8 mac_address[_NM_UTILS_HWADDR_LEN_MAX]; NMPlatformLnkBridge props; int r; guint32 mtu = 0; diff --git a/src/core/devices/nm-device-dummy.c b/src/core/devices/nm-device-dummy.c index 13cfd3b..bb7150c 100644 --- a/src/core/devices/nm-device-dummy.c +++ b/src/core/devices/nm-device-dummy.c @@ -13,10 +13,10 @@ #include "nm-act-request.h" #include "nm-device-private.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-dummy.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceDummy #include "nm-device-logging.h" diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c index 4442886..c96cd15 100644 --- a/src/core/devices/nm-device-ethernet.c +++ b/src/core/devices/nm-device-ethernet.c @@ -24,17 +24,17 @@ #include "ppp/nm-ppp-manager.h" #include "ppp/nm-ppp-manager-call.h" #include "ppp/nm-ppp-status.h" -#include "platform/nm-platform.h" -#include "nm-platform/nm-platform-utils.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-platform-utils.h" #include "nm-dcb.h" #include "settings/nm-settings-connection.h" #include "nm-config.h" #include "nm-device-ethernet-utils.h" #include "settings/nm-settings.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" -#include "nm-udev-aux/nm-udev-utils.h" +#include "libnm-udev-aux/nm-udev-utils.h" #include "nm-device-veth.h" #define _NMLOG_DEVICE_TYPE NMDeviceEthernet @@ -730,7 +730,9 @@ supplicant_iface_state_cb(NMSupplicantInterface *iface, if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { supplicant_interface_release(self); - wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); return; } @@ -1784,7 +1786,8 @@ update_connection(NMDevice *device, NMConnection *connection) const char * mac = nm_device_get_hw_address(device); const char * mac_prop = NM_SETTING_WIRED_MAC_ADDRESS; GHashTableIter iter; - gpointer key, value; + const char * key; + const char * value; if (!s_wired) { s_wired = (NMSettingWired *) nm_setting_wired_new(); @@ -1822,8 +1825,8 @@ update_connection(NMDevice *device, NMConnection *connection) _nm_setting_wired_clear_s390_options(s_wired); g_hash_table_iter_init(&iter, priv->s390_options); - while (g_hash_table_iter_next(&iter, &key, &value)) - nm_setting_wired_add_s390_option(s_wired, (const char *) key, (const char *) value); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) + nm_setting_wired_add_s390_option(s_wired, key, value); } static void diff --git a/src/core/devices/nm-device-factory.c b/src/core/devices/nm-device-factory.c index 81124a8..bdc6413 100644 --- a/src/core/devices/nm-device-factory.c +++ b/src/core/devices/nm-device-factory.c @@ -11,9 +11,9 @@ #include #include -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-setting-bluetooth.h" #define PLUGIN_PREFIX "libnm-device-plugin-" diff --git a/src/core/devices/nm-device-generic.c b/src/core/devices/nm-device-generic.c index a319666..299cb08 100644 --- a/src/core/devices/nm-device-generic.c +++ b/src/core/devices/nm-device-generic.c @@ -8,8 +8,8 @@ #include "nm-device-generic.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" /*****************************************************************************/ diff --git a/src/core/devices/nm-device-infiniband.c b/src/core/devices/nm-device-infiniband.c index f54ffcf..9543025 100644 --- a/src/core/devices/nm-device-infiniband.c +++ b/src/core/devices/nm-device-infiniband.c @@ -14,9 +14,9 @@ #include "nm-device-private.h" #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define NM_DEVICE_INFINIBAND_IS_PARTITION "is-partition" diff --git a/src/core/devices/nm-device-ip-tunnel.c b/src/core/devices/nm-device-ip-tunnel.c index da6afb3..1e7f134 100644 --- a/src/core/devices/nm-device-ip-tunnel.c +++ b/src/core/devices/nm-device-ip-tunnel.c @@ -16,9 +16,9 @@ #include "nm-device-private.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-ip4-config.h" diff --git a/src/core/devices/nm-device-macsec.c b/src/core/devices/nm-device-macsec.c index 51b820a..14844c4 100644 --- a/src/core/devices/nm-device-macsec.c +++ b/src/core/devices/nm-device-macsec.c @@ -11,11 +11,11 @@ #include "nm-act-request.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-manager.h" #include "nm-setting-macsec.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "supplicant/nm-supplicant-manager.h" #include "supplicant/nm-supplicant-interface.h" #include "supplicant/nm-supplicant-config.h" diff --git a/src/core/devices/nm-device-macvlan.c b/src/core/devices/nm-device-macvlan.c index e8b39ed..b9903bc 100644 --- a/src/core/devices/nm-device-macvlan.c +++ b/src/core/devices/nm-device-macvlan.c @@ -13,7 +13,7 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-macvlan.h" #include "nm-setting-wired.h" diff --git a/src/core/devices/nm-device-ppp.c b/src/core/devices/nm-device-ppp.c index 4040f2d..b642d0d 100644 --- a/src/core/devices/nm-device-ppp.c +++ b/src/core/devices/nm-device-ppp.c @@ -13,7 +13,7 @@ #include "nm-device-private.h" #include "nm-manager.h" #include "nm-setting-pppoe.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "ppp/nm-ppp-manager.h" #include "ppp/nm-ppp-manager-call.h" #include "ppp/nm-ppp-status.h" diff --git a/src/core/devices/nm-device-tun.c b/src/core/devices/nm-device-tun.c index edca69e..1b3348d 100644 --- a/src/core/devices/nm-device-tun.c +++ b/src/core/devices/nm-device-tun.c @@ -14,10 +14,10 @@ #include "nm-act-request.h" #include "nm-device-private.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-tun.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceTun #include "nm-device-logging.h" diff --git a/src/core/devices/nm-device-veth.c b/src/core/devices/nm-device-veth.c index e0ba843..b1737b5 100644 --- a/src/core/devices/nm-device-veth.c +++ b/src/core/devices/nm-device-veth.c @@ -7,11 +7,11 @@ #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-device-veth.h" #include "nm-device-private.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-veth.h" diff --git a/src/core/devices/nm-device-vlan.c b/src/core/devices/nm-device-vlan.c index bfde60e..3b426ef 100644 --- a/src/core/devices/nm-device-vlan.c +++ b/src/core/devices/nm-device-vlan.c @@ -16,11 +16,12 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-manager.h" -#include "nm-core-internal.h" -#include "platform/nmp-object.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nm-platform-utils.h" #define _NMLOG_DEVICE_TYPE NMDeviceVlan #include "nm-device-logging.h" @@ -436,7 +437,7 @@ update_connection(NMDevice *device, NMConnection *connection) const NMPlatformLink *plink; const NMPObject * polnk; guint vlan_id; - guint vlan_flags; + _NMVlanFlags vlan_flags; if (!s_vlan) { s_vlan = (NMSettingVlan *) nm_setting_vlan_new(); @@ -463,9 +464,9 @@ update_connection(NMDevice *device, NMConnection *connection) if (polnk) vlan_flags = polnk->lnk_vlan.flags; else - vlan_flags = NM_VLAN_FLAG_REORDER_HEADERS; - if (vlan_flags != nm_setting_vlan_get_flags(s_vlan)) - g_object_set(s_vlan, NM_SETTING_VLAN_FLAGS, (NMVlanFlags) vlan_flags, NULL); + vlan_flags = _NM_VLAN_FLAG_REORDER_HEADERS; + if (NM_VLAN_FLAGS_CAST(vlan_flags) != nm_setting_vlan_get_flags(s_vlan)) + g_object_set(s_vlan, NM_SETTING_VLAN_FLAGS, NM_VLAN_FLAGS_CAST(vlan_flags), NULL); if (polnk) { _nm_setting_vlan_set_priorities(s_vlan, @@ -507,7 +508,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) nm_platform_link_vlan_change(nm_device_get_platform(device), nm_device_get_ifindex(device), - NM_VLAN_FLAGS_ALL, + _NM_VLAN_FLAGS_ALL, nm_setting_vlan_get_flags(s_vlan), TRUE, ingress_map, @@ -674,7 +675,7 @@ get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const c * device, we create one for it using the VLAN ID and the parent * interface's name. */ - return nm_utils_new_vlan_name(parent_iface, nm_setting_vlan_get_id(s_vlan)); + return nmp_utils_new_vlan_name(parent_iface, nm_setting_vlan_get_id(s_vlan)); } NM_DEVICE_FACTORY_DEFINE_INTERNAL( diff --git a/src/core/devices/nm-device-vrf.c b/src/core/devices/nm-device-vrf.c index 4fec59b..2a1f42c 100644 --- a/src/core/devices/nm-device-vrf.c +++ b/src/core/devices/nm-device-vrf.c @@ -4,12 +4,12 @@ #include "nm-device-vrf.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-device-factory.h" #include "nm-device-private.h" #include "nm-manager.h" #include "nm-setting-vrf.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "settings/nm-settings.h" #define _NMLOG_DEVICE_TYPE NMDeviceVrf diff --git a/src/core/devices/nm-device-vxlan.c b/src/core/devices/nm-device-vxlan.c index f16a52c..557b545 100644 --- a/src/core/devices/nm-device-vxlan.c +++ b/src/core/devices/nm-device-vxlan.c @@ -9,7 +9,7 @@ #include "nm-device-private.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" #include "nm-device-factory.h" #include "nm-setting-vxlan.h" @@ -17,7 +17,7 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceVxlan #include "nm-device-logging.h" diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c index 5bee09e..09030dd 100644 --- a/src/core/devices/nm-device-wireguard.c +++ b/src/core/devices/nm-device-wireguard.c @@ -11,12 +11,12 @@ #include #include "nm-setting-wireguard.h" -#include "nm-core-internal.h" -#include "nm-glib-aux/nm-secret-utils.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-glib-aux/nm-secret-utils.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" -#include "platform/nmp-rules-manager.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nmp-rules-manager.h" #include "nm-device-factory.h" #include "nm-active-connection.h" #include "nm-act-request.h" diff --git a/src/core/devices/nm-device-wpan.c b/src/core/devices/nm-device-wpan.c index 2f3b16f..73d7941 100644 --- a/src/core/devices/nm-device-wpan.c +++ b/src/core/devices/nm-device-wpan.c @@ -15,10 +15,10 @@ #include "nm-act-request.h" #include "nm-device-private.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-wpan.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceWpan #include "nm-device-logging.h" diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 040dd0b..e93a32d 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -23,22 +23,22 @@ #include #include -#include "nm-std-aux/unaligned.h" -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-glib-aux/nm-random-utils.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-random-utils.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" -#include "nm-base/nm-ethtool-base.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-base/nm-ethtool-base.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-device-private.h" #include "nm-l3cfg.h" #include "nm-l3-config-data.h" #include "NetworkManagerUtils.h" #include "nm-manager.h" -#include "platform/nm-platform.h" -#include "nm-platform/nm-platform-utils.h" -#include "platform/nmp-object.h" -#include "platform/nmp-rules-manager.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nmp-rules-manager.h" #include "ndisc/nm-ndisc.h" #include "ndisc/nm-lndp-ndisc.h" #include "dhcp/nm-dhcp-manager.h" @@ -65,7 +65,7 @@ #include "c-list/src/c-list.h" #include "dns/nm-dns-manager.h" #include "nm-acd-manager.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "systemd/nm-sd.h" #include "nm-lldp-listener.h" #include "nm-audit-manager.h" @@ -1567,7 +1567,7 @@ _prop_get_ipvx_dhcp_iaid(NMDevice * self, iaid = unaligned_read_be32(&pllink->l_address.data[pllink->l_address.len - 4]); goto out_good; } else if (nm_streq0(iaid_str, NM_IAID_PERM_MAC)) { - guint8 hwaddr_buf[NM_UTILS_HWADDR_LEN_MAX]; + guint8 hwaddr_buf[_NM_UTILS_HWADDR_LEN_MAX]; const char *hwaddr_str; gsize hwaddr_len; @@ -1729,7 +1729,7 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes * gs_free char * client_id_default = NULL; guint8 * client_id_buf; const char * fail_reason; - guint8 hwaddr_bin_buf[NM_UTILS_HWADDR_LEN_MAX]; + guint8 hwaddr_bin_buf[_NM_UTILS_HWADDR_LEN_MAX]; const guint8 * hwaddr_bin; int arp_type; gsize hwaddr_len; @@ -5216,11 +5216,11 @@ ndisc_set_router_config(NMNDisc *ndisc, NMDevice *self) if (addr->plen != 64) continue; - lifetime = nm_utils_lifetime_get(addr->timestamp, - addr->lifetime, - addr->preferred, - NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000, - &preferred); + lifetime = nmp_utils_lifetime_get(addr->timestamp, + addr->lifetime, + addr->preferred, + NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000, + &preferred); if (!lifetime) continue; @@ -7467,11 +7467,10 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e s_match = (NMSettingMatch *) nm_connection_get_setting(connection, NM_TYPE_SETTING_MATCH); if (s_match) { const char *const *patterns; - const char * device_driver; guint num_patterns = 0; patterns = nm_setting_match_get_interface_names(s_match, &num_patterns); - if (!nm_wildcard_match_check(device_iface, patterns, num_patterns)) { + if (num_patterns > 0 && !nm_wildcard_match_check(device_iface, patterns, num_patterns)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "device does not satisfy match.interface-name property"); @@ -7486,9 +7485,9 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e error)) return FALSE; - device_driver = nm_device_get_driver(self); - patterns = nm_setting_match_get_drivers(s_match, &num_patterns); - if (!nm_wildcard_match_check(device_driver, patterns, num_patterns)) { + patterns = nm_setting_match_get_drivers(s_match, &num_patterns); + if (num_patterns > 0 + && !nm_wildcard_match_check(nm_device_get_driver(self), patterns, num_patterns)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "device does not satisfy match.driver property"); @@ -7496,7 +7495,7 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e } patterns = nm_setting_match_get_paths(s_match, &num_patterns); - if (!nm_wildcard_match_check(priv->path, patterns, num_patterns)) { + if (num_patterns > 0 && !nm_wildcard_match_check(priv->path, patterns, num_patterns)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, "device does not satisfy match.path property"); @@ -11634,7 +11633,7 @@ share_init(NMDevice *self, GError **error) } for (i = 0; i < G_N_ELEMENTS(modules); i++) - nm_utils_modprobe(NULL, FALSE, modules[i], NULL); + nmp_utils_modprobe(NULL, FALSE, modules[i], NULL); return TRUE; } @@ -13478,12 +13477,13 @@ nm_device_set_ip_config(NMDevice * self, gboolean commit, GPtrArray * ip4_dev_route_blacklist) { - NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); - const int IS_IPv4 = NM_IS_IPv4(addr_family); - NMIPConfig * old_config; - gboolean has_changes = FALSE; - gboolean success = TRUE; - NMSettingsConnection *settings_connection; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + const int IS_IPv4 = NM_IS_IPv4(addr_family); + NMIPConfig * old_config; + gboolean has_changes = FALSE; + gboolean success = TRUE; + NMSettingsConnection * settings_connection; + NMIPRouteTableSyncMode route_table_sync_mode; nm_assert_addr_family(addr_family); nm_assert(!new_config || nm_ip_config_get_addr_family(new_config) == addr_family); @@ -13495,11 +13495,18 @@ nm_device_set_ip_config(NMDevice * self, }))); nm_assert(IS_IPv4 || !ip4_dev_route_blacklist); + if (commit && new_config) + route_table_sync_mode = _get_route_table_sync_mode_stateful(self, addr_family); + else + route_table_sync_mode = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE; + _LOGD(LOGD_IPX(IS_IPv4), - "ip%c-config: update (commit=%d, new-config=%p)", + "ip%c-config: update (commit=%d, new-config=" NM_HASH_OBFUSCATE_PTR_FMT + ", route-table-sync-mode=%d)", nm_utils_addr_family_to_char(addr_family), commit, - new_config); + NM_HASH_OBFUSCATE_PTR(new_config), + (int) route_table_sync_mode); /* Always commit to nm-platform to update lifetimes */ if (commit && new_config) { @@ -13508,7 +13515,7 @@ nm_device_set_ip_config(NMDevice * self, if (IS_IPv4) { success = nm_ip4_config_commit(NM_IP4_CONFIG(new_config), nm_device_get_platform(self), - _get_route_table_sync_mode_stateful(self, AF_INET)); + route_table_sync_mode); nm_platform_ip4_dev_route_blacklist_set(nm_device_get_platform(self), nm_ip_config_get_ifindex(new_config), ip4_dev_route_blacklist); @@ -13517,7 +13524,7 @@ nm_device_set_ip_config(NMDevice * self, success = nm_ip6_config_commit(NM_IP6_CONFIG(new_config), nm_device_get_platform(self), - _get_route_table_sync_mode_stateful(self, AF_INET6), + route_table_sync_mode, &temporary_not_available); if (!_rt6_temporary_not_available_set(self, temporary_not_available)) @@ -16821,7 +16828,7 @@ const char * nm_device_get_hw_address(NMDevice *self) { NMDevicePrivate *priv; - char buf[NM_UTILS_HWADDR_LEN_MAX]; + char buf[_NM_UTILS_HWADDR_LEN_MAX]; gsize l; g_return_val_if_fail(NM_IS_DEVICE(self), NULL); @@ -16915,7 +16922,7 @@ void nm_device_update_permanent_hw_address(NMDevice *self, gboolean force_freeze) { NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); - guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + guint8 buf[_NM_UTILS_HWADDR_LEN_MAX]; size_t len = 0; gboolean success_read; int ifindex; @@ -17033,7 +17040,7 @@ _hw_addr_set(NMDevice * self, NMDevicePrivate *priv; gboolean success = FALSE; int r; - guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX]; + guint8 addr_bytes[_NM_UTILS_HWADDR_LEN_MAX]; gsize addr_len; gboolean was_taken_down = FALSE; gboolean retry_down; @@ -18216,7 +18223,7 @@ constructor(GType type, guint n_construct_params, GObjectConstructParam *constru } if (priv->hw_addr_perm) { - guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + guint8 buf[_NM_UTILS_HWADDR_LEN_MAX]; gsize l; if (!_nm_utils_hwaddr_aton(priv->hw_addr_perm, buf, sizeof(buf), &l)) { diff --git a/src/core/devices/nm-lldp-listener.c b/src/core/devices/nm-lldp-listener.c index c60fb3a..808c1e2 100644 --- a/src/core/devices/nm-lldp-listener.c +++ b/src/core/devices/nm-lldp-listener.c @@ -9,9 +9,12 @@ #include -#include "nm-std-aux/unaligned.h" -#include "platform/nm-platform.h" -#include "nm-glib-aux/nm-c-list.h" +#include "NetworkManagerUtils.h" +#include "libnm-core-public/nm-errors.h" +#include "libnm-glib-aux/nm-time-utils.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-utils.h" #include "systemd/nm-sd.h" diff --git a/src/core/devices/ovs/meson.build b/src/core/devices/ovs/meson.build index 81c29bd..1974ff4 100644 --- a/src/core/devices/ovs/meson.build +++ b/src/core/devices/ovs/meson.build @@ -13,7 +13,6 @@ libnm_device_plugin_ovs = shared_module( core_plugin_dep, jansson_dep, ], - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/ovs/nm-device-ovs-bridge.c b/src/core/devices/ovs/nm-device-ovs-bridge.c index 3ae8a48..37feb2f 100644 --- a/src/core/devices/ovs/nm-device-ovs-bridge.c +++ b/src/core/devices/ovs/nm-device-ovs-bridge.c @@ -16,7 +16,7 @@ #include "nm-setting-connection.h" #include "nm-setting-ovs-bridge.h" #include "nm-setting-ovs-external-ids.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceOvsBridge #include "devices/nm-device-logging.h" diff --git a/src/core/devices/ovs/nm-ovs-factory.c b/src/core/devices/ovs/nm-ovs-factory.c index e7af38d..6f5d883 100644 --- a/src/core/devices/ovs/nm-ovs-factory.c +++ b/src/core/devices/ovs/nm-ovs-factory.c @@ -10,8 +10,8 @@ #include "nm-device-ovs-interface.h" #include "nm-device-ovs-port.h" #include "nm-device-ovs-bridge.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/nm-settings.h" #include "devices/nm-device-factory.h" #include "devices/nm-device-private.h" diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index da3a798..b8d5311 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -10,10 +10,10 @@ #include #include -#include "nm-glib-aux/nm-jansson.h" -#include "nm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-jansson.h" +#include "libnm-glib-aux/nm-str-buf.h" #include "nm-core-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "devices/nm-device.h" #include "nm-manager.h" #include "nm-setting-ovs-external-ids.h" diff --git a/src/core/devices/team/meson.build b/src/core/devices/team/meson.build index d0ff4ca..b1ee910 100644 --- a/src/core/devices/team/meson.build +++ b/src/core/devices/team/meson.build @@ -11,7 +11,6 @@ libnm_device_plugin_team = shared_module( jansson_dep, libteamdctl_dep, ], - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c index d2d7172..efd71dc 100644 --- a/src/core/devices/team/nm-device-team.c +++ b/src/core/devices/team/nm-device-team.c @@ -15,15 +15,15 @@ #include #include -#include "nm-glib-aux/nm-jansson.h" +#include "libnm-glib-aux/nm-jansson.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-config.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" #include "nm-ip4-config.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #define _NMLOG_DEVICE_TYPE NMDeviceTeam #include "devices/nm-device-logging.h" diff --git a/src/core/devices/team/nm-team-factory.c b/src/core/devices/team/nm-team-factory.c index 57b51bf..e2040d1 100644 --- a/src/core/devices/team/nm-team-factory.c +++ b/src/core/devices/team/nm-team-factory.c @@ -10,8 +10,8 @@ #include "nm-manager.h" #include "devices/nm-device-factory.h" #include "nm-device-team.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" /*****************************************************************************/ diff --git a/src/core/devices/wifi/meson.build b/src/core/devices/wifi/meson.build index 743937d..85553c5 100644 --- a/src/core/devices/wifi/meson.build +++ b/src/core/devices/wifi/meson.build @@ -22,7 +22,6 @@ libnm_device_plugin_wifi_static = static_library( dependencies: [ core_plugin_dep, ], - c_args: daemon_c_flags, ) libnm_device_plugin_wifi_static_dep = declare_dependency( @@ -38,7 +37,6 @@ libnm_device_plugin_wifi = shared_module( core_plugin_dep, libnm_device_plugin_wifi_static_dep ], - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c index 95ade44..760ed89 100644 --- a/src/core/devices/wifi/nm-device-iwd.c +++ b/src/core/devices/wifi/nm-device-iwd.c @@ -13,16 +13,16 @@ #include "devices/nm-device.h" #include "nm-act-request.h" #include "nm-config.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-iwd-manager.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-setting-8021x.h" #include "nm-setting-connection.h" #include "nm-setting-wireless-security.h" #include "nm-setting-wireless.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-utils.h" #include "nm-wifi-common.h" #include "nm-wifi-utils.h" @@ -55,7 +55,7 @@ typedef struct { CList aps_lst_head; NMWifiAP * current_ap; GCancellable * cancellable; - NMDeviceWifiCapabilities capabilities; + _NMDeviceWifiCapabilities capabilities; NMActRequestGetSecretsCallId *wifi_secrets_id; guint periodic_scan_id; guint periodic_update_id; @@ -265,7 +265,7 @@ ap_from_network(NMDeviceIwd *self, .bss_path = bss_path, .last_seen_msec = last_seen_msec, .bssid_valid = TRUE, - .mode = NM_802_11_MODE_INFRA, + .mode = _NM_802_11_MODE_INFRA, .rsn_flags = ap_security_flags_from_network_type(type), .ssid = ssid, .signal_percent = nm_wifi_utils_level_to_quality(signal / 100), @@ -588,10 +588,16 @@ deactivate(NMDevice *device) return; } - cleanup_association_attempt(self, TRUE); + cleanup_association_attempt(self, FALSE); priv->act_mode_switch = FALSE; - if (!priv->dbus_station_proxy) + /* Don't trigger any actions on the IWD side until the device is managed */ + if (priv->iwd_autoconnect && nm_device_get_state(device) < NM_DEVICE_STATE_DISCONNECTED) + return; + + if (priv->dbus_station_proxy) + send_disconnect(self); + else reset_mode(self, NULL, NULL, NULL); } @@ -647,6 +653,11 @@ deactivate_async(NMDevice * device, cleanup_association_attempt(self, FALSE); priv->act_mode_switch = FALSE; + if (priv->iwd_autoconnect && nm_device_get_state(device) < NM_DEVICE_STATE_DISCONNECTED) { + nm_utils_invoke_on_idle(cancellable, disconnect_cb_on_idle, user_data); + return; + } + if (priv->dbus_station_proxy) { g_dbus_proxy_call(priv->dbus_station_proxy, "Disconnect", @@ -801,7 +812,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * NMSettingWirelessSecurity *s_wireless_sec = nm_connection_get_setting_wireless_security(connection); - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_AP)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, "device does not support Access Point mode"); @@ -819,7 +830,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * NMSettingWirelessSecurity *s_wireless_sec = nm_connection_get_setting_wireless_security(connection); - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_ADHOC)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, "device does not support Ad-Hoc mode"); @@ -2610,9 +2621,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) switch (prop_id) { case PROP_MODE: if (!priv->current_ap) - g_value_set_uint(value, NM_802_11_MODE_UNKNOWN); + g_value_set_uint(value, _NM_802_11_MODE_UNKNOWN); else if (nm_wifi_ap_is_hotspot(priv->current_ap)) - g_value_set_uint(value, NM_802_11_MODE_AP); + g_value_set_uint(value, _NM_802_11_MODE_AP); else g_value_set_uint(value, nm_wifi_ap_get_mode(priv->current_ap)); @@ -3034,7 +3045,7 @@ nm_device_iwd_set_dbus_object(NMDeviceIwd *self, GDBusObject *object) GVariantIter * iter; const char * mode; gboolean powered; - NMDeviceWifiCapabilities capabilities; + _NMDeviceWifiCapabilities capabilities; if (!nm_g_object_ref_set(&priv->dbus_obj, object)) return; @@ -3096,14 +3107,14 @@ nm_device_iwd_set_dbus_object(NMDeviceIwd *self, GDBusObject *object) goto error; } - capabilities = NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN; + capabilities = _NM_WIFI_DEVICE_CAP_CIPHER_CCMP | _NM_WIFI_DEVICE_CAP_RSN; g_variant_get(value, "as", &iter); while (g_variant_iter_next(iter, "&s", &mode)) { if (nm_streq(mode, "ap")) - capabilities |= NM_WIFI_DEVICE_CAP_AP; + capabilities |= _NM_WIFI_DEVICE_CAP_AP; else if (nm_streq(mode, "ad-hoc")) - capabilities |= NM_WIFI_DEVICE_CAP_ADHOC; + capabilities |= _NM_WIFI_DEVICE_CAP_ADHOC; } g_variant_iter_free(iter); @@ -3452,9 +3463,9 @@ nm_device_iwd_class_init(NMDeviceIwdClass *klass) obj_properties[PROP_MODE] = g_param_spec_uint(NM_DEVICE_IWD_MODE, "", "", - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_AP, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_UNKNOWN, + _NM_802_11_MODE_AP, + _NM_802_11_MODE_INFRA, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_BITRATE] = g_param_spec_uint(NM_DEVICE_IWD_BITRATE, @@ -3485,7 +3496,7 @@ nm_device_iwd_class_init(NMDeviceIwdClass *klass) "", 0, G_MAXUINT32, - NM_WIFI_DEVICE_CAP_NONE, + _NM_WIFI_DEVICE_CAP_NONE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_SCANNING] = g_param_spec_boolean(NM_DEVICE_IWD_SCANNING, diff --git a/src/core/devices/wifi/nm-device-olpc-mesh.c b/src/core/devices/wifi/nm-device-olpc-mesh.c index af83c4a..4ec8b07 100644 --- a/src/core/devices/wifi/nm-device-olpc-mesh.c +++ b/src/core/devices/wifi/nm-device-olpc-mesh.c @@ -28,7 +28,7 @@ #include "nm-setting-connection.h" #include "nm-setting-olpc-mesh.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #define _NMLOG_DEVICE_TYPE NMDeviceOlpcMesh #include "devices/nm-device-logging.h" diff --git a/src/core/devices/wifi/nm-device-wifi-p2p.c b/src/core/devices/wifi/nm-device-wifi-p2p.c index fb98760..7ff0434 100644 --- a/src/core/devices/wifi/nm-device-wifi-p2p.c +++ b/src/core/devices/wifi/nm-device-wifi-p2p.c @@ -15,16 +15,16 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" #include "nm-act-request.h" -#include "nm-core-internal.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-ip4-config.h" #include "nm-manager.h" #include "nm-manager.h" #include "nm-setting-wifi-p2p.h" #include "nm-utils.h" #include "nm-wifi-p2p-peer.h" -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" #include "settings/nm-settings.h" #define _NMLOG_DEVICE_TYPE NMDeviceWifiP2P diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c index 042d488..0d210f0 100644 --- a/src/core/devices/wifi/nm-device-wifi.c +++ b/src/core/devices/wifi/nm-device-wifi.c @@ -12,11 +12,11 @@ #include #include -#include "nm-glib-aux/nm-ref-string.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-device-wifi-p2p.h" #include "nm-wifi-ap.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "devices/nm-device.h" #include "devices/nm-device-private.h" #include "nm-dbus-manager.h" @@ -33,13 +33,13 @@ #include "nm-setting-ip4-config.h" #include "nm-ip4-config.h" #include "nm-setting-ip6-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-auth-utils.h" #include "settings/nm-settings-connection.h" #include "settings/nm-settings.h" #include "nm-wifi-utils.h" #include "nm-wifi-common.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-config.h" #define _NMLOG_DEVICE_TYPE NMDeviceWifi @@ -114,11 +114,11 @@ typedef struct { guint wps_timeout_id; guint sup_timeout_id; /* supplicant association timeout */ - NMDeviceWifiCapabilities capabilities; - NMSettingWirelessWakeOnWLan wowlan_restore; + _NMDeviceWifiCapabilities capabilities; + _NMSettingWirelessWakeOnWLan wowlan_restore; NMDeviceWifiP2P *p2p_device; - NM80211Mode mode; + _NM80211Mode mode; guint32 failed_iface_count; gint32 hw_addr_scan_expire; @@ -487,7 +487,7 @@ _scan_notify_allowed(NMDeviceWifi *self, NMTernary do_kickoff) if (!c_list_is_empty(&priv->scanning_prohibited_lst_head)) { /* something prohibits scanning. */ - } else if (NM_IN_SET(priv->mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_AP)) { + } else if (NM_IN_SET(priv->mode, _NM_802_11_MODE_ADHOC, _NM_802_11_MODE_AP)) { /* Don't scan when a an AP or Ad-Hoc connection is active as it will * disrupt connected clients or peers. */ } else if (NM_IN_SET(state, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_FAILED)) { @@ -678,7 +678,7 @@ update_seen_bssids_cache(NMDeviceWifi *self, NMWifiAP *ap) return; /* Don't cache the BSSID for Ad-Hoc APs */ - if (nm_wifi_ap_get_mode(ap) != NM_802_11_MODE_INFRA) + if (nm_wifi_ap_get_mode(ap) != _NM_802_11_MODE_INFRA) return; if (nm_device_get_state(NM_DEVICE(self)) == NM_DEVICE_STATE_ACTIVATED @@ -712,10 +712,11 @@ set_current_ap(NMDeviceWifi *self, NMWifiAP *new_ap, gboolean recheck_available_ priv->current_ap = NULL; if (old_ap) { - NM80211Mode mode = nm_wifi_ap_get_mode(old_ap); + _NM80211Mode mode = nm_wifi_ap_get_mode(old_ap); /* Remove any AP from the internal list if it was created by NM or isn't known to the supplicant */ - if (NM_IN_SET(mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_AP) || nm_wifi_ap_get_fake(old_ap)) + if (NM_IN_SET(mode, _NM_802_11_MODE_ADHOC, _NM_802_11_MODE_AP) + || nm_wifi_ap_get_fake(old_ap)) ap_add_remove(self, FALSE, old_ap, recheck_available_connections); g_object_unref(old_ap); } @@ -750,7 +751,7 @@ periodic_update(NMDeviceWifi *self) return; } - if (priv->mode == NM_802_11_MODE_AP) { + if (priv->mode == _NM_802_11_MODE_AP) { /* In AP mode we currently have nothing to do. */ return; } @@ -845,14 +846,14 @@ remove_all_aps(NMDeviceWifi *self) static gboolean wake_on_wlan_restore(NMDeviceWifi *self) { - NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - NMSettingWirelessWakeOnWLan w; + NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + _NMSettingWirelessWakeOnWLan w; w = priv->wowlan_restore; - if (w == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) + if (w == _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) return TRUE; - priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + priv->wowlan_restore = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; return nm_platform_wifi_set_wake_on_wlan(NM_PLATFORM_GET, nm_device_get_ifindex(NM_DEVICE(self)), w); @@ -937,14 +938,14 @@ deactivate(NMDevice *device) * (usually older ones) don't scan well in adhoc mode. */ if (nm_platform_wifi_get_mode(nm_device_get_platform(device), ifindex) - != NM_802_11_MODE_INFRA) { + != _NM_802_11_MODE_INFRA) { nm_device_take_down(NM_DEVICE(self), TRUE); - nm_platform_wifi_set_mode(nm_device_get_platform(device), ifindex, NM_802_11_MODE_INFRA); + nm_platform_wifi_set_mode(nm_device_get_platform(device), ifindex, _NM_802_11_MODE_INFRA); nm_device_bring_up(NM_DEVICE(self), TRUE, NULL); } - if (priv->mode != NM_802_11_MODE_INFRA) { - priv->mode = NM_802_11_MODE_INFRA; + if (priv->mode != _NM_802_11_MODE_INFRA) { + priv->mode = _NM_802_11_MODE_INFRA; _notify(self, PROP_MODE); } @@ -1010,14 +1011,14 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * /* Early exit if supplicant or device doesn't support requested mode */ mode = nm_setting_wireless_get_mode(s_wireless); if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_ADHOC)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "the device does not support Ad-Hoc networks"); return FALSE; } } else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_AP)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "the device does not support Access Point mode"); @@ -1034,7 +1035,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * } } } else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_MESH)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_MESH)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "the device does not support Mesh mode"); @@ -1433,7 +1434,7 @@ ssids_options_to_ptrarray(GVariant *value, GError **error) v = g_variant_get_child_value(value, i); bytes = g_variant_get_fixed_array(v, &len, sizeof(guint8)); - if (len > 32) { + if (len > NM_IW_ESSID_MAX_SIZE) { g_set_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_ARGUMENT, @@ -1822,7 +1823,7 @@ _scan_kickoff(NMDeviceWifi *self) strv = g_new(char *, ssids->len + 1u); for (i = 0; i < ssids->len; i++) - strv[i] = _nm_utils_ssid_to_string(ssids->pdata[i]); + strv[i] = _nm_utils_ssid_to_string_gbytes(ssids->pdata[i]); strv[i] = NULL; nm_assert(ssids->len > 0); @@ -1986,19 +1987,19 @@ supplicant_iface_bss_changed_cb(NMSupplicantInterface *iface, /* Let the manager try to fill in the SSID from seen-bssids lists */ ssid = nm_wifi_ap_get_ssid(ap); - if (!ssid || _nm_utils_is_empty_ssid(ssid)) { + if (!ssid || _nm_utils_is_empty_ssid_gbytes(ssid)) { /* Try to fill the SSID from the AP database */ try_fill_ssid_for_hidden_ap(self, ap); ssid = nm_wifi_ap_get_ssid(ap); - if (ssid && !_nm_utils_is_empty_ssid(ssid)) { + if (ssid && !_nm_utils_is_empty_ssid_gbytes(ssid)) { gs_free char *s = NULL; /* Yay, matched it, no longer treat as hidden */ _LOGD(LOGD_WIFI, "matched hidden AP %s => %s", nm_wifi_ap_get_address(ap), - (s = _nm_utils_ssid_to_string(ssid))); + (s = _nm_utils_ssid_to_string_gbytes(ssid))); } else { /* Didn't have an entry for this AP in the database */ _LOGD(LOGD_WIFI, "failed to match hidden AP %s", nm_wifi_ap_get_address(ap)); @@ -2481,9 +2482,9 @@ supplicant_iface_state(NMDeviceWifi * self, _LOGI(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. %s %s", - priv->mode == NM_802_11_MODE_AP ? "Started Wi-Fi Hotspot" - : "Connected to wireless network", - (ssid_str = _nm_utils_ssid_to_string(ssid))); + priv->mode == _NM_802_11_MODE_AP ? "Started Wi-Fi Hotspot" + : "Connected to wireless network", + (ssid_str = _nm_utils_ssid_to_string_gbytes(ssid))); nm_device_activate_schedule_stage3_ip_config_start(device); } else if (devstate == NM_DEVICE_STATE_ACTIVATED) periodic_update(self); @@ -2565,6 +2566,7 @@ supplicant_iface_notify_current_bss(NMSupplicantInterface *iface, NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); NMRefString * current_bss; NMWifiAP * new_ap = NULL; + NMActRequest * req; current_bss = nm_supplicant_interface_get_current_bss(iface); if (current_bss) @@ -2598,9 +2600,9 @@ supplicant_iface_notify_current_bss(NMSupplicantInterface *iface, _LOGD(LOGD_WIFI, "roamed from BSSID %s (%s) to %s (%s)", old_bssid ?: "(none)", - (old_ssid_s = _nm_utils_ssid_to_string(old_ssid)), + (old_ssid_s = _nm_utils_ssid_to_string_gbytes(old_ssid)), new_bssid ?: "(none)", - (new_ssid_s = _nm_utils_ssid_to_string(new_ssid))); + (new_ssid_s = _nm_utils_ssid_to_string_gbytes(new_ssid))); if (new_bssid) { /* The new AP could be in a different layer 3 network @@ -2612,6 +2614,13 @@ supplicant_iface_notify_current_bss(NMSupplicantInterface *iface, } set_current_ap(self, new_ap, TRUE); + + req = nm_device_get_act_request(NM_DEVICE(self)); + if (req) { + nm_active_connection_set_specific_object( + NM_ACTIVE_CONNECTION(req), + new_ap ? nm_dbus_object_get_path(NM_DBUS_OBJECT(new_ap)) : NULL); + } } } @@ -2782,21 +2791,21 @@ supplicant_connection_timeout_cb(gpointer user_data) connection = nm_act_request_get_applied_connection(req); g_assert(connection); - if (NM_IN_SET(priv->mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_MESH, NM_802_11_MODE_AP)) { + if (NM_IN_SET(priv->mode, _NM_802_11_MODE_ADHOC, _NM_802_11_MODE_MESH, _NM_802_11_MODE_AP)) { /* In Ad-Hoc and AP modes there's nothing to check the encryption key * (if any), so supplicant timeouts here are almost certainly the wifi * driver being really stupid. */ _LOGW(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) %s network creation took too long, failing activation", - priv->mode == NM_802_11_MODE_ADHOC ? "Ad-Hoc" : "Hotspot"); + priv->mode == _NM_802_11_MODE_ADHOC ? "Ad-Hoc" : "Hotspot"); nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); return FALSE; } - g_assert(priv->mode == NM_802_11_MODE_INFRA); + g_assert(priv->mode == _NM_802_11_MODE_INFRA); if (priv->ssid_found && nm_connection_get_setting_wireless_security(connection)) { guint64 timestamp = 0; @@ -2948,9 +2957,10 @@ error: static gboolean wake_on_wlan_enable(NMDeviceWifi *self) { - NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - NMSettingWirelessWakeOnWLan wowl; - NMSettingWireless * s_wireless; + NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMSettingWirelessWakeOnWLan wowl; + _NMSettingWirelessWakeOnWLan wowl2; + NMSettingWireless * s_wireless; s_wireless = nm_device_get_applied_setting(NM_DEVICE(self), NM_TYPE_SETTING_WIRELESS); if (s_wireless) { @@ -2982,9 +2992,11 @@ wake_on_wlan_enable(NMDeviceWifi *self) goto found; wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + found: - if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) { - priv->wowlan_restore = wowl; + wowl2 = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_CAST(wowl); + if (wowl2 == _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) { + priv->wowlan_restore = wowl2; return TRUE; } @@ -2993,7 +3005,7 @@ found: return nm_platform_wifi_set_wake_on_wlan(NM_PLATFORM_GET, nm_device_get_ifindex(NM_DEVICE(self)), - wowl); + wowl2); } static NMActStageReturn @@ -3022,16 +3034,16 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) mode = nm_setting_wireless_get_mode(s_wireless); if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_INFRA) == 0) - priv->mode = NM_802_11_MODE_INFRA; + priv->mode = _NM_802_11_MODE_INFRA; else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) - priv->mode = NM_802_11_MODE_ADHOC; + priv->mode = _NM_802_11_MODE_ADHOC; else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { - priv->mode = NM_802_11_MODE_AP; + priv->mode = _NM_802_11_MODE_AP; /* Scanning not done in AP mode; clear the scan list */ remove_all_aps(self); } else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) - priv->mode = NM_802_11_MODE_MESH; + priv->mode = _NM_802_11_MODE_MESH; _notify(self, PROP_MODE); /* expire the temporary MAC address used during scanning */ @@ -3044,7 +3056,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) } /* AP and Mesh modes never use a specific object or existing scanned AP */ - if (!NM_IN_SET(priv->mode, NM_802_11_MODE_AP, NM_802_11_MODE_MESH)) { + if (!NM_IN_SET(priv->mode, _NM_802_11_MODE_AP, _NM_802_11_MODE_MESH)) { ap_path = nm_active_connection_get_specific_object(NM_ACTIVE_CONNECTION(req)); ap = ap_path ? nm_wifi_ap_lookup_for_device(NM_DEVICE(self), ap_path) : NULL; } @@ -3146,7 +3158,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) NMDeviceWifi * self = NM_DEVICE_WIFI(device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); gs_unref_object NMSupplicantConfig *config = NULL; - NM80211Mode ap_mode; + _NM80211Mode ap_mode; NMActRequest * req; NMWifiAP * ap; NMConnection * connection; @@ -3213,10 +3225,11 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) * if the user didn't specify one and we didn't find an AP that matched * the connection, just pick a frequency the device supports. */ - if (NM_IN_SET(ap_mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_MESH) || nm_wifi_ap_is_hotspot(ap)) + if (NM_IN_SET(ap_mode, _NM_802_11_MODE_ADHOC, _NM_802_11_MODE_MESH) + || nm_wifi_ap_is_hotspot(ap)) ensure_hotspot_frequency(self, s_wireless, ap); - if (ap_mode == NM_802_11_MODE_INFRA) + if (ap_mode == _NM_802_11_MODE_INFRA) set_powersave(device); /* Build up the supplicant configuration */ @@ -3333,7 +3346,7 @@ act_stage4_ip_config_timeout(NMDevice * device, s_ip = nm_connection_get_setting_ip_config(connection, addr_family); may_fail = nm_setting_ip_config_get_may_fail(s_ip); - if (priv->mode == NM_802_11_MODE_AP) + if (priv->mode == _NM_802_11_MODE_AP) goto call_parent; if (may_fail || !is_static_wep(connection)) { @@ -3686,8 +3699,8 @@ nm_device_wifi_init(NMDeviceWifi *self) priv->scan_last_request_started_at_msec = G_MININT64; priv->hidden_probe_scan_warn = TRUE; - priv->mode = NM_802_11_MODE_INFRA; - priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + priv->mode = _NM_802_11_MODE_INFRA; + priv->wowlan_restore = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; } static void @@ -3698,7 +3711,7 @@ constructed(GObject *object) G_OBJECT_CLASS(nm_device_wifi_parent_class)->constructed(object); - if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) + if (priv->capabilities & _NM_WIFI_DEVICE_CAP_AP) _LOGI(LOGD_PLATFORM | LOGD_WIFI, "driver supports Access Point (AP) mode"); /* Connect to the supplicant manager */ @@ -3706,7 +3719,7 @@ constructed(GObject *object) } NMDevice * -nm_device_wifi_new(const char *iface, NMDeviceWifiCapabilities capabilities) +nm_device_wifi_new(const char *iface, _NMDeviceWifiCapabilities capabilities) { return g_object_new(NM_TYPE_DEVICE_WIFI, NM_DEVICE_IFACE, @@ -3814,9 +3827,9 @@ nm_device_wifi_class_init(NMDeviceWifiClass *klass) obj_properties[PROP_MODE] = g_param_spec_uint(NM_DEVICE_WIFI_MODE, "", "", - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_AP, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_UNKNOWN, + _NM_802_11_MODE_AP, + _NM_802_11_MODE_INFRA, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_BITRATE] = g_param_spec_uint(NM_DEVICE_WIFI_BITRATE, @@ -3847,7 +3860,7 @@ nm_device_wifi_class_init(NMDeviceWifiClass *klass) "", 0, G_MAXUINT32, - NM_WIFI_DEVICE_CAP_NONE, + _NM_WIFI_DEVICE_CAP_NONE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_SCANNING] = g_param_spec_boolean(NM_DEVICE_WIFI_SCANNING, diff --git a/src/core/devices/wifi/nm-device-wifi.h b/src/core/devices/wifi/nm-device-wifi.h index d9e9038..c7ff1a1 100644 --- a/src/core/devices/wifi/nm-device-wifi.h +++ b/src/core/devices/wifi/nm-device-wifi.h @@ -33,7 +33,7 @@ typedef struct _NMDeviceWifiClass NMDeviceWifiClass; GType nm_device_wifi_get_type(void); -NMDevice *nm_device_wifi_new(const char *iface, NMDeviceWifiCapabilities capabilities); +NMDevice *nm_device_wifi_new(const char *iface, _NMDeviceWifiCapabilities capabilities); const CList *_nm_device_wifi_get_aps(NMDeviceWifi *self); diff --git a/src/core/devices/wifi/nm-iwd-manager.c b/src/core/devices/wifi/nm-iwd-manager.c index b4b019d..1c4b211 100644 --- a/src/core/devices/wifi/nm-iwd-manager.c +++ b/src/core/devices/wifi/nm-iwd-manager.c @@ -8,14 +8,17 @@ #include "nm-iwd-manager.h" #include +#include +#include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-manager.h" #include "nm-device-iwd.h" #include "nm-wifi-utils.h" -#include "nm-glib-aux/nm-random-utils.h" +#include "libnm-glib-aux/nm-random-utils.h" #include "settings/nm-settings.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" +#include "nm-config.h" /*****************************************************************************/ @@ -28,6 +31,7 @@ typedef struct { typedef struct { GDBusProxy * known_network; NMSettingsConnection *mirror_connection; + const KnownNetworkId *id; } KnownNetworkData; typedef struct { @@ -419,7 +423,7 @@ known_network_update_cb(GObject *source, GAsyncResult *res, gpointer user_data) variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); if (!variant) { nm_log_warn(LOGD_WIFI, - "Updating %s on IWD known network %s failed: %s", + "iwd: updating %s on IWD known network %s failed: %s", (const char *) user_data, g_dbus_proxy_get_object_path(G_DBUS_PROXY(source)), error->message); @@ -427,17 +431,31 @@ known_network_update_cb(GObject *source, GAsyncResult *res, gpointer user_data) } static void -sett_conn_changed(NMSettingsConnection *sett_conn, guint update_reason, KnownNetworkData *data) +sett_conn_changed(NMSettingsConnection * sett_conn, + guint update_reason, + const KnownNetworkData *data) { NMSettingsConnectionIntFlags flags; - NMConnection * conn = nm_settings_connection_get_connection(sett_conn); - NMSettingConnection * s_conn = nm_connection_get_setting_connection(conn); - gboolean nm_autoconnectable = nm_setting_connection_get_autoconnect(s_conn); - gboolean iwd_autoconnectable = get_property_bool(data->known_network, "AutoConnect", TRUE); + NMConnection * conn = nm_settings_connection_get_connection(sett_conn); + NMSettingConnection * s_conn = nm_connection_get_setting_connection(conn); + NMSettingWireless * s_wifi = nm_connection_get_setting_wireless(conn); + nm_auto_unref_keyfile GKeyFile *iwd_config = NULL; + const char * iwd_dir; + gs_free char * filename = NULL; + gs_free char * full_path = NULL; + gs_free_error GError *error = NULL; + NMIwdNetworkSecurity security; + GBytes * ssid; + const guint8 * ssid_data; + gsize ssid_len; + gboolean removed; nm_assert(sett_conn == data->mirror_connection); - if (iwd_autoconnectable == nm_autoconnectable) + if (update_reason + & (NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT)) return; /* If this is a generated connection it may be ourselves updating it */ @@ -445,21 +463,113 @@ sett_conn_changed(NMSettingsConnection *sett_conn, guint update_reason, KnownNet if (NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) return; + iwd_dir = nm_config_data_get_iwd_config_path(NM_CONFIG_GET_DATA); + if (!iwd_dir || iwd_dir[0] == '\0' || !g_file_test(iwd_dir, G_FILE_TEST_IS_DIR)) { + gboolean nm_autoconnectable = nm_setting_connection_get_autoconnect(s_conn); + gboolean iwd_autoconnectable = get_property_bool(data->known_network, "AutoConnect", TRUE); + + if (iwd_autoconnectable == nm_autoconnectable) { + nm_log_dbg(LOGD_WIFI, + "iwd: updating AutoConnect on known network at %s based on connection %s", + g_dbus_proxy_get_object_path(data->known_network), + nm_settings_connection_get_id(data->mirror_connection)); + g_dbus_proxy_call(data->known_network, + DBUS_INTERFACE_PROPERTIES ".Set", + g_variant_new("(ssv)", + NM_IWD_KNOWN_NETWORK_INTERFACE, + "AutoConnect", + g_variant_new_boolean(nm_autoconnectable)), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + known_network_update_cb, + "AutoConnect"); + } + + return; + } + + /* If the SSID and the security type in the NMSettingsConnection haven't + * changed, we just need to overwrite the original IWD config file. + * Otherwise we need to call Forget on the original KnownNetwork or + * remove its file. IWD will have to delete one D-Bus object and + * create another anyway because the SSID and security type are in the + * D-Bus object path, so no point renaming the file. + */ + ssid = nm_setting_wireless_get_ssid(s_wifi); + ssid_data = ssid ? g_bytes_get_data(ssid, &ssid_len) : NULL; + removed = FALSE; + + if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &security) + || security != data->id->security || !ssid_data || ssid_len != strlen(data->id->name) + || memcmp(ssid_data, data->id->name, ssid_len)) { + gs_free char *orig_filename = + nm_wifi_utils_get_iwd_config_filename(data->id->name, -1, data->id->security); + gs_free char *orig_full_path = g_strdup_printf("%s/%s", iwd_dir, orig_filename); + + if (g_remove(orig_full_path) == 0) + nm_log_dbg(LOGD_WIFI, "iwd: profile at %s removed", orig_full_path); + else if (errno != ENOENT) + nm_log_dbg(LOGD_WIFI, + "iwd: profile at %s not removed: %s (%i)", + orig_full_path, + strerror(errno), + errno); + + removed = TRUE; + } + + if (!nm_streq(nm_settings_connection_get_connection_type(sett_conn), "802-11-wireless") + || !s_wifi) + return; + + /* If the connection has any permissions other than the default we don't + * want to save it as an IWD profile. IWD will make it available for + * everybody to attempt a connection, remove, or toggle "autoconnectable". + */ + if (s_conn && nm_setting_connection_get_num_permissions(s_conn)) { + nm_log_dbg( + LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile because of non-default " + "permissions", + nm_settings_connection_get_id(sett_conn)); + return; + } + + iwd_config = nm_wifi_utils_connection_to_iwd_config(conn, &filename, &error); + if (!iwd_config) { + /* The error message here is not translated and it only goes in + * the logs. + */ + nm_log_dbg(LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + + full_path = g_strdup_printf("%s/%s", iwd_dir, filename); + if (removed && g_file_test(full_path, G_FILE_TEST_EXISTS)) { + nm_log_dbg(LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile because %s " + "already exists", + nm_settings_connection_get_id(sett_conn), + full_path); + return; + } + + if (!g_key_file_save_to_file(iwd_config, full_path, &error)) { + nm_log_dbg(LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile: save error: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + nm_log_dbg(LOGD_WIFI, - "Updating AutoConnect on known network at %s based on connection %s", - g_dbus_proxy_get_object_path(data->known_network), - nm_settings_connection_get_id(data->mirror_connection)); - g_dbus_proxy_call(data->known_network, - DBUS_INTERFACE_PROPERTIES ".Set", - g_variant_new("(ssv)", - NM_IWD_KNOWN_NETWORK_INTERFACE, - "AutoConnect", - g_variant_new_boolean(nm_autoconnectable)), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - known_network_update_cb, - "AutoConnect"); + "iwd: changed Wi-Fi connection %s mirrored as IWD profile %s", + nm_settings_connection_get_id(sett_conn), + full_path); } /* Look up an existing NMSettingsConnection for a network that has been @@ -590,7 +700,7 @@ mirror_connection(NMIwdManager * self, NULL); g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_HIDDEN, hidden, NULL); } else { - KnownNetworkData data = {known_network, settings_connection}; + KnownNetworkData data = {known_network, settings_connection, id}; sett_conn_changed(settings_connection, 0, &data); } } @@ -779,6 +889,7 @@ interface_added(GDBusObjectManager *object_manager, } else { data = g_slice_new0(KnownNetworkData); data->known_network = g_object_ref(proxy); + data->id = id; g_hash_table_insert(priv->known_networks, id, data); } @@ -907,6 +1018,9 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint const guint8 * ssid_bytes; gsize ssid_len; NMSettingsConnection *new_mirror_conn; + const char * iwd_dir; + gs_free char * filename = NULL; + gs_free char * full_path = NULL; if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &id.security)) return; @@ -923,8 +1037,12 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint ssid_buf[ssid_len] = '\0'; id.name = ssid_buf; data = g_hash_table_lookup(priv->known_networks, &id); - if (!data) - return; + if (!data) { + if (!g_utf8_validate((const char *) ssid_bytes, ssid_len, NULL)) + return; + + goto try_delete_file; + } if (data->mirror_connection != sett_conn) return; @@ -941,7 +1059,7 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint } if (!priv->running) - return; + goto try_delete_file; g_dbus_proxy_call(data->known_network, "Forget", @@ -951,6 +1069,91 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint NULL, NULL, NULL); + return; + +try_delete_file: + if (mirror_connection(self, &id, FALSE, NULL)) + return; + + iwd_dir = nm_config_data_get_iwd_config_path(NM_CONFIG_GET_DATA); + if (!iwd_dir || iwd_dir[0] == '\0' || !g_file_test(iwd_dir, G_FILE_TEST_IS_DIR)) + return; + + filename = nm_wifi_utils_get_iwd_config_filename(id.name, ssid_len, id.security); + full_path = g_strdup_printf("%s/%s", iwd_dir, filename); + if (g_remove(full_path) == 0) + _LOGD("IWD profile at %s removed", full_path); + else if (errno != ENOENT) + _LOGD("IWD profile at %s not removed: %s (%i)", full_path, strerror(errno), errno); +} + +static void +connection_added(NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) +{ + NMIwdManager * self = user_data; + NMConnection * conn = nm_settings_connection_get_connection(sett_conn); + NMSettingConnection *s_conn = nm_connection_get_setting_connection(conn); + const char * iwd_dir; + gs_free char * filename = NULL; + gs_free char * full_path = NULL; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *iwd_config = NULL; + NMSettingsConnectionIntFlags flags; + + if (!nm_streq(nm_settings_connection_get_connection_type(sett_conn), "802-11-wireless")) + return; + + iwd_dir = nm_config_data_get_iwd_config_path(NM_CONFIG_GET_DATA); + if (!iwd_dir || iwd_dir[0] == '\0' || !g_file_test(iwd_dir, G_FILE_TEST_IS_DIR)) + return; + + /* If this is a generated connection it may be ourselves creating it and + * directly assigning it to a KnownNetwork's .mirror_connection. + */ + flags = nm_settings_connection_get_flags(sett_conn); + if (NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) + return; + + /* If the connection has any permissions other than the default we don't + * want to save it as an IWD profile. IWD will make it available for + * everybody to attempt a connection, remove, or toggle "autoconnectable". + */ + if (s_conn && nm_setting_connection_get_num_permissions(s_conn)) { + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile because of non-default " + "permissions", + nm_settings_connection_get_id(sett_conn)); + return; + } + + iwd_config = nm_wifi_utils_connection_to_iwd_config(conn, &filename, &error); + if (!iwd_config) { + /* The error message here is not translated and it only goes in + * the logs. + */ + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + + full_path = g_strdup_printf("%s/%s", iwd_dir, filename); + if (g_file_test(full_path, G_FILE_TEST_EXISTS)) { + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile because %s already exists", + nm_settings_connection_get_id(sett_conn), + full_path); + return; + } + + if (!g_key_file_save_to_file(iwd_config, full_path, &error)) { + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile: save error: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + + _LOGD("New Wi-Fi connection %s mirrored as IWD profile %s", + nm_settings_connection_get_id(sett_conn), + full_path); } static gboolean @@ -1115,10 +1318,11 @@ device_removed(NMManager *manager, NMDevice *device, gpointer user_data) static int object_compare_interfaces(gconstpointer a, gconstpointer b) { - static const char *interface_order[] = { + static const char *const interface_order[] = { NM_IWD_KNOWN_NETWORK_INTERFACE, NM_IWD_NETWORK_INTERFACE, NM_IWD_DEVICE_INTERFACE, + NULL, }; int rank_a = G_N_ELEMENTS(interface_order); int rank_b = G_N_ELEMENTS(interface_order); @@ -1304,11 +1508,31 @@ nm_iwd_manager_init(NMIwdManager *self) g_signal_connect(priv->manager, NM_MANAGER_DEVICE_ADDED, G_CALLBACK(device_added), self); g_signal_connect(priv->manager, NM_MANAGER_DEVICE_REMOVED, G_CALLBACK(device_removed), self); + /* The current logic is that we track all creations and removals but + * for modifications we only listen to those connections that are + * currently a KnownNetwork's mirror_connection. There may be multiple + * NMSettingsConnections referring to the same SSID+Security type tuple + * so to the same KnownNetwork. So to make connection profile editing + * work at least for the simple cases, we track one NMSettingsConnection + * out of those, and we map its changes to the IWD KnownNetwork. + * + * When an NMSettingsConnection is created by a user for a completely + * new network and the settings are compatible with IWD, we create an + * IWD KnownNetwork config file for it. IWD will notice that and a + * KnownNetwork objects pops up on D-Bus. We look up a suitable + * mirror_connection for it and only then subscribe to modification + * signals. There are various different ways that this could be done, + * it's not clear which one's the best. + */ priv->settings = g_object_ref(NM_SETTINGS_GET); g_signal_connect(priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, G_CALLBACK(connection_removed), self); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_ADDED, + G_CALLBACK(connection_added), + self); priv->cancellable = g_cancellable_new(); diff --git a/src/core/devices/wifi/nm-wifi-ap.c b/src/core/devices/wifi/nm-wifi-ap.c index 08fa10e..69b7b44 100644 --- a/src/core/devices/wifi/nm-wifi-ap.c +++ b/src/core/devices/wifi/nm-wifi-ap.c @@ -13,13 +13,13 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-setting-wireless.h" #include "nm-utils.h" #include "nm-wifi-utils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "supplicant/nm-supplicant-interface.h" #define PROTO_WPA "wpa" @@ -41,12 +41,12 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMWifiAP, struct _NMWifiAPPrivate { /* Scanned or cached values */ - GBytes * ssid; - char * address; - NM80211Mode mode; - guint8 strength; - guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */ - guint32 max_bitrate; /* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */ + GBytes * ssid; + char * address; + _NM80211Mode mode; + guint8 strength; + guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */ + guint32 max_bitrate; /* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */ gint64 last_seen_msec; /* Timestamp when the AP was seen lastly (in nm_utils_get_monotonic_timestamp_*() scale). @@ -98,7 +98,7 @@ nm_wifi_ap_set_ssid(NMWifiAP *ap, GBytes *ssid) } l = g_bytes_get_size(ssid); - if (l == 0 || l > 32) + if (l == 0 || l > NM_IW_ESSID_MAX_SIZE) g_return_val_if_reached(FALSE); priv = NM_WIFI_AP_GET_PRIVATE(ap); @@ -191,24 +191,24 @@ nm_wifi_ap_set_address(NMWifiAP *ap, const char *addr) return nm_wifi_ap_set_address_bin(ap, &addr_buf); } -NM80211Mode +_NM80211Mode nm_wifi_ap_get_mode(NMWifiAP *ap) { - g_return_val_if_fail(NM_IS_WIFI_AP(ap), NM_802_11_MODE_UNKNOWN); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), _NM_802_11_MODE_UNKNOWN); return NM_WIFI_AP_GET_PRIVATE(ap)->mode; } static gboolean -nm_wifi_ap_set_mode(NMWifiAP *ap, NM80211Mode mode) +nm_wifi_ap_set_mode(NMWifiAP *ap, _NM80211Mode mode) { NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(ap); nm_assert(NM_IN_SET(mode, - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_ADHOC, - NM_802_11_MODE_INFRA, - NM_802_11_MODE_MESH)); + _NM_802_11_MODE_UNKNOWN, + _NM_802_11_MODE_ADHOC, + _NM_802_11_MODE_INFRA, + _NM_802_11_MODE_MESH)); if (priv->mode != mode) { priv->mode = mode; @@ -513,34 +513,35 @@ nm_wifi_ap_to_string(const NMWifiAP *self, char *str_buf, gulong buf_len, gint64 nm_utils_get_monotonic_timestamp_msec_cached(&now_msec); - g_snprintf(str_buf, - buf_len, - "%17s %-35s [ %c %3u %3u%% %c%c %c%c W:%04X R:%04X ] %s sup:%s [nm:%s]", - priv->address ?: "(none)", - (ssid_to_free = _nm_utils_ssid_to_string(priv->ssid)), - (priv->mode == NM_802_11_MODE_ADHOC - ? '*' - : (priv->hotspot - ? '#' - : (priv->fake ? 'f' : (priv->mode == NM_802_11_MODE_MESH ? 'm' : 'a')))), - chan, - priv->strength, - priv->flags & NM_802_11_AP_FLAGS_PRIVACY ? 'P' : '_', - priv->metered ? 'M' : '_', - priv->flags & NM_802_11_AP_FLAGS_WPS ? 'W' : '_', - priv->flags & NM_802_11_AP_FLAGS_WPS_PIN - ? 'p' - : (priv->flags & NM_802_11_AP_FLAGS_WPS_PBC ? '#' : '_'), - priv->wpa_flags & 0xFFFF, - priv->rsn_flags & 0xFFFF, - priv->last_seen_msec != G_MININT64 - ? nm_sprintf_buf(str_buf_ts, - "%3u.%03us", - (guint)((now_msec - priv->last_seen_msec) / 1000), - (guint)((now_msec - priv->last_seen_msec) % 1000)) - : " ", - supplicant_id, - export_path); + g_snprintf( + str_buf, + buf_len, + "%17s %-35s [ %c %3u %3u%% %c%c %c%c W:%04X R:%04X ] %s sup:%s [nm:%s]", + priv->address ?: "(none)", + (ssid_to_free = _nm_utils_ssid_to_string_gbytes(priv->ssid)), + (priv->mode == _NM_802_11_MODE_ADHOC + ? '*' + : (priv->hotspot + ? '#' + : (priv->fake ? 'f' : (priv->mode == _NM_802_11_MODE_MESH ? 'm' : 'a')))), + chan, + priv->strength, + priv->flags & NM_802_11_AP_FLAGS_PRIVACY ? 'P' : '_', + priv->metered ? 'M' : '_', + priv->flags & NM_802_11_AP_FLAGS_WPS ? 'W' : '_', + priv->flags & NM_802_11_AP_FLAGS_WPS_PIN + ? 'p' + : (priv->flags & NM_802_11_AP_FLAGS_WPS_PBC ? '#' : '_'), + priv->wpa_flags & 0xFFFF, + priv->rsn_flags & 0xFFFF, + priv->last_seen_msec != G_MININT64 + ? nm_sprintf_buf(str_buf_ts, + "%3u.%03us", + (guint)((now_msec - priv->last_seen_msec) / 1000), + (guint)((now_msec - priv->last_seen_msec) % 1000)) + : " ", + supplicant_id, + export_path); return str_buf; } @@ -589,13 +590,13 @@ nm_wifi_ap_check_compatible(NMWifiAP *self, NMConnection *connection) mode = nm_setting_wireless_get_mode(s_wireless); if (mode) { - if (!strcmp(mode, "infrastructure") && (priv->mode != NM_802_11_MODE_INFRA)) + if (!strcmp(mode, "infrastructure") && (priv->mode != _NM_802_11_MODE_INFRA)) return FALSE; - if (!strcmp(mode, "adhoc") && (priv->mode != NM_802_11_MODE_ADHOC)) + if (!strcmp(mode, "adhoc") && (priv->mode != _NM_802_11_MODE_ADHOC)) return FALSE; - if (!strcmp(mode, "ap") && (priv->mode != NM_802_11_MODE_INFRA || priv->hotspot != TRUE)) + if (!strcmp(mode, "ap") && (priv->mode != _NM_802_11_MODE_INFRA || priv->hotspot != TRUE)) return FALSE; - if (!strcmp(mode, "mesh") && (priv->mode != NM_802_11_MODE_MESH)) + if (!strcmp(mode, "mesh") && (priv->mode != _NM_802_11_MODE_MESH)) return FALSE; } @@ -624,7 +625,7 @@ nm_wifi_ap_check_compatible(NMWifiAP *self, NMConnection *connection) priv->flags, priv->wpa_flags, priv->rsn_flags, - priv->mode); + NM_802_11_MODE_CAST(priv->mode)); } gboolean @@ -713,7 +714,7 @@ nm_wifi_ap_init(NMWifiAP *self) c_list_init(&self->aps_lst); - priv->mode = NM_802_11_MODE_INFRA; + priv->mode = _NM_802_11_MODE_INFRA; priv->flags = NM_802_11_AP_FLAGS_NONE; priv->wpa_flags = NM_802_11_AP_SEC_NONE; priv->rsn_flags = NM_802_11_AP_SEC_NONE; @@ -758,19 +759,19 @@ nm_wifi_ap_new_fake_from_connection(NMConnection *connection) mode = nm_setting_wireless_get_mode(s_wireless); if (mode) { if (!strcmp(mode, "infrastructure")) - nm_wifi_ap_set_mode(ap, NM_802_11_MODE_INFRA); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_INFRA); else if (!strcmp(mode, "adhoc")) { - nm_wifi_ap_set_mode(ap, NM_802_11_MODE_ADHOC); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_ADHOC); adhoc = TRUE; } else if (!strcmp(mode, "mesh")) - nm_wifi_ap_set_mode(ap, NM_802_11_MODE_MESH); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_MESH); else if (!strcmp(mode, "ap")) { - nm_wifi_ap_set_mode(ap, NM_802_11_MODE_INFRA); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_INFRA); NM_WIFI_AP_GET_PRIVATE(ap)->hotspot = TRUE; } else goto error; } else { - nm_wifi_ap_set_mode(ap, NM_802_11_MODE_INFRA); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_INFRA); } band = nm_setting_wireless_get_band(s_wireless); @@ -955,9 +956,9 @@ nm_wifi_ap_class_init(NMWifiAPClass *ap_class) obj_properties[PROP_MODE] = g_param_spec_uint(NM_WIFI_AP_MODE, "", "", - NM_802_11_MODE_ADHOC, - NM_802_11_MODE_INFRA, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_ADHOC, + _NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_MAX_BITRATE] = g_param_spec_uint(NM_WIFI_AP_MAX_BITRATE, diff --git a/src/core/devices/wifi/nm-wifi-ap.h b/src/core/devices/wifi/nm-wifi-ap.h index bdd7241..bffd28a 100644 --- a/src/core/devices/wifi/nm-wifi-ap.h +++ b/src/core/devices/wifi/nm-wifi-ap.h @@ -10,6 +10,7 @@ #include "nm-dbus-object.h" #include "nm-dbus-interface.h" #include "nm-connection.h" +#include "libnm-base/nm-base.h" #define NM_TYPE_WIFI_AP (nm_wifi_ap_get_type()) #define NM_WIFI_AP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIFI_AP, NMWifiAP)) @@ -69,7 +70,7 @@ gboolean nm_wifi_ap_set_ssid(NMWifiAP *ap, GBytes *ssid); const char * nm_wifi_ap_get_address(const NMWifiAP *ap); gboolean nm_wifi_ap_set_address(NMWifiAP *ap, const char *addr); gboolean nm_wifi_ap_set_address_bin(NMWifiAP *ap, const NMEtherAddr *addr); -NM80211Mode nm_wifi_ap_get_mode(NMWifiAP *ap); +_NM80211Mode nm_wifi_ap_get_mode(NMWifiAP *ap); gboolean nm_wifi_ap_is_hotspot(NMWifiAP *ap); gint8 nm_wifi_ap_get_strength(NMWifiAP *ap); gboolean nm_wifi_ap_set_strength(NMWifiAP *ap, gint8 strength); diff --git a/src/core/devices/wifi/nm-wifi-factory.c b/src/core/devices/wifi/nm-wifi-factory.c index 40375e1..c7be7ab 100644 --- a/src/core/devices/wifi/nm-wifi-factory.c +++ b/src/core/devices/wifi/nm-wifi-factory.c @@ -15,7 +15,7 @@ #include "nm-device-olpc-mesh.h" #include "nm-device-iwd.h" #include "settings/nm-settings-connection.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-config.h" /*****************************************************************************/ @@ -97,9 +97,9 @@ create_device(NMDeviceFactory * factory, NM_PRINT_FMT_QUOTE_STRING(backend), WITH_IWD ? " (iwd support enabled)" : ""); if (!backend || !g_ascii_strcasecmp(backend, "wpa_supplicant")) { - NMDevice * device; - NMDeviceWifiCapabilities capabilities; - NM80211Mode mode; + NMDevice * device; + _NMDeviceWifiCapabilities capabilities; + _NM80211Mode mode; if (!nm_platform_wifi_get_capabilities(NM_PLATFORM_GET, plink->ifindex, &capabilities)) { nm_log_warn(LOGD_PLATFORM | LOGD_WIFI, @@ -114,7 +114,7 @@ create_device(NMDeviceFactory * factory, * them if/when they change to a handled type. */ mode = nm_platform_wifi_get_mode(NM_PLATFORM_GET, plink->ifindex); - if (mode == NM_802_11_MODE_UNKNOWN) { + if (mode == _NM_802_11_MODE_UNKNOWN) { *out_ignore = TRUE; return NULL; } diff --git a/src/core/devices/wifi/nm-wifi-p2p-peer.c b/src/core/devices/wifi/nm-wifi-p2p-peer.c index 8488f32..228a26b 100644 --- a/src/core/devices/wifi/nm-wifi-p2p-peer.c +++ b/src/core/devices/wifi/nm-wifi-p2p-peer.c @@ -12,13 +12,13 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-setting-wireless.h" #include "nm-utils.h" #include "nm-wifi-utils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "supplicant/nm-supplicant-types.h" /*****************************************************************************/ diff --git a/src/core/devices/wifi/nm-wifi-utils.c b/src/core/devices/wifi/nm-wifi-utils.c index aed236c..2af1ab7 100644 --- a/src/core/devices/wifi/nm-wifi-utils.c +++ b/src/core/devices/wifi/nm-wifi-utils.c @@ -7,10 +7,13 @@ #include "nm-wifi-utils.h" +#include +#include #include #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-aux-intern/nm-common-macros.h" static gboolean verify_no_wep(NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) @@ -526,7 +529,7 @@ verify_adhoc(NMSettingWirelessSecurity *s_wsec, gboolean nm_wifi_utils_complete_connection(GBytes * ap_ssid, const char * bssid, - NM80211Mode ap_mode, + _NM80211Mode ap_mode, guint32 ap_freq, guint32 ap_flags, guint32 ap_wpa_flags, @@ -575,14 +578,14 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, /* Make sure the supplied mode matches the AP's */ if (!strcmp(mode, NM_SETTING_WIRELESS_MODE_INFRA) || !strcmp(mode, NM_SETTING_WIRELESS_MODE_AP)) { - if (ap_mode == NM_802_11_MODE_INFRA) + if (ap_mode == _NM_802_11_MODE_INFRA) valid = TRUE; } else if (!strcmp(mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { - if (ap_mode == NM_802_11_MODE_ADHOC) + if (ap_mode == _NM_802_11_MODE_ADHOC) valid = TRUE; adhoc = TRUE; } else if (!strcmp(mode, NM_SETTING_WIRELESS_MODE_MESH)) { - if (ap_mode == NM_802_11_MODE_MESH) + if (ap_mode == _NM_802_11_MODE_MESH) valid = TRUE; mesh = TRUE; } @@ -600,10 +603,10 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, } } else { mode = NM_SETTING_WIRELESS_MODE_INFRA; - if (ap_mode == NM_802_11_MODE_ADHOC) { + if (ap_mode == _NM_802_11_MODE_ADHOC) { mode = NM_SETTING_WIRELESS_MODE_ADHOC; adhoc = TRUE; - } else if (ap_mode == NM_802_11_MODE_MESH) { + } else if (ap_mode == _NM_802_11_MODE_MESH) { mode = NM_SETTING_WIRELESS_MODE_MESH; mesh = TRUE; } @@ -943,3 +946,841 @@ nm_wifi_connection_get_iwd_ssid_and_security(NMConnection * connection, return TRUE; } + +/*****************************************************************************/ + +/* Builds the IWD network configuration file name for a given SSID + * and security type pair. The SSID should be valid UTF-8 and in + * any case must contain no NUL-bytes. If @ssid is NUL-terminated, + * @ssid_len can be -1 instead of actual SSID length. + */ +char * +nm_wifi_utils_get_iwd_config_filename(const char * ssid, + gssize ssid_len, + NMIwdNetworkSecurity security) +{ + const char *security_suffix; + const char *ptr; + gboolean alnum_ssid = TRUE; + + for (ptr = ssid; ssid_len != 0 && *ptr != '\0'; ptr++, ssid_len--) + if (!g_ascii_isalnum(*ptr) && !strchr("-_ ", *ptr)) + alnum_ssid = FALSE; + + g_return_val_if_fail(ptr != ssid && ptr - ssid <= NM_IW_ESSID_MAX_SIZE, NULL); + + switch (security) { + case NM_IWD_NETWORK_SECURITY_OPEN: + security_suffix = "open"; + break; + case NM_IWD_NETWORK_SECURITY_PSK: + security_suffix = "psk"; + break; + case NM_IWD_NETWORK_SECURITY_8021X: + security_suffix = "8021x"; + break; + default: + return NULL; + } + + if (alnum_ssid) { + return g_strdup_printf("%.*s.%s", (int) (ptr - ssid), ssid, security_suffix); + } else { + char ssid_buf[NM_IW_ESSID_MAX_SIZE * 2 + 1]; + + return g_strdup_printf("=%s.%s", + nm_utils_bin2hexstr_full(ssid, ptr - ssid, '\0', FALSE, ssid_buf), + security_suffix); + } +} + +/*****************************************************************************/ + +static gboolean +psk_setting_to_iwd_config(GKeyFile *file, NMSettingWirelessSecurity *s_wsec, GError **error) +{ + NMSettingSecretFlags psk_flags = nm_setting_wireless_security_get_psk_flags(s_wsec); + const char * psk = nm_setting_wireless_security_get_psk(s_wsec); + gsize psk_len; + guint8 buffer[32]; + const char * key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + + if (!psk || (psk_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) { + g_key_file_set_comment(file, + "Security", + NULL, + "The passphrase is to be queried through the agent", + NULL); + if (psk_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) { + nm_log_info( + LOGD_WIFI, + "IWD network config is being created wihout the PSK but IWD will save the PSK on " + "successful activation not honoring the psk-flags property"); + } + return TRUE; + } + + psk_len = strlen(psk); + if (nm_streq0(key_mgmt, "sae")) { + g_key_file_set_string(file, "Security", "Passphrase", psk); + } else if (psk_len >= 8 && psk_len <= 63) { + g_key_file_set_string(file, "Security", "Passphrase", psk); + } else if (psk_len == 64 && nm_utils_hexstr2bin_buf(psk, FALSE, FALSE, NULL, buffer)) { + g_key_file_set_string(file, "Security", "PreSharedKey", psk); + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Unknown PSK format"); + return FALSE; + } + + return TRUE; +} + +static gboolean +eap_certs_to_iwd_config(GKeyFile * file, + NMSetting8021x *s_8021x, + bool phase2, + char * iwd_prefix, + GError ** error) +{ + NMSetting8021xCKScheme ca_cert_scheme = + phase2 ? nm_setting_802_1x_get_phase2_ca_cert_scheme(s_8021x) + : nm_setting_802_1x_get_ca_cert_scheme(s_8021x); + NMSetting8021xCKScheme client_cert_scheme = + phase2 ? nm_setting_802_1x_get_phase2_client_cert_scheme(s_8021x) + : nm_setting_802_1x_get_ca_cert_scheme(s_8021x); + NMSetting8021xCKScheme key_scheme; + NMSettingSecretFlags key_password_flags; + const char * ca_path = phase2 ? nm_setting_802_1x_get_phase2_ca_path(s_8021x) + : nm_setting_802_1x_get_ca_path(s_8021x); + const char * cert_path; + const char * key_path = NULL; + const char * key_password; + const char * domain_suffix_match; + const char * domain_match; + char setting_buf[128]; + + /* TODO: should check that all certificates and the key are RSA */ + /* Note: up to IWD 1.9 only the PEM encoding was supported for certificates + * and only PKCS#8 PEM for keys but we don't know the IWD version here. + * From IWD 1.10 raw (DER) X.509 certificates and PKCS#12 are also supported + * for certificates but a certificate list or chain still has to be PEM + * (i.e. if it contains more than one certificate.) Raw PKCS#12 and + * old-style OpenSSL PEM formats are also supported for keys. Hopefully + * this is in practice the same set of file:// formats as supported by + * nm_crypto_* / wpa_supplicant so we need no conversions here. + */ + + if (nm_setting_802_1x_get_system_ca_certs(s_8021x)) { + /* Either overrides or is added to the certificates in (phase2-)ca-cert + * and ca-path depending on whether it points to a file or a directory. + * We can't ignore this property so it's an error if it is set. + * Fortunately not used by nm-connection-editor. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "The system-ca-certs property is not supported"); + return FALSE; + } + + if (ca_path) { + /* To support this (and this could be applied to system-ca-certs as + * well) we'd have to scan the directory, parse the certificates and + * write a new certificate-list file to point to in the IWD config. + * This is going to create issues of where to store these files, for + * how long and with what permission bits. Fortunately this doesn't + * seem to be used by nm-connection-editor either. + * + * That file would also have to contain whatever the (phase2-)ca-cert + * propterty points to because IWD has only one CACert setting per + * phase. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "The (phase2-)ca-path property is not supported"); + return FALSE; + } + + if (ca_cert_scheme != NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { + if (ca_cert_scheme != NM_SETTING_802_1X_CK_SCHEME_PATH) { + /* To support the blob scheme we'd have to either convert the + * certificate data into a PEM payload and embed the PEM file in + * the IWD config file, which is not supported by GKeyFile, or write + * it into a new file to point to in the IWD config. This is again + * is going to create issues of where to store these files, for how + * long and with what permission bits. Fortunately this scheme isn't + * used in nm-connection-editor either. + * + * PKCS#11 is not supported by IWD in any way so we don't need to + * support the PKCS#11 URI scheme. + * + * If scheme is unknown, assume no value is set. + */ + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)ca-cert property schemes other than file:// not supported"); + return FALSE; + } + + cert_path = phase2 ? nm_setting_802_1x_get_phase2_ca_cert_path(s_8021x) + : nm_setting_802_1x_get_ca_cert_path(s_8021x); + if (cert_path) + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "CACert"), + cert_path); + } + + if (client_cert_scheme == NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) + goto private_key_done; + + if (client_cert_scheme != NM_SETTING_802_1X_CK_SCHEME_PATH) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)client-cert property schemes other than file:// not supported"); + return FALSE; + } + + cert_path = phase2 ? nm_setting_802_1x_get_phase2_client_cert_path(s_8021x) + : nm_setting_802_1x_get_client_cert_path(s_8021x); + if (!cert_path) + goto private_key_done; + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ClientCert"), + cert_path); + + key_scheme = phase2 ? nm_setting_802_1x_get_phase2_private_key_scheme(s_8021x) + : nm_setting_802_1x_get_private_key_scheme(s_8021x); + if (key_scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + key_path = phase2 ? nm_setting_802_1x_get_phase2_private_key_path(s_8021x) + : nm_setting_802_1x_get_private_key_path(s_8021x); + if (key_scheme != NM_SETTING_802_1X_CK_SCHEME_PATH || !key_path) { + /* The same comments apply to writing the key into a temporary file + * as for the certificates (above), except this is even more + * sensitive. + */ + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)private-key property schemes other than file:// not supported"); + return FALSE; + } + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ClientKey"), + key_path); + + key_password = phase2 ? nm_setting_802_1x_get_phase2_private_key_password(s_8021x) + : nm_setting_802_1x_get_private_key_password(s_8021x); + key_password_flags = phase2 ? nm_setting_802_1x_get_phase2_private_key_password_flags(s_8021x) + : nm_setting_802_1x_get_private_key_password_flags(s_8021x); + if (!key_password || (key_password_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) { + g_key_file_set_comment( + file, + "Security", + setting_buf, + "ClientKeyPassphrase not to be saved, will be queried through the agent if needed", + NULL); + goto private_key_done; + } + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ClientKeyPassphrase"), + key_password); + +private_key_done: + if (phase2 ? nm_setting_802_1x_get_phase2_subject_match(s_8021x) + : nm_setting_802_1x_get_subject_match(s_8021x)) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)subject-match not supported, use domain-match or domain-suffix-match"); + return FALSE; + } + + if (phase2 ? nm_setting_802_1x_get_num_phase2_altsubject_matches(s_8021x) + : nm_setting_802_1x_get_num_altsubject_matches(s_8021x)) { + /* We could convert the "DNS:" entries into a ServerDomainMask but we'd + * have to leave out the "EMAIL:" and "URI:" types or report error. + * The interpretation still wouldn't be exactly the same as in + * wpa_supplicant. + */ + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)altsubject-matches not supported, use domain-match or domain-suffix-match"); + return FALSE; + } + + domain_suffix_match = phase2 ? nm_setting_802_1x_get_phase2_domain_suffix_match(s_8021x) + : nm_setting_802_1x_get_domain_suffix_match(s_8021x); + domain_match = phase2 ? nm_setting_802_1x_get_phase2_domain_match(s_8021x) + : nm_setting_802_1x_get_domain_match(s_8021x); + + if (domain_suffix_match || domain_match) { + GString * s = g_string_sized_new(128); + const char *ptr; + const char *end; + + for (ptr = domain_suffix_match; ptr; ptr = *end == ';' ? end + 1 : NULL) { + if (s->len) + g_string_append_c(s, ';'); + end = strchrnul(ptr, ';'); + /* Use *. to get the suffix match effect */ + g_string_append(s, "*."); + g_string_append_len(s, ptr, end - ptr); + } + + /* domain-match can be appended as-is */ + if (domain_match) { + if (s->len) + g_string_append_c(s, ';'); + g_string_append(s, domain_match); + } + + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ServerDomainMask"), + s->str); + g_string_free(s, TRUE); + } + + return TRUE; +} + +static void +eap_method_name_to_iwd_config(GKeyFile *file, const char *iwd_prefix, const char *method) +{ + char setting_buf[128]; + + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Method"), + method); +} + +static void +eap_optional_identity_to_iwd_config(GKeyFile *file, const char *iwd_prefix, const char *identity) +{ + char setting_buf[128]; + + /* The identity is optional for some methods where an authenticator may + * in theory not ask for it. For our usage here we treat it as always + * optional because it can be omitted in the config file if the user + * wants IWD to query for it on every connection. + */ + if (identity) { + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Identity"), + identity); + } else { + g_key_file_set_comment( + file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Method"), + "Identity not to be saved, will be queried through the agent if needed", + NULL); + } +} + +static gboolean +eap_optional_password_to_iwd_config(GKeyFile * file, + const char * iwd_prefix, + NMSetting8021x *s_8021x, + GError ** error) +{ + char setting_buf[128]; + const char * password = nm_setting_802_1x_get_password(s_8021x); + NMSettingSecretFlags flags = nm_setting_802_1x_get_password_flags(s_8021x); + + if (!password && nm_setting_802_1x_get_password_raw(s_8021x)) { + /* IWD doesn't support passwords that can't be encoded in the config + * file, i.e. containing NUL characters. Those that don't have NULs + * could in theory be written to the config file but GKeyFile may not + * like that if they're no UTF-8, and the password-raw property is + * not written by nm-connection-editor anyway. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Non-UTF-8 passwords are not supported, if the password is UTF-8 set " + "the \"password\" property"); + return FALSE; + } + if (!password || (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) { + return g_key_file_set_comment(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Method"), + "Password not to be saved, will be queried through the agent", + error); + } else { + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Password"), + password); + return TRUE; + } +} + +static gboolean +eap_method_config_to_iwd_config(GKeyFile * file, + NMSetting8021x *s_8021x, + gboolean phase2, + const char * method, + const char * iwd_prefix, + GError ** error) +{ + char prefix_buf[128]; + + if (nm_streq0(method, "tls")) { + eap_method_name_to_iwd_config(file, iwd_prefix, "TLS"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + + return eap_certs_to_iwd_config(file, + s_8021x, + phase2, + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "TLS-"), + error); + } else if (nm_streq0(method, "ttls") && !phase2) { + const char *noneap_method = nm_setting_802_1x_get_phase2_auth(s_8021x); + + eap_method_name_to_iwd_config(file, iwd_prefix, "TTLS"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_anonymous_identity(s_8021x)); + + if (!eap_certs_to_iwd_config(file, + s_8021x, + phase2, + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "TTLS-"), + error)) + return FALSE; + + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "TTLS-Phase2-"); + + if (nm_setting_802_1x_get_phase2_autheap(s_8021x)) { + if (noneap_method) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Only one TTLS phase 2 method can be set"); + return FALSE; + } + return eap_method_config_to_iwd_config(file, + s_8021x, + TRUE, + nm_setting_802_1x_get_phase2_autheap(s_8021x), + prefix_buf, + error); + } + + if (NM_IN_STRSET(noneap_method, "chap", "mschap", "mschapv2", "pap")) { + const char *iwd_method; + + if (nm_streq0(noneap_method, "chap")) { + iwd_method = "Tunneled-CHAP"; + } else if (nm_streq0(noneap_method, "mschap")) { + iwd_method = "Tunneled-MSCHAP"; + } else if (nm_streq0(noneap_method, "mschapv2")) { + iwd_method = "Tunneled-MSCHAPv2"; + } else { + iwd_method = "Tunneled-PAP"; + } + + eap_method_name_to_iwd_config(file, prefix_buf, iwd_method); + eap_optional_identity_to_iwd_config(file, + prefix_buf, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, prefix_buf, s_8021x, error); + } + + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Unsupported TTLS non-EAP inner method"); + return FALSE; + } else if (nm_streq0(method, "peap") && !phase2) { + eap_method_name_to_iwd_config(file, iwd_prefix, "PEAP"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_anonymous_identity(s_8021x)); + + if (!eap_certs_to_iwd_config(file, + s_8021x, + phase2, + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "PEAP-"), + error)) + return FALSE; + + if (nm_setting_802_1x_get_phase1_peapver(s_8021x) + || nm_setting_802_1x_get_phase1_peaplabel(s_8021x)) + nm_log_info(LOGD_WIFI, + "IWD network config will not honour the PEAP version and label properties " + "in the 802.1x setting (unsupported)"); + + if (!nm_setting_802_1x_get_phase2_auth(s_8021x)) { + /* Apparently PEAP can be used without a phase 2 but this is not + * supported by either NM or IWD. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "PEAP without an inner method is unsupported"); + return FALSE; + } + + return eap_method_config_to_iwd_config( + file, + s_8021x, + TRUE, + nm_setting_802_1x_get_phase2_auth(s_8021x), + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "PEAP-Phase2-"), + error); + } else if (nm_streq0(method, "md5") && phase2) { + eap_method_name_to_iwd_config(file, iwd_prefix, "MD5"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "gtc") && phase2) { + eap_method_name_to_iwd_config(file, iwd_prefix, "GTC"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "pwd")) { + eap_method_name_to_iwd_config(file, iwd_prefix, "PWD"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "mschapv2")) { + eap_method_name_to_iwd_config(file, iwd_prefix, "MSCHAPV2"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + /* In this case we can support password-raw but would have to + * MD4-hash it and set as Password-Hash + */ + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "external")) { + /* This may be a connection created by NMIwdManager in whch case there + * may be no need to be convert it back to the IWD format. Ideally we + * would still rewrite the other sections/groups in the IWD settings + * file and preserve the [Security] group -- TODO. Possibly this should + * also not be reported as an error. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection contains no EAP method configuration"); + return FALSE; + } else { + /* Some methods are only allowed in phase 1 or only phase 2. + * OTP, LEAP and FAST are not supported by IWD at all. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + phase2 ? "Unsupported phase 2 EAP method" + : "Unsupported phase 1 EAP method"); + return FALSE; + } + + return TRUE; +} + +static gboolean +eap_setting_to_iwd_config(GKeyFile *file, NMSetting8021x *s_8021x, GError **error) +{ + const char *method; + + if (!s_8021x || nm_setting_802_1x_get_num_eap_methods(s_8021x) == 0) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "The 802.1x setting is missing or no EAP method set"); + return FALSE; + } + + if (!nm_setting_verify(NM_SETTING(s_8021x), NULL, error)) + return FALSE; + + method = nm_setting_802_1x_get_eap_method(s_8021x, 0); + + if (nm_setting_802_1x_get_num_eap_methods(s_8021x) > 1) + nm_log_info(LOGD_WIFI, + "IWD network config will only contain the first EAP method: %s", + method); + + if (nm_setting_802_1x_get_phase1_auth_flags(s_8021x)) + nm_log_info(LOGD_WIFI, + "IWD network config will not honour the TLSv1.x-disable flags in the 802.1x " + "setting (unsupported)"); + + if (nm_setting_802_1x_get_auth_timeout(s_8021x)) + nm_log_info(LOGD_WIFI, + "IWD network config will not honour the auth-timeout property in the 802.1x " + "setting (unsupported)"); + + return eap_method_config_to_iwd_config(file, s_8021x, FALSE, method, "EAP-", error); +} + +static gboolean +ip4_config_to_iwd_config(GKeyFile *file, NMSettingIPConfig *s_ip, GError **error) +{ + guint num; + struct in_addr ip; + + /* These settings are not acutally used unless global + * [General].EnableNetworkConfiguration is true, which we don't support. + * We add them for sake of completness, although many NMSettingIPConfig + * configurations can't be mapped to IWD configs and we simply ignore + * them. If they were to be used we'd need to add a few warnings. + */ + + if (!s_ip) + return TRUE; + + num = nm_setting_ip_config_get_num_dns(s_ip); + if (num) { + nm_auto_free_gstring GString *s = g_string_sized_new(128); + guint i; + + for (i = 0; i < num; i++) { + if (s->len) + g_string_append_c(s, ' '); + g_string_append(s, nm_setting_ip_config_get_dns(s_ip, i)); + } + /* It doesn't matter whether we add the DNS under [IPv4] or [IPv6] + * except that with method=auto the list will override the + * DNS addresses received over the DHCP version corresponing to + * v4 or v6. + * Note ignore-auto-dns=false isn't supported, this list always + * overrides the DHCP DNSes. + */ + g_key_file_set_string(file, "IPv4", "DNS", s->str); + } + + if (!nm_streq0(nm_setting_ip_config_get_method(s_ip), NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) + return TRUE; + + num = nm_setting_ip_config_get_num_addresses(s_ip); + if (num) { + NMIPAddress *addr = nm_setting_ip_config_get_address(s_ip, 0); + guint prefix = nm_ip_address_get_prefix(addr); + in_addr_t netmask = htonl(0xffffffffu << (32 - prefix)); + char buf[INET_ADDRSTRLEN]; + + nm_ip_address_get_address_binary(addr, &ip); + g_key_file_set_string(file, "IPv4", "Address", nm_ip_address_get_address(addr)); + g_key_file_set_string(file, "IPv4", "Netmask", _nm_utils_inet4_ntop(netmask, buf)); + } else { + inet_pton(AF_INET, "10.42.0.100", &ip); + g_key_file_set_string(file, "IPv4", "Address", "10.42.0.100"); + } + + if (nm_setting_ip_config_get_gateway(s_ip)) { + g_key_file_set_string(file, "IPv4", "Gateway", nm_setting_ip_config_get_gateway(s_ip)); + } else { + uint32_t val; + char buf[INET_ADDRSTRLEN]; + + /* IWD won't enable static IP unless both Address and Gateway are + * set so generate a gateway address if not known. + */ + val = (ntohl(ip.s_addr) & 0xfffffff0) + 1; + if (val == ntohl(ip.s_addr)) + val += 1; + g_key_file_set_string(file, "IPv4", "Gateway", _nm_utils_inet4_ntop(htonl(val), buf)); + } + + return TRUE; +} + +static gboolean +ip6_config_to_iwd_config(GKeyFile *file, NMSettingIPConfig *s_ip, GError **error) +{ + guint num; + NMIPAddress *addr; + char buf[INET6_ADDRSTRLEN + 10]; + + if (!s_ip) + return TRUE; + + num = nm_setting_ip_config_get_num_dns(s_ip); + if (num) { + nm_auto_free_gstring GString *s = g_string_sized_new(128); + guint i; + + for (i = 0; i < num; i++) { + if (s->len) + g_string_append_c(s, ' '); + g_string_append(s, nm_setting_ip_config_get_dns(s_ip, i)); + } + g_key_file_set_string(file, "IPv6", "DNS", s->str); + } + + if (!NM_IN_STRSET(nm_setting_ip_config_get_method(s_ip), + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) + return TRUE; + + g_key_file_set_boolean(file, "IPv6", "Enabled", TRUE); + + if (!nm_streq0(nm_setting_ip_config_get_method(s_ip), NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) + return TRUE; + + if (!nm_setting_ip_config_get_num_addresses(s_ip)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "IP address required for IPv6 manual config"); + return FALSE; + } + + addr = nm_setting_ip_config_get_address(s_ip, 0); + g_key_file_set_string(file, + "IPv6", + "Address", + nm_sprintf_buf(buf, + "%s/%u", + nm_ip_address_get_address(addr), + nm_ip_address_get_prefix(addr))); + if (nm_setting_ip_config_get_gateway(s_ip)) + g_key_file_set_string(file, "IPv6", "Gateway", nm_setting_ip_config_get_gateway(s_ip)); + return TRUE; +} + +GKeyFile * +nm_wifi_utils_connection_to_iwd_config(NMConnection *connection, + char ** out_filename, + GError ** error) +{ + NMSettingConnection * s_conn = nm_connection_get_setting_connection(connection); + NMSettingWireless * s_wifi = nm_connection_get_setting_wireless(connection); + GBytes * ssid; + const guint8 * ssid_data; + gsize ssid_len; + NMIwdNetworkSecurity security; + const char * cloned_mac_addr; + nm_auto_unref_keyfile GKeyFile *file = NULL; + + if (!s_conn || !s_wifi + || !nm_streq(nm_setting_connection_get_connection_type(s_conn), + NM_SETTING_WIRELESS_SETTING_NAME)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection and/or wireless settings are missing"); + return NULL; + } + + if (!NM_IN_STRSET(nm_setting_wireless_get_mode(s_wifi), NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Non-infrastructure-mode connections don't have IWD profiles (or aren't supported)"); + return NULL; + } + + ssid = nm_setting_wireless_get_ssid(s_wifi); + ssid_data = ssid ? g_bytes_get_data(ssid, &ssid_len) : NULL; + if (!ssid_data || ssid_len <= 0 || ssid_len > NM_IW_ESSID_MAX_SIZE + || !g_utf8_validate((const char *) ssid_data, ssid_len, NULL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Empty or non-UTF-8 SSIDs not supported by IWD"); + return NULL; + } + + if (!nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection's security type unrecognised"); + return NULL; + } + + file = g_key_file_new(); + + if (!nm_setting_connection_get_autoconnect(s_conn)) + g_key_file_set_boolean(file, "Settings", "AutoConnect", FALSE); + + if (nm_setting_wireless_get_hidden(s_wifi)) + g_key_file_set_boolean(file, "Settings", "Hidden", TRUE); + + /* Only effective if IWD's global [General].AddressRandomization is set + * to "network". "random" maps to [Settings].AlwaysRandomizeAddress=true, + * "stable" is the default, specific address maps to + * [Settings].AddressOverride set to that address. "permanent" is not + * supported and "preserve" can only be achieved using the global + * [General].AddressRandomization=disabled setting. We don't print + * warnings when we can't map the value here because we don't know what + * IWD's [General].AddressRandomization is set to. + */ + cloned_mac_addr = nm_setting_wireless_get_cloned_mac_address(s_wifi); + if (nm_streq0(cloned_mac_addr, NM_CLONED_MAC_RANDOM)) + g_key_file_set_boolean(file, "Settings", "AlwaysRandomizeAddress", TRUE); + else if (cloned_mac_addr && nm_utils_hwaddr_valid(cloned_mac_addr, ETH_ALEN)) + g_key_file_set_string(file, "Settings", "AddressOverride", cloned_mac_addr); + + if (!ip4_config_to_iwd_config( + file, + NM_SETTING_IP_CONFIG(nm_connection_get_setting_ip4_config(connection)), + error)) + return NULL; + + if (!ip6_config_to_iwd_config( + file, + NM_SETTING_IP_CONFIG(nm_connection_get_setting_ip6_config(connection)), + error)) + return NULL; + + switch (security) { + case NM_IWD_NETWORK_SECURITY_OPEN: + break; + case NM_IWD_NETWORK_SECURITY_PSK: + if (!psk_setting_to_iwd_config(file, + nm_connection_get_setting_wireless_security(connection), + error)) + return NULL; + + break; + case NM_IWD_NETWORK_SECURITY_8021X: + if (!eap_setting_to_iwd_config(file, nm_connection_get_setting_802_1x(connection), error)) + return NULL; + + break; + default: + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection security type is not supported"); + return NULL; + } + + if (out_filename) + *out_filename = + nm_wifi_utils_get_iwd_config_filename((const char *) ssid_data, ssid_len, security); + + return g_steal_pointer(&file); +} diff --git a/src/core/devices/wifi/nm-wifi-utils.h b/src/core/devices/wifi/nm-wifi-utils.h index 474bea4..2664c03 100644 --- a/src/core/devices/wifi/nm-wifi-utils.h +++ b/src/core/devices/wifi/nm-wifi-utils.h @@ -11,6 +11,7 @@ #include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h" #include "nm-setting-8021x.h" +#include "libnm-base/nm-base.h" typedef enum { NM_IWD_NETWORK_SECURITY_OPEN, @@ -21,7 +22,7 @@ typedef enum { gboolean nm_wifi_utils_complete_connection(GBytes * ssid, const char * bssid, - NM80211Mode mode, + _NM80211Mode mode, guint32 ap_freq, guint32 flags, guint32 wpa_flags, @@ -35,5 +36,11 @@ gboolean nm_wifi_utils_is_manf_default_ssid(GBytes *ssid); gboolean nm_wifi_connection_get_iwd_ssid_and_security(NMConnection * connection, char ** ssid, NMIwdNetworkSecurity *security); +char * nm_wifi_utils_get_iwd_config_filename(const char * ssid, + gssize ssid_len, + NMIwdNetworkSecurity security); + +GKeyFile * +nm_wifi_utils_connection_to_iwd_config(NMConnection *conn, char **out_filename, GError **error); #endif /* __NM_WIFI_UTILS_H__ */ diff --git a/src/core/devices/wifi/tests/test-devices-wifi.c b/src/core/devices/wifi/tests/test-devices-wifi.c index bc0ba12..dc278c9 100644 --- a/src/core/devices/wifi/tests/test-devices-wifi.c +++ b/src/core/devices/wifi/tests/test-devices-wifi.c @@ -7,7 +7,7 @@ #include "devices/wifi/nm-wifi-utils.h" #include "devices/wifi/nm-device-wifi.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-test-utils-core.h" @@ -49,7 +49,7 @@ static gboolean complete_connection(const char * ssid, const char * bssid, - NM80211Mode mode, + _NM80211Mode mode, guint32 flags, guint32 wpa_flags, guint32 rsn_flags, @@ -197,7 +197,7 @@ fill_8021x(NMConnection *connection, const KeyData items[]) } static NMConnection * -create_basic(const char *ssid, const char *bssid, NM80211Mode mode) +create_basic(const char *ssid, const char *bssid, _NM80211Mode mode) { NMConnection * connection; NMSettingWireless *s_wifi = NULL; @@ -217,9 +217,9 @@ create_basic(const char *ssid, const char *bssid, NM80211Mode mode) if (bssid) g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); - if (mode == NM_802_11_MODE_INFRA) + if (mode == _NM_802_11_MODE_INFRA) g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - else if (mode == NM_802_11_MODE_ADHOC) + else if (mode == _NM_802_11_MODE_ADHOC) g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_MODE, "adhoc", NULL); else g_assert_not_reached(); @@ -241,14 +241,14 @@ test_lock_bssid(void) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, TRUE, src, &error); - expected = create_basic(ssid, bssid, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, bssid, _NM_802_11_MODE_INFRA); COMPARE(src, expected, success, error, 0, 0); g_object_unref(src); @@ -273,14 +273,14 @@ test_open_ap_empty_connection(void) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); COMPARE(src, expected, success, error, 0, 0); g_object_unref(src); @@ -311,7 +311,7 @@ test_open_ap_leap_connection_1(gconstpointer add_wifi) success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -345,7 +345,7 @@ test_open_ap_leap_connection_2(void) success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -383,7 +383,7 @@ test_open_ap_wep_connection(gconstpointer add_wifi) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -427,7 +427,7 @@ test_ap_wpa_psk_connection_base(const char * key_mgmt, fill_wsec(src, both_wsec); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, flags, wpa_flags, rsn_flags, @@ -553,7 +553,7 @@ test_ap_wpa_eap_connection_base(const char *key_mgmt, fill_8021x(src, src_empty); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, flags, wpa_flags, rsn_flags, @@ -751,7 +751,7 @@ test_priv_ap_empty_connection(void) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -760,7 +760,7 @@ test_priv_ap_empty_connection(void) &error); /* Static WEP connection expected */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); COMPARE(src, expected, success, error, 0, 0); @@ -798,7 +798,7 @@ test_priv_ap_leap_connection_1(gconstpointer add_wifi) fill_wsec(src, src_wsec); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -809,7 +809,7 @@ test_priv_ap_leap_connection_1(gconstpointer add_wifi) * there's no way to determine from the AP's beacon whether it's static WEP, * dynamic WEP, or LEAP. */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); COMPARE(src, expected, success, error, 0, 0); @@ -840,7 +840,7 @@ test_priv_ap_leap_connection_2(void) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -885,7 +885,7 @@ test_priv_ap_dynamic_wep_1(void) fill_8021x(src, both_8021x); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -894,7 +894,7 @@ test_priv_ap_dynamic_wep_1(void) &error); /* We expect a completed Dynamic WEP connection */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); fill_8021x(expected, both_8021x); COMPARE(src, expected, success, error, 0, 0); @@ -933,7 +933,7 @@ test_priv_ap_dynamic_wep_2(void) fill_8021x(src, both_8021x); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -942,7 +942,7 @@ test_priv_ap_dynamic_wep_2(void) &error); /* We expect a completed Dynamic WEP connection */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); fill_8021x(expected, both_8021x); COMPARE(src, expected, success, error, 0, 0); @@ -976,7 +976,7 @@ test_priv_ap_dynamic_wep_3(void) fill_8021x(src, src_8021x); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -1102,7 +1102,7 @@ test_wpa_ap_empty_connection(gconstpointer data) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), @@ -1111,7 +1111,7 @@ test_wpa_ap_empty_connection(gconstpointer data) &error); /* WPA connection expected */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); COMPARE(src, expected, success, error, 0, 0); @@ -1144,7 +1144,7 @@ test_wpa_ap_leap_connection_1(gconstpointer data) fill_wsec(src, src_wsec); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), @@ -1180,7 +1180,7 @@ test_wpa_ap_leap_connection_2(gconstpointer data) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), @@ -1214,7 +1214,7 @@ test_wpa_ap_dynamic_wep_connection(gconstpointer data) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), diff --git a/src/core/devices/wwan/meson.build b/src/core/devices/wwan/meson.build index 87af042..37ef738 100644 --- a/src/core/devices/wwan/meson.build +++ b/src/core/devices/wwan/meson.build @@ -17,7 +17,6 @@ libnm_wwan = shared_module( libsystemd_dep, mm_glib_dep, ], - c_args: daemon_c_flags, link_args: '-Wl,--version-script,@0@'.format(linker_script), link_depends: linker_script, install: true, @@ -51,7 +50,6 @@ libnm_device_plugin_wwan = shared_module( libsystemd_dep, mm_glib_dep, ], - c_args: daemon_c_flags, link_with: libnm_wwan, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, diff --git a/src/core/devices/wwan/nm-device-modem.c b/src/core/devices/wwan/nm-device-modem.c index 3ea89d2..405ced6 100644 --- a/src/core/devices/wwan/nm-device-modem.c +++ b/src/core/devices/wwan/nm-device-modem.c @@ -14,7 +14,7 @@ #include "settings/nm-settings-connection.h" #include "nm-modem-broadband.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceModem #include "devices/nm-device-logging.h" @@ -357,7 +357,6 @@ modem_state_cb(NMModem *modem, int new_state_i, int old_state_i, gpointer user_d nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); - return; } if (new_state > NM_MODEM_STATE_LOCKED && old_state == NM_MODEM_STATE_LOCKED) { diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c index ca02880..0872a8a 100644 --- a/src/core/devices/wwan/nm-modem-broadband.c +++ b/src/core/devices/wwan/nm-modem-broadband.c @@ -11,10 +11,10 @@ #include #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" @@ -369,10 +369,10 @@ static void connect_ready(MMModemSimple *simple_iface, GAsyncResult *res, NMModemBroadband *self) { ConnectContext *ctx; - GError * error = NULL; - NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; - NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; - MMBearer * bearer; + GError * error = NULL; + NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; + gs_unref_object MMBearer *bearer = NULL; bearer = mm_modem_simple_connect_finish(simple_iface, res, &error); @@ -386,7 +386,7 @@ connect_ready(MMModemSimple *simple_iface, GAsyncResult *res, NMModemBroadband * if (!ctx) return; - self->_priv.bearer = bearer; + self->_priv.bearer = g_steal_pointer(&bearer); if (!self->_priv.bearer) { if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) diff --git a/src/core/devices/wwan/nm-modem-manager.c b/src/core/devices/wwan/nm-modem-manager.c index 598c689..4fb9a37 100644 --- a/src/core/devices/wwan/nm-modem-manager.c +++ b/src/core/devices/wwan/nm-modem-manager.c @@ -17,7 +17,7 @@ #define sd_booted() FALSE #endif -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-modem.h" #include "nm-modem-broadband.h" diff --git a/src/core/devices/wwan/nm-modem-ofono.c b/src/core/devices/wwan/nm-modem-ofono.c index 21734ce..78ad7b6 100644 --- a/src/core/devices/wwan/nm-modem-ofono.c +++ b/src/core/devices/wwan/nm-modem-ofono.c @@ -7,10 +7,10 @@ #include "nm-modem-ofono.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "devices/nm-device-private.h" #include "nm-modem.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-ip4-config.h" #define VARIANT_IS_OF_TYPE_BOOLEAN(v) \ @@ -316,10 +316,9 @@ handle_sim_property(GDBusProxy *proxy, const char *property, GVariant *v, gpoint static void sim_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - GVariant *v_child = g_variant_get_child_value(v, 0); + gs_unref_variant GVariant *v_child = g_variant_get_child_value(v, 0); handle_sim_property(proxy, property, v_child, user_data); - g_variant_unref(v_child); } static void @@ -330,7 +329,7 @@ sim_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_dat gs_free_error GError *error = NULL; gs_unref_variant GVariant *v_properties = NULL; gs_unref_variant GVariant *v_dict = NULL; - GVariant * v; + gs_unref_variant GVariant *v = NULL; GVariantIter i; const char * property; @@ -370,9 +369,8 @@ sim_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_dat */ g_variant_iter_init(&i, v_dict); - while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) { handle_sim_property(NULL, property, v, self); - g_variant_unref(v); } } @@ -477,10 +475,9 @@ handle_connman_property(GDBusProxy *proxy, const char *property, GVariant *v, gp static void connman_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - GVariant *v_child = g_variant_get_child_value(v, 0); + gs_unref_variant GVariant *v_child = g_variant_get_child_value(v, 0); handle_connman_property(proxy, property, v_child, user_data); - g_variant_unref(v_child); } static void @@ -491,7 +488,7 @@ connman_get_properties_done(GObject *source, GAsyncResult *result, gpointer user gs_free_error GError *error = NULL; gs_unref_variant GVariant *v_properties = NULL; gs_unref_variant GVariant *v_dict = NULL; - GVariant * v; + gs_unref_variant GVariant *v = NULL; GVariantIter i; const char * property; @@ -523,9 +520,8 @@ connman_get_properties_done(GObject *source, GAsyncResult *result, gpointer user */ g_variant_iter_init(&i, v_dict); - while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) { handle_connman_property(NULL, property, v, self); - g_variant_unref(v); } } @@ -700,9 +696,8 @@ modem_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_d */ g_variant_iter_init(&i, v_dict); - while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) { handle_modem_property(NULL, property, v, self); - g_variant_unref(v); } } @@ -726,35 +721,30 @@ stage1_prepare_done(GObject *source, GAsyncResult *result, gpointer user_data) nm_clear_pointer(&priv->connect_properties, g_hash_table_destroy); if (error) { - _LOGW("connection failed: %s", error->message); - - nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY); - /* - * FIXME: add code to check for InProgress so that the - * connection doesn't continue to try and activate, - * leading to the connection being disabled, and a 5m - * timeout... - */ + if (!g_strstr_len(error->message, + NM_STRLEN(OFONO_ERROR_IN_PROGRESS), + OFONO_ERROR_IN_PROGRESS)) { + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY); + } } } static void -context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) +handle_settings(GVariant *v_dict, gpointer user_data) { NMModemOfono * self = NM_MODEM_OFONO(user_data); NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); NMPlatformIP4Address addr; - gboolean ret = FALSE; - gs_unref_variant GVariant *v_dict = NULL; - const char * interface; - const char * s; - const char ** array, **iter; - guint32 address_network, gateway_network; - guint32 ip4_route_table, ip4_route_metric; - int ifindex; - GError * error = NULL; + gboolean ret = FALSE; + const char * interface; + const char * s; + const char ** array, **iter; + guint32 address_network, gateway_network; + guint32 ip4_route_table, ip4_route_metric; + int ifindex; + GError * error = NULL; - _LOGD("PropertyChanged: %s", property); + //_LOGD("PropertyChanged: %s", property); /* * TODO: might be a good idea and re-factor this to mimic bluez-device, @@ -762,15 +752,6 @@ context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, g * handle the action. */ - if (g_strcmp0(property, "Settings") != 0) - return; - - v_dict = g_variant_get_child_value(v, 0); - if (!v_dict) { - _LOGW("error getting IPv4 Settings: no v_dict"); - goto out; - } - _LOGI("IPv4 static Settings:"); if (!g_variant_lookup(v_dict, "Interface", "&s", &interface)) { @@ -909,6 +890,28 @@ out: } } +static void +context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) +{ + NMModemOfono * self = NM_MODEM_OFONO(user_data); + gs_unref_variant GVariant *v_dict = NULL; + + _LOGD("PropertyChanged: %s", property); + + if (g_strcmp0(property, "Settings") != 0) + return; + + v_dict = g_variant_get_child_value(v, 0); + if (!v_dict) { + _LOGW("ofono: (%s): error getting IPv4 Settings", nm_modem_get_uid(NM_MODEM(self))); + return; + } + + g_assert(g_variant_is_of_type(v_dict, G_VARIANT_TYPE_VARDICT)); + + handle_settings(v_dict, user_data); +} + static NMActStageReturn static_stage3_ip4_config_start(NMModem * modem, NMActRequest * req, @@ -936,6 +939,72 @@ static_stage3_ip4_config_start(NMModem * modem, } static void +context_properties_cb(GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *properties = NULL; + gs_unref_variant GVariant *settings = NULL; + gs_unref_variant GVariant *v_dict = NULL; + gboolean active; + + self = NM_MODEM_OFONO(user_data); + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + properties = g_dbus_proxy_call_finish(proxy, result, &error); + + if (!properties) { + _LOGW("ofono: connection failed: no context properties returned %s", error->message); + g_clear_error(&error); + goto error; + } + + v_dict = g_variant_get_child_value(properties, 0); + if (!v_dict || !g_variant_is_of_type(v_dict, G_VARIANT_TYPE_VARDICT)) { + _LOGW("ofono: connection failed; could not read connection properties"); + goto error; + } + + if (!g_variant_lookup(v_dict, "Active", "b", &active)) { + _LOGW("ofono: connection failed; can not read 'Active' property"); + goto error; + } + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect(priv->context_proxy, + "PropertyChanged", + G_VARIANT_TYPE("(sv)"), + G_CALLBACK(context_property_changed), + self); + + if (active) { + _LOGD("ofono: connection is already Active"); + + settings = g_variant_lookup_value(v_dict, "Settings", G_VARIANT_TYPE_VARDICT); + if (settings == NULL) { + _LOGW("ofono: connection failed; can not read 'Settings' property"); + goto error; + } + + handle_settings(settings, user_data); + } else { + g_dbus_proxy_call(priv->context_proxy, + "SetProperty", + g_variant_new("(sv)", "Active", g_variant_new("b", TRUE)), + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) stage1_prepare_done, + self); + } + return; + +error: + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY); +} + +static void context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data) { NMModemOfono * self; @@ -973,19 +1042,15 @@ context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data) */ g_clear_object(&priv->ip4_config); - _nm_dbus_signal_connect(priv->context_proxy, - "PropertyChanged", - G_VARIANT_TYPE("(sv)"), - G_CALLBACK(context_property_changed), - self); - + /* We need to directly query ConnectionContextinteface to get the current + * property values */ g_dbus_proxy_call(priv->context_proxy, - "SetProperty", - g_variant_new("(sv)", "Active", g_variant_new("b", TRUE)), + "GetProperties", + NULL, G_DBUS_CALL_FLAGS_NONE, 20000, - priv->context_proxy_cancellable, - stage1_prepare_done, + NULL, + (GAsyncReadyCallback) context_properties_cb, self); } @@ -1069,6 +1134,7 @@ modem_act_stage1_prepare(NMModem * modem, _LOGI("activating context %s", priv->context_path); + update_modem_state(self); if (nm_modem_get_state(modem) == NM_MODEM_STATE_REGISTERED) { do_context_activate(self); } else { diff --git a/src/core/devices/wwan/nm-modem-ofono.h b/src/core/devices/wwan/nm-modem-ofono.h index 260e395..ebe2102 100644 --- a/src/core/devices/wwan/nm-modem-ofono.h +++ b/src/core/devices/wwan/nm-modem-ofono.h @@ -25,6 +25,8 @@ #define OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT "org.ofono.ConnectionContext" #define OFONO_DBUS_INTERFACE_SIM_MANAGER "org.ofono.SimManager" +#define OFONO_ERROR_IN_PROGRESS "org.ofono.Error.InProgress" + typedef struct _NMModemOfono NMModemOfono; typedef struct _NMModemOfonoClass NMModemOfonoClass; diff --git a/src/core/devices/wwan/nm-modem.c b/src/core/devices/wwan/nm-modem.c index 0d334fa..5366562 100644 --- a/src/core/devices/wwan/nm-modem.c +++ b/src/core/devices/wwan/nm-modem.c @@ -12,8 +12,8 @@ #include #include -#include "nm-core-internal.h" -#include "platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nm-platform.h" #include "nm-setting-connection.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" diff --git a/src/core/devices/wwan/nm-wwan-factory.c b/src/core/devices/wwan/nm-wwan-factory.c index 5d2ce2b..0d802ae 100644 --- a/src/core/devices/wwan/nm-wwan-factory.c +++ b/src/core/devices/wwan/nm-wwan-factory.c @@ -12,7 +12,7 @@ #include "nm-setting-cdma.h" #include "nm-modem-manager.h" #include "nm-device-modem.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" /*****************************************************************************/ diff --git a/src/core/dhcp/meson.build b/src/core/dhcp/meson.build index 1bb004c..ddaa32f 100644 --- a/src/core/dhcp/meson.build +++ b/src/core/dhcp/meson.build @@ -3,10 +3,11 @@ executable( 'nm-dhcp-helper', 'nm-dhcp-helper.c', - dependencies: glib_nm_default_dep, - c_args: [ - '-DG_LOG_DOMAIN="nm-dhcp-helper"', + include_directories: [ + src_inc, + top_inc, ], + dependencies: glib_dep, link_args: ldflags_linker_script_binary, link_depends: linker_script_binary, install: true, diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index c38c814..c128095 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -14,14 +14,14 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-glib-aux/nm-random-utils.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-random-utils.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" #include "nm-dhcp-utils.h" #include "nm-dhcp-options.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-dhcp-client-logging.h" diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.c b/src/core/dhcp/nm-dhcp-dhclient-utils.c index ad1e097..83de1c1 100644 --- a/src/core/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/core/dhcp/nm-dhcp-dhclient-utils.c @@ -12,12 +12,12 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-dedup-multi.h" #include "nm-dhcp-utils.h" #include "nm-ip4-config.h" #include "nm-utils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "NetworkManagerUtils.h" #define TIMEOUT_TAG "timeout " diff --git a/src/core/dhcp/nm-dhcp-dhclient.c b/src/core/dhcp/nm-dhcp-dhclient.c index c42a0ba..6384f39 100644 --- a/src/core/dhcp/nm-dhcp-dhclient.c +++ b/src/core/dhcp/nm-dhcp-dhclient.c @@ -21,7 +21,7 @@ #include #include - #include "nm-glib-aux/nm-dedup-multi.h" + #include "libnm-glib-aux/nm-dedup-multi.h" #include "nm-utils.h" #include "nm-dhcp-dhclient-utils.h" diff --git a/src/core/dhcp/nm-dhcp-helper.c b/src/core/dhcp/nm-dhcp-helper.c index 0f98add..4ffe93f 100644 --- a/src/core/dhcp/nm-dhcp-helper.c +++ b/src/core/dhcp/nm-dhcp-helper.c @@ -3,13 +3,13 @@ * Copyright (C) 2007 - 2013 Red Hat, Inc. */ -#include "nm-glib-aux/nm-default-glib.h" +#include "libnm-glib-aux/nm-default-glib.h" #include #include #include -#include "nm-utils/nm-vpn-plugin-macros.h" +#include "libnm-glib-aux/nm-logging-syslog.h" #include "nm-dhcp-helper-api.h" diff --git a/src/core/dhcp/nm-dhcp-listener.c b/src/core/dhcp/nm-dhcp-listener.c index 1673bbb..b8bb3c3 100644 --- a/src/core/dhcp/nm-dhcp-listener.c +++ b/src/core/dhcp/nm-dhcp-listener.c @@ -16,7 +16,7 @@ #include "nm-dhcp-helper-api.h" #include "nm-dhcp-client.h" #include "nm-dhcp-manager.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" #include "NetworkManagerUtils.h" diff --git a/src/core/dhcp/nm-dhcp-manager.c b/src/core/dhcp/nm-dhcp-manager.c index bc114ad..a9ca5a0 100644 --- a/src/core/dhcp/nm-dhcp-manager.c +++ b/src/core/dhcp/nm-dhcp-manager.c @@ -16,8 +16,8 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "nm-config.h" #include "NetworkManagerUtils.h" @@ -252,7 +252,7 @@ client_start(NMDhcpManager * self, } hwaddr_len = g_bytes_get_size(hwaddr); - if (hwaddr_len == 0 || hwaddr_len > NM_UTILS_HWADDR_LEN_MAX) { + if (hwaddr_len == 0 || hwaddr_len > _NM_UTILS_HWADDR_LEN_MAX) { nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "invalid MAC address"); g_return_val_if_reached(NULL); } diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index 116e1bd..dc9cbf5 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -13,9 +13,9 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-std-aux/unaligned.h" -#include "nm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-str-buf.h" #include "nm-utils.h" #include "nm-config.h" @@ -23,10 +23,10 @@ #include "nm-dhcp-options.h" #include "nm-core-utils.h" #include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-dhcp-client-logging.h" #include "n-dhcp4/src/n-dhcp4.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "systemd/nm-sd-utils-dhcp.h" /*****************************************************************************/ diff --git a/src/core/dhcp/nm-dhcp-options.c b/src/core/dhcp/nm-dhcp-options.c index 3537cd1..8f0d740 100644 --- a/src/core/dhcp/nm-dhcp-options.c +++ b/src/core/dhcp/nm-dhcp-options.c @@ -7,7 +7,7 @@ #include "nm-dhcp-options.h" -#include "nm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-str-buf.h" /*****************************************************************************/ diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c index b92a907..de8e514 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -13,15 +13,15 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-std-aux/unaligned.h" #include "nm-utils.h" #include "nm-dhcp-utils.h" #include "nm-dhcp-options.h" #include "nm-core-utils.h" #include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-dhcp-client-logging.h" #include "systemd/nm-sd.h" #include "systemd/nm-sd-utils-dhcp.h" diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c index 646411e..c3cbe61 100644 --- a/src/core/dhcp/nm-dhcp-utils.c +++ b/src/core/dhcp/nm-dhcp-utils.c @@ -8,18 +8,18 @@ #include #include -#include "nm-std-aux/unaligned.h" -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-glib-aux/nm-str-buf.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "nm-dhcp-utils.h" #include "nm-utils.h" #include "nm-config.h" #include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-dhcp-client-logging.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" /*****************************************************************************/ diff --git a/src/core/dhcp/tests/test-dhcp-dhclient.c b/src/core/dhcp/tests/test-dhcp-dhclient.c index 77626f6..e9a6209 100644 --- a/src/core/dhcp/tests/test-dhcp-dhclient.c +++ b/src/core/dhcp/tests/test-dhcp-dhclient.c @@ -9,14 +9,14 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-dedup-multi.h" #include "NetworkManagerUtils.h" #include "dhcp/nm-dhcp-dhclient-utils.h" #include "dhcp/nm-dhcp-utils.h" #include "nm-utils.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-test-utils-core.h" diff --git a/src/core/dhcp/tests/test-dhcp-utils.c b/src/core/dhcp/tests/test-dhcp-utils.c index 9b54e2c..4d47e7e 100644 --- a/src/core/dhcp/tests/test-dhcp-utils.c +++ b/src/core/dhcp/tests/test-dhcp-utils.c @@ -9,12 +9,12 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-dedup-multi.h" #include "nm-utils.h" #include "dhcp/nm-dhcp-utils.h" #include "dhcp/nm-dhcp-options.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-test-utils-core.h" diff --git a/src/core/dns/nm-dns-dnsmasq.c b/src/core/dns/nm-dns-dnsmasq.c index dcff98e..126e0a2 100644 --- a/src/core/dns/nm-dns-dnsmasq.c +++ b/src/core/dns/nm-dns-dnsmasq.c @@ -15,9 +15,9 @@ #include #include -#include "nm-glib-aux/nm-dbus-aux.h" -#include "nm-core-internal.h" -#include "platform/nm-platform.h" +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c index f318b9b..5e03b10 100644 --- a/src/core/dns/nm-dns-manager.c +++ b/src/core/dns/nm-dns-manager.c @@ -23,7 +23,7 @@ #endif #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dns-manager.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" @@ -1815,8 +1815,8 @@ plugin_skip:; NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED); } - /* signal that resolv.conf was changed */ - if (do_update && result == SR_SUCCESS) + /* signal that DNS resolution configs were changed */ + if ((do_update || caching) && result == SR_SUCCESS) g_signal_emit(self, signals[CONFIG_CHANGED], 0); nm_clear_pointer(&priv->config_variant, g_variant_unref); diff --git a/src/core/dns/nm-dns-plugin.c b/src/core/dns/nm-dns-plugin.c index 74d4eb2..e5035f0 100644 --- a/src/core/dns/nm-dns-plugin.c +++ b/src/core/dns/nm-dns-plugin.c @@ -12,7 +12,7 @@ #include #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" /*****************************************************************************/ diff --git a/src/core/dns/nm-dns-systemd-resolved.c b/src/core/dns/nm-dns-systemd-resolved.c index f6e116f..de01cf9 100644 --- a/src/core/dns/nm-dns-systemd-resolved.c +++ b/src/core/dns/nm-dns-systemd-resolved.c @@ -16,10 +16,10 @@ #include #include -#include "nm-glib-aux/nm-c-list.h" -#include "nm-glib-aux/nm-dbus-aux.h" -#include "nm-core-internal.h" -#include "platform/nm-platform.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" @@ -28,7 +28,7 @@ #include "nm-setting-connection.h" #include "devices/nm-device.h" #include "NetworkManagerUtils.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #define SYSTEMD_RESOLVED_DBUS_SERVICE "org.freedesktop.resolve1" #define SYSTEMD_RESOLVED_MANAGER_IFACE "org.freedesktop.resolve1.Manager" diff --git a/src/core/dnsmasq/nm-dnsmasq-manager.c b/src/core/dnsmasq/nm-dnsmasq-manager.c index 82c002b..e8697e8 100644 --- a/src/core/dnsmasq/nm-dnsmasq-manager.c +++ b/src/core/dnsmasq/nm-dnsmasq-manager.c @@ -17,7 +17,7 @@ #include "nm-dnsmasq-utils.h" #include "nm-utils.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define CONFDIR NMCONFDIR "/dnsmasq-shared.d" diff --git a/src/core/dnsmasq/nm-dnsmasq-utils.c b/src/core/dnsmasq/nm-dnsmasq-utils.c index ea23a78..86e18b5 100644 --- a/src/core/dnsmasq/nm-dnsmasq-utils.c +++ b/src/core/dnsmasq/nm-dnsmasq-utils.c @@ -8,7 +8,7 @@ #include #include "nm-dnsmasq-utils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" gboolean diff --git a/src/core/dnsmasq/nm-dnsmasq-utils.h b/src/core/dnsmasq/nm-dnsmasq-utils.h index 57bbc4c..1fabc9b 100644 --- a/src/core/dnsmasq/nm-dnsmasq-utils.h +++ b/src/core/dnsmasq/nm-dnsmasq-utils.h @@ -6,7 +6,7 @@ #ifndef __NETWORKMANAGER_DNSMASQ_UTILS_H__ #define __NETWORKMANAGER_DNSMASQ_UTILS_H__ -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" gboolean nm_dnsmasq_utils_get_range(const NMPlatformIP4Address *addr, char * out_first, diff --git a/src/core/main.c b/src/core/main.c index 9b79bcb..bf8f8d4 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -20,7 +20,7 @@ #include "nm-dbus-interface.h" #include "NetworkManagerUtils.h" #include "nm-manager.h" -#include "platform/nm-linux-platform.h" +#include "libnm-platform/nm-linux-platform.h" #include "nm-dbus-manager.h" #include "devices/nm-device.h" #include "dhcp/nm-dhcp-manager.h" @@ -29,7 +29,7 @@ #include "nm-dispatcher.h" #include "settings/nm-settings.h" #include "nm-auth-manager.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-object.h" #include "nm-connectivity.h" #include "dns/nm-dns-manager.h" diff --git a/src/core/meson.build b/src/core/meson.build index 368a3e8..9552f7d 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -1,27 +1,27 @@ # SPDX-License-Identifier: LGPL-2.1-or-later -src_inc = include_directories('.') +src_core_inc = include_directories('.') core_plugin_dep = declare_dependency( - sources: libnm_core_enum_sources[1], include_directories: [ - src_inc, + src_core_inc, top_inc, - shared_inc, - libnm_core_inc, + libnm_core_public_inc, ], dependencies: [ + libnm_core_public_dep, glib_dep, ], ) core_default_dep = declare_dependency( - sources: libnm_core_enum_sources[1], - include_directories: src_inc, + include_directories: [ + src_core_inc, + src_inc, + top_inc, + ], dependencies: [ - libnm_core_nm_default_dep, - libnm_log_core_dep, - libnm_platform_dep, + libnm_core_public_dep, ], ) @@ -34,15 +34,6 @@ subdir('systemd') core_plugins = [] -daemon_c_flags = [ - '-DG_LOG_DOMAIN="NetworkManager"', -] - -platform_wifi_wext_source = files() -if enable_wext - platform_wifi_wext_source += files('platform/wifi/nm-wifi-utils-wext.c') -endif - libNetworkManagerBase = static_library( 'NetworkManagerBase', sources: files( @@ -54,13 +45,6 @@ libNetworkManagerBase = static_library( 'dhcp/nm-dhcp-options.c', 'ndisc/nm-lndp-ndisc.c', 'ndisc/nm-ndisc.c', - 'platform/wifi/nm-wifi-utils-nl80211.c', - 'platform/wifi/nm-wifi-utils.c', - 'platform/wpan/nm-wpan-utils.c', - 'platform/nm-linux-platform.c', - 'platform/nm-platform.c', - 'platform/nmp-object.c', - 'platform/nmp-rules-manager.c', 'main-utils.c', 'NetworkManagerUtils.c', 'nm-core-utils.c', @@ -73,23 +57,19 @@ libNetworkManagerBase = static_library( 'nm-ip-config.c', 'nm-ip4-config.c', 'nm-ip6-config.c', - ) + platform_wifi_wext_source, + ), dependencies: [ core_default_dep, - libn_dhcp4_dep, - libnm_core_dep, - libnm_systemd_shared_dep, - libnm_udev_aux_dep, + libnm_core_public_dep, libsystemd_dep, libudev_dep, ], - c_args: daemon_c_flags, ) nm_deps = [ + libnm_core_public_dep, core_default_dep, dl_dep, - libn_acd_dep, libndp_dep, libudev_dep, logind_dep, @@ -194,7 +174,6 @@ libNetworkManager = static_library( 'nm-sleep-monitor.c', ), dependencies: nm_deps, - c_args: daemon_c_flags, link_with: [ libNetworkManagerBase, libnm_systemd_core, @@ -207,16 +186,28 @@ executable( 'nm-iface-helper.c', dependencies: [ core_default_dep, - dl_dep, - libndp_dep, + glib_dep, libudev_dep, - libn_acd_dep, + libndp_dep, + dl_dep, ], - c_args: daemon_c_flags, link_with: [ libNetworkManagerBase, + libnm_core_aux_intern, + libnm_core_impl, + libnm_crypto, libnm_systemd_core, + libnm_platform, libnm_systemd_shared, + libnm_base, + libnm_udev_aux, + libnm_log_core, + libnm_glib_aux, + libnm_std_aux, + libn_acd, + libn_dhcp4, + libc_rbtree, + libc_siphash, ], link_args: ldflags_linker_script_binary, link_depends: linker_script_binary, @@ -225,7 +216,7 @@ executable( ) if enable_tests - test_c_flags = daemon_c_flags + test_c_flags = [] if require_root_tests test_c_flags += ['-DREQUIRE_ROOT_TESTS=1'] endif @@ -244,7 +235,23 @@ if enable_tests libNetworkManagerTest_dep = declare_dependency( dependencies: core_default_dep, - link_with: libNetworkManagerTest, + link_with: [ + libNetworkManagerTest, + libnm_core_aux_intern, + libnm_core_impl, + libnm_crypto, + libnm_platform, + libnm_base, + libnm_systemd_shared, + libnm_udev_aux, + libnm_log_core, + libnm_glib_aux, + libnm_std_aux, + libn_acd, + libn_dhcp4, + libc_siphash, + libc_rbtree, + ], ) subdir('dnsmasq/tests') @@ -261,7 +268,6 @@ if enable_ppp endif subdir('devices') -subdir('initrd') subdir('settings/plugins') # NetworkManager binary @@ -274,13 +280,27 @@ subdir('settings/plugins') NetworkManager_all_sym = executable( 'NetworkManager-all-sym', 'main.c', - dependencies: nm_deps, - c_args: daemon_c_flags, + dependencies: [ + nm_deps, + libudev_dep, + ], link_args: '-Wl,--no-gc-sections', link_whole: [ libNetworkManager, libNetworkManagerBase, - libnm_core, + libnm_core_aux_intern, + libnm_core_impl, + libnm_crypto, + libnm_platform, + libnm_base, + libnm_log_core, + libnm_udev_aux, + libnm_glib_aux, + libnm_std_aux, + libn_acd, + libn_dhcp4, + libc_rbtree, + libc_siphash, ], ) @@ -301,9 +321,27 @@ ver_script = custom_target( NetworkManager = executable( 'NetworkManager', 'main.c', - dependencies: nm_deps, - c_args: daemon_c_flags, - link_with: libNetworkManager, + dependencies: [ + nm_deps, + libudev_dep, + ], + link_with: [ + libNetworkManager, + libNetworkManagerBase, + libnm_core_aux_intern, + libnm_core_impl, + libnm_crypto, + libnm_platform, + libnm_base, + libnm_udev_aux, + libnm_log_core, + libnm_glib_aux, + libnm_std_aux, + libn_acd, + libn_dhcp4, + libc_rbtree, + libc_siphash, + ], link_args: [ '-rdynamic', '-Wl,--version-script,@0@'.format(ver_script.full_path()), diff --git a/src/core/ndisc/nm-lndp-ndisc.c b/src/core/ndisc/nm-lndp-ndisc.c index f773478..7ba9be3 100644 --- a/src/core/ndisc/nm-lndp-ndisc.c +++ b/src/core/ndisc/nm-lndp-ndisc.c @@ -13,12 +13,12 @@ #include #include -#include "nm-glib-aux/nm-str-buf.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "nm-ndisc-private.h" #include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" -#include "nm-platform/nmp-netns.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-netns.h" #define _NMLOG_PREFIX_NAME "ndisc-lndp" diff --git a/src/core/ndisc/nm-ndisc.c b/src/core/ndisc/nm-ndisc.c index a5c1b93..736fc93 100644 --- a/src/core/ndisc/nm-ndisc.c +++ b/src/core/ndisc/nm-ndisc.c @@ -14,8 +14,8 @@ #include "nm-ndisc-private.h" #include "nm-utils.h" -#include "platform/nm-platform.h" -#include "nm-platform/nmp-netns.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-netns.h" #include "nm-l3-config-data.h" #define _NMLOG_PREFIX_NAME "ndisc" diff --git a/src/core/ndisc/nm-ndisc.h b/src/core/ndisc/nm-ndisc.h index 93aee4d..31f736a 100644 --- a/src/core/ndisc/nm-ndisc.h +++ b/src/core/ndisc/nm-ndisc.h @@ -13,8 +13,8 @@ #include "nm-setting-ip6-config.h" #include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" #define NM_RA_TIMEOUT_DEFAULT ((guint32) 0) #define NM_RA_TIMEOUT_INFINITY ((guint32) G_MAXINT32) diff --git a/src/core/ndisc/tests/test-ndisc-linux.c b/src/core/ndisc/tests/test-ndisc-linux.c index 9a5df60..c84ee14 100644 --- a/src/core/ndisc/tests/test-ndisc-linux.c +++ b/src/core/ndisc/tests/test-ndisc-linux.c @@ -10,7 +10,7 @@ #include "ndisc/nm-ndisc.h" #include "ndisc/nm-lndp-ndisc.h" -#include "platform/nm-linux-platform.h" +#include "libnm-platform/nm-linux-platform.h" #include "nm-test-utils-core.h" diff --git a/src/core/nm-act-request.c b/src/core/nm-act-request.c index defe3e8..cb4b026 100644 --- a/src/core/nm-act-request.c +++ b/src/core/nm-act-request.c @@ -19,7 +19,7 @@ #include "devices/nm-device.h" #include "nm-active-connection.h" #include "settings/nm-settings-connection.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" typedef struct { CList call_ids_lst_head; diff --git a/src/core/nm-active-connection.c b/src/core/nm-active-connection.c index 3c8c472..b0327fd 100644 --- a/src/core/nm-active-connection.c +++ b/src/core/nm-active-connection.c @@ -7,17 +7,17 @@ #include "nm-active-connection.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-dbus-interface.h" #include "devices/nm-device.h" #include "settings/nm-settings-connection.h" #include "nm-simple-connection.h" #include "nm-auth-utils.h" #include "nm-auth-manager.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "nm-keep-alive.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define AUTH_CALL_ID_SHARED_WIFI_PERMISSION_FAILED ((NMAuthManagerCallId *) GINT_TO_POINTER(1)) diff --git a/src/core/nm-audit-manager.c b/src/core/nm-audit-manager.c index 8f41947..a1d20fc 100644 --- a/src/core/nm-audit-manager.c +++ b/src/core/nm-audit-manager.c @@ -11,7 +11,7 @@ #include #endif -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "nm-config.h" #include "nm-dbus-manager.h" #include "settings/nm-settings-connection.h" diff --git a/src/core/nm-auth-manager.c b/src/core/nm-auth-manager.c index 9470838..5c0e465 100644 --- a/src/core/nm-auth-manager.c +++ b/src/core/nm-auth-manager.c @@ -8,9 +8,9 @@ #include "nm-auth-manager.h" #include "c-list/src/c-list.h" -#include "nm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-dbus-aux.h" #include "nm-errors.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" #include "NetworkManagerUtils.h" diff --git a/src/core/nm-auth-manager.h b/src/core/nm-auth-manager.h index 991083c..0586322 100644 --- a/src/core/nm-auth-manager.h +++ b/src/core/nm-auth-manager.h @@ -6,7 +6,7 @@ #ifndef NM_AUTH_MANAGER_H #define NM_AUTH_MANAGER_H -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "nm-config-data.h" /*****************************************************************************/ diff --git a/src/core/nm-auth-utils.c b/src/core/nm-auth-utils.c index 12da574..006264d 100644 --- a/src/core/nm-auth-utils.c +++ b/src/core/nm-auth-utils.c @@ -7,9 +7,9 @@ #include "nm-auth-utils.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-setting-connection.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "nm-auth-manager.h" #include "nm-session-monitor.h" #include "nm-dbus-manager.h" diff --git a/src/core/nm-checkpoint.c b/src/core/nm-checkpoint.c index 2088c24..3e22239 100644 --- a/src/core/nm-checkpoint.c +++ b/src/core/nm-checkpoint.c @@ -9,7 +9,7 @@ #include "nm-active-connection.h" #include "nm-act-request.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "nm-core-utils.h" #include "nm-dbus-interface.h" #include "devices/nm-device.h" diff --git a/src/core/nm-config-data.c b/src/core/nm-config-data.c index c62c677..8594ed5 100644 --- a/src/core/nm-config-data.c +++ b/src/core/nm-config-data.c @@ -10,9 +10,9 @@ #include "nm-config.h" #include "devices/nm-device.h" -#include "nm-core-internal.h" -#include "nm-keyfile-internal.h" -#include "nm-keyfile-utils.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" +#include "libnm-core-intern/nm-keyfile-utils.h" /*****************************************************************************/ @@ -97,6 +97,8 @@ typedef struct { NMGlobalDnsConfig *global_dns; bool systemd_resolved : 1; + + char *iwd_config_path; } NMConfigDataPrivate; struct _NMConfigData { @@ -341,6 +343,12 @@ nm_config_data_get_systemd_resolved(const NMConfigData *self) return NM_CONFIG_DATA_GET_PRIVATE(self)->systemd_resolved; } +const char * +nm_config_data_get_iwd_config_path(const NMConfigData *self) +{ + return NM_CONFIG_DATA_GET_PRIVATE(self)->iwd_config_path; +} + gboolean nm_config_data_get_ignore_carrier(const NMConfigData *self, NMDevice *device) { @@ -576,7 +584,7 @@ _merge_keyfiles(GKeyFile *keyfile_user, GKeyFile *keyfile_intern) const char * key = keys[k]; gs_free char *value = NULL; - if (is_atomic && strcmp(key, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS) == 0) + if (is_atomic && nm_streq(key, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS)) continue; if (!is_intern && !is_atomic @@ -684,6 +692,7 @@ static const struct { NM_CONFIG_KEYFILE_KEY_MAIN_AUTH_POLKIT, NM_CONFIG_DEFAULT_MAIN_AUTH_POLKIT}, {NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_DHCP, NM_CONFIG_DEFAULT_MAIN_DHCP}, + {NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_IWD_CONFIG_PATH, ""}, {NM_CONFIG_KEYFILE_GROUP_LOGGING, "backend", NM_CONFIG_DEFAULT_LOGGING_BACKEND}, {NM_CONFIG_KEYFILE_GROUP_LOGGING, "audit", NM_CONFIG_DEFAULT_LOGGING_AUDIT}, }; @@ -1116,7 +1125,7 @@ load_global_dns(GKeyFile *keyfile, gboolean internal) g_hash_table_insert(dns_config->domains, strdup(name), domain); - if (!strcmp(name, "*")) + if (name[0] == '*' && name[1] == '\0') default_found = TRUE; } @@ -1213,7 +1222,7 @@ global_dns_domain_from_dbus(char *name, GVariant *variant) g_variant_iter_init(&iter, variant); while (g_variant_iter_next(&iter, "{&sv}", &key, &val)) { - if (!g_strcmp0(key, "servers") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { + if (nm_streq0(key, "servers") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { strv = g_variant_dup_strv(val, NULL); _nm_utils_strv_cleanup(strv, TRUE, TRUE, TRUE); for (i = 0, j = 0; strv && strv[i]; i++) { @@ -1230,7 +1239,7 @@ global_dns_domain_from_dbus(char *name, GVariant *variant) g_strfreev(domain->servers); domain->servers = strv; } - } else if (!g_strcmp0(key, "options") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { + } else if (nm_streq0(key, "options") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { strv = g_variant_dup_strv(val, NULL); g_strfreev(domain->options); domain->options = _nm_utils_strv_cleanup(strv, TRUE, TRUE, TRUE); @@ -1278,10 +1287,10 @@ nm_global_dns_config_from_dbus(const GValue *value, GError **error) g_variant_iter_init(&iter, variant); while (g_variant_iter_next(&iter, "{&sv}", &key, &val)) { - if (!g_strcmp0(key, "searches") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { + if (nm_streq0(key, "searches") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { strv = g_variant_dup_strv(val, NULL); dns_config->searches = _nm_utils_strv_cleanup(strv, TRUE, TRUE, TRUE); - } else if (!g_strcmp0(key, "options") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { + } else if (nm_streq0(key, "options") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { strv = g_variant_dup_strv(val, NULL); _nm_utils_strv_cleanup(strv, TRUE, TRUE, TRUE); @@ -1297,7 +1306,7 @@ nm_global_dns_config_from_dbus(const GValue *value, GError **error) strv[j] = NULL; dns_config->options = strv; } - } else if (!g_strcmp0(key, "domains") + } else if (nm_streq0(key, "domains") && g_variant_is_of_type(val, G_VARIANT_TYPE("a{sv}"))) { NMGlobalDnsDomain *domain; GVariantIter domain_iter; @@ -1650,22 +1659,20 @@ nm_config_data_diff(NMConfigData *old_data, NMConfigData *new_data) if (!_nm_keyfile_equals(priv_old->keyfile_intern, priv_new->keyfile_intern, TRUE)) changes |= NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN; - if (g_strcmp0(nm_config_data_get_config_main_file(old_data), - nm_config_data_get_config_main_file(new_data)) - != 0 - || g_strcmp0(nm_config_data_get_config_description(old_data), - nm_config_data_get_config_description(new_data)) - != 0) + if (!nm_streq0(nm_config_data_get_config_main_file(old_data), + nm_config_data_get_config_main_file(new_data)) + || !nm_streq0(nm_config_data_get_config_description(old_data), + nm_config_data_get_config_description(new_data))) changes |= NM_CONFIG_CHANGE_CONFIG_FILES; if (nm_config_data_get_connectivity_enabled(old_data) != nm_config_data_get_connectivity_enabled(new_data) || nm_config_data_get_connectivity_interval(old_data) != nm_config_data_get_connectivity_interval(new_data) - || g_strcmp0(nm_config_data_get_connectivity_uri(old_data), - nm_config_data_get_connectivity_uri(new_data)) - || g_strcmp0(nm_config_data_get_connectivity_response(old_data), - nm_config_data_get_connectivity_response(new_data))) + || !nm_streq0(nm_config_data_get_connectivity_uri(old_data), + nm_config_data_get_connectivity_uri(new_data)) + || !nm_streq0(nm_config_data_get_connectivity_response(old_data), + nm_config_data_get_connectivity_response(new_data))) changes |= NM_CONFIG_CHANGE_CONNECTIVITY; if (nm_utils_g_slist_strlist_cmp(priv_old->no_auto_default.specs, @@ -1676,10 +1683,11 @@ nm_config_data_diff(NMConfigData *old_data, NMConfigData *new_data) != 0) changes |= NM_CONFIG_CHANGE_NO_AUTO_DEFAULT; - if (g_strcmp0(nm_config_data_get_dns_mode(old_data), nm_config_data_get_dns_mode(new_data))) + if (!nm_streq0(nm_config_data_get_dns_mode(old_data), nm_config_data_get_dns_mode(new_data))) changes |= NM_CONFIG_CHANGE_DNS_MODE; - if (g_strcmp0(nm_config_data_get_rc_manager(old_data), nm_config_data_get_rc_manager(new_data))) + if (!nm_streq0(nm_config_data_get_rc_manager(old_data), + nm_config_data_get_rc_manager(new_data))) changes |= NM_CONFIG_CHANGE_RC_MANAGER; if (!global_dns_equal(priv_old->global_dns, priv_new->global_dns)) @@ -1910,6 +1918,12 @@ constructed(GObject *object) if (!priv->global_dns) priv->global_dns = load_global_dns(priv->keyfile_intern, TRUE); + priv->iwd_config_path = + nm_strstrip(g_key_file_get_string(priv->keyfile, + NM_CONFIG_KEYFILE_GROUP_MAIN, + NM_CONFIG_KEYFILE_KEY_MAIN_IWD_CONFIG_PATH, + NULL)); + G_OBJECT_CLASS(nm_config_data_parent_class)->constructed(object); } @@ -1996,6 +2010,8 @@ finalize(GObject *gobject) nm_global_dns_config_free(priv->global_dns); + g_free(priv->iwd_config_path); + _match_section_infos_free(priv->connection_infos); _match_section_infos_free(priv->device_infos); diff --git a/src/core/nm-config-data.h b/src/core/nm-config-data.h index 07cffb4..835edd5 100644 --- a/src/core/nm-config-data.h +++ b/src/core/nm-config-data.h @@ -6,6 +6,8 @@ #ifndef NM_CONFIG_DATA_H #define NM_CONFIG_DATA_H +#include "libnm-platform/nmp-base.h" + /*****************************************************************************/ typedef enum { @@ -188,6 +190,8 @@ int nm_config_data_get_sriov_num_vfs(const NMConfigData *self, NMDevice *de NMGlobalDnsConfig *nm_config_data_get_global_dns_config(const NMConfigData *self); +const char *nm_config_data_get_iwd_config_path(const NMConfigData *self); + extern const char *__start_connection_defaults[]; extern const char *__stop_connection_defaults[]; diff --git a/src/core/nm-config.c b/src/core/nm-config.c index 5532391..033d4c0 100644 --- a/src/core/nm-config.c +++ b/src/core/nm-config.c @@ -13,9 +13,9 @@ #include "nm-utils.h" #include "devices/nm-device.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" -#include "nm-keyfile-internal.h" -#include "nm-keyfile-utils.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" +#include "libnm-core-intern/nm-keyfile-utils.h" #define DEFAULT_CONFIG_MAIN_FILE NMCONFDIR "/NetworkManager.conf" #define DEFAULT_CONFIG_DIR NMCONFDIR "/conf.d" @@ -433,13 +433,7 @@ nm_config_set_no_auto_default_for_device(NMConfig *self, NMDevice *device) len = NM_PTRARRAY_LEN(no_auto_default_current); - idx = nm_utils_ptrarray_find_binary_search((gconstpointer *) no_auto_default_current, - len, - spec, - nm_strcmp_with_data, - NULL, - NULL, - NULL); + idx = nm_utils_strv_find_binary_search(no_auto_default_current, len, spec); if (idx >= 0) { /* @spec is already blocked. We don't have to update our in-memory representation. * Maybe we should write to no_auto_default_file anew, but let's save that too. */ @@ -849,7 +843,8 @@ static const ConfigGroup config_groups[] = { NM_CONFIG_KEYFILE_KEY_MAIN_PLUGINS, NM_CONFIG_KEYFILE_KEY_MAIN_RC_MANAGER, NM_CONFIG_KEYFILE_KEY_MAIN_SLAVES_ORDER, - NM_CONFIG_KEYFILE_KEY_MAIN_SYSTEMD_RESOLVED, ), + NM_CONFIG_KEYFILE_KEY_MAIN_SYSTEMD_RESOLVED, + NM_CONFIG_KEYFILE_KEY_MAIN_IWD_CONFIG_PATH, ), }, { .group = NM_CONFIG_KEYFILE_GROUP_LOGGING, diff --git a/src/core/nm-config.h b/src/core/nm-config.h index 6f3f514..7f1c0c4 100644 --- a/src/core/nm-config.h +++ b/src/core/nm-config.h @@ -9,6 +9,8 @@ #include "nm-config-data.h" +#include "libnm-base/nm-config-base.h" + #define NM_TYPE_CONFIG (nm_config_get_type()) #define NM_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_CONFIG, NMConfig)) #define NM_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_CONFIG, NMConfigClass)) @@ -26,84 +28,6 @@ #define NM_CONFIG_DEFAULT_CONNECTIVITY_INTERVAL 300 #define NM_CONFIG_DEFAULT_CONNECTIVITY_RESPONSE "NetworkManager is online" /* NOT LOCALIZED */ -#define NM_CONFIG_KEYFILE_LIST_SEPARATOR ',' - -#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN ".intern." -#define NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION "connection" -#define NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE "device" -#define NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN "global-dns-domain-" -#define NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST ".test-append-stringlist" - -#define NM_CONFIG_KEYFILE_GROUP_MAIN "main" -#define NM_CONFIG_KEYFILE_GROUP_LOGGING "logging" -#define NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY "connectivity" -#define NM_CONFIG_KEYFILE_GROUP_KEYFILE "keyfile" -#define NM_CONFIG_KEYFILE_GROUP_IFUPDOWN "ifupdown" -#define NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS "global-dns" -#define NM_CONFIG_KEYFILE_GROUP_CONFIG ".config" - -#define NM_CONFIG_KEYFILE_KEY_MAIN_ASSUME_IPV6LL_ONLY "assume-ipv6ll-only" -#define NM_CONFIG_KEYFILE_KEY_MAIN_AUTH_POLKIT "auth-polkit" -#define NM_CONFIG_KEYFILE_KEY_MAIN_AUTOCONNECT_RETRIES_DEFAULT "autoconnect-retries-default" -#define NM_CONFIG_KEYFILE_KEY_MAIN_CONFIGURE_AND_QUIT "configure-and-quit" -#define NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG "debug" -#define NM_CONFIG_KEYFILE_KEY_MAIN_DHCP "dhcp" -#define NM_CONFIG_KEYFILE_KEY_MAIN_DNS "dns" -#define NM_CONFIG_KEYFILE_KEY_MAIN_HOSTNAME_MODE "hostname-mode" -#define NM_CONFIG_KEYFILE_KEY_MAIN_IGNORE_CARRIER "ignore-carrier" -#define NM_CONFIG_KEYFILE_KEY_MAIN_MONITOR_CONNECTION_FILES "monitor-connection-files" -#define NM_CONFIG_KEYFILE_KEY_MAIN_NO_AUTO_DEFAULT "no-auto-default" -#define NM_CONFIG_KEYFILE_KEY_MAIN_PLUGINS "plugins" -#define NM_CONFIG_KEYFILE_KEY_MAIN_RC_MANAGER "rc-manager" -#define NM_CONFIG_KEYFILE_KEY_MAIN_SLAVES_ORDER "slaves-order" -#define NM_CONFIG_KEYFILE_KEY_MAIN_SYSTEMD_RESOLVED "systemd-resolved" - -#define NM_CONFIG_KEYFILE_KEY_LOGGING_AUDIT "audit" -#define NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND "backend" -#define NM_CONFIG_KEYFILE_KEY_LOGGING_DOMAINS "domains" -#define NM_CONFIG_KEYFILE_KEY_LOGGING_LEVEL "level" - -#define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_ENABLED "enabled" -#define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_INTERVAL "interval" -#define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_RESPONSE "response" -#define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_URI "uri" - -#define NM_CONFIG_KEYFILE_KEY_KEYFILE_PATH "path" -#define NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES "unmanaged-devices" -#define NM_CONFIG_KEYFILE_KEY_KEYFILE_HOSTNAME "hostname" - -#define NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED "managed" - -#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_SEARCHES "searches" -#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_OPTIONS "options" - -#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_DOMAIN_SERVERS "servers" -#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_DOMAIN_OPTIONS "options" - -#define NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED "managed" -#define NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER "ignore-carrier" -#define NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS "sriov-num-vfs" -#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_BACKEND "wifi.backend" -#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_RAND_MAC_ADDRESS "wifi.scan-rand-mac-address" -#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_GENERATE_MAC_ADDRESS_MASK \ - "wifi.scan-generate-mac-address-mask" -#define NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT "carrier-wait-timeout" -#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_IWD_AUTOCONNECT "wifi.iwd.autoconnect" - -#define NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE "match-device" -#define NM_CONFIG_KEYFILE_KEY_STOP_MATCH "stop-match" - -#define NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS ".was" /* check-config-options skip */ -#define NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE "enable" /* check-config-options skip */ - -#define NM_CONFIG_KEYFILE_KEYPREFIX_WAS ".was." -#define NM_CONFIG_KEYFILE_KEYPREFIX_SET ".set." - -#define NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS \ - NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS -#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN \ - NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN - typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions; typedef enum { diff --git a/src/core/nm-connectivity.c b/src/core/nm-connectivity.c index f847c8f..1d37bd5 100644 --- a/src/core/nm-connectivity.c +++ b/src/core/nm-connectivity.c @@ -16,7 +16,7 @@ #include #include "c-list/src/c-list.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-config.h" #include "NetworkManagerUtils.h" #include "nm-dbus-manager.h" diff --git a/src/core/nm-connectivity.h b/src/core/nm-connectivity.h index c67668c..0985df9 100644 --- a/src/core/nm-connectivity.h +++ b/src/core/nm-connectivity.h @@ -8,6 +8,7 @@ #define __NETWORKMANAGER_CONNECTIVITY_H__ #include "nm-dbus-interface.h" +#include "libnm-platform/nmp-base.h" /*****************************************************************************/ diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index 9075c30..6a327fa 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -22,13 +22,14 @@ #include #include -#include "nm-std-aux/unaligned.h" -#include "nm-glib-aux/nm-random-utils.h" -#include "nm-glib-aux/nm-io-utils.h" -#include "nm-glib-aux/nm-secret-utils.h" -#include "nm-glib-aux/nm-time-utils.h" +#include "libnm-platform/nmp-base.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-random-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-glib-aux/nm-time-utils.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-setting-connection.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" @@ -156,37 +157,6 @@ _nm_singleton_instance_register_destruction(GObject *instance) /*****************************************************************************/ -static double -_exp10(guint16 ex) -{ - double v; - - if (ex == 0) - return 1.0; - - v = _exp10(ex / 2); - v = v * v; - if (ex % 2) - v *= 10; - return v; -} - -/* - * nm_utils_exp10: - * @ex: the exponent - * - * Returns: 10^ex, or pow(10, ex), or exp10(ex). - */ -double -nm_utils_exp10(gint16 ex) -{ - if (ex >= 0) - return _exp10(ex); - return 1.0 / _exp10(-((gint32) ex)); -} - -/*****************************************************************************/ - gboolean nm_ether_addr_is_valid(const NMEtherAddr *addr) { @@ -304,85 +274,6 @@ nm_utils_array_remove_at_indexes(GArray *array, const guint *indexes_to_delete, g_array_set_size(array, res_length); } -static const char * -_trunk_first_line(char *str) -{ - char *s; - - s = strchr(str, '\n'); - if (s) - s[0] = '\0'; - return str; -} - -int -nm_utils_modprobe(GError **error, gboolean suppress_error_logging, const char *arg1, ...) -{ - gs_unref_ptrarray GPtrArray *argv = NULL; - int exit_status; - gs_free char * _log_str = NULL; -#define ARGV_TO_STR(argv) \ - (_log_str ? _log_str : (_log_str = g_strjoinv(" ", (char **) argv->pdata))) - GError * local = NULL; - va_list ap; - NMLogLevel llevel = suppress_error_logging ? LOGL_DEBUG : LOGL_ERR; - gs_free char *std_out = NULL, *std_err = NULL; - - g_return_val_if_fail(!error || !*error, -1); - g_return_val_if_fail(arg1, -1); - - /* construct the argument list */ - argv = g_ptr_array_sized_new(4); - g_ptr_array_add(argv, "/sbin/modprobe"); - g_ptr_array_add(argv, "--use-blacklist"); - g_ptr_array_add(argv, (char *) arg1); - - va_start(ap, arg1); - while ((arg1 = va_arg(ap, const char *))) - g_ptr_array_add(argv, (char *) arg1); - va_end(ap); - - g_ptr_array_add(argv, NULL); - - nm_log_dbg(LOGD_CORE, "modprobe: '%s'", ARGV_TO_STR(argv)); - if (!g_spawn_sync(NULL, - (char **) argv->pdata, - NULL, - 0, - NULL, - NULL, - &std_out, - &std_err, - &exit_status, - &local)) { - nm_log(llevel, - LOGD_CORE, - NULL, - NULL, - "modprobe: '%s' failed: %s", - ARGV_TO_STR(argv), - local->message); - g_propagate_error(error, local); - return -1; - } else if (exit_status != 0) { - nm_log(llevel, - LOGD_CORE, - NULL, - NULL, - "modprobe: '%s' exited with error %d%s%s%s%s%s%s", - ARGV_TO_STR(argv), - exit_status, - std_out && *std_out ? " (" : "", - std_out && *std_out ? _trunk_first_line(std_out) : "", - std_out && *std_out ? ")" : "", - std_err && *std_err ? " (" : "", - std_err && *std_err ? _trunk_first_line(std_err) : "", - std_err && *std_err ? ")" : ""); - } - - return exit_status; -} - /*****************************************************************************/ typedef struct { @@ -1269,7 +1160,7 @@ typedef struct { const char *value; gboolean is_parsed; guint len; - guint8 bin[NM_UTILS_HWADDR_LEN_MAX]; + guint8 bin[_NM_UTILS_HWADDR_LEN_MAX]; } hwaddr; struct { const char *value; @@ -2051,65 +1942,6 @@ nm_utils_kernel_cmdline_match_check(const char *const *proc_cmdline, /*****************************************************************************/ -char * -nm_utils_new_vlan_name(const char *parent_iface, guint32 vlan_id) -{ - guint id_len; - gsize parent_len; - char *ifname; - - g_return_val_if_fail(parent_iface && *parent_iface, NULL); - - if (vlan_id < 10) - id_len = 2; - else if (vlan_id < 100) - id_len = 3; - else if (vlan_id < 1000) - id_len = 4; - else { - g_return_val_if_fail(vlan_id < 4095, NULL); - id_len = 5; - } - - ifname = g_new(char, IFNAMSIZ); - - parent_len = strlen(parent_iface); - parent_len = MIN(parent_len, IFNAMSIZ - 1 - id_len); - memcpy(ifname, parent_iface, parent_len); - g_snprintf(&ifname[parent_len], IFNAMSIZ - parent_len, ".%u", vlan_id); - - return ifname; -} - -/* nm_utils_new_infiniband_name: - * @name: the output-buffer where the value will be written. Must be - * not %NULL and point to a string buffer of at least IFNAMSIZ bytes. - * @parent_name: the parent interface name - * @p_key: the partition key. - * - * Returns: the infiniband name will be written to @name and @name - * is returned. - */ -const char * -nm_utils_new_infiniband_name(char *name, const char *parent_name, int p_key) -{ - g_return_val_if_fail(name, NULL); - g_return_val_if_fail(parent_name && parent_name[0], NULL); - g_return_val_if_fail(strlen(parent_name) < IFNAMSIZ, NULL); - - /* technically, p_key of 0x0000 and 0x8000 is not allowed either. But we don't - * want to assert against that in nm_utils_new_infiniband_name(). So be more - * resilient here, and accept those. */ - g_return_val_if_fail(p_key >= 0 && p_key <= 0xffff, NULL); - - /* If parent+suffix is too long, kernel would just truncate - * the name. We do the same. See ipoib_vlan_add(). */ - g_snprintf(name, IFNAMSIZ, "%s.%04x", parent_name, p_key); - return name; -} - -/*****************************************************************************/ - /** * nm_utils_cmp_connection_by_autoconnect_priority: * @a: @@ -2538,134 +2370,6 @@ out: g_array_free(sorted_hashes, TRUE); } -#define IPV6_PROPERTY_DIR "/proc/sys/net/ipv6/conf/" -#define IPV4_PROPERTY_DIR "/proc/sys/net/ipv4/conf/" -G_STATIC_ASSERT(sizeof(IPV4_PROPERTY_DIR) == sizeof(IPV6_PROPERTY_DIR)); -G_STATIC_ASSERT(NM_STRLEN(IPV6_PROPERTY_DIR) + IFNAMSIZ + 60 - == NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE); - -/** - * nm_utils_sysctl_ip_conf_path: - * @addr_family: either AF_INET or AF_INET6. - * @buf: the output buffer where to write the path. It - * must be at least NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE bytes - * long. - * @ifname: an interface name - * @property: a property name - * - * Returns: the path to IPv6 property @property on @ifname. Note that - * this returns the input argument @buf. - */ -const char * -nm_utils_sysctl_ip_conf_path(int addr_family, char *buf, const char *ifname, const char *property) -{ - int len; - - nm_assert(buf); - nm_assert_addr_family(addr_family); - - g_assert(nm_utils_ifname_valid_kernel(ifname, NULL)); - property = NM_ASSERT_VALID_PATH_COMPONENT(property); - - len = g_snprintf(buf, - NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE, - "%s%s/%s", - addr_family == AF_INET6 ? IPV6_PROPERTY_DIR : IPV4_PROPERTY_DIR, - ifname, - property); - g_assert(len < NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE - 1); - return buf; -} - -gboolean -nm_utils_sysctl_ip_conf_is_path(int addr_family, - const char *path, - const char *ifname, - const char *property) -{ - g_return_val_if_fail(path, FALSE); - NM_ASSERT_VALID_PATH_COMPONENT(property); - g_assert(!ifname || nm_utils_ifname_valid_kernel(ifname, NULL)); - - if (addr_family == AF_INET) { - if (!g_str_has_prefix(path, IPV4_PROPERTY_DIR)) - return FALSE; - path += NM_STRLEN(IPV4_PROPERTY_DIR); - } else if (addr_family == AF_INET6) { - if (!g_str_has_prefix(path, IPV6_PROPERTY_DIR)) - return FALSE; - path += NM_STRLEN(IPV6_PROPERTY_DIR); - } else - g_return_val_if_reached(FALSE); - - if (ifname) { - if (!g_str_has_prefix(path, ifname)) - return FALSE; - path += strlen(ifname); - if (path[0] != '/') - return FALSE; - path++; - } else { - const char *slash; - char buf[IFNAMSIZ]; - gsize l; - - slash = strchr(path, '/'); - if (!slash) - return FALSE; - l = slash - path; - if (l >= IFNAMSIZ) - return FALSE; - memcpy(buf, path, l); - buf[l] = '\0'; - if (!nm_utils_ifname_valid_kernel(buf, NULL)) - return FALSE; - path = slash + 1; - } - - if (!nm_streq(path, property)) - return FALSE; - - return TRUE; -} - -gboolean -nm_utils_is_valid_path_component(const char *name) -{ - const char *n; - - if (name == NULL || name[0] == '\0') - return FALSE; - - if (name[0] == '.') { - if (name[1] == '\0') - return FALSE; - if (name[1] == '.' && name[2] == '\0') - return FALSE; - } - n = name; - do { - if (*n == '/') - return FALSE; - } while (*(++n) != '\0'); - - return TRUE; -} - -const char * -NM_ASSERT_VALID_PATH_COMPONENT(const char *name) -{ - if (G_LIKELY(nm_utils_is_valid_path_component(name))) - return name; - - nm_log_err(LOGD_CORE, - "Failed asserting path component: %s%s%s", - NM_PRINT_FMT_QUOTED(name, "\"", name, "\"", "(null)")); - g_error("FATAL: Failed asserting path component: %s%s%s", - NM_PRINT_FMT_QUOTED(name, "\"", name, "\"", "(null)")); - g_assert_not_reached(); -} - /*****************************************************************************/ typedef struct { @@ -3407,89 +3111,6 @@ nm_utils_get_ipv6_interface_identifier(NMLinkType link_type, /*****************************************************************************/ -/** - * nm_utils_ipv6_addr_set_interface_identifier: - * @addr: output token encoded as %in6_addr - * @iid: %NMUtilsIPv6IfaceId interface identifier - * - * Converts the %NMUtilsIPv6IfaceId to an %in6_addr (suitable for use - * with Linux platform). This only copies the lower 8 bytes, ignoring - * the /64 network prefix which is expected to be all-zero for a valid - * token. - */ -void -nm_utils_ipv6_addr_set_interface_identifier(struct in6_addr *addr, const NMUtilsIPv6IfaceId iid) -{ - memcpy(addr->s6_addr + 8, &iid.id_u8, 8); -} - -/** - * nm_utils_ipv6_interface_identifier_get_from_addr: - * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token - * @addr: token encoded as %in6_addr - * - * Converts the %in6_addr encoded token (as used by Linux platform) to - * the interface identifier. - */ -void -nm_utils_ipv6_interface_identifier_get_from_addr(NMUtilsIPv6IfaceId * iid, - const struct in6_addr *addr) -{ - memcpy(iid, addr->s6_addr + 8, 8); -} - -/** - * nm_utils_ipv6_interface_identifier_get_from_token: - * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token - * @token: token encoded as string - * - * Converts the %in6_addr encoded token (as used in ip6 settings) to - * the interface identifier. - * - * Returns: %TRUE if the @token is a valid token, %FALSE otherwise - */ -gboolean -nm_utils_ipv6_interface_identifier_get_from_token(NMUtilsIPv6IfaceId *iid, const char *token) -{ - struct in6_addr i6_token; - - g_return_val_if_fail(token, FALSE); - - if (!inet_pton(AF_INET6, token, &i6_token)) - return FALSE; - - if (!_nm_utils_inet6_is_token(&i6_token)) - return FALSE; - - nm_utils_ipv6_interface_identifier_get_from_addr(iid, &i6_token); - return TRUE; -} - -/** - * nm_utils_inet6_interface_identifier_to_token: - * @iid: %NMUtilsIPv6IfaceId interface identifier - * @buf: the destination buffer of at least %NM_UTILS_INET_ADDRSTRLEN - * bytes. - * - * Converts the interface identifier to a string token. - * - * Returns: the input buffer filled with the id as string. - */ -const char * -nm_utils_inet6_interface_identifier_to_token(NMUtilsIPv6IfaceId iid, - char buf[static INET6_ADDRSTRLEN]) -{ - struct in6_addr i6_token = {.s6_addr = { - 0, - }}; - - nm_assert(buf); - nm_utils_ipv6_addr_set_interface_identifier(&i6_token, iid); - return _nm_utils_inet6_ntop(&i6_token, buf); -} - -/*****************************************************************************/ - char * nm_utils_stable_id_random(void) { @@ -4269,89 +3890,6 @@ nm_utils_g_value_set_strv(GValue *value, GPtrArray *strings) /*****************************************************************************/ -/** - * Takes a pair @timestamp and @duration, and returns the remaining duration based - * on the new timestamp @now. - */ -guint32 -nm_utils_lifetime_rebase_relative_time_on_now(guint32 timestamp, guint32 duration, gint32 now) -{ - gint64 t; - - nm_assert(now >= 0); - - if (duration == NM_PLATFORM_LIFETIME_PERMANENT) - return NM_PLATFORM_LIFETIME_PERMANENT; - - if (timestamp == 0) { - /* if the @timestamp is zero, assume it was just left unset and that the relative - * @duration starts counting from @now. This is convenient to construct an address - * and print it in nm_platform_ip4_address_to_string(). - * - * In general it does not make sense to set the @duration without anchoring at - * @timestamp because you don't know the absolute expiration time when looking - * at the address at a later moment. */ - timestamp = now; - } - - /* For timestamp > now, just accept it and calculate the expected(?) result. */ - t = (gint64) timestamp + (gint64) duration - (gint64) now; - - if (t <= 0) - return 0; - if (t >= NM_PLATFORM_LIFETIME_PERMANENT) - return NM_PLATFORM_LIFETIME_PERMANENT - 1; - return t; -} - -guint32 -nm_utils_lifetime_get(guint32 timestamp, - guint32 lifetime, - guint32 preferred, - gint32 now, - guint32 *out_preferred) -{ - guint32 t_lifetime, t_preferred; - - nm_assert(now >= 0); - - if (timestamp == 0 && lifetime == 0) { - /* We treat lifetime==0 && timestamp==0 addresses as permanent addresses to allow easy - * creation of such addresses (without requiring to set the lifetime fields to - * NM_PLATFORM_LIFETIME_PERMANENT). The real lifetime==0 addresses (E.g. DHCP6 telling us - * to drop an address will have timestamp set. - */ - NM_SET_OUT(out_preferred, NM_PLATFORM_LIFETIME_PERMANENT); - g_return_val_if_fail(preferred == 0, NM_PLATFORM_LIFETIME_PERMANENT); - return NM_PLATFORM_LIFETIME_PERMANENT; - } - - if (now <= 0) - now = nm_utils_get_monotonic_timestamp_sec(); - - t_lifetime = nm_utils_lifetime_rebase_relative_time_on_now(timestamp, lifetime, now); - if (!t_lifetime) { - NM_SET_OUT(out_preferred, 0); - return 0; - } - - t_preferred = nm_utils_lifetime_rebase_relative_time_on_now(timestamp, preferred, now); - - NM_SET_OUT(out_preferred, MIN(t_preferred, t_lifetime)); - - /* Assert that non-permanent addresses have a (positive) @timestamp. nm_utils_lifetime_rebase_relative_time_on_now() - * treats addresses with timestamp 0 as *now*. Addresses passed to _address_get_lifetime() always - * should have a valid @timestamp, otherwise on every re-sync, their lifetime will be extended anew. - */ - g_return_val_if_fail(timestamp != 0 - || (lifetime == NM_PLATFORM_LIFETIME_PERMANENT - && preferred == NM_PLATFORM_LIFETIME_PERMANENT), - t_lifetime); - g_return_val_if_fail(t_preferred <= t_lifetime, t_lifetime); - - return t_lifetime; -} - const char * nm_utils_dnsmasq_status_to_string(int status, char *dest, gsize size) { @@ -5102,13 +4640,6 @@ nm_wifi_utils_level_to_quality(int val) /*****************************************************************************/ -NM_UTILS_ENUM2STR_DEFINE(nm_icmpv6_router_pref_to_string, - NMIcmpv6RouterPref, - NM_UTILS_ENUM2STR(NM_ICMPV6_ROUTER_PREF_LOW, "low"), - NM_UTILS_ENUM2STR(NM_ICMPV6_ROUTER_PREF_MEDIUM, "medium"), - NM_UTILS_ENUM2STR(NM_ICMPV6_ROUTER_PREF_HIGH, "high"), - NM_UTILS_ENUM2STR(NM_ICMPV6_ROUTER_PREF_INVALID, "invalid"), ); - NM_UTILS_LOOKUP_STR_DEFINE(nm_activation_type_to_string, NMActivationType, NM_UTILS_LOOKUP_DEFAULT_WARN("(unknown)"), diff --git a/src/core/nm-core-utils.h b/src/core/nm-core-utils.h index 5dc4d43..7fd96d3 100644 --- a/src/core/nm-core-utils.h +++ b/src/core/nm-core-utils.h @@ -12,12 +12,10 @@ #include "nm-connection.h" -#include "nm-glib-aux/nm-time-utils.h" +#include "libnm-glib-aux/nm-time-utils.h" /*****************************************************************************/ -#define NM_PLATFORM_LIFETIME_PERMANENT G_MAXUINT32 - #define NM_DEFINE_SINGLETON_INSTANCE(TYPE) static TYPE *singleton_instance #define NM_DEFINE_SINGLETON_REGISTER(TYPE) \ @@ -98,73 +96,6 @@ void _nm_singleton_instance_register_destruction(GObject *instance); gboolean nm_ether_addr_is_valid(const NMEtherAddr *addr); gboolean nm_ether_addr_is_valid_str(const char *str); -gconstpointer -nm_utils_ipx_address_clear_host_address(int family, gpointer dst, gconstpointer src, guint8 plen); -in_addr_t nm_utils_ip4_address_clear_host_address(in_addr_t addr, guint8 plen); -const struct in6_addr *nm_utils_ip6_address_clear_host_address(struct in6_addr * dst, - const struct in6_addr *src, - guint8 plen); - -static inline int -nm_utils_ip4_address_same_prefix_cmp(in_addr_t addr_a, in_addr_t addr_b, guint8 plen) -{ - NM_CMP_DIRECT(htonl(nm_utils_ip4_address_clear_host_address(addr_a, plen)), - htonl(nm_utils_ip4_address_clear_host_address(addr_b, plen))); - return 0; -} - -int nm_utils_ip6_address_same_prefix_cmp(const struct in6_addr *addr_a, - const struct in6_addr *addr_b, - guint8 plen); - -static inline int -nm_utils_ip_address_same_prefix_cmp(int addr_family, - gconstpointer addr_a, - gconstpointer addr_b, - guint8 plen) -{ - nm_assert_addr_family(addr_family); - - NM_CMP_SELF(addr_a, addr_b); - - if (NM_IS_IPv4(addr_family)) { - return nm_utils_ip4_address_same_prefix_cmp(*((const in_addr_t *) addr_a), - *((const in_addr_t *) addr_b), - plen); - } - - return nm_utils_ip6_address_same_prefix_cmp(addr_a, addr_b, plen); -} - -static inline gboolean -nm_utils_ip4_address_same_prefix(in_addr_t addr_a, in_addr_t addr_b, guint8 plen) -{ - return nm_utils_ip4_address_same_prefix_cmp(addr_a, addr_b, plen) == 0; -} - -static inline gboolean -nm_utils_ip6_address_same_prefix(const struct in6_addr *addr_a, - const struct in6_addr *addr_b, - guint8 plen) -{ - return nm_utils_ip6_address_same_prefix_cmp(addr_a, addr_b, plen) == 0; -} - -static inline gboolean -nm_utils_ip_address_same_prefix(int addr_family, - gconstpointer addr_a, - gconstpointer addr_b, - guint8 plen) -{ - return nm_utils_ip_address_same_prefix_cmp(addr_family, addr_a, addr_b, plen) == 0; -} - -#define NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(a, b, plen) \ - NM_CMP_RETURN(nm_utils_ip4_address_same_prefix_cmp((a), (b), (plen))) - -#define NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(a, b, plen) \ - NM_CMP_RETURN(nm_utils_ip6_address_same_prefix_cmp((a), (b), (plen))) - static inline void nm_hash_update_in6addr(NMHashState *h, const struct in6_addr *addr) { @@ -185,8 +116,6 @@ nm_hash_update_in6addr_prefix(NMHashState *h, const struct in6_addr *addr, guint nm_hash_update_in6addr(h, &a); } -double nm_utils_exp10(gint16 e); - /** * nm_utils_ip6_route_metric_normalize: * @metric: the route metric @@ -221,9 +150,6 @@ nm_utils_ip_route_metric_penalize(guint32 metric, guint32 penalty) return G_MAXUINT32; } -int nm_utils_modprobe(GError **error, gboolean suppress_error_loggin, const char *arg1, ...) - G_GNUC_NULL_TERMINATED; - void nm_utils_kill_process_sync(pid_t pid, guint64 start_time, int sig, @@ -291,9 +217,6 @@ gboolean nm_utils_connection_has_default_route(NMConnection *connection, int addr_family, gboolean * out_is_never_default); -char * nm_utils_new_vlan_name(const char *parent_iface, guint32 vlan_id); -const char *nm_utils_new_infiniband_name(char *name, const char *parent_name, int p_key); - int nm_utils_cmp_connection_by_autoconnect_priority(NMConnection *a, NMConnection *b); void nm_utils_log_connection_diff(NMConnection *connection, @@ -304,19 +227,6 @@ void nm_utils_log_connection_diff(NMConnection *connection, const char * prefix, const char * dbus_path); -gboolean nm_utils_is_valid_path_component(const char *name); -const char *NM_ASSERT_VALID_PATH_COMPONENT(const char *name); - -#define NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE 100 - -const char * -nm_utils_sysctl_ip_conf_path(int addr_family, char *buf, const char *ifname, const char *property); - -gboolean nm_utils_sysctl_ip_conf_is_path(int addr_family, - const char *path, - const char *ifname, - const char *property); - gboolean nm_utils_is_specific_hostname(const char *name); struct _NMUuid; @@ -344,49 +254,6 @@ nm_utils_arp_type_get_hwaddr_relevant_part(int arp_type, const guint8 **hwaddr, /*****************************************************************************/ -/* IPv6 Interface Identifier helpers */ - -/** - * NMUtilsIPv6IfaceId: - * @id: convenience member for validity checking; never use directly - * @id_u8: the 64-bit Interface Identifier - * - * Holds a 64-bit IPv6 Interface Identifier. The IID is a sequence of bytes - * and should not normally be treated as a %guint64, but this is done for - * convenience of validity checking and initialization. - */ -struct _NMUtilsIPv6IfaceId { - union { - guint64 id; - guint8 id_u8[8]; - }; -}; - -#define NM_UTILS_IPV6_IFACE_ID_INIT \ - { \ - { \ - .id = 0 \ - } \ - } - -void nm_utils_ipv6_addr_set_interface_identifier(struct in6_addr * addr, - const NMUtilsIPv6IfaceId iid); - -void nm_utils_ipv6_interface_identifier_get_from_addr(NMUtilsIPv6IfaceId * iid, - const struct in6_addr *addr); - -gboolean nm_utils_ipv6_interface_identifier_get_from_token(NMUtilsIPv6IfaceId *iid, - const char * token); - -const char *nm_utils_inet6_interface_identifier_to_token(NMUtilsIPv6IfaceId iid, - char buf[static INET6_ADDRSTRLEN]); - -gboolean nm_utils_get_ipv6_interface_identifier(NMLinkType link_type, - const guint8 * hwaddr, - guint len, - guint dev_id, - NMUtilsIPv6IfaceId *out_iid); - typedef enum { /* The stable type. Note that this value is encoded in the * generated addresses, thus the numbers MUST not change. @@ -501,33 +368,6 @@ void _nm_utils_set_testing(NMUtilsTestFlags flags); void nm_utils_g_value_set_strv(GValue *value, GPtrArray *strings); -guint32 -nm_utils_lifetime_rebase_relative_time_on_now(guint32 timestamp, guint32 duration, gint32 now); - -guint32 nm_utils_lifetime_get(guint32 timestamp, - guint32 lifetime, - guint32 preferred, - gint32 now, - guint32 *out_preferred); - -/*****************************************************************************/ - -#define NM_IPV4LL_NETWORK ((in_addr_t)(htonl(0xA9FE0000lu))) -#define NM_IPV4LL_NETMASK ((in_addr_t)(htonl(0xFFFF0000lu))) - -static inline gboolean -nm_utils_ip4_address_is_link_local(in_addr_t addr) -{ - return (addr & NM_IPV4LL_NETMASK) == NM_IPV4LL_NETWORK; -} - -static inline gboolean -nm_utils_ip4_address_is_zeronet(in_addr_t network) -{ - /* Same as ipv4_is_zeronet() from kernel's include/linux/in.h. */ - return (network & htonl(0xFF000000u)) == htonl(0x00000000u); -} - /*****************************************************************************/ const char *nm_utils_dnsmasq_status_to_string(int status, char *dest, gsize size); @@ -556,20 +396,6 @@ char * nm_utils_format_con_diff_for_audit(GHashTable *diff); /*****************************************************************************/ -/* this enum is compatible with ICMPV6_ROUTER_PREF_* (from , - * the values for netlink attribute RTA_PREF) and "enum ndp_route_preference" - * from . */ -typedef enum _nm_packed { - NM_ICMPV6_ROUTER_PREF_MEDIUM = 0x0, /* ICMPV6_ROUTER_PREF_MEDIUM */ - NM_ICMPV6_ROUTER_PREF_LOW = 0x3, /* ICMPV6_ROUTER_PREF_LOW */ - NM_ICMPV6_ROUTER_PREF_HIGH = 0x1, /* ICMPV6_ROUTER_PREF_HIGH */ - NM_ICMPV6_ROUTER_PREF_INVALID = 0x2, /* ICMPV6_ROUTER_PREF_INVALID */ -} NMIcmpv6RouterPref; - -const char *nm_icmpv6_router_pref_to_string(NMIcmpv6RouterPref pref, char *buf, gsize len); - -/*****************************************************************************/ - const char *nm_activation_type_to_string(NMActivationType activation_type); /*****************************************************************************/ diff --git a/src/core/nm-dbus-manager.c b/src/core/nm-dbus-manager.c index 4f34ee5..7c1e4ea 100644 --- a/src/core/nm-dbus-manager.c +++ b/src/core/nm-dbus-manager.c @@ -13,13 +13,13 @@ #include #include "c-list/src/c-list.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-dbus-interface.h" -#include "nm-core-internal.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-dbus-object.h" #include "NetworkManagerUtils.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" /* The base path for our GDBusObjectManagerServers. They do not contain * "NetworkManager" because GDBusObjectManagerServer requires that all diff --git a/src/core/nm-dcb.c b/src/core/nm-dcb.c index b3958ca..930a102 100644 --- a/src/core/nm-dcb.c +++ b/src/core/nm-dcb.c @@ -8,7 +8,7 @@ #include #include "nm-dcb.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "NetworkManagerUtils.h" static const char *helper_names[] = {"dcbtool", "fcoeadm"}; diff --git a/src/core/nm-default-daemon.h b/src/core/nm-default-daemon.h index 65ca4b5..57d4c6a 100644 --- a/src/core/nm-default-daemon.h +++ b/src/core/nm-default-daemon.h @@ -8,7 +8,7 @@ /*****************************************************************************/ -#include "nm-glib-aux/nm-default-glib-i18n-prog.h" +#include "libnm-glib-aux/nm-default-glib-i18n-prog.h" #undef NETWORKMANAGER_COMPILATION #define NETWORKMANAGER_COMPILATION NM_NETWORKMANAGER_COMPILATION_DAEMON @@ -19,7 +19,7 @@ #include "nm-core-types.h" #include "nm-types.h" -#include "nm-log-core/nm-logging.h" +#include "libnm-log-core/nm-logging.h" /*****************************************************************************/ diff --git a/src/core/nm-dispatcher.c b/src/core/nm-dispatcher.c index 0ab409f..4fdb905 100644 --- a/src/core/nm-dispatcher.c +++ b/src/core/nm-dispatcher.c @@ -8,7 +8,7 @@ #include "nm-dispatcher.h" -#include "nm-libnm-core-aux/nm-dispatcher-api.h" +#include "libnm-core-aux-extern/nm-dispatcher-api.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" #include "nm-connectivity.h" @@ -20,8 +20,8 @@ #include "nm-ip6-config.h" #include "nm-manager.h" #include "settings/nm-settings-connection.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" #define CALL_TIMEOUT (1000 * 60 * 10) /* 10 minutes for all scripts */ diff --git a/src/core/nm-firewall-manager.c b/src/core/nm-firewall-manager.c index 8f476e5..8094261 100644 --- a/src/core/nm-firewall-manager.c +++ b/src/core/nm-firewall-manager.c @@ -7,7 +7,7 @@ #include "nm-firewall-manager.h" -#include "nm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-dbus-aux.h" #include "c-list/src/c-list.h" #include "NetworkManagerUtils.h" diff --git a/src/core/nm-hostname-manager.c b/src/core/nm-hostname-manager.c index c99c832..4f16242 100644 --- a/src/core/nm-hostname-manager.c +++ b/src/core/nm-hostname-manager.c @@ -14,11 +14,11 @@ #include #endif -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-dbus-interface.h" #include "nm-connection.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" diff --git a/src/core/nm-iface-helper.c b/src/core/nm-iface-helper.c index b6e9981..c4d87b9 100644 --- a/src/core/nm-iface-helper.c +++ b/src/core/nm-iface-helper.c @@ -16,17 +16,17 @@ #include #include -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-c-list.h" #include "main-utils.h" #include "NetworkManagerUtils.h" -#include "platform/nm-linux-platform.h" -#include "nm-platform/nm-platform-utils.h" +#include "libnm-platform/nm-linux-platform.h" +#include "libnm-platform/nm-platform-utils.h" #include "dhcp/nm-dhcp-manager.h" #include "ndisc/nm-ndisc.h" #include "ndisc/nm-lndp-ndisc.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-setting-ip6-config.h" #include "systemd/nm-sd.h" diff --git a/src/core/nm-ip4-config.c b/src/core/nm-ip4-config.c index c49dfb4..9f82388 100644 --- a/src/core/nm-ip4-config.c +++ b/src/core/nm-ip4-config.c @@ -12,14 +12,14 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-dedup-multi.h" #include "nm-utils.h" -#include "platform/nmp-object.h" -#include "platform/nm-platform.h" -#include "nm-platform/nm-platform-utils.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-platform-utils.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-object.h" /*****************************************************************************/ @@ -649,21 +649,6 @@ nm_ip4_config_add_dependent_routes(NMIP4Config *self, if (my_addr->external) continue; - /* Pre-generate local route added by kernel */ - r = nmp_object_new(NMP_OBJECT_TYPE_IP4_ROUTE, NULL); - route = NMP_OBJECT_CAST_IP4_ROUTE(r); - route->ifindex = ifindex; - route->rt_source = NM_IP_CONFIG_SOURCE_KERNEL; - route->network = my_addr->address; - route->plen = 32; - route->pref_src = my_addr->address; - route->type_coerced = nm_platform_route_type_coerce(RTN_LOCAL); - route->scope_inv = nm_platform_route_scope_inv(RT_SCOPE_HOST); - route->table_coerced = - nm_platform_route_table_coerce(is_vrf ? route_table : RT_TABLE_LOCAL); - _add_route(self, r, NULL, NULL); - nm_clear_pointer(&r, nmp_object_unref); - if (nm_utils_ip4_address_is_zeronet(network)) { /* Kernel doesn't add device-routes for destinations that * start with 0.x.y.z. Skip them. */ diff --git a/src/core/nm-ip4-config.h b/src/core/nm-ip4-config.h index a795e15..7032a23 100644 --- a/src/core/nm-ip4-config.h +++ b/src/core/nm-ip4-config.h @@ -10,8 +10,8 @@ #include "nm-setting-ip4-config.h" -#include "nm-glib-aux/nm-dedup-multi.h" -#include "platform/nmp-object.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-platform/nmp-object.h" #include "nm-ip-config.h" /*****************************************************************************/ diff --git a/src/core/nm-ip6-config.c b/src/core/nm-ip6-config.c index 1f7def3..155594c 100644 --- a/src/core/nm-ip6-config.c +++ b/src/core/nm-ip6-config.c @@ -13,13 +13,13 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-dedup-multi.h" #include "nm-utils.h" -#include "platform/nmp-object.h" -#include "platform/nm-platform.h" -#include "nm-platform/nm-platform-utils.h" -#include "nm-core-internal.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" #include "nm-ip4-config.h" #include "ndisc/nm-ndisc.h" @@ -396,23 +396,6 @@ nm_ip6_config_add_dependent_routes(NMIP6Config *self, * * For manually added IPv6 routes, add the device routes explicitly. */ - /* Pre-generate multicast route */ - { - nm_auto_nmpobj NMPObject *r = NULL; - NMPlatformIP6Route * route; - - r = nmp_object_new(NMP_OBJECT_TYPE_IP6_ROUTE, NULL); - route = NMP_OBJECT_CAST_IP6_ROUTE(r); - route->ifindex = ifindex; - route->network.s6_addr[0] = 0xffu; - route->plen = 8; - route->table_coerced = nm_platform_route_table_coerce(RT_TABLE_LOCAL); - route->type_coerced = nm_platform_route_type_coerce(RTN_UNICAST); - route->metric = 256; - - _add_route(self, r, NULL, NULL); - } - nm_ip_config_iter_ip6_address_for_each (&iter, self, &my_addr) { NMPlatformIP6Route *route; gboolean has_peer; @@ -421,22 +404,6 @@ nm_ip6_config_add_dependent_routes(NMIP6Config *self, if (my_addr->external) continue; - { - nm_auto_nmpobj NMPObject *r = NULL; - - /* Pre-generate local route added by kernel */ - r = nmp_object_new(NMP_OBJECT_TYPE_IP6_ROUTE, NULL); - route = NMP_OBJECT_CAST_IP6_ROUTE(r); - route->ifindex = ifindex; - route->network = my_addr->address; - route->plen = 128; - route->type_coerced = nm_platform_route_type_coerce(RTN_LOCAL); - route->metric = 0; - route->table_coerced = - nm_platform_route_table_coerce(is_vrf ? route_table : RT_TABLE_LOCAL); - _add_route(self, r, NULL, NULL); - } - if (NM_FLAGS_HAS(my_addr->n_ifa_flags, IFA_F_NOPREFIXROUTE)) continue; if (my_addr->plen == 0) diff --git a/src/core/nm-ip6-config.h b/src/core/nm-ip6-config.h index 398186d..4aa0ee4 100644 --- a/src/core/nm-ip6-config.h +++ b/src/core/nm-ip6-config.h @@ -10,8 +10,8 @@ #include "nm-setting-ip6-config.h" -#include "nm-glib-aux/nm-dedup-multi.h" -#include "platform/nmp-object.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-platform/nmp-object.h" #include "nm-ip-config.h" /*****************************************************************************/ diff --git a/src/core/nm-keep-alive.c b/src/core/nm-keep-alive.c index 197e30e..6275544 100644 --- a/src/core/nm-keep-alive.c +++ b/src/core/nm-keep-alive.c @@ -8,7 +8,7 @@ #include "nm-keep-alive.h" #include "settings/nm-settings-connection.h" -#include "nm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-dbus-aux.h" /*****************************************************************************/ diff --git a/src/core/nm-l3-config-data.c b/src/core/nm-l3-config-data.c index 5f9af7a..bf358f9 100644 --- a/src/core/nm-l3-config-data.c +++ b/src/core/nm-l3-config-data.c @@ -8,11 +8,11 @@ #include #include -#include "nm-glib-aux/nm-enum-utils.h" -#include "nm-core-internal.h" -#include "platform/nm-platform.h" -#include "nm-platform/nm-platform-utils.h" -#include "platform/nmp-object.h" +#include "libnm-glib-aux/nm-enum-utils.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-platform/nmp-object.h" #include "NetworkManagerUtils.h" /*****************************************************************************/ diff --git a/src/core/nm-l3-config-data.h b/src/core/nm-l3-config-data.h index b3d9cd3..229851c 100644 --- a/src/core/nm-l3-config-data.h +++ b/src/core/nm-l3-config-data.h @@ -3,11 +3,11 @@ #ifndef __NM_L3_CONFIG_DATA_H__ #define __NM_L3_CONFIG_DATA_H__ -#include "nm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-dedup-multi.h" #include "nm-setting-connection.h" #include "nm-setting-ip6-config.h" -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" typedef enum { NM_L3_CONFIG_DAT_FLAGS_NONE = 0, diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c index 839213a..ef875b7 100644 --- a/src/core/nm-l3cfg.c +++ b/src/core/nm-l3cfg.c @@ -9,8 +9,9 @@ #include #include -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" +#include "libnm-glib-aux/nm-time-utils.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" #include "nm-netns.h" #include "n-acd/src/n-acd.h" #include "nm-l3-ipv4ll.h" diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h index 5cfc93f..a477d6c 100644 --- a/src/core/nm-l3cfg.h +++ b/src/core/nm-l3cfg.h @@ -3,7 +3,7 @@ #ifndef __NM_L3CFG_H__ #define __NM_L3CFG_H__ -#include "platform/nmp-object.h" +#include "libnm-platform/nmp-object.h" #include "nm-l3-config-data.h" #define NM_L3CFG_CONFIG_PRIORITY_IPV4LL 0 diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index 5a6e05a..1e9c265 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -16,15 +16,15 @@ #include #include -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-c-list.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-dbus-manager.h" #include "vpn/nm-vpn-manager.h" #include "devices/nm-device.h" #include "devices/nm-device-generic.h" -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" #include "nm-hostname-manager.h" #include "nm-keep-alive.h" #include "nm-rfkill-manager.h" @@ -40,10 +40,10 @@ #include "nm-policy.h" #include "nm-session-monitor.h" #include "nm-act-request.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-config.h" #include "nm-audit-manager.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-checkpoint.h" #include "nm-checkpoint-manager.h" #include "nm-dbus-object.h" @@ -1305,7 +1305,7 @@ find_device_by_permanent_hw_addr(NMManager *self, const char *hwaddr) NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); NMDevice * device; const char * device_addr; - guint8 hwaddr_bin[NM_UTILS_HWADDR_LEN_MAX]; + guint8 hwaddr_bin[_NM_UTILS_HWADDR_LEN_MAX]; gsize hwaddr_len; g_return_val_if_fail(hwaddr != NULL, NULL); diff --git a/src/core/nm-netns.c b/src/core/nm-netns.c index 88ea09b..90728e7 100644 --- a/src/core/nm-netns.c +++ b/src/core/nm-netns.c @@ -7,15 +7,15 @@ #include "nm-netns.h" -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-c-list.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-l3cfg.h" -#include "platform/nm-platform.h" -#include "nm-platform/nmp-netns.h" -#include "platform/nmp-rules-manager.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-netns.h" +#include "libnm-platform/nmp-rules-manager.h" /*****************************************************************************/ diff --git a/src/core/nm-netns.h b/src/core/nm-netns.h index aab3b52..78a9121 100644 --- a/src/core/nm-netns.h +++ b/src/core/nm-netns.h @@ -6,7 +6,7 @@ #ifndef __NM_NETNS_H__ #define __NM_NETNS_H__ -#include "nm-platform/nmp-base.h" +#include "libnm-platform/nmp-base.h" #define NM_TYPE_NETNS (nm_netns_get_type()) #define NM_NETNS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_NETNS, NMNetns)) @@ -19,13 +19,15 @@ typedef struct _NMNetnsClass NMNetnsClass; +struct _NMPlatform; + GType nm_netns_get_type(void); NMNetns *nm_netns_get(void); -NMNetns *nm_netns_new(NMPlatform *platform); +NMNetns *nm_netns_new(struct _NMPlatform *platform); -NMPlatform *nm_netns_get_platform(NMNetns *self); -NMPNetns * nm_netns_get_platform_netns(NMNetns *self); +struct _NMPlatform *nm_netns_get_platform(NMNetns *self); +NMPNetns * nm_netns_get_platform_netns(NMNetns *self); struct _NMPRulesManager *nm_netns_get_rules_manager(NMNetns *self); diff --git a/src/core/nm-pacrunner-manager.c b/src/core/nm-pacrunner-manager.c index b58aef0..a51d48d 100644 --- a/src/core/nm-pacrunner-manager.c +++ b/src/core/nm-pacrunner-manager.c @@ -9,13 +9,13 @@ #include "nm-utils.h" #include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-dbus-manager.h" #include "nm-proxy-config.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" #include "c-list/src/c-list.h" -#include "nm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-dbus-aux.h" #define PACRUNNER_DBUS_SERVICE "org.pacrunner" #define PACRUNNER_DBUS_INTERFACE "org.pacrunner.Manager" diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index db4983f..b247fe9 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -17,14 +17,14 @@ #include "devices/nm-device.h" #include "nm-setting-ip4-config.h" #include "nm-setting-connection.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "dns/nm-dns-manager.h" #include "vpn/nm-vpn-manager.h" #include "nm-auth-utils.h" #include "nm-firewall-manager.h" #include "nm-dispatcher.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-manager.h" #include "settings/nm-settings.h" #include "settings/nm-settings-connection.h" diff --git a/src/core/nm-proxy-config.c b/src/core/nm-proxy-config.c index f41601c..49156df 100644 --- a/src/core/nm-proxy-config.c +++ b/src/core/nm-proxy-config.c @@ -9,7 +9,7 @@ #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" /*****************************************************************************/ diff --git a/src/core/nm-rfkill-manager.c b/src/core/nm-rfkill-manager.c index f032851..7f0b772 100644 --- a/src/core/nm-rfkill-manager.c +++ b/src/core/nm-rfkill-manager.c @@ -9,7 +9,7 @@ #include -#include "nm-udev-aux/nm-udev-utils.h" +#include "libnm-udev-aux/nm-udev-utils.h" /*****************************************************************************/ diff --git a/src/core/nm-sleep-monitor.c b/src/core/nm-sleep-monitor.c index ffb4db4..e275fd0 100644 --- a/src/core/nm-sleep-monitor.c +++ b/src/core/nm-sleep-monitor.c @@ -11,7 +11,7 @@ #include #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" #if defined(SUSPEND_RESUME_UPOWER) diff --git a/src/core/nm-test-utils-core.h b/src/core/nm-test-utils-core.h index e655ce2..99d12ba 100644 --- a/src/core/nm-test-utils-core.h +++ b/src/core/nm-test-utils-core.h @@ -7,41 +7,11 @@ #define __NM_TEST_UTILS_CORE_H__ #include "NetworkManagerUtils.h" -#include "nm-keyfile-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" #define _NMTST_INSIDE_CORE 1 -#include "nm-utils/nm-test-utils.h" - -/*****************************************************************************/ - -#define NMTST_EXPECT_NM(level, msg) NMTST_EXPECT("NetworkManager", level, msg) - -#define NMTST_EXPECT_NM_ERROR(msg) NMTST_EXPECT_NM(G_LOG_LEVEL_MESSAGE, "* [*] " msg) -#define NMTST_EXPECT_NM_WARN(msg) NMTST_EXPECT_NM(G_LOG_LEVEL_MESSAGE, "* [*] " msg) -#define NMTST_EXPECT_NM_INFO(msg) NMTST_EXPECT_NM(G_LOG_LEVEL_INFO, "* [*] " msg) -#define NMTST_EXPECT_NM_DEBUG(msg) NMTST_EXPECT_NM(G_LOG_LEVEL_DEBUG, "* [*] " msg) -#define NMTST_EXPECT_NM_TRACE(msg) NMTST_EXPECT_NM(G_LOG_LEVEL_DEBUG, "* [*] " msg) - -static inline void -nmtst_init_with_logging(int *argc, char ***argv, const char *log_level, const char *log_domains) -{ - __nmtst_init(argc, argv, FALSE, log_level, log_domains, NULL); -} -static inline void -nmtst_init_assert_logging(int *argc, char ***argv, const char *log_level, const char *log_domains) -{ - gboolean set_logging; - - __nmtst_init(argc, argv, TRUE, NULL, NULL, &set_logging); - - if (!set_logging) { - gboolean success; - - success = nm_logging_setup(log_level, log_domains, NULL, NULL); - g_assert(success); - } -} +#include "libnm-glib-aux/nm-test-utils.h" /*****************************************************************************/ @@ -347,7 +317,7 @@ nmtst_platform_ip6_routes_equal_aptr(const NMPObject *const * a, #ifdef __NETWORKMANAGER_IP4_CONFIG_H__ - #include "nm-glib-aux/nm-dedup-multi.h" + #include "libnm-glib-aux/nm-dedup-multi.h" static inline NMIP4Config * nmtst_ip4_config_new(int ifindex) @@ -361,7 +331,7 @@ nmtst_ip4_config_new(int ifindex) #ifdef __NETWORKMANAGER_IP6_CONFIG_H__ - #include "nm-glib-aux/nm-dedup-multi.h" + #include "libnm-glib-aux/nm-dedup-multi.h" static inline NMIP6Config * nmtst_ip6_config_new(int ifindex) diff --git a/src/core/nm-types.h b/src/core/nm-types.h index ab23145..b6abc1b 100644 --- a/src/core/nm-types.h +++ b/src/core/nm-types.h @@ -77,147 +77,6 @@ typedef enum { NM_ACTIVATION_REASON_USER_REQUEST, } NMActivationReason; -/* platform */ -typedef struct _NMPlatform NMPlatform; -typedef struct _NMPlatformObject NMPlatformObject; -typedef struct _NMPlatformObjWithIfindex NMPlatformObjWithIfindex; -typedef struct _NMPlatformIP4Address NMPlatformIP4Address; -typedef struct _NMPlatformIP4Route NMPlatformIP4Route; -typedef struct _NMPlatformIP6Address NMPlatformIP6Address; -typedef struct _NMPlatformIP6Route NMPlatformIP6Route; -typedef struct _NMPlatformLink NMPlatformLink; -typedef struct _NMPObject NMPObject; - -typedef enum { - - /* No type, used as error value */ - NM_LINK_TYPE_NONE, - - NM_LINK_TYPE_UNKNOWN, - - NM_LINK_TYPE_ANY, - -#define _NM_LINK_TYPE_REAL_FIRST NM_LINK_TYPE_ETHERNET - -/* Hardware types */ -#define _NM_LINK_TYPE_HW_FIRST NM_LINK_TYPE_ETHERNET - NM_LINK_TYPE_ETHERNET, - NM_LINK_TYPE_INFINIBAND, - NM_LINK_TYPE_OLPC_MESH, - NM_LINK_TYPE_WIFI, - NM_LINK_TYPE_WWAN_NET, /* WWAN kernel netdevice */ - NM_LINK_TYPE_WIMAX, - NM_LINK_TYPE_WPAN, - NM_LINK_TYPE_6LOWPAN, - NM_LINK_TYPE_WIFI_P2P, -#define _NM_LINK_TYPE_HW_LAST NM_LINK_TYPE_WIFI_P2P - -/* Software types */ -#define _NM_LINK_TYPE_SW_FIRST NM_LINK_TYPE_BNEP - NM_LINK_TYPE_BNEP, /* Bluetooth Ethernet emulation */ - NM_LINK_TYPE_DUMMY, - NM_LINK_TYPE_GRE, - NM_LINK_TYPE_GRETAP, - NM_LINK_TYPE_IFB, - NM_LINK_TYPE_IP6TNL, - NM_LINK_TYPE_IP6GRE, - NM_LINK_TYPE_IP6GRETAP, - NM_LINK_TYPE_IPIP, - NM_LINK_TYPE_LOOPBACK, - NM_LINK_TYPE_MACSEC, - NM_LINK_TYPE_MACVLAN, - NM_LINK_TYPE_MACVTAP, - NM_LINK_TYPE_OPENVSWITCH, - NM_LINK_TYPE_PPP, - NM_LINK_TYPE_SIT, - NM_LINK_TYPE_TUN, - NM_LINK_TYPE_VETH, - NM_LINK_TYPE_VLAN, - NM_LINK_TYPE_VRF, - NM_LINK_TYPE_VXLAN, - NM_LINK_TYPE_WIREGUARD, -#define _NM_LINK_TYPE_SW_LAST NM_LINK_TYPE_WIREGUARD - -/* Software types with slaves */ -#define _NM_LINK_TYPE_SW_MASTER_FIRST NM_LINK_TYPE_BRIDGE - NM_LINK_TYPE_BRIDGE, - NM_LINK_TYPE_BOND, - NM_LINK_TYPE_TEAM, -#define _NM_LINK_TYPE_SW_MASTER_LAST NM_LINK_TYPE_TEAM - -#define _NM_LINK_TYPE_REAL_LAST NM_LINK_TYPE_TEAM - -#define _NM_LINK_TYPE_REAL_NUM ((int) (_NM_LINK_TYPE_REAL_LAST - _NM_LINK_TYPE_REAL_FIRST + 1)) - -} NMLinkType; - -static inline gboolean -nm_link_type_is_software(NMLinkType link_type) -{ - G_STATIC_ASSERT(_NM_LINK_TYPE_SW_LAST + 1 == _NM_LINK_TYPE_SW_MASTER_FIRST); - - return link_type >= _NM_LINK_TYPE_SW_FIRST && link_type <= _NM_LINK_TYPE_SW_MASTER_LAST; -} - -static inline gboolean -nm_link_type_supports_slaves(NMLinkType link_type) -{ - return link_type >= _NM_LINK_TYPE_SW_MASTER_FIRST && link_type <= _NM_LINK_TYPE_SW_MASTER_LAST; -} - -typedef enum { - NMP_OBJECT_TYPE_UNKNOWN, - NMP_OBJECT_TYPE_LINK, - -#define NMP_OBJECT_TYPE_IP_ADDRESS(is_ipv4) \ - ((is_ipv4) ? NMP_OBJECT_TYPE_IP4_ADDRESS : NMP_OBJECT_TYPE_IP6_ADDRESS) - NMP_OBJECT_TYPE_IP4_ADDRESS, - NMP_OBJECT_TYPE_IP6_ADDRESS, - -#define NMP_OBJECT_TYPE_IP_ROUTE(is_ipv4) \ - ((is_ipv4) ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE) - NMP_OBJECT_TYPE_IP4_ROUTE, - NMP_OBJECT_TYPE_IP6_ROUTE, - - NMP_OBJECT_TYPE_ROUTING_RULE, - - NMP_OBJECT_TYPE_QDISC, - - NMP_OBJECT_TYPE_TFILTER, - - NMP_OBJECT_TYPE_LNK_BRIDGE, - NMP_OBJECT_TYPE_LNK_GRE, - NMP_OBJECT_TYPE_LNK_GRETAP, - NMP_OBJECT_TYPE_LNK_INFINIBAND, - NMP_OBJECT_TYPE_LNK_IP6TNL, - NMP_OBJECT_TYPE_LNK_IP6GRE, - NMP_OBJECT_TYPE_LNK_IP6GRETAP, - NMP_OBJECT_TYPE_LNK_IPIP, - NMP_OBJECT_TYPE_LNK_MACSEC, - NMP_OBJECT_TYPE_LNK_MACVLAN, - NMP_OBJECT_TYPE_LNK_MACVTAP, - NMP_OBJECT_TYPE_LNK_SIT, - NMP_OBJECT_TYPE_LNK_TUN, - NMP_OBJECT_TYPE_LNK_VLAN, - NMP_OBJECT_TYPE_LNK_VRF, - NMP_OBJECT_TYPE_LNK_VXLAN, - NMP_OBJECT_TYPE_LNK_WIREGUARD, - - __NMP_OBJECT_TYPE_LAST, - NMP_OBJECT_TYPE_MAX = __NMP_OBJECT_TYPE_LAST - 1, -} NMPObjectType; - -static inline guint32 -nmp_object_type_to_flags(NMPObjectType obj_type) -{ - G_STATIC_ASSERT_EXPR(NMP_OBJECT_TYPE_MAX < 32); - - nm_assert(_NM_INT_NOT_NEGATIVE(obj_type)); - nm_assert(obj_type < NMP_OBJECT_TYPE_MAX); - - return ((guint32) 1u) << obj_type; -} - /** * NMIPConfigMergeFlags: * @NM_IP_CONFIG_MERGE_DEFAULT: no flags set @@ -236,32 +95,12 @@ typedef enum { NM_IP_CONFIG_MERGE_EXTERNAL = (1LL << 3), } NMIPConfigMergeFlags; -/** - * NMIPRouteTableSyncMode: - * @NM_IP_ROUTE_TABLE_SYNC_MODE_NONE: indicate an invalid setting. - * @NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN: only the main table is synced. For all - * other tables, NM won't delete any extra routes. - * @NM_IP_ROUTE_TABLE_SYNC_MODE_FULL: NM will sync all tables, except the - * local table (255). - * @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL: NM will sync all tables, including the - * local table (255). - */ -typedef enum { - NM_IP_ROUTE_TABLE_SYNC_MODE_NONE = 0, - NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN = 1, - NM_IP_ROUTE_TABLE_SYNC_MODE_FULL = 2, - NM_IP_ROUTE_TABLE_SYNC_MODE_ALL = 3, -} NMIPRouteTableSyncMode; - /* settings */ typedef struct _NMAgentManager NMAgentManager; typedef struct _NMSecretAgent NMSecretAgent; typedef struct _NMSettings NMSettings; typedef struct _NMSettingsConnection NMSettingsConnection; -/* utils */ -typedef struct _NMUtilsIPv6IfaceId NMUtilsIPv6IfaceId; - #define NM_SETTING_CONNECTION_MDNS_UNKNOWN ((NMSettingConnectionMdns) -42) #endif /* NM_TYPES_H */ diff --git a/src/core/platform/nm-fake-platform.c b/src/core/platform/nm-fake-platform.c index 81c9f06..f65dbeb 100644 --- a/src/core/platform/nm-fake-platform.c +++ b/src/core/platform/nm-fake-platform.c @@ -13,12 +13,9 @@ #include #include -#include "nm-utils.h" - -#include "nm-core-utils.h" -#include "nm-platform/nm-platform-utils.h" -#include "nm-platform-private.h" -#include "nmp-object.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-platform/nm-platform-private.h" +#include "libnm-platform/nmp-object.h" #include "nm-test-utils-core.h" @@ -608,7 +605,7 @@ link_set_address(NMPlatform *platform, int ifindex, gconstpointer addr, size_t l NMFakePlatformLink *device = link_get(platform, ifindex); nm_auto_nmpobj NMPObject *obj_tmp = NULL; - if (len == 0 || len > NM_UTILS_HWADDR_LEN_MAX || !addr) + if (len == 0 || len > _NM_UTILS_HWADDR_LEN_MAX || !addr) g_return_val_if_reached(-NME_BUG); if (!device) @@ -749,8 +746,8 @@ link_release(NMPlatform *platform, int master_idx, int slave_idx) static gboolean link_vlan_change(NMPlatform * platform, int ifindex, - NMVlanFlags flags_mask, - NMVlanFlags flags_set, + _NMVlanFlags flags_mask, + _NMVlanFlags flags_set, gboolean ingress_reset_all, const NMVlanQosMapping *ingress_map, gsize n_ingress_map, @@ -799,7 +796,7 @@ infiniband_partition_add(NMPlatform * platform, parent_device = link_get(platform, parent); g_return_val_if_fail(parent_device != NULL, FALSE); - nm_utils_new_infiniband_name(name, parent_device->obj->link.name, p_key); + nmp_utils_new_infiniband_name(name, parent_device->obj->link.name, p_key); link_add_one(platform, name, NM_LINK_TYPE_INFINIBAND, _infiniband_add_prepare, &d, out_link); return TRUE; @@ -814,12 +811,12 @@ infiniband_partition_delete(NMPlatform *platform, int parent, int p_key) parent_device = link_get(platform, parent); g_return_val_if_fail(parent_device != NULL, FALSE); - nm_utils_new_infiniband_name(name, parent_device->obj->link.name, p_key); + nmp_utils_new_infiniband_name(name, parent_device->obj->link.name, p_key); return link_delete(platform, nm_platform_link_get_ifindex(platform, name)); } static gboolean -wifi_get_capabilities(NMPlatform *platform, int ifindex, NMDeviceWifiCapabilities *caps) +wifi_get_capabilities(NMPlatform *platform, int ifindex, _NMDeviceWifiCapabilities *caps) { NMFakePlatformLink *device = link_get(platform, ifindex); @@ -829,10 +826,10 @@ wifi_get_capabilities(NMPlatform *platform, int ifindex, NMDeviceWifiCapabilitie return FALSE; if (caps) { - *caps = (NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104 - | NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP - | NM_WIFI_DEVICE_CAP_WPA | NM_WIFI_DEVICE_CAP_RSN | NM_WIFI_DEVICE_CAP_AP - | NM_WIFI_DEVICE_CAP_ADHOC); + *caps = (_NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | _NM_WIFI_DEVICE_CAP_CIPHER_WEP104 + | _NM_WIFI_DEVICE_CAP_CIPHER_TKIP | _NM_WIFI_DEVICE_CAP_CIPHER_CCMP + | _NM_WIFI_DEVICE_CAP_WPA | _NM_WIFI_DEVICE_CAP_RSN | _NM_WIFI_DEVICE_CAP_AP + | _NM_WIFI_DEVICE_CAP_ADHOC); } return TRUE; } @@ -861,14 +858,14 @@ wifi_get_rate(NMPlatform *platform, int ifindex) return 0; } -static NM80211Mode +static _NM80211Mode wifi_get_mode(NMPlatform *platform, int ifindex) { - return NM_802_11_MODE_UNKNOWN; + return _NM_802_11_MODE_UNKNOWN; } static void -wifi_set_mode(NMPlatform *platform, int ifindex, NM80211Mode mode) +wifi_set_mode(NMPlatform *platform, int ifindex, _NM80211Mode mode) { ; } diff --git a/src/core/platform/nm-fake-platform.h b/src/core/platform/nm-fake-platform.h index a1d44f8..8f8571f 100644 --- a/src/core/platform/nm-fake-platform.h +++ b/src/core/platform/nm-fake-platform.h @@ -6,7 +6,7 @@ #ifndef __NETWORKMANAGER_FAKE_PLATFORM_H__ #define __NETWORKMANAGER_FAKE_PLATFORM_H__ -#include "nm-platform.h" +#include "libnm-platform/nm-platform.h" #define NM_TYPE_FAKE_PLATFORM (nm_fake_platform_get_type()) #define NM_FAKE_PLATFORM(obj) \ diff --git a/src/core/platform/tests/monitor.c b/src/core/platform/tests/monitor.c index abdf2cd..ff6fae6 100644 --- a/src/core/platform/tests/monitor.c +++ b/src/core/platform/tests/monitor.c @@ -8,7 +8,7 @@ #include #include -#include "platform/nm-linux-platform.h" +#include "libnm-platform/nm-linux-platform.h" #include "nm-test-utils-core.h" diff --git a/src/core/platform/tests/test-common.c b/src/core/platform/tests/test-common.c index 4a117d5..1b97714 100644 --- a/src/core/platform/tests/test-common.c +++ b/src/core/platform/tests/test-common.c @@ -1542,7 +1542,10 @@ nmtstp_link_bridge_add(NMPlatform * platform, ll = NMP_OBJECT_CAST_LNK_BRIDGE(NMP_OBJECT_UP_CAST(pllink)->_link.netlink.lnk); - g_assert_cmpint(lnk->forward_delay, ==, ll->forward_delay); + /* account for roundtrip rounding error with clock_t_to_jiffies()/jiffies_to_clock_t(). */ + g_assert_cmpint(lnk->forward_delay, >=, ll->forward_delay - 1); + g_assert_cmpint(lnk->forward_delay, <=, ll->forward_delay); + g_assert_cmpint(lnk->hello_time, ==, ll->hello_time); g_assert_cmpint(lnk->max_age, ==, ll->max_age); g_assert_cmpint(lnk->ageing_time, ==, ll->ageing_time); diff --git a/src/core/platform/tests/test-common.h b/src/core/platform/tests/test-common.h index 618645f..ff116fa 100644 --- a/src/core/platform/tests/test-common.h +++ b/src/core/platform/tests/test-common.h @@ -11,10 +11,10 @@ #include #include -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" #include "platform/nm-fake-platform.h" -#include "platform/nm-linux-platform.h" +#include "libnm-platform/nm-linux-platform.h" #include "nm-test-utils-core.h" diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c index 3aaa375..1613703 100644 --- a/src/core/platform/tests/test-link.c +++ b/src/core/platform/tests/test-link.c @@ -11,11 +11,11 @@ #include #include -#include "nm-glib-aux/nm-io-utils.h" -#include "nm-base/nm-ethtool-base.h" -#include "platform/nmp-object.h" -#include "nm-platform/nmp-netns.h" -#include "nm-platform/nm-platform-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-base/nm-ethtool-base.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nmp-netns.h" +#include "libnm-platform/nm-platform-utils.h" #include "test-common.h" #include "nm-test-utils-core.h" @@ -1303,7 +1303,7 @@ test_software_detect(gconstpointer user_data) if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "gre0")) { /* Seems that the ip_gre module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ip_gre", NULL) != 0; + gracefully_skip = nmp_utils_modprobe(NULL, TRUE, "ip_gre", NULL) != 0; } if (!nmtstp_link_gre_add(NULL, ext, DEVICE_NAME, &lnk_gre)) { @@ -1330,7 +1330,7 @@ test_software_detect(gconstpointer user_data) if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "gretap0")) { /* Seems that the ip_gre module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ip_gre", NULL) != 0; + gracefully_skip = nmp_utils_modprobe(NULL, TRUE, "ip_gre", NULL) != 0; } if (!nmtstp_link_gre_add(NULL, ext, DEVICE_NAME, &lnk_gre)) { @@ -1350,7 +1350,7 @@ test_software_detect(gconstpointer user_data) if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "tunl0")) { /* Seems that the ipip module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ipip", NULL) != 0; + gracefully_skip = nmp_utils_modprobe(NULL, TRUE, "ipip", NULL) != 0; } lnk_ipip.local = nmtst_inet4_from_string("1.2.3.4"); @@ -1376,7 +1376,7 @@ test_software_detect(gconstpointer user_data) if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "ip6tnl0")) { /* Seems that the ip6_tunnel module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ip6_tunnel", NULL) != 0; + gracefully_skip = nmp_utils_modprobe(NULL, TRUE, "ip6_tunnel", NULL) != 0; } switch (test_data->test_mode) { @@ -1418,7 +1418,7 @@ test_software_detect(gconstpointer user_data) if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "ip6gre0")) { /* Seems that the ip6_tunnel module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ip6_gre", NULL) != 0; + gracefully_skip = nmp_utils_modprobe(NULL, TRUE, "ip6_gre", NULL) != 0; } lnk_ip6tnl.local = *nmtst_inet6_from_string("fd01::42"); @@ -1445,7 +1445,7 @@ test_software_detect(gconstpointer user_data) if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "ip6gre0")) { /* Seems that the ip6_tunnel module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ip6_gre", NULL) != 0; + gracefully_skip = nmp_utils_modprobe(NULL, TRUE, "ip6_gre", NULL) != 0; } lnk_ip6tnl.local = *nmtst_inet6_from_string("fe80::abcd"); @@ -1526,7 +1526,7 @@ test_software_detect(gconstpointer user_data) if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "sit0")) { /* Seems that the sit module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe(NULL, TRUE, "sit", NULL) != 0; + gracefully_skip = nmp_utils_modprobe(NULL, TRUE, "sit", NULL) != 0; } if (!nmtstp_link_sit_add(NULL, ext, DEVICE_NAME, &lnk_sit)) { @@ -2049,7 +2049,7 @@ _assert_xgress_qos_mappings_impl(int ifindex, gboolean is_ingress_map, int n_ent _assert_xgress_qos_mappings(ifindex, FALSE, n_entries, __VA_ARGS__) static void -_assert_vlan_flags(int ifindex, NMVlanFlags flags) +_assert_vlan_flags(int ifindex, _NMVlanFlags flags) { const NMPlatformLnkVlan *plnk; @@ -2362,8 +2362,8 @@ test_vlan_set_xgress(void) g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, ifindex, - NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP, - NM_VLAN_FLAG_REORDER_HEADERS, + _NM_VLAN_FLAG_REORDER_HEADERS | _NM_VLAN_FLAG_GVRP, + _NM_VLAN_FLAG_REORDER_HEADERS, TRUE, ingress_map, G_N_ELEMENTS(ingress_map), @@ -2372,7 +2372,7 @@ test_vlan_set_xgress(void) G_N_ELEMENTS(egress_map))); _assert_ingress_qos_mappings(ifindex, 2, 4, 1, 6, 12); _assert_egress_qos_mappings(ifindex, 2, 1, 5, 3232, 7); - _assert_vlan_flags(ifindex, NM_VLAN_FLAG_REORDER_HEADERS); + _assert_vlan_flags(ifindex, _NM_VLAN_FLAG_REORDER_HEADERS); } { @@ -2393,8 +2393,8 @@ test_vlan_set_xgress(void) g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, ifindex, - NM_VLAN_FLAG_GVRP, - NM_VLAN_FLAG_GVRP, + _NM_VLAN_FLAG_GVRP, + _NM_VLAN_FLAG_GVRP, FALSE, ingress_map, G_N_ELEMENTS(ingress_map), @@ -2403,7 +2403,7 @@ test_vlan_set_xgress(void) G_N_ELEMENTS(egress_map))); _assert_ingress_qos_mappings(ifindex, 2, 4, 1, 6, 12); _assert_egress_qos_mappings(ifindex, 2, 1, 7, 64, 4); - _assert_vlan_flags(ifindex, NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP); + _assert_vlan_flags(ifindex, _NM_VLAN_FLAG_REORDER_HEADERS | _NM_VLAN_FLAG_GVRP); } nmtstp_link_delete(NULL, -1, ifindex, DEVICE_NAME, TRUE); diff --git a/src/core/platform/tests/test-nmp-object.c b/src/core/platform/tests/test-nmp-object.c index 310611e..6d2236e 100644 --- a/src/core/platform/tests/test-nmp-object.c +++ b/src/core/platform/tests/test-nmp-object.c @@ -8,8 +8,8 @@ #include #include -#include "platform/nmp-object.h" -#include "nm-udev-aux/nm-udev-utils.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-udev-aux/nm-udev-utils.h" #include "nm-test-utils-core.h" diff --git a/src/core/platform/tests/test-platform-general.c b/src/core/platform/tests/test-platform-general.c index b426cc6..685cd18 100644 --- a/src/core/platform/tests/test-platform-general.c +++ b/src/core/platform/tests/test-platform-general.c @@ -7,8 +7,8 @@ #include -#include "nm-platform/nm-platform-utils.h" -#include "platform/nm-linux-platform.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-platform/nm-linux-platform.h" #include "nm-test-utils-core.h" diff --git a/src/core/platform/tests/test-route.c b/src/core/platform/tests/test-route.c index 645bb5b..2b9b2f8 100644 --- a/src/core/platform/tests/test-route.c +++ b/src/core/platform/tests/test-route.c @@ -9,8 +9,8 @@ #include #include "nm-core-utils.h" -#include "nm-platform/nm-platform-utils.h" -#include "platform/nmp-rules-manager.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-platform/nmp-rules-manager.h" #include "test-common.h" diff --git a/src/core/platform/tests/test-tc.c b/src/core/platform/tests/test-tc.c index d15c3d7..cd9536c 100644 --- a/src/core/platform/tests/test-tc.c +++ b/src/core/platform/tests/test-tc.c @@ -5,9 +5,9 @@ #include #include "nm-test-utils-core.h" -#include "platform/nmp-object.h" -#include "nm-platform/nmp-netns.h" -#include "nm-platform/nm-platform-utils.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nmp-netns.h" +#include "libnm-platform/nm-platform-utils.h" #include "test-common.h" static NMPObject * diff --git a/src/core/ppp/meson.build b/src/core/ppp/meson.build index 607b471..ffeb0eb 100644 --- a/src/core/ppp/meson.build +++ b/src/core/ppp/meson.build @@ -4,9 +4,19 @@ nm_pppd_plugin = shared_module( 'nm-pppd-plugin', name_prefix: '', sources: 'nm-pppd-plugin.c', - dependencies: libnm_core_nm_default_dep, - c_args: [ - '-DG_LOG_DOMAIN="nm-pppd-plugin"', + include_directories: [ + src_inc, + top_inc, + ], + dependencies: [ + libnm_core_public_dep, + glib_dep, + ], + link_with: [ + libnm_core_impl, + libnm_glib_aux, + libnm_std_aux, + libc_siphash, ], install: true, install_dir: pppd_plugin_dir, @@ -20,7 +30,6 @@ core_plugins += shared_module( 'nm-ppp-manager.c', ], dependencies: core_plugin_dep, - c_args: daemon_c_flags, link_args: '-Wl,--version-script,@0@'.format(linker_script), link_depends: linker_script, install: true, diff --git a/src/core/ppp/nm-ppp-manager.c b/src/core/ppp/nm-ppp-manager.c index 396a49a..137fccf 100644 --- a/src/core/ppp/nm-ppp-manager.c +++ b/src/core/ppp/nm-ppp-manager.c @@ -28,8 +28,9 @@ #include #include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-act-request.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" @@ -998,7 +999,7 @@ _ppp_manager_start(NMPPPManager *self, /* Make sure /dev/ppp exists (bgo #533064) */ if (stat("/dev/ppp", &st) || !S_ISCHR(st.st_mode)) - nm_utils_modprobe(NULL, FALSE, "ppp_generic", NULL); + nmp_utils_modprobe(NULL, FALSE, "ppp_generic", NULL); connection = nm_act_request_get_applied_connection(req); g_return_val_if_fail(connection, FALSE); diff --git a/src/core/ppp/nm-pppd-plugin.c b/src/core/ppp/nm-pppd-plugin.c index c9016da..13c4e51 100644 --- a/src/core/ppp/nm-pppd-plugin.c +++ b/src/core/ppp/nm-pppd-plugin.c @@ -20,7 +20,7 @@ #include #include -#include "nm-glib-aux/nm-default-glib.h" +#include "libnm-glib-aux/nm-default-glib.h" #include "nm-dbus-interface.h" diff --git a/src/core/settings/nm-agent-manager.c b/src/core/settings/nm-agent-manager.c index 7e61790..a1c2eb9 100644 --- a/src/core/settings/nm-agent-manager.c +++ b/src/core/settings/nm-agent-manager.c @@ -9,7 +9,7 @@ #include -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-dbus-interface.h" #include "nm-secret-agent.h" #include "nm-auth-utils.h" @@ -19,7 +19,7 @@ #include "nm-session-monitor.h" #include "nm-simple-connection.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "c-list/src/c-list.h" /*****************************************************************************/ diff --git a/src/core/settings/nm-secret-agent.c b/src/core/settings/nm-secret-agent.c index 7e7c5d7..5493984 100644 --- a/src/core/settings/nm-secret-agent.c +++ b/src/core/settings/nm-secret-agent.c @@ -10,11 +10,11 @@ #include #include -#include "nm-glib-aux/nm-c-list.h" -#include "nm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-dbus-aux.h" #include "nm-dbus-interface.h" -#include "nm-core-internal.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "nm-simple-connection.h" #include "NetworkManagerUtils.h" #include "c-list/src/c-list.h" diff --git a/src/core/settings/nm-settings-connection.c b/src/core/settings/nm-settings-connection.c index 0ff0718..6f400f7 100644 --- a/src/core/settings/nm-settings-connection.c +++ b/src/core/settings/nm-settings-connection.c @@ -10,8 +10,8 @@ #include "c-list/src/c-list.h" -#include "nm-glib-aux/nm-keyfile-aux.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-glib-aux/nm-keyfile-aux.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-config.h" #include "nm-config-data.h" #include "nm-dbus-interface.h" @@ -20,7 +20,7 @@ #include "nm-auth-utils.h" #include "nm-agent-manager.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-audit-manager.h" #include "nm-settings.h" #include "nm-dbus-manager.h" diff --git a/src/core/settings/nm-settings-plugin.c b/src/core/settings/nm-settings-plugin.c index 9e81caa..66cc19b 100644 --- a/src/core/settings/nm-settings-plugin.c +++ b/src/core/settings/nm-settings-plugin.c @@ -9,7 +9,7 @@ #include "nm-settings-plugin.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-settings-connection.h" diff --git a/src/core/settings/nm-settings.c b/src/core/settings/nm-settings.c index 3d31fb8..92733f5 100644 --- a/src/core/settings/nm-settings.c +++ b/src/core/settings/nm-settings.c @@ -20,9 +20,9 @@ #include #endif -#include "nm-libnm-core-intern/nm-common-macros.h" -#include "nm-glib-aux/nm-keyfile-aux.h" -#include "nm-keyfile-internal.h" +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "libnm-glib-aux/nm-keyfile-aux.h" +#include "libnm-core-intern/nm-keyfile-internal.h" #include "nm-dbus-interface.h" #include "nm-connection.h" #include "nm-setting-8021x.h" @@ -44,17 +44,17 @@ #include "nm-setting-proxy.h" #include "nm-setting-bond.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" -#include "nm-std-aux/c-list-util.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-std-aux/c-list-util.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-dbus-object.h" #include "devices/nm-device-ethernet.h" #include "nm-settings-connection.h" #include "nm-settings-plugin.h" #include "nm-dbus-manager.h" #include "nm-auth-utils.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "nm-session-monitor.h" #include "plugins/keyfile/nms-keyfile-plugin.h" #include "plugins/keyfile/nms-keyfile-storage.h" diff --git a/src/core/settings/plugins/ifcfg-rh/meson.build b/src/core/settings/plugins/ifcfg-rh/meson.build index a2f11a9..c62fa89 100644 --- a/src/core/settings/plugins/ifcfg-rh/meson.build +++ b/src/core/settings/plugins/ifcfg-rh/meson.build @@ -28,7 +28,6 @@ libnms_ifcfg_rh_core = static_library( 'shvar.c', ), dependencies: core_default_dep, - c_args: daemon_c_flags, ) libnm_settings_plugin_ifcfg_rh = shared_module( @@ -38,7 +37,6 @@ libnm_settings_plugin_ifcfg_rh = shared_module( 'nms-ifcfg-rh-plugin.c', ), dependencies: core_plugin_dep, - c_args: daemon_c_flags, link_with: libnms_ifcfg_rh_core, link_args: ldflags_linker_script_settings, link_depends: linker_script_settings, diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c index d114db0..5038ac6 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c @@ -13,12 +13,12 @@ #include #include -#include "nm-std-aux/c-list-util.h" -#include "nm-glib-aux/nm-c-list.h" -#include "nm-glib-aux/nm-io-utils.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/c-list-util.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-config.h" #include "nm-dbus-manager.h" #include "settings/nm-settings-plugin.h" diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 209957d..a2da910 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -18,7 +18,7 @@ #include #include -#include "nm-glib-aux/nm-secret-utils.h" +#include "libnm-glib-aux/nm-secret-utils.h" #include "nm-connection.h" #include "nm-dbus-interface.h" #include "nm-setting-connection.h" @@ -38,11 +38,11 @@ #include "nm-setting-user.h" #include "nm-setting-proxy.h" #include "nm-setting-generic.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-utils.h" -#include "nm-base/nm-ethtool-base.h" +#include "libnm-base/nm-ethtool-base.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "NetworkManagerUtils.h" #include "nms-ifcfg-rh-common.h" @@ -4302,7 +4302,7 @@ make_wireless_setting(shvarFile *ifcfg, GError **error) bytes = g_bytes_new(value, value_len); ssid_len = g_bytes_get_size(bytes); - if (ssid_len > 32 || ssid_len == 0) { + if (ssid_len == 0 || ssid_len > NM_IW_ESSID_MAX_SIZE) { g_set_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, @@ -5118,15 +5118,15 @@ make_wired_setting(shvarFile *ifcfg, const char *file, NMSetting8021x **s_8021x, for (i = 0; options && options[i]; i++) { const char *line = options[i]; const char *equals; - gboolean valid = FALSE; equals = strchr(line, '='); - if (equals) { - ((char *) equals)[0] = '\0'; - valid = nm_setting_wired_add_s390_option(s_wired, line, equals + 1); - } - if (!valid) - PARSE_WARNING("invalid s390 OPTION '%s'", line); + if (!equals) + continue; + + /* Here we don't verify the key/value further. If the file contains invalid keys, + * we will later reject the connection as invalid. */ + ((char *) equals)[0] = '\0'; + nm_setting_wired_add_s390_option(s_wired, line, equals + 1); } found = TRUE; } diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c index 3f674de..714357a 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c @@ -8,7 +8,7 @@ #include "nms-ifcfg-rh-storage.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-connection.h" #include "nms-ifcfg-rh-plugin.h" diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index 8da5de4..aa5f729 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -9,7 +9,7 @@ #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" #include "nms-ifcfg-rh-common.h" diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h index 36ec922..f7a2093 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h @@ -7,7 +7,7 @@ #define _UTILS_H_ #include "nm-connection.h" -#include "nm-base/nm-ethtool-base.h" +#include "libnm-base/nm-ethtool-base.h" #include "shvar.h" diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index a968fce..955a9e8 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -15,8 +15,8 @@ #include #include -#include "nm-glib-aux/nm-enum-utils.h" -#include "nm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-enum-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" #include "nm-manager.h" #include "nm-setting-connection.h" #include "nm-setting-wired.h" @@ -32,9 +32,9 @@ #include "nm-setting-team.h" #include "nm-setting-team-port.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" -#include "nm-base/nm-ethtool-base.h" +#include "libnm-base/nm-ethtool-base.h" #include "nms-ifcfg-rh-common.h" #include "nms-ifcfg-rh-reader.h" @@ -862,7 +862,7 @@ write_wireless_setting(NMConnection *connection, return FALSE; } ssid_data = g_bytes_get_data(ssid, &ssid_len); - if (!ssid_len || ssid_len > 32) { + if (ssid_len == 0 || ssid_len > NM_IW_ESSID_MAX_SIZE) { g_set_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, @@ -903,9 +903,9 @@ write_wireless_setting(NMConnection *connection, svSetValueStr(ifcfg, "ESSID", str->str); g_string_free(str, TRUE); } else { - char buf[33]; + char buf[NM_IW_ESSID_MAX_SIZE + 1]; - nm_assert(ssid_len <= 32); + nm_assert(ssid_len <= NM_IW_ESSID_MAX_SIZE); memcpy(buf, ssid_data, ssid_len); buf[ssid_len] = '\0'; svSetValueStr(ifcfg, "ESSID", buf); diff --git a/src/core/settings/plugins/ifcfg-rh/shvar.c b/src/core/settings/plugins/ifcfg-rh/shvar.c index 386bcac..c6099dd 100644 --- a/src/core/settings/plugins/ifcfg-rh/shvar.c +++ b/src/core/settings/plugins/ifcfg-rh/shvar.c @@ -14,10 +14,10 @@ #include #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-core-utils.h" -#include "nm-glib-aux/nm-enum-utils.h" -#include "nm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-enum-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" #include "c-list/src/c-list.h" #include "nms-ifcfg-rh-utils.h" diff --git a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 59127d0..ad96d0c 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -17,7 +17,7 @@ #include #include -#include "nm-glib-aux/nm-json-aux.h" +#include "libnm-glib-aux/nm-json-aux.h" #include "nm-utils.h" #include "nm-setting-connection.h" #include "nm-setting-wired.h" @@ -36,9 +36,9 @@ #include "nm-setting-serial.h" #include "nm-setting-vlan.h" #include "nm-setting-dcb.h" -#include "nm-core-internal.h" -#include "nm-base/nm-ethtool-base.h" -#include "nm-base/nm-ethtool-utils-base.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-base/nm-ethtool-base.h" +#include "libnm-base/nm-ethtool-utils-base.h" #include "NetworkManagerUtils.h" diff --git a/src/core/settings/plugins/ifupdown/meson.build b/src/core/settings/plugins/ifupdown/meson.build index dd25278..1bff815 100644 --- a/src/core/settings/plugins/ifupdown/meson.build +++ b/src/core/settings/plugins/ifupdown/meson.build @@ -7,14 +7,12 @@ libnms_ifupdown_core = static_library( 'nms-ifupdown-parser.c', ), dependencies: core_default_dep, - c_args: daemon_c_flags, ) libnm_settings_plugin_ifupdown = shared_module( 'nm-settings-plugin-ifupdown', sources: 'nms-ifupdown-plugin.c', dependencies: core_plugin_dep, - c_args: daemon_c_flags, link_with: libnms_ifupdown_core, link_args: ldflags_linker_script_settings, link_depends: linker_script_settings, diff --git a/src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c b/src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c index a4974a9..63c78f9 100644 --- a/src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c +++ b/src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c @@ -12,7 +12,7 @@ #include #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/nm-settings-plugin.h" #include "nms-ifupdown-plugin.h" diff --git a/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c b/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c index 34523f8..80a5638 100644 --- a/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c +++ b/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c @@ -9,7 +9,7 @@ #include "nms-ifupdown-plugin.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-core-utils.h" #include "nm-config.h" #include "settings/nm-settings-plugin.h" diff --git a/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c index 6e3eb0e..0e8db73 100644 --- a/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c +++ b/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c @@ -5,7 +5,7 @@ #include "src/core/nm-default-daemon.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/plugins/ifupdown/nms-ifupdown-interface-parser.h" #include "settings/plugins/ifupdown/nms-ifupdown-parser.h" diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-plugin.c b/src/core/settings/plugins/keyfile/nms-keyfile-plugin.c index 789bfc1..0b48660 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-plugin.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-plugin.c @@ -13,19 +13,19 @@ #include #include -#include "nm-std-aux/c-list-util.h" -#include "nm-glib-aux/nm-c-list.h" -#include "nm-glib-aux/nm-io-utils.h" +#include "libnm-std-aux/c-list-util.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-io-utils.h" #include "nm-connection.h" #include "nm-setting.h" #include "nm-setting-connection.h" #include "nm-utils.h" #include "nm-config.h" -#include "nm-core-internal.h" -#include "nm-keyfile-internal.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "settings/nm-settings-plugin.h" #include "settings/nm-settings-storage.h" diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-reader.c b/src/core/settings/plugins/keyfile/nms-keyfile-reader.c index 70b047f..8b9d982 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-reader.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-reader.c @@ -9,7 +9,7 @@ #include -#include "nm-keyfile-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" #include "NetworkManagerUtils.h" #include "nms-keyfile-utils.h" diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-storage.c b/src/core/settings/plugins/keyfile/nms-keyfile-storage.c index 89be817..c6b4b81 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-storage.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-storage.c @@ -8,7 +8,7 @@ #include "nms-keyfile-storage.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nms-keyfile-plugin.h" /*****************************************************************************/ diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-utils.c b/src/core/settings/plugins/keyfile/nms-keyfile-utils.c index f3dffda..c26b867 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-utils.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-utils.c @@ -10,8 +10,8 @@ #include #include -#include "nm-glib-aux/nm-io-utils.h" -#include "nm-keyfile-internal.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-core-intern/nm-keyfile-internal.h" #include "nm-utils.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-writer.c b/src/core/settings/plugins/keyfile/nms-keyfile-writer.c index 0e2c94b..661a828 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-writer.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-writer.c @@ -12,12 +12,12 @@ #include #include -#include "nm-keyfile-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" #include "nms-keyfile-utils.h" #include "nms-keyfile-reader.h" -#include "nm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" /*****************************************************************************/ diff --git a/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c b/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c index 348b0ed..5c5786b 100644 --- a/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c +++ b/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c @@ -15,7 +15,7 @@ #include #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/plugins/keyfile/nms-keyfile-reader.h" #include "settings/plugins/keyfile/nms-keyfile-writer.h" diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c index eab494b..a4bbb0e 100644 --- a/src/core/supplicant/nm-supplicant-config.c +++ b/src/core/supplicant/nm-supplicant-config.c @@ -10,11 +10,11 @@ #include -#include "nm-glib-aux/nm-str-buf.h" -#include "nm-core-internal.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-supplicant-settings-verify.h" #include "nm-setting.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" #include "nm-setting-ip4-config.h" @@ -815,7 +815,7 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig * nm_auto_free_gstring GString *key_mgmt_conf = NULL; const char * key_mgmt, *auth_alg; const char * psk; - gboolean set_pmf; + gboolean set_pmf, wps_disabled; g_return_val_if_fail(NM_IS_SUPPLICANT_CONFIG(self), FALSE); g_return_val_if_fail(setting != NULL, FALSE); @@ -841,6 +841,11 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig * g_string_append(key_mgmt_conf, " wpa-psk-sha256"); if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) g_string_append(key_mgmt_conf, " ft-psk"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_SAE)) { + g_string_append(key_mgmt_conf, " sae"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) + g_string_append(key_mgmt_conf, " ft-sae"); + } } else if (nm_streq(key_mgmt, "wpa-eap")) { if (_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF)) { g_string_append(key_mgmt_conf, " wpa-eap-sha256"); @@ -1102,6 +1107,13 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig * } } + wps_disabled = (nm_setting_wireless_security_get_wps_method(setting) + == NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DISABLED); + if (wps_disabled) { + if (!nm_supplicant_config_add_option(self, "wps_disabled", "1", 1, NULL, error)) + return FALSE; + } + return TRUE; } diff --git a/src/core/supplicant/nm-supplicant-interface.c b/src/core/supplicant/nm-supplicant-interface.c index 6d9c604..7cb3df9 100644 --- a/src/core/supplicant/nm-supplicant-interface.c +++ b/src/core/supplicant/nm-supplicant-interface.c @@ -12,13 +12,13 @@ #include #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" -#include "nm-glib-aux/nm-c-list.h" -#include "nm-glib-aux/nm-ref-string.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-supplicant-config.h" #include "nm-supplicant-manager.h" -#include "shared/nm-glib-aux/nm-dbus-aux.h" #define DBUS_TIMEOUT_MSEC 20000 @@ -557,7 +557,7 @@ _bss_info_properties_changed(NMSupplicantInterface *self, guint16 v_u16; guint32 v_u32; NM80211ApFlags p_ap_flags; - NM80211Mode p_mode; + _NM80211Mode p_mode; guint8 p_signal_percent; const guint8 * arr_data; gsize arr_len; @@ -605,15 +605,15 @@ _bss_info_properties_changed(NMSupplicantInterface *self, if (nm_g_variant_lookup(properties, "Mode", "&s", &v_s)) { if (nm_streq(v_s, "infrastructure")) - p_mode = NM_802_11_MODE_INFRA; + p_mode = _NM_802_11_MODE_INFRA; else if (nm_streq(v_s, "ad-hoc")) - p_mode = NM_802_11_MODE_ADHOC; + p_mode = _NM_802_11_MODE_ADHOC; else if (nm_streq(v_s, "mesh")) - p_mode = NM_802_11_MODE_MESH; + p_mode = _NM_802_11_MODE_MESH; else - p_mode = NM_802_11_MODE_UNKNOWN; + p_mode = _NM_802_11_MODE_UNKNOWN; } else if (initial) - p_mode = NM_802_11_MODE_UNKNOWN; + p_mode = _NM_802_11_MODE_UNKNOWN; else p_mode = bss_info->mode; if (bss_info->mode != p_mode) { @@ -1171,19 +1171,24 @@ parse_capabilities(NMSupplicantInterface *self, GVariant *capabilities) const gboolean old_prop_scan_ssid = priv->prop_scan_ssid; const guint32 old_max_scan_ssids = priv->max_scan_ssids; gboolean have_ft = FALSE; + gboolean have_sae = FALSE; gint32 max_scan_ssids; const char ** array; nm_assert(capabilities && g_variant_is_of_type(capabilities, G_VARIANT_TYPE_VARDICT)); if (g_variant_lookup(capabilities, "KeyMgmt", "^a&s", &array)) { - have_ft = g_strv_contains(array, "wpa-ft-psk"); + have_ft = g_strv_contains(array, "wpa-ft-psk"); + have_sae = g_strv_contains(array, "sae"); g_free(array); } priv->iface_capabilities = NM_SUPPL_CAP_MASK_SET(priv->iface_capabilities, NM_SUPPL_CAP_TYPE_FT, have_ft ? NM_TERNARY_TRUE : NM_TERNARY_FALSE); + priv->iface_capabilities = NM_SUPPL_CAP_MASK_SET(priv->iface_capabilities, + NM_SUPPL_CAP_TYPE_SAE, + have_sae ? NM_TERNARY_TRUE : NM_TERNARY_FALSE); if (g_variant_lookup(capabilities, "Modes", "^a&s", &array)) { /* Setting p2p_capable might toggle _prop_p2p_available_get(). However, @@ -1255,6 +1260,15 @@ _starting_check_ready(NMSupplicantInterface *self) return; } + _LOGD("interface supported features:" + " AP%c" + " FT%c" + " SAE%c" + "", + NM_SUPPL_CAP_TO_CHAR(priv->iface_capabilities, NM_SUPPL_CAP_TYPE_AP), + NM_SUPPL_CAP_TO_CHAR(priv->iface_capabilities, NM_SUPPL_CAP_TYPE_FT), + NM_SUPPL_CAP_TO_CHAR(priv->iface_capabilities, NM_SUPPL_CAP_TYPE_SAE)); + set_state(self, priv->supp_state); } @@ -1278,6 +1292,10 @@ _get_capability(NMSupplicantInterfacePrivate *priv, NMSupplCapType type) value = iface_value; } break; + case NM_SUPPL_CAP_TYPE_SAE: + nm_assert(NM_SUPPL_CAP_MASK_GET(priv->global_capabilities, type) == NM_TERNARY_DEFAULT); + value = NM_SUPPL_CAP_MASK_GET(priv->iface_capabilities, type); + break; default: nm_assert(NM_SUPPL_CAP_MASK_GET(priv->iface_capabilities, type) == NM_TERNARY_DEFAULT); value = NM_SUPPL_CAP_MASK_GET(priv->global_capabilities, type); @@ -1305,9 +1323,13 @@ nm_supplicant_interface_get_capabilities(NMSupplicantInterface *self) caps = NM_SUPPL_CAP_MASK_SET(caps, NM_SUPPL_CAP_TYPE_FT, _get_capability(priv, NM_SUPPL_CAP_TYPE_FT)); + caps = NM_SUPPL_CAP_MASK_SET(caps, + NM_SUPPL_CAP_TYPE_SAE, + _get_capability(priv, NM_SUPPL_CAP_TYPE_SAE)); nm_assert(!NM_FLAGS_ANY(priv->iface_capabilities, - ~(NM_SUPPL_CAP_MASK_T_AP_MASK | NM_SUPPL_CAP_MASK_T_FT_MASK))); + ~(NM_SUPPL_CAP_MASK_T_AP_MASK | NM_SUPPL_CAP_MASK_T_FT_MASK + | NM_SUPPL_CAP_MASK_T_SAE_MASK))); #if NM_MORE_ASSERTS > 10 { diff --git a/src/core/supplicant/nm-supplicant-manager.c b/src/core/supplicant/nm-supplicant-manager.c index 3255418..8db44c4 100644 --- a/src/core/supplicant/nm-supplicant-manager.c +++ b/src/core/supplicant/nm-supplicant-manager.c @@ -8,13 +8,13 @@ #include "nm-supplicant-manager.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-dbus-aux.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-supplicant-interface.h" #include "nm-supplicant-types.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" /*****************************************************************************/ @@ -168,19 +168,6 @@ _caps_set(NMSupplicantManagerPrivate *priv, NMSupplCapType type, NMTernary value priv->capabilities = NM_SUPPL_CAP_MASK_SET(priv->capabilities, type, value); } -static char -_caps_to_char(NMSupplicantManagerPrivate *priv, NMSupplCapType type) -{ - NMTernary val; - - val = NM_SUPPL_CAP_MASK_GET(priv->capabilities, type); - if (val == NM_TERNARY_TRUE) - return '+'; - if (val == NM_TERNARY_FALSE) - return '-'; - return '?'; -} - /*****************************************************************************/ static void @@ -1008,15 +995,15 @@ _dbus_get_capabilities_cb(GVariant *res, GError *error, gpointer user_data) " FAST%c" " WFD%c" "", - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_AP), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_PMF), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_FILS), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_P2P), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_FT), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_SHA384), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_MESH), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_FAST), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_WFD)); + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_AP), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_PMF), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_FILS), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_P2P), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_FT), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_SHA384), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_MESH), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_FAST), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_WFD)); nm_assert(g_hash_table_size(priv->supp_ifaces) == 0); nm_assert(c_list_is_empty(&priv->supp_lst_head)); diff --git a/src/core/supplicant/nm-supplicant-settings-verify.c b/src/core/supplicant/nm-supplicant-settings-verify.c index 3f0a33e..5e77b20 100644 --- a/src/core/supplicant/nm-supplicant-settings-verify.c +++ b/src/core/supplicant/nm-supplicant-settings-verify.c @@ -144,6 +144,7 @@ static const struct Opt opt_table[] = { OPT_BYTES("wep_key2", 0), OPT_BYTES("wep_key3", 0), OPT_INT("wep_tx_keyidx", 0, 3), + OPT_INT("wps_disabled", 0, 1), }; static gboolean diff --git a/src/core/supplicant/nm-supplicant-types.h b/src/core/supplicant/nm-supplicant-types.h index adcf02d..58ec90c 100644 --- a/src/core/supplicant/nm-supplicant-types.h +++ b/src/core/supplicant/nm-supplicant-types.h @@ -7,6 +7,7 @@ #define __NETWORKMANAGER_SUPPLICANT_TYPES_H__ #include "c-list/src/c-list.h" +#include "libnm-base/nm-base.h" #define NM_WPAS_DBUS_SERVICE "fi.w1.wpa_supplicant1" #define NM_WPAS_DBUS_PATH "/fi/w1/wpa_supplicant1" @@ -41,6 +42,7 @@ typedef enum { NM_SUPPL_CAP_TYPE_FILS, NM_SUPPL_CAP_TYPE_P2P, NM_SUPPL_CAP_TYPE_FT, + NM_SUPPL_CAP_TYPE_SAE, NM_SUPPL_CAP_TYPE_SHA384, NM_SUPPL_CAP_TYPE_MESH, NM_SUPPL_CAP_TYPE_FAST, @@ -71,6 +73,7 @@ typedef enum { _NM_SUPPL_CAP_MASK_DEFINE(MESH), _NM_SUPPL_CAP_MASK_DEFINE(WFD), _NM_SUPPL_CAP_MASK_DEFINE(FT), + _NM_SUPPL_CAP_MASK_DEFINE(SAE), _NM_SUPPL_CAP_MASK_DEFINE(SHA384), #undef _NM_SUPPL_CAP_MASK_DEFINE } NMSupplCapMask; @@ -114,6 +117,19 @@ NM_SUPPL_CAP_MASK_GET(NMSupplCapMask features, NMSupplCapType type) return (NMTernary)(f - 1); } +static inline char +NM_SUPPL_CAP_TO_CHAR(NMSupplCapMask features, NMSupplCapType type) +{ + NMTernary val; + + val = NM_SUPPL_CAP_MASK_GET(features, type); + if (val == NM_TERNARY_TRUE) + return '+'; + if (val == NM_TERNARY_FALSE) + return '-'; + return '?'; +} + /*****************************************************************************/ /** @@ -163,7 +179,7 @@ typedef struct _NMSupplicantBssInfo { NM80211ApFlags ap_flags : 5; - NM80211Mode mode : 4; + _NM80211Mode mode : 4; bool bssid_valid : 1; diff --git a/src/core/supplicant/tests/test-supplicant-config.c b/src/core/supplicant/tests/test-supplicant-config.c index 99729c1..2c2d947 100644 --- a/src/core/supplicant/tests/test-supplicant-config.c +++ b/src/core/supplicant/tests/test-supplicant-config.c @@ -14,7 +14,7 @@ #include #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "supplicant/nm-supplicant-config.h" #include "supplicant/nm-supplicant-settings-verify.h" diff --git a/src/core/systemd/meson.build b/src/core/systemd/meson.build index 70f6b54..2de6077 100644 --- a/src/core/systemd/meson.build +++ b/src/core/systemd/meson.build @@ -38,25 +38,27 @@ libnm_systemd_core = static_library( ), include_directories: [ incs, + top_inc, src_inc, + src_core_inc, ], dependencies: [ - glib_nm_default_dep, - libnm_core_dep, - libnm_systemd_shared_dep, - ], - c_args: [ - '-DG_LOG_DOMAIN="NetworkManager"', + libnm_core_public_dep, + libnm_systemd_shared_dep_inc, + glib_dep, ], - link_with: libc_siphash, ) libnm_systemd_core_dep = declare_dependency( - include_directories: incs, + include_directories: [ + incs, + ], dependencies: [ glib_dep, - libnm_core_dep, - libnm_systemd_shared_dep, ], - link_with: libnm_systemd_core, + link_with: [ + libnm_core_impl, + libnm_systemd_shared, + libnm_systemd_core, + ], ) diff --git a/src/core/systemd/nm-sd-utils-core.c b/src/core/systemd/nm-sd-utils-core.c index af68603..b81e36f 100644 --- a/src/core/systemd/nm-sd-utils-core.c +++ b/src/core/systemd/nm-sd-utils-core.c @@ -7,7 +7,7 @@ #include "nm-sd-utils-core.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-sd-adapt-core.h" diff --git a/src/core/systemd/sd-adapt-core/nm-sd-adapt-core.h b/src/core/systemd/sd-adapt-core/nm-sd-adapt-core.h index f627d7d..ceedfdb 100644 --- a/src/core/systemd/sd-adapt-core/nm-sd-adapt-core.h +++ b/src/core/systemd/sd-adapt-core/nm-sd-adapt-core.h @@ -13,7 +13,7 @@ #include #undef NETWORKMANAGER_COMPILATION -#include "systemd/sd-adapt-shared/nm-sd-adapt-shared.h" +#include "libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h" #undef NETWORKMANAGER_COMPILATION #define NETWORKMANAGER_COMPILATION NM_NETWORKMANAGER_COMPILATION_SYSTEMD diff --git a/src/core/tests/meson.build b/src/core/tests/meson.build index 994563c..5415bb2 100644 --- a/src/core/tests/meson.build +++ b/src/core/tests/meson.build @@ -35,13 +35,15 @@ exe = executable( include_directories: [ top_inc, src_inc, + src_core_inc, ], dependencies: [ + libnm_core_public_dep, libnm_systemd_core_dep, - libnm_systemd_shared_dep, ], - c_args: [ - '-DG_LOG_DOMAIN="test"', + link_with: [ + libnm_systemd_shared, + libc_siphash, ], ) diff --git a/src/core/tests/test-core-with-expect.c b/src/core/tests/test-core-with-expect.c index 022cf8f..0178486 100644 --- a/src/core/tests/test-core-with-expect.c +++ b/src/core/tests/test-core-with-expect.c @@ -11,6 +11,7 @@ #include #include "NetworkManagerUtils.h" +#include "libnm-platform/nm-platform-utils.h" #include "nm-test-utils-core.h" @@ -586,7 +587,7 @@ test_nm_ethernet_address_is_valid(void) /*****************************************************************************/ static void -test_nm_utils_new_vlan_name(void) +test_nmp_utils_new_vlan_name(void) { guint i, j; const char *parent_names[] = { @@ -614,7 +615,7 @@ test_nm_utils_new_vlan_name(void) vlan_id_s = g_strdup_printf(".%d", vlan_id); - ifname = nm_utils_new_vlan_name(parent_names[i], vlan_id); + ifname = nmp_utils_new_vlan_name(parent_names[i], vlan_id); g_assert(ifname && ifname[0]); g_assert_cmpint(strlen(ifname), ==, @@ -643,7 +644,7 @@ main(int argc, char **argv) g_test_add_func("/general/nm_utils_array_remove_at_indexes", test_nm_utils_array_remove_at_indexes); g_test_add_func("/general/nm_ethernet_address_is_valid", test_nm_ethernet_address_is_valid); - g_test_add_func("/general/nm_utils_new_vlan_name", test_nm_utils_new_vlan_name); + g_test_add_func("/general/nmp_utils_new_vlan_name", test_nmp_utils_new_vlan_name); return g_test_run(); } diff --git a/src/core/tests/test-core.c b/src/core/tests/test-core.c index 8698c40..f212886 100644 --- a/src/core/tests/test-core.c +++ b/src/core/tests/test-core.c @@ -12,7 +12,7 @@ #include #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-core-utils.h" #include "systemd/nm-sd-utils-core.h" @@ -867,7 +867,7 @@ test_connection_no_match_vlan(void) /* Check that the connections do not match if VLAN flags differ */ s_vlan_orig = nm_connection_get_setting_vlan(orig); g_assert(s_vlan_orig); - g_object_set(G_OBJECT(s_vlan_orig), NM_SETTING_VLAN_FLAGS, NM_VLAN_FLAG_REORDER_HEADERS, NULL); + g_object_set(G_OBJECT(s_vlan_orig), NM_SETTING_VLAN_FLAGS, _NM_VLAN_FLAG_REORDER_HEADERS, NULL); s_vlan_copy = nm_connection_get_setting_vlan(copy); g_assert(s_vlan_copy); diff --git a/src/core/tests/test-ip4-config.c b/src/core/tests/test-ip4-config.c index 27b1d61..3a095d4 100644 --- a/src/core/tests/test-ip4-config.c +++ b/src/core/tests/test-ip4-config.c @@ -8,7 +8,7 @@ #include #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-test-utils-core.h" diff --git a/src/core/tests/test-ip6-config.c b/src/core/tests/test-ip6-config.c index 3b48fb7..ddf4c78 100644 --- a/src/core/tests/test-ip6-config.c +++ b/src/core/tests/test-ip6-config.c @@ -10,7 +10,7 @@ #include "nm-ip6-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-test-utils-core.h" static NMIP6Config * diff --git a/src/core/tests/test-l3cfg.c b/src/core/tests/test-l3cfg.c index 43132c6..f2af928 100644 --- a/src/core/tests/test-l3cfg.c +++ b/src/core/tests/test-l3cfg.c @@ -5,7 +5,7 @@ #include "nm-l3cfg.h" #include "nm-l3-ipv4ll.h" #include "nm-netns.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "platform/tests/test-common.h" diff --git a/src/core/tests/test-systemd.c b/src/core/tests/test-systemd.c index 03576c1..c6711f0 100644 --- a/src/core/tests/test-systemd.c +++ b/src/core/tests/test-systemd.c @@ -6,7 +6,7 @@ #include "src/core/systemd/nm-default-systemd.h" #include "systemd/nm-sd.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "nm-test-utils-core.h" diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c index 02831b0..ba5e36d 100644 --- a/src/core/vpn/nm-vpn-connection.c +++ b/src/core/vpn/nm-vpn-connection.c @@ -19,14 +19,14 @@ #include "nm-proxy-config.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-active-connection.h" #include "NetworkManagerUtils.h" #include "settings/nm-settings-connection.h" #include "nm-dispatcher.h" #include "nm-netns.h" #include "settings/nm-agent-manager.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-pacrunner-manager.h" #include "nm-firewall-manager.h" #include "nm-config.h" diff --git a/src/core/vpn/nm-vpn-connection.h b/src/core/vpn/nm-vpn-connection.h index 66ec7ee..0209ea3 100644 --- a/src/core/vpn/nm-vpn-connection.h +++ b/src/core/vpn/nm-vpn-connection.h @@ -9,7 +9,7 @@ #include "nm-vpn-dbus-interface.h" #include "devices/nm-device.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "nm-active-connection.h" #include "nm-vpn-plugin-info.h" diff --git a/src/core/vpn/nm-vpn-manager.c b/src/core/vpn/nm-vpn-manager.c index 53fe58d..f30dba7 100644 --- a/src/core/vpn/nm-vpn-manager.c +++ b/src/core/vpn/nm-vpn-manager.c @@ -12,7 +12,7 @@ #include "nm-vpn-connection.h" #include "nm-setting-vpn.h" #include "nm-vpn-dbus-interface.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" typedef struct { GSList * plugins; diff --git a/src/libnm-base/meson.build b/src/libnm-base/meson.build new file mode 100644 index 0000000..d7e7a1b --- /dev/null +++ b/src/libnm-base/meson.build @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_base = static_library( + 'nm-base', + sources: files( + 'nm-ethtool-base.c', + 'nm-net-aux.c', + ), + include_directories: [ + src_inc, + top_inc, + ], + dependencies: glib_dep, +) diff --git a/src/libnm-base/nm-base.h b/src/libnm-base/nm-base.h new file mode 100644 index 0000000..3f0ca02 --- /dev/null +++ b/src/libnm-base/nm-base.h @@ -0,0 +1,373 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_LIBNM_BASE_H__ +#define __NM_LIBNM_BASE_H__ + +/*****************************************************************************/ + +/* this must be the same as NM_UTILS_HWADDR_LEN_MAX from libnm. */ +#define _NM_UTILS_HWADDR_LEN_MAX 20 + +/*****************************************************************************/ + +typedef enum { + NM_ETHTOOL_ID_UNKNOWN = -1, + + _NM_ETHTOOL_ID_FIRST = 0, + + _NM_ETHTOOL_ID_COALESCE_FIRST = _NM_ETHTOOL_ID_FIRST, + NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX = _NM_ETHTOOL_ID_COALESCE_FIRST, + NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX, + NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH, + NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW, + NM_ETHTOOL_ID_COALESCE_RX_FRAMES, + NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH, + NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ, + NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW, + NM_ETHTOOL_ID_COALESCE_RX_USECS, + NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH, + NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ, + NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW, + NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL, + NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS, + NM_ETHTOOL_ID_COALESCE_TX_FRAMES, + NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH, + NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ, + NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW, + NM_ETHTOOL_ID_COALESCE_TX_USECS, + NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH, + NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ, + NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW, + _NM_ETHTOOL_ID_COALESCE_LAST = NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW, + + _NM_ETHTOOL_ID_FEATURE_FIRST = _NM_ETHTOOL_ID_COALESCE_LAST + 1, + NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD = _NM_ETHTOOL_ID_FEATURE_FIRST, + NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_FCOE_MTU, + NM_ETHTOOL_ID_FEATURE_GRO, + NM_ETHTOOL_ID_FEATURE_GSO, + NM_ETHTOOL_ID_FEATURE_HIGHDMA, + NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_LOOPBACK, + NM_ETHTOOL_ID_FEATURE_LRO, + NM_ETHTOOL_ID_FEATURE_MACSEC_HW_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_NTUPLE, + NM_ETHTOOL_ID_FEATURE_RX, + NM_ETHTOOL_ID_FEATURE_RXHASH, + NM_ETHTOOL_ID_FEATURE_RXVLAN, + NM_ETHTOOL_ID_FEATURE_RX_ALL, + NM_ETHTOOL_ID_FEATURE_RX_FCS, + NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, + NM_ETHTOOL_ID_FEATURE_RX_GRO_LIST, + NM_ETHTOOL_ID_FEATURE_RX_UDP_GRO_FORWARDING, + NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, + NM_ETHTOOL_ID_FEATURE_SG, + NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, + NM_ETHTOOL_ID_FEATURE_TLS_HW_RX_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_TSO, + NM_ETHTOOL_ID_FEATURE_TX, + NM_ETHTOOL_ID_FEATURE_TXVLAN, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, + NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GSO_LIST, + NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, + NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, + NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, + NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, + NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, + NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TUNNEL_REMCSUM_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, + _NM_ETHTOOL_ID_FEATURE_LAST = NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, + + _NM_ETHTOOL_ID_RING_FIRST = _NM_ETHTOOL_ID_FEATURE_LAST + 1, + NM_ETHTOOL_ID_RING_RX = _NM_ETHTOOL_ID_RING_FIRST, + NM_ETHTOOL_ID_RING_RX_JUMBO, + NM_ETHTOOL_ID_RING_RX_MINI, + NM_ETHTOOL_ID_RING_TX, + _NM_ETHTOOL_ID_RING_LAST = NM_ETHTOOL_ID_RING_TX, + + _NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_RING_LAST, + + _NM_ETHTOOL_ID_COALESCE_NUM = + (_NM_ETHTOOL_ID_COALESCE_LAST - _NM_ETHTOOL_ID_COALESCE_FIRST + 1), + _NM_ETHTOOL_ID_FEATURE_NUM = (_NM_ETHTOOL_ID_FEATURE_LAST - _NM_ETHTOOL_ID_FEATURE_FIRST + 1), + _NM_ETHTOOL_ID_RING_NUM = (_NM_ETHTOOL_ID_RING_LAST - _NM_ETHTOOL_ID_RING_FIRST + 1), + _NM_ETHTOOL_ID_NUM = (_NM_ETHTOOL_ID_LAST - _NM_ETHTOOL_ID_FIRST + 1), +} NMEthtoolID; + +#define _NM_ETHTOOL_ID_FEATURE_AS_IDX(ethtool_id) ((ethtool_id) -_NM_ETHTOOL_ID_FEATURE_FIRST) +#define _NM_ETHTOOL_ID_COALESCE_AS_IDX(ethtool_id) ((ethtool_id) -_NM_ETHTOOL_ID_COALESCE_FIRST) + +typedef enum { + NM_ETHTOOL_TYPE_UNKNOWN, + NM_ETHTOOL_TYPE_COALESCE, + NM_ETHTOOL_TYPE_FEATURE, + NM_ETHTOOL_TYPE_RING, +} NMEthtoolType; + +/****************************************************************************/ + +static inline gboolean +nm_ethtool_id_is_feature(NMEthtoolID id) +{ + return id >= _NM_ETHTOOL_ID_FEATURE_FIRST && id <= _NM_ETHTOOL_ID_FEATURE_LAST; +} + +static inline gboolean +nm_ethtool_id_is_coalesce(NMEthtoolID id) +{ + return id >= _NM_ETHTOOL_ID_COALESCE_FIRST && id <= _NM_ETHTOOL_ID_COALESCE_LAST; +} + +static inline gboolean +nm_ethtool_id_is_ring(NMEthtoolID id) +{ + return id >= _NM_ETHTOOL_ID_RING_FIRST && id <= _NM_ETHTOOL_ID_RING_LAST; +} + +/*****************************************************************************/ + +typedef enum { + /* Mirrors libnm's NMSettingWiredWakeOnLan */ + _NM_SETTING_WIRED_WAKE_ON_LAN_NONE = 0, + _NM_SETTING_WIRED_WAKE_ON_LAN_PHY = 0x2, + _NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST = 0x4, + _NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST = 0x8, + _NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST = 0x10, + _NM_SETTING_WIRED_WAKE_ON_LAN_ARP = 0x20, + _NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC = 0x40, + + _NM_SETTING_WIRED_WAKE_ON_LAN_ALL = 0x7E, + + _NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT = 0x1, + _NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE = 0x8000, + _NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS = 0x8001, +} _NMSettingWiredWakeOnLan; + +typedef enum { + /* Mirrors libnm's NMSettingWirelessWakeOnWLan */ + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE = 0, + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY = 0x2, + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT = 0x4, + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC = 0x8, + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE = 0x10, + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST = 0x20, + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE = 0x40, + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE = 0x80, + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP = 0x100, + + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL = 0x1FE, + + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT = 0x1, + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE = 0x8000, + + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS = + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT | _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE, +} _NMSettingWirelessWakeOnWLan; + +typedef enum { + /* Mirrors libnm's NMDeviceWifiCapabilities */ + _NM_WIFI_DEVICE_CAP_NONE = 0x00000000, + _NM_WIFI_DEVICE_CAP_CIPHER_WEP40 = 0x00000001, + _NM_WIFI_DEVICE_CAP_CIPHER_WEP104 = 0x00000002, + _NM_WIFI_DEVICE_CAP_CIPHER_TKIP = 0x00000004, + _NM_WIFI_DEVICE_CAP_CIPHER_CCMP = 0x00000008, + _NM_WIFI_DEVICE_CAP_WPA = 0x00000010, + _NM_WIFI_DEVICE_CAP_RSN = 0x00000020, + _NM_WIFI_DEVICE_CAP_AP = 0x00000040, + _NM_WIFI_DEVICE_CAP_ADHOC = 0x00000080, + _NM_WIFI_DEVICE_CAP_FREQ_VALID = 0x00000100, + _NM_WIFI_DEVICE_CAP_FREQ_2GHZ = 0x00000200, + _NM_WIFI_DEVICE_CAP_FREQ_5GHZ = 0x00000400, + _NM_WIFI_DEVICE_CAP_MESH = 0x00001000, + _NM_WIFI_DEVICE_CAP_IBSS_RSN = 0x00002000, +} _NMDeviceWifiCapabilities; + +typedef enum { + /* Mirrors libnm's NM80211Mode */ + _NM_802_11_MODE_UNKNOWN = 0, + _NM_802_11_MODE_ADHOC = 1, + _NM_802_11_MODE_INFRA = 2, + _NM_802_11_MODE_AP = 3, + _NM_802_11_MODE_MESH = 4, +} _NM80211Mode; + +typedef enum { + /* Mirrors libnm's NMVlanFlags */ + _NM_VLAN_FLAG_REORDER_HEADERS = 0x1, + _NM_VLAN_FLAG_GVRP = 0x2, + _NM_VLAN_FLAG_LOOSE_BINDING = 0x4, + _NM_VLAN_FLAG_MVRP = 0x8, + + _NM_VLAN_FLAGS_ALL = _NM_VLAN_FLAG_REORDER_HEADERS | _NM_VLAN_FLAG_GVRP + | _NM_VLAN_FLAG_LOOSE_BINDING | _NM_VLAN_FLAG_MVRP, +} _NMVlanFlags; + +/*****************************************************************************/ + +typedef enum { + /* In priority order; higher number == higher priority */ + + NM_IP_CONFIG_SOURCE_UNKNOWN = 0, + + /* for routes, the source is mapped to the uint8 field rtm_protocol. + * Reserve the range [1,0x100] for native RTPROT values. */ + + NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC = 1 + 0, + NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT = 1 + 1, + NM_IP_CONFIG_SOURCE_RTPROT_KERNEL = 1 + 2, + NM_IP_CONFIG_SOURCE_RTPROT_BOOT = 1 + 3, + NM_IP_CONFIG_SOURCE_RTPROT_STATIC = 1 + 4, + NM_IP_CONFIG_SOURCE_RTPROT_RA = 1 + 9, + NM_IP_CONFIG_SOURCE_RTPROT_DHCP = 1 + 16, + _NM_IP_CONFIG_SOURCE_RTPROT_LAST = 1 + 0xFF, + + NM_IP_CONFIG_SOURCE_KERNEL, + NM_IP_CONFIG_SOURCE_SHARED, + NM_IP_CONFIG_SOURCE_IP4LL, + NM_IP_CONFIG_SOURCE_IP6LL, + NM_IP_CONFIG_SOURCE_PPP, + NM_IP_CONFIG_SOURCE_WWAN, + NM_IP_CONFIG_SOURCE_VPN, + NM_IP_CONFIG_SOURCE_DHCP, + NM_IP_CONFIG_SOURCE_NDISC, + NM_IP_CONFIG_SOURCE_USER, +} NMIPConfigSource; + +static inline gboolean +NM_IS_IP_CONFIG_SOURCE_RTPROT(NMIPConfigSource source) +{ + return source > NM_IP_CONFIG_SOURCE_UNKNOWN && source <= _NM_IP_CONFIG_SOURCE_RTPROT_LAST; +} + +/*****************************************************************************/ + +/* IEEE 802.1D-1998 timer values */ +#define NM_BRIDGE_HELLO_TIME_MIN 1u +#define NM_BRIDGE_HELLO_TIME_DEF 2u +#define NM_BRIDGE_HELLO_TIME_DEF_SYS (NM_BRIDGE_HELLO_TIME_DEF * 100u) +#define NM_BRIDGE_HELLO_TIME_MAX 10u + +#define NM_BRIDGE_FORWARD_DELAY_MIN 2u +#define NM_BRIDGE_FORWARD_DELAY_DEF 15u +#define NM_BRIDGE_FORWARD_DELAY_DEF_SYS (NM_BRIDGE_FORWARD_DELAY_DEF * 100u) +#define NM_BRIDGE_FORWARD_DELAY_MAX 30u + +#define NM_BRIDGE_MAX_AGE_MIN 6u +#define NM_BRIDGE_MAX_AGE_DEF 20u +#define NM_BRIDGE_MAX_AGE_DEF_SYS (NM_BRIDGE_MAX_AGE_DEF * 100u) +#define NM_BRIDGE_MAX_AGE_MAX 40u + +/* IEEE 802.1D-1998 Table 7.4 */ +#define NM_BRIDGE_AGEING_TIME_MIN 0u +#define NM_BRIDGE_AGEING_TIME_DEF 300u +#define NM_BRIDGE_AGEING_TIME_DEF_SYS (NM_BRIDGE_AGEING_TIME_DEF * 100u) +#define NM_BRIDGE_AGEING_TIME_MAX 1000000u + +#define NM_BRIDGE_PORT_PRIORITY_MIN 0u +#define NM_BRIDGE_PORT_PRIORITY_DEF 32u +#define NM_BRIDGE_PORT_PRIORITY_MAX 63u + +#define NM_BRIDGE_PORT_PATH_COST_MIN 0u +#define NM_BRIDGE_PORT_PATH_COST_DEF 100u +#define NM_BRIDGE_PORT_PATH_COST_MAX 65535u + +#define NM_BRIDGE_MULTICAST_HASH_MAX_MIN 1u +#define NM_BRIDGE_MULTICAST_HASH_MAX_DEF 4096u +#define NM_BRIDGE_MULTICAST_HASH_MAX_MAX ((guint) G_MAXUINT32) + +#define NM_BRIDGE_STP_DEF TRUE + +#define NM_BRIDGE_GROUP_ADDRESS_DEF_BIN 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 +#define NM_BRIDGE_GROUP_ADDRESS_DEF_STR "01:80:C2:00:00:00" + +#define NM_BRIDGE_PRIORITY_MIN 0u +#define NM_BRIDGE_PRIORITY_DEF 0x8000u +#define NM_BRIDGE_PRIORITY_MAX ((guint) G_MAXUINT16) + +#define NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_MIN 0u +#define NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF 2u +#define NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_MAX ((guint) G_MAXUINT32) + +#define NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_MIN ((guint64) 0) +#define NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF ((guint64) 100) +#define NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_MAX G_MAXUINT64 + +#define NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_MIN ((guint64) 0) +#define NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF ((guint64) 26000) +#define NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_MAX G_MAXUINT64 + +#define NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_MIN ((guint64) 0) +#define NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF ((guint64) 25500) +#define NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_MAX G_MAXUINT64 + +#define NM_BRIDGE_MULTICAST_QUERIER_DEF FALSE + +#define NM_BRIDGE_MULTICAST_QUERY_INTERVAL_MIN ((guint64) 0) +#define NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF ((guint64) 12500) +#define NM_BRIDGE_MULTICAST_QUERY_INTERVAL_MAX G_MAXUINT64 + +#define NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_MIN ((guint64) 0) +#define NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF ((guint64) 1000) +#define NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_MAX G_MAXUINT64 + +#define NM_BRIDGE_MULTICAST_QUERY_USE_IFADDR_DEF FALSE + +#define NM_BRIDGE_MULTICAST_SNOOPING_DEF TRUE + +#define NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_MIN 0u +#define NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF 2u +#define NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_MAX ((guint) G_MAXUINT32) + +#define NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_MIN ((guint64) 0) +#define NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF ((guint64) 3125) +#define NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_MAX G_MAXUINT64 + +#define NM_BRIDGE_VLAN_STATS_ENABLED_DEF FALSE + +#define NM_BRIDGE_VLAN_DEFAULT_PVID_DEF 1u + +/*****************************************************************************/ + +typedef struct { + guint32 from; + guint32 to; +} NMVlanQosMapping; + +#define _NM_IP_TUNNEL_FLAG_ALL_IP6TNL \ + (NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT | NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS \ + | NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL | NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV \ + | NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY | NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK) + +/****************************************************************************/ + +#define NM_IW_ESSID_MAX_SIZE 32 + +/****************************************************************************/ + +#endif /* __NM_LIBNM_BASE_H__ */ diff --git a/src/libnm-base/nm-config-base.h b/src/libnm-base/nm-config-base.h new file mode 100644 index 0000000..6a2bab1 --- /dev/null +++ b/src/libnm-base/nm-config-base.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_CONFIG_BASE_H__ +#define __NM_CONFIG_BASE_H__ + +#define NM_CONFIG_KEYFILE_LIST_SEPARATOR ',' + +#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN ".intern." +#define NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION "connection" +#define NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE "device" +#define NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN "global-dns-domain-" +#define NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST ".test-append-stringlist" + +#define NM_CONFIG_KEYFILE_GROUP_MAIN "main" +#define NM_CONFIG_KEYFILE_GROUP_LOGGING "logging" +#define NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY "connectivity" +#define NM_CONFIG_KEYFILE_GROUP_KEYFILE "keyfile" +#define NM_CONFIG_KEYFILE_GROUP_IFUPDOWN "ifupdown" +#define NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS "global-dns" +#define NM_CONFIG_KEYFILE_GROUP_CONFIG ".config" + +#define NM_CONFIG_KEYFILE_KEY_MAIN_ASSUME_IPV6LL_ONLY "assume-ipv6ll-only" +#define NM_CONFIG_KEYFILE_KEY_MAIN_AUTH_POLKIT "auth-polkit" +#define NM_CONFIG_KEYFILE_KEY_MAIN_AUTOCONNECT_RETRIES_DEFAULT "autoconnect-retries-default" +#define NM_CONFIG_KEYFILE_KEY_MAIN_CONFIGURE_AND_QUIT "configure-and-quit" +#define NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG "debug" +#define NM_CONFIG_KEYFILE_KEY_MAIN_DHCP "dhcp" +#define NM_CONFIG_KEYFILE_KEY_MAIN_DNS "dns" +#define NM_CONFIG_KEYFILE_KEY_MAIN_HOSTNAME_MODE "hostname-mode" +#define NM_CONFIG_KEYFILE_KEY_MAIN_IGNORE_CARRIER "ignore-carrier" +#define NM_CONFIG_KEYFILE_KEY_MAIN_MONITOR_CONNECTION_FILES "monitor-connection-files" +#define NM_CONFIG_KEYFILE_KEY_MAIN_NO_AUTO_DEFAULT "no-auto-default" +#define NM_CONFIG_KEYFILE_KEY_MAIN_PLUGINS "plugins" +#define NM_CONFIG_KEYFILE_KEY_MAIN_RC_MANAGER "rc-manager" +#define NM_CONFIG_KEYFILE_KEY_MAIN_SLAVES_ORDER "slaves-order" +#define NM_CONFIG_KEYFILE_KEY_MAIN_SYSTEMD_RESOLVED "systemd-resolved" +#define NM_CONFIG_KEYFILE_KEY_MAIN_IWD_CONFIG_PATH "iwd-config-path" + +#define NM_CONFIG_KEYFILE_KEY_LOGGING_AUDIT "audit" +#define NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND "backend" +#define NM_CONFIG_KEYFILE_KEY_LOGGING_DOMAINS "domains" +#define NM_CONFIG_KEYFILE_KEY_LOGGING_LEVEL "level" + +#define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_ENABLED "enabled" +#define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_INTERVAL "interval" +#define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_RESPONSE "response" +#define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_URI "uri" + +#define NM_CONFIG_KEYFILE_KEY_KEYFILE_PATH "path" +#define NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES "unmanaged-devices" +#define NM_CONFIG_KEYFILE_KEY_KEYFILE_HOSTNAME "hostname" + +#define NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED "managed" + +#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_SEARCHES "searches" +#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_OPTIONS "options" + +#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_DOMAIN_SERVERS "servers" +#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_DOMAIN_OPTIONS "options" + +#define NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED "managed" +#define NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER "ignore-carrier" +#define NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS "sriov-num-vfs" +#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_BACKEND "wifi.backend" +#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_RAND_MAC_ADDRESS "wifi.scan-rand-mac-address" +#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_GENERATE_MAC_ADDRESS_MASK \ + "wifi.scan-generate-mac-address-mask" +#define NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT "carrier-wait-timeout" +#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_IWD_AUTOCONNECT "wifi.iwd.autoconnect" + +#define NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE "match-device" +#define NM_CONFIG_KEYFILE_KEY_STOP_MATCH "stop-match" + +#define NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS ".was" /* check-config-options skip */ +#define NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE "enable" /* check-config-options skip */ + +#define NM_CONFIG_KEYFILE_KEYPREFIX_WAS ".was." +#define NM_CONFIG_KEYFILE_KEYPREFIX_SET ".set." + +#define NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS \ + NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS +#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN \ + NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN + +#endif /* __NM_CONFIG_BASE_H__ */ diff --git a/src/libnm-base/nm-ethtool-base.c b/src/libnm-base/nm-ethtool-base.c new file mode 100644 index 0000000..03cbf56 --- /dev/null +++ b/src/libnm-base/nm-ethtool-base.c @@ -0,0 +1,288 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-ethtool-base.h" + +#include "nm-ethtool-utils-base.h" + +/*****************************************************************************/ + +#define ETHT_DATA(xname) \ + [NM_ETHTOOL_ID_##xname] = (&((const NMEthtoolData){ \ + .optname = NM_ETHTOOL_OPTNAME_##xname, \ + .id = NM_ETHTOOL_ID_##xname, \ + })) + +const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1] = { + /* indexed by NMEthtoolID */ + ETHT_DATA(COALESCE_ADAPTIVE_RX), + ETHT_DATA(COALESCE_ADAPTIVE_TX), + ETHT_DATA(COALESCE_PKT_RATE_HIGH), + ETHT_DATA(COALESCE_PKT_RATE_LOW), + ETHT_DATA(COALESCE_RX_FRAMES), + ETHT_DATA(COALESCE_RX_FRAMES_HIGH), + ETHT_DATA(COALESCE_RX_FRAMES_IRQ), + ETHT_DATA(COALESCE_RX_FRAMES_LOW), + ETHT_DATA(COALESCE_RX_USECS), + ETHT_DATA(COALESCE_RX_USECS_HIGH), + ETHT_DATA(COALESCE_RX_USECS_IRQ), + ETHT_DATA(COALESCE_RX_USECS_LOW), + ETHT_DATA(COALESCE_SAMPLE_INTERVAL), + ETHT_DATA(COALESCE_STATS_BLOCK_USECS), + ETHT_DATA(COALESCE_TX_FRAMES), + ETHT_DATA(COALESCE_TX_FRAMES_HIGH), + ETHT_DATA(COALESCE_TX_FRAMES_IRQ), + ETHT_DATA(COALESCE_TX_FRAMES_LOW), + ETHT_DATA(COALESCE_TX_USECS), + ETHT_DATA(COALESCE_TX_USECS_HIGH), + ETHT_DATA(COALESCE_TX_USECS_IRQ), + ETHT_DATA(COALESCE_TX_USECS_LOW), + ETHT_DATA(FEATURE_ESP_HW_OFFLOAD), + ETHT_DATA(FEATURE_ESP_TX_CSUM_HW_OFFLOAD), + ETHT_DATA(FEATURE_FCOE_MTU), + ETHT_DATA(FEATURE_GRO), + ETHT_DATA(FEATURE_GSO), + ETHT_DATA(FEATURE_HIGHDMA), + ETHT_DATA(FEATURE_HW_TC_OFFLOAD), + ETHT_DATA(FEATURE_L2_FWD_OFFLOAD), + ETHT_DATA(FEATURE_LOOPBACK), + ETHT_DATA(FEATURE_LRO), + ETHT_DATA(FEATURE_MACSEC_HW_OFFLOAD), + ETHT_DATA(FEATURE_NTUPLE), + ETHT_DATA(FEATURE_RX), + ETHT_DATA(FEATURE_RXHASH), + ETHT_DATA(FEATURE_RXVLAN), + ETHT_DATA(FEATURE_RX_ALL), + ETHT_DATA(FEATURE_RX_FCS), + ETHT_DATA(FEATURE_RX_GRO_HW), + ETHT_DATA(FEATURE_RX_GRO_LIST), + ETHT_DATA(FEATURE_RX_UDP_GRO_FORWARDING), + ETHT_DATA(FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD), + ETHT_DATA(FEATURE_RX_VLAN_FILTER), + ETHT_DATA(FEATURE_RX_VLAN_STAG_FILTER), + ETHT_DATA(FEATURE_RX_VLAN_STAG_HW_PARSE), + ETHT_DATA(FEATURE_SG), + ETHT_DATA(FEATURE_TLS_HW_RECORD), + ETHT_DATA(FEATURE_TLS_HW_RX_OFFLOAD), + ETHT_DATA(FEATURE_TLS_HW_TX_OFFLOAD), + ETHT_DATA(FEATURE_TSO), + ETHT_DATA(FEATURE_TX), + ETHT_DATA(FEATURE_TXVLAN), + ETHT_DATA(FEATURE_TX_CHECKSUM_FCOE_CRC), + ETHT_DATA(FEATURE_TX_CHECKSUM_IPV4), + ETHT_DATA(FEATURE_TX_CHECKSUM_IPV6), + ETHT_DATA(FEATURE_TX_CHECKSUM_IP_GENERIC), + ETHT_DATA(FEATURE_TX_CHECKSUM_SCTP), + ETHT_DATA(FEATURE_TX_ESP_SEGMENTATION), + ETHT_DATA(FEATURE_TX_FCOE_SEGMENTATION), + ETHT_DATA(FEATURE_TX_GRE_CSUM_SEGMENTATION), + ETHT_DATA(FEATURE_TX_GRE_SEGMENTATION), + ETHT_DATA(FEATURE_TX_GSO_LIST), + ETHT_DATA(FEATURE_TX_GSO_PARTIAL), + ETHT_DATA(FEATURE_TX_GSO_ROBUST), + ETHT_DATA(FEATURE_TX_IPXIP4_SEGMENTATION), + ETHT_DATA(FEATURE_TX_IPXIP6_SEGMENTATION), + ETHT_DATA(FEATURE_TX_NOCACHE_COPY), + ETHT_DATA(FEATURE_TX_SCATTER_GATHER), + ETHT_DATA(FEATURE_TX_SCATTER_GATHER_FRAGLIST), + ETHT_DATA(FEATURE_TX_SCTP_SEGMENTATION), + ETHT_DATA(FEATURE_TX_TCP6_SEGMENTATION), + ETHT_DATA(FEATURE_TX_TCP_ECN_SEGMENTATION), + ETHT_DATA(FEATURE_TX_TCP_MANGLEID_SEGMENTATION), + ETHT_DATA(FEATURE_TX_TCP_SEGMENTATION), + ETHT_DATA(FEATURE_TX_TUNNEL_REMCSUM_SEGMENTATION), + ETHT_DATA(FEATURE_TX_UDP_SEGMENTATION), + ETHT_DATA(FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION), + ETHT_DATA(FEATURE_TX_UDP_TNL_SEGMENTATION), + ETHT_DATA(FEATURE_TX_VLAN_STAG_HW_INSERT), + ETHT_DATA(RING_RX), + ETHT_DATA(RING_RX_JUMBO), + ETHT_DATA(RING_RX_MINI), + ETHT_DATA(RING_TX), + [_NM_ETHTOOL_ID_NUM] = NULL, +}; + +static const guint8 _by_name[_NM_ETHTOOL_ID_NUM] = { + /* sorted by optname. */ + NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX, + NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX, + NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH, + NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW, + NM_ETHTOOL_ID_COALESCE_RX_FRAMES, + NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH, + NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ, + NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW, + NM_ETHTOOL_ID_COALESCE_RX_USECS, + NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH, + NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ, + NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW, + NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL, + NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS, + NM_ETHTOOL_ID_COALESCE_TX_FRAMES, + NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH, + NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ, + NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW, + NM_ETHTOOL_ID_COALESCE_TX_USECS, + NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH, + NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ, + NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW, + NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_FCOE_MTU, + NM_ETHTOOL_ID_FEATURE_GRO, + NM_ETHTOOL_ID_FEATURE_GSO, + NM_ETHTOOL_ID_FEATURE_HIGHDMA, + NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_LOOPBACK, + NM_ETHTOOL_ID_FEATURE_LRO, + NM_ETHTOOL_ID_FEATURE_MACSEC_HW_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_NTUPLE, + NM_ETHTOOL_ID_FEATURE_RX, + NM_ETHTOOL_ID_FEATURE_RX_ALL, + NM_ETHTOOL_ID_FEATURE_RX_FCS, + NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, + NM_ETHTOOL_ID_FEATURE_RX_GRO_LIST, + NM_ETHTOOL_ID_FEATURE_RX_UDP_GRO_FORWARDING, + NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, + NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, + NM_ETHTOOL_ID_FEATURE_RXHASH, + NM_ETHTOOL_ID_FEATURE_RXVLAN, + NM_ETHTOOL_ID_FEATURE_SG, + NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, + NM_ETHTOOL_ID_FEATURE_TLS_HW_RX_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, + NM_ETHTOOL_ID_FEATURE_TSO, + NM_ETHTOOL_ID_FEATURE_TX, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, + NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, + NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_GSO_LIST, + NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, + NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, + NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, + NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, + NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, + NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_TUNNEL_REMCSUM_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, + NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, + NM_ETHTOOL_ID_FEATURE_TXVLAN, + NM_ETHTOOL_ID_RING_RX, + NM_ETHTOOL_ID_RING_RX_JUMBO, + NM_ETHTOOL_ID_RING_RX_MINI, + NM_ETHTOOL_ID_RING_TX, +}; + +/*****************************************************************************/ + +static void +_ASSERT_data(void) +{ + int i; + + if (!NM_MORE_ASSERT_ONCE(10)) + return; + + G_STATIC_ASSERT_EXPR(_NM_ETHTOOL_ID_FIRST == 0); + G_STATIC_ASSERT_EXPR(_NM_ETHTOOL_ID_LAST == _NM_ETHTOOL_ID_NUM - 1); + G_STATIC_ASSERT_EXPR(_NM_ETHTOOL_ID_NUM > 0); + + nm_assert(NM_PTRARRAY_LEN(nm_ethtool_data) == _NM_ETHTOOL_ID_NUM); + nm_assert(G_N_ELEMENTS(_by_name) == _NM_ETHTOOL_ID_NUM); + nm_assert(G_N_ELEMENTS(nm_ethtool_data) == _NM_ETHTOOL_ID_NUM + 1); + + for (i = 0; i < _NM_ETHTOOL_ID_NUM; i++) { + const NMEthtoolData *d = nm_ethtool_data[i]; + + nm_assert(d); + nm_assert(d->id == (NMEthtoolID) i); + nm_assert(d->optname && d->optname[0]); + } + + for (i = 0; i < _NM_ETHTOOL_ID_NUM; i++) { + NMEthtoolID id = _by_name[i]; + const NMEthtoolData *d; + + nm_assert(id >= 0); + nm_assert(id < _NM_ETHTOOL_ID_NUM); + + d = nm_ethtool_data[id]; + if (i > 0) { + /* since we assert that all optnames are sorted strictly monotonically increasing, + * it also follows that there are no duplicates in the _by_name. + * It also follows, that all names in nm_ethtool_data are unique. */ + if (strcmp(nm_ethtool_data[_by_name[i - 1]]->optname, d->optname) >= 0) { + g_error("nm_ethtool_data is not sorted asciibetically: %u/%s should be after %u/%s", + i - 1, + nm_ethtool_data[_by_name[i - 1]]->optname, + i, + d->optname); + } + } + } +} + +static int +_by_name_cmp(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const guint8 *p_id = a; + const char * optname = b; + + nm_assert(p_id && p_id >= _by_name && p_id <= &_by_name[_NM_ETHTOOL_ID_NUM]); + nm_assert(*p_id < _NM_ETHTOOL_ID_NUM); + + return strcmp(nm_ethtool_data[*p_id]->optname, optname); +} + +const NMEthtoolData * +nm_ethtool_data_get_by_optname(const char *optname) +{ + gssize idx; + + if (!optname) + return NULL; + + _ASSERT_data(); + + idx = nm_utils_array_find_binary_search((gconstpointer *) _by_name, + sizeof(_by_name[0]), + _NM_ETHTOOL_ID_NUM, + optname, + _by_name_cmp, + NULL); + return (idx < 0) ? NULL : nm_ethtool_data[_by_name[idx]]; +} + +NMEthtoolType +nm_ethtool_id_to_type(NMEthtoolID id) +{ + if (nm_ethtool_id_is_coalesce(id)) + return NM_ETHTOOL_TYPE_COALESCE; + if (nm_ethtool_id_is_feature(id)) + return NM_ETHTOOL_TYPE_FEATURE; + if (nm_ethtool_id_is_ring(id)) + return NM_ETHTOOL_TYPE_RING; + + return NM_ETHTOOL_TYPE_UNKNOWN; +} diff --git a/src/libnm-base/nm-ethtool-base.h b/src/libnm-base/nm-ethtool-base.h new file mode 100644 index 0000000..abedcaf --- /dev/null +++ b/src/libnm-base/nm-ethtool-base.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_ETHTOOL_BASE_H__ +#define __NM_ETHTOOL_BASE_H__ + +#include "libnm-base/nm-base.h" + +/*****************************************************************************/ + +typedef struct { + const char *optname; + NMEthtoolID id; +} NMEthtoolData; + +extern const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1]; + +const NMEthtoolData *nm_ethtool_data_get_by_optname(const char *optname); + +NMEthtoolType nm_ethtool_id_to_type(NMEthtoolID id); + +/****************************************************************************/ + +static inline NMEthtoolID +nm_ethtool_id_get_by_name(const char *optname) +{ + const NMEthtoolData *d; + + d = nm_ethtool_data_get_by_optname(optname); + return d ? d->id : NM_ETHTOOL_ID_UNKNOWN; +} + +/****************************************************************************/ + +#endif /* __NM_ETHTOOL_BASE_H__ */ diff --git a/src/libnm-base/nm-ethtool-utils-base.h b/src/libnm-base/nm-ethtool-utils-base.h new file mode 100644 index 0000000..d422724 --- /dev/null +++ b/src/libnm-base/nm-ethtool-utils-base.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_ETHTOOL_UTILS_H__ +#define __NM_ETHTOOL_UTILS_H__ + +G_BEGIN_DECLS + +/*****************************************************************************/ + +#define NM_ETHTOOL_OPTNAME_FEATURE_ESP_HW_OFFLOAD "feature-esp-hw-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_ESP_TX_CSUM_HW_OFFLOAD "feature-esp-tx-csum-hw-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_FCOE_MTU "feature-fcoe-mtu" +#define NM_ETHTOOL_OPTNAME_FEATURE_GRO "feature-gro" +#define NM_ETHTOOL_OPTNAME_FEATURE_GSO "feature-gso" +#define NM_ETHTOOL_OPTNAME_FEATURE_HIGHDMA "feature-highdma" +#define NM_ETHTOOL_OPTNAME_FEATURE_HW_TC_OFFLOAD "feature-hw-tc-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_L2_FWD_OFFLOAD "feature-l2-fwd-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_LOOPBACK "feature-loopback" +#define NM_ETHTOOL_OPTNAME_FEATURE_LRO "feature-lro" +#define NM_ETHTOOL_OPTNAME_FEATURE_MACSEC_HW_OFFLOAD "feature-macsec-hw-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_NTUPLE "feature-ntuple" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX "feature-rx" +#define NM_ETHTOOL_OPTNAME_FEATURE_RXHASH "feature-rxhash" +#define NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN "feature-rxvlan" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_ALL "feature-rx-all" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_FCS "feature-rx-fcs" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_GRO_HW "feature-rx-gro-hw" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_GRO_LIST "feature-rx-gro-list" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_UDP_GRO_FORWARDING "feature-rx-udp-gro-forwarding" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD "feature-rx-udp_tunnel-port-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_FILTER "feature-rx-vlan-filter" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_STAG_FILTER "feature-rx-vlan-stag-filter" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_STAG_HW_PARSE "feature-rx-vlan-stag-hw-parse" +#define NM_ETHTOOL_OPTNAME_FEATURE_SG "feature-sg" +#define NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_RECORD "feature-tls-hw-record" +#define NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_RX_OFFLOAD "feature-tls-hw-rx-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_TX_OFFLOAD "feature-tls-hw-tx-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_TSO "feature-tso" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX "feature-tx" +#define NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN "feature-txvlan" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_FCOE_CRC "feature-tx-checksum-fcoe-crc" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IPV4 "feature-tx-checksum-ipv4" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IPV6 "feature-tx-checksum-ipv6" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IP_GENERIC "feature-tx-checksum-ip-generic" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_SCTP "feature-tx-checksum-sctp" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_ESP_SEGMENTATION "feature-tx-esp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_FCOE_SEGMENTATION "feature-tx-fcoe-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GRE_CSUM_SEGMENTATION "feature-tx-gre-csum-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GRE_SEGMENTATION "feature-tx-gre-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_LIST "feature-tx-gso-list" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_PARTIAL "feature-tx-gso-partial" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_ROBUST "feature-tx-gso-robust" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_IPXIP4_SEGMENTATION "feature-tx-ipxip4-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_IPXIP6_SEGMENTATION "feature-tx-ipxip6-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_NOCACHE_COPY "feature-tx-nocache-copy" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_SCATTER_GATHER "feature-tx-scatter-gather" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_SCATTER_GATHER_FRAGLIST "feature-tx-scatter-gather-fraglist" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_SCTP_SEGMENTATION "feature-tx-sctp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP6_SEGMENTATION "feature-tx-tcp6-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_ECN_SEGMENTATION "feature-tx-tcp-ecn-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_MANGLEID_SEGMENTATION \ + "feature-tx-tcp-mangleid-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_SEGMENTATION "feature-tx-tcp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TUNNEL_REMCSUM_SEGMENTATION \ + "feature-tx-tunnel-remcsum-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_SEGMENTATION "feature-tx-udp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION \ + "feature-tx-udp_tnl-csum-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_TNL_SEGMENTATION "feature-tx-udp_tnl-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_VLAN_STAG_HW_INSERT "feature-tx-vlan-stag-hw-insert" + +#define NM_ETHTOOL_OPTNAME_COALESCE_ADAPTIVE_RX "coalesce-adaptive-rx" +#define NM_ETHTOOL_OPTNAME_COALESCE_ADAPTIVE_TX "coalesce-adaptive-tx" +#define NM_ETHTOOL_OPTNAME_COALESCE_PKT_RATE_HIGH "coalesce-pkt-rate-high" +#define NM_ETHTOOL_OPTNAME_COALESCE_PKT_RATE_LOW "coalesce-pkt-rate-low" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES "coalesce-rx-frames" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_HIGH "coalesce-rx-frames-high" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_IRQ "coalesce-rx-frames-irq" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_LOW "coalesce-rx-frames-low" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS "coalesce-rx-usecs" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_HIGH "coalesce-rx-usecs-high" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_IRQ "coalesce-rx-usecs-irq" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_LOW "coalesce-rx-usecs-low" +#define NM_ETHTOOL_OPTNAME_COALESCE_SAMPLE_INTERVAL "coalesce-sample-interval" +#define NM_ETHTOOL_OPTNAME_COALESCE_STATS_BLOCK_USECS "coalesce-stats-block-usecs" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES "coalesce-tx-frames" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_HIGH "coalesce-tx-frames-high" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_IRQ "coalesce-tx-frames-irq" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_LOW "coalesce-tx-frames-low" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS "coalesce-tx-usecs" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_HIGH "coalesce-tx-usecs-high" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_IRQ "coalesce-tx-usecs-irq" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_LOW "coalesce-tx-usecs-low" + +#define NM_ETHTOOL_OPTNAME_RING_RX "ring-rx" +#define NM_ETHTOOL_OPTNAME_RING_RX_JUMBO "ring-rx-jumbo" +#define NM_ETHTOOL_OPTNAME_RING_RX_MINI "ring-rx-mini" +#define NM_ETHTOOL_OPTNAME_RING_TX "ring-tx" + +/*****************************************************************************/ + +G_END_DECLS + +#endif /* __NM_ETHTOOL_UTILS_H__ */ diff --git a/src/libnm-base/nm-net-aux.c b/src/libnm-base/nm-net-aux.c new file mode 100644 index 0000000..0b6c238 --- /dev/null +++ b/src/libnm-base/nm-net-aux.c @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-net-aux.h" + +#include +#include + +/*****************************************************************************/ + +G_STATIC_ASSERT((int) FR_ACT_UNSPEC == RTN_UNSPEC); +G_STATIC_ASSERT((int) FR_ACT_TO_TBL == RTN_UNICAST); +G_STATIC_ASSERT((int) FR_ACT_GOTO == RTN_LOCAL); +G_STATIC_ASSERT((int) FR_ACT_NOP == RTN_BROADCAST); +G_STATIC_ASSERT((int) FR_ACT_RES3 == RTN_ANYCAST); +G_STATIC_ASSERT((int) FR_ACT_RES4 == RTN_MULTICAST); +G_STATIC_ASSERT((int) FR_ACT_BLACKHOLE == RTN_BLACKHOLE); +G_STATIC_ASSERT((int) FR_ACT_UNREACHABLE == RTN_UNREACHABLE); +G_STATIC_ASSERT((int) FR_ACT_PROHIBIT == RTN_PROHIBIT); + +/* see iproute2's rtnl_rtntype_a2n() */ +NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( + nm_net_aux_rtnl_rtntype_a2n, + int, + { nm_assert(name); }, + { + NM_AUTO_PROTECT_ERRNO(errsv); + return _nm_utils_ascii_str_to_int64(name, 0, 0, 255, -1); + }, + {"anycast", RTN_ANYCAST}, + {"blackhole", RTN_BLACKHOLE}, + {"brd", RTN_BROADCAST}, + {"broadcast", RTN_BROADCAST}, + {"local", RTN_LOCAL}, + {"multicast", RTN_MULTICAST}, + {"nat", RTN_NAT}, + {"prohibit", RTN_PROHIBIT}, + {"throw", RTN_THROW}, + {"unicast", RTN_UNICAST}, + {"unreachable", RTN_UNREACHABLE}, + {"xresolve", RTN_XRESOLVE}, ); + +const char * +nm_net_aux_rtnl_rtntype_n2a(guint8 v) +{ + /* see iproute2's rtnl_rtntype_n2a(). */ + + switch (v) { + case RTN_UNSPEC: + return "none"; + case RTN_UNICAST: + return "unicast"; + case RTN_LOCAL: + return "local"; + case RTN_BROADCAST: + return "broadcast"; + case RTN_ANYCAST: + return "anycast"; + case RTN_MULTICAST: + return "multicast"; + case RTN_BLACKHOLE: + return "blackhole"; + case RTN_UNREACHABLE: + return "unreachable"; + case RTN_PROHIBIT: + return "prohibit"; + case RTN_THROW: + return "throw"; + case RTN_NAT: + return "nat"; + case RTN_XRESOLVE: + return "xresolve"; + } + + /* unlike the iproute2 code, this returns %NULL for unknown values. + * You may represent this value as "%d" integer, but do it yourself. */ + return NULL; +} diff --git a/src/libnm-base/nm-net-aux.h b/src/libnm-base/nm-net-aux.h new file mode 100644 index 0000000..6c6b7a7 --- /dev/null +++ b/src/libnm-base/nm-net-aux.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_NET_AUX_H__ +#define __NM_NET_AUX_H__ + +const char *nm_net_aux_rtnl_rtntype_n2a(guint8 v); +int nm_net_aux_rtnl_rtntype_a2n(const char *name); + +#define nm_net_aux_rtnl_rtntype_n2a_maybe_buf(v, buf) \ + ({ \ + const guint8 _v = (v); \ + \ + /* Warning: this will only touch/initialize @buf if necessary. + * That means, don't assume that @buf was initialized after calling + * this macro. */ \ + nm_net_aux_rtnl_rtntype_n2a(v) ?: nm_sprintf_buf((buf), "%u", _v); \ + }) + +/*****************************************************************************/ + +#endif /* __NM_NET_AUX_H__ */ diff --git a/src/libnm-client-aux-extern/README.md b/src/libnm-client-aux-extern/README.md new file mode 100644 index 0000000..460b269 --- /dev/null +++ b/src/libnm-client-aux-extern/README.md @@ -0,0 +1,15 @@ +nm-libnm-aux is a static library that: + + - uses the public parts of "libnm" + - that can also be statically linked into other users of libnm. + +Basically, it is a static library with utility functions that extends +libnm. + +That means: + + - you can use it everywhere where you dynamically link with libnm. + +Also, since nm-libnm-aux itself only uses public (stable) +API of libnm, you theoretically can copy the sources into your +own source tree. diff --git a/src/libnm-client-aux-extern/meson.build b/src/libnm-client-aux-extern/meson.build new file mode 100644 index 0000000..a2b4654 --- /dev/null +++ b/src/libnm-client-aux-extern/meson.build @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_client_aux_extern = static_library( + 'nm-client-aux-extern', + sources: files( + 'nm-libnm-aux.c', + ), + dependencies: [ + libnm_dep, + ], +) diff --git a/src/libnm-client-aux-extern/nm-default-client.h b/src/libnm-client-aux-extern/nm-default-client.h new file mode 100644 index 0000000..a770ae5 --- /dev/null +++ b/src/libnm-client-aux-extern/nm-default-client.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEFAULT_CLIENT_H__ +#define __NM_DEFAULT_CLIENT_H__ + +/*****************************************************************************/ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#undef NETWORKMANAGER_COMPILATION +#define NETWORKMANAGER_COMPILATION NM_NETWORKMANAGER_COMPILATION_CLIENT + +/*****************************************************************************/ + +#include "nm-version.h" +#include "NetworkManager.h" + +/*****************************************************************************/ + +#endif /* __NM_DEFAULT_CLIENT_H__ */ diff --git a/src/libnm-client-aux-extern/nm-libnm-aux.c b/src/libnm-client-aux-extern/nm-libnm-aux.c new file mode 100644 index 0000000..2d17241 --- /dev/null +++ b/src/libnm-client-aux-extern/nm-libnm-aux.c @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-client-aux-extern/nm-default-client.h" + +#include "nm-libnm-aux.h" + +/*****************************************************************************/ + +NMClient * +nmc_client_new_async_valist(GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + const char * first_property_name, + va_list ap) +{ + NMClient *nmc; + + nmc = NM_CLIENT(g_object_new_valist(NM_TYPE_CLIENT, first_property_name, ap)); + g_async_initable_init_async(G_ASYNC_INITABLE(nmc), + G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data); + return nmc; +} + +NMClient * +nmc_client_new_async(GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + const char * first_property_name, + ...) +{ + NMClient *nmc; + va_list ap; + + va_start(ap, first_property_name); + nmc = nmc_client_new_async_valist(cancellable, callback, user_data, first_property_name, ap); + va_end(ap); + return nmc; +} + +/*****************************************************************************/ + +typedef struct { + GMainLoop *main_loop; + NMClient * nmc; + GError * error; +} ClientCreateData; + +static void +_nmc_client_new_waitsync_cb(GObject *source_object, GAsyncResult *result, gpointer user_data) +{ + ClientCreateData *data = user_data; + + g_async_initable_init_finish(G_ASYNC_INITABLE(source_object), result, &data->error); + g_main_loop_quit(data->main_loop); +} + +/** + * nmc_client_new: + * @cancellable: the cancellable to abort the creation. + * @out_nmc: (out): (transfer full): if give, transfers a reference + * to the NMClient instance. Note that this never fails to create + * the NMClient GObject, but depending on the return value, + * the instance was successfully initialized or not. + * @error: the error if creation fails. + * @first_property_name: the name of the first property + * @...: the value of the first property, followed optionally by more + * name/value pairs, followed by %NULL + * + * Returns: %TRUE, if the client was successfully initalized. + * + * This uses nm_client_new_async() to create a NMClient instance, + * but it iterates the current GMainContext until the client is + * ready. As such, it waits for the client creation to complete + * (like sync nm_client_new()) but it iterates the caller's GMainContext + * (unlike sync nm_client_new()). This is often preferable, because + * sync nm_client_new() needs to create an additional internal GMainContext + * that it can iterate instead. That has a performance overhead that + * is often unnecessary. + */ +gboolean +nmc_client_new_waitsync(GCancellable *cancellable, + NMClient ** out_nmc, + GError ** error, + const char * first_property_name, + ...) +{ + gs_unref_object NMClient *nmc = NULL; + nm_auto_unref_gmainloop GMainLoop *main_loop = + g_main_loop_new(g_main_context_get_thread_default(), FALSE); + ClientCreateData data = { + .main_loop = main_loop, + }; + va_list ap; + +#if NM_MORE_ASSERTS > 10 + /* The sync initialization of NMClient is generally a bad idea, because it + * brings the overhead of an additional GMainContext. Anyway, since our own + * code no longer uses that, we hardly test those code paths. But they should + * work just the same. Randomly use instead the sync initialization in a debug + * build... */ + if ((g_random_int() % 2) == 0) { + gboolean success; + + va_start(ap, first_property_name); + nmc = NM_CLIENT(g_object_new_valist(NM_TYPE_CLIENT, first_property_name, ap)); + va_end(ap); + + /* iterate the context at least once, just so that the behavior from POV of the + * caller is roughly the same. */ + g_main_context_iteration(nm_client_get_main_context(nmc), FALSE); + + success = g_initable_init(G_INITABLE(nmc), cancellable, error); + NM_SET_OUT(out_nmc, g_steal_pointer(&nmc)); + return success; + } +#endif + + va_start(ap, first_property_name); + nmc = nmc_client_new_async_valist(cancellable, + _nmc_client_new_waitsync_cb, + &data, + first_property_name, + ap); + va_end(ap); + + g_main_loop_run(main_loop); + + NM_SET_OUT(out_nmc, g_steal_pointer(&nmc)); + if (data.error) { + g_propagate_error(error, data.error); + return FALSE; + } + return TRUE; +} diff --git a/src/libnm-client-aux-extern/nm-libnm-aux.h b/src/libnm-client-aux-extern/nm-libnm-aux.h new file mode 100644 index 0000000..c982eab --- /dev/null +++ b/src/libnm-client-aux-extern/nm-libnm-aux.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_LIBNM_AUX_H__ +#define __NM_LIBNM_AUX_H__ + +NMClient *nmc_client_new_async_valist(GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + const char * first_property_name, + va_list ap); + +NMClient *nmc_client_new_async(GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + const char * first_property_name, + ...); + +gboolean nmc_client_new_waitsync(GCancellable *cancellable, + NMClient ** out_nmc, + GError ** error, + const char * first_property_name, + ...); + +#endif /* __NM_LIBNM_AUX_H__ */ diff --git a/src/libnm-client-aux-extern/tests/test-libnm-client-aux.c b/src/libnm-client-aux-extern/tests/test-libnm-client-aux.c new file mode 100644 index 0000000..c4db4d6 --- /dev/null +++ b/src/libnm-client-aux-extern/tests/test-libnm-client-aux.c @@ -0,0 +1,250 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#include "libnm-client-aux-extern/nm-default-client.h" + +#include "libnm-core-aux-extern/nm-libnm-core-aux.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +/*****************************************************************************/ + +static NMTeamLinkWatcher * +_team_link_watcher_from_string_impl(const char *str, gsize nextra, const char *const *vextra) +{ + NMTeamLinkWatcher *watcher; + gs_free char * str1_free = NULL; + gs_free_error GError *error = NULL; + gsize i; + + g_assert(str); + + watcher = nm_utils_team_link_watcher_from_string(str, &error); + nmtst_assert_success(watcher, error); + + for (i = 0; i < 1 + nextra; i++) { + nm_auto_unref_team_link_watcher NMTeamLinkWatcher *watcher1 = NULL; + const char * str1; + + if (i == 0) { + str1_free = nm_utils_team_link_watcher_to_string(watcher); + g_assert(str1_free); + str1 = str1_free; + g_assert_cmpstr(str, ==, str1); + } else + str1 = vextra[i - 1]; + + watcher1 = nm_utils_team_link_watcher_from_string(str1, &error); + nmtst_assert_success(watcher1, error); + if (!nm_team_link_watcher_equal(watcher, watcher1)) { + gs_free char *ss1 = NULL; + gs_free char *ss2 = NULL; + + g_print(">>> watcher differs: \"%s\" vs. \"%s\"", + (ss1 = nm_utils_team_link_watcher_to_string(watcher)), + (ss2 = nm_utils_team_link_watcher_to_string(watcher1))); + g_print(">>> ORIG: \"%s\" vs. \"%s\"", str, str1); + g_assert_not_reached(); + } + g_assert(nm_team_link_watcher_equal(watcher1, watcher)); + } + + return watcher; +} +#define _team_link_watcher_from_string(str, ...) \ + _team_link_watcher_from_string_impl((str), NM_NARG(__VA_ARGS__), NM_MAKE_STRV(__VA_ARGS__)) + +/*****************************************************************************/ + +static void +test_team_link_watcher_tofro_string(void) +{ + nm_auto_unref_team_link_watcher NMTeamLinkWatcher *w = NULL; + +#define _team_link_watcher_cmp(watcher, \ + name, \ + delay_down, \ + delay_up, \ + init_wait, \ + interval, \ + missed_max, \ + target_host, \ + source_host, \ + vlanid, \ + arping_flags) \ + G_STMT_START \ + { \ + nm_auto_unref_team_link_watcher NMTeamLinkWatcher *_w = g_steal_pointer(watcher); \ + \ + g_assert_cmpstr((name), ==, nm_team_link_watcher_get_name(_w)); \ + g_assert_cmpint((delay_down), ==, nm_team_link_watcher_get_delay_down(_w)); \ + g_assert_cmpint((delay_up), ==, nm_team_link_watcher_get_delay_up(_w)); \ + g_assert_cmpint((init_wait), ==, nm_team_link_watcher_get_init_wait(_w)); \ + g_assert_cmpint((interval), ==, nm_team_link_watcher_get_interval(_w)); \ + g_assert_cmpint((missed_max), ==, nm_team_link_watcher_get_missed_max(_w)); \ + g_assert_cmpstr((target_host), ==, nm_team_link_watcher_get_target_host(_w)); \ + g_assert_cmpstr((source_host), ==, nm_team_link_watcher_get_source_host(_w)); \ + g_assert_cmpint((vlanid), ==, nm_team_link_watcher_get_vlanid(_w)); \ + g_assert_cmpint((arping_flags), ==, nm_team_link_watcher_get_flags(_w)); \ + } \ + G_STMT_END + + w = _team_link_watcher_from_string("name=ethtool", + "delay-up=0 name=ethtool", + " delay-down=0 name=ethtool "); + _team_link_watcher_cmp(&w, + "ethtool", + 0, + 0, + -1, + -1, + -1, + NULL, + NULL, + -1, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE); + + w = _team_link_watcher_from_string("name=ethtool delay-up=10", + " delay-down=0 delay-up=10 name=ethtool"); + _team_link_watcher_cmp(&w, + "ethtool", + 0, + 10, + -1, + -1, + -1, + NULL, + NULL, + -1, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE); + + w = _team_link_watcher_from_string("name=ethtool delay-up=10 delay-down=11", + " delay-down=11 delay-up=10 name=ethtool"); + _team_link_watcher_cmp(&w, + "ethtool", + 11, + 10, + -1, + -1, + -1, + NULL, + NULL, + -1, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE); + + w = _team_link_watcher_from_string( + "name=nsna_ping target-host=xxx", + "name=nsna_ping target-host=xxx", + " missed-max=3 target-host=xxx name=nsna_ping "); + _team_link_watcher_cmp(&w, + "nsna_ping", + -1, + -1, + 0, + 0, + 3, + "xxx", + NULL, + -1, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE); + + w = _team_link_watcher_from_string("name=arp_ping target-host=xxx source-host=yzd", + " source-host=yzd target-host=xxx name=arp_ping "); + _team_link_watcher_cmp(&w, + "arp_ping", + -1, + -1, + 0, + 0, + 3, + "xxx", + "yzd", + -1, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE); + + w = _team_link_watcher_from_string( + "name=arp_ping missed-max=0 target-host=xxx vlanid=0 source-host=yzd"); + _team_link_watcher_cmp(&w, + "arp_ping", + -1, + -1, + 0, + 0, + 0, + "xxx", + "yzd", + 0, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE); + + w = _team_link_watcher_from_string( + "name=arp_ping target-host=xxx source-host=yzd validate-active=true", + "source-host=yzd send-always=false name=arp_ping validate-active=true " + "validate-inactive=false target-host=xxx", + " source-host=yzd target-host=xxx validate-active=true name=arp_ping "); + _team_link_watcher_cmp(&w, + "arp_ping", + -1, + -1, + 0, + 0, + 3, + "xxx", + "yzd", + -1, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE); + + w = _team_link_watcher_from_string( + "name=arp_ping target-host=xxx source-host=yzd validate-active=true validate-inactive=true " + "send-always=true", + "source-host=yzd send-always=true name=arp_ping validate-active=true " + "validate-inactive=true target-host=xxx", + "source-host=yzd send-always=true name=arp_ping validate-active=1 validate-inactive=yes " + "target-host=xxx", + " source-host=yzd target-host=xxx validate-inactive=true send-always=true " + "validate-active=true name=arp_ping "); + _team_link_watcher_cmp(&w, + "arp_ping", + -1, + -1, + 0, + 0, + 3, + "xxx", + "yzd", + -1, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE + | NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE + | NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS); + + w = _team_link_watcher_from_string( + "name=arp_ping missed-max=0 target-host=xxx vlanid=0 source-host=yzd"); + _team_link_watcher_cmp(&w, + "arp_ping", + -1, + -1, + 0, + 0, + 0, + "xxx", + "yzd", + 0, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE); +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_func("/libnm-core-aux/test_team_link_watcher_tofro_string", + test_team_link_watcher_tofro_string); + + return g_test_run(); +} diff --git a/src/libnm-client-impl/libnm.pc.in b/src/libnm-client-impl/libnm.pc.in new file mode 100644 index 0000000..afc5e4d --- /dev/null +++ b/src/libnm-client-impl/libnm.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +vpnservicedir=@nmlibdir@/VPN + +Name: libnm +Description: Convenience library for clients of NetworkManager +Version: @VERSION@ +Requires: gio-2.0 +Cflags: -I${includedir}/libnm +Libs: -L${libdir} -lnm + + diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver new file mode 100644 index 0000000..693591e --- /dev/null +++ b/src/libnm-client-impl/libnm.ver @@ -0,0 +1,1791 @@ +libnm_1_0_0 { +global: + nm_802_11_ap_flags_get_type; + nm_802_11_ap_security_flags_get_type; + nm_802_11_mode_get_type; + nm_access_point_connection_valid; + nm_access_point_filter_connections; + nm_access_point_get_bssid; + nm_access_point_get_flags; + nm_access_point_get_frequency; + nm_access_point_get_max_bitrate; + nm_access_point_get_mode; + nm_access_point_get_rsn_flags; + nm_access_point_get_ssid; + nm_access_point_get_strength; + nm_access_point_get_type; + nm_access_point_get_wpa_flags; + nm_active_connection_get_connection; + nm_active_connection_get_connection_type; + nm_active_connection_get_default6; + nm_active_connection_get_default; + nm_active_connection_get_devices; + nm_active_connection_get_dhcp4_config; + nm_active_connection_get_dhcp6_config; + nm_active_connection_get_id; + nm_active_connection_get_ip4_config; + nm_active_connection_get_ip6_config; + nm_active_connection_get_master; + nm_active_connection_get_specific_object_path; + nm_active_connection_get_state; + nm_active_connection_get_type; + nm_active_connection_get_uuid; + nm_active_connection_get_vpn; + nm_active_connection_state_get_type; + nm_agent_manager_error_get_type; + nm_agent_manager_error_quark; + nm_bluetooth_capabilities_get_type; + nm_client_activate_connection_async; + nm_client_activate_connection_finish; + nm_client_add_and_activate_connection_async; + nm_client_add_and_activate_connection_finish; + nm_client_add_connection_async; + nm_client_add_connection_finish; + nm_client_check_connectivity; + nm_client_check_connectivity_async; + nm_client_check_connectivity_finish; + nm_client_deactivate_connection; + nm_client_deactivate_connection_async; + nm_client_deactivate_connection_finish; + nm_client_error_get_type; + nm_client_error_quark; + nm_client_get_activating_connection; + nm_client_get_active_connections; + nm_client_get_connection_by_id; + nm_client_get_connection_by_path; + nm_client_get_connection_by_uuid; + nm_client_get_connections; + nm_client_get_connectivity; + nm_client_get_device_by_iface; + nm_client_get_device_by_path; + nm_client_get_devices; + nm_client_get_logging; + nm_client_get_nm_running; + nm_client_get_permission_result; + nm_client_get_primary_connection; + nm_client_get_startup; + nm_client_get_state; + nm_client_get_type; + nm_client_get_version; + nm_client_load_connections; + nm_client_load_connections_async; + nm_client_load_connections_finish; + nm_client_networking_get_enabled; + nm_client_networking_set_enabled; + nm_client_new; + nm_client_new_async; + nm_client_new_finish; + nm_client_permission_get_type; + nm_client_permission_result_get_type; + nm_client_reload_connections; + nm_client_reload_connections_async; + nm_client_reload_connections_finish; + nm_client_save_hostname; + nm_client_save_hostname_async; + nm_client_save_hostname_finish; + nm_client_set_logging; + nm_client_wimax_get_enabled; + nm_client_wimax_hardware_get_enabled; + nm_client_wimax_set_enabled; + nm_client_wireless_get_enabled; + nm_client_wireless_hardware_get_enabled; + nm_client_wireless_set_enabled; + nm_client_wwan_get_enabled; + nm_client_wwan_hardware_get_enabled; + nm_client_wwan_set_enabled; + nm_connection_add_setting; + nm_connection_clear_secrets; + nm_connection_clear_secrets_with_flags; + nm_connection_clear_settings; + nm_connection_compare; + nm_connection_diff; + nm_connection_dump; + nm_connection_error_get_type; + nm_connection_error_quark; + nm_connection_for_each_setting_value; + nm_connection_get_connection_type; + nm_connection_get_id; + nm_connection_get_interface_name; + nm_connection_get_path; + nm_connection_get_setting; + nm_connection_get_setting_802_1x; + nm_connection_get_setting_adsl; + nm_connection_get_setting_bluetooth; + nm_connection_get_setting_bond; + nm_connection_get_setting_bridge; + nm_connection_get_setting_bridge_port; + nm_connection_get_setting_by_name; + nm_connection_get_setting_cdma; + nm_connection_get_setting_connection; + nm_connection_get_setting_dcb; + nm_connection_get_setting_generic; + nm_connection_get_setting_gsm; + nm_connection_get_setting_infiniband; + nm_connection_get_setting_ip4_config; + nm_connection_get_setting_ip6_config; + nm_connection_get_setting_olpc_mesh; + nm_connection_get_setting_ppp; + nm_connection_get_setting_pppoe; + nm_connection_get_setting_serial; + nm_connection_get_setting_team; + nm_connection_get_setting_team_port; + nm_connection_get_setting_vlan; + nm_connection_get_setting_vpn; + nm_connection_get_setting_wimax; + nm_connection_get_setting_wired; + nm_connection_get_setting_wireless; + nm_connection_get_setting_wireless_security; + nm_connection_get_type; + nm_connection_get_uuid; + nm_connection_get_virtual_device_description; + nm_connection_is_type; + nm_connection_is_virtual; + nm_connection_need_secrets; + nm_connection_normalize; + nm_connection_remove_setting; + nm_connection_replace_settings; + nm_connection_replace_settings_from_connection; + nm_connection_serialization_flags_get_type; + nm_connection_set_path; + nm_connection_to_dbus; + nm_connection_update_secrets; + nm_connection_verify; + nm_connectivity_state_get_type; + nm_crypto_error_get_type; + nm_crypto_error_quark; + nm_device_adsl_get_carrier; + nm_device_adsl_get_type; + nm_device_bond_get_carrier; + nm_device_bond_get_hw_address; + nm_device_bond_get_slaves; + nm_device_bond_get_type; + nm_device_bridge_get_carrier; + nm_device_bridge_get_hw_address; + nm_device_bridge_get_slaves; + nm_device_bridge_get_type; + nm_device_bt_get_capabilities; + nm_device_bt_get_hw_address; + nm_device_bt_get_name; + nm_device_bt_get_type; + nm_device_capabilities_get_type; + nm_device_connection_compatible; + nm_device_connection_valid; + nm_device_delete; + nm_device_delete_async; + nm_device_delete_finish; + nm_device_disambiguate_names; + nm_device_disconnect; + nm_device_disconnect_async; + nm_device_disconnect_finish; + nm_device_error_get_type; + nm_device_error_quark; + nm_device_ethernet_get_carrier; + nm_device_ethernet_get_hw_address; + nm_device_ethernet_get_permanent_hw_address; + nm_device_ethernet_get_speed; + nm_device_ethernet_get_type; + nm_device_filter_connections; + nm_device_generic_get_hw_address; + nm_device_generic_get_type; + nm_device_get_active_connection; + nm_device_get_autoconnect; + nm_device_get_available_connections; + nm_device_get_capabilities; + nm_device_get_description; + nm_device_get_device_type; + nm_device_get_dhcp4_config; + nm_device_get_dhcp6_config; + nm_device_get_driver; + nm_device_get_driver_version; + nm_device_get_firmware_missing; + nm_device_get_firmware_version; + nm_device_get_hw_address; + nm_device_get_iface; + nm_device_get_ip4_config; + nm_device_get_ip6_config; + nm_device_get_ip_iface; + nm_device_get_managed; + nm_device_get_mtu; + nm_device_get_physical_port_id; + nm_device_get_product; + nm_device_get_setting_type; + nm_device_get_state; + nm_device_get_state_reason; + nm_device_get_type; + nm_device_get_type_description; + nm_device_get_udi; + nm_device_get_vendor; + nm_device_infiniband_get_carrier; + nm_device_infiniband_get_hw_address; + nm_device_infiniband_get_type; + nm_device_is_software; + nm_device_modem_capabilities_get_type; + nm_device_modem_get_current_capabilities; + nm_device_modem_get_modem_capabilities; + nm_device_modem_get_type; + nm_device_olpc_mesh_get_active_channel; + nm_device_olpc_mesh_get_companion; + nm_device_olpc_mesh_get_hw_address; + nm_device_olpc_mesh_get_type; + nm_device_set_autoconnect; + nm_device_state_get_type; + nm_device_state_reason_get_type; + nm_device_team_get_carrier; + nm_device_team_get_hw_address; + nm_device_team_get_slaves; + nm_device_team_get_type; + nm_device_type_get_type; + nm_device_vlan_get_carrier; + nm_device_vlan_get_hw_address; + nm_device_vlan_get_parent; + nm_device_vlan_get_type; + nm_device_vlan_get_vlan_id; + nm_device_wifi_capabilities_get_type; + nm_device_wifi_get_access_point_by_path; + nm_device_wifi_get_access_points; + nm_device_wifi_get_active_access_point; + nm_device_wifi_get_bitrate; + nm_device_wifi_get_capabilities; + nm_device_wifi_get_hw_address; + nm_device_wifi_get_mode; + nm_device_wifi_get_permanent_hw_address; + nm_device_wifi_get_type; + nm_device_wifi_request_scan; + nm_device_wifi_request_scan_async; + nm_device_wifi_request_scan_finish; + nm_device_wimax_get_active_nsp; + nm_device_wimax_get_bsid; + nm_device_wimax_get_center_frequency; + nm_device_wimax_get_cinr; + nm_device_wimax_get_hw_address; + nm_device_wimax_get_nsp_by_path; + nm_device_wimax_get_nsps; + nm_device_wimax_get_rssi; + nm_device_wimax_get_tx_power; + nm_device_wimax_get_type; + nm_dhcp_config_get_family; + nm_dhcp_config_get_one_option; + nm_dhcp_config_get_options; + nm_dhcp_config_get_type; + nm_ip_address_equal; + nm_ip_address_get_address; + nm_ip_address_get_address_binary; + nm_ip_address_get_attribute; + nm_ip_address_get_attribute_names; + nm_ip_address_get_family; + nm_ip_address_get_prefix; + nm_ip_address_get_type; + nm_ip_address_new; + nm_ip_address_new_binary; + nm_ip_address_ref; + nm_ip_address_set_address; + nm_ip_address_set_address_binary; + nm_ip_address_set_attribute; + nm_ip_address_set_prefix; + nm_ip_address_unref; + nm_ip_config_get_addresses; + nm_ip_config_get_domains; + nm_ip_config_get_family; + nm_ip_config_get_gateway; + nm_ip_config_get_nameservers; + nm_ip_config_get_routes; + nm_ip_config_get_searches; + nm_ip_config_get_type; + nm_ip_config_get_wins_servers; + nm_ip_route_equal; + nm_ip_route_get_attribute; + nm_ip_route_get_attribute_names; + nm_ip_route_get_dest; + nm_ip_route_get_dest_binary; + nm_ip_route_get_family; + nm_ip_route_get_metric; + nm_ip_route_get_next_hop; + nm_ip_route_get_next_hop_binary; + nm_ip_route_get_prefix; + nm_ip_route_get_type; + nm_ip_route_new; + nm_ip_route_new_binary; + nm_ip_route_ref; + nm_ip_route_set_attribute; + nm_ip_route_set_dest; + nm_ip_route_set_dest_binary; + nm_ip_route_set_metric; + nm_ip_route_set_next_hop; + nm_ip_route_set_next_hop_binary; + nm_ip_route_set_prefix; + nm_ip_route_unref; + nm_manager_error_get_type; + nm_manager_error_quark; + nm_object_get_path; + nm_object_get_type; + nm_remote_connection_commit_changes; + nm_remote_connection_commit_changes_async; + nm_remote_connection_commit_changes_finish; + nm_remote_connection_delete; + nm_remote_connection_delete_async; + nm_remote_connection_delete_finish; + nm_remote_connection_get_secrets; + nm_remote_connection_get_secrets_async; + nm_remote_connection_get_secrets_finish; + nm_remote_connection_get_type; + nm_remote_connection_get_unsaved; + nm_remote_connection_get_visible; + nm_remote_connection_save; + nm_remote_connection_save_async; + nm_remote_connection_save_finish; + nm_secret_agent_capabilities_get_type; + nm_secret_agent_error_get_type; + nm_secret_agent_error_quark; + nm_secret_agent_get_secrets_flags_get_type; + nm_secret_agent_old_delete_secrets; + nm_secret_agent_old_get_registered; + nm_secret_agent_old_get_secrets; + nm_secret_agent_old_get_type; + nm_secret_agent_old_register; + nm_secret_agent_old_register_async; + nm_secret_agent_old_register_finish; + nm_secret_agent_old_save_secrets; + nm_secret_agent_old_unregister; + nm_secret_agent_old_unregister_async; + nm_secret_agent_old_unregister_finish; + nm_setting_802_1x_add_altsubject_match; + nm_setting_802_1x_add_eap_method; + nm_setting_802_1x_add_phase2_altsubject_match; + nm_setting_802_1x_ck_format_get_type; + nm_setting_802_1x_ck_scheme_get_type; + nm_setting_802_1x_clear_altsubject_matches; + nm_setting_802_1x_clear_eap_methods; + nm_setting_802_1x_clear_phase2_altsubject_matches; + nm_setting_802_1x_get_altsubject_match; + nm_setting_802_1x_get_anonymous_identity; + nm_setting_802_1x_get_ca_cert_blob; + nm_setting_802_1x_get_ca_cert_path; + nm_setting_802_1x_get_ca_cert_scheme; + nm_setting_802_1x_get_ca_path; + nm_setting_802_1x_get_client_cert_blob; + nm_setting_802_1x_get_client_cert_path; + nm_setting_802_1x_get_client_cert_scheme; + nm_setting_802_1x_get_eap_method; + nm_setting_802_1x_get_identity; + nm_setting_802_1x_get_num_altsubject_matches; + nm_setting_802_1x_get_num_eap_methods; + nm_setting_802_1x_get_num_phase2_altsubject_matches; + nm_setting_802_1x_get_pac_file; + nm_setting_802_1x_get_password; + nm_setting_802_1x_get_password_flags; + nm_setting_802_1x_get_password_raw; + nm_setting_802_1x_get_password_raw_flags; + nm_setting_802_1x_get_phase1_fast_provisioning; + nm_setting_802_1x_get_phase1_peaplabel; + nm_setting_802_1x_get_phase1_peapver; + nm_setting_802_1x_get_phase2_altsubject_match; + nm_setting_802_1x_get_phase2_auth; + nm_setting_802_1x_get_phase2_autheap; + nm_setting_802_1x_get_phase2_ca_cert_blob; + nm_setting_802_1x_get_phase2_ca_cert_path; + nm_setting_802_1x_get_phase2_ca_cert_scheme; + nm_setting_802_1x_get_phase2_ca_path; + nm_setting_802_1x_get_phase2_client_cert_blob; + nm_setting_802_1x_get_phase2_client_cert_path; + nm_setting_802_1x_get_phase2_client_cert_scheme; + nm_setting_802_1x_get_phase2_private_key_blob; + nm_setting_802_1x_get_phase2_private_key_format; + nm_setting_802_1x_get_phase2_private_key_password; + nm_setting_802_1x_get_phase2_private_key_password_flags; + nm_setting_802_1x_get_phase2_private_key_path; + nm_setting_802_1x_get_phase2_private_key_scheme; + nm_setting_802_1x_get_phase2_subject_match; + nm_setting_802_1x_get_pin; + nm_setting_802_1x_get_pin_flags; + nm_setting_802_1x_get_private_key_blob; + nm_setting_802_1x_get_private_key_format; + nm_setting_802_1x_get_private_key_password; + nm_setting_802_1x_get_private_key_password_flags; + nm_setting_802_1x_get_private_key_path; + nm_setting_802_1x_get_private_key_scheme; + nm_setting_802_1x_get_subject_match; + nm_setting_802_1x_get_system_ca_certs; + nm_setting_802_1x_get_type; + nm_setting_802_1x_new; + nm_setting_802_1x_remove_altsubject_match; + nm_setting_802_1x_remove_altsubject_match_by_value; + nm_setting_802_1x_remove_eap_method; + nm_setting_802_1x_remove_eap_method_by_value; + nm_setting_802_1x_remove_phase2_altsubject_match; + nm_setting_802_1x_remove_phase2_altsubject_match_by_value; + nm_setting_802_1x_set_ca_cert; + nm_setting_802_1x_set_client_cert; + nm_setting_802_1x_set_phase2_ca_cert; + nm_setting_802_1x_set_phase2_client_cert; + nm_setting_802_1x_set_phase2_private_key; + nm_setting_802_1x_set_private_key; + nm_setting_adsl_get_encapsulation; + nm_setting_adsl_get_password; + nm_setting_adsl_get_password_flags; + nm_setting_adsl_get_protocol; + nm_setting_adsl_get_type; + nm_setting_adsl_get_username; + nm_setting_adsl_get_vci; + nm_setting_adsl_get_vpi; + nm_setting_adsl_new; + nm_setting_bluetooth_get_bdaddr; + nm_setting_bluetooth_get_connection_type; + nm_setting_bluetooth_get_type; + nm_setting_bluetooth_new; + nm_setting_bond_add_option; + nm_setting_bond_get_num_options; + nm_setting_bond_get_option; + nm_setting_bond_get_option_by_name; + nm_setting_bond_get_option_default; + nm_setting_bond_get_type; + nm_setting_bond_get_valid_options; + nm_setting_bond_new; + nm_setting_bond_remove_option; + nm_setting_bond_validate_option; + nm_setting_bridge_get_ageing_time; + nm_setting_bridge_get_forward_delay; + nm_setting_bridge_get_hello_time; + nm_setting_bridge_get_mac_address; + nm_setting_bridge_get_max_age; + nm_setting_bridge_get_priority; + nm_setting_bridge_get_stp; + nm_setting_bridge_get_type; + nm_setting_bridge_new; + nm_setting_bridge_port_get_hairpin_mode; + nm_setting_bridge_port_get_path_cost; + nm_setting_bridge_port_get_priority; + nm_setting_bridge_port_get_type; + nm_setting_bridge_port_new; + nm_setting_cdma_get_number; + nm_setting_cdma_get_password; + nm_setting_cdma_get_password_flags; + nm_setting_cdma_get_type; + nm_setting_cdma_get_username; + nm_setting_cdma_new; + nm_setting_compare; + nm_setting_compare_flags_get_type; + nm_setting_connection_add_permission; + nm_setting_connection_add_secondary; + nm_setting_connection_get_autoconnect; + nm_setting_connection_get_autoconnect_priority; + nm_setting_connection_get_connection_type; + nm_setting_connection_get_gateway_ping_timeout; + nm_setting_connection_get_id; + nm_setting_connection_get_interface_name; + nm_setting_connection_get_master; + nm_setting_connection_get_num_permissions; + nm_setting_connection_get_num_secondaries; + nm_setting_connection_get_permission; + nm_setting_connection_get_read_only; + nm_setting_connection_get_secondary; + nm_setting_connection_get_slave_type; + nm_setting_connection_get_timestamp; + nm_setting_connection_get_type; + nm_setting_connection_get_uuid; + nm_setting_connection_get_zone; + nm_setting_connection_is_slave_type; + nm_setting_connection_new; + nm_setting_connection_permissions_user_allowed; + nm_setting_connection_remove_permission; + nm_setting_connection_remove_permission_by_value; + nm_setting_connection_remove_secondary; + nm_setting_connection_remove_secondary_by_value; + nm_setting_dcb_flags_get_type; + nm_setting_dcb_get_app_fcoe_flags; + nm_setting_dcb_get_app_fcoe_mode; + nm_setting_dcb_get_app_fcoe_priority; + nm_setting_dcb_get_app_fip_flags; + nm_setting_dcb_get_app_fip_priority; + nm_setting_dcb_get_app_iscsi_flags; + nm_setting_dcb_get_app_iscsi_priority; + nm_setting_dcb_get_priority_bandwidth; + nm_setting_dcb_get_priority_flow_control; + nm_setting_dcb_get_priority_flow_control_flags; + nm_setting_dcb_get_priority_group_bandwidth; + nm_setting_dcb_get_priority_group_flags; + nm_setting_dcb_get_priority_group_id; + nm_setting_dcb_get_priority_strict_bandwidth; + nm_setting_dcb_get_priority_traffic_class; + nm_setting_dcb_get_type; + nm_setting_dcb_new; + nm_setting_dcb_set_priority_bandwidth; + nm_setting_dcb_set_priority_flow_control; + nm_setting_dcb_set_priority_group_bandwidth; + nm_setting_dcb_set_priority_group_id; + nm_setting_dcb_set_priority_strict_bandwidth; + nm_setting_dcb_set_priority_traffic_class; + nm_setting_diff; + nm_setting_diff_result_get_type; + nm_setting_duplicate; + nm_setting_enumerate_values; + nm_setting_generic_get_type; + nm_setting_generic_new; + nm_setting_get_dbus_property_type; + nm_setting_get_name; + nm_setting_get_secret_flags; + nm_setting_get_type; + nm_setting_gsm_get_apn; + nm_setting_gsm_get_home_only; + nm_setting_gsm_get_network_id; + nm_setting_gsm_get_number; + nm_setting_gsm_get_password; + nm_setting_gsm_get_password_flags; + nm_setting_gsm_get_pin; + nm_setting_gsm_get_pin_flags; + nm_setting_gsm_get_type; + nm_setting_gsm_get_username; + nm_setting_gsm_new; + nm_setting_infiniband_get_mac_address; + nm_setting_infiniband_get_mtu; + nm_setting_infiniband_get_p_key; + nm_setting_infiniband_get_parent; + nm_setting_infiniband_get_transport_mode; + nm_setting_infiniband_get_type; + nm_setting_infiniband_get_virtual_interface_name; + nm_setting_infiniband_new; + nm_setting_ip4_config_get_dhcp_client_id; + nm_setting_ip4_config_get_type; + nm_setting_ip4_config_new; + nm_setting_ip6_config_get_ip6_privacy; + nm_setting_ip6_config_get_type; + nm_setting_ip6_config_new; + nm_setting_ip6_config_privacy_get_type; + nm_setting_ip_config_add_address; + nm_setting_ip_config_add_dns; + nm_setting_ip_config_add_dns_search; + nm_setting_ip_config_add_route; + nm_setting_ip_config_clear_addresses; + nm_setting_ip_config_clear_dns; + nm_setting_ip_config_clear_dns_searches; + nm_setting_ip_config_clear_routes; + nm_setting_ip_config_get_address; + nm_setting_ip_config_get_dhcp_hostname; + nm_setting_ip_config_get_dhcp_send_hostname; + nm_setting_ip_config_get_dns; + nm_setting_ip_config_get_dns_search; + nm_setting_ip_config_get_gateway; + nm_setting_ip_config_get_ignore_auto_dns; + nm_setting_ip_config_get_ignore_auto_routes; + nm_setting_ip_config_get_may_fail; + nm_setting_ip_config_get_method; + nm_setting_ip_config_get_never_default; + nm_setting_ip_config_get_num_addresses; + nm_setting_ip_config_get_num_dns; + nm_setting_ip_config_get_num_dns_searches; + nm_setting_ip_config_get_num_routes; + nm_setting_ip_config_get_route; + nm_setting_ip_config_get_route_metric; + nm_setting_ip_config_get_type; + nm_setting_ip_config_remove_address; + nm_setting_ip_config_remove_address_by_value; + nm_setting_ip_config_remove_dns; + nm_setting_ip_config_remove_dns_by_value; + nm_setting_ip_config_remove_dns_search; + nm_setting_ip_config_remove_dns_search_by_value; + nm_setting_ip_config_remove_route; + nm_setting_ip_config_remove_route_by_value; + nm_setting_lookup_type; + nm_setting_olpc_mesh_get_channel; + nm_setting_olpc_mesh_get_dhcp_anycast_address; + nm_setting_olpc_mesh_get_ssid; + nm_setting_olpc_mesh_get_type; + nm_setting_olpc_mesh_new; + nm_setting_ppp_get_baud; + nm_setting_ppp_get_crtscts; + nm_setting_ppp_get_lcp_echo_failure; + nm_setting_ppp_get_lcp_echo_interval; + nm_setting_ppp_get_mppe_stateful; + nm_setting_ppp_get_mru; + nm_setting_ppp_get_mtu; + nm_setting_ppp_get_no_vj_comp; + nm_setting_ppp_get_noauth; + nm_setting_ppp_get_nobsdcomp; + nm_setting_ppp_get_nodeflate; + nm_setting_ppp_get_refuse_chap; + nm_setting_ppp_get_refuse_eap; + nm_setting_ppp_get_refuse_mschap; + nm_setting_ppp_get_refuse_mschapv2; + nm_setting_ppp_get_refuse_pap; + nm_setting_ppp_get_require_mppe; + nm_setting_ppp_get_require_mppe_128; + nm_setting_ppp_get_type; + nm_setting_ppp_new; + nm_setting_pppoe_get_password; + nm_setting_pppoe_get_password_flags; + nm_setting_pppoe_get_service; + nm_setting_pppoe_get_type; + nm_setting_pppoe_get_username; + nm_setting_pppoe_new; + nm_setting_secret_flags_get_type; + nm_setting_serial_get_baud; + nm_setting_serial_get_bits; + nm_setting_serial_get_parity; + nm_setting_serial_get_send_delay; + nm_setting_serial_get_stopbits; + nm_setting_serial_get_type; + nm_setting_serial_new; + nm_setting_serial_parity_get_type; + nm_setting_set_secret_flags; + nm_setting_team_get_config; + nm_setting_team_get_type; + nm_setting_team_new; + nm_setting_team_port_get_config; + nm_setting_team_port_get_type; + nm_setting_team_port_new; + nm_setting_to_string; + nm_setting_verify; + nm_setting_vlan_add_priority; + nm_setting_vlan_add_priority_str; + nm_setting_vlan_clear_priorities; + nm_setting_vlan_get_flags; + nm_setting_vlan_get_id; + nm_setting_vlan_get_num_priorities; + nm_setting_vlan_get_parent; + nm_setting_vlan_get_priority; + nm_setting_vlan_get_type; + nm_setting_vlan_new; + nm_setting_vlan_remove_priority; + nm_setting_vlan_remove_priority_by_value; + nm_setting_vlan_remove_priority_str_by_value; + nm_setting_vpn_add_data_item; + nm_setting_vpn_add_secret; + nm_setting_vpn_foreach_data_item; + nm_setting_vpn_foreach_secret; + nm_setting_vpn_get_data_item; + nm_setting_vpn_get_num_data_items; + nm_setting_vpn_get_num_secrets; + nm_setting_vpn_get_secret; + nm_setting_vpn_get_service_type; + nm_setting_vpn_get_type; + nm_setting_vpn_get_user_name; + nm_setting_vpn_new; + nm_setting_vpn_remove_data_item; + nm_setting_vpn_remove_secret; + nm_setting_wimax_get_mac_address; + nm_setting_wimax_get_network_name; + nm_setting_wimax_get_type; + nm_setting_wimax_new; + nm_setting_wired_add_mac_blacklist_item; + nm_setting_wired_add_s390_option; + nm_setting_wired_clear_mac_blacklist_items; + nm_setting_wired_get_auto_negotiate; + nm_setting_wired_get_cloned_mac_address; + nm_setting_wired_get_duplex; + nm_setting_wired_get_mac_address; + nm_setting_wired_get_mac_address_blacklist; + nm_setting_wired_get_mac_blacklist_item; + nm_setting_wired_get_mtu; + nm_setting_wired_get_num_mac_blacklist_items; + nm_setting_wired_get_num_s390_options; + nm_setting_wired_get_port; + nm_setting_wired_get_s390_nettype; + nm_setting_wired_get_s390_option; + nm_setting_wired_get_s390_option_by_key; + nm_setting_wired_get_s390_subchannels; + nm_setting_wired_get_speed; + nm_setting_wired_get_type; + nm_setting_wired_get_valid_s390_options; + nm_setting_wired_new; + nm_setting_wired_remove_mac_blacklist_item; + nm_setting_wired_remove_mac_blacklist_item_by_value; + nm_setting_wired_remove_s390_option; + nm_setting_wireless_add_mac_blacklist_item; + nm_setting_wireless_add_seen_bssid; + nm_setting_wireless_ap_security_compatible; + nm_setting_wireless_clear_mac_blacklist_items; + nm_setting_wireless_get_band; + nm_setting_wireless_get_bssid; + nm_setting_wireless_get_channel; + nm_setting_wireless_get_cloned_mac_address; + nm_setting_wireless_get_hidden; + nm_setting_wireless_get_mac_address; + nm_setting_wireless_get_mac_address_blacklist; + nm_setting_wireless_get_mac_blacklist_item; + nm_setting_wireless_get_mode; + nm_setting_wireless_get_mtu; + nm_setting_wireless_get_num_mac_blacklist_items; + nm_setting_wireless_get_num_seen_bssids; + nm_setting_wireless_get_rate; + nm_setting_wireless_get_seen_bssid; + nm_setting_wireless_get_ssid; + nm_setting_wireless_get_tx_power; + nm_setting_wireless_get_type; + nm_setting_wireless_new; + nm_setting_wireless_remove_mac_blacklist_item; + nm_setting_wireless_remove_mac_blacklist_item_by_value; + nm_setting_wireless_security_add_group; + nm_setting_wireless_security_add_pairwise; + nm_setting_wireless_security_add_proto; + nm_setting_wireless_security_clear_groups; + nm_setting_wireless_security_clear_pairwise; + nm_setting_wireless_security_clear_protos; + nm_setting_wireless_security_get_auth_alg; + nm_setting_wireless_security_get_group; + nm_setting_wireless_security_get_key_mgmt; + nm_setting_wireless_security_get_leap_password; + nm_setting_wireless_security_get_leap_password_flags; + nm_setting_wireless_security_get_leap_username; + nm_setting_wireless_security_get_num_groups; + nm_setting_wireless_security_get_num_pairwise; + nm_setting_wireless_security_get_num_protos; + nm_setting_wireless_security_get_pairwise; + nm_setting_wireless_security_get_proto; + nm_setting_wireless_security_get_psk; + nm_setting_wireless_security_get_psk_flags; + nm_setting_wireless_security_get_type; + nm_setting_wireless_security_get_wep_key; + nm_setting_wireless_security_get_wep_key_flags; + nm_setting_wireless_security_get_wep_key_type; + nm_setting_wireless_security_get_wep_tx_keyidx; + nm_setting_wireless_security_new; + nm_setting_wireless_security_remove_group; + nm_setting_wireless_security_remove_group_by_value; + nm_setting_wireless_security_remove_pairwise; + nm_setting_wireless_security_remove_pairwise_by_value; + nm_setting_wireless_security_remove_proto; + nm_setting_wireless_security_remove_proto_by_value; + nm_setting_wireless_security_set_wep_key; + nm_settings_error_get_type; + nm_settings_error_quark; + nm_simple_connection_get_type; + nm_simple_connection_new; + nm_simple_connection_new_clone; + nm_simple_connection_new_from_dbus; + nm_state_get_type; + nm_utils_ap_mode_security_valid; + nm_utils_bin2hexstr; + nm_utils_check_virtual_device_compatibility; + nm_utils_escape_ssid; + nm_utils_file_is_certificate; + nm_utils_file_is_pkcs12; + nm_utils_file_is_private_key; + nm_utils_file_search_in_paths; + nm_utils_hexstr2bin; + nm_utils_hwaddr_atoba; + nm_utils_hwaddr_aton; + nm_utils_hwaddr_canonical; + nm_utils_hwaddr_len; + nm_utils_hwaddr_matches; + nm_utils_hwaddr_ntoa; + nm_utils_hwaddr_valid; + nm_utils_iface_valid_name; + nm_utils_inet4_ntop; + nm_utils_inet6_ntop; + nm_utils_ip4_addresses_from_variant; + nm_utils_ip4_addresses_to_variant; + nm_utils_ip4_dns_from_variant; + nm_utils_ip4_dns_to_variant; + nm_utils_ip4_get_default_prefix; + nm_utils_ip4_netmask_to_prefix; + nm_utils_ip4_prefix_to_netmask; + nm_utils_ip4_routes_from_variant; + nm_utils_ip4_routes_to_variant; + nm_utils_ip6_addresses_from_variant; + nm_utils_ip6_addresses_to_variant; + nm_utils_ip6_dns_from_variant; + nm_utils_ip6_dns_to_variant; + nm_utils_ip6_routes_from_variant; + nm_utils_ip6_routes_to_variant; + nm_utils_ipaddr_valid; + nm_utils_is_empty_ssid; + nm_utils_is_uuid; + nm_utils_same_ssid; + nm_utils_security_type_get_type; + nm_utils_security_valid; + nm_utils_ssid_to_utf8; + nm_utils_uuid_generate; + nm_utils_wep_key_valid; + nm_utils_wifi_channel_to_freq; + nm_utils_wifi_find_next_channel; + nm_utils_wifi_freq_to_channel; + nm_utils_wifi_is_channel_valid; + nm_utils_wifi_strength_bars; + nm_utils_wpa_psk_valid; + nm_vlan_flags_get_type; + nm_vlan_priority_map_get_type; + nm_vpn_connection_get_banner; + nm_vpn_connection_get_type; + nm_vpn_connection_get_vpn_state; + nm_vpn_connection_state_get_type; + nm_vpn_connection_state_reason_get_type; + nm_vpn_editor_get_type; + nm_vpn_editor_get_widget; + nm_vpn_editor_plugin_capability_get_type; + nm_vpn_editor_plugin_export; + nm_vpn_editor_plugin_get_capabilities; + nm_vpn_editor_plugin_get_editor; + nm_vpn_editor_plugin_get_suggested_filename; + nm_vpn_editor_plugin_get_type; + nm_vpn_editor_plugin_import; + nm_vpn_editor_update_connection; + nm_vpn_plugin_error_get_type; + nm_vpn_plugin_error_quark; + nm_vpn_plugin_failure_get_type; + nm_vpn_plugin_old_disconnect; + nm_vpn_plugin_old_failure; + nm_vpn_plugin_old_get_connection; + nm_vpn_plugin_old_get_secret_flags; + nm_vpn_plugin_old_get_state; + nm_vpn_plugin_old_get_type; + nm_vpn_plugin_old_read_vpn_details; + nm_vpn_plugin_old_secrets_required; + nm_vpn_plugin_old_set_ip4_config; + nm_vpn_plugin_old_set_login_banner; + nm_vpn_plugin_old_set_state; + nm_vpn_service_state_get_type; + nm_wep_key_type_get_type; + nm_wimax_nsp_connection_valid; + nm_wimax_nsp_filter_connections; + nm_wimax_nsp_get_name; + nm_wimax_nsp_get_network_type; + nm_wimax_nsp_get_signal_quality; + nm_wimax_nsp_get_type; + nm_wimax_nsp_network_type_get_type; +local: + *; +}; + +libnm_1_0_4 { + #nm_setting_connection_autoconnect_slaves_get_type@libnm_1_0_4; + #nm_setting_connection_get_autoconnect_slaves@libnm_1_0_4; +} libnm_1_0_0; + +libnm_1_0_6 { + #nm_access_point_get_last_seen@libnm_1_0_6; + #nm_device_get_metered@libnm_1_0_6; + #nm_device_wifi_request_scan_options@libnm_1_0_6; + #nm_device_wifi_request_scan_options_async@libnm_1_0_6; + #nm_metered_get_type@libnm_1_0_6; + #nm_setting_connection_get_metered@libnm_1_0_6; + #nm_setting_wired_get_wake_on_lan@libnm_1_0_6; + #nm_setting_wired_get_wake_on_lan_password@libnm_1_0_6; + #nm_setting_wired_wake_on_lan_get_type@libnm_1_0_6; + #nm_utils_enum_from_str@libnm_1_0_6; + #nm_utils_enum_to_str@libnm_1_0_6; + #nm_utils_wifi_2ghz_freqs@libnm_1_0_6; + #nm_utils_wifi_5ghz_freqs@libnm_1_0_6; +} libnm_1_0_4; + +libnm_1_2_0 { +global: + nm_access_point_get_last_seen; + nm_client_get_all_devices; + nm_connection_get_setting_ip_tunnel; + nm_connection_get_setting_macvlan; + nm_connection_get_setting_vxlan; + nm_connection_verify_secrets; + nm_device_ethernet_get_s390_subchannels; + nm_device_get_applied_connection; + nm_device_get_applied_connection_async; + nm_device_get_applied_connection_finish; + nm_device_get_lldp_neighbors; + nm_device_get_metered; + nm_device_get_nm_plugin_missing; + nm_device_ip_tunnel_get_encapsulation_limit; + nm_device_ip_tunnel_get_flow_label; + nm_device_ip_tunnel_get_input_key; + nm_device_ip_tunnel_get_local; + nm_device_ip_tunnel_get_mode; + nm_device_ip_tunnel_get_output_key; + nm_device_ip_tunnel_get_parent; + nm_device_ip_tunnel_get_path_mtu_discovery; + nm_device_ip_tunnel_get_remote; + nm_device_ip_tunnel_get_tos; + nm_device_ip_tunnel_get_ttl; + nm_device_ip_tunnel_get_type; + nm_device_is_real; + nm_device_macvlan_get_hw_address; + nm_device_macvlan_get_mode; + nm_device_macvlan_get_no_promisc; + nm_device_macvlan_get_parent; + nm_device_macvlan_get_tap; + nm_device_macvlan_get_type; + nm_device_reapply; + nm_device_reapply_async; + nm_device_reapply_finish; + nm_device_set_managed; + nm_device_tun_get_group; + nm_device_tun_get_hw_address; + nm_device_tun_get_mode; + nm_device_tun_get_multi_queue; + nm_device_tun_get_owner; + nm_device_tun_get_no_pi; + nm_device_tun_get_type; + nm_device_tun_get_vnet_hdr; + nm_device_vxlan_get_ageing; + nm_device_vxlan_get_dst_port; + nm_device_vxlan_get_group; + nm_device_vxlan_get_hw_address; + nm_device_vxlan_get_id; + nm_device_vxlan_get_l2miss; + nm_device_vxlan_get_l3miss; + nm_device_vxlan_get_learning; + nm_device_vxlan_get_limit; + nm_device_vxlan_get_local; + nm_device_vxlan_get_parent; + nm_device_vxlan_get_proxy; + nm_device_vxlan_get_src_port_max; + nm_device_vxlan_get_src_port_min; + nm_device_vxlan_get_tos; + nm_device_vxlan_get_ttl; + nm_device_vxlan_get_type; + nm_device_wifi_request_scan_options; + nm_device_wifi_request_scan_options_async; + nm_ip_tunnel_mode_get_type; + nm_lldp_neighbor_get_attr_names; + nm_lldp_neighbor_get_attr_string_value; + nm_lldp_neighbor_get_attr_type; + nm_lldp_neighbor_get_attr_uint_value; + nm_lldp_neighbor_get_type; + nm_lldp_neighbor_new; + nm_lldp_neighbor_ref; + nm_lldp_neighbor_unref; + nm_metered_get_type; + nm_setting_802_1x_check_cert_scheme; + nm_setting_802_1x_get_domain_suffix_match; + nm_setting_802_1x_get_phase2_domain_suffix_match; + nm_setting_bridge_get_multicast_snooping; + nm_setting_connection_autoconnect_slaves_get_type; + nm_setting_connection_get_autoconnect_slaves; + nm_setting_connection_get_lldp; + nm_setting_connection_get_metered; + nm_setting_connection_lldp_get_type; + nm_setting_gsm_get_device_id; + nm_setting_gsm_get_sim_id; + nm_setting_gsm_get_sim_operator_id; + nm_setting_ip4_config_get_dhcp_fqdn; + nm_setting_ip6_config_addr_gen_mode_get_type; + nm_setting_ip6_config_get_addr_gen_mode; + nm_setting_ip_config_add_dns_option; + nm_setting_ip_config_clear_dns_options; + nm_setting_ip_config_get_dad_timeout; + nm_setting_ip_config_get_dhcp_timeout; + nm_setting_ip_config_get_dns_option; + nm_setting_ip_config_get_num_dns_options; + nm_setting_ip_config_has_dns_options; + nm_setting_ip_config_remove_dns_option; + nm_setting_ip_config_remove_dns_option_by_value; + nm_setting_ip_tunnel_get_input_key; + nm_setting_ip_tunnel_get_local; + nm_setting_ip_tunnel_get_mode; + nm_setting_ip_tunnel_get_mtu; + nm_setting_ip_tunnel_get_output_key; + nm_setting_ip_tunnel_get_parent; + nm_setting_ip_tunnel_get_path_mtu_discovery; + nm_setting_ip_tunnel_get_remote; + nm_setting_ip_tunnel_get_tos; + nm_setting_ip_tunnel_get_type; + nm_setting_ip_tunnel_get_ttl; + nm_setting_ip_tunnel_new; + nm_setting_mac_randomization_get_type; + nm_setting_tun_get_group; + nm_setting_tun_get_mode; + nm_setting_tun_get_multi_queue; + nm_setting_tun_get_owner; + nm_setting_tun_get_pi; + nm_setting_tun_get_type; + nm_setting_tun_get_vnet_hdr; + nm_setting_tun_mode_get_type; + nm_setting_tun_new; + nm_setting_verify_secrets; + nm_setting_vpn_get_timeout; + nm_setting_macvlan_get_mode; + nm_setting_macvlan_get_parent; + nm_setting_macvlan_get_promiscuous; + nm_setting_macvlan_get_tap; + nm_setting_macvlan_get_type; + nm_setting_macvlan_mode_get_type; + nm_setting_macvlan_new; + nm_setting_vxlan_get_ageing; + nm_setting_vxlan_get_destination_port; + nm_setting_vxlan_get_id; + nm_setting_vxlan_get_l2_miss; + nm_setting_vxlan_get_l3_miss; + nm_setting_vxlan_get_learning; + nm_setting_vxlan_get_limit; + nm_setting_vxlan_get_local; + nm_setting_vxlan_get_parent; + nm_setting_vxlan_get_proxy; + nm_setting_vxlan_get_remote; + nm_setting_vxlan_get_rsc; + nm_setting_vxlan_get_source_port_max; + nm_setting_vxlan_get_source_port_min; + nm_setting_vxlan_get_tos; + nm_setting_vxlan_get_ttl; + nm_setting_vxlan_get_type; + nm_setting_vxlan_new; + nm_setting_wired_get_wake_on_lan; + nm_setting_wired_get_wake_on_lan_password; + nm_setting_wired_wake_on_lan_get_type; + nm_setting_wireless_get_powersave; + nm_setting_wireless_get_mac_address_randomization; + nm_setting_wireless_powersave_get_type; + nm_utils_bond_mode_int_to_string; + nm_utils_bond_mode_string_to_int; + nm_utils_enum_from_str; + nm_utils_enum_to_str; + nm_utils_enum_get_values; + nm_utils_wifi_2ghz_freqs; + nm_utils_wifi_5ghz_freqs; + nm_vpn_editor_plugin_load_from_file; + nm_vpn_plugin_info_get_filename; + nm_vpn_plugin_info_get_editor_plugin; + nm_vpn_plugin_info_get_name; + nm_vpn_plugin_info_get_plugin; + nm_vpn_plugin_info_get_program; + nm_vpn_plugin_info_get_type; + nm_vpn_plugin_info_load_editor_plugin; + nm_vpn_plugin_info_lookup_property; + nm_vpn_plugin_info_new_from_file; + nm_vpn_plugin_info_new_with_data; + nm_vpn_plugin_info_set_editor_plugin; + nm_vpn_plugin_info_validate_filename; + nm_vpn_plugin_info_list_add; + nm_vpn_plugin_info_list_find_by_filename; + nm_vpn_plugin_info_list_find_by_name; + nm_vpn_plugin_info_list_find_by_service; + nm_vpn_plugin_info_list_load; + nm_vpn_plugin_info_list_remove; + nm_vpn_service_plugin_disconnect; + nm_vpn_service_plugin_failure; + nm_vpn_service_plugin_get_connection; + nm_vpn_service_plugin_get_secret_flags; + nm_vpn_service_plugin_get_type; + nm_vpn_service_plugin_read_vpn_details; + nm_vpn_service_plugin_secrets_required; + nm_vpn_service_plugin_set_config; + nm_vpn_service_plugin_set_ip4_config; + nm_vpn_service_plugin_set_ip6_config; + nm_vpn_service_plugin_set_login_banner; +} libnm_1_0_0; + +libnm_1_2_4 { + #nm_setting_ip_config_get_dns_priority@libnm_1_2_4; +} libnm_1_2_0; + +libnm_1_4_0 { +global: + nm_device_team_get_config; + nm_setting_connection_get_stable_id; + nm_setting_ip6_config_get_token; + nm_setting_ip_config_get_dns_priority; + nm_setting_wired_get_generate_mac_address_mask; + nm_setting_wireless_get_generate_mac_address_mask; + nm_vpn_editor_plugin_get_plugin_info; + nm_vpn_editor_plugin_get_vt; + nm_vpn_editor_plugin_load; + nm_vpn_editor_plugin_set_plugin_info; + nm_vpn_plugin_info_get_aliases; + nm_vpn_plugin_info_get_auth_dialog; + nm_vpn_plugin_info_get_service; + nm_vpn_plugin_info_list_get_service_types; + nm_vpn_plugin_info_list_find_service_type; + nm_vpn_plugin_info_new_search_file; + nm_vpn_plugin_info_supports_hints; +} libnm_1_2_0; + +libnm_1_6_0 { +global: + nm_capability_get_type; + nm_client_get_dns_configuration; + nm_client_get_dns_mode; + nm_client_get_dns_rc_manager; + nm_connection_get_setting_macsec; + nm_connection_get_setting_proxy; + nm_device_macsec_get_cipher_suite; + nm_device_macsec_get_encoding_sa; + nm_device_macsec_get_encrypt; + nm_device_macsec_get_es; + nm_device_macsec_get_hw_address; + nm_device_macsec_get_icv_length; + nm_device_macsec_get_include_sci; + nm_device_macsec_get_protect; + nm_device_macsec_get_replay_protect; + nm_device_macsec_get_scb; + nm_device_macsec_get_sci; + nm_device_macsec_get_type; + nm_device_macsec_get_validation; + nm_device_macsec_get_window; + nm_dns_entry_get_domains; + nm_dns_entry_get_interface; + nm_dns_entry_get_nameservers; + nm_dns_entry_get_priority; + nm_dns_entry_get_type; + nm_dns_entry_get_vpn; + nm_dns_entry_unref; + nm_setting_connection_get_autoconnect_retries; + nm_setting_macsec_get_encrypt; + nm_setting_macsec_get_mka_cak; + nm_setting_macsec_get_mka_cak_flags; + nm_setting_macsec_get_mka_ckn; + nm_setting_macsec_get_mode; + nm_setting_macsec_get_parent; + nm_setting_macsec_get_port; + nm_setting_macsec_get_type; + nm_setting_macsec_get_validation; + nm_setting_macsec_mode_get_type; + nm_setting_macsec_new; + nm_setting_macsec_validation_get_type; + nm_setting_proxy_get_type; + nm_setting_proxy_new; + nm_setting_proxy_get_method; + nm_setting_proxy_method_get_type; + nm_setting_proxy_get_browser_only; + nm_setting_proxy_get_pac_url; + nm_setting_proxy_get_pac_script; + nm_setting_802_1x_get_ca_cert_uri; + nm_setting_802_1x_get_phase2_ca_cert_uri; + nm_setting_802_1x_get_client_cert_uri; + nm_setting_802_1x_get_phase2_client_cert_uri; + nm_setting_802_1x_get_private_key_uri; + nm_setting_802_1x_get_phase2_private_key_uri; + nm_utils_is_json_object; + nm_utils_version; + nm_utils_is_valid_iface_name; +} libnm_1_4_0; + +libnm_1_8_0 { +global: + nm_active_connection_state_reason_get_type; + nm_active_connection_get_state_reason; + nm_connection_get_setting_dummy; + nm_device_dummy_get_type; + nm_ip_route_get_variant_attribute_spec; + nm_ip_route_attribute_validate; + nm_setting_802_1x_auth_flags_get_type; + nm_setting_802_1x_get_auth_timeout; + nm_setting_802_1x_get_ca_cert_password; + nm_setting_802_1x_get_ca_cert_password_flags; + nm_setting_802_1x_get_client_cert_password; + nm_setting_802_1x_get_client_cert_password_flags; + nm_setting_802_1x_get_phase1_auth_flags; + nm_setting_802_1x_get_phase2_ca_cert_password; + nm_setting_802_1x_get_phase2_ca_cert_password_flags; + nm_setting_802_1x_get_phase2_client_cert_password; + nm_setting_802_1x_get_phase2_client_cert_password_flags; + nm_setting_cdma_get_mtu; + nm_setting_dummy_get_type; + nm_setting_dummy_new; + nm_setting_gsm_get_mtu; + nm_setting_user_check_key; + nm_setting_user_check_val; + nm_setting_user_get_data; + nm_setting_user_get_keys; + nm_setting_user_get_type; + nm_setting_user_new; + nm_setting_user_set_data; + nm_utils_format_variant_attributes; + nm_utils_parse_variant_attributes; +} libnm_1_6_0; + +libnm_1_10_0 { +global: + nm_activation_state_flags_get_type; + nm_active_connection_get_state_flags; + nm_client_connectivity_check_get_available; + nm_client_connectivity_check_get_enabled; + nm_client_connectivity_check_set_enabled; + nm_connection_get_settings; + nm_device_dummy_get_hw_address; + nm_device_ovs_bridge_get_type; + nm_device_ovs_interface_get_type; + nm_device_ovs_port_get_type; + nm_device_ppp_get_type; + nm_ip_route_equal_full; + nm_setting_bridge_get_group_forward_mask; + nm_setting_connection_get_auth_retries; + nm_setting_ip_config_get_route_table; + nm_setting_ovs_bridge_get_fail_mode; + nm_setting_ovs_bridge_get_mcast_snooping_enable; + nm_setting_ovs_bridge_get_rstp_enable; + nm_setting_ovs_bridge_get_stp_enable; + nm_setting_ovs_bridge_get_type; + nm_setting_ovs_bridge_new; + nm_setting_ovs_interface_get_interface_type; + nm_setting_ovs_interface_get_type; + nm_setting_ovs_interface_new; + nm_setting_ovs_patch_get_peer; + nm_setting_ovs_patch_get_type; + nm_setting_ovs_patch_new; + nm_setting_ovs_port_get_bond_downdelay; + nm_setting_ovs_port_get_bond_mode; + nm_setting_ovs_port_get_bond_updelay; + nm_setting_ovs_port_get_lacp; + nm_setting_ovs_port_get_tag; + nm_setting_ovs_port_get_type; + nm_setting_ovs_port_get_vlan_mode; + nm_setting_ovs_port_new; + nm_setting_pppoe_get_parent; + nm_setting_wireless_security_get_pmf; + nm_setting_wireless_security_get_wps_method; + nm_setting_wireless_security_pmf_get_type; + nm_setting_wireless_security_wps_method_get_type; +} libnm_1_8_0; + +libnm_1_10_2 { +global: + nm_remote_connection_update2; + nm_remote_connection_update2_finish; + nm_settings_update2_flags_get_type; + nm_setting_tc_config_add_qdisc; + nm_setting_tc_config_add_tfilter; + nm_setting_tc_config_clear_qdiscs; + nm_setting_tc_config_clear_tfilters; + nm_setting_tc_config_get_num_qdiscs; + nm_setting_tc_config_get_num_tfilters; + nm_setting_tc_config_get_qdisc; + nm_setting_tc_config_get_tfilter; + nm_setting_tc_config_get_type; + nm_setting_tc_config_new; + nm_setting_tc_config_remove_qdisc; + nm_setting_tc_config_remove_qdisc_by_value; + nm_setting_tc_config_remove_tfilter; + nm_setting_tc_config_remove_tfilter_by_value; + nm_setting_team_add_link_watcher; + nm_setting_team_add_runner_tx_hash; + nm_setting_team_clear_link_watchers; + nm_setting_team_get_link_watcher; + nm_setting_team_get_mcast_rejoin_count; + nm_setting_team_get_mcast_rejoin_interval; + nm_setting_team_get_notify_peers_count; + nm_setting_team_get_notify_peers_interval; + nm_setting_team_get_num_link_watchers; + nm_setting_team_get_num_runner_tx_hash; + nm_setting_team_get_runner; + nm_setting_team_get_runner_active; + nm_setting_team_get_runner_agg_select_policy; + nm_setting_team_get_runner_fast_rate; + nm_setting_team_get_runner_hwaddr_policy; + nm_setting_team_get_runner_min_ports; + nm_setting_team_get_runner_sys_prio; + nm_setting_team_get_runner_tx_balancer; + nm_setting_team_get_runner_tx_balancer_interval; + nm_setting_team_get_runner_tx_hash; + nm_setting_team_port_add_link_watcher; + nm_setting_team_port_clear_link_watchers; + nm_setting_team_port_get_lacp_key; + nm_setting_team_port_get_lacp_prio; + nm_setting_team_port_get_link_watcher; + nm_setting_team_port_get_num_link_watchers; + nm_setting_team_port_get_prio; + nm_setting_team_port_get_queue_id; + nm_setting_team_port_get_sticky; + nm_setting_team_port_remove_link_watcher; + nm_setting_team_port_remove_link_watcher_by_value; + nm_setting_team_remove_link_watcher; + nm_setting_team_remove_link_watcher_by_value; + nm_setting_team_remove_runner_tx_hash; + nm_setting_team_remove_runner_tx_hash_by_value; + nm_tc_action_dup; + nm_tc_action_equal; + nm_tc_action_get_attribute; + nm_tc_action_get_attribute_names; + nm_tc_action_get_kind; + nm_tc_action_get_type; + nm_tc_action_new; + nm_tc_action_ref; + nm_tc_action_set_attribute; + nm_tc_action_unref; + nm_tc_qdisc_dup; + nm_tc_qdisc_equal; + nm_tc_qdisc_get_handle; + nm_tc_qdisc_get_kind; + nm_tc_qdisc_get_parent; + nm_tc_qdisc_get_type; + nm_tc_qdisc_new; + nm_tc_qdisc_ref; + nm_tc_qdisc_set_handle; + nm_tc_qdisc_unref; + nm_tc_tfilter_dup; + nm_tc_tfilter_equal; + nm_tc_tfilter_get_handle; + nm_tc_tfilter_get_kind; + nm_tc_tfilter_get_parent; + nm_tc_tfilter_get_type; + nm_tc_tfilter_new; + nm_tc_tfilter_ref; + nm_tc_tfilter_set_handle; + nm_tc_tfilter_unref; + nm_team_link_watcher_arp_ping_flags_get_type; + nm_team_link_watcher_dup; + nm_team_link_watcher_equal; + nm_team_link_watcher_get_delay_down; + nm_team_link_watcher_get_delay_up; + nm_team_link_watcher_get_flags; + nm_team_link_watcher_get_init_wait; + nm_team_link_watcher_get_interval; + nm_team_link_watcher_get_missed_max; + nm_team_link_watcher_get_name; + nm_team_link_watcher_get_source_host; + nm_team_link_watcher_get_target_host; + nm_team_link_watcher_get_type; + nm_team_link_watcher_new_arp_ping; + nm_team_link_watcher_new_ethtool; + nm_team_link_watcher_new_nsna_ping; + nm_team_link_watcher_ref; + nm_team_link_watcher_unref; + nm_utils_tc_action_from_str; + nm_utils_tc_action_to_str; + nm_utils_tc_qdisc_from_str; + nm_utils_tc_qdisc_to_str; + nm_utils_tc_tfilter_from_str; + nm_utils_tc_tfilter_to_str; +} libnm_1_10_0; + +libnm_1_10_14 { + #nm_setting_connection_get_mdns@libnm_1_10_14; + #nm_setting_connection_mdns_get_type@libnm_1_10_14; +} libnm_1_10_2; + +libnm_1_12_0 { +global: + nm_checkpoint_create_flags_get_type; + nm_checkpoint_get_created; + nm_checkpoint_get_devices; + nm_checkpoint_get_rollback_timeout; + nm_checkpoint_get_type; + nm_client_checkpoint_adjust_rollback_timeout; + nm_client_checkpoint_adjust_rollback_timeout_finish; + nm_client_checkpoint_create; + nm_client_checkpoint_create_finish; + nm_client_checkpoint_destroy; + nm_client_checkpoint_destroy_finish; + nm_client_checkpoint_rollback; + nm_client_checkpoint_rollback_finish; + nm_client_get_checkpoints; + nm_connection_get_setting_tc_config; + nm_device_ip_tunnel_get_flags; + nm_device_wifi_get_last_scan; + nm_ip_tunnel_flags_get_type; + nm_remote_connection_get_filename; + nm_remote_connection_get_flags; + nm_setting_connection_get_mdns; + nm_setting_connection_mdns_get_type; + nm_setting_ip_tunnel_get_flags; + nm_setting_ip6_config_get_dhcp_duid; + nm_setting_macsec_get_send_sci; + nm_setting_vpn_get_data_keys; + nm_setting_vpn_get_secret_keys; + nm_setting_wireless_security_get_fils; + nm_setting_wireless_security_fils_get_type; + nm_setting_wireless_get_wake_on_wlan; + nm_setting_wireless_wake_on_wlan_get_type; + nm_settings_connection_flags_get_type; + nm_utils_get_timestamp_msec; + nm_vpn_service_plugin_shutdown; +} libnm_1_10_0; + +libnm_1_12_2 { + nm_connection_get_setting_ovs_bridge; + nm_connection_get_setting_ovs_interface; + nm_connection_get_setting_ovs_patch; + nm_connection_get_setting_ovs_port; + nm_connection_get_setting_tun; + nm_device_ovs_bridge_get_slaves; + nm_device_ovs_port_get_slaves; +} libnm_1_12_0; + +libnm_1_14_0 { +global: + nm_connection_multi_connect_get_type; + nm_device_6lowpan_get_type; + nm_device_wireguard_get_fwmark; + nm_device_wireguard_get_listen_port; + nm_device_wireguard_get_public_key; + nm_device_wireguard_get_type; + nm_device_wpan_get_type; + nm_setting_6lowpan_get_type; + nm_setting_connection_get_llmnr; + nm_setting_connection_get_multi_connect; + nm_setting_connection_llmnr_get_type; + nm_setting_ethtool_clear_features; + nm_setting_ethtool_get_feature; + nm_setting_ethtool_get_type; + nm_setting_ethtool_new; + nm_setting_ethtool_set_feature; + nm_setting_match_add_interface_name; + nm_setting_match_clear_interface_names; + nm_setting_match_get_interface_name; + nm_setting_match_get_interface_names; + nm_setting_match_get_num_interface_names; + nm_setting_match_get_type; + nm_setting_match_remove_interface_name; + nm_setting_match_remove_interface_name_by_value; + nm_setting_sriov_add_vf; + nm_setting_sriov_clear_vfs; + nm_setting_sriov_get_autoprobe_drivers; + nm_setting_sriov_get_num_vfs; + nm_setting_sriov_get_total_vfs; + nm_setting_sriov_get_type; + nm_setting_sriov_get_vf; + nm_setting_sriov_new; + nm_setting_sriov_remove_vf; + nm_setting_sriov_remove_vf_by_index; + nm_setting_wpan_get_type; + nm_sriov_vf_add_vlan; + nm_sriov_vf_dup; + nm_sriov_vf_equal; + nm_sriov_vf_get_attribute; + nm_sriov_vf_get_attribute_names; + nm_sriov_vf_get_index; + nm_sriov_vf_get_type; + nm_sriov_vf_get_vlan_ids; + nm_sriov_vf_get_vlan_protocol; + nm_sriov_vf_get_vlan_qos; + nm_sriov_vf_new; + nm_sriov_vf_ref; + nm_sriov_vf_remove_vlan; + nm_sriov_vf_set_attribute; + nm_sriov_vf_set_vlan_protocol; + nm_sriov_vf_set_vlan_qos; + nm_sriov_vf_unref; + nm_sriov_vf_vlan_protocol_get_type; + nm_ternary_get_type; + nm_utils_sriov_vf_from_str; + nm_utils_sriov_vf_to_str; +} libnm_1_12_0; + +libnm_1_14_8 { + nm_ethtool_optname_is_feature; +} libnm_1_14_0; + +libnm_1_16_0 { +global: + nm_client_add_and_activate_connection2; + nm_client_add_and_activate_connection2_finish; + nm_device_get_connectivity; + nm_device_wifi_p2p_get_hw_address; + nm_device_wifi_p2p_get_peers; + nm_device_wifi_p2p_get_type; + nm_device_wifi_p2p_start_find; + nm_device_wifi_p2p_start_find_finish; + nm_device_wifi_p2p_stop_find; + nm_device_wifi_p2p_stop_find_finish; + nm_setting_wifi_p2p_get_peer; + nm_setting_wifi_p2p_get_type; + nm_setting_wifi_p2p_get_wfd_ies; + nm_setting_wifi_p2p_get_wps_method; + nm_setting_wifi_p2p_new; + nm_setting_wireguard_append_peer; + nm_setting_wireguard_clear_peers; + nm_setting_wireguard_get_fwmark; + nm_setting_wireguard_get_listen_port; + nm_setting_wireguard_get_mtu; + nm_setting_wireguard_get_peer; + nm_setting_wireguard_get_peer_by_public_key; + nm_setting_wireguard_get_peer_routes; + nm_setting_wireguard_get_peers_len; + nm_setting_wireguard_get_private_key; + nm_setting_wireguard_get_private_key_flags; + nm_setting_wireguard_get_type; + nm_setting_wireguard_new; + nm_setting_wireguard_remove_peer; + nm_setting_wireguard_set_peer; + nm_team_link_watcher_get_vlanid; + nm_team_link_watcher_new_arp_ping2; + nm_utils_base64secret_decode; + nm_wifi_p2p_peer_connection_valid; + nm_wifi_p2p_peer_filter_connections; + nm_wifi_p2p_peer_get_flags; + nm_wifi_p2p_peer_get_hw_address; + nm_wifi_p2p_peer_get_last_seen; + nm_wifi_p2p_peer_get_manufacturer; + nm_wifi_p2p_peer_get_model; + nm_wifi_p2p_peer_get_model_number; + nm_wifi_p2p_peer_get_name; + nm_wifi_p2p_peer_get_serial; + nm_wifi_p2p_peer_get_strength; + nm_wifi_p2p_peer_get_type; + nm_wifi_p2p_peer_get_wfd_ies; + nm_wireguard_peer_append_allowed_ip; + nm_wireguard_peer_clear_allowed_ips; + nm_wireguard_peer_cmp; + nm_wireguard_peer_get_allowed_ip; + nm_wireguard_peer_get_allowed_ips_len; + nm_wireguard_peer_get_endpoint; + nm_wireguard_peer_get_persistent_keepalive; + nm_wireguard_peer_get_preshared_key; + nm_wireguard_peer_get_preshared_key_flags; + nm_wireguard_peer_get_public_key; + nm_wireguard_peer_get_type; + nm_wireguard_peer_is_sealed; + nm_wireguard_peer_is_valid; + nm_wireguard_peer_new; + nm_wireguard_peer_new_clone; + nm_wireguard_peer_ref; + nm_wireguard_peer_remove_allowed_ip; + nm_wireguard_peer_seal; + nm_wireguard_peer_set_endpoint; + nm_wireguard_peer_set_persistent_keepalive; + nm_wireguard_peer_set_preshared_key; + nm_wireguard_peer_set_preshared_key_flags; + nm_wireguard_peer_set_public_key; + nm_wireguard_peer_unref; +} libnm_1_14_0; + +libnm_1_18_0 { +global: + nm_bridge_vlan_cmp; + nm_bridge_vlan_from_str; + nm_bridge_vlan_get_type; + nm_bridge_vlan_get_vid_range; + nm_bridge_vlan_is_pvid; + nm_bridge_vlan_is_sealed; + nm_bridge_vlan_is_untagged; + nm_bridge_vlan_new; + nm_bridge_vlan_new_clone; + nm_bridge_vlan_ref; + nm_bridge_vlan_seal; + nm_bridge_vlan_set_pvid; + nm_bridge_vlan_set_untagged; + nm_bridge_vlan_to_str; + nm_bridge_vlan_unref; + nm_ip_routing_rule_as_string_flags_get_type; + nm_ip_routing_rule_cmp; + nm_ip_routing_rule_from_string; + nm_ip_routing_rule_get_action; + nm_ip_routing_rule_get_addr_family; + nm_ip_routing_rule_get_destination_port_end; + nm_ip_routing_rule_get_destination_port_start; + nm_ip_routing_rule_get_from; + nm_ip_routing_rule_get_from_len; + nm_ip_routing_rule_get_fwmark; + nm_ip_routing_rule_get_fwmask; + nm_ip_routing_rule_get_iifname; + nm_ip_routing_rule_get_invert; + nm_ip_routing_rule_get_ipproto; + nm_ip_routing_rule_get_oifname; + nm_ip_routing_rule_get_priority; + nm_ip_routing_rule_get_source_port_end; + nm_ip_routing_rule_get_source_port_start; + nm_ip_routing_rule_get_table; + nm_ip_routing_rule_get_to; + nm_ip_routing_rule_get_to_len; + nm_ip_routing_rule_get_tos; + nm_ip_routing_rule_get_type; + nm_ip_routing_rule_is_sealed; + nm_ip_routing_rule_new; + nm_ip_routing_rule_new_clone; + nm_ip_routing_rule_ref; + nm_ip_routing_rule_seal; + nm_ip_routing_rule_set_action; + nm_ip_routing_rule_set_destination_port; + nm_ip_routing_rule_set_from; + nm_ip_routing_rule_set_fwmark; + nm_ip_routing_rule_set_iifname; + nm_ip_routing_rule_set_invert; + nm_ip_routing_rule_set_ipproto; + nm_ip_routing_rule_set_oifname; + nm_ip_routing_rule_set_priority; + nm_ip_routing_rule_set_source_port; + nm_ip_routing_rule_set_table; + nm_ip_routing_rule_set_to; + nm_ip_routing_rule_set_tos; + nm_ip_routing_rule_to_string; + nm_ip_routing_rule_unref; + nm_ip_routing_rule_validate; + nm_lldp_neighbor_get_attr_value; + nm_setting_bridge_add_vlan; + nm_setting_bridge_clear_vlans; + nm_setting_bridge_get_num_vlans; + nm_setting_bridge_get_vlan; + nm_setting_bridge_get_vlan_default_pvid; + nm_setting_bridge_get_vlan_filtering; + nm_setting_bridge_port_add_vlan; + nm_setting_bridge_port_clear_vlans; + nm_setting_bridge_port_get_num_vlans; + nm_setting_bridge_port_get_vlan; + nm_setting_bridge_port_remove_vlan; + nm_setting_bridge_port_remove_vlan_by_vid; + nm_setting_bridge_remove_vlan; + nm_setting_bridge_remove_vlan_by_vid; + nm_setting_ip_config_add_routing_rule; + nm_setting_ip_config_clear_routing_rules; + nm_setting_ip_config_get_num_routing_rules; + nm_setting_ip_config_get_routing_rule; + nm_setting_ip_config_remove_routing_rule; + nm_tc_qdisc_get_attribute; + nm_tc_qdisc_get_attribute_names; + nm_tc_qdisc_set_attribute; +} libnm_1_16_0; + +libnm_1_20_0 { +global: + nm_client_add_connection2; + nm_client_add_connection2_finish; + nm_client_connectivity_check_get_uri; + nm_device_modem_get_apn; + nm_device_modem_get_device_id; + nm_device_modem_get_operator_code; + nm_ip_routing_rule_get_suppress_prefixlength; + nm_ip_routing_rule_set_suppress_prefixlength; + nm_setting_connection_get_wait_device_timeout; + nm_setting_ethtool_get_optnames; + nm_setting_ovs_dpdk_get_devargs; + nm_setting_ovs_dpdk_get_type; + nm_setting_ovs_dpdk_new; + nm_setting_wireguard_get_ip4_auto_default_route; + nm_setting_wireguard_get_ip6_auto_default_route; + nm_settings_add_connection2_flags_get_type; +} libnm_1_18_0; + +libnm_1_20_6 { +global: + nm_setting_802_1x_get_optional; +} libnm_1_20_0; + +libnm_1_22_0 { +global: + nm_client_get_context_busy_watcher; + nm_client_get_dbus_connection; + nm_client_get_dbus_name_owner; + nm_client_get_main_context; + nm_client_get_metered; + nm_client_reload; + nm_client_reload_finish; + nm_device_get_interface_flags; + nm_device_interface_flags_get_type; + nm_dhcp_hostname_flags_get_type; + nm_ip_address_cmp_flags_get_type; + nm_ip_address_cmp_full; + nm_manager_reload_flags_get_type; + nm_setting_gsm_get_auto_config; + nm_setting_ip_config_get_dhcp_hostname_flags; +} libnm_1_20_0; + +libnm_1_22_2 { +global: + nm_client_get_capabilities; +} libnm_1_22_0; + +libnm_1_22_8 { +global: + nm_setting_ip6_config_get_ra_timeout; +} libnm_1_22_2; + +libnm_1_24_0 { +global: + nm_client_dbus_call; + nm_client_dbus_call_finish; + nm_client_dbus_set_property; + nm_client_dbus_set_property_finish; + nm_client_get_instance_flags; + nm_client_get_object_by_path; + nm_client_get_permissions_state; + nm_client_instance_flags_get_type; + nm_device_vrf_get_table; + nm_device_vrf_get_type; + nm_object_get_client; + nm_secret_agent_old_destroy; + nm_secret_agent_old_enable; + nm_secret_agent_old_get_context_busy_watcher; + nm_secret_agent_old_get_dbus_connection; + nm_secret_agent_old_get_dbus_name_owner; + nm_secret_agent_old_get_main_context; + nm_setting_802_1x_get_domain_match; + nm_setting_802_1x_get_phase2_domain_match; + nm_setting_bond_get_option_normalized; + nm_setting_bridge_get_group_address; + nm_setting_bridge_get_multicast_querier; + nm_setting_bridge_get_multicast_query_use_ifaddr; + nm_setting_bridge_get_multicast_router; + nm_setting_bridge_get_vlan_protocol; + nm_setting_bridge_get_vlan_stats_enabled; + nm_setting_vrf_get_table; + nm_setting_vrf_get_type; + nm_setting_vrf_new; +} libnm_1_22_8; + +libnm_1_26_0 { +global: + nm_device_get_path; + nm_ethtool_optname_is_coalesce; + nm_ethtool_optname_is_ring; + nm_setting_bridge_get_multicast_hash_max; + nm_setting_bridge_get_multicast_last_member_count; + nm_setting_bridge_get_multicast_last_member_interval; + nm_setting_bridge_get_multicast_membership_interval; + nm_setting_bridge_get_multicast_querier_interval; + nm_setting_bridge_get_multicast_query_interval; + nm_setting_bridge_get_multicast_query_response_interval; + nm_setting_bridge_get_multicast_startup_query_count; + nm_setting_bridge_get_multicast_startup_query_interval; + nm_setting_connection_get_mud_url; + nm_setting_match_add_driver; + nm_setting_match_add_kernel_command_line; + nm_setting_match_add_path; + nm_setting_match_clear_drivers; + nm_setting_match_clear_kernel_command_lines; + nm_setting_match_clear_paths; + nm_setting_match_get_driver; + nm_setting_match_get_drivers; + nm_setting_match_get_kernel_command_line; + nm_setting_match_get_kernel_command_lines; + nm_setting_match_get_num_drivers; + nm_setting_match_get_num_kernel_command_lines; + nm_setting_match_get_num_paths; + nm_setting_match_get_path; + nm_setting_match_get_paths; + nm_setting_match_remove_driver; + nm_setting_match_remove_driver_by_value; + nm_setting_match_remove_kernel_command_line; + nm_setting_match_remove_kernel_command_line_by_value; + nm_setting_match_remove_path; + nm_setting_match_remove_path_by_value; + nm_setting_option_clear_by_name; + nm_setting_option_get; + nm_setting_option_get_all_names; + nm_setting_option_get_boolean; + nm_setting_option_get_uint32; + nm_setting_option_set; + nm_setting_option_set_boolean; + nm_setting_option_set_uint32; +} libnm_1_24_0; + +libnm_1_26_4 { +global: + nm_setting_ip4_config_get_dhcp_vendor_class_identifier; +} libnm_1_26_0; + +libnm_1_28_0 { +global: + nm_setting_ip_config_add_dhcp_reject_server; + nm_setting_ip_config_clear_dhcp_reject_servers; + nm_setting_ip_config_get_dhcp_reject_servers; + nm_setting_ip_config_remove_dhcp_reject_server; + nm_setting_wireless_get_ap_isolation; +} libnm_1_26_4; + +libnm_1_30_0 { +global: + nm_device_veth_get_type; + nm_keyfile_handler_data_fail_with_error; + nm_keyfile_handler_data_get_context; + nm_keyfile_handler_data_warn_get; + nm_keyfile_handler_flags_get_type; + nm_keyfile_handler_type_get_type; + nm_keyfile_read; + nm_keyfile_warn_severity_get_type; + nm_keyfile_write; + nm_setting_hostname_get_from_dhcp; + nm_setting_hostname_get_from_dns_lookup; + nm_setting_hostname_get_only_from_default; + nm_setting_hostname_get_priority; + nm_setting_hostname_get_type; + nm_setting_ovs_external_ids_check_key; + nm_setting_ovs_external_ids_check_val; + nm_setting_ovs_external_ids_get_data; + nm_setting_ovs_external_ids_get_data_keys; + nm_setting_ovs_external_ids_get_type; + nm_setting_ovs_external_ids_new; + nm_setting_ovs_external_ids_set_data; + nm_setting_veth_get_peer; + nm_setting_veth_get_type; + nm_setting_veth_new; + nm_utils_print; +} libnm_1_28_0; + +libnm_1_32_0 { +global: + nm_setting_match_new; +} libnm_1_30_0; diff --git a/src/libnm-client-impl/meson.build b/src/libnm-client-impl/meson.build new file mode 100644 index 0000000..4682e2b --- /dev/null +++ b/src/libnm-client-impl/meson.build @@ -0,0 +1,231 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_client_impl_sources = files( + 'nm-access-point.c', + 'nm-active-connection.c', + 'nm-checkpoint.c', + 'nm-client.c', + 'nm-dbus-helpers.c', + 'nm-device-6lowpan.c', + 'nm-device-adsl.c', + 'nm-device-bond.c', + 'nm-device-bridge.c', + 'nm-device-bt.c', + 'nm-device-dummy.c', + 'nm-device-ethernet.c', + 'nm-device-generic.c', + 'nm-device-infiniband.c', + 'nm-device-ip-tunnel.c', + 'nm-device-macsec.c', + 'nm-device-macvlan.c', + 'nm-device-modem.c', + 'nm-device-olpc-mesh.c', + 'nm-device-ovs-bridge.c', + 'nm-device-ovs-interface.c', + 'nm-device-ovs-port.c', + 'nm-device-ppp.c', + 'nm-device-team.c', + 'nm-device-tun.c', + 'nm-device-veth.c', + 'nm-device-vlan.c', + 'nm-device-vrf.c', + 'nm-device-vxlan.c', + 'nm-device-wifi-p2p.c', + 'nm-device-wifi.c', + 'nm-device-wimax.c', + 'nm-device-wireguard.c', + 'nm-device-wpan.c', + 'nm-device.c', + 'nm-dhcp-config.c', + 'nm-dhcp4-config.c', + 'nm-dhcp6-config.c', + 'nm-dns-manager.c', + 'nm-ip-config.c', + 'nm-ip4-config.c', + 'nm-ip6-config.c', + 'nm-libnm-utils.c', + 'nm-object.c', + 'nm-remote-connection.c', + 'nm-secret-agent-old.c', + 'nm-vpn-connection.c', + 'nm-vpn-editor.c', + 'nm-vpn-plugin-old.c', + 'nm-vpn-service-plugin.c', + 'nm-wifi-p2p-peer.c', + 'nm-wimax-nsp.c', +) + +libnm_client_impl = static_library( + 'nm-client-impl', + sources: libnm_client_impl_sources + libnm_client_public_enum_sources, + dependencies: [ + libnmdbus_dep, + libnm_core_public_dep, + libnm_client_public_dep, + libudev_dep, + glib_dep, + ], +) + +linker_script = join_paths(meson.current_source_dir(), 'libnm.ver') + +libnm = shared_library( + 'nm', + version: libnm_version, + dependencies: [ + libnm_core_public_dep, + libnm_client_public_dep, + libudev_dep, + glib_dep, + ], + link_whole: [ + libnm_client_impl, + libnm_core_aux_intern, + libnm_core_impl, + libnm_crypto, + libnm_base, + libnm_udev_aux, + libnm_systemd_shared, + libnm_log_null, + libnm_glib_aux, + libnm_std_aux, + libnmdbus, + libc_siphash, + ], + link_args: '-Wl,--version-script,@0@'.format(linker_script), + link_depends: linker_script, + install: true, +) + +libnm_dep = declare_dependency( + dependencies: [ + libnm_core_public_dep, + libnm_client_public_dep, + glib_dep, + ], + link_with: libnm, +) + +pkg.generate( + libraries: libnm, + version: nm_version, + name: libnm_name, + description: 'Convenience library for clients of NetworkManager', + filebase: libnm_name, + subdirs: libnm_name, + requires: 'gio-2.0', + variables: [ + 'exec_prefix=${prefix}', + 'vpnservicedir=' + join_paths('${prefix}', 'lib', nm_name, 'VPN'), + ], +) + +if enable_tests + test( + 'check-local-exports-' + libnm_name, + check_exports, + args: [libnm.full_path(), linker_script], + ) +endif + +if enable_introspection + + libnm_gir = gnome.generate_gir( + libnm, + sources: libnm_core_settings_sources + libnm_core_impl_sources + libnm_core_public_enum_sources + libnm_core_headers + libnm_client_impl_sources + libnm_client_headers + libnm_client_public_enum_sources + [nm_version_macro_header], + includes: 'Gio-2.0', + include_directories: [ + libnm_core_public_inc, + libnm_client_public_inc, + src_inc, + top_inc, + ], + nsversion: nm_gir_version, + namespace: 'NM', + identifier_prefix: nm_id_prefix, + symbol_prefix: nm_id_prefix.to_lower(), + header: 'NetworkManager.h', + export_packages: libnm_name, + extra_args: [ + '-DNETWORKMANAGER_COMPILATION', + ], + install: true, + ) + + infos = [ 'dbus', 'nmcli', 'keyfile' ] + if enable_ifcfg_rh + infos += [ 'ifcfg-rh' ] + endif + foreach info: infos + t = custom_target( + 'nm-propery-infos-' + info + '.xml', + input: libnm_core_settings_sources, + output: 'nm-propery-infos-' + info + '.xml', + command: [ + perl, + join_paths(meson.source_root(), 'tools', 'generate-docs-nm-property-infos.pl'), + info, + '@OUTPUT@', + '@INPUT@' + ], + ) + + # meson 0.47 doesn't support non-static keys for dicts + # nor extending dicts incrementally. Workaround. + if info == 'dbus' + nm_property_infos_xml_dbus = t + elif info == 'keyfile' + nm_property_infos_xml_keyfile = t + elif info == 'ifcfg-rh' + nm_property_infos_xml_ifcfg_rh = t + elif info == 'nmcli' + nm_property_infos_xml_nmcli = t + else + assert(false) + endif + endforeach + if enable_ifcfg_rh + nm_property_infos_xml = { + 'dbus': nm_property_infos_xml_dbus, + 'keyfile': nm_property_infos_xml_keyfile, + 'nmcli': nm_property_infos_xml_nmcli, + 'ifcfg-rh': nm_property_infos_xml_ifcfg_rh, + } + else + nm_property_infos_xml = { + 'dbus': nm_property_infos_xml_dbus, + 'keyfile': nm_property_infos_xml_keyfile, + 'nmcli': nm_property_infos_xml_nmcli, + } + endif + + gi_typelib_path = run_command('printenv', 'GI_TYPELIB_PATH').stdout() + if gi_typelib_path != '' + gi_typelib_path = ':' + gi_typelib_path + endif + gi_typelib_path = meson.current_build_dir() + gi_typelib_path + + ld_library_path = run_command('printenv', 'LD_LIBRARY_PATH').stdout() + if ld_library_path != '' + ld_library_path = ':' + ld_library_path + endif + ld_library_path = meson.current_build_dir() + ld_library_path + + nm_settings_docs_xml_gir = custom_target( + 'nm-settings-docs-gir.xml', + input: libnm_gir[0], + output: 'nm-settings-docs-gir.xml', + command: [ + 'env', + 'GI_TYPELIB_PATH=' + gi_typelib_path, + 'LD_LIBRARY_PATH=' + ld_library_path, + python.path(), + join_paths(meson.source_root(), 'tools', 'generate-docs-nm-settings-docs-gir.py'), + '--lib-path', meson.current_build_dir(), + '--gir', '@INPUT@', + '--output', '@OUTPUT@' + ], + depends: libnm_gir, + ) + +endif diff --git a/src/libnm-client-impl/nm-access-point.c b/src/libnm-client-impl/nm-access-point.c new file mode 100644 index 0000000..3d12aa4 --- /dev/null +++ b/src/libnm-client-impl/nm-access-point.c @@ -0,0 +1,654 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-access-point.h" + +#include + +#include "nm-connection.h" +#include "nm-setting-connection.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wireless-security.h" +#include "nm-utils.h" + +#include "nm-dbus-interface.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMAccessPoint, + PROP_FLAGS, + PROP_WPA_FLAGS, + PROP_RSN_FLAGS, + PROP_SSID, + PROP_FREQUENCY, + PROP_HW_ADDRESS, + PROP_MODE, + PROP_MAX_BITRATE, + PROP_STRENGTH, + PROP_BSSID, + PROP_LAST_SEEN, ); + +typedef struct { + GBytes *ssid; + char * bssid; + guint32 flags; + guint32 wpa_flags; + guint32 rsn_flags; + guint32 frequency; + guint32 mode; + guint32 max_bitrate; + gint32 last_seen; + guint8 strength; +} NMAccessPointPrivate; + +struct _NMAccessPoint { + NMObject parent; + NMAccessPointPrivate _priv; +}; + +struct _NMAccessPointClass { + NMObjectClass parent; +}; + +G_DEFINE_TYPE(NMAccessPoint, nm_access_point, NM_TYPE_OBJECT) + +#define NM_ACCESS_POINT_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMAccessPoint, NM_IS_ACCESS_POINT, NMObject) + +/*****************************************************************************/ + +/** + * nm_access_point_get_flags: + * @ap: a #NMAccessPoint + * + * Gets the flags of the access point. + * + * Returns: the flags + **/ +NM80211ApFlags +nm_access_point_get_flags(NMAccessPoint *ap) +{ + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), NM_802_11_AP_FLAGS_NONE); + + return NM_ACCESS_POINT_GET_PRIVATE(ap)->flags; +} + +/** + * nm_access_point_get_wpa_flags: + * @ap: a #NMAccessPoint + * + * Gets the WPA (version 1) flags of the access point. + * + * Returns: the WPA flags + **/ +NM80211ApSecurityFlags +nm_access_point_get_wpa_flags(NMAccessPoint *ap) +{ + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), NM_802_11_AP_SEC_NONE); + + return NM_ACCESS_POINT_GET_PRIVATE(ap)->wpa_flags; +} + +/** + * nm_access_point_get_rsn_flags: + * @ap: a #NMAccessPoint + * + * Gets the RSN (Robust Secure Network, ie WPA version 2) flags of the access + * point. + * + * Returns: the RSN flags + **/ +NM80211ApSecurityFlags +nm_access_point_get_rsn_flags(NMAccessPoint *ap) +{ + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), NM_802_11_AP_SEC_NONE); + + return NM_ACCESS_POINT_GET_PRIVATE(ap)->rsn_flags; +} + +/** + * nm_access_point_get_ssid: + * @ap: a #NMAccessPoint + * + * Gets the SSID of the access point. + * + * Returns: (transfer none): the #GBytes containing the SSID, or %NULL if the + * SSID is unknown. + **/ +GBytes * +nm_access_point_get_ssid(NMAccessPoint *ap) +{ + NMAccessPointPrivate *priv; + + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), NULL); + + priv = NM_ACCESS_POINT_GET_PRIVATE(ap); + nm_assert(!priv->ssid || g_bytes_get_size(priv->ssid) > 0); + return priv->ssid; +} + +/** + * nm_access_point_get_frequency: + * @ap: a #NMAccessPoint + * + * Gets the frequency of the access point in MHz. + * + * Returns: the frequency in MHz + **/ +guint32 +nm_access_point_get_frequency(NMAccessPoint *ap) +{ + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), 0); + + return NM_ACCESS_POINT_GET_PRIVATE(ap)->frequency; +} + +/** + * nm_access_point_get_bssid: + * @ap: a #NMAccessPoint + * + * Gets the Basic Service Set ID (BSSID) of the Wi-Fi access point. + * + * Returns: the BSSID of the access point. This is an internal string and must + * not be modified or freed. + **/ +const char * +nm_access_point_get_bssid(NMAccessPoint *ap) +{ + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), NULL); + + return _nml_coerce_property_str_not_empty(NM_ACCESS_POINT_GET_PRIVATE(ap)->bssid); +} + +/** + * nm_access_point_get_mode: + * @ap: a #NMAccessPoint + * + * Gets the mode of the access point. + * + * Returns: the mode + **/ +NM80211Mode +nm_access_point_get_mode(NMAccessPoint *ap) +{ + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), 0); + + return NM_ACCESS_POINT_GET_PRIVATE(ap)->mode; +} + +/** + * nm_access_point_get_max_bitrate: + * @ap: a #NMAccessPoint + * + * Gets the maximum bit rate of the access point in kbit/s. + * + * Returns: the maximum bit rate (kbit/s) + **/ +guint32 +nm_access_point_get_max_bitrate(NMAccessPoint *ap) +{ + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), 0); + + return NM_ACCESS_POINT_GET_PRIVATE(ap)->max_bitrate; +} + +/** + * nm_access_point_get_strength: + * @ap: a #NMAccessPoint + * + * Gets the current signal strength of the access point as a percentage. + * + * Returns: the signal strength (0 to 100) + **/ +guint8 +nm_access_point_get_strength(NMAccessPoint *ap) +{ + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), 0); + + return NM_ACCESS_POINT_GET_PRIVATE(ap)->strength; +} + +/** + * nm_access_point_get_last_seen: + * @ap: a #NMAccessPoint + * + * Returns the timestamp (in CLOCK_BOOTTIME seconds) for the last time the + * access point was found in scan results. A value of -1 means the access + * point has not been found in a scan. + * + * Returns: the last seen time in seconds + * + * Since: 1.2 + **/ +int +nm_access_point_get_last_seen(NMAccessPoint *ap) +{ + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), -1); + + return NM_ACCESS_POINT_GET_PRIVATE(ap)->last_seen; +} +NM_BACKPORT_SYMBOL(libnm_1_0_6, int, nm_access_point_get_last_seen, (NMAccessPoint * ap), (ap)); + +/** + * nm_access_point_connection_valid: + * @ap: an #NMAccessPoint to validate @connection against + * @connection: an #NMConnection to validate against @ap + * + * Validates a given connection against a given Wi-Fi access point to ensure that + * the connection may be activated with that AP. The connection must match the + * @ap's SSID, (if given) BSSID, and other attributes like security settings, + * channel, band, etc. + * + * Returns: %TRUE if the connection may be activated with this Wi-Fi AP, + * %FALSE if it cannot be. + **/ +gboolean +nm_access_point_connection_valid(NMAccessPoint *ap, NMConnection *connection) +{ + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity *s_wsec; + const char * ctype, *ap_bssid; + GBytes * setting_ssid; + GBytes * ap_ssid; + const char * setting_bssid; + const char * setting_mode; + NM80211Mode ap_mode; + const char * setting_band; + guint32 ap_freq, setting_chan, ap_chan; + + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + + s_con = nm_connection_get_setting_connection(connection); + if (!s_con) + return FALSE; + + ctype = nm_setting_connection_get_connection_type(s_con); + if (!ctype || !nm_streq(ctype, NM_SETTING_WIRELESS_SETTING_NAME)) + return FALSE; + + s_wifi = nm_connection_get_setting_wireless(connection); + if (!s_wifi) + return FALSE; + + /* SSID checks */ + ap_ssid = nm_access_point_get_ssid(ap); + if (!ap_ssid) + return FALSE; + setting_ssid = nm_setting_wireless_get_ssid(s_wifi); + if (!setting_ssid || !g_bytes_equal(ap_ssid, setting_ssid)) + return FALSE; + + /* BSSID checks */ + ap_bssid = nm_access_point_get_bssid(ap); + if (!ap_bssid) + return FALSE; + setting_bssid = nm_setting_wireless_get_bssid(s_wifi); + if (setting_bssid) { + guint8 c[ETH_ALEN]; + + if (!nm_utils_hwaddr_aton(ap_bssid, c, ETH_ALEN) + || !nm_utils_hwaddr_matches(c, ETH_ALEN, setting_bssid, -1)) + return FALSE; + } + + /* Mode */ + ap_mode = nm_access_point_get_mode(ap); + if (ap_mode == NM_802_11_MODE_UNKNOWN) + return FALSE; + setting_mode = nm_setting_wireless_get_mode(s_wifi); + if (setting_mode && ap_mode) { + if (!strcmp(setting_mode, "infrastructure") && (ap_mode != NM_802_11_MODE_INFRA)) + return FALSE; + if (!strcmp(setting_mode, "adhoc") && (ap_mode != NM_802_11_MODE_ADHOC)) + return FALSE; + /* Hotspot never matches against APs as it's a device-specific mode. */ + if (!strcmp(setting_mode, "ap")) + return FALSE; + } + + /* Band and Channel/Frequency */ + ap_freq = nm_access_point_get_frequency(ap); + if (ap_freq) { + setting_band = nm_setting_wireless_get_band(s_wifi); + if (g_strcmp0(setting_band, "a") == 0) { + if (ap_freq < 4915 || ap_freq > 5825) + return FALSE; + } else if (g_strcmp0(setting_band, "bg") == 0) { + if (ap_freq < 2412 || ap_freq > 2484) + return FALSE; + } + + setting_chan = nm_setting_wireless_get_channel(s_wifi); + if (setting_chan) { + ap_chan = nm_utils_wifi_freq_to_channel(ap_freq); + if (setting_chan != ap_chan) + return FALSE; + } + } + + s_wsec = nm_connection_get_setting_wireless_security(connection); + if (!nm_setting_wireless_ap_security_compatible(s_wifi, + s_wsec, + nm_access_point_get_flags(ap), + nm_access_point_get_wpa_flags(ap), + nm_access_point_get_rsn_flags(ap), + ap_mode)) + return FALSE; + + return TRUE; +} + +/** + * nm_access_point_filter_connections: + * @ap: an #NMAccessPoint to filter connections for + * @connections: (element-type NMConnection): an array of #NMConnections to + * filter + * + * Filters a given array of connections for a given #NMAccessPoint object and + * returns connections which may be activated with the access point. Any + * returned connections will match the @ap's SSID and (if given) BSSID and + * other attributes like security settings, channel, etc. + * + * To obtain the list of connections that are compatible with this access point, + * use nm_client_get_connections() and then filter the returned list for a given + * #NMDevice using nm_device_filter_connections() and finally filter that list + * with this function. + * + * Returns: (transfer full) (element-type NMConnection): an array of + * #NMConnections that could be activated with the given @ap. The array should + * be freed with g_ptr_array_unref() when it is no longer required. + * + * WARNING: the transfer annotation for this function may not work correctly + * with bindings. See https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/305. + * You can filter the list yourself with nm_access_point_connection_valid(). + **/ +GPtrArray * +nm_access_point_filter_connections(NMAccessPoint *ap, const GPtrArray *connections) +{ + GPtrArray *filtered; + guint i; + + g_return_val_if_fail(NM_IS_ACCESS_POINT(ap), NULL); + + if (!connections) + return NULL; + + filtered = g_ptr_array_new_with_free_func(g_object_unref); + for (i = 0; i < connections->len; i++) { + NMConnection *candidate = connections->pdata[i]; + + if (nm_access_point_connection_valid(ap, candidate)) + g_ptr_array_add(filtered, g_object_ref(candidate)); + } + + return filtered; +} + +/*****************************************************************************/ + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_hw_address(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMAccessPoint * self = NM_ACCESS_POINT(dbobj->nmobj); + NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE(self); + + g_free(priv->bssid); + priv->bssid = value ? g_variant_dup_string(value, NULL) : 0u; + _notify(self, PROP_HW_ADDRESS); + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + +/*****************************************************************************/ + +static void +nm_access_point_init(NMAccessPoint *ap) +{ + NM_ACCESS_POINT_GET_PRIVATE(ap)->last_seen = -1; +} + +static void +finalize(GObject *object) +{ + NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE(object); + + if (priv->ssid) + g_bytes_unref(priv->ssid); + g_free(priv->bssid); + + G_OBJECT_CLASS(nm_access_point_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMAccessPoint *ap = NM_ACCESS_POINT(object); + + switch (prop_id) { + case PROP_FLAGS: + g_value_set_flags(value, nm_access_point_get_flags(ap)); + break; + case PROP_WPA_FLAGS: + g_value_set_flags(value, nm_access_point_get_wpa_flags(ap)); + break; + case PROP_RSN_FLAGS: + g_value_set_flags(value, nm_access_point_get_rsn_flags(ap)); + break; + case PROP_SSID: + g_value_set_boxed(value, nm_access_point_get_ssid(ap)); + break; + case PROP_FREQUENCY: + g_value_set_uint(value, nm_access_point_get_frequency(ap)); + break; + case PROP_HW_ADDRESS: + g_value_set_string(value, nm_access_point_get_bssid(ap)); + break; + case PROP_BSSID: + g_value_set_string(value, nm_access_point_get_bssid(ap)); + break; + case PROP_MODE: + g_value_set_enum(value, nm_access_point_get_mode(ap)); + break; + case PROP_MAX_BITRATE: + g_value_set_uint(value, nm_access_point_get_max_bitrate(ap)); + break; + case PROP_STRENGTH: + g_value_set_uchar(value, nm_access_point_get_strength(ap)); + break; + case PROP_LAST_SEEN: + g_value_set_int(value, nm_access_point_get_last_seen(ap)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_accesspoint = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_ACCESS_POINT, + nm_access_point_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_U("Flags", PROP_FLAGS, NMAccessPoint, _priv.flags), + NML_DBUS_META_PROPERTY_INIT_U("Frequency", PROP_FREQUENCY, NMAccessPoint, _priv.frequency), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + PROP_BSSID, + "s", + _notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_I("LastSeen", PROP_LAST_SEEN, NMAccessPoint, _priv.last_seen), + NML_DBUS_META_PROPERTY_INIT_U("MaxBitrate", + PROP_MAX_BITRATE, + NMAccessPoint, + _priv.max_bitrate), + NML_DBUS_META_PROPERTY_INIT_U("Mode", PROP_MODE, NMAccessPoint, _priv.mode), + NML_DBUS_META_PROPERTY_INIT_U("RsnFlags", PROP_RSN_FLAGS, NMAccessPoint, _priv.rsn_flags), + NML_DBUS_META_PROPERTY_INIT_AY("Ssid", PROP_SSID, NMAccessPoint, _priv.ssid), + NML_DBUS_META_PROPERTY_INIT_Y("Strength", PROP_STRENGTH, NMAccessPoint, _priv.strength), + NML_DBUS_META_PROPERTY_INIT_U("WpaFlags", + PROP_WPA_FLAGS, + NMAccessPoint, + _priv.wpa_flags), ), ); + +static void +nm_access_point_class_init(NMAccessPointClass *ap_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(ap_class); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + /** + * NMAccessPoint:flags: + * + * The flags of the access point. + **/ + obj_properties[PROP_FLAGS] = g_param_spec_flags(NM_ACCESS_POINT_FLAGS, + "", + "", + NM_TYPE_802_11_AP_FLAGS, + NM_802_11_AP_FLAGS_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMAccessPoint:wpa-flags: + * + * The WPA flags of the access point. + **/ + obj_properties[PROP_WPA_FLAGS] = g_param_spec_flags(NM_ACCESS_POINT_WPA_FLAGS, + "", + "", + NM_TYPE_802_11_AP_SECURITY_FLAGS, + NM_802_11_AP_SEC_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMAccessPoint:rsn-flags: + * + * The RSN flags of the access point. + **/ + obj_properties[PROP_RSN_FLAGS] = g_param_spec_flags(NM_ACCESS_POINT_RSN_FLAGS, + "", + "", + NM_TYPE_802_11_AP_SECURITY_FLAGS, + NM_802_11_AP_SEC_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMAccessPoint:ssid: + * + * The SSID of the access point, or %NULL if it is not known. + **/ + obj_properties[PROP_SSID] = g_param_spec_boxed(NM_ACCESS_POINT_SSID, + "", + "", + G_TYPE_BYTES, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMAccessPoint:frequency: + * + * The frequency of the access point. + **/ + obj_properties[PROP_FREQUENCY] = g_param_spec_uint(NM_ACCESS_POINT_FREQUENCY, + "", + "", + 0, + 10000, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMAccessPoint:bssid: + * + * The BSSID of the access point. + **/ + obj_properties[PROP_BSSID] = g_param_spec_string(NM_ACCESS_POINT_BSSID, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMAccessPoint:hw-address: + * + * Alias for #NMAccessPoint:bssid. + * + * Deprecated: 1.0: Use #NMAccessPoint:bssid. + **/ + obj_properties[PROP_HW_ADDRESS] = + g_param_spec_string(NM_ACCESS_POINT_HW_ADDRESS, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMAccessPoint:mode: + * + * The mode of the access point; either "infrastructure" (a central + * coordinator of the wireless network allowing clients to connect) or + * "ad-hoc" (a network with no central controller). + **/ + obj_properties[PROP_MODE] = g_param_spec_enum(NM_ACCESS_POINT_MODE, + "", + "", + NM_TYPE_802_11_MODE, + NM_802_11_MODE_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMAccessPoint:max-bitrate: + * + * The maximum bit rate of the access point in kbit/s. + **/ + obj_properties[PROP_MAX_BITRATE] = g_param_spec_uint(NM_ACCESS_POINT_MAX_BITRATE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMAccessPoint:strength: + * + * The current signal strength of the access point. + **/ + obj_properties[PROP_STRENGTH] = g_param_spec_uchar(NM_ACCESS_POINT_STRENGTH, + "", + "", + 0, + G_MAXUINT8, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMAccessPoint:last-seen: + * + * The timestamp (in CLOCK_BOOTTIME seconds) for the last time the + * access point was found in scan results. A value of -1 means the + * access point has not been found in a scan. + * + * Since: 1.2 + **/ + obj_properties[PROP_LAST_SEEN] = g_param_spec_int(NM_ACCESS_POINT_LAST_SEEN, + "", + "", + -1, + G_MAXINT, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_accesspoint); +} diff --git a/src/libnm-client-impl/nm-active-connection.c b/src/libnm-client-impl/nm-active-connection.c new file mode 100644 index 0000000..aa96219 --- /dev/null +++ b/src/libnm-client-impl/nm-active-connection.c @@ -0,0 +1,839 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-active-connection.h" + +#include "nm-dbus-interface.h" +#include "nm-object-private.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-device.h" +#include "nm-connection.h" +#include "nm-vpn-connection.h" +#include "nm-dbus-helpers.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" +#include "nm-remote-connection.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMActiveConnection, + PROP_CONNECTION, + PROP_ID, + PROP_UUID, + PROP_TYPE, + PROP_SPECIFIC_OBJECT_PATH, + PROP_DEVICES, + PROP_STATE, + PROP_STATE_FLAGS, + PROP_DEFAULT, + PROP_IP4_CONFIG, + PROP_DHCP4_CONFIG, + PROP_DEFAULT6, + PROP_IP6_CONFIG, + PROP_DHCP6_CONFIG, + PROP_VPN, + PROP_MASTER, ); + +enum { + STATE_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +enum { + PROPERTY_O_IDX_CONNECTION, + PROPERTY_O_IDX_MASTER, + PROPERTY_O_IDX_IP4_CONFIG, + PROPERTY_O_IDX_IP6_CONFIG, + PROPERTY_O_IDX_DHCP4_CONFIG, + PROPERTY_O_IDX_DHCP6_CONFIG, + _PROPERTY_O_IDX_NUM, +}; + +typedef struct _NMActiveConnectionPrivate { + NMLDBusPropertyO property_o[_PROPERTY_O_IDX_NUM]; + NMLDBusPropertyAO devices; + NMRefString * specific_object_path; + char * id; + char * uuid; + char * type; + + guint32 state; + guint32 state_flags; + + bool is_default; + bool is_default6; + bool is_vpn; + + guint32 reason; +} NMActiveConnectionPrivate; + +G_DEFINE_TYPE(NMActiveConnection, nm_active_connection, NM_TYPE_OBJECT); + +#define NM_ACTIVE_CONNECTION_GET_PRIVATE(self) \ + _NM_GET_PRIVATE_PTR(self, NMActiveConnection, NM_IS_ACTIVE_CONNECTION, NMObject) + +/*****************************************************************************/ + +/** + * nm_active_connection_get_connection: + * @connection: a #NMActiveConnection + * + * Gets the #NMRemoteConnection associated with @connection. + * + * Returns: (transfer none): the #NMRemoteConnection which this + * #NMActiveConnection is an active instance of. + **/ +NMRemoteConnection * +nm_active_connection_get_connection(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return nml_dbus_property_o_get_obj( + &NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->property_o[PROPERTY_O_IDX_CONNECTION]); +} + +/** + * nm_active_connection_get_id: + * @connection: a #NMActiveConnection + * + * Gets the #NMConnection's ID. + * + * Returns: the ID of the #NMConnection that backs the #NMActiveConnection. + * This is the internal string used by the connection, and must not be modified. + **/ +const char * +nm_active_connection_get_id(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return _nml_coerce_property_str_not_empty(NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->id); +} + +/** + * nm_active_connection_get_uuid: + * @connection: a #NMActiveConnection + * + * Gets the #NMConnection's UUID. + * + * Returns: the UUID of the #NMConnection that backs the #NMActiveConnection. + * This is the internal string used by the connection, and must not be modified. + **/ +const char * +nm_active_connection_get_uuid(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return _nml_coerce_property_str_not_empty(NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->uuid); +} + +/** + * nm_active_connection_get_connection_type: + * @connection: a #NMActiveConnection + * + * Gets the #NMConnection's type. + * + * Returns: the type of the #NMConnection that backs the #NMActiveConnection. + * This is the internal string used by the connection, and must not be modified. + **/ +const char * +nm_active_connection_get_connection_type(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return _nml_coerce_property_str_not_empty(NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->type); +} + +/** + * nm_active_connection_get_specific_object_path: + * @connection: a #NMActiveConnection + * + * Gets the path of the "specific object" used at activation. + * + * Currently, there is no single method that will allow you to automatically turn + * this into an appropriate #NMObject; you need to know what kind of object it + * is based on other information. (Eg, if @connection corresponds to a Wi-Fi + * connection, then the specific object will be an #NMAccessPoint, and you can + * resolve it with nm_device_wifi_get_access_point_by_path().) + * + * Returns: the specific object's D-Bus path. This is the internal string used + * by the connection, and must not be modified. + **/ +const char * +nm_active_connection_get_specific_object_path(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return _nml_coerce_property_object_path( + NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->specific_object_path); +} + +/** + * nm_active_connection_get_devices: + * @connection: a #NMActiveConnection + * + * Gets the #NMDevices used for the active connections. + * + * Returns: (element-type NMDevice): the #GPtrArray containing #NMDevices. + * This is the internal copy used by the connection, and must not be modified. + **/ +const GPtrArray * +nm_active_connection_get_devices(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->devices); +} + +/** + * nm_active_connection_get_state: + * @connection: a #NMActiveConnection + * + * Gets the active connection's state. + * + * Returns: the state + **/ +NMActiveConnectionState +nm_active_connection_get_state(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NM_ACTIVE_CONNECTION_STATE_UNKNOWN); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->state; +} + +/** + * nm_active_connection_get_state_flags: + * @connection: a #NMActiveConnection + * + * Gets the active connection's state flags. + * + * Returns: the state flags + * + * Since: 1.10 + **/ +NMActivationStateFlags +nm_active_connection_get_state_flags(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NM_ACTIVATION_STATE_FLAG_NONE); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->state_flags; +} + +/** + * nm_active_connection_get_state_reason: + * @connection: a #NMActiveConnection + * + * Gets the reason for active connection's state. + * + * Returns: the reason + * + * Since: 1.8 + **/ +NMActiveConnectionStateReason +nm_active_connection_get_state_reason(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), + NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->reason; +} + +/** + * nm_active_connection_get_default: + * @connection: a #NMActiveConnection + * + * Whether the active connection is the default IPv4 one (that is, is used for + * the default IPv4 route and DNS information). + * + * Returns: %TRUE if the active connection is the default IPv4 connection + **/ +gboolean +nm_active_connection_get_default(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), FALSE); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->is_default; +} + +/** + * nm_active_connection_get_ip4_config: + * @connection: an #NMActiveConnection + * + * Gets the current IPv4 #NMIPConfig associated with the #NMActiveConnection. + * + * Returns: (transfer none): the IPv4 #NMIPConfig, or %NULL if the connection is + * not in the %NM_ACTIVE_CONNECTION_STATE_ACTIVATED state. + **/ +NMIPConfig * +nm_active_connection_get_ip4_config(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return nml_dbus_property_o_get_obj( + &NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->property_o[PROPERTY_O_IDX_IP4_CONFIG]); +} + +/** + * nm_active_connection_get_dhcp4_config: + * @connection: an #NMActiveConnection + * + * Gets the current IPv4 #NMDhcpConfig (if any) associated with the + * #NMActiveConnection. + * + * Returns: (transfer none): the IPv4 #NMDhcpConfig, or %NULL if the connection + * does not use DHCP, or is not in the %NM_ACTIVE_CONNECTION_STATE_ACTIVATED + * state. + **/ +NMDhcpConfig * +nm_active_connection_get_dhcp4_config(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return nml_dbus_property_o_get_obj( + &NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->property_o[PROPERTY_O_IDX_DHCP4_CONFIG]); +} + +/** + * nm_active_connection_get_default6: + * @connection: a #NMActiveConnection + * + * Whether the active connection is the default IPv6 one (that is, is used for + * the default IPv6 route and DNS information). + * + * Returns: %TRUE if the active connection is the default IPv6 connection + **/ +gboolean +nm_active_connection_get_default6(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), FALSE); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->is_default6; +} + +/** + * nm_active_connection_get_ip6_config: + * @connection: an #NMActiveConnection + * + * Gets the current IPv6 #NMIPConfig associated with the #NMActiveConnection. + * + * Returns: (transfer none): the IPv6 #NMIPConfig, or %NULL if the connection is + * not in the %NM_ACTIVE_CONNECTION_STATE_ACTIVATED state. + **/ +NMIPConfig * +nm_active_connection_get_ip6_config(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return nml_dbus_property_o_get_obj( + &NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->property_o[PROPERTY_O_IDX_IP6_CONFIG]); +} + +/** + * nm_active_connection_get_dhcp6_config: + * @connection: an #NMActiveConnection + * + * Gets the current IPv6 #NMDhcpConfig (if any) associated with the + * #NMActiveConnection. + * + * Returns: (transfer none): the IPv6 #NMDhcpConfig, or %NULL if the connection + * does not use DHCPv6, or is not in the %NM_ACTIVE_CONNECTION_STATE_ACTIVATED + * state. + **/ +NMDhcpConfig * +nm_active_connection_get_dhcp6_config(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return nml_dbus_property_o_get_obj( + &NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->property_o[PROPERTY_O_IDX_DHCP6_CONFIG]); +} + +/** + * nm_active_connection_get_vpn: + * @connection: a #NMActiveConnection + * + * Whether the active connection is a VPN connection. + * + * Returns: %TRUE if the active connection is a VPN connection + **/ +gboolean +nm_active_connection_get_vpn(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), FALSE); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->is_vpn; +} + +/** + * nm_active_connection_get_master: + * @connection: a #NMActiveConnection + * + * Gets the master #NMDevice of the connection. + * + * Returns: (transfer none): the master #NMDevice of the #NMActiveConnection. + **/ +NMDevice * +nm_active_connection_get_master(NMActiveConnection *connection) +{ + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(connection), NULL); + + return nml_dbus_property_o_get_obj( + &NM_ACTIVE_CONNECTION_GET_PRIVATE(connection)->property_o[PROPERTY_O_IDX_MASTER]); +} + +/*****************************************************************************/ + +static void +_notify_event_state_changed(NMClient *client, NMClientNotifyEventWithPtr *notify_event) +{ + gs_unref_object NMActiveConnection *self = notify_event->user_data; + NMActiveConnectionPrivate * priv = NM_ACTIVE_CONNECTION_GET_PRIVATE(self); + + /* we expose here the value cache in @priv. In practice, this is the same + * value as we received from the signal. In the unexpected case where they + * differ, the cached value of the current instance would still be more correct. */ + g_signal_emit(self, signals[STATE_CHANGED], 0, (guint) priv->state, (guint) priv->reason); +} + +void +_nm_active_connection_state_changed_commit(NMActiveConnection *self, guint32 state, guint32 reason) +{ + NMClient * client; + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE(self); + + client = _nm_object_get_client(self); + + if (priv->state != state) { + priv->state = state; + _nm_client_queue_notify_object(client, self, obj_properties[PROP_STATE]); + } + + priv->reason = reason; + + _nm_client_notify_event_queue_with_ptr(client, + NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP + 1, + _notify_event_state_changed, + g_object_ref(self)); +} +/*****************************************************************************/ + +static gboolean +is_ready(NMObject *nmobj) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE(nmobj); + + /* Usually, we don't want to expose our NMObject instances until they are fully initialized. + * For NMRemoteSetting this means to wait until GetSettings() returns. + * + * Note that most object types reference each other (directly or indirectly). E.g. the + * NMActiveConnection refers to the NMRemoteConnection and the NMDevice instance. So, + * we don't want to hide them too long, otherwise basically the entire set of objects + * will be hidden until they are all initialized. So, usually, when a NMObject references + * objects that are not yet initialized, that reference will just be NULL but the object + * will be considered ready already. + * + * For NMActiveConnection referencing a NMRemoteConnection don't do that. Here we wait for the + * NMRemoteConnection to be ready as well. This is somewhat arbitrary special casing, but + * the effect is that when nm_client_add_and_activate*() returns, the NMActiveConnection already + * references a initialized NMRemoteConnection. + */ + if (!nml_dbus_property_o_is_ready_fully(&priv->property_o[PROPERTY_O_IDX_CONNECTION])) + return FALSE; + + return NM_OBJECT_CLASS(nm_active_connection_parent_class)->is_ready(nmobj); +} + +/*****************************************************************************/ + +static void +nm_active_connection_init(NMActiveConnection *self) +{ + NMActiveConnectionPrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionPrivate); + + self->_priv = priv; +} + +static void +finalize(GObject *object) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE(object); + + g_free(priv->id); + g_free(priv->uuid); + g_free(priv->type); + nm_ref_string_unref(priv->specific_object_path); + + G_OBJECT_CLASS(nm_active_connection_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMActiveConnection *self = NM_ACTIVE_CONNECTION(object); + + switch (prop_id) { + case PROP_CONNECTION: + g_value_set_object(value, nm_active_connection_get_connection(self)); + break; + case PROP_ID: + g_value_set_string(value, nm_active_connection_get_id(self)); + break; + case PROP_UUID: + g_value_set_string(value, nm_active_connection_get_uuid(self)); + break; + case PROP_TYPE: + g_value_set_string(value, nm_active_connection_get_connection_type(self)); + break; + case PROP_SPECIFIC_OBJECT_PATH: + g_value_set_string(value, nm_active_connection_get_specific_object_path(self)); + break; + case PROP_DEVICES: + g_value_take_boxed(value, + _nm_utils_copy_object_array(nm_active_connection_get_devices(self))); + break; + case PROP_STATE: + g_value_set_enum(value, nm_active_connection_get_state(self)); + break; + case PROP_STATE_FLAGS: + g_value_set_uint(value, nm_active_connection_get_state_flags(self)); + break; + case PROP_DEFAULT: + g_value_set_boolean(value, nm_active_connection_get_default(self)); + break; + case PROP_IP4_CONFIG: + g_value_set_object(value, nm_active_connection_get_ip4_config(self)); + break; + case PROP_DHCP4_CONFIG: + g_value_set_object(value, nm_active_connection_get_dhcp4_config(self)); + break; + case PROP_DEFAULT6: + g_value_set_boolean(value, nm_active_connection_get_default6(self)); + break; + case PROP_IP6_CONFIG: + g_value_set_object(value, nm_active_connection_get_ip6_config(self)); + break; + case PROP_DHCP6_CONFIG: + g_value_set_object(value, nm_active_connection_get_dhcp6_config(self)); + break; + case PROP_VPN: + g_value_set_boolean(value, nm_active_connection_get_vpn(self)); + break; + case PROP_MASTER: + g_value_set_object(value, nm_active_connection_get_master(self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_connection_active = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + nm_active_connection_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_10, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_O_PROP("Connection", + PROP_CONNECTION, + NMActiveConnectionPrivate, + property_o[PROPERTY_O_IDX_CONNECTION], + nm_remote_connection_get_type), + NML_DBUS_META_PROPERTY_INIT_B("Default", + PROP_DEFAULT, + NMActiveConnectionPrivate, + is_default), + NML_DBUS_META_PROPERTY_INIT_B("Default6", + PROP_DEFAULT6, + NMActiveConnectionPrivate, + is_default6), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Devices", + PROP_DEVICES, + NMActiveConnectionPrivate, + devices, + nm_device_get_type), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Dhcp4Config", + PROP_DHCP4_CONFIG, + NMActiveConnectionPrivate, + property_o[PROPERTY_O_IDX_DHCP4_CONFIG], + nm_dhcp4_config_get_type), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Dhcp6Config", + PROP_DHCP6_CONFIG, + NMActiveConnectionPrivate, + property_o[PROPERTY_O_IDX_DHCP6_CONFIG], + nm_dhcp6_config_get_type), + NML_DBUS_META_PROPERTY_INIT_S("Id", PROP_ID, NMActiveConnectionPrivate, id), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Ip4Config", + PROP_IP4_CONFIG, + NMActiveConnectionPrivate, + property_o[PROPERTY_O_IDX_IP4_CONFIG], + nm_ip4_config_get_type), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Ip6Config", + PROP_IP6_CONFIG, + NMActiveConnectionPrivate, + property_o[PROPERTY_O_IDX_IP6_CONFIG], + nm_ip6_config_get_type), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Master", + PROP_MASTER, + NMActiveConnectionPrivate, + property_o[PROPERTY_O_IDX_MASTER], + nm_device_get_type), + NML_DBUS_META_PROPERTY_INIT_O("SpecificObject", + PROP_SPECIFIC_OBJECT_PATH, + NMActiveConnectionPrivate, + specific_object_path), + NML_DBUS_META_PROPERTY_INIT_U("State", PROP_STATE, NMActiveConnectionPrivate, state), + NML_DBUS_META_PROPERTY_INIT_U("StateFlags", + PROP_STATE_FLAGS, + NMActiveConnectionPrivate, + state_flags), + NML_DBUS_META_PROPERTY_INIT_S("Type", PROP_TYPE, NMActiveConnectionPrivate, type), + NML_DBUS_META_PROPERTY_INIT_S("Uuid", PROP_UUID, NMActiveConnectionPrivate, uuid), + NML_DBUS_META_PROPERTY_INIT_B("Vpn", PROP_VPN, NMActiveConnectionPrivate, is_vpn), ), + .base_struct_offset = G_STRUCT_OFFSET(NMActiveConnection, _priv), ); + +static void +nm_active_connection_class_init(NMActiveConnectionClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMActiveConnectionPrivate)); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + nm_object_class->is_ready = is_ready; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_INDIRECT(nm_object_class, NMActiveConnection); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_N(nm_object_class, + NMActiveConnectionPrivate, + property_o); + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, NMActiveConnectionPrivate, devices); + + /** + * NMActiveConnection:connection: + * + * The connection that this is an active instance of. + **/ + obj_properties[PROP_CONNECTION] = + g_param_spec_object(NM_ACTIVE_CONNECTION_CONNECTION, + "", + "", + NM_TYPE_REMOTE_CONNECTION, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:id: + * + * The active connection's ID + **/ + obj_properties[PROP_ID] = g_param_spec_string(NM_ACTIVE_CONNECTION_ID, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:uuid: + * + * The active connection's UUID + **/ + obj_properties[PROP_UUID] = g_param_spec_string(NM_ACTIVE_CONNECTION_UUID, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:type: + * + * The active connection's type + **/ + obj_properties[PROP_TYPE] = g_param_spec_string(NM_ACTIVE_CONNECTION_TYPE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:specific-object-path: + * + * The path to the "specific object" of the active connection; see + * nm_active_connection_get_specific_object_path() for more details. + **/ + obj_properties[PROP_SPECIFIC_OBJECT_PATH] = + g_param_spec_string(NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT_PATH, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:devices: (type GPtrArray(NMDevice)) + * + * The devices of the active connection. + **/ + obj_properties[PROP_DEVICES] = g_param_spec_boxed(NM_ACTIVE_CONNECTION_DEVICES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:state: + * + * The state of the active connection. + **/ + obj_properties[PROP_STATE] = g_param_spec_enum(NM_ACTIVE_CONNECTION_STATE, + "", + "", + NM_TYPE_ACTIVE_CONNECTION_STATE, + NM_ACTIVE_CONNECTION_STATE_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:state-flags: + * + * The state flags of the active connection. + * + * Since: 1.10 + **/ + obj_properties[PROP_STATE_FLAGS] = g_param_spec_uint(NM_ACTIVE_CONNECTION_STATE_FLAGS, + "", + "", + 0, + G_MAXUINT32, + NM_ACTIVATION_STATE_FLAG_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:default: + * + * Whether the active connection is the default IPv4 one. + **/ + obj_properties[PROP_DEFAULT] = g_param_spec_boolean(NM_ACTIVE_CONNECTION_DEFAULT, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:ip4-config: + * + * The IPv4 #NMIPConfig of the connection. + **/ + obj_properties[PROP_IP4_CONFIG] = + g_param_spec_object(NM_ACTIVE_CONNECTION_IP4_CONFIG, + "", + "", + NM_TYPE_IP_CONFIG, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:dhcp4-config: + * + * The IPv4 #NMDhcpConfig of the connection. + **/ + obj_properties[PROP_DHCP4_CONFIG] = + g_param_spec_object(NM_ACTIVE_CONNECTION_DHCP4_CONFIG, + "", + "", + NM_TYPE_DHCP_CONFIG, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:default6: + * + * Whether the active connection is the default IPv6 one. + **/ + obj_properties[PROP_DEFAULT6] = g_param_spec_boolean(NM_ACTIVE_CONNECTION_DEFAULT6, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:ip6-config: + * + * The IPv6 #NMIPConfig of the connection. + **/ + obj_properties[PROP_IP6_CONFIG] = + g_param_spec_object(NM_ACTIVE_CONNECTION_IP6_CONFIG, + "", + "", + NM_TYPE_IP_CONFIG, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:dhcp6-config: + * + * The IPv6 #NMDhcpConfig of the connection. + **/ + obj_properties[PROP_DHCP6_CONFIG] = + g_param_spec_object(NM_ACTIVE_CONNECTION_DHCP6_CONFIG, + "", + "", + NM_TYPE_DHCP_CONFIG, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:vpn: + * + * Whether the active connection is a VPN connection. + **/ + obj_properties[PROP_VPN] = g_param_spec_boolean(NM_ACTIVE_CONNECTION_VPN, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMActiveConnection:master: + * + * The master device if one exists. + **/ + obj_properties[PROP_MASTER] = g_param_spec_object(NM_ACTIVE_CONNECTION_MASTER, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_connection_active); + + /* TODO: the state reason should also be exposed as a property in libnm's NMActiveConnection, + * like done for NMDevice's state reason. */ + + /* TODO: the D-Bus API should also expose the state-reason as a property instead of + * a "StateChanged" signal. Like done for Device's "StateReason". */ + + /** + * NMActiveConnection::state-changed: + * @active_connection: the source #NMActiveConnection + * @state: the new state number (#NMActiveConnectionState) + * @reason: the state change reason (#NMActiveConnectionStateReason) + */ + signals[STATE_CHANGED] = g_signal_new("state-changed", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_UINT, + G_TYPE_UINT); +} diff --git a/src/libnm-client-impl/nm-checkpoint.c b/src/libnm-client-impl/nm-checkpoint.c new file mode 100644 index 0000000..c1f6b09 --- /dev/null +++ b/src/libnm-client-impl/nm-checkpoint.c @@ -0,0 +1,202 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-checkpoint.h" + +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-dbus-interface.h" +#include "nm-device.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DEVICES, PROP_CREATED, PROP_ROLLBACK_TIMEOUT, ); + +typedef struct { + NMLDBusPropertyAO devices; + gint64 created; + guint32 rollback_timeout; +} NMCheckpointPrivate; + +struct _NMCheckpoint { + NMObject parent; + NMCheckpointPrivate _priv; +}; + +struct _NMCheckpointClass { + NMObjectClass parent; +}; + +G_DEFINE_TYPE(NMCheckpoint, nm_checkpoint, NM_TYPE_OBJECT) + +#define NM_CHECKPOINT_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMCheckpoint, NM_IS_CHECKPOINT, NMObject) + +/*****************************************************************************/ + +/** + * nm_checkpoint_get_devices: + * @checkpoint: a #NMCheckpoint + * + * The devices that are part of this checkpoint. + * + * Returns: (element-type NMDevice): the devices list. + * + * Since: 1.12 + **/ +const GPtrArray * +nm_checkpoint_get_devices(NMCheckpoint *checkpoint) +{ + g_return_val_if_fail(NM_IS_CHECKPOINT(checkpoint), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_CHECKPOINT_GET_PRIVATE(checkpoint)->devices); +} + +/** + * nm_checkpoint_get_created: + * @checkpoint: a #NMCheckpoint + * + * Gets the timestamp (in CLOCK_BOOTTIME milliseconds) of checkpoint creation. + * + * Use nm_utils_get_timestamp_msec() to obtain current time value suitable for + * comparing to this value. + * + * Returns: the timestamp of checkpoint creation. + * + * Since: 1.12 + **/ +gint64 +nm_checkpoint_get_created(NMCheckpoint *checkpoint) +{ + g_return_val_if_fail(NM_IS_CHECKPOINT(checkpoint), 0); + + return NM_CHECKPOINT_GET_PRIVATE(checkpoint)->created; +} + +/** + * nm_checkpoint_get_rollback_timeout: + * @checkpoint: a #NMCheckpoint + * + * Gets the timeout in seconds for automatic rollback. + * + * Returns: the rollback timeout. + * + * Since: 1.12 + **/ +guint32 +nm_checkpoint_get_rollback_timeout(NMCheckpoint *checkpoint) +{ + g_return_val_if_fail(NM_IS_CHECKPOINT(checkpoint), 0); + + return NM_CHECKPOINT_GET_PRIVATE(checkpoint)->rollback_timeout; +} + +/*****************************************************************************/ + +static void +nm_checkpoint_init(NMCheckpoint *checkpoint) +{} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMCheckpoint * checkpoint = NM_CHECKPOINT(object); + NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE(checkpoint); + + switch (prop_id) { + case PROP_DEVICES: + g_value_take_boxed(value, + _nm_utils_copy_object_array(nm_checkpoint_get_devices(checkpoint))); + break; + case PROP_CREATED: + g_value_set_int64(value, priv->created); + break; + case PROP_ROLLBACK_TIMEOUT: + g_value_set_uint(value, priv->rollback_timeout); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_checkpoint = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_CHECKPOINT, + nm_checkpoint_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_X("Created", PROP_CREATED, NMCheckpoint, _priv.created), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Devices", + PROP_DEVICES, + NMCheckpoint, + _priv.devices, + nm_device_get_type, + .is_always_ready = TRUE), + NML_DBUS_META_PROPERTY_INIT_U("RollbackTimeout", + PROP_ROLLBACK_TIMEOUT, + NMCheckpoint, + _priv.rollback_timeout), ), ); + +static void +nm_checkpoint_class_init(NMCheckpointClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMCheckpoint); + + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, NMCheckpointPrivate, devices); + + /** + * NMCheckpoint:devices: (type GPtrArray(NMDevice)) + * + * The devices that are part of this checkpoint. + * + * Since: 1.12 + **/ + obj_properties[PROP_DEVICES] = g_param_spec_boxed(NM_CHECKPOINT_DEVICES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMCheckpoint:created: + * + * The timestamp (in CLOCK_BOOTTIME milliseconds) of checkpoint creation. + * + * Since: 1.12 + **/ + obj_properties[PROP_CREATED] = g_param_spec_int64(NM_CHECKPOINT_CREATED, + "", + "", + G_MININT64, + G_MAXINT64, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMCheckpoint:rollback-timeout: + * + * Timeout in seconds for automatic rollback, or zero. + * + * Since: 1.12 + **/ + obj_properties[PROP_ROLLBACK_TIMEOUT] = + g_param_spec_uint(NM_CHECKPOINT_ROLLBACK_TIMEOUT, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_checkpoint); +} diff --git a/src/libnm-client-impl/nm-client.c b/src/libnm-client-impl/nm-client.c new file mode 100644 index 0000000..211bc21 --- /dev/null +++ b/src/libnm-client-impl/nm-client.c @@ -0,0 +1,8754 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2018 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-client.h" + +#include + +#include "libnm-std-aux/c-list-util.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-core-aux-intern/nm-common-macros.h" + +#include "nm-access-point.h" +#include "nm-active-connection.h" +#include "nm-checkpoint.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-dbus-helpers.h" +#include "nm-device-6lowpan.h" +#include "nm-device-adsl.h" +#include "nm-device-bond.h" +#include "nm-device-bridge.h" +#include "nm-device-bt.h" +#include "nm-device-dummy.h" +#include "nm-device-ethernet.h" +#include "nm-device-generic.h" +#include "nm-device-infiniband.h" +#include "nm-device-ip-tunnel.h" +#include "nm-device-macsec.h" +#include "nm-device-macvlan.h" +#include "nm-device-modem.h" +#include "nm-device-olpc-mesh.h" +#include "nm-device-ovs-bridge.h" +#include "nm-device-ovs-interface.h" +#include "nm-device-ovs-port.h" +#include "nm-device-ppp.h" +#include "nm-device-team.h" +#include "nm-device-tun.h" +#include "nm-device-vlan.h" +#include "nm-device-vxlan.h" +#include "nm-device-wifi-p2p.h" +#include "nm-device-wifi.h" +#include "nm-device-wireguard.h" +#include "nm-device-wpan.h" +#include "nm-dhcp-config.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" +#include "nm-dns-manager.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" +#include "nm-object-private.h" +#include "nm-remote-connection.h" +#include "nm-utils.h" +#include "nm-vpn-connection.h" +#include "nm-wifi-p2p-peer.h" + +/*****************************************************************************/ + +NM_CACHED_QUARK_FCN("nm-context-busy-watcher", nm_context_busy_watcher_quark); + +static void +_context_busy_watcher_attach_integration_source_cb(gpointer data, GObject *where_the_object_was) +{ + nm_g_source_destroy_and_unref(data); +} + +void +nm_context_busy_watcher_integrate_source(GMainContext *outer_context, + GMainContext *inner_context, + GObject * context_busy_watcher) +{ + GSource *source; + + nm_assert(outer_context); + nm_assert(inner_context); + nm_assert(outer_context != inner_context); + nm_assert(G_IS_OBJECT(context_busy_watcher)); + + source = nm_utils_g_main_context_create_integrate_source(inner_context); + g_source_attach(source, outer_context); + + /* The problem is... + * + * NMClient is associated with a GMainContext, just like its underlying GDBusConnection + * also queues signals and callbacks on that main context. During operation, NMClient + * will schedule async operations which will return asynchronously on the GMainContext. + * + * Note that depending on whether NMClient got initialized synchronously or asynchronously, + * it has an internal priv->dbus_context that is different from the outer priv->main_context. + * However, the problem is in both cases. + * + * So, as long as there are pending D-Bus calls, the GMainContext is referenced and kept alive. + * When NMClient gets destroyed, the pending calls get cancelled, but the async callback are still + * scheduled to return. + * That means, the main context stays alive until it gets iterated long enough so that all pending + * operations are completed. + * + * Note that pending operations don't keep NMClient alive, so NMClient can already be gone by + * then, but the user still should iterate the main context long enough to process the (cancelled) + * callbacks... at least, if the user cares about whether the remaining memory and file descriptors + * of the GMainContext can be reclaimed. + * + * In hindsight, maybe pending references should kept NMClient alive. But then NMClient would + * need a special "shutdown()" API that the user must invoke, because unrefing would no longer + * be enough to ensure a shutdown (imagine a situation where NMClient receives a constant flow + * of "CheckPermissions" signals, which keeps retriggering an async request). Anyway, we cannot + * add such a shutdown API now, as it would break client's expectations that they can just unref + * the NMClient to destroy it. + * + * So, we allow NMClient to unref, but the user is advised to keep iterating the main context. + * But for how long? Here comes nm_client_get_context_busy_watcher() into play. The user may + * subscribe a weak pointer to that instance and should keep iterating as long as the object + * exists. + * + * Now, back to synchronous initialization. Here we have the internal priv->dbus_context context. + * We also cannot remove that context right away, instead we need to keep it integrated in the + * caller's priv->main_context as long as we have pending calls: that is, as long as the + * context-busy-watcher is alive. + */ + + g_object_weak_ref(context_busy_watcher, + _context_busy_watcher_attach_integration_source_cb, + source); +} + +/*****************************************************************************/ + +typedef struct { + /* It is quite wasteful to require 2 pointers per property (of an instance) only to track whether + * the property got changed. But it's convenient! */ + CList changed_prop_lst; + + GVariant *prop_data_value; +} NMLDBusObjPropData; + +typedef struct { + CList iface_lst; + union { + const NMLDBusMetaIface *meta; + NMRefString * name; + } dbus_iface; + + CList changed_prop_lst_head; + + /* We also keep track of non-well known interfaces. The presence of a D-Bus interface + * is what makes a D-Bus alive or not. As we should track all D-Bus objects, we also + * need to track whether there are any interfaces on it -- even if we otherwise don't + * care about the interface. */ + bool dbus_iface_is_wellknown : 1; + + /* if TRUE, the interface is about to be removed. */ + bool iface_removed : 1; + + bool nmobj_checked : 1; + bool nmobj_compatible : 1; + + NMLDBusObjPropData prop_datas[]; +} NMLDBusObjIfaceData; + +/* The dbus_path must be the first element, so when we hash the object by the dbus_path, + * we also can lookup the object by only having a NMRefString at hand + * using nm_pdirect_hash()/nm_pdirect_equal(). */ +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMLDBusObject, dbus_path) == 0); + +typedef void (*NMLDBusObjWatchNotifyFcn)(NMClient *client, gpointer obj_watcher); + +struct _NMLDBusObjWatcher { + NMLDBusObject *dbobj; + struct { + CList watcher_lst; + NMLDBusObjWatchNotifyFcn notify_fcn; + } _priv; +}; + +typedef struct { + NMLDBusObjWatcher parent; + gpointer user_data; +} NMLDBusObjWatcherWithPtr; + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMClient, + PROP_DBUS_CONNECTION, + PROP_DBUS_NAME_OWNER, + PROP_VERSION, + PROP_INSTANCE_FLAGS, + PROP_STATE, + PROP_STARTUP, + PROP_NM_RUNNING, + PROP_NETWORKING_ENABLED, + PROP_WIRELESS_ENABLED, + PROP_WIRELESS_HARDWARE_ENABLED, + PROP_WWAN_ENABLED, + PROP_WWAN_HARDWARE_ENABLED, + PROP_WIMAX_ENABLED, + PROP_WIMAX_HARDWARE_ENABLED, + PROP_ACTIVE_CONNECTIONS, + PROP_CONNECTIVITY, + PROP_CONNECTIVITY_CHECK_URI, + PROP_CONNECTIVITY_CHECK_AVAILABLE, + PROP_CONNECTIVITY_CHECK_ENABLED, + PROP_PRIMARY_CONNECTION, + PROP_ACTIVATING_CONNECTION, + PROP_DEVICES, + PROP_ALL_DEVICES, + PROP_CONNECTIONS, + PROP_HOSTNAME, + PROP_CAN_MODIFY, + PROP_METERED, + PROP_DNS_MODE, + PROP_DNS_RC_MANAGER, + PROP_DNS_CONFIGURATION, + PROP_CHECKPOINTS, + PROP_CAPABILITIES, + PROP_PERMISSIONS_STATE, ); + +enum { + DEVICE_ADDED, + DEVICE_REMOVED, + ANY_DEVICE_ADDED, + ANY_DEVICE_REMOVED, + PERMISSION_CHANGED, + CONNECTION_ADDED, + CONNECTION_REMOVED, + ACTIVE_CONNECTION_ADDED, + ACTIVE_CONNECTION_REMOVED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +enum { + PROPERTY_O_IDX_NM_ACTIVATING_CONNECTION = 0, + PROPERTY_O_IDX_NM_PRIMAY_CONNECTION, + _PROPERTY_O_IDX_NM_NUM, +}; + +enum { + PROPERTY_AO_IDX_DEVICES = 0, + PROPERTY_AO_IDX_ALL_DEVICES, + PROPERTY_AO_IDX_ACTIVE_CONNECTIONS, + PROPERTY_AO_IDX_CHECKPOINTS, + _PROPERTY_AO_IDX_NM_NUM, +}; + +typedef struct { + struct udev * udev; + GMainContext * main_context; + GMainContext * dbus_context; + GObject * context_busy_watcher; + GDBusConnection *dbus_connection; + NMLInitData * init_data; + GHashTable * dbus_objects; + CList obj_changed_lst_head; + GCancellable * name_owner_get_cancellable; + GCancellable * get_managed_objects_cancellable; + + CList queue_notify_lst_head; + CList notify_event_lst_head; + + CList dbus_objects_lst_head_watched_only; + CList dbus_objects_lst_head_on_dbus; + CList dbus_objects_lst_head_with_nmobj_not_ready; + CList dbus_objects_lst_head_with_nmobj_ready; + + NMLDBusObject *dbobj_nm; + NMLDBusObject *dbobj_settings; + NMLDBusObject *dbobj_dns_manager; + + gsize log_call_counter; + + guint8 * permissions; + GCancellable *permissions_cancellable; + + char *name_owner; + guint name_owner_changed_id; + guint dbsid_nm_object_manager; + guint dbsid_dbus_properties_properties_changed; + guint dbsid_nm_settings_connection_updated; + guint dbsid_nm_connection_active_state_changed; + guint dbsid_nm_vpn_connection_state_changed; + guint dbsid_nm_check_permissions; + + NMClientInstanceFlags instance_flags : 3; + + NMTernary permissions_state : 3; + + bool instance_flags_constructed : 1; + + bool udev_inited : 1; + bool notify_event_lst_changed : 1; + bool check_dbobj_visible_all : 1; + bool nm_running : 1; + + struct { + NMLDBusPropertyO property_o[_PROPERTY_O_IDX_NM_NUM]; + NMLDBusPropertyAO property_ao[_PROPERTY_AO_IDX_NM_NUM]; + char * connectivity_check_uri; + char * version; + guint32 * capabilities_arr; + gsize capabilities_len; + guint32 connectivity; + guint32 state; + guint32 metered; + bool connectivity_check_available; + bool connectivity_check_enabled; + bool networking_enabled; + bool startup; + bool wireless_enabled; + bool wireless_hardware_enabled; + bool wwan_enabled; + bool wwan_hardware_enabled; + } nm; + + struct { + NMLDBusPropertyAO connections; + char * hostname; + bool can_modify; + } settings; + + struct { + GPtrArray *configuration; + char * mode; + char * rc_manager; + } dns_manager; + +} NMClientPrivate; + +struct _NMClient { + union { + GObject parent; + NMObjectBase obj_base; + }; + NMClientPrivate _priv; +}; + +struct _NMClientClass { + union { + GObjectClass parent; + NMObjectBaseClass obj_base; + }; +}; + +static void nm_client_initable_iface_init(GInitableIface *iface); +static void nm_client_async_initable_iface_init(GAsyncInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE(NMClient, + nm_client, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE, nm_client_initable_iface_init); + G_IMPLEMENT_INTERFACE(G_TYPE_ASYNC_INITABLE, + nm_client_async_initable_iface_init);) + +#define NM_CLIENT_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMClient, NM_IS_CLIENT) + +/*****************************************************************************/ + +static void _init_start_check_complete(NMClient *self); + +static void name_owner_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data); + +static void name_owner_get_call(NMClient *self); + +static void _set_nm_running(NMClient *self); + +/*****************************************************************************/ + +static NMRefString *_dbus_path_nm = NULL; +static NMRefString *_dbus_path_settings = NULL; +static NMRefString *_dbus_path_dns_manager = NULL; + +/*****************************************************************************/ + +static NM_UTILS_LOOKUP_STR_DEFINE( + nml_dbus_obj_state_to_string, + NMLDBusObjState, + NM_UTILS_LOOKUP_DEFAULT_WARN("???"), + NM_UTILS_LOOKUP_ITEM(NML_DBUS_OBJ_STATE_UNLINKED, "unlinked"), + NM_UTILS_LOOKUP_ITEM(NML_DBUS_OBJ_STATE_WATCHED_ONLY, "watched-only"), + NM_UTILS_LOOKUP_ITEM(NML_DBUS_OBJ_STATE_ON_DBUS, "on-dbus"), + NM_UTILS_LOOKUP_ITEM(NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY, "not-ready"), + NM_UTILS_LOOKUP_ITEM(NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY, "ready"), ); + +/*****************************************************************************/ + +/** + * nm_client_error_quark: + * + * Registers an error quark for #NMClient if necessary. + * + * Returns: the error quark used for #NMClient errors. + **/ +NM_CACHED_QUARK_FCN("nm-client-error-quark", nm_client_error_quark); + +/*****************************************************************************/ + +NMLInitData * +nml_init_data_new_sync(GCancellable *cancellable, GMainLoop *main_loop, GError **error_location) +{ + NMLInitData *init_data; + + init_data = g_slice_new(NMLInitData); + *init_data = (NMLInitData){ + .cancellable = nm_g_object_ref(cancellable), + .is_sync = TRUE, + .data.sync = + { + .main_loop = main_loop, + .error_location = error_location, + }, + }; + return init_data; +} + +NMLInitData * +nml_init_data_new_async(GCancellable *cancellable, GTask *task_take) +{ + NMLInitData *init_data; + + init_data = g_slice_new(NMLInitData); + *init_data = (NMLInitData){ + .cancellable = nm_g_object_ref(cancellable), + .is_sync = FALSE, + .data.async = + { + .task = g_steal_pointer(&task_take), + }, + }; + return init_data; +} + +void +nml_init_data_return(NMLInitData *init_data, GError *error_take) +{ + nm_assert(init_data); + + nm_clear_pointer(&init_data->cancel_on_idle_source, nm_g_source_destroy_and_unref); + nm_clear_g_signal_handler(init_data->cancellable, &init_data->cancelled_id); + + if (init_data->is_sync) { + if (error_take) + g_propagate_error(init_data->data.sync.error_location, error_take); + g_main_loop_quit(init_data->data.sync.main_loop); + } else { + if (error_take) + g_task_return_error(init_data->data.async.task, error_take); + else + g_task_return_boolean(init_data->data.async.task, TRUE); + g_object_unref(init_data->data.async.task); + } + nm_g_object_unref(init_data->cancellable); + nm_g_slice_free(init_data); +} + +/*****************************************************************************/ + +GError * +_nm_client_new_error_nm_not_running(void) +{ + return g_error_new_literal(NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); +} + +GError * +_nm_client_new_error_nm_not_cached(void) +{ + return g_error_new_literal(NM_CLIENT_ERROR, + NM_CLIENT_ERROR_FAILED, + "Object is no longer in the client cache"); +} + +static void +_nm_client_dbus_call_simple_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + GAsyncReadyCallback callback; + gpointer callback_user_data; + gs_unref_object GObject *context_busy_watcher = NULL; + gpointer obfuscated_self_ptr; + gpointer log_call_counter_ptr; + + nm_utils_user_data_unpack(user_data, + &callback, + &callback_user_data, + &context_busy_watcher, + &obfuscated_self_ptr, + &log_call_counter_ptr); + + NML_DBUS_LOG(_NML_NMCLIENT_LOG_LEVEL_COERCE(NML_DBUS_LOG_LEVEL_TRACE), + "nmclient[" NM_HASH_OBFUSCATE_PTR_FMT "]: call[%" G_GSIZE_FORMAT "] completed", + (guint64) GPOINTER_TO_SIZE(obfuscated_self_ptr), + GPOINTER_TO_SIZE(log_call_counter_ptr)); + + callback(source, result, callback_user_data); +} + +void +_nm_client_dbus_call_simple(NMClient * self, + GCancellable * cancellable, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMClientPrivate * priv = NM_CLIENT_GET_PRIVATE(self); + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + gs_free char * log_str = NULL; + gsize log_call_counter; + + nm_assert(priv->name_owner); + nm_assert(!cancellable || G_IS_CANCELLABLE(cancellable)); + nm_assert(callback); + nm_assert(object_path); + nm_assert(interface_name); + nm_assert(method_name); + nm_assert(parameters); + nm_assert(reply_type); + + dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context); + + log_call_counter = ++priv->log_call_counter; + + NML_NMCLIENT_LOG_T(self, + "call[%" G_GSIZE_FORMAT "] D-Bus method on %s: %s, %s.%s -> %s (%s)", + log_call_counter, + priv->name_owner, + object_path, + interface_name, + method_name, + (const char *) reply_type ?: "???", + parameters ? (log_str = g_variant_print(parameters, TRUE)) : "NULL"); + + g_dbus_connection_call(priv->dbus_connection, + priv->name_owner, + object_path, + interface_name, + method_name, + parameters, + reply_type, + flags, + timeout_msec, + cancellable, + _nm_client_dbus_call_simple_cb, + nm_utils_user_data_pack(callback, + user_data, + g_object_ref(priv->context_busy_watcher), + GSIZE_TO_POINTER(NM_HASH_OBFUSCATE_PTR(self)), + GSIZE_TO_POINTER(log_call_counter))); +} + +void +_nm_client_dbus_call(NMClient * self, + gpointer source_obj, + gpointer source_tag, + GCancellable * cancellable, + GAsyncReadyCallback user_callback, + gpointer user_callback_data, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + GAsyncReadyCallback internal_callback) +{ + NMClientPrivate *priv; + gs_unref_object GTask *task = NULL; + + nm_assert(!source_obj || G_IS_OBJECT(source_obj)); + nm_assert(source_tag); + nm_assert(!cancellable || G_IS_CANCELLABLE(cancellable)); + nm_assert(internal_callback); + nm_assert(object_path); + nm_assert(interface_name); + nm_assert(method_name); + nm_assert(parameters); + nm_assert(reply_type); + + task = nm_g_task_new(source_obj, cancellable, source_tag, user_callback, user_callback_data); + + if (!self) { + nm_g_variant_unref_floating(parameters); + g_task_return_error(task, _nm_client_new_error_nm_not_cached()); + return; + } + + priv = NM_CLIENT_GET_PRIVATE(self); + if (!priv->name_owner) { + nm_g_variant_unref_floating(parameters); + g_task_return_error(task, _nm_client_new_error_nm_not_running()); + return; + } + + _nm_client_dbus_call_simple(self, + cancellable, + object_path, + interface_name, + method_name, + parameters, + reply_type, + flags, + timeout_msec, + internal_callback, + g_steal_pointer(&task)); +} + +GVariant * +_nm_client_dbus_call_sync(NMClient * self, + GCancellable * cancellable, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + gboolean strip_dbus_error, + GError ** error) +{ + NMClientPrivate *priv; + gs_unref_variant GVariant *ret = NULL; + + nm_assert(!cancellable || G_IS_CANCELLABLE(cancellable)); + nm_assert(!error || !*error); + nm_assert(object_path); + nm_assert(interface_name); + nm_assert(method_name); + nm_assert(parameters); + nm_assert(reply_type); + + if (!self) { + nm_g_variant_unref_floating(parameters); + nm_g_set_error_take_lazy(error, _nm_client_new_error_nm_not_cached()); + return NULL; + } + + priv = NM_CLIENT_GET_PRIVATE(self); + if (!priv->name_owner) { + nm_g_variant_unref_floating(parameters); + nm_g_set_error_take_lazy(error, _nm_client_new_error_nm_not_running()); + return NULL; + } + + ret = g_dbus_connection_call_sync(priv->dbus_connection, + priv->name_owner, + object_path, + interface_name, + method_name, + parameters, + reply_type, + flags, + timeout_msec, + cancellable, + error); + if (!ret) { + if (error && strip_dbus_error) + g_dbus_error_strip_remote_error(*error); + return NULL; + } + + return g_steal_pointer(&ret); +} + +gboolean +_nm_client_dbus_call_sync_void(NMClient * self, + GCancellable * cancellable, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + GDBusCallFlags flags, + int timeout_msec, + gboolean strip_dbus_error, + GError ** error) +{ + gs_unref_variant GVariant *ret = NULL; + + ret = _nm_client_dbus_call_sync(self, + cancellable, + object_path, + interface_name, + method_name, + parameters, + G_VARIANT_TYPE("()"), + flags, + timeout_msec, + strip_dbus_error, + error); + return !!ret; +} + +void +_nm_client_set_property_sync_legacy(NMClient * self, + const char *object_path, + const char *interface_name, + const char *property_name, + const char *format_string, + ...) +{ + NMClientPrivate *priv; + GVariant * val; + gs_unref_variant GVariant *ret = NULL; + va_list ap; + + nm_assert(!self || NM_IS_CLIENT(self)); + nm_assert(interface_name); + nm_assert(property_name); + nm_assert(format_string); + + if (!self) + return; + + priv = NM_CLIENT_GET_PRIVATE(self); + if (!priv->name_owner) + return; + + va_start(ap, format_string); + val = g_variant_new_va(format_string, NULL, &ap); + va_end(ap); + + nm_assert(val); + + /* A synchronous D-Bus call that is not cancellable an ignores the return value. + * This function only exists for backward compatibility. */ + ret = g_dbus_connection_call_sync(priv->dbus_connection, + priv->name_owner, + object_path, + DBUS_INTERFACE_PROPERTIES, + "Set", + g_variant_new("(ssv)", interface_name, property_name, val), + NULL, + G_DBUS_CALL_FLAGS_NONE, + 2000, + NULL, + NULL); +} + +/*****************************************************************************/ + +#define _assert_main_context_is_current_source(self, x_context) \ + G_STMT_START \ + { \ + if (NM_MORE_ASSERTS > 0) { \ + GSource *_source = g_main_current_source(); \ + \ + if (_source) { \ + NMClientPrivate *_priv = NM_CLIENT_GET_PRIVATE(self); \ + \ + nm_assert(g_source_get_context(_source) == _priv->x_context); \ + nm_assert(g_main_context_is_owner(_priv->x_context)); \ + } \ + } \ + } \ + G_STMT_END + +#define _assert_main_context_is_current_thread_default(self, x_context) \ + G_STMT_START \ + { \ + if (NM_MORE_ASSERTS > 0) { \ + NMClientPrivate *_priv = NM_CLIENT_GET_PRIVATE(self); \ + \ + nm_assert((g_main_context_get_thread_default() ?: g_main_context_default()) \ + == _priv->x_context); \ + nm_assert(g_main_context_is_owner(_priv->x_context)); \ + } \ + } \ + G_STMT_END + +/*****************************************************************************/ + +void +_nm_client_queue_notify_object(NMClient *self, gpointer nmobj, const GParamSpec *pspec) +{ + NMObjectBase *base; + + nm_assert(NM_IS_CLIENT(self)); + nm_assert(NM_IS_OBJECT(nmobj) || NM_IS_CLIENT(nmobj)); + + base = (NMObjectBase *) nmobj; + + if (base->is_disposing) { + /* Don't emit property changed signals once the NMClient + * instance is about to shut down. */ + nm_assert(nmobj == self); + return; + } + + if (c_list_is_empty(&base->queue_notify_lst)) { + c_list_link_tail(&NM_CLIENT_GET_PRIVATE(self)->queue_notify_lst_head, + &base->queue_notify_lst); + g_object_ref(nmobj); + g_object_freeze_notify(nmobj); + } + + if (pspec) + g_object_notify_by_pspec(nmobj, (GParamSpec *) pspec); +} + +/*****************************************************************************/ + +gpointer +_nm_client_notify_event_queue(NMClient * self, + int priority, + NMClientNotifyEventCb callback, + gsize event_size) +{ + NMClientPrivate * priv = NM_CLIENT_GET_PRIVATE(self); + NMClientNotifyEvent *notify_event; + + nm_assert(callback); + nm_assert(event_size > sizeof(NMClientNotifyEvent)); + + notify_event = g_malloc(event_size); + notify_event->priority = priority; + notify_event->callback = callback; + c_list_link_tail(&priv->notify_event_lst_head, ¬ify_event->lst); + priv->notify_event_lst_changed = TRUE; + return notify_event; +} + +NMClientNotifyEventWithPtr * +_nm_client_notify_event_queue_with_ptr(NMClient * self, + int priority, + NMClientNotifyEventWithPtrCb callback, + gpointer user_data) +{ + NMClientNotifyEventWithPtr *notify_event; + + notify_event = _nm_client_notify_event_queue(self, + priority, + (NMClientNotifyEventCb) callback, + sizeof(NMClientNotifyEventWithPtr)); + notify_event->user_data = user_data; + return notify_event; +} + +/*****************************************************************************/ + +typedef struct { + NMClientNotifyEvent parent; + GObject * source; + NMObject * obj; + guint signal_id; +} NMClientNotifyEventObjAddedRemove; + +static void +_nm_client_notify_event_queue_emit_obj_signal_cb(NMClient *self, gpointer notify_event_base) +{ + NMClientNotifyEventObjAddedRemove *notify_event = notify_event_base; + + NML_NMCLIENT_LOG_T( + self, + "[%s] emit \"%s\" signal for %s", + NM_IS_CLIENT(notify_event->source) ? "nmclient" : _nm_object_get_path(notify_event->source), + g_signal_name(notify_event->signal_id), + _nm_object_get_path(notify_event->obj)); + + nm_assert(NM_IS_OBJECT(notify_event->source) || NM_IS_CLIENT(notify_event->source)); + + g_signal_emit(notify_event->source, notify_event->signal_id, 0, notify_event->obj); + + g_object_unref(notify_event->obj); + g_object_unref(notify_event->source); +} + +void +_nm_client_notify_event_queue_emit_obj_signal(NMClient *self, + GObject * source, + NMObject *nmobj, + gboolean is_added /* or else removed */, + int prio_offset, + guint signal_id) +{ + NMClientNotifyEventObjAddedRemove *notify_event; + + nm_assert(prio_offset >= 0); + nm_assert(prio_offset < 20); + nm_assert(NM_IS_OBJECT(source) || NM_IS_CLIENT(source)); + nm_assert(NM_IS_OBJECT(nmobj)); + + if (((NMObjectBase *) source)->is_disposing) { + nm_assert(NM_IS_CLIENT(source)); + return; + } + + notify_event = _nm_client_notify_event_queue( + self, + is_added ? NM_CLIENT_NOTIFY_EVENT_PRIO_AFTER - 20 + prio_offset + : NM_CLIENT_NOTIFY_EVENT_PRIO_BEFORE + 20 - prio_offset, + _nm_client_notify_event_queue_emit_obj_signal_cb, + sizeof(NMClientNotifyEventObjAddedRemove)); + notify_event->source = g_object_ref(source); + notify_event->obj = g_object_ref(nmobj); + notify_event->signal_id = signal_id; +} + +/*****************************************************************************/ + +static int +_nm_client_notify_event_cmp(const CList *a, const CList *b, const void *user_data) +{ + NM_CMP_DIRECT(c_list_entry(a, NMClientNotifyEvent, lst)->priority, + c_list_entry(b, NMClientNotifyEvent, lst)->priority); + return 0; +} + +static void +_nm_client_notify_event_emit_parts(NMClient *self, int max_priority /* included! */) +{ + NMClientPrivate * priv = NM_CLIENT_GET_PRIVATE(self); + NMClientNotifyEvent *notify_event; + + while (TRUE) { + if (priv->notify_event_lst_changed) { + priv->notify_event_lst_changed = FALSE; + c_list_sort(&priv->notify_event_lst_head, _nm_client_notify_event_cmp, NULL); + } + notify_event = c_list_first_entry(&priv->notify_event_lst_head, NMClientNotifyEvent, lst); + if (!notify_event) + return; + if (notify_event->priority > max_priority) + return; + c_list_unlink_stale(¬ify_event->lst); + notify_event->callback(self, notify_event); + g_free(notify_event); + } +} + +static void +_nm_client_notify_event_emit(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + NMObjectBase * base; + + _nm_client_notify_event_emit_parts(self, NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP); + + while ( + (base = c_list_first_entry(&priv->queue_notify_lst_head, NMObjectBase, queue_notify_lst))) { + c_list_unlink(&base->queue_notify_lst); + g_object_thaw_notify(G_OBJECT(base)); + g_object_unref(base); + } + + _nm_client_notify_event_emit_parts(self, G_MAXINT); +} + +/*****************************************************************************/ + +GDBusConnection * +_nm_client_get_dbus_connection(NMClient *self) +{ + return NM_CLIENT_GET_PRIVATE(self)->dbus_connection; +} + +const char * +_nm_client_get_dbus_name_owner(NMClient *self) +{ + return NM_CLIENT_GET_PRIVATE(self)->name_owner; +} + +GMainContext * +_nm_client_get_context_main(NMClient *self) +{ + return NM_CLIENT_GET_PRIVATE(self)->main_context; +} + +GMainContext * +_nm_client_get_context_dbus(NMClient *self) +{ + return NM_CLIENT_GET_PRIVATE(self)->dbus_context; +} + +/** + * nm_client_get_main_context: + * @self: the #NMClient instance + * + * The #NMClient instance is permanently associated with the current + * thread default #GMainContext, referenced the time when the instance + * was created. To receive events, the user must iterate this context + * and can use it to synchronize access to the client. + * + * Note that even after #NMClient instance got destroyed, there might + * still be pending sources registered in the context. That means, to fully + * clean up, the user must continue iterating the context as long as + * the nm_client_get_context_busy_watcher() object is alive. + * + * Returns: (transfer none): the #GMainContext of the client. + * + * Since: 1.22 + */ +GMainContext * +nm_client_get_main_context(NMClient *self) +{ + g_return_val_if_fail(NM_IS_CLIENT(self), NULL); + + return _nm_client_get_context_main(self); +} + +/** + * nm_client_get_context_busy_watcher: + * @self: the NMClient instance. + * + * Returns: (transfer none): a GObject that stays alive as long as there are pending + * D-Bus operations. + * + * NMClient will schedule asynchronous D-Bus requests which will complete on + * the GMainContext associated with the instance. When destroying the NMClient + * instance, those requests are cancelled right away, however their pending requests are + * still outstanding and queued in the GMainContext. These outstanding callbacks + * keep the GMainContext alive. In order to fully release all resources, + * the user must keep iterating the main context until all these callbacks + * are handled. Of course, at this point no more actual callbacks will be invoked + * for the user, those are all internally cancelled. + * + * This just leaves one problem: how long does the user need to keep the + * GMainContext running to ensure everything is cleaned up? The answer is + * this GObject. Subscribe a weak reference to the returned object and keep + * iterating the main context until the object got unreferenced. + * + * Note that after the NMClient instance gets destroyed, the remaining callbacks + * will be invoked right away. That means, the user won't have to iterate the + * main context much longer. + * + * Since: 1.22 + */ +GObject * +nm_client_get_context_busy_watcher(NMClient *self) +{ + GObject *w; + + g_return_val_if_fail(NM_IS_CLIENT(self), NULL); + + w = NM_CLIENT_GET_PRIVATE(self)->context_busy_watcher; + return g_object_get_qdata(w, nm_context_busy_watcher_quark()) ?: w; +} + +struct udev * +_nm_client_get_udev(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + if (G_UNLIKELY(!priv->udev_inited)) { + priv->udev_inited = TRUE; + /* for testing, we don't want to use udev in libnm. */ + if (!nm_streq0(g_getenv("LIBNM_USE_NO_UDEV"), "1")) + priv->udev = udev_new(); + } + + return priv->udev; +} + +/*****************************************************************************/ + +static void +_ASSERT_dbobj(NMLDBusObject *dbobj, NMClient *self) +{ +#if NM_MORE_ASSERTS > 5 + nm_assert(NM_IS_CLIENT(self)); + nm_assert(NML_IS_DBUS_OBJECT(dbobj)); + nm_assert(dbobj == g_hash_table_lookup(NM_CLIENT_GET_PRIVATE(self)->dbus_objects, dbobj)); +#endif +} + +static NMLDBusObject * +nml_dbus_object_new(NMRefString *dbus_path_take) +{ + NMLDBusObject *dbobj; + + nm_assert(NM_IS_REF_STRING(dbus_path_take)); + + dbobj = g_slice_new(NMLDBusObject); + *dbobj = (NMLDBusObject){ + .dbus_path = g_steal_pointer(&dbus_path_take), + .ref_count = 1, + .dbus_objects_lst = C_LIST_INIT(dbobj->dbus_objects_lst), + .iface_lst_head = C_LIST_INIT(dbobj->iface_lst_head), + .watcher_lst_head = C_LIST_INIT(dbobj->watcher_lst_head), + .obj_changed_lst = C_LIST_INIT(dbobj->obj_changed_lst), + .obj_state = NML_DBUS_OBJ_STATE_UNLINKED, + }; + return dbobj; +} + +NMLDBusObject * +nml_dbus_object_ref(NMLDBusObject *dbobj) +{ + nm_assert(dbobj); + nm_assert(dbobj->ref_count > 0); + + dbobj->ref_count++; + return dbobj; +} + +void +nml_dbus_object_unref(NMLDBusObject *dbobj) +{ + nm_assert(dbobj); + nm_assert(dbobj->ref_count > 0); + + if (--dbobj->ref_count > 0) + return; + + nm_assert(c_list_is_empty(&dbobj->obj_changed_lst)); + nm_assert(c_list_is_empty(&dbobj->iface_lst_head)); + nm_assert(c_list_is_empty(&dbobj->watcher_lst_head)); + nm_assert(!dbobj->nmobj); + + nm_ref_string_unref(dbobj->dbus_path); + nm_g_slice_free(dbobj); +} + +static NMLDBusObjIfaceData * +nml_dbus_object_iface_data_get(NMLDBusObject *dbobj, + const char * dbus_iface_name, + gboolean allow_create) +{ + const NMLDBusMetaIface *meta_iface; + NMLDBusObjIfaceData * db_iface_data; + NMLDBusObjPropData * db_prop_data; + guint count = 0; + guint i; + + nm_assert(NML_IS_DBUS_OBJECT(dbobj)); + nm_assert(dbus_iface_name); + +#if NM_MORE_ASSERTS > 10 + { + gboolean expect_well_known = TRUE; + + /* all well-known interfaces must come first in the list. */ + c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) { + if (db_iface_data->dbus_iface_is_wellknown == expect_well_known) + continue; + nm_assert(expect_well_known); + expect_well_known = FALSE; + } + } +#endif + + meta_iface = nml_dbus_meta_iface_get(dbus_iface_name); + if (meta_iface) { + c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) { + if (!db_iface_data->dbus_iface_is_wellknown) + break; + if (db_iface_data->iface_removed) + continue; + if (db_iface_data->dbus_iface.meta == meta_iface) + return db_iface_data; + count++; + } + } else { + c_list_for_each_entry_prev (db_iface_data, &dbobj->iface_lst_head, iface_lst) { + if (db_iface_data->dbus_iface_is_wellknown) + break; + if (db_iface_data->iface_removed) + continue; + if (nm_streq(db_iface_data->dbus_iface.name->str, dbus_iface_name)) + return db_iface_data; + count++; + } + } + + if (!allow_create) + return NULL; + + if (count > 20) { + /* We track the list of interfaces that an object has in a linked list. + * That is efficient and convenient, if we assume that each object only has a small + * number of interfaces (which very much should be the case). Here, something is very + * odd, maybe there is a bug or the server side is misbehaving. Anyway, error out. */ + return NULL; + } + + db_iface_data = g_malloc( + G_STRUCT_OFFSET(NMLDBusObjIfaceData, prop_datas) + + (meta_iface ? (sizeof(NMLDBusObjPropData) * meta_iface->n_dbus_properties) : 0u)); + if (meta_iface) { + *db_iface_data = (NMLDBusObjIfaceData){ + .dbus_iface.meta = meta_iface, + .dbus_iface_is_wellknown = TRUE, + .changed_prop_lst_head = C_LIST_INIT(db_iface_data->changed_prop_lst_head), + .iface_removed = FALSE, + }; + db_prop_data = &db_iface_data->prop_datas[0]; + for (i = 0; i < meta_iface->n_dbus_properties; i++, db_prop_data++) { + *db_prop_data = (NMLDBusObjPropData){ + .prop_data_value = NULL, + .changed_prop_lst = C_LIST_INIT(db_prop_data->changed_prop_lst), + }; + } + c_list_link_front(&dbobj->iface_lst_head, &db_iface_data->iface_lst); + } else { + /* Intentionally don't initialize the other fields. We are not supposed + * to touch them, and a valgrind warning would be preferable. */ + db_iface_data->dbus_iface.name = nm_ref_string_new(dbus_iface_name); + db_iface_data->dbus_iface_is_wellknown = FALSE; + db_iface_data->iface_removed = FALSE; + c_list_link_tail(&dbobj->iface_lst_head, &db_iface_data->iface_lst); + } + + return db_iface_data; +} + +static void +nml_dbus_obj_iface_data_destroy(NMLDBusObjIfaceData *db_iface_data) +{ + guint i; + + nm_assert(db_iface_data); + nm_assert(c_list_is_empty(&db_iface_data->iface_lst)); + + if (db_iface_data->dbus_iface_is_wellknown) { + for (i = 0; i < db_iface_data->dbus_iface.meta->n_dbus_properties; i++) + nm_g_variant_unref(db_iface_data->prop_datas[i].prop_data_value); + } else + nm_ref_string_unref(db_iface_data->dbus_iface.name); + + g_free(db_iface_data); +} + +gpointer +nml_dbus_object_get_property_location(NMLDBusObject * dbobj, + const NMLDBusMetaIface * meta_iface, + const NMLDBusMetaProperty *meta_property) +{ + char *target_c; + + target_c = (char *) dbobj->nmobj; + if (meta_iface->base_struct_offset > 0) + target_c = *((gpointer *) (&target_c[meta_iface->base_struct_offset])); + return &target_c[meta_property->prop_struct_offset]; +} + +static void +nml_dbus_object_set_obj_state(NMLDBusObject *dbobj, NMLDBusObjState obj_state, NMClient *self) +{ + NMClientPrivate *priv; + + nm_assert(NM_IS_CLIENT(self)); + nm_assert(NML_IS_DBUS_OBJECT(dbobj)); + +#if NM_MORE_ASSERTS > 10 + priv = NM_CLIENT_GET_PRIVATE(self); + switch (dbobj->obj_state) { + case NML_DBUS_OBJ_STATE_UNLINKED: + nm_assert(c_list_is_empty(&dbobj->dbus_objects_lst)); + break; + case NML_DBUS_OBJ_STATE_WATCHED_ONLY: + nm_assert( + c_list_contains(&priv->dbus_objects_lst_head_watched_only, &dbobj->dbus_objects_lst)); + break; + case NML_DBUS_OBJ_STATE_ON_DBUS: + nm_assert(c_list_contains(&priv->dbus_objects_lst_head_on_dbus, &dbobj->dbus_objects_lst)); + break; + case NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY: + nm_assert(c_list_contains(&priv->dbus_objects_lst_head_with_nmobj_not_ready, + &dbobj->dbus_objects_lst)); + break; + case NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY: + nm_assert(c_list_contains(&priv->dbus_objects_lst_head_with_nmobj_ready, + &dbobj->dbus_objects_lst)); + break; + } +#endif + + if (dbobj->obj_state == obj_state) + return; + + NML_NMCLIENT_LOG_T(self, + "[%s]: set D-Bus object state %s", + dbobj->dbus_path->str, + nml_dbus_obj_state_to_string(obj_state)); + + priv = NM_CLIENT_GET_PRIVATE(self); + dbobj->obj_state = obj_state; + switch (obj_state) { + case NML_DBUS_OBJ_STATE_UNLINKED: + c_list_unlink(&dbobj->dbus_objects_lst); + c_list_unlink(&dbobj->obj_changed_lst); + dbobj->obj_changed_type = NML_DBUS_OBJ_CHANGED_TYPE_NONE; + break; + case NML_DBUS_OBJ_STATE_WATCHED_ONLY: + nm_c_list_move_tail(&priv->dbus_objects_lst_head_watched_only, &dbobj->dbus_objects_lst); + break; + case NML_DBUS_OBJ_STATE_ON_DBUS: + nm_c_list_move_tail(&priv->dbus_objects_lst_head_on_dbus, &dbobj->dbus_objects_lst); + break; + case NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY: + nm_c_list_move_tail(&priv->dbus_objects_lst_head_with_nmobj_not_ready, + &dbobj->dbus_objects_lst); + break; + case NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY: + nm_c_list_move_tail(&priv->dbus_objects_lst_head_with_nmobj_ready, + &dbobj->dbus_objects_lst); + break; + default: + nm_assert_not_reached(); + } +} + +/*****************************************************************************/ + +static void +nml_dbus_object_obj_changed_link(NMClient * self, + NMLDBusObject * dbobj, + NMLDBusObjChangedType changed_type) +{ + nm_assert(NM_IS_CLIENT(self)); + nm_assert(NML_IS_DBUS_OBJECT(dbobj)); + nm_assert(changed_type != NML_DBUS_OBJ_CHANGED_TYPE_NONE); + + if (!NM_FLAGS_ALL((NMLDBusObjChangedType) dbobj->obj_changed_type, changed_type)) + NML_NMCLIENT_LOG_T(self, + "[%s]: changed-type 0x%02x linked", + dbobj->dbus_path->str, + (guint) changed_type); + + if (dbobj->obj_changed_type == NML_DBUS_OBJ_CHANGED_TYPE_NONE) { + NMClientPrivate *priv; + + /* We set the changed-type flag. Need to queue the object in the + * changed list. */ + nm_assert(c_list_is_empty(&dbobj->obj_changed_lst)); + priv = NM_CLIENT_GET_PRIVATE(self); + c_list_link_tail(&priv->obj_changed_lst_head, &dbobj->obj_changed_lst); + } else { + /* The object has changes flags and must be linked already. Note that + * this may be priv->obj_changed_lst_head, or a temporary list on the + * stack. + * + * This dance with the temporary list is done to ensure we can enqueue + * objects while we process the changes. */ + nm_assert(!c_list_is_empty(&dbobj->obj_changed_lst)); + } + + dbobj->obj_changed_type |= changed_type; + + nm_assert(NM_FLAGS_ALL(dbobj->obj_changed_type, changed_type)); +} + +static NMLDBusObjChangedType +nml_dbus_object_obj_changed_consume(NMClient * self, + NMLDBusObject * dbobj, + NMLDBusObjChangedType changed_type) +{ + NMClientPrivate * priv; + NMLDBusObjChangedType changed_type_res; + + nm_assert(NM_IS_CLIENT(self)); + nm_assert(NML_IS_DBUS_OBJECT(dbobj)); + nm_assert(changed_type != NML_DBUS_OBJ_CHANGED_TYPE_NONE); + nm_assert(dbobj->obj_changed_type != NML_DBUS_OBJ_CHANGED_TYPE_NONE); + nm_assert(!c_list_is_empty(&dbobj->obj_changed_lst)); + + changed_type_res = dbobj->obj_changed_type & changed_type; + + dbobj->obj_changed_type &= ~changed_type; + + if (dbobj->obj_changed_type == NML_DBUS_OBJ_CHANGED_TYPE_NONE) { + c_list_unlink(&dbobj->obj_changed_lst); + nm_assert(changed_type_res != NML_DBUS_OBJ_CHANGED_TYPE_NONE); + NML_NMCLIENT_LOG_T(self, + "[%s]: changed-type 0x%02x consumed", + dbobj->dbus_path->str, + (guint) changed_type_res); + return changed_type_res; + } + + priv = NM_CLIENT_GET_PRIVATE(self); + + nm_assert(!c_list_contains(&priv->obj_changed_lst_head, &dbobj->obj_changed_lst)); + nm_c_list_move_tail(&priv->obj_changed_lst_head, &dbobj->obj_changed_lst); + NML_NMCLIENT_LOG_T(self, + "[%s]: changed-type 0x%02x consumed (still has 0x%02x)", + dbobj->dbus_path->str, + (guint) changed_type_res, + (guint) dbobj->obj_changed_type); + return changed_type_res; +} + +static gboolean +nml_dbus_object_obj_changed_any_linked(NMClient *self, NMLDBusObjChangedType changed_type) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + NMLDBusObject * dbobj; + + nm_assert(changed_type != NML_DBUS_OBJ_CHANGED_TYPE_NONE); + + c_list_for_each_entry (dbobj, &priv->obj_changed_lst_head, obj_changed_lst) { + nm_assert(dbobj->obj_changed_type != NML_DBUS_OBJ_CHANGED_TYPE_NONE); + if (NM_FLAGS_ANY(dbobj->obj_changed_type, changed_type)) + return TRUE; + } + return FALSE; +} + +/*****************************************************************************/ + +static void +_dbobjs_notify_watchers_for_dbobj(NMClient *self, NMLDBusObject *dbobj) +{ + NMLDBusObjWatcher *obj_watcher; + NMLDBusObjWatcher *obj_watcher_safe; + + c_list_for_each_entry_safe (obj_watcher, + obj_watcher_safe, + &dbobj->watcher_lst_head, + _priv.watcher_lst) + obj_watcher->_priv.notify_fcn(self, obj_watcher); +} + +static gboolean +_dbobjs_check_dbobj_ready(NMClient *self, NMLDBusObject *dbobj) +{ + nm_assert(NM_IS_CLIENT(self)); + nm_assert(NML_IS_DBUS_OBJECT(dbobj)); + nm_assert(G_IS_OBJECT(dbobj->nmobj)); + nm_assert(NM_IS_OBJECT(dbobj->nmobj) || NM_IS_CLIENT(dbobj->nmobj)); + nm_assert(NM_IN_SET((NMLDBusObjState) dbobj->obj_state, + NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY, + NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY)); + + if (G_LIKELY(dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY)) + return TRUE; + + if (!NM_OBJECT_GET_CLASS(dbobj->nmobj)->is_ready(NM_OBJECT(dbobj->nmobj))) + return FALSE; + + nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY, self); + + nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ); + _dbobjs_notify_watchers_for_dbobj(self, dbobj); + + return TRUE; +} + +void +_nm_client_notify_object_changed(NMClient *self, NMLDBusObject *dbobj) +{ + nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ); + _dbobjs_notify_watchers_for_dbobj(self, dbobj); +} + +/*****************************************************************************/ + +static NMLDBusObject * +_dbobjs_dbobj_get_r(NMClient *self, NMRefString *dbus_path_r) +{ + nm_assert(NM_IS_REF_STRING(dbus_path_r)); + + return g_hash_table_lookup(NM_CLIENT_GET_PRIVATE(self)->dbus_objects, &dbus_path_r); +} + +static NMLDBusObject * +_dbobjs_dbobj_get_s(NMClient *self, const char *dbus_path) +{ + nm_auto_ref_string NMRefString *dbus_path_r = NULL; + + nm_assert(dbus_path); + dbus_path_r = nm_ref_string_new(dbus_path); + return _dbobjs_dbobj_get_r(self, dbus_path_r); +} + +static NMLDBusObject * +_dbobjs_dbobj_create(NMClient *self, NMRefString *dbus_path_take) +{ + nm_auto_ref_string NMRefString *dbus_path = g_steal_pointer(&dbus_path_take); + NMClientPrivate * priv = NM_CLIENT_GET_PRIVATE(self); + NMLDBusObject * dbobj; + + nm_assert(!_dbobjs_dbobj_get_r(self, dbus_path)); + + dbobj = nml_dbus_object_new(g_steal_pointer(&dbus_path)); + if (!g_hash_table_add(priv->dbus_objects, dbobj)) + nm_assert_not_reached(); + return dbobj; +} + +static NMLDBusObject * +_dbobjs_dbobj_get_or_create(NMClient *self, NMRefString *dbus_path_take) +{ + nm_auto_ref_string NMRefString *dbus_path = g_steal_pointer(&dbus_path_take); + NMLDBusObject * dbobj; + + dbobj = _dbobjs_dbobj_get_r(self, dbus_path); + if (dbobj) + return dbobj; + return _dbobjs_dbobj_create(self, g_steal_pointer(&dbus_path)); +} + +static NMLDBusObject * +_dbobjs_get_nmobj(NMClient *self, const char *dbus_path, GType gtype) +{ + NMLDBusObject *dbobj; + + nm_assert(gtype == G_TYPE_NONE || g_type_is_a(gtype, NM_TYPE_OBJECT)); + + dbobj = _dbobjs_dbobj_get_s(self, dbus_path); + + if (!dbobj) + return NULL; + if (!dbobj->nmobj) + return NULL; + + if (gtype != G_TYPE_NONE && !g_type_is_a(G_OBJECT_TYPE(dbobj->nmobj), gtype)) + return NULL; + + return dbobj; +} + +static gpointer +_dbobjs_get_nmobj_unpack_visible(NMClient *self, const char *dbus_path, GType gtype) +{ + NMLDBusObject *dbobj; + + dbobj = _dbobjs_get_nmobj(self, dbus_path, gtype); + if (!dbobj) + return NULL; + if (dbobj->obj_state != NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY) + return NULL; + return dbobj->nmobj; +} + +/*****************************************************************************/ + +static gpointer +_dbobjs_obj_watcher_register_o(NMClient * self, + NMLDBusObject * dbobj, + NMLDBusObjWatchNotifyFcn notify_fcn, + gsize struct_size) +{ + NMLDBusObjWatcher *obj_watcher; + + nm_assert(NM_IS_CLIENT(self)); + _ASSERT_dbobj(dbobj, self); + nm_assert(notify_fcn); + nm_assert(struct_size > sizeof(NMLDBusObjWatcher)); + + obj_watcher = g_malloc(struct_size); + obj_watcher->dbobj = dbobj; + obj_watcher->_priv.notify_fcn = notify_fcn; + + /* we must enqueue the item in the front of the list. That is, because while + * invoking notify_fcn(), we iterate the watchers front-to-end. As we want to + * allow the callee to register new watches and unregister itself, this is + * the right way to do it. */ + c_list_link_front(&dbobj->watcher_lst_head, &obj_watcher->_priv.watcher_lst); + + return obj_watcher; +} + +static gpointer +_dbobjs_obj_watcher_register_r(NMClient * self, + NMRefString * dbus_path_take, + NMLDBusObjWatchNotifyFcn notify_fcn, + gsize struct_size) +{ + nm_auto_ref_string NMRefString *dbus_path = g_steal_pointer(&dbus_path_take); + NMLDBusObject * dbobj; + + nm_assert(NM_IS_CLIENT(self)); + nm_assert(notify_fcn); + + dbobj = _dbobjs_dbobj_get_or_create(self, g_steal_pointer(&dbus_path)); + if (dbobj->obj_state == NML_DBUS_OBJ_STATE_UNLINKED) + nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_WATCHED_ONLY, self); + return _dbobjs_obj_watcher_register_o(self, dbobj, notify_fcn, struct_size); +} + +static void +_dbobjs_obj_watcher_unregister(NMClient *self, gpointer obj_watcher_base) +{ + NMLDBusObjWatcher *obj_watcher = obj_watcher_base; + NMLDBusObject * dbobj; + + nm_assert(NM_IS_CLIENT(self)); + nm_assert(obj_watcher); + nm_assert(NML_IS_DBUS_OBJECT(obj_watcher->dbobj)); + nm_assert(g_hash_table_lookup(NM_CLIENT_GET_PRIVATE(self)->dbus_objects, obj_watcher->dbobj) + == obj_watcher->dbobj); + nm_assert( + c_list_contains(&obj_watcher->dbobj->watcher_lst_head, &obj_watcher->_priv.watcher_lst)); + + c_list_unlink(&obj_watcher->_priv.watcher_lst); + + dbobj = obj_watcher->dbobj; + + g_free(obj_watcher); + + if (c_list_is_empty(&dbobj->iface_lst_head) && c_list_is_empty(&dbobj->watcher_lst_head)) { + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + NML_NMCLIENT_LOG_T(self, "[%s]: drop D-Bus watcher", dbobj->dbus_path->str); + nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_UNLINKED, self); + if (!g_hash_table_steal(priv->dbus_objects, dbobj)) + nm_assert_not_reached(); + nml_dbus_object_unref(dbobj); + } +} + +/*****************************************************************************/ + +typedef struct { + NMLDBusObjWatcher parent; + NMLDBusPropertyO *pr_o; +} PropertyOData; + +gpointer +nml_dbus_property_o_get_obj(NMLDBusPropertyO *pr_o) +{ + nm_assert(!pr_o->nmobj || nml_dbus_property_o_is_ready(pr_o)); + return pr_o->nmobj; +} + +gboolean +nml_dbus_property_o_is_ready(const NMLDBusPropertyO *pr_o) +{ + return pr_o->is_ready || !pr_o->owner_dbobj; +} + +gboolean +nml_dbus_property_o_is_ready_fully(const NMLDBusPropertyO *pr_o) +{ + return !pr_o->owner_dbobj || !pr_o->obj_watcher || pr_o->nmobj; +} + +static void +nml_dbus_property_o_notify_changed(NMLDBusPropertyO *pr_o, NMClient *self) +{ + const NMLDBusPropertVTableO *vtable; + GObject * nmobj = NULL; + gboolean is_ready = TRUE; + gboolean changed_ready; + GType gtype; + + nm_assert(pr_o); + nm_assert(NM_IS_CLIENT(self)); + + if (!pr_o->owner_dbobj) + return; + + if (!pr_o->is_changed) { + if (pr_o->is_ready) + return; + goto done; + } + + pr_o->is_changed = FALSE; + + if (!pr_o->obj_watcher) + goto done; + + if (!pr_o->obj_watcher->dbobj->nmobj) { + if (pr_o->obj_watcher->dbobj->obj_state >= NML_DBUS_OBJ_STATE_ON_DBUS) { + NML_NMCLIENT_LOG_W( + self, + "[%s]: property %s references %s but object is not created", + pr_o->owner_dbobj->dbus_path->str, + pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].dbus_property_name, + pr_o->obj_watcher->dbobj->dbus_path->str); + } else { + NML_NMCLIENT_LOG_E( + self, + "[%s]: property %s references %s but object is not present on D-Bus", + pr_o->owner_dbobj->dbus_path->str, + pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].dbus_property_name, + pr_o->obj_watcher->dbobj->dbus_path->str); + } + goto done; + } + + vtable = pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].extra.property_vtable_o; + + gtype = vtable->get_o_type_fcn(); + if (!g_type_is_a(G_OBJECT_TYPE(pr_o->obj_watcher->dbobj->nmobj), gtype)) { + NML_NMCLIENT_LOG_E( + self, + "[%s]: property %s references %s with unexpected GObject type %s instead of %s", + pr_o->owner_dbobj->dbus_path->str, + pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].dbus_property_name, + pr_o->obj_watcher->dbobj->dbus_path->str, + G_OBJECT_TYPE_NAME(pr_o->obj_watcher->dbobj->nmobj), + g_type_name(gtype)); + goto done; + } + + if (pr_o->obj_watcher->dbobj == pr_o->owner_dbobj) { + NML_NMCLIENT_LOG_W( + self, + "[%s]: property %s references itself", + pr_o->owner_dbobj->dbus_path->str, + pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].dbus_property_name); + nmobj = pr_o->owner_dbobj->nmobj; + goto done; + } + + pr_o->block_is_changed = TRUE; + is_ready = _dbobjs_check_dbobj_ready(self, pr_o->obj_watcher->dbobj); + pr_o->block_is_changed = FALSE; + + if (!is_ready) { + is_ready = vtable->is_always_ready; + goto done; + } + + nmobj = pr_o->obj_watcher->dbobj->nmobj; + +done: + changed_ready = FALSE; + if (!pr_o->is_ready && is_ready) { + pr_o->is_ready = TRUE; + changed_ready = TRUE; + } + if (pr_o->nmobj != nmobj) { + pr_o->nmobj = nmobj; + _nm_client_queue_notify_object( + self, + pr_o->owner_dbobj->nmobj, + pr_o->meta_iface->obj_properties + [pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].obj_properties_idx]); + } + if (changed_ready && pr_o->owner_dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY) + nml_dbus_object_obj_changed_link(self, pr_o->owner_dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ); +} + +void +nml_dbus_property_o_notify_changed_many(NMLDBusPropertyO *ptr, guint len, NMClient *self) +{ + while (len-- > 0) + nml_dbus_property_o_notify_changed(ptr++, self); +} + +static void +nml_dbus_property_o_notify_watch_cb(NMClient *self, gpointer obj_watcher) +{ + PropertyOData * pr_o_data = obj_watcher; + NMLDBusPropertyO *pr_o = pr_o_data->pr_o; + + nm_assert(pr_o->obj_watcher == obj_watcher); + + if (!pr_o->block_is_changed && !pr_o->is_changed) { + pr_o->is_changed = TRUE; + nml_dbus_object_obj_changed_link(self, pr_o->owner_dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ); + } +} + +static NMLDBusNotifyUpdatePropFlags +nml_dbus_property_o_notify(NMClient * self, + NMLDBusPropertyO * pr_o, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + const char *dbus_path = NULL; + gboolean changed = FALSE; + + if (!pr_o->owner_dbobj) { + nm_assert(!pr_o->meta_iface); + nm_assert(pr_o->dbus_property_idx == 0); + nm_assert(!pr_o->is_ready); + pr_o->owner_dbobj = dbobj; + pr_o->meta_iface = meta_iface; + pr_o->dbus_property_idx = dbus_property_idx; + } else { + nm_assert(pr_o->owner_dbobj == dbobj); + nm_assert(pr_o->meta_iface == meta_iface); + nm_assert(pr_o->dbus_property_idx == dbus_property_idx); + } + + if (value) + dbus_path = nm_dbus_path_not_empty(g_variant_get_string(value, NULL)); + + if (pr_o->obj_watcher + && (!dbus_path || !nm_streq(dbus_path, pr_o->obj_watcher->dbobj->dbus_path->str))) { + _dbobjs_obj_watcher_unregister(self, g_steal_pointer(&pr_o->obj_watcher)); + changed = TRUE; + } + if (!pr_o->obj_watcher && dbus_path) { + pr_o->obj_watcher = _dbobjs_obj_watcher_register_r(self, + nm_ref_string_new(dbus_path), + nml_dbus_property_o_notify_watch_cb, + sizeof(PropertyOData)); + ((PropertyOData *) pr_o->obj_watcher)->pr_o = pr_o; + changed = TRUE; + } + + if (changed && !pr_o->is_changed) { + pr_o->is_changed = TRUE; + nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ); + } + + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; +} + +void +nml_dbus_property_o_clear(NMLDBusPropertyO *pr_o, NMClient *self) +{ + if (pr_o->obj_watcher) { + nm_assert(NM_IS_CLIENT(self)); + _dbobjs_obj_watcher_unregister(self, g_steal_pointer(&pr_o->obj_watcher)); + } + if (pr_o->nmobj && pr_o->owner_dbobj && pr_o->owner_dbobj->nmobj) { + _nm_client_queue_notify_object( + self, + pr_o->owner_dbobj->nmobj, + pr_o->meta_iface->obj_properties + [pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].obj_properties_idx]); + } + pr_o->owner_dbobj = NULL; + pr_o->meta_iface = NULL; + pr_o->dbus_property_idx = 0; + pr_o->is_ready = FALSE; +} + +void +nml_dbus_property_o_clear_many(NMLDBusPropertyO *pr_o, guint len, NMClient *self) +{ + while (len-- > 0) + nml_dbus_property_o_clear(pr_o++, self); +} + +/*****************************************************************************/ + +typedef struct _NMLDBusPropertyAOData { + NMLDBusObjWatcher obj_watcher; + NMLDBusPropertyAO * parent; + CList data_lst; + GObject * nmobj; + struct _NMLDBusPropertyAOData *changed_next; + bool is_ready : 1; + bool is_notified : 1; + bool is_changed : 1; + bool block_is_changed : 1; +} PropertyAOData; + +static void +_ASSERT_pr_ao(NMLDBusPropertyAO *pr_ao) +{ + nm_assert(pr_ao); + +#if NM_MORE_ASSERTS > 10 + if (pr_ao->owner_dbobj) { + guint n_not_ready = 0; + guint n_is_changed = 0; + guint n_is_changed_2; + PropertyAOData *pr_ao_data; + + c_list_for_each_entry (pr_ao_data, &pr_ao->data_lst_head, data_lst) { + if (pr_ao_data->is_changed) + n_is_changed++; + if (!pr_ao_data->is_ready) + n_not_ready++; + } + nm_assert(n_not_ready == pr_ao->n_not_ready); + + n_is_changed_2 = 0; + pr_ao_data = pr_ao->changed_head; + while (pr_ao_data) { + nm_assert(pr_ao_data->is_changed); + n_is_changed_2++; + pr_ao_data = pr_ao_data->changed_next; + } + nm_assert(n_is_changed == n_is_changed_2); + } +#endif +} + +static gboolean +nml_dbus_property_ao_notify_changed_ao(PropertyAOData *pr_ao_data, + NMClient * self, + gboolean is_added /* or else removed */) +{ + NMLDBusPropertyAO * pr_ao; + const NMLDBusPropertVTableAO *vtable; + + if (!pr_ao_data->nmobj) + return FALSE; + + nm_assert(pr_ao_data->is_ready); + + if (is_added) { + if (pr_ao_data->is_notified) + return FALSE; + pr_ao_data->is_notified = TRUE; + } else { + if (!pr_ao_data->is_notified) + return FALSE; + pr_ao_data->is_notified = FALSE; + } + + pr_ao = pr_ao_data->parent; + + vtable = pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].extra.property_vtable_ao; + + if (vtable->notify_changed_ao) + vtable->notify_changed_ao(pr_ao, self, NM_OBJECT(pr_ao_data->nmobj), is_added); + return TRUE; +} + +const GPtrArray * +nml_dbus_property_ao_get_objs_as_ptrarray(NMLDBusPropertyAO *pr_ao) +{ + if (!pr_ao->arr) { + PropertyAOData *pr_ao_data; + gsize n; + + n = 0; + if (pr_ao->owner_dbobj) { + c_list_for_each_entry (pr_ao_data, &pr_ao->data_lst_head, data_lst) { + if (pr_ao_data->nmobj) + n++; + } + } + + pr_ao->arr = g_ptr_array_new_full(n, g_object_unref); + if (pr_ao->owner_dbobj) { + c_list_for_each_entry (pr_ao_data, &pr_ao->data_lst_head, data_lst) { + if (pr_ao_data->nmobj) + g_ptr_array_add(pr_ao->arr, g_object_ref(pr_ao_data->nmobj)); + } + } + } + return pr_ao->arr; +} + +gboolean +nml_dbus_property_ao_is_ready(const NMLDBusPropertyAO *pr_ao) +{ + return pr_ao->n_not_ready == 0; +} + +static void +nml_dbus_property_ao_notify_changed(NMLDBusPropertyAO *pr_ao, NMClient *self) +{ + gboolean changed_prop = FALSE; + gboolean changed_ready = FALSE; + PropertyAOData *pr_ao_data; + + nm_assert(NM_IS_CLIENT(self)); + _ASSERT_pr_ao(pr_ao); + + if (!pr_ao->owner_dbobj) + return; + + if (!pr_ao->is_changed) { + if (pr_ao->n_not_ready == 0) + return; + goto done; + } + + pr_ao->is_changed = FALSE; + + while (pr_ao->changed_head) { + const NMLDBusPropertVTableAO *vtable; + GObject * nmobj = NULL; + gboolean is_ready = TRUE; + GType gtype; + + pr_ao_data = g_steal_pointer(&pr_ao->changed_head); + nm_assert(pr_ao_data->is_changed); + + pr_ao->changed_head = pr_ao_data->changed_next; + pr_ao_data->is_changed = FALSE; + + if (!pr_ao_data->obj_watcher.dbobj->nmobj) { + if (pr_ao_data->obj_watcher.dbobj->obj_state >= NML_DBUS_OBJ_STATE_ON_DBUS) { + NML_NMCLIENT_LOG_W( + self, + "[%s]: property %s references %s but object is not created", + pr_ao->owner_dbobj->dbus_path->str, + pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].dbus_property_name, + pr_ao_data->obj_watcher.dbobj->dbus_path->str); + } else { + NML_NMCLIENT_LOG_E( + self, + "[%s]: property %s references %s but object is not present on D-Bus", + pr_ao->owner_dbobj->dbus_path->str, + pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].dbus_property_name, + pr_ao_data->obj_watcher.dbobj->dbus_path->str); + } + goto done_pr_ao_data; + } + + vtable = + pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].extra.property_vtable_ao; + + gtype = vtable->get_o_type_fcn(); + if (!g_type_is_a(G_OBJECT_TYPE(pr_ao_data->obj_watcher.dbobj->nmobj), gtype)) { + NML_NMCLIENT_LOG_E( + self, + "[%s]: property %s references %s with unexpected GObject type %s instead of %s", + pr_ao->owner_dbobj->dbus_path->str, + pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].dbus_property_name, + pr_ao_data->obj_watcher.dbobj->dbus_path->str, + G_OBJECT_TYPE_NAME(pr_ao_data->obj_watcher.dbobj->nmobj), + g_type_name(gtype)); + goto done_pr_ao_data; + } + + if (pr_ao_data->obj_watcher.dbobj == pr_ao->owner_dbobj) { + NML_NMCLIENT_LOG_W( + self, + "[%s]: property %s references itself", + pr_ao->owner_dbobj->dbus_path->str, + pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].dbus_property_name); + nmobj = pr_ao->owner_dbobj->nmobj; + goto done_pr_ao_data; + } + + pr_ao_data->block_is_changed = TRUE; + is_ready = _dbobjs_check_dbobj_ready(self, pr_ao_data->obj_watcher.dbobj); + pr_ao_data->block_is_changed = FALSE; + + if (!is_ready) { + is_ready = vtable->is_always_ready; + goto done_pr_ao_data; + } + + if (vtable->check_nmobj_visible_fcn + && !vtable->check_nmobj_visible_fcn(pr_ao_data->obj_watcher.dbobj->nmobj)) { + is_ready = TRUE; + goto done_pr_ao_data; + } + + nmobj = pr_ao_data->obj_watcher.dbobj->nmobj; + +done_pr_ao_data: + + if (!pr_ao_data->is_ready && is_ready) { + nm_assert(pr_ao->n_not_ready > 0); + pr_ao->n_not_ready--; + pr_ao_data->is_ready = TRUE; + changed_ready = TRUE; + } + + if (pr_ao_data->nmobj != nmobj) { + if (nml_dbus_property_ao_notify_changed_ao(pr_ao_data, self, FALSE)) + changed_prop = TRUE; + pr_ao_data->nmobj = nmobj; + } + + if (!pr_ao_data->is_notified) { + if (nml_dbus_property_ao_notify_changed_ao(pr_ao_data, self, TRUE)) + changed_prop = TRUE; + } + } + + _ASSERT_pr_ao(pr_ao); + +done: + if (changed_prop) { + nm_clear_pointer(&pr_ao->arr, g_ptr_array_unref); + _nm_client_queue_notify_object( + self, + pr_ao->owner_dbobj->nmobj, + pr_ao->meta_iface->obj_properties + [pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].obj_properties_idx]); + } + if (changed_ready && pr_ao->n_not_ready == 0 + && pr_ao->owner_dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY) + nml_dbus_object_obj_changed_link(self, pr_ao->owner_dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ); +} + +void +nml_dbus_property_ao_notify_changed_many(NMLDBusPropertyAO *ptr, guint len, NMClient *self) +{ + while (len-- > 0) + nml_dbus_property_ao_notify_changed(ptr++, self); +} + +static void +nml_dbus_property_ao_notify_watch_cb(NMClient *self, gpointer obj_watcher) +{ + PropertyAOData * pr_ao_data = obj_watcher; + NMLDBusPropertyAO *pr_ao = pr_ao_data->parent; + + nm_assert(g_hash_table_lookup(pr_ao->hash, pr_ao_data) == pr_ao_data); + + if (!pr_ao_data->block_is_changed && !pr_ao_data->is_changed) { + pr_ao_data->is_changed = TRUE; + pr_ao_data->changed_next = pr_ao->changed_head; + pr_ao->changed_head = pr_ao_data; + if (!pr_ao->is_changed) { + pr_ao->is_changed = TRUE; + nml_dbus_object_obj_changed_link(self, + pr_ao->owner_dbobj, + NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ); + } + } + + _ASSERT_pr_ao(pr_ao); +} + +static NMLDBusNotifyUpdatePropFlags +nml_dbus_property_ao_notify(NMClient * self, + NMLDBusPropertyAO * pr_ao, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + CList stale_lst_head = C_LIST_INIT(stale_lst_head); + PropertyAOData *pr_ao_data; + gboolean changed_prop = FALSE; + gboolean changed_obj = FALSE; + + if (!pr_ao->owner_dbobj) { + nm_assert(!pr_ao->data_lst_head.next); + nm_assert(!pr_ao->data_lst_head.prev); + nm_assert(!pr_ao->hash); + nm_assert(!pr_ao->meta_iface); + nm_assert(pr_ao->dbus_property_idx == 0); + nm_assert(pr_ao->n_not_ready == 0); + nm_assert(!pr_ao->changed_head); + nm_assert(!pr_ao->is_changed); + + c_list_init(&pr_ao->data_lst_head); + pr_ao->hash = g_hash_table_new(nm_ppdirect_hash, nm_ppdirect_equal); + pr_ao->owner_dbobj = dbobj; + pr_ao->meta_iface = meta_iface; + pr_ao->dbus_property_idx = dbus_property_idx; + } else { + nm_assert(pr_ao->data_lst_head.next); + nm_assert(pr_ao->data_lst_head.prev); + nm_assert(pr_ao->hash); + nm_assert(pr_ao->meta_iface == meta_iface); + nm_assert(pr_ao->dbus_property_idx == dbus_property_idx); + } + + c_list_splice(&stale_lst_head, &pr_ao->data_lst_head); + + if (value) { + GVariantIter iter; + const char * path; + + g_variant_iter_init(&iter, value); + while (g_variant_iter_next(&iter, "&o", &path)) { + nm_auto_ref_string NMRefString *dbus_path_r = NULL; + gpointer p_dbus_path_1; + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(PropertyAOData, obj_watcher) == 0); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMLDBusObjWatcher, dbobj) == 0); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMLDBusObject, dbus_path) == 0); + + if (!nm_dbus_path_not_empty(path)) { + /* should not happen. Anyway, silently skip empty paths. */ + continue; + } + + dbus_path_r = nm_ref_string_new(path); + p_dbus_path_1 = &dbus_path_r; + pr_ao_data = g_hash_table_lookup(pr_ao->hash, &p_dbus_path_1); + + if (pr_ao_data) { + /* With this implementation we cannot track the same path multiple times. + * Of course, for none of the properties where we use this, the server + * should expose the same path more than once, so this limitation is fine + * (maybe even preferable to drop duplicates form NMClient's API). */ + nm_assert(pr_ao_data->obj_watcher.dbobj->dbus_path == dbus_path_r); + if (!changed_prop && pr_ao_data->is_notified) { + /* The order of a notified entry changed. That means, we need to signal + * a change of the property. This detection of a change is not always + * correct, in particular we might detect some changes when there were + * none. That's not a serious problem, and fixing it would be expensive + * to implement. */ + changed_prop = (c_list_first(&stale_lst_head) != &pr_ao_data->data_lst); + } + nm_c_list_move_tail(&pr_ao->data_lst_head, &pr_ao_data->data_lst); + } else { + pr_ao_data = _dbobjs_obj_watcher_register_r(self, + g_steal_pointer(&dbus_path_r), + nml_dbus_property_ao_notify_watch_cb, + sizeof(PropertyAOData)), + pr_ao_data->parent = pr_ao; + pr_ao_data->nmobj = NULL; + pr_ao_data->changed_next = NULL; + pr_ao_data->is_changed = TRUE; + pr_ao_data->block_is_changed = FALSE; + pr_ao_data->is_ready = FALSE; + pr_ao_data->is_notified = FALSE; + c_list_link_tail(&pr_ao->data_lst_head, &pr_ao_data->data_lst); + if (!g_hash_table_add(pr_ao->hash, pr_ao_data)) + nm_assert_not_reached(); + nm_assert(pr_ao->n_not_ready < G_MAXUINT); + pr_ao->n_not_ready++; + } + +#if NM_MORE_ASSERTS > 10 + { + nm_auto_ref_string NMRefString *p = nm_ref_string_new(path); + gpointer pp = &p; + + nm_assert(g_hash_table_lookup(pr_ao->hash, &pp) == pr_ao_data); + } +#endif + } + } + + pr_ao->changed_head = NULL; + c_list_for_each_entry (pr_ao_data, &pr_ao->data_lst_head, data_lst) { + if (pr_ao_data->is_changed) { + pr_ao_data->changed_next = pr_ao->changed_head; + pr_ao->changed_head = pr_ao_data; + changed_obj = TRUE; + } + } + + while ((pr_ao_data = c_list_first_entry(&stale_lst_head, PropertyAOData, data_lst))) { + changed_obj = TRUE; + c_list_unlink(&pr_ao_data->data_lst); + if (!g_hash_table_remove(pr_ao->hash, pr_ao_data)) + nm_assert_not_reached(); + if (!pr_ao_data->is_ready) { + nm_assert(pr_ao->n_not_ready > 0); + pr_ao->n_not_ready--; + } else { + if (nml_dbus_property_ao_notify_changed_ao(pr_ao_data, self, FALSE)) + changed_prop = TRUE; + } + _dbobjs_obj_watcher_unregister(self, pr_ao_data); + } + + _ASSERT_pr_ao(pr_ao); + + if (changed_obj) { + pr_ao->is_changed = TRUE; + nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ); + } + + if (changed_prop) { + nm_clear_pointer(&pr_ao->arr, g_ptr_array_unref); + _nm_client_queue_notify_object( + self, + pr_ao->owner_dbobj->nmobj, + pr_ao->meta_iface->obj_properties + [pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].obj_properties_idx]); + } + + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; +} + +void +nml_dbus_property_ao_clear(NMLDBusPropertyAO *pr_ao, NMClient *self) +{ + _ASSERT_pr_ao(pr_ao); + + if (!pr_ao->owner_dbobj) { + nm_assert(pr_ao->n_not_ready == 0); + nm_assert((!pr_ao->data_lst_head.next && !pr_ao->data_lst_head.prev) + || (pr_ao->data_lst_head.next == pr_ao->data_lst_head.prev)); + nm_assert(!pr_ao->hash); + nm_assert(!pr_ao->meta_iface); + nm_assert(pr_ao->dbus_property_idx == 0); + nm_assert(!pr_ao->is_changed); + } else { + PropertyAOData *pr_ao_data; + gboolean changed_prop = FALSE; + + nm_assert(NM_IS_CLIENT(self)); + nm_assert(pr_ao->data_lst_head.next); + nm_assert(pr_ao->data_lst_head.prev); + nm_assert(pr_ao->hash); + nm_assert(pr_ao->meta_iface); + + while ((pr_ao_data = c_list_first_entry(&pr_ao->data_lst_head, PropertyAOData, data_lst))) { + if (!pr_ao_data->is_ready) { + nm_assert(pr_ao->n_not_ready > 0); + pr_ao->n_not_ready--; + } else { + if (nml_dbus_property_ao_notify_changed_ao(pr_ao_data, self, FALSE)) + changed_prop = TRUE; + } + c_list_unlink(&pr_ao_data->data_lst); + if (!g_hash_table_remove(pr_ao->hash, pr_ao_data)) + nm_assert_not_reached(); + _dbobjs_obj_watcher_unregister(self, pr_ao_data); + } + + nm_assert(c_list_is_empty(&pr_ao->data_lst_head)); + nm_assert(pr_ao->n_not_ready == 0); + nm_assert(g_hash_table_size(pr_ao->hash) == 0); + + if (changed_prop && pr_ao->owner_dbobj->nmobj) { + _nm_client_queue_notify_object( + self, + pr_ao->owner_dbobj->nmobj, + pr_ao->meta_iface + ->obj_properties[pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx] + .obj_properties_idx]); + } + + nm_assert(c_list_is_empty(&pr_ao->data_lst_head)); + nm_assert(pr_ao->n_not_ready == 0); + nm_assert(g_hash_table_size(pr_ao->hash) == 0); + nm_clear_pointer(&pr_ao->hash, g_hash_table_unref); + pr_ao->owner_dbobj = NULL; + pr_ao->meta_iface = NULL; + pr_ao->dbus_property_idx = 0; + pr_ao->data_lst_head.next = NULL; + pr_ao->data_lst_head.prev = NULL; + pr_ao->is_changed = FALSE; + } + + nm_clear_pointer(&pr_ao->arr, g_ptr_array_unref); +} + +void +nml_dbus_property_ao_clear_many(NMLDBusPropertyAO *pr_ao, guint len, NMClient *self) +{ + while (len-- > 0) + nml_dbus_property_ao_clear(pr_ao++, self); +} + +/*****************************************************************************/ + +NMLDBusNotifyUpdatePropFlags +_nml_dbus_notify_update_prop_ignore(NMClient * self, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; +} + +NMLDBusNotifyUpdatePropFlags +_nml_dbus_notify_update_prop_o(NMClient * self, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + const char * path = NULL; + NMRefString **p_property; + + if (value) + path = g_variant_get_string(value, NULL); + + p_property = + nml_dbus_object_get_property_location(dbobj, + meta_iface, + &meta_iface->dbus_properties[dbus_property_idx]); + + if (!nm_streq0(nm_ref_string_get_str(*p_property), path)) { + nm_ref_string_unref(*p_property); + *p_property = nm_ref_string_new(path); + } + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + +/*****************************************************************************/ + +static void +_obj_handle_dbus_prop_changes(NMClient * self, + NMLDBusObject * dbobj, + NMLDBusObjIfaceData *db_iface_data, + guint dbus_property_idx, + GVariant * value) +{ + const NMLDBusMetaIface * meta_iface = db_iface_data->dbus_iface.meta; + const NMLDBusMetaProperty * meta_property = &meta_iface->dbus_properties[dbus_property_idx]; + gpointer p_property; + const char * dbus_type_s; + const GParamSpec * param_spec; + NMLDBusNotifyUpdatePropFlags notify_update_prop_flags; + + nm_assert(G_IS_OBJECT(dbobj->nmobj)); + + if (value && !g_variant_is_of_type(value, meta_property->dbus_type)) { + NML_NMCLIENT_LOG_E(self, + "[%s] property %s.%s expected of type \"%s\" but is \"%s\". Ignore", + dbobj->dbus_path->str, + meta_iface->dbus_iface_name, + meta_property->dbus_property_name, + (const char *) meta_property->dbus_type, + (const char *) g_variant_get_type(value)); + value = NULL; + } + + if (meta_property->use_notify_update_prop) { + notify_update_prop_flags = + meta_property->notify_update_prop(self, dbobj, meta_iface, dbus_property_idx, value); + if (notify_update_prop_flags == NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE) + return; + + nm_assert(notify_update_prop_flags == NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY); + nm_assert(G_IS_OBJECT(dbobj->nmobj)); + nm_assert(meta_iface->obj_properties); + nm_assert(meta_property->obj_properties_idx > 0); + param_spec = meta_iface->obj_properties[meta_property->obj_properties_idx]; + goto notify; + } + + p_property = nml_dbus_object_get_property_location(dbobj, meta_iface, meta_property); + + dbus_type_s = (const char *) meta_property->dbus_type; + + nm_assert(G_IS_OBJECT(dbobj->nmobj)); + nm_assert(meta_iface->obj_properties); + nm_assert(meta_property->obj_properties_idx > 0); + param_spec = meta_iface->obj_properties[meta_property->obj_properties_idx]; + + notify_update_prop_flags = NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; + + switch (dbus_type_s[0]) { + case 'b': + nm_assert(dbus_type_s[1] == '\0'); + if (value) + *((bool *) p_property) = g_variant_get_boolean(value); + else if (param_spec->value_type == G_TYPE_BOOLEAN) + *((bool *) p_property) = ((GParamSpecBoolean *) param_spec)->default_value; + else { + nm_assert_not_reached(); + *((bool *) p_property) = FALSE; + } + break; + case 'y': + nm_assert(dbus_type_s[1] == '\0'); + if (value) + *((guint8 *) p_property) = g_variant_get_byte(value); + else { + nm_assert(nm_utils_g_param_spec_is_default(param_spec)); + *((guint8 *) p_property) = 0; + } + break; + case 'q': + nm_assert(dbus_type_s[1] == '\0'); + if (value) + *((guint16 *) p_property) = g_variant_get_uint16(value); + else { + nm_assert(nm_utils_g_param_spec_is_default(param_spec)); + *((guint16 *) p_property) = 0; + } + break; + case 'i': + nm_assert(dbus_type_s[1] == '\0'); + if (value) + *((gint32 *) p_property) = g_variant_get_int32(value); + else if (param_spec->value_type == G_TYPE_INT) + *((gint32 *) p_property) = ((GParamSpecInt *) param_spec)->default_value; + else { + nm_assert(nm_utils_g_param_spec_is_default(param_spec)); + *((gint32 *) p_property) = 0; + } + break; + case 'u': + nm_assert(dbus_type_s[1] == '\0'); + if (value) + *((guint32 *) p_property) = g_variant_get_uint32(value); + else { + nm_assert(nm_utils_g_param_spec_is_default(param_spec)); + *((guint32 *) p_property) = 0; + } + break; + case 'x': + nm_assert(dbus_type_s[1] == '\0'); + if (value) + *((gint64 *) p_property) = g_variant_get_int64(value); + else if (param_spec->value_type == G_TYPE_INT64) + *((gint64 *) p_property) = ((GParamSpecInt64 *) param_spec)->default_value; + else { + nm_assert(nm_utils_g_param_spec_is_default(param_spec)); + *((gint64 *) p_property) = 0; + } + break; + case 't': + nm_assert(dbus_type_s[1] == '\0'); + if (value) + *((guint64 *) p_property) = g_variant_get_uint64(value); + else { + nm_assert(nm_utils_g_param_spec_is_default(param_spec)); + *((guint64 *) p_property) = 0; + } + break; + case 's': + nm_assert(dbus_type_s[1] == '\0'); + nm_clear_g_free((char **) p_property); + if (value) + *((char **) p_property) = g_variant_dup_string(value, NULL); + else { + nm_assert(nm_utils_g_param_spec_is_default(param_spec)); + *((char **) p_property) = NULL; + } + break; + case 'o': + nm_assert(dbus_type_s[1] == '\0'); + notify_update_prop_flags = nml_dbus_property_o_notify(self, + p_property, + dbobj, + meta_iface, + dbus_property_idx, + value); + break; + case 'a': + switch (dbus_type_s[1]) { + case 'y': + nm_assert(dbus_type_s[2] == '\0'); + { + gconstpointer v; + gsize l; + GBytes * b = NULL; + + if (value) { + v = g_variant_get_fixed_array(value, &l, 1); + + if (l > 0) { + /* empty arrays are coerced to NULL. */ + b = g_bytes_new(v, l); + } + } + + nm_clear_pointer((GBytes **) p_property, g_bytes_unref); + *((GBytes **) p_property) = b; + } + break; + case 's': + nm_assert(dbus_type_s[2] == '\0'); + nm_assert(param_spec->value_type == G_TYPE_STRV); + + g_strfreev(*((char ***) p_property)); + if (value) + *((char ***) p_property) = g_variant_dup_strv(value, NULL); + else + *((char ***) p_property) = NULL; + break; + case 'o': + nm_assert(dbus_type_s[2] == '\0'); + notify_update_prop_flags = nml_dbus_property_ao_notify(self, + p_property, + dbobj, + meta_iface, + dbus_property_idx, + value); + break; + default: + nm_assert_not_reached(); + } + break; + default: + nm_assert_not_reached(); + } + +notify: + if (NM_FLAGS_HAS(notify_update_prop_flags, NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY)) + g_object_notify_by_pspec(dbobj->nmobj, (GParamSpec *) param_spec); +} + +static void +_obj_handle_dbus_iface_changes(NMClient * self, + NMLDBusObject * dbobj, + NMLDBusObjIfaceData *db_iface_data) +{ + NMLDBusObjPropData *db_prop_data; + gboolean is_self = (G_OBJECT(self) == dbobj->nmobj); + gboolean is_removed; + gboolean type_compatible; + guint8 i_prop; + + nm_assert(NM_IS_CLIENT(self)); + nm_assert(is_self || NM_IS_OBJECT(dbobj->nmobj)); + + if (G_UNLIKELY(!db_iface_data->nmobj_checked)) { + db_iface_data->nmobj_checked = TRUE; + type_compatible = db_iface_data->dbus_iface.meta->get_type_fcn + && g_type_is_a(G_OBJECT_TYPE(dbobj->nmobj), + db_iface_data->dbus_iface.meta->get_type_fcn()); + db_iface_data->nmobj_compatible = type_compatible; + } else + type_compatible = db_iface_data->nmobj_compatible; + + if (!type_compatible) { + /* on D-Bus, we have this interface associate with the object, but apparently + * it is not compatible. This is either a bug, or NetworkManager exposed an + * unexpected interface on D-Bus object for which we create a certain NMObject + * type. */ + return; + } + + is_removed = c_list_is_empty(&db_iface_data->iface_lst); + + nm_assert(is_removed || !c_list_is_empty(&db_iface_data->changed_prop_lst_head)); + + _nm_client_queue_notify_object(self, dbobj->nmobj, NULL); + + if (is_removed) { + for (i_prop = 0; i_prop < db_iface_data->dbus_iface.meta->n_dbus_properties; i_prop++) { + _obj_handle_dbus_prop_changes(self, dbobj, db_iface_data, i_prop, NULL); + } + } else { + while ((db_prop_data = c_list_first_entry(&db_iface_data->changed_prop_lst_head, + NMLDBusObjPropData, + changed_prop_lst))) { + gs_unref_variant GVariant *prop_data_value = NULL; + + c_list_unlink(&db_prop_data->changed_prop_lst); + + nm_assert(db_prop_data >= db_iface_data->prop_datas); + nm_assert( + db_prop_data + < &db_iface_data->prop_datas[db_iface_data->dbus_iface.meta->n_dbus_properties]); + nm_assert(db_prop_data->prop_data_value); + + /* Currently, NMLDBusObject forgets about the variant. Theoretically, it could cache + * it, but there is no need because we update the property in nmobj (which extracts and + * keeps the property value itself). + * + * Note that we only consume the variant here when we process it. + * That implies that we already created a NMObject for the dbobj + * instance. Unless that happens, we cache the last seen property values. */ + prop_data_value = g_steal_pointer(&db_prop_data->prop_data_value); + + i_prop = (db_prop_data - &db_iface_data->prop_datas[0]); + _obj_handle_dbus_prop_changes(self, dbobj, db_iface_data, i_prop, prop_data_value); + } + } +} + +static void +_obj_handle_dbus_changes(NMClient *self, NMLDBusObject *dbobj) +{ + NMClientPrivate * priv = NM_CLIENT_GET_PRIVATE(self); + NMLDBusObjIfaceData *db_iface_data; + NMLDBusObjIfaceData *db_iface_data_safe; + gs_unref_object GObject *nmobj_unregistering = NULL; + + _ASSERT_dbobj(dbobj, self); + + /* In a first step we only remember all the changes that a D-Bus message brings + * and queue the object to process them. + * + * Here (in step 2) we look at what changed on D-Bus and propagate those changes + * to the NMObject instance. + * + * Note that here we still must not emit any GObject signals. That follows later, + * and again if the object changes, we will just queue that we handle the changes + * later. */ + + c_list_for_each_entry_safe (db_iface_data, + db_iface_data_safe, + &dbobj->iface_lst_head, + iface_lst) { + if (!db_iface_data->iface_removed) + continue; + c_list_unlink(&db_iface_data->iface_lst); + if (db_iface_data->dbus_iface_is_wellknown && dbobj->nmobj) + _obj_handle_dbus_iface_changes(self, dbobj, db_iface_data); + nml_dbus_obj_iface_data_destroy(db_iface_data); + } + + if (G_UNLIKELY(!dbobj->nmobj) && !c_list_is_empty(&dbobj->iface_lst_head)) { + /* Try to create a NMObject for this D-Bus object. Note that we detect the type + * based on the interfaces that it has, and if we make a choice once, we don't + * change. That means, one D-Bus object can only be of one type. */ + + if (NM_IN_SET(dbobj->dbus_path, + _dbus_path_nm, + _dbus_path_settings, + _dbus_path_dns_manager)) { + /* For the main types, we don't detect them based on the interfaces present, + * but on the path names. Of course, both should correspond anyway. */ + NML_NMCLIENT_LOG_T(self, + "[%s]: register NMClient for D-Bus object", + dbobj->dbus_path->str); + dbobj->nmobj = G_OBJECT(self); + if (dbobj->dbus_path == _dbus_path_nm) { + nm_assert(!priv->dbobj_nm); + priv->dbobj_nm = dbobj; + } else if (dbobj->dbus_path == _dbus_path_settings) { + nm_assert(!priv->dbobj_settings); + priv->dbobj_settings = dbobj; + } else { + nm_assert(dbobj->dbus_path == _dbus_path_dns_manager); + nm_assert(!priv->dbobj_dns_manager); + priv->dbobj_dns_manager = dbobj; + } + nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY, self); + } else { + GType gtype = G_TYPE_NONE; + NMLDBusMetaInteracePrio curr_prio = NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_10 - 1; + + c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) { + nm_assert(!db_iface_data->iface_removed); + if (!db_iface_data->dbus_iface_is_wellknown) + break; + if (db_iface_data->dbus_iface.meta->interface_prio <= curr_prio) + continue; + curr_prio = db_iface_data->dbus_iface.meta->interface_prio; + gtype = db_iface_data->dbus_iface.meta->get_type_fcn(); + } + if (gtype != G_TYPE_NONE) { + dbobj->nmobj = g_object_new(gtype, NULL); + + NML_NMCLIENT_LOG_T(self, + "[%s]: register new NMObject " NM_HASH_OBFUSCATE_PTR_FMT + " of type %s", + dbobj->dbus_path->str, + NM_HASH_OBFUSCATE_PTR(dbobj->nmobj), + g_type_name(gtype)); + + nm_assert(NM_IS_OBJECT(dbobj->nmobj)); + NM_OBJECT_GET_CLASS(dbobj->nmobj) + ->register_client(NM_OBJECT(dbobj->nmobj), self, dbobj); + nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY, self); + } + } + } + + c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) { + nm_assert(!db_iface_data->iface_removed); + if (!db_iface_data->dbus_iface_is_wellknown) + break; + if (c_list_is_empty(&db_iface_data->changed_prop_lst_head)) + continue; + if (dbobj->nmobj) + _obj_handle_dbus_iface_changes(self, dbobj, db_iface_data); + } + + if (c_list_is_empty(&dbobj->iface_lst_head) && dbobj->nmobj) { + if (dbobj->nmobj == G_OBJECT(self)) { + dbobj->nmobj = NULL; + NML_NMCLIENT_LOG_T(self, + "[%s]: unregister NMClient from D-Bus object", + dbobj->dbus_path->str); + if (dbobj->dbus_path == _dbus_path_nm) { + nm_assert(priv->dbobj_nm == dbobj); + priv->dbobj_nm = NULL; + nml_dbus_property_o_clear_many(priv->nm.property_o, + G_N_ELEMENTS(priv->nm.property_o), + self); + nml_dbus_property_ao_clear_many(priv->nm.property_ao, + G_N_ELEMENTS(priv->nm.property_ao), + self); + } else if (dbobj->dbus_path == _dbus_path_settings) { + nm_assert(priv->dbobj_settings == dbobj); + priv->dbobj_settings = NULL; + nml_dbus_property_ao_clear(&priv->settings.connections, self); + } else { + nm_assert(dbobj->dbus_path == _dbus_path_dns_manager); + nm_assert(priv->dbobj_dns_manager == dbobj); + priv->dbobj_dns_manager = NULL; + } + } else { + nmobj_unregistering = g_steal_pointer(&dbobj->nmobj); + nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_WATCHED_ONLY, self); + NML_NMCLIENT_LOG_T(self, + "[%s]: unregister NMObject " NM_HASH_OBFUSCATE_PTR_FMT " of type %s", + dbobj->dbus_path->str, + NM_HASH_OBFUSCATE_PTR(nmobj_unregistering), + g_type_name(G_OBJECT_TYPE(nmobj_unregistering))); + NM_OBJECT_GET_CLASS(nmobj_unregistering) + ->unregister_client(NM_OBJECT(nmobj_unregistering), self, dbobj); + } + } + + nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ); +} + +/*****************************************************************************/ + +static void +_dbus_handle_obj_changed_nmobj(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + NMLDBusObject * dbobj; + CList obj_changed_tmp_lst_head = C_LIST_INIT(obj_changed_tmp_lst_head); + + nm_assert(!nml_dbus_object_obj_changed_any_linked(self, ~NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ)); + + /* First we notify all watchers that these objects changed. Note that we only do that + * here for the list before processing the changes below in a loop. That is, because + * processing changes can again enqueue changed objects, and we only want to want to + * notify watchers for the events that happened earlier (not repeatedly notify them). */ + c_list_splice(&obj_changed_tmp_lst_head, &priv->obj_changed_lst_head); + while ( + (dbobj = c_list_first_entry(&obj_changed_tmp_lst_head, NMLDBusObject, obj_changed_lst))) { + nm_c_list_move_tail(&priv->obj_changed_lst_head, &dbobj->obj_changed_lst); + _dbobjs_notify_watchers_for_dbobj(self, dbobj); + } + +again: + + nm_assert(!nml_dbus_object_obj_changed_any_linked(self, ~NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ)); + + c_list_splice(&obj_changed_tmp_lst_head, &priv->obj_changed_lst_head); + + while ( + (dbobj = c_list_first_entry(&obj_changed_tmp_lst_head, NMLDBusObject, obj_changed_lst))) { + if (!nml_dbus_object_obj_changed_consume(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ)) { + nm_assert_not_reached(); + continue; + } + + if (!dbobj->nmobj) + continue; + + if (dbobj->nmobj == G_OBJECT(self)) { + if (dbobj == priv->dbobj_nm) { + nml_dbus_property_o_notify_changed_many(priv->nm.property_o, + G_N_ELEMENTS(priv->nm.property_o), + self); + nml_dbus_property_ao_notify_changed_many(priv->nm.property_ao, + G_N_ELEMENTS(priv->nm.property_ao), + self); + } else if (dbobj == priv->dbobj_settings) + nml_dbus_property_ao_notify_changed(&priv->settings.connections, self); + else + nm_assert(dbobj == priv->dbobj_dns_manager); + } else + NM_OBJECT_GET_CLASS(dbobj->nmobj)->obj_changed_notify(NM_OBJECT(dbobj->nmobj)); + + _dbobjs_check_dbobj_ready(self, dbobj); + } + + if (!c_list_is_empty(&priv->obj_changed_lst_head)) { + nm_assert(nml_dbus_object_obj_changed_any_linked(self, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ)); + /* we got new changes enqueued. Need to check again. */ + goto again; + } +} + +static void +_dbus_handle_obj_changed_dbus(NMClient *self, const char *log_context) +{ + NMClientPrivate *priv; + NMLDBusObject * dbobj; + CList obj_changed_tmp_lst_head = C_LIST_INIT(obj_changed_tmp_lst_head); + + priv = NM_CLIENT_GET_PRIVATE(self); + + /* We move the changed list onto a temporary list and consume that. + * Note that nml_dbus_object_obj_changed_consume() will move the object + * back to the original list if there are changes of another type. + * + * This is done so that we can enqueue more changes while processing the + * change list. */ + c_list_splice(&obj_changed_tmp_lst_head, &priv->obj_changed_lst_head); + + while ( + (dbobj = c_list_first_entry(&obj_changed_tmp_lst_head, NMLDBusObject, obj_changed_lst))) { + nm_auto_unref_nml_dbusobj NMLDBusObject *dbobj_unref = NULL; + + if (!nml_dbus_object_obj_changed_consume(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_DBUS)) + continue; + + nm_assert(dbobj->obj_state >= NML_DBUS_OBJ_STATE_ON_DBUS); + + dbobj_unref = nml_dbus_object_ref(dbobj); + + _obj_handle_dbus_changes(self, dbobj); + + if (dbobj->obj_state == NML_DBUS_OBJ_STATE_UNLINKED) + continue; + + if (c_list_is_empty(&dbobj->iface_lst_head) && c_list_is_empty(&dbobj->watcher_lst_head)) { + NML_NMCLIENT_LOG_T(self, "[%s]: drop D-Bus instance", dbobj->dbus_path->str); + nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_UNLINKED, self); + if (!g_hash_table_steal(priv->dbus_objects, dbobj)) + nm_assert_not_reached(); + nml_dbus_object_unref(dbobj); + } + } + + /* D-Bus changes can only be enqueued in an earlier stage. We don't expect + * anymore changes of type D-Bus at this point. */ + nm_assert(!nml_dbus_object_obj_changed_any_linked(self, NML_DBUS_OBJ_CHANGED_TYPE_DBUS)); +} + +static void +_dbus_handle_changes_commit(NMClient *self, gboolean allow_init_start_check_complete) +{ + NMClientPrivate * priv = NM_CLIENT_GET_PRIVATE(self); + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + + _dbus_handle_obj_changed_nmobj(self); + + dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->main_context); + + _nm_client_notify_event_emit(self); + + _set_nm_running(self); + + if (allow_init_start_check_complete) + _init_start_check_complete(self); +} + +static void +_dbus_handle_changes(NMClient * self, + const char *log_context, + gboolean allow_init_start_check_complete) +{ + _dbus_handle_obj_changed_dbus(self, log_context); + _dbus_handle_changes_commit(self, allow_init_start_check_complete); +} + +static gboolean +_dbus_handle_properties_changed(NMClient * self, + const char * log_context, + const char * object_path, + const char * interface_name, + gboolean allow_add_iface, + GVariant * changed_properties, + NMLDBusObject **inout_dbobj) +{ + NMLDBusObject * dbobj = NULL; + NMLDBusObjIfaceData *db_iface_data = NULL; + nm_auto_ref_string NMRefString *dbus_path = NULL; + + nm_assert(!changed_properties + || g_variant_is_of_type(changed_properties, G_VARIANT_TYPE("a{sv}"))); + + { + gs_free char *ss = NULL; + + NML_NMCLIENT_LOG_T(self, + "[%s]: %s: properties changed for interface %s %s%s%s", + object_path, + log_context, + interface_name, + NM_PRINT_FMT_QUOTED(changed_properties, + "{ ", + (ss = g_variant_print(changed_properties, TRUE)), + " }", + "(no changed properties)")); + } + + if (inout_dbobj) { + dbobj = *inout_dbobj; + nm_assert(!dbobj || nm_streq(object_path, dbobj->dbus_path->str)); + } + if (!dbobj) { + dbus_path = nm_ref_string_new(object_path); + dbobj = _dbobjs_dbobj_get_r(self, dbus_path); + } + + if (dbobj) { + nm_assert(dbobj->obj_state >= NML_DBUS_OBJ_STATE_WATCHED_ONLY); + db_iface_data = nml_dbus_object_iface_data_get(dbobj, interface_name, allow_add_iface); + if (db_iface_data && dbobj->obj_state == NML_DBUS_OBJ_STATE_WATCHED_ONLY) + nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_ON_DBUS, self); + } else if (allow_add_iface) { + dbobj = _dbobjs_dbobj_create(self, g_steal_pointer(&dbus_path)); + nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_ON_DBUS, self); + db_iface_data = nml_dbus_object_iface_data_get(dbobj, interface_name, TRUE); + nm_assert(db_iface_data); + } + + NM_SET_OUT(inout_dbobj, dbobj); + + if (!db_iface_data) { + if (allow_add_iface) + NML_NMCLIENT_LOG_E(self, + "%s: [%s] too many interfaces on object. Something is very wrong", + log_context, + object_path); + else + NML_NMCLIENT_LOG_E(self, + "%s: [%s] property changed signal for non existing interface %s", + log_context, + object_path, + interface_name); + nm_assert(!dbobj || dbobj->obj_state != NML_DBUS_OBJ_STATE_UNLINKED); + return FALSE; + } + + if (!db_iface_data->dbus_iface_is_wellknown) + NML_NMCLIENT_LOG_W(self, + "%s: [%s] ignore unknown interface %s", + log_context, + object_path, + interface_name); + else if (changed_properties) { + GVariantIter iter_prop; + const char * property_name; + GVariant * property_value_tmp; + + g_variant_iter_init(&iter_prop, changed_properties); + while (g_variant_iter_next(&iter_prop, "{&sv}", &property_name, &property_value_tmp)) { + _nm_unused gs_unref_variant GVariant *property_value = property_value_tmp; + const NMLDBusMetaProperty * meta_property; + NMLDBusObjPropData * db_propdata; + guint property_idx; + + meta_property = nml_dbus_meta_property_get(db_iface_data->dbus_iface.meta, + property_name, + &property_idx); + if (!meta_property) { + NML_NMCLIENT_LOG_W(self, + "%s: [%s]: ignore unknown property %s.%s", + log_context, + object_path, + interface_name, + property_name); + continue; + } + + db_propdata = &db_iface_data->prop_datas[property_idx]; + + NML_NMCLIENT_LOG_T(self, + "[%s]: %s: %s property %s.%s", + object_path, + log_context, + db_propdata->prop_data_value ? "update" : "set", + interface_name, + property_name); + + nm_g_variant_unref(db_propdata->prop_data_value); + db_propdata->prop_data_value = g_steal_pointer(&property_value); + nm_c_list_move_tail(&db_iface_data->changed_prop_lst_head, + &db_propdata->changed_prop_lst); + } + } + + nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_DBUS); + return TRUE; +} + +static gboolean +_dbus_handle_interface_added(NMClient * self, + const char *log_context, + const char *object_path, + GVariant * ifaces) +{ + gboolean changed = FALSE; + const char * interface_name; + GVariant * changed_properties; + GVariantIter iter_ifaces; + NMLDBusObject *dbobj = NULL; + + nm_assert(g_variant_is_of_type(ifaces, G_VARIANT_TYPE("a{sa{sv}}"))); + + g_variant_iter_init(&iter_ifaces, ifaces); + while (g_variant_iter_next(&iter_ifaces, "{&s@a{sv}}", &interface_name, &changed_properties)) { + _nm_unused gs_unref_variant GVariant *changed_properties_free = changed_properties; + + if (_dbus_handle_properties_changed(self, + log_context, + object_path, + interface_name, + TRUE, + changed_properties, + &dbobj)) + changed = TRUE; + } + + return changed; +} + +static gboolean +_dbus_handle_interface_removed(NMClient * self, + const char * log_context, + const char * object_path, + NMLDBusObject ** inout_dbobj, + const char *const *removed_interfaces) +{ + gboolean changed = FALSE; + NMLDBusObject *dbobj; + gsize i; + + if (inout_dbobj && *inout_dbobj) { + dbobj = *inout_dbobj; + nm_assert(dbobj == _dbobjs_dbobj_get_s(self, object_path)); + } else { + dbobj = _dbobjs_dbobj_get_s(self, object_path); + if (!dbobj) { + NML_NMCLIENT_LOG_E(self, + "%s: [%s]: receive interface removed event for non existing object", + log_context, + object_path); + return FALSE; + } + NM_SET_OUT(inout_dbobj, dbobj); + } + + for (i = 0; removed_interfaces[i]; i++) { + NMLDBusObjIfaceData *db_iface_data; + const char * interface_name = removed_interfaces[i]; + + db_iface_data = nml_dbus_object_iface_data_get(dbobj, interface_name, FALSE); + if (!db_iface_data) { + NML_NMCLIENT_LOG_E( + self, + "%s: [%s] receive interface remove event for unexpected interface %s", + log_context, + object_path, + interface_name); + continue; + } + + NML_NMCLIENT_LOG_T(self, + "%s: [%s] receive interface remove event for interface %s", + log_context, + object_path, + interface_name); + db_iface_data->iface_removed = TRUE; + changed = TRUE; + } + + if (changed) + nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_DBUS); + + return changed; +} + +static void +_dbus_managed_objects_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * arg_object_path, + const char * interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMClient * self = user_data; + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + const char * log_context; + gboolean changed; + + nm_assert(nm_streq0(interface_name, DBUS_INTERFACE_OBJECT_MANAGER)); + + if (priv->get_managed_objects_cancellable) { + /* we still wait for the initial GetManagedObjects(). Ignore the event. */ + return; + } + + if (nm_streq(signal_name, "InterfacesAdded")) { + gs_unref_variant GVariant *interfaces_and_properties = NULL; + const char * object_path; + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(oa{sa{sv}})"))) + return; + + g_variant_get(parameters, "(&o@a{sa{sv}})", &object_path, &interfaces_and_properties); + + log_context = "interfaces-added"; + changed = + _dbus_handle_interface_added(self, log_context, object_path, interfaces_and_properties); + goto out; + } + + if (nm_streq(signal_name, "InterfacesRemoved")) { + gs_free const char **interfaces = NULL; + const char * object_path; + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(oas)"))) + return; + + g_variant_get(parameters, "(&o^a&s)", &object_path, &interfaces); + + log_context = "interfaces-removed"; + changed = _dbus_handle_interface_removed(self, log_context, object_path, NULL, interfaces); + goto out; + } + + return; + +out: + if (changed) + _dbus_handle_changes(self, log_context, TRUE); +} + +static void +_dbus_properties_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * signal_interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMClient * self = user_data; + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + const char * interface_name; + gs_unref_variant GVariant *changed_properties = NULL; + gs_free const char ** invalidated_properties = NULL; + const char * log_context = "properties-changed"; + + if (priv->get_managed_objects_cancellable) { + /* we still wait for the initial GetManagedObjects(). Ignore the event. */ + return; + } + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sa{sv}as)"))) + return; + + g_variant_get(parameters, + "(&s@a{sv}^a&s)", + &interface_name, + &changed_properties, + &invalidated_properties); + + if (invalidated_properties && invalidated_properties[0]) { + NML_NMCLIENT_LOG_W(self, + "%s: [%s] ignore invalidated properties on interface %s", + log_context, + object_path, + interface_name); + } + + if (_dbus_handle_properties_changed(self, + log_context, + object_path, + interface_name, + FALSE, + changed_properties, + NULL)) + _dbus_handle_changes(self, log_context, TRUE); +} + +static void +_dbus_get_managed_objects_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + NMClient * self; + NMClientPrivate *priv; + gs_unref_variant GVariant *ret = NULL; + gs_unref_variant GVariant *managed_objects = NULL; + gs_free_error GError *error = NULL; + gs_unref_object GObject *context_busy_watcher = NULL; + + nm_utils_user_data_unpack(user_data, &self, &context_busy_watcher); + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error); + + nm_assert((!!ret) != (!!error)); + + if (!ret && nm_utils_error_is_cancelled(error)) + return; + + priv = NM_CLIENT_GET_PRIVATE(self); + + if (ret) { + nm_assert(g_variant_is_of_type(ret, G_VARIANT_TYPE("(a{oa{sa{sv}}})"))); + managed_objects = g_variant_get_child_value(ret, 0); + } + + g_clear_object(&priv->get_managed_objects_cancellable); + + if (!managed_objects) { + NML_NMCLIENT_LOG_D(self, "GetManagedObjects() call failed: %s", error->message); + /* hm, now that's odd. Maybe NetworkManager just quit and we are about to get + * a name-owner changed signal soon. Treat this as if we got no managed objects at all. */ + } else + NML_NMCLIENT_LOG_D(self, "GetManagedObjects() completed"); + + if (managed_objects) { + GVariantIter iter; + const char * object_path; + GVariant * ifaces_tmp; + + g_variant_iter_init(&iter, managed_objects); + while (g_variant_iter_next(&iter, "{&o@a{sa{sv}}}", &object_path, &ifaces_tmp)) { + gs_unref_variant GVariant *ifaces = ifaces_tmp; + + _dbus_handle_interface_added(self, "get-managed-objects", object_path, ifaces); + } + } + + /* always call _dbus_handle_changes(), even if nothing changed. We need this to complete + * initialization. */ + _dbus_handle_changes(self, "get-managed-objects", TRUE); +} + +/*****************************************************************************/ + +static void +_nm_client_get_settings_call_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + NMRemoteConnection *remote_connection; + NMClient * self; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *settings = NULL; + NMLDBusObject * dbobj; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error); + if (!ret && nm_utils_error_is_cancelled(error)) + return; + + remote_connection = user_data; + + self = _nm_object_get_client(remote_connection); + + dbobj = _nm_object_get_dbobj(remote_connection); + + _ASSERT_dbobj(dbobj, self); + + if (!ret) { + NML_NMCLIENT_LOG_T(self, + "[%s] GetSettings() completed with error: %s", + dbobj->dbus_path->str, + error->message); + } else { + NML_NMCLIENT_LOG_T(self, + "[%s] GetSettings() completed with success", + dbobj->dbus_path->str); + g_variant_get(ret, "(@a{sa{sv}})", &settings); + } + + _nm_remote_settings_get_settings_commit(remote_connection, settings); + + _dbus_handle_changes_commit(self, TRUE); +} + +void +_nm_client_get_settings_call(NMClient *self, NMLDBusObject *dbobj) +{ + GCancellable *cancellable; + + cancellable = _nm_remote_settings_get_settings_prepare(NM_REMOTE_CONNECTION(dbobj->nmobj)); + + _nm_client_dbus_call_simple(self, + cancellable, + dbobj->dbus_path->str, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + "GetSettings", + g_variant_new("()"), + G_VARIANT_TYPE("(a{sa{sv}})"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + _nm_client_get_settings_call_cb, + dbobj->nmobj); +} + +static void +_dbus_settings_updated_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * signal_interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMClient * self = user_data; + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + const char * log_context = "settings-updated"; + NMLDBusObject * dbobj; + + if (priv->get_managed_objects_cancellable) { + /* we still wait for the initial GetManagedObjects(). Ignore the event. */ + return; + } + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("()"))) + return; + + dbobj = _dbobjs_dbobj_get_s(self, object_path); + + if (!dbobj || !NM_IS_REMOTE_CONNECTION(dbobj->nmobj)) { + NML_NMCLIENT_LOG_W(self, + "%s: [%s] ignore Updated signal for non-existing setting", + log_context, + object_path); + return; + } + + NML_NMCLIENT_LOG_T(self, "%s: [%s] Updated signal received", log_context, object_path); + + _nm_client_get_settings_call(self, dbobj); +} + +/*****************************************************************************/ + +static void +_dbus_nm_connection_active_state_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * signal_interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMClient * self = user_data; + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + const char * log_context = "active-connection-state-changed"; + NMLDBusObject * dbobj; + guint32 state; + guint32 reason; + + if (priv->get_managed_objects_cancellable) { + /* we still wait for the initial GetManagedObjects(). Ignore the event. */ + return; + } + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(uu)"))) { + NML_NMCLIENT_LOG_E(self, + "%s: [%s] ignore StateChanged signal with unexpected signature", + log_context, + object_path); + return; + } + + dbobj = _dbobjs_dbobj_get_s(self, object_path); + + if (!dbobj || !NM_IS_ACTIVE_CONNECTION(dbobj->nmobj)) { + NML_NMCLIENT_LOG_E(self, + "%s: [%s] ignore StateChanged signal for non-existing active connection", + log_context, + object_path); + return; + } + + g_variant_get(parameters, "(uu)", &state, &reason); + + NML_NMCLIENT_LOG_T(self, "%s: [%s] StateChanged signal received", log_context, object_path); + + _nm_active_connection_state_changed_commit(NM_ACTIVE_CONNECTION(dbobj->nmobj), state, reason); + + _dbus_handle_changes_commit(self, TRUE); +} + +/*****************************************************************************/ + +static void +_dbus_nm_vpn_connection_state_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * signal_interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMClient * self = user_data; + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + const char * log_context = "vpn-connection-state-changed"; + NMLDBusObject * dbobj; + guint32 state; + guint32 reason; + + if (priv->get_managed_objects_cancellable) { + /* we still wait for the initial GetManagedObjects(). Ignore the event. */ + return; + } + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(uu)"))) { + NML_NMCLIENT_LOG_E(self, + "%s: [%s] ignore VpnStateChanged signal with unexpected signature", + log_context, + object_path); + return; + } + + dbobj = _dbobjs_dbobj_get_s(self, object_path); + + if (!dbobj || !NM_IS_VPN_CONNECTION(dbobj->nmobj)) { + NML_NMCLIENT_LOG_E(self, + "%s: [%s] ignore VpnStateChanged signal for non-existing vpn connection", + log_context, + object_path); + return; + } + + g_variant_get(parameters, "(uu)", &state, &reason); + + NML_NMCLIENT_LOG_T(self, "%s: [%s] VpnStateChanged signal received", log_context, object_path); + + _nm_vpn_connection_state_changed_commit(NM_VPN_CONNECTION(dbobj->nmobj), state, reason); + + _dbus_handle_changes_commit(self, TRUE); +} + +/*****************************************************************************/ + +static void +_emit_permissions_changed(NMClient *self, const guint8 *old_permissions, const guint8 *permissions) +{ + int i; + + if (self->obj_base.is_disposing) + return; + + if (old_permissions == permissions) + return; + + for (i = 0; i < (int) G_N_ELEMENTS(nm_auth_permission_sorted); i++) { + NMClientPermission perm = nm_auth_permission_sorted[i]; + NMClientPermissionResult perm_result = NM_CLIENT_PERMISSION_RESULT_UNKNOWN; + NMClientPermissionResult perm_result_old = NM_CLIENT_PERMISSION_RESULT_UNKNOWN; + + if (permissions) + perm_result = permissions[perm - 1]; + if (old_permissions) + perm_result_old = old_permissions[perm - 1]; + + if (perm_result == perm_result_old) + continue; + + g_signal_emit(self, signals[PERMISSION_CHANGED], 0, (guint) perm, (guint) perm_result); + } +} + +static void +_dbus_check_permissions_start_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + NMClient * self; + NMClientPrivate * priv; + gs_unref_variant GVariant *ret = NULL; + nm_auto_free_variant_iter GVariantIter *v_permissions = NULL; + gs_free guint8 *old_permissions = NULL; + gs_free_error GError *error = NULL; + const char * pkey; + const char * pvalue; + int i; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error); + if (!ret && nm_utils_error_is_cancelled(error)) + return; + + self = user_data; + priv = NM_CLIENT_GET_PRIVATE(self); + + g_clear_object(&priv->permissions_cancellable); + + old_permissions = g_steal_pointer(&priv->permissions); + + if (!ret) { + /* when the call completes, we always pretend success. Even a failure means + * that we fetched the permissions, however they are all unknown. */ + NML_NMCLIENT_LOG_T(self, "GetPermissions call failed: %s", error->message); + goto out; + } + + NML_NMCLIENT_LOG_T(self, "GetPermissions call finished with success"); + + g_variant_get(ret, "(a{ss})", &v_permissions); + while (g_variant_iter_next(v_permissions, "{&s&s}", &pkey, &pvalue)) { + NMClientPermission perm; + NMClientPermissionResult perm_result; + + perm = nm_auth_permission_from_string(pkey); + if (perm == NM_CLIENT_PERMISSION_NONE) + continue; + + perm_result = nm_client_permission_result_from_string(pvalue); + + if (!priv->permissions) { + if (perm_result == NM_CLIENT_PERMISSION_RESULT_UNKNOWN) + continue; + priv->permissions = g_new(guint8, G_N_ELEMENTS(nm_auth_permission_sorted)); + for (i = 0; i < (int) G_N_ELEMENTS(nm_auth_permission_sorted); i++) + priv->permissions[i] = NM_CLIENT_PERMISSION_RESULT_UNKNOWN; + } + priv->permissions[perm - 1] = perm_result; + } + +out: + priv->permissions_state = NM_TERNARY_TRUE; + + dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->main_context); + _emit_permissions_changed(self, old_permissions, priv->permissions); + _notify(self, PROP_PERMISSIONS_STATE); +} + +static void +_dbus_check_permissions_start(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + gboolean fetch; + + fetch = !NM_FLAGS_HAS((NMClientInstanceFlags) priv->instance_flags, + NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS); + + nm_clear_g_cancellable(&priv->permissions_cancellable); + + if (fetch) { + NML_NMCLIENT_LOG_T(self, "GetPermissions() call started..."); + + priv->permissions_cancellable = g_cancellable_new(); + _nm_client_dbus_call_simple(self, + priv->permissions_cancellable, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "GetPermissions", + g_variant_new("()"), + G_VARIANT_TYPE("(a{ss})"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + _dbus_check_permissions_start_cb, + self); + } +} + +static void +_dbus_nm_check_permissions_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * signal_interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMClient * self = user_data; + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("()"))) { + NML_NMCLIENT_LOG_E(self, + "ignore CheckPermissions signal with unexpected signature %s", + g_variant_get_type_string(parameters)); + return; + } + + _dbus_check_permissions_start(self); + + if (priv->permissions_state == NM_TERNARY_TRUE) + priv->permissions_state = NM_TERNARY_FALSE; + _notify(self, PROP_PERMISSIONS_STATE); +} + +/*****************************************************************************/ + +static void +_property_ao_notify_changed_connections_cb(NMLDBusPropertyAO *pr_ao, + NMClient * self, + NMObject * nmobj, + gboolean is_added /* or else removed */) +{ + _nm_client_notify_event_queue_emit_obj_signal(self, + G_OBJECT(self), + nmobj, + is_added, + 5, + is_added ? signals[CONNECTION_ADDED] + : signals[CONNECTION_REMOVED]); +} + +static void +_property_ao_notify_changed_all_devices_cb(NMLDBusPropertyAO *pr_ao, + NMClient * self, + NMObject * nmobj, + gboolean is_added /* or else removed */) +{ + _nm_client_notify_event_queue_emit_obj_signal(self, + G_OBJECT(self), + nmobj, + is_added, + 6, + is_added ? signals[ANY_DEVICE_ADDED] + : signals[ANY_DEVICE_REMOVED]); +} + +static void +_property_ao_notify_changed_devices_cb(NMLDBusPropertyAO *pr_ao, + NMClient * self, + NMObject * nmobj, + gboolean is_added /* or else removed */) +{ + _nm_client_notify_event_queue_emit_obj_signal(self, + G_OBJECT(self), + nmobj, + is_added, + 7, + is_added ? signals[DEVICE_ADDED] + : signals[DEVICE_REMOVED]); +} + +static void +_property_ao_notify_changed_active_connections_cb(NMLDBusPropertyAO *pr_ao, + NMClient * self, + NMObject * nmobj, + gboolean is_added /* or else removed */) +{ + _nm_client_notify_event_queue_emit_obj_signal(self, + G_OBJECT(self), + nmobj, + is_added, + 8, + is_added ? signals[ACTIVE_CONNECTION_ADDED] + : signals[ACTIVE_CONNECTION_REMOVED]); +} + +/*****************************************************************************/ + +typedef struct { + NMLDBusObjWatcherWithPtr *obj_watcher; + const char * op_name; + NMLDBusObject * dbobj; + GTask * task; + GVariant * extra_results; + gpointer result; + GType gtype; + gulong cancellable_id; +} RequestWaitData; + +static void +_request_wait_data_free(RequestWaitData *request_data) +{ + nm_assert(!request_data->obj_watcher); + nm_assert(request_data->cancellable_id == 0); + nm_assert(!request_data->task || G_IS_TASK(request_data->task)); + + nm_g_object_unref(request_data->task); + nm_g_object_unref(request_data->result); + nm_g_variant_unref(request_data->extra_results); + if (request_data->dbobj) + nml_dbus_object_unref(request_data->dbobj); + nm_g_slice_free(request_data); +} + +static void +_request_wait_task_return(RequestWaitData *request_data) +{ + gs_unref_object GTask *task = NULL; + + nm_assert(request_data); + nm_assert(G_IS_TASK(request_data->task)); + nm_assert(request_data->dbobj); + nm_assert(NM_IS_OBJECT(request_data->dbobj->nmobj)); + nm_assert(!request_data->result); + + task = g_steal_pointer(&request_data->task); + + request_data->result = g_object_ref(request_data->dbobj->nmobj); + nm_clear_g_signal_handler(g_task_get_cancellable(task), &request_data->cancellable_id); + nm_clear_pointer(&request_data->dbobj, nml_dbus_object_unref); + g_task_return_pointer(task, request_data, (GDestroyNotify) _request_wait_data_free); +} + +static gboolean +_request_wait_complete(NMClient *self, RequestWaitData *request_data, gboolean force_complete) +{ + NMLDBusObject *dbobj; + + nm_assert(request_data); + nm_assert(!request_data->result); + nm_assert(!request_data->obj_watcher); + nm_assert(request_data->dbobj); + + dbobj = request_data->dbobj; + + if (dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY) { + NML_NMCLIENT_LOG_D(self, + "%s() succeeded with %s", + request_data->op_name, + dbobj->dbus_path->str); + nm_assert(G_TYPE_CHECK_INSTANCE_TYPE(dbobj->nmobj, request_data->gtype)); + _request_wait_task_return(request_data); + return TRUE; + } + + if (force_complete || dbobj->obj_state != NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY) { + if (force_complete) + NML_NMCLIENT_LOG_D(self, + "%s() succeeded with %s but object is in an unsuitable state", + request_data->op_name, + dbobj->dbus_path->str); + else + NML_NMCLIENT_LOG_W(self, + "%s() succeeded with %s but object is in an unsuitable state", + request_data->op_name, + dbobj->dbus_path->str); + + g_task_return_error( + request_data->task, + g_error_new(NM_CLIENT_ERROR, + NM_CLIENT_ERROR_OBJECT_CREATION_FAILED, + _("request succeeded with %s but object is in an unsuitable state"), + dbobj->dbus_path->str)); + _request_wait_data_free(request_data); + return TRUE; + } + + return FALSE; +} + +static void +_request_wait_complete_cb(NMClient *self, NMClientNotifyEventWithPtr *notify_event) +{ + _request_wait_complete(self, notify_event->user_data, TRUE); +} + +static void +_request_wait_obj_watcher_cb(NMClient *self, gpointer obj_watcher_base) +{ + NMLDBusObjWatcherWithPtr *obj_watcher = obj_watcher_base; + RequestWaitData * request_data = obj_watcher->user_data; + NMLDBusObject * dbobj; + + dbobj = request_data->dbobj; + + if (dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY) + return; + + nm_assert(NM_IN_SET((NMLDBusObjState) dbobj->obj_state, + NML_DBUS_OBJ_STATE_WATCHED_ONLY, + NML_DBUS_OBJ_STATE_ON_DBUS, + NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY)); + + _dbobjs_obj_watcher_unregister(self, g_steal_pointer(&request_data->obj_watcher)); + + nm_clear_g_signal_handler(g_task_get_cancellable(request_data->task), + &request_data->cancellable_id); + + _nm_client_notify_event_queue_with_ptr(self, + NM_CLIENT_NOTIFY_EVENT_PRIO_AFTER + 30, + _request_wait_complete_cb, + request_data); +} + +static void +_request_wait_cancelled_cb(GCancellable *cancellable, gpointer user_data) +{ + RequestWaitData *request_data = user_data; + NMClient * self; + GError * error = NULL; + + nm_assert(cancellable == g_task_get_cancellable(request_data->task)); + + nm_utils_error_set_cancelled(&error, FALSE, NULL); + + self = g_task_get_source_object(request_data->task); + + nm_clear_g_signal_handler(cancellable, &request_data->cancellable_id); + + _dbobjs_obj_watcher_unregister(self, g_steal_pointer(&request_data->obj_watcher)); + + g_task_return_error(request_data->task, error); + + _request_wait_data_free(request_data); +} + +static void +_request_wait_start(GTask * task_take, + const char *op_name, + GType gtype, + const char *dbus_path, + GVariant * extra_results_take) +{ + NMClient * self; + gs_unref_object GTask *task = g_steal_pointer(&task_take); + RequestWaitData * request_data; + GCancellable * cancellable; + NMLDBusObject * dbobj; + + nm_assert(G_IS_TASK(task)); + + self = g_task_get_source_object(task); + + dbobj = _dbobjs_get_nmobj(self, dbus_path, gtype); + + if (!dbobj) { + NML_NMCLIENT_LOG_E(self, + "%s() succeeded with %s but object does not exist", + op_name, + dbus_path); + g_task_return_error(task, + g_error_new(NM_CLIENT_ERROR, + NM_CLIENT_ERROR_FAILED, + _("operation succeeded but object %s does not exist"), + dbus_path)); + return; + } + + request_data = g_slice_new(RequestWaitData); + *request_data = (RequestWaitData){ + .task = g_steal_pointer(&task), + .op_name = op_name, + .gtype = gtype, + .dbobj = nml_dbus_object_ref(dbobj), + .obj_watcher = NULL, + .extra_results = g_steal_pointer(&extra_results_take), + .result = NULL, + .cancellable_id = 0, + }; + + if (_request_wait_complete(self, request_data, FALSE)) + return; + + NML_NMCLIENT_LOG_T(self, + "%s() succeeded with %s. Wait for object to become ready", + op_name, + dbobj->dbus_path->str); + + request_data->obj_watcher = _dbobjs_obj_watcher_register_o(self, + dbobj, + _request_wait_obj_watcher_cb, + sizeof(NMLDBusObjWatcherWithPtr)); + request_data->obj_watcher->user_data = request_data; + + cancellable = g_task_get_cancellable(request_data->task); + if (cancellable) { + gulong id; + + id = g_cancellable_connect(cancellable, + G_CALLBACK(_request_wait_cancelled_cb), + request_data, + NULL); + if (id == 0) { + /* the callback was invoked synchronously, which destroyed @request_data. + * We must not touch @info anymore. */ + } else + request_data->cancellable_id = id; + } +} + +static gpointer +_request_wait_finish(NMClient * client, + GAsyncResult *result, + gpointer source_tag, + GVariant ** out_result, + GError ** error) +{ + RequestWaitData *request_data = NULL; + gpointer r; + + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + g_return_val_if_fail(nm_g_task_is_valid(result, client, source_tag), NULL); + + request_data = g_task_propagate_pointer(G_TASK(result), error); + if (!request_data) { + NM_SET_OUT(out_result, NULL); + return NULL; + } + + nm_assert(NM_IS_OBJECT(request_data->result)); + + NM_SET_OUT(out_result, g_steal_pointer(&request_data->extra_results)); + r = g_steal_pointer(&request_data->result); + + nm_assert(NM_IS_OBJECT(r)); + + _request_wait_data_free(request_data); + return r; +} + +/*****************************************************************************/ + +/** + * nm_client_get_instance_flags: + * @self: the #NMClient instance. + * + * Returns: the #NMClientInstanceFlags flags. + * + * Since: 1.24 + */ +NMClientInstanceFlags +nm_client_get_instance_flags(NMClient *self) +{ + g_return_val_if_fail(NM_IS_CLIENT(self), NM_CLIENT_INSTANCE_FLAGS_NONE); + + return NM_CLIENT_GET_PRIVATE(self)->instance_flags; +} + +/** + * nm_client_get_dbus_connection: + * @client: a #NMClient + * + * Gets the %GDBusConnection of the instance. This can be either passed when + * constructing the instance (as "dbus-connection" property), or it will be + * automatically initialized during async/sync init. + * + * Returns: (transfer none): the D-Bus connection of the client, or %NULL if none is set. + * + * Since: 1.22 + **/ +GDBusConnection * +nm_client_get_dbus_connection(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return NM_CLIENT_GET_PRIVATE(client)->dbus_connection; +} + +/** + * nm_client_get_dbus_name_owner: + * @client: a #NMClient + * + * Returns: (transfer none): the current name owner of the D-Bus service of NetworkManager. + * + * Since: 1.22 + **/ +const char * +nm_client_get_dbus_name_owner(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return NM_CLIENT_GET_PRIVATE(client)->name_owner; +} + +/** + * nm_client_get_version: + * @client: a #NMClient + * + * Gets NetworkManager version. + * + * Returns: string with the version (or %NULL if NetworkManager is not running) + **/ +const char * +nm_client_get_version(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return NM_CLIENT_GET_PRIVATE(client)->nm.version; +} + +/** + * nm_client_get_state: + * @client: a #NMClient + * + * Gets the current daemon state. + * + * Returns: the current %NMState + **/ +NMState +nm_client_get_state(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NM_STATE_UNKNOWN); + + return NM_CLIENT_GET_PRIVATE(client)->nm.state; +} + +/** + * nm_client_get_startup: + * @client: a #NMClient + * + * Tests whether the daemon is still in the process of activating + * connections at startup. + * + * Returns: whether the daemon is still starting up + **/ +gboolean +nm_client_get_startup(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return NM_CLIENT_GET_PRIVATE(client)->nm.startup; +} + +static void +_set_nm_running(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + gboolean nm_running; + + nm_running = priv->name_owner && !priv->get_managed_objects_cancellable; + if (priv->nm_running != nm_running) { + priv->nm_running = nm_running; + _notify(self, PROP_NM_RUNNING); + } +} + +/** + * nm_client_get_nm_running: + * @client: a #NMClient + * + * Determines whether the daemon is running. + * + * Returns: %TRUE if the daemon is running + **/ +gboolean +nm_client_get_nm_running(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return NM_CLIENT_GET_PRIVATE(client)->nm_running; +} + +/** + * nm_client_get_object_by_path: + * @client: the #NMClient instance + * @dbus_path: the D-Bus path of the object to look up + * + * Returns: (transfer none): the #NMObject instance that is + * cached under @dbus_path, or %NULL if no such object exists. + * + * Since: 1.24 + */ +NMObject * +nm_client_get_object_by_path(NMClient *client, const char *dbus_path) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + g_return_val_if_fail(dbus_path, NULL); + + return _dbobjs_get_nmobj_unpack_visible(client, dbus_path, G_TYPE_NONE); +} + +/** + * nm_client_get_metered: + * @client: a #NMClient + * + * Returns: whether the default route is metered. + * + * Since: 1.22 + */ +NMMetered +nm_client_get_metered(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NM_METERED_UNKNOWN); + + return NM_CLIENT_GET_PRIVATE(client)->nm.metered; +} + +/** + * nm_client_networking_get_enabled: + * @client: a #NMClient + * + * Whether networking is enabled or disabled. + * + * Returns: %TRUE if networking is enabled, %FALSE if networking is disabled + **/ +gboolean +nm_client_networking_get_enabled(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return NM_CLIENT_GET_PRIVATE(client)->nm.networking_enabled; +} + +/** + * nm_client_networking_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to set networking enabled, %FALSE to set networking disabled + * @error: (allow-none): return location for a #GError, or %NULL + * + * Enables or disables networking. When networking is disabled, all controlled + * interfaces are disconnected and deactivated. When networking is enabled, + * all controlled interfaces are available for activation. + * + * Returns: %TRUE on success, %FALSE otherwise + * + * Deprecated: 1.22: Use the async command nm_client_dbus_call() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to call "Enable" with "(b)" arguments and no return value. + **/ +gboolean +nm_client_networking_set_enabled(NMClient *client, gboolean enable, GError **error) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return _nm_client_dbus_call_sync_void(client, + NULL, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "Enable", + g_variant_new("(b)", enable), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); +} + +/** + * nm_client_wireless_get_enabled: + * @client: a #NMClient + * + * Determines whether the wireless is enabled. + * + * Returns: %TRUE if wireless is enabled + **/ +gboolean +nm_client_wireless_get_enabled(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return NM_CLIENT_GET_PRIVATE(client)->nm.wireless_enabled; +} + +/** + * nm_client_wireless_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to enable wireless + * + * Enables or disables wireless devices. + * + * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to set "WirelessEnabled" property to a "(b)" value. + */ +void +nm_client_wireless_set_enabled(NMClient *client, gboolean enabled) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + + _nm_client_set_property_sync_legacy(client, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "WirelessEnabled", + "b", + enabled); +} + +/** + * nm_client_wireless_hardware_get_enabled: + * @client: a #NMClient + * + * Determines whether the wireless hardware is enabled. + * + * Returns: %TRUE if the wireless hardware is enabled + **/ +gboolean +nm_client_wireless_hardware_get_enabled(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return NM_CLIENT_GET_PRIVATE(client)->nm.wireless_hardware_enabled; +} + +/** + * nm_client_wwan_get_enabled: + * @client: a #NMClient + * + * Determines whether WWAN is enabled. + * + * Returns: %TRUE if WWAN is enabled + **/ +gboolean +nm_client_wwan_get_enabled(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return NM_CLIENT_GET_PRIVATE(client)->nm.wwan_enabled; +} + +/** + * nm_client_wwan_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to enable WWAN + * + * Enables or disables WWAN devices. + * + * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to set "WwanEnabled" property to a "(b)" value. + **/ +void +nm_client_wwan_set_enabled(NMClient *client, gboolean enabled) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + + _nm_client_set_property_sync_legacy(client, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "WwanEnabled", + "b", + enabled); +} + +/** + * nm_client_wwan_hardware_get_enabled: + * @client: a #NMClient + * + * Determines whether the WWAN hardware is enabled. + * + * Returns: %TRUE if the WWAN hardware is enabled + **/ +gboolean +nm_client_wwan_hardware_get_enabled(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return NM_CLIENT_GET_PRIVATE(client)->nm.wwan_hardware_enabled; +} + +/** + * nm_client_wimax_get_enabled: + * @client: a #NMClient + * + * Determines whether WiMAX is enabled. + * + * Returns: %TRUE if WiMAX is enabled + * + * Deprecated: 1.22: This function always returns FALSE because WiMax is no longer supported. + **/ +gboolean +nm_client_wimax_get_enabled(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return FALSE; +} + +/** + * nm_client_wimax_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to enable WiMAX + * + * Enables or disables WiMAX devices. + * + * Deprecated: 1.22: This function does nothing because WiMax is no longer supported. + **/ +void +nm_client_wimax_set_enabled(NMClient *client, gboolean enabled) +{ + g_return_if_fail(NM_IS_CLIENT(client)); +} + +/** + * nm_client_wimax_hardware_get_enabled: + * @client: a #NMClient + * + * Determines whether the WiMAX hardware is enabled. + * + * Returns: %TRUE if the WiMAX hardware is enabled + * + * Deprecated: 1.22: This function always returns FALSE because WiMax is no longer supported. + **/ +gboolean +nm_client_wimax_hardware_get_enabled(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return FALSE; +} + +/** + * nm_client_connectivity_check_get_available: + * @client: a #NMClient + * + * Determine whether connectivity checking is available. This + * requires that the URI of a connectivity service has been set in the + * configuration file. + * + * Returns: %TRUE if connectivity checking is available. + * + * Since: 1.10 + */ +gboolean +nm_client_connectivity_check_get_available(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return NM_CLIENT_GET_PRIVATE(client)->nm.connectivity_check_available; +} + +/** + * nm_client_connectivity_check_get_enabled: + * @client: a #NMClient + * + * Determine whether connectivity checking is enabled. + * + * Returns: %TRUE if connectivity checking is enabled. + * + * Since: 1.10 + */ +gboolean +nm_client_connectivity_check_get_enabled(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + + return NM_CLIENT_GET_PRIVATE(client)->nm.connectivity_check_enabled; +} + +/** + * nm_client_connectivity_check_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to enable connectivity checking + * + * Enable or disable connectivity checking. Note that if a + * connectivity checking URI has not been configured, this will not + * have any effect. + * + * Since: 1.10 + * + * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to set "ConnectivityCheckEnabled" property to a "(b)" value. + */ +void +nm_client_connectivity_check_set_enabled(NMClient *client, gboolean enabled) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + + _nm_client_set_property_sync_legacy(client, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "ConnectivityCheckEnabled", + "b", + enabled); +} + +/** + * nm_client_connectivity_check_get_uri: + * @client: a #NMClient + * + * Get the URI that will be queried to determine if there is internet + * connectivity. + * + * Returns: (transfer none): the connectivity URI in use + * + * Since: 1.20 + */ +const char * +nm_client_connectivity_check_get_uri(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return NM_CLIENT_GET_PRIVATE(client)->nm.connectivity_check_uri; +} + +/** + * nm_client_get_logging: + * @client: a #NMClient + * @level: (allow-none): return location for logging level string + * @domains: (allow-none): return location for log domains string. The string is + * a list of domains separated by "," + * @error: (allow-none): return location for a #GError, or %NULL + * + * Gets NetworkManager current logging level and domains. + * + * Returns: %TRUE on success, %FALSE otherwise + * + * Deprecated: 1.22: Use the async command nm_client_dbus_call() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to call "GetLogging" with no arguments to get "(ss)" for level + * and domains. + **/ +gboolean +nm_client_get_logging(NMClient *client, char **level, char **domains, GError **error) +{ + gs_unref_variant GVariant *ret = NULL; + + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(level == NULL || *level == NULL, FALSE); + g_return_val_if_fail(domains == NULL || *domains == NULL, FALSE); + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + + ret = _nm_client_dbus_call_sync(client, + NULL, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "GetLogging", + g_variant_new("()"), + G_VARIANT_TYPE("(ss)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); + if (!ret) + return FALSE; + + g_variant_get(ret, "(ss)", level, domains); + return TRUE; +} + +/** + * nm_client_set_logging: + * @client: a #NMClient + * @level: (allow-none): logging level to set (%NULL or an empty string for no change) + * @domains: (allow-none): logging domains to set. The string should be a list of log + * domains separated by ",". (%NULL or an empty string for no change) + * @error: (allow-none): return location for a #GError, or %NULL + * + * Sets NetworkManager logging level and/or domains. + * + * Returns: %TRUE on success, %FALSE otherwise + * + * Deprecated: 1.22: Use the async command nm_client_dbus_call() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to call "SetLogging" with "(ss)" arguments for level and domains. + **/ +gboolean +nm_client_set_logging(NMClient *client, const char *level, const char *domains, GError **error) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + + return _nm_client_dbus_call_sync_void(client, + NULL, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "SetLogging", + g_variant_new("(ss)", level ?: "", domains ?: ""), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); +} + +/** + * nm_client_get_permission_result: + * @client: a #NMClient + * @permission: the permission for which to return the result, one of #NMClientPermission + * + * Requests the result of a specific permission, which indicates whether the + * client can or cannot perform the action the permission represents + * + * Returns: the permission's result, one of #NMClientPermissionResult + **/ +NMClientPermissionResult +nm_client_get_permission_result(NMClient *client, NMClientPermission permission) +{ + NMClientPrivate * priv; + NMClientPermissionResult result = NM_CLIENT_PERMISSION_RESULT_UNKNOWN; + + g_return_val_if_fail(NM_IS_CLIENT(client), NM_CLIENT_PERMISSION_RESULT_UNKNOWN); + + if (permission > NM_CLIENT_PERMISSION_NONE && permission <= NM_CLIENT_PERMISSION_LAST) { + priv = NM_CLIENT_GET_PRIVATE(client); + if (priv->permissions) + result = priv->permissions[permission - 1]; + } + + return result; +} + +/** + * nm_client_get_permissions_state: + * @self: the #NMClient instance + * + * Returns: the state of the cached permissions. %NM_TERNARY_DEFAULT + * means that no permissions result was yet received. All permissions + * are unknown. %NM_TERNARY_TRUE means that the permissions got received + * and are cached. %%NM_TERNARY_FALSE means that permissions are cached, + * but they are invalided as "CheckPermissions" signal was received + * in the meantime. + * + * Since: 1.24 + */ +NMTernary +nm_client_get_permissions_state(NMClient *self) +{ + g_return_val_if_fail(NM_IS_CLIENT(self), NM_TERNARY_DEFAULT); + + return NM_CLIENT_GET_PRIVATE(self)->permissions_state; +} + +/** + * nm_client_get_connectivity: + * @client: an #NMClient + * + * Gets the current network connectivity state. Contrast + * nm_client_check_connectivity() and + * nm_client_check_connectivity_async(), which re-check the + * connectivity state first before returning any information. + * + * Returns: the current connectivity state + */ +NMConnectivityState +nm_client_get_connectivity(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NM_CONNECTIVITY_UNKNOWN); + + return NM_CLIENT_GET_PRIVATE(client)->nm.connectivity; +} + +/** + * nm_client_check_connectivity: + * @client: an #NMClient + * @cancellable: a #GCancellable + * @error: return location for a #GError + * + * Updates the network connectivity state and returns the (new) + * current state. Contrast nm_client_get_connectivity(), which returns + * the most recent known state without re-checking. + * + * This is a blocking call; use nm_client_check_connectivity_async() + * if you do not want to block. + * + * Returns: the (new) current connectivity state + * + * Deprecated: 1.22: Use nm_client_check_connectivity_async() or GDBusConnection. + */ +NMConnectivityState +nm_client_check_connectivity(NMClient *client, GCancellable *cancellable, GError **error) +{ + NMClientPrivate *priv; + gs_unref_variant GVariant *ret = NULL; + guint32 connectivity; + + g_return_val_if_fail(NM_IS_CLIENT(client), NM_CONNECTIVITY_UNKNOWN); + + ret = _nm_client_dbus_call_sync(client, + cancellable, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "CheckConnectivity", + g_variant_new("()"), + G_VARIANT_TYPE("(u)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); + if (!ret) + return NM_CONNECTIVITY_UNKNOWN; + + g_variant_get(ret, "(u)", &connectivity); + + /* upon receiving the synchronous response, we hack the NMClient state + * and update the property outside the ordered D-Bus messages (like + * "PropertiesChanged" signals). + * + * This is really ugly, we shouldn't do this. */ + + priv = NM_CLIENT_GET_PRIVATE(client); + + if (priv->nm.connectivity != connectivity) { + priv->nm.connectivity = connectivity; + _notify(client, PROP_CONNECTIVITY); + } + + return connectivity; +} + +/** + * nm_client_check_connectivity_async: + * @client: an #NMClient + * @cancellable: a #GCancellable + * @callback: callback to call with the result + * @user_data: data for @callback. + * + * Asynchronously updates the network connectivity state and invokes + * @callback when complete. Contrast nm_client_get_connectivity(), + * which (immediately) returns the most recent known state without + * re-checking, and nm_client_check_connectivity(), which blocks. + */ +void +nm_client_check_connectivity_async(NMClient * client, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(client, + client, + nm_client_check_connectivity_async, + cancellable, + callback, + user_data, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "CheckConnectivity", + g_variant_new("()"), + G_VARIANT_TYPE("(u)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_variant_strip_dbus_error_cb); +} + +/** + * nm_client_check_connectivity_finish: + * @client: an #NMClient + * @result: the #GAsyncResult + * @error: return location for a #GError + * + * Retrieves the result of an nm_client_check_connectivity_async() + * call. + * + * Returns: the (new) current connectivity state + */ +NMConnectivityState +nm_client_check_connectivity_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + gs_unref_variant GVariant *ret = NULL; + guint32 connectivity; + + g_return_val_if_fail(NM_IS_CLIENT(client), NM_CONNECTIVITY_UNKNOWN); + g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_check_connectivity_async), + NM_CONNECTIVITY_UNKNOWN); + + ret = g_task_propagate_pointer(G_TASK(result), error); + if (!ret) + return NM_CONNECTIVITY_UNKNOWN; + + g_variant_get(ret, "(u)", &connectivity); + return connectivity; +} + +/** + * nm_client_save_hostname: + * @client: the %NMClient + * @hostname: (allow-none): the new persistent hostname to set, or %NULL to + * clear any existing persistent hostname + * @cancellable: a #GCancellable, or %NULL + * @error: return location for #GError + * + * Requests that the machine's persistent hostname be set to the specified value + * or cleared. + * + * Returns: %TRUE if the request was successful, %FALSE if it failed + * + * Deprecated: 1.22: Use nm_client_save_hostname_async() or GDBusConnection. + **/ +gboolean +nm_client_save_hostname(NMClient * client, + const char * hostname, + GCancellable *cancellable, + GError ** error) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE); + + return _nm_client_dbus_call_sync_void(client, + cancellable, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_INTERFACE_SETTINGS, + "SaveHostname", + g_variant_new("(s)", hostname ?: ""), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); +} + +/** + * nm_client_save_hostname_async: + * @client: the %NMClient + * @hostname: (allow-none): the new persistent hostname to set, or %NULL to + * clear any existing persistent hostname + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Requests that the machine's persistent hostname be set to the specified value + * or cleared. + **/ +void +nm_client_save_hostname_async(NMClient * client, + const char * hostname, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(client, + client, + nm_client_save_hostname_async, + cancellable, + callback, + user_data, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_INTERFACE_SETTINGS, + "SaveHostname", + g_variant_new("(s)", hostname ?: ""), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_client_save_hostname_finish: + * @client: the %NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: return location for #GError + * + * Gets the result of an nm_client_save_hostname_async() call. + * + * Returns: %TRUE if the request was successful, %FALSE if it failed + **/ +gboolean +nm_client_save_hostname_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_save_hostname_async), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/*****************************************************************************/ +/* Devices */ +/*****************************************************************************/ + +/** + * nm_client_get_devices: + * @client: a #NMClient + * + * Gets all the known network devices. Use nm_device_get_type() or the + * NM_IS_DEVICE_XXXX functions to determine what kind of + * device member of the returned array is, and then you may use device-specific + * methods such as nm_device_ethernet_get_hw_address(). + * + * Returns: (transfer none) (element-type NMDevice): a #GPtrArray + * containing all the #NMDevices. The returned array is owned by the + * #NMClient object and should not be modified. + **/ +const GPtrArray * +nm_client_get_devices(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_CLIENT_GET_PRIVATE(client)->nm.property_ao[PROPERTY_AO_IDX_DEVICES]); +} + +/** + * nm_client_get_all_devices: + * @client: a #NMClient + * + * Gets both real devices and device placeholders (eg, software devices which + * do not currently exist, but could be created automatically by NetworkManager + * if one of their NMDevice::ActivatableConnections was activated). Use + * nm_device_is_real() to determine whether each device is a real device or + * a placeholder. + * + * Use nm_device_get_type() or the NM_IS_DEVICE_XXXX() functions to determine + * what kind of device each member of the returned array is, and then you may + * use device-specific methods such as nm_device_ethernet_get_hw_address(). + * + * Returns: (transfer none) (element-type NMDevice): a #GPtrArray + * containing all the #NMDevices. The returned array is owned by the + * #NMClient object and should not be modified. + * + * Since: 1.2 + **/ +const GPtrArray * +nm_client_get_all_devices(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_CLIENT_GET_PRIVATE(client)->nm.property_ao[PROPERTY_AO_IDX_ALL_DEVICES]); +} + +/** + * nm_client_get_device_by_path: + * @client: a #NMClient + * @object_path: the object path to search for + * + * Gets a #NMDevice from a #NMClient. + * + * Returns: (transfer none): the #NMDevice for the given @object_path or %NULL if none is found. + **/ +NMDevice * +nm_client_get_device_by_path(NMClient *client, const char *object_path) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + g_return_val_if_fail(object_path, NULL); + + return _dbobjs_get_nmobj_unpack_visible(client, object_path, NM_TYPE_DEVICE); +} + +/** + * nm_client_get_device_by_iface: + * @client: a #NMClient + * @iface: the interface name to search for + * + * Gets a #NMDevice from a #NMClient. + * + * Returns: (transfer none): the #NMDevice for the given @iface or %NULL if none is found. + **/ +NMDevice * +nm_client_get_device_by_iface(NMClient *client, const char *iface) +{ + const GPtrArray *devices; + guint i; + + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + g_return_val_if_fail(iface, NULL); + + devices = nm_client_get_devices(client); + for (i = 0; i < devices->len; i++) { + NMDevice *candidate = g_ptr_array_index(devices, i); + + if (nm_streq0(nm_device_get_iface(candidate), iface)) + return candidate; + } + + return NULL; +} + +/*****************************************************************************/ +/* Active Connections */ +/*****************************************************************************/ + +/** + * nm_client_get_active_connections: + * @client: a #NMClient + * + * Gets the active connections. + * + * Returns: (transfer none) (element-type NMActiveConnection): a #GPtrArray + * containing all the active #NMActiveConnections. + * The returned array is owned by the client and should not be modified. + **/ +const GPtrArray * +nm_client_get_active_connections(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_CLIENT_GET_PRIVATE(client)->nm.property_ao[PROPERTY_AO_IDX_ACTIVE_CONNECTIONS]); +} + +/** + * nm_client_get_primary_connection: + * @client: an #NMClient + * + * Gets the #NMActiveConnection corresponding to the primary active + * network device. + * + * In particular, when there is no VPN active, or the VPN does not + * have the default route, this returns the active connection that has + * the default route. If there is a VPN active with the default route, + * then this function returns the active connection that contains the + * route to the VPN endpoint. + * + * If there is no default route, or the default route is over a + * non-NetworkManager-recognized device, this will return %NULL. + * + * Returns: (transfer none): the appropriate #NMActiveConnection, if + * any + */ +NMActiveConnection * +nm_client_get_primary_connection(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return nml_dbus_property_o_get_obj( + &NM_CLIENT_GET_PRIVATE(client)->nm.property_o[PROPERTY_O_IDX_NM_PRIMAY_CONNECTION]); +} + +/** + * nm_client_get_activating_connection: + * @client: an #NMClient + * + * Gets the #NMActiveConnection corresponding to a + * currently-activating connection that is expected to become the new + * #NMClient:primary-connection upon successful activation. + * + * Returns: (transfer none): the appropriate #NMActiveConnection, if + * any. + */ +NMActiveConnection * +nm_client_get_activating_connection(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return nml_dbus_property_o_get_obj( + &NM_CLIENT_GET_PRIVATE(client)->nm.property_o[PROPERTY_O_IDX_NM_ACTIVATING_CONNECTION]); +} + +/*****************************************************************************/ + +static void +activate_connection_cb(GObject *object, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object GTask *task = user_data; + gs_unref_variant GVariant *ret = NULL; + const char * v_active_connection; + GError * error = NULL; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), result, &error); + if (!ret) { + if (!nm_utils_error_is_cancelled(error)) + g_dbus_error_strip_remote_error(error); + g_task_return_error(task, error); + return; + } + + g_variant_get(ret, "(&o)", &v_active_connection); + + _request_wait_start(g_steal_pointer(&task), + "ActivateConnection", + NM_TYPE_ACTIVE_CONNECTION, + v_active_connection, + NULL); +} + +/** + * nm_client_activate_connection_async: + * @client: a #NMClient + * @connection: (allow-none): an #NMConnection + * @device: (allow-none): the #NMDevice + * @specific_object: (allow-none): the object path of a connection-type-specific + * object this activation should use. This parameter is currently ignored for + * wired and mobile broadband connections, and the value of %NULL should be used + * (ie, no specific object). For Wi-Fi or WiMAX connections, pass the object + * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can + * get using nm_object_get_path(), and which will be used to complete the + * details of the newly added connection. + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the activation has started + * @user_data: caller-specific data passed to @callback + * + * Asynchronously starts a connection to a particular network using the + * configuration settings from @connection and the network device @device. + * Certain connection types also take a "specific object" which is the object + * path of a connection- specific object, like an #NMAccessPoint for Wi-Fi + * connections, or an #NMWimaxNsp for WiMAX connections, to which you wish to + * connect. If the specific object is not given, NetworkManager can, in some + * cases, automatically determine which network to connect to given the settings + * in @connection. + * + * If @connection is not given for a device-based activation, NetworkManager + * picks the best available connection for the device and activates it. + * + * Note that the callback is invoked when NetworkManager has started activating + * the new connection, not when it finishes. You can use the returned + * #NMActiveConnection object (in particular, #NMActiveConnection:state) to + * track the activation to its completion. + **/ +void +nm_client_activate_connection_async(NMClient * client, + NMConnection * connection, + NMDevice * device, + const char * specific_object, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + const char *arg_connection = NULL; + const char *arg_device = NULL; + + g_return_if_fail(NM_IS_CLIENT(client)); + + if (connection) { + g_return_if_fail(NM_IS_CONNECTION(connection)); + arg_connection = nm_connection_get_path(connection); + g_return_if_fail(arg_connection); + } + + if (device) { + g_return_if_fail(NM_IS_DEVICE(device)); + arg_device = nm_object_get_path(NM_OBJECT(device)); + g_return_if_fail(arg_device); + } + + NML_NMCLIENT_LOG_T( + client, + "ActivateConnection() for connection \"%s\", device \"%s\", specific_object \"%s", + arg_connection ?: "/", + arg_device ?: "/", + specific_object ?: "/"); + + _nm_client_dbus_call( + client, + client, + nm_client_activate_connection_async, + cancellable, + callback, + user_data, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "ActivateConnection", + g_variant_new("(ooo)", arg_connection ?: "/", arg_device ?: "/", specific_object ?: "/"), + G_VARIANT_TYPE("(o)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + activate_connection_cb); +} + +/** + * nm_client_activate_connection_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_activate_connection_async(). + * + * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMActiveConnection * +nm_client_activate_connection_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + return NM_ACTIVE_CONNECTION( + _request_wait_finish(client, result, nm_client_activate_connection_async, NULL, error)); +} + +/*****************************************************************************/ + +static void +_add_and_activate_connection_done(GObject * object, + GAsyncResult *result, + gboolean use_add_and_activate_v2, + GTask * task_take) +{ + _nm_unused gs_unref_object GTask *task = task_take; + gs_unref_variant GVariant *ret = NULL; + GError * error = NULL; + gs_unref_variant GVariant *v_result = NULL; + const char * v_active_connection; + const char * v_path; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), result, &error); + if (!ret) { + if (!nm_utils_error_is_cancelled(error)) + g_dbus_error_strip_remote_error(error); + g_task_return_error(task, error); + return; + } + + if (use_add_and_activate_v2) { + g_variant_get(ret, "(&o&o@a{sv})", &v_path, &v_active_connection, &v_result); + } else { + g_variant_get(ret, "(&o&o)", &v_path, &v_active_connection); + } + + _request_wait_start(g_steal_pointer(&task), + "AddAndActivateConnection", + NM_TYPE_ACTIVE_CONNECTION, + v_active_connection, + g_steal_pointer(&v_result)); +} + +static void +_add_and_activate_connection_v1_cb(GObject *object, GAsyncResult *result, gpointer user_data) +{ + _add_and_activate_connection_done(object, result, FALSE, user_data); +} + +static void +_add_and_activate_connection_v2_cb(GObject *object, GAsyncResult *result, gpointer user_data) +{ + _add_and_activate_connection_done(object, result, TRUE, user_data); +} + +static void +_add_and_activate_connection(NMClient * self, + gboolean is_v2, + NMConnection * partial, + NMDevice * device, + const char * specific_object, + GVariant * options, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVariant * arg_connection = NULL; + gboolean use_add_and_activate_v2 = FALSE; + const char *arg_device = NULL; + gpointer source_tag; + + g_return_if_fail(NM_IS_CLIENT(self)); + g_return_if_fail(!partial || NM_IS_CONNECTION(partial)); + + if (device) { + g_return_if_fail(NM_IS_DEVICE(device)); + arg_device = nm_object_get_path(NM_OBJECT(device)); + g_return_if_fail(arg_device); + } + + if (partial) + arg_connection = nm_connection_to_dbus(partial, NM_CONNECTION_SERIALIZE_ALL); + if (!arg_connection) + arg_connection = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + + if (is_v2) { + if (!options) + options = g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0); + use_add_and_activate_v2 = TRUE; + source_tag = nm_client_add_and_activate_connection2; + } else { + if (options) { + if (g_variant_n_children(options) > 0) + use_add_and_activate_v2 = TRUE; + else + nm_clear_pointer(&options, nm_g_variant_unref_floating); + } + source_tag = nm_client_add_and_activate_connection_async; + } + + NML_NMCLIENT_LOG_D(self, "AddAndActivateConnection() started..."); + + if (use_add_and_activate_v2) { + _nm_client_dbus_call(self, + self, + source_tag, + cancellable, + callback, + user_data, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "AddAndActivateConnection2", + g_variant_new("(@a{sa{sv}}oo@a{sv})", + arg_connection, + arg_device ?: "/", + specific_object ?: "/", + options), + G_VARIANT_TYPE("(ooa{sv})"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + _add_and_activate_connection_v2_cb); + } else { + _nm_client_dbus_call(self, + self, + source_tag, + cancellable, + callback, + user_data, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "AddAndActivateConnection", + g_variant_new("(@a{sa{sv}}oo)", + arg_connection, + arg_device ?: "/", + specific_object ?: "/"), + G_VARIANT_TYPE("(oo)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + _add_and_activate_connection_v1_cb); + } +} + +/** + * nm_client_add_and_activate_connection_async: + * @client: a #NMClient + * @partial: (allow-none): an #NMConnection to add; the connection may be + * partially filled (or even %NULL) and will be completed by NetworkManager + * using the given @device and @specific_object before being added + * @device: the #NMDevice + * @specific_object: (allow-none): the object path of a connection-type-specific + * object this activation should use. This parameter is currently ignored for + * wired and mobile broadband connections, and the value of %NULL should be used + * (ie, no specific object). For Wi-Fi or WiMAX connections, pass the object + * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can + * get using nm_object_get_path(), and which will be used to complete the + * details of the newly added connection. + * If the variant is floating, it will be consumed. + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the activation has started + * @user_data: caller-specific data passed to @callback + * + * Adds a new connection using the given details (if any) as a template, + * automatically filling in missing settings with the capabilities of the given + * device and specific object. The new connection is then asynchronously + * activated as with nm_client_activate_connection_async(). Cannot be used for + * VPN connections at this time. + * + * Note that the callback is invoked when NetworkManager has started activating + * the new connection, not when it finishes. You can used the returned + * #NMActiveConnection object (in particular, #NMActiveConnection:state) to + * track the activation to its completion. + **/ +void +nm_client_add_and_activate_connection_async(NMClient * client, + NMConnection * partial, + NMDevice * device, + const char * specific_object, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + _add_and_activate_connection(client, + FALSE, + partial, + device, + specific_object, + NULL, + cancellable, + callback, + user_data); +} + +/** + * nm_client_add_and_activate_connection_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_add_and_activate_connection_async(). + * + * You can call nm_active_connection_get_connection() on the returned + * #NMActiveConnection to find the path of the created #NMConnection. + * + * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMActiveConnection * +nm_client_add_and_activate_connection_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + return NM_ACTIVE_CONNECTION(_request_wait_finish(client, + result, + nm_client_add_and_activate_connection_async, + NULL, + error)); +} + +/** + * nm_client_add_and_activate_connection2: + * @client: a #NMClient + * @partial: (allow-none): an #NMConnection to add; the connection may be + * partially filled (or even %NULL) and will be completed by NetworkManager + * using the given @device and @specific_object before being added + * @device: the #NMDevice + * @specific_object: (allow-none): the object path of a connection-type-specific + * object this activation should use. This parameter is currently ignored for + * wired and mobile broadband connections, and the value of %NULL should be used + * (i.e., no specific object). For Wi-Fi or WiMAX connections, pass the object + * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can + * get using nm_object_get_path(), and which will be used to complete the + * details of the newly added connection. + * @options: a #GVariant containing a dictionary with options, or %NULL + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the activation has started + * @user_data: caller-specific data passed to @callback + * + * Adds a new connection using the given details (if any) as a template, + * automatically filling in missing settings with the capabilities of the given + * device and specific object. The new connection is then asynchronously + * activated as with nm_client_activate_connection_async(). Cannot be used for + * VPN connections at this time. + * + * Note that the callback is invoked when NetworkManager has started activating + * the new connection, not when it finishes. You can used the returned + * #NMActiveConnection object (in particular, #NMActiveConnection:state) to + * track the activation to its completion. + * + * This is identical to nm_client_add_and_activate_connection_async() but takes + * a further @options parameter. Currently, the following options are supported + * by the daemon: + * * "persist": A string describing how the connection should be stored. + * The default is "disk", but it can be modified to "memory" (until + * the daemon quits) or "volatile" (will be deleted on disconnect). + * * "bind-activation": Bind the connection lifetime to something. The default is "none", + * meaning an explicit disconnect is needed. The value "dbus-client" + * means the connection will automatically be deactivated when the calling + * D-Bus client disappears from the system bus. + * + * Since: 1.16 + **/ +void +nm_client_add_and_activate_connection2(NMClient * client, + NMConnection * partial, + NMDevice * device, + const char * specific_object, + GVariant * options, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + _add_and_activate_connection(client, + TRUE, + partial, + device, + specific_object, + options, + cancellable, + callback, + user_data); +} + +/** + * nm_client_add_and_activate_connection2_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * @out_result: (allow-none) (transfer full): the output result + * of type "a{sv}" returned by D-Bus' AddAndActivate2 call. Currently, no + * output is implemented yet. + * + * Gets the result of a call to nm_client_add_and_activate_connection2(). + * + * You can call nm_active_connection_get_connection() on the returned + * #NMActiveConnection to find the path of the created #NMConnection. + * + * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMActiveConnection * +nm_client_add_and_activate_connection2_finish(NMClient * client, + GAsyncResult *result, + GVariant ** out_result, + GError ** error) +{ + return NM_ACTIVE_CONNECTION(_request_wait_finish(client, + result, + nm_client_add_and_activate_connection2, + out_result, + error)); +} + +/*****************************************************************************/ + +/** + * nm_client_deactivate_connection: + * @client: a #NMClient + * @active: the #NMActiveConnection to deactivate + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Deactivates an active #NMActiveConnection. + * + * Returns: success or failure + * + * Deprecated: 1.22: Use nm_client_deactivate_connection_async() or GDBusConnection. + **/ +gboolean +nm_client_deactivate_connection(NMClient * client, + NMActiveConnection *active, + GCancellable * cancellable, + GError ** error) +{ + const char *active_path; + + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(active), FALSE); + + active_path = nm_object_get_path(NM_OBJECT(active)); + g_return_val_if_fail(active_path, FALSE); + + return _nm_client_dbus_call_sync_void(client, + cancellable, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "DeactivateConnection", + g_variant_new("(o)", active_path), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); +} + +/** + * nm_client_deactivate_connection_async: + * @client: a #NMClient + * @active: the #NMActiveConnection to deactivate + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the deactivation has completed + * @user_data: caller-specific data passed to @callback + * + * Asynchronously deactivates an active #NMActiveConnection. + **/ +void +nm_client_deactivate_connection_async(NMClient * client, + NMActiveConnection *active, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + const char *active_path; + + g_return_if_fail(NM_IS_CLIENT(client)); + g_return_if_fail(NM_IS_ACTIVE_CONNECTION(active)); + + active_path = nm_object_get_path(NM_OBJECT(active)); + g_return_if_fail(active_path); + + _nm_client_dbus_call(client, + client, + nm_client_deactivate_connection_async, + cancellable, + callback, + user_data, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "DeactivateConnection", + g_variant_new("(o)", active_path), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_client_deactivate_connection_finish: + * @client: a #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_deactivate_connection_async(). + * + * Returns: success or failure + **/ +gboolean +nm_client_deactivate_connection_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_deactivate_connection_async), + FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/*****************************************************************************/ +/* Connections */ +/*****************************************************************************/ + +/** + * nm_client_get_connections: + * @client: the %NMClient + * + * Returns: (transfer none) (element-type NMRemoteConnection): an array + * containing all connections provided by the remote settings service. The + * returned array is owned by the #NMClient object and should not be modified. + * + * The connections are as received from D-Bus and might not validate according + * to nm_connection_verify(). + **/ +const GPtrArray * +nm_client_get_connections(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_CLIENT_GET_PRIVATE(client)->settings.connections); +} + +/** + * nm_client_get_connection_by_id: + * @client: the %NMClient + * @id: the id of the remote connection + * + * Returns the first matching %NMRemoteConnection matching a given @id. + * + * Returns: (transfer none): the remote connection object on success, or %NULL if no + * matching object was found. + * + * The connection is as received from D-Bus and might not validate according + * to nm_connection_verify(). + **/ +NMRemoteConnection * +nm_client_get_connection_by_id(NMClient *client, const char *id) +{ + const GPtrArray *arr; + guint i; + + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + g_return_val_if_fail(id, NULL); + + arr = nm_client_get_connections(client); + for (i = 0; i < arr->len; i++) { + NMRemoteConnection *c = NM_REMOTE_CONNECTION(arr->pdata[i]); + + if (nm_streq0(id, nm_connection_get_id(NM_CONNECTION(c)))) + return c; + } + return NULL; +} + +/** + * nm_client_get_connection_by_path: + * @client: the %NMClient + * @path: the D-Bus object path of the remote connection + * + * Returns the %NMRemoteConnection representing the connection at @path. + * + * Returns: (transfer none): the remote connection object on success, or %NULL if the object was + * not known + * + * The connection is as received from D-Bus and might not validate according + * to nm_connection_verify(). + **/ +NMRemoteConnection * +nm_client_get_connection_by_path(NMClient *client, const char *path) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + g_return_val_if_fail(path != NULL, NULL); + + return _dbobjs_get_nmobj_unpack_visible(client, path, NM_TYPE_REMOTE_CONNECTION); +} + +/** + * nm_client_get_connection_by_uuid: + * @client: the %NMClient + * @uuid: the UUID of the remote connection + * + * Returns the %NMRemoteConnection identified by @uuid. + * + * Returns: (transfer none): the remote connection object on success, or %NULL if the object was + * not known + * + * The connection is as received from D-Bus and might not validate according + * to nm_connection_verify(). + **/ +NMRemoteConnection * +nm_client_get_connection_by_uuid(NMClient *client, const char *uuid) +{ + const GPtrArray *arr; + guint i; + + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + g_return_val_if_fail(uuid, NULL); + + arr = nm_client_get_connections(client); + for (i = 0; i < arr->len; i++) { + NMRemoteConnection *c = NM_REMOTE_CONNECTION(arr->pdata[i]); + + if (nm_streq0(uuid, nm_connection_get_uuid(NM_CONNECTION(c)))) + return c; + } + return NULL; +} + +/*****************************************************************************/ + +static void +_add_connection_cb(GObject * source, + GAsyncResult *result, + gboolean with_extra_arg, + gpointer user_data) +{ + gs_unref_variant GVariant *ret = NULL; + gs_unref_object GTask *task = user_data; + gs_unref_variant GVariant *v_result = NULL; + const char * v_path; + GError * error = NULL; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error); + if (!ret) { + if (!nm_utils_error_is_cancelled(error)) + g_dbus_error_strip_remote_error(error); + g_task_return_error(task, error); + return; + } + + if (with_extra_arg) { + g_variant_get(ret, "(&o@a{sv})", &v_path, &v_result); + } else { + g_variant_get(ret, "(&o)", &v_path); + } + + _request_wait_start(g_steal_pointer(&task), + "AddConnection", + NM_TYPE_REMOTE_CONNECTION, + v_path, + g_steal_pointer(&v_result)); +} + +static void +_add_connection_cb_without_extra_result(GObject *object, GAsyncResult *result, gpointer user_data) +{ + _add_connection_cb(object, result, FALSE, user_data); +} + +static void +_add_connection_cb_with_extra_result(GObject *object, GAsyncResult *result, gpointer user_data) +{ + _add_connection_cb(object, result, TRUE, user_data); +} + +static void +_add_connection_call(NMClient * self, + gpointer source_tag, + gboolean ignore_out_result, + GVariant * settings, + NMSettingsAddConnection2Flags flags, + GVariant * args, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(self)); + g_return_if_fail(!settings || g_variant_is_of_type(settings, G_VARIANT_TYPE("a{sa{sv}}"))); + g_return_if_fail(!args || g_variant_is_of_type(args, G_VARIANT_TYPE("a{sv}"))); + + NML_NMCLIENT_LOG_D(self, "AddConnection() started..."); + + if (!settings) + settings = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + + /* Although AddConnection2() being capable to handle also AddConnection() and + * AddConnectionUnsaved() variants, we prefer to use the old D-Bus methods when + * they are sufficient. The reason is that libnm should avoid hard dependencies + * on 1.20 API whenever possible. */ + if (ignore_out_result && flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK) { + _nm_client_dbus_call(self, + self, + source_tag, + cancellable, + callback, + user_data, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_INTERFACE_SETTINGS, + "AddConnection", + g_variant_new("(@a{sa{sv}})", settings), + G_VARIANT_TYPE("(o)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + _add_connection_cb_without_extra_result); + } else if (ignore_out_result && flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY) { + _nm_client_dbus_call(self, + self, + source_tag, + cancellable, + callback, + user_data, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_INTERFACE_SETTINGS, + "AddConnectionUnsaved", + g_variant_new("(@a{sa{sv}})", settings), + G_VARIANT_TYPE("(o)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + _add_connection_cb_without_extra_result); + } else { + _nm_client_dbus_call( + self, + self, + source_tag, + cancellable, + callback, + user_data, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_INTERFACE_SETTINGS, + "AddConnection2", + g_variant_new("(@a{sa{sv}}u@a{sv})", + settings, + (guint32) flags, + args ?: g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0)), + G_VARIANT_TYPE("(oa{sv})"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + _add_connection_cb_with_extra_result); + } +} + +/** + * nm_client_add_connection_async: + * @client: the %NMClient + * @connection: the connection to add. Note that this object's settings will be + * added, not the object itself + * @save_to_disk: whether to immediately save the connection to disk + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Requests that the remote settings service add the given settings to a new + * connection. If @save_to_disk is %TRUE, the connection is immediately written + * to disk; otherwise it is initially only stored in memory, but may be saved + * later by calling the connection's nm_remote_connection_commit_changes() + * method. + * + * @connection is untouched by this function and only serves as a template of + * the settings to add. The #NMRemoteConnection object that represents what + * NetworkManager actually added is returned to @callback when the addition + * operation is complete. + * + * Note that the #NMRemoteConnection returned in @callback may not contain + * identical settings to @connection as NetworkManager may perform automatic + * completion and/or normalization of connection properties. + **/ +void +nm_client_add_connection_async(NMClient * client, + NMConnection * connection, + gboolean save_to_disk, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CONNECTION(connection)); + + _add_connection_call(client, + nm_client_add_connection_async, + TRUE, + nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL), + save_to_disk ? NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK + : NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY, + NULL, + cancellable, + callback, + user_data); +} + +/** + * nm_client_add_connection_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_add_connection_async(). + * + * Returns: (transfer full): the new #NMRemoteConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMRemoteConnection * +nm_client_add_connection_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + return NM_REMOTE_CONNECTION( + _request_wait_finish(client, result, nm_client_add_connection_async, NULL, error)); +} + +/** + * nm_client_add_connection2: + * @client: the %NMClient + * @settings: the "a{sa{sv}}" #GVariant with the content of the setting. + * @flags: the %NMSettingsAddConnection2Flags argument. + * @args: (allow-none): the "a{sv}" #GVariant with extra argument or %NULL + * for no extra arguments. + * @ignore_out_result: this function wraps AddConnection2(), which has an + * additional result "a{sv}" output parameter. By setting this to %TRUE, + * you signal that you are not interested in that output parameter. + * This allows the function to fall back to AddConnection() and AddConnectionUnsaved(), + * which is interesting if you run against an older server version that does + * not yet provide AddConnection2(). By setting this to %FALSE, the function + * under the hood always calls AddConnection2(). + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Call AddConnection2() D-Bus API asynchronously. + * + * Since: 1.20 + **/ +void +nm_client_add_connection2(NMClient * client, + GVariant * settings, + NMSettingsAddConnection2Flags flags, + GVariant * args, + gboolean ignore_out_result, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + _add_connection_call(client, + nm_client_add_connection2, + ignore_out_result, + settings, + flags, + args, + cancellable, + callback, + user_data); +} + +/** + * nm_client_add_connection2_finish: + * @client: the #NMClient + * @result: the #GAsyncResult + * @out_result: (allow-none) (transfer full) (out): the output #GVariant + * from AddConnection2(). + * If you care about the output result, then the "ignore_out_result" + * parameter of nm_client_add_connection2() must not be set to %TRUE. + * @error: (allow-none): the error argument. + * + * Returns: (transfer full): on success, a pointer to the added + * #NMRemoteConnection. + * + * Since: 1.20 + */ +NMRemoteConnection * +nm_client_add_connection2_finish(NMClient * client, + GAsyncResult *result, + GVariant ** out_result, + GError ** error) +{ + return NM_REMOTE_CONNECTION( + _request_wait_finish(client, result, nm_client_add_connection2, out_result, error)); +} + +/*****************************************************************************/ + +/** + * nm_client_load_connections: + * @client: the %NMClient + * @filenames: (array zero-terminated=1): %NULL-terminated array of filenames to load + * @failures: (out) (transfer full): on return, a %NULL-terminated array of + * filenames that failed to load + * @cancellable: a #GCancellable, or %NULL + * @error: return location for #GError + * + * Requests that the remote settings service load or reload the given files, + * adding or updating the connections described within. + * + * The changes to the indicated files will not yet be reflected in + * @client's connections array when the function returns. + * + * If all of the indicated files were successfully loaded, the + * function will return %TRUE, and @failures will be set to %NULL. If + * NetworkManager tried to load the files, but some (or all) failed, + * then @failures will be set to a %NULL-terminated array of the + * filenames that failed to load. + * + * Returns: %TRUE on success. + * + * Warning: before libnm 1.22, the boolean return value was inconsistent. + * That is made worse, because when running against certain server versions + * before 1.20, the server would return wrong values for success/failure. + * This means, if you use this function in libnm before 1.22, you are advised + * to ignore the boolean return value and only look at @failures and @error. + * With libnm >= 1.22, the boolean return value corresponds to whether @error was + * set. Note that even in the success case, you might have individual @failures. + * With 1.22, the return value is consistent with nm_client_load_connections_finish(). + * + * Deprecated: 1.22: Use nm_client_load_connections_async() or GDBusConnection. + **/ +gboolean +nm_client_load_connections(NMClient * client, + char ** filenames, + char *** failures, + GCancellable *cancellable, + GError ** error) +{ + gs_unref_variant GVariant *ret = NULL; + + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE); + + ret = _nm_client_dbus_call_sync(client, + cancellable, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_INTERFACE_SETTINGS, + "LoadConnections", + g_variant_new("(^as)", filenames ?: NM_PTRARRAY_EMPTY(char *)), + G_VARIANT_TYPE("(bas)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); + if (!ret) { + *failures = NULL; + return FALSE; + } + + g_variant_get(ret, "(b^as)", NULL, &failures); + + return TRUE; +} + +/** + * nm_client_load_connections_async: + * @client: the %NMClient + * @filenames: (array zero-terminated=1): %NULL-terminated array of filenames to load + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Requests that the remote settings service asynchronously load or reload the + * given files, adding or updating the connections described within. + * + * See nm_client_load_connections() for more details. + **/ +void +nm_client_load_connections_async(NMClient * client, + char ** filenames, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(client, + client, + nm_client_load_connections_async, + cancellable, + callback, + user_data, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_INTERFACE_SETTINGS, + "LoadConnections", + g_variant_new("(^as)", filenames ?: NM_PTRARRAY_EMPTY(char *)), + G_VARIANT_TYPE("(bas)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_variant_strip_dbus_error_cb); +} + +/** + * nm_client_load_connections_finish: + * @client: the %NMClient + * @failures: (out) (transfer full) (array zero-terminated=1): on return, a + * %NULL-terminated array of filenames that failed to load + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of an nm_client_load_connections_async() call. + + * See nm_client_load_connections() for more details. + * + * Returns: %TRUE on success. + * Note that even in the success case, you might have individual @failures. + **/ +gboolean +nm_client_load_connections_finish(NMClient * client, + char *** failures, + GAsyncResult *result, + GError ** error) +{ + gs_unref_variant GVariant *ret = NULL; + + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_load_connections_async), + FALSE); + + ret = g_task_propagate_pointer(G_TASK(result), error); + if (!ret) { + *failures = NULL; + return FALSE; + } + + g_variant_get(ret, "(b^as)", NULL, &failures); + + return TRUE; +} + +/** + * nm_client_reload_connections: + * @client: the #NMClient + * @cancellable: a #GCancellable, or %NULL + * @error: return location for #GError + * + * Requests that the remote settings service reload all connection + * files from disk, adding, updating, and removing connections until + * the in-memory state matches the on-disk state. + * + * Return value: %TRUE on success, %FALSE on failure + * + * Deprecated: 1.22: Use nm_client_reload_connections_async() or GDBusConnection. + **/ +gboolean +nm_client_reload_connections(NMClient *client, GCancellable *cancellable, GError **error) +{ + gs_unref_variant GVariant *ret = NULL; + + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE); + + ret = _nm_client_dbus_call_sync(client, + cancellable, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_INTERFACE_SETTINGS, + "ReloadConnections", + g_variant_new("()"), + G_VARIANT_TYPE("(b)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); + if (!ret) + return FALSE; + + return TRUE; +} + +/** + * nm_client_reload_connections_async: + * @client: the #NMClient + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the reload operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Requests that the remote settings service begin reloading all connection + * files from disk, adding, updating, and removing connections until the + * in-memory state matches the on-disk state. + **/ +void +nm_client_reload_connections_async(NMClient * client, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(client, + client, + nm_client_reload_connections_async, + cancellable, + callback, + user_data, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_INTERFACE_SETTINGS, + "ReloadConnections", + g_variant_new("()"), + G_VARIANT_TYPE("(b)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_variant_strip_dbus_error_cb); +} + +/** + * nm_client_reload_connections_finish: + * @client: the #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: return location for #GError + * + * Gets the result of an nm_client_reload_connections_async() call. + * + * Return value: %TRUE on success, %FALSE on failure + **/ +gboolean +nm_client_reload_connections_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + gs_unref_variant GVariant *ret = NULL; + + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_reload_connections_async), + FALSE); + + ret = g_task_propagate_pointer(G_TASK(result), error); + if (!ret) + return FALSE; + + return TRUE; +} + +/*****************************************************************************/ + +/** + * nm_client_get_dns_mode: + * @client: the #NMClient + * + * Gets the current DNS processing mode. + * + * Return value: the DNS processing mode, or %NULL in case the + * value is not available. + * + * Since: 1.6 + **/ +const char * +nm_client_get_dns_mode(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return NM_CLIENT_GET_PRIVATE(client)->dns_manager.mode; +} + +/** + * nm_client_get_dns_rc_manager: + * @client: the #NMClient + * + * Gets the current DNS resolv.conf manager. + * + * Return value: the resolv.conf manager or %NULL in case the + * value is not available. + * + * Since: 1.6 + **/ +const char * +nm_client_get_dns_rc_manager(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return NM_CLIENT_GET_PRIVATE(client)->dns_manager.rc_manager; +} + +/** + * nm_client_get_dns_configuration: + * @client: a #NMClient + * + * Gets the current DNS configuration + * + * Returns: (transfer none) (element-type NMDnsEntry): a #GPtrArray + * containing #NMDnsEntry elements or %NULL in case the value is not + * available. The returned array is owned by the #NMClient object + * and should not be modified. + * + * Since: 1.6 + **/ +const GPtrArray * +nm_client_get_dns_configuration(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return NM_CLIENT_GET_PRIVATE(client)->dns_manager.configuration; +} + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_dns_manager_configuration(NMClient * self, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMClientPrivate * priv = NM_CLIENT_GET_PRIVATE(self); + gs_unref_ptrarray GPtrArray *configuration_old = NULL; + gs_unref_ptrarray GPtrArray *configuration_new = NULL; + + nm_assert(G_OBJECT(self) == dbobj->nmobj); + + if (value) { + GVariant * entry_var_tmp; + GVariantIter iter; + GPtrArray * array; + + configuration_new = g_ptr_array_new_with_free_func((GDestroyNotify) nm_dns_entry_unref); + + g_variant_iter_init(&iter, value); + while (g_variant_iter_next(&iter, "@a{sv}", &entry_var_tmp)) { + gs_unref_variant GVariant *entry_var = entry_var_tmp; + nm_auto_free_variant_iter GVariantIter *iterp_nameservers = NULL; + nm_auto_free_variant_iter GVariantIter *iterp_domains = NULL; + gs_free char ** nameservers = NULL; + gs_free char ** domains = NULL; + gboolean vpn = FALSE; + NMDnsEntry * entry; + char * interface = NULL; + char * str; + gint32 priority = 0; + + if (!g_variant_lookup(entry_var, "nameservers", "as", &iterp_nameservers) + || !g_variant_lookup(entry_var, "priority", "i", &priority)) { + g_warning("Ignoring invalid DNS configuration"); + continue; + } + + array = g_ptr_array_new(); + while (g_variant_iter_next(iterp_nameservers, "&s", &str)) + g_ptr_array_add(array, str); + g_ptr_array_add(array, NULL); + nameservers = (char **) g_ptr_array_free(array, FALSE); + + if (g_variant_lookup(entry_var, "domains", "as", &iterp_domains)) { + array = g_ptr_array_new(); + while (g_variant_iter_next(iterp_domains, "&s", &str)) + g_ptr_array_add(array, str); + g_ptr_array_add(array, NULL); + domains = (char **) g_ptr_array_free(array, FALSE); + } + + g_variant_lookup(entry_var, "interface", "&s", &interface); + g_variant_lookup(entry_var, "vpn", "b", &vpn); + + entry = nm_dns_entry_new(interface, + (const char *const *) nameservers, + (const char *const *) domains, + priority, + vpn); + if (!entry) { + g_warning("Ignoring invalid DNS entry"); + continue; + } + + g_ptr_array_add(configuration_new, entry); + } + } + + configuration_old = priv->dns_manager.configuration; + priv->dns_manager.configuration = g_steal_pointer(&configuration_new); + + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + +/** + * nm_client_get_capabilities: + * @client: the #NMClient instance + * @length: (out) (allow-none): the number of returned capabilities. + * + * Returns: (transfer none) (array length=length): the + * list of capabilities reported by the server or %NULL + * if the capabilities are unknown. + * The numeric values correspond to #NMCapability enum. + * The array is terminated by a numeric zero sentinel + * at position @length. + * + * Since: 1.24 + */ +const guint32 * +nm_client_get_capabilities(NMClient *client, gsize *length) +{ + NMClientPrivate *priv; + + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + g_return_val_if_fail(length, NULL); + + priv = NM_CLIENT_GET_PRIVATE(client); + + NM_SET_OUT(length, priv->nm.capabilities_len); + return priv->nm.capabilities_arr; +} + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_nm_capabilities(NMClient * self, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + nm_assert(G_OBJECT(self) == dbobj->nmobj); + + nm_clear_g_free(&priv->nm.capabilities_arr); + priv->nm.capabilities_len = 0; + + if (value) { + const guint32 *arr; + gsize len; + + arr = g_variant_get_fixed_array(value, &len, sizeof(guint32)); + priv->nm.capabilities_len = len; + priv->nm.capabilities_arr = g_new(guint32, len + 1); + if (len > 0) + memcpy(priv->nm.capabilities_arr, arr, len * sizeof(guint32)); + priv->nm.capabilities_arr[len] = 0; + } + + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + +/*****************************************************************************/ + +/** + * nm_client_get_checkpoints: + * @client: a #NMClient + * + * Gets all the active checkpoints. + * + * Returns: (transfer none) (element-type NMCheckpoint): a #GPtrArray + * containing all the #NMCheckpoint. The returned array is owned by the + * #NMClient object and should not be modified. + * + * Since: 1.12 + **/ +const GPtrArray * +nm_client_get_checkpoints(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_CLIENT_GET_PRIVATE(client)->nm.property_ao[PROPERTY_AO_IDX_CHECKPOINTS]); +} + +static void +checkpoint_create_cb(GObject *object, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object GTask *task = user_data; + gs_unref_variant GVariant *ret = NULL; + const char * v_checkpoint_path; + GError * error = NULL; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), result, &error); + if (!ret) { + if (!nm_utils_error_is_cancelled(error)) + g_dbus_error_strip_remote_error(error); + g_task_return_error(task, error); + return; + } + + g_variant_get(ret, "(&o)", &v_checkpoint_path); + + _request_wait_start(g_steal_pointer(&task), + "CheckpointCreate", + NM_TYPE_CHECKPOINT, + v_checkpoint_path, + NULL); +} + +/** + * nm_client_checkpoint_create: + * @client: the %NMClient + * @devices: (element-type NMDevice): a list of devices for which a + * checkpoint should be created. + * @rollback_timeout: the rollback timeout in seconds + * @flags: creation flags + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Creates a checkpoint of the current networking configuration + * for given interfaces. An empty @devices argument means all + * devices. If @rollback_timeout is not zero, a rollback is + * automatically performed after the given timeout. + * + * Since: 1.12 + **/ +void +nm_client_checkpoint_create(NMClient * client, + const GPtrArray * devices, + guint32 rollback_timeout, + NMCheckpointCreateFlags flags, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + gs_free const char **paths = NULL; + guint i; + + g_return_if_fail(NM_IS_CLIENT(client)); + + if (devices && devices->len > 0) { + paths = g_new(const char *, devices->len + 1); + for (i = 0; i < devices->len; i++) + paths[i] = nm_object_get_path(NM_OBJECT(devices->pdata[i])); + paths[i] = NULL; + } + + _nm_client_dbus_call( + client, + client, + nm_client_checkpoint_create, + cancellable, + callback, + user_data, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "CheckpointCreate", + g_variant_new("(^aouu)", paths ?: NM_PTRARRAY_EMPTY(const char *), rollback_timeout, flags), + G_VARIANT_TYPE("(o)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + checkpoint_create_cb); +} + +/** + * nm_client_checkpoint_create_finish: + * @client: the #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_checkpoint_create(). + * + * Returns: (transfer full): the new #NMCheckpoint on success, %NULL on + * failure, in which case @error will be set. + * + * Since: 1.12 + **/ +NMCheckpoint * +nm_client_checkpoint_create_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + return NM_CHECKPOINT( + _request_wait_finish(client, result, nm_client_checkpoint_create, NULL, error)); +} + +/** + * nm_client_checkpoint_destroy: + * @client: the %NMClient + * @checkpoint_path: the D-Bus path for the checkpoint + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Destroys an existing checkpoint without performing a rollback. + * + * Since: 1.12 + **/ +void +nm_client_checkpoint_destroy(NMClient * client, + const char * checkpoint_path, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + g_return_if_fail(checkpoint_path && checkpoint_path[0] == '/'); + + _nm_client_dbus_call(client, + client, + nm_client_checkpoint_destroy, + cancellable, + callback, + user_data, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "CheckpointDestroy", + g_variant_new("(o)", checkpoint_path), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_client_checkpoint_destroy_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_checkpoint_destroy(). + * + * Returns: %TRUE on success or %FALSE on failure, in which case + * @error will be set. + * + * Since: 1.12 + **/ +gboolean +nm_client_checkpoint_destroy_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_checkpoint_destroy), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/** + * nm_client_checkpoint_rollback: + * @client: the %NMClient + * @checkpoint_path: the D-Bus path to the checkpoint + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Performs the rollback of a checkpoint before the timeout is reached. + * + * Since: 1.12 + **/ +void +nm_client_checkpoint_rollback(NMClient * client, + const char * checkpoint_path, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + g_return_if_fail(checkpoint_path && checkpoint_path[0] == '/'); + + _nm_client_dbus_call(client, + client, + nm_client_checkpoint_rollback, + cancellable, + callback, + user_data, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "CheckpointRollback", + g_variant_new("(o)", checkpoint_path), + G_VARIANT_TYPE("(a{su})"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_variant_strip_dbus_error_cb); +} + +/** + * nm_client_checkpoint_rollback_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_checkpoint_rollback(). + * + * Returns: (transfer full) (element-type utf8 guint32): an hash table of + * devices and results. Devices are represented by their original + * D-Bus path; each result is a #NMRollbackResult. + * + * Since: 1.12 + **/ +GHashTable * +nm_client_checkpoint_rollback_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + gs_unref_variant GVariant *ret = NULL; + gs_unref_variant GVariant *v_result = NULL; + GVariantIter iter; + GHashTable * hash; + const char * path; + guint32 r; + + g_return_val_if_fail(NM_IS_CLIENT(client), NULL); + g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_checkpoint_rollback), NULL); + + ret = g_task_propagate_pointer(G_TASK(result), error); + if (!ret) + return NULL; + + g_variant_get(ret, "(@a{su})", &v_result); + + hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); + + g_variant_iter_init(&iter, v_result); + while (g_variant_iter_next(&iter, "{&su}", &path, &r)) + g_hash_table_insert(hash, g_strdup(path), GUINT_TO_POINTER(r)); + + return hash; +} + +/** + * nm_client_checkpoint_adjust_rollback_timeout: + * @client: the %NMClient + * @checkpoint_path: a D-Bus path to a checkpoint + * @add_timeout: the timeout in seconds counting from now. + * Set to zero, to disable the timeout. + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Resets the timeout for the checkpoint with path @checkpoint_path + * to @timeout_add. + * + * Since: 1.12 + **/ +void +nm_client_checkpoint_adjust_rollback_timeout(NMClient * client, + const char * checkpoint_path, + guint32 add_timeout, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + g_return_if_fail(checkpoint_path && checkpoint_path[0] == '/'); + + _nm_client_dbus_call(client, + client, + nm_client_checkpoint_adjust_rollback_timeout, + cancellable, + callback, + user_data, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "CheckpointAdjustRollbackTimeout", + g_variant_new("(ou)", checkpoint_path, add_timeout), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_client_checkpoint_adjust_rollback_timeout_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_checkpoint_adjust_rollback_timeout(). + * + * Returns: %TRUE on success or %FALSE on failure. + * + * Since: 1.12 + **/ +gboolean +nm_client_checkpoint_adjust_rollback_timeout_finish(NMClient * client, + GAsyncResult *result, + GError ** error) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail( + nm_g_task_is_valid(result, client, nm_client_checkpoint_adjust_rollback_timeout), + FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/** + * nm_client_reload: + * @client: the %NMClient + * @flags: flags indicating what to reload. + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Reload NetworkManager's configuration and perform certain updates, like + * flushing caches or rewriting external state to disk. This is similar to + * sending SIGHUP to NetworkManager but it allows for more fine-grained control + * over what to reload (see @flags). It also allows non-root access via + * PolicyKit and contrary to signals it is synchronous. + * + * Since: 1.22 + **/ +void +nm_client_reload(NMClient * client, + NMManagerReloadFlags flags, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + + _nm_client_dbus_call(client, + client, + nm_client_reload, + cancellable, + callback, + user_data, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "Reload", + g_variant_new("(u)", (guint32) flags), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_client_reload_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_reload(). + * + * Returns: %TRUE on success or %FALSE on failure. + * + * Since: 1.22 + **/ +gboolean +nm_client_reload_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_reload), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/*****************************************************************************/ + +/** + * nm_client_dbus_call: + * @client: the #NMClient + * @object_path: path of remote object + * @interface_name: D-Bus interface to invoke method on + * @method_name: the name of the method to invoke + * @parameters: (nullable): a #GVariant tuple with parameters for the method + * or %NULL if not passing parameters + * @reply_type: (nullable): the expected type of the reply (which will be a + * tuple), or %NULL + * @timeout_msec: the timeout in milliseconds, -1 to use the default + * timeout or %G_MAXINT for no timeout + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: (nullable): a #GAsyncReadyCallback to call when the request + * is satisfied or %NULL if you don't care about the result of the + * method invocation + * @user_data: the data to pass to @callback + * + * Call g_dbus_connection_call() on the current name owner with the specified + * arguments. Most importantly, this invokes g_dbus_connection_call() with the + * client's #GMainContext, so that the response is always in order with other + * events D-Bus events. Of course, the call uses #GTask and will invoke the + * callback on the current g_main_context_get_thread_default(). + * + * This API is merely a convenient wrapper for g_dbus_connection_call(). You can + * also use g_dbus_connection_call() directly, with the same effect. + * + * Since: 1.24 + **/ +void +nm_client_dbus_call(NMClient * client, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + const GVariantType *reply_type, + int timeout_msec, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + + _nm_client_dbus_call(client, + client, + nm_client_dbus_call, + cancellable, + callback, + user_data, + object_path, + interface_name, + method_name, + parameters, + reply_type, + G_DBUS_CALL_FLAGS_NONE, + timeout_msec == -1 ? NM_DBUS_DEFAULT_TIMEOUT_MSEC : timeout_msec, + nm_dbus_connection_call_finish_variant_cb); +} + +/** + * nm_client_dbus_call_finish: + * @client: the #NMClient instance + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_dbus_call(). + * + * Returns: (transfer full): the result #GVariant or %NULL on error. + * + * Since: 1.24 + **/ +GVariant * +nm_client_dbus_call_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_dbus_call), FALSE); + + return g_task_propagate_pointer(G_TASK(result), error); +} + +/*****************************************************************************/ + +/** + * nm_client_dbus_set_property: + * @client: the #NMClient + * @object_path: path of remote object + * @interface_name: D-Bus interface for the property to set. + * @property_name: the name of the property to set + * @value: a #GVariant with the value to set. + * @timeout_msec: the timeout in milliseconds, -1 to use the default + * timeout or %G_MAXINT for no timeout + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: (nullable): a #GAsyncReadyCallback to call when the request + * is satisfied or %NULL if you don't care about the result of the + * method invocation + * @user_data: the data to pass to @callback + * + * Like nm_client_dbus_call() but calls "Set" on the standard "org.freedesktop.DBus.Properties" + * D-Bus interface. + * + * Since: 1.24 + **/ +void +nm_client_dbus_set_property(NMClient * client, + const char * object_path, + const char * interface_name, + const char * property_name, + GVariant * value, + int timeout_msec, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_CLIENT(client)); + g_return_if_fail(interface_name); + g_return_if_fail(property_name); + g_return_if_fail(value); + + _nm_client_dbus_call(client, + client, + nm_client_dbus_set_property, + cancellable, + callback, + user_data, + object_path, + DBUS_INTERFACE_PROPERTIES, + "Set", + g_variant_new("(ssv)", interface_name, property_name, value), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + timeout_msec == -1 ? NM_DBUS_DEFAULT_TIMEOUT_MSEC : timeout_msec, + nm_dbus_connection_call_finish_void_cb); +} + +/** + * nm_client_dbus_set_property_finish: + * @client: the #NMClient instance + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_dbus_set_property(). + * + * Returns: %TRUE on success or %FALSE on failure. + * + * Since: 1.24 + **/ +gboolean +nm_client_dbus_set_property_finish(NMClient *client, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_dbus_set_property), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/*****************************************************************************/ + +static void +_init_fetch_all(NMClient *self) +{ + NMClientPrivate * priv = NM_CLIENT_GET_PRIVATE(self); + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + + dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context); + + NML_NMCLIENT_LOG_D(self, "fetch all"); + + nm_assert(!priv->get_managed_objects_cancellable); + + priv->get_managed_objects_cancellable = g_cancellable_new(); + + priv->dbsid_nm_object_manager = + nm_dbus_connection_signal_subscribe_object_manager(priv->dbus_connection, + priv->name_owner, + "/org/freedesktop", + NULL, + _dbus_managed_objects_changed_cb, + self, + NULL); + + priv->dbsid_dbus_properties_properties_changed = + nm_dbus_connection_signal_subscribe_properties_changed(priv->dbus_connection, + priv->name_owner, + NULL, + NULL, + _dbus_properties_changed_cb, + self, + NULL); + + priv->dbsid_nm_settings_connection_updated = + g_dbus_connection_signal_subscribe(priv->dbus_connection, + priv->name_owner, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + "Updated", + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + _dbus_settings_updated_cb, + self, + NULL); + + priv->dbsid_nm_connection_active_state_changed = + g_dbus_connection_signal_subscribe(priv->dbus_connection, + priv->name_owner, + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + "StateChanged", + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + _dbus_nm_connection_active_state_changed_cb, + self, + NULL); + + priv->dbsid_nm_vpn_connection_state_changed = + g_dbus_connection_signal_subscribe(priv->dbus_connection, + priv->name_owner, + NM_DBUS_INTERFACE_VPN_CONNECTION, + "VpnStateChanged", + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + _dbus_nm_vpn_connection_state_changed_cb, + self, + NULL); + + priv->dbsid_nm_check_permissions = + g_dbus_connection_signal_subscribe(priv->dbus_connection, + priv->name_owner, + NM_DBUS_INTERFACE, + "CheckPermissions", + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + _dbus_nm_check_permissions_cb, + self, + NULL); + + g_dbus_connection_call(priv->dbus_connection, + priv->name_owner, + "/org/freedesktop", + DBUS_INTERFACE_OBJECT_MANAGER, + "GetManagedObjects", + NULL, + G_VARIANT_TYPE("(a{oa{sa{sv}}})"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + priv->get_managed_objects_cancellable, + _dbus_get_managed_objects_cb, + nm_utils_user_data_pack(self, g_object_ref(priv->context_busy_watcher))); + + _dbus_check_permissions_start(self); +} + +static void +_init_release_all(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + CList ** dbus_objects_lst_heads; + NMLDBusObject * dbobj; + int i; + gboolean permissions_state_changed = FALSE; + + NML_NMCLIENT_LOG_D(self, "release all"); + + nm_clear_g_cancellable(&priv->permissions_cancellable); + nm_clear_g_cancellable(&priv->get_managed_objects_cancellable); + + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->dbsid_nm_object_manager); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, + &priv->dbsid_dbus_properties_properties_changed); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, + &priv->dbsid_nm_settings_connection_updated); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, + &priv->dbsid_nm_connection_active_state_changed); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, + &priv->dbsid_nm_vpn_connection_state_changed); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->dbsid_nm_check_permissions); + + if (priv->permissions_state != NM_TERNARY_DEFAULT) { + priv->permissions_state = NM_TERNARY_DEFAULT; + permissions_state_changed = TRUE; + } + + if (priv->permissions) { + gs_free guint8 *old_permissions = g_steal_pointer(&priv->permissions); + + _emit_permissions_changed(self, old_permissions, NULL); + } + + if (permissions_state_changed) + _notify(self, PROP_PERMISSIONS_STATE); + + nm_assert(c_list_is_empty(&priv->obj_changed_lst_head)); + + dbus_objects_lst_heads = ((CList *[]){ + &priv->dbus_objects_lst_head_on_dbus, + &priv->dbus_objects_lst_head_with_nmobj_not_ready, + &priv->dbus_objects_lst_head_with_nmobj_ready, + NULL, + }); + for (i = 0; dbus_objects_lst_heads[i]; i++) { + c_list_for_each_entry (dbobj, dbus_objects_lst_heads[i], dbus_objects_lst) { + NMLDBusObjIfaceData *db_iface_data; + + nm_assert(c_list_is_empty(&dbobj->obj_changed_lst)); + c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) + db_iface_data->iface_removed = TRUE; + nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_DBUS); + } + } + + _dbus_handle_changes(self, "release-all", FALSE); + + /* We require that when we remove all D-Bus interfaces, that all object will go + * away. Note that a NMLDBusObject can be alive due to a NMLDBusObjWatcher, but + * even those should be all cleaned up. */ + nm_assert(c_list_is_empty(&priv->obj_changed_lst_head)); + nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_watched_only)); + nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_on_dbus)); + nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_with_nmobj_not_ready)); + nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_with_nmobj_ready)); + nm_assert(nm_g_hash_table_size(priv->dbus_objects) == 0); +} + +/*****************************************************************************/ + +static void +name_owner_changed(NMClient *self, const char *name_owner) +{ + NMClientPrivate * priv = NM_CLIENT_GET_PRIVATE(self); + gboolean changed; + gs_free char * old_name_owner_free = NULL; + const char * old_name_owner; + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + + name_owner = nm_str_not_empty(name_owner); + + changed = !nm_streq0(priv->name_owner, name_owner); + + if (!name_owner && priv->main_context != priv->dbus_context) { + gs_unref_object GObject *old_context_busy_watcher = NULL; + + NML_NMCLIENT_LOG_D(self, "resync main context as we have no name owner"); + + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id); + + /* Our instance was initialized synchronously. Usually we must henceforth + * stick to a internal main context. But now we have no name-owner... + * at this point, we anyway are going to do a full resync. Swap the main + * contexts again. */ + + old_context_busy_watcher = g_steal_pointer(&priv->context_busy_watcher); + priv->context_busy_watcher = g_object_ref( + g_object_get_qdata(old_context_busy_watcher, nm_context_busy_watcher_quark())); + + g_main_context_ref(priv->main_context); + g_main_context_unref(priv->dbus_context); + priv->dbus_context = priv->main_context; + + dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context); + + /* we need to sync again... */ + + _assert_main_context_is_current_thread_default(self, dbus_context); + + priv->name_owner_changed_id = + nm_dbus_connection_signal_subscribe_name_owner_changed(priv->dbus_connection, + NM_DBUS_SERVICE, + name_owner_changed_cb, + self, + NULL); + name_owner_get_call(self); + } else + dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context); + + if (changed) { + NML_NMCLIENT_LOG_D(self, + "name owner changed: %s%s%s -> %s%s%s", + NM_PRINT_FMT_QUOTE_STRING(priv->name_owner), + NM_PRINT_FMT_QUOTE_STRING(name_owner)); + old_name_owner_free = priv->name_owner; + priv->name_owner = g_strdup(name_owner); + old_name_owner = old_name_owner_free; + } else + old_name_owner = priv->name_owner; + + if (changed) + _notify(self, PROP_DBUS_NAME_OWNER); + + if (changed && old_name_owner) + _init_release_all(self); + + if (changed && priv->name_owner) + _init_fetch_all(self); + + _set_nm_running(self); + + if (priv->init_data) { + nm_auto_pop_gmaincontext GMainContext *main_context = NULL; + + if (priv->main_context != priv->dbus_context) + main_context = nm_g_main_context_push_thread_default_if_necessary(priv->main_context); + _init_start_check_complete(self); + } +} + +static void +name_owner_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMClient * self = user_data; + NMClientPrivate *priv; + const char * new_owner; + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) + return; + + priv = NM_CLIENT_GET_PRIVATE(self); + if (priv->name_owner_get_cancellable) + return; + + g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_owner); + + name_owner_changed(self, new_owner); +} + +static void +name_owner_get_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + NMClient * self; + NMClientPrivate *priv; + gs_unref_object GObject *context_busy_watcher = NULL; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + const char * name_owner = NULL; + + nm_utils_user_data_unpack(user_data, &self, &context_busy_watcher); + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error); + + if (!ret && nm_utils_error_is_cancelled(error)) + return; + + priv = NM_CLIENT_GET_PRIVATE(self); + + g_clear_object(&priv->name_owner_get_cancellable); + + if (ret) + g_variant_get(ret, "(&s)", &name_owner); + + name_owner_changed(self, name_owner); +} + +static void +name_owner_get_call(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + nm_assert(!priv->name_owner_get_cancellable); + priv->name_owner_get_cancellable = g_cancellable_new(); + + g_dbus_connection_call(priv->dbus_connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetNameOwner", + g_variant_new("(s)", NM_DBUS_SERVICE), + G_VARIANT_TYPE("(s)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + priv->name_owner_get_cancellable, + name_owner_get_cb, + nm_utils_user_data_pack(self, g_object_ref(priv->context_busy_watcher))); +} + +/*****************************************************************************/ + +static inline gboolean +_nml_cleanup_context_busy_watcher_on_idle_cb(gpointer user_data) +{ + nm_auto_unref_gmaincontext GMainContext *context = NULL; + gs_unref_object GObject *context_busy_watcher = NULL; + + nm_utils_user_data_unpack(user_data, &context, &context_busy_watcher); + + nm_assert(context); + nm_assert(G_IS_OBJECT(context_busy_watcher)); + return G_SOURCE_REMOVE; +} + +void +nml_cleanup_context_busy_watcher_on_idle(GObject *context_busy_watcher_take, GMainContext *context) +{ + gs_unref_object GObject *context_busy_watcher = g_steal_pointer(&context_busy_watcher_take); + GSource * cleanup_source; + + nm_assert(G_IS_OBJECT(context_busy_watcher)); + nm_assert(context); + + /* Technically, we cancelled all pending actions (and these actions + * (GTask) keep the context_busy_watcher object alive). Also, we passed + * no destroy notify to g_dbus_connection_signal_subscribe(). + * That means, there should be no other unaccounted GSource'es left. + * + * However, we really need to be sure that the context_busy_watcher's + * lifetime matches the time that the context is busy. That is especially + * important with synchronous initialization, where the context-busy-watcher + * keeps the inner GMainContext integrated in the caller's. + * We must not g_source_destroy() that integration too early. + * + * So to be really sure all this is given, always schedule one last + * cleanup idle action with low priority. This should be the last + * thing related to this instance that keeps the context busy. + * + * Note that we could also *not* take a reference on @context + * and unref @context_busy_watcher via the GDestroyNotify. That would + * allow for the context to be wrapped up early, and when the last user + * gives up the reference to the context, the destroy notify could complete + * without even invoke the idle handler. However, that destroy notify may + * not be called in the right thread. So, we want to be sure that we unref + * the context-busy-watcher in the right context. Hence, we always take an + * additional reference and always cleanup in the idle handler. This means: + * the user *MUST* always keep iterating the context after NMClient got destroyed. + * But that is not a severe limitation, because the user anyway must be prepared + * to do that. That is because in many cases it is necessary anyway (and the user + * wouldn't know a priory when not). This way, it is just always necessary. */ + + cleanup_source = + nm_g_idle_source_new(G_PRIORITY_LOW + 10, + _nml_cleanup_context_busy_watcher_on_idle_cb, + nm_utils_user_data_pack(g_main_context_ref(context), + g_steal_pointer(&context_busy_watcher)), + NULL); + g_source_attach(cleanup_source, context); + g_source_unref(cleanup_source); +} + +/*****************************************************************************/ + +static void +_init_start_complete(NMClient *self, GError *error_take) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + NML_NMCLIENT_LOG_D( + self, + "%s init complete with %s%s%s", + priv->init_data->is_sync ? "sync" : "async", + NM_PRINT_FMT_QUOTED(error_take, "error: ", error_take->message, "", "success")); + + nml_init_data_return(g_steal_pointer(&priv->init_data), error_take); +} + +static void +_init_start_check_complete(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + _assert_main_context_is_current_thread_default(self, main_context); + + if (!priv->init_data) + return; + + if (priv->get_managed_objects_cancellable) { + /* still initializing. Wait. */ + return; + } + +#if NM_MORE_ASSERTS > 10 + { + NMLDBusObject *dbobj; + + c_list_for_each_entry (dbobj, + &priv->dbus_objects_lst_head_with_nmobj_not_ready, + dbus_objects_lst) { + NML_NMCLIENT_LOG_T(self, "init-start waiting for %s", dbobj->dbus_path->str); + break; + } + } +#endif + + if (!c_list_is_empty(&priv->dbus_objects_lst_head_with_nmobj_not_ready)) + return; + + _init_start_complete(self, NULL); +} + +static void +_init_start_cancelled_cb(GCancellable *cancellable, gpointer user_data) +{ + NMClient *self = user_data; + GError * error; + + nm_assert(NM_IS_CLIENT(self)); + nm_assert(NM_CLIENT_GET_PRIVATE(self)->init_data); + nm_assert(NM_CLIENT_GET_PRIVATE(self)->init_data->cancellable == cancellable); + + nm_utils_error_set_cancelled(&error, FALSE, NULL); + _init_start_complete(self, error); +} + +static gboolean +_init_start_cancel_on_idle_cb(gpointer user_data) +{ + NMClient *self = user_data; + GError * error; + + nm_utils_error_set_cancelled(&error, FALSE, NULL); + _init_start_complete(self, error); + return G_SOURCE_CONTINUE; +} + +static void +_init_start_with_bus(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + if (priv->init_data->cancellable) { + priv->init_data->cancelled_id = g_signal_connect(priv->init_data->cancellable, + "cancelled", + G_CALLBACK(_init_start_cancelled_cb), + self); + if (g_cancellable_is_cancelled(priv->init_data->cancellable)) { + priv->init_data->cancel_on_idle_source = g_idle_source_new(); + g_source_set_callback(priv->init_data->cancel_on_idle_source, + _init_start_cancel_on_idle_cb, + self, + NULL); + g_source_attach(priv->init_data->cancel_on_idle_source, priv->main_context); + return; + } + } + + _assert_main_context_is_current_thread_default(self, dbus_context); + + priv->name_owner_changed_id = + nm_dbus_connection_signal_subscribe_name_owner_changed(priv->dbus_connection, + NM_DBUS_SERVICE, + name_owner_changed_cb, + self, + NULL); + name_owner_get_call(self); +} + +static void +_init_start_bus_get_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + NMClient * self = user_data; + NMClientPrivate *priv; + GDBusConnection *dbus_connection; + GError * error = NULL; + + nm_assert(NM_IS_CLIENT(self)); + + dbus_connection = g_bus_get_finish(result, &error); + + if (!dbus_connection) { + _init_start_complete(self, error); + return; + } + + priv = NM_CLIENT_GET_PRIVATE(self); + priv->dbus_connection = dbus_connection; + + _init_start_with_bus(self); + + _notify(self, PROP_DBUS_CONNECTION); +} + +static void +_init_start(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + NML_NMCLIENT_LOG_D(self, + "starting %s initialization...", + priv->init_data->is_sync ? "sync" : "async"); + + if (!priv->dbus_connection) { + g_bus_get(_nm_dbus_bus_type(), priv->init_data->cancellable, _init_start_bus_get_cb, self); + return; + } + + _init_start_with_bus(self); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMClient * self = NM_CLIENT(object); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_INSTANCE_FLAGS: + g_value_set_uint(value, priv->instance_flags); + break; + case PROP_DBUS_CONNECTION: + g_value_set_object(value, priv->dbus_connection); + break; + case PROP_DBUS_NAME_OWNER: + g_value_set_string(value, nm_client_get_dbus_name_owner(self)); + break; + case PROP_NM_RUNNING: + g_value_set_boolean(value, nm_client_get_nm_running(self)); + break; + + /* Manager properties. */ + case PROP_VERSION: + g_value_set_string(value, nm_client_get_version(self)); + break; + case PROP_STATE: + g_value_set_enum(value, nm_client_get_state(self)); + break; + case PROP_STARTUP: + g_value_set_boolean(value, nm_client_get_startup(self)); + break; + case PROP_NETWORKING_ENABLED: + g_value_set_boolean(value, nm_client_networking_get_enabled(self)); + break; + case PROP_WIRELESS_ENABLED: + g_value_set_boolean(value, nm_client_wireless_get_enabled(self)); + break; + case PROP_WIRELESS_HARDWARE_ENABLED: + g_value_set_boolean(value, nm_client_wireless_hardware_get_enabled(self)); + break; + case PROP_WWAN_ENABLED: + g_value_set_boolean(value, nm_client_wwan_get_enabled(self)); + break; + case PROP_WWAN_HARDWARE_ENABLED: + g_value_set_boolean(value, nm_client_wwan_hardware_get_enabled(self)); + break; + case PROP_WIMAX_ENABLED: + g_value_set_boolean(value, FALSE); + break; + case PROP_WIMAX_HARDWARE_ENABLED: + g_value_set_boolean(value, FALSE); + break; + case PROP_ACTIVE_CONNECTIONS: + g_value_take_boxed(value, + _nm_utils_copy_object_array(nm_client_get_active_connections(self))); + break; + case PROP_CONNECTIVITY: + g_value_set_enum(value, nm_client_get_connectivity(self)); + break; + case PROP_CONNECTIVITY_CHECK_AVAILABLE: + g_value_set_boolean(value, nm_client_connectivity_check_get_available(self)); + break; + case PROP_CONNECTIVITY_CHECK_ENABLED: + g_value_set_boolean(value, nm_client_connectivity_check_get_enabled(self)); + break; + case PROP_CONNECTIVITY_CHECK_URI: + g_value_set_string(value, nm_client_connectivity_check_get_uri(self)); + break; + case PROP_PRIMARY_CONNECTION: + g_value_set_object(value, nm_client_get_primary_connection(self)); + break; + case PROP_ACTIVATING_CONNECTION: + g_value_set_object(value, nm_client_get_activating_connection(self)); + break; + case PROP_DEVICES: + g_value_take_boxed(value, _nm_utils_copy_object_array(nm_client_get_devices(self))); + break; + case PROP_METERED: + g_value_set_uint(value, nm_client_get_metered(self)); + break; + case PROP_ALL_DEVICES: + g_value_take_boxed(value, _nm_utils_copy_object_array(nm_client_get_all_devices(self))); + break; + case PROP_CHECKPOINTS: + g_value_take_boxed(value, _nm_utils_copy_object_array(nm_client_get_checkpoints(self))); + break; + case PROP_CAPABILITIES: + { + const guint32 *arr; + GArray * out; + gsize len; + + arr = nm_client_get_capabilities(self, &len); + if (arr) { + out = g_array_new(TRUE, FALSE, sizeof(guint32)); + g_array_append_vals(out, arr, len); + } else + out = NULL; + g_value_take_boxed(value, out); + } break; + case PROP_PERMISSIONS_STATE: + g_value_set_enum(value, priv->permissions_state); + break; + + /* Settings properties. */ + case PROP_CONNECTIONS: + g_value_take_boxed(value, _nm_utils_copy_object_array(nm_client_get_connections(self))); + break; + case PROP_HOSTNAME: + g_value_set_string(value, priv->settings.hostname); + break; + case PROP_CAN_MODIFY: + g_value_set_boolean(value, priv->settings.can_modify); + break; + + /* DNS properties */ + case PROP_DNS_MODE: + g_value_set_string(value, nm_client_get_dns_mode(self)); + break; + case PROP_DNS_RC_MANAGER: + g_value_set_string(value, nm_client_get_dns_rc_manager(self)); + break; + case PROP_DNS_CONFIGURATION: + g_value_take_boxed(value, + _nm_utils_copy_array(nm_client_get_dns_configuration(self), + (NMUtilsCopyFunc) nm_dns_entry_dup, + (GDestroyNotify) nm_dns_entry_unref)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMClient * self = NM_CLIENT(object); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + gboolean b; + guint v_uint; + + switch (prop_id) { + case PROP_INSTANCE_FLAGS: + /* construct */ + + v_uint = g_value_get_uint(value); + g_return_if_fail(!NM_FLAGS_ANY(v_uint, ~((guint) NM_CLIENT_INSTANCE_FLAGS_ALL))); + v_uint &= ((guint) NM_CLIENT_INSTANCE_FLAGS_ALL); + + if (!priv->instance_flags_constructed) { + priv->instance_flags_constructed = TRUE; + priv->instance_flags = v_uint; + nm_assert((guint) priv->instance_flags == v_uint); + } else { + NMClientInstanceFlags flags = v_uint; + + /* After object construction, we only allow to toggle certain flags and + * ignore all other flags. */ + + if ((priv->instance_flags ^ flags) + & NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS) { + if (NM_FLAGS_HAS(flags, NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS)) + priv->instance_flags |= NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS; + else + priv->instance_flags &= ~NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS; + if (priv->dbsid_nm_check_permissions != 0) + _dbus_check_permissions_start(self); + } + } + break; + + case PROP_DBUS_CONNECTION: + /* construct-only */ + priv->dbus_connection = g_value_dup_object(value); + break; + + case PROP_NETWORKING_ENABLED: + b = g_value_get_boolean(value); + if (priv->nm.networking_enabled != b) { + nm_client_networking_set_enabled(self, b, NULL); + /* Let the property value flip when we get the change signal from NM */ + } + break; + case PROP_WIRELESS_ENABLED: + b = g_value_get_boolean(value); + if (priv->nm.wireless_enabled != b) { + nm_client_wireless_set_enabled(self, b); + /* Let the property value flip when we get the change signal from NM */ + } + break; + case PROP_WWAN_ENABLED: + b = g_value_get_boolean(value); + if (priv->nm.wwan_enabled != b) { + nm_client_wwan_set_enabled(self, b); + /* Let the property value flip when we get the change signal from NM */ + } + break; + case PROP_CONNECTIVITY_CHECK_ENABLED: + b = g_value_get_boolean(value); + if (priv->nm.connectivity_check_enabled != b) { + nm_client_connectivity_check_set_enabled(self, b); + /* Let the property value flip when we get the change signal from NM */ + } + break; + case PROP_WIMAX_ENABLED: + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static gboolean +init_sync(GInitable *initable, GCancellable *cancellable, GError **error) +{ + gs_unref_object NMClient *self = NULL; + NMClientPrivate * priv; + GMainContext * dbus_context; + GError * local_error = NULL; + GMainLoop * main_loop; + GObject * parent_context_busy_watcher; + + g_return_val_if_fail(NM_IS_CLIENT(initable), FALSE); + + self = g_object_ref(NM_CLIENT(initable)); /* keep instance alive. */ + + priv = NM_CLIENT_GET_PRIVATE(self); + + g_return_val_if_fail(!priv->dbus_context, FALSE); + + /* when using init_sync(), we use a separate internal GMainContext for + * all D-Bus operations and use our regular async-init code. That means, + * also in sync-init, we don't actually block waiting for our D-Bus requests, + * instead, we only block (g_main_loop_run()) for the overall result. + * + * Doing this has a performance overhead. Also, we cannot ever fall back + * to the regular main-context (not unless we lose the main-owner and + * need to re-initialize). The reason is that we receive events on our + * dbus_context, and this cannot be brought in sync -- short of full + * reinitalizing. Therefor, using sync init not only is slower during + * construction of the object, but NMClient will stick to the dual GMainContext + * mode. + * + * Aside from this downside, the solution is good: + * + * - we don't duplicate the implementation of async-init. + * - we don't iterate the main-context of the caller while waiting for + * initialization to happen + * - we still invoke all changes under the main_context of the caller. + * - all D-Bus events strictly go through dbus_context and are in order. + */ + + dbus_context = g_main_context_new(); + priv->dbus_context = g_main_context_ref(dbus_context); + + /* We have an inner context. Note that if we loose the name owner, we have a chance + * to resync and drop the inner context. That means, requests made against the inner + * context have a different lifetime. Hence, we create a separate tracking + * object. This "wraps" the outer context-busy-watcher and references it, so + * that the work together. Grep for nm_context_busy_watcher_quark() to + * see how this works. */ + parent_context_busy_watcher = g_steal_pointer(&priv->context_busy_watcher); + priv->context_busy_watcher = g_object_new(G_TYPE_OBJECT, NULL); + g_object_set_qdata_full(priv->context_busy_watcher, + nm_context_busy_watcher_quark(), + parent_context_busy_watcher, + g_object_unref); + + g_main_context_push_thread_default(dbus_context); + + main_loop = g_main_loop_new(dbus_context, FALSE); + + priv->init_data = nml_init_data_new_sync(cancellable, main_loop, &local_error); + + _init_start(self); + + g_main_loop_run(main_loop); + + g_main_loop_unref(main_loop); + + g_main_context_pop_thread_default(dbus_context); + + if (priv->main_context != priv->dbus_context) { + nm_context_busy_watcher_integrate_source(priv->main_context, + priv->dbus_context, + priv->context_busy_watcher); + } + + g_main_context_unref(dbus_context); + + if (local_error) { + g_propagate_error(error, local_error); + return FALSE; + } + return TRUE; +} + +/*****************************************************************************/ + +static void +init_async(GAsyncInitable * initable, + int io_priority, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMClientPrivate * priv; + NMClient * self; + nm_auto_pop_gmaincontext GMainContext *context = NULL; + GTask * task; + + g_return_if_fail(NM_IS_CLIENT(initable)); + + self = NM_CLIENT(initable); + priv = NM_CLIENT_GET_PRIVATE(self); + + g_return_if_fail(!priv->dbus_context); + + priv->dbus_context = g_main_context_ref(priv->main_context); + + context = nm_g_main_context_push_thread_default_if_necessary(priv->main_context); + + task = nm_g_task_new(self, cancellable, init_async, callback, user_data); + g_task_set_priority(task, io_priority); + + priv->init_data = nml_init_data_new_async(cancellable, g_steal_pointer(&task)); + + _init_start(self); +} + +static gboolean +init_finish(GAsyncInitable *initable, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_CLIENT(initable), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, initable, init_async), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/*****************************************************************************/ + +static void +nm_client_init(NMClient *self) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + priv->permissions_state = NM_TERNARY_DEFAULT; + + priv->context_busy_watcher = g_object_new(G_TYPE_OBJECT, NULL); + + c_list_init(&self->obj_base.queue_notify_lst); + c_list_init(&priv->queue_notify_lst_head); + c_list_init(&priv->notify_event_lst_head); + + priv->dbus_objects = g_hash_table_new(nm_pdirect_hash, nm_pdirect_equal); + c_list_init(&priv->dbus_objects_lst_head_watched_only); + c_list_init(&priv->dbus_objects_lst_head_on_dbus); + c_list_init(&priv->dbus_objects_lst_head_with_nmobj_not_ready); + c_list_init(&priv->dbus_objects_lst_head_with_nmobj_ready); + c_list_init(&priv->obj_changed_lst_head); +} + +/** + * nm_client_new: + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Creates a new #NMClient. + * + * Note that this will do blocking D-Bus calls to initialize the + * client. You can use nm_client_new_async() if you want to avoid + * that. + * + * Returns: a new #NMClient or NULL on an error + **/ +NMClient * +nm_client_new(GCancellable *cancellable, GError **error) +{ + return g_initable_new(NM_TYPE_CLIENT, cancellable, error, NULL); +} + +/** + * nm_client_new_async: + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to call when the client is created + * @user_data: data for @callback + * + * Creates a new #NMClient and begins asynchronously initializing it. + * @callback will be called when it is done; use + * nm_client_new_finish() to get the result. Note that on an error, + * the callback can be invoked with two first parameters as NULL. + **/ +void +nm_client_new_async(GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) +{ + g_async_initable_new_async(NM_TYPE_CLIENT, + G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data, + NULL); +} + +/** + * nm_client_new_finish: + * @result: a #GAsyncResult + * @error: location for a #GError, or %NULL + * + * Gets the result of an nm_client_new_async() call. + * + * Returns: a new #NMClient, or %NULL on error + **/ +NMClient * +nm_client_new_finish(GAsyncResult *result, GError **error) +{ + gs_unref_object GObject *source_object = NULL; + GObject * object; + + source_object = g_async_result_get_source_object(result); + g_return_val_if_fail(source_object, NULL); + + object = g_async_initable_new_finish(G_ASYNC_INITABLE(source_object), result, error); + g_return_val_if_fail(!object || NM_IS_CLIENT(object), FALSE); + + return NM_CLIENT(object); +} + +static void +constructed(GObject *object) +{ + NMClient * self = NM_CLIENT(object); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + priv->main_context = g_main_context_ref_thread_default(); + + G_OBJECT_CLASS(nm_client_parent_class)->constructed(object); + + NML_NMCLIENT_LOG_D(self, "new NMClient instance"); +} + +static void +dispose(GObject *object) +{ + NMClient * self = NM_CLIENT(object); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + + nm_assert(!priv->init_data); + + self->obj_base.is_disposing = TRUE; + + nm_clear_g_cancellable(&priv->name_owner_get_cancellable); + + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id); + + nm_clear_g_free(&priv->name_owner); + + _init_release_all(self); + + nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_watched_only)); + nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_on_dbus)); + nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_with_nmobj_not_ready)); + nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_with_nmobj_ready)); + + nm_assert(c_list_is_empty(&priv->queue_notify_lst_head)); + nm_assert(c_list_is_empty(&priv->notify_event_lst_head)); + nm_assert(c_list_is_empty(&self->obj_base.queue_notify_lst)); + nm_assert(nm_g_hash_table_size(priv->dbus_objects) == 0); + + nml_dbus_property_o_clear_many(priv->nm.property_o, G_N_ELEMENTS(priv->nm.property_o), NULL); + nml_dbus_property_ao_clear_many(priv->nm.property_ao, G_N_ELEMENTS(priv->nm.property_ao), NULL); + + nm_clear_g_free(&priv->nm.connectivity_check_uri); + nm_clear_g_free(&priv->nm.version); + + nml_dbus_property_ao_clear(&priv->settings.connections, NULL); + nm_clear_g_free(&priv->settings.hostname); + + nm_clear_pointer(&priv->dns_manager.configuration, g_ptr_array_unref); + nm_clear_g_free(&priv->dns_manager.mode); + nm_clear_g_free(&priv->dns_manager.rc_manager); + + nm_clear_pointer(&priv->dbus_objects, g_hash_table_destroy); + + G_OBJECT_CLASS(nm_client_parent_class)->dispose(object); + + nm_clear_pointer(&priv->udev, udev_unref); + + if (priv->context_busy_watcher && priv->dbus_context) { + nml_cleanup_context_busy_watcher_on_idle(g_steal_pointer(&priv->context_busy_watcher), + priv->dbus_context); + } + + nm_clear_pointer(&priv->dbus_context, g_main_context_unref); + nm_clear_pointer(&priv->main_context, g_main_context_unref); + + nm_clear_g_free(&priv->permissions); + + g_clear_object(&priv->dbus_connection); + + g_clear_object(&priv->context_busy_watcher); + + nm_clear_g_free(&priv->name_owner); + + priv->nm.capabilities_len = 0; + nm_clear_g_free(&priv->nm.capabilities_arr); + + NML_NMCLIENT_LOG_D(self, "disposed"); +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_agentmanager = + NML_DBUS_META_IFACE_INIT(NM_DBUS_INTERFACE_AGENT_MANAGER, + NULL, + NML_DBUS_META_INTERFACE_PRIO_NONE, ); + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE, + nm_client_get_type, + NML_DBUS_META_INTERFACE_PRIO_NMCLIENT, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_O_PROP( + "ActivatingConnection", + PROP_ACTIVATING_CONNECTION, + NMClient, + _priv.nm.property_o[PROPERTY_O_IDX_NM_ACTIVATING_CONNECTION], + nm_active_connection_get_type), + NML_DBUS_META_PROPERTY_INIT_AO_PROP( + "ActiveConnections", + PROP_ACTIVE_CONNECTIONS, + NMClient, + _priv.nm.property_ao[PROPERTY_AO_IDX_ACTIVE_CONNECTIONS], + nm_active_connection_get_type, + .notify_changed_ao = _property_ao_notify_changed_active_connections_cb), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("AllDevices", + PROP_ALL_DEVICES, + NMClient, + _priv.nm.property_ao[PROPERTY_AO_IDX_ALL_DEVICES], + nm_device_get_type, + .notify_changed_ao = + _property_ao_notify_changed_all_devices_cb), + NML_DBUS_META_PROPERTY_INIT_FCN("Capabilities", + PROP_CAPABILITIES, + "au", + _notify_update_prop_nm_capabilities, ), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Checkpoints", + PROP_CHECKPOINTS, + NMClient, + _priv.nm.property_ao[PROPERTY_AO_IDX_CHECKPOINTS], + nm_checkpoint_get_type), + NML_DBUS_META_PROPERTY_INIT_U("Connectivity", + PROP_CONNECTIVITY, + NMClient, + _priv.nm.connectivity), + NML_DBUS_META_PROPERTY_INIT_B("ConnectivityCheckAvailable", + PROP_CONNECTIVITY_CHECK_AVAILABLE, + NMClient, + _priv.nm.connectivity_check_available), + NML_DBUS_META_PROPERTY_INIT_B("ConnectivityCheckEnabled", + PROP_CONNECTIVITY_CHECK_ENABLED, + NMClient, + _priv.nm.connectivity_check_enabled), + NML_DBUS_META_PROPERTY_INIT_S("ConnectivityCheckUri", + PROP_CONNECTIVITY_CHECK_URI, + NMClient, + _priv.nm.connectivity_check_uri), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Devices", + PROP_DEVICES, + NMClient, + _priv.nm.property_ao[PROPERTY_AO_IDX_DEVICES], + nm_device_get_type, + .notify_changed_ao = + _property_ao_notify_changed_devices_cb), + NML_DBUS_META_PROPERTY_INIT_IGNORE("GlobalDnsConfiguration", "a{sv}"), + NML_DBUS_META_PROPERTY_INIT_U("Metered", PROP_METERED, NMClient, _priv.nm.metered), + NML_DBUS_META_PROPERTY_INIT_B("NetworkingEnabled", + PROP_NETWORKING_ENABLED, + NMClient, + _priv.nm.networking_enabled), + NML_DBUS_META_PROPERTY_INIT_O_PROP("PrimaryConnection", + PROP_PRIMARY_CONNECTION, + NMClient, + _priv.nm.property_o[PROPERTY_O_IDX_NM_PRIMAY_CONNECTION], + nm_active_connection_get_type), + NML_DBUS_META_PROPERTY_INIT_IGNORE("PrimaryConnectionType", "s"), + NML_DBUS_META_PROPERTY_INIT_B("Startup", PROP_STARTUP, NMClient, _priv.nm.startup), + NML_DBUS_META_PROPERTY_INIT_U("State", PROP_STATE, NMClient, _priv.nm.state), + NML_DBUS_META_PROPERTY_INIT_S("Version", PROP_VERSION, NMClient, _priv.nm.version), + NML_DBUS_META_PROPERTY_INIT_IGNORE("WimaxEnabled", "b"), + NML_DBUS_META_PROPERTY_INIT_IGNORE("WimaxHardwareEnabled", "b"), + NML_DBUS_META_PROPERTY_INIT_B("WirelessEnabled", + PROP_WIRELESS_ENABLED, + NMClient, + _priv.nm.wireless_enabled), + NML_DBUS_META_PROPERTY_INIT_B("WirelessHardwareEnabled", + PROP_WIRELESS_HARDWARE_ENABLED, + NMClient, + _priv.nm.wireless_hardware_enabled), + NML_DBUS_META_PROPERTY_INIT_B("WwanEnabled", + PROP_WWAN_ENABLED, + NMClient, + _priv.nm.wwan_enabled), + NML_DBUS_META_PROPERTY_INIT_B("WwanHardwareEnabled", + PROP_WWAN_HARDWARE_ENABLED, + NMClient, + _priv.nm.wwan_hardware_enabled), ), ); + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_SETTINGS, + nm_client_get_type, + NML_DBUS_META_INTERFACE_PRIO_NMCLIENT, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_B("CanModify", + PROP_CAN_MODIFY, + NMClient, + _priv.settings.can_modify), + NML_DBUS_META_PROPERTY_INIT_AO_PROP( + "Connections", + PROP_CONNECTIONS, + NMClient, + _priv.settings.connections, + nm_remote_connection_get_type, + .notify_changed_ao = _property_ao_notify_changed_connections_cb, + .check_nmobj_visible_fcn = (gboolean(*)(GObject *)) nm_remote_connection_get_visible), + NML_DBUS_META_PROPERTY_INIT_S("Hostname", + PROP_HOSTNAME, + NMClient, + _priv.settings.hostname), ), ); + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dnsmanager = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DNS_MANAGER, + nm_client_get_type, + NML_DBUS_META_INTERFACE_PRIO_NMCLIENT, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_FCN("Configuration", + PROP_DNS_CONFIGURATION, + "aa{sv}", + _notify_update_prop_dns_manager_configuration), + NML_DBUS_META_PROPERTY_INIT_S("Mode", PROP_DNS_MODE, NMClient, _priv.dns_manager.mode), + NML_DBUS_META_PROPERTY_INIT_S("RcManager", + PROP_DNS_RC_MANAGER, + NMClient, + _priv.dns_manager.rc_manager), ), ); + +static void +nm_client_class_init(NMClientClass *client_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(client_class); + + _dbus_path_nm = nm_ref_string_new(NM_DBUS_PATH); + _dbus_path_settings = nm_ref_string_new(NM_DBUS_PATH_SETTINGS); + _dbus_path_dns_manager = nm_ref_string_new(NM_DBUS_PATH_DNS_MANAGER); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->constructed = constructed; + object_class->dispose = dispose; + + /** + * NMClient:dbus-connection: + * + * The #GDBusConnection to use. + * + * If this is not set during object construction, the D-Bus connection will + * automatically be chosen during async/sync initalization via g_bus_get(). + * + * Since: 1.22 + */ + obj_properties[PROP_DBUS_CONNECTION] = g_param_spec_object( + NM_CLIENT_DBUS_CONNECTION, + "", + "", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:instance-flags: + * + * #NMClientInstanceFlags for the instance. These affect behavior of #NMClient. + * This is a construct property and you may only set most flags only during + * construction. + * + * The flag %NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS can be toggled any time, + * even after constructing the instance. Note that you may want to watch NMClient:permissions-state + * property to know whether permissions are ready. Note that permissions are only fetched + * when NMClient has a D-Bus name owner. + * + * Since: 1.24 + */ + obj_properties[PROP_INSTANCE_FLAGS] = g_param_spec_uint( + NM_CLIENT_INSTANCE_FLAGS, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:dbus-name-owner: + * + * The name owner of the NetworkManager D-Bus service. + * + * Since: 1.22 + **/ + obj_properties[PROP_DBUS_NAME_OWNER] = + g_param_spec_string(NM_CLIENT_DBUS_NAME_OWNER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:version: + * + * The NetworkManager version. + **/ + obj_properties[PROP_VERSION] = g_param_spec_string(NM_CLIENT_VERSION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:state: + * + * The current daemon state. + **/ + obj_properties[PROP_STATE] = g_param_spec_enum(NM_CLIENT_STATE, + "", + "", + NM_TYPE_STATE, + NM_STATE_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:startup: + * + * Whether the daemon is still starting up. + **/ + obj_properties[PROP_STARTUP] = g_param_spec_boolean(NM_CLIENT_STARTUP, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:nm-running: + * + * Whether the daemon is running. + **/ + obj_properties[PROP_NM_RUNNING] = + g_param_spec_boolean(NM_CLIENT_NM_RUNNING, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:networking-enabled: + * + * Whether networking is enabled. + * + * The property setter is a synchronous D-Bus call. This is deprecated since 1.22. + */ + obj_properties[PROP_NETWORKING_ENABLED] = + g_param_spec_boolean(NM_CLIENT_NETWORKING_ENABLED, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:wireless-enabled: + * + * Whether wireless is enabled. + * + * The property setter is a synchronous D-Bus call. This is deprecated since 1.22. + **/ + obj_properties[PROP_WIRELESS_ENABLED] = + g_param_spec_boolean(NM_CLIENT_WIRELESS_ENABLED, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:wireless-hardware-enabled: + * + * Whether the wireless hardware is enabled. + **/ + obj_properties[PROP_WIRELESS_HARDWARE_ENABLED] = + g_param_spec_boolean(NM_CLIENT_WIRELESS_HARDWARE_ENABLED, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:wwan-enabled: + * + * Whether WWAN functionality is enabled. + * + * The property setter is a synchronous D-Bus call. This is deprecated since 1.22. + */ + obj_properties[PROP_WWAN_ENABLED] = + g_param_spec_boolean(NM_CLIENT_WWAN_ENABLED, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:wwan-hardware-enabled: + * + * Whether the WWAN hardware is enabled. + **/ + obj_properties[PROP_WWAN_HARDWARE_ENABLED] = + g_param_spec_boolean(NM_CLIENT_WWAN_HARDWARE_ENABLED, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:wimax-enabled: + * + * Whether WiMAX functionality is enabled. + * + * Deprecated: 1.22: WiMAX is no longer supported and this always returns FALSE. The setter has no effect. + */ + obj_properties[PROP_WIMAX_ENABLED] = + g_param_spec_boolean(NM_CLIENT_WIMAX_ENABLED, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:wimax-hardware-enabled: + * + * Whether the WiMAX hardware is enabled. + * + * Deprecated: 1.22: WiMAX is no longer supported and this always returns FALSE. + **/ + obj_properties[PROP_WIMAX_HARDWARE_ENABLED] = + g_param_spec_boolean(NM_CLIENT_WIMAX_HARDWARE_ENABLED, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:active-connections: (type GPtrArray(NMActiveConnection)) + * + * The active connections. + **/ + obj_properties[PROP_ACTIVE_CONNECTIONS] = + g_param_spec_boxed(NM_CLIENT_ACTIVE_CONNECTIONS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:connectivity: + * + * The network connectivity state. + */ + obj_properties[PROP_CONNECTIVITY] = + g_param_spec_enum(NM_CLIENT_CONNECTIVITY, + "", + "", + NM_TYPE_CONNECTIVITY_STATE, + NM_CONNECTIVITY_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient::connectivity-check-available + * + * Whether a connectivity checking service has been configured. + * + * Since: 1.10 + */ + obj_properties[PROP_CONNECTIVITY_CHECK_AVAILABLE] = + g_param_spec_boolean(NM_CLIENT_CONNECTIVITY_CHECK_AVAILABLE, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient::connectivity-check-enabled + * + * Whether a connectivity checking service has been enabled. + * + * Since: 1.10 + * + * The property setter is a synchronous D-Bus call. This is deprecated since 1.22. + */ + obj_properties[PROP_CONNECTIVITY_CHECK_ENABLED] = + g_param_spec_boolean(NM_CLIENT_CONNECTIVITY_CHECK_ENABLED, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:connectivity-check-uri: + * + * The used URI for connectivity checking. + * + * Since: 1.22 + **/ + obj_properties[PROP_CONNECTIVITY_CHECK_URI] = + g_param_spec_string(NM_CLIENT_CONNECTIVITY_CHECK_URI, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:primary-connection: + * + * The #NMActiveConnection of the device with the default route; + * see nm_client_get_primary_connection() for more details. + **/ + obj_properties[PROP_PRIMARY_CONNECTION] = + g_param_spec_object(NM_CLIENT_PRIMARY_CONNECTION, + "", + "", + NM_TYPE_ACTIVE_CONNECTION, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:activating-connection: + * + * The #NMActiveConnection of the activating connection that is + * likely to become the new #NMClient:primary-connection. + **/ + obj_properties[PROP_ACTIVATING_CONNECTION] = + g_param_spec_object(NM_CLIENT_ACTIVATING_CONNECTION, + "", + "", + NM_TYPE_ACTIVE_CONNECTION, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:devices: (type GPtrArray(NMDevice)) + * + * List of real network devices. Does not include placeholder devices. + **/ + obj_properties[PROP_DEVICES] = g_param_spec_boxed(NM_CLIENT_DEVICES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:all-devices: (type GPtrArray(NMDevice)) + * + * List of both real devices and device placeholders. + * Since: 1.2 + **/ + obj_properties[PROP_ALL_DEVICES] = + g_param_spec_boxed(NM_CLIENT_ALL_DEVICES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:connections: (type GPtrArray(NMRemoteConnection)) + * + * The list of configured connections that are available to the user. (Note + * that this differs from the underlying D-Bus property, which may also + * contain the object paths of connections that the user does not have + * permission to read the details of.) + */ + obj_properties[PROP_CONNECTIONS] = + g_param_spec_boxed(NM_CLIENT_CONNECTIONS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:hostname: + * + * The machine hostname stored in persistent configuration. This can be + * modified by calling nm_client_save_hostname(). + */ + obj_properties[PROP_HOSTNAME] = g_param_spec_string(NM_CLIENT_HOSTNAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:can-modify: + * + * If %TRUE, adding and modifying connections is supported. + */ + obj_properties[PROP_CAN_MODIFY] = + g_param_spec_boolean(NM_CLIENT_CAN_MODIFY, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:metered: + * + * Whether the connectivity is metered. + * + * Since: 1.2 + **/ + obj_properties[PROP_METERED] = g_param_spec_uint(NM_CLIENT_METERED, + "", + "", + 0, + G_MAXUINT32, + NM_METERED_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:dns-mode: + * + * The current DNS processing mode. + * + * Since: 1.6 + **/ + obj_properties[PROP_DNS_MODE] = g_param_spec_string(NM_CLIENT_DNS_MODE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:dns-rc-manager: + * + * The current resolv.conf management mode. + * + * Since: 1.6 + **/ + obj_properties[PROP_DNS_RC_MANAGER] = + g_param_spec_string(NM_CLIENT_DNS_RC_MANAGER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:dns-configuration: (type GPtrArray(NMDnsEntry)) + * + * The current DNS configuration, represented as an array + * of #NMDnsEntry objects. + * + * Since: 1.6 + **/ + obj_properties[PROP_DNS_CONFIGURATION] = + g_param_spec_boxed(NM_CLIENT_DNS_CONFIGURATION, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:checkpoints: (type GPtrArray(NMCheckpoint)) + * + * The list of active checkpoints. + * + * Since: 1.12 + */ + obj_properties[PROP_CHECKPOINTS] = + g_param_spec_boxed(NM_CLIENT_CHECKPOINTS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:capabilities: (type GArray(guint32)) + * + * The list of capabilities numbers as guint32 or %NULL if + * there are no capabilities. The numeric value correspond + * to %NMCapability enum. + * + * Since: 1.24 + */ + obj_properties[PROP_CAPABILITIES] = + g_param_spec_boxed(NM_CLIENT_CAPABILITIES, + "", + "", + G_TYPE_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMClient:permissions-state: + * + * The state of the cached permissions. The value %NM_TERNARY_DEFAULT + * means that no permissions are yet received (or not yet requested). + * %NM_TERNARY_TRUE means that permissions are received, cached and up + * to date. %NM_TERNARY_FALSE means that permissions were received and are + * cached, but in the meantime a "CheckPermissions" signal was received + * that invalidated the cached permissions. + * Note that NMClient will always emit a notify::permissions-state signal + * when a "CheckPermissions" signal got received or after new permissions + * got received (that is regardless whether the value of the permission state + * actually changed). With this you can watch the permissions-state property + * to know whether the permissions are ready. Note that while NMClient has + * no D-Bus name owner, no permissions are fetched (and this property won't + * change). + * + * Since: 1.24 + */ + obj_properties[PROP_PERMISSIONS_STATE] = + g_param_spec_enum(NM_CLIENT_PERMISSIONS_STATE, + "", + "", + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm, + &_nml_dbus_meta_iface_nm_settings, + &_nml_dbus_meta_iface_nm_dnsmanager); + + /** + * NMClient::device-added: + * @client: the client that received the signal + * @device: (type NMDevice): the new device + * + * Notifies that a #NMDevice is added. This signal is not emitted for + * placeholder devices. + **/ + signals[DEVICE_ADDED] = g_signal_new(NM_CLIENT_DEVICE_ADDED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); + + /** + * NMClient::device-removed: + * @client: the client that received the signal + * @device: (type NMDevice): the removed device + * + * Notifies that a #NMDevice is removed. This signal is not emitted for + * placeholder devices. + **/ + signals[DEVICE_REMOVED] = g_signal_new(NM_CLIENT_DEVICE_REMOVED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); + + /** + * NMClient::any-device-added: + * @client: the client that received the signal + * @device: (type NMDevice): the new device + * + * Notifies that a #NMDevice is added. This signal is emitted for both + * regular devices and placeholder devices. + **/ + signals[ANY_DEVICE_ADDED] = g_signal_new(NM_CLIENT_ANY_DEVICE_ADDED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); + + /** + * NMClient::any-device-removed: + * @client: the client that received the signal + * @device: (type NMDevice): the removed device + * + * Notifies that a #NMDevice is removed. This signal is emitted for both + * regular devices and placeholder devices. + **/ + signals[ANY_DEVICE_REMOVED] = g_signal_new(NM_CLIENT_ANY_DEVICE_REMOVED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); + + /** + * NMClient::permission-changed: + * @client: the client that received the signal + * @permission: a permission from #NMClientPermission + * @result: the permission's result, one of #NMClientPermissionResult + * + * Notifies that a permission has changed + **/ + signals[PERMISSION_CHANGED] = g_signal_new(NM_CLIENT_PERMISSION_CHANGED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_UINT, + G_TYPE_UINT); + /** + * NMClient::connection-added: + * @client: the settings object that received the signal + * @connection: the new connection + * + * Notifies that a #NMConnection has been added. + **/ + signals[CONNECTION_ADDED] = g_signal_new(NM_CLIENT_CONNECTION_ADDED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + NM_TYPE_REMOTE_CONNECTION); + + /** + * NMClient::connection-removed: + * @client: the settings object that received the signal + * @connection: the removed connection + * + * Notifies that a #NMConnection has been removed. + **/ + signals[CONNECTION_REMOVED] = g_signal_new(NM_CLIENT_CONNECTION_REMOVED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + NM_TYPE_REMOTE_CONNECTION); + + /** + * NMClient::active-connection-added: + * @client: the settings object that received the signal + * @active_connection: the new active connection + * + * Notifies that a #NMActiveConnection has been added. + **/ + signals[ACTIVE_CONNECTION_ADDED] = g_signal_new(NM_CLIENT_ACTIVE_CONNECTION_ADDED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + NM_TYPE_ACTIVE_CONNECTION); + + /** + * NMClient::active-connection-removed: + * @client: the settings object that received the signal + * @active_connection: the removed active connection + * + * Notifies that a #NMActiveConnection has been removed. + **/ + signals[ACTIVE_CONNECTION_REMOVED] = g_signal_new(NM_CLIENT_ACTIVE_CONNECTION_REMOVED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + NM_TYPE_ACTIVE_CONNECTION); +} + +static void +nm_client_initable_iface_init(GInitableIface *iface) +{ + iface->init = init_sync; +} + +static void +nm_client_async_initable_iface_init(GAsyncInitableIface *iface) +{ + iface->init_async = init_async; + iface->init_finish = init_finish; +} + +/***************************************************************************** + * Backported symbols. Usually, new API is only added in new major versions + * of NetworkManager (that is, on "master" branch). Sometimes however, we might + * have to backport some API to an older stable branch. In that case, we backport + * the symbols with a different version corresponding to the minor API. + * + * To allow upgrading from such a extended minor-release, "master" contains these + * backported symbols too. + * + * For example, 1.2.0 added nm_setting_connection_autoconnect_slaves_get_type. + * This was backported for 1.0.4 as nm_setting_connection_autoconnect_slaves_get_type@libnm_1_0_4 + * To allow an application that was linked against 1.0.4 to seamlessly upgrade to + * a newer major version, the same symbols is also exposed on "master". Note, that + * a user can only seamlessly upgrade to a newer major version, that is released + * *after* 1.0.4 is out. In this example, 1.2.0 was released after 1.4.0, and thus + * a 1.0.4 user can upgrade to 1.2.0 ABI. + *****************************************************************************/ + +NM_BACKPORT_SYMBOL(libnm_1_0_4, + NMSettingConnectionAutoconnectSlaves, + nm_setting_connection_get_autoconnect_slaves, + (NMSettingConnection * setting), + (setting)); + +NM_BACKPORT_SYMBOL(libnm_1_0_4, + GType, + nm_setting_connection_autoconnect_slaves_get_type, + (void), + ()); + +NM_BACKPORT_SYMBOL(libnm_1_0_6, + NMMetered, + nm_setting_connection_get_metered, + (NMSettingConnection * setting), + (setting)); + +NM_BACKPORT_SYMBOL(libnm_1_0_6, GType, nm_metered_get_type, (void), ()); + +NM_BACKPORT_SYMBOL(libnm_1_0_6, + NMSettingWiredWakeOnLan, + nm_setting_wired_get_wake_on_lan, + (NMSettingWired * setting), + (setting)); + +NM_BACKPORT_SYMBOL(libnm_1_0_6, + const char *, + nm_setting_wired_get_wake_on_lan_password, + (NMSettingWired * setting), + (setting)); + +NM_BACKPORT_SYMBOL(libnm_1_0_6, GType, nm_setting_wired_wake_on_lan_get_type, (void), ()); + +NM_BACKPORT_SYMBOL(libnm_1_0_6, const guint *, nm_utils_wifi_2ghz_freqs, (void), ()); + +NM_BACKPORT_SYMBOL(libnm_1_0_6, const guint *, nm_utils_wifi_5ghz_freqs, (void), ()); + +NM_BACKPORT_SYMBOL(libnm_1_0_6, + char *, + nm_utils_enum_to_str, + (GType type, int value), + (type, value)); + +NM_BACKPORT_SYMBOL(libnm_1_0_6, + gboolean, + nm_utils_enum_from_str, + (GType type, const char *str, int *out_value, char **err_token), + (type, str, out_value, err_token)); + +NM_BACKPORT_SYMBOL(libnm_1_2_4, + int, + nm_setting_ip_config_get_dns_priority, + (NMSettingIPConfig * setting), + (setting)); + +NM_BACKPORT_SYMBOL(libnm_1_10_14, + NMSettingConnectionMdns, + nm_setting_connection_get_mdns, + (NMSettingConnection * setting), + (setting)); +NM_BACKPORT_SYMBOL(libnm_1_10_14, GType, nm_setting_connection_mdns_get_type, (void), ()); diff --git a/src/libnm-client-impl/nm-dbus-helpers.c b/src/libnm-client-impl/nm-dbus-helpers.c new file mode 100644 index 0000000..3b5f9ff --- /dev/null +++ b/src/libnm-client-impl/nm-dbus-helpers.c @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-dbus-helpers.h" + +#include "nm-dbus-interface.h" + +GBusType +_nm_dbus_bus_type(void) +{ + static volatile int bus_type = G_BUS_TYPE_NONE; + int v; + + v = g_atomic_int_get(&bus_type); + if (G_UNLIKELY(v == G_BUS_TYPE_NONE)) { + v = G_BUS_TYPE_SYSTEM; + if (g_getenv("LIBNM_USE_SESSION_BUS")) + v = G_BUS_TYPE_SESSION; + if (!g_atomic_int_compare_and_exchange(&bus_type, G_BUS_TYPE_NONE, v)) + v = g_atomic_int_get(&bus_type); + nm_assert(v != G_BUS_TYPE_NONE); + } + return v; +} + +/* Binds the properties on a generated server-side GDBus object to the + * corresponding properties on the public object. + */ +void +_nm_dbus_bind_properties(gpointer object, gpointer skeleton) +{ + GParamSpec **properties; + guint n_properties; + int i; + + properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(skeleton), &n_properties); + for (i = 0; i < n_properties; i++) { + if (g_str_has_prefix(properties[i]->name, "g-")) + continue; + + g_object_bind_property(object, + properties[i]->name, + skeleton, + properties[i]->name, + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + } + g_free(properties); +} + +static char * +signal_name_from_method_name(const char *method_name) +{ + GString * signal_name; + const char *p; + + signal_name = g_string_new("handle"); + for (p = method_name; *p; p++) { + if (g_ascii_isupper(*p)) + g_string_append_c(signal_name, '-'); + g_string_append_c(signal_name, g_ascii_tolower(*p)); + } + + return g_string_free(signal_name, FALSE); +} + +static void +_nm_dbus_method_meta_marshal(GClosure * closure, + GValue * return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + closure->marshal(closure, + return_value, + n_param_values, + param_values, + invocation_hint, + ((GCClosure *) closure)->callback); + + g_value_set_boolean(return_value, TRUE); +} + +/* Takes (method_name, handler_func) pairs and connects the handlers to the + * signals on skeleton, with object as the user_data, but swapped so it comes + * first in the argument list, and handling the return value automatically. + */ +void +_nm_dbus_bind_methods(gpointer object, gpointer skeleton, ...) +{ + va_list ap; + const char *method_name; + char * signal_name; + GCallback handler; + GClosure * closure; + + va_start(ap, skeleton); + while ((method_name = va_arg(ap, const char *)) && (handler = va_arg(ap, GCallback))) { + signal_name = signal_name_from_method_name(method_name); + closure = g_cclosure_new_swap(handler, object, NULL); + g_closure_set_meta_marshal(closure, NULL, _nm_dbus_method_meta_marshal); + g_signal_connect_closure(skeleton, signal_name, closure, FALSE); + g_free(signal_name); + } + va_end(ap); +} diff --git a/src/libnm-client-impl/nm-dbus-helpers.h b/src/libnm-client-impl/nm-dbus-helpers.h new file mode 100644 index 0000000..e519f73 --- /dev/null +++ b/src/libnm-client-impl/nm-dbus-helpers.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#ifndef __NM_DBUS_HELPERS_PRIVATE_H__ +#define __NM_DBUS_HELPERS_PRIVATE_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE) + #error Cannot use this header. +#endif + +#include "libnm-std-aux/nm-dbus-compat.h" + +#define NM_DBUS_DEFAULT_TIMEOUT_MSEC 25000 + +GBusType _nm_dbus_bus_type(void); + +void _nm_dbus_bind_properties(gpointer object, gpointer skeleton); + +void _nm_dbus_bind_methods(gpointer object, gpointer skeleton, ...) G_GNUC_NULL_TERMINATED; + +#endif /* __NM_DBUS_HELPERS_PRIVATE_H__ */ diff --git a/src/libnm-client-impl/nm-default-libnm.h b/src/libnm-client-impl/nm-default-libnm.h new file mode 100644 index 0000000..5b3a8e5 --- /dev/null +++ b/src/libnm-client-impl/nm-default-libnm.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEFAULT_LIBNM_H__ +#define __NM_DEFAULT_LIBNM_H__ + +/*****************************************************************************/ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#undef NETWORKMANAGER_COMPILATION +#define NETWORKMANAGER_COMPILATION NM_NETWORKMANAGER_COMPILATION_LIBNM + +/*****************************************************************************/ + +#include "nm-version.h" +#include "nm-libnm-utils.h" + +/*****************************************************************************/ + +#endif /* __NM_DEFAULT_LIBNM_H__ */ diff --git a/src/libnm-client-impl/nm-device-6lowpan.c b/src/libnm-client-impl/nm-device-6lowpan.c new file mode 100644 index 0000000..e03b4a0 --- /dev/null +++ b/src/libnm-client-impl/nm-device-6lowpan.c @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-6lowpan.h" + +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, ); + +typedef struct { + NMLDBusPropertyO parent; +} NMDevice6LowpanPrivate; + +struct _NMDevice6Lowpan { + NMDevice parent; + NMDevice6LowpanPrivate _priv; +}; + +struct _NMDevice6LowpanClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDevice6Lowpan, nm_device_6lowpan, NM_TYPE_DEVICE) + +#define NM_DEVICE_6LOWPAN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDevice6Lowpan, NM_IS_DEVICE_6LOWPAN, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_6lowpan_get_parent: + * @device: a #NMDevice6Lowpan + * + * Returns: (transfer none): the device's parent device + * + * Since: 1.14 + **/ +NMDevice * +nm_device_6lowpan_get_parent(NMDevice6Lowpan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_6LOWPAN(device), NULL); + + return nml_dbus_property_o_get_obj(&NM_DEVICE_6LOWPAN_GET_PRIVATE(device)->parent); +} + +/** + * nm_device_6lowpan_get_hw_address: (skip) + * @device: a #NMDevice6Lowpan + * + * Gets the hardware (MAC) address of the #NMDevice6Lowpan + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.14 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_6lowpan_get_hw_address(NMDevice6Lowpan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_6LOWPAN(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/*****************************************************************************/ + +static void +nm_device_6lowpan_init(NMDevice6Lowpan *device) +{} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDevice6Lowpan *device = NM_DEVICE_6LOWPAN(object); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_object(value, nm_device_6lowpan_get_parent(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_lowpan = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_6LOWPAN, + nm_device_6lowpan_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Parent", + PROP_PARENT, + NMDevice6Lowpan, + _priv.parent, + nm_device_get_type), ), ); + +static void +nm_device_6lowpan_class_init(NMDevice6LowpanClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDevice6Lowpan); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDevice6LowpanPrivate, parent); + + /** + * NMDevice6Lowpan:parent: + * + * The devices's parent device. + * + * Since: 1.14 + **/ + obj_properties[PROP_PARENT] = g_param_spec_object(NM_DEVICE_6LOWPAN_PARENT, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_lowpan); +} diff --git a/src/libnm-client-impl/nm-device-adsl.c b/src/libnm-client-impl/nm-device-adsl.c new file mode 100644 index 0000000..65f8754 --- /dev/null +++ b/src/libnm-client-impl/nm-device-adsl.c @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Author: Pantelis Koukousoulas + * Copyright (C) 2009 - 2011 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-adsl.h" + +#include "nm-object-private.h" +#include "nm-setting-adsl.h" +#include "nm-setting-connection.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_CARRIER, ); + +typedef struct { + bool carrier; +} NMDeviceAdslPrivate; + +struct _NMDeviceAdsl { + NMDevice parent; + NMDeviceAdslPrivate _priv; +}; + +struct _NMDeviceAdslClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceAdsl, nm_device_adsl, NM_TYPE_DEVICE) + +#define NM_DEVICE_ADSL_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceAdsl, NM_IS_DEVICE_ADSL, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_adsl_get_carrier: + * @device: a #NMDeviceAdsl + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_adsl_get_carrier(NMDeviceAdsl *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_ADSL(device), FALSE); + + return NM_DEVICE_ADSL_GET_PRIVATE(device)->carrier; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS(nm_device_adsl_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_ADSL_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not an ADSL connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_ADSL; +} + +/*****************************************************************************/ + +static void +nm_device_adsl_init(NMDeviceAdsl *device) +{} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceAdsl *device = NM_DEVICE_ADSL(object); + + switch (prop_id) { + case PROP_CARRIER: + g_value_set_boolean(value, nm_device_adsl_get_carrier(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_adsl = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_ADSL, + nm_device_adsl_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_B("Carrier", PROP_CARRIER, NMDeviceAdsl, _priv.carrier), ), ); + +static void +nm_device_adsl_class_init(NMDeviceAdslClass *adsl_class) +{ + GObjectClass * object_class = G_OBJECT_CLASS(adsl_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS(adsl_class); + + object_class->get_property = get_property; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceAdsl:carrier: + * + * Whether the device has carrier. + **/ + obj_properties[PROP_CARRIER] = g_param_spec_boolean(NM_DEVICE_ADSL_CARRIER, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_adsl); +} diff --git a/src/libnm-client-impl/nm-device-bond.c b/src/libnm-client-impl/nm-device-bond.c new file mode 100644 index 0000000..48dfd9b --- /dev/null +++ b/src/libnm-client-impl/nm-device-bond.c @@ -0,0 +1,211 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-setting-bond.h" + +#include "nm-setting-connection.h" +#include "nm-utils.h" +#include "nm-device-bond.h" +#include "nm-object-private.h" +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_CARRIER, PROP_SLAVES, ); + +typedef struct { + NMLDBusPropertyAO slaves; + char * hw_address; + bool carrier; +} NMDeviceBondPrivate; + +struct _NMDeviceBond { + NMDevice parent; + NMDeviceBondPrivate _priv; +}; + +struct _NMDeviceBondClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceBond, nm_device_bond, NM_TYPE_DEVICE) + +#define NM_DEVICE_BOND_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceBond, NM_IS_DEVICE_BOND, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_bond_get_hw_address: (skip) + * @device: a #NMDeviceBond + * + * Gets the hardware (MAC) address of the #NMDeviceBond + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_bond_get_hw_address(NMDeviceBond *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_BOND(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_bond_get_carrier: + * @device: a #NMDeviceBond + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_bond_get_carrier(NMDeviceBond *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_BOND(device), FALSE); + + return NM_DEVICE_BOND_GET_PRIVATE(device)->carrier; +} + +/** + * nm_device_bond_get_slaves: + * @device: a #NMDeviceBond + * + * Gets the devices currently enslaved to @device. + * + * Returns: (element-type NMDevice): the #GPtrArray containing + * #NMDevices that are slaves of @device. This is the internal + * copy used by the device, and must not be modified. + **/ +const GPtrArray * +nm_device_bond_get_slaves(NMDeviceBond *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_BOND(device), FALSE); + + return nml_dbus_property_ao_get_objs_as_ptrarray(&NM_DEVICE_BOND_GET_PRIVATE(device)->slaves); +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS(nm_device_bond_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_BOND_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a bond connection.")); + return FALSE; + } + + /* FIXME: check slaves? */ + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_BOND; +} + +/*****************************************************************************/ + +static void +nm_device_bond_init(NMDeviceBond *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE(object); + + g_free(priv->hw_address); + + G_OBJECT_CLASS(nm_device_bond_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceBond *device = NM_DEVICE_BOND(object); + + switch (prop_id) { + case PROP_CARRIER: + g_value_set_boolean(value, nm_device_bond_get_carrier(device)); + break; + case PROP_SLAVES: + g_value_take_boxed(value, _nm_utils_copy_object_array(nm_device_bond_get_slaves(device))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bond = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_BOND, + nm_device_bond_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_B("Carrier", PROP_CARRIER, NMDeviceBond, _priv.carrier), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Slaves", + PROP_SLAVES, + NMDeviceBond, + _priv.slaves, + nm_device_get_type), ), ); + +static void +nm_device_bond_class_init(NMDeviceBondClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceBond); + + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, NMDeviceBondPrivate, slaves); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceBond:carrier: + * + * Whether the device has carrier. + **/ + obj_properties[PROP_CARRIER] = g_param_spec_boolean(NM_DEVICE_BOND_CARRIER, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceBond:slaves: (type GPtrArray(NMDevice)) + * + * The devices enslaved to the bond device. + **/ + obj_properties[PROP_SLAVES] = g_param_spec_boxed(NM_DEVICE_BOND_SLAVES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_bond); +} diff --git a/src/libnm-client-impl/nm-device-bridge.c b/src/libnm-client-impl/nm-device-bridge.c new file mode 100644 index 0000000..9bc41ac --- /dev/null +++ b/src/libnm-client-impl/nm-device-bridge.c @@ -0,0 +1,204 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-setting-bridge.h" + +#include "nm-setting-connection.h" +#include "nm-utils.h" +#include "nm-device-bridge.h" +#include "nm-object-private.h" +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_CARRIER, PROP_SLAVES, ); + +typedef struct { + NMLDBusPropertyAO slaves; + bool carrier; +} NMDeviceBridgePrivate; + +struct _NMDeviceBridge { + NMDevice parent; + NMDeviceBridgePrivate _priv; +}; + +struct _NMDeviceBridgeClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceBridge, nm_device_bridge, NM_TYPE_DEVICE) + +#define NM_DEVICE_BRIDGE_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceBridge, NM_IS_DEVICE_BRIDGE, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_bridge_get_hw_address: (skip) + * @device: a #NMDeviceBridge + * + * Gets the hardware (MAC) address of the #NMDeviceBridge + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_bridge_get_hw_address(NMDeviceBridge *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_BRIDGE(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_bridge_get_carrier: + * @device: a #NMDeviceBridge + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_bridge_get_carrier(NMDeviceBridge *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_BRIDGE(device), FALSE); + + return NM_DEVICE_BRIDGE_GET_PRIVATE(device)->carrier; +} + +/** + * nm_device_bridge_get_slaves: + * @device: a #NMDeviceBridge + * + * Gets the devices currently enslaved to @device. + * + * Returns: (element-type NMDevice): the #GPtrArray containing + * #NMDevices that are slaves of @device. This is the internal + * copy used by the device, and must not be modified. + **/ +const GPtrArray * +nm_device_bridge_get_slaves(NMDeviceBridge *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_BRIDGE(device), FALSE); + + return nml_dbus_property_ao_get_objs_as_ptrarray(&NM_DEVICE_BRIDGE_GET_PRIVATE(device)->slaves); +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS(nm_device_bridge_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_BRIDGE_SETTING_NAME)) { + if (_nm_connection_get_setting_bluetooth_for_nap(connection) + && nm_connection_is_type(connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) { + /* a bluetooth NAP setting is a compatible connection for a bridge. */ + } else { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a bridge connection.")); + return FALSE; + } + } + + /* FIXME: check ports? */ + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_BRIDGE; +} + +/*****************************************************************************/ + +static void +nm_device_bridge_init(NMDeviceBridge *device) +{} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceBridge *device = NM_DEVICE_BRIDGE(object); + + switch (prop_id) { + case PROP_CARRIER: + g_value_set_boolean(value, nm_device_bridge_get_carrier(device)); + break; + case PROP_SLAVES: + g_value_take_boxed(value, _nm_utils_copy_object_array(nm_device_bridge_get_slaves(device))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bridge = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_BRIDGE, + nm_device_bridge_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_B("Carrier", PROP_CARRIER, NMDeviceBridge, _priv.carrier), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Slaves", + PROP_SLAVES, + NMDeviceBridge, + _priv.slaves, + nm_device_get_type), ), ); + +static void +nm_device_bridge_class_init(NMDeviceBridgeClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceBridge); + + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, NMDeviceBridgePrivate, slaves); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceBridge:carrier: + * + * Whether the device has carrier. + **/ + obj_properties[PROP_CARRIER] = g_param_spec_boolean(NM_DEVICE_BRIDGE_CARRIER, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceBridge:slaves: (type GPtrArray(NMDevice)) + * + * The devices enslaved to the bridge device. + **/ + obj_properties[PROP_SLAVES] = g_param_spec_boxed(NM_DEVICE_BRIDGE_SLAVES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_bridge); +} diff --git a/src/libnm-client-impl/nm-device-bt.c b/src/libnm-client-impl/nm-device-bt.c new file mode 100644 index 0000000..074ada6 --- /dev/null +++ b/src/libnm-client-impl/nm-device-bt.c @@ -0,0 +1,273 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-bt.h" + +#include + +#include "nm-setting-connection.h" +#include "nm-setting-bluetooth.h" +#include "nm-utils.h" +#include "nm-object-private.h" +#include "nm-enum-types.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_NAME, PROP_BT_CAPABILITIES, ); + +typedef struct { + char * name; + guint32 bt_capabilities; +} NMDeviceBtPrivate; + +struct _NMDeviceBt { + NMDevice parent; + NMDeviceBtPrivate _priv; +}; + +struct _NMDeviceBtClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE) + +#define NM_DEVICE_BT_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceBt, NM_IS_DEVICE_BT, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_bt_get_hw_address: (skip) + * @device: a #NMDeviceBt + * + * Gets the hardware (MAC) address of the #NMDeviceBt + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_bt_get_hw_address(NMDeviceBt *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_BT(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_bt_get_name: + * @device: a #NMDeviceBt + * + * Gets the name of the #NMDeviceBt. + * + * Returns: the name of the device + **/ +const char * +nm_device_bt_get_name(NMDeviceBt *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_BT(device), NULL); + + return NM_DEVICE_BT_GET_PRIVATE(device)->name; +} + +/** + * nm_device_bt_get_capabilities: + * @device: a #NMDeviceBt + * + * Returns the Bluetooth device's usable capabilities. + * + * Returns: a combination of #NMBluetoothCapabilities + **/ +NMBluetoothCapabilities +nm_device_bt_get_capabilities(NMDeviceBt *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_BT(device), NM_BT_CAPABILITY_NONE); + + return NM_DEVICE_BT_GET_PRIVATE(device)->bt_capabilities; +} + +static NMBluetoothCapabilities +get_connection_bt_type(NMConnection *connection) +{ + NMSettingBluetooth *s_bt; + const char * bt_type; + + s_bt = nm_connection_get_setting_bluetooth(connection); + if (!s_bt) + return NM_BT_CAPABILITY_NONE; + + bt_type = nm_setting_bluetooth_get_connection_type(s_bt); + g_assert(bt_type); + + if (!strcmp(bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN)) + return NM_BT_CAPABILITY_DUN; + else if (!strcmp(bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)) + return NM_BT_CAPABILITY_NAP; + + return NM_BT_CAPABILITY_NONE; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingBluetooth * s_bt; + const char * hw_addr, *setting_addr; + NMBluetoothCapabilities dev_caps; + NMBluetoothCapabilities bt_type; + + if (!NM_DEVICE_CLASS(nm_device_bt_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_BLUETOOTH_SETTING_NAME) + || !(s_bt = nm_connection_get_setting_bluetooth(connection))) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a Bluetooth connection.")); + return FALSE; + } + + if (nm_streq0(nm_setting_bluetooth_get_connection_type(s_bt), NM_SETTING_BLUETOOTH_TYPE_NAP)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection is of Bluetooth NAP type.")); + return FALSE; + } + + /* Check BT address */ + hw_addr = nm_device_get_hw_address(device); + if (hw_addr) { + if (!nm_utils_hwaddr_valid(hw_addr, ETH_ALEN)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + _("Invalid device Bluetooth address.")); + return FALSE; + } + setting_addr = nm_setting_bluetooth_get_bdaddr(s_bt); + if (setting_addr && !nm_utils_hwaddr_matches(setting_addr, -1, hw_addr, -1)) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The Bluetooth addresses of the device and the connection didn't match.")); + return FALSE; + } + } + + dev_caps = nm_device_bt_get_capabilities(NM_DEVICE_BT(device)); + bt_type = get_connection_bt_type(connection); + if (!(bt_type & dev_caps)) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The device is lacking Bluetooth capabilities required by the connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_BLUETOOTH; +} + +/*****************************************************************************/ + +static void +nm_device_bt_init(NMDeviceBt *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(object); + + g_free(priv->name); + + G_OBJECT_CLASS(nm_device_bt_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceBt *device = NM_DEVICE_BT(object); + + switch (prop_id) { + case PROP_NAME: + g_value_set_string(value, nm_device_bt_get_name(device)); + break; + case PROP_BT_CAPABILITIES: + g_value_set_flags(value, nm_device_bt_get_capabilities(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bluetooth = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, + nm_device_bt_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_U("BtCapabilities", + PROP_BT_CAPABILITIES, + NMDeviceBt, + _priv.bt_capabilities), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_S("Name", PROP_NAME, NMDeviceBt, _priv.name), ), ); + +static void +nm_device_bt_class_init(NMDeviceBtClass *bt_class) +{ + GObjectClass * object_class = G_OBJECT_CLASS(bt_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS(bt_class); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceBt:name: + * + * The name of the bluetooth device. + **/ + obj_properties[PROP_NAME] = g_param_spec_string(NM_DEVICE_BT_NAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceBt:bt-capabilities: + * + * The device's bluetooth capabilities, a combination of #NMBluetoothCapabilities. + **/ + obj_properties[PROP_BT_CAPABILITIES] = + g_param_spec_flags(NM_DEVICE_BT_CAPABILITIES, + "", + "", + NM_TYPE_BLUETOOTH_CAPABILITIES, + NM_BT_CAPABILITY_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_bluetooth); +} diff --git a/src/libnm-client-impl/nm-device-dummy.c b/src/libnm-client-impl/nm-device-dummy.c new file mode 100644 index 0000000..d56f6cd --- /dev/null +++ b/src/libnm-client-impl/nm-device-dummy.c @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-dummy.h" + +#include "nm-object-private.h" +#include "nm-setting-dummy.h" +#include "nm-setting-connection.h" + +/*****************************************************************************/ + +struct _NMDeviceDummy { + NMDevice parent; +}; + +struct _NMDeviceDummyClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceDummy, nm_device_dummy, NM_TYPE_DEVICE) + +#define NM_DEVICE_DUMMY_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceDummy, NM_IS_DEVICE_DUMMY, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_dummy_get_hw_address: (skip) + * @device: a #NMDeviceDummy + * + * Gets the hardware (MAC) address of the #NMDeviceDummy + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.10 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_dummy_get_hw_address(NMDeviceDummy *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_DUMMY(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + const char *iface_name; + + if (!NM_DEVICE_CLASS(nm_device_dummy_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_DUMMY_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a dummy connection.")); + return FALSE; + } + + iface_name = nm_connection_get_interface_name(connection); + if (!iface_name) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection did not specify an interface name.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_DUMMY; +} + +/*****************************************************************************/ + +static void +nm_device_dummy_init(NMDeviceDummy *device) +{} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_dummy = NML_DBUS_META_IFACE_INIT( + NM_DBUS_INTERFACE_DEVICE_DUMMY, + nm_device_dummy_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), ), ); + +static void +nm_device_dummy_class_init(NMDeviceDummyClass *dummy_class) +{ + NMDeviceClass *device_class = NM_DEVICE_CLASS(dummy_class); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; +} diff --git a/src/libnm-client-impl/nm-device-ethernet.c b/src/libnm-client-impl/nm-device-ethernet.c new file mode 100644 index 0000000..b32decd --- /dev/null +++ b/src/libnm-client-impl/nm-device-ethernet.c @@ -0,0 +1,404 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-ethernet.h" + +#include + +#include "nm-libnm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-wired.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-veth.h" +#include "nm-utils.h" +#include "nm-object-private.h" +#include "nm-device-veth.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PERM_HW_ADDRESS, + PROP_SPEED, + PROP_CARRIER, + PROP_S390_SUBCHANNELS, ); + +typedef struct _NMDeviceEthernetPrivate { + char ** s390_subchannels; + char * perm_hw_address; + guint32 speed; + bool carrier; +} NMDeviceEthernetPrivate; + +G_DEFINE_TYPE(NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) + +#define NM_DEVICE_ETHERNET_GET_PRIVATE(self) \ + _NM_GET_PRIVATE_PTR(self, NMDeviceEthernet, NM_IS_DEVICE_ETHERNET, NMObject) + +/*****************************************************************************/ + +/** + * nm_device_ethernet_get_hw_address: (skip) + * @device: a #NMDeviceEthernet + * + * Gets the active hardware (MAC) address of the #NMDeviceEthernet + * + * Returns: the active hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_ethernet_get_hw_address(NMDeviceEthernet *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_ETHERNET(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_ethernet_get_permanent_hw_address: + * @device: a #NMDeviceEthernet + * + * Gets the permanent hardware (MAC) address of the #NMDeviceEthernet + * + * Returns: the permanent hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_ethernet_get_permanent_hw_address(NMDeviceEthernet *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_ETHERNET(device), NULL); + + return _nml_coerce_property_str_not_empty( + NM_DEVICE_ETHERNET_GET_PRIVATE(device)->perm_hw_address); +} + +/** + * nm_device_ethernet_get_speed: + * @device: a #NMDeviceEthernet + * + * Gets the speed of the #NMDeviceEthernet in Mbit/s. + * + * Returns: the speed of the device in Mbit/s + **/ +guint32 +nm_device_ethernet_get_speed(NMDeviceEthernet *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_ETHERNET(device), 0); + + return NM_DEVICE_ETHERNET_GET_PRIVATE(device)->speed; +} + +/** + * nm_device_ethernet_get_carrier: + * @device: a #NMDeviceEthernet + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_ethernet_get_carrier(NMDeviceEthernet *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_ETHERNET(device), FALSE); + + return NM_DEVICE_ETHERNET_GET_PRIVATE(device)->carrier; +} + +/** + * nm_device_ethernet_get_s390_subchannels: + * @device: a #NMDeviceEthernet + * + * Return the list of s390 subchannels if the device supports them. + * + * Returns: (transfer none) (element-type utf8): array of strings, each specifying + * one subchannel the s390 device uses to communicate to the host. + * + * Since: 1.2 + **/ +const char *const * +nm_device_ethernet_get_s390_subchannels(NMDeviceEthernet *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_ETHERNET(device), NULL); + + return (const char *const *) NM_DEVICE_ETHERNET_GET_PRIVATE(device)->s390_subchannels; +} + +static gboolean +match_subchans(NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac) +{ + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + const char *const * subchans; + gsize num1, num2; + gsize i, j; + + *try_mac = TRUE; + + subchans = nm_setting_wired_get_s390_subchannels(s_wired); + num1 = NM_PTRARRAY_LEN(subchans); + num2 = NM_PTRARRAY_LEN(priv->s390_subchannels); + /* connection has no subchannels */ + if (num1 == 0) + return TRUE; + /* connection requires subchannels but the device has none */ + if (num2 == 0) + return FALSE; + /* number of subchannels differ */ + if (num1 != num2) + return FALSE; + + /* Make sure each subchannel in the connection is a subchannel of this device */ + for (i = 0; subchans[i]; i++) { + const char *candidate = subchans[i]; + gboolean found = FALSE; + + for (j = 0; priv->s390_subchannels[j]; j++) { + if (!g_strcmp0(priv->s390_subchannels[j], candidate)) + found = TRUE; + } + if (!found) + return FALSE; /* a subchannel was not found */ + } + + *try_mac = FALSE; + return TRUE; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingWired *s_wired; + + if (!NM_DEVICE_CLASS(nm_device_ethernet_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME) + || nm_connection_is_type(connection, NM_SETTING_WIRED_SETTING_NAME) + || (nm_connection_is_type(connection, NM_SETTING_VETH_SETTING_NAME) + && NM_IS_DEVICE_VETH(device))) { + /* NOP */ + } else { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not an Ethernet or PPPoE connection.")); + return FALSE; + } + + s_wired = nm_connection_get_setting_wired(connection); + /* Wired setting optional for PPPoE */ + if (s_wired) { + const char * perm_addr, *s_mac; + gboolean try_mac = TRUE; + const char *const *mac_blacklist; + int i; + + /* Check s390 subchannels */ + if (!match_subchans(NM_DEVICE_ETHERNET(device), s_wired, &try_mac)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection and device differ in S390 subchannels.")); + return FALSE; + } + + /* Check MAC address */ + perm_addr = nm_device_ethernet_get_permanent_hw_address(NM_DEVICE_ETHERNET(device)); + s_mac = nm_setting_wired_get_mac_address(s_wired); + if (perm_addr) { + /* Virtual devices will have empty permanent addr but they should not be excluded + * from the MAC address check specified in the connection */ + if (*perm_addr == 0) + perm_addr = nm_device_get_hw_address(NM_DEVICE(device)); + + if (!nm_utils_hwaddr_valid(perm_addr, ETH_ALEN)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + _("Invalid device MAC address %s."), + perm_addr); + return FALSE; + } + if (try_mac && s_mac && !nm_utils_hwaddr_matches(s_mac, -1, perm_addr, -1)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The MACs of the device and the connection do not match.")); + return FALSE; + } + + /* Check for MAC address blacklist */ + mac_blacklist = nm_setting_wired_get_mac_address_blacklist(s_wired); + for (i = 0; mac_blacklist[i]; i++) { + if (!nm_utils_hwaddr_valid(mac_blacklist[i], ETH_ALEN)) { + g_warn_if_reached(); + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("Invalid MAC in the blacklist: %s."), + mac_blacklist[i]); + return FALSE; + } + + if (nm_utils_hwaddr_matches(mac_blacklist[i], -1, perm_addr, -1)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("Device MAC (%s) is blacklisted by the connection."), + perm_addr); + return FALSE; + } + } + } + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_WIRED; +} + +/*****************************************************************************/ + +static void +nm_device_ethernet_init(NMDeviceEthernet *device) +{ + NMDeviceEthernetPrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE(device, NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate); + + device->_priv = priv; +} + +static void +finalize(GObject *object) +{ + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(object); + + g_free(priv->perm_hw_address); + g_strfreev(priv->s390_subchannels); + + G_OBJECT_CLASS(nm_device_ethernet_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceEthernet * device = NM_DEVICE_ETHERNET(object); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(device); + + switch (prop_id) { + case PROP_PERM_HW_ADDRESS: + g_value_set_string(value, nm_device_ethernet_get_permanent_hw_address(device)); + break; + case PROP_SPEED: + g_value_set_uint(value, nm_device_ethernet_get_speed(device)); + break; + case PROP_CARRIER: + g_value_set_boolean(value, nm_device_ethernet_get_carrier(device)); + break; + case PROP_S390_SUBCHANNELS: + g_value_set_boxed(value, priv->s390_subchannels); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wired = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_WIRED, + nm_device_ethernet_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_20, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_B("Carrier", PROP_CARRIER, NMDeviceEthernetPrivate, carrier), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_S("PermHwAddress", + PROP_PERM_HW_ADDRESS, + NMDeviceEthernetPrivate, + perm_hw_address), + NML_DBUS_META_PROPERTY_INIT_AS("S390Subchannels", + PROP_S390_SUBCHANNELS, + NMDeviceEthernetPrivate, + s390_subchannels), + NML_DBUS_META_PROPERTY_INIT_U("Speed", PROP_SPEED, NMDeviceEthernetPrivate, speed), ), + .base_struct_offset = G_STRUCT_OFFSET(NMDeviceEthernet, _priv), ); + +static void +nm_device_ethernet_class_init(NMDeviceEthernetClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMDeviceEthernetPrivate)); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceEthernet:perm-hw-address: + * + * The permanent hardware (MAC) address of the device. + **/ + obj_properties[PROP_PERM_HW_ADDRESS] = + g_param_spec_string(NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceEthernet:speed: + * + * The speed of the device. + **/ + obj_properties[PROP_SPEED] = g_param_spec_uint(NM_DEVICE_ETHERNET_SPEED, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceEthernet:carrier: + * + * Whether the device has carrier. + **/ + obj_properties[PROP_CARRIER] = g_param_spec_boolean(NM_DEVICE_ETHERNET_CARRIER, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceEthernet:s390-subchannels: + * + * Identifies subchannels of this network device used for + * communication with z/VM or s390 host. + * + * Since: 1.2 + **/ + obj_properties[PROP_S390_SUBCHANNELS] = + g_param_spec_boxed(NM_DEVICE_ETHERNET_S390_SUBCHANNELS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_wired); +} diff --git a/src/libnm-client-impl/nm-device-generic.c b/src/libnm-client-impl/nm-device-generic.c new file mode 100644 index 0000000..9dcc8c9 --- /dev/null +++ b/src/libnm-client-impl/nm-device-generic.c @@ -0,0 +1,175 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-generic.h" + +#include "nm-object-private.h" +#include "nm-setting-generic.h" +#include "nm-setting-connection.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_TYPE_DESCRIPTION, ); + +typedef struct { + char *type_description; +} NMDeviceGenericPrivate; + +struct _NMDeviceGeneric { + NMDevice parent; + NMDeviceGenericPrivate _priv; +}; + +struct _NMDeviceGenericClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceGeneric, nm_device_generic, NM_TYPE_DEVICE) + +#define NM_DEVICE_GENERIC_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceGeneric, NM_IS_DEVICE_GENERIC, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_generic_get_hw_address: (skip) + * @device: a #NMDeviceGeneric + * + * Gets the hardware address of the #NMDeviceGeneric + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_generic_get_hw_address(NMDeviceGeneric *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_GENERIC(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/*****************************************************************************/ + +static const char * +get_type_description(NMDevice *device) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE(device); + + return _nml_coerce_property_str_not_empty(priv->type_description); +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + const char *iface_name; + + if (!NM_DEVICE_CLASS(nm_device_generic_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_GENERIC_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a generic connection.")); + return FALSE; + } + + iface_name = nm_connection_get_interface_name(connection); + if (!iface_name) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection did not specify an interface name.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_GENERIC; +} + +/*****************************************************************************/ + +static void +nm_device_generic_init(NMDeviceGeneric *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE(object); + + g_free(priv->type_description); + + G_OBJECT_CLASS(nm_device_generic_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceGeneric *self = NM_DEVICE_GENERIC(object); + + switch (prop_id) { + case PROP_TYPE_DESCRIPTION: + g_value_set_string(value, get_type_description((NMDevice *) self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_generic = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_GENERIC, + nm_device_generic_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_S("TypeDescription", + PROP_TYPE_DESCRIPTION, + NMDeviceGeneric, + _priv.type_description), ), ); + +static void +nm_device_generic_class_init(NMDeviceGenericClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + device_class->get_type_description = get_type_description; + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceGeneric:type-description: + * + * A description of the specific type of device this is, or %NULL + * if not known. + **/ + obj_properties[PROP_TYPE_DESCRIPTION] = + g_param_spec_string(NM_DEVICE_GENERIC_TYPE_DESCRIPTION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_generic); +} diff --git a/src/libnm-client-impl/nm-device-infiniband.c b/src/libnm-client-impl/nm-device-infiniband.c new file mode 100644 index 0000000..7e4cc05 --- /dev/null +++ b/src/libnm-client-impl/nm-device-infiniband.c @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2012 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-infiniband.h" + +#include + +#include "nm-setting-connection.h" +#include "nm-setting-infiniband.h" +#include "nm-utils.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_CARRIER, ); + +typedef struct { + bool carrier; +} NMDeviceInfinibandPrivate; + +struct _NMDeviceInfiniband { + NMDevice parent; + NMDeviceInfinibandPrivate _priv; +}; + +struct _NMDeviceInfinibandClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE) + +#define NM_DEVICE_INFINIBAND_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceInfiniband, NM_IS_DEVICE_INFINIBAND, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_infiniband_get_hw_address: (skip) + * @device: a #NMDeviceInfiniband + * + * Gets the hardware (MAC) address of the #NMDeviceInfiniband + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_infiniband_get_hw_address(NMDeviceInfiniband *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_INFINIBAND(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_infiniband_get_carrier: + * @device: a #NMDeviceInfiniband + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_infiniband_get_carrier(NMDeviceInfiniband *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_INFINIBAND(device), FALSE); + + return NM_DEVICE_INFINIBAND_GET_PRIVATE(device)->carrier; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingInfiniband *s_infiniband; + const char * hwaddr, *setting_hwaddr; + + if (!NM_DEVICE_CLASS(nm_device_infiniband_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_INFINIBAND_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not an InfiniBand connection.")); + return FALSE; + } + + hwaddr = nm_device_get_hw_address(NM_DEVICE(device)); + if (hwaddr) { + if (!nm_utils_hwaddr_valid(hwaddr, INFINIBAND_ALEN)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + _("Invalid device MAC address.")); + return FALSE; + } + + s_infiniband = nm_connection_get_setting_infiniband(connection); + setting_hwaddr = nm_setting_infiniband_get_mac_address(s_infiniband); + if (setting_hwaddr && !nm_utils_hwaddr_matches(setting_hwaddr, -1, hwaddr, -1)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The MACs of the device and the connection didn't match.")); + return FALSE; + } + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_INFINIBAND; +} + +/*****************************************************************************/ + +static void +nm_device_infiniband_init(NMDeviceInfiniband *device) +{} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceInfiniband *device = NM_DEVICE_INFINIBAND(object); + + switch (prop_id) { + case PROP_CARRIER: + g_value_set_boolean(value, nm_device_infiniband_get_carrier(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_infiniband = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_INFINIBAND, + nm_device_infiniband_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_B("Carrier", PROP_CARRIER, NMDeviceInfiniband, _priv.carrier), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), ), ); + +static void +nm_device_infiniband_class_init(NMDeviceInfinibandClass *ib_class) +{ + GObjectClass * object_class = G_OBJECT_CLASS(ib_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS(ib_class); + + object_class->get_property = get_property; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceInfiniband:carrier: + * + * Whether the device has carrier. + **/ + obj_properties[PROP_CARRIER] = g_param_spec_boolean(NM_DEVICE_INFINIBAND_CARRIER, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_infiniband); +} diff --git a/src/libnm-client-impl/nm-device-ip-tunnel.c b/src/libnm-client-impl/nm-device-ip-tunnel.c new file mode 100644 index 0000000..14c7228 --- /dev/null +++ b/src/libnm-client-impl/nm-device-ip-tunnel.c @@ -0,0 +1,578 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-ip-tunnel.h" + +#include "nm-setting-connection.h" +#include "nm-setting-ip-tunnel.h" +#include "nm-utils.h" +#include "nm-object-private.h" +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_MODE, + PROP_PARENT, + PROP_LOCAL, + PROP_REMOTE, + PROP_TTL, + PROP_TOS, + PROP_PATH_MTU_DISCOVERY, + PROP_INPUT_KEY, + PROP_OUTPUT_KEY, + PROP_ENCAPSULATION_LIMIT, + PROP_FLOW_LABEL, + PROP_FLAGS, ); + +typedef struct { + NMLDBusPropertyO parent; + char * local; + char * remote; + char * input_key; + char * output_key; + guint32 mode; + guint32 flow_label; + guint32 flags; + guint8 ttl; + guint8 tos; + guint8 encapsulation_limit; + bool path_mtu_discovery; +} NMDeviceIPTunnelPrivate; + +struct _NMDeviceIPTunnel { + NMDevice parent; + NMDeviceIPTunnelPrivate _priv; +}; + +struct _NMDeviceIPTunnelClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceIPTunnel, nm_device_ip_tunnel, NM_TYPE_DEVICE) + +#define NM_DEVICE_IP_TUNNEL_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceIPTunnel, NM_IS_DEVICE_IP_TUNNEL, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_ip_tunnel_get_mode: + * @device: a #NMDeviceIPTunnel + * + * Returns: the tunneling mode + * + * Since: 1.2 + **/ +NMIPTunnelMode +nm_device_ip_tunnel_get_mode(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), 0); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->mode; +} + +/** + * nm_device_ip_tunnel_get_parent: + * @device: a #NMDeviceIPTunnel + * + * Returns: (transfer none): the device's parent device + * + * Since: 1.2 + **/ +NMDevice * +nm_device_ip_tunnel_get_parent(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), NULL); + + return nml_dbus_property_o_get_obj(&NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->parent); +} + +/** + * nm_device_ip_tunnel_get_local: + * @device: a #NMDeviceIPTunnel + * + * Returns: the local endpoint of the tunnel + * + * Since: 1.2 + **/ +const char * +nm_device_ip_tunnel_get_local(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->local); +} + +/** + * nm_device_ip_tunnel_get_remote: + * @device: a #NMDeviceIPTunnel + * + * Returns: the remote endpoint of the tunnel + * + * Since: 1.2 + **/ +const char * +nm_device_ip_tunnel_get_remote(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->remote); +} + +/** + * nm_device_ip_tunnel_get_ttl: + * @device: a #NMDeviceIPTunnel + * + * Returns: the TTL assigned to tunneled packets + * + * Since: 1.2 + **/ +guint8 +nm_device_ip_tunnel_get_ttl(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), 0); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->ttl; +} + +/** + * nm_device_ip_tunnel_get_tos: + * @device: a #NMDeviceIPTunnel + * + * Returns: type of service (IPv4) or traffic class (IPv6) assigned + * to tunneled packets. + * + * Since: 1.2 + **/ +guint8 +nm_device_ip_tunnel_get_tos(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), 0); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->tos; +} + +/** + * nm_device_ip_tunnel_get_path_mtu_discovery: + * @device: a #NMDeviceIPTunnel + * + * Returns: whether path MTU discovery is enabled + * + * Since: 1.2 + **/ +gboolean +nm_device_ip_tunnel_get_path_mtu_discovery(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), TRUE); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->path_mtu_discovery; +} + +/** + * nm_device_ip_tunnel_get_input_key: + * @device: a #NMDeviceIPTunnel + * + * Returns: the key used for incoming packets + * + * Since: 1.2 + **/ +const char * +nm_device_ip_tunnel_get_input_key(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->input_key); +} + +/** + * nm_device_ip_tunnel_get_output_key: + * @device: a #NMDeviceIPTunnel + * + * Returns: the key used for outgoing packets + * + * Since: 1.2 + **/ +const char * +nm_device_ip_tunnel_get_output_key(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->output_key); +} + +/** + * nm_device_ip_tunnel_get_encapsulation_limit: + * @device: a #NMDeviceIPTunnel + * + * Returns: the maximum permitted encapsulation level + * + * Since: 1.2 + **/ +guint8 +nm_device_ip_tunnel_get_encapsulation_limit(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), 0); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->encapsulation_limit; +} + +/** + * nm_device_ip_tunnel_get_flow_label: + * @device: a #NMDeviceIPTunnel + * + * Returns: the flow label assigned to tunnel packets + * + * Since: 1.2 + **/ +guint +nm_device_ip_tunnel_get_flow_label(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), 0); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->flow_label; +} + +/** + * nm_device_ip_tunnel_get_flags: + * @device: a #NMDeviceIPTunnel + * + * Returns: the tunnel flags + * + * Since: 1.12 + **/ +NMIPTunnelFlags +nm_device_ip_tunnel_get_flags(NMDeviceIPTunnel *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IP_TUNNEL(device), NM_IP_TUNNEL_FLAG_NONE); + + return NM_DEVICE_IP_TUNNEL_GET_PRIVATE(device)->flags; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS(nm_device_ip_tunnel_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_IP_TUNNEL_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not an IP tunnel connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_IP_TUNNEL; +} + +/*****************************************************************************/ + +static void +nm_device_ip_tunnel_init(NMDeviceIPTunnel *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(object); + + g_free(priv->local); + g_free(priv->remote); + g_free(priv->input_key); + g_free(priv->output_key); + + G_OBJECT_CLASS(nm_device_ip_tunnel_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceIPTunnel *device = NM_DEVICE_IP_TUNNEL(object); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_object(value, nm_device_ip_tunnel_get_parent(device)); + break; + case PROP_MODE: + g_value_set_uint(value, nm_device_ip_tunnel_get_mode(device)); + break; + case PROP_LOCAL: + g_value_set_string(value, nm_device_ip_tunnel_get_local(device)); + break; + case PROP_REMOTE: + g_value_set_string(value, nm_device_ip_tunnel_get_remote(device)); + break; + case PROP_TTL: + g_value_set_uint(value, nm_device_ip_tunnel_get_ttl(device)); + break; + case PROP_TOS: + g_value_set_uint(value, nm_device_ip_tunnel_get_tos(device)); + break; + case PROP_PATH_MTU_DISCOVERY: + g_value_set_boolean(value, nm_device_ip_tunnel_get_path_mtu_discovery(device)); + break; + case PROP_INPUT_KEY: + g_value_set_string(value, nm_device_ip_tunnel_get_input_key(device)); + break; + case PROP_OUTPUT_KEY: + g_value_set_string(value, nm_device_ip_tunnel_get_output_key(device)); + break; + case PROP_ENCAPSULATION_LIMIT: + g_value_set_uint(value, nm_device_ip_tunnel_get_encapsulation_limit(device)); + break; + case PROP_FLOW_LABEL: + g_value_set_uint(value, nm_device_ip_tunnel_get_flow_label(device)); + break; + case PROP_FLAGS: + g_value_set_uint(value, nm_device_ip_tunnel_get_flags(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_iptunnel = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL, + nm_device_ip_tunnel_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_Y("EncapsulationLimit", + PROP_ENCAPSULATION_LIMIT, + NMDeviceIPTunnel, + _priv.encapsulation_limit), + NML_DBUS_META_PROPERTY_INIT_U("Flags", PROP_FLAGS, NMDeviceIPTunnel, _priv.flags), + NML_DBUS_META_PROPERTY_INIT_U("FlowLabel", + PROP_FLOW_LABEL, + NMDeviceIPTunnel, + _priv.flow_label), + NML_DBUS_META_PROPERTY_INIT_S("InputKey", + PROP_INPUT_KEY, + NMDeviceIPTunnel, + _priv.input_key), + NML_DBUS_META_PROPERTY_INIT_S("Local", PROP_LOCAL, NMDeviceIPTunnel, _priv.local), + NML_DBUS_META_PROPERTY_INIT_U("Mode", PROP_MODE, NMDeviceIPTunnel, _priv.mode), + NML_DBUS_META_PROPERTY_INIT_S("OutputKey", + PROP_OUTPUT_KEY, + NMDeviceIPTunnel, + _priv.output_key), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Parent", + PROP_PARENT, + NMDeviceIPTunnel, + _priv.parent, + nm_device_get_type), + NML_DBUS_META_PROPERTY_INIT_B("PathMtuDiscovery", + PROP_PATH_MTU_DISCOVERY, + NMDeviceIPTunnel, + _priv.path_mtu_discovery), + NML_DBUS_META_PROPERTY_INIT_S("Remote", PROP_REMOTE, NMDeviceIPTunnel, _priv.remote), + NML_DBUS_META_PROPERTY_INIT_Y("Tos", PROP_TOS, NMDeviceIPTunnel, _priv.tos), + NML_DBUS_META_PROPERTY_INIT_Y("Ttl", PROP_TTL, NMDeviceIPTunnel, _priv.ttl), ), ); + +static void +nm_device_ip_tunnel_class_init(NMDeviceIPTunnelClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceIPTunnel); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDeviceIPTunnelPrivate, parent); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceIPTunnel:mode: + * + * The tunneling mode of the device. + * + * Since: 1.2 + **/ + obj_properties[PROP_MODE] = g_param_spec_uint(NM_DEVICE_IP_TUNNEL_MODE, + "", + "", + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:parent: + * + * The devices's parent device. + * + * Since: 1.2 + **/ + obj_properties[PROP_PARENT] = g_param_spec_object(NM_DEVICE_IP_TUNNEL_PARENT, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:local: + * + * The local endpoint of the tunnel. + * + * Since: 1.2 + **/ + obj_properties[PROP_LOCAL] = g_param_spec_string(NM_DEVICE_IP_TUNNEL_LOCAL, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:remote: + * + * The remote endpoint of the tunnel. + * + * Since: 1.2 + **/ + obj_properties[PROP_REMOTE] = g_param_spec_string(NM_DEVICE_IP_TUNNEL_REMOTE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:ttl: + * + * The TTL assigned to tunneled packets. 0 is a special value + * meaning that packets inherit the TTL value + * + * Since: 1.2 + **/ + obj_properties[PROP_TTL] = g_param_spec_uchar(NM_DEVICE_IP_TUNNEL_TTL, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:tos: + * + * The type of service (IPv4) or traffic class (IPv6) assigned to + * tunneled packets. + * + * Since: 1.2 + **/ + obj_properties[PROP_TOS] = g_param_spec_uchar(NM_DEVICE_IP_TUNNEL_TOS, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:path-mtu-discovery: + * + * Whether path MTU discovery is enabled on this tunnel. + * + * Since: 1.2 + **/ + obj_properties[PROP_PATH_MTU_DISCOVERY] = + g_param_spec_boolean(NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:input-key: + * + * The key used for tunneled input packets, if applicable. + * + * Since: 1.2 + **/ + obj_properties[PROP_INPUT_KEY] = g_param_spec_string(NM_DEVICE_IP_TUNNEL_INPUT_KEY, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:output-key: + * + * The key used for tunneled output packets, if applicable. + * + * Since: 1.2 + **/ + obj_properties[PROP_OUTPUT_KEY] = + g_param_spec_string(NM_DEVICE_IP_TUNNEL_OUTPUT_KEY, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:encapsulation-limit: + * + * How many additional levels of encapsulation are permitted to + * be prepended to packets. This property applies only to IPv6 + * tunnels. + * + * Since: 1.2 + **/ + obj_properties[PROP_ENCAPSULATION_LIMIT] = + g_param_spec_uchar(NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:flow-label: + * + * The flow label to assign to tunnel packets. This property + * applies only to IPv6 tunnels. + * + * Since: 1.2 + **/ + obj_properties[PROP_FLOW_LABEL] = g_param_spec_uint(NM_DEVICE_IP_TUNNEL_FLOW_LABEL, + "", + "", + 0, + (1 << 20) - 1, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIPTunnel:flags: + * + * Tunnel flags. + * + * Since: 1.12 + **/ + obj_properties[PROP_FLAGS] = g_param_spec_uint(NM_DEVICE_IP_TUNNEL_FLAGS, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_iptunnel); +} diff --git a/src/libnm-client-impl/nm-device-macsec.c b/src/libnm-client-impl/nm-device-macsec.c new file mode 100644 index 0000000..faa5be7 --- /dev/null +++ b/src/libnm-client-impl/nm-device-macsec.c @@ -0,0 +1,631 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-macsec.h" + +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-utils.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, + PROP_SCI, + PROP_CIPHER_SUITE, + PROP_ICV_LENGTH, + PROP_WINDOW, + PROP_ENCODING_SA, + PROP_ENCRYPT, + PROP_PROTECT, + PROP_INCLUDE_SCI, + PROP_ES, + PROP_SCB, + PROP_REPLAY_PROTECT, + PROP_VALIDATION, ); + +typedef struct { + NMLDBusPropertyO parent; + char * validation; + guint64 sci; + guint64 cipher_suite; + guint32 window; + guint8 icv_length; + guint8 encoding_sa; + bool encrypt; + bool protect; + bool include_sci; + bool es; + bool scb; + bool replay_protect; +} NMDeviceMacsecPrivate; + +struct _NMDeviceMacsec { + NMDevice parent; + NMDeviceMacsecPrivate _priv; +}; + +struct _NMDeviceMacsecClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceMacsec, nm_device_macsec, NM_TYPE_DEVICE) + +#define NM_DEVICE_MACSEC_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceMacsec, NM_IS_DEVICE_MACSEC, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_macsec_get_parent: + * @device: a #NMDeviceMacsec + * + * Returns: (transfer none): the device's parent device + * + * Since: 1.6 + **/ +NMDevice * +nm_device_macsec_get_parent(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), NULL); + + return nml_dbus_property_o_get_obj(&NM_DEVICE_MACSEC_GET_PRIVATE(device)->parent); +} + +/** + * nm_device_macsec_get_hw_address: (skip) + * @device: a #NMDeviceMacsec + * + * Gets the hardware (MAC) address of the #NMDeviceMacsec + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.6 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_macsec_get_hw_address(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_macsec_get_sci: + * @device: a #NMDeviceMacsec + * + * Gets the Secure Channel Identifier in use + * + * Returns: the SCI + * + * Since: 1.6 + **/ +guint64 +nm_device_macsec_get_sci(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), 0); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->sci; +} + +/** + * nm_device_macsec_get_icv_length: + * @device: a #NMDeviceMacsec + * + * Gets the length of ICV (Integrity Check Value) + * + * Returns: the length of ICV + * + * Since: 1.6 + **/ +guint8 +nm_device_macsec_get_icv_length(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), 0); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->icv_length; +} + +/** + * nm_device_macsec_get_cipher_suite: + * @device: a #NMDeviceMacsec + * + * Gets the set of cryptographic algorithms in use + * + * Returns: the set of cryptographic algorithms in use + * + * Since: 1.6 + **/ +guint64 +nm_device_macsec_get_cipher_suite(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), 0); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->cipher_suite; +} + +/** + * nm_device_macsec_get_window: + * @device: a #NMDeviceMacsec + * + * Gets the size of the replay window + * + * Returns: size of the replay window + * + * Since: 1.6 + **/ +guint +nm_device_macsec_get_window(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), 0); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->window; +} + +/** + * nm_device_macsec_get_encoding_sa: + * @device: a #NMDeviceMacsec + * + * Gets the value of the Association Number (0..3) for the Security + * Association in use. + * + * Returns: the current Security Association + * + * Since: 1.6 + **/ +guint8 +nm_device_macsec_get_encoding_sa(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), 0); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->encoding_sa; +} + +/** + * nm_device_macsec_get_validation: + * @device: a #NMDeviceMacsec + * + * Gets the validation mode for incoming packets (strict, check, + * disabled) + * + * Returns: the validation mode + * + * Since: 1.6 + **/ +const char * +nm_device_macsec_get_validation(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), NULL); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->validation; +} + +/** + * nm_device_macsec_get_encrypt: + * @device: a #NMDeviceMacsec + * + * Gets whether encryption of transmitted frames is enabled + * + * Returns: whether encryption is enabled + * + * Since: 1.6 + **/ +gboolean +nm_device_macsec_get_encrypt(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), FALSE); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->encrypt; +} + +/** + * nm_device_macsec_get_protect: + * @device: a #NMDeviceMacsec + * + * Gets whether protection of transmitted frames is enabled + * + * Returns: whether protection is enabled + * + * Since: 1.6 + **/ +gboolean +nm_device_macsec_get_protect(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), FALSE); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->protect; +} + +/** + * nm_device_macsec_get_include_sci: + * @device: a #NMDeviceMacsec + * + * Gets whether the SCI is always included in SecTAG for transmitted + * frames + * + * Returns: whether the SCI is always included + * + * Since: 1.6 + **/ +gboolean +nm_device_macsec_get_include_sci(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), FALSE); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->include_sci; +} + +/** + * nm_device_macsec_get_es: + * @device: a #NMDeviceMacsec + * + * Gets whether the ES (End station) bit is enabled in SecTAG for + * transmitted frames + * + * Returns: whether the ES (End station) bit is enabled + * + * Since: 1.6 + **/ +gboolean +nm_device_macsec_get_es(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), FALSE); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->es; +} + +/** + * nm_device_macsec_get_scb: + * @device: a #NMDeviceMacsec + * + * Gets whether the SCB (Single Copy Broadcast) bit is enabled in + * SecTAG for transmitted frames + * + * Returns: whether the SCB (Single Copy Broadcast) bit is enabled + * + * Since: 1.6 + **/ +gboolean +nm_device_macsec_get_scb(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), FALSE); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->scb; +} + +/** + * nm_device_macsec_get_replay_protect: + * @device: a #NMDeviceMacsec + * + * Gets whether replay protection is enabled + * + * Returns: whether replay protection is enabled + * + * Since: 1.6 + **/ +gboolean +nm_device_macsec_get_replay_protect(NMDeviceMacsec *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACSEC(device), FALSE); + + return NM_DEVICE_MACSEC_GET_PRIVATE(device)->replay_protect; +} + +/***********************************************************/ + +static void +nm_device_macsec_init(NMDeviceMacsec *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(object); + + g_free(priv->validation); + + G_OBJECT_CLASS(nm_device_macsec_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceMacsec *device = NM_DEVICE_MACSEC(object); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_object(value, nm_device_macsec_get_parent(device)); + break; + case PROP_SCI: + g_value_set_uint64(value, nm_device_macsec_get_sci(device)); + break; + case PROP_ICV_LENGTH: + g_value_set_uchar(value, nm_device_macsec_get_icv_length(device)); + break; + case PROP_CIPHER_SUITE: + g_value_set_uint64(value, nm_device_macsec_get_cipher_suite(device)); + break; + case PROP_WINDOW: + g_value_set_uint(value, nm_device_macsec_get_window(device)); + break; + case PROP_ENCODING_SA: + g_value_set_uchar(value, nm_device_macsec_get_encoding_sa(device)); + break; + case PROP_VALIDATION: + g_value_set_string(value, nm_device_macsec_get_validation(device)); + break; + case PROP_ENCRYPT: + g_value_set_boolean(value, nm_device_macsec_get_encrypt(device)); + break; + case PROP_PROTECT: + g_value_set_boolean(value, nm_device_macsec_get_protect(device)); + break; + case PROP_INCLUDE_SCI: + g_value_set_boolean(value, nm_device_macsec_get_include_sci(device)); + break; + case PROP_ES: + g_value_set_boolean(value, nm_device_macsec_get_es(device)); + break; + case PROP_SCB: + g_value_set_boolean(value, nm_device_macsec_get_scb(device)); + break; + case PROP_REPLAY_PROTECT: + g_value_set_boolean(value, nm_device_macsec_get_replay_protect(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_macsec = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_MACSEC, + nm_device_macsec_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_T("CipherSuite", + PROP_CIPHER_SUITE, + NMDeviceMacsec, + _priv.cipher_suite), + NML_DBUS_META_PROPERTY_INIT_Y("EncodingSa", + PROP_ENCODING_SA, + NMDeviceMacsec, + _priv.encoding_sa), + NML_DBUS_META_PROPERTY_INIT_B("Encrypt", PROP_ENCRYPT, NMDeviceMacsec, _priv.encrypt), + NML_DBUS_META_PROPERTY_INIT_B("Es", PROP_ES, NMDeviceMacsec, _priv.es), + NML_DBUS_META_PROPERTY_INIT_Y("IcvLength", + PROP_ICV_LENGTH, + NMDeviceMacsec, + _priv.icv_length), + NML_DBUS_META_PROPERTY_INIT_B("IncludeSci", + PROP_INCLUDE_SCI, + NMDeviceMacsec, + _priv.include_sci), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Parent", + PROP_PARENT, + NMDeviceMacsec, + _priv.parent, + nm_device_get_type), + NML_DBUS_META_PROPERTY_INIT_B("Protect", PROP_PROTECT, NMDeviceMacsec, _priv.protect), + NML_DBUS_META_PROPERTY_INIT_B("ReplayProtect", + PROP_REPLAY_PROTECT, + NMDeviceMacsec, + _priv.replay_protect), + NML_DBUS_META_PROPERTY_INIT_B("Scb", PROP_SCB, NMDeviceMacsec, _priv.scb), + NML_DBUS_META_PROPERTY_INIT_T("Sci", PROP_SCI, NMDeviceMacsec, _priv.sci), + NML_DBUS_META_PROPERTY_INIT_S("Validation", + PROP_VALIDATION, + NMDeviceMacsec, + _priv.validation), + NML_DBUS_META_PROPERTY_INIT_U("Window", PROP_WINDOW, NMDeviceMacsec, _priv.window), ), ); + +static void +nm_device_macsec_class_init(NMDeviceMacsecClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceMacsec); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDeviceMacsecPrivate, parent); + + /** + * NMDeviceMacsec:parent: + * + * The devices's parent device. + * + * Since: 1.6 + **/ + obj_properties[PROP_PARENT] = g_param_spec_object(NM_DEVICE_MACSEC_PARENT, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:sci: + * + * The Secure Channel Identifier in use. + * + * Since: 1.6 + **/ + obj_properties[PROP_SCI] = g_param_spec_uint64(NM_DEVICE_MACSEC_SCI, + "", + "", + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:icv-length: + * + * The length of ICV (Integrity Check Value). + * + * Since: 1.6 + **/ + obj_properties[PROP_ICV_LENGTH] = g_param_spec_uchar(NM_DEVICE_MACSEC_ICV_LENGTH, + "", + "", + 0, + G_MAXUINT8, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:cipher-suite: + * + * The set of cryptographic algorithms in use. + * + * Since: 1.6 + **/ + obj_properties[PROP_CIPHER_SUITE] = + g_param_spec_uint64(NM_DEVICE_MACSEC_CIPHER_SUITE, + "", + "", + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:window: + * + * The size of the replay window. + * + * Since: 1.6 + **/ + obj_properties[PROP_WINDOW] = g_param_spec_uint(NM_DEVICE_MACSEC_WINDOW, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:encoding-sa: + * + * The value of the Association Number (0..3) for the Security + * Association in use. + * + * Since: 1.6 + **/ + obj_properties[PROP_ENCODING_SA] = + g_param_spec_uchar(NM_DEVICE_MACSEC_ENCODING_SA, + "", + "", + 0, + G_MAXUINT8, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:validation: + * + * The validation mode for incoming packets (strict, check, + * disabled). + * + * Since: 1.6 + **/ + obj_properties[PROP_VALIDATION] = + g_param_spec_string(NM_DEVICE_MACSEC_VALIDATION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:encrypt: + * + * Whether encryption of transmitted frames is enabled. + * + * Since: 1.6 + **/ + obj_properties[PROP_ENCRYPT] = g_param_spec_boolean(NM_DEVICE_MACSEC_ENCRYPT, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:protect: + * + * Whether protection of transmitted frames is enabled. + * + * Since: 1.6 + **/ + obj_properties[PROP_PROTECT] = g_param_spec_boolean(NM_DEVICE_MACSEC_PROTECT, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:include-sci: + * + * Whether the SCI is always included in SecTAG for transmitted + * frames. + * + * Since: 1.6 + **/ + obj_properties[PROP_INCLUDE_SCI] = + g_param_spec_boolean(NM_DEVICE_MACSEC_INCLUDE_SCI, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:es: + * + * Whether the ES (End station) bit is enabled in SecTAG for + * transmitted frames. + * + * Since: 1.6 + **/ + obj_properties[PROP_ES] = g_param_spec_boolean(NM_DEVICE_MACSEC_ES, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:scb: + * + * Whether the SCB (Single Copy Broadcast) bit is enabled in + * SecTAG for transmitted frames. + * + * Since: 1.6 + **/ + obj_properties[PROP_SCB] = g_param_spec_boolean(NM_DEVICE_MACSEC_SCB, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacsec:replay-protect: + * + * Whether replay protection is enabled. + * + * Since: 1.6 + **/ + obj_properties[PROP_REPLAY_PROTECT] = + g_param_spec_boolean(NM_DEVICE_MACSEC_REPLAY_PROTECT, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_macsec); +} diff --git a/src/libnm-client-impl/nm-device-macvlan.c b/src/libnm-client-impl/nm-device-macvlan.c new file mode 100644 index 0000000..ddb36ba --- /dev/null +++ b/src/libnm-client-impl/nm-device-macvlan.c @@ -0,0 +1,299 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-setting-macvlan.h" + +#include "nm-setting-connection.h" +#include "nm-setting-wired.h" +#include "nm-utils.h" +#include "nm-device-macvlan.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, PROP_MODE, PROP_NO_PROMISC, PROP_TAP, ); + +typedef struct { + NMLDBusPropertyO parent; + char * mode; + bool no_promisc; + bool tap; +} NMDeviceMacvlanPrivate; + +struct _NMDeviceMacvlan { + NMDevice parent; + NMDeviceMacvlanPrivate _priv; +}; + +struct _NMDeviceMacvlanClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE) + +#define NM_DEVICE_MACVLAN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceMacvlan, NM_IS_DEVICE_MACVLAN, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_macvlan_get_parent: + * @device: a #NMDeviceMacvlan + * + * Returns: (transfer none): the device's parent device + * + * Since: 1.2 + **/ +NMDevice * +nm_device_macvlan_get_parent(NMDeviceMacvlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACVLAN(device), FALSE); + + return nml_dbus_property_o_get_obj(&NM_DEVICE_MACVLAN_GET_PRIVATE(device)->parent); +} + +/** + * nm_device_macvlan_get_mode: + * @device: a #NMDeviceMacvlan + * + * Gets the MACVLAN mode of the device. + * + * Returns: the MACVLAN mode. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.2 + **/ +const char * +nm_device_macvlan_get_mode(NMDeviceMacvlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACVLAN(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_MACVLAN_GET_PRIVATE(device)->mode); +} + +/** + * nm_device_macvlan_get_no_promisc + * @device: a #NMDeviceMacvlan + * + * Gets the no-promiscuous flag of the device. + * + * Returns: the no-promiscuous flag of the device. + * + * Since: 1.2 + **/ +gboolean +nm_device_macvlan_get_no_promisc(NMDeviceMacvlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACVLAN(device), FALSE); + + return NM_DEVICE_MACVLAN_GET_PRIVATE(device)->no_promisc; +} + +/** + * nm_device_macvlan_get_tap: + * @device: a #NMDeviceMacvlan + * + * Gets the device type (MACVLAN or MACVTAP). + * + * Returns: %TRUE if the device is a MACVTAP, %FALSE if it is a MACVLAN. + * + * Since: 1.2 + **/ +gboolean +nm_device_macvlan_get_tap(NMDeviceMacvlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACVLAN(device), FALSE); + + return NM_DEVICE_MACVLAN_GET_PRIVATE(device)->tap; +} + +/** + * nm_device_macvlan_get_hw_address: (skip) + * @device: a #NMDeviceMacvlan + * + * Gets the hardware (MAC) address of the #NMDeviceMacvlan + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.2 + * + * This property is not implemented yet, and the function always return NULL. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_macvlan_get_hw_address(NMDeviceMacvlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_MACVLAN(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE(device); + NMSettingMacvlan * s_macvlan; + + if (!NM_DEVICE_CLASS(nm_device_macvlan_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_MACVLAN_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a MAC-VLAN connection.")); + return FALSE; + } + + s_macvlan = nm_connection_get_setting_macvlan(connection); + if (s_macvlan) { + if (nm_setting_macvlan_get_tap(s_macvlan) != priv->tap) + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_MACVLAN; +} + +/*****************************************************************************/ + +static void +nm_device_macvlan_init(NMDeviceMacvlan *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE(object); + + g_free(priv->mode); + + G_OBJECT_CLASS(nm_device_macvlan_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceMacvlan *device = NM_DEVICE_MACVLAN(object); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_object(value, nm_device_macvlan_get_parent(device)); + break; + case PROP_MODE: + g_value_set_string(value, nm_device_macvlan_get_mode(device)); + break; + case PROP_NO_PROMISC: + g_value_set_boolean(value, nm_device_macvlan_get_no_promisc(device)); + break; + case PROP_TAP: + g_value_set_boolean(value, nm_device_macvlan_get_tap(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_macvlan = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_MACVLAN, + nm_device_macvlan_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_S("Mode", PROP_MODE, NMDeviceMacvlan, _priv.mode), + NML_DBUS_META_PROPERTY_INIT_B("NoPromisc", + PROP_NO_PROMISC, + NMDeviceMacvlan, + _priv.no_promisc), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Parent", + PROP_PARENT, + NMDeviceMacvlan, + _priv.parent, + nm_device_get_type), + NML_DBUS_META_PROPERTY_INIT_B("Tap", PROP_TAP, NMDeviceMacvlan, _priv.tap), ), ); + +static void +nm_device_macvlan_class_init(NMDeviceMacvlanClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceMacvlan); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDeviceMacvlanPrivate, parent); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceMacvlan:parent: + * + * The devices's parent device. + * + * Since: 1.2 + **/ + obj_properties[PROP_PARENT] = g_param_spec_object(NM_DEVICE_MACVLAN_PARENT, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacvlan:mode: + * + * The MACVLAN mode. + * + * Since: 1.2 + **/ + obj_properties[PROP_MODE] = g_param_spec_string(NM_DEVICE_MACVLAN_MODE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacvlan:no-promisc: + * + * Whether the device has the no-promiscuos flag. + * + * Since: 1.2 + **/ + obj_properties[PROP_NO_PROMISC] = + g_param_spec_boolean(NM_DEVICE_MACVLAN_NO_PROMISC, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceMacvlan:tap: + * + * Whether the device is a MACVTAP. + * + * Since: 1.2 + **/ + obj_properties[PROP_TAP] = g_param_spec_boolean(NM_DEVICE_MACVLAN_TAP, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_macvlan); +} diff --git a/src/libnm-client-impl/nm-device-modem.c b/src/libnm-client-impl/nm-device-modem.c new file mode 100644 index 0000000..57e09bc --- /dev/null +++ b/src/libnm-client-impl/nm-device-modem.c @@ -0,0 +1,360 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2012 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-modem.h" + +#include "nm-setting-connection.h" +#include "nm-setting-gsm.h" +#include "nm-setting-cdma.h" +#include "nm-object-private.h" +#include "nm-enum-types.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_MODEM_CAPABILITIES, + PROP_CURRENT_CAPABILITIES, + PROP_DEVICE_ID, + PROP_OPERATOR_CODE, + PROP_APN, ); + +typedef struct { + char * device_id; + char * operator_code; + char * apn; + guint32 modem_capabilities; + guint32 current_capabilities; +} NMDeviceModemPrivate; + +struct _NMDeviceModem { + NMDevice parent; + NMDeviceModemPrivate _priv; +}; + +struct _NMDeviceModemClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) + +#define NM_DEVICE_MODEM_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceModem, NM_IS_DEVICE_MODEM, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_modem_get_modem_capabilities: + * @self: a #NMDeviceModem + * + * Returns a bitfield of the generic access technology families the modem + * supports. Not all capabilities are available concurrently however; some + * may require a firmware reload or reinitialization. + * + * Returns: the generic access technology families the modem supports + **/ +NMDeviceModemCapabilities +nm_device_modem_get_modem_capabilities(NMDeviceModem *self) +{ + g_return_val_if_fail(NM_IS_DEVICE_MODEM(self), NM_DEVICE_MODEM_CAPABILITY_NONE); + + return NM_DEVICE_MODEM_GET_PRIVATE(self)->modem_capabilities; +} + +/** + * nm_device_modem_get_current_capabilities: + * @self: a #NMDeviceModem + * + * Returns a bitfield of the generic access technology families the modem + * supports without a firmware reload or reinitialization. This value + * represents the network types the modem can immediately connect to. + * + * Returns: the generic access technology families the modem supports without + * a firmware reload or other reinitialization + **/ +NMDeviceModemCapabilities +nm_device_modem_get_current_capabilities(NMDeviceModem *self) +{ + g_return_val_if_fail(NM_IS_DEVICE_MODEM(self), NM_DEVICE_MODEM_CAPABILITY_NONE); + + return NM_DEVICE_MODEM_GET_PRIVATE(self)->current_capabilities; +} + +/** + * nm_device_modem_get_device_id: + * @self: a #NMDeviceModem + * + * An identifier used by the modem backend (ModemManager) that aims to + * uniquely identify the a device. Can be used to match a connection to a + * particular device. + * + * Returns: a device-id string + * + * Since: 1.20 + **/ +const char * +nm_device_modem_get_device_id(NMDeviceModem *self) +{ + g_return_val_if_fail(NM_IS_DEVICE_MODEM(self), NULL); + + return NM_DEVICE_MODEM_GET_PRIVATE(self)->device_id; +} + +/** + * nm_device_modem_get_operator_code: + * @self: a #NMDeviceModem + * + * The MCC and MNC (concatenated) of the network the modem is connected to. + * + * Returns: the operator code or %NULL if disconnected or not a 3GPP modem. + * + * Since: 1.20 + **/ +const char * +nm_device_modem_get_operator_code(NMDeviceModem *self) +{ + g_return_val_if_fail(NM_IS_DEVICE_MODEM(self), NULL); + + return NM_DEVICE_MODEM_GET_PRIVATE(self)->operator_code; +} + +/** + * nm_device_modem_get_apn: + * @self: a #NMDeviceModem + * + * The access point name the modem is connected to. + * + * Returns: the APN name or %NULL if disconnected + * + * Since: 1.20 + **/ +const char * +nm_device_modem_get_apn(NMDeviceModem *self) +{ + g_return_val_if_fail(NM_IS_DEVICE_MODEM(self), NULL); + + return NM_DEVICE_MODEM_GET_PRIVATE(self)->apn; +} + +static const char * +get_type_description(NMDevice *device) +{ + NMDeviceModemCapabilities caps; + + caps = nm_device_modem_get_current_capabilities(NM_DEVICE_MODEM(device)); + if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) + return "gsm"; + else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) + return "cdma"; + else + return NULL; +} + +#define MODEM_CAPS_3GPP(caps) \ + (caps & (NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS | NM_DEVICE_MODEM_CAPABILITY_LTE)) + +#define MODEM_CAPS_3GPP2(caps) (caps & (NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingGsm * s_gsm; + NMSettingCdma * s_cdma; + NMDeviceModemCapabilities current_caps; + + if (!NM_DEVICE_CLASS(nm_device_modem_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_GSM_SETTING_NAME) + && !nm_connection_is_type(connection, NM_SETTING_CDMA_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a modem connection.")); + return FALSE; + } + + s_gsm = nm_connection_get_setting_gsm(connection); + s_cdma = nm_connection_get_setting_cdma(connection); + if (!s_cdma && !s_gsm) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection was not a valid modem connection.")); + return FALSE; + } + + current_caps = nm_device_modem_get_current_capabilities(NM_DEVICE_MODEM(device)); + if (!(s_gsm && MODEM_CAPS_3GPP(current_caps)) && !(s_cdma && MODEM_CAPS_3GPP2(current_caps))) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The device is lacking capabilities required by the connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + NMDeviceModemCapabilities caps; + + caps = nm_device_modem_get_current_capabilities(NM_DEVICE_MODEM(device)); + if (caps & (NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS | NM_DEVICE_MODEM_CAPABILITY_LTE)) + return NM_TYPE_SETTING_GSM; + else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) + return NM_TYPE_SETTING_CDMA; + else + return G_TYPE_INVALID; +} + +/*****************************************************************************/ + +static void +nm_device_modem_init(NMDeviceModem *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(object); + + g_free(priv->device_id); + g_free(priv->operator_code); + g_free(priv->apn); + + G_OBJECT_CLASS(nm_device_modem_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceModem *self = NM_DEVICE_MODEM(object); + + switch (prop_id) { + case PROP_MODEM_CAPABILITIES: + g_value_set_flags(value, nm_device_modem_get_modem_capabilities(self)); + break; + case PROP_CURRENT_CAPABILITIES: + g_value_set_flags(value, nm_device_modem_get_current_capabilities(self)); + break; + case PROP_DEVICE_ID: + g_value_set_string(value, nm_device_modem_get_device_id(self)); + break; + case PROP_OPERATOR_CODE: + g_value_set_string(value, nm_device_modem_get_operator_code(self)); + break; + case PROP_APN: + g_value_set_string(value, nm_device_modem_get_apn(self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_modem = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_MODEM, + nm_device_modem_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_S("Apn", PROP_APN, NMDeviceModem, _priv.apn), + NML_DBUS_META_PROPERTY_INIT_U("CurrentCapabilities", + PROP_CURRENT_CAPABILITIES, + NMDeviceModem, + _priv.current_capabilities), + NML_DBUS_META_PROPERTY_INIT_S("DeviceId", PROP_DEVICE_ID, NMDeviceModem, _priv.device_id), + NML_DBUS_META_PROPERTY_INIT_U("ModemCapabilities", + PROP_MODEM_CAPABILITIES, + NMDeviceModem, + _priv.modem_capabilities), + NML_DBUS_META_PROPERTY_INIT_S("OperatorCode", + PROP_OPERATOR_CODE, + NMDeviceModem, + _priv.operator_code), ), ); + +static void +nm_device_modem_class_init(NMDeviceModemClass *modem_class) +{ + GObjectClass * object_class = G_OBJECT_CLASS(modem_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS(modem_class); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + device_class->get_type_description = get_type_description; + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceModem:modem-capabilities: + * + * The generic family of access technologies the modem supports. Not all + * capabilities are available at the same time however; some modems require + * a firmware reload or other reinitialization to switch between eg + * CDMA/EVDO and GSM/UMTS. + **/ + obj_properties[PROP_MODEM_CAPABILITIES] = + g_param_spec_flags(NM_DEVICE_MODEM_MODEM_CAPABILITIES, + "", + "", + NM_TYPE_DEVICE_MODEM_CAPABILITIES, + NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceModem:current-capabilities: + * + * The generic family of access technologies the modem currently supports + * without a firmware reload or reinitialization. + **/ + obj_properties[PROP_CURRENT_CAPABILITIES] = + g_param_spec_flags(NM_DEVICE_MODEM_CURRENT_CAPABILITIES, + "", + "", + NM_TYPE_DEVICE_MODEM_CAPABILITIES, + NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceModem:device-id: + * + * Since: 1.20 + **/ + obj_properties[PROP_DEVICE_ID] = g_param_spec_string(NM_DEVICE_MODEM_DEVICE_ID, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceModem:operator-code: + * + * Since: 1.20 + **/ + obj_properties[PROP_OPERATOR_CODE] = + g_param_spec_string(NM_DEVICE_MODEM_OPERATOR_CODE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceModem:apn: + * + * Since: 1.20 + **/ + obj_properties[PROP_APN] = g_param_spec_string(NM_DEVICE_MODEM_APN, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_modem); +} diff --git a/src/libnm-client-impl/nm-device-olpc-mesh.c b/src/libnm-client-impl/nm-device-olpc-mesh.c new file mode 100644 index 0000000..779990a --- /dev/null +++ b/src/libnm-client-impl/nm-device-olpc-mesh.c @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-olpc-mesh.h" + +#include "nm-setting-connection.h" +#include "nm-setting-olpc-mesh.h" +#include "nm-object-private.h" +#include "nm-device-wifi.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_COMPANION, PROP_ACTIVE_CHANNEL, ); + +typedef struct { + NMLDBusPropertyO companion; + guint32 active_channel; +} NMDeviceOlpcMeshPrivate; + +struct _NMDeviceOlpcMesh { + NMDevice parent; + NMDeviceOlpcMeshPrivate _priv; +}; + +struct _NMDeviceOlpcMeshClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) + +#define NM_DEVICE_OLPC_MESH_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceOlpcMesh, NM_IS_DEVICE_OLPC_MESH, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_olpc_mesh_get_hw_address: (skip) + * @device: a #NMDeviceOlpcMesh + * + * Gets the hardware (MAC) address of the #NMDeviceOlpcMesh + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_olpc_mesh_get_hw_address(NMDeviceOlpcMesh *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_OLPC_MESH(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_olpc_mesh_get_companion: + * @device: a #NMDeviceOlpcMesh + * + * Gets the companion device of the #NMDeviceOlpcMesh. + * + * Returns: (transfer none): the companion of the device of %NULL + **/ +NMDeviceWifi * +nm_device_olpc_mesh_get_companion(NMDeviceOlpcMesh *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_OLPC_MESH(device), NULL); + + return nml_dbus_property_o_get_obj(&NM_DEVICE_OLPC_MESH_GET_PRIVATE(device)->companion); +} + +/** + * nm_device_olpc_mesh_get_active_channel: + * @device: a #NMDeviceOlpcMesh + * + * Returns the active channel of the #NMDeviceOlpcMesh device. + * + * Returns: active channel of the device + **/ +guint32 +nm_device_olpc_mesh_get_active_channel(NMDeviceOlpcMesh *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_OLPC_MESH(device), 0); + + return NM_DEVICE_OLPC_MESH_GET_PRIVATE(device)->active_channel; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS(nm_device_olpc_mesh_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_OLPC_MESH_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not an OLPC Mesh connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_OLPC_MESH; +} + +/*****************************************************************************/ + +static void +nm_device_olpc_mesh_init(NMDeviceOlpcMesh *device) +{} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceOlpcMesh *device = NM_DEVICE_OLPC_MESH(object); + + switch (prop_id) { + case PROP_COMPANION: + g_value_set_object(value, nm_device_olpc_mesh_get_companion(device)); + break; + case PROP_ACTIVE_CHANNEL: + g_value_set_uint(value, nm_device_olpc_mesh_get_active_channel(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_olpcmesh = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_OLPC_MESH, + nm_device_olpc_mesh_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_U("ActiveChannel", + PROP_ACTIVE_CHANNEL, + NMDeviceOlpcMesh, + _priv.active_channel), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Companion", + PROP_COMPANION, + NMDeviceOlpcMesh, + _priv.companion, + nm_device_wifi_get_type), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), ), ); + +static void +nm_device_olpc_mesh_class_init(NMDeviceOlpcMeshClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceOlpcMesh); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDeviceOlpcMeshPrivate, companion); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceOlpcMesh:companion: + * + * The companion device. + **/ + obj_properties[PROP_COMPANION] = g_param_spec_object(NM_DEVICE_OLPC_MESH_COMPANION, + "", + "", + NM_TYPE_DEVICE_WIFI, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceOlpcMesh:active-channel: + * + * The device's active channel. + **/ + obj_properties[PROP_ACTIVE_CHANNEL] = + g_param_spec_uint(NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_olpcmesh); +} diff --git a/src/libnm-client-impl/nm-device-ovs-bridge.c b/src/libnm-client-impl/nm-device-ovs-bridge.c new file mode 100644 index 0000000..898a41f --- /dev/null +++ b/src/libnm-client-impl/nm-device-ovs-bridge.c @@ -0,0 +1,169 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017, 2018 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-ovs-bridge.h" + +#include "nm-object-private.h" +#include "nm-setting-ovs-bridge.h" +#include "nm-setting-ovs-port.h" +#include "nm-setting-connection.h" +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_SLAVES, ); + +typedef struct { + NMLDBusPropertyAO slaves; +} NMDeviceOvsBridgePrivate; + +struct _NMDeviceOvsBridge { + NMDevice parent; + NMDeviceOvsBridgePrivate _priv; +}; + +struct _NMDeviceOvsBridgeClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceOvsBridge, nm_device_ovs_bridge, NM_TYPE_DEVICE) + +#define NM_DEVICE_OVS_BRIDGE_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceOvsBridge, NM_IS_DEVICE_OVS_BRIDGE, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_ovs_bridge_get_slaves: + * @device: a #NMDeviceOvsBridge + * + * Gets the ports currently enslaved to @device. + * + * Returns: (element-type NMDevice): the #GPtrArray containing + * #NMDevices that are slaves of @device. This is the internal + * copy used by the device, and must not be modified. + * + * Since: 1.14 + **/ +const GPtrArray * +nm_device_ovs_bridge_get_slaves(NMDeviceOvsBridge *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_OVS_BRIDGE(device), FALSE); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_DEVICE_OVS_BRIDGE_GET_PRIVATE(device)->slaves); +} + +static const char * +get_type_description(NMDevice *device) +{ + return "ovs-bridge"; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + const char *iface_name; + + if (!NM_DEVICE_CLASS(nm_device_ovs_bridge_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a ovs_bridge connection.")); + return FALSE; + } + + iface_name = nm_connection_get_interface_name(connection); + if (!iface_name) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection did not specify an interface name.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_OVS_BRIDGE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceOvsBridge *device = NM_DEVICE_OVS_BRIDGE(object); + + switch (prop_id) { + case PROP_SLAVES: + g_value_take_boxed(value, + _nm_utils_copy_object_array(nm_device_ovs_bridge_get_slaves(device))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_device_ovs_bridge_init(NMDeviceOvsBridge *device) +{} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsbridge = + NML_DBUS_META_IFACE_INIT_PROP(NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE, + nm_device_ovs_bridge_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Slaves", + PROP_SLAVES, + NMDeviceOvsBridge, + _priv.slaves, + nm_device_get_type), ), ); + +static void +nm_device_ovs_bridge_class_init(NMDeviceOvsBridgeClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceOvsBridge); + + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, NMDeviceOvsBridgePrivate, slaves); + + device_class->get_type_description = get_type_description; + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceOvsBridge:slaves: (type GPtrArray(NMDevice)) + * + * Gets the ports currently enslaved to the device. + * + * Since: 1.22 + */ + obj_properties[PROP_SLAVES] = g_param_spec_boxed(NM_DEVICE_OVS_BRIDGE_SLAVES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_ovsbridge); +} diff --git a/src/libnm-client-impl/nm-device-ovs-interface.c b/src/libnm-client-impl/nm-device-ovs-interface.c new file mode 100644 index 0000000..8632057 --- /dev/null +++ b/src/libnm-client-impl/nm-device-ovs-interface.c @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-ovs-interface.h" + +#include "nm-object-private.h" +#include "nm-setting-ovs-interface.h" +#include "nm-setting-ovs-port.h" +#include "nm-setting-connection.h" + +/*****************************************************************************/ + +struct _NMDeviceOvsInterface { + NMDevice parent; +}; + +struct _NMDeviceOvsInterfaceClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceOvsInterface, nm_device_ovs_interface, NM_TYPE_DEVICE) + +/*****************************************************************************/ + +static const char * +get_type_description(NMDevice *device) +{ + return "ovs-interface"; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + const char *iface_name; + + if (!NM_DEVICE_CLASS(nm_device_ovs_interface_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_OVS_INTERFACE_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a ovs_interface connection.")); + return FALSE; + } + + iface_name = nm_connection_get_interface_name(connection); + if (!iface_name) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection did not specify an interface name.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_OVS_INTERFACE; +} + +/*****************************************************************************/ + +static void +nm_device_ovs_interface_init(NMDeviceOvsInterface *device) +{} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsinterface = + NML_DBUS_META_IFACE_INIT(NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE, + nm_device_ovs_interface_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, ); + +static void +nm_device_ovs_interface_class_init(NMDeviceOvsInterfaceClass *ovs_interface_class) +{ + NMDeviceClass *device_class = NM_DEVICE_CLASS(ovs_interface_class); + + device_class->get_type_description = get_type_description; + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; +} diff --git a/src/libnm-client-impl/nm-device-ovs-port.c b/src/libnm-client-impl/nm-device-ovs-port.c new file mode 100644 index 0000000..db30e1c --- /dev/null +++ b/src/libnm-client-impl/nm-device-ovs-port.c @@ -0,0 +1,169 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017, 2018 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-ovs-port.h" + +#include "nm-object-private.h" +#include "nm-setting-ovs-port.h" +#include "nm-setting-ovs-port.h" +#include "nm-setting-connection.h" +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_SLAVES, ); + +typedef struct { + NMLDBusPropertyAO slaves; +} NMDeviceOvsPortPrivate; + +struct _NMDeviceOvsPort { + NMDevice parent; + NMDeviceOvsPortPrivate _priv; +}; + +struct _NMDeviceOvsPortClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceOvsPort, nm_device_ovs_port, NM_TYPE_DEVICE) + +#define NM_DEVICE_OVS_PORT_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceOvsPort, NM_IS_DEVICE_OVS_PORT, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_ovs_port_get_slaves: + * @device: a #NMDeviceOvsPort + * + * Gets the interfaces currently enslaved to @device. + * + * Returns: (element-type NMDevice): the #GPtrArray containing + * #NMDevices that are slaves of @device. This is the internal + * copy used by the device, and must not be modified. + * + * Since: 1.14 + **/ +const GPtrArray * +nm_device_ovs_port_get_slaves(NMDeviceOvsPort *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_OVS_PORT(device), FALSE); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_DEVICE_OVS_PORT_GET_PRIVATE(device)->slaves); +} + +static const char * +get_type_description(NMDevice *device) +{ + return "ovs-port"; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + const char *iface_name; + + if (!NM_DEVICE_CLASS(nm_device_ovs_port_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_OVS_PORT_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a ovs_port connection.")); + return FALSE; + } + + iface_name = nm_connection_get_interface_name(connection); + if (!iface_name) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection did not specify an interface name.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_OVS_PORT; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceOvsPort *device = NM_DEVICE_OVS_PORT(object); + + switch (prop_id) { + case PROP_SLAVES: + g_value_take_boxed(value, + _nm_utils_copy_object_array(nm_device_ovs_port_get_slaves(device))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_device_ovs_port_init(NMDeviceOvsPort *device) +{} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsport = + NML_DBUS_META_IFACE_INIT_PROP(NM_DBUS_INTERFACE_DEVICE_OVS_PORT, + nm_device_ovs_port_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Slaves", + PROP_SLAVES, + NMDeviceOvsPort, + _priv.slaves, + nm_device_get_type), ), ); + +static void +nm_device_ovs_port_class_init(NMDeviceOvsPortClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceOvsPort); + + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, NMDeviceOvsPortPrivate, slaves); + + device_class->get_type_description = get_type_description; + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceOvsPort:slaves: (type GPtrArray(NMDevice)) + * + * Gets the interfaces currently enslaved to the device. + * + * Since: 1.22 + */ + obj_properties[PROP_SLAVES] = g_param_spec_boxed(NM_DEVICE_OVS_PORT_SLAVES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_ovsport); +} diff --git a/src/libnm-client-impl/nm-device-ppp.c b/src/libnm-client-impl/nm-device-ppp.c new file mode 100644 index 0000000..1dd275c --- /dev/null +++ b/src/libnm-client-impl/nm-device-ppp.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-ppp.h" + +#include "nm-device.h" + +/*****************************************************************************/ + +struct _NMDevicePpp { + NMDevice parent; +}; + +struct _NMDevicePppClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDevicePpp, nm_device_ppp, NM_TYPE_DEVICE) + +/*****************************************************************************/ + +static void +nm_device_ppp_init(NMDevicePpp *device) +{} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ppp = + NML_DBUS_META_IFACE_INIT(NM_DBUS_INTERFACE_DEVICE_PPP, + nm_device_ppp_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, ); + +static void +nm_device_ppp_class_init(NMDevicePppClass *klass) +{} diff --git a/src/libnm-client-impl/nm-device-private.h b/src/libnm-client-impl/nm-device-private.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/libnm-client-impl/nm-device-private.h diff --git a/src/libnm-client-impl/nm-device-team.c b/src/libnm-client-impl/nm-device-team.c new file mode 100644 index 0000000..ca29c9f --- /dev/null +++ b/src/libnm-client-impl/nm-device-team.c @@ -0,0 +1,247 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Jiri Pirko + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-team.h" + +#include "nm-setting-connection.h" +#include "nm-setting-team.h" +#include "nm-utils.h" +#include "nm-object-private.h" +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_CARRIER, PROP_SLAVES, PROP_CONFIG, ); + +typedef struct { + NMLDBusPropertyAO slaves; + char * config; + bool carrier; +} NMDeviceTeamPrivate; + +struct _NMDeviceTeam { + NMDevice parent; + NMDeviceTeamPrivate _priv; +}; + +struct _NMDeviceTeamClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) + +#define NM_DEVICE_TEAM_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceTeam, NM_IS_DEVICE_TEAM, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_team_get_hw_address: (skip) + * @device: a #NMDeviceTeam + * + * Gets the hardware (MAC) address of the #NMDeviceTeam + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_team_get_hw_address(NMDeviceTeam *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TEAM(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_team_get_carrier: + * @device: a #NMDeviceTeam + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_team_get_carrier(NMDeviceTeam *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TEAM(device), FALSE); + + return NM_DEVICE_TEAM_GET_PRIVATE(device)->carrier; +} + +/** + * nm_device_team_get_slaves: + * @device: a #NMDeviceTeam + * + * Gets the devices currently enslaved to @device. + * + * Returns: (element-type NMDevice): the #GPtrArray containing + * #NMDevices that are slaves of @device. This is the internal + * copy used by the device, and must not be modified. + **/ +const GPtrArray * +nm_device_team_get_slaves(NMDeviceTeam *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TEAM(device), FALSE); + + return nml_dbus_property_ao_get_objs_as_ptrarray(&NM_DEVICE_TEAM_GET_PRIVATE(device)->slaves); +} + +/** + * nm_device_team_get_config: + * @device: a #NMDeviceTeam + * + * Gets the current JSON configuration of the #NMDeviceTeam + * + * Returns: the current configuration. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.4 + **/ +const char * +nm_device_team_get_config(NMDeviceTeam *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TEAM(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_TEAM_GET_PRIVATE(device)->config); +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS(nm_device_team_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_TEAM_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection was not a team connection.")); + return FALSE; + } + + /* FIXME: check slaves? */ + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_TEAM; +} + +/*****************************************************************************/ + +static void +nm_device_team_init(NMDeviceTeam *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(object); + + g_free(priv->config); + + G_OBJECT_CLASS(nm_device_team_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceTeam *device = NM_DEVICE_TEAM(object); + + switch (prop_id) { + case PROP_CARRIER: + g_value_set_boolean(value, nm_device_team_get_carrier(device)); + break; + case PROP_SLAVES: + g_value_take_boxed(value, _nm_utils_copy_object_array(nm_device_team_get_slaves(device))); + break; + case PROP_CONFIG: + g_value_set_string(value, nm_device_team_get_config(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_team = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_TEAM, + nm_device_team_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_B("Carrier", PROP_CARRIER, NMDeviceTeam, _priv.carrier), + NML_DBUS_META_PROPERTY_INIT_S("Config", PROP_CONFIG, NMDeviceTeam, _priv.config), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Slaves", + PROP_SLAVES, + NMDeviceTeam, + _priv.slaves, + nm_device_get_type), ), ); + +static void +nm_device_team_class_init(NMDeviceTeamClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceTeam); + + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, NMDeviceTeamPrivate, slaves); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceTeam:carrier: + * + * Whether the device has carrier. + **/ + obj_properties[PROP_CARRIER] = g_param_spec_boolean(NM_DEVICE_TEAM_CARRIER, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceTeam:slaves: (type GPtrArray(NMDevice)) + * + * The devices enslaved to the team device. + **/ + obj_properties[PROP_SLAVES] = g_param_spec_boxed(NM_DEVICE_TEAM_SLAVES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceTeam:config: + * + * The current JSON configuration of the device. + * + * Since: 1.4 + **/ + obj_properties[PROP_CONFIG] = g_param_spec_string(NM_DEVICE_TEAM_CONFIG, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_team); +} diff --git a/src/libnm-client-impl/nm-device-tun.c b/src/libnm-client-impl/nm-device-tun.c new file mode 100644 index 0000000..8b8ca0f --- /dev/null +++ b/src/libnm-client-impl/nm-device-tun.c @@ -0,0 +1,394 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-tun.h" + +#include + +#include "nm-setting-connection.h" +#include "nm-setting-tun.h" +#include "nm-utils.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_MODE, + PROP_OWNER, + PROP_GROUP, + PROP_NO_PI, + PROP_VNET_HDR, + PROP_MULTI_QUEUE, ); + +typedef struct { + char * mode; + gint64 owner; + gint64 group; + bool no_pi; + bool vnet_hdr; + bool multi_queue; +} NMDeviceTunPrivate; + +struct _NMDeviceTun { + NMDevice parent; + NMDeviceTunPrivate _priv; +}; + +struct _NMDeviceTunClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceTun, nm_device_tun, NM_TYPE_DEVICE) + +#define NM_DEVICE_TUN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceTun, NM_IS_DEVICE_TUN, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_tun_get_hw_address: (skip) + * @device: a #NMDeviceTun + * + * Gets the hardware (MAC) address of the #NMDeviceTun + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.2 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_tun_get_hw_address(NMDeviceTun *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TUN(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_tun_get_mode: + * @device: a #NMDeviceTun + * + * Returns the TUN/TAP mode for the device. + * + * Returns: 'tun' or 'tap' + * + * Since: 1.2 + **/ +const char * +nm_device_tun_get_mode(NMDeviceTun *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TUN(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_TUN_GET_PRIVATE(device)->mode); +} + +/** + * nm_device_tun_get_owner: + * @device: a #NMDeviceTun + * + * Gets the tunnel owner. + * + * Returns: the uid of the tunnel owner, or -1 if it has no owner. + * + * Since: 1.2 + **/ +gint64 +nm_device_tun_get_owner(NMDeviceTun *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TUN(device), -1); + + return NM_DEVICE_TUN_GET_PRIVATE(device)->owner; +} + +/** + * nm_device_tun_get_group: + * @device: a #NMDeviceTun + * + * Gets the tunnel group. + * + * Returns: the gid of the tunnel group, or -1 if it has no owner. + * + * Since: 1.2 + **/ +gint64 +nm_device_tun_get_group(NMDeviceTun *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TUN(device), -1); + + return NM_DEVICE_TUN_GET_PRIVATE(device)->group; +} + +/** + * nm_device_tun_get_pi: + * @device: a #NMDeviceTun + * + * Returns whether the #NMDeviceTun has the IFF_NO_PI flag. + * + * Returns: %TRUE if the device has the flag, %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_device_tun_get_no_pi(NMDeviceTun *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TUN(device), FALSE); + + return NM_DEVICE_TUN_GET_PRIVATE(device)->no_pi; +} + +/** + * nm_device_tun_get_vnet_hdr: + * @device: a #NMDeviceTun + * + * Returns whether the #NMDeviceTun has the IFF_VNET_HDR flag. + * + * Returns: %TRUE if the device has the flag, %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_device_tun_get_vnet_hdr(NMDeviceTun *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TUN(device), FALSE); + + return NM_DEVICE_TUN_GET_PRIVATE(device)->vnet_hdr; +} + +/** + * nm_device_tun_get_multi_queue: + * @device: a #NMDeviceTun + * + * Returns whether the #NMDeviceTun has the IFF_MULTI_QUEUE flag. + * + * Returns: %TRUE if the device doesn't have the flag, %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_device_tun_get_multi_queue(NMDeviceTun *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_TUN(device), FALSE); + + return NM_DEVICE_TUN_GET_PRIVATE(device)->multi_queue; +} + +static int +tun_mode_from_string(const char *string) +{ + if (!g_strcmp0(string, "tap")) + return NM_SETTING_TUN_MODE_TAP; + else + return NM_SETTING_TUN_MODE_TUN; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE(device); + NMSettingTunMode mode; + NMSettingTun * s_tun; + + if (!NM_DEVICE_CLASS(nm_device_tun_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_TUN_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a tun connection.")); + return FALSE; + } + + s_tun = nm_connection_get_setting_tun(connection); + + mode = tun_mode_from_string(priv->mode); + if (s_tun && mode != nm_setting_tun_get_mode(s_tun)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The mode of the device and the connection didn't match")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_TUN; +} + +/*****************************************************************************/ + +static void +nm_device_tun_init(NMDeviceTun *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE(object); + + g_free(priv->mode); + + G_OBJECT_CLASS(nm_device_tun_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceTun *device = NM_DEVICE_TUN(object); + + switch (prop_id) { + case PROP_MODE: + g_value_set_string(value, nm_device_tun_get_mode(device)); + break; + case PROP_OWNER: + g_value_set_int64(value, nm_device_tun_get_owner(device)); + break; + case PROP_GROUP: + g_value_set_int64(value, nm_device_tun_get_group(device)); + break; + case PROP_NO_PI: + g_value_set_boolean(value, nm_device_tun_get_no_pi(device)); + break; + case PROP_VNET_HDR: + g_value_set_boolean(value, nm_device_tun_get_vnet_hdr(device)); + break; + case PROP_MULTI_QUEUE: + g_value_set_boolean(value, nm_device_tun_get_multi_queue(device)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_tun = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_TUN, + nm_device_tun_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_X("Group", PROP_GROUP, NMDeviceTun, _priv.group), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_S("Mode", PROP_MODE, NMDeviceTun, _priv.mode), + NML_DBUS_META_PROPERTY_INIT_B("MultiQueue", + PROP_MULTI_QUEUE, + NMDeviceTun, + _priv.multi_queue), + NML_DBUS_META_PROPERTY_INIT_B("NoPi", PROP_NO_PI, NMDeviceTun, _priv.no_pi), + NML_DBUS_META_PROPERTY_INIT_X("Owner", PROP_OWNER, NMDeviceTun, _priv.owner), + NML_DBUS_META_PROPERTY_INIT_B("VnetHdr", PROP_VNET_HDR, NMDeviceTun, _priv.vnet_hdr), ), ); + +static void +nm_device_tun_class_init(NMDeviceTunClass *gre_class) +{ + GObjectClass * object_class = G_OBJECT_CLASS(gre_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS(gre_class); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceTun:mode: + * + * The tunnel mode, either "tun" or "tap". + * + * Since: 1.2 + **/ + obj_properties[PROP_MODE] = g_param_spec_string(NM_DEVICE_TUN_MODE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceTun:owner: + * + * The uid of the tunnel owner, or -1 if it has no owner. + * + * Since: 1.2 + **/ + obj_properties[PROP_OWNER] = g_param_spec_int64(NM_DEVICE_TUN_OWNER, + "", + "", + -1, + G_MAXUINT32, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceTun:group: + * + * The gid of the tunnel group, or -1 if it has no owner. + * + * Since: 1.2 + **/ + obj_properties[PROP_GROUP] = g_param_spec_int64(NM_DEVICE_TUN_GROUP, + "", + "", + -1, + G_MAXUINT32, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceTun:no-pi: + * + * The tunnel's "TUN_NO_PI" flag; true if no protocol info is + * prepended to the tunnel packets. + * + * Since: 1.2 + **/ + obj_properties[PROP_NO_PI] = g_param_spec_boolean(NM_DEVICE_TUN_NO_PI, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceTun:vnet-hdr: + * + * The tunnel's "TUN_VNET_HDR" flag; true if the tunnel packets + * include a virtio network header. + * + * Since: 1.2 + **/ + obj_properties[PROP_VNET_HDR] = g_param_spec_boolean(NM_DEVICE_TUN_VNET_HDR, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceTun:multi-queue: + * + * The tunnel's "TUN_TAP_MQ" flag; true if callers can connect to + * the tap device multiple times, for multiple send/receive + * queues. + * + * Since: 1.2 + **/ + obj_properties[PROP_MULTI_QUEUE] = + g_param_spec_boolean(NM_DEVICE_TUN_MULTI_QUEUE, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_tun); +} diff --git a/src/libnm-client-impl/nm-device-veth.c b/src/libnm-client-impl/nm-device-veth.c new file mode 100644 index 0000000..f35f09b --- /dev/null +++ b/src/libnm-client-impl/nm-device-veth.c @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-veth.h" + +#include "nm-setting-connection.h" +#include "nm-setting-veth.h" +#include "nm-setting-wired.h" +#include "nm-utils.h" +#include "nm-device-ethernet.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PEER, ); + +typedef struct { + NMLDBusPropertyO peer; +} NMDeviceVethPrivate; + +struct _NMDeviceVeth { + NMDeviceEthernet parent; + NMDeviceVethPrivate _priv; +}; + +struct _NMDeviceVethClass { + NMDeviceEthernetClass parent; +}; + +G_DEFINE_TYPE(NMDeviceVeth, nm_device_veth, NM_TYPE_DEVICE_ETHERNET) + +#define NM_DEVICE_VETH_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceVeth, NM_IS_DEVICE_VETH, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_veth_get_peer: + * @device: a #NMDeviceVeth + * + * Returns: (transfer none): the device's peer device + * + * Since: 1.30 + **/ +NMDevice * +nm_device_veth_get_peer(NMDeviceVeth *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VETH(device), FALSE); + + return nml_dbus_property_o_get_obj(&NM_DEVICE_VETH_GET_PRIVATE(device)->peer); +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_VETH; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceVeth *device = NM_DEVICE_VETH(object); + + switch (prop_id) { + case PROP_PEER: + g_value_set_object(value, nm_device_veth_get_peer(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +nm_device_veth_init(NMDeviceVeth *device) +{} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_veth = + NML_DBUS_META_IFACE_INIT_PROP(NM_DBUS_INTERFACE_DEVICE_VETH, + nm_device_veth_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_O_PROP("Peer", + PROP_PEER, + NMDeviceVeth, + _priv.peer, + nm_device_get_type), ), ); + +static void +nm_device_veth_class_init(NMDeviceVethClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceVeth); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDeviceVethPrivate, peer); + + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceVeth:peer: + * + * The device's peer device. + * + * Since: 1.30 + **/ + obj_properties[PROP_PEER] = g_param_spec_object(NM_DEVICE_VETH_PEER, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_veth); +} diff --git a/src/libnm-client-impl/nm-device-vlan.c b/src/libnm-client-impl/nm-device-vlan.c new file mode 100644 index 0000000..4c2a435 --- /dev/null +++ b/src/libnm-client-impl/nm-device-vlan.c @@ -0,0 +1,257 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-vlan.h" + +#include "nm-setting-connection.h" +#include "nm-setting-vlan.h" +#include "nm-setting-wired.h" +#include "nm-utils.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_CARRIER, PROP_PARENT, PROP_VLAN_ID, ); + +typedef struct { + NMLDBusPropertyO parent; + guint32 vlan_id; + bool carrier; +} NMDeviceVlanPrivate; + +struct _NMDeviceVlan { + NMDevice parent; + NMDeviceVlanPrivate _priv; +}; + +struct _NMDeviceVlanClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE) + +#define NM_DEVICE_VLAN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceVlan, NM_IS_DEVICE_VLAN, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_vlan_get_hw_address: (skip) + * @device: a #NMDeviceVlan + * + * Gets the hardware (MAC) address of the #NMDeviceVlan + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_vlan_get_hw_address(NMDeviceVlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VLAN(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_vlan_get_carrier: + * @device: a #NMDeviceVlan + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_vlan_get_carrier(NMDeviceVlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VLAN(device), FALSE); + + return NM_DEVICE_VLAN_GET_PRIVATE(device)->carrier; +} + +/** + * nm_device_vlan_get_parent: + * @device: a #NMDeviceVlan + * + * Returns: (transfer none): the device's parent device + **/ +NMDevice * +nm_device_vlan_get_parent(NMDeviceVlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VLAN(device), FALSE); + + return nml_dbus_property_o_get_obj(&NM_DEVICE_VLAN_GET_PRIVATE(device)->parent); +} + +/** + * nm_device_vlan_get_vlan_id: + * @device: a #NMDeviceVlan + * + * Returns: the device's VLAN ID + **/ +guint +nm_device_vlan_get_vlan_id(NMDeviceVlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VLAN(device), FALSE); + + return NM_DEVICE_VLAN_GET_PRIVATE(device)->vlan_id; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingVlan * s_vlan; + NMSettingWired *s_wired; + const char * setting_hwaddr; + const char * hw_address; + + if (!NM_DEVICE_CLASS(nm_device_vlan_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_VLAN_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a VLAN connection.")); + return FALSE; + } + + s_vlan = nm_connection_get_setting_vlan(connection); + if (nm_setting_vlan_get_id(s_vlan) != nm_device_vlan_get_vlan_id(NM_DEVICE_VLAN(device))) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The VLAN identifiers of the device and the connection didn't match.")); + return FALSE; + } + + s_wired = nm_connection_get_setting_wired(connection); + if (s_wired) + setting_hwaddr = nm_setting_wired_get_mac_address(s_wired); + else + setting_hwaddr = NULL; + if (setting_hwaddr) { + hw_address = nm_device_get_hw_address(NM_DEVICE(device)); + + if (!hw_address || !nm_utils_hwaddr_matches(setting_hwaddr, -1, hw_address, -1)) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The hardware address of the device and the connection didn't match.")); + } + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_VLAN; +} + +/*****************************************************************************/ + +static void +nm_device_vlan_init(NMDeviceVlan *device) +{} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceVlan *device = NM_DEVICE_VLAN(object); + + switch (prop_id) { + case PROP_CARRIER: + g_value_set_boolean(value, nm_device_vlan_get_carrier(device)); + break; + case PROP_PARENT: + g_value_set_object(value, nm_device_vlan_get_parent(device)); + break; + case PROP_VLAN_ID: + g_value_set_uint(value, nm_device_vlan_get_vlan_id(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vlan = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_VLAN, + nm_device_vlan_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_B("Carrier", PROP_CARRIER, NMDeviceVlan, _priv.carrier), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Parent", + PROP_PARENT, + NMDeviceVlan, + _priv.parent, + nm_device_get_type), + NML_DBUS_META_PROPERTY_INIT_U("VlanId", PROP_VLAN_ID, NMDeviceVlan, _priv.vlan_id), ), ); + +static void +nm_device_vlan_class_init(NMDeviceVlanClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceVlan); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDeviceVlanPrivate, parent); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceVlan:carrier: + * + * Whether the device has carrier. + **/ + obj_properties[PROP_CARRIER] = g_param_spec_boolean(NM_DEVICE_VLAN_CARRIER, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVlan:parent: + * + * The devices's parent device. + **/ + obj_properties[PROP_PARENT] = g_param_spec_object(NM_DEVICE_VLAN_PARENT, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVlan:vlan-id: + * + * The device's VLAN ID. + **/ + obj_properties[PROP_VLAN_ID] = g_param_spec_uint(NM_DEVICE_VLAN_VLAN_ID, + "", + "", + 0, + 4095, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_vlan); +} diff --git a/src/libnm-client-impl/nm-device-vrf.c b/src/libnm-client-impl/nm-device-vrf.c new file mode 100644 index 0000000..bbf3781 --- /dev/null +++ b/src/libnm-client-impl/nm-device-vrf.c @@ -0,0 +1,145 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-vrf.h" + +#include "nm-setting-connection.h" +#include "nm-setting-vrf.h" +#include "nm-utils.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_TABLE, ); + +typedef struct { + guint32 table; +} NMDeviceVrfPrivate; + +struct _NMDeviceVrf { + NMDevice parent; + NMDeviceVrfPrivate _priv; +}; + +struct _NMDeviceVrfClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceVrf, nm_device_vrf, NM_TYPE_DEVICE) + +#define NM_DEVICE_VRF_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceVrf, NM_IS_DEVICE_VRF, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_vrf_get_table: + * @device: a #NMDeviceVrf + * + * Returns: the device's VRF routing table. + * + * Since: 1.24 + **/ +guint32 +nm_device_vrf_get_table(NMDeviceVrf *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VRF(device), 0); + + return NM_DEVICE_VRF_GET_PRIVATE(device)->table; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingVrf *s_vrf; + + if (!NM_DEVICE_CLASS(nm_device_vrf_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_VRF_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a VRF connection.")); + return FALSE; + } + + s_vrf = (NMSettingVrf *) nm_connection_get_setting(connection, NM_TYPE_SETTING_VRF); + if (nm_setting_vrf_get_table(s_vrf) != nm_device_vrf_get_table(NM_DEVICE_VRF(device))) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The VRF table of the device and the connection didn't match.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_VRF; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceVrf *device = NM_DEVICE_VRF(object); + + switch (prop_id) { + case PROP_TABLE: + g_value_set_uint(value, nm_device_vrf_get_table(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +nm_device_vrf_init(NMDeviceVrf *device) +{} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vrf = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_VRF, + nm_device_vrf_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_U("Table", PROP_TABLE, NMDeviceVrf, _priv.table), ), ); + +static void +nm_device_vrf_class_init(NMDeviceVrfClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceVrf); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceVrf:table: + * + * The device's VRF table. + * + * Since: 1.24 + **/ + obj_properties[PROP_TABLE] = g_param_spec_uint(NM_DEVICE_VRF_TABLE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_vrf); +} diff --git a/src/libnm-client-impl/nm-device-vxlan.c b/src/libnm-client-impl/nm-device-vxlan.c new file mode 100644 index 0000000..6fac3b7 --- /dev/null +++ b/src/libnm-client-impl/nm-device-vxlan.c @@ -0,0 +1,787 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-vxlan.h" + +#include "nm-setting-connection.h" +#include "nm-setting-vxlan.h" +#include "nm-utils.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_CARRIER, + PROP_PARENT, + PROP_ID, + PROP_GROUP, + PROP_LOCAL, + PROP_TOS, + PROP_TTL, + PROP_LIMIT, + PROP_LEARNING, + PROP_AGEING, + PROP_DST_PORT, + PROP_SRC_PORT_MIN, + PROP_SRC_PORT_MAX, + PROP_PROXY, + PROP_RSC, + PROP_L2MISS, + PROP_L3MISS, ); + +typedef struct { + NMLDBusPropertyO parent; + char * group; + char * local; + guint32 id; + guint32 limit; + guint32 ageing; + guint16 src_port_min; + guint16 src_port_max; + guint16 dst_port; + guint8 tos; + guint8 ttl; + bool learning; + bool proxy; + bool rsc; + bool l2miss; + bool l3miss; +} NMDeviceVxlanPrivate; + +struct _NMDeviceVxlan { + NMDevice parent; + NMDeviceVxlanPrivate _priv; +}; + +struct _NMDeviceVxlanClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceVxlan, nm_device_vxlan, NM_TYPE_DEVICE) + +#define NM_DEVICE_VXLAN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceVxlan, NM_IS_DEVICE_VXLAN, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_vxlan_get_hw_address: (skip) + * @device: a #NMDeviceVxlan + * + * Gets the hardware (MAC) address of the #NMDeviceVxlan + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.2 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_vxlan_get_hw_address(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_vxlan_get_carrier: + * @device: a #NMDeviceVxlan + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier. + * + * Since: 1.2 + * + * This property is not implemented yet, and the function always returns + * FALSE. + **/ +gboolean +nm_device_vxlan_get_carrier(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), FALSE); + + return FALSE; +} + +/** + * nm_device_vxlan_get_parent: + * @device: a #NMDeviceVxlan + * + * Returns: (transfer none): the device's parent device + * + * Since: 1.2 + **/ +NMDevice * +nm_device_vxlan_get_parent(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), NULL); + + return nml_dbus_property_o_get_obj(&NM_DEVICE_VXLAN_GET_PRIVATE(device)->parent); +} + +/** + * nm_device_vxlan_get_id: + * @device: a #NMDeviceVxlan + * + * Returns: the device's VXLAN ID. + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_id(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->id; +} + +/** + * nm_device_vxlan_get_group: + * @device: a #NMDeviceVxlan + * + * Returns: The unicast destination IP address or the multicast + * IP address joined + * + * Since: 1.2 + **/ +const char * +nm_device_vxlan_get_group(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_VXLAN_GET_PRIVATE(device)->group); +} + +/** + * nm_device_vxlan_get_local: + * @device: a #NMDeviceVxlan + * + * Returns: the source IP address to use in outgoing packets + * + * Since: 1.2 + **/ +const char * +nm_device_vxlan_get_local(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_VXLAN_GET_PRIVATE(device)->local); +} + +/** + * nm_device_vxlan_get_src_port_min: + * @device: a #NMDeviceVxlan + * + * Returns: the minimum UDP source port + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_src_port_min(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->src_port_min; +} + +/** + * nm_device_vxlan_get_src_port_max: + * @device: a #NMDeviceVxlan + * + * Returns: the maximum UDP source port + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_src_port_max(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->src_port_max; +} + +/** + * nm_device_vxlan_get_dst_port: + * @device: a #NMDeviceVxlan + * + * Returns: the UDP destination port + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_dst_port(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->dst_port; +} + +/** + * nm_device_vxlan_get_learning: + * @device: a #NMDeviceVxlan + * + * Returns: whether address learning is enabled + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_learning(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->learning; +} + +/** + * nm_device_vxlan_get_ageing: + * @device: a #NMDeviceVxlan + * + * Returns: the lifetime in seconds of FDB entries learnt by the kernel + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_ageing(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->ageing; +} + +/** + * nm_device_vxlan_get_tos: + * @device: a #NMDeviceVxlan + * + * Returns: the TOS value to use in outgoing packets + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_tos(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->tos; +} + +/** + * nm_device_vxlan_get_ttl: + * @device: a #NMDeviceVxlan + * + * Returns: the time-to-live value to use in outgoing packets + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_ttl(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->ttl; +} + +/** + * nm_device_vxlan_get_limit: + * @device: a #NMDeviceVxlan + * + * Returns: the maximum number of entries that can be added to the + * forwarding table + * + * Since: 1.2 + **/ +guint +nm_device_vxlan_get_limit(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), 0); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->limit; +} + +/** + * nm_device_vxlan_get_proxy: + * @device: a #NMDeviceVxlan + * + * Returns: whether ARP proxy is turned on + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_proxy(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->proxy; +} + +/** + * nm_device_vxlan_get_rsc: + * @device: a #NMDeviceVxlan + * + * Returns: whether route short circuit is turned on + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_rsc(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->rsc; +} + +/** + * nm_device_vxlan_get_l2miss: + * @device: a #NMDeviceVxlan + * + * Returns: whether netlink LL ADDR miss notifications are generated + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_l2miss(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->l2miss; +} + +/** + * nm_device_vxlan_get_l3miss: + * @device: a #NMDeviceVxlan + * + * Returns: whether netlink IP ADDR miss notifications are generated + * + * Since: 1.2 + **/ +gboolean +nm_device_vxlan_get_l3miss(NMDeviceVxlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VXLAN(device), FALSE); + + return NM_DEVICE_VXLAN_GET_PRIVATE(device)->l3miss; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingVxlan *s_vxlan; + + if (!NM_DEVICE_CLASS(nm_device_vxlan_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_VXLAN_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a VXLAN connection.")); + return FALSE; + } + + s_vxlan = nm_connection_get_setting_vxlan(connection); + if (nm_setting_vxlan_get_id(s_vxlan) != nm_device_vxlan_get_id(NM_DEVICE_VXLAN(device))) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The VXLAN identifiers of the device and the connection didn't match.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_VXLAN; +} + +/*****************************************************************************/ + +static void +nm_device_vxlan_init(NMDeviceVxlan *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE(object); + + g_free(priv->group); + g_free(priv->local); + + G_OBJECT_CLASS(nm_device_vxlan_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceVxlan *device = NM_DEVICE_VXLAN(object); + + switch (prop_id) { + case PROP_CARRIER: + g_value_set_boolean(value, nm_device_vxlan_get_carrier(device)); + break; + case PROP_PARENT: + g_value_set_object(value, nm_device_vxlan_get_parent(device)); + break; + case PROP_ID: + g_value_set_uint(value, nm_device_vxlan_get_id(device)); + break; + case PROP_GROUP: + g_value_set_string(value, nm_device_vxlan_get_group(device)); + break; + case PROP_LOCAL: + g_value_set_string(value, nm_device_vxlan_get_local(device)); + break; + case PROP_TOS: + g_value_set_uint(value, nm_device_vxlan_get_tos(device)); + break; + case PROP_TTL: + g_value_set_uint(value, nm_device_vxlan_get_ttl(device)); + break; + case PROP_LIMIT: + g_value_set_uint(value, nm_device_vxlan_get_limit(device)); + break; + case PROP_LEARNING: + g_value_set_boolean(value, nm_device_vxlan_get_learning(device)); + break; + case PROP_AGEING: + g_value_set_uint(value, nm_device_vxlan_get_ageing(device)); + break; + case PROP_DST_PORT: + g_value_set_uint(value, nm_device_vxlan_get_dst_port(device)); + break; + case PROP_SRC_PORT_MIN: + g_value_set_uint(value, nm_device_vxlan_get_src_port_min(device)); + break; + case PROP_SRC_PORT_MAX: + g_value_set_uint(value, nm_device_vxlan_get_src_port_max(device)); + break; + case PROP_PROXY: + g_value_set_boolean(value, nm_device_vxlan_get_proxy(device)); + break; + case PROP_RSC: + g_value_set_boolean(value, nm_device_vxlan_get_rsc(device)); + break; + case PROP_L2MISS: + g_value_set_boolean(value, nm_device_vxlan_get_l2miss(device)); + break; + case PROP_L3MISS: + g_value_set_boolean(value, nm_device_vxlan_get_l3miss(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vxlan = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_VXLAN, + nm_device_vxlan_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_U("Ageing", PROP_AGEING, NMDeviceVxlan, _priv.ageing), + NML_DBUS_META_PROPERTY_INIT_Q("DstPort", PROP_DST_PORT, NMDeviceVxlan, _priv.dst_port), + NML_DBUS_META_PROPERTY_INIT_S("Group", PROP_GROUP, NMDeviceVxlan, _priv.group), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_U("Id", PROP_ID, NMDeviceVxlan, _priv.id), + NML_DBUS_META_PROPERTY_INIT_B("L2miss", PROP_L2MISS, NMDeviceVxlan, _priv.l2miss), + NML_DBUS_META_PROPERTY_INIT_B("L3miss", PROP_L3MISS, NMDeviceVxlan, _priv.l3miss), + NML_DBUS_META_PROPERTY_INIT_B("Learning", PROP_LEARNING, NMDeviceVxlan, _priv.learning), + NML_DBUS_META_PROPERTY_INIT_U("Limit", PROP_LIMIT, NMDeviceVxlan, _priv.limit), + NML_DBUS_META_PROPERTY_INIT_S("Local", PROP_LOCAL, NMDeviceVxlan, _priv.local), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Parent", + PROP_PARENT, + NMDeviceVxlan, + _priv.parent, + nm_device_get_type), + NML_DBUS_META_PROPERTY_INIT_B("Proxy", PROP_PROXY, NMDeviceVxlan, _priv.proxy), + NML_DBUS_META_PROPERTY_INIT_B("Rsc", PROP_RSC, NMDeviceVxlan, _priv.rsc), + NML_DBUS_META_PROPERTY_INIT_Q("SrcPortMax", + PROP_SRC_PORT_MAX, + NMDeviceVxlan, + _priv.src_port_max), + NML_DBUS_META_PROPERTY_INIT_Q("SrcPortMin", + PROP_SRC_PORT_MIN, + NMDeviceVxlan, + _priv.src_port_min), + NML_DBUS_META_PROPERTY_INIT_Y("Tos", PROP_TOS, NMDeviceVxlan, _priv.tos), + NML_DBUS_META_PROPERTY_INIT_Y("Ttl", PROP_TTL, NMDeviceVxlan, _priv.ttl), ), ); + +static void +nm_device_vxlan_class_init(NMDeviceVxlanClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceVxlan); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDeviceVxlanPrivate, parent); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceVxlan:carrier: + * + * Whether the device has carrier. + * + * Since: 1.2 + * + * This property is not implemented yet, and the property is always FALSE. + **/ + obj_properties[PROP_CARRIER] = g_param_spec_boolean(NM_DEVICE_VXLAN_CARRIER, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:parent: + * + * The devices's parent device. + * + * Since: 1.2 + **/ + obj_properties[PROP_PARENT] = g_param_spec_object(NM_DEVICE_VXLAN_PARENT, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:id: + * + * The device's VXLAN ID. + * + * Since: 1.2 + **/ + obj_properties[PROP_ID] = g_param_spec_uint(NM_DEVICE_VXLAN_ID, + "", + "", + 0, + (1 << 24) - 1, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:group: + * + * The unicast destination IP address used in outgoing packets when the + * destination link layer address is not known in the VXLAN device + * forwarding database or the multicast IP address joined. + * + * Since: 1.2 + */ + obj_properties[PROP_GROUP] = g_param_spec_string(NM_DEVICE_VXLAN_GROUP, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:local: + * + * The source IP address to use in outgoing packets. + * + * Since: 1.2 + */ + obj_properties[PROP_LOCAL] = g_param_spec_string(NM_DEVICE_VXLAN_LOCAL, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:tos: + * + * The TOS value to use in outgoing packets. + * + * Since: 1.2 + */ + obj_properties[PROP_TOS] = g_param_spec_uchar(NM_DEVICE_VXLAN_TOS, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:ttl: + * + * The time-to-live value to use in outgoing packets. + * + * Since: 1.2 + */ + obj_properties[PROP_TTL] = g_param_spec_uchar(NM_DEVICE_VXLAN_TTL, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:learning: + * + * Whether unknown source link layer addresses and IP addresses are entered + * into the VXLAN device forwarding database. + * + * Since: 1.2 + */ + obj_properties[PROP_LEARNING] = g_param_spec_boolean(NM_DEVICE_VXLAN_LEARNING, + "", + "", + TRUE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:ageing: + * + * The lifetime in seconds of FDB entries learnt by the kernel. + * + * Since: 1.2 + */ + obj_properties[PROP_AGEING] = g_param_spec_uint(NM_DEVICE_VXLAN_AGEING, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:limit: + * + * The maximum number of entries that can be added to the forwarding table. + * + * Since: 1.2 + */ + obj_properties[PROP_LIMIT] = g_param_spec_uint(NM_DEVICE_VXLAN_LIMIT, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:dst-port: + * + * The UDP destination port used to communicate with the remote VXLAN tunnel + * endpoint. + * + * Since: 1.2 + */ + obj_properties[PROP_DST_PORT] = g_param_spec_uint(NM_DEVICE_VXLAN_DST_PORT, + "", + "", + 0, + 65535, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:src-port-min: + * + * The minimum UDP source port used to communicate with the remote VXLAN + * tunnel endpoint. + * + * Since: 1.2 + */ + obj_properties[PROP_SRC_PORT_MIN] = + g_param_spec_uint(NM_DEVICE_VXLAN_SRC_PORT_MIN, + "", + "", + 0, + 65535, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:src-port-max: + * + * The maximum UDP source port used to communicate with the remote VXLAN + * tunnel endpoint. + * + * Since: 1.2 + */ + obj_properties[PROP_SRC_PORT_MAX] = + g_param_spec_uint(NM_DEVICE_VXLAN_SRC_PORT_MAX, + "", + "", + 0, + 65535, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:proxy: + * + * Whether ARP proxy is turned on. + * + * Since: 1.2 + */ + obj_properties[PROP_PROXY] = g_param_spec_boolean(NM_DEVICE_VXLAN_PROXY, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:rsc: + * + * Whether route short circuit is turned on. + * + * Since: 1.2 + */ + obj_properties[PROP_RSC] = g_param_spec_boolean(NM_DEVICE_VXLAN_RSC, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:l2miss: + * + * Whether netlink LL ADDR miss notifications are generated. + * + * Since: 1.2 + */ + obj_properties[PROP_L2MISS] = g_param_spec_boolean(NM_DEVICE_VXLAN_L2MISS, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceVxlan:l3miss: + * + * Whether netlink IP ADDR miss notifications are generated. + * + * Since: 1.2 + */ + obj_properties[PROP_L3MISS] = g_param_spec_boolean(NM_DEVICE_VXLAN_L3MISS, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_vxlan); +} diff --git a/src/libnm-client-impl/nm-device-wifi-p2p.c b/src/libnm-client-impl/nm-device-wifi-p2p.c new file mode 100644 index 0000000..05c430f --- /dev/null +++ b/src/libnm-client-impl/nm-device-wifi-p2p.c @@ -0,0 +1,414 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 - 2019 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-wifi-p2p.h" + +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "nm-setting-connection.h" +#include "nm-setting-wifi-p2p.h" +#include "nm-utils.h" +#include "nm-wifi-p2p-peer.h" +#include "nm-object-private.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-dbus-helpers.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PEERS, ); + +enum { + PEER_ADDED, + PEER_REMOVED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +typedef struct { + NMLDBusPropertyAO peers; +} NMDeviceWifiP2PPrivate; + +struct _NMDeviceWifiP2P { + NMDevice parent; + NMDeviceWifiP2PPrivate _priv; +}; + +struct _NMDeviceWifiP2PClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceWifiP2P, nm_device_wifi_p2p, NM_TYPE_DEVICE) + +#define NM_DEVICE_WIFI_P2P_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceWifiP2P, NM_IS_DEVICE_WIFI_P2P, NMDevice, NMObject) + +/*****************************************************************************/ + +/** + * nm_device_wifi_p2p_get_hw_address: (skip) + * @device: a #NMDeviceWifiP2P + * + * Gets the actual hardware (MAC) address of the #NMDeviceWifiP2P + * + * Returns: the actual hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.16 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_wifi_p2p_get_hw_address(NMDeviceWifiP2P *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI_P2P(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_wifi_p2p_get_peers: + * @device: a #NMDeviceWifiP2P + * + * Gets all the found peers of the #NMDeviceWifiP2P. + * + * Returns: (element-type NMWifiP2PPeer): a #GPtrArray containing all the + * found #NMWifiP2PPeers. + * The returned array is owned by the client and should not be modified. + * + * Since: 1.16 + **/ +const GPtrArray * +nm_device_wifi_p2p_get_peers(NMDeviceWifiP2P *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI_P2P(device), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_DEVICE_WIFI_P2P_GET_PRIVATE(device)->peers); +} + +/** + * nm_device_wifi_p2p_get_peer_by_path: + * @device: a #NMDeviceWifiP2P + * @path: the object path of the peer + * + * Gets a #NMWifiP2PPeer by path. + * + * Returns: (transfer none): the peer or %NULL if none is found. + * + * Since: 1.16 + **/ +NMWifiP2PPeer * +nm_device_wifi_p2p_get_peer_by_path(NMDeviceWifiP2P *device, const char *path) +{ + const GPtrArray *peers; + int i; + NMWifiP2PPeer * peer = NULL; + + g_return_val_if_fail(NM_IS_DEVICE_WIFI_P2P(device), NULL); + g_return_val_if_fail(path != NULL, NULL); + + peers = nm_device_wifi_p2p_get_peers(device); + if (!peers) + return NULL; + + for (i = 0; i < peers->len; i++) { + NMWifiP2PPeer *candidate = g_ptr_array_index(peers, i); + if (!strcmp(nm_object_get_path(NM_OBJECT(candidate)), path)) { + peer = candidate; + break; + } + } + + return peer; +} + +/** + * nm_device_wifi_p2p_start_find: + * @device: a #NMDeviceWifiP2P + * @options: (allow-none): optional options passed to StartFind. + * @cancellable: a #GCancellable, or %NULL + * @callback: a #GAsyncReadyCallback, or %NULL + * @user_data: user_data for @callback + * + * Request NM to search for Wi-Fi P2P peers on @device. Note that the call + * returns immediately after requesting the find, and it may take some time + * after that for peers to be found. + * + * The find operation will run for 30s by default. You can stop it earlier + * using nm_device_p2p_wifi_stop_find(). + * + * Since: 1.16 + **/ +void +nm_device_wifi_p2p_start_find(NMDeviceWifiP2P * device, + GVariant * options, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_DEVICE_WIFI_P2P(device)); + g_return_if_fail(!options || g_variant_is_of_type(options, G_VARIANT_TYPE_VARDICT)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + if (!options) + options = g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0); + + _nm_client_dbus_call(_nm_object_get_client(device), + device, + nm_device_wifi_p2p_start_find, + cancellable, + callback, + user_data, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE_WIFI_P2P, + "StartFind", + g_variant_new("(@a{sv})", options), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_cb); +} + +/** + * nm_device_wifi_p2p_start_find_finish: + * @device: a #NMDeviceWifiP2P + * @result: the #GAsyncResult + * @error: #GError return address + * + * Finish an operation started by nm_device_wifi_p2p_start_find(). + * + * Returns: %TRUE if the call was successful + * + * Since: 1.16 + **/ +gboolean +nm_device_wifi_p2p_start_find_finish(NMDeviceWifiP2P *device, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI_P2P(device), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, device, nm_device_wifi_p2p_start_find), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/** + * nm_device_wifi_p2p_stop_find: + * @device: a #NMDeviceWifiP2P + * @cancellable: a #GCancellable, or %NULL + * @callback: a #GAsyncReadyCallback, or %NULL + * @user_data: user_data for @callback + * + * Request NM to stop any ongoing find operation for Wi-Fi P2P peers on @device. + * + * Since: 1.16 + **/ +void +nm_device_wifi_p2p_stop_find(NMDeviceWifiP2P * device, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_DEVICE_WIFI_P2P(device)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(_nm_object_get_client(device), + device, + nm_device_wifi_p2p_stop_find, + cancellable, + callback, + user_data, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE_WIFI_P2P, + "StopFind", + g_variant_new("()"), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_cb); +} + +/** + * nm_device_wifi_p2p_stop_find_finish: + * @device: a #NMDeviceWifiP2P + * @result: the #GAsyncResult + * @error: #GError return address + * + * Finish an operation started by nm_device_wifi_p2p_stop_find(). + * + * Returns: %TRUE if the call was successful + * + * Since: 1.16 + **/ +gboolean +nm_device_wifi_p2p_stop_find_finish(NMDeviceWifiP2P *device, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI_P2P(device), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, device, nm_device_wifi_p2p_stop_find), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS(nm_device_wifi_p2p_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_WIFI_P2P_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a Wi-Fi P2P connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_WIRELESS; +} + +static const char * +get_type_description(NMDevice *device) +{ + return "wifi-p2p"; +} + +/*****************************************************************************/ + +static void +_property_ao_notify_changed_peers_cb(NMLDBusPropertyAO *pr_ao, + NMClient * client, + NMObject * nmobj, + gboolean is_added /* or else removed */) +{ + _nm_client_notify_event_queue_emit_obj_signal(client, + G_OBJECT(pr_ao->owner_dbobj->nmobj), + nmobj, + is_added, + 10, + is_added ? signals[PEER_ADDED] + : signals[PEER_REMOVED]); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P(object); + + switch (prop_id) { + case PROP_PEERS: + g_value_take_boxed(value, _nm_utils_copy_object_array(nm_device_wifi_p2p_get_peers(self))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_device_wifi_p2p_init(NMDeviceWifiP2P *device) +{} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wifip2p = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_WIFI_P2P, + nm_device_wifi_p2p_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Peers", + PROP_PEERS, + NMDeviceWifiP2P, + _priv.peers, + nm_wifi_p2p_peer_get_type, + .notify_changed_ao = + _property_ao_notify_changed_peers_cb), ), ); + +static void +nm_device_wifi_p2p_class_init(NMDeviceWifiP2PClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceWifiP2P); + + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, NMDeviceWifiP2PPrivate, peers); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_type_description = get_type_description; + + /** + * NMDeviceWifiP2P:peers: (type GPtrArray(NMWifiP2PPeer)) + * + * List of all Wi-Fi P2P peers the device can see. + * + * Since: 1.16 + **/ + obj_properties[PROP_PEERS] = g_param_spec_boxed(NM_DEVICE_WIFI_P2P_PEERS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_wifip2p); + + /** + * NMDeviceWifiP2P::peer-added: + * @device: the Wi-Fi P2P device that received the signal + * @peer: the new access point + * + * Notifies that a #NMWifiP2PPeer is added to the Wi-Fi P2P device. + * + * Since: 1.16 + **/ + signals[PEER_ADDED] = g_signal_new("peer-added", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); + + /** + * NMDeviceWifiP2P::peer-removed: + * @device: the Wi-Fi P2P device that received the signal + * @peer: the removed access point + * + * Notifies that a #NMWifiP2PPeer is removed from the Wi-Fi P2P device. + * + * Since: 1.16 + **/ + signals[PEER_REMOVED] = g_signal_new("peer-removed", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); +} diff --git a/src/libnm-client-impl/nm-device-wifi.c b/src/libnm-client-impl/nm-device-wifi.c new file mode 100644 index 0000000..84c3a06 --- /dev/null +++ b/src/libnm-client-impl/nm-device-wifi.c @@ -0,0 +1,789 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2014 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-wifi.h" + +#include + +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "nm-setting-connection.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wireless-security.h" +#include "nm-utils.h" +#include "nm-access-point.h" +#include "nm-object-private.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-dbus-helpers.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PERM_HW_ADDRESS, + PROP_MODE, + PROP_BITRATE, + PROP_ACCESS_POINTS, + PROP_ACTIVE_ACCESS_POINT, + PROP_WIRELESS_CAPABILITIES, + PROP_LAST_SCAN, ); + +typedef struct { + NMLDBusPropertyAO access_points; + NMLDBusPropertyO active_access_point; + char * perm_hw_address; + gint64 last_scan; + guint32 mode; + guint32 bitrate; + guint32 wireless_capabilities; +} NMDeviceWifiPrivate; + +enum { + ACCESS_POINT_ADDED, + ACCESS_POINT_REMOVED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +struct _NMDeviceWifi { + NMDevice parent; + NMDeviceWifiPrivate _priv; +}; + +struct _NMDeviceWifiClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE) + +#define NM_DEVICE_WIFI_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceWifi, NM_IS_DEVICE_WIFI, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_wifi_get_hw_address: (skip) + * @device: a #NMDeviceWifi + * + * Gets the actual hardware (MAC) address of the #NMDeviceWifi + * + * Returns: the actual hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_wifi_get_hw_address(NMDeviceWifi *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +/** + * nm_device_wifi_get_permanent_hw_address: + * @device: a #NMDeviceWifi + * + * Gets the permanent hardware (MAC) address of the #NMDeviceWifi + * + * Returns: the permanent hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_wifi_get_permanent_hw_address(NMDeviceWifi *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_WIFI_GET_PRIVATE(device)->perm_hw_address); +} + +/** + * nm_device_wifi_get_mode: + * @device: a #NMDeviceWifi + * + * Gets the #NMDeviceWifi mode. + * + * Returns: the mode + **/ +NM80211Mode +nm_device_wifi_get_mode(NMDeviceWifi *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), 0); + + return NM_DEVICE_WIFI_GET_PRIVATE(device)->mode; +} + +/** + * nm_device_wifi_get_bitrate: + * @device: a #NMDeviceWifi + * + * Gets the bit rate of the #NMDeviceWifi in kbit/s. + * + * Returns: the bit rate (kbit/s) + **/ +guint32 +nm_device_wifi_get_bitrate(NMDeviceWifi *device) +{ + NMDeviceState state; + + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), 0); + + state = nm_device_get_state(NM_DEVICE(device)); + switch (state) { + case NM_DEVICE_STATE_IP_CONFIG: + case NM_DEVICE_STATE_IP_CHECK: + case NM_DEVICE_STATE_SECONDARIES: + case NM_DEVICE_STATE_ACTIVATED: + case NM_DEVICE_STATE_DEACTIVATING: + break; + default: + return 0; + } + + return NM_DEVICE_WIFI_GET_PRIVATE(device)->bitrate; +} + +/** + * nm_device_wifi_get_capabilities: + * @device: a #NMDeviceWifi + * + * Gets the Wi-Fi capabilities of the #NMDeviceWifi. + * + * Returns: the capabilities + **/ +NMDeviceWifiCapabilities +nm_device_wifi_get_capabilities(NMDeviceWifi *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), 0); + + return NM_DEVICE_WIFI_GET_PRIVATE(device)->wireless_capabilities; +} + +/** + * nm_device_wifi_get_active_access_point: + * @device: a #NMDeviceWifi + * + * Gets the active #NMAccessPoint. + * + * Returns: (transfer none): the access point or %NULL if none is active + **/ +NMAccessPoint * +nm_device_wifi_get_active_access_point(NMDeviceWifi *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), NULL); + + return nml_dbus_property_o_get_obj(&NM_DEVICE_WIFI_GET_PRIVATE(device)->active_access_point); +} + +/** + * nm_device_wifi_get_access_points: + * @device: a #NMDeviceWifi + * + * Gets all the scanned access points of the #NMDeviceWifi. + * + * Returns: (element-type NMAccessPoint): a #GPtrArray containing all the + * scanned #NMAccessPoints. + * The returned array is owned by the client and should not be modified. + **/ +const GPtrArray * +nm_device_wifi_get_access_points(NMDeviceWifi *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_DEVICE_WIFI_GET_PRIVATE(device)->access_points); +} + +/** + * nm_device_wifi_get_access_point_by_path: + * @device: a #NMDeviceWifi + * @path: the object path of the access point + * + * Gets a #NMAccessPoint by path. + * + * Returns: (transfer none): the access point or %NULL if none is found. + **/ +NMAccessPoint * +nm_device_wifi_get_access_point_by_path(NMDeviceWifi *device, const char *path) +{ + const GPtrArray *aps; + int i; + NMAccessPoint * ap = NULL; + + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), NULL); + g_return_val_if_fail(path != NULL, NULL); + + aps = nm_device_wifi_get_access_points(device); + if (!aps) + return NULL; + + for (i = 0; i < aps->len; i++) { + NMAccessPoint *candidate = g_ptr_array_index(aps, i); + if (!strcmp(nm_object_get_path(NM_OBJECT(candidate)), path)) { + ap = candidate; + break; + } + } + + return ap; +} + +/** + * nm_device_wifi_get_last_scan: + * @device: a #NMDeviceWifi + * + * Returns the timestamp (in CLOCK_BOOTTIME milliseconds) for the last finished + * network scan. A value of -1 means the device never scanned for access points. + * + * Use nm_utils_get_timestamp_msec() to obtain current time value suitable for + * comparing to this value. + * + * Returns: the last scan time in seconds + * + * Since: 1.12 + **/ +gint64 +nm_device_wifi_get_last_scan(NMDeviceWifi *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), -1); + + return NM_DEVICE_WIFI_GET_PRIVATE(device)->last_scan; +} + +/** + * nm_device_wifi_request_scan: + * @device: a #NMDeviceWifi + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Request NM to scan for access points on @device. Note that the function + * returns immediately after requesting the scan, and it may take some time + * after that for the scan to complete. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be + * set. + * + * Deprecated: 1.22: Use nm_device_wifi_request_scan_async() or GDBusConnection. + **/ +gboolean +nm_device_wifi_request_scan(NMDeviceWifi *device, GCancellable *cancellable, GError **error) +{ + return nm_device_wifi_request_scan_options(device, NULL, cancellable, error); +} + +/** + * nm_device_wifi_request_scan_options: + * @device: a #NMDeviceWifi + * @options: dictionary with options for RequestScan(), or %NULL + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Request NM to scan for access points on @device. Note that the function + * returns immediately after requesting the scan, and it may take some time + * after that for the scan to complete. + * This is the same as @nm_device_wifi_request_scan except it accepts @options + * for the scanning. The argument is the dictionary passed to RequestScan() + * D-Bus call. Valid options inside the dictionary are: + * 'ssids' => array of SSIDs (saay) + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be + * set. + * + * Since: 1.2 + * + * Deprecated: 1.22: Use nm_device_wifi_request_scan_options_async() or GDBusConnection. + **/ +gboolean +nm_device_wifi_request_scan_options(NMDeviceWifi *device, + GVariant * options, + GCancellable *cancellable, + GError ** error) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), FALSE); + g_return_val_if_fail(!options || g_variant_is_of_type(options, G_VARIANT_TYPE_VARDICT), FALSE); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + if (!options) + options = g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0); + + return _nm_client_dbus_call_sync_void(_nm_object_get_client(device), + cancellable, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + "RequestScan", + g_variant_new("(@a{sv})", options), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); +} + +NM_BACKPORT_SYMBOL( + libnm_1_0_6, + gboolean, + nm_device_wifi_request_scan_options, + (NMDeviceWifi * device, GVariant *options, GCancellable *cancellable, GError **error), + (device, options, cancellable, error)); + +/** + * nm_device_wifi_request_scan_async: + * @device: a #NMDeviceWifi + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the scan has been requested + * @user_data: caller-specific data passed to @callback + * + * Request NM to scan for access points on @device. Note that @callback will be + * called immediately after requesting the scan, and it may take some time after + * that for the scan to complete. + **/ +void +nm_device_wifi_request_scan_async(NMDeviceWifi * device, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + nm_device_wifi_request_scan_options_async(device, NULL, cancellable, callback, user_data); +} + +/** + * nm_device_wifi_request_scan_options_async: + * @device: a #NMDeviceWifi + * @options: dictionary with options for RequestScan(), or %NULL + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the scan has been requested + * @user_data: caller-specific data passed to @callback + * + * Request NM to scan for access points on @device. Note that @callback will be + * called immediately after requesting the scan, and it may take some time after + * that for the scan to complete. + * This is the same as @nm_device_wifi_request_scan_async except it accepts @options + * for the scanning. The argument is the dictionary passed to RequestScan() + * D-Bus call. Valid options inside the dictionary are: + * 'ssids' => array of SSIDs (saay) + * + * To complete the request call nm_device_wifi_request_scan_finish(). + * + * Since: 1.2 + **/ +void +nm_device_wifi_request_scan_options_async(NMDeviceWifi * device, + GVariant * options, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_DEVICE_WIFI(device)); + g_return_if_fail(!options || g_variant_is_of_type(options, G_VARIANT_TYPE_VARDICT)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + if (!options) + options = g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0); + + _nm_client_dbus_call(_nm_object_get_client(device), + device, + nm_device_wifi_request_scan_async, + cancellable, + callback, + user_data, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + "RequestScan", + g_variant_new("(@a{sv})", options), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +NM_BACKPORT_SYMBOL(libnm_1_0_6, + void, + nm_device_wifi_request_scan_options_async, + (NMDeviceWifi * device, + GVariant * options, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data), + (device, options, cancellable, callback, user_data)); + +/** + * nm_device_wifi_request_scan_finish: + * @device: a #NMDeviceWifi + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_wifi_request_scan_async() and + * nm_device_wifi_request_scan_options_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be + * set. + **/ +gboolean +nm_device_wifi_request_scan_finish(NMDeviceWifi *device, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIFI(device), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, device, nm_device_wifi_request_scan_async), + FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +#define WPA_CAPS \ + (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_WPA \ + | NM_WIFI_DEVICE_CAP_RSN) + +#define RSN_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN) + +static gboolean +has_proto(NMSettingWirelessSecurity *s_wsec, const char *proto) +{ + int i; + + for (i = 0; i < nm_setting_wireless_security_get_num_protos(s_wsec); i++) { + if (g_strcmp0(proto, nm_setting_wireless_security_get_proto(s_wsec, i)) == 0) + return TRUE; + } + return FALSE; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity *s_wsec; + const char * hwaddr, *setting_hwaddr; + NMDeviceWifiCapabilities wifi_caps; + const char * key_mgmt; + + if (!NM_DEVICE_CLASS(nm_device_wifi_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_WIRELESS_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a Wi-Fi connection.")); + return FALSE; + } + + /* Check MAC address */ + hwaddr = nm_device_wifi_get_permanent_hw_address(NM_DEVICE_WIFI(device)); + if (hwaddr) { + if (!nm_utils_hwaddr_valid(hwaddr, ETH_ALEN)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + _("Invalid device MAC address.")); + return FALSE; + } + s_wifi = nm_connection_get_setting_wireless(connection); + setting_hwaddr = nm_setting_wireless_get_mac_address(s_wifi); + if (setting_hwaddr && !nm_utils_hwaddr_matches(setting_hwaddr, -1, hwaddr, -1)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The MACs of the device and the connection didn't match.")); + return FALSE; + } + } + + /* Check device capabilities; we assume all devices can do WEP at least */ + + s_wsec = nm_connection_get_setting_wireless_security(connection); + if (s_wsec) { + /* Connection has security, verify it against the device's capabilities */ + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + if (nm_streq(key_mgmt, "wpa-psk") || nm_streq(key_mgmt, "wpa-eap") + || nm_streq(key_mgmt, "wpa-eap-suite-b-192")) { + wifi_caps = nm_device_wifi_get_capabilities(NM_DEVICE_WIFI(device)); + + /* Is device only WEP capable? */ + if (!(wifi_caps & WPA_CAPS)) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The device is lacking WPA capabilities required by the connection.")); + return FALSE; + } + + /* Make sure WPA2/RSN-only connections don't get chosen for WPA-only cards */ + if (has_proto(s_wsec, "rsn") && !has_proto(s_wsec, "wpa") && !(wifi_caps & RSN_CAPS)) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The device is lacking WPA2/RSN capabilities required by the connection.")); + return FALSE; + } + } + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_WIRELESS; +} + +/*****************************************************************************/ + +static void +_property_ao_notify_changed_access_points_cb(NMLDBusPropertyAO *pr_ao, + NMClient * client, + NMObject * nmobj, + gboolean is_added /* or else removed */) +{ + _nm_client_notify_event_queue_emit_obj_signal(client, + G_OBJECT(pr_ao->owner_dbobj->nmobj), + nmobj, + is_added, + 10, + is_added ? signals[ACCESS_POINT_ADDED] + : signals[ACCESS_POINT_REMOVED]); +} + +/*****************************************************************************/ + +static void +nm_device_wifi_init(NMDeviceWifi *device) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(device); + + priv->last_scan = -1; +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceWifi *self = NM_DEVICE_WIFI(object); + + switch (prop_id) { + case PROP_PERM_HW_ADDRESS: + g_value_set_string(value, nm_device_wifi_get_permanent_hw_address(self)); + break; + case PROP_MODE: + g_value_set_enum(value, nm_device_wifi_get_mode(self)); + break; + case PROP_BITRATE: + g_value_set_uint(value, nm_device_wifi_get_bitrate(self)); + break; + case PROP_ACTIVE_ACCESS_POINT: + g_value_set_object(value, nm_device_wifi_get_active_access_point(self)); + break; + case PROP_WIRELESS_CAPABILITIES: + g_value_set_flags(value, nm_device_wifi_get_capabilities(self)); + break; + case PROP_ACCESS_POINTS: + g_value_take_boxed(value, + _nm_utils_copy_object_array(nm_device_wifi_get_access_points(self))); + break; + case PROP_LAST_SCAN: + g_value_set_int64(value, nm_device_wifi_get_last_scan(self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +finalize(GObject *object) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(object); + + g_free(priv->perm_hw_address); + + G_OBJECT_CLASS(nm_device_wifi_parent_class)->finalize(object); +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wireless = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + nm_device_wifi_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_AO_PROP("AccessPoints", + PROP_ACCESS_POINTS, + NMDeviceWifi, + _priv.access_points, + nm_access_point_get_type, + .notify_changed_ao = + _property_ao_notify_changed_access_points_cb), + NML_DBUS_META_PROPERTY_INIT_O_PROP("ActiveAccessPoint", + PROP_ACTIVE_ACCESS_POINT, + NMDeviceWifi, + _priv.active_access_point, + nm_access_point_get_type), + NML_DBUS_META_PROPERTY_INIT_U("Bitrate", PROP_BITRATE, NMDeviceWifi, _priv.bitrate), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_X("LastScan", PROP_LAST_SCAN, NMDeviceWifi, _priv.last_scan), + NML_DBUS_META_PROPERTY_INIT_U("Mode", PROP_MODE, NMDeviceWifi, _priv.mode), + NML_DBUS_META_PROPERTY_INIT_S("PermHwAddress", + PROP_PERM_HW_ADDRESS, + NMDeviceWifi, + _priv.perm_hw_address), + NML_DBUS_META_PROPERTY_INIT_U("WirelessCapabilities", + PROP_WIRELESS_CAPABILITIES, + NMDeviceWifi, + _priv.wireless_capabilities), ), ); + +static void +nm_device_wifi_class_init(NMDeviceWifiClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceWifi); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, + NMDeviceWifiPrivate, + active_access_point); + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, NMDeviceWifiPrivate, access_points); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceWifi:perm-hw-address: + * + * The hardware (MAC) address of the device. + **/ + obj_properties[PROP_PERM_HW_ADDRESS] = + g_param_spec_string(NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWifi:mode: + * + * The mode of the device. + **/ + obj_properties[PROP_MODE] = g_param_spec_enum(NM_DEVICE_WIFI_MODE, + "", + "", + NM_TYPE_802_11_MODE, + NM_802_11_MODE_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWifi:bitrate: + * + * The bit rate of the device in kbit/s. + **/ + obj_properties[PROP_BITRATE] = g_param_spec_uint(NM_DEVICE_WIFI_BITRATE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWifi:active-access-point: + * + * The active #NMAccessPoint of the device. + **/ + obj_properties[PROP_ACTIVE_ACCESS_POINT] = + g_param_spec_object(NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, + "", + "", + NM_TYPE_ACCESS_POINT, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWifi:wireless-capabilities: + * + * The wireless capabilities of the device. + **/ + obj_properties[PROP_WIRELESS_CAPABILITIES] = + g_param_spec_flags(NM_DEVICE_WIFI_CAPABILITIES, + "", + "", + NM_TYPE_DEVICE_WIFI_CAPABILITIES, + NM_WIFI_DEVICE_CAP_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWifi:access-points: (type GPtrArray(NMAccessPoint)) + * + * List of all Wi-Fi access points the device can see. + **/ + obj_properties[PROP_ACCESS_POINTS] = + g_param_spec_boxed(NM_DEVICE_WIFI_ACCESS_POINTS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWifi:last-scan: + * + * The timestamp (in CLOCK_BOOTTIME seconds) for the last finished + * network scan. A value of -1 means the device never scanned for + * access points. + * + * Since: 1.12 + **/ + obj_properties[PROP_LAST_SCAN] = g_param_spec_int64(NM_DEVICE_WIFI_LAST_SCAN, + "", + "", + -1, + G_MAXINT64, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_wireless); + + /** + * NMDeviceWifi::access-point-added: + * @device: the Wi-Fi device that received the signal + * @ap: the new access point + * + * Notifies that a #NMAccessPoint is added to the Wi-Fi device. + **/ + signals[ACCESS_POINT_ADDED] = g_signal_new("access-point-added", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); + + /** + * NMDeviceWifi::access-point-removed: + * @device: the Wi-Fi device that received the signal + * @ap: the removed access point + * + * Notifies that a #NMAccessPoint is removed from the Wi-Fi device. + **/ + signals[ACCESS_POINT_REMOVED] = g_signal_new("access-point-removed", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); +} diff --git a/src/libnm-client-impl/nm-device-wimax.c b/src/libnm-client-impl/nm-device-wimax.c new file mode 100644 index 0000000..b9db20b --- /dev/null +++ b/src/libnm-client-impl/nm-device-wimax.c @@ -0,0 +1,389 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2012 Red Hat, Inc. + * Copyright (C) 2009 Novell, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-wimax.h" + +#include "nm-wimax-nsp.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_HW_ADDRESS, + PROP_ACTIVE_NSP, + PROP_CENTER_FREQ, + PROP_RSSI, + PROP_CINR, + PROP_TX_POWER, + PROP_BSID, + PROP_NSPS, ); + +enum { + NSP_ADDED, + NSP_REMOVED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +struct _NMDeviceWimax { + NMDevice parent; +}; + +struct _NMDeviceWimaxClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceWimax, nm_device_wimax, NM_TYPE_DEVICE) + +#define NM_DEVICE_WIMAX_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceWimax, NM_IS_DEVICE_WIMAX, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_wimax_get_hw_address: + * @wimax: a #NMDeviceWimax + * + * Gets the hardware (MAC) address of the #NMDeviceWimax + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +const char * +nm_device_wimax_get_hw_address(NMDeviceWimax *wimax) +{ + g_return_val_if_reached(NULL); +} + +/** + * nm_device_wimax_get_active_nsp: + * @wimax: a #NMDeviceWimax + * + * Gets the active #NMWimaxNsp. + * + * Returns: (transfer full): the access point or %NULL if none is active + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +NMWimaxNsp * +nm_device_wimax_get_active_nsp(NMDeviceWimax *wimax) +{ + g_return_val_if_reached(NULL); +} + +/** + * nm_device_wimax_get_nsps: + * @wimax: a #NMDeviceWimax + * + * Gets all the scanned NSPs of the #NMDeviceWimax. + * + * Returns: (element-type NMWimaxNsp): a #GPtrArray containing + * all the scanned #NMWimaxNsps. + * The returned array is owned by the client and should not be modified. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +const GPtrArray * +nm_device_wimax_get_nsps(NMDeviceWimax *wimax) +{ + g_return_val_if_reached(NULL); +} + +/** + * nm_device_wimax_get_nsp_by_path: + * @wimax: a #NMDeviceWimax + * @path: the object path of the NSP + * + * Gets a #NMWimaxNsp by path. + * + * Returns: (transfer none): the access point or %NULL if none is found. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +NMWimaxNsp * +nm_device_wimax_get_nsp_by_path(NMDeviceWimax *wimax, const char *path) +{ + g_return_val_if_reached(NULL); +} + +/** + * nm_device_wimax_get_center_frequency: + * @self: a #NMDeviceWimax + * + * Gets the center frequency (in KHz) of the radio channel the device is using + * to communicate with the network when connected. Has no meaning when the + * device is not connected. + * + * Returns: the center frequency in KHz, or 0 + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +guint +nm_device_wimax_get_center_frequency(NMDeviceWimax *self) +{ + g_return_val_if_reached(0); +} + +/** + * nm_device_wimax_get_rssi: + * @self: a #NMDeviceWimax + * + * Gets the RSSI of the current radio link in dBm. This value indicates how + * strong the raw received RF signal from the base station is, but does not + * indicate the overall quality of the radio link. Has no meaning when the + * device is not connected. + * + * Returns: the RSSI in dBm, or 0 + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +int +nm_device_wimax_get_rssi(NMDeviceWimax *self) +{ + g_return_val_if_reached(0); +} + +/** + * nm_device_wimax_get_cinr: + * @self: a #NMDeviceWimax + * + * Gets the CINR (Carrier to Interference + Noise Ratio) of the current radio + * link in dB. CINR is a more accurate measure of radio link quality. Has no + * meaning when the device is not connected. + * + * Returns: the CINR in dB, or 0 + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +int +nm_device_wimax_get_cinr(NMDeviceWimax *self) +{ + g_return_val_if_reached(0); +} + +/** + * nm_device_wimax_get_tx_power: + * @self: a #NMDeviceWimax + * + * Average power of the last burst transmitted by the device, in units of + * 0.5 dBm. i.e. a TxPower of -11 represents an actual device TX power of + * -5.5 dBm. Has no meaning when the device is not connected. + * + * Returns: the TX power in dBm, or 0 + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +int +nm_device_wimax_get_tx_power(NMDeviceWimax *self) +{ + g_return_val_if_reached(0); +} + +/** + * nm_device_wimax_get_bsid: + * @self: a #NMDeviceWimax + * + * Gets the ID of the serving Base Station when the device is connected. + * + * Returns: the ID of the serving Base Station, or %NULL + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +const char * +nm_device_wimax_get_bsid(NMDeviceWimax *self) +{ + g_return_val_if_reached(0); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + g_return_if_reached(); +} + +static void +nm_device_wimax_init(NMDeviceWimax *device) +{ + g_return_if_reached(); +} + +static void +nm_device_wimax_class_init(NMDeviceWimaxClass *wimax_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(wimax_class); + + object_class->get_property = get_property; + + /** + * NMDeviceWimax:hw-address: + * + * The hardware (MAC) address of the device. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + obj_properties[PROP_HW_ADDRESS] = + g_param_spec_string(NM_DEVICE_WIMAX_HW_ADDRESS, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWimax:active-nsp: + * + * The active #NMWimaxNsp of the device. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + obj_properties[PROP_ACTIVE_NSP] = + g_param_spec_object(NM_DEVICE_WIMAX_ACTIVE_NSP, + "", + "", + NM_TYPE_WIMAX_NSP, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWimax:center-frequency: + * + * The center frequency (in KHz) of the radio channel the device is using to + * communicate with the network when connected. Has no meaning when the + * device is not connected. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + obj_properties[PROP_CENTER_FREQ] = g_param_spec_uint(NM_DEVICE_WIMAX_CENTER_FREQUENCY, + "", + "", + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWimax:rssi: + * + * RSSI of the current radio link in dBm. This value indicates how strong + * the raw received RF signal from the base station is, but does not + * indicate the overall quality of the radio link. Has no meaning when the + * device is not connected. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + obj_properties[PROP_RSSI] = g_param_spec_int(NM_DEVICE_WIMAX_RSSI, + "", + "", + G_MININT, + G_MAXINT, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWimax:cinr: + * + * CINR (Carrier to Interference + Noise Ratio) of the current radio link + * in dB. CINR is a more accurate measure of radio link quality. Has no + * meaning when the device is not connected. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + obj_properties[PROP_CINR] = g_param_spec_int(NM_DEVICE_WIMAX_CINR, + "", + "", + G_MININT, + G_MAXINT, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWimax:tx-power: + * + * Average power of the last burst transmitted by the device, in units of + * 0.5 dBm. i.e. a TxPower of -11 represents an actual device TX power of + * -5.5 dBm. Has no meaning when the device is not connected. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + obj_properties[PROP_TX_POWER] = g_param_spec_int(NM_DEVICE_WIMAX_TX_POWER, + "", + "", + G_MININT, + G_MAXINT, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWimax:bsid: + * + * The ID of the serving base station as received from the network. Has + * no meaning when the device is not connected. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + obj_properties[PROP_BSID] = g_param_spec_string(NM_DEVICE_WIMAX_BSID, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWimax:nsps: (type GPtrArray(NMWimaxNsp)) + * + * List of all WiMAX Network Service Providers the device can see. + **/ + obj_properties[PROP_NSPS] = g_param_spec_boxed(NM_DEVICE_WIMAX_NSPS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + /** + * NMDeviceWimax::nsp-added: + * @self: the wimax device that received the signal + * @nsp: the new NSP + * + * Notifies that a #NMWimaxNsp is added to the wimax device. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + signals[NSP_ADDED] = g_signal_new("nsp-added", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); + + /** + * NMDeviceWimax::nsp-removed: + * @self: the wimax device that received the signal + * @nsp: the removed NSP + * + * Notifies that a #NMWimaxNsp is removed from the wimax device. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + signals[NSP_REMOVED] = g_signal_new("nsp-removed", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); +} diff --git a/src/libnm-client-impl/nm-device-wireguard.c b/src/libnm-client-impl/nm-device-wireguard.c new file mode 100644 index 0000000..cbbd904 --- /dev/null +++ b/src/libnm-client-impl/nm-device-wireguard.c @@ -0,0 +1,202 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Javier Arteaga + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-wireguard.h" + +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PUBLIC_KEY, PROP_LISTEN_PORT, PROP_FWMARK, ); + +typedef struct { + GBytes *public_key; + guint32 fwmark; + guint16 listen_port; +} NMDeviceWireGuardPrivate; + +struct _NMDeviceWireGuard { + NMDevice parent; + NMDeviceWireGuardPrivate _priv; +}; + +struct _NMDeviceWireGuardClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceWireGuard, nm_device_wireguard, NM_TYPE_DEVICE) + +#define NM_DEVICE_WIREGUARD_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceWireGuard, NM_IS_DEVICE_WIREGUARD, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_wireguard_get_public_key: + * @device: a #NMDeviceWireGuard + * + * Gets the public key for this interface + * + * Returns: (transfer none): the #GBytes containing the 32-byte public key + * + * Since: 1.14 + **/ +GBytes * +nm_device_wireguard_get_public_key(NMDeviceWireGuard *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIREGUARD(device), NULL); + + return NM_DEVICE_WIREGUARD_GET_PRIVATE(device)->public_key; +} + +/** + * nm_device_wireguard_get_listen_port: + * @device: a #NMDeviceWireGuard + * + * Gets the local UDP port this interface listens on + * + * Returns: UDP listen port + * + * Since: 1.14 + **/ +guint16 +nm_device_wireguard_get_listen_port(NMDeviceWireGuard *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIREGUARD(device), 0); + + return NM_DEVICE_WIREGUARD_GET_PRIVATE(device)->listen_port; +} + +/** + * nm_device_wireguard_get_fwmark: + * @device: a #NMDeviceWireGuard + * + * Gets the fwmark (firewall mark) for this interface. + * It can be used to set routing policy for outgoing encrypted packets. + * See: ip-rule(8) + * + * Returns: 0 if fwmark not in use, 32-bit fwmark value otherwise + * + * Since: 1.14 + **/ +guint32 +nm_device_wireguard_get_fwmark(NMDeviceWireGuard *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WIREGUARD(device), 0); + + return NM_DEVICE_WIREGUARD_GET_PRIVATE(device)->fwmark; +} + +/***********************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceWireGuard *device = NM_DEVICE_WIREGUARD(object); + + switch (prop_id) { + case PROP_PUBLIC_KEY: + g_value_set_boxed(value, nm_device_wireguard_get_public_key(device)); + break; + case PROP_LISTEN_PORT: + g_value_set_uint(value, nm_device_wireguard_get_listen_port(device)); + break; + case PROP_FWMARK: + g_value_set_uint(value, nm_device_wireguard_get_fwmark(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +nm_device_wireguard_init(NMDeviceWireGuard *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(object); + + g_bytes_unref(priv->public_key); + + G_OBJECT_CLASS(nm_device_wireguard_parent_class)->finalize(object); +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wireguard = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_WIREGUARD, + nm_device_wireguard_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_U("FwMark", PROP_FWMARK, NMDeviceWireGuard, _priv.fwmark), + NML_DBUS_META_PROPERTY_INIT_Q("ListenPort", + PROP_LISTEN_PORT, + NMDeviceWireGuard, + _priv.listen_port), + NML_DBUS_META_PROPERTY_INIT_AY("PublicKey", + PROP_PUBLIC_KEY, + NMDeviceWireGuard, + _priv.public_key), ), ); + +static void +nm_device_wireguard_class_init(NMDeviceWireGuardClass *wireguard_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(wireguard_class); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + /** + * NMDeviceWireGuard:public-key: + * + * 32-byte public key, derived from the current private key. + * + * Since: 1.14 + **/ + obj_properties[PROP_PUBLIC_KEY] = g_param_spec_boxed(NM_DEVICE_WIREGUARD_PUBLIC_KEY, + "", + "", + G_TYPE_BYTES, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWireGuard:listen-port: + * + * Local UDP listen port. + * Set to 0 to allow a random port to be chosen (default). + * + * Since: 1.14 + **/ + obj_properties[PROP_LISTEN_PORT] = g_param_spec_uint(NM_DEVICE_WIREGUARD_LISTEN_PORT, + "", + "", + 0, + G_MAXUINT16, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWireGuard:fwmark: + * + * Optional firewall mark - see ip-rule(8). + * Used when setting routing policy for outgoing encrypted packets. + * Set to 0 to disable the mark (default). + * + * Since: 1.14 + **/ + obj_properties[PROP_FWMARK] = g_param_spec_uint(NM_DEVICE_WIREGUARD_FWMARK, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_device_wireguard); +} diff --git a/src/libnm-client-impl/nm-device-wpan.c b/src/libnm-client-impl/nm-device-wpan.c new file mode 100644 index 0000000..30c1ea1 --- /dev/null +++ b/src/libnm-client-impl/nm-device-wpan.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Lubomir Rintel + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-wpan.h" + +#include "nm-object-private.h" +#include "nm-setting-wpan.h" +#include "nm-setting-connection.h" + +/*****************************************************************************/ + +struct _NMDeviceWpan { + NMDevice parent; +}; + +struct _NMDeviceWpanClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceWpan, nm_device_wpan, NM_TYPE_DEVICE) +/*****************************************************************************/ + +/** + * nm_device_wpan_get_hw_address: (skip) + * @device: a #NMDeviceWpan + * + * Gets the active hardware (MAC) address of the #NMDeviceWpan + * + * Returns: the active hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. + **/ +const char * +nm_device_wpan_get_hw_address(NMDeviceWpan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_WPAN(device), NULL); + + return nm_device_get_hw_address(NM_DEVICE(device)); +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS(nm_device_wpan_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_WPAN_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a wpan connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_WPAN; +} + +/*****************************************************************************/ + +static void +nm_device_wpan_init(NMDeviceWpan *device) +{} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wpan = NML_DBUS_META_IFACE_INIT( + NM_DBUS_INTERFACE_DEVICE_WPAN, + nm_device_wpan_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), ), ); + +static void +nm_device_wpan_class_init(NMDeviceWpanClass *wpan_class) +{ + NMDeviceClass *device_class = NM_DEVICE_CLASS(wpan_class); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; +} diff --git a/src/libnm-client-impl/nm-device.c b/src/libnm-client-impl/nm-device.c new file mode 100644 index 0000000..dd5f7d4 --- /dev/null +++ b/src/libnm-client-impl/nm-device.c @@ -0,0 +1,3080 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2018 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device.h" + +#include + +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "nm-dbus-interface.h" +#include "nm-active-connection.h" +#include "nm-device-bt.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" +#include "nm-object-private.h" +#include "nm-remote-connection.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-utils.h" +#include "nm-dbus-helpers.h" +#include "nm-device-tun.h" +#include "nm-setting-connection.h" +#include "libnm-udev-aux/nm-udev-utils.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMDevice, + PROP_INTERFACE, + PROP_UDI, + PROP_PATH, + PROP_DRIVER, + PROP_DRIVER_VERSION, + PROP_FIRMWARE_VERSION, + PROP_CAPABILITIES, + PROP_REAL, + PROP_MANAGED, + PROP_AUTOCONNECT, + PROP_FIRMWARE_MISSING, + PROP_NM_PLUGIN_MISSING, + PROP_IP4_CONFIG, + PROP_DHCP4_CONFIG, + PROP_IP6_CONFIG, + PROP_STATE, + PROP_STATE_REASON, + PROP_PRODUCT, + PROP_VENDOR, + PROP_DHCP6_CONFIG, + PROP_IP_INTERFACE, + PROP_DEVICE_TYPE, + PROP_ACTIVE_CONNECTION, + PROP_AVAILABLE_CONNECTIONS, + PROP_PHYSICAL_PORT_ID, + PROP_MTU, + PROP_METERED, + PROP_LLDP_NEIGHBORS, + PROP_IP4_CONNECTIVITY, + PROP_IP6_CONNECTIVITY, + PROP_INTERFACE_FLAGS, + PROP_HW_ADDRESS, ); + +enum { + STATE_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +enum { + PROPERTY_O_IDX_ACTIVE_CONNECTION, + PROPERTY_O_IDX_IP4_CONFIG, + PROPERTY_O_IDX_IP6_CONFIG, + PROPERTY_O_IDX_DHCP4_CONFIG, + PROPERTY_O_IDX_DHCP6_CONFIG, + _PROPERTY_O_IDX_NUM, +}; + +typedef struct _NMDevicePrivate { + NMLDBusPropertyO property_o[_PROPERTY_O_IDX_NUM]; + NMLDBusPropertyAO available_connections; + GPtrArray * lldp_neighbors; + char * driver; + char * driver_version; + char * hw_address; + char * interface; + char * ip_interface; + char * firmware_version; + char * physical_port_id; + char * udi; + char * path; + guint32 capabilities; + guint32 device_type; + guint32 ip4_connectivity; + guint32 ip6_connectivity; + guint32 metered; + guint32 mtu; + guint32 state; + guint32 state_reason; + guint32 interface_flags; + bool firmware_missing; + bool nm_plugin_missing; + bool autoconnect; + bool managed; + bool real; + + bool hw_address_is_new : 1; + + guint32 old_state; + + struct udev *udev; + char * type_description; + char * product; + char * vendor; + char * short_vendor; + char * description; + char * bus_name; + +} NMDevicePrivate; + +G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_OBJECT); + +#define NM_DEVICE_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMDevice, NM_IS_DEVICE, NMObject) + +/*****************************************************************************/ + +static gboolean connection_compatible(NMDevice *device, NMConnection *connection, GError **error); +static NMLldpNeighbor *_nm_lldp_neighbor_dup(NMLldpNeighbor *neighbor); + +/*****************************************************************************/ + +struct _NMLldpNeighbor { + int refcount; + GHashTable *attrs; +}; + +G_DEFINE_BOXED_TYPE(NMLldpNeighbor, nm_lldp_neighbor, _nm_lldp_neighbor_dup, nm_lldp_neighbor_unref) + +/*****************************************************************************/ + +static void +nm_device_init(NMDevice *self) +{ + NMDevicePrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_DEVICE, NMDevicePrivate); + + self->_priv = priv; + + priv->old_state = NM_DEVICE_STATE_UNKNOWN; +} + +/*****************************************************************************/ + +static void +_notify_event_state_changed(NMClient *client, NMClientNotifyEventWithPtr *notify_event) +{ + gs_unref_object NMDevice *self = notify_event->user_data; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + + NML_NMCLIENT_LOG_T(client, + "[%s] emit Device's StateChanged signal %u -> %u, reason: %u", + _nm_object_get_path(self), + (guint) priv->old_state, + (guint) priv->state, + (guint) priv->state_reason); + + g_signal_emit(self, + signals[STATE_CHANGED], + 0, + (guint) priv->state, + (guint) priv->old_state, + (guint) priv->state_reason); +} + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_state_reason(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMDevice * self = NM_DEVICE(dbobj->nmobj); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + guint32 new_state = NM_DEVICE_STATE_UNKNOWN; + guint32 reason = NM_DEVICE_STATE_REASON_NONE; + + /* We ignore the "State" property and the "StateChanged" signal of the device. + * This information is redundant to the "StateReason" property, and we rely + * on that one alone. In the best case, the information is identical. If it + * would not be, then we stick to the information from "StateReason" property. */ + + if (value) + g_variant_get(value, "(uu)", &new_state, &reason); + + if (priv->state == new_state && priv->state_reason == reason) { + /* no changes. */ + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; + } + + if (priv->state != new_state) { + priv->old_state = priv->state; + priv->state = new_state; + _nm_client_queue_notify_object(client, self, obj_properties[PROP_STATE]); + } + + if (priv->state_reason != reason) { + priv->state_reason = reason; + _nm_client_queue_notify_object(client, self, obj_properties[PROP_STATE_REASON]); + } + + _nm_client_notify_event_queue_with_ptr(client, + NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP + 1, + _notify_event_state_changed, + g_object_ref(self)); + + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; +} + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_lldp_neighbors(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMDevice * self = NM_DEVICE(dbobj->nmobj); + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + gs_unref_ptrarray GPtrArray *old = NULL; + gs_unref_ptrarray GPtrArray *new = NULL; + GVariantIter * attrs_iter; + GVariantIter iter; + + new = g_ptr_array_new_with_free_func((GDestroyNotify) nm_lldp_neighbor_unref); + + if (value) { + g_variant_iter_init(&iter, value); + while (g_variant_iter_next(&iter, "a{sv}", &attrs_iter)) { + GVariant * attr_variant; + const char * attr_name; + NMLldpNeighbor *neigh; + + /* Note that there is no public API to mutate a NMLldpNeighbor instance. + * This is the only place where we actually mutate it. */ + neigh = nm_lldp_neighbor_new(); + while (g_variant_iter_next(attrs_iter, "{&sv}", &attr_name, &attr_variant)) { + if (attr_name[0] == '\0') { + g_variant_unref(attr_variant); + continue; + } + g_hash_table_insert(neigh->attrs, g_strdup(attr_name), attr_variant); + } + + g_ptr_array_add(new, neigh); + + g_variant_iter_free(attrs_iter); + } + } + + old = g_steal_pointer(&priv->lldp_neighbors); + priv->lldp_neighbors = g_steal_pointer(&new); + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + +/*****************************************************************************/ + +static NMDeviceType +coerce_type(NMDeviceType type) +{ + switch (type) { + case NM_DEVICE_TYPE_ETHERNET: + case NM_DEVICE_TYPE_WIFI: + case NM_DEVICE_TYPE_BT: + case NM_DEVICE_TYPE_OLPC_MESH: + case NM_DEVICE_TYPE_OVS_INTERFACE: + case NM_DEVICE_TYPE_OVS_PORT: + case NM_DEVICE_TYPE_OVS_BRIDGE: + case NM_DEVICE_TYPE_WIMAX: + case NM_DEVICE_TYPE_MODEM: + case NM_DEVICE_TYPE_INFINIBAND: + case NM_DEVICE_TYPE_BOND: + case NM_DEVICE_TYPE_TEAM: + case NM_DEVICE_TYPE_BRIDGE: + case NM_DEVICE_TYPE_VLAN: + case NM_DEVICE_TYPE_ADSL: + case NM_DEVICE_TYPE_MACSEC: + case NM_DEVICE_TYPE_MACVLAN: + case NM_DEVICE_TYPE_VXLAN: + case NM_DEVICE_TYPE_IP_TUNNEL: + case NM_DEVICE_TYPE_TUN: + case NM_DEVICE_TYPE_VETH: + case NM_DEVICE_TYPE_GENERIC: + case NM_DEVICE_TYPE_UNUSED1: + case NM_DEVICE_TYPE_UNUSED2: + case NM_DEVICE_TYPE_UNKNOWN: + case NM_DEVICE_TYPE_DUMMY: + case NM_DEVICE_TYPE_PPP: + case NM_DEVICE_TYPE_WPAN: + case NM_DEVICE_TYPE_6LOWPAN: + case NM_DEVICE_TYPE_WIREGUARD: + case NM_DEVICE_TYPE_WIFI_P2P: + case NM_DEVICE_TYPE_VRF: + return type; + } + return NM_DEVICE_TYPE_UNKNOWN; +} + +/*****************************************************************************/ + +static void +register_client(NMObject *nmobj, NMClient *client, NMLDBusObject *dbobj) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(nmobj); + + priv->udev = _nm_client_get_udev(client); + if (priv->udev) + udev_ref(priv->udev); + + NM_OBJECT_CLASS(nm_device_parent_class)->register_client(nmobj, client, dbobj); +} + +/*****************************************************************************/ + +static void +finalize(GObject *object) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(object); + + nm_clear_pointer(&priv->lldp_neighbors, g_ptr_array_unref); + + g_free(priv->interface); + g_free(priv->ip_interface); + g_free(priv->udi); + g_free(priv->path); + g_free(priv->driver); + g_free(priv->driver_version); + g_free(priv->firmware_version); + g_free(priv->product); + g_free(priv->vendor); + g_free(priv->short_vendor); + g_free(priv->description); + g_free(priv->bus_name); + g_free(priv->type_description); + g_free(priv->physical_port_id); + g_free(priv->hw_address); + + nm_clear_pointer(&priv->udev, udev_unref); + + G_OBJECT_CLASS(nm_device_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDevice *device = NM_DEVICE(object); + + switch (prop_id) { + case PROP_DEVICE_TYPE: + g_value_set_enum(value, nm_device_get_device_type(device)); + break; + case PROP_UDI: + g_value_set_string(value, nm_device_get_udi(device)); + break; + case PROP_PATH: + g_value_set_string(value, nm_device_get_path(device)); + break; + case PROP_INTERFACE: + g_value_set_string(value, nm_device_get_iface(device)); + break; + case PROP_IP_INTERFACE: + g_value_set_string(value, nm_device_get_ip_iface(device)); + break; + case PROP_DRIVER: + g_value_set_string(value, nm_device_get_driver(device)); + break; + case PROP_DRIVER_VERSION: + g_value_set_string(value, nm_device_get_driver_version(device)); + break; + case PROP_FIRMWARE_VERSION: + g_value_set_string(value, nm_device_get_firmware_version(device)); + break; + case PROP_CAPABILITIES: + g_value_set_flags(value, nm_device_get_capabilities(device)); + break; + case PROP_REAL: + g_value_set_boolean(value, nm_device_is_real(device)); + break; + case PROP_MANAGED: + g_value_set_boolean(value, nm_device_get_managed(device)); + break; + case PROP_AUTOCONNECT: + g_value_set_boolean(value, nm_device_get_autoconnect(device)); + break; + case PROP_FIRMWARE_MISSING: + g_value_set_boolean(value, nm_device_get_firmware_missing(device)); + break; + case PROP_NM_PLUGIN_MISSING: + g_value_set_boolean(value, nm_device_get_nm_plugin_missing(device)); + break; + case PROP_IP4_CONFIG: + g_value_set_object(value, nm_device_get_ip4_config(device)); + break; + case PROP_DHCP4_CONFIG: + g_value_set_object(value, nm_device_get_dhcp4_config(device)); + break; + case PROP_IP6_CONFIG: + g_value_set_object(value, nm_device_get_ip6_config(device)); + break; + case PROP_DHCP6_CONFIG: + g_value_set_object(value, nm_device_get_dhcp6_config(device)); + break; + case PROP_STATE: + g_value_set_enum(value, nm_device_get_state(device)); + break; + case PROP_STATE_REASON: + g_value_set_uint(value, nm_device_get_state_reason(device)); + break; + case PROP_ACTIVE_CONNECTION: + g_value_set_object(value, nm_device_get_active_connection(device)); + break; + case PROP_AVAILABLE_CONNECTIONS: + g_value_take_boxed( + value, + _nm_utils_copy_object_array(nm_device_get_available_connections(device))); + break; + case PROP_PRODUCT: + g_value_set_string(value, nm_device_get_product(device)); + break; + case PROP_VENDOR: + g_value_set_string(value, nm_device_get_vendor(device)); + break; + case PROP_PHYSICAL_PORT_ID: + g_value_set_string(value, nm_device_get_physical_port_id(device)); + break; + case PROP_MTU: + g_value_set_uint(value, nm_device_get_mtu(device)); + break; + case PROP_METERED: + g_value_set_uint(value, nm_device_get_metered(device)); + break; + case PROP_LLDP_NEIGHBORS: + g_value_set_boxed(value, nm_device_get_lldp_neighbors(device)); + break; + case PROP_IP4_CONNECTIVITY: + g_value_set_enum(value, nm_device_get_connectivity(device, AF_INET)); + break; + case PROP_IP6_CONNECTIVITY: + g_value_set_enum(value, nm_device_get_connectivity(device, AF_INET6)); + break; + case PROP_INTERFACE_FLAGS: + g_value_set_uint(value, nm_device_get_interface_flags(device)); + break; + case PROP_HW_ADDRESS: + g_value_set_string(value, nm_device_get_hw_address(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMDevice * self = NM_DEVICE(object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gboolean b; + + switch (prop_id) { + case PROP_AUTOCONNECT: + b = g_value_get_boolean(value); + if (priv->autoconnect != b) + nm_device_set_autoconnect(NM_DEVICE(object), b); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/* TODO: statistics interface not yet implemented. */ +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_statistics = NML_DBUS_META_IFACE_INIT( + NM_DBUS_INTERFACE_DEVICE_STATISTICS, + NULL, + NML_DBUS_META_INTERFACE_PRIO_NONE, + NML_DBUS_META_IFACE_DBUS_PROPERTIES(NML_DBUS_META_PROPERTY_INIT_TODO("RefreshRateMs", "u"), + NML_DBUS_META_PROPERTY_INIT_TODO("RxBytes", "t"), + NML_DBUS_META_PROPERTY_INIT_TODO("TxBytes", "t"), ), ); + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE, + nm_device_get_type, + NML_DBUS_META_INTERFACE_PRIO_PARENT_TYPE, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_O_PROP("ActiveConnection", + PROP_ACTIVE_CONNECTION, + NMDevicePrivate, + property_o[PROPERTY_O_IDX_ACTIVE_CONNECTION], + nm_active_connection_get_type, + .is_always_ready = TRUE), + NML_DBUS_META_PROPERTY_INIT_B("Autoconnect", + PROP_AUTOCONNECT, + NMDevicePrivate, + autoconnect), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("AvailableConnections", + PROP_AVAILABLE_CONNECTIONS, + NMDevicePrivate, + available_connections, + nm_remote_connection_get_type, + .is_always_ready = TRUE), + NML_DBUS_META_PROPERTY_INIT_U("Capabilities", + PROP_CAPABILITIES, + NMDevicePrivate, + capabilities), + NML_DBUS_META_PROPERTY_INIT_U("DeviceType", PROP_DEVICE_TYPE, NMDevicePrivate, device_type), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Dhcp4Config", + PROP_DHCP4_CONFIG, + NMDevicePrivate, + property_o[PROPERTY_O_IDX_DHCP4_CONFIG], + nm_dhcp4_config_get_type), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Dhcp6Config", + PROP_DHCP6_CONFIG, + NMDevicePrivate, + property_o[PROPERTY_O_IDX_DHCP6_CONFIG], + nm_dhcp6_config_get_type), + NML_DBUS_META_PROPERTY_INIT_S("Driver", PROP_DRIVER, NMDevicePrivate, driver), + NML_DBUS_META_PROPERTY_INIT_S("DriverVersion", + PROP_DRIVER_VERSION, + NMDevicePrivate, + driver_version), + NML_DBUS_META_PROPERTY_INIT_B("FirmwareMissing", + PROP_FIRMWARE_MISSING, + NMDevicePrivate, + firmware_missing), + NML_DBUS_META_PROPERTY_INIT_S("FirmwareVersion", + PROP_FIRMWARE_VERSION, + NMDevicePrivate, + firmware_version), + NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", + 0, + "s", + _nm_device_notify_update_prop_hw_address), + NML_DBUS_META_PROPERTY_INIT_S("Interface", PROP_INTERFACE, NMDevicePrivate, interface), + NML_DBUS_META_PROPERTY_INIT_U("InterfaceFlags", + PROP_INTERFACE_FLAGS, + NMDevicePrivate, + interface_flags), + NML_DBUS_META_PROPERTY_INIT_IGNORE("Ip4Address", "u"), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Ip4Config", + PROP_IP4_CONFIG, + NMDevicePrivate, + property_o[PROPERTY_O_IDX_IP4_CONFIG], + nm_ip4_config_get_type), + NML_DBUS_META_PROPERTY_INIT_U("Ip4Connectivity", + PROP_IP4_CONNECTIVITY, + NMDevicePrivate, + ip4_connectivity), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Ip6Config", + PROP_IP6_CONFIG, + NMDevicePrivate, + property_o[PROPERTY_O_IDX_IP6_CONFIG], + nm_ip6_config_get_type), + NML_DBUS_META_PROPERTY_INIT_U("Ip6Connectivity", + PROP_IP6_CONNECTIVITY, + NMDevicePrivate, + ip6_connectivity), + NML_DBUS_META_PROPERTY_INIT_S("IpInterface", + PROP_IP_INTERFACE, + NMDevicePrivate, + ip_interface), + NML_DBUS_META_PROPERTY_INIT_FCN("LldpNeighbors", + PROP_LLDP_NEIGHBORS, + "aa{sv}", + _notify_update_prop_lldp_neighbors), + NML_DBUS_META_PROPERTY_INIT_B("Managed", PROP_MANAGED, NMDevicePrivate, managed), + NML_DBUS_META_PROPERTY_INIT_U("Metered", PROP_METERED, NMDevicePrivate, metered), + NML_DBUS_META_PROPERTY_INIT_U("Mtu", PROP_MTU, NMDevicePrivate, mtu), + NML_DBUS_META_PROPERTY_INIT_B("NmPluginMissing", + PROP_NM_PLUGIN_MISSING, + NMDevicePrivate, + nm_plugin_missing), + NML_DBUS_META_PROPERTY_INIT_S("Path", PROP_PATH, NMDevicePrivate, path), + NML_DBUS_META_PROPERTY_INIT_S("PhysicalPortId", + PROP_PHYSICAL_PORT_ID, + NMDevicePrivate, + physical_port_id), + NML_DBUS_META_PROPERTY_INIT_B("Real", PROP_REAL, NMDevicePrivate, real), + NML_DBUS_META_PROPERTY_INIT_IGNORE("State", "u"), + NML_DBUS_META_PROPERTY_INIT_FCN("StateReason", + PROP_STATE_REASON, + "(uu)", + _notify_update_prop_state_reason), + NML_DBUS_META_PROPERTY_INIT_S("Udi", PROP_UDI, NMDevicePrivate, udi), ), + .base_struct_offset = G_STRUCT_OFFSET(NMDevice, _priv), ); + +static void +nm_device_class_init(NMDeviceClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMDevicePrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + nm_object_class->register_client = register_client; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_INDIRECT(nm_object_class, NMDevice); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_N(nm_object_class, NMDevicePrivate, property_o); + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, + NMDevicePrivate, + available_connections); + + klass->connection_compatible = connection_compatible; + + /** + * NMDevice:interface: + * + * The interface of the device. + **/ + obj_properties[PROP_INTERFACE] = g_param_spec_string(NM_DEVICE_INTERFACE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:ip-interface: + * + * The IP interface of the device which should be used for all IP-related + * operations like addressing and routing. + **/ + obj_properties[PROP_IP_INTERFACE] = + g_param_spec_string(NM_DEVICE_IP_INTERFACE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:device-type: + * + * The numeric type of the device. + **/ + obj_properties[PROP_DEVICE_TYPE] = g_param_spec_enum(NM_DEVICE_DEVICE_TYPE, + "", + "", + NM_TYPE_DEVICE_TYPE, + NM_DEVICE_TYPE_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /** + * NMDevice:udi: + * + * An operating-system specific device hardware identifier; this is not + * unique to a specific hardware device across reboots or hotplugs. It + * is an opaque string which for some device types (Bluetooth, Modem) + * contains an identifier provided by the underlying hardware service daemon + * such as Bluez or ModemManager, and clients can use this property to + * request more information about the device from those services. + **/ + obj_properties[PROP_UDI] = + g_param_spec_string(NM_DEVICE_UDI, "", "", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:path: + * + * The device path as exposed by the udev property ID_PATH. + * + * The string is backslash escaped (C escaping) for invalid + * characters. The escaping can be reverted with g_strcompress(), + * however the result may not be valid UTF-8. + * + * Since: 1.26 + **/ + obj_properties[PROP_PATH] = g_param_spec_string(NM_DEVICE_PATH, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:driver: + * + * The driver of the device. + **/ + obj_properties[PROP_DRIVER] = g_param_spec_string(NM_DEVICE_DRIVER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:driver-version: + * + * The version of the device driver. + **/ + obj_properties[PROP_DRIVER_VERSION] = + g_param_spec_string(NM_DEVICE_DRIVER_VERSION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:firmware-version: + * + * The firmware version of the device. + **/ + obj_properties[PROP_FIRMWARE_VERSION] = + g_param_spec_string(NM_DEVICE_FIRMWARE_VERSION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:capabilities: + * + * The capabilities of the device. + **/ + obj_properties[PROP_CAPABILITIES] = + g_param_spec_flags(NM_DEVICE_CAPABILITIES, + "", + "", + NM_TYPE_DEVICE_CAPABILITIES, + NM_DEVICE_CAP_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:real: + * + * Whether the device is real or is a placeholder device that could + * be created automatically by NetworkManager if one of its + * #NMDevice:available-connections was activated. + * + * Since: 1.2 + **/ + obj_properties[PROP_REAL] = g_param_spec_boolean(NM_DEVICE_REAL, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:managed: + * + * Whether the device is managed by NetworkManager. + **/ + obj_properties[PROP_MANAGED] = g_param_spec_boolean(NM_DEVICE_MANAGED, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:autoconnect: + * + * Whether the device can auto-activate a connection. + * + * The property setter is a synchronous D-Bus call. This is deprecated since 1.22. + **/ + obj_properties[PROP_AUTOCONNECT] = + g_param_spec_boolean(NM_DEVICE_AUTOCONNECT, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:firmware-missing: + * + * When %TRUE indicates the device is likely missing firmware required + * for its operation. + **/ + obj_properties[PROP_FIRMWARE_MISSING] = + g_param_spec_boolean(NM_DEVICE_FIRMWARE_MISSING, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:nm-plugin-missing: + * + * When %TRUE indicates that the NetworkManager plugin for the device + * is not installed. + * + * Since: 1.2 + **/ + obj_properties[PROP_NM_PLUGIN_MISSING] = + g_param_spec_boolean(NM_DEVICE_NM_PLUGIN_MISSING, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:ip4-config: + * + * The #NMIP4Config of the device. + **/ + obj_properties[PROP_IP4_CONFIG] = + g_param_spec_object(NM_DEVICE_IP4_CONFIG, + "", + "", + NM_TYPE_IP_CONFIG, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:dhcp4-config: + * + * The IPv4 #NMDhcpConfig of the device. + **/ + obj_properties[PROP_DHCP4_CONFIG] = + g_param_spec_object(NM_DEVICE_DHCP4_CONFIG, + "", + "", + NM_TYPE_DHCP_CONFIG, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:ip6-config: + * + * The IPv6 #NMIPConfig of the device. + **/ + obj_properties[PROP_IP6_CONFIG] = + g_param_spec_object(NM_DEVICE_IP6_CONFIG, + "", + "", + NM_TYPE_IP_CONFIG, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:dhcp6-config: + * + * The IPv6 #NMDhcpConfig of the device. + **/ + obj_properties[PROP_DHCP6_CONFIG] = + g_param_spec_object(NM_DEVICE_DHCP6_CONFIG, + "", + "", + NM_TYPE_DHCP_CONFIG, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:ip4-connectivity: + * + * The IPv4 connectivity state of the device. + * + * Since: 1.16 + **/ + obj_properties[PROP_IP4_CONNECTIVITY] = + g_param_spec_enum(NM_DEVICE_IP4_CONNECTIVITY, + "", + "", + NM_TYPE_CONNECTIVITY_STATE, + NM_CONNECTIVITY_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:ip6-connectivity: + * + * The IPv6 connectivity state of the device. + * + * Since: 1.16 + **/ + obj_properties[PROP_IP6_CONNECTIVITY] = + g_param_spec_enum(NM_DEVICE_IP6_CONNECTIVITY, + "", + "", + NM_TYPE_CONNECTIVITY_STATE, + NM_CONNECTIVITY_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:state: + * + * The state of the device. + **/ + obj_properties[PROP_STATE] = g_param_spec_enum(NM_DEVICE_STATE, + "", + "", + NM_TYPE_DEVICE_STATE, + NM_DEVICE_STATE_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:state-reason: + * + * The reason for the device state. + **/ + obj_properties[PROP_STATE_REASON] = + g_param_spec_uint(NM_DEVICE_STATE_REASON, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:active-connection: + * + * The #NMActiveConnection object that "owns" this device during activation. + **/ + obj_properties[PROP_ACTIVE_CONNECTION] = + g_param_spec_object(NM_DEVICE_ACTIVE_CONNECTION, + "", + "", + NM_TYPE_ACTIVE_CONNECTION, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:available-connections: (type GPtrArray(NMRemoteConnection)) + * + * The available connections of the device + **/ + obj_properties[PROP_AVAILABLE_CONNECTIONS] = + g_param_spec_boxed(NM_DEVICE_AVAILABLE_CONNECTIONS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:vendor: + * + * The vendor string of the device. + **/ + obj_properties[PROP_VENDOR] = g_param_spec_string(NM_DEVICE_VENDOR, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:product: + * + * The product string of the device. + **/ + obj_properties[PROP_PRODUCT] = g_param_spec_string(NM_DEVICE_PRODUCT, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:physical-port-id: + * + * The physical port ID of the device. (See + * nm_device_get_physical_port_id().) + **/ + obj_properties[PROP_PHYSICAL_PORT_ID] = + g_param_spec_string(NM_DEVICE_PHYSICAL_PORT_ID, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:mtu: + * + * The MTU of the device. + **/ + obj_properties[PROP_MTU] = g_param_spec_uint(NM_DEVICE_MTU, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:metered: + * + * Whether the device is metered. + * + * Since: 1.2 + **/ + obj_properties[PROP_METERED] = g_param_spec_uint(NM_DEVICE_METERED, + "", + "", + 0, + G_MAXUINT32, + NM_METERED_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:lldp-neighbors: + * + * The LLDP neighbors. + **/ + obj_properties[PROP_LLDP_NEIGHBORS] = + g_param_spec_boxed(NM_DEVICE_LLDP_NEIGHBORS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:interface-flags: + * + * The interface flags. + * + * Since: 1.22 + **/ + obj_properties[PROP_INTERFACE_FLAGS] = + g_param_spec_uint(NM_DEVICE_INTERFACE_FLAGS, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDevice:hw-address: + * + * The hardware address of the device. + * + * Since: 1.24 + **/ + obj_properties[PROP_HW_ADDRESS] = + g_param_spec_string(NM_DEVICE_HW_ADDRESS, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device); + + /** + * NMDevice::state-changed: + * @device: the device object that received the signal + * @new_state: the new state of the device + * @old_state: the previous state of the device + * @reason: the reason describing the state change + * + * Notifies the state change of a #NMDevice. + **/ + signals[STATE_CHANGED] = g_signal_new("state-changed", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 3, + G_TYPE_UINT, + G_TYPE_UINT, + G_TYPE_UINT); +} + +/** + * nm_device_get_iface: + * @device: a #NMDevice + * + * Gets the interface name of the #NMDevice. + * + * Returns: the interface of the device. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_get_iface(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_GET_PRIVATE(device)->interface); +} + +/** + * nm_device_get_ip_iface: + * @device: a #NMDevice + * + * Gets the IP interface name of the #NMDevice over which IP traffic flows + * when the device is in the ACTIVATED state. + * + * Returns: the IP traffic interface of the device. This is the internal string + * used by the device, and must not be modified. + **/ +const char * +nm_device_get_ip_iface(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_GET_PRIVATE(device)->ip_interface); +} + +/** + * nm_device_get_device_type: + * @device: a #NMDevice + * + * Returns the numeric type of the #NMDevice, ie Ethernet, Wi-Fi, etc. + * + * Returns: the device type + **/ +NMDeviceType +nm_device_get_device_type(NMDevice *self) +{ + g_return_val_if_fail(NM_IS_DEVICE(self), NM_DEVICE_TYPE_UNKNOWN); + + return coerce_type(NM_DEVICE_GET_PRIVATE(self)->device_type); +} + +/** + * nm_device_get_udi: + * @device: a #NMDevice + * + * Gets the Unique Device Identifier of the #NMDevice. + * + * Returns: the Unique Device Identifier of the device. This identifier may be + * used to gather more information about the device from various operating + * system services like udev or sysfs. + **/ +const char * +nm_device_get_udi(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_GET_PRIVATE(device)->udi); +} + +/** + * nm_device_get_path: + * @device: a #NMDevice + * + * Gets the path of the #NMDevice as exposed by the udev property ID_PATH. + * + * Returns: the path of the device. + * + * The string is backslash escaped (C escaping) for invalid characters. The escaping + * can be reverted with g_strcompress(), however the result may not be valid UTF-8. + * + * Since: 1.26 + **/ +const char * +nm_device_get_path(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_GET_PRIVATE(device)->path); +} + +/** + * nm_device_get_driver: + * @device: a #NMDevice + * + * Gets the driver of the #NMDevice. + * + * Returns: the driver of the device. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_get_driver(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_GET_PRIVATE(device)->driver); +} + +/** + * nm_device_get_driver_version: + * @device: a #NMDevice + * + * Gets the driver version of the #NMDevice. + * + * Returns: the version of the device driver. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_get_driver_version(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_GET_PRIVATE(device)->driver_version); +} + +/** + * nm_device_get_firmware_version: + * @device: a #NMDevice + * + * Gets the firmware version of the #NMDevice. + * + * Returns: the firmware version of the device. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_get_firmware_version(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_GET_PRIVATE(device)->firmware_version); +} + +/** + * nm_device_get_type_description: + * @device: a #NMDevice + * + * Gets a (non-localized) description of the type of device that + * @device is. + * + * Returns: the type description of the device. This is the internal + * string used by the device, and must not be modified. + **/ +const char * +nm_device_get_type_description(NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(device); + const char * desc, *typename; + + /* BEWARE: this function should return the same value + * as nm_device_get_type_description() in nm-core. */ + + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + if (priv->type_description) + return _nml_coerce_property_str_not_empty(priv->type_description); + + if (NM_DEVICE_GET_CLASS(device)->get_type_description) { + desc = NM_DEVICE_GET_CLASS(device)->get_type_description(device); + if (desc) + return desc; + } + + typename = G_OBJECT_TYPE_NAME(device); + if (g_str_has_prefix(typename, "NMDevice")) { + typename += 8; + if (nm_streq(typename, "Veth")) + typename = "Ethernet"; + } + priv->type_description = g_ascii_strdown(typename, -1); + + return _nml_coerce_property_str_not_empty(priv->type_description); +} + +NMLDBusNotifyUpdatePropFlags +_nm_device_notify_update_prop_hw_address(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMDevice * self = NM_DEVICE(dbobj->nmobj); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gboolean is_new = (meta_iface == &_nml_dbus_meta_iface_nm_device); + gboolean changed = FALSE; + + if (!is_new && priv->hw_address_is_new) { + /* once the instance is marked to honor the new property, the + * changed signal for the old variant gets ignored. */ + goto out; + } + + if (!value) { + if (nm_clear_g_free(&priv->hw_address)) + changed = TRUE; + goto out; + } + + priv->hw_address_is_new = is_new; + + nm_utils_strdup_reset(&priv->hw_address, + _nml_coerce_property_str_not_empty(g_variant_get_string(value, NULL))); + + /* always emit a changed signal here, even if "priv->hw_address" might be unchanged. + * We want to emit the signal because we received a PropertiesChanged signal on D-Bus, + * even if nothing actually changed. */ + changed = TRUE; + +out: + if (changed) { + _nm_client_queue_notify_object(client, self, obj_properties[PROP_HW_ADDRESS]); + } + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; +} + +/** + * nm_device_get_hw_address: + * @device: a #NMDevice + * + * Gets the current a hardware address (MAC) for the @device. + * + * Returns: the current MAC of the device, or %NULL. + * This is the internal string used by the device, and must not be modified. + **/ +const char * +nm_device_get_hw_address(NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + priv = NM_DEVICE_GET_PRIVATE(device); + + nm_assert(!nm_streq0(priv->hw_address, "")); + + return priv->hw_address; +} + +/** + * nm_device_get_capabilities: + * @device: a #NMDevice + * + * Gets the device' capabilities. + * + * Returns: the capabilities + **/ +NMDeviceCapabilities +nm_device_get_capabilities(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), 0); + + return NM_DEVICE_GET_PRIVATE(device)->capabilities; +} + +/** + * nm_device_get_managed: + * @device: a #NMDevice + * + * Whether the #NMDevice is managed by NetworkManager. + * + * Returns: %TRUE if the device is managed by NetworkManager + **/ +gboolean +nm_device_get_managed(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), 0); + + return NM_DEVICE_GET_PRIVATE(device)->managed; +} + +/** + * nm_device_set_managed: + * @device: a #NMDevice + * @managed: %TRUE to make the device managed by NetworkManager. + * + * Enables or disables management of #NMDevice by NetworkManager. + * + * Since: 1.2 + * + * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on + * nm_object_get_path(), interface %NM_DBUS_INTERFACE_DEVICE to set the + * "Managed" property to a "(b)" boolean value. + * This function is deprecated because it calls a synchronous D-Bus method + * and modifies the content of the NMClient cache client side. Also, it does + * not emit a property changed signal. + **/ +void +nm_device_set_managed(NMDevice *device, gboolean managed) +{ + g_return_if_fail(NM_IS_DEVICE(device)); + + managed = !!managed; + + NM_DEVICE_GET_PRIVATE(device)->managed = managed; + + _nm_client_set_property_sync_legacy(_nm_object_get_client(device), + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "Managed", + "b", + managed); +} + +/** + * nm_device_get_autoconnect: + * @device: a #NMDevice + * + * Whether the #NMDevice can be autoconnected. + * + * Returns: %TRUE if the device is allowed to be autoconnected + **/ +gboolean +nm_device_get_autoconnect(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + + return NM_DEVICE_GET_PRIVATE(device)->autoconnect; +} + +/** + * nm_device_set_autoconnect: + * @device: a #NMDevice + * @autoconnect: %TRUE to enable autoconnecting + * + * Enables or disables automatic activation of the #NMDevice. + * + * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on + * nm_object_get_path(), %NM_DBUS_INTERFACE_DEVICE to set "AutoConnect" property to a "(b)" value. + * This function is deprecated because it calls a synchronous D-Bus method + * and modifies the content of the NMClient cache client side. + **/ +void +nm_device_set_autoconnect(NMDevice *device, gboolean autoconnect) +{ + g_return_if_fail(NM_IS_DEVICE(device)); + + NM_DEVICE_GET_PRIVATE(device)->autoconnect = autoconnect; + + _nm_client_set_property_sync_legacy(_nm_object_get_client(device), + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "AutoConnect", + "b", + autoconnect); +} + +/** + * nm_device_get_firmware_missing: + * @device: a #NMDevice + * + * Indicates that firmware required for the device's operation is likely + * to be missing. + * + * Returns: %TRUE if firmware required for the device's operation is likely + * to be missing. + **/ +gboolean +nm_device_get_firmware_missing(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), 0); + + return NM_DEVICE_GET_PRIVATE(device)->firmware_missing; +} + +/** + * nm_device_get_nm_plugin_missing: + * @device: a #NMDevice + * + * Indicates that the NetworkManager plugin for the device is not installed. + * + * Returns: %TRUE if the device plugin not installed. + * + * Since: 1.2 + **/ +gboolean +nm_device_get_nm_plugin_missing(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + + return NM_DEVICE_GET_PRIVATE(device)->nm_plugin_missing; +} + +/** + * nm_device_get_ip4_config: + * @device: a #NMDevice + * + * Gets the current IPv4 #NMIPConfig associated with the #NMDevice. + * + * You can alternatively use nm_active_connection_get_ip4_config(), which also + * works with VPN connections. + * + * Returns: (transfer none): the IPv4 #NMIPConfig, or %NULL if the device is not + * activated. + **/ +NMIPConfig * +nm_device_get_ip4_config(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return nml_dbus_property_o_get_obj( + &NM_DEVICE_GET_PRIVATE(device)->property_o[PROPERTY_O_IDX_IP4_CONFIG]); +} + +/** + * nm_device_get_dhcp4_config: + * @device: a #NMDevice + * + * Gets the current IPv4 #NMDhcpConfig associated with the #NMDevice. + * + * You can alternatively use nm_active_connection_get_dhcp4_config(), which also + * works with VPN connections. + * + * Returns: (transfer none): the IPv4 #NMDhcpConfig, or %NULL if the device is + * not activated or not using DHCP. + **/ +NMDhcpConfig * +nm_device_get_dhcp4_config(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return nml_dbus_property_o_get_obj( + &NM_DEVICE_GET_PRIVATE(device)->property_o[PROPERTY_O_IDX_DHCP4_CONFIG]); +} + +/** + * nm_device_get_ip6_config: + * @device: a #NMDevice + * + * Gets the current IPv6 #NMIPConfig associated with the #NMDevice. + * + * You can alternatively use nm_active_connection_get_ip6_config(), which also + * works with VPN connections. + * + * Returns: (transfer none): the IPv6 #NMIPConfig or %NULL if the device is not activated. + **/ +NMIPConfig * +nm_device_get_ip6_config(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return nml_dbus_property_o_get_obj( + &NM_DEVICE_GET_PRIVATE(device)->property_o[PROPERTY_O_IDX_IP6_CONFIG]); +} + +/** + * nm_device_get_dhcp6_config: + * @device: a #NMDevice + * + * Gets the current IPv6 #NMDhcpConfig associated with the #NMDevice. + * + * You can alternatively use nm_active_connection_get_dhcp6_config(), which also + * works with VPN connections. + * + * Returns: (transfer none): the IPv6 #NMDhcpConfig, or %NULL if the device is + * not activated or not using DHCPv6. + **/ +NMDhcpConfig * +nm_device_get_dhcp6_config(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return nml_dbus_property_o_get_obj( + &NM_DEVICE_GET_PRIVATE(device)->property_o[PROPERTY_O_IDX_DHCP6_CONFIG]); +} + +/** + * nm_device_get_connectivity: + * @device: a #NMDevice + * @addr_family: network address family + * + * The connectivity state of the device for given address family. + * Supported address families are %AF_INET for IPv4, %AF_INET6 + * for IPv6 or %AF_UNSPEC for any. + * + * Returns: the current connectivity state + * + * Since: 1.16 + **/ +NMConnectivityState +nm_device_get_connectivity(NMDevice *device, int addr_family) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(device); + + switch (addr_family) { + case AF_INET: + return priv->ip4_connectivity; + case AF_INET6: + return priv->ip6_connectivity; + case AF_UNSPEC: + return NM_MAX(priv->ip4_connectivity, priv->ip6_connectivity); + default: + g_return_val_if_reached(NM_CONNECTIVITY_UNKNOWN); + } +} + +/** + * nm_device_get_interface_flags: + * @device: a #NMDevice + * + * Gets the interface flags of the device. + * + * Returns: the flags + * + * Since: 1.22 + **/ +NMDeviceInterfaceFlags +nm_device_get_interface_flags(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NM_DEVICE_INTERFACE_FLAG_NONE); + + return NM_DEVICE_GET_PRIVATE(device)->interface_flags; +} + +/** + * nm_device_get_state: + * @device: a #NMDevice + * + * Gets the current #NMDevice state. + * + * Returns: the current device state + **/ +NMDeviceState +nm_device_get_state(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NM_DEVICE_STATE_UNKNOWN); + + return NM_DEVICE_GET_PRIVATE(device)->state; +} + +/** + * nm_device_get_state_reason: + * @device: a #NMDevice + * + * Gets the reason for entering the current #NMDevice state. + * + * Returns: the reason for entering the current device state + **/ +NMDeviceStateReason +nm_device_get_state_reason(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NM_DEVICE_STATE_REASON_UNKNOWN); + + return NM_DEVICE_GET_PRIVATE(device)->state_reason; +} + +/** + * nm_device_get_active_connection: + * @device: a #NMDevice + * + * Gets the #NMActiveConnection object which owns this device during activation. + * + * Returns: (transfer none): the #NMActiveConnection or %NULL if the device is + * not part of an active connection + **/ +NMActiveConnection * +nm_device_get_active_connection(NMDevice *device) +{ + NMActiveConnection *ac; + + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + ac = nml_dbus_property_o_get_obj( + &NM_DEVICE_GET_PRIVATE(device)->property_o[PROPERTY_O_IDX_ACTIVE_CONNECTION]); + + nm_assert(!ac || NM_IS_ACTIVE_CONNECTION(ac)); + return ac; +} + +/** + * nm_device_get_available_connections: + * @device: a #NMDevice + * + * Gets the #NMRemoteConnections currently known to the daemon that could + * be activated on @device. + * + * Returns: (element-type NMRemoteConnection): the #GPtrArray + * containing #NMRemoteConnections. This is the internal copy used by + * the connection, and must not be modified. + **/ +const GPtrArray * +nm_device_get_available_connections(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_DEVICE_GET_PRIVATE(device)->available_connections); +} + +static const char * +get_type_name(NMDevice *device) +{ + switch (nm_device_get_device_type(device)) { + case NM_DEVICE_TYPE_ETHERNET: + return _("Ethernet"); + case NM_DEVICE_TYPE_WIFI: + return _("Wi-Fi"); + case NM_DEVICE_TYPE_BT: + return _("Bluetooth"); + case NM_DEVICE_TYPE_OLPC_MESH: + return _("OLPC Mesh"); + case NM_DEVICE_TYPE_OVS_INTERFACE: + return _("Open vSwitch Interface"); + case NM_DEVICE_TYPE_OVS_PORT: + return _("Open vSwitch Port"); + case NM_DEVICE_TYPE_OVS_BRIDGE: + return _("Open vSwitch Bridge"); + case NM_DEVICE_TYPE_WIMAX: + return _("WiMAX"); + case NM_DEVICE_TYPE_MODEM: + return _("Mobile Broadband"); + case NM_DEVICE_TYPE_INFINIBAND: + return _("InfiniBand"); + case NM_DEVICE_TYPE_BOND: + return _("Bond"); + case NM_DEVICE_TYPE_TEAM: + return _("Team"); + case NM_DEVICE_TYPE_BRIDGE: + return _("Bridge"); + case NM_DEVICE_TYPE_VLAN: + return _("VLAN"); + case NM_DEVICE_TYPE_ADSL: + return _("ADSL"); + case NM_DEVICE_TYPE_MACVLAN: + return _("MACVLAN"); + case NM_DEVICE_TYPE_VXLAN: + return _("VXLAN"); + case NM_DEVICE_TYPE_IP_TUNNEL: + return _("IPTunnel"); + case NM_DEVICE_TYPE_TUN: + return _("Tun"); + case NM_DEVICE_TYPE_VETH: + return _("Veth"); + case NM_DEVICE_TYPE_MACSEC: + return _("MACsec"); + case NM_DEVICE_TYPE_DUMMY: + return _("Dummy"); + case NM_DEVICE_TYPE_PPP: + return _("PPP"); + case NM_DEVICE_TYPE_WPAN: + return _("IEEE 802.15.4"); + case NM_DEVICE_TYPE_6LOWPAN: + return _("6LoWPAN"); + case NM_DEVICE_TYPE_WIREGUARD: + return _("WireGuard"); + case NM_DEVICE_TYPE_WIFI_P2P: + return _("Wi-Fi P2P"); + case NM_DEVICE_TYPE_VRF: + return _("VRF"); + case NM_DEVICE_TYPE_GENERIC: + case NM_DEVICE_TYPE_UNUSED1: + case NM_DEVICE_TYPE_UNUSED2: + case NM_DEVICE_TYPE_UNKNOWN: + break; + } + return _("Unknown"); +} + +static char * +get_device_type_name_with_iface(NMDevice *device) +{ + const char *type_name = get_type_name(device); + + switch (nm_device_get_device_type(device)) { + case NM_DEVICE_TYPE_BOND: + case NM_DEVICE_TYPE_TEAM: + case NM_DEVICE_TYPE_BRIDGE: + case NM_DEVICE_TYPE_VLAN: + return g_strdup_printf("%s (%s)", type_name, nm_device_get_iface(device)); + default: + return g_strdup(type_name); + } +} + +static char * +get_device_generic_type_name_with_iface(NMDevice *device) +{ + switch (nm_device_get_device_type(device)) { + case NM_DEVICE_TYPE_ETHERNET: + case NM_DEVICE_TYPE_INFINIBAND: + return g_strdup(_("Wired")); + default: + return get_device_type_name_with_iface(device); + } +} + +static const char * +get_bus_name(NMDevice *device) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(device); + struct udev_device *udevice; + const char * ifname; + const char * bus; + + if (priv->bus_name) + goto out; + + if (!priv->udev) + return NULL; + + ifname = nm_device_get_iface(device); + if (!ifname) + return NULL; + + udevice = udev_device_new_from_subsystem_sysname(priv->udev, "net", ifname); + if (!udevice) { + udevice = udev_device_new_from_subsystem_sysname(priv->udev, "tty", ifname); + if (!udevice) + return NULL; + } + bus = udev_device_get_property_value(udevice, "ID_BUS"); + if (!g_strcmp0(bus, "pci")) + priv->bus_name = g_strdup(_("PCI")); + else if (!g_strcmp0(bus, "usb")) + priv->bus_name = g_strdup(_("USB")); + else { + /* Use "" instead of NULL so we can tell later that we've + * already tried. + */ + priv->bus_name = g_strdup(""); + } + udev_device_unref(udevice); + +out: + if (*priv->bus_name) + return priv->bus_name; + else + return NULL; +} + +static char * +_get_udev_property(NMDevice * device, + const char *enc_prop, /* ID_XXX_ENC */ + const char *db_prop) /* ID_XXX_FROM_DATABASE */ +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(device); + struct udev_device *udev_device; + struct udev_device *tmpdev; + const char * ifname; + guint32 count = 0; + char * enc_value = NULL; + char * db_value = NULL; + + if (!priv->udev) + return NULL; + + ifname = nm_device_get_iface(device); + if (!ifname) + return NULL; + + udev_device = udev_device_new_from_subsystem_sysname(priv->udev, "net", ifname); + if (!udev_device) { + udev_device = udev_device_new_from_subsystem_sysname(priv->udev, "tty", ifname); + if (!udev_device) + return NULL; + } + /* Walk up the chain of the device and its parents a few steps to grab + * vendor and device ID information off it. + */ + tmpdev = udev_device; + while ((count++ < 3) && tmpdev && !enc_value) { + if (!enc_value) + enc_value = + nm_udev_utils_property_decode_cp(udev_device_get_property_value(tmpdev, enc_prop)); + if (!db_value) + db_value = g_strdup(udev_device_get_property_value(tmpdev, db_prop)); + + tmpdev = udev_device_get_parent(tmpdev); + } + udev_device_unref(udev_device); + + /* Prefer the hwdata database value over what comes directly + * from the device. */ + if (db_value) { + g_free(enc_value); + return db_value; + } + + return enc_value; +} + +static char * +_get_udev_property_utf8safe(NMDevice * device, + const char *enc_prop, /* ID_XXX_ENC */ + const char *db_prop) /* ID_XXX_FROM_DATABASE */ +{ + return nm_utils_str_utf8safe_escape_take(_get_udev_property(device, enc_prop, db_prop), + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL); +} + +/** + * nm_device_get_product: + * @device: a #NMDevice + * + * Gets the product string of the #NMDevice. + * + * Returns: the product name of the device. This is the internal string used by the + * device, and must not be modified. + * + * The string is backslash escaped (C escaping) for invalid characters. The escaping + * can be reverted with g_strcompress(), however the result may not be valid UTF-8. + **/ +const char * +nm_device_get_product(NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + priv = NM_DEVICE_GET_PRIVATE(device); + if (!priv->product) { + priv->product = + _get_udev_property_utf8safe(device, "ID_MODEL_ENC", "ID_MODEL_FROM_DATABASE"); + + /* Sometimes ID_PRODUCT_FROM_DATABASE is used? */ + if (!priv->product) + priv->product = + _get_udev_property_utf8safe(device, "ID_MODEL_ENC", "ID_PRODUCT_FROM_DATABASE"); + + if (!priv->product) + priv->product = g_strdup(""); + } + + return priv->product; +} + +/** + * nm_device_get_vendor: + * @device: a #NMDevice + * + * Gets the vendor string of the #NMDevice. + * + * Returns: the vendor name of the device. This is the internal string used by the + * device, and must not be modified. + * + * The string is backslash escaped (C escaping) for invalid characters. The escaping + * can be reverted with g_strcompress(), however the result may not be valid UTF-8. + **/ +const char * +nm_device_get_vendor(NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + priv = NM_DEVICE_GET_PRIVATE(device); + + if (!priv->vendor) + priv->vendor = + _get_udev_property_utf8safe(device, "ID_VENDOR_ENC", "ID_VENDOR_FROM_DATABASE"); + + if (!priv->vendor) + priv->vendor = g_strdup(""); + + return priv->vendor; +} + +static void +ensure_description(NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(device); + GParamSpec * name_prop; + gs_free char * short_product = NULL; + + priv->short_vendor = nm_str_realloc(nm_utils_fixup_vendor_string(nm_device_get_vendor(device))); + + /* Grab device's preferred name, if any */ + name_prop = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(device)), "name"); + if (name_prop) { + g_object_get(device, "name", &priv->description, NULL); + if (priv->description && priv->description[0]) + return; + nm_clear_g_free(&priv->description); + } + + if (!priv->short_vendor) { + priv->description = g_strdup(nm_device_get_iface(device) ?: ""); + return; + } + + short_product = nm_utils_fixup_product_string(nm_device_get_product(device)); + if (short_product == NULL) + short_product = g_strdup(get_type_name(device)); + + /* Another quick hack; if all of the fixed up vendor string + * is found in product, ignore the vendor. + */ + { + gs_free char *pdown = g_ascii_strdown(short_product, -1); + gs_free char *vdown = g_ascii_strdown(priv->short_vendor, -1); + + if (!strstr(pdown, vdown)) + priv->description = g_strconcat(priv->short_vendor, " ", short_product, NULL); + else + priv->description = g_steal_pointer(&short_product); + } +} + +static const char * +get_short_vendor(NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + priv = NM_DEVICE_GET_PRIVATE(device); + + if (!priv->description) + ensure_description(device); + + return priv->short_vendor; +} + +/** + * nm_device_get_description: + * @device: an #NMDevice + * + * Gets a description of @device, based on its vendor and product names. + * + * Returns: a description of @device. If either the vendor or the + * product name is unknown, this returns the interface name. + */ +const char * +nm_device_get_description(NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + priv = NM_DEVICE_GET_PRIVATE(device); + + if (!priv->description) + ensure_description(device); + + return priv->description; +} + +static gboolean +find_duplicates(char **names, gboolean *duplicates, int num_devices) +{ + int i, j; + gboolean found_any = FALSE; + + memset(duplicates, 0, num_devices * sizeof(gboolean)); + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) + continue; + for (j = i + 1; j < num_devices; j++) { + if (duplicates[j]) + continue; + if (!strcmp(names[i], names[j])) + duplicates[i] = duplicates[j] = found_any = TRUE; + } + } + + return found_any; +} + +/** + * nm_device_disambiguate_names: + * @devices: (array length=num_devices): an array of #NMDevice + * @num_devices: length of @devices + * + * Generates a list of short-ish unique presentation names for the + * devices in @devices. + * + * Returns: (transfer full) (array zero-terminated=1): the device names + */ +char ** +nm_device_disambiguate_names(NMDevice **devices, int num_devices) +{ + char ** names; + gboolean *duplicates; + int i; + + names = g_new(char *, num_devices + 1); + duplicates = g_new(gboolean, num_devices); + + /* Generic device name */ + for (i = 0; i < num_devices; i++) + names[i] = get_device_generic_type_name_with_iface(devices[i]); + if (!find_duplicates(names, duplicates, num_devices)) + goto done; + + /* Try specific names (eg, "Ethernet" and "InfiniBand" rather + * than "Wired") + */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + g_free(names[i]); + names[i] = get_device_type_name_with_iface(devices[i]); + } + } + if (!find_duplicates(names, duplicates, num_devices)) + goto done; + + /* Try prefixing bus name (eg, "PCI Ethernet" vs "USB Ethernet") */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + const char *bus = get_bus_name(devices[i]); + char * name; + + if (!bus) + continue; + + g_free(names[i]); + name = get_device_type_name_with_iface(devices[i]); + /* TRANSLATORS: the first %s is a bus name (eg, "USB") or + * product name, the second is a device type (eg, + * "Ethernet"). You can change this to something like + * "%2$s (%1$s)" if there's no grammatical way to combine + * the strings otherwise. + */ + names[i] = g_strdup_printf(C_("long device name", "%s %s"), bus, name); + g_free(name); + } + } + if (!find_duplicates(names, duplicates, num_devices)) + goto done; + + /* Try prefixing vendor name */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + const char *vendor = get_short_vendor(devices[i]); + char * name; + + if (!vendor) + continue; + + g_free(names[i]); + name = get_device_type_name_with_iface(devices[i]); + names[i] = + g_strdup_printf(C_("long device name", "%s %s"), vendor, get_type_name(devices[i])); + g_free(name); + } + } + if (!find_duplicates(names, duplicates, num_devices)) + goto done; + + /* If dealing with Bluetooth devices, try to distinguish them by + * device name. + */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i] && NM_IS_DEVICE_BT(devices[i])) { + const char *devname = nm_device_bt_get_name(NM_DEVICE_BT(devices[i])); + char * name; + + if (!devname) + continue; + + g_free(names[i]); + name = get_device_type_name_with_iface(devices[i]); + names[i] = g_strdup_printf("%s (%s)", name, devname); + g_free(name); + } + } + if (!find_duplicates(names, duplicates, num_devices)) + goto done; + + /* We have multiple identical network cards, so we have to differentiate + * them by interface name. + */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + const char *interface = nm_device_get_iface(devices[i]); + + if (!interface) + continue; + + g_free(names[i]); + names[i] = g_strdup_printf("%s (%s)", get_type_name(devices[i]), interface); + } + } + +done: + g_free(duplicates); + names[num_devices] = NULL; + return names; +} + +/** + * nm_device_get_physical_port_id: + * @device: a #NMDevice + * + * Gets the physical port ID of the #NMDevice. If non-%NULL, this is + * an opaque string that can be used to recognize when + * seemingly-unrelated #NMDevices are actually just different virtual + * ports on a single physical port. (Eg, NPAR / SR-IOV.) + * + * Returns: the physical port ID of the device, or %NULL if the port + * ID is unknown. This is the internal string used by the device and + * must not be modified. + **/ +const char * +nm_device_get_physical_port_id(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_GET_PRIVATE(device)->physical_port_id); +} + +/** + * nm_device_get_mtu: + * @device: a #NMDevice + * + * Gets the MTU of the #NMDevice. + * + * Returns: the MTU of the device in bytes. + **/ +guint32 +nm_device_get_mtu(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), 0); + + return NM_DEVICE_GET_PRIVATE(device)->mtu; +} + +/** + * nm_device_get_metered: + * @device: a #NMDevice + * + * Gets the metered setting of a #NMDevice. + * + * Returns: the metered setting. + * + * Since: 1.2 + **/ +NMMetered +nm_device_get_metered(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NM_METERED_UNKNOWN); + + return NM_DEVICE_GET_PRIVATE(device)->metered; +} + +NM_BACKPORT_SYMBOL(libnm_1_0_6, NMMetered, nm_device_get_metered, (NMDevice * device), (device)); + +/** + * nm_device_get_lldp_neighbors: + * @device: a #NMDevice + * + * Gets the list of neighbors discovered through LLDP. + * + * Returns: (element-type NMLldpNeighbor) (transfer none): the #GPtrArray + * containing #NMLldpNeighbors. This is the internal copy used by the + * device and must not be modified. The library never modifies the returned + * array and thus it is safe for callers to reference and keep using it. + * + * Since: 1.2 + **/ +GPtrArray * +nm_device_get_lldp_neighbors(NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + priv = NM_DEVICE_GET_PRIVATE(device); + if (!priv->lldp_neighbors) + priv->lldp_neighbors = + g_ptr_array_new_with_free_func((GDestroyNotify) nm_lldp_neighbor_unref); + return priv->lldp_neighbors; +} + +/** + * nm_device_is_real: + * @device: a #NMDevice + * + * Returns: %TRUE if the device exists, or %FALSE if it is a placeholder device + * that could be automatically created by NetworkManager if one of its + * #NMDevice:available-connections was activated. + * + * Since: 1.2 + **/ +gboolean +nm_device_is_real(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + + return NM_DEVICE_GET_PRIVATE(device)->real; +} + +/** + * nm_device_is_software: + * @device: a #NMDevice + * + * Whether the device is a software device. + * + * Returns: %TRUE if @device is a software device, %FALSE if it is a hardware device. + **/ +gboolean +nm_device_is_software(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + + return !!(NM_DEVICE_GET_PRIVATE(device)->capabilities & NM_DEVICE_CAP_IS_SOFTWARE); +} + +/** + * nm_device_reapply: + * @device: a #NMDevice + * @connection: (allow-none): the #NMConnection to replace the applied + * settings with or %NULL to reuse existing + * @version_id: zero or the expected version id of the applied connection. + * If specified and the version id mismatches, the call fails without + * modification. This allows to catch concurrent accesses. + * @flags: always set this to zero + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Attempts to update device with changes to the currently active connection + * made since it was last applied. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + * + * Since: 1.2 + * + * Deprecated: 1.22: Use nm_device_reapply_async() or GDBusConnection. + **/ +gboolean +nm_device_reapply(NMDevice * device, + NMConnection *connection, + guint64 version_id, + guint32 flags, + GCancellable *cancellable, + GError ** error) +{ + GVariant *arg_connection = NULL; + + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + g_return_val_if_fail(!connection || NM_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + if (connection) + arg_connection = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); + if (!arg_connection) + arg_connection = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + + return _nm_client_dbus_call_sync_void( + _nm_object_get_client(device), + cancellable, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "Reapply", + g_variant_new("(@a{sa{sv}}tu)", arg_connection, version_id, flags), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); +} + +/** + * nm_device_reapply_async: + * @device: a #NMDevice + * @connection: (allow-none): the #NMConnection to replace the applied + * settings with or %NULL to reuse existing + * @version_id: zero or the expected version id of the applied + * connection. If specified and the version id mismatches, the call + * fails without modification. This allows to catch concurrent + * accesses. + * @flags: always set this to zero + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the reapply operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously begins an attempt to update device with changes to the + * currently active connection made since it was last applied. + * + * Since: 1.2 + **/ +void +nm_device_reapply_async(NMDevice * device, + NMConnection * connection, + guint64 version_id, + guint32 flags, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVariant *arg_connection = NULL; + + g_return_if_fail(NM_IS_DEVICE(device)); + g_return_if_fail(!connection || NM_IS_CONNECTION(connection)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + if (connection) + arg_connection = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); + if (!arg_connection) + arg_connection = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + + _nm_client_dbus_call(_nm_object_get_client(device), + device, + nm_device_reapply_async, + cancellable, + callback, + user_data, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "Reapply", + g_variant_new("(@a{sa{sv}}tu)", arg_connection, version_id, flags), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_device_reapply_finish: + * @device: a #NMDevice + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_reapply_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + * + * Since: 1.2 + **/ +gboolean +nm_device_reapply_finish(NMDevice *device, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, device, nm_device_reapply_async), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/*****************************************************************************/ + +/** + * nm_device_get_applied_connection: + * @device: a #NMDevice + * @flags: the flags argument. Currently, this value must always be zero. + * @version_id: (out) (allow-none): returns the current version id of + * the applied connection + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Fetch the currently applied connection on the device. + * + * Returns: (transfer full): a %NMConnection with the currently applied settings + * or %NULL on error. + * + * The connection is as received from D-Bus and might not validate according + * to nm_connection_verify(). + * + * Since: 1.2 + * + * Deprecated: 1.22: Use nm_device_get_applied_connection_async() or GDBusConnection. + **/ +NMConnection * +nm_device_get_applied_connection(NMDevice * device, + guint32 flags, + guint64 * version_id, + GCancellable *cancellable, + GError ** error) +{ + gs_unref_variant GVariant *ret = NULL; + gs_unref_variant GVariant *v_connection = NULL; + guint64 v_version_id; + NMConnection * connection; + + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), NULL); + g_return_val_if_fail(!error || !*error, NULL); + + ret = _nm_client_dbus_call_sync(_nm_object_get_client(device), + cancellable, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "GetAppliedConnection", + g_variant_new("(u)", flags), + G_VARIANT_TYPE("(a{sa{sv}}t)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); + if (!ret) + return NULL; + + g_variant_get(ret, "(@a{sa{sv}}t)", &v_connection, &v_version_id); + + connection = _nm_simple_connection_new_from_dbus(v_connection, + NM_SETTING_PARSE_FLAGS_BEST_EFFORT, + error); + if (!connection) + return NULL; + + NM_SET_OUT(version_id, v_version_id); + return connection; +} + +/** + * nm_device_get_applied_connection_async: + * @device: a #NMDevice + * @flags: the flags argument. Currently, this value must always be zero. + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the reapply operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously begins and gets the currently applied connection. + * + * Since: 1.2 + **/ +void +nm_device_get_applied_connection_async(NMDevice * device, + guint32 flags, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_DEVICE(device)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(_nm_object_get_client(device), + device, + nm_device_get_applied_connection_async, + cancellable, + callback, + user_data, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "GetAppliedConnection", + g_variant_new("(u)", flags), + G_VARIANT_TYPE("(a{sa{sv}}t)"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_variant_strip_dbus_error_cb); +} + +/** + * nm_device_get_applied_connection_finish: + * @device: a #NMDevice + * @result: the result passed to the #GAsyncReadyCallback + * @version_id: (out) (allow-none): the current version id of the applied + * connection. + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_get_applied_connection_async(). + * + * Returns: (transfer full): a currently applied %NMConnection or %NULL in case + * of error. + * + * The connection is as received from D-Bus and might not validate according + * to nm_connection_verify(). + * + * Since: 1.2 + **/ +NMConnection * +nm_device_get_applied_connection_finish(NMDevice * device, + GAsyncResult *result, + guint64 * version_id, + GError ** error) +{ + gs_unref_variant GVariant *ret = NULL; + gs_unref_variant GVariant *v_connection = NULL; + guint64 v_version_id; + NMConnection * connection; + + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + g_return_val_if_fail(nm_g_task_is_valid(result, device, nm_device_get_applied_connection_async), + NULL); + g_return_val_if_fail(!error || !*error, NULL); + + ret = g_task_propagate_pointer(G_TASK(result), error); + if (!ret) + return NULL; + + g_variant_get(ret, "(@a{sa{sv}}t)", &v_connection, &v_version_id); + + connection = _nm_simple_connection_new_from_dbus(v_connection, + NM_SETTING_PARSE_FLAGS_BEST_EFFORT, + error); + if (!connection) + return NULL; + + NM_SET_OUT(version_id, v_version_id); + return connection; +} + +/*****************************************************************************/ + +/** + * nm_device_disconnect: + * @device: a #NMDevice + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Disconnects the device if currently connected, and prevents the device from + * automatically connecting to networks until the next manual network connection + * request. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + * + * Deprecated: 1.22: Use nm_device_disconnect_async() or GDBusConnection. + **/ +gboolean +nm_device_disconnect(NMDevice *device, GCancellable *cancellable, GError **error) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + return _nm_client_dbus_call_sync_void(_nm_object_get_client(device), + cancellable, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "Disconnect", + g_variant_new("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); +} + +/** + * nm_device_disconnect_async: + * @device: a #NMDevice + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the disconnect operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously begins disconnecting the device if currently connected, and + * prevents the device from automatically connecting to networks until the next + * manual network connection request. + **/ +void +nm_device_disconnect_async(NMDevice * device, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_DEVICE(device)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(_nm_object_get_client(device), + device, + nm_device_disconnect_async, + cancellable, + callback, + user_data, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "Disconnect", + g_variant_new("()"), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_device_disconnect_finish: + * @device: a #NMDevice + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_disconnect_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + **/ +gboolean +nm_device_disconnect_finish(NMDevice *device, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, device, nm_device_disconnect_async), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/** + * nm_device_delete: + * @device: a #NMDevice + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Deletes the software device. Hardware devices can't be deleted. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + * + * Deprecated: 1.22: Use nm_device_delete_async() or GDBusConnection. + **/ +gboolean +nm_device_delete(NMDevice *device, GCancellable *cancellable, GError **error) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + return _nm_client_dbus_call_sync_void(_nm_object_get_client(device), + cancellable, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "Delete", + g_variant_new("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); +} + +/** + * nm_device_delete_async: + * @device: a #NMDevice + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when delete operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously begins deleting the software device. Hardware devices can't + * be deleted. + **/ +void +nm_device_delete_async(NMDevice * device, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_DEVICE(device)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(_nm_object_get_client(device), + device, + nm_device_delete_async, + cancellable, + callback, + user_data, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "Delete", + g_variant_new("()"), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_device_delete_finish: + * @device: a #NMDevice + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_delete_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + **/ +gboolean +nm_device_delete_finish(NMDevice *device, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, device, nm_device_delete_async), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/** + * nm_device_connection_valid: + * @device: an #NMDevice to validate @connection against + * @connection: an #NMConnection to validate against @device + * + * Validates a given connection for a given #NMDevice object and returns + * whether the connection may be activated with the device. For example if + * @device is a Wi-Fi device that supports only WEP encryption, the connection + * will only be valid if it is a Wi-Fi connection which describes a WEP or open + * network, and will not be valid if it describes a WPA network, or if it is + * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the + * device. + * + * Returns: %TRUE if the connection may be activated with this device, %FALSE + * if is incompatible with the device's capabilities and characteristics. + **/ +gboolean +nm_device_connection_valid(NMDevice *device, NMConnection *connection) +{ + return nm_device_connection_compatible(device, connection, NULL); +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + const char *config_iface, *device_iface; + GError * local = NULL; + + if (!nm_connection_verify(connection, &local)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection was not valid: %s"), + local->message); + g_error_free(local); + return FALSE; + } + + config_iface = nm_connection_get_interface_name(connection); + device_iface = nm_device_get_iface(device); + if (config_iface && g_strcmp0(config_iface, device_iface) != 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The interface names of the device and the connection didn't match.")); + return FALSE; + } + + return TRUE; +} + +/** + * nm_device_connection_compatible: + * @device: an #NMDevice to validate @connection against + * @connection: an #NMConnection to validate against @device + * @error: return location for a #GError, or %NULL + * + * Validates a given connection for a given #NMDevice object and returns + * whether the connection may be activated with the device. For example if + * @device is a Wi-Fi device that supports only WEP encryption, the connection + * will only be valid if it is a Wi-Fi connection which describes a WEP or open + * network, and will not be valid if it describes a WPA network, or if it is + * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the + * device. + * + * This function does the same as nm_device_connection_valid(), i.e. checking + * compatibility of the given device and connection. But, in addition, it sets + * GError when FALSE is returned. + * + * Returns: %TRUE if the connection may be activated with this device, %FALSE + * if is incompatible with the device's capabilities and characteristics. + **/ +gboolean +nm_device_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + + return NM_DEVICE_GET_CLASS(device)->connection_compatible(device, connection, error); +} + +/** + * nm_device_filter_connections: + * @device: an #NMDevice to filter connections for + * @connections: (element-type NMConnection): an array of #NMConnections to filter + * + * Filters a given array of connections for a given #NMDevice object and returns + * connections which may be activated with the device. For example if @device + * is a Wi-Fi device that supports only WEP encryption, the returned array will + * contain any Wi-Fi connections in @connections that allow connection to + * unencrypted or WEP-enabled SSIDs. The returned array will not contain + * Ethernet, Bluetooth, Wi-Fi WPA connections, or any other connection that is + * incompatible with the device. To get the full list of connections see + * nm_client_get_connections(). + * + * Returns: (transfer full) (element-type NMConnection): an array of + * #NMConnections that could be activated with the given @device. The array + * should be freed with g_ptr_array_unref() when it is no longer required. + * + * WARNING: the transfer annotation for this function may not work correctly + * with bindings. See https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/305. + * You can filter the list yourself with nm_device_connection_valid(). + **/ +GPtrArray * +nm_device_filter_connections(NMDevice *device, const GPtrArray *connections) +{ + GPtrArray *filtered; + int i; + + filtered = g_ptr_array_new_with_free_func(g_object_unref); + for (i = 0; i < connections->len; i++) { + NMConnection *candidate = connections->pdata[i]; + + /* Connection applies to this device */ + if (nm_device_connection_valid(device, candidate)) + g_ptr_array_add(filtered, g_object_ref(candidate)); + } + + return filtered; +} + +/** + * nm_device_get_setting_type: + * @device: an #NMDevice + * + * Gets the (primary) #NMSetting subtype associated with connections + * that can be used on @device. + * + * Returns: @device's associated #NMSetting type + */ +GType +nm_device_get_setting_type(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), G_TYPE_INVALID); + g_return_val_if_fail(NM_DEVICE_GET_CLASS(device)->get_setting_type != NULL, G_TYPE_INVALID); + + return NM_DEVICE_GET_CLASS(device)->get_setting_type(device); +} + +/*****************************************************************************/ + +static gboolean +NM_IS_LLDP_NEIGHBOR(const NMLldpNeighbor *self) +{ + nm_assert(!self || (self->refcount > 0 && self->attrs)); + return self && self->refcount > 0; +} + +/** + * nm_lldp_neighbor_new: + * + * Creates a new #NMLldpNeighbor object. + * + * Note that #NMLldpNeighbor has no public API for mutating + * an instance. Also, libnm will not internally mutate a + * once exposed object. They are guaranteed to be immutable. + * Since 1.32, ref-counting is thread-safe. + * + * This function is not useful, as there is no public API to + * actually modify the (empty) instance. + * + * Returns: (transfer full): the new #NMLldpNeighbor object. + * + * Since: 1.2 + **/ +NMLldpNeighbor * +nm_lldp_neighbor_new(void) +{ + NMLldpNeighbor *neigh; + + neigh = g_slice_new(NMLldpNeighbor); + *neigh = (NMLldpNeighbor){ + .refcount = 1, + .attrs = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref), + }; + + return neigh; +} + +static NMLldpNeighbor * +_nm_lldp_neighbor_dup(NMLldpNeighbor *neighbor) +{ + /* There is no public API for mutating a NMLldpNeighbor. Nor should + * we ever add one, because immutable types (or at least, sealable types) + * are great. + * + * As such, dup is merely taking another ref. */ + nm_lldp_neighbor_ref(neighbor); + return neighbor; +} + +/** + * nm_lldp_neighbor_ref: + * @neighbor: the #NMLldpNeighbor + * + * Increases the reference count of the object. + * + * Since 1.32, ref-counting of #NMLldpNeighbor is thread-safe. + * + * Since: 1.2 + **/ +void +nm_lldp_neighbor_ref(NMLldpNeighbor *neighbor) +{ + g_return_if_fail(NM_IS_LLDP_NEIGHBOR(neighbor)); + + g_atomic_int_inc(&neighbor->refcount); +} + +/** + * nm_lldp_neighbor_unref: + * @neighbor: the #NMLldpNeighbor + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + * + * Since 1.32, ref-counting of #NMLldpNeighbor is thread-safe. + * + * Since: 1.2 + **/ +void +nm_lldp_neighbor_unref(NMLldpNeighbor *neighbor) +{ + g_return_if_fail(NM_IS_LLDP_NEIGHBOR(neighbor)); + + if (g_atomic_int_dec_and_test(&neighbor->refcount)) { + g_hash_table_unref(neighbor->attrs); + nm_g_slice_free(neighbor); + } +} + +/** + * nm_lldp_neighbor_get_attr_value: + * @neighbor: the #NMLldpNeighbor + * @name: the attribute name + * + * Gets the value (as a GVariant) of attribute with name @name on @neighbor + * + * Returns: (transfer none): the value or %NULL if the attribute with @name was + * not found. + * + * Since: 1.18 + **/ +GVariant * +nm_lldp_neighbor_get_attr_value(NMLldpNeighbor *neighbor, const char *name) +{ + g_return_val_if_fail(NM_IS_LLDP_NEIGHBOR(neighbor), FALSE); + g_return_val_if_fail(name && name[0], FALSE); + + return g_hash_table_lookup(neighbor->attrs, name); +} + +/** + * nm_lldp_neighbor_get_attr_names: + * @neighbor: the #NMLldpNeighbor + * + * Gets an array of attribute names available for @neighbor. + * + * Returns: (transfer full): a %NULL-terminated array of attribute names. + * + * Since: 1.2 + **/ +char ** +nm_lldp_neighbor_get_attr_names(NMLldpNeighbor *neighbor) +{ + const char **keys; + + g_return_val_if_fail(NM_IS_LLDP_NEIGHBOR(neighbor), NULL); + + keys = nm_utils_strdict_get_keys(neighbor->attrs, TRUE, NULL); + + return nm_utils_strv_make_deep_copied_nonnull(keys); +} + +/** + * nm_lldp_neighbor_get_attr_string_value: + * @neighbor: the #NMLldpNeighbor + * @name: the attribute name + * @out_value: (out) (allow-none) (transfer none): on return, the attribute value + * + * Gets the string value of attribute with name @name on @neighbor + * + * Returns: %TRUE if a string attribute with name @name was found, %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_lldp_neighbor_get_attr_string_value(NMLldpNeighbor *neighbor, + const char * name, + const char ** out_value) +{ + GVariant *variant; + + variant = nm_lldp_neighbor_get_attr_value(neighbor, name); + if (!variant || !g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) + return FALSE; + + NM_SET_OUT(out_value, g_variant_get_string(variant, NULL)); + return TRUE; +} + +/** + * nm_lldp_neighbor_get_attr_uint_value: + * @neighbor: the #NMLldpNeighbor + * @name: the attribute name + * @out_value: (out) (allow-none): on return, the attribute value + * + * Gets the uint32 value of attribute with name @name on @neighbor + * + * Returns: %TRUE if a uint32 attribute with name @name was found, %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_lldp_neighbor_get_attr_uint_value(NMLldpNeighbor *neighbor, const char *name, guint *out_value) +{ + GVariant *variant; + + variant = nm_lldp_neighbor_get_attr_value(neighbor, name); + if (!variant || !g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32)) + return FALSE; + + NM_SET_OUT(out_value, g_variant_get_uint32(variant)); + return TRUE; +} + +/** + * nm_lldp_neighbor_get_attr_type: + * @neighbor: the #NMLldpNeighbor + * @name: the attribute name + * + * Get the type of an attribute. + * + * Returns: the #GVariantType of the attribute with name @name + * + * Since: 1.2 + **/ +const GVariantType * +nm_lldp_neighbor_get_attr_type(NMLldpNeighbor *neighbor, const char *name) +{ + GVariant *variant; + + variant = nm_lldp_neighbor_get_attr_value(neighbor, name); + if (!variant) + return NULL; + + return g_variant_get_type(variant); +} diff --git a/src/libnm-client-impl/nm-dhcp-config.c b/src/libnm-client-impl/nm-dhcp-config.c new file mode 100644 index 0000000..c7f9a87 --- /dev/null +++ b/src/libnm-client-impl/nm-dhcp-config.c @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 - 2014 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-dhcp-config.h" + +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" +#include "nm-dbus-interface.h" +#include "nm-object-private.h" +#include "nm-utils.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMDhcpConfig, PROP_FAMILY, PROP_OPTIONS, ); + +typedef struct _NMDhcpConfigPrivate { + GHashTable *options; +} NMDhcpConfigPrivate; + +G_DEFINE_ABSTRACT_TYPE(NMDhcpConfig, nm_dhcp_config, NM_TYPE_OBJECT) + +#define NM_DHCP_CONFIG_GET_PRIVATE(self) \ + _NM_GET_PRIVATE_PTR(self, NMDhcpConfig, NM_IS_DHCP_CONFIG, NMObject) + +/*****************************************************************************/ + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_options(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMDhcpConfig * self = NM_DHCP_CONFIG(dbobj->nmobj); + NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE(self); + + g_hash_table_remove_all(priv->options); + + if (value) { + GVariantIter iter; + const char * key; + GVariant * opt; + + g_variant_iter_init(&iter, value); + while (g_variant_iter_next(&iter, "{&sv}", &key, &opt)) { + if (g_variant_is_of_type(opt, G_VARIANT_TYPE_STRING)) + g_hash_table_insert(priv->options, g_strdup(key), g_variant_dup_string(opt, NULL)); + g_variant_unref(opt); + } + } + + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + +/*****************************************************************************/ + +static void +nm_dhcp_config_init(NMDhcpConfig *self) +{ + NMDhcpConfigPrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_DHCP_CONFIG, NMDhcpConfigPrivate); + + self->_priv = priv; + + priv->options = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); +} + +static void +finalize(GObject *object) +{ + NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE(object); + + g_hash_table_destroy(priv->options); + + G_OBJECT_CLASS(nm_dhcp_config_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDhcpConfig *self = NM_DHCP_CONFIG(object); + + switch (prop_id) { + case PROP_FAMILY: + g_value_set_int(value, nm_dhcp_config_get_family(self)); + break; + case PROP_OPTIONS: + g_value_set_boxed(value, nm_dhcp_config_get_options(self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dhcp4config = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DHCP4_CONFIG, + nm_dhcp4_config_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_FCN("Options", + PROP_OPTIONS, + "a{sv}", + _notify_update_prop_options), ), + .base_struct_offset = G_STRUCT_OFFSET(NMDhcpConfig, _priv), ); + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dhcp6config = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DHCP6_CONFIG, + nm_dhcp6_config_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_FCN("Options", + PROP_OPTIONS, + "a{sv}", + _notify_update_prop_options), ), + .base_struct_offset = G_STRUCT_OFFSET(NMDhcpConfig, _priv), ); + +static void +nm_dhcp_config_class_init(NMDhcpConfigClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(config_class); + + g_type_class_add_private(config_class, sizeof(NMDhcpConfigPrivate)); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + /** + * NMDhcpConfig:family: + * + * The IP address family of the configuration; either + * AF_INET or AF_INET6. + **/ + obj_properties[PROP_FAMILY] = g_param_spec_int(NM_DHCP_CONFIG_FAMILY, + "", + "", + 0, + 255, + AF_UNSPEC, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDhcpConfig:options: (type GHashTable(utf8,utf8)): + * + * The #GHashTable containing options of the configuration. + **/ + obj_properties[PROP_OPTIONS] = g_param_spec_boxed(NM_DHCP_CONFIG_OPTIONS, + "", + "", + G_TYPE_HASH_TABLE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_dhcp4config, + &_nml_dbus_meta_iface_nm_dhcp6config); +} + +/** + * nm_dhcp_config_get_family: + * @config: a #NMDhcpConfig + * + * Gets the IP address family of the configuration + * + * Returns: the IP address family; either AF_INET or + * AF_INET6 + **/ +int +nm_dhcp_config_get_family(NMDhcpConfig *config) +{ + g_return_val_if_fail(NM_IS_DHCP_CONFIG(config), AF_UNSPEC); + + return NM_IS_DHCP4_CONFIG(config) ? AF_INET : AF_INET6; +} + +/** + * nm_dhcp_config_get_options: + * @config: a #NMDhcpConfig + * + * Gets all the options contained in the configuration. + * + * Returns: (transfer none) (element-type utf8 utf8): the #GHashTable containing + * strings for keys and values. This is the internal copy used by the + * configuration, and must not be modified. + **/ +GHashTable * +nm_dhcp_config_get_options(NMDhcpConfig *config) +{ + g_return_val_if_fail(NM_IS_DHCP_CONFIG(config), NULL); + + return NM_DHCP_CONFIG_GET_PRIVATE(config)->options; +} + +/** + * nm_dhcp_config_get_one_option: + * @config: a #NMDhcpConfig + * @option: the option to retrieve + * + * Gets one option by option name. + * + * Returns: the configuration option's value. This is the internal string used by the + * configuration, and must not be modified. + **/ +const char * +nm_dhcp_config_get_one_option(NMDhcpConfig *config, const char *option) +{ + g_return_val_if_fail(NM_IS_DHCP_CONFIG(config), NULL); + + return g_hash_table_lookup(nm_dhcp_config_get_options(config), option); +} diff --git a/src/libnm-client-impl/nm-dhcp4-config.c b/src/libnm-client-impl/nm-dhcp4-config.c new file mode 100644 index 0000000..8ce8415 --- /dev/null +++ b/src/libnm-client-impl/nm-dhcp4-config.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-dhcp4-config.h" + +/*****************************************************************************/ + +struct _NMDhcp4Config { + NMDhcpConfig parent; +}; + +struct _NMDhcp4ConfigClass { + NMDhcpConfigClass parent; +}; + +G_DEFINE_TYPE(NMDhcp4Config, nm_dhcp4_config, NM_TYPE_DHCP_CONFIG) + +/*****************************************************************************/ + +static void +nm_dhcp4_config_init(NMDhcp4Config *config) +{} + +static void +nm_dhcp4_config_class_init(NMDhcp4ConfigClass *config_class) +{} diff --git a/src/libnm-client-impl/nm-dhcp4-config.h b/src/libnm-client-impl/nm-dhcp4-config.h new file mode 100644 index 0000000..d0ea2b4 --- /dev/null +++ b/src/libnm-client-impl/nm-dhcp4-config.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NM_DHCP4_CONFIG_H__ +#define __NM_DHCP4_CONFIG_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE) + #error Cannot use this header. +#endif + +#include "nm-dhcp-config.h" + +#define NM_TYPE_DHCP4_CONFIG (nm_dhcp4_config_get_type()) +#define NM_DHCP4_CONFIG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP4_CONFIG, NMDhcp4Config)) +#define NM_DHCP4_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP4_CONFIG, NMDhcp4ConfigClass)) +#define NM_IS_DHCP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP4_CONFIG)) +#define NM_IS_DHCP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP4_CONFIG)) +#define NM_DHCP4_CONFIG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP4_CONFIG, NMDhcp4ConfigClass)) + +/** + * NMDhcp4Config: + */ +typedef struct _NMDhcp4Config NMDhcp4Config; +typedef struct _NMDhcp4ConfigClass NMDhcp4ConfigClass; + +GType nm_dhcp4_config_get_type(void); + +#endif /* __NM_DHCP4_CONFIG_H__ */ diff --git a/src/libnm-client-impl/nm-dhcp6-config.c b/src/libnm-client-impl/nm-dhcp6-config.c new file mode 100644 index 0000000..7db0264 --- /dev/null +++ b/src/libnm-client-impl/nm-dhcp6-config.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-dhcp6-config.h" + +/*****************************************************************************/ + +struct _NMDhcp6Config { + NMDhcpConfig parent; +}; + +struct _NMDhcp6ConfigClass { + NMDhcpConfigClass parent; +}; + +G_DEFINE_TYPE(NMDhcp6Config, nm_dhcp6_config, NM_TYPE_DHCP_CONFIG) + +/*****************************************************************************/ + +static void +nm_dhcp6_config_init(NMDhcp6Config *config) +{} + +static void +nm_dhcp6_config_class_init(NMDhcp6ConfigClass *config_class) +{} diff --git a/src/libnm-client-impl/nm-dhcp6-config.h b/src/libnm-client-impl/nm-dhcp6-config.h new file mode 100644 index 0000000..253594e --- /dev/null +++ b/src/libnm-client-impl/nm-dhcp6-config.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NM_DHCP6_CONFIG_H__ +#define __NM_DHCP6_CONFIG_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE) + #error Cannot use this header. +#endif + +#include "nm-dhcp-config.h" + +#define NM_TYPE_DHCP6_CONFIG (nm_dhcp6_config_get_type()) +#define NM_DHCP6_CONFIG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP6_CONFIG, NMDhcp6Config)) +#define NM_DHCP6_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP6_CONFIG, NMDhcp6ConfigClass)) +#define NM_IS_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP6_CONFIG)) +#define NM_IS_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP6_CONFIG)) +#define NM_DHCP6_CONFIG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP6_CONFIG, NMDhcp6ConfigClass)) + +/** + * NMDhcp6Config: + */ +typedef struct _NMDhcp6Config NMDhcp6Config; +typedef struct _NMDhcp6ConfigClass NMDhcp6ConfigClass; + +GType nm_dhcp6_config_get_type(void); + +#endif /* __NM_DHCP6_CONFIG_H__ */ diff --git a/src/libnm-client-impl/nm-dns-manager.c b/src/libnm-client-impl/nm-dns-manager.c new file mode 100644 index 0000000..f7c564f --- /dev/null +++ b/src/libnm-client-impl/nm-dns-manager.c @@ -0,0 +1,217 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-dns-manager.h" + +#include "nm-dbus-interface.h" +#include "nm-connection.h" +#include "nm-client.h" +#include "nm-object-private.h" +#include "nm-dbus-helpers.h" +#include "libnm-core-intern/nm-core-internal.h" + +/***************************************************************************** + * NMDnsEntry + *****************************************************************************/ + +G_DEFINE_BOXED_TYPE(NMDnsEntry, nm_dns_entry, nm_dns_entry_dup, nm_dns_entry_unref) + +struct NMDnsEntry { + guint refcount; + + char * interface; + char ** nameservers; + char ** domains; + int priority; + gboolean vpn; +}; + +/** + * nm_dns_entry_new: + * + * Creates a new #NMDnsEntry object. + * + * Returns: (transfer full): the new #NMDnsEntry object, or %NULL on error + **/ +NMDnsEntry * +nm_dns_entry_new(const char * interface, + const char *const *nameservers, + const char *const *domains, + int priority, + gboolean vpn) +{ + NMDnsEntry *entry; + guint i, len; + + entry = g_slice_new0(NMDnsEntry); + entry->refcount = 1; + + entry->interface = g_strdup(interface); + + if (nameservers) { + len = g_strv_length((char **) nameservers); + entry->nameservers = g_new(char *, len + 1); + for (i = 0; i < len + 1; i++) + entry->nameservers[i] = g_strdup(nameservers[i]); + } + + if (domains) { + len = g_strv_length((char **) domains); + entry->domains = g_new(char *, len + 1); + for (i = 0; i < len + 1; i++) + entry->domains[i] = g_strdup(domains[i]); + } + + entry->priority = priority; + entry->vpn = vpn; + + return entry; +} + +/** + * nm_dns_entry_dup: + * @entry: the #NMDnsEntry + * + * Creates a copy of @entry + * + * Returns: (transfer full): a copy of @entry + **/ +NMDnsEntry * +nm_dns_entry_dup(NMDnsEntry *entry) +{ + NMDnsEntry *copy; + + g_return_val_if_fail(entry != NULL, NULL); + g_return_val_if_fail(entry->refcount > 0, NULL); + + copy = nm_dns_entry_new(entry->interface, + (const char *const *) entry->nameservers, + (const char *const *) entry->domains, + entry->priority, + entry->vpn); + + return copy; +} + +/** + * nm_dns_entry_unref: + * @entry: the #NMDnsEntry + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + * + * Since: 1.6 + **/ +void +nm_dns_entry_unref(NMDnsEntry *entry) +{ + g_return_if_fail(entry != NULL); + g_return_if_fail(entry->refcount > 0); + + entry->refcount--; + if (entry->refcount == 0) { + g_free(entry->interface); + g_strfreev(entry->nameservers); + g_strfreev(entry->domains); + g_slice_free(NMDnsEntry, entry); + } +} + +/** + * nm_dns_entry_get_interface: + * @entry: the #NMDnsEntry + * + * Gets the interface on which name servers are contacted. + * + * Returns: (transfer none): the interface name + * + * Since: 1.6 + **/ +const char * +nm_dns_entry_get_interface(NMDnsEntry *entry) +{ + g_return_val_if_fail(entry, 0); + g_return_val_if_fail(entry->refcount > 0, 0); + + return entry->interface; +} + +/** + * nm_dns_entry_get_nameservers: + * @entry: the #NMDnsEntry + * + * Gets the list of name servers for this entry. + * + * Returns: (transfer none): the list of name servers + * + * Since: 1.6 + **/ +const char *const * +nm_dns_entry_get_nameservers(NMDnsEntry *entry) +{ + g_return_val_if_fail(entry, 0); + g_return_val_if_fail(entry->refcount > 0, 0); + + return (const char *const *) entry->nameservers; +} + +/** + * nm_dns_entry_get_domains: + * @entry: the #NMDnsEntry + * + * Gets the list of DNS domains. + * + * Returns: (transfer none): the list of DNS domains + * + * Since: 1.6 + **/ +const char *const * +nm_dns_entry_get_domains(NMDnsEntry *entry) +{ + g_return_val_if_fail(entry, 0); + g_return_val_if_fail(entry->refcount > 0, 0); + + return (const char *const *) entry->domains; +} + +/** + * nm_dns_entry_get_vpn: + * @entry: the #NMDnsEntry + * + * Gets whether the entry refers to VPN name servers. + * + * Returns: %TRUE if the entry refers to VPN name servers + * + * Since: 1.6 + **/ +gboolean +nm_dns_entry_get_vpn(NMDnsEntry *entry) +{ + g_return_val_if_fail(entry, 0); + g_return_val_if_fail(entry->refcount > 0, 0); + + return entry->vpn; +} + +/** + * nm_dns_entry_get_priority: + * @entry: the #NMDnsEntry + * + * Gets the priority of the entry + * + * Returns: the priority of the entry + * + * Since: 1.6 + **/ +int +nm_dns_entry_get_priority(NMDnsEntry *entry) +{ + g_return_val_if_fail(entry, 0); + g_return_val_if_fail(entry->refcount > 0, 0); + + return entry->priority; +} diff --git a/src/libnm-client-impl/nm-dns-manager.h b/src/libnm-client-impl/nm-dns-manager.h new file mode 100644 index 0000000..8053b24 --- /dev/null +++ b/src/libnm-client-impl/nm-dns-manager.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#ifndef __NM_DNS_MANAGER_H__ +#define __NM_DNS_MANAGER_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE) + #error Cannot use this header. +#endif + +#include "nm-client.h" + +NMDnsEntry *nm_dns_entry_new(const char * interface, + const char *const *nameservers, + const char *const *domains, + int priority, + gboolean vpn); +NMDnsEntry *nm_dns_entry_dup(NMDnsEntry *entry); + +#endif /* __NM_DNS_MANAGER_H__ */ diff --git a/src/libnm-client-impl/nm-ip-config.c b/src/libnm-client-impl/nm-ip-config.c new file mode 100644 index 0000000..099dd08 --- /dev/null +++ b/src/libnm-client-impl/nm-ip-config.c @@ -0,0 +1,644 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2011 Novell, Inc. + * Copyright (C) 2008 - 2014 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-ip-config.h" + +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" +#include "nm-setting-ip-config.h" +#include "nm-dbus-interface.h" +#include "nm-object-private.h" +#include "nm-utils.h" +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMIPConfig, + PROP_FAMILY, + PROP_GATEWAY, + PROP_ADDRESSES, + PROP_ROUTES, + PROP_NAMESERVERS, + PROP_DOMAINS, + PROP_SEARCHES, + PROP_WINS_SERVERS, ); + +typedef struct _NMIPConfigPrivate { + GPtrArray *addresses; + GPtrArray *routes; + char ** nameservers; + char ** domains; + char ** searches; + char ** wins_servers; + char * gateway; + + bool addresses_new_style : 1; + bool routes_new_style : 1; + bool nameservers_new_style : 1; + bool wins_servers_new_style : 1; +} NMIPConfigPrivate; + +G_DEFINE_ABSTRACT_TYPE(NMIPConfig, nm_ip_config, NM_TYPE_OBJECT) + +#define NM_IP_CONFIG_GET_PRIVATE(self) \ + _NM_GET_PRIVATE_PTR(self, NMIPConfig, NM_IS_IP_CONFIG, NMObject) + +/*****************************************************************************/ + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_addresses(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMIPConfig * self = NM_IP_CONFIG(dbobj->nmobj); + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self); + gs_unref_ptrarray GPtrArray *addresses_old = NULL; + gs_unref_ptrarray GPtrArray *addresses_new = NULL; + int addr_family = meta_iface == &_nml_dbus_meta_iface_nm_ip4config ? AF_INET : AF_INET6; + gboolean new_style; + + new_style = + (((const char *) meta_iface->dbus_properties[dbus_property_idx].dbus_type)[2] == '{'); + + if (priv->addresses_new_style) { + if (!new_style) + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; + } else + priv->addresses_new_style = new_style; + + if (value) { + if (new_style) + addresses_new = nm_utils_ip_addresses_from_variant(value, addr_family); + else if (addr_family == AF_INET) + addresses_new = nm_utils_ip4_addresses_from_variant(value, NULL); + else + addresses_new = nm_utils_ip6_addresses_from_variant(value, NULL); + nm_assert(addresses_new); + } + if (!addresses_new) + addresses_new = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + + addresses_old = priv->addresses; + priv->addresses = g_steal_pointer(&addresses_new); + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_routes(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMIPConfig * self = NM_IP_CONFIG(dbobj->nmobj); + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self); + gs_unref_ptrarray GPtrArray *routes_old = NULL; + gs_unref_ptrarray GPtrArray *routes_new = NULL; + int addr_family = meta_iface == &_nml_dbus_meta_iface_nm_ip4config ? AF_INET : AF_INET6; + gboolean new_style; + + new_style = + (((const char *) meta_iface->dbus_properties[dbus_property_idx].dbus_type)[2] == '{'); + + if (priv->routes_new_style) { + if (!new_style) + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; + } else + priv->routes_new_style = new_style; + + if (value) { + if (new_style) + routes_new = nm_utils_ip_routes_from_variant(value, addr_family); + else if (addr_family == AF_INET) + routes_new = nm_utils_ip4_routes_from_variant(value); + else + routes_new = nm_utils_ip6_routes_from_variant(value); + nm_assert(routes_new); + } + if (!routes_new) + routes_new = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); + + routes_old = priv->routes; + priv->routes = g_steal_pointer(&routes_new); + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_nameservers(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMIPConfig * self = NM_IP_CONFIG(dbobj->nmobj); + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self); + gs_strfreev char **nameservers_new = NULL; + gboolean new_style = TRUE; + int addr_family = meta_iface == &_nml_dbus_meta_iface_nm_ip4config ? AF_INET : AF_INET6; + + if (addr_family == AF_INET) { + new_style = + (((const char *) meta_iface->dbus_properties[dbus_property_idx].dbus_type)[1] == 'a'); + + if (priv->nameservers_new_style) { + if (!new_style) + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; + } else + priv->nameservers_new_style = new_style; + } + + if (value) { + if (addr_family == AF_INET6) + nameservers_new = nm_utils_ip6_dns_from_variant(value); + else if (!new_style) + nameservers_new = nm_utils_ip4_dns_from_variant(value); + else { + GVariantIter iter; + GVariantIter * iter_v; + gs_unref_ptrarray GPtrArray *arr = NULL; + + g_variant_iter_init(&iter, value); + while (g_variant_iter_next(&iter, "a{sv}", &iter_v)) { + const char *key; + GVariant * val; + + while (g_variant_iter_next(iter_v, "{&sv}", &key, &val)) { + if (nm_streq(key, "address")) { + gs_free char *val_str = NULL; + + if (!g_variant_is_of_type(val, G_VARIANT_TYPE_STRING)) + goto next; + if (!nm_utils_parse_inaddr(AF_INET, + g_variant_get_string(val, NULL), + &val_str)) + goto next; + if (!arr) + arr = g_ptr_array_new(); + g_ptr_array_add(arr, g_steal_pointer(&val_str)); + goto next; + } +next: + g_variant_unref(val); + } + g_variant_iter_free(iter_v); + } + if (arr && arr->len > 0) + nameservers_new = nm_utils_strv_dup((char **) arr->pdata, arr->len, FALSE); + else + nameservers_new = g_new0(char *, 1); + } + nm_assert(nameservers_new); + } + + g_strfreev(priv->nameservers); + priv->nameservers = g_steal_pointer(&nameservers_new); + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_wins_servers(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + NMIPConfig * self = NM_IP_CONFIG(dbobj->nmobj); + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self); + gs_strfreev char **wins_servers_new = NULL; + gboolean new_style; + + new_style = + (((const char *) meta_iface->dbus_properties[dbus_property_idx].dbus_type)[1] == 's'); + + if (priv->wins_servers_new_style) { + if (!new_style) + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; + } else + priv->wins_servers_new_style = new_style; + + if (value) { + if (new_style) + wins_servers_new = g_variant_dup_strv(value, NULL); + else + wins_servers_new = nm_utils_ip4_dns_from_variant(value); + nm_assert(wins_servers_new); + } + + g_strfreev(priv->wins_servers); + priv->wins_servers = g_steal_pointer(&wins_servers_new); + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMIPConfig *self = NM_IP_CONFIG(object); + + switch (prop_id) { + case PROP_FAMILY: + g_value_set_int(value, nm_ip_config_get_family(self)); + break; + case PROP_GATEWAY: + g_value_set_string(value, nm_ip_config_get_gateway(self)); + break; + case PROP_ADDRESSES: + g_value_take_boxed(value, + _nm_utils_copy_array(nm_ip_config_get_addresses(self), + (NMUtilsCopyFunc) nm_ip_address_dup, + (GDestroyNotify) nm_ip_address_unref)); + break; + case PROP_ROUTES: + g_value_take_boxed(value, + _nm_utils_copy_array(nm_ip_config_get_routes(self), + (NMUtilsCopyFunc) nm_ip_route_dup, + (GDestroyNotify) nm_ip_route_unref)); + break; + case PROP_NAMESERVERS: + g_value_set_boxed(value, (char **) nm_ip_config_get_nameservers(self)); + break; + case PROP_DOMAINS: + g_value_set_boxed(value, (char **) nm_ip_config_get_domains(self)); + break; + case PROP_SEARCHES: + g_value_set_boxed(value, (char **) nm_ip_config_get_searches(self)); + break; + case PROP_WINS_SERVERS: + g_value_set_boxed(value, (char **) nm_ip_config_get_wins_servers(self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_ip_config_init(NMIPConfig *self) +{ + NMIPConfigPrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_IP_CONFIG, NMIPConfigPrivate); + + self->_priv = priv; + + priv->addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + priv->routes = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); +} + +static void +finalize(GObject *object) +{ + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(object); + + g_free(priv->gateway); + + g_ptr_array_unref(priv->routes); + g_ptr_array_unref(priv->addresses); + + g_strfreev(priv->nameservers); + g_strfreev(priv->domains); + g_strfreev(priv->searches); + g_strfreev(priv->wins_servers); + + G_OBJECT_CLASS(nm_ip_config_parent_class)->finalize(object); +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_ip4config = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_IP4_CONFIG, + nm_ip4_config_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_FCN("AddressData", + PROP_ADDRESSES, + "aa{sv}", + _notify_update_prop_addresses), + NML_DBUS_META_PROPERTY_INIT_FCN("Addresses", + PROP_ADDRESSES, + "aau", + _notify_update_prop_addresses, + .obj_property_no_reverse_idx = TRUE), + NML_DBUS_META_PROPERTY_INIT_TODO("DnsOptions", "as"), + NML_DBUS_META_PROPERTY_INIT_TODO("DnsPriority", "i"), + NML_DBUS_META_PROPERTY_INIT_AS("Domains", PROP_DOMAINS, NMIPConfigPrivate, domains), + NML_DBUS_META_PROPERTY_INIT_S("Gateway", PROP_GATEWAY, NMIPConfigPrivate, gateway), + NML_DBUS_META_PROPERTY_INIT_FCN("NameserverData", + PROP_NAMESERVERS, + "aa{sv}", + _notify_update_prop_nameservers), + NML_DBUS_META_PROPERTY_INIT_FCN("Nameservers", + PROP_NAMESERVERS, + "au", + _notify_update_prop_nameservers, + .obj_property_no_reverse_idx = TRUE), + NML_DBUS_META_PROPERTY_INIT_FCN("RouteData", + PROP_ROUTES, + "aa{sv}", + _notify_update_prop_routes), + NML_DBUS_META_PROPERTY_INIT_FCN("Routes", + PROP_ROUTES, + "aau", + _notify_update_prop_routes, + .obj_property_no_reverse_idx = TRUE), + NML_DBUS_META_PROPERTY_INIT_AS("Searches", PROP_SEARCHES, NMIPConfigPrivate, searches), + NML_DBUS_META_PROPERTY_INIT_FCN("WinsServerData", + PROP_WINS_SERVERS, + "as", + _notify_update_prop_wins_servers), + NML_DBUS_META_PROPERTY_INIT_FCN("WinsServers", + PROP_WINS_SERVERS, + "au", + _notify_update_prop_wins_servers, + .obj_property_no_reverse_idx = TRUE), ), + .base_struct_offset = G_STRUCT_OFFSET(NMIPConfig, _priv), ); + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_ip6config = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_IP6_CONFIG, + nm_ip6_config_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_FCN("AddressData", + PROP_ADDRESSES, + "aa{sv}", + _notify_update_prop_addresses), + NML_DBUS_META_PROPERTY_INIT_FCN("Addresses", + PROP_ADDRESSES, + "a(ayuay)", + _notify_update_prop_addresses, + .obj_property_no_reverse_idx = TRUE), + NML_DBUS_META_PROPERTY_INIT_TODO("DnsOptions", "as"), + NML_DBUS_META_PROPERTY_INIT_TODO("DnsPriority", "i"), + NML_DBUS_META_PROPERTY_INIT_AS("Domains", PROP_DOMAINS, NMIPConfigPrivate, domains), + NML_DBUS_META_PROPERTY_INIT_S("Gateway", PROP_GATEWAY, NMIPConfigPrivate, gateway), + NML_DBUS_META_PROPERTY_INIT_FCN("Nameservers", + PROP_NAMESERVERS, + "aay", + _notify_update_prop_nameservers), + NML_DBUS_META_PROPERTY_INIT_FCN("RouteData", + PROP_ROUTES, + "aa{sv}", + _notify_update_prop_routes), + NML_DBUS_META_PROPERTY_INIT_FCN("Routes", + PROP_ROUTES, + "a(ayuayu)", + _notify_update_prop_routes, + .obj_property_no_reverse_idx = TRUE), + NML_DBUS_META_PROPERTY_INIT_AS("Searches", PROP_SEARCHES, NMIPConfigPrivate, searches), ), + .base_struct_offset = G_STRUCT_OFFSET(NMIPConfig, _priv), ); + +static void +nm_ip_config_class_init(NMIPConfigClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(config_class); + + g_type_class_add_private(config_class, sizeof(NMIPConfigPrivate)); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + /** + * NMIPConfig:family: + * + * The IP address family of the configuration; either + * AF_INET or AF_INET6. + **/ + obj_properties[PROP_FAMILY] = g_param_spec_int(NM_IP_CONFIG_FAMILY, + "", + "", + 0, + 255, + AF_UNSPEC, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMIPConfig:gateway: + * + * The IP gateway address of the configuration as string. + **/ + obj_properties[PROP_GATEWAY] = g_param_spec_string(NM_IP_CONFIG_GATEWAY, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMIPConfig:addresses: + * + * A #GPtrArray containing the addresses (#NMIPAddress) of the configuration. + **/ + obj_properties[PROP_ADDRESSES] = g_param_spec_boxed(NM_IP_CONFIG_ADDRESSES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMIPConfig:routes: (type GPtrArray(NMIPRoute)) + * + * A #GPtrArray containing the routes (#NMIPRoute) of the configuration. + **/ + obj_properties[PROP_ROUTES] = g_param_spec_boxed(NM_IP_CONFIG_ROUTES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMIPConfig:nameservers: + * + * The array containing name server IP addresses of the configuration. + **/ + obj_properties[PROP_NAMESERVERS] = + g_param_spec_boxed(NM_IP_CONFIG_NAMESERVERS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMIPConfig:domains: + * + * The array containing domain strings of the configuration. + **/ + obj_properties[PROP_DOMAINS] = g_param_spec_boxed(NM_IP_CONFIG_DOMAINS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMIPConfig:searches: + * + * The array containing DNS search strings of the configuration. + **/ + obj_properties[PROP_SEARCHES] = g_param_spec_boxed(NM_IP_CONFIG_SEARCHES, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMIPConfig:wins-servers: + * + * The array containing WINS server IP addresses of the configuration. + * (This will always be empty for IPv6 configurations.) + **/ + obj_properties[PROP_WINS_SERVERS] = + g_param_spec_boxed(NM_IP_CONFIG_WINS_SERVERS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_ip4config, + &_nml_dbus_meta_iface_nm_ip6config); +} + +/** + * nm_ip_config_get_family: + * @config: a #NMIPConfig + * + * Gets the IP address family + * + * Returns: the IP address family; either AF_INET or + * AF_INET6 + **/ +int +nm_ip_config_get_family(NMIPConfig *config) +{ + g_return_val_if_fail(NM_IS_IP_CONFIG(config), AF_UNSPEC); + + return NM_IS_IP4_CONFIG(config) ? AF_INET : AF_INET6; +} + +/** + * nm_ip_config_get_gateway: + * @config: a #NMIPConfig + * + * Gets the IP gateway address. + * + * Returns: (transfer none): the IP address of the gateway. + **/ +const char * +nm_ip_config_get_gateway(NMIPConfig *config) +{ + g_return_val_if_fail(NM_IS_IP_CONFIG(config), NULL); + + return _nml_coerce_property_str_not_empty(NM_IP_CONFIG_GET_PRIVATE(config)->gateway); +} + +/** + * nm_ip_config_get_addresses: + * @config: a #NMIPConfig + * + * Gets the IP addresses (containing the address, prefix, and gateway). + * + * Returns: (element-type NMIPAddress) (transfer none): the #GPtrArray + * containing #NMIPAddresses. This is the internal copy used by the + * configuration and must not be modified. The library never modifies the + * returned array and thus it is safe for callers to reference and keep using it. + **/ +GPtrArray * +nm_ip_config_get_addresses(NMIPConfig *config) +{ + g_return_val_if_fail(NM_IS_IP_CONFIG(config), NULL); + + return NM_IP_CONFIG_GET_PRIVATE(config)->addresses; +} + +/** + * nm_ip_config_get_nameservers: + * @config: a #NMIPConfig + * + * Gets the domain name servers (DNS). + * + * Returns: (transfer none): the array of nameserver IP addresses + **/ +const char *const * +nm_ip_config_get_nameservers(NMIPConfig *config) +{ + g_return_val_if_fail(NM_IS_IP_CONFIG(config), NULL); + + return _nml_coerce_property_strv_not_null(NM_IP_CONFIG_GET_PRIVATE(config)->nameservers); +} + +/** + * nm_ip_config_get_domains: + * @config: a #NMIPConfig + * + * Gets the domain names. + * + * Returns: (transfer none): the array of domains. + * (This is never %NULL, though it may be 0-length). + **/ +const char *const * +nm_ip_config_get_domains(NMIPConfig *config) +{ + g_return_val_if_fail(NM_IS_IP_CONFIG(config), NULL); + + return _nml_coerce_property_strv_not_null(NM_IP_CONFIG_GET_PRIVATE(config)->domains); +} + +/** + * nm_ip_config_get_searches: + * @config: a #NMIPConfig + * + * Gets the DNS searches. + * + * Returns: (transfer none): the array of DNS search strings. + * (This is never %NULL, though it may be 0-length). + **/ +const char *const * +nm_ip_config_get_searches(NMIPConfig *config) +{ + g_return_val_if_fail(NM_IS_IP_CONFIG(config), NULL); + + return _nml_coerce_property_strv_not_null(NM_IP_CONFIG_GET_PRIVATE(config)->searches); +} + +/** + * nm_ip_config_get_wins_servers: + * @config: a #NMIPConfig + * + * Gets the Windows Internet Name Service servers (WINS). + * + * Returns: (transfer none): the arry of WINS server IP address strings. + * (This is never %NULL, though it may be 0-length.) + **/ +const char *const * +nm_ip_config_get_wins_servers(NMIPConfig *config) +{ + g_return_val_if_fail(NM_IS_IP_CONFIG(config), NULL); + + return _nml_coerce_property_strv_not_null(NM_IP_CONFIG_GET_PRIVATE(config)->wins_servers); +} + +/** + * nm_ip_config_get_routes: + * @config: a #NMIPConfig + * + * Gets the routes. + * + * Returns: (element-type NMIPRoute) (transfer none): the #GPtrArray containing + * #NMIPRoutes. This is the internal copy used by the configuration, and must + * not be modified. The library never modifies the returned array and thus it is + * safe for callers to reference and keep using it. + * + **/ +GPtrArray * +nm_ip_config_get_routes(NMIPConfig *config) +{ + g_return_val_if_fail(NM_IS_IP_CONFIG(config), NULL); + + return NM_IP_CONFIG_GET_PRIVATE(config)->routes; +} diff --git a/src/libnm-client-impl/nm-ip4-config.c b/src/libnm-client-impl/nm-ip4-config.c new file mode 100644 index 0000000..0f2fdb0 --- /dev/null +++ b/src/libnm-client-impl/nm-ip4-config.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-ip4-config.h" + +/*****************************************************************************/ + +struct _NMIP4Config { + NMIPConfig parent; +}; + +struct _NMIP4ConfigClass { + NMIPConfigClass parent; +}; + +G_DEFINE_TYPE(NMIP4Config, nm_ip4_config, NM_TYPE_IP_CONFIG) + +/*****************************************************************************/ + +static void +nm_ip4_config_init(NMIP4Config *config) +{} + +static void +nm_ip4_config_class_init(NMIP4ConfigClass *config_class) +{} diff --git a/src/libnm-client-impl/nm-ip4-config.h b/src/libnm-client-impl/nm-ip4-config.h new file mode 100644 index 0000000..b9297dc --- /dev/null +++ b/src/libnm-client-impl/nm-ip4-config.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2008 Red Hat, Inc. + */ + +#ifndef __NM_IP4_CONFIG_H__ +#define __NM_IP4_CONFIG_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE) + #error Cannot use this header. +#endif + +#include "nm-ip-config.h" + +#define NM_TYPE_IP4_CONFIG (nm_ip4_config_get_type()) +#define NM_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_IP4_CONFIG, NMIP4Config)) +#define NM_IP4_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass)) +#define NM_IS_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_IP4_CONFIG)) +#define NM_IS_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_IP4_CONFIG)) +#define NM_IP4_CONFIG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass)) + +/** + * NMIP4Config: + */ +typedef struct _NMIP4Config NMIP4Config; +typedef struct _NMIP4ConfigClass NMIP4ConfigClass; + +GType nm_ip4_config_get_type(void); + +#endif /* __NM_IP4_CONFIG_H__ */ diff --git a/src/libnm-client-impl/nm-ip6-config.c b/src/libnm-client-impl/nm-ip6-config.c new file mode 100644 index 0000000..78e0b7d --- /dev/null +++ b/src/libnm-client-impl/nm-ip6-config.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-ip6-config.h" + +/*****************************************************************************/ + +struct _NMIP6Config { + NMIPConfig parent; +}; + +struct _NMIP6ConfigClass { + NMIPConfigClass parent; +}; + +G_DEFINE_TYPE(NMIP6Config, nm_ip6_config, NM_TYPE_IP_CONFIG) + +/*****************************************************************************/ + +static void +nm_ip6_config_init(NMIP6Config *config) +{} + +static void +nm_ip6_config_class_init(NMIP6ConfigClass *config_class) +{} diff --git a/src/libnm-client-impl/nm-ip6-config.h b/src/libnm-client-impl/nm-ip6-config.h new file mode 100644 index 0000000..0c7c2a9 --- /dev/null +++ b/src/libnm-client-impl/nm-ip6-config.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2008 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_IP6_CONFIG_H__ +#define __NM_IP6_CONFIG_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE) + #error Cannot use this header. +#endif + +#include "nm-ip-config.h" + +#define NM_TYPE_IP6_CONFIG (nm_ip6_config_get_type()) +#define NM_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_IP6_CONFIG, NMIP6Config)) +#define NM_IP6_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_IP6_CONFIG, NMIP6ConfigClass)) +#define NM_IS_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_IP6_CONFIG)) +#define NM_IS_IP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_IP6_CONFIG)) +#define NM_IP6_CONFIG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_IP6_CONFIG, NMIP6ConfigClass)) + +/** + * NMIP6Config: + */ +typedef struct _NMIP6Config NMIP6Config; +typedef struct _NMIP6ConfigClass NMIP6ConfigClass; + +GType nm_ip6_config_get_type(void); + +#endif /* __NM_IP6_CONFIG_H__ */ diff --git a/src/libnm-client-impl/nm-libnm-utils.c b/src/libnm-client-impl/nm-libnm-utils.c new file mode 100644 index 0000000..3cc88ef --- /dev/null +++ b/src/libnm-client-impl/nm-libnm-utils.c @@ -0,0 +1,913 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2018 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-libnm-utils.h" + +#include "libnm-glib-aux/nm-time-utils.h" +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "nm-object.h" + +/*****************************************************************************/ + +volatile int _nml_dbus_log_level = 0; + +int +_nml_dbus_log_level_init(void) +{ + const GDebugKey keys[] = { + {"trace", _NML_DBUS_LOG_LEVEL_TRACE}, + {"debug", _NML_DBUS_LOG_LEVEL_DEBUG}, + {"warning", _NML_DBUS_LOG_LEVEL_WARN}, + {"error", _NML_DBUS_LOG_LEVEL_ERROR}, + {"stdout", NML_DBUS_LOG_STDOUT}, + }; + int l; + + l = _NML_DBUS_LOG_LEVEL_INITIALIZED + | nm_utils_parse_debug_string(g_getenv("LIBNM_CLIENT_DEBUG"), keys, G_N_ELEMENTS(keys)); + + if (!g_atomic_int_compare_and_exchange(&_nml_dbus_log_level, 0, l)) + l = g_atomic_int_get(&_nml_dbus_log_level); + + nm_assert(l & _NML_DBUS_LOG_LEVEL_INITIALIZED); + return l; +} + +void +_nml_dbus_log(NMLDBusLogLevel level, gboolean use_stdout, const char *fmt, ...) +{ + NMLDBusLogLevel configured_log_level; + gs_free char * msg = NULL; + va_list args; + const char * prefix = ""; + gint64 ts; + pid_t pid; + + /* we only call _nml_dbus_log() after nml_dbus_log_enabled(), which already does + * an atomic access to the variable. Since the value is only initialized once and + * never changes, we can just access it without additional locking. */ + configured_log_level = _nml_dbus_log_level; + + nm_assert(level & configured_log_level); + + va_start(args, fmt); + msg = g_strdup_vprintf(fmt, args); + va_end(args); + + switch (level) { + case NML_DBUS_LOG_LEVEL_TRACE: + prefix = " "; + break; + case NML_DBUS_LOG_LEVEL_DEBUG: + prefix = " "; + break; + case NML_DBUS_LOG_LEVEL_WARN: + prefix = " "; + if (NM_FLAGS_HAS(configured_log_level, _NML_DBUS_LOG_LEVEL_WARN)) { + g_warning("libnm-dbus: %s%s", prefix, msg); + return; + } + break; + case NML_DBUS_LOG_LEVEL_ERROR: + prefix = " "; + if (NM_FLAGS_HAS(configured_log_level, _NML_DBUS_LOG_LEVEL_ERROR)) { + g_critical("libnm-dbus: %s%s", prefix, msg); + return; + } + if (NM_FLAGS_HAS(configured_log_level, _NML_DBUS_LOG_LEVEL_WARN)) { + g_warning("libnm-dbus: %s%s", prefix, msg); + return; + } + break; + default: + break; + } + + ts = nm_utils_clock_gettime_nsec(CLOCK_BOOTTIME); + + pid = getpid(); + + if (use_stdout) { + g_print("libnm-dbus[%lld]: %s[%" G_GINT64_FORMAT ".%05" G_GINT64_FORMAT "] %s\n", + (long long) pid, + prefix, + ts / NM_UTILS_NSEC_PER_SEC, + (ts / (NM_UTILS_NSEC_PER_SEC / 10000)) % 10000, + msg); + } else { + g_printerr("libnm-dbus[%lld]: %s[%" G_GINT64_FORMAT ".%05" G_GINT64_FORMAT "] %s\n", + (long long) pid, + prefix, + ts / NM_UTILS_NSEC_PER_SEC, + (ts / (NM_UTILS_NSEC_PER_SEC / 10000)) % 10000, + msg); + } +} + +/*****************************************************************************/ + +/* Stolen from dbus-glib */ +char * +nm_utils_wincaps_to_dash(const char *caps) +{ + const char *p; + GString * str; + + str = g_string_new(NULL); + p = caps; + while (*p) { + if (g_ascii_isupper(*p)) { + if (str->len > 0 && (str->len < 2 || str->str[str->len - 2] != '-')) + g_string_append_c(str, '-'); + g_string_append_c(str, g_ascii_tolower(*p)); + } else + g_string_append_c(str, *p); + ++p; + } + + return g_string_free(str, FALSE); +} + +/*****************************************************************************/ + +static char * +_fixup_string(const char * desc, + const char *const *ignored_phrases, + const char *const *ignored_words, + gboolean square_brackets_sensible) +{ + char * desc_full; + gboolean in_paren = FALSE; + char * p, *q; + int i; + + if (!desc || !desc[0]) + return NULL; + + /* restore original non-UTF-8-safe text. */ + desc_full = nm_utils_str_utf8safe_unescape_cp(desc, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + + /* replace all invalid UTF-8 bytes with space. */ + p = desc_full; + while (!g_utf8_validate(p, -1, (const char **) &q)) { + /* the byte is invalid UTF-8. Replace it with space and proceed. */ + *q = ' '; + p = q + 1; + } + + /* replace '_', ',', ASCII control characters and parentheses, with space. */ + for (p = desc_full; p[0]; p++) { + if (*p == '(') + in_paren = TRUE; + if (NM_IN_SET(*p, '_', ',') || *p < ' ' || in_paren) + *p = ' '; + if (*p == ')') + in_paren = FALSE; + } + + /* Attempt to shorten ID by ignoring certain phrases */ + for (i = 0; ignored_phrases[i]; i++) { + p = strstr(desc_full, ignored_phrases[i]); + if (p) { + const char *eow = &p[strlen(ignored_phrases[i])]; + + /* require that the phrase is delimited by space, or + * at the beginning or end of the description. */ + if ((p == desc_full || p[-1] == ' ') && NM_IN_SET(eow[0], '\0', ' ')) + memmove(p, eow, strlen(eow) + 1); /* +1 for the \0 */ + } + } + + /* Attempt to shorten ID by ignoring certain individual words. + * - word-split the description at spaces + * - coalesce multiple spaces + * - skip over ignored_words */ + p = desc_full; + q = desc_full; + for (;;) { + char *eow; + gsize l; + + /* skip leading spaces. */ + while (p[0] == ' ') + p++; + + if (!p[0]) + break; + + /* split leading word on first space */ + eow = strchr(p, ' '); + if (eow) + *eow = '\0'; + + if (nm_utils_strv_find_first((char **) ignored_words, -1, p) >= 0) + goto next; + + l = strlen(p); + if (q != p) { + if (q != desc_full) + *q++ = ' '; + memmove(q, p, l); + } + q += l; + +next: + if (!eow) + break; + p = eow + 1; + } + + *q++ = '\0'; + + p = strchr(desc_full, '['); + if (p == desc_full) { + /* All we're left with is in square brackets. + * Always prefer that to a blank string.*/ + square_brackets_sensible = TRUE; + } + if (square_brackets_sensible) { + /* If there's a [] that survived the substitution, then the string + * is a short form that is generally preferable. */ + q = strchr(desc_full, ']'); + if (p && q > p) { + p++; + memmove(desc_full, p, q - p); + desc_full[q - p] = '\0'; + } + } else { + /* [] sometimes contains the preferred human-readable name, but + * mostly it's utterly useless. Sigh. Drop it. */ + if (p) { + if (p > desc_full && p[-1] == ' ') + p--; + *p = '\0'; + } + } + + if (!desc_full[0]) { + g_free(desc_full); + return NULL; + } + + return desc_full; +} + +char * +nm_utils_fixup_vendor_string(const char *desc) +{ + static const char *const IGNORED_PHRASES[] = { + "Access Systems", + "Business Mobile Networks BV", + "Communications & Multimedia", + "Company of Japan", + "Computer Co.", + "Computer Corp.", + "Computer Corporation", + "Computer Inc.", + "Computer, Inc.", + "Information and Communication Products", + "Macao Commercial Offshore", + "Mobile Phones", + "(M) Son", + "Multimedia Internet Technology", + "Technology Group Ltd.", + "Wireless Networks", + "Wireless Solutions", + NULL, + }; + static const char *const IGNORED_WORDS[] = { + "AB", + "AG", + "A/S", + "ASA", + "B.V.", + "Chips", + "Co.", + "Co", + "Communications", + "Components", + "Computers", + "Computertechnik", + "corp.", + "Corp.", + "Corp", + "Corporation", + "Design", + "Electronics", + "Enterprise", + "Enterprises", + "Europe", + "GmbH", + "Hardware", + "[hex]", + "Holdings", + "Inc.", + "Inc", + "INC.", + "Incorporated", + "Instruments", + "International", + "Intl.", + "Labs", + "Limited.", + "Limited", + "Ltd.", + "Ltd", + "Microelectronics", + "Microsystems", + "MSM", + "Multimedia", + "Networks", + "Norway", + "Optical", + "PCS", + "Semiconductor", + "Systems", + "Systemtechnik", + "Techcenter", + "Technik", + "Technologies", + "Technology", + "TECHNOLOGY", + "Telephonics", + "USA", + "WCDMA", + NULL, + }; + char *desc_full; + char *p; + + desc_full = _fixup_string(desc, IGNORED_PHRASES, IGNORED_WORDS, TRUE); + if (!desc_full) + return NULL; + + /* Chop off everything after a slash. */ + for (p = desc_full; *p; p++) { + if ((p[0] == ' ' && p[1] == '/') || p[0] == '/') { + p[0] = '\0'; + break; + } + } + + nm_assert(g_utf8_validate(desc_full, -1, NULL)); + + return desc_full; +} + +char * +nm_utils_fixup_product_string(const char *desc) +{ + static const char *const IGNORED_PHRASES[] = { + "100/10 MBit", + "10/100 Mbps", + "1.0 GbE", + "10 GbE", + "10 Gigabit", + "10 Mbps", + "1/10 Gigabit", + "150 Mbps", + "2.5 GbE", + "54 Mbps", + "Attached Port", + "+ BT", + "\"CDC Subset\"", + "CE Media Processor", + "Controller Area Network", + "Converged Network", + "DEC-Tulip compatible", + "Dish Adapter", + "Double 108 Mbps", + "Dual Band", + "Dual Port", + "Embedded UTP", + "Ethernet Connection", + "Ethernet Pro 100", + "Express Module", + "Fabric Adapter", + "Fast Ethernet", + "for 10GBASE-T", + "for 10GbE backplane", + "for 10GbE QSFP+", + "for 10GbE SFP+", + "for 1GbE", + "for 20GbE backplane", + "for 25GbE backplane", + "for 25GbE SFP28", + "for 40GbE backplane", + "for 40GbE QSFP+", + "G Adapter", + "Gigabit Desktop Network", + "Gigabit Ethernet", + "Gigabit or", + "Host Interface", + "Host Virtual Interface", + "IEEE 802.11a/b/g", + "IEEE 802.11g", + "IEEE 802.11G", + "IEEE 802.11n", + "MAC + PHY", + "Mini Card", + "Mini Wireless", + "multicore SoC", + "Multi Function", + "N Draft 11n Wireless", + "Network Connection", + "Network Everywhere", + "N Wireless", + "N+ Wireless", + "OCT To Fast Ethernet Converter", + "PC Card", + "PCI Express", + "Platform Controller Hub", + "Plus Bluetooth", + "Quad Gigabit", + "rev 1", + "rev 17", + "rev 2", + "rev A", + "rev B", + "rev F", + "TO Ethernet", + "Turbo Wireless Adapter", + "Unified Wire", + "USB 1.1", + "USB 2.0", + "Virtual media for", + "WiFi Link", + "+ WiMAX", + "WiMAX/WiFi Link", + "Wireless G", + "Wireless G+", + "Wireless Lan", + "Wireless Mini adapter", + "Wireless Mini Adapter", + "Wireless N", + "with 1000-BASE-T interface", + "with CX4 copper interface", + "with Range Amplifier", + "with SR-XFP optical interface", + "w/ Upgradable Antenna", + NULL, + }; + static const char *const IGNORED_WORDS[] = { + "1000BaseSX", + "1000BASE-T", + "1000Base-ZX", + "100/10M", + "100baseFx", + "100Base-MII", + "100Base-T", + "100BaseT4", + "100Base-TX", + "100BaseTX", + "100GbE", + "100Mbps", + "100MBps", + "10/100", + "10/100/1000", + "10/100/1000Base-T", + "10/100/1000BASE-T", + "10/100BaseT", + "10/100baseTX", + "10/100BaseTX", + "10/100/BNC", + "10/100M", + "10/20-Gigabit", + "10/25/40/50GbE", + "10/40G", + "10base-FL", + "10BaseT", + "10BASE-T", + "10G", + "10Gb", + "10Gb/25Gb", + "10Gb/25Gb/40Gb/50Gb", + "10Gbase-T", + "10GBase-T", + "10GBASE-T", + "10GbE", + "10Gbps", + "10-Giga", + "10-Gigabit", + "10mbps", + "10Mbps", + "1/10GbE", + "1/10-Gigabit", + "11b/g/n", + "11g", + "150Mbps", + "16Gbps/10Gbps", + "1GbE", + "1x2:2", + "20GbE", + "25Gb", + "25GbE", + "2-Port", + "2x3:3", + "3G", + "3G/4G", + "3x3:3", + "40GbE", + "4G", + "54g", + "54M", + "54Mbps", + "56k", + "5G", + "802.11", + "802.11a/b/g", + "802.11abg", + "802.11a/b/g/n", + "802.11abgn", + "802.11ac", + "802.11ad", + "802.11a/g", + "802.11b", + "802.11b/g", + "802.11bg", + "802.11b/g/n", + "802.11bgn", + "802.11b/g/n-draft", + "802.11g", + "802.11n", + "802.11N", + "802.11n/b/g", + "802.11ng", + "802AIN", + "802UIG-1", + "adapter", + "Adapter", + "adaptor", + "ADSL", + "Basic", + "CAN-Bus", + "card", + "Card", + "Cardbus", + "CardBus", + "CDMA", + "CNA", + "Composite", + "controller", + "Controller", + "Copper", + "DB", + "Desktop", + "device", + "Device", + "dongle", + "driver", + "Dual-band", + "Dual-Protocol", + "EISA", + "Enhanced", + "ethernet.", + "ethernet", + "Ethernet", + "Ethernet/RNDIS", + "ExpressModule", + "family", + "Family", + "Fast/Gigabit", + "Fiber", + "gigabit", + "Gigabit", + "G-NIC", + "Hi-Gain", + "Hi-Speed", + "HSDPA", + "HSUPA", + "integrated", + "Integrated", + "interface", + "LAN", + "LAN+Winmodem", + "Laptop", + "LTE", + "LTE/UMTS/GSM", + "MAC", + "Micro", + "Mini-Card", + "Mini-USB", + "misprogrammed", + "modem", + "Modem", + "Modem/Networkcard", + "Module", + "Multimode", + "Multithreaded", + "Name:", + "net", + "network", + "Network", + "n/g/b", + "NIC", + "Notebook", + "OEM", + "PCI", + "PCI64", + "PCIe", + "PCI-E", + "PCI-Express", + "PCI-X", + "PCMCIA", + "PDA", + "PnP", + "RDMA", + "RJ-45", + "Series", + "Server", + "SoC", + "Switch", + "Technologies", + "TOE", + "USB", + "USB2.0", + "USB/Ethernet", + "UTP", + "UTP/Coax", + "v1", + "v1.1", + "v2", + "V2.0", + "v3", + "v4", + "wifi", + "Wi-Fi", + "WiFi", + "wireless", + "Wireless", + "Wireless-150N", + "Wireless-300N", + "Wireless-G", + "Wireless-N", + "WLAN", + NULL, + }; + char *desc_full; + char *p; + + desc_full = _fixup_string(desc, IGNORED_PHRASES, IGNORED_WORDS, FALSE); + if (!desc_full) + return NULL; + + /* Chop off everything after a '-'. */ + for (p = desc_full; *p; p++) { + if (p[0] == ' ' && p[1] == '-' && p[2] == ' ') { + p[0] = '\0'; + break; + } + } + + nm_assert(g_utf8_validate(desc_full, -1, NULL)); + + return desc_full; +} + +/*****************************************************************************/ + +const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[] = { + &_nml_dbus_meta_iface_nm, + &_nml_dbus_meta_iface_nm_accesspoint, + &_nml_dbus_meta_iface_nm_agentmanager, + &_nml_dbus_meta_iface_nm_checkpoint, + &_nml_dbus_meta_iface_nm_connection_active, + &_nml_dbus_meta_iface_nm_dhcp4config, + &_nml_dbus_meta_iface_nm_dhcp6config, + &_nml_dbus_meta_iface_nm_device, + &_nml_dbus_meta_iface_nm_device_adsl, + &_nml_dbus_meta_iface_nm_device_bluetooth, + &_nml_dbus_meta_iface_nm_device_bond, + &_nml_dbus_meta_iface_nm_device_bridge, + &_nml_dbus_meta_iface_nm_device_dummy, + &_nml_dbus_meta_iface_nm_device_generic, + &_nml_dbus_meta_iface_nm_device_iptunnel, + &_nml_dbus_meta_iface_nm_device_infiniband, + &_nml_dbus_meta_iface_nm_device_lowpan, + &_nml_dbus_meta_iface_nm_device_macsec, + &_nml_dbus_meta_iface_nm_device_macvlan, + &_nml_dbus_meta_iface_nm_device_modem, + &_nml_dbus_meta_iface_nm_device_olpcmesh, + &_nml_dbus_meta_iface_nm_device_ovsbridge, + &_nml_dbus_meta_iface_nm_device_ovsinterface, + &_nml_dbus_meta_iface_nm_device_ovsport, + &_nml_dbus_meta_iface_nm_device_ppp, + &_nml_dbus_meta_iface_nm_device_statistics, + &_nml_dbus_meta_iface_nm_device_team, + &_nml_dbus_meta_iface_nm_device_tun, + &_nml_dbus_meta_iface_nm_device_veth, + &_nml_dbus_meta_iface_nm_device_vlan, + &_nml_dbus_meta_iface_nm_device_vrf, + &_nml_dbus_meta_iface_nm_device_vxlan, + &_nml_dbus_meta_iface_nm_device_wifip2p, + &_nml_dbus_meta_iface_nm_device_wireguard, + &_nml_dbus_meta_iface_nm_device_wired, + &_nml_dbus_meta_iface_nm_device_wireless, + &_nml_dbus_meta_iface_nm_device_wpan, + &_nml_dbus_meta_iface_nm_dnsmanager, + &_nml_dbus_meta_iface_nm_ip4config, + &_nml_dbus_meta_iface_nm_ip6config, + &_nml_dbus_meta_iface_nm_settings, + &_nml_dbus_meta_iface_nm_settings_connection, + &_nml_dbus_meta_iface_nm_vpn_connection, + &_nml_dbus_meta_iface_nm_wifip2ppeer, +}; + +#define COMMON_PREFIX "org.freedesktop.NetworkManager" + +static int +_strcmp_common_prefix(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const NMLDBusMetaIface *iface = a; + const char * dbus_iface_name = b; + + nm_assert(g_str_has_prefix(iface->dbus_iface_name, COMMON_PREFIX)); + + return strcmp(&iface->dbus_iface_name[NM_STRLEN(COMMON_PREFIX)], dbus_iface_name); +} + +const NMLDBusMetaIface * +nml_dbus_meta_iface_get(const char *dbus_iface_name) +{ + gssize idx; + + nm_assert(dbus_iface_name); + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMLDBusMetaIface, dbus_iface_name) == 0); + + /* we assume that NetworkManager only uses unique interface names. E.g. one + * interface name always has one particular meaning (and offers one set of + * properties, signals and methods). This is a convenient assumption, and + * we sure would never violate it when extending NM's D-Bus API. */ + + if (NM_STR_HAS_PREFIX(dbus_iface_name, COMMON_PREFIX)) { + /* optimize, that in fact all our interfaces have the same prefix. */ + idx = nm_utils_ptrarray_find_binary_search((gconstpointer *) _nml_dbus_meta_ifaces, + G_N_ELEMENTS(_nml_dbus_meta_ifaces), + &dbus_iface_name[NM_STRLEN(COMMON_PREFIX)], + _strcmp_common_prefix, + NULL); + } else + return NULL; + + if (idx < 0) + return NULL; + return _nml_dbus_meta_ifaces[idx]; +} + +const NMLDBusMetaProperty * +nml_dbus_meta_property_get(const NMLDBusMetaIface *meta_iface, + const char * dbus_property_name, + guint * out_idx) +{ + gssize idx; + + nm_assert(meta_iface); + nm_assert(dbus_property_name); + + idx = nm_utils_array_find_binary_search(meta_iface->dbus_properties, + sizeof(meta_iface->dbus_properties[0]), + meta_iface->n_dbus_properties, + &dbus_property_name, + nm_strcmp_p_with_data, + NULL); + if (idx < 0) { + NM_SET_OUT(out_idx, meta_iface->n_dbus_properties); + return NULL; + } + NM_SET_OUT(out_idx, idx); + return &meta_iface->dbus_properties[idx]; +} + +void +_nml_dbus_meta_class_init_with_properties_impl(GObjectClass * object_class, + const NMLDBusMetaIface *const *meta_ifaces) +{ + int i_iface; + + nm_assert(G_IS_OBJECT_CLASS(object_class)); + nm_assert(meta_ifaces); + nm_assert(meta_ifaces[0]); + + for (i_iface = 0; meta_ifaces[i_iface]; i_iface++) { + const NMLDBusMetaIface *meta_iface = meta_ifaces[i_iface]; + guint8 * reverse_idx; + guint8 i; + + nm_assert(g_type_is_a(meta_iface->get_type_fcn(), G_OBJECT_CLASS_TYPE(object_class))); + nm_assert(meta_iface->n_obj_properties > 0); + nm_assert(meta_iface->obj_properties); + nm_assert(meta_iface->obj_properties_reverse_idx[0] == 0); + nm_assert(meta_iface->obj_properties == meta_ifaces[0]->obj_properties); + + if (i_iface == 0) + g_object_class_install_properties(object_class, + meta_iface->n_obj_properties, + (GParamSpec **) meta_iface->obj_properties); + + reverse_idx = (guint8 *) meta_iface->obj_properties_reverse_idx; + + for (i = 0; i < meta_iface->n_obj_properties; i++) + reverse_idx[i] = 0xFFu; + for (i = 0; i < meta_iface->n_dbus_properties; i++) { + const NMLDBusMetaProperty *mpr = &meta_iface->dbus_properties[i]; + + if (mpr->obj_properties_idx != 0 && !mpr->obj_property_no_reverse_idx) { + nm_assert(mpr->obj_properties_idx < meta_iface->n_obj_properties); + nm_assert(reverse_idx[mpr->obj_properties_idx] == 0xFFu); + + reverse_idx[mpr->obj_properties_idx] = i; + } + } + } +} + +gboolean +nm_utils_g_param_spec_is_default(const GParamSpec *pspec) +{ + g_return_val_if_fail(pspec, FALSE); + + if (pspec->value_type == G_TYPE_BOOLEAN) + return ((((GParamSpecBoolean *) pspec)->default_value) == FALSE); + if (pspec->value_type == G_TYPE_UCHAR) + return ((((GParamSpecUChar *) pspec)->default_value) == 0u); + if (pspec->value_type == G_TYPE_INT) + return ((((GParamSpecInt *) pspec)->default_value) == 0); + if (pspec->value_type == G_TYPE_UINT) + return ((((GParamSpecUInt *) pspec)->default_value) == 0u); + if (pspec->value_type == G_TYPE_INT64) + return ((((GParamSpecInt64 *) pspec)->default_value) == 0); + if (pspec->value_type == G_TYPE_UINT64) + return ((((GParamSpecUInt64 *) pspec)->default_value) == 0u); + if (g_type_is_a(pspec->value_type, G_TYPE_ENUM)) + return ((((GParamSpecEnum *) pspec)->default_value) == 0); + if (g_type_is_a(pspec->value_type, G_TYPE_FLAGS)) + return ((((GParamSpecFlags *) pspec)->default_value) == 0u); + if (pspec->value_type == G_TYPE_STRING) + return ((((GParamSpecString *) pspec)->default_value) == NULL); + if (NM_IN_SET(pspec->value_type, + G_TYPE_BYTES, + G_TYPE_PTR_ARRAY, + G_TYPE_ARRAY, + G_TYPE_HASH_TABLE, + G_TYPE_STRV)) { + /* boxed types have NULL default. */ + g_return_val_if_fail(G_IS_PARAM_SPEC_BOXED(pspec), FALSE); + g_return_val_if_fail(G_TYPE_IS_BOXED(pspec->value_type), FALSE); + return TRUE; + } + if (g_type_is_a(pspec->value_type, NM_TYPE_OBJECT)) { + /* object types have NULL default. */ + g_return_val_if_fail(G_IS_PARAM_SPEC_OBJECT(pspec), FALSE); + g_return_val_if_fail(G_TYPE_IS_OBJECT(pspec->value_type), FALSE); + return TRUE; + } + + /* This function is only used for asserting/testing. It thus + * strictly asserts and only support argument types that we expect. */ + g_return_val_if_reached(FALSE); +} + +/*****************************************************************************/ + +/** + * nm_utils_print: + * @output_mode: if 1 it uses g_print(). If 2, it uses g_printerr(). + * If 0, it uses either g_print() or g_printerr(), depending + * on LIBNM_CLIENT_DEBUG (and the "stdout" flag). + * @msg: the message to print. The function does not append + * a trailing newline. + * + * The only purpose of this function is to give access to g_print() + * or g_printerr() from pygobject. libnm can do debug logging by + * setting LIBNM_CLIENT_DEBUG and uses thereby g_printerr() or + * g_print(). A plain "print()" function in python is not in sync + * with these functions (it implements additional buffering). By + * using nm_utils_print(), the same logging mechanisms can be used. + * + * Since: 1.30 + */ +void +nm_utils_print(int output_mode, const char *msg) +{ + gboolean use_stdout; + + g_return_if_fail(msg); + + if (output_mode == 0) { + nml_dbus_log_enabled_full(NML_DBUS_LOG_LEVEL_ANY, &use_stdout); + output_mode = use_stdout ? 1 : 2; + } + + if (output_mode == 1) + g_print("%s", msg); + else if (output_mode == 2) + g_printerr("%s", msg); + else + g_return_if_reached(); +} diff --git a/src/libnm-client-impl/nm-libnm-utils.h b/src/libnm-client-impl/nm-libnm-utils.h new file mode 100644 index 0000000..3fd3b67 --- /dev/null +++ b/src/libnm-client-impl/nm-libnm-utils.h @@ -0,0 +1,1030 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017, 2018 Red Hat, Inc. + */ + +#ifndef __NM_LIBNM_UTILS_H__ +#define __NM_LIBNM_UTILS_H__ + +#include "c-list/src/c-list.h" +#include "nm-device.h" +#include "libnm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-logging-fwd.h" +#include "nm-types.h" +#include "nm-object.h" +#include "nm-client.h" + +/*****************************************************************************/ + +char *nm_utils_fixup_vendor_string(const char *desc); +char *nm_utils_fixup_product_string(const char *desc); + +char *nm_utils_wincaps_to_dash(const char *caps); + +gboolean nm_utils_g_param_spec_is_default(const GParamSpec *pspec); + +/*****************************************************************************/ + +typedef enum { + _NML_DBUS_LOG_LEVEL_NONE = 0x00, + + _NML_DBUS_LOG_LEVEL_INITIALIZED = 0x01, + + _NML_DBUS_LOG_LEVEL_TRACE = 0x02, + + _NML_DBUS_LOG_LEVEL_DEBUG = 0x04, + + /* the difference between a warning and a critical is that it results in + * g_warning() vs. g_critical() messages. Note that we want to use "warnings" + * for unknown D-Bus API that could just result because we run against a + * newer NetworkManager version (such warnings are more graceful, because + * we want that libnm can be forward compatible against newer servers). + * Critical warnings should be emitted when NetworkManager exposes something + * on D-Bus that breaks the current expectations. Usually NetworkManager + * should not break API, hence such issues are more severe. */ + _NML_DBUS_LOG_LEVEL_WARN = 0x08, + _NML_DBUS_LOG_LEVEL_ERROR = 0x10, + + /* ANY is only relevant for nml_dbus_log_enabled() to check whether any of the + * options is on. */ + NML_DBUS_LOG_LEVEL_ANY = _NML_DBUS_LOG_LEVEL_INITIALIZED, + + NML_DBUS_LOG_LEVEL_TRACE = _NML_DBUS_LOG_LEVEL_TRACE, + NML_DBUS_LOG_LEVEL_DEBUG = _NML_DBUS_LOG_LEVEL_DEBUG | NML_DBUS_LOG_LEVEL_TRACE, + NML_DBUS_LOG_LEVEL_WARN = _NML_DBUS_LOG_LEVEL_WARN | NML_DBUS_LOG_LEVEL_DEBUG, + NML_DBUS_LOG_LEVEL_ERROR = _NML_DBUS_LOG_LEVEL_ERROR | NML_DBUS_LOG_LEVEL_WARN, + + NML_DBUS_LOG_STDOUT = 0x20, +} NMLDBusLogLevel; + +#undef _LOGL_TRACE +#undef _LOGL_DEBUG +#undef _LOGL_INFO +#undef _LOGL_WARN +#undef _LOGL_ERR + +#define _LOGL_TRACE NML_DBUS_LOG_LEVEL_TRACE +#define _LOGL_DEBUG NML_DBUS_LOG_LEVEL_DEBUG +#define _LOGL_INFO NML_DBUS_LOG_LEVEL_INFO +#define _LOGL_WARN NML_DBUS_LOG_LEVEL_WARN +#define _LOGL_ERR NML_DBUS_LOG_LEVEL_ERR + +extern volatile int _nml_dbus_log_level; + +int _nml_dbus_log_level_init(void); + +static inline gboolean +nml_dbus_log_enabled_full(NMLDBusLogLevel level, gboolean *out_use_stdout) +{ + int l; + + nm_assert(NM_IN_SET(level, + NML_DBUS_LOG_LEVEL_ANY, + _NML_DBUS_LOG_LEVEL_NONE, + NML_DBUS_LOG_LEVEL_TRACE, + NML_DBUS_LOG_LEVEL_DEBUG, + NML_DBUS_LOG_LEVEL_WARN, + NML_DBUS_LOG_LEVEL_ERROR)); + + l = g_atomic_int_get(&_nml_dbus_log_level); + if (G_UNLIKELY(l == 0)) + l = _nml_dbus_log_level_init(); + + nm_assert(l & _NML_DBUS_LOG_LEVEL_INITIALIZED); + NM_SET_OUT(out_use_stdout, NM_FLAGS_HAS(l, NML_DBUS_LOG_STDOUT)); + if (level == NML_DBUS_LOG_LEVEL_ANY) + return l != _NML_DBUS_LOG_LEVEL_INITIALIZED; + return !!(((NMLDBusLogLevel) l) & level); +} + +static inline gboolean +nml_dbus_log_enabled(NMLDBusLogLevel level) +{ + return nml_dbus_log_enabled_full(level, NULL); +} + +void _nml_dbus_log(NMLDBusLogLevel level, gboolean use_stdout, const char *fmt, ...) + _nm_printf(3, 4); + +#define NML_DBUS_LOG(level, ...) \ + G_STMT_START \ + { \ + gboolean _use_stdout; \ + \ + G_STATIC_ASSERT((level) == _NML_DBUS_LOG_LEVEL_NONE || (level) == NML_DBUS_LOG_LEVEL_TRACE \ + || (level) == NML_DBUS_LOG_LEVEL_DEBUG \ + || (level) == NML_DBUS_LOG_LEVEL_WARN \ + || (level) == NML_DBUS_LOG_LEVEL_ERROR); \ + \ + if (nml_dbus_log_enabled_full(level, &_use_stdout)) { \ + _nml_dbus_log((level), _use_stdout, __VA_ARGS__); \ + } \ + } \ + G_STMT_END + +#define NML_DBUS_LOG_T(...) NML_DBUS_LOG(NML_DBUS_LOG_LEVEL_TRACE, __VA_ARGS__) +#define NML_DBUS_LOG_D(...) NML_DBUS_LOG(NML_DBUS_LOG_LEVEL_DEBUG, __VA_ARGS__) +#define NML_DBUS_LOG_W(...) NML_DBUS_LOG(NML_DBUS_LOG_LEVEL_WARN, __VA_ARGS__) +#define NML_DBUS_LOG_E(...) NML_DBUS_LOG(NML_DBUS_LOG_LEVEL_ERROR, __VA_ARGS__) + +/* _NML_NMCLIENT_LOG_LEVEL_COERCE is only for printf debugging. You can disable client logging by + * mapping the requested log level to a different one (or disable it altogether). + * That's useful for example if you are interested in *other* trace logging messages from + * libnm and don't want to get flooded by NMClient's trace messages. */ +#define _NML_NMCLIENT_LOG_LEVEL_COERCE(level) \ + /* for example, change condition below to suppress messages from NMClient. */ \ + ((TRUE || ((level) != NML_DBUS_LOG_LEVEL_TRACE)) ? (level) : _NML_DBUS_LOG_LEVEL_NONE) + +#define NML_NMCLIENT_LOG(level, self, ...) \ + NML_DBUS_LOG(_NML_NMCLIENT_LOG_LEVEL_COERCE(level), \ + "nmclient[" NM_HASH_OBFUSCATE_PTR_FMT "]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + NM_HASH_OBFUSCATE_PTR(self) _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +#define NML_NMCLIENT_LOG_T(self, ...) NML_NMCLIENT_LOG(NML_DBUS_LOG_LEVEL_TRACE, self, __VA_ARGS__) +#define NML_NMCLIENT_LOG_D(self, ...) NML_NMCLIENT_LOG(NML_DBUS_LOG_LEVEL_DEBUG, self, __VA_ARGS__) +#define NML_NMCLIENT_LOG_W(self, ...) NML_NMCLIENT_LOG(NML_DBUS_LOG_LEVEL_WARN, self, __VA_ARGS__) +#define NML_NMCLIENT_LOG_E(self, ...) NML_NMCLIENT_LOG(NML_DBUS_LOG_LEVEL_ERROR, self, __VA_ARGS__) + +/*****************************************************************************/ + +static inline const char * +_nml_coerce_property_str_not_null(const char *str) +{ + return str ?: ""; +} + +static inline const char * +_nml_coerce_property_str_not_empty(const char *str) +{ + return str && str[0] ? str : NULL; +} + +static inline const char * +_nml_coerce_property_object_path(NMRefString *path) +{ + if (!path) + return NULL; + return nm_dbus_path_not_empty(path->str); +} + +static inline const char *const * +_nml_coerce_property_strv_not_null(char **strv) +{ + return ((const char *const *) strv) ?: NM_PTRARRAY_EMPTY(const char *); +} + +/*****************************************************************************/ + +GQuark nm_context_busy_watcher_quark(void); + +void nm_context_busy_watcher_integrate_source(GMainContext *outer_context, + GMainContext *inner_context, + GObject * context_busy_watcher); + +/*****************************************************************************/ + +typedef struct { + GCancellable *cancellable; + GSource * cancel_on_idle_source; + gulong cancelled_id; + union { + struct { + GTask *task; + } async; + struct { + GMainLoop *main_loop; + GError ** error_location; + } sync; + } data; + bool is_sync : 1; +} NMLInitData; + +NMLInitData * +nml_init_data_new_sync(GCancellable *cancellable, GMainLoop *main_loop, GError **error_location); + +NMLInitData *nml_init_data_new_async(GCancellable *cancellable, GTask *task_take); + +void nml_init_data_return(NMLInitData *init_data, GError *error_take); + +void nml_cleanup_context_busy_watcher_on_idle(GObject * context_busy_watcher_take, + GMainContext *context); + +/*****************************************************************************/ + +typedef struct _NMLDBusObject NMLDBusObject; +typedef struct _NMLDBusObjWatcher NMLDBusObjWatcher; +typedef struct _NMLDBusMetaIface NMLDBusMetaIface; +typedef struct _NMLDBusPropertyO NMLDBusPropertyO; +typedef struct _NMLDBusPropertyAO NMLDBusPropertyAO; + +typedef enum { + /* See comments below for NMLDBusMetaIface.interface_prio. + * + * Higher numbers means more important to detect the GObject type. */ + NML_DBUS_META_INTERFACE_PRIO_NONE = 0, + NML_DBUS_META_INTERFACE_PRIO_NMCLIENT = 1, + NML_DBUS_META_INTERFACE_PRIO_PARENT_TYPE = 2, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_10 = 3, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_20 = 4, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30 = 5, +} NMLDBusMetaInteracePrio; + +/*****************************************************************************/ + +#define NM_CLIENT_INSTANCE_FLAGS_ALL ((NMClientInstanceFlags) 0x1) + +typedef struct { + GType (*get_o_type_fcn)(void); + + /* Ignore whether the referenced NMObject is ready or not. That means, + * the property is always ready (and if the pointed object itself is + * not yet ready, the property pretends to be %NULL for the moment. */ + bool is_always_ready : 1; + +} NMLDBusPropertVTableO; + +struct _NMLDBusPropertyO { + NMLDBusObject * owner_dbobj; + NMLDBusObjWatcher * obj_watcher; + GObject * nmobj; + const NMLDBusMetaIface *meta_iface; + guint dbus_property_idx; + bool is_ready : 1; + bool is_changed : 1; + bool block_is_changed : 1; +}; + +gpointer nml_dbus_property_o_get_obj(NMLDBusPropertyO *pr_o); + +gboolean nml_dbus_property_o_is_ready(const NMLDBusPropertyO *pr_o); + +gboolean nml_dbus_property_o_is_ready_fully(const NMLDBusPropertyO *pr_o); + +void nml_dbus_property_o_clear(NMLDBusPropertyO *pr_o, NMClient *client); + +void nml_dbus_property_o_clear_many(NMLDBusPropertyO *pr_o, guint len, NMClient *self); + +void nml_dbus_property_o_notify_changed_many(NMLDBusPropertyO *ptr, guint len, NMClient *self); + +/*****************************************************************************/ + +typedef struct { + GType (*get_o_type_fcn)(void); + + void (*notify_changed_ao)(NMLDBusPropertyAO *pr_ao, + NMClient * self, + NMObject * nmobj, + gboolean is_added /* or else removed */); + + gboolean (*check_nmobj_visible_fcn)(GObject *nmobj); + + /* Ignore whether the referenced NMObject is ready or not. That means, + * the property is always ready (and if the pointed object itself is + * not yet ready, the property pretends to be %NULL for the moment. */ + bool is_always_ready : 1; + +} NMLDBusPropertVTableAO; + +struct _NMLDBusPropertyAOData; + +struct _NMLDBusPropertyAO { + CList data_lst_head; + GHashTable * hash; + NMLDBusObject * owner_dbobj; + const NMLDBusMetaIface * meta_iface; + GPtrArray * arr; + struct _NMLDBusPropertyAOData *changed_head; + guint dbus_property_idx; + guint n_not_ready; + bool is_changed : 1; +}; + +const GPtrArray *nml_dbus_property_ao_get_objs_as_ptrarray(NMLDBusPropertyAO *pr_ao); + +gboolean nml_dbus_property_ao_is_ready(const NMLDBusPropertyAO *pr_ao); + +void nml_dbus_property_ao_clear(NMLDBusPropertyAO *pr_ao, NMClient *client); + +void nml_dbus_property_ao_clear_many(NMLDBusPropertyAO *pr_ao, guint len, NMClient *self); + +void nml_dbus_property_ao_notify_changed_many(NMLDBusPropertyAO *ptr, guint len, NMClient *self); + +/*****************************************************************************/ + +typedef enum { + NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE = 0, + NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY = 0x1, +} NMLDBusNotifyUpdatePropFlags; + +NMLDBusNotifyUpdatePropFlags _nml_dbus_notify_update_prop_ignore(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant *value); + +NMLDBusNotifyUpdatePropFlags _nml_dbus_notify_update_prop_o(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant *value); + +typedef struct { + const char * dbus_property_name; + const GVariantType *dbus_type; + + guint16 prop_struct_offset; + + guint8 obj_properties_idx; + + bool use_notify_update_prop : 1; + + bool obj_property_no_reverse_idx : 1; + + union { + union { + const NMLDBusPropertVTableO * property_vtable_o; + const NMLDBusPropertVTableAO *property_vtable_ao; + } extra; + + NMLDBusNotifyUpdatePropFlags (*notify_update_prop)(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant *value); + }; + +} NMLDBusMetaProperty; + +#define NML_DBUS_META_PROPERTY_INIT(v_dbus_property_name, v_dbus_type, v_obj_properties_idx, ...) \ + { \ + .dbus_property_name = "" v_dbus_property_name "", \ + .dbus_type = NM_G_VARIANT_TYPE("" v_dbus_type ""), \ + .obj_properties_idx = v_obj_properties_idx, ##__VA_ARGS__ \ + } + +#define _NML_DBUS_META_PROPERTY_INIT_DEFAULT(v_dbus_type, \ + v_exp_type, \ + v_dbus_property_name, \ + v_obj_properties_idx, \ + v_container, \ + v_field) \ + NML_DBUS_META_PROPERTY_INIT( \ + v_dbus_property_name, \ + v_dbus_type, \ + v_obj_properties_idx, \ + .prop_struct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(v_exp_type, v_container, v_field)) + +#define NML_DBUS_META_PROPERTY_INIT_B(...) \ + _NML_DBUS_META_PROPERTY_INIT_DEFAULT("b", bool, __VA_ARGS__) +#define NML_DBUS_META_PROPERTY_INIT_Y(...) \ + _NML_DBUS_META_PROPERTY_INIT_DEFAULT("y", guint8, __VA_ARGS__) +#define NML_DBUS_META_PROPERTY_INIT_Q(...) \ + _NML_DBUS_META_PROPERTY_INIT_DEFAULT("q", guint16, __VA_ARGS__) +#define NML_DBUS_META_PROPERTY_INIT_I(...) \ + _NML_DBUS_META_PROPERTY_INIT_DEFAULT("i", gint32, __VA_ARGS__) +#define NML_DBUS_META_PROPERTY_INIT_U(...) \ + _NML_DBUS_META_PROPERTY_INIT_DEFAULT("u", guint32, __VA_ARGS__) +#define NML_DBUS_META_PROPERTY_INIT_X(...) \ + _NML_DBUS_META_PROPERTY_INIT_DEFAULT("x", gint64, __VA_ARGS__) +#define NML_DBUS_META_PROPERTY_INIT_T(...) \ + _NML_DBUS_META_PROPERTY_INIT_DEFAULT("t", guint64, __VA_ARGS__) +#define NML_DBUS_META_PROPERTY_INIT_S(...) \ + _NML_DBUS_META_PROPERTY_INIT_DEFAULT("s", char *, __VA_ARGS__) +#define NML_DBUS_META_PROPERTY_INIT_AS(...) \ + _NML_DBUS_META_PROPERTY_INIT_DEFAULT("as", char **, __VA_ARGS__) +#define NML_DBUS_META_PROPERTY_INIT_AY(...) \ + _NML_DBUS_META_PROPERTY_INIT_DEFAULT("ay", GBytes *, __VA_ARGS__) + +#define NML_DBUS_META_PROPERTY_INIT_O(v_dbus_property_name, \ + v_obj_properties_idx, \ + v_container, \ + v_field) \ + NML_DBUS_META_PROPERTY_INIT( \ + v_dbus_property_name, \ + "o", \ + v_obj_properties_idx, \ + .prop_struct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(NMRefString *, v_container, v_field), \ + .use_notify_update_prop = TRUE, \ + .notify_update_prop = _nml_dbus_notify_update_prop_o) + +#define NML_DBUS_META_PROPERTY_INIT_O_PROP(v_dbus_property_name, \ + v_obj_properties_idx, \ + v_container, \ + v_field, \ + v_get_o_type_fcn, \ + ...) \ + NML_DBUS_META_PROPERTY_INIT( \ + v_dbus_property_name, \ + "o", \ + v_obj_properties_idx, \ + .prop_struct_offset = \ + NM_STRUCT_OFFSET_ENSURE_TYPE(NMLDBusPropertyO, v_container, v_field), \ + .extra.property_vtable_o = \ + &((const NMLDBusPropertVTableO){.get_o_type_fcn = (v_get_o_type_fcn), ##__VA_ARGS__})) + +#define NML_DBUS_META_PROPERTY_INIT_AO_PROP(v_dbus_property_name, \ + v_obj_properties_idx, \ + v_container, \ + v_field, \ + v_get_o_type_fcn, \ + ...) \ + NML_DBUS_META_PROPERTY_INIT( \ + v_dbus_property_name, \ + "ao", \ + v_obj_properties_idx, \ + .prop_struct_offset = \ + NM_STRUCT_OFFSET_ENSURE_TYPE(NMLDBusPropertyAO, v_container, v_field), \ + .extra.property_vtable_ao = &( \ + (const NMLDBusPropertVTableAO){.get_o_type_fcn = (v_get_o_type_fcn), ##__VA_ARGS__})) + +#define NML_DBUS_META_PROPERTY_INIT_FCN(v_dbus_property_name, \ + v_obj_properties_idx, \ + v_dbus_type, \ + v_notify_update_prop, \ + ...) \ + NML_DBUS_META_PROPERTY_INIT(v_dbus_property_name, \ + v_dbus_type, \ + v_obj_properties_idx, \ + .use_notify_update_prop = TRUE, \ + .notify_update_prop = (v_notify_update_prop), \ + ##__VA_ARGS__) + +#define NML_DBUS_META_PROPERTY_INIT_IGNORE(v_dbus_property_name, v_dbus_type) \ + NML_DBUS_META_PROPERTY_INIT(v_dbus_property_name, \ + v_dbus_type, \ + 0, \ + .use_notify_update_prop = TRUE, \ + .notify_update_prop = _nml_dbus_notify_update_prop_ignore) + +/* "TODO" is like "IGNORE". The difference is that we don't plan to ever implement "IGNORE", but + * "TODO" is something we should add support for. */ +#define NML_DBUS_META_PROPERTY_INIT_TODO(...) NML_DBUS_META_PROPERTY_INIT_IGNORE(__VA_ARGS__) + +struct _NMLDBusMetaIface { + const char *dbus_iface_name; + GType (*get_type_fcn)(void); + + /* Usually there is a one-to-one correspondence between the properties + * on D-Bus (dbus_properties) and the GObject properties (obj_properties). + * + * With: + * meta_iface->obj_properties[o_idx] (o_idx < n_obj_properties) + * &meta_iface->dbus_properties[d_idx] (d_idx < n_dbus_properties) + * it follows that + * assert (meta_iface->obj_properties_reverse_idx[o_idx] == d_idx) + * assert (meta_iface->dbus_properties[d_idx].obj_properties_idx == o_idx) + * if (and only if) two properties correspond. + */ + const GParamSpec *const * obj_properties; + const NMLDBusMetaProperty *dbus_properties; + const guint8 * obj_properties_reverse_idx; + + guint8 n_dbus_properties; + guint8 n_obj_properties; + + /* The offsets "prop_struct_offset" in NMLDBusMetaProperty are based on some base + * struct. If "base_struct_offset" is 0, then the base struct is the GObject pointer + * itself. + * If this is non-null, then we expect at that location a pointer to the offset. + * In this case we need to first find the base pointer via + * *((gpointer *) ((char *) nmobj + meta_iface->base_struct_offset)). + * + * This covers NMDeviceBridge._priv vs. NMDevice._priv. In the second case, + * _priv is a pointer that we first need to follow. + */ + guint8 base_struct_offset; + + /* We create the appropriate NMObject GType based on the D-Bus interfaces that + * are present. For example, if we see a "org.freedesktop.NetworkManager.Device.Bridge" + * interface, we create a NMDeviceBridge. Basically, if it looks like a certain + * object (based on the D-Bus interface), we assume it is. + * + * Some interfaces are purely additional ("org.freedesktop.NetworkManager.Device.Statistics") + * and don't determine the NMObject type (%NML_DBUS_META_INTERFACE_PRIO_NONE). + * + * Some interfaces are of a parent type ("org.freedesktop.NetworkManager.Device" for + * NMDevice), and don't determine the type either (%NML_DBUS_META_INTERFACE_PRIO_PARENT_TYPE). + * + * Some interfaces ("org.freedesktop.NetworkManager.AgentManager") belong to NMClient + * itself. Those have priority %NML_DBUS_META_INTERFACE_PRIO_NMCLIENT. + * + * In most cases, each D-Bus object is expected to have only one D-Bus interface + * to determine the type. While theoretically an object + * "/org/freedesktop/NetworkManager/Devices/3" could have interfaces "org.freedesktop.NetworkManager.Device.Bridge" + * and "org.freedesktop.NetworkManager.Device.Bond" at the same time, in practice it doesn't. + * Note that we also assume that once a D-Bus object gets a NMObject, it cannot change (*). + * NetworkManager's API does not add/remove interfaces after exporting the object the + * first time, so in practice each D-Bus object is expected to have a suitable D-Bus + * interface (and only determining interface, which doesn't change). Those interfaces have + * priority %NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30. + * + * (*) note that nothing bad would happen if a faulty NetworkManager would violate that. + * Of course, something would not work correctly, but the D-Bus interface we find is unexpected + * and wrong. + * + * One exception is "org.freedesktop.NetworkManager.Connection.Active". This can either + * be a NMActiveConnection or a NMVpnConnection. Hence, this profile has priority + * %NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_10, and depending on whether there is + * a "org.freedesktop.NetworkManager.VPN.Connection" (with high priority), we create + * one or the other type. + * + * Another exception is "org.freedesktop.NetworkManager.Device.Veth". It is a NMDeviceVeth + * and the parent is NMDeviceEthernet. Therefore it contains "org.freedesktop.NetworkManager.Device.Wired" + * as it should be registered as NMDeviceVeth, the profile has priority + * %NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_20. + * + */ + NMLDBusMetaInteracePrio interface_prio : 3; +}; + +#define NML_DBUS_META_IFACE_OBJ_PROPERTIES() \ + .obj_properties = (const GParamSpec *const *) (obj_properties), \ + .n_obj_properties = _PROPERTY_ENUMS_LAST, \ + .obj_properties_reverse_idx = ((guint8[_PROPERTY_ENUMS_LAST]){}) + +#define NML_DBUS_META_IFACE_DBUS_PROPERTIES(...) \ + .dbus_properties = ((const NMLDBusMetaProperty[]){__VA_ARGS__}), \ + .n_dbus_properties = \ + (sizeof((const NMLDBusMetaProperty[]){__VA_ARGS__}) / sizeof(NMLDBusMetaProperty)) + +#define NML_DBUS_META_IFACE_INIT(v_dbus_iface_name, v_get_type_fcn, v_interface_prio, ...) \ + { \ + .dbus_iface_name = "" v_dbus_iface_name "", .get_type_fcn = v_get_type_fcn, \ + .interface_prio = v_interface_prio, ##__VA_ARGS__ \ + } + +#define NML_DBUS_META_IFACE_INIT_PROP(v_dbus_iface_name, v_get_type_fcn, v_interface_prio, ...) \ + NML_DBUS_META_IFACE_INIT(v_dbus_iface_name, \ + v_get_type_fcn, \ + v_interface_prio, \ + NML_DBUS_META_IFACE_OBJ_PROPERTIES(), \ + ##__VA_ARGS__) + +extern const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[44]; + +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_accesspoint; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_agentmanager; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_checkpoint; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_connection_active; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_adsl; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bluetooth; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bond; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bridge; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_dummy; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_generic; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_infiniband; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_iptunnel; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_lowpan; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_macsec; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_macvlan; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_modem; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_olpcmesh; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsbridge; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsinterface; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsport; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ppp; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_statistics; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_team; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_tun; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_veth; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vlan; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vrf; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vxlan; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wifip2p; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wired; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wireguard; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wireless; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wpan; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dhcp4config; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dhcp6config; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dnsmanager; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_ip4config; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_ip6config; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings_connection; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_vpn_connection; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_wifip2ppeer; + +const NMLDBusMetaIface *nml_dbus_meta_iface_get(const char *dbus_iface_name); + +const NMLDBusMetaProperty *nml_dbus_meta_property_get(const NMLDBusMetaIface *meta_iface, + const char * dbus_property_name, + guint * out_idx); + +void _nml_dbus_meta_class_init_with_properties_impl(GObjectClass * object_class, + const NMLDBusMetaIface *const *meta_iface); +#define _nml_dbus_meta_class_init_with_properties(object_class, ...) \ + _nml_dbus_meta_class_init_with_properties_impl( \ + (object_class), \ + ((const NMLDBusMetaIface *const[]){__VA_ARGS__, NULL})) + +/*****************************************************************************/ + +typedef enum { + NML_DBUS_OBJ_STATE_UNLINKED = 0, + NML_DBUS_OBJ_STATE_WATCHED_ONLY, + NML_DBUS_OBJ_STATE_ON_DBUS, + NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY, + NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY, +} NMLDBusObjState; + +typedef enum { + NML_DBUS_OBJ_CHANGED_TYPE_NONE = 0, + NML_DBUS_OBJ_CHANGED_TYPE_DBUS = (1LL << 0), + NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ = (1LL << 1), +} NMLDBusObjChangedType; + +struct _NMLDBusObject { + NMRefString *dbus_path; + + /* While the object is tracked by NMClient, it is linked with this list. + * The lists are partitioned based on the NMLDBusObjState. */ + CList dbus_objects_lst; + + /* The list of D-Bus interface NMLDBusObjIfaceData. + * + * Some may be about to be removed (iface_removed) or + * unknown (!dbus_iface_is_wellknown). */ + CList iface_lst_head; + + /* The list of registered NMLDBusObjWatcher. */ + CList watcher_lst_head; + + /* When an object changes (e.g. because of new information on D-Bus), we often + * don't process the changes right away, but enqueue the object in a changed + * list. This list goes together with obj_changed_type property below, which + * tracks what changed. */ + CList obj_changed_lst; + + GObject *nmobj; + + int ref_count; + + NMLDBusObjState obj_state : 4; + + NMLDBusObjChangedType obj_changed_type : 3; +}; + +static inline gboolean +NML_IS_DBUS_OBJECT(NMLDBusObject *dbobj) +{ + nm_assert(!dbobj || (NM_IS_REF_STRING(dbobj->dbus_path) && dbobj->ref_count > 0)); + nm_assert(!dbobj || !dbobj->nmobj || NM_IS_OBJECT(dbobj->nmobj) || NM_IS_CLIENT(dbobj->nmobj)); + return !!dbobj; +} + +NMLDBusObject *nml_dbus_object_ref(NMLDBusObject *dbobj); + +void nml_dbus_object_unref(NMLDBusObject *dbobj); + +NM_AUTO_DEFINE_FCN0(NMLDBusObject *, _nm_auto_unref_nml_dbusobj, nml_dbus_object_unref); +#define nm_auto_unref_nml_dbusobj nm_auto(_nm_auto_unref_nml_dbusobj) + +gpointer nml_dbus_object_get_property_location(NMLDBusObject * dbobj, + const NMLDBusMetaIface * meta_iface, + const NMLDBusMetaProperty *meta_property); + +/*****************************************************************************/ + +/* NMClient is not an NMObject, but in some aspects we want to track it like + * an NMObject. For that, both NMClient and NMObject "implement" NMObjectBase, + * despite not actually implementing such a GObject type. */ +typedef struct { + GObject parent; + CList queue_notify_lst; + bool is_disposing : 1; +} NMObjectBase; + +typedef struct { + GObjectClass parent; +} NMObjectBaseClass; + +struct _NMObjectPrivate; + +struct _NMObject { + union { + GObject parent; + NMObjectBase obj_base; + }; + struct _NMObjectPrivate *_priv; +}; + +typedef struct _NMObjectClassFieldInfo { + const struct _NMObjectClassFieldInfo *parent; + NMObjectClass * klass; + guint16 offset; + guint16 num; +} _NMObjectClassFieldInfo; + +struct _NMObjectClass { + union { + GObjectClass parent; + NMObjectBaseClass obj_base; + }; + + void (*register_client)(NMObject *self, NMClient *client, NMLDBusObject *dbobj); + + void (*unregister_client)(NMObject *self, NMClient *client, NMLDBusObject *dbobj); + + gboolean (*is_ready)(NMObject *self); + + void (*obj_changed_notify)(NMObject *self); + + const _NMObjectClassFieldInfo *property_o_info; + const _NMObjectClassFieldInfo *property_ao_info; + + guint16 priv_ptr_offset; + + bool priv_ptr_indirect : 1; +}; + +#define _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, type_name) \ + G_STMT_START \ + { \ + (nm_object_class)->priv_ptr_offset = \ + NM_STRUCT_OFFSET_ENSURE_TYPE(type_name##Private, type_name, _priv); \ + (nm_object_class)->priv_ptr_indirect = FALSE; \ + } \ + G_STMT_END + +#define _NM_OBJECT_CLASS_INIT_PRIV_PTR_INDIRECT(nm_object_class, type_name) \ + G_STMT_START \ + { \ + (nm_object_class)->priv_ptr_offset = \ + NM_STRUCT_OFFSET_ENSURE_TYPE(type_name##Private *, type_name, _priv); \ + (nm_object_class)->priv_ptr_indirect = TRUE; \ + } \ + G_STMT_END + +#define _NM_OBJECT_CLASS_INIT_FIELD_INFO(_nm_object_class, _field_name, _offset, _num) \ + G_STMT_START \ + { \ + (_nm_object_class)->_field_name = ({ \ + static _NMObjectClassFieldInfo _f; \ + \ + _f = (_NMObjectClassFieldInfo){ \ + .parent = (_nm_object_class)->_field_name, \ + .klass = (_nm_object_class), \ + .offset = _offset, \ + .num = _num, \ + }; \ + &_f; \ + }); \ + } \ + G_STMT_END + +#define _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, type_name, field_name) \ + _NM_OBJECT_CLASS_INIT_FIELD_INFO( \ + nm_object_class, \ + property_o_info, \ + NM_STRUCT_OFFSET_ENSURE_TYPE(NMLDBusPropertyO, type_name, field_name), \ + 1) + +#define _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_N(nm_object_class, type_name, field_name) \ + _NM_OBJECT_CLASS_INIT_FIELD_INFO( \ + nm_object_class, \ + property_o_info, \ + NM_STRUCT_OFFSET_ENSURE_TYPE(NMLDBusPropertyO *, type_name, field_name), \ + G_N_ELEMENTS(((type_name *) NULL)->field_name)) + +#define _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, type_name, field_name) \ + _NM_OBJECT_CLASS_INIT_FIELD_INFO( \ + nm_object_class, \ + property_ao_info, \ + NM_STRUCT_OFFSET_ENSURE_TYPE(NMLDBusPropertyAO, type_name, field_name), \ + 1) + +#define _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_N(nm_object_class, type_name, field_name) \ + _NM_OBJECT_CLASS_INIT_FIELD_INFO( \ + nm_object_class, \ + property_ao_info, \ + NM_STRUCT_OFFSET_ENSURE_TYPE(NMLDBusPropertyAO *, type_name, field_name), \ + G_N_ELEMENTS(((type_name *) NULL)->field_name)) + +/*****************************************************************************/ + +struct _NMDevicePrivate; + +struct _NMDevice { + NMObject parent; + struct _NMDevicePrivate *_priv; +}; + +struct _NMDeviceClass { + struct _NMObjectClass parent; + + gboolean (*connection_compatible)(NMDevice *device, NMConnection *connection, GError **error); + + const char *(*get_type_description)(NMDevice *device); + + GType (*get_setting_type)(NMDevice *device); +}; + +/*****************************************************************************/ + +struct _NMDeviceEthernetPrivate; + +struct _NMDeviceEthernet { + NMDevice parent; + struct _NMDeviceEthernetPrivate *_priv; +}; + +struct _NMDeviceEthernetClass { + NMDeviceClass parent; +}; + +/*****************************************************************************/ + +struct _NMActiveConnectionPrivate; + +struct _NMActiveConnection { + NMObject parent; + struct _NMActiveConnectionPrivate *_priv; +}; + +struct _NMActiveConnectionClass { + struct _NMObjectClass parent; +}; + +/*****************************************************************************/ + +struct _NMDhcpConfigPrivate; + +struct _NMDhcpConfig { + NMObject parent; + struct _NMDhcpConfigPrivate *_priv; +}; + +struct _NMDhcpConfigClass { + struct _NMObjectClass parent; +}; + +/*****************************************************************************/ + +struct _NMIPConfigPrivate; + +struct _NMIPConfig { + NMObject parent; + struct _NMIPConfigPrivate *_priv; +}; + +struct _NMIPConfigClass { + struct _NMObjectClass parent; +}; + +/*****************************************************************************/ + +NMLDBusObject *_nm_object_get_dbobj(gpointer self); + +const char *_nm_object_get_path(gpointer self); + +NMClient *_nm_object_get_client(gpointer self); + +GDBusConnection *_nm_client_get_dbus_connection(NMClient *client); + +const char *_nm_client_get_dbus_name_owner(NMClient *client); + +GMainContext *_nm_client_get_context_main(NMClient *client); +GMainContext *_nm_client_get_context_dbus(NMClient *client); + +void _nm_client_queue_notify_object(NMClient *client, gpointer nmobj, const GParamSpec *pspec); + +void _nm_client_notify_object_changed(NMClient *self, NMLDBusObject *dbobj); + +struct udev *_nm_client_get_udev(NMClient *self); + +/*****************************************************************************/ + +#define NM_CLIENT_NOTIFY_EVENT_PRIO_BEFORE (-100) +#define NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP 0 +#define NM_CLIENT_NOTIFY_EVENT_PRIO_AFTER 100 + +typedef struct _NMClientNotifyEvent NMClientNotifyEvent; + +typedef void (*NMClientNotifyEventCb)(NMClient *self, gpointer notify_event); + +struct _NMClientNotifyEvent { + CList lst; + NMClientNotifyEventCb callback; + int priority; +}; + +gpointer _nm_client_notify_event_queue(NMClient * self, + int priority, + NMClientNotifyEventCb callback, + gsize event_size); + +typedef struct _NMClientNotifyEventWithPtr NMClientNotifyEventWithPtr; + +typedef void (*NMClientNotifyEventWithPtrCb)(NMClient * self, + NMClientNotifyEventWithPtr *notify_event); + +struct _NMClientNotifyEventWithPtr { + NMClientNotifyEvent parent; + gpointer user_data; +}; + +NMClientNotifyEventWithPtr * +_nm_client_notify_event_queue_with_ptr(NMClient * self, + int priority, + NMClientNotifyEventWithPtrCb callback, + gpointer user_data); + +void _nm_client_notify_event_queue_emit_obj_signal(NMClient *self, + GObject * source, + NMObject *nmobj, + gboolean is_added /* or else removed */, + int prio_offset, + guint signal_id); + +/*****************************************************************************/ + +GError *_nm_client_new_error_nm_not_running(void); +GError *_nm_client_new_error_nm_not_cached(void); + +void _nm_client_dbus_call_simple(NMClient * self, + GCancellable * cancellable, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + GAsyncReadyCallback callback, + gpointer user_data); + +void _nm_client_dbus_call(NMClient * self, + gpointer source_obj, + gpointer source_tag, + GCancellable * cancellable, + GAsyncReadyCallback user_callback, + gpointer user_callback_data, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + GAsyncReadyCallback internal_callback); + +GVariant *_nm_client_dbus_call_sync(NMClient * self, + GCancellable * cancellable, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + gboolean strip_dbus_error, + GError ** error); + +gboolean _nm_client_dbus_call_sync_void(NMClient * self, + GCancellable * cancellable, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + GDBusCallFlags flags, + int timeout_msec, + gboolean strip_dbus_error, + GError ** error); + +void _nm_client_set_property_sync_legacy(NMClient * self, + const char *object_path, + const char *interface, + const char *prop_name, + const char *format_string, + ...); + +/*****************************************************************************/ + +void _nm_client_get_settings_call(NMClient *self, NMLDBusObject *dbobj); + +GCancellable *_nm_remote_settings_get_settings_prepare(NMRemoteConnection *self); + +void _nm_remote_settings_get_settings_commit(NMRemoteConnection *self, GVariant *settings); + +/*****************************************************************************/ + +void +_nm_active_connection_state_changed_commit(NMActiveConnection *self, guint32 state, guint32 reason); + +void _nm_vpn_connection_state_changed_commit(NMVpnConnection *self, guint32 state, guint32 reason); + +/*****************************************************************************/ + +NMLDBusNotifyUpdatePropFlags +_nm_device_notify_update_prop_hw_address(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value); + +/*****************************************************************************/ + +#endif /* __NM_LIBNM_UTILS_H__ */ diff --git a/src/libnm-client-impl/nm-object-private.h b/src/libnm-client-impl/nm-object-private.h new file mode 100644 index 0000000..9f78304 --- /dev/null +++ b/src/libnm-client-impl/nm-object-private.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#ifndef __NM_OBJECT_PRIVATE_H__ +#define __NM_OBJECT_PRIVATE_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE) + #error Cannot use this header. +#endif + +#include "nm-object.h" + +#endif /* __NM_OBJECT_PRIVATE_H__ */ diff --git a/src/libnm-client-impl/nm-object.c b/src/libnm-client-impl/nm-object.c new file mode 100644 index 0000000..2e7de8c --- /dev/null +++ b/src/libnm-client-impl/nm-object.c @@ -0,0 +1,311 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-object.h" + +#include +#include + +#include "nm-utils.h" +#include "nm-dbus-interface.h" +#include "nm-object-private.h" +#include "nm-dbus-helpers.h" +#include "nm-client.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "c-list/src/c-list.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PATH, ); + +typedef struct _NMObjectPrivate { + NMClient * client; + NMLDBusObject *dbobj; +} NMObjectPrivate; + +G_DEFINE_ABSTRACT_TYPE(NMObject, nm_object, G_TYPE_OBJECT); + +#define NM_OBJECT_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMObject, NM_IS_OBJECT) + +static NMObjectClass *_nm_object_class = NULL; + +/*****************************************************************************/ + +static gpointer +_nm_object_get_private(NMObjectClass *klass, NMObject *self, guint16 extra_offset) +{ + char *ptr; + + nm_assert(klass->priv_ptr_offset > 0); + + ptr = (char *) self; + ptr += klass->priv_ptr_offset; + if (klass->priv_ptr_indirect) + ptr = *((gpointer *) ptr); + return ptr + extra_offset; +} + +NMLDBusObject * +_nm_object_get_dbobj(gpointer self) +{ + return NM_OBJECT_GET_PRIVATE(self)->dbobj; +} + +const char * +_nm_object_get_path(gpointer self) +{ + return NM_OBJECT_GET_PRIVATE(self)->dbobj->dbus_path->str; +} + +NMClient * +_nm_object_get_client(gpointer self) +{ + return NM_OBJECT_GET_PRIVATE(self)->client; +} + +/** + * nm_object_get_path: + * @object: a #NMObject + * + * Gets the DBus path of the #NMObject. + * + * Returns: the object's path. This is the internal string used by the + * object, and must not be modified. + * + * Note that the D-Bus path of an NMObject never changes, even + * if the instance gets removed from the cache. To find out + * whether the object is still alive/cached, check nm_object_get_client(). + **/ +const char * +nm_object_get_path(NMObject *object) +{ + g_return_val_if_fail(NM_IS_OBJECT(object), NULL); + + return _nm_object_get_path(object); +} + +/** + * nm_object_get_client: + * @object: a #NMObject + * + * Returns the #NMClient instance in which object is cached. + * Also, if the object got removed from the client cached, + * this returns %NULL. So it can be used to check whether the + * object is still alive. + * + * Returns: (transfer none): the #NMClient cache in which the + * object can be found, or %NULL if the object is no longer + * cached. + * + * Since: 1.24 + **/ +NMClient * +nm_object_get_client(NMObject *object) +{ + g_return_val_if_fail(NM_IS_OBJECT(object), NULL); + + return _nm_object_get_client(object); +} + +/*****************************************************************************/ + +static void +clear_properties(NMObject *self, NMClient *client) +{ + NMObjectClass * klass = NM_OBJECT_GET_CLASS(self); + const _NMObjectClassFieldInfo *p; + + nm_assert(NM_IS_OBJECT(self)); + nm_assert(!client || NM_IS_CLIENT(client)); + + for (p = klass->property_o_info; p; p = p->parent) { + nml_dbus_property_o_clear_many(_nm_object_get_private(p->klass, self, p->offset), + p->num, + client); + } + + for (p = klass->property_ao_info; p; p = p->parent) { + nml_dbus_property_ao_clear_many(_nm_object_get_private(p->klass, self, p->offset), + p->num, + client); + } +} + +/*****************************************************************************/ + +static gboolean +is_ready(NMObject *self) +{ + NMObjectClass * klass = NM_OBJECT_GET_CLASS(self); + NMClient * client = _nm_object_get_client(self); + const _NMObjectClassFieldInfo *p; + guint16 i; + + nm_assert(NM_IS_CLIENT(client)); + + for (p = klass->property_o_info; p; p = p->parent) { + NMLDBusPropertyO *fields = _nm_object_get_private(p->klass, self, p->offset); + + for (i = 0; i < p->num; i++) { + if (!nml_dbus_property_o_is_ready(&fields[i])) + return FALSE; + } + } + + for (p = klass->property_ao_info; p; p = p->parent) { + NMLDBusPropertyAO *fields = _nm_object_get_private(p->klass, self, p->offset); + + for (i = 0; i < p->num; i++) { + if (!nml_dbus_property_ao_is_ready(&fields[i])) + return FALSE; + } + } + + return TRUE; +} + +static void +obj_changed_notify(NMObject *self) +{ + NMObjectClass * klass = NM_OBJECT_GET_CLASS(self); + NMClient * client = _nm_object_get_client(self); + const _NMObjectClassFieldInfo *p; + + nm_assert(NM_IS_CLIENT(client)); + + for (p = klass->property_o_info; p; p = p->parent) { + nml_dbus_property_o_notify_changed_many(_nm_object_get_private(p->klass, self, p->offset), + p->num, + client); + } + + for (p = klass->property_ao_info; p; p = p->parent) { + nml_dbus_property_ao_notify_changed_many(_nm_object_get_private(p->klass, self, p->offset), + p->num, + client); + } +} + +/*****************************************************************************/ + +static void +register_client(NMObject *self, NMClient *client, NMLDBusObject *dbobj) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE(self); + + nm_assert(!priv->client); + nm_assert(NML_IS_DBUS_OBJECT(dbobj)); + nm_assert(dbobj->nmobj == G_OBJECT(self)); + + priv->client = client; + priv->dbobj = nml_dbus_object_ref(dbobj); +} + +static void +unregister_client(NMObject *self, NMClient *client, NMLDBusObject *dbobj) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE(self); + + nm_assert(NM_IS_CLIENT(client)); + nm_assert(priv->client == client); + priv->client = NULL; + + clear_properties(self, client); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMObject *self = NM_OBJECT(object); + + switch (prop_id) { + case PROP_PATH: + g_value_set_string(value, nm_object_get_path(self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_object_init(NMObject *object) +{ + NMObject * self = NM_OBJECT(object); + NMObjectPrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_OBJECT, NMObjectPrivate); + + self->_priv = priv; + + c_list_init(&self->obj_base.queue_notify_lst); + + NML_DBUS_LOG(_NML_NMCLIENT_LOG_LEVEL_COERCE(NML_DBUS_LOG_LEVEL_TRACE), + "nmobj[" NM_HASH_OBFUSCATE_PTR_FMT "]: creating", + NM_HASH_OBFUSCATE_PTR(self)); +} + +static void +dispose(GObject *object) +{ + NMObject * self = NM_OBJECT(object); + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE(self); + + if (!self->obj_base.is_disposing) { + NML_DBUS_LOG(_NML_NMCLIENT_LOG_LEVEL_COERCE(NML_DBUS_LOG_LEVEL_TRACE), + "nmobj[" NM_HASH_OBFUSCATE_PTR_FMT "]: disposing", + NM_HASH_OBFUSCATE_PTR(self)); + } + + self->obj_base.is_disposing = TRUE; + + nm_assert(c_list_is_empty(&self->obj_base.queue_notify_lst)); + nm_assert(!priv->client); + nm_assert(!priv->dbobj || !priv->dbobj->nmobj); + + clear_properties(self, NULL); + + G_OBJECT_CLASS(nm_object_parent_class)->dispose(object); + + nm_clear_pointer(&priv->dbobj, nml_dbus_object_unref); +} + +static void +nm_object_class_init(NMObjectClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + _nm_object_class = klass; + + g_type_class_add_private(klass, sizeof(NMObjectPrivate)); + + object_class->get_property = get_property; + object_class->dispose = dispose; + + klass->register_client = register_client; + klass->unregister_client = unregister_client; + klass->is_ready = is_ready; + klass->obj_changed_notify = obj_changed_notify; + + /** + * NMObject:path: + * + * The D-Bus object path. + **/ + obj_properties[PROP_PATH] = g_param_spec_string(NM_OBJECT_PATH, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} diff --git a/src/libnm-client-impl/nm-property-infos-dbus.xml b/src/libnm-client-impl/nm-property-infos-dbus.xml new file mode 100644 index 0000000..7100140 --- /dev/null +++ b/src/libnm-client-impl/nm-property-infos-dbus.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml b/src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml new file mode 100644 index 0000000..baa892b --- /dev/null +++ b/src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libnm-client-impl/nm-property-infos-keyfile.xml b/src/libnm-client-impl/nm-property-infos-keyfile.xml new file mode 100644 index 0000000..0445d94 --- /dev/null +++ b/src/libnm-client-impl/nm-property-infos-keyfile.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libnm-client-impl/nm-property-infos-nmcli.xml b/src/libnm-client-impl/nm-property-infos-nmcli.xml new file mode 100644 index 0000000..604cb5a --- /dev/null +++ b/src/libnm-client-impl/nm-property-infos-nmcli.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libnm-client-impl/nm-remote-connection-private.h b/src/libnm-client-impl/nm-remote-connection-private.h new file mode 100644 index 0000000..3ca934b --- /dev/null +++ b/src/libnm-client-impl/nm-remote-connection-private.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2009 Red Hat, Inc. + */ + +#ifndef __NM_REMOTE_CONNECTION_PRIVATE_H__ +#define __NM_REMOTE_CONNECTION_PRIVATE_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE) + #error Cannot use this header. +#endif + +#define NM_REMOTE_CONNECTION_INIT_RESULT "init-result" + +typedef enum { + NM_REMOTE_CONNECTION_INIT_RESULT_UNKNOWN = 0, + NM_REMOTE_CONNECTION_INIT_RESULT_SUCCESS, + NM_REMOTE_CONNECTION_INIT_RESULT_ERROR, + NM_REMOTE_CONNECTION_INIT_RESULT_INVISIBLE, +} NMRemoteConnectionInitResult; + +#endif /* __NM_REMOTE_CONNECTION_PRIVATE__ */ diff --git a/src/libnm-client-impl/nm-remote-connection.c b/src/libnm-client-impl/nm-remote-connection.c new file mode 100644 index 0000000..007da3a --- /dev/null +++ b/src/libnm-client-impl/nm-remote-connection.c @@ -0,0 +1,839 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-remote-connection.h" + +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "nm-dbus-interface.h" +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-remote-connection-private.h" +#include "nm-object-private.h" +#include "nm-dbus-helpers.h" + +/** + * SECTION:nm-remote-connection + * @short_description: A connection managed by NetworkManager server + * + * A #NMRemoteConnection represents a connection that is exported via + * NetworkManager D-Bus interface. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMRemoteConnection, + PROP_UNSAVED, + PROP_FLAGS, + PROP_FILENAME, + PROP_VISIBLE, ); + +typedef struct { + GCancellable *get_settings_cancellable; + + char * filename; + guint32 flags; + bool unsaved; + + bool visible : 1; + bool is_initialized : 1; +} NMRemoteConnectionPrivate; + +struct _NMRemoteConnection { + NMObject parent; + NMRemoteConnectionPrivate _priv; +}; + +struct _NMRemoteConnectionClass { + NMObjectClass parent_class; +}; + +static void nm_remote_connection_connection_iface_init(NMConnectionInterface *iface); + +G_DEFINE_TYPE_WITH_CODE(NMRemoteConnection, + nm_remote_connection, + NM_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(NM_TYPE_CONNECTION, + nm_remote_connection_connection_iface_init);) + +#define NM_REMOTE_CONNECTION_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMRemoteConnection, NM_IS_REMOTE_CONNECTION, NMObject) + +/*****************************************************************************/ + +/** + * nm_remote_connection_update2: + * @connection: the #NMRemoteConnection + * @settings: (allow-none): optional connection to update the settings. + * @flags: update-flags + * @args: (allow-none): optional arguments. + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the commit operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously calls the Update2() D-Bus method. + * + * Since: 1.12 + **/ +void +nm_remote_connection_update2(NMRemoteConnection * connection, + GVariant * settings, + NMSettingsUpdate2Flags flags, + GVariant * args, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_REMOTE_CONNECTION(connection)); + g_return_if_fail(!settings || g_variant_is_of_type(settings, NM_VARIANT_TYPE_CONNECTION)); + g_return_if_fail(!args || g_variant_is_of_type(args, G_VARIANT_TYPE("a{sv}"))); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + if (!settings) + settings = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + if (!args) + args = g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0); + + _nm_client_dbus_call(_nm_object_get_client(connection), + connection, + nm_remote_connection_update2, + cancellable, + callback, + user_data, + _nm_object_get_path(connection), + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + "Update2", + g_variant_new("(@a{sa{sv}}u@a{sv})", settings, (guint32) flags, args), + G_VARIANT_TYPE("(a{sv})"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_variant_strip_dbus_error_cb); +} + +/** + * nm_remote_connection_update2_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_commit_changes_async(). + * + * Returns: (transfer full): on success, a #GVariant of type "a{sv}" with the result. On failure, + * %NULL. + **/ +GVariant * +nm_remote_connection_update2_finish(NMRemoteConnection *connection, + GAsyncResult * result, + GError ** error) +{ + gs_unref_variant GVariant *ret = NULL; + GVariant * v_result; + + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), NULL); + g_return_val_if_fail(nm_g_task_is_valid(result, connection, nm_remote_connection_update2), + NULL); + + ret = g_task_propagate_pointer(G_TASK(result), error); + if (!ret) + return NULL; + + g_variant_get(ret, "(@a{sv})", &v_result); + + return v_result; +} + +/*****************************************************************************/ + +/** + * nm_remote_connection_commit_changes: + * @connection: the #NMRemoteConnection + * @save_to_disk: whether to persist the changes to disk + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Send any local changes to the settings and properties of @connection to + * NetworkManager. If @save_to_disk is %TRUE, the updated connection will be saved to + * disk; if %FALSE, then only the in-memory representation will be changed. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + * + * Deprecated: 1.22: Use nm_remote_connection_commit_changes_async() or GDBusConnection. + **/ +gboolean +nm_remote_connection_commit_changes(NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable * cancellable, + GError ** error) +{ + gs_unref_variant GVariant *ret = NULL; + + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE); + + ret = _nm_client_dbus_call_sync( + _nm_object_get_client(connection), + cancellable, + _nm_object_get_path(connection), + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + "Update2", + g_variant_new("(@a{sa{sv}}u@a{sv})", + nm_connection_to_dbus(NM_CONNECTION(connection), NM_CONNECTION_SERIALIZE_ALL), + (guint32)(save_to_disk ? NM_SETTINGS_UPDATE2_FLAG_TO_DISK + : NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY), + g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0)), + G_VARIANT_TYPE("(a{sv})"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); + if (!ret) + return FALSE; + + return TRUE; +} + +/** + * nm_remote_connection_commit_changes_async: + * @connection: the #NMRemoteConnection + * @save_to_disk: whether to save the changes to persistent storage + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the commit operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously sends any local changes to the settings and properties of + * @connection to NetworkManager. If @save is %TRUE, the updated connection will + * be saved to disk; if %FALSE, then only the in-memory representation will be + * changed. + **/ +void +nm_remote_connection_commit_changes_async(NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_REMOTE_CONNECTION(connection)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + nm_remote_connection_update2( + connection, + nm_connection_to_dbus(NM_CONNECTION(connection), NM_CONNECTION_SERIALIZE_ALL), + save_to_disk ? NM_SETTINGS_UPDATE2_FLAG_TO_DISK : NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY, + NULL, + cancellable, + callback, + user_data); +} + +/** + * nm_remote_connection_commit_changes_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_commit_changes_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_commit_changes_finish(NMRemoteConnection *connection, + GAsyncResult * result, + GError ** error) +{ + gs_unref_variant GVariant *v_result = NULL; + + v_result = nm_remote_connection_update2_finish(connection, result, error); + return !!v_result; +} + +/*****************************************************************************/ + +/** + * nm_remote_connection_save: + * @connection: the #NMRemoteConnection + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Saves the connection to disk if the connection has changes that have not yet + * been written to disk, or if the connection has never been saved. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + * + * Deprecated: 1.22: Use nm_remote_connection_save_async() or GDBusConnection. + **/ +gboolean +nm_remote_connection_save(NMRemoteConnection *connection, GCancellable *cancellable, GError **error) +{ + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE); + + return _nm_client_dbus_call_sync_void(_nm_object_get_client(connection), + cancellable, + _nm_object_get_path(connection), + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + "Save", + g_variant_new("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); +} + +/** + * nm_remote_connection_save_async: + * @connection: the #NMRemoteConnection + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the save operation completes + * @user_data: caller-specific data passed to @callback + * + * Saves the connection to disk if the connection has changes that have not yet + * been written to disk, or if the connection has never been saved. + **/ +void +nm_remote_connection_save_async(NMRemoteConnection *connection, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_REMOTE_CONNECTION(connection)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(_nm_object_get_client(connection), + connection, + nm_remote_connection_save_async, + cancellable, + callback, + user_data, + _nm_object_get_path(connection), + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + "Save", + g_variant_new("()"), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_remote_connection_save_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_save_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_save_finish(NMRemoteConnection *connection, + GAsyncResult * result, + GError ** error) +{ + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, connection, nm_remote_connection_save_async), + FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/*****************************************************************************/ + +/** + * nm_remote_connection_delete: + * @connection: the #NMRemoteConnection + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Deletes the connection. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + * + * Deprecated: 1.22: Use nm_remote_connection_delete_async() or GDBusConnection. + **/ +gboolean +nm_remote_connection_delete(NMRemoteConnection *connection, + GCancellable * cancellable, + GError ** error) +{ + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE); + + return _nm_client_dbus_call_sync_void(_nm_object_get_client(connection), + cancellable, + _nm_object_get_path(connection), + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + "Delete", + g_variant_new("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); +} + +/** + * nm_remote_connection_delete_async: + * @connection: the #NMRemoteConnection + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the delete operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously deletes the connection. + **/ +void +nm_remote_connection_delete_async(NMRemoteConnection *connection, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_REMOTE_CONNECTION(connection)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(_nm_object_get_client(connection), + connection, + nm_remote_connection_delete_async, + cancellable, + callback, + user_data, + _nm_object_get_path(connection), + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + "Delete", + g_variant_new("()"), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_remote_connection_delete_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_delete_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_delete_finish(NMRemoteConnection *connection, + GAsyncResult * result, + GError ** error) +{ + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, connection, nm_remote_connection_delete_async), + FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/** + * nm_remote_connection_get_secrets: + * @connection: the #NMRemoteConnection + * @setting_name: the #NMSetting object name to get secrets for + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Request the connection's secrets. Note that this is a blocking D-Bus call, + * not a simple property accessor. + * + * Returns: (transfer full): a #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing + * @connection's secrets, or %NULL on error. + * + * Deprecated: 1.22: Use nm_remote_connection_get_secrets_async() or GDBusConnection. + **/ +GVariant * +nm_remote_connection_get_secrets(NMRemoteConnection *connection, + const char * setting_name, + GCancellable * cancellable, + GError ** error) +{ + gs_unref_variant GVariant *ret = NULL; + GVariant * secrets; + + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), NULL); + g_return_val_if_fail(setting_name, NULL); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), NULL); + + ret = _nm_client_dbus_call_sync(_nm_object_get_client(connection), + cancellable, + _nm_object_get_path(connection), + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + "GetSecrets", + g_variant_new("(s)", setting_name), + G_VARIANT_TYPE("(a{sa{sv}})"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + TRUE, + error); + if (!ret) + return NULL; + + g_variant_get(ret, "(@a{sa{sv}})", &secrets); + + return secrets; +} + +/** + * nm_remote_connection_get_secrets_async: + * @connection: the #NMRemoteConnection + * @setting_name: the #NMSetting object name to get secrets for + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the secret request completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously requests the connection's secrets. + **/ +void +nm_remote_connection_get_secrets_async(NMRemoteConnection *connection, + const char * setting_name, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_REMOTE_CONNECTION(connection)); + g_return_if_fail(setting_name); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(_nm_object_get_client(connection), + connection, + nm_remote_connection_get_secrets_async, + cancellable, + callback, + user_data, + _nm_object_get_path(connection), + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + "GetSecrets", + g_variant_new("(s)", setting_name), + G_VARIANT_TYPE("(a{sa{sv}})"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_variant_strip_dbus_error_cb); +} + +/** + * nm_remote_connection_get_secrets_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_get_secrets_async(). + * + * Returns: (transfer full): a #GVariant of type %NM_VARIANT_TYPE_CONNECTION + * containing @connection's secrets, or %NULL on error. + **/ +GVariant * +nm_remote_connection_get_secrets_finish(NMRemoteConnection *connection, + GAsyncResult * result, + GError ** error) +{ + gs_unref_variant GVariant *ret = NULL; + GVariant * secrets; + + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), NULL); + g_return_val_if_fail( + nm_g_task_is_valid(result, connection, nm_remote_connection_get_secrets_async), + FALSE); + + ret = g_task_propagate_pointer(G_TASK(result), error); + if (!ret) + return NULL; + + g_variant_get(ret, "(@a{sa{sv}})", &secrets); + + return secrets; +} + +/** + * nm_remote_connection_get_unsaved: + * @connection: the #NMRemoteConnection + * + * Returns: %TRUE if the remote connection contains changes that have not + * been saved to disk, %FALSE if the connection is the same as its on-disk + * representation. + **/ +gboolean +nm_remote_connection_get_unsaved(NMRemoteConnection *connection) +{ + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE); + + return NM_REMOTE_CONNECTION_GET_PRIVATE(connection)->unsaved; +} + +/** + * nm_remote_connection_get_flags: + * @connection: the #NMRemoteConnection + * + * Returns: the flags of the connection of type #NMSettingsConnectionFlags. + * + * Since: 1.12 + **/ +NMSettingsConnectionFlags +nm_remote_connection_get_flags(NMRemoteConnection *connection) +{ + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE); + + return (NMSettingsConnectionFlags) NM_REMOTE_CONNECTION_GET_PRIVATE(connection)->flags; +} + +/** + * nm_remote_connection_get_filename: + * @connection: the #NMRemoteConnection + * + * Returns: file that stores the connection in case the connection is file-backed. + * + * Since: 1.12 + **/ +const char * +nm_remote_connection_get_filename(NMRemoteConnection *connection) +{ + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), NULL); + + return NM_REMOTE_CONNECTION_GET_PRIVATE(connection)->filename; +} + +/** + * nm_remote_connection_get_visible: + * @connection: the #NMRemoteConnection + * + * Checks if the connection is visible to the current user. If the + * connection is not visible then it is essentially useless; it will + * not contain any settings, and operations such as + * nm_remote_connection_save() and nm_remote_connection_delete() will + * always fail. (#NMRemoteSettings will not normally return + * non-visible connections to callers, but it is possible for a + * connection's visibility to change after you already have a + * reference to it.) + * + * Returns: %TRUE if the remote connection is visible to the current + * user, %FALSE if not. + **/ +gboolean +nm_remote_connection_get_visible(NMRemoteConnection *connection) +{ + g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE); + + return NM_REMOTE_CONNECTION_GET_PRIVATE(connection)->visible; +} + +/*****************************************************************************/ + +GCancellable * +_nm_remote_settings_get_settings_prepare(NMRemoteConnection *self) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE(self); + + nm_clear_g_cancellable(&priv->get_settings_cancellable); + priv->get_settings_cancellable = g_cancellable_new(); + return priv->get_settings_cancellable; +} + +void +_nm_remote_settings_get_settings_commit(NMRemoteConnection *self, GVariant *settings) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE(self); + GError * error = NULL; + gboolean visible = FALSE; + gboolean changed = FALSE; + + g_clear_object(&priv->get_settings_cancellable); + + if (!priv->is_initialized) { + changed = TRUE; + priv->is_initialized = TRUE; + } + + if (settings) { + if (!_nm_connection_replace_settings((NMConnection *) self, + settings, + NM_SETTING_PARSE_FLAGS_BEST_EFFORT, + &error)) { + NML_NMCLIENT_LOG_E(_nm_object_get_client(self), + "[%s] failure to update settings: %s", + _nm_object_get_path(self), + error->message); + g_clear_error(&error); + } else + visible = TRUE; + } else + nm_connection_clear_settings(NM_CONNECTION(self)); + + if (priv->visible != visible) { + priv->visible = visible; + _nm_client_queue_notify_object(_nm_object_get_client(self), + self, + obj_properties[PROP_VISIBLE]); + changed = TRUE; + } + + if (changed) + _nm_client_notify_object_changed(_nm_object_get_client(self), _nm_object_get_dbobj(self)); +} + +/*****************************************************************************/ + +static gboolean +is_ready(NMObject *nmobj) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE(nmobj); + + if (!priv->is_initialized) + return FALSE; + + return NM_OBJECT_CLASS(nm_remote_connection_parent_class)->is_ready(nmobj); +} + +/*****************************************************************************/ + +static void +register_client(NMObject *nmobj, NMClient *client, NMLDBusObject *dbobj) +{ + NM_OBJECT_CLASS(nm_remote_connection_parent_class)->register_client(nmobj, client, dbobj); + nm_connection_set_path(NM_CONNECTION(nmobj), dbobj->dbus_path->str); + _nm_client_get_settings_call(client, dbobj); +} + +static void +unregister_client(NMObject *nmobj, NMClient *client, NMLDBusObject *dbobj) +{ + nm_clear_g_cancellable(&NM_REMOTE_CONNECTION_GET_PRIVATE(nmobj)->get_settings_cancellable); + NM_OBJECT_CLASS(nm_remote_connection_parent_class)->unregister_client(nmobj, client, dbobj); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_UNSAVED: + g_value_set_boolean(value, NM_REMOTE_CONNECTION_GET_PRIVATE(object)->unsaved); + break; + case PROP_FLAGS: + g_value_set_uint(value, NM_REMOTE_CONNECTION_GET_PRIVATE(object)->flags); + break; + case PROP_FILENAME: + g_value_set_string(value, NM_REMOTE_CONNECTION_GET_PRIVATE(object)->filename); + break; + case PROP_VISIBLE: + g_value_set_boolean(value, NM_REMOTE_CONNECTION_GET_PRIVATE(object)->visible); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_remote_connection_init(NMRemoteConnection *self) +{} + +static void +dispose(GObject *object) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE(object); + + nm_clear_g_free(&priv->filename); + + G_OBJECT_CLASS(nm_remote_connection_parent_class)->dispose(object); +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings_connection = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + nm_remote_connection_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_S("Filename", + PROP_FILENAME, + NMRemoteConnection, + _priv.filename), + NML_DBUS_META_PROPERTY_INIT_U("Flags", PROP_FLAGS, NMRemoteConnection, _priv.flags), + NML_DBUS_META_PROPERTY_INIT_B("Unsaved", + PROP_UNSAVED, + NMRemoteConnection, + _priv.unsaved), ), ); + +static void +nm_remote_connection_class_init(NMRemoteConnectionClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + + object_class->get_property = get_property; + object_class->dispose = dispose; + + nm_object_class->is_ready = is_ready; + nm_object_class->register_client = register_client; + nm_object_class->unregister_client = unregister_client; + + /** + * NMRemoteConnection:unsaved: + * + * %TRUE if the remote connection contains changes that have not been saved + * to disk, %FALSE if the connection is the same as its on-disk representation. + **/ + obj_properties[PROP_UNSAVED] = g_param_spec_boolean(NM_REMOTE_CONNECTION_UNSAVED, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMRemoteConnection:flags: + * + * The flags of the connection as unsigned integer. The values + * correspond to the #NMSettingsConnectionFlags enum. + * + * Since: 1.12 + **/ + obj_properties[PROP_FLAGS] = g_param_spec_uint(NM_REMOTE_CONNECTION_FLAGS, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMRemoteConnection:filename: + * + * File that stores the connection in case the connection is + * file-backed. + * + * Since: 1.12 + **/ + obj_properties[PROP_FILENAME] = g_param_spec_string(NM_REMOTE_CONNECTION_FILENAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMRemoteConnection:visible: + * + * %TRUE if the remote connection is visible to the current user, %FALSE if + * not. If the connection is not visible then it is essentially useless; it + * will not contain any settings, and operations such as + * nm_remote_connection_save() and nm_remote_connection_delete() will always + * fail. (#NMRemoteSettings will not normally return non-visible connections + * to callers, but it is possible for a connection's visibility to change + * after you already have a reference to it.) + **/ + obj_properties[PROP_VISIBLE] = g_param_spec_boolean(NM_REMOTE_CONNECTION_VISIBLE, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_settings_connection); +} + +static void +nm_remote_connection_connection_iface_init(NMConnectionInterface *iface) +{} diff --git a/src/libnm-client-impl/nm-secret-agent-old.c b/src/libnm-client-impl/nm-secret-agent-old.c new file mode 100644 index 0000000..881dfd5 --- /dev/null +++ b/src/libnm-client-impl/nm-secret-agent-old.c @@ -0,0 +1,1995 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2010 - 2011 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-secret-agent-old.h" + +#include "c-list/src/c-list.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-dbus-helpers.h" +#include "nm-dbus-interface.h" +#include "nm-enum-types.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-time-utils.h" +#include "nm-simple-connection.h" + +#define REGISTER_RETRY_TIMEOUT_MSEC 3000 +#define _CALL_REGISTER_TIMEOUT_MSEC 15000 + +/*****************************************************************************/ + +typedef struct { + char * connection_path; + char * setting_name; + GDBusMethodInvocation *context; + CList gsi_lst; + bool is_cancelling : 1; +} GetSecretsInfo; + +NM_GOBJECT_PROPERTIES_DEFINE(NMSecretAgentOld, + PROP_IDENTIFIER, + PROP_AUTO_REGISTER, + PROP_REGISTERED, + PROP_CAPABILITIES, + PROP_DBUS_CONNECTION, ); + +typedef struct { + GDBusConnection *dbus_connection; + GMainContext * main_context; + GMainContext * dbus_context; + GObject * context_busy_watcher; + GCancellable * name_owner_cancellable; + GCancellable * registering_cancellable; + GSource * registering_retry_source; + + NMLInitData *init_data; + + CList gsi_lst_head; + + CList pending_tasks_register_lst_head; + + char *identifier; + + NMRefString *name_owner_curr; + NMRefString *name_owner_next; + + gint64 registering_timeout_msec; + + guint name_owner_changed_id; + + guint exported_id; + + guint capabilities; + + guint8 registering_try_count; + + guint8 register_state_change_reenter : 2; + + bool session_bus : 1; + + bool auto_register : 1; + + bool is_registered : 1; + + bool is_enabled : 1; + + bool registration_force_unregister : 1; + + /* This is true, if we either are in the process of RegisterWithCapabilities() or + * are already successfully registered. + * + * This is only TRUE, if the name owner was authenticated to run as root user. + * + * It also means, we should follow up with an Unregister() call during shutdown. */ + bool registered_against_server : 1; + + bool is_initialized : 1; + bool is_destroyed : 1; +} NMSecretAgentOldPrivate; + +static void nm_secret_agent_old_initable_iface_init(GInitableIface *iface); +static void nm_secret_agent_old_async_initable_iface_init(GAsyncInitableIface *iface); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE( + NMSecretAgentOld, + nm_secret_agent_old, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE, nm_secret_agent_old_initable_iface_init); + G_IMPLEMENT_INTERFACE(G_TYPE_ASYNC_INITABLE, nm_secret_agent_old_async_initable_iface_init);) + +#define NM_SECRET_AGENT_OLD_GET_PRIVATE(self) \ + (G_TYPE_INSTANCE_GET_PRIVATE((self), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldPrivate)) + +/*****************************************************************************/ + +#define _NMLOG(level, ...) \ + NML_DBUS_LOG((level), \ + "secret-agent[" NM_HASH_OBFUSCATE_PTR_FMT \ + "]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + NM_HASH_OBFUSCATE_PTR(self) _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/*****************************************************************************/ + +static const GDBusInterfaceInfo interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_SECRET_AGENT, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS( + NM_DEFINE_GDBUS_METHOD_INFO("GetSecrets", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO("connection_path", "o"), + NM_DEFINE_GDBUS_ARG_INFO("setting_name", "s"), + NM_DEFINE_GDBUS_ARG_INFO("hints", "as"), + NM_DEFINE_GDBUS_ARG_INFO("flags", "u"), ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("secrets", "a{sa{sv}}"), ), ), + NM_DEFINE_GDBUS_METHOD_INFO("CancelGetSecrets", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("connection_path", "o"), + NM_DEFINE_GDBUS_ARG_INFO("setting_name", "s"), ), ), + NM_DEFINE_GDBUS_METHOD_INFO("SaveSecrets", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO("connection_path", "o"), ), ), + NM_DEFINE_GDBUS_METHOD_INFO( + "DeleteSecrets", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO("connection_path", "o"), ), ), ), ); + +/*****************************************************************************/ + +static void _register_state_change(NMSecretAgentOld *self); + +static void _register_dbus_call(NMSecretAgentOld *self); + +static void _init_complete(NMSecretAgentOld *self, GError *error_take); + +static void _register_state_complete(NMSecretAgentOld *self); + +/*****************************************************************************/ + +/** + * nm_secret_agent_old_get_dbus_connection: + * @self: the #NMSecretAgentOld instance + * + * Returns: (transfer none): the #GDBusConnection used by the secret agent. + * You may either set this as construct property %NM_SECRET_AGENT_OLD_DBUS_CONNECTION, + * or it will automatically set during initialization. + * + * Since: 1.24 + */ +GDBusConnection * +nm_secret_agent_old_get_dbus_connection(NMSecretAgentOld *self) +{ + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(self), NULL); + + return NM_SECRET_AGENT_OLD_GET_PRIVATE(self)->dbus_connection; +} + +/** + * nm_secret_agent_old_get_main_context: + * @self: the #NMSecretAgentOld instance + * + * Returns: (transfer none): the #GMainContext instance associate with the + * instance. This is the g_main_context_get_thread_default() at the time + * when creating the instance. + * + * Since: 1.24 + */ +GMainContext * +nm_secret_agent_old_get_main_context(NMSecretAgentOld *self) +{ + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(self), NULL); + + return NM_SECRET_AGENT_OLD_GET_PRIVATE(self)->main_context; +} + +/** + * nm_secret_agent_old_get_context_busy_watcher: + * @self: the #NMSecretAgentOld instance + * + * Returns a #GObject that stays alive as long as there are pending + * requests in the #GDBusConnection. Such requests keep the #GMainContext + * alive, and thus you may want to keep iterating the context as long + * until a weak reference indicates that this object is gone. This is + * useful because even when you destroy the instance right away (and all + * the internally pending requests get cancelled), any pending g_dbus_connection_call() + * requests will still invoke the result on the #GMainContext. Hence, this + * allows you to know how long you must iterate the context to know + * that all remains are cleaned up. + * + * Returns: (transfer none): a #GObject that you may register a weak pointer + * to know that the #GMainContext is still kept busy by @self. + * + * Since: 1.24 + */ +GObject * +nm_secret_agent_old_get_context_busy_watcher(NMSecretAgentOld *self) +{ + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(self), NULL); + + return NM_SECRET_AGENT_OLD_GET_PRIVATE(self)->context_busy_watcher; +} + +/** + * nm_secret_agent_old_get_dbus_name_owner: + * @self: the #NMSecretAgentOld instance + * + * Returns: the current D-Bus name owner. While this property + * is set while registering, it really only makes sense when + * the nm_secret_agent_old_get_registered() indicates that + * registration is successful. + * + * Since: 1.24 + */ +const char * +nm_secret_agent_old_get_dbus_name_owner(NMSecretAgentOld *self) +{ + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(self), NULL); + + return nm_ref_string_get_str(NM_SECRET_AGENT_OLD_GET_PRIVATE(self)->name_owner_curr); +} + +/** + * nm_secret_agent_old_get_registered: + * @self: a #NMSecretAgentOld + * + * Note that the secret agent transparently registers and re-registers + * as the D-Bus name owner appears. Hence, this property is not really + * useful. Also, to be graceful against races during registration, the + * instance will already accept requests while being in the process of + * registering. + * If you need to avoid races and want to wait until @self is registered, + * call nm_secret_agent_old_register_async(). If that function completes + * with success, you know the instance is registered. + * + * Returns: a %TRUE if the agent is registered, %FALSE if it is not. + **/ +gboolean +nm_secret_agent_old_get_registered(NMSecretAgentOld *self) +{ + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(self), FALSE); + + return NM_SECRET_AGENT_OLD_GET_PRIVATE(self)->is_registered; +} + +/*****************************************************************************/ + +static void +get_secret_info_free(GetSecretsInfo *info) +{ + nm_assert(info); + nm_assert(!info->context); + + c_list_unlink_stale(&info->gsi_lst); + g_free(info->connection_path); + g_free(info->setting_name); + nm_g_slice_free(info); +} + +static void +get_secret_info_complete_and_free(GetSecretsInfo *info, GVariant *secrets, GError *error) +{ + if (error) { + if (secrets) + nm_g_variant_unref_floating(secrets); + g_dbus_method_invocation_return_gerror(g_steal_pointer(&info->context), error); + } else { + g_dbus_method_invocation_return_value(g_steal_pointer(&info->context), + g_variant_new("(@a{sa{sv}})", secrets)); + } + get_secret_info_free(info); +} + +static void +get_secret_info_complete_and_free_error(GetSecretsInfo *info, + GQuark error_domain, + int error_code, + const char * error_message) +{ + g_dbus_method_invocation_return_error_literal(g_steal_pointer(&info->context), + error_domain, + error_code, + error_message); + get_secret_info_free(info); +} + +/*****************************************************************************/ + +static void +_dbus_connection_call_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object GObject *context_busy_watcher = NULL; + GAsyncReadyCallback callback; + gpointer callback_user_data; + + nm_utils_user_data_unpack(user_data, &context_busy_watcher, &callback, &callback_user_data); + callback(source, result, callback_user_data); +} + +static void +_dbus_connection_call(NMSecretAgentOld * self, + const char * bus_name, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + nm_assert(nm_g_main_context_is_thread_default(priv->dbus_context)); + + g_dbus_connection_call( + priv->dbus_connection, + bus_name, + object_path, + interface_name, + method_name, + parameters, + reply_type, + flags, + timeout_msec, + cancellable, + callback ? _dbus_connection_call_cb : NULL, + callback + ? nm_utils_user_data_pack(g_object_ref(priv->context_busy_watcher), callback, user_data) + : NULL); +} + +/*****************************************************************************/ + +static GetSecretsInfo * +find_get_secrets_info(NMSecretAgentOldPrivate *priv, + const char * connection_path, + const char * setting_name) +{ + GetSecretsInfo *info; + + c_list_for_each_entry (info, &priv->gsi_lst_head, gsi_lst) { + if (nm_streq(connection_path, info->connection_path) + && nm_streq(setting_name, info->setting_name)) + return info; + } + return NULL; +} + +static void +_cancel_get_secret_request(NMSecretAgentOld *self, GetSecretsInfo *info, const char *message) +{ + c_list_unlink(&info->gsi_lst); + info->is_cancelling = TRUE; + + _LOGT("cancel get-secrets request \"%s\", \"%s\": %s", + info->connection_path, + info->setting_name, + message); + + NM_SECRET_AGENT_OLD_GET_CLASS(self)->cancel_get_secrets(self, + info->connection_path, + info->setting_name); + + get_secret_info_complete_and_free_error(info, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_AGENT_CANCELED, + message); +} + +static gboolean +verify_request(NMSecretAgentOld * self, + GDBusMethodInvocation *context, + GVariant * connection_dict, + const char * connection_path, + NMConnection ** out_connection, + GError ** error) +{ + gs_unref_object NMConnection *connection = NULL; + gs_free_error GError *local = NULL; + + if (!nm_dbus_path_not_empty(connection_path)) { + g_set_error_literal(error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "Invalid connection: no connection path given."); + return FALSE; + } + + connection = _nm_simple_connection_new_from_dbus(connection_dict, + NM_SETTING_PARSE_FLAGS_BEST_EFFORT, + &local); + if (!connection) { + g_set_error(error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "Invalid connection: %s", + local->message); + return FALSE; + } + + nm_connection_set_path(connection, connection_path); + NM_SET_OUT(out_connection, g_steal_pointer(&connection)); + return TRUE; +} + +static void +get_secrets_cb(NMSecretAgentOld *self, + NMConnection * connection, + GVariant * secrets, + GError * error, + gpointer user_data) +{ + GetSecretsInfo *info = user_data; + + if (info->is_cancelling) { + if (secrets) + nm_g_variant_unref_floating(secrets); + return; + } + + _LOGT("request: get-secrets request \"%s\", \"%s\" complete with %s%s%s", + info->connection_path, + info->setting_name, + NM_PRINT_FMT_QUOTED(error, "error: ", error->message, "", "success")); + + get_secret_info_complete_and_free(info, secrets, error); +} + +static void +impl_get_secrets(NMSecretAgentOld *self, GVariant *parameters, GDBusMethodInvocation *context) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + GError * error = NULL; + gs_unref_object NMConnection *connection = NULL; + GetSecretsInfo * info; + gs_unref_variant GVariant *arg_connection = NULL; + const char * arg_connection_path; + const char * arg_setting_name; + gs_free const char ** arg_hints = NULL; + guint32 arg_flags; + + g_variant_get(parameters, + "(@a{sa{sv}}&o&s^a&su)", + &arg_connection, + &arg_connection_path, + &arg_setting_name, + &arg_hints, + &arg_flags); + + if (!verify_request(self, context, arg_connection, arg_connection_path, &connection, &error)) { + g_dbus_method_invocation_take_error(context, error); + return; + } + + _LOGT("request: get-secrets(\"%s\", \"%s\")", arg_connection_path, arg_setting_name); + + info = find_get_secrets_info(priv, arg_connection_path, arg_setting_name); + if (info) + _cancel_get_secret_request(self, info, "Request aborted due to new request"); + + info = g_slice_new(GetSecretsInfo); + *info = (GetSecretsInfo){ + .context = context, + .connection_path = g_strdup(arg_connection_path), + .setting_name = g_strdup(arg_setting_name), + }; + c_list_link_tail(&priv->gsi_lst_head, &info->gsi_lst); + + NM_SECRET_AGENT_OLD_GET_CLASS(self)->get_secrets(self, + connection, + info->connection_path, + info->setting_name, + arg_hints, + arg_flags, + get_secrets_cb, + info); +} + +static void +impl_cancel_get_secrets(NMSecretAgentOld * self, + GVariant * parameters, + GDBusMethodInvocation *context) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + GetSecretsInfo * info; + const char * arg_connection_path; + const char * arg_setting_name; + + g_variant_get(parameters, "(&o&s)", &arg_connection_path, &arg_setting_name); + + info = find_get_secrets_info(priv, arg_connection_path, arg_setting_name); + if (!info) { + g_dbus_method_invocation_return_error_literal( + context, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "No secrets request in progress for this connection."); + return; + } + + _cancel_get_secret_request(self, info, "Request cancelled by NetworkManager"); + + g_dbus_method_invocation_return_value(context, NULL); +} + +static void +save_secrets_cb(NMSecretAgentOld *self, NMConnection *connection, GError *error, gpointer user_data) +{ + GDBusMethodInvocation *context = user_data; + + if (error) + g_dbus_method_invocation_return_gerror(context, error); + else + g_dbus_method_invocation_return_value(context, NULL); +} + +static void +impl_save_secrets(NMSecretAgentOld *self, GVariant *parameters, GDBusMethodInvocation *context) +{ + gs_unref_object NMConnection *connection = NULL; + gs_unref_variant GVariant *arg_connection = NULL; + const char * arg_connection_path; + GError * error = NULL; + + g_variant_get(parameters, "(@a{sa{sv}}&o)", &arg_connection, &arg_connection_path); + + if (!verify_request(self, context, arg_connection, arg_connection_path, &connection, &error)) { + g_dbus_method_invocation_take_error(context, error); + return; + } + + _LOGT("request: save-secrets(\"%s\")", arg_connection_path); + + NM_SECRET_AGENT_OLD_GET_CLASS(self)->save_secrets(self, + connection, + arg_connection_path, + save_secrets_cb, + context); +} + +static void +delete_secrets_cb(NMSecretAgentOld *self, + NMConnection * connection, + GError * error, + gpointer user_data) +{ + GDBusMethodInvocation *context = user_data; + + if (error) + g_dbus_method_invocation_return_gerror(context, error); + else + g_dbus_method_invocation_return_value(context, NULL); +} + +static void +impl_delete_secrets(NMSecretAgentOld *self, GVariant *parameters, GDBusMethodInvocation *context) +{ + gs_unref_object NMConnection *connection = NULL; + gs_unref_variant GVariant *arg_connection = NULL; + const char * arg_connection_path; + GError * error = NULL; + + g_variant_get(parameters, "(@a{sa{sv}}&o)", &arg_connection, &arg_connection_path); + + if (!verify_request(self, context, arg_connection, arg_connection_path, &connection, &error)) { + g_dbus_method_invocation_take_error(context, error); + return; + } + + _LOGT("request: delete-secrets(\"%s\")", arg_connection_path); + + NM_SECRET_AGENT_OLD_GET_CLASS(self)->delete_secrets(self, + connection, + arg_connection_path, + delete_secrets_cb, + context); +} + +/*****************************************************************************/ + +/** + * nm_secret_agent_old_enable: + * @self: the #NMSecretAgentOld instance + * @enable: whether to enable or disable the listener. + * + * This has the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER + * property. + * + * Unlike most other functions, you may already call this function before + * initialization completes. + * + * Since: 1.24 + */ +void +nm_secret_agent_old_enable(NMSecretAgentOld *self, gboolean enable) +{ + NMSecretAgentOldPrivate *priv; + + g_return_if_fail(NM_IS_SECRET_AGENT_OLD(self)); + + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + enable = (!!enable); + + if (priv->auto_register != enable) { + priv->auto_register = enable; + priv->is_enabled = enable; + _notify(self, PROP_AUTO_REGISTER); + } + _register_state_change(self); +} + +static void +_secret_agent_old_destroy(NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + priv->is_destroyed = TRUE; + + if (priv->exported_id != 0) { + g_dbus_connection_unregister_object(priv->dbus_connection, + nm_steal_int(&priv->exported_id)); + } + + _register_state_change(self); + + nm_assert(!priv->name_owner_changed_id); + nm_assert(!priv->name_owner_curr); + nm_assert(!priv->name_owner_next); + nm_assert(!priv->name_owner_cancellable); + nm_assert(!priv->registering_retry_source); + nm_assert(!priv->registering_cancellable); + nm_assert(!priv->init_data); + nm_assert(c_list_is_empty(&priv->gsi_lst_head)); + nm_assert(c_list_is_empty(&priv->pending_tasks_register_lst_head)); +} + +/** + * nm_secret_agent_old_destroy: + * @self: the #NMSecretAgentOld instance. + * + * Since 1.24, the instance will already register a D-Bus object on the + * D-Bus connection during initialization. That object will stay registered + * until @self gets unrefed (destroyed) or this function is called. This + * function performs the necessary cleanup to tear down the instance. Afterwards, + * the function can not longer be used. This is optional, but necessary to + * ensure unregistering the D-Bus object at a define point, when other users + * might still have a reference on @self. + * + * You may call this function any time and repeatedly. However, after destroying + * the instance, it is a bug to still use the instance for other purposes. The + * instance becomes defunct and cannot re-register. + * + * Since: 1.24 + */ +void +nm_secret_agent_old_destroy(NMSecretAgentOld *self) +{ + g_return_if_fail(NM_IS_SECRET_AGENT_OLD(self)); + + _LOGT("destroying"); + + _secret_agent_old_destroy(self); +} + +/*****************************************************************************/ + +/** + * nm_secret_agent_old_register: + * @self: a #NMSecretAgentOld + * @cancellable: a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Registers the #NMSecretAgentOld with the NetworkManager secret manager, + * indicating to NetworkManager that the agent is able to provide and save + * secrets for connections on behalf of its user. + * + * Returns: %TRUE if registration was successful, %FALSE on error. + * + * Since 1.24, this can no longer fail unless the @cancellable gets + * cancelled. Contrary to nm_secret_agent_old_register_async(), this also + * does not wait for the registration to succeed. You cannot synchronously + * (without iterating the caller's GMainContext) wait for registration. + * + * Since 1.24, registration is idempotent. It has the same effect as setting + * %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %TRUE or nm_secret_agent_old_enable(). + * + * Deprecated: 1.24: Use nm_secret_agent_old_enable() or nm_secret_agent_old_register_async(). + **/ +gboolean +nm_secret_agent_old_register(NMSecretAgentOld *self, GCancellable *cancellable, GError **error) +{ + NMSecretAgentOldPrivate *priv; + + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(self), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + g_return_val_if_fail(priv->is_initialized && !priv->is_destroyed, FALSE); + + priv->is_enabled = TRUE; + _register_state_change(self); + + if (g_cancellable_set_error_if_cancelled(cancellable, error)) + return FALSE; + + /* This is a synchronous function, meaning: we are not allowed to iterate + * the caller's GMainContext. This is a catch 22, because we don't want + * to perform synchronous calls that bypasses the ordering of our otherwise + * asynchronous mode of operation. Hence, we always signal success. + * That's why this function is deprecated. + * + * So despite claiming success, we might still be in the process of registering + * or NetworkManager might not be available. + * + * This is a change in behavior with respect to libnm before 1.24. + */ + return TRUE; +} + +static void +_register_cancelled_cb(GObject *object, gpointer user_data) +{ + GTask * task0 = user_data; + gs_unref_object GTask * task = NULL; + NMSecretAgentOld * self = g_task_get_source_object(task0); + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + gulong * p_cancelled_id; + NMCListElem * elem; + gs_free_error GError *error = NULL; + + elem = nm_c_list_elem_find_first(&priv->pending_tasks_register_lst_head, x, x == task0); + + g_return_if_fail(elem); + + task = nm_c_list_elem_free_steal(elem); + + p_cancelled_id = g_task_get_task_data(task); + if (p_cancelled_id) { + g_signal_handler_disconnect(g_task_get_cancellable(task), *p_cancelled_id); + g_task_set_task_data(task, NULL, NULL); + } + + nm_utils_error_set_cancelled(&error, FALSE, NULL); + g_task_return_error(task, error); +} + +/** + * nm_secret_agent_old_register_async: + * @self: a #NMSecretAgentOld + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to call when the agent is registered + * @user_data: data for @callback + * + * Asynchronously registers the #NMSecretAgentOld with the NetworkManager secret + * manager, indicating to NetworkManager that the agent is able to provide and + * save secrets for connections on behalf of its user. + * + * Since 1.24, registration cannot fail and is idempotent. It has + * the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %TRUE + * or nm_secret_agent_old_enable(). + * + * Since 1.24, the asynchronous result indicates whether the instance is successfully + * registered. In any case, this call enables the agent and it will automatically + * try to register and handle secret requests. A failure of this function only indicates + * that currently the instance might not be ready (but since it will automatically + * try to recover, it might be ready in a moment afterwards). Use this function if + * you want to check and ensure that the agent is registered. + **/ +void +nm_secret_agent_old_register_async(NMSecretAgentOld * self, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMSecretAgentOldPrivate *priv; + + g_return_if_fail(NM_IS_SECRET_AGENT_OLD(self)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + g_return_if_fail(priv->is_initialized && !priv->is_destroyed); + + if (callback) { + GTask *task; + + task = nm_g_task_new(self, + cancellable, + nm_secret_agent_old_register_async, + callback, + user_data); + + c_list_link_tail(&priv->pending_tasks_register_lst_head, + &nm_c_list_elem_new_stale(task)->lst); + + if (cancellable) { + gulong cancelled_id; + + cancelled_id = + g_cancellable_connect(cancellable, G_CALLBACK(_register_cancelled_cb), task, NULL); + if (cancelled_id != 0) { + g_task_set_task_data(task, g_memdup(&cancelled_id, sizeof(cancelled_id)), g_free); + } + } + } + + priv->is_enabled = TRUE; + _register_state_change(self); +} + +/** + * nm_secret_agent_old_register_finish: + * @self: a #NMSecretAgentOld + * @result: the result passed to the #GAsyncReadyCallback + * @error: return location for a #GError, or %NULL + * + * Gets the result of a call to nm_secret_agent_old_register_async(). + * + * Returns: %TRUE if registration was successful, %FALSE on error. + * + * Since 1.24, registration cannot fail and is idempotent. It has + * the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %TRUE + * or nm_secret_agent_old_enable(). + **/ +gboolean +nm_secret_agent_old_register_finish(NMSecretAgentOld *self, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(self), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, self, nm_secret_agent_old_register_async), + FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/** + * nm_secret_agent_old_unregister: + * @self: a #NMSecretAgentOld + * @cancellable: a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Unregisters the #NMSecretAgentOld with the NetworkManager secret manager, + * indicating to NetworkManager that the agent will no longer provide or + * store secrets on behalf of this user. + * + * Returns: %TRUE if unregistration was successful, %FALSE on error + * + * Since 1.24, registration cannot fail and is idempotent. It has + * the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %FALSE + * or nm_secret_agent_old_enable(). + * + * Deprecated: 1.24: Use nm_secret_agent_old_enable(). + **/ +gboolean +nm_secret_agent_old_unregister(NMSecretAgentOld *self, GCancellable *cancellable, GError **error) +{ + NMSecretAgentOldPrivate *priv; + + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(self), FALSE); + g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + g_return_val_if_fail(priv->is_initialized && !priv->is_destroyed, FALSE); + + priv->is_enabled = FALSE; + _register_state_change(self); + + return !g_cancellable_set_error_if_cancelled(cancellable, error); +} + +/** + * nm_secret_agent_old_unregister_async: + * @self: a #NMSecretAgentOld + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to call when the agent is unregistered + * @user_data: data for @callback + * + * Asynchronously unregisters the #NMSecretAgentOld with the NetworkManager secret + * manager, indicating to NetworkManager that the agent will no longer provide + * or store secrets on behalf of this user. + * + * Since 1.24, registration cannot fail and is idempotent. It has + * the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %FALSE + * or nm_secret_agent_old_enable(). + * + * Deprecated: 1.24: Use nm_secret_agent_old_enable(). + **/ +void +nm_secret_agent_old_unregister_async(NMSecretAgentOld * self, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMSecretAgentOldPrivate *priv; + + g_return_if_fail(NM_IS_SECRET_AGENT_OLD(self)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + g_return_if_fail(priv->is_initialized && !priv->is_destroyed); + + if (callback) { + gs_unref_object GTask *task = NULL; + + task = nm_g_task_new(self, + cancellable, + nm_secret_agent_old_unregister_async, + callback, + user_data); + g_task_return_boolean(task, TRUE); + } + + priv->is_enabled = FALSE; + _register_state_change(self); +} + +/** + * nm_secret_agent_old_unregister_finish: + * @self: a #NMSecretAgentOld + * @result: the result passed to the #GAsyncReadyCallback + * @error: return location for a #GError, or %NULL + * + * Gets the result of a call to nm_secret_agent_old_unregister_async(). + * + * Returns: %TRUE if unregistration was successful, %FALSE on error. + * + * Since 1.24, registration cannot fail and is idempotent. It has + * the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %FALSE + * or nm_secret_agent_old_enable(). + * + * Deprecated: 1.24: Use nm_secret_agent_old_enable(). + **/ +gboolean +nm_secret_agent_old_unregister_finish(NMSecretAgentOld *self, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(self), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, self, nm_secret_agent_old_unregister_async), + FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/*****************************************************************************/ + +/** + * nm_secret_agent_old_get_secrets: (virtual get_secrets): + * @self: a #NMSecretAgentOld + * @connection: the #NMConnection for which we're asked secrets + * @setting_name: the name of the secret setting + * @hints: (array zero-terminated=1): hints to the agent + * @flags: flags that modify the behavior of the request + * @callback: (scope async): a callback, to be invoked when the operation is done + * @user_data: (closure): caller-specific data to be passed to @callback + * + * Asynchronously retrieves secrets belonging to @connection for the + * setting @setting_name. @flags indicate specific behavior that the secret + * agent should use when performing the request, for example returning only + * existing secrets without user interaction, or requesting entirely new + * secrets from the user. + */ +void +nm_secret_agent_old_get_secrets(NMSecretAgentOld * self, + NMConnection * connection, + const char * setting_name, + const char ** hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_SECRET_AGENT_OLD(self)); + g_return_if_fail(NM_IS_CONNECTION(connection)); + g_return_if_fail(nm_connection_get_path(connection)); + g_return_if_fail(setting_name && setting_name[0]); + g_return_if_fail(!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM)); + g_return_if_fail(!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS)); + g_return_if_fail(callback != NULL); + + NM_SECRET_AGENT_OLD_GET_CLASS(self)->get_secrets(self, + connection, + nm_connection_get_path(connection), + setting_name, + hints, + flags, + callback, + user_data); +} + +/** + * nm_secret_agent_old_save_secrets: (virtual save_secrets): + * @self: a #NMSecretAgentOld + * @connection: a #NMConnection + * @callback: (scope async): a callback, to be invoked when the operation is done + * @user_data: (closure): caller-specific data to be passed to @callback + * + * Asynchronously ensures that all secrets inside @connection are stored to + * disk. + */ +void +nm_secret_agent_old_save_secrets(NMSecretAgentOld * self, + NMConnection * connection, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_SECRET_AGENT_OLD(self)); + g_return_if_fail(NM_IS_CONNECTION(connection)); + g_return_if_fail(nm_connection_get_path(connection)); + + NM_SECRET_AGENT_OLD_GET_CLASS(self)->save_secrets(self, + connection, + nm_connection_get_path(connection), + callback, + user_data); +} + +/** + * nm_secret_agent_old_delete_secrets: (virtual delete_secrets): + * @self: a #NMSecretAgentOld + * @connection: a #NMConnection + * @callback: (scope async): a callback, to be invoked when the operation is done + * @user_data: (closure): caller-specific data to be passed to @callback + * + * Asynchronously asks the agent to delete all saved secrets belonging to + * @connection. + */ +void +nm_secret_agent_old_delete_secrets(NMSecretAgentOld * self, + NMConnection * connection, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_SECRET_AGENT_OLD(self)); + g_return_if_fail(NM_IS_CONNECTION(connection)); + g_return_if_fail(nm_connection_get_path(connection)); + + NM_SECRET_AGENT_OLD_GET_CLASS(self)->delete_secrets(self, + connection, + nm_connection_get_path(connection), + callback, + user_data); +} + +/*****************************************************************************/ + +static gboolean +validate_identifier(const char *identifier) +{ + const char *p = identifier; + size_t id_len; + + /* Length between 3 and 255 characters inclusive */ + id_len = strlen(identifier); + if (id_len < 3 || id_len > 255) + return FALSE; + + if ((identifier[0] == '.') || (identifier[id_len - 1] == '.')) + return FALSE; + + /* FIXME: do complete validation here */ + while (p && *p) { + if (!g_ascii_isalnum(*p) && (*p != '_') && (*p != '-') && (*p != '.')) + return FALSE; + if ((*p == '.') && (*(p + 1) == '.')) + return FALSE; + p++; + } + + return TRUE; +} + +/*****************************************************************************/ + +static gboolean +_register_retry_cb(gpointer user_data) +{ + NMSecretAgentOld * self = user_data; + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + + dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context); + + nm_clear_g_source_inst(&priv->registering_retry_source); + _register_dbus_call(self); + return G_SOURCE_CONTINUE; +} + +static void +_register_call_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + NMSecretAgentOld * self = user_data; + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error); + + if (nm_utils_error_is_cancelled(error)) + return; + + nm_assert(!priv->registering_retry_source); + nm_assert(!priv->is_registered); + nm_assert(priv->registering_cancellable); + + if (nm_dbus_error_is(error, NM_DBUS_ERROR_NAME_UNKNOWN_METHOD) + && nm_utils_get_monotonic_timestamp_msec() < priv->registering_timeout_msec) { + guint timeout_msec; + + timeout_msec = (2u << NM_MIN(6u, ++priv->registering_try_count)); + + _LOGT("register: registration failed with error \"%s\". Retry in %u msec...", + error->message, + timeout_msec); + + priv->registering_retry_source = + nm_g_source_attach(nm_g_timeout_source_new(timeout_msec, + G_PRIORITY_DEFAULT, + _register_retry_cb, + self, + NULL), + priv->dbus_context); + return; + } + + g_clear_object(&priv->registering_cancellable); + + if (error) { + /* registration apparently failed. However we still keep priv->registered_against_server TRUE, because + * + * - eventually we want to still make an Unregister() call. Even if it probably has no effect, + * better be sure. + * + * - we actually accept secret request (from the right name owner). We register so that + * NetworkManager knows that we are here. We don't require the registration to succeed + * for our purpose. If NetworkManager makes requests for us, despite the registration + * failing, that is fine. */ + _LOGT("register: registration failed with error \"%s\"", error->message); + goto out; + } + + _LOGT("register: registration succeeded"); + priv->is_registered = TRUE; + _notify(self, PROP_REGISTERED); + +out: + _register_state_complete(self); +} + +static void +_register_dbus_call(NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + _dbus_connection_call(self, + nm_ref_string_get_str(priv->name_owner_curr), + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER, + "RegisterWithCapabilities", + g_variant_new("(su)", priv->identifier, (guint32) priv->capabilities), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + _CALL_REGISTER_TIMEOUT_MSEC, + priv->registering_cancellable, + _register_call_cb, + self); +} + +static void +_get_connection_unix_user_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + NMSecretAgentOld * self; + NMSecretAgentOldPrivate *priv; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + guint32 sender_uid = 0; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error); + if (nm_utils_error_is_cancelled(error)) + return; + + self = user_data; + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + nm_assert(priv->registering_cancellable); + nm_assert(!priv->registered_against_server); + + if (ret) + g_variant_get(ret, "(u)", &sender_uid); + + if (ret && sender_uid == 0) + _LOGT("register: peer %s is owned by root. Validated to accept requests.", + priv->name_owner_curr->str); + else if (ret && priv->session_bus) { + _LOGT( + "register: peer %s is owned by user %d for session bus. Validated to accept requests.", + priv->name_owner_curr->str, + sender_uid); + } else { + /* the peer is not validated. We don't actually register. */ + if (ret) + _LOGT("register: peer %s is owned by user %u. Not validated as NetworkManager service.", + priv->name_owner_curr->str, + sender_uid); + else + _LOGT("register: failed to get user id for peer %s: %s. Not validated as " + "NetworkManager service.", + priv->name_owner_curr->str, + error->message); + + /* we actually don't do anything and keep the agent unregistered. + * + * We keep priv->registering_cancellable set to not retry this again, until we loose the + * name owner. But the state of the agent is lingering and won't accept any requests. */ + return; + } + + priv->registering_timeout_msec = + nm_utils_get_monotonic_timestamp_msec() + REGISTER_RETRY_TIMEOUT_MSEC; + priv->registering_try_count = 0; + priv->registered_against_server = TRUE; + _register_dbus_call(self); +} + +/*****************************************************************************/ + +static void +_name_owner_changed(NMSecretAgentOld *self, const char *name_owner, gboolean is_event) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + if (is_event) { + if (priv->name_owner_cancellable) { + /* we are still fetching the name-owner. Ignore this event. */ + return; + } + } else + g_clear_object(&priv->name_owner_cancellable); + + nm_ref_string_unref(priv->name_owner_next); + priv->name_owner_next = nm_ref_string_new(nm_str_not_empty(name_owner)); + + _LOGT("name-owner changed: %s%s%s -> %s%s%s", + NM_PRINT_FMT_QUOTED(priv->name_owner_curr, + "\"", + priv->name_owner_curr->str, + "\"", + "(null)"), + NM_PRINT_FMT_QUOTED(priv->name_owner_next, + "\"", + priv->name_owner_next->str, + "\"", + "(null)")); + + _register_state_change(self); +} + +static void +_name_owner_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMSecretAgentOld *self = user_data; + const char * new_owner; + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) + return; + + g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_owner); + + _name_owner_changed(self, new_owner, TRUE); +} + +static void +_name_owner_get_cb(const char *name_owner, GError *error, gpointer user_data) +{ + if (name_owner || !nm_utils_error_is_cancelled(error)) + _name_owner_changed(user_data, name_owner, FALSE); +} + +/*****************************************************************************/ + +static void +_method_call(GDBusConnection * connection, + const char * sender, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + GDBusMethodInvocation *context, + gpointer user_data) +{ + NMSecretAgentOld * self = user_data; + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + nm_assert(nm_streq0(object_path, NM_DBUS_PATH_SECRET_AGENT)); + nm_assert(nm_streq0(interface_name, NM_DBUS_INTERFACE_SECRET_AGENT)); + nm_assert(sender); + nm_assert(nm_streq0(sender, g_dbus_method_invocation_get_sender(context))); + + if (!priv->name_owner_curr || !priv->registered_against_server) { + /* priv->registered_against_server means that we started to register, but not necessarily + * that the registration fully succeeded. However, we already authenticated the request + * and so we accept it, even if the registration is not yet complete. */ + g_dbus_method_invocation_return_error_literal(context, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, + "Request by non authenticated peer rejected"); + return; + } + + if (nm_streq(method_name, "GetSecrets")) + impl_get_secrets(self, parameters, context); + else if (nm_streq(method_name, "CancelGetSecrets")) + impl_cancel_get_secrets(self, parameters, context); + else if (nm_streq(method_name, "SaveSecrets")) + impl_save_secrets(self, parameters, context); + else if (nm_streq(method_name, "DeleteSecrets")) + impl_delete_secrets(self, parameters, context); + else + nm_assert_not_reached(); +} + +/*****************************************************************************/ + +static void +_register_state_complete(NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + NMCListElem * elem; + gboolean any_tasks_to_complete = FALSE; + + if (!c_list_is_empty(&priv->pending_tasks_register_lst_head)) { + /* add a dummy sentinel. We want to complete all the task we started + * so far, but as we invoke user callbacks, the user might register + * new tasks. Those we don't complete in this run. */ + g_object_ref(self); + any_tasks_to_complete = TRUE; + c_list_link_tail(&priv->pending_tasks_register_lst_head, + &nm_c_list_elem_new_stale(&any_tasks_to_complete)->lst); + } + + _init_complete(self, NULL); + + if (any_tasks_to_complete) { + while ( + (elem = c_list_first_entry(&priv->pending_tasks_register_lst_head, NMCListElem, lst))) { + gpointer data = nm_c_list_elem_free_steal(elem); + gs_unref_object GTask *task = NULL; + + if (data == &any_tasks_to_complete) { + any_tasks_to_complete = FALSE; + break; + } + + task = data; + + if (!priv->is_registered) { + g_task_return_error(task, + g_error_new_literal(NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + _("registration failed"))); + continue; + } + g_task_return_boolean(task, TRUE); + } + nm_assert(!any_tasks_to_complete); + g_object_unref(self); + } +} + +static void +_register_state_change_do(NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + if (priv->is_destroyed) + priv->is_enabled = FALSE; + + if (!priv->is_enabled || priv->registration_force_unregister + || priv->name_owner_curr != priv->name_owner_next) { + GetSecretsInfo *info; + + while ((info = c_list_first_entry(&priv->gsi_lst_head, GetSecretsInfo, gsi_lst))) { + _cancel_get_secret_request(self, info, "The secret agent is going away"); + _register_state_change(self); + return; + } + + priv->registration_force_unregister = FALSE; + + nm_clear_g_cancellable(&priv->registering_cancellable); + nm_clear_g_source_inst(&priv->registering_retry_source); + + if (priv->registered_against_server) { + priv->registered_against_server = FALSE; + if (priv->name_owner_curr) { + _LOGT("register: unregister from %s", priv->name_owner_curr->str); + _dbus_connection_call(self, + priv->name_owner_curr->str, + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER, + "Unregister", + g_variant_new("()"), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + _CALL_REGISTER_TIMEOUT_MSEC, + NULL, + NULL, + NULL); + } + } + + if (!priv->is_enabled) { + nm_clear_g_cancellable(&priv->name_owner_cancellable); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id); + nm_clear_pointer(&priv->name_owner_curr, nm_ref_string_unref); + nm_clear_pointer(&priv->name_owner_next, nm_ref_string_unref); + } + + if (priv->is_registered) { + priv->is_registered = FALSE; + if (!priv->is_destroyed) { + _LOGT("register: now unregistered"); + _notify(self, PROP_REGISTERED); + _register_state_change(self); + return; + } + } + + if (!priv->is_enabled) { + _register_state_complete(self); + return; + } + + if (priv->name_owner_curr != priv->name_owner_next) { + nm_ref_string_unref(priv->name_owner_curr); + priv->name_owner_curr = nm_ref_string_ref(priv->name_owner_next); + } + } + + if (priv->name_owner_changed_id == 0) { + nm_assert(!priv->name_owner_cancellable); + nm_assert(!priv->name_owner_curr); + nm_assert(!priv->name_owner_next); + priv->name_owner_cancellable = g_cancellable_new(); + priv->name_owner_changed_id = + nm_dbus_connection_signal_subscribe_name_owner_changed(priv->dbus_connection, + NM_DBUS_SERVICE, + _name_owner_changed_cb, + self, + NULL); + nm_dbus_connection_call_get_name_owner(priv->dbus_connection, + NM_DBUS_SERVICE, + -1, + priv->name_owner_cancellable, + _name_owner_get_cb, + self); + return; + } + + if (priv->name_owner_cancellable) { + /* we still wait for the name owner. Nothing to do for now. */ + return; + } + + if (!priv->name_owner_curr) { + /* we don't have a name owner. We are done and wait. */ + _register_state_complete(self); + return; + } + + if (priv->registering_cancellable) { + /* we are already registering... wait longer. */ + return; + } + + nm_assert(!priv->registering_retry_source); + + if (!priv->is_registered) { + /* start registering... */ + priv->registering_cancellable = g_cancellable_new(); + _dbus_connection_call(self, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionUnixUser", + g_variant_new("(s)", priv->name_owner_curr->str), + G_VARIANT_TYPE("(u)"), + G_DBUS_CALL_FLAGS_NONE, + _CALL_REGISTER_TIMEOUT_MSEC, + priv->registering_cancellable, + _get_connection_unix_user_cb, + self); + return; + } + + /* we are fully registered and done. */ + _register_state_complete(self); +} + +static void +_register_state_change(NMSecretAgentOld *self) +{ + _nm_unused gs_unref_object NMSecretAgentOld *self_keep_alive = g_object_ref(self); + NMSecretAgentOldPrivate * priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + + if (priv->register_state_change_reenter == 0) { + /* We are not yet initialized. Do nothing. */ + return; + } + + if (priv->register_state_change_reenter != 1) { + /* Recursive calls are prevented. Do nothing for now, but repeat + * the state change afterwards. */ + priv->register_state_change_reenter = 3; + return; + } + + dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context); + +again: + priv->register_state_change_reenter = 2; + + _register_state_change_do(self); + + if (priv->register_state_change_reenter != 2) + goto again; + + priv->register_state_change_reenter = 1; +} + +/*****************************************************************************/ + +static void +_init_complete(NMSecretAgentOld *self, GError *error_take) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + gs_free_error GError *error = g_steal_pointer(&error_take); + GError * error_cancelled = NULL; + + if (!priv->init_data) + return; + + if (g_cancellable_set_error_if_cancelled(priv->init_data->cancellable, &error_cancelled)) { + g_clear_error(&error); + g_propagate_error(&error, error_cancelled); + } + + priv->is_initialized = (!error); + + _LOGT("%s init complete with %s%s%s", + priv->init_data->is_sync ? "sync" : "async", + NM_PRINT_FMT_QUOTED(error_take, "error: ", error_take->message, "", "success")); + + nml_init_data_return(g_steal_pointer(&priv->init_data), g_steal_pointer(&error)); +} + +static void +_init_register_object(NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + gs_free_error GError *error = NULL; + GDBusInterfaceVTable interface_vtable = { + .method_call = _method_call, + }; + + if (g_cancellable_set_error_if_cancelled(priv->init_data->cancellable, &error)) { + _init_complete(self, g_steal_pointer(&error)); + return; + } + + priv->exported_id = g_dbus_connection_register_object(priv->dbus_connection, + NM_DBUS_PATH_SECRET_AGENT, + (GDBusInterfaceInfo *) &interface_info, + &interface_vtable, + self, + NULL, + &error); + if (priv->exported_id == 0) { + _init_complete(self, g_steal_pointer(&error)); + return; + } + + priv->register_state_change_reenter = 1; + + _register_state_change(self); +} + +static void +_init_got_bus(GObject *initable, GAsyncResult *result, gpointer user_data) +{ + NMSecretAgentOld * self = user_data; + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + gs_free_error GError *error = NULL; + + priv->dbus_connection = g_bus_get_finish(result, &error); + if (!priv->dbus_connection) { + _init_complete(self, g_steal_pointer(&error)); + return; + } + + _LOGT("init: got GDBusConnection"); + + _notify(self, PROP_DBUS_CONNECTION); + + _init_register_object(self); +} + +static void +_init_start(NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + if (!priv->dbus_connection) { + GBusType bus_type; + + bus_type = _nm_dbus_bus_type(); + + priv->session_bus = (bus_type == G_BUS_TYPE_SESSION); + + g_bus_get(bus_type, priv->init_data->cancellable, _init_got_bus, self); + return; + } + + _init_register_object(self); +} + +static void +init_async(GAsyncInitable * initable, + int io_priority, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMSecretAgentOld * self; + NMSecretAgentOldClass * klass; + NMSecretAgentOldPrivate *priv; + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + gs_unref_object GTask *task = NULL; + + g_return_if_fail(NM_IS_SECRET_AGENT_OLD(initable)); + + self = NM_SECRET_AGENT_OLD(initable); + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + g_return_if_fail(!priv->dbus_context); + g_return_if_fail(!priv->is_destroyed); + + klass = NM_SECRET_AGENT_OLD_GET_CLASS(self); + g_return_if_fail(klass->get_secrets); + g_return_if_fail(klass->cancel_get_secrets); + g_return_if_fail(klass->save_secrets); + g_return_if_fail(klass->delete_secrets); + + _LOGT("init-async starting..."); + + priv->dbus_context = g_main_context_ref(priv->main_context); + + dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context); + + task = nm_g_task_new(self, cancellable, init_async, callback, user_data); + g_task_set_priority(task, io_priority); + + priv->init_data = nml_init_data_new_async(cancellable, g_steal_pointer(&task)); + + _init_start(self); +} + +static gboolean +init_finish(GAsyncInitable *initable, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(initable), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, initable, init_async), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/*****************************************************************************/ + +static gboolean +init_sync(GInitable *initable, GCancellable *cancellable, GError **error) +{ + gs_unref_object NMSecretAgentOld *self = NULL; + NMSecretAgentOldPrivate * priv; + NMSecretAgentOldClass * klass; + GMainLoop * main_loop; + GError * local_error = NULL; + + g_return_val_if_fail(NM_IS_SECRET_AGENT_OLD(initable), FALSE); + + self = g_object_ref(NM_SECRET_AGENT_OLD(initable)); + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + g_return_val_if_fail(!priv->dbus_context, FALSE); + g_return_val_if_fail(!priv->is_destroyed, FALSE); + + klass = NM_SECRET_AGENT_OLD_GET_CLASS(self); + g_return_val_if_fail(klass->get_secrets, FALSE); + g_return_val_if_fail(klass->cancel_get_secrets, FALSE); + g_return_val_if_fail(klass->save_secrets, FALSE); + g_return_val_if_fail(klass->delete_secrets, FALSE); + + _LOGT("init-sync"); + + /* See NMClient's sync-init method for explanation about why we create + * an internal GMainContext priv->dbus_context. */ + + priv->dbus_context = g_main_context_new(); + + g_main_context_push_thread_default(priv->dbus_context); + + main_loop = g_main_loop_new(priv->dbus_context, FALSE); + + priv->init_data = nml_init_data_new_sync(cancellable, main_loop, &local_error); + + _init_start(self); + + g_main_loop_run(main_loop); + + g_main_loop_unref(main_loop); + + g_main_context_pop_thread_default(priv->dbus_context); + + nm_context_busy_watcher_integrate_source(priv->main_context, + priv->dbus_context, + priv->context_busy_watcher); + + if (local_error) { + g_propagate_error(error, local_error); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_DBUS_CONNECTION: + g_value_set_object(value, priv->dbus_connection); + break; + case PROP_IDENTIFIER: + g_value_set_string(value, priv->identifier); + break; + case PROP_AUTO_REGISTER: + g_value_set_boolean(value, priv->auto_register); + break; + case PROP_REGISTERED: + g_value_set_boolean(value, priv->is_registered); + break; + case PROP_CAPABILITIES: + g_value_set_flags(value, priv->capabilities); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSecretAgentOld * self = NM_SECRET_AGENT_OLD(object); + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + guint u; + + switch (prop_id) { + case PROP_DBUS_CONNECTION: + /* construct-only */ + priv->dbus_connection = g_value_dup_object(value); + break; + case PROP_IDENTIFIER: + /* construct-only */ + priv->identifier = g_value_dup_string(value); + g_return_if_fail(validate_identifier(priv->identifier)); + break; + case PROP_AUTO_REGISTER: + /* construct */ + priv->auto_register = g_value_get_boolean(value); + priv->is_enabled = priv->auto_register; + _register_state_change(self); + break; + case PROP_CAPABILITIES: + /* construct */ + u = g_value_get_flags(value); + if (u != priv->capabilities) { + priv->capabilities = u; + priv->registration_force_unregister = TRUE; + _register_state_change(self); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_secret_agent_old_init(NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + _LOGT("create new instance"); + + c_list_init(&priv->gsi_lst_head); + c_list_init(&priv->pending_tasks_register_lst_head); + + priv->main_context = g_main_context_ref_thread_default(); + priv->context_busy_watcher = g_object_new(G_TYPE_OBJECT, NULL); +} + +static void +dispose(GObject *object) +{ + NMSecretAgentOld *self = NM_SECRET_AGENT_OLD(object); + + _LOGT("disposing"); + + _secret_agent_old_destroy(self); + + G_OBJECT_CLASS(nm_secret_agent_old_parent_class)->dispose(object); +} + +static void +finalize(GObject *object) +{ + NMSecretAgentOld * self = NM_SECRET_AGENT_OLD(object); + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE(self); + + _LOGT("finalizing"); + + if (priv->dbus_context) { + nml_cleanup_context_busy_watcher_on_idle(g_steal_pointer(&priv->context_busy_watcher), + priv->dbus_context); + } + + g_clear_object(&priv->dbus_connection); + nm_clear_pointer(&priv->dbus_context, g_main_context_unref); + nm_clear_pointer(&priv->main_context, g_main_context_unref); + + g_clear_object(&priv->context_busy_watcher); + + g_free(priv->identifier); + + G_OBJECT_CLASS(nm_secret_agent_old_parent_class)->finalize(object); +} + +static void +nm_secret_agent_old_class_init(NMSecretAgentOldClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(class); + + g_type_class_add_private(class, sizeof(NMSecretAgentOldPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + /** + * NMSecretAgentOld:dbus-connection: + * + * The #GDBusConnection used by the instance. You may either set this + * as construct-only property, or otherwise #NMSecretAgentOld will choose + * a connection via g_bus_get() during initialization. + * + * Since: 1.24 + **/ + obj_properties[PROP_DBUS_CONNECTION] = + g_param_spec_object(NM_SECRET_AGENT_OLD_DBUS_CONNECTION, + "", + "", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + /** + * NMSecretAgentOld:identifier: + * + * Identifies this agent; only one agent in each user session may use the + * same identifier. Identifier formatting follows the same rules as + * D-Bus bus names with the exception that the ':' character is not + * allowed. The valid set of characters is "[A-Z][a-z][0-9]_-." and the + * identifier is limited in length to 255 characters with a minimum + * of 3 characters. An example valid identifier is 'org.gnome.nm-applet' + * (without quotes). + **/ + obj_properties[PROP_IDENTIFIER] = + g_param_spec_string(NM_SECRET_AGENT_OLD_IDENTIFIER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + /** + * NMSecretAgentOld:auto-register: + * + * If %TRUE (the default), the agent will always be registered when + * NetworkManager is running; if NetworkManager exits and restarts, the + * agent will re-register itself automatically. + * + * In particular, if this property is %TRUE at construct time, then the + * agent will register itself with NetworkManager during + * construction/initialization and initialization will only complete + * after registration is completed (either successfully or unsuccessfully). + * Since 1.24, a failure to register will no longer cause initialization + * of #NMSecretAgentOld to fail. + * + * If the property is %FALSE, the agent will not automatically register with + * NetworkManager, and nm_secret_agent_old_enable() or + * nm_secret_agent_old_register_async() must be called to register it. + * + * Calling nm_secret_agent_old_enable() has the same effect as setting this + * property. + **/ + obj_properties[PROP_AUTO_REGISTER] = + g_param_spec_boolean(NM_SECRET_AGENT_OLD_AUTO_REGISTER, + "", + "", + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + + /** + * NMSecretAgentOld:registered: + * + * %TRUE if the agent is registered with NetworkManager, %FALSE if not. + **/ + obj_properties[PROP_REGISTERED] = + g_param_spec_boolean(NM_SECRET_AGENT_OLD_REGISTERED, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSecretAgentOld:capabilities: + * + * A bitfield of %NMSecretAgentCapabilities. + * + * Changing this property is possible at any time. In case the secret + * agent is currently registered, this will cause a re-registration. + **/ + obj_properties[PROP_CAPABILITIES] = + g_param_spec_flags(NM_SECRET_AGENT_OLD_CAPABILITIES, + "", + "", + NM_TYPE_SECRET_AGENT_CAPABILITIES, + NM_SECRET_AGENT_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} + +static void +nm_secret_agent_old_initable_iface_init(GInitableIface *iface) +{ + iface->init = init_sync; +} + +static void +nm_secret_agent_old_async_initable_iface_init(GAsyncInitableIface *iface) +{ + iface->init_async = init_async; + iface->init_finish = init_finish; +} diff --git a/src/libnm-client-impl/nm-settings-docs-gir.xml b/src/libnm-client-impl/nm-settings-docs-gir.xml new file mode 100644 index 0000000..1214267 --- /dev/null +++ b/src/libnm-client-impl/nm-settings-docs-gir.xml @@ -0,0 +1,529 @@ + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libnm-client-impl/nm-vpn-connection.c b/src/libnm-client-impl/nm-vpn-connection.c new file mode 100644 index 0000000..fb06153 --- /dev/null +++ b/src/libnm-client-impl/nm-vpn-connection.c @@ -0,0 +1,223 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-vpn-connection.h" + +#include "nm-dbus-interface.h" +#include "nm-utils.h" +#include "nm-object-private.h" +#include "nm-active-connection.h" +#include "nm-dbus-helpers.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMVpnConnection, PROP_VPN_STATE, PROP_BANNER, ); + +enum { + VPN_STATE_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +typedef struct { + char * banner; + guint32 vpn_state; + guint32 reason; +} NMVpnConnectionPrivate; + +struct _NMVpnConnection { + NMActiveConnection parent; + NMVpnConnectionPrivate _priv; +}; + +struct _NMVpnConnectionClass { + NMActiveConnectionClass parent; +}; + +G_DEFINE_TYPE(NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) + +#define NM_VPN_CONNECTION_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMVpnConnection, NM_IS_VPN_CONNECTION, NMObject, NMActiveConnection) + +G_STATIC_ASSERT(sizeof(NMVpnConnectionStateReason) == sizeof(NMActiveConnectionStateReason)); + +/*****************************************************************************/ + +/** + * nm_vpn_connection_get_banner: + * @vpn: a #NMVpnConnection + * + * Gets the VPN login banner of the active #NMVpnConnection. + * + * Returns: the VPN login banner of the VPN connection. This is the internal + * string used by the connection, and must not be modified. + **/ +const char * +nm_vpn_connection_get_banner(NMVpnConnection *vpn) +{ + g_return_val_if_fail(NM_IS_VPN_CONNECTION(vpn), NULL); + + return _nml_coerce_property_str_not_empty(NM_VPN_CONNECTION_GET_PRIVATE(vpn)->banner); +} + +/** + * nm_vpn_connection_get_vpn_state: + * @vpn: a #NMVpnConnection + * + * Gets the current #NMVpnConnection state. + * + * Returns: the VPN state of the active VPN connection. + **/ +NMVpnConnectionState +nm_vpn_connection_get_vpn_state(NMVpnConnection *vpn) +{ + g_return_val_if_fail(NM_IS_VPN_CONNECTION(vpn), NM_VPN_CONNECTION_STATE_UNKNOWN); + + return NM_VPN_CONNECTION_GET_PRIVATE(vpn)->vpn_state; +} + +/*****************************************************************************/ + +static void +_notify_event_state_changed(NMClient *client, NMClientNotifyEventWithPtr *notify_event) +{ + gs_unref_object NMVpnConnection *self = notify_event->user_data; + NMVpnConnectionPrivate * priv = NM_VPN_CONNECTION_GET_PRIVATE(self); + + /* we expose here the value cache in @priv. In practice, this is the same + * value as we received from the signal. In the unexpected case where they + * differ, the cached value of the current instance would still be more correct. */ + g_signal_emit(self, + signals[VPN_STATE_CHANGED], + 0, + (guint) priv->vpn_state, + (guint) priv->reason); +} + +void +_nm_vpn_connection_state_changed_commit(NMVpnConnection *self, guint32 state, guint32 reason) +{ + NMClient * client; + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self); + + client = _nm_object_get_client(self); + + if (priv->vpn_state != state) { + priv->vpn_state = state; + _nm_client_queue_notify_object(client, self, obj_properties[PROP_VPN_STATE]); + } + + priv->reason = reason; + + _nm_client_notify_event_queue_with_ptr(client, + NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP + 1, + _notify_event_state_changed, + g_object_ref(self)); +} + +/*****************************************************************************/ + +static void +nm_vpn_connection_init(NMVpnConnection *connection) +{} + +static void +finalize(GObject *object) +{ + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(object); + + g_free(priv->banner); + + G_OBJECT_CLASS(nm_vpn_connection_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMVpnConnection *self = NM_VPN_CONNECTION(object); + + switch (prop_id) { + case PROP_VPN_STATE: + g_value_set_enum(value, nm_vpn_connection_get_vpn_state(self)); + break; + case PROP_BANNER: + g_value_set_string(value, nm_vpn_connection_get_banner(self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_vpn_connection = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_VPN_CONNECTION, + nm_vpn_connection_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_S("Banner", PROP_BANNER, NMVpnConnection, _priv.banner), + NML_DBUS_META_PROPERTY_INIT_U("VpnState", + PROP_VPN_STATE, + NMVpnConnection, + _priv.vpn_state), ), ); + +static void +nm_vpn_connection_class_init(NMVpnConnectionClass *connection_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(connection_class); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + /** + * NMVpnConnection:vpn-state: + * + * The VPN state of the active VPN connection. + **/ + obj_properties[PROP_VPN_STATE] = g_param_spec_enum(NM_VPN_CONNECTION_VPN_STATE, + "", + "", + NM_TYPE_VPN_CONNECTION_STATE, + NM_VPN_CONNECTION_STATE_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMVpnConnection:banner: + * + * The VPN login banner of the active VPN connection. + **/ + obj_properties[PROP_BANNER] = g_param_spec_string(NM_VPN_CONNECTION_BANNER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, + &_nml_dbus_meta_iface_nm_vpn_connection); + + /* TODO: the state reason should also be exposed as a property in libnm's NMVpnConnection, + * like done for NMDevice's state reason. */ + + /* TODO: the D-Bus API should also expose the state-reason as a property instead of + * a "VpnStateChanged" signal. Like done for Device's "StateReason". */ + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + signals[VPN_STATE_CHANGED] = g_signal_new("vpn-state-changed", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_UINT, + G_TYPE_UINT); + G_GNUC_END_IGNORE_DEPRECATIONS +} diff --git a/src/libnm-client-impl/nm-vpn-editor.c b/src/libnm-client-impl/nm-vpn-editor.c new file mode 100644 index 0000000..57aa8b0 --- /dev/null +++ b/src/libnm-client-impl/nm-vpn-editor.c @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-vpn-editor.h" + +static void nm_vpn_editor_default_init(NMVpnEditorInterface *iface); + +G_DEFINE_INTERFACE(NMVpnEditor, nm_vpn_editor, G_TYPE_OBJECT) + +static void +nm_vpn_editor_default_init(NMVpnEditorInterface *iface) +{ + GType iface_type = G_TYPE_FROM_INTERFACE(iface); + + /* Signals */ + g_signal_new("changed", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnEditorInterface, changed), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +/** + * nm_vpn_editor_get_widget: + * @editor: the #NMVpnEditor + * + * Returns: (transfer none): + */ +GObject * +nm_vpn_editor_get_widget(NMVpnEditor *editor) +{ + g_return_val_if_fail(NM_IS_VPN_EDITOR(editor), NULL); + + return NM_VPN_EDITOR_GET_INTERFACE(editor)->get_widget(editor); +} + +gboolean +nm_vpn_editor_update_connection(NMVpnEditor *editor, NMConnection *connection, GError **error) +{ + g_return_val_if_fail(NM_IS_VPN_EDITOR(editor), FALSE); + + if (error) + g_return_val_if_fail(*error == NULL, FALSE); + + return NM_VPN_EDITOR_GET_INTERFACE(editor)->update_connection(editor, connection, error); +} diff --git a/src/libnm-client-impl/nm-vpn-plugin-old.c b/src/libnm-client-impl/nm-vpn-plugin-old.c new file mode 100644 index 0000000..be4e1cf --- /dev/null +++ b/src/libnm-client-impl/nm-vpn-plugin-old.c @@ -0,0 +1,1137 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2008 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-vpn-plugin-old.h" + +#include +#include + +#include "nm-enum-types.h" +#include "nm-utils.h" +#include "nm-connection.h" +#include "nm-dbus-helpers.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-simple-connection.h" +#include "nm-vpn-service-plugin.h" + +#include "introspection/org.freedesktop.NetworkManager.VPN.Plugin.h" + +#define NM_VPN_PLUGIN_OLD_QUIT_TIMER 180 + +static void nm_vpn_plugin_old_initable_iface_init(GInitableIface *iface); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE(NMVpnPluginOld, + nm_vpn_plugin_old, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE, + nm_vpn_plugin_old_initable_iface_init);) + +typedef struct { + NMVpnServiceState state; + + /* DBUS-y stuff */ + GDBusConnection *connection; + NMDBusVpnPlugin *dbus_vpn_plugin_old; + char * dbus_service_name; + + /* Temporary stuff */ + guint connect_timer; + guint quit_timer; + guint fail_stop_id; + gboolean interactive; + + gboolean got_config; + gboolean has_ip4, got_ip4; + gboolean has_ip6, got_ip6; + + /* Config stuff copied from config to ip4config */ + GVariant *banner, *tundev, *gateway, *mtu; +} NMVpnPluginOldPrivate; + +#define NM_VPN_PLUGIN_OLD_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOldPrivate)) + +enum { + STATE_CHANGED, + CONFIG, + IP4_CONFIG, + IP6_CONFIG, + LOGIN_BANNER, + FAILURE, + QUIT, + SECRETS_REQUIRED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DBUS_SERVICE_NAME, PROP_STATE, ); + +static GSList *active_plugins = NULL; + +static void +nm_vpn_plugin_old_set_connection(NMVpnPluginOld *plugin, GDBusConnection *connection) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + + g_clear_object(&priv->connection); + + if (connection) + priv->connection = g_object_ref(connection); +} + +/** + * nm_vpn_plugin_old_get_connection: + * + * Returns: (transfer full): + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ +GDBusConnection * +nm_vpn_plugin_old_get_connection(NMVpnPluginOld *plugin) +{ + GDBusConnection *connection; + + g_return_val_if_fail(NM_IS_VPN_PLUGIN_OLD(plugin), NULL); + + connection = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin)->connection; + + if (connection) + g_object_ref(connection); + + return connection; +} + +/** + * nm_vpn_plugin_old_get_state: + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ +NMVpnServiceState +nm_vpn_plugin_old_get_state(NMVpnPluginOld *plugin) +{ + g_return_val_if_fail(NM_IS_VPN_PLUGIN_OLD(plugin), NM_VPN_SERVICE_STATE_UNKNOWN); + + return NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin)->state; +} + +/** + * nm_vpn_plugin_old_set_state: + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ +void +nm_vpn_plugin_old_set_state(NMVpnPluginOld *plugin, NMVpnServiceState state) +{ + NMVpnPluginOldPrivate *priv; + + g_return_if_fail(NM_IS_VPN_PLUGIN_OLD(plugin)); + + priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + if (priv->state != state) { + priv->state = state; + g_signal_emit(plugin, signals[STATE_CHANGED], 0, state); + } +} + +/** + * nm_vpn_plugin_old_set_login_banner: + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ +void +nm_vpn_plugin_old_set_login_banner(NMVpnPluginOld *plugin, const char *banner) +{ + g_return_if_fail(NM_IS_VPN_PLUGIN_OLD(plugin)); + g_return_if_fail(banner != NULL); + + g_signal_emit(plugin, signals[LOGIN_BANNER], 0, banner); +} + +/** + * nm_vpn_plugin_old_failure: + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ +void +nm_vpn_plugin_old_failure(NMVpnPluginOld *plugin, NMVpnPluginFailure reason) +{ + g_return_if_fail(NM_IS_VPN_PLUGIN_OLD(plugin)); + + g_signal_emit(plugin, signals[FAILURE], 0, reason); +} + +/** + * nm_vpn_plugin_old_disconnect: + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ +gboolean +nm_vpn_plugin_old_disconnect(NMVpnPluginOld *plugin, GError **err) +{ + gboolean ret = FALSE; + NMVpnServiceState state; + + g_return_val_if_fail(NM_IS_VPN_PLUGIN_OLD(plugin), FALSE); + + state = nm_vpn_plugin_old_get_state(plugin); + switch (state) { + case NM_VPN_SERVICE_STATE_STOPPING: + g_set_error( + err, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, + "%s", + "Could not process the request because the VPN connection is already being stopped."); + break; + case NM_VPN_SERVICE_STATE_STOPPED: + g_set_error(err, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, + "%s", + "Could not process the request because no VPN connection was active."); + break; + case NM_VPN_SERVICE_STATE_STARTING: + case NM_VPN_SERVICE_STATE_STARTED: + nm_vpn_plugin_old_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPING); + ret = NM_VPN_PLUGIN_OLD_GET_CLASS(plugin)->disconnect(plugin, err); + nm_vpn_plugin_old_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPED); + break; + case NM_VPN_SERVICE_STATE_INIT: + ret = TRUE; + break; + + default: + g_warning("Unhandled VPN service state %d", state); + g_assert_not_reached(); + break; + } + + return ret; +} + +static void +nm_vpn_plugin_old_emit_quit(NMVpnPluginOld *plugin) +{ + g_signal_emit(plugin, signals[QUIT], 0); +} + +static gboolean +connect_timer_expired(gpointer data) +{ + NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD(data); + GError * err = NULL; + + NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin)->connect_timer = 0; + g_message("Connect timer expired, disconnecting."); + nm_vpn_plugin_old_disconnect(plugin, &err); + if (err) { + g_warning("Disconnect failed: %s", err->message); + g_error_free(err); + } + + return G_SOURCE_REMOVE; +} + +static gboolean +quit_timer_expired(gpointer data) +{ + NMVpnPluginOld *self = NM_VPN_PLUGIN_OLD(data); + + NM_VPN_PLUGIN_OLD_GET_PRIVATE(self)->quit_timer = 0; + nm_vpn_plugin_old_emit_quit(self); + return G_SOURCE_REMOVE; +} + +static void +schedule_quit_timer(NMVpnPluginOld *self) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(self); + + nm_clear_g_source(&priv->quit_timer); + priv->quit_timer = + g_timeout_add_seconds(NM_VPN_PLUGIN_OLD_QUIT_TIMER, quit_timer_expired, self); +} + +static gboolean +fail_stop(gpointer data) +{ + NMVpnPluginOld *self = NM_VPN_PLUGIN_OLD(data); + + NM_VPN_PLUGIN_OLD_GET_PRIVATE(self)->fail_stop_id = 0; + nm_vpn_plugin_old_set_state(self, NM_VPN_SERVICE_STATE_STOPPED); + return G_SOURCE_REMOVE; +} + +static void +schedule_fail_stop(NMVpnPluginOld *plugin, guint timeout_secs) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + + nm_clear_g_source(&priv->fail_stop_id); + if (timeout_secs) + priv->fail_stop_id = g_timeout_add_seconds(timeout_secs, fail_stop, plugin); + else + priv->fail_stop_id = g_idle_add(fail_stop, plugin); +} + +/** + * nm_vpn_plugin_old_set_config: + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ +void +nm_vpn_plugin_old_set_config(NMVpnPluginOld *plugin, GVariant *config) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + + g_return_if_fail(NM_IS_VPN_PLUGIN_OLD(plugin)); + g_return_if_fail(config != NULL); + + priv->got_config = TRUE; + + (void) g_variant_lookup(config, NM_VPN_PLUGIN_CONFIG_HAS_IP4, "b", &priv->has_ip4); + (void) g_variant_lookup(config, NM_VPN_PLUGIN_CONFIG_HAS_IP6, "b", &priv->has_ip6); + + g_warn_if_fail(priv->has_ip4 || priv->has_ip6); + + /* Record the items that need to also be inserted into the + * ip4config, for compatibility with older daemons. + */ + if (priv->banner) + g_variant_unref(priv->banner); + priv->banner = g_variant_lookup_value(config, NM_VPN_PLUGIN_CONFIG_BANNER, G_VARIANT_TYPE("s")); + if (priv->tundev) + g_variant_unref(priv->tundev); + priv->tundev = g_variant_lookup_value(config, NM_VPN_PLUGIN_CONFIG_TUNDEV, G_VARIANT_TYPE("s")); + if (priv->gateway) + g_variant_unref(priv->gateway); + priv->gateway = + g_variant_lookup_value(config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, G_VARIANT_TYPE("u")); + if (priv->mtu) + g_variant_unref(priv->mtu); + priv->mtu = g_variant_lookup_value(config, NM_VPN_PLUGIN_CONFIG_MTU, G_VARIANT_TYPE("u")); + + g_signal_emit(plugin, signals[CONFIG], 0, config); +} + +/** + * nm_vpn_plugin_old_set_ip4_config: + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ +void +nm_vpn_plugin_old_set_ip4_config(NMVpnPluginOld *plugin, GVariant *ip4_config) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + GVariant * combined_config; + GVariantBuilder builder; + GVariantIter iter; + const char * key; + GVariant * value; + + g_return_if_fail(NM_IS_VPN_PLUGIN_OLD(plugin)); + g_return_if_fail(ip4_config != NULL); + + priv->got_ip4 = TRUE; + + /* Old plugins won't send the "config" signal and thus can't send + * NM_VPN_PLUGIN_OLD_CONFIG_HAS_IP4 either. But since they don't support IPv6, + * we can safely assume that, if we don't receive a "config" signal but do + * receive an "ip4-config" signal, the old plugin supports IPv4. + */ + if (!priv->got_config) + priv->has_ip4 = TRUE; + + /* Older NetworkManager daemons expect all config info to be in + * the ip4 config, so they won't even notice the "config" signal + * being emitted. So just copy all of that data into the ip4 + * config too. + */ + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + g_variant_iter_init(&iter, ip4_config); + while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) { + g_variant_builder_add(&builder, "{sv}", key, value); + g_variant_unref(value); + } + + if (priv->banner) + g_variant_builder_add(&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_BANNER, &priv->banner); + if (priv->tundev) + g_variant_builder_add(&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, &priv->tundev); + if (priv->gateway) + g_variant_builder_add(&builder, + "{sv}", + NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, + &priv->gateway); + if (priv->mtu) + g_variant_builder_add(&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_MTU, &priv->mtu); + + combined_config = g_variant_builder_end(&builder); + g_variant_ref_sink(combined_config); + g_signal_emit(plugin, signals[IP4_CONFIG], 0, combined_config); + g_variant_unref(combined_config); + + if (priv->has_ip4 == priv->got_ip4 && priv->has_ip6 == priv->got_ip6) + nm_vpn_plugin_old_set_state(plugin, NM_VPN_SERVICE_STATE_STARTED); +} + +/** + * nm_vpn_plugin_old_set_ip6_config: + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ +void +nm_vpn_plugin_old_set_ip6_config(NMVpnPluginOld *plugin, GVariant *ip6_config) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + + g_return_if_fail(NM_IS_VPN_PLUGIN_OLD(plugin)); + g_return_if_fail(ip6_config != NULL); + + g_variant_ref_sink(ip6_config); + + priv->got_ip6 = TRUE; + g_signal_emit(plugin, signals[IP6_CONFIG], 0, ip6_config); + + g_variant_unref(ip6_config); + + if (priv->has_ip4 == priv->got_ip4 && priv->has_ip6 == priv->got_ip6) + nm_vpn_plugin_old_set_state(plugin, NM_VPN_SERVICE_STATE_STARTED); +} + +static void +connect_timer_start(NMVpnPluginOld *plugin) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + + priv->connect_timer = g_timeout_add_seconds(60, connect_timer_expired, plugin); +} + +static void +_connect_generic(NMVpnPluginOld * plugin, + GDBusMethodInvocation *context, + GVariant * properties, + GVariant * details) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + NMVpnPluginOldClass * vpn_class = NM_VPN_PLUGIN_OLD_GET_CLASS(plugin); + NMConnection * connection; + gboolean success = FALSE; + GError * error = NULL; + guint fail_stop_timeout = 0; + + if (priv->state != NM_VPN_SERVICE_STATE_STOPPED && priv->state != NM_VPN_SERVICE_STATE_INIT) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not start connection: wrong plugin state %d", + priv->state); + return; + } + + connection = + _nm_simple_connection_new_from_dbus(properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); + if (!connection) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: %s", + error->message); + g_clear_error(&error); + } + + priv->interactive = FALSE; + if (details && !vpn_class->connect_interactive) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Plugin does not implement ConnectInteractive()"); + return; + } + + nm_clear_g_source(&priv->fail_stop_id); + + if (details) { + priv->interactive = TRUE; + success = vpn_class->connect_interactive(plugin, connection, details, &error); + if (g_error_matches(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED)) { + /* Give NetworkManager a bit of time to fall back to Connect() */ + fail_stop_timeout = 5; + } + } else + success = vpn_class->connect(plugin, connection, &error); + + if (success) { + nm_vpn_plugin_old_set_state(plugin, NM_VPN_SERVICE_STATE_STARTING); + + g_dbus_method_invocation_return_value(context, NULL); + + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ + connect_timer_start(plugin); + } else { + g_dbus_method_invocation_take_error(context, error); + + /* Stop the plugin from an idle handler so that the Connect + * method return gets sent before the STOP StateChanged signal. + */ + schedule_fail_stop(plugin, fail_stop_timeout); + } + + g_object_unref(connection); +} + +static void +impl_vpn_plugin_old_connect(NMVpnPluginOld * plugin, + GDBusMethodInvocation *context, + GVariant * connection, + gpointer user_data) +{ + _connect_generic(plugin, context, connection, NULL); +} + +static void +impl_vpn_plugin_old_connect_interactive(NMVpnPluginOld * plugin, + GDBusMethodInvocation *context, + GVariant * connection, + GVariant * details, + gpointer user_data) +{ + _connect_generic(plugin, context, connection, details); +} + +/*****************************************************************************/ + +static void +impl_vpn_plugin_old_need_secrets(NMVpnPluginOld * plugin, + GDBusMethodInvocation *context, + GVariant * properties, + gpointer user_data) +{ + NMConnection *connection; + const char * setting_name; + gboolean needed; + GError * error = NULL; + + connection = + _nm_simple_connection_new_from_dbus(properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); + if (!connection) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION, + "The connection was invalid: %s", + error->message); + g_error_free(error); + return; + } + + if (!NM_VPN_PLUGIN_OLD_GET_CLASS(plugin)->need_secrets) { + g_dbus_method_invocation_return_value(context, g_variant_new("(s)", "")); + return; + } + + needed = NM_VPN_PLUGIN_OLD_GET_CLASS(plugin)->need_secrets(plugin, + connection, + &setting_name, + &error); + if (error) { + g_dbus_method_invocation_take_error(context, error); + return; + } + + if (needed) { + /* Push back the quit timer so the VPN plugin doesn't quit in the + * middle of asking the user for secrets. + */ + schedule_quit_timer(plugin); + + g_assert(setting_name); + g_dbus_method_invocation_return_value(context, g_variant_new("(s)", setting_name)); + } else { + /* No secrets required */ + g_dbus_method_invocation_return_value(context, g_variant_new("(s)", "")); + } +} + +static void +impl_vpn_plugin_old_new_secrets(NMVpnPluginOld * plugin, + GDBusMethodInvocation *context, + GVariant * properties, + gpointer user_data) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + NMConnection * connection; + GError * error = NULL; + gboolean success; + + if (priv->state != NM_VPN_SERVICE_STATE_STARTING) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not accept new secrets: wrong plugin state %d", + priv->state); + return; + } + + connection = + _nm_simple_connection_new_from_dbus(properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); + if (!connection) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: %s", + error->message); + g_clear_error(&error); + return; + } + + if (!NM_VPN_PLUGIN_OLD_GET_CLASS(plugin)->new_secrets) { + g_dbus_method_invocation_return_error( + context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Could not accept new secrets: plugin cannot process interactive secrets"); + g_object_unref(connection); + return; + } + + success = NM_VPN_PLUGIN_OLD_GET_CLASS(plugin)->new_secrets(plugin, connection, &error); + if (success) { + g_dbus_method_invocation_return_value(context, NULL); + + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ + connect_timer_start(plugin); + } else { + g_dbus_method_invocation_take_error(context, error); + + /* Stop the plugin from and idle handler so that the NewSecrets + * method return gets sent before the STOP StateChanged signal. + */ + schedule_fail_stop(plugin, 0); + } + + g_object_unref(connection); +} + +/** + * nm_vpn_plugin_old_secrets_required: + * @plugin: the #NMVpnPluginOld + * @message: an information message about why secrets are required, if any + * @hints: VPN specific secret names for required new secrets + * + * Called by VPN plugin implementations to signal to NetworkManager that secrets + * are required during the connection process. This signal may be used to + * request new secrets when the secrets originally provided by NetworkManager + * are insufficient, or the VPN process indicates that it needs additional + * information to complete the request. + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ +void +nm_vpn_plugin_old_secrets_required(NMVpnPluginOld *plugin, const char *message, const char **hints) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + + /* Plugin must be able to accept the new secrets if it calls this method */ + g_return_if_fail(NM_VPN_PLUGIN_OLD_GET_CLASS(plugin)->new_secrets); + + /* Plugin cannot call this method if NetworkManager didn't originally call + * ConnectInteractive(). + */ + g_return_if_fail(priv->interactive == TRUE); + + /* Cancel the connect timer since secrets might take a while. It'll + * get restarted when the secrets come back via NewSecrets(). + */ + nm_clear_g_source(&priv->connect_timer); + + g_signal_emit(plugin, signals[SECRETS_REQUIRED], 0, message, hints); +} + +/*****************************************************************************/ + +/** + * nm_vpn_plugin_old_read_vpn_details: + * @fd: file descriptor to read from, usually stdin (0) + * @out_data: (out) (transfer full): on successful return, a hash table + * (mapping char*:char*) containing the key/value pairs of VPN data items + * @out_secrets: (out) (transfer full): on successful return, a hash table + * (mapping char*:char*) containing the key/value pairsof VPN secrets + * + * Parses key/value pairs from a file descriptor (normally stdin) passed by + * an applet when the applet calls the authentication dialog of the VPN plugin. + * + * Returns: %TRUE if reading values was successful, %FALSE if not + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + **/ +gboolean +nm_vpn_plugin_old_read_vpn_details(int fd, GHashTable **out_data, GHashTable **out_secrets) +{ + return nm_vpn_service_plugin_read_vpn_details(fd, out_data, out_secrets); +} + +/** + * nm_vpn_plugin_old_get_secret_flags: + * @data: hash table containing VPN key/value pair data items + * @secret_name: VPN secret key name for which to retrieve flags for + * @out_flags: (out): on success, the flags associated with @secret_name + * + * Given a VPN secret key name, attempts to find the corresponding flags data + * item in @data. If found, converts the flags data item to + * #NMSettingSecretFlags and returns it. + * + * Returns: %TRUE if the flag data item was found and successfully converted + * to flags, %FALSE if not + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + **/ +gboolean +nm_vpn_plugin_old_get_secret_flags(GHashTable * data, + const char * secret_name, + NMSettingSecretFlags *out_flags) +{ + return nm_vpn_service_plugin_get_secret_flags(data, secret_name, out_flags); +} + +/*****************************************************************************/ + +static void +impl_vpn_plugin_old_disconnect(NMVpnPluginOld * plugin, + GDBusMethodInvocation *context, + gpointer user_data) +{ + GError *error = NULL; + + if (nm_vpn_plugin_old_disconnect(plugin, &error)) + g_dbus_method_invocation_return_value(context, NULL); + else + g_dbus_method_invocation_take_error(context, error); +} + +static void +impl_vpn_plugin_old_set_config(NMVpnPluginOld * plugin, + GDBusMethodInvocation *context, + GVariant * config, + gpointer user_data) +{ + nm_vpn_plugin_old_set_config(plugin, config); + g_dbus_method_invocation_return_value(context, NULL); +} + +static void +impl_vpn_plugin_old_set_ip4_config(NMVpnPluginOld * plugin, + GDBusMethodInvocation *context, + GVariant * config, + gpointer user_data) +{ + nm_vpn_plugin_old_set_ip4_config(plugin, config); + g_dbus_method_invocation_return_value(context, NULL); +} + +static void +impl_vpn_plugin_old_set_ip6_config(NMVpnPluginOld * plugin, + GDBusMethodInvocation *context, + GVariant * config, + gpointer user_data) +{ + nm_vpn_plugin_old_set_ip6_config(plugin, config); + g_dbus_method_invocation_return_value(context, NULL); +} + +static void +impl_vpn_plugin_old_set_failure(NMVpnPluginOld * plugin, + GDBusMethodInvocation *context, + char * reason, + gpointer user_data) +{ + nm_vpn_plugin_old_failure(plugin, NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG); + g_dbus_method_invocation_return_value(context, NULL); +} + +/*****************************************************************************/ + +static void +_emit_quit(gpointer data, gpointer user_data) +{ + NMVpnPluginOld *plugin = data; + + nm_vpn_plugin_old_emit_quit(plugin); +} + +static void +sigterm_handler(int signum) +{ + g_slist_foreach(active_plugins, _emit_quit, NULL); +} + +static void +setup_unix_signal_handler(void) +{ + struct sigaction action; + sigset_t block_mask; + + action.sa_handler = sigterm_handler; + sigemptyset(&block_mask); + action.sa_mask = block_mask; + action.sa_flags = 0; + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); +} + +/*****************************************************************************/ + +static void +one_plugin_destroyed(gpointer data, GObject *object) +{ + active_plugins = g_slist_remove(active_plugins, object); +} + +static void +nm_vpn_plugin_old_init(NMVpnPluginOld *plugin) +{ + active_plugins = g_slist_append(active_plugins, plugin); + g_object_weak_ref(G_OBJECT(plugin), one_plugin_destroyed, NULL); +} + +static gboolean +init_sync(GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMVpnPluginOld * plugin = NM_VPN_PLUGIN_OLD(initable); + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + GDBusConnection * connection = NULL; + GDBusProxy * proxy; + GVariant * ret; + gboolean success = FALSE; + + if (!priv->dbus_service_name) { + g_set_error_literal(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("No service name specified")); + return FALSE; + } + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, error); + if (!connection) + return FALSE; + + proxy = g_dbus_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + cancellable, + error); + if (!proxy) + goto out; + + ret = g_dbus_proxy_call_sync(proxy, + "RequestName", + g_variant_new("(su)", priv->dbus_service_name, 0), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + error); + g_object_unref(proxy); + if (!ret) { + if (error && *error) + g_dbus_error_strip_remote_error(*error); + goto out; + } + g_variant_unref(ret); + + priv->dbus_vpn_plugin_old = nmdbus_vpn_plugin_skeleton_new(); + if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(priv->dbus_vpn_plugin_old), + connection, + NM_VPN_DBUS_PLUGIN_PATH, + error)) + goto out; + + _nm_dbus_bind_properties(plugin, priv->dbus_vpn_plugin_old); + _nm_dbus_bind_methods(plugin, + priv->dbus_vpn_plugin_old, + "Connect", + impl_vpn_plugin_old_connect, + "ConnectInteractive", + impl_vpn_plugin_old_connect_interactive, + "NeedSecrets", + impl_vpn_plugin_old_need_secrets, + "NewSecrets", + impl_vpn_plugin_old_new_secrets, + "Disconnect", + impl_vpn_plugin_old_disconnect, + "SetConfig", + impl_vpn_plugin_old_set_config, + "SetIp4Config", + impl_vpn_plugin_old_set_ip4_config, + "SetIp6Config", + impl_vpn_plugin_old_set_ip6_config, + "SetFailure", + impl_vpn_plugin_old_set_failure, + NULL); + + nm_vpn_plugin_old_set_connection(plugin, connection); + nm_vpn_plugin_old_set_state(plugin, NM_VPN_SERVICE_STATE_INIT); + + success = TRUE; + +out: + g_clear_object(&connection); + + return success; +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_DBUS_SERVICE_NAME: + /* construct-only */ + priv->dbus_service_name = g_value_dup_string(value); + break; + case PROP_STATE: + nm_vpn_plugin_old_set_state(NM_VPN_PLUGIN_OLD(object), + (NMVpnServiceState) g_value_get_enum(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_DBUS_SERVICE_NAME: + g_value_set_string(value, priv->dbus_service_name); + break; + case PROP_STATE: + g_value_set_enum(value, nm_vpn_plugin_old_get_state(NM_VPN_PLUGIN_OLD(object))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +dispose(GObject *object) +{ + NMVpnPluginOld * plugin = NM_VPN_PLUGIN_OLD(object); + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + NMVpnServiceState state; + GError * err = NULL; + + nm_clear_g_source(&priv->fail_stop_id); + nm_clear_g_source(&priv->quit_timer); + nm_clear_g_source(&priv->connect_timer); + + state = nm_vpn_plugin_old_get_state(plugin); + + if (state == NM_VPN_SERVICE_STATE_STARTED || state == NM_VPN_SERVICE_STATE_STARTING) + nm_vpn_plugin_old_disconnect(plugin, &err); + + if (err) { + g_warning("Error disconnecting VPN connection: %s", err->message); + g_error_free(err); + } + + G_OBJECT_CLASS(nm_vpn_plugin_old_parent_class)->dispose(object); +} + +static void +finalize(GObject *object) +{ + NMVpnPluginOld * plugin = NM_VPN_PLUGIN_OLD(object); + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + + nm_vpn_plugin_old_set_connection(plugin, NULL); + g_free(priv->dbus_service_name); + + nm_clear_pointer(&priv->banner, g_variant_unref); + nm_clear_pointer(&priv->tundev, g_variant_unref); + nm_clear_pointer(&priv->gateway, g_variant_unref); + nm_clear_pointer(&priv->mtu, g_variant_unref); + + G_OBJECT_CLASS(nm_vpn_plugin_old_parent_class)->finalize(object); +} + +static void +state_changed(NMVpnPluginOld *plugin, NMVpnServiceState state) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE(plugin); + + switch (state) { + case NM_VPN_SERVICE_STATE_STARTING: + nm_clear_g_source(&priv->quit_timer); + nm_clear_g_source(&priv->fail_stop_id); + break; + case NM_VPN_SERVICE_STATE_STOPPED: + schedule_quit_timer(plugin); + break; + default: + /* Clean up all timers we might have set up. */ + nm_clear_g_source(&priv->connect_timer); + nm_clear_g_source(&priv->quit_timer); + nm_clear_g_source(&priv->fail_stop_id); + break; + } +} + +static void +nm_vpn_plugin_old_class_init(NMVpnPluginOldClass *plugin_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(plugin_class); + + g_type_class_add_private(object_class, sizeof(NMVpnPluginOldPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + plugin_class->state_changed = state_changed; + + /** + * NMVpnPluginOld:service-name: + * + * The D-Bus service name of this plugin. + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ + obj_properties[PROP_DBUS_SERVICE_NAME] = + g_param_spec_string(NM_VPN_PLUGIN_OLD_DBUS_SERVICE_NAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + /** + * NMVpnPluginOld:state: + * + * The state of the plugin. + * + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. + */ + obj_properties[PROP_STATE] = g_param_spec_enum(NM_VPN_PLUGIN_OLD_STATE, + "", + "", + NM_TYPE_VPN_SERVICE_STATE, + NM_VPN_SERVICE_STATE_INIT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + signals[STATE_CHANGED] = g_signal_new("state-changed", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnPluginOldClass, state_changed), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_UINT); + + signals[SECRETS_REQUIRED] = g_signal_new("secrets-required", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_STRV); + + signals[CONFIG] = g_signal_new("config", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnPluginOldClass, config), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_VARIANT); + + signals[IP4_CONFIG] = g_signal_new("ip4-config", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnPluginOldClass, ip4_config), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_VARIANT); + + signals[IP6_CONFIG] = g_signal_new("ip6-config", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnPluginOldClass, ip6_config), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_VARIANT); + + signals[LOGIN_BANNER] = g_signal_new("login-banner", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnPluginOldClass, login_banner), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + + signals[FAILURE] = g_signal_new("failure", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnPluginOldClass, failure), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_UINT); + + signals[QUIT] = g_signal_new("quit", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnPluginOldClass, quit), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0, + G_TYPE_NONE); + + setup_unix_signal_handler(); +} + +static void +nm_vpn_plugin_old_initable_iface_init(GInitableIface *iface) +{ + iface->init = init_sync; +} diff --git a/src/libnm-client-impl/nm-vpn-service-plugin.c b/src/libnm-client-impl/nm-vpn-service-plugin.c new file mode 100644 index 0000000..74e9e24 --- /dev/null +++ b/src/libnm-client-impl/nm-vpn-service-plugin.c @@ -0,0 +1,1335 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2015 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-vpn-service-plugin.h" + +#include +#include + +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "nm-enum-types.h" +#include "nm-utils.h" +#include "nm-connection.h" +#include "nm-dbus-helpers.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-simple-connection.h" + +#include "introspection/org.freedesktop.NetworkManager.VPN.Plugin.h" + +#define NM_VPN_SERVICE_PLUGIN_QUIT_TIMER 180 + +static void nm_vpn_service_plugin_initable_iface_init(GInitableIface *iface); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE(NMVpnServicePlugin, + nm_vpn_service_plugin, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE, + nm_vpn_service_plugin_initable_iface_init);) + +typedef struct { + NMVpnServiceState state; + + /* DBUS-y stuff */ + GDBusConnection *connection; + NMDBusVpnPlugin *dbus_vpn_service_plugin; + char * dbus_service_name; + gboolean dbus_watch_peer; + + /* Temporary stuff */ + guint connect_timer; + guint quit_timer; + guint fail_stop_id; + guint peer_watch_id; + gboolean interactive; + + gboolean got_config; + gboolean has_ip4, got_ip4; + gboolean has_ip6, got_ip6; + + /* Config stuff copied from config to ip4config */ + GVariant *banner, *tundev, *gateway, *mtu; +} NMVpnServicePluginPrivate; + +#define NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePluginPrivate)) + +enum { + STATE_CHANGED, + CONFIG, + IP4_CONFIG, + IP6_CONFIG, + LOGIN_BANNER, + FAILURE, + QUIT, + SECRETS_REQUIRED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DBUS_SERVICE_NAME, PROP_DBUS_WATCH_PEER, PROP_STATE, ); + +static GSList *active_plugins = NULL; + +static void +nm_vpn_service_plugin_set_connection(NMVpnServicePlugin *plugin, GDBusConnection *connection) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + g_clear_object(&priv->connection); + + if (connection) + priv->connection = g_object_ref(connection); +} + +/** + * nm_vpn_service_plugin_get_connection: + * + * Returns: (transfer full): + * + * Since: 1.2 + */ +GDBusConnection * +nm_vpn_service_plugin_get_connection(NMVpnServicePlugin *plugin) +{ + GDBusConnection *connection; + + g_return_val_if_fail(NM_IS_VPN_SERVICE_PLUGIN(plugin), NULL); + + connection = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin)->connection; + + if (connection) + g_object_ref(connection); + + return connection; +} + +static NMVpnServiceState +nm_vpn_service_plugin_get_state(NMVpnServicePlugin *plugin) +{ + g_return_val_if_fail(NM_IS_VPN_SERVICE_PLUGIN(plugin), NM_VPN_SERVICE_STATE_UNKNOWN); + + return NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin)->state; +} + +static void +nm_vpn_service_plugin_set_state(NMVpnServicePlugin *plugin, NMVpnServiceState state) +{ + NMVpnServicePluginPrivate *priv; + + g_return_if_fail(NM_IS_VPN_SERVICE_PLUGIN(plugin)); + + priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + if (priv->state != state) { + priv->state = state; + g_signal_emit(plugin, signals[STATE_CHANGED], 0, state); + if (priv->dbus_vpn_service_plugin) + nmdbus_vpn_plugin_emit_state_changed(priv->dbus_vpn_service_plugin, state); + } +} + +void +nm_vpn_service_plugin_set_login_banner(NMVpnServicePlugin *plugin, const char *banner) +{ + NMVpnServicePluginPrivate *priv; + + g_return_if_fail(NM_IS_VPN_SERVICE_PLUGIN(plugin)); + g_return_if_fail(banner != NULL); + + priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + g_signal_emit(plugin, signals[LOGIN_BANNER], 0, banner); + if (priv->dbus_vpn_service_plugin) + nmdbus_vpn_plugin_emit_login_banner(priv->dbus_vpn_service_plugin, banner); +} + +static void +_emit_failure(NMVpnServicePlugin *plugin, NMVpnPluginFailure reason) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + g_signal_emit(plugin, signals[FAILURE], 0, reason); + if (priv->dbus_vpn_service_plugin) + nmdbus_vpn_plugin_emit_failure(priv->dbus_vpn_service_plugin, reason); +} + +void +nm_vpn_service_plugin_failure(NMVpnServicePlugin *plugin, NMVpnPluginFailure reason) +{ + g_return_if_fail(NM_IS_VPN_SERVICE_PLUGIN(plugin)); + + _emit_failure(plugin, reason); + nm_vpn_service_plugin_disconnect(plugin, NULL); +} + +gboolean +nm_vpn_service_plugin_disconnect(NMVpnServicePlugin *plugin, GError **err) +{ + gboolean ret = FALSE; + NMVpnServiceState state; + + g_return_val_if_fail(NM_IS_VPN_SERVICE_PLUGIN(plugin), FALSE); + + state = nm_vpn_service_plugin_get_state(plugin); + switch (state) { + case NM_VPN_SERVICE_STATE_STOPPING: + g_set_error( + err, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, + "%s", + "Could not process the request because the VPN connection is already being stopped."); + break; + case NM_VPN_SERVICE_STATE_STOPPED: + g_set_error(err, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, + "%s", + "Could not process the request because no VPN connection was active."); + break; + case NM_VPN_SERVICE_STATE_STARTING: + _emit_failure(plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED); + /* fall-through */ + case NM_VPN_SERVICE_STATE_STARTED: + nm_vpn_service_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPING); + ret = NM_VPN_SERVICE_PLUGIN_GET_CLASS(plugin)->disconnect(plugin, err); + nm_vpn_service_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPED); + break; + case NM_VPN_SERVICE_STATE_INIT: + ret = TRUE; + nm_vpn_service_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPED); + break; + + default: + g_warning("Unhandled VPN service state %d", state); + g_assert_not_reached(); + break; + } + + return ret; +} + +static void +nm_vpn_service_plugin_emit_quit(NMVpnServicePlugin *plugin) +{ + g_signal_emit(plugin, signals[QUIT], 0); +} + +/** + * nm_vpn_service_plugin_shutdown: + * @plugin: the #NMVpnServicePlugin instance + * + * Shutdown the @plugin and disconnect from D-Bus. After this, + * the plugin instance is dead and should no longer be used. + * It ensures to get no more requests from D-Bus. In principle, + * you don't need to shutdown the plugin, disposing the instance + * has the same effect. However, this gives a way to deactivate + * the plugin before giving up the last reference. + * + * Since: 1.12 + */ +void +nm_vpn_service_plugin_shutdown(NMVpnServicePlugin *plugin) +{ + NMVpnServicePluginPrivate *priv; + NMVpnServiceState state; + GError * error = NULL; + + g_return_if_fail(NM_IS_VPN_SERVICE_PLUGIN(plugin)); + + priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + nm_clear_g_source(&priv->fail_stop_id); + nm_clear_g_source(&priv->quit_timer); + nm_clear_g_source(&priv->connect_timer); + + state = nm_vpn_service_plugin_get_state(plugin); + if (state == NM_VPN_SERVICE_STATE_STARTED || state == NM_VPN_SERVICE_STATE_STARTING) { + nm_vpn_service_plugin_disconnect(plugin, &error); + + if (error) { + g_warning("Error disconnecting VPN connection: %s", error->message); + g_error_free(error); + } + } + + if (priv->dbus_vpn_service_plugin) { + g_dbus_interface_skeleton_unexport( + G_DBUS_INTERFACE_SKELETON(priv->dbus_vpn_service_plugin)); + g_clear_object(&priv->dbus_vpn_service_plugin); + } +} + +static gboolean +connect_timer_expired(gpointer data) +{ + NMVpnServicePlugin *plugin = NM_VPN_SERVICE_PLUGIN(data); + GError * err = NULL; + + NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin)->connect_timer = 0; + g_message("Connect timer expired, disconnecting."); + nm_vpn_service_plugin_disconnect(plugin, &err); + if (err) { + g_warning("Disconnect failed: %s", err->message); + g_error_free(err); + } + + return G_SOURCE_REMOVE; +} + +static gboolean +quit_timer_expired(gpointer data) +{ + NMVpnServicePlugin *self = NM_VPN_SERVICE_PLUGIN(data); + + NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(self)->quit_timer = 0; + nm_vpn_service_plugin_emit_quit(self); + return G_SOURCE_REMOVE; +} + +static void +schedule_quit_timer(NMVpnServicePlugin *self) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(self); + + nm_clear_g_source(&priv->quit_timer); + priv->quit_timer = + g_timeout_add_seconds(NM_VPN_SERVICE_PLUGIN_QUIT_TIMER, quit_timer_expired, self); +} + +static gboolean +fail_stop(gpointer data) +{ + NMVpnServicePlugin *self = NM_VPN_SERVICE_PLUGIN(data); + + NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(self)->fail_stop_id = 0; + nm_vpn_service_plugin_set_state(self, NM_VPN_SERVICE_STATE_STOPPED); + return G_SOURCE_REMOVE; +} + +static void +schedule_fail_stop(NMVpnServicePlugin *plugin, guint timeout_secs) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + nm_clear_g_source(&priv->fail_stop_id); + if (timeout_secs) + priv->fail_stop_id = g_timeout_add_seconds(timeout_secs, fail_stop, plugin); + else + priv->fail_stop_id = g_idle_add(fail_stop, plugin); +} + +void +nm_vpn_service_plugin_set_config(NMVpnServicePlugin *plugin, GVariant *config) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + g_return_if_fail(NM_IS_VPN_SERVICE_PLUGIN(plugin)); + g_return_if_fail(config != NULL); + + priv->got_config = TRUE; + + (void) g_variant_lookup(config, NM_VPN_PLUGIN_CONFIG_HAS_IP4, "b", &priv->has_ip4); + (void) g_variant_lookup(config, NM_VPN_PLUGIN_CONFIG_HAS_IP6, "b", &priv->has_ip6); + + /* Record the items that need to also be inserted into the + * ip4config, for compatibility with older daemons. + */ + if (priv->banner) + g_variant_unref(priv->banner); + priv->banner = g_variant_lookup_value(config, NM_VPN_PLUGIN_CONFIG_BANNER, G_VARIANT_TYPE("s")); + if (priv->tundev) + g_variant_unref(priv->tundev); + priv->tundev = g_variant_lookup_value(config, NM_VPN_PLUGIN_CONFIG_TUNDEV, G_VARIANT_TYPE("s")); + if (priv->gateway) + g_variant_unref(priv->gateway); + priv->gateway = + g_variant_lookup_value(config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, G_VARIANT_TYPE("u")); + if (priv->mtu) + g_variant_unref(priv->mtu); + priv->mtu = g_variant_lookup_value(config, NM_VPN_PLUGIN_CONFIG_MTU, G_VARIANT_TYPE("u")); + + g_signal_emit(plugin, signals[CONFIG], 0, config); + if (priv->dbus_vpn_service_plugin) + nmdbus_vpn_plugin_emit_config(priv->dbus_vpn_service_plugin, config); + + if (priv->has_ip4 == priv->got_ip4 && priv->has_ip6 == priv->got_ip6) + nm_vpn_service_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STARTED); +} + +void +nm_vpn_service_plugin_set_ip4_config(NMVpnServicePlugin *plugin, GVariant *ip4_config) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + GVariant * combined_config; + GVariantBuilder builder; + GVariantIter iter; + const char * key; + GVariant * value; + + g_return_if_fail(NM_IS_VPN_SERVICE_PLUGIN(plugin)); + g_return_if_fail(ip4_config != NULL); + + priv->got_ip4 = TRUE; + + /* Old plugins won't send the "config" signal and thus can't send + * NM_VPN_SERVICE_PLUGIN_CONFIG_HAS_IP4 either. But since they don't support IPv6, + * we can safely assume that, if we don't receive a "config" signal but do + * receive an "ip4-config" signal, the old plugin supports IPv4. + */ + if (!priv->got_config) + priv->has_ip4 = TRUE; + + /* Older NetworkManager daemons expect all config info to be in + * the ip4 config, so they won't even notice the "config" signal + * being emitted. So just copy all of that data into the ip4 + * config too. + */ + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + g_variant_iter_init(&iter, ip4_config); + while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) { + g_variant_builder_add(&builder, "{sv}", key, value); + g_variant_unref(value); + } + + if (priv->banner) + g_variant_builder_add(&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_BANNER, priv->banner); + if (priv->tundev) + g_variant_builder_add(&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, priv->tundev); + if (priv->gateway) + g_variant_builder_add(&builder, + "{sv}", + NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, + priv->gateway); + if (priv->mtu) + g_variant_builder_add(&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_MTU, priv->mtu); + + combined_config = g_variant_builder_end(&builder); + g_variant_ref_sink(combined_config); + g_signal_emit(plugin, signals[IP4_CONFIG], 0, combined_config); + if (priv->dbus_vpn_service_plugin) + nmdbus_vpn_plugin_emit_ip4_config(priv->dbus_vpn_service_plugin, combined_config); + g_variant_unref(combined_config); + + if (priv->has_ip4 == priv->got_ip4 && priv->has_ip6 == priv->got_ip6) + nm_vpn_service_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STARTED); +} + +void +nm_vpn_service_plugin_set_ip6_config(NMVpnServicePlugin *plugin, GVariant *ip6_config) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + g_return_if_fail(NM_IS_VPN_SERVICE_PLUGIN(plugin)); + g_return_if_fail(ip6_config != NULL); + + g_variant_ref_sink(ip6_config); + + priv->got_ip6 = TRUE; + g_signal_emit(plugin, signals[IP6_CONFIG], 0, ip6_config); + if (priv->dbus_vpn_service_plugin) + nmdbus_vpn_plugin_emit_ip6_config(priv->dbus_vpn_service_plugin, ip6_config); + + g_variant_unref(ip6_config); + + if (priv->has_ip4 == priv->got_ip4 && priv->has_ip6 == priv->got_ip6) + nm_vpn_service_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STARTED); +} + +static void +connect_timer_start(NMVpnServicePlugin *plugin) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + nm_clear_g_source(&priv->connect_timer); + priv->connect_timer = g_timeout_add_seconds(60, connect_timer_expired, plugin); +} + +static void +peer_vanished(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + nm_vpn_service_plugin_disconnect(NM_VPN_SERVICE_PLUGIN(user_data), NULL); +} + +static guint +watch_peer(NMVpnServicePlugin *plugin, GDBusMethodInvocation *context) +{ + GDBusConnection *connection = g_dbus_method_invocation_get_connection(context); + const char *peer = g_dbus_message_get_sender(g_dbus_method_invocation_get_message(context)); + + return nm_dbus_connection_signal_subscribe_name_owner_changed(connection, + peer, + peer_vanished, + plugin, + NULL); +} + +static void +_connect_generic(NMVpnServicePlugin * plugin, + GDBusMethodInvocation *context, + GVariant * properties, + GVariant * details) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + NMVpnServicePluginClass * vpn_class = NM_VPN_SERVICE_PLUGIN_GET_CLASS(plugin); + NMConnection * connection; + gboolean success = FALSE; + GError * error = NULL; + guint fail_stop_timeout = 0; + + if (priv->state != NM_VPN_SERVICE_STATE_STOPPED && priv->state != NM_VPN_SERVICE_STATE_INIT) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not start connection: wrong plugin state %d", + priv->state); + return; + } + + connection = + _nm_simple_connection_new_from_dbus(properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); + if (!connection) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: %s", + error->message); + g_clear_error(&error); + return; + } + + priv->interactive = FALSE; + if (details && !vpn_class->connect_interactive) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Plugin does not implement ConnectInteractive()"); + return; + } + + nm_clear_g_source(&priv->fail_stop_id); + + if (priv->dbus_watch_peer) + priv->peer_watch_id = watch_peer(plugin, context); + + if (details) { + priv->interactive = TRUE; + success = vpn_class->connect_interactive(plugin, connection, details, &error); + if (g_error_matches(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED)) { + /* Give NetworkManager a bit of time to fall back to Connect() */ + fail_stop_timeout = 5; + } + } else + success = vpn_class->connect(plugin, connection, &error); + + if (success) { + nm_vpn_service_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STARTING); + + g_dbus_method_invocation_return_value(context, NULL); + + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ + connect_timer_start(plugin); + } else { + g_dbus_method_invocation_take_error(context, error); + + /* Stop the plugin from an idle handler so that the Connect + * method return gets sent before the STOP StateChanged signal. + */ + schedule_fail_stop(plugin, fail_stop_timeout); + } + + g_object_unref(connection); +} + +static void +impl_vpn_service_plugin_connect(NMVpnServicePlugin * plugin, + GDBusMethodInvocation *context, + GVariant * connection, + gpointer user_data) +{ + _connect_generic(plugin, context, connection, NULL); +} + +static void +impl_vpn_service_plugin_connect_interactive(NMVpnServicePlugin * plugin, + GDBusMethodInvocation *context, + GVariant * connection, + GVariant * details, + gpointer user_data) +{ + _connect_generic(plugin, context, connection, details); +} + +/*****************************************************************************/ + +static void +impl_vpn_service_plugin_need_secrets(NMVpnServicePlugin * plugin, + GDBusMethodInvocation *context, + GVariant * properties, + gpointer user_data) +{ + NMConnection *connection; + const char * setting_name; + gboolean needed; + GError * error = NULL; + + connection = + _nm_simple_connection_new_from_dbus(properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); + if (!connection) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION, + "The connection was invalid: %s", + error->message); + g_error_free(error); + return; + } + + if (!NM_VPN_SERVICE_PLUGIN_GET_CLASS(plugin)->need_secrets) { + g_dbus_method_invocation_return_value(context, g_variant_new("(s)", "")); + return; + } + + needed = NM_VPN_SERVICE_PLUGIN_GET_CLASS(plugin)->need_secrets(plugin, + connection, + &setting_name, + &error); + if (error) { + g_dbus_method_invocation_take_error(context, error); + return; + } + + if (needed) { + /* Push back the quit timer so the VPN plugin doesn't quit in the + * middle of asking the user for secrets. + */ + schedule_quit_timer(plugin); + + g_assert(setting_name); + g_dbus_method_invocation_return_value(context, g_variant_new("(s)", setting_name)); + } else { + /* No secrets required */ + g_dbus_method_invocation_return_value(context, g_variant_new("(s)", "")); + } +} + +static void +impl_vpn_service_plugin_new_secrets(NMVpnServicePlugin * plugin, + GDBusMethodInvocation *context, + GVariant * properties, + gpointer user_data) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + NMConnection * connection; + GError * error = NULL; + gboolean success; + + if (priv->state != NM_VPN_SERVICE_STATE_STARTING) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not accept new secrets: wrong plugin state %d", + priv->state); + return; + } + + connection = + _nm_simple_connection_new_from_dbus(properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); + if (!connection) { + g_dbus_method_invocation_return_error(context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: %s", + error->message); + g_clear_error(&error); + return; + } + + if (!NM_VPN_SERVICE_PLUGIN_GET_CLASS(plugin)->new_secrets) { + g_dbus_method_invocation_return_error( + context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Could not accept new secrets: plugin cannot process interactive secrets"); + g_object_unref(connection); + return; + } + + success = NM_VPN_SERVICE_PLUGIN_GET_CLASS(plugin)->new_secrets(plugin, connection, &error); + if (success) { + g_dbus_method_invocation_return_value(context, NULL); + + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ + connect_timer_start(plugin); + } else { + g_dbus_method_invocation_take_error(context, error); + + /* Stop the plugin from and idle handler so that the NewSecrets + * method return gets sent before the STOP StateChanged signal. + */ + schedule_fail_stop(plugin, 0); + } + + g_object_unref(connection); +} + +/** + * nm_vpn_service_plugin_secrets_required: + * @plugin: the #NMVpnServicePlugin + * @message: an information message about why secrets are required, if any + * @hints: VPN specific secret names for required new secrets + * + * Called by VPN plugin implementations to signal to NetworkManager that secrets + * are required during the connection process. This signal may be used to + * request new secrets when the secrets originally provided by NetworkManager + * are insufficient, or the VPN process indicates that it needs additional + * information to complete the request. + * + * Since: 1.2 + */ +void +nm_vpn_service_plugin_secrets_required(NMVpnServicePlugin *plugin, + const char * message, + const char ** hints) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + /* Plugin must be able to accept the new secrets if it calls this method */ + g_return_if_fail(NM_VPN_SERVICE_PLUGIN_GET_CLASS(plugin)->new_secrets); + + /* Plugin cannot call this method if NetworkManager didn't originally call + * ConnectInteractive(). + */ + g_return_if_fail(priv->interactive == TRUE); + + /* Cancel the connect timer since secrets might take a while. It'll + * get restarted when the secrets come back via NewSecrets(). + */ + nm_clear_g_source(&priv->connect_timer); + + g_signal_emit(plugin, signals[SECRETS_REQUIRED], 0, message, hints); + if (priv->dbus_vpn_service_plugin) + nmdbus_vpn_plugin_emit_secrets_required(priv->dbus_vpn_service_plugin, message, hints); +} + +/*****************************************************************************/ + +#define DATA_KEY_TAG "DATA_KEY=" +#define DATA_VAL_TAG "DATA_VAL=" +#define SECRET_KEY_TAG "SECRET_KEY=" +#define SECRET_VAL_TAG "SECRET_VAL=" + +/** + * nm_vpn_service_plugin_read_vpn_details: + * @fd: file descriptor to read from, usually stdin (0) + * @out_data: (out) (transfer full): on successful return, a hash table + * (mapping char*:char*) containing the key/value pairs of VPN data items + * @out_secrets: (out) (transfer full): on successful return, a hash table + * (mapping char*:char*) containing the key/value pairsof VPN secrets + * + * Parses key/value pairs from a file descriptor (normally stdin) passed by + * an applet when the applet calls the authentication dialog of the VPN plugin. + * + * Returns: %TRUE if reading values was successful, %FALSE if not + * + * Since: 1.2 + **/ +gboolean +nm_vpn_service_plugin_read_vpn_details(int fd, GHashTable **out_data, GHashTable **out_secrets) +{ + gs_unref_hashtable GHashTable *data = NULL; + gs_unref_hashtable GHashTable *secrets = NULL; + gboolean success = FALSE; + GHashTable * hash = NULL; + GString * key = NULL, *val = NULL; + nm_auto_free_gstring GString *line = NULL; + char c; + + GString *str = NULL; + + if (out_data) + g_return_val_if_fail(*out_data == NULL, FALSE); + if (out_secrets) + g_return_val_if_fail(*out_secrets == NULL, FALSE); + + data = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + secrets = + g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, (GDestroyNotify) nm_free_secret); + + line = g_string_new(NULL); + + /* Read stdin for data and secret items until we get a DONE */ + while (1) { + ssize_t nr; + + nr = read(fd, &c, 1); + if (nr < 0) { + if (errno == EAGAIN) { + g_usleep(100); + continue; + } + break; + } + if (nr > 0 && c != '\n') { + g_string_append_c(line, c); + continue; + } + + if (str && *line->str == '=') { + /* continuation */ + g_string_append_c(str, '\n'); + g_string_append(str, line->str + 1); + } else if (key && val) { + /* done a line */ + g_return_val_if_fail(hash, FALSE); + g_hash_table_insert(hash, g_string_free(key, FALSE), g_string_free(val, FALSE)); + key = NULL; + val = NULL; + hash = NULL; + success = TRUE; /* Got at least one value */ + } + + if (strcmp(line->str, "DONE") == 0) { + /* finish marker */ + break; + } else if (strncmp(line->str, DATA_KEY_TAG, strlen(DATA_KEY_TAG)) == 0) { + if (key != NULL) { + g_warning("a value expected"); + g_string_free(key, TRUE); + } + key = g_string_new(line->str + strlen(DATA_KEY_TAG)); + str = key; + hash = data; + } else if (strncmp(line->str, DATA_VAL_TAG, strlen(DATA_VAL_TAG)) == 0) { + if (val != NULL) + g_string_free(val, TRUE); + if (val || !key || hash != data) { + g_warning("%s not preceded by %s", DATA_VAL_TAG, DATA_KEY_TAG); + break; + } + val = g_string_new(line->str + strlen(DATA_VAL_TAG)); + str = val; + } else if (strncmp(line->str, SECRET_KEY_TAG, strlen(SECRET_KEY_TAG)) == 0) { + if (key != NULL) { + g_warning("a value expected"); + g_string_free(key, TRUE); + } + key = g_string_new(line->str + strlen(SECRET_KEY_TAG)); + str = key; + hash = secrets; + } else if (strncmp(line->str, SECRET_VAL_TAG, strlen(SECRET_VAL_TAG)) == 0) { + if (val != NULL) + g_string_free(val, TRUE); + if (val || !key || hash != secrets) { + g_warning("%s not preceded by %s", SECRET_VAL_TAG, SECRET_KEY_TAG); + break; + } + val = g_string_new(line->str + strlen(SECRET_VAL_TAG)); + str = val; + } + + g_string_truncate(line, 0); + + if (nr == 0) + break; + } + + if (success) { + NM_SET_OUT(out_data, g_steal_pointer(&data)); + NM_SET_OUT(out_secrets, g_steal_pointer(&secrets)); + } + return success; +} + +/** + * nm_vpn_service_plugin_get_secret_flags: + * @data: hash table containing VPN key/value pair data items + * @secret_name: VPN secret key name for which to retrieve flags for + * @out_flags: (out): on success, the flags associated with @secret_name + * + * Given a VPN secret key name, attempts to find the corresponding flags data + * item in @data. If found, converts the flags data item to + * #NMSettingSecretFlags and returns it. + * + * Returns: %TRUE if the flag data item was found and successfully converted + * to flags, %FALSE if not + * + * Since: 1.2 + **/ +gboolean +nm_vpn_service_plugin_get_secret_flags(GHashTable * data, + const char * secret_name, + NMSettingSecretFlags *out_flags) +{ + gs_free char * flag_name_free = NULL; + const char * s; + gint64 t1; + NMSettingSecretFlags t0; + + g_return_val_if_fail(data, FALSE); + g_return_val_if_fail(out_flags && *out_flags == NM_SETTING_SECRET_FLAG_NONE, FALSE); + if (!secret_name || !*secret_name) + g_return_val_if_reached(FALSE); + + s = g_hash_table_lookup(data, nm_construct_name_a("%s-flags", secret_name, &flag_name_free)); + if (!s) + return FALSE; + t1 = _nm_utils_ascii_str_to_int64(s, 10, 0, G_MAXINT64, -1); + if (t1 == -1) + return FALSE; + t0 = (NMSettingSecretFlags) t1; + if ((gint64) t0 != t1) + return FALSE; + NM_SET_OUT(out_flags, t0); + return TRUE; +} + +/*****************************************************************************/ + +static void +impl_vpn_service_plugin_disconnect(NMVpnServicePlugin * plugin, + GDBusMethodInvocation *context, + gpointer user_data) +{ + GError *error = NULL; + + if (nm_vpn_service_plugin_disconnect(plugin, &error)) + g_dbus_method_invocation_return_value(context, NULL); + else + g_dbus_method_invocation_take_error(context, error); +} + +static void +impl_vpn_service_plugin_set_config(NMVpnServicePlugin * plugin, + GDBusMethodInvocation *context, + GVariant * config, + gpointer user_data) +{ + nm_vpn_service_plugin_set_config(plugin, config); + g_dbus_method_invocation_return_value(context, NULL); +} + +static void +impl_vpn_service_plugin_set_ip4_config(NMVpnServicePlugin * plugin, + GDBusMethodInvocation *context, + GVariant * config, + gpointer user_data) +{ + nm_vpn_service_plugin_set_ip4_config(plugin, config); + g_dbus_method_invocation_return_value(context, NULL); +} + +static void +impl_vpn_service_plugin_set_ip6_config(NMVpnServicePlugin * plugin, + GDBusMethodInvocation *context, + GVariant * config, + gpointer user_data) +{ + nm_vpn_service_plugin_set_ip6_config(plugin, config); + g_dbus_method_invocation_return_value(context, NULL); +} + +static void +impl_vpn_service_plugin_set_failure(NMVpnServicePlugin * plugin, + GDBusMethodInvocation *context, + char * reason, + gpointer user_data) +{ + nm_vpn_service_plugin_failure(plugin, NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG); + g_dbus_method_invocation_return_value(context, NULL); +} + +/*****************************************************************************/ + +static void +_emit_quit(gpointer data, gpointer user_data) +{ + NMVpnServicePlugin *plugin = data; + + nm_vpn_service_plugin_emit_quit(plugin); +} + +static void +sigterm_handler(int signum) +{ + g_slist_foreach(active_plugins, _emit_quit, NULL); +} + +static void +setup_unix_signal_handler(void) +{ + struct sigaction action; + sigset_t block_mask; + + action.sa_handler = sigterm_handler; + sigemptyset(&block_mask); + action.sa_mask = block_mask; + action.sa_flags = 0; + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); +} + +/*****************************************************************************/ + +static void +one_plugin_destroyed(gpointer data, GObject *object) +{ + active_plugins = g_slist_remove(active_plugins, object); +} + +static void +nm_vpn_service_plugin_init(NMVpnServicePlugin *plugin) +{ + active_plugins = g_slist_append(active_plugins, plugin); + g_object_weak_ref(G_OBJECT(plugin), one_plugin_destroyed, NULL); +} + +static gboolean +init_sync(GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMVpnServicePlugin * plugin = NM_VPN_SERVICE_PLUGIN(initable); + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + gs_unref_object GDBusConnection *connection = NULL; + gs_unref_object GDBusProxy *proxy = NULL; + GVariant * ret; + + if (!priv->dbus_service_name) { + g_set_error_literal(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("No service name specified")); + return FALSE; + } + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, error); + if (!connection) + return FALSE; + + proxy = g_dbus_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + cancellable, + error); + if (!proxy) + return FALSE; + + priv->dbus_vpn_service_plugin = nmdbus_vpn_plugin_skeleton_new(); + + _nm_dbus_bind_properties(plugin, priv->dbus_vpn_service_plugin); + _nm_dbus_bind_methods(plugin, + priv->dbus_vpn_service_plugin, + "Connect", + impl_vpn_service_plugin_connect, + "ConnectInteractive", + impl_vpn_service_plugin_connect_interactive, + "NeedSecrets", + impl_vpn_service_plugin_need_secrets, + "NewSecrets", + impl_vpn_service_plugin_new_secrets, + "Disconnect", + impl_vpn_service_plugin_disconnect, + "SetConfig", + impl_vpn_service_plugin_set_config, + "SetIp4Config", + impl_vpn_service_plugin_set_ip4_config, + "SetIp6Config", + impl_vpn_service_plugin_set_ip6_config, + "SetFailure", + impl_vpn_service_plugin_set_failure, + NULL); + + if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(priv->dbus_vpn_service_plugin), + connection, + NM_VPN_DBUS_PLUGIN_PATH, + error)) + return FALSE; + + nm_vpn_service_plugin_set_connection(plugin, connection); + nm_vpn_service_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_INIT); + + ret = g_dbus_proxy_call_sync(proxy, + "RequestName", + g_variant_new("(su)", priv->dbus_service_name, 0), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + error); + if (!ret) { + if (error && *error) + g_dbus_error_strip_remote_error(*error); + return FALSE; + } + g_variant_unref(ret); + + return TRUE; +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_DBUS_SERVICE_NAME: + /* construct-only */ + priv->dbus_service_name = g_value_dup_string(value); + break; + case PROP_DBUS_WATCH_PEER: + /* construct-only */ + priv->dbus_watch_peer = g_value_get_boolean(value); + break; + case PROP_STATE: + nm_vpn_service_plugin_set_state(NM_VPN_SERVICE_PLUGIN(object), + (NMVpnServiceState) g_value_get_enum(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_DBUS_SERVICE_NAME: + g_value_set_string(value, priv->dbus_service_name); + break; + case PROP_DBUS_WATCH_PEER: + g_value_set_boolean(value, priv->dbus_watch_peer); + break; + case PROP_STATE: + g_value_set_enum(value, nm_vpn_service_plugin_get_state(NM_VPN_SERVICE_PLUGIN(object))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +dispose(GObject *object) +{ + nm_vpn_service_plugin_shutdown(NM_VPN_SERVICE_PLUGIN(object)); + G_OBJECT_CLASS(nm_vpn_service_plugin_parent_class)->dispose(object); +} + +static void +finalize(GObject *object) +{ + NMVpnServicePlugin * plugin = NM_VPN_SERVICE_PLUGIN(object); + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + nm_vpn_service_plugin_set_connection(plugin, NULL); + g_free(priv->dbus_service_name); + + nm_clear_pointer(&priv->banner, g_variant_unref); + nm_clear_pointer(&priv->tundev, g_variant_unref); + nm_clear_pointer(&priv->gateway, g_variant_unref); + nm_clear_pointer(&priv->mtu, g_variant_unref); + + G_OBJECT_CLASS(nm_vpn_service_plugin_parent_class)->finalize(object); +} + +static void +state_changed(NMVpnServicePlugin *plugin, NMVpnServiceState state) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + switch (state) { + case NM_VPN_SERVICE_STATE_STARTING: + nm_clear_g_source(&priv->quit_timer); + nm_clear_g_source(&priv->fail_stop_id); + break; + case NM_VPN_SERVICE_STATE_STOPPED: + if (priv->dbus_watch_peer) + nm_vpn_service_plugin_emit_quit(plugin); + else + schedule_quit_timer(plugin); + nm_clear_g_dbus_connection_signal(nm_vpn_service_plugin_get_connection(plugin), + &priv->peer_watch_id); + break; + default: + /* Clean up all timers we might have set up. */ + nm_clear_g_source(&priv->connect_timer); + nm_clear_g_source(&priv->quit_timer); + nm_clear_g_source(&priv->fail_stop_id); + break; + } +} + +static void +nm_vpn_service_plugin_class_init(NMVpnServicePluginClass *plugin_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(plugin_class); + + g_type_class_add_private(object_class, sizeof(NMVpnServicePluginPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + plugin_class->state_changed = state_changed; + + /** + * NMVpnServicePlugin:service-name: + * + * The D-Bus service name of this plugin. + * + * Since: 1.2 + */ + obj_properties[PROP_DBUS_SERVICE_NAME] = + g_param_spec_string(NM_VPN_SERVICE_PLUGIN_DBUS_SERVICE_NAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + /** + * NMVpnServicePlugin:watch-peer: + * + * Whether to watch for D-Bus peer's changes. + * + * Since: 1.2 + */ + obj_properties[PROP_DBUS_WATCH_PEER] = + g_param_spec_boolean(NM_VPN_SERVICE_PLUGIN_DBUS_WATCH_PEER, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + /** + * NMVpnServicePlugin:state: + * + * The state of the plugin. + * + * Since: 1.2 + */ + obj_properties[PROP_STATE] = g_param_spec_enum(NM_VPN_SERVICE_PLUGIN_STATE, + "", + "", + NM_TYPE_VPN_SERVICE_STATE, + NM_VPN_SERVICE_STATE_INIT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + signals[STATE_CHANGED] = g_signal_new("state-changed", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnServicePluginClass, state_changed), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_UINT); + + signals[SECRETS_REQUIRED] = g_signal_new("secrets-required", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_STRV); + + signals[CONFIG] = g_signal_new("config", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnServicePluginClass, config), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_VARIANT); + + signals[IP4_CONFIG] = g_signal_new("ip4-config", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnServicePluginClass, ip4_config), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_VARIANT); + + signals[IP6_CONFIG] = g_signal_new("ip6-config", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnServicePluginClass, ip6_config), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_VARIANT); + + signals[LOGIN_BANNER] = g_signal_new("login-banner", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnServicePluginClass, login_banner), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + + signals[FAILURE] = g_signal_new("failure", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnServicePluginClass, failure), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_UINT); + + signals[QUIT] = g_signal_new("quit", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMVpnServicePluginClass, quit), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0, + G_TYPE_NONE); + + setup_unix_signal_handler(); +} + +static void +nm_vpn_service_plugin_initable_iface_init(GInitableIface *iface) +{ + iface->init = init_sync; +} diff --git a/src/libnm-client-impl/nm-wifi-p2p-peer.c b/src/libnm-client-impl/nm-wifi-p2p-peer.c new file mode 100644 index 0000000..1d6b7c9 --- /dev/null +++ b/src/libnm-client-impl/nm-wifi-p2p-peer.c @@ -0,0 +1,575 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 - 2019 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-wifi-p2p-peer.h" + +#include "nm-connection.h" +#include "nm-setting-connection.h" +#include "nm-setting-wifi-p2p.h" +#include "nm-utils.h" +#include "nm-dbus-interface.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_FLAGS, + PROP_NAME, + PROP_MANUFACTURER, + PROP_MODEL, + PROP_MODEL_NUMBER, + PROP_SERIAL, + PROP_WFD_IES, + PROP_HW_ADDRESS, + PROP_STRENGTH, + PROP_LAST_SEEN, ); + +typedef struct { + GBytes *wfd_ies; + char * name; + char * manufacturer; + char * model; + char * model_number; + char * serial; + char * hw_address; + gint32 last_seen; + guint32 flags; + guint8 strength; +} NMWifiP2PPeerPrivate; + +struct _NMWifiP2PPeer { + NMObject parent; + NMWifiP2PPeerPrivate _priv; +}; + +struct _NMWifiP2PPeerClass { + NMObjectClass parent; +}; + +G_DEFINE_TYPE(NMWifiP2PPeer, nm_wifi_p2p_peer, NM_TYPE_OBJECT) + +#define NM_WIFI_P2P_PEER_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMWifiP2PPeer, NM_IS_WIFI_P2P_PEER, NMObject) + +/*****************************************************************************/ + +/** + * nm_wifi_p2p_peer_get_flags: + * @peer: a #NMWifiP2PPeer + * + * Gets the flags of the P2P peer. + * + * Returns: the flags + * + * Since: 1.16 + **/ +NM80211ApFlags +nm_wifi_p2p_peer_get_flags(NMWifiP2PPeer *peer) +{ + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NM_802_11_AP_FLAGS_NONE); + + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->flags; +} + +/** + * nm_wifi_p2p_peer_get_name: + * @peer: a #NMWifiP2PPeer + * + * Gets the name of the P2P peer. + * + * Returns: the name + * + * Since: 1.16 + **/ +const char * +nm_wifi_p2p_peer_get_name(NMWifiP2PPeer *peer) +{ + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); + + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->name; +} + +/** + * nm_wifi_p2p_peer_get_manufacturer: + * @peer: a #NMWifiP2PPeer + * + * Gets the manufacturer of the P2P peer. + * + * Returns: the manufacturer + * + * Since: 1.16 + **/ +const char * +nm_wifi_p2p_peer_get_manufacturer(NMWifiP2PPeer *peer) +{ + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); + + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->manufacturer; +} + +/** + * nm_wifi_p2p_peer_get_model: + * @peer: a #NMWifiP2PPeer + * + * Gets the model of the P2P peer. + * + * Returns: the model + * + * Since: 1.16 + **/ +const char * +nm_wifi_p2p_peer_get_model(NMWifiP2PPeer *peer) +{ + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); + + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->model; +} + +/** + * nm_wifi_p2p_peer_get_model_number: + * @peer: a #NMWifiP2PPeer + * + * Gets the model number of the P2P peer. + * + * Returns: the model number + * + * Since: 1.16 + **/ +const char * +nm_wifi_p2p_peer_get_model_number(NMWifiP2PPeer *peer) +{ + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); + + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->model_number; +} + +/** + * nm_wifi_p2p_peer_get_serial: + * @peer: a #NMWifiP2PPeer + * + * Gets the serial number of the P2P peer. + * + * Returns: the serial number + * + * Since: 1.16 + **/ +const char * +nm_wifi_p2p_peer_get_serial(NMWifiP2PPeer *peer) +{ + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); + + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->serial; +} + +/** + * nm_wifi_p2p_peer_get_wfd_ies: + * @peer: a #NMWifiP2PPeer + * + * Gets the WFD information elements of the P2P peer. + * + * Returns: (transfer none): the #GBytes containing the WFD IEs, or %NULL. + * + * Since: 1.16 + **/ +GBytes * +nm_wifi_p2p_peer_get_wfd_ies(NMWifiP2PPeer *peer) +{ + NMWifiP2PPeerPrivate *priv; + + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); + + priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); + if (!priv->wfd_ies || g_bytes_get_size(priv->wfd_ies) == 0) + return NULL; + + return priv->wfd_ies; +} + +/** + * nm_wifi_p2p_peer_get_hw_address: + * @peer: a #NMWifiP2PPeer + * + * Gets the hardware address of the P2P peer. + * + * Returns: the hardware address + * + * Since: 1.16 + **/ +const char * +nm_wifi_p2p_peer_get_hw_address(NMWifiP2PPeer *peer) +{ + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); + + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->hw_address; +} + +/** + * nm_wifi_p2p_peer_get_strength: + * @peer: a #NMWifiP2PPeer + * + * Gets the current signal strength of the P2P peer as a percentage. + * + * Returns: the signal strength (0 to 100) + * + * Since: 1.16 + **/ +guint8 +nm_wifi_p2p_peer_get_strength(NMWifiP2PPeer *peer) +{ + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), 0); + + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->strength; +} + +/** + * nm_wifi_p2p_peer_get_last_seen: + * @peer: a #NMWifiP2PPeer + * + * Returns the timestamp (in CLOCK_BOOTTIME seconds) for the last time the + * P2P peer was seen. A value of -1 means the P2P peer has never been seen. + * + * Returns: the last seen time in seconds + * + * Since: 1.16 + **/ +int +nm_wifi_p2p_peer_get_last_seen(NMWifiP2PPeer *peer) +{ + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), -1); + + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->last_seen; +} + +/** + * nm_wifi_p2p_peer_connection_valid: + * @peer: an #NMWifiP2PPeer to validate @connection against + * @connection: an #NMConnection to validate against @peer + * + * Validates a given connection against a given Wi-Fi P2P peer to ensure that + * the connection may be activated with that peer. The connection must match the + * @peer's address and in the future possibly other attributes. + * + * Returns: %TRUE if the connection may be activated with this Wi-Fi P2P Peer, + * %FALSE if it cannot be. + * + * Since: 1.16 + **/ +gboolean +nm_wifi_p2p_peer_connection_valid(NMWifiP2PPeer *peer, NMConnection *connection) +{ + NMSettingConnection *s_con; + NMSettingWifiP2P * s_wifi_p2p; + const char * ctype; + const char * hw_address; + const char * setting_peer; + + s_wifi_p2p = + (NMSettingWifiP2P *) nm_connection_get_setting(connection, NM_TYPE_SETTING_WIFI_P2P); + if (!s_wifi_p2p) + return FALSE; + + s_con = nm_connection_get_setting_connection(connection); + if (!s_con) + return FALSE; + + ctype = nm_setting_connection_get_connection_type(s_con); + if (!ctype || !nm_streq(ctype, NM_SETTING_WIFI_P2P_SETTING_NAME)) + return FALSE; + + /* HW Address check */ + hw_address = nm_wifi_p2p_peer_get_hw_address(peer); + if (!hw_address) + return FALSE; + + setting_peer = nm_setting_wifi_p2p_get_peer(s_wifi_p2p); + if (!setting_peer || !nm_streq(hw_address, setting_peer)) + return FALSE; + + return TRUE; +} + +/** + * nm_wifi_p2p_peer_filter_connections: + * @peer: an #NMWifiP2PPeer to filter connections for + * @connections: (element-type NMConnection): an array of #NMConnections to + * filter + * + * Filters a given array of connections for a given #NMWifiP2PPeer object and + * returns connections which may be activated with the P2P peer. Any + * returned connections will match the @peers's HW address and in the future + * possibly other attributes. + * + * To obtain the list of connections that are compatible with this P2P peer, + * use nm_client_get_connections() and then filter the returned list for a given + * #NMDevice using nm_device_filter_connections() and finally filter that list + * with this function. + * + * Returns: (transfer container) (element-type NMConnection): an array of + * #NMConnections that could be activated with the given @peer. The array should + * be freed with g_ptr_array_unref() when it is no longer required. + * + * Since: 1.16 + **/ +GPtrArray * +nm_wifi_p2p_peer_filter_connections(NMWifiP2PPeer *peer, const GPtrArray *connections) +{ + GPtrArray *filtered; + guint i; + + filtered = g_ptr_array_new_with_free_func(g_object_unref); + for (i = 0; i < connections->len; i++) { + NMConnection *candidate = connections->pdata[i]; + + if (nm_wifi_p2p_peer_connection_valid(peer, candidate)) + g_ptr_array_add(filtered, g_object_ref(candidate)); + } + + return filtered; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMWifiP2PPeer *peer = NM_WIFI_P2P_PEER(object); + + switch (prop_id) { + case PROP_FLAGS: + g_value_set_flags(value, nm_wifi_p2p_peer_get_flags(peer)); + break; + case PROP_NAME: + g_value_set_string(value, nm_wifi_p2p_peer_get_name(peer)); + break; + case PROP_MANUFACTURER: + g_value_set_string(value, nm_wifi_p2p_peer_get_manufacturer(peer)); + break; + case PROP_MODEL: + g_value_set_string(value, nm_wifi_p2p_peer_get_model(peer)); + break; + case PROP_MODEL_NUMBER: + g_value_set_string(value, nm_wifi_p2p_peer_get_model_number(peer)); + break; + case PROP_SERIAL: + g_value_set_string(value, nm_wifi_p2p_peer_get_serial(peer)); + break; + case PROP_WFD_IES: + g_value_set_boxed(value, nm_wifi_p2p_peer_get_wfd_ies(peer)); + break; + case PROP_HW_ADDRESS: + g_value_set_string(value, nm_wifi_p2p_peer_get_hw_address(peer)); + break; + case PROP_STRENGTH: + g_value_set_uchar(value, nm_wifi_p2p_peer_get_strength(peer)); + break; + case PROP_LAST_SEEN: + g_value_set_int(value, nm_wifi_p2p_peer_get_last_seen(peer)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_wifi_p2p_peer_init(NMWifiP2PPeer *peer) +{ + NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->last_seen = -1; +} + +static void +finalize(GObject *object) +{ + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(object); + + g_free(priv->name); + g_free(priv->manufacturer); + g_free(priv->model); + g_free(priv->model_number); + g_free(priv->serial); + g_free(priv->hw_address); + + g_bytes_unref(priv->wfd_ies); + + G_OBJECT_CLASS(nm_wifi_p2p_peer_parent_class)->finalize(object); +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_wifip2ppeer = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_WIFI_P2P_PEER, + nm_wifi_p2p_peer_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_U("Flags", PROP_FLAGS, NMWifiP2PPeer, _priv.flags), + NML_DBUS_META_PROPERTY_INIT_IGNORE("Groups", "as"), + NML_DBUS_META_PROPERTY_INIT_S("HwAddress", + PROP_HW_ADDRESS, + NMWifiP2PPeer, + _priv.hw_address), + NML_DBUS_META_PROPERTY_INIT_I("LastSeen", PROP_LAST_SEEN, NMWifiP2PPeer, _priv.last_seen), + NML_DBUS_META_PROPERTY_INIT_S("Manufacturer", + PROP_MANUFACTURER, + NMWifiP2PPeer, + _priv.manufacturer), + NML_DBUS_META_PROPERTY_INIT_S("Model", PROP_MODEL, NMWifiP2PPeer, _priv.model), + NML_DBUS_META_PROPERTY_INIT_S("ModelNumber", + PROP_MODEL_NUMBER, + NMWifiP2PPeer, + _priv.model_number), + NML_DBUS_META_PROPERTY_INIT_S("Name", PROP_NAME, NMWifiP2PPeer, _priv.name), + NML_DBUS_META_PROPERTY_INIT_S("Serial", PROP_SERIAL, NMWifiP2PPeer, _priv.serial), + NML_DBUS_META_PROPERTY_INIT_Y("Strength", PROP_STRENGTH, NMWifiP2PPeer, _priv.strength), + NML_DBUS_META_PROPERTY_INIT_AY("WfdIEs", PROP_WFD_IES, NMWifiP2PPeer, _priv.wfd_ies), ), ); + +static void +nm_wifi_p2p_peer_class_init(NMWifiP2PPeerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + /** + * NMWifiP2PPeer:flags: + * + * The flags of the P2P peer. + * + * Since: 1.16 + **/ + obj_properties[PROP_FLAGS] = g_param_spec_flags(NM_WIFI_P2P_PEER_FLAGS, + "", + "", + NM_TYPE_802_11_AP_FLAGS, + NM_802_11_AP_FLAGS_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMWifiP2PPeer:name: + * + * The name of the P2P peer. + * + * Since: 1.16 + **/ + obj_properties[PROP_NAME] = g_param_spec_string(NM_WIFI_P2P_PEER_NAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMWifiP2PPeer:manufacturer: + * + * The manufacturer of the P2P peer. + * + * Since: 1.16 + **/ + obj_properties[PROP_MANUFACTURER] = + g_param_spec_string(NM_WIFI_P2P_PEER_MANUFACTURER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMWifiP2PPeer:model: + * + * The model of the P2P peer. + * + * Since: 1.16 + **/ + obj_properties[PROP_MODEL] = g_param_spec_string(NM_WIFI_P2P_PEER_MODEL, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMWifiP2PPeer:model-number: + * + * The hardware address of the P2P peer. + * + * Since: 1.16 + **/ + obj_properties[PROP_MODEL_NUMBER] = + g_param_spec_string(NM_WIFI_P2P_PEER_MODEL_NUMBER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMWifiP2PPeer:serial: + * + * The serial number of the P2P peer. + * + * Since: 1.16 + **/ + obj_properties[PROP_SERIAL] = g_param_spec_string(NM_WIFI_P2P_PEER_SERIAL, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMWifiP2PPeer:wfd-ies: + * + * The WFD information elements of the P2P peer. + * + * Since: 1.16 + **/ + obj_properties[PROP_WFD_IES] = g_param_spec_boxed(NM_WIFI_P2P_PEER_WFD_IES, + "", + "", + G_TYPE_BYTES, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /** + * NMWifiP2PPeer:hw-address: + * + * The hardware address of the P2P peer. + * + * Since: 1.16 + **/ + obj_properties[PROP_HW_ADDRESS] = + g_param_spec_string(NM_WIFI_P2P_PEER_HW_ADDRESS, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMWifiP2PPeer:strength: + * + * The current signal strength of the P2P peer. + * + * Since: 1.16 + **/ + obj_properties[PROP_STRENGTH] = g_param_spec_uchar(NM_WIFI_P2P_PEER_STRENGTH, + "", + "", + 0, + G_MAXUINT8, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMWifiP2PPeer:last-seen: + * + * The timestamp (in CLOCK_BOOTTIME seconds) for the last time the + * P2P peer was found. A value of -1 means the peer has never been seen. + * + * Since: 1.16 + **/ + obj_properties[PROP_LAST_SEEN] = g_param_spec_int(NM_WIFI_P2P_PEER_LAST_SEEN, + "", + "", + -1, + G_MAXINT, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_wifip2ppeer); +} diff --git a/src/libnm-client-impl/nm-wimax-nsp.c b/src/libnm-client-impl/nm-wimax-nsp.c new file mode 100644 index 0000000..62181d6 --- /dev/null +++ b/src/libnm-client-impl/nm-wimax-nsp.c @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-wimax-nsp.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_NAME, PROP_SIGNAL_QUALITY, PROP_NETWORK_TYPE, ); + +struct _NMWimaxNsp { + NMObject parent; +}; + +struct _NMWimaxNspClass { + NMObjectClass parent; +}; + +G_DEFINE_TYPE(NMWimaxNsp, nm_wimax_nsp, NM_TYPE_OBJECT) + +#define NM_WIMAX_NSP_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMWimaxNsp, NM_IS_WIMAX_NSP, NMObject) + +/*****************************************************************************/ + +/** + * nm_wimax_nsp_get_name: + * @nsp: a #NMWimaxNsp + * + * Gets the name of the wimax NSP + * + * Returns: the name + * + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. + **/ +const char * +nm_wimax_nsp_get_name(NMWimaxNsp *nsp) +{ + g_return_val_if_reached(NULL); +} + +/** + * nm_wimax_nsp_get_signal_quality: + * @nsp: a #NMWimaxNsp + * + * Gets the WPA signal quality of the wimax NSP. + * + * Returns: the signal quality + * + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. + **/ +guint32 +nm_wimax_nsp_get_signal_quality(NMWimaxNsp *nsp) +{ + g_return_val_if_reached(0); +} + +/** + * nm_wimax_nsp_get_network_type: + * @nsp: a #NMWimaxNsp + * + * Gets the network type of the wimax NSP. + * + * Returns: the network type + * + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. + **/ +NMWimaxNspNetworkType +nm_wimax_nsp_get_network_type(NMWimaxNsp *nsp) +{ + g_return_val_if_reached(NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN); +} + +/** + * nm_wimax_nsp_connection_valid: + * @nsp: an #NMWimaxNsp to validate @connection against + * @connection: an #NMConnection to validate against @nsp + * + * Validates a given connection against a given WiMAX NSP to ensure that the + * connection may be activated with that NSP. The connection must match the + * @nsp's network name and other attributes. + * + * Returns: %TRUE if the connection may be activated with this WiMAX NSP, + * %FALSE if it cannot be. + * + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. + **/ +gboolean +nm_wimax_nsp_connection_valid(NMWimaxNsp *nsp, NMConnection *connection) +{ + g_return_val_if_reached(FALSE); +} + +/** + * nm_wimax_nsp_filter_connections: + * @nsp: an #NMWimaxNsp to filter connections for + * @connections: (element-type NMConnection): an array of #NMConnections to + * filter + * + * Filters a given array of connections for a given #NMWimaxNsp object and + * return connections which may be activated with the NSP. Any returned + * connections will match the @nsp's network name and other attributes. + * + * Returns: (transfer full) (element-type NMConnection): an array of + * #NMConnections that could be activated with the given @nsp. The array should + * be freed with g_ptr_array_unref() when it is no longer required. + * + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. + **/ +GPtrArray * +nm_wimax_nsp_filter_connections(NMWimaxNsp *nsp, const GPtrArray *connections) +{ + g_return_val_if_reached(NULL); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + g_return_if_reached(); +} + +static void +nm_wimax_nsp_init(NMWimaxNsp *nsp) +{ + g_return_if_reached(); +} + +static void +nm_wimax_nsp_class_init(NMWimaxNspClass *nsp_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(nsp_class); + + object_class->get_property = get_property; + + /** + * NMWimaxNsp:name: + * + * The name of the WiMAX NSP. + * + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. + **/ + obj_properties[PROP_NAME] = g_param_spec_string(NM_WIMAX_NSP_NAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMWimaxNsp:signal-quality: + * + * The signal quality of the WiMAX NSP. + * + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. + **/ + obj_properties[PROP_SIGNAL_QUALITY] = + g_param_spec_uint(NM_WIMAX_NSP_SIGNAL_QUALITY, + "", + "", + 0, + 100, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMWimaxNsp:network-type: + * + * The network type of the WiMAX NSP. + * + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. + **/ + obj_properties[PROP_NETWORK_TYPE] = + g_param_spec_enum(NM_WIMAX_NSP_NETWORK_TYPE, + "", + "", + NM_TYPE_WIMAX_NSP_NETWORK_TYPE, + NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} diff --git a/src/libnm-client-impl/tests/meson.build b/src/libnm-client-impl/tests/meson.build new file mode 100644 index 0000000..3f2e78a --- /dev/null +++ b/src/libnm-client-impl/tests/meson.build @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +test_units = [ + 'test-libnm', + 'test-nm-client', + 'test-remote-settings-client', + 'test-secret-agent', +] + +foreach test_unit: test_units + exe = executable( + test_unit, + [ test_unit + '.c' ] + (test_unit == 'test-libnm' ? src_contrib_nm_compat_source : []), + include_directories: [ + libnm_client_public_inc, + ], + dependencies: [ + libnm_core_public_dep, + libnm_client_public_dep, + glib_dep, + libudev_dep, + ], + link_with: [ + libnm_client_impl, + libnm_client_test, + libnm_core_aux_intern, + libnm_core_impl, + libnm_crypto, + libnm_base, + libnm_udev_aux, + libnm_systemd_shared, + libnm_log_null, + libnm_glib_aux, + libnm_std_aux, + libc_siphash, + libnmdbus, + ], + ) + + test( + 'src/libnm-client-impl/tests/' + test_unit, + test_script, + timeout: 90, + args: test_args + [exe.full_path()], + ) +endforeach diff --git a/src/libnm-client-impl/tests/test-libnm.c b/src/libnm-client-impl/tests/test-libnm.c new file mode 100644 index 0000000..fab36cb --- /dev/null +++ b/src/libnm-client-impl/tests/test-libnm.c @@ -0,0 +1,3469 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#if defined(HAVE_DECL_MEMFD_CREATE) && HAVE_DECL_MEMFD_CREATE + #include +#endif + +#include + +#include "NetworkManager.h" +#include "nm-access-point.h" +#include "nm-checkpoint.h" +#include "libnm-client-impl/nm-dhcp4-config.h" +#include "libnm-client-impl/nm-dhcp6-config.h" +#include "libnm-client-impl/nm-dns-manager.h" +#include "libnm-client-impl/nm-ip4-config.h" +#include "libnm-client-impl/nm-ip6-config.h" +#include "libnm-client-impl/nm-libnm-utils.h" +#include "nm-object.h" +#include "nm-vpn-service-plugin.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +/*****************************************************************************/ + +typedef struct { + const char *desc; + const char *expected; + int line; +} TestFixupData; + +static void +_test_fixup_string(const TestFixupData *data, guint n_data, char *(*func)(const char *) ) +{ + guint i; + + g_assert(data); + g_assert(n_data > 0); + g_assert(func); + + for (i = 0; i < n_data; i++, data++) { + gs_free char *value = func(data->desc); + + if (!nm_streq0(value, data->expected)) { + g_error("Error comparing value: %s:%i: expected %s%s%s for %s%s%s, but got %s%s%s", + __FILE__, + data->line, + NM_PRINT_FMT_QUOTE_STRING(data->expected), + NM_PRINT_FMT_QUOTE_STRING(data->desc), + NM_PRINT_FMT_QUOTE_STRING(value)); + } + } +} + +#define T_DATA(_desc, _expected) \ + { \ + .desc = _desc, .expected = _expected, .line = __LINE__, \ + } + +static void +test_fixup_vendor_string(void) +{ + static const TestFixupData data[] = { + T_DATA("3Com", "3Com"), + T_DATA("3Com Corp.", "3Com"), + T_DATA("3Com Corporation", "3Com"), + T_DATA("Abocom Systems Inc", "Abocom"), + T_DATA("AboCom Systems Inc", "AboCom"), + T_DATA("Accton Technology Corp.", "Accton"), + T_DATA("Accton Technology Corporation", "Accton"), + T_DATA("Acer Communications & Multimedia", "Acer"), + T_DATA("Actiontec Electronics, Inc. [hex]", "Actiontec"), + T_DATA("Adaptec", "Adaptec"), + T_DATA("Addtron Technology Co, Inc.", "Addtron"), + T_DATA("ADMtek", "ADMtek"), + T_DATA("ADMtek, Inc.", "ADMtek"), + T_DATA("ADS Technologies, Inc.", "ADS"), + T_DATA("Advanced Micro Devices, Inc. [AMD]", "AMD"), + T_DATA("Advance Multimedia Internet Technology Inc. (AMIT)", "Advance"), + T_DATA("AEI", "AEI"), + T_DATA("Airprime, Incorporated", "Airprime"), + T_DATA("AirTies Wireless Networks", "AirTies"), + T_DATA("AirVast", "AirVast"), + T_DATA("Alcatel Telecom", "Alcatel Telecom"), + T_DATA("ALi Corp.", "ALi"), + T_DATA("Allied Telesis", "Allied Telesis"), + T_DATA("Allied Telesyn International", "Allied Telesyn"), + T_DATA("Alteon Networks Inc.", "Alteon"), + T_DATA("Altima (nee Broadcom)", "Altima"), + T_DATA("A-Max Technology Macao Commercial Offshore Co. Ltd.", "A-Max"), + T_DATA("Amigo Technology Inc.", "Amigo"), + T_DATA("AMIT Technology, Inc.", "AMIT"), + T_DATA("Anchor Chips, Inc.", "Anchor"), + T_DATA("AnyDATA Corporation", "AnyDATA"), + T_DATA("Apple Inc.", "Apple"), + T_DATA("Apple, Inc.", "Apple"), + T_DATA("ARC International", "ARC"), + T_DATA("ASIX Electronics Corp.", "ASIX"), + T_DATA("Asix Electronics Corporation", "Asix"), + T_DATA("Askey Computer Corp. [hex]", "Askey"), + T_DATA("ASUSTek Computer, Inc.", "ASUSTek Computer"), + T_DATA("ASUSTek Computer, Inc. (wrong ID)", "ASUSTek Computer"), + T_DATA("ATEN International Co., Ltd", "ATEN"), + T_DATA("Atheros Communications", "Atheros"), + T_DATA("Atheros Communications, Inc.", "Atheros"), + T_DATA("AVM GmbH", "AVM"), + T_DATA("AzureWave", "AzureWave"), + T_DATA("Belkin", "Belkin"), + T_DATA("Belkin Components", "Belkin"), + T_DATA("Billionton Systems, Inc.", "Billionton"), + T_DATA("Broadcom Corp.", "Broadcom"), + T_DATA("Broadcom Limited", "Broadcom"), + T_DATA("Brocade Communications Systems, Inc.", "Brocade"), + T_DATA("BUFFALO INC. (formerly MelCo., Inc.)", "BUFFALO"), + T_DATA("CACE Technologies Inc.", "CACE"), + T_DATA("Cadence Design Systems, Inc.", "Cadence"), + T_DATA("Chelsio Communications Inc", "Chelsio"), + T_DATA("Chicony Electronics Co., Ltd", "Chicony"), + T_DATA("Chu Yuen Enterprise Co., Ltd", "Chu Yuen"), + T_DATA("Cisco Systems Inc", "Cisco"), + T_DATA("Cisco Systems, Inc.", "Cisco"), + T_DATA("CMOTECH Co., Ltd.", "CMOTECH"), + T_DATA("CNet Technology Inc.", "CNet"), + T_DATA("CNet Technology Inc", "CNet"), + T_DATA("Comneon", "Comneon"), + T_DATA("Compaq Computer Corp.", "Compaq"), + T_DATA("Compaq Computer Corporation", "Compaq"), + T_DATA("Compex", "Compex"), + T_DATA("Computer Access Technology Corp.", "Computer Access"), + T_DATA("Conexant Systems, Inc.", "Conexant"), + T_DATA("Conexant Systems (Rockwell), Inc.", "Conexant"), + T_DATA("Corega K.K.", "Corega K.K."), + T_DATA("Curitel Communications, Inc.", "Curitel"), + T_DATA("CyberTAN Technology", "CyberTAN"), + T_DATA("Cypress Semiconductor Corp.", "Cypress"), + T_DATA("Davicom Semiconductor, Inc.", "Davicom"), + T_DATA("Dell Computer Corp.", "Dell"), + T_DATA("DELTA Electronics, Inc", "DELTA"), + T_DATA("Digital Equipment Corporation", "Digital Equipment"), + T_DATA("D-Link Corp.", "D-Link"), + T_DATA("D-Link System", "D-Link System"), + T_DATA("D-Link System Inc", "D-Link System"), + T_DATA("DrayTek Corp.", "DrayTek"), + T_DATA("d'TV", "d'TV"), + T_DATA("DVICO", "DVICO"), + T_DATA("Edimax Computer Co.", "Edimax"), + T_DATA("Edimax Technology Co., Ltd", "Edimax"), + T_DATA("Efar Microsystems", "Efar"), + T_DATA("Efficient Networks, Inc.", "Efficient"), + T_DATA("ELCON Systemtechnik", "ELCON"), + T_DATA("Elecom Co., Ltd", "Elecom"), + T_DATA("ELSA AG", "ELSA"), + T_DATA("Emulex Corporation", "Emulex"), + T_DATA("Encore Electronics Inc.", "Encore"), + T_DATA("EndPoints, Inc.", "EndPoints"), + T_DATA("Entrega [hex]", "Entrega"), + T_DATA("Ericsson Business Mobile Networks BV", "Ericsson"), + T_DATA("eTEK Labs", "eTEK"), + T_DATA("Exar Corp.", "Exar"), + T_DATA("Fiberline", "Fiberline"), + T_DATA("Fujitsu Limited.", "Fujitsu"), + T_DATA("Fujitsu Siemens Computers", "Fujitsu Siemens"), + T_DATA("Gateway, Inc.", "Gateway"), + T_DATA("Gemtek", "Gemtek"), + T_DATA("Genesys Logic, Inc.", "Genesys Logic"), + T_DATA("Global Sun Technology", "Global Sun"), + T_DATA("Global Sun Technology, Inc.", "Global Sun"), + T_DATA("GlobeSpan, Inc.", "GlobeSpan"), + T_DATA("Gmate, Inc.", "Gmate"), + T_DATA("Good Way Technology", "Good Way"), + T_DATA("Guillemot Corp.", "Guillemot"), + T_DATA("Hangzhou Silan Microelectronics Co., Ltd.", "Hangzhou Silan"), + T_DATA("Hawking Technologies", "Hawking"), + T_DATA("Hewlett-Packard", "Hewlett-Packard"), + T_DATA("Hirose Electric", "Hirose Electric"), + T_DATA("Holtek Microelectronics Inc", "Holtek"), + T_DATA("Huawei-3Com", "Huawei-3Com"), + T_DATA("Huawei Technologies Co., Ltd.", "Huawei"), + T_DATA("ICS Advent", "ICS Advent"), + T_DATA("IMC Networks", "IMC"), + T_DATA("Intel Corp.", "Intel"), + T_DATA("Intel Corporation", "Intel"), + T_DATA("Intellon Corp.", "Intellon"), + T_DATA("InterBiometrics", "InterBiometrics"), + T_DATA("Intersil Corp.", "Intersil"), + T_DATA("Intersil Corporation", "Intersil"), + T_DATA("I-O Data Device, Inc.", "I-O Data Device"), + T_DATA("Jaton Corp.", "Jaton"), + T_DATA("JMicron Technology Corp.", "JMicron"), + T_DATA("Kawasaki LSI", "Kawasaki LSI"), + T_DATA("KC Technology, Inc.", "KC"), + T_DATA("Kingston Technology", "Kingston"), + T_DATA("KTI", "KTI"), + T_DATA("Kvaser AB", "Kvaser"), + T_DATA("LapLink, Inc.", "LapLink"), + T_DATA("Lenovo", "Lenovo"), + T_DATA("LevelOne", "LevelOne"), + T_DATA("LG Electronics, Inc.", "LG"), + T_DATA("LG Electronics USA, Inc.", "LG"), + T_DATA("Linksys, Inc.", "Linksys"), + T_DATA("Linksys (?)", "Linksys"), + T_DATA("Linksys", "Linksys"), + T_DATA("Lite-On Communications Inc", "Lite-On"), + T_DATA("Lite-On Technology Corp.", "Lite-On"), + T_DATA("Logitec Corp.", "Logitec"), + T_DATA("Logitech, Inc.", "Logitech"), + T_DATA("LSI Corporation", "LSI"), + T_DATA("LSI Logic / Symbios Logic", "LSI Logic"), + T_DATA("Macronix, Inc. [MXIC]", "MXIC"), + T_DATA("Marvell Semiconductor, Inc.", "Marvell"), + T_DATA("Marvell Technology Group Ltd.", "Marvell"), + T_DATA("MediaTek Inc.", "MediaTek"), + T_DATA("Mellanox Technologies", "Mellanox"), + T_DATA("Memorex", "Memorex"), + T_DATA("Micrel-Kendin", "Micrel-Kendin"), + T_DATA("Microchip Technology, Inc.", "Microchip"), + T_DATA("Microcomputer Systems (M) Son", "Microcomputer"), + T_DATA("Microsoft Corp.", "Microsoft"), + T_DATA("Microsoft Corporation", "Microsoft"), + T_DATA("Micro-Star International Co., Ltd. [MSI]", "MSI"), + T_DATA("Micro Star International", "Micro Star"), + T_DATA("Mobility", "Mobility"), + T_DATA("MosChip Semiconductor", "MosChip"), + T_DATA("Motorola PCS", "Motorola"), + T_DATA("MYRICOM Inc.", "MYRICOM"), + T_DATA("MYSON Technology Inc", "MYSON"), + T_DATA("National Instruments Corp.", "National"), + T_DATA("National Semiconductor Corporation", "National"), + T_DATA("NEC Corp.", "NEC"), + T_DATA("Netchip Technology, Inc.", "Netchip"), + T_DATA("Netgear, Inc", "Netgear"), + T_DATA("NetGear, Inc.", "NetGear"), + T_DATA("Netgear", "Netgear"), + T_DATA("Netopia, Inc.", "Netopia"), + T_DATA("Netronome Systems, Inc.", "Netronome"), + T_DATA("NetVin", "NetVin"), + T_DATA("NetXen Incorporated", "NetXen"), + T_DATA("Nordic Semiconductor ASA", "Nordic"), + T_DATA("Northern Telecom", "Northern Telecom"), + T_DATA("NovaTech", "NovaTech"), + T_DATA("Novatel Wireless", "Novatel Wireless"), + T_DATA("NVIDIA Corp.", "NVIDIA"), + T_DATA("NVIDIA Corporation", "NVIDIA"), + T_DATA("Olicom", "Olicom"), + T_DATA("Olivetti Techcenter", "Olivetti"), + T_DATA("Olympus Optical Co., Ltd", "Olympus"), + T_DATA("OMEGA TECHNOLOGY", "OMEGA"), + T_DATA("Omnidirectional Control Technology, Inc.", "Omnidirectional Control"), + T_DATA("OpenMoko, Inc.", "OpenMoko"), + T_DATA("Option", "Option"), + T_DATA("OQO", "OQO"), + T_DATA("Oracle/SUN", "Oracle"), + T_DATA("Ovislink Corp.", "Ovislink"), + T_DATA("Packet Engines Inc.", "Packet Engines"), + T_DATA("Panasonic (Matsushita)", "Panasonic"), + T_DATA("PEAK System", "PEAK System"), + T_DATA("PEAK-System Technik GmbH", "PEAK-System"), + T_DATA("PEGATRON CORPORATION", "PEGATRON CORPORATION"), + T_DATA("Peppercon AG", "Peppercon"), + T_DATA("Peracom Networks, Inc.", "Peracom"), + T_DATA("Philips (or NXP)", "Philips"), + T_DATA("Planex Communications, Inc", "Planex"), + T_DATA("Planex Communications", "Planex"), + T_DATA("Planex", "Planex"), + T_DATA("PLANEX", "PLANEX"), + T_DATA("Portsmith", "Portsmith"), + T_DATA("Prolific Technology, Inc.", "Prolific"), + T_DATA("Qcom", "Qcom"), + T_DATA("Qi Hardware", "Qi"), + T_DATA("QinHeng Electronics", "QinHeng"), + T_DATA("QLogic Corp.", "QLogic"), + T_DATA("Qualcomm Atheros Communications", "Qualcomm Atheros"), + T_DATA("Qualcomm Atheros", "Qualcomm Atheros"), + T_DATA("Qualcomm, Inc.", "Qualcomm"), + T_DATA("Qualcomm / Option", "Qualcomm"), + T_DATA("Quanta Computer, Inc.", "Quanta Computer"), + T_DATA("Quanta Microsystems, Inc.", "Quanta"), + T_DATA("Quantenna Communications, Inc.", "Quantenna"), + T_DATA("RadioShack Corp. (Tandy)", "RadioShack"), + T_DATA("Ralink corp.", "Ralink"), + T_DATA("Ralink Technology, Corp.", "Ralink"), + T_DATA("RDC Semiconductor, Inc.", "RDC"), + T_DATA("Realtek Semiconductor Co., Ltd.", "Realtek"), + T_DATA("Realtek Semiconductor Corp.", "Realtek"), + T_DATA("Red Hat, Inc.", "Red Hat"), + T_DATA("SafeNet (wrong ID)", "SafeNet"), + T_DATA("Sagem", "Sagem"), + T_DATA("Samsung Electronics Co., Ltd", "Samsung"), + T_DATA("Sega Enterprises Ltd", "Sega"), + T_DATA("Senao", "Senao"), + T_DATA("Shark Multimedia", "Shark"), + T_DATA("Sharp Corp.", "Sharp"), + T_DATA("Siemens Information and Communication Products", "Siemens"), + T_DATA("Sierra Wireless, Inc.", "Sierra Wireless"), + T_DATA("Silicom", "Silicom"), + T_DATA("Silicon Graphics Intl. Corp.", "Silicon Graphics"), + T_DATA("Silicon Integrated Systems [SiS]", "SiS"), + T_DATA("Sitecom Europe B.V.", "Sitecom"), + T_DATA("Sitecom", "Sitecom"), + T_DATA("smartBridges, Inc.", "smartBridges"), + T_DATA("SohoWare", "SohoWare"), + T_DATA("Solarflare Communications", "Solarflare"), + T_DATA("Sony Corp.", "Sony"), + T_DATA("SpeedStream", "SpeedStream"), + T_DATA("Sphairon Access Systems GmbH", "Sphairon"), + T_DATA("Standard Microsystems Corp [SMC]", "SMC"), + T_DATA("Standard Microsystems Corp.", "Standard"), + T_DATA("STMicroelectronics", "STMicroelectronics"), + T_DATA("Sundance Technology Inc / IC Plus Corp", "Sundance"), + T_DATA("Surecom Technology Corp.", "Surecom"), + T_DATA("Surecom Technology", "Surecom"), + T_DATA("Sweex", "Sweex"), + T_DATA("SysKonnect", "SysKonnect"), + T_DATA("T & A Mobile Phones", "T & A"), + T_DATA("TDK Semiconductor Corp.", "TDK"), + T_DATA("Tehuti Networks Ltd.", "Tehuti"), + T_DATA("Tekram Technology Co., Ltd", "Tekram"), + T_DATA("Telit Wireless Solutions", "Telit"), + T_DATA("Texas Instruments, Inc.", "Texas"), + T_DATA("Thales Norway A/S", "Thales"), + T_DATA("TMT Technology, Inc.", "TMT"), + T_DATA("Toshiba Corp.", "Toshiba"), + T_DATA("TRENDnet", "TRENDnet"), + T_DATA("Trident Microsystems", "Trident"), + T_DATA("Trust International B.V.", "Trust"), + T_DATA("TTTech Computertechnik AG (Wrong ID)", "TTTech"), + T_DATA("TwinMOS", "TwinMOS"), + T_DATA("U-Blox AG", "U-Blox"), + T_DATA("ULi Electronics Inc.", "ULi"), + T_DATA("U.S. Robotics", "U.S. Robotics"), + T_DATA("Vaillant", "Vaillant"), + T_DATA("VIA Technologies, Inc.", "VIA"), + T_DATA("Victor Company of Japan, Ltd", "Victor"), + T_DATA("VMware", "VMware"), + T_DATA("VTech Holdings, Ltd", "VTech"), + T_DATA("Wavecom", "Wavecom"), + T_DATA("Westell", "Westell"), + T_DATA("Western Digital Technologies, Inc.", "Western Digital"), + T_DATA("Wilocity Ltd.", "Wilocity"), + T_DATA("Winbond Electronics Corp", "Winbond"), + T_DATA("Winbond", "Winbond"), + T_DATA("Wistron NeWeb", "Wistron NeWeb"), + T_DATA("Xircom", "Xircom"), + T_DATA("Z-Com", "Z-Com"), + T_DATA("Zinwell", "Zinwell"), + T_DATA("Zoom Telephonics, Inc.", "Zoom"), + T_DATA("ZTE WCDMA Technologies MSM", "ZTE"), + T_DATA("ZyDAS", "ZyDAS"), + T_DATA("ZyXEL Communications Corp.", "ZyXEL"), + }; + + _test_fixup_string(data, G_N_ELEMENTS(data), nm_utils_fixup_vendor_string); +} + +static void +test_fixup_product_string(void) +{ + static const TestFixupData data[] = { + T_DATA("10/100BaseTX [RTL81xx]", "RTL81xx"), + T_DATA("10/100 Ethernet", NULL), + T_DATA("10/100 Ethernet [pegasus]", "pegasus"), + T_DATA("10/100 USB Ethernet", NULL), + T_DATA("10/100 USB NIC", NULL), + T_DATA("1010/1020/1007/1741 10Gbps CNA", "1010/1020/1007/1741"), + T_DATA("1012 PCMCIA 10/100 Ethernet Card [RTL81xx]", "1012"), + T_DATA("101 Ethernet [klsi]", "101"), + T_DATA("10GbE Converged Network Adapter (TCP/IP Networking)", NULL), + T_DATA("10GbE Ethernet Adapter", NULL), + T_DATA("10 Gigabit BR KX4 Dual Port Network Connection", "BR KX4"), + T_DATA("10-Giga TOE SmartNIC 2-Port", "SmartNIC"), + T_DATA("10-Giga TOE SmartNIC", "SmartNIC"), + T_DATA("10Mbps Ethernet [klsi]", "klsi"), + T_DATA("1860 16Gbps/10Gbps Fabric Adapter", "1860"), + T_DATA("190 Ethernet Adapter", "190"), + T_DATA("191 Gigabit Ethernet Adapter", "191"), + T_DATA("21145 Fast Ethernet", "21145"), + T_DATA("21x4x DEC-Tulip compatible 10/100 Ethernet", "21x4x"), + T_DATA("21x4x DEC-Tulip compatible Fast Ethernet", "21x4x"), + T_DATA("2202 Ethernet [klsi]", "2202"), + T_DATA("2202 Ethernet [pegasus]", "2202"), + T_DATA("3C19250 Ethernet [klsi]", "3C19250"), + T_DATA("3c450 HomePNA [Tornado]", "3c450 HomePNA"), + T_DATA("3C460B 10/100 Ethernet Adapter", "3C460B"), + T_DATA("3c555 Laptop Hurricane", "3c555 Hurricane"), + T_DATA("3c556B CardBus [Tornado]", "3c556B"), + T_DATA("3c556 Hurricane CardBus [Cyclone]", "3c556 Hurricane"), + T_DATA("3c575 Megahertz 10/100 LAN CardBus [Boomerang]", "3c575 Megahertz"), + T_DATA("3c590 10BaseT [Vortex]", "3c590"), + T_DATA("3c592 EISA 10mbps Demon/Vortex", "3c592 Demon/Vortex"), + T_DATA("3c595 100Base-MII [Vortex]", "3c595"), + T_DATA("3c595 100BaseT4 [Vortex]", "3c595"), + T_DATA("3c595 100BaseTX [Vortex]", "3c595"), + T_DATA("3c595 Megahertz 10/100 LAN CardBus [Boomerang]", "3c595 Megahertz"), + T_DATA("3c597 EISA Fast Demon/Vortex", "3c597 Fast Demon/Vortex"), + T_DATA("3c900 10BaseT [Boomerang]", "3c900"), + T_DATA("3c900 10Mbps Combo [Boomerang]", "3c900 Combo"), + T_DATA("3c900B-Combo Etherlink XL [Cyclone]", "3c900B-Combo Etherlink XL"), + T_DATA("3c900B-FL 10base-FL [Cyclone]", "3c900B-FL"), + T_DATA("3c900B-TPC Etherlink XL [Cyclone]", "3c900B-TPC Etherlink XL"), + T_DATA("3c900B-TPO Etherlink XL [Cyclone]", "3c900B-TPO Etherlink XL"), + T_DATA("3c905 100BaseT4 [Boomerang]", "3c905"), + T_DATA("3c905 100BaseTX [Boomerang]", "3c905"), + T_DATA("3c905B 100BaseTX [Cyclone]", "3c905B"), + T_DATA("3c905B Deluxe Etherlink 10/100/BNC [Cyclone]", "3c905B Deluxe Etherlink"), + T_DATA("3c905B-FX Fast Etherlink XL FX 100baseFx [Cyclone]", + "3c905B-FX Fast Etherlink XL FX"), + T_DATA("3c905B-T4 Fast EtherLink XL [Cyclone]", "3c905B-T4 Fast EtherLink XL"), + T_DATA("3C905B-TX Fast Etherlink XL PCI", "3C905B-TX Fast Etherlink XL"), + T_DATA("3c905C-TX/TX-M [Tornado]", "3c905C-TX/TX-M"), + T_DATA("3C920B-EMB Integrated Fast Ethernet Controller [Tornado]", "3C920B-EMB"), + T_DATA("3C920B-EMB-WNM Integrated Fast Ethernet Controller", "3C920B-EMB-WNM"), + T_DATA("3c940 10/100/1000Base-T [Marvell]", "3c940"), + T_DATA("3c940B 10/100/1000Base-T", "3c940B"), + T_DATA("3c980-C 10/100baseTX NIC [Python-T]", "3c980-C"), + T_DATA("3c980-TX Fast Etherlink XL Server Adapter [Cyclone]", "3c980-TX Fast Etherlink XL"), + T_DATA("3c982-TXM 10/100baseTX Dual Port A [Hydra]", "3c982-TXM A"), + T_DATA("3c982-TXM 10/100baseTX Dual Port B [Hydra]", "3c982-TXM B"), + T_DATA("3c985 1000BaseSX (SX/TX)", "3c985"), + T_DATA("3C990B-TX-M/3C990BSVR [Typhoon2]", "3C990B-TX-M/3C990BSVR"), + T_DATA("3C990SVR [Typhoon Server]", "3C990SVR"), + T_DATA("3C990-TX [Typhoon]", "3C990-TX"), + T_DATA("3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone]", "3cCFE575BT Megahertz"), + T_DATA("3cCFE575CT CardBus [Cyclone]", "3cCFE575CT"), + T_DATA("3cCFE656 CardBus [Cyclone]", "3cCFE656"), + T_DATA("3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone]", "3cCFEM656B"), + T_DATA("3Com 3C920B-EMB-WNM Integrated Fast Ethernet Controller", "3Com 3C920B-EMB-WNM"), + T_DATA("3Com 3CRUSBN275 802.11abgn Wireless Adapter [Atheros AR9170]", "3Com 3CRUSBN275"), + T_DATA("3com 3CRWE154G72 [Office Connect Wireless LAN Adapter]", "3com 3CRWE154G72"), + T_DATA("3CR990-FX-95/97/95 [Typhon Fiber]", "3CR990-FX-95/97/95"), + T_DATA("3CR990SVR95 [Typhoon Server 56-bit]", "3CR990SVR95"), + T_DATA("3CR990SVR97 [Typhoon Server 168-bit]", "3CR990SVR97"), + T_DATA("3CR990-TX-95 [Typhoon 56-bit]", "3CR990-TX-95"), + T_DATA("3CR990-TX-97 [Typhoon 168-bit]", "3CR990-TX-97"), + T_DATA("3CRPAG175 Wireless PC Card", "3CRPAG175"), + T_DATA("3CRUSB10075 802.11bg [ZyDAS ZD1211]", "3CRUSB10075"), + T_DATA("3CRWE254G72 802.11g Adapter", "3CRWE254G72"), + T_DATA("3CSOHO100B-TX 910-A01 [tulip]", "3CSOHO100B-TX 910-A01"), + T_DATA("3cSOHO100-TX Hurricane", "3cSOHO100-TX Hurricane"), + T_DATA("3cXFEM656C 10/100 LAN+Winmodem CardBus [Tornado]", "3cXFEM656C"), + T_DATA("4410a Wireless-G Adapter [Intersil ISL3887]", "4410a"), + T_DATA("4DWave DX", "4DWave DX"), + T_DATA("4G LTE adapter", NULL), + T_DATA("54g USB Network Adapter", NULL), + T_DATA("570x 10/100 Integrated Controller", "570x"), + T_DATA("79c970 [PCnet32 LANCE]", "79c970"), + T_DATA("79c978 [HomePNA]", "79c978"), + T_DATA("80003ES2LAN Gigabit Ethernet Controller (Copper)", "80003ES2LAN"), + T_DATA("80003ES2LAN Gigabit Ethernet Controller (Serdes)", "80003ES2LAN"), + T_DATA("802.11a/b/g/n USB Wireless LAN Card", NULL), + T_DATA("802.11 Adapter", NULL), + T_DATA("802.11bgn 1T1R Mini Card Wireless Adapter", "1T1R"), + T_DATA("802.11bg", NULL), + T_DATA("802.11b/g/n USB Wireless LAN Card", NULL), + T_DATA("802.11b/g/n USB Wireless Network Adapter", NULL), + T_DATA("802.11b/g/n Wireless Network Adapter", NULL), + T_DATA("802.11b/g Turbo Wireless Adapter", NULL), + T_DATA("802.11b/g Wireless Network Adapter", NULL), + T_DATA("802.11g Wireless Adapter [Intersil ISL3886]", "Intersil ISL3886"), + T_DATA("802.11n adapter", NULL), + T_DATA("802.11n/b/g Mini Wireless LAN USB2.0 Adapter", NULL), + T_DATA("802.11n/b/g Wireless LAN USB2.0 Adapter", NULL), + T_DATA("802.11 n/g/b Wireless LAN Adapter", NULL), + T_DATA("802.11 n/g/b Wireless LAN USB Adapter", NULL), + T_DATA("802.11 n/g/b Wireless LAN USB Mini-Card", NULL), + T_DATA("802.11n Network Adapter", NULL), + T_DATA("802.11n Network Adapter (wrong ID - swapped vendor and device)", NULL), + T_DATA("802.11n USB Wireless Card", NULL), + T_DATA("802.11n Wireless Adapter", NULL), + T_DATA("802.11n Wireless LAN Card", NULL), + T_DATA("802.11n Wireless USB Card", NULL), + T_DATA("802AIN Wireless N Network Adapter [Atheros AR9170+AR9101]", + "Atheros AR9170+AR9101"), + T_DATA("802UIG-1 802.11g Wireless Mini Adapter [Intersil ISL3887]", "Intersil ISL3887"), + T_DATA("82540EM Gigabit Ethernet Controller", "82540EM"), + T_DATA("82540EM Gigabit Ethernet Controller (LOM)", "82540EM"), + T_DATA("82540EP Gigabit Ethernet Controller", "82540EP"), + T_DATA("82540EP Gigabit Ethernet Controller (Mobile)", "82540EP"), + T_DATA("82541EI Gigabit Ethernet Controller", "82541EI"), + T_DATA("82541ER Gigabit Ethernet Controller", "82541ER"), + T_DATA("82541GI Gigabit Ethernet Controller", "82541GI"), + T_DATA("82541PI Gigabit Ethernet Controller", "82541PI"), + T_DATA("82542 Gigabit Ethernet Controller (Fiber)", "82542"), + T_DATA("82543GC Gigabit Ethernet Controller (Copper)", "82543GC"), + T_DATA("82543GC Gigabit Ethernet Controller (Fiber)", "82543GC"), + T_DATA("82544EI Gigabit Ethernet Controller (Copper)", "82544EI"), + T_DATA("82544EI Gigabit Ethernet Controller (Fiber)", "82544EI"), + T_DATA("82544GC Gigabit Ethernet Controller (Copper)", "82544GC"), + T_DATA("82544GC Gigabit Ethernet Controller (LOM)", "82544GC"), + T_DATA("82545EM Gigabit Ethernet Controller (Copper)", "82545EM"), + T_DATA("82545EM Gigabit Ethernet Controller (Fiber)", "82545EM"), + T_DATA("82545GM Gigabit Ethernet Controller", "82545GM"), + T_DATA("82546EB Gigabit Ethernet Controller", "82546EB"), + T_DATA("82546EB Gigabit Ethernet Controller (Copper)", "82546EB"), + T_DATA("82546EB Gigabit Ethernet Controller (Fiber)", "82546EB"), + T_DATA("82546GB Gigabit Ethernet Controller", "82546GB"), + T_DATA("82546GB Gigabit Ethernet Controller (Copper)", "82546GB"), + T_DATA("82547EI Gigabit Ethernet Controller", "82547EI"), + T_DATA("82547EI Gigabit Ethernet Controller (Mobile)", "82547EI"), + T_DATA("82547GI Gigabit Ethernet Controller", "82547GI"), + T_DATA("82551QM Ethernet Controller", "82551QM"), + T_DATA("82552 10/100 Network Connection", "82552"), + T_DATA("82557/8/9/0/1 Ethernet Pro 100", "82557/8/9/0/1"), + T_DATA("82559 Ethernet Controller", "82559"), + T_DATA("82559 InBusiness 10/100", "82559 InBusiness"), + T_DATA("8255xER/82551IT Fast Ethernet Controller", "8255xER/82551IT"), + T_DATA("82562 EM/EX/GX - PRO/100 VM Ethernet Controller", "82562 EM/EX/GX"), + T_DATA("82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller", "82562 EM/EX/GX"), + T_DATA("82562EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller Mobile", "82562EM/EX/GX"), + T_DATA("82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller", "82562ET/EZ/GT/GZ"), + T_DATA("82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller", "82562ET/EZ/GT/GZ"), + T_DATA("82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller Mobile", + "82562ET/EZ/GT/GZ"), + T_DATA("82562EZ 10/100 Ethernet Controller", "82562EZ"), + T_DATA("82562G 10/100 Network Connection", "82562G"), + T_DATA("82562G-2 10/100 Network Connection", "82562G-2"), + T_DATA("82562G - PRO/100 VE Ethernet Controller Mobile", "82562G"), + T_DATA("82562G - PRO/100 VE (LOM) Ethernet Controller", "82562G"), + T_DATA("82562GT 10/100 Network Connection", "82562GT"), + T_DATA("82562GT-2 10/100 Network Connection", "82562GT-2"), + T_DATA("82562V 10/100 Network Connection", "82562V"), + T_DATA("82562V-2 10/100 Network Connection", "82562V-2"), + T_DATA("82566DC-2 Gigabit Network Connection", "82566DC-2"), + T_DATA("82566DC Gigabit Network Connection", "82566DC"), + T_DATA("82566DM-2 Gigabit Network Connection", "82566DM-2"), + T_DATA("82566DM Gigabit Network Connection", "82566DM"), + T_DATA("82566MC Gigabit Network Connection", "82566MC"), + T_DATA("82566MM Gigabit Network Connection", "82566MM"), + T_DATA("82567LF-2 Gigabit Network Connection", "82567LF-2"), + T_DATA("82567LF-3 Gigabit Network Connection", "82567LF-3"), + T_DATA("82567LF Gigabit Network Connection", "82567LF"), + T_DATA("82567LM-2 Gigabit Network Connection", "82567LM-2"), + T_DATA("82567LM-3 Gigabit Network Connection", "82567LM-3"), + T_DATA("82567LM-4 Gigabit Network Connection", "82567LM-4"), + T_DATA("82567LM Gigabit Network Connection", "82567LM"), + T_DATA("82567V-2 Gigabit Network Connection", "82567V-2"), + T_DATA("82567V-3 Gigabit Network Connection", "82567V-3"), + T_DATA("82567V-4 Gigabit Network Connection", "82567V-4"), + T_DATA("82567V Gigabit Network Connection", "82567V"), + T_DATA("82571EB Dual Port Gigabit Mezzanine Adapter", "82571EB Mezzanine"), + T_DATA("82571EB Gigabit Ethernet Controller", "82571EB"), + T_DATA("82571EB Gigabit Ethernet Controller (Copper)", "82571EB"), + T_DATA("82571EB Gigabit Ethernet Controller (Fiber)", "82571EB"), + T_DATA("82571EB Quad Port Gigabit Mezzanine Adapter", "82571EB Quad Port Mezzanine"), + T_DATA("82571PT Gigabit PT Quad Port Server ExpressModule", "82571PT PT Quad Port"), + T_DATA("82572EI Gigabit Ethernet Controller", "82572EI"), + T_DATA("82572EI Gigabit Ethernet Controller (Copper)", "82572EI"), + T_DATA("82572EI Gigabit Ethernet Controller (Fiber)", "82572EI"), + T_DATA("82573E Gigabit Ethernet Controller (Copper)", "82573E"), + T_DATA("82573L Gigabit Ethernet Controller", "82573L"), + T_DATA("82573V Gigabit Ethernet Controller (Copper)", "82573V"), + T_DATA("82574L Gigabit Network Connection", "82574L"), + T_DATA("82575EB Gigabit Backplane Connection", "82575EB Backplane Connection"), + T_DATA("82575EB Gigabit Network Connection", "82575EB"), + T_DATA("82575GB Gigabit Network Connection", "82575GB"), + T_DATA("82576 Gigabit Backplane Connection", "82576 Backplane Connection"), + T_DATA("82576 Gigabit Network Connection", "82576"), + T_DATA("82576NS Gigabit Network Connection", "82576NS"), + T_DATA("82576NS SerDes Gigabit Network Connection", "82576NS SerDes"), + T_DATA("82576 Virtual Function", "82576 Virtual Function"), + T_DATA("82577LC Gigabit Network Connection", "82577LC"), + T_DATA("82577LM Gigabit Network Connection", "82577LM"), + T_DATA("82578DC Gigabit Network Connection", "82578DC"), + T_DATA("82578DM Gigabit Network Connection", "82578DM"), + T_DATA("82579LM Gigabit Network Connection (Lewisville)", "82579LM"), + T_DATA("82579V Gigabit Network Connection", "82579V"), + T_DATA("82580 Gigabit Backplane Connection", "82580 Backplane Connection"), + T_DATA("82580 Gigabit Fiber Network Connection", "82580"), + T_DATA("82580 Gigabit Network Connection", "82580"), + T_DATA("82580 Gigabit SFP Connection", "82580 SFP Connection"), + T_DATA("82583V Gigabit Network Connection", "82583V"), + T_DATA("82597EX 10GbE Ethernet Controller", "82597EX"), + T_DATA("82598 10GbE PCI-Express Ethernet Controller", "82598"), + T_DATA("82598EB 10-Gigabit AF Dual Port Network Connection", "82598EB AF"), + T_DATA("82598EB 10-Gigabit AF Network Connection", "82598EB AF"), + T_DATA("82598EB 10-Gigabit AT2 Server Adapter", "82598EB AT2"), + T_DATA("82598EB 10-Gigabit AT CX4 Network Connection", "82598EB AT CX4"), + T_DATA("82598EB 10-Gigabit AT Network Connection", "82598EB AT"), + T_DATA("82598EB 10-Gigabit Dual Port Network Connection", "82598EB"), + T_DATA("82598EB Gigabit BX Network Connection", "82598EB BX"), + T_DATA("82599 10 Gigabit Dual Port Backplane Connection", "82599 Backplane Connection"), + T_DATA("82599 10 Gigabit Dual Port Backplane Connection with FCoE", + "82599 Backplane Connection with FCoE"), + T_DATA("82599 10 Gigabit Dual Port Network Connection", "82599"), + T_DATA("82599 10 Gigabit Dual Port Network Connection with FCoE", "82599 with FCoE"), + T_DATA("82599 10 Gigabit Network Connection", "82599"), + T_DATA("82599 10 Gigabit TN Network Connection", "82599 TN"), + T_DATA("82599ES 10 Gigabit Network Connection", "82599ES"), + T_DATA("82599ES 10-Gigabit SFI/SFP+ Network Connection", "82599ES SFI/SFP+"), + T_DATA("82599 Ethernet Controller Virtual Function", "82599 Virtual Function"), + T_DATA("82599 Virtual Function", "82599 Virtual Function"), + T_DATA("82801BA/BAM/CA/CAM Ethernet Controller", "82801BA/BAM/CA/CAM"), + T_DATA("82801CAM (ICH3) PRO/100 VE Ethernet Controller", "82801CAM"), + T_DATA("82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller", "82801CAM"), + T_DATA("82801CAM (ICH3) PRO/100 VM Ethernet Controller", "82801CAM"), + T_DATA("82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller", "82801CAM"), + T_DATA("82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller", "82801CAM"), + T_DATA("82801DB PRO/100 VE (CNR) Ethernet Controller", "82801DB PRO/100 VE"), + T_DATA("82801DB PRO/100 VE (LOM) Ethernet Controller", "82801DB PRO/100 VE"), + T_DATA("82801DB PRO/100 VE (MOB) Ethernet Controller", "82801DB PRO/100 VE"), + T_DATA("82801DB PRO/100 VM (CNR) Ethernet Controller", "82801DB PRO/100 VM"), + T_DATA("82801DB PRO/100 VM (LOM) Ethernet Controller", "82801DB PRO/100 VM"), + T_DATA("82801DB PRO/100 VM (MOB) Ethernet Controller", "82801DB PRO/100 VM"), + T_DATA("82801EB/ER (ICH5/ICH5R) integrated LAN Controller", "82801EB/ER"), + T_DATA("82801E Ethernet Controller 0", "82801E 0"), + T_DATA("82801E Ethernet Controller 1", "82801E 1"), + T_DATA("83c170 EPIC/100 Fast Ethernet Adapter", "83c170 EPIC/100"), + T_DATA("83c175 EPIC/100 Fast Ethernet Adapter", "83c175 EPIC/100"), + T_DATA("83C885 NT50 DigitalScape Fast Ethernet", "83C885 NT50 DigitalScape"), + T_DATA("88E8001 Gigabit Ethernet Controller", "88E8001"), + T_DATA("88E8021 PCI-X IPMI Gigabit Ethernet Controller", "88E8021 IPMI"), + T_DATA("88E8022 PCI-X IPMI Gigabit Ethernet Controller", "88E8022 IPMI"), + T_DATA("88E8035 PCI-E Fast Ethernet Controller", "88E8035"), + T_DATA("88E8036 PCI-E Fast Ethernet Controller", "88E8036"), + T_DATA("88E8038 PCI-E Fast Ethernet Controller", "88E8038"), + T_DATA("88E8039 PCI-E Fast Ethernet Controller", "88E8039"), + T_DATA("88E8040 PCI-E Fast Ethernet Controller", "88E8040"), + T_DATA("88E8040T PCI-E Fast Ethernet Controller", "88E8040T"), + T_DATA("88E8042 PCI-E Fast Ethernet Controller", "88E8042"), + T_DATA("88E8048 PCI-E Fast Ethernet Controller", "88E8048"), + T_DATA("88E8050 PCI-E ASF Gigabit Ethernet Controller", "88E8050 ASF"), + T_DATA("88E8052 PCI-E ASF Gigabit Ethernet Controller", "88E8052 ASF"), + T_DATA("88E8053 PCI-E Gigabit Ethernet Controller", "88E8053"), + T_DATA("88E8055 PCI-E Gigabit Ethernet Controller", "88E8055"), + T_DATA("88E8056 PCI-E Gigabit Ethernet Controller", "88E8056"), + T_DATA("88E8057 PCI-E Gigabit Ethernet Controller", "88E8057"), + T_DATA("88E8058 PCI-E Gigabit Ethernet Controller", "88E8058"), + T_DATA("88E8061 PCI-E IPMI Gigabit Ethernet Controller", "88E8061 IPMI"), + T_DATA("88E8062 PCI-E IPMI Gigabit Ethernet Controller", "88E8062 IPMI"), + T_DATA("88E8070 based Ethernet Controller", "88E8070 based"), + T_DATA("88E8071 PCI-E Gigabit Ethernet Controller", "88E8071"), + T_DATA("88E8072 PCI-E Gigabit Ethernet Controller", "88E8072"), + T_DATA("88E8075 PCI-E Gigabit Ethernet Controller", "88E8075"), + T_DATA("88EC032 Ethernet Controller", "88EC032"), + T_DATA("88EC033 PCI-E Fast Ethernet Controller", "88EC033"), + T_DATA("88EC034 Ethernet Controller", "88EC034"), + T_DATA("88EC036 PCI-E Gigabit Ethernet Controller", "88EC036"), + T_DATA("88EC042 Ethernet Controller", "88EC042"), + T_DATA("88W8363 [TopDog] 802.11n Wireless", "88W8363"), + T_DATA("88W8366 [TopDog] 802.11n Wireless", "88W8366"), + T_DATA("88W8388 802.11a/b/g WLAN", "88W8388"), + T_DATA("88W8687 [TopDog] 802.11b/g Wireless", "88W8687"), + T_DATA("88W8764 [Avastar] 802.11n Wireless", "88W8764"), + T_DATA("88W8897 [AVASTAR] 802.11ac Wireless", "88W8897"), + T_DATA("A90-211WG-01 802.11g Adapter [Intersil ISL3887]", "A90-211WG-01"), + T_DATA("A9T wireless 802.11bg", "A9T"), + T_DATA("AboCom Systems Inc [WN2001 Prolink Wireless-N Nano Adapter]", "AboCom Systems Inc"), + T_DATA("AC1000 Gigabit Ethernet", "AC1000"), + T_DATA("AC1001 Gigabit Ethernet", "AC1001"), + T_DATA("AC1003 Gigabit Ethernet", "AC1003"), + T_DATA("AC9100 Gigabit Ethernet", "AC9100"), + T_DATA("AceNIC Gigabit Ethernet", "AceNIC"), + T_DATA("AceNIC Gigabit Ethernet (Copper)", "AceNIC"), + T_DATA("Acer Gobi 2000 Wireless Modem", "Acer Gobi 2000"), + T_DATA("Acer Gobi Wireless Modem", "Acer Gobi"), + T_DATA("ADM8511 Pegasus II Ethernet", "ADM8511 Pegasus II"), + T_DATA("ADMtek ADM8515 NIC", "ADMtek ADM8515"), + T_DATA("ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter", + "ADMtek Centaur-C"), + T_DATA("ADSL Modem", NULL), + T_DATA("AE1000 v1 802.11n [Ralink RT3572]", "AE1000"), + T_DATA("AE1200 802.11bgn Wireless Adapter [Broadcom BCM43235]", "AE1200"), + T_DATA("AE3000 802.11abgn (3x3) Wireless Adapter [Ralink RT3573]", "AE3000"), + T_DATA("AG-225H 802.11bg", "AG-225H"), + T_DATA("Air2210 54 Mbps Wireless Adapter", "Air2210"), + T_DATA("Air2310 150 Mbps Wireless Adapter", "Air2310"), + T_DATA("Airlink101 AWLL6070 802.11bgn Wireless Adapter [Ralink RT2770]", + "Airlink101 AWLL6070"), + T_DATA("Airlink101 AWLL6080 802.11bgn Wireless Adapter [Ralink RT2870]", + "Airlink101 AWLL6080"), + T_DATA("AirLive WL-1600USB 802.11g Adapter [Realtek RTL8187L]", "AirLive WL-1600USB"), + T_DATA("AirLive WN-200USB wireless 11b/g/n dongle", "AirLive WN-200USB"), + T_DATA("AirLive WN-360USB adapter", "AirLive WN-360USB"), + T_DATA("AirLive X.USB 802.11abgn [Atheros AR9170+AR9104]", "AirLive X.USB"), + T_DATA("AirPcap NX [Atheros AR9001U-(2)NG]", "AirPcap NX"), + T_DATA("AirPlus G DWL-G120 Wireless Adapter(rev.C) [Intersil ISL3887]", + "AirPlus G DWL-G120"), + T_DATA("AirPlus G DWL-G122 Wireless Adapter(rev.A1) [Intersil ISL3880]", + "AirPlus G DWL-G122"), + T_DATA("AirPlus G DWL-G122 Wireless Adapter(rev.A2) [Intersil ISL3887]", + "AirPlus G DWL-G122"), + T_DATA("AirPlus G DWL-G122 Wireless Adapter(rev.B1) [Ralink RT2571]", "AirPlus G DWL-G122"), + T_DATA("AirPlus G DWL-G122 Wireless Adapter(rev.C1) [Ralink RT2571W]", + "AirPlus G DWL-G122"), + T_DATA("AirPlus G DWL-G122 Wireless Adapter(rev.E1) [Ralink RT2070]", "AirPlus G DWL-G122"), + T_DATA("Alcatel One Touch L100V / Telekom Speedstick LTE II", + "Alcatel One Touch L100V / Telekom Speedstick II"), + T_DATA("Allnet ALL0283 [AR5523]", "Allnet ALL0283"), + T_DATA("Allnet ALL0283 [AR5523](no firmware)", "Allnet ALL0283"), + T_DATA("Allnet ALL0298 v2 802.11bg", "Allnet ALL0298"), + T_DATA("AM10 v1 802.11n [Ralink RT3072]", "AM10"), + T_DATA("AMD-8111 Ethernet", "AMD-8111"), + T_DATA("AN2720 USB-USB Bridge", "AN2720 USB-USB Bridge"), + T_DATA("AN8513 Ethernet", "AN8513"), + T_DATA("AN8515 Ethernet", "AN8515"), + T_DATA("AN986A Ethernet", "AN986A"), + T_DATA("AN986 Pegasus Ethernet", "AN986 Pegasus"), + T_DATA("ANA620xx/ANA69011A", "ANA620xx/ANA69011A"), + T_DATA("AN-WF500 802.11abgn + BT Wireless Adapter [Broadcom BCM43242]", "AN-WF500"), + T_DATA("Aolynk WUB320g", "Aolynk WUB320g"), + T_DATA("AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg]", "AR2413/AR2414"), + T_DATA("AR2417 Wireless Network Adapter [AR5007G 802.11bg]", "AR2417"), + T_DATA("AR2425 Wireless Network Adapter [AR5007EG 802.11bg]", "AR2425"), + T_DATA("AR2427 802.11bg Wireless Network Adapter (PCI-Express)", "AR2427"), + T_DATA("AR242x / AR542x Wireless Network Adapter (PCI-Express)", "AR242x / AR542x"), + T_DATA("AR5210 Wireless Network Adapter [AR5000 802.11a]", "AR5210"), + T_DATA("AR5211 Wireless Network Adapter [AR5001A 802.11a]", "AR5211"), + T_DATA("AR5211 Wireless Network Adapter [AR5001X 802.11ab]", "AR5211"), + T_DATA("AR5212/5213/2414 Wireless Network Adapter", "AR5212/5213/2414"), + T_DATA("AR5212 802.11abg NIC (3CRDAG675)", "AR5212"), + T_DATA("AR5212 802.11abg NIC", "AR5212"), + T_DATA("AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg]", "AR5413/AR5414"), + T_DATA("AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn]", "AR5416"), + T_DATA("AR5418 Wireless Network Adapter [AR5008E 802.11(a)bgn] (PCI-Express)", "AR5418"), + T_DATA("AR5523", "AR5523"), + T_DATA("AR5523 driver (no firmware)", "AR5523"), + T_DATA("AR5523 (no firmware)", "AR5523"), + T_DATA("AR7010 (no firmware)", "AR7010"), + T_DATA("AR8121/AR8113/AR8114 Gigabit or Fast Ethernet", "AR8121/AR8113/AR8114"), + T_DATA("AR8131 Gigabit Ethernet", "AR8131"), + T_DATA("AR8132 Fast Ethernet", "AR8132"), + T_DATA("AR8151 v1.0 Gigabit Ethernet", "AR8151 v1.0"), + T_DATA("AR8151 v2.0 Gigabit Ethernet", "AR8151 v2.0"), + T_DATA("AR8152 v1.1 Fast Ethernet", "AR8152"), + T_DATA("AR8152 v2.0 Fast Ethernet", "AR8152 v2.0"), + T_DATA("AR8161 Gigabit Ethernet", "AR8161"), + T_DATA("AR8162 Fast Ethernet", "AR8162"), + T_DATA("AR9160 Wireless Network Adapter [AR9001 802.11(a)bgn]", "AR9160"), + T_DATA("AR9170 802.11n", "AR9170"), + T_DATA("AR9170+AR9104 802.11abgn Wireless Adapter", "AR9170+AR9104"), + T_DATA("AR9227 Wireless Network Adapter", "AR9227"), + T_DATA("AR922X Wireless Network Adapter", "AR922X"), + T_DATA("AR922X Wireless Network Adapter (Compex WLM200NX / Wistron DNMA-92)", "AR922X"), + T_DATA("AR9271 802.11n", "AR9271"), + T_DATA("AR9285 Wireless Network Adapter (PCI-Express)", "AR9285"), + T_DATA("AR9285 Wireless Network Adapter (PCI-Express) (AW-NB037H 802.11bgn Wireless " + "Half-size Mini PCIe Card [AR9002WB-1NGCD])", + "AR9285"), + T_DATA("AR9287 Wireless Network Adapter (PCI-Express)", "AR9287"), + T_DATA("AR928X Wireless Network Adapter (PCI-Express)", "AR928X"), + T_DATA("AR928X Wireless Network Adapter (PCI-Express) (EM306 802.11bgn Wireless Half-size " + "Mini PCIe Card [AR9283])", + "AR928X"), + T_DATA("AR928X Wireless Network Adapter (PCI-Express) (T77H047.31 802.11bgn Wireless " + "Half-size Mini PCIe Card [AR9283])", + "AR928X"), + T_DATA("AR93xx Wireless Network Adapter", "AR93xx"), + T_DATA("AR93xx Wireless Network Adapter (Killer Wireless-N 1102 Half-size Mini PCIe Card " + "[AR9382])", + "AR93xx"), + T_DATA("AR93xx Wireless Network Adapter (Killer Wireless-N 1103 Half-size Mini PCIe Card " + "[AR9380])", + "AR93xx"), + T_DATA("AR9462 Wireless Network Adapter", "AR9462"), + T_DATA("AR9462 Wireless Network Adapter (Wireless 1601 802.11abgn Adapter)", "AR9462"), + T_DATA("AR9462 Wireless Network Adapter (Wireless 1802 802.11abgn Adapter)", "AR9462"), + T_DATA("AR9485 Wireless Network Adapter", "AR9485"), + T_DATA("AR9485 Wireless Network Adapter (AR9485WB-EG 802.11b/g/n mini-PCIe card on a " + "series 3 laptop)", + "AR9485"), + T_DATA("AR9485 Wireless Network Adapter (AW-NE186H)", "AR9485"), + T_DATA("AR958x 802.11abgn Wireless Network Adapter", "AR958x"), + T_DATA("Arcadyan 802.11N Wireless Adapter", "Arcadyan"), + T_DATA("Arcadyan WN4501 802.11b/g", "Arcadyan WN4501"), + T_DATA("Arcadyan WN7512 802.11n", "Arcadyan WN7512"), + T_DATA("Asus Gobi 2000 Wireless Modem", "Asus Gobi 2000"), + T_DATA("Aterm PA-WL54GU", "Aterm PA-WL54GU"), + T_DATA("Aterm WL300NU-AG", "Aterm WL300NU-AG"), + T_DATA("Aterm WL300NU-G", "Aterm WL300NU-G"), + T_DATA("Attansic L1 Gigabit Ethernet", "Attansic L1"), + T_DATA("Attansic L2c Gigabit Ethernet", "Attansic L2c"), + T_DATA("Attansic L2 Fast Ethernet", "Attansic L2"), + T_DATA("AT-USB100", "AT-USB100"), + T_DATA("AX88141 Fast Ethernet Controller", "AX88141"), + T_DATA("AX88178", "AX88178"), + T_DATA("AX88179 Gigabit Ethernet", "AX88179"), + T_DATA("AX88179 Gigabit Ethernet [Sitecom]", "AX88179"), + T_DATA("AX88179 Gigabit Ethernet [ThinkPad OneLink GigaLAN]", "AX88179"), + T_DATA("AX88772A Fast Ethernet", "AX88772A"), + T_DATA("AX88772", "AX88772"), + T_DATA("AX88772B", "AX88772B"), + T_DATA("AX88772B Fast Ethernet Controller", "AX88772B"), + T_DATA("B404-BT Unified Wire Ethernet Controller", "B404-BT"), + T_DATA("B404-BT Unified Wire Ethernet Controller [VF]", "B404-BT"), + T_DATA("B420-SR Unified Wire Ethernet Controller", "B420-SR"), + T_DATA("B420-SR Unified Wire Ethernet Controller [VF]", "B420-SR"), + T_DATA("B504-BT Unified Wire Ethernet Controller", "B504-BT"), + T_DATA("B504-BT Unified Wire Ethernet Controller [VF]", "B504-BT"), + T_DATA("B520-SR Unified Wire Ethernet Controller", "B520-SR"), + T_DATA("B520-SR Unified Wire Ethernet Controller [VF]", "B520-SR"), + T_DATA("BCM43142 802.11b/g/n", "BCM43142"), + T_DATA("BCM43143 802.11bgn (1x1) Wireless Adapter", "BCM43143"), + T_DATA("BCM43143 WLAN card", "BCM43143"), + T_DATA("BCM43236 802.11abgn Wireless Adapter", "BCM43236"), + T_DATA("BCM43241 WLAN card", "BCM43241"), + T_DATA("BCM43242 802.11abgn Wireless Adapter", "BCM43242"), + T_DATA("BCM4329 WLAN card", "BCM4329"), + T_DATA("BCM4330 WLAN card", "BCM4330"), + T_DATA("BCM43340 WLAN card", "BCM43340"), + T_DATA("BCM43341 WLAN card", "BCM43341"), + T_DATA("BCM4334 WLAN card", "BCM4334"), + T_DATA("BCM4335/BCM4339 WLAN card", "BCM4335/BCM4339"), + T_DATA("BCM43362 WLAN card", "BCM43362"), + T_DATA("BCM4350 802.11ac Wireless Network Adapter", "BCM4350"), + T_DATA("BCM4354 WLAN card", "BCM4354"), + T_DATA("BCM43567 802.11ac Wireless Network Adapter", "BCM43567"), + T_DATA("BCM4356 802.11ac Wireless Network Adapter", "BCM4356"), + T_DATA("BCM43570 802.11ac Wireless Network Adapter", "BCM43570"), + T_DATA("BCM4358 802.11ac Wireless LAN SoC", "BCM4358"), + T_DATA("BCM43602 802.11ac Wireless LAN SoC", "BCM43602"), + T_DATA("BCM4401 100Base-T", "BCM4401"), + T_DATA("BCM4401-B0 100Base-TX", "BCM4401-B0"), + T_DATA("BCM4402 Integrated 10/100BaseT", "BCM4402"), + T_DATA("BCM57301 NetXtreme-C 10Gb Ethernet Controller", "BCM57301 NetXtreme-C"), + T_DATA("BCM57302 NetXtreme-C 10Gb/25Gb Ethernet Controller", "BCM57302 NetXtreme-C"), + T_DATA("BCM57304 NetXtreme-C 10Gb/25Gb/40Gb/50Gb Ethernet Controller", + "BCM57304 NetXtreme-C"), + T_DATA("BCM57311 NetXtreme-C 10Gb RDMA Ethernet Controller", "BCM57311 NetXtreme-C"), + T_DATA("BCM57312 NetXtreme-C 10Gb/25Gb RDMA Ethernet Controller", "BCM57312 NetXtreme-C"), + T_DATA("BCM57314 NetXtreme-C 10Gb/25Gb/40Gb/50Gb RDMA Ethernet Controller", + "BCM57314 NetXtreme-C"), + T_DATA("BCM57402 NetXtreme-E 10Gb Ethernet Controller", "BCM57402 NetXtreme-E"), + T_DATA("BCM57402 NetXtreme-E Ethernet Partition", "BCM57402 NetXtreme-E Partition"), + T_DATA("BCM57404 NetXtreme-E 10Gb/25Gb Ethernet Controller", "BCM57404 NetXtreme-E"), + T_DATA("BCM57404 NetXtreme-E Ethernet Partition", "BCM57404 NetXtreme-E Partition"), + T_DATA("BCM57406 NetXtreme-E 10GBASE-T Ethernet Controller", "BCM57406 NetXtreme-E"), + T_DATA("BCM57406 NetXtreme-E Ethernet Partition", "BCM57406 NetXtreme-E Partition"), + T_DATA("BCM57407 NetXtreme-E 10GBase-T Ethernet Controller", "BCM57407 NetXtreme-E"), + T_DATA("BCM57407 NetXtreme-E 25Gb Ethernet Controller", "BCM57407 NetXtreme-E"), + T_DATA("BCM57412 NetXtreme-E 10Gb RDMA Ethernet Controller", "BCM57412 NetXtreme-E"), + T_DATA("BCM57412 NetXtreme-E Ethernet Partition", "BCM57412 NetXtreme-E Partition"), + T_DATA("BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller", "BCM57414 NetXtreme-E"), + T_DATA("BCM57414 NetXtreme-E Ethernet Partition", "BCM57414 NetXtreme-E Partition"), + T_DATA("BCM57414 NetXtreme-E RDMA Partition", "BCM57414 NetXtreme-E Partition"), + T_DATA("BCM57416 NetXtreme-E 10GBase-T RDMA Ethernet Controller", "BCM57416 NetXtreme-E"), + T_DATA("BCM57416 NetXtreme-E 10Gb RDMA Ethernet Controller", "BCM57416 NetXtreme-E"), + T_DATA("BCM57416 NetXtreme-E Ethernet Partition", "BCM57416 NetXtreme-E Partition"), + T_DATA("BCM57416 NetXtreme-E RDMA Partition", "BCM57416 NetXtreme-E Partition"), + T_DATA("BCM57417 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller", "BCM57417 NetXtreme-E"), + T_DATA("BCM57417 NetXtreme-E 10GBASE-T RDMA Ethernet Controller", "BCM57417 NetXtreme-E"), + T_DATA("BCM57417 NetXtreme-E Ethernet Partition", "BCM57417 NetXtreme-E Partition"), + T_DATA("BCM57840 NetXtreme II 10/20-Gigabit Ethernet", "BCM57840 NetXtreme II"), + T_DATA("BCM57840 NetXtreme II 10 Gigabit Ethernet", "BCM57840 NetXtreme II"), + T_DATA("BCM57840 NetXtreme II Ethernet Multi Function", "BCM57840 NetXtreme II"), + T_DATA("Belkin F5D5005 Gigabit Desktop Network PCI Card", "Belkin F5D5005"), + T_DATA("ben-wpan, AT86RF230-based", "ben-wpan AT86RF230-based"), + T_DATA("BladeCenter-H 10-Gigabit Ethernet High Speed Daughter Card", + "BladeCenter-H High Speed Daughter"), + T_DATA("BladeEngine2 10Gb Gen2 PCIe Network Adapter", "BladeEngine2 Gen2"), + T_DATA("BladeEngine3 10Gb Gen2 PCIe Network Adapter", "BladeEngine3 Gen2"), + T_DATA("BLOB boot loader firmware", "BLOB boot loader firmware"), + T_DATA("Broadcom NetXtreme BCM5701 Gigabit Ethernet", "Broadcom NetXtreme BCM5701"), + T_DATA("BWIFI-USB54AR 802.11bg", "BWIFI-USB54AR"), + T_DATA("Cardbus Ethernet 10/100", NULL), + T_DATA("Cassini 10/100/1000", "Cassini"), + T_DATA("CE Media Processor Gigabit Ethernet Controller", NULL), + T_DATA("Centrino Advanced-N 6200", "Centrino Advanced-N 6200"), + T_DATA("Centrino Advanced-N 6205 [Taylor Peak]", "Centrino Advanced-N 6205"), + T_DATA("Centrino Advanced-N 6230 [Rainbow Peak]", "Centrino Advanced-N 6230"), + T_DATA("Centrino Advanced-N 6235", "Centrino Advanced-N 6235"), + T_DATA("Centrino Advanced-N + WiMAX 6250 [Kilmer Peak]", "Centrino Advanced-N 6250"), + T_DATA("Centrino Ultimate-N 6300", "Centrino Ultimate-N 6300"), + T_DATA("Centrino Wireless-N 1000 [Condor Peak]", "Centrino 1000"), + T_DATA("Centrino Wireless-N 100", "Centrino 100"), + T_DATA("Centrino Wireless-N 1030 [Rainbow Peak]", "Centrino 1030"), + T_DATA("Centrino Wireless-N 105", "Centrino 105"), + T_DATA("Centrino Wireless-N 130", "Centrino 130"), + T_DATA("Centrino Wireless-N 135", "Centrino 135"), + T_DATA("Centrino Wireless-N 2200", "Centrino 2200"), + T_DATA("Centrino Wireless-N 2230", "Centrino 2230"), + T_DATA("Centrino Wireless-N + WiMAX 6150", "Centrino 6150"), + T_DATA("CG-WLUSB10 Corega Wireless USB Adapter", "CG-WLUSB10 Corega"), + T_DATA("CG-WLUSB2GNL", "CG-WLUSB2GNL"), + T_DATA("CG-WLUSB2GNR Corega Wireless USB Adapter", "CG-WLUSB2GNR Corega"), + T_DATA("CG-WLUSB2GO", "CG-WLUSB2GO"), + T_DATA("CG-WLUSB2GPX [Ralink RT2571W]", "CG-WLUSB2GPX"), + T_DATA("CG-WLUSB2GT 802.11g Wireless Adapter [Intersil ISL3880]", "CG-WLUSB2GT"), + T_DATA("CG-WLUSB2GTST 802.11g Wireless Adapter [Intersil ISL3887]", "CG-WLUSB2GTST"), + T_DATA("CG-WLUSB300AGN", "CG-WLUSB300AGN"), + T_DATA("CG-WLUSB300GNM", "CG-WLUSB300GNM"), + T_DATA("CG-WLUSB300GNS", "CG-WLUSB300GNS"), + T_DATA("CK804 Ethernet Controller", "CK804"), + T_DATA("CK8S Ethernet Controller", "CK8S"), + T_DATA("cLOM8214 1/10GbE Controller", "cLOM8214"), + T_DATA("CMOTECH CDMA Technologies modem", "CMOTECH"), + T_DATA("Cohiba 802.11g Wireless Mini adapter [Intersil ISL3887]", "Cohiba"), + T_DATA("Conceptronic C300RU v1 802.11bgn Wireless Adapter [Ralink RT2870]", + "Conceptronic C300RU"), + T_DATA("Conceptronic C300RU v2 802.11bgn Wireless Adapter [Ralink RT2770]", + "Conceptronic C300RU"), + T_DATA("Conceptronic C54RU v2 802.11bg Wireless Adapter [Ralink RT2571]", + "Conceptronic C54RU"), + T_DATA("Conceptronic C54RU v3 802.11bg Wireless Adapter [Ralink RT2571W]", + "Conceptronic C54RU"), + T_DATA("Connect2Air E-5400 802.11g Wireless Adapter", "Connect2Air E-5400"), + T_DATA("Connect2Air E-5400 D1700 802.11g Wireless Adapter [Intersil ISL3887]", + "Connect2Air E-5400 D1700"), + T_DATA("CPWUE001 USB/Ethernet Adapter", "CPWUE001"), + T_DATA("CWD-854 rev F", "CWD-854"), + T_DATA("CWD-854 [RT2573]", "CWD-854"), + T_DATA("CWD-854 Wireless 802.11g 54Mbps Network Adapter [RTL8187]", "CWD-854"), + T_DATA("DECchip 21040 [Tulip]", "DECchip 21040"), + T_DATA("DECchip 21041 [Tulip Pass 3]", "DECchip 21041"), + T_DATA("DECchip 21140 [FasterNet]", "DECchip 21140"), + T_DATA("DECchip 21142/43", "DECchip 21142/43"), + T_DATA("DFE-680TXD CardBus PC Card", "DFE-680TXD"), + T_DATA("DFE-690TXD CardBus PC Card", "DFE-690TXD"), + T_DATA("DGE-528T Gigabit Ethernet Adapter", "DGE-528T"), + T_DATA("DGE-528T Gigabit Ethernet Adapter (DGE-560T PCI Express (x1) Gigabit Ethernet " + "Adapter)", + "DGE-528T"), + T_DATA("DGE-530T Gigabit Ethernet Adapter (rev 11)", "DGE-530T"), + T_DATA("DGE-530T Gigabit Ethernet Adapter (rev.C1) [Realtek RTL8169]", "DGE-530T"), + T_DATA("DGE-550SX PCI-X Gigabit Ethernet Adapter", "DGE-550SX"), + T_DATA("DGE-550T Gigabit Ethernet Adapter V.B1", "DGE-550T V.B1"), + T_DATA("DGE-560SX PCI Express Gigabit Ethernet Adapter", "DGE-560SX"), + T_DATA("DGE-560T PCI Express Gigabit Ethernet Adapter", "DGE-560T"), + T_DATA("DH8900CC Series Gigabit Backplane Network Connection", "DH8900CC Backplane"), + T_DATA("DH8900CC Series Gigabit Fiber Network Connection", "DH8900CC"), + T_DATA("DH8900CC Series Gigabit Network Connection", "DH8900CC"), + T_DATA("DH8900CC Series Gigabit SFP Network Connection", "DH8900CC SFP"), + T_DATA("Direct Connect", "Direct Connect"), + T_DATA("DL10050 Sundance Ethernet (DFE-550TX/FX)", "DL10050 Sundance"), + T_DATA("DL10050 Sundance Ethernet (DFE-580TX)", "DL10050 Sundance"), + T_DATA("DL10050 Sundance Ethernet", "DL10050 Sundance"), + T_DATA("DL2000-based Gigabit Ethernet", "DL2000-based"), + T_DATA("DM9000E Fast Ethernet Adapter", "DM9000E"), + T_DATA("DM9601 Fast Ethernet Adapter", "DM9601"), + T_DATA("DP83065 [Saturn] 10/100/1000 Ethernet Controller", "DP83065"), + T_DATA("DP83815 (MacPhyter) Ethernet Controller (Aculab E1/T1 PMXc cPCI carrier card)", + "DP83815"), + T_DATA("DP83815 (MacPhyter) Ethernet Controller", "DP83815"), + T_DATA("DP83820 10/100/1000 Ethernet Controller", "DP83820"), + T_DATA("DrayTek Vigor N61 802.11bgn Wireless Adapter [Ralink RT2870]", "DrayTek Vigor N61"), + T_DATA("DRP-32TXD Cardbus PC Card", "DRP-32TXD"), + T_DATA("DSB-650 10Mbps Ethernet [klsi]", "DSB-650"), + T_DATA("DSB-650C Ethernet [klsi]", "DSB-650C"), + T_DATA("DSB-650 Ethernet [pegasus]", "DSB-650"), + T_DATA("DSB-650TX Ethernet [pegasus]", "DSB-650TX"), + T_DATA("DSB-650TX-PNA Ethernet [pegasus]", "DSB-650TX-PNA"), + T_DATA("Dual Band Wireless-AC 3165 Plus Bluetooth", "Wireless-AC 3165"), + T_DATA("DUB-E100 Fast Ethernet Adapter(rev.A) [ASIX AX88172]", "DUB-E100"), + T_DATA("DUB-E100 Fast Ethernet Adapter(rev.B1) [ASIX AX88772]", "DUB-E100"), + T_DATA("DUB-E100 Fast Ethernet Adapter(rev.C1) [ASIX AX88772]", "DUB-E100"), + T_DATA("DU-E100 Ethernet [pegasus]", "DU-E100"), + T_DATA("DU-E10 Ethernet [klsi]", "DU-E10"), + T_DATA("DU-E10 Ethernet [pegasus]", "DU-E10"), + T_DATA("DWA-110 Wireless G Adapter(rev.A1) [Ralink RT2571W]", "DWA-110"), + T_DATA("DWA-110 Wireless G Adapter(rev.B) [Ralink RT2870]", "DWA-110"), + T_DATA("DWA-111 802.11bg Wireless Adapter [Ralink RT2571W]", "DWA-111"), + T_DATA("DWA-121 802.11n Wireless N 150 Pico Adapter [Realtek RTL8188CUS]", + "DWA-121 150 Pico"), + T_DATA("DWA-123 Wireless N 150 Adapter(rev.A1) [Ralink RT3370]", "DWA-123 150"), + T_DATA("DWA-125 Wireless N 150 Adapter(rev.A1) [Ralink RT3070]", "DWA-125 150"), + T_DATA("DWA-125 Wireless N 150 Adapter(rev.A2) [Ralink RT3070]", "DWA-125 150"), + T_DATA("DWA-125 Wireless N 150 Adapter(rev.A3) [Ralink RT5370]", "DWA-125 150"), + T_DATA("DWA-126 802.11n Wireless Adapter [Atheros AR9271]", "DWA-126"), + T_DATA("DWA-127 Wireless N 150 High-Gain Adapter(rev.A1) [Ralink RT3070]", + "DWA-127 150 High-Gain"), + T_DATA("DWA-130 802.11n Wireless N Adapter(rev.B) [Ralink RT2870]", "DWA-130"), + T_DATA("DWA-130 802.11n Wireless N Adapter(rev.D) [Atheros AR9170+AR9102]", "DWA-130"), + T_DATA("DWA-133 802.11n Wireless N Adapter [Realtek RTL8192CU]", "DWA-133"), + T_DATA("DWA-135 802.11n Wireless N Adapter(rev.A1) [Realtek RTL8192CU]", "DWA-135"), + T_DATA("DWA-140 RangeBooster N Adapter(rev.B1) [Ralink RT2870]", "DWA-140 RangeBooster N"), + T_DATA("DWA-140 RangeBooster N Adapter(rev.B2) [Ralink RT3072]", "DWA-140 RangeBooster N"), + T_DATA("DWA-140 RangeBooster N Adapter(rev.B3) [Ralink RT2870]", "DWA-140 RangeBooster N"), + T_DATA("DWA-140 RangeBooster N Adapter(rev.B3) [Ralink RT5372]", "DWA-140 RangeBooster N"), + T_DATA("DWA-160 802.11abgn Xtreme N Dual Band Adapter(rev.A1) [Atheros AR9170+AR9104]", + "DWA-160 Xtreme N"), + T_DATA("DWA-160 802.11abgn Xtreme N Dual Band Adapter(rev.A2) [Atheros AR9170+AR9104]", + "DWA-160 Xtreme N"), + T_DATA("DWA-160 802.11abgn Xtreme N Dual Band Adapter(rev.B2) [Ralink RT5572]", + "DWA-160 Xtreme N"), + T_DATA("DWA-160 Xtreme N Dual Band USB Adapter(rev.B) [Ralink RT2870]", "DWA-160 Xtreme N"), + T_DATA("DWL-510 / DWL-610 802.11b [Realtek RTL8180L]", "DWL-510 / DWL-610"), + T_DATA("DWL-AG122 [Atheros AR5523]", "DWL-AG122"), + T_DATA("DWL-AG122 (no firmware) [Atheros AR5523]", "DWL-AG122"), + T_DATA("DWL-AG132 [Atheros AR5523]", "DWL-AG132"), + T_DATA("DWL-AG132 (no firmware) [Atheros AR5523]", "DWL-AG132"), + T_DATA("DWL-G120 Spinnaker 802.11g [Intersil ISL3886]", "DWL-G120 Spinnaker"), + T_DATA("DWL-G132 [Atheros AR5523]", "DWL-G132"), + T_DATA("DWL-G132 (no firmware) [Atheros AR5523]", "DWL-G132"), + T_DATA("DY-WL10 802.11abgn Adapter [Broadcom BCM4323]", "DY-WL10"), + T_DATA("E180v", "E180v"), + T_DATA("E45 Ethernet [klsi]", "E45"), + T_DATA("E815", "E815"), + T_DATA("EA101 10 Mbps 10BASE-T Ethernet [Kawasaki LSI KL5KLUSB101B]", "EA101"), + T_DATA("EasiDock Ethernet", "EasiDock"), + T_DATA("EH103 Wireless G Adapter", "EH103"), + T_DATA("Eminent EM4045 [Broadcom 4320 USB]", "Eminent EM4045"), + T_DATA("EN-1216 Ethernet Adapter", "EN-1216"), + T_DATA("EN-1217 Ethernet Adapter", "EN-1217"), + T_DATA("Enet2 Ethernet [klsi]", "Enet2"), + T_DATA("Enet Ethernet [klsi]", "Enet"), + T_DATA("EnGenius 802.11n Wireless USB Adapter", "EnGenius"), + T_DATA("ENUWI-N3 [802.11n Wireless N150 Adapter]", "ENUWI-N3"), + T_DATA("EP-1427X-2 Ethernet Adapter [Acer]", "EP-1427X-2"), + T_DATA("EP-9001-g 802.11g 54M WLAN Adapter", "EP-9001-g"), + T_DATA("ET-131x PCI-E Ethernet Controller", "ET-131x"), + T_DATA("ET32P2", "ET32P2"), + T_DATA("ETG-US2", "ETG-US2"), + T_DATA("Ethernet 100/10 MBit", NULL), + T_DATA("Ethernet 10G 2P X520 Adapter", "2P X520"), + T_DATA("Ethernet Adapter [A1277]", "A1277"), + T_DATA("Ethernet Adapter", NULL), + T_DATA("Ethernet adapter [U2L 100P-Y1]", "U2L 100P-Y1"), + T_DATA("Ethernet Adaptive Virtual Function", "Adaptive Virtual Function"), + T_DATA("Ethernet Connection (2) I218-LM", NULL), + T_DATA("Ethernet Connection (2) I218-V", NULL), + T_DATA("Ethernet Connection (2) I219-LM", NULL), + T_DATA("Ethernet Connection (2) I219-V", NULL), + T_DATA("Ethernet Connection (3) I218-LM", NULL), + T_DATA("Ethernet Connection (3) I218-V", NULL), + T_DATA("Ethernet Connection (3) I219-LM", NULL), + T_DATA("Ethernet Connection (4) I219-LM", NULL), + T_DATA("Ethernet Connection (4) I219-V", NULL), + T_DATA("Ethernet Connection (5) I219-LM", NULL), + T_DATA("Ethernet Connection (5) I219-V", NULL), + T_DATA("Ethernet Connection (6) I219-LM", NULL), + T_DATA("Ethernet Connection (6) I219-V", NULL), + T_DATA("Ethernet Connection (7) I219-LM", NULL), + T_DATA("Ethernet Connection (7) I219-V", NULL), + T_DATA("Ethernet Connection (8) I219-LM", NULL), + T_DATA("Ethernet Connection (8) I219-V", NULL), + T_DATA("Ethernet Connection (9) I219-LM", NULL), + T_DATA("Ethernet Connection (9) I219-V", NULL), + T_DATA("Ethernet Connection I217-LM", "I217-LM"), + T_DATA("Ethernet Connection I217-V", "I217-V"), + T_DATA("Ethernet Connection I218-LM", "I218-LM"), + T_DATA("Ethernet Connection I218-V", "I218-V"), + T_DATA("Ethernet Connection I219-LM", "I219-LM"), + T_DATA("Ethernet Connection I219-V", "I219-V"), + T_DATA("Ethernet Connection I354 1.0 GbE Backplane", "I354 Backplane"), + T_DATA("Ethernet Connection I354 2.5 GbE Backplane", "I354 Backplane"), + T_DATA("Ethernet Connection I354", "I354"), + T_DATA("Ethernet Connection X552 1000BASE-T", "X552"), + T_DATA("Ethernet Connection X552 10 GbE Backplane", "X552 Backplane"), + T_DATA("Ethernet Connection X552 10 GbE SFP+", "X552 SFP+"), + T_DATA("Ethernet Connection X552 Backplane", "X552 Backplane"), + T_DATA("Ethernet Connection X552 Virtual Function", "X552 Virtual Function"), + T_DATA("Ethernet Connection X552/X557-AT 10GBASE-T", "X552/X557-AT"), + T_DATA("Ethernet Connection X553 10 GbE SFP+", "X553 SFP+"), + T_DATA("Ethernet Connection X553 1GbE", "X553"), + T_DATA("Ethernet Connection X553 Backplane", "X553 Backplane"), + T_DATA("Ethernet Connection X553/X557-AT 10GBASE-T", "X553/X557-AT"), + T_DATA("Ethernet Connection X722 for 10GBASE-T", "X722"), + T_DATA("Ethernet Connection X722 for 10GbE backplane", "X722"), + T_DATA("Ethernet Connection X722 for 10GbE QSFP+", "X722"), + T_DATA("Ethernet Connection X722 for 10GbE SFP+", "X722"), + T_DATA("Ethernet Connection X722 for 1GbE", "X722"), + T_DATA("Ethernet Controller 10-Gigabit X540-AT2", "X540-AT2"), + T_DATA("Ethernet Controller 10G X550T", "X550T"), + T_DATA("Ethernet Controller X540", "X540"), + T_DATA("Ethernet Controller X710 for 10GBASE-T", "X710"), + T_DATA("Ethernet Controller X710 for 10GbE backplane", "X710"), + T_DATA("Ethernet Controller X710 for 10GbE QSFP+", "X710"), + T_DATA("Ethernet Controller X710 for 10GbE SFP+", "X710"), + T_DATA("Ethernet Controller X710/X557-AT 10GBASE-T", "X710/X557-AT"), + T_DATA("Ethernet Controller XL710 for 20GbE backplane", "XL710"), + T_DATA("Ethernet Controller XL710 for 40GbE backplane", "XL710"), + T_DATA("Ethernet Controller XL710 for 40GbE QSFP+", "XL710"), + T_DATA("Ethernet Controller XXV710 for 25GbE backplane", "XXV710"), + T_DATA("Ethernet Controller XXV710 for 25GbE SFP28", "XXV710"), + T_DATA("Ethernet Converged Network Adapter X520-Q1", "X520-Q1"), + T_DATA("Ethernet Express Module X520-P2", "X520-P2"), + T_DATA("Ethernet HN210E", "HN210E"), + T_DATA("Ethernet", NULL), + T_DATA("Ethernet Server Adapter X520-4", "X520-4"), + T_DATA("Ethernet Switch FM10000 Host Interface", "FM10000"), + T_DATA("Ethernet Switch FM10000 Host Virtual Interface", "FM10000"), + T_DATA("Ethernet X520 10GbE Dual Port KX4 Mezz", "X520 KX4 Mezz"), + T_DATA("Ether USB-T Ethernet [klsi]", "Ether USB-T"), + T_DATA("ET/TX Ethernet [pegasus]", "ET/TX"), + T_DATA("ET/TX-S Ethernet [pegasus2]", "ET/TX-S"), + T_DATA("EUB-3701 EXT 802.11g Wireless Adapter [Ralink RT2571W]", "EUB-3701 EXT"), + T_DATA("EUB600v1 802.11abgn Wireless Adapter [Ralink RT3572]", "EUB600v1"), + T_DATA("EUB9706 802.11n Wireless Adapter [Ralink RT3072]", "EUB9706"), + T_DATA("EUB9801 802.11abgn Wireless Adapter [Ralink RT3572]", "EUB9801"), + T_DATA("EW-7711UTn nLite Wireless Adapter [Ralink RT2870]", "EW-7711UTn nLite"), + T_DATA("EW-7717UN 802.11n Wireless Adapter [Ralink RT2870]", "EW-7717UN"), + T_DATA("EW-7718UN 802.11n Wireless Adapter [Ralink RT2870]", "EW-7718UN"), + T_DATA("EW-7722UTn 802.11n Wireless Adapter [Ralink RT307x]", "EW-7722UTn"), + T_DATA("EW-7811Un 802.11n Wireless Adapter [Realtek RTL8188CUS]", "EW-7811Un"), + T_DATA("Expedite E362", "Expedite E362"), + T_DATA("Express Ethernet", "Express"), + T_DATA("EZ Connect USB Ethernet", "EZ Connect"), + T_DATA("F5D5050 100Mbps Ethernet", "F5D5050"), + T_DATA("F5D5055 Gigabit Network Adapter [AX88xxx]", "F5D5055"), + T_DATA("F5D6001 Wireless PCI Card [Realtek RTL8180]", "F5D6001"), + T_DATA("F5D6020 v3000 Wireless PCMCIA Card [Realtek RTL8180]", "F5D6020 v3000"), + T_DATA("F5D7000 v7000 Wireless G Desktop Card [Realtek RTL8185]", "F5D7000 v7000"), + T_DATA("F5D7010 v7000 Wireless G Notebook Card [Realtek RTL8185]", "F5D7010 v7000"), + T_DATA("F5D7050 Wireless G Adapter v1000/v2000 [Intersil ISL3887]", "F5D7050 v1000/v2000"), + T_DATA("F5D7050 Wireless G Adapter v3000 [Ralink RT2571W]", "F5D7050 v3000"), + T_DATA("F5D7050 Wireless G Adapter v4000 [Zydas ZD1211B]", "F5D7050 v4000"), + T_DATA("F5D7050 Wireless G Adapter v5000 [Realtek RTL8187B]", "F5D7050 v5000"), + T_DATA("F5D7051 802.11g Adapter v1000 [Broadcom 4320 USB]", "F5D7051 v1000"), + T_DATA("F5D8053 N Wireless Adapter v3000 [Ralink RT2870]", "F5D8053 v3000"), + T_DATA("F5D8053 N Wireless USB Adapter v1000/v4000 [Ralink RT2870]", "F5D8053 v1000/v4000"), + T_DATA("F5D8053 N Wireless USB Adapter v3000 [Ralink RT2870]", "F5D8053 v3000"), + T_DATA("F5D8055 N+ Wireless Adapter v1000 [Ralink RT2870]", "F5D8055 v1000"), + T_DATA("F5D8055 N+ Wireless Adapter v2000 [Ralink RT3072]", "F5D8055 v2000"), + T_DATA("F5D9050 Wireless G+ MIMO Network Adapter v3000 [Ralink RT2573]", + "F5D9050 MIMO v3000"), + T_DATA("F5D9050 Wireless G+ MIMO Network Adapter v4000 [Ralink RT2573]", + "F5D9050 MIMO v4000"), + T_DATA("F5U258 Host to Host cable", "F5U258 Host to Host cable"), + T_DATA("F6D4050 N150 Enhanced Wireless Network Adapter v1000 [Ralink RT3070]", + "F6D4050 N150 v1000"), + T_DATA("F6D4050 N150 Enhanced Wireless Network Adapter v2000 [Ralink RT3070]", + "F6D4050 N150 v2000"), + T_DATA("F7D1101 v2 Basic Wireless Adapter [Ralink RT3370]", "F7D1101"), + T_DATA("F7D1102 N150/Surf Micro Wireless Adapter v1000 [Realtek RTL8188CUS]", + "F7D1102 N150/Surf v1000"), + T_DATA("F7D2102 802.11n N300 Micro Wireless Adapter v3000 [Realtek RTL8192CU]", + "F7D2102 N300 v3000"), + T_DATA("F9L1004 802.11n Surf N300 XR Wireless Adapter [Realtek RTL8192CU]", + "F9L1004 Surf N300 XR"), + T_DATA("F9L1103 N750 DB 802.11abgn 2x3:3 [Ralink RT3573]", "F9L1103 N750"), + T_DATA("FA101 Fast Ethernet USB 1.1", "FA101"), + T_DATA("FA120 Fast Ethernet USB 2.0 [Asix AX88172 / AX8817x]", "FA120"), + T_DATA("Farallon PN9000SX Gigabit Ethernet", "Farallon PN9000SX"), + T_DATA("Farallon PN9100-T Gigabit Ethernet", "Farallon PN9100-T"), + T_DATA("Fast Ethernet", NULL), + T_DATA("FastLinQ QL41000 Series 10/25/40/50GbE Controller", "FastLinQ QL41000"), + T_DATA("FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF)", + "FastLinQ QL41000"), + T_DATA("FastLinQ QL45000 Series 100GbE Controller", "FastLinQ QL45000"), + T_DATA("FastLinQ QL45000 Series 25GbE Controller", "FastLinQ QL45000"), + T_DATA("FastLinQ QL45000 Series 40GbE Controller", "FastLinQ QL45000"), + T_DATA("FastLinQ QL45000 Series Gigabit Ethernet Controller (SR-IOV VF)", + "FastLinQ QL45000"), + T_DATA("FEther USB2-TX", "FEther USB2-TX"), + T_DATA("FEther USB-TXC", "FEther USB-TXC"), + T_DATA("FEther USB-TX Ethernet [pegasus]", "FEther USB-TX"), + T_DATA("FEther USB-TXS", "FEther USB-TXS"), + T_DATA("FNW-3602-TX CardBus Fast Ethernet", "FNW-3602-TX"), + T_DATA("FNW-3603-TX CardBus Fast Ethernet", "FNW-3603-TX"), + T_DATA("FPC-0106TX misprogrammed [RTL81xx]", "FPC-0106TX"), + T_DATA("Fritz!WLAN N 2.4 [Atheros AR9001U]", "Fritz!WLAN N 2.4"), + T_DATA("Fritz!WLAN N [Atheros AR9001U]", "Fritz!WLAN N"), + T_DATA("Fritz!WLAN N v2 [Atheros AR9271]", "Fritz!WLAN N"), + T_DATA("FRITZ WLAN N v2 [RT5572/rt2870.bin]", "FRITZ N"), + T_DATA("G-200 v2 802.11bg", "G-200"), + T_DATA("G-210H 802.11g Wireless Adapter", "G-210H"), + T_DATA("G-220 v2 802.11bg", "G-220"), + T_DATA("G240 802.11bg", "G240"), + T_DATA("GA620 Gigabit Ethernet", "GA620"), + T_DATA("GA630 Gigabit Ethernet", "GA630"), + T_DATA("GEM 10/100/1000 Ethernet [ge]", "GEM"), + T_DATA("Gigabit Ethernet Adapter", NULL), + T_DATA("Gigabit Network Adapter", NULL), + T_DATA("GigaCard Network Adapter", "GigaCard"), + T_DATA("Gigaset USB Adapter 300", "Gigaset 300"), + T_DATA("GL620USB-A GeneLink USB-USB Bridge", "GL620USB-A GeneLink USB-USB Bridge"), + T_DATA("GlobeTrotter Express 7.2 v2", "GlobeTrotter Express 7.2"), + T_DATA("Globetrotter GI0505 [iCON 505]", "Globetrotter GI0505"), + T_DATA("Globetrotter HSDPA Modem", "Globetrotter"), + T_DATA("Globetrotter HSUPA Modem (aka icon 451)", "Globetrotter"), + T_DATA("Globetrotter HSUPA Modem (aka iCON HSUPA E)", "Globetrotter"), + T_DATA("Globetrotter HSUPA Modem (icon 411 aka \"Vodafone K3760\")", "Globetrotter"), + T_DATA("Globetrotter MO40x 3G Modem (GTM 382)", "Globetrotter MO40x"), + T_DATA("GN-54G", "GN-54G"), + T_DATA("GN-BR402W", "GN-BR402W"), + T_DATA("GNIC-II PCI Gigabit Ethernet [Hamachi]", "GNIC-II"), + T_DATA("GN-WB01GS", "GN-WB01GS"), + T_DATA("GN-WB30N 802.11n WLAN Card", "GN-WB30N"), + T_DATA("GN-WB31N 802.11n USB WLAN Card", "GN-WB31N"), + T_DATA("GN-WB32L 802.11n USB WLAN Card", "GN-WB32L"), + T_DATA("GN-WBKG", "GN-WBKG"), + T_DATA("GN-WI05GS", "GN-WI05GS"), + T_DATA("Gobi 2000", "Gobi 2000"), + T_DATA("Gobi 2000 Wireless Modem", "Gobi 2000"), + T_DATA("Gobi 3000 HSPA+ Modem", "Gobi 3000 HSPA+"), + T_DATA("Gobi 9x15 Multimode 3G/4G LTE Modem (IP passthrough mode)", "Gobi 9x15"), + T_DATA("Gobi 9x15 Multimode 3G/4G LTE Modem (NAT mode)", "Gobi 9x15"), + T_DATA("Gobi Wireless Modem", "Gobi"), + T_DATA("Goldpfeil P-LAN", "Goldpfeil P-LAN"), + T_DATA("GT-B3730 Composite LTE device (Commercial)", "GT-B3730"), + T_DATA("GU-1000T", "GU-1000T"), + T_DATA("GWUS300 802.11n", "GWUS300"), + T_DATA("GW-US300MiniS", "GW-US300MiniS"), + T_DATA("GW-US300MiniW 802.11bgn Wireless Adapter", "GW-US300MiniW"), + T_DATA("GW-US54GXS 802.11bg", "GW-US54GXS"), + T_DATA("GW-US54GZ", "GW-US54GZ"), + T_DATA("GW-US54HP", "GW-US54HP"), + T_DATA("GW-US54Mini2", "GW-US54Mini2"), + T_DATA("GW-US54Mini 802.11bg", "GW-US54Mini"), + T_DATA("GW-US54ZGL 802.11bg", "GW-US54ZGL"), + T_DATA("GWUSB2E", "GWUSB2E"), + T_DATA("GW-USEco300 802.11bgn Wireless Adapter [Realtek RTL8192CU]", "GW-USEco300"), + T_DATA("GW-USMicro300", "GW-USMicro300"), + T_DATA("GW-USMini2N 802.11n Wireless Adapter [Ralink RT2870]", "GW-USMini2N"), + T_DATA("GW-USNano2 802.11n Wireless Adapter [Realtek RTL8188CUS]", "GW-USNano2"), + T_DATA("GW-USValue-EZ 802.11n Wireless Adapter [Realtek RTL8188CUS]", "GW-USValue-EZ"), + T_DATA("Happy Meal 10/100 Ethernet [hme]", "Happy Meal"), + T_DATA("Harmony 900/1100 Remote", "Harmony 900/1100 Remote"), + T_DATA("HAWNU1 Hi-Gain Wireless-150N Network Adapter with Range Amplifier [Ralink RT3070]", + "HAWNU1"), + T_DATA("HCF 56k Modem", "HCF"), + T_DATA("Hercules HWNUp-150 802.11n Wireless N Pico [Realtek RTL8188CUS]", + "Hercules HWNUp-150 Pico"), + T_DATA("HNE-300 (RealTek RTL8139c) [iPaq Networking]", "HNE-300"), + T_DATA("HomeConnect 3C460", "HomeConnect 3C460"), + T_DATA("@Home Networks Ethernet [klsi]", "@Home Networks"), + T_DATA("HU200TS Wireless Adapter", "HU200TS"), + T_DATA("HWDN1 Hi-Gain Wireless-300N Dish Adapter [Ralink RT2870]", "HWDN1"), + T_DATA("HWDN2 Hi-Gain Wireless-150N Dish Adapter [Ralink RT2770]", "HWDN2"), + T_DATA("HWGUSB2-54-LB", "HWGUSB2-54-LB"), + T_DATA("HWGUSB2-54V2-AP", "HWGUSB2-54V2-AP"), + T_DATA("HWGUSB2-54 WLAN", "HWGUSB2-54"), + T_DATA("HWU54DM", "HWU54DM"), + T_DATA("HWUN1 Hi-Gain Wireless-300N Adapter w/ Upgradable Antenna [Ralink RT2870]", + "HWUN1"), + T_DATA("HWUN2 Hi-Gain Wireless-150N Adapter w/ Upgradable Antenna [Ralink RT2770]", + "HWUN2"), + T_DATA("HWUN3 Hi-Gain Wireless-N Adapter [Ralink RT3070]", "HWUN3"), + T_DATA("I210 Gigabit Backplane Connection", "I210 Backplane Connection"), + T_DATA("I210 Gigabit Fiber Network Connection", "I210"), + T_DATA("I210 Gigabit Network Connection", "I210"), + T_DATA("I211 Gigabit Network Connection", "I211"), + T_DATA("I350 Ethernet Controller Virtual Function", "I350 Virtual Function"), + T_DATA("I350 Gigabit Backplane Connection", "I350 Backplane Connection"), + T_DATA("I350 Gigabit Connection", "I350 Connection"), + T_DATA("I350 Gigabit Fiber Network Connection", "I350"), + T_DATA("I350 Gigabit Network Connection", "I350"), + T_DATA("IC Plus IP100A Integrated 10/100 Ethernet MAC + PHY", "IC Plus IP100A"), + T_DATA("IEEE 802.11g Wireless Network Adapter", NULL), + T_DATA("IFU-WLM2 USB Wireless LAN Module (Wireless Mode)", "IFU-WLM2"), + T_DATA("Integrated NetFlex-3/P", "NetFlex-3/P"), + T_DATA("Intrepid2 GMAC (Sun GEM)", "Intrepid2 GMAC"), + T_DATA("IOGear GWU513 v2 802.11bg Wireless Adapter [Intersil ISL3887]", "IOGear GWU513"), + T_DATA("IP1000 Family Gigabit Ethernet", "IP1000"), + T_DATA("iPad 2 (3G; 64GB)", "iPad 2"), + T_DATA("iPad 3 (3G, 16 GB)", "iPad 3"), + T_DATA("iPad 4/Mini1", "iPad 4/Mini1"), + T_DATA("iPad", "iPad"), + T_DATA("iPAQ Networking 10/100 Ethernet [pegasus2]", "iPAQ Networking"), + T_DATA("iPhone 3G", "iPhone"), + T_DATA("iPhone 3GS", "iPhone 3GS"), + T_DATA("iPhone 4(CDMA)", "iPhone 4"), + T_DATA("iPhone 4", "iPhone 4"), + T_DATA("iPhone 4S", "iPhone 4S"), + T_DATA("iPhone5/5C/5S/6", "iPhone5/5C/5S/6"), + T_DATA("iPhone", "iPhone"), + T_DATA("iRex Technologies Gobi 2000 Wireless Modem", "iRex Gobi 2000"), + T_DATA("ISL3877 [Prism Indigo]", "ISL3877"), + T_DATA("ISL3886IK", "ISL3886IK"), + T_DATA("ISL3886 [Prism Javelin/Prism Xbow]", "ISL3886"), + T_DATA("ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow]", "ISL3890"), + T_DATA("ISP4022-based Ethernet NIC", "ISP4022-based"), + T_DATA("ISP4032-based Ethernet IPv6 NIC", "ISP4032-based IPv6"), + T_DATA("ISP8324 1/10GbE Converged Network Controller", "ISP8324"), + T_DATA("ISP8324 1/10GbE Converged Network Controller (NIC VF)", "ISP8324"), + T_DATA("ISY Wireless Micro Adapter IWL 2000 [RTL8188CUS]", "ISY IWL 2000"), + T_DATA("JMC250 PCI Express Gigabit Ethernet Controller", "JMC250"), + T_DATA("JMC260 PCI Express Fast Ethernet Controller", "JMC260"), + T_DATA("K2 GMAC (Sun GEM)", "K2 GMAC"), + T_DATA("K3565-Z HSDPA", "K3565-Z"), + T_DATA("K3570-Z", "K3570-Z"), + T_DATA("K3571-Z", "K3571-Z"), + T_DATA("K4505-Z", "K4505-Z"), + T_DATA("K5006-Z vodafone LTE/UMTS/GSM Modem/Networkcard", "K5006-Z vodafone"), + T_DATA("KC2190 USB Host-to-Host cable", "KC2190 Host-to-Host cable"), + T_DATA("Keebox W150NU 802.11bgn Wireless Adapter [Ralink RT3070]", "Keebox W150NU"), + T_DATA("Killer E220x Gigabit Ethernet Controller", "Killer E220x"), + T_DATA("Killer E2400 Gigabit Ethernet Controller", "Killer E2400"), + T_DATA("KL5KUSB101B Ethernet [klsi]", "KL5KUSB101B"), + T_DATA("KNU101TX 100baseTX Ethernet", "KNU101TX 100baseTX"), + T_DATA("KSZ8842-PMQL 2-Port Ethernet Switch", "KSZ8842-PMQL"), + T_DATA("KwikLink Host-Host Connector", "KwikLink Host-Host Connector"), + T_DATA("LAN7500 Ethernet 10/100/1000 Adapter", "LAN7500"), + T_DATA("LAN9420/LAN9420i", "LAN9420/LAN9420i"), + T_DATA("LAN9512/LAN9514 Ethernet 10/100 Adapter (SAL10)", "LAN9512/LAN9514"), + T_DATA("Laneed 100Mbps Ethernet LD-USB/TX [pegasus]", "Laneed LD-USB/TX"), + T_DATA("LAN-GTJ/U2A", "LAN-GTJ/U2A"), + T_DATA("LAN-W150N/U2 Wireless LAN Adapter", "LAN-W150N/U2"), + T_DATA("LAN-W150/U2M Wireless LAN Adapter", "LAN-W150/U2M"), + T_DATA("LAN-W300AN/U2 Wireless LAN Adapter", "LAN-W300AN/U2"), + T_DATA("LAN-W300N/U2 Wireless LAN Adapter", "LAN-W300N/U2"), + T_DATA("LAN-WN12/U2 Wireless LAN Adapter", "LAN-WN12/U2"), + T_DATA("LAN-WN22/U2 Wireless LAN Adapter", "LAN-WN22/U2"), + T_DATA("LapLink Gold USB-USB Bridge [net1080]", "LapLink Gold USB-USB Bridge"), + T_DATA("LD-USB20", "LD-USB20"), + T_DATA("LD-USBL/TX", "LD-USBL/TX"), + T_DATA("LD-USB/TX", "LD-USB/TX"), + T_DATA("LE920", "LE920"), + T_DATA("Leaf Light HS", "Leaf Light HS"), + T_DATA("Leaf SemiPro HS", "Leaf SemiPro HS"), + T_DATA("LevelOne WUA-0605 N_Max Wireless USB Adapter", "LevelOne WUA-0605 N Max"), + T_DATA("LevelOne WUA-0615 N_Max Wireless USB Adapter", "LevelOne WUA-0615 N Max"), + T_DATA("Libertas", "Libertas"), + T_DATA("Linksys WUSB54GP v1 OEM 802.11g Adapter [Intersil ISL3886]", "Linksys WUSB54GP"), + T_DATA("Linksys WUSB54G v1 OEM 802.11g Adapter [Intersil ISL3886]", "Linksys WUSB54G"), + T_DATA("Linux-USB \"CDC Subset\" Device, or Itsy (experimental)", "Linux-USB or Itsy"), + T_DATA("Linux-USB Ethernet/RNDIS Gadget", "Linux-USB Gadget"), + T_DATA("LN-028 Network USB 2.0 Adapter", "LN-028"), + T_DATA("LN-031 10/100/1000 Ethernet Adapter", "LN-031"), + T_DATA("LNE100TX [Linksys EtherFast 10/100]", "LNE100TX"), + T_DATA("LNE100TX", "LNE100TX"), + T_DATA("lt4112 Gobi 4G Module Network Device", "lt4112 Gobi"), + T_DATA("LTE4G O2 ZTE MF821D LTE/UMTS/GSM Modem/Networkcard", "LTE4G O2 ZTE MF821D"), + T_DATA("LTE Storage Driver [CMC2xx]", "Storage Driver"), + T_DATA("LUA2-TX Ethernet", "LUA2-TX"), + T_DATA("LUA-KTX Ethernet", "LUA-KTX"), + T_DATA("LUA-TX Ethernet", "LUA-TX"), + T_DATA("LUA-TX Ethernet [pegasus]", "LUA-TX"), + T_DATA("LUA-U2-GT 10/100/1000 Ethernet Adapter", "LUA-U2-GT"), + T_DATA("LUA-U2-KTX Ethernet", "LUA-U2-KTX"), + T_DATA("LW153 802.11n Adapter [ralink rt3070]", "LW153"), + T_DATA("LW313 802.11n Adapter [ralink rt2770 + rt2720]", "LW313"), + T_DATA("M-202 802.11bg", "M-202"), + T_DATA("M5261 Ethernet Controller", "M5261"), + T_DATA("M5632 Host-to-Host Link", "M5632 Host-to-Host Link"), + T_DATA("Marvell 88W8388 802.11a/b/g WLAN", "Marvell 88W8388"), + T_DATA("MC8700 Modem", "MC8700"), + T_DATA("MCP04 Ethernet Controller", "MCP04"), + T_DATA("MCP2A Ethernet Controller", "MCP2A"), + T_DATA("MCP51 Ethernet Controller", "MCP51"), + T_DATA("MCP55 Ethernet", "MCP55"), + T_DATA("MCP61 Ethernet", "MCP61"), + T_DATA("MCP65 Ethernet", "MCP65"), + T_DATA("MCP67 Ethernet", "MCP67"), + T_DATA("MCP73 Ethernet", "MCP73"), + T_DATA("MCP77 Ethernet", "MCP77"), + T_DATA("MCP79 Ethernet", "MCP79"), + T_DATA("MCP89 Ethernet", "MCP89"), + T_DATA("MCS7730 10/100 Mbps Ethernet adapter", "MCS7730"), + T_DATA("MCS7830 10/100 Mbps Ethernet adapter", "MCS7830"), + T_DATA("MCS7832 10/100 Mbps Ethernet adapter", "MCS7832"), + T_DATA("Metronic 495257 wifi 802.11ng", "Metronic 495257"), + T_DATA("MF110/MF627/MF636", "MF110/MF627/MF636"), + T_DATA("MF632/ONDA ET502HS/MT505UP", "MF632/ONDA ET502HS/MT505UP"), + T_DATA("MF820 4G LTE", "MF820"), + T_DATA("Micolink USB2Ethernet [pegasus]", "Micolink USB2Ethernet"), + T_DATA("MicroLink dLAN", "MicroLink dLAN"), + T_DATA("MN-120 (ADMtek Centaur-C based)", "MN-120"), + T_DATA("MN-130 (ADMtek Centaur-P based)", "MN-130"), + T_DATA("MN-710 802.11g Wireless Adapter [Intersil ISL3886]", "MN-710"), + T_DATA("model 01 Ethernet interface", "model 01"), + T_DATA("model 01+ Ethernet", "model 01+"), + T_DATA("Motorola 802.11n 5G USB Wireless Adapter", "Motorola"), + T_DATA("Motorola 802.11n Dualband USB Wireless Adapter", "Motorola Dualband"), + T_DATA("MP-PRX1 Ethernet", "MP-PRX1"), + T_DATA("MS-3870 802.11bgn Wireless Module [Ralink RT3070]", "MS-3870"), + T_DATA("MS-3871 802.11bgn Wireless Module [Ralink RT8070]", "MS-3871"), + T_DATA("MSI-6861 802.11g WiFi adapter", "MSI-6861"), + T_DATA("MT25400 Family [ConnectX-2 Virtual Function]", "MT25400"), + T_DATA("MT25408 [ConnectX EN 10GigE 10GBaseT, PCIe 2.0 2.5GT/s]", "MT25408"), + T_DATA("MT25408 [ConnectX EN 10GigE 10GBaseT, PCIe Gen2 5GT/s]", "MT25408"), + T_DATA("MT25408 [ConnectX VPI - IB SDR / 10GigE]", "MT25408"), + T_DATA("MT25418 [ConnectX VPI PCIe 2.0 2.5GT/s - IB DDR / 10GigE]", "MT25418"), + T_DATA("MT25448 [ConnectX EN 10GigE, PCIe 2.0 2.5GT/s]", "MT25448"), + T_DATA("MT26418 [ConnectX VPI PCIe 2.0 5GT/s - IB DDR / 10GigE]", "MT26418"), + T_DATA("MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE]", "MT26428"), + T_DATA("MT26438 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE Virtualization+]", + "MT26438"), + T_DATA("MT26448 [ConnectX EN 10GigE, PCIe 2.0 5GT/s]", "MT26448"), + T_DATA("MT26468 [ConnectX EN 10GigE, PCIe 2.0 5GT/s Virtualization+]", "MT26468"), + T_DATA("MT26478 [ConnectX EN 40GigE, PCIe 2.0 5GT/s]", "MT26478"), + T_DATA("MT27500 Family [ConnectX-3]", "MT27500"), + T_DATA("MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]", + "MT27500/MT27520"), + T_DATA("MT27510 Family", "MT27510"), + T_DATA("MT27511 Family", "MT27511"), + T_DATA("MT27520 Family [ConnectX-3 Pro]", "MT27520"), + T_DATA("MT27530 Family", "MT27530"), + T_DATA("MT27531 Family", "MT27531"), + T_DATA("MT27540 Family", "MT27540"), + T_DATA("MT27541 Family", "MT27541"), + T_DATA("MT27550 Family", "MT27550"), + T_DATA("MT27551 Family", "MT27551"), + T_DATA("MT27560 Family", "MT27560"), + T_DATA("MT27561 Family", "MT27561"), + T_DATA("MT27600 [Connect-IB]", "MT27600"), + T_DATA("MT27600 Family [Connect-IB Virtual Function]", "MT27600"), + T_DATA("MT27700 Family [ConnectX-4]", "MT27700"), + T_DATA("MT27700 Family [ConnectX-4 Virtual Function]", "MT27700"), + T_DATA("MT27710 Family [ConnectX-4 Lx]", "MT27710"), + T_DATA("MT27710 Family [ConnectX-4 Lx Virtual Function]", "MT27710"), + T_DATA("MT27800 Family [ConnectX-5]", "MT27800"), + T_DATA("MT27800 Family [ConnectX-5 Virtual Function]", "MT27800"), + T_DATA("MT28800 Family [ConnectX-5 Ex]", "MT28800"), + T_DATA("MT28800 Family [ConnectX-5 Ex Virtual Function]", "MT28800"), + T_DATA("MT28908 Family [ConnectX-6]", "MT28908"), + T_DATA("MT28908 Family [ConnectX-6 Virtual Function]", "MT28908"), + T_DATA("MT416842 BlueField integrated ConnectX-5 network controller", + "MT416842 BlueField ConnectX-5"), + T_DATA("MT416842 BlueField multicore SoC family VF", "MT416842 BlueField VF"), + T_DATA("MT51136", "MT51136"), + T_DATA("MT52100", "MT52100"), + T_DATA("MT53236", "MT53236"), + T_DATA("MT7601U Wireless Adapter", "MT7601U"), + T_DATA("MTD-8xx 100/10M Ethernet PCI Adapter", "MTD-8xx"), + T_DATA("Multithreaded 10-Gigabit Ethernet Network Controller", NULL), + T_DATA("MX98713", "MX98713"), + T_DATA("MX987x5", "MX987x5"), + T_DATA("Myri-10G Dual-Protocol NIC", "Myri-10G"), + T_DATA("N10 Nano 802.11n Network Adapter [Realtek RTL8192CU]", "N10 Nano"), + T_DATA("N220 802.11bgn Wireless Adapter", "N220"), + T_DATA("N320-G2-CR 10GbE Dual Port Adapter", "N320-G2-CR"), + T_DATA("N5HBZ0000055 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]", "N5HBZ0000055"), + T_DATA("Name: Voyager 1055 Laptop 802.11g Adapter [Broadcom 4320]", "Voyager 1055"), + T_DATA("NC100 Network Everywhere Fast Ethernet 10/100", "NC100"), + T_DATA("NE-34", "NE-34"), + T_DATA("NET1080 USB-USB Bridge", "NET1080 USB-USB Bridge"), + T_DATA("Netelligent 10/100 TX Embedded UTP", "Netelligent TX"), + T_DATA("Netelligent 10/100 TX PCI UTP", "Netelligent TX"), + T_DATA("Netelligent 10/100 TX UTP", "Netelligent TX"), + T_DATA("Netelligent 10 T/2 PCI UTP/Coax", "Netelligent 10 T/2"), + T_DATA("Netelligent 10 T PCI UTP", "Netelligent 10 T"), + T_DATA("Netelligent Dual 10/100 TX PCI UTP", "Netelligent Dual TX"), + T_DATA("Netelligent Integrated 10/100 TX UTP", "Netelligent TX"), + T_DATA("NetFlex-3/P ThunderLAN 1.0", "NetFlex-3/P ThunderLAN 1.0"), + T_DATA("NetFlex-3/P ThunderLAN 2.3", "NetFlex-3/P ThunderLAN 2.3"), + T_DATA("NetLink BCM57780 Gigabit Ethernet PCIe", "NetLink BCM57780"), + T_DATA("NetLink BCM57781 Gigabit Ethernet PCIe", "NetLink BCM57781"), + T_DATA("NetLink BCM57785 Gigabit Ethernet PCIe", "NetLink BCM57785"), + T_DATA("NetLink BCM57788 Gigabit Ethernet PCIe", "NetLink BCM57788"), + T_DATA("NetLink BCM57790 Gigabit Ethernet PCIe", "NetLink BCM57790"), + T_DATA("NetLink BCM57791 Gigabit Ethernet PCIe", "NetLink BCM57791"), + T_DATA("NetLink BCM57795 Gigabit Ethernet PCIe", "NetLink BCM57795"), + T_DATA("NetLink BCM5781 Gigabit Ethernet PCI Express", "NetLink BCM5781"), + T_DATA("NetLink BCM5784M Gigabit Ethernet PCIe", "NetLink BCM5784M"), + T_DATA("NetLink BCM5785 Fast Ethernet", "NetLink BCM5785"), + T_DATA("NetLink BCM5785 Gigabit Ethernet", "NetLink BCM5785"), + T_DATA("NetLink BCM5786 Gigabit Ethernet PCI Express", "NetLink BCM5786"), + T_DATA("NetLink BCM5787F Fast Ethernet PCI Express", "NetLink BCM5787F"), + T_DATA("NetLink BCM5787 Gigabit Ethernet PCI Express", "NetLink BCM5787"), + T_DATA("NetLink BCM5787M Gigabit Ethernet PCI Express", "NetLink BCM5787M"), + T_DATA("NetLink BCM5789 Gigabit Ethernet PCI Express", "NetLink BCM5789"), + T_DATA("NetLink BCM5906 Fast Ethernet PCI Express", "NetLink BCM5906"), + T_DATA("NetLink BCM5906M Fast Ethernet PCI Express", "NetLink BCM5906M"), + T_DATA("NetMate2 Ethernet", "NetMate2"), + T_DATA("NetMate Ethernet", "NetMate"), + T_DATA("NetXen Dual Port 10GbE Multifunction Adapter for c-Class", + "NetXen Multifunction for c-Class"), + T_DATA("NetXtreme 5714S Gigabit Ethernet", "NetXtreme 5714S"), + T_DATA("NetXtreme BCM5700 Gigabit Ethernet", "NetXtreme BCM5700"), + T_DATA("NetXtreme BCM5701 Gigabit Ethernet", "NetXtreme BCM5701"), + T_DATA("NetXtreme BCM5702A3 Gigabit Ethernet", "NetXtreme BCM5702A3"), + T_DATA("NetXtreme BCM5702FE Gigabit Ethernet", "NetXtreme BCM5702FE"), + T_DATA("NetXtreme BCM5702 Gigabit Ethernet", "NetXtreme BCM5702"), + T_DATA("NetXtreme BCM5702X Gigabit Ethernet", "NetXtreme BCM5702X"), + T_DATA("NetXtreme BCM5703 Gigabit Ethernet", "NetXtreme BCM5703"), + T_DATA("NetXtreme BCM5703X Gigabit Ethernet", "NetXtreme BCM5703X"), + T_DATA("NetXtreme BCM5704 Gigabit Ethernet", "NetXtreme BCM5704"), + T_DATA("NetXtreme BCM5704S_2 Gigabit Ethernet", "NetXtreme BCM5704S 2"), + T_DATA("NetXtreme BCM5704S Gigabit Ethernet", "NetXtreme BCM5704S"), + T_DATA("NetXtreme BCM5705_2 Gigabit Ethernet", "NetXtreme BCM5705 2"), + T_DATA("NetXtreme BCM5705 Gigabit Ethernet", "NetXtreme BCM5705"), + T_DATA("NetXtreme BCM5705M_2 Gigabit Ethernet", "NetXtreme BCM5705M 2"), + T_DATA("NetXtreme BCM5705M Gigabit Ethernet", "NetXtreme BCM5705M"), + T_DATA("NetXtreme BCM5714 Gigabit Ethernet", "NetXtreme BCM5714"), + T_DATA("NetXtreme BCM5715 Gigabit Ethernet", "NetXtreme BCM5715"), + T_DATA("NetXtreme BCM5715S Gigabit Ethernet", "NetXtreme BCM5715S"), + T_DATA("NetXtreme BCM5717 Gigabit Ethernet PCIe", "NetXtreme BCM5717"), + T_DATA("NetXtreme BCM5718 Gigabit Ethernet PCIe", "NetXtreme BCM5718"), + T_DATA("NetXtreme BCM5719 Gigabit Ethernet PCIe", "NetXtreme BCM5719"), + T_DATA("NetXtreme BCM5720 Gigabit Ethernet PCIe", "NetXtreme BCM5720"), + T_DATA("NetXtreme BCM5721 Gigabit Ethernet PCI Express", "NetXtreme BCM5721"), + T_DATA("NetXtreme BCM5722 Gigabit Ethernet PCI Express", "NetXtreme BCM5722"), + T_DATA("NetXtreme BCM5723 Gigabit Ethernet PCIe", "NetXtreme BCM5723"), + T_DATA("NetXtreme BCM5725 Gigabit Ethernet PCIe", "NetXtreme BCM5725"), + T_DATA("NetXtreme BCM5727 Gigabit Ethernet PCIe", "NetXtreme BCM5727"), + T_DATA("NetXtreme BCM5751F Fast Ethernet PCI Express", "NetXtreme BCM5751F"), + T_DATA("NetXtreme BCM5751 Gigabit Ethernet PCI Express", "NetXtreme BCM5751"), + T_DATA("NetXtreme BCM5751M Gigabit Ethernet PCI Express", "NetXtreme BCM5751M"), + T_DATA("NetXtreme BCM5752 Gigabit Ethernet PCI Express", "NetXtreme BCM5752"), + T_DATA("NetXtreme BCM5752M Gigabit Ethernet PCI Express", "NetXtreme BCM5752M"), + T_DATA("NetXtreme BCM5753F Fast Ethernet PCI Express", "NetXtreme BCM5753F"), + T_DATA("NetXtreme BCM5753 Gigabit Ethernet PCI Express", "NetXtreme BCM5753"), + T_DATA("NetXtreme BCM5753M Gigabit Ethernet PCI Express", "NetXtreme BCM5753M"), + T_DATA("NetXtreme BCM5754 Gigabit Ethernet PCI Express", "NetXtreme BCM5754"), + T_DATA("NetXtreme BCM5754M Gigabit Ethernet PCI Express", "NetXtreme BCM5754M"), + T_DATA("NetXtreme BCM5755 Gigabit Ethernet PCI Express", "NetXtreme BCM5755"), + T_DATA("NetXtreme BCM5755M Gigabit Ethernet PCI Express", "NetXtreme BCM5755M"), + T_DATA("NetXtreme BCM5756ME Gigabit Ethernet PCI Express", "NetXtreme BCM5756ME"), + T_DATA("NetXtreme BCM5761 10/100/1000BASE-T Ethernet", "NetXtreme BCM5761"), + T_DATA("NetXtreme BCM5761e Gigabit Ethernet PCIe", "NetXtreme BCM5761e"), + T_DATA("NetXtreme BCM5761 Gigabit Ethernet PCIe", "NetXtreme BCM5761"), + T_DATA("NetXtreme BCM5762 Gigabit Ethernet PCIe", "NetXtreme BCM5762"), + T_DATA("NetXtreme BCM5764M Gigabit Ethernet PCIe", "NetXtreme BCM5764M"), + T_DATA("NetXtreme BCM57760 Gigabit Ethernet PCIe", "NetXtreme BCM57760"), + T_DATA("NetXtreme BCM57761 Gigabit Ethernet PCIe", "NetXtreme BCM57761"), + T_DATA("NetXtreme BCM57762 Gigabit Ethernet PCIe", "NetXtreme BCM57762"), + T_DATA("NetXtreme BCM57764 Gigabit Ethernet PCIe", "NetXtreme BCM57764"), + T_DATA("NetXtreme BCM57765 Gigabit Ethernet PCIe", "NetXtreme BCM57765"), + T_DATA("NetXtreme BCM57766 Gigabit Ethernet PCIe", "NetXtreme BCM57766"), + T_DATA("NetXtreme BCM57767 Gigabit Ethernet PCIe", "NetXtreme BCM57767"), + T_DATA("NetXtreme BCM57782 Gigabit Ethernet PCIe", "NetXtreme BCM57782"), + T_DATA("NetXtreme BCM57786 Gigabit Ethernet PCIe", "NetXtreme BCM57786"), + T_DATA("NetXtreme BCM57787 Gigabit Ethernet PCIe", "NetXtreme BCM57787"), + T_DATA("NetXtreme BCM5780 Gigabit Ethernet", "NetXtreme BCM5780"), + T_DATA("NetXtreme BCM5780S Gigabit Ethernet", "NetXtreme BCM5780S"), + T_DATA("NetXtreme BCM5782 Gigabit Ethernet", "NetXtreme BCM5782"), + T_DATA("NetXtreme BCM5788 Gigabit Ethernet", "NetXtreme BCM5788"), + T_DATA("NetXtreme BCM5901 100Base-TX", "NetXtreme BCM5901"), + T_DATA("NetXtreme-C Ethernet Virtual Function", "NetXtreme-C Virtual Function"), + T_DATA("NetXtreme-C RDMA Virtual Function", "NetXtreme-C Virtual Function"), + T_DATA("NetXtreme-E Ethernet Virtual Function", "NetXtreme-E Virtual Function"), + T_DATA("NetXtreme-E RDMA Virtual Function", "NetXtreme-E Virtual Function"), + T_DATA( + "NetXtreme II BCM5706 Gigabit Ethernet (NC370i Multifunction Gigabit Server Adapter)", + "NetXtreme II BCM5706"), + T_DATA( + "NetXtreme II BCM5706 Gigabit Ethernet (NC370T MultifuNCtion Gigabit Server Adapter)", + "NetXtreme II BCM5706"), + T_DATA("NetXtreme II BCM5706 Gigabit Ethernet", "NetXtreme II BCM5706"), + T_DATA( + "NetXtreme II BCM5706S Gigabit Ethernet (NC370F MultifuNCtion Gigabit Server Adapter)", + "NetXtreme II BCM5706S"), + T_DATA("NetXtreme II BCM5706S Gigabit Ethernet", "NetXtreme II BCM5706S"), + T_DATA("NetXtreme II BCM5708 Gigabit Ethernet", "NetXtreme II BCM5708"), + T_DATA("NetXtreme II BCM5708S Gigabit Ethernet", "NetXtreme II BCM5708S"), + T_DATA("NetXtreme II BCM5709 Gigabit Ethernet", "NetXtreme II BCM5709"), + T_DATA("NetXtreme II BCM5709S Gigabit Ethernet", "NetXtreme II BCM5709S"), + T_DATA("NetXtreme II BCM5716 Gigabit Ethernet", "NetXtreme II BCM5716"), + T_DATA("NetXtreme II BCM5716S Gigabit Ethernet", "NetXtreme II BCM5716S"), + T_DATA("NetXtreme II BCM57710 10-Gigabit PCIe [Everest]", "NetXtreme II BCM57710"), + T_DATA("NetXtreme II BCM57711 10-Gigabit PCIe", "NetXtreme II BCM57711"), + T_DATA("NetXtreme II BCM57711E 10-Gigabit PCIe", "NetXtreme II BCM57711E"), + T_DATA("NetXtreme II BCM57712 10 Gigabit Ethernet Multi Function", "NetXtreme II BCM57712"), + T_DATA("NetXtreme II BCM57712 10 Gigabit Ethernet", "NetXtreme II BCM57712"), + T_DATA("NetXtreme II BCM57712 10 Gigabit Ethernet Virtual Function", + "NetXtreme II BCM57712 Virtual Function"), + T_DATA("NetXtreme II BCM57800 1/10 Gigabit Ethernet Multi Function", + "NetXtreme II BCM57800"), + T_DATA("NetXtreme II BCM57800 1/10 Gigabit Ethernet", "NetXtreme II BCM57800"), + T_DATA("NetXtreme II BCM57800 1/10 Gigabit Ethernet Virtual Function", + "NetXtreme II BCM57800 Virtual Function"), + T_DATA("NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function", "NetXtreme II BCM57810"), + T_DATA("NetXtreme II BCM57810 10 Gigabit Ethernet", "NetXtreme II BCM57810"), + T_DATA("NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function", + "NetXtreme II BCM57810 Virtual Function"), + T_DATA("NetXtreme II BCM57811 10 Gigabit Ethernet Multi Function", "NetXtreme II BCM57811"), + T_DATA("NetXtreme II BCM57811 10-Gigabit Ethernet", "NetXtreme II BCM57811"), + T_DATA("NetXtreme II BCM57811 10-Gigabit Ethernet Virtual Function", + "NetXtreme II BCM57811 Virtual Function"), + T_DATA("NetXtreme II BCM57840 10/20 Gigabit Ethernet Multi Function", + "NetXtreme II BCM57840 10/20"), + T_DATA("NetXtreme II BCM57840 10/20 Gigabit Ethernet", "NetXtreme II BCM57840 10/20"), + T_DATA("NetXtreme II BCM57840 10/20 Gigabit Ethernet Virtual Function", + "NetXtreme II BCM57840 10/20 Virtual Function"), + T_DATA("nForce2 Ethernet Controller", "nForce2"), + T_DATA("nForce3 Ethernet", "nForce3"), + T_DATA("nForce Ethernet Controller", "nForce"), + T_DATA("Nintendo Wi-Fi", "Nintendo"), + T_DATA("NM10/ICH7 Family LAN Controller", "NM10/ICH7"), + T_DATA("NovaTech NV-902W", "NovaTech NV-902W"), + T_DATA("NUB100 Ethernet [pegasus]", "NUB100"), + T_DATA("NUB-350 802.11g Wireless Adapter [Intersil ISL3887]", "NUB-350"), + T_DATA("NUB-8301 802.11bg", "NUB-8301"), + T_DATA("NV5000SC", "NV5000SC"), + T_DATA("NW-3100 802.11b/g 54Mbps Wireless Network Adapter [zd1211]", "NW-3100"), + T_DATA("NWD2105 802.11bgn Wireless Adapter [Ralink RT3070]", "NWD2105"), + T_DATA("NWD-210N 802.11b/g/n-draft wireless adapter", "NWD-210N"), + T_DATA("NWD211AN 802.11abgn Wireless Adapter [Ralink RT2870]", "NWD211AN"), + T_DATA("NWD2205 802.11n Wireless N Adapter [Realtek RTL8192CU]", "NWD2205"), + T_DATA("NWD-270N Wireless N-lite USB Adapter", "NWD-270N N-lite"), + T_DATA("NWD271N 802.11n Wireless Adapter [Atheros AR9001U-(2)NG]", "NWD271N"), + T_DATA("NX3031 Multifunction 1/10-Gigabit Server Adapter", "NX3031 Multifunction"), + T_DATA("NXB-10GCX4 10-Gigabit Ethernet PCIe Adapter with CX4 copper interface", + "NXB-10GCX4"), + T_DATA("NXB-10GXSR 10-Gigabit Ethernet PCIe Adapter with SR-XFP optical interface", + "NXB-10GXSR"), + T_DATA("NXB-4GCU Quad Gigabit Ethernet PCIe Adapter with 1000-BASE-T interface", + "NXB-4GCU Quad"), + T_DATA("OC-2183/2185", "OC-2183/2185"), + T_DATA("OC-2325", "OC-2325"), + T_DATA("OC-2326", "OC-2326"), + T_DATA("OCT To Fast Ethernet Converter", "OCT To Converter"), + T_DATA("Olicard 100", "Olicard 100"), + T_DATA("OneConnect 10Gb NIC (be3)", "OneConnect"), + T_DATA("OneConnect NIC (Lancer)", "OneConnect"), + T_DATA("OneConnect NIC (Skyhawk)", "OneConnect"), + T_DATA("OneConnect NIC (Skyhawk-VF)", "OneConnect"), + T_DATA("OneConnect OCe10100/OCe10102 Series 10 GbE", "OneConnect OCe10100/OCe10102"), + T_DATA("On Networks N300MA 802.11bgn [Realtek RTL8192CU]", "On Networks N300MA"), + T_DATA("Ovation MC551", "Ovation MC551"), + T_DATA("PCAN-PCI CAN-Bus controller", "PCAN-PCI"), + T_DATA("PCAN Pro", "PCAN Pro"), + T_DATA("PCAN-USB", "PCAN-USB"), + T_DATA("PCI NE2K Ethernet", "NE2K"), + T_DATA("PCI Rocker Ethernet switch device", "Rocker switch"), + T_DATA("PL2301 USB-USB Bridge", "PL2301 USB-USB Bridge"), + T_DATA("PL2302 USB-USB Bridge", "PL2302 USB-USB Bridge"), + T_DATA("PL25A1 Host-Host Bridge", "PL25A1 Host-Host Bridge"), + T_DATA("Platform Controller Hub EG20T Controller Area Network (CAN) Controller", "EG20T"), + T_DATA("PN672TX 10/100 Ethernet", "PN672TX"), + T_DATA("Pocket Ethernet [klsi]", "Pocket"), + T_DATA("Prism GT 802.11b/g Adapter", "Prism GT"), + T_DATA("PRO/100 VE Network Connection", "PRO/100 VE"), + T_DATA("PRO/100 VM Network Connection", "PRO/100 VM"), + T_DATA("PRO/Wireless 2200BG [Calexico2] Network Connection", "PRO/Wireless 2200BG"), + T_DATA("PRO/Wireless 2915ABG [Calexico2] Network Connection", "PRO/Wireless 2915ABG"), + T_DATA("PRO/Wireless 3945ABG [Golan] Network Connection", "PRO/Wireless 3945ABG"), + T_DATA("PRO/Wireless 4965 AG or AGN [Kedron] Network Connection", + "PRO/Wireless 4965 AG or AGN"), + T_DATA("PRO/Wireless 5100 AGN [Shiloh] Network Connection", "PRO/Wireless 5100 AGN"), + T_DATA("PRO/Wireless 5350 AGN [Echo Peak] Network Connection", "PRO/Wireless 5350 AGN"), + T_DATA("PRO/Wireless LAN 2100 3B Mini PCI Adapter (Dell Latitude D800)", + "PRO/Wireless 2100 3B Mini"), + T_DATA("PRO/Wireless LAN 2100 3B Mini PCI Adapter (MIM2000/Centrino)", + "PRO/Wireless 2100 3B Mini"), + T_DATA("PRO/Wireless LAN 2100 3B Mini PCI Adapter", "PRO/Wireless 2100 3B Mini"), + T_DATA("PRO/Wireless LAN 2100 3B Mini PCI Adapter (Samsung X10/P30 integrated WLAN)", + "PRO/Wireless 2100 3B Mini"), + T_DATA("PRO/Wireless LAN 2100 3B Mini PCI Adapter (Toshiba Satellite M10)", + "PRO/Wireless 2100 3B Mini"), + T_DATA("Psion Gold Port Ethernet", "Psion Gold Port"), + T_DATA("PTA01 Wireless Adapter", "PTA01"), + T_DATA("QCA6164 802.11ac Wireless Network Adapter", "QCA6164"), + T_DATA("QCA6174 802.11ac Wireless Network Adapter", "QCA6174"), + T_DATA("QCA8171 Gigabit Ethernet", "QCA8171"), + T_DATA("QCA8172 Fast Ethernet", "QCA8172"), + T_DATA("QCA9377 802.11ac Wireless Network Adapter", "QCA9377"), + T_DATA("QCA9565 / AR9565 Wireless Network Adapter", "QCA9565 / AR9565"), + T_DATA("QCA986x/988x 802.11ac Wireless Network Adapter", "QCA986x/988x"), + T_DATA("QCA9887 802.11ac Wireless Network Adapter", "QCA9887"), + T_DATA("QCA9980/9990 802.11ac Wireless Network Adapter", "QCA9980/9990"), + T_DATA("Qualcomm HSUSB Device", "Qualcomm HSUSB"), + T_DATA("Quectel UC20", "Quectel UC20"), + T_DATA("QuickWLAN 802.11bg", "QuickWLAN"), + T_DATA("R6040 MAC Controller", "R6040"), + T_DATA("Ralink RT2770/2720 802.11b/g/n Wireless LAN Mini-USB Device", "Ralink RT2770/2720"), + T_DATA("Ralink RT3070 802.11b/g/n Wireless Lan USB Device", "Ralink RT3070"), + T_DATA("ReadyLink 2000", "ReadyLink 2000"), + T_DATA("Realtek RTL8187 Wireless 802.11g 54Mbps Network Adapter", "Realtek RTL8187"), + T_DATA("RIO 10/100 Ethernet [eri]", "RIO"), + T_DATA("RL100-ATX 10/100", "RL100-ATX"), + T_DATA("RL100TX Fast Ethernet", "RL100TX"), + T_DATA("ROL/F-100 Fast Ethernet Adapter with ROL", "ROL/F-100 with ROL"), + T_DATA("RT2070 Wireless Adapter", "RT2070"), + T_DATA("RT2500USB Wireless Adapter", "RT2500USB"), + T_DATA("RT2500 Wireless 802.11bg", "RT2500"), + T_DATA("RT2501/RT2573 Wireless Adapter", "RT2501/RT2573"), + T_DATA("RT2501USB Wireless Adapter", "RT2501USB"), + T_DATA("RT2561/RT61 802.11g PCI", "RT2561/RT61"), + T_DATA("RT2561/RT61 rev B 802.11g", "RT2561/RT61"), + T_DATA("RT2570", "RT2570"), + T_DATA("RT2570 Wireless Adapter", "RT2570"), + T_DATA("RT2573", "RT2573"), + T_DATA("RT2600 802.11 MIMO", "RT2600 MIMO"), + T_DATA("RT2601/RT2671 Wireless Adapter", "RT2601/RT2671"), + T_DATA("RT2760 Wireless 802.11n 1T/2R", "RT2760 1T/2R"), + T_DATA("RT2770 Wireless Adapter", "RT2770"), + T_DATA("RT2790 Wireless 802.11n 1T/2R PCIe", "RT2790 1T/2R"), + T_DATA("RT2800 802.11n PCI", "RT2800"), + T_DATA("RT2870/RT3070 Wireless Adapter", "RT2870/RT3070"), + T_DATA("RT2870 Wireless Adapter", "RT2870"), + T_DATA("RT2890 Wireless 802.11n PCIe", "RT2890"), + T_DATA("RT3060 Wireless 802.11n 1T/1R", "RT3060 1T/1R"), + T_DATA("RT3062 Wireless 802.11n 2T/2R", "RT3062 2T/2R"), + T_DATA("RT3071 Wireless Adapter", "RT3071"), + T_DATA("RT3072 Wireless Adapter", "RT3072"), + T_DATA("RT3090 Wireless 802.11n 1T/1R PCIe", "RT3090 1T/1R"), + T_DATA("RT3091 Wireless 802.11n 1T/2R PCIe", "RT3091 1T/2R"), + T_DATA("RT3092 Wireless 802.11n 2T/2R PCIe", "RT3092 2T/2R"), + T_DATA("RT3290 Wireless 802.11n 1T/1R PCIe", "RT3290 1T/1R"), + T_DATA("RT3370 Wireless Adapter", "RT3370"), + T_DATA("RT3572 Wireless Adapter", "RT3572"), + T_DATA("RT3573 Wireless Adapter", "RT3573"), + T_DATA("RT3592 PCIe Wireless Network Adapter", "RT3592"), + T_DATA("RT3592 Wireless 802.11abgn 2T/2R PCIe", "RT3592 2T/2R"), + T_DATA("RT5360 Wireless 802.11n 1T/1R", "RT5360 1T/1R"), + T_DATA("RT5362 PCI 802.11n Wireless Network Adapter", "RT5362"), + T_DATA("RT5370 Wireless Adapter", "RT5370"), + T_DATA("RT5372 Wireless Adapter", "RT5372"), + T_DATA("RT5390 [802.11 b/g/n 1T1R G-band PCI Express Single Chip]", "RT5390"), + T_DATA("RT5390R 802.11bgn PCIe Wireless Network Adapter", "RT5390R"), + T_DATA("RT5390 Wireless 802.11n 1T/1R PCIe", "RT5390 1T/1R"), + T_DATA("RT5392 PCIe Wireless Network Adapter", "RT5392"), + T_DATA("RT5572 Wireless Adapter", "RT5572"), + T_DATA("RT8139 (B/C) Cardbus Fast Ethernet Adapter", "RT8139"), + T_DATA("RTL-8029(AS)", "RTL-8029"), + T_DATA("RTL-8100/8101L/8139 PCI Fast Ethernet Adapter", "RTL-8100/8101L/8139"), + T_DATA("RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller", "RTL8101/2/6E"), + T_DATA("RTL-8110SC/8169SC Gigabit Ethernet", "RTL-8110SC/8169SC"), + T_DATA("RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller", "RTL8111/8168/8411"), + T_DATA("RTL-8129", "RTL-8129"), + T_DATA("RTL8139D [Realtek] PCI 10/100BaseTX ethernet adaptor", "RTL8139D"), + T_DATA("RTL8139 Ethernet", "RTL8139"), + T_DATA("RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter", "RTL8139"), + T_DATA("RTL8150 Fast Ethernet Adapter", "RTL8150"), + T_DATA("RTL8151", "RTL8151"), + T_DATA("RTL8152 Fast Ethernet Adapter", "RTL8152"), + T_DATA("RTL8153 Gigabit Ethernet Adapter", "RTL8153"), + T_DATA("RTL8169 PCI Gigabit Ethernet Controller", "RTL8169"), + T_DATA("RTL8180L 802.11b MAC", "RTL8180L"), + T_DATA("RTL-8185 IEEE 802.11a/b/g Wireless LAN Controller", "RTL-8185"), + T_DATA("RTL8187B Wireless 802.11g 54Mbps Network Adapter", "RTL8187B"), + T_DATA("RTL8187B Wireless Adapter", "RTL8187B"), + T_DATA("RTL8187SE Wireless LAN Controller", "RTL8187SE"), + T_DATA("RTL8187 Wireless Adapter", "RTL8187"), + T_DATA("RTL8188CE 802.11b/g/n WiFi Adapter", "RTL8188CE"), + T_DATA("RTL8188CUS 802.11n WLAN Adapter", "RTL8188CUS"), + T_DATA("RTL8188EE Wireless Network Adapter", "RTL8188EE"), + T_DATA("RTL8188RU 802.11n WLAN Adapter", "RTL8188RU"), + T_DATA("RTL8191CE PCIe Wireless Network Adapter", "RTL8191CE"), + T_DATA("RTL8191SEvA Wireless LAN Controller", "RTL8191SEvA"), + T_DATA("RTL8191SEvB Wireless LAN Controller", "RTL8191SEvB"), + T_DATA("RTL8192CE PCIe Wireless Network Adapter", "RTL8192CE"), + T_DATA("RTL8192CU 802.11n WLAN Adapter", "RTL8192CU"), + T_DATA("RTL8192DE Wireless LAN Controller", "RTL8192DE"), + T_DATA("RTL8192EE PCIe Wireless Network Adapter", "RTL8192EE"), + T_DATA("RTL8192E/RTL8192SE Wireless LAN Controller", "RTL8192E/RTL8192SE"), + T_DATA("RTL8192EU 802.11b/g/n WLAN Adapter", "RTL8192EU"), + T_DATA("RTL8192SE Wireless LAN Controller", "RTL8192SE"), + T_DATA("RTL81xx Fast Ethernet", "RTL81xx"), + T_DATA("RTL81xx RealTek Ethernet", "RTL81xx RealTek"), + T_DATA("RTL8723AE PCIe Wireless Network Adapter", "RTL8723AE"), + T_DATA("RTL8723AU 802.11n WLAN Adapter", "RTL8723AU"), + T_DATA("RTL8723BE PCIe Wireless Network Adapter", "RTL8723BE"), + T_DATA("RTL8812AE 802.11ac PCIe Wireless Network Adapter", "RTL8812AE"), + T_DATA("RTL8821AE 802.11ac PCIe Wireless Network Adapter", "RTL8821AE"), + T_DATA("S310-CR 10GbE Single Port Adapter", "S310-CR Single Port"), + T_DATA("S320-LP-CR 10GbE Dual Port Adapter", "S320-LP-CR"), + T_DATA("Samsung Gobi 2000 Wireless Modem", "Samsung Gobi 2000"), + T_DATA("SC92031 PCI Fast Ethernet Adapter", "SC92031"), + T_DATA("SD8688 WLAN", "SD8688"), + T_DATA("SD8786 WLAN", "SD8786"), + T_DATA("SD8787 WLAN", "SD8787"), + T_DATA("SD8797 WLAN", "SD8797"), + T_DATA("SD8897 WLAN", "SD8897"), + T_DATA("SFC4000 rev A net [Solarstorm]", "SFC4000"), + T_DATA("SFC4000 rev B [Solarstorm]", "SFC4000"), + T_DATA("SFC9020 10G Ethernet Controller", "SFC9020"), + T_DATA("SFC9120 10G Ethernet Controller", "SFC9120"), + T_DATA("SFC9120 10G Ethernet Controller (Virtual Function)", "SFC9120"), + T_DATA("SFC9140 10/40G Ethernet Controller", "SFC9140"), + T_DATA("SFC9140 10/40G Ethernet Controller (Virtual Function)", "SFC9140"), + T_DATA("SFC9220 10/40G Ethernet Controller", "SFC9220"), + T_DATA("SFC9220 10/40G Ethernet Controller (Virtual Function)", "SFC9220"), + T_DATA("SFL9021 10GBASE-T Ethernet Controller", "SFL9021"), + T_DATA("Shasta (Sun GEM)", "Shasta"), + T_DATA("Siemens S30853-S1016-R107 802.11g Wireless Adapter [Intersil ISL3886]", + "Siemens S30853-S1016-R107"), + T_DATA("Siemens S30853-S1031-R351 802.11g Wireless Adapter [Atheros AR5523]", + "Siemens S30853-S1031-R351"), + T_DATA("Siemens S30853-S1038-R351 802.11g Wireless Adapter [Atheros AR5523]", + "Siemens S30853-S1038-R351"), + T_DATA("Siemens S30863-S1016-R107-2 802.11g Wireless Adapter [Intersil ISL3887]", + "Siemens S30863-S1016-R107-2"), + T_DATA("Siemens SpeedStream 100MBps Ethernet", "Siemens SpeedStream"), + T_DATA("Sierra Wireless Gobi 3000 Modem device (MC8355)", "Sierra Gobi 3000"), + T_DATA("SIMCom SIM5218 modem", "SIMCom SIM5218"), + T_DATA("SiS7016 PCI Fast Ethernet Adapter", "SiS7016"), + T_DATA("SiS900 PCI Fast Ethernet", "SiS900"), + T_DATA("SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC", + "SK-9871 ZX/SC"), + T_DATA("SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)", "SK-9872"), + T_DATA("SK-9Dxx Gigabit Ethernet Adapter", "SK-9Dxx"), + T_DATA("SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45", "SK-9E21D"), + T_DATA("SK-9E21M 10/100/1000Base-T Adapter", "SK-9E21M"), + T_DATA("SK-9Mxx Gigabit Ethernet Adapter", "SK-9Mxx"), + T_DATA("SK-9S21 10/100/1000Base-T Server Adapter, PCI-X, Copper RJ-45", "SK-9S21"), + T_DATA("smartNIC 2 PnP Ethernet", "smartNIC 2"), + T_DATA("smartNIC Ethernet [catc]", "smartNIC"), + T_DATA("SMC2-1211TX", "SMC2-1211TX"), + T_DATA("SMC2862W-G v1 EZ Connect 802.11g Adapter [Intersil ISL3886]", + "SMC2862W-G EZ Connect"), + T_DATA("SMC2862W-G v2 EZ Connect 802.11g Adapter [Intersil ISL3887]", + "SMC2862W-G EZ Connect"), + T_DATA("SMC2862W-G v3 EZ Connect 802.11g Adapter [Intersil ISL3887]", + "SMC2862W-G EZ Connect"), + T_DATA("SMC SMCWUSB-N 802.11bgn 2x2:2 Wireless Adapter [Ralink RT2870]", + "SMC SMCWUSB-N 2x2:2"), + T_DATA("SMCWUSB-G 802.11bg", "SMCWUSB-G"), + T_DATA("SMCWUSBS-N2 EZ Connect N Wireless Adapter [Ralink RT2870]", + "SMCWUSBS-N2 EZ Connect"), + T_DATA("SMCWUSBS-N3 EZ Connect N Wireless Adapter [Ralink RT3070]", + "SMCWUSBS-N3 EZ Connect"), + T_DATA("SMCWUSBS-N EZ Connect N Draft 11n Wireless Adapter [Ralink RT2870]", + "SMCWUSBS-N EZ Connect"), + T_DATA("SMCWUSBT-G (no firmware)", "SMCWUSBT-G"), + T_DATA("SMCWUSBT-G", "SMCWUSBT-G"), + T_DATA("SMSC9512/9514 Fast Ethernet Adapter", "SMSC9512/9514"), + T_DATA("SNU5600 802.11bg", "SNU5600"), + T_DATA("SoftGate 802.11 Adapter", "SoftGate"), + T_DATA("Sony 10Mbps Ethernet [pegasus]", "Sony"), + T_DATA("Sony Gobi 2000 Wireless Modem", "Sony Gobi 2000"), + T_DATA("Sony UWA-BR100 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]", + "Sony UWA-BR100"), + T_DATA("SparkLAN WL-682 802.11bg Wireless Adapter [Intersil ISL3887]", "SparkLAN WL-682"), + T_DATA("Speedport W 102 Stick IEEE 802.11n USB 2.0 Adapter", "Speedport W 102 Stick"), + T_DATA("SpeedStream 10/100 Ethernet [pegasus]", "SpeedStream"), + T_DATA("SpeedTouch 120g 802.11g Wireless Adapter [Intersil ISL3886]", "SpeedTouch 120g"), + T_DATA("SpeedTouch 121g Wireless Dongle", "SpeedTouch 121g Dongle"), + T_DATA("Sphairon Homelink 1202 802.11n Wireless Adapter [Atheros AR9170]", + "Sphairon Homelink 1202"), + T_DATA("ST201 Sundance Ethernet", "ST201 Sundance"), + T_DATA("ST268", "ST268"), + T_DATA("SURECOM EP-320X-S 100/10M Ethernet PCI Adapter", "SURECOM EP-320X-S"), + T_DATA("T210 Protocol Engine", "T210 Protocol Engine"), + T_DATA("T302 1GbE Dual Port Adapter", "T302"), + T_DATA("T310 10GbE Single Port Adapter", "T310 Single Port"), + T_DATA("T320 10GbE Dual Port Adapter", "T320"), + T_DATA("T404-BT Unified Wire Ethernet Controller", "T404-BT"), + T_DATA("T404-BT Unified Wire Ethernet Controller [VF]", "T404-BT"), + T_DATA("T420-4082 Unified Wire Ethernet Controller", "T420-4082"), + T_DATA("T420-4082 Unified Wire Ethernet Controller [VF]", "T420-4082"), + T_DATA("T420-4085 SFP+ Unified Wire Ethernet Controller", "T420-4085 SFP+"), + T_DATA("T420-4085 SFP+ Unified Wire Ethernet Controller [VF]", "T420-4085 SFP+"), + T_DATA("T420-BCH Unified Wire Ethernet Controller", "T420-BCH"), + T_DATA("T420-BCH Unified Wire Ethernet Controller [VF]", "T420-BCH"), + T_DATA("T420-BT Unified Wire Ethernet Controller", "T420-BT"), + T_DATA("T420-BT Unified Wire Ethernet Controller [VF]", "T420-BT"), + T_DATA("T420-CR Unified Wire Ethernet Controller", "T420-CR"), + T_DATA("T420-CR Unified Wire Ethernet Controller [VF]", "T420-CR"), + T_DATA("T420-CX Unified Wire Ethernet Controller", "T420-CX"), + T_DATA("T420-CX Unified Wire Ethernet Controller [VF]", "T420-CX"), + T_DATA("T420-SO Unified Wire Ethernet Controller", "T420-SO"), + T_DATA("T420-SO Unified Wire Ethernet Controller [VF]", "T420-SO"), + T_DATA("T420X-4083 Unified Wire Ethernet Controller", "T420X-4083"), + T_DATA("T420X-4083 Unified Wire Ethernet Controller [VF]", "T420X-4083"), + T_DATA("T422-CR Unified Wire Ethernet Controller", "T422-CR"), + T_DATA("T422-CR Unified Wire Ethernet Controller [VF]", "T422-CR"), + T_DATA("T440-4084 Unified Wire Ethernet Controller", "T440-4084"), + T_DATA("T440-4084 Unified Wire Ethernet Controller [VF]", "T440-4084"), + T_DATA("T440-4086 10Gbase-T Unified Wire Ethernet Controller", "T440-4086"), + T_DATA("T440-4086 10Gbase-T Unified Wire Ethernet Controller [VF]", "T440-4086"), + T_DATA("T440-4088 Unified Wire Ethernet Controller", "T440-4088"), + T_DATA("T440-4088 Unified Wire Ethernet Controller [VF]", "T440-4088"), + T_DATA("T440-BCH Unified Wire Ethernet Controller", "T440-BCH"), + T_DATA("T440-BCH Unified Wire Ethernet Controller [VF]", "T440-BCH"), + T_DATA("T440-CH Unified Wire Ethernet Controller", "T440-CH"), + T_DATA("T440-CH Unified Wire Ethernet Controller [VF]", "T440-CH"), + T_DATA("T440-CR Unified Wire Ethernet Controller", "T440-CR"), + T_DATA("T440-CR Unified Wire Ethernet Controller [VF]", "T440-CR"), + T_DATA("T440F-4081 T440-FCoE Unified Wire Ethernet Controller", "T440F-4081 T440-FCoE"), + T_DATA("T440F-4081 T440-FCoE Unified Wire Ethernet Controller [VF]", + "T440F-4081 T440-FCoE"), + T_DATA("T440-LP-CR Unified Wire Ethernet Controller", "T440-LP-CR"), + T_DATA("T440-LP-CR Unified Wire Ethernet Controller [VF]", "T440-LP-CR"), + T_DATA("T440T-4087 Unified Wire Ethernet Controller", "T440T-4087"), + T_DATA("T440T-4087 Unified Wire Ethernet Controller [VF]", "T440T-4087"), + T_DATA("T480-4080 T480 Unified Wire Ethernet Controller", "T480-4080 T480"), + T_DATA("T480-4080 T480 Unified Wire Ethernet Controller [VF]", "T480-4080 T480"), + T_DATA("T480 Unified Wire Ethernet Controller", "T480"), + T_DATA("T480 Unified Wire Ethernet Controller [VF]", "T480"), + T_DATA("T502-BT Unified Wire Ethernet Controller", "T502-BT"), + T_DATA("T502-BT Unified Wire Ethernet Controller [VF]", "T502-BT"), + T_DATA("T504-5082 Unified Wire Ethernet Controller", "T504-5082"), + T_DATA("T504-5082 Unified Wire Ethernet Controller [VF]", "T504-5082"), + T_DATA("T504-BT Unified Wire Ethernet Controller", "T504-BT"), + T_DATA("T504-BT Unified Wire Ethernet Controller [VF]", "T504-BT"), + T_DATA("T520-5089 Unified Wire Ethernet Controller", "T520-5089"), + T_DATA("T520-5089 Unified Wire Ethernet Controller [VF]", "T520-5089"), + T_DATA("T520-5092 Unified Wire Ethernet Controller", "T520-5092"), + T_DATA("T520-5092 Unified Wire Ethernet Controller [VF]", "T520-5092"), + T_DATA("T520-5097 Unified Wire Ethernet Controller", "T520-5097"), + T_DATA("T520-5097 Unified Wire Ethernet Controller [VF]", "T520-5097"), + T_DATA("T520-509A Unified Wire Ethernet Controller", "T520-509A"), + T_DATA("T520-509A Unified Wire Ethernet Controller [VF]", "T520-509A"), + T_DATA("T520-509C Unified Wire Ethernet Controller", "T520-509C"), + T_DATA("T520-509C Unified Wire Ethernet Controller [VF]", "T520-509C"), + T_DATA("T520-509E Unified Wire Ethernet Controller", "T520-509E"), + T_DATA("T520-509E Unified Wire Ethernet Controller [VF]", "T520-509E"), + T_DATA("T520-BCH Unified Wire Ethernet Controller", "T520-BCH"), + T_DATA("T520-BCH Unified Wire Ethernet Controller [VF]", "T520-BCH"), + T_DATA("T520-BT Unified Wire Ethernet Controller", "T520-BT"), + T_DATA("T520-BT Unified Wire Ethernet Controller [VF]", "T520-BT"), + T_DATA("T520-CR Unified Wire Ethernet Controller", "T520-CR"), + T_DATA("T520-CR Unified Wire Ethernet Controller [VF]", "T520-CR"), + T_DATA("T520-CX Unified Wire Ethernet Controller", "T520-CX"), + T_DATA("T520-CX Unified Wire Ethernet Controller [VF]", "T520-CX"), + T_DATA("T520-LL-CR Unified Wire Ethernet Controller", "T520-LL-CR"), + T_DATA("T520-LL-CR Unified Wire Ethernet Controller [VF]", "T520-LL-CR"), + T_DATA("T520-OCP-SO Unified Wire Ethernet Controller", "T520-OCP-SO"), + T_DATA("T520-OCP-SO Unified Wire Ethernet Controller [VF]", "T520-OCP-SO"), + T_DATA("T520-SO Unified Wire Ethernet Controller", "T520-SO"), + T_DATA("T520-SO Unified Wire Ethernet Controller [VF]", "T520-SO"), + T_DATA("T522-5091 Unified Wire Ethernet Controller", "T522-5091"), + T_DATA("T522-5091 Unified Wire Ethernet Controller [VF]", "T522-5091"), + T_DATA("T522-CR Unified Wire Ethernet Controller", "T522-CR"), + T_DATA("T522-CR Unified Wire Ethernet Controller [VF]", "T522-CR"), + T_DATA("T540-5080 Unified Wire Ethernet Controller", "T540-5080"), + T_DATA("T540-5080 Unified Wire Ethernet Controller [VF]", "T540-5080"), + T_DATA("T540-5081 Unified Wire Ethernet Controller", "T540-5081"), + T_DATA("T540-5081 Unified Wire Ethernet Controller [VF]", "T540-5081"), + T_DATA("T540-5083 Unified Wire Ethernet Controller", "T540-5083"), + T_DATA("T540-5083 Unified Wire Ethernet Controller [VF]", "T540-5083"), + T_DATA("T540-5084 Unified Wire Ethernet Controller", "T540-5084"), + T_DATA("T540-5084 Unified Wire Ethernet Controller [VF]", "T540-5084"), + T_DATA("T540-5090 Unified Wire Ethernet Controller", "T540-5090"), + T_DATA("T540-5090 Unified Wire Ethernet Controller [VF]", "T540-5090"), + T_DATA("T540-5094 Unified Wire Ethernet Controller", "T540-5094"), + T_DATA("T540-5094 Unified Wire Ethernet Controller [VF]", "T540-5094"), + T_DATA("T540-5095 Unified Wire Ethernet Controller", "T540-5095"), + T_DATA("T540-5095 Unified Wire Ethernet Controller [VF]", "T540-5095"), + T_DATA("T540-509B Unified Wire Ethernet Controller", "T540-509B"), + T_DATA("T540-509B Unified Wire Ethernet Controller [VF]", "T540-509B"), + T_DATA("T540-509D Unified Wire Ethernet Controller", "T540-509D"), + T_DATA("T540-509D Unified Wire Ethernet Controller [VF]", "T540-509D"), + T_DATA("T540-509F Unified Wire Ethernet Controller", "T540-509F"), + T_DATA("T540-509F Unified Wire Ethernet Controller [VF]", "T540-509F"), + T_DATA("T540-50A0 Unified Wire Ethernet Controller", "T540-50A0"), + T_DATA("T540-50A0 Unified Wire Ethernet Controller [VF]", "T540-50A0"), + T_DATA("T540-50A1 Unified Wire Ethernet Controller", "T540-50A1"), + T_DATA("T540-50A1 Unified Wire Ethernet Controller [VF]", "T540-50A1"), + T_DATA("T540-BCH Unified Wire Ethernet Controller", "T540-BCH"), + T_DATA("T540-BCH Unified Wire Ethernet Controller [VF]", "T540-BCH"), + T_DATA("T540-BT Unified Wire Ethernet Controller", "T540-BT"), + T_DATA("T540-BT Unified Wire Ethernet Controller [VF]", "T540-BT"), + T_DATA("T540-CH Unified Wire Ethernet Controller", "T540-CH"), + T_DATA("T540-CH Unified Wire Ethernet Controller [VF]", "T540-CH"), + T_DATA("T540-CR Unified Wire Ethernet Controller", "T540-CR"), + T_DATA("T540-CR Unified Wire Ethernet Controller [VF]", "T540-CR"), + T_DATA("T540-LP-CR Unified Wire Ethernet Controller", "T540-LP-CR"), + T_DATA("T540-LP-CR Unified Wire Ethernet Controller [VF]", "T540-LP-CR"), + T_DATA("T560-CR Unified Wire Ethernet Controller", "T560-CR"), + T_DATA("T560-CR Unified Wire Ethernet Controller [VF]", "T560-CR"), + T_DATA("T570-5088 Unified Wire Ethernet Controller", "T570-5088"), + T_DATA("T570-5088 Unified Wire Ethernet Controller [VF]", "T570-5088"), + T_DATA("T580-5085 Unified Wire Ethernet Controller", "T580-5085"), + T_DATA("T580-5085 Unified Wire Ethernet Controller [VF]", "T580-5085"), + T_DATA("T580-5086 Unified Wire Ethernet Controller", "T580-5086"), + T_DATA("T580-5086 Unified Wire Ethernet Controller [VF]", "T580-5086"), + T_DATA("T580-5087 Unified Wire Ethernet Controller", "T580-5087"), + T_DATA("T580-5087 Unified Wire Ethernet Controller [VF]", "T580-5087"), + T_DATA("T580-5093 Unified Wire Ethernet Controller", "T580-5093"), + T_DATA("T580-5093 Unified Wire Ethernet Controller [VF]", "T580-5093"), + T_DATA("T580-5096 Unified Wire Ethernet Controller", "T580-5096"), + T_DATA("T580-5096 Unified Wire Ethernet Controller [VF]", "T580-5096"), + T_DATA("T580-5098 Unified Wire Ethernet Controller", "T580-5098"), + T_DATA("T580-5098 Unified Wire Ethernet Controller [VF]", "T580-5098"), + T_DATA("T580-5099 Unified Wire Ethernet Controller", "T580-5099"), + T_DATA("T580-5099 Unified Wire Ethernet Controller [VF]", "T580-5099"), + T_DATA("T580-50A2 Unified Wire Ethernet Controller", "T580-50A2"), + T_DATA("T580-50A2 Unified Wire Ethernet Controller [VF]", "T580-50A2"), + T_DATA("T580-CHR Unified Wire Ethernet Controller", "T580-CHR"), + T_DATA("T580-CHR Unified Wire Ethernet Controller [VF]", "T580-CHR"), + T_DATA("T580-CR Unified Wire Ethernet Controller", "T580-CR"), + T_DATA("T580-CR Unified Wire Ethernet Controller [VF]", "T580-CR"), + T_DATA("T580-LP-CR Unified Wire Ethernet Controller", "T580-LP-CR"), + T_DATA("T580-LP-CR Unified Wire Ethernet Controller [VF]", "T580-LP-CR"), + T_DATA("T580-OCP-SO Unified Wire Ethernet Controller", "T580-OCP-SO"), + T_DATA("T580-OCP-SO Unified Wire Ethernet Controller [VF]", "T580-OCP-SO"), + T_DATA("T580-SO-CR Unified Wire Ethernet Controller", "T580-SO-CR"), + T_DATA("T580-SO-CR Unified Wire Ethernet Controller [VF]", "T580-SO-CR"), + T_DATA("T61100-OCP-SO Unified Wire Ethernet Controller", "T61100-OCP-SO"), + T_DATA("T61100-OCP-SO Unified Wire Ethernet Controller [VF]", "T61100-OCP-SO"), + T_DATA("T6201-BT Unified Wire Ethernet Controller", "T6201-BT"), + T_DATA("T6201-BT Unified Wire Ethernet Controller [VF]", "T6201-BT"), + T_DATA("T62100-6081 Unified Wire Ethernet Controller", "T62100-6081"), + T_DATA("T62100-6081 Unified Wire Ethernet Controller [VF]", "T62100-6081"), + T_DATA("T62100-6083 Unified Wire Ethernet Controller", "T62100-6083"), + T_DATA("T62100-6083 Unified Wire Ethernet Controller [VF]", "T62100-6083"), + T_DATA("T62100-CR Unified Wire Ethernet Controller", "T62100-CR"), + T_DATA("T62100-CR Unified Wire Ethernet Controller [VF]", "T62100-CR"), + T_DATA("T62100-LP-CR Unified Wire Ethernet Controller", "T62100-LP-CR"), + T_DATA("T62100-LP-CR Unified Wire Ethernet Controller [VF]", "T62100-LP-CR"), + T_DATA("T62100-OCP-SO Unified Wire Ethernet Controller", "T62100-OCP-SO"), + T_DATA("T62100-OCP-SO Unified Wire Ethernet Controller [VF]", "T62100-OCP-SO"), + T_DATA("T62100-SO-CR Unified Wire Ethernet Controller", "T62100-SO-CR"), + T_DATA("T62100-SO-CR Unified Wire Ethernet Controller [VF]", "T62100-SO-CR"), + T_DATA("T6210-BT Unified Wire Ethernet Controller", "T6210-BT"), + T_DATA("T6210-BT Unified Wire Ethernet Controller [VF]", "T6210-BT"), + T_DATA("T6225-6080 Unified Wire Ethernet Controller", "T6225-6080"), + T_DATA("T6225-6080 Unified Wire Ethernet Controller [VF]", "T6225-6080"), + T_DATA("T6225-6082 Unified Wire Ethernet Controller", "T6225-6082"), + T_DATA("T6225-6082 Unified Wire Ethernet Controller [VF]", "T6225-6082"), + T_DATA("T6225-CR Unified Wire Ethernet Controller", "T6225-CR"), + T_DATA("T6225-CR Unified Wire Ethernet Controller [VF]", "T6225-CR"), + T_DATA("T6225-LL-CR Unified Wire Ethernet Controller", "T6225-LL-CR"), + T_DATA("T6225-LL-CR Unified Wire Ethernet Controller [VF]", "T6225-LL-CR"), + T_DATA("T6225-OCP-SO Unified Wire Ethernet Controller", "T6225-OCP-SO"), + T_DATA("T6225-OCP-SO Unified Wire Ethernet Controller [VF]", "T6225-OCP-SO"), + T_DATA("T6225-SO-CR Unified Wire Ethernet Controller", "T6225-SO-CR"), + T_DATA("T6225-SO-CR Unified Wire Ethernet Controller [VF]", "T6225-SO-CR"), + T_DATA("T64100-6084 Unified Wire Ethernet Controller", "T64100-6084"), + T_DATA("T64100-6084 Unified Wire Ethernet Controller [VF]", "T64100-6084"), + T_DATA("T6425-CR Unified Wire Ethernet Controller", "T6425-CR"), + T_DATA("T6425-CR Unified Wire Ethernet Controller [VF]", "T6425-CR"), + T_DATA("T6425-SO-CR Unified Wire Ethernet Controller", "T6425-SO-CR"), + T_DATA("T6425-SO-CR Unified Wire Ethernet Controller [VF]", "T6425-SO-CR"), + T_DATA("TalkTalk SNU5630NS/05 802.11bg", "TalkTalk SNU5630NS/05"), + T_DATA("TC902x Gigabit Ethernet", "TC902x"), + T_DATA("T-Com Sinus 154 data II [Intersil ISL3887]", "T-Com Sinus 154 data II"), + T_DATA("TEW-429UB 802.11bg", "TEW-429UB"), + T_DATA("TEW-429UB C1 802.11bg", "TEW-429UB C1"), + T_DATA("TEW-444UB EU (no firmware)", "TEW-444UB EU"), + T_DATA("TEW-444UB EU [TRENDnet]", "TEW-444UB EU"), + T_DATA("TEW-509UB A1 802.11abg Wireless Adapter [ZyDAS ZD1211]", "TEW-509UB A1"), + T_DATA("TEW-645UB 802.11bgn 1x2:2 Wireless Adapter [Ralink RT2770]", "TEW-645UB"), + T_DATA("TEW-648UBM 802.11n 150Mbps Micro Wireless N Adapter [Realtek RTL8188CUS]", + "TEW-648UBM"), + T_DATA("TG54USB 802.11bg", "TG54USB"), + T_DATA("Thomson TG121N [Atheros AR9001U-(2)NG]", "Thomson TG121N"), + T_DATA("Top Global Gobi 2000 Wireless Modem", "Top Global Gobi 2000"), + T_DATA("TP-Link TL-WN322G v3 / TL-WN422G v2 802.11g [Atheros AR9271]", + "TP-Link TL-WN322G / TL-WN422G"), + T_DATA("TP-Link TL-WN821N v2 / TL-WN822N v1 802.11n [Atheros AR9170]", + "TP-Link TL-WN821N / TL-WN822N"), + T_DATA("TP-Link TL-WN821N v3 / TL-WN822N v2 802.11n [Atheros AR7010+AR9287]", + "TP-Link TL-WN821N / TL-WN822N"), + T_DATA("TrueMobile 1300 802.11g Wireless Adapter [Intersil ISL3880]", "TrueMobile 1300"), + T_DATA("T-Sinus 154data", "T-Sinus 154data"), + T_DATA("TTP-Monitoring Card V2.0", "TTP-Monitoring"), + T_DATA("Turbolink UB801RE Wireless 802.11g 54Mbps Network Adapter [RTL8187]", + "Turbolink UB801RE"), + T_DATA("Turbolink UB801R WLAN Adapter", "Turbolink UB801R"), + T_DATA("U2E", "U2E"), + T_DATA("U5 802.11g Adapter", "U5"), + T_DATA("UB81 802.11bgn", "UB81"), + T_DATA("UB82 802.11abgn", "UB82"), + T_DATA("Ubiquiti WiFiStation 802.11n [Atheros AR9271]", "Ubiquiti WiFiStation"), + T_DATA("Ubiquiti WiFiStationEXT 802.11n [Atheros AR9271]", "Ubiquiti WiFiStationEXT"), + T_DATA("UBS-10BT Ethernet [klsi]", "UBS-10BT"), + T_DATA("UBS-10BT Ethernet", "UBS-10BT"), + T_DATA("UC-110T 100Mbps Ethernet [pegasus]", "UC-110T"), + T_DATA("UC-210T Ethernet", "UC-210T"), + T_DATA("UF100 Ethernet [pegasus2]", "UF100"), + T_DATA("UF200 Ethernet", "UF200"), + T_DATA("ULi 1689,1573 integrated ethernet.", "ULi 1689 1573"), + T_DATA("Ultimate N WiFi Link 5300", "Ultimate N 5300"), + T_DATA("un2400 Gobi Wireless Modem", "un2400 Gobi"), + T_DATA("UniNorth 2 GMAC (Sun GEM)", "UniNorth 2 GMAC"), + T_DATA("UniNorth GMAC (Sun GEM)", "UniNorth GMAC"), + T_DATA("UniNorth/Pangea GMAC (Sun GEM)", "UniNorth/Pangea GMAC"), + T_DATA("UR054g 802.11g Wireless Adapter [Intersil ISL3887]", "UR054g"), + T_DATA("UR055G 802.11bg", "UR055G"), + T_DATA("USB1000 Gigabit Notebook Adapter", "USB1000"), + T_DATA("USB-100N Ethernet [pegasus]", "USB-100N"), + T_DATA("USB100TX Ethernet [pegasus]", "USB100TX"), + T_DATA("USB100TX HomePNA Ethernet [pegasus]", "USB100TX HomePNA"), + T_DATA("USB10TX Ethernet [pegasus]", "USB10TX"), + T_DATA("USB10TX", "USB10TX"), + T_DATA("USB 1.1 10/100M Fast Ethernet Adapter", NULL), + T_DATA("USB200M 100baseTX Adapter", "USB200M 100baseTX"), + T_DATA("USB200M 10/100 Ethernet Adapter", "USB200M"), + T_DATA("USB 2.0 Ethernet", NULL), + T_DATA("USB2AR Ethernet", "USB2AR"), + T_DATA("USBcan II", "USBcan II"), + T_DATA("USBE-100 Ethernet [pegasus2]", "USBE-100"), + T_DATA("USBEL-100 Ethernet [pegasus]", "USBEL-100"), + T_DATA("USB Ethernet [pegasus]", "pegasus"), + T_DATA("USB ETT", "ETT"), + T_DATA("USBLAN", "USBLAN"), + T_DATA("USBLP-100 HomePNA Ethernet [pegasus]", "USBLP-100 HomePNA"), + T_DATA("USB-N10 v2 802.11b/g/n Wireless Adapter [MediaTek MT7601U]", "USB-N10"), + T_DATA("USB-N11 802.11n Network Adapter [Ralink RT2870]", "USB-N11"), + T_DATA("USB-N13 802.11n Network Adapter (rev. A1) [Ralink RT3072]", "USB-N13"), + T_DATA("USB-N13 802.11n Network Adapter (rev. B1) [Realtek RTL8192CU]", "USB-N13"), + T_DATA("USB-N14 802.11b/g/n (2x2) Wireless Adapter [Ralink RT5372]", "USB-N14"), + T_DATA("USB-N53 802.11abgn Network Adapter [Ralink RT3572]", "USB-N53"), + T_DATA("USB TO Ethernet", NULL), + T_DATA("USR5420 802.11g Adapter [Broadcom 4320 USB]", "USR5420"), + T_DATA("USR5423 802.11bg Wireless Adapter [ZyDAS ZD1211B]", "USR5423"), + T_DATA("USR997902 10/100/1000 Mbps PCI Network Card", "USR997902 Mbps"), + T_DATA("VIC Ethernet NIC Dynamic", "VIC Dynamic"), + T_DATA("VIC Ethernet NIC", "VIC"), + T_DATA("VIC SR-IOV VF", "VIC SR-IOV VF"), + T_DATA("Vigor530 IEEE 802.11G Adapter (ISL3880+NET2280)", "Vigor530"), + T_DATA("Virtual media for 802.11bg", NULL), + T_DATA("VMXNET3 Ethernet Controller", "VMXNET3"), + T_DATA("VT6102/VT6103 [Rhine-II]", "VT6102/VT6103"), + T_DATA("VT6105M [Rhine-III]", "VT6105M"), + T_DATA("VT6105/VT6106S [Rhine-III]", "VT6105/VT6106S"), + T_DATA("VT6120/VT6121/VT6122 Gigabit Ethernet Adapter", "VT6120/VT6121/VT6122"), + T_DATA("VT82C926 [Amazon]", "VT82C926"), + T_DATA("VT86C100A [Rhine]", "VT86C100A"), + T_DATA("W89C840", "W89C840"), + T_DATA("W89C940F", "W89C940F"), + T_DATA("W89C940 misprogrammed [ne2k]", "W89C940"), + T_DATA("W89C940", "W89C940"), + T_DATA("WG111T (no firmware)", "WG111T"), + T_DATA("WG111T", "WG111T"), + T_DATA("WG111U Double 108 Mbps Wireless [Atheros AR5004X / AR5005UX]", "WG111U"), + T_DATA("WG111U (no firmware) Double 108 Mbps Wireless [Atheros AR5004X / AR5005UX]", + "WG111U"), + T_DATA("WG111(v1) 54 Mbps Wireless [Intersil ISL3886]", "WG111"), + T_DATA("WG111(v1) rev 2 54 Mbps Wireless [Intersil ISL3887]", "WG111"), + T_DATA("WG111v2 54 Mbps Wireless [RealTek RTL8187L]", "WG111v2"), + T_DATA("WG111v3 54 Mbps Wireless [realtek RTL8187B]", "WG111v3"), + T_DATA("WG121(v1) 54 Mbps Wireless [Intersil ISL3886]", "WG121"), + T_DATA("WG121(v2) 54 Mbps Wireless [Intersil ISL3886]", "WG121"), + T_DATA("WGU-210 802.11g Adapter [Intersil ISL3886]", "WGU-210"), + T_DATA("WHG-AGDN/US Wireless LAN Adapter", "WHG-AGDN/US"), + T_DATA("Wi-Fi 11g adapter", NULL), + T_DATA("WiFi Link 5100", "5100"), + T_DATA("Wil6200 802.11ad Wireless Network Adapter", "Wil6200"), + T_DATA("WiMAX/WiFi Link 5150", "5150"), + T_DATA("Wireless 11n USB Adapter", "11n"), + T_DATA("Wireless 1450 Dual-band (802.11a/b/g) Adapter [Intersil ISL3887]", "1450"), + T_DATA("Wireless 3160", "3160"), + T_DATA("Wireless 3165", "3165"), + T_DATA("Wireless 7260", "7260"), + T_DATA("Wireless 7265", "7265"), + T_DATA("Wireless 802.11g 54Mbps Network Adapter [RTL8187]", "RTL8187"), + T_DATA("Wireless 8260", "8260"), + T_DATA("Wireless 8265 / 8275", "8265 / 8275"), + T_DATA("Wireless Adapter 11g", NULL), + T_DATA("Wireless LAN USB Mini-Card", NULL), + T_DATA("Wireless MAXg Adapter [Broadcom 4320]", "MAXg"), + T_DATA("Wireless Network Adapter", NULL), + T_DATA("Wireless-N Network Adapter [Ralink RT2870]", "Ralink RT2870"), + T_DATA("Wireless PCI Adapter RT2400 / RT2460", "RT2400 / RT2460"), + T_DATA("WIS09ABGN LinkStick Wireless LAN Adapter", "WIS09ABGN LinkStick"), + T_DATA("WL-113 rev 1 Wireless Network USB Adapter", "WL-113"), + T_DATA("WL-113 rev 2 Wireless Network USB Adapter", "WL-113"), + T_DATA("WL-117 Hi-Speed USB Adapter", "WL-117"), + T_DATA("WL1271", "WL1271"), + T_DATA("WL-159g 802.11bg [ZyDAS ZD1211B+AL2230]", "WL-159g"), + T_DATA("WL-167G v1 802.11g Adapter [Ralink RT2571]", "WL-167G"), + T_DATA("WL-167G v2 802.11g Adapter [Ralink RT2571W]", "WL-167G"), + T_DATA("WL-168 Wireless Network Adapter 54g", "WL-168"), + T_DATA("WL169gE 802.11g Adapter [Broadcom 4320 USB]", "WL169gE"), + T_DATA("WL-172 Wireless Network USB Adapter 54g Turbo", "WL-172 Turbo"), + T_DATA("WL-182 Wireless-N Network USB Card", "WL-182"), + T_DATA("WL-188 Wireless Network 300N USB Adapter", "WL-188 300N"), + T_DATA("WL-301 Wireless Network 300N USB Adapter", "WL-301 300N"), + T_DATA("WL-302 Wireless Network 300N USB dongle", "WL-302 300N"), + T_DATA("WL-315 Wireless-N USB Adapter", "WL-315"), + T_DATA("WL-321 Wireless USB Gaming Adapter 300N", "WL-321 Gaming 300N"), + T_DATA("WL-323 Wireless-N USB Adapter", "WL-323"), + T_DATA("WL-324 Wireless USB Adapter 300N", "WL-324 300N"), + T_DATA("WL-329 Wireless Dualband USB adapter 300N", "WL-329 Dualband 300N"), + T_DATA("WL-343 Wireless USB Adapter 150N X1", "WL-343 150N X1"), + T_DATA("WL-344 Wireless Adapter 300N X2 [Ralink RT3071]", "WL-344 300N X2"), + T_DATA("WL-345 Wireless USB adapter 300N X3", "WL-345 300N X3"), + T_DATA("WL-349v1 Wireless Adapter 150N 002 [Ralink RT3070]", "WL-349v1 150N 002"), + T_DATA("WL-349v4 Wireless Micro Adapter 150N X1 [Ralink RT3370]", "WL-349v4 150N X1"), + T_DATA("WL-352v1 Wireless USB Adapter 300N 002", "WL-352v1 300N 002"), + T_DATA("WL-358v1 Wireless Micro USB Adapter 300N X3 002", "WL-358v1 300N X3 002"), + T_DATA("WL-430U 802.11bg", "WL-430U"), + T_DATA("WL532U 802.11g Adapter", "WL532U"), + T_DATA("WL-603 Wireless Adapter", "WL-603"), + T_DATA("WL-608 Wireless USB Adapter 54g", "WL-608"), + T_DATA("WLA3310 Wireless Adapter [Intersil ISL3887]", "WLA3310"), + T_DATA("WLA-4000 802.11bgn [Ralink RT3072]", "WLA-4000"), + T_DATA("WLA-5000 802.11abgn [Ralink RT3572]", "WLA-5000"), + T_DATA("WLA-5100", "WLA-5100"), + T_DATA("WLI2-USB2-G54 Wireless LAN Adapter", "WLI2-USB2-G54"), + T_DATA("WLI-U2-G54HP", "WLI-U2-G54HP"), + T_DATA("WLI-U2-KG125S 802.11g Adapter [Broadcom 4320 USB]", "WLI-U2-KG125S"), + T_DATA("WLI-U2-KG54-AI WLAN", "WLI-U2-KG54-AI"), + T_DATA("WLI-U2-KG54-BB", "WLI-U2-KG54-BB"), + T_DATA("WLI-U2-KG54L 802.11bg [ZyDAS ZD1211B]", "WLI-U2-KG54L"), + T_DATA("WLI-U2-KG54 WLAN", "WLI-U2-KG54"), + T_DATA("WLI-U2-KG54-YB WLAN", "WLI-U2-KG54-YB"), + T_DATA("WLI-U2-SG54HP", "WLI-U2-SG54HP"), + T_DATA("WLI-UC-AG300N Wireless LAN Adapter", "WLI-UC-AG300N"), + T_DATA("WLI-UC-G300HP Wireless LAN Adapter", "WLI-UC-G300HP"), + T_DATA("WLI-UC-G300N Wireless LAN Adapter [Ralink RT2870]", "WLI-UC-G300N"), + T_DATA("WLI-UC-G301N Wireless LAN Adapter [Ralink RT3072]", "WLI-UC-G301N"), + T_DATA("WLI-UC-G450 Wireless LAN Adapter", "WLI-UC-G450"), + T_DATA("WLI-UC-GNHP Wireless LAN Adapter", "WLI-UC-GNHP"), + T_DATA("WLI-UC-GNM2 Wireless LAN Adapter [Ralink RT3070]", "WLI-UC-GNM2"), + T_DATA("WLI-UC-GNM Wireless LAN Adapter [Ralink RT8070]", "WLI-UC-GNM"), + T_DATA("WLI-UC-GN Wireless LAN Adapter [Ralink RT3070]", "WLI-UC-GN"), + T_DATA("WLI-USB-G54 802.11g Adapter [Broadcom 4320 USB]", "WLI-USB-G54"), + T_DATA("WLM-10U1 802.11abgn Wireless Adapter [Ralink RT3572]", "WLM-10U1"), + T_DATA("WLM-20U2/GN-1080 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]", + "WLM-20U2/GN-1080"), + T_DATA("WLP-UC-AG300 Wireless LAN Adapter", "WLP-UC-AG300"), + T_DATA("WM168g 802.11bg Wireless Adapter [Intersil ISL3886]", "WM168g"), + T_DATA("WN111(v2) RangeMax Next Wireless [Atheros AR9170+AR9101]", "WN111"), + T_DATA("WNA1000M 802.11bgn [Realtek RTL8188CUS]", "WNA1000M"), + T_DATA("WNA1000Mv2 802.11bgn [Realtek RTL8188CUS?]", "WNA1000Mv2"), + T_DATA("WNA1000 Wireless-N 150 [Atheros AR9170+AR9101]", "WNA1000 150"), + T_DATA("WNA1100 Wireless-N 150 [Atheros AR9271]", "WNA1100 150"), + T_DATA("WNA3100M(v1) Wireless-N 300 [Realtek RTL8192CU]", "WNA3100M"), + T_DATA("WNDA3100v1 802.11abgn [Atheros AR9170+AR9104]", "WNDA3100v1"), + T_DATA("WNDA3200 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]", "WNDA3200"), + T_DATA("WNDA4100 802.11abgn 3x3:3 [Ralink RT3573]", "WNDA4100"), + T_DATA("WN-G150U Wireless LAN Adapter", "WN-G150U"), + T_DATA("WN-G300U Wireless LAN Adapter", "WN-G300U"), + T_DATA("WNGDNUS2 802.11n", "WNGDNUS2"), + T_DATA("WN-GDN/US3 Wireless LAN Adapter", "WN-GDN/US3"), + T_DATA("WPN111 802.11g Wireless Adapter [Atheros AR5523]", "WPN111"), + T_DATA("WPN111 (no firmware)", "WPN111"), + T_DATA("WPN111 RangeMax(TM) Wireless USB 2.0 Adapter", "WPN111 RangeMax"), + T_DATA("WUA-1340", "WUA-1340"), + T_DATA("WUA-2340 RangeBooster G Adapter(rev.A) [Atheros AR5523]", "WUA-2340 RangeBooster"), + T_DATA("WUA-2340 RangeBooster G Adapter(rev.A) (no firmware) [Atheros AR5523]", + "WUA-2340 RangeBooster"), + T_DATA("WUA-2340 RangeBooster G Adapter(rev.B) [Ralink RT2070]", "WUA-2340 RangeBooster"), + T_DATA("WUBR-177G [Ralink RT2571W]", "WUBR-177G"), + T_DATA("WUBR-208N 802.11abgn Wireless Adapter [Ralink RT2870]", "WUBR-208N"), + T_DATA("WUG2690 802.11bg Wireless Module [ZyDAS ZD1211+AL2230]", "WUG2690"), + T_DATA("WUG2700", "WUG2700"), + T_DATA("WUS-201 802.11bg", "WUS-201"), + T_DATA("WUSB100 v1 RangePlus Wireless Network Adapter [Ralink RT2870]", + "WUSB100 RangePlus"), + T_DATA("WUSB100 v2 RangePlus Wireless Network Adapter [Ralink RT3070]", + "WUSB100 RangePlus"), + T_DATA("WUSB200 802.11g Adapter [Ralink RT2671]", "WUSB200"), + T_DATA("WUSB54AG 802.11a/g Adapter [Intersil ISL3887]", "WUSB54AG"), + T_DATA("WUSB54GC v1 802.11g Adapter [Ralink RT73]", "WUSB54GC"), + T_DATA("WUSB54GC v2 802.11g Adapter [Realtek RTL8187B]", "WUSB54GC"), + T_DATA("WUSB54GC v3 802.11g Adapter [Ralink RT2070L]", "WUSB54GC"), + T_DATA("WUSB54GP v1 802.11g Adapter [Intersil ISL3886]", "WUSB54GP"), + T_DATA("WUSB54GP v4.0 802.11g Adapter [Ralink RT2500USB]", "WUSB54GP v4.0"), + T_DATA("WUSB54GR", "WUSB54GR"), + T_DATA("WUSB54GSC v1 802.11g Adapter [Broadcom 4320 USB]", "WUSB54GSC"), + T_DATA("WUSB54GS v1 802.11g Adapter [Broadcom 4320 USB]", "WUSB54GS"), + T_DATA("WUSB54GS v2 802.11g Adapter [Broadcom 4320 USB]", "WUSB54GS"), + T_DATA("WUSB54G v1 802.11g Adapter [Intersil ISL3886]", "WUSB54G"), + T_DATA("WUSB54G v2 802.11g Adapter [Intersil ISL3887]", "WUSB54G"), + T_DATA("WUSB54G v4 802.11g Adapter [Ralink RT2500USB]", "WUSB54G"), + T_DATA("WUSB600N v1 Dual-Band Wireless-N Network Adapter [Ralink RT2870]", + "WUSB600N Dual-Band"), + T_DATA("WUSB600N v2 Dual-Band Wireless-N Network Adapter [Ralink RT3572]", + "WUSB600N Dual-Band"), + T_DATA("WUSBF54G 802.11bg", "WUSBF54G"), + T_DATA("WUSBF54G v1.1 802.11bg", "WUSBF54G"), + T_DATA("X3100 Series 10 Gigabit Ethernet PCIe", "X3100"), + T_DATA("X540 Ethernet Controller Virtual Function", "X540 Virtual Function"), + T_DATA("X540 Virtual Function", "X540 Virtual Function"), + T_DATA("X550 Virtual Function", "X550 Virtual Function"), + T_DATA("X552 Virtual Function", "X552 Virtual Function"), + T_DATA("X553 Virtual Function", "X553 Virtual Function"), + T_DATA("X722 Virtual Function", "X722 Virtual Function"), + T_DATA("Xframe 10-Gigabit Ethernet PCI-X", "Xframe"), + T_DATA("Xframe II 10-Gigabit Ethernet PCI-X 2.0", "Xframe II 2.0"), + T_DATA("XG-300 802.11b Adapter", "XG-300"), + T_DATA("XG-703A 802.11g Wireless Adapter [Intersil ISL3887]", "XG-703A"), + T_DATA("XG-705A 802.11g Wireless Adapter [Intersil ISL3887]", "XG-705A"), + T_DATA("XG-760A 802.11bg", "XG-760A"), + T_DATA("XG-76NA 802.11bg", "XG-76NA"), + T_DATA("XG Mgmt", "XG Mgmt"), + T_DATA("Xircom PGUNET USB-USB Bridge", "Xircom PGUNET USB-USB Bridge"), + T_DATA("XL710/X710 Virtual Function", "XL710/X710 Virtual Function"), + T_DATA("XX1", "XX1"), + T_DATA("XX2", "XX2"), + T_DATA("XX4", "XX4"), + T_DATA("XX5", "XX5"), + T_DATA("XX6", "XX6"), + T_DATA("XX7", "XX7"), + T_DATA("XX9", "XX9"), + T_DATA("Yellowfin G-NIC gigabit ethernet", "Yellowfin"), + T_DATA("YP3X00 PDA", "YP3X00"), + T_DATA("Yukon Optima 88E8059 [PCIe Gigabit Ethernet Controller with AVB]", + "Yukon Optima 88E8059"), + T_DATA("Zaurus A-300", "Zaurus A-300"), + T_DATA("Zaurus C-700 PDA", "Zaurus C-700"), + T_DATA("Zaurus C-750/C-760/C-860/SL-C3000 PDA", "Zaurus C-750/C-760/C-860/SL-C3000"), + T_DATA("Zaurus C-860 PDA", "Zaurus C-860"), + T_DATA("Zaurus SL-5000D/SL-5500 PDA", "Zaurus SL-5000D/SL-5500"), + T_DATA("Zaurus SL-6000", "Zaurus SL-6000"), + T_DATA("Zaurus SL-B500/SL-5600 PDA", "Zaurus SL-B500/SL-5600"), + T_DATA("ZD1211 802.11b/g Wireless Adapter", "ZD1211"), + T_DATA("ZD1211 802.11g", "ZD1211"), + T_DATA("ZD1211B 802.11g", "ZD1211B"), + T_DATA("ZD1211B", "ZD1211B"), + T_DATA("ZD1221 802.11n", "ZD1221"), + T_DATA("Zoom 4410 Wireless-G [Intersil ISL3887]", "Zoom 4410"), + T_DATA("ZT6688 Fast Ethernet Adapter", "ZT6688"), + T_DATA("ZyAIR AG-225H v2 802.11bg", "ZyAIR AG-225H"), + T_DATA("ZyAIR G-202 802.11bg", "ZyAIR G-202"), + T_DATA("ZyAIR G-220 802.11bg", "ZyAIR G-220"), + T_DATA("ZyAIR G-220F 802.11bg", "ZyAIR G-220F"), + }; + + _test_fixup_string(data, G_N_ELEMENTS(data), nm_utils_fixup_product_string); +} + +/*****************************************************************************/ + +static int +_memfd_create(const char *name) +{ +#if defined(HAVE_DECL_MEMFD_CREATE) && HAVE_DECL_MEMFD_CREATE + return memfd_create(name, MFD_CLOEXEC); +#endif + return -1; +} + +typedef struct { + const char *key; + const char *val; +} ReadVpnDetailData; + +#define READ_VPN_DETAIL_DATA(...) ((ReadVpnDetailData[]){__VA_ARGS__}) + +static gboolean +_do_read_vpn_details_impl1(const char * file, + int line, + int memfd, + char * mem, + gsize len, + const ReadVpnDetailData *expected_data, + guint expected_data_len, + const ReadVpnDetailData *expected_secrets, + guint expected_secrets_len) +{ + gssize written; + off_t lseeked; + gs_unref_hashtable GHashTable *data = NULL; + gs_unref_hashtable GHashTable *secrets = NULL; + + written = write(memfd, mem, len); + g_assert_cmpint(written, ==, (gssize) len); + + lseeked = lseek(memfd, 0, SEEK_SET); + g_assert_cmpint(lseeked, ==, 0); + + if (!nm_vpn_service_plugin_read_vpn_details(memfd, &data, &secrets)) { + g_assert(!data); + g_assert(!secrets); + g_assert_cmpint(expected_data_len, ==, 0); + g_assert_cmpint(expected_secrets_len, ==, 0); + return TRUE; + } + +#define _assert_hash(hash, expected, expected_len) \ + G_STMT_START \ + { \ + GHashTable * _hash = (hash); \ + guint _expected_len = (expected_len); \ + const ReadVpnDetailData *_expected = (expected); \ + GHashTableIter _iter; \ + const char * _k, *_v; \ + guint _i; \ + \ + g_assert(_hash); \ + \ + g_hash_table_iter_init(&_iter, _hash); \ + while (g_hash_table_iter_next(&_iter, (gpointer *) &_k, (gpointer *) &_v)) { \ + for (_i = 0; _i < _expected_len; _i++) { \ + if (nm_streq(_expected[_i].key, _k)) \ + break; \ + } \ + if (_i >= _expected_len) \ + g_error("%s:%d: hash '%s' contains unexpected data key '%s' with value '%s'", \ + file, \ + line, \ + G_STRINGIFY(hash), \ + _k, \ + _v); \ + } \ + \ + for (_i = 0; _i < _expected_len; _i++) { \ + const ReadVpnDetailData *_d = &_expected[_i]; \ + \ + g_assert(_d->key); \ + g_assert(_d->val); \ + _v = g_hash_table_lookup(_hash, _d->key); \ + if (!nm_streq0(_v, _d->val)) \ + g_error("%s:%d: hash '%s' contains data key '%s' with value %s%s%s but we " \ + "expected '%s'", \ + file, \ + line, \ + G_STRINGIFY(hash), \ + _d->key, \ + NM_PRINT_FMT_QUOTE_STRING(_v), \ + _d->val); \ + } \ + \ + g_assert_cmpint(g_hash_table_size(_hash), ==, _expected_len); \ + } \ + G_STMT_END + + _assert_hash(data, expected_data, expected_data_len); + _assert_hash(secrets, expected_secrets, expected_secrets_len); + +#undef _assert_hash + return TRUE; +} + +#define _do_read_vpn_details_impl0(str, \ + expected_data, \ + expected_data_len, \ + expected_secrets, \ + expected_secrets_len, \ + pre_setup_cmd) \ + G_STMT_START \ + { \ + nm_auto_close int _memfd = _memfd_create("libnm-test-read-vpn-details"); \ + \ + if (_memfd < 0) \ + g_test_skip("cannot create memfd"); \ + else { \ + { \ + pre_setup_cmd; \ + } \ + _do_read_vpn_details_impl1(__FILE__, \ + __LINE__, \ + _memfd, \ + "" str "", \ + NM_STRLEN(str), \ + expected_data, \ + expected_data_len, \ + expected_secrets, \ + expected_secrets_len); \ + } \ + } \ + G_STMT_END + +#define _do_read_vpn_details_empty(str) _do_read_vpn_details_impl0(str, NULL, 0, NULL, 0, {}) + +#define _do_read_vpn_details(str, expected_data, expected_secrets, pre_setup_cmd) \ + _do_read_vpn_details_impl0(str, \ + expected_data, \ + G_N_ELEMENTS(expected_data), \ + expected_secrets, \ + G_N_ELEMENTS(expected_secrets), \ + pre_setup_cmd) + +static void +test_nm_vpn_service_plugin_read_vpn_details(void) +{ + _do_read_vpn_details_empty(""); + _do_read_vpn_details_empty("hallo"); + _do_read_vpn_details_empty("DONE"); + _do_read_vpn_details_empty("DONE\n"); + _do_read_vpn_details_empty("DONE\0"); + _do_read_vpn_details_empty("\0DONE\0"); + + _do_read_vpn_details("" + "DATA_KEY=some-key\n" + "DATA_VAL=string\n" + "\n" + "DATA_KEY=some-other-key\n" + "DATA_VAL=val2\n" + "\n" + "SECRET_KEY=some-secret\n" + "SECRET_VAL=val3\n" + "\n" + "DONE\n" + "\n" + "", + READ_VPN_DETAIL_DATA({"some-key", "string"}, {"some-other-key", "val2"}, ), + READ_VPN_DETAIL_DATA({"some-secret", "val3"}, ), ); + + _do_read_vpn_details("" + "DATA_KEY=some-key\n" + "DATA_VAL=string\n" + "DONE\n", + READ_VPN_DETAIL_DATA({"some-key", "string"}, ), + READ_VPN_DETAIL_DATA(), ); + + _do_read_vpn_details( + "" + "DATA_KEY=some-key\n" + "DATA_VAL=string\n" + "=continued after a line break\n" + "SECRET_KEY=key names\n" + "=can have\n" + "=continuations too\n" + "bogus1=\n" + "SECRET_VAL=value\n" + "bogus=value\n" + "bogus=\n" + "DATA_VAL=x\n" + "DATA_KEY=\n" + "DATA_VAL=\n" + "DATA_VAL=y\n" + "DATA_KEY=y\n" + "DATA_KEY=y\n" + "DATA_KEY=z\n" + "SECRET_KEY=s1\n" + "DATA_VAL=z\n" + "SECRET_VAL=S1\n" + "\n" + "DONE\n" + "", + READ_VPN_DETAIL_DATA({"some-key", "string\ncontinued after a line break"}, ), + READ_VPN_DETAIL_DATA({"key names\ncan have\ncontinuations too", "value"}, ), + NMTST_EXPECT_LIBNM_WARNING("DATA_VAL= not preceded by DATA_KEY=")); + + _do_read_vpn_details( + "" + "DATA_KEY=some-key\n" + "DATA_VAL=string\n" + "=continued after a line break\n" + "SECRET_KEY=key names\n" + "=can have\n" + "=continuations too\n" + "SECRET_VAL=value\n" + "", + READ_VPN_DETAIL_DATA({"some-key", "string\ncontinued after a line break"}, ), + READ_VPN_DETAIL_DATA({"key names\ncan have\ncontinuations too", "value"}, ), ); + + _do_read_vpn_details( + "" + "DATA_KEY=some-key\n" + "DATA_VAL=string\n" + "\n" + "DATA_KEY=some\n" + "=key-2\n" + "DATA_VAL=val2\n" + "\n" + "DATA_KEY=key3\0" + "=key-2\n" + "DATA_VAL=val3\n" + "\n" + "SECRET_KEY=some-secret\n" + "SECRET_VAL=val3\n" + "\n" + "SECRET_KEY=\n" + "SECRET_VAL=val3\n" + "\n" + "SECRET_KEY=keyx\n" + "SECRET_VAL=\n" + "\n" + "SECRET_KEY=ke\xc0yx\n" + "SECRET_VAL=inval\n" + "\n" + "SECRET_KEY=key-inval\n" + "SECRET_VAL=in\xc1val\n" + "\n" + "DONE\n" + "\n" + "", + READ_VPN_DETAIL_DATA({"some\nkey-2", "val2"}, {"some-key", "string"}, {"key3", "val3"}, ), + READ_VPN_DETAIL_DATA({"some-secret", "val3"}, + {"", "val3"}, + {"keyx", ""}, + {"ke\xc0yx", "inval"}, + {"key-inval", "in\xc1val"}, ), ); +} + +/*****************************************************************************/ + +static void +test_types(void) +{ +#define G(get_type_fcn) \ + ({ \ + GType get_type_fcn(void); \ + \ + get_type_fcn; \ + }) + GType (*get_type_fcns[])(void) = { + G(nm_802_11_ap_flags_get_type), + G(nm_802_11_ap_security_flags_get_type), + G(nm_802_11_mode_get_type), + G(nm_access_point_get_type), + G(nm_activation_state_flags_get_type), + G(nm_active_connection_get_type), + G(nm_active_connection_state_get_type), + G(nm_active_connection_state_reason_get_type), + G(nm_agent_manager_error_get_type), + G(nm_bluetooth_capabilities_get_type), + G(nm_bridge_vlan_get_type), + G(nm_capability_get_type), + G(nm_checkpoint_create_flags_get_type), + G(nm_checkpoint_get_type), + G(nm_client_error_get_type), + G(nm_client_get_type), + G(nm_client_permission_get_type), + G(nm_client_permission_result_get_type), + G(nm_connection_error_get_type), + G(nm_connection_get_type), + G(nm_connection_multi_connect_get_type), + G(nm_connection_serialization_flags_get_type), + G(nm_connectivity_state_get_type), + G(nm_crypto_error_get_type), + G(nm_device_6lowpan_get_type), + G(nm_device_adsl_get_type), + G(nm_device_bond_get_type), + G(nm_device_bridge_get_type), + G(nm_device_bt_get_type), + G(nm_device_capabilities_get_type), + G(nm_device_dummy_get_type), + G(nm_device_error_get_type), + G(nm_device_ethernet_get_type), + G(nm_device_generic_get_type), + G(nm_device_get_type), + G(nm_device_infiniband_get_type), + G(nm_device_ip_tunnel_get_type), + G(nm_device_macsec_get_type), + G(nm_device_macvlan_get_type), + G(nm_device_modem_capabilities_get_type), + G(nm_device_modem_get_type), + G(nm_device_olpc_mesh_get_type), + G(nm_device_ovs_bridge_get_type), + G(nm_device_ovs_interface_get_type), + G(nm_device_ovs_port_get_type), + G(nm_device_ppp_get_type), + G(nm_device_state_get_type), + G(nm_device_state_reason_get_type), + G(nm_device_team_get_type), + G(nm_device_tun_get_type), + G(nm_device_type_get_type), + G(nm_device_vlan_get_type), + G(nm_device_vxlan_get_type), + G(nm_device_wifi_capabilities_get_type), + G(nm_device_wifi_get_type), + G(nm_device_wifi_p2p_get_type), + G(nm_device_wimax_get_type), + G(nm_device_wireguard_get_type), + G(nm_device_wpan_get_type), + G(nm_dhcp4_config_get_type), + G(nm_dhcp6_config_get_type), + G(nm_dhcp_config_get_type), + G(nm_dns_entry_get_type), + G(nm_ip4_config_get_type), + G(nm_ip6_config_get_type), + G(nm_ip_address_get_type), + G(nm_ip_config_get_type), + G(nm_ip_route_get_type), + G(nm_ip_routing_rule_as_string_flags_get_type), + G(nm_ip_routing_rule_get_type), + G(nm_ip_tunnel_flags_get_type), + G(nm_ip_tunnel_mode_get_type), + G(nm_lldp_neighbor_get_type), + G(nm_manager_error_get_type), + G(nm_manager_reload_flags_get_type), + G(nm_metered_get_type), + G(nm_object_get_type), + G(nm_remote_connection_get_type), + G(nm_secret_agent_capabilities_get_type), + G(nm_secret_agent_error_get_type), + G(nm_secret_agent_get_secrets_flags_get_type), + G(nm_secret_agent_old_get_type), + G(nm_setting_6lowpan_get_type), + G(nm_setting_802_1x_auth_flags_get_type), + G(nm_setting_802_1x_ck_format_get_type), + G(nm_setting_802_1x_ck_scheme_get_type), + G(nm_setting_802_1x_get_type), + G(nm_setting_adsl_get_type), + G(nm_setting_bluetooth_get_type), + G(nm_setting_bond_get_type), + G(nm_setting_bridge_get_type), + G(nm_setting_bridge_port_get_type), + G(nm_setting_cdma_get_type), + G(nm_setting_compare_flags_get_type), + G(nm_setting_connection_autoconnect_slaves_get_type), + G(nm_setting_connection_get_type), + G(nm_setting_connection_lldp_get_type), + G(nm_setting_connection_llmnr_get_type), + G(nm_setting_connection_mdns_get_type), + G(nm_setting_dcb_flags_get_type), + G(nm_setting_dcb_get_type), + G(nm_setting_diff_result_get_type), + G(nm_setting_dummy_get_type), + G(nm_setting_ethtool_get_type), + G(nm_setting_generic_get_type), + G(nm_setting_get_type), + G(nm_setting_gsm_get_type), + G(nm_setting_infiniband_get_type), + G(nm_setting_ip4_config_get_type), + G(nm_setting_ip6_config_addr_gen_mode_get_type), + G(nm_setting_ip6_config_get_type), + G(nm_setting_ip6_config_privacy_get_type), + G(nm_setting_ip_config_get_type), + G(nm_setting_ip_tunnel_get_type), + G(nm_setting_mac_randomization_get_type), + G(nm_setting_macsec_get_type), + G(nm_setting_macsec_mode_get_type), + G(nm_setting_macsec_validation_get_type), + G(nm_setting_macvlan_get_type), + G(nm_setting_macvlan_mode_get_type), + G(nm_setting_match_get_type), + G(nm_setting_olpc_mesh_get_type), + G(nm_setting_ovs_bridge_get_type), + G(nm_setting_ovs_dpdk_get_type), + G(nm_setting_ovs_interface_get_type), + G(nm_setting_ovs_patch_get_type), + G(nm_setting_ovs_port_get_type), + G(nm_setting_ppp_get_type), + G(nm_setting_pppoe_get_type), + G(nm_setting_proxy_get_type), + G(nm_setting_proxy_method_get_type), + G(nm_settings_add_connection2_flags_get_type), + G(nm_settings_connection_flags_get_type), + G(nm_setting_secret_flags_get_type), + G(nm_setting_serial_get_type), + G(nm_setting_serial_parity_get_type), + G(nm_settings_error_get_type), + G(nm_setting_sriov_get_type), + G(nm_settings_update2_flags_get_type), + G(nm_setting_tc_config_get_type), + G(nm_setting_team_get_type), + G(nm_setting_team_port_get_type), + G(nm_setting_tun_get_type), + G(nm_setting_tun_mode_get_type), + G(nm_setting_user_get_type), + G(nm_setting_vlan_get_type), + G(nm_setting_vpn_get_type), + G(nm_setting_vxlan_get_type), + G(nm_setting_wifi_p2p_get_type), + G(nm_setting_wimax_get_type), + G(nm_setting_wired_get_type), + G(nm_setting_wired_wake_on_lan_get_type), + G(nm_setting_wireguard_get_type), + G(nm_setting_wireless_get_type), + G(nm_setting_wireless_powersave_get_type), + G(nm_setting_wireless_security_fils_get_type), + G(nm_setting_wireless_security_get_type), + G(nm_setting_wireless_security_pmf_get_type), + G(nm_setting_wireless_security_wps_method_get_type), + G(nm_setting_wireless_wake_on_wlan_get_type), + G(nm_setting_wpan_get_type), + G(nm_simple_connection_get_type), + G(nm_sriov_vf_get_type), + G(nm_sriov_vf_vlan_protocol_get_type), + G(nm_state_get_type), + G(nm_tc_action_get_type), + G(nm_tc_qdisc_get_type), + G(nm_tc_tfilter_get_type), + G(nm_team_link_watcher_arp_ping_flags_get_type), + G(nm_team_link_watcher_get_type), + G(nm_ternary_get_type), + G(nm_utils_security_type_get_type), + G(nm_vlan_flags_get_type), + G(nm_vlan_priority_map_get_type), + G(nm_vpn_connection_get_type), + G(nm_vpn_connection_state_get_type), + G(nm_vpn_connection_state_reason_get_type), + G(nm_vpn_editor_get_type), + G(nm_vpn_editor_plugin_capability_get_type), + G(nm_vpn_editor_plugin_get_type), + G(nm_vpn_plugin_error_get_type), + G(nm_vpn_plugin_failure_get_type), + G(nm_vpn_plugin_info_get_type), + G(nm_vpn_plugin_old_get_type), + G(nm_vpn_service_plugin_get_type), + G(nm_vpn_service_state_get_type), + G(nm_wep_key_type_get_type), + G(nm_wifi_p2p_peer_get_type), + G(nm_wimax_nsp_get_type), + G(nm_wimax_nsp_network_type_get_type), + G(nm_wireguard_peer_get_type), + }; + guint i_type; + + for (i_type = 0; i_type < G_N_ELEMENTS(get_type_fcns); i_type++) { + nm_auto_unref_gtypeclass GObjectClass *klass_unref = NULL; + GType gtype = (get_type_fcns[i_type])(); + GObjectClass * klass; + + g_assert(g_str_has_prefix(g_type_name(gtype), "NM")); + + if (G_TYPE_IS_INTERFACE(gtype)) { + if (!NM_IN_STRSET(g_type_name(gtype), + "NMConnection", + "NMVpnEditor", + "NMVpnEditorPlugin")) + g_error("unexpected interface type %s", g_type_name(gtype)); + continue; + } + + if (g_type_is_a(gtype, G_TYPE_BOXED)) + continue; + + /* We only test parts of the types, and avoid initializing all the types. + * That is so that other unit tests in this process randomly run with either + * the class instance already initialized or not. */ + if ((nmtst_get_rand_uint() % 5) == 0) { + klass = (klass_unref = g_type_class_ref(gtype)); + g_assert(klass); + } else { + klass = g_type_class_peek(gtype); + if (!klass) + continue; + } + + if (g_type_is_a(gtype, G_TYPE_ENUM)) + continue; + + if (g_type_is_a(gtype, G_TYPE_FLAGS)) + continue; + + g_assert(g_type_is_a(gtype, G_TYPE_OBJECT)); + g_assert(G_IS_OBJECT_CLASS(klass)); + } +} + +/*****************************************************************************/ + +static void +test_nml_dbus_meta(void) +{ + const NMLDBusMetaIface * meta_iface; + const NMLDBusMetaProperty *meta_property; + guint prop_idx; + gsize i, j; + guint l, m; + + for (i = 0; i < G_N_ELEMENTS(_nml_dbus_meta_ifaces); i++) { + const NMLDBusMetaIface * mif = _nml_dbus_meta_ifaces[i]; + nm_auto_unref_gtypeclass GObjectClass *klass_unref = NULL; + GObjectClass * klass; + GType gtype; + +#define COMMON_PREFIX "org.freedesktop.NetworkManager" + + g_assert(mif); + g_assert(mif->dbus_iface_name); + g_assert(g_str_has_prefix(mif->dbus_iface_name, COMMON_PREFIX) + && !g_str_has_suffix(mif->dbus_iface_name, ".") + && NM_IN_SET(mif->dbus_iface_name[NM_STRLEN(COMMON_PREFIX)], '\0', '.')); + for (j = i + 1; j < G_N_ELEMENTS(_nml_dbus_meta_ifaces); j++) + g_assert(mif != _nml_dbus_meta_ifaces[j]); + if (i > 0) { + if (strcmp(_nml_dbus_meta_ifaces[i - 1]->dbus_iface_name, mif->dbus_iface_name) >= 0) { + g_error("meta-ifaces are not properly sorted: [%zu] \"%s\" should be after [%zu] " + "\"%s\"", + i - 1, + _nml_dbus_meta_ifaces[i - 1]->dbus_iface_name, + i, + mif->dbus_iface_name); + } + } + + g_assert((mif->n_dbus_properties > 0) == (!!mif->dbus_properties)); + + if (mif->interface_prio == NML_DBUS_META_INTERFACE_PRIO_NONE) { + g_assert(!mif->get_type_fcn); + g_assert(!mif->obj_properties); + g_assert(mif->n_obj_properties == 0); + g_assert(!mif->obj_properties_reverse_idx); + if (!NM_IN_STRSET(mif->dbus_iface_name, + NM_DBUS_INTERFACE_AGENT_MANAGER, + NM_DBUS_INTERFACE_DEVICE_STATISTICS, + NM_DBUS_INTERFACE_DEVICE_VETH)) + g_error("D-Bus interface \"%s\" is unexpectedly empty", mif->dbus_iface_name); + if (mif->n_dbus_properties == 0) + continue; + gtype = G_TYPE_NONE; + klass = NULL; + goto check_dbus_properties; + } + + g_assert(NM_IN_SET((NMLDBusMetaInteracePrio) mif->interface_prio, + NML_DBUS_META_INTERFACE_PRIO_NMCLIENT, + NML_DBUS_META_INTERFACE_PRIO_PARENT_TYPE, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_10, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_20, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30)); + + g_assert(mif->get_type_fcn); + gtype = mif->get_type_fcn(); + g_assert(g_type_is_a(gtype, G_TYPE_OBJECT)); + + if (mif->interface_prio == NML_DBUS_META_INTERFACE_PRIO_NMCLIENT) + g_assert(gtype == NM_TYPE_CLIENT); + else + g_assert(g_type_is_a(gtype, NM_TYPE_OBJECT)); + + /* We only test parts of the types, and avoid initializing all the types. + * That is so that other unit tests in this process randomly run with either + * the class instance already initialized or not. */ + if ((nmtst_get_rand_uint() % 5) == 0) { + klass = (klass_unref = g_type_class_ref(gtype)); + g_assert(klass); + } else + klass = g_type_class_peek(gtype); + + if (klass) { + if (NM_IS_OBJECT_CLASS(klass)) { + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + + if (nm_object_class->property_o_info || nm_object_class->property_ao_info) { + int ii; + + for (ii = 0; ii < 2; ii++) { + const _NMObjectClassFieldInfo *p_prev = NULL; + const _NMObjectClassFieldInfo *p0 = ii == 0 + ? nm_object_class->property_o_info + : nm_object_class->property_ao_info; + const _NMObjectClassFieldInfo *p; + + for (p = p0; p; p = p->parent) { + GType parent_gtype; + NMObjectClass *parent_klass; + + g_assert(p->num > 0); + g_assert(NM_IS_OBJECT_CLASS(p->klass)); + g_assert(g_type_is_a(gtype, G_TYPE_FROM_CLASS(p->klass))); + if (ii == 0) + g_assert(p->klass->property_o_info == p); + else + g_assert(p->klass->property_ao_info == p); + g_assert_cmpint(p->klass->priv_ptr_offset, >, 0); + if (p_prev) { + g_assert(g_type_is_a(G_TYPE_FROM_CLASS(p_prev->klass), + G_TYPE_FROM_CLASS(p->klass))); + g_assert(p_prev->klass != p->klass); + g_assert_cmpint(p_prev->klass->priv_ptr_offset, + >, + p->klass->priv_ptr_offset); + g_assert_cmpint(p->klass->priv_ptr_indirect, ==, TRUE); + } + + parent_gtype = g_type_parent(G_TYPE_FROM_CLASS(p->klass)); + g_assert(g_type_is_a(parent_gtype, NM_TYPE_OBJECT)); + parent_klass = g_type_class_peek(parent_gtype); + g_assert(NM_IS_OBJECT_CLASS(parent_klass)); + if (parent_gtype == NM_TYPE_OBJECT) { + g_assert_cmpint(parent_klass->priv_ptr_offset, ==, 0); + g_assert_cmpint(parent_klass->priv_ptr_indirect, ==, FALSE); + g_assert(!p->parent); + } else { + if (parent_klass->priv_ptr_offset == 0) { + g_assert(!parent_klass->property_o_info); + g_assert(!parent_klass->property_ao_info); + g_assert_cmpint(parent_klass->priv_ptr_indirect, ==, FALSE); + g_assert(!p->parent); + } else if (p->klass->priv_ptr_offset + == parent_klass->priv_ptr_offset) { + g_assert(p->klass->property_o_info + == parent_klass->property_o_info); + g_assert(p->klass->property_ao_info + == parent_klass->property_ao_info); + g_assert(p->klass->priv_ptr_indirect + == parent_klass->priv_ptr_indirect); + } else { + g_assert_cmpint(parent_klass->priv_ptr_offset, >, 0); + g_assert_cmpint(parent_klass->priv_ptr_offset, + <, + p->klass->priv_ptr_offset); + g_assert_cmpint(parent_klass->priv_ptr_indirect, ==, TRUE); + g_assert(p->klass->property_o_info + != parent_klass->property_o_info + || p->klass->property_ao_info + != parent_klass->property_ao_info); + } + } + + p_prev = p; + } + } + + g_assert_cmpint(nm_object_class->priv_ptr_offset, >, 0); + } else { + g_assert_cmpint(nm_object_class->priv_ptr_offset, ==, 0); + g_assert_cmpint(nm_object_class->priv_ptr_indirect, ==, FALSE); + } + + } else + g_assert(NM_IS_CLIENT_CLASS(klass)); + } + + if (!mif->obj_properties) { + g_assert_cmpint(mif->n_obj_properties, ==, 0); + g_assert(!mif->obj_properties_reverse_idx); + } else { + g_assert(mif->obj_properties); + g_assert(mif->obj_properties[0] == 0); + g_assert_cmpint(mif->n_obj_properties, >, 1); + if (klass) { + for (l = 1; l < mif->n_obj_properties; l++) { + const GParamSpec *sp = mif->obj_properties[l]; + + g_assert(sp); + g_assert(sp->name); + g_assert(strlen(sp->name) > 0); + } + } + + g_assert(mif->obj_properties_reverse_idx); + if (klass) { + g_assert(mif->obj_properties_reverse_idx[0] == 0xFFu); + for (l = 0; l < mif->n_obj_properties; l++) { + guint8 ridx = mif->obj_properties_reverse_idx[l]; + + if (ridx != 0xFFu) { + g_assert_cmpint(ridx, <=, mif->n_dbus_properties); + for (m = l + 1; m < mif->n_obj_properties; m++) + g_assert_cmpint(ridx, !=, mif->obj_properties_reverse_idx[m]); + } + } + } + } + +check_dbus_properties: + for (l = 0; l < mif->n_dbus_properties; l++) { + const NMLDBusMetaProperty *mpr = &mif->dbus_properties[l]; + gs_free char * obj_property_name = NULL; + const struct { + const char *dbus_type; + GType default_gtype; + } * p_expected_type, *p_expected_type_2, + expected_types[] = { + {"b", G_TYPE_BOOLEAN}, {"q", G_TYPE_UINT}, + {"y", G_TYPE_UCHAR}, {"i", G_TYPE_INT}, + {"u", G_TYPE_UINT}, {"x", G_TYPE_INT64}, + {"t", G_TYPE_UINT64}, {"s", G_TYPE_STRING}, + {"o", G_TYPE_STRING}, {"ay", G_TYPE_BYTES}, + {"as", G_TYPE_STRV}, {"ao", G_TYPE_PTR_ARRAY}, + {"a{sv}", G_TYPE_HASH_TABLE}, {"aa{sv}", G_TYPE_PTR_ARRAY}, + + {"(uu)", G_TYPE_NONE}, {"aau", G_TYPE_NONE}, + {"au", G_TYPE_NONE}, {"a(ayuay)", G_TYPE_NONE}, + {"aay", G_TYPE_NONE}, {"a(ayuayu)", G_TYPE_NONE}, + + {"u", G_TYPE_FLAGS}, {"u", G_TYPE_ENUM}, + {"o", NM_TYPE_OBJECT}, + }; + const GParamSpec *pspec = NULL; + + g_assert(mpr->dbus_property_name); + g_assert(g_variant_type_string_is_valid((const char *) mpr->dbus_type)); + if (l > 0) { + if (strcmp(mif->dbus_properties[l - 1].dbus_property_name, mpr->dbus_property_name) + >= 0) { + g_error("meta-ifaces[%s] must have property #%u \"%s\" after #%u \"%s\"", + mif->dbus_iface_name, + l - 1, + mif->dbus_properties[l - 1].dbus_property_name, + l, + mpr->dbus_property_name); + } + } + + obj_property_name = nm_utils_wincaps_to_dash(mpr->dbus_property_name); + g_assert(obj_property_name); + + for (p_expected_type = &expected_types[0]; TRUE;) { + if (nm_streq((const char *) mpr->dbus_type, p_expected_type->dbus_type)) + break; + p_expected_type++; + if (p_expected_type >= &expected_types[G_N_ELEMENTS(expected_types)]) { + g_error("D-Bus type \"%s\" is not implemented (in property %s.%s)", + (const char *) mpr->dbus_type, + mif->dbus_iface_name, + mpr->dbus_property_name); + } + } + + if (klass && mpr->obj_properties_idx > 0) { + g_assert_cmpint(mpr->obj_properties_idx, <, mif->n_obj_properties); + if (!mpr->obj_property_no_reverse_idx) + g_assert_cmpint(mif->obj_properties_reverse_idx[mpr->obj_properties_idx], + ==, + l); + else { + g_assert_cmpint(mif->obj_properties_reverse_idx[mpr->obj_properties_idx], + !=, + l); + g_assert_cmpint(mif->obj_properties_reverse_idx[mpr->obj_properties_idx], + !=, + 0xFFu); + } + pspec = mif->obj_properties[mpr->obj_properties_idx]; + } + + if (mpr->use_notify_update_prop) { + g_assert(mpr->notify_update_prop); + } else { + if (klass) + g_assert(pspec); + } + + if (pspec) { + const char *expected_property_name; + + if (mif == &_nml_dbus_meta_iface_nm_connection_active + && nm_streq(pspec->name, NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT_PATH)) { + g_assert_cmpstr(obj_property_name, ==, "specific-object"); + expected_property_name = NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT_PATH; + } else if (mif == &_nml_dbus_meta_iface_nm_accesspoint + && nm_streq(pspec->name, NM_ACCESS_POINT_BSSID)) { + g_assert_cmpstr(obj_property_name, ==, "hw-address"); + expected_property_name = NM_ACCESS_POINT_BSSID; + } else if (mif == &_nml_dbus_meta_iface_nm_device_wireguard + && nm_streq(pspec->name, NM_DEVICE_WIREGUARD_FWMARK)) { + g_assert_cmpstr(obj_property_name, ==, "fw-mark"); + expected_property_name = NM_DEVICE_WIREGUARD_FWMARK; + } else if (NM_IN_SET(mif, + &_nml_dbus_meta_iface_nm_ip4config, + &_nml_dbus_meta_iface_nm_ip6config) + && nm_streq(pspec->name, NM_IP_CONFIG_ADDRESSES)) { + g_assert(NM_IN_STRSET(obj_property_name, "addresses", "address-data")); + expected_property_name = NM_IP_CONFIG_ADDRESSES; + } else if (NM_IN_SET(mif, + &_nml_dbus_meta_iface_nm_ip4config, + &_nml_dbus_meta_iface_nm_ip6config) + && nm_streq(pspec->name, NM_IP_CONFIG_ROUTES)) { + g_assert(NM_IN_STRSET(obj_property_name, "routes", "route-data")); + expected_property_name = NM_IP_CONFIG_ROUTES; + } else if (NM_IN_SET(mif, + &_nml_dbus_meta_iface_nm_ip4config, + &_nml_dbus_meta_iface_nm_ip6config) + && nm_streq(pspec->name, NM_IP_CONFIG_NAMESERVERS)) { + g_assert(NM_IN_STRSET(obj_property_name, "nameservers", "nameserver-data")); + expected_property_name = NM_IP_CONFIG_NAMESERVERS; + } else if (mif == &_nml_dbus_meta_iface_nm_ip4config + && nm_streq(pspec->name, NM_IP_CONFIG_WINS_SERVERS)) { + g_assert(NM_IN_STRSET(obj_property_name, "wins-servers", "wins-server-data")); + expected_property_name = NM_IP_CONFIG_WINS_SERVERS; + } else if (mif == &_nml_dbus_meta_iface_nm_dnsmanager + && nm_streq(pspec->name, NM_CLIENT_DNS_CONFIGURATION)) { + g_assert_cmpstr(obj_property_name, ==, "configuration"); + expected_property_name = NM_CLIENT_DNS_CONFIGURATION; + } else if (mif == &_nml_dbus_meta_iface_nm_dnsmanager + && nm_streq(pspec->name, NM_CLIENT_DNS_MODE)) { + g_assert_cmpstr(obj_property_name, ==, "mode"); + expected_property_name = NM_CLIENT_DNS_MODE; + } else if (mif == &_nml_dbus_meta_iface_nm_dnsmanager + && nm_streq(pspec->name, NM_CLIENT_DNS_RC_MANAGER)) { + g_assert_cmpstr(obj_property_name, ==, "rc-manager"); + expected_property_name = NM_CLIENT_DNS_RC_MANAGER; + } else + expected_property_name = obj_property_name; + + g_assert_cmpstr(expected_property_name, ==, pspec->name); + + if (!mpr->use_notify_update_prop) { + for (p_expected_type_2 = &expected_types[0]; + p_expected_type_2 < &expected_types[G_N_ELEMENTS(expected_types)]; + p_expected_type_2++) { + if (!nm_streq((const char *) mpr->dbus_type, p_expected_type_2->dbus_type)) + continue; + if (pspec->value_type == p_expected_type_2->default_gtype + || (p_expected_type_2->default_gtype == G_TYPE_ENUM + && g_type_is_a(pspec->value_type, G_TYPE_ENUM)) + || (p_expected_type_2->default_gtype == G_TYPE_FLAGS + && g_type_is_a(pspec->value_type, G_TYPE_FLAGS)) + || (p_expected_type_2->default_gtype == NM_TYPE_OBJECT + && nm_streq((const char *) mpr->dbus_type, "o") + && g_type_is_a(pspec->value_type, NM_TYPE_OBJECT))) + break; + } + if (p_expected_type_2 >= &expected_types[G_N_ELEMENTS(expected_types)]) { + g_error("D-Bus property \"%s.%s\" (type \"%s\") maps to property \"%s\", " + "but that has an unexpected property type %s (expected %s)", + mif->dbus_iface_name, + mpr->dbus_property_name, + (const char *) mpr->dbus_type, + pspec->name, + g_type_name(pspec->value_type), + g_type_name(p_expected_type->default_gtype)); + } + } + + if (!nm_utils_g_param_spec_is_default(pspec)) { + /* We expect our properties to have a default value of zero/NULL. + * Except those whitelisted here: */ + if ((mif == &_nml_dbus_meta_iface_nm_accesspoint + && nm_streq(pspec->name, NM_ACCESS_POINT_LAST_SEEN)) + || (mif == &_nml_dbus_meta_iface_nm_device_vxlan + && nm_streq(pspec->name, NM_DEVICE_VXLAN_LEARNING)) + || (mif == &_nml_dbus_meta_iface_nm_device_wireless + && nm_streq(pspec->name, NM_DEVICE_WIFI_LAST_SCAN)) + || (mif == &_nml_dbus_meta_iface_nm_wifip2ppeer + && nm_streq(pspec->name, NM_WIFI_P2P_PEER_LAST_SEEN)) + || (mif == &_nml_dbus_meta_iface_nm_device_tun + && NM_IN_STRSET(pspec->name, + NM_DEVICE_TUN_GROUP, + NM_DEVICE_TUN_OWNER))) { + /* pass */ + } else { + g_error("property %s.%s (%s.%s) does not have a default value of zero", + mif->dbus_iface_name, + mpr->dbus_property_name, + g_type_name(gtype), + pspec->name); + } + } + } + } + + if (klass) { + for (l = 0; l < mif->n_obj_properties; l++) { + guint8 ridx = mif->obj_properties_reverse_idx[l]; + + if (ridx != 0xFFu) + g_assert_cmpint(mif->dbus_properties[ridx].obj_properties_idx, ==, l); + } + } + + g_assert(mif == nml_dbus_meta_iface_get(mif->dbus_iface_name)); + } + + meta_iface = nml_dbus_meta_iface_get(NM_DBUS_INTERFACE); + g_assert(meta_iface); + g_assert(meta_iface == &_nml_dbus_meta_iface_nm); + g_assert_cmpstr(meta_iface->dbus_iface_name, ==, NM_DBUS_INTERFACE); + + meta_property = nml_dbus_meta_property_get(meta_iface, "Version", &prop_idx); + g_assert(meta_property); + g_assert_cmpstr(meta_property->dbus_property_name, ==, "Version"); + g_assert(&meta_iface->dbus_properties[prop_idx] == meta_property); +} + +/*****************************************************************************/ + +static void +test_dbus_meta_types(void) +{ + struct list_data { + const char * dbus_iface_name; + GType gtype; + NMLDBusMetaInteracePrio interface_prio; + } list[] = { + { + NM_DBUS_INTERFACE, + NM_TYPE_CLIENT, + NML_DBUS_META_INTERFACE_PRIO_NMCLIENT, + }, + { + NM_DBUS_INTERFACE_ACCESS_POINT, + NM_TYPE_ACCESS_POINT, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + NM_TYPE_ACTIVE_CONNECTION, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_10, + }, /* otherwise, NM_TYPE_VPN_CONNECTION. */ + { + NM_DBUS_INTERFACE_DEVICE_6LOWPAN, + NM_TYPE_DEVICE_6LOWPAN, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_ADSL, + NM_TYPE_DEVICE_ADSL, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_BOND, + NM_TYPE_DEVICE_BOND, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_BRIDGE, + NM_TYPE_DEVICE_BRIDGE, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, + NM_TYPE_DEVICE_BT, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_DUMMY, + NM_TYPE_DEVICE_DUMMY, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_WIRED, + NM_TYPE_DEVICE_ETHERNET, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_20, + }, + { + NM_DBUS_INTERFACE_DEVICE_VETH, + NM_TYPE_DEVICE_VETH, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_GENERIC, + NM_TYPE_DEVICE_GENERIC, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_INFINIBAND, + NM_TYPE_DEVICE_INFINIBAND, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL, + NM_TYPE_DEVICE_IP_TUNNEL, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_MACSEC, + NM_TYPE_DEVICE_MACSEC, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_MACVLAN, + NM_TYPE_DEVICE_MACVLAN, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_MODEM, + NM_TYPE_DEVICE_MODEM, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_OLPC_MESH, + NM_TYPE_DEVICE_OLPC_MESH, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE, + NM_TYPE_DEVICE_OVS_INTERFACE, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_OVS_PORT, + NM_TYPE_DEVICE_OVS_PORT, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE, + NM_TYPE_DEVICE_OVS_BRIDGE, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_WIFI_P2P, + NM_TYPE_DEVICE_WIFI_P2P, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_PPP, + NM_TYPE_DEVICE_PPP, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_TEAM, + NM_TYPE_DEVICE_TEAM, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_TUN, + NM_TYPE_DEVICE_TUN, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_VLAN, + NM_TYPE_DEVICE_VLAN, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_WPAN, + NM_TYPE_DEVICE_WPAN, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_VXLAN, + NM_TYPE_DEVICE_VXLAN, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + NM_TYPE_DEVICE_WIFI, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DEVICE_WIREGUARD, + NM_TYPE_DEVICE_WIREGUARD, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DHCP4_CONFIG, + NM_TYPE_DHCP4_CONFIG, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_DHCP6_CONFIG, + NM_TYPE_DHCP6_CONFIG, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_IP4_CONFIG, + NM_TYPE_IP4_CONFIG, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_IP6_CONFIG, + NM_TYPE_IP6_CONFIG, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_WIFI_P2P_PEER, + NM_TYPE_WIFI_P2P_PEER, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NM_TYPE_REMOTE_CONNECTION, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_SETTINGS, + NM_TYPE_CLIENT, + NML_DBUS_META_INTERFACE_PRIO_NMCLIENT, + }, + { + NM_DBUS_INTERFACE_DNS_MANAGER, + NM_TYPE_CLIENT, + NML_DBUS_META_INTERFACE_PRIO_NMCLIENT, + }, + { + NM_DBUS_INTERFACE_VPN_CONNECTION, + NM_TYPE_VPN_CONNECTION, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { + NM_DBUS_INTERFACE_CHECKPOINT, + NM_TYPE_CHECKPOINT, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + }; + guint i; + + /* These iface<->gtype associations are copied from "nm-client.c"'s obj_nm_for_gdbus_object(). + * This is redundant to the meta-data, still check that the meta data matches. */ + for (i = 0; i < G_N_ELEMENTS(list); i++) { + const struct list_data *d = &list[i]; + const NMLDBusMetaIface *meta_iface; + + meta_iface = nml_dbus_meta_iface_get(d->dbus_iface_name); + g_assert(meta_iface); + g_assert_cmpint(meta_iface->interface_prio, ==, d->interface_prio); + g_assert(meta_iface->get_type_fcn() == d->gtype); + } +} + +/*****************************************************************************/ + +static void +test_nm_auth_permissions(void) +{ + int i, j; + + G_STATIC_ASSERT(G_N_ELEMENTS(nm_auth_permission_names_by_idx) == NM_CLIENT_PERMISSION_LAST); + G_STATIC_ASSERT(G_N_ELEMENTS(nm_auth_permission_sorted) == NM_CLIENT_PERMISSION_LAST); + + for (i = 0; i < NM_CLIENT_PERMISSION_LAST; i++) { + g_assert(nm_auth_permission_names_by_idx[i]); + g_assert(NM_STR_HAS_PREFIX(nm_auth_permission_names_by_idx[i], + "org.freedesktop.NetworkManager.")); + g_assert_cmpint(nm_auth_permission_sorted[i], >, 0); + g_assert_cmpint(nm_auth_permission_sorted[i], <=, NM_CLIENT_PERMISSION_LAST); + for (j = i + 1; j < NM_CLIENT_PERMISSION_LAST; j++) { + g_assert_cmpint(nm_auth_permission_sorted[i], !=, nm_auth_permission_sorted[j]); + g_assert_cmpstr(nm_auth_permission_names_by_idx[i], + !=, + nm_auth_permission_names_by_idx[j]); + } + } + for (i = 1; i < NM_CLIENT_PERMISSION_LAST; i++) { + NMClientPermission a = nm_auth_permission_sorted[i - 1]; + NMClientPermission b = nm_auth_permission_sorted[i]; + const char * s_a = nm_auth_permission_names_by_idx[a - 1]; + const char * s_b = nm_auth_permission_names_by_idx[b - 1]; + + g_assert_cmpstr(s_a, <, s_b); + g_assert(a != b); + g_assert(s_a != s_b); + } + for (i = 1; i <= NM_CLIENT_PERMISSION_LAST; i++) { + const char *s = nm_auth_permission_to_string(i); + + g_assert_cmpstr(s, ==, nm_auth_permission_names_by_idx[i - 1]); + g_assert(s == nm_auth_permission_names_by_idx[i - 1]); + g_assert_cmpint(nm_auth_permission_from_string(s), ==, i); + } + + for (i = 0; i < NM_CLIENT_PERMISSION_LAST; i++) + g_assert_cmpint(nm_auth_permission_from_string(nm_auth_permission_names_by_idx[i]), + ==, + i + 1); +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_func("/libnm/general/fixup_product_string", test_fixup_product_string); + g_test_add_func("/libnm/general/fixup_vendor_string", test_fixup_vendor_string); + g_test_add_func("/libnm/general/nm_vpn_service_plugin_read_vpn_details", + test_nm_vpn_service_plugin_read_vpn_details); + g_test_add_func("/libnm/general/test_types", test_types); + g_test_add_func("/libnm/general/test_nml_dbus_meta", test_nml_dbus_meta); + g_test_add_func("/libnm/general/test_dbus_meta_types", test_dbus_meta_types); + g_test_add_func("/libnm/general/test_nm_auth_permissions", test_nm_auth_permissions); + + return g_test_run(); +} diff --git a/src/libnm-client-impl/tests/test-nm-client.c b/src/libnm-client-impl/tests/test-nm-client.c new file mode 100644 index 0000000..55b886a --- /dev/null +++ b/src/libnm-client-impl/tests/test-nm-client.c @@ -0,0 +1,1300 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2010 - 2014 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include +#include + +#include "libnm-client-test/nm-test-libnm-utils.h" + +static struct { + GMainLoop *loop; +} gl = {}; + +/*****************************************************************************/ + +static gboolean +loop_quit(gpointer user_data) +{ + g_main_loop_quit((GMainLoop *) user_data); + return G_SOURCE_REMOVE; +} + +/*****************************************************************************/ + +static void +devices_notify_cb(NMClient *c, GParamSpec *pspec, gpointer user_data) +{ + gboolean * notified = user_data; + const GPtrArray *devices; + NMDevice * device; + + devices = nm_client_get_devices(c); + g_assert(devices); + g_assert_cmpint(devices->len, ==, 1); + + device = g_ptr_array_index(devices, 0); + g_assert(device); + g_assert_cmpstr(nm_device_get_iface(device), ==, "eth0"); + + *notified = TRUE; +} + +static void +test_device_added(void) +{ + nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL; + gs_unref_object NMClient *client = NULL; + const GPtrArray * devices; + NMDevice * device; + gboolean notified = FALSE; + GError * error = NULL; + + sinfo = nmtstc_service_init(); + if (!nmtstc_service_available(sinfo)) + return; + + client = nmtstc_client_new(TRUE); + + devices = nm_client_get_devices(client); + g_assert(devices->len == 0); + + g_signal_connect(client, "notify::devices", (GCallback) devices_notify_cb, ¬ified); + + /* Tell the test service to add a new device */ + nmtstc_service_add_device(sinfo, client, "AddWiredDevice", "eth0"); + + /* coverity[loop_condition] */ + while (!notified) + g_main_context_iteration(NULL, TRUE); + + g_signal_handlers_disconnect_by_func(client, devices_notify_cb, ¬ified); + + devices = nm_client_get_devices(client); + g_assert(devices); + g_assert_cmpint(devices->len, ==, 1); + + device = g_ptr_array_index(devices, 0); + g_assert(device); + g_assert_cmpstr(nm_device_get_iface(device), ==, "eth0"); + + /* Try deleting the device via the ordinary NM interface, which should fail */ + nm_device_delete(device, NULL, &error); + g_assert_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_SOFTWARE); + g_clear_error(&error); +} + +/*****************************************************************************/ + +typedef enum { + SIGNAL_FIRST = 0x01, + SIGNAL_SECOND = 0x02, + SIGNAL_MASK = 0x0F, + NOTIFY_FIRST = 0x10, + NOTIFY_SECOND = 0x20, + NOTIFY_MASK = 0xF0 +} DeviceSignaledAfterInitType; + +static void +device_sai_added_cb(NMClient *c, NMDevice *device, gpointer user_data) +{ + guint *result = user_data; + + g_assert(device); + g_assert_cmpstr(nm_device_get_iface(device), ==, "eth0"); + + g_assert((*result & SIGNAL_MASK) == 0); + *result |= *result ? SIGNAL_SECOND : SIGNAL_FIRST; +} + +static void +devices_sai_notify_cb(NMClient *c, GParamSpec *pspec, gpointer user_data) +{ + guint * result = user_data; + const GPtrArray *devices; + NMDevice * device; + + g_assert_cmpstr(pspec->name, ==, "devices"); + + devices = nm_client_get_devices(c); + g_assert(devices); + g_assert_cmpint(devices->len, ==, 1); + + device = g_ptr_array_index(devices, 0); + g_assert(device); + g_assert_cmpstr(nm_device_get_iface(device), ==, "eth0"); + + g_assert((*result & NOTIFY_MASK) == 0); + *result |= *result ? NOTIFY_SECOND : NOTIFY_FIRST; +} + +static void +test_device_added_signal_after_init(void) +{ + nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL; + gs_unref_object NMClient *client = NULL; + const GPtrArray * devices; + NMDevice * device; + guint result = 0; + + sinfo = nmtstc_service_init(); + if (!nmtstc_service_available(sinfo)) + return; + + client = nmtstc_client_new(TRUE); + + devices = nm_client_get_devices(client); + g_assert(devices->len == 0); + + g_signal_connect(client, NM_CLIENT_DEVICE_ADDED, (GCallback) device_sai_added_cb, &result); + + g_signal_connect(client, + "notify::" NM_CLIENT_DEVICES, + (GCallback) devices_sai_notify_cb, + &result); + + /* Tell the test service to add a new device */ + nmtstc_service_add_device(sinfo, client, "AddWiredDevice", "eth0"); + + /* Ensure the 'device-added' signal doesn't show up before + * the 'Devices' property change notification */ + /* coverity[loop_condition] */ + while (!(result & SIGNAL_MASK) && !(result & NOTIFY_MASK)) + g_main_context_iteration(NULL, TRUE); + + g_signal_handlers_disconnect_by_func(client, device_sai_added_cb, &result); + g_signal_handlers_disconnect_by_func(client, devices_sai_notify_cb, &result); + + g_assert((result & SIGNAL_MASK) == SIGNAL_SECOND); + g_assert((result & NOTIFY_MASK) == NOTIFY_FIRST); + + devices = nm_client_get_devices(client); + g_assert(devices); + g_assert_cmpint(devices->len, ==, 1); + + device = g_ptr_array_index(devices, 0); + g_assert(device); + g_assert_cmpstr(nm_device_get_iface(device), ==, "eth0"); +} + +/*****************************************************************************/ + +static const char *expected_bssid = "66:55:44:33:22:11"; + +typedef struct { + GMainLoop *loop; + gboolean found; + char * ap_path; + gboolean signaled; + gboolean notified; + guint quit_id; + guint quit_count; +} WifiApInfo; + +static void +wifi_check_quit(WifiApInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove(info->quit_id); + info->quit_id = 0; + g_main_loop_quit(info->loop); + } +} + +static void +got_ap_path(WifiApInfo *info, const char *path) +{ + if (info->ap_path) + g_assert_cmpstr(info->ap_path, ==, path); + else + info->ap_path = g_strdup(path); +} + +static void +wifi_ap_added_cb(NMDeviceWifi *w, NMAccessPoint *ap, WifiApInfo *info) +{ + g_assert(ap); + g_assert_cmpstr(nm_access_point_get_bssid(ap), ==, expected_bssid); + got_ap_path(info, nm_object_get_path(NM_OBJECT(ap))); + + info->signaled = TRUE; + wifi_check_quit(info); +} + +static void +wifi_ap_add_notify_cb(NMDeviceWifi *w, GParamSpec *pspec, WifiApInfo *info) +{ + const GPtrArray *aps; + NMAccessPoint * ap; + + aps = nm_device_wifi_get_access_points(w); + g_assert(aps); + g_assert_cmpint(aps->len, ==, 1); + + ap = g_ptr_array_index(aps, 0); + g_assert(ap); + g_assert_cmpstr(nm_access_point_get_bssid(ap), ==, "66:55:44:33:22:11"); + got_ap_path(info, nm_object_get_path(NM_OBJECT(ap))); + + info->notified = TRUE; + wifi_check_quit(info); +} + +static void +wifi_ap_removed_cb(NMDeviceWifi *w, NMAccessPoint *ap, WifiApInfo *info) +{ + g_assert(ap); + g_assert_cmpstr(info->ap_path, ==, nm_object_get_path(NM_OBJECT(ap))); + + info->signaled = TRUE; + wifi_check_quit(info); +} + +static void +wifi_ap_remove_notify_cb(NMDeviceWifi *w, GParamSpec *pspec, WifiApInfo *info) +{ + const GPtrArray *aps; + + aps = nm_device_wifi_get_access_points(w); + g_assert(aps->len == 0); + + info->notified = TRUE; + wifi_check_quit(info); +} + +static void +test_wifi_ap_added_removed(void) +{ + nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL; + gs_unref_object NMClient *client = NULL; + NMDeviceWifi * wifi; + WifiApInfo info = {gl.loop, FALSE, FALSE, 0, 0}; + GVariant * ret; + GError * error = NULL; + gs_free char * expected_path = NULL; + + sinfo = nmtstc_service_init(); + if (!nmtstc_service_available(sinfo)) + return; + + client = nmtstc_client_new(TRUE); + + /*************************************/ + /* Add the wifi device */ + wifi = (NMDeviceWifi *) nmtstc_service_add_device(sinfo, client, "AddWifiDevice", "wlan0"); + g_assert(NM_IS_DEVICE_WIFI(wifi)); + + /*************************************/ + /* Add the wifi AP */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + ret = g_dbus_proxy_call_sync(sinfo->proxy, + "AddWifiAp", + g_variant_new("(sss)", "wlan0", "test-ap", expected_bssid), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error(error); + g_assert(ret); + g_assert_cmpstr(g_variant_get_type_string(ret), ==, "(o)"); + g_variant_get(ret, "(o)", &expected_path); + g_variant_unref(ret); + + g_signal_connect(wifi, "access-point-added", (GCallback) wifi_ap_added_cb, &info); + info.quit_count = 1; + + g_signal_connect(wifi, "notify::access-points", (GCallback) wifi_ap_add_notify_cb, &info); + info.quit_count++; + + /* Wait for libnm to find the AP */ + info.quit_id = g_timeout_add_seconds(5, loop_quit, gl.loop); + g_main_loop_run(gl.loop); + + g_assert(info.signaled); + g_assert(info.notified); + g_assert(info.ap_path); + g_assert_cmpstr(info.ap_path, ==, expected_path); + g_signal_handlers_disconnect_by_func(wifi, wifi_ap_added_cb, &info); + g_signal_handlers_disconnect_by_func(wifi, wifi_ap_add_notify_cb, &info); + + /*************************************/ + /* Remove the wifi device */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + ret = g_dbus_proxy_call_sync(sinfo->proxy, + "RemoveWifiAp", + g_variant_new("(so)", "wlan0", expected_path), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error(error); + nm_clear_pointer(&ret, g_variant_unref); + + g_signal_connect(wifi, "access-point-removed", (GCallback) wifi_ap_removed_cb, &info); + info.quit_count = 1; + + g_signal_connect(wifi, "notify::access-points", (GCallback) wifi_ap_remove_notify_cb, &info); + info.quit_count++; + + /* Wait for libnm to find the AP */ + info.quit_id = g_timeout_add_seconds(5, loop_quit, gl.loop); + g_main_loop_run(gl.loop); + + g_assert(info.signaled); + g_assert(info.notified); + g_signal_handlers_disconnect_by_func(wifi, wifi_ap_removed_cb, &info); + g_signal_handlers_disconnect_by_func(wifi, wifi_ap_remove_notify_cb, &info); + + g_free(info.ap_path); +} + +/*****************************************************************************/ + +typedef struct { + GMainLoop *loop; + gboolean signaled; + gboolean notified; + guint quit_count; + guint quit_id; +} DaInfo; + +static void +da_check_quit(DaInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove(info->quit_id); + info->quit_id = 0; + g_main_loop_quit(info->loop); + } +} + +static void +da_device_removed_cb(NMClient *c, NMDevice *device, DaInfo *info) +{ + g_assert_cmpstr(nm_device_get_iface(device), ==, "eth0"); + info->signaled = TRUE; + da_check_quit(info); +} + +static void +da_devices_notify_cb(NMClient *c, GParamSpec *pspec, DaInfo *info) +{ + const GPtrArray *devices; + NMDevice * device; + guint i; + const char * iface; + + devices = nm_client_get_devices(c); + g_assert(devices); + g_assert_cmpint(devices->len, ==, 2); + + for (i = 0; i < devices->len; i++) { + device = g_ptr_array_index(devices, i); + iface = nm_device_get_iface(device); + + g_assert(!strcmp(iface, "wlan0") || !strcmp(iface, "eth1")); + } + + info->notified = TRUE; + da_check_quit(info); +} + +static void +test_devices_array(void) +{ + nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL; + gs_unref_object NMClient *client = NULL; + DaInfo info = {gl.loop}; + NMDevice * wlan0, *eth0, *eth1, *device; + const GPtrArray * devices; + GError * error = NULL; + GVariant * ret; + + sinfo = nmtstc_service_init(); + if (!nmtstc_service_available(sinfo)) + return; + + client = nmtstc_client_new(TRUE); + + /*************************************/ + /* Add some devices */ + wlan0 = nmtstc_service_add_device(sinfo, client, "AddWifiDevice", "wlan0"); + eth0 = nmtstc_service_add_device(sinfo, client, "AddWiredDevice", "eth0"); + eth1 = nmtstc_service_add_device(sinfo, client, "AddWiredDevice", "eth1"); + + /* Ensure the devices now exist */ + devices = nm_client_get_devices(client); + g_assert(devices); + g_assert_cmpint(devices->len, ==, 3); + + device = nm_client_get_device_by_iface(client, "wlan0"); + g_assert(NM_IS_DEVICE_WIFI(device)); + g_assert(device == wlan0); + + device = nm_client_get_device_by_iface(client, "eth0"); + g_assert(NM_IS_DEVICE_ETHERNET(device)); + g_assert(device == eth0); + + device = nm_client_get_device_by_iface(client, "eth1"); + g_assert(NM_IS_DEVICE_ETHERNET(device)); + g_assert(device == eth1); + + /********************************/ + /* Now remove the device in the middle */ + ret = g_dbus_proxy_call_sync(sinfo->proxy, + "RemoveDevice", + g_variant_new("(o)", nm_object_get_path(NM_OBJECT(eth0))), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error(error); + g_assert(ret); + g_variant_unref(ret); + + g_signal_connect(client, "device-removed", (GCallback) da_device_removed_cb, &info); + + g_signal_connect(client, "notify::devices", (GCallback) da_devices_notify_cb, &info); + info.quit_count = 2; + + /* Wait for libnm to notice the changes */ + info.quit_id = g_timeout_add_seconds(5, loop_quit, gl.loop); + g_main_loop_run(gl.loop); + + g_assert_cmpint(info.quit_count, ==, 0); + g_signal_handlers_disconnect_by_func(client, da_device_removed_cb, &info); + g_signal_handlers_disconnect_by_func(client, da_devices_notify_cb, &info); + + /* Ensure only two are left */ + devices = nm_client_get_devices(client); + g_assert(devices); + g_assert_cmpint(devices->len, ==, 2); + + device = nm_client_get_device_by_iface(client, "wlan0"); + g_assert(NM_IS_DEVICE_WIFI(device)); + g_assert(device == wlan0); + + device = nm_client_get_device_by_iface(client, "eth1"); + g_assert(NM_IS_DEVICE_ETHERNET(device)); + g_assert(device == eth1); +} + +static void +nm_running_changed(GObject *client, GParamSpec *pspec, gpointer user_data) +{ + int *running_changed = user_data; + + (*running_changed)++; + g_main_loop_quit(gl.loop); +} + +static void +test_client_nm_running(void) +{ + nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL; + gs_unref_object NMClient *client1 = NULL; + gs_unref_object NMClient *client2 = NULL; + guint quit_id; + int running_changed = 0; + GError * error = NULL; + + client1 = nmtstc_client_new(TRUE); + + g_assert(!nm_client_get_nm_running(client1)); + g_assert_cmpstr(nm_client_get_version(client1), ==, NULL); + + g_assert(!nm_client_networking_get_enabled(client1)); + /* This will have no effect, but it shouldn't cause any warnings either. */ + nm_client_networking_set_enabled(client1, TRUE, NULL); + g_assert(!nm_client_networking_get_enabled(client1)); + + /* OTOH, this should result in an error */ + nm_client_set_logging(client1, "DEFAULT", "INFO", &error); + g_assert_error(error, NM_CLIENT_ERROR, NM_CLIENT_ERROR_MANAGER_NOT_RUNNING); + g_clear_error(&error); + + /* Now start the test service. */ + sinfo = nmtstc_service_init(); + if (!nmtstc_service_available(sinfo)) + return; + + client2 = nmtstc_client_new(FALSE); + + /* client2 should know that NM is running, but the previously-created + * client1 hasn't gotten the news yet. + */ + g_assert(!nm_client_get_nm_running(client1)); + g_assert(nm_client_get_nm_running(client2)); + + g_signal_connect(client1, + "notify::" NM_CLIENT_NM_RUNNING, + G_CALLBACK(nm_running_changed), + &running_changed); + quit_id = g_timeout_add_seconds(5, loop_quit, gl.loop); + g_main_loop_run(gl.loop); + g_assert_cmpint(running_changed, ==, 1); + g_assert(nm_client_get_nm_running(client1)); + g_source_remove(quit_id); + + /* And kill it */ + nm_clear_pointer(&sinfo, nmtstc_service_cleanup); + + g_assert(nm_client_get_nm_running(client1)); + + quit_id = g_timeout_add_seconds(5, loop_quit, gl.loop); + g_main_loop_run(gl.loop); + g_assert_cmpint(running_changed, ==, 2); + g_assert(!nm_client_get_nm_running(client1)); + g_source_remove(quit_id); +} + +typedef struct { + GMainLoop * loop; + NMActiveConnection *ac; + + int remaining; + + NMDevice *device; + gulong ac_signal_id; +} TestACInfo; + +static void +assert_ac_and_device(NMClient *client) +{ + const GPtrArray * devices, *acs, *ac_devices; + NMDevice * device, *ac_device; + NMActiveConnection *ac, *device_ac; + + acs = nm_client_get_active_connections(client); + g_assert(acs != NULL); + g_assert_cmpint(acs->len, ==, 1); + devices = nm_client_get_devices(client); + g_assert(devices != NULL); + g_assert_cmpint(devices->len, >=, 1); + + ac = acs->pdata[0]; + ac_devices = nm_active_connection_get_devices(ac); + g_assert(ac_devices != NULL); + g_assert_cmpint(ac_devices->len, ==, 1); + ac_device = ac_devices->pdata[0]; + g_assert(ac_device != NULL); + + device = devices->pdata[0]; + if (device != ac_device && devices->len > 1) + device = devices->pdata[1]; + + g_assert_cmpstr(nm_object_get_path(NM_OBJECT(device)), + ==, + nm_object_get_path(NM_OBJECT(ac_device))); + g_assert(device == ac_device); + + device_ac = nm_device_get_active_connection(device); + if (!device_ac) { + /* the stub NetworkManager service starts activating in an idle handler (delayed). That means, the + * device may not yet refer to the active connection at this point. */ + } else { + g_assert_cmpstr(nm_object_get_path(NM_OBJECT(ac)), + ==, + nm_object_get_path(NM_OBJECT(device_ac))); + g_assert(ac == device_ac); + } +} + +static void +add_and_activate_cb(GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMClient * client = NM_CLIENT(object); + TestACInfo *info = user_data; + GError * error = NULL; + + info->ac = nm_client_add_and_activate_connection_finish(client, result, &error); + g_assert_no_error(error); + g_assert(info->ac != NULL); + + assert_ac_and_device(client); + + info->remaining--; + if (!info->remaining) + g_main_loop_quit(info->loop); +} + +static void +client_acs_changed_cb(GObject *client, GParamSpec *pspec, gpointer user_data) +{ + TestACInfo * info = user_data; + const GPtrArray *acs; + + acs = nm_client_get_active_connections(NM_CLIENT(client)); + g_assert(acs != NULL); + g_assert_cmpint(acs->len, ==, 1); + + info->remaining--; + if (!info->remaining) + g_main_loop_quit(info->loop); +} + +static void +device_ac_changed_cb(GObject *device, GParamSpec *pspec, gpointer user_data) +{ + TestACInfo *info = user_data; + + g_assert(nm_device_get_active_connection(NM_DEVICE(device)) != NULL); + + info->remaining--; + if (!info->remaining) + g_main_loop_quit(info->loop); +} + +static void +test_active_connections(void) +{ + nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL; + gs_unref_object NMClient *client = NULL; + NMDevice * device; + NMConnection * conn; + TestACInfo info = {gl.loop, NULL, 0}; + + sinfo = nmtstc_service_init(); + if (!nmtstc_service_available(sinfo)) + return; + + client = nmtstc_client_new(TRUE); + + /* Tell the test service to add a new device */ + device = nmtstc_service_add_device(sinfo, client, "AddWiredDevice", "eth0"); + + conn = nmtst_create_minimal_connection("test-ac", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_client_add_and_activate_connection_async(client, + conn, + device, + NULL, + NULL, + add_and_activate_cb, + &info); + g_object_unref(conn); + + g_signal_connect(client, + "notify::" NM_CLIENT_ACTIVE_CONNECTIONS, + G_CALLBACK(client_acs_changed_cb), + &info); + g_signal_connect(device, + "notify::" NM_DEVICE_ACTIVE_CONNECTION, + G_CALLBACK(device_ac_changed_cb), + &info); + + /* Two signals plus activate_cb */ + info.remaining = 3; + g_main_loop_run(gl.loop); + g_signal_handlers_disconnect_by_func(client, client_acs_changed_cb, &info); + g_signal_handlers_disconnect_by_func(device, device_ac_changed_cb, &info); + + g_assert(info.ac != NULL); + + g_object_unref(info.ac); + g_clear_object(&client); + + /* Ensure that we can correctly resolve the recursive property link between the + * AC and the Device in a newly-created client. + */ + client = nmtstc_client_new(TRUE); + assert_ac_and_device(client); + g_clear_object(&client); + + client = nmtstc_client_new(TRUE); + assert_ac_and_device(client); + g_clear_object(&client); +} + +static void +client_devices_changed_cb(GObject *client, GParamSpec *pspec, gpointer user_data) +{ + TestACInfo * info = user_data; + const GPtrArray *devices; + NMDevice * device; + + devices = nm_client_get_devices(NM_CLIENT(client)); + g_assert(devices != NULL); + if (devices->len < 2) + return; + g_assert_cmpint(devices->len, ==, 2); + + if (NM_IS_DEVICE_VLAN(devices->pdata[0])) + device = devices->pdata[0]; + else if (NM_IS_DEVICE_VLAN(devices->pdata[1])) + device = devices->pdata[1]; + else + g_assert_not_reached(); + + g_assert_cmpstr(nm_device_get_iface(device), ==, "eth0.1"); + + if (!nm_device_get_active_connection(device)) { + g_assert(info->ac_signal_id == 0); + info->remaining++; + info->device = device; + g_object_add_weak_pointer(G_OBJECT(device), (gpointer *) &info->device); + info->ac_signal_id = g_signal_connect(device, + "notify::" NM_DEVICE_ACTIVE_CONNECTION, + G_CALLBACK(device_ac_changed_cb), + info); + } + + info->remaining--; + if (!info->remaining) + g_main_loop_quit(info->loop); +} + +typedef struct { + GMainLoop * loop; + NMRemoteConnection *remote; +} TestConnectionInfo; + +static void +add_connection_cb(GObject *object, GAsyncResult *result, gpointer user_data) +{ + TestConnectionInfo *info = user_data; + GError * error = NULL; + + info->remote = nm_client_add_connection_finish(NM_CLIENT(object), result, &error); + g_assert_no_error(error); + g_main_loop_quit(info->loop); +} + +static void +activate_cb(GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMClient * client = NM_CLIENT(object); + TestACInfo *info = user_data; + GError * error = NULL; + + info->ac = nm_client_activate_connection_finish(client, result, &error); + g_assert_no_error(error); + g_assert(info->ac != NULL); + + assert_ac_and_device(client); + + info->remaining--; + if (!info->remaining) + g_main_loop_quit(info->loop); +} + +static void +test_activate_virtual(void) +{ + nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL; + gs_unref_object NMClient *client = NULL; + NMConnection * conn; + NMSettingConnection * s_con; + NMSettingVlan * s_vlan; + TestACInfo info = {gl.loop, NULL, 0}; + TestConnectionInfo conn_info = {gl.loop, NULL}; + + sinfo = nmtstc_service_init(); + if (!nmtstc_service_available(sinfo)) + return; + + client = nmtstc_client_new(TRUE); + + nmtstc_service_add_device(sinfo, client, "AddWiredDevice", "eth0"); + + conn = nmtst_create_minimal_connection("test-ac", NULL, NM_SETTING_VLAN_SETTING_NAME, &s_con); + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "eth0.1", NULL); + s_vlan = nm_connection_get_setting_vlan(conn); + g_object_set(s_vlan, NM_SETTING_VLAN_ID, 1, NM_SETTING_VLAN_PARENT, "eth0", NULL); + + nm_client_add_connection_async(client, conn, TRUE, NULL, add_connection_cb, &conn_info); + g_main_loop_run(gl.loop); + g_object_unref(conn); + conn = NM_CONNECTION(conn_info.remote); + + nm_client_activate_connection_async(client, conn, NULL, NULL, NULL, activate_cb, &info); + g_object_unref(conn); + + g_signal_connect(client, + "notify::" NM_CLIENT_ACTIVE_CONNECTIONS, + G_CALLBACK(client_acs_changed_cb), + &info); + g_signal_connect(client, + "notify::" NM_CLIENT_DEVICES, + G_CALLBACK(client_devices_changed_cb), + &info); + + /* We're expecting a client::devices change, client::activate callback, + * and a device::active-connection change. + * The client::devices callback can hook a client::active-connections + * change and bump this if the property is not yet loaded. + */ + info.remaining = 3; + + g_main_loop_run(gl.loop); + g_signal_handlers_disconnect_by_func(client, client_acs_changed_cb, &info); + g_signal_handlers_disconnect_by_func(client, client_devices_changed_cb, &info); + + g_assert(info.ac != NULL); + g_clear_object(&info.ac); + + if (info.device) { + g_object_remove_weak_pointer(G_OBJECT(info.device), (gpointer *) &info.device); + nm_clear_g_signal_handler(info.device, &info.ac_signal_id); + } +} + +static void +test_device_connection_compatibility(void) +{ + nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = NULL; + gs_unref_object NMClient *client = NULL; + gs_unref_object NMConnection *conn = NULL; + NMDevice * device1; + NMDevice * device2; + NMSettingWired * s_wired; + GError * error = NULL; + const char * subchannels[] = {"0.0.8000", "0.0.8001", "0.0.8002", NULL}; + const char * subchannels_2[] = {"0.0.8000", "0.0.8001", NULL}; + const char * subchannels_x[] = {"0.0.8000", "0.0.8001", "0.0.800X", NULL}; + const char * hw_addr1 = "52:54:00:ab:db:23"; + const char * hw_addr2 = "52:54:00:ab:db:24"; + + sinfo = nmtstc_service_init(); + if (!nmtstc_service_available(sinfo)) + return; + + client = nmtstc_client_new(TRUE); + + /* Create two devices */ + device1 = nmtstc_service_add_wired_device(sinfo, client, "eth0", hw_addr1, subchannels); + device2 = nmtstc_service_add_wired_device(sinfo, client, "eth1", hw_addr2, NULL); + + g_assert_cmpstr(nm_device_get_hw_address(device1), ==, hw_addr1); + g_assert_cmpstr(nm_device_get_hw_address(device2), ==, hw_addr2); + + conn = + nmtst_create_minimal_connection("wired-matches", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_wired = nm_connection_get_setting_wired(conn); + nm_setting_wired_add_mac_blacklist_item(s_wired, "00:11:22:33:44:55"); + + /* device1 and conn are compatible */ + g_object_set(s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, + hw_addr1, + NM_SETTING_WIRED_S390_SUBCHANNELS, + subchannels, + NULL); + nm_device_connection_compatible(device1, conn, &error); + g_assert_no_error(error); + + /* device2 and conn differ in subchannels */ + g_object_set(s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels_x, NULL); + nm_device_connection_compatible(device2, conn, &error); + g_assert_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION); + g_clear_error(&error); + + /* device1 and conn differ in subchannels - 2 in connection, 3 in device */ + g_object_set(s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels_2, NULL); + nm_device_connection_compatible(device1, conn, &error); + g_assert_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION); + g_clear_error(&error); + + g_object_set(s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, NULL, NULL); + + /* device2 and conn differ in MAC address */ + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, "aa:bb:cc:dd:ee:ee", NULL); + nm_device_connection_compatible(device2, conn, &error); + g_assert_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION); + g_clear_error(&error); + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, NULL, NULL); + + /* device1 is blacklisted in conn */ + nm_setting_wired_add_mac_blacklist_item(s_wired, hw_addr1); + nm_device_connection_compatible(device1, conn, &error); + g_assert_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION); + g_clear_error(&error); +} + +/*****************************************************************************/ + +static gboolean +_test_connection_invalid_find_connections(gpointer element, gpointer needle, gpointer user_data) +{ + NMRemoteConnection *con = NM_REMOTE_CONNECTION(element); + const char * path = needle; + + g_assert(NM_IS_REMOTE_CONNECTION(con)); + g_assert(path && *path); + + return strcmp(path, nm_connection_get_path((NMConnection *) con)) == 0; +} + +#define ASSERT_IDX(i) \ + G_STMT_START \ + { \ + g_assert_cmpint(idx[i], >=, 0); \ + g_assert(path##i &&*path##i); \ + g_assert(NM_IS_REMOTE_CONNECTION(connections->pdata[idx[i]])); \ + g_assert_cmpstr(nm_connection_get_path(connections->pdata[idx[i]]), ==, path##i); \ + } \ + G_STMT_END + +static void +test_connection_invalid(void) +{ + NMTSTC_SERVICE_INFO_SETUP(my_sinfo) + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + gs_unref_object NMClient *client = NULL; + const GPtrArray * connections; + gs_free char * path0 = NULL; + gs_free char * path1 = NULL; + gs_free char * path2 = NULL; + gs_free char * path3 = NULL; + gs_free char * uuid2 = NULL; + gsize n_found; + gssize idx[4]; + gs_unref_variant GVariant *variant = NULL; + + g_assert(g_main_loop_get_context(gl.loop) + == (g_main_context_get_thread_default() ?: g_main_context_default())); + + /************************************************************************** + * Add three connections before starting libnm. One valid, two invalid. + *************************************************************************/ + + connection = nmtst_create_minimal_connection("test-connection-invalid-0", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + nmtst_connection_normalize(connection); + g_object_set(s_con, NM_SETTING_CONNECTION_UUID, nmtst_uuid_generate(), NULL); + nmtstc_service_add_connection(my_sinfo, connection, TRUE, &path0); + + nm_connection_remove_setting(connection, NM_TYPE_SETTING_WIRED); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "test-connection-invalid-1", + NM_SETTING_CONNECTION_TYPE, + "invalid-type-1", + NM_SETTING_CONNECTION_UUID, + nmtst_uuid_generate(), + NULL); + nmtstc_service_add_connection(my_sinfo, connection, FALSE, &path1); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "test-connection-invalid-2", + NM_SETTING_CONNECTION_TYPE, + "invalid-type-2", + NM_SETTING_CONNECTION_UUID, + nmtst_uuid_generate(), + NULL); + variant = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); + NMTST_VARIANT_EDITOR( + variant, + NMTST_VARIANT_ADD_SETTING("invalid-type-2", + nmtst_variant_new_vardict("some-key1", + g_variant_new_string("some-value1"), + "some-key2", + g_variant_new_uint32(4722)))); + g_variant_ref_sink(variant); + nmtstc_service_add_connection_variant(my_sinfo, variant, FALSE, &path2); + + client = nmtstc_client_new(TRUE); + + connections = nm_client_get_connections(client); + g_assert(connections); + + g_assert_cmpint(connections->len, ==, 3); + n_found = nmtst_find_all_indexes(connections->pdata, + connections->len, + (gpointer *) ((const char *[]){path0, path1, path2}), + 3, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint(n_found, ==, 3); + ASSERT_IDX(0); + ASSERT_IDX(1); + ASSERT_IDX(2); + nmtst_assert_connection_verifies_without_normalization(connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[2]], 0, 0); + + /************************************************************************** + * After having the client up and running, add another invalid connection + *************************************************************************/ + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "test-connection-invalid-2", + NM_SETTING_CONNECTION_TYPE, + "invalid-type-2", + NM_SETTING_CONNECTION_UUID, + (uuid2 = g_strdup(nmtst_uuid_generate())), + NULL); + nmtstc_service_add_connection(my_sinfo, connection, FALSE, &path3); + + nmtst_main_loop_run(gl.loop, 1000); + + connections = nm_client_get_connections(client); + g_assert(connections); + + g_assert_cmpint(connections->len, ==, 4); + n_found = nmtst_find_all_indexes(connections->pdata, + connections->len, + (gpointer *) ((const char *[]){path0, path1, path2, path3}), + 4, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint(n_found, ==, 4); + ASSERT_IDX(0); + ASSERT_IDX(1); + ASSERT_IDX(2); + ASSERT_IDX(3); + nmtst_assert_connection_verifies_without_normalization(connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[3]], 0, 0); + + /************************************************************************** + * Modify the invalid connection (still invalid) + *************************************************************************/ + + NMTST_VARIANT_EDITOR(variant, + NMTST_VARIANT_CHANGE_PROPERTY("invalid-type-2", "some-key2", "u", 4721)); + g_variant_ref_sink(variant); + nmtstc_service_update_connection_variant(my_sinfo, path2, variant, FALSE); + + nmtst_main_loop_run(gl.loop, 100); + + connections = nm_client_get_connections(client); + g_assert(connections); + + g_assert_cmpint(connections->len, ==, 4); + n_found = nmtst_find_all_indexes(connections->pdata, + connections->len, + (gpointer *) ((const char *[]){path0, path1, path2, path3}), + 4, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint(n_found, ==, 4); + ASSERT_IDX(0); + ASSERT_IDX(1); + ASSERT_IDX(2); + ASSERT_IDX(3); + nmtst_assert_connection_verifies_without_normalization(connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[3]], 0, 0); + + /************************************************************************** + * Modify the invalid connection (becomes valid) + *************************************************************************/ + + NMTST_VARIANT_EDITOR(variant, NMTST_VARIANT_DROP_SETTING("invalid-type-2")); + NMTST_VARIANT_EDITOR(variant, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TYPE, + "s", + NM_SETTING_WIRED_SETTING_NAME)); + g_variant_ref_sink(variant); + nmtstc_service_update_connection_variant(my_sinfo, path2, variant, FALSE); + + nmtst_main_loop_run(gl.loop, 100); + + connections = nm_client_get_connections(client); + g_assert(connections); + + g_assert_cmpint(connections->len, ==, 4); + n_found = nmtst_find_all_indexes(connections->pdata, + connections->len, + (gpointer *) ((const char *[]){path0, path1, path2, path3}), + 4, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint(n_found, ==, 4); + ASSERT_IDX(0); + ASSERT_IDX(1); + ASSERT_IDX(2); + ASSERT_IDX(3); + nmtst_assert_connection_verifies_without_normalization(connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_verifies_after_normalization(connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[3]], 0, 0); + + /************************************************************************** + * Modify the invalid connection (still invalid) + *************************************************************************/ + + g_object_set(s_con, NM_SETTING_CONNECTION_ID, "test-connection-invalid-2x", NULL); + nmtstc_service_update_connection(my_sinfo, path3, connection, FALSE); + + nmtst_main_loop_run(gl.loop, 100); + + connections = nm_client_get_connections(client); + g_assert(connections); + + g_assert_cmpint(connections->len, ==, 4); + n_found = nmtst_find_all_indexes(connections->pdata, + connections->len, + (gpointer *) ((const char *[]){path0, path1, path2, path3}), + 4, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint(n_found, ==, 4); + ASSERT_IDX(0); + ASSERT_IDX(1); + ASSERT_IDX(2); + ASSERT_IDX(3); + nmtst_assert_connection_verifies_without_normalization(connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_verifies_after_normalization(connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[3]], 0, 0); + g_assert_cmpstr("test-connection-invalid-2x", + ==, + nm_connection_get_id(connections->pdata[idx[3]])); + + /************************************************************************** + * Modify the invalid connection (now becomes valid) + *************************************************************************/ + + g_clear_object(&connection); + connection = nmtst_create_minimal_connection("test-connection-invalid-2", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + nmtst_connection_normalize(connection); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "test-connection-invalid-2z", + NM_SETTING_CONNECTION_TYPE, + "802-3-ethernet", + NM_SETTING_CONNECTION_UUID, + uuid2, + NULL); + + nmtstc_service_update_connection(my_sinfo, path3, connection, FALSE); + + nmtst_main_loop_run(gl.loop, 100); + + connections = nm_client_get_connections(client); + g_assert(connections); + + g_assert_cmpint(connections->len, ==, 4); + n_found = nmtst_find_all_indexes(connections->pdata, + connections->len, + (gpointer *) ((const char *[]){path0, path1, path2, path3}), + 4, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint(n_found, ==, 4); + ASSERT_IDX(0); + ASSERT_IDX(1); + ASSERT_IDX(2); + ASSERT_IDX(3); + nmtst_assert_connection_verifies_without_normalization(connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable(connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_verifies_after_normalization(connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_verifies_without_normalization(connections->pdata[idx[3]]); + g_assert_cmpstr("test-connection-invalid-2z", + ==, + nm_connection_get_id(connections->pdata[idx[3]])); + + /************************************************************************** + * Modify the invalid connection and make it valid + *************************************************************************/ + + g_clear_object(&connection); + connection = nmtst_create_minimal_connection("test-connection-invalid-1", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + nmtst_connection_normalize(connection); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "test-connection-invalid-1x", + NM_SETTING_CONNECTION_TYPE, + "802-3-ethernet", + NM_SETTING_CONNECTION_UUID, + nm_connection_get_uuid(connections->pdata[idx[1]]), + NULL); + + nmtstc_service_update_connection(my_sinfo, path1, connection, FALSE); + + nmtst_main_loop_run(gl.loop, 100); + + connections = nm_client_get_connections(client); + g_assert(connections); + + g_assert_cmpint(connections->len, ==, 4); + n_found = nmtst_find_all_indexes(connections->pdata, + connections->len, + (gpointer *) ((const char *[]){path0, path1, path2, path3}), + 4, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint(n_found, ==, 4); + ASSERT_IDX(0); + ASSERT_IDX(1); + ASSERT_IDX(2); + ASSERT_IDX(3); + nmtst_assert_connection_verifies_without_normalization(connections->pdata[idx[0]]); + nmtst_assert_connection_verifies_without_normalization(connections->pdata[idx[1]]); + nmtst_assert_connection_verifies_after_normalization(connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_verifies_without_normalization(connections->pdata[idx[3]]); + g_assert_cmpstr("test-connection-invalid-1x", + ==, + nm_connection_get_id(connections->pdata[idx[1]])); + g_assert_cmpstr("test-connection-invalid-2z", + ==, + nm_connection_get_id(connections->pdata[idx[3]])); + +#undef ASSERT_IDX +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + g_setenv("LIBNM_USE_SESSION_BUS", "1", TRUE); + + nmtst_init(&argc, &argv, TRUE); + + gl.loop = g_main_loop_new(NULL, FALSE); + + g_test_add_func("/libnm/device-added", test_device_added); + g_test_add_func("/libnm/device-added-signal-after-init", test_device_added_signal_after_init); + g_test_add_func("/libnm/wifi-ap-added-removed", test_wifi_ap_added_removed); + g_test_add_func("/libnm/devices-array", test_devices_array); + g_test_add_func("/libnm/client-nm-running", test_client_nm_running); + g_test_add_func("/libnm/active-connections", test_active_connections); + g_test_add_func("/libnm/activate-virtual", test_activate_virtual); + g_test_add_func("/libnm/device-connection-compatibility", test_device_connection_compatibility); + g_test_add_func("/libnm/connection/invalid", test_connection_invalid); + + return g_test_run(); +} + +/*****************************************************************************/ + +/* this header is intended to be copied to users of nm_vpn_editor_plugin_call(), + * to simplify invocation of generic functions. Include it here, to compile + * the code. */ +#include "contrib/nm-vpn-editor-plugin-call.h" diff --git a/src/libnm-client-impl/tests/test-remote-settings-client.c b/src/libnm-client-impl/tests/test-remote-settings-client.c new file mode 100644 index 0000000..e5415f5 --- /dev/null +++ b/src/libnm-client-impl/tests/test-remote-settings-client.c @@ -0,0 +1,498 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2010 - 2011 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include +#include + +#include "libnm-glib-aux/nm-time-utils.h" + +#include "libnm-client-test/nm-test-libnm-utils.h" + +static struct { + NMTstcServiceInfo * sinfo; + NMClient * client; + GDBusConnection * bus; + NMRemoteConnection *remote; +} gl = {}; + +/*****************************************************************************/ + +static void +add_cb(GObject *s, GAsyncResult *result, gpointer user_data) +{ + gboolean *done = user_data; + GError * error = NULL; + + gl.remote = nm_client_add_connection_finish(gl.client, result, &error); + g_assert_no_error(error); + + *done = TRUE; + g_object_add_weak_pointer(G_OBJECT(gl.remote), (void **) &gl.remote); + + /* nm_client_add_connection_finish() adds a ref to @remote, but we + * want the weak pointer to be cleared as soon as @client drops its own ref. + * So drop ours. + */ + g_object_unref(gl.remote); +} + +#define TEST_CON_ID "blahblahblah" + +static void +test_add_connection(void) +{ + NMConnection *connection; + gboolean done = FALSE; + + if (!nmtstc_service_available(gl.sinfo)) + return; + + connection = + nmtst_create_minimal_connection(TEST_CON_ID, NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + + nm_client_add_connection_async(gl.client, connection, TRUE, NULL, add_cb, &done); + + nmtst_main_context_iterate_until_assert(NULL, 5000, done); + + g_assert(gl.remote != NULL); + + /* Make sure the connection is the same as what we added */ + g_assert( + nm_connection_compare(connection, NM_CONNECTION(gl.remote), NM_SETTING_COMPARE_FLAG_EXACT) + == TRUE); + g_object_unref(connection); +} + +/*****************************************************************************/ + +static void +set_visible_cb(GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GError * error = NULL; + GVariant *ret; + + ret = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), result, &error); + g_assert_no_error(error); + g_variant_unref(ret); +} + +static void +visible_changed_cb(GObject *object, GParamSpec *pspec, gboolean *done) +{ + if (!nm_remote_connection_get_visible(NM_REMOTE_CONNECTION(object))) + *done = TRUE; +} + +static void +connection_removed_cb(NMClient *s, NMRemoteConnection *connection, gboolean *done) +{ + if (connection == gl.remote) + *done = TRUE; +} + +static void +invis_has_settings_cb(NMSetting * setting, + const char * key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + *((gboolean *) user_data) = TRUE; +} + +static void +test_make_invisible(void) +{ + const GPtrArray *conns; + int i; + GDBusProxy * proxy; + gboolean visible_changed = FALSE, connection_removed = FALSE; + gboolean has_settings = FALSE; + char * path; + + if (!nmtstc_service_available(gl.sinfo)) + return; + + g_assert(gl.remote != NULL); + + /* Listen for the remove event when the connection becomes invisible */ + g_signal_connect(gl.remote, + "notify::" NM_REMOTE_CONNECTION_VISIBLE, + G_CALLBACK(visible_changed_cb), + &visible_changed); + g_signal_connect(gl.client, + "connection-removed", + G_CALLBACK(connection_removed_cb), + &connection_removed); + + path = g_strdup(nm_connection_get_path(NM_CONNECTION(gl.remote))); + proxy = g_dbus_proxy_new_sync(gl.bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NULL, + NULL); + g_assert(proxy != NULL); + + /* Bypass the NMClient object so we can test it independently */ + g_dbus_proxy_call(proxy, + "SetVisible", + g_variant_new("(b)", FALSE), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + set_visible_cb, + NULL); + + /* Wait for the connection to be removed */ + nmtst_main_context_iterate_until_assert(NULL, 5000, visible_changed && connection_removed); + + g_signal_handlers_disconnect_by_func(gl.remote, + G_CALLBACK(visible_changed_cb), + &visible_changed); + g_signal_handlers_disconnect_by_func(gl.client, + G_CALLBACK(connection_removed_cb), + &connection_removed); + + /* Ensure NMClient no longer has the connection */ + conns = nm_client_get_connections(gl.client); + for (i = 0; i < conns->len; i++) { + NMConnection *candidate = NM_CONNECTION(conns->pdata[i]); + + g_assert((gpointer) gl.remote != (gpointer) candidate); + g_assert(strcmp(path, nm_connection_get_path(candidate)) != 0); + } + + /* And ensure the invisible connection no longer has any settings */ + g_assert(gl.remote); + nm_connection_for_each_setting_value(NM_CONNECTION(gl.remote), + invis_has_settings_cb, + &has_settings); + g_assert(has_settings == FALSE); + + g_free(path); + g_object_unref(proxy); +} + +/*****************************************************************************/ + +static void +vis_new_connection_cb(NMClient *foo, NMRemoteConnection *connection, NMRemoteConnection **new) +{ + *new = connection; +} + +static void +test_make_visible(void) +{ + const GPtrArray *conns; + int i; + GDBusProxy * proxy; + gboolean found = FALSE; + char * path; + NMRemoteConnection *new = NULL; + + if (!nmtstc_service_available(gl.sinfo)) + return; + + g_assert(gl.remote != NULL); + + /* Wait for the new-connection signal when the connection is visible again */ + g_signal_connect(gl.client, + NM_CLIENT_CONNECTION_ADDED, + G_CALLBACK(vis_new_connection_cb), + &new); + + path = g_strdup(nm_connection_get_path(NM_CONNECTION(gl.remote))); + proxy = g_dbus_proxy_new_sync(gl.bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NULL, + NULL); + g_assert(proxy != NULL); + + /* Bypass the NMClient object so we can test it independently */ + g_dbus_proxy_call(proxy, + "SetVisible", + g_variant_new("(b)", TRUE), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + set_visible_cb, + NULL); + + /* Wait for the settings service to announce the connection again */ + nmtst_main_context_iterate_until_assert(NULL, 5000, new); + + /* Ensure the new connection is the same as the one we made visible again */ + g_assert(new == gl.remote); + + g_signal_handlers_disconnect_by_func(gl.client, G_CALLBACK(vis_new_connection_cb), &new); + + /* Ensure NMClient has the connection */ + conns = nm_client_get_connections(gl.client); + for (i = 0; i < conns->len; i++) { + NMConnection *candidate = NM_CONNECTION(conns->pdata[i]); + + if ((gpointer) gl.remote == (gpointer) candidate) { + g_assert_cmpstr(path, ==, nm_connection_get_path(candidate)); + g_assert_cmpstr(TEST_CON_ID, ==, nm_connection_get_id(candidate)); + found = TRUE; + break; + } + } + g_assert(found == TRUE); + + g_free(path); + g_object_unref(proxy); +} + +/*****************************************************************************/ + +static void +deleted_cb(GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GError * error = NULL; + GVariant *ret; + + ret = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), result, &error); + g_assert_no_error(error); + g_variant_unref(ret); +} + +static void +removed_cb(NMClient *s, NMRemoteConnection *connection, gboolean *done) +{ + if (connection == gl.remote) + *done = TRUE; +} + +static void +test_remove_connection(void) +{ + NMRemoteConnection *connection; + const GPtrArray * conns; + int i; + GDBusProxy * proxy; + gboolean done = FALSE; + char * path; + + if (!nmtstc_service_available(gl.sinfo)) + return; + + /* Find a connection to delete */ + conns = nm_client_get_connections(gl.client); + g_assert_cmpint(conns->len, >, 0); + + connection = NM_REMOTE_CONNECTION(conns->pdata[0]); + g_assert(connection); + g_assert(gl.remote == connection); + path = g_strdup(nm_connection_get_path(NM_CONNECTION(connection))); + g_signal_connect(gl.client, "connection-removed", G_CALLBACK(removed_cb), &done); + + proxy = g_dbus_proxy_new_sync(gl.bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NULL, + NULL); + g_assert(proxy != NULL); + + /* Bypass the NMClient object so we can test it independently */ + g_dbus_proxy_call(proxy, "Delete", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, deleted_cb, NULL); + + nmtst_main_context_iterate_until_assert(NULL, 5000, done && !gl.remote); + + /* Ensure NMClient no longer has the connection */ + conns = nm_client_get_connections(gl.client); + for (i = 0; i < conns->len; i++) { + NMConnection *candidate = NM_CONNECTION(conns->pdata[i]); + + g_assert((gpointer) connection != (gpointer) candidate); + g_assert_cmpstr(path, ==, nm_connection_get_path(candidate)); + } + + g_free(path); + g_object_unref(proxy); +} + +/*****************************************************************************/ + +#define TEST_ADD_REMOVE_ID "add-remove-test-connection" + +static void +add_remove_cb(GObject *s, GAsyncResult *result, gpointer user_data) +{ + NMRemoteConnection *connection; + gboolean * done = user_data; + gs_free_error GError *error = NULL; + + connection = nm_client_add_connection_finish(gl.client, result, &error); + g_assert_error(error, NM_CLIENT_ERROR, NM_CLIENT_ERROR_OBJECT_CREATION_FAILED); + g_assert(connection == NULL); + + *done = TRUE; +} + +static void +test_add_remove_connection(void) +{ + gs_unref_variant GVariant *ret = NULL; + GError * error = NULL; + gs_unref_object NMConnection *connection = NULL; + gboolean done = FALSE; + + if (!nmtstc_service_available(gl.sinfo)) + return; + + /* This will cause the test server to immediately delete the connection + * after creating it. + */ + ret = g_dbus_proxy_call_sync(gl.sinfo->proxy, + "AutoRemoveNextConnection", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + nmtst_assert_success(ret, error); + + connection = nmtst_create_minimal_connection(TEST_ADD_REMOVE_ID, + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + nm_client_add_connection_async(gl.client, connection, TRUE, NULL, add_remove_cb, &done); + + nmtst_main_context_iterate_until_assert(NULL, 5000, done); +} + +/*****************************************************************************/ + +static void +add_bad_cb(GObject *s, GAsyncResult *result, gpointer user_data) +{ + gboolean * done = user_data; + gs_free_error GError *error = NULL; + + gl.remote = nm_client_add_connection_finish(gl.client, result, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + + *done = TRUE; +} + +static void +test_add_bad_connection(void) +{ + gs_unref_object NMConnection *connection = NULL; + gboolean done = FALSE; + + if (!nmtstc_service_available(gl.sinfo)) + return; + + /* The test daemon doesn't support bond connections */ + connection = nmtst_create_minimal_connection("bad connection test", + NULL, + NM_SETTING_BOND_SETTING_NAME, + NULL); + + nm_client_add_connection_async(gl.client, connection, TRUE, NULL, add_bad_cb, &done); + g_clear_object(&connection); + + nmtst_main_context_iterate_until_assert(NULL, 5000, done); + g_assert(gl.remote == NULL); +} + +/*****************************************************************************/ + +static void +save_hostname_cb(GObject *s, GAsyncResult *result, gpointer user_data) +{ + gboolean * done = user_data; + gs_free_error GError *error = NULL; + + nm_client_save_hostname_finish(gl.client, result, &error); + g_assert_no_error(error); + + *done = TRUE; +} + +static void +test_save_hostname(void) +{ + gint64 until_ts; + gboolean done = FALSE; + GError * error = NULL; + + if (!nmtstc_service_available(gl.sinfo)) + return; + + /* test-networkmanager-service.py requires the hostname to contain a '.' */ + nm_client_save_hostname(gl.client, "foo", NULL, &error); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_HOSTNAME); + g_clear_error(&error); + + nm_client_save_hostname_async(gl.client, "example.com", NULL, save_hostname_cb, &done); + + until_ts = nm_utils_get_monotonic_timestamp_msec() + 5000; + while (TRUE) { + g_main_context_iteration(NULL, FALSE); + if (done) + break; + if (nm_utils_get_monotonic_timestamp_msec() >= until_ts) + g_assert_not_reached(); + } + + g_assert(gl.remote == NULL); +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + int ret; + GError *error = NULL; + + g_setenv("LIBNM_USE_SESSION_BUS", "1", TRUE); + + nmtst_init(&argc, &argv, TRUE); + + gl.bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); + nmtst_assert_success(gl.bus, error); + + gl.sinfo = nmtstc_service_init(); + + gl.client = nmtstc_client_new(TRUE); + + /* FIXME: these tests assume that they get run in order, but g_test_run() + * does not actually guarantee that! + */ + g_test_add_func("/client/add_connection", test_add_connection); + g_test_add_func("/client/make_invisible", test_make_invisible); + g_test_add_func("/client/make_visible", test_make_visible); + g_test_add_func("/client/remove_connection", test_remove_connection); + g_test_add_func("/client/add_remove_connection", test_add_remove_connection); + g_test_add_func("/client/add_bad_connection", test_add_bad_connection); + g_test_add_func("/client/save_hostname", test_save_hostname); + + ret = g_test_run(); + + nm_clear_pointer(&gl.sinfo, nmtstc_service_cleanup); + g_clear_object(&gl.client); + g_clear_object(&gl.bus); + + return ret; +} diff --git a/src/libnm-client-impl/tests/test-secret-agent.c b/src/libnm-client-impl/tests/test-secret-agent.c new file mode 100644 index 0000000..8f758f3 --- /dev/null +++ b/src/libnm-client-impl/tests/test-secret-agent.c @@ -0,0 +1,746 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2010 - 2014 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include +#include + +#include "nm-secret-agent-old.h" + +#include "libnm-client-test/nm-test-libnm-utils.h" + +/*****************************************************************************/ + +enum { + SECRET_REQUESTED, + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL] = {0}; + +typedef NMSecretAgentOld TestSecretAgent; +typedef NMSecretAgentOldClass TestSecretAgentClass; + +GType test_secret_agent_get_type(void); + +G_DEFINE_TYPE(TestSecretAgent, test_secret_agent, NM_TYPE_SECRET_AGENT_OLD) + +static void +test_secret_agent_get_secrets(NMSecretAgentOld * agent, + NMConnection * connection, + const char * connection_path, + const char * setting_name, + const char ** hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer callback_data) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant * secrets = NULL; + GVariantBuilder secrets_builder, setting_builder; + char * secret = NULL; + GError * error = NULL; + + g_assert_cmpstr(setting_name, ==, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec); + g_assert_cmpstr(nm_setting_wireless_security_get_key_mgmt(s_wsec), ==, "wpa-psk"); + g_assert_cmpstr(nm_setting_wireless_security_get_psk(s_wsec), ==, NULL); + + g_signal_emit(agent, + signals[SECRET_REQUESTED], + 0, + connection, + connection_path, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK, + &secret); + + if (!secret) { + error = g_error_new(NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_NO_SECRETS, "No secrets"); + goto done; + } + + if (!strcmp(secret, "CANCEL")) { + error = g_error_new(NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_USER_CANCELED, + "User canceled"); + goto done; + } + + g_variant_builder_init(&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add(&setting_builder, + "{sv}", + NM_SETTING_WIRELESS_SECURITY_PSK, + g_variant_new_string(secret)); + + g_variant_builder_init(&secrets_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_add(&secrets_builder, "{sa{sv}}", setting_name, &setting_builder); + secrets = g_variant_ref_sink(g_variant_builder_end(&secrets_builder)); + +done: + callback(agent, connection, secrets, error, callback_data); + g_clear_error(&error); + nm_clear_pointer(&secrets, g_variant_unref); + g_free(secret); +} + +static void +test_secret_agent_cancel_get_secrets(NMSecretAgentOld *agent, + const char * connection_path, + const char * setting_name) +{ + g_assert_not_reached(); +} + +static void +test_secret_agent_save_secrets(NMSecretAgentOld * agent, + NMConnection * connection, + const char * connection_path, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer callback_data) +{ + g_assert_not_reached(); +} + +static void +test_secret_agent_delete_secrets(NMSecretAgentOld * agent, + NMConnection * connection, + const char * connection_path, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer callback_data) +{ + g_assert_not_reached(); +} + +static void +test_secret_agent_init(TestSecretAgent *agent) +{} + +static NMSecretAgentOld * +test_secret_agent_new(gboolean auto_register) +{ + return nmtstc_context_object_new(test_secret_agent_get_type(), + TRUE, + NM_SECRET_AGENT_OLD_IDENTIFIER, + "test-secret-agent", + NM_SECRET_AGENT_OLD_AUTO_REGISTER, + auto_register, + NULL); +} + +static void +test_secret_agent_class_init(TestSecretAgentClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSecretAgentOldClass *agent_class = NM_SECRET_AGENT_OLD_CLASS(klass); + + agent_class->get_secrets = test_secret_agent_get_secrets; + agent_class->cancel_get_secrets = test_secret_agent_cancel_get_secrets; + agent_class->save_secrets = test_secret_agent_save_secrets; + agent_class->delete_secrets = test_secret_agent_delete_secrets; + + signals[SECRET_REQUESTED] = g_signal_new("secret-requested", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + NULL, + G_TYPE_STRING, + 4, + NM_TYPE_CONNECTION, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); +} + +/*****************************************************************************/ + +typedef struct { + NMTstcServiceInfo *sinfo; + NMClient * client; + + NMSecretAgentOld *agent; + NMDevice * device; + NMConnection * connection; + + GMainLoop *loop; + GSource * timeout_source; + + char *ifname; + char *con_id; + + int secrets_requested; +} TestSecretAgentData; + +static void +connection_added_cb(GObject *s, GAsyncResult *result, gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + NMRemoteConnection * connection; + GError * error = NULL; + + connection = nm_client_add_connection_finish(sadata->client, result, &error); + + g_assert_no_error(error); + g_assert_cmpstr(nm_connection_get_id(NM_CONNECTION(connection)), ==, sadata->con_id); + + sadata->connection = NM_CONNECTION(connection); + g_main_loop_quit(sadata->loop); +} + +static void +register_cb(GObject *object, GAsyncResult *result, gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + GError * error = NULL; + + nm_secret_agent_old_register_finish(sadata->agent, result, &error); + g_assert_no_error(error); + g_assert(nm_secret_agent_old_get_registered(sadata->agent)); + + g_main_loop_quit(sadata->loop); +} + +#define TEST_CON_ID_PREFIX "test-secret-agent" + +static void +test_setup(TestSecretAgentData *sadata, gconstpointer test_data) +{ + static int static_counter = 0; + const int counter = static_counter++; + const char * create_agent = test_data; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWireless * s_wireless; + GBytes * ssid; + NMSetting * s_wsec; + gs_free_error GError *error = NULL; + + sadata->sinfo = nmtstc_service_init(); + if (!sadata->sinfo) + return; + + g_assert(nm_g_main_context_is_thread_default(NULL)); + + sadata->client = nmtstc_client_new(TRUE); + + g_assert(nm_g_main_context_is_thread_default(NULL)); + g_assert(nm_g_main_context_is_thread_default(nm_client_get_main_context(sadata->client))); + + sadata->loop = g_main_loop_new(NULL, FALSE); + + sadata->timeout_source = g_timeout_source_new_seconds(5); + g_source_set_callback(sadata->timeout_source, nmtst_g_source_assert_not_called, NULL, NULL); + g_source_attach(sadata->timeout_source, NULL); + + sadata->ifname = g_strdup_printf("wlan%d", counter); + sadata->con_id = g_strdup_printf("%s-%d", TEST_CON_ID_PREFIX, counter); + + sadata->device = + nmtstc_service_add_device(sadata->sinfo, sadata->client, "AddWifiDevice", sadata->ifname); + + /* Create the connection */ + connection = nmtst_create_minimal_connection(sadata->con_id, + NULL, + NM_SETTING_WIRELESS_SETTING_NAME, + &s_con); + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, sadata->ifname, NULL); + + s_wireless = nm_connection_get_setting_wireless(connection); + ssid = g_bytes_new("foo", 3); + g_object_set(s_wireless, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_bytes_unref(ssid); + + s_wsec = g_object_new(NM_TYPE_SETTING_WIRELESS_SECURITY, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-psk", + NULL); + nm_connection_add_setting(connection, s_wsec); + + nm_client_add_connection_async(sadata->client, + connection, + TRUE, + NULL, + connection_added_cb, + sadata); + g_object_unref(connection); + + g_main_loop_run(sadata->loop); + g_assert(sadata->connection); + + if (nm_streq(create_agent, "1")) { + gboolean auto_register = nmtst_get_rand_bool(); + + sadata->agent = test_secret_agent_new(auto_register); + + if (auto_register) { + g_assert(nm_secret_agent_old_get_registered(sadata->agent)); + nm_secret_agent_old_register(sadata->agent, NULL, &error); + g_assert_no_error(error); + } else { + g_assert(!nm_secret_agent_old_get_registered(sadata->agent)); + nm_secret_agent_old_register_async(sadata->agent, NULL, register_cb, sadata); + g_main_loop_run(sadata->loop); + } + + g_assert(nm_secret_agent_old_get_registered(sadata->agent)); + } +} + +static void +test_cleanup(TestSecretAgentData *sadata, gconstpointer test_data) +{ + GVariant * ret; + GError * error = NULL; + NMTstContextBusyWatcherData watcher_data = {}; + + g_assert(nm_g_main_context_is_thread_default(NULL)); + + if (!sadata->sinfo) + return; + + g_assert(nm_g_main_context_is_thread_default(nm_client_get_main_context(sadata->client))); + + nmtst_context_busy_watcher_add(&watcher_data, + nm_client_get_context_busy_watcher(sadata->client)); + + if (sadata->agent) { + nmtst_context_busy_watcher_add(&watcher_data, + nm_secret_agent_old_get_context_busy_watcher(sadata->agent)); + + if (nm_secret_agent_old_get_registered(sadata->agent)) { + nm_secret_agent_old_unregister(sadata->agent, NULL, &error); + g_assert_no_error(error); + } + g_object_unref(sadata->agent); + } + + ret = + g_dbus_proxy_call_sync(sadata->sinfo->proxy, + "RemoveDevice", + g_variant_new("(s)", nm_object_get_path(NM_OBJECT(sadata->device))), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error(error); + g_variant_unref(ret); + + g_object_unref(sadata->connection); + g_object_unref(sadata->client); + + nmtstc_service_cleanup(sadata->sinfo); + + nm_clear_g_source_inst(&sadata->timeout_source); + + g_main_loop_unref(sadata->loop); + + g_free(sadata->ifname); + g_free(sadata->con_id); + + *sadata = (TestSecretAgentData){}; + + nmtst_context_busy_watcher_wait(&watcher_data); + + while (g_main_context_iteration(NULL, FALSE)) {} + + nmtst_main_context_assert_no_dispatch(NULL, nmtst_get_rand_uint32() % 500); +} + +/*****************************************************************************/ + +static void +connection_activated_none_cb(GObject *c, GAsyncResult *result, gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + gs_free_error GError *error = NULL; + + nm_client_activate_connection_finish(sadata->client, result, &error); + g_assert_error(error, NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_NO_SECRETS); + + g_main_loop_quit(sadata->loop); +} + +static void +test_secret_agent_none(TestSecretAgentData *sadata, gconstpointer test_data) +{ + if (!nmtstc_service_available(sadata->sinfo)) + return; + + nm_client_activate_connection_async(sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_none_cb, + sadata); + g_main_loop_run(sadata->loop); +} + +/*****************************************************************************/ + +static char * +secrets_requested_no_secrets_cb(TestSecretAgent *agent, + NMConnection * connection, + const char * connection_path, + const char * setting_name, + const char * secret_name, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + + g_assert_cmpstr(connection_path, ==, nm_connection_get_path(sadata->connection)); + sadata->secrets_requested++; + + return NULL; +} + +static void +connection_activated_no_secrets_cb(GObject *c, GAsyncResult *result, gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + gs_unref_object NMActiveConnection *ac = NULL; + gs_free_error GError *error = NULL; + + ac = nm_client_activate_connection_finish(sadata->client, result, &error); + g_assert_error(error, NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_NO_SECRETS); + g_main_loop_quit(sadata->loop); +} + +static void +test_secret_agent_no_secrets(TestSecretAgentData *sadata, gconstpointer test_data) +{ + if (!nmtstc_service_available(sadata->sinfo)) + return; + + g_signal_connect(sadata->agent, + "secret-requested", + G_CALLBACK(secrets_requested_no_secrets_cb), + sadata); + + nm_client_activate_connection_async(sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_no_secrets_cb, + sadata); + g_main_loop_run(sadata->loop); + + g_assert_cmpint(sadata->secrets_requested, ==, 1); +} + +/*****************************************************************************/ + +static void +connection_activated_cancel_cb(GObject *c, GAsyncResult *result, gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + gs_unref_object NMActiveConnection *ac = NULL; + gs_free_error GError *error = NULL; + + ac = nm_client_activate_connection_finish(sadata->client, result, &error); + g_assert_error(error, NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_USER_CANCELED); + g_main_loop_quit(sadata->loop); +} + +static char * +secrets_requested_cancel_cb(TestSecretAgent *agent, + NMConnection * connection, + const char * connection_path, + const char * setting_name, + const char * secret_name, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + + g_assert_cmpstr(connection_path, ==, nm_connection_get_path(sadata->connection)); + sadata->secrets_requested++; + + return g_strdup("CANCEL"); +} + +static void +test_secret_agent_cancel(TestSecretAgentData *sadata, gconstpointer test_data) +{ + if (!nmtstc_service_available(sadata->sinfo)) + return; + + g_signal_connect(sadata->agent, + "secret-requested", + G_CALLBACK(secrets_requested_cancel_cb), + sadata); + + nm_client_activate_connection_async(sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_cancel_cb, + sadata); + g_main_loop_run(sadata->loop); + + g_assert_cmpint(sadata->secrets_requested, ==, 1); +} + +/*****************************************************************************/ + +static void +connection_activated_good_cb(GObject *c, GAsyncResult *result, gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + NMActiveConnection * ac; + GError * error = NULL; + + ac = nm_client_activate_connection_finish(sadata->client, result, &error); + g_assert_no_error(error); + + g_object_unref(ac); + + g_main_loop_quit(sadata->loop); +} + +static char * +secrets_requested_good_cb(TestSecretAgent *agent, + NMConnection * connection, + const char * connection_path, + const char * setting_name, + const char * secret_name, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + + g_assert_cmpstr(connection_path, ==, nm_connection_get_path(sadata->connection)); + sadata->secrets_requested++; + + return g_strdup("password"); +} + +static void +test_secret_agent_good(TestSecretAgentData *sadata, gconstpointer test_data) +{ + if (!nmtstc_service_available(sadata->sinfo)) + return; + + g_signal_connect(sadata->agent, + "secret-requested", + G_CALLBACK(secrets_requested_good_cb), + sadata); + + nm_client_activate_connection_async(sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_good_cb, + sadata); + g_main_loop_run(sadata->loop); + + g_assert_cmpint(sadata->secrets_requested, ==, 1); +} + +/*****************************************************************************/ + +static void +async_init_cb(GObject *object, GAsyncResult *result, gpointer user_data) +{ + GMainLoop * loop = user_data; + gs_free_error GError *error = NULL; + gs_unref_object GObject *agent = NULL; + + agent = g_async_initable_new_finish(G_ASYNC_INITABLE(object), result, &error); + nmtst_assert_success(NM_IS_SECRET_AGENT_OLD(agent), error); + g_assert(!nm_secret_agent_old_get_registered(NM_SECRET_AGENT_OLD(agent))); + + g_main_loop_quit(loop); +} + +static void +test_secret_agent_nm_not_running(void) +{ + gs_unref_object NMSecretAgentOld *agent = NULL; + nm_auto_unref_gmainloop GMainLoop *loop = NULL; + GError * error = NULL; + + agent = g_initable_new(test_secret_agent_get_type(), + NULL, + &error, + NM_SECRET_AGENT_OLD_IDENTIFIER, + "test-secret-agent", + NULL); + nmtst_assert_success(NM_IS_SECRET_AGENT_OLD(agent), error); + g_assert(!nm_secret_agent_old_get_registered(agent)); + g_clear_object(&agent); + + loop = g_main_loop_new(NULL, FALSE); + g_async_initable_new_async(test_secret_agent_get_type(), + G_PRIORITY_DEFAULT, + NULL, + async_init_cb, + loop, + NM_SECRET_AGENT_OLD_IDENTIFIER, + "test-secret-agent", + NULL); + g_main_loop_run(loop); +} + +/*****************************************************************************/ + +typedef struct { + int step; + int invoke_count; +} AutoRegisterData; + +static void +registered_changed(GObject *object, GParamSpec *pspec, gpointer user_data) +{ + NMSecretAgentOld *agent = NM_SECRET_AGENT_OLD(object); + AutoRegisterData *data = user_data; + + g_assert(data); + g_assert(NM_IS_SECRET_AGENT_OLD(agent)); + + data->invoke_count++; + g_assert_cmpint(data->invoke_count, ==, data->step); + + switch (data->step) { + case 1: + case 3: + g_assert(nm_secret_agent_old_get_registered(agent)); + break; + case 2: + case 4: + g_assert(!nm_secret_agent_old_get_registered(agent)); + break; + default: + g_assert_not_reached(); + } +} + +static void +test_secret_agent_auto_register(void) +{ + NMTstcServiceInfo *sinfo; + gs_unref_object NMSecretAgentOld *agent = NULL; + GError * error = NULL; + AutoRegisterData auto_register_data = { + .step = 0, + .invoke_count = 0, + }; + gulong signal_id; + NMTstContextBusyWatcherData watcher_data = {}; + + sinfo = nmtstc_service_init(); + if (!nmtstc_service_available(sinfo)) + return; + + agent = test_secret_agent_new(FALSE); + g_assert(!nm_secret_agent_old_get_registered(agent)); + + signal_id = g_signal_connect(agent, + "notify::" NM_SECRET_AGENT_OLD_REGISTERED, + G_CALLBACK(registered_changed), + &auto_register_data); + + if (nmtst_get_rand_bool()) { + g_object_set(agent, NM_SECRET_AGENT_OLD_AUTO_REGISTER, TRUE, NULL); + } else + nm_secret_agent_old_enable(agent, TRUE); + g_assert(!nm_secret_agent_old_get_registered(agent)); + + nm_secret_agent_old_register(agent, NULL, &error); + g_assert_no_error(error); + g_assert(!nm_secret_agent_old_get_registered(agent)); + + auto_register_data.step = 1; + nmtst_main_context_iterate_until_assert(NULL, 1000, nm_secret_agent_old_get_registered(agent)); + + auto_register_data.step = 2; + nm_secret_agent_old_enable(agent, FALSE); + g_assert(!nm_secret_agent_old_get_registered(agent)); + + nmtst_main_context_iterate_until(NULL, nmtst_get_rand_uint32() % 200, FALSE); + + g_assert(!nm_secret_agent_old_get_registered(agent)); + + nmtstc_service_cleanup(sinfo); + + g_assert(!nm_secret_agent_old_get_registered(agent)); + + nm_secret_agent_old_enable(agent, TRUE); + + g_assert(!nm_secret_agent_old_get_registered(agent)); + + nmtst_main_context_iterate_until(NULL, nmtst_get_rand_uint32() % 200, FALSE); + + g_assert(!nm_secret_agent_old_get_registered(agent)); + + sinfo = nmtstc_service_init(); + g_assert(nmtstc_service_available(sinfo)); + + auto_register_data.step = 3; + nmtst_main_context_iterate_until_assert(NULL, 1000, nm_secret_agent_old_get_registered(agent)); + + nmtstc_service_cleanup(sinfo); + + auto_register_data.step = 4; + nmtst_main_context_iterate_until_assert(NULL, 1000, !nm_secret_agent_old_get_registered(agent)); + + nm_clear_g_signal_handler(agent, &signal_id); + + nmtst_context_busy_watcher_add(&watcher_data, + nm_secret_agent_old_get_context_busy_watcher(agent)); + + g_clear_object(&agent); + + nmtst_context_busy_watcher_wait(&watcher_data); + + nmtst_main_context_assert_no_dispatch(NULL, nmtst_get_rand_uint32() % 500); +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + g_setenv("LIBNM_USE_SESSION_BUS", "1", TRUE); + + nmtst_init(&argc, &argv, TRUE); + + g_test_add("/libnm/secret-agent/none", + TestSecretAgentData, + "0", + test_setup, + test_secret_agent_none, + test_cleanup); + g_test_add("/libnm/secret-agent/no-secrets", + TestSecretAgentData, + "1", + test_setup, + test_secret_agent_no_secrets, + test_cleanup); + g_test_add("/libnm/secret-agent/cancel", + TestSecretAgentData, + "1", + test_setup, + test_secret_agent_cancel, + test_cleanup); + g_test_add("/libnm/secret-agent/good", + TestSecretAgentData, + "1", + test_setup, + test_secret_agent_good, + test_cleanup); + g_test_add_func("/libnm/secret-agent/nm-not-running", test_secret_agent_nm_not_running); + g_test_add_func("/libnm/secret-agent/auto-register", test_secret_agent_auto_register); + + return g_test_run(); +} diff --git a/src/libnm-client-public/NetworkManager.h b/src/libnm-client-public/NetworkManager.h new file mode 100644 index 0000000..f9cc856 --- /dev/null +++ b/src/libnm-client-public/NetworkManager.h @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 - 2018 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_H__ +#define __NETWORKMANAGER_H__ + +#define __NETWORKMANAGER_H_INSIDE__ + +#include "nm-access-point.h" +#include "nm-active-connection.h" +#include "nm-client.h" +#include "nm-connection.h" +#include "nm-core-enum-types.h" +#include "nm-dbus-interface.h" +#include "nm-device-6lowpan.h" +#include "nm-device-adsl.h" +#include "nm-device-bond.h" +#include "nm-device-bridge.h" +#include "nm-device-bt.h" +#include "nm-device-dummy.h" +#include "nm-device-ethernet.h" +#include "nm-device-generic.h" +#include "nm-device-infiniband.h" +#include "nm-device-ip-tunnel.h" +#include "nm-device-macsec.h" +#include "nm-device-macvlan.h" +#include "nm-device-modem.h" +#include "nm-device-olpc-mesh.h" +#include "nm-device-ovs-bridge.h" +#include "nm-device-ovs-interface.h" +#include "nm-device-ovs-port.h" +#include "nm-device-ppp.h" +#include "nm-device-team.h" +#include "nm-device-tun.h" +#include "nm-device-veth.h" +#include "nm-device-vlan.h" +#include "nm-device-vxlan.h" +#include "nm-device-wifi-p2p.h" +#include "nm-device-wifi.h" +#include "nm-device-wimax.h" +#include "nm-device-wireguard.h" +#include "nm-device-wpan.h" +#include "nm-device.h" +#include "nm-dhcp-config.h" +#include "nm-enum-types.h" +#include "nm-ethtool-utils.h" +#include "nm-ip-config.h" +#include "nm-keyfile.h" +#include "nm-object.h" +#include "nm-remote-connection.h" +#include "nm-setting-6lowpan.h" +#include "nm-setting-8021x.h" +#include "nm-setting-adsl.h" +#include "nm-setting-bluetooth.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-dcb.h" +#include "nm-setting-dummy.h" +#include "nm-setting-ethtool.h" +#include "nm-setting-generic.h" +#include "nm-setting-gsm.h" +#include "nm-setting-hostname.h" +#include "nm-setting-infiniband.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" +#include "nm-setting-ip-config.h" +#include "nm-setting-ip-tunnel.h" +#include "nm-setting-macsec.h" +#include "nm-setting-macvlan.h" +#include "nm-setting-match.h" +#include "nm-setting-olpc-mesh.h" +#include "nm-setting-ovs-bridge.h" +#include "nm-setting-ovs-interface.h" +#include "nm-setting-ovs-dpdk.h" +#include "nm-setting-ovs-patch.h" +#include "nm-setting-ovs-port.h" +#include "nm-setting-wifi-p2p.h" +#include "nm-setting-ppp.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-proxy.h" +#include "nm-setting-serial.h" +#include "nm-setting-sriov.h" +#include "nm-setting-tc-config.h" +#include "nm-setting-team.h" +#include "nm-setting-team-port.h" +#include "nm-setting-tun.h" +#include "nm-setting-user.h" +#include "nm-setting-veth.h" +#include "nm-setting-vlan.h" +#include "nm-setting-vpn.h" +#include "nm-setting-vrf.h" +#include "nm-setting-vxlan.h" +#include "nm-setting-wimax.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireguard.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-wpan.h" +#include "nm-setting.h" +#include "nm-simple-connection.h" +#include "nm-utils.h" +#include "nm-version.h" +#include "nm-vpn-connection.h" +#include "nm-vpn-dbus-interface.h" +#include "nm-vpn-editor.h" +#include "nm-vpn-editor-plugin.h" +#include "nm-vpn-plugin-info.h" +#include "nm-vpn-service-plugin.h" +#include "nm-wifi-p2p-peer.h" +#include "nm-wimax-nsp.h" + +#include "nm-autoptr.h" + +#if !defined(NETWORKMANAGER_COMPILATION) \ + && (!defined(NM_NO_INCLUDE_EXTRA_HEADERS) || !NM_NO_INCLUDE_EXTRA_HEADERS) + /* historically, NetworkManager.h drags in the following system headers. + * These are not strictly necessary and the user may wish to opt out from + * including them. */ + #include + #include + #include + #include +#endif + +#undef __NETWORKMANAGER_H_INSIDE__ + +#endif /* __NETWORKMANAGER_H__ */ diff --git a/src/libnm-client-public/nm-access-point.h b/src/libnm-client-public/nm-access-point.h new file mode 100644 index 0000000..0460ea0 --- /dev/null +++ b/src/libnm-client-public/nm-access-point.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. + */ + +#ifndef __NM_ACCESS_POINT_H__ +#define __NM_ACCESS_POINT_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_ACCESS_POINT (nm_access_point_get_type()) +#define NM_ACCESS_POINT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_ACCESS_POINT, NMAccessPoint)) +#define NM_ACCESS_POINT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_ACCESS_POINT, NMAccessPointClass)) +#define NM_IS_ACCESS_POINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_ACCESS_POINT)) +#define NM_IS_ACCESS_POINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_ACCESS_POINT)) +#define NM_ACCESS_POINT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_ACCESS_POINT, NMAccessPointClass)) + +#define NM_ACCESS_POINT_FLAGS "flags" +#define NM_ACCESS_POINT_WPA_FLAGS "wpa-flags" +#define NM_ACCESS_POINT_RSN_FLAGS "rsn-flags" +#define NM_ACCESS_POINT_SSID "ssid" +#define NM_ACCESS_POINT_BSSID "bssid" +#define NM_ACCESS_POINT_FREQUENCY "frequency" +#define NM_ACCESS_POINT_MODE "mode" +#define NM_ACCESS_POINT_MAX_BITRATE "max-bitrate" +#define NM_ACCESS_POINT_STRENGTH "strength" +#define NM_ACCESS_POINT_LAST_SEEN "last-seen" + +/* DEPRECATED */ +#define NM_ACCESS_POINT_HW_ADDRESS "hw-address" + +/** + * NMAccessPoint: + */ +typedef struct _NMAccessPointClass NMAccessPointClass; + +GType nm_access_point_get_type(void); + +NM80211ApFlags nm_access_point_get_flags(NMAccessPoint *ap); +NM80211ApSecurityFlags nm_access_point_get_wpa_flags(NMAccessPoint *ap); +NM80211ApSecurityFlags nm_access_point_get_rsn_flags(NMAccessPoint *ap); +GBytes * nm_access_point_get_ssid(NMAccessPoint *ap); +const char * nm_access_point_get_bssid(NMAccessPoint *ap); +guint32 nm_access_point_get_frequency(NMAccessPoint *ap); +NM80211Mode nm_access_point_get_mode(NMAccessPoint *ap); +guint32 nm_access_point_get_max_bitrate(NMAccessPoint *ap); +guint8 nm_access_point_get_strength(NMAccessPoint *ap); +NM_AVAILABLE_IN_1_2 +int nm_access_point_get_last_seen(NMAccessPoint *ap); + +GPtrArray *nm_access_point_filter_connections(NMAccessPoint *ap, const GPtrArray *connections); + +gboolean nm_access_point_connection_valid(NMAccessPoint *ap, NMConnection *connection); + +G_END_DECLS + +#endif /* __NM_ACCESS_POINT_H__ */ diff --git a/src/libnm-client-public/nm-active-connection.h b/src/libnm-client-public/nm-active-connection.h new file mode 100644 index 0000000..44b715c --- /dev/null +++ b/src/libnm-client-public/nm-active-connection.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#ifndef __NM_ACTIVE_CONNECTION_H__ +#define __NM_ACTIVE_CONNECTION_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_ACTIVE_CONNECTION (nm_active_connection_get_type()) +#define NM_ACTIVE_CONNECTION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnection)) +#define NM_ACTIVE_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass)) +#define NM_IS_ACTIVE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_ACTIVE_CONNECTION)) +#define NM_IS_ACTIVE_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_ACTIVE_CONNECTION)) +#define NM_ACTIVE_CONNECTION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass)) + +#define NM_ACTIVE_CONNECTION_CONNECTION "connection" +#define NM_ACTIVE_CONNECTION_ID "id" +#define NM_ACTIVE_CONNECTION_UUID "uuid" +#define NM_ACTIVE_CONNECTION_TYPE "type" +#define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT_PATH "specific-object-path" +#define NM_ACTIVE_CONNECTION_DEVICES "devices" +#define NM_ACTIVE_CONNECTION_STATE "state" +#define NM_ACTIVE_CONNECTION_STATE_FLAGS "state-flags" +#define NM_ACTIVE_CONNECTION_DEFAULT "default" +#define NM_ACTIVE_CONNECTION_IP4_CONFIG "ip4-config" +#define NM_ACTIVE_CONNECTION_DHCP4_CONFIG "dhcp4-config" +#define NM_ACTIVE_CONNECTION_DEFAULT6 "default6" +#define NM_ACTIVE_CONNECTION_IP6_CONFIG "ip6-config" +#define NM_ACTIVE_CONNECTION_DHCP6_CONFIG "dhcp6-config" +#define NM_ACTIVE_CONNECTION_VPN "vpn" +#define NM_ACTIVE_CONNECTION_MASTER "master" + +/** + * NMActiveConnection: + */ +typedef struct _NMActiveConnectionClass NMActiveConnectionClass; + +GType nm_active_connection_get_type(void); + +NMRemoteConnection *nm_active_connection_get_connection(NMActiveConnection *connection); +const char * nm_active_connection_get_id(NMActiveConnection *connection); +const char * nm_active_connection_get_uuid(NMActiveConnection *connection); +const char * nm_active_connection_get_connection_type(NMActiveConnection *connection); +const char * nm_active_connection_get_specific_object_path(NMActiveConnection *connection); +const GPtrArray * nm_active_connection_get_devices(NMActiveConnection *connection); +NMActiveConnectionState nm_active_connection_get_state(NMActiveConnection *connection); +NM_AVAILABLE_IN_1_10 +NMActivationStateFlags nm_active_connection_get_state_flags(NMActiveConnection *connection); +NM_AVAILABLE_IN_1_8 +NMActiveConnectionStateReason nm_active_connection_get_state_reason(NMActiveConnection *connection); +NMDevice * nm_active_connection_get_master(NMActiveConnection *connection); +gboolean nm_active_connection_get_default(NMActiveConnection *connection); +NMIPConfig * nm_active_connection_get_ip4_config(NMActiveConnection *connection); +NMDhcpConfig * nm_active_connection_get_dhcp4_config(NMActiveConnection *connection); +gboolean nm_active_connection_get_default6(NMActiveConnection *connection); +NMIPConfig * nm_active_connection_get_ip6_config(NMActiveConnection *connection); +NMDhcpConfig * nm_active_connection_get_dhcp6_config(NMActiveConnection *connection); +gboolean nm_active_connection_get_vpn(NMActiveConnection *connection); + +G_END_DECLS + +#endif /* __NM_ACTIVE_CONNECTION_H__ */ diff --git a/src/libnm-client-public/nm-autoptr.h b/src/libnm-client-public/nm-autoptr.h new file mode 100644 index 0000000..f37e2cf --- /dev/null +++ b/src/libnm-client-public/nm-autoptr.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_AUTOPTR_H__ +#define __NM_AUTOPTR_H__ + +/* + * Note that you might use this header with older versions of libnm + * that do not yet ship this header. In that case, copy the header + * into your source tree. + */ + +#include +#include + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMClient, g_object_unref) + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMAccessPoint, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMActiveConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMCheckpoint, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDevice, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDhcpConfig, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMIPConfig, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMObject, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMRemoteConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSetting, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSimpleConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMWifiP2PPeer, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMWimaxNsp, g_object_unref) + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDevice6Lowpan, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceAdsl, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceBond, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceBridge, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceBt, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceDummy, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceEthernet, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceGeneric, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceIPTunnel, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceInfiniband, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceMacsec, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceMacvlan, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceModem, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceOlpcMesh, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceOvsBridge, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceOvsInterface, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceOvsPort, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDevicePpp, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceTeam, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceTun, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceVeth, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceVlan, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceVxlan, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceWifi, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceWifiP2P, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceWimax, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceWireGuard, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceWpan, g_object_unref) + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSetting6Lowpan, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSetting8021x, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingAdsl, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingBluetooth, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingBond, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingBridge, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingBridgePort, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingCdma, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingDcb, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingDummy, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingEthtool, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingGeneric, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingGsm, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIP4Config, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIP6Config, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIPConfig, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIPTunnel, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingInfiniband, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingMacsec, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingMacvlan, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingMatch, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingOlpcMesh, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingOvsBridge, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingOvsInterface, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingOvsPatch, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingOvsPort, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingPpp, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingPppoe, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingProxy, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingSerial, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingSriov, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingTCConfig, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingTeam, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingTeamPort, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingTun, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingUser, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingVeth, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingVlan, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingVpn, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingVxlan, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingWifiP2P, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingWimax, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingWired, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingWireGuard, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingWireless, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingWirelessSecurity, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingWpan, g_object_unref) + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMVpnConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMVpnEditor, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMVpnEditorPlugin, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMVpnPluginInfo, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMVpnServicePlugin, g_object_unref) + +#endif + +#endif /* __NM_AUTOPTR_H__ */ diff --git a/src/libnm-client-public/nm-checkpoint.h b/src/libnm-client-public/nm-checkpoint.h new file mode 100644 index 0000000..3bc28f6 --- /dev/null +++ b/src/libnm-client-public/nm-checkpoint.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_CHECKPOINT_H__ +#define __NM_CHECKPOINT_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_CHECKPOINT (nm_checkpoint_get_type()) +#define NM_CHECKPOINT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_CHECKPOINT, NMCheckpoint)) +#define NM_CHECKPOINT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_CHECKPOINT, NMCheckpointClass)) +#define NM_IS_CHECKPOINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_CHECKPOINT)) +#define NM_IS_CHECKPOINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_CHECKPOINT)) +#define NM_CHECKPOINT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_CHECKPOINT, NMCheckpointClass)) + +#define NM_CHECKPOINT_DEVICES "devices" +#define NM_CHECKPOINT_CREATED "created" +#define NM_CHECKPOINT_ROLLBACK_TIMEOUT "rollback-timeout" + +/** + * NMCheckpoint: + */ +typedef struct _NMCheckpointClass NMCheckpointClass; + +GType nm_checkpoint_get_type(void); + +NM_AVAILABLE_IN_1_12 +const GPtrArray *nm_checkpoint_get_devices(NMCheckpoint *checkpoint); +NM_AVAILABLE_IN_1_12 +gint64 nm_checkpoint_get_created(NMCheckpoint *checkpoint); +NM_AVAILABLE_IN_1_12 +guint32 nm_checkpoint_get_rollback_timeout(NMCheckpoint *checkpoint); + +G_END_DECLS + +#endif /* __NM_CHECKPOINT_H__ */ diff --git a/src/libnm-client-public/nm-client.h b/src/libnm-client-public/nm-client.h new file mode 100644 index 0000000..5a97708 --- /dev/null +++ b/src/libnm-client-public/nm-client.h @@ -0,0 +1,490 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_CLIENT_H__ +#define __NM_CLIENT_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-types.h" + +G_BEGIN_DECLS + +/** + * NMClientInstanceFlags: + * @NM_CLIENT_INSTANCE_FLAGS_NONE: special value to indicate no flags. + * @NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS: by default, NMClient + * will fetch the permissions via "GetPermissions" and refetch them when + * "CheckPermissions" signal gets received. By setting this flag, this behavior + * can be disabled. You can toggle this flag to enable and disable automatic + * fetching of the permissions. Watch also nm_client_get_permissions_state() + * to know whether the permissions are up to date. + * + * Since: 1.24 + */ +typedef enum { /*< flags >*/ + NM_CLIENT_INSTANCE_FLAGS_NONE = 0, + NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS = 1, +} NMClientInstanceFlags; + +#define NM_TYPE_CLIENT (nm_client_get_type()) +#define NM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_CLIENT, NMClient)) +#define NM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_CLIENT, NMClientClass)) +#define NM_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_CLIENT)) +#define NM_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_CLIENT)) +#define NM_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_CLIENT, NMClientClass)) + +#define NM_CLIENT_VERSION "version" +#define NM_CLIENT_STATE "state" +#define NM_CLIENT_STARTUP "startup" +#define NM_CLIENT_NM_RUNNING "nm-running" +#define NM_CLIENT_DBUS_CONNECTION "dbus-connection" +#define NM_CLIENT_DBUS_NAME_OWNER "dbus-name-owner" +#define NM_CLIENT_INSTANCE_FLAGS "instance-flags" + +_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY +#define NM_CLIENT_NETWORKING_ENABLED "networking-enabled" + +_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY +#define NM_CLIENT_WIRELESS_ENABLED "wireless-enabled" +_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY +#define NM_CLIENT_WWAN_ENABLED "wwan-enabled" +_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY +#define NM_CLIENT_WIMAX_ENABLED "wimax-enabled" + +#define NM_CLIENT_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled" +#define NM_CLIENT_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled" +#define NM_CLIENT_WIMAX_HARDWARE_ENABLED "wimax-hardware-enabled" + +#define NM_CLIENT_ACTIVE_CONNECTIONS "active-connections" +#define NM_CLIENT_CONNECTIVITY "connectivity" +#define NM_CLIENT_CONNECTIVITY_CHECK_URI "connectivity-check-uri" +#define NM_CLIENT_CONNECTIVITY_CHECK_AVAILABLE "connectivity-check-available" + +_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY +#define NM_CLIENT_CONNECTIVITY_CHECK_ENABLED "connectivity-check-enabled" + +#define NM_CLIENT_PRIMARY_CONNECTION "primary-connection" +#define NM_CLIENT_ACTIVATING_CONNECTION "activating-connection" +#define NM_CLIENT_DEVICES "devices" +#define NM_CLIENT_ALL_DEVICES "all-devices" +#define NM_CLIENT_CONNECTIONS "connections" +#define NM_CLIENT_HOSTNAME "hostname" +#define NM_CLIENT_CAN_MODIFY "can-modify" +#define NM_CLIENT_METERED "metered" +#define NM_CLIENT_DNS_MODE "dns-mode" +#define NM_CLIENT_DNS_RC_MANAGER "dns-rc-manager" +#define NM_CLIENT_DNS_CONFIGURATION "dns-configuration" +#define NM_CLIENT_CHECKPOINTS "checkpoints" +#define NM_CLIENT_CAPABILITIES "capabilities" +#define NM_CLIENT_PERMISSIONS_STATE "permissions-state" + +#define NM_CLIENT_DEVICE_ADDED "device-added" +#define NM_CLIENT_DEVICE_REMOVED "device-removed" +#define NM_CLIENT_ANY_DEVICE_ADDED "any-device-added" +#define NM_CLIENT_ANY_DEVICE_REMOVED "any-device-removed" +#define NM_CLIENT_PERMISSION_CHANGED "permission-changed" +#define NM_CLIENT_CONNECTION_ADDED "connection-added" +#define NM_CLIENT_CONNECTION_REMOVED "connection-removed" +#define NM_CLIENT_ACTIVE_CONNECTION_ADDED "active-connection-added" +#define NM_CLIENT_ACTIVE_CONNECTION_REMOVED "active-connection-removed" + +/** + * NMClientError: + * @NM_CLIENT_ERROR_FAILED: unknown or unclassified error + * @NM_CLIENT_ERROR_MANAGER_NOT_RUNNING: an operation that requires NetworkManager + * failed because NetworkManager is not running + * @NM_CLIENT_ERROR_OBJECT_CREATION_FAILED: NetworkManager claimed that an + * operation succeeded, but the object that was allegedly created (eg, + * #NMRemoteConnection, #NMActiveConnection) was apparently destroyed before + * #NMClient could create a representation of it. + * + * Describes errors that may result from operations involving a #NMClient. + * + * D-Bus operations may also return errors from other domains, including + * #NMManagerError, #NMSettingsError, #NMAgentManagerError, and #NMConnectionError. + **/ +typedef enum { + NM_CLIENT_ERROR_FAILED = 0, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + NM_CLIENT_ERROR_OBJECT_CREATION_FAILED, +} NMClientError; + +#define NM_CLIENT_ERROR nm_client_error_quark() +GQuark nm_client_error_quark(void); + +/* DNS stuff */ + +typedef struct NMDnsEntry NMDnsEntry; + +NM_AVAILABLE_IN_1_6 +GType nm_dns_entry_get_type(void); +NM_AVAILABLE_IN_1_6 +void nm_dns_entry_unref(NMDnsEntry *entry); +NM_AVAILABLE_IN_1_6 +const char *nm_dns_entry_get_interface(NMDnsEntry *entry); +NM_AVAILABLE_IN_1_6 +const char *const *nm_dns_entry_get_nameservers(NMDnsEntry *entry); +NM_AVAILABLE_IN_1_6 +const char *const *nm_dns_entry_get_domains(NMDnsEntry *entry); +NM_AVAILABLE_IN_1_6 +int nm_dns_entry_get_priority(NMDnsEntry *entry); +NM_AVAILABLE_IN_1_6 +gboolean nm_dns_entry_get_vpn(NMDnsEntry *entry); + +/** + * NMClient: + */ +typedef struct _NMClientClass NMClientClass; + +GType nm_client_get_type(void); + +NMClient *nm_client_new(GCancellable *cancellable, GError **error); + +void +nm_client_new_async(GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); +NMClient *nm_client_new_finish(GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_24 +NMClientInstanceFlags nm_client_get_instance_flags(NMClient *self); + +NM_AVAILABLE_IN_1_22 +GDBusConnection *nm_client_get_dbus_connection(NMClient *client); + +NM_AVAILABLE_IN_1_22 +GMainContext *nm_client_get_main_context(NMClient *self); + +NM_AVAILABLE_IN_1_22 +GObject *nm_client_get_context_busy_watcher(NMClient *self); + +NM_AVAILABLE_IN_1_22 +const char *nm_client_get_dbus_name_owner(NMClient *client); + +const char *nm_client_get_version(NMClient *client); +NMState nm_client_get_state(NMClient *client); +gboolean nm_client_get_startup(NMClient *client); +gboolean nm_client_get_nm_running(NMClient *client); + +NMObject *nm_client_get_object_by_path(NMClient *client, const char *dbus_path); + +NM_AVAILABLE_IN_1_22 +NMMetered nm_client_get_metered(NMClient *client); + +gboolean nm_client_networking_get_enabled(NMClient *client); + +NM_AVAILABLE_IN_1_24 +const guint32 *nm_client_get_capabilities(NMClient *client, gsize *length); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_client_networking_set_enabled(NMClient *client, gboolean enabled, GError **error); + +gboolean nm_client_wireless_get_enabled(NMClient *client); + +_NM_DEPRECATED_SYNC_METHOD +void nm_client_wireless_set_enabled(NMClient *client, gboolean enabled); + +gboolean nm_client_wireless_hardware_get_enabled(NMClient *client); + +gboolean nm_client_wwan_get_enabled(NMClient *client); + +_NM_DEPRECATED_SYNC_METHOD +void nm_client_wwan_set_enabled(NMClient *client, gboolean enabled); + +gboolean nm_client_wwan_hardware_get_enabled(NMClient *client); + +NM_DEPRECATED_IN_1_22 +gboolean nm_client_wimax_get_enabled(NMClient *client); + +NM_DEPRECATED_IN_1_22 +_NM_DEPRECATED_SYNC_METHOD +void nm_client_wimax_set_enabled(NMClient *client, gboolean enabled); + +NM_DEPRECATED_IN_1_22 +gboolean nm_client_wimax_hardware_get_enabled(NMClient *client); + +NM_AVAILABLE_IN_1_10 +gboolean nm_client_connectivity_check_get_available(NMClient *client); + +NM_AVAILABLE_IN_1_10 +gboolean nm_client_connectivity_check_get_enabled(NMClient *client); + +NM_AVAILABLE_IN_1_10 +_NM_DEPRECATED_SYNC_METHOD +void nm_client_connectivity_check_set_enabled(NMClient *client, gboolean enabled); + +NM_AVAILABLE_IN_1_20 +const char *nm_client_connectivity_check_get_uri(NMClient *client); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_client_get_logging(NMClient *client, char **level, char **domains, GError **error); + +_NM_DEPRECATED_SYNC_METHOD +gboolean +nm_client_set_logging(NMClient *client, const char *level, const char *domains, GError **error); + +NMClientPermissionResult nm_client_get_permission_result(NMClient * client, + NMClientPermission permission); + +NM_AVAILABLE_IN_1_24 +NMTernary nm_client_get_permissions_state(NMClient *self); + +NMConnectivityState nm_client_get_connectivity(NMClient *client); + +_NM_DEPRECATED_SYNC_METHOD +NM_DEPRECATED_IN_1_22 +NMConnectivityState +nm_client_check_connectivity(NMClient *client, GCancellable *cancellable, GError **error); + +void nm_client_check_connectivity_async(NMClient * client, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMConnectivityState +nm_client_check_connectivity_finish(NMClient *client, GAsyncResult *result, GError **error); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_client_save_hostname(NMClient * client, + const char * hostname, + GCancellable *cancellable, + GError ** error); + +void nm_client_save_hostname_async(NMClient * client, + const char * hostname, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_client_save_hostname_finish(NMClient *client, GAsyncResult *result, GError **error); + +/* Devices */ + +const GPtrArray *nm_client_get_devices(NMClient *client); +NM_AVAILABLE_IN_1_2 +const GPtrArray *nm_client_get_all_devices(NMClient *client); +NMDevice * nm_client_get_device_by_path(NMClient *client, const char *object_path); +NMDevice * nm_client_get_device_by_iface(NMClient *client, const char *iface); + +/* Active Connections */ + +const GPtrArray *nm_client_get_active_connections(NMClient *client); + +NMActiveConnection *nm_client_get_primary_connection(NMClient *client); +NMActiveConnection *nm_client_get_activating_connection(NMClient *client); + +void nm_client_activate_connection_async(NMClient * client, + NMConnection * connection, + NMDevice * device, + const char * specific_object, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMActiveConnection * +nm_client_activate_connection_finish(NMClient *client, GAsyncResult *result, GError **error); + +void nm_client_add_and_activate_connection_async(NMClient * client, + NMConnection * partial, + NMDevice * device, + const char * specific_object, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMActiveConnection *nm_client_add_and_activate_connection_finish(NMClient * client, + GAsyncResult *result, + GError ** error); + +NM_AVAILABLE_IN_1_16 +void nm_client_add_and_activate_connection2(NMClient * client, + NMConnection * partial, + NMDevice * device, + const char * specific_object, + GVariant * options, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_16 +NMActiveConnection *nm_client_add_and_activate_connection2_finish(NMClient * client, + GAsyncResult *result, + GVariant ** out_result, + GError ** error); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_client_deactivate_connection(NMClient * client, + NMActiveConnection *active, + GCancellable * cancellable, + GError ** error); + +void nm_client_deactivate_connection_async(NMClient * client, + NMActiveConnection *active, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean +nm_client_deactivate_connection_finish(NMClient *client, GAsyncResult *result, GError **error); + +/* Connections */ + +const GPtrArray *nm_client_get_connections(NMClient *client); + +NMRemoteConnection *nm_client_get_connection_by_id(NMClient *client, const char *id); +NMRemoteConnection *nm_client_get_connection_by_path(NMClient *client, const char *path); +NMRemoteConnection *nm_client_get_connection_by_uuid(NMClient *client, const char *uuid); + +void nm_client_add_connection_async(NMClient * client, + NMConnection * connection, + gboolean save_to_disk, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMRemoteConnection * +nm_client_add_connection_finish(NMClient *client, GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_20 +void nm_client_add_connection2(NMClient * client, + GVariant * settings, + NMSettingsAddConnection2Flags flags, + GVariant * args, + gboolean ignore_out_result, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +NM_AVAILABLE_IN_1_20 +NMRemoteConnection *nm_client_add_connection2_finish(NMClient * client, + GAsyncResult *result, + GVariant ** out_result, + GError ** error); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_client_load_connections(NMClient * client, + char ** filenames, + char *** failures, + GCancellable *cancellable, + GError ** error); + +void nm_client_load_connections_async(NMClient * client, + char ** filenames, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_client_load_connections_finish(NMClient * client, + char *** failures, + GAsyncResult *result, + GError ** error); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_client_reload_connections(NMClient *client, GCancellable *cancellable, GError **error); + +void nm_client_reload_connections_async(NMClient * client, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean +nm_client_reload_connections_finish(NMClient *client, GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_6 +const char *nm_client_get_dns_mode(NMClient *client); +NM_AVAILABLE_IN_1_6 +const char *nm_client_get_dns_rc_manager(NMClient *client); +NM_AVAILABLE_IN_1_6 +const GPtrArray *nm_client_get_dns_configuration(NMClient *client); + +NM_AVAILABLE_IN_1_12 +const GPtrArray *nm_client_get_checkpoints(NMClient *client); + +NM_AVAILABLE_IN_1_12 +void nm_client_checkpoint_create(NMClient * client, + const GPtrArray * devices, + guint32 rollback_timeout, + NMCheckpointCreateFlags flags, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_12 +NMCheckpoint * +nm_client_checkpoint_create_finish(NMClient *client, GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_12 +void nm_client_checkpoint_destroy(NMClient * client, + const char * checkpoint_path, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_12 +gboolean +nm_client_checkpoint_destroy_finish(NMClient *client, GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_12 +void nm_client_checkpoint_rollback(NMClient * client, + const char * checkpoint_path, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_12 +GHashTable * +nm_client_checkpoint_rollback_finish(NMClient *client, GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_12 +void nm_client_checkpoint_adjust_rollback_timeout(NMClient * client, + const char * checkpoint_path, + guint32 add_timeout, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +NM_AVAILABLE_IN_1_12 +gboolean nm_client_checkpoint_adjust_rollback_timeout_finish(NMClient * client, + GAsyncResult *result, + GError ** error); + +NM_AVAILABLE_IN_1_22 +void nm_client_reload(NMClient * client, + NMManagerReloadFlags flags, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_22 +gboolean nm_client_reload_finish(NMClient *client, GAsyncResult *result, GError **error); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_24 +void nm_client_dbus_call(NMClient * client, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + const GVariantType *reply_type, + int timeout_msec, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +NM_AVAILABLE_IN_1_24 +GVariant *nm_client_dbus_call_finish(NMClient *client, GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_24 +void nm_client_dbus_set_property(NMClient * client, + const char * object_path, + const char * interface_name, + const char * property_name, + GVariant * value, + int timeout_msec, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +NM_AVAILABLE_IN_1_24 +gboolean nm_client_dbus_set_property_finish(NMClient *client, GAsyncResult *result, GError **error); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_30 +void nm_utils_print(int output_mode, const char *msg); + +G_END_DECLS + +#endif /* __NM_CLIENT_H__ */ diff --git a/src/libnm-client-public/nm-device-6lowpan.h b/src/libnm-client-public/nm-device-6lowpan.h new file mode 100644 index 0000000..d46e6db --- /dev/null +++ b/src/libnm-client-public/nm-device-6lowpan.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_6LOWPAN_H__ +#define __NM_DEVICE_6LOWPAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_6LOWPAN (nm_device_6lowpan_get_type()) +#define NM_DEVICE_6LOWPAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_6LOWPAN, NMDevice6Lowpan)) +#define NM_DEVICE_6LOWPAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_6LOWPAN, NMDevice6LowpanClass)) +#define NM_IS_DEVICE_6LOWPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_6LOWPAN)) +#define NM_IS_DEVICE_6LOWPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_6LOWPAN)) +#define NM_DEVICE_6LOWPAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_6LOWPAN, NMDevice6LowpanClass)) + +#define NM_DEVICE_6LOWPAN_PARENT "parent" +#define NM_DEVICE_6LOWPAN_HW_ADDRESS "hw-address" + +/** + * NMDevice6Lowpan: + */ +typedef struct _NMDevice6LowpanClass NMDevice6LowpanClass; + +NM_AVAILABLE_IN_1_14 +GType nm_device_6lowpan_get_type(void); + +NM_AVAILABLE_IN_1_14 +NMDevice *nm_device_6lowpan_get_parent(NMDevice6Lowpan *device); + +NM_AVAILABLE_IN_1_14 +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_6lowpan_get_hw_address(NMDevice6Lowpan *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_6LOWPAN_H__ */ diff --git a/src/libnm-client-public/nm-device-adsl.h b/src/libnm-client-public/nm-device-adsl.h new file mode 100644 index 0000000..92eaf36 --- /dev/null +++ b/src/libnm-client-public/nm-device-adsl.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 Pantelis Koukousoulas + */ + +#ifndef __NM_DEVICE_ADSL_H__ +#define __NM_DEVICE_ADSL_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_ADSL (nm_device_adsl_get_type()) +#define NM_DEVICE_ADSL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_ADSL, NMDeviceAdsl)) +#define NM_DEVICE_ADSL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass)) +#define NM_IS_DEVICE_ADSL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_ADSL)) +#define NM_IS_DEVICE_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_ADSL)) +#define NM_DEVICE_ADSL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass)) + +#define NM_DEVICE_ADSL_CARRIER "carrier" + +/** + * NMDeviceAdsl: + */ +typedef struct _NMDeviceAdslClass NMDeviceAdslClass; + +GType nm_device_adsl_get_type(void); + +gboolean nm_device_adsl_get_carrier(NMDeviceAdsl *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_ADSL_H__ */ diff --git a/src/libnm-client-public/nm-device-bond.h b/src/libnm-client-public/nm-device-bond.h new file mode 100644 index 0000000..91c023a --- /dev/null +++ b/src/libnm-client-public/nm-device-bond.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_BOND_H__ +#define __NM_DEVICE_BOND_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_BOND (nm_device_bond_get_type()) +#define NM_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_BOND, NMDeviceBond)) +#define NM_DEVICE_BOND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) +#define NM_IS_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_BOND)) +#define NM_IS_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_BOND)) +#define NM_DEVICE_BOND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) + +#define NM_DEVICE_BOND_HW_ADDRESS "hw-address" +#define NM_DEVICE_BOND_CARRIER "carrier" +#define NM_DEVICE_BOND_SLAVES "slaves" + +/** + * NMDeviceBond: + */ +typedef struct _NMDeviceBondClass NMDeviceBondClass; + +GType nm_device_bond_get_type(void); + +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_bond_get_hw_address(NMDeviceBond *device); + +gboolean nm_device_bond_get_carrier(NMDeviceBond *device); +const GPtrArray *nm_device_bond_get_slaves(NMDeviceBond *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_BOND_H__ */ diff --git a/src/libnm-client-public/nm-device-bridge.h b/src/libnm-client-public/nm-device-bridge.h new file mode 100644 index 0000000..a6c5065 --- /dev/null +++ b/src/libnm-client-public/nm-device-bridge.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_BRIDGE_H__ +#define __NM_DEVICE_BRIDGE_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_BRIDGE (nm_device_bridge_get_type()) +#define NM_DEVICE_BRIDGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridge)) +#define NM_DEVICE_BRIDGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) +#define NM_IS_DEVICE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_BRIDGE)) +#define NM_IS_DEVICE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_BRIDGE)) +#define NM_DEVICE_BRIDGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) + +#define NM_DEVICE_BRIDGE_HW_ADDRESS "hw-address" +#define NM_DEVICE_BRIDGE_CARRIER "carrier" +#define NM_DEVICE_BRIDGE_SLAVES "slaves" + +/** + * NMDeviceBridge: + */ +typedef struct _NMDeviceBridgeClass NMDeviceBridgeClass; + +GType nm_device_bridge_get_type(void); + +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_bridge_get_hw_address(NMDeviceBridge *device); + +gboolean nm_device_bridge_get_carrier(NMDeviceBridge *device); +const GPtrArray *nm_device_bridge_get_slaves(NMDeviceBridge *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_BRIDGE_H__ */ diff --git a/src/libnm-client-public/nm-device-bt.h b/src/libnm-client-public/nm-device-bt.h new file mode 100644 index 0000000..a7cfc79 --- /dev/null +++ b/src/libnm-client-public/nm-device-bt.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 - 2012 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#ifndef __NM_DEVICE_BT_H__ +#define __NM_DEVICE_BT_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_BT (nm_device_bt_get_type()) +#define NM_DEVICE_BT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_BT, NMDeviceBt)) +#define NM_DEVICE_BT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) +#define NM_IS_DEVICE_BT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_BT)) +#define NM_IS_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_BT)) +#define NM_DEVICE_BT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) + +#define NM_DEVICE_BT_HW_ADDRESS "hw-address" +#define NM_DEVICE_BT_NAME "name" +#define NM_DEVICE_BT_CAPABILITIES "bt-capabilities" + +/** + * NMDeviceBt: + */ +typedef struct _NMDeviceBtClass NMDeviceBtClass; + +GType nm_device_bt_get_type(void); + +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_bt_get_hw_address(NMDeviceBt *device); + +const char *nm_device_bt_get_name(NMDeviceBt *device); + +NMBluetoothCapabilities nm_device_bt_get_capabilities(NMDeviceBt *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_BT_H__ */ diff --git a/src/libnm-client-public/nm-device-dummy.h b/src/libnm-client-public/nm-device-dummy.h new file mode 100644 index 0000000..ad34b65 --- /dev/null +++ b/src/libnm-client-public/nm-device-dummy.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_DUMMY_H__ +#define __NM_DEVICE_DUMMY_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_DUMMY (nm_device_dummy_get_type()) +#define NM_DEVICE_DUMMY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_DUMMY, NMDeviceDummy)) +#define NM_DEVICE_DUMMY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_DUMMY, NMDeviceDummyClass)) +#define NM_IS_DEVICE_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_DUMMY)) +#define NM_IS_DEVICE_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_DUMMY)) +#define NM_DEVICE_DUMMY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_DUMMY, NMDeviceDummyClass)) + +#define NM_DEVICE_DUMMY_HW_ADDRESS "hw-address" + +/** + * NMDeviceDummy: + */ +typedef struct _NMDeviceDummyClass NMDeviceDummyClass; + +GType nm_device_dummy_get_type(void); + +NM_AVAILABLE_IN_1_10 +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_dummy_get_hw_address(NMDeviceDummy *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_DUMMY_H__ */ diff --git a/src/libnm-client-public/nm-device-ethernet.h b/src/libnm-client-public/nm-device-ethernet.h new file mode 100644 index 0000000..877930e --- /dev/null +++ b/src/libnm-client-public/nm-device-ethernet.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_ETHERNET_H__ +#define __NM_DEVICE_ETHERNET_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_ETHERNET (nm_device_ethernet_get_type()) +#define NM_DEVICE_ETHERNET(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernet)) +#define NM_DEVICE_ETHERNET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) +#define NM_IS_DEVICE_ETHERNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_ETHERNET)) +#define NM_IS_DEVICE_ETHERNET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_ETHERNET)) +#define NM_DEVICE_ETHERNET_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) + +#define NM_DEVICE_ETHERNET_HW_ADDRESS "hw-address" +#define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address" +#define NM_DEVICE_ETHERNET_SPEED "speed" +#define NM_DEVICE_ETHERNET_CARRIER "carrier" +#define NM_DEVICE_ETHERNET_S390_SUBCHANNELS "s390-subchannels" + +/** + * NMDeviceEthernet: + */ +typedef struct _NMDeviceEthernetClass NMDeviceEthernetClass; + +GType nm_device_ethernet_get_type(void); + +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_ethernet_get_hw_address(NMDeviceEthernet *device); + +const char *nm_device_ethernet_get_permanent_hw_address(NMDeviceEthernet *device); +guint32 nm_device_ethernet_get_speed(NMDeviceEthernet *device); +gboolean nm_device_ethernet_get_carrier(NMDeviceEthernet *device); +NM_AVAILABLE_IN_1_2 +const char *const *nm_device_ethernet_get_s390_subchannels(NMDeviceEthernet *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_ETHERNET_H__ */ diff --git a/src/libnm-client-public/nm-device-generic.h b/src/libnm-client-public/nm-device-generic.h new file mode 100644 index 0000000..5c1f308 --- /dev/null +++ b/src/libnm-client-public/nm-device-generic.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_GENERIC_H__ +#define __NM_DEVICE_GENERIC_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_GENERIC (nm_device_generic_get_type()) +#define NM_DEVICE_GENERIC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGeneric)) +#define NM_DEVICE_GENERIC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) +#define NM_IS_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_GENERIC)) +#define NM_IS_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_GENERIC)) +#define NM_DEVICE_GENERIC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) + +#define NM_DEVICE_GENERIC_HW_ADDRESS "hw-address" +#define NM_DEVICE_GENERIC_TYPE_DESCRIPTION "type-description" + +/** + * NMDeviceGeneric: + */ +typedef struct _NMDeviceGenericClass NMDeviceGenericClass; + +GType nm_device_generic_get_type(void); + +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_generic_get_hw_address(NMDeviceGeneric *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_GENERIC_H__ */ diff --git a/src/libnm-client-public/nm-device-infiniband.h b/src/libnm-client-public/nm-device-infiniband.h new file mode 100644 index 0000000..be9a26e --- /dev/null +++ b/src/libnm-client-public/nm-device-infiniband.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_INFINIBAND_H__ +#define __NM_DEVICE_INFINIBAND_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_INFINIBAND (nm_device_infiniband_get_type()) +#define NM_DEVICE_INFINIBAND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfiniband)) +#define NM_DEVICE_INFINIBAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) +#define NM_IS_DEVICE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_INFINIBAND)) +#define NM_IS_DEVICE_INFINIBAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_INFINIBAND)) +#define NM_DEVICE_INFINIBAND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) + +#define NM_DEVICE_INFINIBAND_HW_ADDRESS "hw-address" +#define NM_DEVICE_INFINIBAND_CARRIER "carrier" + +/** + * NMDeviceInfiniband: + */ +typedef struct _NMDeviceInfinibandClass NMDeviceInfinibandClass; + +GType nm_device_infiniband_get_type(void); + +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_infiniband_get_hw_address(NMDeviceInfiniband *device); + +gboolean nm_device_infiniband_get_carrier(NMDeviceInfiniband *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_INFINIBAND_H__ */ diff --git a/src/libnm-client-public/nm-device-ip-tunnel.h b/src/libnm-client-public/nm-device-ip-tunnel.h new file mode 100644 index 0000000..0d9c3e5 --- /dev/null +++ b/src/libnm-client-public/nm-device-ip-tunnel.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_IP_TUNNEL_H__ +#define __NM_DEVICE_IP_TUNNEL_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" +#include "nm-setting-ip-tunnel.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_IP_TUNNEL (nm_device_ip_tunnel_get_type()) +#define NM_DEVICE_IP_TUNNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnel)) +#define NM_DEVICE_IP_TUNNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelClass)) +#define NM_IS_DEVICE_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_IP_TUNNEL)) +#define NM_IS_DEVICE_IP_TUNNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_IP_TUNNEL)) +#define NM_DEVICE_IP_TUNNEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelClass)) + +#define NM_DEVICE_IP_TUNNEL_MODE "mode" +#define NM_DEVICE_IP_TUNNEL_PARENT "parent" +#define NM_DEVICE_IP_TUNNEL_LOCAL "local" +#define NM_DEVICE_IP_TUNNEL_REMOTE "remote" +#define NM_DEVICE_IP_TUNNEL_TTL "ttl" +#define NM_DEVICE_IP_TUNNEL_TOS "tos" +#define NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY "path-mtu-discovery" +#define NM_DEVICE_IP_TUNNEL_INPUT_KEY "input-key" +#define NM_DEVICE_IP_TUNNEL_OUTPUT_KEY "output-key" +#define NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT "encapsulation-limit" +#define NM_DEVICE_IP_TUNNEL_FLOW_LABEL "flow-label" +#define NM_DEVICE_IP_TUNNEL_FLAGS "flags" + +/** + * NMDeviceIPTunnel: + */ +typedef struct _NMDeviceIPTunnelClass NMDeviceIPTunnelClass; + +NM_AVAILABLE_IN_1_2 +GType nm_device_ip_tunnel_get_type(void); + +NM_AVAILABLE_IN_1_2 +NMDevice *nm_device_ip_tunnel_get_parent(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +NMIPTunnelMode nm_device_ip_tunnel_get_mode(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +const char *nm_device_ip_tunnel_get_local(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +const char *nm_device_ip_tunnel_get_remote(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +guint8 nm_device_ip_tunnel_get_ttl(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +guint8 nm_device_ip_tunnel_get_tos(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_ip_tunnel_get_path_mtu_discovery(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +const char *nm_device_ip_tunnel_get_input_key(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +const char *nm_device_ip_tunnel_get_output_key(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +guint8 nm_device_ip_tunnel_get_encapsulation_limit(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_ip_tunnel_get_flow_label(NMDeviceIPTunnel *device); +NM_AVAILABLE_IN_1_12 +NMIPTunnelFlags nm_device_ip_tunnel_get_flags(NMDeviceIPTunnel *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_IP_TUNNEL_H__ */ diff --git a/src/libnm-client-public/nm-device-macsec.h b/src/libnm-client-public/nm-device-macsec.h new file mode 100644 index 0000000..5a03660 --- /dev/null +++ b/src/libnm-client-public/nm-device-macsec.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_MACSEC_H__ +#define __NM_DEVICE_MACSEC_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_MACSEC (nm_device_macsec_get_type()) +#define NM_DEVICE_MACSEC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsec)) +#define NM_DEVICE_MACSEC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecClass)) +#define NM_IS_DEVICE_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_MACSEC)) +#define NM_IS_DEVICE_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_MACSEC)) +#define NM_DEVICE_MACSEC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecClass)) + +#define NM_DEVICE_MACSEC_PARENT "parent" +#define NM_DEVICE_MACSEC_HW_ADDRESS "hw-address" +#define NM_DEVICE_MACSEC_SCI "sci" +#define NM_DEVICE_MACSEC_ICV_LENGTH "icv-length" +#define NM_DEVICE_MACSEC_CIPHER_SUITE "cipher-suite" +#define NM_DEVICE_MACSEC_WINDOW "window" +#define NM_DEVICE_MACSEC_ENCODING_SA "encoding-sa" +#define NM_DEVICE_MACSEC_VALIDATION "validation" +#define NM_DEVICE_MACSEC_ENCRYPT "encrypt" +#define NM_DEVICE_MACSEC_PROTECT "protect" +#define NM_DEVICE_MACSEC_INCLUDE_SCI "include-sci" +#define NM_DEVICE_MACSEC_ES "es" +#define NM_DEVICE_MACSEC_SCB "scb" +#define NM_DEVICE_MACSEC_REPLAY_PROTECT "replay-protect" + +/** + * NMDeviceMacsec: + */ +typedef struct _NMDeviceMacsecClass NMDeviceMacsecClass; + +NM_AVAILABLE_IN_1_6 +GType nm_device_macsec_get_type(void); + +NM_AVAILABLE_IN_1_6 +NMDevice *nm_device_macsec_get_parent(NMDeviceMacsec *device); + +NM_AVAILABLE_IN_1_6 +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_macsec_get_hw_address(NMDeviceMacsec *device); + +NM_AVAILABLE_IN_1_6 +guint64 nm_device_macsec_get_sci(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +guint8 nm_device_macsec_get_icv_length(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +guint64 nm_device_macsec_get_cipher_suite(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +guint nm_device_macsec_get_window(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +guint8 nm_device_macsec_get_encoding_sa(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +const char *nm_device_macsec_get_validation(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +gboolean nm_device_macsec_get_encrypt(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +gboolean nm_device_macsec_get_protect(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +gboolean nm_device_macsec_get_include_sci(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +gboolean nm_device_macsec_get_es(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +gboolean nm_device_macsec_get_scb(NMDeviceMacsec *device); +NM_AVAILABLE_IN_1_6 +gboolean nm_device_macsec_get_replay_protect(NMDeviceMacsec *device); +G_END_DECLS + +#endif /* __NM_DEVICE_MACSEC_H__ */ diff --git a/src/libnm-client-public/nm-device-macvlan.h b/src/libnm-client-public/nm-device-macvlan.h new file mode 100644 index 0000000..b8d2706 --- /dev/null +++ b/src/libnm-client-public/nm-device-macvlan.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_MACVLAN_H__ +#define __NM_DEVICE_MACVLAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_MACVLAN (nm_device_macvlan_get_type()) +#define NM_DEVICE_MACVLAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlan)) +#define NM_DEVICE_MACVLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass)) +#define NM_IS_DEVICE_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_MACVLAN)) +#define NM_IS_DEVICE_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_MACVLAN)) +#define NM_DEVICE_MACVLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass)) + +#define NM_DEVICE_MACVLAN_PARENT "parent" +#define NM_DEVICE_MACVLAN_MODE "mode" +#define NM_DEVICE_MACVLAN_NO_PROMISC "no-promisc" +#define NM_DEVICE_MACVLAN_TAP "tap" +#define NM_DEVICE_MACVLAN_HW_ADDRESS "hw-address" + +/** + * NMDeviceMacvlan: + */ +typedef struct _NMDeviceMacvlanClass NMDeviceMacvlanClass; + +NM_AVAILABLE_IN_1_2 +GType nm_device_macvlan_get_type(void); + +NM_AVAILABLE_IN_1_2 +NMDevice *nm_device_macvlan_get_parent(NMDeviceMacvlan *device); +NM_AVAILABLE_IN_1_2 +const char *nm_device_macvlan_get_mode(NMDeviceMacvlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_macvlan_get_no_promisc(NMDeviceMacvlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_macvlan_get_tap(NMDeviceMacvlan *device); + +NM_AVAILABLE_IN_1_2 +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_macvlan_get_hw_address(NMDeviceMacvlan *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_MACVLAN_H__ */ diff --git a/src/libnm-client-public/nm-device-modem.h b/src/libnm-client-public/nm-device-modem.h new file mode 100644 index 0000000..eced137 --- /dev/null +++ b/src/libnm-client-public/nm-device-modem.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2012 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#ifndef __NM_DEVICE_MODEM_H__ +#define __NM_DEVICE_MODEM_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_MODEM (nm_device_modem_get_type()) +#define NM_DEVICE_MODEM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModem)) +#define NM_DEVICE_MODEM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass)) +#define NM_IS_DEVICE_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_MODEM)) +#define NM_IS_DEVICE_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_MODEM)) +#define NM_DEVICE_MODEM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass)) + +#define NM_DEVICE_MODEM_MODEM_CAPABILITIES "modem-capabilities" +#define NM_DEVICE_MODEM_CURRENT_CAPABILITIES "current-capabilities" +#define NM_DEVICE_MODEM_DEVICE_ID "device-id" +#define NM_DEVICE_MODEM_OPERATOR_CODE "operator-code" +#define NM_DEVICE_MODEM_APN "apn" + +/** + * NMDeviceModem: + */ +typedef struct _NMDeviceModemClass NMDeviceModemClass; + +GType nm_device_modem_get_type(void); + +NMDeviceModemCapabilities nm_device_modem_get_modem_capabilities(NMDeviceModem *self); +NMDeviceModemCapabilities nm_device_modem_get_current_capabilities(NMDeviceModem *self); + +NM_AVAILABLE_IN_1_20 +const char *nm_device_modem_get_device_id(NMDeviceModem *self); + +NM_AVAILABLE_IN_1_20 +const char *nm_device_modem_get_operator_code(NMDeviceModem *self); + +NM_AVAILABLE_IN_1_20 +const char *nm_device_modem_get_apn(NMDeviceModem *self); + +G_END_DECLS + +#endif /* __NM_DEVICE_MODEM_H__ */ diff --git a/src/libnm-client-public/nm-device-olpc-mesh.h b/src/libnm-client-public/nm-device-olpc-mesh.h new file mode 100644 index 0000000..d8b835f --- /dev/null +++ b/src/libnm-client-public/nm-device-olpc-mesh.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_OLPC_MESH_H__ +#define __NM_DEVICE_OLPC_MESH_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_OLPC_MESH (nm_device_olpc_mesh_get_type()) +#define NM_DEVICE_OLPC_MESH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMesh)) +#define NM_DEVICE_OLPC_MESH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) +#define NM_IS_DEVICE_OLPC_MESH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_OLPC_MESH)) +#define NM_IS_DEVICE_OLPC_MESH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_OLPC_MESH)) +#define NM_DEVICE_OLPC_MESH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) + +#define NM_DEVICE_OLPC_MESH_HW_ADDRESS "hw-address" +#define NM_DEVICE_OLPC_MESH_COMPANION "companion" +#define NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL "active-channel" + +/** + * NMDeviceOlpcMesh: + */ +typedef struct _NMDeviceOlpcMeshClass NMDeviceOlpcMeshClass; + +GType nm_device_olpc_mesh_get_type(void); + +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_olpc_mesh_get_hw_address(NMDeviceOlpcMesh *device); + +NMDeviceWifi *nm_device_olpc_mesh_get_companion(NMDeviceOlpcMesh *device); +guint32 nm_device_olpc_mesh_get_active_channel(NMDeviceOlpcMesh *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_OLPC_MESH_H__ */ diff --git a/src/libnm-client-public/nm-device-ovs-bridge.h b/src/libnm-client-public/nm-device-ovs-bridge.h new file mode 100644 index 0000000..50754e1 --- /dev/null +++ b/src/libnm-client-public/nm-device-ovs-bridge.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017, 2018 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_OVS_BRIDGE_H__ +#define __NM_DEVICE_OVS_BRIDGE_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_OVS_BRIDGE (nm_device_ovs_bridge_get_type()) +#define NM_DEVICE_OVS_BRIDGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridge)) +#define NM_DEVICE_OVS_BRIDGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridgeClass)) +#define NM_IS_DEVICE_OVS_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_OVS_BRIDGE)) +#define NM_IS_DEVICE_OVS_BRIDGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_OVS_BRIDGE)) +#define NM_DEVICE_OVS_BRIDGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridgeClass)) + +#define NM_DEVICE_OVS_BRIDGE_SLAVES "slaves" + +/** + * NMDeviceOvsBridge: + */ +typedef struct _NMDeviceOvsBridgeClass NMDeviceOvsBridgeClass; + +NM_AVAILABLE_IN_1_10 +GType nm_device_ovs_bridge_get_type(void); + +NM_AVAILABLE_IN_1_14 +const GPtrArray *nm_device_ovs_bridge_get_slaves(NMDeviceOvsBridge *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_OVS_BRIDGE_H__ */ diff --git a/src/libnm-client-public/nm-device-ovs-interface.h b/src/libnm-client-public/nm-device-ovs-interface.h new file mode 100644 index 0000000..6767ad4 --- /dev/null +++ b/src/libnm-client-public/nm-device-ovs-interface.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_OVS_INTERFACE_H__ +#define __NM_DEVICE_OVS_INTERFACE_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_OVS_INTERFACE (nm_device_ovs_interface_get_type()) +#define NM_DEVICE_OVS_INTERFACE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterface)) +#define NM_DEVICE_OVS_INTERFACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterfaceClass)) +#define NM_IS_DEVICE_OVS_INTERFACE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_OVS_INTERFACE)) +#define NM_IS_DEVICE_OVS_INTERFACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_OVS_INTERFACE)) +#define NM_DEVICE_OVS_INTERFACE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterfaceClass)) + +/** + * NMDeviceOvsInterface: + */ +typedef struct _NMDeviceOvsInterfaceClass NMDeviceOvsInterfaceClass; + +NM_AVAILABLE_IN_1_10 +GType nm_device_ovs_interface_get_type(void); + +G_END_DECLS + +#endif /* __NM_DEVICE_OVS_INTERFACE_H__ */ diff --git a/src/libnm-client-public/nm-device-ovs-port.h b/src/libnm-client-public/nm-device-ovs-port.h new file mode 100644 index 0000000..1f69641 --- /dev/null +++ b/src/libnm-client-public/nm-device-ovs-port.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017, 2018 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_OVS_PORT_H__ +#define __NM_DEVICE_OVS_PORT_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_OVS_PORT (nm_device_ovs_port_get_type()) +#define NM_DEVICE_OVS_PORT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPort)) +#define NM_DEVICE_OVS_PORT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPortClass)) +#define NM_IS_DEVICE_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_OVS_PORT)) +#define NM_IS_DEVICE_OVS_PORT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_OVS_PORT)) +#define NM_DEVICE_OVS_PORT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPortClass)) + +#define NM_DEVICE_OVS_PORT_SLAVES "slaves" + +/** + * NMDeviceOvsPort: + */ +typedef struct _NMDeviceOvsPortClass NMDeviceOvsPortClass; + +NM_AVAILABLE_IN_1_10 +GType nm_device_ovs_port_get_type(void); + +NM_AVAILABLE_IN_1_14 +const GPtrArray *nm_device_ovs_port_get_slaves(NMDeviceOvsPort *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_OVS_PORT_H__ */ diff --git a/src/libnm-client-public/nm-device-ppp.h b/src/libnm-client-public/nm-device-ppp.h new file mode 100644 index 0000000..7bd282d --- /dev/null +++ b/src/libnm-client-public/nm-device-ppp.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_PPP_H__ +#define __NM_DEVICE_PPP_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_PPP (nm_device_ppp_get_type()) +#define NM_DEVICE_PPP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_PPP, NMDevicePpp)) +#define NM_DEVICE_PPP_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_PPP, NMDevicePppClass)) +#define NM_IS_DEVICE_PPP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_PPP)) +#define NM_IS_DEVICE_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_PPP)) +#define NM_DEVICE_PPP_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_PPP, NMDevicePppClass)) + +/** + * NMDevicePpp: + */ +typedef struct _NMDevicePppClass NMDevicePppClass; + +GType nm_device_ppp_get_type(void); + +G_END_DECLS + +#endif /* __NM_DEVICE_PPP_H__ */ diff --git a/src/libnm-client-public/nm-device-team.h b/src/libnm-client-public/nm-device-team.h new file mode 100644 index 0000000..921353b --- /dev/null +++ b/src/libnm-client-public/nm-device-team.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Jiri Pirko + */ + +#ifndef __NM_DEVICE_TEAM_H__ +#define __NM_DEVICE_TEAM_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_TEAM (nm_device_team_get_type()) +#define NM_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeam)) +#define NM_DEVICE_TEAM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) +#define NM_IS_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_TEAM)) +#define NM_IS_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_TEAM)) +#define NM_DEVICE_TEAM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) + +#define NM_DEVICE_TEAM_HW_ADDRESS "hw-address" +#define NM_DEVICE_TEAM_CARRIER "carrier" +#define NM_DEVICE_TEAM_SLAVES "slaves" +#define NM_DEVICE_TEAM_CONFIG "config" + +/** + * NMDeviceTeam: + */ +typedef struct _NMDeviceTeamClass NMDeviceTeamClass; + +GType nm_device_team_get_type(void); + +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_team_get_hw_address(NMDeviceTeam *device); + +gboolean nm_device_team_get_carrier(NMDeviceTeam *device); +const GPtrArray *nm_device_team_get_slaves(NMDeviceTeam *device); +NM_AVAILABLE_IN_1_4 +const char *nm_device_team_get_config(NMDeviceTeam *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_TEAM_H__ */ diff --git a/src/libnm-client-public/nm-device-tun.h b/src/libnm-client-public/nm-device-tun.h new file mode 100644 index 0000000..ee7342d --- /dev/null +++ b/src/libnm-client-public/nm-device-tun.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_TUN_H__ +#define __NM_DEVICE_TUN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_TUN (nm_device_tun_get_type()) +#define NM_DEVICE_TUN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_TUN, NMDeviceTun)) +#define NM_DEVICE_TUN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_TUN, NMDeviceTunClass)) +#define NM_IS_DEVICE_TUN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_TUN)) +#define NM_IS_DEVICE_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_TUN)) +#define NM_DEVICE_TUN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_TUN, NMDeviceTunClass)) + +#define NM_DEVICE_TUN_HW_ADDRESS "hw-address" +#define NM_DEVICE_TUN_OWNER "owner" +#define NM_DEVICE_TUN_GROUP "group" +#define NM_DEVICE_TUN_MODE "mode" +#define NM_DEVICE_TUN_NO_PI "no-pi" +#define NM_DEVICE_TUN_VNET_HDR "vnet-hdr" +#define NM_DEVICE_TUN_MULTI_QUEUE "multi-queue" + +/** + * NMDeviceTun: + */ +typedef struct _NMDeviceTunClass NMDeviceTunClass; + +NM_AVAILABLE_IN_1_2 +GType nm_device_tun_get_type(void); + +NM_AVAILABLE_IN_1_2 +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_tun_get_hw_address(NMDeviceTun *device); + +NM_AVAILABLE_IN_1_2 +const char *nm_device_tun_get_mode(NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +gint64 nm_device_tun_get_owner(NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +gint64 nm_device_tun_get_group(NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_tun_get_no_pi(NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_tun_get_vnet_hdr(NMDeviceTun *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_tun_get_multi_queue(NMDeviceTun *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_TUN_H__ */ diff --git a/src/libnm-client-public/nm-device-veth.h b/src/libnm-client-public/nm-device-veth.h new file mode 100644 index 0000000..689762a --- /dev/null +++ b/src/libnm-client-public/nm-device-veth.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_VETH_H__ +#define __NM_DEVICE_VETH_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_VETH (nm_device_veth_get_type()) +#define NM_DEVICE_VETH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_VETH, NMDeviceVeth)) +#define NM_DEVICE_VETH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_VETH, NMDeviceVethClass)) +#define NM_IS_DEVICE_VETH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_VETH)) +#define NM_IS_DEVICE_VETH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_VETH)) +#define NM_DEVICE_VETH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_VETH, NMDeviceVethClass)) + +#define NM_DEVICE_VETH_PEER "peer" + +/** + * NMDeviceVeth: + */ +typedef struct _NMDeviceVethClass NMDeviceVethClass; + +NM_AVAILABLE_IN_1_30 +GType nm_device_veth_get_type(void); + +NM_AVAILABLE_IN_1_30 +NMDevice *nm_device_veth_get_peer(NMDeviceVeth *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_VETH_H__ */ diff --git a/src/libnm-client-public/nm-device-vlan.h b/src/libnm-client-public/nm-device-vlan.h new file mode 100644 index 0000000..8143050 --- /dev/null +++ b/src/libnm-client-public/nm-device-vlan.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_VLAN_H__ +#define __NM_DEVICE_VLAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_VLAN (nm_device_vlan_get_type()) +#define NM_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlan)) +#define NM_DEVICE_VLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) +#define NM_IS_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_VLAN)) +#define NM_IS_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_VLAN)) +#define NM_DEVICE_VLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) + +#define NM_DEVICE_VLAN_HW_ADDRESS "hw-address" +#define NM_DEVICE_VLAN_CARRIER "carrier" +#define NM_DEVICE_VLAN_PARENT "parent" +#define NM_DEVICE_VLAN_VLAN_ID "vlan-id" + +/** + * NMDeviceVlan: + */ +typedef struct _NMDeviceVlanClass NMDeviceVlanClass; + +GType nm_device_vlan_get_type(void); + +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_vlan_get_hw_address(NMDeviceVlan *device); + +gboolean nm_device_vlan_get_carrier(NMDeviceVlan *device); +NMDevice *nm_device_vlan_get_parent(NMDeviceVlan *device); +guint nm_device_vlan_get_vlan_id(NMDeviceVlan *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_VLAN_H__ */ diff --git a/src/libnm-client-public/nm-device-vrf.h b/src/libnm-client-public/nm-device-vrf.h new file mode 100644 index 0000000..f835dd2 --- /dev/null +++ b/src/libnm-client-public/nm-device-vrf.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_DEVICE_VRF_H__ +#define __NM_DEVICE_VRF_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_VRF (nm_device_vrf_get_type()) +#define NM_DEVICE_VRF(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_VRF, NMDeviceVrf)) +#define NM_DEVICE_VRF_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_VRF, NMDeviceVrfClass)) +#define NM_IS_DEVICE_VRF(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_VRF)) +#define NM_IS_DEVICE_VRF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_VRF)) +#define NM_DEVICE_VRF_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_VRF, NMDeviceVrfClass)) + +#define NM_DEVICE_VRF_TABLE "table" + +/** + * NMDeviceVrf: + */ +typedef struct _NMDeviceVrfClass NMDeviceVrfClass; + +NM_AVAILABLE_IN_1_24 +GType nm_device_vrf_get_type(void); +NM_AVAILABLE_IN_1_24 +guint32 nm_device_vrf_get_table(NMDeviceVrf *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_VRF_H__ */ diff --git a/src/libnm-client-public/nm-device-vxlan.h b/src/libnm-client-public/nm-device-vxlan.h new file mode 100644 index 0000000..9ef5eb2 --- /dev/null +++ b/src/libnm-client-public/nm-device-vxlan.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_VXLAN_H__ +#define __NM_DEVICE_VXLAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_VXLAN (nm_device_vxlan_get_type()) +#define NM_DEVICE_VXLAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlan)) +#define NM_DEVICE_VXLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass)) +#define NM_IS_DEVICE_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_VXLAN)) +#define NM_IS_DEVICE_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_VXLAN)) +#define NM_DEVICE_VXLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass)) + +#define NM_DEVICE_VXLAN_HW_ADDRESS "hw-address" +#define NM_DEVICE_VXLAN_CARRIER "carrier" +#define NM_DEVICE_VXLAN_PARENT "parent" +#define NM_DEVICE_VXLAN_ID "id" +#define NM_DEVICE_VXLAN_GROUP "group" +#define NM_DEVICE_VXLAN_LOCAL "local" +#define NM_DEVICE_VXLAN_SRC_PORT_MIN "src-port-min" +#define NM_DEVICE_VXLAN_SRC_PORT_MAX "src-port-max" +#define NM_DEVICE_VXLAN_LEARNING "learning" +#define NM_DEVICE_VXLAN_AGEING "ageing" +#define NM_DEVICE_VXLAN_TOS "tos" +#define NM_DEVICE_VXLAN_TTL "ttl" +#define NM_DEVICE_VXLAN_LIMIT "limit" +#define NM_DEVICE_VXLAN_PROXY "proxy" +#define NM_DEVICE_VXLAN_RSC "rsc" +#define NM_DEVICE_VXLAN_L2MISS "l2miss" +#define NM_DEVICE_VXLAN_L3MISS "l3miss" +#define NM_DEVICE_VXLAN_DST_PORT "dst-port" + +/** + * NMDeviceVxlan: + */ +typedef struct _NMDeviceVxlanClass NMDeviceVxlanClass; + +NM_AVAILABLE_IN_1_2 +GType nm_device_vxlan_get_type(void); + +NM_AVAILABLE_IN_1_2 +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_vxlan_get_hw_address(NMDeviceVxlan *device); + +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_carrier(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +NMDevice *nm_device_vxlan_get_parent(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_id(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +const char *nm_device_vxlan_get_group(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +const char *nm_device_vxlan_get_local(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_src_port_min(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_src_port_max(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_dst_port(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_learning(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_ageing(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_tos(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_ttl(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +guint nm_device_vxlan_get_limit(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_proxy(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_rsc(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_l2miss(NMDeviceVxlan *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_vxlan_get_l3miss(NMDeviceVxlan *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_VXLAN_H__ */ diff --git a/src/libnm-client-public/nm-device-wifi-p2p.h b/src/libnm-client-public/nm-device-wifi-p2p.h new file mode 100644 index 0000000..374ef4b --- /dev/null +++ b/src/libnm-client-public/nm-device-wifi-p2p.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 - 2019 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_WIFI_P2P_H__ +#define __NM_DEVICE_WIFI_P2P_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_WIFI_P2P (nm_device_wifi_p2p_get_type()) +#define NM_DEVICE_WIFI_P2P(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_WIFI_P2P, NMDeviceWifiP2P)) +#define NM_DEVICE_WIFI_P2P_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_WIFI_P2P, NMDeviceWifiP2PClass)) +#define NM_IS_DEVICE_WIFI_P2P(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_WIFI_P2P)) +#define NM_IS_DEVICE_WIFI_P2P_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_WIFI_P2P)) +#define NM_DEVICE_WIFI_P2P_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_WIFI_P2P, NMDeviceWifiP2PClass)) + +#define NM_DEVICE_WIFI_P2P_HW_ADDRESS "hw-address" +#define NM_DEVICE_WIFI_P2P_PEERS "peers" +#define NM_DEVICE_WIFI_P2P_WFDIES "wfdies" + +/** + * NMDeviceWifiP2P: + * + * Since: 1.16 + */ +typedef struct _NMDeviceWifiP2PClass NMDeviceWifiP2PClass; + +NM_AVAILABLE_IN_1_16 +GType nm_device_wifi_p2p_get_type(void); + +NM_AVAILABLE_IN_1_16 +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_wifi_p2p_get_hw_address(NMDeviceWifiP2P *device); + +NM_AVAILABLE_IN_1_16 +NMWifiP2PPeer *nm_device_wifi_p2p_get_peer_by_path(NMDeviceWifiP2P *device, const char *path); + +NM_AVAILABLE_IN_1_16 +const GPtrArray *nm_device_wifi_p2p_get_peers(NMDeviceWifiP2P *device); + +NM_AVAILABLE_IN_1_16 +void nm_device_wifi_p2p_start_find(NMDeviceWifiP2P * device, + GVariant * options, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_16 +gboolean +nm_device_wifi_p2p_start_find_finish(NMDeviceWifiP2P *device, GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_16 +void nm_device_wifi_p2p_stop_find(NMDeviceWifiP2P * device, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_16 +gboolean +nm_device_wifi_p2p_stop_find_finish(NMDeviceWifiP2P *device, GAsyncResult *result, GError **error); + +G_END_DECLS + +#endif /* __NM_DEVICE_WIFI_P2P_H__ */ diff --git a/src/libnm-client-public/nm-device-wifi.h b/src/libnm-client-public/nm-device-wifi.h new file mode 100644 index 0000000..bf712bb --- /dev/null +++ b/src/libnm-client-public/nm-device-wifi.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_WIFI_H__ +#define __NM_DEVICE_WIFI_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_WIFI (nm_device_wifi_get_type()) +#define NM_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifi)) +#define NM_DEVICE_WIFI_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) +#define NM_IS_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_WIFI)) +#define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_WIFI)) +#define NM_DEVICE_WIFI_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) + +#define NM_DEVICE_WIFI_HW_ADDRESS "hw-address" +#define NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS "perm-hw-address" +#define NM_DEVICE_WIFI_MODE "mode" +#define NM_DEVICE_WIFI_BITRATE "bitrate" +#define NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT "active-access-point" +#define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities" +#define NM_DEVICE_WIFI_ACCESS_POINTS "access-points" +#define NM_DEVICE_WIFI_LAST_SCAN "last-scan" + +/** + * NMDeviceWifi: + */ +typedef struct _NMDeviceWifiClass NMDeviceWifiClass; + +GType nm_device_wifi_get_type(void); + +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_wifi_get_hw_address(NMDeviceWifi *device); + +const char * nm_device_wifi_get_permanent_hw_address(NMDeviceWifi *device); +NM80211Mode nm_device_wifi_get_mode(NMDeviceWifi *device); +guint32 nm_device_wifi_get_bitrate(NMDeviceWifi *device); +NMDeviceWifiCapabilities nm_device_wifi_get_capabilities(NMDeviceWifi *device); +NMAccessPoint * nm_device_wifi_get_active_access_point(NMDeviceWifi *device); + +NMAccessPoint *nm_device_wifi_get_access_point_by_path(NMDeviceWifi *device, const char *path); + +const GPtrArray *nm_device_wifi_get_access_points(NMDeviceWifi *device); + +NM_AVAILABLE_IN_1_12 +gint64 nm_device_wifi_get_last_scan(NMDeviceWifi *device); + +_NM_DEPRECATED_SYNC_METHOD +gboolean +nm_device_wifi_request_scan(NMDeviceWifi *device, GCancellable *cancellable, GError **error); +NM_AVAILABLE_IN_1_2 +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_device_wifi_request_scan_options(NMDeviceWifi *device, + GVariant * options, + GCancellable *cancellable, + GError ** error); +void nm_device_wifi_request_scan_async(NMDeviceWifi * device, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_2 +void nm_device_wifi_request_scan_options_async(NMDeviceWifi * device, + GVariant * options, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean +nm_device_wifi_request_scan_finish(NMDeviceWifi *device, GAsyncResult *result, GError **error); + +G_END_DECLS + +#endif /* __NM_DEVICE_WIFI_H__ */ diff --git a/src/libnm-client-public/nm-device-wimax.h b/src/libnm-client-public/nm-device-wimax.h new file mode 100644 index 0000000..8a0fd90 --- /dev/null +++ b/src/libnm-client-public/nm-device-wimax.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2012 Red Hat, Inc. + * Copyright (C) 2009 Novell, Inc. + */ + +#ifndef __NM_DEVICE_WIMAX_H__ +#define __NM_DEVICE_WIMAX_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_WIMAX (nm_device_wimax_get_type()) +#define NM_DEVICE_WIMAX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimax)) +#define NM_DEVICE_WIMAX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) +#define NM_IS_DEVICE_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_WIMAX)) +#define NM_IS_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_WIMAX)) +#define NM_DEVICE_WIMAX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) + +#define NM_DEVICE_WIMAX_HW_ADDRESS "hw-address" +#define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp" +#define NM_DEVICE_WIMAX_CENTER_FREQUENCY "center-frequency" +#define NM_DEVICE_WIMAX_RSSI "rssi" +#define NM_DEVICE_WIMAX_CINR "cinr" +#define NM_DEVICE_WIMAX_TX_POWER "tx-power" +#define NM_DEVICE_WIMAX_BSID "bsid" +#define NM_DEVICE_WIMAX_NSPS "nsps" + +/** + * NMDeviceWimax: + * + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. + */ +typedef struct _NMDeviceWimaxClass NMDeviceWimaxClass; + +NM_DEPRECATED_IN_1_2 +GType nm_device_wimax_get_type(void); + +NM_DEPRECATED_IN_1_2 +const char *nm_device_wimax_get_hw_address(NMDeviceWimax *wimax); +NM_DEPRECATED_IN_1_2 +NMWimaxNsp *nm_device_wimax_get_active_nsp(NMDeviceWimax *wimax); +NM_DEPRECATED_IN_1_2 +NMWimaxNsp *nm_device_wimax_get_nsp_by_path(NMDeviceWimax *wimax, const char *path); + +NM_DEPRECATED_IN_1_2 +const GPtrArray *nm_device_wimax_get_nsps(NMDeviceWimax *wimax); + +NM_DEPRECATED_IN_1_2 +guint nm_device_wimax_get_center_frequency(NMDeviceWimax *self); +NM_DEPRECATED_IN_1_2 +int nm_device_wimax_get_rssi(NMDeviceWimax *self); +NM_DEPRECATED_IN_1_2 +int nm_device_wimax_get_cinr(NMDeviceWimax *self); +NM_DEPRECATED_IN_1_2 +int nm_device_wimax_get_tx_power(NMDeviceWimax *self); +NM_DEPRECATED_IN_1_2 +const char *nm_device_wimax_get_bsid(NMDeviceWimax *self); + +G_END_DECLS + +#endif /* __NM_DEVICE_WIMAX_H__ */ diff --git a/src/libnm-client-public/nm-device-wireguard.h b/src/libnm-client-public/nm-device-wireguard.h new file mode 100644 index 0000000..f54695e --- /dev/null +++ b/src/libnm-client-public/nm-device-wireguard.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Javier Arteaga + */ + +#ifndef __NM_DEVICE_WIREGUARD_H__ +#define __NM_DEVICE_WIREGUARD_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_WIREGUARD (nm_device_wireguard_get_type()) +#define NM_DEVICE_WIREGUARD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuard)) +#define NM_DEVICE_WIREGUARD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass)) +#define NM_IS_DEVICE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_WIREGUARD)) +#define NM_IS_DEVICE_WIREGUARD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_WIREGUARD)) +#define NM_DEVICE_WIREGUARD_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass)) + +/** + * NMDeviceWireGuard: + */ +typedef struct _NMDeviceWireGuardClass NMDeviceWireGuardClass; + +#define NM_DEVICE_WIREGUARD_PUBLIC_KEY "public-key" +#define NM_DEVICE_WIREGUARD_LISTEN_PORT "listen-port" +#define NM_DEVICE_WIREGUARD_FWMARK "fwmark" + +NM_AVAILABLE_IN_1_14 +GType nm_device_wireguard_get_type(void); + +NM_AVAILABLE_IN_1_14 +GBytes *nm_device_wireguard_get_public_key(NMDeviceWireGuard *device); +NM_AVAILABLE_IN_1_14 +guint16 nm_device_wireguard_get_listen_port(NMDeviceWireGuard *device); +NM_AVAILABLE_IN_1_14 +guint32 nm_device_wireguard_get_fwmark(NMDeviceWireGuard *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_WIREGUARD_H__ */ diff --git a/src/libnm-client-public/nm-device-wpan.h b/src/libnm-client-public/nm-device-wpan.h new file mode 100644 index 0000000..7d50fd9 --- /dev/null +++ b/src/libnm-client-public/nm-device-wpan.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Lubomir Rintel + */ + +#ifndef __NM_DEVICE_WPAN_H__ +#define __NM_DEVICE_WPAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_WPAN (nm_device_wpan_get_type()) +#define NM_DEVICE_WPAN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_WPAN, NMDeviceWpan)) +#define NM_DEVICE_WPAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_WPAN, NMDeviceWpanClass)) +#define NM_IS_DEVICE_WPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_WPAN)) +#define NM_IS_DEVICE_WPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_WPAN)) +#define NM_DEVICE_WPAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_WPAN, NMDeviceWpanClass)) + +#define NM_DEVICE_WPAN_HW_ADDRESS "hw-address" + +/** + * NMDeviceWpan: + */ +typedef struct _NMDeviceWpanClass NMDeviceWpanClass; + +NM_AVAILABLE_IN_1_14 +GType nm_device_wpan_get_type(void); + +NM_AVAILABLE_IN_1_14 +NM_DEPRECATED_IN_1_24_FOR(nm_device_get_hw_address) +const char *nm_device_wpan_get_hw_address(NMDeviceWpan *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_WPAN_H__ */ diff --git a/src/libnm-client-public/nm-device.h b/src/libnm-client-public/nm-device.h new file mode 100644 index 0000000..62baac9 --- /dev/null +++ b/src/libnm-client-public/nm-device.h @@ -0,0 +1,273 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2013 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_H__ +#define __NM_DEVICE_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE (nm_device_get_type()) +#define NM_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE, NMDevice)) +#define NM_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE, NMDeviceClass)) +#define NM_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE)) +#define NM_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE)) +#define NM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE, NMDeviceClass)) + +#define NM_DEVICE_DEVICE_TYPE "device-type" +#define NM_DEVICE_UDI "udi" +#define NM_DEVICE_PATH "path" +#define NM_DEVICE_INTERFACE "interface" +#define NM_DEVICE_IP_INTERFACE "ip-interface" +#define NM_DEVICE_DRIVER "driver" +#define NM_DEVICE_DRIVER_VERSION "driver-version" +#define NM_DEVICE_FIRMWARE_VERSION "firmware-version" +#define NM_DEVICE_CAPABILITIES "capabilities" +#define NM_DEVICE_REAL "real" +#define NM_DEVICE_MANAGED "managed" + +_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY +#define NM_DEVICE_AUTOCONNECT "autoconnect" + +#define NM_DEVICE_FIRMWARE_MISSING "firmware-missing" +#define NM_DEVICE_NM_PLUGIN_MISSING "nm-plugin-missing" +#define NM_DEVICE_IP4_CONFIG "ip4-config" +#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config" +#define NM_DEVICE_IP6_CONFIG "ip6-config" +#define NM_DEVICE_DHCP6_CONFIG "dhcp6-config" +#define NM_DEVICE_STATE "state" +#define NM_DEVICE_STATE_REASON "state-reason" +#define NM_DEVICE_ACTIVE_CONNECTION "active-connection" +#define NM_DEVICE_AVAILABLE_CONNECTIONS "available-connections" +#define NM_DEVICE_VENDOR "vendor" +#define NM_DEVICE_PRODUCT "product" +#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" +#define NM_DEVICE_MTU "mtu" +#define NM_DEVICE_METERED "metered" +#define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors" +#define NM_DEVICE_IP4_CONNECTIVITY "ip4-connectivity" +#define NM_DEVICE_IP6_CONNECTIVITY "ip6-connectivity" +#define NM_DEVICE_INTERFACE_FLAGS "interface-flags" +#define NM_DEVICE_HW_ADDRESS "hw-address" + +/** + * NMDevice: + */ +typedef struct _NMDeviceClass NMDeviceClass; + +/** + * NMLldpNeighbor: + * + * Supported attributes are: + * + * - #NM_LLDP_ATTR_CHASSIS_ID_TYPE (type: 'u') + * - #NM_LLDP_ATTR_CHASSIS_ID (type: 's') + * - #NM_LLDP_ATTR_DESTINATION (type: 's') + * - #NM_LLDP_ATTR_IEEE_802_1_PPVID (type: 'u'). This attribute only reports the first PPVID + * and therefore it is deprecated in favor of NM_LLDP_ATTR_IEEE_802_1_PPVIDS which reports + * all the PPVID. + * - #NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS (type: 'u'). This attribute only reports the first PPVID + * and therefore it is deprecated in favor of NM_LLDP_ATTR_IEEE_802_1_PPVIDS which reports + * all the PPVID. + * - #NM_LLDP_ATTR_IEEE_802_1_PPVIDS (type: 'aa{sv}') + * + * An array of dictionaries where each element has keys: + * - flags (type: 'u') + * - ppvid (type: 'u') + * - #NM_LLDP_ATTR_IEEE_802_1_PVID (type: 'u') + * - #NM_LLDP_ATTR_IEEE_802_1_VID (type: 'u'). This attribute only reports the first VLAN + * and therefore it is deprecated in favor of NM_LLDP_ATTR_IEEE_802_1_VLANS which reports + * all the VLANs. + * - #NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME (type: 's'). This attribute only reports the first VLAN + * and therefore it is deprecated in favor of NM_LLDP_ATTR_IEEE_802_1_VLANS which reports + * all the VLANs. + * - #NM_LLDP_ATTR_IEEE_802_1_VLANS (type: 'aa{sv}') + * + * An array of dictionaries where each element has keys: + * - name (type: 's') + * - vid (type: 'u') + * - #NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF (type: 'a{sv}') + * + * Dictionary where each element has keys: + * - autoneg (type: 'u') + * - operational-mau-type (type: 'u') + * - pmd-autoneg-cap (type: 'u') + * - #NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE (type: 'u') + * - #NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI (type: 'a{sv}') + * + * Dictionary where each element has keys: + * - mdi-power-support (type: 'u') + * - power-class (type: 'u') + * - pse-power-pair (type: 'u') + * - #NM_LLDP_ATTR_MANAGEMENT_ADDRESSES (type: 'aa{sv}') + * + * An array of dictionaries where each element has keys: + * - address (type: 'ay') + * - address-subtype (type: 'u') + * - interface-number (type: 'u') + * - interface-number-subtype (type: 'u') + * - object-id (type: 'ay') + * - #NM_LLDP_ATTR_PORT_DESCRIPTION (type: 's') + * - #NM_LLDP_ATTR_PORT_ID_TYPE (type: 'u') + * - #NM_LLDP_ATTR_PORT_ID (type: 's') + * - #NM_LLDP_ATTR_RAW (type: 'ay') + * - #NM_LLDP_ATTR_SYSTEM_CAPABILITIES (type: 'u') + * - #NM_LLDP_ATTR_SYSTEM_DESCRIPTION (type: 's') + * - #NM_LLDP_ATTR_SYSTEM_NAME (type: 's') + **/ +typedef struct _NMLldpNeighbor NMLldpNeighbor; + +GType nm_device_get_type(void); + +const char * nm_device_get_iface(NMDevice *device); +const char * nm_device_get_ip_iface(NMDevice *device); +NMDeviceType nm_device_get_device_type(NMDevice *device); +const char * nm_device_get_udi(NMDevice *device); +NM_AVAILABLE_IN_1_26 +const char * nm_device_get_path(NMDevice *device); +const char * nm_device_get_driver(NMDevice *device); +const char * nm_device_get_driver_version(NMDevice *device); +const char * nm_device_get_firmware_version(NMDevice *device); +const char * nm_device_get_type_description(NMDevice *device); +const char * nm_device_get_hw_address(NMDevice *device); +NMDeviceCapabilities nm_device_get_capabilities(NMDevice *device); +gboolean nm_device_get_managed(NMDevice *device); + +NM_AVAILABLE_IN_1_2 +NM_DEPRECATED_IN_1_22 +_NM_DEPRECATED_SYNC_METHOD +void nm_device_set_managed(NMDevice *device, gboolean managed); + +gboolean nm_device_get_autoconnect(NMDevice *device); + +NM_DEPRECATED_IN_1_22 +_NM_DEPRECATED_SYNC_METHOD +void nm_device_set_autoconnect(NMDevice *device, gboolean autoconnect); + +gboolean nm_device_get_firmware_missing(NMDevice *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_get_nm_plugin_missing(NMDevice *device); +NMIPConfig * nm_device_get_ip4_config(NMDevice *device); +NMDhcpConfig *nm_device_get_dhcp4_config(NMDevice *device); +NMIPConfig * nm_device_get_ip6_config(NMDevice *device); +NMDhcpConfig *nm_device_get_dhcp6_config(NMDevice *device); +NM_AVAILABLE_IN_1_16 +NMConnectivityState nm_device_get_connectivity(NMDevice *device, int addr_family); +NMDeviceState nm_device_get_state(NMDevice *device); +NMDeviceStateReason nm_device_get_state_reason(NMDevice *device); +NMActiveConnection *nm_device_get_active_connection(NMDevice *device); +const GPtrArray * nm_device_get_available_connections(NMDevice *device); +const char * nm_device_get_physical_port_id(NMDevice *device); +guint32 nm_device_get_mtu(NMDevice *device); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_is_real(NMDevice *device); +gboolean nm_device_is_software(NMDevice *device); + +const char *nm_device_get_product(NMDevice *device); +const char *nm_device_get_vendor(NMDevice *device); +const char *nm_device_get_description(NMDevice *device); +NM_AVAILABLE_IN_1_2 +NMMetered nm_device_get_metered(NMDevice *device); +NM_AVAILABLE_IN_1_2 +GPtrArray *nm_device_get_lldp_neighbors(NMDevice *device); +NM_AVAILABLE_IN_1_22 +NMDeviceInterfaceFlags nm_device_get_interface_flags(NMDevice *device); + +char **nm_device_disambiguate_names(NMDevice **devices, int num_devices); +NM_AVAILABLE_IN_1_2 +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_device_reapply(NMDevice * device, + NMConnection *connection, + guint64 version_id, + guint32 flags, + GCancellable *cancellable, + GError ** error); +NM_AVAILABLE_IN_1_2 +void nm_device_reapply_async(NMDevice * device, + NMConnection * connection, + guint64 version_id, + guint32 flags, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_2 +gboolean nm_device_reapply_finish(NMDevice *device, GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_2 +_NM_DEPRECATED_SYNC_METHOD +NMConnection *nm_device_get_applied_connection(NMDevice * device, + guint32 flags, + guint64 * version_id, + GCancellable *cancellable, + GError ** error); +NM_AVAILABLE_IN_1_2 +void nm_device_get_applied_connection_async(NMDevice * device, + guint32 flags, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_2 +NMConnection *nm_device_get_applied_connection_finish(NMDevice * device, + GAsyncResult *result, + guint64 * version_id, + GError ** error); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_device_disconnect(NMDevice *device, GCancellable *cancellable, GError **error); +void nm_device_disconnect_async(NMDevice * device, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_device_disconnect_finish(NMDevice *device, GAsyncResult *result, GError **error); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_device_delete(NMDevice *device, GCancellable *cancellable, GError **error); +void nm_device_delete_async(NMDevice * device, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_device_delete_finish(NMDevice *device, GAsyncResult *result, GError **error); + +GPtrArray *nm_device_filter_connections(NMDevice *device, const GPtrArray *connections); + +gboolean nm_device_connection_valid(NMDevice *device, NMConnection *connection); + +gboolean +nm_device_connection_compatible(NMDevice *device, NMConnection *connection, GError **error); + +GType nm_device_get_setting_type(NMDevice *device); + +NM_AVAILABLE_IN_1_2 +GType nm_lldp_neighbor_get_type(void); +NM_AVAILABLE_IN_1_2 +void nm_lldp_neighbor_ref(NMLldpNeighbor *neighbor); +NM_AVAILABLE_IN_1_2 +void nm_lldp_neighbor_unref(NMLldpNeighbor *neighbor); +NM_AVAILABLE_IN_1_2 +char **nm_lldp_neighbor_get_attr_names(NMLldpNeighbor *neighbor); +NM_AVAILABLE_IN_1_18 +GVariant *nm_lldp_neighbor_get_attr_value(NMLldpNeighbor *neighbor, const char *name); + +NM_AVAILABLE_IN_1_2 +NMLldpNeighbor *nm_lldp_neighbor_new(void); +NM_AVAILABLE_IN_1_2 +gboolean nm_lldp_neighbor_get_attr_string_value(NMLldpNeighbor *neighbor, + const char * name, + const char ** out_value); +NM_AVAILABLE_IN_1_2 +gboolean +nm_lldp_neighbor_get_attr_uint_value(NMLldpNeighbor *neighbor, const char *name, guint *out_value); +NM_AVAILABLE_IN_1_2 +const GVariantType *nm_lldp_neighbor_get_attr_type(NMLldpNeighbor *neighbor, const char *name); + +G_END_DECLS + +#endif /* __NM_DEVICE_H__ */ diff --git a/src/libnm-client-public/nm-dhcp-config.h b/src/libnm-client-public/nm-dhcp-config.h new file mode 100644 index 0000000..7663fb9 --- /dev/null +++ b/src/libnm-client-public/nm-dhcp-config.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#ifndef __NM_DHCP_CONFIG_H__ +#define __NM_DHCP_CONFIG_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DHCP_CONFIG (nm_dhcp_config_get_type()) +#define NM_DHCP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP_CONFIG, NMDhcpConfig)) +#define NM_DHCP_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP_CONFIG, NMDhcpConfigClass)) +#define NM_IS_DHCP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP_CONFIG)) +#define NM_IS_DHCP_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP_CONFIG)) + +/** + * NMDhcpConfig: + */ +typedef struct _NMDhcpConfigClass NMDhcpConfigClass; + +#define NM_DHCP_CONFIG_FAMILY "family" +#define NM_DHCP_CONFIG_OPTIONS "options" + +GType nm_dhcp_config_get_type(void); + +int nm_dhcp_config_get_family(NMDhcpConfig *config); + +GHashTable *nm_dhcp_config_get_options(NMDhcpConfig *config); +const char *nm_dhcp_config_get_one_option(NMDhcpConfig *config, const char *option); + +G_END_DECLS + +#endif /* __NM_DHCP_CONFIG_H__ */ diff --git a/src/libnm-client-public/nm-enum-types.c.template b/src/libnm-client-public/nm-enum-types.c.template new file mode 100644 index 0000000..c2627f4 --- /dev/null +++ b/src/libnm-client-public/nm-enum-types.c.template @@ -0,0 +1,75 @@ +/*** BEGIN file-header ***/ +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-enum-types.h" + +#include "nm-version-macros.h" +#include "NetworkManager.h" +#include "nm-access-point.h" +#include "nm-active-connection.h" +#include "nm-checkpoint.h" +#include "nm-client.h" +#include "nm-device-adsl.h" +#include "nm-device-bond.h" +#include "nm-device-bridge.h" +#include "nm-device-bt.h" +#include "nm-device-dummy.h" +#include "nm-device-ethernet.h" +#include "nm-device-generic.h" +#include "nm-device-infiniband.h" +#include "nm-device-ip-tunnel.h" +#include "nm-device-macsec.h" +#include "nm-device-macvlan.h" +#include "nm-device-modem.h" +#include "nm-device-olpc-mesh.h" +#include "nm-device-ovs-interface.h" +#include "nm-device-ovs-port.h" +#include "nm-device-ovs-bridge.h" +#include "nm-device-ppp.h" +#include "nm-device-team.h" +#include "nm-device-tun.h" +#include "nm-device-vlan.h" +#include "nm-device-vxlan.h" +#include "nm-device-wifi.h" +#include "nm-device-wimax.h" +#include "nm-device.h" +#include "nm-dhcp-config.h" +#include "nm-ip-config.h" +#include "nm-object.h" +#include "nm-remote-connection.h" +#include "nm-types.h" +#include "nm-vpn-connection.h" +#include "nm-vpn-editor.h" +#include "nm-wimax-nsp.h" +#include "nm-secret-agent-old.h" +#include "nm-vpn-plugin-old.h" +#include "nm-vpn-service-plugin.h" +/*** END file-header ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} + +/*** END value-tail ***/ diff --git a/src/libnm-client-public/nm-enum-types.h.template b/src/libnm-client-public/nm-enum-types.h.template new file mode 100644 index 0000000..bc70af1 --- /dev/null +++ b/src/libnm-client-public/nm-enum-types.h.template @@ -0,0 +1,23 @@ +/*** BEGIN file-header ***/ +#ifndef __NM_ENUM_TYPES_H__ +#define __NM_ENUM_TYPES_H__ + +#include "nm-core-enum-types.h" +# +#include + +G_BEGIN_DECLS + +/*** END file-header ***/ + +/*** BEGIN enumeration-production ***/ +GType @enum_name@_get_type (void) G_GNUC_CONST; +#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) + +/*** END enumeration-production ***/ + +/*** BEGIN file-tail ***/ +G_END_DECLS + +#endif /* __NM_ENUM_TYPES_H__ */ +/*** END file-tail ***/ diff --git a/src/libnm-client-public/nm-ethtool-utils.h b/src/libnm-client-public/nm-ethtool-utils.h new file mode 100644 index 0000000..d422724 --- /dev/null +++ b/src/libnm-client-public/nm-ethtool-utils.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_ETHTOOL_UTILS_H__ +#define __NM_ETHTOOL_UTILS_H__ + +G_BEGIN_DECLS + +/*****************************************************************************/ + +#define NM_ETHTOOL_OPTNAME_FEATURE_ESP_HW_OFFLOAD "feature-esp-hw-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_ESP_TX_CSUM_HW_OFFLOAD "feature-esp-tx-csum-hw-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_FCOE_MTU "feature-fcoe-mtu" +#define NM_ETHTOOL_OPTNAME_FEATURE_GRO "feature-gro" +#define NM_ETHTOOL_OPTNAME_FEATURE_GSO "feature-gso" +#define NM_ETHTOOL_OPTNAME_FEATURE_HIGHDMA "feature-highdma" +#define NM_ETHTOOL_OPTNAME_FEATURE_HW_TC_OFFLOAD "feature-hw-tc-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_L2_FWD_OFFLOAD "feature-l2-fwd-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_LOOPBACK "feature-loopback" +#define NM_ETHTOOL_OPTNAME_FEATURE_LRO "feature-lro" +#define NM_ETHTOOL_OPTNAME_FEATURE_MACSEC_HW_OFFLOAD "feature-macsec-hw-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_NTUPLE "feature-ntuple" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX "feature-rx" +#define NM_ETHTOOL_OPTNAME_FEATURE_RXHASH "feature-rxhash" +#define NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN "feature-rxvlan" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_ALL "feature-rx-all" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_FCS "feature-rx-fcs" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_GRO_HW "feature-rx-gro-hw" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_GRO_LIST "feature-rx-gro-list" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_UDP_GRO_FORWARDING "feature-rx-udp-gro-forwarding" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD "feature-rx-udp_tunnel-port-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_FILTER "feature-rx-vlan-filter" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_STAG_FILTER "feature-rx-vlan-stag-filter" +#define NM_ETHTOOL_OPTNAME_FEATURE_RX_VLAN_STAG_HW_PARSE "feature-rx-vlan-stag-hw-parse" +#define NM_ETHTOOL_OPTNAME_FEATURE_SG "feature-sg" +#define NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_RECORD "feature-tls-hw-record" +#define NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_RX_OFFLOAD "feature-tls-hw-rx-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_TLS_HW_TX_OFFLOAD "feature-tls-hw-tx-offload" +#define NM_ETHTOOL_OPTNAME_FEATURE_TSO "feature-tso" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX "feature-tx" +#define NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN "feature-txvlan" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_FCOE_CRC "feature-tx-checksum-fcoe-crc" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IPV4 "feature-tx-checksum-ipv4" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IPV6 "feature-tx-checksum-ipv6" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_IP_GENERIC "feature-tx-checksum-ip-generic" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_CHECKSUM_SCTP "feature-tx-checksum-sctp" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_ESP_SEGMENTATION "feature-tx-esp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_FCOE_SEGMENTATION "feature-tx-fcoe-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GRE_CSUM_SEGMENTATION "feature-tx-gre-csum-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GRE_SEGMENTATION "feature-tx-gre-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_LIST "feature-tx-gso-list" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_PARTIAL "feature-tx-gso-partial" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_GSO_ROBUST "feature-tx-gso-robust" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_IPXIP4_SEGMENTATION "feature-tx-ipxip4-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_IPXIP6_SEGMENTATION "feature-tx-ipxip6-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_NOCACHE_COPY "feature-tx-nocache-copy" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_SCATTER_GATHER "feature-tx-scatter-gather" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_SCATTER_GATHER_FRAGLIST "feature-tx-scatter-gather-fraglist" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_SCTP_SEGMENTATION "feature-tx-sctp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP6_SEGMENTATION "feature-tx-tcp6-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_ECN_SEGMENTATION "feature-tx-tcp-ecn-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_MANGLEID_SEGMENTATION \ + "feature-tx-tcp-mangleid-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TCP_SEGMENTATION "feature-tx-tcp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_TUNNEL_REMCSUM_SEGMENTATION \ + "feature-tx-tunnel-remcsum-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_SEGMENTATION "feature-tx-udp-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION \ + "feature-tx-udp_tnl-csum-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_UDP_TNL_SEGMENTATION "feature-tx-udp_tnl-segmentation" +#define NM_ETHTOOL_OPTNAME_FEATURE_TX_VLAN_STAG_HW_INSERT "feature-tx-vlan-stag-hw-insert" + +#define NM_ETHTOOL_OPTNAME_COALESCE_ADAPTIVE_RX "coalesce-adaptive-rx" +#define NM_ETHTOOL_OPTNAME_COALESCE_ADAPTIVE_TX "coalesce-adaptive-tx" +#define NM_ETHTOOL_OPTNAME_COALESCE_PKT_RATE_HIGH "coalesce-pkt-rate-high" +#define NM_ETHTOOL_OPTNAME_COALESCE_PKT_RATE_LOW "coalesce-pkt-rate-low" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES "coalesce-rx-frames" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_HIGH "coalesce-rx-frames-high" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_IRQ "coalesce-rx-frames-irq" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES_LOW "coalesce-rx-frames-low" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS "coalesce-rx-usecs" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_HIGH "coalesce-rx-usecs-high" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_IRQ "coalesce-rx-usecs-irq" +#define NM_ETHTOOL_OPTNAME_COALESCE_RX_USECS_LOW "coalesce-rx-usecs-low" +#define NM_ETHTOOL_OPTNAME_COALESCE_SAMPLE_INTERVAL "coalesce-sample-interval" +#define NM_ETHTOOL_OPTNAME_COALESCE_STATS_BLOCK_USECS "coalesce-stats-block-usecs" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES "coalesce-tx-frames" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_HIGH "coalesce-tx-frames-high" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_IRQ "coalesce-tx-frames-irq" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES_LOW "coalesce-tx-frames-low" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS "coalesce-tx-usecs" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_HIGH "coalesce-tx-usecs-high" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_IRQ "coalesce-tx-usecs-irq" +#define NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_LOW "coalesce-tx-usecs-low" + +#define NM_ETHTOOL_OPTNAME_RING_RX "ring-rx" +#define NM_ETHTOOL_OPTNAME_RING_RX_JUMBO "ring-rx-jumbo" +#define NM_ETHTOOL_OPTNAME_RING_RX_MINI "ring-rx-mini" +#define NM_ETHTOOL_OPTNAME_RING_TX "ring-tx" + +/*****************************************************************************/ + +G_END_DECLS + +#endif /* __NM_ETHTOOL_UTILS_H__ */ diff --git a/src/libnm-client-public/nm-ip-config.h b/src/libnm-client-public/nm-ip-config.h new file mode 100644 index 0000000..bdfebb6 --- /dev/null +++ b/src/libnm-client-public/nm-ip-config.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2008 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_IP_CONFIG_H__ +#define __NM_IP_CONFIG_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_IP_CONFIG (nm_ip_config_get_type()) +#define NM_IP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_IP_CONFIG, NMIPConfig)) +#define NM_IP_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_IP_CONFIG, NMIPConfigClass)) +#define NM_IS_IP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_IP_CONFIG)) +#define NM_IS_IP_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_IP_CONFIG)) +#define NM_IP_CONFIG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_IP_CONFIG, NMIPConfigClass)) + +/** + * NMIPConfig: + */ +typedef struct _NMIPConfigClass NMIPConfigClass; + +#define NM_IP_CONFIG_FAMILY "family" +#define NM_IP_CONFIG_GATEWAY "gateway" +#define NM_IP_CONFIG_ADDRESSES "addresses" +#define NM_IP_CONFIG_ROUTES "routes" +#define NM_IP_CONFIG_NAMESERVERS "nameservers" +#define NM_IP_CONFIG_DOMAINS "domains" +#define NM_IP_CONFIG_SEARCHES "searches" +#define NM_IP_CONFIG_WINS_SERVERS "wins-servers" + +GType nm_ip_config_get_type(void); + +int nm_ip_config_get_family(NMIPConfig *config); +const char * nm_ip_config_get_gateway(NMIPConfig *config); +GPtrArray * nm_ip_config_get_addresses(NMIPConfig *config); +GPtrArray * nm_ip_config_get_routes(NMIPConfig *config); +const char *const *nm_ip_config_get_nameservers(NMIPConfig *config); +const char *const *nm_ip_config_get_domains(NMIPConfig *config); +const char *const *nm_ip_config_get_searches(NMIPConfig *config); +const char *const *nm_ip_config_get_wins_servers(NMIPConfig *config); + +G_END_DECLS + +#endif /* __NM_IP_CONFIG_H__ */ diff --git a/src/libnm-client-public/nm-object.h b/src/libnm-client-public/nm-object.h new file mode 100644 index 0000000..7b4a323 --- /dev/null +++ b/src/libnm-client-public/nm-object.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_OBJECT_H__ +#define __NM_OBJECT_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-types.h" + +G_BEGIN_DECLS + +#define NM_TYPE_OBJECT (nm_object_get_type()) +#define NM_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_OBJECT, NMObject)) +#define NM_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_OBJECT, NMObjectClass)) +#define NM_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_OBJECT)) +#define NM_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_OBJECT)) +#define NM_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_OBJECT, NMObjectClass)) + +#define NM_OBJECT_PATH "path" + +/** + * NMObject: + */ +typedef struct _NMObjectClass NMObjectClass; + +GType nm_object_get_type(void); + +const char *nm_object_get_path(NMObject *object); + +NM_AVAILABLE_IN_1_24 +NMClient *nm_object_get_client(NMObject *object); + +G_END_DECLS + +#endif /* __NM_OBJECT_H__ */ diff --git a/src/libnm-client-public/nm-remote-connection.h b/src/libnm-client-public/nm-remote-connection.h new file mode 100644 index 0000000..e29bf07 --- /dev/null +++ b/src/libnm-client-public/nm-remote-connection.h @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. + */ + +#ifndef __NM_REMOTE_CONNECTION_H__ +#define __NM_REMOTE_CONNECTION_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_REMOTE_CONNECTION (nm_remote_connection_get_type()) +#define NM_REMOTE_CONNECTION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnection)) +#define NM_REMOTE_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionClass)) +#define NM_IS_REMOTE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_REMOTE_CONNECTION)) +#define NM_IS_REMOTE_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_REMOTE_CONNECTION)) +#define NM_REMOTE_CONNECTION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionClass)) + +/* Properties */ +#define NM_REMOTE_CONNECTION_DBUS_CONNECTION "dbus-connection" +#define NM_REMOTE_CONNECTION_PATH "path" +#define NM_REMOTE_CONNECTION_UNSAVED "unsaved" +#define NM_REMOTE_CONNECTION_FLAGS "flags" +#define NM_REMOTE_CONNECTION_FILENAME "filename" +#define NM_REMOTE_CONNECTION_VISIBLE "visible" + +/** + * NMRemoteConnection: + */ +typedef struct _NMRemoteConnectionClass NMRemoteConnectionClass; + +GType nm_remote_connection_get_type(void); + +NM_AVAILABLE_IN_1_12 +void nm_remote_connection_update2(NMRemoteConnection * connection, + GVariant * settings, + NMSettingsUpdate2Flags flags, + GVariant * args, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_12 +GVariant *nm_remote_connection_update2_finish(NMRemoteConnection *connection, + GAsyncResult * result, + GError ** error); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_remote_connection_commit_changes(NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable * cancellable, + GError ** error); + +void nm_remote_connection_commit_changes_async(NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_connection_commit_changes_finish(NMRemoteConnection *connection, + GAsyncResult * result, + GError ** error); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_remote_connection_save(NMRemoteConnection *connection, + GCancellable * cancellable, + GError ** error); + +void nm_remote_connection_save_async(NMRemoteConnection *connection, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_connection_save_finish(NMRemoteConnection *connection, + GAsyncResult * result, + GError ** error); + +_NM_DEPRECATED_SYNC_METHOD +gboolean nm_remote_connection_delete(NMRemoteConnection *connection, + GCancellable * cancellable, + GError ** error); + +void nm_remote_connection_delete_async(NMRemoteConnection *connection, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_connection_delete_finish(NMRemoteConnection *connection, + GAsyncResult * result, + GError ** error); + +_NM_DEPRECATED_SYNC_METHOD +GVariant *nm_remote_connection_get_secrets(NMRemoteConnection *connection, + const char * setting_name, + GCancellable * cancellable, + GError ** error); + +void nm_remote_connection_get_secrets_async(NMRemoteConnection *connection, + const char * setting_name, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GVariant *nm_remote_connection_get_secrets_finish(NMRemoteConnection *connection, + GAsyncResult * result, + GError ** error); + +gboolean nm_remote_connection_get_unsaved(NMRemoteConnection *connection); + +NM_AVAILABLE_IN_1_12 +NMSettingsConnectionFlags nm_remote_connection_get_flags(NMRemoteConnection *connection); + +NM_AVAILABLE_IN_1_12 +const char *nm_remote_connection_get_filename(NMRemoteConnection *connection); + +gboolean nm_remote_connection_get_visible(NMRemoteConnection *connection); + +G_END_DECLS + +#endif /* __NM_REMOTE_CONNECTION__ */ diff --git a/src/libnm-client-public/nm-secret-agent-old.h b/src/libnm-client-public/nm-secret-agent-old.h new file mode 100644 index 0000000..cc33c14 --- /dev/null +++ b/src/libnm-client-public/nm-secret-agent-old.h @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2010 - 2011 Red Hat, Inc. + */ + +#ifndef __NM_SECRET_AGENT_OLD_H__ +#define __NM_SECRET_AGENT_OLD_H__ + +#include "nm-types.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SECRET_AGENT_OLD (nm_secret_agent_old_get_type()) +#define NM_SECRET_AGENT_OLD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOld)) +#define NM_SECRET_AGENT_OLD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldClass)) +#define NM_IS_SECRET_AGENT_OLD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SECRET_AGENT_OLD)) +#define NM_IS_SECRET_AGENT_OLD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SECRET_AGENT_OLD)) +#define NM_SECRET_AGENT_OLD_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldClass)) + +#define NM_SECRET_AGENT_OLD_IDENTIFIER "identifier" +#define NM_SECRET_AGENT_OLD_AUTO_REGISTER "auto-register" +#define NM_SECRET_AGENT_OLD_REGISTERED "registered" +#define NM_SECRET_AGENT_OLD_CAPABILITIES "capabilities" +#define NM_SECRET_AGENT_OLD_DBUS_CONNECTION "dbus-connection" + +/** + * NMSecretAgentOld: + */ +typedef struct { + GObject parent; +} NMSecretAgentOld; + +/** + * NMSecretAgentOldGetSecretsFunc: + * @agent: the secret agent object + * @connection: (transfer none): the connection for which secrets were requested, + * note that this object will be unrefed after the callback has returned, use + * g_object_ref()/g_object_unref() if you want to use this object after the callback + * has returned + * @secrets: the #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing the requested + * secrets (as created by nm_connection_to_dbus() for example). Each key in @secrets + * should be the name of a #NMSetting object (like "802-11-wireless-security") + * and each value should be an %NM_VARIANT_TYPE_SETTING variant. The sub-dicts + * map string:value, where the string is the setting property name (like "psk") + * and the value is the secret + * @error: if the secrets request failed, give a descriptive error here + * @user_data: caller-specific data to be passed to the function + * + * Called as a result of a request by NM to retrieve secrets. When the + * #NMSecretAgentOld subclass has finished retrieving secrets and is ready to + * return them, or to return an error, this function should be called with + * those secrets or the error. + * + * To easily create the dictionary to return the Wi-Fi PSK, you could do + * something like this: + * + * Creating a secrets dictionary + * + * NMConnection *secrets; + * NMSettingWirelessSecurity *s_wsec; + * GVariant *secrets_dict; + * + * secrets = nm_simple_connection_new (); + * s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + * g_object_set (G_OBJECT (s_wsec), + * NM_SETTING_WIRELESS_SECURITY_PSK, "my really cool PSK", + * NULL); + * nm_connection_add_setting (secrets, NM_SETTING (s_wsec)); + * secrets_dict = nm_connection_to_dbus (secrets, NM_CONNECTION_SERIALIZE_ALL); + * + * (call the NMSecretAgentOldGetSecretsFunc with secrets_dict) + * + * g_object_unref (secrets); + * g_variant_unref (secrets_dict); + * + * + */ +typedef void (*NMSecretAgentOldGetSecretsFunc)(NMSecretAgentOld *agent, + NMConnection * connection, + GVariant * secrets, + GError * error, + gpointer user_data); + +/** + * NMSecretAgentOldSaveSecretsFunc: + * @agent: the secret agent object + * @connection: (transfer none): the connection for which secrets were to be saved, + * note that this object will be unrefed after the callback has returned, use + * g_object_ref()/g_object_unref() if you want to use this object after the callback + * has returned + * @error: if the saving secrets failed, give a descriptive error here + * @user_data: caller-specific data to be passed to the function + * + * Called as a result of a request by NM to save secrets. When the + * #NMSecretAgentOld subclass has finished saving the secrets, this function + * should be called. + */ +typedef void (*NMSecretAgentOldSaveSecretsFunc)(NMSecretAgentOld *agent, + NMConnection * connection, + GError * error, + gpointer user_data); + +/** + * NMSecretAgentOldDeleteSecretsFunc: + * @agent: the secret agent object + * @connection: (transfer none): the connection for which secrets were to be deleted, + * note that this object will be unrefed after the callback has returned, use + * g_object_ref()/g_object_unref() if you want to use this object after the callback + * has returned + * @error: if the deleting secrets failed, give a descriptive error here + * @user_data: caller-specific data to be passed to the function + * + * Called as a result of a request by NM to delete secrets. When the + * #NMSecretAgentOld subclass has finished deleting the secrets, this function + * should be called. + */ +typedef void (*NMSecretAgentOldDeleteSecretsFunc)(NMSecretAgentOld *agent, + NMConnection * connection, + GError * error, + gpointer user_data); + +typedef struct { + GObjectClass parent; + + /* Virtual methods for subclasses */ + + /* Called when the subclass should retrieve and return secrets. Subclass + * must copy or reference any arguments it may require after returning from + * this method, as the arguments will freed (except for 'self', 'callback', + * and 'user_data' of course). + * + * Before version 1.24, if the request is canceled, the callback + * should still be called, but with the NM_SECRET_AGENT_ERROR_AGENT_CANCELED + * error. Since 1.24, invoking the callback has no effect during cancellation + * and may be omitted. + */ + void (*get_secrets)(NMSecretAgentOld * self, + NMConnection * connection, + const char * connection_path, + const char * setting_name, + const char ** hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer user_data); + + /* Called when the subclass should cancel an outstanding request to + * get secrets for a given connection. + * + * Before version 1.24, canceling the request MUST call the callback that was + * passed along with the initial get_secrets call, sending the NM_SECRET_AGENT_ERROR/ + * NM_SECRET_AGENT_ERROR_AGENT_CANCELED error to that callback. Since 1.24, + * the get_secrets callback will be ignored during cancellation and may be omitted. + */ + void (*cancel_get_secrets)(NMSecretAgentOld *self, + const char * connection_path, + const char * setting_name); + + /* Called when the subclass should save the secrets contained in the + * connection to backing storage. Subclass must copy or reference any + * arguments it may require after returning from this method, as the + * arguments will freed (except for 'self', 'callback', and 'user_data' + * of course). + */ + void (*save_secrets)(NMSecretAgentOld * self, + NMConnection * connection, + const char * connection_path, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer user_data); + + /* Called when the subclass should delete the secrets contained in the + * connection from backing storage. Subclass must copy or reference any + * arguments it may require after returning from this method, as the + * arguments will freed (except for 'self', 'callback', and 'user_data' + * of course). + */ + void (*delete_secrets)(NMSecretAgentOld * self, + NMConnection * connection, + const char * connection_path, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer user_data); + + /*< private >*/ + gpointer padding[8]; +} NMSecretAgentOldClass; + +GType nm_secret_agent_old_get_type(void); + +NM_AVAILABLE_IN_1_24 +GDBusConnection *nm_secret_agent_old_get_dbus_connection(NMSecretAgentOld *self); + +NM_AVAILABLE_IN_1_24 +GMainContext *nm_secret_agent_old_get_main_context(NMSecretAgentOld *self); + +NM_AVAILABLE_IN_1_24 +GObject *nm_secret_agent_old_get_context_busy_watcher(NMSecretAgentOld *self); + +NM_AVAILABLE_IN_1_24 +const char *nm_secret_agent_old_get_dbus_name_owner(NMSecretAgentOld *self); + +gboolean nm_secret_agent_old_get_registered(NMSecretAgentOld *self); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_24 +void nm_secret_agent_old_enable(NMSecretAgentOld *self, gboolean enable); + +void nm_secret_agent_old_register_async(NMSecretAgentOld * self, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean +nm_secret_agent_old_register_finish(NMSecretAgentOld *self, GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_24 +void nm_secret_agent_old_destroy(NMSecretAgentOld *self); + +/*****************************************************************************/ + +NM_DEPRECATED_IN_1_24_FOR(nm_secret_agent_old_enable) +gboolean +nm_secret_agent_old_register(NMSecretAgentOld *self, GCancellable *cancellable, GError **error); + +NM_DEPRECATED_IN_1_24_FOR(nm_secret_agent_old_enable) +gboolean +nm_secret_agent_old_unregister(NMSecretAgentOld *self, GCancellable *cancellable, GError **error); + +NM_DEPRECATED_IN_1_24_FOR(nm_secret_agent_old_enable) +void nm_secret_agent_old_unregister_async(NMSecretAgentOld * self, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +NM_DEPRECATED_IN_1_24_FOR(nm_secret_agent_old_enable) +gboolean +nm_secret_agent_old_unregister_finish(NMSecretAgentOld *self, GAsyncResult *result, GError **error); + +/*****************************************************************************/ + +void nm_secret_agent_old_get_secrets(NMSecretAgentOld * self, + NMConnection * connection, + const char * setting_name, + const char ** hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer user_data); + +void nm_secret_agent_old_save_secrets(NMSecretAgentOld * self, + NMConnection * connection, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer user_data); + +void nm_secret_agent_old_delete_secrets(NMSecretAgentOld * self, + NMConnection * connection, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer user_data); + +G_END_DECLS + +#endif /* __NM_SECRET_AGENT_OLD_H__ */ diff --git a/src/libnm-client-public/nm-types.h b/src/libnm-client-public/nm-types.h new file mode 100644 index 0000000..81ffe79 --- /dev/null +++ b/src/libnm-client-public/nm-types.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 - 2018 Red Hat, Inc. + */ + +#ifndef __NM_TYPES_H__ +#define __NM_TYPES_H__ + +#include + +#include "nm-dbus-interface.h" +#include "nm-connection.h" + +typedef struct _NMAccessPoint NMAccessPoint; +typedef struct _NMActiveConnection NMActiveConnection; +typedef struct _NMCheckpoint NMCheckpoint; +typedef struct _NMClient NMClient; +typedef struct _NMDevice NMDevice; +typedef struct _NMDevice6Lowpan NMDevice6Lowpan; +typedef struct _NMDeviceAdsl NMDeviceAdsl; +typedef struct _NMDeviceBond NMDeviceBond; +typedef struct _NMDeviceBridge NMDeviceBridge; +typedef struct _NMDeviceBt NMDeviceBt; +typedef struct _NMDeviceDummy NMDeviceDummy; +typedef struct _NMDeviceEthernet NMDeviceEthernet; +typedef struct _NMDeviceGeneric NMDeviceGeneric; +typedef struct _NMDeviceIPTunnel NMDeviceIPTunnel; +typedef struct _NMDeviceInfiniband NMDeviceInfiniband; +typedef struct _NMDeviceMacsec NMDeviceMacsec; +typedef struct _NMDeviceMacvlan NMDeviceMacvlan; +typedef struct _NMDeviceModem NMDeviceModem; +typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh; +typedef struct _NMDeviceOvsBridge NMDeviceOvsBridge; +typedef struct _NMDeviceOvsInterface NMDeviceOvsInterface; +typedef struct _NMDeviceOvsPort NMDeviceOvsPort; +typedef struct _NMDevicePpp NMDevicePpp; +typedef struct _NMDeviceTeam NMDeviceTeam; +typedef struct _NMDeviceTun NMDeviceTun; +typedef struct _NMDeviceVeth NMDeviceVeth; +typedef struct _NMDeviceVlan NMDeviceVlan; +typedef struct _NMDeviceVrf NMDeviceVrf; +typedef struct _NMDeviceVxlan NMDeviceVxlan; +typedef struct _NMDeviceWifi NMDeviceWifi; +typedef struct _NMDeviceWifiP2P NMDeviceWifiP2P; +typedef struct _NMDeviceWimax NMDeviceWimax; +typedef struct _NMDeviceWireGuard NMDeviceWireGuard; +typedef struct _NMDeviceWpan NMDeviceWpan; +typedef struct _NMDhcpConfig NMDhcpConfig; +typedef struct _NMIPConfig NMIPConfig; +typedef struct _NMObject NMObject; +typedef struct _NMRemoteConnection NMRemoteConnection; +typedef struct _NMVpnConnection NMVpnConnection; +typedef struct _NMWifiP2PPeer NMWifiP2PPeer; +typedef struct _NMWimaxNsp NMWimaxNsp; + +#endif /* NM_TYPES_H */ diff --git a/src/libnm-client-public/nm-vpn-connection.h b/src/libnm-client-public/nm-vpn-connection.h new file mode 100644 index 0000000..aac259d --- /dev/null +++ b/src/libnm-client-public/nm-vpn-connection.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2010 Red Hat, Inc. + */ + +#ifndef __NM_VPN_CONNECTION_H__ +#define __NM_VPN_CONNECTION_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-active-connection.h" +#include "nm-vpn-dbus-interface.h" + +G_BEGIN_DECLS + +#define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type()) +#define NM_VPN_CONNECTION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_VPN_CONNECTION, NMVpnConnection)) +#define NM_VPN_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_VPN_CONNECTION, NMVpnConnectionClass)) +#define NM_IS_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_VPN_CONNECTION)) +#define NM_IS_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_VPN_CONNECTION)) +#define NM_VPN_CONNECTION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_VPN_CONNECTION, NMVpnConnectionClass)) + +#define NM_VPN_CONNECTION_VPN_STATE "vpn-state" +#define NM_VPN_CONNECTION_BANNER "banner" + +/** + * NMVpnConnection: + */ +typedef struct _NMVpnConnectionClass NMVpnConnectionClass; + +GType nm_vpn_connection_get_type(void); + +NMVpnConnectionState nm_vpn_connection_get_vpn_state(NMVpnConnection *vpn); +const char * nm_vpn_connection_get_banner(NMVpnConnection *vpn); + +G_END_DECLS + +#endif /* __NM_VPN_CONNECTION_H__ */ diff --git a/src/libnm-client-public/nm-vpn-editor.h b/src/libnm-client-public/nm-vpn-editor.h new file mode 100644 index 0000000..8cd7805 --- /dev/null +++ b/src/libnm-client-public/nm-vpn-editor.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_VPN_EDITOR_H__ +#define __NM_VPN_EDITOR_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include +#include +#include "nm-types.h" + +#include "nm-vpn-editor-plugin.h" + +G_BEGIN_DECLS + +/*****************************************************************************/ +/* Editor interface */ +/*****************************************************************************/ + +#define NM_TYPE_VPN_EDITOR (nm_vpn_editor_get_type()) +#define NM_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_VPN_EDITOR, NMVpnEditor)) +#define NM_IS_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_VPN_EDITOR)) +#define NM_VPN_EDITOR_GET_INTERFACE(obj) \ + (G_TYPE_INSTANCE_GET_INTERFACE((obj), NM_TYPE_VPN_EDITOR, NMVpnEditorInterface)) + +/** + * NMVpnEditorInterface: + * @g_iface: the parent interface + * @get_widget: return the #GtkWidget for the VPN editor's UI + * @placeholder: not currently used + * @update_connection: called to save the user-entered options to the connection + * object. Should return %FALSE and set @error if the current options are + * invalid. @error should contain enough information for the plugin to + * determine which UI widget is invalid at a later point in time. For + * example, creating unique error codes for what error occurred and populating + * the message field of @error with the name of the invalid property. + * @changed: emitted when the value of a UI widget changes. May trigger a + * validity check via @update_connection to write values to the connection. + * + * Interface for editing a specific #NMConnection + */ +typedef struct { + GTypeInterface g_iface; + + GObject *(*get_widget)(NMVpnEditor *editor); + + void (*placeholder)(void); + + gboolean (*update_connection)(NMVpnEditor *editor, NMConnection *connection, GError **error); + + void (*changed)(NMVpnEditor *editor); +} NMVpnEditorInterface; + +GType nm_vpn_editor_get_type(void); + +GObject *nm_vpn_editor_get_widget(NMVpnEditor *editor); + +gboolean +nm_vpn_editor_update_connection(NMVpnEditor *editor, NMConnection *connection, GError **error); + +G_END_DECLS + +#endif /* __NM_VPN_EDITOR_H__ */ diff --git a/src/libnm-client-public/nm-vpn-plugin-old.h b/src/libnm-client-public/nm-vpn-plugin-old.h new file mode 100644 index 0000000..116b8b9 --- /dev/null +++ b/src/libnm-client-public/nm-vpn-plugin-old.h @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_VPN_PLUGIN_OLD_H__ +#define __NM_VPN_PLUGIN_OLD_H__ + +#include +#include "nm-vpn-dbus-interface.h" +#include "nm-connection.h" + +G_BEGIN_DECLS + +#define NM_TYPE_VPN_PLUGIN_OLD (nm_vpn_plugin_old_get_type()) +#define NM_VPN_PLUGIN_OLD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOld)) +#define NM_VPN_PLUGIN_OLD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOldClass)) +#define NM_IS_VPN_PLUGIN_OLD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_VPN_PLUGIN_OLD)) +#define NM_IS_VPN_PLUGIN_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_VPN_PLUGIN_OLD)) +#define NM_VPN_PLUGIN_OLD_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOldClass)) + +#define NM_VPN_PLUGIN_OLD_DBUS_SERVICE_NAME "service-name" +#define NM_VPN_PLUGIN_OLD_STATE "state" + +/** + * NMVpnPluginOld: + */ +typedef struct { + NM_DEPRECATED_IN_1_2 + GObject parent; +} NMVpnPluginOld NM_DEPRECATED_IN_1_2; + +typedef struct { + NM_DEPRECATED_IN_1_2 + GObjectClass parent; + + /* Signals */ + NM_DEPRECATED_IN_1_2 + void (*state_changed)(NMVpnPluginOld *plugin, NMVpnServiceState state); + + NM_DEPRECATED_IN_1_2 + void (*ip4_config)(NMVpnPluginOld *plugin, GVariant *ip4_config); + + NM_DEPRECATED_IN_1_2 + void (*login_banner)(NMVpnPluginOld *plugin, const char *banner); + + NM_DEPRECATED_IN_1_2 + void (*failure)(NMVpnPluginOld *plugin, NMVpnPluginFailure reason); + + NM_DEPRECATED_IN_1_2 + void (*quit)(NMVpnPluginOld *plugin); + + NM_DEPRECATED_IN_1_2 + void (*config)(NMVpnPluginOld *plugin, GVariant *config); + + NM_DEPRECATED_IN_1_2 + void (*ip6_config)(NMVpnPluginOld *plugin, GVariant *config); + + /* virtual methods */ + NM_DEPRECATED_IN_1_2 + gboolean (*connect)(NMVpnPluginOld *plugin, NMConnection *connection, GError **err); + + NM_DEPRECATED_IN_1_2 + gboolean (*need_secrets)(NMVpnPluginOld *plugin, + NMConnection * connection, + const char ** setting_name, + GError ** error); + + NM_DEPRECATED_IN_1_2 + gboolean (*disconnect)(NMVpnPluginOld *plugin, GError **err); + + NM_DEPRECATED_IN_1_2 + gboolean (*new_secrets)(NMVpnPluginOld *plugin, NMConnection *connection, GError **error); + + NM_DEPRECATED_IN_1_2 + gboolean (*connect_interactive)(NMVpnPluginOld *plugin, + NMConnection * connection, + GVariant * details, + GError ** error); + + /*< private >*/ + NM_DEPRECATED_IN_1_2 + gpointer padding[8]; +} NMVpnPluginOldClass NM_DEPRECATED_IN_1_2; + +NM_DEPRECATED_IN_1_2 +GType nm_vpn_plugin_old_get_type(void); + +NM_DEPRECATED_IN_1_2 +GDBusConnection *nm_vpn_plugin_old_get_connection(NMVpnPluginOld *plugin); +NM_DEPRECATED_IN_1_2 +NMVpnServiceState nm_vpn_plugin_old_get_state(NMVpnPluginOld *plugin); +NM_DEPRECATED_IN_1_2 +void nm_vpn_plugin_old_set_state(NMVpnPluginOld *plugin, NMVpnServiceState state); + +NM_DEPRECATED_IN_1_2 +void +nm_vpn_plugin_old_secrets_required(NMVpnPluginOld *plugin, const char *message, const char **hints); + +NM_DEPRECATED_IN_1_2 +void nm_vpn_plugin_old_set_login_banner(NMVpnPluginOld *plugin, const char *banner); + +NM_DEPRECATED_IN_1_2 +void nm_vpn_plugin_old_failure(NMVpnPluginOld *plugin, NMVpnPluginFailure reason); + +NM_DEPRECATED_IN_1_2 +void nm_vpn_plugin_old_set_config(NMVpnPluginOld *plugin, GVariant *config); + +NM_DEPRECATED_IN_1_2 +void nm_vpn_plugin_old_set_ip4_config(NMVpnPluginOld *plugin, GVariant *ip4_config); + +NM_DEPRECATED_IN_1_2 +void nm_vpn_plugin_old_set_ip6_config(NMVpnPluginOld *plugin, GVariant *ip6_config); + +NM_DEPRECATED_IN_1_2 +gboolean nm_vpn_plugin_old_disconnect(NMVpnPluginOld *plugin, GError **err); + +/* Utility functions */ + +NM_DEPRECATED_IN_1_2 +gboolean +nm_vpn_plugin_old_read_vpn_details(int fd, GHashTable **out_data, GHashTable **out_secrets); + +NM_DEPRECATED_IN_1_2 +gboolean nm_vpn_plugin_old_get_secret_flags(GHashTable * data, + const char * secret_name, + NMSettingSecretFlags *out_flags); + +G_END_DECLS + +#endif /* __NM_VPN_PLUGIN_OLD_H__ */ diff --git a/src/libnm-client-public/nm-vpn-service-plugin.h b/src/libnm-client-public/nm-vpn-service-plugin.h new file mode 100644 index 0000000..e45622a --- /dev/null +++ b/src/libnm-client-public/nm-vpn-service-plugin.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_VPN_SERVICE_PLUGIN_H__ +#define __NM_VPN_SERVICE_PLUGIN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include +#include "nm-vpn-dbus-interface.h" +#include "nm-connection.h" + +G_BEGIN_DECLS + +#define NM_TYPE_VPN_SERVICE_PLUGIN (nm_vpn_service_plugin_get_type()) +#define NM_VPN_SERVICE_PLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePlugin)) +#define NM_VPN_SERVICE_PLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePluginClass)) +#define NM_IS_VPN_SERVICE_PLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_VPN_SERVICE_PLUGIN)) +#define NM_IS_VPN_SERVICE_PLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_VPN_SERVICE_PLUGIN)) +#define NM_VPN_SERVICE_PLUGIN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePluginClass)) + +#define NM_VPN_SERVICE_PLUGIN_DBUS_SERVICE_NAME "service-name" +#define NM_VPN_SERVICE_PLUGIN_DBUS_WATCH_PEER "watch-peer" +#define NM_VPN_SERVICE_PLUGIN_STATE "state" + +/** + * NMVpnServicePlugin: + */ +typedef struct { + NM_AVAILABLE_IN_1_2 + GObject parent; +} NMVpnServicePlugin NM_AVAILABLE_IN_1_2; + +typedef struct { + NM_AVAILABLE_IN_1_2 + GObjectClass parent; + + /* Signals */ + NM_AVAILABLE_IN_1_2 + void (*state_changed)(NMVpnServicePlugin *plugin, NMVpnServiceState state); + + NM_AVAILABLE_IN_1_2 + void (*ip4_config)(NMVpnServicePlugin *plugin, GVariant *ip4_config); + + NM_AVAILABLE_IN_1_2 + void (*login_banner)(NMVpnServicePlugin *plugin, const char *banner); + + NM_AVAILABLE_IN_1_2 + void (*failure)(NMVpnServicePlugin *plugin, NMVpnPluginFailure reason); + + NM_AVAILABLE_IN_1_2 + void (*quit)(NMVpnServicePlugin *plugin); + + NM_AVAILABLE_IN_1_2 + void (*config)(NMVpnServicePlugin *plugin, GVariant *config); + + NM_AVAILABLE_IN_1_2 + void (*ip6_config)(NMVpnServicePlugin *plugin, GVariant *config); + + /* virtual methods */ + NM_AVAILABLE_IN_1_2 + gboolean (*connect)(NMVpnServicePlugin *plugin, NMConnection *connection, GError **err); + + NM_AVAILABLE_IN_1_2 + gboolean (*need_secrets)(NMVpnServicePlugin *plugin, + NMConnection * connection, + const char ** setting_name, + GError ** error); + + NM_AVAILABLE_IN_1_2 + gboolean (*disconnect)(NMVpnServicePlugin *plugin, GError **err); + + NM_AVAILABLE_IN_1_2 + gboolean (*new_secrets)(NMVpnServicePlugin *plugin, NMConnection *connection, GError **error); + + NM_AVAILABLE_IN_1_2 + gboolean (*connect_interactive)(NMVpnServicePlugin *plugin, + NMConnection * connection, + GVariant * details, + GError ** error); + + /*< private >*/ + NM_AVAILABLE_IN_1_2 + gpointer padding[8]; +} NMVpnServicePluginClass NM_AVAILABLE_IN_1_2; + +NM_AVAILABLE_IN_1_2 +GType nm_vpn_service_plugin_get_type(void); + +NM_AVAILABLE_IN_1_2 +GDBusConnection *nm_vpn_service_plugin_get_connection(NMVpnServicePlugin *plugin); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_secrets_required(NMVpnServicePlugin *plugin, + const char * message, + const char ** hints); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_set_login_banner(NMVpnServicePlugin *plugin, const char *banner); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_failure(NMVpnServicePlugin *plugin, NMVpnPluginFailure reason); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_set_config(NMVpnServicePlugin *plugin, GVariant *config); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_set_ip4_config(NMVpnServicePlugin *plugin, GVariant *ip4_config); + +NM_AVAILABLE_IN_1_2 +void nm_vpn_service_plugin_set_ip6_config(NMVpnServicePlugin *plugin, GVariant *ip6_config); + +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_service_plugin_disconnect(NMVpnServicePlugin *plugin, GError **err); + +NM_AVAILABLE_IN_1_12 +void nm_vpn_service_plugin_shutdown(NMVpnServicePlugin *plugin); + +/* Utility functions */ + +NM_AVAILABLE_IN_1_2 +gboolean +nm_vpn_service_plugin_read_vpn_details(int fd, GHashTable **out_data, GHashTable **out_secrets); + +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_service_plugin_get_secret_flags(GHashTable * data, + const char * secret_name, + NMSettingSecretFlags *out_flags); + +G_END_DECLS + +#endif /* __NM_VPN_SERVICE_PLUGIN_H__ */ diff --git a/src/libnm-client-public/nm-wifi-p2p-peer.h b/src/libnm-client-public/nm-wifi-p2p-peer.h new file mode 100644 index 0000000..4ab7c0e --- /dev/null +++ b/src/libnm-client-public/nm-wifi-p2p-peer.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 - 2019 Red Hat, Inc. + */ + +#ifndef __NM_WIFI_P2P_PEER_H__ +#define __NM_WIFI_P2P_PEER_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_WIFI_P2P_PEER (nm_wifi_p2p_peer_get_type()) +#define NM_WIFI_P2P_PEER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeer)) +#define NM_WIFI_P2P_PEER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeerClass)) +#define NM_IS_WIFI_P2P_PEER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WIFI_P2P_PEER)) +#define NM_IS_WIFI_P2P_PEER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WIFI_P2P_PEER)) +#define NM_WIFI_P2P_PEER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeerClass)) + +#define NM_WIFI_P2P_PEER_FLAGS "flags" +#define NM_WIFI_P2P_PEER_NAME "name" +#define NM_WIFI_P2P_PEER_MANUFACTURER "manufacturer" +#define NM_WIFI_P2P_PEER_MODEL "model" +#define NM_WIFI_P2P_PEER_MODEL_NUMBER "model-number" +#define NM_WIFI_P2P_PEER_SERIAL "serial" +#define NM_WIFI_P2P_PEER_WFD_IES "wfd-ies" +#define NM_WIFI_P2P_PEER_HW_ADDRESS "hw-address" +#define NM_WIFI_P2P_PEER_STRENGTH "strength" +#define NM_WIFI_P2P_PEER_LAST_SEEN "last-seen" + +/** + * NMWifiP2PPeer: + */ +typedef struct _NMWifiP2PPeerClass NMWifiP2PPeerClass; + +NM_AVAILABLE_IN_1_16 +GType nm_wifi_p2p_peer_get_type(void); + +NM_AVAILABLE_IN_1_16 +NM80211ApFlags nm_wifi_p2p_peer_get_flags(NMWifiP2PPeer *peer); + +NM_AVAILABLE_IN_1_16 +const char *nm_wifi_p2p_peer_get_name(NMWifiP2PPeer *peer); +NM_AVAILABLE_IN_1_16 +const char *nm_wifi_p2p_peer_get_manufacturer(NMWifiP2PPeer *peer); +NM_AVAILABLE_IN_1_16 +const char *nm_wifi_p2p_peer_get_model(NMWifiP2PPeer *peer); +NM_AVAILABLE_IN_1_16 +const char *nm_wifi_p2p_peer_get_model_number(NMWifiP2PPeer *peer); +NM_AVAILABLE_IN_1_16 +const char *nm_wifi_p2p_peer_get_serial(NMWifiP2PPeer *peer); + +NM_AVAILABLE_IN_1_16 +GBytes *nm_wifi_p2p_peer_get_wfd_ies(NMWifiP2PPeer *peer); + +NM_AVAILABLE_IN_1_16 +const char *nm_wifi_p2p_peer_get_hw_address(NMWifiP2PPeer *peer); + +NM_AVAILABLE_IN_1_16 +guint8 nm_wifi_p2p_peer_get_strength(NMWifiP2PPeer *peer); +NM_AVAILABLE_IN_1_16 +int nm_wifi_p2p_peer_get_last_seen(NMWifiP2PPeer *peer); + +NM_AVAILABLE_IN_1_16 +GPtrArray *nm_wifi_p2p_peer_filter_connections(NMWifiP2PPeer *peer, const GPtrArray *connections); + +NM_AVAILABLE_IN_1_16 +gboolean nm_wifi_p2p_peer_connection_valid(NMWifiP2PPeer *peer, NMConnection *connection); + +G_END_DECLS + +#endif /* __NM_WIFI_P2P_PEER_H__ */ diff --git a/src/libnm-client-public/nm-wimax-nsp.h b/src/libnm-client-public/nm-wimax-nsp.h new file mode 100644 index 0000000..15b8daa --- /dev/null +++ b/src/libnm-client-public/nm-wimax-nsp.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 Red Hat, Inc. + * Copyright (C) 2009 Novell, Inc. + */ + +#ifndef __NM_WIMAX_NSP_H__ +#define __NM_WIMAX_NSP_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_WIMAX_NSP (nm_wimax_nsp_get_type()) +#define NM_WIMAX_NSP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIMAX_NSP, NMWimaxNsp)) +#define NM_WIMAX_NSP_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WIMAX_NSP, NMWimaxNspClass)) +#define NM_IS_WIMAX_NSP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WIMAX_NSP)) +#define NM_IS_WIMAX_NSP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WIMAX_NSP)) +#define NM_WIMAX_NSP_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WIMAX_NSP, NMWimaxNspClass)) + +#define NM_WIMAX_NSP_NAME "name" +#define NM_WIMAX_NSP_SIGNAL_QUALITY "signal-quality" +#define NM_WIMAX_NSP_NETWORK_TYPE "network-type" + +/** + * NMWimaxNsp: + * + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. + */ +typedef struct _NMWimaxNspClass NMWimaxNspClass; + +GType nm_wimax_nsp_get_type(void); + +NM_DEPRECATED_IN_1_22 +const char *nm_wimax_nsp_get_name(NMWimaxNsp *nsp); +NM_DEPRECATED_IN_1_22 +guint32 nm_wimax_nsp_get_signal_quality(NMWimaxNsp *nsp); +NM_DEPRECATED_IN_1_22 +NMWimaxNspNetworkType nm_wimax_nsp_get_network_type(NMWimaxNsp *nsp); + +NM_DEPRECATED_IN_1_22 +GPtrArray *nm_wimax_nsp_filter_connections(NMWimaxNsp *nsp, const GPtrArray *connections); + +NM_DEPRECATED_IN_1_22 +gboolean nm_wimax_nsp_connection_valid(NMWimaxNsp *nsp, NMConnection *connection); + +G_END_DECLS + +#endif /* __NM_WIMAX_NSP_H__ */ diff --git a/src/libnm-client-test/meson.build b/src/libnm-client-test/meson.build new file mode 100644 index 0000000..8e2fba1 --- /dev/null +++ b/src/libnm-client-test/meson.build @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_client_test = static_library( + 'nm-client-test', + sources: files( + 'nm-test-utils-impl.c', + ), + include_directories: [ + libnm_core_public_inc, + libnm_client_public_inc, + src_inc, + top_inc, + ], + dependencies: [ + libnm_core_public_dep, + glib_dep, + ], +) diff --git a/src/libnm-client-test/nm-test-libnm-utils.h b/src/libnm-client-test/nm-test-libnm-utils.h new file mode 100644 index 0000000..5890930 --- /dev/null +++ b/src/libnm-client-test/nm-test-libnm-utils.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_TEST_LIBNM_UTILS_H__ +#define __NM_TEST_LIBNM_UTILS_H__ + +#include "NetworkManager.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +typedef struct { + GDBusConnection *bus; + GDBusProxy * proxy; + GPid pid; + int keepalive_fd; +} NMTstcServiceInfo; + +NMTstcServiceInfo *nmtstc_service_init(void); +void nmtstc_service_cleanup(NMTstcServiceInfo *info); +NMTstcServiceInfo *nmtstc_service_available(NMTstcServiceInfo *info); + +static inline void +_nmtstc_auto_service_cleanup(NMTstcServiceInfo **info) +{ + nmtstc_service_cleanup(g_steal_pointer(info)); +} +#define nmtstc_auto_service_cleanup nm_auto(_nmtstc_auto_service_cleanup) + +#define NMTSTC_SERVICE_INFO_SETUP(sinfo) \ + NM_PRAGMA_WARNING_DISABLE("-Wunused-variable") \ + nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = ({ \ + NMTstcServiceInfo *_sinfo; \ + \ + _sinfo = nmtstc_service_init(); \ + if (!nmtstc_service_available(_sinfo)) \ + return; \ + _sinfo; \ + }); \ + NM_PRAGMA_WARNING_REENABLE + +NMDevice *nmtstc_service_add_device(NMTstcServiceInfo *info, + NMClient * client, + const char * method, + const char * ifname); + +NMDevice *nmtstc_service_add_wired_device(NMTstcServiceInfo *sinfo, + NMClient * client, + const char * ifname, + const char * hwaddr, + const char ** subchannels); + +void nmtstc_service_add_connection(NMTstcServiceInfo *sinfo, + NMConnection * connection, + gboolean verify_connection, + char ** out_path); + +void nmtstc_service_add_connection_variant(NMTstcServiceInfo *sinfo, + GVariant * connection, + gboolean verify_connection, + char ** out_path); + +void nmtstc_service_update_connection(NMTstcServiceInfo *sinfo, + const char * path, + NMConnection * connection, + gboolean verify_connection); + +void nmtstc_service_update_connection_variant(NMTstcServiceInfo *sinfo, + const char * path, + GVariant * connection, + gboolean verify_connection); + +gpointer nmtstc_context_object_new_valist(GType gtype, + gboolean allow_iterate_main_context, + const char *first_property_name, + va_list var_args); + +gpointer nmtstc_context_object_new(GType gtype, + gboolean allow_iterate_main_context, + const char *first_property_name, + ...); + +static inline NMClient * +nmtstc_client_new(gboolean allow_iterate_main_context) +{ + return nmtstc_context_object_new(NM_TYPE_CLIENT, allow_iterate_main_context, NULL); +} + +#endif /* __NM_TEST_LIBNM_UTILS_H__ */ diff --git a/src/libnm-client-test/nm-test-utils-impl.c b/src/libnm-client-test/nm-test-utils-impl.c new file mode 100644 index 0000000..610232b --- /dev/null +++ b/src/libnm-client-test/nm-test-utils-impl.c @@ -0,0 +1,644 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2010 - 2015 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include + +#include "NetworkManager.h" +#include "libnm-std-aux/nm-dbus-compat.h" + +#include "libnm-client-test/nm-test-libnm-utils.h" + +#define NMTSTC_NM_SERVICE NM_BUILD_SRCDIR "/tools/test-networkmanager-service.py" + +/*****************************************************************************/ + +static gboolean +name_exists(GDBusConnection *c, const char *name) +{ + GVariant *reply; + gboolean exists = FALSE; + + reply = g_dbus_connection_call_sync(c, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetNameOwner", + g_variant_new("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + NULL); + if (reply != NULL) { + exists = TRUE; + g_variant_unref(reply); + } + + return exists; +} + +typedef struct { + GMainLoop * mainloop; + GDBusConnection *bus; + int exit_code; + bool exited : 1; + bool name_found : 1; +} ServiceInitWaitData; + +static gboolean +_service_init_wait_probe_name(gpointer user_data) +{ + ServiceInitWaitData *data = user_data; + + if (!name_exists(data->bus, "org.freedesktop.NetworkManager")) + return G_SOURCE_CONTINUE; + + data->name_found = TRUE; + g_main_loop_quit(data->mainloop); + return G_SOURCE_REMOVE; +} + +static void +_service_init_wait_child_wait(GPid pid, int status, gpointer user_data) +{ + ServiceInitWaitData *data = user_data; + + data->exited = TRUE; + data->exit_code = status; + g_main_loop_quit(data->mainloop); +} + +NMTstcServiceInfo * +nmtstc_service_available(NMTstcServiceInfo *info) +{ + gs_free char *m = NULL; + + if (info) + return info; + + /* This happens, when test-networkmanager-service.py exits with 77 status + * code. */ + m = g_strdup_printf("missing dependency for running NetworkManager stub service %s", + NMTSTC_NM_SERVICE); + g_test_skip(m); + return NULL; +} + +NMTstcServiceInfo * +nmtstc_service_init(void) +{ + NMTstcServiceInfo *info; + const char * args[] = {TEST_NM_PYTHON, NMTSTC_NM_SERVICE, NULL}; + GError * error = NULL; + + info = g_malloc0(sizeof(*info)); + + info->bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error(error); + + /* Spawn the test service. info->keepalive_fd will be a pipe to the service's + * stdin; if it closes, the service will exit immediately. We use this to + * make sure the service exits if the test program crashes. + */ + g_spawn_async_with_pipes(NULL, + (char **) args, + NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &info->pid, + &info->keepalive_fd, + NULL, + NULL, + &error); + g_assert_no_error(error); + + { + nm_auto_unref_gsource GSource *timeout_source = NULL; + nm_auto_unref_gsource GSource *child_source = NULL; + GMainContext * context = g_main_context_new(); + ServiceInitWaitData data = { + .bus = info->bus, + .mainloop = g_main_loop_new(context, FALSE), + }; + gboolean had_timeout; + + timeout_source = g_timeout_source_new(50); + g_source_set_callback(timeout_source, _service_init_wait_probe_name, &data, NULL); + g_source_attach(timeout_source, context); + + child_source = g_child_watch_source_new(info->pid); + g_source_set_callback(child_source, + G_SOURCE_FUNC(_service_init_wait_child_wait), + &data, + NULL); + g_source_attach(child_source, context); + + had_timeout = !nmtst_main_loop_run(data.mainloop, 30000); + + g_source_destroy(timeout_source); + g_source_destroy(child_source); + g_main_loop_unref(data.mainloop); + g_main_context_unref(context); + + if (had_timeout) + g_error("test service %s did not start in time", NMTSTC_NM_SERVICE); + if (!data.name_found) { + g_assert(data.exited); + info->pid = NM_PID_T_INVAL; + nmtstc_service_cleanup(info); + + if (WIFEXITED(data.exit_code) && WEXITSTATUS(data.exit_code) == 77) { + /* If the stub service exited with status 77 it means that it decided + * that it cannot conduct the tests and the test should be (gracefully) + * skip. The likely reason for that, is that libnm is not available + * via pygobject. */ + return NULL; + } + g_error("test service %s exited with error code %d", NMTSTC_NM_SERVICE, data.exit_code); + } + } + + /* Grab a proxy to our fake NM service to trigger tests */ + info->proxy = g_dbus_proxy_new_sync(info->bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS + | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + NM_DBUS_SERVICE, + NM_DBUS_PATH, + "org.freedesktop.NetworkManager.LibnmGlibTest", + NULL, + &error); + g_assert_no_error(error); + + return info; +} + +void +nmtstc_service_cleanup(NMTstcServiceInfo *info) +{ + int ret; + gint64 t; + int status; + + if (!info) + return; + + nm_close(nm_steal_fd(&info->keepalive_fd)); + + g_clear_object(&info->proxy); + + if (info->pid != NM_PID_T_INVAL) { + kill(info->pid, SIGTERM); + + t = g_get_monotonic_time(); +again_wait: + ret = waitpid(info->pid, &status, WNOHANG); + if (ret == 0) { + if (t + 2000000 < g_get_monotonic_time()) { + kill(info->pid, SIGKILL); + g_error("child process %lld did not exit within timeout", (long long) info->pid); + } + g_usleep(G_USEC_PER_SEC / 50); + goto again_wait; + } + if (ret == -1 && errno == EINTR) + goto again_wait; + + g_assert(ret == info->pid); + } + + nmtst_main_context_iterate_until_assert_full( + NULL, + 1000, + 80, + (!name_exists(info->bus, "org.freedesktop.NetworkManager"))); + + g_clear_object(&info->bus); + + memset(info, 0, sizeof(*info)); + g_free(info); +} + +typedef struct { + GMainLoop * loop; + const char *ifname; + const char *path; + NMDevice * device; +} AddDeviceInfo; + +static void +device_added_cb(NMClient *client, NMDevice *device, gpointer user_data) +{ + AddDeviceInfo *info = user_data; + + g_assert(info); + g_assert(!info->device); + + g_assert(NM_IS_DEVICE(device)); + g_assert_cmpstr(nm_object_get_path(NM_OBJECT(device)), ==, info->path); + g_assert_cmpstr(nm_device_get_iface(device), ==, info->ifname); + + info->device = g_object_ref(device); + g_main_loop_quit(info->loop); +} + +static GVariant * +call_add_wired_device(GDBusProxy * proxy, + const char * ifname, + const char * hwaddr, + const char **subchannels, + GError ** error) +{ + const char *empty[] = {NULL}; + + if (!hwaddr) + hwaddr = "/"; + if (!subchannels) + subchannels = empty; + + return g_dbus_proxy_call_sync(proxy, + "AddWiredDevice", + g_variant_new("(ss^as)", ifname, hwaddr, subchannels), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + error); +} + +static GVariant * +call_add_device(GDBusProxy *proxy, const char *method, const char *ifname, GError **error) +{ + return g_dbus_proxy_call_sync(proxy, + method, + g_variant_new("(s)", ifname), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + error); +} + +static NMDevice * +add_device_common(NMTstcServiceInfo *sinfo, + NMClient * client, + const char * method, + const char * ifname, + const char * hwaddr, + const char ** subchannels) +{ + nm_auto_unref_gmainloop GMainLoop *loop = NULL; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + AddDeviceInfo info; + + g_assert(sinfo); + g_assert(NM_IS_CLIENT(client)); + + if (nm_streq0(method, "AddWiredDevice")) + ret = call_add_wired_device(sinfo->proxy, ifname, hwaddr, subchannels, &error); + else + ret = call_add_device(sinfo->proxy, method, ifname, &error); + + nmtst_assert_success(ret, error); + g_assert_cmpstr(g_variant_get_type_string(ret), ==, "(o)"); + + /* Wait for NMClient to find the device */ + + loop = g_main_loop_new(nm_client_get_main_context(client), FALSE); + + info = (AddDeviceInfo){ + .ifname = ifname, + .loop = loop, + }; + g_variant_get(ret, "(&o)", &info.path); + + g_signal_connect(client, NM_CLIENT_DEVICE_ADDED, G_CALLBACK(device_added_cb), &info); + + if (!nmtst_main_loop_run(loop, 5000)) + g_assert_not_reached(); + + g_signal_handlers_disconnect_by_func(client, device_added_cb, &info); + + g_assert(NM_IS_DEVICE(info.device)); + + g_assert(info.device + == nm_client_get_device_by_path(client, nm_object_get_path(NM_OBJECT(info.device)))); + g_object_unref(info.device); + return info.device; +} + +NMDevice * +nmtstc_service_add_device(NMTstcServiceInfo *sinfo, + NMClient * client, + const char * method, + const char * ifname) +{ + return add_device_common(sinfo, client, method, ifname, NULL, NULL); +} + +NMDevice * +nmtstc_service_add_wired_device(NMTstcServiceInfo *sinfo, + NMClient * client, + const char * ifname, + const char * hwaddr, + const char ** subchannels) +{ + return add_device_common(sinfo, client, "AddWiredDevice", ifname, hwaddr, subchannels); +} + +void +nmtstc_service_add_connection(NMTstcServiceInfo *sinfo, + NMConnection * connection, + gboolean verify_connection, + char ** out_path) +{ + nmtstc_service_add_connection_variant( + sinfo, + nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL), + verify_connection, + out_path); +} + +void +nmtstc_service_add_connection_variant(NMTstcServiceInfo *sinfo, + GVariant * connection, + gboolean verify_connection, + char ** out_path) +{ + GVariant *result; + GError * error = NULL; + + g_assert(sinfo); + g_assert(G_IS_DBUS_PROXY(sinfo->proxy)); + g_assert(g_variant_is_of_type(connection, G_VARIANT_TYPE("a{sa{sv}}"))); + + result = g_dbus_proxy_call_sync(sinfo->proxy, + "AddConnection", + g_variant_new("(vb)", connection, verify_connection), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error(error); + g_assert(g_variant_is_of_type(result, G_VARIANT_TYPE("(o)"))); + if (out_path) + g_variant_get(result, "(o)", out_path); + g_variant_unref(result); +} + +void +nmtstc_service_update_connection(NMTstcServiceInfo *sinfo, + const char * path, + NMConnection * connection, + gboolean verify_connection) +{ + if (!path) + path = nm_connection_get_path(connection); + g_assert(path); + + nmtstc_service_update_connection_variant( + sinfo, + path, + nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL), + verify_connection); +} + +void +nmtstc_service_update_connection_variant(NMTstcServiceInfo *sinfo, + const char * path, + GVariant * connection, + gboolean verify_connection) +{ + GVariant *result; + GError * error = NULL; + + g_assert(sinfo); + g_assert(G_IS_DBUS_PROXY(sinfo->proxy)); + g_assert(g_variant_is_of_type(connection, G_VARIANT_TYPE("a{sa{sv}}"))); + g_assert(path && path[0] == '/'); + + result = g_dbus_proxy_call_sync(sinfo->proxy, + "UpdateConnection", + g_variant_new("(ovb)", path, connection, verify_connection), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error(error); + g_assert(g_variant_is_of_type(result, G_VARIANT_TYPE("()"))); + g_variant_unref(result); +} + +/*****************************************************************************/ + +typedef struct { + GType gtype; + GMainLoop *loop; + GObject * obj; + bool call_nm_client_new_async : 1; +} NMTstcObjNewData; + +static void +_context_object_new_do_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + NMTstcObjNewData *d = user_data; + gs_free_error GError *error = NULL; + + g_assert(!d->obj); + + if (d->call_nm_client_new_async) { + d->obj = G_OBJECT(nm_client_new_finish(res, nmtst_get_rand_bool() ? &error : NULL)); + } else { + d->obj = g_async_initable_new_finish(G_ASYNC_INITABLE(source_object), + res, + nmtst_get_rand_bool() ? &error : NULL); + } + + nmtst_assert_success(G_IS_OBJECT(d->obj), error); + g_assert(G_OBJECT_TYPE(d->obj) == d->gtype); + + g_main_loop_quit(d->loop); +} + +static GObject * +_context_object_new_do(GType gtype, + gboolean sync, + const char *first_property_name, + va_list var_args) +{ + gs_free_error GError *error = NULL; + GObject * obj; + + /* Create a GObject instance synchronously, and arbitrarily use either + * the sync or async constructor. + * + * Note that the sync and async construct differ in one important aspect: + * the async constructor iterates the current g_main_context_get_thread_default(), + * while the sync constructor does not! Aside from that, both should behave + * pretty much the same way. */ + + if (sync) { + nm_auto_destroy_and_unref_gsource GSource *source = NULL; + + if (nmtst_get_rand_bool()) { + /* the current main context must not be iterated! */ + source = g_idle_source_new(); + g_source_set_callback(source, nmtst_g_source_assert_not_called, NULL, NULL); + g_source_attach(source, g_main_context_get_thread_default()); + } + + if (gtype != NM_TYPE_CLIENT || first_property_name || nmtst_get_rand_bool()) { + gboolean success; + + if (first_property_name || nmtst_get_rand_bool()) + obj = g_object_new_valist(gtype, first_property_name, var_args); + else + obj = g_object_new(gtype, NULL); + + success = g_initable_init(G_INITABLE(obj), NULL, nmtst_get_rand_bool() ? &error : NULL); + nmtst_assert_success(success, error); + } else { + obj = G_OBJECT(nm_client_new(NULL, nmtst_get_rand_bool() ? &error : NULL)); + } + } else { + nm_auto_unref_gmainloop GMainLoop *loop = NULL; + NMTstcObjNewData d = { + .gtype = gtype, + .loop = NULL, + }; + gs_unref_object GObject *obj2 = NULL; + + loop = g_main_loop_new(g_main_context_get_thread_default(), FALSE); + d.loop = loop; + + if (gtype != NM_TYPE_CLIENT || first_property_name || nmtst_get_rand_bool()) { + if (first_property_name || nmtst_get_rand_bool()) + obj2 = g_object_new_valist(gtype, first_property_name, var_args); + else + obj2 = g_object_new(gtype, NULL); + + g_async_initable_init_async(G_ASYNC_INITABLE(obj2), + G_PRIORITY_DEFAULT, + NULL, + _context_object_new_do_cb, + &d); + } else { + d.call_nm_client_new_async = TRUE; + nm_client_new_async(NULL, _context_object_new_do_cb, &d); + } + g_main_loop_run(loop); + obj = d.obj; + g_assert(!obj2 || obj == obj2); + } + + nmtst_assert_success(G_IS_OBJECT(obj), error); + g_assert(G_OBJECT_TYPE(obj) == gtype); + return obj; +} + +typedef struct { + GType gtype; + const char *first_property_name; + va_list var_args; + GMainLoop * loop; + GObject * obj; + bool sync; +} NewSyncInsideDispatchedData; + +static gboolean +_context_object_new_inside_loop_do(gpointer user_data) +{ + NewSyncInsideDispatchedData *d = user_data; + + g_assert(d->loop); + g_assert(!d->obj); + + d->obj = + nmtstc_context_object_new_valist(d->gtype, d->sync, d->first_property_name, d->var_args); + g_main_loop_quit(d->loop); + return G_SOURCE_CONTINUE; +} + +static GObject * +_context_object_new_inside_loop(GType gtype, + gboolean sync, + const char *first_property_name, + va_list var_args) +{ + GMainContext * context = g_main_context_get_thread_default(); + nm_auto_unref_gmainloop GMainLoop *loop = g_main_loop_new(context, FALSE); + NewSyncInsideDispatchedData d = { + .gtype = gtype, + .first_property_name = first_property_name, + .sync = sync, + .loop = loop, + }; + nm_auto_destroy_and_unref_gsource GSource *source = NULL; + + va_copy(d.var_args, var_args); + + source = g_idle_source_new(); + g_source_set_callback(source, _context_object_new_inside_loop_do, &d, NULL); + g_source_attach(source, context); + + g_main_loop_run(loop); + + va_end(d.var_args); + + g_assert(G_IS_OBJECT(d.obj)); + g_assert(G_OBJECT_TYPE(d.obj) == gtype); + return d.obj; +} + +gpointer +nmtstc_context_object_new_valist(GType gtype, + gboolean allow_iterate_main_context, + const char *first_property_name, + va_list var_args) +{ + gboolean inside_loop; + gboolean sync; + + if (!allow_iterate_main_context) { + sync = TRUE; + inside_loop = FALSE; + } else { + /* The caller allows to iterate the main context. On that point, + * we can both use the synchronous and the asynchronous initialization, + * both should yield the same result. Choose one randomly. */ + sync = nmtst_get_rand_bool(); + inside_loop = ((nmtst_get_rand_uint32() % 3) == 0); + } + + if (inside_loop) { + /* Create the obj on an idle handler of the current context. + * In practice, it should make no difference, which this check + * tries to prove. */ + return _context_object_new_inside_loop(gtype, sync, first_property_name, var_args); + } + + return _context_object_new_do(gtype, sync, first_property_name, var_args); +} + +gpointer +nmtstc_context_object_new(GType gtype, + gboolean allow_iterate_main_context, + const char *first_property_name, + ...) +{ + GObject *obj; + va_list var_args; + + va_start(var_args, first_property_name); + obj = nmtstc_context_object_new_valist(gtype, + allow_iterate_main_context, + first_property_name, + var_args); + va_end(var_args); + return obj; +} diff --git a/src/libnm-core-aux-extern/README.md b/src/libnm-core-aux-extern/README.md new file mode 100644 index 0000000..27f2ccc --- /dev/null +++ b/src/libnm-core-aux-extern/README.md @@ -0,0 +1,11 @@ +libnm-core-aux-extern +===================== + +libnm-core-aux-extern is a static library that is similar to +[`libnm-core-aux-intern`](../libnm-core-aux-intern). + +The only difference is that `libnm-core-aux-extern` is not used by +[`libnm-core-impl`](../libnm-core-impl) itself. So you must not +use it there. + +Otherwise, it's the same and has the same usage. diff --git a/src/libnm-core-aux-extern/meson.build b/src/libnm-core-aux-extern/meson.build new file mode 100644 index 0000000..b48670b --- /dev/null +++ b/src/libnm-core-aux-extern/meson.build @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_core_aux_extern = static_library( + 'nm-core-aux-extern', + sources: files( + 'nm-libnm-core-aux.c', + ), + dependencies: [ + libnm_core_public_dep, + glib_dep, + ], +) diff --git a/src/libnm-core-aux-extern/nm-dispatcher-api.h b/src/libnm-core-aux-extern/nm-dispatcher-api.h new file mode 100644 index 0000000..7776c84 --- /dev/null +++ b/src/libnm-core-aux-extern/nm-dispatcher-api.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_DISPACHER_API_H__ +#define __NM_DISPACHER_API_H__ + +#define NM_DISPATCHER_DBUS_SERVICE "org.freedesktop.nm_dispatcher" +#define NM_DISPATCHER_DBUS_INTERFACE "org.freedesktop.nm_dispatcher" +#define NM_DISPATCHER_DBUS_PATH "/org/freedesktop/nm_dispatcher" + +#define NMD_CONNECTION_PROPS_PATH "path" +#define NMD_CONNECTION_PROPS_FILENAME "filename" +#define NMD_CONNECTION_PROPS_EXTERNAL "external" + +#define NMD_DEVICE_PROPS_INTERFACE "interface" +#define NMD_DEVICE_PROPS_IP_INTERFACE "ip-interface" +#define NMD_DEVICE_PROPS_TYPE "type" +#define NMD_DEVICE_PROPS_STATE "state" +#define NMD_DEVICE_PROPS_PATH "path" + +/* Actions */ +#define NMD_ACTION_HOSTNAME "hostname" +#define NMD_ACTION_PRE_UP "pre-up" +#define NMD_ACTION_UP "up" +#define NMD_ACTION_PRE_DOWN "pre-down" +#define NMD_ACTION_DOWN "down" +#define NMD_ACTION_VPN_PRE_UP "vpn-pre-up" +#define NMD_ACTION_VPN_UP "vpn-up" +#define NMD_ACTION_VPN_PRE_DOWN "vpn-pre-down" +#define NMD_ACTION_VPN_DOWN "vpn-down" +#define NMD_ACTION_DHCP4_CHANGE "dhcp4-change" +#define NMD_ACTION_DHCP6_CHANGE "dhcp6-change" +#define NMD_ACTION_CONNECTIVITY_CHANGE "connectivity-change" + +typedef enum { + DISPATCH_RESULT_UNKNOWN = 0, + DISPATCH_RESULT_SUCCESS = 1, + DISPATCH_RESULT_EXEC_FAILED = 2, + DISPATCH_RESULT_FAILED = 3, + DISPATCH_RESULT_TIMEOUT = 4, +} DispatchResult; + +#endif /* __NM_DISPACHER_API_H__ */ diff --git a/src/libnm-core-aux-extern/nm-libnm-core-aux.c b/src/libnm-core-aux-extern/nm-libnm-core-aux.c new file mode 100644 index 0000000..6c45ecf --- /dev/null +++ b/src/libnm-core-aux-extern/nm-libnm-core-aux.c @@ -0,0 +1,436 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-libnm-core-aux.h" + +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" + +/*****************************************************************************/ + +typedef enum { + KEY_TYPE_STRING, + KEY_TYPE_INT, + KEY_TYPE_BOOL, +} KeyType; + +typedef struct { + const char *str_val; + union { + int vint; + bool vbool; + } typ_val; +} ParseData; + +typedef struct { + const char * name; + NMTeamLinkWatcherType watcher_type; + KeyType key_type; + union { + int (*fint)(const NMTeamLinkWatcher *watcher); + gboolean (*fbool)(const NMTeamLinkWatcher *watcher); + const char *(*fstring)(const NMTeamLinkWatcher *watcher); + } get_fcn; + union { + int vint; + bool vbool; + } def_val; +} TeamLinkWatcherKeyInfo; + +static gboolean +_team_link_watcher_validate_active(const NMTeamLinkWatcher *watcher) +{ + return NM_FLAGS_HAS(nm_team_link_watcher_get_flags(watcher), + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE); +} + +static gboolean +_team_link_watcher_validate_inactive(const NMTeamLinkWatcher *watcher) +{ + return NM_FLAGS_HAS(nm_team_link_watcher_get_flags(watcher), + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE); +} + +static gboolean +_team_link_watcher_send_always(const NMTeamLinkWatcher *watcher) +{ + return NM_FLAGS_HAS(nm_team_link_watcher_get_flags(watcher), + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS); +} + +static const TeamLinkWatcherKeyInfo _team_link_watcher_key_infos[_NM_TEAM_LINK_WATCHER_KEY_NUM] = { + +#define _KEY_INFO(key_id, _name, _watcher_type, _key_type, ...) \ + [key_id] = {.name = ""_name \ + "", \ + .watcher_type = (_watcher_type), \ + .key_type = _key_type, \ + ##__VA_ARGS__} + + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_NAME, + "name", + NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL | NM_TEAM_LINK_WATCHER_TYPE_NSNAPING + | NM_TEAM_LINK_WATCHER_TYPE_ARPING, + KEY_TYPE_STRING, + .get_fcn.fstring = nm_team_link_watcher_get_name, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_DELAY_UP, + "delay-up", + NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL, + KEY_TYPE_INT, + .get_fcn.fint = nm_team_link_watcher_get_delay_up, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_DELAY_DOWN, + "delay-down", + NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL, + KEY_TYPE_INT, + .get_fcn.fint = nm_team_link_watcher_get_delay_down, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_INIT_WAIT, + "init-wait", + NM_TEAM_LINK_WATCHER_TYPE_NSNAPING | NM_TEAM_LINK_WATCHER_TYPE_ARPING, + KEY_TYPE_INT, + .get_fcn.fint = nm_team_link_watcher_get_init_wait, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_INTERVAL, + "interval", + NM_TEAM_LINK_WATCHER_TYPE_NSNAPING | NM_TEAM_LINK_WATCHER_TYPE_ARPING, + KEY_TYPE_INT, + .get_fcn.fint = nm_team_link_watcher_get_interval, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_MISSED_MAX, + "missed-max", + NM_TEAM_LINK_WATCHER_TYPE_NSNAPING | NM_TEAM_LINK_WATCHER_TYPE_ARPING, + KEY_TYPE_INT, + .get_fcn.fint = nm_team_link_watcher_get_missed_max, + .def_val.vint = 3, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_TARGET_HOST, + "target-host", + NM_TEAM_LINK_WATCHER_TYPE_NSNAPING | NM_TEAM_LINK_WATCHER_TYPE_ARPING, + KEY_TYPE_STRING, + .get_fcn.fstring = nm_team_link_watcher_get_target_host, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_VLANID, + "vlanid", + NM_TEAM_LINK_WATCHER_TYPE_ARPING, + KEY_TYPE_INT, + .get_fcn.fint = nm_team_link_watcher_get_vlanid, + .def_val.vint = -1, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_SOURCE_HOST, + "source-host", + NM_TEAM_LINK_WATCHER_TYPE_ARPING, + KEY_TYPE_STRING, + .get_fcn.fstring = nm_team_link_watcher_get_source_host, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_VALIDATE_ACTIVE, + "validate-active", + NM_TEAM_LINK_WATCHER_TYPE_ARPING, + KEY_TYPE_BOOL, + .get_fcn.fbool = _team_link_watcher_validate_active, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_VALIDATE_INACTIVE, + "validate-inactive", + NM_TEAM_LINK_WATCHER_TYPE_ARPING, + KEY_TYPE_BOOL, + .get_fcn.fbool = _team_link_watcher_validate_inactive, ), + _KEY_INFO(NM_TEAM_LINK_WATCHER_KEY_SEND_ALWAYS, + "send-always", + NM_TEAM_LINK_WATCHER_TYPE_ARPING, + KEY_TYPE_BOOL, + .get_fcn.fbool = _team_link_watcher_send_always, ), + +}; + +static NMTeamLinkWatcherType +_team_link_watcher_get_watcher_type_from_name(const char *name) +{ + if (name) { + if (nm_streq(name, NM_TEAM_LINK_WATCHER_ETHTOOL)) + return NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL; + if (nm_streq(name, NM_TEAM_LINK_WATCHER_NSNA_PING)) + return NM_TEAM_LINK_WATCHER_TYPE_NSNAPING; + if (nm_streq(name, NM_TEAM_LINK_WATCHER_ARP_PING)) + return NM_TEAM_LINK_WATCHER_TYPE_ARPING; + } + return NM_TEAM_LINK_WATCHER_TYPE_NONE; +} + +static const char * +_parse_data_get_str(const ParseData parse_data[static _NM_TEAM_LINK_WATCHER_KEY_NUM], + NMTeamLinkWatcherKeyId key_id) +{ + nm_assert(_NM_INT_NOT_NEGATIVE(key_id) && key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM); + nm_assert(_team_link_watcher_key_infos[key_id].key_type == KEY_TYPE_STRING); + + return parse_data[key_id].str_val; +} + +static int +_parse_data_get_int(const ParseData parse_data[static _NM_TEAM_LINK_WATCHER_KEY_NUM], + NMTeamLinkWatcherKeyId key_id) +{ + nm_assert(_NM_INT_NOT_NEGATIVE(key_id) && key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM); + nm_assert(_team_link_watcher_key_infos[key_id].key_type == KEY_TYPE_INT); + + if (parse_data[key_id].str_val) + return parse_data[key_id].typ_val.vint; + return _team_link_watcher_key_infos[key_id].def_val.vint; +} + +static int +_parse_data_get_bool(const ParseData parse_data[static _NM_TEAM_LINK_WATCHER_KEY_NUM], + NMTeamLinkWatcherKeyId key_id) +{ + nm_assert(_NM_INT_NOT_NEGATIVE(key_id) && key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM); + nm_assert(_team_link_watcher_key_infos[key_id].key_type == KEY_TYPE_BOOL); + + if (parse_data[key_id].str_val) + return parse_data[key_id].typ_val.vbool; + return _team_link_watcher_key_infos[key_id].def_val.vbool; +} + +char * +nm_utils_team_link_watcher_to_string(const NMTeamLinkWatcher *watcher) +{ + nm_auto_free_gstring GString *str = NULL; + const char * name; + NMTeamLinkWatcherType watcher_type; + NMTeamLinkWatcherKeyId key_id; + + if (!watcher) + return NULL; + + str = g_string_new(NULL); + + name = nm_team_link_watcher_get_name(watcher); + g_string_append_printf(str, "name=%s", name ?: ""); + + watcher_type = _team_link_watcher_get_watcher_type_from_name(name); + + for (key_id = 0; key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM; key_id++) { + const TeamLinkWatcherKeyInfo *info = &_team_link_watcher_key_infos[key_id]; + const char * vstr; + int vint; + bool vbool; + + nm_assert( + info->name && info->name + && NM_STRCHAR_ALL(info->name, ch, ((ch >= 'a' && ch <= 'z') || NM_IN_SET(ch, '-')))); + nm_assert(NM_IN_SET(info->key_type, KEY_TYPE_STRING, KEY_TYPE_INT, KEY_TYPE_BOOL)); + + if (key_id == NM_TEAM_LINK_WATCHER_KEY_NAME) + continue; + + if (!NM_FLAGS_ALL(info->watcher_type, watcher_type)) + continue; + + switch (info->key_type) { + case KEY_TYPE_STRING: + vstr = info->get_fcn.fstring(watcher); + if (vstr) { + g_string_append_printf(nm_gstring_add_space_delimiter(str), + "%s=%s", + info->name, + vstr); + } + break; + case KEY_TYPE_INT: + vint = info->get_fcn.fint(watcher); + if (vint != info->def_val.vint) { + g_string_append_printf(nm_gstring_add_space_delimiter(str), + "%s=%d", + info->name, + vint); + } + break; + case KEY_TYPE_BOOL: + vbool = info->get_fcn.fbool(watcher); + if (vbool != info->def_val.vbool) { + g_string_append_printf(nm_gstring_add_space_delimiter(str), + "%s=%s", + info->name, + vbool ? "true" : "false"); + } + break; + } + } + + return g_string_free(g_steal_pointer(&str), FALSE); +} + +NMTeamLinkWatcher * +nm_utils_team_link_watcher_from_string(const char *str, GError **error) +{ + gs_free const char ** tokens = NULL; + ParseData parse_data[_NM_TEAM_LINK_WATCHER_KEY_NUM] = {}; + NMTeamLinkWatcherType watcher_type; + NMTeamLinkWatcherKeyId key_id; + gsize i_token; + NMTeamLinkWatcher * watcher; + int errsv; + + g_return_val_if_fail(str, NULL); + g_return_val_if_fail(!error || !*error, NULL); + + tokens = nm_utils_escaped_tokens_split(str, NM_ASCII_SPACES); + if (!tokens) { + g_set_error(error, 1, 0, "'%s' is not valid", str); + return NULL; + } + + for (i_token = 0; tokens[i_token]; i_token++) { + const TeamLinkWatcherKeyInfo *info; + const char * key = tokens[i_token]; + const char * val; + + val = strchr(key, '='); + if (!val) { + nm_utils_error_set( + error, + NM_UTILS_ERROR_UNKNOWN, + _("'%s' is not valid: properties should be specified as 'key=value'"), + key); + return NULL; + } + ((char *) val)[0] = '\0'; + val++; + + for (key_id = 0; key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM; key_id++) { + info = &_team_link_watcher_key_infos[key_id]; + if (nm_streq(key, info->name)) + break; + } + + if (key_id == _NM_TEAM_LINK_WATCHER_KEY_NUM) { + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("'%s' is not a valid key"), key); + return NULL; + } + + if (parse_data[key_id].str_val) { + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("duplicate key '%s'"), key); + return NULL; + } + + parse_data[key_id].str_val = val; + + if (info->key_type == KEY_TYPE_INT) { + gint64 v64; + + v64 = _nm_utils_ascii_str_to_int64(val, 10, G_MININT, G_MAXINT, G_MAXINT64); + if (v64 == G_MAXINT64 && ((errsv = errno) != 0)) { + if (errsv == ERANGE) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("number for '%s' is out of range"), + key); + } else { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("value for '%s' must be a number"), + key); + } + return NULL; + } + parse_data[key_id].typ_val.vint = v64; + } else if (info->key_type == KEY_TYPE_BOOL) { + int vbool; + + vbool = _nm_utils_ascii_str_to_bool(val, -1); + if (vbool == -1) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("value for '%s' must be a boolean"), + key); + return NULL; + } + parse_data[key_id].typ_val.vbool = vbool; + } + } + + if (!parse_data[NM_TEAM_LINK_WATCHER_KEY_NAME].str_val) { + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("missing 'name' attribute")); + return NULL; + } + + watcher_type = _team_link_watcher_get_watcher_type_from_name( + parse_data[NM_TEAM_LINK_WATCHER_KEY_NAME].str_val); + if (watcher_type == NM_TEAM_LINK_WATCHER_TYPE_NONE) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("invalid 'name' \"%s\""), + parse_data[NM_TEAM_LINK_WATCHER_KEY_NAME].str_val); + return NULL; + } + + for (key_id = 0; key_id < _NM_TEAM_LINK_WATCHER_KEY_NUM; key_id++) { + const TeamLinkWatcherKeyInfo *info = &_team_link_watcher_key_infos[key_id]; + + if (!parse_data[key_id].str_val) + continue; + if (!NM_FLAGS_ALL(info->watcher_type, watcher_type)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("attribute '%s' is invalid for \"%s\""), + info->name, + parse_data[NM_TEAM_LINK_WATCHER_KEY_NAME].str_val); + return NULL; + } + } + + switch (watcher_type) { + case NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL: + watcher = nm_team_link_watcher_new_ethtool( + _parse_data_get_int(parse_data, NM_TEAM_LINK_WATCHER_KEY_DELAY_UP), + _parse_data_get_int(parse_data, NM_TEAM_LINK_WATCHER_KEY_DELAY_DOWN), + error); + break; + case NM_TEAM_LINK_WATCHER_TYPE_NSNAPING: + watcher = nm_team_link_watcher_new_nsna_ping( + _parse_data_get_int(parse_data, NM_TEAM_LINK_WATCHER_KEY_INIT_WAIT), + _parse_data_get_int(parse_data, NM_TEAM_LINK_WATCHER_KEY_INTERVAL), + _parse_data_get_int(parse_data, NM_TEAM_LINK_WATCHER_KEY_MISSED_MAX), + _parse_data_get_str(parse_data, NM_TEAM_LINK_WATCHER_KEY_TARGET_HOST), + error); + break; + default: + nm_assert(watcher_type == NM_TEAM_LINK_WATCHER_TYPE_ARPING); + watcher = nm_team_link_watcher_new_arp_ping2( + _parse_data_get_int(parse_data, NM_TEAM_LINK_WATCHER_KEY_INIT_WAIT), + _parse_data_get_int(parse_data, NM_TEAM_LINK_WATCHER_KEY_INTERVAL), + _parse_data_get_int(parse_data, NM_TEAM_LINK_WATCHER_KEY_MISSED_MAX), + _parse_data_get_int(parse_data, NM_TEAM_LINK_WATCHER_KEY_VLANID), + _parse_data_get_str(parse_data, NM_TEAM_LINK_WATCHER_KEY_TARGET_HOST), + _parse_data_get_str(parse_data, NM_TEAM_LINK_WATCHER_KEY_SOURCE_HOST), + (NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE + | (_parse_data_get_bool(parse_data, NM_TEAM_LINK_WATCHER_KEY_VALIDATE_ACTIVE) + ? NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE + : NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE) + | (_parse_data_get_bool(parse_data, NM_TEAM_LINK_WATCHER_KEY_VALIDATE_INACTIVE) + ? NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE + : NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE) + | (_parse_data_get_bool(parse_data, NM_TEAM_LINK_WATCHER_KEY_SEND_ALWAYS) + ? NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS + : NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE)), + error); + break; + } + +#if NM_MORE_ASSERTS > 5 + if (watcher) { + gs_free char * str2 = NULL; + nm_auto_unref_team_link_watcher NMTeamLinkWatcher *watcher2 = NULL; + static _nm_thread_local int recursive; + + nm_assert(!error || !*error); + if (recursive == 0) { + recursive = 1; + str2 = nm_utils_team_link_watcher_to_string(watcher); + nm_assert(str2); + watcher2 = nm_utils_team_link_watcher_from_string(str2, NULL); + nm_assert(watcher2); + nm_assert(nm_team_link_watcher_equal(watcher, watcher2)); + nm_assert(nm_team_link_watcher_equal(watcher2, watcher)); + nm_assert(recursive == 1); + recursive = 0; + } + } else + nm_assert(!error || *error); +#endif + + return watcher; +} diff --git a/src/libnm-core-aux-extern/nm-libnm-core-aux.h b/src/libnm-core-aux-extern/nm-libnm-core-aux.h new file mode 100644 index 0000000..905f243 --- /dev/null +++ b/src/libnm-core-aux-extern/nm-libnm-core-aux.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#ifndef __NM_LIBNM_CORE_AUX_H__ +#define __NM_LIBNM_CORE_AUX_H__ + +#include "nm-setting-team.h" + +typedef enum { + NM_TEAM_LINK_WATCHER_TYPE_NONE = 0, + NM_TEAM_LINK_WATCHER_TYPE_ETHTOOL = (1u << 0), + NM_TEAM_LINK_WATCHER_TYPE_NSNAPING = (1u << 1), + NM_TEAM_LINK_WATCHER_TYPE_ARPING = (1u << 2), +} NMTeamLinkWatcherType; + +typedef enum { + NM_TEAM_LINK_WATCHER_KEY_NAME, + NM_TEAM_LINK_WATCHER_KEY_DELAY_UP, + NM_TEAM_LINK_WATCHER_KEY_DELAY_DOWN, + NM_TEAM_LINK_WATCHER_KEY_INIT_WAIT, + NM_TEAM_LINK_WATCHER_KEY_INTERVAL, + NM_TEAM_LINK_WATCHER_KEY_MISSED_MAX, + NM_TEAM_LINK_WATCHER_KEY_TARGET_HOST, + NM_TEAM_LINK_WATCHER_KEY_VLANID, + NM_TEAM_LINK_WATCHER_KEY_SOURCE_HOST, + NM_TEAM_LINK_WATCHER_KEY_VALIDATE_ACTIVE, + NM_TEAM_LINK_WATCHER_KEY_VALIDATE_INACTIVE, + NM_TEAM_LINK_WATCHER_KEY_SEND_ALWAYS, + _NM_TEAM_LINK_WATCHER_KEY_NUM, +} NMTeamLinkWatcherKeyId; + +char *nm_utils_team_link_watcher_to_string(const NMTeamLinkWatcher *watcher); + +NMTeamLinkWatcher *nm_utils_team_link_watcher_from_string(const char *str, GError **error); + +#endif /* __NM_LIBNM_CORE_AUX_H__ */ diff --git a/src/libnm-core-aux-intern/README.md b/src/libnm-core-aux-intern/README.md new file mode 100644 index 0000000..37e238f --- /dev/null +++ b/src/libnm-core-aux-intern/README.md @@ -0,0 +1,28 @@ +libnm-core-aux-intern +===================== + +`libnm-core-aux-intern` is a static library that: + + - uses parts of [`libnm-core-impl`](../libnm-core-impl), that are public API + of [`libnm`](../../libnm) (i.e. [`libnm-core-public`](../libnm-core-public)). + - that is statically linked into [`libnm-core-impl`](../libnm-core-impl) (and thus + [`libnm`](../libnm) and NetworkManager core. + - that can also be statically linked into other users of [`libnm`](../libnm). + +Basically, it is a static library with utility functions that extends +[`libnm-core-impl`](../libnm-core-impl) (the part that is public API of libnm), +but it is also used by [`libnm-core-impl`](../libnm-core-impl) itself. + +That means: + + - you can use it everywhere where you either statically link + with [`libnm-core-impl`](../libnm-core-impl), or dynamically link with + [`libnm`](../../libnm). + - you can even use it inside of [`libnm-core-impl`](../libnm-core-impl) itself. + This is the difference between `libnm-core-aux-intern` and + [`libnm-core-aux-extern`](..libnm-core-aux-extern). + +Note that `libnm-core-aux-intern` only uses public API of `libnm`. + +This directory should not be added to the include search path. Instead, +users should fully qualify the include like `#include "libnm-core-aux-intern/nm-auth-subject.h"`. diff --git a/src/libnm-core-aux-intern/meson.build b/src/libnm-core-aux-intern/meson.build new file mode 100644 index 0000000..a58921e --- /dev/null +++ b/src/libnm-core-aux-intern/meson.build @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_core_aux_intern = static_library( + 'nm-core-aux-intern', + sources: files( + 'nm-auth-subject.c', + 'nm-libnm-core-utils.c', + ), + dependencies: [ + libnm_core_public_dep, + glib_dep, + ], +) diff --git a/src/libnm-core-aux-intern/nm-auth-subject.c b/src/libnm-core-aux-intern/nm-auth-subject.c new file mode 100644 index 0000000..536b4e4 --- /dev/null +++ b/src/libnm-core-aux-intern/nm-auth-subject.c @@ -0,0 +1,468 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 - 2014 Red Hat, Inc. + */ + +/** + * SECTION:nm-auth-subject + * @short_description: Encapsulates authentication information about a requestor + * + * #NMAuthSubject encpasulates identifying information about an entity that + * makes requests, like process identifier and user UID. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-auth-subject.h" + +#include + +enum { + PROP_0, + PROP_SUBJECT_TYPE, + PROP_UNIX_PROCESS_DBUS_SENDER, + PROP_UNIX_PROCESS_PID, + PROP_UNIX_PROCESS_UID, + PROP_UNIX_SESSION_ID, + + PROP_LAST, +}; + +typedef struct { + NMAuthSubjectType subject_type; + struct { + gulong pid; + gulong uid; + guint64 start_time; + char * dbus_sender; + } unix_process; + + struct { + char *id; + } unix_session; +} NMAuthSubjectPrivate; + +struct _NMAuthSubject { + GObject parent; + NMAuthSubjectPrivate _priv; +}; + +struct _NMAuthSubjectClass { + GObjectClass parent; +}; + +G_DEFINE_TYPE(NMAuthSubject, nm_auth_subject, G_TYPE_OBJECT) + +#define NM_AUTH_SUBJECT_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMAuthSubject, NM_IS_AUTH_SUBJECT) + +/*****************************************************************************/ + +#define CHECK_SUBJECT(self, error_value) \ + NMAuthSubjectPrivate *priv; \ + g_return_val_if_fail(NM_IS_AUTH_SUBJECT(self), error_value); \ + priv = NM_AUTH_SUBJECT_GET_PRIVATE(self); + +#define CHECK_SUBJECT_TYPED(self, expected_subject_type, error_value) \ + CHECK_SUBJECT(self, error_value); \ + g_return_val_if_fail(priv->subject_type == (expected_subject_type), error_value); + +const char * +nm_auth_subject_to_string(NMAuthSubject *self, char *buf, gsize buf_len) +{ + CHECK_SUBJECT(self, NULL); + + switch (priv->subject_type) { + case NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS: + g_snprintf(buf, + buf_len, + "unix-process[pid=%lu, uid=%lu, start=%llu]", + (unsigned long) priv->unix_process.pid, + (unsigned long) priv->unix_process.uid, + (unsigned long long) priv->unix_process.start_time); + break; + case NM_AUTH_SUBJECT_TYPE_INTERNAL: + g_strlcpy(buf, "internal", buf_len); + break; + case NM_AUTH_SUBJECT_TYPE_UNIX_SESSION: + g_snprintf(buf, buf_len, "unix-session[id=%s]", priv->unix_session.id); + break; + default: + g_strlcpy(buf, "invalid", buf_len); + break; + } + return buf; +} + +/* returns a floating variant */ +GVariant * +nm_auth_subject_unix_to_polkit_gvariant(NMAuthSubject *self) +{ + GVariantBuilder builder; + CHECK_SUBJECT(self, NULL); + + switch (priv->subject_type) { + case NM_AUTH_SUBJECT_TYPE_UNIX_SESSION: + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(&builder, + "{sv}", + "session-id", + g_variant_new_string(priv->unix_session.id)); + return g_variant_new("(sa{sv})", "unix-session", &builder); + + case NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS: + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(&builder, + "{sv}", + "pid", + g_variant_new_uint32(priv->unix_process.pid)); + g_variant_builder_add(&builder, + "{sv}", + "start-time", + g_variant_new_uint64(priv->unix_process.start_time)); + g_variant_builder_add(&builder, "{sv}", "uid", g_variant_new_int32(priv->unix_process.uid)); + return g_variant_new("(sa{sv})", "unix-process", &builder); + + default: + g_return_val_if_reached(NULL); + } +} + +NMAuthSubjectType +nm_auth_subject_get_subject_type(NMAuthSubject *subject) +{ + CHECK_SUBJECT(subject, NM_AUTH_SUBJECT_TYPE_INVALID); + + return priv->subject_type; +} + +gulong +nm_auth_subject_get_unix_process_pid(NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED(subject, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, G_MAXULONG); + + return priv->unix_process.pid; +} + +gulong +nm_auth_subject_get_unix_process_uid(NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED(subject, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, G_MAXULONG); + + return priv->unix_process.uid; +} + +const char * +nm_auth_subject_get_unix_process_dbus_sender(NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED(subject, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, NULL); + + return priv->unix_process.dbus_sender; +} + +const char * +nm_auth_subject_get_unix_session_id(NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED(subject, NM_AUTH_SUBJECT_TYPE_UNIX_SESSION, NULL); + + return priv->unix_session.id; +} + +/*****************************************************************************/ + +/** + * nm_auth_subject_new_internal(): + * + * Creates a new auth subject representing the NetworkManager process itself. + * + * Returns: the new #NMAuthSubject + */ +NMAuthSubject * +nm_auth_subject_new_internal(void) +{ + return g_object_new(NM_TYPE_AUTH_SUBJECT, + NM_AUTH_SUBJECT_SUBJECT_TYPE, + (int) NM_AUTH_SUBJECT_TYPE_INTERNAL, + NULL); +} + +/** + * nm_auth_subject_new_unix_session(): + * + * Creates a new auth subject representing a given unix session. + * + * Returns: the new #NMAuthSubject + */ +NMAuthSubject * +nm_auth_subject_new_unix_session(const char *session_id) +{ + return g_object_new(NM_TYPE_AUTH_SUBJECT, + NM_AUTH_SUBJECT_SUBJECT_TYPE, + (int) NM_AUTH_SUBJECT_TYPE_UNIX_SESSION, + NM_AUTH_SUBJECT_UNIX_SESSION_ID, + session_id, + NULL); +} + +/** + * nm_auth_subject_new_unix_process(): + * + * Creates a new auth subject representing a given unix process. + * + * Returns: the new #NMAuthSubject + */ +NMAuthSubject * +nm_auth_subject_new_unix_process(const char *dbus_sender, gulong pid, gulong uid) +{ + return g_object_new(NM_TYPE_AUTH_SUBJECT, + NM_AUTH_SUBJECT_SUBJECT_TYPE, + (int) NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, + NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER, + dbus_sender, + NM_AUTH_SUBJECT_UNIX_PROCESS_PID, + pid, + NM_AUTH_SUBJECT_UNIX_PROCESS_UID, + uid, + NULL); +} + +/** + * nm_auth_subject_new_unix_process_self(): + * + * Creates a new auth subject representing the current executing process. + * + * Returns: the new #NMAuthSubject + */ +NMAuthSubject * +nm_auth_subject_new_unix_process_self(void) +{ + return nm_auth_subject_new_unix_process(NULL, getpid(), getuid()); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_SUBJECT_TYPE: + g_value_set_int(value, priv->subject_type); + break; + case PROP_UNIX_PROCESS_DBUS_SENDER: + g_value_set_string(value, priv->unix_process.dbus_sender); + break; + case PROP_UNIX_PROCESS_PID: + g_value_set_ulong(value, priv->unix_process.pid); + break; + case PROP_UNIX_PROCESS_UID: + g_value_set_ulong(value, priv->unix_process.uid); + break; + case PROP_UNIX_SESSION_ID: + g_value_set_string(value, priv->unix_session.id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE(object); + NMAuthSubjectType subject_type; + int i; + const char * str; + gulong id; + + switch (prop_id) { + case PROP_SUBJECT_TYPE: + /* construct-only */ + i = g_value_get_int(value); + g_return_if_fail(NM_IN_SET(i, + (int) NM_AUTH_SUBJECT_TYPE_INTERNAL, + (int) NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, + (int) NM_AUTH_SUBJECT_TYPE_UNIX_SESSION)); + subject_type = i; + priv->subject_type |= subject_type; + g_return_if_fail(priv->subject_type == subject_type); + break; + case PROP_UNIX_PROCESS_DBUS_SENDER: + /* construct-only */ + if ((str = g_value_get_string(value))) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; + g_return_if_fail(priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + priv->unix_process.dbus_sender = g_strdup(str); + } + break; + case PROP_UNIX_PROCESS_PID: + /* construct-only */ + if ((id = g_value_get_ulong(value)) != G_MAXULONG) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; + g_return_if_fail(priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + priv->unix_process.pid = id; + } + break; + case PROP_UNIX_PROCESS_UID: + /* construct-only */ + if ((id = g_value_get_ulong(value)) != G_MAXULONG) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; + g_return_if_fail(priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + priv->unix_process.uid = id; + } + break; + case PROP_UNIX_SESSION_ID: + /* construct-only */ + if ((str = g_value_get_string(value))) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_SESSION; + g_return_if_fail(priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_SESSION); + priv->unix_session.id = g_strdup(str); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +_clear_private(NMAuthSubject *self) +{ + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE(self); + + priv->subject_type = NM_AUTH_SUBJECT_TYPE_INVALID; + priv->unix_process.pid = G_MAXULONG; + priv->unix_process.uid = G_MAXULONG; + nm_clear_g_free(&priv->unix_process.dbus_sender); + + nm_clear_g_free(&priv->unix_session.id); +} + +static void +nm_auth_subject_init(NMAuthSubject *self) +{ + _clear_private(self); +} + +static void +constructed(GObject *object) +{ + NMAuthSubject * self = NM_AUTH_SUBJECT(object); + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE(self); + + /* validate that the created instance. */ + + switch (priv->subject_type) { + case NM_AUTH_SUBJECT_TYPE_INTERNAL: + priv->unix_process.pid = G_MAXULONG; + priv->unix_process.uid = 0; /* internal uses 'root' user */ + return; + case NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS: + /* Ensure pid and uid to be representable as int32. + * DBUS treats them as uint32, polkit library as int. */ + if (priv->unix_process.pid > MIN(G_MAXINT, G_MAXINT32)) + break; + if (priv->unix_process.uid > MIN(G_MAXINT, G_MAXINT32)) { + /* for uid==-1, libpolkit-gobject-1 detects the user based on the process id. + * Don't bother and require the user id as parameter. */ + break; + } + + priv->unix_process.start_time = + nm_utils_get_start_time_for_pid(priv->unix_process.pid, NULL, NULL); + + if (!priv->unix_process.start_time) { + /* Is the process already gone? Then fail creation of the auth subject + * by clearing the type. */ + if (kill(priv->unix_process.pid, 0) != 0) + _clear_private(self); + + /* Otherwise, although we didn't detect a start_time, the process is still around. + * That could be due to procfs mounted with hidepid. So just accept the request. + * + * Polkit on the other side, will accept 0 and try to lookup /proc/$PID/stat + * itself (and if it fails to do so, assume a start-time of 0 and proceed). + * The only combination that would fail here, is when NM is able to read the + * start-time, but polkit is not. */ + } + return; + case NM_AUTH_SUBJECT_TYPE_UNIX_SESSION: + return; + default: + break; + } + + _clear_private(self); + g_return_if_reached(); +} + +static void +finalize(GObject *object) +{ + _clear_private((NMAuthSubject *) object); + + G_OBJECT_CLASS(nm_auth_subject_parent_class)->finalize(object); +} + +static void +nm_auth_subject_class_init(NMAuthSubjectClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(config_class); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->constructed = constructed; + object_class->finalize = finalize; + + g_object_class_install_property( + object_class, + PROP_SUBJECT_TYPE, + g_param_spec_int(NM_AUTH_SUBJECT_SUBJECT_TYPE, + "", + "", + NM_AUTH_SUBJECT_TYPE_INVALID, + NM_AUTH_SUBJECT_TYPE_UNIX_SESSION, + NM_AUTH_SUBJECT_TYPE_INVALID, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property( + object_class, + PROP_UNIX_PROCESS_DBUS_SENDER, + g_param_spec_string(NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property( + object_class, + PROP_UNIX_PROCESS_PID, + g_param_spec_ulong(NM_AUTH_SUBJECT_UNIX_PROCESS_PID, + "", + "", + 0, + G_MAXULONG, + G_MAXULONG, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property( + object_class, + PROP_UNIX_PROCESS_UID, + g_param_spec_ulong(NM_AUTH_SUBJECT_UNIX_PROCESS_UID, + "", + "", + 0, + G_MAXULONG, + G_MAXULONG, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property( + object_class, + PROP_UNIX_SESSION_ID, + g_param_spec_string(NM_AUTH_SUBJECT_UNIX_SESSION_ID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); +} diff --git a/src/libnm-core-aux-intern/nm-auth-subject.h b/src/libnm-core-aux-intern/nm-auth-subject.h new file mode 100644 index 0000000..2c9c4f7 --- /dev/null +++ b/src/libnm-core-aux-intern/nm-auth-subject.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_AUTH_SUBJECT_H__ +#define __NETWORKMANAGER_AUTH_SUBJECT_H__ + +#define NM_TYPE_AUTH_SUBJECT (nm_auth_subject_get_type()) +#define NM_AUTH_SUBJECT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_AUTH_SUBJECT, NMAuthSubject)) +#define NM_AUTH_SUBJECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_AUTH_SUBJECT, NMAuthSubjectClass)) +#define NM_IS_AUTH_SUBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_AUTH_SUBJECT)) +#define NM_IS_AUTH_SUBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_AUTH_SUBJECT)) +#define NM_AUTH_SUBJECT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_AUTH_SUBJECT, NMAuthSubjectClass)) + +typedef enum { + NM_AUTH_SUBJECT_TYPE_INVALID = 0, + NM_AUTH_SUBJECT_TYPE_INTERNAL = 1, + NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS = 2, + NM_AUTH_SUBJECT_TYPE_UNIX_SESSION = 4, +} NMAuthSubjectType; + +#define NM_AUTH_SUBJECT_SUBJECT_TYPE "subject-type" +#define NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER "unix-process-dbus-sender" +#define NM_AUTH_SUBJECT_UNIX_PROCESS_PID "unix-process-pid" +#define NM_AUTH_SUBJECT_UNIX_PROCESS_UID "unix-process-uid" +#define NM_AUTH_SUBJECT_UNIX_SESSION_ID "unix-session-id" + +typedef struct _NMAuthSubjectClass NMAuthSubjectClass; +typedef struct _NMAuthSubject NMAuthSubject; + +GType nm_auth_subject_get_type(void); + +NMAuthSubject *nm_auth_subject_new_internal(void); + +NMAuthSubject *nm_auth_subject_new_unix_session(const char *session_id); + +NMAuthSubject *nm_auth_subject_new_unix_process(const char *dbus_sender, gulong pid, gulong uid); + +NMAuthSubject *nm_auth_subject_new_unix_process_self(void); + +NMAuthSubjectType nm_auth_subject_get_subject_type(NMAuthSubject *subject); + +gulong nm_auth_subject_get_unix_process_pid(NMAuthSubject *subject); + +const char *nm_auth_subject_get_unix_process_dbus_sender(NMAuthSubject *subject); + +gulong nm_auth_subject_get_unix_process_uid(NMAuthSubject *subject); + +const char *nm_auth_subject_get_unix_session_id(NMAuthSubject *subject); + +const char *nm_auth_subject_to_string(NMAuthSubject *self, char *buf, gsize buf_len); + +GVariant *nm_auth_subject_unix_to_polkit_gvariant(NMAuthSubject *self); + +#endif /* __NETWORKMANAGER_AUTH_SUBJECT_H__ */ diff --git a/src/libnm-core-aux-intern/nm-common-macros.h b/src/libnm-core-aux-intern/nm-common-macros.h new file mode 100644 index 0000000..c452b7d --- /dev/null +++ b/src/libnm-core-aux-intern/nm-common-macros.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#ifndef __NM_COMMON_MACROS_H__ +#define __NM_COMMON_MACROS_H__ + +/*****************************************************************************/ + +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK \ + "org.freedesktop.NetworkManager.enable-disable-network" +#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX \ + "org.freedesktop.NetworkManager.enable-disable-wimax" +#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" +#define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED \ + "org.freedesktop.NetworkManager.wifi.share.protected" +#define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM \ + "org.freedesktop.NetworkManager.settings.modify.system" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN "org.freedesktop.NetworkManager.settings.modify.own" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME \ + "org.freedesktop.NetworkManager.settings.modify.hostname" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS \ + "org.freedesktop.NetworkManager.settings.modify.global-dns" +#define NM_AUTH_PERMISSION_RELOAD "org.freedesktop.NetworkManager.reload" +#define NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK "org.freedesktop.NetworkManager.checkpoint-rollback" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS \ + "org.freedesktop.NetworkManager.enable-disable-statistics" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK \ + "org.freedesktop.NetworkManager.enable-disable-connectivity-check" +#define NM_AUTH_PERMISSION_WIFI_SCAN "org.freedesktop.NetworkManager.wifi.scan" + +#define NM_CLONED_MAC_PRESERVE "preserve" +#define NM_CLONED_MAC_PERMANENT "permanent" +#define NM_CLONED_MAC_RANDOM "random" +#define NM_CLONED_MAC_STABLE "stable" + +static inline gboolean +NM_CLONED_MAC_IS_SPECIAL(const char *str) +{ + return NM_IN_STRSET(str, + NM_CLONED_MAC_PRESERVE, + NM_CLONED_MAC_PERMANENT, + NM_CLONED_MAC_RANDOM, + NM_CLONED_MAC_STABLE); +} + +#define NM_IAID_MAC "mac" +#define NM_IAID_PERM_MAC "perm-mac" +#define NM_IAID_IFNAME "ifname" +#define NM_IAID_STABLE "stable" + +#define NM_CONNECTION_MUD_URL_NONE "none" + +static inline gboolean +NM_IAID_IS_SPECIAL(const char *str) +{ + return NM_IN_STRSET(str, NM_IAID_MAC, NM_IAID_PERM_MAC, NM_IAID_IFNAME, NM_IAID_STABLE); +} + +#endif /* __NM_COMMON_MACROS_H__ */ diff --git a/src/libnm-core-aux-intern/nm-libnm-core-utils.c b/src/libnm-core-aux-intern/nm-libnm-core-utils.c new file mode 100644 index 0000000..78daac4 --- /dev/null +++ b/src/libnm-core-aux-intern/nm-libnm-core-utils.c @@ -0,0 +1,359 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-libnm-core-utils.h" + +#include + +#include "nm-common-macros.h" +#include "nm-errors.h" + +/*****************************************************************************/ + +const char ** +nm_utils_bond_option_arp_ip_targets_split(const char *arp_ip_target) +{ + return nm_utils_strsplit_set_full(arp_ip_target, ",", NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); +} + +void +_nm_setting_bond_remove_options_miimon(NMSettingBond *s_bond) +{ + g_return_if_fail(NM_IS_SETTING_BOND(s_bond)); + + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_MIIMON); + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_UPDELAY); + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY); +} + +void +_nm_setting_bond_remove_options_arp_interval(NMSettingBond *s_bond) +{ + g_return_if_fail(NM_IS_SETTING_BOND(s_bond)); + + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL); + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET); +} + +/*****************************************************************************/ + +NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( + _nm_setting_bond_mode_from_string, + NMBondMode, + { + G_STATIC_ASSERT_EXPR(_NM_BOND_MODE_NUM <= 9); + + if (name && name[0] < '0' + _NM_BOND_MODE_NUM && name[0] >= '0' && name[1] == '\0') { + return name[0] - '0'; + } + }, + { return NM_BOND_MODE_UNKNOWN; }, + {"802.3ad", NM_BOND_MODE_8023AD}, + {"active-backup", NM_BOND_MODE_ACTIVEBACKUP}, + {"balance-alb", NM_BOND_MODE_ALB}, + {"balance-rr", NM_BOND_MODE_ROUNDROBIN}, + {"balance-tlb", NM_BOND_MODE_TLB}, + {"balance-xor", NM_BOND_MODE_XOR}, + {"broadcast", NM_BOND_MODE_BROADCAST}, ); + +const char * +_nm_setting_bond_mode_to_string(int mode) +{ + static const char *const modes[] = { + [NM_BOND_MODE_8023AD] = "802.3ad", + [NM_BOND_MODE_ACTIVEBACKUP] = "active-backup", + [NM_BOND_MODE_ALB] = "balance-alb", + [NM_BOND_MODE_BROADCAST] = "broadcast", + [NM_BOND_MODE_ROUNDROBIN] = "balance-rr", + [NM_BOND_MODE_TLB] = "balance-tlb", + [NM_BOND_MODE_XOR] = "balance-xor", + }; + + G_STATIC_ASSERT(G_N_ELEMENTS(modes) == _NM_BOND_MODE_NUM); + + if (NM_MORE_ASSERT_ONCE(5)) { + char sbuf[100]; + int i; + NMBondMode m; + + for (i = 0; i < (int) G_N_ELEMENTS(modes); i++) { + nm_assert(modes[i]); + nm_assert(i == _nm_setting_bond_mode_from_string(modes[i])); + nm_assert(i == _nm_setting_bond_mode_from_string(nm_sprintf_buf(sbuf, "%d", i))); + } + nm_assert(NM_BOND_MODE_UNKNOWN == _nm_setting_bond_mode_from_string(NULL)); + nm_assert(NM_BOND_MODE_UNKNOWN == _nm_setting_bond_mode_from_string("")); + for (i = -2; i < ((int) G_N_ELEMENTS(modes)) + 20; i++) { + if (i < 0 || i >= G_N_ELEMENTS(modes)) + m = NM_BOND_MODE_UNKNOWN; + else + m = i; + nm_assert(m == _nm_setting_bond_mode_from_string(nm_sprintf_buf(sbuf, "%d", i))); + } + } + + if (mode >= 0 && mode < (int) G_N_ELEMENTS(modes)) + return modes[mode]; + return NULL; +} + +/*****************************************************************************/ + +gboolean +nm_utils_vlan_priority_map_parse_str(NMVlanPriorityMap map_type, + const char * str, + gboolean allow_wildcard_to, + guint32 * out_from, + guint32 * out_to, + gboolean * out_has_wildcard_to) +{ + const char *s2; + gint64 v1, v2; + + nm_assert(str); + + s2 = strchr(str, ':'); + + if (!s2) { + if (!allow_wildcard_to) + return FALSE; + v1 = _nm_utils_ascii_str_to_int64(str, 10, 0, G_MAXUINT32, -1); + v2 = -1; + } else { + gs_free char *s1_free = NULL; + gsize s1_len = (s2 - str); + + s2 = nm_str_skip_leading_spaces(&s2[1]); + if (s2[0] == '\0' || (s2[0] == '*' && NM_STRCHAR_ALL(&s2[1], ch, g_ascii_isspace(ch)))) { + if (!allow_wildcard_to) + return FALSE; + v2 = -1; + } else { + v2 = _nm_utils_ascii_str_to_int64(s2, 10, 0, G_MAXUINT32, -1); + if (v2 < 0 || (guint32) v2 > nm_utils_vlan_priority_map_get_max_prio(map_type, FALSE)) + return FALSE; + } + + v1 = _nm_utils_ascii_str_to_int64(nm_strndup_a(100, str, s1_len, &s1_free), + 10, + 0, + G_MAXUINT32, + -1); + } + + if (v1 < 0 || (guint32) v1 > nm_utils_vlan_priority_map_get_max_prio(map_type, TRUE)) + return FALSE; + + NM_SET_OUT(out_from, v1); + NM_SET_OUT(out_to, v2 < 0 ? 0u : (guint) v2); + NM_SET_OUT(out_has_wildcard_to, v2 < 0); + return TRUE; +} + +/*****************************************************************************/ + +const char *const nm_auth_permission_names_by_idx[NM_CLIENT_PERMISSION_LAST] = { + [NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK - 1] = NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK - 1] = + NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS - 1] = + NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, + [NM_CLIENT_PERMISSION_NETWORK_CONTROL - 1] = NM_AUTH_PERMISSION_NETWORK_CONTROL, + [NM_CLIENT_PERMISSION_RELOAD - 1] = NM_AUTH_PERMISSION_RELOAD, + [NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS - 1] = + NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS, + [NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME - 1] = + NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, + [NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN - 1] = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, + [NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM - 1] = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, + [NM_CLIENT_PERMISSION_SLEEP_WAKE - 1] = NM_AUTH_PERMISSION_SLEEP_WAKE, + [NM_CLIENT_PERMISSION_WIFI_SCAN - 1] = NM_AUTH_PERMISSION_WIFI_SCAN, + [NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN - 1] = NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, + [NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED - 1] = NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, +}; + +const NMClientPermission nm_auth_permission_sorted[NM_CLIENT_PERMISSION_LAST] = { + NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN, + NM_CLIENT_PERMISSION_NETWORK_CONTROL, + NM_CLIENT_PERMISSION_RELOAD, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM, + NM_CLIENT_PERMISSION_SLEEP_WAKE, + NM_CLIENT_PERMISSION_WIFI_SCAN, + NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN, + NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED, +}; + +const char * +nm_auth_permission_to_string(NMClientPermission permission) +{ + if (permission < 1) + return NULL; + if (permission > NM_CLIENT_PERMISSION_LAST) + return NULL; + return nm_auth_permission_names_by_idx[permission - 1]; +} + +#define AUTH_PERMISSION_PREFIX "org.freedesktop.NetworkManager." + +static int +_nm_auth_permission_from_string_cmp(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const NMClientPermission *const p = a; + const char *const needle = b; + const char * ss = nm_auth_permission_names_by_idx[*p - 1]; + + nm_assert(NM_STR_HAS_PREFIX(ss, AUTH_PERMISSION_PREFIX)); + nm_assert(ss[NM_STRLEN(AUTH_PERMISSION_PREFIX)] != '\0'); + + return strcmp(&ss[NM_STRLEN(AUTH_PERMISSION_PREFIX)], needle); +} + +NMClientPermission +nm_auth_permission_from_string(const char *str) +{ + gssize idx; + + if (!str) + return NM_CLIENT_PERMISSION_NONE; + + if (!NM_STR_HAS_PREFIX(str, AUTH_PERMISSION_PREFIX)) + return NM_CLIENT_PERMISSION_NONE; + idx = nm_utils_array_find_binary_search(nm_auth_permission_sorted, + sizeof(nm_auth_permission_sorted[0]), + G_N_ELEMENTS(nm_auth_permission_sorted), + &str[NM_STRLEN(AUTH_PERMISSION_PREFIX)], + _nm_auth_permission_from_string_cmp, + NULL); + if (idx < 0) + return NM_CLIENT_PERMISSION_NONE; + return nm_auth_permission_sorted[idx]; +} + +/*****************************************************************************/ + +NMClientPermissionResult +nm_client_permission_result_from_string(const char *nm) +{ + if (!nm) + return NM_CLIENT_PERMISSION_RESULT_UNKNOWN; + if (nm_streq(nm, "yes")) + return NM_CLIENT_PERMISSION_RESULT_YES; + if (nm_streq(nm, "no")) + return NM_CLIENT_PERMISSION_RESULT_NO; + if (nm_streq(nm, "auth")) + return NM_CLIENT_PERMISSION_RESULT_AUTH; + return NM_CLIENT_PERMISSION_RESULT_UNKNOWN; +} + +const char * +nm_client_permission_result_to_string(NMClientPermissionResult permission) +{ + switch (permission) { + case NM_CLIENT_PERMISSION_RESULT_YES: + return "yes"; + case NM_CLIENT_PERMISSION_RESULT_NO: + return "no"; + case NM_CLIENT_PERMISSION_RESULT_AUTH: + return "auth"; + case NM_CLIENT_PERMISSION_RESULT_UNKNOWN: + return "unknown"; + } + nm_assert_not_reached(); + return NULL; +} + +gboolean +nm_utils_validate_dhcp4_vendor_class_id(const char *vci, GError **error) +{ + const char * bin; + gsize unescaped_len; + gs_free char *to_free = NULL; + + g_return_val_if_fail(!error || !(*error), FALSE); + g_return_val_if_fail(vci, FALSE); + + if (vci[0] == '\0') { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property cannot be an empty string")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER); + return FALSE; + } + + bin = nm_utils_buf_utf8safe_unescape(vci, + NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, + &unescaped_len, + (gpointer *) &to_free); + /* a DHCP option cannot be longer than 255 bytes */ + if (unescaped_len > 255) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property cannot be longer than 255 bytes")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER); + return FALSE; + } + if (strlen(bin) != unescaped_len) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property cannot contain any nul bytes")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER); + return FALSE; + } + + return TRUE; +} + +gboolean +nm_settings_connection_validate_permission_user(const char *item, gssize len) +{ + gsize l; + + if (!item) + return FALSE; + + if (len < 0) { + nm_assert(len == -1); + l = strlen(item); + } else + l = (gsize) len; + + if (l == 0) + return FALSE; + + if (!g_utf8_validate(item, l, NULL)) + return FALSE; + + if (l >= 100) + return FALSE; + + if (memchr(item, ':', l)) + return FALSE; + + return TRUE; +} diff --git a/src/libnm-core-aux-intern/nm-libnm-core-utils.h b/src/libnm-core-aux-intern/nm-libnm-core-utils.h new file mode 100644 index 0000000..e2a350e --- /dev/null +++ b/src/libnm-core-aux-intern/nm-libnm-core-utils.h @@ -0,0 +1,158 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_LIBNM_SHARED_UTILS_H__ +#define __NM_LIBNM_SHARED_UTILS_H__ + +/****************************************************************************/ + +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-connection.h" +#include "nm-setting-ip-config.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" +#include "nm-setting-sriov.h" +#include "nm-setting-team.h" +#include "nm-setting-vlan.h" +#include "nm-setting-wireguard.h" + +/****************************************************************************/ + +#define nm_auto_unref_ip_address nm_auto(_nm_ip_address_unref) +NM_AUTO_DEFINE_FCN0(NMIPAddress *, _nm_ip_address_unref, nm_ip_address_unref); + +#define nm_auto_unref_ip_route nm_auto(_nm_auto_unref_ip_route) +NM_AUTO_DEFINE_FCN0(NMIPRoute *, _nm_auto_unref_ip_route, nm_ip_route_unref); + +#define nm_auto_unref_ip_routing_rule nm_auto(_nm_auto_unref_ip_routing_rule) +NM_AUTO_DEFINE_FCN0(NMIPRoutingRule *, _nm_auto_unref_ip_routing_rule, nm_ip_routing_rule_unref); + +#define nm_auto_unref_sriov_vf nm_auto(_nm_auto_unref_sriov_vf) +NM_AUTO_DEFINE_FCN0(NMSriovVF *, _nm_auto_unref_sriov_vf, nm_sriov_vf_unref); + +#define nm_auto_unref_tc_qdisc nm_auto(_nm_auto_unref_tc_qdisc) +NM_AUTO_DEFINE_FCN0(NMTCQdisc *, _nm_auto_unref_tc_qdisc, nm_tc_qdisc_unref); + +#define nm_auto_unref_tc_tfilter nm_auto(_nm_auto_unref_tc_tfilter) +NM_AUTO_DEFINE_FCN0(NMTCTfilter *, _nm_auto_unref_tc_tfilter, nm_tc_tfilter_unref); + +#define nm_auto_unref_bridge_vlan nm_auto(_nm_auto_unref_bridge_vlan) +NM_AUTO_DEFINE_FCN0(NMBridgeVlan *, _nm_auto_unref_bridge_vlan, nm_bridge_vlan_unref); + +#define nm_auto_unref_team_link_watcher nm_auto(_nm_auto_unref_team_link_watcher) +NM_AUTO_DEFINE_FCN0(NMTeamLinkWatcher *, + _nm_auto_unref_team_link_watcher, + nm_team_link_watcher_unref); + +#define nm_auto_unref_wgpeer nm_auto(_nm_auto_unref_wgpeer) +NM_AUTO_DEFINE_FCN0(NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_unref); + +/****************************************************************************/ + +const char **nm_utils_bond_option_arp_ip_targets_split(const char *arp_ip_target); + +void _nm_setting_bond_remove_options_miimon(NMSettingBond *s_bond); +void _nm_setting_bond_remove_options_arp_interval(NMSettingBond *s_bond); + +typedef enum { + NM_BOND_MODE_UNKNOWN = -1, + + /* The numeric values correspond to kernel's numbering of the modes. */ + NM_BOND_MODE_ROUNDROBIN = 0, + NM_BOND_MODE_ACTIVEBACKUP = 1, + NM_BOND_MODE_XOR = 2, + NM_BOND_MODE_BROADCAST = 3, + NM_BOND_MODE_8023AD = 4, + NM_BOND_MODE_TLB = 5, + NM_BOND_MODE_ALB = 6, + + _NM_BOND_MODE_NUM, +} NMBondMode; + +NMBondMode _nm_setting_bond_mode_from_string(const char *str); + +const char *_nm_setting_bond_mode_to_string(int mode); + +gboolean _nm_setting_bond_validate_option(const char *name, const char *value, GError **error); + +/*****************************************************************************/ + +static inline guint32 +nm_utils_vlan_priority_map_get_max_prio(NMVlanPriorityMap map, gboolean from) +{ + if (map == NM_VLAN_INGRESS_MAP) { + return from ? 7u /* MAX_8021P_PRIO */ + : (guint32) G_MAXUINT32 /* MAX_SKB_PRIO */; + } + nm_assert(map == NM_VLAN_EGRESS_MAP); + return from ? (guint32) G_MAXUINT32 /* MAX_SKB_PRIO */ + : 7u /* MAX_8021P_PRIO */; +} + +gboolean nm_utils_vlan_priority_map_parse_str(NMVlanPriorityMap map_type, + const char * str, + gboolean allow_wildcard_to, + guint32 * out_from, + guint32 * out_to, + gboolean * out_has_wildcard_to); + +/*****************************************************************************/ + +#define NM_OVS_EXTERNAL_ID_NM_PREFIX "NM." +#define NM_OVS_EXTERNAL_ID_NM_CONNECTION_UUID "NM.connection.uuid" + +/*****************************************************************************/ + +static inline int +nm_setting_ip_config_get_addr_family(NMSettingIPConfig *s_ip) +{ + if (NM_IS_SETTING_IP4_CONFIG(s_ip)) + return AF_INET; + if (NM_IS_SETTING_IP6_CONFIG(s_ip)) + return AF_INET6; + g_return_val_if_reached(AF_UNSPEC); +} + +/*****************************************************************************/ + +/* The maximum MTU for infiniband. + * + * This is both in transport-mode "datagram" and "connected" + * and they both have the same maximum define. + * + * Note that in the past, MTU in "datagram" mode was restricted + * to 2044 bytes. That is no longer the case and we accept large + * MTUs. + * + * This define is the maxiumum for the MTU in a connection profile (the + * setting). Whether large MTUs can be configured later (at activation time) + * depends on other factors. */ +#define NM_INFINIBAND_MAX_MTU ((guint) 65520) + +/*****************************************************************************/ + +#define _NM_CAPABILITY_MAX NM_CAPABILITY_OVS + +/*****************************************************************************/ + +extern const char *const nm_auth_permission_names_by_idx[NM_CLIENT_PERMISSION_LAST]; +extern const NMClientPermission nm_auth_permission_sorted[NM_CLIENT_PERMISSION_LAST]; + +const char * nm_auth_permission_to_string(NMClientPermission permission); +NMClientPermission nm_auth_permission_from_string(const char *str); + +/*****************************************************************************/ + +NMClientPermissionResult nm_client_permission_result_from_string(const char *nm); +const char * nm_client_permission_result_to_string(NMClientPermissionResult permission); + +gboolean nm_utils_validate_dhcp4_vendor_class_id(const char *vci, GError **error); + +/*****************************************************************************/ + +#define NM_SETTINGS_CONNECTION_PERMISSION_USER "user" +#define NM_SETTINGS_CONNECTION_PERMISSION_USER_PREFIX "user:" + +gboolean nm_settings_connection_validate_permission_user(const char *item, gssize len); + +#endif /* __NM_LIBNM_SHARED_UTILS_H__ */ diff --git a/src/libnm-core-impl/README.md b/src/libnm-core-impl/README.md new file mode 100644 index 0000000..0fce8e1 --- /dev/null +++ b/src/libnm-core-impl/README.md @@ -0,0 +1,22 @@ +libnm-core-impl +=============== + +NetworkManager provides a client library [`libnm`](../../libnm). +NetworkManager core does not (dynamically) link against all of libnm. +Instead, it statically links against a part of it. +That part is the static helper library `libnm-core-impl`. + +`libnm-core-impl` implements (and provides) the API from +[`libnm-core-public`](../libnm-core-public), which is part of the public +API of [`libnm`](../../libnm). In this form, `libnm-core-impl` is part +of the implementation of [`libnm`](../../libnm). It also implements (and +provides) an internal API [`libnm-core-intern`](../libnm-core-intern) which +can only be used by those who link statically against `libnm-core-impl`. + +Only NetworkManager core and [`libnm`](../../libnm) are allowed to statically +link with `libnm-core-impl`. Consequently, only those are allowed to include +[`libnm-core-intern`](../libnm-core-intern). + +This directory should not be added to the include search path of other +components as they are only allowed to include [`libnm-core-public`](../libnm-core-public) +and [`libnm-core-intern`](../libnm-core-intern). diff --git a/src/libnm-core-impl/meson.build b/src/libnm-core-impl/meson.build new file mode 100644 index 0000000..2b76961 --- /dev/null +++ b/src/libnm-core-impl/meson.build @@ -0,0 +1,115 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_core_impl_inc = include_directories('.') + +libnm_crypto_nss = static_library( + 'nm-crypto-nss', + sources: 'nm-crypto-nss.c', + dependencies: [ + libnm_core_public_dep, + crypto_nss_dep, + ], +) + +libnm_crypto_gnutls = static_library( + 'nm-crypto-gnutls', + sources: 'nm-crypto-gnutls.c', + dependencies: [ + libnm_core_public_dep, + crypto_gnutls_dep, + ], +) + +if crypto == 'nss' + libnm_crypto = libnm_crypto_nss +else + assert(crypto == 'gnutls', 'Unexpected setting "crypto=' + crypto + '"') + libnm_crypto = libnm_crypto_gnutls +endif + +libnm_core_settings_sources = files( + 'nm-setting-6lowpan.c', + 'nm-setting-8021x.c', + 'nm-setting-adsl.c', + 'nm-setting-bluetooth.c', + 'nm-setting-bond.c', + 'nm-setting-bridge-port.c', + 'nm-setting-bridge.c', + 'nm-setting-cdma.c', + 'nm-setting-connection.c', + 'nm-setting-dcb.c', + 'nm-setting-dummy.c', + 'nm-setting-ethtool.c', + 'nm-setting-generic.c', + 'nm-setting-gsm.c', + 'nm-setting-hostname.c', + 'nm-setting-infiniband.c', + 'nm-setting-ip-config.c', + 'nm-setting-ip-tunnel.c', + 'nm-setting-ip4-config.c', + 'nm-setting-ip6-config.c', + 'nm-setting-macsec.c', + 'nm-setting-macvlan.c', + 'nm-setting-match.c', + 'nm-setting-olpc-mesh.c', + 'nm-setting-ovs-bridge.c', + 'nm-setting-ovs-dpdk.c', + 'nm-setting-ovs-external-ids.c', + 'nm-setting-ovs-interface.c', + 'nm-setting-ovs-patch.c', + 'nm-setting-ovs-port.c', + 'nm-setting-ppp.c', + 'nm-setting-pppoe.c', + 'nm-setting-proxy.c', + 'nm-setting-serial.c', + 'nm-setting-sriov.c', + 'nm-setting-tc-config.c', + 'nm-setting-team-port.c', + 'nm-setting-team.c', + 'nm-setting-tun.c', + 'nm-setting-user.c', + 'nm-setting-veth.c', + 'nm-setting-vlan.c', + 'nm-setting-vpn.c', + 'nm-setting-vrf.c', + 'nm-setting-vxlan.c', + 'nm-setting-wifi-p2p.c', + 'nm-setting-wimax.c', + 'nm-setting-wired.c', + 'nm-setting-wireguard.c', + 'nm-setting-wireless-security.c', + 'nm-setting-wireless.c', + 'nm-setting-wpan.c', +) + +libnm_core_impl_sources = files( + 'nm-connection.c', + 'nm-crypto.c', + 'nm-dbus-utils.c', + 'nm-errors.c', + 'nm-keyfile-utils.c', + 'nm-keyfile.c', + 'nm-meta-setting-base-impl.c', + 'nm-property-compare.c', + 'nm-setting.c', + 'nm-simple-connection.c', + 'nm-team-utils.c', + 'nm-utils.c', + 'nm-vpn-editor-plugin.c', + 'nm-vpn-plugin-info.c', +) + +libnm_core_impl = static_library( + 'nm-core-impl', + sources: libnm_core_impl_sources + libnm_core_settings_sources + libnm_core_public_enum_sources + [nm_version_macro_header], + include_directories: [ + top_inc, + src_inc, + libnm_core_intern_inc, + ], + dependencies: [ + dl_dep, + libnm_core_public_dep, + uuid_dep, + ], +) diff --git a/src/libnm-core-impl/nm-connection-private.h b/src/libnm-core-impl/nm-connection-private.h new file mode 100644 index 0000000..532b176 --- /dev/null +++ b/src/libnm-core-impl/nm-connection-private.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NM_CONNECTION_PRIVATE_H__ +#define __NM_CONNECTION_PRIVATE_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) + #error Cannot use this header. +#endif + +#include "nm-setting.h" +#include "nm-connection.h" + +NMSetting *_nm_connection_find_base_type_setting(NMConnection *connection); + +const char *_nm_connection_detect_slave_type(NMConnection *connection, NMSetting **out_s_port); + +gboolean _nm_connection_detect_slave_type_full(NMSettingConnection *s_con, + NMConnection * connection, + const char ** out_slave_type, + const char ** out_normerr_slave_setting_type, + const char ** out_normerr_missing_slave_type, + const char **out_normerr_missing_slave_type_port, + GError ** error); + +const char *_nm_connection_detect_bluetooth_type(NMConnection *self); + +gboolean _nm_connection_verify_required_interface_name(NMConnection *connection, GError **error); + +int _nm_setting_ovs_interface_verify_interface_type(NMSettingOvsInterface *self, + const char * type, + NMConnection * connection, + gboolean normalize, + gboolean * out_modified, + const char ** out_normalized_type, + GError ** error); + +#endif /* __NM_CONNECTION_PRIVATE_H__ */ diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c new file mode 100644 index 0000000..bc070a9 --- /dev/null +++ b/src/libnm-core-impl/nm-connection.c @@ -0,0 +1,3391 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2018 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-connection.h" + +#include + +#include "nm-connection-private.h" +#include "nm-utils.h" +#include "nm-setting-private.h" +#include "libnm-core-intern/nm-core-internal.h" + +/** + * SECTION:nm-connection + * @short_description: Describes a connection to specific network or provider + * + * An #NMConnection describes all the settings and configuration values that + * are necessary to configure network devices for operation on a specific + * network. Connections are the fundamental operating object for + * NetworkManager; no device is connected without a #NMConnection, or + * disconnected without having been connected with a #NMConnection. + * + * Each #NMConnection contains a list of #NMSetting objects usually referenced + * by name (using nm_connection_get_setting_by_name()) or by type (with + * nm_connection_get_setting()). The settings describe the actual parameters + * with which the network devices are configured, including device-specific + * parameters (MTU, SSID, APN, channel, rate, etc) and IP-level parameters + * (addresses, routes, addressing methods, etc). + * + */ + +/*****************************************************************************/ + +enum { SECRETS_UPDATED, SECRETS_CLEARED, CHANGED, LAST_SIGNAL }; + +static guint signals[LAST_SIGNAL] = {0}; + +typedef struct { + NMConnection *self; + + GHashTable *settings; + + /* D-Bus path of the connection, if any */ + char *path; +} NMConnectionPrivate; + +G_DEFINE_INTERFACE(NMConnection, nm_connection, G_TYPE_OBJECT) + +static NMConnectionPrivate *nm_connection_get_private(NMConnection *connection); +#define NM_CONNECTION_GET_PRIVATE(o) (nm_connection_get_private((NMConnection *) o)) + +/*****************************************************************************/ + +static gpointer +_gtype_to_hash_key(GType gtype) +{ +#if NM_MORE_ASSERTS + _nm_unused const gsize *const test_gtype_typedef = >ype; + + nm_assert((GType)(GPOINTER_TO_SIZE(GSIZE_TO_POINTER(gtype))) == gtype); + G_STATIC_ASSERT_EXPR(sizeof(gpointer) >= sizeof(gsize)); + G_STATIC_ASSERT_EXPR(sizeof(gsize) == sizeof(GType)); +#endif + + return GSIZE_TO_POINTER(gtype); +} + +/*****************************************************************************/ + +static void +setting_changed_cb(NMSetting *setting, GParamSpec *pspec, NMConnection *self) +{ + g_signal_emit(self, signals[CHANGED], 0); +} + +static void +_setting_release(NMConnection *connection, NMSetting *setting) +{ + g_signal_handlers_disconnect_by_func(setting, setting_changed_cb, connection); +} + +static gboolean +_setting_release_hfr(gpointer key, gpointer value, gpointer user_data) +{ + _setting_release(user_data, value); + return TRUE; +} + +static void +_nm_connection_add_setting(NMConnection *connection, NMSetting *setting) +{ + NMConnectionPrivate *priv; + GType setting_type; + NMSetting * s_old; + + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(NM_IS_SETTING(setting)); + + priv = NM_CONNECTION_GET_PRIVATE(connection); + setting_type = G_OBJECT_TYPE(setting); + + if ((s_old = g_hash_table_lookup(priv->settings, _gtype_to_hash_key(setting_type)))) + _setting_release(connection, s_old); + + g_hash_table_insert(priv->settings, _gtype_to_hash_key(setting_type), setting); + + g_signal_connect(setting, "notify", (GCallback) setting_changed_cb, connection); +} + +/** + * nm_connection_add_setting: + * @connection: a #NMConnection + * @setting: (transfer full): the #NMSetting to add to the connection object + * + * Adds a #NMSetting to the connection, replacing any previous #NMSetting of the + * same name which has previously been added to the #NMConnection. The + * connection takes ownership of the #NMSetting object and does not increase + * the setting object's reference count. + **/ +void +nm_connection_add_setting(NMConnection *connection, NMSetting *setting) +{ + g_return_if_fail(NM_IS_CONNECTION(connection)); + g_return_if_fail(NM_IS_SETTING(setting)); + + _nm_connection_add_setting(connection, setting); + g_signal_emit(connection, signals[CHANGED], 0); +} + +gboolean +_nm_connection_remove_setting(NMConnection *connection, GType setting_type) +{ + NMConnectionPrivate *priv; + NMSetting * setting; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(g_type_is_a(setting_type, NM_TYPE_SETTING), FALSE); + + priv = NM_CONNECTION_GET_PRIVATE(connection); + setting = g_hash_table_lookup(priv->settings, _gtype_to_hash_key(setting_type)); + if (setting) { + g_signal_handlers_disconnect_by_func(setting, setting_changed_cb, connection); + g_hash_table_remove(priv->settings, _gtype_to_hash_key(setting_type)); + g_signal_emit(connection, signals[CHANGED], 0); + return TRUE; + } + return FALSE; +} + +/** + * nm_connection_remove_setting: + * @connection: a #NMConnection + * @setting_type: the #GType of the setting object to remove + * + * Removes the #NMSetting with the given #GType from the #NMConnection. This + * operation dereferences the #NMSetting object. + **/ +void +nm_connection_remove_setting(NMConnection *connection, GType setting_type) +{ + _nm_connection_remove_setting(connection, setting_type); +} + +static gpointer +_connection_get_setting(NMConnection *connection, GType setting_type) +{ + NMSetting *setting; + + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(g_type_is_a(setting_type, NM_TYPE_SETTING)); + + setting = g_hash_table_lookup(NM_CONNECTION_GET_PRIVATE(connection)->settings, + _gtype_to_hash_key(setting_type)); + nm_assert(!setting || G_TYPE_CHECK_INSTANCE_TYPE(setting, setting_type)); + return setting; +} + +static gpointer +_connection_get_setting_check(NMConnection *connection, GType setting_type) +{ + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + + return _connection_get_setting(connection, setting_type); +} + +/** + * nm_connection_get_setting: + * @connection: a #NMConnection + * @setting_type: the #GType of the setting object to return + * + * Gets the #NMSetting with the given #GType, if one has been previously added + * to the #NMConnection. + * + * Returns: (transfer none): the #NMSetting, or %NULL if no setting of that type was previously + * added to the #NMConnection + **/ +NMSetting * +nm_connection_get_setting(NMConnection *connection, GType setting_type) +{ + g_return_val_if_fail(g_type_is_a(setting_type, NM_TYPE_SETTING), NULL); + + return _connection_get_setting_check(connection, setting_type); +} + +NMSettingIPConfig * +nm_connection_get_setting_ip_config(NMConnection *connection, int addr_family) +{ + nm_assert_addr_family(addr_family); + + return NM_SETTING_IP_CONFIG(_connection_get_setting( + connection, + (addr_family == AF_INET) ? NM_TYPE_SETTING_IP4_CONFIG : NM_TYPE_SETTING_IP6_CONFIG)); +} + +/** + * nm_connection_get_setting_by_name: + * @connection: a #NMConnection + * @name: a setting name + * + * Gets the #NMSetting with the given name, if one has been previously added + * the #NMConnection. + * + * Returns: (transfer none): the #NMSetting, or %NULL if no setting with that name was previously + * added to the #NMConnection + **/ +NMSetting * +nm_connection_get_setting_by_name(NMConnection *connection, const char *name) +{ + GType type; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + + type = nm_setting_lookup_type(name); + return type ? _connection_get_setting(connection, type) : NULL; +} + +/*****************************************************************************/ + +gpointer /* (NMSetting *) */ +_nm_connection_check_main_setting(NMConnection *connection, + const char * setting_name, + GError ** error) +{ + NMSetting *setting; + + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(setting_name); + + if (!nm_connection_is_type(connection, setting_name)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, + "connection type is not \"%s\"", + setting_name); + return NULL; + } + + setting = nm_connection_get_setting_by_name(connection, setting_name); + if (!setting) { + nm_utils_error_set(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, + "connection misses \"%s\" settings", + setting_name); + return NULL; + } + + return setting; +} + +/*****************************************************************************/ + +static gboolean +validate_permissions_type(GVariant *variant, GError **error) +{ + GVariant *s_con; + GVariant *permissions; + gboolean valid = TRUE; + + /* Ensure the connection::permissions item (if present) is the correct + * type, otherwise the g_object_set() will throw a warning and ignore the + * error, leaving us with no permissions. + */ + s_con = g_variant_lookup_value(variant, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_VARIANT_TYPE_SETTING); + if (!s_con) + return TRUE; + + permissions = g_variant_lookup_value(s_con, NM_SETTING_CONNECTION_PERMISSIONS, NULL); + if (permissions) { + if (!g_variant_is_of_type(permissions, G_VARIANT_TYPE_STRING_ARRAY)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("wrong type; should be a list of strings.")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_PERMISSIONS); + valid = FALSE; + } + g_variant_unref(permissions); + } + + g_variant_unref(s_con); + return valid; +} + +/** + * _nm_connection_replace_settings: + * @connection: a #NMConnection + * @new_settings: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION, with the new settings + * @parse_flags: flags. + * @error: location to store error, or %NULL + * + * Replaces @connection's settings with @new_settings (which must be + * syntactically valid, and describe a known type of connection, but does not + * need to result in a connection that passes nm_connection_verify()). + * + * Returns: %TRUE if connection was updated, %FALSE if @new_settings could not + * be deserialized (in which case @connection will be unchanged). + * Only exception is the NM_SETTING_PARSE_FLAGS_NORMALIZE flag: if normalization + * fails, the input @connection is already modified and the original settings + * are lost. + **/ +gboolean +_nm_connection_replace_settings(NMConnection * connection, + GVariant * new_settings, + NMSettingParseFlags parse_flags, + GError ** error) +{ + NMConnectionPrivate *priv; + GVariantIter iter; + const char * setting_name; + GVariant * setting_dict; + GSList * settings = NULL, *s; + gboolean changed, success; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(g_variant_is_of_type(new_settings, NM_VARIANT_TYPE_CONNECTION), FALSE); + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + + nm_assert(!NM_FLAGS_ANY(parse_flags, ~NM_SETTING_PARSE_FLAGS_ALL)); + nm_assert(!NM_FLAGS_ALL(parse_flags, + NM_SETTING_PARSE_FLAGS_STRICT | NM_SETTING_PARSE_FLAGS_BEST_EFFORT)); + + priv = NM_CONNECTION_GET_PRIVATE(connection); + + if (!NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_BEST_EFFORT) + && !validate_permissions_type(new_settings, error)) + return FALSE; + + g_variant_iter_init(&iter, new_settings); + while (g_variant_iter_next(&iter, "{&s@a{sv}}", &setting_name, &setting_dict)) { + gs_unref_variant GVariant *setting_dict_free = NULL; + GError * local = NULL; + NMSetting * setting; + GType type; + + setting_dict_free = setting_dict; + + type = nm_setting_lookup_type(setting_name); + if (type == G_TYPE_INVALID) { + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_BEST_EFFORT)) + continue; + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("unknown setting name")); + g_prefix_error(error, "%s: ", setting_name); + g_slist_free_full(settings, g_object_unref); + return FALSE; + } + + for (s = settings; s; s = s->next) { + if (G_OBJECT_TYPE(s->data) == type) { + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("duplicate setting name")); + g_prefix_error(error, "%s: ", setting_name); + g_slist_free_full(settings, g_object_unref); + return FALSE; + } + /* last wins. */ + g_object_unref(s->data); + settings = g_slist_delete_link(settings, s); + break; + } + } + + setting = _nm_setting_new_from_dbus(type, setting_dict, new_settings, parse_flags, &local); + + if (!setting) { + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_BEST_EFFORT)) + continue; + g_propagate_error(error, local); + g_slist_free_full(settings, g_object_unref); + return FALSE; + } + + settings = g_slist_prepend(settings, setting); + } + + if (g_hash_table_size(priv->settings) > 0) { + g_hash_table_foreach_remove(priv->settings, _setting_release_hfr, connection); + changed = TRUE; + } else + changed = (settings != NULL); + + /* Note: @settings might be empty in which case the connection + * has no NMSetting instances... which is fine, just something + * to be aware of. */ + for (s = settings; s; s = s->next) + _nm_connection_add_setting(connection, s->data); + + g_slist_free(settings); + + /* If verification/normalization fails, the original connection + * is already lost. From an API point of view, it would be nicer + * not to touch the input argument if we fail at the end. + * However, that would require creating a temporary connection + * to validate it first. As none of the caller cares about the + * state of the @connection when normalization fails, just do it + * this way. */ + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_NORMALIZE)) + success = nm_connection_normalize(connection, NULL, NULL, error); + else + success = TRUE; + + if (changed) + g_signal_emit(connection, signals[CHANGED], 0); + return success; +} + +/** + * nm_connection_replace_settings: + * @connection: a #NMConnection + * @new_settings: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION, with the new settings + * @error: location to store error, or %NULL + * + * Replaces @connection's settings with @new_settings (which must be + * syntactically valid, and describe a known type of connection, but does not + * need to result in a connection that passes nm_connection_verify()). + * + * Returns: %TRUE if connection was updated, %FALSE if @new_settings could not + * be deserialized (in which case @connection will be unchanged). + **/ +gboolean +nm_connection_replace_settings(NMConnection *connection, GVariant *new_settings, GError **error) +{ + return _nm_connection_replace_settings(connection, + new_settings, + NM_SETTING_PARSE_FLAGS_NONE, + error); +} + +/** + * nm_connection_replace_settings_from_connection: + * @connection: a #NMConnection + * @new_connection: a #NMConnection to replace the settings of @connection with + * + * Deep-copies the settings of @new_connection and replaces the settings of @connection + * with the copied settings. + **/ +void +nm_connection_replace_settings_from_connection(NMConnection *connection, + NMConnection *new_connection) +{ + NMConnectionPrivate *priv, *new_priv; + GHashTableIter iter; + NMSetting * setting; + gboolean changed; + + g_return_if_fail(NM_IS_CONNECTION(connection)); + g_return_if_fail(NM_IS_CONNECTION(new_connection)); + + /* When 'connection' and 'new_connection' are the same object simply return + * in order not to destroy 'connection'. + */ + if (connection == new_connection) + return; + + /* No need to validate permissions like nm_connection_replace_settings() + * since we're dealing with an NMConnection which has already done that. + */ + + priv = NM_CONNECTION_GET_PRIVATE(connection); + new_priv = NM_CONNECTION_GET_PRIVATE(new_connection); + + if ((changed = g_hash_table_size(priv->settings) > 0)) + g_hash_table_foreach_remove(priv->settings, _setting_release_hfr, connection); + + if (g_hash_table_size(new_priv->settings)) { + g_hash_table_iter_init(&iter, new_priv->settings); + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &setting)) + _nm_connection_add_setting(connection, nm_setting_duplicate(setting)); + changed = TRUE; + } + + if (changed) + g_signal_emit(connection, signals[CHANGED], 0); +} + +/** + * nm_connection_clear_settings: + * @connection: a #NMConnection + * + * Deletes all of @connection's settings. + **/ +void +nm_connection_clear_settings(NMConnection *connection) +{ + NMConnectionPrivate *priv; + + g_return_if_fail(NM_IS_CONNECTION(connection)); + + priv = NM_CONNECTION_GET_PRIVATE(connection); + + if (g_hash_table_size(priv->settings) > 0) { + g_hash_table_foreach_remove(priv->settings, _setting_release_hfr, connection); + g_signal_emit(connection, signals[CHANGED], 0); + } +} + +/** + * nm_connection_compare: + * @a: a #NMConnection + * @b: a second #NMConnection to compare with the first + * @flags: compare flags, e.g. %NM_SETTING_COMPARE_FLAG_EXACT + * + * Compares two #NMConnection objects for similarity, with comparison behavior + * modified by a set of flags. See nm_setting_compare() for a description of + * each flag's behavior. + * + * Returns: %TRUE if the comparison succeeds, %FALSE if it does not + **/ +gboolean +nm_connection_compare(NMConnection *a, NMConnection *b, NMSettingCompareFlags flags) +{ + GHashTableIter iter; + NMSetting * src; + + if (a == b) + return TRUE; + if (!a || !b) + return FALSE; + + /* B / A: ensure settings in B that are not in A make the comparison fail */ + if (g_hash_table_size(NM_CONNECTION_GET_PRIVATE(a)->settings) + != g_hash_table_size(NM_CONNECTION_GET_PRIVATE(b)->settings)) + return FALSE; + + /* A / B: ensure all settings in A match corresponding ones in B */ + g_hash_table_iter_init(&iter, NM_CONNECTION_GET_PRIVATE(a)->settings); + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &src)) { + NMSetting *cmp = nm_connection_get_setting(b, G_OBJECT_TYPE(src)); + + if (!cmp || !_nm_setting_compare(a, src, b, cmp, flags)) + return FALSE; + } + + return TRUE; +} + +static gboolean +diff_one_connection(NMConnection * a, + NMConnection * b, + NMSettingCompareFlags flags, + gboolean invert_results, + GHashTable * diffs) +{ + NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE(a); + GHashTableIter iter; + NMSetting * a_setting = NULL; + gboolean diff_found = FALSE; + + g_hash_table_iter_init(&iter, priv->settings); + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &a_setting)) { + NMSetting * b_setting = NULL; + const char *setting_name = nm_setting_get_name(a_setting); + GHashTable *results; + gboolean new_results = TRUE; + + if (b) + b_setting = nm_connection_get_setting(b, G_OBJECT_TYPE(a_setting)); + + results = g_hash_table_lookup(diffs, setting_name); + if (results) + new_results = FALSE; + + if (!_nm_setting_diff(a, a_setting, b, b_setting, flags, invert_results, &results)) + diff_found = TRUE; + + if (new_results && results) + g_hash_table_insert(diffs, g_strdup(setting_name), results); + } + + return diff_found; +} + +/** + * nm_connection_diff: + * @a: a #NMConnection + * @b: a second #NMConnection to compare with the first + * @flags: compare flags, e.g. %NM_SETTING_COMPARE_FLAG_EXACT + * @out_settings: (element-type utf8 GLib.HashTable): if the + * connections differ, on return a hash table mapping setting names to + * second-level GHashTable (utf8 to guint32), which contains the key names that + * differ mapped to one or more of %NMSettingDiffResult as a bitfield + * + * Compares two #NMConnection objects for similarity, with comparison behavior + * modified by a set of flags. See nm_setting_compare() for a description of + * each flag's behavior. If the connections differ, settings and keys within + * each setting that differ are added to the returned @out_settings hash table. + * No values are returned, only key names. + * + * Returns: %TRUE if the connections contain the same values, %FALSE if they do + * not + **/ +gboolean +nm_connection_diff(NMConnection * a, + NMConnection * b, + NMSettingCompareFlags flags, + GHashTable ** out_settings) +{ + GHashTable *diffs; + gboolean diff_found = FALSE; + + g_return_val_if_fail(NM_IS_CONNECTION(a), FALSE); + g_return_val_if_fail(!out_settings || !*out_settings, FALSE); + g_return_val_if_fail(!b || NM_IS_CONNECTION(b), FALSE); + + if (a == b) + return TRUE; + + diffs = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_hash_table_destroy); + + /* Diff A to B, then B to A to capture keys in B that aren't in A */ + if (diff_one_connection(a, b, flags, FALSE, diffs)) + diff_found = TRUE; + if (b && diff_one_connection(b, a, flags, TRUE, diffs)) + diff_found = TRUE; + + nm_assert(diff_found == (g_hash_table_size(diffs) != 0)); + + if (g_hash_table_size(diffs) == 0) { + g_hash_table_destroy(diffs); + diffs = NULL; + } + + NM_SET_OUT(out_settings, diffs); + + return !diff_found; +} + +NMSetting * +_nm_connection_find_base_type_setting(NMConnection *connection) +{ + NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE(connection); + GHashTableIter iter; + NMSetting * setting = NULL; + NMSetting * s_iter; + NMSettingPriority setting_prio = NM_SETTING_PRIORITY_USER; + NMSettingPriority s_iter_prio; + + g_hash_table_iter_init(&iter, priv->settings); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &s_iter)) { + s_iter_prio = _nm_setting_get_base_type_priority(s_iter); + if (s_iter_prio == NM_SETTING_PRIORITY_INVALID) + continue; + + if (setting) { + if (s_iter_prio > setting_prio) { + continue; + } else if (s_iter_prio == setting_prio) { + NMSettingConnection *s_con = nm_connection_get_setting_connection(connection); + const char * type; + + if (s_con) { + type = nm_setting_connection_get_connection_type(s_con); + if (type) + return nm_connection_get_setting_by_name(connection, type); + } + return NULL; + } + } + setting = s_iter; + setting_prio = s_iter_prio; + } + return setting; +} + +static gboolean +_normalize_connection_uuid(NMConnection *self) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection(self); + char uuid[37]; + + nm_assert(s_con); + + if (nm_setting_connection_get_uuid(s_con)) + return FALSE; + + g_object_set(s_con, NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_buf(uuid), NULL); + return TRUE; +} + +static gboolean +_normalize_connection_type(NMConnection *self) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection(self); + NMSetting * s_base = NULL; + const char * type; + + type = nm_setting_connection_get_connection_type(s_con); + + if (type) { + s_base = nm_connection_get_setting_by_name(self, type); + + if (!s_base) { + GType base_type = nm_setting_lookup_type(type); + + g_return_val_if_fail(base_type, FALSE); + nm_connection_add_setting(self, g_object_new(base_type, NULL)); + return TRUE; + } + } else { + s_base = _nm_connection_find_base_type_setting(self); + g_return_val_if_fail(s_base, FALSE); + + type = nm_setting_get_name(s_base); + g_object_set(s_con, NM_SETTING_CONNECTION_TYPE, type, NULL); + return TRUE; + } + + return FALSE; +} + +const char * +_nm_connection_detect_bluetooth_type(NMConnection *self) +{ + NMSettingBluetooth *s_bt = nm_connection_get_setting_bluetooth(self); + + if (s_bt && nm_setting_bluetooth_get_connection_type(s_bt)) { + if (nm_connection_get_setting_gsm(self) || nm_connection_get_setting_cdma(self)) + return NM_SETTING_BLUETOOTH_TYPE_DUN; + if (nm_connection_get_setting_bridge(self)) + return NM_SETTING_BLUETOOTH_TYPE_NAP; + return NM_SETTING_BLUETOOTH_TYPE_PANU; + } + + /* NULL means the connection is not a bluetooth type, or it needs + * no normalization, as the type is set explicitly. */ + return NULL; +} + +const char * +_nm_connection_detect_slave_type(NMConnection *connection, NMSetting **out_s_port) +{ + NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE(connection); + GHashTableIter iter; + const char * slave_type = NULL; + NMSetting * s_port = NULL, *s_iter; + + g_hash_table_iter_init(&iter, priv->settings); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &s_iter)) { + const char *name = nm_setting_get_name(s_iter); + const char *i_slave_type = NULL; + + if (!strcmp(name, NM_SETTING_BRIDGE_PORT_SETTING_NAME)) + i_slave_type = NM_SETTING_BRIDGE_SETTING_NAME; + else if (!strcmp(name, NM_SETTING_TEAM_PORT_SETTING_NAME)) + i_slave_type = NM_SETTING_TEAM_SETTING_NAME; + else if (!strcmp(name, NM_SETTING_OVS_PORT_SETTING_NAME)) + i_slave_type = NM_SETTING_OVS_BRIDGE_SETTING_NAME; + else if (!strcmp(name, NM_SETTING_OVS_INTERFACE_SETTING_NAME)) + i_slave_type = NM_SETTING_OVS_PORT_SETTING_NAME; + else + continue; + + if (slave_type) { + /* there are more then one matching port types, cannot detect the slave type. */ + slave_type = NULL; + s_port = NULL; + break; + } + slave_type = i_slave_type; + s_port = s_iter; + } + + if (out_s_port) + *out_s_port = s_port; + return slave_type; +} + +static gboolean +_normalize_connection_slave_type(NMConnection *self) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection(self); + const char * slave_type, *port_type; + + if (!s_con) + return FALSE; + if (!nm_setting_connection_get_master(s_con)) + return FALSE; + + slave_type = nm_setting_connection_get_slave_type(s_con); + if (slave_type) { + if (_nm_setting_slave_type_is_valid(slave_type, &port_type) && port_type) { + NMSetting *s_port; + + s_port = nm_connection_get_setting_by_name(self, port_type); + if (!s_port) { + GType p_type = nm_setting_lookup_type(port_type); + + g_return_val_if_fail(p_type, FALSE); + nm_connection_add_setting(self, g_object_new(p_type, NULL)); + return TRUE; + } + } + } else { + if ((slave_type = _nm_connection_detect_slave_type(self, NULL))) { + g_object_set(s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, slave_type, NULL); + return TRUE; + } + } + return FALSE; +} + +static gboolean +_normalize_ethernet_link_neg(NMConnection *self) +{ + NMSettingWired *s_wired = nm_connection_get_setting_wired(self); + + if (s_wired) { + guint32 speed = nm_setting_wired_get_speed(s_wired); + const char *duplex = nm_setting_wired_get_duplex(s_wired); + + if ((speed && !duplex) || (!speed && duplex)) { + speed = 0; + duplex = NULL; + g_object_set(s_wired, + NM_SETTING_WIRED_SPEED, + (guint) speed, + NM_SETTING_WIRED_DUPLEX, + duplex, + NULL); + return TRUE; + } + } + + return FALSE; +} + +/** + * _supports_addr_family: + * @self: a #NMConnection + * @family: AF_* + * + * Check whether the connection supports certain L3 address family, + * in order to be able to tell whether is should have the corresponding + * setting ("ipv4" for AF_INET and "ipv6" for AF_INET6). + * + * If AF_UNSPEC is given, then the function checks whether the connection + * supports any L3 configuration at all. + * + * Returns: %TRUE if the AF is supported, %FALSE otherwise + **/ +static gboolean +_supports_addr_family(NMConnection *self, int family) +{ + const char * connection_type = nm_connection_get_connection_type(self); + NMSettingConnection *s_con; + + g_return_val_if_fail(connection_type, TRUE); + if (strcmp(connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME) == 0) + return TRUE; + if (strcmp(connection_type, NM_SETTING_WPAN_SETTING_NAME) == 0) + return FALSE; + if (strcmp(connection_type, NM_SETTING_6LOWPAN_SETTING_NAME) == 0) + return family == AF_INET6 || family == AF_UNSPEC; + if ((s_con = nm_connection_get_setting_connection(self)) + && (nm_streq0(nm_setting_connection_get_slave_type(s_con), NM_SETTING_VRF_SETTING_NAME))) + return TRUE; + + return !nm_setting_connection_get_master(nm_connection_get_setting_connection(self)); +} + +static gboolean +_normalize_ip_config(NMConnection *self, GHashTable *parameters) +{ + NMSettingIPConfig *s_ip4, *s_ip6; + NMSettingProxy * s_proxy; + NMSetting * setting; + gboolean changed = FALSE; + guint num, i; + + s_ip4 = nm_connection_get_setting_ip4_config(self); + s_ip6 = nm_connection_get_setting_ip6_config(self); + s_proxy = nm_connection_get_setting_proxy(self); + + if (_supports_addr_family(self, AF_INET)) { + if (!s_ip4) { + const char *default_ip4_method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + + if (nm_connection_is_type(self, NM_SETTING_WIREGUARD_SETTING_NAME)) + default_ip4_method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + + /* But if no IP4 setting was specified, assume the caller was just + * being lazy and use the default method. + */ + setting = nm_setting_ip4_config_new(); + + g_object_set(setting, NM_SETTING_IP_CONFIG_METHOD, default_ip4_method, NULL); + nm_connection_add_setting(self, setting); + changed = TRUE; + } else { + if (nm_setting_ip_config_get_gateway(s_ip4) + && nm_setting_ip_config_get_never_default(s_ip4)) { + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL); + changed = TRUE; + } + + if (nm_streq0(nm_setting_ip_config_get_method(s_ip4), + NM_SETTING_IP4_CONFIG_METHOD_DISABLED) + && !nm_setting_ip_config_get_may_fail(s_ip4)) { + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); + changed = TRUE; + } + + num = nm_setting_ip_config_get_num_addresses(s_ip4); + if (num > 1 + && nm_streq0(nm_setting_ip_config_get_method(s_ip4), + NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { + for (i = num - 1; i > 0; i--) + nm_setting_ip_config_remove_address(s_ip4, i); + changed = TRUE; + } + } + } else { + if (s_ip4) { + nm_connection_remove_setting(self, NM_TYPE_SETTING_IP4_CONFIG); + changed = TRUE; + } + } + + if (_supports_addr_family(self, AF_INET6)) { + if (!s_ip6) { + const char *default_ip6_method = NULL; + + if (parameters) + default_ip6_method = + g_hash_table_lookup(parameters, + NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD); + if (!default_ip6_method) { + if (nm_connection_is_type(self, NM_SETTING_WIREGUARD_SETTING_NAME)) + default_ip6_method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE; + else + default_ip6_method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + } + + /* If no IP6 setting was specified, then assume that means IP6 config is + * allowed to fail. + */ + setting = nm_setting_ip6_config_new(); + + g_object_set(setting, + NM_SETTING_IP_CONFIG_METHOD, + default_ip6_method, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + nm_connection_add_setting(self, setting); + changed = TRUE; + } else { + const char *token; + + token = nm_setting_ip6_config_get_token((NMSettingIP6Config *) s_ip6); + if (token + && nm_setting_ip6_config_get_addr_gen_mode((NMSettingIP6Config *) s_ip6) + == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) { + struct in6_addr i6_token; + char normalized[NM_UTILS_INET_ADDRSTRLEN]; + + if (inet_pton(AF_INET6, token, &i6_token) == 1 + && _nm_utils_inet6_is_token(&i6_token)) { + _nm_utils_inet6_ntop(&i6_token, normalized); + if (g_strcmp0(token, normalized)) { + g_object_set(s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, normalized, NULL); + changed = TRUE; + } + } + } + + if (nm_setting_ip_config_get_gateway(s_ip6) + && nm_setting_ip_config_get_never_default(s_ip6)) { + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL); + changed = TRUE; + } + + if (NM_IN_STRSET(nm_setting_ip_config_get_method(s_ip6), + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED) + && !nm_setting_ip_config_get_may_fail(s_ip6)) { + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); + changed = TRUE; + } + } + } else { + if (s_ip6) { + nm_connection_remove_setting(self, NM_TYPE_SETTING_IP6_CONFIG); + changed = TRUE; + } + } + + if (_supports_addr_family(self, AF_UNSPEC)) { + if (!s_proxy) { + setting = nm_setting_proxy_new(); + nm_connection_add_setting(self, setting); + changed = TRUE; + } + } else { + if (s_proxy) { + nm_connection_remove_setting(self, NM_TYPE_SETTING_PROXY); + changed = TRUE; + } + } + + return changed; +} + +static gboolean +_normalize_infiniband_mtu(NMConnection *self) +{ + NMSettingInfiniband *s_infini = nm_connection_get_setting_infiniband(self); + + if (!s_infini || nm_setting_infiniband_get_mtu(s_infini) <= NM_INFINIBAND_MAX_MTU + || !NM_IN_STRSET(nm_setting_infiniband_get_transport_mode(s_infini), + "datagram", + "connected")) + return FALSE; + + g_object_set(s_infini, NM_SETTING_INFINIBAND_MTU, (guint) NM_INFINIBAND_MAX_MTU, NULL); + return TRUE; +} + +static gboolean +_normalize_bond_mode(NMConnection *self) +{ + NMSettingBond *s_bond = nm_connection_get_setting_bond(self); + + /* Convert mode from numeric to string notation */ + if (s_bond) { + const char *mode = nm_setting_bond_get_option_by_name(s_bond, NM_SETTING_BOND_OPTION_MODE); + int mode_int = nm_utils_bond_mode_string_to_int(mode); + + if (mode_int != -1) { + const char *mode_new = nm_utils_bond_mode_int_to_string(mode_int); + + if (!nm_streq0(mode_new, mode)) { + nm_setting_bond_add_option(s_bond, NM_SETTING_BOND_OPTION_MODE, mode_new); + return TRUE; + } + } + } + return FALSE; +} + +static gboolean +_normalize_bond_options(NMConnection *self) +{ + NMSettingBond *s_bond = nm_connection_get_setting_bond(self); + gboolean changed = FALSE; + const char * name, *mode_str; + NMBondMode mode; + guint32 num, i; + + /* Strip away unsupported options for current mode */ + if (s_bond) { + mode_str = nm_setting_bond_get_option_by_name(s_bond, NM_SETTING_BOND_OPTION_MODE); + mode = _nm_setting_bond_mode_from_string(mode_str); + if (mode == NM_BOND_MODE_UNKNOWN) + return FALSE; +again: + num = nm_setting_bond_get_num_options(s_bond); + for (i = 0; i < num; i++) { + if (nm_setting_bond_get_option(s_bond, i, &name, NULL) + && !_nm_setting_bond_option_supported(name, mode)) { + nm_setting_bond_remove_option(s_bond, name); + changed = TRUE; + goto again; + } + } + } + + return changed; +} + +static gboolean +_normalize_wireless_mac_address_randomization(NMConnection *self) +{ + NMSettingWireless * s_wifi = nm_connection_get_setting_wireless(self); + const char * cloned_mac_address; + NMSettingMacRandomization mac_address_randomization; + + if (!s_wifi) + return FALSE; + + mac_address_randomization = nm_setting_wireless_get_mac_address_randomization(s_wifi); + if (!NM_IN_SET(mac_address_randomization, + NM_SETTING_MAC_RANDOMIZATION_DEFAULT, + NM_SETTING_MAC_RANDOMIZATION_NEVER, + NM_SETTING_MAC_RANDOMIZATION_ALWAYS)) + return FALSE; + + cloned_mac_address = nm_setting_wireless_get_cloned_mac_address(s_wifi); + if (cloned_mac_address) { + if (nm_streq(cloned_mac_address, "random")) { + if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS) + return FALSE; + mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_ALWAYS; + } else if (nm_streq(cloned_mac_address, "permanent")) { + if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_NEVER) + return FALSE; + mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER; + } else { + if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) + return FALSE; + mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; + } + g_object_set(s_wifi, + NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, + mac_address_randomization, + NULL); + return TRUE; + } + if (mac_address_randomization != NM_SETTING_MAC_RANDOMIZATION_DEFAULT) { + g_object_set(s_wifi, + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, + mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS ? "random" + : "permanent", + NULL); + return TRUE; + } + return FALSE; +} + +static gboolean +_normalize_macsec(NMConnection *self) +{ + NMSettingMacsec *s_macsec = nm_connection_get_setting_macsec(self); + gboolean changed = FALSE; + + if (!s_macsec) + return FALSE; + + if (nm_setting_macsec_get_mode(s_macsec) != NM_SETTING_MACSEC_MODE_PSK) { + if (nm_setting_macsec_get_mka_cak(s_macsec)) { + g_object_set(s_macsec, NM_SETTING_MACSEC_MKA_CAK, NULL, NULL); + changed = TRUE; + } + if (nm_setting_macsec_get_mka_ckn(s_macsec)) { + g_object_set(s_macsec, NM_SETTING_MACSEC_MKA_CKN, NULL, NULL); + changed = TRUE; + } + } + + return changed; +} + +static gboolean +_normalize_team_config(NMConnection *self) +{ + NMSettingTeam *s_team = nm_connection_get_setting_team(self); + + if (s_team) { + const char *config = nm_setting_team_get_config(s_team); + + if (config && !*config) { + g_object_set(s_team, NM_SETTING_TEAM_CONFIG, NULL, NULL); + return TRUE; + } + } + return FALSE; +} + +static gboolean +_normalize_team_port_config(NMConnection *self) +{ + NMSettingTeamPort *s_team_port = nm_connection_get_setting_team_port(self); + + if (s_team_port) { + const char *config = nm_setting_team_port_get_config(s_team_port); + + if (config && !*config) { + g_object_set(s_team_port, NM_SETTING_TEAM_PORT_CONFIG, NULL, NULL); + return TRUE; + } + } + return FALSE; +} + +static gboolean +_normalize_bluetooth_type(NMConnection *self) +{ + const char *type = _nm_connection_detect_bluetooth_type(self); + + if (type) { + g_object_set(nm_connection_get_setting_bluetooth(self), + NM_SETTING_BLUETOOTH_TYPE, + type, + NULL); + return TRUE; + } + return FALSE; +} + +static gboolean +_normalize_ovs_interface_type(NMConnection *self) +{ + NMSettingOvsInterface *s_ovs_interface = nm_connection_get_setting_ovs_interface(self); + gboolean modified; + int v; + + if (!s_ovs_interface) + return FALSE; + + v = _nm_setting_ovs_interface_verify_interface_type( + s_ovs_interface, + nm_setting_ovs_interface_get_interface_type(s_ovs_interface), + self, + TRUE, + &modified, + NULL, + NULL); + if (v != TRUE) + g_return_val_if_reached(modified); + + return modified; +} + +static gboolean +_normalize_ip_tunnel_wired_setting(NMConnection *self) +{ + NMSettingIPTunnel *s_ip_tunnel; + + s_ip_tunnel = nm_connection_get_setting_ip_tunnel(self); + if (!s_ip_tunnel) + return FALSE; + + if (nm_connection_get_setting_wired(self) + && !NM_IN_SET(nm_setting_ip_tunnel_get_mode(s_ip_tunnel), + NM_IP_TUNNEL_MODE_GRETAP, + NM_IP_TUNNEL_MODE_IP6GRETAP)) { + nm_connection_remove_setting(self, NM_TYPE_SETTING_WIRED); + return TRUE; + } + + return FALSE; +} + +static gboolean +_normalize_sriov_vf_order(NMConnection *self) +{ + NMSettingSriov *s_sriov; + + s_sriov = NM_SETTING_SRIOV(nm_connection_get_setting(self, NM_TYPE_SETTING_SRIOV)); + if (!s_sriov) + return FALSE; + + return _nm_setting_sriov_sort_vfs(s_sriov); +} + +static gboolean +_normalize_bridge_vlan_order(NMConnection *self) +{ + NMSettingBridge *s_bridge; + + s_bridge = nm_connection_get_setting_bridge(self); + if (!s_bridge) + return FALSE; + + return _nm_setting_bridge_sort_vlans(s_bridge); +} + +static gboolean +_normalize_bridge_port_vlan_order(NMConnection *self) +{ + NMSettingBridgePort *s_port; + + s_port = nm_connection_get_setting_bridge_port(self); + if (!s_port) + return FALSE; + + return _nm_setting_bridge_port_sort_vlans(s_port); +} + +static gboolean +_normalize_gsm_auto_config(NMConnection *self) +{ + NMSettingGsm *s_gsm; + + s_gsm = nm_connection_get_setting_gsm(self); + if (!s_gsm) + return FALSE; + + if (!nm_setting_gsm_get_auto_config(s_gsm)) + return FALSE; + + if (!nm_setting_gsm_get_apn(s_gsm) && !nm_setting_gsm_get_username(s_gsm) + && !nm_setting_gsm_get_password(s_gsm)) + return FALSE; + + g_object_set(s_gsm, NM_SETTING_GSM_AUTO_CONFIG, FALSE, NULL); + return TRUE; +} + +static gboolean +_normalize_required_settings(NMConnection *self) +{ + NMSettingBluetooth *s_bt = nm_connection_get_setting_bluetooth(self); + NMSetting * s_bridge; + gboolean changed = FALSE; + + if (nm_connection_get_setting_vlan(self)) { + if (!nm_connection_get_setting_wired(self)) { + nm_connection_add_setting(self, nm_setting_wired_new()); + changed = TRUE; + } + } + if (s_bt + && nm_streq0(nm_setting_bluetooth_get_connection_type(s_bt), + NM_SETTING_BLUETOOTH_TYPE_NAP)) { + if (!nm_connection_get_setting_bridge(self)) { + s_bridge = nm_setting_bridge_new(); + g_object_set(s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL); + nm_connection_add_setting(self, s_bridge); + changed = TRUE; + } + } + return changed; +} + +static gboolean +_normalize_invalid_slave_port_settings(NMConnection *self) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection(self); + const char * slave_type; + gboolean changed = FALSE; + + slave_type = nm_setting_connection_get_slave_type(s_con); + + if (!nm_streq0(slave_type, NM_SETTING_BRIDGE_SETTING_NAME) + && _nm_connection_remove_setting(self, NM_TYPE_SETTING_BRIDGE_PORT)) + changed = TRUE; + + if (!nm_streq0(slave_type, NM_SETTING_TEAM_SETTING_NAME) + && _nm_connection_remove_setting(self, NM_TYPE_SETTING_TEAM_PORT)) + changed = TRUE; + + return changed; +} + +/** + * nm_connection_verify: + * @connection: the #NMConnection to verify + * @error: location to store error, or %NULL + * + * Validates the connection and all its settings. Each setting's properties + * have allowed values, and some values are dependent on other values. For + * example, if a Wi-Fi connection is security enabled, the #NMSettingWireless + * setting object's 'security' property must contain the setting name of the + * #NMSettingWirelessSecurity object, which must also be present in the + * connection for the connection to be valid. As another example, the + * #NMSettingWired object's 'mac-address' property must be a validly formatted + * MAC address. The returned #GError contains information about which + * setting and which property failed validation, and how it failed validation. + * + * Returns: %TRUE if the connection is valid, %FALSE if it is not + **/ +gboolean +nm_connection_verify(NMConnection *connection, GError **error) +{ + NMSettingVerifyResult result; + + result = _nm_connection_verify(connection, error); + + /* we treat normalizable connections as valid. */ + if (result == NM_SETTING_VERIFY_NORMALIZABLE) + g_clear_error(error); + + return result == NM_SETTING_VERIFY_SUCCESS || result == NM_SETTING_VERIFY_NORMALIZABLE; +} + +NMSettingVerifyResult +_nm_connection_verify(NMConnection *connection, GError **error) +{ + NMSettingIPConfig *s_ip4, *s_ip6; + NMSettingProxy * s_proxy; + gs_free NMSetting **settings = NULL; + gs_free_error GError *normalizable_error = NULL; + NMSettingVerifyResult normalizable_error_type = NM_SETTING_VERIFY_SUCCESS; + guint i; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail(!error || !*error, NM_SETTING_VERIFY_ERROR); + + settings = nm_connection_get_settings(connection, NULL); + if (!settings || !NM_IS_SETTING_CONNECTION(settings[0])) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("setting not found")); + g_prefix_error(error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME); + return NM_SETTING_VERIFY_ERROR; + } + + for (i = 0; settings[i]; i++) { + GError * verify_error = NULL; + NMSettingVerifyResult verify_result; + + nm_assert(NM_IS_SETTING(settings[i])); + nm_assert(NM_IS_SETTING_CONNECTION(settings[i]) == (i == 0)); + + /* verify all settings. We stop if we find the first non-normalizable + * @NM_SETTING_VERIFY_ERROR. If we find normalizable errors we continue + * but remember the error to return it to the user. + * @NM_SETTING_VERIFY_NORMALIZABLE_ERROR has a higher priority then + * @NM_SETTING_VERIFY_NORMALIZABLE, so, if we encounter such an error type, + * we remember it instead (to return it as output). + **/ + verify_result = _nm_setting_verify(settings[i], connection, &verify_error); + if (verify_result == NM_SETTING_VERIFY_NORMALIZABLE + || verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR) { + if (verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR + && normalizable_error_type == NM_SETTING_VERIFY_NORMALIZABLE) { + /* NORMALIZABLE_ERROR has higher priority. */ + g_clear_error(&normalizable_error); + } + if (!normalizable_error) { + g_propagate_error(&normalizable_error, verify_error); + verify_error = NULL; + normalizable_error_type = verify_result; + } + } else if (verify_result != NM_SETTING_VERIFY_SUCCESS) { + g_propagate_error(error, verify_error); + g_return_val_if_fail(verify_result == NM_SETTING_VERIFY_ERROR, NM_SETTING_VERIFY_ERROR); + return NM_SETTING_VERIFY_ERROR; + } + g_clear_error(&verify_error); + } + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + s_ip6 = nm_connection_get_setting_ip6_config(connection); + s_proxy = nm_connection_get_setting_proxy(connection); + + nm_assert(normalizable_error_type != NM_SETTING_VERIFY_ERROR); + if (NM_IN_SET(normalizable_error_type, + NM_SETTING_VERIFY_SUCCESS, + NM_SETTING_VERIFY_NORMALIZABLE)) { + if (_supports_addr_family(connection, AF_INET)) { + if (!s_ip4 && normalizable_error_type == NM_SETTING_VERIFY_SUCCESS) { + g_set_error_literal(&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("setting is required for non-slave connections")); + g_prefix_error(&normalizable_error, "%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* having a master without IP config was not a verify() error, accept + * it for backward compatibility. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE; + } + } else { + if (s_ip4) { + g_clear_error(&normalizable_error); + g_set_error_literal(&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("setting not allowed in slave connection")); + g_prefix_error(&normalizable_error, "%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME); + /* having a slave with IP config *was* and is a verify() error. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + } + + if (_supports_addr_family(connection, AF_INET6)) { + if (!s_ip6 && normalizable_error_type == NM_SETTING_VERIFY_SUCCESS) { + g_set_error_literal(&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("setting is required for non-slave connections")); + g_prefix_error(&normalizable_error, "%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME); + + /* having a master without IP config was not a verify() error, accept + * it for backward compatibility. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE; + } + } else { + if (s_ip6) { + g_clear_error(&normalizable_error); + g_set_error_literal(&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("setting not allowed in slave connection")); + g_prefix_error(&normalizable_error, "%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME); + /* having a slave with IP config *was* and is a verify() error. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + } + + if (_supports_addr_family(connection, AF_UNSPEC)) { + if (!s_proxy && normalizable_error_type == NM_SETTING_VERIFY_SUCCESS) { + g_set_error_literal(&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("setting is required for non-slave connections")); + g_prefix_error(&normalizable_error, "%s: ", NM_SETTING_PROXY_SETTING_NAME); + + /* having a master without proxy config was not a verify() error, accept + * it for backward compatibility. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE; + } + } else { + if (s_proxy) { + g_clear_error(&normalizable_error); + g_set_error_literal(&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("setting not allowed in slave connection")); + g_prefix_error(&normalizable_error, "%s: ", NM_SETTING_PROXY_SETTING_NAME); + /* having a slave with proxy config *was* and is a verify() error. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + } + } + + if (normalizable_error_type != NM_SETTING_VERIFY_SUCCESS) { + g_propagate_error(error, normalizable_error); + normalizable_error = NULL; + return normalizable_error_type; + } + + return NM_SETTING_VERIFY_SUCCESS; +} + +/** + * nm_connection_verify_secrets: + * @connection: the #NMConnection to verify in + * @error: location to store error, or %NULL + * + * Verifies the secrets in the connection. + * + * Returns: %TRUE if the secrets are valid, %FALSE if they are not + * + * Since: 1.2 + **/ +gboolean +nm_connection_verify_secrets(NMConnection *connection, GError **error) +{ + GHashTableIter iter; + NMSetting * setting; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + g_hash_table_iter_init(&iter, NM_CONNECTION_GET_PRIVATE(connection)->settings); + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &setting)) { + if (!nm_setting_verify_secrets(setting, connection, error)) + return FALSE; + } + return TRUE; +} + +static gboolean +_connection_normalize(NMConnection *connection, + GHashTable * parameters, + gboolean * modified, + GError ** error) +{ + NMSettingVerifyResult success; + gboolean was_modified; + +#if NM_MORE_ASSERTS > 10 + /* only call this _nm_connection_verify() confirms that the connection + * requires normalization and is normalizable. */ + nm_assert(NM_IN_SET(_nm_connection_verify(connection, NULL), + NM_SETTING_VERIFY_NORMALIZABLE, + NM_SETTING_VERIFY_NORMALIZABLE_ERROR)); +#endif + + /* Try to perform all kind of normalizations on the settings to fix it. + * We only do this, after verifying that the connection contains no un-normalizable + * errors, because in that case we rather fail without touching the settings. */ + + was_modified = FALSE; + + was_modified |= _normalize_connection_uuid(connection); + was_modified |= _normalize_connection_type(connection); + was_modified |= _normalize_connection_slave_type(connection); + was_modified |= _normalize_required_settings(connection); + was_modified |= _normalize_invalid_slave_port_settings(connection); + was_modified |= _normalize_ip_config(connection, parameters); + was_modified |= _normalize_ethernet_link_neg(connection); + was_modified |= _normalize_infiniband_mtu(connection); + was_modified |= _normalize_bond_mode(connection); + was_modified |= _normalize_bond_options(connection); + was_modified |= _normalize_wireless_mac_address_randomization(connection); + was_modified |= _normalize_macsec(connection); + was_modified |= _normalize_team_config(connection); + was_modified |= _normalize_team_port_config(connection); + was_modified |= _normalize_bluetooth_type(connection); + was_modified |= _normalize_ovs_interface_type(connection); + was_modified |= _normalize_ip_tunnel_wired_setting(connection); + was_modified |= _normalize_sriov_vf_order(connection); + was_modified |= _normalize_bridge_vlan_order(connection); + was_modified |= _normalize_bridge_port_vlan_order(connection); + was_modified |= _normalize_gsm_auto_config(connection); + + was_modified = !!was_modified; + + /* Verify anew */ + success = _nm_connection_verify(connection, error); + + NM_SET_OUT(modified, was_modified); + + if (success != NM_SETTING_VERIFY_SUCCESS) { + /* we would expect, that after normalization, the connection can be verified. + * Also treat NM_SETTING_VERIFY_NORMALIZABLE as failure, because there is something + * odd going on. */ + if (error && !*error) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Unexpected failure to normalize the connection")); + } + g_warning("connection did not verify after normalization: %s", + error ? (*error)->message : "??"); + g_return_val_if_reached(FALSE); + } + + /* we would expect, that the connection was modified during normalization. */ + g_return_val_if_fail(was_modified, TRUE); + + return TRUE; +} + +/** + * nm_connection_normalize: + * @connection: the #NMConnection to normalize + * @parameters: (allow-none) (element-type utf8 gpointer): a #GHashTable with + * normalization parameters to allow customization of the normalization by providing + * specific arguments. Unknown arguments will be ignored and the default will be + * used. The keys must be strings compared with g_str_equal() function. + * The values are opaque and depend on the parameter name. + * @modified: (out) (allow-none): outputs whether any settings were modified. + * @error: location to store error, or %NULL. Contains the reason, + * why the connection is invalid, if the function returns an error. + * + * Does some basic normalization and fixup of well known inconsistencies + * and deprecated fields. If the connection was modified in any way, + * the output parameter @modified is set %TRUE. + * + * Finally the connection will be verified and %TRUE returns if the connection + * is valid. As this function only performs some specific normalization steps + * it cannot repair all connections. If the connection has errors that + * cannot be normalized, the connection will not be modified. + * + * Returns: %TRUE if the connection is valid, %FALSE if it is not + **/ +gboolean +nm_connection_normalize(NMConnection *connection, + GHashTable * parameters, + gboolean * modified, + GError ** error) +{ + NMSettingVerifyResult success; + gs_free_error GError *normalizable_error = NULL; + + success = _nm_connection_verify(connection, &normalizable_error); + + if (!NM_IN_SET(success, NM_SETTING_VERIFY_NORMALIZABLE, NM_SETTING_VERIFY_NORMALIZABLE_ERROR)) { + if (normalizable_error) { + nm_assert(success == NM_SETTING_VERIFY_ERROR); + g_propagate_error(error, g_steal_pointer(&normalizable_error)); + } else + nm_assert(success == NM_SETTING_VERIFY_SUCCESS); + + NM_SET_OUT(modified, FALSE); + + if (success != NM_SETTING_VERIFY_SUCCESS) { + if (error && !*error) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Unexpected failure to verify the connection")); + return FALSE; + } + return FALSE; + } + + if (error && *error) + return FALSE; + return TRUE; + } + + return _connection_normalize(connection, parameters, modified, error); +} + +gboolean +_nm_connection_ensure_normalized(NMConnection * connection, + gboolean allow_modify, + const char * expected_uuid, + gboolean coerce_uuid, + NMConnection **out_connection_clone, + GError ** error) +{ + gs_unref_object NMConnection *connection_clone = NULL; + gs_free_error GError *local = NULL; + NMSettingVerifyResult vresult; + + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(!out_connection_clone || !*out_connection_clone); + nm_assert(!expected_uuid || nm_utils_is_uuid(expected_uuid)); + + if (expected_uuid) { + if (nm_streq0(expected_uuid, nm_connection_get_uuid(connection))) + expected_uuid = NULL; + else if (!coerce_uuid || (!allow_modify && !out_connection_clone)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unexpected uuid %s instead of %s"), + nm_connection_get_uuid(connection), + expected_uuid); + return FALSE; + } + } + + vresult = _nm_connection_verify(connection, &local); + if (vresult != NM_SETTING_VERIFY_SUCCESS) { + if (!NM_IN_SET(vresult, + NM_SETTING_VERIFY_NORMALIZABLE, + NM_SETTING_VERIFY_NORMALIZABLE_ERROR)) { + g_propagate_error(error, g_steal_pointer(&local)); + return FALSE; + } + if (!allow_modify) { + if (!out_connection_clone) { + /* even NM_SETTING_VERIFY_NORMALIZABLE is treated as an error. We could normalize, + * but are not allowed to (and no out argument is provided for cloning). */ + g_propagate_error(error, g_steal_pointer(&local)); + return FALSE; + } + connection_clone = nm_simple_connection_new_clone(connection); + connection = connection_clone; + } + if (!_connection_normalize(connection, NULL, NULL, error)) + g_return_val_if_reached(FALSE); + } + + if (expected_uuid) { + NMSettingConnection *s_con; + + if (!allow_modify && !connection_clone) { + nm_assert(out_connection_clone); + connection_clone = nm_simple_connection_new_clone(connection); + connection = connection_clone; + } + s_con = nm_connection_get_setting_connection(connection); + g_object_set(s_con, NM_SETTING_CONNECTION_UUID, expected_uuid, NULL); + } + + NM_SET_OUT(out_connection_clone, g_steal_pointer(&connection_clone)); + return TRUE; +} + +/*****************************************************************************/ + +#if NM_MORE_ASSERTS +static void +_nmtst_connection_unchanging_changed_cb(NMConnection *connection, gpointer user_data) +{ + nm_assert_not_reached(); +} + +static void +_nmtst_connection_unchanging_secrets_updated_cb(NMConnection *connection, + const char * setting_name, + gpointer user_data) +{ + nm_assert_not_reached(); +} + +const char _nmtst_connection_unchanging_user_data = 0; + +void +nmtst_connection_assert_unchanging(NMConnection *connection) +{ + if (!connection) + return; + + nm_assert(NM_IS_CONNECTION(connection)); + + if (g_signal_handler_find(connection, + G_SIGNAL_MATCH_DATA, + 0, + 0, + NULL, + NULL, + (gpointer) &_nmtst_connection_unchanging_user_data) + != 0) { + /* avoid connecting the assertion handler multiple times. */ + return; + } + + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + G_CALLBACK(_nmtst_connection_unchanging_changed_cb), + (gpointer) &_nmtst_connection_unchanging_user_data); + g_signal_connect(connection, + NM_CONNECTION_SECRETS_CLEARED, + G_CALLBACK(_nmtst_connection_unchanging_changed_cb), + (gpointer) &_nmtst_connection_unchanging_user_data); + g_signal_connect(connection, + NM_CONNECTION_SECRETS_UPDATED, + G_CALLBACK(_nmtst_connection_unchanging_secrets_updated_cb), + (gpointer) &_nmtst_connection_unchanging_user_data); +} +#endif + +/*****************************************************************************/ + +/** + * nm_connection_update_secrets: + * @connection: the #NMConnection + * @setting_name: the setting object name to which the secrets apply + * @secrets: a #GVariant of secrets, of type %NM_VARIANT_TYPE_CONNECTION + * or %NM_VARIANT_TYPE_SETTING + * @error: location to store error, or %NULL + * + * Update the specified setting's secrets, given a dictionary of secrets + * intended for that setting (deserialized from D-Bus for example). Will also + * extract the given setting's secrets hash if given a connection dictionary. + * If @setting_name is %NULL, expects a fully serialized #NMConnection as + * returned by nm_connection_to_dbus() and will update all secrets from all + * settings contained in @secrets. + * + * Returns: %TRUE if the secrets were successfully updated, %FALSE if the update + * failed (tried to update secrets for a setting that doesn't exist, etc) + **/ +gboolean +nm_connection_update_secrets(NMConnection *connection, + const char * setting_name, + GVariant * secrets, + GError ** error) +{ + NMSetting * setting; + gboolean success = TRUE; + gboolean updated = FALSE; + GVariant * setting_dict = NULL; + GVariantIter iter; + const char * key; + gboolean full_connection; + int success_detail; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + + full_connection = g_variant_is_of_type(secrets, NM_VARIANT_TYPE_CONNECTION); + + g_return_val_if_fail(full_connection || g_variant_is_of_type(secrets, NM_VARIANT_TYPE_SETTING), + FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + g_return_val_if_fail(setting_name || full_connection, FALSE); + + /* Empty @secrets means success */ + if (g_variant_n_children(secrets) == 0) + return TRUE; + + if (setting_name) { + /* Update just one setting's secrets */ + setting = nm_connection_get_setting_by_name(connection, setting_name); + if (!setting) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + setting_name); + return FALSE; + } + + if (full_connection) { + setting_dict = g_variant_lookup_value(secrets, setting_name, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) { + /* The connection dictionary didn't contain any secrets for + * @setting_name; just return success. + */ + return TRUE; + } + } + + g_signal_handlers_block_by_func(setting, (GCallback) setting_changed_cb, connection); + success_detail = _nm_setting_update_secrets(setting, setting_dict ?: secrets, error); + g_signal_handlers_unblock_by_func(setting, (GCallback) setting_changed_cb, connection); + + nm_clear_pointer(&setting_dict, g_variant_unref); + + if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) { + nm_assert(!error || *error); + return FALSE; + } + if (success_detail == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED) + updated = TRUE; + } else { + /* check first, whether all the settings exist... */ + g_variant_iter_init(&iter, secrets); + while (g_variant_iter_next(&iter, "{&s@a{sv}}", &key, NULL)) { + setting = nm_connection_get_setting_by_name(connection, key); + if (!setting) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + key); + return FALSE; + } + } + + /* Update each setting with any secrets from the connection dictionary */ + g_variant_iter_init(&iter, secrets); + while (g_variant_iter_next(&iter, "{&s@a{sv}}", &key, &setting_dict)) { + gs_free_error GError *local = NULL; + + /* Update the secrets for this setting */ + setting = nm_connection_get_setting_by_name(connection, key); + + g_signal_handlers_block_by_func(setting, (GCallback) setting_changed_cb, connection); + success_detail = + _nm_setting_update_secrets(setting, setting_dict, error ? &local : NULL); + g_signal_handlers_unblock_by_func(setting, (GCallback) setting_changed_cb, connection); + + g_variant_unref(setting_dict); + + if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) { + if (success) { + if (error) { + nm_assert(local); + g_propagate_error(error, g_steal_pointer(&local)); + error = NULL; + } else + nm_assert(!local); + success = FALSE; + } + break; + } + if (success_detail == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED) + updated = TRUE; + } + } + + if (updated) + g_signal_emit(connection, signals[SECRETS_UPDATED], 0, setting_name); + + return success; +} + +/** + * nm_connection_need_secrets: + * @connection: the #NMConnection + * @hints: (out) (element-type utf8) (allow-none) (transfer container): + * the address of a pointer to a #GPtrArray, initialized to %NULL, which on + * return points to an allocated #GPtrArray containing the property names of + * secrets of the #NMSetting which may be required; the caller owns the array + * and must free the array itself with g_ptr_array_free(), but not free its + * elements + * + * Returns the name of the first setting object in the connection which would + * need secrets to make a successful connection. The returned hints are only + * intended as a guide to what secrets may be required, because in some + * circumstances, there is no way to conclusively determine exactly which + * secrets are needed. + * + * Returns: the setting name of the #NMSetting object which has invalid or + * missing secrets + **/ +const char * +nm_connection_need_secrets(NMConnection *connection, GPtrArray **hints) +{ + NMConnectionPrivate *priv; + GHashTableIter hiter; + GSList * settings = NULL; + GSList * iter; + const char * name = NULL; + NMSetting * setting; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + if (hints) + g_return_val_if_fail(*hints == NULL, NULL); + + priv = NM_CONNECTION_GET_PRIVATE(connection); + + /* Get list of settings in priority order */ + g_hash_table_iter_init(&hiter, priv->settings); + while (g_hash_table_iter_next(&hiter, NULL, (gpointer) &setting)) + settings = g_slist_insert_sorted(settings, setting, _nm_setting_compare_priority); + + for (iter = settings; iter; iter = g_slist_next(iter)) { + GPtrArray *secrets; + + setting = NM_SETTING(iter->data); + secrets = _nm_setting_need_secrets(setting); + if (secrets) { + if (hints) + *hints = secrets; + else + g_ptr_array_free(secrets, TRUE); + + name = nm_setting_get_name(setting); + break; + } + } + + g_slist_free(settings); + return name; +} + +/** + * nm_connection_clear_secrets: + * @connection: the #NMConnection + * + * Clears and frees any secrets that may be stored in the connection, to avoid + * keeping secret data in memory when not needed. + **/ +void +nm_connection_clear_secrets(NMConnection *connection) +{ + return nm_connection_clear_secrets_with_flags(connection, NULL, NULL); +} + +/** + * nm_connection_clear_secrets_with_flags: + * @connection: the #NMConnection + * @func: (scope call) (allow-none): function to be called to determine whether a + * specific secret should be cleared or not. If %NULL, all secrets are cleared. + * @user_data: caller-supplied data passed to @func + * + * Clears and frees secrets determined by @func. + **/ +void +nm_connection_clear_secrets_with_flags(NMConnection * connection, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) +{ + GHashTableIter iter; + NMSetting * setting; + + g_return_if_fail(NM_IS_CONNECTION(connection)); + + g_hash_table_iter_init(&iter, NM_CONNECTION_GET_PRIVATE(connection)->settings); + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &setting)) { + g_signal_handlers_block_by_func(setting, (GCallback) setting_changed_cb, connection); + _nm_setting_clear_secrets(setting, func, user_data); + g_signal_handlers_unblock_by_func(setting, (GCallback) setting_changed_cb, connection); + } + + g_signal_emit(connection, signals[SECRETS_CLEARED], 0); +} + +static gboolean +_clear_secrets_by_secret_flags_cb(NMSetting * setting, + const char * secret, + NMSettingSecretFlags flags, + gpointer user_data) +{ + NMSettingSecretFlags filter_flags = GPOINTER_TO_UINT(user_data); + gboolean remove_secret; + + if (filter_flags == NM_SETTING_SECRET_FLAG_NONE) { + /* Can't use bitops with SECRET_FLAG_NONE so handle that specifically */ + remove_secret = (flags != NM_SETTING_SECRET_FLAG_NONE); + } else { + /* Otherwise, if the secret has at least one of the desired flags keep it */ + remove_secret = !NM_FLAGS_ANY(flags, filter_flags); + } + + return remove_secret; +} + +/** + * _nm_connection_clear_secrets_by_secret_flags: + * @self: the #NMConnection to filter (will be modified) + * @filter_flags: the secret flags to control whether to drop/remove + * a secret or to keep it. The meaning of the filter flags is to + * preserve the secrets. The secrets that have matching (see below) + * flags are kept, the others are dropped. + * + * Removes/drops secrets from @self according to @filter_flags. + * If @filter_flags is %NM_SETTING_SECRET_NONE, then only secrets that + * have %NM_SETTING_SECRET_NONE flags are kept. + * Otherwise, only secrets with secret flags are kept that have at least + * one of the filter flags. + */ +void +_nm_connection_clear_secrets_by_secret_flags(NMConnection *self, NMSettingSecretFlags filter_flags) +{ + nm_connection_clear_secrets_with_flags(self, + _clear_secrets_by_secret_flags_cb, + GUINT_TO_POINTER(filter_flags)); +} + +/*****************************************************************************/ + +/*****************************************************************************/ + +/* Returns always a non-NULL, floating variant that must + * be unrefed by the caller. */ +GVariant * +_nm_connection_for_each_secret(NMConnection * self, + GVariant * secrets, + gboolean remove_non_secrets, + _NMConnectionForEachSecretFunc callback, + gpointer callback_data) +{ + GVariantBuilder secrets_builder; + GVariantBuilder setting_builder; + GVariantIter secrets_iter; + GVariantIter * setting_iter; + const char * setting_name; + + /* This function, given a dict of dicts representing new secrets of + * an NMConnection, walks through each toplevel dict (which represents a + * NMSetting), and for each setting, walks through that setting dict's + * properties. For each property that's a secret, it will check that + * secret's flags in the backing NMConnection object, and call a supplied + * callback. + * + * The one complexity is that the VPN setting's 'secrets' property is + * *also* a dict (since the key/value pairs are arbitrary and known + * only to the VPN plugin itself). That means we have three levels of + * dicts that we potentially have to traverse here. The differences + * are handled by the virtual for_each_secret() function. + */ + + g_return_val_if_fail(callback, NULL); + + g_variant_iter_init(&secrets_iter, secrets); + g_variant_builder_init(&secrets_builder, NM_VARIANT_TYPE_CONNECTION); + while (g_variant_iter_next(&secrets_iter, "{&sa{sv}}", &setting_name, &setting_iter)) { + _nm_unused nm_auto_free_variant_iter GVariantIter *setting_iter_free = setting_iter; + NMSetting * setting; + const char * secret_name; + GVariant * val; + + setting = nm_connection_get_setting_by_name(self, setting_name); + if (!setting) + continue; + + g_variant_builder_init(&setting_builder, NM_VARIANT_TYPE_SETTING); + while (g_variant_iter_next(setting_iter, "{&sv}", &secret_name, &val)) { + _nm_unused gs_unref_variant GVariant *val_free = val; + + NM_SETTING_GET_CLASS(setting)->for_each_secret(setting, + secret_name, + val, + remove_non_secrets, + callback, + callback_data, + &setting_builder); + } + + g_variant_builder_add(&secrets_builder, "{sa{sv}}", setting_name, &setting_builder); + } + + return g_variant_builder_end(&secrets_builder); +} + +/*****************************************************************************/ + +typedef struct { + NMConnectionFindSecretFunc find_func; + gpointer find_func_data; + gboolean found; +} FindSecretData; + +static gboolean +find_secret_for_each_func(NMSettingSecretFlags flags, gpointer user_data) +{ + FindSecretData *data = user_data; + + if (!data->found) + data->found = data->find_func(flags, data->find_func_data); + return FALSE; +} + +gboolean +_nm_connection_find_secret(NMConnection * self, + GVariant * secrets, + NMConnectionFindSecretFunc callback, + gpointer callback_data) +{ + gs_unref_variant GVariant *dummy = NULL; + FindSecretData data = { + .find_func = callback, + .find_func_data = callback_data, + .found = FALSE, + }; + + dummy = _nm_connection_for_each_secret(self, secrets, FALSE, find_secret_for_each_func, &data); + return data.found; +} + +/*****************************************************************************/ + +/** + * nm_connection_to_dbus: + * @connection: the #NMConnection + * @flags: serialization flags, e.g. %NM_CONNECTION_SERIALIZE_ALL + * + * Converts the #NMConnection into a #GVariant of type + * %NM_VARIANT_TYPE_CONNECTION describing the connection, suitable for + * marshalling over D-Bus or otherwise serializing. + * + * Returns: (transfer none): a new floating #GVariant describing the connection, + * its settings, and each setting's properties. + **/ +GVariant * +nm_connection_to_dbus(NMConnection *connection, NMConnectionSerializationFlags flags) +{ + return nm_connection_to_dbus_full(connection, flags, NULL); +} + +GVariant * +nm_connection_to_dbus_full(NMConnection * connection, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + GVariantBuilder builder; + gboolean any = FALSE; + gs_free NMSetting **settings = NULL; + guint settings_len = 0; + guint i; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + + settings = nm_connection_get_settings(connection, &settings_len); + for (i = 0; i < settings_len; i++) { + NMSetting *setting = settings[i]; + GVariant * setting_dict; + + setting_dict = _nm_setting_to_dbus(setting, connection, flags, options); + if (!setting_dict) + continue; + if (!any) { + any = TRUE; + g_variant_builder_init(&builder, NM_VARIANT_TYPE_CONNECTION); + } + g_variant_builder_add(&builder, "{s@a{sv}}", nm_setting_get_name(setting), setting_dict); + } + + if (!any) + return NULL; + + return g_variant_builder_end(&builder); +} + +/** + * nm_connection_is_type: + * @connection: the #NMConnection + * @type: a setting name to check the connection's type against (like + * %NM_SETTING_WIRELESS_SETTING_NAME or %NM_SETTING_WIRED_SETTING_NAME) + * + * A convenience function to check if the given @connection is a particular + * type (ie wired, Wi-Fi, ppp, etc). Checks the #NMSettingConnection:type + * property of the connection and matches that against @type. + * + * Returns: %TRUE if the connection is of the given @type, %FALSE if not + **/ +gboolean +nm_connection_is_type(NMConnection *connection, const char *type) +{ + g_return_val_if_fail(type, FALSE); + + return nm_streq0(type, nm_connection_get_connection_type(connection)); +} + +static int +_get_settings_sort(gconstpointer p_a, gconstpointer p_b, gpointer unused) +{ + NMSetting *a = *((NMSetting **) p_a); + NMSetting *b = *((NMSetting **) p_b); + + nm_assert(NM_IS_SETTING(a)); + nm_assert(NM_IS_SETTING(b)); + nm_assert(a != b); + nm_assert(G_OBJECT_TYPE(a) != G_OBJECT_TYPE(b)); + + NM_CMP_RETURN(_nm_setting_compare_priority(a, b)); + NM_CMP_DIRECT_STRCMP(nm_setting_get_name(a), nm_setting_get_name(b)); + + nm_assert_not_reached(); + return 0; +} + +/** + * nm_connection_get_settings: + * @connection: the #NMConnection instance + * @out_length: (allow-none) (out): the length of the returned array + * + * Retrieves the settings in @connection. + * + * The returned array is %NULL-terminated. + * + * Returns: (array length=out_length) (transfer container): a + * %NULL-terminated array containing every setting of + * @connection. + * If the connection has no settings, %NULL is returned. + * + * Since: 1.10 + */ +NMSetting ** +nm_connection_get_settings(NMConnection *connection, guint *out_length) +{ + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + + return (NMSetting **) nm_utils_hash_values_to_array( + NM_CONNECTION_GET_PRIVATE(connection)->settings, + _get_settings_sort, + NULL, + out_length); +} + +/** + * nm_connection_for_each_setting_value: + * @connection: the #NMConnection + * @func: (scope call): user-supplied function called for each setting's property + * @user_data: user data passed to @func at each invocation + * + * Iterates over the properties of each #NMSetting object in the #NMConnection, + * calling the supplied user function for each property. + **/ +void +nm_connection_for_each_setting_value(NMConnection * connection, + NMSettingValueIterFn func, + gpointer user_data) +{ + gs_free NMSetting **settings = NULL; + guint i, length = 0; + + g_return_if_fail(NM_IS_CONNECTION(connection)); + g_return_if_fail(func); + + settings = nm_connection_get_settings(connection, &length); + for (i = 0; i < length; i++) + nm_setting_enumerate_values(settings[i], func, user_data); +} + +/** + * _nm_connection_aggregate: + * @connection: the #NMConnection for which values are to be aggregated. + * @type: one of the supported aggregate types. + * @arg: the input/output argument that depends on @type. + * + * For example, with %NM_CONNECTION_AGGREGATE_ANY_SECRETS and + * %NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS @arg is a boolean + * output argument. It is either %NULL or a pointer to an gboolean + * out-argument. The function will always set @arg if given. + * Also, the return value of the function is likewise the result + * that is set to @arg. + * + * Returns: a boolean result with the meaning depending on the aggregation + * type @type. + */ +gboolean +_nm_connection_aggregate(NMConnection *connection, NMConnectionAggregateType type, gpointer arg) +{ + NMConnectionPrivate *priv; + GHashTableIter iter; + NMSetting * setting; + gboolean arg_boolean; + gboolean completed_early; + gpointer my_arg; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + + switch (type) { + case NM_CONNECTION_AGGREGATE_ANY_SECRETS: + arg_boolean = FALSE; + my_arg = &arg_boolean; + goto good; + case NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS: + arg_boolean = FALSE; + my_arg = &arg_boolean; + goto good; + } + g_return_val_if_reached(FALSE); + +good: + priv = NM_CONNECTION_GET_PRIVATE(connection); + + completed_early = FALSE; + g_hash_table_iter_init(&iter, priv->settings); + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &setting)) { + if (_nm_setting_aggregate(setting, type, my_arg)) { + completed_early = TRUE; + break; + } + nm_assert(my_arg != &arg_boolean || !arg_boolean); + } + + if (my_arg == &arg_boolean) { + nm_assert(completed_early == arg_boolean); + if (arg) + *((gboolean *) arg) = arg_boolean; + return arg_boolean; + } + + nm_assert_not_reached(); + return FALSE; +} + +/** + * nm_connection_dump: + * @connection: the #NMConnection + * + * Print the connection (including secrets!) to stdout. For debugging + * purposes ONLY, should NOT be used for serialization of the setting, + * or machine-parsed in any way. The output format is not guaranteed to + * be stable and may change at any time. + **/ +void +nm_connection_dump(NMConnection *connection) +{ + GHashTableIter iter; + NMSetting * setting; + char * str; + + if (!connection) + return; + + g_hash_table_iter_init(&iter, NM_CONNECTION_GET_PRIVATE(connection)->settings); + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &setting)) { + str = nm_setting_to_string(setting); + g_print("%s\n", str); + g_free(str); + } +} + +/** + * nm_connection_set_path: + * @connection: the #NMConnection + * @path: the D-Bus path of the connection as given by the settings service + * which provides the connection + * + * Sets the D-Bus path of the connection. This property is not serialized, and + * is only for the reference of the caller. Sets the #NMConnection:path + * property. + **/ +void +nm_connection_set_path(NMConnection *connection, const char *path) +{ + NMConnectionPrivate *priv; + + g_return_if_fail(NM_IS_CONNECTION(connection)); + + priv = NM_CONNECTION_GET_PRIVATE(connection); + + g_free(priv->path); + priv->path = g_strdup(path); +} + +/** + * nm_connection_get_path: + * @connection: the #NMConnection + * + * Returns the connection's D-Bus path. + * + * Returns: the D-Bus path of the connection, previously set by a call to + * nm_connection_set_path(). + **/ +const char * +nm_connection_get_path(NMConnection *connection) +{ + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + + return NM_CONNECTION_GET_PRIVATE(connection)->path; +} + +/** + * nm_connection_get_interface_name: + * @connection: The #NMConnection + * + * Returns the interface name as stored in NMSettingConnection:interface_name. + * If the connection contains no NMSettingConnection, it will return %NULL. + * + * For hardware devices and software devices created outside of NetworkManager, + * this name is used to match the device. for software devices created by + * NetworkManager, this is the name of the created interface. + * + * Returns: Name of the kernel interface or %NULL + */ +const char * +nm_connection_get_interface_name(NMConnection *connection) +{ + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection(connection); + return s_con ? nm_setting_connection_get_interface_name(s_con) : NULL; +} + +NMConnectionMultiConnect +_nm_connection_get_multi_connect(NMConnection *connection) +{ + NMSettingConnection * s_con; + NMConnectionMultiConnect multi_connect; + const NMConnectionMultiConnect DEFAULT = NM_CONNECTION_MULTI_CONNECT_SINGLE; + + /* connection.multi_connect property cannot be specified via regular + * connection defaults in NetworkManager.conf, because those are per-device, + * and we need to determine the multi_connect independent of a particular + * device. + * + * There is however still a default-value, so theoretically, the default + * value could be specified in NetworkManager.conf. Just not as [connection*] + * and indepdented of a device. */ + + s_con = nm_connection_get_setting_connection(connection); + if (!s_con) + return DEFAULT; + + multi_connect = nm_setting_connection_get_multi_connect(s_con); + return multi_connect == NM_CONNECTION_MULTI_CONNECT_DEFAULT ? DEFAULT : multi_connect; +} + +gboolean +_nm_connection_verify_required_interface_name(NMConnection *connection, GError **error) +{ + const char *interface_name; + + if (!connection) + return TRUE; + + interface_name = nm_connection_get_interface_name(connection); + if (interface_name) + return TRUE; + + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME); + return FALSE; +} + +/** + * nm_connection_get_uuid: + * @connection: the #NMConnection + * + * A shortcut to return the UUID from the connection's #NMSettingConnection. + * + * Returns: the UUID from the connection's 'connection' setting + **/ +const char * +nm_connection_get_uuid(NMConnection *connection) +{ + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection(connection); + return s_con ? nm_setting_connection_get_uuid(s_con) : NULL; +} + +/** + * nm_connection_get_id: + * @connection: the #NMConnection + * + * A shortcut to return the ID from the connection's #NMSettingConnection. + * + * Returns: the ID from the connection's 'connection' setting + **/ +const char * +nm_connection_get_id(NMConnection *connection) +{ + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection(connection); + return s_con ? nm_setting_connection_get_id(s_con) : NULL; +} + +/** + * nm_connection_get_connection_type: + * @connection: the #NMConnection + * + * A shortcut to return the type from the connection's #NMSettingConnection. + * + * Returns: the type from the connection's 'connection' setting + **/ +const char * +nm_connection_get_connection_type(NMConnection *connection) +{ + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection(connection); + return s_con ? nm_setting_connection_get_connection_type(s_con) : NULL; +} + +/** + * nm_connection_is_virtual: + * @connection: an #NMConnection + * + * Checks if @connection refers to a virtual device (and thus can potentially be + * activated even if the device it refers to doesn't exist). + * + * Returns: whether @connection refers to a virtual device + */ +gboolean +nm_connection_is_virtual(NMConnection *connection) +{ + const char *type; + + type = nm_connection_get_connection_type(connection); + if (!type) + return FALSE; + + if (NM_IN_STRSET(type, + NM_SETTING_6LOWPAN_SETTING_NAME, + NM_SETTING_BOND_SETTING_NAME, + NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_DUMMY_SETTING_NAME, + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_MACSEC_SETTING_NAME, + NM_SETTING_MACVLAN_SETTING_NAME, + NM_SETTING_OVS_BRIDGE_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_PORT_SETTING_NAME, + NM_SETTING_TEAM_SETTING_NAME, + NM_SETTING_TUN_SETTING_NAME, + NM_SETTING_VETH_SETTING_NAME, + NM_SETTING_VLAN_SETTING_NAME, + NM_SETTING_VRF_SETTING_NAME, + NM_SETTING_VXLAN_SETTING_NAME, + NM_SETTING_WIREGUARD_SETTING_NAME)) + return TRUE; + + if (nm_streq(type, NM_SETTING_INFINIBAND_SETTING_NAME)) { + NMSettingInfiniband *s_ib; + + s_ib = nm_connection_get_setting_infiniband(connection); + return s_ib && nm_setting_infiniband_get_virtual_interface_name(s_ib); + } + + if (nm_streq(type, NM_SETTING_BLUETOOTH_SETTING_NAME)) + return !!_nm_connection_get_setting_bluetooth_for_nap(connection); + + if (nm_streq(type, NM_SETTING_PPPOE_SETTING_NAME)) { + NMSettingPppoe *s_pppoe; + + s_pppoe = nm_connection_get_setting_pppoe(connection); + return !!nm_setting_pppoe_get_parent(s_pppoe); + } + + return FALSE; +} + +/** + * nm_connection_get_virtual_device_description: + * @connection: an #NMConnection for a virtual device type + * + * Returns the name that nm_device_disambiguate_names() would + * return for the virtual device that would be created for @connection. + * Eg, "VLAN (eth1.1)". + * + * Returns: (transfer full): the name of @connection's device, + * or %NULL if @connection is not a virtual connection type + */ +char * +nm_connection_get_virtual_device_description(NMConnection *connection) +{ + const char *type; + const char *iface = NULL, *display_type = NULL; + + type = nm_connection_get_connection_type(connection); + if (!type) + return NULL; + + iface = nm_connection_get_interface_name(connection); + + if (!strcmp(type, NM_SETTING_BOND_SETTING_NAME)) + display_type = _("Bond"); + else if (!strcmp(type, NM_SETTING_TEAM_SETTING_NAME)) + display_type = _("Team"); + else if (!strcmp(type, NM_SETTING_BRIDGE_SETTING_NAME)) + display_type = _("Bridge"); + else if (!strcmp(type, NM_SETTING_VLAN_SETTING_NAME)) + display_type = _("VLAN"); + else if (!strcmp(type, NM_SETTING_INFINIBAND_SETTING_NAME)) { + display_type = _("InfiniBand"); + iface = nm_setting_infiniband_get_virtual_interface_name( + nm_connection_get_setting_infiniband(connection)); + } else if (!strcmp(type, NM_SETTING_IP_TUNNEL_SETTING_NAME)) + display_type = _("IP Tunnel"); + + if (!iface || !display_type) + return NULL; + + return g_strdup_printf("%s (%s)", display_type, iface); +} + +/*****************************************************************************/ + +/** + * nm_connection_get_setting_802_1x: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSetting8021x the connection might contain. + * + * Returns: (transfer none): an #NMSetting8021x if the connection contains one, otherwise %NULL + **/ +NMSetting8021x * +nm_connection_get_setting_802_1x(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_802_1X); +} + +/** + * nm_connection_get_setting_bluetooth: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBluetooth the connection might contain. + * + * Returns: (transfer none): an #NMSettingBluetooth if the connection contains one, otherwise %NULL + **/ +NMSettingBluetooth * +nm_connection_get_setting_bluetooth(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_BLUETOOTH); +} + +/** + * nm_connection_get_setting_bond: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBond the connection might contain. + * + * Returns: (transfer none): an #NMSettingBond if the connection contains one, otherwise %NULL + **/ +NMSettingBond * +nm_connection_get_setting_bond(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_BOND); +} + +/** + * nm_connection_get_setting_team: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingTeam the connection might contain. + * + * Returns: (transfer none): an #NMSettingTeam if the connection contains one, otherwise %NULL + **/ +NMSettingTeam * +nm_connection_get_setting_team(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_TEAM); +} + +/** + * nm_connection_get_setting_team_port: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingTeamPort the connection might contain. + * + * Returns: (transfer none): an #NMSettingTeamPort if the connection contains one, otherwise %NULL + **/ +NMSettingTeamPort * +nm_connection_get_setting_team_port(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_TEAM_PORT); +} + +/** + * nm_connection_get_setting_bridge: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBridge the connection might contain. + * + * Returns: (transfer none): an #NMSettingBridge if the connection contains one, otherwise %NULL + **/ +NMSettingBridge * +nm_connection_get_setting_bridge(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_BRIDGE); +} + +/** + * nm_connection_get_setting_cdma: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingCdma the connection might contain. + * + * Returns: (transfer none): an #NMSettingCdma if the connection contains one, otherwise %NULL + **/ +NMSettingCdma * +nm_connection_get_setting_cdma(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_CDMA); +} + +/** + * nm_connection_get_setting_connection: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingConnection the connection might contain. + * + * Returns: (transfer none): an #NMSettingConnection if the connection contains one, otherwise %NULL + **/ +NMSettingConnection * +nm_connection_get_setting_connection(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_CONNECTION); +} + +/** + * nm_connection_get_setting_dcb: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingDcb the connection might contain. + * + * Returns: (transfer none): an #NMSettingDcb if the connection contains one, otherwise NULL + **/ +NMSettingDcb * +nm_connection_get_setting_dcb(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_DCB); +} + +/** + * nm_connection_get_setting_dummy: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingDummy the connection might contain. + * + * Returns: (transfer none): an #NMSettingDummy if the connection contains one, otherwise %NULL + * + * Since: 1.8 + **/ +NMSettingDummy * +nm_connection_get_setting_dummy(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_DUMMY); +} + +/** + * nm_connection_get_setting_generic: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingGeneric the connection might contain. + * + * Returns: (transfer none): an #NMSettingGeneric if the connection contains one, otherwise NULL + **/ +NMSettingGeneric * +nm_connection_get_setting_generic(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_GENERIC); +} + +/** + * nm_connection_get_setting_gsm: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingGsm the connection might contain. + * + * Returns: (transfer none): an #NMSettingGsm if the connection contains one, otherwise %NULL + **/ +NMSettingGsm * +nm_connection_get_setting_gsm(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_GSM); +} + +/** + * nm_connection_get_setting_infiniband: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingInfiniband the connection might contain. + * + * Returns: (transfer none): an #NMSettingInfiniband if the connection contains one, otherwise %NULL + **/ +NMSettingInfiniband * +nm_connection_get_setting_infiniband(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_INFINIBAND); +} + +/** + * nm_connection_get_setting_ip4_config: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingIP4Config the connection might contain. + * + * Note that it returns the value as type #NMSettingIPConfig, since the vast + * majority of IPv4-setting-related methods are on that type, not + * #NMSettingIP4Config. + * + * Returns: (type NMSettingIP4Config) (transfer none): an #NMSettingIP4Config if the + * connection contains one, otherwise %NULL + **/ +NMSettingIPConfig * +nm_connection_get_setting_ip4_config(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_IP4_CONFIG); +} + +/** + * nm_connection_get_setting_ip_tunnel: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingIPTunnel the connection might contain. + * + * Returns: (transfer none): an #NMSettingIPTunnel if the connection contains one, otherwise %NULL + * + * Since: 1.2 + **/ +NMSettingIPTunnel * +nm_connection_get_setting_ip_tunnel(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_IP_TUNNEL); +} + +/** + * nm_connection_get_setting_ip6_config: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingIP6Config the connection might contain. + * + * Note that it returns the value as type #NMSettingIPConfig, since the vast + * majority of IPv6-setting-related methods are on that type, not + * #NMSettingIP6Config. + * + * Returns: (type NMSettingIP6Config) (transfer none): an #NMSettingIP6Config if the + * connection contains one, otherwise %NULL + **/ +NMSettingIPConfig * +nm_connection_get_setting_ip6_config(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_IP6_CONFIG); +} + +/** + * nm_connection_get_setting_macsec: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingMacsec the connection might contain. + * + * Returns: (transfer none): an #NMSettingMacsec if the connection contains one, otherwise %NULL + * + * Since: 1.6 + **/ +NMSettingMacsec * +nm_connection_get_setting_macsec(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_MACSEC); +} + +/** + * nm_connection_get_setting_macvlan: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingMacvlan the connection might contain. + * + * Returns: (transfer none): an #NMSettingMacvlan if the connection contains one, otherwise %NULL + * + * Since: 1.2 + **/ +NMSettingMacvlan * +nm_connection_get_setting_macvlan(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_MACVLAN); +} + +/** + * nm_connection_get_setting_olpc_mesh: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingOlpcMesh the connection might contain. + * + * Returns: (transfer none): an #NMSettingOlpcMesh if the connection contains one, otherwise %NULL + **/ +NMSettingOlpcMesh * +nm_connection_get_setting_olpc_mesh(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_OLPC_MESH); +} + +/** + * nm_connection_get_setting_ovs_bridge: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingOvsBridge the connection might contain. + * + * Returns: (transfer none): an #NMSettingOvsBridge if the connection contains one, otherwise %NULL + * + * Since: 1.10 + **/ +NMSettingOvsBridge * +nm_connection_get_setting_ovs_bridge(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_OVS_BRIDGE); +} + +/** + * nm_connection_get_setting_ovs_interface: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingOvsInterface the connection might contain. + * + * Returns: (transfer none): an #NMSettingOvsInterface if the connection contains one, otherwise %NULL + * + * Since: 1.10 + **/ +NMSettingOvsInterface * +nm_connection_get_setting_ovs_interface(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_OVS_INTERFACE); +} + +/** + * nm_connection_get_setting_ovs_patch: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingOvsPatch the connection might contain. + * + * Returns: (transfer none): an #NMSettingOvsPatch if the connection contains one, otherwise %NULL + * + * Since: 1.10 + **/ +NMSettingOvsPatch * +nm_connection_get_setting_ovs_patch(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_OVS_PATCH); +} + +/** + * nm_connection_get_setting_ovs_port: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingOvsPort the connection might contain. + * + * Returns: (transfer none): an #NMSettingOvsPort if the connection contains one, otherwise %NULL + * + * Since: 1.10 + **/ +NMSettingOvsPort * +nm_connection_get_setting_ovs_port(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_OVS_PORT); +} + +/** + * nm_connection_get_setting_ppp: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingPpp the connection might contain. + * + * Returns: (transfer none): an #NMSettingPpp if the connection contains one, otherwise %NULL + **/ +NMSettingPpp * +nm_connection_get_setting_ppp(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_PPP); +} + +/** + * nm_connection_get_setting_pppoe: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingPppoe the connection might contain. + * + * Returns: (transfer none): an #NMSettingPppoe if the connection contains one, otherwise %NULL + **/ +NMSettingPppoe * +nm_connection_get_setting_pppoe(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_PPPOE); +} + +/** + * nm_connection_get_setting_proxy: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingProxy the connection might contain. + * + * Returns: (transfer none): an #NMSettingProxy if the connection contains one, otherwise %NULL + * + * Since: 1.6 + **/ +NMSettingProxy * +nm_connection_get_setting_proxy(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_PROXY); +} + +/** + * nm_connection_get_setting_serial: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingSerial the connection might contain. + * + * Returns: (transfer none): an #NMSettingSerial if the connection contains one, otherwise %NULL + **/ +NMSettingSerial * +nm_connection_get_setting_serial(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_SERIAL); +} + +/** + * nm_connection_get_setting_tc_config: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingTCConfig the connection might contain. + * + * Returns: (transfer none): an #NMSettingTCConfig if the connection contains one, otherwise %NULL + * + * Since: 1.12 + **/ +NMSettingTCConfig * +nm_connection_get_setting_tc_config(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_TC_CONFIG); +} + +/** + * nm_connection_get_setting_tun: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingTun the connection might contain. + * + * Returns: (transfer none): an #NMSettingTun if the connection contains one, otherwise %NULL + * + * Since: 1.2 + **/ +NMSettingTun * +nm_connection_get_setting_tun(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_TUN); +} + +/** + * nm_connection_get_setting_vpn: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingVpn the connection might contain. + * + * Returns: (transfer none): an #NMSettingVpn if the connection contains one, otherwise %NULL + **/ +NMSettingVpn * +nm_connection_get_setting_vpn(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_VPN); +} + +/** + * nm_connection_get_setting_vxlan: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingVxlan the connection might contain. + * + * Returns: (transfer none): an #NMSettingVxlan if the connection contains one, otherwise %NULL + * + * Since: 1.2 + **/ +NMSettingVxlan * +nm_connection_get_setting_vxlan(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_VXLAN); +} + +/** + * nm_connection_get_setting_wimax: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWimax the connection might contain. + * + * Returns: (transfer none): an #NMSettingWimax if the connection contains one, otherwise %NULL + **/ +NMSettingWimax * +nm_connection_get_setting_wimax(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_WIMAX); +} + +/** + * nm_connection_get_setting_wired: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWired the connection might contain. + * + * Returns: (transfer none): an #NMSettingWired if the connection contains one, otherwise %NULL + **/ +NMSettingWired * +nm_connection_get_setting_wired(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_WIRED); +} + +/** + * nm_connection_get_setting_adsl: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingAdsl the connection might contain. + * + * Returns: (transfer none): an #NMSettingAdsl if the connection contains one, otherwise %NULL + **/ +NMSettingAdsl * +nm_connection_get_setting_adsl(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_ADSL); +} + +/** + * nm_connection_get_setting_wireless: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWireless the connection might contain. + * + * Returns: (transfer none): an #NMSettingWireless if the connection contains one, otherwise %NULL + **/ +NMSettingWireless * +nm_connection_get_setting_wireless(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_WIRELESS); +} + +/** + * nm_connection_get_setting_wireless_security: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWirelessSecurity the connection might contain. + * + * Returns: (transfer none): an #NMSettingWirelessSecurity if the connection contains one, otherwise %NULL + **/ +NMSettingWirelessSecurity * +nm_connection_get_setting_wireless_security(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_WIRELESS_SECURITY); +} + +/** + * nm_connection_get_setting_bridge_port: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBridgePort the connection might contain. + * + * Returns: (transfer none): an #NMSettingBridgePort if the connection contains one, otherwise %NULL + **/ +NMSettingBridgePort * +nm_connection_get_setting_bridge_port(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_BRIDGE_PORT); +} + +/** + * nm_connection_get_setting_vlan: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingVlan the connection might contain. + * + * Returns: (transfer none): an #NMSettingVlan if the connection contains one, otherwise %NULL + **/ +NMSettingVlan * +nm_connection_get_setting_vlan(NMConnection *connection) +{ + return _connection_get_setting_check(connection, NM_TYPE_SETTING_VLAN); +} + +NMSettingBluetooth * +_nm_connection_get_setting_bluetooth_for_nap(NMConnection *connection) +{ + NMSettingBluetooth *s_bt = nm_connection_get_setting_bluetooth(connection); + + if (s_bt + && nm_streq0(nm_setting_bluetooth_get_connection_type(s_bt), NM_SETTING_BLUETOOTH_TYPE_NAP)) + return s_bt; + return NULL; +} + +/*****************************************************************************/ + +static void +nm_connection_private_free(NMConnectionPrivate *priv) +{ + NMConnection *self = priv->self; + + g_hash_table_foreach_remove(priv->settings, _setting_release_hfr, self); + g_hash_table_destroy(priv->settings); + g_free(priv->path); + + g_slice_free(NMConnectionPrivate, priv); +} + +static NMConnectionPrivate * +nm_connection_get_private(NMConnection *connection) +{ + GQuark key; + NMConnectionPrivate *priv; + + nm_assert(NM_IS_CONNECTION(connection)); + + key = NM_CACHED_QUARK("NMConnectionPrivate"); + + priv = g_object_get_qdata((GObject *) connection, key); + if (G_UNLIKELY(!priv)) { + priv = g_slice_new0(NMConnectionPrivate); + g_object_set_qdata_full((GObject *) connection, + key, + priv, + (GDestroyNotify) nm_connection_private_free); + + priv->self = connection; + priv->settings = g_hash_table_new_full(nm_direct_hash, NULL, NULL, g_object_unref); + } + + return priv; +} + +static void +nm_connection_default_init(NMConnectionInterface *iface) +{ + /** + * NMConnection::secrets-updated: + * @connection: the object on which the signal is emitted + * @setting_name: the setting name of the #NMSetting for which secrets were + * updated + * + * The ::secrets-updated signal is emitted when the secrets of a setting + * have been changed. + */ + signals[SECRETS_UPDATED] = g_signal_new(NM_CONNECTION_SECRETS_UPDATED, + NM_TYPE_CONNECTION, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMConnectionInterface, secrets_updated), + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + + /** + * NMConnection::secrets-cleared: + * @connection: the object on which the signal is emitted + * + * The ::secrets-cleared signal is emitted when the secrets of a connection + * are cleared. + */ + signals[SECRETS_CLEARED] = g_signal_new(NM_CONNECTION_SECRETS_CLEARED, + NM_TYPE_CONNECTION, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMConnectionInterface, secrets_cleared), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * NMConnection::changed: + * @connection: the object on which the signal is emitted + * + * The ::changed signal is emitted when any property of any property + * (including secrets) of any setting of the connection is modified, + * or when settings are added or removed. + */ + signals[CHANGED] = g_signal_new(NM_CONNECTION_CHANGED, + NM_TYPE_CONNECTION, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(NMConnectionInterface, changed), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} diff --git a/src/libnm-core-impl/nm-crypto-gnutls.c b/src/libnm-core-impl/nm-crypto-gnutls.c new file mode 100644 index 0000000..db4be8a --- /dev/null +++ b/src/libnm-core-impl/nm-crypto-gnutls.c @@ -0,0 +1,415 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Dan Williams + * Copyright (C) 2007 - 2015 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-crypto-impl.h" + +#include +#include +#include +#include + +#include "libnm-glib-aux/nm-secret-utils.h" +#include "nm-errors.h" + +/*****************************************************************************/ + +static gboolean +_get_cipher_info(NMCryptoCipherType cipher, int *out_cipher_mech, guint8 *out_real_iv_len) +{ + static const int cipher_mechs[] = { + [NM_CRYPTO_CIPHER_DES_EDE3_CBC] = GNUTLS_CIPHER_3DES_CBC, + [NM_CRYPTO_CIPHER_DES_CBC] = GNUTLS_CIPHER_DES_CBC, + [NM_CRYPTO_CIPHER_AES_128_CBC] = GNUTLS_CIPHER_AES_128_CBC, + [NM_CRYPTO_CIPHER_AES_192_CBC] = GNUTLS_CIPHER_AES_192_CBC, + [NM_CRYPTO_CIPHER_AES_256_CBC] = GNUTLS_CIPHER_AES_256_CBC, + }; + + g_return_val_if_fail(_NM_INT_NOT_NEGATIVE(cipher) + && (gsize) cipher < G_N_ELEMENTS(cipher_mechs), + FALSE); + + if (cipher_mechs[cipher] == 0) + return FALSE; + + NM_SET_OUT(out_cipher_mech, cipher_mechs[cipher]); + NM_SET_OUT(out_real_iv_len, nm_crypto_cipher_get_info(cipher)->real_iv_len); + return TRUE; +} + +/*****************************************************************************/ + +gboolean +_nm_crypto_init(GError **error) +{ + static gboolean initialized = FALSE; + + if (initialized) + return TRUE; + + if (gnutls_global_init() != 0) { + gnutls_global_deinit(); + g_set_error_literal(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Failed to initialize the crypto engine.")); + return FALSE; + } + + initialized = TRUE; + return TRUE; +} + +/*****************************************************************************/ + +guint8 * +_nmtst_crypto_decrypt(NMCryptoCipherType cipher, + const guint8 * data, + gsize data_len, + const guint8 * iv, + gsize iv_len, + const guint8 * key, + gsize key_len, + gsize * out_len, + GError ** error) +{ + gnutls_cipher_hd_t ctx; + gnutls_datum_t key_dt, iv_dt; + int err; + int cipher_mech; + nm_auto_clear_secret_ptr NMSecretPtr output = {0}; + guint8 pad_i, pad_len; + guint8 real_iv_len; + + if (!_get_cipher_info(cipher, &cipher_mech, &real_iv_len)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + _("Unsupported key cipher for decryption")); + return NULL; + } + + if (!_nm_crypto_init(error)) + return NULL; + + if (iv_len < real_iv_len) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Invalid IV length (must be at least %u)."), + (guint) real_iv_len); + return NULL; + } + + output.len = data_len; + output.bin = g_malloc(data_len); + + key_dt.data = (unsigned char *) key; + key_dt.size = key_len; + iv_dt.data = (unsigned char *) iv; + iv_dt.size = iv_len; + + err = gnutls_cipher_init(&ctx, cipher_mech, &key_dt, &iv_dt); + if (err < 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to initialize the decryption cipher context: %s (%s)"), + gnutls_strerror_name(err), + gnutls_strerror(err)); + return NULL; + } + + err = gnutls_cipher_decrypt2(ctx, data, data_len, output.bin, output.len); + + gnutls_cipher_deinit(ctx); + + if (err < 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key: %s (%s)"), + gnutls_strerror_name(err), + gnutls_strerror(err)); + return NULL; + } + + pad_len = output.len > 0 ? output.bin[output.len - 1] : 0; + + /* Check if the padding at the end of the decrypted data is valid */ + if (pad_len == 0 || pad_len > real_iv_len) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key: unexpected padding length.")); + return NULL; + } + + /* Validate tail padding; last byte is the padding size, and all pad bytes + * should contain the padding size. + */ + for (pad_i = 1; pad_i <= pad_len; ++pad_i) { + if (output.bin[data_len - pad_i] != pad_len) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key.")); + return NULL; + } + } + + *out_len = output.len - pad_len; + return g_steal_pointer(&output.bin); +} + +guint8 * +_nmtst_crypto_encrypt(NMCryptoCipherType cipher, + const guint8 * data, + gsize data_len, + const guint8 * iv, + gsize iv_len, + const guint8 * key, + gsize key_len, + gsize * out_len, + GError ** error) +{ + gnutls_cipher_hd_t ctx; + gnutls_datum_t key_dt, iv_dt; + int err; + int cipher_mech; + nm_auto_clear_secret_ptr NMSecretPtr output = {0}; + nm_auto_clear_secret_ptr NMSecretPtr padded_buf = {0}; + gsize i, pad_len; + + nm_assert(iv_len); + + if (cipher == NM_CRYPTO_CIPHER_DES_CBC || !_get_cipher_info(cipher, &cipher_mech, NULL)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + _("Unsupported key cipher for encryption")); + return NULL; + } + + if (!_nm_crypto_init(error)) + return NULL; + + key_dt.data = (unsigned char *) key; + key_dt.size = key_len; + iv_dt.data = (unsigned char *) iv; + iv_dt.size = iv_len; + + err = gnutls_cipher_init(&ctx, cipher_mech, &key_dt, &iv_dt); + if (err < 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to initialize the encryption cipher context: %s (%s)"), + gnutls_strerror_name(err), + gnutls_strerror(err)); + return NULL; + } + + /* If data_len % ivlen == 0, then we add another complete block + * onto the end so that the decrypter knows there's padding. + */ + pad_len = iv_len - (data_len % iv_len); + + padded_buf.len = data_len + pad_len; + padded_buf.bin = g_malloc(padded_buf.len); + memcpy(padded_buf.bin, data, data_len); + for (i = 0; i < pad_len; i++) + padded_buf.bin[data_len + i] = (guint8)(pad_len & 0xFF); + + output.len = padded_buf.len; + output.bin = g_malloc(output.len); + + err = gnutls_cipher_encrypt2(ctx, padded_buf.bin, padded_buf.len, output.bin, output.len); + + gnutls_cipher_deinit(ctx); + + if (err < 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to encrypt the data: %s (%s)"), + gnutls_strerror_name(err), + gnutls_strerror(err)); + return NULL; + } + + *out_len = output.len; + return g_steal_pointer(&output.bin); +} + +gboolean +_nm_crypto_verify_x509(const guint8 *data, gsize len, GError **error) +{ + gnutls_x509_crt_t der; + gnutls_datum_t dt; + int err; + + if (!_nm_crypto_init(error)) + return FALSE; + + err = gnutls_x509_crt_init(&der); + if (err < 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Error initializing certificate data: %s"), + gnutls_strerror(err)); + return FALSE; + } + + /* Try DER first */ + dt.data = (unsigned char *) data; + dt.size = len; + err = gnutls_x509_crt_import(der, &dt, GNUTLS_X509_FMT_DER); + if (err == GNUTLS_E_SUCCESS) { + gnutls_x509_crt_deinit(der); + return TRUE; + } + + /* And PEM next */ + err = gnutls_x509_crt_import(der, &dt, GNUTLS_X509_FMT_PEM); + gnutls_x509_crt_deinit(der); + if (err == GNUTLS_E_SUCCESS) + return TRUE; + + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Couldn't decode certificate: %s"), + gnutls_strerror(err)); + return FALSE; +} + +gboolean +_nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *password, GError **error) +{ + gnutls_pkcs12_t p12; + gnutls_datum_t dt; + int err; + + g_return_val_if_fail(data != NULL, FALSE); + + if (!_nm_crypto_init(error)) + return FALSE; + + dt.data = (unsigned char *) data; + dt.size = data_len; + + err = gnutls_pkcs12_init(&p12); + if (err < 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Couldn't initialize PKCS#12 decoder: %s"), + gnutls_strerror(err)); + return FALSE; + } + + /* DER first */ + err = gnutls_pkcs12_import(p12, &dt, GNUTLS_X509_FMT_DER, 0); + if (err < 0) { + /* PEM next */ + err = gnutls_pkcs12_import(p12, &dt, GNUTLS_X509_FMT_PEM, 0); + if (err < 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Couldn't decode PKCS#12 file: %s"), + gnutls_strerror(err)); + gnutls_pkcs12_deinit(p12); + return FALSE; + } + } + + err = gnutls_pkcs12_verify_mac(p12, password); + + gnutls_pkcs12_deinit(p12); + + if (err != GNUTLS_E_SUCCESS) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Couldn't verify PKCS#12 file: %s"), + gnutls_strerror(err)); + return FALSE; + } + + return TRUE; +} + +gboolean +_nm_crypto_verify_pkcs8(const guint8 *data, + gsize data_len, + gboolean is_encrypted, + const char * password, + GError ** error) +{ + gnutls_x509_privkey_t p8; + gnutls_datum_t dt; + int err; + + g_return_val_if_fail(data != NULL, FALSE); + + if (!_nm_crypto_init(error)) + return FALSE; + + err = gnutls_x509_privkey_init(&p8); + if (err < 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Couldn't initialize PKCS#8 decoder: %s"), + gnutls_strerror(err)); + return FALSE; + } + + dt.data = (unsigned char *) data; + dt.size = data_len; + + err = gnutls_x509_privkey_import_pkcs8(p8, + &dt, + GNUTLS_X509_FMT_DER, + is_encrypted ? password : NULL, + is_encrypted ? 0 : GNUTLS_PKCS_PLAIN); + + gnutls_x509_privkey_deinit(p8); + + if (err < 0) { + if (err == GNUTLS_E_UNKNOWN_CIPHER_TYPE) { + /* HACK: gnutls < 3.5.4 doesn't support all the cipher types that openssl + * can use with PKCS#8, so if we encounter one, we have to assume + * the given password works. gnutls needs to unsuckify, apparently. + * Specifically, by default openssl uses pbeWithMD5AndDES-CBC + * which gnutls does not support. + */ + } else { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Couldn't decode PKCS#8 file: %s"), + gnutls_strerror(err)); + return FALSE; + } + } + + return TRUE; +} + +gboolean +_nm_crypto_randomize(void *buffer, gsize buffer_len, GError **error) +{ + if (!_nm_crypto_init(error)) + return FALSE; + + gnutls_rnd(GNUTLS_RND_RANDOM, buffer, buffer_len); + return TRUE; +} diff --git a/src/libnm-core-impl/nm-crypto-impl.h b/src/libnm-core-impl/nm-crypto-impl.h new file mode 100644 index 0000000..0fd8f19 --- /dev/null +++ b/src/libnm-core-impl/nm-crypto-impl.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Dan Williams + * Copyright (C) 2007 - 2018 Red Hat, Inc. + */ + +#ifndef __NM_CRYPTO_IMPL_H__ +#define __NM_CRYPTO_IMPL_H__ + +#include "nm-crypto.h" + +gboolean _nm_crypto_init(GError **error); + +gboolean _nm_crypto_randomize(void *buffer, gsize buffer_len, GError **error); + +gboolean _nm_crypto_verify_x509(const guint8 *data, gsize len, GError **error); + +gboolean +_nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *password, GError **error); + +gboolean _nm_crypto_verify_pkcs8(const guint8 *data, + gsize data_len, + gboolean is_encrypted, + const char * password, + GError ** error); + +/*****************************************************************************/ + +guint8 *_nmtst_crypto_encrypt(NMCryptoCipherType cipher, + const guint8 * data, + gsize data_len, + const guint8 * iv, + gsize iv_len, + const guint8 * key, + gsize key_len, + gsize * out_len, + GError ** error); + +guint8 *_nmtst_crypto_decrypt(NMCryptoCipherType cipher, + const guint8 * data, + gsize data_len, + const guint8 * iv, + gsize iv_len, + const guint8 * key, + gsize key_len, + gsize * out_len, + GError ** error); + +#endif /* __NM_CRYPTO_IMPL_H__ */ diff --git a/src/libnm-core-impl/nm-crypto-nss.c b/src/libnm-core-impl/nm-crypto-nss.c new file mode 100644 index 0000000..6f43228 --- /dev/null +++ b/src/libnm-core-impl/nm-crypto-nss.c @@ -0,0 +1,548 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Dan Williams + * Copyright (C) 2007 - 2009 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-crypto-impl.h" + +NM_PRAGMA_WARNING_DISABLE("-Wstrict-prototypes") +#include +#include +#include +#include +#include +#include +#include +#include +#include +NM_PRAGMA_WARNING_REENABLE + +#include "libnm-glib-aux/nm-secret-utils.h" +#include "nm-errors.h" + +/*****************************************************************************/ + +static gboolean +_get_cipher_info(NMCryptoCipherType cipher, + CK_MECHANISM_TYPE *out_cipher_mech, + guint8 * out_real_iv_len) +{ + static const CK_MECHANISM_TYPE cipher_mechs[] = { + [NM_CRYPTO_CIPHER_DES_EDE3_CBC] = CKM_DES3_CBC_PAD, + [NM_CRYPTO_CIPHER_DES_CBC] = CKM_DES_CBC_PAD, + [NM_CRYPTO_CIPHER_AES_128_CBC] = CKM_AES_CBC_PAD, + [NM_CRYPTO_CIPHER_AES_192_CBC] = CKM_AES_CBC_PAD, + [NM_CRYPTO_CIPHER_AES_256_CBC] = CKM_AES_CBC_PAD, + }; + + g_return_val_if_fail(_NM_INT_NOT_NEGATIVE(cipher) + && (gsize) cipher < G_N_ELEMENTS(cipher_mechs), + FALSE); + + if (!cipher_mechs[cipher]) + return FALSE; + + NM_SET_OUT(out_cipher_mech, cipher_mechs[cipher]); + NM_SET_OUT(out_real_iv_len, nm_crypto_cipher_get_info(cipher)->real_iv_len); + return TRUE; +} + +/*****************************************************************************/ + +gboolean +_nm_crypto_init(GError **error) +{ + static gboolean initialized = FALSE; + SECStatus ret; + + if (initialized) + return TRUE; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 1); + ret = NSS_NoDB_Init(NULL); + if (ret != SECSuccess) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Failed to initialize the crypto engine: %d."), + PR_GetError()); + PR_Cleanup(); + return FALSE; + } + + SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1); + SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1); + SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1); + SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1); + SEC_PKCS12EnableCipher(PKCS12_DES_56, 1); + SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1); + SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1); + + initialized = TRUE; + return TRUE; +} + +guint8 * +_nmtst_crypto_decrypt(NMCryptoCipherType cipher, + const guint8 * data, + gsize data_len, + const guint8 * iv, + gsize iv_len, + const guint8 * key, + gsize key_len, + gsize * out_len, + GError ** error) +{ + CK_MECHANISM_TYPE cipher_mech; + PK11SlotInfo * slot = NULL; + SECItem key_item; + PK11SymKey * sym_key = NULL; + SECItem * sec_param = NULL; + PK11Context * ctx = NULL; + nm_auto_clear_secret_ptr NMSecretPtr output = {0}; + SECStatus s; + gboolean success = FALSE; + int decrypted_len = 0; + unsigned extra = 0; + unsigned pad_len = 0; + guint32 i; + guint8 real_iv_len; + + if (!_get_cipher_info(cipher, &cipher_mech, &real_iv_len)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + _("Unsupported key cipher for decryption")); + return NULL; + } + + if (iv_len < real_iv_len) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Invalid IV length (must be at least %u)."), + (guint) real_iv_len); + return NULL; + } + + if (!_nm_crypto_init(error)) + return NULL; + + slot = PK11_GetBestSlot(cipher_mech, NULL); + if (!slot) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Failed to initialize the decryption cipher slot.")); + goto out; + } + + key_item.data = (unsigned char *) key; + key_item.len = key_len; + sym_key = PK11_ImportSymKey(slot, cipher_mech, PK11_OriginUnwrap, CKA_DECRYPT, &key_item, NULL); + if (!sym_key) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to set symmetric key for decryption.")); + goto out; + } + + key_item.data = (unsigned char *) iv; + key_item.len = real_iv_len; + sec_param = PK11_ParamFromIV(cipher_mech, &key_item); + if (!sec_param) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to set IV for decryption.")); + goto out; + } + + ctx = PK11_CreateContextBySymKey(cipher_mech, CKA_DECRYPT, sym_key, sec_param); + if (!ctx) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to initialize the decryption context.")); + goto out; + } + + output.len = data_len; + output.bin = g_malloc(data_len); + + s = PK11_CipherOp(ctx, + (unsigned char *) output.bin, + &decrypted_len, + output.len, + data, + data_len); + if (s != SECSuccess) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key: %d."), + PORT_GetError()); + goto out; + } + + if (decrypted_len > data_len) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key: decrypted data too large.")); + goto out; + } + + s = PK11_DigestFinal(ctx, + (unsigned char *) &output.bin[decrypted_len], + &extra, + data_len - decrypted_len); + if (s != SECSuccess) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to finalize decryption of the private key: %d."), + PORT_GetError()); + goto out; + } + + decrypted_len += extra; + pad_len = data_len - decrypted_len; + + /* Check if the padding at the end of the decrypted data is valid */ + if (pad_len == 0 || pad_len > real_iv_len) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key: unexpected padding length.")); + goto out; + } + + /* Validate tail padding; last byte is the padding size, and all pad bytes + * should contain the padding size. + */ + for (i = pad_len; i > 0; i--) { + if (output.bin[data_len - i] != pad_len) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key.")); + goto out; + } + } + + success = TRUE; + +out: + if (ctx) + PK11_DestroyContext(ctx, PR_TRUE); + if (sym_key) + PK11_FreeSymKey(sym_key); + if (sec_param) + SECITEM_FreeItem(sec_param, PR_TRUE); + if (slot) + PK11_FreeSlot(slot); + + if (!success) + return NULL; + + if (decrypted_len < output.len) + nm_explicit_bzero(&output.bin[decrypted_len], output.len - decrypted_len); + *out_len = decrypted_len; + return g_steal_pointer(&output.bin); +} + +guint8 * +_nmtst_crypto_encrypt(NMCryptoCipherType cipher, + const guint8 * data, + gsize data_len, + const guint8 * iv, + gsize iv_len, + const guint8 * key, + gsize key_len, + gsize * out_len, + GError ** error) +{ + SECStatus ret; + CK_MECHANISM_TYPE cipher_mech = CKM_DES3_CBC_PAD; + PK11SlotInfo * slot = NULL; + SECItem key_item = {.data = (unsigned char *) key, .len = key_len}; + SECItem iv_item = {.data = (unsigned char *) iv, .len = iv_len}; + PK11SymKey * sym_key = NULL; + SECItem * sec_param = NULL; + PK11Context * ctx = NULL; + nm_auto_clear_secret_ptr NMSecretPtr padded_buf = {0}; + nm_auto_clear_secret_ptr NMSecretPtr output = {0}; + int encrypted_len = 0, i; + gboolean success = FALSE; + gsize pad_len; + + if (cipher == NM_CRYPTO_CIPHER_DES_CBC || !_get_cipher_info(cipher, &cipher_mech, NULL)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + _("Unsupported key cipher for encryption")); + return NULL; + } + + if (!_nm_crypto_init(error)) + return NULL; + + slot = PK11_GetBestSlot(cipher_mech, NULL); + if (!slot) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Failed to initialize the encryption cipher slot.")); + return NULL; + } + + sym_key = PK11_ImportSymKey(slot, cipher_mech, PK11_OriginUnwrap, CKA_ENCRYPT, &key_item, NULL); + if (!sym_key) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to set symmetric key for encryption.")); + goto out; + } + + sec_param = PK11_ParamFromIV(cipher_mech, &iv_item); + if (!sec_param) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to set IV for encryption.")); + goto out; + } + + ctx = PK11_CreateContextBySymKey(cipher_mech, CKA_ENCRYPT, sym_key, sec_param); + if (!ctx) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to initialize the encryption context.")); + goto out; + } + + /* If data->len % ivlen == 0, then we add another complete block + * onto the end so that the decrypter knows there's padding. + */ + pad_len = iv_len - (data_len % iv_len); + + padded_buf.len = data_len + pad_len; + padded_buf.bin = g_malloc(padded_buf.len); + + memcpy(padded_buf.bin, data, data_len); + for (i = 0; i < pad_len; i++) + padded_buf.bin[data_len + i] = (guint8)(pad_len & 0xFF); + + output.len = padded_buf.len; + output.bin = g_malloc(output.len); + + ret = + PK11_CipherOp(ctx, output.bin, &encrypted_len, output.len, padded_buf.bin, padded_buf.len); + if (ret != SECSuccess) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to encrypt: %d."), + PORT_GetError()); + goto out; + } + + if (encrypted_len != output.len) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Unexpected amount of data after encrypting.")); + goto out; + } + + success = TRUE; + +out: + if (ctx) + PK11_DestroyContext(ctx, PR_TRUE); + if (sec_param) + SECITEM_FreeItem(sec_param, PR_TRUE); + if (sym_key) + PK11_FreeSymKey(sym_key); + if (slot) + PK11_FreeSlot(slot); + + if (!success) + return NULL; + + *out_len = output.len; + return g_steal_pointer(&output.bin); +} + +gboolean +_nm_crypto_verify_x509(const guint8 *data, gsize len, GError **error) +{ + CERTCertificate *cert; + + if (!_nm_crypto_init(error)) + return FALSE; + + /* Try DER/PEM first */ + cert = CERT_DecodeCertFromPackage((char *) data, len); + if (!cert) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Couldn't decode certificate: %d"), + PORT_GetError()); + return FALSE; + } + + CERT_DestroyCertificate(cert); + return TRUE; +} + +gboolean +_nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *password, GError **error) +{ + SEC_PKCS12DecoderContext *p12ctx = NULL; + SECItem pw = {0}; + PK11SlotInfo * slot = NULL; + SECStatus s; + gboolean success = FALSE; + + g_return_val_if_fail(!error || !*error, FALSE); + + if (!_nm_crypto_init(error)) + return FALSE; + + /* PKCS#12 passwords are apparently UCS2 BIG ENDIAN, and NSS doesn't do + * any conversions for us. + */ + if (password && *password) { + nm_auto_clear_secret_ptr NMSecretPtr ucs2_password = {0}; + + if (g_utf8_validate(password, -1, NULL)) { + long ucs2_chars; + + ucs2_password.bin = + (guint8 *) g_utf8_to_utf16(password, strlen(password), NULL, &ucs2_chars, NULL); + + /* cannot fail, because password is valid UTF-8*/ + nm_assert(ucs2_password.bin && ucs2_chars > 0); + + ucs2_password.len = ucs2_chars * 2; + } + + if (!ucs2_password.bin || ucs2_password.len == 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_PASSWORD, + _("Password must be UTF-8")); + return FALSE; + } + + pw.data = PORT_ZAlloc(ucs2_password.len + 2); + memcpy(pw.data, ucs2_password.bin, ucs2_password.len); + pw.len = ucs2_password.len + 2; + +#if __BYTE_ORDER == __LITTLE_ENDIAN + { + guint16 *p, *p_end; + + p_end = (guint16 *) &(((guint8 *) pw.data)[ucs2_password.len]); + for (p = (guint16 *) pw.data; p < p_end; p++) + *p = GUINT16_SWAP_LE_BE(*p); + } +#endif + } + + slot = PK11_GetInternalKeySlot(); + if (!slot) { + g_set_error(error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_FAILED, _("Couldn't initialize slot")); + goto out; + } + + p12ctx = SEC_PKCS12DecoderStart(&pw, slot, NULL, NULL, NULL, NULL, NULL, NULL); + if (!p12ctx) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Couldn't initialize PKCS#12 decoder: %d"), + PORT_GetError()); + goto out; + } + + s = SEC_PKCS12DecoderUpdate(p12ctx, (guint8 *) data, data_len); + if (s != SECSuccess) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Couldn't decode PKCS#12 file: %d"), + PORT_GetError()); + goto out; + } + + s = SEC_PKCS12DecoderVerify(p12ctx); + if (s != SECSuccess) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Couldn't verify PKCS#12 file: %d"), + PORT_GetError()); + goto out; + } + + success = TRUE; + +out: + if (p12ctx) + SEC_PKCS12DecoderFinish(p12ctx); + if (slot) + PK11_FreeSlot(slot); + + if (pw.data) + SECITEM_ZfreeItem(&pw, PR_FALSE); + + return success; +} + +gboolean +_nm_crypto_verify_pkcs8(const guint8 *data, + gsize data_len, + gboolean is_encrypted, + const char * password, + GError ** error) +{ + g_return_val_if_fail(data != NULL, FALSE); + + if (!_nm_crypto_init(error)) + return FALSE; + + /* NSS apparently doesn't do PKCS#8 natively, but you have to put the + * PKCS#8 key into a PKCS#12 file and import that?? So until we figure + * all that out, we can only assume the password is valid. + */ + return TRUE; +} + +gboolean +_nm_crypto_randomize(void *buffer, gsize buffer_len, GError **error) +{ + SECStatus s; + + if (!_nm_crypto_init(error)) + return FALSE; + + s = PK11_GenerateRandom(buffer, buffer_len); + if (s != SECSuccess) { + g_set_error_literal(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Could not generate random data.")); + return FALSE; + } + return TRUE; +} diff --git a/src/libnm-core-impl/nm-crypto.c b/src/libnm-core-impl/nm-crypto.c new file mode 100644 index 0000000..d84a2b1 --- /dev/null +++ b/src/libnm-core-impl/nm-crypto.c @@ -0,0 +1,1084 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Dan Williams + * Copyright (C) 2007 - 2018 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-crypto.h" + +#include +#include +#include + +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" + +#include "nm-crypto-impl.h" +#include "nm-utils.h" +#include "nm-errors.h" + +#define PEM_RSA_KEY_BEGIN "-----BEGIN RSA PRIVATE KEY-----" +#define PEM_RSA_KEY_END "-----END RSA PRIVATE KEY-----" + +#define PEM_DSA_KEY_BEGIN "-----BEGIN DSA PRIVATE KEY-----" +#define PEM_DSA_KEY_END "-----END DSA PRIVATE KEY-----" + +#define PEM_CERT_BEGIN "-----BEGIN CERTIFICATE-----" +#define PEM_CERT_END "-----END CERTIFICATE-----" + +#define PEM_PKCS8_ENC_KEY_BEGIN "-----BEGIN ENCRYPTED PRIVATE KEY-----" +#define PEM_PKCS8_ENC_KEY_END "-----END ENCRYPTED PRIVATE KEY-----" + +#define PEM_PKCS8_DEC_KEY_BEGIN "-----BEGIN PRIVATE KEY-----" +#define PEM_PKCS8_DEC_KEY_END "-----END PRIVATE KEY-----" + +#define PEM_TPM2_WRAPPED_KEY_BEGIN "-----BEGIN TSS2 PRIVATE KEY-----" +#define PEM_TPM2_WRAPPED_KEY_END "-----END TSS2 PRIVATE KEY-----" + +#define PEM_TPM2_OLD_WRAPPED_KEY_BEGIN "-----BEGIN TSS2 KEY BLOB-----" +#define PEM_TPM2_OLD_WRAPPED_KEY_END "-----END TSS2 KEY BLOB-----" + +/*****************************************************************************/ + +static const NMCryptoCipherInfo cipher_infos[] = { +#define _CI(_cipher, _name, _digest_len, _real_iv_len) \ + [(_cipher) -1] = {.cipher = _cipher, \ + .name = ""_name \ + "", \ + .digest_len = _digest_len, \ + .real_iv_len = _real_iv_len} + _CI(NM_CRYPTO_CIPHER_DES_EDE3_CBC, "DES-EDE3-CBC", 24, 8), + _CI(NM_CRYPTO_CIPHER_DES_CBC, "DES-CBC", 8, 8), + _CI(NM_CRYPTO_CIPHER_AES_128_CBC, "AES-128-CBC", 16, 16), + _CI(NM_CRYPTO_CIPHER_AES_192_CBC, "AES-192-CBC", 24, 16), + _CI(NM_CRYPTO_CIPHER_AES_256_CBC, "AES-256-CBC", 32, 16), +}; + +const NMCryptoCipherInfo * +nm_crypto_cipher_get_info(NMCryptoCipherType cipher) +{ + g_return_val_if_fail(cipher > NM_CRYPTO_CIPHER_UNKNOWN + && (gsize) cipher < G_N_ELEMENTS(cipher_infos) + 1, + NULL); + +#if NM_MORE_ASSERTS > 10 + { + int i, j; + + for (i = 0; i < (int) G_N_ELEMENTS(cipher_infos); i++) { + const NMCryptoCipherInfo *info = &cipher_infos[i]; + + nm_assert(info->cipher == (NMCryptoCipherType)(i + 1)); + nm_assert(info->name && info->name[0]); + for (j = 0; j < i; j++) + nm_assert(g_ascii_strcasecmp(info->name, cipher_infos[j].name) != 0); + } + } +#endif + + return &cipher_infos[cipher - 1]; +} + +const NMCryptoCipherInfo * +nm_crypto_cipher_get_info_by_name(const char *cipher_name, gssize p_len) +{ + int i; + + nm_assert(nm_crypto_cipher_get_info(NM_CRYPTO_CIPHER_DES_CBC)->cipher + == NM_CRYPTO_CIPHER_DES_CBC); + + if (p_len < 0) { + if (!cipher_name) + return FALSE; + p_len = strlen(cipher_name); + } + + for (i = 0; i < (int) G_N_ELEMENTS(cipher_infos); i++) { + const NMCryptoCipherInfo *info = &cipher_infos[i]; + + if ((gsize) p_len == strlen(info->name) + && g_ascii_strncasecmp(info->name, cipher_name, p_len) == 0) + return info; + } + return NULL; +} + +/*****************************************************************************/ + +static gboolean +find_tag(const char *tag, const guint8 *data, gsize data_len, gsize start_at, gsize *out_pos) +{ + const guint8 *p; + gsize taglen; + + nm_assert(out_pos); + nm_assert(start_at <= data_len); + + taglen = strlen(tag); + + p = memmem(&data[start_at], data_len - start_at, tag, taglen); + if (!p) + return FALSE; + + *out_pos = p - data; + + nm_assert(memcmp(&data[*out_pos], tag, taglen) == 0); + + return TRUE; +} + +#define DEK_INFO_TAG "DEK-Info: " +#define PROC_TYPE_TAG "Proc-Type: " + +static char * +_extract_line(const guint8 **p, const guint8 *p_end) +{ + const guint8 *x, *x0; + + nm_assert(p); + nm_assert(p_end); + nm_assert(*p); + nm_assert(*p < p_end); + + x = x0 = *p; + while (TRUE) { + if (x == p_end) { + *p = p_end; + break; + } + if (*x == '\0') { + /* the data contains embedded NUL. This is the end. */ + *p = p_end; + break; + } + if (*x == '\n') { + *p = x + 1; + break; + } + x++; + } + + if (x == x0) + return NULL; + return g_strndup((char *) x0, x - x0); +} + +static gboolean +parse_old_openssl_key_file(const guint8 * data, + gsize data_len, + NMSecretPtr * out_parsed, + NMCryptoKeyType * out_key_type, + NMCryptoCipherType *out_cipher, + char ** out_iv, + GError ** error) +{ + gsize start = 0, end = 0; + nm_auto_free_secret char * str = NULL; + char * str_p; + gsize str_len; + int enc_tags = 0; + NMCryptoKeyType key_type; + nm_auto_clear_secret_ptr NMSecretPtr parsed = {0}; + nm_auto_free_secret char * iv = NULL; + NMCryptoCipherType cipher = NM_CRYPTO_CIPHER_UNKNOWN; + const char * start_tag; + const char * end_tag; + const guint8 * data_start, *data_end; + + nm_assert(!out_parsed || (out_parsed->len == 0 && !out_parsed->bin)); + nm_assert(!out_iv || !*out_iv); + + NM_SET_OUT(out_key_type, NM_CRYPTO_KEY_TYPE_UNKNOWN); + NM_SET_OUT(out_cipher, NM_CRYPTO_CIPHER_UNKNOWN); + + if (find_tag(PEM_RSA_KEY_BEGIN, data, data_len, 0, &start)) { + key_type = NM_CRYPTO_KEY_TYPE_RSA; + start_tag = PEM_RSA_KEY_BEGIN; + end_tag = PEM_RSA_KEY_END; + } else if (find_tag(PEM_DSA_KEY_BEGIN, data, data_len, 0, &start)) { + key_type = NM_CRYPTO_KEY_TYPE_DSA; + start_tag = PEM_DSA_KEY_BEGIN; + end_tag = PEM_DSA_KEY_END; + } else { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("PEM key file had no start tag")); + return FALSE; + } + + start += strlen(start_tag); + if (!find_tag(end_tag, data, data_len, start, &end)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("PEM key file had no end tag '%s'."), + end_tag); + return FALSE; + } + + str_len = end - start + 1; + str = g_new(char, str_len); + str[0] = '\0'; + str_p = str; + + data_start = &data[start]; + data_end = &data[end]; + + while (data_start < data_end) { + nm_auto_free_secret char *line = NULL; + char * p; + + line = _extract_line(&data_start, data_end); + if (!line) + continue; + + p = nm_secret_strchomp(nm_str_skip_leading_spaces(line)); + + if (!strncmp(p, PROC_TYPE_TAG, strlen(PROC_TYPE_TAG))) { + if (enc_tags++ != 0 || str_p != str) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: Proc-Type was not first tag.")); + return FALSE; + } + + p += strlen(PROC_TYPE_TAG); + if (strcmp(p, "4,ENCRYPTED")) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: unknown Proc-Type tag '%s'."), + p); + return FALSE; + } + } else if (!strncmp(p, DEK_INFO_TAG, strlen(DEK_INFO_TAG))) { + const NMCryptoCipherInfo *cipher_info; + char * comma; + gsize p_len; + + if (enc_tags++ != 1 || str_p != str) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: DEK-Info was not the second tag.")); + return FALSE; + } + + p += strlen(DEK_INFO_TAG); + + /* Grab the IV first */ + comma = strchr(p, ','); + if (!comma || (*(comma + 1) == '\0')) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: no IV found in DEK-Info tag.")); + return FALSE; + } + p_len = comma - p; + comma++; + if (!g_ascii_isxdigit(*comma)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: invalid format of IV in DEK-Info tag.")); + return FALSE; + } + nm_free_secret(iv); + iv = g_strdup(comma); + + /* Get the private key cipher */ + cipher_info = nm_crypto_cipher_get_info_by_name(p, p_len); + if (!cipher_info) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: unknown private key cipher '%s'."), + p); + return FALSE; + } + cipher = cipher_info->cipher; + } else { + if (enc_tags == 1) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + "Malformed PEM file: both Proc-Type and DEK-Info tags are required."); + return FALSE; + } + nm_utils_strbuf_append_str(&str_p, &str_len, p); + nm_assert(str_len > 0); + } + } + + parsed.bin = (guint8 *) g_base64_decode(str, &parsed.len); + if (!parsed.bin || parsed.len == 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Could not decode private key.")); + nm_secret_ptr_clear(&parsed); + return FALSE; + } + + NM_SET_OUT(out_key_type, key_type); + NM_SET_OUT(out_iv, g_steal_pointer(&iv)); + NM_SET_OUT(out_cipher, cipher); + nm_secret_ptr_move(out_parsed, &parsed); + return TRUE; +} + +static gboolean +parse_pkcs8_key_file(const guint8 *data, + gsize data_len, + NMSecretPtr * parsed, + gboolean * out_encrypted, + GError ** error) +{ + gsize start = 0, end = 0; + const char * start_tag = NULL, *end_tag = NULL; + gboolean encrypted = FALSE; + nm_auto_free_secret char *der_base64 = NULL; + + nm_assert(parsed); + nm_assert(!parsed->bin); + nm_assert(parsed->len == 0); + nm_assert(out_encrypted); + + /* Try encrypted first, decrypted next */ + if (find_tag(PEM_PKCS8_ENC_KEY_BEGIN, data, data_len, 0, &start)) { + start_tag = PEM_PKCS8_ENC_KEY_BEGIN; + end_tag = PEM_PKCS8_ENC_KEY_END; + encrypted = TRUE; + } else if (find_tag(PEM_PKCS8_DEC_KEY_BEGIN, data, data_len, 0, &start)) { + start_tag = PEM_PKCS8_DEC_KEY_BEGIN; + end_tag = PEM_PKCS8_DEC_KEY_END; + encrypted = FALSE; + } else { + g_set_error_literal(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to find expected PKCS#8 start tag.")); + return FALSE; + } + + start += strlen(start_tag); + if (!find_tag(end_tag, data, data_len, start, &end)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to find expected PKCS#8 end tag '%s'."), + end_tag); + return FALSE; + } + + /* g_base64_decode() wants a NULL-terminated string */ + der_base64 = g_strndup((char *) &data[start], end - start); + + parsed->bin = (guint8 *) g_base64_decode(der_base64, &parsed->len); + if (!parsed->bin || parsed->len == 0) { + g_set_error_literal(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to decode PKCS#8 private key.")); + nm_secret_ptr_clear(parsed); + return FALSE; + } + + *out_encrypted = encrypted; + return TRUE; +} + +static gboolean +parse_tpm2_wrapped_key_file(const guint8 *data, + gsize data_len, + gboolean * out_encrypted, + GError ** error) +{ + gsize start = 0, end = 0; + const char *start_tag = NULL, *end_tag = NULL; + + nm_assert(out_encrypted); + + if (find_tag(PEM_TPM2_WRAPPED_KEY_BEGIN, data, data_len, 0, &start)) { + start_tag = PEM_TPM2_WRAPPED_KEY_BEGIN; + end_tag = PEM_TPM2_WRAPPED_KEY_END; + } else if (find_tag(PEM_TPM2_OLD_WRAPPED_KEY_BEGIN, data, data_len, 0, &start)) { + start_tag = PEM_TPM2_OLD_WRAPPED_KEY_BEGIN; + end_tag = PEM_TPM2_OLD_WRAPPED_KEY_END; + } else { + g_set_error_literal(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to find expected TSS start tag.")); + return FALSE; + } + + start += strlen(start_tag); + if (!find_tag(end_tag, data, data_len, start, &end)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to find expected TSS end tag '%s'."), + end_tag); + return FALSE; + } + + *out_encrypted = FALSE; + return TRUE; +} + +static gboolean +file_read_contents(const char *filename, NMSecretPtr *out_contents, GError **error) +{ + nm_assert(out_contents); + nm_assert(out_contents->len == 0); + nm_assert(!out_contents->str); + + return nm_utils_file_get_contents(-1, + filename, + 100 * 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET, + &out_contents->str, + &out_contents->len, + NULL, + error); +} + +GBytes * +nm_crypto_read_file(const char *filename, GError **error) +{ + nm_auto_clear_secret_ptr NMSecretPtr contents = {0}; + + g_return_val_if_fail(filename, NULL); + + if (!file_read_contents(filename, &contents, error)) + return NULL; + return nm_secret_copy_to_gbytes(contents.bin, contents.len); +} + +/* + * Convert a hex string into bytes. + */ +static guint8 * +_nmtst_convert_iv(const char *src, gsize *out_len, GError **error) +{ + gsize i, num; + gs_free guint8 *c = NULL; + int c0, c1; + + nm_assert(src); + + num = strlen(src); + if (num == 0 || (num % 2) != 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("IV must be an even number of bytes in length.")); + return NULL; + } + + num /= 2; + c = g_malloc(num + 1); + + /* defensively add trailing NUL. This function returns binary data, + * do not assume it's NUL terminated. */ + c[num] = '\0'; + + for (i = 0; i < num; i++) { + if (((c0 = nm_utils_hexchar_to_int(*(src++))) < 0) + || ((c1 = nm_utils_hexchar_to_int(*(src++))) < 0)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("IV contains non-hexadecimal digits.")); + nm_explicit_bzero(c, i); + return FALSE; + } + + c[i] = (c0 << 4) + c1; + } + *out_len = num; + return g_steal_pointer(&c); +} + +guint8 * +nmtst_crypto_make_des_aes_key(NMCryptoCipherType cipher, + const guint8 * salt, + gsize salt_len, + const char * password, + gsize * out_len, + GError ** error) +{ + guint8 * key; + const NMCryptoCipherInfo *cipher_info; + + g_return_val_if_fail(salt != NULL, NULL); + g_return_val_if_fail(salt_len >= 8, NULL); + g_return_val_if_fail(password != NULL, NULL); + g_return_val_if_fail(out_len != NULL, NULL); + + *out_len = 0; + + cipher_info = nm_crypto_cipher_get_info(cipher); + + g_return_val_if_fail(cipher_info, NULL); + + if (password[0] == '\0') + return NULL; + + key = g_malloc(cipher_info->digest_len); + + nm_crypto_md5_hash(salt, + 8, + (guint8 *) password, + strlen(password), + key, + cipher_info->digest_len); + + *out_len = cipher_info->digest_len; + return key; +} + +static gboolean +_nmtst_decrypt_key(NMCryptoCipherType cipher, + const guint8 * data, + gsize data_len, + const char * iv, + const char * password, + NMSecretPtr * parsed, + GError ** error) +{ + nm_auto_clear_secret_ptr NMSecretPtr bin_iv = {0}; + nm_auto_clear_secret_ptr NMSecretPtr key = {0}; + + nm_assert(password); + nm_assert(cipher != NM_CRYPTO_CIPHER_UNKNOWN); + nm_assert(iv); + nm_assert(parsed); + nm_assert(!parsed->bin); + nm_assert(parsed->len == 0); + + bin_iv.bin = _nmtst_convert_iv(iv, &bin_iv.len, error); + if (!bin_iv.bin) + return FALSE; + + if (bin_iv.len < 8) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("IV must contain at least 8 characters")); + return FALSE; + } + + /* Convert the password and IV into a DES or AES key */ + key.bin = + nmtst_crypto_make_des_aes_key(cipher, bin_iv.bin, bin_iv.len, password, &key.len, error); + if (!key.bin || !key.len) + return FALSE; + + parsed->bin = _nmtst_crypto_decrypt(cipher, + data, + data_len, + bin_iv.bin, + bin_iv.len, + key.bin, + key.len, + &parsed->len, + error); + if (!parsed->bin || parsed->len == 0) { + nm_secret_ptr_clear(parsed); + return FALSE; + } + + return TRUE; +} + +GBytes * +nmtst_crypto_decrypt_openssl_private_key_data(const guint8 * data, + gsize data_len, + const char * password, + NMCryptoKeyType *out_key_type, + GError ** error) +{ + NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + nm_auto_clear_secret_ptr NMSecretPtr parsed = {0}; + nm_auto_free_secret char * iv = NULL; + NMCryptoCipherType cipher = NM_CRYPTO_CIPHER_UNKNOWN; + + g_return_val_if_fail(data != NULL, NULL); + + NM_SET_OUT(out_key_type, NM_CRYPTO_KEY_TYPE_UNKNOWN); + + if (!_nm_crypto_init(error)) + return NULL; + + if (!parse_old_openssl_key_file(data, data_len, &parsed, &key_type, &cipher, &iv, NULL)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Unable to determine private key type.")); + return NULL; + } + + NM_SET_OUT(out_key_type, key_type); + + if (password) { + nm_auto_clear_secret_ptr NMSecretPtr parsed2 = {0}; + + if (cipher == NM_CRYPTO_CIPHER_UNKNOWN || !iv) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_PASSWORD, + _("Password provided, but key was not encrypted.")); + return NULL; + } + + if (!_nmtst_decrypt_key(cipher, parsed.bin, parsed.len, iv, password, &parsed2, error)) + return NULL; + + return nm_secret_copy_to_gbytes(parsed2.bin, parsed2.len); + } + + if (cipher != NM_CRYPTO_CIPHER_UNKNOWN || iv) + return NULL; + + return nm_secret_copy_to_gbytes(parsed.bin, parsed.len); +} + +GBytes * +nmtst_crypto_decrypt_openssl_private_key(const char * file, + const char * password, + NMCryptoKeyType *out_key_type, + GError ** error) +{ + nm_auto_clear_secret_ptr NMSecretPtr contents = {0}; + + if (!_nm_crypto_init(error)) + return NULL; + + if (!file_read_contents(file, &contents, error)) + return NULL; + + return nmtst_crypto_decrypt_openssl_private_key_data(contents.bin, + contents.len, + password, + out_key_type, + error); +} + +static gboolean +extract_pem_cert_data(const guint8 *contents, + gsize contents_len, + NMSecretPtr * out_cert, + GError ** error) +{ + gsize start = 0; + gsize end = 0; + nm_auto_free_secret char *der_base64 = NULL; + + nm_assert(contents); + nm_assert(out_cert); + nm_assert(out_cert->len == 0); + nm_assert(!out_cert->ptr); + + if (!find_tag(PEM_CERT_BEGIN, contents, contents_len, 0, &start)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("PEM certificate had no start tag '%s'."), + PEM_CERT_BEGIN); + return FALSE; + } + + start += strlen(PEM_CERT_BEGIN); + if (!find_tag(PEM_CERT_END, contents, contents_len, start, &end)) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("PEM certificate had no end tag '%s'."), + PEM_CERT_END); + return FALSE; + } + + /* g_base64_decode() wants a NULL-terminated string */ + der_base64 = g_strndup((const char *) &contents[start], end - start); + + out_cert->bin = (guint8 *) g_base64_decode(der_base64, &out_cert->len); + if (!out_cert->bin || !out_cert->len) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to decode certificate.")); + nm_secret_ptr_clear(out_cert); + return FALSE; + } + + return TRUE; +} + +gboolean +nm_crypto_load_and_verify_certificate(const char * file, + NMCryptoFileFormat *out_file_format, + GBytes ** out_certificate, + GError ** error) +{ + nm_auto_clear_secret_ptr NMSecretPtr contents = {0}; + + g_return_val_if_fail(file, FALSE); + nm_assert(!error || !*error); + + if (!_nm_crypto_init(error)) + goto out; + + if (!file_read_contents(file, &contents, error)) + goto out; + + if (contents.len == 0) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Certificate file is empty")); + goto out; + } + + /* Check for PKCS#12 */ + if (nm_crypto_is_pkcs12_data(contents.bin, contents.len, NULL)) { + NM_SET_OUT(out_file_format, NM_CRYPTO_FILE_FORMAT_PKCS12); + NM_SET_OUT(out_certificate, nm_secret_copy_to_gbytes(contents.bin, contents.len)); + return TRUE; + } + + /* Check for plain DER format */ + if (contents.len > 2 && contents.bin[0] == 0x30 && contents.bin[1] == 0x82) { + if (_nm_crypto_verify_x509(contents.bin, contents.len, NULL)) { + NM_SET_OUT(out_file_format, NM_CRYPTO_FILE_FORMAT_X509); + NM_SET_OUT(out_certificate, nm_secret_copy_to_gbytes(contents.bin, contents.len)); + return TRUE; + } + } else { + nm_auto_clear_secret_ptr NMSecretPtr pem_cert = {0}; + + if (extract_pem_cert_data(contents.bin, contents.len, &pem_cert, NULL)) { + if (_nm_crypto_verify_x509(pem_cert.bin, pem_cert.len, NULL)) { + NM_SET_OUT(out_file_format, NM_CRYPTO_FILE_FORMAT_X509); + NM_SET_OUT(out_certificate, nm_secret_copy_to_gbytes(contents.bin, contents.len)); + return TRUE; + } + } + } + + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to recognize certificate")); + +out: + NM_SET_OUT(out_file_format, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + NM_SET_OUT(out_certificate, NULL); + return FALSE; +} + +gboolean +nm_crypto_is_pkcs12_data(const guint8 *data, gsize data_len, GError **error) +{ + GError * local = NULL; + gboolean success; + + if (!data_len) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Certificate file is empty")); + return FALSE; + } + + g_return_val_if_fail(data != NULL, FALSE); + + if (!_nm_crypto_init(error)) + return FALSE; + + success = _nm_crypto_verify_pkcs12(data, data_len, NULL, &local); + if (success == FALSE) { + /* If the error was just a decryption error, then it's pkcs#12 */ + if (local) { + if (g_error_matches(local, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_DECRYPTION_FAILED)) { + success = TRUE; + g_error_free(local); + } else + g_propagate_error(error, local); + } + } + return success; +} + +gboolean +nm_crypto_is_pkcs12_file(const char *file, GError **error) +{ + nm_auto_clear_secret_ptr NMSecretPtr contents = {0}; + + g_return_val_if_fail(file != NULL, FALSE); + + if (!_nm_crypto_init(error)) + return FALSE; + + if (!file_read_contents(file, &contents, error)) + return FALSE; + + return nm_crypto_is_pkcs12_data(contents.bin, contents.len, error); +} + +/* Verifies that a private key can be read, and if a password is given, that + * the private key can be decrypted with that password. + */ +NMCryptoFileFormat +nm_crypto_verify_private_key_data(const guint8 *data, + gsize data_len, + const char * password, + gboolean * out_is_encrypted, + GError ** error) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean is_encrypted = FALSE; + + g_return_val_if_fail(data != NULL, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + g_return_val_if_fail(out_is_encrypted == NULL || *out_is_encrypted == FALSE, + NM_CRYPTO_FILE_FORMAT_UNKNOWN); + + if (!_nm_crypto_init(error)) + return NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + /* Check for PKCS#12 first */ + if (nm_crypto_is_pkcs12_data(data, data_len, NULL)) { + is_encrypted = TRUE; + if (!password || _nm_crypto_verify_pkcs12(data, data_len, password, error)) + format = NM_CRYPTO_FILE_FORMAT_PKCS12; + } else { + nm_auto_clear_secret_ptr NMSecretPtr parsed = {0}; + + /* Maybe it's PKCS#8 */ + if (parse_pkcs8_key_file(data, data_len, &parsed, &is_encrypted, NULL)) { + if (!password + || _nm_crypto_verify_pkcs8(parsed.bin, parsed.len, is_encrypted, password, error)) + format = NM_CRYPTO_FILE_FORMAT_RAW_KEY; + } else if (parse_tpm2_wrapped_key_file(data, data_len, &is_encrypted, NULL)) { + format = NM_CRYPTO_FILE_FORMAT_RAW_KEY; + } else { + NMCryptoCipherType cipher; + nm_auto_free_secret char *iv = NULL; + + /* Or it's old-style OpenSSL */ + if (parse_old_openssl_key_file(data, data_len, NULL, NULL, &cipher, &iv, NULL)) { + format = NM_CRYPTO_FILE_FORMAT_RAW_KEY; + is_encrypted = (cipher != NM_CRYPTO_CIPHER_UNKNOWN && iv); + } + } + } + + if (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN && error && !*error) { + g_set_error(error, + NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("not a valid private key")); + } + + if (out_is_encrypted) + *out_is_encrypted = is_encrypted; + return format; +} + +NMCryptoFileFormat +nm_crypto_verify_private_key(const char *filename, + const char *password, + gboolean * out_is_encrypted, + GError ** error) +{ + nm_auto_clear_secret_ptr NMSecretPtr contents = {0}; + + g_return_val_if_fail(filename != NULL, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + + if (!_nm_crypto_init(error)) + return NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + if (!file_read_contents(filename, &contents, error)) + return NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + return nm_crypto_verify_private_key_data(contents.bin, + contents.len, + password, + out_is_encrypted, + error); +} + +void +nm_crypto_md5_hash(const guint8 *salt, + gsize salt_len, + const guint8 *password, + gsize password_len, + guint8 * buffer, + gsize buflen) +{ + nm_auto_free_checksum GChecksum * ctx = NULL; + nm_auto_clear_static_secret_ptr const NMSecretPtr digest = + NM_SECRET_PTR_STATIC(NM_UTILS_CHECKSUM_LENGTH_MD5); + gsize bufidx = 0; + int i; + + g_return_if_fail(password_len == 0 || password); + g_return_if_fail(buffer); + g_return_if_fail(buflen > 0); + g_return_if_fail(salt_len == 0 || salt); + + ctx = g_checksum_new(G_CHECKSUM_MD5); + + for (;;) { + if (password_len > 0) + g_checksum_update(ctx, (const guchar *) password, password_len); + if (salt_len > 0) + g_checksum_update(ctx, (const guchar *) salt, salt_len); + + nm_utils_checksum_get_digest_len(ctx, digest.bin, NM_UTILS_CHECKSUM_LENGTH_MD5); + + for (i = 0; i < NM_UTILS_CHECKSUM_LENGTH_MD5; i++) { + if (bufidx >= buflen) + return; + buffer[bufidx++] = digest.bin[i]; + } + + g_checksum_reset(ctx); + g_checksum_update(ctx, digest.ptr, NM_UTILS_CHECKSUM_LENGTH_MD5); + } +} + +gboolean +nm_crypto_randomize(void *buffer, gsize buffer_len, GError **error) +{ + return _nm_crypto_randomize(buffer, buffer_len, error); +} + +/** + * nmtst_crypto_rsa_key_encrypt: + * @data: (array length=len): RSA private key data to be encrypted + * @len: length of @data + * @in_password: (allow-none): existing password to use, if any + * @out_password: (out) (allow-none): if @in_password was %NULL, a random + * password will be generated and returned in this argument + * @error: detailed error information on return, if an error occurred + * + * Encrypts the given RSA private key data with the given password (or generates + * a password if no password was given) and converts the data to PEM format + * suitable for writing to a file. It uses Triple DES cipher for the encryption. + * + * Returns: (transfer full): on success, PEM-formatted data suitable for writing + * to a PEM-formatted certificate/private key file. + **/ +GBytes * +nmtst_crypto_rsa_key_encrypt(const guint8 *data, + gsize len, + const char * in_password, + char ** out_password, + GError ** error) +{ + guint8 salt[8]; + nm_auto_clear_secret_ptr NMSecretPtr key = {0}; + nm_auto_clear_secret_ptr NMSecretPtr enc = {0}; + gs_unref_ptrarray GPtrArray *pem = NULL; + nm_auto_free_secret char * tmp_password = NULL; + nm_auto_free_secret char * enc_base64 = NULL; + gsize enc_base64_len; + const char * p; + gsize ret_len, ret_idx; + guint i; + NMSecretBuf * ret; + + g_return_val_if_fail(data, NULL); + g_return_val_if_fail(len > 0, NULL); + g_return_val_if_fail(!out_password || !*out_password, NULL); + + /* Make the password if needed */ + if (!in_password) { + nm_auto_clear_static_secret_ptr NMSecretPtr pw_buf = NM_SECRET_PTR_STATIC(32); + + if (!nm_crypto_randomize(pw_buf.bin, pw_buf.len, error)) + return NULL; + tmp_password = nm_utils_bin2hexstr(pw_buf.bin, pw_buf.len, -1); + in_password = tmp_password; + } + + if (!nm_crypto_randomize(salt, sizeof(salt), error)) + return NULL; + + key.bin = nmtst_crypto_make_des_aes_key(NM_CRYPTO_CIPHER_DES_EDE3_CBC, + salt, + sizeof(salt), + in_password, + &key.len, + NULL); + if (!key.bin) + g_return_val_if_reached(NULL); + + enc.bin = _nmtst_crypto_encrypt(NM_CRYPTO_CIPHER_DES_EDE3_CBC, + data, + len, + salt, + sizeof(salt), + key.bin, + key.len, + &enc.len, + error); + if (!enc.bin) + return NULL; + + /* What follows is not the most efficient way to construct the pem + * file line-by-line. At least, it makes sure, that the data will be cleared + * again and not left around in memory. + * + * If this would not be test code, we should improve the implementation + * to avoid some of the copying. */ + pem = g_ptr_array_new_with_free_func((GDestroyNotify) nm_free_secret); + + g_ptr_array_add(pem, g_strdup("-----BEGIN RSA PRIVATE KEY-----\n")); + g_ptr_array_add(pem, g_strdup("Proc-Type: 4,ENCRYPTED\n")); + + /* Convert the salt to a hex string */ + g_ptr_array_add( + pem, + g_strdup_printf("DEK-Info: %s,", + nm_crypto_cipher_get_info(NM_CRYPTO_CIPHER_DES_EDE3_CBC)->name)); + g_ptr_array_add(pem, nm_utils_bin2hexstr(salt, sizeof(salt), sizeof(salt) * 2)); + g_ptr_array_add(pem, g_strdup("\n\n")); + + /* Convert the encrypted key to a base64 string */ + enc_base64 = g_base64_encode((const guchar *) enc.bin, enc.len); + enc_base64_len = strlen(enc_base64); + for (p = enc_base64; (p - enc_base64) < (ptrdiff_t) enc_base64_len; p += 64) { + g_ptr_array_add(pem, g_strndup(p, 64)); + g_ptr_array_add(pem, g_strdup("\n")); + } + + g_ptr_array_add(pem, g_strdup("-----END RSA PRIVATE KEY-----\n")); + + ret_len = 0; + for (i = 0; i < pem->len; i++) + ret_len += strlen(pem->pdata[i]); + + ret = nm_secret_buf_new(ret_len + 1); + ret_idx = 0; + for (i = 0; i < pem->len; i++) { + const char *line = pem->pdata[i]; + gsize line_l = strlen(line); + + memcpy(&ret->bin[ret_idx], line, line_l); + ret_idx += line_l; + nm_assert(ret_idx <= ret_len); + } + nm_assert(ret_idx == ret_len); + ret->bin[ret_len] = '\0'; + + NM_SET_OUT(out_password, g_strdup(tmp_password)); + return nm_secret_buf_to_gbytes_take(ret, ret_len); +} diff --git a/src/libnm-core-impl/nm-crypto.h b/src/libnm-core-impl/nm-crypto.h new file mode 100644 index 0000000..8665a23 --- /dev/null +++ b/src/libnm-core-impl/nm-crypto.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Dan Williams + * Copyright (C) 2007 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_CRYPTO_H__ +#define __NM_CRYPTO_H__ + +typedef enum { + NM_CRYPTO_CIPHER_UNKNOWN, + NM_CRYPTO_CIPHER_DES_EDE3_CBC, + NM_CRYPTO_CIPHER_DES_CBC, + NM_CRYPTO_CIPHER_AES_128_CBC, + NM_CRYPTO_CIPHER_AES_192_CBC, + NM_CRYPTO_CIPHER_AES_256_CBC, +} NMCryptoCipherType; + +typedef struct { + const char * name; + NMCryptoCipherType cipher; + guint8 digest_len; + guint8 real_iv_len; +} NMCryptoCipherInfo; + +const NMCryptoCipherInfo *nm_crypto_cipher_get_info(NMCryptoCipherType cipher); +const NMCryptoCipherInfo *nm_crypto_cipher_get_info_by_name(const char *cipher_name, gssize p_len); + +typedef enum { + NM_CRYPTO_KEY_TYPE_UNKNOWN = 0, + NM_CRYPTO_KEY_TYPE_RSA, + NM_CRYPTO_KEY_TYPE_DSA +} NMCryptoKeyType; + +typedef enum { + NM_CRYPTO_FILE_FORMAT_UNKNOWN = 0, + NM_CRYPTO_FILE_FORMAT_X509, + NM_CRYPTO_FILE_FORMAT_RAW_KEY, + NM_CRYPTO_FILE_FORMAT_PKCS12 +} NMCryptoFileFormat; + +/*****************************************************************************/ + +GBytes *nm_crypto_read_file(const char *filename, GError **error); + +gboolean nm_crypto_load_and_verify_certificate(const char * file, + NMCryptoFileFormat *out_file_format, + GBytes ** out_certificat, + GError ** error); + +gboolean nm_crypto_is_pkcs12_file(const char *file, GError **error); + +gboolean nm_crypto_is_pkcs12_data(const guint8 *data, gsize len, GError **error); + +NMCryptoFileFormat nm_crypto_verify_private_key_data(const guint8 *data, + gsize data_len, + const char * password, + gboolean * out_is_encrypted, + GError ** error); + +NMCryptoFileFormat nm_crypto_verify_private_key(const char *file, + const char *password, + gboolean * out_is_encrypted, + GError ** error); + +void nm_crypto_md5_hash(const guint8 *salt, + gsize salt_len, + const guint8 *password, + gsize password_len, + guint8 * buffer, + gsize buflen); + +gboolean nm_crypto_randomize(void *buffer, gsize buffer_len, GError **error); + +/*****************************************************************************/ + +GBytes *nmtst_crypto_decrypt_openssl_private_key_data(const guint8 * data, + gsize data_len, + const char * password, + NMCryptoKeyType *out_key_type, + GError ** error); + +GBytes *nmtst_crypto_decrypt_openssl_private_key(const char * file, + const char * password, + NMCryptoKeyType *out_key_type, + GError ** error); + +GBytes *nmtst_crypto_rsa_key_encrypt(const guint8 *data, + gsize len, + const char * in_password, + char ** out_password, + GError ** error); + +guint8 *nmtst_crypto_make_des_aes_key(NMCryptoCipherType cipher, + const guint8 * salt, + gsize salt_len, + const char * password, + gsize * out_len, + GError ** error); + +/*****************************************************************************/ + +#endif /* __NM_CRYPTO_H__ */ diff --git a/src/libnm-core-impl/nm-dbus-utils.c b/src/libnm-core-impl/nm-dbus-utils.c new file mode 100644 index 0000000..a272f08 --- /dev/null +++ b/src/libnm-core-impl/nm-dbus-utils.c @@ -0,0 +1,259 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "libnm-core-intern/nm-core-internal.h" + +typedef struct { + char * signal_name; + const GVariantType *signature; +} NMDBusSignalData; + +static void +dbus_signal_data_free(gpointer data, GClosure *closure) +{ + NMDBusSignalData *sd = data; + + g_free(sd->signal_name); + g_slice_free(NMDBusSignalData, sd); +} + +static void +dbus_signal_meta_marshal(GClosure * closure, + GValue * return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + NMDBusSignalData *sd = marshal_data; + const char * signal_name; + GVariant * parameters, *param; + GValue * closure_params; + gsize n_params, i; + + g_return_if_fail(n_param_values == 4); + + signal_name = g_value_get_string(¶m_values[2]); + parameters = g_value_get_variant(¶m_values[3]); + + if (strcmp(signal_name, sd->signal_name) != 0) + return; + + if (sd->signature) { + if (!g_variant_is_of_type(parameters, sd->signature)) { + g_warning("%p: got signal '%s' but parameters were of type '%s', not '%s'", + g_value_get_object(¶m_values[0]), + signal_name, + g_variant_get_type_string(parameters), + g_variant_type_peek_string(sd->signature)); + return; + } + + n_params = g_variant_n_children(parameters) + 1; + } else + n_params = 1; + + closure_params = g_new0(GValue, n_params); + g_value_init(&closure_params[0], G_TYPE_OBJECT); + g_value_copy(¶m_values[0], &closure_params[0]); + + for (i = 1; i < n_params; i++) { + param = g_variant_get_child_value(parameters, i - 1); + if (g_variant_is_of_type(param, G_VARIANT_TYPE("ay")) + || g_variant_is_of_type(param, G_VARIANT_TYPE("aay"))) { + /* g_dbus_gvariant_to_gvalue() thinks 'ay' means "non-UTF-8 NUL-terminated string" */ + g_value_init(&closure_params[i], G_TYPE_VARIANT); + g_value_set_variant(&closure_params[i], param); + } else + g_dbus_gvariant_to_gvalue(param, &closure_params[i]); + g_variant_unref(param); + } + + g_cclosure_marshal_generic(closure, NULL, n_params, closure_params, invocation_hint, NULL); + + for (i = 0; i < n_params; i++) + g_value_unset(&closure_params[i]); + g_free(closure_params); +} + +/** + * _nm_dbus_signal_connect_data: + * @proxy: a #GDBusProxy + * @signal_name: the D-Bus signal to connect to + * @signature: (allow-none): the signal's type signature (must be a tuple) + * @c_handler: the signal handler function + * @data: (allow-none): data to pass to @c_handler + * @destroy_data: (allow-none): closure destroy notify for @data + * @connect_flags: connection flags + * + * Connects to the D-Bus signal @signal_name on @proxy. @c_handler must be a + * void function whose first argument is a #GDBusProxy, followed by arguments + * for each element of @signature, ending with a #gpointer argument for @data. + * + * The argument types in @c_handler correspond to the types output by + * g_dbus_gvariant_to_gvalue(), except for 'ay' and 'aay'. In particular: + * - both 16-bit and 32-bit integers are passed as #int/#guint + * - 'as' values are passed as #GStrv (char **) + * - all other array, tuple, and dict types are passed as #GVariant + * + * If @signature is %NULL, then the signal's parameters will be ignored, and + * @c_handler should take only the #GDBusProxy and #gpointer arguments. + * + * Returns: the signal handler ID, which can be used with + * g_signal_handler_remove(). Beware that because of the way the signal is + * connected, you will not be able to remove it with + * g_signal_handlers_disconnect_by_func(), although + * g_signal_handlers_disconnect_by_data() will work correctly. + */ +gulong +_nm_dbus_signal_connect_data(GDBusProxy * proxy, + const char * signal_name, + const GVariantType *signature, + GCallback c_handler, + gpointer data, + GClosureNotify destroy_data, + GConnectFlags connect_flags) +{ + NMDBusSignalData *sd; + GClosure * closure; + gboolean swapped = !!(connect_flags & G_CONNECT_SWAPPED); + gboolean after = !!(connect_flags & G_CONNECT_AFTER); + + g_return_val_if_fail(G_IS_DBUS_PROXY(proxy), 0); + g_return_val_if_fail(signal_name != NULL, 0); + g_return_val_if_fail(signature == NULL || g_variant_type_is_tuple(signature), 0); + g_return_val_if_fail(c_handler != NULL, 0); + + sd = g_slice_new(NMDBusSignalData); + sd->signal_name = g_strdup(signal_name); + sd->signature = signature; + + closure = (swapped ? g_cclosure_new_swap : g_cclosure_new)(c_handler, data, destroy_data); + g_closure_set_marshal(closure, g_cclosure_marshal_generic); + g_closure_set_meta_marshal(closure, sd, dbus_signal_meta_marshal); + g_closure_add_finalize_notifier(closure, sd, dbus_signal_data_free); + + return g_signal_connect_closure(proxy, "g-signal", closure, after); +} + +/** + * _nm_dbus_signal_connect: + * @proxy: a #GDBusProxy + * @signal_name: the D-Bus signal to connect to + * @signature: the signal's type signature (must be a tuple) + * @c_handler: the signal handler function + * @data: (allow-none): data to pass to @c_handler + * + * Simplified version of _nm_dbus_signal_connect_data() with fewer arguments. + * + * Returns: the signal handler ID, as with _nm_signal_connect_data(). + */ + +/** + * _nm_dbus_typecheck_response: + * @response: the #GVariant response to check. + * @reply_type: the expected reply type. It may be %NULL to perform no + * checking. + * @error: (allow-none): the error in case the @reply_type does not match. + * + * Returns: %TRUE, if @response is of the expected @reply_type. + */ +gboolean +_nm_dbus_typecheck_response(GVariant *response, const GVariantType *reply_type, GError **error) +{ + g_return_val_if_fail(response, FALSE); + + if (!reply_type) + return TRUE; + if (g_variant_is_of_type(response, reply_type)) + return TRUE; + + /* This is the same error code that g_dbus_connection_call() returns if + * @reply_type doesn't match. + */ + g_set_error(error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Method returned type '%s', but expected '%s'"), + g_variant_get_type_string(response), + g_variant_type_peek_string(reply_type)); + return FALSE; +} + +/** + * _nm_dbus_proxy_call_finish: + * @proxy: A #GDBusProxy. + * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to + * g_dbus_proxy_call(). + * @reply_type: (allow-none): the expected type of the reply, or %NULL + * @error: Return location for error or %NULL. + * + * Finishes an operation started with g_dbus_proxy_call(), as with + * g_dbus_proxy_call_finish(), except thatif @reply_type is non-%NULL, then it + * will also check that the response matches that type signature, and return + * an error if not. + * + * Returns: %NULL if @error is set. Otherwise, a #GVariant tuple with + * return values. Free with g_variant_unref(). + */ +GVariant * +_nm_dbus_proxy_call_finish(GDBusProxy * proxy, + GAsyncResult * res, + const GVariantType *reply_type, + GError ** error) +{ + GVariant *variant; + + variant = g_dbus_proxy_call_finish(proxy, res, error); + if (variant && !_nm_dbus_typecheck_response(variant, reply_type, error)) + nm_clear_pointer(&variant, g_variant_unref); + return variant; +} + +GVariant * +_nm_dbus_connection_call_finish(GDBusConnection * dbus_connection, + GAsyncResult * result, + const GVariantType *reply_type, + GError ** error) +{ + GVariant *variant; + + variant = g_dbus_connection_call_finish(dbus_connection, result, error); + if (variant && !_nm_dbus_typecheck_response(variant, reply_type, error)) + nm_clear_pointer(&variant, g_variant_unref); + return variant; +} + +/** + * _nm_dbus_error_has_name: + * @error: (allow-none): a #GError, or %NULL + * @dbus_error_name: a D-Bus error name + * + * Checks if @error is set and corresponds to the D-Bus error @dbus_error_name. + * + * This should only be used for "foreign" D-Bus errors (eg, errors + * from BlueZ or wpa_supplicant). All NetworkManager D-Bus errors + * should be properly mapped by gdbus to one of the domains/codes in + * nm-errors.h. + * + * Returns: %TRUE or %FALSE + */ +gboolean +_nm_dbus_error_has_name(GError *error, const char *dbus_error_name) +{ + gboolean has_name = FALSE; + + if (error && g_dbus_error_is_remote_error(error)) { + char *error_name; + + error_name = g_dbus_error_get_remote_error(error); + has_name = !g_strcmp0(error_name, dbus_error_name); + g_free(error_name); + } + + return has_name; +} diff --git a/src/libnm-core-impl/nm-default-libnm-core.h b/src/libnm-core-impl/nm-default-libnm-core.h new file mode 100644 index 0000000..0f27f82 --- /dev/null +++ b/src/libnm-core-impl/nm-default-libnm-core.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEFAULT_LIBNM_CORE_H__ +#define __NM_DEFAULT_LIBNM_CORE_H__ + +/*****************************************************************************/ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#undef NETWORKMANAGER_COMPILATION +#define NETWORKMANAGER_COMPILATION NM_NETWORKMANAGER_COMPILATION_LIBNM_CORE + +/*****************************************************************************/ + +#include "nm-version.h" + +/*****************************************************************************/ + +#endif /* __NM_DEFAULT_LIBNM_CORE_H__ */ diff --git a/src/libnm-core-impl/nm-errors.c b/src/libnm-core-impl/nm-errors.c new file mode 100644 index 0000000..ea4ca5e --- /dev/null +++ b/src/libnm-core-impl/nm-errors.c @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2004 - 2014 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-errors.h" + +#include "nm-vpn-dbus-interface.h" +#include "libnm-core-intern/nm-core-internal.h" + +NM_CACHED_QUARK_FCN("nm-agent-manager-error-quark", nm_agent_manager_error_quark); +NM_CACHED_QUARK_FCN("nm-connection-error-quark", nm_connection_error_quark); +NM_CACHED_QUARK_FCN("nm-crypto-error-quark", nm_crypto_error_quark); +NM_CACHED_QUARK_FCN("nm-device-error-quark", nm_device_error_quark); +NM_CACHED_QUARK_FCN("nm-secret-agent-error-quark", nm_secret_agent_error_quark); +NM_CACHED_QUARK_FCN("nm-settings-error-quark", nm_settings_error_quark); +NM_CACHED_QUARK_FCN("nm-vpn-plugin-error-quark", nm_vpn_plugin_error_quark); + +static void +register_error_domain(GQuark domain, const char *interface, GType enum_type) +{ + nm_auto_unref_gtypeclass GEnumClass *enum_class = g_type_class_ref(enum_type); + guint i; + + for (i = 0; i < enum_class->n_values; i++) { + const GEnumValue *e = &enum_class->values[i]; + char error_name[200]; + + nm_assert(e && e->value_nick && !strchr(e->value_nick, '-')); + + nm_sprintf_buf(error_name, "%s.%s", interface, e->value_nick); + if (!g_dbus_error_register_error(domain, e->value, error_name)) + nm_assert_not_reached(); + } +} + +void +_nm_dbus_errors_init(void) +{ + register_error_domain(NM_AGENT_MANAGER_ERROR, + NM_DBUS_INTERFACE_AGENT_MANAGER, + NM_TYPE_AGENT_MANAGER_ERROR); + register_error_domain(NM_CONNECTION_ERROR, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NM_TYPE_CONNECTION_ERROR); + register_error_domain(NM_DEVICE_ERROR, NM_DBUS_INTERFACE_DEVICE, NM_TYPE_DEVICE_ERROR); + register_error_domain(NM_MANAGER_ERROR, NM_DBUS_INTERFACE, NM_TYPE_MANAGER_ERROR); + register_error_domain(NM_SECRET_AGENT_ERROR, + NM_DBUS_INTERFACE_SECRET_AGENT, + NM_TYPE_SECRET_AGENT_ERROR); + register_error_domain(NM_SETTINGS_ERROR, NM_DBUS_INTERFACE_SETTINGS, NM_TYPE_SETTINGS_ERROR); + register_error_domain(NM_VPN_PLUGIN_ERROR, NM_DBUS_VPN_ERROR_PREFIX, NM_TYPE_VPN_PLUGIN_ERROR); +} diff --git a/src/libnm-core-impl/nm-keyfile-utils.c b/src/libnm-core-impl/nm-keyfile-utils.c new file mode 100644 index 0000000..9c4a981 --- /dev/null +++ b/src/libnm-core-impl/nm-keyfile-utils.c @@ -0,0 +1,684 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2010 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "libnm-core-intern/nm-keyfile-utils.h" + +#include + +#include "libnm-glib-aux/nm-str-buf.h" + +#include "nm-keyfile.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wireless-security.h" + +#include "libnm-core-intern/nm-keyfile-internal.h" + +/*****************************************************************************/ + +/** + * nm_key_file_get_boolean: + * @kf: the #GKeyFile + * @group: the group + * @key: the key + * @default_value: the default value if the value is set or not parsable as a boolean. + * + * Replacement for g_key_file_get_boolean() (which uses g_key_file_parse_value_as_boolean()). + * g_key_file_get_boolean() seems odd to me, because it accepts trailing ASCII whitespace, + * but not leading. + * This uses _nm_utils_ascii_str_to_bool(), which accepts trailing and leading whitespace, + * case-insensitive words, and also strings like "on" and "off". + * _nm_utils_ascii_str_to_bool() is our way to parse booleans from string, and we should + * use that one consistently. + * + * Also, it doesn't have g_key_file_get_boolean()'s odd API to require an error argument + * to detect parsing failures. + * + * Returns: either %TRUE or %FALSE if the key exists and is parsable as a boolean. + * Otherwise, @default_value. Sets errno to ENODATA, EINVAL or 0, depending on whether + * the key exists, whether the value is invalid, or success. + */ +int +nm_key_file_get_boolean(GKeyFile *kf, const char *group, const char *key, int default_value) +{ + int v; + gs_free char *value = NULL; + + value = g_key_file_get_value(kf, group, key, NULL); + + if (!value) { + errno = ENODATA; + return default_value; + } + v = _nm_utils_ascii_str_to_bool(value, -1); + if (v != -1) { + errno = 0; + return v; + } + errno = EINVAL; + return default_value; +} + +/*****************************************************************************/ + +typedef struct { + const char *setting; + const char *alias; +} SettingAlias; + +static const SettingAlias alias_list[] = { + {NM_SETTING_WIRED_SETTING_NAME, "ethernet"}, + {NM_SETTING_WIRELESS_SETTING_NAME, "wifi"}, + {NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, "wifi-security"}, +}; + +const char * +nm_keyfile_plugin_get_alias_for_setting_name(const char *setting_name) +{ + guint i; + + g_return_val_if_fail(setting_name != NULL, NULL); + + for (i = 0; i < G_N_ELEMENTS(alias_list); i++) { + if (nm_streq(setting_name, alias_list[i].setting)) + return alias_list[i].alias; + } + return NULL; +} + +const char * +nm_keyfile_plugin_get_setting_name_for_alias(const char *alias) +{ + guint i; + + g_return_val_if_fail(alias != NULL, NULL); + + for (i = 0; i < G_N_ELEMENTS(alias_list); i++) { + if (nm_streq(alias, alias_list[i].alias)) + return alias_list[i].setting; + } + return NULL; +} + +/*****************************************************************************/ + +char ** +nm_keyfile_plugin_kf_get_string_list(GKeyFile * kf, + const char *group, + const char *key, + gsize * out_length, + GError ** error) +{ + char ** list; + const char *alias; + GError * local = NULL; + gsize l; + + list = g_key_file_get_string_list(kf, group, key, &l, &local); + if (nm_g_error_matches(local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { + alias = nm_keyfile_plugin_get_alias_for_setting_name(group); + if (alias) { + g_clear_error(&local); + list = g_key_file_get_string_list(kf, alias, key, &l, &local); + } + } + if (local) + g_propagate_error(error, local); + if (!list) + l = 0; + NM_SET_OUT(out_length, l); + return list; +} + +guint * +nm_keyfile_plugin_kf_get_integer_list_uint(GKeyFile * key_file, + const char *group_name, + const char *key, + gsize * out_length, + GError ** error) +{ + GError * key_file_error = NULL; + gs_strfreev char **values = NULL; + gs_free guint *int_values = NULL; + gsize i, num_ints; + + NM_SET_OUT(out_length, 0); + + g_return_val_if_fail(key_file != NULL, NULL); + g_return_val_if_fail(group_name != NULL, NULL); + g_return_val_if_fail(key != NULL, NULL); + + values = + nm_keyfile_plugin_kf_get_string_list(key_file, group_name, key, &num_ints, &key_file_error); + + if (key_file_error) + g_propagate_error(error, key_file_error); + if (!values) + return NULL; + + int_values = g_new(guint, num_ints); + + for (i = 0; i < num_ints; i++) { + gint64 v; + + G_STATIC_ASSERT_EXPR(sizeof(v) > sizeof(guint)); + v = _nm_utils_ascii_str_to_int64(values[i], 10, 0, G_MAXUINT, -1); + if (v == -1) { + g_set_error(error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value cannot be interpreted as a list of numbers.")); + return NULL; + } + + int_values[i] = v; + } + + NM_SET_OUT(out_length, num_ints); + return g_steal_pointer(&int_values); +} + +void +nm_keyfile_plugin_kf_set_string_list(GKeyFile * kf, + const char * group, + const char * key, + const char *const *list, + gsize length) +{ + const char *alias; + + alias = nm_keyfile_plugin_get_alias_for_setting_name(group); + g_key_file_set_string_list(kf, alias ?: group, key, list, length); +} + +void +nm_keyfile_plugin_kf_set_integer_list_uint(GKeyFile * kf, + const char * group, + const char * key, + const guint *data, + gsize length) +{ + nm_auto_str_buf NMStrBuf strbuf = {}; + gsize i; + + g_return_if_fail(kf); + g_return_if_fail(!length || data); + g_return_if_fail(group && group[0]); + g_return_if_fail(key && key[0]); + + nm_str_buf_init(&strbuf, length * 4u + 2u, FALSE); + for (i = 0; i < length; i++) + nm_str_buf_append_printf(&strbuf, "%u;", data[i]); + nm_keyfile_plugin_kf_set_value(kf, group, key, nm_str_buf_get_str(&strbuf)); +} + +void +nm_keyfile_plugin_kf_set_integer_list_uint8(GKeyFile * kf, + const char * group, + const char * key, + const guint8 *data, + gsize length) +{ + nm_auto_str_buf NMStrBuf strbuf = {}; + gsize i; + + g_return_if_fail(kf); + g_return_if_fail(!length || data); + g_return_if_fail(group && group[0]); + g_return_if_fail(key && key[0]); + + nm_str_buf_init(&strbuf, length * 4u + 2u, FALSE); + for (i = 0; i < length; i++) + nm_str_buf_append_printf(&strbuf, "%u;", (guint) data[i]); + nm_keyfile_plugin_kf_set_value(kf, group, key, nm_str_buf_get_str(&strbuf)); +} + +#define DEFINE_KF_WRAPPER_GET(fcn_name, get_ctype, key_file_get_fcn) \ + get_ctype fcn_name(GKeyFile *kf, const char *group, const char *key, GError **error) \ + { \ + get_ctype val; \ + const char *alias; \ + GError * local = NULL; \ + \ + val = key_file_get_fcn(kf, group, key, &local); \ + if (nm_g_error_matches(local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \ + alias = nm_keyfile_plugin_get_alias_for_setting_name(group); \ + if (alias) { \ + g_clear_error(&local); \ + val = key_file_get_fcn(kf, alias, key, &local); \ + } \ + } \ + if (local) \ + g_propagate_error(error, local); \ + return val; \ + } + +DEFINE_KF_WRAPPER_GET(nm_keyfile_plugin_kf_get_string, char *, g_key_file_get_string); +DEFINE_KF_WRAPPER_GET(nm_keyfile_plugin_kf_get_boolean, gboolean, g_key_file_get_boolean); +DEFINE_KF_WRAPPER_GET(nm_keyfile_plugin_kf_get_value, char *, g_key_file_get_value); + +#define DEFINE_KF_WRAPPER_SET(fcn_name, set_ctype, key_file_set_fcn) \ + void fcn_name(GKeyFile *kf, const char *group, const char *key, set_ctype value) \ + { \ + const char *alias; \ + \ + alias = nm_keyfile_plugin_get_alias_for_setting_name(group); \ + key_file_set_fcn(kf, alias ?: group, key, value); \ + } + +DEFINE_KF_WRAPPER_SET(nm_keyfile_plugin_kf_set_string, const char *, g_key_file_set_string); +DEFINE_KF_WRAPPER_SET(nm_keyfile_plugin_kf_set_boolean, gboolean, g_key_file_set_boolean); +DEFINE_KF_WRAPPER_SET(nm_keyfile_plugin_kf_set_value, const char *, g_key_file_set_value); + +gint64 +nm_keyfile_plugin_kf_get_int64(GKeyFile * kf, + const char *group, + const char *key, + guint base, + gint64 min, + gint64 max, + gint64 fallback, + GError ** error) +{ + gs_free char *s = NULL; + int errsv; + gint64 v; + + s = nm_keyfile_plugin_kf_get_value(kf, group, key, error); + if (!s) { + errno = ENODATA; + return fallback; + } + + v = _nm_utils_ascii_str_to_int64(s, base, min, max, fallback); + errsv = errno; + if (errsv != 0 && error) { + g_set_error(error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("value is not an integer in range [%lld, %lld]"), + (long long) min, + (long long) max); + errno = errsv; + } + return v; +} + +char ** +nm_keyfile_plugin_kf_get_keys(GKeyFile *kf, const char *group, gsize *out_length, GError **error) +{ + char ** keys; + const char *alias; + GError * local = NULL; + gsize l; + + keys = g_key_file_get_keys(kf, group, &l, &local); + if (nm_g_error_matches(local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { + alias = nm_keyfile_plugin_get_alias_for_setting_name(group); + if (alias) { + g_clear_error(&local); + keys = g_key_file_get_keys(kf, alias, &l, error ? &local : NULL); + } + } + nm_assert((!local) != (!keys)); + if (!keys) + l = 0; + nm_assert(l == NM_PTRARRAY_LEN(keys)); + NM_SET_OUT(out_length, l); + if (local) + g_propagate_error(error, local); + return keys; +} + +gboolean +nm_keyfile_plugin_kf_has_key(GKeyFile *kf, const char *group, const char *key, GError **error) +{ + gboolean has; + const char *alias; + GError * local = NULL; + + has = g_key_file_has_key(kf, group, key, &local); + if (nm_g_error_matches(local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { + alias = nm_keyfile_plugin_get_alias_for_setting_name(group); + if (alias) { + g_clear_error(&local); + has = g_key_file_has_key(kf, alias, key, &local); + } + } + if (local) + g_propagate_error(error, local); + return has; +} + +/*****************************************************************************/ + +void +_nm_keyfile_copy(GKeyFile *dst, GKeyFile *src) +{ + gs_strfreev char **groups = NULL; + guint g, k; + + groups = g_key_file_get_groups(src, NULL); + for (g = 0; groups && groups[g]; g++) { + const char * group = groups[g]; + gs_strfreev char **keys = NULL; + + keys = g_key_file_get_keys(src, group, NULL, NULL); + if (!keys) + continue; + + for (k = 0; keys[k]; k++) { + const char * key = keys[k]; + gs_free char *value = NULL; + + value = g_key_file_get_value(src, group, key, NULL); + if (value) + g_key_file_set_value(dst, group, key, value); + else + g_key_file_remove_key(dst, group, key, NULL); + } + } +} + +/*****************************************************************************/ + +gboolean +_nm_keyfile_a_contains_all_in_b(GKeyFile *kf_a, GKeyFile *kf_b) +{ + gs_strfreev char **groups = NULL; + guint i, j; + + if (kf_a == kf_b) + return TRUE; + if (!kf_a || !kf_b) + return FALSE; + + groups = g_key_file_get_groups(kf_a, NULL); + for (i = 0; groups && groups[i]; i++) { + gs_strfreev char **keys = NULL; + + keys = g_key_file_get_keys(kf_a, groups[i], NULL, NULL); + if (!keys) + continue; + + for (j = 0; keys[j]; j++) { + gs_free char *key_a = g_key_file_get_value(kf_a, groups[i], keys[j], NULL); + gs_free char *key_b = g_key_file_get_value(kf_b, groups[i], keys[j], NULL); + + if (g_strcmp0(key_a, key_b) != 0) + return FALSE; + } + } + return TRUE; +} + +static gboolean +_nm_keyfile_equals_ordered(GKeyFile *kf_a, GKeyFile *kf_b) +{ + gs_strfreev char **groups = NULL; + gs_strfreev char **groups_b = NULL; + guint i, j; + + if (kf_a == kf_b) + return TRUE; + if (!kf_a || !kf_b) + return FALSE; + + groups = g_key_file_get_groups(kf_a, NULL); + groups_b = g_key_file_get_groups(kf_b, NULL); + if (!groups && !groups_b) + return TRUE; + if (!groups || !groups_b) + return FALSE; + for (i = 0; groups[i] && groups_b[i] && !strcmp(groups[i], groups_b[i]); i++) + ; + if (groups[i] || groups_b[i]) + return FALSE; + + for (i = 0; groups[i]; i++) { + gs_strfreev char **keys = NULL; + gs_strfreev char **keys_b = NULL; + + keys = g_key_file_get_keys(kf_a, groups[i], NULL, NULL); + keys_b = g_key_file_get_keys(kf_b, groups[i], NULL, NULL); + + if ((!keys) != (!keys_b)) + return FALSE; + if (!keys) + continue; + + for (j = 0; keys[j] && keys_b[j] && !strcmp(keys[j], keys_b[j]); j++) + ; + if (keys[j] || keys_b[j]) + return FALSE; + + for (j = 0; keys[j]; j++) { + gs_free char *key_a = g_key_file_get_value(kf_a, groups[i], keys[j], NULL); + gs_free char *key_b = g_key_file_get_value(kf_b, groups[i], keys[j], NULL); + + if (g_strcmp0(key_a, key_b) != 0) + return FALSE; + } + } + return TRUE; +} + +gboolean +_nm_keyfile_equals(GKeyFile *kf_a, GKeyFile *kf_b, gboolean consider_order) +{ + if (!consider_order) { + return _nm_keyfile_a_contains_all_in_b(kf_a, kf_b) + && _nm_keyfile_a_contains_all_in_b(kf_b, kf_a); + } else { + return _nm_keyfile_equals_ordered(kf_a, kf_b); + } +} + +gboolean +_nm_keyfile_has_values(GKeyFile *keyfile) +{ + gs_strfreev char **groups = NULL; + + g_return_val_if_fail(keyfile, FALSE); + + groups = g_key_file_get_groups(keyfile, NULL); + return groups && groups[0]; +} + +/*****************************************************************************/ + +static const char * +_keyfile_key_encode(const char *name, char **out_to_free) +{ + NMStrBuf str; + gsize len; + gsize i; + + nm_assert(name); + nm_assert(out_to_free && !*out_to_free); + + /* See g_key_file_is_key_name(). + * + * GKeyFile allows all UTF-8 characters (even non-well formed sequences), + * except: + * - no empty keys + * - no leading/trailing ' ' + * - no '=', '[', ']' + * + * We do something more strict here. All non-ASCII characters, all non-printable + * characters, and all invalid characters are escaped with "\\XX". + * + * We don't escape \\, unless it is followed by two hex digits. + */ + + if (!name[0]) { + /* empty keys are backslash encoded. Note that usually + * \\00 is not a valid encode, the only exception is the empty + * word. */ + return "\\00"; + } + + /* find the first character that needs escaping. */ + i = 0; + if (name[0] != ' ') { + for (;; i++) { + const guchar ch = (guchar) name[i]; + + if (ch == '\0') + return name; + + if (ch < 0x20 || ch >= 127 || NM_IN_SET(ch, '=', '[', ']') + || (ch == '\\' && g_ascii_isxdigit(name[i + 1]) && g_ascii_isxdigit(name[i + 2])) + || (ch == ' ' && name[i + 1] == '\0')) + break; + } + } else if (name[1] == '\0') + return "\\20"; + + len = i + strlen(&name[i]); + nm_assert(len == strlen(name)); + + nm_str_buf_init(&str, len + 15u, FALSE); + + if (name[0] == ' ') { + nm_assert(i == 0); + nm_str_buf_append(&str, "\\20"); + i = 1; + } else + nm_str_buf_append_len(&str, name, i); + + for (;; i++) { + const guchar ch = (guchar) name[i]; + + if (ch == '\0') + break; + + if (ch < 0x20 || ch >= 127 || NM_IN_SET(ch, '=', '[', ']') + || (ch == '\\' && g_ascii_isxdigit(name[i + 1]) && g_ascii_isxdigit(name[i + 2])) + || (ch == ' ' && name[i + 1] == '\0')) { + nm_str_buf_append_c(&str, '\\'); + nm_str_buf_append_c_hex(&str, ch, TRUE); + } else + nm_str_buf_append_c(&str, (char) ch); + } + + return (*out_to_free = nm_str_buf_finalize(&str, NULL)); +} + +static const char * +_keyfile_key_decode(const char *key, char **out_to_free) +{ + char *out; + gsize len; + gsize i; + gsize j; + + nm_assert(key); + nm_assert(out_to_free && !*out_to_free); + + if (!key[0]) + return ""; + + for (i = 0; TRUE; i++) { + const char ch = key[i]; + + if (ch == '\0') + return key; + if (ch == '\\' && g_ascii_isxdigit(key[i + 1]) && g_ascii_isxdigit(key[i + 2])) + break; + } + + len = i + strlen(&key[i]); + + if (len == 3 && nm_streq(key, "\\00")) + return ""; + + nm_assert(len == strlen(key)); + + out = g_new(char, len + 1u); + + memcpy(out, key, sizeof(char) * i); + + j = i; + for (;;) { + const char ch = key[i]; + char ch1, ch2; + unsigned v; + + if (ch == '\0') + break; + + if (ch == '\\' && g_ascii_isxdigit((ch1 = key[i + 1])) + && g_ascii_isxdigit((ch2 = key[i + 2]))) { + v = (g_ascii_xdigit_value(ch1) << 4) + g_ascii_xdigit_value(ch2); + if (v != 0) { + out[j++] = (char) v; + i += 3; + continue; + } + } + out[j++] = ch; + i++; + } + + nm_assert(j <= len); + out[j] = '\0'; + return (*out_to_free = out); +} + +/*****************************************************************************/ + +const char * +nm_keyfile_key_encode(const char *name, char **out_to_free) +{ + const char *key; + + key = _keyfile_key_encode(name, out_to_free); +#if NM_MORE_ASSERTS > 5 + nm_assert(key); + nm_assert(!*out_to_free || key == *out_to_free); + nm_assert(!*out_to_free || !nm_streq0(name, key)); + { + gs_free char *to_free2 = NULL; + const char * name2; + + name2 = _keyfile_key_decode(key, &to_free2); + /* name2, the result of encode()+decode() is identical to name. + * That is because + * - encode() is a injective function. + * - decode() is a surjective function, however for output + * values of encode() is behaves injective too. */ + nm_assert(nm_streq0(name2, name)); + } +#endif + return key; +} + +const char * +nm_keyfile_key_decode(const char *key, char **out_to_free) +{ + const char *name; + + name = _keyfile_key_decode(key, out_to_free); +#if NM_MORE_ASSERTS > 5 + nm_assert(name); + nm_assert(!*out_to_free || name == *out_to_free); + { + gs_free char *to_free2 = NULL; + const char * key2; + + key2 = _keyfile_key_encode(name, &to_free2); + /* key2, the result of decode+encode may not be identical + * to the original key. That is, decode() is a surjective + * function mapping different keys to the same name. + * However, decode() behaves injective for input that + * are valid output of encode(). */ + nm_assert(key2); + } +#endif + return name; +} diff --git a/src/libnm-core-impl/nm-keyfile.c b/src/libnm-core-impl/nm-keyfile.c new file mode 100644 index 0000000..bd89345 --- /dev/null +++ b/src/libnm-core-impl/nm-keyfile.c @@ -0,0 +1,4443 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 - 2009 Novell, Inc. + * Copyright (C) 2008 - 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "libnm-core-intern/nm-keyfile-internal.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" +#include "libnm-core-aux-intern/nm-common-macros.h" + +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-keyfile.h" +#include "nm-setting-user.h" +#include "nm-setting-ovs-external-ids.h" + +#include "libnm-core-intern/nm-keyfile-utils.h" + +#define ETHERNET_S390_OPTIONS_GROUP_NAME "ethernet-s390-options" + +#define OVS_EXTERNAL_IDS_DATA_PREFIX "data." + +/*****************************************************************************/ + +typedef struct _ParseInfoProperty ParseInfoProperty; + +typedef struct { + NMConnection * connection; + GKeyFile * keyfile; + const char * base_dir; + NMKeyfileReadHandler read_handler; + void * user_data; + GError * error; + const char * group; + NMSetting * setting; +} KeyfileReaderInfo; + +typedef struct { + NMConnection * connection; + GKeyFile * keyfile; + GError * error; + NMKeyfileWriteHandler write_handler; + void * user_data; +} KeyfileWriterInfo; + +/*****************************************************************************/ + +static void +_key_file_handler_data_init(NMKeyfileHandlerData *handler_data, + NMKeyfileHandlerType handler_type, + const char * kf_group_name, + const char * kf_key, + NMSetting * cur_setting, + const char * cur_property, + GError ** p_error) +{ + nm_assert(handler_data); + nm_assert(p_error && !*p_error); + + handler_data->type = handler_type; + handler_data->p_error = p_error; + handler_data->kf_group_name = kf_group_name; + handler_data->kf_key = kf_key; + handler_data->cur_setting = cur_setting; + handler_data->cur_property = cur_property; +} + +static void +_key_file_handler_data_init_read(NMKeyfileHandlerData *handler_data, + NMKeyfileHandlerType handler_type, + KeyfileReaderInfo * info, + const char * kf_key, + const char * cur_property) +{ + _key_file_handler_data_init(handler_data, + handler_type, + info->group, + kf_key, + info->setting, + cur_property, + &info->error); +} + +static void +_key_file_handler_data_init_write(NMKeyfileHandlerData *handler_data, + NMKeyfileHandlerType handler_type, + KeyfileWriterInfo * info, + const char * kf_group, + const char * kf_key, + NMSetting * cur_setting, + const char * cur_property) +{ + _key_file_handler_data_init(handler_data, + handler_type, + kf_group, + kf_key, + cur_setting, + cur_property, + &info->error); +} + +_nm_printf(5, 6) static void _handle_warn(KeyfileReaderInfo * info, + const char * kf_key, + const char * cur_property, + NMKeyfileWarnSeverity severity, + const char * fmt, + ...) +{ + NMKeyfileHandlerData handler_data; + + _key_file_handler_data_init_read(&handler_data, + NM_KEYFILE_HANDLER_TYPE_WARN, + info, + kf_key, + cur_property); + handler_data.warn = (NMKeyfileHandlerDataWarn){ + .severity = severity, + .message = NULL, + .fmt = fmt, + }; + + va_start(handler_data.warn.ap, fmt); + + info->read_handler(info->keyfile, + info->connection, + NM_KEYFILE_HANDLER_TYPE_WARN, + &handler_data, + info->user_data); + + va_end(handler_data.warn.ap); + + g_free(handler_data.warn.message); +} + +#define handle_warn(arg_info, arg_kf_key, arg_property_name, arg_severity, ...) \ + ({ \ + KeyfileReaderInfo *_info = (arg_info); \ + \ + nm_assert(!_info->error); \ + \ + if (_info->read_handler) { \ + _handle_warn(_info, (arg_kf_key), (arg_property_name), (arg_severity), __VA_ARGS__); \ + } \ + _info->error == NULL; \ + }) + +/*****************************************************************************/ + +static gboolean +_secret_flags_persist_secret(NMSettingSecretFlags flags) +{ + return flags == NM_SETTING_SECRET_FLAG_NONE; +} + +/*****************************************************************************/ +/* Some setting properties also contain setting names, such as + * NMSettingConnection's 'type' property (which specifies the base type of the + * connection, e.g. ethernet or wifi) or 'slave-type' (specifies type of slave + * connection, e.g. bond or bridge). This function handles translating those + * properties' values to the real setting name if they are an alias. + */ +static void +setting_alias_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char * setting_name = nm_setting_get_name(setting); + const char * key_setting_name; + gs_free char *s = NULL; + + s = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL); + if (!s) + return; + + key_setting_name = nm_keyfile_plugin_get_setting_name_for_alias(s); + g_object_set(G_OBJECT(setting), key, key_setting_name ?: s, NULL); +} + +static void +sriov_vfs_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char * setting_name = nm_setting_get_name(setting); + gs_unref_ptrarray GPtrArray *vfs = NULL; + gs_strfreev char ** keys = NULL; + gsize n_keys = 0; + int i; + + keys = nm_keyfile_plugin_kf_get_keys(info->keyfile, setting_name, &n_keys, NULL); + if (n_keys == 0) + return; + + vfs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_sriov_vf_unref); + + for (i = 0; i < n_keys; i++) { + gs_free char *value = NULL; + NMSriovVF * vf; + const char * rest; + + if (!g_str_has_prefix(keys[i], "vf.")) + continue; + + rest = &keys[i][3]; + + if (!NM_STRCHAR_ALL(rest, ch, g_ascii_isdigit(ch))) + continue; + + value = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, keys[i], NULL); + + vf = _nm_utils_sriov_vf_from_strparts(rest, value, TRUE, NULL); + if (vf) + g_ptr_array_add(vfs, vf); + } + + g_object_set(G_OBJECT(setting), key, vfs, NULL); +} + +static void +read_array_of_uint(GKeyFile *file, NMSetting *setting, const char *key) +{ + gs_unref_array GArray *array = NULL; + gs_free_error GError *error = NULL; + gs_free guint *tmp = NULL; + gsize length; + + tmp = nm_keyfile_plugin_kf_get_integer_list_uint(file, + nm_setting_get_name(setting), + key, + &length, + &error); + if (error) + return; + + array = g_array_sized_new(FALSE, FALSE, sizeof(guint), length); + g_array_append_vals(array, tmp, length); + g_object_set(setting, key, array, NULL); +} + +static gboolean +get_one_int(KeyfileReaderInfo *info, + const char * kf_key, + const char * property_name, + const char * str, + guint32 max_val, + guint32 * out) +{ + gint64 tmp; + + nm_assert((!info) == (!property_name)); + nm_assert((!info) == (!kf_key)); + + if (!str || !str[0]) { + if (info) { + handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring missing number")); + } + return FALSE; + } + + tmp = _nm_utils_ascii_str_to_int64(str, 10, 0, max_val, -1); + if (tmp == -1) { + if (info) { + handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring invalid number '%s'"), + str); + } + return FALSE; + } + + *out = (guint32) tmp; + return TRUE; +} + +static gpointer +build_address(KeyfileReaderInfo *info, + const char * kf_key, + const char * property_name, + int family, + const char * address_str, + guint32 plen) +{ + NMIPAddress *addr; + GError * error = NULL; + + g_return_val_if_fail(address_str, NULL); + + addr = nm_ip_address_new(family, address_str, plen, &error); + if (!addr) { + handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring invalid %s address: %s"), + family == AF_INET ? "IPv4" : "IPv6", + error->message); + g_error_free(error); + } + + return addr; +} + +static gpointer +build_route(KeyfileReaderInfo *info, + const char * kf_key, + const char * property_name, + int family, + const char * dest_str, + guint32 plen, + const char * gateway_str, + const char * metric_str) +{ + NMIPRoute *route; + guint32 u32; + gint64 metric = -1; + GError * error = NULL; + + g_return_val_if_fail(dest_str, NULL); + + /* Next hop */ + if (gateway_str && gateway_str[0]) { + if (!nm_utils_ipaddr_is_valid(family, gateway_str)) { + /* Try workaround for routes written by broken keyfile writer. + * Due to bug bgo#719851, an older version of writer would have + * written "a:b:c:d::/plen,metric" if the gateway was ::, instead + * of "a:b:c:d::/plen,,metric" or "a:b:c:d::/plen,::,metric" + * Try workaround by interpreting gateway_str as metric to accept such + * invalid routes. This broken syntax should not be not officially + * supported. + **/ + if (family == AF_INET6 && !metric_str + && get_one_int(NULL, NULL, NULL, gateway_str, G_MAXUINT32, &u32)) { + metric = u32; + gateway_str = NULL; + } else { + handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring invalid gateway '%s' for %s route"), + gateway_str, + family == AF_INET ? "IPv4" : "IPv6"); + return NULL; + } + } + } else + gateway_str = NULL; + + /* parse metric, default to -1 */ + if (metric_str) { + if (!get_one_int(info, kf_key, property_name, metric_str, G_MAXUINT32, &u32)) + return NULL; + metric = u32; + } + + route = nm_ip_route_new(family, dest_str, plen, gateway_str, metric, &error); + if (!route) { + handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring invalid %s route: %s"), + family == AF_INET ? "IPv4" : "IPv6", + error->message); + g_error_free(error); + } + + return route; +} + +/* On success, returns pointer to the zero-terminated field (original @current). + * The @current * pointer target is set to point to the rest of the input + * or %NULL if there is no more input. Sets error to %NULL for convenience. + * + * On failure, returns %NULL (unspecified). The @current pointer target is + * resets to its original value to allow skipping fields. The @error target + * is set to the character that breaks the parsing or %NULL if @current was %NULL. + * + * When @current target is %NULL, gracefully fail returning %NULL while + * leaving the @current target %NULL end setting @error to %NULL; + */ +static const char * +read_field(char **current, const char **out_err_str, const char *characters, const char *delimiters) +{ + const char *start; + + nm_assert(current); + nm_assert(out_err_str); + nm_assert(characters); + nm_assert(delimiters); + + *out_err_str = NULL; + + if (!*current) { + /* graceful failure, leave '*current' NULL */ + return NULL; + } + + /* fail on empty input */ + if (!**current) + return NULL; + + /* remember beginning of input */ + start = *current; + + while (**current && strchr(characters, **current)) + (*current)++; + if (**current) + if (strchr(delimiters, **current)) { + /* success, more data available */ + *(*current)++ = '\0'; + return start; + } else { + /* error, bad character */ + *out_err_str = *current; + *current = (char *) start; + return NULL; + } + else { + /* success, end of input */ + *current = NULL; + return start; + } +} + +/*****************************************************************************/ + +#define NM_DBUS_SERVICE_OPENCONNECT "org.freedesktop.NetworkManager.openconnect" +#define NM_OPENCONNECT_KEY_GATEWAY "gateway" +#define NM_OPENCONNECT_KEY_COOKIE "cookie" +#define NM_OPENCONNECT_KEY_GWCERT "gwcert" +#define NM_OPENCONNECT_KEY_XMLCONFIG "xmlconfig" +#define NM_OPENCONNECT_KEY_LASTHOST "lasthost" +#define NM_OPENCONNECT_KEY_AUTOCONNECT "autoconnect" +#define NM_OPENCONNECT_KEY_CERTSIGS "certsigs" + +static void +openconnect_fix_secret_flags(NMSetting *setting) +{ + NMSettingVpn * s_vpn; + NMSettingSecretFlags flags; + + /* Huge hack. There were some openconnect changes that needed to happen + * pretty late, too late to get into distros. Migration has already + * happened for many people, and their secret flags are wrong. But we + * don't want to require re-migration, so we have to fix it up here. Ugh. + */ + + if (!NM_IS_SETTING_VPN(setting)) + return; + + s_vpn = NM_SETTING_VPN(setting); + + if (!nm_streq0(nm_setting_vpn_get_service_type(s_vpn), NM_DBUS_SERVICE_OPENCONNECT)) + return; + + /* These are different for every login session, and should not be stored */ + flags = NM_SETTING_SECRET_FLAG_NOT_SAVED; + nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_GATEWAY, flags, NULL); + nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_COOKIE, flags, NULL); + nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_GWCERT, flags, NULL); + + /* These are purely internal data for the auth-dialog, and should be stored */ + flags = 0; + nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_XMLCONFIG, flags, NULL); + nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_LASTHOST, flags, NULL); + nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_AUTOCONNECT, flags, NULL); + nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_CERTSIGS, flags, NULL); +} + +/*****************************************************************************/ + +#define IP_ADDRESS_CHARS "0123456789abcdefABCDEF:.%" +#define DIGITS "0123456789" +#define DELIMITERS "/;," + +/* The following IPv4 and IPv6 address formats are supported: + * + * address (DEPRECATED) + * address/plen + * address/gateway (DEPRECATED) + * address/plen,gateway + * + * The following IPv4 and IPv6 route formats are supported: + * + * address/plen (NETWORK dev DEVICE) + * address/plen,gateway (NETWORK via GATEWAY dev DEVICE) + * address/plen,,metric (NETWORK dev DEVICE metric METRIC) + * address/plen,gateway,metric (NETWORK via GATEWAY dev DEVICE metric METRIC) + * + * For backward, forward and sideward compatibility, slash (/), + * semicolon (;) and comma (,) are interchangeable. The choice of + * separator in the above examples is therefore not significant. + * + * Leaving out the prefix length is discouraged and DEPRECATED. The + * default value of IPv6 prefix length was 64 and has not been + * changed. The default for IPv4 is now 24, which is the closest + * IPv4 equivalent. These defaults may just as well be changed to + * match the iproute2 defaults (32 for IPv4 and 128 for IPv6). + */ +static gpointer +read_one_ip_address_or_route(KeyfileReaderInfo *info, + const char * property_name, + const char * setting_name, + const char * kf_key, + gboolean ipv6, + gboolean route, + char ** out_gateway, + NMSetting * setting) +{ + guint plen; + gpointer result; + const char * address_str; + const char * plen_str; + const char * gateway_str; + const char * metric_str; + const char * err_str = NULL; + char * current; + gs_free char *value = NULL; + gs_free char *value_orig = NULL; + +#define VALUE_ORIG() \ + (value_orig \ + ?: (value_orig = \ + nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, kf_key, NULL))) + + value = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, kf_key, NULL); + if (!value) + return NULL; + + current = value; + + /* get address field */ + address_str = read_field(¤t, &err_str, IP_ADDRESS_CHARS, DELIMITERS); + if (err_str) { + handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("unexpected character '%c' for address %s: '%s' (position %td)"), + *err_str, + kf_key, + VALUE_ORIG(), + err_str - current); + return NULL; + } + /* get prefix length field (skippable) */ + plen_str = read_field(¤t, &err_str, DIGITS, DELIMITERS); + /* get gateway field */ + gateway_str = read_field(¤t, &err_str, IP_ADDRESS_CHARS, DELIMITERS); + if (err_str) { + handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("unexpected character '%c' for %s: '%s' (position %td)"), + *err_str, + kf_key, + VALUE_ORIG(), + err_str - current); + return NULL; + } + /* for routes, get metric */ + if (route) { + metric_str = read_field(¤t, &err_str, DIGITS, DELIMITERS); + if (err_str) { + handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("unexpected character '%c' in prefix length for %s: '%s' (position %td)"), + *err_str, + kf_key, + VALUE_ORIG(), + err_str - current); + return NULL; + } + } else + metric_str = NULL; + if (current) { + /* there is still some data */ + if (*current) { + /* another field follows */ + handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("garbage at the end of value %s: '%s'"), + kf_key, + VALUE_ORIG()); + return NULL; + } else { + /* semicolon at the end of input */ + if (!handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_INFO, + _("deprecated semicolon at the end of value %s: '%s'"), + kf_key, + VALUE_ORIG())) + return NULL; + } + } + +#define DEFAULT_PREFIX(for_route, for_ipv6) \ + ((for_route) ? ((for_ipv6) ? 128 : 24) : ((for_ipv6) ? 64 : 24)) + + /* parse plen, fallback to defaults */ + if (plen_str) { + if (!get_one_int(info, kf_key, property_name, plen_str, ipv6 ? 128 : 32, &plen)) { + plen = DEFAULT_PREFIX(route, ipv6); + if (info->error + || !handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid prefix length for %s '%s', defaulting to %d"), + kf_key, + VALUE_ORIG(), + plen)) + return NULL; + } + } else { + plen = DEFAULT_PREFIX(route, ipv6); + if (!handle_warn(info, + kf_key, + property_name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("missing prefix length for %s '%s', defaulting to %d"), + kf_key, + VALUE_ORIG(), + plen)) + return NULL; + } + + /* build the appropriate data structure for NetworkManager settings */ + if (route) { + result = build_route(info, + kf_key, + property_name, + ipv6 ? AF_INET6 : AF_INET, + address_str, + plen, + gateway_str, + metric_str); + } else { + result = build_address(info, + kf_key, + property_name, + ipv6 ? AF_INET6 : AF_INET, + address_str, + plen); + if (!result) + return NULL; + if (gateway_str) + NM_SET_OUT(out_gateway, g_strdup(gateway_str)); + } + +#undef VALUE_ORIG + + return result; +} + +static void +fill_route_attributes(GKeyFile * kf, + NMIPRoute * route, + const char *setting, + const char *key, + int family) +{ + gs_free char * value = NULL; + gs_unref_hashtable GHashTable *hash = NULL; + GHashTableIter iter; + char * name; + GVariant * variant; + + value = nm_keyfile_plugin_kf_get_string(kf, setting, key, NULL); + if (!value || !value[0]) + return; + + hash = nm_utils_parse_variant_attributes(value, + ',', + '=', + TRUE, + nm_ip_route_get_variant_attribute_spec(), + NULL); + if (hash) { + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) { + if (nm_ip_route_attribute_validate(name, variant, family, NULL, NULL)) + nm_ip_route_set_attribute(route, name, g_variant_ref(variant)); + } + } +} + +typedef struct { + const char *s_key; + gint32 key_idx; + gint8 key_type; +} BuildListData; + +typedef enum { + BUILD_LIST_TYPE_ADDRESSES, + BUILD_LIST_TYPE_ROUTES, + BUILD_LIST_TYPE_ROUTING_RULES, +} BuildListType; + +static int +_build_list_data_cmp(gconstpointer p_a, gconstpointer p_b, gpointer user_data) +{ + const BuildListData *a = p_a; + const BuildListData *b = p_b; + + NM_CMP_FIELD(a, b, key_idx); + NM_CMP_FIELD(a, b, key_type); + NM_CMP_FIELD_STR(a, b, s_key); + return 0; +} + +static gboolean +_build_list_data_is_shadowed(const BuildListData *build_list, gsize build_list_len, gsize idx) +{ + /* the keyfile contains duplicate keys, which are both returned + * by g_key_file_get_keys() (WHY??). + * + * Skip the earlier one. */ + return idx + 1 < build_list_len && build_list[idx].key_idx == build_list[idx + 1].key_idx + && build_list[idx].key_type == build_list[idx + 1].key_type + && nm_streq(build_list[idx].s_key, build_list[idx + 1].s_key); +} + +static gboolean +_build_list_match_key_w_name_impl(const char *key, + const char *base_name, + gsize base_name_l, + gint32 * out_key_idx) +{ + gint64 v; + + /* some very strict parsing. */ + + /* the key must start with base_name. */ + if (strncmp(key, base_name, base_name_l) != 0) + return FALSE; + + key += base_name_l; + if (key[0] == '\0') { + /* if key is identical to base_name, that's good. */ + NM_SET_OUT(out_key_idx, -1); + return TRUE; + } + + /* if base_name is followed by a zero, then it must be + * only a zero, nothing else. */ + if (key[0] == '0') { + if (key[1] != '\0') + return FALSE; + NM_SET_OUT(out_key_idx, 0); + return TRUE; + } + + /* otherwise, it can only be followed by a non-zero decimal. */ + if (!(key[0] >= '1' && key[0] <= '9')) + return FALSE; + /* and all remaining chars must be decimals too. */ + if (!NM_STRCHAR_ALL(&key[1], ch, g_ascii_isdigit(ch))) + return FALSE; + + /* and it must be convertible to a (positive) int. */ + v = _nm_utils_ascii_str_to_int64(key, 10, 0, G_MAXINT32, -1); + if (v < 0) + return FALSE; + + /* good */ + NM_SET_OUT(out_key_idx, v); + return TRUE; +} + +#define _build_list_match_key_w_name(key, base_name, out_key_idx) \ + _build_list_match_key_w_name_impl(key, base_name, NM_STRLEN(base_name), out_key_idx) + +static BuildListData * +_build_list_create(GKeyFile * keyfile, + const char * group_name, + BuildListType build_list_type, + gsize * out_build_list_len, + char *** out_keys_strv) +{ + gs_strfreev char **keys = NULL; + gsize i_keys, n_keys; + gs_free BuildListData *build_list = NULL; + gsize build_list_len = 0; + + nm_assert(out_build_list_len && *out_build_list_len == 0); + nm_assert(out_keys_strv && !*out_keys_strv); + + keys = nm_keyfile_plugin_kf_get_keys(keyfile, group_name, &n_keys, NULL); + if (n_keys == 0) + return NULL; + + for (i_keys = 0; i_keys < n_keys; i_keys++) { + const char *s_key = keys[i_keys]; + gint32 key_idx; + gint8 key_type = 0; + + switch (build_list_type) { + case BUILD_LIST_TYPE_ROUTES: + if (_build_list_match_key_w_name(s_key, "route", &key_idx)) + key_type = 0; + else if (_build_list_match_key_w_name(s_key, "routes", &key_idx)) + key_type = 1; + else + continue; + break; + case BUILD_LIST_TYPE_ADDRESSES: + if (_build_list_match_key_w_name(s_key, "address", &key_idx)) + key_type = 0; + else if (_build_list_match_key_w_name(s_key, "addresses", &key_idx)) + key_type = 1; + else + continue; + break; + case BUILD_LIST_TYPE_ROUTING_RULES: + if (_build_list_match_key_w_name(s_key, "routing-rule", &key_idx)) + key_type = 0; + else + continue; + break; + default: + nm_assert_not_reached(); + break; + } + + if (G_UNLIKELY(!build_list)) + build_list = g_new(BuildListData, n_keys - i_keys); + + build_list[build_list_len++] = (BuildListData){ + .s_key = s_key, + .key_idx = key_idx, + .key_type = key_type, + }; + } + + if (build_list_len == 0) + return NULL; + + if (build_list_len > 1) { + g_qsort_with_data(build_list, + build_list_len, + sizeof(BuildListData), + _build_list_data_cmp, + NULL); + } + + *out_build_list_len = build_list_len; + *out_keys_strv = g_steal_pointer(&keys); + return g_steal_pointer(&build_list); +} + +static void +ip_address_or_route_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *setting_key) +{ + const char * setting_name = nm_setting_get_name(setting); + gboolean is_ipv6 = nm_streq(setting_name, "ipv6"); + gboolean is_routes = nm_streq(setting_key, "routes"); + gs_free char * gateway = NULL; + gs_unref_ptrarray GPtrArray *list = NULL; + gs_strfreev char ** keys = NULL; + gs_free BuildListData *build_list = NULL; + gsize i_build_list, build_list_len = 0; + + build_list = _build_list_create(info->keyfile, + setting_name, + is_routes ? BUILD_LIST_TYPE_ROUTES : BUILD_LIST_TYPE_ADDRESSES, + &build_list_len, + &keys); + if (!build_list) + return; + + list = g_ptr_array_new_with_free_func(is_routes ? (GDestroyNotify) nm_ip_route_unref + : (GDestroyNotify) nm_ip_address_unref); + + for (i_build_list = 0; i_build_list < build_list_len; i_build_list++) { + const char *s_key; + gpointer item; + + if (_build_list_data_is_shadowed(build_list, build_list_len, i_build_list)) + continue; + + s_key = build_list[i_build_list].s_key; + item = read_one_ip_address_or_route(info, + setting_key, + setting_name, + s_key, + is_ipv6, + is_routes, + gateway ? NULL : &gateway, + setting); + if (item && is_routes) { + char options_key[128]; + + nm_sprintf_buf(options_key, "%s_options", s_key); + fill_route_attributes(info->keyfile, + item, + setting_name, + options_key, + is_ipv6 ? AF_INET6 : AF_INET); + } + + if (info->error) + return; + + if (item) + g_ptr_array_add(list, item); + } + + if (list->len >= 1) + g_object_set(setting, setting_key, list, NULL); + + if (gateway) + g_object_set(setting, "gateway", gateway, NULL); +} + +static void +ip_routing_rule_parser_full(KeyfileReaderInfo * info, + const NMMetaSettingInfo * setting_info, + const NMSettInfoProperty *property_info, + const ParseInfoProperty * pip, + NMSetting * setting) +{ + const char * setting_name = nm_setting_get_name(setting); + gboolean is_ipv6 = nm_streq(setting_name, "ipv6"); + gs_strfreev char **keys = NULL; + gs_free BuildListData *build_list = NULL; + gsize i_build_list, build_list_len = 0; + + build_list = _build_list_create(info->keyfile, + setting_name, + BUILD_LIST_TYPE_ROUTING_RULES, + &build_list_len, + &keys); + if (!build_list) + return; + + for (i_build_list = 0; i_build_list < build_list_len; i_build_list++) { + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL; + gs_free char * value = NULL; + gs_free_error GError *local = NULL; + + if (_build_list_data_is_shadowed(build_list, build_list_len, i_build_list)) + continue; + + value = nm_keyfile_plugin_kf_get_string(info->keyfile, + setting_name, + build_list[i_build_list].s_key, + NULL); + if (!value) + continue; + + rule = nm_ip_routing_rule_from_string( + value, + (NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (is_ipv6 ? NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6 + : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET)), + NULL, + &local); + if (!rule) { + if (!handle_warn(info, + build_list[i_build_list].s_key, + property_info->name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid value for \"%s\": %s"), + build_list[i_build_list].s_key, + local->message)) + return; + continue; + } + + nm_setting_ip_config_add_routing_rule(NM_SETTING_IP_CONFIG(setting), rule); + } +} + +static void +_parser_full_ovs_external_ids_data(KeyfileReaderInfo * info, + const NMMetaSettingInfo * setting_info, + const NMSettInfoProperty *property_info, + const ParseInfoProperty * pip, + NMSetting * setting) +{ + const char * setting_name = NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME; + gs_strfreev char **keys = NULL; + gsize n_keys; + gsize i; + + nm_assert(NM_IS_SETTING_OVS_EXTERNAL_IDS(setting)); + nm_assert(nm_streq(property_info->name, NM_SETTING_OVS_EXTERNAL_IDS_DATA)); + nm_assert(nm_streq(setting_name, setting_info->setting_name)); + nm_assert(nm_streq(setting_name, nm_setting_get_name(setting))); + + keys = nm_keyfile_plugin_kf_get_keys(info->keyfile, setting_name, &n_keys, NULL); + + for (i = 0; i < n_keys; i++) { + const char * key = keys[i]; + gs_free char *name_to_free = NULL; + gs_free char *value = NULL; + const char * name; + + if (!NM_STR_HAS_PREFIX(key, OVS_EXTERNAL_IDS_DATA_PREFIX)) + continue; + + value = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL); + if (!value) + continue; + + name = &key[NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX)]; + name = nm_keyfile_key_decode(name, &name_to_free); + nm_setting_ovs_external_ids_set_data(NM_SETTING_OVS_EXTERNAL_IDS(setting), name, value); + } +} + +static void +ip_dns_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + int addr_family; + gs_strfreev char **list = NULL; + gsize i, n, length; + + nm_assert(NM_IS_SETTING_IP4_CONFIG(setting) || NM_IS_SETTING_IP6_CONFIG(setting)); + + list = nm_keyfile_plugin_kf_get_string_list(info->keyfile, + nm_setting_get_name(setting), + key, + &length, + NULL); + nm_assert(length == NM_PTRARRAY_LEN(list)); + if (length == 0) + return; + + addr_family = NM_IS_SETTING_IP4_CONFIG(setting) ? AF_INET : AF_INET6; + + n = 0; + for (i = 0; i < length; i++) { + NMIPAddr addr; + + if (inet_pton(addr_family, list[i], &addr) <= 0) { + if (!handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring invalid DNS server IPv%c address '%s'"), + nm_utils_addr_family_to_char(addr_family), + list[i])) { + do { + nm_clear_g_free(&list[i]); + } while (++i < length); + return; + } + nm_clear_g_free(&list[i]); + continue; + } + + if (n != i) + list[n] = g_steal_pointer(&list[i]); + n++; + } + + g_object_set(setting, key, list, NULL); +} + +static void +ip6_addr_gen_mode_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + NMSettingIP6ConfigAddrGenMode addr_gen_mode; + const char * setting_name = nm_setting_get_name(setting); + gs_free char * s = NULL; + + s = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL); + if (s) { + if (!nm_utils_enum_from_str(nm_setting_ip6_config_addr_gen_mode_get_type(), + s, + (int *) &addr_gen_mode, + NULL)) { + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid option '%s', use one of [%s]"), + s, + "eui64,stable-privacy"); + return; + } + } else + addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64; + + g_object_set(G_OBJECT(setting), key, (int) addr_gen_mode, NULL); +} + +static void +mac_address_parser(KeyfileReaderInfo *info, + NMSetting * setting, + const char * key, + gsize addr_len, + gboolean cloned_mac_addr) +{ + const char * setting_name = nm_setting_get_name(setting); + char addr_str[NM_UTILS_HWADDR_LEN_MAX * 3]; + guint8 addr_bin[NM_UTILS_HWADDR_LEN_MAX]; + gs_free char *tmp_string = NULL; + gs_free guint *int_list = NULL; + const char * mac_str; + gsize int_list_len; + gsize i; + + nm_assert(addr_len > 0); + nm_assert(addr_len <= NM_UTILS_HWADDR_LEN_MAX); + + tmp_string = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL); + + if (cloned_mac_addr && NM_CLONED_MAC_IS_SPECIAL(tmp_string)) { + mac_str = tmp_string; + goto out; + } + + if (tmp_string && nm_utils_hwaddr_aton(tmp_string, addr_bin, addr_len)) + goto good_addr_bin; + + /* Old format; list of ints */ + int_list = nm_keyfile_plugin_kf_get_integer_list_uint(info->keyfile, + setting_name, + key, + &int_list_len, + NULL); + if (int_list_len == addr_len) { + for (i = 0; i < addr_len; i++) { + const guint val = int_list[i]; + + if (val > 255) + break; + addr_bin[i] = (guint8) val; + } + if (i == addr_len) + goto good_addr_bin; + } + + handle_warn(info, key, key, NM_KEYFILE_WARN_SEVERITY_WARN, _("ignoring invalid MAC address")); + return; + +good_addr_bin: + nm_utils_bin2hexstr_full(addr_bin, addr_len, ':', TRUE, addr_str); + mac_str = addr_str; + +out: + g_object_set(setting, key, mac_str, NULL); +} + +static void +mac_address_parser_ETHER(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + mac_address_parser(info, setting, key, ETH_ALEN, FALSE); +} + +static void +mac_address_parser_ETHER_cloned(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + mac_address_parser(info, setting, key, ETH_ALEN, TRUE); +} + +static void +mac_address_parser_INFINIBAND(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + mac_address_parser(info, setting, key, INFINIBAND_ALEN, FALSE); +} + +static void +read_hash_of_string(KeyfileReaderInfo *info, + GKeyFile * file, + NMSetting * setting, + const char * kf_group) +{ + gs_strfreev char **keys = NULL; + const char *const *iter; + const char * setting_name = nm_setting_get_name(setting); + gboolean is_vpn; + gsize n_keys; + + nm_assert((NM_IS_SETTING_VPN(setting) && nm_streq(kf_group, NM_SETTING_VPN_DATA)) + || (NM_IS_SETTING_VPN(setting) && nm_streq(kf_group, NM_SETTING_VPN_SECRETS)) + || (NM_IS_SETTING_BOND(setting) && nm_streq(kf_group, NM_SETTING_BOND_OPTIONS)) + || (NM_IS_SETTING_USER(setting) && nm_streq(kf_group, NM_SETTING_USER_DATA))); + + keys = nm_keyfile_plugin_kf_get_keys(file, setting_name, &n_keys, NULL); + if (n_keys == 0) + return; + + if ((is_vpn = NM_IS_SETTING_VPN(setting)) || NM_IS_SETTING_BOND(setting)) { + for (iter = (const char *const *) keys; *iter; iter++) { + const char * kf_key = *iter; + gs_free char *to_free = NULL; + gs_free char *value = NULL; + const char * name; + + value = nm_keyfile_plugin_kf_get_string(file, setting_name, kf_key, NULL); + if (!value) + continue; + + name = nm_keyfile_key_decode(kf_key, &to_free); + + if (is_vpn) { + /* Add any item that's not a class property to the data hash */ + if (!g_object_class_find_property(G_OBJECT_GET_CLASS(setting), name)) + nm_setting_vpn_add_data_item(NM_SETTING_VPN(setting), name, value); + } else { + if (!nm_streq(name, "interface-name")) { + gs_free_error GError *error = NULL; + + if (!_nm_setting_bond_validate_option(name, value, &error)) { + if (!handle_warn(info, + kf_key, + name, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring invalid bond option %s%s%s = %s%s%s: %s"), + NM_PRINT_FMT_QUOTE_STRING(name), + NM_PRINT_FMT_QUOTE_STRING(value), + error->message)) + return; + } else + nm_setting_bond_add_option(NM_SETTING_BOND(setting), name, value); + } + } + } + openconnect_fix_secret_flags(setting); + return; + } + + if (NM_IS_SETTING_USER(setting)) { + gs_unref_hashtable GHashTable *data = NULL; + + data = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + for (iter = (const char *const *) keys; *iter; iter++) { + gs_free char *to_free = NULL; + char * value = NULL; + const char * name; + + value = nm_keyfile_plugin_kf_get_string(file, setting_name, *iter, NULL); + if (!value) + continue; + name = nm_keyfile_key_decode(*iter, &to_free); + g_hash_table_insert(data, g_steal_pointer(&to_free) ?: g_strdup(name), value); + } + g_object_set(setting, NM_SETTING_USER_DATA, data, NULL); + return; + } + + nm_assert_not_reached(); +} + +static gsize +unescape_semicolons(char *str) +{ + gsize i, j; + + for (i = 0, j = 0; str[i];) { + if (str[i] == '\\' && str[i + 1] == ';') + i++; + str[j++] = str[i++]; + } + nm_explicit_bzero(&str[j], i - j); + return j; +} + +static GBytes * +get_bytes(KeyfileReaderInfo *info, + const char * setting_name, + const char * key, + gboolean zero_terminate, + gboolean unescape_semicolon) +{ + nm_auto_free_secret char *tmp_string = NULL; + gboolean may_be_int_list = TRUE; + gsize length; + GBytes * result; + + /* New format: just a string + * Old format: integer list; e.g. 11;25;38; + */ + tmp_string = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL); + if (!tmp_string) + return NULL; + + /* if the string is empty, we return an empty GBytes array. + * Note that for NM_SETTING_802_1X_PASSWORD_RAW both %NULL and + * an empty GBytes are valid, and shall be destinguished. */ + if (!tmp_string[0]) { + /* note that even if @zero_terminate is TRUE, we return an empty + * byte-array. The reason is that zero_terminate is there to terminate + * *valid* strings. It's not there to terminated invalid (empty) strings. + */ + return g_bytes_new_static("", 0); + } + + for (length = 0; tmp_string[length]; length++) { + const char ch = tmp_string[length]; + + if (!g_ascii_isspace(ch) && !g_ascii_isdigit(ch) && ch != ';') { + may_be_int_list = FALSE; + length += strlen(&tmp_string[length]); + break; + } + } + + /* Try to parse the string as a integer list. */ + if (may_be_int_list && length > 0) { + nm_auto_free_secret_buf NMSecretBuf *bin = NULL; + const char *const s = tmp_string; + gsize i, d; + + bin = nm_secret_buf_new(length / 2 + 3); + +#define DIGIT(c) ((c) - '0') + i = 0; + d = 0; + while (TRUE) { + int n; + + /* leading whitespace */ + while (g_ascii_isspace(s[i])) + i++; + if (s[i] == '\0') + break; + /* then expect 1 to 3 digits */ + if (!g_ascii_isdigit(s[i])) { + d = 0; + break; + } + n = DIGIT(s[i]); + i++; + if (g_ascii_isdigit(s[i])) { + n = 10 * n + DIGIT(s[i]); + i++; + if (g_ascii_isdigit(s[i])) { + n = 10 * n + DIGIT(s[i]); + i++; + } + } + if (n > 255) { + d = 0; + break; + } + + nm_assert(d < bin->len); + bin->bin[d++] = n; + + /* allow whitespace after the digit. */ + while (g_ascii_isspace(s[i])) + i++; + /* need a semicolon as separator. */ + if (s[i] != ';') { + d = 0; + break; + } + i++; + } +#undef DIGIT + + /* Old format; list of ints. We already did a strict validation of the + * string format before. We expect that this conversion cannot fail. */ + if (d > 0) { + /* note that @zero_terminate does not add a terminating '\0' to + * binary data as an integer list. If the bytes are expressed as + * an integer list, all potential NUL characters are supposed to + * be included there explicitly. + * + * However, in the spirit of defensive programming, we do append a + * NUL character to the buffer, although this character is hidden + * and only a mitigation for bugs. */ + + if (d + 10 < bin->len) { + /* hm, too much unused memory. Copy the memory to a suitable + * sized buffer. */ + return nm_secret_copy_to_gbytes(bin->bin, d); + } + + nm_assert(d < bin->len); + bin->bin[d] = '\0'; + return nm_secret_buf_to_gbytes_take(g_steal_pointer(&bin), d); + } + } + + /* Handle as a simple string (ie, new format) */ + if (unescape_semicolon) + length = unescape_semicolons(tmp_string); + if (zero_terminate) + length++; + if (length == 0) + return NULL; + + result = + g_bytes_new_with_free_func(tmp_string, length, (GDestroyNotify) nm_free_secret, tmp_string); + tmp_string = NULL; + return result; +} + +static void +ssid_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char * setting_name = nm_setting_get_name(setting); + gs_unref_bytes GBytes *bytes = NULL; + + bytes = get_bytes(info, setting_name, key, FALSE, TRUE); + if (!bytes) { + handle_warn(info, key, key, NM_KEYFILE_WARN_SEVERITY_WARN, _("ignoring invalid SSID")); + return; + } + g_object_set(setting, key, bytes, NULL); +} + +static void +password_raw_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char * setting_name = nm_setting_get_name(setting); + gs_unref_bytes GBytes *bytes = NULL; + + bytes = get_bytes(info, setting_name, key, FALSE, TRUE); + if (!bytes) { + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring invalid raw password")); + return; + } + g_object_set(setting, key, bytes, NULL); +} + +static char * +get_cert_path(const char *base_dir, const guint8 *cert_path, gsize cert_path_len) +{ + const char *base; + char * p = NULL, *path, *tmp; + + g_return_val_if_fail(base_dir != NULL, NULL); + g_return_val_if_fail(cert_path != NULL, NULL); + + path = g_strndup((char *) cert_path, cert_path_len); + + if (path[0] == '/') + return path; + + base = path; + p = strrchr(path, '/'); + if (p) + base = p + 1; + + tmp = g_build_path("/", base_dir, base, NULL); + g_free(path); + return tmp; +} + +static const char *certext[] = {".pem", ".cert", ".crt", ".cer", ".p12", ".der", ".key"}; + +static gboolean +has_cert_ext(const char *path) +{ + int i; + + for (i = 0; i < G_N_ELEMENTS(certext); i++) { + if (g_str_has_suffix(path, certext[i])) + return TRUE; + } + return FALSE; +} + +char * +nm_keyfile_detect_unqualified_path_scheme(const char * base_dir, + gconstpointer pdata, + gsize data_len, + gboolean consider_exists, + gboolean * out_exists) +{ + const char * data = pdata; + gboolean exists = FALSE; + gsize validate_len; + gsize path_len, pathuri_len; + gs_free char *path = NULL; + gs_free char *pathuri = NULL; + + g_return_val_if_fail(base_dir && base_dir[0] == '/', NULL); + + if (!pdata) + return NULL; + if (data_len == -1) + data_len = strlen(data); + if (data_len > 500 || data_len < 1) + return NULL; + + /* If there's a trailing zero tell g_utf8_validate() to validate until the zero */ + if (data[data_len - 1] == '\0') { + /* setting it to -1, would mean we accept data to contain NUL characters before the + * end. Don't accept any NUL in [0 .. data_len-1[ . */ + validate_len = data_len - 1; + } else + validate_len = data_len; + if (validate_len == 0 || g_utf8_validate((const char *) data, validate_len, NULL) == FALSE) + return NULL; + + /* Might be a bare path without the file:// prefix; in that case + * if it's an absolute path, use that, otherwise treat it as a + * relative path to the current directory. + */ + + path = get_cert_path(base_dir, (const guint8 *) data, data_len); + + /* FIXME(keyfile-parse-in-memory): it is wrong that keyfile reader makes decisions based on + * the file systems content. The serialization/parsing should be entirely in-memory. */ + if (!memchr(data, '/', data_len) && !has_cert_ext(path)) { + if (!consider_exists) + return NULL; + exists = g_file_test(path, G_FILE_TEST_EXISTS); + if (!exists) + return NULL; + } else if (out_exists) + exists = g_file_test(path, G_FILE_TEST_EXISTS); + + /* Construct the proper value as required for the PATH scheme. + * + * When returning TRUE, we must also be sure that @data_len does not look like + * the deprecated format of list of integers. With this implementation that is the + * case, as long as @consider_exists is FALSE. */ + path_len = strlen(path); + pathuri_len = (NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH) + 1) + path_len; + pathuri = g_new(char, pathuri_len); + memcpy(pathuri, + NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, + NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)); + memcpy(&pathuri[NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)], path, path_len + 1); + if (nm_setting_802_1x_check_cert_scheme(pathuri, pathuri_len, NULL) + != NM_SETTING_802_1X_CK_SCHEME_PATH) + return NULL; + + NM_SET_OUT(out_exists, exists); + return g_steal_pointer(&pathuri); +} + +#define HAS_SCHEME_PREFIX(bin, bin_len, scheme) \ + ({ \ + const char *const _bin = (bin); \ + const gsize _bin_len = (bin_len); \ + \ + nm_assert(_bin &&_bin_len > 0); \ + \ + (_bin_len > NM_STRLEN(scheme) + 1 && _bin[_bin_len - 1] == '\0' \ + && memcmp(_bin, scheme, NM_STRLEN(scheme)) == 0); \ + }) + +static void +cert_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char * setting_name = nm_setting_get_name(setting); + gs_unref_bytes GBytes *bytes = NULL; + const char * bin = NULL; + gsize bin_len = 0; + char * path; + gboolean path_exists; + + bytes = get_bytes(info, setting_name, key, TRUE, FALSE); + if (bytes) + bin = g_bytes_get_data(bytes, &bin_len); + if (bin_len == 0) { + if (!info->error) { + handle_warn(info, key, key, NM_KEYFILE_WARN_SEVERITY_WARN, _("invalid key/cert value")); + } + return; + } + + if (HAS_SCHEME_PREFIX(bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)) { + const char * path2 = &bin[NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)]; + gs_free char *path2_free = NULL; + + if (nm_setting_802_1x_check_cert_scheme(bin, bin_len, NULL) + != NM_SETTING_802_1X_CK_SCHEME_PATH) { + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid key/cert value path \"%s\""), + bin); + return; + } + + g_object_set(setting, key, bytes, NULL); + + if (path2[0] != '/') { + /* we want to read absolute paths because we use keyfile as exchange + * between different processes which might not have the same cwd. */ + path2_free = get_cert_path(info->base_dir, + (const guint8 *) path2, + bin_len - NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH) - 1); + path2 = path2_free; + } + + /* FIXME(keyfile-parse-in-memory): keyfile reader must not access the file system and + * (in a first step) only operate in memory-only. If the presence of files should be checked, + * then by invoking a callback (and possibly keyfile settings plugin would + * collect the file names to be checked and check them later). */ + if (!g_file_test(path2, G_FILE_TEST_EXISTS)) { + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE, + _("certificate or key file '%s' does not exist"), + path2); + } + return; + } + + if (HAS_SCHEME_PREFIX(bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_PKCS11)) { + if (nm_setting_802_1x_check_cert_scheme(bin, bin_len, NULL) + != NM_SETTING_802_1X_CK_SCHEME_PKCS11) { + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid PKCS#11 URI \"%s\""), + bin); + return; + } + + g_object_set(setting, key, bytes, NULL); + return; + } + + if (HAS_SCHEME_PREFIX(bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB)) { + const char *cdata = bin + NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB); + gsize cdata_len = bin_len - NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB) - 1; + gs_free guchar *bin_decoded = NULL; + gsize bin_decoded_len = 0; + gsize i; + gboolean valid_base64; + gs_unref_bytes GBytes *val = NULL; + + /* Let's be strict here. We expect valid base64, no funny stuff!! + * We didn't write such invalid data ourselfes and refuse to read it as blob. */ + if ((valid_base64 = (cdata_len % 4 == 0))) { + for (i = 0; i < cdata_len; i++) { + char c = cdata[i]; + + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') + || (c == '+' || c == '/'))) { + if (c != '=' || i < cdata_len - 2) + valid_base64 = FALSE; + else { + for (; i < cdata_len; i++) { + if (cdata[i] != '=') + valid_base64 = FALSE; + } + } + break; + } + } + } + if (valid_base64) + bin_decoded = g_base64_decode(cdata, &bin_decoded_len); + + if (bin_decoded_len == 0) { + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid key/cert value data:;base64, is not base64")); + return; + } + + if (nm_setting_802_1x_check_cert_scheme(bin_decoded, bin_decoded_len, NULL) + != NM_SETTING_802_1X_CK_SCHEME_BLOB) { + /* The blob probably starts with "file://". Setting the cert data will confuse NMSetting8021x. + * In fact this is a limitation of NMSetting8021x which does not support setting blobs that start + * with file://. Just warn and return TRUE to signal that we ~handled~ the setting. */ + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid key/cert value data:;base64,file://")); + return; + } + + val = g_bytes_new_take(g_steal_pointer(&bin_decoded), bin_decoded_len); + g_object_set(setting, key, val, NULL); + return; + } + + /* If not, it might be a plain path */ + path = + nm_keyfile_detect_unqualified_path_scheme(info->base_dir, bin, bin_len, TRUE, &path_exists); + if (path) { + gs_unref_bytes GBytes *val = NULL; + + /* Construct the proper value as required for the PATH scheme */ + val = g_bytes_new_take(path, strlen(path) + 1); + g_object_set(setting, key, val, NULL); + + /* Warn if the certificate didn't exist */ + if (!path_exists) { + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE, + _("certificate or key file '%s' does not exist"), + path); + } + return; + } + + if (nm_setting_802_1x_check_cert_scheme(bin, bin_len, NULL) + != NM_SETTING_802_1X_CK_SCHEME_BLOB) { + /* The blob probably starts with "file://" but contains invalid characters for a path. + * Setting the cert data will confuse NMSetting8021x. + * In fact, NMSetting8021x does not support setting such binary data, so just warn and + * continue. */ + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid key/cert value is not a valid blob")); + return; + } + + g_object_set(setting, key, bytes, NULL); +} + +static int +_parity_from_char(int ch) +{ +#if NM_MORE_ASSERTS > 5 + { + static char check = 0; + + if (check == 0) { + nm_auto_unref_gtypeclass GEnumClass *klass = + g_type_class_ref(NM_TYPE_SETTING_SERIAL_PARITY); + guint i; + + check = 1; + + /* In older versions, parity was G_TYPE_CHAR/gint8, and the character + * value was stored as integer. + * For example parity=69 equals parity=E, meaning NM_SETTING_SERIAL_PARITY_EVEN. + * + * That means, certain values are reserved. Assert that these numbers + * are not reused when we extend NMSettingSerialParity enum. + * Actually, since NM_SETTING_SERIAL_PARITY is g_param_spec_enum(), + * we anyway cannot extend the enum without breaking API... + * + * [1] commit "a91e60902e libnm-core: make NMSettingSerial:parity an enum" + * [2] https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=a91e60902eabae1de93d61323dae6ac894b5d40f + */ + g_assert(G_IS_ENUM_CLASS(klass)); + for (i = 0; i < klass->n_values; i++) { + const GEnumValue *v = &klass->values[i]; + int num = v->value; + + g_assert(_parity_from_char(num) == -1); + g_assert(!NM_IN_SET(num, 'e', 'E', 'o', 'O', 'n', 'N')); + } + } + } +#endif + + switch (ch) { + case 'E': + case 'e': + return NM_SETTING_SERIAL_PARITY_EVEN; + case 'O': + case 'o': + return NM_SETTING_SERIAL_PARITY_ODD; + case 'N': + case 'n': + return NM_SETTING_SERIAL_PARITY_NONE; + } + + return -1; +} + +static void +parity_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char * setting_name = nm_setting_get_name(setting); + gs_free_error GError *err = NULL; + int parity; + gs_free char * tmp_str = NULL; + gint64 i64; + + /* Keyfile traditionally stored this as the ASCII value for 'E', 'o', or 'n'. + * We now accept either that or the (case-insensitive) character itself (but + * still always write it the old way, for backward compatibility). + */ + tmp_str = nm_keyfile_plugin_kf_get_value(info->keyfile, setting_name, key, &err); + if (err) + goto out_err; + + if (tmp_str && tmp_str[0] != '\0' && tmp_str[1] == '\0') { + /* the ASCII characters like 'E' are taken directly... */ + parity = _parity_from_char(tmp_str[0]); + if (parity >= 0) + goto parity_good; + } + + i64 = _nm_utils_ascii_str_to_int64(tmp_str, 0, G_MININT, G_MAXINT, G_MININT64); + if (i64 != G_MININT64 && errno == 0) { + if ((parity = _parity_from_char(i64)) >= 0) { + /* another oddity: the string is a valid number. However, if the numeric values + * is one of the supported ASCII codes, accept it (like 69 for 'E'). + */ + goto parity_good; + } + + /* Finally, take the numeric value as is. */ + parity = i64; + goto parity_good; + } + + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid parity value '%s'"), + tmp_str ?: ""); + return; + +parity_good: + nm_g_object_set_property_enum(G_OBJECT(setting), + key, + NM_TYPE_SETTING_SERIAL_PARITY, + parity, + &err); + +out_err: + if (!err) + return; + if (nm_keyfile_error_is_not_found(err)) { + /* ignore such errors. The key is not present. */ + return; + } + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid setting: %s"), + err->message); +} + +static void +team_config_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char * setting_name = nm_setting_get_name(setting); + gs_free char *conf = NULL; + gs_free_error GError *error = NULL; + + conf = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL); + + g_object_set(G_OBJECT(setting), key, conf, NULL); + + if (conf && !nm_setting_verify(setting, NULL, &error)) { + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring invalid team configuration: %s"), + error->message); + g_object_set(G_OBJECT(setting), key, NULL, NULL); + } +} + +static void +bridge_vlan_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + gs_unref_ptrarray GPtrArray *vlans = NULL; + gs_free char * value = NULL; + gs_free const char ** strv = NULL; + const char *const * iter; + GError * local = NULL; + NMBridgeVlan * vlan; + + value = nm_keyfile_plugin_kf_get_string(info->keyfile, nm_setting_get_name(setting), key, NULL); + if (!value || !value[0]) + return; + + vlans = g_ptr_array_new_with_free_func((GDestroyNotify) nm_bridge_vlan_unref); + + strv = nm_utils_escaped_tokens_split(value, ","); + if (strv) { + for (iter = strv; *iter; iter++) { + vlan = nm_bridge_vlan_from_str(*iter, &local); + if (!vlan) { + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + "invalid bridge VLAN: %s", + local->message); + g_clear_error(&local); + continue; + } + g_ptr_array_add(vlans, vlan); + } + } + + if (vlans->len > 0) + g_object_set(setting, key, vlans, NULL); +} + +static void +qdisc_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char * setting_name = nm_setting_get_name(setting); + gs_unref_ptrarray GPtrArray *qdiscs = NULL; + gs_strfreev char ** keys = NULL; + gsize n_keys = 0; + int i; + + keys = nm_keyfile_plugin_kf_get_keys(info->keyfile, setting_name, &n_keys, NULL); + if (n_keys == 0) + return; + + qdiscs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_tc_qdisc_unref); + + for (i = 0; i < n_keys; i++) { + NMTCQdisc * qdisc; + const char * qdisc_parent; + gs_free char *qdisc_rest = NULL; + gs_free char *qdisc_str = NULL; + gs_free_error GError *err = NULL; + + if (!g_str_has_prefix(keys[i], "qdisc.")) + continue; + + qdisc_parent = keys[i] + sizeof("qdisc.") - 1; + qdisc_rest = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, keys[i], NULL); + qdisc_str = g_strdup_printf( + "%s%s %s", + _nm_utils_parse_tc_handle(qdisc_parent, NULL) != TC_H_UNSPEC ? "parent " : "", + qdisc_parent, + qdisc_rest); + + qdisc = nm_utils_tc_qdisc_from_str(qdisc_str, &err); + if (!qdisc) { + handle_warn(info, + keys[i], + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid qdisc: %s"), + err->message); + } else { + g_ptr_array_add(qdiscs, qdisc); + } + } + + if (qdiscs->len >= 1) + g_object_set(setting, key, qdiscs, NULL); +} + +static void +tfilter_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char * setting_name = nm_setting_get_name(setting); + gs_unref_ptrarray GPtrArray *tfilters = NULL; + gs_strfreev char ** keys = NULL; + gsize n_keys = 0; + int i; + + keys = nm_keyfile_plugin_kf_get_keys(info->keyfile, setting_name, &n_keys, NULL); + if (n_keys == 0) + return; + + tfilters = g_ptr_array_new_with_free_func((GDestroyNotify) nm_tc_tfilter_unref); + + for (i = 0; i < n_keys; i++) { + NMTCTfilter * tfilter; + const char * tfilter_parent; + gs_free char *tfilter_rest = NULL; + gs_free char *tfilter_str = NULL; + gs_free_error GError *err = NULL; + + if (!g_str_has_prefix(keys[i], "tfilter.")) + continue; + + tfilter_parent = keys[i] + sizeof("tfilter.") - 1; + tfilter_rest = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, keys[i], NULL); + tfilter_str = g_strdup_printf( + "%s%s %s", + _nm_utils_parse_tc_handle(tfilter_parent, NULL) != TC_H_UNSPEC ? "parent " : "", + tfilter_parent, + tfilter_rest); + + tfilter = nm_utils_tc_tfilter_from_str(tfilter_str, &err); + if (!tfilter) { + handle_warn(info, + keys[i], + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid tfilter: %s"), + err->message); + } else { + g_ptr_array_add(tfilters, tfilter); + } + } + + if (tfilters->len >= 1) + g_object_set(setting, key, tfilters, NULL); +} + +/*****************************************************************************/ + +/* Some setting properties also contain setting names, such as + * NMSettingConnection's 'type' property (which specifies the base type of the + * connection, eg ethernet or wifi) or the 802-11-wireless setting's + * 'security' property which specifies whether or not the AP requires + * encryption. This function handles translating those properties' values + * from the real setting name to the more-readable alias. + */ +static void +setting_alias_writer(KeyfileWriterInfo *info, + NMSetting * setting, + const char * key, + const GValue * value) +{ + const char *str, *alias; + + str = g_value_get_string(value); + alias = nm_keyfile_plugin_get_alias_for_setting_name(str); + nm_keyfile_plugin_kf_set_string(info->keyfile, nm_setting_get_name(setting), key, alias ?: str); +} + +static void +sriov_vfs_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value) +{ + GPtrArray *vfs; + guint i; + + vfs = g_value_get_boxed(value); + if (!vfs) + return; + + for (i = 0; i < vfs->len; i++) { + const NMSriovVF *vf = vfs->pdata[i]; + gs_free char * kf_value = NULL; + char kf_key[32]; + + kf_value = nm_utils_sriov_vf_to_str(vf, TRUE, NULL); + if (!kf_value) + continue; + + nm_sprintf_buf(kf_key, "vf.%u", nm_sriov_vf_get_index(vf)); + + nm_keyfile_plugin_kf_set_string(info->keyfile, + nm_setting_get_name(setting), + kf_key, + kf_value); + } +} + +static void +write_array_of_uint(GKeyFile *file, NMSetting *setting, const char *key, const GValue *value) +{ + GArray *array; + + array = g_value_get_boxed(value); + + nm_assert(!array || g_array_get_element_size(array) == sizeof(guint)); + + if (!array || !array->len) + return; + + nm_keyfile_plugin_kf_set_integer_list_uint(file, + nm_setting_get_name(setting), + key, + (const guint *) array->data, + array->len); +} + +static void +dns_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value) +{ + char **list; + + list = g_value_get_boxed(value); + if (list && list[0]) { + nm_keyfile_plugin_kf_set_string_list(info->keyfile, + nm_setting_get_name(setting), + key, + (const char **) list, + g_strv_length(list)); + } +} + +static void +ip6_addr_gen_mode_writer(KeyfileWriterInfo *info, + NMSetting * setting, + const char * key, + const GValue * value) +{ + NMSettingIP6ConfigAddrGenMode addr_gen_mode; + gs_free char * str = NULL; + + addr_gen_mode = (NMSettingIP6ConfigAddrGenMode) g_value_get_int(value); + str = nm_utils_enum_to_str(nm_setting_ip6_config_addr_gen_mode_get_type(), addr_gen_mode); + nm_keyfile_plugin_kf_set_string(info->keyfile, nm_setting_get_name(setting), key, str); +} + +static void +write_ip_values(GKeyFile * file, + const char *setting_name, + GPtrArray * array, + const char *gateway, + gboolean is_route) +{ + if (array->len > 0) { + nm_auto_str_buf NMStrBuf output = NM_STR_BUF_INIT(2 * INET_ADDRSTRLEN + 10, FALSE); + int addr_family; + guint i; + const char * addr; + const char * gw; + guint32 plen; + char key_name[64]; + char * key_name_idx; + + addr_family = + nm_streq(setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME) ? AF_INET : AF_INET6; + + strcpy(key_name, is_route ? "route" : "address"); + key_name_idx = key_name + strlen(key_name); + + for (i = 0; i < array->len; i++) { + gint64 metric = -1; + + if (is_route) { + NMIPRoute *route = array->pdata[i]; + + addr = nm_ip_route_get_dest(route); + plen = nm_ip_route_get_prefix(route); + gw = nm_ip_route_get_next_hop(route); + metric = nm_ip_route_get_metric(route); + } else { + NMIPAddress *address = array->pdata[i]; + + addr = nm_ip_address_get_address(address); + plen = nm_ip_address_get_prefix(address); + gw = (i == 0) ? gateway : NULL; + } + + nm_str_buf_set_size(&output, 0, FALSE, FALSE); + nm_str_buf_append_printf(&output, "%s/%u", addr, plen); + if (metric != -1 || gw) { + /* Older versions of the plugin do not support the form + * "a.b.c.d/plen,,metric", so, we always have to write the + * gateway, even if there isn't one. + * The current version supports reading of the above form. + */ + if (!gw) { + if (addr_family == AF_INET) + gw = "0.0.0.0"; + else + gw = "::"; + } + + nm_str_buf_append_c(&output, ','); + nm_str_buf_append(&output, gw); + if (is_route && metric != -1) + nm_str_buf_append_printf(&output, ",%lu", (unsigned long) metric); + } + + sprintf(key_name_idx, "%u", i + 1); + nm_keyfile_plugin_kf_set_string(file, + setting_name, + key_name, + nm_str_buf_get_str(&output)); + + if (is_route) { + gs_free char *attributes = NULL; + + attributes = + nm_utils_format_variant_attributes(_nm_ip_route_get_attributes(array->pdata[i]), + ',', + '='); + if (attributes) { + g_strlcat(key_name, "_options", sizeof(key_name)); + nm_keyfile_plugin_kf_set_string(file, setting_name, key_name, attributes); + } + } + } + } +} + +static void +addr_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value) +{ + GPtrArray * array; + const char *setting_name = nm_setting_get_name(setting); + const char *gateway = nm_setting_ip_config_get_gateway(NM_SETTING_IP_CONFIG(setting)); + + array = (GPtrArray *) g_value_get_boxed(value); + if (array && array->len) + write_ip_values(info->keyfile, setting_name, array, gateway, FALSE); +} + +static void +route_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value) +{ + GPtrArray * array; + const char *setting_name = nm_setting_get_name(setting); + + array = (GPtrArray *) g_value_get_boxed(value); + if (array && array->len) + write_ip_values(info->keyfile, setting_name, array, NULL, TRUE); +} + +static void +bridge_vlan_writer(KeyfileWriterInfo *info, + NMSetting * setting, + const char * key, + const GValue * value) +{ + GPtrArray *vlans; + + vlans = g_value_get_boxed(value); + if (vlans && vlans->len > 0) { + const guint string_initial_size = vlans->len * 10u; + nm_auto_str_buf NMStrBuf string = NM_STR_BUF_INIT(string_initial_size, FALSE); + guint i; + + for (i = 0; i < vlans->len; i++) { + gs_free char *vlan_str = NULL; + + vlan_str = nm_bridge_vlan_to_str(vlans->pdata[i], NULL); + if (i > 0) + nm_str_buf_append_c(&string, ','); + nm_utils_escaped_tokens_escape_strbuf_assert(vlan_str, ",", &string); + } + + nm_keyfile_plugin_kf_set_string(info->keyfile, + nm_setting_get_name(setting), + "vlans", + nm_str_buf_get_str(&string)); + } +} + +static void +wired_s390_options_parser_full(KeyfileReaderInfo * info, + const NMMetaSettingInfo * setting_info, + const NMSettInfoProperty *property_info, + const ParseInfoProperty * pip, + NMSetting * setting) +{ + NMSettingWired * s_wired = NM_SETTING_WIRED(setting); + gs_strfreev char **keys = NULL; + gsize n_keys; + gsize i; + + keys = nm_keyfile_plugin_kf_get_keys(info->keyfile, + ETHERNET_S390_OPTIONS_GROUP_NAME, + &n_keys, + NULL); + for (i = 0; i < n_keys; i++) { + gs_free char *value = NULL; + gs_free char *key_to_free = NULL; + + value = nm_keyfile_plugin_kf_get_string(info->keyfile, + ETHERNET_S390_OPTIONS_GROUP_NAME, + keys[i], + NULL); + if (!value) + continue; + + /* Here we don't verify the key/value further. If the file contains invalid keys, + * we will later reject the connection as invalid. */ + nm_setting_wired_add_s390_option(s_wired, + nm_keyfile_key_decode(keys[i], &key_to_free), + value); + } +} + +static void +wired_s390_options_writer_full(KeyfileWriterInfo * info, + const NMMetaSettingInfo * setting_info, + const NMSettInfoProperty *property_info, + const ParseInfoProperty * pip, + NMSetting * setting) +{ + NMSettingWired *s_wired = NM_SETTING_WIRED(setting); + guint i, n; + + n = nm_setting_wired_get_num_s390_options(s_wired); + for (i = 0; i < n; i++) { + gs_free char *key_to_free = NULL; + const char * opt_key; + const char * opt_val; + + nm_setting_wired_get_s390_option(s_wired, i, &opt_key, &opt_val); + nm_keyfile_plugin_kf_set_string(info->keyfile, + ETHERNET_S390_OPTIONS_GROUP_NAME, + nm_keyfile_key_encode(opt_key, &key_to_free), + opt_val); + } +} + +static void +ip_routing_rule_writer_full(KeyfileWriterInfo * info, + const NMMetaSettingInfo * setting_info, + const NMSettInfoProperty *property_info, + const ParseInfoProperty * pip, + NMSetting * setting) +{ + const char * setting_name = nm_setting_get_name(setting); + NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG(setting); + guint i, j, n; + char key_name_full[100] = "routing-rule"; + char * key_name_num = &key_name_full[NM_STRLEN("routing-rule")]; + + n = nm_setting_ip_config_get_num_routing_rules(s_ip); + j = 0; + for (i = 0; i < n; i++) { + NMIPRoutingRule *rule = nm_setting_ip_config_get_routing_rule(s_ip, i); + gs_free char * str = NULL; + + str = + nm_ip_routing_rule_to_string(rule, NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE, NULL, NULL); + if (!str) + continue; + + sprintf(key_name_num, "%u", ++j); + nm_keyfile_plugin_kf_set_string(info->keyfile, setting_name, key_name_full, str); + } +} + +static void +qdisc_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value) +{ + nm_auto_free_gstring GString *key_name = NULL; + nm_auto_free_gstring GString *value_str = NULL; + GPtrArray * array; + guint i; + + array = g_value_get_boxed(value); + if (!array || !array->len) + return; + + for (i = 0; i < array->len; i++) { + NMTCQdisc *qdisc = array->pdata[i]; + + nm_gstring_prepare(&key_name); + nm_gstring_prepare(&value_str); + + g_string_append(key_name, "qdisc."); + _nm_utils_string_append_tc_parent(key_name, NULL, nm_tc_qdisc_get_parent(qdisc)); + _nm_utils_string_append_tc_qdisc_rest(value_str, qdisc); + + nm_keyfile_plugin_kf_set_string(info->keyfile, + NM_SETTING_TC_CONFIG_SETTING_NAME, + key_name->str, + value_str->str); + } +} + +static void +tfilter_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value) +{ + nm_auto_free_gstring GString *key_name = NULL; + nm_auto_free_gstring GString *value_str = NULL; + GPtrArray * array; + guint i; + + array = g_value_get_boxed(value); + if (!array || !array->len) + return; + + for (i = 0; i < array->len; i++) { + NMTCTfilter *tfilter = array->pdata[i]; + + nm_gstring_prepare(&key_name); + nm_gstring_prepare(&value_str); + + g_string_append(key_name, "tfilter."); + _nm_utils_string_append_tc_parent(key_name, NULL, nm_tc_tfilter_get_parent(tfilter)); + _nm_utils_string_append_tc_tfilter_rest(value_str, tfilter, NULL); + + nm_keyfile_plugin_kf_set_string(info->keyfile, + NM_SETTING_TC_CONFIG_SETTING_NAME, + key_name->str, + value_str->str); + } +} + +static void +_writer_full_ovs_external_ids_data(KeyfileWriterInfo * info, + const NMMetaSettingInfo * setting_info, + const NMSettInfoProperty *property_info, + const ParseInfoProperty * pip, + NMSetting * setting) +{ + GHashTable * hash; + NMUtilsNamedValue data_static[300u / sizeof(NMUtilsNamedValue)]; + gs_free NMUtilsNamedValue *data_free = NULL; + const NMUtilsNamedValue * data; + guint data_len; + char full_key_static[NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX) + 300u]; + guint i; + + nm_assert(NM_IS_SETTING_OVS_EXTERNAL_IDS(setting)); + nm_assert(nm_streq(property_info->name, NM_SETTING_OVS_EXTERNAL_IDS_DATA)); + + hash = _nm_setting_ovs_external_ids_get_data(NM_SETTING_OVS_EXTERNAL_IDS(setting)); + if (!hash) + return; + + data = nm_utils_named_values_from_strdict(hash, &data_len, data_static, &data_free); + if (data_len == 0) + return; + + memcpy(full_key_static, OVS_EXTERNAL_IDS_DATA_PREFIX, NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX)); + + for (i = 0; i < data_len; i++) { + const char * key = data[i].name; + const char * val = data[i].value_str; + gs_free char *escaped_key_to_free = NULL; + const char * escaped_key; + gsize len; + gs_free char *full_key_free = NULL; + char * full_key = full_key_static; + + escaped_key = nm_keyfile_key_encode(key, &escaped_key_to_free); + + len = strlen(escaped_key) + 1u; + if (len >= G_N_ELEMENTS(full_key_static) - NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX)) { + full_key_free = g_new(char, NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX) + len); + full_key = full_key_free; + memcpy(full_key, OVS_EXTERNAL_IDS_DATA_PREFIX, NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX)); + } + memcpy(&full_key[NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX)], escaped_key, len); + + nm_keyfile_plugin_kf_set_string(info->keyfile, + NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME, + full_key, + val); + } +} + +static void +write_hash_of_string(GKeyFile *file, NMSetting *setting, const char *key, const GValue *value) +{ + GHashTable * hash; + const char * group_name = nm_setting_get_name(setting); + gboolean vpn_secrets = FALSE; + gs_free const char **keys = NULL; + guint i, l; + + nm_assert((NM_IS_SETTING_VPN(setting) && nm_streq(key, NM_SETTING_VPN_DATA)) + || (NM_IS_SETTING_VPN(setting) && nm_streq(key, NM_SETTING_VPN_SECRETS)) + || (NM_IS_SETTING_BOND(setting) && nm_streq(key, NM_SETTING_BOND_OPTIONS)) + || (NM_IS_SETTING_USER(setting) && nm_streq(key, NM_SETTING_USER_DATA))); + + /* Write VPN secrets out to a different group to keep them separate */ + if (NM_IS_SETTING_VPN(setting) && nm_streq(key, NM_SETTING_VPN_SECRETS)) { + group_name = NM_KEYFILE_GROUP_VPN_SECRETS; + vpn_secrets = TRUE; + } + + hash = g_value_get_boxed(value); + + keys = nm_utils_strdict_get_keys(hash, TRUE, &l); + for (i = 0; i < l; i++) { + gs_free char *to_free = NULL; + const char * property, *data; + + property = keys[i]; + + /* Handle VPN secrets specially; they are nested in the property's hash; + * we don't want to write them if the secret is not saved, not required, + * or owned by a user's secret agent. + */ + if (vpn_secrets) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + if (!nm_setting_get_secret_flags(setting, property, &secret_flags, NULL)) + nm_assert_not_reached(); + if (!_secret_flags_persist_secret(secret_flags)) + continue; + } + + data = g_hash_table_lookup(hash, property); + nm_keyfile_plugin_kf_set_string(file, + group_name, + nm_keyfile_key_encode(property, &to_free), + data); + } +} + +static void +ssid_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value) +{ + GBytes * bytes; + const guint8 *ssid_data; + gsize ssid_len; + const char * setting_name = nm_setting_get_name(setting); + gboolean new_format = TRUE; + gsize semicolons = 0; + gsize i; + + g_return_if_fail(G_VALUE_HOLDS(value, G_TYPE_BYTES)); + + bytes = g_value_get_boxed(value); + if (!bytes) + return; + ssid_data = g_bytes_get_data(bytes, &ssid_len); + if (!ssid_data || !ssid_len) { + nm_keyfile_plugin_kf_set_string(info->keyfile, setting_name, key, ""); + return; + } + + /* Check whether each byte is printable. If not, we have to use an + * integer list, otherwise we can just use a string. + */ + for (i = 0; i < ssid_len; i++) { + const char c = ssid_data[i]; + + if (!g_ascii_isprint(c)) { + new_format = FALSE; + break; + } + if (c == ';') + semicolons++; + } + + if (new_format) { + gs_free char *ssid = NULL; + + if (semicolons == 0) + ssid = g_strndup((char *) ssid_data, ssid_len); + else { + /* Escape semicolons with backslashes to make strings + * containing ';', such as '16;17;' unambiguous */ + gsize j = 0; + + ssid = g_malloc(ssid_len + semicolons + 1); + for (i = 0; i < ssid_len; i++) { + if (ssid_data[i] == ';') + ssid[j++] = '\\'; + ssid[j++] = ssid_data[i]; + } + ssid[j] = '\0'; + } + nm_keyfile_plugin_kf_set_string(info->keyfile, setting_name, key, ssid); + } else + nm_keyfile_plugin_kf_set_integer_list_uint8(info->keyfile, + setting_name, + key, + ssid_data, + ssid_len); +} + +static void +password_raw_writer(KeyfileWriterInfo *info, + NMSetting * setting, + const char * key, + const GValue * value) +{ + const char * setting_name = nm_setting_get_name(setting); + GBytes * array; + gsize len; + const guint8 *data; + + g_return_if_fail(G_VALUE_HOLDS(value, G_TYPE_BYTES)); + + array = (GBytes *) g_value_get_boxed(value); + if (!array) + return; + data = g_bytes_get_data(array, &len); + if (!data) + len = 0; + nm_keyfile_plugin_kf_set_integer_list_uint8(info->keyfile, setting_name, key, data, len); +} + +/*****************************************************************************/ + +static void +cert_writer_default(NMConnection * connection, + GKeyFile * file, + NMSetting8021x * setting, + const char * setting_name, + const NMSetting8021xSchemeVtable *vtable) +{ + NMSetting8021xCKScheme scheme; + + scheme = vtable->scheme_func(setting); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + gs_free char *path_free = NULL; + gs_free char *base_dir = NULL; + gs_free char *tmp = NULL; + const char * path; + + path = vtable->path_func(setting); + g_assert(path); + + /* If the path is relative, make it an absolute path. + * Relative paths make a keyfile not easily usable in another + * context. */ + if (path[0] && path[0] != '/') { + base_dir = g_get_current_dir(); + path_free = g_strconcat(base_dir, "/", path, NULL); + path = path_free; + } else + base_dir = g_path_get_dirname(path); + + /* path cannot start with "file://" or "data:;base64,", because it is an absolute path. + * Still, make sure that a prefix-less path will be recognized. This can happen + * for example if the path is longer then 500 chars. */ + tmp = nm_keyfile_detect_unqualified_path_scheme(base_dir, path, -1, FALSE, NULL); + if (tmp) + nm_clear_g_free(&tmp); + else { + tmp = g_strconcat(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL); + path = tmp; + } + + /* Path contains at least a '/', hence it cannot be recognized as the old + * binary format consisting of a list of integers. */ + + nm_keyfile_plugin_kf_set_string(file, setting_name, vtable->setting_key, path); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + GBytes * blob; + const guint8 *blob_data; + gsize blob_len; + gs_free char *blob_base64 = NULL; + gs_free char *val = NULL; + + blob = vtable->blob_func(setting); + g_assert(blob); + blob_data = g_bytes_get_data(blob, &blob_len); + + blob_base64 = g_base64_encode(blob_data, blob_len); + val = g_strconcat(NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB, blob_base64, NULL); + + nm_keyfile_plugin_kf_set_string(file, setting_name, vtable->setting_key, val); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { + nm_keyfile_plugin_kf_set_string(file, + setting_name, + vtable->setting_key, + vtable->uri_func(setting)); + } else { + /* scheme_func() returns UNKNOWN in all other cases. The only valid case + * where a scheme is allowed to be UNKNOWN, is unsetting the value. In this + * case, we don't expect the writer to be called, because the default value + * will not be serialized. + * The only other reason for the scheme to be UNKNOWN is an invalid cert. + * But our connection verifies, so that cannot happen either. */ + g_return_if_reached(); + } +} + +static void +cert_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value) +{ + const NMSetting8021xSchemeVtable *vtable = NULL; + const char * setting_name; + guint i; + + for (i = 0; nm_setting_8021x_scheme_vtable[i].setting_key; i++) { + if (nm_streq0(nm_setting_8021x_scheme_vtable[i].setting_key, key)) { + vtable = &nm_setting_8021x_scheme_vtable[i]; + break; + } + } + if (!vtable) + g_return_if_reached(); + + setting_name = nm_setting_get_name(NM_SETTING(setting)); + + if (info->write_handler) { + NMKeyfileHandlerData handler_data; + + _key_file_handler_data_init_write(&handler_data, + NM_KEYFILE_HANDLER_TYPE_WRITE_CERT, + info, + setting_name, + vtable->setting_key, + setting, + key); + handler_data.write_cert = (NMKeyfileHandlerDataWriteCert){ + .vtable = vtable, + }; + + if (info->write_handler(info->connection, + info->keyfile, + NM_KEYFILE_HANDLER_TYPE_WRITE_CERT, + &handler_data, + info->user_data)) + return; + if (info->error) + return; + } + + cert_writer_default(info->connection, + info->keyfile, + NM_SETTING_802_1X(setting), + setting_name, + vtable); +} + +/*****************************************************************************/ + +struct _ParseInfoProperty { + const char *property_name; + union { + void (*parser)(KeyfileReaderInfo *info, NMSetting *setting, const char *key); + void (*parser_full)(KeyfileReaderInfo * info, + const NMMetaSettingInfo * setting_info, + const NMSettInfoProperty *property_info, + const ParseInfoProperty * pip, + NMSetting * setting); + }; + union { + void (*writer)(KeyfileWriterInfo *info, + NMSetting * setting, + const char * key, + const GValue * value); + void (*writer_full)(KeyfileWriterInfo * info, + const NMMetaSettingInfo * setting_info, + const NMSettInfoProperty *property_info, + const ParseInfoProperty * pip, + NMSetting * setting); + }; + bool parser_skip; + bool parser_no_check_key : 1; + bool writer_skip : 1; + bool has_writer_full : 1; + bool has_parser_full : 1; + + /* usually, we skip to write values that have their + * default value. By setting this flag to TRUE, also + * default values are written. */ + bool writer_persist_default : 1; +}; + +#define PARSE_INFO_PROPERTY(_property_name, ...) \ + (&((const ParseInfoProperty){.property_name = _property_name, __VA_ARGS__})) + +#define PARSE_INFO_PROPERTIES(...) \ + .properties = ((const ParseInfoProperty *const[]){ \ + __VA_ARGS__ NULL, \ + }) + +typedef struct { + const ParseInfoProperty *const *properties; +} ParseInfoSetting; + +#define PARSE_INFO_SETTING(setting_type, ...) \ + [setting_type] = (&((const ParseInfoSetting){__VA_ARGS__})) + +static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_WIRELESS, + PARSE_INFO_PROPERTIES( + PARSE_INFO_PROPERTY(NM_SETTING_WIRELESS_BSSID, .parser = mac_address_parser_ETHER, ), + PARSE_INFO_PROPERTY(NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, + .parser = mac_address_parser_ETHER_cloned, ), + PARSE_INFO_PROPERTY(NM_SETTING_WIRELESS_MAC_ADDRESS, + .parser = mac_address_parser_ETHER, ), + PARSE_INFO_PROPERTY(NM_SETTING_WIRELESS_SSID, + .parser = ssid_parser, + .writer = ssid_writer, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_802_1X, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_802_1X_CA_CERT, + .parser = cert_parser, + .writer = cert_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_802_1X_CLIENT_CERT, + .parser = cert_parser, + .writer = cert_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_802_1X_PASSWORD_RAW, + .parser = password_raw_parser, + .writer = password_raw_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_802_1X_PHASE2_CA_CERT, + .parser = cert_parser, + .writer = cert_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_802_1X_PHASE2_CLIENT_CERT, + .parser = cert_parser, + .writer = cert_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + .parser = cert_parser, + .writer = cert_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_802_1X_PRIVATE_KEY, + .parser = cert_parser, + .writer = cert_writer, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_WIRED, + PARSE_INFO_PROPERTIES( + PARSE_INFO_PROPERTY(NM_SETTING_WIRED_CLONED_MAC_ADDRESS, + .parser = mac_address_parser_ETHER_cloned, ), + PARSE_INFO_PROPERTY(NM_SETTING_WIRED_MAC_ADDRESS, .parser = mac_address_parser_ETHER, ), + PARSE_INFO_PROPERTY(NM_SETTING_WIRED_S390_OPTIONS, + .parser_no_check_key = TRUE, + .parser_full = wired_s390_options_parser_full, + .writer_full = wired_s390_options_writer_full, + .has_parser_full = TRUE, + .has_writer_full = TRUE, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_BLUETOOTH, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_BLUETOOTH_BDADDR, + .parser = mac_address_parser_ETHER, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_BOND, + PARSE_INFO_PROPERTIES( + PARSE_INFO_PROPERTY(NM_SETTING_BOND_OPTIONS, .parser_no_check_key = TRUE, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_BRIDGE, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_BRIDGE_MAC_ADDRESS, + .parser = mac_address_parser_ETHER, ), + PARSE_INFO_PROPERTY(NM_SETTING_BRIDGE_VLANS, + .parser_no_check_key = TRUE, + .parser = bridge_vlan_parser, + .writer = bridge_vlan_writer, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_BRIDGE_PORT, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_BRIDGE_PORT_VLANS, + .parser_no_check_key = TRUE, + .parser = bridge_vlan_parser, + .writer = bridge_vlan_writer, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_CONNECTION, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_CONNECTION_READ_ONLY, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_CONNECTION_TYPE, + .parser = setting_alias_parser, + .writer = setting_alias_writer, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_INFINIBAND, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_INFINIBAND_MAC_ADDRESS, + .parser = mac_address_parser_INFINIBAND, ), ), ), + PARSE_INFO_SETTING(NM_META_SETTING_TYPE_IP4_CONFIG, + PARSE_INFO_PROPERTIES( + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ADDRESSES, + .parser_no_check_key = TRUE, + .parser = ip_address_or_route_parser, + .writer = addr_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS, + .parser_no_check_key = TRUE, + .parser = ip_dns_parser, + .writer = dns_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTES, + .parser_no_check_key = TRUE, + .parser = ip_address_or_route_parser, + .writer = route_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTING_RULES, + .parser_no_check_key = TRUE, + .parser_full = ip_routing_rule_parser_full, + .writer_full = ip_routing_rule_writer_full, + .has_parser_full = TRUE, + .has_writer_full = TRUE, ), ), ), + PARSE_INFO_SETTING(NM_META_SETTING_TYPE_IP6_CONFIG, + PARSE_INFO_PROPERTIES( + PARSE_INFO_PROPERTY(NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, + .parser_no_check_key = TRUE, + .parser = ip6_addr_gen_mode_parser, + .writer = ip6_addr_gen_mode_writer, + .writer_persist_default = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ADDRESSES, + .parser_no_check_key = TRUE, + .parser = ip_address_or_route_parser, + .writer = addr_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS, + .parser_no_check_key = TRUE, + .parser = ip_dns_parser, + .writer = dns_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTES, + .parser_no_check_key = TRUE, + .parser = ip_address_or_route_parser, + .writer = route_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTING_RULES, + .parser_no_check_key = TRUE, + .parser_full = ip_routing_rule_parser_full, + .writer_full = ip_routing_rule_writer_full, + .has_parser_full = TRUE, + .has_writer_full = TRUE, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_OVS_EXTERNAL_IDS_DATA, + .parser_no_check_key = TRUE, + .parser_full = _parser_full_ovs_external_ids_data, + .writer_full = _writer_full_ovs_external_ids_data, + .has_parser_full = TRUE, + .has_writer_full = TRUE, ), ), ), + PARSE_INFO_SETTING(NM_META_SETTING_TYPE_SERIAL, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_SERIAL_PARITY, + .parser = parity_parser, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_SRIOV, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_SRIOV_VFS, + .parser_no_check_key = TRUE, + .parser = sriov_vfs_parser, + .writer = sriov_vfs_writer, ), ), ), + PARSE_INFO_SETTING(NM_META_SETTING_TYPE_TC_CONFIG, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_TC_CONFIG_QDISCS, + .parser_no_check_key = TRUE, + .parser = qdisc_parser, + .writer = qdisc_writer, ), + PARSE_INFO_PROPERTY(NM_SETTING_TC_CONFIG_TFILTERS, + .parser_no_check_key = TRUE, + .parser = tfilter_parser, + .writer = tfilter_writer, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_TEAM, + PARSE_INFO_PROPERTIES( + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_CONFIG, .parser = team_config_parser, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_LINK_WATCHERS, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_MCAST_REJOIN_COUNT, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER, .parser_skip = TRUE, .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_ACTIVE, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_FAST_RATE, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_HWADDR_POLICY, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_MIN_PORTS, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_SYS_PRIO, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_TX_BALANCER, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_TX_HASH, + .parser_skip = TRUE, + .writer_skip = TRUE, ), ), ), + PARSE_INFO_SETTING(NM_META_SETTING_TYPE_TEAM_PORT, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_TEAM_CONFIG, + .parser = team_config_parser, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_LACP_KEY, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_LACP_PRIO, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_LINK_WATCHERS, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_PRIO, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_QUEUE_ID, + .parser_skip = TRUE, + .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_STICKY, + .parser_skip = TRUE, + .writer_skip = TRUE, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_USER, + PARSE_INFO_PROPERTIES( + PARSE_INFO_PROPERTY(NM_SETTING_USER_DATA, .parser_no_check_key = TRUE, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_VLAN, + PARSE_INFO_PROPERTIES( + PARSE_INFO_PROPERTY(NM_SETTING_VLAN_FLAGS, .writer_persist_default = TRUE, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_VPN, + PARSE_INFO_PROPERTIES( + PARSE_INFO_PROPERTY(NM_SETTING_VPN_DATA, .parser_no_check_key = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_VPN_PERSISTENT, .parser_no_check_key = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_VPN_SECRETS, .parser_no_check_key = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_VPN_SERVICE_TYPE, .parser_no_check_key = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_VPN_TIMEOUT, .parser_no_check_key = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_VPN_USER_NAME, .parser_no_check_key = TRUE, ), ), ), + PARSE_INFO_SETTING( + NM_META_SETTING_TYPE_WIMAX, + PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_WIMAX_MAC_ADDRESS, + .parser = mac_address_parser_ETHER, ), ), ), +}; + +static void +_parse_info_find(NMSetting * setting, + const char * property_name, + const NMMetaSettingInfo **out_setting_info, + const ParseInfoSetting ** out_parse_info_setting, + const ParseInfoProperty **out_parse_info_property) +{ + const NMMetaSettingInfo *setting_info; + const ParseInfoSetting * pis; + const ParseInfoProperty *pip; + +#if NM_MORE_ASSERTS > 10 + { + guint i, j; + static int asserted = FALSE; + + if (!asserted) { + for (i = 0; i < G_N_ELEMENTS(parse_infos); i++) { + pis = parse_infos[i]; + + if (!pis) + continue; + if (!pis->properties) + continue; + + g_assert(pis->properties[0]); + for (j = 0; pis->properties[j]; j++) { + const ParseInfoProperty *pip0; + const ParseInfoProperty *pipj = pis->properties[j]; + + g_assert(pipj->property_name); + if (j > 0 && (pip0 = pis->properties[j - 1]) + && strcmp(pip0->property_name, pipj->property_name) >= 0) { + g_error("Wrong order at index #%d.%d: \"%s.%s\" before \"%s.%s\"", + i, + j - 1, + nm_meta_setting_infos[i].setting_name, + pip0->property_name, + nm_meta_setting_infos[i].setting_name, + pipj->property_name); + } + } + } + asserted = TRUE; + } + } +#endif + + if (!NM_IS_SETTING(setting) || !(setting_info = NM_SETTING_GET_CLASS(setting)->setting_info)) { + /* handle invalid setting objects gracefully. */ + NM_SET_OUT(out_setting_info, NULL); + NM_SET_OUT(out_parse_info_setting, NULL); + NM_SET_OUT(out_parse_info_property, NULL); + return; + } + + nm_assert(setting_info->setting_name); + nm_assert(_NM_INT_NOT_NEGATIVE(setting_info->meta_type)); + nm_assert(setting_info->meta_type < G_N_ELEMENTS(parse_infos)); + + pis = parse_infos[setting_info->meta_type]; + + pip = NULL; + if (pis && property_name) { + gssize idx; + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(ParseInfoProperty, property_name) == 0); + + idx = nm_utils_ptrarray_find_binary_search((gconstpointer *) pis->properties, + NM_PTRARRAY_LEN(pis->properties), + &property_name, + nm_strcmp_p_with_data, + NULL); + if (idx >= 0) + pip = pis->properties[idx]; + } + + NM_SET_OUT(out_setting_info, setting_info); + NM_SET_OUT(out_parse_info_setting, pis); + NM_SET_OUT(out_parse_info_property, pip); +} + +/*****************************************************************************/ + +static void +read_one_setting_value(KeyfileReaderInfo * info, + NMSetting * setting, + const NMSettInfoProperty *property_info) +{ + GKeyFile * keyfile = info->keyfile; + gs_free_error GError * err = NULL; + const NMMetaSettingInfo *setting_info; + const ParseInfoProperty *pip; + gs_free char * tmp_str = NULL; + const char * key; + GType type; + guint64 u64; + gint64 i64; + + nm_assert(!info->error); + nm_assert(!property_info->param_spec + || nm_streq(property_info->param_spec->name, property_info->name)); + + key = property_info->name; + + _parse_info_find(setting, key, &setting_info, NULL, &pip); + + nm_assert(setting_info); + + if (!pip) { + if (nm_streq(key, NM_SETTING_NAME)) + return; + if (!property_info->param_spec) + return; + if ((property_info->param_spec->flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)) + != G_PARAM_WRITABLE) + return; + } else { + if (pip->parser_skip) + return; + if (pip->has_parser_full) { + pip->parser_full(info, setting_info, property_info, pip, setting); + return; + } + } + + nm_assert(property_info->param_spec); + nm_assert((property_info->param_spec->flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)) + == G_PARAM_WRITABLE); + + /* Check for the exact key in the GKeyFile if required. Most setting + * properties map 1:1 to a key in the GKeyFile, but for those properties + * like IP addresses and routes where more than one value is actually + * encoded by the setting property, this won't be true. + */ + if ((!pip || !pip->parser_no_check_key) + && !nm_keyfile_plugin_kf_has_key(keyfile, setting_info->setting_name, key, &err)) { + /* Key doesn't exist or an error occurred, thus nothing to do. */ + if (err) { + if (!handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("error loading setting value: %s"), + err->message)) + return; + } + return; + } + + if (pip && pip->parser) { + pip->parser(info, setting, key); + return; + } + + type = G_PARAM_SPEC_VALUE_TYPE(property_info->param_spec); + + if (type == G_TYPE_STRING) { + gs_free char *str_val = NULL; + + str_val = nm_keyfile_plugin_kf_get_string(keyfile, setting_info->setting_name, key, &err); + if (!err) + nm_g_object_set_property_string_take(G_OBJECT(setting), + key, + g_steal_pointer(&str_val), + &err); + } else if (type == G_TYPE_UINT) { + tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err); + if (!err) { + u64 = _nm_utils_ascii_str_to_uint64(tmp_str, 0, 0, G_MAXUINT, G_MAXUINT64); + if (u64 == G_MAXUINT64 && errno != 0) { + g_set_error_literal(&err, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("value cannot be interpreted as integer")); + } else + nm_g_object_set_property_uint(G_OBJECT(setting), key, u64, &err); + } + } else if (type == G_TYPE_INT) { + tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err); + if (!err) { + i64 = _nm_utils_ascii_str_to_int64(tmp_str, 0, G_MININT, G_MAXINT, G_MININT64); + if (i64 == G_MININT64 && errno != 0) { + g_set_error_literal(&err, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("value cannot be interpreted as integer")); + } else + nm_g_object_set_property_int(G_OBJECT(setting), key, i64, &err); + } + } else if (type == G_TYPE_BOOLEAN) { + gboolean bool_val; + + bool_val = nm_keyfile_plugin_kf_get_boolean(keyfile, setting_info->setting_name, key, &err); + if (!err) + nm_g_object_set_property_boolean(G_OBJECT(setting), key, bool_val, &err); + } else if (type == G_TYPE_CHAR) { + tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err); + if (!err) { + /* As documented by glib, G_TYPE_CHAR is really a (signed!) gint8. */ + i64 = _nm_utils_ascii_str_to_int64(tmp_str, 0, G_MININT8, G_MAXINT8, G_MININT64); + if (i64 == G_MININT64 && errno != 0) { + g_set_error_literal(&err, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("value cannot be interpreted as integer")); + } else + nm_g_object_set_property_char(G_OBJECT(setting), key, i64, &err); + } + } else if (type == G_TYPE_UINT64) { + tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err); + if (!err) { + u64 = _nm_utils_ascii_str_to_uint64(tmp_str, 0, 0, G_MAXUINT64, G_MAXUINT64); + if (u64 == G_MAXUINT64 && errno != 0) { + g_set_error_literal(&err, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("value cannot be interpreted as integer")); + } else + nm_g_object_set_property_uint64(G_OBJECT(setting), key, u64, &err); + } + } else if (type == G_TYPE_INT64) { + tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err); + if (!err) { + i64 = _nm_utils_ascii_str_to_int64(tmp_str, 0, G_MININT64, G_MAXINT64, G_MAXINT64); + if (i64 == G_MAXINT64 && errno != 0) { + g_set_error_literal(&err, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("value cannot be interpreted as integer")); + } else + nm_g_object_set_property_int64(G_OBJECT(setting), key, i64, &err); + } + } else if (type == G_TYPE_BYTES) { + nm_auto_unref_bytearray GByteArray *array = NULL; + gs_unref_bytes GBytes *bytes = NULL; + gs_free guint *tmp = NULL; + gsize length; + int i; + gboolean already_warned = FALSE; + + tmp = nm_keyfile_plugin_kf_get_integer_list_uint(keyfile, + setting_info->setting_name, + key, + &length, + NULL); + + array = g_byte_array_sized_new(length); + for (i = 0; i < length; i++) { + const guint val = tmp[i]; + unsigned char v = (unsigned char) (val & 0xFF); + + if (val > 255u) { + if (!already_warned + && !handle_warn( + info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring invalid byte element '%u' (not between 0 and 255 inclusive)"), + val)) + return; + already_warned = TRUE; + } else + g_byte_array_append(array, (const unsigned char *) &v, sizeof(v)); + } + + bytes = g_byte_array_free_to_bytes(g_steal_pointer(&array)); + g_object_set(setting, key, bytes, NULL); + } else if (type == G_TYPE_STRV) { + gs_strfreev char **sa = NULL; + gsize length; + + sa = nm_keyfile_plugin_kf_get_string_list(keyfile, + setting_info->setting_name, + key, + &length, + NULL); + g_object_set(setting, key, sa, NULL); + } else if (type == G_TYPE_HASH_TABLE) { + read_hash_of_string(info, keyfile, setting, key); + } else if (type == G_TYPE_ARRAY) { + read_array_of_uint(keyfile, setting, key); + } else if (G_TYPE_IS_FLAGS(type)) { + tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err); + if (!err) { + u64 = _nm_utils_ascii_str_to_uint64(tmp_str, 0, 0, G_MAXUINT, G_MAXUINT64); + if (u64 == G_MAXUINT64 && errno != 0) { + g_set_error_literal(&err, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("value cannot be interpreted as integer")); + } else + nm_g_object_set_property_flags(G_OBJECT(setting), key, type, u64, &err); + } + } else if (G_TYPE_IS_ENUM(type)) { + tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err); + if (!err) { + i64 = _nm_utils_ascii_str_to_int64(tmp_str, 0, G_MININT, G_MAXINT, G_MAXINT64); + if (i64 == G_MAXINT64 && errno != 0) { + g_set_error_literal(&err, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("value cannot be interpreted as integer")); + } else + nm_g_object_set_property_enum(G_OBJECT(setting), key, type, i64, &err); + } + } else + g_return_if_reached(); + + if (err) { + if (nm_keyfile_error_is_not_found(err)) { + /* ignore such errors. The key is not present. */ + } else { + handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid setting: %s"), + err->message); + } + } +} + +static void +_read_setting(KeyfileReaderInfo *info) +{ + const NMSettInfoSetting *sett_info; + gs_unref_object NMSetting *setting = NULL; + const char * alias; + GType type; + guint i; + + alias = nm_keyfile_plugin_get_setting_name_for_alias(info->group); + if (!alias) + alias = info->group; + + type = nm_setting_lookup_type(alias); + if (!type) { + handle_warn(info, + NULL, + NULL, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid setting name '%s'"), + info->group); + return; + } + + setting = g_object_new(type, NULL); + + info->setting = setting; + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); + + if (sett_info->detail.gendata_info) { + gs_free char **keys = NULL; + gsize k, n_keys; + + keys = g_key_file_get_keys(info->keyfile, info->group, &n_keys, NULL); + if (!keys) + n_keys = 0; + if (n_keys > 0) { + GHashTable *h = _nm_setting_option_hash(setting, TRUE); + + nm_utils_strv_sort(keys, n_keys); + for (k = 0; k < n_keys; k++) { + gs_free char *key = keys[k]; + gs_free_error GError *local = NULL; + const GVariantType * variant_type; + GVariant * variant; + + /* a GKeyFile can return duplicate keys, there is just no API to make sense + * of them. Skip them. */ + if (k + 1 < n_keys && nm_streq(key, keys[k + 1])) + continue; + + /* currently, the API is very simple. The setting class just returns + * the desired variant type, and keyfile reader will try to parse + * it accordingly. Note, that this does currently not allow, that + * a particular key can contain different variant types, nor is it + * very flexible in general. + * + * We add flexibility when we need it. Keep it simple for now. */ + variant_type = + sett_info->detail.gendata_info->get_variant_type(sett_info, key, &local); + if (!variant_type) { + if (!handle_warn(info, + key, + NULL, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid key '%s.%s'"), + info->group, + key)) + break; + continue; + } + + if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BOOLEAN)) { + gboolean v; + + v = g_key_file_get_boolean(info->keyfile, info->group, key, &local); + if (local) { + if (!handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("key '%s.%s' is not boolean"), + info->group, + key)) + break; + continue; + } + variant = g_variant_new_boolean(v); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT32)) { + guint64 v; + + v = g_key_file_get_uint64(info->keyfile, info->group, key, &local); + + if (local) { + if (!handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("key '%s.%s' is not a uint32"), + info->group, + key)) + break; + continue; + } + variant = g_variant_new_uint32((guint32) v); + } else { + nm_assert_not_reached(); + continue; + } + + g_hash_table_insert(h, g_steal_pointer(&key), g_variant_take_ref(variant)); + } + for (; k < n_keys; k++) + g_free(keys[k]); + } + } + + for (i = 0; i < sett_info->property_infos_len; i++) { + read_one_setting_value(info, setting, &sett_info->property_infos[i]); + if (info->error) + goto out; + } + +out: + info->setting = NULL; + if (!info->error) + nm_connection_add_setting(info->connection, g_steal_pointer(&setting)); +} + +static void +_read_setting_wireguard_peer(KeyfileReaderInfo *info) +{ + gs_unref_object NMSettingWireGuard *s_wg_new = NULL; + nm_auto_unref_wgpeer NMWireGuardPeer *peer = NULL; + gs_free_error GError *error = NULL; + NMSettingWireGuard * s_wg; + gs_free char * str = NULL; + const char * cstr = NULL; + const char * key; + gint64 i64; + gs_strfreev char ** sa = NULL; + gsize n_sa; + + peer = nm_wireguard_peer_new(); + + nm_assert(g_str_has_prefix(info->group, NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER)); + cstr = &info->group[NM_STRLEN(NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER)]; + if (!nm_utils_base64secret_normalize(cstr, NM_WIREGUARD_PUBLIC_KEY_LEN, &str) + || !nm_streq0(str, cstr)) { + /* the group name must be identical to the normalized(!) key, so that it + * is uniquely identified. */ + handle_warn(info, + NULL, + NM_SETTING_WIREGUARD_PEERS, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid peer public key in section '%s'"), + info->group); + return; + } + nm_wireguard_peer_set_public_key(peer, cstr, TRUE); + nm_clear_g_free(&str); + + key = NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY; + str = nm_keyfile_plugin_kf_get_string(info->keyfile, info->group, key, NULL); + if (str) { + if (!nm_wireguard_peer_set_preshared_key(peer, str, FALSE)) { + if (!handle_warn(info, + key, + NM_SETTING_WIREGUARD_PEERS, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("key '%s.%s' is not a valid 256 bit key in base64 encoding"), + info->group, + key)) + return; + } + nm_clear_g_free(&str); + } + + key = NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY_FLAGS; + i64 = nm_keyfile_plugin_kf_get_int64(info->keyfile, + info->group, + key, + 0, + 0, + NM_SETTING_SECRET_FLAG_ALL, + -1, + NULL); + if (errno != ENODATA) { + if (i64 == -1 || !_nm_setting_secret_flags_valid(i64)) { + if (!handle_warn(info, + key, + NM_SETTING_WIREGUARD_PEERS, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("key '%s.%s' is not a valid secret flag"), + info->group, + key)) + return; + } else + nm_wireguard_peer_set_preshared_key_flags(peer, i64); + } + + key = NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE; + i64 = nm_keyfile_plugin_kf_get_int64(info->keyfile, + info->group, + key, + 0, + 0, + G_MAXUINT32, + -1, + NULL); + if (errno != ENODATA) { + if (i64 == -1) { + if (!handle_warn(info, + key, + NM_SETTING_WIREGUARD_PEERS, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("key '%s.%s' is not a integer in range 0 to 2^32"), + info->group, + key)) + return; + } else + nm_wireguard_peer_set_persistent_keepalive(peer, i64); + } + + key = NM_WIREGUARD_PEER_ATTR_ENDPOINT; + str = nm_keyfile_plugin_kf_get_string(info->keyfile, info->group, key, NULL); + if (str && str[0]) { + if (!nm_wireguard_peer_set_endpoint(peer, str, FALSE)) { + if (!handle_warn(info, + key, + NM_SETTING_WIREGUARD_PEERS, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("key '%s.%s' is not a valid endpoint"), + info->group, + key)) + return; + } + } + nm_clear_g_free(&str); + + key = NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS; + sa = nm_keyfile_plugin_kf_get_string_list(info->keyfile, info->group, key, &n_sa, NULL); + if (n_sa > 0) { + gboolean has_error = FALSE; + gsize i; + + for (i = 0; i < n_sa; i++) { + if (!nm_utils_parse_inaddr_prefix_bin(AF_UNSPEC, sa[i], NULL, NULL, NULL)) { + has_error = TRUE; + continue; + } + nm_wireguard_peer_append_allowed_ip(peer, sa[i], TRUE); + } + if (has_error) { + if (!handle_warn(info, + key, + NM_SETTING_WIREGUARD_PEERS, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("key '%s.%s' has invalid allowed-ips"), + info->group, + key)) + return; + } + } + + if (info->error) + return; + + if (!nm_wireguard_peer_is_valid(peer, TRUE, TRUE, &error)) { + handle_warn(info, + NULL, + NM_SETTING_WIREGUARD_PEERS, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("peer '%s' is invalid: %s"), + info->group, + error->message); + return; + } + + s_wg = NM_SETTING_WIREGUARD( + nm_connection_get_setting(info->connection, NM_TYPE_SETTING_WIREGUARD)); + if (!s_wg) { + s_wg_new = NM_SETTING_WIREGUARD(nm_setting_wireguard_new()); + s_wg = s_wg_new; + } + + nm_setting_wireguard_append_peer(s_wg, peer); + + if (s_wg_new) { + nm_connection_add_setting(info->connection, NM_SETTING(g_steal_pointer(&s_wg_new))); + } +} + +static void +_read_setting_vpn_secrets(KeyfileReaderInfo *info) +{ + gs_strfreev char **keys = NULL; + gsize i, n_keys; + NMSettingVpn * s_vpn; + + s_vpn = nm_connection_get_setting_vpn(info->connection); + if (!s_vpn) { + /* if we don't also have a [vpn] section (which must be parsed earlier), + * we don't do anything. */ + nm_assert(!g_key_file_has_group(info->keyfile, "vpn")); + return; + } + + keys = + nm_keyfile_plugin_kf_get_keys(info->keyfile, NM_KEYFILE_GROUP_VPN_SECRETS, &n_keys, NULL); + for (i = 0; i < n_keys; i++) { + gs_free char *secret = NULL; + + secret = nm_keyfile_plugin_kf_get_string(info->keyfile, + NM_KEYFILE_GROUP_VPN_SECRETS, + keys[i], + NULL); + if (secret) + nm_setting_vpn_add_secret(s_vpn, keys[i], secret); + } +} + +gboolean +nm_keyfile_read_ensure_id(NMConnection *connection, const char *fallback_id) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(fallback_id, FALSE); + + s_con = nm_connection_get_setting_connection(connection); + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(s_con), FALSE); + + if (nm_setting_connection_get_id(s_con)) + return FALSE; + + g_object_set(s_con, NM_SETTING_CONNECTION_ID, fallback_id, NULL); + return TRUE; +} + +gboolean +nm_keyfile_read_ensure_uuid(NMConnection *connection, const char *fallback_uuid_seed) +{ + NMSettingConnection *s_con; + gs_free char * hashed_uuid = NULL; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(fallback_uuid_seed, FALSE); + + s_con = nm_connection_get_setting_connection(connection); + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(s_con), FALSE); + + if (nm_setting_connection_get_uuid(s_con)) + return FALSE; + + hashed_uuid = _nm_utils_uuid_generate_from_strings("keyfile", fallback_uuid_seed, NULL); + g_object_set(s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL); + return TRUE; +} + +/** + * nm_keyfile_read: + * @keyfile: the keyfile from which to create the connection + * @base_dir: when reading certificates from files with relative name, + * the relative path is made absolute using @base_dir. This must + * be an absolute path. + * @handler_flags: the #NMKeyfileHandlerFlags. + * @handler: (allow-none) (scope call): read handler + * @user_data: user data for read handler + * @error: (allow-none) (out): error + * + * Tries to create a NMConnection from a keyfile. The resulting keyfile is + * not normalized and might not even verify. + * + * Returns: (transfer full): on success, returns the created connection. + * + * Since: 1.30 + */ +NMConnection * +nm_keyfile_read(GKeyFile * keyfile, + const char * base_dir, + NMKeyfileHandlerFlags handler_flags, + NMKeyfileReadHandler handler, + void * user_data, + GError ** error) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + gs_strfreev char ** groups = NULL; + gsize n_groups; + gsize i; + gboolean vpn_secrets = FALSE; + KeyfileReaderInfo info; + + g_return_val_if_fail(keyfile, NULL); + g_return_val_if_fail(!error || !*error, NULL); + g_return_val_if_fail(base_dir && base_dir[0] == '/', NULL); + g_return_val_if_fail(handler_flags == NM_KEYFILE_HANDLER_FLAGS_NONE, NULL); + + connection = nm_simple_connection_new(); + + info = (KeyfileReaderInfo){ + .connection = connection, + .keyfile = keyfile, + .base_dir = base_dir, + .read_handler = handler, + .user_data = user_data, + }; + + groups = g_key_file_get_groups(keyfile, &n_groups); + if (!groups) + n_groups = 0; + + for (i = 0; i < n_groups; i++) { + info.group = groups[i]; + + if (nm_streq(groups[i], NM_KEYFILE_GROUP_VPN_SECRETS)) { + /* Only read out secrets when needed */ + vpn_secrets = TRUE; + } else if (NM_STR_HAS_PREFIX(groups[i], NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER)) + _read_setting_wireguard_peer(&info); + else if (NM_IN_STRSET(groups[i], + NM_KEYFILE_GROUP_NMMETA, + ETHERNET_S390_OPTIONS_GROUP_NAME)) { + /* pass */ + } else + _read_setting(&info); + + info.group = NULL; + + if (info.error) + goto out_with_info_error; + } + + s_con = nm_connection_get_setting_connection(connection); + if (!s_con) { + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + } + + /* Make sure that we have 'interface-name' even if it was specified in the + * "wrong" (ie, deprecated) group. + */ + if (!nm_setting_connection_get_interface_name(s_con) + && nm_setting_connection_get_connection_type(s_con)) { + gs_free char *interface_name = NULL; + + interface_name = g_key_file_get_string(keyfile, + nm_setting_connection_get_connection_type(s_con), + "interface-name", + NULL); + if (interface_name) + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, interface_name, NULL); + } + + if (vpn_secrets) { + info.group = NM_KEYFILE_GROUP_VPN_SECRETS; + _read_setting_vpn_secrets(&info); + info.group = NULL; + if (info.error) + goto out_with_info_error; + } + + return g_steal_pointer(&connection); + +out_with_info_error: + g_propagate_error(error, info.error); + return NULL; +} + +/*****************************************************************************/ + +static void +write_setting_value(KeyfileWriterInfo * info, + NMSetting * setting, + const NMSettInfoProperty *property_info) +{ + const NMMetaSettingInfo *setting_info; + const ParseInfoProperty *pip; + const char * key; + char numstr[64]; + GValue value; + GType type; + + nm_assert(!info->error); + nm_assert(!property_info->param_spec + || nm_streq(property_info->param_spec->name, property_info->name)); + + key = property_info->name; + + _parse_info_find(setting, key, &setting_info, NULL, &pip); + + if (!pip) { + if (!setting_info) { + /* the setting type is unknown. That is highly unexpected + * (and as this is currently only called from NetworkManager + * daemon, not possible). + * + * Still, handle it gracefully, because later keyfile writer will become + * public API of libnm, where @setting is (untrusted) user input. + * + * Gracefully here just means: ignore the setting. */ + return; + } + if (!property_info->param_spec) + return; + if (nm_streq(key, NM_SETTING_NAME)) + return; + } else { + if (pip->has_writer_full) { + pip->writer_full(info, setting_info, property_info, pip, setting); + return; + } + if (pip->writer_skip) + return; + } + + nm_assert(property_info->param_spec); + + /* Don't write secrets that are owned by user secret agents or aren't + * supposed to be saved. VPN secrets are handled specially though since + * the secret flags there are in a third-level hash in the 'secrets' + * property. + */ + if ((property_info->param_spec->flags & NM_SETTING_PARAM_SECRET) + && !NM_IS_SETTING_VPN(setting)) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + if (!nm_setting_get_secret_flags(setting, key, &secret_flags, NULL)) + g_return_if_reached(); + if (!_secret_flags_persist_secret(secret_flags)) + return; + } + + value = (GValue){0}; + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(property_info->param_spec)); + g_object_get_property(G_OBJECT(setting), property_info->param_spec->name, &value); + + if ((!pip || !pip->writer_persist_default) + && g_param_value_defaults(property_info->param_spec, &value)) { + nm_assert(!g_key_file_has_key(info->keyfile, setting_info->setting_name, key, NULL)); + goto out_unset_value; + } + + if (pip && pip->writer) { + pip->writer(info, setting, key, &value); + goto out_unset_value; + } + + type = G_VALUE_TYPE(&value); + if (type == G_TYPE_STRING) { + const char *str; + + str = g_value_get_string(&value); + if (str) + nm_keyfile_plugin_kf_set_string(info->keyfile, setting_info->setting_name, key, str); + } else if (type == G_TYPE_UINT) { + nm_sprintf_buf(numstr, "%u", g_value_get_uint(&value)); + nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr); + } else if (type == G_TYPE_INT) { + nm_sprintf_buf(numstr, "%d", g_value_get_int(&value)); + nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr); + } else if (type == G_TYPE_UINT64) { + nm_sprintf_buf(numstr, "%" G_GUINT64_FORMAT, g_value_get_uint64(&value)); + nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr); + } else if (type == G_TYPE_INT64) { + nm_sprintf_buf(numstr, "%" G_GINT64_FORMAT, g_value_get_int64(&value)); + nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr); + } else if (type == G_TYPE_BOOLEAN) { + nm_keyfile_plugin_kf_set_value(info->keyfile, + setting_info->setting_name, + key, + g_value_get_boolean(&value) ? "true" : "false"); + } else if (type == G_TYPE_CHAR) { + nm_sprintf_buf(numstr, "%d", (int) g_value_get_schar(&value)); + nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr); + } else if (type == G_TYPE_BYTES) { + GBytes * bytes; + const guint8 *data; + gsize len = 0; + + bytes = g_value_get_boxed(&value); + data = bytes ? g_bytes_get_data(bytes, &len) : NULL; + + if (data != NULL && len > 0) + nm_keyfile_plugin_kf_set_integer_list_uint8(info->keyfile, + setting_info->setting_name, + key, + data, + len); + } else if (type == G_TYPE_STRV) { + char **array; + + array = (char **) g_value_get_boxed(&value); + nm_keyfile_plugin_kf_set_string_list(info->keyfile, + setting_info->setting_name, + key, + (const char **const) array, + g_strv_length(array)); + } else if (type == G_TYPE_HASH_TABLE) { + write_hash_of_string(info->keyfile, setting, key, &value); + } else if (type == G_TYPE_ARRAY) { + write_array_of_uint(info->keyfile, setting, key, &value); + } else if (G_VALUE_HOLDS_FLAGS(&value)) { + nm_sprintf_buf(numstr, "%u", g_value_get_flags(&value)); + nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr); + } else if (G_VALUE_HOLDS_ENUM(&value)) { + nm_sprintf_buf(numstr, "%d", g_value_get_enum(&value)); + nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr); + } else + g_return_if_reached(); + +out_unset_value: + g_value_unset(&value); +} + +static void +_write_setting_wireguard(NMSetting *setting, KeyfileWriterInfo *info) +{ + NMSettingWireGuard *s_wg; + guint i_peer, n_peers; + + s_wg = NM_SETTING_WIREGUARD(setting); + + n_peers = nm_setting_wireguard_get_peers_len(s_wg); + for (i_peer = 0; i_peer < n_peers; i_peer++) { + NMWireGuardPeer * peer = nm_setting_wireguard_get_peer(s_wg, i_peer); + const char * public_key; + char group[NM_STRLEN(NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER) + 200]; + NMSettingSecretFlags secret_flags; + gboolean any_key = FALSE; + guint i_aip, n_aip; + const char * cstr; + guint32 u32; + + public_key = nm_wireguard_peer_get_public_key(peer); + if (!public_key || !public_key[0] + || !NM_STRCHAR_ALL(public_key, ch, nm_sd_utils_unbase64char(ch, TRUE) >= 0)) { + /* invalid peer. Skip it */ + continue; + } + + if (g_snprintf(group, + sizeof(group), + "%s%s", + NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER, + nm_wireguard_peer_get_public_key(peer)) + >= sizeof(group)) { + /* Too long. Not a valid public key. Skip the peer. */ + continue; + } + + cstr = nm_wireguard_peer_get_endpoint(peer); + if (cstr) { + g_key_file_set_string(info->keyfile, group, NM_WIREGUARD_PEER_ATTR_ENDPOINT, cstr); + any_key = TRUE; + } + + secret_flags = nm_wireguard_peer_get_preshared_key_flags(peer); + if (_secret_flags_persist_secret(secret_flags)) { + cstr = nm_wireguard_peer_get_preshared_key(peer); + if (cstr) { + g_key_file_set_string(info->keyfile, + group, + NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY, + cstr); + any_key = TRUE; + } + } + + /* usually, we don't persist the secret-flags 0 (because they are the default). + * For WireGuard peers, the default secret-flags for preshared-key are 4 (not-required). + * So, in this case behave differently: a missing preshared-key-flag setting means + * "not-required". */ + if (secret_flags != NM_SETTING_SECRET_FLAG_NOT_REQUIRED) { + g_key_file_set_int64(info->keyfile, + group, + NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY_FLAGS, + secret_flags); + any_key = TRUE; + } + + u32 = nm_wireguard_peer_get_persistent_keepalive(peer); + if (u32) { + g_key_file_set_uint64(info->keyfile, + group, + NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE, + u32); + any_key = TRUE; + } + + n_aip = nm_wireguard_peer_get_allowed_ips_len(peer); + if (n_aip > 0) { + gs_free const char **strv = NULL; + + strv = g_new(const char *, ((gsize) n_aip) + 1); + for (i_aip = 0; i_aip < n_aip; i_aip++) + strv[i_aip] = nm_wireguard_peer_get_allowed_ip(peer, i_aip, NULL); + strv[n_aip] = NULL; + g_key_file_set_string_list(info->keyfile, + group, + NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS, + strv, + n_aip); + any_key = TRUE; + } + + if (!any_key) { + /* we cannot omit all keys. At an empty endpoint. */ + g_key_file_set_string(info->keyfile, group, NM_WIREGUARD_PEER_ATTR_ENDPOINT, ""); + } + } +} + +/** + * nm_keyfile_write: + * @connection: the #NMConnection to persist to keyfile. + * @handler_flags: the #NMKeyfileHandlerFlags. + * @handler: (allow-none) (scope call): optional handler for events and + * to override the default behavior. + * @user_data: argument for @handler. + * @error: the #GError in case writing fails. + * + * @connection must verify as a valid profile according to + * nm_connection_verify(). + * + * Returns: (transfer full): a new #GKeyFile or %NULL on error. + * + * Since: 1.30 + */ +GKeyFile * +nm_keyfile_write(NMConnection * connection, + NMKeyfileHandlerFlags handler_flags, + NMKeyfileWriteHandler handler, + void * user_data, + GError ** error) +{ + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + GError * local = NULL; + KeyfileWriterInfo info; + gs_free NMSetting **settings = NULL; + guint n_settings = 0; + guint i; + guint j; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + g_return_val_if_fail(!error || !*error, NULL); + g_return_val_if_fail(handler_flags == NM_KEYFILE_HANDLER_FLAGS_NONE, NULL); + + /* Technically, we might not require that a profile is valid in + * order to serialize it. Like also nm_keyfile_read() does not + * ensure that the read profile validates. + * + * However, if the profile does not validate, then there might be + * unexpected edge cases when we try to serialize it. Edge cases + * that might result in dangerous crash. + * + * So, for now we require valid profiles. */ + if (!nm_connection_verify(connection, error ? &local : NULL)) { + if (error) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("the profile is not valid: %s"), + local->message); + g_error_free(local); + } else + nm_assert(!local); + return NULL; + } + + keyfile = g_key_file_new(); + + info = (KeyfileWriterInfo){ + .connection = connection, + .keyfile = keyfile, + .error = NULL, + .write_handler = handler, + .user_data = user_data, + }; + + settings = nm_connection_get_settings(connection, &n_settings); + for (i = 0; i < n_settings; i++) { + const NMSettInfoSetting *sett_info; + NMSetting * setting = settings[i]; + const char * setting_name; + const char * setting_alias; + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); + + setting_name = sett_info->setting_class->setting_info->setting_name; + + if (sett_info->detail.gendata_info) { + guint k, n_keys; + const char *const *keys; + + nm_assert(!nm_keyfile_plugin_get_alias_for_setting_name( + sett_info->setting_class->setting_info->setting_name)); + + n_keys = _nm_setting_option_get_all(setting, &keys, NULL); + + if (n_keys > 0) { + GHashTable *h = _nm_setting_option_hash(setting, FALSE); + + for (k = 0; k < n_keys; k++) { + const char *key = keys[k]; + GVariant * v; + + v = g_hash_table_lookup(h, key); + + if (g_variant_is_of_type(v, G_VARIANT_TYPE_BOOLEAN)) { + g_key_file_set_boolean(info.keyfile, + setting_name, + key, + g_variant_get_boolean(v)); + } else if (g_variant_is_of_type(v, G_VARIANT_TYPE_UINT32)) { + g_key_file_set_uint64(info.keyfile, + setting_name, + key, + (guint64) g_variant_get_uint32(v)); + } else { + /* BUG: The variant type is not implemented. Since the connection + * verifies, this can only mean we either wrongly didn't reject + * the connection as invalid, or we didn't properly implement the + * variant type. */ + nm_assert_not_reached(); + continue; + } + } + } + } + + for (j = 0; j < sett_info->property_infos_len; j++) { + const NMSettInfoProperty *property_info = + _nm_sett_info_property_info_get_sorted(sett_info, j); + + write_setting_value(&info, setting, property_info); + if (info.error) + goto out_with_info_error; + } + + setting_alias = nm_keyfile_plugin_get_alias_for_setting_name(setting_name); + if ((setting_alias && g_key_file_has_group(info.keyfile, setting_alias)) + || g_key_file_has_group(info.keyfile, setting_name)) { + /* we have a section for the setting. Nothing to do. */ + } else { + /* ensure the group is present. There is no API for that, so add and remove + * a dummy key. */ + g_key_file_set_value(info.keyfile, setting_alias ?: setting_name, ".X", "1"); + g_key_file_remove_key(info.keyfile, setting_alias ?: setting_name, ".X", NULL); + } + + if (NM_IS_SETTING_WIREGUARD(setting)) { + _write_setting_wireguard(setting, &info); + if (info.error) + goto out_with_info_error; + } + + nm_assert(!info.error); + } + + nm_assert(!info.error); + + return g_steal_pointer(&keyfile); + +out_with_info_error: + g_propagate_error(error, info.error); + return NULL; +} + +/*****************************************************************************/ + +static const char temp_letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +/* + * Check '.[a-zA-Z0-9]{6}' file suffix used for temporary files by g_file_set_contents() (mkstemp()). + */ +static gboolean +check_mkstemp_suffix(const char *path) +{ + const char *ptr; + + nm_assert(path); + + /* Matches *.[a-zA-Z0-9]{6} suffix of mkstemp()'s temporary files */ + ptr = strrchr(path, '.'); + if (ptr && strspn(&ptr[1], temp_letters) == 6 && ptr[7] == '\0') + return TRUE; + return FALSE; +} + +#define SWP_TAG ".swp" +#define SWPX_TAG ".swpx" +#define PEM_TAG ".pem" +#define DER_TAG ".der" + +gboolean +nm_keyfile_utils_ignore_filename(const char *filename, gboolean require_extension) +{ + const char *base; + gsize l; + + /* ignore_filename() must mirror nm_keyfile_utils_create_filename() */ + + g_return_val_if_fail(filename, TRUE); + + base = strrchr(filename, '/'); + if (base) + base++; + else + base = filename; + + if (!base[0]) { + /* this check above with strrchr() also rejects "/some/path/with/trailing/slash/", + * but that is fine, because such a path would name a directory, and we are not + * interested in directories. */ + return TRUE; + } + + if (base[0] == '.') { + /* don't allow hidden files */ + return TRUE; + } + + if (require_extension) { + if (!NM_STR_HAS_SUFFIX_WITH_MORE(base, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)) + return TRUE; + return FALSE; + } + + l = strlen(base); + + /* Ignore backup files */ + if (base[l - 1] == '~') + return TRUE; + + /* Ignore temporary files + * + * This check is also important to ignore .nmload files (see + * %NM_KEYFILE_PATH_SUFFIX_NMMETA). */ + if (check_mkstemp_suffix(base)) + return TRUE; + + /* Ignore 802.1x certificates and keys */ + if (NM_STR_HAS_SUFFIX_ASCII_CASE_WITH_MORE(base, PEM_TAG) + || NM_STR_HAS_SUFFIX_ASCII_CASE_WITH_MORE(base, DER_TAG)) + return TRUE; + + return FALSE; +} + +char * +nm_keyfile_utils_create_filename(const char *name, gboolean with_extension) +{ + /* keyfile used to escape with '*', do not change that behavior. + * + * But for newly added escapings, use '_' instead. + * Also, @with_extension is new-style. */ + const char ESCAPE_CHAR = with_extension ? '_' : '*'; + const char ESCAPE_CHAR2 = '_'; + NMStrBuf str; + char * p; + gsize len; + gsize i; + + g_return_val_if_fail(name && name[0], NULL); + + nm_str_buf_init(&str, 0, FALSE); + + len = strlen(name); + + p = nm_str_buf_append_len0(&str, name, len); + + /* Convert '/' to ESCAPE_CHAR */ + for (i = 0; i < len; i++) { + if (p[i] == '/') + p[i] = ESCAPE_CHAR; + } + + /* nm_keyfile_utils_create_filename() must avoid anything that ignore_filename() would reject. + * We can escape here more aggressively then what we would read back. */ + if (p[0] == '.') + p[0] = ESCAPE_CHAR2; + if (p[str.len - 1] == '~') + p[str.len - 1] = ESCAPE_CHAR2; + + if (check_mkstemp_suffix(p) || NM_STR_HAS_SUFFIX_ASCII_CASE_WITH_MORE(p, PEM_TAG) + || NM_STR_HAS_SUFFIX_ASCII_CASE_WITH_MORE(p, DER_TAG)) + nm_str_buf_append_c(&str, ESCAPE_CHAR2); + + if (with_extension) + nm_str_buf_append(&str, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION); + + p = nm_str_buf_finalize(&str, NULL); + + /* nm_keyfile_utils_create_filename() must mirror ignore_filename() */ + nm_assert(!strchr(p, '/')); + nm_assert(!nm_keyfile_utils_ignore_filename(p, with_extension)); + + return p; +} + +/*****************************************************************************/ + +/** + * nm_keyfile_handler_data_fail_with_error: + * @handler_data: the #NMKeyfileHandlerData + * @src: (transfer full): error to move into the return location + * + * Set the error for the handler. This lets the operation fail + * with the provided error. You may only set the error once. + * + * @src must be non-%NULL. + * + * Note that @src is no longer valid after this call. If you want + * to keep using the same GError*, you need to set it to %NULL + * after calling this function on it. + * + * Since: 1.30 + */ +void +nm_keyfile_handler_data_fail_with_error(NMKeyfileHandlerData *handler_data, GError *src) +{ + g_return_if_fail(handler_data); + g_return_if_fail(handler_data->p_error && !*handler_data->p_error); + g_return_if_fail(src); + + *handler_data->p_error = src; +} + +/** + * nm_keyfile_handler_data_get_context: + * @handler_data: the #NMKeyfileHandlerData for any event. + * @out_kf_group_name: (out) (allow-none) (transfer none): if the event is in the + * context of a keyfile group, the group name. + * @out_kf_key_name: (out) (allow-none) (transfer none): if the event is in the + * context of a keyfile value, the key name. + * @out_cur_setting: (out) (allow-none) (transfer none): if the event happens while + * handling a particular #NMSetting instance. + * @out_cur_property_name: (out) (allow-none) (transfer none): the property name if applicable. + * + * Get context information of the current event. This function can be called + * on all events, but the context information may be unset. + * + * Since: 1.30 + */ +void +nm_keyfile_handler_data_get_context(const NMKeyfileHandlerData *handler_data, + const char ** out_kf_group_name, + const char ** out_kf_key_name, + NMSetting ** out_cur_setting, + const char ** out_cur_property_name) +{ + g_return_if_fail(handler_data); + + NM_SET_OUT(out_kf_group_name, handler_data->kf_group_name); + NM_SET_OUT(out_kf_key_name, handler_data->kf_key); + NM_SET_OUT(out_cur_setting, handler_data->cur_setting); + NM_SET_OUT(out_cur_property_name, handler_data->cur_property); +} + +const char * +_nm_keyfile_handler_data_warn_get_message(const NMKeyfileHandlerData *handler_data) +{ + nm_assert(handler_data); + nm_assert(handler_data->type == NM_KEYFILE_HANDLER_TYPE_WARN); + + if (!handler_data->warn.message) { + /* we cast the const away. @handler_data is const w.r.t. visible mutations + * from POV of the user. Internally, we construct the message in + * a lazy manner. It's like a mutable field in C++. */ + NM_PRAGMA_WARNING_DISABLE("-Wformat-nonliteral") + ((NMKeyfileHandlerData *) handler_data)->warn.message = + g_strdup_vprintf(handler_data->warn.fmt, + ((NMKeyfileHandlerData *) handler_data)->warn.ap); + NM_PRAGMA_WARNING_REENABLE + } + return handler_data->warn.message; +} + +/** + * nm_keyfile_handler_data_warn_get: + * @handler_data: the #NMKeyfileHandlerData for a %NM_KEYFILE_HANDLER_TYPE_WARN + * event. + * @out_message: (out) (allow-none) (transfer none): the warning message. + * @out_severity: (out) (allow-none): the #NMKeyfileWarnSeverity warning severity. + * + * Since: 1.30 + */ +void +nm_keyfile_handler_data_warn_get(const NMKeyfileHandlerData *handler_data, + const char ** out_message, + NMKeyfileWarnSeverity * out_severity) +{ + g_return_if_fail(handler_data); + g_return_if_fail(handler_data->type == NM_KEYFILE_HANDLER_TYPE_WARN); + + NM_SET_OUT(out_message, _nm_keyfile_handler_data_warn_get_message(handler_data)); + NM_SET_OUT(out_severity, handler_data->warn.severity); +} diff --git a/src/libnm-core-impl/nm-meta-setting-base-impl.c b/src/libnm-core-impl/nm-meta-setting-base-impl.c new file mode 100644 index 0000000..da85e56 --- /dev/null +++ b/src/libnm-core-impl/nm-meta-setting-base-impl.c @@ -0,0 +1,641 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 - 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-meta-setting-base.h" + +#include "nm-setting-6lowpan.h" +#include "nm-setting-8021x.h" +#include "nm-setting-adsl.h" +#include "nm-setting-bluetooth.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-bridge.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-dcb.h" +#include "nm-setting-dummy.h" +#include "nm-setting-ethtool.h" +#include "nm-setting-generic.h" +#include "nm-setting-gsm.h" +#include "nm-setting-hostname.h" +#include "nm-setting-infiniband.h" +#include "nm-setting-ip-config.h" +#include "nm-setting-ip-tunnel.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" +#include "nm-setting-macsec.h" +#include "nm-setting-macvlan.h" +#include "nm-setting-match.h" +#include "nm-setting-olpc-mesh.h" +#include "nm-setting-ovs-bridge.h" +#include "nm-setting-ovs-interface.h" +#include "nm-setting-ovs-dpdk.h" +#include "nm-setting-ovs-external-ids.h" +#include "nm-setting-ovs-patch.h" +#include "nm-setting-ovs-port.h" +#include "nm-setting-ppp.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-proxy.h" +#include "nm-setting-serial.h" +#include "nm-setting-tc-config.h" +#include "nm-setting-team-port.h" +#include "nm-setting-team.h" +#include "nm-setting-tun.h" +#include "nm-setting-user.h" +#include "nm-setting-veth.h" +#include "nm-setting-vlan.h" +#include "nm-setting-vpn.h" +#include "nm-setting-vrf.h" +#include "nm-setting-vxlan.h" +#include "nm-setting-wifi-p2p.h" +#include "nm-setting-wimax.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireguard.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wpan.h" + +/*****************************************************************************/ + +const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = { + +#define _D(_scheme_type, ...) [(_scheme_type)] = {.scheme_type = (_scheme_type), __VA_ARGS__} + + _D(NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT, + .setting_key = NM_SETTING_802_1X_CA_CERT, + .scheme_func = nm_setting_802_1x_get_ca_cert_scheme, + .format_func = NULL, + .path_func = nm_setting_802_1x_get_ca_cert_path, + .blob_func = nm_setting_802_1x_get_ca_cert_blob, + .uri_func = nm_setting_802_1x_get_ca_cert_uri, + .passwd_func = nm_setting_802_1x_get_ca_cert_password, + .pwflag_func = nm_setting_802_1x_get_ca_cert_password_flags, + .set_cert_func = nm_setting_802_1x_set_ca_cert, + .file_suffix = "ca-cert", ), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT, + .setting_key = NM_SETTING_802_1X_PHASE2_CA_CERT, + .scheme_func = nm_setting_802_1x_get_phase2_ca_cert_scheme, + .format_func = NULL, + .path_func = nm_setting_802_1x_get_phase2_ca_cert_path, + .blob_func = nm_setting_802_1x_get_phase2_ca_cert_blob, + .uri_func = nm_setting_802_1x_get_phase2_ca_cert_uri, + .passwd_func = nm_setting_802_1x_get_phase2_ca_cert_password, + .pwflag_func = nm_setting_802_1x_get_phase2_ca_cert_password_flags, + .set_cert_func = nm_setting_802_1x_set_phase2_ca_cert, + .file_suffix = "inner-ca-cert", ), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT, + .setting_key = NM_SETTING_802_1X_CLIENT_CERT, + .scheme_func = nm_setting_802_1x_get_client_cert_scheme, + .format_func = NULL, + .path_func = nm_setting_802_1x_get_client_cert_path, + .blob_func = nm_setting_802_1x_get_client_cert_blob, + .uri_func = nm_setting_802_1x_get_client_cert_uri, + .passwd_func = nm_setting_802_1x_get_client_cert_password, + .pwflag_func = nm_setting_802_1x_get_client_cert_password_flags, + .set_cert_func = nm_setting_802_1x_set_client_cert, + .file_suffix = "client-cert", ), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT, + .setting_key = NM_SETTING_802_1X_PHASE2_CLIENT_CERT, + .scheme_func = nm_setting_802_1x_get_phase2_client_cert_scheme, + .format_func = NULL, + .path_func = nm_setting_802_1x_get_phase2_client_cert_path, + .blob_func = nm_setting_802_1x_get_phase2_client_cert_blob, + .uri_func = nm_setting_802_1x_get_phase2_client_cert_uri, + .passwd_func = nm_setting_802_1x_get_phase2_client_cert_password, + .pwflag_func = nm_setting_802_1x_get_phase2_client_cert_password_flags, + .set_cert_func = nm_setting_802_1x_set_phase2_client_cert, + .file_suffix = "inner-client-cert", ), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY, + .setting_key = NM_SETTING_802_1X_PRIVATE_KEY, + .scheme_func = nm_setting_802_1x_get_private_key_scheme, + .format_func = nm_setting_802_1x_get_private_key_format, + .path_func = nm_setting_802_1x_get_private_key_path, + .blob_func = nm_setting_802_1x_get_private_key_blob, + .uri_func = nm_setting_802_1x_get_private_key_uri, + .passwd_func = nm_setting_802_1x_get_private_key_password, + .pwflag_func = nm_setting_802_1x_get_private_key_password_flags, + .set_private_key_func = nm_setting_802_1x_set_private_key, + .file_suffix = "private-key", + .is_secret = TRUE, ), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY, + .setting_key = NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + .scheme_func = nm_setting_802_1x_get_phase2_private_key_scheme, + .format_func = nm_setting_802_1x_get_phase2_private_key_format, + .path_func = nm_setting_802_1x_get_phase2_private_key_path, + .blob_func = nm_setting_802_1x_get_phase2_private_key_blob, + .uri_func = nm_setting_802_1x_get_phase2_private_key_uri, + .passwd_func = nm_setting_802_1x_get_phase2_private_key_password, + .pwflag_func = nm_setting_802_1x_get_phase2_private_key_password_flags, + .set_private_key_func = nm_setting_802_1x_set_phase2_private_key, + .file_suffix = "inner-private-key", + .is_secret = TRUE, ), + +#undef _D +}; + +/*****************************************************************************/ + +const NMMetaSettingInfo nm_meta_setting_infos[] = { + [NM_META_SETTING_TYPE_6LOWPAN] = + { + .meta_type = NM_META_SETTING_TYPE_6LOWPAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_6LOWPAN_SETTING_NAME, + .get_setting_gtype = nm_setting_6lowpan_get_type, + }, + [NM_META_SETTING_TYPE_802_1X] = + { + .meta_type = NM_META_SETTING_TYPE_802_1X, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, + .setting_name = NM_SETTING_802_1X_SETTING_NAME, + .get_setting_gtype = nm_setting_802_1x_get_type, + }, + [NM_META_SETTING_TYPE_ADSL] = + { + .meta_type = NM_META_SETTING_TYPE_ADSL, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_ADSL_SETTING_NAME, + .get_setting_gtype = nm_setting_adsl_get_type, + }, + [NM_META_SETTING_TYPE_BLUETOOTH] = + { + .meta_type = NM_META_SETTING_TYPE_BLUETOOTH, + .setting_priority = NM_SETTING_PRIORITY_HW_NON_BASE, + .setting_name = NM_SETTING_BLUETOOTH_SETTING_NAME, + .get_setting_gtype = nm_setting_bluetooth_get_type, + }, + [NM_META_SETTING_TYPE_BOND] = + { + .meta_type = NM_META_SETTING_TYPE_BOND, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_BOND_SETTING_NAME, + .get_setting_gtype = nm_setting_bond_get_type, + }, + [NM_META_SETTING_TYPE_BRIDGE] = + { + .meta_type = NM_META_SETTING_TYPE_BRIDGE, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_BRIDGE_SETTING_NAME, + .get_setting_gtype = nm_setting_bridge_get_type, + }, + [NM_META_SETTING_TYPE_BRIDGE_PORT] = + { + .meta_type = NM_META_SETTING_TYPE_BRIDGE_PORT, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_BRIDGE_PORT_SETTING_NAME, + .get_setting_gtype = nm_setting_bridge_port_get_type, + }, + [NM_META_SETTING_TYPE_CDMA] = + { + .meta_type = NM_META_SETTING_TYPE_CDMA, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_CDMA_SETTING_NAME, + .get_setting_gtype = nm_setting_cdma_get_type, + }, + [NM_META_SETTING_TYPE_CONNECTION] = + { + .meta_type = NM_META_SETTING_TYPE_CONNECTION, + .setting_priority = NM_SETTING_PRIORITY_CONNECTION, + .setting_name = NM_SETTING_CONNECTION_SETTING_NAME, + .get_setting_gtype = nm_setting_connection_get_type, + }, + [NM_META_SETTING_TYPE_DCB] = + { + .meta_type = NM_META_SETTING_TYPE_DCB, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, + .setting_name = NM_SETTING_DCB_SETTING_NAME, + .get_setting_gtype = nm_setting_dcb_get_type, + }, + [NM_META_SETTING_TYPE_DUMMY] = + { + .meta_type = NM_META_SETTING_TYPE_DUMMY, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_DUMMY_SETTING_NAME, + .get_setting_gtype = nm_setting_dummy_get_type, + }, + [NM_META_SETTING_TYPE_ETHTOOL] = + { + .meta_type = NM_META_SETTING_TYPE_ETHTOOL, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_ETHTOOL_SETTING_NAME, + .get_setting_gtype = nm_setting_ethtool_get_type, + }, + [NM_META_SETTING_TYPE_GENERIC] = + { + .meta_type = NM_META_SETTING_TYPE_GENERIC, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_GENERIC_SETTING_NAME, + .get_setting_gtype = nm_setting_generic_get_type, + }, + [NM_META_SETTING_TYPE_GSM] = + { + .meta_type = NM_META_SETTING_TYPE_GSM, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_GSM_SETTING_NAME, + .get_setting_gtype = nm_setting_gsm_get_type, + }, + [NM_META_SETTING_TYPE_HOSTNAME] = + { + .meta_type = NM_META_SETTING_TYPE_HOSTNAME, + .setting_priority = NM_SETTING_PRIORITY_IP, + .setting_name = NM_SETTING_HOSTNAME_SETTING_NAME, + .get_setting_gtype = nm_setting_hostname_get_type, + }, + [NM_META_SETTING_TYPE_INFINIBAND] = + { + .meta_type = NM_META_SETTING_TYPE_INFINIBAND, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_INFINIBAND_SETTING_NAME, + .get_setting_gtype = nm_setting_infiniband_get_type, + }, + [NM_META_SETTING_TYPE_IP4_CONFIG] = + { + .meta_type = NM_META_SETTING_TYPE_IP4_CONFIG, + .setting_priority = NM_SETTING_PRIORITY_IP, + .setting_name = NM_SETTING_IP4_CONFIG_SETTING_NAME, + .get_setting_gtype = nm_setting_ip4_config_get_type, + }, + [NM_META_SETTING_TYPE_IP6_CONFIG] = + { + .meta_type = NM_META_SETTING_TYPE_IP6_CONFIG, + .setting_priority = NM_SETTING_PRIORITY_IP, + .setting_name = NM_SETTING_IP6_CONFIG_SETTING_NAME, + .get_setting_gtype = nm_setting_ip6_config_get_type, + }, + [NM_META_SETTING_TYPE_IP_TUNNEL] = + { + .meta_type = NM_META_SETTING_TYPE_IP_TUNNEL, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_IP_TUNNEL_SETTING_NAME, + .get_setting_gtype = nm_setting_ip_tunnel_get_type, + }, + [NM_META_SETTING_TYPE_MACSEC] = + { + .meta_type = NM_META_SETTING_TYPE_MACSEC, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_MACSEC_SETTING_NAME, + .get_setting_gtype = nm_setting_macsec_get_type, + }, + [NM_META_SETTING_TYPE_MACVLAN] = + { + .meta_type = NM_META_SETTING_TYPE_MACVLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_MACVLAN_SETTING_NAME, + .get_setting_gtype = nm_setting_macvlan_get_type, + }, + [NM_META_SETTING_TYPE_MATCH] = + { + .meta_type = NM_META_SETTING_TYPE_MATCH, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_MATCH_SETTING_NAME, + .get_setting_gtype = nm_setting_match_get_type, + }, + [NM_META_SETTING_TYPE_OLPC_MESH] = + { + .meta_type = NM_META_SETTING_TYPE_OLPC_MESH, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OLPC_MESH_SETTING_NAME, + .get_setting_gtype = nm_setting_olpc_mesh_get_type, + }, + [NM_META_SETTING_TYPE_OVS_BRIDGE] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_BRIDGE, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OVS_BRIDGE_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_bridge_get_type, + }, + [NM_META_SETTING_TYPE_OVS_DPDK] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_DPDK, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OVS_DPDK_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_dpdk_get_type, + }, + [NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_external_ids_get_type, + }, + [NM_META_SETTING_TYPE_OVS_INTERFACE] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_INTERFACE, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OVS_INTERFACE_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_interface_get_type, + }, + [NM_META_SETTING_TYPE_OVS_PATCH] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_PATCH, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OVS_PATCH_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_patch_get_type, + }, + [NM_META_SETTING_TYPE_OVS_PORT] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_PORT, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OVS_PORT_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_port_get_type, + }, + [NM_META_SETTING_TYPE_PPPOE] = + { + .meta_type = NM_META_SETTING_TYPE_PPPOE, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_PPPOE_SETTING_NAME, + .get_setting_gtype = nm_setting_pppoe_get_type, + }, + [NM_META_SETTING_TYPE_PPP] = + { + .meta_type = NM_META_SETTING_TYPE_PPP, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_PPP_SETTING_NAME, + .get_setting_gtype = nm_setting_ppp_get_type, + }, + [NM_META_SETTING_TYPE_PROXY] = + { + .meta_type = NM_META_SETTING_TYPE_PROXY, + .setting_priority = NM_SETTING_PRIORITY_IP, + .setting_name = NM_SETTING_PROXY_SETTING_NAME, + .get_setting_gtype = nm_setting_proxy_get_type, + }, + [NM_META_SETTING_TYPE_SERIAL] = + { + .meta_type = NM_META_SETTING_TYPE_SERIAL, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, + .setting_name = NM_SETTING_SERIAL_SETTING_NAME, + .get_setting_gtype = nm_setting_serial_get_type, + }, + [NM_META_SETTING_TYPE_SRIOV] = + { + .meta_type = NM_META_SETTING_TYPE_SRIOV, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, + .setting_name = NM_SETTING_SRIOV_SETTING_NAME, + .get_setting_gtype = nm_setting_sriov_get_type, + }, + [NM_META_SETTING_TYPE_TC_CONFIG] = + { + .meta_type = NM_META_SETTING_TYPE_TC_CONFIG, + .setting_priority = NM_SETTING_PRIORITY_IP, + .setting_name = NM_SETTING_TC_CONFIG_SETTING_NAME, + .get_setting_gtype = nm_setting_tc_config_get_type, + }, + [NM_META_SETTING_TYPE_TEAM] = + { + .meta_type = NM_META_SETTING_TYPE_TEAM, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_TEAM_SETTING_NAME, + .get_setting_gtype = nm_setting_team_get_type, + }, + [NM_META_SETTING_TYPE_TEAM_PORT] = + { + .meta_type = NM_META_SETTING_TYPE_TEAM_PORT, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_TEAM_PORT_SETTING_NAME, + .get_setting_gtype = nm_setting_team_port_get_type, + }, + [NM_META_SETTING_TYPE_TUN] = + { + .meta_type = NM_META_SETTING_TYPE_TUN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_TUN_SETTING_NAME, + .get_setting_gtype = nm_setting_tun_get_type, + }, + [NM_META_SETTING_TYPE_USER] = + { + .meta_type = NM_META_SETTING_TYPE_USER, + .setting_priority = NM_SETTING_PRIORITY_USER, + .setting_name = NM_SETTING_USER_SETTING_NAME, + .get_setting_gtype = nm_setting_user_get_type, + }, + [NM_META_SETTING_TYPE_VETH] = + { + .meta_type = NM_META_SETTING_TYPE_VETH, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VETH_SETTING_NAME, + .get_setting_gtype = nm_setting_veth_get_type, + }, + [NM_META_SETTING_TYPE_VLAN] = + { + .meta_type = NM_META_SETTING_TYPE_VLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VLAN_SETTING_NAME, + .get_setting_gtype = nm_setting_vlan_get_type, + }, + [NM_META_SETTING_TYPE_VPN] = + { + .meta_type = NM_META_SETTING_TYPE_VPN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VPN_SETTING_NAME, + .get_setting_gtype = nm_setting_vpn_get_type, + }, + [NM_META_SETTING_TYPE_VRF] = + { + .meta_type = NM_META_SETTING_TYPE_VRF, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VRF_SETTING_NAME, + .get_setting_gtype = nm_setting_vrf_get_type, + }, + [NM_META_SETTING_TYPE_VXLAN] = + { + .meta_type = NM_META_SETTING_TYPE_VXLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VXLAN_SETTING_NAME, + .get_setting_gtype = nm_setting_vxlan_get_type, + }, + [NM_META_SETTING_TYPE_WIFI_P2P] = + { + .meta_type = NM_META_SETTING_TYPE_WIFI_P2P, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WIFI_P2P_SETTING_NAME, + .get_setting_gtype = nm_setting_wifi_p2p_get_type, + }, + [NM_META_SETTING_TYPE_WIMAX] = + { + .meta_type = NM_META_SETTING_TYPE_WIMAX, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WIMAX_SETTING_NAME, + .get_setting_gtype = nm_setting_wimax_get_type, + }, + [NM_META_SETTING_TYPE_WIRED] = + { + .meta_type = NM_META_SETTING_TYPE_WIRED, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WIRED_SETTING_NAME, + .get_setting_gtype = nm_setting_wired_get_type, + }, + [NM_META_SETTING_TYPE_WIREGUARD] = + { + .meta_type = NM_META_SETTING_TYPE_WIREGUARD, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WIREGUARD_SETTING_NAME, + .get_setting_gtype = nm_setting_wireguard_get_type, + }, + [NM_META_SETTING_TYPE_WIRELESS] = + { + .meta_type = NM_META_SETTING_TYPE_WIRELESS, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WIRELESS_SETTING_NAME, + .get_setting_gtype = nm_setting_wireless_get_type, + }, + [NM_META_SETTING_TYPE_WIRELESS_SECURITY] = + { + .meta_type = NM_META_SETTING_TYPE_WIRELESS_SECURITY, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, + .setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + .get_setting_gtype = nm_setting_wireless_security_get_type, + }, + [NM_META_SETTING_TYPE_WPAN] = + { + .meta_type = NM_META_SETTING_TYPE_WPAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WPAN_SETTING_NAME, + .get_setting_gtype = nm_setting_wpan_get_type, + }, + + [NM_META_SETTING_TYPE_UNKNOWN] = + { + .meta_type = NM_META_SETTING_TYPE_UNKNOWN, + }, +}; + +const NMMetaSettingInfo * +nm_meta_setting_infos_by_name(const char *name) +{ + gssize idx; + + if (NM_MORE_ASSERTS > 10) { + guint i, j; + + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + const NMMetaSettingInfo *setting_info = &nm_meta_setting_infos[i]; + + nm_assert(setting_info->meta_type == (NMMetaSettingType) i); + nm_assert(setting_info->setting_name); + nm_assert(setting_info->setting_name[0]); + nm_assert(setting_info->get_setting_gtype); + nm_assert(setting_info->setting_priority != NM_SETTING_PRIORITY_INVALID); + if (i > 0 + && strcmp(nm_meta_setting_infos[i - 1].setting_name, setting_info->setting_name) + >= 0) { + g_error("nm_meta_setting_infos[%u, \"%s\"] is wrongly sorted before " + "nm_meta_setting_infos[%u, \"%s\"]. Rearange NMMetaSettingType enum", + i - 1, + nm_meta_setting_infos[i - 1].setting_name, + i, + setting_info->setting_name); + } + for (j = 0; j < i; j++) { + const NMMetaSettingInfo *s = &nm_meta_setting_infos[j]; + + nm_assert(setting_info->get_setting_gtype != s->get_setting_gtype); + } + } + } + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMMetaSettingInfo, setting_name) == 0); + idx = nm_utils_array_find_binary_search(nm_meta_setting_infos, + sizeof(NMMetaSettingInfo), + _NM_META_SETTING_TYPE_NUM, + &name, + nm_strcmp_p_with_data, + NULL); + + return idx >= 0 ? &nm_meta_setting_infos[idx] : NULL; +} + +const NMMetaSettingInfo * +nm_meta_setting_infos_by_gtype(GType gtype) +{ +#if _NM_META_SETTING_BASE_IMPL_LIBNM + nm_auto_unref_gtypeclass GTypeClass *gtypeclass_unref = NULL; + GTypeClass * gtypeclass; + NMSettingClass * klass; + + if (!g_type_is_a(gtype, NM_TYPE_SETTING)) + goto out_none; + + gtypeclass = g_type_class_peek(gtype); + if (!gtypeclass) + gtypeclass = gtypeclass_unref = g_type_class_ref(gtype); + + nm_assert(NM_IS_SETTING_CLASS(gtypeclass)); + + klass = (NMSettingClass *) gtypeclass; + + if (!klass->setting_info) + goto out_none; + + nm_assert(klass->setting_info->get_setting_gtype); + nm_assert(klass->setting_info->get_setting_gtype() == gtype); + + return klass->setting_info; + +out_none: + + if (NM_MORE_ASSERTS > 10) { + int i; + + /* this might hint to a bug, but it would be expected for NM_TYPE_SETTING + * and NM_TYPE_SETTING_IP_CONFIG. + * + * Assert that we didn't lookup for a gtype, which we would expect to find. + * An assertion failure here, hints to a bug in nm_setting_*_class_init(). + */ + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) + nm_assert(nm_meta_setting_infos[i].get_setting_gtype() != gtype); + } + + return NULL; +#else + guint i; + + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + if (nm_meta_setting_infos[i].get_setting_gtype() == gtype) + return &nm_meta_setting_infos[i]; + } + return NULL; +#endif +} + +/*****************************************************************************/ + +NMSettingPriority +nm_meta_setting_info_get_base_type_priority(const NMMetaSettingInfo *setting_info, GType gtype) +{ + /* Historical oddity: PPPoE is a base-type even though it's not + * priority 1. It needs to be sorted *after* lower-level stuff like + * Wi-Fi security or 802.1x for secrets, but it's still allowed as a + * base type. + */ + + if (setting_info) { + if (NM_IN_SET(setting_info->setting_priority, + NM_SETTING_PRIORITY_HW_BASE, + NM_SETTING_PRIORITY_HW_NON_BASE) + || gtype == NM_TYPE_SETTING_PPPOE) + return setting_info->setting_priority; + } + + return NM_SETTING_PRIORITY_INVALID; +} + +NMSettingPriority +_nm_setting_type_get_base_type_priority(GType type) +{ + return nm_meta_setting_info_get_base_type_priority(nm_meta_setting_infos_by_gtype(type), type); +} + +/*****************************************************************************/ diff --git a/src/libnm-core-impl/nm-property-compare.c b/src/libnm-core-impl/nm-property-compare.c new file mode 100644 index 0000000..4347d6d --- /dev/null +++ b/src/libnm-core-impl/nm-property-compare.c @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-property-compare.h" + +#include + +static int +_nm_property_compare_collection(GVariant *value1, GVariant *value2) +{ + GVariant *child1, *child2; + int i, len1, len2; + int ret; + + len1 = g_variant_n_children(value1); + len2 = g_variant_n_children(value2); + + if (len1 != len2) + return len1 < len2 ? -1 : len1 > len2; + + for (i = 0; i < len1; i++) { + child1 = g_variant_get_child_value(value1, i); + child2 = g_variant_get_child_value(value2, i); + + ret = nm_property_compare(child1, child2); + g_variant_unref(child1); + g_variant_unref(child2); + + if (ret) + return ret; + } + + return 0; +} + +static int +_nm_property_compare_vardict(GVariant *value1, GVariant *value2) +{ + GVariantIter iter; + int len1, len2; + const char * key; + GVariant * val1, *val2; + + len1 = g_variant_n_children(value1); + len2 = g_variant_n_children(value2); + + if (len1 != len2) + return len1 < len2 ? -1 : 1; + + g_variant_iter_init(&iter, value1); + while (g_variant_iter_next(&iter, "{&sv}", &key, &val1)) { + if (!g_variant_lookup(value2, key, "v", &val2)) { + g_variant_unref(val1); + return -1; + } + if (!g_variant_equal(val1, val2)) { + g_variant_unref(val1); + g_variant_unref(val2); + return -1; + } + g_variant_unref(val1); + g_variant_unref(val2); + } + + return 0; +} + +static int +_nm_property_compare_strdict(GVariant *value1, GVariant *value2) +{ + GVariantIter iter; + int len1, len2; + const char * key, *val1, *val2; + int ret; + + len1 = g_variant_n_children(value1); + len2 = g_variant_n_children(value2); + + if (len1 != len2) + return len1 < len2 ? -1 : len1 > len2; + + g_variant_iter_init(&iter, value1); + while (g_variant_iter_next(&iter, "{&s&s}", &key, &val1)) { + if (!g_variant_lookup(value2, key, "&s", &val2)) + return -1; + + ret = strcmp(val1, val2); + if (ret) + return ret; + } + + return 0; +} + +int +nm_property_compare(GVariant *value1, GVariant *value2) +{ + const GVariantType *type1; + const GVariantType *type2; + int ret; + + if (value1 == value2) + return 0; + if (!value1) + return 1; + if (!value2) + return -1; + + type1 = g_variant_get_type(value1); + type2 = g_variant_get_type(value2); + + if (!g_variant_type_equal(type1, type2)) + return type1 < type2 ? -1 : type1 > type2; + + if (g_variant_type_is_basic(type1)) + ret = g_variant_compare(value1, value2); + else if (g_variant_is_of_type(value1, G_VARIANT_TYPE("a{ss}"))) + ret = _nm_property_compare_strdict(value1, value2); + else if (g_variant_is_of_type(value1, G_VARIANT_TYPE("a{sv}"))) + ret = _nm_property_compare_vardict(value1, value2); + else if (g_variant_type_is_array(type1)) + ret = _nm_property_compare_collection(value1, value2); + else if (g_variant_type_is_tuple(type1)) + ret = _nm_property_compare_collection(value1, value2); + else { + g_warning("Don't know how to compare variant type '%s'", (const char *) type1); + ret = value1 == value2; + } + + return ret; +} diff --git a/src/libnm-core-impl/nm-property-compare.h b/src/libnm-core-impl/nm-property-compare.h new file mode 100644 index 0000000..d422b1c --- /dev/null +++ b/src/libnm-core-impl/nm-property-compare.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_PROPERTY_COMPARE_H__ +#define __NM_PROPERTY_COMPARE_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) + #error Cannot use this header. +#endif + +int nm_property_compare(GVariant *value1, GVariant *value2); + +#endif /* __NM_PROPERTY_COMPARE_H__ */ diff --git a/src/libnm-core-impl/nm-setting-6lowpan.c b/src/libnm-core-impl/nm-setting-6lowpan.c new file mode 100644 index 0000000..408b39b --- /dev/null +++ b/src/libnm-core-impl/nm-setting-6lowpan.c @@ -0,0 +1,228 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-6lowpan.h" + +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-6lowpan + * @short_description: Describes connection properties for 6LoWPAN interfaces + * + * The #NMSetting6Lowpan object is a #NMSetting subclass that describes properties + * necessary for connection to 6LoWPAN interfaces. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, ); + +typedef struct { + char *parent; +} NMSetting6LowpanPrivate; + +/** + * NMSetting6Lowpan: + * + * 6LoWPAN Settings + */ +struct _NMSetting6Lowpan { + NMSetting parent; +}; + +struct _NMSetting6LowpanClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSetting6Lowpan, nm_setting_6lowpan, NM_TYPE_SETTING) + +#define NM_SETTING_6LOWPAN_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_6LOWPAN, NMSetting6LowpanPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_6lowpan_get_parent: + * @setting: the #NMSetting6Lowpan + * + * Returns: the #NMSetting6Lowpan:parent property of the setting + * + * Since: 1.14 + **/ +const char * +nm_setting_6lowpan_get_parent(NMSetting6Lowpan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_6LOWPAN(setting), NULL); + return NM_SETTING_6LOWPAN_GET_PRIVATE(setting)->parent; +} + +/*********************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSetting6LowpanPrivate *priv = NM_SETTING_6LOWPAN_GET_PRIVATE(setting); + NMSettingConnection * s_con = NULL; + + if (connection) + s_con = nm_connection_get_setting_connection(connection); + + if (!priv->parent) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_6LOWPAN_SETTING_NAME, + NM_SETTING_6LOWPAN_PARENT); + return FALSE; + } + + if (nm_utils_is_uuid(priv->parent)) { + /* If we have an NMSettingConnection:master with slave-type="6lowpan", + * then it must be the same UUID. + */ + if (s_con) { + const char *master = NULL, *slave_type = NULL; + + slave_type = nm_setting_connection_get_slave_type(s_con); + if (!g_strcmp0(slave_type, NM_SETTING_6LOWPAN_SETTING_NAME)) + master = nm_setting_connection_get_master(s_con); + + if (master && g_strcmp0(priv->parent, master) != 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' value doesn't match '%s=%s'"), + priv->parent, + NM_SETTING_CONNECTION_MASTER, + master); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_6LOWPAN_SETTING_NAME, + NM_SETTING_6LOWPAN_PARENT); + return FALSE; + } + } + } else if (!nm_utils_iface_valid_name(priv->parent)) { + /* parent must be either a UUID or an interface name */ + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_6LOWPAN_SETTING_NAME, + NM_SETTING_6LOWPAN_PARENT); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSetting6Lowpan * setting = NM_SETTING_6LOWPAN(object); + NMSetting6LowpanPrivate *priv = NM_SETTING_6LOWPAN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string(value, priv->parent); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSetting6Lowpan * setting = NM_SETTING_6LOWPAN(object); + NMSetting6LowpanPrivate *priv = NM_SETTING_6LOWPAN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_free(priv->parent); + priv->parent = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_6lowpan_init(NMSetting6Lowpan *setting) +{} + +/** + * nm_setting_6lowpan_new: + * + * Creates a new #NMSetting6Lowpan object with default values. + * + * Returns: (transfer full): the new empty #NMSetting6Lowpan object + * + * Since: 1.14 + **/ +NMSetting * +nm_setting_6lowpan_new(void) +{ + return g_object_new(NM_TYPE_SETTING_6LOWPAN, NULL); +} + +static void +finalize(GObject *object) +{ + NMSetting6Lowpan * setting = NM_SETTING_6LOWPAN(object); + NMSetting6LowpanPrivate *priv = NM_SETTING_6LOWPAN_GET_PRIVATE(setting); + + g_free(priv->parent); + + G_OBJECT_CLASS(nm_setting_6lowpan_parent_class)->finalize(object); +} + +static void +nm_setting_6lowpan_class_init(NMSetting6LowpanClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSetting6LowpanPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSetting6Lowpan:parent: + * + * If given, specifies the parent interface name or parent connection UUID + * from which this 6LowPAN interface should be created. + * + * Since: 1.14 + **/ + obj_properties[PROP_PARENT] = g_param_spec_string( + NM_SETTING_6LOWPAN_PARENT, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_6LOWPAN); +} diff --git a/src/libnm-core-impl/nm-setting-8021x.c b/src/libnm-core-impl/nm-setting-8021x.c new file mode 100644 index 0000000..39afa3a --- /dev/null +++ b/src/libnm-core-impl/nm-setting-8021x.c @@ -0,0 +1,4683 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-8021x.h" + +#include "libnm-glib-aux/nm-secret-utils.h" +#include "nm-utils.h" +#include "nm-crypto.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-8021x + * @short_description: Describes 802.1x-authenticated connection properties + * + * The #NMSetting8021x object is a #NMSetting subclass that describes + * properties necessary for connection to 802.1x-authenticated networks, such as + * WPA and WPA2 Enterprise Wi-Fi networks and wired 802.1x networks. 802.1x + * connections typically use certificates and/or EAP authentication methods to + * securely verify, identify, and authenticate the client to the network itself, + * instead of simply relying on a widely shared static key. + * + * It's a good idea to read up on wpa_supplicant configuration before using this + * setting extensively, since most of the options here correspond closely with + * the relevant wpa_supplicant configuration options. + * + * Furthermore, to get a good idea of 802.1x, EAP, TLS, TTLS, etc and their + * applications to Wi-Fi and wired networks, you'll want to get copies of the + * following books. + * + * 802.11 Wireless Networks: The Definitive Guide, Second Edition + * Author: Matthew Gast + * ISBN: 978-0596100520 + * + * Cisco Wireless LAN Security + * Authors: Krishna Sankar, Sri Sundaralingam, Darrin Miller, and Andrew Balinsky + * ISBN: 978-1587051548 + **/ + +/*****************************************************************************/ + +static NMSetting8021xCKFormat +_crypto_format_to_ck(NMCryptoFileFormat format) +{ + G_STATIC_ASSERT((NM_SETTING_802_1X_CK_FORMAT_UNKNOWN + == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_UNKNOWN)); + G_STATIC_ASSERT( + (NM_SETTING_802_1X_CK_FORMAT_X509 == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_X509)); + G_STATIC_ASSERT((NM_SETTING_802_1X_CK_FORMAT_RAW_KEY + == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_RAW_KEY)); + G_STATIC_ASSERT((NM_SETTING_802_1X_CK_FORMAT_PKCS12 + == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_PKCS12)); + + nm_assert(NM_IN_SET(format, + NM_CRYPTO_FILE_FORMAT_UNKNOWN, + NM_CRYPTO_FILE_FORMAT_X509, + NM_CRYPTO_FILE_FORMAT_RAW_KEY, + NM_CRYPTO_FILE_FORMAT_PKCS12)); + return (NMSetting8021xCKFormat) format; +} + +/*****************************************************************************/ + +typedef void (*EAPMethodNeedSecretsFunc)(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2); + +typedef gboolean (*EAPMethodValidateFunc)(NMSetting8021x *self, gboolean phase2, GError **error); + +typedef struct { + const char * method; + EAPMethodNeedSecretsFunc ns_func; + EAPMethodValidateFunc v_func; +} EAPMethodsTable; + +static const EAPMethodsTable eap_methods_table[]; + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSetting8021x, + PROP_EAP, + PROP_IDENTITY, + PROP_ANONYMOUS_IDENTITY, + PROP_PAC_FILE, + PROP_CA_CERT, + PROP_CA_CERT_PASSWORD, + PROP_CA_CERT_PASSWORD_FLAGS, + PROP_CA_PATH, + PROP_SUBJECT_MATCH, + PROP_ALTSUBJECT_MATCHES, + PROP_DOMAIN_SUFFIX_MATCH, + PROP_DOMAIN_MATCH, + PROP_CLIENT_CERT, + PROP_CLIENT_CERT_PASSWORD, + PROP_CLIENT_CERT_PASSWORD_FLAGS, + PROP_PHASE1_PEAPVER, + PROP_PHASE1_PEAPLABEL, + PROP_PHASE1_FAST_PROVISIONING, + PROP_PHASE1_AUTH_FLAGS, + PROP_PHASE2_AUTH, + PROP_PHASE2_AUTHEAP, + PROP_PHASE2_CA_CERT, + PROP_PHASE2_CA_CERT_PASSWORD, + PROP_PHASE2_CA_CERT_PASSWORD_FLAGS, + PROP_PHASE2_CA_PATH, + PROP_PHASE2_SUBJECT_MATCH, + PROP_PHASE2_ALTSUBJECT_MATCHES, + PROP_PHASE2_DOMAIN_SUFFIX_MATCH, + PROP_PHASE2_DOMAIN_MATCH, + PROP_PHASE2_CLIENT_CERT, + PROP_PHASE2_CLIENT_CERT_PASSWORD, + PROP_PHASE2_CLIENT_CERT_PASSWORD_FLAGS, + PROP_PASSWORD, + PROP_PASSWORD_FLAGS, + PROP_PASSWORD_RAW, + PROP_PASSWORD_RAW_FLAGS, + PROP_PRIVATE_KEY, + PROP_PRIVATE_KEY_PASSWORD, + PROP_PRIVATE_KEY_PASSWORD_FLAGS, + PROP_PHASE2_PRIVATE_KEY, + PROP_PHASE2_PRIVATE_KEY_PASSWORD, + PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, + PROP_PIN, + PROP_PIN_FLAGS, + PROP_SYSTEM_CA_CERTS, + PROP_OPTIONAL, + PROP_AUTH_TIMEOUT, ); + +typedef struct { + GSList * eap; /* GSList of strings */ + char * identity; + char * anonymous_identity; + char * pac_file; + GBytes * ca_cert; + char * ca_cert_password; + char * ca_path; + char * subject_match; + GSList * altsubject_matches; + char * domain_suffix_match; + char * domain_match; + GBytes * client_cert; + char * client_cert_password; + char * phase1_peapver; + char * phase1_peaplabel; + char * phase1_fast_provisioning; + char * phase2_auth; + char * phase2_autheap; + GBytes * phase2_ca_cert; + char * phase2_ca_cert_password; + char * phase2_ca_path; + char * phase2_subject_match; + GSList * phase2_altsubject_matches; + char * phase2_domain_suffix_match; + char * phase2_domain_match; + GBytes * phase2_client_cert; + char * phase2_client_cert_password; + char * password; + GBytes * password_raw; + char * pin; + GBytes * private_key; + char * private_key_password; + GBytes * phase2_private_key; + char * phase2_private_key_password; + int auth_timeout; + NMSetting8021xAuthFlags phase1_auth_flags; + NMSettingSecretFlags ca_cert_password_flags; + NMSettingSecretFlags client_cert_password_flags; + NMSettingSecretFlags phase2_ca_cert_password_flags; + NMSettingSecretFlags phase2_client_cert_password_flags; + NMSettingSecretFlags password_flags; + NMSettingSecretFlags password_raw_flags; + NMSettingSecretFlags pin_flags; + NMSettingSecretFlags private_key_password_flags; + NMSettingSecretFlags phase2_private_key_password_flags; + bool optional : 1; + bool system_ca_certs : 1; +} NMSetting8021xPrivate; + +G_DEFINE_TYPE(NMSetting8021x, nm_setting_802_1x, NM_TYPE_SETTING) + +#define NM_SETTING_802_1X_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_802_1X, NMSetting8021xPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_802_1x_check_cert_scheme: + * @pdata: (allow-none): the data pointer + * @length: the length of the data + * @error: (allow-none) (out): validation reason + * + * Determines and verifies the blob type. + * When setting certificate properties of NMSetting8021x + * the blob must be not UNKNOWN (or NULL). + * + * Returns: the scheme of the blob or %NM_SETTING_802_1X_CK_SCHEME_UNKNOWN. + * For NULL it also returns NM_SETTING_802_1X_CK_SCHEME_UNKNOWN. + * + * Since: 1.2 + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_check_cert_scheme(gconstpointer pdata, gsize length, GError **error) +{ + const char * data = pdata; + NMSetting8021xCKScheme scheme; + gsize prefix_length; + + g_return_val_if_fail(!length || data, NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); + + if (!length || !data) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("binary data missing")); + return NM_SETTING_802_1X_CK_SCHEME_UNKNOWN; + } + + if (length >= NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH) + && !memcmp(data, + NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH, + NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH))) { + scheme = NM_SETTING_802_1X_CK_SCHEME_PATH; + prefix_length = NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); + } else if (length >= NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11) + && !memcmp(data, + NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11, + NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11))) { + scheme = NM_SETTING_802_1X_CK_SCHEME_PKCS11; + prefix_length = NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11); + } else { + scheme = NM_SETTING_802_1X_CK_SCHEME_BLOB; + prefix_length = 0; + } + + if (scheme != NM_SETTING_802_1X_CK_SCHEME_BLOB) { + /* An actual URI must be NUL terminated, contain at least + * one non-NUL character, and contain only one trailing NUL + * character. + * And ensure it's UTF-8 valid too so we can pass it through + * D-Bus and stuff like that. */ + + if (data[length - 1] != '\0') { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("URI not NUL terminated")); + return NM_SETTING_802_1X_CK_SCHEME_UNKNOWN; + } + length--; + + if (length <= prefix_length) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("URI is empty")); + return NM_SETTING_802_1X_CK_SCHEME_UNKNOWN; + } + + if (!g_utf8_validate(data + prefix_length, length - prefix_length, NULL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("URI is not valid UTF-8")); + return NM_SETTING_802_1X_CK_SCHEME_UNKNOWN; + } + } + + return scheme; +} + +NMSetting8021xCKScheme +_nm_setting_802_1x_cert_get_scheme(GBytes *bytes, GError **error) +{ + const char *data; + gsize length; + + if (!bytes) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("data missing")); + return NM_SETTING_802_1X_CK_SCHEME_UNKNOWN; + } + + data = g_bytes_get_data(bytes, &length); + return nm_setting_802_1x_check_cert_scheme(data, length, error); +} + +static gboolean +_cert_verify_scheme(NMSetting8021xCKScheme scheme, GBytes *bytes, GError **error) +{ + GError * local = NULL; + NMSetting8021xCKScheme scheme_detected; + + nm_assert(bytes); + + scheme_detected = _nm_setting_802_1x_cert_get_scheme(bytes, &local); + if (scheme_detected == NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("certificate is invalid: %s"), + local->message); + return FALSE; + } + + if (scheme_detected != scheme) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("certificate detected as invalid scheme")); + return FALSE; + } + + return TRUE; +} + +GBytes * +_nm_setting_802_1x_cert_value_to_bytes(NMSetting8021xCKScheme scheme, + const guint8 * val_bin, + gssize val_len, + GError ** error) +{ + gs_unref_bytes GBytes *bytes = NULL; + guint8 * mem; + gsize total_len; + + nm_assert(val_bin); + + switch (scheme) { + case NM_SETTING_802_1X_CK_SCHEME_PKCS11: + if (val_len < 0) + val_len = strlen((char *) val_bin) + 1; + + bytes = g_bytes_new(val_bin, val_len); + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + if (val_len < 0) + val_len = strlen((char *) val_bin) + 1; + + total_len = NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH) + ((gsize) val_len); + + mem = g_new(guint8, total_len); + memcpy(mem, + NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH, + NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)); + memcpy(&mem[NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)], val_bin, val_len); + bytes = g_bytes_new_take(mem, total_len); + break; + default: + g_return_val_if_reached(NULL); + } + + if (!_cert_verify_scheme(scheme, bytes, error)) + return NULL; + + return g_steal_pointer(&bytes); +} + +static const char * +_cert_get_path(GBytes *bytes) +{ + const guint8 *bin; + + nm_assert(bytes); + nm_assert(g_bytes_get_size(bytes) >= NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)); + + bin = g_bytes_get_data(bytes, NULL); + + nm_assert(bin); + nm_assert(bin[g_bytes_get_size(bytes) - 1] == '\0'); + nm_assert(g_str_has_prefix((const char *) bin, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)); + + return (const char *) &bin[NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)]; +} + +#define _cert_assert_scheme(cert, check_scheme, ret_val) \ + G_STMT_START \ + { \ + NMSetting8021xCKScheme scheme; \ + \ + scheme = _nm_setting_802_1x_cert_get_scheme((cert), NULL); \ + if (scheme != check_scheme) { \ + g_return_val_if_fail(scheme == check_scheme, ret_val); \ + return ret_val; \ + } \ + } \ + G_STMT_END + +#define _cert_impl_get_scheme(setting, cert_field) \ + G_STMT_START \ + { \ + NMSetting8021x *const _setting = (setting); \ + GBytes * _cert; \ + \ + g_return_val_if_fail(NM_IS_SETTING_802_1X(_setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); \ + \ + _cert = NM_SETTING_802_1X_GET_PRIVATE(_setting)->cert_field; \ + \ + return _nm_setting_802_1x_cert_get_scheme(_cert, NULL); \ + } \ + G_STMT_END + +#define _cert_impl_get_blob(setting, cert_field) \ + G_STMT_START \ + { \ + NMSetting8021x *const _setting = (setting); \ + GBytes * _cert; \ + \ + g_return_val_if_fail(NM_IS_SETTING_802_1X(_setting), NULL); \ + \ + _cert = NM_SETTING_802_1X_GET_PRIVATE(_setting)->cert_field; \ + \ + _cert_assert_scheme(_cert, NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL); \ + \ + return _cert; \ + } \ + G_STMT_END + +#define _cert_impl_get_path(setting, cert_field) \ + G_STMT_START \ + { \ + NMSetting8021x *const _setting = (setting); \ + GBytes * _cert; \ + \ + g_return_val_if_fail(NM_IS_SETTING_802_1X(_setting), NULL); \ + \ + _cert = NM_SETTING_802_1X_GET_PRIVATE(_setting)->cert_field; \ + \ + _cert_assert_scheme(_cert, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL); \ + \ + return _cert_get_path(_cert); \ + } \ + G_STMT_END + +#define _cert_impl_get_uri(setting, cert_field) \ + G_STMT_START \ + { \ + NMSetting8021x *const _setting = (setting); \ + GBytes * _cert; \ + \ + g_return_val_if_fail(NM_IS_SETTING_802_1X(_setting), NULL); \ + \ + _cert = NM_SETTING_802_1X_GET_PRIVATE(_setting)->cert_field; \ + \ + _cert_assert_scheme(_cert, NM_SETTING_802_1X_CK_SCHEME_PKCS11, NULL); \ + \ + return g_bytes_get_data(_cert, NULL); \ + } \ + G_STMT_END + +static gboolean +_cert_impl_set(NMSetting8021x * setting, + _PropertyEnums property, + const char * value, + const char * password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error) +{ + NMSetting8021xPrivate *priv; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gs_unref_bytes GBytes *cert = NULL; + GBytes ** p_cert = NULL; + GBytes ** p_client_cert = NULL; + char ** p_password = NULL; + _PropertyEnums notify_cert = property; + _PropertyEnums notify_password = PROP_0; + _PropertyEnums notify_client_cert = PROP_0; + + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + if (value) { + g_return_val_if_fail(g_utf8_validate(value, -1, NULL), FALSE); + g_return_val_if_fail(NM_IN_SET(scheme, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NM_SETTING_802_1X_CK_SCHEME_PKCS11), + FALSE); + } + + if (!value) { + /* coerce password to %NULL. It should be already. */ + password = NULL; + } + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + + if (!value) { + /* pass. */ + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { + cert = _nm_setting_802_1x_cert_value_to_bytes(scheme, (guint8 *) value, -1, error); + if (!cert) + goto err; + } else { + gs_unref_bytes GBytes *file = NULL; + + if (NM_IN_SET(property, PROP_PRIVATE_KEY, PROP_PHASE2_PRIVATE_KEY)) { + file = nm_crypto_read_file(value, error); + if (!file) + goto err; + format = nm_crypto_verify_private_key_data(g_bytes_get_data(file, NULL), + g_bytes_get_size(file), + password, + NULL, + error); + if (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN) + goto err; + } else { + if (!nm_crypto_load_and_verify_certificate(value, &format, &file, error)) + goto err; + } + + nm_assert(format != NM_CRYPTO_FILE_FORMAT_UNKNOWN); + nm_assert(file); + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + cert = g_steal_pointer(&file); + if (!_cert_verify_scheme(scheme, cert, error)) + goto err; + } else { + cert = _nm_setting_802_1x_cert_value_to_bytes(scheme, (guint8 *) value, -1, error); + if (!cert) + goto err; + } + } + + switch (property) { + case PROP_CA_CERT: + case PROP_PHASE2_CA_CERT: + if (value && scheme != NM_SETTING_802_1X_CK_SCHEME_PKCS11 + && format != NM_CRYPTO_FILE_FORMAT_X509) { + /* wpa_supplicant can only use raw x509 CA certs */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("CA certificate must be in X.509 format")); + goto err; + } + p_cert = (property == PROP_CA_CERT) ? &priv->ca_cert : &priv->phase2_ca_cert; + break; + case PROP_CLIENT_CERT: + case PROP_PHASE2_CLIENT_CERT: + if (value && scheme != NM_SETTING_802_1X_CK_SCHEME_PKCS11 + && !NM_IN_SET(format, NM_CRYPTO_FILE_FORMAT_X509, NM_CRYPTO_FILE_FORMAT_PKCS12)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid certificate format")); + goto err; + } + p_cert = (property == PROP_CLIENT_CERT) ? &priv->client_cert : &priv->phase2_client_cert; + break; + case PROP_PRIVATE_KEY: + p_cert = &priv->private_key; + p_password = &priv->private_key_password; + p_client_cert = &priv->client_cert; + notify_password = PROP_PRIVATE_KEY_PASSWORD; + notify_client_cert = PROP_CLIENT_CERT; + break; + case PROP_PHASE2_PRIVATE_KEY: + p_cert = &priv->phase2_private_key; + p_password = &priv->phase2_private_key_password; + p_client_cert = &priv->phase2_client_cert; + notify_password = PROP_PHASE2_PRIVATE_KEY_PASSWORD; + notify_client_cert = PROP_PHASE2_CLIENT_CERT; + break; + default: + nm_assert_not_reached(); + break; + } + + /* As required by NM and wpa_supplicant, set the client-cert + * property to the same PKCS#12 data. + */ + if (cert && p_client_cert && format == NM_CRYPTO_FILE_FORMAT_PKCS12 + && !nm_gbytes_equal0(cert, *p_client_cert)) { + g_bytes_unref(*p_client_cert); + *p_client_cert = g_bytes_ref(cert); + } else + notify_client_cert = PROP_0; + + if (p_cert && !nm_gbytes_equal0(cert, *p_cert)) { + g_bytes_unref(*p_cert); + *p_cert = g_steal_pointer(&cert); + } else + notify_cert = PROP_0; + + if (p_password && !nm_streq0(password, *p_password)) { + nm_free_secret(*p_password); + *p_password = g_strdup(password); + } else + notify_password = PROP_0; + + nm_gobject_notify_together(setting, notify_cert, notify_password, notify_client_cert); + + NM_SET_OUT(out_format, _crypto_format_to_ck(format)); + return TRUE; + +err: + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + obj_properties[property]->name); + NM_SET_OUT(out_format, NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + return FALSE; +} + +static NMSetting8021xCKFormat +_cert_impl_get_key_format_from_bytes(GBytes *private_key) +{ + const char *path; + GError * error = NULL; + + if (!private_key) + return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + + switch (_nm_setting_802_1x_cert_get_scheme(private_key, NULL)) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + if (nm_crypto_is_pkcs12_data(g_bytes_get_data(private_key, NULL), + g_bytes_get_size(private_key), + NULL)) + return NM_SETTING_802_1X_CK_FORMAT_PKCS12; + return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = _cert_get_path(private_key); + if (nm_crypto_is_pkcs12_file(path, &error)) + return NM_SETTING_802_1X_CK_FORMAT_PKCS12; + if (error && error->domain == G_FILE_ERROR) { + g_error_free(error); + return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + } + g_error_free(error); + return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; + default: + break; + } + + return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; +} +#define _cert_impl_get_key_format(setting, private_key_field) \ + ({ \ + NMSetting8021x * _setting = (setting); \ + NMSetting8021xPrivate *_priv; \ + \ + g_return_val_if_fail(NM_IS_SETTING_802_1X(_setting), NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); \ + \ + _priv = NM_SETTING_802_1X_GET_PRIVATE(_setting); \ + _cert_impl_get_key_format_from_bytes(_priv->private_key_field); \ + }) + +static gboolean +_cert_verify_property(GBytes * bytes, + const char *prop_name, + const char *password, + const char *password_prop_name, + GError ** error) +{ + GError * local = NULL; + NMSetting8021xCKScheme scheme; + + if (!bytes) + return TRUE; + + scheme = _nm_setting_802_1x_cert_get_scheme(bytes, &local); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("certificate is invalid: %s"), + local->message); + g_prefix_error(error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, prop_name); + g_error_free(local); + return FALSE; + } + + if (password && (scheme != NM_SETTING_802_1X_CK_SCHEME_PKCS11)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("password is not supported when certificate is not on a PKCS#11 token")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, password_prop_name); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +/** + * nm_setting_802_1x_get_num_eap_methods: + * @setting: the #NMSetting8021x + * + * Returns the number of eap methods allowed for use when connecting to the + * network. Generally only one EAP method is used. Use the functions + * nm_setting_802_1x_get_eap_method(), nm_setting_802_1x_add_eap_method(), + * and nm_setting_802_1x_remove_eap_method() for adding, removing, and retrieving + * allowed EAP methods. + * + * Returns: the number of allowed EAP methods + **/ +guint32 +nm_setting_802_1x_get_num_eap_methods(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), 0); + + return g_slist_length(NM_SETTING_802_1X_GET_PRIVATE(setting)->eap); +} + +/** + * nm_setting_802_1x_get_eap_method: + * @setting: the #NMSetting8021x + * @i: the index of the EAP method name to return + * + * Returns the name of the allowed EAP method at index @i. + * + * Returns: the name of the allowed EAP method at index @i + **/ +const char * +nm_setting_802_1x_get_eap_method(NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + g_return_val_if_fail(i <= g_slist_length(priv->eap), NULL); + + return (const char *) g_slist_nth_data(priv->eap, i); +} + +/** + * nm_setting_802_1x_add_eap_method: + * @setting: the #NMSetting8021x + * @eap: the name of the EAP method to allow for this connection + * + * Adds an allowed EAP method. The setting is not valid until at least one + * EAP method has been added. See #NMSetting8021x:eap property for a list of + * allowed EAP methods. + * + * Returns: %TRUE if the EAP method was successfully added, %FALSE if it was + * not a valid method or if it was already allowed. + **/ +gboolean +nm_setting_802_1x_add_eap_method(NMSetting8021x *setting, const char *eap) +{ + NMSetting8021xPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), FALSE); + g_return_val_if_fail(eap != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + for (iter = priv->eap; iter; iter = g_slist_next(iter)) { + if (!strcmp(eap, (char *) iter->data)) + return FALSE; + } + + priv->eap = g_slist_append(priv->eap, g_ascii_strdown(eap, -1)); + _notify(setting, PROP_EAP); + return TRUE; +} + +/** + * nm_setting_802_1x_remove_eap_method: + * @setting: the #NMSetting8021x + * @i: the index of the EAP method to remove + * + * Removes the allowed EAP method at the specified index. + **/ +void +nm_setting_802_1x_remove_eap_method(NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + GSList * elt; + + g_return_if_fail(NM_IS_SETTING_802_1X(setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + elt = g_slist_nth(priv->eap, i); + g_return_if_fail(elt != NULL); + + g_free(elt->data); + priv->eap = g_slist_delete_link(priv->eap, elt); + _notify(setting, PROP_EAP); +} + +/** + * nm_setting_802_1x_remove_eap_method_by_value: + * @setting: the #NMSetting8021x + * @eap: the name of the EAP method to remove + * + * Removes the allowed EAP method @method. + * + * Returns: %TRUE if the EAP method was founs and removed, %FALSE if it was not. + **/ +gboolean +nm_setting_802_1x_remove_eap_method_by_value(NMSetting8021x *setting, const char *eap) +{ + NMSetting8021xPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), FALSE); + g_return_val_if_fail(eap != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + for (iter = priv->eap; iter; iter = g_slist_next(iter)) { + if (!strcmp(eap, (char *) iter->data)) { + priv->eap = g_slist_delete_link(priv->eap, iter); + _notify(setting, PROP_EAP); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_802_1x_clear_eap_methods: + * @setting: the #NMSetting8021x + * + * Clears all allowed EAP methods. + **/ +void +nm_setting_802_1x_clear_eap_methods(NMSetting8021x *setting) +{ + NMSetting8021xPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_802_1X(setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + g_slist_free_full(priv->eap, g_free); + priv->eap = NULL; + _notify(setting, PROP_EAP); +} + +/** + * nm_setting_802_1x_get_identity: + * @setting: the #NMSetting8021x + * + * Returns the identifier used by some EAP methods (like TLS) to + * authenticate the user. Often this is a username or login name. + * + * Returns: the user identifier + **/ +const char * +nm_setting_802_1x_get_identity(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->identity; +} + +/** + * nm_setting_802_1x_get_anonymous_identity: + * @setting: the #NMSetting8021x + * + * Returns the anonymous identifier used by some EAP methods (like TTLS) to + * authenticate the user in the outer unencrypted "phase 1" authentication. The + * inner "phase 2" authentication will use the #NMSetting8021x:identity in + * a secure form, if applicable for that EAP method. + * + * Returns: the anonymous identifier + **/ +const char * +nm_setting_802_1x_get_anonymous_identity(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->anonymous_identity; +} + +/** + * nm_setting_802_1x_get_pac_file: + * @setting: the #NMSetting8021x + * + * Returns the file containing PAC credentials used by EAP-FAST method. + * + * Returns: the PAC file + **/ +const char * +nm_setting_802_1x_get_pac_file(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->pac_file; +} + +/** + * nm_setting_802_1x_get_ca_path: + * @setting: the #NMSetting8021x + * + * Returns the path of the CA certificate directory if previously set. Systems + * will often have a directory that contains multiple individual CA certificates + * which the supplicant can then add to the verification chain. This may be + * used in addition to the #NMSetting8021x:ca-cert property to add more CA + * certificates for verifying the network to client. + * + * Returns: the CA certificate directory path + **/ +const char * +nm_setting_802_1x_get_ca_path(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->ca_path; +} + +/** + * nm_setting_802_1x_get_system_ca_certs: + * @setting: the #NMSetting8021x + * + * Sets the #NMSetting8021x:system-ca-certs property. The + * #NMSetting8021x:ca-path and #NMSetting8021x:phase2-ca-path + * properties are ignored if the #NMSetting8021x:system-ca-certs property is + * %TRUE, in which case a system-wide CA certificate directory specified at + * compile time (using the --system-ca-path configure option) is used in place + * of these properties. + * + * Returns: %TRUE if a system CA certificate path should be used, %FALSE if not + **/ +gboolean +nm_setting_802_1x_get_system_ca_certs(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), FALSE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->system_ca_certs; +} + +/** + * nm_setting_802_1x_get_ca_cert_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the CA certificate. If the returned scheme + * is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use nm_setting_802_1x_get_ca_cert_blob(); + * if %NM_SETTING_802_1X_CK_SCHEME_PATH, use nm_setting_802_1x_get_ca_cert_path(); + * if %NM_SETTING_802_1X_CK_SCHEME_PKCS11, use nm_setting_802_1x_get_ca_cert_uri(). + * + * Returns: scheme used to store the CA certificate (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_ca_cert_scheme(NMSetting8021x *setting) +{ + _cert_impl_get_scheme(setting, ca_cert); +} + +/** + * nm_setting_802_1x_get_ca_cert_blob: + * @setting: the #NMSetting8021x + * + * Returns the CA certificate blob if the CA certificate is stored using the + * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. Not all EAP methods use a + * CA certificate (LEAP for example), and those that can take advantage of the + * CA certificate allow it to be unset. Note that lack of a CA certificate + * reduces security by allowing man-in-the-middle attacks, because the identity + * of the network cannot be confirmed by the client. + * + * Returns: (transfer none): the CA certificate data + **/ +GBytes * +nm_setting_802_1x_get_ca_cert_blob(NMSetting8021x *setting) +{ + _cert_impl_get_blob(setting, ca_cert); +} + +/** + * nm_setting_802_1x_get_ca_cert_path: + * @setting: the #NMSetting8021x + * + * Returns the CA certificate path if the CA certificate is stored using the + * %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. Not all EAP methods use a + * CA certificate (LEAP for example), and those that can take advantage of the + * CA certificate allow it to be unset. Note that lack of a CA certificate + * reduces security by allowing man-in-the-middle attacks, because the identity + * of the network cannot be confirmed by the client. + * + * Returns: path to the CA certificate file + **/ +const char * +nm_setting_802_1x_get_ca_cert_path(NMSetting8021x *setting) +{ + _cert_impl_get_path(setting, ca_cert); +} + +/** + * nm_setting_802_1x_get_ca_cert_uri: + * @setting: the #NMSetting8021x + * + * Returns the CA certificate URI analogously to + * nm_setting_802_1x_get_ca_cert_blob() and + * nm_setting_802_1x_get_ca_cert_path(). + * + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * 7512), but may be extended to other schemes in future (such as 'file' URIs + * for local files and 'data' URIs for inline certificate data). + * + * Returns: the URI string + * + * Since: 1.6 + **/ +const char * +nm_setting_802_1x_get_ca_cert_uri(NMSetting8021x *setting) +{ + _cert_impl_get_uri(setting, ca_cert); +} + +/** + * nm_setting_802_1x_set_ca_cert: + * @setting: the #NMSetting8021x + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the CA certificate + * file (PEM or DER format). The path must be UTF-8 encoded; use + * g_filename_to_utf8() to convert if needed. Passing %NULL with any @scheme + * clears the CA certificate. + * @scheme: desired storage scheme for the certificate + * @out_format: on successful return, the type of the certificate added + * @error: on unsuccessful return, an error + * + * Reads a certificate from disk and sets the #NMSetting8021x:ca-cert property + * with the raw certificate data if using the %NM_SETTING_802_1X_CK_SCHEME_BLOB + * scheme, or with the path to the certificate file if using the + * %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_ca_cert(NMSetting8021x * setting, + const char * value, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error) +{ + return _cert_impl_set(setting, PROP_CA_CERT, value, NULL, scheme, out_format, error); +} + +/** + * nm_setting_802_1x_get_ca_cert_password: + * @setting: the #NMSetting8021x + * + * Returns: the password used to access the CA certificate stored in + * #NMSetting8021x:ca-cert property. Only makes sense if the certificate + * is stored on a PKCS#11 token that requires a login. + * + * Since: 1.8 + **/ +const char * +nm_setting_802_1x_get_ca_cert_password(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->ca_cert_password; +} + +/** + * nm_setting_802_1x_get_ca_cert_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:ca-cert-password + * + * Since: 1.8 + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_ca_cert_password_flags(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->ca_cert_password_flags; +} + +/** + * nm_setting_802_1x_get_subject_match: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSetting8021x:subject-match property. This is the + * substring to be matched against the subject of the authentication + * server certificate, or %NULL no subject verification is to be + * performed. + **/ +const char * +nm_setting_802_1x_get_subject_match(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->subject_match; +} + +/** + * nm_setting_802_1x_get_num_altsubject_matches: + * @setting: the #NMSetting8021x + * + * Returns the number of entries in the + * #NMSetting8021x:altsubject-matches property of this setting. + * + * Returns: the number of altsubject-matches entries. + **/ +guint32 +nm_setting_802_1x_get_num_altsubject_matches(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), 0); + + return g_slist_length(NM_SETTING_802_1X_GET_PRIVATE(setting)->altsubject_matches); +} + +/** + * nm_setting_802_1x_get_altsubject_match: + * @setting: the #NMSettingConnection + * @i: the zero-based index of the array of altSubjectName matches + * + * Returns the altSubjectName match at index @i. + * + * Returns: the altSubjectName match at index @i + **/ +const char * +nm_setting_802_1x_get_altsubject_match(NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + g_return_val_if_fail(i <= g_slist_length(priv->altsubject_matches), NULL); + + return (const char *) g_slist_nth_data(priv->altsubject_matches, i); +} + +/** + * nm_setting_802_1x_add_altsubject_match: + * @setting: the #NMSetting8021x + * @altsubject_match: the altSubjectName to allow for this connection + * + * Adds an allowed alternate subject name match. Until at least one + * match is added, the altSubjectName of the remote authentication + * server is not verified. + * + * Returns: %TRUE if the alternative subject name match was + * successfully added, %FALSE if it was already allowed. + **/ +gboolean +nm_setting_802_1x_add_altsubject_match(NMSetting8021x *setting, const char *altsubject_match) +{ + NMSetting8021xPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), FALSE); + g_return_val_if_fail(altsubject_match != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + for (iter = priv->altsubject_matches; iter; iter = g_slist_next(iter)) { + if (!strcmp(altsubject_match, (char *) iter->data)) + return FALSE; + } + + priv->altsubject_matches = g_slist_append(priv->altsubject_matches, g_strdup(altsubject_match)); + _notify(setting, PROP_ALTSUBJECT_MATCHES); + return TRUE; +} + +/** + * nm_setting_802_1x_remove_altsubject_match: + * @setting: the #NMSetting8021x + * @i: the index of the altSubjectName match to remove + * + * Removes the allowed altSubjectName at the specified index. + **/ +void +nm_setting_802_1x_remove_altsubject_match(NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + GSList * elt; + + g_return_if_fail(NM_IS_SETTING_802_1X(setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + elt = g_slist_nth(priv->altsubject_matches, i); + g_return_if_fail(elt != NULL); + + g_free(elt->data); + priv->altsubject_matches = g_slist_delete_link(priv->altsubject_matches, elt); + _notify(setting, PROP_ALTSUBJECT_MATCHES); +} + +/** + * nm_setting_802_1x_remove_altsubject_match_by_value: + * @setting: the #NMSetting8021x + * @altsubject_match: the altSubjectName to remove + * + * Removes the allowed altSubjectName @altsubject_match. + * + * Returns: %TRUE if the alternative subject name match was found and removed, + * %FALSE if it was not. + **/ +gboolean +nm_setting_802_1x_remove_altsubject_match_by_value(NMSetting8021x *setting, + const char * altsubject_match) +{ + NMSetting8021xPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), FALSE); + g_return_val_if_fail(altsubject_match != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + for (iter = priv->altsubject_matches; iter; iter = g_slist_next(iter)) { + if (!strcmp(altsubject_match, (char *) iter->data)) { + priv->altsubject_matches = g_slist_delete_link(priv->altsubject_matches, iter); + _notify(setting, PROP_ALTSUBJECT_MATCHES); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_802_1x_clear_altsubject_matches: + * @setting: the #NMSetting8021x + * + * Clears all altSubjectName matches. + **/ +void +nm_setting_802_1x_clear_altsubject_matches(NMSetting8021x *setting) +{ + NMSetting8021xPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_802_1X(setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + g_slist_free_full(priv->altsubject_matches, g_free); + priv->altsubject_matches = NULL; + _notify(setting, PROP_ALTSUBJECT_MATCHES); +} + +/** + * nm_setting_802_1x_get_domain_suffix_match: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSetting8021x:domain-suffix-match property. + * + * Since: 1.2 + **/ +const char * +nm_setting_802_1x_get_domain_suffix_match(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->domain_suffix_match; +} + +/** + * nm_setting_802_1x_get_domain_match: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSetting8021x:domain-match property. + * + * Since: 1.24 + **/ +const char * +nm_setting_802_1x_get_domain_match(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->domain_match; +} + +/** + * nm_setting_802_1x_get_client_cert_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the client certificate. If the returned scheme + * is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use nm_setting_802_1x_get_client_cert_blob(); + * if %NM_SETTING_802_1X_CK_SCHEME_PATH, use nm_setting_802_1x_get_client_cert_path(); + * if %NM_SETTING_802_1X_CK_SCHEME_PKCS11, use nm_setting_802_1x_get_client_cert_uri(). + * + * Returns: scheme used to store the client certificate (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_client_cert_scheme(NMSetting8021x *setting) +{ + _cert_impl_get_scheme(setting, client_cert); +} + +/** + * nm_setting_802_1x_get_client_cert_blob: + * @setting: the #NMSetting8021x + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: (transfer none): the client certificate data + **/ +GBytes * +nm_setting_802_1x_get_client_cert_blob(NMSetting8021x *setting) +{ + _cert_impl_get_blob(setting, client_cert); +} + +/** + * nm_setting_802_1x_get_client_cert_path: + * @setting: the #NMSetting8021x + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: path to the client certificate file + **/ +const char * +nm_setting_802_1x_get_client_cert_path(NMSetting8021x *setting) +{ + _cert_impl_get_path(setting, client_cert); +} + +/** + * nm_setting_802_1x_get_client_cert_uri: + * @setting: the #NMSetting8021x + * + * Returns the client certificate URI analogously to + * nm_setting_802_1x_get_client_cert_blob() and + * nm_setting_802_1x_get_client_cert_path(). + * + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * 7512), but may be extended to other schemes in future (such as 'file' URIs + * for local files and 'data' URIs for inline certificate data). + * + * Returns: the URI string + * + * Since: 1.6 + **/ +const char * +nm_setting_802_1x_get_client_cert_uri(NMSetting8021x *setting) +{ + _cert_impl_get_uri(setting, client_cert); +} + +/** + * nm_setting_802_1x_set_client_cert: + * @setting: the #NMSetting8021x + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the client + * certificate file (PEM, DER, or PKCS#12 format). The path must be UTF-8 + * encoded; use g_filename_to_utf8() to convert if needed. Passing %NULL with + * any @scheme clears the client certificate. + * @scheme: desired storage scheme for the certificate + * @out_format: on successful return, the type of the certificate added + * @error: on unsuccessful return, an error + * + * Reads a certificate from disk and sets the #NMSetting8021x:client-cert + * property with the raw certificate data if using the + * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the certificate + * file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_client_cert(NMSetting8021x * setting, + const char * value, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error) +{ + return _cert_impl_set(setting, PROP_CLIENT_CERT, value, NULL, scheme, out_format, error); +} + +/** + * nm_setting_802_1x_get_client_cert_password: + * @setting: the #NMSetting8021x + * + * Returns: the password used to access the client certificate stored in + * #NMSetting8021x:client-cert property. Only makes sense if the certificate + * is stored on a PKCS#11 token that requires a login. + * + * Since: 1.8 + **/ +const char * +nm_setting_802_1x_get_client_cert_password(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->client_cert_password; +} + +/** + * nm_setting_802_1x_get_client_cert_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:client-cert-password + * + * Since: 1.8 + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_client_cert_password_flags(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->client_cert_password_flags; +} + +/** + * nm_setting_802_1x_get_phase1_peapver: + * @setting: the #NMSetting8021x + * + * Returns: the "phase 1" PEAP version to be used when authenticating with + * EAP-PEAP as contained in the #NMSetting8021x:phase1-peapver property. Valid + * values are %NULL (unset), "0" (PEAP version 0), and "1" (PEAP version 1). + **/ +const char * +nm_setting_802_1x_get_phase1_peapver(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase1_peapver; +} + +/** + * nm_setting_802_1x_get_phase1_peaplabel: + * @setting: the #NMSetting8021x + * + * Returns: whether the "phase 1" PEAP label is new-style or old-style, to be + * used when authenticating with EAP-PEAP, as contained in the + * #NMSetting8021x:phase1-peaplabel property. Valid values are %NULL (unset), + * "0" (use old-style label), and "1" (use new-style label). See the + * wpa_supplicant documentation for more details. + **/ +const char * +nm_setting_802_1x_get_phase1_peaplabel(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase1_peaplabel; +} + +/** + * nm_setting_802_1x_get_phase1_fast_provisioning: + * @setting: the #NMSetting8021x + * + * Returns: whether "phase 1" PEAP fast provisioning should be used, as specified + * by the #NMSetting8021x:phase1-fast-provisioning property. See the + * wpa_supplicant documentation for more details. + **/ +const char * +nm_setting_802_1x_get_phase1_fast_provisioning(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase1_fast_provisioning; +} + +/** + * nm_setting_802_1x_get_phase1_auth_flags: + * @setting: the #NMSetting8021x + * + * Returns: the authentication flags for "phase 1". + * + * Since: 1.8 + */ +NMSetting8021xAuthFlags +nm_setting_802_1x_get_phase1_auth_flags(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), 0); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase1_auth_flags; +} + +/** + * nm_setting_802_1x_get_phase2_auth: + * @setting: the #NMSetting8021x + * + * Returns: the "phase 2" non-EAP (ex MD5) allowed authentication method as + * specified by the #NMSetting8021x:phase2-auth property. + **/ +const char * +nm_setting_802_1x_get_phase2_auth(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_auth; +} + +/** + * nm_setting_802_1x_get_phase2_autheap: + * @setting: the #NMSetting8021x + * + * Returns: the "phase 2" EAP-based (ex TLS) allowed authentication method as + * specified by the #NMSetting8021x:phase2-autheap property. + **/ +const char * +nm_setting_802_1x_get_phase2_autheap(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_autheap; +} + +/** + * nm_setting_802_1x_get_phase2_ca_path: + * @setting: the #NMSetting8021x + * + * Returns the path of the "phase 2" CA certificate directory if previously set. + * Systems will often have a directory that contains multiple individual CA + * certificates which the supplicant can then add to the verification chain. + * This may be used in addition to the #NMSetting8021x:phase2-ca-cert property + * to add more CA certificates for verifying the network to client. + * + * Returns: the "phase 2" CA certificate directory path + **/ +const char * +nm_setting_802_1x_get_phase2_ca_path(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_ca_path; +} + +/** + * nm_setting_802_1x_get_phase2_ca_cert_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the "phase 2" CA certificate. If the + * returned scheme is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use + * nm_setting_802_1x_get_ca_cert_blob(); if %NM_SETTING_802_1X_CK_SCHEME_PATH, + * use nm_setting_802_1x_get_ca_cert_path(); if %NM_SETTING_802_1X_CK_SCHEME_PKCS11, + * use nm_setting_802_1x_get_ca_cert_uri(). + * + * Returns: scheme used to store the "phase 2" CA certificate (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_phase2_ca_cert_scheme(NMSetting8021x *setting) +{ + _cert_impl_get_scheme(setting, phase2_ca_cert); +} + +/** + * nm_setting_802_1x_get_phase2_ca_cert_blob: + * @setting: the #NMSetting8021x + * + * Returns the "phase 2" CA certificate blob if the CA certificate is stored + * using the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. Not all EAP methods use + * a CA certificate (LEAP for example), and those that can take advantage of the + * CA certificate allow it to be unset. Note that lack of a CA certificate + * reduces security by allowing man-in-the-middle attacks, because the identity + * of the network cannot be confirmed by the client. + * + * Returns: (transfer none): the "phase 2" CA certificate data + **/ +GBytes * +nm_setting_802_1x_get_phase2_ca_cert_blob(NMSetting8021x *setting) +{ + _cert_impl_get_blob(setting, phase2_ca_cert); +} + +/** + * nm_setting_802_1x_get_phase2_ca_cert_path: + * @setting: the #NMSetting8021x + * + * Returns the "phase 2" CA certificate path if the CA certificate is stored + * using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. Not all EAP methods use + * a CA certificate (LEAP for example), and those that can take advantage of the + * CA certificate allow it to be unset. Note that lack of a CA certificate + * reduces security by allowing man-in-the-middle attacks, because the identity + * of the network cannot be confirmed by the client. + * + * Returns: path to the "phase 2" CA certificate file + **/ +const char * +nm_setting_802_1x_get_phase2_ca_cert_path(NMSetting8021x *setting) +{ + _cert_impl_get_path(setting, phase2_ca_cert); +} + +/** + * nm_setting_802_1x_get_phase2_ca_cert_uri: + * @setting: the #NMSetting8021x + * + * Returns the "phase 2" CA certificate URI analogously to + * nm_setting_802_1x_get_phase2_ca_cert_blob() and + * nm_setting_802_1x_get_phase2_ca_cert_path(). + * + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * 7512), but may be extended to other schemes in future (such as 'file' URIs + * for local files and 'data' URIs for inline certificate data). + * + * Returns: the URI string + * + * Since: 1.6 + **/ +const char * +nm_setting_802_1x_get_phase2_ca_cert_uri(NMSetting8021x *setting) +{ + _cert_impl_get_uri(setting, phase2_ca_cert); +} + +/** + * nm_setting_802_1x_set_phase2_ca_cert: + * @setting: the #NMSetting8021x + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" CA + * certificate file (PEM or DER format). The path must be UTF-8 encoded; use + * g_filename_to_utf8() to convert if needed. Passing %NULL with any @scheme + * clears the "phase2" CA certificate. + * @scheme: desired storage scheme for the certificate + * @out_format: on successful return, the type of the certificate added + * @error: on unsuccessful return, an error + * + * Reads a certificate from disk and sets the #NMSetting8021x:phase2-ca-cert + * property with the raw certificate data if using the + * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the certificate + * file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_phase2_ca_cert(NMSetting8021x * setting, + const char * value, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error) +{ + return _cert_impl_set(setting, PROP_PHASE2_CA_CERT, value, NULL, scheme, out_format, error); +} + +/** + * nm_setting_802_1x_get_phase2_ca_cert_password: + * @setting: the #NMSetting8021x + * + * Returns: the password used to access the "phase2" CA certificate stored in + * #NMSetting8021x:phase2-ca-cert property. Only makes sense if the certificate + * is stored on a PKCS#11 token that requires a login. + * + * Since: 1.8 + **/ +const char * +nm_setting_802_1x_get_phase2_ca_cert_password(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_ca_cert_password; +} + +/** + * nm_setting_802_1x_get_phase2_ca_cert_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:phase2-private-key-password + * + * Since: 1.8 + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_phase2_ca_cert_password_flags(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_ca_cert_password_flags; +} + +/** + * nm_setting_802_1x_get_phase2_subject_match: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSetting8021x:phase2-subject-match property. This is + * the substring to be matched against the subject of the "phase 2" + * authentication server certificate, or %NULL no subject verification + * is to be performed. + **/ +const char * +nm_setting_802_1x_get_phase2_subject_match(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_subject_match; +} + +/** + * nm_setting_802_1x_get_num_phase2_altsubject_matches: + * @setting: the #NMSetting8021x + * + * Returns the number of entries in the + * #NMSetting8021x:phase2-altsubject-matches property of this setting. + * + * Returns: the number of phase2-altsubject-matches entries. + **/ +guint32 +nm_setting_802_1x_get_num_phase2_altsubject_matches(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), 0); + + return g_slist_length(NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_altsubject_matches); +} + +/** + * nm_setting_802_1x_get_phase2_domain_suffix_match: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSetting8021x:phase2-domain-suffix-match property. + * + * Since: 1.2 + **/ +const char * +nm_setting_802_1x_get_phase2_domain_suffix_match(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_domain_suffix_match; +} + +/** + * nm_setting_802_1x_get_phase2_domain_match: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSetting8021x:phase2-domain-match property. + * + * Since: 1.24 + **/ +const char * +nm_setting_802_1x_get_phase2_domain_match(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_domain_match; +} + +/** + * nm_setting_802_1x_get_phase2_altsubject_match: + * @setting: the #NMSettingConnection + * @i: the zero-based index of the array of "phase 2" altSubjectName matches + * + * Returns the "phase 2" altSubjectName match at index @i. + * + * Returns: the "phase 2" altSubjectName match at index @i + **/ +const char * +nm_setting_802_1x_get_phase2_altsubject_match(NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + g_return_val_if_fail(i <= g_slist_length(priv->phase2_altsubject_matches), NULL); + + return (const char *) g_slist_nth_data(priv->phase2_altsubject_matches, i); +} + +/** + * nm_setting_802_1x_add_phase2_altsubject_match: + * @setting: the #NMSetting8021x + * @phase2_altsubject_match: the "phase 2" altSubjectName to allow for this + * connection + * + * Adds an allowed alternate subject name match for "phase 2". Until + * at least one match is added, the altSubjectName of the "phase 2" + * remote authentication server is not verified. + * + * Returns: %TRUE if the "phase 2" alternative subject name match was + * successfully added, %FALSE if it was already allowed. + **/ +gboolean +nm_setting_802_1x_add_phase2_altsubject_match(NMSetting8021x *setting, + const char * phase2_altsubject_match) +{ + NMSetting8021xPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), FALSE); + g_return_val_if_fail(phase2_altsubject_match != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + for (iter = priv->phase2_altsubject_matches; iter; iter = g_slist_next(iter)) { + if (!strcmp(phase2_altsubject_match, (char *) iter->data)) + return FALSE; + } + + priv->phase2_altsubject_matches = + g_slist_append(priv->phase2_altsubject_matches, g_strdup(phase2_altsubject_match)); + _notify(setting, PROP_PHASE2_ALTSUBJECT_MATCHES); + return TRUE; +} + +/** + * nm_setting_802_1x_remove_phase2_altsubject_match: + * @setting: the #NMSetting8021x + * @i: the index of the "phase 2" altSubjectName match to remove + * + * Removes the allowed "phase 2" altSubjectName at the specified index. + **/ +void +nm_setting_802_1x_remove_phase2_altsubject_match(NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + GSList * elt; + + g_return_if_fail(NM_IS_SETTING_802_1X(setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + elt = g_slist_nth(priv->phase2_altsubject_matches, i); + g_return_if_fail(elt != NULL); + + g_free(elt->data); + priv->phase2_altsubject_matches = g_slist_delete_link(priv->phase2_altsubject_matches, elt); + _notify(setting, PROP_PHASE2_ALTSUBJECT_MATCHES); +} + +/** + * nm_setting_802_1x_remove_phase2_altsubject_match_by_value: + * @setting: the #NMSetting8021x + * @phase2_altsubject_match: the "phase 2" altSubjectName to remove + * + * Removes the allowed "phase 2" altSubjectName @phase2_altsubject_match. + * + * Returns: %TRUE if the alternative subject name match for "phase 2" was found and removed, + * %FALSE if it was not. + **/ +gboolean +nm_setting_802_1x_remove_phase2_altsubject_match_by_value(NMSetting8021x *setting, + const char * phase2_altsubject_match) +{ + NMSetting8021xPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), FALSE); + g_return_val_if_fail(phase2_altsubject_match != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + for (iter = priv->phase2_altsubject_matches; iter; iter = g_slist_next(iter)) { + if (!strcmp(phase2_altsubject_match, (char *) iter->data)) { + priv->phase2_altsubject_matches = + g_slist_delete_link(priv->phase2_altsubject_matches, iter); + _notify(setting, PROP_PHASE2_ALTSUBJECT_MATCHES); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_802_1x_clear_phase2_altsubject_matches: + * @setting: the #NMSetting8021x + * + * Clears all "phase 2" altSubjectName matches. + **/ +void +nm_setting_802_1x_clear_phase2_altsubject_matches(NMSetting8021x *setting) +{ + NMSetting8021xPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_802_1X(setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + g_slist_free_full(priv->phase2_altsubject_matches, g_free); + priv->phase2_altsubject_matches = NULL; + _notify(setting, PROP_PHASE2_ALTSUBJECT_MATCHES); +} + +/** + * nm_setting_802_1x_get_phase2_client_cert_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the "phase 2" client certificate. If the + * returned scheme is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use + * nm_setting_802_1x_get_client_cert_blob(); if + * %NM_SETTING_802_1X_CK_SCHEME_PATH, use + * nm_setting_802_1x_get_client_cert_path(); if + * %NM_SETTING_802_1X_CK_SCHEME_PKCS11, use + * nm_setting_802_1x_get_client_cert_uri(). + * + * Returns: scheme used to store the "phase 2" client certificate (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_phase2_client_cert_scheme(NMSetting8021x *setting) +{ + _cert_impl_get_scheme(setting, phase2_client_cert); +} + +/** + * nm_setting_802_1x_get_phase2_client_cert_blob: + * @setting: the #NMSetting8021x + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: (transfer none): the "phase 2" client certificate data + **/ +GBytes * +nm_setting_802_1x_get_phase2_client_cert_blob(NMSetting8021x *setting) +{ + _cert_impl_get_blob(setting, phase2_client_cert); +} + +/** + * nm_setting_802_1x_get_phase2_client_cert_path: + * @setting: the #NMSetting8021x + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: path to the "phase 2" client certificate file + **/ +const char * +nm_setting_802_1x_get_phase2_client_cert_path(NMSetting8021x *setting) +{ + _cert_impl_get_path(setting, phase2_client_cert); +} + +/** + * nm_setting_802_1x_get_phase2_client_cert_uri: + * @setting: the #NMSetting8021x + * + * Returns the "phase 2" client certificate URI analogously to + * nm_setting_802_1x_get_phase2_ca_cert_blob() and + * nm_setting_802_1x_get_phase2_ca_cert_path(). + * + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * 7512), but may be extended to other schemes in future (such as 'file' URIs + * for local files and 'data' URIs for inline certificate data). + * + * Returns: the URI string + * + * Since: 1.6 + **/ +const char * +nm_setting_802_1x_get_phase2_client_cert_uri(NMSetting8021x *setting) +{ + _cert_impl_get_uri(setting, phase2_client_cert); +} + +/** + * nm_setting_802_1x_set_phase2_client_cert: + * @setting: the #NMSetting8021x + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" client + * certificate file (PEM, DER, or PKCS#12 format). The path must be UTF-8 + * encoded; use g_filename_to_utf8() to convert if needed. Passing %NULL with + * any @scheme clears the "phase2" client certificate. + * @scheme: desired storage scheme for the certificate + * @out_format: on successful return, the type of the certificate added + * @error: on unsuccessful return, an error + * + * Reads a certificate from disk and sets the #NMSetting8021x:phase2-client-cert + * property with the raw certificate data if using the + * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the certificate + * file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_phase2_client_cert(NMSetting8021x * setting, + const char * value, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error) +{ + return _cert_impl_set(setting, PROP_PHASE2_CLIENT_CERT, value, NULL, scheme, out_format, error); +} + +/** + * nm_setting_802_1x_get_phase2_client_cert_password: + * @setting: the #NMSetting8021x + * + * Returns: the password used to access the "phase2" client certificate stored in + * #NMSetting8021x:phase2-client-cert property. Only makes sense if the certificate + * is stored on a PKCS#11 token that requires a login. + * + * Since: 1.8 + **/ +const char * +nm_setting_802_1x_get_phase2_client_cert_password(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_client_cert_password; +} + +/** + * nm_setting_802_1x_get_phase2_client_cert_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:phase2-client-cert-password + * + * Since: 1.8 + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_phase2_client_cert_password_flags(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_client_cert_password_flags; +} + +/** + * nm_setting_802_1x_get_password: + * @setting: the #NMSetting8021x + * + * Returns: the password used by the authentication method, if any, as specified + * by the #NMSetting8021x:password property + **/ +const char * +nm_setting_802_1x_get_password(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->password; +} + +/** + * nm_setting_802_1x_get_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSetting8021x:password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_password_flags(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->password_flags; +} + +/** + * nm_setting_802_1x_get_password_raw: + * @setting: the #NMSetting8021x + * + * Returns: (transfer none): the password used by the authentication method as a + * UTF-8-encoded array of bytes, as specified by the + * #NMSetting8021x:password-raw property + **/ +GBytes * +nm_setting_802_1x_get_password_raw(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->password_raw; +} + +/** + * nm_setting_802_1x_get_password_raw_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:password-raw + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_password_raw_flags(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->password_raw_flags; +} + +/** + * nm_setting_802_1x_get_pin: + * @setting: the #NMSetting8021x + * + * Returns: the PIN used by the authentication method, if any, as specified + * by the #NMSetting8021x:pin property + **/ +const char * +nm_setting_802_1x_get_pin(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->pin; +} + +/** + * nm_setting_802_1x_get_pin_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:pin + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_pin_flags(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->pin_flags; +} + +/** + * nm_setting_802_1x_get_private_key_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the private key. If the returned scheme is + * %NM_SETTING_802_1X_CK_SCHEME_BLOB, use + * nm_setting_802_1x_get_client_cert_blob(); if + * %NM_SETTING_802_1X_CK_SCHEME_PATH, use + * nm_setting_802_1x_get_client_cert_path(); if + * %NM_SETTING_802_1X_CK_SCHEME_PKCS11, use + * nm_setting_802_1x_get_client_cert_uri(). + * + * Returns: scheme used to store the private key (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_private_key_scheme(NMSetting8021x *setting) +{ + _cert_impl_get_scheme(setting, private_key); +} + +/** + * nm_setting_802_1x_get_private_key_blob: + * @setting: the #NMSetting8021x + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * WARNING: the private key property is not a "secret" property, and thus + * unencrypted private key data may be readable by unprivileged users. Private + * keys should always be encrypted with a private key password. + * + * Returns: (transfer none): the private key data + **/ +GBytes * +nm_setting_802_1x_get_private_key_blob(NMSetting8021x *setting) +{ + _cert_impl_get_blob(setting, private_key); +} + +/** + * nm_setting_802_1x_get_private_key_path: + * @setting: the #NMSetting8021x + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: path to the private key file + **/ +const char * +nm_setting_802_1x_get_private_key_path(NMSetting8021x *setting) +{ + _cert_impl_get_path(setting, private_key); +} + +/** + * nm_setting_802_1x_get_private_key_uri: + * @setting: the #NMSetting8021x + * + * Returns the private key URI analogously to + * nm_setting_802_1x_get_private_key_blob() and + * nm_setting_802_1x_get_private_key_path(). + * + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * 7512), but may be extended to other schemes in future (such as 'file' URIs + * for local files and 'data' URIs for inline certificate data). + * + * Returns: the URI string + * + * Since: 1.6 + **/ +const char * +nm_setting_802_1x_get_private_key_uri(NMSetting8021x *setting) +{ + _cert_impl_get_uri(setting, private_key); +} + +/** + * nm_setting_802_1x_set_private_key: + * @setting: the #NMSetting8021x + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or + * %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the private key file + * (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; use + * g_filename_to_utf8() to convert if needed. Passing %NULL with any @scheme + * clears the private key. + * @password: password used to decrypt the private key, or %NULL if the password + * is unknown. If the password is given but fails to decrypt the private key, + * an error is returned. + * @scheme: desired storage scheme for the private key + * @out_format: on successful return, the type of the private key added + * @error: on unsuccessful return, an error + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * This function reads a private key from disk and sets the + * #NMSetting8021x:private-key property with the private key file data if using + * the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the private + * key file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * If @password is given, this function attempts to decrypt the private key to + * verify that @password is correct, and if it is, updates the + * #NMSetting8021x:private-key-password property with the given @password. If + * the decryption is unsuccessful, %FALSE is returned, @error is set, and no + * internal data is changed. If no @password is given, the private key is + * assumed to be valid, no decryption is performed, and the password may be set + * at a later time. + * + * WARNING: the private key property is not a "secret" property, and thus + * unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a private + * key password to prevent unauthorized access to unencrypted private key data. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_private_key(NMSetting8021x * setting, + const char * value, + const char * password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error) +{ + return _cert_impl_set(setting, PROP_PRIVATE_KEY, value, password, scheme, out_format, error); +} + +/** + * nm_setting_802_1x_get_private_key_password: + * @setting: the #NMSetting8021x + * + * Returns: the private key password used to decrypt the private key if + * previously set with nm_setting_802_1x_set_private_key(), or the + * #NMSetting8021x:private-key-password property. + **/ +const char * +nm_setting_802_1x_get_private_key_password(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->private_key_password; +} + +/** + * nm_setting_802_1x_get_private_key_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:private-key-password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_private_key_password_flags(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->private_key_password_flags; +} + +/** + * nm_setting_802_1x_get_private_key_format: + * @setting: the #NMSetting8021x + * + * Returns: the data format of the private key data stored in the + * #NMSetting8021x:private-key property + **/ +NMSetting8021xCKFormat +nm_setting_802_1x_get_private_key_format(NMSetting8021x *setting) +{ + return _cert_impl_get_key_format(setting, private_key); +} + +/** + * nm_setting_802_1x_get_phase2_private_key_password: + * @setting: the #NMSetting8021x + * + * Returns: the private key password used to decrypt the private key if + * previously set with nm_setting_802_1x_set_phase2_private_key() or the + * #NMSetting8021x:phase2-private-key-password property. + **/ +const char * +nm_setting_802_1x_get_phase2_private_key_password(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_private_key_password; +} + +/** + * nm_setting_802_1x_get_phase2_private_key_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:phase2-private-key-password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_phase2_private_key_password_flags(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->phase2_private_key_password_flags; +} + +/** + * nm_setting_802_1x_get_phase2_private_key_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the "phase 2" private key. If the returned + * scheme is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use + * nm_setting_802_1x_get_client_cert_blob(); if + * %NM_SETTING_802_1X_CK_SCHEME_PATH, use + * nm_setting_802_1x_get_client_cert_path(); if + * %NM_SETTING_802_1X_CK_SCHEME_PKCS11, use + * nm_setting_802_1x_get_client_cert_uri(). + * + * Returns: scheme used to store the "phase 2" private key (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_phase2_private_key_scheme(NMSetting8021x *setting) +{ + _cert_impl_get_scheme(setting, phase2_private_key); +} + +/** + * nm_setting_802_1x_get_phase2_private_key_blob: + * @setting: the #NMSetting8021x + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * WARNING: the phase2 private key property is not a "secret" property, and thus + * unencrypted private key data may be readable by unprivileged users. Private + * keys should always be encrypted with a private key password. + * + * Returns: (transfer none): the "phase 2" private key data + **/ +GBytes * +nm_setting_802_1x_get_phase2_private_key_blob(NMSetting8021x *setting) +{ + _cert_impl_get_blob(setting, phase2_private_key); +} + +/** + * nm_setting_802_1x_get_phase2_private_key_path: + * @setting: the #NMSetting8021x + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: path to the "phase 2" private key file + **/ +const char * +nm_setting_802_1x_get_phase2_private_key_path(NMSetting8021x *setting) +{ + _cert_impl_get_path(setting, phase2_private_key); +} + +/** + * nm_setting_802_1x_get_phase2_private_key_uri: + * @setting: the #NMSetting8021x + * + * Returns the "phase 2" private key URI analogously to + * nm_setting_802_1x_get_phase2_private_key_blob() and + * nm_setting_802_1x_get_phase2_private_key_path(). + * + * Currently, it's limited to PKCS#11 URIs ('pkcs11' scheme as defined by RFC + * 7512), but may be extended to other schemes in future (such as 'file' URIs + * for local files and 'data' URIs for inline certificate data). + * + * Returns: the URI string + * + * Since: 1.6 + **/ +const char * +nm_setting_802_1x_get_phase2_private_key_uri(NMSetting8021x *setting) +{ + _cert_impl_get_uri(setting, phase2_private_key); +} + +/** + * nm_setting_802_1x_set_phase2_private_key: + * @setting: the #NMSetting8021x + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or + * %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" private + * key file (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; + * use g_filename_to_utf8() to convert if needed. Passing %NULL with any + * @scheme clears the private key. + * @password: password used to decrypt the private key, or %NULL if the password + * is unknown. If the password is given but fails to decrypt the private key, + * an error is returned. + * @scheme: desired storage scheme for the private key + * @out_format: on successful return, the type of the private key added + * @error: on unsuccessful return, an error + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * This function reads a private key from disk and sets the + * #NMSetting8021x:phase2-private-key property with the private key file data if + * using the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the + * private key file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * If @password is given, this function attempts to decrypt the private key to + * verify that @password is correct, and if it is, updates the + * #NMSetting8021x:phase2-private-key-password property with the given + * @password. If the decryption is unsuccessful, %FALSE is returned, @error is + * set, and no internal data is changed. If no @password is given, the private + * key is assumed to be valid, no decryption is performed, and the password may + * be set at a later time. + * + * WARNING: the "phase2" private key property is not a "secret" property, and + * thus unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a private + * key password to prevent unauthorized access to unencrypted private key data. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_phase2_private_key(NMSetting8021x * setting, + const char * value, + const char * password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error) +{ + return _cert_impl_set(setting, + PROP_PHASE2_PRIVATE_KEY, + value, + password, + scheme, + out_format, + error); +} + +/** + * nm_setting_802_1x_get_phase2_private_key_format: + * @setting: the #NMSetting8021x + * + * Returns: the data format of the "phase 2" private key data stored in the + * #NMSetting8021x:phase2-private-key property + **/ +NMSetting8021xCKFormat +nm_setting_802_1x_get_phase2_private_key_format(NMSetting8021x *setting) +{ + return _cert_impl_get_key_format(setting, phase2_private_key); +} + +/** + * nm_setting_802_1x_get_auth_timeout: + * @setting: the #NMSetting8021x + * + * Returns the value contained in the #NMSetting8021x:auth-timeout property. + * + * Returns: the configured authentication timeout in seconds. Zero means the + * global default value. + * + * Since: 1.8 + **/ +int +nm_setting_802_1x_get_auth_timeout(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), 0); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->auth_timeout; +} + +/** + * nm_setting_802_1x_get_optional: + * @setting: the #NMSetting8021x + * + * Returns the value contained in the #NMSetting8021x:optional property. + * + * Returns: %TRUE if the activation should proceed even when the 802.1X + * authentication fails; %FALSE otherwise + * + * Since: 1.22 + **/ +gboolean +nm_setting_802_1x_get_optional(NMSetting8021x *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_802_1X(setting), FALSE); + + return NM_SETTING_802_1X_GET_PRIVATE(setting)->optional; +} + +/*****************************************************************************/ + +static void +need_secrets_password(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self); + + if ((!priv->password || !strlen(priv->password)) + && (!priv->password_raw || !g_bytes_get_size(priv->password_raw))) { + g_ptr_array_add(secrets, NM_SETTING_802_1X_PASSWORD); + g_ptr_array_add(secrets, NM_SETTING_802_1X_PASSWORD_RAW); + } +} + +static void +need_secrets_sim(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self); + + if (!priv->pin || !strlen(priv->pin)) + g_ptr_array_add(secrets, NM_SETTING_802_1X_PIN); +} + +static gboolean +need_private_key_password(GBytes * blob, + NMSetting8021xCKScheme scheme, + const char * path, + const char * password, + NMSettingSecretFlags flags) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) + return FALSE; + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11 && flags == NM_SETTING_SECRET_FLAG_NONE) + return FALSE; + + /* Private key password is required */ + if (password) { + if (path) + format = nm_crypto_verify_private_key(path, password, NULL, NULL); + else if (blob) + format = nm_crypto_verify_private_key_data(g_bytes_get_data(blob, NULL), + g_bytes_get_size(blob), + password, + NULL, + NULL); + else + return FALSE; + } + + return (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN); +} + +static void +need_secrets_tls(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self); + NMSetting8021xCKScheme scheme; + GBytes * blob = NULL; + const char * path = NULL; + + if (phase2) { + scheme = nm_setting_802_1x_get_phase2_private_key_scheme(self); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + path = nm_setting_802_1x_get_phase2_private_key_path(self); + else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) + blob = nm_setting_802_1x_get_phase2_private_key_blob(self); + else if (scheme != NM_SETTING_802_1X_CK_SCHEME_PKCS11) + g_warning("%s: unknown phase2 private key scheme %d", __func__, scheme); + + if (need_private_key_password(blob, + scheme, + path, + priv->phase2_private_key_password, + priv->phase2_private_key_password_flags)) + g_ptr_array_add(secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); + + scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme(self); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11 + && !(priv->phase2_ca_cert_password_flags == NM_SETTING_SECRET_FLAG_NONE + || priv->phase2_ca_cert_password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) + && !priv->phase2_ca_cert_password) + g_ptr_array_add(secrets, NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD); + + scheme = nm_setting_802_1x_get_phase2_client_cert_scheme(self); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11 + && !(priv->phase2_client_cert_password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED + || priv->phase2_client_cert_password_flags == NM_SETTING_SECRET_FLAG_NONE) + && !priv->phase2_client_cert_password) + g_ptr_array_add(secrets, NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD); + } else { + scheme = nm_setting_802_1x_get_private_key_scheme(self); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + path = nm_setting_802_1x_get_private_key_path(self); + else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) + blob = nm_setting_802_1x_get_private_key_blob(self); + else if (scheme != NM_SETTING_802_1X_CK_SCHEME_PKCS11) + g_warning("%s: unknown private key scheme %d", __func__, scheme); + + if (need_private_key_password(blob, + scheme, + path, + priv->private_key_password, + priv->private_key_password_flags)) + g_ptr_array_add(secrets, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + + scheme = nm_setting_802_1x_get_ca_cert_scheme(self); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11 + && !(priv->ca_cert_password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED + || priv->ca_cert_password_flags == NM_SETTING_SECRET_FLAG_NONE) + && !priv->ca_cert_password) + g_ptr_array_add(secrets, NM_SETTING_802_1X_CA_CERT_PASSWORD); + + scheme = nm_setting_802_1x_get_client_cert_scheme(self); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11 + && !(priv->client_cert_password_flags == NM_SETTING_SECRET_FLAG_NONE + || priv->client_cert_password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) + && !priv->client_cert_password) + g_ptr_array_add(secrets, NM_SETTING_802_1X_CLIENT_CERT_PASSWORD); + } +} + +static gboolean +verify_tls(NMSetting8021x *self, gboolean phase2, GError **error) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self); + + if (phase2) { + if (!priv->phase2_client_cert) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + return FALSE; + } else if (!g_bytes_get_size(priv->phase2_client_cert)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + return FALSE; + } + + /* Private key is required for TLS */ + if (!priv->phase2_private_key) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return FALSE; + } else if (!g_bytes_get_size(priv->phase2_private_key)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return FALSE; + } + + /* If the private key is PKCS#12, check that it matches the client cert */ + if (nm_crypto_is_pkcs12_data(g_bytes_get_data(priv->phase2_private_key, NULL), + g_bytes_get_size(priv->phase2_private_key), + NULL)) { + if (!g_bytes_equal(priv->phase2_private_key, priv->phase2_client_cert)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("has to match '%s' property for PKCS#12"), + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + return FALSE; + } + } + } else { + if (!priv->client_cert) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CLIENT_CERT); + return FALSE; + } else if (!g_bytes_get_size(priv->client_cert)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CLIENT_CERT); + return FALSE; + } + + /* Private key is required for TLS */ + if (!priv->private_key) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PRIVATE_KEY); + return FALSE; + } else if (!g_bytes_get_size(priv->private_key)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PRIVATE_KEY); + return FALSE; + } + + /* If the private key is PKCS#12, check that it matches the client cert */ + if (nm_crypto_is_pkcs12_data(g_bytes_get_data(priv->private_key, NULL), + g_bytes_get_size(priv->private_key), + NULL)) { + if (!g_bytes_equal(priv->private_key, priv->client_cert)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("has to match '%s' property for PKCS#12"), + NM_SETTING_802_1X_PRIVATE_KEY); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CLIENT_CERT); + return FALSE; + } + } + } + + return TRUE; +} + +static gboolean +verify_ttls(NMSetting8021x *self, gboolean phase2, GError **error) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self); + + if ((!priv->identity || !strlen(priv->identity)) + && (!priv->anonymous_identity || !strlen(priv->anonymous_identity))) { + if (!priv->identity) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + } else if (!strlen(priv->identity)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + } else if (!priv->anonymous_identity) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_ANONYMOUS_IDENTITY); + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_ANONYMOUS_IDENTITY); + } + return FALSE; + } + + if ((!priv->phase2_auth || !strlen(priv->phase2_auth)) + && (!priv->phase2_autheap || !strlen(priv->phase2_autheap))) { + if (!priv->phase2_auth) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_AUTH); + } else if (!strlen(priv->phase2_auth)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_AUTH); + } else if (!priv->phase2_autheap) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_AUTHEAP); + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_AUTHEAP); + } + return FALSE; + } + + return TRUE; +} + +static gboolean +verify_identity(NMSetting8021x *self, gboolean phase2, GError **error) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self); + + if (!priv->identity) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + return FALSE; + } else if (!strlen(priv->identity)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_IDENTITY); + return FALSE; + } + + return TRUE; +} + +static void +need_secrets_phase2(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self); + char * method = NULL; + int i; + + g_return_if_fail(phase2 == FALSE); + + /* Check phase2_auth and phase2_autheap */ + method = priv->phase2_auth; + if (!method && priv->phase2_autheap) + method = priv->phase2_autheap; + + if (!method) { + g_warning("Couldn't find EAP method."); + g_assert_not_reached(); + return; + } + + /* Ask the configured phase2 method if it needs secrets */ + for (i = 0; eap_methods_table[i].method; i++) { + if (eap_methods_table[i].ns_func == NULL) + continue; + if (!strcmp(eap_methods_table[i].method, method)) { + (*eap_methods_table[i].ns_func)(self, secrets, TRUE); + break; + } + } +} + +static const EAPMethodsTable eap_methods_table[] = { + {"leap", need_secrets_password, verify_identity}, + {"pwd", need_secrets_password, verify_identity}, + {"md5", need_secrets_password, verify_identity}, + {"pap", need_secrets_password, verify_identity}, + {"chap", need_secrets_password, verify_identity}, + {"mschap", need_secrets_password, verify_identity}, + {"mschapv2", need_secrets_password, verify_identity}, + {"fast", need_secrets_password, verify_identity}, + {"tls", need_secrets_tls, verify_tls}, + {"peap", need_secrets_phase2, verify_ttls}, + {"ttls", need_secrets_phase2, verify_ttls}, + {"sim", need_secrets_sim, NULL}, + {"gtc", need_secrets_password, verify_identity}, + {"otp", NULL, NULL}, // FIXME: implement + {"external", NULL, NULL}, + {NULL, NULL, NULL}}; + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSetting8021x * self = NM_SETTING_802_1X(setting); + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self); + const char * valid_eap[] = + {"leap", "md5", "tls", "peap", "ttls", "sim", "fast", "pwd", "external", NULL}; + GSList *iter; + + if (error) + g_return_val_if_fail(*error == NULL, FALSE); + + if (connection && priv->optional + && !nm_streq0(nm_connection_get_connection_type(connection), + NM_SETTING_WIRED_SETTING_NAME)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("can be enabled only on Ethernet connections")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_OPTIONAL); + return FALSE; + } + + if (!priv->eap) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_EAP); + return FALSE; + } + + if (!_nm_utils_string_slist_validate(priv->eap, valid_eap)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_EAP); + return FALSE; + } + + /* Ask each configured EAP method if its valid */ + for (iter = priv->eap; iter; iter = g_slist_next(iter)) { + const char *method = (const char *) iter->data; + int i; + + for (i = 0; eap_methods_table[i].method; i++) { + if (eap_methods_table[i].v_func == NULL) + continue; + if (!strcmp(eap_methods_table[i].method, method)) { + if (!(*eap_methods_table[i].v_func)(self, FALSE, error)) + return FALSE; + break; + } + } + } + + if (!NM_IN_STRSET(priv->phase1_peapver, NULL, "0", "1")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->phase1_peapver); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE1_PEAPVER); + return FALSE; + } + + if (!NM_IN_STRSET(priv->phase1_peaplabel, NULL, "0", "1")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->phase1_peaplabel); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE1_PEAPLABEL); + return FALSE; + } + + if (!NM_IN_STRSET(priv->phase1_fast_provisioning, NULL, "0", "1", "2", "3")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->phase1_fast_provisioning); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING); + return FALSE; + } + + if (NM_FLAGS_ANY(priv->phase1_auth_flags, ~NM_SETTING_802_1X_AUTH_FLAGS_ALL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid auth flags")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE1_AUTH_FLAGS); + return FALSE; + } + + if (!NM_IN_STRSET(priv->phase2_auth, + NULL, + "pap", + "chap", + "mschap", + "mschapv2", + "gtc", + "otp", + "md5", + "tls")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->phase2_auth); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_AUTH); + return FALSE; + } + + if (!NM_IN_STRSET(priv->phase2_autheap, NULL, "md5", "mschapv2", "otp", "gtc", "tls")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->phase2_autheap); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PHASE2_AUTHEAP); + return FALSE; + } + + if (!_cert_verify_property(priv->ca_cert, + NM_SETTING_802_1X_CA_CERT, + priv->ca_cert_password, + NM_SETTING_802_1X_CA_CERT_PASSWORD, + error)) + return FALSE; + if (!_cert_verify_property(priv->phase2_ca_cert, + NM_SETTING_802_1X_PHASE2_CA_CERT, + priv->phase2_ca_cert_password, + NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD, + error)) + return FALSE; + + if (!_cert_verify_property(priv->client_cert, + NM_SETTING_802_1X_CLIENT_CERT, + priv->client_cert_password, + NM_SETTING_802_1X_CLIENT_CERT_PASSWORD, + error)) + return FALSE; + if (!_cert_verify_property(priv->phase2_client_cert, + NM_SETTING_802_1X_PHASE2_CLIENT_CERT, + priv->phase2_client_cert_password, + NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD, + error)) + return FALSE; + + if (!_cert_verify_property(priv->private_key, NM_SETTING_802_1X_PRIVATE_KEY, NULL, NULL, error)) + return FALSE; + if (!_cert_verify_property(priv->phase2_private_key, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + NULL, + NULL, + error)) + return FALSE; + + return TRUE; +} + +/*****************************************************************************/ + +static GPtrArray * +need_secrets(NMSetting *setting) +{ + NMSetting8021x * self = NM_SETTING_802_1X(setting); + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self); + GSList * iter; + GPtrArray * secrets; + gboolean eap_method_found = FALSE; + + secrets = g_ptr_array_sized_new(4); + + /* Ask each configured EAP method if it needs secrets */ + for (iter = priv->eap; iter && !eap_method_found; iter = g_slist_next(iter)) { + const char *method = (const char *) iter->data; + int i; + + for (i = 0; eap_methods_table[i].method; i++) { + if (eap_methods_table[i].ns_func == NULL) + continue; + if (!strcmp(eap_methods_table[i].method, method)) { + (*eap_methods_table[i].ns_func)(self, secrets, FALSE); + + /* Only break out of the outer loop if this EAP method + * needed secrets. + */ + if (secrets->len > 0) + eap_method_found = TRUE; + break; + } + } + } + + if (secrets->len == 0) { + g_ptr_array_free(secrets, TRUE); + return NULL; + } + + return secrets; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSetting8021x * setting = NM_SETTING_802_1X(object); + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_EAP: + g_value_take_boxed(value, _nm_utils_slist_to_strv(priv->eap, TRUE)); + break; + case PROP_IDENTITY: + g_value_set_string(value, priv->identity); + break; + case PROP_ANONYMOUS_IDENTITY: + g_value_set_string(value, priv->anonymous_identity); + break; + case PROP_PAC_FILE: + g_value_set_string(value, priv->pac_file); + break; + case PROP_CA_CERT: + g_value_set_boxed(value, priv->ca_cert); + break; + case PROP_CA_CERT_PASSWORD: + g_value_set_string(value, priv->ca_cert_password); + break; + case PROP_CA_CERT_PASSWORD_FLAGS: + g_value_set_flags(value, priv->ca_cert_password_flags); + break; + case PROP_CA_PATH: + g_value_set_string(value, priv->ca_path); + break; + case PROP_SUBJECT_MATCH: + g_value_set_string(value, priv->subject_match); + break; + case PROP_ALTSUBJECT_MATCHES: + g_value_take_boxed(value, _nm_utils_slist_to_strv(priv->altsubject_matches, TRUE)); + break; + case PROP_DOMAIN_SUFFIX_MATCH: + g_value_set_string(value, priv->domain_suffix_match); + break; + case PROP_DOMAIN_MATCH: + g_value_set_string(value, priv->domain_match); + break; + case PROP_CLIENT_CERT: + g_value_set_boxed(value, priv->client_cert); + break; + case PROP_CLIENT_CERT_PASSWORD: + g_value_set_string(value, priv->client_cert_password); + break; + case PROP_CLIENT_CERT_PASSWORD_FLAGS: + g_value_set_flags(value, priv->client_cert_password_flags); + break; + case PROP_PHASE1_PEAPVER: + g_value_set_string(value, priv->phase1_peapver); + break; + case PROP_PHASE1_PEAPLABEL: + g_value_set_string(value, priv->phase1_peaplabel); + break; + case PROP_PHASE1_FAST_PROVISIONING: + g_value_set_string(value, priv->phase1_fast_provisioning); + break; + case PROP_PHASE1_AUTH_FLAGS: + g_value_set_uint(value, priv->phase1_auth_flags); + break; + case PROP_PHASE2_AUTH: + g_value_set_string(value, priv->phase2_auth); + break; + case PROP_PHASE2_AUTHEAP: + g_value_set_string(value, priv->phase2_autheap); + break; + case PROP_PHASE2_CA_CERT: + g_value_set_boxed(value, priv->phase2_ca_cert); + break; + case PROP_PHASE2_CA_CERT_PASSWORD: + g_value_set_string(value, priv->phase2_ca_cert_password); + break; + case PROP_PHASE2_CA_CERT_PASSWORD_FLAGS: + g_value_set_flags(value, priv->phase2_ca_cert_password_flags); + break; + case PROP_PHASE2_CA_PATH: + g_value_set_string(value, priv->phase2_ca_path); + break; + case PROP_PHASE2_SUBJECT_MATCH: + g_value_set_string(value, priv->phase2_subject_match); + break; + case PROP_PHASE2_ALTSUBJECT_MATCHES: + g_value_take_boxed(value, _nm_utils_slist_to_strv(priv->phase2_altsubject_matches, TRUE)); + break; + case PROP_PHASE2_DOMAIN_SUFFIX_MATCH: + g_value_set_string(value, priv->phase2_domain_suffix_match); + break; + case PROP_PHASE2_DOMAIN_MATCH: + g_value_set_string(value, priv->phase2_domain_match); + break; + case PROP_PHASE2_CLIENT_CERT: + g_value_set_boxed(value, priv->phase2_client_cert); + break; + case PROP_PHASE2_CLIENT_CERT_PASSWORD: + g_value_set_string(value, priv->phase2_client_cert_password); + break; + case PROP_PHASE2_CLIENT_CERT_PASSWORD_FLAGS: + g_value_set_flags(value, priv->phase2_client_cert_password_flags); + break; + case PROP_PASSWORD: + g_value_set_string(value, priv->password); + break; + case PROP_PASSWORD_FLAGS: + g_value_set_flags(value, priv->password_flags); + break; + case PROP_PASSWORD_RAW: + g_value_set_boxed(value, priv->password_raw); + break; + case PROP_PASSWORD_RAW_FLAGS: + g_value_set_flags(value, priv->password_raw_flags); + break; + case PROP_PRIVATE_KEY: + g_value_set_boxed(value, priv->private_key); + break; + case PROP_PRIVATE_KEY_PASSWORD: + g_value_set_string(value, priv->private_key_password); + break; + case PROP_PRIVATE_KEY_PASSWORD_FLAGS: + g_value_set_flags(value, priv->private_key_password_flags); + break; + case PROP_PHASE2_PRIVATE_KEY: + g_value_set_boxed(value, priv->phase2_private_key); + break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD: + g_value_set_string(value, priv->phase2_private_key_password); + break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS: + g_value_set_flags(value, priv->phase2_private_key_password_flags); + break; + case PROP_PIN: + g_value_set_string(value, priv->pin); + break; + case PROP_PIN_FLAGS: + g_value_set_flags(value, priv->pin_flags); + break; + case PROP_SYSTEM_CA_CERTS: + g_value_set_boolean(value, priv->system_ca_certs); + break; + case PROP_AUTH_TIMEOUT: + g_value_set_int(value, priv->auth_timeout); + break; + case PROP_OPTIONAL: + g_value_set_boolean(value, priv->optional); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSetting8021x * setting = NM_SETTING_802_1X(object); + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_EAP: + g_slist_free_full(priv->eap, g_free); + priv->eap = _nm_utils_strv_to_slist(g_value_get_boxed(value), TRUE); + break; + case PROP_IDENTITY: + g_free(priv->identity); + priv->identity = g_value_dup_string(value); + break; + case PROP_ANONYMOUS_IDENTITY: + g_free(priv->anonymous_identity); + priv->anonymous_identity = g_value_dup_string(value); + break; + case PROP_PAC_FILE: + g_free(priv->pac_file); + priv->pac_file = g_value_dup_string(value); + break; + case PROP_CA_CERT: + g_bytes_unref(priv->ca_cert); + priv->ca_cert = g_value_dup_boxed(value); + break; + case PROP_CA_CERT_PASSWORD: + g_free(priv->ca_cert_password); + priv->ca_cert_password = g_value_dup_string(value); + break; + case PROP_CA_CERT_PASSWORD_FLAGS: + priv->ca_cert_password_flags = g_value_get_flags(value); + break; + case PROP_CA_PATH: + g_free(priv->ca_path); + priv->ca_path = g_value_dup_string(value); + break; + case PROP_SUBJECT_MATCH: + g_free(priv->subject_match); + priv->subject_match = nm_strdup_not_empty(g_value_get_string(value)); + break; + case PROP_ALTSUBJECT_MATCHES: + g_slist_free_full(priv->altsubject_matches, g_free); + priv->altsubject_matches = _nm_utils_strv_to_slist(g_value_get_boxed(value), TRUE); + break; + case PROP_DOMAIN_SUFFIX_MATCH: + g_free(priv->domain_suffix_match); + priv->domain_suffix_match = nm_strdup_not_empty(g_value_get_string(value)); + break; + case PROP_DOMAIN_MATCH: + g_free(priv->domain_match); + priv->domain_match = nm_strdup_not_empty(g_value_get_string(value)); + break; + case PROP_CLIENT_CERT: + g_bytes_unref(priv->client_cert); + priv->client_cert = g_value_dup_boxed(value); + break; + case PROP_CLIENT_CERT_PASSWORD: + g_free(priv->client_cert_password); + priv->client_cert_password = g_value_dup_string(value); + break; + case PROP_CLIENT_CERT_PASSWORD_FLAGS: + priv->client_cert_password_flags = g_value_get_flags(value); + break; + case PROP_PHASE1_PEAPVER: + g_free(priv->phase1_peapver); + priv->phase1_peapver = g_value_dup_string(value); + break; + case PROP_PHASE1_PEAPLABEL: + g_free(priv->phase1_peaplabel); + priv->phase1_peaplabel = g_value_dup_string(value); + break; + case PROP_PHASE1_FAST_PROVISIONING: + g_free(priv->phase1_fast_provisioning); + priv->phase1_fast_provisioning = g_value_dup_string(value); + break; + case PROP_PHASE1_AUTH_FLAGS: + priv->phase1_auth_flags = g_value_get_uint(value); + break; + case PROP_PHASE2_AUTH: + g_free(priv->phase2_auth); + priv->phase2_auth = g_value_dup_string(value); + break; + case PROP_PHASE2_AUTHEAP: + g_free(priv->phase2_autheap); + priv->phase2_autheap = g_value_dup_string(value); + break; + case PROP_PHASE2_CA_CERT: + g_bytes_unref(priv->phase2_ca_cert); + priv->phase2_ca_cert = g_value_dup_boxed(value); + break; + case PROP_PHASE2_CA_CERT_PASSWORD: + g_free(priv->phase2_ca_cert_password); + priv->phase2_ca_cert_password = g_value_dup_string(value); + break; + case PROP_PHASE2_CA_CERT_PASSWORD_FLAGS: + priv->phase2_ca_cert_password_flags = g_value_get_flags(value); + break; + case PROP_PHASE2_CA_PATH: + g_free(priv->phase2_ca_path); + priv->phase2_ca_path = g_value_dup_string(value); + break; + case PROP_PHASE2_SUBJECT_MATCH: + g_free(priv->phase2_subject_match); + priv->phase2_subject_match = nm_strdup_not_empty(g_value_get_string(value)); + break; + case PROP_PHASE2_ALTSUBJECT_MATCHES: + g_slist_free_full(priv->phase2_altsubject_matches, g_free); + priv->phase2_altsubject_matches = _nm_utils_strv_to_slist(g_value_get_boxed(value), TRUE); + break; + case PROP_PHASE2_DOMAIN_SUFFIX_MATCH: + g_free(priv->phase2_domain_suffix_match); + priv->phase2_domain_suffix_match = nm_strdup_not_empty(g_value_get_string(value)); + break; + case PROP_PHASE2_DOMAIN_MATCH: + g_free(priv->phase2_domain_match); + priv->phase2_domain_match = nm_strdup_not_empty(g_value_get_string(value)); + break; + case PROP_PHASE2_CLIENT_CERT: + g_bytes_unref(priv->phase2_client_cert); + priv->phase2_client_cert = g_value_dup_boxed(value); + break; + case PROP_PHASE2_CLIENT_CERT_PASSWORD: + g_free(priv->phase2_client_cert_password); + priv->phase2_client_cert_password = g_value_dup_string(value); + break; + case PROP_PHASE2_CLIENT_CERT_PASSWORD_FLAGS: + priv->phase2_client_cert_password_flags = g_value_get_flags(value); + break; + case PROP_PASSWORD: + g_free(priv->password); + priv->password = g_value_dup_string(value); + break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_flags(value); + break; + case PROP_PASSWORD_RAW: + g_bytes_unref(priv->password_raw); + priv->password_raw = g_value_dup_boxed(value); + break; + case PROP_PASSWORD_RAW_FLAGS: + priv->password_raw_flags = g_value_get_flags(value); + break; + case PROP_PRIVATE_KEY: + g_bytes_unref(priv->private_key); + priv->private_key = g_value_dup_boxed(value); + break; + case PROP_PRIVATE_KEY_PASSWORD: + nm_free_secret(priv->private_key_password); + priv->private_key_password = g_value_dup_string(value); + break; + case PROP_PRIVATE_KEY_PASSWORD_FLAGS: + priv->private_key_password_flags = g_value_get_flags(value); + break; + case PROP_PHASE2_PRIVATE_KEY: + g_bytes_unref(priv->phase2_private_key); + priv->phase2_private_key = g_value_dup_boxed(value); + break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD: + nm_free_secret(priv->phase2_private_key_password); + priv->phase2_private_key_password = g_value_dup_string(value); + break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS: + priv->phase2_private_key_password_flags = g_value_get_flags(value); + break; + case PROP_PIN: + g_free(priv->pin); + priv->pin = g_value_dup_string(value); + break; + case PROP_PIN_FLAGS: + priv->pin_flags = g_value_get_flags(value); + break; + case PROP_SYSTEM_CA_CERTS: + priv->system_ca_certs = g_value_get_boolean(value); + break; + case PROP_AUTH_TIMEOUT: + priv->auth_timeout = g_value_get_int(value); + break; + case PROP_OPTIONAL: + priv->optional = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_802_1x_init(NMSetting8021x *setting) +{} + +/** + * nm_setting_802_1x_new: + * + * Creates a new #NMSetting8021x object with default values. + * + * Returns: the new empty #NMSetting8021x object + **/ +NMSetting * +nm_setting_802_1x_new(void) +{ + return g_object_new(NM_TYPE_SETTING_802_1X, NULL); +} + +static void +finalize(GObject *object) +{ + NMSetting8021x * self = NM_SETTING_802_1X(object); + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self); + + g_free(priv->identity); + g_free(priv->anonymous_identity); + g_free(priv->ca_path); + g_free(priv->subject_match); + g_free(priv->domain_suffix_match); + g_free(priv->phase1_peapver); + g_free(priv->phase1_peaplabel); + g_free(priv->phase1_fast_provisioning); + g_free(priv->phase2_auth); + g_free(priv->phase2_autheap); + g_free(priv->phase2_ca_path); + g_free(priv->phase2_subject_match); + g_free(priv->phase2_domain_suffix_match); + g_free(priv->password); + g_bytes_unref(priv->password_raw); + g_free(priv->pin); + + g_slist_free_full(priv->eap, g_free); + g_slist_free_full(priv->altsubject_matches, g_free); + g_slist_free_full(priv->phase2_altsubject_matches, g_free); + + g_bytes_unref(priv->ca_cert); + g_free(priv->ca_cert_password); + g_bytes_unref(priv->client_cert); + g_free(priv->client_cert_password); + g_bytes_unref(priv->private_key); + nm_free_secret(priv->private_key_password); + g_bytes_unref(priv->phase2_ca_cert); + g_free(priv->phase2_ca_cert_password); + g_bytes_unref(priv->phase2_client_cert); + g_free(priv->phase2_client_cert_password); + g_bytes_unref(priv->phase2_private_key); + nm_free_secret(priv->phase2_private_key_password); + + G_OBJECT_CLASS(nm_setting_802_1x_parent_class)->finalize(object); +} + +static void +nm_setting_802_1x_class_init(NMSetting8021xClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSetting8021xPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->need_secrets = need_secrets; + + /** + * NMSetting8021x:eap: + * + * The allowed EAP method to be used when authenticating to the network with + * 802.1x. Valid methods are: "leap", "md5", "tls", "peap", "ttls", "pwd", + * and "fast". Each method requires different configuration using the + * properties of this setting; refer to wpa_supplicant documentation for the + * allowed combinations. + **/ + /* ---ifcfg-rh--- + * property: eap + * variable: IEEE_8021X_EAP_METHODS(+) + * values: "LEAP", "PWD", "TLS", "PEAP", "TTLS", "FAST" + * description: EAP method for 802.1X authentication. + * example: IEEE_8021X_EAP_METHODS=PEAP + * ---end--- + */ + obj_properties[PROP_EAP] = g_param_spec_boxed(NM_SETTING_802_1X_EAP, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:identity: + * + * Identity string for EAP authentication methods. Often the user's user or + * login name. + **/ + /* ---ifcfg-rh--- + * property: identity + * variable: IEEE_8021X_IDENTITY(+) + * description: Identity for EAP authentication methods. + * example: IEEE_8021X_IDENTITY=itsme + * ---end--- + */ + obj_properties[PROP_IDENTITY] = g_param_spec_string(NM_SETTING_802_1X_IDENTITY, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:anonymous-identity: + * + * Anonymous identity string for EAP authentication methods. Used as the + * unencrypted identity with EAP types that support different tunneled + * identity like EAP-TTLS. + **/ + /* ---ifcfg-rh--- + * property: anonymous-identity + * variable: IEEE_8021X_ANON_IDENTITY(+) + * description: Anonymous identity for EAP authentication methods. + * ---end--- + */ + obj_properties[PROP_ANONYMOUS_IDENTITY] = + g_param_spec_string(NM_SETTING_802_1X_ANONYMOUS_IDENTITY, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:pac-file: + * + * UTF-8 encoded file path containing PAC for EAP-FAST. + **/ + /* ---ifcfg-rh--- + * property: pac-file + * variable: IEEE_8021X_PAC_FILE(+) + * description: File with PAC (Protected Access Credential) for EAP-FAST. + * example: IEEE_8021X_PAC_FILE=/home/joe/my-fast.pac + * ---end--- + */ + obj_properties[PROP_PAC_FILE] = g_param_spec_string(NM_SETTING_802_1X_PAC_FILE, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:ca-cert: + * + * Contains the CA certificate if used by the EAP method specified in the + * #NMSetting8021x:eap property. + * + * Certificate data is specified using a "scheme"; three are currently + * supported: blob, path and pkcs#11 URL. When using the blob scheme this property + * should be set to the certificate's DER encoded data. When using the path + * scheme, this property should be set to the full UTF-8 encoded path of the + * certificate, prefixed with the string "file://" and ending with a terminating + * NUL byte. + * This property can be unset even if the EAP method supports CA certificates, + * but this allows man-in-the-middle attacks and is NOT recommended. + * + * Note that enabling NMSetting8021x:system-ca-certs will override this + * setting to use the built-in path, if the built-in path is not a directory. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_ca_cert() function instead. + **/ + /* ---ifcfg-rh--- + * property: ca-cert + * variable: IEEE_8021X_CA_CERT(+) + * description: CA certificate for EAP. + * example: IEEE_8021X_CA_CERT=/home/joe/cacert.crt + * ---end--- + */ + obj_properties[PROP_CA_CERT] = g_param_spec_boxed(NM_SETTING_802_1X_CA_CERT, + "", + "", + G_TYPE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:ca-cert-password: + * + * The password used to access the CA certificate stored in + * #NMSetting8021x:ca-cert property. Only makes sense if the certificate + * is stored on a PKCS#11 token that requires a login. + * + * Since: 1.8 + **/ + /* ---ifcfg-rh--- + * ---end--- + */ + obj_properties[PROP_CA_CERT_PASSWORD] = + g_param_spec_string(NM_SETTING_802_1X_CA_CERT_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:ca-cert-password-flags: + * + * Flags indicating how to handle the #NMSetting8021x:ca-cert-password property. + * + * Since: 1.8 + **/ + /* ---ifcfg-rh--- + * ---end--- + */ + obj_properties[PROP_CA_CERT_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_802_1X_CA_CERT_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:ca-path: + * + * UTF-8 encoded path to a directory containing PEM or DER formatted + * certificates to be added to the verification chain in addition to the + * certificate specified in the #NMSetting8021x:ca-cert property. + * + * If NMSetting8021x:system-ca-certs is enabled and the built-in CA + * path is an existing directory, then this setting is ignored. + **/ + /* ---ifcfg-rh--- + * property: ca-path + * variable: IEEE_8021X_CA_PATH(+) + * description: The search path for the certificate. + * ---end--- + */ + obj_properties[PROP_CA_PATH] = g_param_spec_string(NM_SETTING_802_1X_CA_PATH, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:subject-match: + * + * Substring to be matched against the subject of the certificate presented + * by the authentication server. When unset, no verification of the + * authentication server certificate's subject is performed. This property + * provides little security, if any, and its use is deprecated in favor of + * NMSetting8021x:domain-suffix-match. + **/ + /* ---ifcfg-rh--- + * property: subject-match + * variable: IEEE_8021X_SUBJECT_MATCH(+) + * description: Substring to match subject of server certificate against. + * example: IEEE_8021X_SUBJECT_MATCH="Red Hat" + * ---end--- + */ + obj_properties[PROP_SUBJECT_MATCH] = + g_param_spec_string(NM_SETTING_802_1X_SUBJECT_MATCH, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:altsubject-matches: + * + * List of strings to be matched against the altSubjectName of the + * certificate presented by the authentication server. If the list is empty, + * no verification of the server certificate's altSubjectName is performed. + **/ + /* ---ifcfg-rh--- + * property: altsubject-matches + * variable: IEEE_8021X_ALTSUBJECT_MATCHES(+) + * description: List of strings to be matched against the altSubjectName. + * example: IEEE_8021X_ALTSUBJECT_MATCHES="s1.domain.cc" + * ---end--- + */ + obj_properties[PROP_ALTSUBJECT_MATCHES] = + g_param_spec_boxed(NM_SETTING_802_1X_ALTSUBJECT_MATCHES, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:domain-suffix-match: + * + * Constraint for server domain name. If set, this FQDN is used as a suffix + * match requirement for dNSName element(s) of the certificate presented by + * the authentication server. If a matching dNSName is found, this + * constraint is met. If no dNSName values are present, this constraint is + * matched against SubjectName CN using same suffix match comparison. + * Since version 1.24, multiple valid FQDNs can be passed as a ";" delimited + * list. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: domain-suffix-match + * description: Suffix to match domain of server certificate against. + * variable: IEEE_8021X_DOMAIN_SUFFIX_MATCH(+) + * ---end--- + */ + obj_properties[PROP_DOMAIN_SUFFIX_MATCH] = + g_param_spec_string(NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:domain-match: + * + * Constraint for server domain name. If set, this list of FQDNs is used as + * a match requirement for dNSName element(s) of the certificate presented + * by the authentication server. If a matching dNSName is found, this + * constraint is met. If no dNSName values are present, this constraint is + * matched against SubjectName CN using the same comparison. + * Multiple valid FQDNs can be passed as a ";" delimited list. + * + * Since: 1.24 + **/ + /* ---ifcfg-rh--- + * property: domain-match + * description: Value to match domain of server certificate against. + * variable: IEEE_8021X_DOMAIN_MATCH(+) + * ---end--- + */ + obj_properties[PROP_DOMAIN_MATCH] = + g_param_spec_string(NM_SETTING_802_1X_DOMAIN_MATCH, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:client-cert: + * + * Contains the client certificate if used by the EAP method specified in + * the #NMSetting8021x:eap property. + * + * Certificate data is specified using a "scheme"; two are currently + * supported: blob and path. When using the blob scheme (which is backwards + * compatible with NM 0.7.x) this property should be set to the + * certificate's DER encoded data. When using the path scheme, this property + * should be set to the full UTF-8 encoded path of the certificate, prefixed + * with the string "file://" and ending with a terminating NUL byte. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_client_cert() function instead. + **/ + /* ---ifcfg-rh--- + * property: client-cert + * variable: IEEE_8021X_CLIENT_CERT(+) + * description: Client certificate for EAP. + * example: IEEE_8021X_CLIENT_CERT=/home/joe/mycert.crt + * ---end--- + */ + obj_properties[PROP_CLIENT_CERT] = + g_param_spec_boxed(NM_SETTING_802_1X_CLIENT_CERT, + "", + "", + G_TYPE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:client-cert-password: + * + * The password used to access the client certificate stored in + * #NMSetting8021x:client-cert property. Only makes sense if the certificate + * is stored on a PKCS#11 token that requires a login. + * + * Since: 1.8 + **/ + /* ---ifcfg-rh--- + * ---end--- + */ + obj_properties[PROP_CLIENT_CERT_PASSWORD] = + g_param_spec_string(NM_SETTING_802_1X_CLIENT_CERT_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:client-cert-password-flags: + * + * Flags indicating how to handle the #NMSetting8021x:client-cert-password property. + * + * Since: 1.8 + **/ + /* ---ifcfg-rh--- + * ---end--- + */ + obj_properties[PROP_CLIENT_CERT_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_802_1X_CLIENT_CERT_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase1-peapver: + * + * Forces which PEAP version is used when PEAP is set as the EAP method in + * the #NMSetting8021x:eap property. When unset, the version reported by + * the server will be used. Sometimes when using older RADIUS servers, it + * is necessary to force the client to use a particular PEAP version. To do + * so, this property may be set to "0" or "1" to force that specific PEAP + * version. + **/ + /* ---ifcfg-rh--- + * property: phase1-peapver + * variable: IEEE_8021X_PEAP_VERSION(+) + * values: 0, 1 + * description: Use to force a specific PEAP version. + * ---end--- + */ + obj_properties[PROP_PHASE1_PEAPVER] = + g_param_spec_string(NM_SETTING_802_1X_PHASE1_PEAPVER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase1-peaplabel: + * + * Forces use of the new PEAP label during key derivation. Some RADIUS + * servers may require forcing the new PEAP label to interoperate with + * PEAPv1. Set to "1" to force use of the new PEAP label. See the + * wpa_supplicant documentation for more details. + **/ + /* ---ifcfg-rh--- + * property: phase1-peaplabel + * variable: IEEE_8021X_PEAP_FORCE_NEW_LABEL(+) + * values: yes, no + * default: no + * description: Use to force the new PEAP label during key derivation. + * ---end--- + */ + obj_properties[PROP_PHASE1_PEAPLABEL] = + g_param_spec_string(NM_SETTING_802_1X_PHASE1_PEAPLABEL, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase1-fast-provisioning: + * + * Enables or disables in-line provisioning of EAP-FAST credentials when + * FAST is specified as the EAP method in the #NMSetting8021x:eap property. + * Recognized values are "0" (disabled), "1" (allow unauthenticated + * provisioning), "2" (allow authenticated provisioning), and "3" (allow + * both authenticated and unauthenticated provisioning). See the + * wpa_supplicant documentation for more details. + **/ + /* ---ifcfg-rh--- + * property: phase1-fast-provisioning + * variable: IEEE_8021X_FAST_PROVISIONING(+) + * values: space-separated list of these values [allow-auth, allow-unauth] + * description: Enable in-line provisioning of EAP-FAST credentials. + * example: IEEE_8021X_FAST_PROVISIONING="allow-auth allow-unauth" + * ---end--- + */ + obj_properties[PROP_PHASE1_FAST_PROVISIONING] = + g_param_spec_string(NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase1-auth-flags: + * + * Specifies authentication flags to use in "phase 1" outer + * authentication using #NMSetting8021xAuthFlags options. + * The individual TLS versions can be explicitly disabled. If a certain + * TLS disable flag is not set, it is up to the supplicant to allow + * or forbid it. The TLS options map to tls_disable_tlsv1_x settings. + * See the wpa_supplicant documentation for more details. + * + * Since: 1.8 + */ + /* ---ifcfg-rh--- + * property: phase1-auth-flags + * variable: IEEE_8021X_PHASE1_AUTH_FLAGS(+) + * values: space-separated list of authentication flags names + * description: Authentication flags for the supplicant + * example: IEEE_8021X_PHASE1_AUTH_FLAGS="tls-1-0-disable tls-1-1-disable" + * ---end--- + */ + obj_properties[PROP_PHASE1_AUTH_FLAGS] = + g_param_spec_uint(NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, + "", + "", + 0, + G_MAXUINT32, + NM_SETTING_802_1X_AUTH_FLAGS_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-auth: + * + * Specifies the allowed "phase 2" inner authentication method when an EAP + * method that uses an inner TLS tunnel is specified in the #NMSetting8021x:eap + * property. For TTLS this property selects one of the supported non-EAP + * inner methods: "pap", "chap", "mschap", "mschapv2" while + * #NMSetting8021x:phase2-autheap selects an EAP inner method. For PEAP + * this selects an inner EAP method, one of: "gtc", "otp", "md5" and "tls". + * Each "phase 2" inner method requires specific parameters for successful + * authentication; see the wpa_supplicant documentation for more details. + * Both #NMSetting8021x:phase2-auth and #NMSetting8021x:phase2-autheap cannot + * be specified. + **/ + /* ---ifcfg-rh--- + * property: phase2-auth + * variable: IEEE_8021X_INNER_AUTH_METHODS(+) + * values: "PAP", "CHAP", "MSCHAP", "MSCHAPV2", "GTC", "OTP", "MD5" and "TLS" + * description: Inner non-EAP authentication methods for TTLS or the inner EAP + * authentication method for PEAP. IEEE_8021X_INNER_AUTH_METHODS can contain + * values both for 'phase2-auth' and 'phase2-autheap' properties. + * example: IEEE_8021X_INNER_AUTH_METHODS=PAP + * ---end--- + */ + obj_properties[PROP_PHASE2_AUTH] = + g_param_spec_string(NM_SETTING_802_1X_PHASE2_AUTH, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-autheap: + * + * Specifies the allowed "phase 2" inner EAP-based authentication method + * when TTLS is specified in the #NMSetting8021x:eap property. Recognized + * EAP-based "phase 2" methods are "md5", "mschapv2", "otp", "gtc", and + * "tls". Each "phase 2" inner method requires specific parameters for + * successful authentication; see the wpa_supplicant documentation for + * more details. + **/ + /* ---ifcfg-rh--- + * property: phase2-autheap + * variable: IEEE_8021X_INNER_AUTH_METHODS(+) + * values: "EAP-MD5", "EAP-MSCHAPV2", "EAP-GTC", "EAP-OTP" and "EAP-TLS" + * description: Inner EAP-based authentication methods. Note that + * IEEE_8021X_INNER_AUTH_METHODS is also used for 'phase2-auth' values. + * example: IEEE_8021X_INNER_AUTH_METHODS="MSCHAPV2 EAP-TLS" + * ---end--- + */ + obj_properties[PROP_PHASE2_AUTHEAP] = + g_param_spec_string(NM_SETTING_802_1X_PHASE2_AUTHEAP, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-ca-cert: + * + * Contains the "phase 2" CA certificate if used by the EAP method specified + * in the #NMSetting8021x:phase2-auth or #NMSetting8021x:phase2-autheap + * properties. + * + * Certificate data is specified using a "scheme"; three are currently + * supported: blob, path and pkcs#11 URL. When using the blob scheme this property + * should be set to the certificate's DER encoded data. When using the path + * scheme, this property should be set to the full UTF-8 encoded path of the + * certificate, prefixed with the string "file://" and ending with a terminating + * NUL byte. + * This property can be unset even if the EAP method supports CA certificates, + * but this allows man-in-the-middle attacks and is NOT recommended. + * + * Note that enabling NMSetting8021x:system-ca-certs will override this + * setting to use the built-in path, if the built-in path is not a directory. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_phase2_ca_cert() function instead. + **/ + obj_properties[PROP_PHASE2_CA_CERT] = + g_param_spec_boxed(NM_SETTING_802_1X_PHASE2_CA_CERT, + "", + "", + G_TYPE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-ca-cert-password: + * + * The password used to access the "phase2" CA certificate stored in + * #NMSetting8021x:phase2-ca-cert property. Only makes sense if the certificate + * is stored on a PKCS#11 token that requires a login. + * + * Since: 1.8 + **/ + /* ---ifcfg-rh--- + * ---end--- + */ + obj_properties[PROP_PHASE2_CA_CERT_PASSWORD] = + g_param_spec_string(NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-ca-cert-password-flags: + * + * Flags indicating how to handle the #NMSetting8021x:phase2-ca-cert-password property. + * + * Since: 1.8 + **/ + /* ---ifcfg-rh--- + * ---end--- + */ + obj_properties[PROP_PHASE2_CA_CERT_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-ca-path: + * + * UTF-8 encoded path to a directory containing PEM or DER formatted + * certificates to be added to the verification chain in addition to the + * certificate specified in the #NMSetting8021x:phase2-ca-cert property. + * + * If NMSetting8021x:system-ca-certs is enabled and the built-in CA + * path is an existing directory, then this setting is ignored. + **/ + /* ---ifcfg-rh--- + * property: phase2-ca-path + * variable: IEEE_8021X_PHASE2_CA_PATH(+) + * description: The search path for the certificate. + * ---end--- + */ + obj_properties[PROP_PHASE2_CA_PATH] = + g_param_spec_string(NM_SETTING_802_1X_PHASE2_CA_PATH, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-subject-match: + * + * Substring to be matched against the subject of the certificate presented + * by the authentication server during the inner "phase 2" + * authentication. When unset, no verification of the authentication server + * certificate's subject is performed. This property provides little security, + * if any, and its use is deprecated in favor of + * NMSetting8021x:phase2-domain-suffix-match. + **/ + /* ---ifcfg-rh--- + * property: phase2-subject-match + * variable: IEEE_8021X_PHASE2_SUBJECT_MATCH(+) + * description: Substring to match subject of server certificate against. + * example: IEEE_8021X_PHASE2_SUBJECT_MATCH="Red Hat" + * ---end--- + */ + obj_properties[PROP_PHASE2_SUBJECT_MATCH] = + g_param_spec_string(NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-altsubject-matches: + * + * List of strings to be matched against the altSubjectName of the + * certificate presented by the authentication server during the inner + * "phase 2" authentication. If the list is empty, no verification of the + * server certificate's altSubjectName is performed. + **/ + /* ---ifcfg-rh--- + * property: phase2-altsubject-matches + * variable: IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES(+) + * ---end--- + */ + obj_properties[PROP_PHASE2_ALTSUBJECT_MATCHES] = + g_param_spec_boxed(NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-domain-suffix-match: + * + * Constraint for server domain name. If set, this FQDN is used as a suffix + * match requirement for dNSName element(s) of the certificate presented by + * the authentication server during the inner "phase 2" authentication. If + * a matching dNSName is found, this constraint is met. If no dNSName + * values are present, this constraint is matched against SubjectName CN + * using same suffix match comparison. + * Since version 1.24, multiple valid FQDNs can be passed as a ";" delimited + * list. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: phase2-domain-suffix-match + * description: Suffix to match domain of server certificate for phase 2 against. + * variable: IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH(+) + * ---end--- + */ + obj_properties[PROP_PHASE2_DOMAIN_SUFFIX_MATCH] = + g_param_spec_string(NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-domain-match: + * + * Constraint for server domain name. If set, this list of FQDNs is used as + * a match requirement for dNSName element(s) of the certificate presented + * by the authentication server during the inner "phase 2" authentication. + * If a matching dNSName is found, this constraint is met. If no dNSName + * values are present, this constraint is matched against SubjectName CN + * using the same comparison. + * Multiple valid FQDNs can be passed as a ";" delimited list. + * + * Since: 1.24 + **/ + /* ---ifcfg-rh--- + * property: phase2-domain-match + * description: Value to match domain of server certificate for phase 2 against. + * variable: IEEE_8021X_PHASE2_DOMAIN_MATCH(+) + * ---end--- + */ + obj_properties[PROP_PHASE2_DOMAIN_MATCH] = + g_param_spec_string(NM_SETTING_802_1X_PHASE2_DOMAIN_MATCH, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-client-cert: + * + * Contains the "phase 2" client certificate if used by the EAP method + * specified in the #NMSetting8021x:phase2-auth or + * #NMSetting8021x:phase2-autheap properties. + * + * Certificate data is specified using a "scheme"; two are currently + * supported: blob and path. When using the blob scheme (which is backwards + * compatible with NM 0.7.x) this property should be set to the + * certificate's DER encoded data. When using the path scheme, this property + * should be set to the full UTF-8 encoded path of the certificate, prefixed + * with the string "file://" and ending with a terminating NUL byte. This + * property can be unset even if the EAP method supports CA certificates, + * but this allows man-in-the-middle attacks and is NOT recommended. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_phase2_client_cert() function instead. + **/ + /* ---ifcfg-rh--- + * property: phase2-client-cert + * variable: IEEE_8021X_INNER_CLIENT_CERT(+) + * description: Client certificate for inner EAP method. + * example: IEEE_8021X_INNER_CLIENT_CERT=/home/joe/mycert.crt + * ---end--- + */ + obj_properties[PROP_PHASE2_CLIENT_CERT] = + g_param_spec_boxed(NM_SETTING_802_1X_PHASE2_CLIENT_CERT, + "", + "", + G_TYPE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-client-cert-password: + * + * The password used to access the "phase2" client certificate stored in + * #NMSetting8021x:phase2-client-cert property. Only makes sense if the certificate + * is stored on a PKCS#11 token that requires a login. + * + * Since: 1.8 + **/ + /* ---ifcfg-rh--- + * ---end--- + */ + obj_properties[PROP_PHASE2_CLIENT_CERT_PASSWORD] = + g_param_spec_string(NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-client-cert-password-flags: + * + * Flags indicating how to handle the #NMSetting8021x:phase2-client-cert-password property. + * + * Since: 1.8 + **/ + /* ---ifcfg-rh--- + * ---end--- + */ + obj_properties[PROP_PHASE2_CLIENT_CERT_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:password: + * + * UTF-8 encoded password used for EAP authentication methods. If both the + * #NMSetting8021x:password property and the #NMSetting8021x:password-raw + * property are specified, #NMSetting8021x:password is preferred. + **/ + /* ---ifcfg-rh--- + * property: password + * variable: IEEE_8021X_PASSWORD(+) + * description: UTF-8 encoded password used for EAP. It can also go to "key-" + * lookaside file, or it can be owned by a secret agent. + * ---end--- + */ + obj_properties[PROP_PASSWORD] = + g_param_spec_string(NM_SETTING_802_1X_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:password-flags: + * + * Flags indicating how to handle the #NMSetting8021x:password property. + **/ + /* ---ifcfg-rh--- + * property: password-flags + * variable: IEEE_8021X_PASSWORD_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for IEEE_8021X_PASSWORD password. + * ---end--- + */ + obj_properties[PROP_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_802_1X_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:password-raw: + * + * Password used for EAP authentication methods, given as a byte array to + * allow passwords in other encodings than UTF-8 to be used. If both the + * #NMSetting8021x:password property and the #NMSetting8021x:password-raw + * property are specified, #NMSetting8021x:password is preferred. + **/ + /* ---ifcfg-rh--- + * property: password-raw + * variable: IEEE_8021X_PASSWORD_RAW(+) + * description: password used for EAP, encoded as a hexadecimal string. It + * can also go to "key-" lookaside file. + * example: IEEE_8021X_PASSWORD_RAW=041c8320083aa4bf + * ---end--- + */ + obj_properties[PROP_PASSWORD_RAW] = + g_param_spec_boxed(NM_SETTING_802_1X_PASSWORD_RAW, + "", + "", + G_TYPE_BYTES, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:password-raw-flags: + * + * Flags indicating how to handle the #NMSetting8021x:password-raw property. + **/ + /* ---ifcfg-rh--- + * property: password-raw-flags + * variable: IEEE_8021X_PASSWORD_RAW_FLAGS(+) + * description: The secret flags for password-raw. + * ---end--- + */ + obj_properties[PROP_PASSWORD_RAW_FLAGS] = + g_param_spec_flags(NM_SETTING_802_1X_PASSWORD_RAW_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:private-key: + * + * Contains the private key when the #NMSetting8021x:eap property is set to + * "tls". + * + * Key data is specified using a "scheme"; two are currently supported: blob + * and path. When using the blob scheme and private keys, this property + * should be set to the key's encrypted PEM encoded data. When using private + * keys with the path scheme, this property should be set to the full UTF-8 + * encoded path of the key, prefixed with the string "file://" and ending + * with a terminating NUL byte. When using PKCS#12 format private + * keys and the blob scheme, this property should be set to the + * PKCS#12 data and the #NMSetting8021x:private-key-password + * property must be set to password used to decrypt the PKCS#12 + * certificate and key. When using PKCS#12 files and the path + * scheme, this property should be set to the full UTF-8 encoded path of the + * key, prefixed with the string "file://" and ending with a terminating + * NUL byte, and as with the blob scheme the "private-key-password" property + * must be set to the password used to decode the PKCS#12 private + * key and certificate. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_private_key() function instead. + * + * WARNING: #NMSetting8021x:private-key is not a "secret" property, and thus + * unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a + * private key password to prevent unauthorized access to unencrypted + * private key data. + **/ + /* ---ifcfg-rh--- + * property: private-key + * variable: IEEE_8021X_PRIVATE_KEY(+) + * description: Private key for EAP-TLS. + * example: IEEE_8021X_PRIVATE_KEY=/home/joe/mykey.p12 + * ---end--- + */ + obj_properties[PROP_PRIVATE_KEY] = + g_param_spec_boxed(NM_SETTING_802_1X_PRIVATE_KEY, + "", + "", + G_TYPE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:private-key-password: + * + * The password used to decrypt the private key specified in the + * #NMSetting8021x:private-key property when the private key either uses the + * path scheme, or if the private key is a PKCS#12 format key. Setting this + * property directly is not generally necessary except when returning + * secrets to NetworkManager; it is generally set automatically when setting + * the private key by the nm_setting_802_1x_set_private_key() function. + **/ + /* ---ifcfg-rh--- + * property: private-key-password + * variable: IEEE_8021X_PRIVATE_KEY_PASSWORD(+) + * description: Password for IEEE_8021X_PRIVATE_KEY. It can also go to "key-" + * lookaside file, or it can be owned by a secret agent. + * ---end--- + */ + obj_properties[PROP_PRIVATE_KEY_PASSWORD] = + g_param_spec_string(NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:private-key-password-flags: + * + * Flags indicating how to handle the #NMSetting8021x:private-key-password + * property. + **/ + /* ---ifcfg-rh--- + * property: private-key-password-flags + * variable: IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for IEEE_8021X_PRIVATE_KEY_PASSWORD password. + * ---end--- + */ + obj_properties[PROP_PRIVATE_KEY_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-private-key: + * + * Contains the "phase 2" inner private key when the + * #NMSetting8021x:phase2-auth or #NMSetting8021x:phase2-autheap property is + * set to "tls". + * + * Key data is specified using a "scheme"; two are currently supported: blob + * and path. When using the blob scheme and private keys, this property + * should be set to the key's encrypted PEM encoded data. When using private + * keys with the path scheme, this property should be set to the full UTF-8 + * encoded path of the key, prefixed with the string "file://" and ending + * with a terminating NUL byte. When using PKCS#12 format private + * keys and the blob scheme, this property should be set to the + * PKCS#12 data and the #NMSetting8021x:phase2-private-key-password + * property must be set to password used to decrypt the PKCS#12 + * certificate and key. When using PKCS#12 files and the path + * scheme, this property should be set to the full UTF-8 encoded path of the + * key, prefixed with the string "file://" and ending with a terminating + * NUL byte, and as with the blob scheme the + * #NMSetting8021x:phase2-private-key-password property must be set to the + * password used to decode the PKCS#12 private key and certificate. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_phase2_private_key() function instead. + **/ + /* ---ifcfg-rh--- + * property: phase2-private-key + * variable: IEEE_8021X_INNER_PRIVATE_KEY(+) + * description: Private key for inner authentication method for EAP-TLS. + * ---end--- + */ + obj_properties[PROP_PHASE2_PRIVATE_KEY] = + g_param_spec_boxed(NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + "", + "", + G_TYPE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-private-key-password: + * + * The password used to decrypt the "phase 2" private key specified in the + * #NMSetting8021x:phase2-private-key property when the private key either + * uses the path scheme, or is a PKCS#12 format key. Setting this + * property directly is not generally necessary except when returning + * secrets to NetworkManager; it is generally set automatically when setting + * the private key by the nm_setting_802_1x_set_phase2_private_key() + * function. + **/ + /* ---ifcfg-rh--- + * property: phase2-private-key-password + * variable: IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD(+) + * description: Password for IEEE_8021X_INNER_PRIVATE_KEY. It can also go to "key-" + * lookaside file, or it can be owned by a secret agent. + * ---end--- + */ + obj_properties[PROP_PHASE2_PRIVATE_KEY_PASSWORD] = + g_param_spec_string(NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:phase2-private-key-password-flags: + * + * Flags indicating how to handle the + * #NMSetting8021x:phase2-private-key-password property. + **/ + /* ---ifcfg-rh--- + * property: phase2-private-key-password-flags + * variable: IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD password. + * ---end--- + */ + obj_properties[PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:pin: + * + * PIN used for EAP authentication methods. + **/ + /* ---ifcfg-rh--- + * property: pin + * variable: IEEE_8021X_PIN(+) + * description: The pin secret used for EAP authentication methods. + * ---end--- + */ + obj_properties[PROP_PIN] = + g_param_spec_string(NM_SETTING_802_1X_PIN, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:pin-flags: + * + * Flags indicating how to handle the #NMSetting8021x:pin property. + **/ + /* ---ifcfg-rh--- + * property: pin-flags + * variable: IEEE_8021X_PIN_FLAGS(+) + * description: The secret flags for the pin property. + * ---end--- + */ + obj_properties[PROP_PIN_FLAGS] = g_param_spec_flags(NM_SETTING_802_1X_PIN_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:system-ca-certs: + * + * When %TRUE, overrides the #NMSetting8021x:ca-path and + * #NMSetting8021x:phase2-ca-path properties using the system CA directory + * specified at configure time with the --system-ca-path switch. The + * certificates in this directory are added to the verification chain in + * addition to any certificates specified by the #NMSetting8021x:ca-cert and + * #NMSetting8021x:phase2-ca-cert properties. If the path provided with + * --system-ca-path is rather a file name (bundle of trusted CA certificates), + * it overrides #NMSetting8021x:ca-cert and #NMSetting8021x:phase2-ca-cert + * properties instead (sets ca_cert/ca_cert2 options for wpa_supplicant). + **/ + /* ---ifcfg-rh--- + * property: system-ca-certs + * variable: IEEE_8021X_SYSTEM_CA_CERTS(+) + * description: a boolean value. + * ---end--- + */ + obj_properties[PROP_SYSTEM_CA_CERTS] = + g_param_spec_boolean(NM_SETTING_802_1X_SYSTEM_CA_CERTS, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:auth-timeout: + * + * A timeout for the authentication. Zero means the global default; if the + * global default is not set, the authentication timeout is 25 seconds. + * + * Since: 1.8 + **/ + /* ---ifcfg-rh--- + * property: auth-timeout + * variable: IEEE_8021X_AUTH_TIMEOUT(+) + * default: 0 + * description: Timeout in seconds for the 802.1X authentication. Zero means the global default or 25. + * ---end--- + */ + obj_properties[PROP_AUTH_TIMEOUT] = g_param_spec_int( + NM_SETTING_802_1X_AUTH_TIMEOUT, + "", + "", + 0, + G_MAXINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSetting8021x:optional: + * + * Whether the 802.1X authentication is optional. If %TRUE, the activation + * will continue even after a timeout or an authentication failure. Setting + * the property to %TRUE is currently allowed only for Ethernet connections. + * If set to %FALSE, the activation can continue only after a successful + * authentication. + * + * Since: 1.22 + **/ + /* ---ifcfg-rh--- + * property: optional + * variable: IEEE_8021X_OPTIONAL(+) + * default=no + * description: whether the 802.1X authentication is optional + * ---end--- + */ + obj_properties[PROP_OPTIONAL] = + g_param_spec_boolean(NM_SETTING_802_1X_OPTIONAL, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_802_1X); +} diff --git a/src/libnm-core-impl/nm-setting-adsl.c b/src/libnm-core-impl/nm-setting-adsl.c new file mode 100644 index 0000000..5b1afab --- /dev/null +++ b/src/libnm-core-impl/nm-setting-adsl.c @@ -0,0 +1,439 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2013 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-adsl.h" + +#include "nm-setting-ppp.h" +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-adsl + * @short_description: Describes ADSL-based properties + * + * The #NMSettingAdsl object is a #NMSetting subclass that describes + * properties of ADSL connections. + */ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_USERNAME, + PROP_PASSWORD, + PROP_PASSWORD_FLAGS, + PROP_PROTOCOL, + PROP_ENCAPSULATION, + PROP_VPI, + PROP_VCI, ); + +typedef struct { + char * username; + char * password; + NMSettingSecretFlags password_flags; + char * protocol; + char * encapsulation; + guint32 vpi; + guint32 vci; +} NMSettingAdslPrivate; + +G_DEFINE_TYPE(NMSettingAdsl, nm_setting_adsl, NM_TYPE_SETTING) + +#define NM_SETTING_ADSL_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_ADSL, NMSettingAdslPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_adsl_get_username: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:username property of the setting + **/ +const char * +nm_setting_adsl_get_username(NMSettingAdsl *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_ADSL(setting), NULL); + + return NM_SETTING_ADSL_GET_PRIVATE(setting)->username; +} + +/** + * nm_setting_adsl_get_password: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:password property of the setting + **/ +const char * +nm_setting_adsl_get_password(NMSettingAdsl *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_ADSL(setting), NULL); + + return NM_SETTING_ADSL_GET_PRIVATE(setting)->password; +} + +/** + * nm_setting_adsl_get_password_flags: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingAdsl:password + **/ +NMSettingSecretFlags +nm_setting_adsl_get_password_flags(NMSettingAdsl *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_ADSL(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_ADSL_GET_PRIVATE(setting)->password_flags; +} + +/** + * nm_setting_adsl_get_protocol: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:protocol property of the setting + **/ +const char * +nm_setting_adsl_get_protocol(NMSettingAdsl *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_ADSL(setting), NULL); + + return NM_SETTING_ADSL_GET_PRIVATE(setting)->protocol; +} + +/** + * nm_setting_adsl_get_encapsulation: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:encapsulation property of the setting + **/ +const char * +nm_setting_adsl_get_encapsulation(NMSettingAdsl *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_ADSL(setting), NULL); + + return NM_SETTING_ADSL_GET_PRIVATE(setting)->encapsulation; +} + +/** + * nm_setting_adsl_get_vpi: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:vpi property of the setting + **/ +guint32 +nm_setting_adsl_get_vpi(NMSettingAdsl *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_ADSL(setting), 0); + + return NM_SETTING_ADSL_GET_PRIVATE(setting)->vpi; +} + +/** + * nm_setting_adsl_get_vci: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:vci property of the setting + **/ +guint32 +nm_setting_adsl_get_vci(NMSettingAdsl *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_ADSL(setting), 0); + + return NM_SETTING_ADSL_GET_PRIVATE(setting)->vci; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingAdslPrivate *priv = NM_SETTING_ADSL_GET_PRIVATE(setting); + + if (!priv->username) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_USERNAME); + return FALSE; + } + if (!priv->username[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_USERNAME); + return FALSE; + } + + if (!NM_IN_STRSET(priv->protocol, + NM_SETTING_ADSL_PROTOCOL_PPPOA, + NM_SETTING_ADSL_PROTOCOL_PPPOE, + NM_SETTING_ADSL_PROTOCOL_IPOATM)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->protocol ?: "(null)"); + g_prefix_error(error, "%s.%s: ", NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PROTOCOL); + return FALSE; + } + + if (!NM_IN_STRSET(priv->encapsulation, + NULL, + NM_SETTING_ADSL_ENCAPSULATION_VCMUX, + NM_SETTING_ADSL_ENCAPSULATION_LLC)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->encapsulation); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_ADSL_SETTING_NAME, + NM_SETTING_ADSL_ENCAPSULATION); + return FALSE; + } + + return TRUE; +} + +static gboolean +verify_secrets(NMSetting *setting, NMConnection *connection, GError **error) +{ + return _nm_setting_verify_secret_string(NM_SETTING_ADSL_GET_PRIVATE(setting)->password, + NM_SETTING_ADSL_SETTING_NAME, + NM_SETTING_ADSL_PASSWORD, + error); +} + +static GPtrArray * +need_secrets(NMSetting *setting) +{ + NMSettingAdslPrivate *priv = NM_SETTING_ADSL_GET_PRIVATE(setting); + GPtrArray * secrets = NULL; + + if (priv->password && *priv->password) + return NULL; + + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new(1); + g_ptr_array_add(secrets, NM_SETTING_ADSL_PASSWORD); + } + + return secrets; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingAdsl *setting = NM_SETTING_ADSL(object); + + switch (prop_id) { + case PROP_USERNAME: + g_value_set_string(value, nm_setting_adsl_get_username(setting)); + break; + case PROP_PASSWORD: + g_value_set_string(value, nm_setting_adsl_get_password(setting)); + break; + case PROP_PASSWORD_FLAGS: + g_value_set_flags(value, nm_setting_adsl_get_password_flags(setting)); + break; + case PROP_PROTOCOL: + g_value_set_string(value, nm_setting_adsl_get_protocol(setting)); + break; + case PROP_ENCAPSULATION: + g_value_set_string(value, nm_setting_adsl_get_encapsulation(setting)); + break; + case PROP_VPI: + g_value_set_uint(value, nm_setting_adsl_get_vpi(setting)); + break; + case PROP_VCI: + g_value_set_uint(value, nm_setting_adsl_get_vci(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingAdslPrivate *priv = NM_SETTING_ADSL_GET_PRIVATE(object); + const char * str; + + switch (prop_id) { + case PROP_USERNAME: + g_free(priv->username); + priv->username = g_value_dup_string(value); + break; + case PROP_PASSWORD: + g_free(priv->password); + priv->password = g_value_dup_string(value); + break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_flags(value); + break; + case PROP_PROTOCOL: + g_free(priv->protocol); + str = g_value_get_string(value); + priv->protocol = str ? g_ascii_strdown(str, -1) : NULL; + break; + case PROP_ENCAPSULATION: + g_free(priv->encapsulation); + str = g_value_get_string(value); + priv->encapsulation = str ? g_ascii_strdown(str, -1) : NULL; + break; + case PROP_VPI: + priv->vpi = g_value_get_uint(value); + break; + case PROP_VCI: + priv->vci = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_adsl_init(NMSettingAdsl *setting) +{} + +/** + * nm_setting_adsl_new: + * + * Creates a new #NMSettingAdsl object with default values. + * + * Returns: the new empty #NMSettingAdsl object + **/ +NMSetting * +nm_setting_adsl_new(void) +{ + return g_object_new(NM_TYPE_SETTING_ADSL, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingAdslPrivate *priv = NM_SETTING_ADSL_GET_PRIVATE(object); + + g_free(priv->username); + g_free(priv->password); + g_free(priv->protocol); + g_free(priv->encapsulation); + + G_OBJECT_CLASS(nm_setting_adsl_parent_class)->finalize(object); +} + +static void +nm_setting_adsl_class_init(NMSettingAdslClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingAdslPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->verify_secrets = verify_secrets; + setting_class->need_secrets = need_secrets; + + /** + * NMSettingAdsl:username: + * + * Username used to authenticate with the ADSL service. + **/ + obj_properties[PROP_USERNAME] = g_param_spec_string(NM_SETTING_ADSL_USERNAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingAdsl:password: + * + * Password used to authenticate with the ADSL service. + **/ + obj_properties[PROP_PASSWORD] = + g_param_spec_string(NM_SETTING_ADSL_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingAdsl:password-flags: + * + * Flags indicating how to handle the #NMSettingAdsl:password property. + **/ + obj_properties[PROP_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_ADSL_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingAdsl:protocol: + * + * ADSL connection protocol. Can be "pppoa", "pppoe" or "ipoatm". + **/ + obj_properties[PROP_PROTOCOL] = g_param_spec_string(NM_SETTING_ADSL_PROTOCOL, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingAdsl:encapsulation: + * + * Encapsulation of ADSL connection. Can be "vcmux" or "llc". + **/ + obj_properties[PROP_ENCAPSULATION] = + g_param_spec_string(NM_SETTING_ADSL_ENCAPSULATION, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingAdsl:vpi: + * + * VPI of ADSL connection + **/ + obj_properties[PROP_VPI] = g_param_spec_uint(NM_SETTING_ADSL_VPI, + "", + "", + 0, + 65536, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingAdsl:vci: + * + * VCI of ADSL connection + **/ + obj_properties[PROP_VCI] = g_param_spec_uint(NM_SETTING_ADSL_VCI, + "", + "", + 0, + 65536, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_ADSL); +} diff --git a/src/libnm-core-impl/nm-setting-bluetooth.c b/src/libnm-core-impl/nm-setting-bluetooth.c new file mode 100644 index 0000000..18d0848 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-bluetooth.c @@ -0,0 +1,332 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-bluetooth.h" + +#include + +#include "nm-connection-private.h" +#include "nm-setting-cdma.h" +#include "nm-setting-gsm.h" +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-bluetooth + * @short_description: Describes Bluetooth connection properties + * + * The #NMSettingBluetooth object is a #NMSetting subclass that describes + * properties necessary for connection to devices that provide network + * connections via the Bluetooth Dial-Up Networking (DUN) and Network Access + * Point (NAP) profiles. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_BDADDR, PROP_TYPE, ); + +typedef struct { + char *bdaddr; + char *type; +} NMSettingBluetoothPrivate; + +G_DEFINE_TYPE(NMSettingBluetooth, nm_setting_bluetooth, NM_TYPE_SETTING) + +#define NM_SETTING_BLUETOOTH_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetoothPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_bluetooth_get_connection_type: + * @setting: the #NMSettingBluetooth + * + * Returns the connection method for communicating with the remote device (i.e. + * either DUN to a DUN-capable device or PANU to a NAP-capable device). + * + * Returns: the type, either %NM_SETTING_BLUETOOTH_TYPE_PANU, + * %NM_SETTING_BLUETOOTH_TYPE_NAP or %NM_SETTING_BLUETOOTH_TYPE_DUN + **/ +const char * +nm_setting_bluetooth_get_connection_type(NMSettingBluetooth *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BLUETOOTH(setting), NULL); + + return NM_SETTING_BLUETOOTH_GET_PRIVATE(setting)->type; +} + +/** + * nm_setting_bluetooth_get_bdaddr: + * @setting: the #NMSettingBluetooth + * + * Gets the Bluetooth address of the remote device which this setting + * describes a connection to. + * + * Returns: the Bluetooth address + **/ +const char * +nm_setting_bluetooth_get_bdaddr(NMSettingBluetooth *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BLUETOOTH(setting), NULL); + + return NM_SETTING_BLUETOOTH_GET_PRIVATE(setting)->bdaddr; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingBluetoothPrivate *priv = NM_SETTING_BLUETOOTH_GET_PRIVATE(setting); + const char * type; + gboolean missing_nap_bridge = FALSE; + + if (priv->bdaddr && !nm_utils_hwaddr_valid(priv->bdaddr, ETH_ALEN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_BDADDR); + return FALSE; + } + + type = priv->type; + if (!type) { + if (connection) { + /* We may infer the type from the (non-)existence of gsm/cdma/bridge settings. */ + type = _nm_connection_detect_bluetooth_type(connection); + } + if (!type) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_TYPE); + return FALSE; + } + } + + if (!NM_IN_STRSET(type, + NM_SETTING_BLUETOOTH_TYPE_DUN, + NM_SETTING_BLUETOOTH_TYPE_NAP, + NM_SETTING_BLUETOOTH_TYPE_PANU)) { + nm_assert(priv->type == type); + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_TYPE); + return FALSE; + } + + /* Make sure the corresponding 'type' setting is present */ + if (connection && nm_streq(type, NM_SETTING_BLUETOOTH_TYPE_DUN)) { + gboolean gsm = FALSE, cdma = FALSE; + + gsm = !!nm_connection_get_setting_gsm(connection); + cdma = !!nm_connection_get_setting_cdma(connection); + + if (!gsm && !cdma) { + /* We can't return MISSING_SETTING here, because we don't know + * whether to prefix the message with NM_SETTING_GSM_SETTING_NAME or + * NM_SETTING_CDMA_SETTING_NAME. + */ + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("'%s' connection requires '%s' or '%s' setting"), + NM_SETTING_BLUETOOTH_TYPE_DUN, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_CDMA_SETTING_NAME); + g_prefix_error(error, "%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME); + return FALSE; + } + } + /* PANU doesn't need a 'type' setting since no further configuration + * is required at the interface level. + */ + + /* NAP mode needs a bridge setting, and a bridge needs a name. */ + if (nm_streq(type, NM_SETTING_BLUETOOTH_TYPE_NAP)) { + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + if (connection && !nm_connection_get_setting_bridge(connection)) + missing_nap_bridge = TRUE; + } else { + if (!priv->bdaddr) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_BDADDR); + return FALSE; + } + } + + /* errors form here are normalizable. */ + + if (!priv->type) { + /* as determined above, we can detect the bluetooth type. */ + nm_assert(!missing_nap_bridge); + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_TYPE); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + + if (missing_nap_bridge) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("'%s' connection requires '%s' setting"), + NM_SETTING_BLUETOOTH_TYPE_NAP, + NM_SETTING_BRIDGE_SETTING_NAME); + g_prefix_error(error, "%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingBluetooth *setting = NM_SETTING_BLUETOOTH(object); + + switch (prop_id) { + case PROP_BDADDR: + g_value_set_string(value, nm_setting_bluetooth_get_bdaddr(setting)); + break; + case PROP_TYPE: + g_value_set_string(value, nm_setting_bluetooth_get_connection_type(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingBluetoothPrivate *priv = NM_SETTING_BLUETOOTH_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_BDADDR: + g_free(priv->bdaddr); + priv->bdaddr = g_value_dup_string(value); + break; + case PROP_TYPE: + g_free(priv->type); + priv->type = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_bluetooth_init(NMSettingBluetooth *setting) +{} + +/** + * nm_setting_bluetooth_new: + * + * Creates a new #NMSettingBluetooth object with default values. + * + * Returns: (transfer full): the new empty #NMSettingBluetooth object + **/ +NMSetting * +nm_setting_bluetooth_new(void) +{ + return g_object_new(NM_TYPE_SETTING_BLUETOOTH, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingBluetoothPrivate *priv = NM_SETTING_BLUETOOTH_GET_PRIVATE(object); + + g_free(priv->bdaddr); + g_free(priv->type); + + G_OBJECT_CLASS(nm_setting_bluetooth_parent_class)->finalize(object); +} + +static void +nm_setting_bluetooth_class_init(NMSettingBluetoothClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingBluetoothPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingBluetooth:bdaddr: + * + * The Bluetooth address of the device. + **/ + obj_properties[PROP_BDADDR] = g_param_spec_string( + NM_SETTING_BLUETOOTH_BDADDR, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_BDADDR], + &nm_sett_info_propert_type_mac_address); + + /** + * NMSettingBluetooth:type: + * + * Either "dun" for Dial-Up Networking connections or "panu" for Personal + * Area Networking connections to devices supporting the NAP profile. + **/ + obj_properties[PROP_TYPE] = g_param_spec_string(NM_SETTING_BLUETOOTH_TYPE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_BLUETOOTH, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-bond.c b/src/libnm-core-impl/nm-setting-bond.c new file mode 100644 index 0000000..a14ede3 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-bond.c @@ -0,0 +1,1185 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2013 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-bond.h" + +#include +#include +#include +#include + +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-connection-private.h" +#include "nm-setting-infiniband.h" +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +/** + * SECTION:nm-setting-bond + * @short_description: Describes connection properties for bonds + * + * The #NMSettingBond object is a #NMSetting subclass that describes properties + * necessary for bond connections. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingBond, PROP_OPTIONS, ); + +typedef struct { + GHashTable * options; + NMUtilsNamedValue *options_idx_cache; +} NMSettingBondPrivate; + +G_DEFINE_TYPE(NMSettingBond, nm_setting_bond, NM_TYPE_SETTING) + +#define NM_SETTING_BOND_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_BOND, NMSettingBondPrivate)) + +/*****************************************************************************/ + +static const char *const valid_options_lst[] = { + /* mode must be the first element. nm-device-bond.c relies on that. */ + NM_SETTING_BOND_OPTION_MODE, + NM_SETTING_BOND_OPTION_MIIMON, + NM_SETTING_BOND_OPTION_DOWNDELAY, + NM_SETTING_BOND_OPTION_UPDELAY, + NM_SETTING_BOND_OPTION_ARP_INTERVAL, + NM_SETTING_BOND_OPTION_ARP_IP_TARGET, + NM_SETTING_BOND_OPTION_ARP_VALIDATE, + NM_SETTING_BOND_OPTION_PRIMARY, + NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, + NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, + NM_SETTING_BOND_OPTION_USE_CARRIER, + NM_SETTING_BOND_OPTION_AD_SELECT, + NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, + NM_SETTING_BOND_OPTION_RESEND_IGMP, + NM_SETTING_BOND_OPTION_LACP_RATE, + NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, + NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, + NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, + NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, + NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, + NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS, + NM_SETTING_BOND_OPTION_MIN_LINKS, + NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, + NM_SETTING_BOND_OPTION_NUM_UNSOL_NA, + NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, + NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB, + NM_SETTING_BOND_OPTION_LP_INTERVAL, + NULL, +}; + +typedef struct { + const char * val; + NMBondOptionType opt_type; + guint min; + guint max; + const char *const *list; +} OptionMeta; + +static gboolean +_nm_assert_bond_meta(const OptionMeta *option_meta) +{ + nm_assert(option_meta); + + switch (option_meta->opt_type) { + case NM_BOND_OPTION_TYPE_BOTH: + nm_assert(option_meta->val); + nm_assert(option_meta->list); + nm_assert(option_meta->list[0]); + nm_assert(option_meta->min == 0); + nm_assert(option_meta->max == NM_PTRARRAY_LEN(option_meta->list) - 1); + nm_assert(g_strv_contains(option_meta->list, option_meta->val)); + return TRUE; + case NM_BOND_OPTION_TYPE_INT: + nm_assert(option_meta->val); + nm_assert(!option_meta->list); + nm_assert(option_meta->min < option_meta->max); + nm_assert(NM_STRCHAR_ALL(option_meta->val, ch, g_ascii_isdigit(ch))); + nm_assert(NM_STRCHAR_ALL(option_meta->val, ch, g_ascii_isdigit(ch))); + nm_assert(({ + _nm_utils_ascii_str_to_uint64(option_meta->val, + 10, + option_meta->min, + option_meta->max, + 0); + errno == 0; + })); + return TRUE; + case NM_BOND_OPTION_TYPE_IP: + nm_assert(option_meta->val); + /* fall-through */ + case NM_BOND_OPTION_TYPE_IFNAME: + case NM_BOND_OPTION_TYPE_MAC: + nm_assert(!option_meta->list); + nm_assert(option_meta->min == 0); + nm_assert(option_meta->max == 0); + return TRUE; + } + + nm_assert_not_reached(); + return FALSE; +} + +static char const *const _option_default_strv_ad_select[] = + NM_MAKE_STRV("stable", "bandwidth", "count"); +static char const *const _option_default_strv_arp_all_targets[] = NM_MAKE_STRV("any", "all"); +static char const *const _option_default_strv_arp_validate[] = + NM_MAKE_STRV("none", "active", "backup", "all", "filter", "filter_active", "filter_backup"); +static char const *const _option_default_strv_fail_over_mac[] = + NM_MAKE_STRV("none", "active", "follow"); +static char const *const _option_default_strv_lacp_rate[] = NM_MAKE_STRV("slow", "fast"); +static char const *const _option_default_strv_mode[] = NM_MAKE_STRV("balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb"); +static char const *const _option_default_strv_primary_reselect[] = + NM_MAKE_STRV("always", "better", "failure"); +static char const *const _option_default_strv_xmit_hash_policy[] = + NM_MAKE_STRV("layer2", "layer3+4", "layer2+3", "encap2+3", "encap3+4", "vlan+srcmac"); + +static NM_UTILS_STRING_TABLE_LOOKUP_STRUCT_DEFINE( + _get_option_meta, + OptionMeta, + { + G_STATIC_ASSERT_EXPR(G_N_ELEMENTS(LIST) == G_N_ELEMENTS(valid_options_lst) - 1); + + if (NM_MORE_ASSERT_ONCE(5)) { + int i; + + nm_assert(G_N_ELEMENTS(LIST) == NM_PTRARRAY_LEN(valid_options_lst)); + for (i = 0; i < G_N_ELEMENTS(LIST); i++) + _nm_assert_bond_meta(&LIST[i].value); + nm_assert(nm_streq(valid_options_lst[0], NM_SETTING_BOND_OPTION_MODE)); + } + }, + { return NULL; }, + {NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, {NULL, NM_BOND_OPTION_TYPE_IFNAME}}, + {NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, {"65535", NM_BOND_OPTION_TYPE_INT, 1, 65535}}, + {NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, {NULL, NM_BOND_OPTION_TYPE_MAC}}, + {NM_SETTING_BOND_OPTION_AD_SELECT, + {"stable", NM_BOND_OPTION_TYPE_BOTH, 0, 2, _option_default_strv_ad_select}}, + {NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, {"0", NM_BOND_OPTION_TYPE_INT, 0, 1023}}, + {NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, {"0", NM_BOND_OPTION_TYPE_INT, 0, 1}}, + {NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS, + {"any", NM_BOND_OPTION_TYPE_BOTH, 0, 1, _option_default_strv_arp_all_targets}}, + {NM_SETTING_BOND_OPTION_ARP_INTERVAL, {"0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}}, + {NM_SETTING_BOND_OPTION_ARP_IP_TARGET, {"", NM_BOND_OPTION_TYPE_IP}}, + {NM_SETTING_BOND_OPTION_ARP_VALIDATE, + {"none", NM_BOND_OPTION_TYPE_BOTH, 0, 6, _option_default_strv_arp_validate}}, + {NM_SETTING_BOND_OPTION_DOWNDELAY, {"0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}}, + {NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, + {"none", NM_BOND_OPTION_TYPE_BOTH, 0, 2, _option_default_strv_fail_over_mac}}, + {NM_SETTING_BOND_OPTION_LACP_RATE, + {"slow", NM_BOND_OPTION_TYPE_BOTH, 0, 1, _option_default_strv_lacp_rate}}, + {NM_SETTING_BOND_OPTION_LP_INTERVAL, {"1", NM_BOND_OPTION_TYPE_INT, 1, G_MAXINT}}, + {NM_SETTING_BOND_OPTION_MIIMON, {"100", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}}, + {NM_SETTING_BOND_OPTION_MIN_LINKS, {"0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}}, + {NM_SETTING_BOND_OPTION_MODE, + {"balance-rr", NM_BOND_OPTION_TYPE_BOTH, 0, 6, _option_default_strv_mode}}, + {NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, {"1", NM_BOND_OPTION_TYPE_INT, 0, 255}}, + {NM_SETTING_BOND_OPTION_NUM_UNSOL_NA, {"1", NM_BOND_OPTION_TYPE_INT, 0, 255}}, + {NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, {"1", NM_BOND_OPTION_TYPE_INT, 0, 65535}}, + {NM_SETTING_BOND_OPTION_PRIMARY, {"", NM_BOND_OPTION_TYPE_IFNAME}}, + {NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, + {"always", NM_BOND_OPTION_TYPE_BOTH, 0, 2, _option_default_strv_primary_reselect}}, + {NM_SETTING_BOND_OPTION_RESEND_IGMP, {"1", NM_BOND_OPTION_TYPE_INT, 0, 255}}, + {NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB, {"1", NM_BOND_OPTION_TYPE_INT, 0, 1}}, + {NM_SETTING_BOND_OPTION_UPDELAY, {"0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}}, + {NM_SETTING_BOND_OPTION_USE_CARRIER, {"1", NM_BOND_OPTION_TYPE_INT, 0, 1}}, + {NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, + {"layer2", NM_BOND_OPTION_TYPE_BOTH, 0, 5, _option_default_strv_xmit_hash_policy}}, ); + +/*****************************************************************************/ + +#define BIT(x) (((guint32) 1) << (x)) + +static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( + _bond_option_unsupp_mode, + guint32, + { ; }, + { return 0; }, + {NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, + ~(BIT(NM_BOND_MODE_ACTIVEBACKUP) | BIT(NM_BOND_MODE_TLB) | BIT(NM_BOND_MODE_ALB))}, + {NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, ~(BIT(NM_BOND_MODE_8023AD))}, + {NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, ~(BIT(NM_BOND_MODE_8023AD))}, + {NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, ~(BIT(NM_BOND_MODE_8023AD))}, + {NM_SETTING_BOND_OPTION_ARP_INTERVAL, + (BIT(NM_BOND_MODE_8023AD) | BIT(NM_BOND_MODE_TLB) | BIT(NM_BOND_MODE_ALB))}, + {NM_SETTING_BOND_OPTION_ARP_IP_TARGET, + (BIT(NM_BOND_MODE_8023AD) | BIT(NM_BOND_MODE_TLB) | BIT(NM_BOND_MODE_ALB))}, + {NM_SETTING_BOND_OPTION_ARP_VALIDATE, + (BIT(NM_BOND_MODE_8023AD) | BIT(NM_BOND_MODE_TLB) | BIT(NM_BOND_MODE_ALB))}, + {NM_SETTING_BOND_OPTION_LACP_RATE, ~(BIT(NM_BOND_MODE_8023AD))}, + {NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, ~(BIT(NM_BOND_MODE_ROUNDROBIN))}, + {NM_SETTING_BOND_OPTION_PRIMARY, + ~(BIT(NM_BOND_MODE_ACTIVEBACKUP) | BIT(NM_BOND_MODE_TLB) | BIT(NM_BOND_MODE_ALB))}, + {NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB, ~(BIT(NM_BOND_MODE_TLB))}, ); + +gboolean +_nm_setting_bond_option_supported(const char *option, NMBondMode mode) +{ + nm_assert(option); + nm_assert(mode != NM_BOND_MODE_UNKNOWN); + nm_assert(_NM_INT_NOT_NEGATIVE(mode) && mode < 32); + + return !NM_FLAGS_ANY(_bond_option_unsupp_mode(option), BIT(mode)); +} + +static const char * +_bond_get_option(NMSettingBond *self, const char *option) +{ + g_return_val_if_fail(NM_IS_SETTING_BOND(self), NULL); + g_return_val_if_fail(option, NULL); + + return g_hash_table_lookup(NM_SETTING_BOND_GET_PRIVATE(self)->options, option); +} + +static const char * +_bond_get_option_default(NMSettingBond *self, const char *option) +{ + const OptionMeta *option_meta; + + g_return_val_if_fail(NM_IS_SETTING_BOND(self), NULL); + + option_meta = _get_option_meta(option); + + g_return_val_if_fail(option_meta, NULL); + + return option_meta->val; +} + +static const char * +_bond_get_option_or_default(NMSettingBond *self, const char *option) +{ + return _bond_get_option(self, option) ?: _bond_get_option_default(self, option); +} + +static const char * +_bond_get_option_normalized(NMSettingBond *self, const char *option, gboolean get_default_only) +{ + const char *mode_str; + NMBondMode mode; + const char *value = NULL; + + g_return_val_if_fail(NM_IS_SETTING_BOND(self), NULL); + g_return_val_if_fail(option, NULL); + + mode_str = _bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_MODE); + mode = _nm_setting_bond_mode_from_string(mode_str); + + if (mode == NM_BOND_MODE_UNKNOWN) { + /* the mode is unknown, consequently, there is no normalized/default + * value either. */ + return NULL; + } + + if (!_nm_setting_bond_option_supported(option, mode)) + return NULL; + + /* Apply custom NetworkManager policies here */ + if (!get_default_only) { + if (NM_IN_STRSET(option, + NM_SETTING_BOND_OPTION_ARP_INTERVAL, + NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) { + int miimon; + + /* if arp_interval is explicitly set and miimon is not, then disable miimon + * (and related updelay and downdelay) as recommended by the kernel docs */ + miimon = + _nm_utils_ascii_str_to_int64(_bond_get_option(self, NM_SETTING_BOND_OPTION_MIIMON), + 10, + 0, + G_MAXINT, + 0); + if (miimon != 0) { + /* miimon is enabled. arp_interval values are unset. */ + if (nm_streq(option, NM_SETTING_BOND_OPTION_ARP_INTERVAL)) + return "0"; + return ""; + } + value = _bond_get_option(self, option); + } else if (NM_IN_STRSET(option, + NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, + NM_SETTING_BOND_OPTION_NUM_UNSOL_NA)) { + /* just get one of the 2, at kernel level they're the same bond option */ + value = _bond_get_option(self, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP); + if (!value) + value = _bond_get_option(self, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA); + } else if (NM_IN_STRSET(option, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE)) { + /* "active_slave" is deprecated, and an alias for "primary". The property + * itself always normalizes to %NULL. */ + value = NULL; + } else if (NM_IN_STRSET(option, NM_SETTING_BOND_OPTION_PRIMARY)) { + /* "active_slave" is deprecated, and an alias for "primary". */ + value = _bond_get_option(self, NM_SETTING_BOND_OPTION_PRIMARY); + if (!value) + value = _bond_get_option(self, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE); + } else + value = _bond_get_option(self, option); + + if (value) + return value; + } + + /* Apply rules that change the default value of an option */ + if (nm_streq(option, NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM)) { + /* The default value depends on the current mode */ + if (mode == NM_BOND_MODE_8023AD) + return NM_BOND_AD_ACTOR_SYSTEM_DEFAULT; + return ""; + } + + return _bond_get_option_or_default(self, option); +} + +const char * +nm_setting_bond_get_option_or_default(NMSettingBond *self, const char *option) +{ + g_return_val_if_fail(NM_IS_SETTING_BOND(self), NULL); + g_return_val_if_fail(option, NULL); + + return _bond_get_option_normalized(self, option, FALSE); +} + +static int +_atoi(const char *value) +{ + int v; + + v = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXINT, -1); + nm_assert(v >= 0); + return v; +}; + +/** + * nm_setting_bond_get_num_options: + * @setting: the #NMSettingBond + * + * Returns the number of options that should be set for this bond when it + * is activated. This can be used to retrieve each option individually + * using nm_setting_bond_get_option(). + * + * Returns: the number of bonding options + **/ +guint32 +nm_setting_bond_get_num_options(NMSettingBond *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BOND(setting), 0); + + return g_hash_table_size(NM_SETTING_BOND_GET_PRIVATE(setting)->options); +} + +static int +_get_option_sort(gconstpointer p_a, gconstpointer p_b, gpointer _unused) +{ + const char *a = *((const char *const *) p_a); + const char *b = *((const char *const *) p_b); + + NM_CMP_DIRECT(nm_streq(b, NM_SETTING_BOND_OPTION_MODE), + nm_streq(a, NM_SETTING_BOND_OPTION_MODE)); + NM_CMP_DIRECT_STRCMP(a, b); + nm_assert_not_reached(); + return 0; +} + +static void +_ensure_options_idx_cache(NMSettingBondPrivate *priv) +{ + if (!G_UNLIKELY(priv->options_idx_cache)) + priv->options_idx_cache = nm_utils_named_values_from_strdict_full(priv->options, + NULL, + _get_option_sort, + NULL, + NULL, + 0, + NULL); +} + +/** + * nm_setting_bond_get_option: + * @setting: the #NMSettingBond + * @idx: index of the desired option, from 0 to + * nm_setting_bond_get_num_options() - 1 + * @out_name: (out) (transfer none): on return, the name of the bonding option; + * this value is owned by the setting and should not be modified + * @out_value: (out) (transfer none): on return, the value of the name of the + * bonding option; this value is owned by the setting and should not be + * modified + * + * Given an index, return the value of the bonding option at that index. Indexes + * are *not* guaranteed to be static across modifications to options done by + * nm_setting_bond_add_option() and nm_setting_bond_remove_option(), + * and should not be used to refer to options except for short periods of time + * such as during option iteration. + * + * Returns: %TRUE on success if the index was valid and an option was found, + * %FALSE if the index was invalid (ie, greater than the number of options + * currently held by the setting) + **/ +gboolean +nm_setting_bond_get_option(NMSettingBond *setting, + guint32 idx, + const char ** out_name, + const char ** out_value) +{ + NMSettingBondPrivate *priv; + guint len; + + g_return_val_if_fail(NM_IS_SETTING_BOND(setting), FALSE); + + priv = NM_SETTING_BOND_GET_PRIVATE(setting); + + len = g_hash_table_size(priv->options); + if (idx >= len) + return FALSE; + + _ensure_options_idx_cache(priv); + + NM_SET_OUT(out_name, priv->options_idx_cache[idx].name); + NM_SET_OUT(out_value, priv->options_idx_cache[idx].value_str); + return TRUE; +} + +static gboolean +validate_int(const char *name, const char *value, const OptionMeta *option_meta) +{ + guint64 num; + + if (!NM_STRCHAR_ALL(value, ch, g_ascii_isdigit(ch))) + return FALSE; + + num = _nm_utils_ascii_str_to_uint64(value, 10, option_meta->min, option_meta->max, G_MAXUINT64); + if (num == G_MAXUINT64 && errno != 0) + return FALSE; + + return TRUE; +} + +static gboolean +validate_list(const char *name, const char *value, const OptionMeta *option_meta) +{ + int i; + + nm_assert(option_meta->list); + + for (i = 0; option_meta->list[i]; i++) { + if (nm_streq(option_meta->list[i], value)) + return TRUE; + } + return FALSE; +} + +static gboolean +validate_ip(const char *name, const char *value, GError **error) +{ + gs_free const char **addrs = NULL; + gsize i; + + addrs = nm_utils_bond_option_arp_ip_targets_split(value); + if (!addrs) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option is empty"), + name); + return FALSE; + } + for (i = 0; addrs[i]; i++) { + if (!nm_utils_parse_inaddr_bin(AF_INET, addrs[i], NULL, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IPv4 address for '%s' option"), + addrs[i], + name); + return FALSE; + } + } + return TRUE; +} + +static gboolean +validate_ifname(const char *name, const char *value) +{ + return nm_utils_ifname_valid_kernel(value, NULL); +} + +gboolean +_nm_setting_bond_validate_option(const char *name, const char *value, GError **error) +{ + const OptionMeta *option_meta; + gboolean success; + + option_meta = _get_option_meta(name); + if (!option_meta) { + if (!name) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("missing option name")); + } else { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid option '%s'"), + name); + } + return FALSE; + } + + if (!value) + return TRUE; + + switch (option_meta->opt_type) { + case NM_BOND_OPTION_TYPE_INT: + success = validate_int(name, value, option_meta); + goto handle_error; + case NM_BOND_OPTION_TYPE_BOTH: + success = + (validate_int(name, value, option_meta) || validate_list(name, value, option_meta)); + goto handle_error; + case NM_BOND_OPTION_TYPE_IP: + nm_assert(nm_streq0(name, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)); + return validate_ip(name, value, error); + case NM_BOND_OPTION_TYPE_MAC: + success = nm_utils_hwaddr_valid(value, ETH_ALEN); + goto handle_error; + case NM_BOND_OPTION_TYPE_IFNAME: + success = validate_ifname(name, value); + goto handle_error; + } + + nm_assert_not_reached(); + success = FALSE; + +handle_error: + if (!success) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid value '%s' for option '%s'"), + value, + name); + } + return success; +} + +/** + * nm_setting_bond_validate_option: + * @name: the name of the option to validate + * @value (allow-none): the value of the option to validate. + * + * Checks whether @name is a valid bond option and @value is a valid value for + * the @name. If @value is %NULL, the function only validates the option name. + * + * Returns: %TRUE, if the @value is valid for the given name. + * If the @name is not a valid option, %FALSE will be returned. + **/ +gboolean +nm_setting_bond_validate_option(const char *name, const char *value) +{ + return _nm_setting_bond_validate_option(name, value, NULL); +} + +/** + * nm_setting_bond_get_option_by_name: + * @setting: the #NMSettingBond + * @name: the option name for which to retrieve the value + * + * Returns the value associated with the bonding option specified by + * @name, if it exists. + * + * Returns: the value, or %NULL if the key/value pair was never added to the + * setting; the value is owned by the setting and must not be modified + **/ +const char * +nm_setting_bond_get_option_by_name(NMSettingBond *setting, const char *name) +{ + g_return_val_if_fail(NM_IS_SETTING_BOND(setting), NULL); + + return _bond_get_option(setting, name); +} + +/** + * nm_setting_bond_add_option: + * @setting: the #NMSettingBond + * @name: name for the option + * @value: value for the option + * + * Add an option to the table. Adding a new name replaces any existing name/value pair + * that may already exist. + * + * Returns: returns %FALSE if either @name or @value is %NULL, in that case + * the option is not set. Otherwise, the function does not fail and does not validate + * the arguments. All validation happens via nm_connection_verify() or do basic validation + * yourself with nm_setting_bond_validate_option(). + * + * Note: Before 1.30, libnm would perform basic validation of the name and the value + * via nm_setting_bond_validate_option() and reject the request by returning FALSE. + * Since 1.30, libnm no longer rejects any values as the setter is not supposed + * to perform validation. + **/ +gboolean +nm_setting_bond_add_option(NMSettingBond *setting, const char *name, const char *value) +{ + NMSettingBondPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_BOND(setting), FALSE); + + if (!name) + return FALSE; + if (!value) + return FALSE; + + priv = NM_SETTING_BOND_GET_PRIVATE(setting); + + nm_clear_g_free(&priv->options_idx_cache); + g_hash_table_insert(priv->options, g_strdup(name), g_strdup(value)); + _notify(setting, PROP_OPTIONS); + return TRUE; +} + +/** + * nm_setting_bond_remove_option: + * @setting: the #NMSettingBond + * @name: name of the option to remove + * + * Remove the bonding option referenced by @name from the internal option + * list. + * + * Returns: %TRUE if the option was found and removed from the internal option + * list, %FALSE if it was not. + **/ +gboolean +nm_setting_bond_remove_option(NMSettingBond *setting, const char *name) +{ + NMSettingBondPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_BOND(setting), FALSE); + + priv = NM_SETTING_BOND_GET_PRIVATE(setting); + + if (!g_hash_table_remove(priv->options, name)) + return FALSE; + + nm_clear_g_free(&priv->options_idx_cache); + _notify(setting, PROP_OPTIONS); + return TRUE; +} + +/** + * nm_setting_bond_get_valid_options: + * @setting: (allow-none): the #NMSettingBond + * + * Returns a list of valid bond options. + * + * The @setting argument is unused and may be passed as %NULL. + * + * Returns: (transfer none): a %NULL-terminated array of strings of valid bond options. + **/ +const char ** +nm_setting_bond_get_valid_options(NMSettingBond *setting) +{ + return (const char **) valid_options_lst; +} + +/** + * nm_setting_bond_get_option_default: + * @setting: the #NMSettingBond + * @name: the name of the option + * + * Returns: the value of the bond option if not overridden by an entry in + * the #NMSettingBond:options property. + **/ +const char * +nm_setting_bond_get_option_default(NMSettingBond *setting, const char *name) +{ + g_return_val_if_fail(NM_IS_SETTING_BOND(setting), NULL); + + if (!name) + return NULL; + + return _bond_get_option_normalized(setting, name, TRUE); +} + +/** + * nm_setting_bond_get_option_normalized: + * @setting: the #NMSettingBond + * @name: the name of the option + * + * Since: 1.24 + * + * Returns: the value of the bond option after normalization, which is what NetworkManager + * will actually apply when activating the connection. %NULL if the option won't be applied + * to the connection. + **/ +const char * +nm_setting_bond_get_option_normalized(NMSettingBond *setting, const char *name) +{ + g_return_val_if_fail(NM_IS_SETTING_BOND(setting), NULL); + g_return_val_if_fail(name, NULL); + + return _bond_get_option_normalized(setting, name, FALSE); +} + +/** + * nm_setting_bond_get_option_type: + * @setting: the #NMSettingBond + * @name: the name of the option + * + * Returns: the type of the bond option. + **/ +NMBondOptionType +_nm_setting_bond_get_option_type(NMSettingBond *setting, const char *name) +{ + const OptionMeta *option_meta; + + g_return_val_if_fail(NM_IS_SETTING_BOND(setting), NM_BOND_OPTION_TYPE_INT); + + option_meta = _get_option_meta(name); + + g_return_val_if_fail(option_meta, NM_BOND_OPTION_TYPE_INT); + + return option_meta->opt_type; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingBond * self = NM_SETTING_BOND(setting); + NMSettingBondPrivate * priv = NM_SETTING_BOND_GET_PRIVATE(setting); + int miimon; + int arp_interval; + int num_grat_arp; + int num_unsol_na; + const char * mode_str; + const char * arp_ip_target = NULL; + const char * lacp_rate; + const char * primary; + NMBondMode bond_mode; + guint i; + const NMUtilsNamedValue *n; + + _ensure_options_idx_cache(priv); + + if (priv->options_idx_cache) { + for (i = 0; priv->options_idx_cache[i].name; i++) { + n = &priv->options_idx_cache[i]; + + if (!n->value_str || !_nm_setting_bond_validate_option(n->name, n->value_str, error)) { + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BOND_SETTING_NAME, + NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + } + + miimon = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_MIIMON)); + arp_interval = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_ARP_INTERVAL)); + num_grat_arp = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP)); + num_unsol_na = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA)); + + /* Option restrictions: + * + * arp_interval conflicts [ alb, tlb ] + * arp_interval needs arp_ip_target + * arp_validate does not work with [ BOND_MODE_8023AD, BOND_MODE_TLB, BOND_MODE_ALB ] + * downdelay needs miimon + * updelay needs miimon + * primary needs [ active-backup, tlb, alb ] + */ + + /* Verify bond mode */ + mode_str = _bond_get_option(self, NM_SETTING_BOND_OPTION_MODE); + if (!mode_str) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("mandatory option '%s' is missing"), + NM_SETTING_BOND_OPTION_MODE); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + bond_mode = _nm_setting_bond_mode_from_string(mode_str); + if (bond_mode == NM_BOND_MODE_UNKNOWN) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for '%s'"), + mode_str, + NM_SETTING_BOND_OPTION_MODE); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + + /* Make sure mode is compatible with other settings */ + if (NM_IN_SET(bond_mode, NM_BOND_MODE_TLB, NM_BOND_MODE_ALB)) { + if (arp_interval > 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s=%s' is incompatible with '%s > 0'"), + NM_SETTING_BOND_OPTION_MODE, + mode_str, + NM_SETTING_BOND_OPTION_ARP_INTERVAL); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + + primary = _bond_get_option(self, NM_SETTING_BOND_OPTION_PRIMARY); + if (NM_IN_SET(bond_mode, NM_BOND_MODE_ACTIVEBACKUP, NM_BOND_MODE_TLB, NM_BOND_MODE_ALB)) { + GError *tmp_error = NULL; + + if (primary && !nm_utils_ifname_valid_kernel(primary, &tmp_error)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not valid for the '%s' option: %s"), + primary, + NM_SETTING_BOND_OPTION_PRIMARY, + tmp_error->message); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + g_error_free(tmp_error); + return FALSE; + } + } else if (primary) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option is only valid for '%s=%s'"), + NM_SETTING_BOND_OPTION_PRIMARY, + NM_SETTING_BOND_OPTION_MODE, + "active-backup"); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + + if (connection && nm_connection_get_setting_infiniband(connection)) { + if (bond_mode != NM_BOND_MODE_ACTIVEBACKUP) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s=%s' is not a valid configuration for '%s'"), + NM_SETTING_BOND_OPTION_MODE, + mode_str, + NM_SETTING_INFINIBAND_SETTING_NAME); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + + if (miimon == 0) { + /* updelay and downdelay need miimon to be enabled to be valid */ + if (_atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_UPDELAY))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option requires '%s' option to be enabled"), + NM_SETTING_BOND_OPTION_UPDELAY, + NM_SETTING_BOND_OPTION_MIIMON); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + + if (_atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_DOWNDELAY))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option requires '%s' option to be enabled"), + NM_SETTING_BOND_OPTION_DOWNDELAY, + NM_SETTING_BOND_OPTION_MIIMON); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + + /* arp_ip_target can only be used with arp_interval, and must + * contain a comma-separated list of IPv4 addresses. + */ + arp_ip_target = _bond_get_option(self, NM_SETTING_BOND_OPTION_ARP_IP_TARGET); + if (arp_interval > 0) { + if (!arp_ip_target) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option requires '%s' option to be set"), + NM_SETTING_BOND_OPTION_ARP_INTERVAL, + NM_SETTING_BOND_OPTION_ARP_IP_TARGET); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } else { + if (arp_ip_target) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option requires '%s' option to be set"), + NM_SETTING_BOND_OPTION_ARP_IP_TARGET, + NM_SETTING_BOND_OPTION_ARP_INTERVAL); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + + lacp_rate = _bond_get_option(self, NM_SETTING_BOND_OPTION_LACP_RATE); + if (lacp_rate && bond_mode != NM_BOND_MODE_8023AD && !NM_IN_STRSET(lacp_rate, "0", "slow")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option is only valid with mode '%s'"), + NM_SETTING_BOND_OPTION_LACP_RATE, + "802.3ad"); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + + if (_bond_get_option(self, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP) + && _bond_get_option(self, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA) + && num_grat_arp != num_unsol_na) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' and '%s' cannot have different values"), + NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, + NM_SETTING_BOND_OPTION_NUM_UNSOL_NA); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */ + + if (!NM_IN_STRSET(mode_str, + "802.3ad", + "active-backup", + "balance-rr", + "balance-alb", + "balance-tlb", + "balance-xor", + "broadcast")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option should be string"), + NM_SETTING_BOND_OPTION_MODE); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + + /* normalize unsupported options for the current mode */ + for (i = 0; priv->options_idx_cache[i].name; i++) { + n = &priv->options_idx_cache[i]; + if (!_nm_setting_bond_option_supported(n->name, bond_mode)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option is not valid with mode '%s'"), + n->name, + mode_str); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + } + + return TRUE; +} + +/*****************************************************************************/ + +static gboolean +options_equal_asym(NMSettingBond *s_bond, NMSettingBond *s_bond2, NMSettingCompareFlags flags) +{ + GHashTableIter iter; + const char * key, *value; + + g_hash_table_iter_init(&iter, NM_SETTING_BOND_GET_PRIVATE(s_bond)->options); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) { + /* when doing an inferrable match, the active-slave should be ignored + * as it might be differ from the setting in the connection. + * + * Also, the fail_over_mac setting can change, see for example + * https://bugzilla.redhat.com/show_bug.cgi?id=1375558#c8 */ + if (NM_IN_STRSET(key, "fail_over_mac", "active_slave")) + continue; + } + + if (!nm_streq0(value, _bond_get_option(s_bond2, key))) + return FALSE; + } + + return TRUE; +} + +static gboolean +options_equal(NMSettingBond *s_bond, NMSettingBond *s_bond2, NMSettingCompareFlags flags) +{ + return options_equal_asym(s_bond, s_bond2, flags) && options_equal_asym(s_bond2, s_bond, flags); +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_BOND_OPTIONS)) { + return (!set_b || options_equal(NM_SETTING_BOND(set_a), NM_SETTING_BOND(set_b), flags)); + } + + return NM_SETTING_CLASS(nm_setting_bond_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_OPTIONS: + g_value_take_boxed(value, _nm_utils_copy_strdict(priv->options)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_OPTIONS: + nm_clear_g_free(&priv->options_idx_cache); + g_hash_table_unref(priv->options); + priv->options = _nm_utils_copy_strdict(g_value_get_boxed(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_bond_init(NMSettingBond *setting) +{ + NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE(setting); + + priv->options = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + + /* Default values: */ + nm_setting_bond_add_option(setting, NM_SETTING_BOND_OPTION_MODE, "balance-rr"); +} + +/** + * nm_setting_bond_new: + * + * Creates a new #NMSettingBond object with default values. + * + * Returns: (transfer full): the new empty #NMSettingBond object + **/ +NMSetting * +nm_setting_bond_new(void) +{ + return g_object_new(NM_TYPE_SETTING_BOND, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE(object); + + nm_clear_g_free(&priv->options_idx_cache); + g_hash_table_destroy(priv->options); + + G_OBJECT_CLASS(nm_setting_bond_parent_class)->finalize(object); +} + +static void +nm_setting_bond_class_init(NMSettingBondClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingBondPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->compare_property = compare_property; + + /** + * NMSettingBond:options: (type GHashTable(utf8,utf8)): + * + * Dictionary of key/value pairs of bonding options. Both keys and values + * must be strings. Option names must contain only alphanumeric characters + * (ie, [a-zA-Z0-9]). + **/ + /* ---ifcfg-rh--- + * property: options + * variable: BONDING_OPTS + * description: Bonding options. + * example: BONDING_OPTS="miimon=100 mode=broadcast" + * ---end--- + */ + obj_properties[PROP_OPTIONS] = g_param_spec_boxed( + NM_SETTING_BOND_OPTIONS, + "", + "", + G_TYPE_HASH_TABLE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_OPTIONS], + &nm_sett_info_propert_type_strdict); + + /* ---dbus--- + * property: interface-name + * format: string + * description: Deprecated in favor of connection.interface-name, but can + * be used for backward-compatibility with older daemons, to set the + * bond's interface name. + * ---end--- + */ + _nm_properties_override_dbus(properties_override, + "interface-name", + &nm_sett_info_propert_type_deprecated_interface_name); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_BOND, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-bridge-port.c b/src/libnm-core-impl/nm-setting-bridge-port.c new file mode 100644 index 0000000..9d1ff25 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-bridge-port.c @@ -0,0 +1,589 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 - 2013 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-bridge-port.h" + +#include +#include + +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-bridge.h" + +/** + * SECTION:nm-setting-bridge-port + * @short_description: Describes connection properties for bridge ports + * + * The #NMSettingBridgePort object is a #NMSetting subclass that describes + * optional properties that apply to bridge ports. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingBridgePort, + PROP_PRIORITY, + PROP_PATH_COST, + PROP_HAIRPIN_MODE, + PROP_VLANS, ); + +typedef struct { + GPtrArray *vlans; + guint16 priority; + guint16 path_cost; + bool hairpin_mode : 1; +} NMSettingBridgePortPrivate; + +G_DEFINE_TYPE(NMSettingBridgePort, nm_setting_bridge_port, NM_TYPE_SETTING) + +#define NM_SETTING_BRIDGE_PORT_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePortPrivate)) + +static int +vlan_ptr_cmp(gconstpointer a, gconstpointer b) +{ + const NMBridgeVlan *vlan_a = *(const NMBridgeVlan **) a; + const NMBridgeVlan *vlan_b = *(const NMBridgeVlan **) b; + + return nm_bridge_vlan_cmp(vlan_a, vlan_b); +} + +gboolean +_nm_setting_bridge_port_sort_vlans(NMSettingBridgePort *setting) +{ + NMSettingBridgePortPrivate *priv; + gboolean need_sort = FALSE; + guint i; + + priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting); + + for (i = 1; i < priv->vlans->len; i++) { + NMBridgeVlan *vlan_prev = priv->vlans->pdata[i - 1]; + NMBridgeVlan *vlan = priv->vlans->pdata[i]; + + if (nm_bridge_vlan_cmp(vlan_prev, vlan) > 0) { + need_sort = TRUE; + break; + } + } + + if (need_sort) { + g_ptr_array_sort(priv->vlans, vlan_ptr_cmp); + _notify(setting, PROP_VLANS); + } + + return need_sort; +} + +/*****************************************************************************/ + +/** + * nm_setting_bridge_port_get_priority: + * @setting: the #NMSettingBridgePort + * + * Returns: the #NMSettingBridgePort:priority property of the setting + **/ +guint16 +nm_setting_bridge_port_get_priority(NMSettingBridgePort *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE_PORT(setting), 0); + + return NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting)->priority; +} + +/** + * nm_setting_bridge_port_get_path_cost: + * @setting: the #NMSettingBridgePort + * + * Returns: the #NMSettingBridgePort:path-cost property of the setting + **/ +guint16 +nm_setting_bridge_port_get_path_cost(NMSettingBridgePort *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE_PORT(setting), 0); + + return NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting)->path_cost; +} + +/** + * nm_setting_bridge_port_get_hairpin_mode: + * @setting: the #NMSettingBridgePort + * + * Returns: the #NMSettingBridgePort:hairpin-mode property of the setting + **/ +gboolean +nm_setting_bridge_port_get_hairpin_mode(NMSettingBridgePort *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE_PORT(setting), FALSE); + + return NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting)->hairpin_mode; +} + +/** + * nm_setting_bridge_port_add_vlan: + * @setting: the #NMSettingBridgePort + * @vlan: the vlan to add + * + * Appends a new vlan and associated information to the setting. The + * given vlan gets sealed and a reference to it is added. + * + * Since: 1.18 + **/ +void +nm_setting_bridge_port_add_vlan(NMSettingBridgePort *setting, NMBridgeVlan *vlan) +{ + NMSettingBridgePortPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_BRIDGE_PORT(setting)); + g_return_if_fail(vlan); + + priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting); + + nm_bridge_vlan_seal(vlan); + nm_bridge_vlan_ref(vlan); + + g_ptr_array_add(priv->vlans, vlan); + _notify(setting, PROP_VLANS); +} + +/** + * nm_setting_bridge_port_get_num_vlans: + * @setting: the #NMSettingBridgePort + * + * Returns: the number of VLANs + * + * Since: 1.18 + **/ +guint +nm_setting_bridge_port_get_num_vlans(NMSettingBridgePort *setting) +{ + NMSettingBridgePortPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_BRIDGE_PORT(setting), 0); + priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting); + + return priv->vlans->len; +} + +/** + * nm_setting_bridge_port_get_vlan: + * @setting: the #NMSettingBridgePort + * @idx: index number of the VLAN to return + * + * Returns: (transfer none): the VLAN at index @idx + * + * Since: 1.18 + **/ +NMBridgeVlan * +nm_setting_bridge_port_get_vlan(NMSettingBridgePort *setting, guint idx) +{ + NMSettingBridgePortPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_BRIDGE_PORT(setting), NULL); + priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting); + + g_return_val_if_fail(idx < priv->vlans->len, NULL); + + return priv->vlans->pdata[idx]; +} + +/** + * nm_setting_bridge_port_remove_vlan: + * @setting: the #NMSettingBridgePort + * @idx: index number of the VLAN. + * + * Removes the vlan at index @idx. + * + * Since: 1.18 + **/ +void +nm_setting_bridge_port_remove_vlan(NMSettingBridgePort *setting, guint idx) +{ + NMSettingBridgePortPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_BRIDGE_PORT(setting)); + priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting); + + g_return_if_fail(idx < priv->vlans->len); + + g_ptr_array_remove_index(priv->vlans, idx); + _notify(setting, PROP_VLANS); +} + +/** + * nm_setting_bridge_port_remove_vlan_by_vid: + * @setting: the #NMSettingBridgePort + * @vid_start: the vlan start index + * @vid_end: the vlan end index + * + * Remove the VLAN with range @vid_start to @vid_end. + * If @vid_end is zero, it is assumed to be equal to @vid_start + * and so the single-id VLAN with id @vid_start is removed. + * + * Returns: %TRUE if the vlan was found and removed; %FALSE otherwise + * + * Since: 1.18 + **/ +gboolean +nm_setting_bridge_port_remove_vlan_by_vid(NMSettingBridgePort *setting, + guint16 vid_start, + guint16 vid_end) +{ + NMSettingBridgePortPrivate *priv; + guint i; + + if (vid_end == 0) + vid_end = vid_start; + + g_return_val_if_fail(NM_IS_SETTING_BRIDGE_PORT(setting), FALSE); + + priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting); + + for (i = 0; i < priv->vlans->len; i++) { + NMBridgeVlan *vlan = priv->vlans->pdata[i]; + guint16 v_start = 0; + guint16 v_end = 0; + + nm_bridge_vlan_get_vid_range(vlan, &v_start, &v_end); + if (v_start == vid_start && v_end == vid_end) { + g_ptr_array_remove_index(priv->vlans, i); + _notify(setting, PROP_VLANS); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_bridge_port_clear_vlans: + * @setting: the #NMSettingBridgePort + * + * Removes all configured VLANs. + * + * Since: 1.18 + **/ +void +nm_setting_bridge_port_clear_vlans(NMSettingBridgePort *setting) +{ + NMSettingBridgePortPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_BRIDGE_PORT(setting)); + priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting); + + if (priv->vlans->len != 0) { + g_ptr_array_set_size(priv->vlans, 0); + _notify(setting, PROP_VLANS); + } +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingBridgePortPrivate *priv; + + priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting); + + if (connection) { + NMSettingConnection *s_con; + const char * slave_type; + + s_con = nm_connection_get_setting_connection(connection); + if (!s_con) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("missing setting")); + g_prefix_error(error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME); + return FALSE; + } + + slave_type = nm_setting_connection_get_slave_type(s_con); + if (slave_type && strcmp(slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with a '%s' setting must have the slave-type set to '%s'. " + "Instead it is '%s'"), + NM_SETTING_BRIDGE_PORT_SETTING_NAME, + NM_SETTING_BRIDGE_SETTING_NAME, + slave_type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + } + + if (!_nm_utils_bridge_vlan_verify_list(priv->vlans, + FALSE, + error, + NM_SETTING_BRIDGE_PORT_SETTING_NAME, + NM_SETTING_BRIDGE_PORT_VLANS)) + return FALSE; + + /* Failures from here on are NORMALIZABLE... */ + + if (!_nm_utils_bridge_vlan_verify_list(priv->vlans, + TRUE, + error, + NM_SETTING_BRIDGE_PORT_SETTING_NAME, + NM_SETTING_BRIDGE_PORT_VLANS)) + return NM_SETTING_VERIFY_NORMALIZABLE; + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingBridgePortPrivate *priv_a; + NMSettingBridgePortPrivate *priv_b; + guint i; + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_BRIDGE_PORT_VLANS)) { + if (set_b) { + priv_a = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(set_a); + priv_b = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(set_b); + + if (priv_a->vlans->len != priv_b->vlans->len) + return FALSE; + for (i = 0; i < priv_a->vlans->len; i++) { + if (nm_bridge_vlan_cmp(priv_a->vlans->pdata[i], priv_b->vlans->pdata[i])) + return FALSE; + } + } + return TRUE; + } + + return NM_SETTING_CLASS(nm_setting_bridge_port_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingBridgePortPrivate *priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_PRIORITY: + g_value_set_uint(value, priv->priority); + break; + case PROP_PATH_COST: + g_value_set_uint(value, priv->path_cost); + break; + case PROP_HAIRPIN_MODE: + g_value_set_boolean(value, priv->hairpin_mode); + break; + case PROP_VLANS: + g_value_take_boxed(value, + _nm_utils_copy_array(priv->vlans, + (NMUtilsCopyFunc) nm_bridge_vlan_ref, + (GDestroyNotify) nm_bridge_vlan_unref)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingBridgePortPrivate *priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_PRIORITY: + priv->priority = g_value_get_uint(value); + break; + case PROP_PATH_COST: + priv->path_cost = g_value_get_uint(value); + break; + case PROP_HAIRPIN_MODE: + priv->hairpin_mode = g_value_get_boolean(value); + break; + case PROP_VLANS: + g_ptr_array_unref(priv->vlans); + priv->vlans = _nm_utils_copy_array(g_value_get_boxed(value), + (NMUtilsCopyFunc) _nm_bridge_vlan_dup_and_seal, + (GDestroyNotify) nm_bridge_vlan_unref); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_bridge_port_init(NMSettingBridgePort *setting) +{ + NMSettingBridgePortPrivate *priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(setting); + + priv->vlans = g_ptr_array_new_with_free_func((GDestroyNotify) nm_bridge_vlan_unref); + + priv->priority = NM_BRIDGE_PORT_PRIORITY_DEF; + priv->path_cost = NM_BRIDGE_PORT_PATH_COST_DEF; +} + +/** + * nm_setting_bridge_port_new: + * + * Creates a new #NMSettingBridgePort object with default values. + * + * Returns: (transfer full): the new empty #NMSettingBridgePort object + **/ +NMSetting * +nm_setting_bridge_port_new(void) +{ + return g_object_new(NM_TYPE_SETTING_BRIDGE_PORT, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingBridgePortPrivate *priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(object); + + g_ptr_array_unref(priv->vlans); + + G_OBJECT_CLASS(nm_setting_bridge_port_parent_class)->finalize(object); +} + +static void +nm_setting_bridge_port_class_init(NMSettingBridgePortClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingBridgePortPrivate)); + + object_class->finalize = finalize; + object_class->get_property = get_property; + object_class->set_property = set_property; + + setting_class->compare_property = compare_property; + setting_class->verify = verify; + + /** + * NMSettingBridgePort:priority: + * + * The Spanning Tree Protocol (STP) priority of this bridge port. + **/ + /* ---ifcfg-rh--- + * property: priority + * variable: BRIDGING_OPTS: priority= + * values: 0 - 63 + * default: 32 + * description: STP priority. + * ---end--- + */ + obj_properties[PROP_PRIORITY] = + g_param_spec_uint(NM_SETTING_BRIDGE_PORT_PRIORITY, + "", + "", + NM_BRIDGE_PORT_PRIORITY_MIN, + NM_BRIDGE_PORT_PRIORITY_MAX, + NM_BRIDGE_PORT_PRIORITY_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridgePort:path-cost: + * + * The Spanning Tree Protocol (STP) port cost for destinations via this + * port. + **/ + /* ---ifcfg-rh--- + * property: path-cost + * variable: BRIDGING_OPTS: path_cost= + * values: 1 - 65535 + * default: 100 + * description: STP cost. + * ---end--- + */ + obj_properties[PROP_PATH_COST] = g_param_spec_uint(NM_SETTING_BRIDGE_PORT_PATH_COST, + "", + "", + NM_BRIDGE_PORT_PATH_COST_MIN, + NM_BRIDGE_PORT_PATH_COST_MAX, + NM_BRIDGE_PORT_PATH_COST_DEF, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridgePort:hairpin-mode: + * + * Enables or disables "hairpin mode" for the port, which allows frames to + * be sent back out through the port the frame was received on. + **/ + /* ---ifcfg-rh--- + * property: hairpin-mode + * variable: BRIDGING_OPTS: hairpin_mode= + * default: yes + * description: Hairpin mode of the bridge port. + * ---end--- + */ + obj_properties[PROP_HAIRPIN_MODE] = g_param_spec_boolean( + NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridgePort:vlans: (type GPtrArray(NMBridgeVlan)) + * + * Array of bridge VLAN objects. In addition to the VLANs + * specified here, the port will also have the default-pvid + * VLAN configured on the bridge by the bridge.vlan-default-pvid + * property. + * + * In nmcli the VLAN list can be specified with the following + * syntax: + * + * $vid [pvid] [untagged] [, $vid [pvid] [untagged]]... + * + * where $vid is either a single id between 1 and 4094 or a + * range, represented as a couple of ids separated by a dash. + * + * Since: 1.18 + **/ + /* ---ifcfg-rh--- + * property: vlans + * variable: BRIDGE_PORT_VLANS + * description: List of VLANs on the bridge port + * example: BRIDGE_PORT_VLANS="1 pvid untagged,20,300-400 untagged" + * ---end--- + */ + obj_properties[PROP_VLANS] = g_param_spec_boxed(NM_SETTING_BRIDGE_PORT_VLANS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_VLANS], + &nm_sett_info_propert_type_bridge_vlans); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_BRIDGE_PORT, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-bridge.c b/src/libnm-core-impl/nm-setting-bridge.c new file mode 100644 index 0000000..202a879 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-bridge.c @@ -0,0 +1,2292 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-bridge.h" + +#include +#include +#include + +#include "libnm-glib-aux/nm-str-buf.h" +#include "nm-connection-private.h" +#include "nm-utils.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-bridge + * @short_description: Describes connection properties for bridges + * + * The #NMSettingBridge object is a #NMSetting subclass that describes properties + * necessary for bridging connections. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingBridge, + PROP_MAC_ADDRESS, + PROP_STP, + PROP_PRIORITY, + PROP_FORWARD_DELAY, + PROP_HELLO_TIME, + PROP_MAX_AGE, + PROP_AGEING_TIME, + PROP_GROUP_ADDRESS, + PROP_GROUP_FORWARD_MASK, + PROP_MULTICAST_HASH_MAX, + PROP_MULTICAST_LAST_MEMBER_COUNT, + PROP_MULTICAST_LAST_MEMBER_INTERVAL, + PROP_MULTICAST_MEMBERSHIP_INTERVAL, + PROP_MULTICAST_ROUTER, + PROP_MULTICAST_QUERIER, + PROP_MULTICAST_QUERIER_INTERVAL, + PROP_MULTICAST_QUERY_INTERVAL, + PROP_MULTICAST_QUERY_RESPONSE_INTERVAL, + PROP_MULTICAST_QUERY_USE_IFADDR, + PROP_MULTICAST_SNOOPING, + PROP_MULTICAST_STARTUP_QUERY_COUNT, + PROP_MULTICAST_STARTUP_QUERY_INTERVAL, + PROP_VLAN_FILTERING, + PROP_VLAN_DEFAULT_PVID, + PROP_VLAN_PROTOCOL, + PROP_VLAN_STATS_ENABLED, + PROP_VLANS, ); + +typedef struct { + GPtrArray *vlans; + char * mac_address; + char * multicast_router; + char * group_address; + char * vlan_protocol; + guint64 multicast_last_member_interval; + guint64 multicast_membership_interval; + guint64 multicast_querier_interval; + guint64 multicast_query_interval; + guint64 multicast_query_response_interval; + guint64 multicast_startup_query_interval; + guint32 ageing_time; + guint32 multicast_hash_max; + guint32 multicast_last_member_count; + guint32 multicast_startup_query_count; + guint16 priority; + guint16 forward_delay; + guint16 hello_time; + guint16 max_age; + guint16 vlan_default_pvid; + guint16 group_forward_mask; + bool multicast_snooping : 1; + bool vlan_filtering : 1; + bool stp : 1; + bool vlan_stats_enabled : 1; + bool multicast_query_use_ifaddr : 1; + bool multicast_querier : 1; +} NMSettingBridgePrivate; + +/** + * NMSettingBridge: + * + * Bridging Settings + */ +struct _NMSettingBridge { + NMSetting parent; + NMSettingBridgePrivate _priv; +}; + +struct _NMSettingBridgeClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingBridge, nm_setting_bridge, NM_TYPE_SETTING) + +#define NM_SETTING_BRIDGE_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSettingBridge, NM_IS_SETTING_BRIDGE, NMSetting) + +/*****************************************************************************/ + +G_DEFINE_BOXED_TYPE(NMBridgeVlan, nm_bridge_vlan, _nm_bridge_vlan_dup, nm_bridge_vlan_unref) + +struct _NMBridgeVlan { + guint refcount; + guint16 vid_start; + guint16 vid_end; + bool untagged : 1; + bool pvid : 1; + bool sealed : 1; +}; + +static gboolean +NM_IS_BRIDGE_VLAN(const NMBridgeVlan *self, gboolean also_sealed) +{ + return self && self->refcount > 0 && (also_sealed || !self->sealed); +} + +/** + * nm_bridge_vlan_new: + * @vid_start: the start VLAN id, must be between 1 and 4094. + * @vid_end: the end VLAN id, must be 0 or between @vid_start and 4094. + * + * Creates a new #NMBridgeVlan object for the given VLAN id range. + * Setting @vid_end to 0 is equivalent to setting it to @vid_start + * and creates a single-id VLAN. + * + * Returns: (transfer full): the new #NMBridgeVlan object. + * + * Since: 1.18 + **/ +NMBridgeVlan * +nm_bridge_vlan_new(guint16 vid_start, guint16 vid_end) +{ + NMBridgeVlan *vlan; + + if (vid_end == 0) + vid_end = vid_start; + + g_return_val_if_fail(vid_start >= NM_BRIDGE_VLAN_VID_MIN, NULL); + g_return_val_if_fail(vid_end <= NM_BRIDGE_VLAN_VID_MAX, NULL); + g_return_val_if_fail(vid_start <= vid_end, NULL); + + vlan = g_slice_new0(NMBridgeVlan); + vlan->refcount = 1; + vlan->vid_start = vid_start; + vlan->vid_end = vid_end; + + return vlan; +} + +/** + * nm_bridge_vlan_ref: + * @vlan: the #NMBridgeVlan + * + * Increases the reference count of the object. + * + * Returns: the input argument @vlan object. + * + * Since: 1.18 + **/ +NMBridgeVlan * +nm_bridge_vlan_ref(NMBridgeVlan *vlan) +{ + g_return_val_if_fail(NM_IS_BRIDGE_VLAN(vlan, TRUE), NULL); + + nm_assert(vlan->refcount < G_MAXUINT); + + vlan->refcount++; + return vlan; +} + +/** + * nm_bridge_vlan_unref: + * @vlan: the #NMBridgeVlan + * + * Decreases the reference count of the object. If the reference count + * reaches zero the object will be destroyed. + * + * Since: 1.18 + **/ +void +nm_bridge_vlan_unref(NMBridgeVlan *vlan) +{ + g_return_if_fail(NM_IS_BRIDGE_VLAN(vlan, TRUE)); + + if (--vlan->refcount == 0) + g_slice_free(NMBridgeVlan, vlan); +} + +/** + * nm_bridge_vlan_cmp: + * @a: a #NMBridgeVlan + * @b: another #NMBridgeVlan + * + * Compare two bridge VLAN objects. + * + * Returns: zero of the two instances are equivalent or + * a non-zero integer otherwise. This defines a total ordering + * over the VLANs. Whether a VLAN is sealed or not does not + * affect the comparison. + * + * Since: 1.18 + **/ +int +nm_bridge_vlan_cmp(const NMBridgeVlan *a, const NMBridgeVlan *b) +{ + g_return_val_if_fail(NM_IS_BRIDGE_VLAN(a, TRUE), 0); + g_return_val_if_fail(NM_IS_BRIDGE_VLAN(b, TRUE), 0); + + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, vid_start); + NM_CMP_FIELD(a, b, vid_end); + NM_CMP_FIELD_BOOL(a, b, untagged); + NM_CMP_FIELD_BOOL(a, b, pvid); + + return 0; +} + +NMBridgeVlan * +_nm_bridge_vlan_dup(const NMBridgeVlan *vlan) +{ + g_return_val_if_fail(NM_IS_BRIDGE_VLAN(vlan, TRUE), NULL); + + if (vlan->sealed) { + nm_bridge_vlan_ref((NMBridgeVlan *) vlan); + return (NMBridgeVlan *) vlan; + } + + return nm_bridge_vlan_new_clone(vlan); +} + +NMBridgeVlan * +_nm_bridge_vlan_dup_and_seal(const NMBridgeVlan *vlan) +{ + NMBridgeVlan *new; + + g_return_val_if_fail(NM_IS_BRIDGE_VLAN(vlan, TRUE), NULL); + + new = _nm_bridge_vlan_dup(vlan); + nm_bridge_vlan_seal(new); + + return new; +} + +/** + * nm_bridge_vlan_get_vid_range: + * @vlan: the #NMBridgeVlan + * @vid_start: (out): location to store the VLAN id range start. + * @vid_end: (out): location to store the VLAN id range end + * + * Gets the VLAN id range. + * + * Returns: %TRUE is the VLAN specifies a range, %FALSE if it is + * a single-id VLAN. + * + * Since: 1.18 + **/ +gboolean +nm_bridge_vlan_get_vid_range(const NMBridgeVlan *vlan, guint16 *vid_start, guint16 *vid_end) +{ + /* with LTO and optimization, the compiler complains that the + * output variables are not initialized. In practice, the function + * only sets the output on success. But make the compiler happy. + */ + NM_SET_OUT(vid_start, 0); + NM_SET_OUT(vid_end, 0); + + g_return_val_if_fail(NM_IS_BRIDGE_VLAN(vlan, TRUE), 0); + + NM_SET_OUT(vid_start, vlan->vid_start); + NM_SET_OUT(vid_end, vlan->vid_end); + + return vlan->vid_start != vlan->vid_end; +} + +/** + * nm_bridge_vlan_is_untagged: + * @vlan: the #NMBridgeVlan + * + * Returns whether the VLAN is untagged. + * + * Returns: %TRUE if the VLAN is untagged, %FALSE otherwise + * + * Since: 1.18 + **/ +gboolean +nm_bridge_vlan_is_untagged(const NMBridgeVlan *vlan) +{ + g_return_val_if_fail(NM_IS_BRIDGE_VLAN(vlan, TRUE), FALSE); + + return vlan->untagged; +} + +/** + * nm_bridge_vlan_is_pvid: + * @vlan: the #NMBridgeVlan + * + * Returns whether the VLAN is the PVID for the port. + * + * Returns: %TRUE if the VLAN is the PVID + * + * Since: 1.18 + **/ +gboolean +nm_bridge_vlan_is_pvid(const NMBridgeVlan *vlan) +{ + g_return_val_if_fail(NM_IS_BRIDGE_VLAN(vlan, TRUE), FALSE); + + return vlan->pvid; +} + +/** + * nm_bridge_vlan_set_untagged: + * @vlan: the #NMBridgeVlan + * @value: the new value + * + * Change the value of the untagged property of the VLAN. + * + * Since: 1.18 + **/ +void +nm_bridge_vlan_set_untagged(NMBridgeVlan *vlan, gboolean value) +{ + g_return_if_fail(NM_IS_BRIDGE_VLAN(vlan, FALSE)); + + vlan->untagged = value; +} + +/** + * nm_bridge_vlan_set_pvid: + * @vlan: the #NMBridgeVlan + * @value: the new value + * + * Change the value of the PVID property of the VLAN. It + * is invalid to set the value to %TRUE for non-single-id + * VLANs. + * + * Since: 1.18 + **/ +void +nm_bridge_vlan_set_pvid(NMBridgeVlan *vlan, gboolean value) +{ + g_return_if_fail(NM_IS_BRIDGE_VLAN(vlan, FALSE)); + g_return_if_fail(!value || vlan->vid_start == vlan->vid_end); + + vlan->pvid = value; +} + +/** + * nm_bridge_vlan_is_sealed: + * @vlan: the #NMBridgeVlan instance + * + * Returns: whether @self is sealed or not. + * + * Since: 1.18 + */ +gboolean +nm_bridge_vlan_is_sealed(const NMBridgeVlan *vlan) +{ + g_return_val_if_fail(NM_IS_BRIDGE_VLAN(vlan, TRUE), FALSE); + + return vlan->sealed; +} + +/** + * nm_bridge_vlan_seal: + * @vlan: the #NMBridgeVlan instance + * + * Seal the #NMBridgeVlan instance. Afterwards, it is a bug + * to call all functions that modify the instance (except ref/unref). + * A sealed instance cannot be unsealed again, but you can create + * an unsealed copy with nm_bridge_vlan_new_clone(). + * + * Since: 1.18 + */ +void +nm_bridge_vlan_seal(NMBridgeVlan *vlan) +{ + g_return_if_fail(NM_IS_BRIDGE_VLAN(vlan, TRUE)); + + vlan->sealed = TRUE; +} + +/** + * nm_bridge_vlan_new_clone: + * @vlan: the #NMBridgeVlan instance to copy + * + * Returns: (transfer full): a clone of @vlan. This instance + * is always unsealed. + * + * Since: 1.18 + */ +NMBridgeVlan * +nm_bridge_vlan_new_clone(const NMBridgeVlan *vlan) +{ + NMBridgeVlan *copy; + + g_return_val_if_fail(NM_IS_BRIDGE_VLAN(vlan, TRUE), NULL); + + copy = nm_bridge_vlan_new(vlan->vid_start, vlan->vid_end); + copy->untagged = vlan->untagged; + copy->pvid = vlan->pvid; + + return copy; +} + +/** + * nm_bridge_vlan_to_str: + * @vlan: the %NMBridgeVlan + * @error: location of the error + * + * Convert a %NMBridgeVlan to a string. + * + * Returns: formatted string or %NULL + * + * Since: 1.18 + */ +char * +nm_bridge_vlan_to_str(const NMBridgeVlan *vlan, GError **error) +{ + NMStrBuf string; + + g_return_val_if_fail(vlan, NULL); + g_return_val_if_fail(!error || !*error, NULL); + + /* The function never fails at the moment, but it might in the + * future if more parameters are added to the object that could + * make it invalid. */ + + nm_str_buf_init(&string, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); + + if (vlan->vid_start == vlan->vid_end) + nm_str_buf_append_printf(&string, "%u", vlan->vid_start); + else + nm_str_buf_append_printf(&string, "%u-%u", vlan->vid_start, vlan->vid_end); + + if (nm_bridge_vlan_is_pvid(vlan)) + nm_str_buf_append(&string, " pvid"); + if (nm_bridge_vlan_is_untagged(vlan)) + nm_str_buf_append(&string, " untagged"); + + return nm_str_buf_finalize(&string, NULL); +} + +/** + * nm_bridge_vlan_from_str: + * @str: the string representation of a bridge VLAN + * @error: location of the error + * + * Parses the string representation of the queueing + * discipline to a %NMBridgeVlan instance. + * + * Returns: the %NMBridgeVlan or %NULL + * + * Since: 1.18 + */ +NMBridgeVlan * +nm_bridge_vlan_from_str(const char *str, GError **error) +{ + NMBridgeVlan * vlan = NULL; + gs_free const char **tokens = NULL; + guint i, vid_start, vid_end = 0; + gboolean pvid = FALSE; + gboolean untagged = FALSE; + char * c; + + g_return_val_if_fail(str, NULL); + g_return_val_if_fail(!error || !*error, NULL); + + tokens = nm_utils_escaped_tokens_split(str, NM_ASCII_SPACES); + if (!tokens || !tokens[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "missing VLAN id"); + return NULL; + } + + c = strchr(tokens[0], '-'); + if (c) + *c = '\0'; + + vid_start = _nm_utils_ascii_str_to_uint64(tokens[0], + 10, + NM_BRIDGE_VLAN_VID_MIN, + NM_BRIDGE_VLAN_VID_MAX, + G_MAXUINT); + if (vid_start == G_MAXUINT) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "invalid VLAN id range start '%s', must be in [1,4094]", + tokens[0]); + return NULL; + } + + if (c) { + vid_end = _nm_utils_ascii_str_to_uint64(c + 1, + 10, + NM_BRIDGE_VLAN_VID_MIN, + NM_BRIDGE_VLAN_VID_MAX, + G_MAXUINT); + if (vid_end == G_MAXUINT) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "invalid VLAN id range end '%s', must be in [1,4094]", + c + 1); + return NULL; + } + if (vid_end < vid_start) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "invalid VLAN id range %u-%u, start VLAN id must be less than end VLAN id", + vid_start, + vid_end); + return NULL; + } + } else + vid_end = vid_start; + + for (i = 1; tokens[i]; i++) { + if (nm_streq(tokens[i], "pvid")) { + if (vid_start != vid_end) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "a VLAN range can't be a PVID"); + return NULL; + } + pvid = TRUE; + } else if (nm_streq(tokens[i], "untagged")) + untagged = TRUE; + else { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "invalid option '%s'", + tokens[i]); + return NULL; + } + } + + vlan = nm_bridge_vlan_new(vid_start, vid_end); + nm_bridge_vlan_set_pvid(vlan, pvid); + nm_bridge_vlan_set_untagged(vlan, untagged); + + return vlan; +} + +/*****************************************************************************/ + +static int +vlan_ptr_cmp(gconstpointer a, gconstpointer b) +{ + const NMBridgeVlan *vlan_a = *(const NMBridgeVlan **) a; + const NMBridgeVlan *vlan_b = *(const NMBridgeVlan **) b; + + return nm_bridge_vlan_cmp(vlan_a, vlan_b); +} + +gboolean +_nm_setting_bridge_sort_vlans(NMSettingBridge *setting) +{ + NMSettingBridgePrivate *priv; + gboolean need_sort = FALSE; + guint i; + + priv = NM_SETTING_BRIDGE_GET_PRIVATE(setting); + + for (i = 1; i < priv->vlans->len; i++) { + NMBridgeVlan *vlan_prev = priv->vlans->pdata[i - 1]; + NMBridgeVlan *vlan = priv->vlans->pdata[i]; + + if (nm_bridge_vlan_cmp(vlan_prev, vlan) > 0) { + need_sort = TRUE; + break; + } + } + + if (need_sort) { + g_ptr_array_sort(priv->vlans, vlan_ptr_cmp); + _notify(setting, PROP_VLANS); + } + + return need_sort; +} + +/*****************************************************************************/ + +/** + * nm_setting_bridge_get_mac_address: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:mac-address property of the setting + **/ +const char * +nm_setting_bridge_get_mac_address(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), NULL); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->mac_address; +} + +/** + * nm_setting_bridge_get_stp: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:stp property of the setting + **/ +gboolean +nm_setting_bridge_get_stp(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), FALSE); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->stp; +} + +/** + * nm_setting_bridge_get_priority: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:priority property of the setting + **/ +guint16 +nm_setting_bridge_get_priority(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->priority; +} + +/** + * nm_setting_bridge_get_forward_delay: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:forward-delay property of the setting + **/ +guint16 +nm_setting_bridge_get_forward_delay(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->forward_delay; +} + +/** + * nm_setting_bridge_get_hello_time: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:hello-time property of the setting + **/ +guint16 +nm_setting_bridge_get_hello_time(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->hello_time; +} + +/** + * nm_setting_bridge_get_max_age: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:max-age property of the setting + **/ +guint16 +nm_setting_bridge_get_max_age(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->max_age; +} + +/** + * nm_setting_bridge_get_ageing_time: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:ageing-time property of the setting + **/ +guint +nm_setting_bridge_get_ageing_time(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->ageing_time; +} + +/** + * nm_setting_bridge_get_group_forward_mask: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:group-forward-mask property of the setting + * + * Since: 1.10 + **/ +guint16 +nm_setting_bridge_get_group_forward_mask(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->group_forward_mask; +} + +/** + * nm_setting_bridge_get_multicast_snooping: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-snooping property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_bridge_get_multicast_snooping(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), FALSE); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_snooping; +} + +/** + * nm_setting_bridge_get_vlan_filtering: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:vlan-filtering property of the setting + * + * Since: 1.18 + **/ +gboolean +nm_setting_bridge_get_vlan_filtering(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), FALSE); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->vlan_filtering; +} + +/** + * nm_setting_bridge_get_vlan_default_pvid: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:vlan-default-pvid property of the setting + * + * Since: 1.18 + **/ +guint16 +nm_setting_bridge_get_vlan_default_pvid(NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 1); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->vlan_default_pvid; +} + +/** + * nm_setting_bridge_add_vlan: + * @setting: the #NMSettingBridge + * @vlan: the vlan to add + * + * Appends a new vlan and associated information to the setting. The + * given vlan gets sealed and a reference to it is added. + * + * Since: 1.18 + **/ +void +nm_setting_bridge_add_vlan(NMSettingBridge *setting, NMBridgeVlan *vlan) +{ + NMSettingBridgePrivate *priv; + + g_return_if_fail(NM_IS_SETTING_BRIDGE(setting)); + g_return_if_fail(vlan); + + priv = NM_SETTING_BRIDGE_GET_PRIVATE(setting); + + nm_bridge_vlan_seal(vlan); + nm_bridge_vlan_ref(vlan); + + g_ptr_array_add(priv->vlans, vlan); + _notify(setting, PROP_VLANS); +} + +/** + * nm_setting_bridge_get_num_vlans: + * @setting: the #NMSettingBridge + * + * Returns: the number of VLANs + * + * Since: 1.18 + **/ +guint +nm_setting_bridge_get_num_vlans(NMSettingBridge *setting) +{ + NMSettingBridgePrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + priv = NM_SETTING_BRIDGE_GET_PRIVATE(setting); + + return priv->vlans->len; +} + +/** + * nm_setting_bridge_get_vlan: + * @setting: the #NMSettingBridge + * @idx: index number of the VLAN to return + * + * Returns: (transfer none): the VLAN at index @idx + * + * Since: 1.18 + **/ +NMBridgeVlan * +nm_setting_bridge_get_vlan(NMSettingBridge *setting, guint idx) +{ + NMSettingBridgePrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), NULL); + priv = NM_SETTING_BRIDGE_GET_PRIVATE(setting); + + g_return_val_if_fail(idx < priv->vlans->len, NULL); + + return priv->vlans->pdata[idx]; +} + +/** + * nm_setting_bridge_remove_vlan: + * @setting: the #NMSettingBridge + * @idx: index number of the VLAN. + * + * Removes the vlan at index @idx. + * + * Since: 1.18 + **/ +void +nm_setting_bridge_remove_vlan(NMSettingBridge *setting, guint idx) +{ + NMSettingBridgePrivate *priv; + + g_return_if_fail(NM_IS_SETTING_BRIDGE(setting)); + priv = NM_SETTING_BRIDGE_GET_PRIVATE(setting); + + g_return_if_fail(idx < priv->vlans->len); + + g_ptr_array_remove_index(priv->vlans, idx); + _notify(setting, PROP_VLANS); +} + +/** + * nm_setting_bridge_remove_vlan_by_vid: + * @setting: the #NMSettingBridge + * @vid_start: the vlan start index + * @vid_end: the vlan end index + * + * Remove the VLAN with range @vid_start to @vid_end. + * If @vid_end is zero, it is assumed to be equal to @vid_start + * and so the single-id VLAN with id @vid_start is removed. + * + * Returns: %TRUE if the vlan was found and removed; %FALSE otherwise + * + * Since: 1.18 + **/ +gboolean +nm_setting_bridge_remove_vlan_by_vid(NMSettingBridge *setting, guint16 vid_start, guint16 vid_end) +{ + NMSettingBridgePrivate *priv; + NMBridgeVlan * vlan; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), FALSE); + priv = NM_SETTING_BRIDGE_GET_PRIVATE(setting); + + if (vid_end == 0) + vid_end = vid_start; + + for (i = 0; i < priv->vlans->len; i++) { + vlan = (NMBridgeVlan *) priv->vlans->pdata[i]; + if (vlan->vid_start == vid_start && vlan->vid_end == vid_end) { + g_ptr_array_remove_index(priv->vlans, i); + _notify(setting, PROP_VLANS); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_bridge_clear_vlans: + * @setting: the #NMSettingBridge + * + * Removes all configured VLANs. + * + * Since: 1.18 + **/ +void +nm_setting_bridge_clear_vlans(NMSettingBridge *setting) +{ + NMSettingBridgePrivate *priv; + + g_return_if_fail(NM_IS_SETTING_BRIDGE(setting)); + priv = NM_SETTING_BRIDGE_GET_PRIVATE(setting); + + if (priv->vlans->len != 0) { + g_ptr_array_set_size(priv->vlans, 0); + _notify(setting, PROP_VLANS); + } +} + +/** + * nm_setting_bridge_get_group_address: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:group-address property of the setting + * + * Since 1.24 + **/ +const char * +nm_setting_bridge_get_group_address(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), NULL); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->group_address; +} + +/** + * nm_setting_bridge_get_vlan_protocol: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:vlan-protocol property of the setting + * + * Since 1.24 + **/ +const char * +nm_setting_bridge_get_vlan_protocol(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), NULL); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->vlan_protocol; +} + +/** + * nm_setting_bridge_get_vlan_stats_enabled: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:vlan-stats-enabled property of the setting + * + * Since 1.24 + **/ +gboolean +nm_setting_bridge_get_vlan_stats_enabled(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), FALSE); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->vlan_stats_enabled; +} + +/** + * nm_setting_bridge_get_multicast_router: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-router property of the setting + * + * Since 1.24 + **/ +const char * +nm_setting_bridge_get_multicast_router(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), NULL); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_router; +} + +/** + * nm_setting_bridge_get_multicast_query_use_ifaddr: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-query-use-ifaddr property of the setting + * + * Since 1.24 + **/ +gboolean +nm_setting_bridge_get_multicast_query_use_ifaddr(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), FALSE); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_query_use_ifaddr; +} + +/** + * nm_setting_bridge_get_multicast_querier: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-querier property of the setting + * + * Since 1.24 + **/ +gboolean +nm_setting_bridge_get_multicast_querier(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), FALSE); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_querier; +} + +/** + * nm_setting_bridge_get_multicast_hash_max: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-hash-max property of the setting + * + * Since 1.26 + **/ +guint32 +nm_setting_bridge_get_multicast_hash_max(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_hash_max; +} + +/** + * nm_setting_bridge_get_multicast_last_member_count: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-last-member-count property of the setting + * + * Since 1.26 + **/ +guint32 +nm_setting_bridge_get_multicast_last_member_count(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_last_member_count; +} + +/** + * nm_setting_bridge_get_multicast_last_member_interval: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-last-member-interval property of the setting + * + * Since 1.26 + **/ +guint64 +nm_setting_bridge_get_multicast_last_member_interval(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_last_member_interval; +} + +/** + * nm_setting_bridge_get_multicast_membership_interval: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-membership-interval property of the setting + * + * Since 1.26 + **/ +guint64 +nm_setting_bridge_get_multicast_membership_interval(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_membership_interval; +} + +/** + * nm_setting_bridge_get_multicast_querier_interval: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-querier-interval property of the setting + * + * Since 1.26 + **/ +guint64 +nm_setting_bridge_get_multicast_querier_interval(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_querier_interval; +} + +/** + * nm_setting_bridge_get_multicast_query_interval: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-query-interval property of the setting + * + * Since 1.26 + **/ +guint64 +nm_setting_bridge_get_multicast_query_interval(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_query_interval; +} + +/** + * nm_setting_bridge_get_multicast_query_response_interval: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-query-response-interval property of the setting + * + * Since 1.26 + **/ +guint64 +nm_setting_bridge_get_multicast_query_response_interval(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_query_response_interval; +} + +/** + * nm_setting_bridge_get_multicast_startup_query_count: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-query-response-interval property of the setting + * + * Since 1.26 + **/ +guint32 +nm_setting_bridge_get_multicast_startup_query_count(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_startup_query_count; +} + +/** + * nm_setting_bridge_get_multicast_startup_query_interval: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-startup-query-interval property of the setting + * + * Since 1.26 + **/ +guint64 +nm_setting_bridge_get_multicast_startup_query_interval(const NMSettingBridge *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_BRIDGE(setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE(setting)->multicast_startup_query_interval; +} + +/*****************************************************************************/ + +static gboolean +check_range(guint32 val, guint32 min, guint32 max, gboolean zero, const char *prop, GError **error) +{ + if (zero && val == 0) + return TRUE; + + if (val < min || val > max) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value '%d' is out of range <%d-%d>"), + val, + min, + max); + g_prefix_error(error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, prop); + return FALSE; + } + return TRUE; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE(setting); + + if (priv->mac_address && !nm_utils_hwaddr_valid(priv->mac_address, ETH_ALEN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a valid MAC address")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BRIDGE_MAC_ADDRESS); + return FALSE; + } + + if (!check_range(priv->forward_delay, + NM_BRIDGE_FORWARD_DELAY_MIN, + NM_BRIDGE_FORWARD_DELAY_MAX, + !priv->stp, + NM_SETTING_BRIDGE_FORWARD_DELAY, + error)) + return FALSE; + + if (!check_range(priv->hello_time, + NM_BRIDGE_HELLO_TIME_MIN, + NM_BRIDGE_HELLO_TIME_MAX, + !priv->stp, + NM_SETTING_BRIDGE_HELLO_TIME, + error)) + return FALSE; + + if (!check_range(priv->max_age, + NM_BRIDGE_MAX_AGE_MIN, + NM_BRIDGE_MAX_AGE_MAX, + !priv->stp, + NM_SETTING_BRIDGE_MAX_AGE, + error)) + return FALSE; + + if (!check_range(priv->ageing_time, + NM_BRIDGE_AGEING_TIME_MIN, + NM_BRIDGE_AGEING_TIME_MAX, + !priv->stp, + NM_SETTING_BRIDGE_AGEING_TIME, + error)) + return FALSE; + + if (priv->group_forward_mask & 7) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the mask can't contain bits 0 (STP), 1 (MAC) or 2 (LACP)")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BRIDGE_GROUP_FORWARD_MASK); + return FALSE; + } + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + if (!_nm_utils_bridge_vlan_verify_list(priv->vlans, + FALSE, + error, + NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BRIDGE_VLANS)) + return FALSE; + + if (priv->group_address && !_nm_utils_hwaddr_link_local_valid(priv->group_address)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a valid link local MAC address")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BRIDGE_GROUP_ADDRESS); + return FALSE; + } + + if (priv->vlan_protocol && !NM_IN_STRSET(priv->vlan_protocol, "802.1Q", "802.1ad")) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a valid VLAN filtering protocol")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BRIDGE_VLAN_PROTOCOL); + return FALSE; + } + + if (!NM_IN_STRSET(priv->multicast_router, NULL, "auto", "enabled", "disabled")) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a valid option")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BRIDGE_MULTICAST_ROUTER); + return FALSE; + } + + if (!nm_utils_is_power_of_two(priv->multicast_hash_max)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option must be a power of 2"), + NM_SETTING_BRIDGE_MULTICAST_HASH_MAX); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BRIDGE_MULTICAST_HASH_MAX); + return FALSE; + } + + /* Failures from here on are NORMALIZABLE... */ + + if (!_nm_utils_bridge_vlan_verify_list(priv->vlans, + TRUE, + error, + NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BRIDGE_VLANS)) + return NM_SETTING_VERIFY_NORMALIZABLE; + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingBridgePrivate *priv_a; + NMSettingBridgePrivate *priv_b; + guint i; + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_BRIDGE_VLANS)) { + if (set_b) { + priv_a = NM_SETTING_BRIDGE_GET_PRIVATE(set_a); + priv_b = NM_SETTING_BRIDGE_GET_PRIVATE(set_b); + + if (priv_a->vlans->len != priv_b->vlans->len) + return FALSE; + for (i = 0; i < priv_a->vlans->len; i++) { + if (nm_bridge_vlan_cmp(priv_a->vlans->pdata[i], priv_b->vlans->pdata[i])) + return FALSE; + } + } + return TRUE; + } + + return NM_SETTING_CLASS(nm_setting_bridge_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE(object); + NMSettingBridge * setting = NM_SETTING_BRIDGE(object); + + switch (prop_id) { + case PROP_MAC_ADDRESS: + g_value_set_string(value, nm_setting_bridge_get_mac_address(setting)); + break; + case PROP_STP: + g_value_set_boolean(value, priv->stp); + break; + case PROP_PRIORITY: + g_value_set_uint(value, priv->priority); + break; + case PROP_FORWARD_DELAY: + g_value_set_uint(value, priv->forward_delay); + break; + case PROP_HELLO_TIME: + g_value_set_uint(value, priv->hello_time); + break; + case PROP_MAX_AGE: + g_value_set_uint(value, priv->max_age); + break; + case PROP_AGEING_TIME: + g_value_set_uint(value, priv->ageing_time); + break; + case PROP_GROUP_ADDRESS: + g_value_set_string(value, priv->group_address); + break; + case PROP_GROUP_FORWARD_MASK: + g_value_set_uint(value, priv->group_forward_mask); + break; + case PROP_MULTICAST_HASH_MAX: + g_value_set_uint(value, priv->multicast_hash_max); + break; + case PROP_MULTICAST_LAST_MEMBER_COUNT: + g_value_set_uint(value, priv->multicast_last_member_count); + break; + case PROP_MULTICAST_LAST_MEMBER_INTERVAL: + g_value_set_uint64(value, priv->multicast_last_member_interval); + break; + case PROP_MULTICAST_MEMBERSHIP_INTERVAL: + g_value_set_uint64(value, priv->multicast_membership_interval); + break; + case PROP_MULTICAST_SNOOPING: + g_value_set_boolean(value, priv->multicast_snooping); + break; + case PROP_MULTICAST_ROUTER: + g_value_set_string(value, priv->multicast_router); + break; + case PROP_MULTICAST_QUERIER: + g_value_set_boolean(value, priv->multicast_querier); + break; + case PROP_MULTICAST_QUERIER_INTERVAL: + g_value_set_uint64(value, priv->multicast_querier_interval); + break; + case PROP_MULTICAST_QUERY_INTERVAL: + g_value_set_uint64(value, priv->multicast_query_interval); + break; + case PROP_MULTICAST_QUERY_RESPONSE_INTERVAL: + g_value_set_uint64(value, priv->multicast_query_response_interval); + break; + case PROP_MULTICAST_QUERY_USE_IFADDR: + g_value_set_boolean(value, priv->multicast_query_use_ifaddr); + break; + case PROP_MULTICAST_STARTUP_QUERY_COUNT: + g_value_set_uint(value, priv->multicast_startup_query_count); + break; + case PROP_MULTICAST_STARTUP_QUERY_INTERVAL: + g_value_set_uint64(value, priv->multicast_startup_query_interval); + break; + case PROP_VLAN_FILTERING: + g_value_set_boolean(value, priv->vlan_filtering); + break; + case PROP_VLAN_DEFAULT_PVID: + g_value_set_uint(value, priv->vlan_default_pvid); + break; + case PROP_VLAN_PROTOCOL: + g_value_set_string(value, priv->vlan_protocol); + break; + case PROP_VLAN_STATS_ENABLED: + g_value_set_boolean(value, priv->vlan_stats_enabled); + break; + case PROP_VLANS: + g_value_take_boxed(value, + _nm_utils_copy_array(priv->vlans, + (NMUtilsCopyFunc) nm_bridge_vlan_ref, + (GDestroyNotify) nm_bridge_vlan_unref)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_MAC_ADDRESS: + g_free(priv->mac_address); + priv->mac_address = + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); + break; + case PROP_STP: + priv->stp = g_value_get_boolean(value); + break; + case PROP_PRIORITY: + priv->priority = (guint16) g_value_get_uint(value); + break; + case PROP_FORWARD_DELAY: + priv->forward_delay = (guint16) g_value_get_uint(value); + break; + case PROP_HELLO_TIME: + priv->hello_time = (guint16) g_value_get_uint(value); + break; + case PROP_MAX_AGE: + priv->max_age = (guint16) g_value_get_uint(value); + break; + case PROP_AGEING_TIME: + priv->ageing_time = g_value_get_uint(value); + break; + case PROP_GROUP_ADDRESS: + g_free(priv->group_address); + priv->group_address = + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); + break; + case PROP_GROUP_FORWARD_MASK: + priv->group_forward_mask = (guint16) g_value_get_uint(value); + break; + case PROP_MULTICAST_HASH_MAX: + priv->multicast_hash_max = g_value_get_uint(value); + break; + case PROP_MULTICAST_LAST_MEMBER_COUNT: + priv->multicast_last_member_count = g_value_get_uint(value); + break; + case PROP_MULTICAST_LAST_MEMBER_INTERVAL: + priv->multicast_last_member_interval = g_value_get_uint64(value); + break; + case PROP_MULTICAST_MEMBERSHIP_INTERVAL: + priv->multicast_membership_interval = g_value_get_uint64(value); + break; + case PROP_MULTICAST_SNOOPING: + priv->multicast_snooping = g_value_get_boolean(value); + break; + case PROP_MULTICAST_ROUTER: + g_free(priv->multicast_router); + priv->multicast_router = g_value_dup_string(value); + break; + case PROP_MULTICAST_QUERIER: + priv->multicast_querier = g_value_get_boolean(value); + break; + case PROP_MULTICAST_QUERIER_INTERVAL: + priv->multicast_querier_interval = g_value_get_uint64(value); + break; + case PROP_MULTICAST_QUERY_INTERVAL: + priv->multicast_query_interval = g_value_get_uint64(value); + break; + case PROP_MULTICAST_QUERY_RESPONSE_INTERVAL: + priv->multicast_query_response_interval = g_value_get_uint64(value); + break; + case PROP_MULTICAST_QUERY_USE_IFADDR: + priv->multicast_query_use_ifaddr = g_value_get_boolean(value); + break; + case PROP_MULTICAST_STARTUP_QUERY_COUNT: + priv->multicast_startup_query_count = g_value_get_uint(value); + break; + case PROP_MULTICAST_STARTUP_QUERY_INTERVAL: + priv->multicast_startup_query_interval = g_value_get_uint64(value); + break; + case PROP_VLAN_FILTERING: + priv->vlan_filtering = g_value_get_boolean(value); + break; + case PROP_VLAN_DEFAULT_PVID: + priv->vlan_default_pvid = g_value_get_uint(value); + break; + case PROP_VLAN_PROTOCOL: + g_free(priv->vlan_protocol); + priv->vlan_protocol = g_value_dup_string(value); + break; + case PROP_VLAN_STATS_ENABLED: + priv->vlan_stats_enabled = g_value_get_boolean(value); + break; + case PROP_VLANS: + g_ptr_array_unref(priv->vlans); + priv->vlans = _nm_utils_copy_array(g_value_get_boxed(value), + (NMUtilsCopyFunc) _nm_bridge_vlan_dup_and_seal, + (GDestroyNotify) nm_bridge_vlan_unref); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_bridge_init(NMSettingBridge *setting) +{ + NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE(setting); + + priv->vlans = g_ptr_array_new_with_free_func((GDestroyNotify) nm_bridge_vlan_unref); + + priv->ageing_time = NM_BRIDGE_AGEING_TIME_DEF; + priv->forward_delay = NM_BRIDGE_FORWARD_DELAY_DEF; + priv->hello_time = NM_BRIDGE_HELLO_TIME_DEF; + priv->max_age = NM_BRIDGE_MAX_AGE_DEF; + priv->multicast_last_member_count = NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF; + priv->multicast_last_member_interval = NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF; + priv->multicast_membership_interval = NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF; + priv->multicast_hash_max = NM_BRIDGE_MULTICAST_HASH_MAX_DEF; + priv->multicast_snooping = NM_BRIDGE_MULTICAST_SNOOPING_DEF; + priv->priority = NM_BRIDGE_PRIORITY_DEF; + priv->stp = NM_BRIDGE_STP_DEF; + priv->vlan_default_pvid = NM_BRIDGE_VLAN_DEFAULT_PVID_DEF; + priv->multicast_query_interval = NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF; + priv->multicast_query_response_interval = NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF; + priv->multicast_querier_interval = NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF; + priv->multicast_startup_query_count = NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF; + priv->multicast_startup_query_interval = NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF; + + nm_assert(priv->multicast_querier == NM_BRIDGE_MULTICAST_QUERIER_DEF); + nm_assert(priv->multicast_query_use_ifaddr == NM_BRIDGE_MULTICAST_QUERY_USE_IFADDR_DEF); + nm_assert(priv->vlan_stats_enabled == NM_BRIDGE_VLAN_STATS_ENABLED_DEF); +} + +/** + * nm_setting_bridge_new: + * + * Creates a new #NMSettingBridge object with default values. + * + * Returns: (transfer full): the new empty #NMSettingBridge object + **/ +NMSetting * +nm_setting_bridge_new(void) +{ + return g_object_new(NM_TYPE_SETTING_BRIDGE, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE(object); + + g_free(priv->mac_address); + g_free(priv->multicast_router); + g_free(priv->group_address); + g_free(priv->vlan_protocol); + g_ptr_array_unref(priv->vlans); + + G_OBJECT_CLASS(nm_setting_bridge_parent_class)->finalize(object); +} + +static void +nm_setting_bridge_class_init(NMSettingBridgeClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->compare_property = compare_property; + setting_class->verify = verify; + + /** + * NMSettingBridge:mac-address: + * + * If specified, the MAC address of bridge. When creating a new bridge, this + * MAC address will be set. + * + * If this field is left unspecified, the "ethernet.cloned-mac-address" is + * referred instead to generate the initial MAC address. Note that setting + * "ethernet.cloned-mac-address" anyway overwrites the MAC address of + * the bridge later while activating the bridge. Hence, this property + * is deprecated. + * + * Deprecated: 1.12: Use the ethernet.cloned-mac-address property instead. + **/ + /* ---keyfile--- + * property: mac-address + * format: usual hex-digits-and-colons notation + * description: MAC address in traditional hex-digits-and-colons notation, + * or semicolon separated list of 6 decimal bytes (obsolete) + * example: mac-address=00:22:68:12:79:A2 + * mac-address=0;34;104;18;121;162; + * ---end--- + * ---ifcfg-rh--- + * property: mac-address + * variable: BRIDGE_MACADDR(+) + * description: MAC address of the bridge. Note that this requires a recent + * kernel support, originally introduced in 3.15 upstream kernel) + * BRIDGE_MACADDR for bridges is an NM extension. + * ---end--- + */ + obj_properties[PROP_MAC_ADDRESS] = g_param_spec_string( + NM_SETTING_BRIDGE_MAC_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_MAC_ADDRESS], + &nm_sett_info_propert_type_mac_address); + + /** + * NMSettingBridge:stp: + * + * Controls whether Spanning Tree Protocol (STP) is enabled for this bridge. + **/ + /* ---ifcfg-rh--- + * property: stp + * variable: STP + * default: no + * description: Span tree protocol participation. + * ---end--- + */ + obj_properties[PROP_STP] = g_param_spec_boolean(NM_SETTING_BRIDGE_STP, + "", + "", + NM_BRIDGE_STP_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:priority: + * + * Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower + * values are "better"; the lowest priority bridge will be elected the root + * bridge. + **/ + /* ---ifcfg-rh--- + * property: priority + * variable: BRIDGING_OPTS: priority= + * values: 0 - 32768 + * default: 32768 + * description: STP priority. + * ---end--- + */ + obj_properties[PROP_PRIORITY] = + g_param_spec_uint(NM_SETTING_BRIDGE_PRIORITY, + "", + "", + NM_BRIDGE_PRIORITY_MIN, + NM_BRIDGE_PRIORITY_MAX, + NM_BRIDGE_PRIORITY_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:forward-delay: + * + * The Spanning Tree Protocol (STP) forwarding delay, in seconds. + **/ + /* ---ifcfg-rh--- + * property: forward-delay + * variable: DELAY + * values: 2 - 30 + * default: 15 + * description: STP forwarding delay. + * ---end--- + */ + obj_properties[PROP_FORWARD_DELAY] = + g_param_spec_uint(NM_SETTING_BRIDGE_FORWARD_DELAY, + "", + "", + 0, + NM_BRIDGE_FORWARD_DELAY_MAX, + NM_BRIDGE_FORWARD_DELAY_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:hello-time: + * + * The Spanning Tree Protocol (STP) hello time, in seconds. + **/ + /* ---ifcfg-rh--- + * property: hello-time + * variable: BRIDGING_OPTS: hello_time= + * values: 1 - 10 + * default: 2 + * description: STP hello time. + * ---end--- + */ + obj_properties[PROP_HELLO_TIME] = + g_param_spec_uint(NM_SETTING_BRIDGE_HELLO_TIME, + "", + "", + 0, + NM_BRIDGE_HELLO_TIME_MAX, + NM_BRIDGE_HELLO_TIME_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:max-age: + * + * The Spanning Tree Protocol (STP) maximum message age, in seconds. + **/ + /* ---ifcfg-rh--- + * property: max-age + * variable: BRIDGING_OPTS: max_age= + * values: 6 - 40 + * default: 20 + * description: STP maximum message age. + * ---end--- + */ + obj_properties[PROP_MAX_AGE] = + g_param_spec_uint(NM_SETTING_BRIDGE_MAX_AGE, + "", + "", + 0, + NM_BRIDGE_MAX_AGE_MAX, + NM_BRIDGE_MAX_AGE_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:ageing-time: + * + * The Ethernet MAC address aging time, in seconds. + **/ + /* ---ifcfg-rh--- + * property: ageing-time + * variable: BRIDGING_OPTS: ageing_time= + * values: 0 - 1000000 + * default: 300 + * description: Ethernet MAC ageing time. + * ---end--- + */ + obj_properties[PROP_AGEING_TIME] = + g_param_spec_uint(NM_SETTING_BRIDGE_AGEING_TIME, + "", + "", + NM_BRIDGE_AGEING_TIME_MIN, + NM_BRIDGE_AGEING_TIME_MAX, + NM_BRIDGE_AGEING_TIME_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:group-forward-mask: + * + * A mask of group addresses to forward. Usually, group addresses in + * the range from 01:80:C2:00:00:00 to 01:80:C2:00:00:0F are not + * forwarded according to standards. This property is a mask of 16 bits, + * each corresponding to a group address in that range that must be + * forwarded. The mask can't have bits 0, 1 or 2 set because they are + * used for STP, MAC pause frames and LACP. + * + * Since: 1.10 + **/ + obj_properties[PROP_GROUP_FORWARD_MASK] = + g_param_spec_uint(NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, + "", + "", + 0, + 0xFFFF, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-snooping: + * + * Controls whether IGMP snooping is enabled for this bridge. + * Note that if snooping was automatically disabled due to hash collisions, + * the system may refuse to enable the feature until the collisions are + * resolved. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: multicast-snooping + * variable: BRIDGING_OPTS: multicast_snooping= + * values: 0 or 1 + * default: 1 + * description: IGMP snooping support. + * ---end--- + */ + obj_properties[PROP_MULTICAST_SNOOPING] = g_param_spec_boolean( + NM_SETTING_BRIDGE_MULTICAST_SNOOPING, + "", + "", + NM_BRIDGE_MULTICAST_SNOOPING_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:vlan-filtering: + * + * Control whether VLAN filtering is enabled on the bridge. + * + * Since: 1.18 + **/ + /* ---ifcfg-rh--- + * property: vlan-filtering + * variable: BRIDGING_OPTS: vlan_filtering= + * values: 0 or 1 + * default: 0 + * description: VLAN filtering support. + * ---end--- + */ + obj_properties[PROP_VLAN_FILTERING] = g_param_spec_boolean( + NM_SETTING_BRIDGE_VLAN_FILTERING, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:vlan-default-pvid: + * + * The default PVID for the ports of the bridge, that is the VLAN id + * assigned to incoming untagged frames. + * + * Since: 1.18 + **/ + /* ---ifcfg-rh--- + * property: vlan-default-pvid + * variable: BRIDGING_OPTS: default_pvid= + * values: 0 - 4094 + * default: 1 + * description: default VLAN PVID. + * ---end--- + */ + obj_properties[PROP_VLAN_DEFAULT_PVID] = + g_param_spec_uint(NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, + "", + "", + 0, + NM_BRIDGE_VLAN_VID_MAX, + NM_BRIDGE_VLAN_DEFAULT_PVID_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:vlans: (type GPtrArray(NMBridgeVlan)) + * + * Array of bridge VLAN objects. In addition to the VLANs + * specified here, the bridge will also have the default-pvid + * VLAN configured by the bridge.vlan-default-pvid property. + * + * In nmcli the VLAN list can be specified with the following + * syntax: + * + * $vid [pvid] [untagged] [, $vid [pvid] [untagged]]... + * + * where $vid is either a single id between 1 and 4094 or a + * range, represented as a couple of ids separated by a dash. + * + * Since: 1.18 + **/ + /* ---ifcfg-rh--- + * property: vlans + * variable: BRIDGE_VLANS + * description: List of VLANs on the bridge + * example: BRIDGE_VLANS="1 pvid untagged,20,300-400 untagged" + * ---end--- + */ + obj_properties[PROP_VLANS] = g_param_spec_boxed(NM_SETTING_BRIDGE_VLANS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_VLANS], + &nm_sett_info_propert_type_bridge_vlans); + + /* ---dbus--- + * property: interface-name + * format: string + * description: Deprecated in favor of connection.interface-name, but can + * be used for backward-compatibility with older daemons, to set the + * bridge's interface name. + * ---end--- + */ + _nm_properties_override_dbus(properties_override, + "interface-name", + &nm_sett_info_propert_type_deprecated_interface_name); + + /** + * NMSettingBridge:group-address: + * + * If specified, The MAC address of the multicast group this bridge uses for STP. + * + * The address must be a link-local address in standard Ethernet MAC address format, + * ie an address of the form 01:80:C2:00:00:0X, with X in [0, 4..F]. + * If not specified the default value is 01:80:C2:00:00:00. + * + * Since: 1.24 + **/ + /* ---ifcfg-rh--- + * property: group-address + * variable: BRIDGING_OPTS: group_address= + * description: STP group address. + * example: BRIDGING_OPTS="group_address=01:80:C2:00:00:0A" + * ---end--- + */ + obj_properties[PROP_GROUP_ADDRESS] = g_param_spec_string( + NM_SETTING_BRIDGE_GROUP_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_GROUP_ADDRESS], + &nm_sett_info_propert_type_mac_address); + + /** + * NMSettingBridge:vlan-protocol: + * + * If specified, the protocol used for VLAN filtering. + * + * Supported values are: '802.1Q', '802.1ad'. + * If not specified the default value is '802.1Q'. + * + * Since: 1.24 + **/ + /* ---ifcfg-rh--- + * property: vlan-protocol + * variable: BRIDGING_OPTS: vlan_protocol= + * description: VLAN filtering protocol. + * example: BRIDGING_OPTS="vlan_protocol=802.1Q" + * ---end--- + * + * Since: 1.24 + */ + obj_properties[PROP_VLAN_PROTOCOL] = g_param_spec_string( + NM_SETTING_BRIDGE_VLAN_PROTOCOL, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:vlan-stats-enabled: + * + * Controls whether per-VLAN stats accounting is enabled. + **/ + /* ---ifcfg-rh--- + * property: vlan-stats-enabled + * variable: BRIDGING_OPTS: vlan_stats_enabled= + * default: 0 + * example: BRIDGING_OPTS="vlan_stats_enabled=1" + * ---end--- + * + * Since: 1.24 + */ + obj_properties[PROP_VLAN_STATS_ENABLED] = g_param_spec_boolean( + NM_SETTING_BRIDGE_VLAN_STATS_ENABLED, + "", + "", + NM_BRIDGE_VLAN_STATS_ENABLED_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-router: + * + * Sets bridge's multicast router. Multicast-snooping must be enabled + * for this option to work. + * + * Supported values are: 'auto', 'disabled', 'enabled' to which kernel + * assigns the numbers 1, 0, and 2, respectively. + * If not specified the default value is 'auto' (1). + **/ + /* ---ifcfg-rh--- + * property: multicast-router + * variable: BRIDGING_OPTS: multicast_router= + * values: auto, enabled, disabled + * default: auto + * example: BRIDGING_OPTS="multicast_router=enabled" + * ---end--- + * + * Since: 1.24 + */ + obj_properties[PROP_MULTICAST_ROUTER] = g_param_spec_string( + NM_SETTING_BRIDGE_MULTICAST_ROUTER, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-query-use-ifaddr: + * + * If enabled the bridge's own IP address is used as + * the source address for IGMP queries otherwise + * the default of 0.0.0.0 is used. + **/ + /* ---ifcfg-rh--- + * property: multicast-query-use-ifaddr + * variable: BRIDGING_OPTS: multicast_query_use_ifaddr= + * default: 0 + * example: BRIDGING_OPTS="multicast_query-use_ifaddr=1" + * ---end--- + * + * Since: 1.24 + */ + obj_properties[PROP_MULTICAST_QUERY_USE_IFADDR] = g_param_spec_boolean( + NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR, + "", + "", + NM_BRIDGE_MULTICAST_QUERY_USE_IFADDR_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-querier: + * + * Enable or disable sending of multicast queries by the bridge. + * If not specified the option is disabled. + **/ + /* ---ifcfg-rh--- + * property: multicast-querier + * variable: BRIDGING_OPTS: multicast_querier= + * default: 0 + * example: BRIDGING_OPTS="multicast_querier=1" + * ---end--- + * + * Since: 1.24 + */ + obj_properties[PROP_MULTICAST_QUERIER] = g_param_spec_boolean( + NM_SETTING_BRIDGE_MULTICAST_QUERIER, + "", + "", + NM_BRIDGE_MULTICAST_QUERIER_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-hash-max: + * + * Set maximum size of multicast hash table (value must be a power of 2). + **/ + /* ---ifcfg-rh--- + * property: multicast-hash-max + * variable: BRIDGING_OPTS: multicast_hash_max= + * default: 4096 + * example: BRIDGING_OPTS="multicast_hash_max=8192" + * ---end--- + * + * Since: 1.26 + */ + obj_properties[PROP_MULTICAST_HASH_MAX] = + g_param_spec_uint(NM_SETTING_BRIDGE_MULTICAST_HASH_MAX, + "", + "", + NM_BRIDGE_MULTICAST_HASH_MAX_MIN, + NM_BRIDGE_MULTICAST_HASH_MAX_MAX, + NM_BRIDGE_MULTICAST_HASH_MAX_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-last-member-count: + * + * Set the number of queries the bridge will send before + * stopping forwarding a multicast group after a "leave" + * message has been received. + **/ + /* ---ifcfg-rh--- + * property: multicast-last-member-count + * variable: BRIDGING_OPTS: multicast_last_member_count= + * default: 2 + * example: BRIDGING_OPTS="multicast_last_member_count=4" + * ---end--- + * + * Since: 1.26 + */ + obj_properties[PROP_MULTICAST_LAST_MEMBER_COUNT] = + g_param_spec_uint(NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT, + "", + "", + NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_MIN, + NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_MAX, + NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-last-member-interval: + * + * Set interval (in deciseconds) between queries to find remaining + * members of a group, after a "leave" message is received. + **/ + /* ---ifcfg-rh--- + * property: multicast-last-member-interval + * variable: BRIDGING_OPTS: multicast_last_member_interval= + * default: 100 + * example: BRIDGING_OPTS="multicast_last_member_interval=200" + * ---end--- + * + * Since: 1.26 + */ + obj_properties[PROP_MULTICAST_LAST_MEMBER_INTERVAL] = g_param_spec_uint64( + NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL, + "", + "", + NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-membership-interval: + * + * Set delay (in deciseconds) after which the bridge will + * leave a group, if no membership reports for this + * group are received. + **/ + /* ---ifcfg-rh--- + * property: multicast-membership-interval + * variable: BRIDGING_OPTS: multicast_membership_interval= + * default: 26000 + * example: BRIDGING_OPTS="multicast_membership_interval=16000" + * ---end--- + * + * Since: 1.26 + */ + obj_properties[PROP_MULTICAST_MEMBERSHIP_INTERVAL] = g_param_spec_uint64( + NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL, + "", + "", + NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-querier-interval: + * + * If no queries are seen after this delay (in deciseconds) has passed, + * the bridge will start to send its own queries. + **/ + /* ---ifcfg-rh--- + * property: multicast-querier-interval + * variable: BRIDGING_OPTS: multicast_querier_interval= + * default: 25500 + * example: BRIDGING_OPTS="multicast_querier_interval=20000" + * ---end--- + * + * Since: 1.26 + */ + obj_properties[PROP_MULTICAST_QUERIER_INTERVAL] = g_param_spec_uint64( + NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL, + "", + "", + NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-query-interval: + * + * Interval (in deciseconds) between queries sent + * by the bridge after the end of the startup phase. + **/ + /* ---ifcfg-rh--- + * property: multicast-query-interval + * variable: BRIDGING_OPTS: multicast_query_interval= + * default: 12500 + * example: BRIDGING_OPTS="multicast_query_interval=22500" + * ---end--- + * + * Since: 1.26 + */ + obj_properties[PROP_MULTICAST_QUERY_INTERVAL] = g_param_spec_uint64( + NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL, + "", + "", + NM_BRIDGE_MULTICAST_QUERY_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_QUERY_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-query-response-interval: + * + * Set the Max Response Time/Max Response Delay + * (in deciseconds) for IGMP/MLD queries sent by the bridge. + **/ + /* ---ifcfg-rh--- + * property: multicast-query-response-interval + * variable: BRIDGING_OPTS: multicast_query_response_interval= + * default: 1000 + * example: BRIDGING_OPTS="multicast_query_response_interval=2000" + * ---end--- + * + * Since: 1.26 + */ + obj_properties[PROP_MULTICAST_QUERY_RESPONSE_INTERVAL] = g_param_spec_uint64( + NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL, + "", + "", + NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-startup-query-count: + * + * Set the number of IGMP queries to send during startup phase. + **/ + /* ---ifcfg-rh--- + * property: multicast-startup-query-count + * variable: BRIDGING_OPTS: multicast_startup_query_count= + * default: 2 + * example: BRIDGING_OPTS="multicast_startup_query_count=4" + * ---end--- + * + * Since: 1.26 + */ + obj_properties[PROP_MULTICAST_STARTUP_QUERY_COUNT] = + g_param_spec_uint(NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT, + "", + "", + NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_MIN, + NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_MAX, + NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingBridge:multicast-startup-query-interval: + * + * Sets the time (in deciseconds) between queries sent out + * at startup to determine membership information. + **/ + /* ---ifcfg-rh--- + * property: multicast-startup-query-interval + * variable: BRIDGING_OPTS: multicast_startup_query_interval= + * default: 3125 + * example: BRIDGING_OPTS="multicast_startup_query_interval=4000" + * ---end--- + * + * Since: 1.26 + */ + obj_properties[PROP_MULTICAST_STARTUP_QUERY_INTERVAL] = g_param_spec_uint64( + NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL, + "", + "", + NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_BRIDGE, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-cdma.c b/src/libnm-core-impl/nm-setting-cdma.c new file mode 100644 index 0000000..bb30d10 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-cdma.c @@ -0,0 +1,358 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2013 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-cdma.h" + +#include "nm-utils.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-cdma + * @short_description: Describes CDMA-based mobile broadband properties + * + * The #NMSettingCdma object is a #NMSetting subclass that describes + * properties that allow connections to IS-95-based mobile broadband + * networks, including those using CDMA2000/EVDO technology. + */ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_NUMBER, + PROP_USERNAME, + PROP_PASSWORD, + PROP_PASSWORD_FLAGS, + PROP_MTU, ); + +typedef struct { + char * number; /* For dialing, duh */ + char * username; + char * password; + guint32 mtu; + NMSettingSecretFlags password_flags; +} NMSettingCdmaPrivate; + +G_DEFINE_TYPE(NMSettingCdma, nm_setting_cdma, NM_TYPE_SETTING) + +#define NM_SETTING_CDMA_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_CDMA, NMSettingCdmaPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_cdma_get_number: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingCdma:number property of the setting + **/ +const char * +nm_setting_cdma_get_number(NMSettingCdma *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CDMA(setting), NULL); + + return NM_SETTING_CDMA_GET_PRIVATE(setting)->number; +} + +/** + * nm_setting_cdma_get_username: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingCdma:username property of the setting + **/ +const char * +nm_setting_cdma_get_username(NMSettingCdma *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CDMA(setting), NULL); + + return NM_SETTING_CDMA_GET_PRIVATE(setting)->username; +} + +/** + * nm_setting_cdma_get_password: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingCdma:password property of the setting + **/ +const char * +nm_setting_cdma_get_password(NMSettingCdma *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CDMA(setting), NULL); + + return NM_SETTING_CDMA_GET_PRIVATE(setting)->password; +} + +/** + * nm_setting_cdma_get_password_flags: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingCdma:password + **/ +NMSettingSecretFlags +nm_setting_cdma_get_password_flags(NMSettingCdma *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CDMA(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_CDMA_GET_PRIVATE(setting)->password_flags; +} + +/** + * nm_setting_cdma_get_mtu: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingCdma:mtu property of the setting + * + * Since: 1.8 + **/ +guint32 +nm_setting_cdma_get_mtu(NMSettingCdma *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CDMA(setting), 0); + + return NM_SETTING_CDMA_GET_PRIVATE(setting)->mtu; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE(setting); + + if (!priv->number) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_NUMBER); + return FALSE; + } else if (!strlen(priv->number)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_NUMBER); + return FALSE; + } + + if (priv->username && !strlen(priv->username)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_USERNAME); + return FALSE; + } + + return TRUE; +} + +static gboolean +verify_secrets(NMSetting *setting, NMConnection *connection, GError **error) +{ + return _nm_setting_verify_secret_string(NM_SETTING_CDMA_GET_PRIVATE(setting)->password, + NM_SETTING_CDMA_SETTING_NAME, + NM_SETTING_CDMA_PASSWORD, + error); +} + +static GPtrArray * +need_secrets(NMSetting *setting) +{ + NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE(setting); + GPtrArray * secrets = NULL; + + if (priv->password && *priv->password) + return NULL; + + if (priv->username) { + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new(1); + g_ptr_array_add(secrets, NM_SETTING_CDMA_PASSWORD); + } + } + + return secrets; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingCdma *setting = NM_SETTING_CDMA(object); + + switch (prop_id) { + case PROP_NUMBER: + g_value_set_string(value, nm_setting_cdma_get_number(setting)); + break; + case PROP_USERNAME: + g_value_set_string(value, nm_setting_cdma_get_username(setting)); + break; + case PROP_PASSWORD: + g_value_set_string(value, nm_setting_cdma_get_password(setting)); + break; + case PROP_PASSWORD_FLAGS: + g_value_set_flags(value, nm_setting_cdma_get_password_flags(setting)); + break; + case PROP_MTU: + g_value_set_uint(value, nm_setting_cdma_get_mtu(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_NUMBER: + g_free(priv->number); + priv->number = g_value_dup_string(value); + break; + case PROP_USERNAME: + g_free(priv->username); + priv->username = g_value_dup_string(value); + break; + case PROP_PASSWORD: + g_free(priv->password); + priv->password = g_value_dup_string(value); + break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_flags(value); + break; + case PROP_MTU: + priv->mtu = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_cdma_init(NMSettingCdma *setting) +{} + +/** + * nm_setting_cdma_new: + * + * Creates a new #NMSettingCdma object with default values. + * + * Returns: the new empty #NMSettingCdma object + **/ +NMSetting * +nm_setting_cdma_new(void) +{ + return g_object_new(NM_TYPE_SETTING_CDMA, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE(object); + + g_free(priv->number); + g_free(priv->username); + g_free(priv->password); + + G_OBJECT_CLASS(nm_setting_cdma_parent_class)->finalize(object); +} + +static void +nm_setting_cdma_class_init(NMSettingCdmaClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingCdmaPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->verify_secrets = verify_secrets; + setting_class->need_secrets = need_secrets; + + /** + * NMSettingCdma:number: + * + * The number to dial to establish the connection to the CDMA-based mobile + * broadband network, if any. If not specified, the default number (#777) + * is used when required. + **/ + obj_properties[PROP_NUMBER] = g_param_spec_string(NM_SETTING_CDMA_NUMBER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingCdma:username: + * + * The username used to authenticate with the network, if required. Many + * providers do not require a username, or accept any username. But if a + * username is required, it is specified here. + **/ + obj_properties[PROP_USERNAME] = g_param_spec_string(NM_SETTING_CDMA_USERNAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingCdma:password: + * + * The password used to authenticate with the network, if required. Many + * providers do not require a password, or accept any password. But if a + * password is required, it is specified here. + **/ + obj_properties[PROP_PASSWORD] = + g_param_spec_string(NM_SETTING_CDMA_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingCdma:password-flags: + * + * Flags indicating how to handle the #NMSettingCdma:password property. + **/ + obj_properties[PROP_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_CDMA_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingCdma:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple frames. + * + * Since: 1.8 + **/ + obj_properties[PROP_MTU] = g_param_spec_uint(NM_SETTING_CDMA_MTU, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_CDMA); +} diff --git a/src/libnm-core-impl/nm-setting-connection.c b/src/libnm-core-impl/nm-setting-connection.c new file mode 100644 index 0000000..241a871 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-connection.c @@ -0,0 +1,2529 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-connection.h" + +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-core-enum-types.h" +#include "nm-connection-private.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-team.h" +#include "nm-setting-vlan.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" + +/** + * SECTION:nm-setting-connection + * @short_description: Describes general connection properties + * + * The #NMSettingConnection object is a #NMSetting subclass that describes + * properties that apply to all #NMConnection objects, regardless of what type + * of network connection they describe. Each #NMConnection object must contain + * a #NMSettingConnection setting. + **/ + +/*****************************************************************************/ + +typedef enum _nm_packed { + PERM_TYPE_INVALID, + PERM_TYPE_USER, +} PermType; + +typedef struct { + PermType ptype; + char * item; +} Permission; + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingConnection, + PROP_ID, + PROP_UUID, + PROP_INTERFACE_NAME, + PROP_TYPE, + PROP_PERMISSIONS, + PROP_AUTOCONNECT, + PROP_AUTOCONNECT_PRIORITY, + PROP_AUTOCONNECT_RETRIES, + PROP_MULTI_CONNECT, + PROP_TIMESTAMP, + PROP_READ_ONLY, + PROP_ZONE, + PROP_MASTER, + PROP_SLAVE_TYPE, + PROP_AUTOCONNECT_SLAVES, + PROP_SECONDARIES, + PROP_GATEWAY_PING_TIMEOUT, + PROP_METERED, + PROP_LLDP, + PROP_MDNS, + PROP_LLMNR, + PROP_STABLE_ID, + PROP_AUTH_RETRIES, + PROP_WAIT_DEVICE_TIMEOUT, + PROP_MUD_URL, ); + +typedef struct { + GArray *permissions; + GSList *secondaries; /* secondary connections to activate with the base connection */ + char * id; + char * uuid; + char * stable_id; + char * interface_name; + char * type; + char * master; + char * slave_type; + char * zone; + char * mud_url; + guint64 timestamp; + int autoconnect_priority; + int autoconnect_retries; + int multi_connect; + int auth_retries; + int mdns; + int llmnr; + int wait_device_timeout; + guint gateway_ping_timeout; + NMSettingConnectionAutoconnectSlaves autoconnect_slaves; + NMMetered metered; + NMSettingConnectionLldp lldp; + bool read_only : 1; + bool autoconnect : 1; +} NMSettingConnectionPrivate; + +G_DEFINE_TYPE(NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING) + +#define NM_SETTING_CONNECTION_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionPrivate)) + +/*****************************************************************************/ + +static void +_permission_set_stale(Permission *permission, PermType ptype, char *item_take) +{ + nm_assert(permission); + nm_assert(NM_IN_SET(ptype, PERM_TYPE_INVALID, PERM_TYPE_USER)); + nm_assert(ptype != PERM_TYPE_USER + || nm_settings_connection_validate_permission_user(item_take, -1)); + + /* we don't inspect (clear) permission before setting. It takes a + * stale instance. */ + *permission = (Permission){ + .ptype = ptype, + .item = item_take, + }; +} + +static void +_permission_clear_stale(Permission *permission) +{ + g_free(permission->item); + /* We leave the permission instance with dangling pointers. + * It is "stale". */ +} + +static gboolean +_permission_set_stale_parse(Permission *permission, const char *str) +{ + const char *str0 = str; + const char *last_colon; + gsize ulen; + + nm_assert(str); + + if (!str) + goto invalid; + + if (!NM_STR_HAS_PREFIX(str, NM_SETTINGS_CONNECTION_PERMISSION_USER_PREFIX)) + goto invalid; + + str += NM_STRLEN(NM_SETTINGS_CONNECTION_PERMISSION_USER_PREFIX); + + last_colon = strrchr(str, ':'); + if (last_colon) { + /* Reject :[detail] for now */ + if (last_colon[1] != '\0') + goto invalid; + ulen = last_colon - str; + } else + ulen = strlen(str); + + if (!nm_settings_connection_validate_permission_user(str, ulen)) + goto invalid; + + /* Yay, valid... create the new permission */ + if (permission) + _permission_set_stale(permission, PERM_TYPE_USER, g_strndup(str, ulen)); + return TRUE; + +invalid: + if (permission) + _permission_set_stale(permission, PERM_TYPE_INVALID, g_strdup(str0)); + return FALSE; +} + +static char * +_permission_to_string(Permission *permission) +{ + nm_assert(permission); + + switch (permission->ptype) { + case PERM_TYPE_USER: + return g_strdup_printf(NM_SETTINGS_CONNECTION_PERMISSION_USER_PREFIX "%s:", + permission->item); + case PERM_TYPE_INVALID: + nm_assert(permission->item); + return g_strdup(permission->item); + } + nm_assert_not_reached(); + return g_strdup(permission->item ?: ""); +} + +/*****************************************************************************/ + +/** + * nm_setting_connection_get_id: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:id property of the connection. + * + * Returns: the connection ID + **/ +const char * +nm_setting_connection_get_id(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->id; +} + +/** + * nm_setting_connection_get_uuid: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:uuid property of the connection. + * + * Returns: the connection UUID + **/ +const char * +nm_setting_connection_get_uuid(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->uuid; +} + +/** + * nm_setting_connection_get_stable_id: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:stable_id property of the connection. + * + * Returns: the stable-id for the connection + * + * Since: 1.4 + **/ +const char * +nm_setting_connection_get_stable_id(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->stable_id; +} + +/** + * nm_setting_connection_get_interface_name: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:interface-name property of the connection. + * + * Returns: the connection's interface name + **/ +const char * +nm_setting_connection_get_interface_name(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->interface_name; +} + +/** + * nm_setting_connection_get_connection_type: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:type property of the connection. + * + * Returns: the connection type + **/ +const char * +nm_setting_connection_get_connection_type(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->type; +} + +/** + * nm_setting_connection_get_num_permissions: + * @setting: the #NMSettingConnection + * + * Returns the number of entries in the #NMSettingConnection:permissions + * property of this setting. + * + * Returns: the number of permissions entries + */ +guint32 +nm_setting_connection_get_num_permissions(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), 0); + + return nm_g_array_len(NM_SETTING_CONNECTION_GET_PRIVATE(setting)->permissions); +} + +/** + * nm_setting_connection_get_permission: + * @setting: the #NMSettingConnection + * @idx: the zero-based index of the permissions entry + * @out_ptype: on return, the permission type. This is currently always "user", + * unless the entry is invalid, in which case it returns "invalid". + * @out_pitem: on return, the permission item (formatted according to @ptype, see + * #NMSettingConnection:permissions for more detail + * @out_detail: on return, the permission detail (at this time, always %NULL) + * + * Retrieve one of the entries of the #NMSettingConnection:permissions property + * of this setting. + * + * Returns: %TRUE if a permission was returned, %FALSE if @idx was invalid + */ +gboolean +nm_setting_connection_get_permission(NMSettingConnection *setting, + guint32 idx, + const char ** out_ptype, + const char ** out_pitem, + const char ** out_detail) +{ + NMSettingConnectionPrivate *priv; + Permission * permission; + + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + + g_return_val_if_fail(idx < nm_g_array_len(priv->permissions), FALSE); + + permission = &g_array_index(priv->permissions, Permission, idx); + switch (permission->ptype) { + case PERM_TYPE_USER: + NM_SET_OUT(out_ptype, NM_SETTINGS_CONNECTION_PERMISSION_USER); + NM_SET_OUT(out_pitem, permission->item); + NM_SET_OUT(out_detail, NULL); + return TRUE; + case PERM_TYPE_INVALID: + goto invalid; + } + nm_assert_not_reached(); +invalid: + NM_SET_OUT(out_ptype, "invalid"); + NM_SET_OUT(out_pitem, permission->item); + NM_SET_OUT(out_detail, NULL); + return TRUE; +} + +/** + * nm_setting_connection_permissions_user_allowed: + * @setting: the #NMSettingConnection + * @uname: the user name to check permissions for + * + * Checks whether the given username is allowed to view/access this connection. + * + * Returns: %TRUE if the requested user is allowed to view this connection, + * %FALSE if the given user is not allowed to view this connection + */ +gboolean +nm_setting_connection_permissions_user_allowed(NMSettingConnection *setting, const char *uname) +{ + NMSettingConnectionPrivate *priv; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + g_return_val_if_fail(uname != NULL, FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + + if (nm_g_array_len(priv->permissions) == 0) { + /* If no permissions, visible to all */ + return TRUE; + } + + for (i = 0; i < priv->permissions->len; i++) { + const Permission *permission = &g_array_index(priv->permissions, Permission, i); + + if (permission->ptype == PERM_TYPE_USER && nm_streq(permission->item, uname)) + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_connection_add_permission: + * @setting: the #NMSettingConnection + * @ptype: the permission type; at this time only "user" is supported + * @pitem: the permission item formatted as required for @ptype + * @detail: (allow-none): unused at this time; must be %NULL + * + * Adds a permission to the connection's permission list. At this time, only + * the "user" permission type is supported, and @pitem must be a username. See + * #NMSettingConnection:permissions: for more details. + * + * Returns: %TRUE if the permission was unique and was successfully added to the + * list, %FALSE if @ptype or @pitem was invalid. + * If the permission was already present in the list, it will not be added + * a second time but %TRUE will be returned. Note that before 1.28, in this + * case %FALSE would be returned. + */ +gboolean +nm_setting_connection_add_permission(NMSettingConnection *setting, + const char * ptype, + const char * pitem, + const char * detail) +{ + NMSettingConnectionPrivate *priv; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + g_return_val_if_fail(ptype, FALSE); + g_return_val_if_fail(pitem, FALSE); + + if (!nm_streq0(ptype, NM_SETTINGS_CONNECTION_PERMISSION_USER)) + return FALSE; + + if (!nm_settings_connection_validate_permission_user(pitem, -1)) + return FALSE; + + if (detail) + return FALSE; + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + + if (!priv->permissions) { + priv->permissions = g_array_sized_new(FALSE, FALSE, sizeof(Permission), 1); + g_array_set_clear_func(priv->permissions, (GDestroyNotify) _permission_clear_stale); + } + + for (i = 0; i < priv->permissions->len; i++) { + const Permission *permission = &g_array_index(priv->permissions, Permission, i); + + if (permission->ptype == PERM_TYPE_USER && nm_streq(permission->item, pitem)) + return TRUE; + } + + _permission_set_stale(nm_g_array_append_new(priv->permissions, Permission), + PERM_TYPE_USER, + g_strdup(pitem)); + _notify(setting, PROP_PERMISSIONS); + return TRUE; +} + +/** + * nm_setting_connection_remove_permission: + * @setting: the #NMSettingConnection + * @idx: the zero-based index of the permission to remove + * + * Removes the permission at index @idx from the connection. + */ +void +nm_setting_connection_remove_permission(NMSettingConnection *setting, guint32 idx) +{ + NMSettingConnectionPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_CONNECTION(setting)); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + + g_return_if_fail(idx < nm_g_array_len(priv->permissions)); + + g_array_remove_index(priv->permissions, idx); + + _notify(setting, PROP_PERMISSIONS); +} + +/** + * nm_setting_connection_remove_permission_by_value: + * @setting: the #NMSettingConnection + * @ptype: the permission type; at this time only "user" is supported + * @pitem: the permission item formatted as required for @ptype + * @detail: (allow-none): unused at this time; must be %NULL + * + * Removes the permission from the connection. + * At this time, only the "user" permission type is supported, and @pitem must + * be a username. See #NMSettingConnection:permissions: for more details. + * + * Returns: %TRUE if the permission was found and removed; %FALSE if it was not. + */ +gboolean +nm_setting_connection_remove_permission_by_value(NMSettingConnection *setting, + const char * ptype, + const char * pitem, + const char * detail) +{ + NMSettingConnectionPrivate *priv; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + g_return_val_if_fail(ptype, FALSE); + g_return_val_if_fail(pitem, FALSE); + + if (!nm_streq0(ptype, NM_SETTINGS_CONNECTION_PERMISSION_USER)) + return FALSE; + + if (detail) + return FALSE; + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + if (priv->permissions) { + for (i = 0; i < priv->permissions->len; i++) { + const Permission *permission = &g_array_index(priv->permissions, Permission, i); + + if (permission->ptype == PERM_TYPE_USER && nm_streq(permission->item, pitem)) { + g_array_remove_index(priv->permissions, i); + _notify(setting, PROP_PERMISSIONS); + return TRUE; + } + } + } + return FALSE; +} + +/** + * nm_setting_connection_get_autoconnect: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:autoconnect property of the connection. + * + * Returns: the connection's autoconnect behavior + **/ +gboolean +nm_setting_connection_get_autoconnect(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->autoconnect; +} + +/** + * nm_setting_connection_get_autoconnect_priority: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:autoconnect-priority property of the connection. + * The higher number, the higher priority. + * + * Returns: the connection's autoconnect priority + **/ +int +nm_setting_connection_get_autoconnect_priority(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), 0); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->autoconnect_priority; +} + +/** + * nm_setting_connection_get_autoconnect_retries: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:autoconnect-retries property of the connection. + * Zero means infinite, -1 means the global default value. + * + * Returns: the connection's autoconnect retries + * + * Since: 1.6 + **/ +int +nm_setting_connection_get_autoconnect_retries(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), -1); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->autoconnect_retries; +} + +/** + * nm_setting_connection_get_multi_connect: + * @setting: the #NMSettingConnection + * + * Returns: the #NMSettingConnection:multi-connect property of the connection. + * + * Since: 1.14 + **/ +NMConnectionMultiConnect +nm_setting_connection_get_multi_connect(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), -1); + + return (NMConnectionMultiConnect) NM_SETTING_CONNECTION_GET_PRIVATE(setting)->multi_connect; +} + +/** + * nm_setting_connection_get_auth_retries: + * @setting: the #NMSettingConnection + * + * Returns the value contained in the #NMSettingConnection:auth-retries property. + * + * Returns: the configured authentication retries. Zero means + * infinity and -1 means a global default value. + * + * Since: 1.10 + **/ +int +nm_setting_connection_get_auth_retries(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), -1); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->auth_retries; +} + +/** + * nm_setting_connection_get_timestamp: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:timestamp property of the connection. + * + * Returns: the connection's timestamp + **/ +guint64 +nm_setting_connection_get_timestamp(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), 0); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->timestamp; +} + +static GVariant * +_to_dbus_fcn_timestamp(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + guint64 v; + + v = options && options->timestamp.has ? options->timestamp.val + : NM_SETTING_CONNECTION_GET_PRIVATE(setting)->timestamp; + + if (v == 0u) + return NULL; + + return g_variant_new_uint64(v); +} + +/** + * nm_setting_connection_get_read_only: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:read-only property of the connection. + * + * Returns: %TRUE if the connection is read-only, %FALSE if it is not + **/ +gboolean +nm_setting_connection_get_read_only(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), TRUE); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->read_only; +} + +/** + * nm_setting_connection_get_zone: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:zone property of the connection. + * + * Returns: the trust level of a connection + **/ +const char * +nm_setting_connection_get_zone(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->zone; +} + +/** + * nm_setting_connection_get_master: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:master property of the connection. + * + * Returns: interface name of the master device or UUID of the master + * connection. + */ +const char * +nm_setting_connection_get_master(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->master; +} + +/** + * nm_setting_connection_get_slave_type: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:slave-type property of the connection. + * + * Returns: the type of slave this connection is, if any + */ +const char * +nm_setting_connection_get_slave_type(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->slave_type; +} + +/** + * nm_setting_connection_is_slave_type: + * @setting: the #NMSettingConnection + * @type: the setting name (ie #NM_SETTING_BOND_SETTING_NAME) to be matched + * against @setting's slave type + * + * Returns: %TRUE if connection is of the given slave @type + */ +gboolean +nm_setting_connection_is_slave_type(NMSettingConnection *setting, const char *type) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + + return !g_strcmp0(NM_SETTING_CONNECTION_GET_PRIVATE(setting)->slave_type, type); +} + +/** + * nm_setting_connection_get_wait_device_timeout: + * @setting: the #NMSettingConnection + * + * Returns: the %NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT property with + * the timeout in milliseconds. -1 is the default. + * + * Since: 1.20 + */ +gint32 +nm_setting_connection_get_wait_device_timeout(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), -1); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->wait_device_timeout; +} + +/** + * nm_setting_connection_get_autoconnect_slaves: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:autoconnect-slaves property of the connection. + * + * Returns: whether slaves of the connection should be activated together + * with the connection. + * + * Since: 1.2 + **/ +NMSettingConnectionAutoconnectSlaves +nm_setting_connection_get_autoconnect_slaves(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), + NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->autoconnect_slaves; +} + +/** + * nm_setting_connection_get_num_secondaries: + * @setting: the #NMSettingConnection + * + * Returns: the number of configured secondary connection UUIDs + **/ +guint32 +nm_setting_connection_get_num_secondaries(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), 0); + + return g_slist_length(NM_SETTING_CONNECTION_GET_PRIVATE(setting)->secondaries); +} + +/** + * nm_setting_connection_get_secondary: + * @setting: the #NMSettingConnection + * @idx: the zero-based index of the secondary connection UUID entry + * + * Returns: the secondary connection UUID at index @idx + **/ +const char * +nm_setting_connection_get_secondary(NMSettingConnection *setting, guint32 idx) +{ + NMSettingConnectionPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + g_return_val_if_fail(idx <= g_slist_length(priv->secondaries), NULL); + + return (const char *) g_slist_nth_data(priv->secondaries, idx); +} + +/** + * nm_setting_connection_get_mud_url: + * @setting: the #NMSettingConnection + * + * Returns the value contained in the #NMSettingConnection:mud-url + * property. + * + * Since: 1.26 + **/ +const char * +nm_setting_connection_get_mud_url(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->mud_url; +} + +/** + * nm_setting_connection_add_secondary: + * @setting: the #NMSettingConnection + * @sec_uuid: the secondary connection UUID to add + * + * Adds a new secondary connection UUID to the setting. + * + * Returns: %TRUE if the secondary connection UUID was added; %FALSE if the UUID + * was already present + **/ +gboolean +nm_setting_connection_add_secondary(NMSettingConnection *setting, const char *sec_uuid) +{ + NMSettingConnectionPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + g_return_val_if_fail(sec_uuid != NULL, FALSE); + g_return_val_if_fail(sec_uuid[0] != '\0', FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + for (iter = priv->secondaries; iter; iter = g_slist_next(iter)) { + if (!strcmp(sec_uuid, (char *) iter->data)) + return FALSE; + } + + priv->secondaries = g_slist_append(priv->secondaries, g_strdup(sec_uuid)); + _notify(setting, PROP_SECONDARIES); + return TRUE; +} + +/** + * nm_setting_connection_remove_secondary: + * @setting: the #NMSettingConnection + * @idx: index number of the secondary connection UUID + * + * Removes the secondary connection UUID at index @idx. + **/ +void +nm_setting_connection_remove_secondary(NMSettingConnection *setting, guint32 idx) +{ + NMSettingConnectionPrivate *priv; + GSList * elt; + + g_return_if_fail(NM_IS_SETTING_CONNECTION(setting)); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + elt = g_slist_nth(priv->secondaries, idx); + g_return_if_fail(elt != NULL); + + g_free(elt->data); + priv->secondaries = g_slist_delete_link(priv->secondaries, elt); + _notify(setting, PROP_SECONDARIES); +} + +/** + * nm_setting_connection_remove_secondary_by_value: + * @setting: the #NMSettingConnection + * @sec_uuid: the secondary connection UUID to remove + * + * Removes the secondary connection UUID @sec_uuid. + * + * Returns: %TRUE if the secondary connection UUID was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_connection_remove_secondary_by_value(NMSettingConnection *setting, const char *sec_uuid) +{ + NMSettingConnectionPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + g_return_val_if_fail(sec_uuid != NULL, FALSE); + g_return_val_if_fail(sec_uuid[0] != '\0', FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + for (iter = priv->secondaries; iter; iter = g_slist_next(iter)) { + if (!strcmp(sec_uuid, (char *) iter->data)) { + priv->secondaries = g_slist_delete_link(priv->secondaries, iter); + _notify(setting, PROP_SECONDARIES); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_connection_get_gateway_ping_timeout: + * @setting: the #NMSettingConnection + * + * Returns: the value contained in the #NMSettingConnection:gateway-ping-timeout + * property. + **/ +guint32 +nm_setting_connection_get_gateway_ping_timeout(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), 0); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->gateway_ping_timeout; +} + +/** + * nm_setting_connection_get_metered: + * @setting: the #NMSettingConnection + * + * Returns: the #NMSettingConnection:metered property of the setting. + * + * Since: 1.2 + **/ +NMMetered +nm_setting_connection_get_metered(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NM_METERED_UNKNOWN); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->metered; +} + +/** + * nm_setting_connection_get_lldp: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:lldp property of the connection. + * + * Returns: a %NMSettingConnectionLldp which indicates whether LLDP must be + * enabled for the connection. + * + * Since: 1.2 + **/ +NMSettingConnectionLldp +nm_setting_connection_get_lldp(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NM_SETTING_CONNECTION_LLDP_DEFAULT); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->lldp; +} + +/** + * nm_setting_connection_get_mdns: + * @setting: the #NMSettingConnection + * + * Returns: the #NMSettingConnection:mdns property of the setting. + * + * Since: 1.12 + **/ +NMSettingConnectionMdns +nm_setting_connection_get_mdns(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NM_SETTING_CONNECTION_MDNS_DEFAULT); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->mdns; +} + +/** + * nm_setting_connection_get_llmnr: + * @setting: the #NMSettingConnection + * + * Returns: the #NMSettingConnection:llmnr property of the setting. + * + * Since: 1.14 + **/ +NMSettingConnectionLlmnr +nm_setting_connection_get_llmnr(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NM_SETTING_CONNECTION_LLMNR_DEFAULT); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->llmnr; +} + +static void +_set_error_missing_base_setting(GError **error, const char *type) +{ + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("setting required for connection of type '%s'"), + type); + g_prefix_error(error, "%s: ", type); +} + +gboolean +_nm_connection_detect_slave_type_full(NMSettingConnection *s_con, + NMConnection * connection, + const char ** out_slave_type, + const char ** out_normerr_slave_setting_type, + const char ** out_normerr_missing_slave_type, + const char ** out_normerr_missing_slave_type_port, + GError ** error) +{ + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE(s_con); + gboolean is_slave; + const char * slave_setting_type; + const char * slave_type; + const char * normerr_slave_setting_type = NULL; + const char * normerr_missing_slave_type = NULL; + const char * normerr_missing_slave_type_port = NULL; + + is_slave = FALSE; + slave_setting_type = NULL; + slave_type = priv->slave_type; + if (slave_type) { + is_slave = _nm_setting_slave_type_is_valid(slave_type, &slave_setting_type); + if (!is_slave) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Unknown slave type '%s'"), + slave_type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + } + + if (is_slave) { + if (!priv->master) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("Slave connections need a valid '%s' property"), + NM_SETTING_CONNECTION_MASTER); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER); + return FALSE; + } + if (slave_setting_type && connection + && !nm_connection_get_setting_by_name(connection, slave_setting_type)) + normerr_slave_setting_type = slave_setting_type; + } else { + nm_assert(!slave_type); + if (priv->master) { + NMSetting *s_port; + + if (connection + && (slave_type = _nm_connection_detect_slave_type(connection, &s_port))) { + normerr_missing_slave_type = slave_type; + normerr_missing_slave_type_port = nm_setting_get_name(s_port); + } else { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("Cannot set '%s' without '%s'"), + NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_SLAVE_TYPE); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + } + } + + NM_SET_OUT(out_slave_type, slave_type); + NM_SET_OUT(out_normerr_slave_setting_type, normerr_slave_setting_type); + NM_SET_OUT(out_normerr_missing_slave_type, normerr_missing_slave_type); + NM_SET_OUT(out_normerr_missing_slave_type_port, normerr_missing_slave_type_port); + return TRUE; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingConnection * self = NM_SETTING_CONNECTION(setting); + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE(self); + NMSetting * normerr_base_type = NULL; + const char * type; + const char * slave_type; + const char * normerr_slave_setting_type = NULL; + const char * normerr_missing_slave_type = NULL; + const char * normerr_missing_slave_type_port = NULL; + gboolean normerr_base_setting = FALSE; + + if (!priv->id) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + return FALSE; + } else if (!priv->id[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + return FALSE; + } + + if (priv->uuid && !nm_utils_is_uuid(priv->uuid)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid UUID"), + priv->uuid); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + return FALSE; + } + + type = priv->type; + if (!type) { + if (!connection + || !(normerr_base_type = _nm_connection_find_base_type_setting(connection))) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TYPE); + return FALSE; + } + type = nm_setting_get_name(normerr_base_type); + } else { + GType base_type; + + if (!type[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TYPE); + return FALSE; + } + + base_type = nm_setting_lookup_type(type); + if (base_type == G_TYPE_INVALID + || _nm_setting_type_get_base_type_priority(base_type) == NM_SETTING_PRIORITY_INVALID) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection type '%s' is not valid"), + type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TYPE); + return FALSE; + } + + /* Make sure the corresponding 'type' item is present */ + if (connection && !nm_connection_get_setting_by_name(connection, type)) { + NMSetting * s_base; + NMConnection *connection2; + + s_base = g_object_new(base_type, NULL); + connection2 = nm_simple_connection_new_clone(connection); + nm_connection_add_setting(connection2, s_base); + + normerr_base_setting = nm_setting_verify(s_base, connection2, NULL); + + g_object_unref(connection2); + + if (!normerr_base_setting) { + _set_error_missing_base_setting(error, type); + return FALSE; + } + } + } + + if (priv->interface_name) { + GError * tmp_error = NULL; + NMUtilsIfaceType iface_type; + + if (NM_IN_STRSET(type, + NM_SETTING_OVS_BRIDGE_SETTING_NAME, + NM_SETTING_OVS_PORT_SETTING_NAME)) + iface_type = NMU_IFACE_OVS; + else if (nm_streq(type, NM_SETTING_OVS_INTERFACE_SETTING_NAME)) { + NMSettingOvsInterface *s_ovs_iface = NULL; + const char * ovs_iface_type; + + if (connection) + s_ovs_iface = nm_connection_get_setting_ovs_interface(connection); + _nm_setting_ovs_interface_verify_interface_type( + s_ovs_iface, + s_ovs_iface ? nm_setting_ovs_interface_get_interface_type(s_ovs_iface) : NULL, + connection, + FALSE, + NULL, + &ovs_iface_type, + NULL); + if (!ovs_iface_type) { + /* We cannot determine to OVS interface type. Consequently, we cannot + * fully validate the interface name. + * + * If we have a connection (and we do a full validation anyway), skip the + * check. The connection will fail validation when we validate the OVS setting. + * + * Otherwise, do the most basic validation. + */ + if (connection) + goto after_interface_name; + iface_type = NMU_IFACE_ANY; + } else if (NM_IN_STRSET(ovs_iface_type, "patch")) { + /* this interface type is internal to OVS. */ + iface_type = NMU_IFACE_OVS; + } else { + /* This interface type also requires a netdev. We need to validate + * for both OVS and KERNEL. */ + nm_assert(NM_IN_STRSET(ovs_iface_type, "internal", "system", "dpdk")); + iface_type = NMU_IFACE_OVS_AND_KERNEL; + } + } else + iface_type = NMU_IFACE_KERNEL; + + if (!nm_utils_ifname_valid(priv->interface_name, iface_type, &tmp_error)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "'%s': %s", + priv->interface_name, + tmp_error->message); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME); + g_error_free(tmp_error); + return FALSE; + } + } +after_interface_name: + + if (!_nm_connection_detect_slave_type_full(self, + connection, + &slave_type, + &normerr_slave_setting_type, + &normerr_missing_slave_type, + &normerr_missing_slave_type_port, + error)) + return FALSE; + + if (nm_streq(type, NM_SETTING_OVS_PORT_SETTING_NAME) && slave_type + && !nm_streq(slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("'%s' connections must be enslaved to '%s', not '%s'"), + NM_SETTING_OVS_PORT_SETTING_NAME, + NM_SETTING_OVS_BRIDGE_SETTING_NAME, + slave_type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + + if (priv->metered != NM_METERED_UNKNOWN && priv->metered != NM_METERED_YES + && priv->metered != NM_METERED_NO) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("metered value %d is not valid"), + priv->metered); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_METERED); + return FALSE; + } + + if (priv->mdns < (int) NM_SETTING_CONNECTION_MDNS_DEFAULT + || priv->mdns > (int) NM_SETTING_CONNECTION_MDNS_YES) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value %d is not valid"), + priv->mdns); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MDNS); + return FALSE; + } + + if (priv->llmnr < (int) NM_SETTING_CONNECTION_LLMNR_DEFAULT + || priv->llmnr > (int) NM_SETTING_CONNECTION_LLMNR_YES) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value %d is not valid"), + priv->llmnr); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_LLMNR); + return FALSE; + } + + if (!NM_IN_SET(priv->multi_connect, + (int) NM_CONNECTION_MULTI_CONNECT_DEFAULT, + (int) NM_CONNECTION_MULTI_CONNECT_SINGLE, + (int) NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE, + (int) NM_CONNECTION_MULTI_CONNECT_MULTIPLE)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value %d is not valid"), + priv->multi_connect); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MULTI_CONNECT); + return FALSE; + } + + if (priv->mud_url) { + if (!priv->mud_url[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_CONNECTION_MUD_URL); + return FALSE; + } + if (nm_streq(priv->mud_url, NM_CONNECTION_MUD_URL_NONE)) { + /* pass */ + } else { + if (strlen(priv->mud_url) > 255) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("DHCP option cannot be longer than 255 characters")); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_CONNECTION_MUD_URL); + return FALSE; + } + if (!nm_sd_http_url_is_valid_https(priv->mud_url)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("MUD URL is not a valid URL")); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_CONNECTION_MUD_URL); + return FALSE; + } + } + } + + if (priv->permissions) { + guint i; + + for (i = 0; i < priv->permissions->len; i++) { + const Permission *permissions = &g_array_index(priv->permissions, Permission, i); + + if (permissions->ptype != PERM_TYPE_USER) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid permissions not in format \"user:$UNAME[:]\"")); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_CONNECTION_PERMISSIONS); + return FALSE; + } + nm_assert(nm_settings_connection_validate_permission_user(permissions->item, -1)); + } + } + + /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */ + + if (!priv->uuid) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + if (normerr_base_type) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property type should be set to '%s'"), + nm_setting_get_name(normerr_base_type)); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TYPE); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + if (normerr_base_setting) { + _set_error_missing_base_setting(error, priv->type); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + if (normerr_slave_setting_type) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("slave-type '%s' requires a '%s' setting in the connection"), + priv->slave_type, + normerr_slave_setting_type); + g_prefix_error(error, "%s: ", normerr_slave_setting_type); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + if (normerr_missing_slave_type) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("Detect a slave connection with '%s' set and a port type '%s'. '%s' should " + "be set to '%s'"), + NM_SETTING_CONNECTION_MASTER, + normerr_missing_slave_type_port, + NM_SETTING_CONNECTION_SLAVE_TYPE, + normerr_missing_slave_type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_SLAVE_TYPE); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + if (connection) { + gboolean has_bridge_port = FALSE; + + if ((!nm_streq0(priv->slave_type, NM_SETTING_BRIDGE_SETTING_NAME) + && (has_bridge_port = + !!nm_connection_get_setting_by_name(connection, + NM_SETTING_BRIDGE_PORT_SETTING_NAME))) + || (!nm_streq0(priv->slave_type, NM_SETTING_TEAM_SETTING_NAME) + && nm_connection_get_setting_by_name(connection, + NM_SETTING_TEAM_PORT_SETTING_NAME))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("A slave connection with '%s' set to '%s' cannot have a '%s' setting"), + NM_SETTING_CONNECTION_SLAVE_TYPE, + priv->slave_type ?: "", + has_bridge_port ? NM_SETTING_BRIDGE_PORT_SETTING_NAME + : NM_SETTING_TEAM_PORT_SETTING_NAME); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_SLAVE_TYPE); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + } + + return TRUE; +} + +static const char * +find_virtual_interface_name(GVariant *connection_dict, GVariant **variant_to_free) +{ + GVariant * setting_dict; + const char *interface_name; + + nm_assert(variant_to_free && !*variant_to_free); + + setting_dict = g_variant_lookup_value(connection_dict, + NM_SETTING_BOND_SETTING_NAME, + NM_VARIANT_TYPE_SETTING); + if (!setting_dict) + setting_dict = g_variant_lookup_value(connection_dict, + NM_SETTING_BRIDGE_SETTING_NAME, + NM_VARIANT_TYPE_SETTING); + if (!setting_dict) + setting_dict = g_variant_lookup_value(connection_dict, + NM_SETTING_TEAM_SETTING_NAME, + NM_VARIANT_TYPE_SETTING); + if (!setting_dict) + setting_dict = g_variant_lookup_value(connection_dict, + NM_SETTING_VLAN_SETTING_NAME, + NM_VARIANT_TYPE_SETTING); + + if (!setting_dict) + return NULL; + + *variant_to_free = setting_dict; + + /* All of the deprecated virtual interface name properties were named "interface-name". */ + if (!g_variant_lookup(setting_dict, "interface-name", "&s", &interface_name)) + interface_name = NULL; + + return interface_name; +} + +static gboolean +nm_setting_connection_no_interface_name(NMSetting * setting, + GVariant * connection_dict, + const char * property, + NMSettingParseFlags parse_flags, + GError ** error) +{ + const char * virtual_interface_name; + gs_unref_variant GVariant *variant_to_free = NULL; + + virtual_interface_name = find_virtual_interface_name(connection_dict, &variant_to_free); + g_object_set(G_OBJECT(setting), + NM_SETTING_CONNECTION_INTERFACE_NAME, + virtual_interface_name, + NULL); + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_ID) + && nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_CONNECTION_ID)) + return NM_TERNARY_DEFAULT; + + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP) + && nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_CONNECTION_TIMESTAMP)) + return NM_TERNARY_DEFAULT; + + return NM_SETTING_CLASS(nm_setting_connection_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingConnection * setting = NM_SETTING_CONNECTION(object); + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_ID: + g_value_set_string(value, nm_setting_connection_get_id(setting)); + break; + case PROP_UUID: + g_value_set_string(value, nm_setting_connection_get_uuid(setting)); + break; + case PROP_STABLE_ID: + g_value_set_string(value, nm_setting_connection_get_stable_id(setting)); + break; + case PROP_INTERFACE_NAME: + g_value_set_string(value, nm_setting_connection_get_interface_name(setting)); + break; + case PROP_TYPE: + g_value_set_string(value, nm_setting_connection_get_connection_type(setting)); + break; + case PROP_PERMISSIONS: + { + char **strv; + gsize i, l; + + l = nm_g_array_len(priv->permissions); + strv = g_new(char *, l + 1u); + + for (i = 0; i < l; i++) + strv[i] = _permission_to_string(&g_array_index(priv->permissions, Permission, i)); + strv[i] = NULL; + + g_value_take_boxed(value, strv); + break; + } + case PROP_AUTOCONNECT: + g_value_set_boolean(value, nm_setting_connection_get_autoconnect(setting)); + break; + case PROP_AUTOCONNECT_PRIORITY: + g_value_set_int(value, nm_setting_connection_get_autoconnect_priority(setting)); + break; + case PROP_AUTOCONNECT_RETRIES: + g_value_set_int(value, nm_setting_connection_get_autoconnect_retries(setting)); + break; + case PROP_MULTI_CONNECT: + g_value_set_int(value, priv->multi_connect); + break; + case PROP_TIMESTAMP: + g_value_set_uint64(value, nm_setting_connection_get_timestamp(setting)); + break; + case PROP_READ_ONLY: + g_value_set_boolean(value, nm_setting_connection_get_read_only(setting)); + break; + case PROP_ZONE: + g_value_set_string(value, nm_setting_connection_get_zone(setting)); + break; + case PROP_MASTER: + g_value_set_string(value, nm_setting_connection_get_master(setting)); + break; + case PROP_SLAVE_TYPE: + g_value_set_string(value, nm_setting_connection_get_slave_type(setting)); + break; + case PROP_AUTOCONNECT_SLAVES: + g_value_set_enum(value, nm_setting_connection_get_autoconnect_slaves(setting)); + break; + case PROP_SECONDARIES: + g_value_take_boxed(value, _nm_utils_slist_to_strv(priv->secondaries, TRUE)); + break; + case PROP_GATEWAY_PING_TIMEOUT: + g_value_set_uint(value, priv->gateway_ping_timeout); + break; + case PROP_METERED: + g_value_set_enum(value, priv->metered); + break; + case PROP_LLDP: + g_value_set_int(value, priv->lldp); + break; + case PROP_AUTH_RETRIES: + g_value_set_int(value, priv->auth_retries); + break; + case PROP_MDNS: + g_value_set_int(value, priv->mdns); + break; + case PROP_LLMNR: + g_value_set_int(value, priv->llmnr); + break; + case PROP_WAIT_DEVICE_TIMEOUT: + g_value_set_int(value, priv->wait_device_timeout); + break; + case PROP_MUD_URL: + g_value_set_string(value, priv->mud_url); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_ID: + g_free(priv->id); + priv->id = g_value_dup_string(value); + break; + case PROP_UUID: + g_free(priv->uuid); + priv->uuid = g_value_dup_string(value); + break; + case PROP_STABLE_ID: + g_free(priv->stable_id); + priv->stable_id = g_value_dup_string(value); + break; + case PROP_INTERFACE_NAME: + g_free(priv->interface_name); + priv->interface_name = g_value_dup_string(value); + break; + case PROP_TYPE: + g_free(priv->type); + priv->type = g_value_dup_string(value); + break; + case PROP_PERMISSIONS: + { + const char *const *strv; + guint i; + + nm_clear_pointer(&priv->permissions, g_array_unref); + strv = g_value_get_boxed(value); + if (strv && strv[0]) { + priv->permissions = + g_array_sized_new(FALSE, FALSE, sizeof(Permission), NM_PTRARRAY_LEN(strv)); + g_array_set_clear_func(priv->permissions, (GDestroyNotify) _permission_clear_stale); + + for (i = 0; strv[i]; i++) { + Permission *permission = nm_g_array_append_new(priv->permissions, Permission); + + _permission_set_stale_parse(permission, strv[i]); + } + } + break; + } + case PROP_AUTOCONNECT: + priv->autoconnect = g_value_get_boolean(value); + break; + case PROP_AUTOCONNECT_PRIORITY: + priv->autoconnect_priority = g_value_get_int(value); + break; + case PROP_AUTOCONNECT_RETRIES: + priv->autoconnect_retries = g_value_get_int(value); + break; + case PROP_MULTI_CONNECT: + priv->multi_connect = g_value_get_int(value); + break; + case PROP_TIMESTAMP: + priv->timestamp = g_value_get_uint64(value); + break; + case PROP_READ_ONLY: + priv->read_only = g_value_get_boolean(value); + break; + case PROP_ZONE: + g_free(priv->zone); + priv->zone = g_value_dup_string(value); + break; + case PROP_MASTER: + g_free(priv->master); + priv->master = g_value_dup_string(value); + break; + case PROP_SLAVE_TYPE: + g_free(priv->slave_type); + priv->slave_type = g_value_dup_string(value); + break; + case PROP_AUTOCONNECT_SLAVES: + priv->autoconnect_slaves = g_value_get_enum(value); + break; + case PROP_SECONDARIES: + g_slist_free_full(priv->secondaries, g_free); + priv->secondaries = _nm_utils_strv_to_slist(g_value_get_boxed(value), TRUE); + break; + case PROP_GATEWAY_PING_TIMEOUT: + priv->gateway_ping_timeout = g_value_get_uint(value); + break; + case PROP_METERED: + priv->metered = g_value_get_enum(value); + break; + case PROP_LLDP: + priv->lldp = g_value_get_int(value); + break; + case PROP_AUTH_RETRIES: + priv->auth_retries = g_value_get_int(value); + break; + case PROP_MDNS: + priv->mdns = g_value_get_int(value); + break; + case PROP_LLMNR: + priv->llmnr = g_value_get_int(value); + break; + case PROP_WAIT_DEVICE_TIMEOUT: + priv->wait_device_timeout = g_value_get_int(value); + break; + case PROP_MUD_URL: + g_free(priv->mud_url); + priv->mud_url = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_connection_init(NMSettingConnection *setting) +{ + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + + priv->auth_retries = -1; + priv->autoconnect = TRUE; + priv->autoconnect_priority = NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT; + priv->autoconnect_retries = -1; + priv->autoconnect_slaves = NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT; + priv->lldp = NM_SETTING_CONNECTION_LLDP_DEFAULT; + priv->llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT; + priv->mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT; + priv->wait_device_timeout = -1; +} + +/** + * nm_setting_connection_new: + * + * Creates a new #NMSettingConnection object with default values. + * + * Returns: the new empty #NMSettingConnection object + **/ +NMSetting * +nm_setting_connection_new(void) +{ + return g_object_new(NM_TYPE_SETTING_CONNECTION, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE(object); + + g_free(priv->id); + g_free(priv->uuid); + g_free(priv->stable_id); + g_free(priv->interface_name); + g_free(priv->type); + g_free(priv->zone); + g_free(priv->master); + g_free(priv->slave_type); + g_free(priv->mud_url); + nm_clear_pointer(&priv->permissions, g_array_unref); + g_slist_free_full(priv->secondaries, g_free); + + G_OBJECT_CLASS(nm_setting_connection_parent_class)->finalize(object); +} + +static void +nm_setting_connection_class_init(NMSettingConnectionClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingConnectionPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->compare_property = compare_property; + + /** + * NMSettingConnection:id: + * + * A human readable unique identifier for the connection, like "Work Wi-Fi" + * or "T-Mobile 3G". + **/ + /* ---ifcfg-rh--- + * property: id + * variable: NAME(+) + * description: User friendly name for the connection profile. + * ---end--- + */ + obj_properties[PROP_ID] = g_param_spec_string(NM_SETTING_CONNECTION_ID, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:uuid: + * + * A universally unique identifier for the connection, for example generated + * with libuuid. It should be assigned when the connection is created, and + * never changed as long as the connection still applies to the same + * network. For example, it should not be changed when the + * #NMSettingConnection:id property or #NMSettingIP4Config changes, but + * might need to be re-created when the Wi-Fi SSID, mobile broadband network + * provider, or #NMSettingConnection:type property changes. + * + * The UUID must be in the format "2815492f-7e56-435e-b2e9-246bd7cdc664" + * (ie, contains only hexadecimal characters and "-"). A suitable UUID may + * be generated by nm_utils_uuid_generate() or + * nm_utils_uuid_generate_from_string(). + **/ + /* ---ifcfg-rh--- + * property: uuid + * variable: UUID(+) + * description: UUID for the connection profile. When missing, NetworkManager + * creates the UUID itself (by hashing the filename). + * ---end--- + */ + obj_properties[PROP_UUID] = g_param_spec_string( + NM_SETTING_CONNECTION_UUID, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:stable-id: + * + * This represents the identity of the connection used for various purposes. + * It allows to configure multiple profiles to share the identity. Also, + * the stable-id can contain placeholders that are substituted dynamically and + * deterministically depending on the context. + * + * The stable-id is used for generating IPv6 stable private addresses + * with ipv6.addr-gen-mode=stable-privacy. It is also used to seed the + * generated cloned MAC address for ethernet.cloned-mac-address=stable + * and wifi.cloned-mac-address=stable. It is also used as DHCP client + * identifier with ipv4.dhcp-client-id=stable and to derive the DHCP + * DUID with ipv6.dhcp-duid=stable-[llt,ll,uuid]. + * + * Note that depending on the context where it is used, other parameters are + * also seeded into the generation algorithm. For example, a per-host key + * is commonly also included, so that different systems end up generating + * different IDs. Or with ipv6.addr-gen-mode=stable-privacy, also the device's + * name is included, so that different interfaces yield different addresses. + * The per-host key is the identity of your machine and stored in /var/lib/NetworkManager/secret-key. + * + * The '$' character is treated special to perform dynamic substitutions + * at runtime. Currently, supported are "${CONNECTION}", "${DEVICE}", "${MAC}", + * "${BOOT}", "${RANDOM}". + * These effectively create unique IDs per-connection, per-device, per-boot, + * or every time. Note that "${DEVICE}" corresponds to the interface name of the + * device and "${MAC}" is the permanent MAC address of the device. + * Any unrecognized patterns following '$' are treated verbatim, however + * are reserved for future use. You are thus advised to avoid '$' or + * escape it as "$$". + * For example, set it to "${CONNECTION}-${BOOT}-${DEVICE}" to create a unique id for + * this connection that changes with every reboot and differs depending on the + * interface where the profile activates. + * + * If the value is unset, a global connection default is consulted. If the + * value is still unset, the default is similar to "${CONNECTION}" and uses + * a unique, fixed ID for the connection. + * + * Since: 1.4 + **/ + /* ---ifcfg-rh--- + * property: stable-id + * variable: STABLE_ID(+) + * description: Token to generate stable IDs. + * ---end--- + */ + obj_properties[PROP_STABLE_ID] = g_param_spec_string( + NM_SETTING_CONNECTION_STABLE_ID, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:interface-name: + * + * The name of the network interface this connection is bound to. If not + * set, then the connection can be attached to any interface of the + * appropriate type (subject to restrictions imposed by other settings). + * + * For software devices this specifies the name of the created device. + * + * For connection types where interface names cannot easily be made + * persistent (e.g. mobile broadband or USB Ethernet), this property should + * not be used. Setting this property restricts the interfaces a connection + * can be used with, and if interface names change or are reordered the + * connection may be applied to the wrong interface. + **/ + /* ---ifcfg-rh--- + * property: interface-name + * variable: DEVICE + * description: Interface name of the device this profile is bound to. The variable + * can be left out when the profile should apply for more devices. Note that DEVICE + * can be required for some connection types. + * ---end--- + */ + obj_properties[PROP_INTERFACE_NAME] = g_param_spec_string( + NM_SETTING_CONNECTION_INTERFACE_NAME, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_INTERFACE_NAME], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING, + .missing_from_dbus_fcn = + nm_setting_connection_no_interface_name, )); + + /** + * NMSettingConnection:type: + * + * Base type of the connection. For hardware-dependent connections, should + * contain the setting name of the hardware-type specific setting (ie, + * "802-3-ethernet" or "802-11-wireless" or "bluetooth", etc), and for + * non-hardware dependent connections like VPN or otherwise, should contain + * the setting name of that setting type (ie, "vpn" or "bridge", etc). + **/ + /* ---ifcfg-rh--- + * property: type + * variable: TYPE (DEVICETYPE, DEVICE) + * values: Ethernet, Wireless, InfiniBand, Bridge, Bond, Vlan, Team, TeamPort + * description: Base type of the connection. DEVICETYPE is used for teaming + * connections. + * example: TYPE=Ethernet; TYPE=Bond; TYPE=Bridge; DEVICETYPE=TeamPort + * ---end--- + */ + obj_properties[PROP_TYPE] = g_param_spec_string(NM_SETTING_CONNECTION_TYPE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:permissions: + * + * An array of strings defining what access a given user has to this + * connection. If this is %NULL or empty, all users are allowed to access + * this connection; otherwise users are allowed if and only if they are in + * this list. When this is not empty, the connection can be active only when + * one of the specified users is logged into an active session. Each entry + * is of the form "[type]:[id]:[reserved]"; for example, "user:dcbw:blah". + * + * At this time only the "user" [type] is allowed. Any other values are + * ignored and reserved for future use. [id] is the username that this + * permission refers to, which may not contain the ":" character. Any + * [reserved] information present must be ignored and is reserved for future + * use. All of [type], [id], and [reserved] must be valid UTF-8. + */ + /* ---ifcfg-rh--- + * property: permissions + * variable: USERS(+) + * description: Restrict to certain users the access to this connection, and + * allow the connection to be active only when at least one of the + * specified users is logged into an active session. + * example: USERS="joe bob" + * ---end--- + */ + obj_properties[PROP_PERMISSIONS] = + g_param_spec_boxed(NM_SETTING_CONNECTION_PERMISSIONS, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:autoconnect: + * + * Whether or not the connection should be automatically connected by + * NetworkManager when the resources for the connection are available. + * %TRUE to automatically activate the connection, %FALSE to require manual + * intervention to activate the connection. + * + * Note that autoconnect is not implemented for VPN profiles. See + * #NMSettingConnection:secondaries as an alternative to automatically + * connect VPN profiles. + **/ + /* ---ifcfg-rh--- + * property: autoconnect + * variable: ONBOOT + * default: yes + * description: Whether the connection should be autoconnected (not only while booting). + * ---end--- + */ + obj_properties[PROP_AUTOCONNECT] = g_param_spec_boolean( + NM_SETTING_CONNECTION_AUTOCONNECT, + "", + "", + TRUE, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:autoconnect-priority: + * + * The autoconnect priority. If the connection is set to autoconnect, + * connections with higher priority will be preferred. Defaults to 0. + * The higher number means higher priority. + **/ + /* ---ifcfg-rh--- + * property: autoconnect-priority + * variable: AUTOCONNECT_PRIORITY(+) + * values: -999 to 999 + * default: 0 + * description: Connection priority for automatic activation. Connections with + * higher numbers are preferred when selecting profiles for automatic activation. + * example: AUTOCONNECT_PRIORITY=20 + * ---end--- + */ + obj_properties[PROP_AUTOCONNECT_PRIORITY] = g_param_spec_int( + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, + "", + "", + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:autoconnect-retries: + * + * The number of times a connection should be tried when autoactivating before + * giving up. Zero means forever, -1 means the global default (4 times if not + * overridden). Setting this to 1 means to try activation only once before + * blocking autoconnect. Note that after a timeout, NetworkManager will try + * to autoconnect again. + */ + /* ---ifcfg-rh--- + * property: autoconnect-retries + * variable: AUTOCONNECT_RETRIES(+) + * description: The number of times a connection should be autoactivated + * before giving up and switching to the next one. + * values: -1 (use global default), 0 (forever) or a positive value + * example: AUTOCONNECT_RETRIES=1 + * ---end--- + */ + obj_properties[PROP_AUTOCONNECT_RETRIES] = g_param_spec_int( + NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, + "", + "", + -1, + G_MAXINT32, + -1, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:multi-connect: + * + * Specifies whether the profile can be active multiple times at a particular + * moment. The value is of type #NMConnectionMultiConnect. + * + * Since: 1.14 + */ + /* ---ifcfg-rh--- + * property: multi-connect + * variable: MULTI_CONNECT(+) + * description: whether the profile can be active on multiple devices at a given + * moment. The values are numbers corresponding to #NMConnectionMultiConnect enum. + * example: MULTI_CONNECT=3 + * ---end--- + */ + obj_properties[PROP_MULTI_CONNECT] = g_param_spec_int( + NM_SETTING_CONNECTION_MULTI_CONNECT, + "", + "", + G_MININT32, + G_MAXINT32, + NM_CONNECTION_MULTI_CONNECT_DEFAULT, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:timestamp: + * + * The time, in seconds since the Unix Epoch, that the connection was last + * _successfully_ fully activated. + * + * NetworkManager updates the connection timestamp periodically when the + * connection is active to ensure that an active connection has the latest + * timestamp. The property is only meant for reading (changes to this + * property will not be preserved). + **/ + obj_properties[PROP_TIMESTAMP] = g_param_spec_uint64( + NM_SETTING_CONNECTION_TIMESTAMP, + "", + "", + 0, + G_MAXUINT64, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_TIMESTAMP], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_UINT64, + .to_dbus_fcn = _to_dbus_fcn_timestamp, )); + + /** + * NMSettingConnection:read-only: + * + * %FALSE if the connection can be modified using the provided settings + * service's D-Bus interface with the right privileges, or %TRUE if the + * connection is read-only and cannot be modified. + **/ + obj_properties[PROP_READ_ONLY] = g_param_spec_boolean( + NM_SETTING_CONNECTION_READ_ONLY, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:zone: + * + * The trust level of a the connection. Free form case-insensitive string + * (for example "Home", "Work", "Public"). %NULL or unspecified zone means + * the connection will be placed in the default zone as defined by the + * firewall. + * + * When updating this property on a currently activated connection, + * the change takes effect immediately. + **/ + /* ---ifcfg-rh--- + * property: zone + * variable: ZONE(+) + * description: Trust level of this connection. The string is usually used + * for a firewall. + * example: ZONE=Work + * ---end--- + */ + obj_properties[PROP_ZONE] = + g_param_spec_string(NM_SETTING_CONNECTION_ZONE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | NM_SETTING_PARAM_REAPPLY_IMMEDIATELY | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:master: + * + * Interface name of the master device or UUID of the master connection. + **/ + /* ---ifcfg-rh--- + * property: master + * variable: MASTER, MASTER_UUID, TEAM_MASTER, TEAM_MASTER_UUID, BRIDGE, BRIDGE_UUID + * description: Reference to master connection. The variable used depends on + * the connection type and the value. In general, if the *_UUID variant is present, + * the variant without *_UUID is ignored. NetworkManager attempts to write both + * for compatibility with legacy tooling. + * ---end--- + */ + obj_properties[PROP_MASTER] = + g_param_spec_string(NM_SETTING_CONNECTION_MASTER, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:slave-type: + * + * Setting name of the device type of this slave's master connection (eg, + * %NM_SETTING_BOND_SETTING_NAME), or %NULL if this connection is not a + * slave. + **/ + /* ---ifcfg-rh--- + * property: slave-type + * variable: MASTER, MASTER_UUID, TEAM_MASTER, TEAM_MASTER_UUID, DEVICETYPE, + * BRIDGE, BRIDGE_UUID + * description: Slave type doesn't map directly to a variable, but it is + * recognized using different variables. MASTER and MASTER_UUID for bonding, + * TEAM_MASTER, TEAM_MASTER_UUID and DEVICETYPE for teaming, BRIDGE + * and BRIDGE_UUID for bridging. + * ---end--- + */ + obj_properties[PROP_SLAVE_TYPE] = + g_param_spec_string(NM_SETTING_CONNECTION_SLAVE_TYPE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:autoconnect-slaves: + * + * Whether or not slaves of this connection should be automatically brought up + * when NetworkManager activates this connection. This only has a real effect + * for master connections. The properties #NMSettingConnection:autoconnect, + * #NMSettingConnection:autoconnect-priority and #NMSettingConnection:autoconnect-retries + * are unrelated to this setting. + * The permitted values are: 0: leave slave connections untouched, + * 1: activate all the slave connections with this connection, -1: default. + * If -1 (default) is set, global connection.autoconnect-slaves is read to + * determine the real value. If it is default as well, this fallbacks to 0. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: autoconnect-slaves + * variable: AUTOCONNECT_SLAVES(+) + * default: missing variable means global default + * description: Whether slaves of this connection should be auto-connected + * when this connection is activated. + * ---end--- + */ + obj_properties[PROP_AUTOCONNECT_SLAVES] = g_param_spec_enum( + NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES, + "", + "", + NM_TYPE_SETTING_CONNECTION_AUTOCONNECT_SLAVES, + NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:secondaries: + * + * List of connection UUIDs that should be activated when the base + * connection itself is activated. Currently, only VPN connections are + * supported. + **/ + /* ---ifcfg-rh--- + * property: secondaries + * variable: SECONDARY_UUIDS(+) + * description: UUID of VPN connections that should be activated + * together with this connection. + * ---end--- + */ + obj_properties[PROP_SECONDARIES] = g_param_spec_boxed( + NM_SETTING_CONNECTION_SECONDARIES, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:gateway-ping-timeout: + * + * If greater than zero, delay success of IP addressing until either the + * timeout is reached, or an IP gateway replies to a ping. + **/ + /* ---ifcfg-rh--- + * property: gateway-ping-timeout + * variable: GATEWAY_PING_TIMEOUT(+) + * default: 0 + * description: If greater than zero, the IP connectivity will be checked by + * pinging the gateway and waiting for the specified timeout (in seconds). + * example: GATEWAY_PING_TIMEOUT=5 + * ---end--- + */ + obj_properties[PROP_GATEWAY_PING_TIMEOUT] = + g_param_spec_uint(NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, + "", + "", + 0, + 600, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:metered: + * + * Whether the connection is metered. + * + * When updating this property on a currently activated connection, + * the change takes effect immediately. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: metered + * variable: CONNECTION_METERED(+) + * values: yes,no,unknown + * description: Whether the device is metered + * example: CONNECTION_METERED=yes + * ---end--- + */ + obj_properties[PROP_METERED] = g_param_spec_enum( + NM_SETTING_CONNECTION_METERED, + "", + "", + NM_TYPE_METERED, + NM_METERED_UNKNOWN, + G_PARAM_READWRITE | NM_SETTING_PARAM_REAPPLY_IMMEDIATELY | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:lldp: + * + * Whether LLDP is enabled for the connection. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: lldp + * variable: LLDP(+) + * values: boolean value or 'rx' + * default: missing variable means global default + * description: whether LLDP is enabled for the connection + * example: LLDP=no + * ---end--- + */ + obj_properties[PROP_LLDP] = g_param_spec_int(NM_SETTING_CONNECTION_LLDP, + "", + "", + G_MININT32, + G_MAXINT32, + NM_SETTING_CONNECTION_LLDP_DEFAULT, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:auth-retries: + * + * The number of retries for the authentication. Zero means to try indefinitely; -1 means + * to use a global default. If the global default is not set, the authentication + * retries for 3 times before failing the connection. + * + * Currently, this only applies to 802-1x authentication. + * + * Since: 1.10 + **/ + /* ---ifcfg-rh--- + * property: auth-retries + * variable: AUTH_RETRIES(+) + * default: 0 + * description: Number of retries for authentication. + * ---end--- + */ + obj_properties[PROP_AUTH_RETRIES] = g_param_spec_int( + NM_SETTING_CONNECTION_AUTH_RETRIES, + "", + "", + -1, + G_MAXINT32, + -1, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:mdns: + * + * Whether mDNS is enabled for the connection. + * + * The permitted values are: "yes" (2) register hostname and resolving + * for the connection, "no" (0) disable mDNS for the interface, "resolve" + * (1) do not register hostname but allow resolving of mDNS host names + * and "default" (-1) to allow lookup of a global default in NetworkManager.conf. + * If unspecified, "default" ultimately depends on the DNS plugin (which + * for systemd-resolved currently means "no"). + * + * This feature requires a plugin which supports mDNS. Otherwise, the + * setting has no effect. One such plugin is dns-systemd-resolved. +* + * Since: 1.12 + **/ + /* ---ifcfg-rh--- + * property: mdns + * variable: MDNS(+) + * values: yes,no,resolve + * default: missing variable means global default + * description: Whether or not mDNS is enabled for the connection + * example: MDNS=yes + * ---end--- + */ + obj_properties[PROP_MDNS] = g_param_spec_int(NM_SETTING_CONNECTION_MDNS, + "", + "", + G_MININT32, + G_MAXINT32, + NM_SETTING_CONNECTION_MDNS_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:llmnr: + * + * Whether Link-Local Multicast Name Resolution (LLMNR) is enabled + * for the connection. LLMNR is a protocol based on the Domain Name + * System (DNS) packet format that allows both IPv4 and IPv6 hosts + * to perform name resolution for hosts on the same local link. + * + * The permitted values are: "yes" (2) register hostname and resolving + * for the connection, "no" (0) disable LLMNR for the interface, "resolve" + * (1) do not register hostname but allow resolving of LLMNR host names + * If unspecified, "default" ultimately depends on the DNS plugin (which + * for systemd-resolved currently means "yes"). + * + * This feature requires a plugin which supports LLMNR. Otherwise, the + * setting has no effect. One such plugin is dns-systemd-resolved. + * + * Since: 1.14 + **/ + /* ---ifcfg-rh--- + * property: llmnr + * variable: LLMNR(+) + * values: yes,no,resolve + * default: missing variable means global default + * description: Whether or not LLMNR is enabled for the connection + * example: LLMNR=yes + * ---end--- + */ + obj_properties[PROP_LLMNR] = g_param_spec_int(NM_SETTING_CONNECTION_LLMNR, + "", + "", + G_MININT32, + G_MAXINT32, + NM_SETTING_CONNECTION_LLMNR_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:wait-device-timeout: + * + * Timeout in milliseconds to wait for device at startup. + * During boot, devices may take a while to be detected by the driver. + * This property will cause to delay NetworkManager-wait-online.service + * and nm-online to give the device a chance to appear. This works by + * waiting for the given timeout until a compatible device for the + * profile is available and managed. + * + * The value 0 means no wait time. The default value is -1, which + * currently has the same meaning as no wait time. + * + * Since: 1.20 + **/ + /* ---ifcfg-rh--- + * property: wait-device-timeout + * variable: DEVTIMEOUT(+) + * values: timeout in seconds. + * description: for initscripts compatibility, this variable must be + * a whole integer. If necessary, NetworkManager stores also a fractional + * component for the milliseconds. + * example: DEVTIMEOUT=5 + * ---end--- + */ + obj_properties[PROP_WAIT_DEVICE_TIMEOUT] = + g_param_spec_int(NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, + "", + "", + -1, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingConnection:mud-url: + * + * If configured, set to a Manufacturer Usage Description (MUD) URL that points + * to manufacturer-recommended network policies for IoT devices. It is transmitted + * as a DHCPv4 or DHCPv6 option. The value must be a valid URL starting with "https://". + * + * The special value "none" is allowed to indicate that no MUD URL is used. + * + * If the per-profile value is unspecified (the default), a global connection default gets + * consulted. If still unspecified, the ultimate default is "none". + * + * Since: 1.26 + **/ + /* ---ifcfg-rh--- + * property: mud-url + * variable: MUD_URL + * values: a valid URL that points to recommended policy for this device + * description: MUD_URL to be sent by device (See RFC 8520). + * example: https://yourdevice.example.com/model.json + * ---end--- + */ + obj_properties[PROP_MUD_URL] = g_param_spec_string(NM_SETTING_CONNECTION_MUD_URL, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_CONNECTION, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-dcb.c b/src/libnm-core-impl/nm-setting-dcb.c new file mode 100644 index 0000000..695953d --- /dev/null +++ b/src/libnm-core-impl/nm-setting-dcb.c @@ -0,0 +1,1281 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-dcb.h" + +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-dcb + * @short_description: Connection properties for Data Center Bridging + * + * The #NMSettingDcb object is a #NMSetting subclass that describes properties + * for enabling and using Data Center Bridging (DCB) on Ethernet networks. + * DCB is a set of protocols (including 802.1Qbb, 802.1Qaz, 802.1Qau, and + * 802.1AB) to eliminate packet loss in Ethernet networks and support the use + * of storage technologies like Fibre Channel over Ethernet (FCoE) and iSCSI. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingDcb, + + PROP_APP_FCOE_FLAGS, + PROP_APP_FCOE_PRIORITY, + PROP_APP_FCOE_MODE, + + PROP_APP_ISCSI_FLAGS, + PROP_APP_ISCSI_PRIORITY, + + PROP_APP_FIP_FLAGS, + PROP_APP_FIP_PRIORITY, + + PROP_PFC_FLAGS, + PROP_PRIORITY_FLOW_CONTROL, + + PROP_PRIORITY_GROUP_FLAGS, + PROP_PRIORITY_GROUP_ID, + PROP_PRIORITY_GROUP_BANDWIDTH, + PROP_PRIORITY_BANDWIDTH, + PROP_PRIORITY_STRICT_BANDWIDTH, + PROP_PRIORITY_TRAFFIC_CLASS, ); + +typedef struct { + char * app_fcoe_mode; + guint pfc[8]; + guint priority_group_id[8]; + guint priority_group_bandwidth[8]; + guint priority_bandwidth[8]; + guint priority_strict[8]; + guint priority_traffic_class[8]; + int app_fcoe_priority; + int app_iscsi_priority; + int app_fip_priority; + NMSettingDcbFlags app_fcoe_flags; + NMSettingDcbFlags app_iscsi_flags; + NMSettingDcbFlags app_fip_flags; + NMSettingDcbFlags pfc_flags; + NMSettingDcbFlags priority_group_flags; +} NMSettingDcbPrivate; + +G_DEFINE_TYPE(NMSettingDcb, nm_setting_dcb, NM_TYPE_SETTING) + +#define NM_SETTING_DCB_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_DCB, NMSettingDcbPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_dcb_get_app_fcoe_flags: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-fcoe-flags property of the setting + **/ +NMSettingDcbFlags +nm_setting_dcb_get_app_fcoe_flags(NMSettingDcb *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->app_fcoe_flags; +} + +/** + * nm_setting_dcb_get_app_fcoe_priority: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-fcoe-priority property of the setting + **/ +int +nm_setting_dcb_get_app_fcoe_priority(NMSettingDcb *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->app_fcoe_priority; +} + +/** + * nm_setting_dcb_get_app_fcoe_mode: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-fcoe-mode property of the setting + **/ +const char * +nm_setting_dcb_get_app_fcoe_mode(NMSettingDcb *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), NULL); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->app_fcoe_mode; +} + +/** + * nm_setting_dcb_get_app_iscsi_flags: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-iscsi-flags property of the setting + **/ +NMSettingDcbFlags +nm_setting_dcb_get_app_iscsi_flags(NMSettingDcb *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->app_iscsi_flags; +} + +/** + * nm_setting_dcb_get_app_iscsi_priority: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-iscsi-priority property of the setting + **/ +int +nm_setting_dcb_get_app_iscsi_priority(NMSettingDcb *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->app_iscsi_priority; +} + +/** + * nm_setting_dcb_get_app_fip_flags: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-fip-flags property of the setting + **/ +NMSettingDcbFlags +nm_setting_dcb_get_app_fip_flags(NMSettingDcb *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->app_fip_flags; +} + +/** + * nm_setting_dcb_get_app_fip_priority: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-fip-priority property of the setting + **/ +int +nm_setting_dcb_get_app_fip_priority(NMSettingDcb *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->app_fip_priority; +} + +/** + * nm_setting_dcb_get_priority_flow_control_flags: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:priority-flow-control-flags property of the setting + **/ +NMSettingDcbFlags +nm_setting_dcb_get_priority_flow_control_flags(NMSettingDcb *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->pfc_flags; +} + +/** + * nm_setting_dcb_get_priority_flow_control: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to retrieve flow control for + * + * Returns: %TRUE if flow control is enabled for the given @user_priority, + * %FALSE if not enabled + **/ +gboolean +nm_setting_dcb_get_priority_flow_control(NMSettingDcb *setting, guint user_priority) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), FALSE); + g_return_val_if_fail(user_priority <= 7, FALSE); + + return !!NM_SETTING_DCB_GET_PRIVATE(setting)->pfc[user_priority]; +} + +/** + * nm_setting_dcb_set_priority_flow_control: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to set flow control for + * @enabled: %TRUE to enable flow control for this priority, %FALSE to disable it + * + * These values are only valid when #NMSettingDcb:priority-flow-control includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_flow_control(NMSettingDcb *setting, + guint user_priority, + gboolean enabled) +{ + NMSettingDcbPrivate *priv; + guint uint_enabled = enabled ? 1 : 0; + + g_return_if_fail(NM_IS_SETTING_DCB(setting)); + g_return_if_fail(user_priority <= 7); + + priv = NM_SETTING_DCB_GET_PRIVATE(setting); + if (priv->pfc[user_priority] != uint_enabled) { + priv->pfc[user_priority] = uint_enabled; + _notify(setting, PROP_PRIORITY_FLOW_CONTROL); + } +} + +/** + * nm_setting_dcb_get_priority_group_flags: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:priority-group-flags property of the setting + **/ +NMSettingDcbFlags +nm_setting_dcb_get_priority_group_flags(NMSettingDcb *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->priority_group_flags; +} + +/** + * nm_setting_dcb_get_priority_group_id: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to retrieve the group ID for + * + * Returns: the group number @user_priority is assigned to. These values are + * only valid when #NMSettingDcb:priority-group-flags includes the + * %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +guint +nm_setting_dcb_get_priority_group_id(NMSettingDcb *setting, guint user_priority) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + g_return_val_if_fail(user_priority <= 7, 0); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->priority_group_id[user_priority]; +} + +/** + * nm_setting_dcb_set_priority_group_id: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to set flow control for + * @group_id: the group (0 - 7) to assign @user_priority to, or 15 for the + * unrestricted group. + * + * These values are only valid when #NMSettingDcb:priority-group-flags includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_group_id(NMSettingDcb *setting, guint user_priority, guint group_id) +{ + NMSettingDcbPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_DCB(setting)); + g_return_if_fail(user_priority <= 7); + g_return_if_fail(group_id <= 7 || group_id == 15); + + priv = NM_SETTING_DCB_GET_PRIVATE(setting); + if (priv->priority_group_id[user_priority] != group_id) { + priv->priority_group_id[user_priority] = group_id; + _notify(setting, PROP_PRIORITY_GROUP_ID); + } +} + +/** + * nm_setting_dcb_get_priority_group_bandwidth: + * @setting: the #NMSettingDcb + * @group_id: the priority group (0 - 7) to retrieve the bandwidth percentage for + * + * Returns: the bandwidth percentage assigned to @group_id. These values are + * only valid when #NMSettingDcb:priority-group-flags includes the + * %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +guint +nm_setting_dcb_get_priority_group_bandwidth(NMSettingDcb *setting, guint group_id) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + g_return_val_if_fail(group_id <= 7, FALSE); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->priority_group_bandwidth[group_id]; +} + +/** + * nm_setting_dcb_set_priority_group_bandwidth: + * @setting: the #NMSettingDcb + * @group_id: the priority group (0 - 7) to set the bandwidth percentage for + * @bandwidth_percent: the bandwidth percentage (0 - 100) to assign to @group_id to + * + * These values are only valid when #NMSettingDcb:priority-group-flags includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_group_bandwidth(NMSettingDcb *setting, + guint group_id, + guint bandwidth_percent) +{ + NMSettingDcbPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_DCB(setting)); + g_return_if_fail(group_id <= 7); + g_return_if_fail(bandwidth_percent <= 100); + + priv = NM_SETTING_DCB_GET_PRIVATE(setting); + if (priv->priority_group_bandwidth[group_id] != bandwidth_percent) { + priv->priority_group_bandwidth[group_id] = bandwidth_percent; + _notify(setting, PROP_PRIORITY_GROUP_BANDWIDTH); + } +} + +/** + * nm_setting_dcb_get_priority_bandwidth: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to retrieve the group bandwidth percentage for + * + * Returns: the allowed bandwidth percentage of @user_priority in its priority group. + * These values are only valid when #NMSettingDcb:priority-group-flags includes the + * %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +guint +nm_setting_dcb_get_priority_bandwidth(NMSettingDcb *setting, guint user_priority) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + g_return_val_if_fail(user_priority <= 7, FALSE); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->priority_bandwidth[user_priority]; +} + +/** + * nm_setting_dcb_set_priority_bandwidth: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to set the bandwidth percentage for + * @bandwidth_percent: the bandwidth percentage (0 - 100) that @user_priority is + * allowed to use within its priority group + * + * These values are only valid when #NMSettingDcb:priority-group-flags includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_bandwidth(NMSettingDcb *setting, + guint user_priority, + guint bandwidth_percent) +{ + NMSettingDcbPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_DCB(setting)); + g_return_if_fail(user_priority <= 7); + g_return_if_fail(bandwidth_percent <= 100); + + priv = NM_SETTING_DCB_GET_PRIVATE(setting); + if (priv->priority_bandwidth[user_priority] != bandwidth_percent) { + priv->priority_bandwidth[user_priority] = bandwidth_percent; + _notify(setting, PROP_PRIORITY_BANDWIDTH); + } +} + +/** + * nm_setting_dcb_get_priority_strict_bandwidth: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to retrieve strict bandwidth for + * + * Returns: %TRUE if @user_priority may use all of the bandwidth allocated to its + * assigned group, or %FALSE if not. These values are only valid when + * #NMSettingDcb:priority-group-flags includes the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +gboolean +nm_setting_dcb_get_priority_strict_bandwidth(NMSettingDcb *setting, guint user_priority) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + g_return_val_if_fail(user_priority <= 7, FALSE); + + return !!NM_SETTING_DCB_GET_PRIVATE(setting)->priority_strict[user_priority]; +} + +/** + * nm_setting_dcb_set_priority_strict_bandwidth: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to set strict bandwidth for + * @strict: %TRUE to allow @user_priority to use all the bandwidth allocated to + * its priority group, or %FALSE if not + * + * These values are only valid when #NMSettingDcb:priority-group-flags includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_strict_bandwidth(NMSettingDcb *setting, + guint user_priority, + gboolean strict) +{ + NMSettingDcbPrivate *priv; + guint uint_strict = strict ? 1 : 0; + + g_return_if_fail(NM_IS_SETTING_DCB(setting)); + g_return_if_fail(user_priority <= 7); + + priv = NM_SETTING_DCB_GET_PRIVATE(setting); + if (priv->priority_strict[user_priority] != uint_strict) { + priv->priority_strict[user_priority] = uint_strict; + _notify(setting, PROP_PRIORITY_STRICT_BANDWIDTH); + } +} + +/** + * nm_setting_dcb_get_priority_traffic_class: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to retrieve the traffic class for + * + * Returns: the traffic class assigned to @user_priority. These values are only + * valid when #NMSettingDcb:priority-group-flags includes the + * %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +guint +nm_setting_dcb_get_priority_traffic_class(NMSettingDcb *setting, guint user_priority) +{ + g_return_val_if_fail(NM_IS_SETTING_DCB(setting), 0); + g_return_val_if_fail(user_priority <= 7, FALSE); + + return NM_SETTING_DCB_GET_PRIVATE(setting)->priority_traffic_class[user_priority]; +} + +/** + * nm_setting_dcb_set_priority_traffic_clas: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to set the bandwidth percentage for + * @traffic_class: the traffic_class (0 - 7) that @user_priority should map to + * + * These values are only valid when #NMSettingDcb:priority-group-flags includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_traffic_class(NMSettingDcb *setting, + guint user_priority, + guint traffic_class) +{ + NMSettingDcbPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_DCB(setting)); + g_return_if_fail(user_priority <= 7); + g_return_if_fail(traffic_class <= 7); + + priv = NM_SETTING_DCB_GET_PRIVATE(setting); + if (priv->priority_traffic_class[user_priority] != traffic_class) { + priv->priority_traffic_class[user_priority] = traffic_class; + _notify(setting, PROP_PRIORITY_TRAFFIC_CLASS); + } +} + +/*****************************************************************************/ + +#define DCB_FLAGS_ALL \ + (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE | NM_SETTING_DCB_FLAG_WILLING) + +static gboolean +check_dcb_flags(NMSettingDcbFlags flags, const char *prop_name, GError **error) +{ + if (flags & ~DCB_FLAGS_ALL) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("flags invalid")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE) && (flags & ~NM_SETTING_DCB_FLAG_ENABLE)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("flags invalid - disabled")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + + return TRUE; +} + +static gboolean +check_uint_array(const guint * array, + guint len, + NMSettingDcbFlags flags, + guint max, + guint extra, + gboolean sum_pct, + const char * prop_name, + GError ** error) +{ + guint i, sum = 0; + + /* Ensure each element is <= to max or equals extra */ + for (i = 0; i < len; i++) { + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE) && array[i]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property invalid (not enabled)")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + + if ((array[i] > max) && (array[i] != extra)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("element invalid")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + sum += array[i]; + } + + /* Verify sum of percentages */ + if (sum_pct) { + if (flags & NM_SETTING_DCB_FLAG_ENABLE) { + /* If the feature is enabled, sum must equal 100% */ + if (sum != 100) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("sum not 100%")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + } else { + /* If the feature is disabled, sum must equal 0%, which was checked + * by the for() loop above. + */ + g_assert_cmpint(sum, ==, 0); + } + } + + return TRUE; +} + +static gboolean +check_priority(int val, NMSettingDcbFlags flags, const char *prop_name, GError **error) +{ + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE) && (val >= 0)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property invalid (not enabled)")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + + if (val < -1 || val > 7) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property invalid")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + return TRUE; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE(setting); + + if (!check_dcb_flags(priv->app_fcoe_flags, NM_SETTING_DCB_APP_FCOE_FLAGS, error)) + return FALSE; + + if (!check_priority(priv->app_fcoe_priority, + priv->app_fcoe_flags, + NM_SETTING_DCB_APP_FCOE_PRIORITY, + error)) + return FALSE; + + if (!priv->app_fcoe_mode) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property missing")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, NM_SETTING_DCB_APP_FCOE_MODE); + return FALSE; + } + + if (strcmp(priv->app_fcoe_mode, NM_SETTING_DCB_FCOE_MODE_FABRIC) + && strcmp(priv->app_fcoe_mode, NM_SETTING_DCB_FCOE_MODE_VN2VN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property invalid")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, NM_SETTING_DCB_APP_FCOE_MODE); + return FALSE; + } + + if (!check_dcb_flags(priv->app_iscsi_flags, NM_SETTING_DCB_APP_ISCSI_FLAGS, error)) + return FALSE; + + if (!check_priority(priv->app_iscsi_priority, + priv->app_iscsi_flags, + NM_SETTING_DCB_APP_ISCSI_PRIORITY, + error)) + return FALSE; + + if (!check_dcb_flags(priv->app_fip_flags, NM_SETTING_DCB_APP_FIP_FLAGS, error)) + return FALSE; + + if (!check_priority(priv->app_fip_priority, + priv->app_fip_flags, + NM_SETTING_DCB_APP_FIP_PRIORITY, + error)) + return FALSE; + + if (!check_dcb_flags(priv->pfc_flags, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, error)) + return FALSE; + + if (!check_uint_array(priv->pfc, + G_N_ELEMENTS(priv->pfc), + priv->pfc_flags, + 1, + 0, + FALSE, + NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, + error)) + return FALSE; + + if (!check_dcb_flags(priv->priority_group_flags, NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, error)) + return FALSE; + + if (!check_uint_array(priv->priority_group_id, + G_N_ELEMENTS(priv->priority_group_id), + priv->priority_group_flags, + 7, + 15, + FALSE, + NM_SETTING_DCB_PRIORITY_GROUP_ID, + error)) + return FALSE; + + if (!check_uint_array(priv->priority_group_bandwidth, + G_N_ELEMENTS(priv->priority_group_bandwidth), + priv->priority_group_flags, + 100, + 0, + TRUE, + NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, + error)) + return FALSE; + + /* FIXME: sum bandwidths in each group */ + if (!check_uint_array(priv->priority_bandwidth, + G_N_ELEMENTS(priv->priority_bandwidth), + priv->priority_group_flags, + 100, + 0, + FALSE, + NM_SETTING_DCB_PRIORITY_BANDWIDTH, + error)) + return FALSE; + + if (!check_uint_array(priv->priority_strict, + G_N_ELEMENTS(priv->priority_strict), + priv->priority_group_flags, + 1, + 0, + FALSE, + NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, + error)) + return FALSE; + + if (!check_uint_array(priv->priority_traffic_class, + G_N_ELEMENTS(priv->priority_traffic_class), + priv->priority_group_flags, + 7, + 0, + FALSE, + NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, + error)) + return FALSE; + + return TRUE; +} + +/*****************************************************************************/ + +G_STATIC_ASSERT(sizeof(guint) == sizeof(gboolean)); + +static void +set_array_from_gvalue(const GValue *v, uint *a, size_t len) +{ + GArray * src = g_value_get_boxed(v); + const guint total_len = len * sizeof(a[0]); + + memset(a, 0, total_len); + if (src) { + g_return_if_fail(g_array_get_element_size(src) == sizeof(a[0])); + g_return_if_fail(src->len == len); + memcpy(a, src->data, total_len); + } +} +#define SET_ARRAY_FROM_GVALUE(v, a) set_array_from_gvalue(v, a, G_N_ELEMENTS(a)) + +static void +set_gvalue_from_array(GValue *v, uint *a, size_t len) +{ + GArray *src = g_array_sized_new(FALSE, TRUE, sizeof(guint), len); + + g_array_append_vals(src, a, len); + g_value_take_boxed(v, src); +} + +#define SET_GVALUE_FROM_ARRAY(v, a) set_gvalue_from_array(v, a, G_N_ELEMENTS(a)) + +static GVariant * +_nm_setting_dcb_uint_array_to_dbus(const GValue *prop_value) +{ + GArray *src = g_value_get_boxed(prop_value); + + return g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, src->data, src->len, sizeof(guint32)); +} + +static void +_nm_setting_dcb_uint_array_from_dbus(GVariant *dbus_value, GValue *prop_value) +{ + gconstpointer array; + gsize length; + + array = g_variant_get_fixed_array(dbus_value, &length, sizeof(guint32)); + set_gvalue_from_array(prop_value, (guint *) array, length); +} + +static const NMSettInfoPropertType nm_sett_info_propert_type_dcb_au = { + .dbus_type = NM_G_VARIANT_TYPE("au"), + .gprop_to_dbus_fcn = _nm_setting_dcb_uint_array_to_dbus, + .gprop_from_dbus_fcn = _nm_setting_dcb_uint_array_from_dbus, +}; + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingDcb * setting = NM_SETTING_DCB(object); + NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_APP_FCOE_FLAGS: + g_value_set_flags(value, priv->app_fcoe_flags); + break; + case PROP_APP_FCOE_PRIORITY: + g_value_set_int(value, priv->app_fcoe_priority); + break; + case PROP_APP_FCOE_MODE: + g_value_set_string(value, priv->app_fcoe_mode); + break; + case PROP_APP_ISCSI_FLAGS: + g_value_set_flags(value, priv->app_iscsi_flags); + break; + case PROP_APP_ISCSI_PRIORITY: + g_value_set_int(value, priv->app_iscsi_priority); + break; + case PROP_APP_FIP_FLAGS: + g_value_set_flags(value, priv->app_fip_flags); + break; + case PROP_APP_FIP_PRIORITY: + g_value_set_int(value, priv->app_fip_priority); + break; + case PROP_PFC_FLAGS: + g_value_set_flags(value, priv->pfc_flags); + break; + case PROP_PRIORITY_FLOW_CONTROL: + SET_GVALUE_FROM_ARRAY(value, priv->pfc); + break; + case PROP_PRIORITY_GROUP_FLAGS: + g_value_set_flags(value, priv->priority_group_flags); + break; + case PROP_PRIORITY_GROUP_ID: + SET_GVALUE_FROM_ARRAY(value, priv->priority_group_id); + break; + case PROP_PRIORITY_GROUP_BANDWIDTH: + SET_GVALUE_FROM_ARRAY(value, priv->priority_group_bandwidth); + break; + case PROP_PRIORITY_BANDWIDTH: + SET_GVALUE_FROM_ARRAY(value, priv->priority_bandwidth); + break; + case PROP_PRIORITY_STRICT_BANDWIDTH: + SET_GVALUE_FROM_ARRAY(value, priv->priority_strict); + break; + case PROP_PRIORITY_TRAFFIC_CLASS: + SET_GVALUE_FROM_ARRAY(value, priv->priority_traffic_class); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_APP_FCOE_FLAGS: + priv->app_fcoe_flags = g_value_get_flags(value); + break; + case PROP_APP_FCOE_PRIORITY: + priv->app_fcoe_priority = g_value_get_int(value); + break; + case PROP_APP_FCOE_MODE: + g_free(priv->app_fcoe_mode); + priv->app_fcoe_mode = g_value_dup_string(value); + break; + case PROP_APP_ISCSI_FLAGS: + priv->app_iscsi_flags = g_value_get_flags(value); + break; + case PROP_APP_ISCSI_PRIORITY: + priv->app_iscsi_priority = g_value_get_int(value); + break; + case PROP_APP_FIP_FLAGS: + priv->app_fip_flags = g_value_get_flags(value); + break; + case PROP_APP_FIP_PRIORITY: + priv->app_fip_priority = g_value_get_int(value); + break; + case PROP_PFC_FLAGS: + priv->pfc_flags = g_value_get_flags(value); + break; + case PROP_PRIORITY_FLOW_CONTROL: + SET_ARRAY_FROM_GVALUE(value, priv->pfc); + break; + case PROP_PRIORITY_GROUP_FLAGS: + priv->priority_group_flags = g_value_get_flags(value); + break; + case PROP_PRIORITY_GROUP_ID: + SET_ARRAY_FROM_GVALUE(value, priv->priority_group_id); + break; + case PROP_PRIORITY_GROUP_BANDWIDTH: + SET_ARRAY_FROM_GVALUE(value, priv->priority_group_bandwidth); + break; + case PROP_PRIORITY_BANDWIDTH: + SET_ARRAY_FROM_GVALUE(value, priv->priority_bandwidth); + break; + case PROP_PRIORITY_STRICT_BANDWIDTH: + SET_ARRAY_FROM_GVALUE(value, priv->priority_strict); + break; + case PROP_PRIORITY_TRAFFIC_CLASS: + SET_ARRAY_FROM_GVALUE(value, priv->priority_traffic_class); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_dcb_init(NMSettingDcb *self) +{ + NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE(self); + + priv->app_fcoe_mode = g_strdup(NM_SETTING_DCB_FCOE_MODE_FABRIC); + priv->app_fcoe_priority = -1; + priv->app_fip_priority = -1; + priv->app_iscsi_priority = -1; +} + +/** + * nm_setting_dcb_new: + * + * Creates a new #NMSettingDcb object with default values. + * + * Returns: (transfer full): the new empty #NMSettingDcb object + **/ +NMSetting * +nm_setting_dcb_new(void) +{ + return g_object_new(NM_TYPE_SETTING_DCB, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE(object); + + g_free(priv->app_fcoe_mode); + + G_OBJECT_CLASS(nm_setting_dcb_parent_class)->finalize(object); +} + +static void +nm_setting_dcb_class_init(NMSettingDcbClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingDcbPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingDcb:app-fcoe-flags: + * + * Specifies the #NMSettingDcbFlags for the DCB FCoE application. Flags may + * be any combination of %NM_SETTING_DCB_FLAG_ENABLE, + * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING. + **/ + /* ---ifcfg-rh--- + * property: app-fcoe-flags + * variable: DCB_APP_FCOE_ENABLE, DCB_APP_FCOE_ADVERTISE, DCB_APP_FCOE_WILLING + * description: FCOE flags. + * default: no + * example: DCB_APP_FCOE_ENABLE=yes DCB_APP_FCOE_ADVERTISE=yes + * ---end--- + */ + obj_properties[PROP_APP_FCOE_FLAGS] = + g_param_spec_flags(NM_SETTING_DCB_APP_FCOE_FLAGS, + "", + "", + NM_TYPE_SETTING_DCB_FLAGS, + NM_SETTING_DCB_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingDcb:app-fcoe-priority: + * + * The highest User Priority (0 - 7) which FCoE frames should use, or -1 for + * default priority. Only used when the #NMSettingDcb:app-fcoe-flags + * property includes the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ + /* ---ifcfg-rh--- + * property: app-fcoe-priority + * variable: DCB_APP_FCOE_PRIORITY + * values: 0 - 7 + * description: Priority of FCoE frames. + * ---end--- + */ + obj_properties[PROP_APP_FCOE_PRIORITY] = + g_param_spec_int(NM_SETTING_DCB_APP_FCOE_PRIORITY, + "", + "", + -1, + 7, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingDcb:app-fcoe-mode: + * + * The FCoE controller mode; either %NM_SETTING_DCB_FCOE_MODE_FABRIC + * (default) or %NM_SETTING_DCB_FCOE_MODE_VN2VN. + **/ + /* ---ifcfg-rh--- + * property: app-fcoe-mode + * variable: DCB_APP_FCOE_MODE + * values: fabric, vn2vn + * default: fabric + * description: FCoE controller mode. + * ---end--- + */ + obj_properties[PROP_APP_FCOE_MODE] = + g_param_spec_string(NM_SETTING_DCB_APP_FCOE_MODE, + "", + "", + NM_SETTING_DCB_FCOE_MODE_FABRIC, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingDcb:app-iscsi-flags: + * + * Specifies the #NMSettingDcbFlags for the DCB iSCSI application. Flags + * may be any combination of %NM_SETTING_DCB_FLAG_ENABLE, + * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING. + **/ + /* ---ifcfg-rh--- + * property: app-iscsi-flags + * variable: DCB_APP_ISCSI_ENABLE, DCB_APP_ISCSI_ADVERTISE, DCB_APP_ISCSI_WILLING + * default: no + * description: iSCSI flags. + * ---end--- + */ + obj_properties[PROP_APP_ISCSI_FLAGS] = + g_param_spec_flags(NM_SETTING_DCB_APP_ISCSI_FLAGS, + "", + "", + NM_TYPE_SETTING_DCB_FLAGS, + NM_SETTING_DCB_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingDcb:app-iscsi-priority: + * + * The highest User Priority (0 - 7) which iSCSI frames should use, or -1 + * for default priority. Only used when the #NMSettingDcb:app-iscsi-flags + * property includes the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ + /* ---ifcfg-rh--- + * property: app-iscsi-priority + * variable: DCB_APP_ISCSI_PRIORITY + * values: 0 - 7 + * description: Priority of iSCSI frames. + * ---end--- + */ + obj_properties[PROP_APP_ISCSI_PRIORITY] = + g_param_spec_int(NM_SETTING_DCB_APP_ISCSI_PRIORITY, + "", + "", + -1, + 7, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingDcb:app-fip-flags: + * + * Specifies the #NMSettingDcbFlags for the DCB FIP application. Flags may + * be any combination of %NM_SETTING_DCB_FLAG_ENABLE, + * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING. + **/ + /* ---ifcfg-rh--- + * property: app-fip-flags + * variable: DCB_APP_FIP_ENABLE, DCB_APP_FIP_ADVERTISE, DCB_APP_FIP_WILLING + * default: no + * description: FIP flags. + * ---end--- + */ + obj_properties[PROP_APP_FIP_FLAGS] = + g_param_spec_flags(NM_SETTING_DCB_APP_FIP_FLAGS, + "", + "", + NM_TYPE_SETTING_DCB_FLAGS, + NM_SETTING_DCB_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingDcb:app-fip-priority: + * + * The highest User Priority (0 - 7) which FIP frames should use, or -1 for + * default priority. Only used when the #NMSettingDcb:app-fip-flags + * property includes the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ + /* ---ifcfg-rh--- + * property: app-fip-priority + * variable: DCB_APP_FIP_PRIORITY + * values: 0 - 7 + * description: Priority of FIP frames. + * ---end--- + */ + obj_properties[PROP_APP_FIP_PRIORITY] = + g_param_spec_int(NM_SETTING_DCB_APP_FIP_PRIORITY, + "", + "", + -1, + 7, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingDcb:priority-flow-control-flags: + * + * Specifies the #NMSettingDcbFlags for DCB Priority Flow Control (PFC). + * Flags may be any combination of %NM_SETTING_DCB_FLAG_ENABLE, + * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING. + **/ + /* ---ifcfg-rh--- + * property: priority-flow-control-flags + * variable: DCB_PFC_ENABLE, DCB_PFC_ADVERTISE, DCB_PFC_WILLING + * default: no + * description: Priority flow control flags. + * ---end--- + */ + obj_properties[PROP_PFC_FLAGS] = g_param_spec_flags(NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, + "", + "", + NM_TYPE_SETTING_DCB_FLAGS, + NM_SETTING_DCB_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingDcb:priority-flow-control: (type GArray(gboolean)) + * + * An array of 8 boolean values, where the array index corresponds to the User + * Priority (0 - 7) and the value indicates whether or not the corresponding + * priority should transmit priority pause. + **/ + /* ---ifcfg-rh--- + * property: priority-flow-control + * variable: DCB_PFC_UP + * description: Priority flow control values. String of 8 "0" and "1", where "0". + * means "do not transmit priority pause", "1" means "transmit pause". + * example: DCB_PFC_UP=01101110 + * ---end--- + */ + obj_properties[PROP_PRIORITY_FLOW_CONTROL] = + g_param_spec_boxed(NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, + "", + "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_PRIORITY_FLOW_CONTROL], + &nm_sett_info_propert_type_dcb_au); + + /** + * NMSettingDcb:priority-group-flags: + * + * Specifies the #NMSettingDcbFlags for DCB Priority Groups. Flags may be + * any combination of %NM_SETTING_DCB_FLAG_ENABLE, + * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING. + **/ + /* ---ifcfg-rh--- + * property: priority-group-flags + * variable: DCB_PG_ENABLE, DCB_PG_ADVERTISE, DCB_PG_WILLING + * default: no + * description: Priority groups flags. + * ---end--- + */ + obj_properties[PROP_PRIORITY_GROUP_FLAGS] = + g_param_spec_flags(NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, + "", + "", + NM_TYPE_SETTING_DCB_FLAGS, + NM_SETTING_DCB_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingDcb:priority-group-id: (type GArray(guint)) + * + * An array of 8 uint values, where the array index corresponds to the User + * Priority (0 - 7) and the value indicates the Priority Group ID. Allowed + * Priority Group ID values are 0 - 7 or 15 for the unrestricted group. + **/ + /* ---ifcfg-rh--- + * property: priority-group-id + * variable: DCB_PG_ID + * description: Priority groups values. String of eight priorities (0 - 7) or "f" + * (unrestricted). + * example: DCB_PG_ID=1205f173 + * ---end--- + */ + obj_properties[PROP_PRIORITY_GROUP_ID] = + g_param_spec_boxed(NM_SETTING_DCB_PRIORITY_GROUP_ID, + "", + "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_PRIORITY_GROUP_ID], + &nm_sett_info_propert_type_dcb_au); + + /** + * NMSettingDcb:priority-group-bandwidth: (type GArray(guint)) + * + * An array of 8 uint values, where the array index corresponds to the + * Priority Group ID (0 - 7) and the value indicates the percentage of link + * bandwidth allocated to that group. Allowed values are 0 - 100, and the + * sum of all values must total 100 percents. + **/ + /* ---ifcfg-rh--- + * property: priority-group-bandwidth + * variable: DCB_PG_PCT + * description: Priority groups values. Eight bandwidths (in percent), separated with commas. + * example: DCB_PG_PCT=10,5,10,15,10,10,10,30 + * ---end--- + */ + obj_properties[PROP_PRIORITY_GROUP_BANDWIDTH] = + g_param_spec_boxed(NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, + "", + "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_PRIORITY_GROUP_BANDWIDTH], + &nm_sett_info_propert_type_dcb_au); + + /** + * NMSettingDcb:priority-bandwidth: (type GArray(guint)) + * + * An array of 8 uint values, where the array index corresponds to the User + * Priority (0 - 7) and the value indicates the percentage of bandwidth of + * the priority's assigned group that the priority may use. The sum of all + * percentages for priorities which belong to the same group must total 100 + * percents. + **/ + /* ---ifcfg-rh--- + * property: priority-bandwidth + * variable: DCB_PG_UPPCT + * description: Priority values. Eight bandwidths (in percent), separated with commas. + * The sum of the numbers must be 100. + * example: DCB_PG_UPPCT=7,13,10,10,15,15,10,20 + * ---end--- + */ + obj_properties[PROP_PRIORITY_BANDWIDTH] = + g_param_spec_boxed(NM_SETTING_DCB_PRIORITY_BANDWIDTH, + "", + "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_PRIORITY_BANDWIDTH], + &nm_sett_info_propert_type_dcb_au); + + /** + * NMSettingDcb:priority-strict-bandwidth: (type GArray(gboolean)) + * + * An array of 8 boolean values, where the array index corresponds to the User + * Priority (0 - 7) and the value indicates whether or not the priority may + * use all of the bandwidth allocated to its assigned group. + **/ + /* ---ifcfg-rh--- + * property: priority-strict-bandwidth + * variable: DCB_PG_STRICT + * description: Priority values. String of eight "0" or "1", where "0" means + * "may not utilize all bandwidth", "1" means "may utilize all bandwidth". + * example: DCB_PG_STRICT=01101110 + * ---end--- + */ + obj_properties[PROP_PRIORITY_STRICT_BANDWIDTH] = + g_param_spec_boxed(NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, + "", + "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_PRIORITY_STRICT_BANDWIDTH], + &nm_sett_info_propert_type_dcb_au); + + /** + * NMSettingDcb:priority-traffic-class: (type GArray(guint)) + * + * An array of 8 uint values, where the array index corresponds to the User + * Priority (0 - 7) and the value indicates the traffic class (0 - 7) to + * which the priority is mapped. + **/ + /* ---ifcfg-rh--- + * property: priority-traffic-class + * variable: DCB_PG_UP2TC + * description: Priority values. String of eight traffic class values (0 - 7). + * example: DCB_PG_UP2TC=01623701 + * ---end--- + */ + obj_properties[PROP_PRIORITY_TRAFFIC_CLASS] = + g_param_spec_boxed(NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, + "", + "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_PRIORITY_TRAFFIC_CLASS], + &nm_sett_info_propert_type_dcb_au); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_DCB, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-dummy.c b/src/libnm-core-impl/nm-setting-dummy.c new file mode 100644 index 0000000..f2b479b --- /dev/null +++ b/src/libnm-core-impl/nm-setting-dummy.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-dummy.h" + +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-dummy + * @short_description: Describes connection properties for dummy interfaces + * + * The #NMSettingDummy object is a #NMSetting subclass that describes properties + * necessary for connection to dummy devices + **/ + +/*****************************************************************************/ + +G_DEFINE_TYPE(NMSettingDummy, nm_setting_dummy, NM_TYPE_SETTING) + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + return TRUE; +} + +/*****************************************************************************/ + +static void +nm_setting_dummy_init(NMSettingDummy *setting) +{} + +/** + * nm_setting_dummy_new: + * + * Creates a new #NMSettingDummy object with default values. + * + * Returns: (transfer full): the new empty #NMSettingDummy object + * + * Since: 1.8 + **/ +NMSetting * +nm_setting_dummy_new(void) +{ + return g_object_new(NM_TYPE_SETTING_DUMMY, NULL); +} + +static void +nm_setting_dummy_class_init(NMSettingDummyClass *klass) +{ + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + setting_class->verify = verify; + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_DUMMY); +} diff --git a/src/libnm-core-impl/nm-setting-ethtool.c b/src/libnm-core-impl/nm-setting-ethtool.c new file mode 100644 index 0000000..b32372e --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ethtool.c @@ -0,0 +1,378 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ethtool.h" + +#include "nm-setting-private.h" +#include "libnm-base/nm-ethtool-base.h" + +/*****************************************************************************/ + +/** + * SECTION:nm-setting-ethtool + * @short_description: Describes connection properties for ethtool related options + * + * The #NMSettingEthtool object is a #NMSetting subclass that describes properties + * to control network driver and hardware settings. + **/ + +/*****************************************************************************/ + +static const GVariantType * +get_variant_type_from_ethtool_id(NMEthtoolID ethtool_id) +{ + if (nm_ethtool_id_is_feature(ethtool_id)) + return G_VARIANT_TYPE_BOOLEAN; + + if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id)) + return G_VARIANT_TYPE_UINT32; + + return NULL; +} + +/*****************************************************************************/ + +/** + * nm_ethtool_optname_is_feature: + * @optname: (allow-none): the option name to check + * + * Checks whether @optname is a valid option name for an offload feature. + * + * %Returns: %TRUE, if @optname is valid + * + * Since: 1.20 + * + * Note that nm_ethtool_optname_is_feature() was first added to the libnm header files + * in 1.14.0 but forgot to actually add to the library. This happened belatedly in 1.20.0 and + * the stable versions 1.18.2, 1.16.4 and 1.14.8 (with linker version "libnm_1_14_8"). + */ +gboolean +nm_ethtool_optname_is_feature(const char *optname) +{ + return optname && nm_ethtool_id_is_feature(nm_ethtool_id_get_by_name(optname)); +} + +/** + * nm_ethtool_optname_is_coalesce: + * @optname: (allow-none): the option name to check + * + * Checks whether @optname is a valid option name for a coalesce setting. + * + * %Returns: %TRUE, if @optname is valid + * + * Since: 1.26 + */ +gboolean +nm_ethtool_optname_is_coalesce(const char *optname) +{ + return optname && nm_ethtool_id_is_coalesce(nm_ethtool_id_get_by_name(optname)); +} + +/** + * nm_ethtool_optname_is_ring: + * @optname: (allow-none): the option name to check + * + * Checks whether @optname is a valid option name for a ring setting. + * + * %Returns: %TRUE, if @optname is valid + * + * Since: 1.26 + */ +gboolean +nm_ethtool_optname_is_ring(const char *optname) +{ + return optname && nm_ethtool_id_is_ring(nm_ethtool_id_get_by_name(optname)); +} + +/*****************************************************************************/ + +/** + * NMSettingEthtool: + * + * Ethtool Ethernet Settings + * + * Since: 1.14 + */ +struct _NMSettingEthtool { + NMSetting parent; +}; + +struct _NMSettingEthtoolClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingEthtool, nm_setting_ethtool, NM_TYPE_SETTING) + +#define NM_SETTING_ETHTOOL_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSettingEthtool, NM_IS_SETTING_ETHTOOL, NMSetting) + +/*****************************************************************************/ + +/** + * nm_setting_ethtool_get_feature: + * @setting: the #NMSettingEthtool + * @optname: option name of the offload feature to get + * + * Gets and offload feature setting. Returns %NM_TERNARY_DEFAULT if the + * feature is not set. + * + * Note that @optname must be a valid name for a feature, according to + * nm_ethtool_optname_is_feature(). + * + * Returns: a #NMTernary value indicating whether the offload feature + * is enabled, disabled, or left untouched. + * + * Since: 1.14 + * + * Deprecated: 1.26: use nm_setting_option_get_boolean() instead. + */ +NMTernary +nm_setting_ethtool_get_feature(NMSettingEthtool *setting, const char *optname) +{ + gboolean v; + + g_return_val_if_fail(NM_IS_SETTING_ETHTOOL(setting), NM_TERNARY_DEFAULT); + g_return_val_if_fail(optname && nm_ethtool_optname_is_feature(optname), NM_TERNARY_DEFAULT); + + if (!nm_setting_option_get_boolean(NM_SETTING(setting), optname, &v)) + return NM_TERNARY_DEFAULT; + return v ? NM_TERNARY_TRUE : NM_TERNARY_FALSE; +} + +/** + * nm_setting_ethtool_set_feature: + * @setting: the #NMSettingEthtool + * @optname: option name of the offload feature to get + * @value: the new value to set. The special value %NM_TERNARY_DEFAULT + * means to clear the offload feature setting. + * + * Sets and offload feature setting. + * + * Note that @optname must be a valid name for a feature, according to + * nm_ethtool_optname_is_feature(). + * + * Since: 1.14 + * + * Deprecated: 1.26: use nm_setting_option_set() or nm_setting_option_set_boolean() instead. + */ +void +nm_setting_ethtool_set_feature(NMSettingEthtool *setting, const char *optname, NMTernary value) +{ + g_return_if_fail(NM_IS_SETTING_ETHTOOL(setting)); + g_return_if_fail(optname && nm_ethtool_optname_is_feature(optname)); + g_return_if_fail(NM_IN_SET(value, NM_TERNARY_DEFAULT, NM_TERNARY_FALSE, NM_TERNARY_TRUE)); + + if (value == NM_TERNARY_DEFAULT) + nm_setting_option_set(NM_SETTING(setting), optname, NULL); + else + nm_setting_option_set_boolean(NM_SETTING(setting), optname, (value != NM_TERNARY_FALSE)); +} + +/** + * nm_setting_ethtool_clear_features: + * @setting: the #NMSettingEthtool + * + * Clears all offload features settings + * + * Since: 1.14 + * + * Deprecated: 1.26: use nm_setting_option_clear_by_name() with nm_ethtool_optname_is_feature() predicate instead. + */ +void +nm_setting_ethtool_clear_features(NMSettingEthtool *setting) +{ + g_return_if_fail(NM_IS_SETTING_ETHTOOL(setting)); + + nm_setting_option_clear_by_name(NM_SETTING(setting), nm_ethtool_optname_is_feature); +} + +/*****************************************************************************/ + +guint +nm_setting_ethtool_init_features( + NMSettingEthtool *setting, + NMOptionBool * requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */) +{ + GHashTable * hash; + GHashTableIter iter; + guint i; + guint n_req = 0; + const char * name; + GVariant * variant; + + nm_assert(NM_IS_SETTING_ETHTOOL(setting)); + nm_assert(requested); + + for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) + requested[i] = NM_OPTION_BOOL_DEFAULT; + + hash = _nm_setting_option_hash(NM_SETTING(setting), FALSE); + if (!hash) + return 0; + + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) { + NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name(name); + + if (!nm_ethtool_id_is_feature(ethtool_id)) + continue; + if (!g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)) + continue; + + requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX(ethtool_id)] = + g_variant_get_boolean(variant) ? NM_OPTION_BOOL_TRUE : NM_OPTION_BOOL_FALSE; + n_req++; + } + + return n_req; +} + +/*****************************************************************************/ + +/** + * nm_setting_ethtool_get_optnames: + * @setting: the #NMSettingEthtool instance. + * @out_length: (out) (optional): return location for the number of keys returned, or %NULL + * + * This returns all options names that are set. This includes the feature names + * like %NM_ETHTOOL_OPTNAME_FEATURE_GRO. See nm_ethtool_optname_is_feature() to + * check whether the option name is valid for offload features. + * + * Returns: (array zero-terminated=1) (transfer container): list of set option + * names or %NULL if no options are set. The option names are still owned by + * @setting and may get invalidated when @setting gets modified. + * + * Since: 1.20 + * + * Deprecated: 1.26: use nm_setting_option_get_all_names() instead. + */ +const char ** +nm_setting_ethtool_get_optnames(NMSettingEthtool *setting, guint *out_length) +{ + const char *const *names; + guint len = 0; + + g_return_val_if_fail(NM_IS_SETTING_ETHTOOL(setting), NULL); + + names = nm_setting_option_get_all_names(NM_SETTING(setting), &len); + NM_SET_OUT(out_length, len); + return len > 0 ? nm_memdup(names, sizeof(names[0]) * (((gsize) len) + 1u)) : NULL; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + const char *const *optnames; + GVariant *const * variants; + guint len; + guint i; + + len = _nm_setting_option_get_all(setting, &optnames, &variants); + + for (i = 0; i < len; i++) { + const char * optname = optnames[i]; + GVariant * variant = variants[i]; + const GVariantType *variant_type; + NMEthtoolID ethtool_id; + + ethtool_id = nm_ethtool_id_get_by_name(optname); + variant_type = get_variant_type_from_ethtool_id(ethtool_id); + + if (!variant_type) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unsupported ethtool setting")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_ETHTOOL_SETTING_NAME, optname); + return FALSE; + } + + if (!g_variant_is_of_type(variant, variant_type)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("setting has invalid variant type")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_ETHTOOL_SETTING_NAME, optname); + return FALSE; + } + + if (NM_IN_SET(ethtool_id, + NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX, + NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX)) { + if (!NM_IN_SET(g_variant_get_uint32(variant), 0, 1)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("coalesce option must be either 0 or 1")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_ETHTOOL_SETTING_NAME, optname); + return FALSE; + } + } + } + + return TRUE; +} + +/*****************************************************************************/ + +static const GVariantType * +get_variant_type(const NMSettInfoSetting *sett_info, const char *name, GError **error) +{ + const GVariantType *variant_type; + + variant_type = get_variant_type_from_ethtool_id(nm_ethtool_id_get_by_name(name)); + + if (!variant_type) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unknown ethtool option '%s'"), + name); + return NULL; + } + + return variant_type; +} + +/*****************************************************************************/ + +static void +nm_setting_ethtool_init(NMSettingEthtool *setting) +{} + +/** + * nm_setting_ethtool_new: + * + * Creates a new #NMSettingEthtool object with default values. + * + * Returns: (transfer full): the new empty #NMSettingEthtool object + * + * Since: 1.14 + **/ +NMSetting * +nm_setting_ethtool_new(void) +{ + return g_object_new(NM_TYPE_SETTING_ETHTOOL, NULL); +} + +static void +nm_setting_ethtool_class_init(NMSettingEthtoolClass *klass) +{ + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + setting_class->verify = verify; + + _nm_setting_class_commit_full( + setting_class, + NM_META_SETTING_TYPE_ETHTOOL, + NM_SETT_INFO_SETT_DETAIL(.gendata_info = + NM_SETT_INFO_SETT_GENDATA(.get_variant_type = + get_variant_type, ), ), + NULL); +} diff --git a/src/libnm-core-impl/nm-setting-generic.c b/src/libnm-core-impl/nm-setting-generic.c new file mode 100644 index 0000000..70752c0 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-generic.c @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-generic.h" + +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-generic + * @short_description: Describes connection properties for generic devices + * + * The #NMSettingGeneric object is a #NMSetting subclass that describes + * optional properties that apply to "generic" devices (ie, devices that + * NetworkManager does not specifically recognize). + * + * There are currently no properties on this object; it exists only to be + * the "connection type" setting on #NMConnections for generic devices. + **/ + +/*****************************************************************************/ + +typedef struct { + int dummy; +} NMSettingGenericPrivate; + +G_DEFINE_TYPE(NMSettingGeneric, nm_setting_generic, NM_TYPE_SETTING) + +#define NM_SETTING_GENERIC_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_GENERIC, NMSettingGenericPrivate)) + +/*****************************************************************************/ + +static void +nm_setting_generic_init(NMSettingGeneric *setting) +{} + +/** + * nm_setting_generic_new: + * + * Creates a new #NMSettingGeneric object with default values. + * + * Returns: (transfer full): the new empty #NMSettingGeneric object + **/ +NMSetting * +nm_setting_generic_new(void) +{ + return g_object_new(NM_TYPE_SETTING_GENERIC, NULL); +} + +static void +nm_setting_generic_class_init(NMSettingGenericClass *klass) +{ + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingGenericPrivate)); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_GENERIC); +} diff --git a/src/libnm-core-impl/nm-setting-gsm.c b/src/libnm-core-impl/nm-setting-gsm.c new file mode 100644 index 0000000..a148e13 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-gsm.c @@ -0,0 +1,868 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-gsm.h" + +#include "nm-utils.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-gsm + * @short_description: Describes GSM/3GPP-based mobile broadband properties + * + * The #NMSettingGsm object is a #NMSetting subclass that describes + * properties that allow connections to 3GPP-based mobile broadband + * networks, including those using GPRS/EDGE and UMTS/HSPA technology. + */ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_AUTO_CONFIG, + PROP_NUMBER, + PROP_USERNAME, + PROP_PASSWORD, + PROP_PASSWORD_FLAGS, + PROP_APN, + PROP_NETWORK_ID, + PROP_PIN, + PROP_PIN_FLAGS, + PROP_HOME_ONLY, + PROP_DEVICE_ID, + PROP_SIM_ID, + PROP_SIM_OPERATOR_ID, + PROP_MTU, ); + +typedef struct { + char * number; /* For dialing, duh */ + char * username; + char * password; + char * device_id; + char * sim_id; + char * sim_operator_id; + char * apn; /* NULL for dynamic */ + char * network_id; /* for manual registration or NULL for automatic */ + char * pin; + NMSettingSecretFlags password_flags; + NMSettingSecretFlags pin_flags; + guint32 mtu; + bool auto_config : 1; + bool home_only : 1; +} NMSettingGsmPrivate; + +G_DEFINE_TYPE(NMSettingGsm, nm_setting_gsm, NM_TYPE_SETTING) + +#define NM_SETTING_GSM_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_GSM, NMSettingGsmPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_gsm_get_auto_config: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:auto-config property of the setting + * + * Since: 1.22 + **/ +gboolean +nm_setting_gsm_get_auto_config(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), FALSE); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->auto_config; +} + +/** + * nm_setting_gsm_get_number: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:number property of the setting + * + * Deprecated: 1.16: User-provided values for this setting are no longer used. + **/ +const char * +nm_setting_gsm_get_number(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->number; +} + +/** + * nm_setting_gsm_get_username: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:username property of the setting + **/ +const char * +nm_setting_gsm_get_username(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->username; +} + +/** + * nm_setting_gsm_get_password: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:password property of the setting + **/ +const char * +nm_setting_gsm_get_password(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->password; +} + +/** + * nm_setting_gsm_get_password_flags: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingGsm:password + **/ +NMSettingSecretFlags +nm_setting_gsm_get_password_flags(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->password_flags; +} + +/** + * nm_setting_gsm_get_apn: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:apn property of the setting + **/ +const char * +nm_setting_gsm_get_apn(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->apn; +} + +/** + * nm_setting_gsm_get_network_id: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:network-id property of the setting + **/ +const char * +nm_setting_gsm_get_network_id(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->network_id; +} + +/** + * nm_setting_gsm_get_pin: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:pin property of the setting + **/ +const char * +nm_setting_gsm_get_pin(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->pin; +} + +/** + * nm_setting_gsm_get_pin_flags: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingGsm:pin + **/ +NMSettingSecretFlags +nm_setting_gsm_get_pin_flags(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->pin_flags; +} + +/** + * nm_setting_gsm_get_home_only: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:home-only property of the setting + **/ +gboolean +nm_setting_gsm_get_home_only(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), FALSE); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->home_only; +} + +/** + * nm_setting_gsm_get_device_id: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:device-id property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_gsm_get_device_id(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->device_id; +} + +/** + * nm_setting_gsm_get_sim_id: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:sim-id property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_gsm_get_sim_id(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->sim_id; +} + +/** + * nm_setting_gsm_get_sim_operator_id: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:sim-operator-id property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_gsm_get_sim_operator_id(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->sim_operator_id; +} + +/** + * nm_setting_gsm_get_mtu: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:mtu property of the setting + * + * Since: 1.8 + **/ +guint32 +nm_setting_gsm_get_mtu(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), 0); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->mtu; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE(setting); + + if (priv->number && !priv->number[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_NUMBER); + return FALSE; + } + + if (priv->apn) { + gsize apn_len = strlen(priv->apn); + gsize i; + + if (apn_len > 64) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property value '%s' is empty or too long (>64)"), + priv->apn); + g_prefix_error(error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_APN); + return FALSE; + } + + /* APNs roughly follow the same rules as DNS domain names. Allowed + * characters are a-z, 0-9, . and -. GSM 03.03 Section 9.1 states: + * + * The syntax of the APN shall follow the Name Syntax defined in + * RFC 2181 [14] and RFC 1035 [15]. The APN consists of one or + * more labels. Each label is coded as one octet length field + * followed by that number of octets coded as 8 bit ASCII characters. + * Following RFC 1035 [15] the labels should consist only of the + * alphabetic characters (A-Z and a-z), digits (0-9) and the + * dash (-). The case of alphabetic characters is not significant. + * + * A dot (.) is commonly used to separate parts of the APN, and + * apparently the underscore (_) is used as well. RFC 2181 indicates + * that no restrictions of any kind are placed on DNS labels, and thus + * it would appear that none are placed on APNs either, but many modems + * and networks will fail to accept APNs that include odd characters + * like space ( ) and such. + */ + for (i = 0; i < apn_len; i++) { + if (!g_ascii_isalnum(priv->apn[i]) && (priv->apn[i] != '.') && (priv->apn[i] != '_') + && (priv->apn[i] != '-')) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' contains invalid char(s) (use [A-Za-z._-])"), + priv->apn); + g_prefix_error(error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_APN); + return FALSE; + } + } + } + + if (priv->username && priv->username[0] == '\0') { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_USERNAME); + return FALSE; + } + + if (priv->network_id) { + gsize nid_len = strlen(priv->network_id); + gsize i; + + /* Accept both 5 and 6 digit MCC/MNC codes */ + if ((nid_len < 5) || (nid_len > 6)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' length is invalid (should be 5 or 6 digits)"), + priv->network_id); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_NETWORK_ID); + return FALSE; + } + + for (i = 0; i < nid_len; i++) { + if (!g_ascii_isdigit(priv->network_id[i])) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a number"), + priv->network_id); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_NETWORK_ID); + return FALSE; + } + } + } + + if (priv->device_id && !priv->device_id[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_DEVICE_ID); + return FALSE; + } + + if (priv->sim_id && !priv->sim_id[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_SIM_ID); + return FALSE; + } + + if (priv->sim_operator_id) { + size_t len = strlen(priv->sim_operator_id); + const char *p = priv->sim_operator_id; + + if (len == 0 || (len != 5 && len != 6)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty or wrong size")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_SIM_OPERATOR_ID); + return FALSE; + } + + while (p && *p) { + if (!g_ascii_isdigit(*p++)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property must contain only digits")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_SIM_OPERATOR_ID); + return FALSE; + } + } + } + + if (priv->auto_config && (priv->apn || priv->username || priv->password)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("can't be enabled when manual configuration is present")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_AUTO_CONFIG); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + return TRUE; +} + +static gboolean +verify_secrets(NMSetting *setting, NMConnection *connection, GError **error) +{ + return _nm_setting_verify_secret_string(NM_SETTING_GSM_GET_PRIVATE(setting)->password, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_GSM_PASSWORD, + error); +} + +static GPtrArray * +need_secrets(NMSetting *setting) +{ + NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE(setting); + GPtrArray * secrets = NULL; + + if (priv->password && *priv->password) + return NULL; + + if (priv->username) { + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new(1); + g_ptr_array_add(secrets, NM_SETTING_GSM_PASSWORD); + } + } + + return secrets; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingGsm *setting = NM_SETTING_GSM(object); + + switch (prop_id) { + case PROP_AUTO_CONFIG: + g_value_set_boolean(value, nm_setting_gsm_get_auto_config(setting)); + break; + case PROP_NUMBER: + g_value_set_string(value, nm_setting_gsm_get_number(setting)); + break; + case PROP_USERNAME: + g_value_set_string(value, nm_setting_gsm_get_username(setting)); + break; + case PROP_PASSWORD: + g_value_set_string(value, nm_setting_gsm_get_password(setting)); + break; + case PROP_PASSWORD_FLAGS: + g_value_set_flags(value, nm_setting_gsm_get_password_flags(setting)); + break; + case PROP_APN: + g_value_set_string(value, nm_setting_gsm_get_apn(setting)); + break; + case PROP_NETWORK_ID: + g_value_set_string(value, nm_setting_gsm_get_network_id(setting)); + break; + case PROP_PIN: + g_value_set_string(value, nm_setting_gsm_get_pin(setting)); + break; + case PROP_PIN_FLAGS: + g_value_set_flags(value, nm_setting_gsm_get_pin_flags(setting)); + break; + case PROP_HOME_ONLY: + g_value_set_boolean(value, nm_setting_gsm_get_home_only(setting)); + break; + case PROP_DEVICE_ID: + g_value_set_string(value, nm_setting_gsm_get_device_id(setting)); + break; + case PROP_SIM_ID: + g_value_set_string(value, nm_setting_gsm_get_sim_id(setting)); + break; + case PROP_SIM_OPERATOR_ID: + g_value_set_string(value, nm_setting_gsm_get_sim_operator_id(setting)); + break; + case PROP_MTU: + g_value_set_uint(value, nm_setting_gsm_get_mtu(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE(object); + char * tmp; + + switch (prop_id) { + case PROP_AUTO_CONFIG: + priv->auto_config = g_value_get_boolean(value); + break; + case PROP_NUMBER: + g_free(priv->number); + priv->number = g_value_dup_string(value); + break; + case PROP_USERNAME: + g_free(priv->username); + priv->username = g_value_dup_string(value); + break; + case PROP_PASSWORD: + g_free(priv->password); + priv->password = g_value_dup_string(value); + break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_flags(value); + break; + case PROP_APN: + g_free(priv->apn); + priv->apn = NULL; + tmp = g_value_dup_string(value); + if (tmp) + priv->apn = g_strstrip(tmp); + break; + case PROP_NETWORK_ID: + g_free(priv->network_id); + priv->network_id = NULL; + tmp = g_value_dup_string(value); + if (tmp) + priv->network_id = g_strstrip(tmp); + break; + case PROP_PIN: + g_free(priv->pin); + priv->pin = g_value_dup_string(value); + break; + case PROP_PIN_FLAGS: + priv->pin_flags = g_value_get_flags(value); + break; + case PROP_HOME_ONLY: + priv->home_only = g_value_get_boolean(value); + break; + case PROP_DEVICE_ID: + g_free(priv->device_id); + priv->device_id = g_value_dup_string(value); + break; + case PROP_SIM_ID: + g_free(priv->sim_id); + priv->sim_id = g_value_dup_string(value); + break; + case PROP_SIM_OPERATOR_ID: + g_free(priv->sim_operator_id); + priv->sim_operator_id = g_value_dup_string(value); + break; + case PROP_MTU: + priv->mtu = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_gsm_init(NMSettingGsm *setting) +{} + +/** + * nm_setting_gsm_new: + * + * Creates a new #NMSettingGsm object with default values. + * + * Returns: the new empty #NMSettingGsm object + **/ +NMSetting * +nm_setting_gsm_new(void) +{ + return g_object_new(NM_TYPE_SETTING_GSM, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE(object); + + g_free(priv->number); + g_free(priv->username); + g_free(priv->password); + g_free(priv->apn); + g_free(priv->network_id); + g_free(priv->pin); + g_free(priv->device_id); + g_free(priv->sim_id); + g_free(priv->sim_operator_id); + + G_OBJECT_CLASS(nm_setting_gsm_parent_class)->finalize(object); +} + +static void +nm_setting_gsm_class_init(NMSettingGsmClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingGsmPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->verify_secrets = verify_secrets; + setting_class->need_secrets = need_secrets; + + /** + * NMSettingGsm:auto-config: + * + * When %TRUE, the settings such as APN, username, or password will + * default to values that match the network the modem will register + * to in the Mobile Broadband Provider database. + * + * Since: 1.22 + **/ + obj_properties[PROP_AUTO_CONFIG] = + g_param_spec_boolean(NM_SETTING_GSM_AUTO_CONFIG, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:number: + * + * Legacy setting that used to help establishing PPP data sessions for + * GSM-based modems. + * + * Deprecated: 1.16: User-provided values for this setting are no longer used. + **/ + obj_properties[PROP_NUMBER] = g_param_spec_string(NM_SETTING_GSM_NUMBER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:username: + * + * The username used to authenticate with the network, if required. Many + * providers do not require a username, or accept any username. But if a + * username is required, it is specified here. + **/ + obj_properties[PROP_USERNAME] = g_param_spec_string(NM_SETTING_GSM_USERNAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:password: + * + * The password used to authenticate with the network, if required. Many + * providers do not require a password, or accept any password. But if a + * password is required, it is specified here. + **/ + obj_properties[PROP_PASSWORD] = + g_param_spec_string(NM_SETTING_GSM_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:password-flags: + * + * Flags indicating how to handle the #NMSettingGsm:password property. + **/ + obj_properties[PROP_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_GSM_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:apn: + * + * The GPRS Access Point Name specifying the APN used when establishing a + * data session with the GSM-based network. The APN often determines how + * the user will be billed for their network usage and whether the user has + * access to the Internet or just a provider-specific walled-garden, so it + * is important to use the correct APN for the user's mobile broadband plan. + * The APN may only be composed of the characters a-z, 0-9, ., and - per GSM + * 03.60 Section 14.9. + **/ + obj_properties[PROP_APN] = g_param_spec_string(NM_SETTING_GSM_APN, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:network-id: + * + * The Network ID (GSM LAI format, ie MCC-MNC) to force specific network + * registration. If the Network ID is specified, NetworkManager will + * attempt to force the device to register only on the specified network. + * This can be used to ensure that the device does not roam when direct + * roaming control of the device is not otherwise possible. + **/ + obj_properties[PROP_NETWORK_ID] = + g_param_spec_string(NM_SETTING_GSM_NETWORK_ID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:pin: + * + * If the SIM is locked with a PIN it must be unlocked before any other + * operations are requested. Specify the PIN here to allow operation of the + * device. + **/ + obj_properties[PROP_PIN] = + g_param_spec_string(NM_SETTING_GSM_PIN, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:pin-flags: + * + * Flags indicating how to handle the #NMSettingGsm:pin property. + **/ + obj_properties[PROP_PIN_FLAGS] = g_param_spec_flags(NM_SETTING_GSM_PIN_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:home-only: + * + * When %TRUE, only connections to the home network will be allowed. + * Connections to roaming networks will not be made. + **/ + obj_properties[PROP_HOME_ONLY] = + g_param_spec_boolean(NM_SETTING_GSM_HOME_ONLY, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:device-id: + * + * The device unique identifier (as given by the WWAN management service) + * which this connection applies to. If given, the connection will only + * apply to the specified device. + * + * Since: 1.2 + **/ + obj_properties[PROP_DEVICE_ID] = + g_param_spec_string(NM_SETTING_GSM_DEVICE_ID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:sim-id: + * + * The SIM card unique identifier (as given by the WWAN management service) + * which this connection applies to. If given, the connection will apply + * to any device also allowed by #NMSettingGsm:device-id which contains a + * SIM card matching the given identifier. + * + * Since: 1.2 + **/ + obj_properties[PROP_SIM_ID] = g_param_spec_string(NM_SETTING_GSM_SIM_ID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:sim-operator-id: + * + * A MCC/MNC string like "310260" or "21601" identifying the specific + * mobile network operator which this connection applies to. If given, + * the connection will apply to any device also allowed by + * #NMSettingGsm:device-id and #NMSettingGsm:sim-id which contains a SIM + * card provisioned by the given operator. + * + * Since: 1.2 + **/ + obj_properties[PROP_SIM_OPERATOR_ID] = + g_param_spec_string(NM_SETTING_GSM_SIM_OPERATOR_ID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingGsm:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple frames. + * + * Since: 1.8 + **/ + obj_properties[PROP_MTU] = g_param_spec_uint(NM_SETTING_GSM_MTU, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + /* Ignore incoming deprecated properties */ + _nm_properties_override_dbus(properties_override, + "allowed-bands", + &nm_sett_info_propert_type_deprecated_ignore_u); + _nm_properties_override_dbus(properties_override, + "network-type", + &nm_sett_info_propert_type_deprecated_ignore_i); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_GSM, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-hostname.c b/src/libnm-core-impl/nm-setting-hostname.c new file mode 100644 index 0000000..248ae55 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-hostname.c @@ -0,0 +1,339 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-hostname.h" + +#include "nm-setting-private.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-hostname + * @short_description: Contains properties related to the hostname + * @include: nm-setting-hostname.h + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingHostname, + PROP_PRIORITY, + PROP_FROM_DHCP, + PROP_FROM_DNS_LOOKUP, + PROP_ONLY_FROM_DEFAULT, ); + +/** + * NMSettingHostname: + * + * Hostname settings + * + * Since: 1.30 + */ +struct _NMSettingHostname { + NMSetting parent; + int priority; + NMTernary from_dhcp; + NMTernary from_dns_lookup; + NMTernary only_from_default; +}; + +struct _NMSettingHostnameClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingHostname, nm_setting_hostname, NM_TYPE_SETTING) + +/** + * nm_setting_hostname_get_priority: + * @setting: the #NMSettingHostname + * + * Returns the value contained in the #NMSettingHostname:priority + * property. + * + * Returns: the 'priority' property value + * + * Since: 1.30 + **/ +int +nm_setting_hostname_get_priority(NMSettingHostname *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_HOSTNAME(setting), 0); + + return setting->priority; +} + +/** + * nm_setting_hostname_get_from_dhcp: + * @setting: the #NMSettingHostname + * + * Returns the value contained in the #NMSettingHostname:from-dhcp + * property. + * + * Returns: the 'from-dhcp' property value + * + * Since: 1.30 + **/ +NMTernary +nm_setting_hostname_get_from_dhcp(NMSettingHostname *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_HOSTNAME(setting), NM_TERNARY_DEFAULT); + + return setting->from_dhcp; +} + +/** + * nm_setting_hostname_get_from_dns_lookup: + * @setting: the #NMSettingHostname + * + * Returns the value contained in the #NMSettingHostname:from-dns-lookup + * property. + * + * Returns: the 'from-dns-lookup' property value + * + * Since: 1.30 + **/ +NMTernary +nm_setting_hostname_get_from_dns_lookup(NMSettingHostname *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_HOSTNAME(setting), NM_TERNARY_DEFAULT); + + return setting->from_dns_lookup; +} + +/** + * nm_setting_hostname_get_only_from_default: + * @setting: the #NMSettingHostname + * + * Returns the value contained in the #NMSettingHostname:only-from-default + * property. + * + * Returns: the 'only-from-default' property value + * + * Since: 1.30 + **/ +NMTernary +nm_setting_hostname_get_only_from_default(NMSettingHostname *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_HOSTNAME(setting), NM_TERNARY_DEFAULT); + + return setting->only_from_default; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingHostname *self = NM_SETTING_HOSTNAME(object); + + switch (prop_id) { + case PROP_PRIORITY: + g_value_set_int(value, self->priority); + break; + case PROP_FROM_DHCP: + g_value_set_enum(value, self->from_dhcp); + break; + case PROP_FROM_DNS_LOOKUP: + g_value_set_enum(value, self->from_dns_lookup); + break; + case PROP_ONLY_FROM_DEFAULT: + g_value_set_enum(value, self->only_from_default); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingHostname *self = NM_SETTING_HOSTNAME(object); + + switch (prop_id) { + case PROP_PRIORITY: + self->priority = g_value_get_int(value); + break; + case PROP_FROM_DHCP: + self->from_dhcp = g_value_get_enum(value); + break; + case PROP_FROM_DNS_LOOKUP: + self->from_dns_lookup = g_value_get_enum(value); + break; + case PROP_ONLY_FROM_DEFAULT: + self->only_from_default = g_value_get_enum(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_hostname_init(NMSettingHostname *setting) +{ + setting->from_dhcp = NM_TERNARY_DEFAULT; + setting->from_dns_lookup = NM_TERNARY_DEFAULT; + setting->only_from_default = NM_TERNARY_DEFAULT; +} + +/** + * nm_setting_hostname_new: + * + * Creates a new #NMSettingHostname object with default values. + * + * Returns: (transfer full): the new empty #NMSettingHostname object + * + * Since: 1.30 + **/ +NMSetting * +nm_setting_hostname_new(void) +{ + return g_object_new(NM_TYPE_SETTING_HOSTNAME, NULL); +} + +static void +nm_setting_hostname_class_init(NMSettingHostnameClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + object_class->get_property = get_property; + object_class->set_property = set_property; + + /** + * NMSettingHostname:priority + * + * The relative priority of this connection to determine the + * system hostname. A lower numerical value is better (higher + * priority). A connection with higher priority is considered + * before connections with lower priority. + * + * If the value is zero, it can be overridden by a global value + * from NetworkManager configuration. If the property doesn't have + * a value in the global configuration, the value is assumed to be + * 100. + * + * Negative values have the special effect of excluding other + * connections with a greater numerical priority value; so in + * presence of at least one negative priority, only connections + * with the lowest priority value will be used to determine the + * hostname. + * + * Since: 1.30 + **/ + /* ---ifcfg-rh--- + * property: priority + * variable: HOSTNAME_PRIORITY(+) + * default: missing variable means global value or 100 + * description: hostname priority + * example: HOSTNAME_PRIORITY=50 + * ---end--- + */ + obj_properties[PROP_PRIORITY] = g_param_spec_int(NM_SETTING_HOSTNAME_PRIORITY, + "", + "", + G_MININT32, + G_MAXINT32, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingHostname:from-dhcp + * + * Whether the system hostname can be determined from DHCP on + * this connection. + * + * When set to %NM_TERNARY_DEFAULT, the value from global configuration + * is used. If the property doesn't have a value in the global + * configuration, NetworkManager assumes the value to be %NM_TERNARY_TRUE. + * + * Since: 1.30 + **/ + /* ---ifcfg-rh--- + * property: from-dhcp + * variable: HOSTNAME_FROM_DHCP(+) + * default: missing variable means global default or 1 + * description: whether the system hostname can be determined from DHCP + * example: HOSTNAME_FROM_DHCP=0,1 + * ---end--- + */ + obj_properties[PROP_FROM_DHCP] = g_param_spec_enum( + NM_SETTING_HOSTNAME_FROM_DHCP, + "", + "", + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingHostname:from-dns-lookup + * + * Whether the system hostname can be determined from reverse + * DNS lookup of addresses on this device. + * + * When set to %NM_TERNARY_DEFAULT, the value from global configuration + * is used. If the property doesn't have a value in the global + * configuration, NetworkManager assumes the value to be %NM_TERNARY_TRUE. + * + * Since: 1.30 + **/ + /* ---ifcfg-rh--- + * property: from-dhcp + * variable: HOSTNAME_FROM_DNS_LOOKUP(+) + * default: missing variable means global default or 1 + * description: whether the system hostname can be determined from reverse + * DNS lookup + * example: HOSTNAME_FROM_DNS_LOOKUP=0,1 + * ---end--- + */ + obj_properties[PROP_FROM_DNS_LOOKUP] = g_param_spec_enum( + NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP, + "", + "", + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingHostname:only-from-default + * + * If set to %NM_TERNARY_TRUE, NetworkManager attempts to get + * the hostname via DHCPv4/DHCPv6 or reverse DNS lookup on this + * device only when the device has the default route for the given + * address family (IPv4/IPv6). + * + * If set to %NM_TERNARY_FALSE, the hostname can be set from this + * device even if it doesn't have the default route. + * + * When set to %NM_TERNARY_DEFAULT, the value from global configuration + * is used. If the property doesn't have a value in the global + * configuration, NetworkManager assumes the value to be %NM_TERNARY_FALSE. + * + * Since: 1.30 + **/ + /* ---ifcfg-rh--- + * property: only-best-device + * variable: HOSTNAME_ONLY_FROM_DEFAULT(+) + * default: missing variable means global default or 1 + * description: whether the hostname can be determined only from + * devices with the default route + * example: HOSTNAME_ONLY_FROM_DEFAULT=0,1 + * ---end--- + */ + obj_properties[PROP_ONLY_FROM_DEFAULT] = g_param_spec_enum( + NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT, + "", + "", + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_HOSTNAME); +} diff --git a/src/libnm-core-impl/nm-setting-infiniband.c b/src/libnm-core-impl/nm-setting-infiniband.c new file mode 100644 index 0000000..11485dd --- /dev/null +++ b/src/libnm-core-impl/nm-setting-infiniband.c @@ -0,0 +1,521 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2013 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-infiniband.h" + +#include +#include + +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" +#include "nm-setting-connection.h" + +/** + * SECTION:nm-setting-infiniband + * @short_description: Describes connection properties for IP-over-InfiniBand networks + * + * The #NMSettingInfiniband object is a #NMSetting subclass that describes properties + * necessary for connection to IP-over-InfiniBand networks. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_MAC_ADDRESS, + PROP_MTU, + PROP_TRANSPORT_MODE, + PROP_P_KEY, + PROP_PARENT, ); + +typedef struct { + char * mac_address; + char * transport_mode; + char * parent; + char * virtual_iface_name; + int p_key; + guint32 mtu; +} NMSettingInfinibandPrivate; + +G_DEFINE_TYPE(NMSettingInfiniband, nm_setting_infiniband, NM_TYPE_SETTING) + +#define NM_SETTING_INFINIBAND_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_INFINIBAND, NMSettingInfinibandPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_infiniband_get_mac_address: + * @setting: the #NMSettingInfiniband + * + * Returns: the #NMSettingInfiniband:mac-address property of the setting + **/ +const char * +nm_setting_infiniband_get_mac_address(NMSettingInfiniband *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_INFINIBAND(setting), NULL); + + return NM_SETTING_INFINIBAND_GET_PRIVATE(setting)->mac_address; +} + +/** + * nm_setting_infiniband_get_mtu: + * @setting: the #NMSettingInfiniband + * + * Returns: the #NMSettingInfiniband:mtu property of the setting + **/ +guint32 +nm_setting_infiniband_get_mtu(NMSettingInfiniband *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_INFINIBAND(setting), 0); + + return NM_SETTING_INFINIBAND_GET_PRIVATE(setting)->mtu; +} + +/** + * nm_setting_infiniband_get_transport_mode: + * @setting: the #NMSettingInfiniband + * + * Returns the transport mode for this device. Either 'datagram' or + * 'connected'. + * + * Returns: the IPoIB transport mode + **/ +const char * +nm_setting_infiniband_get_transport_mode(NMSettingInfiniband *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_INFINIBAND(setting), NULL); + + return NM_SETTING_INFINIBAND_GET_PRIVATE(setting)->transport_mode; +} + +/** + * nm_setting_infiniband_get_p_key: + * @setting: the #NMSettingInfiniband + * + * Returns the P_Key to use for this device. A value of -1 means to + * use the default P_Key (aka "the P_Key at index 0"). Otherwise, it is + * a 16-bit unsigned integer. + * + * Returns: the IPoIB P_Key + **/ +int +nm_setting_infiniband_get_p_key(NMSettingInfiniband *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_INFINIBAND(setting), -1); + + return NM_SETTING_INFINIBAND_GET_PRIVATE(setting)->p_key; +} + +/** + * nm_setting_infiniband_get_parent: + * @setting: the #NMSettingInfiniband + * + * Returns the parent interface name for this device, if set. + * + * Returns: the parent interface name + **/ +const char * +nm_setting_infiniband_get_parent(NMSettingInfiniband *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_INFINIBAND(setting), NULL); + + return NM_SETTING_INFINIBAND_GET_PRIVATE(setting)->parent; +} + +/** + * nm_setting_infiniband_get_virtual_interface_name: + * @setting: the #NMSettingInfiniband + * + * Returns the interface name created by combining #NMSettingInfiniband:parent + * and #NMSettingInfiniband:p-key. (If either property is unset, this will + * return %NULL.) + * + * Returns: the interface name, or %NULL + **/ +const char * +nm_setting_infiniband_get_virtual_interface_name(NMSettingInfiniband *setting) +{ + NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE(setting); + + if (priv->p_key == -1 || !priv->parent) + return NULL; + + if (!priv->virtual_iface_name) + priv->virtual_iface_name = g_strdup_printf("%s.%04x", priv->parent, priv->p_key); + + return NM_SETTING_INFINIBAND_GET_PRIVATE(setting)->virtual_iface_name; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingConnection * s_con = NULL; + NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE(setting); + + if (priv->mac_address && !nm_utils_hwaddr_valid(priv->mac_address, INFINIBAND_ALEN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_INFINIBAND_MAC_ADDRESS); + return FALSE; + } + + if (!NM_IN_STRSET(priv->transport_mode, "datagram", "connected")) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_INFINIBAND_TRANSPORT_MODE); + return FALSE; + } + + if (priv->parent) { + GError *tmp_error = NULL; + + if (!nm_utils_ifname_valid_kernel(priv->parent, &tmp_error)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "'%s': %s", + priv->parent, + tmp_error->message); + g_prefix_error(error, "%s: ", NM_SETTING_INFINIBAND_PARENT); + g_error_free(tmp_error); + return FALSE; + } + if (priv->p_key == -1) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Must specify a P_Key if specifying parent")); + g_prefix_error(error, "%s: ", NM_SETTING_INFINIBAND_PARENT); + } + } + + if (priv->p_key != -1) { + if (!priv->mac_address && !priv->parent) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("InfiniBand P_Key connection did not specify parent interface name")); + g_prefix_error(error, "%s: ", NM_SETTING_INFINIBAND_PARENT); + return FALSE; + } + } + + if (connection) + s_con = nm_connection_get_setting_connection(connection); + if (s_con) { + const char *interface_name = nm_setting_connection_get_interface_name(s_con); + + if (interface_name && priv->p_key != -1) { + if (!priv->virtual_iface_name) + priv->virtual_iface_name = g_strdup_printf("%s.%04x", priv->parent, priv->p_key); + + if (strcmp(interface_name, priv->virtual_iface_name) != 0) { + /* We don't support renaming software infiniband devices. Later we might, but + * for now just reject such connections. + **/ + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("interface name of software infiniband device must be '%s' or unset " + "(instead it is '%s')"), + priv->virtual_iface_name, + interface_name); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME); + return FALSE; + } + } + } + + /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */ + + if (priv->mtu > NM_INFINIBAND_MAX_MTU) { + /* Traditionally, MTU for "datagram" mode was limited to 2044 + * and for "connected" mode it was 65520. + * + * This is no longer the case, and both transport modes use the same + * maximum of 65520 (NM_INFINIBAND_MAX_MTU). + * + * Note that this is the MTU in the connection profile. Whether + * we will be able to configure large MTUs later (during activation) + * is unknown at this point. */ + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("mtu can be at most %u but it is %u"), + NM_INFINIBAND_MAX_MTU, + priv->mtu); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_INFINIBAND_MTU); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingInfiniband *setting = NM_SETTING_INFINIBAND(object); + + switch (prop_id) { + case PROP_MAC_ADDRESS: + g_value_set_string(value, nm_setting_infiniband_get_mac_address(setting)); + break; + case PROP_MTU: + g_value_set_uint(value, nm_setting_infiniband_get_mtu(setting)); + break; + case PROP_TRANSPORT_MODE: + g_value_set_string(value, nm_setting_infiniband_get_transport_mode(setting)); + break; + case PROP_P_KEY: + g_value_set_int(value, nm_setting_infiniband_get_p_key(setting)); + break; + case PROP_PARENT: + g_value_set_string(value, nm_setting_infiniband_get_parent(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_MAC_ADDRESS: + g_free(priv->mac_address); + priv->mac_address = + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), INFINIBAND_ALEN); + break; + case PROP_MTU: + priv->mtu = g_value_get_uint(value); + break; + case PROP_TRANSPORT_MODE: + g_free(priv->transport_mode); + priv->transport_mode = g_value_dup_string(value); + break; + case PROP_P_KEY: + priv->p_key = g_value_get_int(value); + nm_clear_g_free(&priv->virtual_iface_name); + break; + case PROP_PARENT: + g_free(priv->parent); + priv->parent = g_value_dup_string(value); + nm_clear_g_free(&priv->virtual_iface_name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_infiniband_init(NMSettingInfiniband *self) +{ + NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE(self); + + priv->p_key = -1; +} + +/** + * nm_setting_infiniband_new: + * + * Creates a new #NMSettingInfiniband object with default values. + * + * Returns: (transfer full): the new empty #NMSettingInfiniband object + **/ +NMSetting * +nm_setting_infiniband_new(void) +{ + return g_object_new(NM_TYPE_SETTING_INFINIBAND, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE(object); + + g_free(priv->transport_mode); + g_free(priv->mac_address); + g_free(priv->parent); + g_free(priv->virtual_iface_name); + + G_OBJECT_CLASS(nm_setting_infiniband_parent_class)->finalize(object); +} + +static void +nm_setting_infiniband_class_init(NMSettingInfinibandClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingInfinibandPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingInfiniband:mac-address: + * + * If specified, this connection will only apply to the IPoIB device whose + * permanent MAC address matches. This property does not change the MAC + * address of the device (i.e. MAC spoofing). + **/ + /* ---keyfile--- + * property: mac-address + * format: usual hex-digits-and-colons notation + * description: MAC address in traditional hex-digits-and-colons notation, or + * or semicolon separated list of 20 decimal bytes (obsolete) + * example: mac-address= 80:00:00:6d:fe:80:00:00:00:00:00:00:00:02:55:00:70:33:cf:01 + * ---end--- + * ---ifcfg-rh--- + * property: mac-address + * variable: HWADDR + * description: IBoIP 20-byte hardware address of the device (in traditional + * hex-digits-and-colons notation). + * Note that for initscripts this is the current MAC address of the device as found + * during ifup. For NetworkManager this is the permanent MAC address. Or in case no + * permanent MAC address exists, the MAC address initially configured on the device. + * example: HWADDR=01:02:03:04:05:06:07:08:09:0A:01:02:03:04:05:06:07:08:09:11 + * ---end--- + */ + obj_properties[PROP_MAC_ADDRESS] = g_param_spec_string( + NM_SETTING_INFINIBAND_MAC_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_MAC_ADDRESS], + &nm_sett_info_propert_type_mac_address); + + /** + * NMSettingInfiniband:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple frames. + **/ + /* ---ifcfg-rh--- + * property: mtu + * variable: MTU + * description: MTU of the interface. + * ---end--- + */ + obj_properties[PROP_MTU] = g_param_spec_uint(NM_SETTING_INFINIBAND_MTU, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingInfiniband:transport-mode: + * + * The IP-over-InfiniBand transport mode. Either "datagram" or + * "connected". + **/ + /* ---ifcfg-rh--- + * property: transport-mode + * variable: CONNECTED_MODE + * default: CONNECTED_MODE=no + * description: CONNECTED_MODE=yes for "connected" mode, CONNECTED_MODE=no for + * "datagram" mode + * ---end--- + */ + obj_properties[PROP_TRANSPORT_MODE] = g_param_spec_string( + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingInfiniband:p-key: + * + * The InfiniBand P_Key to use for this device. A value of -1 means to use + * the default P_Key (aka "the P_Key at index 0"). Otherwise, it is a 16-bit + * unsigned integer, whose high bit is set if it is a "full membership" + * P_Key. + **/ + /* ---ifcfg-rh--- + * property: p-key + * variable: PKEY_ID (and PKEY=yes) + * default: PKEY=no + * description: InfiniBand P_Key. The value can be a hex number prefixed with "0x" + * or a decimal number. + * When PKEY_ID is specified, PHYSDEV and DEVICE also must be specified. + * example: PKEY=yes PKEY_ID=2 PHYSDEV=mlx4_ib0 DEVICE=mlx4_ib0.8002 + * ---end--- + */ + obj_properties[PROP_P_KEY] = + g_param_spec_int(NM_SETTING_INFINIBAND_P_KEY, + "", + "", + -1, + 0xFFFF, + -1, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingInfiniband:parent: + * + * The interface name of the parent device of this device. Normally %NULL, + * but if the #NMSettingInfiniband:p_key property is set, then you must + * specify the base device by setting either this property or + * #NMSettingInfiniband:mac-address. + **/ + /* ---ifcfg-rh--- + * property: parent + * variable: PHYSDEV (PKEY=yes) + * default: PKEY=no + * description: InfiniBand parent device. + * example: PHYSDEV=ib0 + * ---end--- + */ + obj_properties[PROP_PARENT] = g_param_spec_string( + NM_SETTING_INFINIBAND_PARENT, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_INFINIBAND, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c new file mode 100644 index 0000000..c032433 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -0,0 +1,6498 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2017 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ip-config.h" + +#include +#include + +#include "libnm-base/nm-net-aux.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" +#include "nm-utils.h" +#include "nm-setting-private.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-ip-config + * @short_description: Abstract base class for IPv4 and IPv6 + * addressing, routing, and name service properties + * @include: nm-setting-ip-config.h + * @see_also: #NMSettingIP4Config, #NMSettingIP6Config + * + * #NMSettingIPConfig is the abstract base class of + * #NMSettingIP4Config and #NMSettingIP6Config, providing properties + * related to IP addressing, routing, and Domain Name Service. + **/ + +/*****************************************************************************/ + +const NMUtilsDNSOptionDesc _nm_utils_dns_option_descs[] = { + {NM_SETTING_DNS_OPTION_DEBUG, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_NDOTS, TRUE, FALSE}, + {NM_SETTING_DNS_OPTION_TIMEOUT, TRUE, FALSE}, + {NM_SETTING_DNS_OPTION_ATTEMPTS, TRUE, FALSE}, + {NM_SETTING_DNS_OPTION_ROTATE, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_NO_CHECK_NAMES, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_INET6, FALSE, TRUE}, + {NM_SETTING_DNS_OPTION_IP6_BYTESTRING, FALSE, TRUE}, + {NM_SETTING_DNS_OPTION_IP6_DOTINT, FALSE, TRUE}, + {NM_SETTING_DNS_OPTION_NO_IP6_DOTINT, FALSE, TRUE}, + {NM_SETTING_DNS_OPTION_EDNS0, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_SINGLE_REQUEST, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_SINGLE_REQUEST_REOPEN, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_NO_TLD_QUERY, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_USE_VC, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_NO_RELOAD, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_TRUST_AD, FALSE, FALSE}, + {NULL, FALSE, FALSE}}; + +static char * +canonicalize_ip(int family, const char *ip, gboolean null_any) +{ + guint8 addr_bytes[sizeof(struct in6_addr)]; + char addr_str[NM_UTILS_INET_ADDRSTRLEN]; + int ret; + + if (!ip) { + if (null_any) + return NULL; + if (family == AF_INET) + return g_strdup("0.0.0.0"); + if (family == AF_INET6) + return g_strdup("::"); + g_return_val_if_reached(NULL); + } + + ret = inet_pton(family, ip, addr_bytes); + g_return_val_if_fail(ret == 1, NULL); + + if (null_any) { + if (!memcmp(addr_bytes, &in6addr_any, nm_utils_addr_family_to_size(family))) + return NULL; + } + + return g_strdup(inet_ntop(family, addr_bytes, addr_str, sizeof(addr_str))); +} + +static char * +canonicalize_ip_binary(int family, gconstpointer ip, gboolean null_any) +{ + char string[NM_UTILS_INET_ADDRSTRLEN]; + + if (!ip) { + if (null_any) + return NULL; + if (family == AF_INET) + return g_strdup("0.0.0.0"); + if (family == AF_INET6) + return g_strdup("::"); + g_return_val_if_reached(NULL); + } + if (null_any) { + if (!memcmp(ip, &in6addr_any, nm_utils_addr_family_to_size(family))) + return NULL; + } + return g_strdup(inet_ntop(family, ip, string, sizeof(string))); +} + +static gboolean +valid_ip(int family, const char *ip, GError **error) +{ + if (!ip) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + family == AF_INET ? _("Missing IPv4 address") : _("Missing IPv6 address")); + return FALSE; + } + if (!nm_utils_ipaddr_is_valid(family, ip)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + family == AF_INET ? _("Invalid IPv4 address '%s'") + : _("Invalid IPv6 address '%s'"), + ip); + return FALSE; + } else + return TRUE; +} + +static gboolean +valid_prefix(int family, guint prefix, GError **error) +{ + if ((family == AF_INET && prefix <= 32) || (family == AF_INET6 && prefix <= 128)) + return TRUE; + + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + family == AF_INET ? _("Invalid IPv4 address prefix '%u'") + : _("Invalid IPv6 address prefix '%u'"), + prefix); + return FALSE; +} + +static gboolean +valid_metric(gint64 metric, GError **error) +{ + if (metric < -1 || metric > G_MAXUINT32) { + if (error) { + char buf[64]; + + /* We can't concatenate G_GINT64_FORMAT into a translatable string */ + g_snprintf(buf, sizeof(buf), "%" G_GINT64_FORMAT, metric); + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Invalid routing metric '%s'"), + buf); + } + return FALSE; + } + + return TRUE; +} + +/***************************************************************************** + * NMIPAddress + *****************************************************************************/ + +G_DEFINE_BOXED_TYPE(NMIPAddress, nm_ip_address, nm_ip_address_dup, nm_ip_address_unref) + +struct NMIPAddress { + guint refcount; + + char *address; + int prefix, family; + + GHashTable *attributes; +}; + +/** + * nm_ip_address_new: + * @family: the IP address family (AF_INET or + * AF_INET6) + * @addr: the IP address + * @prefix: the address prefix length + * @error: location to store error, or %NULL + * + * Creates a new #NMIPAddress object. + * + * Returns: (transfer full): the new #NMIPAddress object, or %NULL on error + **/ +NMIPAddress * +nm_ip_address_new(int family, const char *addr, guint prefix, GError **error) +{ + NMIPAddress *address; + + g_return_val_if_fail(family == AF_INET || family == AF_INET6, NULL); + g_return_val_if_fail(addr != NULL, NULL); + + if (!valid_ip(family, addr, error)) + return NULL; + if (!valid_prefix(family, prefix, error)) + return NULL; + + address = g_slice_new0(NMIPAddress); + address->refcount = 1; + + address->family = family; + address->address = canonicalize_ip(family, addr, FALSE); + address->prefix = prefix; + + return address; +} + +/** + * nm_ip_address_new_binary: + * @family: the IP address family (AF_INET or + * AF_INET6) + * @addr: the IP address + * @prefix: the address prefix length + * @error: location to store error, or %NULL + * + * Creates a new #NMIPAddress object. @addr must point to a buffer of the + * correct size for @family. + * + * Returns: (transfer full): the new #NMIPAddress object, or %NULL on error + **/ +NMIPAddress * +nm_ip_address_new_binary(int family, gconstpointer addr, guint prefix, GError **error) +{ + NMIPAddress *address; + char string[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_val_if_fail(family == AF_INET || family == AF_INET6, NULL); + g_return_val_if_fail(addr != NULL, NULL); + + if (!valid_prefix(family, prefix, error)) + return NULL; + + address = g_slice_new0(NMIPAddress); + address->refcount = 1; + + address->family = family; + address->address = g_strdup(inet_ntop(family, addr, string, sizeof(string))); + address->prefix = prefix; + + return address; +} + +/** + * nm_ip_address_ref: + * @address: the #NMIPAddress + * + * Increases the reference count of the object. + **/ +void +nm_ip_address_ref(NMIPAddress *address) +{ + g_return_if_fail(address != NULL); + g_return_if_fail(address->refcount > 0); + + address->refcount++; +} + +/** + * nm_ip_address_unref: + * @address: the #NMIPAddress + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + **/ +void +nm_ip_address_unref(NMIPAddress *address) +{ + g_return_if_fail(address != NULL); + g_return_if_fail(address->refcount > 0); + + address->refcount--; + if (address->refcount == 0) { + g_free(address->address); + if (address->attributes) + g_hash_table_unref(address->attributes); + g_slice_free(NMIPAddress, address); + } +} + +/** + * nm_ip_address_cmp_full: + * @a: the #NMIPAddress + * @b: the #NMIPAddress to compare @address to. + * @cmp_flags: the #NMIPAddressCmpFlags that indicate what to compare. + * + * Note that with @cmp_flags #NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS, there + * is no total order for comparing GVariant. That means, if the two addresses + * only differ by their attributes, the sort order is undefined and the return + * value only indicates equality. + * + * Returns: 0 if the two objects have the same values (according to their flags) + * or a integer indicating the compare order. + **/ +int +nm_ip_address_cmp_full(const NMIPAddress *a, const NMIPAddress *b, NMIPAddressCmpFlags cmp_flags) +{ + g_return_val_if_fail(!a || a->refcount > 0, 0); + g_return_val_if_fail(!b || b->refcount > 0, 0); + g_return_val_if_fail(!NM_FLAGS_ANY(cmp_flags, ~NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS), 0); + + NM_CMP_SELF(a, b); + + NM_CMP_FIELD(a, b, family); + NM_CMP_FIELD(a, b, prefix); + NM_CMP_FIELD_STR(a, b, address); + + if (NM_FLAGS_HAS(cmp_flags, NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS)) { + GHashTableIter iter; + const char * key; + GVariant * value, *value2; + guint n; + + n = a->attributes ? g_hash_table_size(a->attributes) : 0u; + NM_CMP_DIRECT(n, (b->attributes ? g_hash_table_size(b->attributes) : 0u)); + + if (n > 0) { + g_hash_table_iter_init(&iter, a->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) { + value2 = g_hash_table_lookup(b->attributes, key); + /* We cannot really compare GVariants, because g_variant_compare() does + * not work in general. So, don't bother. NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS is + * documented to not provide a total order for the attribute contents. + * + * Theoretically, we can implement also a total order. However we should + * not do that by default because it would require us to sort the keys + * first. Most callers don't care about total order, so they shouldn't + * pay the overhead. */ + if (!value2) + return -2; + if (!g_variant_equal(value, value2)) + return -2; + } + } + } + + return 0; +} + +/** + * nm_ip_address_equal: + * @address: the #NMIPAddress + * @other: the #NMIPAddress to compare @address to. + * + * Determines if two #NMIPAddress objects contain the same address and prefix + * (attributes are not compared). + * + * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + **/ +gboolean +nm_ip_address_equal(NMIPAddress *address, NMIPAddress *other) +{ + return nm_ip_address_cmp_full(address, other, NM_IP_ADDRESS_CMP_FLAGS_NONE) == 0; +} + +/** + * nm_ip_address_dup: + * @address: the #NMIPAddress + * + * Creates a copy of @address + * + * Returns: (transfer full): a copy of @address + **/ +NMIPAddress * +nm_ip_address_dup(NMIPAddress *address) +{ + NMIPAddress *copy; + + g_return_val_if_fail(address != NULL, NULL); + g_return_val_if_fail(address->refcount > 0, NULL); + + copy = nm_ip_address_new(address->family, address->address, address->prefix, NULL); + if (address->attributes) { + GHashTableIter iter; + const char * key; + GVariant * value; + + g_hash_table_iter_init(&iter, address->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) + nm_ip_address_set_attribute(copy, key, value); + } + + return copy; +} + +/** + * nm_ip_address_get_family: + * @address: the #NMIPAddress + * + * Gets the IP address family (eg, AF_INET) property of this address + * object. + * + * Returns: the IP address family + **/ +int +nm_ip_address_get_family(NMIPAddress *address) +{ + g_return_val_if_fail(address != NULL, 0); + g_return_val_if_fail(address->refcount > 0, 0); + + return address->family; +} + +/** + * nm_ip_address_get_address: + * @address: the #NMIPAddress + * + * Gets the IP address property of this address object. + * + * Returns: the IP address + **/ +const char * +nm_ip_address_get_address(NMIPAddress *address) +{ + g_return_val_if_fail(address != NULL, NULL); + g_return_val_if_fail(address->refcount > 0, NULL); + + return address->address; +} + +/** + * nm_ip_address_set_address: + * @address: the #NMIPAddress + * @addr: the IP address, as a string + * + * Sets the IP address property of this address object. + * + * @addr must be a valid address of @address's family. If you aren't sure you + * have a valid address, use nm_utils_ipaddr_valid() to check it. + **/ +void +nm_ip_address_set_address(NMIPAddress *address, const char *addr) +{ + g_return_if_fail(address != NULL); + g_return_if_fail(addr != NULL); + g_return_if_fail(nm_utils_ipaddr_is_valid(address->family, addr)); + + g_free(address->address); + address->address = canonicalize_ip(address->family, addr, FALSE); +} + +/** + * nm_ip_address_get_address_binary: (skip) + * @address: the #NMIPAddress + * @addr: a buffer in which to store the address in binary format. + * + * Gets the IP address property of this address object. + * + * @addr must point to a buffer that is the correct size for @address's family. + **/ +void +nm_ip_address_get_address_binary(NMIPAddress *address, gpointer addr) +{ + g_return_if_fail(address != NULL); + g_return_if_fail(addr != NULL); + + inet_pton(address->family, address->address, addr); +} + +/** + * nm_ip_address_set_address_binary: (skip) + * @address: the #NMIPAddress + * @addr: the address, in binary format + * + * Sets the IP address property of this address object. + * + * @addr must point to a buffer that is the correct size for @address's family. + **/ +void +nm_ip_address_set_address_binary(NMIPAddress *address, gconstpointer addr) +{ + char string[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_if_fail(address != NULL); + g_return_if_fail(addr != NULL); + + g_free(address->address); + address->address = g_strdup(inet_ntop(address->family, addr, string, sizeof(string))); +} + +/** + * nm_ip_address_get_prefix: + * @address: the #NMIPAddress + * + * Gets the IP address prefix (ie "24" or "30" etc) property of this address + * object. + * + * Returns: the IP address prefix + **/ +guint +nm_ip_address_get_prefix(NMIPAddress *address) +{ + g_return_val_if_fail(address != NULL, 0); + g_return_val_if_fail(address->refcount > 0, 0); + + return address->prefix; +} + +/** + * nm_ip_address_set_prefix: + * @address: the #NMIPAddress + * @prefix: the IP address prefix + * + * Sets the IP address prefix property of this address object. + **/ +void +nm_ip_address_set_prefix(NMIPAddress *address, guint prefix) +{ + g_return_if_fail(address != NULL); + g_return_if_fail(valid_prefix(address->family, prefix, NULL)); + + address->prefix = prefix; +} + +const char ** +_nm_ip_address_get_attribute_names(const NMIPAddress *address, gboolean sorted, guint *out_length) +{ + nm_assert(address); + + return nm_utils_strdict_get_keys(address->attributes, sorted, out_length); +} + +/** + * nm_ip_address_get_attribute_names: + * @address: the #NMIPAddress + * + * Gets an array of attribute names defined on @address. + * + * Returns: (transfer full): a %NULL-terminated array of attribute names, + **/ +char ** +nm_ip_address_get_attribute_names(NMIPAddress *address) +{ + const char **names; + + g_return_val_if_fail(address, NULL); + + names = _nm_ip_address_get_attribute_names(address, TRUE, NULL); + return nm_utils_strv_make_deep_copied_nonnull(names); +} + +/** + * nm_ip_address_get_attribute: + * @address: the #NMIPAddress + * @name: the name of an address attribute + * + * Gets the value of the attribute with name @name on @address + * + * Returns: (transfer none): the value of the attribute with name @name on + * @address, or %NULL if @address has no such attribute. + **/ +GVariant * +nm_ip_address_get_attribute(NMIPAddress *address, const char *name) +{ + g_return_val_if_fail(address != NULL, NULL); + g_return_val_if_fail(name != NULL && *name != '\0', NULL); + + if (address->attributes) + return g_hash_table_lookup(address->attributes, name); + else + return NULL; +} + +/** + * nm_ip_address_set_attribute: + * @address: the #NMIPAddress + * @name: the name of an address attribute + * @value: (transfer none) (allow-none): the value + * + * Sets or clears the named attribute on @address to the given value. + **/ +void +nm_ip_address_set_attribute(NMIPAddress *address, const char *name, GVariant *value) +{ + g_return_if_fail(address != NULL); + g_return_if_fail(name != NULL && *name != '\0'); + g_return_if_fail(strcmp(name, "address") != 0 && strcmp(name, "prefix") != 0); + + if (!address->attributes) { + address->attributes = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref); + } + + if (value) + g_hash_table_insert(address->attributes, g_strdup(name), g_variant_ref_sink(value)); + else + g_hash_table_remove(address->attributes, name); +} + +/***************************************************************************** + * NMIPRoute + *****************************************************************************/ + +G_DEFINE_BOXED_TYPE(NMIPRoute, nm_ip_route, nm_ip_route_dup, nm_ip_route_unref) + +struct NMIPRoute { + guint refcount; + + int family; + char * dest; + guint prefix; + char * next_hop; + gint64 metric; + + GHashTable *attributes; +}; + +/** + * nm_ip_route_new: + * @family: the IP address family (AF_INET or + * AF_INET6) + * @dest: the IP address of the route's destination + * @prefix: the address prefix length + * @next_hop: (allow-none): the IP address of the next hop (or %NULL) + * @metric: the route metric (or -1 for "default") + * @error: location to store error, or %NULL + * + * Creates a new #NMIPRoute object. + * + * Returns: (transfer full): the new #NMIPRoute object, or %NULL on error + **/ +NMIPRoute * +nm_ip_route_new(int family, + const char *dest, + guint prefix, + const char *next_hop, + gint64 metric, + GError ** error) +{ + NMIPRoute *route; + + g_return_val_if_fail(family == AF_INET || family == AF_INET6, NULL); + g_return_val_if_fail(dest, NULL); + + if (!valid_ip(family, dest, error)) + return NULL; + if (!valid_prefix(family, prefix, error)) + return NULL; + if (next_hop && !valid_ip(family, next_hop, error)) + return NULL; + if (!valid_metric(metric, error)) + return NULL; + + route = g_slice_new0(NMIPRoute); + route->refcount = 1; + + route->family = family; + route->dest = canonicalize_ip(family, dest, FALSE); + route->prefix = prefix; + route->next_hop = canonicalize_ip(family, next_hop, TRUE); + route->metric = metric; + + return route; +} + +/** + * nm_ip_route_new_binary: + * @family: the IP address family (AF_INET or + * AF_INET6) + * @dest: the IP address of the route's destination + * @prefix: the address prefix length + * @next_hop: (allow-none): the IP address of the next hop (or %NULL) + * @metric: the route metric (or -1 for "default") + * @error: location to store error, or %NULL + * + * Creates a new #NMIPRoute object. @dest and @next_hop (if non-%NULL) must + * point to buffers of the correct size for @family. + * + * Returns: (transfer full): the new #NMIPRoute object, or %NULL on error + **/ +NMIPRoute * +nm_ip_route_new_binary(int family, + gconstpointer dest, + guint prefix, + gconstpointer next_hop, + gint64 metric, + GError ** error) +{ + NMIPRoute *route; + + g_return_val_if_fail(family == AF_INET || family == AF_INET6, NULL); + g_return_val_if_fail(dest, NULL); + + if (!valid_prefix(family, prefix, error)) + return NULL; + if (!valid_metric(metric, error)) + return NULL; + + route = g_slice_new0(NMIPRoute); + route->refcount = 1; + + route->family = family; + route->dest = canonicalize_ip_binary(family, dest, FALSE); + route->prefix = prefix; + route->next_hop = canonicalize_ip_binary(family, next_hop, TRUE); + route->metric = metric; + + return route; +} + +/** + * nm_ip_route_ref: + * @route: the #NMIPRoute + * + * Increases the reference count of the object. + **/ +void +nm_ip_route_ref(NMIPRoute *route) +{ + g_return_if_fail(route != NULL); + g_return_if_fail(route->refcount > 0); + + route->refcount++; +} + +/** + * nm_ip_route_unref: + * @route: the #NMIPRoute + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + **/ +void +nm_ip_route_unref(NMIPRoute *route) +{ + g_return_if_fail(route != NULL); + g_return_if_fail(route->refcount > 0); + + route->refcount--; + if (route->refcount == 0) { + g_free(route->dest); + g_free(route->next_hop); + if (route->attributes) + g_hash_table_unref(route->attributes); + g_slice_free(NMIPRoute, route); + } +} + +/** + * nm_ip_route_equal_full: + * @route: the #NMIPRoute + * @other: the #NMIPRoute to compare @route to. + * @cmp_flags: tune how to compare attributes. Currently, only + * NM_IP_ROUTE_EQUAL_CMP_FLAGS_NONE (0) and NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS (1) + * is supported. + * + * Determines if two #NMIPRoute objects contain the same destination, prefix, + * next hop, and metric. + * + * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + * + * Since: 1.10 + **/ +gboolean +nm_ip_route_equal_full(NMIPRoute *route, NMIPRoute *other, guint cmp_flags) +{ + g_return_val_if_fail(route != NULL, FALSE); + g_return_val_if_fail(route->refcount > 0, FALSE); + + g_return_val_if_fail(other != NULL, FALSE); + g_return_val_if_fail(other->refcount > 0, FALSE); + + g_return_val_if_fail(NM_IN_SET(cmp_flags, + NM_IP_ROUTE_EQUAL_CMP_FLAGS_NONE, + NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS), + FALSE); + + if (route->prefix != other->prefix || route->metric != other->metric + || strcmp(route->dest, other->dest) != 0 + || g_strcmp0(route->next_hop, other->next_hop) != 0) + return FALSE; + if (cmp_flags == NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS) { + GHashTableIter iter; + const char * key; + GVariant * value, *value2; + guint n; + + n = route->attributes ? g_hash_table_size(route->attributes) : 0u; + if (n != (other->attributes ? g_hash_table_size(other->attributes) : 0u)) + return FALSE; + if (n) { + g_hash_table_iter_init(&iter, route->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) { + value2 = g_hash_table_lookup(other->attributes, key); + if (!value2) + return FALSE; + if (!g_variant_equal(value, value2)) + return FALSE; + } + } + } + return TRUE; +} + +/** + * nm_ip_route_equal: + * @route: the #NMIPRoute + * @other: the #NMIPRoute to compare @route to. + * + * Determines if two #NMIPRoute objects contain the same destination, prefix, + * next hop, and metric. (Attributes are not compared.) + * + * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + **/ +gboolean +nm_ip_route_equal(NMIPRoute *route, NMIPRoute *other) +{ + return nm_ip_route_equal_full(route, other, NM_IP_ROUTE_EQUAL_CMP_FLAGS_NONE); +} + +/** + * nm_ip_route_dup: + * @route: the #NMIPRoute + * + * Creates a copy of @route + * + * Returns: (transfer full): a copy of @route + **/ +NMIPRoute * +nm_ip_route_dup(NMIPRoute *route) +{ + NMIPRoute *copy; + + g_return_val_if_fail(route != NULL, NULL); + g_return_val_if_fail(route->refcount > 0, NULL); + + copy = nm_ip_route_new(route->family, + route->dest, + route->prefix, + route->next_hop, + route->metric, + NULL); + if (route->attributes) { + GHashTableIter iter; + const char * key; + GVariant * value; + + g_hash_table_iter_init(&iter, route->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) + nm_ip_route_set_attribute(copy, key, value); + } + + return copy; +} + +/** + * nm_ip_route_get_family: + * @route: the #NMIPRoute + * + * Gets the IP address family (eg, AF_INET) property of this route + * object. + * + * Returns: the IP address family + **/ +int +nm_ip_route_get_family(NMIPRoute *route) +{ + g_return_val_if_fail(route != NULL, 0); + g_return_val_if_fail(route->refcount > 0, 0); + + return route->family; +} + +/** + * nm_ip_route_get_dest: + * @route: the #NMIPRoute + * + * Gets the IP destination address property of this route object. + * + * Returns: the IP address of the route's destination + **/ +const char * +nm_ip_route_get_dest(NMIPRoute *route) +{ + g_return_val_if_fail(route != NULL, NULL); + g_return_val_if_fail(route->refcount > 0, NULL); + + return route->dest; +} + +/** + * nm_ip_route_set_dest: + * @route: the #NMIPRoute + * @dest: the route's destination, as a string + * + * Sets the destination property of this route object. + * + * @dest must be a valid address of @route's family. If you aren't sure you + * have a valid address, use nm_utils_ipaddr_is_valid() to check it. + **/ +void +nm_ip_route_set_dest(NMIPRoute *route, const char *dest) +{ + g_return_if_fail(route != NULL); + g_return_if_fail(nm_utils_ipaddr_is_valid(route->family, dest)); + + g_free(route->dest); + route->dest = canonicalize_ip(route->family, dest, FALSE); +} + +/** + * nm_ip_route_get_dest_binary: (skip) + * @route: the #NMIPRoute + * @dest: a buffer in which to store the destination in binary format. + * + * Gets the destination property of this route object. + * + * @dest must point to a buffer that is the correct size for @route's family. + **/ +void +nm_ip_route_get_dest_binary(NMIPRoute *route, gpointer dest) +{ + g_return_if_fail(route != NULL); + g_return_if_fail(dest != NULL); + + inet_pton(route->family, route->dest, dest); +} + +/** + * nm_ip_route_set_dest_binary: (skip) + * @route: the #NMIPRoute + * @dest: the route's destination, in binary format + * + * Sets the destination property of this route object. + * + * @dest must point to a buffer that is the correct size for @route's family. + **/ +void +nm_ip_route_set_dest_binary(NMIPRoute *route, gconstpointer dest) +{ + char string[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_if_fail(route != NULL); + g_return_if_fail(dest != NULL); + + g_free(route->dest); + route->dest = g_strdup(inet_ntop(route->family, dest, string, sizeof(string))); +} + +/** + * nm_ip_route_get_prefix: + * @route: the #NMIPRoute + * + * Gets the IP prefix (ie "24" or "30" etc) of this route. + * + * Returns: the IP prefix + **/ +guint +nm_ip_route_get_prefix(NMIPRoute *route) +{ + g_return_val_if_fail(route != NULL, 0); + g_return_val_if_fail(route->refcount > 0, 0); + + return route->prefix; +} + +/** + * nm_ip_route_set_prefix: + * @route: the #NMIPRoute + * @prefix: the route prefix + * + * Sets the prefix property of this route object. + **/ +void +nm_ip_route_set_prefix(NMIPRoute *route, guint prefix) +{ + g_return_if_fail(route != NULL); + g_return_if_fail(valid_prefix(route->family, prefix, NULL)); + + route->prefix = prefix; +} + +/** + * nm_ip_route_get_next_hop: + * @route: the #NMIPRoute + * + * Gets the IP address of the next hop of this route; this will be %NULL if the + * route has no next hop. + * + * Returns: the IP address of the next hop, or %NULL if this is a device route. + **/ +const char * +nm_ip_route_get_next_hop(NMIPRoute *route) +{ + g_return_val_if_fail(route != NULL, NULL); + g_return_val_if_fail(route->refcount > 0, NULL); + + return route->next_hop; +} + +/** + * nm_ip_route_set_next_hop: + * @route: the #NMIPRoute + * @next_hop: (allow-none): the route's next hop, as a string + * + * Sets the next-hop property of this route object. + * + * @next_hop (if non-%NULL) must be a valid address of @route's family. If you + * aren't sure you have a valid address, use nm_utils_ipaddr_valid() to check + * it. + **/ +void +nm_ip_route_set_next_hop(NMIPRoute *route, const char *next_hop) +{ + g_return_if_fail(route != NULL); + g_return_if_fail(!next_hop || nm_utils_ipaddr_is_valid(route->family, next_hop)); + + g_free(route->next_hop); + route->next_hop = canonicalize_ip(route->family, next_hop, TRUE); +} + +/** + * nm_ip_route_get_next_hop_binary: (skip) + * @route: the #NMIPRoute + * @next_hop: a buffer in which to store the next hop in binary format. + * + * Gets the next hop property of this route object. + * + * @next_hop must point to a buffer that is the correct size for @route's family. + * + * Returns: %TRUE if @route has a next hop, %FALSE if not (in which case + * @next_hop will be zeroed out) + **/ +gboolean +nm_ip_route_get_next_hop_binary(NMIPRoute *route, gpointer next_hop) +{ + g_return_val_if_fail(route != NULL, FALSE); + g_return_val_if_fail(next_hop != NULL, FALSE); + + if (route->next_hop) { + inet_pton(route->family, route->next_hop, next_hop); + return TRUE; + } else { + memset(next_hop, 0, nm_utils_addr_family_to_size(route->family)); + return FALSE; + } +} + +/** + * nm_ip_route_set_next_hop_binary: (skip) + * @route: the #NMIPRoute + * @next_hop: the route's next hop, in binary format + * + * Sets the destination property of this route object. + * + * @next_hop (if non-%NULL) must point to a buffer that is the correct size for + * @route's family. + **/ +void +nm_ip_route_set_next_hop_binary(NMIPRoute *route, gconstpointer next_hop) +{ + g_return_if_fail(route != NULL); + + g_free(route->next_hop); + route->next_hop = canonicalize_ip_binary(route->family, next_hop, TRUE); +} + +/** + * nm_ip_route_get_metric: + * @route: the #NMIPRoute + * + * Gets the route metric property of this route object; lower values + * indicate "better" or more preferred routes; -1 indicates "default" + * (meaning NetworkManager will set it appropriately). + * + * Returns: the route metric + **/ +gint64 +nm_ip_route_get_metric(NMIPRoute *route) +{ + g_return_val_if_fail(route != NULL, 0); + g_return_val_if_fail(route->refcount > 0, 0); + + return route->metric; +} + +/** + * nm_ip_route_set_metric: + * @route: the #NMIPRoute + * @metric: the route metric (or -1 for "default") + * + * Sets the metric property of this route object. + **/ +void +nm_ip_route_set_metric(NMIPRoute *route, gint64 metric) +{ + g_return_if_fail(route != NULL); + g_return_if_fail(valid_metric(metric, NULL)); + + route->metric = metric; +} + +GHashTable * +_nm_ip_route_get_attributes(NMIPRoute *route) +{ + nm_assert(route); + + return route->attributes; +} + +/** + * _nm_ip_route_get_attribute_names: + * @route: the #NMIPRoute + * @sorted: whether to sort the names. Otherwise, their order is + * undefined and unstable. + * @out_length: (allow-none) (out): the number of elements + * + * Gets an array of attribute names defined on @route. + * + * Returns: (array length=out_length) (transfer container): a %NULL-terminated array + * of attribute names or %NULL if there are no attributes. The order of the returned + * names depends on @sorted. + **/ +const char ** +_nm_ip_route_get_attribute_names(const NMIPRoute *route, gboolean sorted, guint *out_length) +{ + nm_assert(route); + + return nm_utils_strdict_get_keys(route->attributes, sorted, out_length); +} + +/** + * nm_ip_route_get_attribute_names: + * @route: the #NMIPRoute + * + * Gets an array of attribute names defined on @route. + * + * Returns: (transfer full): a %NULL-terminated array of attribute names + **/ +char ** +nm_ip_route_get_attribute_names(NMIPRoute *route) +{ + const char **names; + + g_return_val_if_fail(route != NULL, NULL); + + names = _nm_ip_route_get_attribute_names(route, TRUE, NULL); + return nm_utils_strv_make_deep_copied_nonnull(names); +} + +/** + * nm_ip_route_get_attribute: + * @route: the #NMIPRoute + * @name: the name of an route attribute + * + * Gets the value of the attribute with name @name on @route + * + * Returns: (transfer none): the value of the attribute with name @name on + * @route, or %NULL if @route has no such attribute. + **/ +GVariant * +nm_ip_route_get_attribute(NMIPRoute *route, const char *name) +{ + g_return_val_if_fail(route != NULL, NULL); + g_return_val_if_fail(name != NULL && *name != '\0', NULL); + + if (route->attributes) + return g_hash_table_lookup(route->attributes, name); + else + return NULL; +} + +/** + * nm_ip_route_set_attribute: + * @route: the #NMIPRoute + * @name: the name of a route attribute + * @value: (transfer none) (allow-none): the value + * + * Sets the named attribute on @route to the given value. + **/ +void +nm_ip_route_set_attribute(NMIPRoute *route, const char *name, GVariant *value) +{ + g_return_if_fail(route != NULL); + g_return_if_fail(name != NULL && *name != '\0'); + g_return_if_fail(strcmp(name, "dest") != 0 && strcmp(name, "prefix") != 0 + && strcmp(name, "next-hop") != 0 && strcmp(name, "metric") != 0); + + if (!route->attributes) { + route->attributes = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref); + } + + if (value) + g_hash_table_insert(route->attributes, g_strdup(name), g_variant_ref_sink(value)); + else + g_hash_table_remove(route->attributes, name); +} + +static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_CWND, + G_VARIANT_TYPE_UINT32, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_FROM, + G_VARIANT_TYPE_STRING, + .v6 = TRUE, + .str_type = 'p', ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_INITCWND, + G_VARIANT_TYPE_UINT32, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_INITRWND, + G_VARIANT_TYPE_UINT32, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, + G_VARIANT_TYPE_BOOLEAN, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, + G_VARIANT_TYPE_BOOLEAN, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_LOCK_INITRWND, + G_VARIANT_TYPE_BOOLEAN, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, + G_VARIANT_TYPE_BOOLEAN, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, + G_VARIANT_TYPE_BOOLEAN, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_MTU, + G_VARIANT_TYPE_UINT32, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_ONLINK, + G_VARIANT_TYPE_BOOLEAN, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_SCOPE, + G_VARIANT_TYPE_BYTE, + .v4 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_SRC, + G_VARIANT_TYPE_STRING, + .v4 = TRUE, + .v6 = TRUE, + .str_type = 'a', ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_TABLE, + G_VARIANT_TYPE_UINT32, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, .v4 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_TYPE, + G_VARIANT_TYPE_STRING, + .v4 = TRUE, + .v6 = TRUE, + .str_type = 'T', ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_WINDOW, + G_VARIANT_TYPE_UINT32, + .v4 = TRUE, + .v6 = TRUE, ), + NULL, +}; + +/** + * nm_ip_route_get_variant_attribute_spec: + * + * Returns: the specifiers for route attributes + * + * Since: 1.8 + */ +const NMVariantAttributeSpec *const * +nm_ip_route_get_variant_attribute_spec(void) +{ + return ip_route_attribute_spec; +} + +/** + * nm_ip_route_attribute_validate: + * @name: the attribute name + * @value: the attribute value + * @family: IP address family of the route + * @known: (out): on return, whether the attribute name is a known one + * @error: (allow-none): return location for a #GError, or %NULL + * + * Validates a route attribute, i.e. checks that the attribute is a known one + * and the value is of the correct type and well-formed. + * + * Returns: %TRUE if the attribute is valid, %FALSE otherwise + * + * Since: 1.8 + */ +gboolean +nm_ip_route_attribute_validate(const char *name, + GVariant * value, + int family, + gboolean * known, + GError ** error) +{ + const NMVariantAttributeSpec *spec; + + g_return_val_if_fail(name, FALSE); + g_return_val_if_fail(value, FALSE); + g_return_val_if_fail(family == AF_INET || family == AF_INET6, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + spec = _nm_variant_attribute_spec_find_binary_search(ip_route_attribute_spec, + G_N_ELEMENTS(ip_route_attribute_spec) - 1, + name); + if (!spec) { + NM_SET_OUT(known, FALSE); + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("unknown attribute")); + return FALSE; + } + + NM_SET_OUT(known, TRUE); + + if (!g_variant_is_of_type(value, spec->type)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid attribute type '%s'"), + g_variant_get_type_string(value)); + return FALSE; + } + + if ((family == AF_INET && !spec->v4) || (family == AF_INET6 && !spec->v6)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + family == AF_INET ? _("attribute is not valid for a IPv4 route") + : _("attribute is not valid for a IPv6 route")); + return FALSE; + } + + if (g_variant_type_equal(spec->type, G_VARIANT_TYPE_STRING)) { + const char *string = g_variant_get_string(value, NULL); + + switch (spec->str_type) { + case 'a': /* IP address */ + if (!nm_utils_ipaddr_is_valid(family, string)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + family == AF_INET ? _("'%s' is not a valid IPv4 address") + : _("'%s' is not a valid IPv6 address"), + string); + return FALSE; + } + break; + case 'p': /* IP address + optional prefix */ + { + gs_free char *addr_free = NULL; + const char * addr = string; + const char * str; + + str = strchr(addr, '/'); + if (str) { + addr = nm_strndup_a(200, addr, str - addr, &addr_free); + str++; + if (_nm_utils_ascii_str_to_int64(str, 10, 0, family == AF_INET ? 32 : 128, -1) + < 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid prefix %s"), + str); + return FALSE; + } + } + if (!nm_utils_ipaddr_is_valid(family, addr)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + family == AF_INET ? _("'%s' is not a valid IPv4 address") + : _("'%s' is not a valid IPv6 address"), + string); + return FALSE; + } + break; + } + case 'T': /* route type. */ + if (!NM_IN_SET(nm_net_aux_rtnl_rtntype_a2n(string), RTN_UNICAST, RTN_LOCAL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%s is not a valid route type"), + string); + return FALSE; + } + break; + default: + break; + } + } + + return TRUE; +} + +gboolean +_nm_ip_route_attribute_validate_all(const NMIPRoute *route, GError **error) +{ + NMUtilsNamedValue attrs_static[G_N_ELEMENTS(ip_route_attribute_spec)]; + gs_free NMUtilsNamedValue *attrs_free = NULL; + const NMUtilsNamedValue * attrs; + guint attrs_len; + GVariant * val; + guint i; + guint8 u8; + + g_return_val_if_fail(route, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + if (!route->attributes) + return TRUE; + + attrs = nm_utils_named_values_from_strdict(route->attributes, + &attrs_len, + attrs_static, + &attrs_free); + for (i = 0; i < attrs_len; i++) { + const char *key = attrs[i].name; + GVariant * val2 = attrs[i].value_ptr; + + if (!nm_ip_route_attribute_validate(key, val2, route->family, NULL, NULL)) + return FALSE; + } + + if ((val = g_hash_table_lookup(route->attributes, NM_IP_ROUTE_ATTRIBUTE_TYPE))) { + int v_i; + + nm_assert(g_variant_is_of_type(val, G_VARIANT_TYPE_STRING)); + + v_i = nm_net_aux_rtnl_rtntype_a2n(g_variant_get_string(val, NULL)); + nm_assert(v_i >= 0); + + if (v_i == RTN_LOCAL && route->family == AF_INET + && (val = g_hash_table_lookup(route->attributes, NM_IP_ROUTE_ATTRIBUTE_SCOPE))) { + nm_assert(g_variant_is_of_type(val, G_VARIANT_TYPE_BYTE)); + u8 = g_variant_get_byte(val); + + if (!NM_IN_SET(u8, RT_SCOPE_HOST, RT_SCOPE_NOWHERE)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("route scope is invalid")); + return FALSE; + } + } + } + + return TRUE; +} + +/*****************************************************************************/ + +struct NMIPRoutingRule { + NMIPAddr from_bin; + NMIPAddr to_bin; + char * from_str; + char * to_str; + char * iifname; + char * oifname; + guint ref_count; + guint32 priority; + guint32 table; + gint32 suppress_prefixlength; + guint32 fwmark; + guint32 fwmask; + guint32 uid_range_start; + guint32 uid_range_end; + guint16 sport_start; + guint16 sport_end; + guint16 dport_start; + guint16 dport_end; + guint8 action; + guint8 from_len; + guint8 to_len; + guint8 tos; + guint8 ipproto; + bool is_v4 : 1; + bool sealed : 1; + bool priority_has : 1; + bool uid_range_has : 1; + bool from_has : 1; + bool from_valid : 1; + bool to_has : 1; + bool to_valid : 1; + bool invert : 1; +}; + +static NMIPRoutingRule *_ip_routing_rule_dup(const NMIPRoutingRule *rule); + +G_DEFINE_BOXED_TYPE(NMIPRoutingRule, + nm_ip_routing_rule, + _ip_routing_rule_dup, + nm_ip_routing_rule_unref) + +static gboolean +NM_IS_IP_ROUTING_RULE(const NMIPRoutingRule *self, gboolean also_sealed) +{ + return self && self->ref_count > 0 && (also_sealed || !self->sealed); +} + +static int +_ip_routing_rule_get_addr_family(const NMIPRoutingRule *self) +{ + nm_assert(NM_IS_IP_ROUTING_RULE(self, TRUE)); + + return self->is_v4 ? AF_INET : AF_INET6; +} + +static int +_ip_routing_rule_get_addr_size(const NMIPRoutingRule *self) +{ + nm_assert(NM_IS_IP_ROUTING_RULE(self, TRUE)); + + return self->is_v4 ? sizeof(struct in_addr) : sizeof(struct in6_addr); +} + +static NMIPRoutingRule * +_ip_routing_rule_dup(const NMIPRoutingRule *rule) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(rule, TRUE), NULL); + + if (rule->sealed) + return nm_ip_routing_rule_ref((NMIPRoutingRule *) rule); + return nm_ip_routing_rule_new_clone(rule); +} + +/** + * nm_ip_routing_rule_new: + * @addr_family: the address family of the routing rule. Must be either + * %AF_INET (2) or %AF_INET6 (10). + * + * Returns: (transfer full): a newly created rule instance with the + * provided address family. The instance is unsealed. + * + * Since: 1.18 + */ +NMIPRoutingRule * +nm_ip_routing_rule_new(int addr_family) +{ + NMIPRoutingRule *self; + + g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), NULL); + + self = g_slice_new(NMIPRoutingRule); + *self = (NMIPRoutingRule){ + .ref_count = 1, + .is_v4 = (addr_family == AF_INET), + .action = FR_ACT_TO_TBL, + .table = RT_TABLE_MAIN, + .suppress_prefixlength = -1, + }; + return self; +} + +/** + * nm_ip_routing_rule_new_clone: + * @rule: the #NMIPRoutingRule to clone. + * + * Returns: (transfer full): a newly created rule instance with + * the same settings as @rule. Note that the instance will + * always be unsealred. + * + * Since: 1.18 + */ +NMIPRoutingRule * +nm_ip_routing_rule_new_clone(const NMIPRoutingRule *rule) +{ + NMIPRoutingRule *self; + + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(rule, TRUE), NULL); + + self = g_slice_new(NMIPRoutingRule); + *self = (NMIPRoutingRule){ + .ref_count = 1, + .sealed = FALSE, + .is_v4 = rule->is_v4, + + .priority = rule->priority, + .priority_has = rule->priority_has, + + .invert = rule->invert, + + .tos = rule->tos, + + .fwmark = rule->fwmark, + .fwmask = rule->fwmask, + + .sport_start = rule->sport_start, + .sport_end = rule->sport_end, + .dport_start = rule->dport_start, + .dport_end = rule->dport_end, + + .uid_range_start = rule->uid_range_start, + .uid_range_end = rule->uid_range_end, + .uid_range_has = rule->uid_range_has, + + .ipproto = rule->ipproto, + + .from_len = rule->from_len, + .from_bin = rule->from_bin, + .from_str = (rule->from_has && !rule->from_valid) ? g_strdup(rule->from_str) : NULL, + .from_has = rule->from_has, + .from_valid = rule->from_valid, + + .to_len = rule->to_len, + .to_bin = rule->to_bin, + .to_str = (rule->to_has && !rule->to_valid) ? g_strdup(rule->to_str) : NULL, + .to_has = rule->to_has, + .to_valid = rule->to_valid, + + .iifname = g_strdup(rule->iifname), + .oifname = g_strdup(rule->oifname), + + .action = rule->action, + .table = rule->table, + + .suppress_prefixlength = rule->suppress_prefixlength, + }; + return self; +} + +/** + * nm_ip_routing_rule_ref: + * @self: (allow-none): the #NMIPRoutingRule instance + * + * Increases the reference count of the instance. + * This is not thread-safe. + * + * Returns: (transfer full): the @self argument with incremented + * reference count. + * + * Since: 1.18 + */ +NMIPRoutingRule * +nm_ip_routing_rule_ref(NMIPRoutingRule *self) +{ + if (!self) + return NULL; + + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), NULL); + + nm_assert(self->ref_count < G_MAXUINT); + self->ref_count++; + return self; +} + +/** + * nm_ip_routing_rule_unref: + * @self: (allow-none): the #NMIPRoutingRule instance + * + * Decreases the reference count of the instance and destroys + * the instance if the reference count reaches zero. + * This is not thread-safe. + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_unref(NMIPRoutingRule *self) +{ + if (!self) + return; + + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE)); + + if (--self->ref_count > 0) + return; + + g_free(self->from_str); + g_free(self->to_str); + g_free(self->iifname); + g_free(self->oifname); + + g_slice_free(NMIPRoutingRule, self); +} + +/** + * nm_ip_routing_rule_is_sealed: + * @self: the #NMIPRoutingRule instance + * + * Returns: whether @self is sealed. Once sealed, an instance + * cannot be modified nor unsealed. + * + * Since: 1.18 + */ +gboolean +nm_ip_routing_rule_is_sealed(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), FALSE); + + return self->sealed; +} + +/** + * nm_ip_routing_rule_seal: + * @self: the #NMIPRoutingRule instance + * + * Seals the routing rule. Afterwards, the instance can no longer be + * modified, and it is a bug to call any of the accessors that would + * modify the rule. If @self was already sealed, this has no effect. + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_seal(NMIPRoutingRule *self) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE)); + + self->sealed = TRUE; +} + +/** + * nm_ip_routing_rule_get_addr_family: + * @self: the #NMIPRoutingRule instance + * + * Returns: the address family of the rule. Either %AF_INET or %AF_INET6. + * + * Since: 1.18 + */ +int +nm_ip_routing_rule_get_addr_family(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), AF_UNSPEC); + + return _ip_routing_rule_get_addr_family(self); +} + +/** + * nm_ip_routing_rule_get_priority: + * @self: the #NMIPRoutingRule instance + * + * Returns: the priority. A valid priority is in the range from + * 0 to %G_MAXUINT32. If unset, -1 is returned. + * + * Since: 1.18 + */ +gint64 +nm_ip_routing_rule_get_priority(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), -1); + + return self->priority_has ? (gint64) self->priority : (gint64) -1; +} + +/** + * nm_ip_routing_rule_set_priority: + * @self: the #NMIPRoutingRule instance + * @priority: the priority to set + * + * A valid priority ranges from 0 to %G_MAXUINT32. "-1" is also allowed + * to reset the priority. It is a bug calling this function with any + * other value. + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_priority(NMIPRoutingRule *self, gint64 priority) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + if (priority >= 0 && priority <= (gint64) G_MAXUINT32) { + self->priority = (guint32) priority; + self->priority_has = TRUE; + } else { + g_return_if_fail(priority == -1); + self->priority = 0; + self->priority_has = FALSE; + } +} + +/** + * nm_ip_routing_rule_get_invert: + * @self: the #NMIPRoutingRule instance + * + * Returns: the "invert" setting of the rule. + * + * Since: 1.18 + */ +gboolean +nm_ip_routing_rule_get_invert(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), FALSE); + + return self->invert; +} + +/** + * nm_ip_routing_rule_set_invert: + * @self: the #NMIPRoutingRule instance + * @invert: the new value to set + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_invert(NMIPRoutingRule *self, gboolean invert) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + self->invert = invert; +} + +/** + * nm_ip_routing_rule_get_from_len: + * @self: the #NMIPRoutingRule instance + * + * Returns: the set prefix length for the from/src parameter. + * + * Since: 1.18 + */ +guint8 +nm_ip_routing_rule_get_from_len(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->from_len; +} + +/** + * nm_ip_routing_rule_get_from: + * @self: the #NMIPRoutingRule instance + * + * Returns: (transfer none): the set from/src parameter or + * %NULL, if no value is set. + * + * Since: 1.18 + */ +const char * +nm_ip_routing_rule_get_from(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), NULL); + + if (!self->from_has) + return NULL; + if (!self->from_str) { + nm_assert(self->from_valid); + ((NMIPRoutingRule *) self)->from_str = + nm_utils_inet_ntop_dup(_ip_routing_rule_get_addr_family(self), &self->from_bin); + } + return self->from_str; +} + +const NMIPAddr * +nm_ip_routing_rule_get_from_bin(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), NULL); + + return (self->from_has && self->from_valid) ? &self->from_bin : NULL; +} + +void +nm_ip_routing_rule_set_from_bin(NMIPRoutingRule *self, gconstpointer from, guint8 len) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + nm_clear_g_free(&self->from_str); + + if (!from) { + self->from_has = FALSE; + self->from_len = len; + return; + } + + self->from_has = TRUE; + self->from_len = len; + self->from_valid = TRUE; + nm_ip_addr_set(_ip_routing_rule_get_addr_family(self), &self->from_bin, from); +} + +/** + * nm_ip_routing_rule_set_from: + * @self: the #NMIPRoutingRule instance + * @from: (allow-none): the from/src address to set. + * The address family must match. + * @len: the corresponding prefix length of the address. + * + * Setting invalid values is accepted, but will later fail + * during nm_ip_routing_rule_validate(). + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_from(NMIPRoutingRule *self, const char *from, guint8 len) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + if (!from) { + nm_clear_g_free(&self->from_str); + self->from_has = FALSE; + self->from_len = len; + return; + } + + nm_clear_g_free(&self->from_str); + self->from_has = TRUE; + self->from_len = len; + self->from_valid = nm_utils_parse_inaddr_bin(_ip_routing_rule_get_addr_family(self), + from, + NULL, + &self->from_bin); + if (!self->from_valid) + self->from_str = g_strdup(from); +} + +/** + * nm_ip_routing_rule_get_to_len: + * @self: the #NMIPRoutingRule instance + * + * Returns: the set prefix length for the to/dst parameter. + * + * Since: 1.18 + */ +guint8 +nm_ip_routing_rule_get_to_len(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->to_len; +} + +/** + * nm_ip_routing_rule_get_to: + * @self: the #NMIPRoutingRule instance + * + * Returns: (transfer none): the set to/dst parameter or + * %NULL, if no value is set. + * + * Since: 1.18 + */ +const char * +nm_ip_routing_rule_get_to(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), NULL); + + if (!self->to_has) + return NULL; + if (!self->to_str) { + nm_assert(self->to_valid); + ((NMIPRoutingRule *) self)->to_str = + nm_utils_inet_ntop_dup(_ip_routing_rule_get_addr_family(self), &self->to_bin); + } + return self->to_str; +} + +const NMIPAddr * +nm_ip_routing_rule_get_to_bin(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), NULL); + + return (self->to_has && self->to_valid) ? &self->to_bin : NULL; +} + +void +nm_ip_routing_rule_set_to_bin(NMIPRoutingRule *self, gconstpointer to, guint8 len) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + nm_clear_g_free(&self->to_str); + + if (!to) { + self->to_has = FALSE; + self->to_len = len; + return; + } + + self->to_has = TRUE; + self->to_len = len; + self->to_valid = TRUE; + nm_ip_addr_set(_ip_routing_rule_get_addr_family(self), &self->to_bin, to); +} + +/** + * nm_ip_routing_rule_set_to: + * @self: the #NMIPRoutingRule instance + * @to: (allow-none): the to/dst address to set. + * The address family must match. + * @len: the corresponding prefix length of the address. + * If @to is %NULL, this valid is ignored. + * + * Setting invalid values is accepted, but will later fail + * during nm_ip_routing_rule_validate(). + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_to(NMIPRoutingRule *self, const char *to, guint8 len) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + if (!to) { + nm_clear_g_free(&self->to_str); + self->to_has = FALSE; + self->to_len = len; + return; + } + + nm_clear_g_free(&self->to_str); + self->to_has = TRUE; + self->to_len = len; + self->to_valid = + nm_utils_parse_inaddr_bin(_ip_routing_rule_get_addr_family(self), to, NULL, &self->to_bin); + if (!self->to_valid) + self->to_str = g_strdup(to); +} + +/** + * nm_ip_routing_rule_get_tos: + * @self: the #NMIPRoutingRule instance + * + * Returns: the tos of the rule. + * + * Since: 1.18 + */ +guint8 +nm_ip_routing_rule_get_tos(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->tos; +} + +/** + * nm_ip_routing_rule_set_tos: + * @self: the #NMIPRoutingRule instance + * @tos: the tos to set + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_tos(NMIPRoutingRule *self, guint8 tos) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + self->tos = tos; +} + +/** + * nm_ip_routing_rule_get_ipproto: + * @self: the #NMIPRoutingRule instance + * + * Returns: the ipproto of the rule. + * + * Since: 1.18 + */ +guint8 +nm_ip_routing_rule_get_ipproto(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->ipproto; +} + +/** + * nm_ip_routing_rule_set_ipproto: + * @self: the #NMIPRoutingRule instance + * @ipproto: the ipproto to set + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_ipproto(NMIPRoutingRule *self, guint8 ipproto) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + self->ipproto = ipproto; +} + +/** + * nm_ip_routing_rule_get_source_port_start: + * @self: the #NMIPRoutingRule instance + * + * Returns: the source port start setting. + * + * Since: 1.18 + */ +guint16 +nm_ip_routing_rule_get_source_port_start(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->sport_start; +} + +/** + * nm_ip_routing_rule_get_source_port_end: + * @self: the #NMIPRoutingRule instance + * + * Returns: the source port end setting. + * + * Since: 1.18 + */ +guint16 +nm_ip_routing_rule_get_source_port_end(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->sport_end; +} + +/** + * nm_ip_routing_rule_set_source_port: + * @self: the #NMIPRoutingRule instance + * @start: the start port to set. + * @end: the end port to set. + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_source_port(NMIPRoutingRule *self, guint16 start, guint16 end) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + self->sport_start = start; + self->sport_end = end; +} + +/** + * nm_ip_routing_rule_get_destination_port_start: + * @self: the #NMIPRoutingRule instance + * + * Returns: the destination port start setting. + * + * Since: 1.18 + */ +guint16 +nm_ip_routing_rule_get_destination_port_start(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->dport_start; +} + +/** + * nm_ip_routing_rule_get_destination_port_end: + * @self: the #NMIPRoutingRule instance + * + * Returns: the destination port end setting. + * + * Since: 1.18 + */ +guint16 +nm_ip_routing_rule_get_destination_port_end(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->dport_end; +} + +/** + * nm_ip_routing_rule_set_destination_port: + * @self: the #NMIPRoutingRule instance + * @start: the start port to set. + * @end: the end port to set. + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_destination_port(NMIPRoutingRule *self, guint16 start, guint16 end) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + self->dport_start = start; + self->dport_end = end; +} + +/** + * nm_ip_routing_rule_get_fwmark: + * @self: the #NMIPRoutingRule instance + * + * Returns: the fwmark setting. + * + * Since: 1.18 + */ +guint32 +nm_ip_routing_rule_get_fwmark(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->fwmark; +} + +/** + * nm_ip_routing_rule_get_fwmask: + * @self: the #NMIPRoutingRule instance + * + * Returns: the fwmask setting. + * + * Since: 1.18 + */ +guint32 +nm_ip_routing_rule_get_fwmask(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->fwmask; +} + +/** + * nm_ip_routing_rule_set_fwmark: + * @self: the #NMIPRoutingRule instance + * @fwmark: the fwmark + * @fwmask: the fwmask + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_fwmark(NMIPRoutingRule *self, guint32 fwmark, guint32 fwmask) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + self->fwmark = fwmark; + self->fwmask = fwmask; +} + +/** + * nm_ip_routing_rule_get_iifname: + * @self: the #NMIPRoutingRule instance. + * + * Returns: (transfer none): the set iifname or %NULL if unset. + * + * Since: 1.18 + */ +const char * +nm_ip_routing_rule_get_iifname(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), NULL); + + return self->iifname; +} + +gboolean +nm_ip_routing_rule_get_xifname_bin(const NMIPRoutingRule *self, + gboolean iif /* or else oif */, + char out_xifname[static 16 /* IFNAMSIZ */]) +{ + gs_free gpointer bin_to_free = NULL; + const char * xifname; + gconstpointer bin; + gsize len; + + nm_assert(NM_IS_IP_ROUTING_RULE(self, TRUE)); + nm_assert(out_xifname); + + xifname = iif ? self->iifname : self->oifname; + + if (!xifname) + return FALSE; + + bin = nm_utils_buf_utf8safe_unescape(xifname, + NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, + &len, + &bin_to_free); + + strncpy(out_xifname, bin, 16 /* IFNAMSIZ */); + out_xifname[15] = '\0'; + return TRUE; +} + +/** + * nm_ip_routing_rule_set_iifname: + * @self: the #NMIPRoutingRule instance. + * @iifname: (allow-none): the iifname to set or %NULL to unset. + * + * The name supports C backslash escaping for non-UTF-8 characters. + * Note that nm_ip_routing_rule_from_string() too uses backslash + * escaping when tokenizing the words by whitespace. So, in string + * representation you'd get double backslashes. + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_iifname(NMIPRoutingRule *self, const char *iifname) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + g_free(self->iifname); + self->iifname = g_strdup(iifname); +} + +/** + * nm_ip_routing_rule_get_oifname: + * @self: the #NMIPRoutingRule instance. + * + * Returns: (transfer none): the set oifname or %NULL if unset. + * + * Since: 1.18 + */ +const char * +nm_ip_routing_rule_get_oifname(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), NULL); + + return self->oifname; +} + +/** + * nm_ip_routing_rule_set_oifname: + * @self: the #NMIPRoutingRule instance. + * @oifname: (allow-none): the oifname to set or %NULL to unset. + * + * The name supports C backslash escaping for non-UTF-8 characters. + * Note that nm_ip_routing_rule_from_string() too uses backslash + * escaping when tokenizing the words by whitespace. So, in string + * representation you'd get double backslashes. + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_oifname(NMIPRoutingRule *self, const char *oifname) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + g_free(self->oifname); + self->oifname = g_strdup(oifname); +} + +/** + * nm_ip_routing_rule_get_action: + * @self: the #NMIPRoutingRule instance + * + * Returns: the set action. + * + * Since: 1.18 + */ +guint8 +nm_ip_routing_rule_get_action(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->action; +} + +/** + * nm_ip_routing_rule_set_action: + * @self: the #NMIPRoutingRule instance + * @action: the action to set + * + * Note that currently only certain actions are allowed. nm_ip_routing_rule_validate() + * will reject unsupported actions as invalid. + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_action(NMIPRoutingRule *self, guint8 action) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + self->action = action; +} + +/** + * nm_ip_routing_rule_get_table: + * @self: the #NMIPRoutingRule instance + * + * Returns: the set table. + * + * Since: 1.18 + */ +guint32 +nm_ip_routing_rule_get_table(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), 0); + + return self->table; +} + +/** + * nm_ip_routing_rule_set_table: + * @self: the #NMIPRoutingRule instance + * @table: the table to set + * + * Since: 1.18 + */ +void +nm_ip_routing_rule_set_table(NMIPRoutingRule *self, guint32 table) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + self->table = table; +} + +/** + * nm_ip_routing_rule_get_suppress_prefixlength: + * @self: the #NMIPRoutingRule instance + * + * Returns: the suppress_prefixlength of the rule. -1 means that the value is unset. + * + * Since: 1.20 + */ +gint32 +nm_ip_routing_rule_get_suppress_prefixlength(const NMIPRoutingRule *self) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), -1); + + return self->suppress_prefixlength; +} + +/** + * nm_ip_routing_rule_set_suppress_prefixlength: + * @self: the #NMIPRoutingRule instance + * @suppress_prefixlength: the suppress_prefixlength to set. The value -1 means + * unset. + * + * Since: 1.20 + */ +void +nm_ip_routing_rule_set_suppress_prefixlength(NMIPRoutingRule *self, gint32 suppress_prefixlength) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + self->suppress_prefixlength = suppress_prefixlength; +} + +/** + * nm_ip_routing_rule_get_uid_range: + * @self: the #NMIPRoutingRule instance + * @out_range_start: (out) (allow-none): returns the start of the range + * or 0 if the range is not set. + * @out_range_end: (out) (allow-none): returns the end of the range + * or 0 if the range is not set. + * + * Returns: %TRUE if a uid range is set. + * + * Since: 1.32 + */ +gboolean +nm_ip_routing_rule_get_uid_range(const NMIPRoutingRule *self, + guint32 * out_range_start, + guint32 * out_range_end) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), -1); + + nm_assert(self->uid_range_has || (self->uid_range_start == 0 && self->uid_range_end == 0)); + + NM_SET_OUT(out_range_start, self->uid_range_start); + NM_SET_OUT(out_range_end, self->uid_range_end); + return self->uid_range_has; +} + +/** + * nm_ip_routing_rule_set_uid_range: + * @self: the #NMIPRoutingRule instance + * @uid_range_start: the uid_range start to set. + * @uid_range_end: the uid_range start to set. + * + * For a valid range, start must be less or equal to end. + * If set to an invalid range, the range gets unset. + * + * Since: 1.32 + */ +void +nm_ip_routing_rule_set_uid_range(NMIPRoutingRule *self, + guint32 uid_range_start, + guint32 uid_range_end) +{ + g_return_if_fail(NM_IS_IP_ROUTING_RULE(self, FALSE)); + + if (uid_range_start > uid_range_end) { + self->uid_range_start = 0; + self->uid_range_end = 0; + self->uid_range_has = FALSE; + return; + } + self->uid_range_start = uid_range_start; + self->uid_range_end = uid_range_end; + self->uid_range_has = TRUE; +} + +/** + * nm_ip_routing_rule_cmp: + * @rule: (allow-none): the #NMIPRoutingRule instance to compare + * @other: (allow-none): the other #NMIPRoutingRule instance to compare + * + * Returns: zero, a positive, or a negative integer to indicate + * equality or how the arguments compare. + * + * Since: 1.18 + */ +int +nm_ip_routing_rule_cmp(const NMIPRoutingRule *rule, const NMIPRoutingRule *other) +{ + NM_CMP_SELF(rule, other); + + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(rule, TRUE), 0); + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(other, TRUE), 0); + + NM_CMP_FIELD_UNSAFE(rule, other, priority_has); + if (rule->priority_has) + NM_CMP_FIELD(rule, other, priority); + + NM_CMP_FIELD_UNSAFE(rule, other, is_v4); + + NM_CMP_FIELD_UNSAFE(rule, other, invert); + + NM_CMP_FIELD(rule, other, tos); + + NM_CMP_FIELD(rule, other, fwmark); + NM_CMP_FIELD(rule, other, fwmask); + + NM_CMP_FIELD(rule, other, action); + + NM_CMP_FIELD(rule, other, table); + + NM_CMP_FIELD(rule, other, suppress_prefixlength); + + NM_CMP_FIELD(rule, other, sport_start); + NM_CMP_FIELD(rule, other, sport_end); + NM_CMP_FIELD(rule, other, dport_start); + NM_CMP_FIELD(rule, other, dport_end); + + NM_CMP_FIELD(rule, other, ipproto); + + NM_CMP_FIELD_UNSAFE(rule, other, uid_range_has); + if (rule->uid_range_has) { + NM_CMP_FIELD(rule, other, uid_range_end); + NM_CMP_FIELD(rule, other, uid_range_start); + } + + /* We compare the plain strings, not the binary values after utf8safe unescaping. + * + * The reason is, that the rules differ already when the direct strings differ, not + * only when the unescaped names differ. */ + NM_CMP_FIELD_STR0(rule, other, iifname); + NM_CMP_FIELD_STR0(rule, other, oifname); + + NM_CMP_FIELD(rule, other, from_len); + + NM_CMP_FIELD_UNSAFE(rule, other, from_has); + if (rule->from_has) { + NM_CMP_FIELD_UNSAFE(rule, other, from_valid); + if (rule->from_valid) { + NM_CMP_RETURN( + memcmp(&rule->from_bin, &other->from_bin, _ip_routing_rule_get_addr_size(rule))); + } else + NM_CMP_FIELD_STR(rule, other, from_str); + } + + NM_CMP_FIELD(rule, other, to_len); + + NM_CMP_FIELD_UNSAFE(rule, other, to_has); + if (rule->to_has) { + NM_CMP_FIELD_UNSAFE(rule, other, to_valid); + if (rule->to_valid) { + NM_CMP_RETURN( + memcmp(&rule->to_bin, &other->to_bin, _ip_routing_rule_get_addr_size(rule))); + } else + NM_CMP_FIELD_STR(rule, other, to_str); + } + + return 0; +} + +static gboolean +_rr_xport_range_valid(guint16 xport_start, guint16 xport_end) +{ + if (xport_start == 0) + return (xport_end == 0); + + return xport_start <= xport_end && xport_end < 0xFFFFu; +} + +static gboolean +_rr_xport_range_parse(char *str, gint64 *out_start, guint16 *out_end) +{ + guint16 start, end; + gint64 i64; + char * s; + + s = strchr(str, '-'); + if (s) + *(s++) = '\0'; + + i64 = _nm_utils_ascii_str_to_int64(str, 10, 0, 0xFFFF, -1); + if (i64 == -1) + return FALSE; + + start = i64; + if (s) { + i64 = _nm_utils_ascii_str_to_int64(s, 10, 0, 0xFFFF, -1); + if (i64 == -1) + return FALSE; + end = i64; + } else + end = start; + + *out_start = start; + *out_end = end; + return TRUE; +} + +/** + * nm_ip_routing_rule_validate: + * @self: the #NMIPRoutingRule instance to validate + * @error: (allow-none) (out): the error result if validation fails. + * + * Returns: %TRUE if the rule validates. + * + * Since: 1.18 + */ +gboolean +nm_ip_routing_rule_validate(const NMIPRoutingRule *self, GError **error) +{ + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + /* Kernel may be more flexible about validating. We do a strict validation + * here and reject certain settings eagerly. We can always relax it later. */ + + if (!self->priority_has) { + /* iproute2 accepts not specifying the priority, in which case kernel will select + * an unused priority. We don't allow for that, and will always require the user to + * select a priority. + * + * Note that if the user selects priority 0 or a non-unique priority, this is problematic + * due to kernel bugs rh#1685816 and rh#1685816. It may result in NetworkManager wrongly being + * unable to add a rule or deleting the wrong rule. + * This problem is not at all specific to the priority, it affects all rules that + * have default values which confuse kernel. But setting a unique priority avoids + * this problem nicely. */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid priority")); + return FALSE; + } + + if (NM_IN_SET(self->action, FR_ACT_TO_TBL)) { + if (self->table == 0) { + /* with IPv4, kernel allows a table (in RTM_NEWRULE) of zero to automatically select + * an unused table. We don't. The user needs to specify the table. + * + * For IPv6, kernel doesn't allow a table of zero, so we are consistent here. */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("missing table")); + return FALSE; + } + } else if (NM_IN_SET(self->action, FR_ACT_BLACKHOLE, FR_ACT_PROHIBIT, FR_ACT_UNREACHABLE)) { + /* pass */ + } else { + /* we currently only support the listed actions. */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid action type")); + return FALSE; + } + + if (self->from_len == 0) { + if (self->from_has) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("has from/src but the prefix-length is zero")); + return FALSE; + } + } else if (self->from_len > 0 && self->from_len <= 8 * _ip_routing_rule_get_addr_size(self)) { + if (!self->from_has) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("missing from/src for a non zero prefix-length")); + return FALSE; + } + if (!self->from_valid) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid from/src")); + return FALSE; + } + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid prefix length for from/src")); + return FALSE; + } + + if (self->to_len == 0) { + if (self->to_has) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("has to/dst but the prefix-length is zero")); + return FALSE; + } + } else if (self->to_len > 0 && self->to_len <= 8 * _ip_routing_rule_get_addr_size(self)) { + if (!self->to_has) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("missing to/dst for a non zero prefix-length")); + return FALSE; + } + if (!self->to_valid) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid to/dst")); + return FALSE; + } + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid prefix length for to/dst")); + return FALSE; + } + + if (self->iifname + && (!g_utf8_validate(self->iifname, -1, NULL) + || !nm_utils_is_valid_iface_name_utf8safe(self->iifname))) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid iifname")); + return FALSE; + } + + if (self->oifname + && (!g_utf8_validate(self->oifname, -1, NULL) + || !nm_utils_is_valid_iface_name_utf8safe(self->oifname))) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid oifname")); + return FALSE; + } + + if (!_rr_xport_range_valid(self->sport_start, self->sport_end)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid source port range")); + return FALSE; + } + + if (!_rr_xport_range_valid(self->dport_start, self->dport_end)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid destination port range")); + return FALSE; + } + + if (self->suppress_prefixlength != -1) { + if (self->suppress_prefixlength < -1 + || self->suppress_prefixlength > (self->is_v4 ? 32 : 128)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("suppress_prefixlength out of range")); + return FALSE; + } + if (self->action != FR_ACT_TO_TBL) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("suppress_prefixlength is only allowed with the to-table action")); + return FALSE; + } + } + + return TRUE; +} + +/*****************************************************************************/ + +typedef enum { + RR_DBUS_ATTR_ACTION, + RR_DBUS_ATTR_DPORT_END, + RR_DBUS_ATTR_DPORT_START, + RR_DBUS_ATTR_FAMILY, + RR_DBUS_ATTR_FROM, + RR_DBUS_ATTR_FROM_LEN, + RR_DBUS_ATTR_FWMARK, + RR_DBUS_ATTR_FWMASK, + RR_DBUS_ATTR_IIFNAME, + RR_DBUS_ATTR_INVERT, + RR_DBUS_ATTR_IPPROTO, + RR_DBUS_ATTR_OIFNAME, + RR_DBUS_ATTR_PRIORITY, + RR_DBUS_ATTR_SPORT_END, + RR_DBUS_ATTR_SPORT_START, + RR_DBUS_ATTR_SUPPRESS_PREFIXLENGTH, + RR_DBUS_ATTR_TABLE, + RR_DBUS_ATTR_TO, + RR_DBUS_ATTR_TO_LEN, + RR_DBUS_ATTR_TOS, + RR_DBUS_ATTR_UID_RANGE_END, + RR_DBUS_ATTR_UID_RANGE_START, + + _RR_DBUS_ATTR_NUM, +} RRDbusAttr; + +typedef struct { + const char * name; + const GVariantType *dbus_type; +} RRDbusData; + +static const RRDbusData rr_dbus_data[_RR_DBUS_ATTR_NUM] = { +#define _D(attr, _name, type) \ + [attr] = { \ + .name = _name, \ + .dbus_type = type, \ + } + _D(RR_DBUS_ATTR_ACTION, NM_IP_ROUTING_RULE_ATTR_ACTION, G_VARIANT_TYPE_BYTE), + _D(RR_DBUS_ATTR_DPORT_END, NM_IP_ROUTING_RULE_ATTR_DPORT_END, G_VARIANT_TYPE_UINT16), + _D(RR_DBUS_ATTR_DPORT_START, NM_IP_ROUTING_RULE_ATTR_DPORT_START, G_VARIANT_TYPE_UINT16), + _D(RR_DBUS_ATTR_FAMILY, NM_IP_ROUTING_RULE_ATTR_FAMILY, G_VARIANT_TYPE_INT32), + _D(RR_DBUS_ATTR_FROM, NM_IP_ROUTING_RULE_ATTR_FROM, G_VARIANT_TYPE_STRING), + _D(RR_DBUS_ATTR_FROM_LEN, NM_IP_ROUTING_RULE_ATTR_FROM_LEN, G_VARIANT_TYPE_BYTE), + _D(RR_DBUS_ATTR_FWMARK, NM_IP_ROUTING_RULE_ATTR_FWMARK, G_VARIANT_TYPE_UINT32), + _D(RR_DBUS_ATTR_FWMASK, NM_IP_ROUTING_RULE_ATTR_FWMASK, G_VARIANT_TYPE_UINT32), + _D(RR_DBUS_ATTR_IIFNAME, NM_IP_ROUTING_RULE_ATTR_IIFNAME, G_VARIANT_TYPE_STRING), + _D(RR_DBUS_ATTR_INVERT, NM_IP_ROUTING_RULE_ATTR_INVERT, G_VARIANT_TYPE_BOOLEAN), + _D(RR_DBUS_ATTR_IPPROTO, NM_IP_ROUTING_RULE_ATTR_IPPROTO, G_VARIANT_TYPE_BYTE), + _D(RR_DBUS_ATTR_OIFNAME, NM_IP_ROUTING_RULE_ATTR_OIFNAME, G_VARIANT_TYPE_STRING), + _D(RR_DBUS_ATTR_PRIORITY, NM_IP_ROUTING_RULE_ATTR_PRIORITY, G_VARIANT_TYPE_UINT32), + _D(RR_DBUS_ATTR_SPORT_END, NM_IP_ROUTING_RULE_ATTR_SPORT_END, G_VARIANT_TYPE_UINT16), + _D(RR_DBUS_ATTR_SPORT_START, NM_IP_ROUTING_RULE_ATTR_SPORT_START, G_VARIANT_TYPE_UINT16), + _D(RR_DBUS_ATTR_SUPPRESS_PREFIXLENGTH, + NM_IP_ROUTING_RULE_ATTR_SUPPRESS_PREFIXLENGTH, + G_VARIANT_TYPE_INT32), + _D(RR_DBUS_ATTR_TABLE, NM_IP_ROUTING_RULE_ATTR_TABLE, G_VARIANT_TYPE_UINT32), + _D(RR_DBUS_ATTR_TO, NM_IP_ROUTING_RULE_ATTR_TO, G_VARIANT_TYPE_STRING), + _D(RR_DBUS_ATTR_TOS, NM_IP_ROUTING_RULE_ATTR_TOS, G_VARIANT_TYPE_BYTE), + _D(RR_DBUS_ATTR_TO_LEN, NM_IP_ROUTING_RULE_ATTR_TO_LEN, G_VARIANT_TYPE_BYTE), + _D(RR_DBUS_ATTR_UID_RANGE_END, NM_IP_ROUTING_RULE_ATTR_UID_RANGE_END, G_VARIANT_TYPE_UINT32), + _D(RR_DBUS_ATTR_UID_RANGE_START, + NM_IP_ROUTING_RULE_ATTR_UID_RANGE_START, + G_VARIANT_TYPE_UINT32), +#undef _D +}; + +static RRDbusAttr +_rr_dbus_attr_from_name(const char *name) +{ + gssize idx; + + nm_assert(name); + + if (NM_MORE_ASSERT_ONCE(10)) { + int i; + + for (i = 0; i < _RR_DBUS_ATTR_NUM; i++) { + nm_assert(rr_dbus_data[i].name); + nm_assert(g_variant_type_string_is_valid((const char *) rr_dbus_data[i].dbus_type)); + if (i > 0) + nm_assert(strcmp(rr_dbus_data[i - 1].name, rr_dbus_data[i].name) < 0); + } + } + + idx = nm_utils_array_find_binary_search(rr_dbus_data, + sizeof(rr_dbus_data[0]), + _RR_DBUS_ATTR_NUM, + &name, + nm_strcmp_p_with_data, + NULL); + if (idx < 0) + return _RR_DBUS_ATTR_NUM; + return idx; +} + +static void +_rr_variants_free(GVariant *(*p_variants)[]) +{ + int i; + + for (i = 0; i < _RR_DBUS_ATTR_NUM; i++) { + if ((*p_variants)[i]) + g_variant_unref((*p_variants)[i]); + } +} + +NMIPRoutingRule * +nm_ip_routing_rule_from_dbus(GVariant *variant, gboolean strict, GError **error) +{ + nm_auto(_rr_variants_free) GVariant *variants[_RR_DBUS_ATTR_NUM] = {}; + nm_auto_unref_ip_routing_rule NMIPRoutingRule *self = NULL; + RRDbusAttr attr; + GVariantIter iter; + const char * iter_key; + GVariant * iter_val; + int addr_family; + int i; + GVariant * v_start; + GVariant * v_end; + + g_variant_iter_init(&iter, variant); + + while (g_variant_iter_next(&iter, "{&sv}", &iter_key, &iter_val)) { + gs_unref_variant GVariant *iter_val2 = iter_val; + + attr = _rr_dbus_attr_from_name(iter_key); + + if (attr >= _RR_DBUS_ATTR_NUM) { + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid key \"%s\""), + iter_key); + return NULL; + } + continue; + } + + if (variants[attr]) { + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("duplicate key %s"), + iter_key); + return NULL; + } + g_variant_unref(variants[attr]); + } + variants[attr] = g_steal_pointer(&iter_val2); + } + + for (attr = 0; attr < _RR_DBUS_ATTR_NUM; attr++) { + if (!variants[attr]) + continue; + if (!g_variant_is_of_type(variants[attr], rr_dbus_data[attr].dbus_type)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid variant type '%s' for \"%s\""), + (const char *) rr_dbus_data[attr].dbus_type, + rr_dbus_data[attr].name); + return NULL; + } + } + + if (!variants[RR_DBUS_ATTR_FAMILY]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("missing \"" NM_IP_ROUTING_RULE_ATTR_FAMILY "\"")); + return NULL; + } + addr_family = g_variant_get_int32(variants[RR_DBUS_ATTR_FAMILY]); + if (!NM_IN_SET(addr_family, AF_INET, AF_INET6)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid \"" NM_IP_ROUTING_RULE_ATTR_FAMILY "\"")); + return NULL; + } + + self = nm_ip_routing_rule_new(addr_family); + + if (variants[RR_DBUS_ATTR_PRIORITY]) + nm_ip_routing_rule_set_priority(self, + g_variant_get_uint32(variants[RR_DBUS_ATTR_PRIORITY])); + + if (variants[RR_DBUS_ATTR_INVERT]) + nm_ip_routing_rule_set_invert(self, g_variant_get_boolean(variants[RR_DBUS_ATTR_INVERT])); + + if (variants[RR_DBUS_ATTR_TOS]) + nm_ip_routing_rule_set_tos(self, g_variant_get_byte(variants[RR_DBUS_ATTR_TOS])); + + if (variants[RR_DBUS_ATTR_IPPROTO]) + nm_ip_routing_rule_set_ipproto(self, g_variant_get_byte(variants[RR_DBUS_ATTR_IPPROTO])); + + for (i = 0; i < 2; i++) { + guint16 start, end; + + v_start = variants[i ? RR_DBUS_ATTR_SPORT_START : RR_DBUS_ATTR_DPORT_START]; + v_end = variants[i ? RR_DBUS_ATTR_SPORT_END : RR_DBUS_ATTR_DPORT_END]; + if (!v_start && !v_end) + continue; + + /* if start or end is missing, it defaults to the other parameter, respectively. */ + start = g_variant_get_uint16(v_start ?: v_end); + if (v_end && v_start) + end = g_variant_get_uint16(v_end); + else + end = start; + + if (i) + nm_ip_routing_rule_set_source_port(self, start, end); + else + nm_ip_routing_rule_set_destination_port(self, start, end); + } + + v_start = variants[RR_DBUS_ATTR_UID_RANGE_START]; + v_end = variants[RR_DBUS_ATTR_UID_RANGE_END]; + if (v_start || v_end) { + guint32 start, end; + + /* if start or end is missing, it defaults to the other parameter, respectively. */ + start = g_variant_get_uint32(v_start ?: v_end); + if (v_end && v_start) + end = g_variant_get_uint32(v_end); + else + end = start; + + if (end < start) { + if (strict) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("\"" NM_IP_ROUTING_RULE_ATTR_UID_RANGE_START + "\" is greater than \"" NM_IP_ROUTING_RULE_ATTR_UID_RANGE_END + "\"")); + return FALSE; + } + } else + nm_ip_routing_rule_set_uid_range(self, start, end); + } + + if (variants[RR_DBUS_ATTR_FWMARK] || variants[RR_DBUS_ATTR_FWMASK]) { + nm_ip_routing_rule_set_fwmark( + self, + variants[RR_DBUS_ATTR_FWMARK] ? g_variant_get_uint32(variants[RR_DBUS_ATTR_FWMARK]) + : 0u, + variants[RR_DBUS_ATTR_FWMASK] ? g_variant_get_uint32(variants[RR_DBUS_ATTR_FWMASK]) + : 0u); + } + + if (variants[RR_DBUS_ATTR_FROM] || variants[RR_DBUS_ATTR_FROM_LEN]) { + nm_ip_routing_rule_set_from( + self, + variants[RR_DBUS_ATTR_FROM] ? g_variant_get_string(variants[RR_DBUS_ATTR_FROM], NULL) + : NULL, + variants[RR_DBUS_ATTR_FROM_LEN] ? g_variant_get_byte(variants[RR_DBUS_ATTR_FROM_LEN]) + : 0u); + } + + if (variants[RR_DBUS_ATTR_TO] || variants[RR_DBUS_ATTR_TO_LEN]) { + nm_ip_routing_rule_set_to( + self, + variants[RR_DBUS_ATTR_TO] ? g_variant_get_string(variants[RR_DBUS_ATTR_TO], NULL) + : NULL, + variants[RR_DBUS_ATTR_TO_LEN] ? g_variant_get_byte(variants[RR_DBUS_ATTR_TO_LEN]) : 0u); + } + + if (variants[RR_DBUS_ATTR_IIFNAME]) + nm_ip_routing_rule_set_iifname(self, + g_variant_get_string(variants[RR_DBUS_ATTR_IIFNAME], NULL)); + + if (variants[RR_DBUS_ATTR_OIFNAME]) + nm_ip_routing_rule_set_oifname(self, + g_variant_get_string(variants[RR_DBUS_ATTR_OIFNAME], NULL)); + + /* For the ip-rule string format, the table default depends on the action. For + * our D-Bus format it's always the same: either a table is specified or it defaults + * to zero. And either the action is specified or it defaults to FR_ACT_TO_TBL. */ + nm_ip_routing_rule_set_action(self, + !variants[RR_DBUS_ATTR_ACTION] + ? (guint8) FR_ACT_TO_TBL + : g_variant_get_byte(variants[RR_DBUS_ATTR_ACTION])); + nm_ip_routing_rule_set_table(self, + !variants[RR_DBUS_ATTR_TABLE] + ? (guint32) 0 + : g_variant_get_uint32(variants[RR_DBUS_ATTR_TABLE])); + + if (variants[RR_DBUS_ATTR_SUPPRESS_PREFIXLENGTH]) + nm_ip_routing_rule_set_suppress_prefixlength( + self, + g_variant_get_int32(variants[RR_DBUS_ATTR_SUPPRESS_PREFIXLENGTH])); + + if (strict && !nm_ip_routing_rule_validate(self, error)) + return NULL; + + return g_steal_pointer(&self); +} + +static void +_rr_to_dbus_add(GVariantBuilder *builder, RRDbusAttr attr, GVariant *value) +{ + nm_assert(builder); + nm_assert(value); + nm_assert(g_variant_is_floating(value)); + nm_assert(g_variant_is_of_type(value, rr_dbus_data[attr].dbus_type)); + + g_variant_builder_add(builder, "{sv}", rr_dbus_data[attr].name, value); +} + +GVariant * +nm_ip_routing_rule_to_dbus(const NMIPRoutingRule *self) +{ + GVariantBuilder builder; + char addr_str[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), NULL); + + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + + _rr_to_dbus_add(&builder, + RR_DBUS_ATTR_FAMILY, + g_variant_new_int32(_ip_routing_rule_get_addr_family(self))); + + if (self->invert) + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_INVERT, g_variant_new_boolean(TRUE)); + + if (self->priority_has) + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_PRIORITY, g_variant_new_uint32(self->priority)); + + if (self->tos != 0) + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_TOS, g_variant_new_byte(self->tos)); + + if (self->ipproto != 0) + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_IPPROTO, g_variant_new_byte(self->ipproto)); + + if (self->fwmark != 0) + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_FWMARK, g_variant_new_uint32(self->fwmark)); + + if (self->fwmask != 0) + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_FWMASK, g_variant_new_uint32(self->fwmask)); + + if (self->sport_start != 0 || self->sport_end != 0) { + _rr_to_dbus_add(&builder, + RR_DBUS_ATTR_SPORT_START, + g_variant_new_uint16(self->sport_start)); + if (self->sport_start != self->sport_end) + _rr_to_dbus_add(&builder, + RR_DBUS_ATTR_SPORT_END, + g_variant_new_uint16(self->sport_end)); + } + + if (self->dport_start != 0 || self->dport_end != 0) { + _rr_to_dbus_add(&builder, + RR_DBUS_ATTR_DPORT_START, + g_variant_new_uint16(self->dport_start)); + if (self->dport_start != self->dport_end) + _rr_to_dbus_add(&builder, + RR_DBUS_ATTR_DPORT_END, + g_variant_new_uint16(self->dport_end)); + } + + if (self->from_has || self->from_len != 0) { + _rr_to_dbus_add( + &builder, + RR_DBUS_ATTR_FROM, + g_variant_new_string(self->from_str + ?: nm_utils_inet_ntop(_ip_routing_rule_get_addr_family(self), + &self->from_bin, + addr_str))); + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_FROM_LEN, g_variant_new_byte(self->from_len)); + } + + if (self->to_has || self->to_len != 0) { + _rr_to_dbus_add( + &builder, + RR_DBUS_ATTR_TO, + g_variant_new_string(self->to_str + ?: nm_utils_inet_ntop(_ip_routing_rule_get_addr_family(self), + &self->to_bin, + addr_str))); + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_TO_LEN, g_variant_new_byte(self->to_len)); + } + + if (self->iifname) + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_IIFNAME, g_variant_new_string(self->iifname)); + + if (self->oifname) + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_OIFNAME, g_variant_new_string(self->oifname)); + + if (self->action != FR_ACT_TO_TBL) + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_ACTION, g_variant_new_byte(self->action)); + + if (self->table != 0) + _rr_to_dbus_add(&builder, RR_DBUS_ATTR_TABLE, g_variant_new_uint32(self->table)); + + if (self->suppress_prefixlength != -1) + _rr_to_dbus_add(&builder, + RR_DBUS_ATTR_SUPPRESS_PREFIXLENGTH, + g_variant_new_int32(self->suppress_prefixlength)); + + if (self->uid_range_has) { + _rr_to_dbus_add(&builder, + RR_DBUS_ATTR_UID_RANGE_START, + g_variant_new_uint32(self->uid_range_start)); + if (self->uid_range_start != self->uid_range_end) + _rr_to_dbus_add(&builder, + RR_DBUS_ATTR_UID_RANGE_END, + g_variant_new_uint32(self->uid_range_end)); + } + + return g_variant_builder_end(&builder); +} + +/*****************************************************************************/ + +static gboolean +_rr_string_validate(gboolean for_from /* or else to-string */, + NMIPRoutingRuleAsStringFlags to_string_flags, + GHashTable * extra_args, + GError ** error) +{ + if (NM_FLAGS_ANY(to_string_flags, + ~(NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET + | NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6 + | NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE))) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Unsupported to-string-flags argument")); + return FALSE; + } + + if (extra_args && g_hash_table_size(extra_args) > 0) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Unsupported extra-argument")); + return FALSE; + } + + return TRUE; +} + +static int +_rr_string_addr_family_from_flags(NMIPRoutingRuleAsStringFlags to_string_flags) +{ + if (NM_FLAGS_HAS(to_string_flags, NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET)) { + if (!NM_FLAGS_HAS(to_string_flags, NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6)) + return AF_INET; + } else if (NM_FLAGS_HAS(to_string_flags, NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6)) + return AF_INET6; + return AF_UNSPEC; +} + +/** + * nm_ip_routing_rule_from_string: + * @str: the string representation to convert to an #NMIPRoutingRule + * @to_string_flags: #NMIPRoutingRuleAsStringFlags for controlling the + * string conversion. + * @extra_args: (allow-none): extra arguments for controlling the string + * conversion. Currently, not extra arguments are supported. + * @error: (allow-none) (out): the error reason. + * + * Returns: (transfer full): the new #NMIPRoutingRule or %NULL on error. + * + * Since: 1.18 + */ +NMIPRoutingRule * +nm_ip_routing_rule_from_string(const char * str, + NMIPRoutingRuleAsStringFlags to_string_flags, + GHashTable * extra_args, + GError ** error) +{ + nm_auto_unref_ip_routing_rule NMIPRoutingRule *self = NULL; + gs_free const char ** tokens = NULL; + gsize i_token; + gboolean any_words = FALSE; + char * word0 = NULL; + char * word1 = NULL; + char * word_from = NULL; + char * word_to = NULL; + char * word_iifname = NULL; + char * word_oifname = NULL; + gint64 i64_priority = -1; + gint64 i64_table = -1; + gint64 i64_tos = -1; + gint64 i64_fwmark = -1; + gint64 i64_fwmask = -1; + gint64 i64_sport_start = -1; + gint64 i64_ipproto = -1; + gint64 i64_suppress_prefixlength = -1; + guint16 sport_end = 0; + gint64 i64_dport_start = -1; + int i_action = -1; + guint16 dport_end = 0; + guint32 uid_range_start = 0; + guint32 uid_range_end = 0; + gboolean uid_range_has = FALSE; + gboolean val_invert = FALSE; + int addr_family = AF_UNSPEC; + NMIPAddr val_from = {}; + NMIPAddr val_to = {}; + int val_from_len = -1; + int val_to_len = -1; + char * s; + + g_return_val_if_fail(str, NULL); + + if (!_rr_string_validate(TRUE, to_string_flags, extra_args, error)) + return NULL; + + /* NM_IP_ROUTING_RULE_TO_STRING_TYPE_IPROUTE gives a string representation that is + * partly compatibly with iproute2. That is, the part after `ip -[46] rule add $ARGS`. + * There are differences though: + * + * - trying to convert an invalid rule to string may not be possible. The reason is for + * example that an invalid rule can have nm_ip_routing_rule_get_from() like "bogus", + * but we don't write that as "from bogus". In general, if you try to convert an invalid + * rule to string, the operation may fail or the result may itself not be parsable. + * Of course, valid rules can be converted to string and read back the same (round-trip). + * + * - iproute2 in may regards is flexible about the command lines. For example + * - for tables it accepts table names from /etc/iproute2/rt_tables. We only + * accept the special aliases "main", "local", and "default". + * - key names like "preference" can be abbreviated to "pref", we don't do that. + * - the "preference"/"priority" may be unspecified, in which kernel automatically + * chooses an unused priority (during `ip rule add`). We don't allow for that, the + * priority must be explicitly set. + * + * - iproute2 does not support any escaping. Well, it's the shell that supports quoting + * and escaping and splits the command line. We need to split the command line ourself, + * but we don't support full shell quotation. + * from-string tokenizes words at (ASCII) whitespaces (removing the whitespaces). + * It also supports backslash escaping (e.g. to contain whitespace), but it does + * not support special escape sequences. Values are taken literally, meaning + * "\n\ \111" gives results in "n 111". + * The strings really shouldn't contain any special characters that require escaping, + * but that's the rule. + * This also goes together with the @allow_escaping parameter of nm_utils_strsplit_set(). + * If you concatenate multiple rule expressions with a delimiter, the delimiter inside + * each word can be backslash escaped, and nm_utils_strsplit_set(allow_escaping=TRUE) will + * properly split the words, preserving the backslashes, which then will be removed by + * nm_ip_routing_rule_from_string(). + */ + + addr_family = _rr_string_addr_family_from_flags(to_string_flags); + + tokens = nm_utils_escaped_tokens_split(str, NM_ASCII_SPACES); + for (i_token = 0; tokens && tokens[i_token]; i_token++) { + char *str_word = (char *) tokens[i_token]; + + any_words = TRUE; + if (!word0) + word0 = str_word; + else { + nm_assert(!word1); + word1 = str_word; + } + + /* iproute2 matches keywords with any partial prefix. We don't allow + * for that flexibility. */ + + if (NM_IN_STRSET(word0, "from")) { + if (!word1) + continue; + if (word_from) + goto next_fail_word0_duplicate_key; + word_from = word1; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "to")) { + if (!word1) + continue; + if (word_to) + goto next_fail_word0_duplicate_key; + word_to = word1; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "not")) { + /* we accept multiple "not" specifiers. "not not" still means + * not. */ + val_invert = TRUE; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "priority", "order", "pref", "preference")) { + if (!word1) + continue; + if (i64_priority != -1) + goto next_fail_word0_duplicate_key; + i64_priority = _nm_utils_ascii_str_to_int64(word1, 0, 0, G_MAXUINT32, -1); + if (i64_priority == -1) + goto next_fail_word1_invalid_value; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "table", "lookup")) { + if (!word1) + continue; + if (i64_table != -1) + goto next_fail_word0_duplicate_key; + i64_table = _nm_utils_ascii_str_to_int64(word1, 0, 0, G_MAXUINT32, -1); + if (i64_table == -1) { + if (nm_streq(word1, "main")) + i64_table = RT_TABLE_MAIN; + else if (nm_streq(word1, "local")) + i64_table = RT_TABLE_LOCAL; + else if (nm_streq(word1, "default")) + i64_table = RT_TABLE_DEFAULT; + else + goto next_fail_word1_invalid_value; + } + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "tos", "dsfield")) { + if (!word1) + continue; + if (i64_tos != -1) + goto next_fail_word0_duplicate_key; + i64_tos = _nm_utils_ascii_str_to_int64(word1, 16, 0, G_MAXUINT8, -1); + if (i64_tos == -1) + goto next_fail_word1_invalid_value; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "ipproto")) { + if (!word1) + continue; + if (i64_ipproto != -1) + goto next_fail_word0_duplicate_key; + i64_ipproto = _nm_utils_ascii_str_to_int64(word1, 10, 0, G_MAXUINT8, -1); + if (i64_ipproto == -1) + goto next_fail_word1_invalid_value; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "sport")) { + if (!word1) + continue; + if (i64_sport_start != -1) + goto next_fail_word0_duplicate_key; + if (!_rr_xport_range_parse(word1, &i64_sport_start, &sport_end)) + goto next_fail_word1_invalid_value; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "dport")) { + if (!word1) + continue; + if (i64_dport_start != -1) + goto next_fail_word0_duplicate_key; + if (!_rr_xport_range_parse(word1, &i64_dport_start, &dport_end)) + goto next_fail_word1_invalid_value; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "fwmark")) { + if (!word1) + continue; + if (i64_fwmark != -1) + goto next_fail_word0_duplicate_key; + s = strchr(word1, '/'); + if (s) + *(s++) = '\0'; + i64_fwmark = _nm_utils_ascii_str_to_int64(word1, 0, 0, G_MAXUINT32, -1); + if (i64_fwmark == -1) + goto next_fail_word1_invalid_value; + if (s) { + i64_fwmask = _nm_utils_ascii_str_to_int64(s, 0, 0, G_MAXUINT32, -1); + if (i64_fwmask == -1) + goto next_fail_word1_invalid_value; + } else + i64_fwmask = 0xFFFFFFFFu; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "iif", "dev")) { + if (!word1) + continue; + if (word_iifname) + goto next_fail_word0_duplicate_key; + word_iifname = word1; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "oif")) { + if (!word1) + continue; + if (word_oifname) + goto next_fail_word0_duplicate_key; + word_oifname = word1; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "suppress_prefixlength", "sup_pl")) { + if (!word1) + continue; + if (i64_suppress_prefixlength != -1) + goto next_fail_word0_duplicate_key; + i64_suppress_prefixlength = _nm_utils_ascii_str_to_int64(word1, 0, 0, G_MAXINT32, -1); + if (i64_suppress_prefixlength == -1) + goto next_fail_word1_invalid_value; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "uidrange")) { + if (!word1) + continue; + if (uid_range_has) + goto next_fail_word0_duplicate_key; + s = strchr(word1, '-'); + if (s) + (s++)[0] = '\0'; + uid_range_start = _nm_utils_ascii_str_to_int64(word1, 0, 0, G_MAXUINT32, 0); + if (errno) + goto next_fail_word1_invalid_value; + if (s) { + uid_range_end = _nm_utils_ascii_str_to_int64(s, 0, 0, G_MAXUINT32, 0); + if (errno) + goto next_fail_word1_invalid_value; + if (uid_range_end < uid_range_start) + goto next_fail_word1_invalid_value; + } else + uid_range_end = uid_range_start; + uid_range_has = TRUE; + goto next_words_consumed; + } + if (NM_IN_STRSET(word0, "type")) { + if (!word1) + continue; + if (i_action >= 0) + goto next_fail_word0_duplicate_key; + i_action = nm_net_aux_rtnl_rtntype_a2n(word1); + if (i_action < 0) + goto next_fail_word1_invalid_value; + goto next_words_consumed; + } + + if (i_action < 0) { + i_action = nm_net_aux_rtnl_rtntype_a2n(word1); + if (i_action >= 0) + goto next_words_consumed; + } + + /* also the action is still unsupported. For the moment, we only support + * FR_ACT_TO_TBL, which is the default (by not expressing it on the command + * line). */ + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("unsupported key \"%s\""), + word0); + return FALSE; +next_fail_word0_duplicate_key: + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("duplicate key \"%s\""), + word0); + return FALSE; +next_fail_word1_invalid_value: + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid value for \"%s\""), + word0); + return FALSE; +next_words_consumed: + word0 = NULL; + word1 = NULL; + } + + if (!any_words) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("empty text does not describe a rule")); + return FALSE; + } + + if (word0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("missing argument for \"%s\""), + word0); + return FALSE; + } + + if (!NM_IN_STRSET(word_from, NULL, "all")) { + if (!nm_utils_parse_inaddr_prefix_bin(addr_family, + word_from, + &addr_family, + &val_from, + &val_from_len)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid \"from\" part")); + return FALSE; + } + if (val_from_len == -1) + val_from_len = nm_utils_addr_family_to_size(addr_family) * 8; + } + + if (!NM_IN_STRSET(word_to, NULL, "all")) { + if (!nm_utils_parse_inaddr_prefix_bin(addr_family, + word_to, + &addr_family, + &val_to, + &val_to_len)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid \"to\" part")); + return FALSE; + } + if (val_to_len == -1) + val_to_len = nm_utils_addr_family_to_size(addr_family) * 8; + } + + if (!NM_IN_SET(addr_family, AF_INET, AF_INET6)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("cannot detect address family for rule")); + return FALSE; + } + + self = nm_ip_routing_rule_new(addr_family); + + if (val_invert) + self->invert = TRUE; + + if (i64_priority != -1) + nm_ip_routing_rule_set_priority(self, i64_priority); + + if (i_action >= 0) { + nm_ip_routing_rule_set_action(self, i_action); + if (i64_table == -1) { + if (i_action != FR_ACT_TO_TBL) + i64_table = 0; + else + i64_table = RT_TABLE_MAIN; + } + } + + if (i64_tos != -1) + nm_ip_routing_rule_set_tos(self, i64_tos); + + if (i64_ipproto != -1) + nm_ip_routing_rule_set_ipproto(self, i64_ipproto); + + if (i64_fwmark != -1) + nm_ip_routing_rule_set_fwmark(self, i64_fwmark, i64_fwmask); + + if (i64_sport_start != -1) + nm_ip_routing_rule_set_source_port(self, i64_sport_start, sport_end); + + if (i64_dport_start != -1) + nm_ip_routing_rule_set_destination_port(self, i64_dport_start, dport_end); + + if (i64_suppress_prefixlength != -1) + nm_ip_routing_rule_set_suppress_prefixlength(self, i64_suppress_prefixlength); + + if (val_from_len > 0 || (val_from_len == 0 && !nm_ip_addr_is_null(addr_family, &val_from))) { + nm_ip_routing_rule_set_from_bin(self, &val_from, val_from_len); + } + + if (val_to_len > 0 || (val_to_len == 0 && !nm_ip_addr_is_null(addr_family, &val_to))) { + nm_ip_routing_rule_set_to_bin(self, &val_to, val_to_len); + } + + if (word_iifname) + nm_ip_routing_rule_set_iifname(self, word_iifname); + + if (word_oifname) + nm_ip_routing_rule_set_oifname(self, word_oifname); + + if (i64_table != -1) + nm_ip_routing_rule_set_table(self, i64_table); + + if (uid_range_has) + nm_ip_routing_rule_set_uid_range(self, uid_range_start, uid_range_end); + + if (NM_FLAGS_HAS(to_string_flags, NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE)) { + gs_free_error GError *local = NULL; + + if (!nm_ip_routing_rule_validate(self, &local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("rule is invalid: %s"), + local->message); + return NULL; + } + } + + return g_steal_pointer(&self); +} + +static void +_rr_string_append_inet_addr(NMStrBuf * str, + gboolean is_from /* or else is-to */, + gboolean required, + int addr_family, + const NMIPAddr *addr_bin, + guint8 addr_len) +{ + char addr_str[NM_UTILS_INET_ADDRSTRLEN]; + + if (addr_len == 0) { + if (required) { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(str, ' '), + "%s %s/0", + is_from ? "from" : "to", + (addr_family == AF_INET) ? "0.0.0.0" : "::"); + } + return; + } + + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(str, ' '), + "%s %s", + is_from ? "from" : "to", + nm_utils_inet_ntop(addr_family, addr_bin, addr_str)); + if (addr_len != nm_utils_addr_family_to_size(addr_family) * 8) { + nm_str_buf_append_printf(str, "/%u", addr_len); + } +} + +/** + * nm_ip_routing_rule_to_string: + * @self: the #NMIPRoutingRule instance to convert to string. + * @to_string_flags: #NMIPRoutingRuleAsStringFlags for controlling the + * string conversion. + * @extra_args: (allow-none): extra arguments for controlling the string + * conversion. Currently, not extra arguments are supported. + * @error: (allow-none) (out): the error reason. + * + * Returns: (transfer full): the string representation or %NULL on error. + * + * Since: 1.18 + */ +char * +nm_ip_routing_rule_to_string(const NMIPRoutingRule * self, + NMIPRoutingRuleAsStringFlags to_string_flags, + GHashTable * extra_args, + GError ** error) +{ + int addr_family; + NMStrBuf str; + + g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(self, TRUE), NULL); + + if (!_rr_string_validate(FALSE, to_string_flags, extra_args, error)) + return NULL; + + addr_family = nm_ip_routing_rule_get_addr_family(self); + + if (!NM_IN_SET(_rr_string_addr_family_from_flags(to_string_flags), AF_UNSPEC, addr_family)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid address family")); + return NULL; + } + + /* It is only guaranteed that valid rules can be expressed as string. + * + * Still, unless requested proceed to convert to string without validating and + * hope for the best. + * + * That is, because self->from_str might contain an invalid IP address (indicated + * by self->from_valid). But we don't support serializing such arbitrary strings + * as "from %s". */ + if (NM_FLAGS_HAS(to_string_flags, NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE)) { + gs_free_error GError *local = NULL; + + if (!nm_ip_routing_rule_validate(self, &local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("rule is invalid: %s"), + local->message); + return NULL; + } + } + + nm_str_buf_init(&str, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); + + if (self->priority_has) { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), + "priority %u", + (guint) self->priority); + } + + if (self->invert) + nm_str_buf_append(nm_str_buf_append_required_delimiter(&str, ' '), "not"); + + _rr_string_append_inet_addr(&str, + TRUE, + (!self->to_has || !self->to_valid), + addr_family, + &self->from_bin, + (self->from_has && self->from_valid) ? self->from_len : 0); + + _rr_string_append_inet_addr(&str, + FALSE, + FALSE, + addr_family, + &self->to_bin, + (self->to_has && self->to_valid) ? self->to_len : 0); + + if (self->tos != 0) { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), + "tos 0x%02x", + (guint) self->tos); + } + + if (self->ipproto != 0) { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), + "ipproto %u", + (guint) self->ipproto); + } + + if (self->fwmark != 0 || self->fwmask != 0) { + if (self->fwmark != 0) { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), + "fwmark 0x%x", + self->fwmark); + } else { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), "fwmark 0"); + } + if (self->fwmask != 0xFFFFFFFFu) { + if (self->fwmask != 0) + nm_str_buf_append_printf(&str, "/0x%x", self->fwmask); + else + nm_str_buf_append_printf(&str, "/0"); + } + } + + if (self->sport_start != 0 || self->sport_end != 0) { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), + "sport %u", + self->sport_start); + if (self->sport_start != self->sport_end) { + nm_str_buf_append_printf(&str, "-%u", self->sport_end); + } + } + + if (self->dport_start != 0 || self->dport_end != 0) { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), + "dport %u", + self->dport_start); + if (self->dport_start != self->dport_end) { + nm_str_buf_append_printf(&str, "-%u", self->dport_end); + } + } + + if (self->iifname) { + nm_str_buf_append(nm_str_buf_append_required_delimiter(&str, ' '), "iif "); + nm_utils_escaped_tokens_escape_strbuf(self->iifname, NM_ASCII_SPACES, &str); + } + + if (self->oifname) { + nm_str_buf_append(nm_str_buf_append_required_delimiter(&str, ' '), "oif "); + nm_utils_escaped_tokens_escape_strbuf(self->oifname, NM_ASCII_SPACES, &str); + } + + if (self->uid_range_has) { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), + "uidrange %u-%u", + self->uid_range_start, + self->uid_range_end); + } + + if (self->suppress_prefixlength != -1) { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), + "suppress_prefixlength %d", + (int) self->suppress_prefixlength); + } + + if (self->table != 0 || self->action == FR_ACT_TO_TBL) { + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), + "table %u", + (guint) self->table); + } + + if (self->action != FR_ACT_TO_TBL) { + char sbuf[100]; + + nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), + "type %s", + nm_net_aux_rtnl_rtntype_n2a_maybe_buf(self->action, sbuf)); + } + + return nm_str_buf_finalize(&str, NULL); +} + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingIPConfig, + PROP_METHOD, + PROP_DNS, + PROP_DNS_SEARCH, + PROP_DNS_OPTIONS, + PROP_DNS_PRIORITY, + PROP_ADDRESSES, + PROP_GATEWAY, + PROP_ROUTES, + PROP_ROUTE_METRIC, + PROP_ROUTE_TABLE, + PROP_IGNORE_AUTO_ROUTES, + PROP_IGNORE_AUTO_DNS, + PROP_DHCP_HOSTNAME, + PROP_DHCP_HOSTNAME_FLAGS, + PROP_DHCP_SEND_HOSTNAME, + PROP_NEVER_DEFAULT, + PROP_MAY_FAIL, + PROP_DAD_TIMEOUT, + PROP_DHCP_TIMEOUT, + PROP_DHCP_IAID, + PROP_DHCP_REJECT_SERVERS, ); + +typedef struct { + GPtrArray *dns; /* array of IP address strings */ + GPtrArray *dns_search; /* array of domain name strings */ + GPtrArray *dns_options; /* array of DNS options */ + GPtrArray *addresses; /* array of NMIPAddress */ + GPtrArray *routes; /* array of NMIPRoute */ + GPtrArray *routing_rules; + GArray * dhcp_reject_servers; + char * method; + char * gateway; + char * dhcp_hostname; + char * dhcp_iaid; + gint64 route_metric; + guint dhcp_hostname_flags; + int dns_priority; + int dad_timeout; + int dhcp_timeout; + guint32 route_table; + bool ignore_auto_routes : 1; + bool ignore_auto_dns : 1; + bool dhcp_send_hostname : 1; + bool never_default : 1; + bool may_fail : 1; +} NMSettingIPConfigPrivate; + +G_DEFINE_ABSTRACT_TYPE(NMSettingIPConfig, nm_setting_ip_config, NM_TYPE_SETTING) + +#define NM_SETTING_IP_CONFIG_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_IP_CONFIG, NMSettingIPConfigPrivate)) + +/*****************************************************************************/ + +#define NM_SETTING_IP_CONFIG_GET_FAMILY(setting) \ + (NM_IS_SETTING_IP4_CONFIG(setting) ? AF_INET : AF_INET6) + +/** + * nm_setting_ip_config_get_method: + * @setting: the #NMSettingIPConfig + * + * Returns: the #NMSettingIPConfig:method property of the setting; see + * #NMSettingIP4Config and #NMSettingIP6Config for details of the + * methods available with each type. + **/ +const char * +nm_setting_ip_config_get_method(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->method; +} + +/** + * nm_setting_ip_config_get_num_dns: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured DNS servers + **/ +guint +nm_setting_ip_config_get_num_dns(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns->len; +} + +/** + * nm_setting_ip_config_get_dns: + * @setting: the #NMSettingIPConfig + * @idx: index number of the DNS server to return + * + * Returns: the IP address of the DNS server at index @idx + **/ +const char * +nm_setting_ip_config_get_dns(NMSettingIPConfig *setting, int idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_val_if_fail(idx >= 0 && idx < priv->dns->len, NULL); + + return priv->dns->pdata[idx]; +} + +/** + * nm_setting_ip_config_add_dns: + * @setting: the #NMSettingIPConfig + * @dns: the IP address of the DNS server to add + * + * Adds a new DNS server to the setting. + * + * Returns: %TRUE if the DNS server was added; %FALSE if the server was already + * known + **/ +gboolean +nm_setting_ip_config_add_dns(NMSettingIPConfig *setting, const char *dns) +{ + NMSettingIPConfigPrivate *priv; + char * dns_canonical; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + g_return_val_if_fail(dns != NULL, FALSE); + g_return_val_if_fail(nm_utils_ipaddr_is_valid(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), dns), + FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + dns_canonical = canonicalize_ip(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), dns, FALSE); + for (i = 0; i < priv->dns->len; i++) { + if (!strcmp(dns_canonical, priv->dns->pdata[i])) { + g_free(dns_canonical); + return FALSE; + } + } + + g_ptr_array_add(priv->dns, dns_canonical); + _notify(setting, PROP_DNS); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_dns: + * @setting: the #NMSettingIPConfig + * @idx: index number of the DNS server to remove + * + * Removes the DNS server at index @idx. + **/ +void +nm_setting_ip_config_remove_dns(NMSettingIPConfig *setting, int idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_if_fail(idx >= 0 && idx < priv->dns->len); + + g_ptr_array_remove_index(priv->dns, idx); + _notify(setting, PROP_DNS); +} + +/** + * nm_setting_ip_config_remove_dns_by_value: + * @setting: the #NMSettingIPConfig + * @dns: the DNS server to remove + * + * Removes the DNS server @dns. + * + * Returns: %TRUE if the DNS server was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_ip_config_remove_dns_by_value(NMSettingIPConfig *setting, const char *dns) +{ + NMSettingIPConfigPrivate *priv; + char * dns_canonical; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + g_return_val_if_fail(dns != NULL, FALSE); + g_return_val_if_fail(nm_utils_ipaddr_is_valid(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), dns), + FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + dns_canonical = canonicalize_ip(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), dns, FALSE); + for (i = 0; i < priv->dns->len; i++) { + if (!strcmp(dns_canonical, priv->dns->pdata[i])) { + g_ptr_array_remove_index(priv->dns, i); + _notify(setting, PROP_DNS); + g_free(dns_canonical); + return TRUE; + } + } + g_free(dns_canonical); + return FALSE; +} + +/** + * nm_setting_ip_config_clear_dns: + * @setting: the #NMSettingIPConfig + * + * Removes all configured DNS servers. + **/ +void +nm_setting_ip_config_clear_dns(NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + if (priv->dns->len != 0) { + g_ptr_array_set_size(priv->dns, 0); + _notify(setting, PROP_DNS); + } +} + +/** + * nm_setting_ip_config_get_num_dns_searches: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured DNS search domains + **/ +guint +nm_setting_ip_config_get_num_dns_searches(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_search->len; +} + +/** + * nm_setting_ip_config_get_dns_search: + * @setting: the #NMSettingIPConfig + * @idx: index number of the DNS search domain to return + * + * Returns: the DNS search domain at index @idx + **/ +const char * +nm_setting_ip_config_get_dns_search(NMSettingIPConfig *setting, int idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_val_if_fail(idx >= 0 && idx < priv->dns_search->len, NULL); + + return priv->dns_search->pdata[idx]; +} + +/** + * nm_setting_ip_config_add_dns_search: + * @setting: the #NMSettingIPConfig + * @dns_search: the search domain to add + * + * Adds a new DNS search domain to the setting. + * + * Returns: %TRUE if the DNS search domain was added; %FALSE if the search + * domain was already known + **/ +gboolean +nm_setting_ip_config_add_dns_search(NMSettingIPConfig *setting, const char *dns_search) +{ + NMSettingIPConfigPrivate *priv; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + g_return_val_if_fail(dns_search != NULL, FALSE); + g_return_val_if_fail(dns_search[0] != '\0', FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + for (i = 0; i < priv->dns_search->len; i++) { + if (!strcmp(dns_search, priv->dns_search->pdata[i])) + return FALSE; + } + + g_ptr_array_add(priv->dns_search, g_strdup(dns_search)); + _notify(setting, PROP_DNS_SEARCH); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_dns_search: + * @setting: the #NMSettingIPConfig + * @idx: index number of the DNS search domain + * + * Removes the DNS search domain at index @idx. + **/ +void +nm_setting_ip_config_remove_dns_search(NMSettingIPConfig *setting, int idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_if_fail(idx >= 0 && idx < priv->dns_search->len); + + g_ptr_array_remove_index(priv->dns_search, idx); + _notify(setting, PROP_DNS_SEARCH); +} + +/** + * nm_setting_ip_config_remove_dns_search_by_value: + * @setting: the #NMSettingIPConfig + * @dns_search: the search domain to remove + * + * Removes the DNS search domain @dns_search. + * + * Returns: %TRUE if the DNS search domain was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_ip_config_remove_dns_search_by_value(NMSettingIPConfig *setting, const char *dns_search) +{ + NMSettingIPConfigPrivate *priv; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + g_return_val_if_fail(dns_search != NULL, FALSE); + g_return_val_if_fail(dns_search[0] != '\0', FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + for (i = 0; i < priv->dns_search->len; i++) { + if (!strcmp(dns_search, priv->dns_search->pdata[i])) { + g_ptr_array_remove_index(priv->dns_search, i); + _notify(setting, PROP_DNS_SEARCH); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_ip_config_clear_dns_searches: + * @setting: the #NMSettingIPConfig + * + * Removes all configured DNS search domains. + **/ +void +nm_setting_ip_config_clear_dns_searches(NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + if (priv->dns_search->len != 0) { + g_ptr_array_set_size(priv->dns_search, 0); + _notify(setting, PROP_DNS_SEARCH); + } +} + +/** + * nm_setting_ip_config_get_num_dns_options: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured DNS options + * + * Since: 1.2 + **/ +guint +nm_setting_ip_config_get_num_dns_options(NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + return priv->dns_options ? priv->dns_options->len : 0; +} + +/** + * nm_setting_ip_config_has_dns_options: + * @setting: the #NMSettingIPConfig + * + * NMSettingIPConfig can have a list of dns-options. If the list + * is empty, there are two similar (but differentiated) states. + * Either the options are explicitly set to have no values, + * or the options are left undefined. The latter means to use + * a default configuration, while the former explicitly means "no-options". + * + * Returns: whether DNS options are initialized or left unset (the default). + **/ +gboolean +nm_setting_ip_config_has_dns_options(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + return !!NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_options; +} + +/** + * nm_setting_ip_config_get_dns_option: + * @setting: the #NMSettingIPConfig + * @idx: index number of the DNS option + * + * Returns: the DNS option at index @idx + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_config_get_dns_option(NMSettingIPConfig *setting, guint idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_val_if_fail(priv->dns_options, NULL); + g_return_val_if_fail(idx < priv->dns_options->len, NULL); + + return priv->dns_options->pdata[idx]; +} + +/** + * nm_setting_ip_config_next_valid_dns_option: + * @setting: the #NMSettingIPConfig + * @idx: index to start the search from + * + * Returns: the index, greater or equal than @idx, of the first valid + * DNS option, or -1 if no valid option is found + **/ +int +nm_setting_ip_config_next_valid_dns_option(NMSettingIPConfig *setting, guint idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), -1); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + if (!priv->dns_options) + return -1; + + for (; idx < priv->dns_options->len; idx++) { + if (_nm_utils_dns_option_validate(priv->dns_options->pdata[idx], + NULL, + NULL, + NM_IS_SETTING_IP6_CONFIG(setting), + _nm_utils_dns_option_descs)) + return idx; + } + + return -1; +} + +/** + * nm_setting_ip_config_add_dns_option: + * @setting: the #NMSettingIPConfig + * @dns_option: the DNS option to add + * + * Adds a new DNS option to the setting. + * + * Returns: %TRUE if the DNS option was added; %FALSE otherwise + * + * Since: 1.2 + **/ +gboolean +nm_setting_ip_config_add_dns_option(NMSettingIPConfig *setting, const char *dns_option) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + g_return_val_if_fail(dns_option != NULL, FALSE); + g_return_val_if_fail(dns_option[0] != '\0', FALSE); + + if (!_nm_utils_dns_option_validate(dns_option, NULL, NULL, FALSE, NULL)) + return FALSE; + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + if (!priv->dns_options) + priv->dns_options = g_ptr_array_new_with_free_func(g_free); + else { + if (_nm_utils_dns_option_find_idx(priv->dns_options, dns_option) >= 0) + return FALSE; + } + + g_ptr_array_add(priv->dns_options, g_strdup(dns_option)); + _notify(setting, PROP_DNS_OPTIONS); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_dns_option: + * @setting: the #NMSettingIPConfig + * @idx: index number of the DNS option + * + * Removes the DNS option at index @idx. + * + * Since: 1.2 + **/ +void +nm_setting_ip_config_remove_dns_option(NMSettingIPConfig *setting, int idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_if_fail(priv->dns_options); + g_return_if_fail(idx >= 0 && idx < priv->dns_options->len); + + g_ptr_array_remove_index(priv->dns_options, idx); + _notify(setting, PROP_DNS_OPTIONS); +} + +/** + * nm_setting_ip_config_remove_dns_option_by_value: + * @setting: the #NMSettingIPConfig + * @dns_option: the DNS option to remove + * + * Removes the DNS option @dns_option. + * + * Returns: %TRUE if the DNS option was found and removed; %FALSE if it was not. + * + * Since: 1.2 + **/ +gboolean +nm_setting_ip_config_remove_dns_option_by_value(NMSettingIPConfig *setting, const char *dns_option) +{ + NMSettingIPConfigPrivate *priv; + gssize i; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + g_return_val_if_fail(dns_option != NULL, FALSE); + g_return_val_if_fail(dns_option[0] != '\0', FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + if (!priv->dns_options) + return FALSE; + + i = _nm_utils_dns_option_find_idx(priv->dns_options, dns_option); + if (i >= 0) { + g_ptr_array_remove_index(priv->dns_options, i); + _notify(setting, PROP_DNS_OPTIONS); + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_ip_config_clear_dns_options: + * @setting: the #NMSettingIPConfig + * @is_set: the dns-options can be either empty or unset (default). + * Specify how to clear the options. + * + * Removes all configured DNS options. + * + * Since: 1.2 + **/ +void +nm_setting_ip_config_clear_dns_options(NMSettingIPConfig *setting, gboolean is_set) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + if (!priv->dns_options) { + if (!is_set) + return; + priv->dns_options = g_ptr_array_new_with_free_func(g_free); + } else { + if (!is_set) { + g_ptr_array_unref(priv->dns_options); + priv->dns_options = NULL; + } else { + if (priv->dns_options->len == 0) + return; + g_ptr_array_set_size(priv->dns_options, 0); + } + } + _notify(setting, PROP_DNS_OPTIONS); +} + +/** + * nm_setting_ip_config_get_dns_priority: + * @setting: the #NMSettingIPConfig + * + * Returns: the priority of DNS servers + * + * Since: 1.4 + **/ +int +nm_setting_ip_config_get_dns_priority(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_priority; +} + +/** + * nm_setting_ip_config_get_num_addresses: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured addresses + **/ +guint +nm_setting_ip_config_get_num_addresses(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->addresses->len; +} + +/** + * nm_setting_ip_config_get_address: + * @setting: the #NMSettingIPConfig + * @idx: index number of the address to return + * + * Returns: (transfer none): the address at index @idx + **/ +NMIPAddress * +nm_setting_ip_config_get_address(NMSettingIPConfig *setting, int idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_val_if_fail(idx >= 0 && idx < priv->addresses->len, NULL); + + return priv->addresses->pdata[idx]; +} + +/** + * nm_setting_ip_config_add_address: + * @setting: the #NMSettingIPConfig + * @address: the new address to add + * + * Adds a new IP address and associated information to the setting. The + * given address is duplicated internally and is not changed by this function. + * + * Returns: %TRUE if the address was added; %FALSE if the address was already + * known. + **/ +gboolean +nm_setting_ip_config_add_address(NMSettingIPConfig *setting, NMIPAddress *address) +{ + NMSettingIPConfigPrivate *priv; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + g_return_val_if_fail(address != NULL, FALSE); + g_return_val_if_fail(address->family == NM_SETTING_IP_CONFIG_GET_FAMILY(setting), FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + for (i = 0; i < priv->addresses->len; i++) { + if (nm_ip_address_equal(priv->addresses->pdata[i], address)) + return FALSE; + } + + g_ptr_array_add(priv->addresses, nm_ip_address_dup(address)); + + _notify(setting, PROP_ADDRESSES); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_address: + * @setting: the #NMSettingIPConfig + * @idx: index number of the address to remove + * + * Removes the address at index @idx. + **/ +void +nm_setting_ip_config_remove_address(NMSettingIPConfig *setting, int idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_if_fail(idx >= 0 && idx < priv->addresses->len); + + g_ptr_array_remove_index(priv->addresses, idx); + + _notify(setting, PROP_ADDRESSES); +} + +/** + * nm_setting_ip_config_remove_address_by_value: + * @setting: the #NMSettingIPConfig + * @address: the IP address to remove + * + * Removes the address @address. + * + * Returns: %TRUE if the address was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_ip_config_remove_address_by_value(NMSettingIPConfig *setting, NMIPAddress *address) +{ + NMSettingIPConfigPrivate *priv; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + g_return_val_if_fail(address != NULL, FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + for (i = 0; i < priv->addresses->len; i++) { + if (nm_ip_address_equal(priv->addresses->pdata[i], address)) { + g_ptr_array_remove_index(priv->addresses, i); + _notify(setting, PROP_ADDRESSES); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_ip_config_clear_addresses: + * @setting: the #NMSettingIPConfig + * + * Removes all configured addresses. + **/ +void +nm_setting_ip_config_clear_addresses(NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + if (priv->addresses->len != 0) { + g_ptr_array_set_size(priv->addresses, 0); + _notify(setting, PROP_ADDRESSES); + } +} + +/** + * nm_setting_ip_config_get_gateway: + * @setting: the #NMSettingIPConfig + * + * Returns: the IP address of the gateway associated with this configuration, or + * %NULL. + **/ +const char * +nm_setting_ip_config_get_gateway(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->gateway; +} + +/** + * nm_setting_ip_config_get_num_routes: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured routes + **/ +guint +nm_setting_ip_config_get_num_routes(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->routes->len; +} + +/** + * nm_setting_ip_config_get_route: + * @setting: the #NMSettingIPConfig + * @idx: index number of the route to return + * + * Returns: (transfer none): the route at index @idx + **/ +NMIPRoute * +nm_setting_ip_config_get_route(NMSettingIPConfig *setting, int idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_val_if_fail(idx >= 0 && idx < priv->routes->len, NULL); + + return priv->routes->pdata[idx]; +} + +/** + * nm_setting_ip_config_add_route: + * @setting: the #NMSettingIPConfig + * @route: the route to add + * + * Appends a new route and associated information to the setting. The + * given route is duplicated internally and is not changed by this function. + * If an identical route (considering attributes as well) already exists, the + * route is not added and the function returns %FALSE. + * + * Note that before 1.10, this function would not consider route attributes + * and not add a route that has an existing route with same dest/prefix,next_hop,metric + * parameters. + * + * Returns: %TRUE if the route was added; %FALSE if the route was already known. + **/ +gboolean +nm_setting_ip_config_add_route(NMSettingIPConfig *setting, NMIPRoute *route) +{ + NMSettingIPConfigPrivate *priv; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + g_return_val_if_fail(route != NULL, FALSE); + g_return_val_if_fail(route->family == NM_SETTING_IP_CONFIG_GET_FAMILY(setting), FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + for (i = 0; i < priv->routes->len; i++) { + if (nm_ip_route_equal_full(priv->routes->pdata[i], + route, + NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS)) + return FALSE; + } + + g_ptr_array_add(priv->routes, nm_ip_route_dup(route)); + _notify(setting, PROP_ROUTES); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_route: + * @setting: the #NMSettingIPConfig + * @idx: index number of the route + * + * Removes the route at index @idx. + **/ +void +nm_setting_ip_config_remove_route(NMSettingIPConfig *setting, int idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_if_fail(idx >= 0 && idx < priv->routes->len); + + g_ptr_array_remove_index(priv->routes, idx); + _notify(setting, PROP_ROUTES); +} + +/** + * nm_setting_ip_config_remove_route_by_value: + * @setting: the #NMSettingIPConfig + * @route: the route to remove + * + * Removes the first matching route that matches @route. + * Note that before 1.10, this function would only compare dest/prefix,next_hop,metric + * and ignore route attributes. Now, @route must match exactly. + * + * Returns: %TRUE if the route was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_ip_config_remove_route_by_value(NMSettingIPConfig *setting, NMIPRoute *route) +{ + NMSettingIPConfigPrivate *priv; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + g_return_val_if_fail(route != NULL, FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + for (i = 0; i < priv->routes->len; i++) { + if (nm_ip_route_equal_full(priv->routes->pdata[i], + route, + NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS)) { + g_ptr_array_remove_index(priv->routes, i); + _notify(setting, PROP_ROUTES); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_ip_config_clear_routes: + * @setting: the #NMSettingIPConfig + * + * Removes all configured routes. + **/ +void +nm_setting_ip_config_clear_routes(NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + if (priv->routes->len != 0) { + g_ptr_array_set_size(priv->routes, 0); + _notify(setting, PROP_ROUTES); + } +} + +/** + * nm_setting_ip_config_get_route_metric: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:route-metric + * property. + * + * Returns: the route metric that is used for routes that don't explicitly + * specify a metric. See #NMSettingIPConfig:route-metric for more details. + **/ +gint64 +nm_setting_ip_config_get_route_metric(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), -1); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->route_metric; +} + +/** + * nm_setting_ip_config_get_route_table: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:route-table + * property. + * + * Returns: the configured route-table. + * + * Since: 1.10 + **/ +guint32 +nm_setting_ip_config_get_route_table(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->route_table; +} + +/*****************************************************************************/ + +static void +_routing_rules_notify(NMSettingIPConfig *setting) +{ + _nm_setting_emit_property_changed(NM_SETTING(setting)); +} + +/** + * nm_setting_ip_config_get_num_routing_rules: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured routing rules + * + * Since: 1.18 + **/ +guint +nm_setting_ip_config_get_num_routing_rules(NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + return priv->routing_rules ? priv->routing_rules->len : 0u; +} + +/** + * nm_setting_ip_config_get_routing_rule: + * @setting: the #NMSettingIPConfig + * @idx: index number of the routing_rule to return + * + * Returns: (transfer none): the routing rule at index @idx + * + * Since: 1.18 + **/ +NMIPRoutingRule * +nm_setting_ip_config_get_routing_rule(NMSettingIPConfig *setting, guint idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + g_return_val_if_fail(priv->routing_rules && idx < priv->routing_rules->len, NULL); + + return priv->routing_rules->pdata[idx]; +} + +/** + * nm_setting_ip_config_add_routing_rule: + * @setting: the #NMSettingIPConfig + * @routing_rule: the #NMIPRoutingRule to add. The address family + * of the added rule must be compatible with the setting. + * + * Appends a new routing-rule and associated information to the setting. The + * given routing rules gets sealed and the reference count is incremented. + * The function does not check whether an identical rule already exists + * and always appends the rule to the end of the list. + * + * Since: 1.18 + **/ +void +nm_setting_ip_config_add_routing_rule(NMSettingIPConfig *setting, NMIPRoutingRule *routing_rule) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + g_return_if_fail(NM_IS_IP_ROUTING_RULE(routing_rule, TRUE)); + g_return_if_fail(_ip_routing_rule_get_addr_family(routing_rule) + == NM_SETTING_IP_CONFIG_GET_FAMILY(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + if (!priv->routing_rules) + priv->routing_rules = + g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_routing_rule_unref); + + nm_ip_routing_rule_seal(routing_rule); + g_ptr_array_add(priv->routing_rules, nm_ip_routing_rule_ref(routing_rule)); + _routing_rules_notify(setting); +} + +/** + * nm_setting_ip_config_remove_routing_rule: + * @setting: the #NMSettingIPConfig + * @idx: index number of the routing_rule + * + * Removes the routing_rule at index @idx. + * + * Since: 1.18 + **/ +void +nm_setting_ip_config_remove_routing_rule(NMSettingIPConfig *setting, guint idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_if_fail(priv->routing_rules && idx < priv->routing_rules->len); + + g_ptr_array_remove_index(priv->routing_rules, idx); + _routing_rules_notify(setting); +} + +/** + * nm_setting_ip_config_clear_routing_rules: + * @setting: the #NMSettingIPConfig + * + * Removes all configured routing rules. + * + * Since: 1.18 + **/ +void +nm_setting_ip_config_clear_routing_rules(NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + if (priv->routing_rules && priv->routing_rules->len > 0) { + g_ptr_array_set_size(priv->routing_rules, 0); + _routing_rules_notify(setting); + } +} + +static GVariant * +_routing_rules_dbus_only_synth(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + NMSettingIPConfig * self = NM_SETTING_IP_CONFIG(setting); + NMSettingIPConfigPrivate *priv; + GVariantBuilder builder; + gboolean any = FALSE; + guint i; + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(self); + + if (!priv->routing_rules || priv->routing_rules->len == 0) + return NULL; + + for (i = 0; i < priv->routing_rules->len; i++) { + GVariant *variant; + + variant = nm_ip_routing_rule_to_dbus(priv->routing_rules->pdata[i]); + if (!variant) + continue; + + if (!any) { + any = TRUE; + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + } + g_variant_builder_add(&builder, "@a{sv}", variant); + } + + return any ? g_variant_builder_end(&builder) : NULL; +} + +static gboolean +_routing_rules_dbus_only_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GVariantIter iter_rules; + GVariant * rule_var; + guint i_rule; + gboolean success = FALSE; + gboolean rules_changed = FALSE; + + nm_assert(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}"))); + + g_variant_iter_init(&iter_rules, value); + + i_rule = 0; + while (g_variant_iter_next(&iter_rules, "@a{sv}", &rule_var)) { + _nm_unused gs_unref_variant GVariant *rule_var_unref = rule_var; + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL; + gs_free_error GError *local = NULL; + + i_rule++; + + rule = + nm_ip_routing_rule_from_dbus(rule_var, + NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT), + &local); + if (!rule) { + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("rule #%u is invalid: %s"), + i_rule, + local->message); + goto out; + } + continue; + } + + nm_setting_ip_config_add_routing_rule(NM_SETTING_IP_CONFIG(setting), rule); + rules_changed = TRUE; + } + + success = TRUE; + +out: + if (rules_changed) + _routing_rules_notify(NM_SETTING_IP_CONFIG(setting)); + return success; +} + +/*****************************************************************************/ + +/** + * nm_setting_ip_config_get_ignore_auto_routes: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:ignore-auto-routes + * property. + * + * Returns: %TRUE if automatically configured (ie via DHCP) routes should be + * ignored. + **/ +gboolean +nm_setting_ip_config_get_ignore_auto_routes(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->ignore_auto_routes; +} + +/** + * nm_setting_ip_config_get_ignore_auto_dns: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:ignore-auto-dns + * property. + * + * Returns: %TRUE if automatically configured (ie via DHCP) DNS information + * should be ignored. + **/ +gboolean +nm_setting_ip_config_get_ignore_auto_dns(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->ignore_auto_dns; +} + +/** + * nm_setting_ip_config_get_dhcp_hostname: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:dhcp-hostname + * property. + * + * Returns: the configured hostname to send to the DHCP server + **/ +const char * +nm_setting_ip_config_get_dhcp_hostname(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_hostname; +} + +/** + * nm_setting_ip_config_get_dhcp_send_hostname: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:dhcp-send-hostname + * property. + * + * Returns: %TRUE if NetworkManager should send the machine hostname to the + * DHCP server when requesting addresses to allow the server to automatically + * update DNS information for this machine. + **/ +gboolean +nm_setting_ip_config_get_dhcp_send_hostname(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_send_hostname; +} + +/** + * nm_setting_ip_config_get_never_default: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:never-default + * property. + * + * Returns: %TRUE if this connection should never be the default + * connection + **/ +gboolean +nm_setting_ip_config_get_never_default(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->never_default; +} + +/** + * nm_setting_ip_config_get_may_fail: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:may-fail + * property. + * + * Returns: %TRUE if this connection doesn't require this type of IP + * addressing to complete for the connection to succeed. + **/ +gboolean +nm_setting_ip_config_get_may_fail(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->may_fail; +} + +/** + * nm_setting_ip_config_get_dad_timeout: + * @setting: the #NMSettingIPConfig + * + * Returns: the #NMSettingIPConfig:dad-timeout property. + * + * Since: 1.2 + **/ +int +nm_setting_ip_config_get_dad_timeout(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dad_timeout; +} + +/** + * nm_setting_ip_config_get_dhcp_hostname_flags: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:dhcp-hostname-flags + * property. + * + * Returns: flags for the DHCP hostname and FQDN + * + * Since: 1.22 + */ +NMDhcpHostnameFlags +nm_setting_ip_config_get_dhcp_hostname_flags(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NM_DHCP_HOSTNAME_FLAG_NONE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_hostname_flags; +} + +/** + * nm_setting_ip_config_get_dhcp_timeout: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:dhcp-timeout + * property. + * + * Returns: the configured DHCP timeout in seconds. 0 = default for + * the particular kind of device. + * + * Since: 1.2 + **/ +int +nm_setting_ip_config_get_dhcp_timeout(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_timeout; +} + +/** + * nm_setting_ip_config_get_dhcp_iaid: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:dhcp-iaid + * property. + * + * Returns: the configured DHCP IAID (Identity Association Identifier) + * + * Since: 1.22 + **/ +const char * +nm_setting_ip_config_get_dhcp_iaid(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_iaid; +} + +/** + * nm_setting_ip_config_get_dhcp_reject_servers: + * @setting: the #NMSettingIPConfig + * @out_len: (allow-none) (out): the number of returned elements + * + * Returns: (array length=out_len zero-terminated=1) (transfer none): + * A %NULL terminated array of DHCP reject servers. Even if no reject + * servers are configured, this always returns a non %NULL value. + * + * Since: 1.28 + */ +const char *const * +nm_setting_ip_config_get_dhcp_reject_servers(NMSettingIPConfig *setting, guint *out_len) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + return nm_strvarray_get_strv(&NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_reject_servers, + out_len); +} + +/** + * nm_setting_ip_config_add_dhcp_reject_server: + * @setting: the #NMSettingIPConfig + * @server: the DHCP reject server to add + * + * Adds a new DHCP reject server to the setting. + * + * Since: 1.28 + **/ +void +nm_setting_ip_config_add_dhcp_reject_server(NMSettingIPConfig *setting, const char *server) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + g_return_if_fail(server != NULL); + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + nm_strvarray_add(nm_strvarray_ensure(&priv->dhcp_reject_servers), server); + _notify(setting, PROP_DHCP_REJECT_SERVERS); +} + +/** + * nm_setting_ip_config_remove_dhcp_reject_server: + * @setting: the #NMSettingIPConfig + * @idx: index number of the DHCP reject server + * + * Removes the DHCP reject server at index @idx. + * + * Since: 1.28 + **/ +void +nm_setting_ip_config_remove_dhcp_reject_server(NMSettingIPConfig *setting, guint idx) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_if_fail(priv->dhcp_reject_servers && idx < priv->dhcp_reject_servers->len); + + g_array_remove_index(priv->dhcp_reject_servers, idx); + _notify(setting, PROP_DHCP_REJECT_SERVERS); +} + +/** + * nm_setting_ip_config_clear_dhcp_reject_servers: + * @setting: the #NMSettingIPConfig + * + * Removes all configured DHCP reject servers. + * + * Since: 1.28 + **/ +void +nm_setting_ip_config_clear_dhcp_reject_servers(NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + if (nm_g_array_len(priv->dhcp_reject_servers) != 0) { + nm_clear_pointer(&priv->dhcp_reject_servers, g_array_unref); + _notify(setting, PROP_DHCP_REJECT_SERVERS); + } +} + +static gboolean +verify_label(const char *label) +{ + const char *p; + char * iface; + + p = strchr(label, ':'); + if (!p) + return FALSE; + iface = g_strndup(label, p - label); + if (!nm_utils_ifname_valid_kernel(iface, NULL)) { + g_free(iface); + return FALSE; + } + g_free(iface); + + for (p++; *p; p++) { + if (!g_ascii_isalnum(*p) && *p != '_') + return FALSE; + } + + return TRUE; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + guint i; + + if (!priv->method) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), NM_SETTING_IP_CONFIG_METHOD); + return FALSE; + } + + if (priv->dhcp_hostname && !*priv->dhcp_hostname) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME); + return FALSE; + } + + /* Validate DNS */ + for (i = 0; i < priv->dns->len; i++) { + const char *dns = priv->dns->pdata[i]; + + if (!nm_utils_ipaddr_is_valid(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), dns)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. DNS server address is invalid"), + (int) (i + 1)); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_DNS); + return FALSE; + } + } + + /* Validate addresses */ + for (i = 0; i < priv->addresses->len; i++) { + NMIPAddress *addr = (NMIPAddress *) priv->addresses->pdata[i]; + GVariant * label; + + if (nm_ip_address_get_family(addr) != NM_SETTING_IP_CONFIG_GET_FAMILY(setting)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. IP address is invalid"), + (int) (i + 1)); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + if (label) { + if (!g_variant_is_of_type(label, G_VARIANT_TYPE_STRING)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. IP address has 'label' property with invalid type"), + (int) (i + 1)); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + if (!verify_label(g_variant_get_string(label, NULL))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. IP address has invalid label '%s'"), + (int) (i + 1), + g_variant_get_string(label, NULL)); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + } + } + + /* Validate gateway */ + if (priv->gateway) { + if (!priv->addresses->len) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("gateway cannot be set if there are no addresses configured")); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_GATEWAY); + return FALSE; + } + + if (!nm_utils_ipaddr_is_valid(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), priv->gateway)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("gateway is invalid")); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_GATEWAY); + return FALSE; + } + } + + /* Validate routes */ + for (i = 0; i < priv->routes->len; i++) { + gs_free_error GError *local = NULL; + NMIPRoute * route = (NMIPRoute *) priv->routes->pdata[i]; + + if (nm_ip_route_get_family(route) != NM_SETTING_IP_CONFIG_GET_FAMILY(setting)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. route is invalid"), + (int) (i + 1)); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_ROUTES); + return FALSE; + } + + if (!_nm_ip_route_attribute_validate_all(route, &local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid attribute: %s"), + local->message); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_ROUTES); + return FALSE; + } + } + + if (priv->routing_rules) { + for (i = 0; i < priv->routing_rules->len; i++) { + NMIPRoutingRule *rule = priv->routing_rules->pdata[i]; + gs_free_error GError *local = NULL; + + if (_ip_routing_rule_get_addr_family(rule) + != NM_SETTING_IP_CONFIG_GET_FAMILY(setting)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%u. rule has wrong address-family"), + i + 1); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_ROUTING_RULES); + return FALSE; + } + if (!nm_ip_routing_rule_validate(rule, &local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%u. rule is invalid: %s"), + i + 1, + local->message); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_ROUTES); + return FALSE; + } + } + } + + if (priv->dhcp_iaid && !_nm_utils_iaid_verify(priv->dhcp_iaid, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IAID"), + priv->dhcp_iaid); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_DHCP_IAID); + return FALSE; + } + + /* Validate DHCP hostname flags */ + if (priv->dhcp_hostname_flags != NM_DHCP_HOSTNAME_FLAG_NONE && !priv->dhcp_send_hostname) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the property cannot be set when '%s' is disabled"), + NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS); + return FALSE; + } + + if (!_nm_utils_validate_dhcp_hostname_flags(priv->dhcp_hostname_flags, + NM_SETTING_IP_CONFIG_GET_FAMILY(setting), + error)) { + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS); + return FALSE; + } + + /* Validate reject servers */ + if (priv->dhcp_reject_servers && priv->dhcp_reject_servers->len != 0) { + if (NM_SETTING_IP_CONFIG_GET_FAMILY(setting) != AF_INET) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the property is currently supported only for DHCPv4")); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_DHCP_REJECT_SERVERS); + return FALSE; + } + + for (i = 0; i < priv->dhcp_reject_servers->len; i++) { + if (!nm_utils_parse_inaddr_prefix( + NM_SETTING_IP_CONFIG_GET_FAMILY(setting), + g_array_index(priv->dhcp_reject_servers, const char *, i), + NULL, + NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IP or subnet"), + g_array_index(priv->dhcp_reject_servers, const char *, i)); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_DHCP_REJECT_SERVERS); + return FALSE; + } + } + } + + /* Normalizable errors */ + if (priv->gateway && priv->never_default) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a gateway is incompatible with '%s'"), + NM_SETTING_IP_CONFIG_NEVER_DEFAULT); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_GATEWAY); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingIPConfigPrivate *a_priv; + NMSettingIPConfigPrivate *b_priv; + guint i; + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_IP_CONFIG_ADDRESSES)) { + if (set_b) { + a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_a); + b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_b); + + if (a_priv->addresses->len != b_priv->addresses->len) + return FALSE; + for (i = 0; i < a_priv->addresses->len; i++) { + if (nm_ip_address_cmp_full(a_priv->addresses->pdata[i], + b_priv->addresses->pdata[i], + NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS) + != 0) + return FALSE; + } + } + return TRUE; + } + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_IP_CONFIG_ROUTES)) { + if (set_b) { + a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_a); + b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_b); + + if (a_priv->routes->len != b_priv->routes->len) + return FALSE; + for (i = 0; i < a_priv->routes->len; i++) { + if (!nm_ip_route_equal_full(a_priv->routes->pdata[i], + b_priv->routes->pdata[i], + NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS)) + return FALSE; + } + } + return TRUE; + } + + if (nm_streq(sett_info->property_infos[property_idx].name, + NM_SETTING_IP_CONFIG_ROUTING_RULES)) { + if (set_b) { + guint n; + + a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_a); + b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_b); + + n = (a_priv->routing_rules) ? a_priv->routing_rules->len : 0u; + if (n != (b_priv->routing_rules ? b_priv->routing_rules->len : 0u)) + return FALSE; + for (i = 0; i < n; i++) { + if (nm_ip_routing_rule_cmp(a_priv->routing_rules->pdata[i], + b_priv->routing_rules->pdata[i]) + != 0) + return FALSE; + } + } + return TRUE; + } + + return NM_SETTING_CLASS(nm_setting_ip_config_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +static void +duplicate_copy_properties(const NMSettInfoSetting *sett_info, NMSetting *src, NMSetting *dst) +{ + NMSettingIPConfigPrivate *priv_src = NM_SETTING_IP_CONFIG_GET_PRIVATE(src); + NMSettingIPConfigPrivate *priv_dst = NM_SETTING_IP_CONFIG_GET_PRIVATE(dst); + guint i; + gboolean changed = FALSE; + + NM_SETTING_CLASS(nm_setting_ip_config_parent_class) + ->duplicate_copy_properties(sett_info, src, dst); + + if (priv_dst->routing_rules && priv_dst->routing_rules->len > 0) { + changed = TRUE; + g_ptr_array_set_size(priv_dst->routing_rules, 0); + } + if (priv_src->routing_rules && priv_src->routing_rules->len > 0) { + changed = TRUE; + if (!priv_dst->routing_rules) + priv_dst->routing_rules = + g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_routing_rule_unref); + for (i = 0; i < priv_src->routing_rules->len; i++) { + g_ptr_array_add(priv_dst->routing_rules, + nm_ip_routing_rule_ref(priv_src->routing_rules->pdata[i])); + } + } + if (changed) + _routing_rules_notify(NM_SETTING_IP_CONFIG(dst)); +} + +static void +enumerate_values(const NMSettInfoProperty *property_info, + NMSetting * setting, + NMSettingValueIterFn func, + gpointer user_data) +{ + if (nm_streq(property_info->name, NM_SETTING_IP_CONFIG_ROUTING_RULES)) { + NMSettingIPConfigPrivate * priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + nm_auto_unset_gvalue GValue value = G_VALUE_INIT; + GPtrArray * ptr = NULL; + guint i; + + if (priv->routing_rules && priv->routing_rules->len > 0) { + ptr = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_routing_rule_unref); + for (i = 0; i < priv->routing_rules->len; i++) + g_ptr_array_add(ptr, nm_ip_routing_rule_ref(priv->routing_rules->pdata[i])); + } + g_value_init(&value, G_TYPE_PTR_ARRAY); + g_value_take_boxed(&value, ptr); + func(setting, property_info->name, &value, 0, user_data); + return; + } + + NM_SETTING_CLASS(nm_setting_ip_config_parent_class) + ->enumerate_values(property_info, setting, func, user_data); +} + +/*****************************************************************************/ + +static gboolean +ip_gateway_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + /* FIXME: properly handle errors */ + + /* Don't set from 'gateway' if we're going to use the gateway in 'addresses' */ + if (_nm_setting_use_legacy_property(setting, connection_dict, "addresses", "gateway")) + return TRUE; + + g_object_set(setting, property, g_variant_get_string(value, NULL), NULL); + return TRUE; +} + +GArray * +_nm_sett_info_property_override_create_array_ip_config(void) +{ + GArray *properties_override = _nm_sett_info_property_override_create_array(); + + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_GATEWAY], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING, + .from_dbus_fcn = ip_gateway_set, )); + + /* ---dbus--- + * property: routing-rules + * format: array of 'a{sv}' + * description: Array of dictionaries for routing rules. + * ---end--- + */ + _nm_properties_override_dbus( + properties_override, + NM_SETTING_IP_CONFIG_ROUTING_RULES, + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = _routing_rules_dbus_only_synth, + .from_dbus_fcn = _routing_rules_dbus_only_set, )); + + return properties_override; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingIPConfig * setting = NM_SETTING_IP_CONFIG(object); + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_METHOD: + g_value_set_string(value, nm_setting_ip_config_get_method(setting)); + break; + case PROP_DNS: + g_value_take_boxed(value, _nm_utils_ptrarray_to_strv(priv->dns)); + break; + case PROP_DNS_SEARCH: + g_value_take_boxed(value, _nm_utils_ptrarray_to_strv(priv->dns_search)); + break; + case PROP_DNS_OPTIONS: + g_value_take_boxed(value, + priv->dns_options ? _nm_utils_ptrarray_to_strv(priv->dns_options) + : NULL); + break; + case PROP_DNS_PRIORITY: + g_value_set_int(value, priv->dns_priority); + break; + case PROP_ADDRESSES: + g_value_take_boxed(value, + _nm_utils_copy_array(priv->addresses, + (NMUtilsCopyFunc) nm_ip_address_dup, + (GDestroyNotify) nm_ip_address_unref)); + break; + case PROP_GATEWAY: + g_value_set_string(value, nm_setting_ip_config_get_gateway(setting)); + break; + case PROP_ROUTES: + g_value_take_boxed(value, + _nm_utils_copy_array(priv->routes, + (NMUtilsCopyFunc) nm_ip_route_dup, + (GDestroyNotify) nm_ip_route_unref)); + break; + case PROP_ROUTE_METRIC: + g_value_set_int64(value, priv->route_metric); + break; + case PROP_ROUTE_TABLE: + g_value_set_uint(value, priv->route_table); + break; + case PROP_IGNORE_AUTO_ROUTES: + g_value_set_boolean(value, nm_setting_ip_config_get_ignore_auto_routes(setting)); + break; + case PROP_IGNORE_AUTO_DNS: + g_value_set_boolean(value, nm_setting_ip_config_get_ignore_auto_dns(setting)); + break; + case PROP_DHCP_HOSTNAME: + g_value_set_string(value, nm_setting_ip_config_get_dhcp_hostname(setting)); + break; + case PROP_DHCP_SEND_HOSTNAME: + g_value_set_boolean(value, nm_setting_ip_config_get_dhcp_send_hostname(setting)); + break; + case PROP_NEVER_DEFAULT: + g_value_set_boolean(value, priv->never_default); + break; + case PROP_MAY_FAIL: + g_value_set_boolean(value, priv->may_fail); + break; + case PROP_DAD_TIMEOUT: + g_value_set_int(value, nm_setting_ip_config_get_dad_timeout(setting)); + break; + case PROP_DHCP_TIMEOUT: + g_value_set_int(value, nm_setting_ip_config_get_dhcp_timeout(setting)); + break; + case PROP_DHCP_IAID: + g_value_set_string(value, nm_setting_ip_config_get_dhcp_iaid(setting)); + break; + case PROP_DHCP_HOSTNAME_FLAGS: + g_value_set_uint(value, nm_setting_ip_config_get_dhcp_hostname_flags(setting)); + break; + case PROP_DHCP_REJECT_SERVERS: + g_value_set_boxed(value, nm_strvarray_get_strv_non_empty(priv->dhcp_reject_servers, NULL)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingIPConfig * setting = NM_SETTING_IP_CONFIG(object); + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + const char * gateway; + char ** strv; + guint i; + + switch (prop_id) { + case PROP_METHOD: + g_free(priv->method); + priv->method = g_value_dup_string(value); + break; + case PROP_DNS: + g_ptr_array_unref(priv->dns); + priv->dns = _nm_utils_strv_to_ptrarray(g_value_get_boxed(value)); + break; + case PROP_DNS_SEARCH: + g_ptr_array_unref(priv->dns_search); + priv->dns_search = _nm_utils_strv_to_ptrarray(g_value_get_boxed(value)); + break; + case PROP_DNS_OPTIONS: + strv = g_value_get_boxed(value); + if (!strv) { + if (priv->dns_options) { + g_ptr_array_unref(priv->dns_options); + priv->dns_options = NULL; + } + } else { + if (priv->dns_options) + g_ptr_array_set_size(priv->dns_options, 0); + else + priv->dns_options = g_ptr_array_new_with_free_func(g_free); + for (i = 0; strv[i]; i++) { + if (_nm_utils_dns_option_validate(strv[i], NULL, NULL, FALSE, NULL) + && _nm_utils_dns_option_find_idx(priv->dns_options, strv[i]) < 0) + g_ptr_array_add(priv->dns_options, g_strdup(strv[i])); + } + } + break; + case PROP_DNS_PRIORITY: + priv->dns_priority = g_value_get_int(value); + break; + case PROP_ADDRESSES: + g_ptr_array_unref(priv->addresses); + priv->addresses = _nm_utils_copy_array(g_value_get_boxed(value), + (NMUtilsCopyFunc) nm_ip_address_dup, + (GDestroyNotify) nm_ip_address_unref); + break; + case PROP_GATEWAY: + gateway = g_value_get_string(value); + g_return_if_fail( + !gateway + || nm_utils_ipaddr_is_valid(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), gateway)); + g_free(priv->gateway); + priv->gateway = canonicalize_ip(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), gateway, TRUE); + break; + case PROP_ROUTES: + g_ptr_array_unref(priv->routes); + priv->routes = _nm_utils_copy_array(g_value_get_boxed(value), + (NMUtilsCopyFunc) nm_ip_route_dup, + (GDestroyNotify) nm_ip_route_unref); + break; + case PROP_ROUTE_METRIC: + priv->route_metric = g_value_get_int64(value); + break; + case PROP_ROUTE_TABLE: + priv->route_table = g_value_get_uint(value); + break; + case PROP_IGNORE_AUTO_ROUTES: + priv->ignore_auto_routes = g_value_get_boolean(value); + break; + case PROP_IGNORE_AUTO_DNS: + priv->ignore_auto_dns = g_value_get_boolean(value); + break; + case PROP_DHCP_HOSTNAME: + g_free(priv->dhcp_hostname); + priv->dhcp_hostname = g_value_dup_string(value); + break; + case PROP_DHCP_SEND_HOSTNAME: + priv->dhcp_send_hostname = g_value_get_boolean(value); + break; + case PROP_NEVER_DEFAULT: + priv->never_default = g_value_get_boolean(value); + break; + case PROP_MAY_FAIL: + priv->may_fail = g_value_get_boolean(value); + break; + case PROP_DAD_TIMEOUT: + priv->dad_timeout = g_value_get_int(value); + break; + case PROP_DHCP_TIMEOUT: + priv->dhcp_timeout = g_value_get_int(value); + break; + case PROP_DHCP_IAID: + priv->dhcp_iaid = g_value_dup_string(value); + break; + case PROP_DHCP_HOSTNAME_FLAGS: + priv->dhcp_hostname_flags = g_value_get_uint(value); + break; + case PROP_DHCP_REJECT_SERVERS: + nm_strvarray_set_strv(&priv->dhcp_reject_servers, g_value_get_boxed(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ip_config_init(NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + + priv->dns = g_ptr_array_new_with_free_func(g_free); + priv->dns_search = g_ptr_array_new_with_free_func(g_free); + priv->addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + priv->routes = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); + priv->route_metric = -1; + priv->dhcp_send_hostname = TRUE; + priv->may_fail = TRUE; + priv->dad_timeout = -1; +} + +static void +finalize(GObject *object) +{ + NMSettingIPConfig * self = NM_SETTING_IP_CONFIG(object); + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(self); + + g_free(priv->method); + g_free(priv->gateway); + g_free(priv->dhcp_hostname); + g_free(priv->dhcp_iaid); + + g_ptr_array_unref(priv->dns); + g_ptr_array_unref(priv->dns_search); + if (priv->dns_options) + g_ptr_array_unref(priv->dns_options); + g_ptr_array_unref(priv->addresses); + g_ptr_array_unref(priv->routes); + if (priv->routing_rules) + g_ptr_array_unref(priv->routing_rules); + nm_clear_pointer(&priv->dhcp_reject_servers, g_array_unref); + + G_OBJECT_CLASS(nm_setting_ip_config_parent_class)->finalize(object); +} + +static void +nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingIPConfigPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->compare_property = compare_property; + setting_class->duplicate_copy_properties = duplicate_copy_properties; + setting_class->enumerate_values = enumerate_values; + + /** + * NMSettingIPConfig:method: + * + * IP configuration method. + * + * #NMSettingIP4Config and #NMSettingIP6Config both support "disabled", + * "auto", "manual", and "link-local". See the subclass-specific + * documentation for other values. + * + * In general, for the "auto" method, properties such as + * #NMSettingIPConfig:dns and #NMSettingIPConfig:routes specify information + * that is added on to the information returned from automatic + * configuration. The #NMSettingIPConfig:ignore-auto-routes and + * #NMSettingIPConfig:ignore-auto-dns properties modify this behavior. + * + * For methods that imply no upstream network, such as "shared" or + * "link-local", these properties must be empty. + * + * For IPv4 method "shared", the IP subnet can be configured by adding one + * manual IPv4 address or otherwise 10.42.x.0/24 is chosen. Note that the + * shared method must be configured on the interface which shares the internet + * to a subnet, not on the uplink which is shared. + **/ + obj_properties[PROP_METHOD] = g_param_spec_string( + NM_SETTING_IP_CONFIG_METHOD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dns: + * + * Array of IP addresses of DNS servers. + **/ + obj_properties[PROP_DNS] = g_param_spec_boxed(NM_SETTING_IP_CONFIG_DNS, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dns-search: + * + * Array of DNS search domains. Domains starting with a tilde ('~') + * are considered 'routing' domains and are used only to decide the + * interface over which a query must be forwarded; they are not used + * to complete unqualified host names. + * + * When using a DNS plugin that supports Conditional Forwarding or + * Split DNS, then the search domains specify which name servers to + * query. This makes the behavior different from running with plain + * /etc/resolv.conf. For more information see also the dns-priority setting. + **/ + obj_properties[PROP_DNS_SEARCH] = + g_param_spec_boxed(NM_SETTING_IP_CONFIG_DNS_SEARCH, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dns-options: + * + * Array of DNS options as described in man 5 resolv.conf. + * + * %NULL means that the options are unset and left at the default. + * In this case NetworkManager will use default options. This is + * distinct from an empty list of properties. + * + * The currently supported options are "attempts", "debug", "edns0", + * "inet6", "ip6-bytestring", "ip6-dotint", "ndots", "no-check-names", + * "no-ip6-dotint", "no-reload", "no-tld-query", "rotate", "single-request", + * "single-request-reopen", "timeout", "trust-ad", "use-vc". + * + * The "trust-ad" setting is only honored if the profile contributes + * name servers to resolv.conf, and if all contributing profiles have + * "trust-ad" enabled. + * + * When using a caching DNS plugin (dnsmasq or systemd-resolved in + * NetworkManager.conf) then "edns0" and "trust-ad" are automatically + * added. + * + * Since: 1.2 + **/ + obj_properties[PROP_DNS_OPTIONS] = + g_param_spec_boxed(NM_SETTING_IP_CONFIG_DNS_OPTIONS, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dns-priority: + * + * DNS servers priority. + * + * The relative priority for DNS servers specified by this setting. A lower + * numerical value is better (higher priority). + * + * Negative values have the special effect of excluding other configurations + * with a greater numerical priority value; so in presence of at least one negative + * priority, only DNS servers from connections with the lowest priority value will be used. + * To avoid all DNS leaks, set the priority of the profile that should be used + * to the most negative value of all active connections profiles. + * + * Zero selects a globally configured default value. If the latter is missing + * or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for + * other connections. + * + * Note that the priority is to order DNS settings for multiple active + * connections. It does not disambiguate multiple DNS servers within the + * same connection profile. + * + * When multiple devices have configurations with the same priority, VPNs will be + * considered first, then devices with the best (lowest metric) default + * route and then all other devices. + * + * When using dns=default, servers with higher priority will be on top of + * resolv.conf. To prioritize a given server over another one within the + * same connection, just specify them in the desired order. + * Note that commonly the resolver tries name servers in /etc/resolv.conf + * in the order listed, proceeding with the next server in the list + * on failure. See for example the "rotate" option of the dns-options setting. + * If there are any negative DNS priorities, then only name servers from + * the devices with that lowest priority will be considered. + * + * When using a DNS resolver that supports Conditional Forwarding or + * Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection + * is used to query domains in its search list. The search domains determine which + * name servers to ask, and the DNS priority is used to prioritize + * name servers based on the domain. Queries for domains not present in any + * search list are routed through connections having the '~.' special wildcard + * domain, which is added automatically to connections with the default route + * (or can be added manually). When multiple connections specify the same domain, the + * one with the best priority (lowest numerical value) wins. If a sub domain + * is configured on another interface it will be accepted regardless the priority, + * unless parent domain on the other interface has a negative priority, which causes + * the sub domain to be shadowed. + * With Split DNS one can avoid undesired DNS leaks by properly configuring + * DNS priorities and the search domains, so that only name servers of the desired + * interface are configured. + * + * Since: 1.4 + **/ + obj_properties[PROP_DNS_PRIORITY] = + g_param_spec_int(NM_SETTING_IP_CONFIG_DNS_PRIORITY, + "", + "", + G_MININT32, + G_MAXINT32, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:addresses: (type GPtrArray(NMIPAddress)) + * + * Array of IP addresses. + **/ + obj_properties[PROP_ADDRESSES] = + g_param_spec_boxed(NM_SETTING_IP_CONFIG_ADDRESSES, + "", + "", + G_TYPE_PTR_ARRAY, + /* "addresses" is a legacy D-Bus property, because the + * "addresses" GObject property normally gets set from + * the "address-data" D-Bus property... + */ + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | NM_SETTING_PARAM_LEGACY + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:gateway: + * + * The gateway associated with this configuration. This is only meaningful + * if #NMSettingIPConfig:addresses is also set. + * + * The gateway's main purpose is to control the next hop of the standard default route on the device. + * Hence, the gateway property conflicts with #NMSettingIPConfig:never-default and will be + * automatically dropped if the IP configuration is set to never-default. + * + * As an alternative to set the gateway, configure a static default route with /0 as prefix + * length. + **/ + obj_properties[PROP_GATEWAY] = g_param_spec_string( + NM_SETTING_IP_CONFIG_GATEWAY, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:routes: (type GPtrArray(NMIPRoute)) + * + * Array of IP routes. + **/ + obj_properties[PROP_ROUTES] = + g_param_spec_boxed(NM_SETTING_IP_CONFIG_ROUTES, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | + /* See :addresses above Re: LEGACY */ + NM_SETTING_PARAM_LEGACY | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:route-metric: + * + * The default metric for routes that don't explicitly specify a metric. + * The default value -1 means that the metric is chosen automatically + * based on the device type. + * The metric applies to dynamic routes, manual (static) routes that + * don't have an explicit metric setting, address prefix routes, and + * the default route. + * Note that for IPv6, the kernel accepts zero (0) but coerces it to + * 1024 (user default). Hence, setting this property to zero effectively + * mean setting it to 1024. + * For IPv4, zero is a regular value for the metric. + **/ + obj_properties[PROP_ROUTE_METRIC] = + g_param_spec_int64(NM_SETTING_IP_CONFIG_ROUTE_METRIC, + "", + "", + -1, + G_MAXUINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:route-table: + * + * Enable policy routing (source routing) and set the routing table used when adding routes. + * + * This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes + * and static routes. But note that static routes can individually overwrite the setting + * by explicitly specifying a non-zero routing table. + * + * If the table setting is left at zero, it is eligible to be overwritten via global + * configuration. If the property is zero even after applying the global configuration + * value, policy routing is disabled for the address family of this connection. + * + * Policy routing disabled means that NetworkManager will add all routes to the main + * table (except static routes that explicitly configure a different table). Additionally, + * NetworkManager will not delete any extraneous routes from tables except the main table. + * This is to preserve backward compatibility for users who manage routing tables outside + * of NetworkManager. + * + * Since: 1.10 + **/ + obj_properties[PROP_ROUTE_TABLE] = g_param_spec_uint( + NM_SETTING_IP_CONFIG_ROUTE_TABLE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + /** + * NMSettingIPConfig:ignore-auto-routes: + * + * When #NMSettingIPConfig:method is set to "auto" and this property to + * %TRUE, automatically configured routes are ignored and only routes + * specified in the #NMSettingIPConfig:routes property, if any, are used. + **/ + obj_properties[PROP_IGNORE_AUTO_ROUTES] = + g_param_spec_boolean(NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:ignore-auto-dns: + * + * When #NMSettingIPConfig:method is set to "auto" and this property to + * %TRUE, automatically configured name servers and search domains are + * ignored and only name servers and search domains specified in the + * #NMSettingIPConfig:dns and #NMSettingIPConfig:dns-search properties, if + * any, are used. + **/ + obj_properties[PROP_IGNORE_AUTO_DNS] = + g_param_spec_boolean(NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dhcp-hostname: + * + * If the #NMSettingIPConfig:dhcp-send-hostname property is %TRUE, then the + * specified name will be sent to the DHCP server when acquiring a lease. + * This property and #NMSettingIP4Config:dhcp-fqdn are mutually exclusive and + * cannot be set at the same time. + **/ + obj_properties[PROP_DHCP_HOSTNAME] = + g_param_spec_string(NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dhcp-send-hostname: + * + * If %TRUE, a hostname is sent to the DHCP server when acquiring a lease. + * Some DHCP servers use this hostname to update DNS databases, essentially + * providing a static hostname for the computer. If the + * #NMSettingIPConfig:dhcp-hostname property is %NULL and this property is + * %TRUE, the current persistent hostname of the computer is sent. + **/ + obj_properties[PROP_DHCP_SEND_HOSTNAME] = + g_param_spec_boolean(NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, + "", + "", + TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:never-default: + * + * If %TRUE, this connection will never be the default connection for this + * IP type, meaning it will never be assigned the default route by + * NetworkManager. + **/ + obj_properties[PROP_NEVER_DEFAULT] = + g_param_spec_boolean(NM_SETTING_IP_CONFIG_NEVER_DEFAULT, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:may-fail: + * + * If %TRUE, allow overall network configuration to proceed even if the + * configuration specified by this property times out. Note that at least + * one IP configuration must succeed or overall network configuration will + * still fail. For example, in IPv6-only networks, setting this property to + * %TRUE on the #NMSettingIP4Config allows the overall network configuration + * to succeed if IPv4 configuration fails but IPv6 configuration completes + * successfully. + **/ + obj_properties[PROP_MAY_FAIL] = + g_param_spec_boolean(NM_SETTING_IP_CONFIG_MAY_FAIL, + "", + "", + TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dad-timeout: + * + * Timeout in milliseconds used to check for the presence of duplicate IP + * addresses on the network. If an address conflict is detected, the + * activation will fail. A zero value means that no duplicate address + * detection is performed, -1 means the default value (either configuration + * ipvx.dad-timeout override or zero). A value greater than zero is a + * timeout in milliseconds. + * + * The property is currently implemented only for IPv4. + * + * Since: 1.2 + **/ + obj_properties[PROP_DAD_TIMEOUT] = g_param_spec_int( + NM_SETTING_IP_CONFIG_DAD_TIMEOUT, + "", + "", + -1, + NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, + -1, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dhcp-timeout: + * + * A timeout for a DHCP transaction in seconds. If zero (the default), a + * globally configured default is used. If still unspecified, a device specific + * timeout is used (usually 45 seconds). + * + * Set to 2147483647 (MAXINT32) for infinity. + **/ + obj_properties[PROP_DHCP_TIMEOUT] = g_param_spec_int( + NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, + "", + "", + 0, + G_MAXINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dhcp-iaid: + * + * A string containing the "Identity Association Identifier" (IAID) used + * by the DHCP client. The property is a 32-bit decimal value or a + * special value among "mac", "perm-mac", "ifname" and "stable". When + * set to "mac" (or "perm-mac"), the last 4 bytes of the current (or + * permanent) MAC address are used as IAID. When set to "ifname", the + * IAID is computed by hashing the interface name. The special value + * "stable" can be used to generate an IAID based on the stable-id (see + * connection.stable-id), a per-host key and the interface name. When + * the property is unset, the value from global configuration is used; + * if no global default is set then the IAID is assumed to be + * "ifname". Note that at the moment this property is ignored for IPv6 + * by dhclient, which always derives the IAID from the MAC address. + * + * Since: 1.22 + **/ + obj_properties[PROP_DHCP_IAID] = + g_param_spec_string(NM_SETTING_IP_CONFIG_DHCP_IAID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dhcp-hostname-flags: + * + * Flags for the DHCP hostname and FQDN. + * + * Currently, this property only includes flags to control the FQDN flags + * set in the DHCP FQDN option. Supported FQDN flags are + * %NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE, + * %NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED and + * %NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE. When no FQDN flag is set and + * %NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS is set, the DHCP FQDN option will + * contain no flag. Otherwise, if no FQDN flag is set and + * %NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS is not set, the standard FQDN flags + * are set in the request: + * %NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE, + * %NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED for IPv4 and + * %NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE for IPv6. + * + * When this property is set to the default value %NM_DHCP_HOSTNAME_FLAG_NONE, + * a global default is looked up in NetworkManager configuration. If that value + * is unset or also %NM_DHCP_HOSTNAME_FLAG_NONE, then the standard FQDN flags + * described above are sent in the DHCP requests. + * + * Since: 1.22 + */ + obj_properties[PROP_DHCP_HOSTNAME_FLAGS] = + g_param_spec_uint(NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, + "", + "", + 0, + G_MAXUINT32, + NM_DHCP_HOSTNAME_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dhcp-reject-servers: + * + * Array of servers from which DHCP offers must be rejected. This property + * is useful to avoid getting a lease from misconfigured or rogue servers. + * + * For DHCPv4, each element must be an IPv4 address, optionally + * followed by a slash and a prefix length (e.g. "192.168.122.0/24"). + * + * This property is currently not implemented for DHCPv6. + * + * Since: 1.28 + **/ + obj_properties[PROP_DHCP_REJECT_SERVERS] = + g_param_spec_boxed(NM_SETTING_IP_CONFIG_DHCP_REJECT_SERVERS, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} diff --git a/src/libnm-core-impl/nm-setting-ip-tunnel.c b/src/libnm-core-impl/nm-setting-ip-tunnel.c new file mode 100644 index 0000000..5cdcdc8 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ip-tunnel.c @@ -0,0 +1,867 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ip-tunnel.h" + +#include "nm-setting-private.h" +#include "nm-utils.h" + +/** + * SECTION:nm-setting-ip-tunnel + * @short_description: Describes connection properties for IP tunnel devices + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, + PROP_MODE, + PROP_LOCAL, + PROP_REMOTE, + PROP_TTL, + PROP_TOS, + PROP_PATH_MTU_DISCOVERY, + PROP_INPUT_KEY, + PROP_OUTPUT_KEY, + PROP_ENCAPSULATION_LIMIT, + PROP_FLOW_LABEL, + PROP_MTU, + PROP_FLAGS, ); + +typedef struct { + char * parent; + char * local; + char * remote; + char * input_key; + char * output_key; + guint ttl; + guint tos; + guint encapsulation_limit; + guint flow_label; + NMIPTunnelMode mode; + guint32 mtu; + guint32 flags; + bool path_mtu_discovery : 1; +} NMSettingIPTunnelPrivate; + +G_DEFINE_TYPE(NMSettingIPTunnel, nm_setting_ip_tunnel, NM_TYPE_SETTING) + +#define NM_SETTING_IP_TUNNEL_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnelPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_ip_tunnel_get_parent: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:parent property of the setting + * + * Returns: the parent device + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_tunnel_get_parent(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NULL); + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->parent; +} + +/** + * nm_setting_ip_tunnel_get_mode: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:mode property of the setting. + * + * Returns: the tunnel mode + * + * Since: 1.2 + **/ +NMIPTunnelMode +nm_setting_ip_tunnel_get_mode(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->mode; +} + +/** + * nm_setting_ip_tunnel_get_local: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:local property of the setting. + * + * Returns: the local endpoint + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_tunnel_get_local(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NULL); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->local; +} + +/** + * nm_setting_ip_tunnel_get_remote: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:remote property of the setting. + * + * Returns: the remote endpoint + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_tunnel_get_remote(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NULL); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->remote; +} + +/** + * nm_setting_ip_tunnel_get_ttl: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:ttl property of the setting. + * + * Returns: the Time-to-live value + * + * Since: 1.2 + **/ + +guint +nm_setting_ip_tunnel_get_ttl(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->ttl; +} + +/** + * nm_setting_ip_tunnel_get_tos: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:tos property of the setting. + * + * Returns: the TOS value + * + * Since: 1.2 + **/ +guint +nm_setting_ip_tunnel_get_tos(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->tos; +} + +/** + * nm_setting_ip_tunnel_get_path_mtu_discovery: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:path-mtu-discovery property of the setting. + * + * Returns: whether path MTU discovery is enabled + * + * Since: 1.2 + **/ +gboolean +nm_setting_ip_tunnel_get_path_mtu_discovery(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), TRUE); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->path_mtu_discovery; +} + +/** + * nm_setting_ip_tunnel_get_input_key: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:input-key property of the setting. + * + * Returns: the input key + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_tunnel_get_input_key(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NULL); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->input_key; +} + +/** + * nm_setting_ip_tunnel_get_output_key: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:output-key property of the setting. + * + * Returns: the output key + * + * Since: 1.2 + **/ +const char * +nm_setting_ip_tunnel_get_output_key(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NULL); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->output_key; +} + +/** + * nm_setting_ip_tunnel_get_encapsulation_limit: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:encapsulation-limit property of the setting. + * + * Returns: the encapsulation limit value + * + * Since: 1.2 + **/ +guint +nm_setting_ip_tunnel_get_encapsulation_limit(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->encapsulation_limit; +} + +/** + * nm_setting_ip_tunnel_get_flow_label: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:flow-label property of the setting. + * + * Returns: the flow label value + * + * Since: 1.2 + **/ +guint +nm_setting_ip_tunnel_get_flow_label(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->flow_label; +} + +/** + * nm_setting_ip_tunnel_get_mtu: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:mtu property of the setting. + * + * Returns: the MTU + * + * Since: 1.2 + **/ +guint +nm_setting_ip_tunnel_get_mtu(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->mtu; +} + +/* + * nm_setting_ip_tunnel_get_flags: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:flags property of the setting. + * + * Returns: the tunnel flags + * + * Since: 1.12 + **/ +NMIPTunnelFlags +nm_setting_ip_tunnel_get_flags(NMSettingIPTunnel *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NM_IP_TUNNEL_FLAG_NONE); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->flags; +} + +/*****************************************************************************/ + +gboolean +_nm_ip_tunnel_mode_is_layer2(NMIPTunnelMode mode) +{ + return NM_IN_SET(mode, NM_IP_TUNNEL_MODE_GRETAP, NM_IP_TUNNEL_MODE_IP6GRETAP); +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting); + int family = AF_UNSPEC; + guint32 flags; + + switch (priv->mode) { + case NM_IP_TUNNEL_MODE_IPIP: + case NM_IP_TUNNEL_MODE_SIT: + case NM_IP_TUNNEL_MODE_ISATAP: + case NM_IP_TUNNEL_MODE_GRE: + case NM_IP_TUNNEL_MODE_VTI: + case NM_IP_TUNNEL_MODE_GRETAP: + family = AF_INET; + break; + case NM_IP_TUNNEL_MODE_IP6IP6: + case NM_IP_TUNNEL_MODE_IPIP6: + case NM_IP_TUNNEL_MODE_IP6GRE: + case NM_IP_TUNNEL_MODE_VTI6: + case NM_IP_TUNNEL_MODE_IP6GRETAP: + family = AF_INET6; + break; + case NM_IP_TUNNEL_MODE_UNKNOWN: + break; + } + + if (family == AF_UNSPEC) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' is not a valid tunnel mode"), + (int) priv->mode); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_MODE); + return FALSE; + } + + if (priv->parent && !nm_utils_ifname_valid_kernel(priv->parent, NULL) + && !nm_utils_is_uuid(priv->parent)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_PARENT); + return FALSE; + } + + if (priv->local && !nm_utils_ipaddr_is_valid(family, priv->local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IPv%c address"), + priv->local, + family == AF_INET ? '4' : '6'); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_LOCAL); + return FALSE; + } + + if (!priv->remote) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_REMOTE); + return FALSE; + } + + if (!nm_utils_ipaddr_is_valid(family, priv->remote)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IPv%c address"), + priv->remote, + family == AF_INET ? '4' : '6'); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_REMOTE); + return FALSE; + } + + if ((priv->input_key && priv->input_key[0]) || (priv->output_key && priv->output_key[0])) { + if (!NM_IN_SET(priv->mode, + NM_IP_TUNNEL_MODE_GRE, + NM_IP_TUNNEL_MODE_GRETAP, + NM_IP_TUNNEL_MODE_IP6GRE, + NM_IP_TUNNEL_MODE_IP6GRETAP)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("tunnel keys can only be specified for GRE tunnels")); + return FALSE; + } + } + + if (priv->input_key && priv->input_key[0]) { + gint64 val; + + val = _nm_utils_ascii_str_to_int64(priv->input_key, 10, 0, G_MAXUINT32, -1); + if (val == -1) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid tunnel key"), + priv->input_key); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_INPUT_KEY); + return FALSE; + } + } + + if (priv->output_key && priv->output_key[0]) { + gint64 val; + + val = _nm_utils_ascii_str_to_int64(priv->output_key, 10, 0, G_MAXUINT32, -1); + if (val == -1) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid tunnel key"), + priv->output_key); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_OUTPUT_KEY); + return FALSE; + } + } + + if (!priv->path_mtu_discovery && priv->ttl != 0) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a fixed TTL is allowed only when path MTU discovery is enabled")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_TTL); + return FALSE; + } + + flags = priv->flags; + if (NM_IN_SET(priv->mode, NM_IP_TUNNEL_MODE_IPIP6, NM_IP_TUNNEL_MODE_IP6IP6)) + flags &= (guint32)(~_NM_IP_TUNNEL_FLAG_ALL_IP6TNL); + if (flags) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("some flags are invalid for the select mode: %s"), + nm_utils_enum_to_str(nm_ip_tunnel_flags_get_type(), flags)); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_FLAGS); + return FALSE; + } + + if (nm_connection_get_setting_wired(connection) && !_nm_ip_tunnel_mode_is_layer2(priv->mode)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("wired setting not allowed for mode %s"), + nm_utils_enum_to_str(nm_ip_tunnel_mode_get_type(), priv->mode)); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IP_TUNNEL_MODE); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingIPTunnel * setting = NM_SETTING_IP_TUNNEL(object); + NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string(value, priv->parent); + break; + case PROP_MODE: + g_value_set_uint(value, priv->mode); + break; + case PROP_LOCAL: + g_value_set_string(value, priv->local); + break; + case PROP_REMOTE: + g_value_set_string(value, priv->remote); + break; + case PROP_TTL: + g_value_set_uint(value, priv->ttl); + break; + case PROP_TOS: + g_value_set_uint(value, priv->tos); + break; + case PROP_PATH_MTU_DISCOVERY: + g_value_set_boolean(value, priv->path_mtu_discovery); + break; + case PROP_INPUT_KEY: + g_value_set_string(value, priv->input_key); + break; + case PROP_OUTPUT_KEY: + g_value_set_string(value, priv->output_key); + break; + case PROP_ENCAPSULATION_LIMIT: + g_value_set_uint(value, priv->encapsulation_limit); + break; + case PROP_FLOW_LABEL: + g_value_set_uint(value, priv->flow_label); + break; + case PROP_MTU: + g_value_set_uint(value, priv->mtu); + break; + case PROP_FLAGS: + g_value_set_uint(value, priv->flags); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingIPTunnel * setting = NM_SETTING_IP_TUNNEL(object); + NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_free(priv->parent); + priv->parent = g_value_dup_string(value); + break; + case PROP_MODE: + priv->mode = g_value_get_uint(value); + break; + case PROP_LOCAL: + g_free(priv->local); + priv->local = g_value_dup_string(value); + break; + case PROP_REMOTE: + g_free(priv->remote); + priv->remote = g_value_dup_string(value); + break; + case PROP_TTL: + priv->ttl = g_value_get_uint(value); + break; + case PROP_TOS: + priv->tos = g_value_get_uint(value); + break; + case PROP_PATH_MTU_DISCOVERY: + priv->path_mtu_discovery = g_value_get_boolean(value); + break; + case PROP_INPUT_KEY: + g_free(priv->input_key); + priv->input_key = g_value_dup_string(value); + break; + case PROP_OUTPUT_KEY: + g_free(priv->output_key); + priv->output_key = g_value_dup_string(value); + break; + case PROP_ENCAPSULATION_LIMIT: + priv->encapsulation_limit = g_value_get_uint(value); + break; + case PROP_FLOW_LABEL: + priv->flow_label = g_value_get_uint(value); + break; + case PROP_MTU: + priv->mtu = g_value_get_uint(value); + break; + case PROP_FLAGS: + priv->flags = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ip_tunnel_init(NMSettingIPTunnel *self) +{ + NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE(self); + + priv->path_mtu_discovery = TRUE; +} + +/** + * nm_setting_ip_tunnel_new: + * + * Creates a new #NMSettingIPTunnel object with default values. + * + * Returns: (transfer full): the new empty #NMSettingIPTunnel object + * + * Since: 1.2 + **/ +NMSetting * +nm_setting_ip_tunnel_new(void) +{ + return g_object_new(NM_TYPE_SETTING_IP_TUNNEL, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingIPTunnel * setting = NM_SETTING_IP_TUNNEL(object); + NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting); + + g_free(priv->parent); + g_free(priv->local); + g_free(priv->remote); + g_free(priv->input_key); + g_free(priv->output_key); + + G_OBJECT_CLASS(nm_setting_ip_tunnel_parent_class)->finalize(object); +} + +static void +nm_setting_ip_tunnel_class_init(NMSettingIPTunnelClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingIPTunnelPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingIPTunnel:parent: + * + * If given, specifies the parent interface name or parent connection UUID + * the new device will be bound to so that tunneled packets will only be + * routed via that interface. + * + * Since: 1.2 + **/ + obj_properties[PROP_PARENT] = g_param_spec_string( + NM_SETTING_IP_TUNNEL_PARENT, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:mode: + * + * The tunneling mode, for example %NM_IP_TUNNEL_MODE_IPIP or + * %NM_IP_TUNNEL_MODE_GRE. + * + * Since: 1.2 + **/ + obj_properties[PROP_MODE] = + g_param_spec_uint(NM_SETTING_IP_TUNNEL_MODE, + "", + "", + 0, + G_MAXUINT, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:local: + * + * The local endpoint of the tunnel; the value can be empty, otherwise it + * must contain an IPv4 or IPv6 address. + * + * Since: 1.2 + **/ + obj_properties[PROP_LOCAL] = g_param_spec_string(NM_SETTING_IP_TUNNEL_LOCAL, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:remote: + * + * The remote endpoint of the tunnel; the value must contain an IPv4 or IPv6 + * address. + * + * Since: 1.2 + **/ + obj_properties[PROP_REMOTE] = g_param_spec_string( + NM_SETTING_IP_TUNNEL_REMOTE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:ttl + * + * The TTL to assign to tunneled packets. 0 is a special value meaning that + * packets inherit the TTL value. + * + * Since: 1.2 + **/ + obj_properties[PROP_TTL] = + g_param_spec_uint(NM_SETTING_IP_TUNNEL_TTL, + "", + "", + 0, + 255, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:tos + * + * The type of service (IPv4) or traffic class (IPv6) field to be set on + * tunneled packets. + * + * Since: 1.2 + **/ + obj_properties[PROP_TOS] = + g_param_spec_uint(NM_SETTING_IP_TUNNEL_TOS, + "", + "", + 0, + 255, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:path-mtu-discovery + * + * Whether to enable Path MTU Discovery on this tunnel. + * + * Since: 1.2 + **/ + obj_properties[PROP_PATH_MTU_DISCOVERY] = g_param_spec_boolean( + NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY, + "", + "", + TRUE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:input-key: + * + * The key used for tunnel input packets; the property is valid only for + * certain tunnel modes (GRE, IP6GRE). If empty, no key is used. + * + * Since: 1.2 + **/ + obj_properties[PROP_INPUT_KEY] = g_param_spec_string( + NM_SETTING_IP_TUNNEL_INPUT_KEY, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:output-key: + * + * The key used for tunnel output packets; the property is valid only for + * certain tunnel modes (GRE, IP6GRE). If empty, no key is used. + * + * Since: 1.2 + **/ + obj_properties[PROP_OUTPUT_KEY] = g_param_spec_string( + NM_SETTING_IP_TUNNEL_OUTPUT_KEY, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:encapsulation-limit: + * + * How many additional levels of encapsulation are permitted to be prepended + * to packets. This property applies only to IPv6 tunnels. + * + * Since: 1.2 + **/ + obj_properties[PROP_ENCAPSULATION_LIMIT] = + g_param_spec_uint(NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT, + "", + "", + 0, + 255, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:flow-label: + * + * The flow label to assign to tunnel packets. This property applies only to + * IPv6 tunnels. + * + * Since: 1.2 + **/ + obj_properties[PROP_FLOW_LABEL] = + g_param_spec_uint(NM_SETTING_IP_TUNNEL_FLOW_LABEL, + "", + "", + 0, + (1 << 20) - 1, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple fragments. + * + * Since: 1.2 + **/ + obj_properties[PROP_MTU] = g_param_spec_uint(NM_SETTING_IP_TUNNEL_MTU, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPTunnel:flags: + * + * Tunnel flags. Currently, the following values are supported: + * %NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT, %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS, + * %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL, %NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV, + * %NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY, %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK. + * They are valid only for IPv6 tunnels. + * + * Since: 1.12 + **/ + obj_properties[PROP_FLAGS] = g_param_spec_uint(NM_SETTING_IP_TUNNEL_FLAGS, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_IP_TUNNEL); +} diff --git a/src/libnm-core-impl/nm-setting-ip4-config.c b/src/libnm-core-impl/nm-setting-ip4-config.c new file mode 100644 index 0000000..b19d82e --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ip4-config.c @@ -0,0 +1,1042 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ip4-config.h" + +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-ip4-config + * @short_description: Describes IPv4 addressing, routing, and name service properties + * + * The #NMSettingIP4Config object is a #NMSetting subclass that describes + * properties related to IPv4 addressing, routing, and Domain Name Service. + * + * #NMSettingIP4Config has few properties or methods of its own; it inherits + * almost everything from #NMSettingIPConfig. + * + * NetworkManager supports 5 values for the #NMSettingIPConfig:method property + * for IPv4. If "auto" is specified then the appropriate automatic method + * (DHCP, PPP, etc) is used for the interface and most other properties can be + * left unset. If "link-local" is specified, then a link-local address in the + * 169.254/16 range will be assigned to the interface. If "manual" is + * specified, static IP addressing is used and at least one IP address must be + * given in the "addresses" property. If "shared" is specified (indicating that + * this connection will provide network access to other computers) then the + * interface is assigned an address in the 10.42.x.1/24 range and a DHCP and + * forwarding DNS server are started, and the interface is NAT-ed to the current + * default network connection. "disabled" means IPv4 will not be used on this + * connection. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DHCP_CLIENT_ID, + PROP_DHCP_FQDN, + PROP_DHCP_VENDOR_CLASS_IDENTIFIER, ); + +typedef struct { + char *dhcp_client_id; + char *dhcp_fqdn; + char *dhcp_vendor_class_identifier; +} NMSettingIP4ConfigPrivate; + +G_DEFINE_TYPE(NMSettingIP4Config, nm_setting_ip4_config, NM_TYPE_SETTING_IP_CONFIG) + +#define NM_SETTING_IP4_CONFIG_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4ConfigPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_ip4_config_get_dhcp_client_id: + * @setting: the #NMSettingIP4Config + * + * Returns the value contained in the #NMSettingIP4Config:dhcp-client-id + * property. + * + * Returns: the configured Client ID to send to the DHCP server when requesting + * addresses via DHCP. + **/ +const char * +nm_setting_ip4_config_get_dhcp_client_id(NMSettingIP4Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP4_CONFIG(setting), NULL); + + return NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting)->dhcp_client_id; +} + +/** + * nm_setting_ip4_config_get_dhcp_fqdn: + * @setting: the #NMSettingIP4Config + * + * Returns the value contained in the #NMSettingIP4Config:dhcp-fqdn + * property. + * + * Returns: the configured FQDN to send to the DHCP server + * + * Since: 1.2 + **/ +const char * +nm_setting_ip4_config_get_dhcp_fqdn(NMSettingIP4Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP4_CONFIG(setting), NULL); + + return NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting)->dhcp_fqdn; +} + +/** + * nm_setting_ip4_config_get_dhcp_vendor_class_identifier: + * @setting: the #NMSettingIP4Config + * + * Returns the value contained in the #NMSettingIP4Config:dhcp_vendor_class_identifier + * property. + * + * Returns: the vendor class identifier option to send to the DHCP server + * + * Since: 1.28 + **/ +const char * +nm_setting_ip4_config_get_dhcp_vendor_class_identifier(NMSettingIP4Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP4_CONFIG(setting), NULL); + + return NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting)->dhcp_vendor_class_identifier; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting); + NMSettingIPConfig * s_ip = NM_SETTING_IP_CONFIG(setting); + NMSettingVerifyResult ret; + const char * method; + + ret = NM_SETTING_CLASS(nm_setting_ip4_config_parent_class)->verify(setting, connection, error); + if (ret != NM_SETTING_VERIFY_SUCCESS) + return ret; + + method = nm_setting_ip_config_get_method(s_ip); + /* Base class already checked that it exists */ + g_assert(method); + + if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + if (nm_setting_ip_config_get_num_addresses(s_ip) == 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("this property cannot be empty for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + } else if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) + || !strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) + || !strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { + if (nm_setting_ip_config_get_num_dns(s_ip) > 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_DNS); + return FALSE; + } + + if (nm_setting_ip_config_get_num_dns_searches(s_ip) > 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_DNS_SEARCH); + return FALSE; + } + + /* Shared allows IP addresses; link-local and disabled do not */ + if (strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) != 0) { + if (nm_setting_ip_config_get_num_addresses(s_ip) > 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + } + } else if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + /* nothing to do */ + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_METHOD); + return FALSE; + } + + if (priv->dhcp_client_id && !priv->dhcp_client_id[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID); + return FALSE; + } + + if (priv->dhcp_fqdn && !*priv->dhcp_fqdn) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_FQDN); + return FALSE; + } + + if (priv->dhcp_fqdn && !strchr(priv->dhcp_fqdn, '.')) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid FQDN"), + priv->dhcp_fqdn); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_FQDN); + return FALSE; + } + + if (priv->dhcp_fqdn && nm_setting_ip_config_get_dhcp_hostname(s_ip)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property cannot be set when dhcp-hostname is also set")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_FQDN); + return FALSE; + } + + if (NM_FLAGS_ANY(nm_setting_ip_config_get_dhcp_hostname_flags(s_ip), + NM_DHCP_HOSTNAME_FLAGS_FQDN_MASK) + && !priv->dhcp_fqdn) { + /* Currently, we send a FQDN option only when ipv4.dhcp-fqdn is set */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("FQDN flags requires a FQDN set")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS); + return FALSE; + } + + if (priv->dhcp_vendor_class_identifier + && !nm_utils_validate_dhcp4_vendor_class_id(priv->dhcp_vendor_class_identifier, error)) + return FALSE; + + /* Failures from here on are NORMALIZABLE_ERROR... */ + + if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) + && nm_setting_ip_config_get_num_addresses(s_ip) > 1) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("multiple addresses are not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_SHARED); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_ADDRESSES); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + /* Failures from here on are NORMALIZABLE... */ + + if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) + && !nm_setting_ip_config_get_may_fail(s_ip)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property should be TRUE when method is set to disabled")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_MAY_FAIL); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + + return TRUE; +} + +static GVariant * +ip4_dns_to_dbus(const GValue *prop_value) +{ + return nm_utils_ip4_dns_to_variant(g_value_get_boxed(prop_value)); +} + +static void +ip4_dns_from_dbus(GVariant *dbus_value, GValue *prop_value) +{ + g_value_take_boxed(prop_value, nm_utils_ip4_dns_from_variant(dbus_value)); +} + +static GVariant * +ip4_addresses_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *addrs = NULL; + const char * gateway; + + g_object_get(setting, NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL); + gateway = nm_setting_ip_config_get_gateway(NM_SETTING_IP_CONFIG(setting)); + return nm_utils_ip4_addresses_to_variant(addrs, gateway); +} + +static gboolean +ip4_addresses_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GPtrArray *addrs; + GVariant * s_ip4; + char ** labels, *gateway = NULL; + int i; + + /* FIXME: properly handle errors */ + + if (!_nm_setting_use_legacy_property(setting, connection_dict, "addresses", "address-data")) + return TRUE; + + addrs = nm_utils_ip4_addresses_from_variant(value, &gateway); + + s_ip4 = g_variant_lookup_value(connection_dict, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_VARIANT_TYPE_SETTING); + if (g_variant_lookup(s_ip4, "address-labels", "^as", &labels)) { + for (i = 0; i < addrs->len && labels[i]; i++) + if (*labels[i]) + nm_ip_address_set_attribute(addrs->pdata[i], + NM_IP_ADDRESS_ATTRIBUTE_LABEL, + g_variant_new_string(labels[i])); + g_strfreev(labels); + } + g_variant_unref(s_ip4); + + g_object_set(setting, + NM_SETTING_IP_CONFIG_ADDRESSES, + addrs, + NM_SETTING_IP_CONFIG_GATEWAY, + gateway, + NULL); + g_ptr_array_unref(addrs); + g_free(gateway); + return TRUE; +} + +static GVariant * +ip4_address_labels_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG(setting); + gboolean have_labels = FALSE; + GPtrArray * labels; + GVariant * ret; + int num_addrs, i; + + if (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + return NULL; + + num_addrs = nm_setting_ip_config_get_num_addresses(s_ip); + for (i = 0; i < num_addrs; i++) { + NMIPAddress *addr = nm_setting_ip_config_get_address(s_ip, i); + GVariant * label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + + if (label) { + have_labels = TRUE; + break; + } + } + if (!have_labels) + return NULL; + + labels = g_ptr_array_sized_new(num_addrs); + for (i = 0; i < num_addrs; i++) { + NMIPAddress *addr = nm_setting_ip_config_get_address(s_ip, i); + GVariant * label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + + g_ptr_array_add(labels, (char *) (label ? g_variant_get_string(label, NULL) : "")); + } + + ret = g_variant_new_strv((const char *const *) labels->pdata, labels->len); + g_ptr_array_unref(labels); + + return ret; +} + +static GVariant * +ip4_address_data_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *addrs = NULL; + + if (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + return NULL; + + g_object_get(setting, NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL); + return nm_utils_ip_addresses_to_variant(addrs); +} + +static gboolean +ip4_address_data_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GPtrArray *addrs; + + /* FIXME: properly handle errors */ + + /* Ignore 'address-data' if we're going to process 'addresses' */ + if (_nm_setting_use_legacy_property(setting, connection_dict, "addresses", "address-data")) + return TRUE; + + addrs = nm_utils_ip_addresses_from_variant(value, AF_INET); + g_object_set(setting, NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL); + g_ptr_array_unref(addrs); + return TRUE; +} + +static GVariant * +ip4_routes_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *routes = NULL; + + g_object_get(setting, NM_SETTING_IP_CONFIG_ROUTES, &routes, NULL); + return nm_utils_ip4_routes_to_variant(routes); +} + +static gboolean +ip4_routes_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GPtrArray *routes; + + /* FIXME: properly handle errors */ + + if (!_nm_setting_use_legacy_property(setting, connection_dict, "routes", "route-data")) + return TRUE; + + routes = nm_utils_ip4_routes_from_variant(value); + g_object_set(setting, property, routes, NULL); + g_ptr_array_unref(routes); + return TRUE; +} + +static GVariant * +ip4_route_data_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *routes = NULL; + + if (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + return NULL; + + g_object_get(setting, NM_SETTING_IP_CONFIG_ROUTES, &routes, NULL); + return nm_utils_ip_routes_to_variant(routes); +} + +static gboolean +ip4_route_data_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GPtrArray *routes; + + /* FIXME: properly handle errors */ + + /* Ignore 'route-data' if we're going to process 'routes' */ + if (_nm_setting_use_legacy_property(setting, connection_dict, "routes", "route-data")) + return TRUE; + + routes = nm_utils_ip_routes_from_variant(value, AF_INET); + g_object_set(setting, NM_SETTING_IP_CONFIG_ROUTES, routes, NULL); + g_ptr_array_unref(routes); + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingIP4Config *s_ip4 = NM_SETTING_IP4_CONFIG(object); + + switch (prop_id) { + case PROP_DHCP_CLIENT_ID: + g_value_set_string(value, nm_setting_ip4_config_get_dhcp_client_id(s_ip4)); + break; + case PROP_DHCP_FQDN: + g_value_set_string(value, nm_setting_ip4_config_get_dhcp_fqdn(s_ip4)); + break; + case PROP_DHCP_VENDOR_CLASS_IDENTIFIER: + g_value_set_string(value, nm_setting_ip4_config_get_dhcp_vendor_class_identifier(s_ip4)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_DHCP_CLIENT_ID: + g_free(priv->dhcp_client_id); + priv->dhcp_client_id = g_value_dup_string(value); + break; + case PROP_DHCP_FQDN: + g_free(priv->dhcp_fqdn); + priv->dhcp_fqdn = g_value_dup_string(value); + break; + case PROP_DHCP_VENDOR_CLASS_IDENTIFIER: + g_free(priv->dhcp_vendor_class_identifier); + priv->dhcp_vendor_class_identifier = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ip4_config_init(NMSettingIP4Config *setting) +{} + +/** + * nm_setting_ip4_config_new: + * + * Creates a new #NMSettingIP4Config object with default values. + * + * Returns: (transfer full): the new empty #NMSettingIP4Config object + **/ +NMSetting * +nm_setting_ip4_config_new(void) +{ + return g_object_new(NM_TYPE_SETTING_IP4_CONFIG, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE(object); + + g_free(priv->dhcp_client_id); + g_free(priv->dhcp_fqdn); + g_free(priv->dhcp_vendor_class_identifier); + + G_OBJECT_CLASS(nm_setting_ip4_config_parent_class)->finalize(object); +} + +static void +nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array_ip_config(); + + g_type_class_add_private(setting_class, sizeof(NMSettingIP4ConfigPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /* ---ifcfg-rh--- + * property: method + * variable: BOOTPROTO + * format: string + * values: none, dhcp (bootp), static, ibft, autoip, shared + * default: none + * description: Method used for IPv4 protocol configuration. + * ---end--- + */ + + /* ---keyfile--- + * property: dns + * format: list of DNS IP addresses + * description: List of DNS servers. + * example: dns=1.2.3.4;8.8.8.8;8.8.4.4; + * ---end--- + * ---ifcfg-rh--- + * property: dns + * variable: DNS1, DNS2, ... + * format: string + * description: List of DNS servers. Even if NetworkManager supports many DNS + * servers, initscripts and resolver only care about the first three, usually. + * example: DNS1=1.2.3.4 DNS2=10.0.0.254 DNS3=8.8.8.8 + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dns-search + * variable: DOMAIN + * format: string (space-separated domains) + * description: List of DNS search domains. + * ---end--- + */ + + /* ---keyfile--- + * property: addresses + * variable: address1, address2, ... + * format: address/plen + * description: List of static IP addresses. + * example: address1=192.168.100.100/24 address2=10.1.1.5/24 + * ---end--- + * ---ifcfg-rh--- + * property: addresses + * variable: IPADDR, PREFIX (NETMASK), IPADDR1, PREFIX1 (NETMASK1), ... + * description: List of static IP addresses. + * example: IPADDR=10.5.5.23 PREFIX=24 IPADDR1=1.1.1.2 PREFIX1=16 + * ---end--- + */ + + /* ---keyfile--- + * property: gateway + * variable: gateway + * format: string + * description: Gateway IP addresses as a string. + * example: gateway=192.168.100.1 + * ---end--- + * ---ifcfg-rh--- + * property: gateway + * variable: GATEWAY + * description: Gateway IP address. + * example: GATEWAY=10.5.5.1 + * ---end--- + */ + + /* ---keyfile--- + * property: routes + * variable: route1, route2, ... + * format: route/plen[,gateway,metric] + * description: List of IP routes. + * example: route1=8.8.8.0/24,10.1.1.1,77 + * route2=7.7.0.0/16 + * ---end--- + * ---ifcfg-rh--- + * property: routes + * variable: ADDRESS1, NETMASK1, GATEWAY1, METRIC1, OPTIONS1, ... + * description: List of static routes. They are not stored in ifcfg-* file, + * but in route-* file instead. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: ignore-auto-routes + * variable: PEERROUTES(+) + * default: yes + * description: PEERROUTES has the opposite meaning as 'ignore-auto-routes' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: ignore-auto-dns + * variable: PEERDNS + * default: yes + * description: PEERDNS has the opposite meaning as 'ignore-auto-dns' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dhcp-send-hostname + * variable: DHCP_SEND_HOSTNAME(+) + * default: yes + * description: Whether DHCP_HOSTNAME should be sent to the DHCP server. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dhcp-hostname + * variable: DHCP_HOSTNAME + * description: Hostname to send to the DHCP server. When both DHCP_HOSTNAME and + * DHCP_FQDN are specified only the latter is used. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: never-default + * variable: DEFROUTE (GATEWAYDEV in /etc/sysconfig/network) + * default: yes + * description: DEFROUTE=no tells NetworkManager that this connection + * should not be assigned the default route. DEFROUTE has the opposite + * meaning as 'never-default' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: may-fail + * variable: IPV4_FAILURE_FATAL(+) + * default: no + * description: IPV4_FAILURE_FATAL has the opposite meaning as 'may-fail' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: route-metric + * variable: IPV4_ROUTE_METRIC(+) + * default: -1 + * description: IPV4_ROUTE_METRIC is the default IPv4 metric for routes on this connection. + * If set to -1, a default metric based on the device type is used. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: route-table + * variable: IPV4_ROUTE_TABLE(+) + * default: 0 + * description: IPV4_ROUTE_TABLE enables policy-routing and sets the default routing table. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dns-options + * variable: RES_OPTIONS(+) + * description: List of DNS options to be added to /etc/resolv.conf + * example: RES_OPTIONS=ndots:2 timeout:3 + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dns-priority + * variable: IPV4_DNS_PRIORITY(+) + * description: The priority for DNS servers of this connection. Lower values have higher priority. + * If zero, the default value will be used (50 for VPNs, 100 for other connections). + * A negative value prevents DNS from other connections with greater values to be used. + * default: 0 + * example: IPV4_DNS_PRIORITY=20 + * ---end--- + */ + + /** + * NMSettingIP4Config:dhcp-client-id: + * + * A string sent to the DHCP server to identify the local machine which the + * DHCP server may use to customize the DHCP lease and options. + * When the property is a hex string ('aa:bb:cc') it is interpreted as a + * binary client ID, in which case the first byte is assumed to be the + * 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be + * an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet + * ARP type and the rest is a MAC address). + * If the property is not a hex string it is considered as a + * non-hardware-address client ID and the 'type' field is set to 0. + * + * The special values "mac" and "perm-mac" are supported, which use the + * current or permanent MAC address of the device to generate a client identifier + * with type ethernet (01). Currently, these options only work for ethernet + * type of links. + * + * The special value "ipv6-duid" uses the DUID from "ipv6.dhcp-duid" property as + * an RFC4361-compliant client identifier. As IAID it uses "ipv4.dhcp-iaid" + * and falls back to "ipv6.dhcp-iaid" if unset. + * + * The special value "duid" generates a RFC4361-compliant client identifier based + * on "ipv4.dhcp-iaid" and uses a DUID generated by hashing /etc/machine-id. + * + * The special value "stable" is supported to generate a type 0 client identifier based + * on the stable-id (see connection.stable-id) and a per-host key. If you set the + * stable-id, you may want to include the "${DEVICE}" or "${MAC}" specifier to get a + * per-device key. + * + * If unset, a globally configured default is used. If still unset, the default + * depends on the DHCP plugin. + **/ + /* ---ifcfg-rh--- + * property: dhcp-client-id + * variable: DHCP_CLIENT_ID(+) + * description: A string sent to the DHCP server to identify the local machine. + * A binary value can be specified using hex notation ('aa:bb:cc'). + * example: DHCP_CLIENT_ID=ax-srv-1; DHCP_CLIENT_ID=01:44:44:44:44:44:44 + * ---end--- + */ + obj_properties[PROP_DHCP_CLIENT_ID] = + g_param_spec_string(NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /* ---ifcfg-rh--- + * property: dad-timeout + * variable: ACD_TIMEOUT(+), ARPING_WAIT + * default: missing variable means global default (config override or zero) + * description: Timeout (in milliseconds for ACD_TIMEOUT or in seconds + * for ARPING_WAIT) for address conflict detection before configuring + * IPv4 addresses. 0 turns off the ACD completely, -1 means default value. + * example: ACD_TIMEOUT=2000 or ARPING_WAIT=2 + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dhcp-timeout + * variable: IPV4_DHCP_TIMEOUT(+) + * description: A timeout after which the DHCP transaction fails in case of no response. + * example: IPV4_DHCP_TIMEOUT=10 + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dhcp-hostname-flags + * variable: DHCP_HOSTNAME_FLAGS + * description: flags for the DHCP hostname and FQDN properties + * example: DHCP_HOSTNAME_FLAGS=5 + */ + + /** + * NMSettingIP4Config:dhcp-fqdn: + * + * If the #NMSettingIPConfig:dhcp-send-hostname property is %TRUE, then the + * specified FQDN will be sent to the DHCP server when acquiring a lease. This + * property and #NMSettingIPConfig:dhcp-hostname are mutually exclusive and + * cannot be set at the same time. + * + * Since: 1.2 + */ + /* ---ifcfg-rh--- + * property: dhcp-fqdn + * variable: DHCP_FQDN + * description: FQDN to send to the DHCP server. When both DHCP_HOSTNAME and + * DHCP_FQDN are specified only the latter is used. + * example: DHCP_FQDN=foo.bar.com + * ---end--- + */ + obj_properties[PROP_DHCP_FQDN] = + g_param_spec_string(NM_SETTING_IP4_CONFIG_DHCP_FQDN, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIP4Config:dhcp-vendor-class-identifier: + * + * The Vendor Class Identifier DHCP option (60). + * Special characters in the data string may be escaped using C-style escapes, + * nevertheless this property cannot contain nul bytes. + * If the per-profile value is unspecified (the default), + * a global connection default gets consulted. + * If still unspecified, the DHCP option is not sent to the server. + * + * Since 1.28 + */ + /* ---ifcfg-rh--- + * property: dhcp-vendor-class-identifier + * variable: DHCP_VENDOR_CLASS_IDENTIFIER(+) + * description: The Vendor Class Identifier DHCP option (60). + * example: DHCP_VENDOR_CLASS_IDENTIFIER=foo + * ---end--- + */ + obj_properties[PROP_DHCP_VENDOR_CLASS_IDENTIFIER] = + g_param_spec_string(NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /* IP4-specific property overrides */ + + /* ---dbus--- + * property: dns + * format: array of uint32 + * description: Array of IP addresses of DNS servers (as network-byte-order + * integers) + * ---end--- + */ + _nm_properties_override_gobj( + properties_override, + g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_DNS), + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("au"), + .gprop_to_dbus_fcn = ip4_dns_to_dbus, + .gprop_from_dbus_fcn = ip4_dns_from_dbus, )); + + /* ---dbus--- + * property: addresses + * format: array of array of uint32 + * description: Deprecated in favor of the 'address-data' and 'gateway' + * properties, but this can be used for backward-compatibility with older + * daemons. Note that if you send this property the daemon will ignore + * 'address-data' and 'gateway'. + * + * Array of IPv4 address structures. Each IPv4 address structure is + * composed of 3 32-bit values; the first being the IPv4 address (network + * byte order), the second the prefix (1 - 32), and last the IPv4 gateway + * (network byte order). The gateway may be left as 0 if no gateway exists + * for that subnet. + * ---end--- + */ + /* ---nmcli--- + * property: addresses + * format: a comma separated list of addresses + * description: A list of IPv4 addresses and their prefix length. Multiple addresses + * can be separated by comma. For example "192.168.1.5/24, 10.1.0.5/24". + * ---end--- + */ + _nm_properties_override_gobj( + properties_override, + g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_ADDRESSES), + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aau"), + .to_dbus_fcn = ip4_addresses_get, + .from_dbus_fcn = ip4_addresses_set, )); + _nm_properties_override_dbus( + properties_override, + "address-labels", + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING_ARRAY, + .to_dbus_fcn = ip4_address_labels_get, )); + + /* ---dbus--- + * property: address-data + * format: array of vardict + * description: Array of IPv4 addresses. Each address dictionary contains at + * least 'address' and 'prefix' entries, containing the IP address as a + * string, and the prefix length as a uint32. Additional attributes may + * also exist on some addresses. + * ---end--- + */ + _nm_properties_override_dbus( + properties_override, + "address-data", + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = ip4_address_data_get, + .from_dbus_fcn = ip4_address_data_set, )); + + /* ---dbus--- + * property: routes + * format: array of array of uint32 + * description: Deprecated in favor of the 'route-data' property, but this + * can be used for backward-compatibility with older daemons. Note that if + * you send this property the daemon will ignore 'route-data'. + * + * Array of IPv4 route structures. Each IPv4 route structure is composed + * of 4 32-bit values; the first being the destination IPv4 network or + * address (network byte order), the second the destination network or + * address prefix (1 - 32), the third being the next-hop (network byte + * order) if any, and the fourth being the route metric. If the metric is + * 0, NM will choose an appropriate default metric for the device. (There + * is no way to explicitly specify an actual metric of 0 with this + * property.) + * ---end--- + */ + /* ---nmcli--- + * property: routes + * format: a comma separated list of routes + * description: A list of IPv4 destination addresses, prefix length, optional IPv4 + * next hop addresses, optional route metric, optional attribute. The valid syntax is: + * "ip[/prefix] [next-hop] [metric] [attribute=val]...[,ip[/prefix]...]". For example + * "192.0.2.0/24 10.1.1.1 77, 198.51.100.0/24". + * ---end--- + */ + _nm_properties_override_gobj( + properties_override, + g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_ROUTES), + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aau"), + .to_dbus_fcn = ip4_routes_get, + .from_dbus_fcn = ip4_routes_set, )); + + /* ---dbus--- + * property: route-data + * format: array of vardict + * description: Array of IPv4 routes. Each route dictionary contains at + * least 'dest' and 'prefix' entries, containing the destination IP + * address as a string, and the prefix length as a uint32. Most routes + * will also have a 'next-hop' entry, containing the next hop IP address as + * a string. If the route has a 'metric' entry (containing a uint32), that + * will be used as the metric for the route (otherwise NM will pick a + * default value appropriate to the device). Additional attributes may + * also exist on some routes. + * ---end--- + */ + _nm_properties_override_dbus(properties_override, + "route-data", + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = ip4_route_data_get, + .from_dbus_fcn = ip4_route_data_set, )); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_IP4_CONFIG, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-ip6-config.c b/src/libnm-core-impl/nm-setting-ip6-config.c new file mode 100644 index 0000000..4477436 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ip6-config.c @@ -0,0 +1,1085 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ip6-config.h" + +#include + +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" +#include "libnm-core-intern/nm-core-internal.h" + +/** + * SECTION:nm-setting-ip6-config + * @short_description: Describes IPv6 addressing, routing, and name service properties + * + * The #NMSettingIP6Config object is a #NMSetting subclass that describes + * properties related to IPv6 addressing, routing, and Domain Name Service + * + * #NMSettingIP6Config has few properties or methods of its own; it inherits + * almost everything from #NMSettingIPConfig. + * + * NetworkManager supports 7 values for the #NMSettingIPConfig:method property + * for IPv6. If "auto" is specified then the appropriate automatic method (PPP, + * router advertisement, etc) is used for the device and most other properties + * can be left unset. To force the use of DHCP only, specify "dhcp"; this + * method is only valid for Ethernet- based hardware. If "link-local" is + * specified, then an IPv6 link-local address will be assigned to the interface. + * If "manual" is specified, static IP addressing is used and at least one IP + * address must be given in the "addresses" property. If "ignore" is specified, + * IPv6 configuration is not done. Note: the "shared" method is not yet + * supported. If "disabled" is specified, IPv6 is disabled completely for the + * interface. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_IP6_PRIVACY, + PROP_ADDR_GEN_MODE, + PROP_TOKEN, + PROP_DHCP_DUID, + PROP_RA_TIMEOUT, ); + +typedef struct { + char * token; + char * dhcp_duid; + NMSettingIP6ConfigPrivacy ip6_privacy; + NMSettingIP6ConfigAddrGenMode addr_gen_mode; + gint32 ra_timeout; +} NMSettingIP6ConfigPrivate; + +G_DEFINE_TYPE(NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING_IP_CONFIG) + +#define NM_SETTING_IP6_CONFIG_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6ConfigPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_ip6_config_get_ip6_privacy: + * @setting: the #NMSettingIP6Config + * + * Returns the value contained in the #NMSettingIP6Config:ip6-privacy + * property. + * + * Returns: IPv6 Privacy Extensions configuration value (#NMSettingIP6ConfigPrivacy). + **/ +NMSettingIP6ConfigPrivacy +nm_setting_ip6_config_get_ip6_privacy(NMSettingIP6Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP6_CONFIG(setting), NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting)->ip6_privacy; +} + +/** + * nm_setting_ip6_config_get_addr_gen_mode: + * @setting: the #NMSettingIP6Config + * + * Returns the value contained in the #NMSettingIP6Config:addr-gen-mode + * property. + * + * Returns: IPv6 Address Generation Mode. + * + * Since: 1.2 + **/ +NMSettingIP6ConfigAddrGenMode +nm_setting_ip6_config_get_addr_gen_mode(NMSettingIP6Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP6_CONFIG(setting), + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting)->addr_gen_mode; +} + +/** + * nm_setting_ip6_config_get_token: + * @setting: the #NMSettingIP6Config + * + * Returns the value contained in the #NMSettingIP6Config:token + * property. + * + * Returns: A string. + * + * Since: 1.4 + **/ +const char * +nm_setting_ip6_config_get_token(NMSettingIP6Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP6_CONFIG(setting), NULL); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting)->token; +} + +/** + * nm_setting_ip6_config_get_dhcp_duid: + * @setting: the #NMSettingIP6Config + * + * Returns the value contained in the #NMSettingIP6Config:dhcp-duid + * property. + * + * Returns: The configured DUID value to be included in the DHCPv6 requests + * sent to the DHCPv6 servers. + * + * Since: 1.12 + **/ +const char * +nm_setting_ip6_config_get_dhcp_duid(NMSettingIP6Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP6_CONFIG(setting), NULL); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting)->dhcp_duid; +} + +/** + * nm_setting_ip6_config_get_ra_timeout: + * @setting: the #NMSettingIP6Config + * + * Returns: The configured %NM_SETTING_IP6_CONFIG_RA_TIMEOUT value with the + * timeout for router advertisements in seconds. + * + * Since: 1.24 + **/ +gint32 +nm_setting_ip6_config_get_ra_timeout(NMSettingIP6Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP6_CONFIG(setting), 0); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting)->ra_timeout; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting); + NMSettingIPConfig * s_ip = NM_SETTING_IP_CONFIG(setting); + NMSettingVerifyResult ret; + const char * method; + gboolean token_needs_normalization = FALSE; + + ret = NM_SETTING_CLASS(nm_setting_ip6_config_parent_class)->verify(setting, connection, error); + if (ret != NM_SETTING_VERIFY_SUCCESS) + return ret; + + method = nm_setting_ip_config_get_method(s_ip); + /* Base class already checked that it exists */ + g_assert(method); + + if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + if (nm_setting_ip_config_get_num_addresses(s_ip) == 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("this property cannot be empty for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + } else if (NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP6_CONFIG_METHOD_SHARED, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { + /* Shared allows IP addresses and DNS; other methods do not */ + if (!nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { + if (nm_setting_ip_config_get_num_dns(s_ip) > 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_DNS); + return FALSE; + } + + if (nm_setting_ip_config_get_num_dns_searches(s_ip) > 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_DNS_SEARCH); + return FALSE; + } + + if (nm_setting_ip_config_get_num_addresses(s_ip) > 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + } + } else if (NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { + /* nothing to do */ + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_METHOD); + return FALSE; + } + + if (!NM_IN_SET(priv->addr_gen_mode, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE); + return FALSE; + } + + if (priv->token) { + if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) { + struct in6_addr i6_token; + char s_token[NM_UTILS_INET_ADDRSTRLEN]; + + if (inet_pton(AF_INET6, priv->token, &i6_token) != 1 + || !_nm_utils_inet6_is_token(&i6_token)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value is not a valid token")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_TOKEN); + return FALSE; + } + + if (g_strcmp0(priv->token, _nm_utils_inet6_ntop(&i6_token, s_token))) + token_needs_normalization = TRUE; + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("only makes sense with EUI64 address generation mode")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_TOKEN); + return FALSE; + } + } + + if (priv->dhcp_duid) { + if (!_nm_utils_dhcp_duid_valid(priv->dhcp_duid, NULL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid DUID")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_DHCP_DUID); + return FALSE; + } + } + + /* Failures from here on, are NORMALIZABLE_ERROR... */ + + if (token_needs_normalization) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("token is not in canonical form")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_TOKEN); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + /* Failures from here on are NORMALIZABLE... */ + + if (NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED) + && !nm_setting_ip_config_get_may_fail(s_ip)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property should be TRUE when method is set to ignore or disabled")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_MAY_FAIL); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + + return TRUE; +} + +static GVariant * +ip6_dns_to_dbus(const GValue *prop_value) +{ + return nm_utils_ip6_dns_to_variant(g_value_get_boxed(prop_value)); +} + +static void +ip6_dns_from_dbus(GVariant *dbus_value, GValue *prop_value) +{ + g_value_take_boxed(prop_value, nm_utils_ip6_dns_from_variant(dbus_value)); +} + +static GVariant * +ip6_addresses_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *addrs = NULL; + const char * gateway; + + g_object_get(setting, NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL); + gateway = nm_setting_ip_config_get_gateway(NM_SETTING_IP_CONFIG(setting)); + return nm_utils_ip6_addresses_to_variant(addrs, gateway); +} + +static gboolean +ip6_addresses_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GPtrArray *addrs; + char * gateway = NULL; + + /* FIXME: properly handle errors */ + + if (!_nm_setting_use_legacy_property(setting, connection_dict, "addresses", "address-data")) + return TRUE; + + addrs = nm_utils_ip6_addresses_from_variant(value, &gateway); + + g_object_set(setting, + NM_SETTING_IP_CONFIG_ADDRESSES, + addrs, + NM_SETTING_IP_CONFIG_GATEWAY, + gateway, + NULL); + g_ptr_array_unref(addrs); + g_free(gateway); + return TRUE; +} + +static GVariant * +ip6_address_data_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *addrs = NULL; + + if (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + return NULL; + + g_object_get(setting, NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL); + return nm_utils_ip_addresses_to_variant(addrs); +} + +static gboolean +ip6_address_data_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GPtrArray *addrs; + + /* FIXME: properly handle errors */ + + /* Ignore 'address-data' if we're going to process 'addresses' */ + if (_nm_setting_use_legacy_property(setting, connection_dict, "addresses", "address-data")) + return TRUE; + + addrs = nm_utils_ip_addresses_from_variant(value, AF_INET6); + g_object_set(setting, NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL); + g_ptr_array_unref(addrs); + return TRUE; +} + +static GVariant * +ip6_routes_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *routes = NULL; + + g_object_get(setting, NM_SETTING_IP_CONFIG_ROUTES, &routes, NULL); + return nm_utils_ip6_routes_to_variant(routes); +} + +static gboolean +ip6_routes_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GPtrArray *routes; + + /* FIXME: properly handle errors */ + + if (!_nm_setting_use_legacy_property(setting, connection_dict, "routes", "route-data")) + return TRUE; + + routes = nm_utils_ip6_routes_from_variant(value); + g_object_set(setting, property, routes, NULL); + g_ptr_array_unref(routes); + return TRUE; +} + +static GVariant * +ip6_route_data_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *routes = NULL; + + if (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + return NULL; + + g_object_get(setting, NM_SETTING_IP_CONFIG_ROUTES, &routes, NULL); + return nm_utils_ip_routes_to_variant(routes); +} + +static gboolean +ip6_route_data_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GPtrArray *routes; + + /* FIXME: properly handle errors */ + + /* Ignore 'route-data' if we're going to process 'routes' */ + if (_nm_setting_use_legacy_property(setting, connection_dict, "routes", "route-data")) + return TRUE; + + routes = nm_utils_ip_routes_from_variant(value, AF_INET6); + g_object_set(setting, NM_SETTING_IP_CONFIG_ROUTES, routes, NULL); + g_ptr_array_unref(routes); + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_IP6_PRIVACY: + g_value_set_enum(value, priv->ip6_privacy); + break; + case PROP_ADDR_GEN_MODE: + g_value_set_int(value, priv->addr_gen_mode); + break; + case PROP_TOKEN: + g_value_set_string(value, priv->token); + break; + case PROP_DHCP_DUID: + g_value_set_string(value, priv->dhcp_duid); + break; + case PROP_RA_TIMEOUT: + g_value_set_int(value, priv->ra_timeout); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_IP6_PRIVACY: + priv->ip6_privacy = g_value_get_enum(value); + break; + case PROP_ADDR_GEN_MODE: + priv->addr_gen_mode = g_value_get_int(value); + break; + case PROP_TOKEN: + g_free(priv->token); + priv->token = g_value_dup_string(value); + break; + case PROP_DHCP_DUID: + g_free(priv->dhcp_duid); + priv->dhcp_duid = g_value_dup_string(value); + break; + case PROP_RA_TIMEOUT: + priv->ra_timeout = g_value_get_int(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ip6_config_init(NMSettingIP6Config *setting) +{ + NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting); + + priv->ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; + priv->addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY; +} + +/** + * nm_setting_ip6_config_new: + * + * Creates a new #NMSettingIP6Config object with default values. + * + * Returns: (transfer full): the new empty #NMSettingIP6Config object + **/ +NMSetting * +nm_setting_ip6_config_new(void) +{ + return g_object_new(NM_TYPE_SETTING_IP6_CONFIG, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingIP6Config * self = NM_SETTING_IP6_CONFIG(object); + NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE(self); + + g_free(priv->token); + g_free(priv->dhcp_duid); + + G_OBJECT_CLASS(nm_setting_ip6_config_parent_class)->finalize(object); +} + +static void +nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array_ip_config(); + + g_type_class_add_private(klass, sizeof(NMSettingIP6ConfigPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /* ---ifcfg-rh--- + * property: method + * variable: IPV6INIT, IPV6FORWARDING, IPV6_AUTOCONF, DHCPV6C, IPV6_DISABLED + * default: IPV6INIT=yes; IPV6FORWARDING=no; IPV6_AUTOCONF=!IPV6FORWARDING, DHCPV6=no + * description: Method used for IPv6 protocol configuration. + * ignore ~ IPV6INIT=no; auto ~ IPV6_AUTOCONF=yes; dhcp ~ IPV6_AUTOCONF=no and DHCPV6C=yes; + * disabled ~ IPV6_DISABLED=yes + * ---end--- + */ + + /* ---keyfile--- + * property: dns + * format: list of DNS IP addresses + * description: List of DNS servers. + * example: dns=2001:4860:4860::8888;2001:4860:4860::8844; + * ---end--- + * ---ifcfg-rh--- + * property: dns + * variable: DNS1, DNS2, ... + * format: string + * description: List of DNS servers. NetworkManager uses the variables both + * for IPv4 and IPv6. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dns-search + * variable: IPV6_DOMAIN(+) + * format: string (space-separated domains) + * description: List of DNS search domains. + * ---end--- + */ + + /* ---keyfile--- + * property: addresses + * variable: address1, address2, ... + * format: address/plen + * description: List of static IP addresses. + * example: address1=abbe::cafe/96 address2=2001::1234 + * ---end--- + * ---ifcfg-rh--- + * property: addresses + * variable: IPV6ADDR, IPV6ADDR_SECONDARIES + * description: List of static IP addresses. + * example: IPV6ADDR=ab12:9876::1 + * IPV6ADDR_SECONDARIES="ab12:9876::2 ab12:9876::3" + * ---end--- + */ + + /* ---keyfile--- + * property: gateway + * variable: gateway + * format: string + * description: Gateway IP addresses as a string. + * example: gateway=abbe::1 + * ---end--- + * ---ifcfg-rh--- + * property: gateway + * variable: IPV6_DEFAULTGW + * description: Gateway IP address. + * example: IPV6_DEFAULTGW=abbe::1 + * ---end--- + */ + + /* ---keyfile--- + * property: routes + * variable: route1, route2, ... + * format: route/plen[,gateway,metric] + * description: List of IP routes. + * example: route1=2001:4860:4860::/64,2620:52:0:2219:222:68ff:fe11:5403 + * ---end--- + * ---ifcfg-rh--- + * property: routes + * variable: (none) + * description: List of static routes. They are not stored in ifcfg-* file, + * but in route6-* file instead in the form of command line for 'ip route add'. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: ignore-auto-routes + * variable: IPV6_PEERROUTES(+) + * default: yes + * description: IPV6_PEERROUTES has the opposite meaning as 'ignore-auto-routes' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: ignore-auto-dns + * variable: IPV6_PEERDNS(+) + * default: yes + * description: IPV6_PEERDNS has the opposite meaning as 'ignore-auto-dns' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dhcp-hostname + * variable: DHCPV6_HOSTNAME + * description: Hostname to send the DHCP server. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dhcp-timeout + * variable: IPV6_DHCP_TIMEOUT(+) + * description: A timeout after which the DHCP transaction fails in case of no response. + * example: IPV6_DHCP_TIMEOUT=10 + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dhcp-hostname-flags + * variable: DHCPV6_HOSTNAME_FLAGS + * description: flags for the DHCP hostname property + * example: DHCPV6_HOSTNAME_FLAGS=5 + */ + + /* ---ifcfg-rh--- + * property: never-default + * variable: IPV6_DEFROUTE(+), (and IPV6_DEFAULTGW, IPV6_DEFAULTDEV in /etc/sysconfig/network) + * default: IPV6_DEFROUTE=yes (when no variable specified) + * description: IPV6_DEFROUTE=no tells NetworkManager that this connection + * should not be assigned the default IPv6 route. IPV6_DEFROUTE has the opposite + * meaning as 'never-default' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: may-fail + * variable: IPV6_FAILURE_FATAL(+) + * default: no + * description: IPV6_FAILURE_FATAL has the opposite meaning as 'may-fail' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: route-metric + * variable: IPV6_ROUTE_METRIC(+) + * default: -1 + * description: IPV6_ROUTE_METRIC is the default IPv6 metric for routes on this connection. + * If set to -1, a default metric based on the device type is used. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: route-table + * variable: IPV6_ROUTE_TABLE(+) + * default: 0 + * description: IPV6_ROUTE_TABLE enables policy-routing and sets the default routing table. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dns-priority + * variable: IPV6_DNS_PRIORITY(+) + * description: The priority for DNS servers of this connection. Lower values have higher priority. + * If zero, the default value will be used (50 for VPNs, 100 for other connections). + * A negative value prevents DNS from other connections with greater values to be used. + * default: 0 + * example: IPV6_DNS_PRIORITY=20 + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dns-options + * variable: IPV6_RES_OPTIONS(+) + * description: List of DNS options to be added to /etc/resolv.conf + * example: IPV6_RES_OPTIONS=ndots:2 timeout:3 + * ---end--- + */ + + /** + * NMSettingIP6Config:ip6-privacy: + * + * Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If + * enabled, it makes the kernel generate a temporary IPv6 address in + * addition to the public one generated from MAC address via modified + * EUI-64. This enhances privacy, but could cause problems in some + * applications, on the other hand. The permitted values are: -1: unknown, + * 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary + * addresses). + * + * Having a per-connection setting set to "-1" (unknown) means fallback to + * global configuration "ipv6.ip6-privacy". + * + * If also global configuration is unspecified or set to "-1", fallback to read + * "/proc/sys/net/ipv6/conf/default/use_tempaddr". + * + * Note that this setting is distinct from the Stable Privacy addresses + * that can be enabled with the "addr-gen-mode" property's "stable-privacy" + * setting as another way of avoiding host tracking with IPv6 addresses. + **/ + /* ---ifcfg-rh--- + * property: ip6-privacy + * variable: IPV6_PRIVACY, IPV6_PRIVACY_PREFER_PUBLIC_IP(+) + * values: IPV6_PRIVACY: no, yes (rfc3041 or rfc4941); + * IPV6_PRIVACY_PREFER_PUBLIC_IP: yes, no + * default: no + * description: Configure IPv6 Privacy Extensions for SLAAC (RFC4941). + * example: IPV6_PRIVACY=rfc3041 IPV6_PRIVACY_PREFER_PUBLIC_IP=yes + * ---end--- + */ + obj_properties[PROP_IP6_PRIVACY] = + g_param_spec_enum(NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + "", + "", + NM_TYPE_SETTING_IP6_CONFIG_PRIVACY, + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIP6Config:addr-gen-mode: + * + * Configure method for creating the address for use with RFC4862 IPv6 + * Stateless Address Autoconfiguration. The permitted values are: + * %NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 or + * %NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY. + * + * If the property is set to EUI64, the addresses will be generated + * using the interface tokens derived from hardware address. This makes + * the host part of the address to stay constant, making it possible + * to track host's presence when it changes networks. The address changes + * when the interface hardware is replaced. + * + * The value of stable-privacy enables use of cryptographically + * secure hash of a secret host-specific key along with the connection's + * stable-id and the network address as specified by RFC7217. + * This makes it impossible to use the address track host's presence, + * and makes the address stable when the network interface hardware is + * replaced. + * + * On D-Bus, the absence of an addr-gen-mode setting equals enabling + * stable-privacy. For keyfile plugin, the absence of the setting + * on disk means EUI64 so that the property doesn't change on upgrade + * from older versions. + * + * Note that this setting is distinct from the Privacy Extensions as + * configured by "ip6-privacy" property and it does not affect the + * temporary addresses configured with this option. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: addr-gen-mode + * variable: IPV6_ADDR_GEN_MODE + * values: IPV6_ADDR_GEN_MODE: eui64, stable-privacy + * default: eui64 + * description: Configure IPv6 Stable Privacy addressing for SLAAC (RFC7217). + * example: IPV6_ADDR_GEN_MODE=stable-privacy + * ---end--- + */ + obj_properties[PROP_ADDR_GEN_MODE] = + g_param_spec_int(NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, + "", + "", + G_MININT, + G_MAXINT, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIP6Config:token: + * + * Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02 + * IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode. + * + * Since: 1.4 + **/ + /* ---ifcfg-rh--- + * property: token + * variable: IPV6_TOKEN + * description: The IPv6 tokenized interface identifier token + * example: IPV6_TOKEN=::53 + * ---end--- + */ + obj_properties[PROP_TOKEN] = g_param_spec_string(NM_SETTING_IP6_CONFIG_TOKEN, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIP6Config:ra-timeout: + * + * A timeout for waiting Router Advertisements in seconds. If zero (the default), a + * globally configured default is used. If still unspecified, the timeout depends on the + * sysctl settings of the device. + * + * Set to 2147483647 (MAXINT32) for infinity. + * + * Since: 1.24 + **/ + /* ---ifcfg-rh--- + * property: dhcp-timeout + * variable: IPV6_RA_TIMEOUT(+) + * description: A timeout for waiting Router Advertisements in seconds. + * example: IPV6_RA_TIMEOUT=10 + * ---end--- + */ + + obj_properties[PROP_RA_TIMEOUT] = g_param_spec_int( + NM_SETTING_IP6_CONFIG_RA_TIMEOUT, + "", + "", + 0, + G_MAXINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIP6Config:dhcp-duid: + * + * A string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp + * client to identify itself to DHCPv6 servers (RFC 3315). The DUID is carried + * in the Client Identifier option. + * If the property is a hex string ('aa:bb:cc') it is interpreted as a binary + * DUID and filled as an opaque value in the Client Identifier option. + * + * The special value "lease" will retrieve the DUID previously used from the + * lease file belonging to the connection. If no DUID is found and "dhclient" + * is the configured dhcp client, the DUID is searched in the system-wide + * dhclient lease file. If still no DUID is found, or another dhcp client is + * used, a global and permanent DUID-UUID (RFC 6355) will be generated based + * on the machine-id. + * + * The special values "llt" and "ll" will generate a DUID of type LLT or LL + * (see RFC 3315) based on the current MAC address of the device. In order to + * try providing a stable DUID-LLT, the time field will contain a constant + * timestamp that is used globally (for all profiles) and persisted to disk. + * + * The special values "stable-llt", "stable-ll" and "stable-uuid" will generate + * a DUID of the corresponding type, derived from the connection's stable-id and + * a per-host unique key. You may want to include the "${DEVICE}" or "${MAC}" specifier + * in the stable-id, in case this profile gets activated on multiple devices. + * So, the link-layer address of "stable-ll" and "stable-llt" will be a generated + * address derived from the stable id. The DUID-LLT time value in the "stable-llt" + * option will be picked among a static timespan of three years (the upper bound + * of the interval is the same constant timestamp used in "llt"). + * + * When the property is unset, the global value provided for "ipv6.dhcp-duid" is + * used. If no global value is provided, the default "lease" value is assumed. + * + * Since: 1.12 + **/ + /* ---ifcfg-rh--- + * property: dhcp-duid + * variable: DHCPV6_DUID(+) + * description: A string sent to the DHCPv6 server to identify the local machine. + * Apart from the special values "lease", "stable-llt", "stable-ll", "stable-uuid", + * "llt" and "ll" a binary value in hex format is expected. An hex string where + * each octet is separated by a colon is also accepted. + * example: DHCPV6_DUID=LL; DHCPV6_DUID=0301deadbeef0001; DHCPV6_DUID=03:01:de:ad:be:ef:00:01 + * ---end--- + */ + obj_properties[PROP_DHCP_DUID] = + g_param_spec_string(NM_SETTING_IP6_CONFIG_DHCP_DUID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /* IP6-specific property overrides */ + + /* ---dbus--- + * property: dns + * format: array of byte array + * description: Array of IP addresses of DNS servers (in network byte order) + * ---end--- + */ + _nm_properties_override_gobj( + properties_override, + g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_DNS), + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aay"), + .gprop_to_dbus_fcn = ip6_dns_to_dbus, + .gprop_from_dbus_fcn = ip6_dns_from_dbus, )); + + /* ---dbus--- + * property: addresses + * format: array of legacy IPv6 address struct (a(ayuay)) + * description: Deprecated in favor of the 'address-data' and 'gateway' + * properties, but this can be used for backward-compatibility with older + * daemons. Note that if you send this property the daemon will ignore + * 'address-data' and 'gateway'. + * + * Array of IPv6 address structures. Each IPv6 address structure is + * composed of an IPv6 address, a prefix length (1 - 128), and an IPv6 + * gateway address. The gateway may be zeroed out if no gateway exists for + * that subnet. + * ---end--- + */ + _nm_properties_override_gobj( + properties_override, + g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_ADDRESSES), + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("a(ayuay)"), + .to_dbus_fcn = ip6_addresses_get, + .from_dbus_fcn = ip6_addresses_set, )); + + /* ---dbus--- + * property: address-data + * format: array of vardict + * description: Array of IPv6 addresses. Each address dictionary contains at + * least 'address' and 'prefix' entries, containing the IP address as a + * string, and the prefix length as a uint32. Additional attributes may + * also exist on some addresses. + * ---end--- + */ + _nm_properties_override_dbus( + properties_override, + "address-data", + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = ip6_address_data_get, + .from_dbus_fcn = ip6_address_data_set, )); + + /* ---dbus--- + * property: routes + * format: array of legacy IPv6 route struct (a(ayuayu)) + * description: Deprecated in favor of the 'route-data' property, but this + * can be used for backward-compatibility with older daemons. Note that if + * you send this property the daemon will ignore 'route-data'. + * + * Array of IPv6 route structures. Each IPv6 route structure is + * composed of an IPv6 address, a prefix length (1 - 128), an IPv6 + * next hop address (which may be zeroed out if there is no next hop), + * and a metric. If the metric is 0, NM will choose an appropriate + * default metric for the device. + * ---end--- + */ + _nm_properties_override_gobj( + properties_override, + g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_ROUTES), + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("a(ayuayu)"), + .to_dbus_fcn = ip6_routes_get, + .from_dbus_fcn = ip6_routes_set, )); + + /* ---dbus--- + * property: route-data + * format: array of vardict + * description: Array of IPv6 routes. Each route dictionary contains at + * least 'dest' and 'prefix' entries, containing the destination IP + * address as a string, and the prefix length as a uint32. Most routes + * will also have a 'next-hop' entry, containing the next hop IP address as + * a string. If the route has a 'metric' entry (containing a uint32), that + * will be used as the metric for the route (otherwise NM will pick a + * default value appropriate to the device). Additional attributes may + * also exist on some routes. + * ---end--- + */ + _nm_properties_override_dbus(properties_override, + "route-data", + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = ip6_route_data_get, + .from_dbus_fcn = ip6_route_data_set, )); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_IP6_CONFIG, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-macsec.c b/src/libnm-core-impl/nm-setting-macsec.c new file mode 100644 index 0000000..8cb0f28 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-macsec.c @@ -0,0 +1,670 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-macsec.h" + +#include + +#include "libnm-glib-aux/nm-secret-utils.h" + +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-setting-wired.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-macsec + * @short_description: Describes connection properties for MACSEC interfaces + * + * The #NMSettingMacsec object is a #NMSetting subclass that describes properties + * necessary for connection to MACsec (IEEE 802.1AE) interfaces. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, + PROP_MODE, + PROP_ENCRYPT, + PROP_MKA_CAK, + PROP_MKA_CAK_FLAGS, + PROP_MKA_CKN, + PROP_PORT, + PROP_VALIDATION, + PROP_SEND_SCI, ); + +typedef struct { + char * parent; + char * mka_cak; + char * mka_ckn; + int port; + NMSettingMacsecMode mode; + NMSettingSecretFlags mka_cak_flags; + NMSettingMacsecValidation validation; + bool encrypt : 1; + bool send_sci : 1; +} NMSettingMacsecPrivate; + +G_DEFINE_TYPE(NMSettingMacsec, nm_setting_macsec, NM_TYPE_SETTING) + +#define NM_SETTING_MACSEC_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_MACSEC, NMSettingMacsecPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_macsec_get_parent: + * @setting: the #NMSettingMacsec + * + * Returns: the #NMSettingMacsec:parent property of the setting + * + * Since: 1.6 + **/ +const char * +nm_setting_macsec_get_parent(NMSettingMacsec *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACSEC(setting), NULL); + return NM_SETTING_MACSEC_GET_PRIVATE(setting)->parent; +} + +/** + * nm_setting_macsec_get_mode: + * @setting: the #NMSettingMacsec + * + * Returns: the #NMSettingMacsec:mode property of the setting + * + * Since: 1.6 + **/ +NMSettingMacsecMode +nm_setting_macsec_get_mode(NMSettingMacsec *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACSEC(setting), NM_SETTING_MACSEC_MODE_PSK); + return NM_SETTING_MACSEC_GET_PRIVATE(setting)->mode; +} + +/** + * nm_setting_macsec_get_encrypt: + * @setting: the #NMSettingMacsec + * + * Returns: the #NMSettingMacsec:encrypt property of the setting + * + * Since: 1.6 + **/ +gboolean +nm_setting_macsec_get_encrypt(NMSettingMacsec *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACSEC(setting), TRUE); + return NM_SETTING_MACSEC_GET_PRIVATE(setting)->encrypt; +} + +/** + * nm_setting_macsec_get_mka_cak + * @setting: the #NMSettingMacsec + * + * Returns: the #NMSettingMacsec:mka-cak property of the setting + * + * Since: 1.6 + **/ +const char * +nm_setting_macsec_get_mka_cak(NMSettingMacsec *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACSEC(setting), NULL); + return NM_SETTING_MACSEC_GET_PRIVATE(setting)->mka_cak; +} + +/** + * nm_setting_macsec_get_mka_cak_flags: + * @setting: the #NMSettingMacsec + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingMacsec:mka-cak + * + * Since: 1.6 + **/ +NMSettingSecretFlags +nm_setting_macsec_get_mka_cak_flags(NMSettingMacsec *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACSEC(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_MACSEC_GET_PRIVATE(setting)->mka_cak_flags; +} + +/** + * nm_setting_macsec_get_mka_ckn: + * @setting: the #NMSettingMacsec + * + * Returns: the #NMSettingMacsec:mka-ckn property of the setting + * + * Since: 1.6 + **/ +const char * +nm_setting_macsec_get_mka_ckn(NMSettingMacsec *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACSEC(setting), NULL); + return NM_SETTING_MACSEC_GET_PRIVATE(setting)->mka_ckn; +} + +/** + * nm_setting_macsec_get_port: + * @setting: the #NMSettingMacsec + * + * Returns: the #NMSettingMacsec:port property of the setting + * + * Since: 1.6 + **/ +int +nm_setting_macsec_get_port(NMSettingMacsec *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACSEC(setting), 1); + return NM_SETTING_MACSEC_GET_PRIVATE(setting)->port; +} + +/** + * nm_setting_macsec_get_validation: + * @setting: the #NMSettingMacsec + * + * Returns: the #NMSettingMacsec:validation property of the setting + * + * Since: 1.6 + **/ +NMSettingMacsecValidation +nm_setting_macsec_get_validation(NMSettingMacsec *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACSEC(setting), NM_SETTING_MACSEC_VALIDATION_DISABLE); + return NM_SETTING_MACSEC_GET_PRIVATE(setting)->validation; +} + +/** + * nm_setting_macsec_get_send_sci: + * @setting: the #NMSettingMacsec + * + * Returns: the #NMSettingMacsec:send-sci property of the setting + * + * Since: 1.12 + **/ +gboolean +nm_setting_macsec_get_send_sci(NMSettingMacsec *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACSEC(setting), TRUE); + return NM_SETTING_MACSEC_GET_PRIVATE(setting)->send_sci; +} + +static GPtrArray * +need_secrets(NMSetting *setting) +{ + NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE(setting); + GPtrArray * secrets = NULL; + + if (priv->mode == NM_SETTING_MACSEC_MODE_PSK) { + if (!priv->mka_cak + && !NM_FLAGS_HAS(priv->mka_cak_flags, NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new(1); + g_ptr_array_add(secrets, NM_SETTING_MACSEC_MKA_CAK); + } + } + + return secrets; +} + +/*********************************************************************/ + +static gboolean +verify_macsec_key(const char *key, gboolean cak, GError **error) +{ + int req_len; + + /* CAK is a connection secret and can be NULL for various + * reasons (agent-owned, no permissions to get secrets, etc.) + */ + if (cak && !key) + return TRUE; + + if (!key || !key[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the key is empty")); + return FALSE; + } + + req_len = cak ? NM_SETTING_MACSEC_MKA_CAK_LENGTH : NM_SETTING_MACSEC_MKA_CKN_LENGTH; + if (strlen(key) != (gsize) req_len) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the key must be %d characters"), + req_len); + return FALSE; + } + + if (!NM_STRCHAR_ALL(key, ch, g_ascii_isxdigit(ch))) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the key contains non-hexadecimal characters")); + return FALSE; + } + + return TRUE; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE(setting); + NMSettingConnection * s_con = NULL; + NMSettingWired * s_wired = NULL; + NMSetting8021x * s_8021x = NULL; + + if (connection) { + s_con = nm_connection_get_setting_connection(connection); + s_wired = nm_connection_get_setting_wired(connection); + s_8021x = nm_connection_get_setting_802_1x(connection); + } + + if (priv->parent) { + if (nm_utils_is_uuid(priv->parent)) { + /* If we have an NMSettingConnection:master with slave-type="macsec", + * then it must be the same UUID. + */ + if (s_con) { + const char *master = NULL, *slave_type = NULL; + + slave_type = nm_setting_connection_get_slave_type(s_con); + if (!g_strcmp0(slave_type, NM_SETTING_MACSEC_SETTING_NAME)) + master = nm_setting_connection_get_master(s_con); + + if (master && g_strcmp0(priv->parent, master) != 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' value doesn't match '%s=%s'"), + priv->parent, + NM_SETTING_CONNECTION_MASTER, + master); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MACSEC_SETTING_NAME, + NM_SETTING_MACSEC_PARENT); + return FALSE; + } + } + } else if (!nm_utils_iface_valid_name(priv->parent)) { + /* parent must be either a UUID or an interface name */ + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MACSEC_SETTING_NAME, + NM_SETTING_MACSEC_PARENT); + return FALSE; + } + } else { + /* If parent is NULL, the parent must be specified via + * NMSettingWired:mac-address. + */ + if (connection && (!s_wired || !nm_setting_wired_get_mac_address(s_wired))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified and neither is '%s:%s'"), + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MACSEC_SETTING_NAME, + NM_SETTING_MACSEC_PARENT); + return FALSE; + } + } + + if (priv->mode == NM_SETTING_MACSEC_MODE_PSK) { + if (!verify_macsec_key(priv->mka_ckn, FALSE, error)) { + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MACSEC_SETTING_NAME, + NM_SETTING_MACSEC_MKA_CKN); + return FALSE; + } + if (!verify_macsec_key(priv->mka_cak, TRUE, error)) { + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MACSEC_SETTING_NAME, + NM_SETTING_MACSEC_MKA_CAK); + return FALSE; + } + } else if (priv->mode == NM_SETTING_MACSEC_MODE_EAP) { + if (!s_8021x) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("EAP key management requires '%s' setting presence"), + NM_SETTING_802_1X_SETTING_NAME); + g_prefix_error(error, "%s: ", NM_SETTING_MACSEC_SETTING_NAME); + return FALSE; + } + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("must be either psk (0) or eap (1)")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MODE); + return FALSE; + } + + if (priv->port <= 0 || priv->port > 65534) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("invalid port %d"), + priv->port); + g_prefix_error(error, "%s.%s: ", NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PORT); + return FALSE; + } + + if (priv->mode != NM_SETTING_MACSEC_MODE_PSK && (priv->mka_cak || priv->mka_ckn)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("only valid for psk mode")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MACSEC_SETTING_NAME, + priv->mka_cak ? NM_SETTING_MACSEC_MKA_CAK : NM_SETTING_MACSEC_MKA_CKN); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingMacsec * setting = NM_SETTING_MACSEC(object); + NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string(value, priv->parent); + break; + case PROP_MODE: + g_value_set_int(value, priv->mode); + break; + case PROP_ENCRYPT: + g_value_set_boolean(value, priv->encrypt); + break; + case PROP_MKA_CAK: + g_value_set_string(value, priv->mka_cak); + break; + case PROP_MKA_CAK_FLAGS: + g_value_set_flags(value, priv->mka_cak_flags); + break; + case PROP_MKA_CKN: + g_value_set_string(value, priv->mka_ckn); + break; + case PROP_PORT: + g_value_set_int(value, priv->port); + break; + case PROP_VALIDATION: + g_value_set_int(value, priv->validation); + break; + case PROP_SEND_SCI: + g_value_set_boolean(value, priv->send_sci); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingMacsec * setting = NM_SETTING_MACSEC(object); + NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_free(priv->parent); + priv->parent = g_value_dup_string(value); + break; + case PROP_MODE: + priv->mode = g_value_get_int(value); + break; + case PROP_ENCRYPT: + priv->encrypt = g_value_get_boolean(value); + break; + case PROP_MKA_CAK: + nm_free_secret(priv->mka_cak); + priv->mka_cak = g_value_dup_string(value); + break; + case PROP_MKA_CAK_FLAGS: + priv->mka_cak_flags = g_value_get_flags(value); + break; + case PROP_MKA_CKN: + g_free(priv->mka_ckn); + priv->mka_ckn = g_value_dup_string(value); + break; + case PROP_PORT: + priv->port = g_value_get_int(value); + break; + case PROP_VALIDATION: + priv->validation = g_value_get_int(value); + break; + case PROP_SEND_SCI: + priv->send_sci = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_macsec_init(NMSettingMacsec *self) +{ + NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE(self); + + nm_assert(priv->mode == NM_SETTING_MACSEC_MODE_PSK); + priv->encrypt = TRUE; + priv->port = 1; + priv->send_sci = TRUE; + priv->validation = NM_SETTING_MACSEC_VALIDATION_STRICT; +} + +/** + * nm_setting_macsec_new: + * + * Creates a new #NMSettingMacsec object with default values. + * + * Returns: (transfer full): the new empty #NMSettingMacsec object + * + * Since: 1.6 + **/ +NMSetting * +nm_setting_macsec_new(void) +{ + return g_object_new(NM_TYPE_SETTING_MACSEC, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingMacsec * setting = NM_SETTING_MACSEC(object); + NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE(setting); + + g_free(priv->parent); + nm_free_secret(priv->mka_cak); + g_free(priv->mka_ckn); + + G_OBJECT_CLASS(nm_setting_macsec_parent_class)->finalize(object); +} + +static void +nm_setting_macsec_class_init(NMSettingMacsecClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingMacsecPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->need_secrets = need_secrets; + + /** + * NMSettingMacsec:parent: + * + * If given, specifies the parent interface name or parent connection UUID + * from which this MACSEC interface should be created. If this property is + * not specified, the connection must contain an #NMSettingWired setting + * with a #NMSettingWired:mac-address property. + * + * Since: 1.6 + **/ + obj_properties[PROP_PARENT] = g_param_spec_string( + NM_SETTING_MACSEC_PARENT, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacsec:mode: + * + * Specifies how the CAK (Connectivity Association Key) for MKA (MACsec Key + * Agreement) is obtained. + * + * Since: 1.6 + **/ + obj_properties[PROP_MODE] = + g_param_spec_int(NM_SETTING_MACSEC_MODE, + "", + "", + G_MININT, + G_MAXINT, + NM_SETTING_MACSEC_MODE_PSK, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacsec:encrypt: + * + * Whether the transmitted traffic must be encrypted. + * + * Since: 1.6 + **/ + obj_properties[PROP_ENCRYPT] = g_param_spec_boolean(NM_SETTING_MACSEC_ENCRYPT, + "", + "", + TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacsec:mka-cak: + * + * The pre-shared CAK (Connectivity Association Key) for MACsec + * Key Agreement. + * + * Since: 1.6 + **/ + obj_properties[PROP_MKA_CAK] = + g_param_spec_string(NM_SETTING_MACSEC_MKA_CAK, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacsec:mka-cak-flags: + * + * Flags indicating how to handle the #NMSettingMacsec:mka-cak + * property. + * + * Since: 1.6 + **/ + obj_properties[PROP_MKA_CAK_FLAGS] = + g_param_spec_flags(NM_SETTING_MACSEC_MKA_CAK_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacsec:mka-ckn: + * + * The pre-shared CKN (Connectivity-association Key Name) for + * MACsec Key Agreement. + * + * Since: 1.6 + **/ + obj_properties[PROP_MKA_CKN] = g_param_spec_string(NM_SETTING_MACSEC_MKA_CKN, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacsec:port: + * + * The port component of the SCI (Secure Channel Identifier), between 1 and 65534. + * + * Since: 1.6 + **/ + obj_properties[PROP_PORT] = + g_param_spec_int(NM_SETTING_MACSEC_PORT, + "", + "", + 1, + 65534, + 1, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacsec:validation: + * + * Specifies the validation mode for incoming frames. + * + * Since: 1.6 + **/ + obj_properties[PROP_VALIDATION] = + g_param_spec_int(NM_SETTING_MACSEC_VALIDATION, + "", + "", + G_MININT, + G_MAXINT, + NM_SETTING_MACSEC_VALIDATION_STRICT, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacsec:send-sci: + * + * Specifies whether the SCI (Secure Channel Identifier) is included + * in every packet. + * + * Since: 1.12 + **/ + obj_properties[PROP_SEND_SCI] = + g_param_spec_boolean(NM_SETTING_MACSEC_SEND_SCI, + "", + "", + TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_MACSEC); +} diff --git a/src/libnm-core-impl/nm-setting-macvlan.c b/src/libnm-core-impl/nm-setting-macvlan.c new file mode 100644 index 0000000..0e6414b --- /dev/null +++ b/src/libnm-core-impl/nm-setting-macvlan.c @@ -0,0 +1,332 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-macvlan.h" + +#include + +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-setting-wired.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-macvlan + * @short_description: Describes connection properties for macvlan interfaces + * + * The #NMSettingMacvlan object is a #NMSetting subclass that describes properties + * necessary for connection to macvlan interfaces. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, PROP_MODE, PROP_PROMISCUOUS, PROP_TAP, ); + +typedef struct { + char * parent; + NMSettingMacvlanMode mode; + bool promiscuous : 1; + bool tap : 1; +} NMSettingMacvlanPrivate; + +G_DEFINE_TYPE(NMSettingMacvlan, nm_setting_macvlan, NM_TYPE_SETTING) + +#define NM_SETTING_MACVLAN_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_macvlan_get_parent: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:parent property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_macvlan_get_parent(NMSettingMacvlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACVLAN(setting), NULL); + return NM_SETTING_MACVLAN_GET_PRIVATE(setting)->parent; +} + +/** + * nm_setting_macvlan_get_mode: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:mode property of the setting + * + * Since: 1.2 + **/ +NMSettingMacvlanMode +nm_setting_macvlan_get_mode(NMSettingMacvlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACVLAN(setting), NM_SETTING_MACVLAN_MODE_UNKNOWN); + return NM_SETTING_MACVLAN_GET_PRIVATE(setting)->mode; +} + +/** + * nm_setting_macvlan_get_promiscuous: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:promiscuous property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_macvlan_get_promiscuous(NMSettingMacvlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACVLAN(setting), FALSE); + return NM_SETTING_MACVLAN_GET_PRIVATE(setting)->promiscuous; +} + +/** + * nm_setting_macvlan_get_tap: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:tap property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_macvlan_get_tap(NMSettingMacvlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MACVLAN(setting), FALSE); + return NM_SETTING_MACVLAN_GET_PRIVATE(setting)->tap; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE(setting); + NMSettingWired * s_wired; + + if (connection) + s_wired = nm_connection_get_setting_wired(connection); + else + s_wired = NULL; + + if (priv->parent) { + if (!nm_utils_is_uuid(priv->parent) && !nm_utils_ifname_valid_kernel(priv->parent, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MACVLAN_SETTING_NAME, + NM_SETTING_MACVLAN_PARENT); + return FALSE; + } + } else { + /* If parent is NULL, the parent must be specified via + * NMSettingWired:mac-address. + */ + if (connection && (!s_wired || !nm_setting_wired_get_mac_address(s_wired))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified and neither is '%s:%s'"), + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MACVLAN_SETTING_NAME, + NM_SETTING_MACVLAN_PARENT); + return FALSE; + } + } + + if (!priv->promiscuous && priv->mode != NM_SETTING_MACVLAN_MODE_PASSTHRU) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("non promiscuous operation is allowed only in passthru mode")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MACVLAN_SETTING_NAME, + NM_SETTING_MACVLAN_PROMISCUOUS); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingMacvlan * setting = NM_SETTING_MACVLAN(object); + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string(value, priv->parent); + break; + case PROP_MODE: + g_value_set_uint(value, priv->mode); + break; + case PROP_PROMISCUOUS: + g_value_set_boolean(value, priv->promiscuous); + break; + case PROP_TAP: + g_value_set_boolean(value, priv->tap); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingMacvlan * setting = NM_SETTING_MACVLAN(object); + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_free(priv->parent); + priv->parent = g_value_dup_string(value); + break; + case PROP_MODE: + priv->mode = g_value_get_uint(value); + break; + case PROP_PROMISCUOUS: + priv->promiscuous = g_value_get_boolean(value); + break; + case PROP_TAP: + priv->tap = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_macvlan_init(NMSettingMacvlan *self) +{ + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE(self); + + priv->promiscuous = TRUE; +} + +/** + * nm_setting_macvlan_new: + * + * Creates a new #NMSettingMacvlan object with default values. + * + * Returns: (transfer full): the new empty #NMSettingMacvlan object + * + * Since: 1.2 + **/ +NMSetting * +nm_setting_macvlan_new(void) +{ + return g_object_new(NM_TYPE_SETTING_MACVLAN, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingMacvlan * setting = NM_SETTING_MACVLAN(object); + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE(setting); + + g_free(priv->parent); + + G_OBJECT_CLASS(nm_setting_macvlan_parent_class)->finalize(object); +} + +static void +nm_setting_macvlan_class_init(NMSettingMacvlanClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingMacvlanPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingMacvlan:parent: + * + * If given, specifies the parent interface name or parent connection UUID + * from which this MAC-VLAN interface should be created. If this property is + * not specified, the connection must contain an #NMSettingWired setting + * with a #NMSettingWired:mac-address property. + * + * Since: 1.2 + **/ + obj_properties[PROP_PARENT] = g_param_spec_string( + NM_SETTING_MACVLAN_PARENT, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacvlan:mode: + * + * The macvlan mode, which specifies the communication mechanism between multiple + * macvlans on the same lower device. + * + * Since: 1.2 + **/ + obj_properties[PROP_MODE] = + g_param_spec_uint(NM_SETTING_MACVLAN_MODE, + "", + "", + 0, + G_MAXUINT, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacvlan:promiscuous: + * + * Whether the interface should be put in promiscuous mode. + * + * Since: 1.2 + **/ + obj_properties[PROP_PROMISCUOUS] = g_param_spec_boolean( + NM_SETTING_MACVLAN_PROMISCUOUS, + "", + "", + TRUE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMacvlan:tap: + * + * Whether the interface should be a MACVTAP. + * + * Since: 1.2 + **/ + obj_properties[PROP_TAP] = g_param_spec_boolean(NM_SETTING_MACVLAN_TAP, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_MACVLAN); +} diff --git a/src/libnm-core-impl/nm-setting-match.c b/src/libnm-core-impl/nm-setting-match.c new file mode 100644 index 0000000..9efca1e --- /dev/null +++ b/src/libnm-core-impl/nm-setting-match.c @@ -0,0 +1,912 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-match.h" + +#include "nm-setting-private.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-match + * @short_description: Properties to match a connection with a device. + * @include: nm-setting-match.h + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingMatch, + PROP_INTERFACE_NAME, + PROP_KERNEL_COMMAND_LINE, + PROP_DRIVER, + PROP_PATH, ); + +/** + * NMSettingMatch: + * + * Match settings + * + * Since: 1.14 + */ +struct _NMSettingMatch { + NMSetting parent; + GArray * interface_name; + GArray * kernel_command_line; + GArray * driver; + GArray * path; +}; + +struct _NMSettingMatchClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingMatch, nm_setting_match, NM_TYPE_SETTING) + +/*****************************************************************************/ + +/** + * nm_setting_match_get_num_interface_names: + * @setting: the #NMSettingMatch + * + * Returns: the number of configured interface names + * + * Since: 1.14 + **/ +guint +nm_setting_match_get_num_interface_names(NMSettingMatch *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), 0); + + return nm_g_array_len(setting->interface_name); +} + +/** + * nm_setting_match_get_interface_name: + * @setting: the #NMSettingMatch + * @idx: index number of the DNS search domain to return + * + * Returns: the interface name at index @idx + * + * Since: 1.14 + **/ +const char * +nm_setting_match_get_interface_name(NMSettingMatch *setting, int idx) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); + + g_return_val_if_fail(setting->interface_name && idx >= 0 && idx < setting->interface_name->len, + NULL); + + return g_array_index(setting->interface_name, const char *, idx); +} + +/** + * nm_setting_match_add_interface_name: + * @setting: the #NMSettingMatch + * @interface_name: the interface name to add + * + * Adds a new interface name to the setting. + * + * Since: 1.14 + **/ +void +nm_setting_match_add_interface_name(NMSettingMatch *setting, const char *interface_name) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + g_return_if_fail(interface_name != NULL); + g_return_if_fail(interface_name[0] != '\0'); + + nm_strvarray_add(nm_strvarray_ensure(&setting->interface_name), interface_name); + _notify(setting, PROP_INTERFACE_NAME); +} + +/** + * nm_setting_match_remove_interface_name: + * @setting: the #NMSettingMatch + * @idx: index number of the interface name + * + * Removes the interface name at index @idx. + * + * Since: 1.14 + **/ +void +nm_setting_match_remove_interface_name(NMSettingMatch *setting, int idx) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + + g_return_if_fail(setting->interface_name && idx >= 0 && idx < setting->interface_name->len); + + g_array_remove_index(setting->interface_name, idx); + _notify(setting, PROP_INTERFACE_NAME); +} + +/** + * nm_setting_match_remove_interface_name_by_value: + * @setting: the #NMSettingMatch + * @interface_name: the interface name to remove + * + * Removes @interface_name. + * + * Returns: %TRUE if the interface name was found and removed; %FALSE if it was not. + * + * Since: 1.14 + **/ +gboolean +nm_setting_match_remove_interface_name_by_value(NMSettingMatch *setting, const char *interface_name) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE); + g_return_val_if_fail(interface_name != NULL, FALSE); + g_return_val_if_fail(interface_name[0] != '\0', FALSE); + + if (nm_strvarray_remove_first(setting->interface_name, interface_name)) { + _notify(setting, PROP_INTERFACE_NAME); + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_match_clear_interface_names: + * @setting: the #NMSettingMatch + * + * Removes all configured interface names. + * + * Since: 1.14 + **/ +void +nm_setting_match_clear_interface_names(NMSettingMatch *setting) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + + if (nm_g_array_len(setting->interface_name) != 0) { + nm_clear_pointer(&setting->interface_name, g_array_unref); + _notify(setting, PROP_INTERFACE_NAME); + } +} + +/** + * nm_setting_match_get_interface_names: + * @setting: the #NMSettingMatch + * @length: (out) (allow-none): the length of the returned interface names array. + * + * Returns all the interface names. + * + * Returns: (transfer none) (array length=length): the NULL terminated list of + * configured interface names. + * + * Before 1.26, the returned array was not %NULL terminated and you MUST provide a length. + * + * Since: 1.14 + **/ +const char *const * +nm_setting_match_get_interface_names(NMSettingMatch *setting, guint *length) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); + + return nm_strvarray_get_strv(&setting->interface_name, length); +} + +/*****************************************************************************/ + +/** + * nm_setting_match_get_num_kernel_command_lines: + * @setting: the #NMSettingMatch + * + * Returns: the number of configured kernel command line arguments + * + * Since: 1.26 + **/ +guint +nm_setting_match_get_num_kernel_command_lines(NMSettingMatch *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), 0); + + return nm_g_array_len(setting->kernel_command_line); +} + +/** + * nm_setting_match_get_kernel_command_line: + * @setting: the #NMSettingMatch + * @idx: index number of the kernel command line argument to return + * + * Returns: the kernel command line argument at index @idx + * + * Since: 1.26 + **/ +const char * +nm_setting_match_get_kernel_command_line(NMSettingMatch *setting, guint idx) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); + + g_return_val_if_fail(setting->kernel_command_line && idx < setting->kernel_command_line->len, + NULL); + + return g_array_index(setting->kernel_command_line, const char *, idx); +} + +/** + * nm_setting_match_add_kernel_command_line: + * @setting: the #NMSettingMatch + * @kernel_command_line: the kernel command line argument to add + * + * Adds a new kernel command line argument to the setting. + * + * Since: 1.26 + **/ +void +nm_setting_match_add_kernel_command_line(NMSettingMatch *setting, const char *kernel_command_line) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + g_return_if_fail(kernel_command_line != NULL); + g_return_if_fail(kernel_command_line[0] != '\0'); + + nm_strvarray_add(nm_strvarray_ensure(&setting->kernel_command_line), kernel_command_line); + _notify(setting, PROP_KERNEL_COMMAND_LINE); +} + +/** + * nm_setting_match_remove_kernel_command_line: + * @setting: the #NMSettingMatch + * @idx: index number of the kernel command line argument + * + * Removes the kernel command line argument at index @idx. + * + * Since: 1.26 + **/ +void +nm_setting_match_remove_kernel_command_line(NMSettingMatch *setting, guint idx) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + + g_return_if_fail(setting->kernel_command_line && idx < setting->kernel_command_line->len); + + g_array_remove_index(setting->kernel_command_line, idx); + _notify(setting, PROP_KERNEL_COMMAND_LINE); +} + +/** + * nm_setting_match_remove_kernel_command_line_by_value: + * @setting: the #NMSettingMatch + * @kernel_command_line: the kernel command line argument name to remove + * + * Removes @kernel_command_line. + * + * Returns: %TRUE if the kernel command line argument was found and removed; %FALSE if it was not. + * + * Since: 1.26 + **/ +gboolean +nm_setting_match_remove_kernel_command_line_by_value(NMSettingMatch *setting, + const char * kernel_command_line) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE); + g_return_val_if_fail(kernel_command_line != NULL, FALSE); + g_return_val_if_fail(kernel_command_line[0] != '\0', FALSE); + + if (nm_strvarray_remove_first(setting->kernel_command_line, kernel_command_line)) { + _notify(setting, PROP_KERNEL_COMMAND_LINE); + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_match_clear_kernel_command_lines: + * @setting: the #NMSettingMatch + * + * Removes all configured kernel command line arguments. + * + * Since: 1.26 + **/ +void +nm_setting_match_clear_kernel_command_lines(NMSettingMatch *setting) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + + if (nm_g_array_len(setting->kernel_command_line) != 0) { + nm_clear_pointer(&setting->kernel_command_line, g_array_unref); + _notify(setting, PROP_KERNEL_COMMAND_LINE); + } +} + +/** + * nm_setting_match_get_kernel_command_lines: + * @setting: the #NMSettingMatch + * @length: (out) (allow-none): the length of the returned interface names array. + * + * Returns all the interface names. + * + * Returns: (transfer none) (array length=length): the configured interface names. + * + * Since: 1.26 + **/ +const char *const * +nm_setting_match_get_kernel_command_lines(NMSettingMatch *setting, guint *length) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); + + return nm_strvarray_get_strv(&setting->kernel_command_line, length); +} + +/*****************************************************************************/ + +/** + * nm_setting_match_get_num_drivers: + * @setting: the #NMSettingMatch + * + * Returns: the number of configured drivers + * + * Since: 1.26 + **/ +guint +nm_setting_match_get_num_drivers(NMSettingMatch *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), 0); + + return nm_g_array_len(setting->driver); +} + +/** + * nm_setting_match_get_driver: + * @setting: the #NMSettingMatch + * @idx: index number of the DNS search domain to return + * + * Returns: the driver at index @idx + * + * Since: 1.26 + **/ +const char * +nm_setting_match_get_driver(NMSettingMatch *setting, guint idx) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); + + g_return_val_if_fail(setting->driver && idx < setting->driver->len, NULL); + + return g_array_index(setting->driver, const char *, idx); +} + +/** + * nm_setting_match_add_driver: + * @setting: the #NMSettingMatch + * @driver: the driver to add + * + * Adds a new driver to the setting. + * + * Since: 1.26 + **/ +void +nm_setting_match_add_driver(NMSettingMatch *setting, const char *driver) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + g_return_if_fail(driver != NULL); + g_return_if_fail(driver[0] != '\0'); + + nm_strvarray_add(nm_strvarray_ensure(&setting->driver), driver); + _notify(setting, PROP_DRIVER); +} + +/** + * nm_setting_match_remove_driver: + * @setting: the #NMSettingMatch + * @idx: index number of the driver + * + * Removes the driver at index @idx. + * + * Since: 1.26 + **/ +void +nm_setting_match_remove_driver(NMSettingMatch *setting, guint idx) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + + g_return_if_fail(setting->driver && idx < setting->driver->len); + + g_array_remove_index(setting->driver, idx); + _notify(setting, PROP_DRIVER); +} + +/** + * nm_setting_match_remove_driver_by_value: + * @setting: the #NMSettingMatch + * @driver: the driver to remove + * + * Removes @driver. + * + * Returns: %TRUE if the driver was found and removed; %FALSE if it was not. + * + * Since: 1.26 + **/ +gboolean +nm_setting_match_remove_driver_by_value(NMSettingMatch *setting, const char *driver) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE); + g_return_val_if_fail(driver != NULL, FALSE); + g_return_val_if_fail(driver[0] != '\0', FALSE); + + if (nm_strvarray_remove_first(setting->driver, driver)) { + _notify(setting, PROP_DRIVER); + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_match_clear_drivers: + * @setting: the #NMSettingMatch + * + * Removes all configured drivers. + * + * Since: 1.26 + **/ +void +nm_setting_match_clear_drivers(NMSettingMatch *setting) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + + if (nm_g_array_len(setting->driver) != 0) { + nm_clear_pointer(&setting->driver, g_array_unref); + _notify(setting, PROP_DRIVER); + } +} + +/** + * nm_setting_match_get_drivers: + * @setting: the #NMSettingMatch + * @length: (out) (allow-none): the length of the returned interface names array. + * + * Returns all the drivers. + * + * Returns: (transfer none) (array length=length): the configured drivers. + * + * Since: 1.26 + **/ +const char *const * +nm_setting_match_get_drivers(NMSettingMatch *setting, guint *length) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); + + return nm_strvarray_get_strv(&setting->driver, length); +} + +/*****************************************************************************/ + +/** + * nm_setting_match_get_num_paths: + * @setting: the #NMSettingMatch + * + * Returns: the number of configured paths + * + * Since: 1.26 + **/ +guint +nm_setting_match_get_num_paths(NMSettingMatch *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), 0); + + return nm_g_array_len(setting->path); +} + +/** + * nm_setting_match_get_path: + * @setting: the #NMSettingMatch + * @idx: index number of the path to return + * + * Returns: the path at index @idx + * + * Since: 1.26 + **/ +const char * +nm_setting_match_get_path(NMSettingMatch *setting, guint idx) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); + + g_return_val_if_fail(setting->path && idx < setting->path->len, NULL); + + return g_array_index(setting->path, const char *, idx); +} + +/** + * nm_setting_match_add_path: + * @setting: the #NMSettingMatch + * @path: the path to add + * + * Adds a new path to the setting. + * + * Since: 1.26 + **/ +void +nm_setting_match_add_path(NMSettingMatch *setting, const char *path) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + g_return_if_fail(path != NULL); + g_return_if_fail(path[0] != '\0'); + + nm_strvarray_add(nm_strvarray_ensure(&setting->path), path); + _notify(setting, PROP_PATH); +} + +/** + * nm_setting_match_remove_path: + * @setting: the #NMSettingMatch + * @idx: index number of the path + * + * Removes the path at index @idx. + * + * Since: 1.26 + **/ +void +nm_setting_match_remove_path(NMSettingMatch *setting, guint idx) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + + g_return_if_fail(setting->path && idx < setting->path->len); + + g_array_remove_index(setting->path, idx); + _notify(setting, PROP_PATH); +} + +/** + * nm_setting_match_remove_path_by_value: + * @setting: the #NMSettingMatch + * @path: the path to remove + * + * Removes @path. + * + * Returns: %TRUE if the path was found and removed; %FALSE if it was not. + * + * Since: 1.26 + **/ +gboolean +nm_setting_match_remove_path_by_value(NMSettingMatch *setting, const char *path) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE); + g_return_val_if_fail(path != NULL, FALSE); + g_return_val_if_fail(path[0] != '\0', FALSE); + + if (nm_strvarray_remove_first(setting->path, path)) { + _notify(setting, PROP_PATH); + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_match_clear_paths: + * @setting: the #NMSettingMatch + * + * Removes all configured paths. + * + * Since: 1.26 + **/ +void +nm_setting_match_clear_paths(NMSettingMatch *setting) +{ + g_return_if_fail(NM_IS_SETTING_MATCH(setting)); + + if (nm_g_array_len(setting->path) != 0) { + nm_clear_pointer(&setting->path, g_array_unref); + _notify(setting, PROP_PATH); + } +} + +/** + * nm_setting_match_get_paths: + * @setting: the #NMSettingMatch + * @length: (out) (allow-none): the length of the returned paths array. + * + * Returns all the paths. + * + * Returns: (transfer none) (array length=length): the configured paths. + * + * Since: 1.26 + **/ +const char *const * +nm_setting_match_get_paths(NMSettingMatch *setting, guint *length) +{ + g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); + + return nm_strvarray_get_strv(&setting->path, length); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingMatch *self = NM_SETTING_MATCH(object); + + switch (prop_id) { + case PROP_INTERFACE_NAME: + g_value_set_boxed(value, nm_strvarray_get_strv_non_empty(self->interface_name, NULL)); + break; + case PROP_KERNEL_COMMAND_LINE: + g_value_set_boxed(value, nm_strvarray_get_strv_non_empty(self->kernel_command_line, NULL)); + break; + case PROP_DRIVER: + g_value_set_boxed(value, nm_strvarray_get_strv_non_empty(self->driver, NULL)); + break; + case PROP_PATH: + g_value_set_boxed(value, nm_strvarray_get_strv_non_empty(self->path, NULL)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingMatch *self = NM_SETTING_MATCH(object); + + switch (prop_id) { + case PROP_INTERFACE_NAME: + nm_strvarray_set_strv(&self->interface_name, g_value_get_boxed(value)); + break; + case PROP_KERNEL_COMMAND_LINE: + nm_strvarray_set_strv(&self->kernel_command_line, g_value_get_boxed(value)); + break; + case PROP_DRIVER: + nm_strvarray_set_strv(&self->driver, g_value_get_boxed(value)); + break; + case PROP_PATH: + nm_strvarray_set_strv(&self->path, g_value_get_boxed(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_match_init(NMSettingMatch *setting) +{} + +/** + * nm_setting_match_new: + * + * Creates a new #NMSettingMatch object with default values. + * + * Returns: (transfer full): the new empty #NMSettingMatch object + * + * Note that this function was present in header files since version 1.14. + * But due to a bug the symbol is only exposed and usable since version 1.32. + * As workaround, use g_object_new(NM_TYPE_SETTING_MATCH) which works with all + * versions since 1.14. + * + * Since: 1.32 + **/ +NMSetting * +nm_setting_match_new(void) +{ + /* Note that function nm_setting_match_new() was libnm headers from 1.14+, + * but due to a bug was the symbol only exposed since version 1.32+. + * + * The workaround is to always use g_object_new(), which works for all + * versions since 1.14. + * + * As such, this function must never do anything except calling + * g_object_new() to not break the workaround. */ + return g_object_new(NM_TYPE_SETTING_MATCH, NULL); +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingMatch *self = NM_SETTING_MATCH(setting); + guint i; + + if (self->interface_name) { + for (i = 0; i < self->interface_name->len; i++) { + if (nm_str_is_empty(g_array_index(self->interface_name, const char *, i))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MATCH_SETTING_NAME, + NM_SETTING_MATCH_INTERFACE_NAME); + return FALSE; + } + } + } + + if (self->kernel_command_line) { + for (i = 0; i < self->kernel_command_line->len; i++) { + if (nm_str_is_empty(g_array_index(self->kernel_command_line, const char *, i))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MATCH_SETTING_NAME, + NM_SETTING_MATCH_KERNEL_COMMAND_LINE); + return FALSE; + } + } + } + + if (self->driver) { + for (i = 0; i < self->driver->len; i++) { + if (nm_str_is_empty(g_array_index(self->driver, const char *, i))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MATCH_SETTING_NAME, + NM_SETTING_MATCH_DRIVER); + return FALSE; + } + } + } + + if (self->path) { + for (i = 0; i < self->path->len; i++) { + if (nm_str_is_empty(g_array_index(self->path, const char *, i))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_MATCH_SETTING_NAME, + NM_SETTING_MATCH_PATH); + return FALSE; + } + } + } + + return TRUE; +} + +static void +finalize(GObject *object) +{ + NMSettingMatch *self = NM_SETTING_MATCH(object); + + nm_clear_pointer(&self->interface_name, g_array_unref); + nm_clear_pointer(&self->kernel_command_line, g_array_unref); + nm_clear_pointer(&self->driver, g_array_unref); + nm_clear_pointer(&self->path, g_array_unref); + + G_OBJECT_CLASS(nm_setting_match_parent_class)->finalize(object); +} + +static void +nm_setting_match_class_init(NMSettingMatchClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingMatch:interface-name + * + * A list of interface names to match. Each element is a shell wildcard + * pattern. + * + * An element can be prefixed with a pipe symbol (|) or an ampersand (&). + * The former means that the element is optional and the latter means that + * it is mandatory. If there are any optional elements, than the match + * evaluates to true if at least one of the optional element matches + * (logical OR). If there are any mandatory elements, then they all + * must match (logical AND). By default, an element is optional. This means + * that an element "foo" behaves the same as "|foo". An element can also be inverted + * with exclamation mark (!) between the pipe symbol (or the ampersand) and before + * the pattern. Note that "!foo" is a shortcut for the mandatory match "&!foo". Finally, + * a backslash can be used at the beginning of the element (after the optional special characters) + * to escape the start of the pattern. For example, "&\\!a" is an mandatory match for literally "!a". + * + * Since: 1.14 + **/ + obj_properties[PROP_INTERFACE_NAME] = g_param_spec_boxed( + NM_SETTING_MATCH_INTERFACE_NAME, + "", + "", + G_TYPE_STRV, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMatch:kernel-command-line + * + * A list of kernel command line arguments to match. This may be used to check + * whether a specific kernel command line option is set (or unset, if prefixed with + * the exclamation mark). The argument must either be a single word, or + * an assignment (i.e. two words, joined by "="). In the former case the kernel + * command line is searched for the word appearing as is, or as left hand side + * of an assignment. In the latter case, the exact assignment is looked for + * with right and left hand side matching. Wildcard patterns are not supported. + * + * See NMSettingMatch:interface-name for how special characters '|', '&', + * '!' and '\\' are used for optional and mandatory matches and inverting the + * match. + * + * Since: 1.26 + **/ + obj_properties[PROP_KERNEL_COMMAND_LINE] = g_param_spec_boxed( + NM_SETTING_MATCH_KERNEL_COMMAND_LINE, + "", + "", + G_TYPE_STRV, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMatch:driver + * + * A list of driver names to match. Each element is a shell wildcard pattern. + * + * See NMSettingMatch:interface-name for how special characters '|', '&', + * '!' and '\\' are used for optional and mandatory matches and inverting the + * pattern. + * + * Since: 1.26 + **/ + obj_properties[PROP_DRIVER] = g_param_spec_boxed( + NM_SETTING_MATCH_DRIVER, + "", + "", + G_TYPE_STRV, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingMatch:path + * + * A list of paths to match against the ID_PATH udev property of + * devices. ID_PATH represents the topological persistent path of a + * device. It typically contains a subsystem string (pci, usb, platform, + * etc.) and a subsystem-specific identifier. + * + * For PCI devices the path has the form + * "pci-$domain:$bus:$device.$function", where each variable is an + * hexadecimal value; for example "pci-0000:0a:00.0". + * + * The path of a device can be obtained with "udevadm info + * /sys/class/net/$dev | grep ID_PATH=" or by looking at the "path" + * property exported by NetworkManager ("nmcli -f general.path device + * show $dev"). + * + * Each element of the list is a shell wildcard pattern. + * + * See NMSettingMatch:interface-name for how special characters '|', '&', + * '!' and '\\' are used for optional and mandatory matches and inverting the + * pattern. + * + * Since: 1.26 + **/ + /* ---ifcfg-rh--- + * property: path + * variable: MATCH_PATH + * description: space-separated list of paths to match against the udev + * property ID_PATHS of devices + * example: MATCH_PATH="pci-0000:01:00.0 pci-0000:0c:00.0" + * ---end--- + */ + obj_properties[PROP_PATH] = g_param_spec_boxed(NM_SETTING_MATCH_PATH, + "", + "", + G_TYPE_STRV, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE + | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_MATCH); +} diff --git a/src/libnm-core-impl/nm-setting-olpc-mesh.c b/src/libnm-core-impl/nm-setting-olpc-mesh.c new file mode 100644 index 0000000..04e24ff --- /dev/null +++ b/src/libnm-core-impl/nm-setting-olpc-mesh.c @@ -0,0 +1,274 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2009 One Laptop per Child + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-olpc-mesh.h" + +#include + +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-olpc-mesh + * @short_description: Describes connection properties for OLPC-Mesh devices + * + * The #NMSettingOlpcMesh object is a #NMSetting subclass that describes properties + * necessary for connection to OLPC-Mesh devices. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_SSID, PROP_CHANNEL, PROP_DHCP_ANYCAST_ADDRESS, ); + +typedef struct { + GBytes *ssid; + char * dhcp_anycast_addr; + guint32 channel; +} NMSettingOlpcMeshPrivate; + +G_DEFINE_TYPE(NMSettingOlpcMesh, nm_setting_olpc_mesh, NM_TYPE_SETTING) + +#define NM_SETTING_OLPC_MESH_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_OLPC_MESH, NMSettingOlpcMeshPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_olpc_mesh_get_ssid: + * @setting: the #NMSettingOlpcMesh + * + * Returns: (transfer none): + */ +GBytes * +nm_setting_olpc_mesh_get_ssid(NMSettingOlpcMesh *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_OLPC_MESH(setting), NULL); + + return NM_SETTING_OLPC_MESH_GET_PRIVATE(setting)->ssid; +} + +guint32 +nm_setting_olpc_mesh_get_channel(NMSettingOlpcMesh *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_OLPC_MESH(setting), 0); + + return NM_SETTING_OLPC_MESH_GET_PRIVATE(setting)->channel; +} + +const char * +nm_setting_olpc_mesh_get_dhcp_anycast_address(NMSettingOlpcMesh *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_OLPC_MESH(setting), NULL); + + return NM_SETTING_OLPC_MESH_GET_PRIVATE(setting)->dhcp_anycast_addr; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingOlpcMeshPrivate *priv = NM_SETTING_OLPC_MESH_GET_PRIVATE(setting); + gsize length; + + if (!priv->ssid) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OLPC_MESH_SETTING_NAME, + NM_SETTING_OLPC_MESH_SSID); + return FALSE; + } + + length = g_bytes_get_size(priv->ssid); + if (length == 0 || length > 32) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("SSID length is out of range <1-32> bytes")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OLPC_MESH_SETTING_NAME, + NM_SETTING_OLPC_MESH_SSID); + return FALSE; + } + + if (priv->channel == 0 || priv->channel > 13) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' is not a valid channel"), + priv->channel); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OLPC_MESH_SETTING_NAME, + NM_SETTING_OLPC_MESH_CHANNEL); + return FALSE; + } + + if (priv->dhcp_anycast_addr && !nm_utils_hwaddr_valid(priv->dhcp_anycast_addr, ETH_ALEN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OLPC_MESH_SETTING_NAME, + NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingOlpcMesh *setting = NM_SETTING_OLPC_MESH(object); + + switch (prop_id) { + case PROP_SSID: + g_value_set_boxed(value, nm_setting_olpc_mesh_get_ssid(setting)); + break; + case PROP_CHANNEL: + g_value_set_uint(value, nm_setting_olpc_mesh_get_channel(setting)); + break; + case PROP_DHCP_ANYCAST_ADDRESS: + g_value_set_string(value, nm_setting_olpc_mesh_get_dhcp_anycast_address(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingOlpcMeshPrivate *priv = NM_SETTING_OLPC_MESH_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_SSID: + if (priv->ssid) + g_bytes_unref(priv->ssid); + priv->ssid = g_value_dup_boxed(value); + break; + case PROP_CHANNEL: + priv->channel = g_value_get_uint(value); + break; + case PROP_DHCP_ANYCAST_ADDRESS: + g_free(priv->dhcp_anycast_addr); + priv->dhcp_anycast_addr = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_olpc_mesh_init(NMSettingOlpcMesh *setting) +{} + +/** + * nm_setting_olpc_mesh_new: + * + * Creates a new #NMSettingOlpcMesh object with default values. + * + * Returns: the new empty #NMSettingOlpcMesh object + **/ +NMSetting * +nm_setting_olpc_mesh_new(void) +{ + return g_object_new(NM_TYPE_SETTING_OLPC_MESH, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingOlpcMeshPrivate *priv = NM_SETTING_OLPC_MESH_GET_PRIVATE(object); + + if (priv->ssid) + g_bytes_unref(priv->ssid); + g_free(priv->dhcp_anycast_addr); + + G_OBJECT_CLASS(nm_setting_olpc_mesh_parent_class)->finalize(object); +} + +static void +nm_setting_olpc_mesh_class_init(NMSettingOlpcMeshClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingOlpcMeshPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingOlpcMesh:ssid: + * + * SSID of the mesh network to join. + **/ + obj_properties[PROP_SSID] = g_param_spec_boxed(NM_SETTING_OLPC_MESH_SSID, + "", + "", + G_TYPE_BYTES, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOlpcMesh:channel: + * + * Channel on which the mesh network to join is located. + **/ + obj_properties[PROP_CHANNEL] = + g_param_spec_uint(NM_SETTING_OLPC_MESH_CHANNEL, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOlpcMesh:dhcp-anycast-address: + * + * Anycast DHCP MAC address used when requesting an IP address via DHCP. + * The specific anycast address used determines which DHCP server class + * answers the request. + **/ + obj_properties[PROP_DHCP_ANYCAST_ADDRESS] = + g_param_spec_string(NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_DHCP_ANYCAST_ADDRESS], + &nm_sett_info_propert_type_mac_address); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_OLPC_MESH, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-ovs-bridge.c b/src/libnm-core-impl/nm-setting-ovs-bridge.c new file mode 100644 index 0000000..9d67231 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ovs-bridge.c @@ -0,0 +1,374 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ovs-bridge.h" + +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-ovs-bridge + * @short_description: Describes connection properties for Open vSwitch bridges. + * + * The #NMSettingOvsBridge object is a #NMSetting subclass that describes properties + * necessary for Open vSwitch bridges. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_FAIL_MODE, + PROP_MCAST_SNOOPING_ENABLE, + PROP_RSTP_ENABLE, + PROP_STP_ENABLE, + PROP_DATAPATH_TYPE, ); + +/** + * NMSettingOvsBridge: + * + * OvsBridge Link Settings + */ +struct _NMSettingOvsBridge { + NMSetting parent; + + char *fail_mode; + char *datapath_type; + bool mcast_snooping_enable : 1; + bool rstp_enable : 1; + bool stp_enable : 1; +}; + +struct _NMSettingOvsBridgeClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingOvsBridge, nm_setting_ovs_bridge, NM_TYPE_SETTING) + +/*****************************************************************************/ + +/** + * nm_setting_ovs_bridge_get_fail_mode: + * @self: the #NMSettingOvsBridge + * + * Returns: the #NMSettingOvsBridge:fail_mode property of the setting + * + * Since: 1.10 + **/ +const char * +nm_setting_ovs_bridge_get_fail_mode(NMSettingOvsBridge *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_BRIDGE(self), NULL); + + return self->fail_mode; +} + +/** + * nm_setting_ovs_bridge_get_mcast_snooping_enable: + * @self: the #NMSettingOvsBridge + * + * Returns: the #NMSettingOvsBridge:mcast_snooping_enable property of the setting + * + * Since: 1.10 + **/ +gboolean +nm_setting_ovs_bridge_get_mcast_snooping_enable(NMSettingOvsBridge *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_BRIDGE(self), FALSE); + + return self->mcast_snooping_enable; +} + +/** + * nm_setting_ovs_bridge_get_rstp_enable: + * @self: the #NMSettingOvsBridge + * + * Returns: the #NMSettingOvsBridge:rstp_enable property of the setting + * + * Since: 1.10 + **/ +gboolean +nm_setting_ovs_bridge_get_rstp_enable(NMSettingOvsBridge *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_BRIDGE(self), FALSE); + + return self->rstp_enable; +} + +/** + * nm_setting_ovs_bridge_get_stp_enable: + * @self: the #NMSettingOvsBridge + * + * Returns: the #NMSettingOvsBridge:stp_enable property of the setting + * + * Since: 1.10 + **/ +gboolean +nm_setting_ovs_bridge_get_stp_enable(NMSettingOvsBridge *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_BRIDGE(self), FALSE); + + return self->stp_enable; +} + +/** + * nm_setting_ovs_bridge_get_datapath_type: + * @self: the #NMSettingOvsBridge + * + * Returns: the #NMSettingOvsBridge:datapath_type property of the setting + * + * Since: 1.20 + **/ +const char * +nm_setting_ovs_bridge_get_datapath_type(NMSettingOvsBridge *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_BRIDGE(self), NULL); + + return self->datapath_type; +} + +/*****************************************************************************/ + +static int +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingOvsBridge *self = NM_SETTING_OVS_BRIDGE(setting); + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + if (connection) { + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection(connection); + if (!s_con) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("missing setting")); + g_prefix_error(error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME); + return FALSE; + } + + if (nm_setting_connection_get_master(s_con)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with a '%s' setting must not have a master."), + NM_SETTING_OVS_BRIDGE_SETTING_NAME); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER); + return FALSE; + } + } + + if (!NM_IN_STRSET(self->fail_mode, "secure", "standalone", NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not allowed in fail_mode"), + self->fail_mode); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_BRIDGE_SETTING_NAME, + NM_SETTING_OVS_BRIDGE_FAIL_MODE); + return FALSE; + } + + if (!NM_IN_STRSET(self->datapath_type, "system", "netdev", NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not valid"), + self->datapath_type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_BRIDGE_SETTING_NAME, + NM_SETTING_OVS_BRIDGE_DATAPATH_TYPE); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingOvsBridge *self = NM_SETTING_OVS_BRIDGE(object); + + switch (prop_id) { + case PROP_FAIL_MODE: + g_value_set_string(value, self->fail_mode); + break; + case PROP_MCAST_SNOOPING_ENABLE: + g_value_set_boolean(value, self->mcast_snooping_enable); + break; + case PROP_RSTP_ENABLE: + g_value_set_boolean(value, self->rstp_enable); + break; + case PROP_STP_ENABLE: + g_value_set_boolean(value, self->stp_enable); + break; + case PROP_DATAPATH_TYPE: + g_value_set_string(value, self->datapath_type); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingOvsBridge *self = NM_SETTING_OVS_BRIDGE(object); + + switch (prop_id) { + case PROP_FAIL_MODE: + g_free(self->fail_mode); + self->fail_mode = g_value_dup_string(value); + break; + case PROP_MCAST_SNOOPING_ENABLE: + self->mcast_snooping_enable = g_value_get_boolean(value); + break; + case PROP_RSTP_ENABLE: + self->rstp_enable = g_value_get_boolean(value); + break; + case PROP_STP_ENABLE: + self->stp_enable = g_value_get_boolean(value); + break; + case PROP_DATAPATH_TYPE: + g_free(self->datapath_type); + self->datapath_type = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ovs_bridge_init(NMSettingOvsBridge *self) +{} + +/** + * nm_setting_ovs_bridge_new: + * + * Creates a new #NMSettingOvsBridge object with default values. + * + * Returns: (transfer full): the new empty #NMSettingOvsBridge object + * + * Since: 1.10 + **/ +NMSetting * +nm_setting_ovs_bridge_new(void) +{ + return g_object_new(NM_TYPE_SETTING_OVS_BRIDGE, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingOvsBridge *self = NM_SETTING_OVS_BRIDGE(object); + + g_free(self->fail_mode); + g_free(self->datapath_type); + + G_OBJECT_CLASS(nm_setting_ovs_bridge_parent_class)->finalize(object); +} + +static void +nm_setting_ovs_bridge_class_init(NMSettingOvsBridgeClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingOvsBridge:fail-mode: + * + * The bridge failure mode. One of "secure", "standalone" or empty. + * + * Since: 1.10 + **/ + obj_properties[PROP_FAIL_MODE] = g_param_spec_string( + NM_SETTING_OVS_BRIDGE_FAIL_MODE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOvsBridge:mcast-snooping-enable: + * + * Enable or disable multicast snooping. + * + * Since: 1.10 + **/ + obj_properties[PROP_MCAST_SNOOPING_ENABLE] = + g_param_spec_boolean(NM_SETTING_OVS_BRIDGE_MCAST_SNOOPING_ENABLE, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOvsBridge:rstp-enable: + * + * Enable or disable RSTP. + * + * Since: 1.10 + **/ + obj_properties[PROP_RSTP_ENABLE] = + g_param_spec_boolean(NM_SETTING_OVS_BRIDGE_RSTP_ENABLE, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOvsBridge:stp-enable: + * + * Enable or disable STP. + * + * Since: 1.10 + **/ + obj_properties[PROP_STP_ENABLE] = + g_param_spec_boolean(NM_SETTING_OVS_BRIDGE_STP_ENABLE, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOvsBridge:datapath-type: + * + * The data path type. One of "system", "netdev" or empty. + * + * Since: 1.20 + **/ + obj_properties[PROP_DATAPATH_TYPE] = g_param_spec_string( + NM_SETTING_OVS_BRIDGE_DATAPATH_TYPE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_OVS_BRIDGE); +} diff --git a/src/libnm-core-impl/nm-setting-ovs-dpdk.c b/src/libnm-core-impl/nm-setting-ovs-dpdk.c new file mode 100644 index 0000000..957b0f5 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ovs-dpdk.c @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ovs-dpdk.h" + +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-ovs-dpdk + * @short_description: Describes connection properties for Open vSwitch DPDK interfaces. + * + * The #NMSettingOvsDpdk object is a #NMSetting subclass that describes properties + * necessary for Open vSwitch interfaces of type "dpdk". + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DEVARGS, ); + +/** + * NMSettingOvsDpdk: + * + * OvsDpdk Link Settings + */ +struct _NMSettingOvsDpdk { + NMSetting parent; + + char *devargs; +}; + +struct _NMSettingOvsDpdkClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingOvsDpdk, nm_setting_ovs_dpdk, NM_TYPE_SETTING) + +/*****************************************************************************/ + +/** + * nm_setting_ovs_dpdk_get_devargs: + * @self: the #NMSettingOvsDpdk + * + * Returns: the #NMSettingOvsDpdk:devargs property of the setting + * + * Since: 1.20 + **/ +const char * +nm_setting_ovs_dpdk_get_devargs(NMSettingOvsDpdk *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_DPDK(self), NULL); + + return self->devargs; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingOvsDpdk *self = NM_SETTING_OVS_DPDK(object); + + switch (prop_id) { + case PROP_DEVARGS: + g_value_set_string(value, self->devargs); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingOvsDpdk *self = NM_SETTING_OVS_DPDK(object); + + switch (prop_id) { + case PROP_DEVARGS: + g_free(self->devargs); + self->devargs = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ovs_dpdk_init(NMSettingOvsDpdk *self) +{} + +/** + * nm_setting_ovs_dpdk_new: + * + * Creates a new #NMSettingOvsDpdk object with default values. + * + * Returns: (transfer full): the new empty #NMSettingOvsDpdk object + * + * Since: 1.20 + **/ +NMSetting * +nm_setting_ovs_dpdk_new(void) +{ + return g_object_new(NM_TYPE_SETTING_OVS_DPDK, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingOvsDpdk *self = NM_SETTING_OVS_DPDK(object); + + g_free(self->devargs); + + G_OBJECT_CLASS(nm_setting_ovs_dpdk_parent_class)->finalize(object); +} + +static void +nm_setting_ovs_dpdk_class_init(NMSettingOvsDpdkClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + /** + * NMSettingOvsDpdk:devargs: + * + * Open vSwitch DPDK device arguments. + * + * Since: 1.20 + **/ + obj_properties[PROP_DEVARGS] = g_param_spec_string( + NM_SETTING_OVS_DPDK_DEVARGS, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_OVS_DPDK); +} diff --git a/src/libnm-core-impl/nm-setting-ovs-external-ids.c b/src/libnm-core-impl/nm-setting-ovs-external-ids.c new file mode 100644 index 0000000..b73c1af --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ovs-external-ids.c @@ -0,0 +1,551 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 - 2020 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ovs-external-ids.h" + +#include "nm-setting-private.h" +#include "nm-utils-private.h" +#include "nm-connection-private.h" + +#define MAX_NUM_KEYS 256 + +/*****************************************************************************/ + +/** + * SECTION:nm-setting-ovs-external-ids + * @short_description: External-IDs for OVS database + * + * The #NMSettingOvsExternalIDs object is a #NMSetting subclass that allow to + * configure external ids for OVS. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingOvsExternalIDs, PROP_DATA, ); + +typedef struct { + GHashTable * data; + const char **data_keys; +} NMSettingOvsExternalIDsPrivate; + +/** + * NMSettingOvsExternalIDs: + * + * OVS External IDs Settings + */ +struct _NMSettingOvsExternalIDs { + NMSetting parent; + NMSettingOvsExternalIDsPrivate _priv; +}; + +struct _NMSettingOvsExternalIDsClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingOvsExternalIDs, nm_setting_ovs_external_ids, NM_TYPE_SETTING) + +#define NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSettingOvsExternalIDs, NM_IS_SETTING_OVS_EXTERNAL_IDS) + +/*****************************************************************************/ + +static gboolean +_exid_key_char_is_regular(char ch) +{ + /* allow words of printable characters, plus some + * special characters, for example to support base64 encoding. */ + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') + || NM_IN_SET(ch, '-', '_', '+', '/', '=', '.'); +} + +/** + * nm_setting_ovs_external_ids_check_key: + * @key: (allow-none): the key to check + * @error: a #GError, %NULL to ignore. + * + * Checks whether @key is a valid key for OVS' external-ids. + * This means, the key cannot be %NULL, not too large and valid ASCII. + * Also, only digits and numbers are allowed with a few special + * characters. They key must also not start with "NM.". + * + * Since: 1.30 + * + * Returns: %TRUE if @key is a valid user data key. + */ +gboolean +nm_setting_ovs_external_ids_check_key(const char *key, GError **error) +{ + gsize len; + + g_return_val_if_fail(!error || !*error, FALSE); + + if (!key || !key[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("missing key")); + return FALSE; + } + len = strlen(key); + if (len > 255u) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("key is too long")); + return FALSE; + } + if (!g_utf8_validate(key, len, NULL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("key must be UTF8")); + return FALSE; + } + if (!NM_STRCHAR_ALL(key, ch, _exid_key_char_is_regular(ch))) { + /* Probably OVS is more forgiving about what makes a valid key for + * an external-id. However, we are strict (at least, for now). */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("key contains invalid characters")); + return FALSE; + } + + if (NM_STR_HAS_PREFIX(key, NM_OVS_EXTERNAL_ID_NM_PREFIX)) { + /* these keys are reserved. */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("key cannot start with \"NM.\"")); + return FALSE; + } + + return TRUE; +} + +/** + * nm_setting_ovs_external_ids_check_val: + * @val: (allow-none): the value to check + * @error: a #GError, %NULL to ignore. + * + * Checks whether @val is a valid user data value. This means, + * value is not %NULL, not too large and valid UTF-8. + * + * Since: 1.30 + * + * Returns: %TRUE if @val is a valid user data value. + */ +gboolean +nm_setting_ovs_external_ids_check_val(const char *val, GError **error) +{ + gsize len; + + g_return_val_if_fail(!error || !*error, FALSE); + + if (!val) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value is missing")); + return FALSE; + } + + len = strlen(val); + if (len > (8u * 1024u)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value is too large")); + return FALSE; + } + + if (!g_utf8_validate(val, len, NULL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value is not valid UTF8")); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static GHashTable * +_create_data_hash(void) +{ + return g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); +} + +GHashTable * +_nm_setting_ovs_external_ids_get_data(NMSettingOvsExternalIDs *self) +{ + return NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self)->data; +} + +/** + * nm_setting_ovs_external_ids_get_data_keys: + * @setting: the #NMSettingOvsExternalIDs + * @out_len: (out): the length of the returned array + * + * Returns: (array length=out_len) (transfer none): a + * %NULL-terminated array containing each key from the table. + **/ +const char *const * +nm_setting_ovs_external_ids_get_data_keys(NMSettingOvsExternalIDs *setting, guint *out_len) +{ + NMSettingOvsExternalIDs * self = setting; + NMSettingOvsExternalIDsPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_OVS_EXTERNAL_IDS(self), NULL); + + priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); + + if (priv->data_keys) { + NM_SET_OUT(out_len, g_hash_table_size(priv->data)); + return priv->data_keys; + } + + priv->data_keys = nm_utils_strdict_get_keys(priv->data, TRUE, out_len); + + /* don't return %NULL, but hijack the @data_keys fields as a pseudo + * empty strv array. */ + return priv->data_keys ?: ((const char **) &priv->data_keys); +} + +/*****************************************************************************/ + +/** + * nm_setting_ovs_external_ids_get_data: + * @setting: the #NMSettingOvsExternalIDs instance + * @key: the external-id to lookup + * + * Since: 1.30 + * + * Returns: (transfer none): the value associated with @key or %NULL if no such + * value exists. + */ +const char * +nm_setting_ovs_external_ids_get_data(NMSettingOvsExternalIDs *setting, const char *key) +{ + NMSettingOvsExternalIDs * self = setting; + NMSettingOvsExternalIDsPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_OVS_EXTERNAL_IDS(self), NULL); + g_return_val_if_fail(key, NULL); + + priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); + + if (!priv->data) + return NULL; + + return g_hash_table_lookup(priv->data, key); +} + +/** + * nm_setting_ovs_external_ids_set_data: + * @setting: the #NMSettingOvsExternalIDs instance + * @key: the key to set + * @val: (allow-none): the value to set or %NULL to clear a key. + * + * Since: 1.30 + */ +void +nm_setting_ovs_external_ids_set_data(NMSettingOvsExternalIDs *setting, + const char * key, + const char * val) +{ + NMSettingOvsExternalIDs * self = setting; + NMSettingOvsExternalIDsPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_OVS_EXTERNAL_IDS(self)); + + priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); + + if (!val) { + if (priv->data && g_hash_table_remove(priv->data, key)) + goto out_changed; + return; + } + + if (priv->data) { + const char *val2; + + if (g_hash_table_lookup_extended(priv->data, key, NULL, (gpointer *) &val2)) { + if (nm_streq(val, val2)) + return; + } + } else + priv->data = _create_data_hash(); + + g_hash_table_insert(priv->data, g_strdup(key), g_strdup(val)); + +out_changed: + nm_clear_g_free(&priv->data_keys); + _notify(self, PROP_DATA); +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(setting); + NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); + + if (priv->data) { + gs_free_error GError *local = NULL; + GHashTableIter iter; + const char * key; + const char * val; + + g_hash_table_iter_init(&iter, priv->data); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + if (!nm_setting_ovs_external_ids_check_key(key, &local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid key \"%s\": %s"), + key, + local->message); + } else if (!nm_setting_ovs_external_ids_check_val(val, &local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid value for \"%s\": %s"), + key, + local->message); + } else + continue; + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME, + NM_SETTING_OVS_EXTERNAL_IDS_DATA); + return FALSE; + } + } + + if (priv->data && g_hash_table_size(priv->data) > MAX_NUM_KEYS) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("maximum number of user data entries reached (%u instead of %u)"), + g_hash_table_size(priv->data), + (unsigned) MAX_NUM_KEYS); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME, + NM_SETTING_OVS_EXTERNAL_IDS_DATA); + return FALSE; + } + + if (connection) { + NMSettingConnection *s_con; + const char * type; + const char * slave_type; + + type = nm_connection_get_connection_type(connection); + if (!type) { + NMSetting *s_base; + + s_base = _nm_connection_find_base_type_setting(connection); + if (s_base) + type = nm_setting_get_name(s_base); + } + if (NM_IN_STRSET(type, + NM_SETTING_OVS_BRIDGE_SETTING_NAME, + NM_SETTING_OVS_PORT_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME)) + goto connection_type_is_good; + + if ((s_con = nm_connection_get_setting_connection(connection)) + && _nm_connection_detect_slave_type_full(s_con, + connection, + &slave_type, + NULL, + NULL, + NULL, + NULL) + && nm_streq0(slave_type, NM_SETTING_OVS_PORT_SETTING_NAME)) + goto connection_type_is_good; + + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("OVS external IDs can only be added to a profile of type OVS " + "bridge/port/interface or to OVS system interface")); + return FALSE; + } +connection_type_is_good: + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingOvsExternalIDsPrivate *priv; + NMSettingOvsExternalIDsPrivate *pri2; + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_OVS_EXTERNAL_IDS_DATA)) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; + + if (!set_b) + return TRUE; + + priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(NM_SETTING_OVS_EXTERNAL_IDS(set_a)); + pri2 = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(NM_SETTING_OVS_EXTERNAL_IDS(set_b)); + return nm_utils_hashtable_equal(priv->data, pri2->data, TRUE, g_str_equal); + } + + return NM_SETTING_CLASS(nm_setting_ovs_external_ids_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(object); + NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); + GHashTableIter iter; + GHashTable * data; + const char * key; + const char * val; + + switch (prop_id) { + case PROP_DATA: + data = _create_data_hash(); + if (priv->data) { + g_hash_table_iter_init(&iter, priv->data); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) + g_hash_table_insert(data, g_strdup(key), g_strdup(val)); + } + g_value_take_boxed(value, data); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(object); + NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_DATA: + { + gs_unref_hashtable GHashTable *old = NULL; + GHashTableIter iter; + GHashTable * data; + const char * key; + const char * val; + + nm_clear_g_free(&priv->data_keys); + + old = g_steal_pointer(&priv->data); + + data = g_value_get_boxed(value); + if (nm_g_hash_table_size(data) <= 0) + return; + + priv->data = _create_data_hash(); + g_hash_table_iter_init(&iter, data); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) + g_hash_table_insert(priv->data, g_strdup(key), g_strdup(val)); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ovs_external_ids_init(NMSettingOvsExternalIDs *self) +{} + +/** + * nm_setting_ovs_external_ids_new: + * + * Creates a new #NMSettingOvsExternalIDs object with default values. + * + * Returns: (transfer full) (type NMSettingOvsExternalIDs): the new empty + * #NMSettingOvsExternalIDs object + * + * Since: 1.30 + */ +NMSetting * +nm_setting_ovs_external_ids_new(void) +{ + return g_object_new(NM_TYPE_SETTING_OVS_EXTERNAL_IDS, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(object); + NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); + + g_free(priv->data_keys); + if (priv->data) + g_hash_table_unref(priv->data); + + G_OBJECT_CLASS(nm_setting_ovs_external_ids_parent_class)->finalize(object); +} + +static void +nm_setting_ovs_external_ids_class_init(NMSettingOvsExternalIDsClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->compare_property = compare_property; + setting_class->verify = verify; + + /** + * NMSettingOvsExternalIDs:data: (type GHashTable(utf8,utf8)) + * + * A dictionary of key/value pairs with exernal-ids for OVS. + * + * Since: 1.30 + **/ + obj_properties[PROP_DATA] = g_param_spec_boxed(NM_SETTING_OVS_EXTERNAL_IDS_DATA, + "", + "", + G_TYPE_HASH_TABLE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_DATA], + &nm_sett_info_propert_type_strdict); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-ovs-interface.c b/src/libnm-core-impl/nm-setting-ovs-interface.c new file mode 100644 index 0000000..1fde960 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ovs-interface.c @@ -0,0 +1,427 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ovs-interface.h" + +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-ovs-interface + * @short_description: Describes connection properties for Open vSwitch interfaces. + * + * The #NMSettingOvsInterface object is a #NMSetting subclass that describes properties + * necessary for Open vSwitch interfaces. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_TYPE, ); + +/** + * NMSettingOvsInterface: + * + * Open vSwitch Interface Settings + */ +struct _NMSettingOvsInterface { + NMSetting parent; + + char *type; +}; + +struct _NMSettingOvsInterfaceClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingOvsInterface, nm_setting_ovs_interface, NM_TYPE_SETTING) + +/*****************************************************************************/ + +/** + * nm_setting_ovs_interface_get_interface_type: + * @self: the #NMSettingOvsInterface + * + * Returns: the #NMSettingOvsInterface:type property of the setting + * + * Since: 1.10 + **/ +const char * +nm_setting_ovs_interface_get_interface_type(NMSettingOvsInterface *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_INTERFACE(self), NULL); + + return self->type; +} + +/*****************************************************************************/ + +int +_nm_setting_ovs_interface_verify_interface_type(NMSettingOvsInterface *self, + const char * type, + NMConnection * connection, + gboolean normalize, + gboolean * out_modified, + const char ** out_normalized_type, + GError ** error) +{ + const char *type_from_setting = NULL; + const char *type_setting = NULL; + const char *connection_type; + gboolean is_ovs_connection_type; + + if (normalize) { + g_return_val_if_fail(NM_IS_SETTING_OVS_INTERFACE(self), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + nm_assert(self == nm_connection_get_setting_ovs_interface(connection)); + } else { + g_return_val_if_fail(!self || NM_IS_SETTING_OVS_INTERFACE(self), FALSE); + g_return_val_if_fail(!connection || NM_IS_CONNECTION(connection), FALSE); + } + + NM_SET_OUT(out_modified, FALSE); + NM_SET_OUT(out_normalized_type, NULL); + + if (type && !NM_IN_STRSET(type, "internal", "system", "patch", "dpdk")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid interface type"), + type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_TYPE); + return FALSE; + } + + if (!connection) { + NM_SET_OUT(out_normalized_type, type); + return TRUE; + } + + connection_type = nm_connection_get_connection_type(connection); + if (!connection_type) { + /* if we have an ovs-interface, then the connection type must be either + * "ovs-interface" (for non "system" type) or anything else (for "system" type). + * + * The connection type usually can be normalized based on the presence of a + * base setting. However, in this case, if the connection type is missing, + * that is too complicate to guess what the user wanted. + * + * Require the use to be explicit and fail. */ + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with a '%s' setting needs connection.type explicitly set"), + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TYPE); + return FALSE; + } + + if (nm_streq(connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME)) { + if (type && nm_streq(type, "system")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection of type '%s' cannot have ovs-interface.type \"system\""), + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_TYPE); + return FALSE; + } + is_ovs_connection_type = TRUE; + } else { + if (type && !nm_streq(type, "system")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection of type '%s' cannot have an ovs-interface.type \"%s\""), + connection_type, + type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_TYPE); + return FALSE; + } + is_ovs_connection_type = FALSE; + } + + if (nm_connection_get_setting_by_name(connection, NM_SETTING_OVS_PATCH_SETTING_NAME)) { + type_from_setting = "patch"; + type_setting = NM_SETTING_OVS_PATCH_SETTING_NAME; + } + + if (nm_connection_get_setting_by_name(connection, NM_SETTING_OVS_DPDK_SETTING_NAME)) { + if (type_from_setting) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection can not have both '%s' and '%s' settings at the same time"), + NM_SETTING_OVS_DPDK_SETTING_NAME, + type_setting); + return FALSE; + } + type_from_setting = "dpdk"; + type_setting = NM_SETTING_OVS_DPDK_SETTING_NAME; + } + + if (type_from_setting) { + if (!is_ovs_connection_type) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with '%s' setting must be of connection.type " + "\"ovs-interface\" but is \"%s\""), + NM_SETTING_OVS_PATCH_SETTING_NAME, + connection_type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_TYPE); + return FALSE; + } + + if (type) { + if (!nm_streq(type, type_from_setting)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with '%s' setting needs to be of '%s' interface type, " + "not '%s'"), + type_setting, + type_from_setting, + type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_TYPE); + return FALSE; + } + NM_SET_OUT(out_normalized_type, type); + return TRUE; + } + type = type_from_setting; + goto normalize; + } else { + if (nm_streq0(type, "patch")) { + g_set_error( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("A connection with ovs-interface.type '%s' setting a 'ovs-patch' setting"), + type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_TYPE); + return FALSE; + } + } + + if (type) { + NM_SET_OUT(out_normalized_type, type); + return TRUE; + } + + if (is_ovs_connection_type) + type = "internal"; + else + type = "system"; + + NM_SET_OUT(out_normalized_type, type); + +normalize: + if (!normalize) { + if (!self) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("Missing ovs interface setting")); + g_prefix_error(error, "%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME); + } else { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("Missing ovs interface type")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_TYPE); + } + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + if (!self) { + self = NM_SETTING_OVS_INTERFACE(nm_setting_ovs_interface_new()); + nm_connection_add_setting(connection, NM_SETTING(self)); + } + g_object_set(self, NM_SETTING_OVS_INTERFACE_TYPE, type, NULL); + NM_SET_OUT(out_modified, TRUE); + + return TRUE; +} + +static int +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingOvsInterface *self = NM_SETTING_OVS_INTERFACE(setting); + NMSettingConnection * s_con = NULL; + + if (connection) { + const char *slave_type; + + s_con = nm_connection_get_setting_connection(connection); + if (!s_con) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("missing setting")); + g_prefix_error(error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME); + return FALSE; + } + + if (!nm_setting_connection_get_master(s_con)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with a '%s' setting must have a master."), + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER); + return FALSE; + } + + slave_type = nm_setting_connection_get_slave_type(s_con); + if (slave_type && !nm_streq(slave_type, NM_SETTING_OVS_PORT_SETTING_NAME)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with a '%s' setting must have the slave-type set to '%s'. " + "Instead it is '%s'"), + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_PORT_SETTING_NAME, + slave_type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + } + + return _nm_setting_ovs_interface_verify_interface_type(self, + self->type, + connection, + FALSE, + NULL, + NULL, + error); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingOvsInterface *self = NM_SETTING_OVS_INTERFACE(object); + + switch (prop_id) { + case PROP_TYPE: + g_value_set_string(value, self->type); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingOvsInterface *self = NM_SETTING_OVS_INTERFACE(object); + + switch (prop_id) { + case PROP_TYPE: + g_free(self->type); + self->type = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ovs_interface_init(NMSettingOvsInterface *self) +{} + +/** + * nm_setting_ovs_interface_new: + * + * Creates a new #NMSettingOvsInterface object with default values. + * + * Returns: (transfer full): the new empty #NMSettingOvsInterface object + * + * Since: 1.10 + **/ +NMSetting * +nm_setting_ovs_interface_new(void) +{ + return g_object_new(NM_TYPE_SETTING_OVS_INTERFACE, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingOvsInterface *self = NM_SETTING_OVS_INTERFACE(object); + + g_free(self->type); + + G_OBJECT_CLASS(nm_setting_ovs_interface_parent_class)->finalize(object); +} + +static void +nm_setting_ovs_interface_class_init(NMSettingOvsInterfaceClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingOvsInterface:type: + * + * The interface type. Either "internal", "system", "patch", "dpdk", or empty. + * + * Since: 1.10 + **/ + obj_properties[PROP_TYPE] = g_param_spec_string(NM_SETTING_OVS_INTERFACE_TYPE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_OVS_INTERFACE); +} diff --git a/src/libnm-core-impl/nm-setting-ovs-patch.c b/src/libnm-core-impl/nm-setting-ovs-patch.c new file mode 100644 index 0000000..a226a26 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ovs-patch.c @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ovs-patch.h" + +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-ovs-patch + * @short_description: Describes connection properties for Open vSwitch patch interfaces. + * + * The #NMSettingOvsPatch object is a #NMSetting subclass that describes properties + * necessary for Open vSwitch interfaces of type "patch". + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PEER, ); + +/** + * NMSettingOvsPatch: + * + * OvsPatch Link Settings + */ +struct _NMSettingOvsPatch { + NMSetting parent; + + char *peer; +}; + +struct _NMSettingOvsPatchClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingOvsPatch, nm_setting_ovs_patch, NM_TYPE_SETTING) + +/*****************************************************************************/ + +/** + * nm_setting_ovs_patch_get_peer: + * @self: the #NMSettingOvsPatch + * + * Returns: the #NMSettingOvsPatch:peer property of the setting + * + * Since: 1.10 + **/ +const char * +nm_setting_ovs_patch_get_peer(NMSettingOvsPatch *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_PATCH(self), NULL); + + return self->peer; +} + +/*****************************************************************************/ + +static int +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingOvsPatch *self = NM_SETTING_OVS_PATCH(setting); + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + if (!self->peer) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_PATCH_SETTING_NAME, + NM_SETTING_OVS_PATCH_PEER); + return FALSE; + } + + if (!nm_utils_ifname_valid(self->peer, NMU_IFACE_OVS, error)) { + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_PATCH_SETTING_NAME, + NM_SETTING_OVS_PATCH_PEER); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingOvsPatch *self = NM_SETTING_OVS_PATCH(object); + + switch (prop_id) { + case PROP_PEER: + g_value_set_string(value, self->peer); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingOvsPatch *self = NM_SETTING_OVS_PATCH(object); + + switch (prop_id) { + case PROP_PEER: + g_free(self->peer); + self->peer = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ovs_patch_init(NMSettingOvsPatch *self) +{} + +/** + * nm_setting_ovs_patch_new: + * + * Creates a new #NMSettingOvsPatch object with default values. + * + * Returns: (transfer full): the new empty #NMSettingOvsPatch object + * + * Since: 1.10 + **/ +NMSetting * +nm_setting_ovs_patch_new(void) +{ + return g_object_new(NM_TYPE_SETTING_OVS_PATCH, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingOvsPatch *self = NM_SETTING_OVS_PATCH(object); + + g_free(self->peer); + + G_OBJECT_CLASS(nm_setting_ovs_patch_parent_class)->finalize(object); +} + +static void +nm_setting_ovs_patch_class_init(NMSettingOvsPatchClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingOvsPatch:peer: + * + * Specifies the name of the interface for the other side of the patch. + * The patch on the other side must also set this interface as peer. + * + * Since: 1.10 + **/ + obj_properties[PROP_PEER] = g_param_spec_string(NM_SETTING_OVS_PATCH_PEER, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_OVS_PATCH); +} diff --git a/src/libnm-core-impl/nm-setting-ovs-port.c b/src/libnm-core-impl/nm-setting-ovs-port.c new file mode 100644 index 0000000..821f29a --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ovs-port.c @@ -0,0 +1,467 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ovs-port.h" + +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-ovs-port + * @short_description: Describes connection properties for Open vSwitch ports. + * + * The #NMSettingOvsPort object is a #NMSetting subclass that describes properties + * necessary for Open vSwitch ports. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_VLAN_MODE, + PROP_TAG, + PROP_LACP, + PROP_BOND_MODE, + PROP_BOND_UPDELAY, + PROP_BOND_DOWNDELAY, ); + +/** + * NMSettingOvsPort: + * + * OvsPort Link Settings + */ +struct _NMSettingOvsPort { + NMSetting parent; + + char *vlan_mode; + char *lacp; + char *bond_mode; + guint tag; + guint bond_updelay; + guint bond_downdelay; +}; + +struct _NMSettingOvsPortClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingOvsPort, nm_setting_ovs_port, NM_TYPE_SETTING) + +/*****************************************************************************/ + +/** + * nm_setting_ovs_port_get_vlan_mode: + * @self: the #NMSettingOvsPort + * + * Returns: the #NMSettingOvsPort:vlan-mode property of the setting + * + * Since: 1.10 + **/ +const char * +nm_setting_ovs_port_get_vlan_mode(NMSettingOvsPort *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_PORT(self), NULL); + + return self->vlan_mode; +} + +/** + * nm_setting_ovs_port_get_tag: + * @self: the #NMSettingOvsPort + * + * Returns: the #NMSettingOvsPort:tag property of the setting + * + * Since: 1.10 + **/ +guint +nm_setting_ovs_port_get_tag(NMSettingOvsPort *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_PORT(self), 0); + + return self->tag; +} + +/** + * nm_setting_ovs_port_get_lacp: + * @self: the #NMSettingOvsPort + * + * Returns: the #NMSettingOvsPort:lacp property of the setting + * + * Since: 1.10 + **/ +const char * +nm_setting_ovs_port_get_lacp(NMSettingOvsPort *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_PORT(self), NULL); + + return self->lacp; +} + +/** + * nm_setting_ovs_port_get_bond_mode: + * @self: the #NMSettingOvsPort + * + * Returns: the #NMSettingOvsPort:bond-mode property of the setting + * + * Since: 1.10 + **/ +const char * +nm_setting_ovs_port_get_bond_mode(NMSettingOvsPort *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_PORT(self), NULL); + + return self->bond_mode; +} + +/** + * nm_setting_ovs_port_get_bond_updelay: + * @self: the #NMSettingOvsPort + * + * Returns: the #NMSettingOvsPort:bond-updelay property of the setting + * + * Since: 1.10 + **/ +guint +nm_setting_ovs_port_get_bond_updelay(NMSettingOvsPort *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_PORT(self), 0); + + return self->bond_updelay; +} + +/** + * nm_setting_ovs_port_get_bond_downdelay: + * @self: the #NMSettingOvsPort + * + * Returns: the #NMSettingOvsPort:bond-downdelay property of the setting + * + * Since: 1.10 + **/ +guint +nm_setting_ovs_port_get_bond_downdelay(NMSettingOvsPort *self) +{ + g_return_val_if_fail(NM_IS_SETTING_OVS_PORT(self), 0); + + return self->bond_downdelay; +} + +/*****************************************************************************/ + +static int +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingOvsPort *self = NM_SETTING_OVS_PORT(setting); + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + if (connection) { + NMSettingConnection *s_con; + const char * slave_type; + + s_con = nm_connection_get_setting_connection(connection); + if (!s_con) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("missing setting")); + g_prefix_error(error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME); + return FALSE; + } + + if (!nm_setting_connection_get_master(s_con)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with a '%s' setting must have a master."), + NM_SETTING_OVS_PORT_SETTING_NAME); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER); + return FALSE; + } + + slave_type = nm_setting_connection_get_slave_type(s_con); + if (slave_type && strcmp(slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with a '%s' setting must have the slave-type set to '%s'. " + "Instead it is '%s'"), + NM_SETTING_OVS_PORT_SETTING_NAME, + NM_SETTING_OVS_BRIDGE_SETTING_NAME, + slave_type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + } + + if (!NM_IN_STRSET(self->vlan_mode, + "access", + "native-tagged", + "native-untagged", + "trunk", + NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not allowed in vlan_mode"), + self->vlan_mode); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_PORT_SETTING_NAME, + NM_SETTING_OVS_PORT_VLAN_MODE); + return FALSE; + } + + if (self->tag >= 4095) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the tag id must be in range 0-4094 but is %u"), + self->tag); + g_prefix_error(error, "%s.%s: ", NM_SETTING_OVS_PORT_SETTING_NAME, NM_SETTING_OVS_PORT_TAG); + return FALSE; + } + + if (!NM_IN_STRSET(self->lacp, "active", "off", "passive", NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not allowed in lacp"), + self->lacp); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_PORT_SETTING_NAME, + NM_SETTING_OVS_PORT_LACP); + return FALSE; + } + + if (!NM_IN_STRSET(self->bond_mode, "active-backup", "balance-slb", "balance-tcp", NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not allowed in bond_mode"), + self->bond_mode); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_OVS_PORT_SETTING_NAME, + NM_SETTING_OVS_PORT_BOND_MODE); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingOvsPort *self = NM_SETTING_OVS_PORT(object); + + switch (prop_id) { + case PROP_VLAN_MODE: + g_value_set_string(value, self->vlan_mode); + break; + case PROP_TAG: + g_value_set_uint(value, self->tag); + break; + case PROP_LACP: + g_value_set_string(value, self->lacp); + break; + case PROP_BOND_MODE: + g_value_set_string(value, self->bond_mode); + break; + case PROP_BOND_UPDELAY: + g_value_set_uint(value, self->bond_updelay); + break; + case PROP_BOND_DOWNDELAY: + g_value_set_uint(value, self->bond_downdelay); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingOvsPort *self = NM_SETTING_OVS_PORT(object); + + switch (prop_id) { + case PROP_VLAN_MODE: + g_free(self->vlan_mode); + self->vlan_mode = g_value_dup_string(value); + break; + case PROP_TAG: + self->tag = g_value_get_uint(value); + break; + case PROP_LACP: + g_free(self->lacp); + self->lacp = g_value_dup_string(value); + break; + case PROP_BOND_MODE: + g_free(self->bond_mode); + self->bond_mode = g_value_dup_string(value); + break; + case PROP_BOND_UPDELAY: + self->bond_updelay = g_value_get_uint(value); + break; + case PROP_BOND_DOWNDELAY: + self->bond_downdelay = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ovs_port_init(NMSettingOvsPort *self) +{} + +/** + * nm_setting_ovs_port_new: + * + * Creates a new #NMSettingOvsPort object with default values. + * + * Returns: (transfer full): the new empty #NMSettingOvsPort object + * + * Since: 1.10 + **/ +NMSetting * +nm_setting_ovs_port_new(void) +{ + return g_object_new(NM_TYPE_SETTING_OVS_PORT, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingOvsPort *self = NM_SETTING_OVS_PORT(object); + + g_free(self->vlan_mode); + g_free(self->lacp); + g_free(self->bond_mode); + + G_OBJECT_CLASS(nm_setting_ovs_port_parent_class)->finalize(object); +} + +static void +nm_setting_ovs_port_class_init(NMSettingOvsPortClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingOvsPort:vlan-mode: + * + * The VLAN mode. One of "access", "native-tagged", "native-untagged", + * "trunk" or unset. + * + * Since: 1.10 + **/ + obj_properties[PROP_VLAN_MODE] = g_param_spec_string( + NM_SETTING_OVS_PORT_VLAN_MODE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOvsPort:tag: + * + * The VLAN tag in the range 0-4095. + * + * Since: 1.10 + **/ + obj_properties[PROP_TAG] = + g_param_spec_uint(NM_SETTING_OVS_PORT_TAG, + "", + "", + 0, + 4095, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOvsPort:lacp: + * + * LACP mode. One of "active", "off", or "passive". + * + * Since: 1.10 + **/ + obj_properties[PROP_LACP] = g_param_spec_string(NM_SETTING_OVS_PORT_LACP, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOvsPort:bond-mode: + * + * Bonding mode. One of "active-backup", "balance-slb", or "balance-tcp". + * + * Since: 1.10 + **/ + obj_properties[PROP_BOND_MODE] = g_param_spec_string( + NM_SETTING_OVS_PORT_BOND_MODE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOvsPort:bond-updelay: + * + * The time port must be active before it starts forwarding traffic. + * + * Since: 1.10 + **/ + obj_properties[PROP_BOND_UPDELAY] = + g_param_spec_uint(NM_SETTING_OVS_PORT_BOND_UPDELAY, + "", + "", + 0, + G_MAXUINT, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingOvsPort:bond-downdelay: + * + * The time port must be inactive in order to be considered down. + * + * Since: 1.10 + **/ + obj_properties[PROP_BOND_DOWNDELAY] = + g_param_spec_uint(NM_SETTING_OVS_PORT_BOND_DOWNDELAY, + "", + "", + 0, + G_MAXUINT, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_OVS_PORT); +} diff --git a/src/libnm-core-impl/nm-setting-ppp.c b/src/libnm-core-impl/nm-setting-ppp.c new file mode 100644 index 0000000..cddd834 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ppp.c @@ -0,0 +1,778 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ppp.h" + +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-ppp + * @short_description: Describes connection properties for devices/networks + * that require PPP to deliver IP capability + * + * The #NMSettingPpp object is a #NMSetting subclass that describes properties + * necessary for connection to networks that require PPP transport, like PPPoE + * cable and DSL modems and some mobile broadband devices. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_NOAUTH, + PROP_REFUSE_EAP, + PROP_REFUSE_PAP, + PROP_REFUSE_CHAP, + PROP_REFUSE_MSCHAP, + PROP_REFUSE_MSCHAPV2, + PROP_NOBSDCOMP, + PROP_NODEFLATE, + PROP_NO_VJ_COMP, + PROP_REQUIRE_MPPE, + PROP_REQUIRE_MPPE_128, + PROP_MPPE_STATEFUL, + PROP_CRTSCTS, + PROP_BAUD, + PROP_MRU, + PROP_MTU, + PROP_LCP_ECHO_FAILURE, + PROP_LCP_ECHO_INTERVAL, ); + +typedef struct { + guint32 baud; + guint32 mru; + guint32 mtu; + guint32 lcp_echo_failure; + guint32 lcp_echo_interval; + bool noauth : 1; + bool refuse_eap : 1; + bool refuse_pap : 1; + bool refuse_chap : 1; + bool refuse_mschap : 1; + bool refuse_mschapv2 : 1; + bool nobsdcomp : 1; + bool nodeflate : 1; + bool no_vj_comp : 1; + bool require_mppe : 1; + bool require_mppe_128 : 1; + bool mppe_stateful : 1; + bool crtscts : 1; +} NMSettingPppPrivate; + +G_DEFINE_TYPE(NMSettingPpp, nm_setting_ppp, NM_TYPE_SETTING) + +#define NM_SETTING_PPP_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_PPP, NMSettingPppPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_ppp_get_noauth: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:noauth property of the setting + **/ +gboolean +nm_setting_ppp_get_noauth(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->noauth; +} + +/** + * nm_setting_ppp_get_refuse_eap: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:refuse-eap property of the setting + **/ +gboolean +nm_setting_ppp_get_refuse_eap(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->refuse_eap; +} + +/** + * nm_setting_ppp_get_refuse_pap: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:refuse-pap property of the setting + **/ +gboolean +nm_setting_ppp_get_refuse_pap(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->refuse_pap; +} + +/** + * nm_setting_ppp_get_refuse_chap: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:refuse-chap property of the setting + **/ +gboolean +nm_setting_ppp_get_refuse_chap(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->refuse_chap; +} + +/** + * nm_setting_ppp_get_refuse_mschap: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:refuse-mschap property of the setting + **/ +gboolean +nm_setting_ppp_get_refuse_mschap(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->refuse_mschap; +} + +/** + * nm_setting_ppp_get_refuse_mschapv2: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:refuse-mschapv2 property of the setting + **/ +gboolean +nm_setting_ppp_get_refuse_mschapv2(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->refuse_mschapv2; +} + +/** + * nm_setting_ppp_get_nobsdcomp: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:nobsdcomp property of the setting + **/ +gboolean +nm_setting_ppp_get_nobsdcomp(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->nobsdcomp; +} + +/** + * nm_setting_ppp_get_nodeflate: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:nodeflate property of the setting + **/ +gboolean +nm_setting_ppp_get_nodeflate(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->nodeflate; +} + +/** + * nm_setting_ppp_get_no_vj_comp: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:no-vj-comp property of the setting + **/ +gboolean +nm_setting_ppp_get_no_vj_comp(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->no_vj_comp; +} + +/** + * nm_setting_ppp_get_require_mppe: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:require-mppe property of the setting + **/ +gboolean +nm_setting_ppp_get_require_mppe(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->require_mppe; +} + +/** + * nm_setting_ppp_get_require_mppe_128: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:require-mppe-128 property of the setting + **/ +gboolean +nm_setting_ppp_get_require_mppe_128(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->require_mppe_128; +} + +/** + * nm_setting_ppp_get_mppe_stateful: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:mppe-stateful property of the setting + **/ +gboolean +nm_setting_ppp_get_mppe_stateful(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->mppe_stateful; +} + +/** + * nm_setting_ppp_get_crtscts: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:crtscts property of the setting + **/ +gboolean +nm_setting_ppp_get_crtscts(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->crtscts; +} + +/** + * nm_setting_ppp_get_baud: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:baud property of the setting + **/ +guint32 +nm_setting_ppp_get_baud(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), 0); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->baud; +} + +/** + * nm_setting_ppp_get_mru: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:mru property of the setting + **/ +guint32 +nm_setting_ppp_get_mru(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), 0); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->mru; +} + +/** + * nm_setting_ppp_get_mtu: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:mtu property of the setting + **/ +guint32 +nm_setting_ppp_get_mtu(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), 0); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->mtu; +} + +/** + * nm_setting_ppp_get_lcp_echo_failure: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:lcp-echo-failure property of the setting + **/ +guint32 +nm_setting_ppp_get_lcp_echo_failure(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), 0); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->lcp_echo_failure; +} + +/** + * nm_setting_ppp_get_lcp_echo_interval: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:lcp-echo-interval property of the setting + **/ +guint32 +nm_setting_ppp_get_lcp_echo_interval(NMSettingPpp *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPP(setting), 0); + + return NM_SETTING_PPP_GET_PRIVATE(setting)->lcp_echo_interval; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingPppPrivate *priv = NM_SETTING_PPP_GET_PRIVATE(setting); + + /* FIXME: Do we even want this or can we just let pppd evaluate the options? */ + if (priv->mru > 0) { + if (priv->mru < 128 || priv->mru > 16384) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' is out of valid range <128-16384>"), + priv->mru); + g_prefix_error(error, "%s.%s: ", NM_SETTING_PPP_SETTING_NAME, NM_SETTING_PPP_MRU); + return FALSE; + } + } + + if (priv->lcp_echo_failure > 0) { + /* lcp_echo_interval must also be non-zero */ + if (priv->lcp_echo_interval == 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("setting this property requires non-zero '%s' property"), + NM_SETTING_PPP_LCP_ECHO_INTERVAL); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_PPP_SETTING_NAME, + NM_SETTING_PPP_LCP_ECHO_FAILURE); + return FALSE; + } + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingPpp *setting = NM_SETTING_PPP(object); + + switch (prop_id) { + case PROP_NOAUTH: + g_value_set_boolean(value, nm_setting_ppp_get_noauth(setting)); + break; + case PROP_REFUSE_EAP: + g_value_set_boolean(value, nm_setting_ppp_get_refuse_eap(setting)); + break; + case PROP_REFUSE_PAP: + g_value_set_boolean(value, nm_setting_ppp_get_refuse_pap(setting)); + break; + case PROP_REFUSE_CHAP: + g_value_set_boolean(value, nm_setting_ppp_get_refuse_chap(setting)); + break; + case PROP_REFUSE_MSCHAP: + g_value_set_boolean(value, nm_setting_ppp_get_refuse_mschap(setting)); + break; + case PROP_REFUSE_MSCHAPV2: + g_value_set_boolean(value, nm_setting_ppp_get_refuse_mschapv2(setting)); + break; + case PROP_NOBSDCOMP: + g_value_set_boolean(value, nm_setting_ppp_get_nobsdcomp(setting)); + break; + case PROP_NODEFLATE: + g_value_set_boolean(value, nm_setting_ppp_get_nodeflate(setting)); + break; + case PROP_NO_VJ_COMP: + g_value_set_boolean(value, nm_setting_ppp_get_no_vj_comp(setting)); + break; + case PROP_REQUIRE_MPPE: + g_value_set_boolean(value, nm_setting_ppp_get_require_mppe(setting)); + break; + case PROP_REQUIRE_MPPE_128: + g_value_set_boolean(value, nm_setting_ppp_get_require_mppe_128(setting)); + break; + case PROP_MPPE_STATEFUL: + g_value_set_boolean(value, nm_setting_ppp_get_mppe_stateful(setting)); + break; + case PROP_CRTSCTS: + g_value_set_boolean(value, nm_setting_ppp_get_crtscts(setting)); + break; + case PROP_BAUD: + g_value_set_uint(value, nm_setting_ppp_get_baud(setting)); + break; + case PROP_MRU: + g_value_set_uint(value, nm_setting_ppp_get_mru(setting)); + break; + case PROP_MTU: + g_value_set_uint(value, nm_setting_ppp_get_mtu(setting)); + break; + case PROP_LCP_ECHO_FAILURE: + g_value_set_uint(value, nm_setting_ppp_get_lcp_echo_failure(setting)); + break; + case PROP_LCP_ECHO_INTERVAL: + g_value_set_uint(value, nm_setting_ppp_get_lcp_echo_interval(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingPppPrivate *priv = NM_SETTING_PPP_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_NOAUTH: + priv->noauth = g_value_get_boolean(value); + break; + case PROP_REFUSE_EAP: + priv->refuse_eap = g_value_get_boolean(value); + break; + case PROP_REFUSE_PAP: + priv->refuse_pap = g_value_get_boolean(value); + break; + case PROP_REFUSE_CHAP: + priv->refuse_chap = g_value_get_boolean(value); + break; + case PROP_REFUSE_MSCHAP: + priv->refuse_mschap = g_value_get_boolean(value); + break; + case PROP_REFUSE_MSCHAPV2: + priv->refuse_mschapv2 = g_value_get_boolean(value); + break; + case PROP_NOBSDCOMP: + priv->nobsdcomp = g_value_get_boolean(value); + break; + case PROP_NODEFLATE: + priv->nodeflate = g_value_get_boolean(value); + break; + case PROP_NO_VJ_COMP: + priv->no_vj_comp = g_value_get_boolean(value); + break; + case PROP_REQUIRE_MPPE: + priv->require_mppe = g_value_get_boolean(value); + break; + case PROP_REQUIRE_MPPE_128: + priv->require_mppe_128 = g_value_get_boolean(value); + break; + case PROP_MPPE_STATEFUL: + priv->mppe_stateful = g_value_get_boolean(value); + break; + case PROP_CRTSCTS: + priv->crtscts = g_value_get_boolean(value); + break; + case PROP_BAUD: + priv->baud = g_value_get_uint(value); + break; + case PROP_MRU: + priv->mru = g_value_get_uint(value); + break; + case PROP_MTU: + priv->mtu = g_value_get_uint(value); + break; + case PROP_LCP_ECHO_FAILURE: + priv->lcp_echo_failure = g_value_get_uint(value); + break; + case PROP_LCP_ECHO_INTERVAL: + priv->lcp_echo_interval = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_ppp_init(NMSettingPpp *self) +{ + NMSettingPppPrivate *priv = NM_SETTING_PPP_GET_PRIVATE(self); + + priv->noauth = TRUE; +} + +/** + * nm_setting_ppp_new: + * + * Creates a new #NMSettingPpp object with default values. + * + * Returns: (transfer full): the new empty #NMSettingPpp object + **/ +NMSetting * +nm_setting_ppp_new(void) +{ + return g_object_new(NM_TYPE_SETTING_PPP, NULL); +} + +static void +nm_setting_ppp_class_init(NMSettingPppClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingPppPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + + setting_class->verify = verify; + + /** + * NMSettingPpp:noauth: + * + * If %TRUE, do not require the other side (usually the PPP server) to + * authenticate itself to the client. If %FALSE, require authentication + * from the remote side. In almost all cases, this should be %TRUE. + **/ + obj_properties[PROP_NOAUTH] = g_param_spec_boolean(NM_SETTING_PPP_NOAUTH, + "", + "", + TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:refuse-eap: + * + * If %TRUE, the EAP authentication method will not be used. + **/ + obj_properties[PROP_REFUSE_EAP] = + g_param_spec_boolean(NM_SETTING_PPP_REFUSE_EAP, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:refuse-pap: + * + * If %TRUE, the PAP authentication method will not be used. + **/ + obj_properties[PROP_REFUSE_PAP] = + g_param_spec_boolean(NM_SETTING_PPP_REFUSE_PAP, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:refuse-chap: + * + * If %TRUE, the CHAP authentication method will not be used. + **/ + obj_properties[PROP_REFUSE_CHAP] = + g_param_spec_boolean(NM_SETTING_PPP_REFUSE_CHAP, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:refuse-mschap: + * + * If %TRUE, the MSCHAP authentication method will not be used. + **/ + obj_properties[PROP_REFUSE_MSCHAP] = + g_param_spec_boolean(NM_SETTING_PPP_REFUSE_MSCHAP, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:refuse-mschapv2: + * + * If %TRUE, the MSCHAPv2 authentication method will not be used. + **/ + obj_properties[PROP_REFUSE_MSCHAPV2] = + g_param_spec_boolean(NM_SETTING_PPP_REFUSE_MSCHAPV2, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:nobsdcomp: + * + * If %TRUE, BSD compression will not be requested. + **/ + obj_properties[PROP_NOBSDCOMP] = g_param_spec_boolean( + NM_SETTING_PPP_NOBSDCOMP, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:nodeflate: + * + * If %TRUE, "deflate" compression will not be requested. + **/ + obj_properties[PROP_NODEFLATE] = g_param_spec_boolean( + NM_SETTING_PPP_NODEFLATE, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:no-vj-comp: + * + * If %TRUE, Van Jacobsen TCP header compression will not be requested. + **/ + obj_properties[PROP_NO_VJ_COMP] = g_param_spec_boolean( + NM_SETTING_PPP_NO_VJ_COMP, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:require-mppe: + * + * If %TRUE, MPPE (Microsoft Point-to-Point Encryption) will be required for + * the PPP session. If either 64-bit or 128-bit MPPE is not available the + * session will fail. Note that MPPE is not used on mobile broadband + * connections. + **/ + obj_properties[PROP_REQUIRE_MPPE] = + g_param_spec_boolean(NM_SETTING_PPP_REQUIRE_MPPE, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:require-mppe-128: + * + * If %TRUE, 128-bit MPPE (Microsoft Point-to-Point Encryption) will be + * required for the PPP session, and the "require-mppe" property must also + * be set to %TRUE. If 128-bit MPPE is not available the session will fail. + **/ + obj_properties[PROP_REQUIRE_MPPE_128] = + g_param_spec_boolean(NM_SETTING_PPP_REQUIRE_MPPE_128, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:mppe-stateful: + * + * If %TRUE, stateful MPPE is used. See pppd documentation for more + * information on stateful MPPE. + **/ + obj_properties[PROP_MPPE_STATEFUL] = + g_param_spec_boolean(NM_SETTING_PPP_MPPE_STATEFUL, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:crtscts: + * + * If %TRUE, specify that pppd should set the serial port to use hardware + * flow control with RTS and CTS signals. This value should normally be set + * to %FALSE. + **/ + obj_properties[PROP_CRTSCTS] = g_param_spec_boolean(NM_SETTING_PPP_CRTSCTS, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:baud: + * + * If non-zero, instruct pppd to set the serial port to the specified + * baudrate. This value should normally be left as 0 to automatically + * choose the speed. + **/ + obj_properties[PROP_BAUD] = g_param_spec_uint(NM_SETTING_PPP_BAUD, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:mru: + * + * If non-zero, instruct pppd to request that the peer send packets no + * larger than the specified size. If non-zero, the MRU should be between + * 128 and 16384. + */ + obj_properties[PROP_MRU] = g_param_spec_uint(NM_SETTING_PPP_MRU, + "", + "", + 0, + 16384, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:mtu: + * + * If non-zero, instruct pppd to send packets no larger than the specified + * size. + **/ + obj_properties[PROP_MTU] = g_param_spec_uint(NM_SETTING_PPP_MTU, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:lcp-echo-failure: + * + * If non-zero, instruct pppd to presume the connection to the peer has + * failed if the specified number of LCP echo-requests go unanswered by the + * peer. The "lcp-echo-interval" property must also be set to a non-zero + * value if this property is used. + **/ + obj_properties[PROP_LCP_ECHO_FAILURE] = g_param_spec_uint( + NM_SETTING_PPP_LCP_ECHO_FAILURE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPpp:lcp-echo-interval: + * + * If non-zero, instruct pppd to send an LCP echo-request frame to the peer + * every n seconds (where n is the specified value). Note that some PPP + * peers will respond to echo requests and some will not, and it is not + * possible to autodetect this. + **/ + obj_properties[PROP_LCP_ECHO_INTERVAL] = g_param_spec_uint( + NM_SETTING_PPP_LCP_ECHO_INTERVAL, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_PPP); +} diff --git a/src/libnm-core-impl/nm-setting-pppoe.c b/src/libnm-core-impl/nm-setting-pppoe.c new file mode 100644 index 0000000..218bf94 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-pppoe.c @@ -0,0 +1,358 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-pppoe.h" + +#include "nm-setting-ppp.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-pppoe + * @short_description: Describes PPPoE connection properties + * + * The #NMSettingPppoe object is a #NMSetting subclass that describes + * properties necessary for connection to networks that require PPPoE connections + * to provide IP transport, for example cable or DSL modems. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, + PROP_SERVICE, + PROP_USERNAME, + PROP_PASSWORD, + PROP_PASSWORD_FLAGS, ); + +typedef struct { + char * parent; + char * service; + char * username; + char * password; + NMSettingSecretFlags password_flags; +} NMSettingPppoePrivate; + +G_DEFINE_TYPE(NMSettingPppoe, nm_setting_pppoe, NM_TYPE_SETTING) + +#define NM_SETTING_PPPOE_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_PPPOE, NMSettingPppoePrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_pppoe_get_parent: + * @setting: the #NMSettingPppoe + * + * Returns: the #NMSettingPppoe:parent property of the setting + * + * Since: 1.10 + **/ +const char * +nm_setting_pppoe_get_parent(NMSettingPppoe *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPPOE(setting), NULL); + + return NM_SETTING_PPPOE_GET_PRIVATE(setting)->parent; +} + +/** + * nm_setting_pppoe_get_service: + * @setting: the #NMSettingPppoe + * + * Returns: the #NMSettingPppoe:service property of the setting + **/ +const char * +nm_setting_pppoe_get_service(NMSettingPppoe *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPPOE(setting), NULL); + + return NM_SETTING_PPPOE_GET_PRIVATE(setting)->service; +} + +/** + * nm_setting_pppoe_get_username: + * @setting: the #NMSettingPppoe + * + * Returns: the #NMSettingPppoe:username property of the setting + **/ +const char * +nm_setting_pppoe_get_username(NMSettingPppoe *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPPOE(setting), NULL); + + return NM_SETTING_PPPOE_GET_PRIVATE(setting)->username; +} + +/** + * nm_setting_pppoe_get_password: + * @setting: the #NMSettingPppoe + * + * Returns: the #NMSettingPppoe:password property of the setting + **/ +const char * +nm_setting_pppoe_get_password(NMSettingPppoe *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPPOE(setting), NULL); + + return NM_SETTING_PPPOE_GET_PRIVATE(setting)->password; +} + +/** + * nm_setting_pppoe_get_password_flags: + * @setting: the #NMSettingPppoe + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingPppoe:password + **/ +NMSettingSecretFlags +nm_setting_pppoe_get_password_flags(NMSettingPppoe *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PPPOE(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_PPPOE_GET_PRIVATE(setting)->password_flags; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE(setting); + gs_free_error GError *local_error = NULL; + + if (!priv->username) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_USERNAME); + return FALSE; + } else if (!strlen(priv->username)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_USERNAME); + return FALSE; + } + + if (priv->service && !strlen(priv->service)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_SERVICE); + return FALSE; + } + + if (priv->parent && !nm_utils_ifname_valid_kernel(priv->parent, &local_error)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "'%s': %s", + priv->parent, + local_error->message); + g_prefix_error(error, "%s.%s: ", NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_PARENT); + return FALSE; + } + + return TRUE; +} + +static GPtrArray * +need_secrets(NMSetting *setting) +{ + NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE(setting); + GPtrArray * secrets = NULL; + + if (priv->password) + return NULL; + + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new(1); + g_ptr_array_add(secrets, NM_SETTING_PPPOE_PASSWORD); + } + + return secrets; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingPppoe *setting = NM_SETTING_PPPOE(object); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string(value, nm_setting_pppoe_get_parent(setting)); + break; + case PROP_SERVICE: + g_value_set_string(value, nm_setting_pppoe_get_service(setting)); + break; + case PROP_USERNAME: + g_value_set_string(value, nm_setting_pppoe_get_username(setting)); + break; + case PROP_PASSWORD: + g_value_set_string(value, nm_setting_pppoe_get_password(setting)); + break; + case PROP_PASSWORD_FLAGS: + g_value_set_flags(value, nm_setting_pppoe_get_password_flags(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_PARENT: + g_free(priv->parent); + priv->parent = g_value_dup_string(value); + break; + case PROP_SERVICE: + g_free(priv->service); + priv->service = g_value_dup_string(value); + break; + case PROP_USERNAME: + g_free(priv->username); + priv->username = g_value_dup_string(value); + break; + case PROP_PASSWORD: + g_free(priv->password); + priv->password = g_value_dup_string(value); + break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_flags(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_pppoe_init(NMSettingPppoe *setting) +{} + +/** + * nm_setting_pppoe_new: + * + * Creates a new #NMSettingPppoe object with default values. + * + * Returns: (transfer full): the new empty #NMSettingPppoe object + **/ +NMSetting * +nm_setting_pppoe_new(void) +{ + return g_object_new(NM_TYPE_SETTING_PPPOE, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE(object); + + g_free(priv->parent); + g_free(priv->username); + g_free(priv->password); + g_free(priv->service); + + G_OBJECT_CLASS(nm_setting_pppoe_parent_class)->finalize(object); +} + +static void +nm_setting_pppoe_class_init(NMSettingPppoeClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingPppoePrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->need_secrets = need_secrets; + + /** + * NMSettingPppoe:parent: + * + * If given, specifies the parent interface name on which this PPPoE + * connection should be created. If this property is not specified, + * the connection is activated on the interface specified in + * #NMSettingConnection:interface-name of #NMSettingConnection. + * + * Since: 1.10 + **/ + obj_properties[PROP_PARENT] = g_param_spec_string( + NM_SETTING_PPPOE_PARENT, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPppoe:service: + * + * If specified, instruct PPPoE to only initiate sessions with access + * concentrators that provide the specified service. For most providers, + * this should be left blank. It is only required if there are multiple + * access concentrators or a specific service is known to be required. + **/ + obj_properties[PROP_SERVICE] = g_param_spec_string(NM_SETTING_PPPOE_SERVICE, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPppoe:username: + * + * Username used to authenticate with the PPPoE service. + **/ + obj_properties[PROP_USERNAME] = g_param_spec_string(NM_SETTING_PPPOE_USERNAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPppoe:password: + * + * Password used to authenticate with the PPPoE service. + **/ + obj_properties[PROP_PASSWORD] = + g_param_spec_string(NM_SETTING_PPPOE_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingPppoe:password-flags: + * + * Flags indicating how to handle the #NMSettingPppoe:password property. + **/ + obj_properties[PROP_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_PPPOE_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_PPPOE); +} diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h new file mode 100644 index 0000000..bf59a3c --- /dev/null +++ b/src/libnm-core-impl/nm-setting-private.h @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_PRIVATE_H__ +#define __NM_SETTING_PRIVATE_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) + #error Cannot use this header. +#endif + +#include "nm-setting.h" +#include "nm-setting-bridge.h" +#include "nm-connection.h" +#include "nm-core-enum-types.h" + +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +NMSettingPriority _nm_setting_get_base_type_priority(NMSetting *setting); +int _nm_setting_compare_priority(gconstpointer a, gconstpointer b); + +/*****************************************************************************/ + +void _nm_setting_emit_property_changed(NMSetting *setting); + +typedef enum NMSettingUpdateSecretResult { + NM_SETTING_UPDATE_SECRET_ERROR = FALSE, + NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED = TRUE, + NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED = 2, +} NMSettingUpdateSecretResult; + +NMSettingUpdateSecretResult + _nm_setting_update_secrets(NMSetting *setting, GVariant *secrets, GError **error); +gboolean _nm_setting_clear_secrets(NMSetting * setting, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data); + +/* The property of the #NMSetting should be considered during comparisons that + * use the %NM_SETTING_COMPARE_FLAG_INFERRABLE flag. Properties that don't have + * this flag, are ignored when doing an infrerrable comparison. This flag should + * be set on all properties that are read from the kernel or the system when a + * connection is generated. eg, IP addresses/routes can be read from the + * kernel, but the 'autoconnect' property cannot, so + * %NM_SETTING_IP4_CONFIG_ADDRESSES gets the INFERRABLE flag, but + * %NM_SETTING_CONNECTION_AUTOCONNECT would not. + * + * This flag should not be used with properties where the default cannot be + * read separately from the current value, like MTU or wired duplex mode. + */ +#define NM_SETTING_PARAM_INFERRABLE (1 << (4 + G_PARAM_USER_SHIFT)) + +/* This is a legacy property, which clients should not send to the daemon. */ +#define NM_SETTING_PARAM_LEGACY (1 << (5 + G_PARAM_USER_SHIFT)) + +/* When a connection is active and gets modified, usually the change + * to the settings-connection does not propagate automatically to the + * applied-connection of the device. For certain properties like the + * firewall zone and the metered property, this is different. + * + * Such fields can be ignored during nm_connection_compare() with the + * NMSettingCompareFlag NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY. + */ +#define NM_SETTING_PARAM_REAPPLY_IMMEDIATELY (1 << (6 + G_PARAM_USER_SHIFT)) + +/* property_to_dbus() should ignore the property flags, and instead always calls to_dbus_fcn() + */ +#define NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS (1 << (7 + G_PARAM_USER_SHIFT)) + +extern const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_interface_name; +extern const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_i; +extern const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_u; + +extern const NMSettInfoPropertType nm_sett_info_propert_type_plain_i; +extern const NMSettInfoPropertType nm_sett_info_propert_type_plain_u; + +NMSettingVerifyResult +_nm_setting_verify(NMSetting *setting, NMConnection *connection, GError **error); + +gboolean _nm_setting_verify_secret_string(const char *str, + const char *setting_name, + const char *property, + GError ** error); + +gboolean _nm_setting_aggregate(NMSetting *setting, NMConnectionAggregateType type, gpointer arg); + +gboolean _nm_setting_slave_type_is_valid(const char *slave_type, const char **out_port_type); + +GVariant *_nm_setting_to_dbus(NMSetting * setting, + NMConnection * connection, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); + +NMSetting *_nm_setting_new_from_dbus(GType setting_type, + GVariant * setting_dict, + GVariant * connection_dict, + NMSettingParseFlags parse_flags, + GError ** error); + +gboolean _nm_setting_property_is_regular_secret(NMSetting *setting, const char *secret_name); +gboolean _nm_setting_property_is_regular_secret_flags(NMSetting * setting, + const char *secret_flags_name); + +/*****************************************************************************/ + +static inline GArray * +_nm_sett_info_property_override_create_array(void) +{ + return g_array_new(FALSE, FALSE, sizeof(NMSettInfoProperty)); +} + +GArray *_nm_sett_info_property_override_create_array_ip_config(void); + +void _nm_setting_class_commit_full(NMSettingClass * setting_class, + NMMetaSettingType meta_type, + const NMSettInfoSettDetail *detail, + GArray * properties_override); + +static inline void +_nm_setting_class_commit(NMSettingClass *setting_class, NMMetaSettingType meta_type) +{ + _nm_setting_class_commit_full(setting_class, meta_type, NULL, NULL); +} + +#define NM_SETT_INFO_SETT_GENDATA(...) \ + ({ \ + static const NMSettInfoSettGendata _g = {__VA_ARGS__}; \ + \ + &_g; \ + }) + +#define NM_SETT_INFO_SETT_DETAIL(...) (&((const NMSettInfoSettDetail){__VA_ARGS__})) + +#define NM_SETT_INFO_PROPERT_TYPE(...) \ + ({ \ + static const NMSettInfoPropertType _g = {__VA_ARGS__}; \ + \ + &_g; \ + }) + +#define NM_SETT_INFO_PROPERTY(...) (&((const NMSettInfoProperty){__VA_ARGS__})) + +gboolean _nm_properties_override_assert(const NMSettInfoProperty *prop_info); + +static inline void +_nm_properties_override(GArray *properties_override, const NMSettInfoProperty *prop_info) +{ + nm_assert(properties_override); + nm_assert(_nm_properties_override_assert(prop_info)); + g_array_append_vals(properties_override, prop_info, 1); +} + +#define _nm_properties_override_gobj(properties_override, p_param_spec, p_property_type) \ + _nm_properties_override( \ + (properties_override), \ + NM_SETT_INFO_PROPERTY(.param_spec = (p_param_spec), .property_type = (p_property_type), )) + +#define _nm_properties_override_dbus(properties_override, p_name, p_property_type) \ + _nm_properties_override( \ + (properties_override), \ + NM_SETT_INFO_PROPERTY(.name = ("" p_name ""), .property_type = (p_property_type), )) + +/*****************************************************************************/ + +gboolean _nm_setting_use_legacy_property(NMSetting * setting, + GVariant * connection_dict, + const char *legacy_property, + const char *new_property); + +GPtrArray *_nm_setting_need_secrets(NMSetting *setting); + +gboolean _nm_setting_should_compare_secret_property(NMSetting * setting, + NMSetting * other, + const char * secret_name, + NMSettingCompareFlags flags); + +NMBridgeVlan *_nm_bridge_vlan_dup(const NMBridgeVlan *vlan); +NMBridgeVlan *_nm_bridge_vlan_dup_and_seal(const NMBridgeVlan *vlan); + +/*****************************************************************************/ + +#endif /* NM_SETTING_PRIVATE_H */ diff --git a/src/libnm-core-impl/nm-setting-proxy.c b/src/libnm-core-impl/nm-setting-proxy.c new file mode 100644 index 0000000..1e7eca8 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-proxy.c @@ -0,0 +1,383 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Atul Anand . + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-proxy.h" + +#include "nm-utils.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-proxy + * @short_description: Describes proxy URL, script and other related properties + * + * The #NMSettingProxy object is a #NMSetting subclass that describes properties + * related to Proxy settings like PAC URL, PAC script etc. + * + * NetworkManager support 2 values for the #NMSettingProxy:method property for + * proxy. If "auto" is specified then WPAD takes place and the appropriate details + * are pushed into PacRunner or user can override this URL with a new PAC URL or a + * PAC script. If "none" is selected then no proxy configuration is given to PacRunner + * to fulfill client queries. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_METHOD, PROP_BROWSER_ONLY, PROP_PAC_URL, PROP_PAC_SCRIPT, ); + +typedef struct { + char *pac_url; + char *pac_script; + int method; + bool browser_only : 1; +} NMSettingProxyPrivate; + +G_DEFINE_TYPE(NMSettingProxy, nm_setting_proxy, NM_TYPE_SETTING) + +#define NM_SETTING_PROXY_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_PROXY, NMSettingProxyPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_proxy_get_method: + * @setting: the #NMSettingProxy + * + * Returns the proxy configuration method. By default the value is %NM_SETTING_PROXY_METHOD_NONE. + * %NM_SETTING_PROXY_METHOD_NONE should be selected for a connection intended for direct network + * access. + * + * Returns: the proxy configuration method + * + * Since: 1.6 + **/ +NMSettingProxyMethod +nm_setting_proxy_get_method(NMSettingProxy *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PROXY(setting), NM_SETTING_PROXY_METHOD_NONE); + + return NM_SETTING_PROXY_GET_PRIVATE(setting)->method; +} + +/** + * nm_setting_proxy_get_browser_only: + * @setting: the #NMSettingProxy + * + * Returns: %TRUE if this proxy configuration is only for browser + * clients/schemes, %FALSE otherwise. + * + * Since: 1.6 + **/ +gboolean +nm_setting_proxy_get_browser_only(NMSettingProxy *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PROXY(setting), FALSE); + + return NM_SETTING_PROXY_GET_PRIVATE(setting)->browser_only; +} + +/** + * nm_setting_proxy_get_pac_url: + * @setting: the #NMSettingProxy + * + * Returns: the PAC URL for obtaining PAC file + * + * Since: 1.6 + **/ +const char * +nm_setting_proxy_get_pac_url(NMSettingProxy *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PROXY(setting), NULL); + + return NM_SETTING_PROXY_GET_PRIVATE(setting)->pac_url; +} + +/** + * nm_setting_proxy_get_pac_script: + * @setting: the #NMSettingProxy + * + * Returns: the PAC script + * + * Since: 1.6 + **/ +const char * +nm_setting_proxy_get_pac_script(NMSettingProxy *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_PROXY(setting), NULL); + + return NM_SETTING_PROXY_GET_PRIVATE(setting)->pac_script; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingProxyPrivate *priv = NM_SETTING_PROXY_GET_PRIVATE(setting); + + if (!NM_IN_SET(priv->method, NM_SETTING_PROXY_METHOD_NONE, NM_SETTING_PROXY_METHOD_AUTO)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid proxy method")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_URL); + return FALSE; + } + + if (priv->method != NM_SETTING_PROXY_METHOD_AUTO) { + if (priv->pac_url) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for method none")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_PROXY_PAC_URL); + return FALSE; + } + + if (priv->pac_script) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for method none")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_PROXY_PAC_SCRIPT); + return FALSE; + } + } + + if (priv->pac_script) { + if (strlen(priv->pac_script) > 1 * 1024 * 1024) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the script is too large")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_PROXY_PAC_SCRIPT); + return FALSE; + } + if (!g_utf8_validate(priv->pac_script, -1, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the script is not valid utf8")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_PROXY_PAC_SCRIPT); + return FALSE; + } + if (!strstr(priv->pac_script, "FindProxyForURL")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the script lacks FindProxyForURL function")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_PROXY_PAC_SCRIPT); + return FALSE; + } + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingProxy *setting = NM_SETTING_PROXY(object); + + switch (prop_id) { + case PROP_METHOD: + g_value_set_int(value, nm_setting_proxy_get_method(setting)); + break; + case PROP_BROWSER_ONLY: + g_value_set_boolean(value, nm_setting_proxy_get_browser_only(setting)); + break; + case PROP_PAC_URL: + g_value_set_string(value, nm_setting_proxy_get_pac_url(setting)); + break; + case PROP_PAC_SCRIPT: + g_value_set_string(value, nm_setting_proxy_get_pac_script(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingProxyPrivate *priv = NM_SETTING_PROXY_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_METHOD: + priv->method = g_value_get_int(value); + break; + case PROP_BROWSER_ONLY: + priv->browser_only = g_value_get_boolean(value); + break; + case PROP_PAC_URL: + g_free(priv->pac_url); + priv->pac_url = g_value_dup_string(value); + break; + case PROP_PAC_SCRIPT: + g_free(priv->pac_script); + priv->pac_script = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_proxy_init(NMSettingProxy *self) +{ + nm_assert(NM_SETTING_PROXY_GET_PRIVATE(self)->method == NM_SETTING_PROXY_METHOD_NONE); +} + +/** + * nm_setting_proxy_new: + * + * Creates a new #NMSettingProxy object. + * + * Returns: the new empty #NMSettingProxy object + * + * Since: 1.6 + **/ +NMSetting * +nm_setting_proxy_new(void) +{ + return g_object_new(NM_TYPE_SETTING_PROXY, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingProxy * self = NM_SETTING_PROXY(object); + NMSettingProxyPrivate *priv = NM_SETTING_PROXY_GET_PRIVATE(self); + + g_free(priv->pac_url); + g_free(priv->pac_script); + + G_OBJECT_CLASS(nm_setting_proxy_parent_class)->finalize(object); +} + +static void +nm_setting_proxy_class_init(NMSettingProxyClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingProxyPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingProxy:method: + * + * Method for proxy configuration, Default is %NM_SETTING_PROXY_METHOD_NONE + * + * Since: 1.6 + **/ + /* ---ifcfg-rh--- + * property: method + * variable: PROXY_METHOD(+) + * default: none + * description: Method for proxy configuration. For "auto", WPAD is used for + * proxy configuration, or set the PAC file via PAC_URL or PAC_SCRIPT. + * values: none, auto + * ---end--- + */ + obj_properties[PROP_METHOD] = g_param_spec_int(NM_SETTING_PROXY_METHOD, + "", + "", + G_MININT32, + G_MAXINT32, + NM_SETTING_PROXY_METHOD_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingProxy:browser-only: + * + * Whether the proxy configuration is for browser only. + * + * Since: 1.6 + **/ + /* ---ifcfg-rh--- + * property: browser-only + * variable: BROWSER_ONLY(+) + * default: no + * description: Whether the proxy configuration is for browser only. + * ---end--- + */ + obj_properties[PROP_BROWSER_ONLY] = + g_param_spec_boolean(NM_SETTING_PROXY_BROWSER_ONLY, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingProxy:pac-url: + * + * PAC URL for obtaining PAC file. + * + * Since: 1.6 + **/ + /* ---ifcfg-rh--- + * property: pac-url + * variable: PAC_URL(+) + * description: URL for PAC file. + * example: PAC_URL=http://wpad.mycompany.com/wpad.dat + * ---end--- + */ + obj_properties[PROP_PAC_URL] = g_param_spec_string(NM_SETTING_PROXY_PAC_URL, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingProxy:pac-script: + * + * PAC script for the connection. + * + * Since: 1.6 + **/ + /* ---ifcfg-rh--- + * property: pac-script + * variable: PAC_SCRIPT(+) + * description: Path of the PAC script. + * example: PAC_SCRIPT=/home/joe/proxy.pac + * ---end--- + */ + obj_properties[PROP_PAC_SCRIPT] = + g_param_spec_string(NM_SETTING_PROXY_PAC_SCRIPT, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_PROXY); +} diff --git a/src/libnm-core-impl/nm-setting-serial.c b/src/libnm-core-impl/nm-setting-serial.c new file mode 100644 index 0000000..1df87b6 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-serial.c @@ -0,0 +1,336 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2018 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-serial.h" + +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-serial + * @short_description: Describes connection properties for devices that use + * serial communications + * + * The #NMSettingSerial object is a #NMSetting subclass that describes + * properties necessary for connections that may use serial communications, + * such as mobile broadband or analog telephone connections. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_BAUD, + PROP_BITS, + PROP_PARITY, + PROP_STOPBITS, + PROP_SEND_DELAY, ); + +typedef struct { + guint64 send_delay; + guint baud; + guint bits; + guint stopbits; + char parity; +} NMSettingSerialPrivate; + +G_DEFINE_TYPE(NMSettingSerial, nm_setting_serial, NM_TYPE_SETTING) + +#define NM_SETTING_SERIAL_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_SERIAL, NMSettingSerialPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_serial_get_baud: + * @setting: the #NMSettingSerial + * + * Returns: the #NMSettingSerial:baud property of the setting + **/ +guint +nm_setting_serial_get_baud(NMSettingSerial *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_SERIAL(setting), 0); + + return NM_SETTING_SERIAL_GET_PRIVATE(setting)->baud; +} + +/** + * nm_setting_serial_get_bits: + * @setting: the #NMSettingSerial + * + * Returns: the #NMSettingSerial:bits property of the setting + **/ +guint +nm_setting_serial_get_bits(NMSettingSerial *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_SERIAL(setting), 0); + + return NM_SETTING_SERIAL_GET_PRIVATE(setting)->bits; +} + +/** + * nm_setting_serial_get_parity: + * @setting: the #NMSettingSerial + * + * Returns: the #NMSettingSerial:parity property of the setting + **/ +NMSettingSerialParity +nm_setting_serial_get_parity(NMSettingSerial *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_SERIAL(setting), 0); + + return NM_SETTING_SERIAL_GET_PRIVATE(setting)->parity; +} + +/** + * nm_setting_serial_get_stopbits: + * @setting: the #NMSettingSerial + * + * Returns: the #NMSettingSerial:stopbits property of the setting + **/ +guint +nm_setting_serial_get_stopbits(NMSettingSerial *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_SERIAL(setting), 0); + + return NM_SETTING_SERIAL_GET_PRIVATE(setting)->stopbits; +} + +/** + * nm_setting_serial_get_send_delay: + * @setting: the #NMSettingSerial + * + * Returns: the #NMSettingSerial:send-delay property of the setting + **/ +guint64 +nm_setting_serial_get_send_delay(NMSettingSerial *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_SERIAL(setting), 0); + + return NM_SETTING_SERIAL_GET_PRIVATE(setting)->send_delay; +} + +static GVariant * +parity_to_dbus(const GValue *from) +{ + switch (g_value_get_enum(from)) { + case NM_SETTING_SERIAL_PARITY_EVEN: + return g_variant_new_byte('E'); + case NM_SETTING_SERIAL_PARITY_ODD: + return g_variant_new_byte('o'); + case NM_SETTING_SERIAL_PARITY_NONE: + default: + return g_variant_new_byte('n'); + } +} + +static void +parity_from_dbus(GVariant *from, GValue *to) +{ + switch (g_variant_get_byte(from)) { + case 'E': + g_value_set_enum(to, NM_SETTING_SERIAL_PARITY_EVEN); + break; + case 'o': + g_value_set_enum(to, NM_SETTING_SERIAL_PARITY_ODD); + break; + case 'n': + default: + g_value_set_enum(to, NM_SETTING_SERIAL_PARITY_NONE); + break; + } +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingSerial *setting = NM_SETTING_SERIAL(object); + + switch (prop_id) { + case PROP_BAUD: + g_value_set_uint(value, nm_setting_serial_get_baud(setting)); + break; + case PROP_BITS: + g_value_set_uint(value, nm_setting_serial_get_bits(setting)); + break; + case PROP_PARITY: + g_value_set_enum(value, nm_setting_serial_get_parity(setting)); + break; + case PROP_STOPBITS: + g_value_set_uint(value, nm_setting_serial_get_stopbits(setting)); + break; + case PROP_SEND_DELAY: + g_value_set_uint64(value, nm_setting_serial_get_send_delay(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingSerialPrivate *priv = NM_SETTING_SERIAL_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_BAUD: + priv->baud = g_value_get_uint(value); + break; + case PROP_BITS: + priv->bits = g_value_get_uint(value); + break; + case PROP_PARITY: + priv->parity = g_value_get_enum(value); + break; + case PROP_STOPBITS: + priv->stopbits = g_value_get_uint(value); + break; + case PROP_SEND_DELAY: + priv->send_delay = g_value_get_uint64(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_serial_init(NMSettingSerial *self) +{ + NMSettingSerialPrivate *priv = NM_SETTING_SERIAL_GET_PRIVATE(self); + + nm_assert(priv->parity == NM_SETTING_SERIAL_PARITY_NONE); + priv->stopbits = 1; + priv->baud = 57600; + priv->bits = 8; +} + +/** + * nm_setting_serial_new: + * + * Creates a new #NMSettingSerial object with default values. + * + * Returns: (transfer full): the new empty #NMSettingSerial object + **/ +NMSetting * +nm_setting_serial_new(void) +{ + return g_object_new(NM_TYPE_SETTING_SERIAL, NULL); +} + +static void +nm_setting_serial_class_init(NMSettingSerialClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingSerialPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + + /** + * NMSettingSerial:baud: + * + * Speed to use for communication over the serial port. Note that this + * value usually has no effect for mobile broadband modems as they generally + * ignore speed settings and use the highest available speed. + **/ + obj_properties[PROP_BAUD] = g_param_spec_uint(NM_SETTING_SERIAL_BAUD, + "", + "", + 0, + G_MAXUINT, + 57600, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingSerial:bits: + * + * Byte-width of the serial communication. The 8 in "8n1" for example. + **/ + obj_properties[PROP_BITS] = g_param_spec_uint(NM_SETTING_SERIAL_BITS, + "", + "", + 5, + 8, + 8, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingSerial:parity: + * + * Parity setting of the serial port. + **/ + /* ---keyfile--- + * property: parity + * format: 'e', 'o', or 'n' + * description: The connection parity; even, odd, or none. Note that older + * versions of NetworkManager stored this as an integer: 69 ('E') for even, + * 111 ('o') for odd, or 110 ('n') for none. + * example: parity=n + * ---end--- + * ---dbus--- + * property: parity + * format: byte + * description: The connection parity: 69 (ASCII 'E') for even parity, + * 111 (ASCII 'o') for odd, 110 (ASCII 'n') for none. + * ---end--- + */ + obj_properties[PROP_PARITY] = g_param_spec_enum(NM_SETTING_SERIAL_PARITY, + "", + "", + NM_TYPE_SETTING_SERIAL_PARITY, + NM_SETTING_SERIAL_PARITY_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_PARITY], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_BYTE, + .gprop_to_dbus_fcn = parity_to_dbus, + .gprop_from_dbus_fcn = parity_from_dbus, )); + + /** + * NMSettingSerial:stopbits: + * + * Number of stop bits for communication on the serial port. Either 1 or 2. + * The 1 in "8n1" for example. + **/ + obj_properties[PROP_STOPBITS] = g_param_spec_uint(NM_SETTING_SERIAL_STOPBITS, + "", + "", + 1, + 2, + 1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingSerial:send-delay: + * + * Time to delay between each byte sent to the modem, in microseconds. + **/ + obj_properties[PROP_SEND_DELAY] = + g_param_spec_uint64(NM_SETTING_SERIAL_SEND_DELAY, + "", + "", + 0, + G_MAXUINT64, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_SERIAL, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-sriov.c b/src/libnm-core-impl/nm-setting-sriov.c new file mode 100644 index 0000000..70e542d --- /dev/null +++ b/src/libnm-core-impl/nm-setting-sriov.c @@ -0,0 +1,1372 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-sriov.h" + +#include "nm-setting-private.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-sriov + * @short_description: Describes SR-IOV connection properties + * @include: nm-setting-sriov.h + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingSriov, PROP_TOTAL_VFS, PROP_VFS, PROP_AUTOPROBE_DRIVERS, ); + +/** + * NMSettingSriov: + * + * SR-IOV settings + * + * Since: 1.14 + */ +struct _NMSettingSriov { + NMSetting parent; + GPtrArray *vfs; + guint total_vfs; + NMTernary autoprobe_drivers; +}; + +struct _NMSettingSriovClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingSriov, nm_setting_sriov, NM_TYPE_SETTING) + +/*****************************************************************************/ + +G_DEFINE_BOXED_TYPE(NMSriovVF, nm_sriov_vf, nm_sriov_vf_dup, nm_sriov_vf_unref) + +struct _NMSriovVF { + guint refcount; + guint index; + GHashTable *attributes; + GHashTable *vlans; + guint * vlan_ids; +}; + +typedef struct { + guint id; + guint qos; + NMSriovVFVlanProtocol protocol; +} VFVlan; + +static guint +_vf_vlan_hash(gconstpointer ptr) +{ + return nm_hash_val(1348254767u, *((guint *) ptr)); +} + +static gboolean +_vf_vlan_equal(gconstpointer a, gconstpointer b) +{ + return *((guint *) a) == *((guint *) b); +} + +static GHashTable * +_vf_vlan_create_hash(void) +{ + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(VFVlan, id) == 0); + return g_hash_table_new_full(_vf_vlan_hash, _vf_vlan_equal, NULL, nm_g_slice_free_fcn(VFVlan)); +} + +/** + * nm_sriov_vf_new: + * @index: the VF index + * + * Creates a new #NMSriovVF object. + * + * Returns: (transfer full): the new #NMSriovVF object. + * + * Since: 1.14 + **/ +NMSriovVF * +nm_sriov_vf_new(guint index) +{ + NMSriovVF *vf; + + vf = g_slice_new(NMSriovVF); + *vf = (NMSriovVF){ + .refcount = 1, + .index = index, + .attributes = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref), + }; + return vf; +} + +/** + * nm_sriov_vf_ref: + * @vf: the #NMSriovVF + * + * Increases the reference count of the object. + * + * Since: 1.14 + **/ +void +nm_sriov_vf_ref(NMSriovVF *vf) +{ + g_return_if_fail(vf); + g_return_if_fail(vf->refcount > 0); + + vf->refcount++; +} + +/** + * nm_sriov_vf_unref: + * @vf: the #NMSriovVF + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + * + * Since: 1.14 + **/ +void +nm_sriov_vf_unref(NMSriovVF *vf) +{ + g_return_if_fail(vf); + g_return_if_fail(vf->refcount > 0); + + vf->refcount--; + if (vf->refcount == 0) { + g_hash_table_unref(vf->attributes); + if (vf->vlans) + g_hash_table_unref(vf->vlans); + g_free(vf->vlan_ids); + nm_g_slice_free(vf); + } +} + +/** + * nm_sriov_vf_equal: + * @vf: the #NMSriovVF + * @other: the #NMSriovVF to compare @vf to. + * + * Determines if two #NMSriovVF objects have the same index, + * attributes and VLANs. + * + * Returns: %TRUE if the objects contain the same values, %FALSE + * if they do not. + * + * Since: 1.14 + **/ +gboolean +nm_sriov_vf_equal(const NMSriovVF *vf, const NMSriovVF *other) +{ + GHashTableIter iter; + const char * key; + GVariant * value, *value2; + VFVlan * vlan, *vlan2; + guint n_vlans; + + g_return_val_if_fail(vf, FALSE); + g_return_val_if_fail(vf->refcount > 0, FALSE); + g_return_val_if_fail(other, FALSE); + g_return_val_if_fail(other->refcount > 0, FALSE); + + if (vf == other) + return TRUE; + + if (vf->index != other->index) + return FALSE; + + if (g_hash_table_size(vf->attributes) != g_hash_table_size(other->attributes)) + return FALSE; + g_hash_table_iter_init(&iter, vf->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) { + value2 = g_hash_table_lookup(other->attributes, key); + if (!value2) + return FALSE; + if (!g_variant_equal(value, value2)) + return FALSE; + } + + n_vlans = vf->vlans ? g_hash_table_size(vf->vlans) : 0u; + if (n_vlans != (other->vlans ? g_hash_table_size(other->vlans) : 0u)) + return FALSE; + if (n_vlans > 0) { + g_hash_table_iter_init(&iter, vf->vlans); + while (g_hash_table_iter_next(&iter, (gpointer *) &vlan, NULL)) { + vlan2 = g_hash_table_lookup(other->vlans, vlan); + if (!vlan2) + return FALSE; + if (vlan->qos != vlan2->qos || vlan->protocol != vlan2->protocol) + return FALSE; + } + } + + return TRUE; +} + +static void +vf_add_vlan(NMSriovVF *vf, guint vlan_id, guint qos, NMSriovVFVlanProtocol protocol) +{ + VFVlan *vlan; + + vlan = g_slice_new(VFVlan); + *vlan = (VFVlan){ + .id = vlan_id, + .qos = qos, + .protocol = protocol, + }; + + if (!vf->vlans) + vf->vlans = _vf_vlan_create_hash(); + + g_hash_table_add(vf->vlans, vlan); + nm_clear_g_free(&vf->vlan_ids); +} + +/** + * nm_sriov_vf_dup: + * @vf: the #NMSriovVF + * + * Creates a copy of @vf. + * + * Returns: (transfer full): a copy of @vf + * + * Since: 1.14 + **/ +NMSriovVF * +nm_sriov_vf_dup(const NMSriovVF *vf) +{ + NMSriovVF * copy; + GHashTableIter iter; + const char * name; + GVariant * variant; + VFVlan * vlan; + + g_return_val_if_fail(vf, NULL); + g_return_val_if_fail(vf->refcount > 0, NULL); + + copy = nm_sriov_vf_new(vf->index); + + g_hash_table_iter_init(&iter, vf->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) + nm_sriov_vf_set_attribute(copy, name, variant); + + if (vf->vlans) { + g_hash_table_iter_init(&iter, vf->vlans); + while (g_hash_table_iter_next(&iter, (gpointer *) &vlan, NULL)) + vf_add_vlan(copy, vlan->id, vlan->qos, vlan->protocol); + } + + return copy; +} + +/** + * nm_sriov_vf_get_index: + * @vf: the #NMSriovVF + * + * Gets the index property of this VF object. + * + * Returns: the VF index + * + * Since: 1.14 + **/ +guint +nm_sriov_vf_get_index(const NMSriovVF *vf) +{ + g_return_val_if_fail(vf, 0); + g_return_val_if_fail(vf->refcount > 0, 0); + + return vf->index; +} + +/** + * nm_sriov_vf_set_attribute: + * @vf: the #NMSriovVF + * @name: the name of a route attribute + * @value: (transfer none) (allow-none): the value + * + * Sets the named attribute on @vf to the given value. + * + * Since: 1.14 + **/ +void +nm_sriov_vf_set_attribute(NMSriovVF *vf, const char *name, GVariant *value) +{ + g_return_if_fail(vf); + g_return_if_fail(vf->refcount > 0); + g_return_if_fail(name && *name != '\0'); + g_return_if_fail(!nm_streq(name, "index")); + + if (value) { + g_hash_table_insert(vf->attributes, g_strdup(name), g_variant_ref_sink(value)); + } else + g_hash_table_remove(vf->attributes, name); +} + +/** + * nm_sriov_vf_get_attribute_names: + * @vf: the #NMSriovVF + * + * Gets an array of attribute names defined on @vf. + * + * Returns: (transfer container): a %NULL-terminated array of attribute names + * + * Since: 1.14 + **/ +const char ** +nm_sriov_vf_get_attribute_names(const NMSriovVF *vf) +{ + g_return_val_if_fail(vf, NULL); + g_return_val_if_fail(vf->refcount > 0, NULL); + + return nm_utils_strdict_get_keys(vf->attributes, TRUE, NULL); +} + +/** + * nm_sriov_vf_get_attribute: + * @vf: the #NMSriovVF + * @name: the name of a VF attribute + * + * Gets the value of the attribute with name @name on @vf + * + * Returns: (transfer none): the value of the attribute with name @name on + * @vf, or %NULL if @vf has no such attribute. + * + * Since: 1.14 + **/ +GVariant * +nm_sriov_vf_get_attribute(const NMSriovVF *vf, const char *name) +{ + g_return_val_if_fail(vf, NULL); + g_return_val_if_fail(vf->refcount > 0, NULL); + g_return_val_if_fail(name && *name != '\0', NULL); + + return g_hash_table_lookup(vf->attributes, name); +} + +const NMVariantAttributeSpec *const _nm_sriov_vf_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_SRIOV_VF_ATTRIBUTE_MAC, + G_VARIANT_TYPE_STRING, + .str_type = 'm', ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK, G_VARIANT_TYPE_BOOLEAN, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_SRIOV_VF_ATTRIBUTE_TRUST, G_VARIANT_TYPE_BOOLEAN, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE, G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE, G_VARIANT_TYPE_UINT32, ), + /* D-Bus only, synthetic attributes */ + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("vlans", G_VARIANT_TYPE_STRING, .str_type = 'd', ), + NULL, +}; + +/** + * nm_sriov_vf_attribute_validate: + * @name: the attribute name + * @value: the attribute value + * @known: (out): on return, whether the attribute name is a known one + * @error: (allow-none): return location for a #GError, or %NULL + * + * Validates a VF attribute, i.e. checks that the attribute is a known one, + * the value is of the correct type and well-formed. + * + * Returns: %TRUE if the attribute is valid, %FALSE otherwise + * + * Since: 1.14 + */ +gboolean +nm_sriov_vf_attribute_validate(const char *name, GVariant *value, gboolean *known, GError **error) +{ + const NMVariantAttributeSpec *const *iter; + const NMVariantAttributeSpec * spec = NULL; + + g_return_val_if_fail(name, FALSE); + g_return_val_if_fail(value, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + for (iter = _nm_sriov_vf_attribute_spec; *iter; iter++) { + if (nm_streq(name, (*iter)->name)) { + spec = *iter; + break; + } + } + + if (!spec || spec->str_type == 'd') { + NM_SET_OUT(known, FALSE); + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("unknown attribute")); + return FALSE; + } + + NM_SET_OUT(known, TRUE); + + if (!g_variant_is_of_type(value, spec->type)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid attribute type '%s'"), + g_variant_get_type_string(value)); + return FALSE; + } + + if (g_variant_type_equal(spec->type, G_VARIANT_TYPE_STRING)) { + const char *string; + + switch (spec->str_type) { + case 'm': /* MAC address */ + string = g_variant_get_string(value, NULL); + if (!nm_utils_hwaddr_valid(string, -1)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("'%s' is not a valid MAC address"), + string); + return FALSE; + } + break; + default: + break; + } + } + + return TRUE; +} + +gboolean +_nm_sriov_vf_attribute_validate_all(const NMSriovVF *vf, GError **error) +{ + GHashTableIter iter; + const char * name; + GVariant * variant; + GVariant * min, *max; + + g_return_val_if_fail(vf, FALSE); + g_return_val_if_fail(vf->refcount > 0, FALSE); + + g_hash_table_iter_init(&iter, vf->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) { + if (!nm_sriov_vf_attribute_validate(name, variant, NULL, error)) { + g_prefix_error(error, "attribute '%s':", name); + return FALSE; + } + } + + min = g_hash_table_lookup(vf->attributes, NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE); + max = g_hash_table_lookup(vf->attributes, NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE); + if (min && max && g_variant_get_uint32(min) > g_variant_get_uint32(max)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "min_tx_rate is greater than max_tx_rate"); + return FALSE; + } + + return TRUE; +} + +/** + * nm_sriov_vf_add_vlan: + * @vf: the #NMSriovVF + * @vlan_id: the VLAN id + * + * Adds a VLAN to the VF. + * + * Returns: %TRUE if the VLAN was added; %FALSE if it already existed + * + * Since: 1.14 + **/ +gboolean +nm_sriov_vf_add_vlan(NMSriovVF *vf, guint vlan_id) +{ + g_return_val_if_fail(vf, FALSE); + g_return_val_if_fail(vf->refcount > 0, FALSE); + + if (vf->vlans && g_hash_table_contains(vf->vlans, &vlan_id)) + return FALSE; + + vf_add_vlan(vf, vlan_id, 0, NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); + + return TRUE; +} + +/** + * nm_sriov_vf_remove_vlan: + * @vf: the #NMSriovVF + * @vlan_id: the VLAN id + * + * Removes a VLAN from a VF. + * + * Returns: %TRUE if the VLAN was removed, %FALSE if the VLAN @vlan_id + * did not belong to the VF. + * + * Since: 1.14 + */ +gboolean +nm_sriov_vf_remove_vlan(NMSriovVF *vf, guint vlan_id) +{ + g_return_val_if_fail(vf, FALSE); + g_return_val_if_fail(vf->refcount > 0, FALSE); + + if (!vf->vlans || !g_hash_table_remove(vf->vlans, &vlan_id)) + return FALSE; + + nm_clear_g_free(&vf->vlan_ids); + return TRUE; +} + +static int +vlan_id_compare(gconstpointer a, gconstpointer b, gpointer user_data) +{ + guint id_a = *(guint *) a; + guint id_b = *(guint *) b; + + if (id_a < id_b) + return -1; + else if (id_a > id_b) + return 1; + else + return 0; +} + +/** + * nm_sriov_vf_get_vlan_ids: + * @vf: the #NMSriovVF + * @length: (out) (allow-none): on return, the number of VLANs configured + * + * Returns the VLANs currently configured on the VF. + * + * Returns: (transfer none) (array length=length): a list of VLAN ids configured on the VF. + * + * Since: 1.14 + */ +const guint * +nm_sriov_vf_get_vlan_ids(const NMSriovVF *vf, guint *length) +{ + GHashTableIter iter; + VFVlan * vlan; + guint num, i; + + g_return_val_if_fail(vf, NULL); + g_return_val_if_fail(vf->refcount > 0, NULL); + + num = vf->vlans ? g_hash_table_size(vf->vlans) : 0u; + NM_SET_OUT(length, num); + + if (vf->vlan_ids) + return vf->vlan_ids; + if (num == 0) + return NULL; + + /* vf is const, however, vlan_ids is a mutable field caching the + * result ("mutable" in C++ terminology) */ + ((NMSriovVF *) vf)->vlan_ids = g_new0(guint, num); + + i = 0; + g_hash_table_iter_init(&iter, vf->vlans); + while (g_hash_table_iter_next(&iter, (gpointer *) &vlan, NULL)) + vf->vlan_ids[i++] = vlan->id; + + nm_assert(num == i); + + g_qsort_with_data(vf->vlan_ids, num, sizeof(guint), vlan_id_compare, NULL); + + return vf->vlan_ids; +} + +/** + * nm_sriov_vf_set_vlan_qos: + * @vf: the #NMSriovVF + * @vlan_id: the VLAN id + * @qos: a QoS (priority) value + * + * Sets a QoS value for the given VLAN. + * + * Since: 1.14 + */ +void +nm_sriov_vf_set_vlan_qos(NMSriovVF *vf, guint vlan_id, guint32 qos) +{ + VFVlan *vlan; + + g_return_if_fail(vf); + g_return_if_fail(vf->refcount > 0); + + if (!vf->vlans || !(vlan = g_hash_table_lookup(vf->vlans, &vlan_id))) + g_return_if_reached(); + + vlan->qos = qos; +} + +/** + * nm_sriov_vf_set_vlan_protocol: + * @vf: the #NMSriovVF + * @vlan_id: the VLAN id + * @protocol: the VLAN protocol + * + * Sets the protocol for the given VLAN. + * + * Since: 1.14 + */ +void +nm_sriov_vf_set_vlan_protocol(NMSriovVF *vf, guint vlan_id, NMSriovVFVlanProtocol protocol) +{ + VFVlan *vlan; + + g_return_if_fail(vf); + g_return_if_fail(vf->refcount > 0); + + if (!vf->vlans || !(vlan = g_hash_table_lookup(vf->vlans, &vlan_id))) + g_return_if_reached(); + + vlan->protocol = protocol; +} + +/** + * nm_sriov_vf_get_vlan_qos: + * @vf: the #NMSriovVF + * @vlan_id: the VLAN id + * + * Returns the QoS value for the given VLAN. + * + * Returns: the QoS value + * + * Since: 1.14 + */ +guint32 +nm_sriov_vf_get_vlan_qos(const NMSriovVF *vf, guint vlan_id) +{ + VFVlan *vlan; + + g_return_val_if_fail(vf, 0); + g_return_val_if_fail(vf->refcount > 0, 0); + + if (!vf->vlans || !(vlan = g_hash_table_lookup(vf->vlans, &vlan_id))) + g_return_val_if_reached(0); + + return vlan->qos; +} + +/* + * nm_sriov_vf_get_vlan_protocol: + * @vf: the #NMSriovVF + * @vlan_id: the VLAN id + * + * Returns the configured protocol for the given VLAN. + * + * Returns: the configured protocol + * + * Since: 1.14 + */ +NMSriovVFVlanProtocol +nm_sriov_vf_get_vlan_protocol(const NMSriovVF *vf, guint vlan_id) +{ + VFVlan *vlan; + + g_return_val_if_fail(vf, NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); + g_return_val_if_fail(vf->refcount > 0, NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); + + if (!vf->vlans || !(vlan = g_hash_table_lookup(vf->vlans, &vlan_id))) + g_return_val_if_reached(NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); + + return vlan->protocol; +} + +/*****************************************************************************/ + +/** + * nm_setting_sriov_get_total_vfs: + * @setting: the #NMSettingSriov + * + * Returns the value contained in the #NMSettingSriov:total-vfs + * property. + * + * Returns: the total number of SR-IOV virtual functions to create + * + * Since: 1.14 + **/ +guint +nm_setting_sriov_get_total_vfs(NMSettingSriov *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_SRIOV(setting), 0); + + return setting->total_vfs; +} + +/** + * nm_setting_sriov_get_num_vfs: + * @setting: the #NMSettingSriov + * + * Returns: the number of configured VFs + * + * Since: 1.14 + **/ +guint +nm_setting_sriov_get_num_vfs(NMSettingSriov *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_SRIOV(setting), 0); + + return setting->vfs->len; +} + +/** + * nm_setting_sriov_get_vf: + * @setting: the #NMSettingSriov + * @idx: index number of the VF to return + * + * Returns: (transfer none): the VF at index @idx + * + * Since: 1.14 + **/ +NMSriovVF * +nm_setting_sriov_get_vf(NMSettingSriov *setting, guint idx) +{ + g_return_val_if_fail(NM_IS_SETTING_SRIOV(setting), NULL); + g_return_val_if_fail(idx < setting->vfs->len, NULL); + + return setting->vfs->pdata[idx]; +} + +/** + * nm_setting_sriov_add_vf: + * @setting: the #NMSettingSriov + * @vf: the VF to add + * + * Appends a new VF and associated information to the setting. The + * given VF is duplicated internally and is not changed by this function. + * + * Since: 1.14 + **/ +void +nm_setting_sriov_add_vf(NMSettingSriov *setting, NMSriovVF *vf) +{ + g_return_if_fail(NM_IS_SETTING_SRIOV(setting)); + g_return_if_fail(vf); + g_return_if_fail(vf->refcount > 0); + + g_ptr_array_add(setting->vfs, nm_sriov_vf_dup(vf)); + _notify(setting, PROP_VFS); +} + +/** + * nm_setting_sriov_remove_vf: + * @setting: the #NMSettingSriov + * @idx: index number of the VF + * + * Removes the VF at index @idx. + * + * Since: 1.14 + **/ +void +nm_setting_sriov_remove_vf(NMSettingSriov *setting, guint idx) +{ + g_return_if_fail(NM_IS_SETTING_SRIOV(setting)); + g_return_if_fail(idx < setting->vfs->len); + + g_ptr_array_remove_index(setting->vfs, idx); + _notify(setting, PROP_VFS); +} + +/** + * nm_setting_sriov_remove_vf_by_index: + * @setting: the #NMSettingSriov + * @index: the VF index of the VF to remove + * + * Removes the VF with VF index @index. + * + * Returns: %TRUE if the VF was found and removed; %FALSE if it was not + * + * Since: 1.14 + **/ +gboolean +nm_setting_sriov_remove_vf_by_index(NMSettingSriov *setting, guint index) +{ + guint i; + + g_return_val_if_fail(NM_IS_SETTING_SRIOV(setting), FALSE); + + for (i = 0; i < setting->vfs->len; i++) { + if (nm_sriov_vf_get_index(setting->vfs->pdata[i]) == index) { + g_ptr_array_remove_index(setting->vfs, i); + _notify(setting, PROP_VFS); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_sriov_clear_vfs: + * @setting: the #NMSettingSriov + * + * Removes all configured VFs. + * + * Since: 1.14 + **/ +void +nm_setting_sriov_clear_vfs(NMSettingSriov *setting) +{ + g_return_if_fail(NM_IS_SETTING_SRIOV(setting)); + + if (setting->vfs->len != 0) { + g_ptr_array_set_size(setting->vfs, 0); + _notify(setting, PROP_VFS); + } +} + +/** + * nm_setting_sriov_get_autoprobe_drivers: + * @setting: the #NMSettingSriov + * + * Returns the value contained in the #NMSettingSriov:autoprobe-drivers + * property. + * + * Returns: the autoprobe-drivers property value + * + * Since: 1.14 + **/ +NMTernary +nm_setting_sriov_get_autoprobe_drivers(NMSettingSriov *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_SRIOV(setting), NM_TERNARY_DEFAULT); + + return setting->autoprobe_drivers; +} + +static int +vf_index_compare(gconstpointer a, gconstpointer b) +{ + NMSriovVF *vf_a = *(NMSriovVF **) a; + NMSriovVF *vf_b = *(NMSriovVF **) b; + + if (vf_a->index < vf_b->index) + return -1; + else if (vf_a->index > vf_b->index) + return 1; + else + return 0; +} + +gboolean +_nm_setting_sriov_sort_vfs(NMSettingSriov *setting) +{ + gboolean need_sort = FALSE; + guint i; + + for (i = 1; i < setting->vfs->len; i++) { + NMSriovVF *vf_prev = setting->vfs->pdata[i - 1]; + NMSriovVF *vf = setting->vfs->pdata[i]; + + if (vf->index <= vf_prev->index) { + need_sort = TRUE; + break; + } + } + + if (need_sort) { + g_ptr_array_sort(setting->vfs, vf_index_compare); + _notify(setting, PROP_VFS); + } + + return need_sort; +} + +/*****************************************************************************/ + +static GVariant * +vfs_to_dbus(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *vfs = NULL; + GVariantBuilder builder; + guint i; + + g_object_get(setting, NM_SETTING_SRIOV_VFS, &vfs, NULL); + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + + if (vfs) { + for (i = 0; i < vfs->len; i++) { + gs_free const char **attr_names = NULL; + NMSriovVF * vf = vfs->pdata[i]; + GVariantBuilder vf_builder; + const guint * vlan_ids; + const char ** name; + guint num_vlans = 0; + + g_variant_builder_init(&vf_builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add(&vf_builder, + "{sv}", + "index", + g_variant_new_uint32(nm_sriov_vf_get_index(vf))); + + attr_names = nm_utils_strdict_get_keys(vf->attributes, TRUE, NULL); + if (attr_names) { + for (name = attr_names; *name; name++) { + g_variant_builder_add(&vf_builder, + "{sv}", + *name, + nm_sriov_vf_get_attribute(vf, *name)); + } + } + + /* VLANs are translated into an array of maps, where each map has + * keys 'id', 'qos' and 'proto'. This guarantees enough flexibility + * to accommodate any future new option. */ + vlan_ids = nm_sriov_vf_get_vlan_ids(vf, &num_vlans); + if (num_vlans) { + GVariantBuilder vlans_builder; + guint j; + + g_variant_builder_init(&vlans_builder, G_VARIANT_TYPE("aa{sv}")); + for (j = 0; j < num_vlans; j++) { + GVariantBuilder vlan_builder; + + g_variant_builder_init(&vlan_builder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(&vlan_builder, + "{sv}", + "id", + g_variant_new_uint32(vlan_ids[j])); + g_variant_builder_add( + &vlan_builder, + "{sv}", + "qos", + g_variant_new_uint32(nm_sriov_vf_get_vlan_qos(vf, vlan_ids[j]))); + g_variant_builder_add( + &vlan_builder, + "{sv}", + "protocol", + g_variant_new_uint32(nm_sriov_vf_get_vlan_protocol(vf, vlan_ids[j]))); + g_variant_builder_add(&vlans_builder, "a{sv}", &vlan_builder); + } + g_variant_builder_add(&vf_builder, + "{sv}", + "vlans", + g_variant_builder_end(&vlans_builder)); + } + g_variant_builder_add(&builder, "a{sv}", &vf_builder); + } + } + + return g_variant_builder_end(&builder); +} + +static gboolean +vfs_from_dbus(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GPtrArray * vfs; + GVariantIter vf_iter; + GVariant * vf_var; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), FALSE); + + vfs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_sriov_vf_unref); + g_variant_iter_init(&vf_iter, value); + while (g_variant_iter_next(&vf_iter, "@a{sv}", &vf_var)) { + NMSriovVF * vf; + guint32 index; + GVariantIter attr_iter; + const char * attr_name; + GVariant * attr_var, *vlans_var; + + if (!g_variant_lookup(vf_var, "index", "u", &index)) + goto next; + + vf = nm_sriov_vf_new(index); + + g_variant_iter_init(&attr_iter, vf_var); + while (g_variant_iter_next(&attr_iter, "{&sv}", &attr_name, &attr_var)) { + if (!NM_IN_STRSET(attr_name, "index", "vlans")) + nm_sriov_vf_set_attribute(vf, attr_name, attr_var); + g_variant_unref(attr_var); + } + + if (g_variant_lookup(vf_var, "vlans", "@aa{sv}", &vlans_var)) { + GVariantIter vlan_iter; + GVariant * vlan_var; + + g_variant_iter_init(&vlan_iter, vlans_var); + while (g_variant_iter_next(&vlan_iter, "@a{sv}", &vlan_var)) { + NMSriovVFVlanProtocol proto = NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q; + gint64 vlan_id = -1; + guint qos = 0; + + g_variant_iter_init(&attr_iter, vlan_var); + while (g_variant_iter_next(&attr_iter, "{&sv}", &attr_name, &attr_var)) { + if (nm_streq(attr_name, "id") + && g_variant_is_of_type(attr_var, G_VARIANT_TYPE_UINT32)) + vlan_id = g_variant_get_uint32(attr_var); + else if (nm_streq(attr_name, "qos") + && g_variant_is_of_type(attr_var, G_VARIANT_TYPE_UINT32)) + qos = g_variant_get_uint32(attr_var); + else if (nm_streq(attr_name, "protocol") + && g_variant_is_of_type(attr_var, G_VARIANT_TYPE_UINT32)) + proto = g_variant_get_uint32(attr_var); + g_variant_unref(attr_var); + } + if (vlan_id != -1) + vf_add_vlan(vf, vlan_id, qos, proto); + g_variant_unref(vlan_var); + } + g_variant_unref(vlans_var); + } + + g_ptr_array_add(vfs, vf); +next: + g_variant_unref(vf_var); + } + + g_object_set(setting, NM_SETTING_SRIOV_VFS, vfs, NULL); + g_ptr_array_unref(vfs); + + return TRUE; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingSriov *self = NM_SETTING_SRIOV(setting); + guint i; + + if (self->vfs->len) { + gs_unref_hashtable GHashTable *h = NULL; + + h = g_hash_table_new(nm_direct_hash, NULL); + for (i = 0; i < self->vfs->len; i++) { + NMSriovVF * vf = self->vfs->pdata[i]; + gs_free_error GError *local = NULL; + + if (vf->index >= self->total_vfs) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("VF with index %u, but the total number of VFs is %u"), + vf->index, + self->total_vfs); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_SRIOV_SETTING_NAME, + NM_SETTING_SRIOV_VFS); + return FALSE; + } + + if (!_nm_sriov_vf_attribute_validate_all(vf, &local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid VF %u: %s"), + vf->index, + local->message); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_SRIOV_SETTING_NAME, + NM_SETTING_SRIOV_VFS); + return FALSE; + } + + if (g_hash_table_contains(h, GUINT_TO_POINTER(vf->index))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("duplicate VF index %u"), + vf->index); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_SRIOV_SETTING_NAME, + NM_SETTING_SRIOV_VFS); + return FALSE; + } + + g_hash_table_add(h, GUINT_TO_POINTER(vf->index)); + } + } + + /* Failures from here on are NORMALIZABLE... */ + + if (self->vfs->len) { + for (i = 1; i < self->vfs->len; i++) { + NMSriovVF *vf_prev = self->vfs->pdata[i - 1]; + NMSriovVF *vf = self->vfs->pdata[i]; + + if (vf->index <= vf_prev->index) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("VFs %d and %d are not sorted by ascending index"), + vf_prev->index, + vf->index); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_SRIOV_SETTING_NAME, + NM_SETTING_SRIOV_VFS); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + } + } + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingSriov *a; + NMSettingSriov *b; + guint i; + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_SRIOV_VFS)) { + if (set_b) { + a = NM_SETTING_SRIOV(set_a); + b = NM_SETTING_SRIOV(set_b); + + if (a->vfs->len != b->vfs->len) + return FALSE; + for (i = 0; i < a->vfs->len; i++) { + if (!nm_sriov_vf_equal(a->vfs->pdata[i], b->vfs->pdata[i])) + return FALSE; + } + } + return TRUE; + } + + return NM_SETTING_CLASS(nm_setting_sriov_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingSriov *self = NM_SETTING_SRIOV(object); + + switch (prop_id) { + case PROP_TOTAL_VFS: + g_value_set_uint(value, self->total_vfs); + break; + case PROP_VFS: + g_value_take_boxed(value, + _nm_utils_copy_array(self->vfs, + (NMUtilsCopyFunc) nm_sriov_vf_dup, + (GDestroyNotify) nm_sriov_vf_unref)); + break; + case PROP_AUTOPROBE_DRIVERS: + g_value_set_enum(value, self->autoprobe_drivers); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingSriov *self = NM_SETTING_SRIOV(object); + + switch (prop_id) { + case PROP_TOTAL_VFS: + self->total_vfs = g_value_get_uint(value); + break; + case PROP_VFS: + g_ptr_array_unref(self->vfs); + self->vfs = _nm_utils_copy_array(g_value_get_boxed(value), + (NMUtilsCopyFunc) nm_sriov_vf_dup, + (GDestroyNotify) nm_sriov_vf_unref); + break; + case PROP_AUTOPROBE_DRIVERS: + self->autoprobe_drivers = g_value_get_enum(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_sriov_init(NMSettingSriov *setting) +{ + setting->vfs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_sriov_vf_unref); + + setting->autoprobe_drivers = NM_TERNARY_DEFAULT; +} + +/** + * nm_setting_sriov_new: + * + * Creates a new #NMSettingSriov object with default values. + * + * Returns: (transfer full): the new empty #NMSettingSriov object + * + * Since: 1.14 + **/ +NMSetting * +nm_setting_sriov_new(void) +{ + return g_object_new(NM_TYPE_SETTING_SRIOV, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingSriov *self = NM_SETTING_SRIOV(object); + + g_ptr_array_unref(self->vfs); + + G_OBJECT_CLASS(nm_setting_sriov_parent_class)->finalize(object); +} + +static void +nm_setting_sriov_class_init(NMSettingSriovClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->compare_property = compare_property; + setting_class->verify = verify; + + /** + * NMSettingSriov:total-vfs + * + * The total number of virtual functions to create. + * + * Note that when the sriov setting is present NetworkManager + * enforces the number of virtual functions on the interface + * (also when it is zero) during activation and resets it + * upon deactivation. To prevent any changes to SR-IOV + * parameters don't add a sriov setting to the connection. + * + * Since: 1.14 + **/ + /* ---ifcfg-rh--- + * property: total-vfs + * variable: SRIOV_TOTAL_VFS(+) + * description: The total number of virtual functions to create + * example: SRIOV_TOTAL_VFS=16 + * ---end--- + */ + obj_properties[PROP_TOTAL_VFS] = g_param_spec_uint( + NM_SETTING_SRIOV_TOTAL_VFS, + "", + "", + 0, + G_MAXUINT32, + 0, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingSriov:vfs: (type GPtrArray(NMSriovVF)) + * + * Array of virtual function descriptors. + * + * Each VF descriptor is a dictionary mapping attribute names + * to GVariant values. The 'index' entry is mandatory for + * each VF. + * + * When represented as string a VF is in the form: + * + * "INDEX [ATTR=VALUE[ ATTR=VALUE]...]". + * + * for example: + * + * "2 mac=00:11:22:33:44:55 spoof-check=true". + * + * Multiple VFs can be specified using a comma as separator. + * Currently, the following attributes are supported: mac, + * spoof-check, trust, min-tx-rate, max-tx-rate, vlans. + * + * The "vlans" attribute is represented as a semicolon-separated + * list of VLAN descriptors, where each descriptor has the form + * + * "ID[.PRIORITY[.PROTO]]". + * + * PROTO can be either 'q' for 802.1Q (the default) or 'ad' for + * 802.1ad. + * + + * Since: 1.14 + **/ + /* ---ifcfg-rh--- + * property: vfs + * variable: SRIOV_VF1(+), SRIOV_VF2(+), ... + * description: SR-IOV virtual function descriptors + * example: SRIOV_VF10="mac=00:11:22:33:44:55", ... + * ---end--- + */ + obj_properties[PROP_VFS] = g_param_spec_boxed(NM_SETTING_SRIOV_VFS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_VFS], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = vfs_to_dbus, + .from_dbus_fcn = vfs_from_dbus, )); + + /** + * NMSettingSriov:autoprobe-drivers + * + * Whether to autoprobe virtual functions by a compatible driver. + * + * If set to %NM_TERNARY_TRUE, the kernel will try to bind VFs to + * a compatible driver and if this succeeds a new network + * interface will be instantiated for each VF. + * + * If set to %NM_TERNARY_FALSE, VFs will not be claimed and no + * network interfaces will be created for them. + * + * When set to %NM_TERNARY_DEFAULT, the global default is used; in + * case the global default is unspecified it is assumed to be + * %NM_TERNARY_TRUE. + * + * Since: 1.14 + **/ + /* ---ifcfg-rh--- + * property: autoprobe-drivers + * variable: SRIOV_AUTOPROBE_DRIVERS(+) + * default: missing variable means global default + * description: Whether to autoprobe virtual functions by a compatible driver + * example: SRIOV_AUTOPROBE_DRIVERS=0,1 + * ---end--- + */ + obj_properties[PROP_AUTOPROBE_DRIVERS] = g_param_spec_enum( + NM_SETTING_SRIOV_AUTOPROBE_DRIVERS, + "", + "", + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_SRIOV, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-tc-config.c b/src/libnm-core-impl/nm-setting-tc-config.c new file mode 100644 index 0000000..c5b28b5 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-tc-config.c @@ -0,0 +1,1863 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-tc-config.h" + +#include + +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-tc-config + * @short_description: Describes connection properties for the Linux Traffic Control + * @include: nm-setting-tc-config.h + **/ + +/*****************************************************************************/ + +G_DEFINE_BOXED_TYPE(NMTCQdisc, nm_tc_qdisc, nm_tc_qdisc_dup, nm_tc_qdisc_unref) + +struct NMTCQdisc { + guint refcount; + + char * kind; + guint32 handle; + guint32 parent; + GHashTable *attributes; +}; + +/** + * nm_tc_qdisc_new: + * @kind: name of the queueing discipline + * @parent: the parent queueing discipline + * @error: location to store error, or %NULL + * + * Creates a new #NMTCQdisc object. + * + * Returns: (transfer full): the new #NMTCQdisc object, or %NULL on error + * + * Since: 1.12 + **/ +NMTCQdisc * +nm_tc_qdisc_new(const char *kind, guint32 parent, GError **error) +{ + NMTCQdisc *qdisc; + + if (!kind || !*kind) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("kind is missing")); + return NULL; + } + + if (strchr(kind, ' ') || strchr(kind, '\t')) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid kind"), + kind); + return NULL; + } + + if (!parent) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("parent handle missing")); + return NULL; + } + + qdisc = g_slice_new0(NMTCQdisc); + qdisc->refcount = 1; + + qdisc->kind = g_strdup(kind); + qdisc->parent = parent; + + return qdisc; +} + +/** + * nm_tc_qdisc_ref: + * @qdisc: the #NMTCQdisc + * + * Increases the reference count of the object. + * + * Since: 1.12 + **/ +void +nm_tc_qdisc_ref(NMTCQdisc *qdisc) +{ + g_return_if_fail(qdisc != NULL); + g_return_if_fail(qdisc->refcount > 0); + + qdisc->refcount++; +} + +/** + * nm_tc_qdisc_unref: + * @qdisc: the #NMTCQdisc + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + * + * Since: 1.12 + **/ +void +nm_tc_qdisc_unref(NMTCQdisc *qdisc) +{ + g_return_if_fail(qdisc != NULL); + g_return_if_fail(qdisc->refcount > 0); + + qdisc->refcount--; + if (qdisc->refcount == 0) { + g_free(qdisc->kind); + if (qdisc->attributes) + g_hash_table_unref(qdisc->attributes); + g_slice_free(NMTCQdisc, qdisc); + } +} + +/** + * nm_tc_qdisc_equal: + * @qdisc: the #NMTCQdisc + * @other: the #NMTCQdisc to compare @qdisc to. + * + * Determines if two #NMTCQdisc objects contain the same kind, * handle + * and parent. + * + * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + * + * Since: 1.12 + **/ +gboolean +nm_tc_qdisc_equal(NMTCQdisc *qdisc, NMTCQdisc *other) +{ + GHashTableIter iter; + const char * key; + GVariant * value, *value2; + guint n; + + g_return_val_if_fail(qdisc != NULL, FALSE); + g_return_val_if_fail(qdisc->refcount > 0, FALSE); + + g_return_val_if_fail(other != NULL, FALSE); + g_return_val_if_fail(other->refcount > 0, FALSE); + + if (qdisc->handle != other->handle || qdisc->parent != other->parent + || g_strcmp0(qdisc->kind, other->kind) != 0) + return FALSE; + + n = qdisc->attributes ? g_hash_table_size(qdisc->attributes) : 0; + if (n != (other->attributes ? g_hash_table_size(other->attributes) : 0)) + return FALSE; + if (n) { + g_hash_table_iter_init(&iter, qdisc->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) { + value2 = g_hash_table_lookup(other->attributes, key); + if (!value2) + return FALSE; + if (!g_variant_equal(value, value2)) + return FALSE; + } + } + + return TRUE; +} + +static guint +_nm_tc_qdisc_hash(NMTCQdisc *qdisc) +{ + NMUtilsNamedValue attrs_static[30]; + gs_free NMUtilsNamedValue *attrs_free = NULL; + const NMUtilsNamedValue * attrs; + NMHashState h; + guint length; + guint i; + + attrs = + nm_utils_named_values_from_strdict(qdisc->attributes, &length, attrs_static, &attrs_free); + + nm_hash_init(&h, 43869703); + nm_hash_update_vals(&h, qdisc->handle, qdisc->parent, length); + nm_hash_update_str0(&h, qdisc->kind); + for (i = 0; i < length; i++) { + const char * key = attrs[i].name; + GVariant * variant = attrs[i].value_ptr; + const GVariantType *vtype; + + vtype = g_variant_get_type(variant); + + nm_hash_update_str(&h, key); + nm_hash_update_str(&h, (const char *) vtype); + if (g_variant_type_is_basic(vtype)) + nm_hash_update_val(&h, g_variant_hash(variant)); + } + + return nm_hash_complete(&h); +} + +/** + * nm_tc_qdisc_dup: + * @qdisc: the #NMTCQdisc + * + * Creates a copy of @qdisc + * + * Returns: (transfer full): a copy of @qdisc + * + * Since: 1.12 + **/ +NMTCQdisc * +nm_tc_qdisc_dup(NMTCQdisc *qdisc) +{ + NMTCQdisc *copy; + + g_return_val_if_fail(qdisc != NULL, NULL); + g_return_val_if_fail(qdisc->refcount > 0, NULL); + + copy = nm_tc_qdisc_new(qdisc->kind, qdisc->parent, NULL); + nm_tc_qdisc_set_handle(copy, qdisc->handle); + + if (qdisc->attributes) { + GHashTableIter iter; + const char * key; + GVariant * value; + + g_hash_table_iter_init(&iter, qdisc->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) + nm_tc_qdisc_set_attribute(copy, key, value); + } + + return copy; +} + +/** + * nm_tc_qdisc_get_kind: + * @qdisc: the #NMTCQdisc + * + * Returns: + * + * Since: 1.12 + **/ +const char * +nm_tc_qdisc_get_kind(NMTCQdisc *qdisc) +{ + g_return_val_if_fail(qdisc != NULL, NULL); + g_return_val_if_fail(qdisc->refcount > 0, NULL); + + return qdisc->kind; +} + +/** + * nm_tc_qdisc_get_handle: + * @qdisc: the #NMTCQdisc + * + * Returns: the queueing discipline handle + * + * Since: 1.12 + **/ +guint32 +nm_tc_qdisc_get_handle(NMTCQdisc *qdisc) +{ + g_return_val_if_fail(qdisc != NULL, TC_H_UNSPEC); + g_return_val_if_fail(qdisc->refcount > 0, TC_H_UNSPEC); + + return qdisc->handle; +} + +/** + * nm_tc_qdisc_set_handle: + * @qdisc: the #NMTCQdisc + * @handle: the queueing discipline handle + * + * Sets the queueing discipline handle. + * + * Since: 1.12 + **/ +void +nm_tc_qdisc_set_handle(NMTCQdisc *qdisc, guint32 handle) +{ + g_return_if_fail(qdisc != NULL); + g_return_if_fail(qdisc->refcount > 0); + + qdisc->handle = handle; +} + +/** + * nm_tc_qdisc_get_parent: + * @qdisc: the #NMTCQdisc + * + * Returns: the parent class + * + * Since: 1.12 + **/ +guint32 +nm_tc_qdisc_get_parent(NMTCQdisc *qdisc) +{ + g_return_val_if_fail(qdisc != NULL, TC_H_UNSPEC); + g_return_val_if_fail(qdisc->refcount > 0, TC_H_UNSPEC); + + return qdisc->parent; +} + +/** + * nm_tc_qdisc_get_attribute_names: + * @qdisc: the #NMTCQdisc + * + * Gets an array of attribute names defined on @qdisc. + * + * Returns: (transfer container): a %NULL-terminated array of attribute names + * or %NULL if no attributes are set. + * + * Since: 1.18 + **/ +const char ** +nm_tc_qdisc_get_attribute_names(NMTCQdisc *qdisc) +{ + g_return_val_if_fail(qdisc, NULL); + + return nm_utils_strdict_get_keys(qdisc->attributes, TRUE, NULL); +} + +GHashTable * +_nm_tc_qdisc_get_attributes(NMTCQdisc *qdisc) +{ + nm_assert(qdisc); + + return qdisc->attributes; +} + +/** + * nm_tc_qdisc_get_attribute: + * @qdisc: the #NMTCQdisc + * @name: the name of an qdisc attribute + * + * Gets the value of the attribute with name @name on @qdisc + * + * Returns: (transfer none): the value of the attribute with name @name on + * @qdisc, or %NULL if @qdisc has no such attribute. + * + * Since: 1.18 + **/ +GVariant * +nm_tc_qdisc_get_attribute(NMTCQdisc *qdisc, const char *name) +{ + g_return_val_if_fail(qdisc != NULL, NULL); + g_return_val_if_fail(name != NULL && *name != '\0', NULL); + + if (qdisc->attributes) + return g_hash_table_lookup(qdisc->attributes, name); + else + return NULL; +} + +/** + * nm_tc_qdisc_set_attribute: + * @qdisc: the #NMTCQdisc + * @name: the name of an qdisc attribute + * @value: (transfer none) (allow-none): the value + * + * Sets or clears the named attribute on @qdisc to the given value. + * + * Since: 1.18 + **/ +void +nm_tc_qdisc_set_attribute(NMTCQdisc *qdisc, const char *name, GVariant *value) +{ + g_return_if_fail(qdisc != NULL); + g_return_if_fail(name != NULL && *name != '\0'); + g_return_if_fail(strcmp(name, "kind") != 0); + + if (!qdisc->attributes) { + qdisc->attributes = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref); + } + + if (value) + g_hash_table_insert(qdisc->attributes, g_strdup(name), g_variant_ref_sink(value)); + else + g_hash_table_remove(qdisc->attributes, name); +} + +/*****************************************************************************/ + +G_DEFINE_BOXED_TYPE(NMTCAction, nm_tc_action, nm_tc_action_dup, nm_tc_action_unref) + +struct NMTCAction { + guint refcount; + + char *kind; + + GHashTable *attributes; +}; + +/** + * nm_tc_action_new: + * @kind: name of the queueing discipline + * @error: location to store error, or %NULL + * + * Creates a new #NMTCAction object. + * + * Returns: (transfer full): the new #NMTCAction object, or %NULL on error + * + * Since: 1.12 + **/ +NMTCAction * +nm_tc_action_new(const char *kind, GError **error) +{ + NMTCAction *action; + + if (!kind || !*kind) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("kind is missing")); + return NULL; + } + + if (strchr(kind, ' ') || strchr(kind, '\t')) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid kind"), + kind); + return NULL; + } + + action = g_slice_new0(NMTCAction); + action->refcount = 1; + + action->kind = g_strdup(kind); + + return action; +} + +/** + * nm_tc_action_ref: + * @action: the #NMTCAction + * + * Increases the reference count of the object. + * + * Since: 1.12 + **/ +void +nm_tc_action_ref(NMTCAction *action) +{ + g_return_if_fail(action != NULL); + g_return_if_fail(action->refcount > 0); + + action->refcount++; +} + +/** + * nm_tc_action_unref: + * @action: the #NMTCAction + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + * + * Since: 1.12 + **/ +void +nm_tc_action_unref(NMTCAction *action) +{ + g_return_if_fail(action != NULL); + g_return_if_fail(action->refcount > 0); + + action->refcount--; + if (action->refcount == 0) { + g_free(action->kind); + if (action->attributes) + g_hash_table_unref(action->attributes); + g_slice_free(NMTCAction, action); + } +} + +/** + * nm_tc_action_equal: + * @action: the #NMTCAction + * @other: the #NMTCAction to compare @action to. + * + * Determines if two #NMTCAction objects contain the same kind, family, + * handle, parent and info. + * + * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + * + * Since: 1.12 + **/ +gboolean +nm_tc_action_equal(NMTCAction *action, NMTCAction *other) +{ + GHashTableIter iter; + const char * key; + GVariant * value, *value2; + guint n; + + g_return_val_if_fail(!action || action->refcount > 0, FALSE); + g_return_val_if_fail(!other || other->refcount > 0, FALSE); + + if (action == other) + return TRUE; + if (!action || !other) + return FALSE; + + if (g_strcmp0(action->kind, other->kind) != 0) + return FALSE; + + n = action->attributes ? g_hash_table_size(action->attributes) : 0; + if (n != (other->attributes ? g_hash_table_size(other->attributes) : 0)) + return FALSE; + if (n) { + g_hash_table_iter_init(&iter, action->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) { + value2 = g_hash_table_lookup(other->attributes, key); + if (!value2) + return FALSE; + if (!g_variant_equal(value, value2)) + return FALSE; + } + } + + return TRUE; +} + +/** + * nm_tc_action_dup: + * @action: the #NMTCAction + * + * Creates a copy of @action + * + * Returns: (transfer full): a copy of @action + * + * Since: 1.12 + **/ +NMTCAction * +nm_tc_action_dup(NMTCAction *action) +{ + NMTCAction *copy; + + g_return_val_if_fail(action != NULL, NULL); + g_return_val_if_fail(action->refcount > 0, NULL); + + copy = nm_tc_action_new(action->kind, NULL); + + if (action->attributes) { + GHashTableIter iter; + const char * key; + GVariant * value; + + g_hash_table_iter_init(&iter, action->attributes); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) + nm_tc_action_set_attribute(copy, key, value); + } + + return copy; +} + +/** + * nm_tc_action_get_kind: + * @action: the #NMTCAction + * + * Returns: + * + * Since: 1.12 + **/ +const char * +nm_tc_action_get_kind(NMTCAction *action) +{ + g_return_val_if_fail(action != NULL, NULL); + g_return_val_if_fail(action->refcount > 0, NULL); + + return action->kind; +} + +/** + * nm_tc_action_get_attribute_names: + * @action: the #NMTCAction + * + * Gets an array of attribute names defined on @action. + * + * Returns: (transfer full): a %NULL-terminated array of attribute names, + * + * Since: 1.12 + **/ +char ** +nm_tc_action_get_attribute_names(NMTCAction *action) +{ + const char **names; + + g_return_val_if_fail(action, NULL); + + names = nm_utils_strdict_get_keys(action->attributes, TRUE, NULL); + return nm_utils_strv_make_deep_copied_nonnull(names); +} + +GHashTable * +_nm_tc_action_get_attributes(NMTCAction *action) +{ + nm_assert(action); + + return action->attributes; +} + +/** + * nm_tc_action_get_attribute: + * @action: the #NMTCAction + * @name: the name of an action attribute + * + * Gets the value of the attribute with name @name on @action + * + * Returns: (transfer none): the value of the attribute with name @name on + * @action, or %NULL if @action has no such attribute. + * + * Since: 1.12 + **/ +GVariant * +nm_tc_action_get_attribute(NMTCAction *action, const char *name) +{ + g_return_val_if_fail(action != NULL, NULL); + g_return_val_if_fail(name != NULL && *name != '\0', NULL); + + if (action->attributes) + return g_hash_table_lookup(action->attributes, name); + else + return NULL; +} + +/** + * nm_tc_action_set_attribute: + * @action: the #NMTCAction + * @name: the name of an action attribute + * @value: (transfer none) (allow-none): the value + * + * Sets or clears the named attribute on @action to the given value. + * + * Since: 1.12 + **/ +void +nm_tc_action_set_attribute(NMTCAction *action, const char *name, GVariant *value) +{ + g_return_if_fail(action != NULL); + g_return_if_fail(name != NULL && *name != '\0'); + g_return_if_fail(strcmp(name, "kind") != 0); + + if (!action->attributes) { + action->attributes = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref); + } + + if (value) + g_hash_table_insert(action->attributes, g_strdup(name), g_variant_ref_sink(value)); + else + g_hash_table_remove(action->attributes, name); +} + +/*****************************************************************************/ + +G_DEFINE_BOXED_TYPE(NMTCTfilter, nm_tc_tfilter, nm_tc_tfilter_dup, nm_tc_tfilter_unref) + +struct NMTCTfilter { + guint refcount; + + char * kind; + guint32 handle; + guint32 parent; + NMTCAction *action; +}; + +/** + * nm_tc_tfilter_new: + * @kind: name of the queueing discipline + * @parent: the parent queueing discipline + * @error: location to store error, or %NULL + * + * Creates a new #NMTCTfilter object. + * + * Returns: (transfer full): the new #NMTCTfilter object, or %NULL on error + * + * Since: 1.12 + **/ +NMTCTfilter * +nm_tc_tfilter_new(const char *kind, guint32 parent, GError **error) +{ + NMTCTfilter *tfilter; + + if (!kind || !*kind) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("kind is missing")); + return NULL; + } + + if (strchr(kind, ' ') || strchr(kind, '\t')) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid kind"), + kind); + return NULL; + } + + if (!parent) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("parent handle missing")); + return NULL; + } + + tfilter = g_slice_new0(NMTCTfilter); + tfilter->refcount = 1; + + tfilter->kind = g_strdup(kind); + tfilter->parent = parent; + + return tfilter; +} + +/** + * nm_tc_tfilter_ref: + * @tfilter: the #NMTCTfilter + * + * Increases the reference count of the object. + * + * Since: 1.12 + **/ +void +nm_tc_tfilter_ref(NMTCTfilter *tfilter) +{ + g_return_if_fail(tfilter != NULL); + g_return_if_fail(tfilter->refcount > 0); + + tfilter->refcount++; +} + +/** + * nm_tc_tfilter_unref: + * @tfilter: the #NMTCTfilter + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + * + * Since: 1.12 + **/ +void +nm_tc_tfilter_unref(NMTCTfilter *tfilter) +{ + g_return_if_fail(tfilter != NULL); + g_return_if_fail(tfilter->refcount > 0); + + tfilter->refcount--; + if (tfilter->refcount == 0) { + g_free(tfilter->kind); + if (tfilter->action) + nm_tc_action_unref(tfilter->action); + g_slice_free(NMTCTfilter, tfilter); + } +} + +/** + * nm_tc_tfilter_equal: + * @tfilter: the #NMTCTfilter + * @other: the #NMTCTfilter to compare @tfilter to. + * + * Determines if two #NMTCTfilter objects contain the same kind, family, + * handle, parent and info. + * + * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + * + * Since: 1.12 + **/ +gboolean +nm_tc_tfilter_equal(NMTCTfilter *tfilter, NMTCTfilter *other) +{ + g_return_val_if_fail(tfilter != NULL, FALSE); + g_return_val_if_fail(tfilter->refcount > 0, FALSE); + + g_return_val_if_fail(other != NULL, FALSE); + g_return_val_if_fail(other->refcount > 0, FALSE); + + if (tfilter->handle != other->handle || tfilter->parent != other->parent + || g_strcmp0(tfilter->kind, other->kind) != 0 + || !nm_tc_action_equal(tfilter->action, other->action)) + return FALSE; + + return TRUE; +} + +static guint +_nm_tc_tfilter_hash(NMTCTfilter *tfilter) +{ + NMHashState h; + + nm_hash_init(&h, 63624437); + nm_hash_update_vals(&h, tfilter->handle, tfilter->parent); + nm_hash_update_str0(&h, tfilter->kind); + + if (tfilter->action) { + gs_free NMUtilsNamedValue *attrs_free = NULL; + NMUtilsNamedValue attrs_static[30]; + const NMUtilsNamedValue * attrs; + guint length; + guint i; + + nm_hash_update_str0(&h, tfilter->action->kind); + + attrs = nm_utils_named_values_from_strdict(tfilter->action->attributes, + &length, + attrs_static, + &attrs_free); + for (i = 0; i < length; i++) { + GVariant *variant = attrs[i].value_ptr; + + nm_hash_update_str(&h, attrs[i].name); + if (g_variant_type_is_basic(g_variant_get_type(variant))) { + guint attr_hash; + + /* g_variant_hash() works only for basic types, thus + * we ignore any non-basic attribute. Actions differing + * only for non-basic attributes will collide. */ + attr_hash = g_variant_hash(variant); + nm_hash_update_val(&h, attr_hash); + } + } + } + + return nm_hash_complete(&h); +} + +/** + * nm_tc_tfilter_dup: + * @tfilter: the #NMTCTfilter + * + * Creates a copy of @tfilter + * + * Returns: (transfer full): a copy of @tfilter + * + * Since: 1.12 + **/ +NMTCTfilter * +nm_tc_tfilter_dup(NMTCTfilter *tfilter) +{ + NMTCTfilter *copy; + + g_return_val_if_fail(tfilter != NULL, NULL); + g_return_val_if_fail(tfilter->refcount > 0, NULL); + + copy = nm_tc_tfilter_new(tfilter->kind, tfilter->parent, NULL); + nm_tc_tfilter_set_handle(copy, tfilter->handle); + nm_tc_tfilter_set_action(copy, tfilter->action); + + return copy; +} + +/** + * nm_tc_tfilter_get_kind: + * @tfilter: the #NMTCTfilter + * + * Returns: + * + * Since: 1.12 + **/ +const char * +nm_tc_tfilter_get_kind(NMTCTfilter *tfilter) +{ + g_return_val_if_fail(tfilter != NULL, NULL); + g_return_val_if_fail(tfilter->refcount > 0, NULL); + + return tfilter->kind; +} + +/** + * nm_tc_tfilter_get_handle: + * @tfilter: the #NMTCTfilter + * + * Returns: the queueing discipline handle + * + * Since: 1.12 + **/ +guint32 +nm_tc_tfilter_get_handle(NMTCTfilter *tfilter) +{ + g_return_val_if_fail(tfilter != NULL, TC_H_UNSPEC); + g_return_val_if_fail(tfilter->refcount > 0, TC_H_UNSPEC); + + return tfilter->handle; +} + +/** + * nm_tc_tfilter_set_handle: + * @tfilter: the #NMTCTfilter + * @handle: the queueing discipline handle + * + * Sets the queueing discipline handle. + * + * Since: 1.12 + **/ +void +nm_tc_tfilter_set_handle(NMTCTfilter *tfilter, guint32 handle) +{ + g_return_if_fail(tfilter != NULL); + g_return_if_fail(tfilter->refcount > 0); + + tfilter->handle = handle; +} + +/** + * nm_tc_tfilter_get_parent: + * @tfilter: the #NMTCTfilter + * + * Returns: the parent class + * + * Since: 1.12 + **/ +guint32 +nm_tc_tfilter_get_parent(NMTCTfilter *tfilter) +{ + g_return_val_if_fail(tfilter != NULL, TC_H_UNSPEC); + g_return_val_if_fail(tfilter->refcount > 0, TC_H_UNSPEC); + + return tfilter->parent; +} + +/** + * nm_tc_tfilter_get_action: + * @tfilter: the #NMTCTfilter + * + * Returns: the action associated with a traffic filter. + * + * Since: 1.12 + **/ +NMTCAction * +nm_tc_tfilter_get_action(NMTCTfilter *tfilter) +{ + g_return_val_if_fail(tfilter != NULL, TC_H_UNSPEC); + g_return_val_if_fail(tfilter->refcount > 0, TC_H_UNSPEC); + + if (tfilter->action == NULL) + return NULL; + + return tfilter->action; +} + +/** + * nm_tc_tfilter_set_action: + * @tfilter: the #NMTCTfilter + * @action: the action object + * + * Sets the action associated with a traffic filter. + * + * Since: 1.12 + **/ +void +nm_tc_tfilter_set_action(NMTCTfilter *tfilter, NMTCAction *action) +{ + g_return_if_fail(tfilter != NULL); + g_return_if_fail(tfilter->refcount > 0); + + if (action) + nm_tc_action_ref(action); + if (tfilter->action) + nm_tc_action_unref(tfilter->action); + tfilter->action = action; +} + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingTCConfig, PROP_QDISCS, PROP_TFILTERS, ); + +/** + * NMSettingTCConfig: + * + * Linux Traffic Control Settings + * + * Since: 1.12 + */ +struct _NMSettingTCConfig { + NMSetting parent; + GPtrArray *qdiscs; + GPtrArray *tfilters; +}; + +struct _NMSettingTCConfigClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingTCConfig, nm_setting_tc_config, NM_TYPE_SETTING) + +/*****************************************************************************/ + +/** + * nm_setting_tc_config_get_num_qdiscs: + * @setting: the #NMSettingTCConfig + * + * Returns: the number of configured queueing disciplines + * + * Since: 1.12 + **/ +guint +nm_setting_tc_config_get_num_qdiscs(NMSettingTCConfig *self) +{ + g_return_val_if_fail(NM_IS_SETTING_TC_CONFIG(self), 0); + + return self->qdiscs->len; +} + +/** + * nm_setting_tc_config_get_qdisc: + * @setting: the #NMSettingTCConfig + * @idx: index number of the qdisc to return + * + * Returns: (transfer none): the qdisc at index @idx + * + * Since: 1.12 + **/ +NMTCQdisc * +nm_setting_tc_config_get_qdisc(NMSettingTCConfig *self, guint idx) +{ + g_return_val_if_fail(NM_IS_SETTING_TC_CONFIG(self), NULL); + g_return_val_if_fail(idx < self->qdiscs->len, NULL); + + return self->qdiscs->pdata[idx]; +} + +/** + * nm_setting_tc_config_add_qdisc: + * @setting: the #NMSettingTCConfig + * @qdisc: the qdisc to add + * + * Appends a new qdisc and associated information to the setting. The + * given qdisc is duplicated internally and is not changed by this function. + * If an identical qdisc (considering attributes as well) already exists, the + * qdisc is not added and the function returns %FALSE. + * + * Returns: %TRUE if the qdisc was added; %FALSE if the qdisc was already known. + * + * Since: 1.12 + **/ +gboolean +nm_setting_tc_config_add_qdisc(NMSettingTCConfig *self, NMTCQdisc *qdisc) +{ + guint i; + + g_return_val_if_fail(NM_IS_SETTING_TC_CONFIG(self), FALSE); + g_return_val_if_fail(qdisc != NULL, FALSE); + + for (i = 0; i < self->qdiscs->len; i++) { + if (nm_tc_qdisc_equal(self->qdiscs->pdata[i], qdisc)) + return FALSE; + } + + g_ptr_array_add(self->qdiscs, nm_tc_qdisc_dup(qdisc)); + _notify(self, PROP_QDISCS); + return TRUE; +} + +/** + * nm_setting_tc_config_remove_qdisc: + * @setting: the #NMSettingTCConfig + * @idx: index number of the qdisc + * + * Removes the qdisc at index @idx. + * + * Since: 1.12 + **/ +void +nm_setting_tc_config_remove_qdisc(NMSettingTCConfig *self, guint idx) +{ + g_return_if_fail(NM_IS_SETTING_TC_CONFIG(self)); + + g_return_if_fail(idx < self->qdiscs->len); + + g_ptr_array_remove_index(self->qdiscs, idx); + _notify(self, PROP_QDISCS); +} + +/** + * nm_setting_tc_config_remove_qdisc_by_value: + * @setting: the #NMSettingTCConfig + * @qdisc: the qdisc to remove + * + * Removes the first matching qdisc that matches @qdisc. + * + * Returns: %TRUE if the qdisc was found and removed; %FALSE if it was not. + * + * Since: 1.12 + **/ +gboolean +nm_setting_tc_config_remove_qdisc_by_value(NMSettingTCConfig *self, NMTCQdisc *qdisc) +{ + guint i; + + g_return_val_if_fail(NM_IS_SETTING_TC_CONFIG(self), FALSE); + g_return_val_if_fail(qdisc != NULL, FALSE); + + for (i = 0; i < self->qdiscs->len; i++) { + if (nm_tc_qdisc_equal(self->qdiscs->pdata[i], qdisc)) { + g_ptr_array_remove_index(self->qdiscs, i); + _notify(self, PROP_QDISCS); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_tc_config_clear_qdiscs: + * @setting: the #NMSettingTCConfig + * + * Removes all configured queueing disciplines. + * + * Since: 1.12 + **/ +void +nm_setting_tc_config_clear_qdiscs(NMSettingTCConfig *self) +{ + g_return_if_fail(NM_IS_SETTING_TC_CONFIG(self)); + + if (self->qdiscs->len != 0) { + g_ptr_array_set_size(self->qdiscs, 0); + _notify(self, PROP_QDISCS); + } +} + +/*****************************************************************************/ +/** + * nm_setting_tc_config_get_num_tfilters: + * @setting: the #NMSettingTCConfig + * + * Returns: the number of configured queueing disciplines + * + * Since: 1.12 + **/ +guint +nm_setting_tc_config_get_num_tfilters(NMSettingTCConfig *self) +{ + g_return_val_if_fail(NM_IS_SETTING_TC_CONFIG(self), 0); + + return self->tfilters->len; +} + +/** + * nm_setting_tc_config_get_tfilter: + * @setting: the #NMSettingTCConfig + * @idx: index number of the tfilter to return + * + * Returns: (transfer none): the tfilter at index @idx + * + * Since: 1.12 + **/ +NMTCTfilter * +nm_setting_tc_config_get_tfilter(NMSettingTCConfig *self, guint idx) +{ + g_return_val_if_fail(NM_IS_SETTING_TC_CONFIG(self), NULL); + g_return_val_if_fail(idx < self->tfilters->len, NULL); + + return self->tfilters->pdata[idx]; +} + +/** + * nm_setting_tc_config_add_tfilter: + * @setting: the #NMSettingTCConfig + * @tfilter: the tfilter to add + * + * Appends a new tfilter and associated information to the setting. The + * given tfilter is duplicated internally and is not changed by this function. + * If an identical tfilter (considering attributes as well) already exists, the + * tfilter is not added and the function returns %FALSE. + * + * Returns: %TRUE if the tfilter was added; %FALSE if the tfilter was already known. + * + * Since: 1.12 + **/ +gboolean +nm_setting_tc_config_add_tfilter(NMSettingTCConfig *self, NMTCTfilter *tfilter) +{ + guint i; + + g_return_val_if_fail(NM_IS_SETTING_TC_CONFIG(self), FALSE); + g_return_val_if_fail(tfilter != NULL, FALSE); + + for (i = 0; i < self->tfilters->len; i++) { + if (nm_tc_tfilter_equal(self->tfilters->pdata[i], tfilter)) + return FALSE; + } + + g_ptr_array_add(self->tfilters, nm_tc_tfilter_dup(tfilter)); + _notify(self, PROP_TFILTERS); + return TRUE; +} + +/** + * nm_setting_tc_config_remove_tfilter: + * @setting: the #NMSettingTCConfig + * @idx: index number of the tfilter + * + * Removes the tfilter at index @idx. + * + * Since: 1.12 + **/ +void +nm_setting_tc_config_remove_tfilter(NMSettingTCConfig *self, guint idx) +{ + g_return_if_fail(NM_IS_SETTING_TC_CONFIG(self)); + g_return_if_fail(idx < self->tfilters->len); + + g_ptr_array_remove_index(self->tfilters, idx); + _notify(self, PROP_TFILTERS); +} + +/** + * nm_setting_tc_config_remove_tfilter_by_value: + * @setting: the #NMSettingTCConfig + * @tfilter: the tfilter to remove + * + * Removes the first matching tfilter that matches @tfilter. + * + * Returns: %TRUE if the tfilter was found and removed; %FALSE if it was not. + * + * Since: 1.12 + **/ +gboolean +nm_setting_tc_config_remove_tfilter_by_value(NMSettingTCConfig *self, NMTCTfilter *tfilter) +{ + guint i; + + g_return_val_if_fail(NM_IS_SETTING_TC_CONFIG(self), FALSE); + g_return_val_if_fail(tfilter != NULL, FALSE); + + for (i = 0; i < self->tfilters->len; i++) { + if (nm_tc_tfilter_equal(self->tfilters->pdata[i], tfilter)) { + g_ptr_array_remove_index(self->tfilters, i); + _notify(self, PROP_TFILTERS); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_tc_config_clear_tfilters: + * @setting: the #NMSettingTCConfig + * + * Removes all configured queueing disciplines. + * + * Since: 1.12 + **/ +void +nm_setting_tc_config_clear_tfilters(NMSettingTCConfig *self) +{ + g_return_if_fail(NM_IS_SETTING_TC_CONFIG(self)); + + if (self->tfilters->len != 0) { + g_ptr_array_set_size(self->tfilters, 0); + _notify(self, PROP_TFILTERS); + } +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingTCConfig *self = NM_SETTING_TC_CONFIG(setting); + guint i; + + if (self->qdiscs->len != 0) { + gs_unref_hashtable GHashTable *ht = NULL; + + ht = g_hash_table_new((GHashFunc) _nm_tc_qdisc_hash, (GEqualFunc) nm_tc_qdisc_equal); + for (i = 0; i < self->qdiscs->len; i++) { + if (!g_hash_table_add(ht, self->qdiscs->pdata[i])) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("there are duplicate TC qdiscs")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_TC_CONFIG_SETTING_NAME, + NM_SETTING_TC_CONFIG_QDISCS); + return FALSE; + } + } + } + + if (self->tfilters->len != 0) { + gs_unref_hashtable GHashTable *ht = NULL; + + ht = g_hash_table_new((GHashFunc) _nm_tc_tfilter_hash, (GEqualFunc) nm_tc_tfilter_equal); + for (i = 0; i < self->tfilters->len; i++) { + if (!g_hash_table_add(ht, self->tfilters->pdata[i])) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("there are duplicate TC filters")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_TC_CONFIG_SETTING_NAME, + NM_SETTING_TC_CONFIG_TFILTERS); + return FALSE; + } + } + } + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingTCConfig *a_tc_config = NM_SETTING_TC_CONFIG(set_a); + NMSettingTCConfig *b_tc_config = NM_SETTING_TC_CONFIG(set_b); + guint i; + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_TC_CONFIG_QDISCS)) { + if (set_b) { + if (a_tc_config->qdiscs->len != b_tc_config->qdiscs->len) + return FALSE; + for (i = 0; i < a_tc_config->qdiscs->len; i++) { + if (!nm_tc_qdisc_equal(a_tc_config->qdiscs->pdata[i], + b_tc_config->qdiscs->pdata[i])) + return FALSE; + } + } + return TRUE; + } + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_TC_CONFIG_TFILTERS)) { + if (set_b) { + if (a_tc_config->tfilters->len != b_tc_config->tfilters->len) + return FALSE; + for (i = 0; i < a_tc_config->tfilters->len; i++) { + if (!nm_tc_tfilter_equal(a_tc_config->tfilters->pdata[i], + b_tc_config->tfilters->pdata[i])) + return FALSE; + } + } + return TRUE; + } + + return NM_SETTING_CLASS(nm_setting_tc_config_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +/** + * _qdiscs_to_variant: + * @qdiscs: (element-type NMTCQdisc): an array of #NMTCQdisc objects + * + * Utility function to convert a #GPtrArray of #NMTCQdisc objects representing + * TC qdiscs into a #GVariant of type 'aa{sv}' representing an array + * of NetworkManager TC qdiscs. + * + * Returns: (transfer none): a new floating #GVariant representing @qdiscs. + **/ +static GVariant * +_qdiscs_to_variant(GPtrArray *qdiscs) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + + if (qdiscs) { + for (i = 0; i < qdiscs->len; i++) { + NMUtilsNamedValue attrs_static[30]; + gs_free NMUtilsNamedValue *attrs_free = NULL; + const NMUtilsNamedValue * attrs; + NMTCQdisc * qdisc = qdiscs->pdata[i]; + guint length; + GVariantBuilder qdisc_builder; + guint y; + + g_variant_builder_init(&qdisc_builder, G_VARIANT_TYPE_VARDICT); + + g_variant_builder_add(&qdisc_builder, + "{sv}", + "kind", + g_variant_new_string(nm_tc_qdisc_get_kind(qdisc))); + + g_variant_builder_add(&qdisc_builder, + "{sv}", + "handle", + g_variant_new_uint32(nm_tc_qdisc_get_handle(qdisc))); + + g_variant_builder_add(&qdisc_builder, + "{sv}", + "parent", + g_variant_new_uint32(nm_tc_qdisc_get_parent(qdisc))); + + attrs = nm_utils_named_values_from_strdict(qdisc->attributes, + &length, + attrs_static, + &attrs_free); + for (y = 0; y < length; y++) { + g_variant_builder_add(&qdisc_builder, "{sv}", attrs[y].name, attrs[y].value_ptr); + } + + g_variant_builder_add(&builder, "a{sv}", &qdisc_builder); + } + } + + return g_variant_builder_end(&builder); +} + +/** + * _qdiscs_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * + * Utility function to convert a #GVariant representing a list of TC qdiscs + * into a #GPtrArray of * #NMTCQdisc objects. + * + * Returns: (transfer full) (element-type NMTCQdisc): a newly allocated + * #GPtrArray of #NMTCQdisc objects + **/ +static GPtrArray * +_qdiscs_from_variant(GVariant *value) +{ + GPtrArray * qdiscs; + GVariant * qdisc_var; + GVariantIter iter; + GError * error = NULL; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), NULL); + + g_variant_iter_init(&iter, value); + qdiscs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_tc_qdisc_unref); + + while (g_variant_iter_next(&iter, "@a{sv}", &qdisc_var)) { + const char * kind; + guint32 parent; + NMTCQdisc * qdisc; + GVariantIter qdisc_iter; + const char * key; + GVariant * attr_value; + + if (!g_variant_lookup(qdisc_var, "kind", "&s", &kind) + || !g_variant_lookup(qdisc_var, "parent", "u", &parent)) { + //g_warning ("Ignoring invalid qdisc"); + goto next; + } + + qdisc = nm_tc_qdisc_new(kind, parent, &error); + if (!qdisc) { + //g_warning ("Ignoring invalid qdisc: %s", error->message); + g_clear_error(&error); + goto next; + } + + g_variant_iter_init(&qdisc_iter, qdisc_var); + while (g_variant_iter_next(&qdisc_iter, "{&sv}", &key, &attr_value)) { + if (strcmp(key, "kind") == 0 || strcmp(key, "parent") == 0) { + /* Already processed above */ + } else if (strcmp(key, "handle") == 0) { + nm_tc_qdisc_set_handle(qdisc, g_variant_get_uint32(attr_value)); + } else { + nm_tc_qdisc_set_attribute(qdisc, key, attr_value); + } + g_variant_unref(attr_value); + } + + g_ptr_array_add(qdiscs, qdisc); +next: + g_variant_unref(qdisc_var); + } + + return qdiscs; +} + +static GVariant * +tc_qdiscs_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *qdiscs = NULL; + + g_object_get(setting, NM_SETTING_TC_CONFIG_QDISCS, &qdiscs, NULL); + return _qdiscs_to_variant(qdiscs); +} + +static gboolean +tc_qdiscs_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GPtrArray *qdiscs; + + qdiscs = _qdiscs_from_variant(value); + g_object_set(setting, NM_SETTING_TC_CONFIG_QDISCS, qdiscs, NULL); + g_ptr_array_unref(qdiscs); + + return TRUE; +} + +static GVariant * +_action_to_variant(NMTCAction *action) +{ + GVariantBuilder builder; + gs_strfreev char **attrs = nm_tc_action_get_attribute_names(action); + int i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + + g_variant_builder_add(&builder, + "{sv}", + "kind", + g_variant_new_string(nm_tc_action_get_kind(action))); + + for (i = 0; attrs[i]; i++) { + g_variant_builder_add(&builder, + "{sv}", + attrs[i], + nm_tc_action_get_attribute(action, attrs[i])); + } + + return g_variant_builder_end(&builder); +} + +/** + * _tfilters_to_variant: + * @tfilters: (element-type NMTCTfilter): an array of #NMTCTfilter objects + * + * Utility function to convert a #GPtrArray of #NMTCTfilter objects representing + * TC tfilters into a #GVariant of type 'aa{sv}' representing an array + * of NetworkManager TC tfilters. + * + * Returns: (transfer none): a new floating #GVariant representing @tfilters. + **/ +static GVariant * +_tfilters_to_variant(GPtrArray *tfilters) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + + if (tfilters) { + for (i = 0; i < tfilters->len; i++) { + NMTCTfilter * tfilter = tfilters->pdata[i]; + NMTCAction * action = nm_tc_tfilter_get_action(tfilter); + GVariantBuilder tfilter_builder; + + g_variant_builder_init(&tfilter_builder, G_VARIANT_TYPE("a{sv}")); + + g_variant_builder_add(&tfilter_builder, + "{sv}", + "kind", + g_variant_new_string(nm_tc_tfilter_get_kind(tfilter))); + g_variant_builder_add(&tfilter_builder, + "{sv}", + "handle", + g_variant_new_uint32(nm_tc_tfilter_get_handle(tfilter))); + g_variant_builder_add(&tfilter_builder, + "{sv}", + "parent", + g_variant_new_uint32(nm_tc_tfilter_get_parent(tfilter))); + + if (action) { + g_variant_builder_add(&tfilter_builder, + "{sv}", + "action", + _action_to_variant(action)); + } + + g_variant_builder_add(&builder, "a{sv}", &tfilter_builder); + } + } + + return g_variant_builder_end(&builder); +} + +/** + * _tfilters_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * + * Utility function to convert a #GVariant representing a list of TC tfilters + * into a #GPtrArray of * #NMTCTfilter objects. + * + * Returns: (transfer full) (element-type NMTCTfilter): a newly allocated + * #GPtrArray of #NMTCTfilter objects + **/ +static GPtrArray * +_tfilters_from_variant(GVariant *value) +{ + GPtrArray * tfilters; + GVariant * tfilter_var; + GVariantIter iter; + GError * error = NULL; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), NULL); + + g_variant_iter_init(&iter, value); + tfilters = g_ptr_array_new_with_free_func((GDestroyNotify) nm_tc_tfilter_unref); + + while (g_variant_iter_next(&iter, "@a{sv}", &tfilter_var)) { + NMTCTfilter *tfilter = NULL; + const char * kind; + guint32 handle; + guint32 parent; + NMTCAction * action; + const char * action_kind = NULL; + char * action_key; + GVariantIter action_iter; + GVariant * action_var = NULL; + GVariant * action_val; + + if (!g_variant_lookup(tfilter_var, "kind", "&s", &kind) + || !g_variant_lookup(tfilter_var, "parent", "u", &parent)) { + //g_warning ("Ignoring invalid tfilter"); + goto next; + } + + tfilter = nm_tc_tfilter_new(kind, parent, &error); + if (!tfilter) { + //g_warning ("Ignoring invalid tfilter: %s", error->message); + g_clear_error(&error); + goto next; + } + + if (g_variant_lookup(tfilter_var, "handle", "u", &handle)) + nm_tc_tfilter_set_handle(tfilter, handle); + + action_var = g_variant_lookup_value(tfilter_var, "action", G_VARIANT_TYPE_VARDICT); + + if (action_var) { + if (!g_variant_lookup(action_var, "kind", "&s", &action_kind)) { + //g_warning ("Ignoring tfilter with invalid action"); + goto next; + } + + action = nm_tc_action_new(action_kind, &error); + if (!action) { + //g_warning ("Ignoring tfilter with invalid action: %s", error->message); + g_clear_error(&error); + goto next; + } + + g_variant_iter_init(&action_iter, action_var); + while (g_variant_iter_next(&action_iter, "{&sv}", &action_key, &action_val)) { + if (strcmp(action_key, "kind") != 0) + nm_tc_action_set_attribute(action, action_key, action_val); + g_variant_unref(action_val); + } + + nm_tc_tfilter_set_action(tfilter, action); + nm_tc_action_unref(action); + } + + nm_tc_tfilter_ref(tfilter); + g_ptr_array_add(tfilters, tfilter); +next: + if (tfilter) + nm_tc_tfilter_unref(tfilter); + if (action_var) + g_variant_unref(action_var); + g_variant_unref(tfilter_var); + } + + return tfilters; +} + +static GVariant * +tc_tfilters_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *tfilters = NULL; + + g_object_get(setting, NM_SETTING_TC_CONFIG_TFILTERS, &tfilters, NULL); + return _tfilters_to_variant(tfilters); +} + +static gboolean +tc_tfilters_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + gs_unref_ptrarray GPtrArray *tfilters = NULL; + + tfilters = _tfilters_from_variant(value); + g_object_set(setting, NM_SETTING_TC_CONFIG_TFILTERS, tfilters, NULL); + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingTCConfig *self = NM_SETTING_TC_CONFIG(object); + + switch (prop_id) { + case PROP_QDISCS: + g_value_take_boxed(value, + _nm_utils_copy_array(self->qdiscs, + (NMUtilsCopyFunc) nm_tc_qdisc_dup, + (GDestroyNotify) nm_tc_qdisc_unref)); + break; + case PROP_TFILTERS: + g_value_take_boxed(value, + _nm_utils_copy_array(self->tfilters, + (NMUtilsCopyFunc) nm_tc_tfilter_dup, + (GDestroyNotify) nm_tc_tfilter_unref)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingTCConfig *self = NM_SETTING_TC_CONFIG(object); + + switch (prop_id) { + case PROP_QDISCS: + g_ptr_array_unref(self->qdiscs); + self->qdiscs = _nm_utils_copy_array(g_value_get_boxed(value), + (NMUtilsCopyFunc) nm_tc_qdisc_dup, + (GDestroyNotify) nm_tc_qdisc_unref); + break; + case PROP_TFILTERS: + g_ptr_array_unref(self->tfilters); + self->tfilters = _nm_utils_copy_array(g_value_get_boxed(value), + (NMUtilsCopyFunc) nm_tc_tfilter_dup, + (GDestroyNotify) nm_tc_tfilter_unref); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_tc_config_init(NMSettingTCConfig *self) +{ + self->qdiscs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_tc_qdisc_unref); + self->tfilters = g_ptr_array_new_with_free_func((GDestroyNotify) nm_tc_tfilter_unref); +} + +/** + * nm_setting_tc_config_new: + * + * Creates a new #NMSettingTCConfig object with default values. + * + * Returns: (transfer full): the new empty #NMSettingTCConfig object + * + * Since: 1.12 + **/ +NMSetting * +nm_setting_tc_config_new(void) +{ + return g_object_new(NM_TYPE_SETTING_TC_CONFIG, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingTCConfig *self = NM_SETTING_TC_CONFIG(object); + + g_ptr_array_unref(self->qdiscs); + g_ptr_array_unref(self->tfilters); + + G_OBJECT_CLASS(nm_setting_tc_config_parent_class)->finalize(object); +} + +static void +nm_setting_tc_config_class_init(NMSettingTCConfigClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->compare_property = compare_property; + setting_class->verify = verify; + + /** + * NMSettingTCConfig:qdiscs: (type GPtrArray(NMTCQdisc)) + * + * Array of TC queueing disciplines. + **/ + /* ---ifcfg-rh--- + * property: qdiscs + * variable: QDISC1(+), QDISC2(+), ... + * description: Queueing disciplines + * example: QDISC1=ingress, QDISC2="root handle 1234: fq_codel" + * ---end--- + */ + obj_properties[PROP_QDISCS] = g_param_spec_boxed(NM_SETTING_TC_CONFIG_QDISCS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_QDISCS], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = tc_qdiscs_get, + .from_dbus_fcn = tc_qdiscs_set, )); + + /** + * NMSettingTCConfig:tfilters: (type GPtrArray(NMTCTfilter)) + * + * Array of TC traffic filters. + **/ + /* ---ifcfg-rh--- + * property: qdiscs + * variable: FILTER1(+), FILTER2(+), ... + * description: Traffic filters + * example: FILTER1="parent ffff: matchall action simple sdata Input", ... + * ---end--- + */ + obj_properties[PROP_TFILTERS] = g_param_spec_boxed( + NM_SETTING_TC_CONFIG_TFILTERS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_TFILTERS], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = tc_tfilters_get, + .from_dbus_fcn = tc_tfilters_set, )); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_TC_CONFIG, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-team-port.c b/src/libnm-core-impl/nm-setting-team-port.c new file mode 100644 index 0000000..f3e3adb --- /dev/null +++ b/src/libnm-core-impl/nm-setting-team-port.c @@ -0,0 +1,685 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + * Copyright (C) 2013 Jiri Pirko + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-team-port.h" + +#include +#include + +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-team-utils.h" + +/** + * SECTION:nm-setting-team-port + * @short_description: Describes connection properties for team ports + * + * The #NMSettingTeamPort object is a #NMSetting subclass that describes + * optional properties that apply to team ports. + **/ + +/*****************************************************************************/ + +static GParamSpec *obj_properties[_NM_TEAM_ATTRIBUTE_PORT_NUM] = { + NULL, +}; + +typedef struct { + NMTeamSetting *team_setting; +} NMSettingTeamPortPrivate; + +G_DEFINE_TYPE(NMSettingTeamPort, nm_setting_team_port, NM_TYPE_SETTING) + +#define NM_SETTING_TEAM_PORT_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPortPrivate)) + +/*****************************************************************************/ + +NMTeamSetting * +_nm_setting_team_port_get_team_setting(NMSettingTeamPort *setting) +{ + return NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting; +} + +/*****************************************************************************/ + +#define _maybe_changed(self, changed) \ + nm_team_setting_maybe_changed(NM_SETTING(_NM_ENSURE_TYPE(NMSettingTeamPort *, self)), \ + (const GParamSpec *const *) obj_properties, \ + (changed)) + +#define _maybe_changed_with_assert(self, changed) \ + G_STMT_START \ + { \ + if (!_maybe_changed((self), (changed))) \ + nm_assert_not_reached(); \ + } \ + G_STMT_END + +/*****************************************************************************/ + +/** + * nm_setting_team_port_get_config: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:config property of the setting + **/ +const char * +nm_setting_team_port_get_config(NMSettingTeamPort *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM_PORT(setting), NULL); + + return nm_team_setting_config_get(NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting); +} + +/** + * nm_setting_team_port_get_queue_id: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:queue_id property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_port_get_queue_id(NMSettingTeamPort *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM_PORT(setting), -1); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting->d.port.queue_id; +} + +/** + * nm_setting_team_port_get_prio: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:prio property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_port_get_prio(NMSettingTeamPort *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM_PORT(setting), 0); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting->d.port.prio; +} + +/** + * nm_setting_team_port_get_sticky: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:sticky property of the setting + * + * Since: 1.12 + **/ +gboolean +nm_setting_team_port_get_sticky(NMSettingTeamPort *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM_PORT(setting), FALSE); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting->d.port.sticky; +} + +/** + * nm_setting_team_port_get_lacp_prio: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:lacp-prio property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_port_get_lacp_prio(NMSettingTeamPort *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM_PORT(setting), 0); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting->d.port.lacp_prio; +} + +/** + * nm_setting_team_port_get_lacp_key: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:lacp-key property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_port_get_lacp_key(NMSettingTeamPort *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM_PORT(setting), 0); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting->d.port.lacp_key; +} + +/** + * nm_setting_team_port_get_num_link_watchers: + * @setting: the #NMSettingTeamPort + * + * Returns: the number of configured link watchers + * + * Since: 1.12 + **/ +guint +nm_setting_team_port_get_num_link_watchers(NMSettingTeamPort *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM_PORT(setting), 0); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting->d.link_watchers->len; +} + +/** + * nm_setting_team_port_get_link_watcher: + * @setting: the #NMSettingTeamPort + * @idx: index number of the link watcher to return + * + * Returns: (transfer none): the link watcher at index @idx. + * + * Since: 1.12 + **/ +NMTeamLinkWatcher * +nm_setting_team_port_get_link_watcher(NMSettingTeamPort *setting, guint idx) +{ + NMSettingTeamPortPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_TEAM_PORT(setting), NULL); + + priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(setting); + + g_return_val_if_fail(idx < priv->team_setting->d.link_watchers->len, NULL); + + return priv->team_setting->d.link_watchers->pdata[idx]; +} + +/** + * nm_setting_team_port_add_link_watcher: + * @setting: the #NMSettingTeamPort + * @link_watcher: the link watcher to add + * + * Appends a new link watcher to the setting. + * + * Returns: %TRUE if the link watcher is added; %FALSE if an identical link + * watcher was already there. + * + * Since: 1.12 + **/ +gboolean +nm_setting_team_port_add_link_watcher(NMSettingTeamPort *setting, NMTeamLinkWatcher *link_watcher) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM_PORT(setting), FALSE); + g_return_val_if_fail(link_watcher != NULL, FALSE); + + return _maybe_changed(setting, + nm_team_setting_value_link_watchers_add( + NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting, + link_watcher)); +} + +/** + * nm_setting_team_port_remove_link_watcher: + * @setting: the #NMSettingTeamPort + * @idx: index number of the link watcher to remove + * + * Removes the link watcher at index #idx. + * + * Since: 1.12 + **/ +void +nm_setting_team_port_remove_link_watcher(NMSettingTeamPort *setting, guint idx) +{ + NMSettingTeamPortPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_TEAM_PORT(setting)); + + priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(setting); + + g_return_if_fail(idx < priv->team_setting->d.link_watchers->len); + + _maybe_changed_with_assert(setting, + nm_team_setting_value_link_watchers_remove(priv->team_setting, idx)); +} + +/** + * nm_setting_team_port_remove_link_watcher_by_value: + * @setting: the #NMSettingTeamPort + * @link_watcher: the link watcher to remove + * + * Removes the link watcher entry matching link_watcher. + * + * Returns: %TRUE if the link watcher was found and removed, %FALSE otherwise. + * + * Since: 1.12 + **/ +gboolean +nm_setting_team_port_remove_link_watcher_by_value(NMSettingTeamPort *setting, + NMTeamLinkWatcher *link_watcher) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM_PORT(setting), FALSE); + g_return_val_if_fail(link_watcher, FALSE); + + return _maybe_changed(setting, + nm_team_setting_value_link_watchers_remove_by_value( + NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting, + link_watcher)); +} + +/** + * nm_setting_team_port_clear_link_watchers: + * @setting: the #NMSettingTeamPort + * + * Removes all configured link watchers. + * + * Since: 1.12 + **/ +void +nm_setting_team_port_clear_link_watchers(NMSettingTeamPort *setting) +{ + g_return_if_fail(NM_IS_SETTING_TEAM_PORT(setting)); + + _maybe_changed(setting, + nm_team_setting_value_link_watchers_set_list( + NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting, + NULL, + 0)); +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(setting); + + if (connection) { + NMSettingConnection *s_con; + const char * slave_type; + + s_con = nm_connection_get_setting_connection(connection); + if (!s_con) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("missing setting")); + g_prefix_error(error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME); + return FALSE; + } + + slave_type = nm_setting_connection_get_slave_type(s_con); + if (slave_type && strcmp(slave_type, NM_SETTING_TEAM_SETTING_NAME)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with a '%s' setting must have the slave-type set to '%s'. " + "Instead it is '%s'"), + NM_SETTING_TEAM_PORT_SETTING_NAME, + NM_SETTING_TEAM_SETTING_NAME, + slave_type); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + } + + if (!nm_team_setting_verify(priv->team_setting, error)) + return FALSE; + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingTeamPortPrivate *a_priv; + NMSettingTeamPortPrivate *b_priv; + + if (nm_streq(sett_info->property_infos[property_idx].name, + NM_SETTING_TEAM_PORT_LINK_WATCHERS)) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; + if (!set_b) + return TRUE; + a_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_a); + b_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_b); + return nm_team_link_watchers_equal(a_priv->team_setting->d.link_watchers, + b_priv->team_setting->d.link_watchers, + TRUE); + } + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_TEAM_PORT_CONFIG)) { + if (set_b) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) { + /* If we are trying to match a connection in order to assume it (and thus + * @flags contains INFERRABLE), use the "relaxed" matching for team + * configuration. Otherwise, for all other purposes (including connection + * comparison before an update), resort to the default string comparison. */ + return TRUE; + } + + a_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_a); + b_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_b); + + return nm_streq0(nm_team_setting_config_get(a_priv->team_setting), + nm_team_setting_config_get(b_priv->team_setting)); + } + + return TRUE; + } + + return NM_SETTING_CLASS(nm_setting_team_port_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +static void +duplicate_copy_properties(const NMSettInfoSetting *sett_info, NMSetting *src, NMSetting *dst) +{ + _maybe_changed(NM_SETTING_TEAM_PORT(dst), + nm_team_setting_reset(NM_SETTING_TEAM_PORT_GET_PRIVATE(dst)->team_setting, + NM_SETTING_TEAM_PORT_GET_PRIVATE(src)->team_setting)); +} + +static gboolean +init_from_dbus(NMSetting * setting, + GHashTable * keys, + GVariant * setting_dict, + GVariant * connection_dict, + guint /* NMSettingParseFlags */ parse_flags, + GError ** error) +{ + guint32 changed = 0; + gboolean success; + + success = + nm_team_setting_reset_from_dbus(NM_SETTING_TEAM_PORT_GET_PRIVATE(setting)->team_setting, + setting_dict, + keys, + &changed, + parse_flags, + error); + _maybe_changed(NM_SETTING_TEAM_PORT(setting), changed); + return success; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingTeamPort * setting = NM_SETTING_TEAM_PORT(object); + NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(setting); + + switch (prop_id) { + case NM_TEAM_ATTRIBUTE_CONFIG: + g_value_set_string(value, nm_team_setting_config_get(priv->team_setting)); + break; + case NM_TEAM_ATTRIBUTE_PORT_STICKY: + g_value_set_boolean(value, nm_team_setting_value_get_bool(priv->team_setting, prop_id)); + break; + case NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID: + case NM_TEAM_ATTRIBUTE_PORT_PRIO: + case NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO: + case NM_TEAM_ATTRIBUTE_PORT_LACP_KEY: + g_value_set_int(value, nm_team_setting_value_get_int32(priv->team_setting, prop_id)); + break; + case NM_TEAM_ATTRIBUTE_LINK_WATCHERS: + g_value_take_boxed(value, + _nm_utils_copy_array(priv->team_setting->d.link_watchers, + (NMUtilsCopyFunc) _nm_team_link_watcher_ref, + (GDestroyNotify) nm_team_link_watcher_unref)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingTeamPort * setting = NM_SETTING_TEAM_PORT(object); + NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(setting); + guint32 changed; + const GPtrArray * v_ptrarr; + + switch (prop_id) { + case NM_TEAM_ATTRIBUTE_CONFIG: + changed = nm_team_setting_config_set(priv->team_setting, g_value_get_string(value)); + break; + case NM_TEAM_ATTRIBUTE_PORT_STICKY: + changed = + nm_team_setting_value_set_bool(priv->team_setting, prop_id, g_value_get_boolean(value)); + break; + case NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID: + case NM_TEAM_ATTRIBUTE_PORT_PRIO: + case NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO: + case NM_TEAM_ATTRIBUTE_PORT_LACP_KEY: + changed = + nm_team_setting_value_set_int32(priv->team_setting, prop_id, g_value_get_int(value)); + break; + case NM_TEAM_ATTRIBUTE_LINK_WATCHERS: + v_ptrarr = g_value_get_boxed(value); + changed = nm_team_setting_value_link_watchers_set_list( + priv->team_setting, + v_ptrarr ? (const NMTeamLinkWatcher *const *) v_ptrarr->pdata : NULL, + v_ptrarr ? v_ptrarr->len : 0u); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + return; + } + + _maybe_changed(setting, changed & ~(((guint32) 1) << prop_id)); +} + +/*****************************************************************************/ + +static void +nm_setting_team_port_init(NMSettingTeamPort *setting) +{ + NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(setting); + + priv->team_setting = nm_team_setting_new(TRUE, NULL); +} + +/** + * nm_setting_team_port_new: + * + * Creates a new #NMSettingTeamPort object with default values. + * + * Returns: (transfer full): the new empty #NMSettingTeamPort object + **/ +NMSetting * +nm_setting_team_port_new(void) +{ + return g_object_new(NM_TYPE_SETTING_TEAM_PORT, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(object); + + nm_team_setting_free(priv->team_setting); + + G_OBJECT_CLASS(nm_setting_team_port_parent_class)->finalize(object); +} + +static void +nm_setting_team_port_class_init(NMSettingTeamPortClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingTeamPortPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->compare_property = compare_property; + setting_class->verify = verify; + setting_class->duplicate_copy_properties = duplicate_copy_properties; + setting_class->init_from_dbus = init_from_dbus; + + /** + * NMSettingTeamPort:config: + * + * The JSON configuration for the team port. The property should contain raw + * JSON configuration data suitable for teamd, because the value is passed + * directly to teamd. If not specified, the default configuration is + * used. See man teamd.conf for the format details. + **/ + /* ---ifcfg-rh--- + * property: config + * variable: TEAM_PORT_CONFIG + * description: Team port configuration in JSON. See man teamd.conf for details. + * ---end--- + */ + obj_properties[NM_TEAM_ATTRIBUTE_CONFIG] = g_param_spec_string( + NM_SETTING_TEAM_PORT_CONFIG, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_CONFIG], + &nm_sett_info_propert_type_team_s); + + /** + * NMSettingTeamPort:queue-id: + * + * Corresponds to the teamd ports.PORTIFNAME.queue_id. + * When set to -1 means the parameter is skipped from the json config. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID] = + g_param_spec_int(NM_SETTING_TEAM_PORT_QUEUE_ID, + "", + "", + G_MININT32, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeamPort:prio: + * + * Corresponds to the teamd ports.PORTIFNAME.prio. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_PORT_PRIO] = + g_param_spec_int(NM_SETTING_TEAM_PORT_PRIO, + "", + "", + G_MININT32, + G_MAXINT32, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_PORT_PRIO], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeamPort:sticky: + * + * Corresponds to the teamd ports.PORTIFNAME.sticky. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_PORT_STICKY] = + g_param_spec_boolean(NM_SETTING_TEAM_PORT_STICKY, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_PORT_STICKY], + &nm_sett_info_propert_type_team_b); + + /** + * NMSettingTeamPort:lacp-prio: + * + * Corresponds to the teamd ports.PORTIFNAME.lacp_prio. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO] = + g_param_spec_int(NM_SETTING_TEAM_PORT_LACP_PRIO, + "", + "", + G_MININT32, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeamPort:lacp-key: + * + * Corresponds to the teamd ports.PORTIFNAME.lacp_key. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_PORT_LACP_KEY] = + g_param_spec_int(NM_SETTING_TEAM_PORT_LACP_KEY, + "", + "", + G_MININT32, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_PORT_LACP_KEY], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeamPort:link-watchers: (type GPtrArray(NMTeamLinkWatcher)) + * + * Link watchers configuration for the connection: each link watcher is + * defined by a dictionary, whose keys depend upon the selected link + * watcher. Available link watchers are 'ethtool', 'nsna_ping' and + * 'arp_ping' and it is specified in the dictionary with the key 'name'. + * Available keys are: ethtool: 'delay-up', 'delay-down', 'init-wait'; + * nsna_ping: 'init-wait', 'interval', 'missed-max', 'target-host'; + * arp_ping: all the ones in nsna_ping and 'source-host', 'validate-active', + * 'validate-inactive', 'send-always'. See teamd.conf man for more details. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS] = + g_param_spec_boxed(NM_SETTING_TEAM_PORT_LINK_WATCHERS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS], + &nm_sett_info_propert_type_team_link_watchers); + + g_object_class_install_properties(object_class, G_N_ELEMENTS(obj_properties), obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_TEAM_PORT, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-team.c b/src/libnm-core-impl/nm-setting-team.c new file mode 100644 index 0000000..d05f04c --- /dev/null +++ b/src/libnm-core-impl/nm-setting-team.c @@ -0,0 +1,1818 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + * Copyright (C) 2013 Jiri Pirko + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-team.h" + +#include + +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-team-utils.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-team + * @short_description: Describes connection properties for teams + * + * The #NMSettingTeam object is a #NMSetting subclass that describes properties + * necessary for team connections. + **/ + +/***************************************************************************** + * NMTeamLinkWatcher + *****************************************************************************/ + +G_DEFINE_BOXED_TYPE(NMTeamLinkWatcher, + nm_team_link_watcher, + _nm_team_link_watcher_ref, + nm_team_link_watcher_unref) + +typedef enum { + LINK_WATCHER_ETHTOOL = 0, + LINK_WATCHER_NSNA_PING = 1, + LINK_WATCHER_ARP_PING = 2, +} LinkWatcherTypes; + +static const char *_link_watcher_name[] = {[LINK_WATCHER_ETHTOOL] = NM_TEAM_LINK_WATCHER_ETHTOOL, + [LINK_WATCHER_NSNA_PING] = + NM_TEAM_LINK_WATCHER_NSNA_PING, + [LINK_WATCHER_ARP_PING] = NM_TEAM_LINK_WATCHER_ARP_PING}; + +struct NMTeamLinkWatcher { + int ref_count; + + guint8 type; /* LinkWatcherTypes */ + + union { + struct { + int delay_up; + int delay_down; + } ethtool; + struct { + const char *target_host; + int init_wait; + int interval; + int missed_max; + } nsna_ping; + struct { + const char * target_host; + const char * source_host; + int init_wait; + int interval; + int missed_max; + int vlanid; + NMTeamLinkWatcherArpPingFlags flags; + } arp_ping; + }; +}; + +#define _CHECK_WATCHER_VOID(watcher) \ + G_STMT_START \ + { \ + g_return_if_fail(watcher != NULL); \ + g_return_if_fail(watcher->ref_count > 0); \ + nm_assert(watcher->type <= LINK_WATCHER_ARP_PING); \ + } \ + G_STMT_END + +#define _CHECK_WATCHER(watcher, err_val) \ + G_STMT_START \ + { \ + g_return_val_if_fail(watcher != NULL, err_val); \ + g_return_val_if_fail(watcher->ref_count > 0, err_val); \ + nm_assert(watcher->type <= LINK_WATCHER_ARP_PING); \ + } \ + G_STMT_END + +/** + * nm_team_link_watcher_new_ethtool: + * @delay_up: delay_up value + * @delay_down: delay_down value + * @error: this call never fails, so this var is not used but kept for format + * consistency with the link_watcher constructors of other type + * + * Creates a new ethtool #NMTeamLinkWatcher object + * + * Returns: (transfer full): the new #NMTeamLinkWatcher object + * + * Since: 1.12 + **/ +NMTeamLinkWatcher * +nm_team_link_watcher_new_ethtool(int delay_up, int delay_down, GError **error) +{ + NMTeamLinkWatcher *watcher; + const char * val_fail = NULL; + + if (delay_up < 0 || !_NM_INT_LE_MAXINT32(delay_up)) + val_fail = "delay-up"; + if (delay_down < 0 || !_NM_INT_LE_MAXINT32(delay_down)) + val_fail = "delay-down"; + if (val_fail) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("%s is out of range [0, %d]"), + val_fail, + G_MAXINT32); + return NULL; + } + + NM_PRAGMA_WARNING_DISABLE("-Warray-bounds") + + watcher = g_malloc(nm_offsetofend(NMTeamLinkWatcher, ethtool)); + + watcher->ref_count = 1; + watcher->type = LINK_WATCHER_ETHTOOL; + watcher->ethtool.delay_up = delay_up; + watcher->ethtool.delay_down = delay_down; + + NM_PRAGMA_WARNING_REENABLE + + return watcher; +} + +/** + * nm_team_link_watcher_new_nsna_ping: + * @init_wait: init_wait value + * @interval: interval value + * @missed_max: missed_max value + * @target_host: the host name or the ipv6 address that will be used as + * target address in the NS packet + * @error: (out) (allow-none): location to store the error on failure + * + * Creates a new nsna_ping #NMTeamLinkWatcher object + * + * Returns: (transfer full): the new #NMTeamLinkWatcher object, or %NULL on error + * + * Since: 1.12 + **/ +NMTeamLinkWatcher * +nm_team_link_watcher_new_nsna_ping(int init_wait, + int interval, + int missed_max, + const char *target_host, + GError ** error) +{ + NMTeamLinkWatcher *watcher; + const char * val_fail = NULL; + char * str; + gsize l_target_host; + + if (!target_host) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Missing target-host in nsna_ping link watcher")); + return NULL; + } + + if (strpbrk(target_host, " \\/\t=\"\'")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("target-host '%s' contains invalid characters"), + target_host); + return NULL; + } + + if (init_wait < 0 || !_NM_INT_LE_MAXINT32(init_wait)) + val_fail = "init-wait"; + if (interval < 0 || !_NM_INT_LE_MAXINT32(interval)) + val_fail = "interval"; + if (missed_max < 0 || !_NM_INT_LE_MAXINT32(missed_max)) + val_fail = "missed-max"; + if (val_fail) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("%s is out of range [0, %d]"), + val_fail, + G_MAXINT32); + return NULL; + } + + l_target_host = strlen(target_host) + 1; + + watcher = g_malloc(nm_offsetofend(NMTeamLinkWatcher, nsna_ping) + l_target_host); + + watcher->ref_count = 1; + watcher->type = LINK_WATCHER_NSNA_PING; + watcher->nsna_ping.init_wait = init_wait; + watcher->nsna_ping.interval = interval; + watcher->nsna_ping.missed_max = missed_max; + + str = &((char *) watcher)[nm_offsetofend(NMTeamLinkWatcher, nsna_ping)]; + watcher->nsna_ping.target_host = str; + memcpy(str, target_host, l_target_host); + + return watcher; +} + +/** + * nm_team_link_watcher_new_arp_ping: + * @init_wait: init_wait value + * @interval: interval value + * @missed_max: missed_max value + * @target_host: the host name or the ip address that will be used as destination + * address in the arp request + * @source_host: the host name or the ip address that will be used as source + * address in the arp request + * @flags: the watcher #NMTeamLinkWatcherArpPingFlags + * @error: (out) (allow-none): location to store the error on failure + * + * Creates a new arp_ping #NMTeamLinkWatcher object + * + * Returns: (transfer full): the new #NMTeamLinkWatcher object, or %NULL on error + * + * Since: 1.12 + **/ +NMTeamLinkWatcher * +nm_team_link_watcher_new_arp_ping(int init_wait, + int interval, + int missed_max, + const char * target_host, + const char * source_host, + NMTeamLinkWatcherArpPingFlags flags, + GError ** error) +{ + return nm_team_link_watcher_new_arp_ping2(init_wait, + interval, + missed_max, + -1, + target_host, + source_host, + flags, + error); +} + +/** + * nm_team_link_watcher_new_arp_ping2: + * @init_wait: init_wait value + * @interval: interval value + * @missed_max: missed_max value + * @vlanid: vlanid value + * @target_host: the host name or the ip address that will be used as destination + * address in the arp request + * @source_host: the host name or the ip address that will be used as source + * address in the arp request + * @flags: the watcher #NMTeamLinkWatcherArpPingFlags + * @error: (out) (allow-none): location to store the error on failure + * + * Creates a new arp_ping #NMTeamLinkWatcher object + * + * Returns: (transfer full): the new #NMTeamLinkWatcher object, or %NULL on error + * + * Since: 1.16 + **/ +NMTeamLinkWatcher * +nm_team_link_watcher_new_arp_ping2(int init_wait, + int interval, + int missed_max, + int vlanid, + const char * target_host, + const char * source_host, + NMTeamLinkWatcherArpPingFlags flags, + GError ** error) +{ + NMTeamLinkWatcher *watcher; + const char * val_fail = NULL; + char * str; + gsize l_target_host; + gsize l_source_host; + + if (!target_host || !source_host) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Missing %s in arp_ping link watcher"), + target_host ? "source-host" : "target-host"); + return NULL; + } + + if (strpbrk(target_host, " \\/\t=\"\'")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("target-host '%s' contains invalid characters"), + target_host); + return NULL; + } + + if (strpbrk(source_host, " \\/\t=\"\'")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("source-host '%s' contains invalid characters"), + source_host); + return NULL; + } + + else if (init_wait < 0 || !_NM_INT_LE_MAXINT32(init_wait)) + val_fail = "init-wait"; + else if (interval < 0 || !_NM_INT_LE_MAXINT32(interval)) + val_fail = "interval"; + else if (missed_max < 0 || !_NM_INT_LE_MAXINT32(missed_max)) + val_fail = "missed-max"; + if (val_fail) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("%s is out of range [0, %d]"), + val_fail, + G_MAXINT32); + return NULL; + } + + if (vlanid < -1 || vlanid > 4094) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("vlanid is out of range [-1, 4094]")); + return NULL; + } + + l_target_host = strlen(target_host) + 1; + l_source_host = strlen(source_host) + 1; + + watcher = g_malloc(nm_offsetofend(NMTeamLinkWatcher, arp_ping) + l_target_host + l_source_host); + + watcher->ref_count = 1; + watcher->type = LINK_WATCHER_ARP_PING; + watcher->arp_ping.init_wait = init_wait; + watcher->arp_ping.interval = interval; + watcher->arp_ping.missed_max = missed_max; + watcher->arp_ping.flags = flags; + watcher->arp_ping.vlanid = vlanid; + + str = &((char *) watcher)[nm_offsetofend(NMTeamLinkWatcher, arp_ping)]; + watcher->arp_ping.target_host = str; + memcpy(str, target_host, l_target_host); + + str += l_target_host; + watcher->arp_ping.source_host = str; + memcpy(str, source_host, l_source_host); + + return watcher; +} + +NMTeamLinkWatcher * +_nm_team_link_watcher_ref(NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, NULL); + + g_atomic_int_inc(&watcher->ref_count); + return watcher; +} + +/** + * nm_team_link_watcher_ref: + * @watcher: the #NMTeamLinkWatcher + * + * Increases the reference count of the object. + * + * Since: 1.12 + **/ +void +nm_team_link_watcher_ref(NMTeamLinkWatcher *watcher) +{ + _nm_team_link_watcher_ref(watcher); +} + +/** + * nm_team_link_watcher_unref: + * @watcher: the #NMTeamLinkWatcher + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + * + * Since: 1.12 + **/ +void +nm_team_link_watcher_unref(NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER_VOID(watcher); + + if (g_atomic_int_dec_and_test(&watcher->ref_count)) + g_free(watcher); +} + +int +nm_team_link_watcher_cmp(const NMTeamLinkWatcher *watcher, const NMTeamLinkWatcher *other) +{ + NM_CMP_SELF(watcher, other); + + NM_CMP_FIELD(watcher, other, type); + + switch (watcher->type) { + case LINK_WATCHER_ETHTOOL: + NM_CMP_FIELD(watcher, other, ethtool.delay_up); + NM_CMP_FIELD(watcher, other, ethtool.delay_down); + break; + case LINK_WATCHER_NSNA_PING: + NM_CMP_FIELD_STR(watcher, other, nsna_ping.target_host); + NM_CMP_FIELD(watcher, other, nsna_ping.init_wait); + NM_CMP_FIELD(watcher, other, nsna_ping.interval); + NM_CMP_FIELD(watcher, other, nsna_ping.missed_max); + break; + case LINK_WATCHER_ARP_PING: + NM_CMP_FIELD_STR(watcher, other, arp_ping.target_host); + NM_CMP_FIELD_STR(watcher, other, arp_ping.source_host); + NM_CMP_FIELD(watcher, other, arp_ping.init_wait); + NM_CMP_FIELD(watcher, other, arp_ping.interval); + NM_CMP_FIELD(watcher, other, arp_ping.missed_max); + NM_CMP_FIELD(watcher, other, arp_ping.vlanid); + NM_CMP_FIELD(watcher, other, arp_ping.flags); + break; + } + return 0; +} + +/** + * nm_team_link_watcher_equal: + * @watcher: the #NMTeamLinkWatcher + * @other: the #NMTeamLinkWatcher to compare @watcher to. + * + * Determines if two #NMTeamLinkWatcher objects contain the same values + * in all the properties. + * + * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + * + * Since: 1.12 + **/ +gboolean +nm_team_link_watcher_equal(const NMTeamLinkWatcher *watcher, const NMTeamLinkWatcher *other) +{ + return nm_team_link_watcher_cmp(watcher, other) == 0; +} + +static int +_team_link_watchers_cmp_p_with_data(gconstpointer data_a, gconstpointer data_b, gpointer user_data) +{ + return nm_team_link_watcher_cmp(*((const NMTeamLinkWatcher *const *) data_a), + *((const NMTeamLinkWatcher *const *) data_b)); +} + +int +nm_team_link_watchers_cmp(const NMTeamLinkWatcher *const *a, + const NMTeamLinkWatcher *const *b, + gsize len, + gboolean ignore_order) +{ + gs_free const NMTeamLinkWatcher **a_free = NULL; + gs_free const NMTeamLinkWatcher **b_free = NULL; + guint i; + + if (ignore_order && len > 1) { + a = nm_memdup_maybe_a(200, a, len * sizeof(*a), &a_free); + b = nm_memdup_maybe_a(200, b, len * sizeof(*b), &b_free); + g_qsort_with_data((gpointer) a, len, sizeof(*a), _team_link_watchers_cmp_p_with_data, NULL); + g_qsort_with_data((gpointer) b, len, sizeof(*b), _team_link_watchers_cmp_p_with_data, NULL); + } + for (i = 0; i < len; i++) { + NM_CMP_RETURN(nm_team_link_watcher_cmp(a[i], b[i])); + } + return 0; +} + +gboolean +nm_team_link_watchers_equal(const GPtrArray *a, const GPtrArray *b, gboolean ignore_order) +{ + return a == b + || (a && b && a->len == b->len + && (nm_team_link_watchers_cmp((const NMTeamLinkWatcher *const *) a->pdata, + (const NMTeamLinkWatcher *const *) b->pdata, + a->len, + ignore_order) + == 0)); +} + +/** + * nm_team_link_watcher_dup: + * @watcher: the #NMTeamLinkWatcher + * + * Creates a copy of @watcher + * + * Returns: (transfer full): a copy of @watcher + * + * Since: 1.12 + **/ +NMTeamLinkWatcher * +nm_team_link_watcher_dup(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, NULL); + + switch (watcher->type) { + case LINK_WATCHER_ETHTOOL: + return nm_team_link_watcher_new_ethtool(watcher->ethtool.delay_up, + watcher->ethtool.delay_down, + NULL); + break; + case LINK_WATCHER_NSNA_PING: + return nm_team_link_watcher_new_nsna_ping(watcher->nsna_ping.init_wait, + watcher->nsna_ping.interval, + watcher->nsna_ping.missed_max, + watcher->nsna_ping.target_host, + NULL); + break; + case LINK_WATCHER_ARP_PING: + return nm_team_link_watcher_new_arp_ping2(watcher->arp_ping.init_wait, + watcher->arp_ping.interval, + watcher->arp_ping.missed_max, + watcher->arp_ping.vlanid, + watcher->arp_ping.target_host, + watcher->arp_ping.source_host, + watcher->arp_ping.flags, + NULL); + default: + nm_assert_not_reached(); + return NULL; + } +} + +/** + * nm_team_link_watcher_get_name: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the name of the link watcher to be used. + * + * Since: 1.12 + **/ +const char * +nm_team_link_watcher_get_name(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, NULL); + + return _link_watcher_name[watcher->type]; +} + +/** + * nm_team_link_watcher_get_delay_up: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the delay_up interval (in milliseconds) that elapses between the link + * coming up and the runner being notified about it. + * + * Since: 1.12 + **/ +int +nm_team_link_watcher_get_delay_up(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, 0); + + if (watcher->type == LINK_WATCHER_ETHTOOL) + return watcher->ethtool.delay_up; + return -1; +} + +/** + * nm_team_link_watcher_get_delay_down: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the delay_down interval (in milliseconds) that elapses between the link + * going down and the runner being notified about it. + * + * Since: 1.12 + **/ +int +nm_team_link_watcher_get_delay_down(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, 0); + + if (watcher->type == LINK_WATCHER_ETHTOOL) + return watcher->ethtool.delay_down; + return -1; +} + +/** + * nm_team_link_watcher_get_init_wait: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the init_wait interval (in milliseconds) that the team slave should + * wait before sending the first packet to the target host. + * + * Since: 1.12 + **/ +int +nm_team_link_watcher_get_init_wait(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, 0); + + if (watcher->type == LINK_WATCHER_NSNA_PING) + return watcher->nsna_ping.init_wait; + if (watcher->type == LINK_WATCHER_ARP_PING) + return watcher->arp_ping.init_wait; + return -1; +} + +/** + * nm_team_link_watcher_get_interval: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the interval (in milliseconds) that the team slave should wait between + * sending two check packets to the target host. + * + * Since: 1.12 + **/ +int +nm_team_link_watcher_get_interval(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, 0); + + if (watcher->type == LINK_WATCHER_NSNA_PING) + return watcher->nsna_ping.interval; + if (watcher->type == LINK_WATCHER_ARP_PING) + return watcher->arp_ping.interval; + return -1; +} + +/** + * nm_team_link_watcher_get_missed_max: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the number of missed replies after which the link is considered down. + * + * Since: 1.12 + **/ +int +nm_team_link_watcher_get_missed_max(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, 0); + + if (watcher->type == LINK_WATCHER_NSNA_PING) + return watcher->nsna_ping.missed_max; + if (watcher->type == LINK_WATCHER_ARP_PING) + return watcher->arp_ping.missed_max; + return -1; +} + +/** + * nm_team_link_watcher_get_vlanid: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the VLAN tag ID to be used to outgoing link probes + * + * Since: 1.16 + **/ +int +nm_team_link_watcher_get_vlanid(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, -1); + + if (watcher->type == LINK_WATCHER_ARP_PING) + return watcher->arp_ping.vlanid; + return -1; +} + +/** + * nm_team_link_watcher_get_target_host: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the host name/ip address to be used as destination for the link probing + * packets. + * + * Since: 1.12 + **/ +const char * +nm_team_link_watcher_get_target_host(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, NULL); + + if (watcher->type == LINK_WATCHER_NSNA_PING) + return watcher->nsna_ping.target_host; + if (watcher->type == LINK_WATCHER_ARP_PING) + return watcher->arp_ping.target_host; + return NULL; +} + +/** + * nm_team_link_watcher_get_source_host: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the ip address to be used as source for the link probing packets. + * + * Since: 1.12 + **/ +const char * +nm_team_link_watcher_get_source_host(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, NULL); + + if (watcher->type == LINK_WATCHER_ARP_PING) + return watcher->arp_ping.source_host; + return NULL; +} + +/** + * nm_team_link_watcher_get_flags: + * @watcher: the #NMTeamLinkWatcher + * + * Gets the arp ping watcher flags. + * + * Since: 1.12 + **/ +NMTeamLinkWatcherArpPingFlags +nm_team_link_watcher_get_flags(const NMTeamLinkWatcher *watcher) +{ + _CHECK_WATCHER(watcher, 0); + + if (watcher->type == LINK_WATCHER_ARP_PING) + return watcher->arp_ping.flags; + return 0; +} + +/*****************************************************************************/ + +static GParamSpec *obj_properties[_NM_TEAM_ATTRIBUTE_MASTER_NUM] = { + NULL, +}; + +typedef struct { + NMTeamSetting *team_setting; +} NMSettingTeamPrivate; + +G_DEFINE_TYPE(NMSettingTeam, nm_setting_team, NM_TYPE_SETTING) + +#define NM_SETTING_TEAM_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_TEAM, NMSettingTeamPrivate)) + +/*****************************************************************************/ + +NMTeamSetting * +_nm_setting_team_get_team_setting(NMSettingTeam *setting) +{ + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting; +} + +/*****************************************************************************/ + +#define _maybe_changed(self, changed) \ + nm_team_setting_maybe_changed(NM_SETTING(_NM_ENSURE_TYPE(NMSettingTeam *, self)), \ + (const GParamSpec *const *) obj_properties, \ + (changed)) + +#define _maybe_changed_with_assert(self, changed) \ + G_STMT_START \ + { \ + if (!_maybe_changed((self), (changed))) \ + nm_assert_not_reached(); \ + } \ + G_STMT_END + +/** + * nm_setting_team_get_config: + * @setting: the #NMSettingTeam + * + * Returns: the #NMSettingTeam:config property of the setting + **/ +const char * +nm_setting_team_get_config(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), NULL); + + return nm_team_setting_config_get(NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting); +} + +/** + * nm_setting_team_get_notify_peers_count: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:notify-peers-count property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_get_notify_peers_count(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.notify_peers_count; +} + +/** + * nm_setting_team_get_notify_peers_interval: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:notify-peers-interval property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_get_notify_peers_interval(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.notify_peers_interval; +} + +/** + * nm_setting_team_get_mcast_rejoin_count: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:mcast-rejoin-count property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_get_mcast_rejoin_count(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.mcast_rejoin_count; +} + +/** + * nm_setting_team_get_mcast_rejoin_interval: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:mcast-rejoin-interval property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_get_mcast_rejoin_interval(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.mcast_rejoin_interval; +} + +/** + * nm_setting_team_get_runner: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner property of the setting + * + * Since: 1.12 + **/ +const char * +nm_setting_team_get_runner(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), NULL); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner; +} + +/** + * nm_setting_team_get_runner_hwaddr_policy: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-hwaddr-policy property of the setting + * + * Since: 1.12 + **/ +const char * +nm_setting_team_get_runner_hwaddr_policy(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), NULL); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner_hwaddr_policy; +} + +/** + * nm_setting_team_get_runner_tx_balancer: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-tx-balancer property of the setting + * + * Since: 1.12 + **/ +const char * +nm_setting_team_get_runner_tx_balancer(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), NULL); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner_tx_balancer; +} + +/** + * nm_setting_team_get_runner_tx_balancer_interval: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-tx-balancer_interval property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_get_runner_tx_balancer_interval(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner_tx_balancer_interval; +} + +/** + * nm_setting_team_get_runner_active: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner_active property of the setting + * + * Since: 1.12 + **/ +gboolean +nm_setting_team_get_runner_active(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), FALSE); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner_active; +} + +/** + * nm_setting_team_get_runner_fast_rate: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-fast-rate property of the setting + * + * Since: 1.12 + **/ +gboolean +nm_setting_team_get_runner_fast_rate(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), FALSE); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner_fast_rate; +} + +/** + * nm_setting_team_get_runner_sys_prio: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-sys-prio property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_get_runner_sys_prio(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner_sys_prio; +} + +/** + * nm_setting_team_get_runner_min_ports: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-min-ports property of the setting + * + * Since: 1.12 + **/ +int +nm_setting_team_get_runner_min_ports(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner_min_ports; +} + +/** + * nm_setting_team_get_runner_agg_select_policy: + * @setting: the #NMSettingTeam + * + * Returns: the ##NMSettingTeam:runner-agg-select-policy property of the setting + * + * Since: 1.12 + **/ +const char * +nm_setting_team_get_runner_agg_select_policy(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), NULL); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner_agg_select_policy; +} + +/** + * nm_setting_team_remove_runner_tx_hash_by_value: + * @setting: the #NMSetetingTeam + * @txhash: the txhash element to remove + * + * Removes the txhash element #txhash + * + * Returns: %TRUE if the txhash element was found and removed; %FALSE if it was not. + * + * Since: 1.12 + **/ +gboolean +nm_setting_team_remove_runner_tx_hash_by_value(NMSettingTeam *setting, const char *txhash) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE(setting); + const GPtrArray * arr; + guint i; + + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), FALSE); + g_return_val_if_fail(txhash != NULL, FALSE); + + arr = priv->team_setting->d.master.runner_tx_hash; + if (arr) { + for (i = 0; i < arr->len; i++) { + if (nm_streq(txhash, arr->pdata[i])) { + _maybe_changed_with_assert( + setting, + nm_team_setting_value_master_runner_tx_hash_remove(priv->team_setting, i)); + return TRUE; + } + } + } + return FALSE; +} + +/** + * nm_setting_team_get_num_runner_tx_hash: + * @setting: the #NMSettingTeam + * + * Returns: the number of elements in txhash + * + * Since: 1.12 + **/ +guint +nm_setting_team_get_num_runner_tx_hash(NMSettingTeam *setting) +{ + const GPtrArray *arr; + + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), 0); + + arr = NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner_tx_hash; + return arr ? arr->len : 0u; +} + +/** + * nm_setting_team_get_runner_tx_hash + * @setting: the #NMSettingTeam + * @idx: index number of the txhash element to return + * + * Returns: the txhash element at index @idx + * + * Since: 1.12 + **/ +const char * +nm_setting_team_get_runner_tx_hash(NMSettingTeam *setting, guint idx) +{ + const GPtrArray *arr; + + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), NULL); + + arr = NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.master.runner_tx_hash; + + g_return_val_if_fail(arr, NULL); + g_return_val_if_fail(idx < arr->len, NULL); + + return arr->pdata[idx]; +} + +/** + * nm_setting_team_remove_runner_tx_hash: + * @setting: the #NMSettingTeam + * @idx: index number of the element to remove from txhash + * + * Removes the txhash element at index @idx. + * + * Since: 1.12 + **/ +void +nm_setting_team_remove_runner_tx_hash(NMSettingTeam *setting, guint idx) +{ + NMSettingTeamPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_TEAM(setting)); + + priv = NM_SETTING_TEAM_GET_PRIVATE(setting); + + g_return_if_fail(priv->team_setting->d.master.runner_tx_hash); + g_return_if_fail(idx < priv->team_setting->d.master.runner_tx_hash->len); + + _maybe_changed_with_assert( + setting, + nm_team_setting_value_master_runner_tx_hash_remove(priv->team_setting, idx)); +} + +/** + * nm_setting_team_add_runner_tx_hash: + * @setting: the #NMSettingTeam + * @txhash: the element to add to txhash + * + * Adds a new txhash element to the setting. + * + * Returns: %TRUE if the txhash element was added; %FALSE if the element + * was already knnown. + * + * Since: 1.12 + **/ +gboolean +nm_setting_team_add_runner_tx_hash(NMSettingTeam *setting, const char *txhash) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), FALSE); + g_return_val_if_fail(txhash, FALSE); + + return _maybe_changed(setting, + nm_team_setting_value_master_runner_tx_hash_add( + NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting, + txhash)); +} + +/** + * nm_setting_team_get_num_link_watchers: + * @setting: the #NMSettingTeam + * + * Returns: the number of configured link watchers + * + * Since: 1.12 + **/ +guint +nm_setting_team_get_num_link_watchers(NMSettingTeam *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), 0); + + return NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.link_watchers->len; +} + +/** + * nm_setting_team_get_link_watcher: + * @setting: the #NMSettingTeam + * @idx: index number of the link watcher to return + * + * Returns: (transfer none): the link watcher at index @idx. + * + * Since: 1.12 + **/ +NMTeamLinkWatcher * +nm_setting_team_get_link_watcher(NMSettingTeam *setting, guint idx) +{ + const GPtrArray *arr; + + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), NULL); + + arr = NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting->d.link_watchers; + + g_return_val_if_fail(idx < arr->len, NULL); + + return arr->pdata[idx]; +} + +/** + * nm_setting_team_add_link_watcher: + * @setting: the #NMSettingTeam + * @link_watcher: the link watcher to add + * + * Appends a new link watcher to the setting. + * + * Returns: %TRUE if the link watcher is added; %FALSE if an identical link + * watcher was already there. + * + * Since: 1.12 + **/ +gboolean +nm_setting_team_add_link_watcher(NMSettingTeam *setting, NMTeamLinkWatcher *link_watcher) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), FALSE); + g_return_val_if_fail(link_watcher != NULL, FALSE); + + return _maybe_changed( + setting, + nm_team_setting_value_link_watchers_add(NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting, + link_watcher)); +} + +/** + * nm_setting_team_remove_link_watcher: + * @setting: the #NMSettingTeam + * @idx: index number of the link watcher to remove + * + * Removes the link watcher at index #idx. + * + * Since: 1.12 + **/ +void +nm_setting_team_remove_link_watcher(NMSettingTeam *setting, guint idx) +{ + NMSettingTeamPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_TEAM(setting)); + + priv = NM_SETTING_TEAM_GET_PRIVATE(setting); + + g_return_if_fail(idx < priv->team_setting->d.link_watchers->len); + + _maybe_changed_with_assert(setting, + nm_team_setting_value_link_watchers_remove(priv->team_setting, idx)); +} + +/** + * nm_setting_team_remove_link_watcher_by_value: + * @setting: the #NMSettingTeam + * @link_watcher: the link watcher to remove + * + * Removes the link watcher entry matching link_watcher. + * + * Returns: %TRUE if the link watcher was found and removed, %FALSE otherwise. + * + * Since: 1.12 + **/ +gboolean +nm_setting_team_remove_link_watcher_by_value(NMSettingTeam * setting, + NMTeamLinkWatcher *link_watcher) +{ + g_return_val_if_fail(NM_IS_SETTING_TEAM(setting), FALSE); + g_return_val_if_fail(link_watcher, FALSE); + + return _maybe_changed(setting, + nm_team_setting_value_link_watchers_remove_by_value( + NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting, + link_watcher)); +} + +/** + * nm_setting_team_clear_link_watchers: + * @setting: the #NMSettingTeam + * + * Removes all configured link watchers. + * + * Since: 1.12 + **/ +void +nm_setting_team_clear_link_watchers(NMSettingTeam *setting) +{ + g_return_if_fail(NM_IS_SETTING_TEAM(setting)); + + _maybe_changed(setting, + nm_team_setting_value_link_watchers_set_list( + NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting, + NULL, + 0)); +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE(setting); + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + if (!nm_team_setting_verify(priv->team_setting, error)) + return FALSE; + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingTeamPrivate *a_priv, *b_priv; + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_TEAM_LINK_WATCHERS)) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; + if (!set_b) + return TRUE; + a_priv = NM_SETTING_TEAM_GET_PRIVATE(set_a); + b_priv = NM_SETTING_TEAM_GET_PRIVATE(set_b); + return nm_team_link_watchers_equal(a_priv->team_setting->d.link_watchers, + b_priv->team_setting->d.link_watchers, + TRUE); + } + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_TEAM_CONFIG)) { + if (set_b) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) { + /* If we are trying to match a connection in order to assume it (and thus + * @flags contains INFERRABLE), use the "relaxed" matching for team + * configuration. Otherwise, for all other purposes (including connection + * comparison before an update), resort to the default string comparison. */ + return TRUE; + } + + a_priv = NM_SETTING_TEAM_GET_PRIVATE(set_a); + b_priv = NM_SETTING_TEAM_GET_PRIVATE(set_b); + + return nm_streq0(nm_team_setting_config_get(a_priv->team_setting), + nm_team_setting_config_get(b_priv->team_setting)); + } + + return TRUE; + } + + return NM_SETTING_CLASS(nm_setting_team_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +static void +duplicate_copy_properties(const NMSettInfoSetting *sett_info, NMSetting *src, NMSetting *dst) +{ + _maybe_changed(NM_SETTING_TEAM(dst), + nm_team_setting_reset(NM_SETTING_TEAM_GET_PRIVATE(dst)->team_setting, + NM_SETTING_TEAM_GET_PRIVATE(src)->team_setting)); +} + +static gboolean +init_from_dbus(NMSetting * setting, + GHashTable * keys, + GVariant * setting_dict, + GVariant * connection_dict, + guint /* NMSettingParseFlags */ parse_flags, + GError ** error) +{ + guint32 changed = 0; + gboolean success; + + if (keys) + g_hash_table_remove(keys, "interface-name"); + + success = nm_team_setting_reset_from_dbus(NM_SETTING_TEAM_GET_PRIVATE(setting)->team_setting, + setting_dict, + keys, + &changed, + parse_flags, + error); + _maybe_changed(NM_SETTING_TEAM(setting), changed); + return success; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingTeam * setting = NM_SETTING_TEAM(object); + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE(setting); + const GPtrArray * v_ptrarr; + + switch (prop_id) { + case NM_TEAM_ATTRIBUTE_CONFIG: + g_value_set_string(value, nm_team_setting_config_get(priv->team_setting)); + break; + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE: + g_value_set_boolean(value, nm_team_setting_value_get_bool(priv->team_setting, prop_id)); + break; + case NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT: + case NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL: + case NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT: + case NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS: + g_value_set_int(value, nm_team_setting_value_get_int32(priv->team_setting, prop_id)); + break; + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY: + g_value_set_string(value, nm_team_setting_value_get_string(priv->team_setting, prop_id)); + break; + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH: + v_ptrarr = priv->team_setting->d.master.runner_tx_hash; + g_value_take_boxed(value, + v_ptrarr ? _nm_utils_ptrarray_to_strv((GPtrArray *) v_ptrarr) : NULL); + break; + case NM_TEAM_ATTRIBUTE_LINK_WATCHERS: + g_value_take_boxed(value, + _nm_utils_copy_array(priv->team_setting->d.link_watchers, + (NMUtilsCopyFunc) _nm_team_link_watcher_ref, + (GDestroyNotify) nm_team_link_watcher_unref)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingTeam * setting = NM_SETTING_TEAM(object); + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE(object); + guint32 changed; + const GPtrArray * v_ptrarr; + + switch (prop_id) { + case NM_TEAM_ATTRIBUTE_CONFIG: + changed = nm_team_setting_config_set(priv->team_setting, g_value_get_string(value)); + break; + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE: + changed = + nm_team_setting_value_set_bool(priv->team_setting, prop_id, g_value_get_boolean(value)); + break; + case NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT: + case NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL: + case NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT: + case NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS: + changed = + nm_team_setting_value_set_int32(priv->team_setting, prop_id, g_value_get_int(value)); + break; + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY: + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY: + changed = nm_team_setting_value_set_string(priv->team_setting, + prop_id, + g_value_get_string(value)); + break; + case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH: + v_ptrarr = g_value_get_boxed(value); + changed = nm_team_setting_value_master_runner_tx_hash_set_list( + priv->team_setting, + v_ptrarr ? (const char *const *) v_ptrarr->pdata : NULL, + v_ptrarr ? v_ptrarr->len : 0u); + break; + case NM_TEAM_ATTRIBUTE_LINK_WATCHERS: + v_ptrarr = g_value_get_boxed(value); + changed = nm_team_setting_value_link_watchers_set_list( + priv->team_setting, + v_ptrarr ? (const NMTeamLinkWatcher *const *) v_ptrarr->pdata : NULL, + v_ptrarr ? v_ptrarr->len : 0u); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + return; + } + + _maybe_changed(setting, changed & ~(((guint32) 1) << prop_id)); +} + +/*****************************************************************************/ + +static void +nm_setting_team_init(NMSettingTeam *setting) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE(setting); + + priv->team_setting = nm_team_setting_new(FALSE, NULL); +} + +/** + * nm_setting_team_new: + * + * Creates a new #NMSettingTeam object with default values. + * + * Returns: (transfer full): the new empty #NMSettingTeam object + **/ +NMSetting * +nm_setting_team_new(void) +{ + return g_object_new(NM_TYPE_SETTING_TEAM, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE(object); + + nm_team_setting_free(priv->team_setting); + + G_OBJECT_CLASS(nm_setting_team_parent_class)->finalize(object); +} + +static void +nm_setting_team_class_init(NMSettingTeamClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingTeamPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->compare_property = compare_property; + setting_class->verify = verify; + setting_class->duplicate_copy_properties = duplicate_copy_properties; + setting_class->init_from_dbus = init_from_dbus; + + /** + * NMSettingTeam:config: + * + * The JSON configuration for the team network interface. The property + * should contain raw JSON configuration data suitable for teamd, because + * the value is passed directly to teamd. If not specified, the default + * configuration is used. See man teamd.conf for the format details. + **/ + /* ---ifcfg-rh--- + * property: config + * variable: TEAM_CONFIG + * description: Team configuration in JSON. See man teamd.conf for details. + * ---end--- + */ + obj_properties[NM_TEAM_ATTRIBUTE_CONFIG] = g_param_spec_string( + NM_SETTING_TEAM_CONFIG, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_CONFIG], + &nm_sett_info_propert_type_team_s); + + /** + * NMSettingTeam:notify-peers-count: + * + * Corresponds to the teamd notify_peers.count. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT] = + g_param_spec_int(NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, + "", + "", + G_MININT32, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeam:notify-peers-interval: + * + * Corresponds to the teamd notify_peers.interval. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL] = + g_param_spec_int(NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL, + "", + "", + G_MININT32, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeam:mcast-rejoin-count: + * + * Corresponds to the teamd mcast_rejoin.count. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT] = + g_param_spec_int(NM_SETTING_TEAM_MCAST_REJOIN_COUNT, + "", + "", + G_MININT32, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeam:mcast-rejoin-interval: + * + * Corresponds to the teamd mcast_rejoin.interval. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL] = + g_param_spec_int(NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL, + "", + "", + G_MININT32, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeam:runner: + * + * Corresponds to the teamd runner.name. + * Permitted values are: "roundrobin", "broadcast", "activebackup", + * "loadbalance", "lacp", "random". + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER] = + g_param_spec_string(NM_SETTING_TEAM_RUNNER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER], + &nm_sett_info_propert_type_team_s); + + /** + * NMSettingTeam:runner-hwaddr-policy: + * + * Corresponds to the teamd runner.hwaddr_policy. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY] = + g_param_spec_string(NM_SETTING_TEAM_RUNNER_HWADDR_POLICY, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY], + &nm_sett_info_propert_type_team_s); + + /** + * NMSettingTeam:runner-tx-hash: + * + * Corresponds to the teamd runner.tx_hash. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH] = g_param_spec_boxed( + NM_SETTING_TEAM_RUNNER_TX_HASH, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH], + &nm_sett_info_propert_type_team_as); + + /** + * NMSettingTeam:runner-tx-balancer: + * + * Corresponds to the teamd runner.tx_balancer.name. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER] = + g_param_spec_string(NM_SETTING_TEAM_RUNNER_TX_BALANCER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER], + &nm_sett_info_propert_type_team_s); + + /** + * NMSettingTeam:runner-tx-balancer-interval: + * + * Corresponds to the teamd runner.tx_balancer.interval. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL] = + g_param_spec_int(NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, + "", + "", + G_MININT32, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj( + properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeam:runner-active: + * + * Corresponds to the teamd runner.active. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE] = + g_param_spec_boolean(NM_SETTING_TEAM_RUNNER_ACTIVE, + "", + "", + TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE], + &nm_sett_info_propert_type_team_b); + + /** + * NMSettingTeam:runner-fast-rate: + * + * Corresponds to the teamd runner.fast_rate. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE] = + g_param_spec_boolean(NM_SETTING_TEAM_RUNNER_FAST_RATE, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE], + &nm_sett_info_propert_type_team_b); + + /** + * NMSettingTeam:runner-sys-prio: + * + * Corresponds to the teamd runner.sys_prio. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO] = + g_param_spec_int(NM_SETTING_TEAM_RUNNER_SYS_PRIO, + "", + "", + G_MININT32, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeam:runner-min-ports: + * + * Corresponds to the teamd runner.min_ports. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS] = + g_param_spec_int(NM_SETTING_TEAM_RUNNER_MIN_PORTS, + "", + "", + G_MININT32, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS], + &nm_sett_info_propert_type_team_i); + + /** + * NMSettingTeam:runner-agg-select-policy: + * + * Corresponds to the teamd runner.agg_select_policy. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY] = + g_param_spec_string(NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY], + &nm_sett_info_propert_type_team_s); + + /** + * NMSettingTeam:link-watchers: (type GPtrArray(NMTeamLinkWatcher)) + * + * Link watchers configuration for the connection: each link watcher is + * defined by a dictionary, whose keys depend upon the selected link + * watcher. Available link watchers are 'ethtool', 'nsna_ping' and + * 'arp_ping' and it is specified in the dictionary with the key 'name'. + * Available keys are: ethtool: 'delay-up', 'delay-down', 'init-wait'; + * nsna_ping: 'init-wait', 'interval', 'missed-max', 'target-host'; + * arp_ping: all the ones in nsna_ping and 'source-host', 'validate-active', + * 'validate-inactive', 'send-always'. See teamd.conf man for more details. + * + * Since: 1.12 + **/ + obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS] = + g_param_spec_boxed(NM_SETTING_TEAM_LINK_WATCHERS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS], + &nm_sett_info_propert_type_team_link_watchers); + + /* ---dbus--- + * property: interface-name + * format: string + * description: Deprecated in favor of connection.interface-name, but can + * be used for backward-compatibility with older daemons, to set the + * team's interface name. + * ---end--- + */ + _nm_properties_override_dbus(properties_override, + "interface-name", + &nm_sett_info_propert_type_deprecated_interface_name); + + g_object_class_install_properties(object_class, G_N_ELEMENTS(obj_properties), obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_TEAM, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-tun.c b/src/libnm-core-impl/nm-setting-tun.c new file mode 100644 index 0000000..412292a --- /dev/null +++ b/src/libnm-core-impl/nm-setting-tun.c @@ -0,0 +1,397 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-tun.h" + +#include + +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-tun + * @short_description: Describes connection properties for TUN/TAP interfaces + * + * The #NMSettingTun object is a #NMSetting subclass that describes properties + * necessary for connection to TUN/TAP interfaces. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_MODE, + PROP_OWNER, + PROP_GROUP, + PROP_PI, + PROP_VNET_HDR, + PROP_MULTI_QUEUE, ); + +typedef struct { + char * owner; + char * group; + NMSettingTunMode mode; + bool pi : 1; + bool vnet_hdr : 1; + bool multi_queue : 1; +} NMSettingTunPrivate; + +G_DEFINE_TYPE(NMSettingTun, nm_setting_tun, NM_TYPE_SETTING) + +#define NM_SETTING_TUN_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_TUN, NMSettingTunPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_tun_get_mode: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:mode property of the setting + * + * Since: 1.2 + **/ +NMSettingTunMode +nm_setting_tun_get_mode(NMSettingTun *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TUN(setting), NM_SETTING_TUN_MODE_TUN); + return NM_SETTING_TUN_GET_PRIVATE(setting)->mode; +} + +/** + * nm_setting_tun_get_owner: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:owner property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_tun_get_owner(NMSettingTun *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TUN(setting), NULL); + return NM_SETTING_TUN_GET_PRIVATE(setting)->owner; +} + +/** + * nm_setting_tun_get_group: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:group property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_tun_get_group(NMSettingTun *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TUN(setting), NULL); + return NM_SETTING_TUN_GET_PRIVATE(setting)->group; +} + +/** + * nm_setting_tun_get_pi: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:pi property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_tun_get_pi(NMSettingTun *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TUN(setting), FALSE); + return NM_SETTING_TUN_GET_PRIVATE(setting)->pi; +} + +/** + * nm_setting_tun_get_vnet_hdr: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:vnet_hdr property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_tun_get_vnet_hdr(NMSettingTun *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TUN(setting), FALSE); + return NM_SETTING_TUN_GET_PRIVATE(setting)->vnet_hdr; +} + +/** + * nm_setting_tun_get_multi_queue: + * @setting: the #NMSettingTun + * + * Returns: the #NMSettingTun:multi-queue property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_tun_get_multi_queue(NMSettingTun *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_TUN(setting), FALSE); + return NM_SETTING_TUN_GET_PRIVATE(setting)->multi_queue; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingTunPrivate *priv = NM_SETTING_TUN_GET_PRIVATE(setting); + + if (!NM_IN_SET(priv->mode, NM_SETTING_TUN_MODE_TUN, NM_SETTING_TUN_MODE_TAP)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%u': invalid mode"), + (unsigned) priv->mode); + g_prefix_error(error, "%s.%s: ", NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_MODE); + return FALSE; + } + + if (priv->owner) { + if (_nm_utils_ascii_str_to_int64(priv->owner, 10, 0, G_MAXINT32, -1) == -1) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s': invalid user ID"), + priv->owner); + g_prefix_error(error, "%s.%s: ", NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_OWNER); + return FALSE; + } + } + + if (priv->group) { + if (_nm_utils_ascii_str_to_int64(priv->group, 10, 0, G_MAXINT32, -1) == -1) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s': invalid group ID"), + priv->group); + g_prefix_error(error, "%s.%s: ", NM_SETTING_TUN_SETTING_NAME, NM_SETTING_TUN_GROUP); + return FALSE; + } + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingTun * setting = NM_SETTING_TUN(object); + NMSettingTunPrivate *priv = NM_SETTING_TUN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_MODE: + g_value_set_uint(value, priv->mode); + break; + case PROP_OWNER: + g_value_set_string(value, priv->owner); + break; + case PROP_GROUP: + g_value_set_string(value, priv->group); + break; + case PROP_PI: + g_value_set_boolean(value, priv->pi); + break; + case PROP_VNET_HDR: + g_value_set_boolean(value, priv->vnet_hdr); + break; + case PROP_MULTI_QUEUE: + g_value_set_boolean(value, priv->multi_queue); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingTun * setting = NM_SETTING_TUN(object); + NMSettingTunPrivate *priv = NM_SETTING_TUN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_MODE: + priv->mode = g_value_get_uint(value); + break; + case PROP_OWNER: + g_free(priv->owner); + priv->owner = g_value_dup_string(value); + break; + case PROP_GROUP: + g_free(priv->group); + priv->group = g_value_dup_string(value); + break; + case PROP_PI: + priv->pi = g_value_get_boolean(value); + break; + case PROP_VNET_HDR: + priv->vnet_hdr = g_value_get_boolean(value); + break; + case PROP_MULTI_QUEUE: + priv->multi_queue = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} +/*****************************************************************************/ + +static void +nm_setting_tun_init(NMSettingTun *self) +{ + NMSettingTunPrivate *priv = NM_SETTING_TUN_GET_PRIVATE(self); + + priv->mode = NM_SETTING_TUN_MODE_TUN; +} + +/** + * nm_setting_tun_new: + * + * Creates a new #NMSettingTun object with default values. + * + * Returns: (transfer full): the new empty #NMSettingTun object + * + * Since: 1.2 + **/ +NMSetting * +nm_setting_tun_new(void) +{ + return g_object_new(NM_TYPE_SETTING_TUN, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingTun * setting = NM_SETTING_TUN(object); + NMSettingTunPrivate *priv = NM_SETTING_TUN_GET_PRIVATE(setting); + + g_free(priv->owner); + g_free(priv->group); + + G_OBJECT_CLASS(nm_setting_tun_parent_class)->finalize(object); +} + +static void +nm_setting_tun_class_init(NMSettingTunClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingTunPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingTun:mode: + * + * The operating mode of the virtual device. Allowed values are + * %NM_SETTING_TUN_MODE_TUN to create a layer 3 device and + * %NM_SETTING_TUN_MODE_TAP to create an Ethernet-like layer 2 + * one. + * + * Since: 1.2 + */ + obj_properties[PROP_MODE] = + g_param_spec_uint(NM_SETTING_TUN_MODE, + "", + "", + 0, + G_MAXUINT, + NM_SETTING_TUN_MODE_TUN, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingTun:owner: + * + * The user ID which will own the device. If set to %NULL everyone + * will be able to use the device. + * + * Since: 1.2 + */ + obj_properties[PROP_OWNER] = g_param_spec_string(NM_SETTING_TUN_OWNER, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingTun:group: + * + * The group ID which will own the device. If set to %NULL everyone + * will be able to use the device. + * + * Since: 1.2 + */ + obj_properties[PROP_GROUP] = g_param_spec_string(NM_SETTING_TUN_GROUP, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingTun:pi: + * + * If %TRUE the interface will prepend a 4 byte header describing the + * physical interface to the packets. + * + * Since: 1.2 + */ + obj_properties[PROP_PI] = g_param_spec_boolean(NM_SETTING_TUN_PI, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingTun:vnet-hdr: + * + * If %TRUE the IFF_VNET_HDR the tunnel packets will include a virtio + * network header. + * + * Since: 1.2 + */ + obj_properties[PROP_VNET_HDR] = g_param_spec_boolean( + NM_SETTING_TUN_VNET_HDR, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingTun:multi-queue: + * + * If the property is set to %TRUE, the interface will support + * multiple file descriptors (queues) to parallelize packet + * sending or receiving. Otherwise, the interface will only + * support a single queue. + * + * Since: 1.2 + */ + obj_properties[PROP_MULTI_QUEUE] = g_param_spec_boolean( + NM_SETTING_TUN_MULTI_QUEUE, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_TUN); +} diff --git a/src/libnm-core-impl/nm-setting-user.c b/src/libnm-core-impl/nm-setting-user.c new file mode 100644 index 0000000..0f99baa --- /dev/null +++ b/src/libnm-core-impl/nm-setting-user.c @@ -0,0 +1,594 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-user.h" + +#include "nm-setting.h" +#include "nm-setting-private.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-user + * @short_description: Describes user properties + * + * The #NMSettingUser object is a #NMSetting subclass that allow to attach + * arbitrary user data to #NMConnection objects. + **/ + +#define MAX_NUM_KEYS 256 + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingUser, PROP_DATA, ); + +typedef struct { + GHashTable * data; + GHashTable * data_invalid; + const char **keys; +} NMSettingUserPrivate; + +/** + * NMSettingUser: + * + * General User Profile Settings + */ +struct _NMSettingUser { + NMSetting parent; + NMSettingUserPrivate _priv; +}; + +struct _NMSettingUserClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingUser, nm_setting_user, NM_TYPE_SETTING) + +#define NM_SETTING_USER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMSettingUser, NM_IS_SETTING_USER) + +/*****************************************************************************/ + +static gboolean +_key_char_is_regular(char ch) +{ + /* allow words of printable characters, plus some + * special characters, for example to support base64 encoding. */ + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') + || NM_IN_SET(ch, '-', '_', '+', '/', '='); +} + +/** + * nm_setting_user_check_key: + * @key: the key to check + * @error: a #GError, %NULL to ignore. + * + * Checks whether @key is a valid user data key. This means, + * key is not %NULL, not too large and valid ASCII. Also, + * only digits and numbers are allowed with a few special + * characters. The key must contain at least one '.' and + * look like a fully qualified DNS name. + * + * Since: 1.8 + * + * Returns: %TRUE if @key is a valid user data key. + */ +gboolean +nm_setting_user_check_key(const char *key, GError **error) +{ + gsize len; + gboolean has_dot; + char ch; + + g_return_val_if_fail(!error || !*error, FALSE); + + if (!key || !key[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("missing key")); + return FALSE; + } + len = strlen(key); + if (len > 255) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("key is too long")); + return FALSE; + } + if (!g_utf8_validate(key, len, NULL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("key must be UTF8")); + return FALSE; + } + + has_dot = FALSE; + while (TRUE) { + ch = (key++)[0]; + + /* Allow something that looks like a FQN, separating namespaces by a single '.' + * We want to print the keys nicely in nmcli requiring escaping. + * + * If a user really has to encode special values in the name, he may base64 encode it. */ + + if (!_key_char_is_regular(ch)) + break; + + while (_key_char_is_regular(key[0])) + key++; + + ch = key[0]; + if (ch == '\0') { + if (!has_dot) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("key requires a '.' for a namespace")); + return FALSE; + } + return TRUE; + } + + if (ch != '.') + break; + + has_dot = TRUE; + ch = (++key)[0]; + if (ch == '.') { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("key cannot contain \"..\"")); + return FALSE; + } + } + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("key contains invalid characters")); + return FALSE; +} + +/** + * nm_setting_user_check_val: + * @val: the value to check + * @error: a #GError, %NULL to ignore. + * + * Checks whether @val is a valid user data value. This means, + * value is not %NULL, not too large and valid UTF-8. + * + * Since: 1.8 + * + * Returns: %TRUE if @val is a valid user data value. + */ +gboolean +nm_setting_user_check_val(const char *val, GError **error) +{ + gsize len; + + g_return_val_if_fail(!error || !*error, FALSE); + + if (!val) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value is missing")); + return FALSE; + } + + len = strlen(val); + if (len > 8 * 1024) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value is too large")); + return FALSE; + } + + if (!g_utf8_validate(val, len, NULL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value is not valid UTF8")); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static GHashTable * +_create_data_hash(void) +{ + return g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); +} + +/** + * nm_setting_user_get_keys: + * @setting: the #NMSettingUser + * @out_len: (out): the length of the returned array + * + * Returns: (array length=out_len) (transfer none): a + * %NULL-terminated array containing each key from the table. + **/ +const char *const * +nm_setting_user_get_keys(NMSettingUser *setting, guint *out_len) +{ + NMSettingUser * self = setting; + NMSettingUserPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_USER(self), NULL); + + priv = NM_SETTING_USER_GET_PRIVATE(self); + + if (priv->keys) { + NM_SET_OUT(out_len, g_hash_table_size(priv->data)); + return priv->keys; + } + + priv->keys = nm_utils_strdict_get_keys(priv->data, TRUE, out_len); + + /* don't return %NULL, but hijack the @keys fields as a pseudo + * empty strv array. */ + return priv->keys ?: ((const char **) &priv->keys); +} + +/*****************************************************************************/ + +/** + * nm_setting_user_get_data: + * @setting: the #NMSettingUser instance + * @key: the key to lookup + * + * Since: 1.8 + * + * Returns: (transfer none): the value associated with @key or %NULL if no such + * value exists. + */ +const char * +nm_setting_user_get_data(NMSettingUser *setting, const char *key) +{ + NMSettingUser * self = setting; + NMSettingUserPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_USER(self), NULL); + g_return_val_if_fail(key, NULL); + + priv = NM_SETTING_USER_GET_PRIVATE(self); + + if (!priv->data) + return NULL; + + return g_hash_table_lookup(priv->data, key); +} + +/** + * nm_setting_user_set_data: + * @setting: the #NMSettingUser instance + * @key: the key to set + * @val: (allow-none): the value to set or %NULL to clear a key. + * @error: (allow-none): optional error argument + * + * Since: 1.8 + * + * Returns: %TRUE if the operation was successful. The operation + * can fail if @key or @val are not valid strings according + * to nm_setting_user_check_key() and nm_setting_user_check_val(). + */ +gboolean +nm_setting_user_set_data(NMSettingUser *setting, const char *key, const char *val, GError **error) +{ + NMSettingUser * self = setting; + NMSettingUserPrivate *priv; + gboolean changed = FALSE; + + g_return_val_if_fail(NM_IS_SETTING_USER(self), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + if (!nm_setting_user_check_key(key, error)) + return FALSE; + + if (val && !nm_setting_user_check_val(val, error)) + return FALSE; + + priv = NM_SETTING_USER_GET_PRIVATE(self); + + if (!val) { + if (priv->data && g_hash_table_remove(priv->data, key)) { + nm_clear_g_free(&priv->keys); + changed = TRUE; + } + goto out; + } + + if (priv->data) { + const char *key2, *val2; + + if (g_hash_table_lookup_extended(priv->data, key, (gpointer *) &key2, (gpointer *) &val2)) { + if (nm_streq(val, val2)) + goto out; + } else { + if (g_hash_table_size(priv->data) >= MAX_NUM_KEYS) { + /* limit the number of valid keys */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("maximum number of user data entries reached")); + return FALSE; + } + + nm_clear_g_free(&priv->keys); + } + } else + priv->data = _create_data_hash(); + + g_hash_table_insert(priv->data, g_strdup(key), g_strdup(val)); + changed = TRUE; + +out: + if (priv->data_invalid) { + /* setting a value purges all invalid values that were set + * via GObject property. */ + changed = TRUE; + nm_clear_pointer(&priv->data_invalid, g_hash_table_unref); + } + if (changed) + _notify(self, PROP_DATA); + return TRUE; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingUser * self = NM_SETTING_USER(setting); + NMSettingUserPrivate *priv = NM_SETTING_USER_GET_PRIVATE(self); + + if (priv->data_invalid) { + const char * key, *val; + GHashTableIter iter; + gs_free_error GError *local = NULL; + + g_hash_table_iter_init(&iter, priv->data_invalid); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + if (!nm_setting_user_check_key(key, &local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid key \"%s\": %s"), + key, + local->message); + } else if (!nm_setting_user_check_val(val, &local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid value for \"%s\": %s"), + key, + local->message); + } else { + nm_assert_not_reached(); + continue; + } + g_prefix_error(error, "%s.%s: ", NM_SETTING_USER_SETTING_NAME, NM_SETTING_USER_DATA); + return FALSE; + } + nm_assert_not_reached(); + } + + if (priv->data && g_hash_table_size(priv->data) > MAX_NUM_KEYS) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("maximum number of user data entries reached (%u instead of %u)"), + g_hash_table_size(priv->data), + (unsigned) MAX_NUM_KEYS); + g_prefix_error(error, "%s.%s: ", NM_SETTING_USER_SETTING_NAME, NM_SETTING_USER_DATA); + return FALSE; + } + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingUserPrivate *priv, *pri2; + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_USER_DATA)) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; + + if (!set_b) + return TRUE; + + priv = NM_SETTING_USER_GET_PRIVATE(NM_SETTING_USER(set_a)); + pri2 = NM_SETTING_USER_GET_PRIVATE(NM_SETTING_USER(set_b)); + return nm_utils_hashtable_equal(priv->data, pri2->data, TRUE, g_str_equal) + && nm_utils_hashtable_equal(priv->data_invalid, + pri2->data_invalid, + TRUE, + g_str_equal); + } + + return NM_SETTING_CLASS(nm_setting_user_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingUser * self = NM_SETTING_USER(object); + NMSettingUserPrivate *priv = NM_SETTING_USER_GET_PRIVATE(self); + GHashTableIter iter; + GHashTable * data; + const char * key, *val; + + switch (prop_id) { + case PROP_DATA: + data = _create_data_hash(); + if (priv->data) { + g_hash_table_iter_init(&iter, priv->data); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) + g_hash_table_insert(data, g_strdup(key), g_strdup(val)); + } + if (priv->data_invalid) { + g_hash_table_iter_init(&iter, priv->data_invalid); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) + g_hash_table_insert(data, g_strdup(key), g_strdup(val)); + } + g_value_take_boxed(value, data); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingUser * self = NM_SETTING_USER(object); + NMSettingUserPrivate *priv = NM_SETTING_USER_GET_PRIVATE(self); + GHashTableIter iter; + GHashTable * data; + const char * key, *val; + + switch (prop_id) { + case PROP_DATA: + nm_clear_g_free(&priv->keys); + + data = g_value_get_boxed(value); + if (!data || !g_hash_table_size(data)) { + nm_clear_pointer(&priv->data, g_hash_table_unref); + nm_clear_pointer(&priv->data_invalid, g_hash_table_unref); + return; + } + + if (priv->data) + g_hash_table_remove_all(priv->data); + else + priv->data = _create_data_hash(); + + if (priv->data_invalid) + g_hash_table_remove_all(priv->data_invalid); + + g_hash_table_iter_init(&iter, data); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + if (nm_setting_user_check_key(key, NULL) && nm_setting_user_check_val(val, NULL)) + g_hash_table_insert(priv->data, g_strdup(key), g_strdup(val)); + else { + if (!priv->data_invalid) + priv->data_invalid = _create_data_hash(); + g_hash_table_insert(priv->data_invalid, g_strdup(key), g_strdup(val)); + } + } + if (priv->data_invalid && !g_hash_table_size(priv->data_invalid)) + nm_clear_pointer(&priv->data_invalid, g_hash_table_unref); + + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_user_init(NMSettingUser *self) +{} + +/** + * nm_setting_user_new: + * + * Creates a new #NMSettingUser object with default values. + * + * Returns: the new empty #NMSettingUser object + **/ +NMSetting * +nm_setting_user_new(void) +{ + return g_object_new(NM_TYPE_SETTING_USER, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingUser * self = NM_SETTING_USER(object); + NMSettingUserPrivate *priv = NM_SETTING_USER_GET_PRIVATE(self); + + g_free(priv->keys); + if (priv->data) + g_hash_table_unref(priv->data); + if (priv->data_invalid) + g_hash_table_unref(priv->data_invalid); + + G_OBJECT_CLASS(nm_setting_user_parent_class)->finalize(object); +} + +static void +nm_setting_user_class_init(NMSettingUserClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->compare_property = compare_property; + setting_class->verify = verify; + + /** + * NMSettingUser:data: (type GHashTable(utf8,utf8)) + * + * A dictionary of key/value pairs with user data. This data is ignored by NetworkManager + * and can be used at the users discretion. The keys only support a strict ascii format, + * but the values can be arbitrary UTF8 strings up to a certain length. + * + * Since: 1.8 + **/ + /* ---ifcfg-rh--- + * property: data + * variable: NM_USER_* + * description: each key/value pair is stored as a separate variable with + * name composed by concatenating NM_USER_ with the encoded key. The key is + * encoded by substituting lowercase letters with uppercase and prepending + * uppercase letters with an underscore. A dot is encoded as a double + * underscore. Remaining characters are encoded as underscore followed by a + * 3 digit octal representation of the character. + * example: NM_USER_FOO__BAR=something + * ---end--- + */ + obj_properties[PROP_DATA] = g_param_spec_boxed(NM_SETTING_USER_DATA, + "", + "", + G_TYPE_HASH_TABLE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_DATA], + &nm_sett_info_propert_type_strdict); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_USER, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-veth.c b/src/libnm-core-impl/nm-setting-veth.c new file mode 100644 index 0000000..70cfe50 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-veth.c @@ -0,0 +1,194 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-veth.h" + +#include + +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-veth + * @short_description: Describes connection properties for veth interfaces + * + * The #NMSettingVeth object is a #NMSetting subclass that describes properties + * necessary for connection to veth interfaces. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PEER, ); + +typedef struct { + char *peer; +} NMSettingVethPrivate; + +/** + * NMSettingVeth: + * + * Veth Settings + */ +struct _NMSettingVeth { + NMSetting parent; + NMSettingVethPrivate _priv; +}; + +struct _NMSettingVethClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingVeth, nm_setting_veth, NM_TYPE_SETTING) + +#define NM_SETTING_VETH_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSettingVeth, NM_IS_SETTING_VETH, NMSetting) + +/*****************************************************************************/ + +/** + * nm_setting_veth_get_peer: + * @setting: the #NMSettingVeth + * + * Returns: the #NMSettingVeth:peer property of the setting + * + * Since: 1.30 + **/ +const char * +nm_setting_veth_get_peer(NMSettingVeth *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VETH(setting), NULL); + return NM_SETTING_VETH_GET_PRIVATE(setting)->peer; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVethPrivate *priv = NM_SETTING_VETH_GET_PRIVATE(setting); + + if (!priv->peer) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VETH_SETTING_NAME, NM_SETTING_VETH_PEER); + return FALSE; + } + + if (!nm_utils_ifname_valid(priv->peer, NMU_IFACE_KERNEL, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid interface name"), + priv->peer); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VETH_SETTING_NAME, NM_SETTING_VETH_PEER); + return FALSE; + } + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingVeth * setting = NM_SETTING_VETH(object); + NMSettingVethPrivate *priv = NM_SETTING_VETH_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PEER: + g_value_set_string(value, priv->peer); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingVeth * setting = NM_SETTING_VETH(object); + NMSettingVethPrivate *priv = NM_SETTING_VETH_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PEER: + g_free(priv->peer); + priv->peer = g_value_dup_string(value); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_veth_init(NMSettingVeth *setting) +{} + +/** + * nm_setting_veth_new: + * + * Creates a new #NMSettingVeth object with default values. + * + * Returns: (transfer full): the new empty #NMSettingVeth object + * + * Since: 1.30 + **/ +NMSetting * +nm_setting_veth_new(void) +{ + return g_object_new(NM_TYPE_SETTING_VETH, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingVeth * setting = NM_SETTING_VETH(object); + NMSettingVethPrivate *priv = NM_SETTING_VETH_GET_PRIVATE(setting); + + g_free(priv->peer); + + G_OBJECT_CLASS(nm_setting_veth_parent_class)->finalize(object); +} + +static void +nm_setting_veth_class_init(NMSettingVethClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingVethPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingVeth:peer: + * + * This property specifies the peer interface name of the veth. This + * property is mandatory. + * + * Since: 1.30 + **/ + obj_properties[PROP_PEER] = g_param_spec_string(NM_SETTING_VETH_PEER, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_VETH); +} diff --git a/src/libnm-core-impl/nm-setting-vlan.c b/src/libnm-core-impl/nm-setting-vlan.c new file mode 100644 index 0000000..0d28555 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-vlan.c @@ -0,0 +1,982 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2014 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-vlan.h" + +#include + +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-setting-wired.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-vlan + * @short_description: Describes connection properties for VLAN interfaces + * + * The #NMSettingVlan object is a #NMSetting subclass that describes properties + * necessary for connection to VLAN interfaces. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingVlan, + PROP_PARENT, + PROP_ID, + PROP_FLAGS, + PROP_INGRESS_PRIORITY_MAP, + PROP_EGRESS_PRIORITY_MAP, ); + +typedef struct { + GSList *ingress_priority_map; + GSList *egress_priority_map; + char * parent; + guint32 id; + guint32 flags; +} NMSettingVlanPrivate; + +G_DEFINE_TYPE(NMSettingVlan, nm_setting_vlan, NM_TYPE_SETTING) + +#define NM_SETTING_VLAN_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_VLAN, NMSettingVlanPrivate)) + +/*****************************************************************************/ + +#define MAX_SKB_PRIO G_MAXUINT32 +#define MAX_8021P_PRIO 7 /* Max 802.1p priority */ + +/** + * nm_setting_vlan_get_parent: + * @setting: the #NMSettingVlan + * + * Returns: the #NMSettingVlan:parent property of the setting + **/ +const char * +nm_setting_vlan_get_parent(NMSettingVlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VLAN(setting), NULL); + return NM_SETTING_VLAN_GET_PRIVATE(setting)->parent; +} + +/** + * nm_setting_vlan_get_id: + * @setting: the #NMSettingVlan + * + * Returns: the #NMSettingVlan:id property of the setting + **/ +guint32 +nm_setting_vlan_get_id(NMSettingVlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VLAN(setting), 0); + return NM_SETTING_VLAN_GET_PRIVATE(setting)->id; +} + +/** + * nm_setting_vlan_get_flags: + * @setting: the #NMSettingVlan + * + * Returns: the #NMSettingVlan:flags property of the setting + **/ +guint32 +nm_setting_vlan_get_flags(NMSettingVlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VLAN(setting), 0); + return NM_SETTING_VLAN_GET_PRIVATE(setting)->flags; +} + +static NMVlanQosMapping * +priority_map_new(guint32 from, guint32 to) +{ + NMVlanQosMapping *mapping; + + mapping = g_new(NMVlanQosMapping, 1); + *mapping = (NMVlanQosMapping){ + .from = from, + .to = to, + }; + return mapping; +} + +static NMVlanQosMapping * +priority_map_new_from_str(NMVlanPriorityMap map, const char *str) +{ + guint32 from, to; + + if (!nm_utils_vlan_priority_map_parse_str(map, str, FALSE, &from, &to, NULL)) + return NULL; + return priority_map_new(from, to); +} + +static void +priority_map_free(NMVlanQosMapping *map) +{ + nm_assert(map); + g_free(map); +} + +static GSList * +get_map(NMSettingVlan *self, NMVlanPriorityMap map) +{ + if (map == NM_VLAN_INGRESS_MAP) + return NM_SETTING_VLAN_GET_PRIVATE(self)->ingress_priority_map; + else if (map == NM_VLAN_EGRESS_MAP) + return NM_SETTING_VLAN_GET_PRIVATE(self)->egress_priority_map; + nm_assert_not_reached(); + return NULL; +} + +static int +prio_map_compare(gconstpointer p_a, gconstpointer p_b) +{ + const NMVlanQosMapping *a = p_a; + const NMVlanQosMapping *b = p_b; + + return a->from < b->from + ? -1 + : (a->from > b->from ? 1 : (a->to < b->to ? -1 : (a->to > b->to ? 1 : 0))); +} + +static void +set_map(NMSettingVlan *self, NMVlanPriorityMap map, GSList *list) +{ + /* Assert that the list is sorted */ +#if NM_MORE_ASSERTS >= 2 + { + GSList *iter, *last; + + last = list; + iter = list ? list->next : NULL; + while (iter) { + const NMVlanQosMapping *l = last->data; + const NMVlanQosMapping *m = iter->data; + + nm_assert(prio_map_compare(last->data, iter->data) < 0); + + /* Also reject duplicates (based on "from") */ + nm_assert(l->from < m->from); + + last = iter; + iter = iter->next; + } + } +#endif + + if (map == NM_VLAN_INGRESS_MAP) { + NM_SETTING_VLAN_GET_PRIVATE(self)->ingress_priority_map = list; + _notify(self, PROP_INGRESS_PRIORITY_MAP); + } else if (map == NM_VLAN_EGRESS_MAP) { + NM_SETTING_VLAN_GET_PRIVATE(self)->egress_priority_map = list; + _notify(self, PROP_EGRESS_PRIORITY_MAP); + } else + nm_assert_not_reached(); +} + +static gboolean +check_replace_duplicate_priority(GSList *list, guint32 from, guint32 to) +{ + GSList * iter; + NMVlanQosMapping *p; + + for (iter = list; iter; iter = g_slist_next(iter)) { + p = iter->data; + if (p->from == from) { + p->to = to; + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_vlan_add_priority_str: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @str: the string which contains a priority map, like "3:7" + * + * Adds a priority map entry into either the #NMSettingVlan:ingress_priority_map + * or the #NMSettingVlan:egress_priority_map properties. The priority map maps + * the Linux SKB priorities to 802.1p priorities. + * + * Returns: %TRUE if the entry was successfully added to the list, or it + * overwrote the old value, %FALSE if @str is not a valid mapping. + */ +gboolean +nm_setting_vlan_add_priority_str(NMSettingVlan *setting, NMVlanPriorityMap map, const char *str) +{ + GSList * list = NULL; + NMVlanQosMapping *item = NULL; + + g_return_val_if_fail(NM_IS_SETTING_VLAN(setting), FALSE); + g_return_val_if_fail(map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + g_return_val_if_fail(str && str[0], FALSE); + + item = priority_map_new_from_str(map, str); + if (!item) + return FALSE; + + list = get_map(setting, map); + + /* Duplicates get replaced */ + if (check_replace_duplicate_priority(list, item->from, item->to)) { + g_free(item); + if (map == NM_VLAN_INGRESS_MAP) + _notify(setting, PROP_INGRESS_PRIORITY_MAP); + else + _notify(setting, PROP_EGRESS_PRIORITY_MAP); + return TRUE; + } + + set_map(setting, map, g_slist_insert_sorted(list, item, prio_map_compare)); + return TRUE; +} + +/** + * nm_setting_vlan_get_num_priorities: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * + * Returns the number of entries in the + * #NMSettingVlan:ingress_priority_map or #NMSettingVlan:egress_priority_map + * properties of this setting. + * + * Returns: return the number of ingress/egress priority entries. + **/ +gint32 +nm_setting_vlan_get_num_priorities(NMSettingVlan *setting, NMVlanPriorityMap map) +{ + g_return_val_if_fail(NM_IS_SETTING_VLAN(setting), -1); + g_return_val_if_fail(map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, -1); + + return g_slist_length(get_map(setting, map)); +} + +/** + * nm_setting_vlan_get_priority: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @idx: the zero-based index of the ingress/egress priority map entry + * @out_from: (out) (allow-none): on return the value of the priority map's 'from' item + * @out_to: (out) (allow-none): on return the value of priority map's 'to' item + * + * Retrieve one of the entries of the #NMSettingVlan:ingress_priority_map + * or #NMSettingVlan:egress_priority_map properties of this setting. + * + * Returns: returns %TRUE if @idx is in range. Otherwise, %FALSE. + **/ +gboolean +nm_setting_vlan_get_priority(NMSettingVlan * setting, + NMVlanPriorityMap map, + guint32 idx, + guint32 * out_from, + guint32 * out_to) +{ + NMVlanQosMapping *item; + GSList * list; + + g_return_val_if_fail(NM_IS_SETTING_VLAN(setting), FALSE); + g_return_val_if_fail(NM_IN_SET(map, NM_VLAN_INGRESS_MAP, NM_VLAN_EGRESS_MAP), FALSE); + + list = get_map(setting, map); + item = g_slist_nth_data(list, idx); + + if (!item) { + NM_SET_OUT(out_from, 0); + NM_SET_OUT(out_to, 0); + return FALSE; + } + + NM_SET_OUT(out_from, item->from); + NM_SET_OUT(out_to, item->to); + return TRUE; +} + +/** + * nm_setting_vlan_add_priority: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @from: the priority to map to @to + * @to: the priority to map @from to + * + * Adds a priority mapping to the #NMSettingVlan:ingress_priority_map or + * #NMSettingVlan:egress_priority_map properties of the setting. If @from is + * already in the given priority map, this function will overwrite the + * existing entry with the new @to. + * + * If @map is #NM_VLAN_INGRESS_MAP then @from is the incoming 802.1q VLAN + * Priority Code Point (PCP) value, and @to is the Linux SKB priority value. + * + * If @map is #NM_VLAN_EGRESS_MAP then @from is the Linux SKB priority value and + * @to is the outgoing 802.1q VLAN Priority Code Point (PCP) value. + * + * Returns: %TRUE. + */ +gboolean +nm_setting_vlan_add_priority(NMSettingVlan * setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to) +{ + GSList * list = NULL; + NMVlanQosMapping *item; + + g_return_val_if_fail(NM_IS_SETTING_VLAN(setting), FALSE); + g_return_val_if_fail(map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + + list = get_map(setting, map); + if (check_replace_duplicate_priority(list, from, to)) { + if (map == NM_VLAN_INGRESS_MAP) + _notify(setting, PROP_INGRESS_PRIORITY_MAP); + else + _notify(setting, PROP_EGRESS_PRIORITY_MAP); + return TRUE; + } + + item = g_malloc0(sizeof(NMVlanQosMapping)); + item->from = from; + item->to = to; + set_map(setting, map, g_slist_insert_sorted(list, item, prio_map_compare)); + + return TRUE; +} + +gboolean +_nm_setting_vlan_set_priorities(NMSettingVlan * setting, + NMVlanPriorityMap map, + const NMVlanQosMapping *qos_map, + guint n_qos_map) +{ + gboolean has_changes = FALSE; + GSList * map_prev, *map_new; + guint i; + gint64 from_last; + + map_prev = get_map(setting, map); + + if (n_qos_map != g_slist_length(map_prev)) + has_changes = TRUE; + else { + const GSList *iter; + + iter = map_prev; + for (i = 0; i < n_qos_map; i++, iter = iter->next) { + const NMVlanQosMapping *m = iter->data; + + if (m->from != qos_map[i].from || m->to != qos_map[i].to) { + has_changes = TRUE; + break; + } + } + } + + if (!has_changes) + return FALSE; + + map_new = NULL; + from_last = G_MAXINT64; + for (i = n_qos_map; i > 0;) { + const NMVlanQosMapping *m = &qos_map[--i]; + NMVlanQosMapping * item; + + /* We require the array to be presorted. */ + if (m->from >= from_last) + g_return_val_if_reached(FALSE); + from_last = m->from; + + item = g_malloc0(sizeof(NMVlanQosMapping)); + item->from = m->from; + item->to = m->to; + map_new = g_slist_prepend(map_new, item); + } + + g_slist_free_full(map_prev, g_free); + set_map(setting, map, map_new); + + return TRUE; +} + +void +_nm_setting_vlan_get_priorities(NMSettingVlan * setting, + NMVlanPriorityMap map, + NMVlanQosMapping **out_qos_map, + guint * out_n_qos_map) +{ + GSList * list; + NMVlanQosMapping *qos_map = NULL; + guint n_qos_map, i; + + list = get_map(setting, map); + + n_qos_map = g_slist_length(list); + + if (n_qos_map > 0) { + qos_map = g_new(NMVlanQosMapping, n_qos_map); + + for (i = 0; list; i++, list = list->next) { + nm_assert(i < n_qos_map); + qos_map[i] = *((const NMVlanQosMapping *) list->data); + } + } + *out_qos_map = qos_map; + *out_n_qos_map = n_qos_map; +} + +/** + * nm_setting_vlan_remove_priority: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @idx: the zero-based index of the priority map to remove + * + * Removes the priority map at index @idx from the + * #NMSettingVlan:ingress_priority_map or #NMSettingVlan:egress_priority_map + * properties. + */ +void +nm_setting_vlan_remove_priority(NMSettingVlan *setting, NMVlanPriorityMap map, guint32 idx) +{ + GSList *list = NULL, *item = NULL; + + g_return_if_fail(NM_IS_SETTING_VLAN(setting)); + g_return_if_fail(map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP); + + list = get_map(setting, map); + g_return_if_fail(idx < g_slist_length(list)); + + item = g_slist_nth(list, idx); + priority_map_free((NMVlanQosMapping *) (item->data)); + set_map(setting, map, g_slist_delete_link(list, item)); +} + +static gboolean +priority_map_remove_by_value(NMSettingVlan * setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to, + gboolean wildcard_to) +{ + GSList * list = NULL, *iter = NULL; + NMVlanQosMapping *item; + + nm_assert(NM_IS_SETTING_VLAN(setting)); + nm_assert(NM_IN_SET(map, NM_VLAN_INGRESS_MAP, NM_VLAN_EGRESS_MAP)); + + list = get_map(setting, map); + for (iter = list; iter; iter = g_slist_next(iter)) { + item = iter->data; + + if (item->from != from) + continue; + if (!wildcard_to && item->to != to) + continue; + + priority_map_free((NMVlanQosMapping *) (iter->data)); + set_map(setting, map, g_slist_delete_link(list, iter)); + return TRUE; + } + return FALSE; +} + +/** + * nm_setting_vlan_remove_priority_by_value: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @from: the priority to map to @to + * @to: the priority to map @from to + * + * Removes the priority map @form:@to from the #NMSettingVlan:ingress_priority_map + * or #NMSettingVlan:egress_priority_map (according to @map argument) + * properties. + * + * Returns: %TRUE if the priority mapping was found and removed; %FALSE if it was not. + */ +gboolean +nm_setting_vlan_remove_priority_by_value(NMSettingVlan * setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to) +{ + g_return_val_if_fail(NM_IS_SETTING_VLAN(setting), FALSE); + g_return_val_if_fail(map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + + return priority_map_remove_by_value(setting, map, from, to, FALSE); +} + +/** + * nm_setting_vlan_remove_priority_str_by_value: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @str: the string which contains a priority map, like "3:7" + * + * Removes the priority map @str from the #NMSettingVlan:ingress_priority_map + * or #NMSettingVlan:egress_priority_map (according to @map argument) + * properties. + * + * Returns: %TRUE if the priority mapping was found and removed; %FALSE if it was not. + */ +gboolean +nm_setting_vlan_remove_priority_str_by_value(NMSettingVlan * setting, + NMVlanPriorityMap map, + const char * str) +{ + gboolean is_wildcard_to; + guint32 from, to; + + g_return_val_if_fail(NM_IS_SETTING_VLAN(setting), FALSE); + g_return_val_if_fail(map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + + if (!nm_utils_vlan_priority_map_parse_str(map, str, TRUE, &from, &to, &is_wildcard_to)) + return FALSE; + return priority_map_remove_by_value(setting, map, from, to, is_wildcard_to); +} + +/** + * nm_setting_vlan_clear_priorities: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * + * Clear all the entries from #NMSettingVlan:ingress_priority_map or + * #NMSettingVlan:egress_priority_map properties. + */ +void +nm_setting_vlan_clear_priorities(NMSettingVlan *setting, NMVlanPriorityMap map) +{ + GSList *list = NULL; + + g_return_if_fail(NM_IS_SETTING_VLAN(setting)); + g_return_if_fail(map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP); + + list = get_map(setting, map); + g_slist_free_full(list, g_free); + set_map(setting, map, NULL); +} + +/*****************************************************************************/ + +static int +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE(setting); + NMSettingConnection * s_con; + NMSettingWired * s_wired; + + if (connection) { + s_con = nm_connection_get_setting_connection(connection); + s_wired = nm_connection_get_setting_wired(connection); + } else { + s_con = NULL; + s_wired = NULL; + } + + if (priv->parent) { + if (nm_utils_is_uuid(priv->parent)) { + /* If we have an NMSettingConnection:master with slave-type="vlan", + * then it must be the same UUID. + */ + if (s_con) { + const char *master = NULL, *slave_type = NULL; + + slave_type = nm_setting_connection_get_slave_type(s_con); + if (!g_strcmp0(slave_type, NM_SETTING_VLAN_SETTING_NAME)) + master = nm_setting_connection_get_master(s_con); + + if (master && g_strcmp0(priv->parent, master) != 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' value doesn't match '%s=%s'"), + priv->parent, + NM_SETTING_CONNECTION_MASTER, + master); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_VLAN_SETTING_NAME, + NM_SETTING_VLAN_PARENT); + return FALSE; + } + } + } else if (!nm_utils_ifname_valid_kernel(priv->parent, NULL)) { + /* parent must be either a UUID or an interface name */ + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT); + return FALSE; + } + } else { + /* If parent is NULL, the parent must be specified via + * NMSettingWired:mac-address. + */ + if (connection && (!s_wired || !nm_setting_wired_get_mac_address(s_wired))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified and neither is '%s:%s'"), + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT); + return FALSE; + } + } + + if (priv->id >= 4095) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the vlan id must be in range 0-4094 but is %u"), + priv->id); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_ID); + return FALSE; + } + + if (priv->flags & ~NM_VLAN_FLAGS_ALL) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("flags are invalid")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_FLAGS); + return FALSE; + } + + if (connection && !s_wired) { + /* technically, a VLAN setting does not require an ethernet setting. However, + * the ifcfg-rh reader always adds a ethernet setting when reading a vlan setting. + * Thus, in order to be consistent, always add one via normalization. */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + _("vlan setting should have a ethernet setting as well")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_FLAGS); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + + return TRUE; +} + +static GVariant * +_override_flags_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + return g_variant_new_uint32(nm_setting_vlan_get_flags((NMSettingVlan *) setting)); +} + +static gboolean +_override_flags_not_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + NMSettingParseFlags parse_flags, + GError ** error) +{ + /* we changed the default value for FLAGS. When an older client + * doesn't serialize the property, we assume it is the old default. */ + g_object_set(G_OBJECT(setting), NM_SETTING_VLAN_FLAGS, (NMVlanFlags) 0, NULL); + return TRUE; +} + +static GSList * +priority_strv_to_maplist(NMVlanPriorityMap map, char **strv) +{ + GSList *list = NULL; + gsize i; + + for (i = 0; strv && strv[i]; i++) { + guint32 from, to; + + if (!nm_utils_vlan_priority_map_parse_str(map, strv[i], FALSE, &from, &to, NULL)) + continue; + if (check_replace_duplicate_priority(list, from, to)) + continue; + list = g_slist_prepend(list, priority_map_new(from, to)); + } + return g_slist_sort(list, prio_map_compare); +} + +static char ** +priority_maplist_to_strv(GSList *list) +{ + GSList * iter; + GPtrArray *strv; + + strv = g_ptr_array_new(); + + for (iter = list; iter; iter = g_slist_next(iter)) { + NMVlanQosMapping *item = iter->data; + + g_ptr_array_add(strv, g_strdup_printf("%d:%d", item->from, item->to)); + } + g_ptr_array_add(strv, NULL); + + return (char **) g_ptr_array_free(strv, FALSE); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingVlan * setting = NM_SETTING_VLAN(object); + NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string(value, priv->parent); + break; + case PROP_ID: + g_value_set_uint(value, priv->id); + break; + case PROP_FLAGS: + g_value_set_flags(value, priv->flags); + break; + case PROP_INGRESS_PRIORITY_MAP: + g_value_take_boxed(value, priority_maplist_to_strv(priv->ingress_priority_map)); + break; + case PROP_EGRESS_PRIORITY_MAP: + g_value_take_boxed(value, priority_maplist_to_strv(priv->egress_priority_map)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingVlan * setting = NM_SETTING_VLAN(object); + NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_free(priv->parent); + priv->parent = g_value_dup_string(value); + break; + case PROP_ID: + priv->id = g_value_get_uint(value); + break; + case PROP_FLAGS: + priv->flags = g_value_get_flags(value); + break; + case PROP_INGRESS_PRIORITY_MAP: + g_slist_free_full(priv->ingress_priority_map, g_free); + priv->ingress_priority_map = + priority_strv_to_maplist(NM_VLAN_INGRESS_MAP, g_value_get_boxed(value)); + break; + case PROP_EGRESS_PRIORITY_MAP: + g_slist_free_full(priv->egress_priority_map, g_free); + priv->egress_priority_map = + priority_strv_to_maplist(NM_VLAN_EGRESS_MAP, g_value_get_boxed(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_vlan_init(NMSettingVlan *self) +{ + NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE(self); + + priv->flags = NM_VLAN_FLAG_REORDER_HEADERS; +} + +/** + * nm_setting_vlan_new: + * + * Creates a new #NMSettingVlan object with default values. + * + * Returns: (transfer full): the new empty #NMSettingVlan object + **/ +NMSetting * +nm_setting_vlan_new(void) +{ + return g_object_new(NM_TYPE_SETTING_VLAN, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingVlan * setting = NM_SETTING_VLAN(object); + NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE(setting); + + g_free(priv->parent); + g_slist_free_full(priv->ingress_priority_map, g_free); + g_slist_free_full(priv->egress_priority_map, g_free); + + G_OBJECT_CLASS(nm_setting_vlan_parent_class)->finalize(object); +} + +static void +nm_setting_vlan_class_init(NMSettingVlanClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingVlanPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingVlan:parent: + * + * If given, specifies the parent interface name or parent connection UUID + * from which this VLAN interface should be created. If this property is + * not specified, the connection must contain an #NMSettingWired setting + * with a #NMSettingWired:mac-address property. + **/ + /* ---ifcfg-rh--- + * property: parent + * variable: DEVICE or PHYSDEV + * description: Parent interface of the VLAN. + * ---end--- + */ + obj_properties[PROP_PARENT] = g_param_spec_string( + NM_SETTING_VLAN_PARENT, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVlan:id: + * + * The VLAN identifier that the interface created by this connection should + * be assigned. The valid range is from 0 to 4094, without the reserved id 4095. + **/ + /* ---ifcfg-rh--- + * property: id + * variable: VLAN_ID or DEVICE + * description: VLAN identifier. + * ---end--- + */ + obj_properties[PROP_ID] = + g_param_spec_uint(NM_SETTING_VLAN_ID, + "", + "", + 0, + 4095, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVlan:flags: + * + * One or more flags which control the behavior and features of the VLAN + * interface. Flags include %NM_VLAN_FLAG_REORDER_HEADERS (reordering of + * output packet headers), %NM_VLAN_FLAG_GVRP (use of the GVRP protocol), + * and %NM_VLAN_FLAG_LOOSE_BINDING (loose binding of the interface to its + * master device's operating state). %NM_VLAN_FLAG_MVRP (use of the MVRP + * protocol). + * + * The default value of this property is NM_VLAN_FLAG_REORDER_HEADERS, + * but it used to be 0. To preserve backward compatibility, the default-value + * in the D-Bus API continues to be 0 and a missing property on D-Bus + * is still considered as 0. + **/ + /* ---ifcfg-rh--- + * property: flags + * variable: GVRP, MVRP, VLAN_FLAGS + * values: "yes or "no" for GVRP and MVRP; "LOOSE_BINDING" and "NO_REORDER_HDR" for VLAN_FLAGS + * description: VLAN flags. + * ---end--- + */ + obj_properties[PROP_FLAGS] = g_param_spec_flags(NM_SETTING_VLAN_FLAGS, + "", + "", + NM_TYPE_VLAN_FLAGS, + NM_VLAN_FLAG_REORDER_HEADERS, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_FLAGS], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_UINT32, + .to_dbus_fcn = _override_flags_get, + .missing_from_dbus_fcn = _override_flags_not_set, )); + + /** + * NMSettingVlan:ingress-priority-map: + * + * For incoming packets, a list of mappings from 802.1p priorities to Linux + * SKB priorities. The mapping is given in the format "from:to" where both + * "from" and "to" are unsigned integers, ie "7:3". + **/ + /* ---ifcfg-rh--- + * property: ingress-priority-map + * variable: VLAN_INGRESS_PRIORITY_MAP + * description: Ingress priority mapping. + * example: VLAN_INGRESS_PRIORITY_MAP=4:2,3:5 + * ---end--- + */ + obj_properties[PROP_INGRESS_PRIORITY_MAP] = g_param_spec_boxed( + NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVlan:egress-priority-map: + * + * For outgoing packets, a list of mappings from Linux SKB priorities to + * 802.1p priorities. The mapping is given in the format "from:to" where + * both "from" and "to" are unsigned integers, ie "7:3". + **/ + /* ---ifcfg-rh--- + * property: egress-priority-map + * variable: VLAN_EGRESS_PRIORITY_MAP + * description: Egress priority mapping. + * example: VLAN_EGRESS_PRIORITY_MAP=5:4,4:1,3:7 + * ---end--- + */ + obj_properties[PROP_EGRESS_PRIORITY_MAP] = g_param_spec_boxed( + NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /* ---ifcfg-rh--- + * property: interface-name + * variable: PHYSDEV and VLAN_ID, or DEVICE + * description: VLAN interface name. + * If all variables are set, parent device from PHYSDEV takes precedence over DEVICE, + * but VLAN id from DEVICE takes precedence over VLAN_ID. + * example: PHYSDEV=eth0, VLAN_ID=12; or DEVICE=eth0.12 + * ---end--- + * ---dbus--- + * property: interface-name + * format: string + * description: Deprecated in favor of connection.interface-name, but can + * be used for backward-compatibility with older daemons, to set the + * vlan's interface name. + * ---end--- + */ + _nm_properties_override_dbus(properties_override, + "interface-name", + &nm_sett_info_propert_type_deprecated_interface_name); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_VLAN, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-vpn.c b/src/libnm-core-impl/nm-setting-vpn.c new file mode 100644 index 0000000..ce6e73f --- /dev/null +++ b/src/libnm-core-impl/nm-setting-vpn.c @@ -0,0 +1,1233 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-vpn.h" + +#include + +#include "libnm-glib-aux/nm-secret-utils.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-vpn + * @short_description: Describes connection properties for Virtual Private Networks + * + * The #NMSettingVpn object is a #NMSetting subclass that describes properties + * necessary for connection to Virtual Private Networks. NetworkManager uses + * a plugin architecture to allow easier use of new VPN types, and this + * setting abstracts the configuration for those plugins. Since the configuration + * options are only known to the VPN plugins themselves, the VPN configuration + * options are stored as key/value pairs of strings rather than GObject + * properties. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingVpn, + PROP_SERVICE_TYPE, + PROP_USER_NAME, + PROP_PERSISTENT, + PROP_DATA, + PROP_SECRETS, + PROP_TIMEOUT, ); + +typedef struct { + char *service_type; + + /* username of the user requesting this connection, thus + * it's really only valid for user connections, and it also + * should never be saved out to persistent config. + */ + char *user_name; + + /* Whether the VPN stays up across link changes, until the user + * explicitly disconnects it. + */ + gboolean persistent; + + /* The hash table is created at setting object + * init time and should not be replaced. It is + * a char * -> char * mapping, and both the key + * and value are owned by the hash table, and should + * be allocated with functions whose value can be + * freed with g_free(). Should not contain secrets. + */ + GHashTable *data; + + /* The hash table is created at setting object + * init time and should not be replaced. It is + * a char * -> char * mapping, and both the key + * and value are owned by the hash table, and should + * be allocated with functions whose value can be + * freed with g_free(). Should contain secrets only. + */ + GHashTable *secrets; + + /* Timeout for the VPN service to establish the connection */ + guint32 timeout; +} NMSettingVpnPrivate; + +G_DEFINE_TYPE(NMSettingVpn, nm_setting_vpn, NM_TYPE_SETTING) + +#define NM_SETTING_VPN_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_VPN, NMSettingVpnPrivate)) + +/*****************************************************************************/ + +static GHashTable * +_ensure_strdict(GHashTable **p_hash, gboolean for_secrets) +{ + if (!*p_hash) { + *p_hash = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + for_secrets ? (GDestroyNotify) nm_free_secret : g_free); + } + return *p_hash; +} + +/*****************************************************************************/ + +/** + * nm_setting_vpn_get_service_type: + * @setting: the #NMSettingVpn + * + * Returns the service name of the VPN, which identifies the specific VPN + * plugin that should be used to connect to this VPN. + * + * Returns: the VPN plugin's service name + **/ +const char * +nm_setting_vpn_get_service_type(NMSettingVpn *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), NULL); + + return NM_SETTING_VPN_GET_PRIVATE(setting)->service_type; +} + +/** + * nm_setting_vpn_get_user_name: + * @setting: the #NMSettingVpn + * + * Returns: the #NMSettingVpn:user-name property of the setting + **/ +const char * +nm_setting_vpn_get_user_name(NMSettingVpn *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), NULL); + + return NM_SETTING_VPN_GET_PRIVATE(setting)->user_name; +} + +/** + * nm_setting_vpn_get_persistent: + * @setting: the #NMSettingVpn + * + * Returns: the #NMSettingVpn:persistent property of the setting + **/ +gboolean +nm_setting_vpn_get_persistent(NMSettingVpn *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), FALSE); + + return NM_SETTING_VPN_GET_PRIVATE(setting)->persistent; +} + +/** + * nm_setting_vpn_get_num_data_items: + * @setting: the #NMSettingVpn + * + * Gets number of key/value pairs of VPN configuration data. + * + * Returns: the number of VPN plugin specific configuration data items + **/ +guint32 +nm_setting_vpn_get_num_data_items(NMSettingVpn *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), 0); + + return nm_g_hash_table_size(NM_SETTING_VPN_GET_PRIVATE(setting)->data); +} + +/** + * nm_setting_vpn_add_data_item: + * @setting: the #NMSettingVpn + * @key: a name that uniquely identifies the given value @item + * @item: (allow-none): the value to be referenced by @key + * + * Establishes a relationship between @key and @item internally in the + * setting which may be retrieved later. Should not be used to store passwords + * or other secrets, which is what nm_setting_vpn_add_secret() is for. + * + * Before 1.24, @item must not be %NULL and not an empty string. Since 1.24, + * @item can be set to an empty string. It can also be set to %NULL to unset + * the key. In that case, the behavior is as if calling nm_setting_vpn_remove_data_item(). + **/ +void +nm_setting_vpn_add_data_item(NMSettingVpn *setting, const char *key, const char *item) +{ + if (!item) { + nm_setting_vpn_remove_data_item(setting, key); + return; + } + + g_return_if_fail(NM_IS_SETTING_VPN(setting)); + g_return_if_fail(key && key[0]); + + g_hash_table_insert(_ensure_strdict(&NM_SETTING_VPN_GET_PRIVATE(setting)->data, FALSE), + g_strdup(key), + g_strdup(item)); + _notify(setting, PROP_DATA); +} + +/** + * nm_setting_vpn_get_data_item: + * @setting: the #NMSettingVpn + * @key: the name of the data item to retrieve + * + * Retrieves the data item of a key/value relationship previously established + * by nm_setting_vpn_add_data_item(). + * + * Returns: the data item, if any + **/ +const char * +nm_setting_vpn_get_data_item(NMSettingVpn *setting, const char *key) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), NULL); + g_return_val_if_fail(key && key[0], NULL); + + return nm_g_hash_table_lookup(NM_SETTING_VPN_GET_PRIVATE(setting)->data, key); +} + +/** + * nm_setting_vpn_get_data_keys: + * @setting: the #NMSettingVpn + * @out_length: (allow-none) (out): the length of the returned array + * + * Retrieves every data key inside @setting, as an array. + * + * Returns: (array length=out_length) (transfer container): a + * %NULL-terminated array containing each data key or %NULL if + * there are no data items. + * + * Since: 1.12 + */ +const char ** +nm_setting_vpn_get_data_keys(NMSettingVpn *setting, guint *out_length) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), NULL); + + return nm_utils_strdict_get_keys(NM_SETTING_VPN_GET_PRIVATE(setting)->data, TRUE, out_length); +} + +/** + * nm_setting_vpn_remove_data_item: + * @setting: the #NMSettingVpn + * @key: the name of the data item to remove + * + * Deletes a key/value relationship previously established by + * nm_setting_vpn_add_data_item(). + * + * Returns: %TRUE if the data item was found and removed from the internal list, + * %FALSE if it was not. + **/ +gboolean +nm_setting_vpn_remove_data_item(NMSettingVpn *setting, const char *key) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), FALSE); + g_return_val_if_fail(key && key[0], FALSE); + + if (nm_g_hash_table_remove(NM_SETTING_VPN_GET_PRIVATE(setting)->data, key)) { + _notify(setting, PROP_DATA); + return TRUE; + } + return FALSE; +} + +static void +foreach_item_helper(NMSettingVpn *self, GHashTable **p_hash, NMVpnIterFunc func, gpointer user_data) +{ + gs_unref_object NMSettingVpn *self_keep_alive = NULL; + gs_strfreev char ** keys = NULL; + guint i, len; + + nm_assert(NM_IS_SETTING_VPN(self)); + nm_assert(func); + + keys = nm_utils_strv_make_deep_copied(nm_utils_strdict_get_keys(*p_hash, TRUE, &len)); + if (len == 0u) { + nm_assert(!keys); + return; + } + + if (len > 1u) + self_keep_alive = g_object_ref(self); + + for (i = 0; i < len; i++) { + /* NOTE: note that we call the function with a clone of @key, + * not with the actual key from the dictionary. + * + * The @value on the other hand, is not cloned but retrieved before + * invoking @func(). That means, if @func() modifies the setting while + * being called, the values are as they currently are, but the + * keys (and their order) were pre-determined before starting to + * invoke the callbacks. + * + * The idea is to give some sensible, stable behavior in case the user + * modifies the settings. Whether this particular behavior is optimal + * is unclear. It's probably a bad idea to modify the settings while + * iterating the values. But at least, it's a safe thing to do and we + * do something sensible. */ + func(keys[i], nm_g_hash_table_lookup(*p_hash, keys[i]), user_data); + } +} + +/** + * nm_setting_vpn_foreach_data_item: + * @setting: a #NMSettingVpn + * @func: (scope call): an user provided function + * @user_data: data to be passed to @func + * + * Iterates all data items stored in this setting. It is safe to add, remove, + * and modify data items inside @func, though any additions or removals made + * during iteration will not be part of the iteration. + */ +void +nm_setting_vpn_foreach_data_item(NMSettingVpn *setting, NMVpnIterFunc func, gpointer user_data) +{ + g_return_if_fail(NM_IS_SETTING_VPN(setting)); + g_return_if_fail(func); + + foreach_item_helper(setting, &NM_SETTING_VPN_GET_PRIVATE(setting)->data, func, user_data); +} + +/** + * nm_setting_vpn_get_num_secrets: + * @setting: the #NMSettingVpn + * + * Gets number of VPN plugin specific secrets in the setting. + * + * Returns: the number of VPN plugin specific secrets + **/ +guint32 +nm_setting_vpn_get_num_secrets(NMSettingVpn *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), 0); + + return nm_g_hash_table_size(NM_SETTING_VPN_GET_PRIVATE(setting)->secrets); +} + +/** + * nm_setting_vpn_add_secret: + * @setting: the #NMSettingVpn + * @key: a name that uniquely identifies the given secret @secret + * @secret: (allow-none): the secret to be referenced by @key + * + * Establishes a relationship between @key and @secret internally in the + * setting which may be retrieved later. + * + * Before 1.24, @secret must not be %NULL and not an empty string. Since 1.24, + * @secret can be set to an empty string. It can also be set to %NULL to unset + * the key. In that case, the behavior is as if calling nm_setting_vpn_remove_secret(). + **/ +void +nm_setting_vpn_add_secret(NMSettingVpn *setting, const char *key, const char *secret) +{ + if (!secret) { + nm_setting_vpn_remove_secret(setting, key); + return; + } + + g_return_if_fail(NM_IS_SETTING_VPN(setting)); + g_return_if_fail(key && key[0]); + + g_hash_table_insert(_ensure_strdict(&NM_SETTING_VPN_GET_PRIVATE(setting)->secrets, TRUE), + g_strdup(key), + g_strdup(secret)); + _notify(setting, PROP_SECRETS); +} + +/** + * nm_setting_vpn_get_secret: + * @setting: the #NMSettingVpn + * @key: the name of the secret to retrieve + * + * Retrieves the secret of a key/value relationship previously established + * by nm_setting_vpn_add_secret(). + * + * Returns: the secret, if any + **/ +const char * +nm_setting_vpn_get_secret(NMSettingVpn *setting, const char *key) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), NULL); + g_return_val_if_fail(key && key[0], NULL); + + return nm_g_hash_table_lookup(NM_SETTING_VPN_GET_PRIVATE(setting)->secrets, key); +} + +/** + * nm_setting_vpn_get_secret_keys: + * @setting: the #NMSettingVpn + * @out_length: (allow-none) (out): the length of the returned array + * + * Retrieves every secret key inside @setting, as an array. + * + * Returns: (array length=out_length) (transfer container): a + * %NULL-terminated array containing each secret key or %NULL if + * there are no secrets. + * + * Since: 1.12 + */ +const char ** +nm_setting_vpn_get_secret_keys(NMSettingVpn *setting, guint *out_length) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), NULL); + + return nm_utils_strdict_get_keys(NM_SETTING_VPN_GET_PRIVATE(setting)->secrets, + TRUE, + out_length); +} + +/** + * nm_setting_vpn_remove_secret: + * @setting: the #NMSettingVpn + * @key: the name of the secret to remove + * + * Deletes a key/value relationship previously established by + * nm_setting_vpn_add_secret(). + * + * Returns: %TRUE if the secret was found and removed from the internal list, + * %FALSE if it was not. + **/ +gboolean +nm_setting_vpn_remove_secret(NMSettingVpn *setting, const char *key) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), FALSE); + g_return_val_if_fail(key && key[0], FALSE); + + if (nm_g_hash_table_remove(NM_SETTING_VPN_GET_PRIVATE(setting)->secrets, key)) { + _notify(setting, PROP_SECRETS); + return TRUE; + } + return FALSE; +} + +/** + * nm_setting_vpn_foreach_secret: + * @setting: a #NMSettingVpn + * @func: (scope call): an user provided function + * @user_data: data to be passed to @func + * + * Iterates all secrets stored in this setting. It is safe to add, remove, + * and modify secrets inside @func, though any additions or removals made during + * iteration will not be part of the iteration. + */ +void +nm_setting_vpn_foreach_secret(NMSettingVpn *setting, NMVpnIterFunc func, gpointer user_data) +{ + g_return_if_fail(NM_IS_SETTING_VPN(setting)); + g_return_if_fail(func); + + foreach_item_helper(setting, &NM_SETTING_VPN_GET_PRIVATE(setting)->secrets, func, user_data); +} + +static gboolean +aggregate(NMSetting *setting, int type_i, gpointer arg) +{ + NMSettingVpnPrivate * priv = NM_SETTING_VPN_GET_PRIVATE(setting); + NMConnectionAggregateType type = type_i; + NMSettingSecretFlags secret_flags; + const char * key_name; + GHashTableIter iter; + + switch (type) { + case NM_CONNECTION_AGGREGATE_ANY_SECRETS: + if (nm_g_hash_table_size(priv->secrets) > 0u) { + *((gboolean *) arg) = TRUE; + return TRUE; + } + return FALSE; + + case NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS: + + if (priv->secrets) { + g_hash_table_iter_init(&iter, priv->secrets); + while (g_hash_table_iter_next(&iter, (gpointer *) &key_name, NULL)) { + if (!nm_setting_get_secret_flags(NM_SETTING(setting), + key_name, + &secret_flags, + NULL)) + nm_assert_not_reached(); + if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) { + *((gboolean *) arg) = TRUE; + return TRUE; + } + } + } + + /* OK, we have no secrets with system-secret flags. + * But do we have any secret-flags (without secrets) that indicate system secrets? */ + if (priv->data) { + g_hash_table_iter_init(&iter, priv->data); + while (g_hash_table_iter_next(&iter, (gpointer *) &key_name, NULL)) { + gs_free char *secret_name = NULL; + + if (!NM_STR_HAS_SUFFIX(key_name, "-flags")) + continue; + secret_name = g_strndup(key_name, strlen(key_name) - NM_STRLEN("-flags")); + if (secret_name[0] == '\0') + continue; + if (!nm_setting_get_secret_flags(NM_SETTING(setting), + secret_name, + &secret_flags, + NULL)) + nm_assert_not_reached(); + if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) { + *((gboolean *) arg) = TRUE; + return TRUE; + } + } + } + + return FALSE; + } + + g_return_val_if_reached(FALSE); +} + +/** + * nm_setting_vpn_get_timeout: + * @setting: the #NMSettingVpn + * + * Returns: the #NMSettingVpn:timeout property of the setting + * + * Since: 1.2 + **/ +guint32 +nm_setting_vpn_get_timeout(NMSettingVpn *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VPN(setting), 0); + + return NM_SETTING_VPN_GET_PRIVATE(setting)->timeout; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(setting); + NMSettingConnection *s_con; + + if (!priv->service_type) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE); + return FALSE; + } + if (!priv->service_type[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE); + return FALSE; + } + + /* default username can be NULL, but can't be zero-length */ + if (priv->user_name && !priv->user_name[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_USER_NAME); + return FALSE; + } + + if (connection && (s_con = nm_connection_get_setting_connection(connection)) + && nm_setting_connection_get_multi_connect(s_con) != NM_CONNECTION_MULTI_CONNECT_DEFAULT) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("cannot set connection.multi-connect for VPN setting")); + return FALSE; + } + + return TRUE; +} + +static NMSettingUpdateSecretResult +update_secret_string(NMSetting *setting, const char *key, const char *value, GError **error) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(setting); + + g_return_val_if_fail(key && key[0], NM_SETTING_UPDATE_SECRET_ERROR); + g_return_val_if_fail(value, NM_SETTING_UPDATE_SECRET_ERROR); + + if (nm_streq0(nm_g_hash_table_lookup(priv->secrets, key), value)) + return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; + + g_hash_table_insert(_ensure_strdict(&priv->secrets, TRUE), g_strdup(key), g_strdup(value)); + return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; +} + +static NMSettingUpdateSecretResult +update_secret_dict(NMSetting *setting, GVariant *secrets, GError **error) +{ + NMSettingVpnPrivate * priv = NM_SETTING_VPN_GET_PRIVATE(setting); + GVariantIter iter; + const char * name, *value; + NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; + + g_return_val_if_fail(secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR); + + /* Make sure the items are valid */ + g_variant_iter_init(&iter, secrets); + while (g_variant_iter_next(&iter, "{&s&s}", &name, &value)) { + if (!name[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("setting contained a secret with an empty name")); + g_prefix_error(error, "%s: ", NM_SETTING_VPN_SETTING_NAME); + return NM_SETTING_UPDATE_SECRET_ERROR; + } + } + + /* Now add the items to the settings' secrets list */ + g_variant_iter_init(&iter, secrets); + while (g_variant_iter_next(&iter, "{&s&s}", &name, &value)) { + if (nm_streq0(nm_g_hash_table_lookup(priv->secrets, name), value)) + continue; + + g_hash_table_insert(_ensure_strdict(&priv->secrets, TRUE), g_strdup(name), g_strdup(value)); + result = NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; + } + + return result; +} + +static int +update_one_secret(NMSetting *setting, const char *key, GVariant *value, GError **error) +{ + NMSettingUpdateSecretResult success = NM_SETTING_UPDATE_SECRET_ERROR; + + g_return_val_if_fail(key != NULL, NM_SETTING_UPDATE_SECRET_ERROR); + g_return_val_if_fail(value != NULL, NM_SETTING_UPDATE_SECRET_ERROR); + + if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) { + /* Passing the string properties individually isn't correct, and won't + * produce the correct result, but for some reason that's how it used + * to be done. So even though it's not correct, keep the code around + * for compatibility's sake. + */ + success = update_secret_string(setting, key, g_variant_get_string(value, NULL), error); + } else if (g_variant_is_of_type(value, G_VARIANT_TYPE("a{ss}"))) { + if (!nm_streq(key, NM_SETTING_VPN_SECRETS)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, + _("not a secret property")); + g_prefix_error(error, "%s.%s ", NM_SETTING_VPN_SETTING_NAME, key); + } else + success = update_secret_dict(setting, value, error); + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("secret is not of correct type")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, key); + } + + if (success == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED) + _notify(NM_SETTING_VPN(setting), PROP_SECRETS); + + return success; +} + +static void +for_each_secret(NMSetting * setting, + const char * secret_name, + GVariant * val, + gboolean remove_non_secrets, + _NMConnectionForEachSecretFunc callback, + gpointer callback_data, + GVariantBuilder * setting_builder) +{ + GVariantBuilder vpn_secrets_builder; + GVariantIter vpn_secrets_iter; + const char * vpn_secret_name; + const char * secret; + + if (!nm_streq(secret_name, NM_SETTING_VPN_SECRETS)) { + NM_SETTING_CLASS(nm_setting_vpn_parent_class) + ->for_each_secret(setting, + secret_name, + val, + remove_non_secrets, + callback, + callback_data, + setting_builder); + return; + } + + if (!g_variant_is_of_type(val, G_VARIANT_TYPE("a{ss}"))) { + /* invalid type. Silently ignore the secrets as we cannot find out the + * secret-flags. */ + return; + } + + /* Iterate through each secret from the VPN dict in the overall secrets dict */ + g_variant_builder_init(&vpn_secrets_builder, G_VARIANT_TYPE("a{ss}")); + g_variant_iter_init(&vpn_secrets_iter, val); + while (g_variant_iter_next(&vpn_secrets_iter, "{&s&s}", &vpn_secret_name, &secret)) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + /* we ignore the return value of get_secret_flags. The function may determine + * that this is not a secret, based on having not secret-flags and no secrets. + * But we have the secret at hand. We know it would be a valid secret, if we + * only add it to the VPN settings. */ + nm_setting_get_secret_flags(setting, vpn_secret_name, &secret_flags, NULL); + + if (callback(secret_flags, callback_data)) + g_variant_builder_add(&vpn_secrets_builder, "{ss}", vpn_secret_name, secret); + } + + g_variant_builder_add(setting_builder, + "{sv}", + secret_name, + g_variant_builder_end(&vpn_secrets_builder)); +} + +static gboolean +get_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags *out_flags, + GError ** error) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(setting); + gs_free char * flags_key_free = NULL; + const char * flags_key; + const char * flags_val; + gint64 i64; + + nm_assert(secret_name); + + if (!secret_name[0]) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, + _("secret name cannot be empty")); + return FALSE; + } + + flags_key = nm_construct_name_a("%s-flags", secret_name, &flags_key_free); + + if (!priv->data + || !g_hash_table_lookup_extended(priv->data, flags_key, NULL, (gpointer *) &flags_val)) { + NM_SET_OUT(out_flags, NM_SETTING_SECRET_FLAG_NONE); + + /* having no secret flag for the secret is fine, as long as there + * is the secret itself... */ + if (!nm_g_hash_table_lookup(priv->secrets, secret_name)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, + _("secret flags property not found")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, flags_key); + return FALSE; + } + return TRUE; + } + + i64 = _nm_utils_ascii_str_to_int64(flags_val, 10, 0, NM_SETTING_SECRET_FLAG_ALL, -1); + if (i64 == -1 || !_nm_setting_secret_flags_valid(i64)) { + /* The flags keys is set to an unexpected value. That is a configuration + * error. Note that keys named "*-flags" are reserved for secrets. The user + * must not use this for anything but secret flags. Hence, we cannot fail + * to read the secret, we pretend that the secret flag is set to the default + * NM_SETTING_SECRET_FLAG_NONE. */ + NM_SET_OUT(out_flags, NM_SETTING_SECRET_FLAG_NONE); + return TRUE; + } + + NM_SET_OUT(out_flags, (NMSettingSecretFlags) i64); + return TRUE; +} + +static gboolean +set_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags flags, + GError ** error) +{ + nm_assert(secret_name); + + if (!secret_name[0]) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, + _("secret name cannot be empty")); + return FALSE; + } + + g_hash_table_insert(_ensure_strdict(&NM_SETTING_VPN_GET_PRIVATE(setting)->data, FALSE), + g_strdup_printf("%s-flags", secret_name), + g_strdup_printf("%u", flags)); + _notify(NM_SETTING_VPN(setting), PROP_SECRETS); + return TRUE; +} + +static GPtrArray * +need_secrets(NMSetting *setting) +{ + /* Assume that VPN connections need secrets since they almost always will */ + return g_ptr_array_sized_new(1); +} + +static NMTernary +compare_property_secrets(NMSettingVpn *a, NMSettingVpn *b, NMSettingCompareFlags flags) +{ + GHashTableIter iter; + const char * key, *val; + int run; + + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_FUZZY)) + return NM_TERNARY_DEFAULT; + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)) + return NM_TERNARY_DEFAULT; + + if (!b) + return TRUE; + + for (run = 0; run < 2; run++) { + NMSettingVpn * current_a = (run == 0) ? a : b; + NMSettingVpn * current_b = (run == 0) ? b : a; + NMSettingVpnPrivate *priv_a = NM_SETTING_VPN_GET_PRIVATE(current_a); + + if (!priv_a->secrets) + continue; + + g_hash_table_iter_init(&iter, priv_a->secrets); + while (g_hash_table_iter_next(&iter, (gpointer) &key, (gpointer) &val)) { + if (nm_streq0(val, nm_setting_vpn_get_secret(current_b, key))) + continue; + if (!_nm_setting_should_compare_secret_property(NM_SETTING(current_a), + NM_SETTING(current_b), + key, + flags)) + continue; + + return FALSE; + } + } + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_VPN_SECRETS)) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; + return compare_property_secrets(NM_SETTING_VPN(set_a), NM_SETTING_VPN(set_b), flags); + } + + return NM_SETTING_CLASS(nm_setting_vpn_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +static gboolean +clear_secrets(const NMSettInfoSetting * sett_info, + guint property_idx, + NMSetting * setting, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(setting); + GParamSpec * prop_spec = sett_info->property_infos[property_idx].param_spec; + GHashTableIter iter; + const char * secret; + gboolean changed = TRUE; + + if (!prop_spec || !NM_FLAGS_HAS(prop_spec->flags, NM_SETTING_PARAM_SECRET)) + return FALSE; + + nm_assert(nm_streq(prop_spec->name, NM_SETTING_VPN_SECRETS)); + + if (!priv->secrets) + return FALSE; + + g_hash_table_iter_init(&iter, priv->secrets); + while (g_hash_table_iter_next(&iter, (gpointer) &secret, NULL)) { + if (func) { + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + + if (!nm_setting_get_secret_flags(setting, secret, &flags, NULL)) + nm_assert_not_reached(); + + if (!func(setting, secret, flags, user_data)) + continue; + } else + nm_assert(nm_setting_get_secret_flags(setting, secret, NULL, NULL)); + + g_hash_table_iter_remove(&iter); + changed = TRUE; + } + + if (changed) + _notify(NM_SETTING_VPN(setting), PROP_SECRETS); + + return changed; +} + +static gboolean +vpn_secrets_from_dbus(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + NMSettingVpn * self = NM_SETTING_VPN(setting); + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(self); + gs_unref_hashtable GHashTable *hash_free = NULL; + GVariantIter iter; + const char * key; + const char * val; + + hash_free = g_steal_pointer(&priv->secrets); + + g_variant_iter_init(&iter, value); + while (g_variant_iter_next(&iter, "{&s&s}", &key, &val)) { + if (!key[0]) + continue; + g_hash_table_insert(_ensure_strdict(&priv->secrets, TRUE), g_strdup(key), g_strdup(val)); + } + + _notify(self, PROP_SECRETS); + return TRUE; +} + +static GVariant * +vpn_secrets_to_dbus(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(setting); + GVariantBuilder builder; + gs_free const char **keys = NULL; + guint i, len; + + if (NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_NO_SECRETS)) + return NULL; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}")); + + keys = nm_utils_strdict_get_keys(priv->secrets, TRUE, &len); + for (i = 0; i < len; i++) { + const char * key = keys[i]; + NMSettingSecretFlags secret_flags; + + if (NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED)) { + if (!nm_setting_get_secret_flags(setting, key, &secret_flags, NULL) + || !NM_FLAGS_HAS(secret_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED)) + continue; + } + g_variant_builder_add(&builder, "{ss}", key, g_hash_table_lookup(priv->secrets, key)); + } + + return g_variant_builder_end(&builder); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingVpn * setting = NM_SETTING_VPN(object); + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_SERVICE_TYPE: + g_value_set_string(value, nm_setting_vpn_get_service_type(setting)); + break; + case PROP_USER_NAME: + g_value_set_string(value, nm_setting_vpn_get_user_name(setting)); + break; + case PROP_PERSISTENT: + g_value_set_boolean(value, priv->persistent); + break; + case PROP_DATA: + g_value_take_boxed(value, _nm_utils_copy_strdict(priv->data)); + break; + case PROP_SECRETS: + g_value_take_boxed(value, _nm_utils_copy_strdict(priv->secrets)); + break; + case PROP_TIMEOUT: + g_value_set_uint(value, nm_setting_vpn_get_timeout(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_SERVICE_TYPE: + g_free(priv->service_type); + priv->service_type = g_value_dup_string(value); + break; + case PROP_USER_NAME: + g_free(priv->user_name); + priv->user_name = g_value_dup_string(value); + break; + case PROP_PERSISTENT: + priv->persistent = g_value_get_boolean(value); + break; + case PROP_DATA: + case PROP_SECRETS: + { + gs_unref_hashtable GHashTable *hash_free = NULL; + GHashTable * src_hash = g_value_get_boxed(value); + GHashTable ** p_hash; + const gboolean is_secrets = (prop_id == PROP_SECRETS); + + if (is_secrets) + p_hash = &priv->secrets; + else + p_hash = &priv->data; + + hash_free = g_steal_pointer(p_hash); + + if (src_hash && g_hash_table_size(src_hash) > 0) { + GHashTableIter iter; + const char * key; + const char * val; + + g_hash_table_iter_init(&iter, src_hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + if (!key || !key[0] || !val) { + /* NULL keys/values and empty key are not allowed. Usually, we would reject them in verify(), but + * then our nm_setting_vpn_remove_data_item() also doesn't allow empty keys. So, if we failed + * it in verify(), it would be only fixable by setting PROP_DATA again. Instead, + * silently ignore them. */ + continue; + } + g_hash_table_insert(_ensure_strdict(p_hash, is_secrets), + g_strdup(key), + g_strdup(val)); + } + } + } break; + case PROP_TIMEOUT: + priv->timeout = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_vpn_init(NMSettingVpn *setting) +{} + +/** + * nm_setting_vpn_new: + * + * Creates a new #NMSettingVpn object with default values. + * + * Returns: (transfer full): the new empty #NMSettingVpn object + **/ +NMSetting * +nm_setting_vpn_new(void) +{ + return g_object_new(NM_TYPE_SETTING_VPN, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(object); + + g_free(priv->service_type); + g_free(priv->user_name); + if (priv->data) + g_hash_table_unref(priv->data); + if (priv->secrets) + g_hash_table_unref(priv->secrets); + + G_OBJECT_CLASS(nm_setting_vpn_parent_class)->finalize(object); +} + +static void +nm_setting_vpn_class_init(NMSettingVpnClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingVpnPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->update_one_secret = update_one_secret; + setting_class->for_each_secret = for_each_secret; + setting_class->get_secret_flags = get_secret_flags; + setting_class->set_secret_flags = set_secret_flags; + setting_class->need_secrets = need_secrets; + setting_class->compare_property = compare_property; + setting_class->clear_secrets = clear_secrets; + setting_class->aggregate = aggregate; + + /** + * NMSettingVpn:service-type: + * + * D-Bus service name of the VPN plugin that this setting uses to connect to + * its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc + * plugin. + **/ + obj_properties[PROP_SERVICE_TYPE] = + g_param_spec_string(NM_SETTING_VPN_SERVICE_TYPE, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVpn:user-name: + * + * If the VPN connection requires a user name for authentication, that name + * should be provided here. If the connection is available to more than one + * user, and the VPN requires each user to supply a different name, then + * leave this property empty. If this property is empty, NetworkManager + * will automatically supply the username of the user which requested the + * VPN connection. + **/ + obj_properties[PROP_USER_NAME] = + g_param_spec_string(NM_SETTING_VPN_USER_NAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVpn:persistent: + * + * If the VPN service supports persistence, and this property is %TRUE, + * the VPN will attempt to stay connected across link changes and outages, + * until explicitly disconnected. + **/ + obj_properties[PROP_PERSISTENT] = + g_param_spec_boolean(NM_SETTING_VPN_PERSISTENT, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVpn:data: (type GHashTable(utf8,utf8)): + * + * Dictionary of key/value pairs of VPN plugin specific data. Both keys and + * values must be strings. + **/ + /* ---keyfile--- + * property: data + * variable: separate variables named after keys of the dictionary + * description: The keys of the data dictionary are used as variable names directly + * under [vpn] section. + * example: remote=ovpn.corp.com cipher=AES-256-CBC username=joe + * ---end--- + */ + obj_properties[PROP_DATA] = g_param_spec_boxed(NM_SETTING_VPN_DATA, + "", + "", + G_TYPE_HASH_TABLE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_DATA], + &nm_sett_info_propert_type_strdict); + + /** + * NMSettingVpn:secrets: (type GHashTable(utf8,utf8)): + * + * Dictionary of key/value pairs of VPN plugin specific secrets like + * passwords or private keys. Both keys and values must be strings. + **/ + /* ---keyfile--- + * property: secrets + * variable: separate variables named after keys of the dictionary + * description: The keys of the secrets dictionary are used as variable names directly + * under [vpn-secrets] section. + * example: password=Popocatepetl + * ---end--- + */ + obj_properties[PROP_SECRETS] = + g_param_spec_boxed(NM_SETTING_VPN_SECRETS, + "", + "", + G_TYPE_HASH_TABLE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET + | NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_SECRETS], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("a{ss}"), + .to_dbus_fcn = vpn_secrets_to_dbus, + .from_dbus_fcn = vpn_secrets_from_dbus, )); + + /** + * NMSettingVpn:timeout: + * + * Timeout for the VPN service to establish the connection. Some services + * may take quite a long time to connect. + * Value of 0 means a default timeout, which is 60 seconds (unless overridden + * by vpn.timeout in configuration file). Values greater than zero mean + * timeout in seconds. + * + * Since: 1.2 + **/ + obj_properties[PROP_TIMEOUT] = g_param_spec_uint(NM_SETTING_VPN_TIMEOUT, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_VPN, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-vrf.c b/src/libnm-core-impl/nm-setting-vrf.c new file mode 100644 index 0000000..a5ee739 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-vrf.c @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-vrf.h" + +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-vrf + * @short_description: Describes connection properties for vrf interfaces + * + * The #NMSettingVrf object is a #NMSetting subclass that describes properties + * necessary for connection to vrf devices + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_TABLE, ); + +/** + * NMSettingVrf: + * + * VRF settings + * + * Since: 1.24 + */ +struct _NMSettingVrf { + NMSetting parent; + guint32 table; +}; + +struct _NMSettingVrfClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingVrf, nm_setting_vrf, NM_TYPE_SETTING) + +/*****************************************************************************/ + +/** + * nm_setting_vrf_get_table: + * @setting: the #NMSettingVrf + * + * Returns: the routing table for the VRF + * + * Since: 1.24 + **/ +guint32 +nm_setting_vrf_get_table(NMSettingVrf *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VRF(setting), 0); + + return setting->table; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVrf *self = NM_SETTING_VRF(setting); + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + if (self->table == 0) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("table cannot be zero")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VRF_SETTING_NAME, NM_SETTING_VRF_TABLE); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingVrf *self = NM_SETTING_VRF(object); + + switch (prop_id) { + case PROP_TABLE: + g_value_set_uint(value, self->table); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingVrf *self = NM_SETTING_VRF(object); + + switch (prop_id) { + case PROP_TABLE: + self->table = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_vrf_init(NMSettingVrf *setting) +{} + +/** + * nm_setting_vrf_new: + * + * Creates a new #NMSettingVrf object with default values. + * + * Returns: (transfer full): the new empty #NMSettingVrf object + * + * Since: 1.24 + **/ +NMSetting * +nm_setting_vrf_new(void) +{ + return g_object_new(NM_TYPE_SETTING_VRF, NULL); +} + +static void +nm_setting_vrf_class_init(NMSettingVrfClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + object_class->get_property = get_property; + object_class->set_property = set_property; + + setting_class->verify = verify; + + /** + * NMSettingVrf:table: + * + * The routing table for this VRF. + * + * Since: 1.24 + **/ + obj_properties[PROP_TABLE] = + g_param_spec_uint(NM_SETTING_VRF_TABLE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_VRF); +} diff --git a/src/libnm-core-impl/nm-setting-vxlan.c b/src/libnm-core-impl/nm-setting-vxlan.c new file mode 100644 index 0000000..ad7156f --- /dev/null +++ b/src/libnm-core-impl/nm-setting-vxlan.c @@ -0,0 +1,816 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-vxlan.h" + +#include + +#include "nm-utils.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-vxlan + * @short_description: Describes connection properties for VXLAN interfaces + * + * The #NMSettingVxlan object is a #NMSetting subclass that describes properties + * necessary for connection to VXLAN interfaces. + **/ + +#define DST_PORT_DEFAULT 8472 + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, + PROP_ID, + PROP_LOCAL, + PROP_REMOTE, + PROP_SOURCE_PORT_MIN, + PROP_SOURCE_PORT_MAX, + PROP_DESTINATION_PORT, + PROP_TOS, + PROP_TTL, + PROP_AGEING, + PROP_LIMIT, + PROP_LEARNING, + PROP_PROXY, + PROP_RSC, + PROP_L2_MISS, + PROP_L3_MISS, ); + +typedef struct { + char *parent; + char *local; + char *remote; + guint id; + guint source_port_min; + guint source_port_max; + guint destination_port; + guint tos; + guint ttl; + guint ageing; + guint limit; + bool learning : 1; + bool proxy : 1; + bool rsc : 1; + bool l2_miss : 1; + bool l3_miss : 1; +} NMSettingVxlanPrivate; + +G_DEFINE_TYPE(NMSettingVxlan, nm_setting_vxlan, NM_TYPE_SETTING) + +#define NM_SETTING_VXLAN_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_VXLAN, NMSettingVxlanPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_vxlan_get_parent: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:parent property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_vxlan_get_parent(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), NULL); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->parent; +} + +/** + * nm_setting_vxlan_get_id: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:id property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_id(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->id; +} + +/** + * nm_setting_vxlan_get_local: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:local property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_vxlan_get_local(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), NULL); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->local; +} + +/** + * nm_setting_vxlan_get_remote: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:remote property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_vxlan_get_remote(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), NULL); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->remote; +} + +/** + * nm_setting_vxlan_get_source_port_min: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:source-port-min property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_source_port_min(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->source_port_min; +} + +/** + * nm_setting_vxlan_get_source_port_max: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:source-port-max property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_source_port_max(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->source_port_max; +} + +/** + * nm_setting_vxlan_get_destination_port: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:destination-port property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_destination_port(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), DST_PORT_DEFAULT); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->destination_port; +} + +/** + * nm_setting_vxlan_get_proxy: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:proxy property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_vxlan_get_proxy(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), FALSE); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->proxy; +} + +/** + * nm_setting_vxlan_get_ageing: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:ageing property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_ageing(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->ageing; +} + +/** + * nm_setting_vxlan_get_limit: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:limit property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_limit(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->limit; +} + +/** + * nm_setting_vxlan_get_tos: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:tos property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_tos(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->tos; +} + +/** + * nm_setting_vxlan_get_ttl: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:ttl property of the setting + * + * Since: 1.2 + **/ +guint +nm_setting_vxlan_get_ttl(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), 0); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->ttl; +} + +/** + * nm_setting_vxlan_get_learning: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:learning property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_vxlan_get_learning(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), FALSE); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->learning; +} + +/** + * nm_setting_vxlan_get_rsc: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:rsc property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_vxlan_get_rsc(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), FALSE); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->rsc; +} + +/** + * nm_setting_vxlan_get_l2_miss: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:l2_miss property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_vxlan_get_l2_miss(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), FALSE); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->l2_miss; +} + +/** + * nm_setting_vxlan_get_l3_miss: + * @setting: the #NMSettingVxlan + * + * Returns: the #NMSettingVxlan:l3_miss property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_vxlan_get_l3_miss(NMSettingVxlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VXLAN(setting), FALSE); + return NM_SETTING_VXLAN_GET_PRIVATE(setting)->l3_miss; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE(setting); + int addr_family = AF_UNSPEC; + gboolean remote_is_valid = TRUE; + gboolean local_is_valid = TRUE; + + if (priv->remote && !nm_utils_parse_inaddr_bin(addr_family, priv->remote, &addr_family, NULL)) + remote_is_valid = FALSE; + if (priv->local && !nm_utils_parse_inaddr_bin(addr_family, priv->local, &addr_family, NULL)) + local_is_valid = FALSE; + + if (!remote_is_valid) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IP%s address"), + priv->remote, + addr_family == AF_UNSPEC ? "" : (addr_family == AF_INET ? "4" : "6")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_REMOTE); + return FALSE; + } + + if (!local_is_valid) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IP%s address"), + priv->local, + addr_family == AF_UNSPEC ? "" : (addr_family == AF_INET ? "4" : "6")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_LOCAL); + return FALSE; + } + + if (priv->parent && !nm_utils_ifname_valid_kernel(priv->parent, NULL) + && !nm_utils_is_uuid(priv->parent)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_PARENT); + return FALSE; + } + + if ((priv->source_port_min || priv->source_port_max) + && (priv->source_port_min > priv->source_port_max)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d is greater than local port max %d"), + priv->source_port_min, + priv->source_port_max); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_VXLAN_SETTING_NAME, + NM_SETTING_VXLAN_SOURCE_PORT_MIN); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +_addrstr_set(char **dst, const char *src) +{ + gs_free char *old = NULL; + + old = *dst; + if (!src) + *dst = NULL; + else if (!nm_utils_parse_inaddr(AF_UNSPEC, src, dst)) + *dst = g_strdup(src); +} +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingVxlan * setting = NM_SETTING_VXLAN(object); + NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string(value, priv->parent); + break; + case PROP_ID: + g_value_set_uint(value, priv->id); + break; + case PROP_LOCAL: + g_value_set_string(value, priv->local); + break; + case PROP_REMOTE: + g_value_set_string(value, priv->remote); + break; + case PROP_SOURCE_PORT_MIN: + g_value_set_uint(value, priv->source_port_min); + break; + case PROP_SOURCE_PORT_MAX: + g_value_set_uint(value, priv->source_port_max); + break; + case PROP_DESTINATION_PORT: + g_value_set_uint(value, priv->destination_port); + break; + case PROP_TOS: + g_value_set_uint(value, priv->tos); + break; + case PROP_AGEING: + g_value_set_uint(value, priv->ageing); + break; + case PROP_LIMIT: + g_value_set_uint(value, priv->limit); + break; + case PROP_PROXY: + g_value_set_boolean(value, priv->proxy); + break; + case PROP_TTL: + g_value_set_uint(value, priv->ttl); + break; + case PROP_LEARNING: + g_value_set_boolean(value, priv->learning); + break; + case PROP_RSC: + g_value_set_boolean(value, priv->rsc); + break; + case PROP_L2_MISS: + g_value_set_boolean(value, priv->l2_miss); + break; + case PROP_L3_MISS: + g_value_set_boolean(value, priv->l3_miss); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingVxlan * setting = NM_SETTING_VXLAN(object); + NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PARENT: + g_free(priv->parent); + priv->parent = g_value_dup_string(value); + break; + case PROP_ID: + priv->id = g_value_get_uint(value); + break; + case PROP_LOCAL: + _addrstr_set(&priv->local, g_value_get_string(value)); + break; + case PROP_REMOTE: + _addrstr_set(&priv->remote, g_value_get_string(value)); + break; + case PROP_SOURCE_PORT_MIN: + priv->source_port_min = g_value_get_uint(value); + break; + case PROP_SOURCE_PORT_MAX: + priv->source_port_max = g_value_get_uint(value); + break; + case PROP_DESTINATION_PORT: + priv->destination_port = g_value_get_uint(value); + break; + case PROP_TOS: + priv->tos = g_value_get_uint(value); + break; + case PROP_AGEING: + priv->ageing = g_value_get_uint(value); + break; + case PROP_LIMIT: + priv->limit = g_value_get_uint(value); + break; + case PROP_PROXY: + priv->proxy = g_value_get_boolean(value); + break; + case PROP_TTL: + priv->ttl = g_value_get_uint(value); + break; + case PROP_LEARNING: + priv->learning = g_value_get_boolean(value); + break; + case PROP_RSC: + priv->rsc = g_value_get_boolean(value); + break; + case PROP_L2_MISS: + priv->l2_miss = g_value_get_boolean(value); + break; + case PROP_L3_MISS: + priv->l3_miss = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_vxlan_init(NMSettingVxlan *self) +{ + NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE(self); + + priv->destination_port = DST_PORT_DEFAULT; + priv->ageing = 300; + priv->learning = TRUE; +} + +/** + * nm_setting_vxlan_new: + * + * Creates a new #NMSettingVxlan object with default values. + * + * Returns: (transfer full): the new empty #NMSettingVxlan object + * + * Since: 1.2 + **/ +NMSetting * +nm_setting_vxlan_new(void) +{ + return g_object_new(NM_TYPE_SETTING_VXLAN, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingVxlan * setting = NM_SETTING_VXLAN(object); + NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE(setting); + + g_free(priv->parent); + g_free(priv->local); + g_free(priv->remote); + + G_OBJECT_CLASS(nm_setting_vxlan_parent_class)->finalize(object); +} + +static void +nm_setting_vxlan_class_init(NMSettingVxlanClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingVxlanPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingVxlan:parent: + * + * If given, specifies the parent interface name or parent connection UUID. + * + * Since: 1.2 + **/ + obj_properties[PROP_PARENT] = g_param_spec_string( + NM_SETTING_VXLAN_PARENT, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + /** + * NMSettingVxlan:id: + * + * Specifies the VXLAN Network Identifier (or VXLAN Segment Identifier) to + * use. + * + * Since: 1.2 + **/ + obj_properties[PROP_ID] = + g_param_spec_uint(NM_SETTING_VXLAN_ID, + "", + "", + 0, + (1 << 24) - 1, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:local: + * + * If given, specifies the source IP address to use in outgoing packets. + * + * Since: 1.2 + **/ + obj_properties[PROP_LOCAL] = g_param_spec_string(NM_SETTING_VXLAN_LOCAL, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:remote: + * + * Specifies the unicast destination IP address to use in outgoing packets + * when the destination link layer address is not known in the VXLAN device + * forwarding database, or the multicast IP address to join. + * + * Since: 1.2 + **/ + obj_properties[PROP_REMOTE] = g_param_spec_string( + NM_SETTING_VXLAN_REMOTE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:source-port-min: + * + * Specifies the minimum UDP source port to communicate to the remote VXLAN + * tunnel endpoint. + * + * Since: 1.2 + **/ + obj_properties[PROP_SOURCE_PORT_MIN] = + g_param_spec_uint(NM_SETTING_VXLAN_SOURCE_PORT_MIN, + "", + "", + 0, + G_MAXUINT16, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:source-port-max: + * + * Specifies the maximum UDP source port to communicate to the remote VXLAN + * tunnel endpoint. + * + * Since: 1.2 + **/ + obj_properties[PROP_SOURCE_PORT_MAX] = + g_param_spec_uint(NM_SETTING_VXLAN_SOURCE_PORT_MAX, + "", + "", + 0, + G_MAXUINT16, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:destination-port: + * + * Specifies the UDP destination port to communicate to the remote VXLAN + * tunnel endpoint. + * + * Since: 1.2 + **/ + obj_properties[PROP_DESTINATION_PORT] = + g_param_spec_uint(NM_SETTING_VXLAN_DESTINATION_PORT, + "", + "", + 0, + G_MAXUINT16, + DST_PORT_DEFAULT, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:ageing: + * + * Specifies the lifetime in seconds of FDB entries learnt by the kernel. + * + * Since: 1.2 + **/ + obj_properties[PROP_AGEING] = + g_param_spec_uint(NM_SETTING_VXLAN_AGEING, + "", + "", + 0, + G_MAXUINT32, + 300, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:limit: + * + * Specifies the maximum number of FDB entries. A value of zero means that + * the kernel will store unlimited entries. + * + * Since: 1.2 + **/ + obj_properties[PROP_LIMIT] = + g_param_spec_uint(NM_SETTING_VXLAN_LIMIT, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:tos: + * + * Specifies the TOS value to use in outgoing packets. + * + * Since: 1.2 + **/ + obj_properties[PROP_TOS] = + g_param_spec_uint(NM_SETTING_VXLAN_TOS, + "", + "", + 0, + 255, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:ttl: + * + * Specifies the time-to-live value to use in outgoing packets. + * + * Since: 1.2 + **/ + obj_properties[PROP_TTL] = + g_param_spec_uint(NM_SETTING_VXLAN_TTL, + "", + "", + 0, + 255, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:proxy: + * + * Specifies whether ARP proxy is turned on. + * + * Since: 1.2 + **/ + obj_properties[PROP_PROXY] = g_param_spec_boolean( + NM_SETTING_VXLAN_PROXY, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:learning: + * + * Specifies whether unknown source link layer addresses and IP addresses + * are entered into the VXLAN device forwarding database. + * + * Since: 1.2 + **/ + obj_properties[PROP_LEARNING] = g_param_spec_boolean( + NM_SETTING_VXLAN_LEARNING, + "", + "", + TRUE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + /** + * NMSettingVxlan:rsc: + * + * Specifies whether route short circuit is turned on. + * + * Since: 1.2 + **/ + obj_properties[PROP_RSC] = g_param_spec_boolean(NM_SETTING_VXLAN_RSC, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + /** + * NMSettingVxlan:l2-miss: + * + * Specifies whether netlink LL ADDR miss notifications are generated. + * + * Since: 1.2 + **/ + obj_properties[PROP_L2_MISS] = g_param_spec_boolean( + NM_SETTING_VXLAN_L2_MISS, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingVxlan:l3-miss: + * + * Specifies whether netlink IP ADDR miss notifications are generated. + * + * Since: 1.2 + **/ + obj_properties[PROP_L3_MISS] = g_param_spec_boolean( + NM_SETTING_VXLAN_L3_MISS, + "", + "", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_VXLAN); +} diff --git a/src/libnm-core-impl/nm-setting-wifi-p2p.c b/src/libnm-core-impl/nm-setting-wifi-p2p.c new file mode 100644 index 0000000..8f67747 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-wifi-p2p.c @@ -0,0 +1,304 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-wifi-p2p.h" + +#include + +#include "nm-utils.h" +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-wifi-p2p + * @short_description: Describes connection properties for 802.11 Wi-Fi P2P networks + * + * The #NMSettingWifiP2P object is a #NMSetting subclass that describes properties + * necessary for connection to 802.11 Wi-Fi P2P networks (aka Wi-Fi Direct). + **/ + +/** + * NMSettingWifiP2P: + * + * Wi-Fi P2P Settings + * + * Since: 1.16 + */ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PEER, PROP_WPS_METHOD, PROP_WFD_IES, ); + +typedef struct { + char * peer_mac_address; + GBytes *wfd_ies; + + NMSettingWirelessSecurityWpsMethod wps_method; +} NMSettingWifiP2PPrivate; + +struct _NMSettingWifiP2P { + NMSetting parent; + NMSettingWifiP2PPrivate _priv; +}; + +struct _NMSettingWifiP2PClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingWifiP2P, nm_setting_wifi_p2p, NM_TYPE_SETTING) + +#define NM_SETTING_WIFI_P2P_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSettingWifiP2P, NM_IS_SETTING_WIFI_P2P, NMSetting) + +/*****************************************************************************/ + +/** + * nm_setting_wifi_p2p_get_peer: + * @setting: the #NMSettingWifiP2P + * + * Returns: the #NMSettingWifiP2P:peer property of the setting + * + * Since: 1.16 + **/ +const char * +nm_setting_wifi_p2p_get_peer(NMSettingWifiP2P *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIFI_P2P(setting), NULL); + + return NM_SETTING_WIFI_P2P_GET_PRIVATE(setting)->peer_mac_address; +} + +/** + * nm_setting_wifi_p2p_get_wps_method: + * @setting: the #NMSettingWifiP2P + * + * Returns: the #NMSettingWifiP2P:wps-method property of the setting + * + * Since: 1.16 + **/ +NMSettingWirelessSecurityWpsMethod +nm_setting_wifi_p2p_get_wps_method(NMSettingWifiP2P *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIFI_P2P(setting), + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT); + + return NM_SETTING_WIFI_P2P_GET_PRIVATE(setting)->wps_method; +} + +/** + * nm_setting_wifi_p2p_get_wfd_ies: + * @setting: the #NMSettingWiFiP2P + * + * Returns: (transfer none): the #NMSettingWiFiP2P:wfd-ies property of the setting + * + * Since: 1.16 + **/ +GBytes * +nm_setting_wifi_p2p_get_wfd_ies(NMSettingWifiP2P *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIFI_P2P(setting), NULL); + + return NM_SETTING_WIFI_P2P_GET_PRIVATE(setting)->wfd_ies; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWifiP2PPrivate *priv = NM_SETTING_WIFI_P2P_GET_PRIVATE(setting); + + if (!priv->peer_mac_address) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIFI_P2P_SETTING_NAME, + NM_SETTING_WIFI_P2P_PEER); + return FALSE; + } + + if (!nm_utils_hwaddr_valid(priv->peer_mac_address, ETH_ALEN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIFI_P2P_SETTING_NAME, + NM_SETTING_WIFI_P2P_PEER); + return FALSE; + } + + if (!_nm_utils_wps_method_validate(priv->wps_method, + NM_SETTING_WIFI_P2P_SETTING_NAME, + NM_SETTING_WIFI_P2P_WPS_METHOD, + TRUE, + error)) + return FALSE; + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingWifiP2P *setting = NM_SETTING_WIFI_P2P(object); + + switch (prop_id) { + case PROP_PEER: + g_value_set_string(value, nm_setting_wifi_p2p_get_peer(setting)); + break; + case PROP_WPS_METHOD: + g_value_set_uint(value, nm_setting_wifi_p2p_get_wps_method(setting)); + break; + case PROP_WFD_IES: + g_value_set_boxed(value, nm_setting_wifi_p2p_get_wfd_ies(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingWifiP2PPrivate *priv = NM_SETTING_WIFI_P2P_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_PEER: + g_free(priv->peer_mac_address); + priv->peer_mac_address = + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); + break; + case PROP_WPS_METHOD: + priv->wps_method = g_value_get_uint(value); + break; + case PROP_WFD_IES: + nm_clear_pointer(&priv->wfd_ies, g_bytes_unref); + priv->wfd_ies = g_value_dup_boxed(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_wifi_p2p_init(NMSettingWifiP2P *setting) +{} + +/** + * nm_setting_wifi_p2p_new: + * + * Creates a new #NMSettingWifiP2P object with default values. + * + * Returns: (transfer full): the new empty #NMSettingWifiP2P object + * + * Since: 1.16 + **/ +NMSetting * +nm_setting_wifi_p2p_new(void) +{ + return g_object_new(NM_TYPE_SETTING_WIFI_P2P, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingWifiP2PPrivate *priv = NM_SETTING_WIFI_P2P_GET_PRIVATE(object); + + g_free(priv->peer_mac_address); + g_bytes_unref(priv->wfd_ies); + + G_OBJECT_CLASS(nm_setting_wifi_p2p_parent_class)->finalize(object); +} + +static void +nm_setting_wifi_p2p_class_init(NMSettingWifiP2PClass *setting_wifi_p2p_class) +{ + GObjectClass * object_class = G_OBJECT_CLASS(setting_wifi_p2p_class); + NMSettingClass *setting_class = NM_SETTING_CLASS(setting_wifi_p2p_class); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingWifiP2P:peer: + * + * The P2P device that should be connected to. Currently, this is the only + * way to create or join a group. + * + * Since: 1.16 + */ + /* ---keyfile--- + * property: peer + * format: usual hex-digits-and-colons notation + * description: MAC address in traditional hex-digits-and-colons notation + * (e.g. 00:22:68:12:79:A2), or semicolon separated list of 6 bytes (obsolete) + * (e.g. 0;34;104;18;121;162). + * ---end--- + */ + obj_properties[PROP_PEER] = g_param_spec_string(NM_SETTING_WIFI_P2P_PEER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWifiP2P:wps-method: + * + * Flags indicating which mode of WPS is to be used. + * + * There's little point in changing the default setting as NetworkManager will + * automatically determine the best method to use. + * + * Since: 1.16 + */ + obj_properties[PROP_WPS_METHOD] = g_param_spec_uint( + NM_SETTING_WIFI_P2P_WPS_METHOD, + "", + "", + 0, + G_MAXUINT32, + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWifiP2P:wfd-ies: + * + * The Wi-Fi Display (WFD) Information Elements (IEs) to set. + * + * Wi-Fi Display requires a protocol specific information element to be + * set in certain Wi-Fi frames. These can be specified here for the + * purpose of establishing a connection. + * This setting is only useful when implementing a Wi-Fi Display client. + * + * Since: 1.16 + */ + obj_properties[PROP_WFD_IES] = g_param_spec_boxed( + NM_SETTING_WIFI_P2P_WFD_IES, + "", + "", + G_TYPE_BYTES, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_WIFI_P2P); +} diff --git a/src/libnm-core-impl/nm-setting-wimax.c b/src/libnm-core-impl/nm-setting-wimax.c new file mode 100644 index 0000000..3051405 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-wimax.c @@ -0,0 +1,255 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2013 Red Hat, Inc. + * Copyright (C) 2009 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-wimax.h" + +#include + +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-wimax + * @short_description: Describes 802.16e Mobile WiMAX connection properties + * + * The #NMSettingWimax object is a #NMSetting subclass that describes properties + * necessary for connection to 802.16e Mobile WiMAX networks. + * + * NetworkManager no longer supports WiMAX; while this API remains available for + * backward-compatibility reasons, it serves no real purpose, since WiMAX + * connections cannot be activated. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_NETWORK_NAME, PROP_MAC_ADDRESS, ); + +typedef struct { + char *network_name; + char *mac_address; +} NMSettingWimaxPrivate; + +G_DEFINE_TYPE(NMSettingWimax, nm_setting_wimax, NM_TYPE_SETTING) + +#define NM_SETTING_WIMAX_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_WIMAX, NMSettingWimaxPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_wimax_get_network_name: + * @setting: the #NMSettingWimax + * + * Returns the WiMAX NSP name (ex "Sprint" or "CLEAR") which identifies the + * specific WiMAX network this setting describes a connection to. + * + * Returns: the WiMAX NSP name + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +const char * +nm_setting_wimax_get_network_name(NMSettingWimax *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIMAX(setting), NULL); + + return NM_SETTING_WIMAX_GET_PRIVATE(setting)->network_name; +} + +/** + * nm_setting_wimax_get_mac_address: + * @setting: the #NMSettingWimax + * + * Returns the MAC address of a WiMAX device which this connection is locked + * to. + * + * Returns: the MAC address + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +const char * +nm_setting_wimax_get_mac_address(NMSettingWimax *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIMAX(setting), NULL); + + return NM_SETTING_WIMAX_GET_PRIVATE(setting)->mac_address; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE(setting); + + if (!priv->network_name) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIMAX_SETTING_NAME, + NM_SETTING_WIMAX_NETWORK_NAME); + return FALSE; + } + + if (!strlen(priv->network_name)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIMAX_SETTING_NAME, + NM_SETTING_WIMAX_NETWORK_NAME); + return FALSE; + } + + if (priv->mac_address && !nm_utils_hwaddr_valid(priv->mac_address, ETH_ALEN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIMAX_SETTING_NAME, + NM_SETTING_WIMAX_MAC_ADDRESS); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingWimax *setting = NM_SETTING_WIMAX(object); + + switch (prop_id) { + case PROP_NETWORK_NAME: + g_value_set_string(value, nm_setting_wimax_get_network_name(setting)); + break; + case PROP_MAC_ADDRESS: + g_value_set_string(value, nm_setting_wimax_get_mac_address(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_NETWORK_NAME: + g_free(priv->network_name); + priv->network_name = g_value_dup_string(value); + break; + case PROP_MAC_ADDRESS: + g_free(priv->mac_address); + priv->mac_address = + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_wimax_init(NMSettingWimax *setting) +{} + +/** + * nm_setting_wimax_new: + * + * Creates a new #NMSettingWimax object with default values. + * + * Returns: the new empty #NMSettingWimax object + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ +NMSetting * +nm_setting_wimax_new(void) +{ + return g_object_new(NM_TYPE_SETTING_WIMAX, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE(object); + + g_free(priv->network_name); + g_free(priv->mac_address); + + G_OBJECT_CLASS(nm_setting_wimax_parent_class)->finalize(object); +} + +static void +nm_setting_wimax_class_init(NMSettingWimaxClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingWimaxPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingWimax:network-name: + * + * Network Service Provider (NSP) name of the WiMAX network this connection + * should use. + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + obj_properties[PROP_NETWORK_NAME] = + g_param_spec_string(NM_SETTING_WIMAX_NETWORK_NAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWimax:mac-address: + * + * If specified, this connection will only apply to the WiMAX device whose + * MAC address matches. This property does not change the MAC address of the + * device (known as MAC spoofing). + * + * Deprecated: 1.2: WiMAX is no longer supported. + **/ + obj_properties[PROP_MAC_ADDRESS] = + g_param_spec_string(NM_SETTING_WIMAX_MAC_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_MAC_ADDRESS], + &nm_sett_info_propert_type_mac_address); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_WIMAX, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-wired.c b/src/libnm-core-impl/nm-setting-wired.c new file mode 100644 index 0000000..0d79f0a --- /dev/null +++ b/src/libnm-core-impl/nm-setting-wired.c @@ -0,0 +1,1694 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-wired.h" + +#include + +#include "nm-utils.h" +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-wired + * @short_description: Describes connection properties for Ethernet-based networks + * + * The #NMSettingWired object is a #NMSetting subclass that describes properties + * necessary for connection to Ethernet networks. + **/ + +/*****************************************************************************/ + +G_STATIC_ASSERT(NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS + == (NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT | NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE)); + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingWired, + PROP_PORT, + PROP_SPEED, + PROP_DUPLEX, + PROP_AUTO_NEGOTIATE, + PROP_MAC_ADDRESS, + PROP_CLONED_MAC_ADDRESS, + PROP_GENERATE_MAC_ADDRESS_MASK, + PROP_MAC_ADDRESS_BLACKLIST, + PROP_MTU, + PROP_S390_SUBCHANNELS, + PROP_S390_NETTYPE, + PROP_S390_OPTIONS, + PROP_WAKE_ON_LAN, + PROP_WAKE_ON_LAN_PASSWORD, ); + +typedef struct { + struct { + NMUtilsNamedValue *arr; + guint len; + guint n_alloc; + } s390_options; + GArray * mac_address_blacklist; + char ** s390_subchannels; + char * port; + char * duplex; + char * device_mac_address; + char * cloned_mac_address; + char * generate_mac_address_mask; + char * s390_nettype; + char * wol_password; + NMSettingWiredWakeOnLan wol; + guint32 speed; + guint32 mtu; + bool auto_negotiate : 1; +} NMSettingWiredPrivate; + +G_DEFINE_TYPE(NMSettingWired, nm_setting_wired, NM_TYPE_SETTING) + +#define NM_SETTING_WIRED_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_WIRED, NMSettingWiredPrivate)) + +/*****************************************************************************/ + +static const char *const valid_s390_opts[] = { + "bridge_role", + "broadcast_mode", + "buffer_count", + "canonical_macaddr", + "checksumming", + "ctcprot", + "fake_broadcast", + "inter", + "inter_jumbo", + "ipato_add4", + "ipato_add6", + "ipato_enable", + "ipato_invert4", + "ipato_invert6", + "isolation", + "lancmd_timeout", + "large_send", + "layer2", + "portname", + "portno", + "priority_queueing", + "protocol", + "route4", + "route6", + "rxip_add4", + "rxip_add6", + "sniffer", + "total", + "vipa_add4", + "vipa_add6", + NULL, +}; + +gboolean +_nm_setting_wired_is_valid_s390_option(const char *option) +{ + if (NM_MORE_ASSERT_ONCE(10)) { + gsize i; + + nm_assert(NM_PTRARRAY_LEN(valid_s390_opts) + 1u == G_N_ELEMENTS(valid_s390_opts)); + + for (i = 0; i < G_N_ELEMENTS(valid_s390_opts); i++) { + if (i == G_N_ELEMENTS(valid_s390_opts) - 1u) + nm_assert(!valid_s390_opts[i]); + else { + nm_assert(valid_s390_opts[i]); + nm_assert(valid_s390_opts[i][0] != '\0'); + if (i > 0) + nm_assert(strcmp(valid_s390_opts[i - 1], valid_s390_opts[i]) < 0); + } + } + } + + return option + && (nm_utils_strv_find_binary_search(valid_s390_opts, + G_N_ELEMENTS(valid_s390_opts) - 1, + option) + >= 0); +} + +gboolean +_nm_setting_wired_is_valid_s390_option_value(const char *name, const char *option) +{ + nm_assert(name); + + if (!option) + return FALSE; + + /* For historic reasons, the s390-options values were not validated beyond + * simple length check (below). + * + * Here, for certain (recently added) options we add strict validation. + * As this is only done for a few hand picked options, do it right here. + * + * Maybe we should find a backward compatible way to validate all options. + * In that case, the validation should become more elaborate, like we do + * for bond options. */ + + if (nm_streq(name, "bridge_role")) { + return NM_IN_STRSET(option, "primary", "secondary", "none"); + } + + return option[0] != '\0' && strlen(option) <= NM_SETTING_WIRED_S390_OPTION_MAX_LEN; +} + +/** + * nm_setting_wired_get_port: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:port property of the setting + **/ +const char * +nm_setting_wired_get_port(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->port; +} + +/** + * nm_setting_wired_get_speed: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:speed property of the setting + **/ +guint32 +nm_setting_wired_get_speed(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), 0); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->speed; +} + +/** + * nm_setting_wired_get_duplex: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:duplex property of the setting + **/ +const char * +nm_setting_wired_get_duplex(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->duplex; +} + +/** + * nm_setting_wired_get_auto_negotiate: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:auto-negotiate property of the setting + **/ +gboolean +nm_setting_wired_get_auto_negotiate(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->auto_negotiate; +} + +/** + * nm_setting_wired_get_mac_address: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:mac-address property of the setting + **/ +const char * +nm_setting_wired_get_mac_address(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->device_mac_address; +} + +/** + * nm_setting_wired_get_cloned_mac_address: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:cloned-mac-address property of the setting + **/ +const char * +nm_setting_wired_get_cloned_mac_address(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->cloned_mac_address; +} + +/** + * nm_setting_wired_get_generate_mac_address_mask: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:generate-mac-address-mask property of the setting + * + * Since: 1.4 + **/ +const char * +nm_setting_wired_get_generate_mac_address_mask(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->generate_mac_address_mask; +} + +/** + * nm_setting_wired_get_mac_address_blacklist: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:mac-address-blacklist property of the setting + **/ +const char *const * +nm_setting_wired_get_mac_address_blacklist(NMSettingWired *setting) +{ + NMSettingWiredPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + + priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + return (const char *const *) priv->mac_address_blacklist->data; +} + +/** + * nm_setting_wired_get_num_mac_blacklist_items: + * @setting: the #NMSettingWired + * + * Returns: the number of blacklisted MAC addresses + **/ +guint32 +nm_setting_wired_get_num_mac_blacklist_items(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), 0); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->mac_address_blacklist->len; +} + +/** + * nm_setting_wired_get_mac_blacklist_item: + * @setting: the #NMSettingWired + * @idx: the zero-based index of the MAC address entry + * + * Returns: the blacklisted MAC address string (hex-digits-and-colons notation) + * at index @idx + **/ +const char * +nm_setting_wired_get_mac_blacklist_item(NMSettingWired *setting, guint32 idx) +{ + NMSettingWiredPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + + priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + g_return_val_if_fail(idx <= priv->mac_address_blacklist->len, NULL); + + return g_array_index(priv->mac_address_blacklist, const char *, idx); +} + +/** + * nm_setting_wired_add_mac_blacklist_item: + * @setting: the #NMSettingWired + * @mac: the MAC address string (hex-digits-and-colons notation) to blacklist + * + * Adds a new MAC address to the #NMSettingWired:mac-address-blacklist property. + * + * Returns: %TRUE if the MAC address was added; %FALSE if the MAC address + * is invalid or was already present + **/ +gboolean +nm_setting_wired_add_mac_blacklist_item(NMSettingWired *setting, const char *mac) +{ + NMSettingWiredPrivate *priv; + const char * candidate; + int i; + + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); + g_return_val_if_fail(mac != NULL, FALSE); + + if (!nm_utils_hwaddr_valid(mac, ETH_ALEN)) + return FALSE; + + priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + candidate = g_array_index(priv->mac_address_blacklist, char *, i); + if (nm_utils_hwaddr_matches(mac, -1, candidate, -1)) + return FALSE; + } + + mac = nm_utils_hwaddr_canonical(mac, ETH_ALEN); + g_array_append_val(priv->mac_address_blacklist, mac); + _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); + return TRUE; +} + +/** + * nm_setting_wired_remove_mac_blacklist_item: + * @setting: the #NMSettingWired + * @idx: index number of the MAC address + * + * Removes the MAC address at index @idx from the blacklist. + **/ +void +nm_setting_wired_remove_mac_blacklist_item(NMSettingWired *setting, guint32 idx) +{ + NMSettingWiredPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_WIRED(setting)); + + priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + g_return_if_fail(idx < priv->mac_address_blacklist->len); + + g_array_remove_index(priv->mac_address_blacklist, idx); + _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); +} + +/** + * nm_setting_wired_remove_mac_blacklist_item_by_value: + * @setting: the #NMSettingWired + * @mac: the MAC address string (hex-digits-and-colons notation) to remove from + * the blacklist + * + * Removes the MAC address @mac from the blacklist. + * + * Returns: %TRUE if the MAC address was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_wired_remove_mac_blacklist_item_by_value(NMSettingWired *setting, const char *mac) +{ + NMSettingWiredPrivate *priv; + const char * candidate; + int i; + + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); + g_return_val_if_fail(mac != NULL, FALSE); + + priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + candidate = g_array_index(priv->mac_address_blacklist, char *, i); + if (!nm_utils_hwaddr_matches(mac, -1, candidate, -1)) { + g_array_remove_index(priv->mac_address_blacklist, i); + _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wired_clear_mac_blacklist_items: + * @setting: the #NMSettingWired + * + * Removes all blacklisted MAC addresses. + **/ +void +nm_setting_wired_clear_mac_blacklist_items(NMSettingWired *setting) +{ + g_return_if_fail(NM_IS_SETTING_WIRED(setting)); + + g_array_set_size(NM_SETTING_WIRED_GET_PRIVATE(setting)->mac_address_blacklist, 0); + _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); +} + +/** + * nm_setting_wired_get_mtu: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:mtu property of the setting + **/ +guint32 +nm_setting_wired_get_mtu(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), 0); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->mtu; +} + +/** + * nm_setting_wired_get_s390_subchannels: + * @setting: the #NMSettingWired + * + * Return the list of s390 subchannels that identify the device that this + * connection is applicable to. The connection should only be used in + * conjunction with that device. + * + * Returns: (transfer none) (element-type utf8): array of strings, each specifying + * one subchannel the s390 device uses to communicate to the host. + **/ +const char *const * +nm_setting_wired_get_s390_subchannels(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + + return (const char *const *) NM_SETTING_WIRED_GET_PRIVATE(setting)->s390_subchannels; +} + +/** + * nm_setting_wired_get_s390_nettype: + * @setting: the #NMSettingWired + * + * Returns the s390 device type this connection should apply to. Will be one + * of 'qeth', 'lcs', or 'ctc'. + * + * Returns: the s390 device type + **/ +const char * +nm_setting_wired_get_s390_nettype(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->s390_nettype; +} + +/** + * nm_setting_wired_get_num_s390_options: + * @setting: the #NMSettingWired + * + * Returns the number of s390-specific options that should be set for this + * device when it is activated. This can be used to retrieve each s390 + * option individually using nm_setting_wired_get_s390_option(). + * + * Returns: the number of s390-specific device options + **/ +guint32 +nm_setting_wired_get_num_s390_options(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), 0); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->s390_options.len; +} + +/** + * nm_setting_wired_get_s390_option: + * @setting: the #NMSettingWired + * @idx: index of the desired option, from 0 to + * nm_setting_wired_get_num_s390_options() - 1 + * @out_key: (allow-none) (out) (transfer none): on return, the key name of the s390 specific + * option; this value is owned by the setting and should not be modified + * @out_value: (allow-none) (out) (transfer none): on return, the value of the key of the + * s390 specific option; this value is owned by the setting and should not be + * modified + * + * Given an index, return the value of the s390 option at that index. indexes + * are *not* guaranteed to be static across modifications to options done by + * nm_setting_wired_add_s390_option() and nm_setting_wired_remove_s390_option(), + * and should not be used to refer to options except for short periods of time + * such as during option iteration. + * + * Returns: %TRUE on success if the index was valid and an option was found, + * %FALSE if the index was invalid (ie, greater than the number of options + * currently held by the setting) + **/ +gboolean +nm_setting_wired_get_s390_option(NMSettingWired *setting, + guint32 idx, + const char ** out_key, + const char ** out_value) +{ + NMSettingWiredPrivate *priv; + + /* with LTO and optimization, the compiler complains that the + * output variables are not initialized. In practice, the function + * only sets the output on success. But make the compiler happy. + */ + NM_SET_OUT(out_key, NULL); + NM_SET_OUT(out_value, NULL); + + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); + + priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + + g_return_val_if_fail(idx < priv->s390_options.len, FALSE); + + NM_SET_OUT(out_key, priv->s390_options.arr[idx].name); + NM_SET_OUT(out_value, priv->s390_options.arr[idx].value_str); + return TRUE; +} + +/** + * nm_setting_wired_get_s390_option_by_key: + * @setting: the #NMSettingWired + * @key: the key for which to retrieve the value + * + * Returns the value associated with the s390-specific option specified by + * @key, if it exists. + * + * Returns: the value, or %NULL if the key/value pair was never added to the + * setting; the value is owned by the setting and must not be modified + **/ +const char * +nm_setting_wired_get_s390_option_by_key(NMSettingWired *setting, const char *key) +{ + NMSettingWiredPrivate *priv; + gssize idx; + + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + g_return_val_if_fail(key, NULL); + + priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + + idx = nm_utils_named_value_list_find(priv->s390_options.arr, priv->s390_options.len, key, TRUE); + if (idx < 0) + return NULL; + return priv->s390_options.arr[idx].value_str; +} + +/** + * nm_setting_wired_add_s390_option: + * @setting: the #NMSettingWired + * @key: key name for the option + * @value: value for the option + * + * Add an option to the table. If the key already exists, the value gets + * replaced. + * + * Before 1.32, the function would assert that the key is valid. Since then, + * an invalid key gets silently added but renders the profile as invalid. + * + * Returns: since 1.32 this always returns %TRUE. + **/ +gboolean +nm_setting_wired_add_s390_option(NMSettingWired *setting, const char *key, const char *value) +{ + NMSettingWiredPrivate *priv; + gssize idx; + + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); + g_return_val_if_fail(key, FALSE); + g_return_val_if_fail(value, FALSE); + + priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + + idx = nm_utils_named_value_list_find(priv->s390_options.arr, priv->s390_options.len, key, TRUE); + if (idx < 0) { + gsize dst_idx = ~idx; + + g_return_val_if_fail(priv->s390_options.len < G_MAXUINT32 - 1u, FALSE); + + if (priv->s390_options.n_alloc < ((gsize) priv->s390_options.len) + 1u) { + priv->s390_options.n_alloc = NM_MAX(4u, (((gsize) priv->s390_options.len) + 1u) * 2u); + priv->s390_options.arr = + g_realloc(priv->s390_options.arr, + priv->s390_options.n_alloc * sizeof(NMUtilsNamedValue)); + } + if (dst_idx < priv->s390_options.len) { + memmove(&priv->s390_options.arr[dst_idx + 1u], + &priv->s390_options.arr[dst_idx], + (priv->s390_options.len - dst_idx) * sizeof(NMUtilsNamedValue)); + } + priv->s390_options.arr[dst_idx] = (NMUtilsNamedValue){ + .name = g_strdup(key), + .value_str = g_strdup(value), + }; + priv->s390_options.len++; + } else { + if (!nm_utils_strdup_reset(&priv->s390_options.arr[idx].value_str_mutable, value)) + return TRUE; + } + + _notify(setting, PROP_S390_OPTIONS); + return TRUE; +} + +/** + * nm_setting_wired_remove_s390_option: + * @setting: the #NMSettingWired + * @key: key name for the option to remove + * + * Remove the s390-specific option referenced by @key from the internal option + * list. + * + * Returns: %TRUE if the option was found and removed from the internal option + * list, %FALSE if it was not. + **/ +gboolean +nm_setting_wired_remove_s390_option(NMSettingWired *setting, const char *key) +{ + NMSettingWiredPrivate *priv; + gsize dst_idx; + gssize idx; + + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); + g_return_val_if_fail(key, FALSE); + + priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + + idx = nm_utils_named_value_list_find(priv->s390_options.arr, priv->s390_options.len, key, TRUE); + if (idx < 0) + return FALSE; + + dst_idx = idx; + + g_free((char *) priv->s390_options.arr[dst_idx].name); + g_free((char *) priv->s390_options.arr[dst_idx].value_str); + if (dst_idx + 1u != priv->s390_options.len) { + memmove(&priv->s390_options.arr[dst_idx], + &priv->s390_options.arr[dst_idx + 1u], + (priv->s390_options.len - dst_idx - 1u) * sizeof(NMUtilsNamedValue)); + } + + priv->s390_options.len--; + + _notify(setting, PROP_S390_OPTIONS); + return TRUE; +} + +static void +_s390_options_clear(NMSettingWiredPrivate *priv) +{ + guint i; + + for (i = 0; i < priv->s390_options.len; i++) { + g_free((char *) priv->s390_options.arr[i].name); + g_free((char *) priv->s390_options.arr[i].value_str); + } + nm_clear_g_free(&priv->s390_options.arr); + priv->s390_options.len = 0; + priv->s390_options.n_alloc = 0; +} + +void +_nm_setting_wired_clear_s390_options(NMSettingWired *setting) +{ + g_return_if_fail(NM_IS_SETTING_WIRED(setting)); + + _s390_options_clear(NM_SETTING_WIRED_GET_PRIVATE(setting)); +} + +/** + * nm_setting_wired_get_valid_s390_options: + * @setting: (allow-none): the #NMSettingWired. This argument is unused + * and you may pass %NULL. + * + * Returns a list of valid s390 options. + * + * The @setting argument is unused and %NULL may be passed instead. + * + * Returns: (transfer none): a %NULL-terminated array of strings of valid s390 options. + **/ +const char ** +nm_setting_wired_get_valid_s390_options(NMSettingWired *setting) +{ + return (const char **) valid_s390_opts; +} + +/** + * nm_setting_wired_get_wake_on_lan: + * @setting: the #NMSettingWired + * + * Returns the Wake-on-LAN options enabled for the connection + * + * Returns: the Wake-on-LAN options + * + * Since: 1.2 + */ +NMSettingWiredWakeOnLan +nm_setting_wired_get_wake_on_lan(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NM_SETTING_WIRED_WAKE_ON_LAN_NONE); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->wol; +} + +/** + * nm_setting_wired_get_wake_on_lan_password: + * @setting: the #NMSettingWired + * + * Returns the Wake-on-LAN password. This only applies to + * %NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC. + * + * Returns: the Wake-on-LAN setting password, or %NULL if there is no password. + * + * Since: 1.2 + */ +const char * +nm_setting_wired_get_wake_on_lan_password(NMSettingWired *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE(setting)->wol_password; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + GError * local = NULL; + guint i; + + if (!NM_IN_STRSET(priv->port, NULL, "tp", "aui", "bnc", "mii")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid Ethernet port value"), + priv->port); + g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_PORT); + return FALSE; + } + + if (!NM_IN_STRSET(priv->duplex, NULL, "half", "full")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid duplex value"), + priv->duplex); + g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_DUPLEX); + return FALSE; + } + + if (priv->device_mac_address && !nm_utils_hwaddr_valid(priv->device_mac_address, ETH_ALEN)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid MAC address"), + priv->device_mac_address); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + return FALSE; + } + + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + const char *mac = g_array_index(priv->mac_address_blacklist, const char *, i); + + if (!nm_utils_hwaddr_valid(mac, ETH_ALEN)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid MAC address"), + mac); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); + return FALSE; + } + } + + if (priv->s390_subchannels) { + guint len = g_strv_length(priv->s390_subchannels); + + if (len != 2 && len != 3) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_SUBCHANNELS); + return FALSE; + } + } + + if (!NM_IN_STRSET(priv->s390_nettype, NULL, "qeth", "lcs", "ctc")) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_NETTYPE); + return FALSE; + } + + for (i = 0; i < priv->s390_options.len; i++) { + const NMUtilsNamedValue *v = &priv->s390_options.arr[i]; + + nm_assert(v->name); + + if (!_nm_setting_wired_is_valid_s390_option(v->name)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid key '%s'"), + v->name); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_OPTIONS); + return FALSE; + } + if (!_nm_setting_wired_is_valid_s390_option_value(v->name, v->value_str)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid value for key '%s'"), + v->name); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_OPTIONS); + return FALSE; + } + } + + if (priv->cloned_mac_address && !NM_CLONED_MAC_IS_SPECIAL(priv->cloned_mac_address) + && !nm_utils_hwaddr_valid(priv->cloned_mac_address, ETH_ALEN)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid MAC address"), + priv->cloned_mac_address); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS); + return FALSE; + } + + /* generate-mac-address-mask only makes sense with cloned-mac-address "random" or + * "stable". Still, let's not be so strict about that and accept the value + * even if it is unused. */ + if (!_nm_utils_generate_mac_address_mask_parse(priv->generate_mac_address_mask, + NULL, + NULL, + NULL, + &local)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + local->message); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK); + g_error_free(local); + return FALSE; + } + + if (NM_FLAGS_ANY(priv->wol, NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS) + && !nm_utils_is_power_of_two(priv->wol)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Wake-on-LAN mode 'default' and 'ignore' are exclusive flags")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_WAKE_ON_LAN); + return FALSE; + } + + if (priv->wol_password && !NM_FLAGS_HAS(priv->wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Wake-on-LAN password can only be used with magic packet mode")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD); + return FALSE; + } + + if (priv->wol_password && !nm_utils_hwaddr_valid(priv->wol_password, ETH_ALEN)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid MAC address"), + priv->wol_password); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD); + return FALSE; + } + + /* Normalizable properties - just return NM_SETTING_VERIFY_NORMALIZABLE for compatibility + * with legacy nm-connection-editor which used to save "full" duplex connection as default + */ + + if (((priv->speed) && (!priv->duplex)) || ((!priv->speed) && (priv->duplex))) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + priv->auto_negotiate + ? _("both speed and duplex should have a valid value or both should be unset") + : _("both speed and duplex are required for static link configuration")); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + if (nm_streq(sett_info->property_infos[property_idx].name, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS)) { + return !set_b + || nm_streq0(NM_SETTING_WIRED_GET_PRIVATE(set_a)->cloned_mac_address, + NM_SETTING_WIRED_GET_PRIVATE(set_b)->cloned_mac_address); + } + + return NM_SETTING_CLASS(nm_setting_wired_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +static GVariant * +_override_autoneg_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + return g_variant_new_boolean(nm_setting_wired_get_auto_negotiate((NMSettingWired *) setting)); +} + +/*****************************************************************************/ + +static void +clear_blacklist_item(char **item_p) +{ + g_free(*item_p); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingWired * setting = NM_SETTING_WIRED(object); + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + GHashTable * hash; + guint i; + + switch (prop_id) { + case PROP_PORT: + g_value_set_string(value, nm_setting_wired_get_port(setting)); + break; + case PROP_SPEED: + g_value_set_uint(value, nm_setting_wired_get_speed(setting)); + break; + case PROP_DUPLEX: + g_value_set_string(value, nm_setting_wired_get_duplex(setting)); + break; + case PROP_AUTO_NEGOTIATE: + g_value_set_boolean(value, nm_setting_wired_get_auto_negotiate(setting)); + break; + case PROP_MAC_ADDRESS: + g_value_set_string(value, nm_setting_wired_get_mac_address(setting)); + break; + case PROP_CLONED_MAC_ADDRESS: + g_value_set_string(value, nm_setting_wired_get_cloned_mac_address(setting)); + break; + case PROP_GENERATE_MAC_ADDRESS_MASK: + g_value_set_string(value, nm_setting_wired_get_generate_mac_address_mask(setting)); + break; + case PROP_MAC_ADDRESS_BLACKLIST: + g_value_set_boxed(value, (char **) priv->mac_address_blacklist->data); + break; + case PROP_MTU: + g_value_set_uint(value, nm_setting_wired_get_mtu(setting)); + break; + case PROP_S390_SUBCHANNELS: + g_value_set_boxed(value, priv->s390_subchannels); + break; + case PROP_S390_NETTYPE: + g_value_set_string(value, nm_setting_wired_get_s390_nettype(setting)); + break; + case PROP_S390_OPTIONS: + hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + for (i = 0; i < priv->s390_options.len; i++) { + g_hash_table_insert(hash, + g_strdup(priv->s390_options.arr[i].name), + g_strdup(priv->s390_options.arr[i].value_str)); + } + g_value_take_boxed(value, hash); + break; + case PROP_WAKE_ON_LAN: + g_value_set_uint(value, priv->wol); + break; + case PROP_WAKE_ON_LAN_PASSWORD: + g_value_set_string(value, priv->wol_password); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE(object); + const char *const * blacklist; + const char * mac; + + switch (prop_id) { + case PROP_PORT: + g_free(priv->port); + priv->port = g_value_dup_string(value); + break; + case PROP_SPEED: + priv->speed = g_value_get_uint(value); + break; + case PROP_DUPLEX: + g_free(priv->duplex); + priv->duplex = g_value_dup_string(value); + break; + case PROP_AUTO_NEGOTIATE: + priv->auto_negotiate = g_value_get_boolean(value); + break; + case PROP_MAC_ADDRESS: + g_free(priv->device_mac_address); + priv->device_mac_address = + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); + break; + case PROP_CLONED_MAC_ADDRESS: + g_free(priv->cloned_mac_address); + priv->cloned_mac_address = + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); + break; + case PROP_GENERATE_MAC_ADDRESS_MASK: + g_free(priv->generate_mac_address_mask); + priv->generate_mac_address_mask = g_value_dup_string(value); + break; + case PROP_MAC_ADDRESS_BLACKLIST: + blacklist = g_value_get_boxed(value); + g_array_set_size(priv->mac_address_blacklist, 0); + if (blacklist && *blacklist) { + guint i; + + for (i = 0; blacklist[i]; i++) { + mac = _nm_utils_hwaddr_canonical_or_invalid(blacklist[i], ETH_ALEN); + g_array_append_val(priv->mac_address_blacklist, mac); + } + } + break; + case PROP_MTU: + priv->mtu = g_value_get_uint(value); + break; + case PROP_S390_SUBCHANNELS: + if (priv->s390_subchannels) + g_strfreev(priv->s390_subchannels); + priv->s390_subchannels = g_value_dup_boxed(value); + break; + case PROP_S390_NETTYPE: + g_free(priv->s390_nettype); + priv->s390_nettype = g_value_dup_string(value); + break; + case PROP_S390_OPTIONS: + { + GHashTable *hash; + + _s390_options_clear(priv); + + hash = g_value_get_boxed(value); + + priv->s390_options.n_alloc = nm_g_hash_table_size(hash); + + if (priv->s390_options.n_alloc > 0u) { + gboolean invalid_content = FALSE; + GHashTableIter iter; + const char * key; + const char * val; + guint j; + guint i; + + priv->s390_options.arr = g_new(NMUtilsNamedValue, priv->s390_options.n_alloc); + + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + if (!key || !val) { + invalid_content = TRUE; + continue; + } + + nm_assert(priv->s390_options.len < priv->s390_options.n_alloc); + + priv->s390_options.arr[priv->s390_options.len] = (NMUtilsNamedValue){ + .name = g_strdup(key), + .value_str = g_strdup(val), + }; + priv->s390_options.len++; + } + if (priv->s390_options.len > 1) { + nm_utils_named_value_list_sort(priv->s390_options.arr, + priv->s390_options.len, + NULL, + NULL); + /* prune duplicate keys. This is only possible if @hash does not use + * g_str_equal() as compare function (which would be a bug). + * Still, handle this, because we use later binary sort and rely + * on unique names. One bug here, should not bork the remainder + * of the program. */ + j = 1; + for (i = 1; i < priv->s390_options.len; i++) { + if (nm_streq(priv->s390_options.arr[j - 1].name, + priv->s390_options.arr[i].name)) { + g_free((char *) priv->s390_options.arr[i].name); + g_free((char *) priv->s390_options.arr[i].value_str); + invalid_content = TRUE; + continue; + } + priv->s390_options.arr[j++] = priv->s390_options.arr[i]; + } + priv->s390_options.len = j; + } + + g_return_if_fail(!invalid_content); + } + } break; + case PROP_WAKE_ON_LAN: + priv->wol = g_value_get_uint(value); + break; + case PROP_WAKE_ON_LAN_PASSWORD: + g_free(priv->wol_password); + priv->wol_password = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_wired_init(NMSettingWired *setting) +{ + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE(setting); + + /* We use GArray rather than GPtrArray so it will automatically be NULL-terminated */ + priv->mac_address_blacklist = g_array_new(TRUE, FALSE, sizeof(char *)); + g_array_set_clear_func(priv->mac_address_blacklist, (GDestroyNotify) clear_blacklist_item); + + priv->wol = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT; +} + +/** + * nm_setting_wired_new: + * + * Creates a new #NMSettingWired object with default values. + * + * Returns: (transfer full): the new empty #NMSettingWired object + **/ +NMSetting * +nm_setting_wired_new(void) +{ + return g_object_new(NM_TYPE_SETTING_WIRED, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE(object); + + g_free(priv->port); + g_free(priv->duplex); + g_free(priv->s390_nettype); + + _s390_options_clear(priv); + + g_free(priv->device_mac_address); + g_free(priv->cloned_mac_address); + g_free(priv->generate_mac_address_mask); + g_array_unref(priv->mac_address_blacklist); + + if (priv->s390_subchannels) + g_strfreev(priv->s390_subchannels); + + g_free(priv->wol_password); + + G_OBJECT_CLASS(nm_setting_wired_parent_class)->finalize(object); +} + +static void +nm_setting_wired_class_init(NMSettingWiredClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingWiredPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->compare_property = compare_property; + + /** + * NMSettingWired:port: + * + * Specific port type to use if the device supports multiple + * attachment methods. One of "tp" (Twisted Pair), "aui" (Attachment Unit + * Interface), "bnc" (Thin Ethernet) or "mii" (Media Independent Interface). + * If the device supports only one port type, this setting is ignored. + **/ + /* ---ifcfg-rh--- + * property: port + * variable: (none) + * description: The property is not saved by the plugin. + * ---end--- + */ + obj_properties[PROP_PORT] = g_param_spec_string(NM_SETTING_WIRED_PORT, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWired:speed: + * + * When a value greater than 0 is set, configures the device to use + * the specified speed. If "auto-negotiate" is "yes" the specified + * speed will be the only one advertised during link negotiation: + * this works only for BASE-T 802.3 specifications and is useful for + * enforcing gigabit speeds, as in this case link negotiation is + * mandatory. + * If the value is unset (0, the default), the link configuration will be + * either skipped (if "auto-negotiate" is "no", the default) or will + * be auto-negotiated (if "auto-negotiate" is "yes") and the local device + * will advertise all the supported speeds. + * In Mbit/s, ie 100 == 100Mbit/s. + * Must be set together with the "duplex" property when non-zero. + * Before specifying a speed value be sure your device supports it. + **/ + /* ---ifcfg-rh--- + * property: speed + * variable: ETHTOOL_OPTS + * description: Fixed speed for the ethernet link. It is added as "speed" + * parameter in the ETHTOOL_OPTS variable. + * ---end--- + */ + obj_properties[PROP_SPEED] = g_param_spec_uint(NM_SETTING_WIRED_SPEED, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWired:duplex: + * + * When a value is set, either "half" or "full", configures the device + * to use the specified duplex mode. If "auto-negotiate" is "yes" the + * specified duplex mode will be the only one advertised during link + * negotiation: this works only for BASE-T 802.3 specifications and is + * useful for enforcing gigabits modes, as in these cases link negotiation + * is mandatory. + * If the value is unset (the default), the link configuration will be + * either skipped (if "auto-negotiate" is "no", the default) or will + * be auto-negotiated (if "auto-negotiate" is "yes") and the local device + * will advertise all the supported duplex modes. + * Must be set together with the "speed" property if specified. + * Before specifying a duplex mode be sure your device supports it. + **/ + /* ---ifcfg-rh--- + * property: duplex + * variable: ETHTOOL_OPTS + * description: Fixed duplex mode for the ethernet link. It is added as + * "duplex" parameter in the ETHOOL_OPTS variable. + * ---end--- + */ + obj_properties[PROP_DUPLEX] = g_param_spec_string(NM_SETTING_WIRED_DUPLEX, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWired:auto-negotiate: + * + * When %TRUE, enforce auto-negotiation of speed and duplex mode. + * If "speed" and "duplex" properties are both specified, only that + * single mode will be advertised and accepted during the link + * auto-negotiation process: this works only for BASE-T 802.3 specifications + * and is useful for enforcing gigabits modes, as in these cases link + * negotiation is mandatory. + * When %FALSE, "speed" and "duplex" properties should be both set or + * link configuration will be skipped. + **/ + /* ---ifcfg-rh--- + * property: auto-negotiate + * variable: ETHTOOL_OPTS + * description: Whether link speed and duplex autonegotiation is enabled. + * It is not saved only if disabled and no values are provided for the + * "speed" and "duplex" parameters (skips link configuration). + * ---end--- + */ + obj_properties[PROP_AUTO_NEGOTIATE] = + g_param_spec_boolean(NM_SETTING_WIRED_AUTO_NEGOTIATE, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_AUTO_NEGOTIATE], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_BOOLEAN, + .to_dbus_fcn = _override_autoneg_get, )); + + /** + * NMSettingWired:mac-address: + * + * If specified, this connection will only apply to the Ethernet device + * whose permanent MAC address matches. This property does not change the + * MAC address of the device (i.e. MAC spoofing). + **/ + /* ---keyfile--- + * property: mac-address + * format: usual hex-digits-and-colons notation + * description: MAC address in traditional hex-digits-and-colons notation + * (e.g. 00:22:68:12:79:A2), or semicolon separated list of 6 bytes (obsolete) + * (e.g. 0;34;104;18;121;162) + * ---end--- + * ---ifcfg-rh--- + * property: mac-address + * variable: HWADDR + * description: Hardware address of the device in traditional hex-digits-and-colons + * notation (e.g. 00:22:68:14:5A:05). + * Note that for initscripts this is the current MAC address of the device as found + * during ifup. For NetworkManager this is the permanent MAC address. Or in case no + * permanent MAC address exists, the MAC address initially configured on the device. + * ---end--- + */ + obj_properties[PROP_MAC_ADDRESS] = g_param_spec_string( + NM_SETTING_WIRED_MAC_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_MAC_ADDRESS], + &nm_sett_info_propert_type_mac_address); + + /** + * NMSettingWired:cloned-mac-address: + * + * If specified, request that the device use this MAC address instead. + * This is known as MAC cloning or spoofing. + * + * Beside explicitly specifying a MAC address, the special values "preserve", "permanent", + * "random" and "stable" are supported. + * "preserve" means not to touch the MAC address on activation. + * "permanent" means to use the permanent hardware address if the device + * has one (otherwise this is treated as "preserve"). + * "random" creates a random MAC address on each connect. + * "stable" creates a hashed MAC address based on connection.stable-id and a + * machine dependent key. + * + * If unspecified, the value can be overwritten via global defaults, see manual + * of NetworkManager.conf. If still unspecified, it defaults to "preserve" + * (older versions of NetworkManager may use a different default value). + * + * On D-Bus, this field is expressed as "assigned-mac-address" or the deprecated + * "cloned-mac-address". + **/ + /* ---keyfile--- + * property: cloned-mac-address + * format: usual hex-digits-and-colons notation + * description: Cloned MAC address in traditional hex-digits-and-colons notation + * (e.g. 00:22:68:12:79:B2), or semicolon separated list of 6 bytes (obsolete) + * (e.g. 0;34;104;18;121;178). + * ---end--- + * ---ifcfg-rh--- + * property: cloned-mac-address + * variable: MACADDR + * description: Cloned (spoofed) MAC address in traditional hex-digits-and-colons + * notation (e.g. 00:22:68:14:5A:99). + * ---end--- + * ---dbus--- + * property: cloned-mac-address + * format: byte array + * description: This D-Bus field is deprecated in favor of "assigned-mac-address" + * which is more flexible and allows specifying special variants like "random". + * For libnm and nmcli, this field is called "cloned-mac-address". + * ---end--- + */ + obj_properties[PROP_CLONED_MAC_ADDRESS] = g_param_spec_string( + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_CLONED_MAC_ADDRESS], + &nm_sett_info_propert_type_cloned_mac_address); + + /* ---dbus--- + * property: assigned-mac-address + * format: string + * description: The new field for the cloned MAC address. It can be either + * a hardware address in ASCII representation, or one of the special values + * "preserve", "permanent", "random" or "stable". + * This field replaces the deprecated "cloned-mac-address" on D-Bus, which + * can only contain explicit hardware addresses. Note that this property + * only exists in D-Bus API. libnm and nmcli continue to call this property + * "cloned-mac-address". + * ---end--- + */ + _nm_properties_override_dbus(properties_override, + "assigned-mac-address", + &nm_sett_info_propert_type_assigned_mac_address); + + /** + * NMSettingWired:generate-mac-address-mask: + * + * With #NMSettingWired:cloned-mac-address setting "random" or "stable", + * by default all bits of the MAC address are scrambled and a locally-administered, + * unicast MAC address is created. This property allows to specify that certain bits + * are fixed. Note that the least significant bit of the first MAC address will + * always be unset to create a unicast MAC address. + * + * If the property is %NULL, it is eligible to be overwritten by a default + * connection setting. If the value is still %NULL or an empty string, the + * default is to create a locally-administered, unicast MAC address. + * + * If the value contains one MAC address, this address is used as mask. The set + * bits of the mask are to be filled with the current MAC address of the device, + * while the unset bits are subject to randomization. + * Setting "FE:FF:FF:00:00:00" means to preserve the OUI of the current MAC address + * and only randomize the lower 3 bytes using the "random" or "stable" algorithm. + * + * If the value contains one additional MAC address after the mask, + * this address is used instead of the current MAC address to fill the bits + * that shall not be randomized. For example, a value of + * "FE:FF:FF:00:00:00 68:F7:28:00:00:00" will set the OUI of the MAC address + * to 68:F7:28, while the lower bits are randomized. A value of + * "02:00:00:00:00:00 00:00:00:00:00:00" will create a fully scrambled + * globally-administered, burned-in MAC address. + * + * If the value contains more than one additional MAC addresses, one of + * them is chosen randomly. For example, "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00" + * will create a fully scrambled MAC address, randomly locally or globally + * administered. + **/ + /* ---ifcfg-rh--- + * property: generate-mac-address-mask + * variable: GENERATE_MAC_ADDRESS_MASK(+) + * description: the MAC address mask for generating randomized and stable + * cloned-mac-address. + * ---end--- + */ + obj_properties[PROP_GENERATE_MAC_ADDRESS_MASK] = g_param_spec_string( + NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWired:mac-address-blacklist: + * + * If specified, this connection will never apply to the Ethernet device + * whose permanent MAC address matches an address in the list. Each MAC + * address is in the standard hex-digits-and-colons notation + * (00:11:22:33:44:55). + **/ + /* ---keyfile--- + * property: mac-address-blacklist + * format: list of MACs (separated with semicolons) + * description: MAC address blacklist. + * example: mac-address-blacklist= 00:22:68:12:79:A6;00:22:68:12:79:78 + * ---end--- + * ---ifcfg-rh--- + * property: mac-address-blacklist + * variable: HWADDR_BLACKLIST(+) + * description: It denies usage of the connection for any device whose address + * is listed. + * example: HWADDR_BLACKLIST="00:22:68:11:69:08 00:11:22:11:44:55" + * ---end--- + */ + obj_properties[PROP_MAC_ADDRESS_BLACKLIST] = g_param_spec_boxed( + NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWired:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple Ethernet frames. + **/ + /* ---ifcfg-rh--- + * property: mtu + * variable: MTU + * description: MTU of the interface. + * ---end--- + */ + obj_properties[PROP_MTU] = g_param_spec_uint(NM_SETTING_WIRED_MTU, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWired:s390-subchannels: + * + * Identifies specific subchannels that this network device uses for + * communication with z/VM or s390 host. Like the + * #NMSettingWired:mac-address property for non-z/VM devices, this property + * can be used to ensure this connection only applies to the network device + * that uses these subchannels. The list should contain exactly 3 strings, + * and each string may only be composed of hexadecimal characters and the + * period (.) character. + **/ + /* ---ifcfg-rh--- + * property: s390-subchannels + * variable: SUBCHANNELS + * description: Subchannels for IBM S390 hosts. + * example: SUBCHANNELS=0.0.b00a,0.0.b00b,0.0.b00c + * ---end--- + */ + obj_properties[PROP_S390_SUBCHANNELS] = g_param_spec_boxed( + NM_SETTING_WIRED_S390_SUBCHANNELS, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWired:s390-nettype: + * + * s390 network device type; one of "qeth", "lcs", or "ctc", representing + * the different types of virtual network devices available on s390 systems. + **/ + /* ---ifcfg-rh--- + * property: s390-nettype + * variable: NETTYPE + * values: "qeth", "lcs" or "ctc" + * description: Network type of the S390 host. + * example: NETTYPE=qeth + * ---end--- + */ + obj_properties[PROP_S390_NETTYPE] = g_param_spec_string( + NM_SETTING_WIRED_S390_NETTYPE, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWired:s390-options: (type GHashTable(utf8,utf8)): + * + * Dictionary of key/value pairs of s390-specific device options. Both keys + * and values must be strings. Allowed keys include "portno", "layer2", + * "portname", "protocol", among others. Key names must contain only + * alphanumeric characters (ie, [a-zA-Z0-9]). + **/ + /* ---ifcfg-rh--- + * property: s390-options + * variable: OPTIONS and PORTNAME, CTCPROTO, + * description: S390 device options. All options go to OPTIONS, except for + * "portname" and "ctcprot" that have their own variables. + * ---end--- + */ + obj_properties[PROP_S390_OPTIONS] = g_param_spec_boxed( + NM_SETTING_WIRED_S390_OPTIONS, + "", + "", + G_TYPE_HASH_TABLE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_S390_OPTIONS], + &nm_sett_info_propert_type_strdict); + + /** + * NMSettingWired:wake-on-lan: + * + * The #NMSettingWiredWakeOnLan options to enable. Not all devices support all options. + * May be any combination of %NM_SETTING_WIRED_WAKE_ON_LAN_PHY, + * %NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST, %NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST, + * %NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST, %NM_SETTING_WIRED_WAKE_ON_LAN_ARP, + * %NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC or the special values + * %NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT (to use global settings) and + * %NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE (to disable management of Wake-on-LAN in + * NetworkManager). + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: wake-on-lan + * variable: ETHTOOL_OPTS, ETHTOOL_WAKE_ON_LAN + * description: Wake on Lan mode for ethernet. The setting "ignore" is expressed + * with "ETHTOOL_WAKE_ON_LAN=ignore". Otherwise, the "ETHTOOL_OPTS" variable is set + * with the value "wol" and several of the characters "p|u|m|b|a|g|s|f|d" as explained + * in the ethtool manual page. + * ---end--- + */ + obj_properties[PROP_WAKE_ON_LAN] = + g_param_spec_uint(NM_SETTING_WIRED_WAKE_ON_LAN, + "", + "", + 0, + G_MAXUINT32, + NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWired:wake-on-lan-password: + * + * If specified, the password used with magic-packet-based + * Wake-on-LAN, represented as an Ethernet MAC address. If %NULL, + * no password will be required. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: wake-on-lan-password + * variable: ETHTOOL_OPTS + * description: Password for secure-on based Wake-on-Lan. It is added as "sopass" + * parameter in the ETHTOOL_OPTS variable. + * example: ETHTOOL_OPTS="wol gs sopass 00:11:22:33:44:55" + * ---end--- + */ + obj_properties[PROP_WAKE_ON_LAN_PASSWORD] = + g_param_spec_string(NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_WIRED, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-wireguard.c b/src/libnm-core-impl/nm-setting-wireguard.c new file mode 100644 index 0000000..5c96fc6 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-wireguard.c @@ -0,0 +1,2594 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 - 2019 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-wireguard.h" + +#include "nm-setting-private.h" +#include "nm-utils-private.h" +#include "nm-connection-private.h" +#include "libnm-glib-aux/nm-secret-utils.h" + +/*****************************************************************************/ + +/** + * SECTION:nm-setting-wireguard + * @short_description: Describes connection properties for wireguard related options + * + * The #NMSettingWireGuard object is a #NMSetting subclass that contains settings + * for configuring WireGuard. + **/ + +/*****************************************************************************/ + +static NMWireGuardPeer *_wireguard_peer_dup(const NMWireGuardPeer *self); + +G_DEFINE_BOXED_TYPE(NMWireGuardPeer, + nm_wireguard_peer, + _wireguard_peer_dup, + nm_wireguard_peer_unref) + +/* NMWireGuardPeer can also track invalid allowed-ip settings, and only reject + * them later during is_valid(). Such values are marked by a leading 'X' character + * in the @allowed_ips. It is expected, that such values are the exception, and + * commonly not present. */ +#define ALLOWED_IP_INVALID_X 'X' +#define ALLOWED_IP_INVALID_X_STR "X" + +/** + * NMWireGuardPeer: + * + * The settings of one WireGuard peer. + * + * Since: 1.16 + */ +struct _NMWireGuardPeer { + NMSockAddrEndpoint * endpoint; + char * public_key; + char * preshared_key; + GPtrArray * allowed_ips; + guint refcount; + NMSettingSecretFlags preshared_key_flags; + guint16 persistent_keepalive; + bool public_key_valid : 1; + bool preshared_key_valid : 1; + bool sealed : 1; +}; + +static gboolean +NM_IS_WIREGUARD_PEER(const NMWireGuardPeer *self, gboolean also_sealed) +{ + return self && self->refcount > 0 && (also_sealed || !self->sealed); +} + +/** + * nm_wireguard_peer_new: + * + * Returns: (transfer full): a new, default, unsealed #NMWireGuardPeer instance. + * + * Since: 1.16 + */ +NMWireGuardPeer * +nm_wireguard_peer_new(void) +{ + NMWireGuardPeer *self; + + self = g_slice_new(NMWireGuardPeer); + *self = (NMWireGuardPeer){ + .refcount = 1, + .preshared_key_flags = NM_SETTING_SECRET_FLAG_NOT_REQUIRED, + }; + return self; +} + +/** + * nm_wireguard_peer_new_clone: + * @self: the #NMWireGuardPeer instance to copy. + * @with_secrets: if %TRUE, the preshared-key secrets are copied + * as well. Otherwise, they will be removed. + * + * Returns: (transfer full): a clone of @self. This instance + * is always unsealed. + * + * Since: 1.16 + */ +NMWireGuardPeer * +nm_wireguard_peer_new_clone(const NMWireGuardPeer *self, gboolean with_secrets) +{ + NMWireGuardPeer *new; + guint i; + + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), NULL); + + new = g_slice_new(NMWireGuardPeer); + *new = (NMWireGuardPeer){ + .refcount = 1, + .public_key = g_strdup(self->public_key), + .public_key_valid = self->public_key_valid, + .preshared_key = with_secrets ? g_strdup(self->preshared_key) : NULL, + .preshared_key_valid = self->preshared_key_valid, + .preshared_key_flags = self->preshared_key_flags, + .endpoint = nm_sock_addr_endpoint_ref(self->endpoint), + .persistent_keepalive = self->persistent_keepalive, + }; + if (self->allowed_ips && self->allowed_ips->len > 0) { + new->allowed_ips = g_ptr_array_new_full(self->allowed_ips->len, g_free); + for (i = 0; i < self->allowed_ips->len; i++) { + g_ptr_array_add(new->allowed_ips, g_strdup(self->allowed_ips->pdata[i])); + } + } + return new; +} + +/** + * nm_wireguard_peer_ref: + * @self: (allow-none): the #NMWireGuardPeer instance + * + * This is not thread-safe. + * + * Returns: returns the input argument @self after incrementing + * the reference count. + * + * Since: 1.16 + */ +NMWireGuardPeer * +nm_wireguard_peer_ref(NMWireGuardPeer *self) +{ + if (!self) + return NULL; + + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), NULL); + + nm_assert(self->refcount < G_MAXUINT); + + self->refcount++; + return self; +} + +/** + * nm_wireguard_peer_unref: + * @self: (allow-none): the #NMWireGuardPeer instance + * + * Drop a reference to @self. If the last reference is dropped, + * the instance is freed and all associate data released. + * + * This is not thread-safe. + * + * Since: 1.16 + */ +void +nm_wireguard_peer_unref(NMWireGuardPeer *self) +{ + if (!self) + return; + + g_return_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE)); + + if (--self->refcount > 0) + return; + + nm_sock_addr_endpoint_unref(self->endpoint); + if (self->allowed_ips) + g_ptr_array_unref(self->allowed_ips); + g_free(self->public_key); + nm_free_secret(self->preshared_key); + g_slice_free(NMWireGuardPeer, self); +} + +/** + * _wireguard_peer_dup: + * @self: the #NMWireGuardPeer instance + * + * Duplicates the #NMWireGuardPeer instance. Note that if @self + * is already sealed, this increments the reference count and + * returns it. If the instance is still unsealed, it is copied. + * + * Returns: (transfer full): a duplicate of @self, or (if the + * instance is sealed and thus immutable) a reference to @self. + * As such, the instance will be sealed if and only if @self is + * sealed. + */ +static NMWireGuardPeer * +_wireguard_peer_dup(const NMWireGuardPeer *self) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), NULL); + + if (self->sealed) + return nm_wireguard_peer_ref((NMWireGuardPeer *) self); + return nm_wireguard_peer_new_clone(self, TRUE); +} + +/** + * nm_wireguard_peer_seal: + * @self: the #NMWireGuardPeer instance + * + * Seal the #NMWireGuardPeer instance. Afterwards, it is a bug + * to call all functions that modify the instance (except ref/unref). + * A sealed instance cannot be unsealed again, but you can create + * an unsealed copy with nm_wireguard_peer_new_clone(). + * + * Since: 1.16 + */ +void +nm_wireguard_peer_seal(NMWireGuardPeer *self) +{ + g_return_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE)); + + self->sealed = TRUE; + + if (self->allowed_ips) { + if (self->allowed_ips->len == 0) + nm_clear_pointer(&self->allowed_ips, g_ptr_array_unref); + } +} + +/** + * nm_wireguard_peer_is_sealed: + * @self: the #NMWireGuardPeer instance + * + * Returns: whether @self is sealed or not. + * + * Since: 1.16 + */ +gboolean +nm_wireguard_peer_is_sealed(const NMWireGuardPeer *self) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), FALSE); + + return self->sealed; +} + +/** + * nm_wireguard_peer_get_public_key: + * @self: the #NMWireGuardPeer instance + * + * Returns: (transfer none): the public key or %NULL if unset. + * + * Since: 1.16 + */ +const char * +nm_wireguard_peer_get_public_key(const NMWireGuardPeer *self) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), NULL); + + return self->public_key; +} + +/** + * nm_wireguard_peer_set_public_key: + * @self: the unsealed #NMWireGuardPeer instance + * @public_key: (allow-none) (transfer none): the new public + * key or %NULL to clear the public key. + * @accept_invalid: if %TRUE and @public_key is not %NULL and + * invalid, then do not modify the instance. + * + * Reset the public key. Note that if the public key is valid, it + * will be normalized (which may or may not modify the set value). + * + * It is a bug trying to modify a sealed #NMWireGuardPeer instance. + * + * Returns: %TRUE if the key was valid or %NULL. Returns + * %FALSE for invalid keys. Depending on @accept_invalid + * will an invalid key be set or not. + * + * Since: 1.16 + */ +gboolean +nm_wireguard_peer_set_public_key(NMWireGuardPeer *self, + const char * public_key, + gboolean accept_invalid) +{ + char * public_key_normalized = NULL; + gboolean is_valid; + + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, FALSE), FALSE); + + if (!public_key) { + nm_clear_g_free(&self->public_key); + return TRUE; + } + + is_valid = nm_utils_base64secret_normalize(public_key, + NM_WIREGUARD_PUBLIC_KEY_LEN, + &public_key_normalized); + nm_assert(is_valid == (public_key_normalized != NULL)); + + if (!is_valid && !accept_invalid) + return FALSE; + + self->public_key_valid = is_valid; + g_free(self->public_key); + self->public_key = public_key_normalized ?: g_strdup(public_key); + return is_valid; +} + +void +_nm_wireguard_peer_set_public_key_bin(NMWireGuardPeer *self, + const guint8 public_key[static NM_WIREGUARD_PUBLIC_KEY_LEN]) +{ + g_return_if_fail(NM_IS_WIREGUARD_PEER(self, FALSE)); + + nm_clear_g_free(&self->public_key); + + if (!public_key) + return; + + self->public_key = g_base64_encode(public_key, NM_WIREGUARD_PUBLIC_KEY_LEN); + self->public_key_valid = TRUE; +} + +/** + * nm_wireguard_peer_get_preshared_key: + * @self: the #NMWireGuardPeer instance + * + * Returns: (transfer none): the preshared key or %NULL if unset. + * + * Since: 1.16 + */ +const char * +nm_wireguard_peer_get_preshared_key(const NMWireGuardPeer *self) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), NULL); + + return self->preshared_key; +} + +/** + * nm_wireguard_peer_set_preshared_key: + * @self: the unsealed #NMWireGuardPeer instance + * @preshared_key: (allow-none) (transfer none): the new preshared + * key or %NULL to clear the preshared key. + * @accept_invalid: whether to allow setting the key to an invalid + * value. If %FALSE, @self is unchanged if the key is invalid + * and if %FALSE is returned. + * + * Reset the preshared key. Note that if the preshared key is valid, it + * will be normalized (which may or may not modify the set value). + * + * Note that the preshared-key is a secret and consequently has corresponding + * preshared-key-flags property. This is so that secrets can be optional + * and requested on demand from a secret-agent. Also, an invalid preshared-key + * may optionally cause nm_wireguard_peer_is_valid() to fail or it may + * be accepted. + * + * It is a bug trying to modify a sealed #NMWireGuardPeer instance. + * + * Returns: %TRUE if the preshared-key is valid, otherwise %FALSE. + * %NULL is considered a valid value. + * If the key is invalid, it depends on @accept_invalid whether the + * previous value was reset. + * + * Since: 1.16 + */ +gboolean +nm_wireguard_peer_set_preshared_key(NMWireGuardPeer *self, + const char * preshared_key, + gboolean accept_invalid) +{ + char * preshared_key_normalized = NULL; + gboolean is_valid; + + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, FALSE), FALSE); + + if (!preshared_key) { + nm_clear_pointer(&self->preshared_key, nm_free_secret); + return TRUE; + } + + is_valid = nm_utils_base64secret_normalize(preshared_key, + NM_WIREGUARD_SYMMETRIC_KEY_LEN, + &preshared_key_normalized); + nm_assert(is_valid == (preshared_key_normalized != NULL)); + + if (!is_valid && !accept_invalid) + return FALSE; + + self->preshared_key_valid = is_valid; + nm_free_secret(self->preshared_key); + self->preshared_key = preshared_key_normalized ?: g_strdup(preshared_key); + return is_valid; +} + +/** + * nm_wireguard_peer_get_preshared_key_flags: + * @self: the #NMWireGuardPeer instance + * + * Returns: get the secret flags for the preshared-key. + * + * Since: 1.16 + */ +NMSettingSecretFlags +nm_wireguard_peer_get_preshared_key_flags(const NMWireGuardPeer *self) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), 0); + + return self->preshared_key_flags; +} + +/** + * nm_wireguard_peer_set_preshared_key_flags: + * @self: the unsealed #NMWireGuardPeer instance + * @preshared_key_flags: the secret flags to set. + * + * It is a bug trying to modify a sealed #NMWireGuardPeer instance. + * + * Since: 1.16 + */ +void +nm_wireguard_peer_set_preshared_key_flags(NMWireGuardPeer * self, + NMSettingSecretFlags preshared_key_flags) +{ + g_return_if_fail(NM_IS_WIREGUARD_PEER(self, FALSE)); + + self->preshared_key_flags = preshared_key_flags; +} + +/** + * nm_wireguard_peer_get_persistent_keepalive: + * @self: the #NMWireGuardPeer instance + * + * Returns: get the persistent-keepalive setting in seconds. Set to zero to disable + * keep-alive. + * + * Since: 1.16 + */ +guint16 +nm_wireguard_peer_get_persistent_keepalive(const NMWireGuardPeer *self) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), 0); + + return self->persistent_keepalive; +} + +/** + * nm_wireguard_peer_set_persistent_keepalive: + * @self: the unsealed #NMWireGuardPeer instance + * @persistent_keepalive: the keep-alive value to set. + * + * It is a bug trying to modify a sealed #NMWireGuardPeer instance. + * + * Since: 1.16 + */ +void +nm_wireguard_peer_set_persistent_keepalive(NMWireGuardPeer *self, guint16 persistent_keepalive) +{ + g_return_if_fail(NM_IS_WIREGUARD_PEER(self, FALSE)); + + self->persistent_keepalive = persistent_keepalive; +} + +NMSockAddrEndpoint * +_nm_wireguard_peer_get_endpoint(const NMWireGuardPeer *self) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), NULL); + + return self->endpoint; +} + +/** + * nm_wireguard_peer_get_endpoint: + * @self: the #NMWireGuardPeer instance + * + * Returns: (transfer none): the endpoint or %NULL if none was set. + * + * Since: 1.16 + */ +const char * +nm_wireguard_peer_get_endpoint(const NMWireGuardPeer *self) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), NULL); + + return self->endpoint ? nm_sock_addr_endpoint_get_endpoint(self->endpoint) : NULL; +} + +void +_nm_wireguard_peer_set_endpoint(NMWireGuardPeer *self, NMSockAddrEndpoint *endpoint) +{ + NMSockAddrEndpoint *old; + + nm_assert(NM_IS_WIREGUARD_PEER(self, FALSE)); + + old = self->endpoint; + self->endpoint = nm_sock_addr_endpoint_ref(endpoint); + nm_sock_addr_endpoint_unref(old); +} + +/** + * nm_wireguard_peer_set_endpoint: + * @self: the unsealed #NMWireGuardPeer instance + * @endpoint: the socket address endpoint to set or %NULL. + * @allow_invalid: if %TRUE, also invalid values are set. + * If %FALSE, the function does nothing for invalid @endpoint + * arguments. + * + * Sets or clears the endpoint of @self. + * + * It is a bug trying to modify a sealed #NMWireGuardPeer instance. + * + * Returns: %TRUE if the endpoint is %NULL or valid. For an + * invalid @endpoint argument, %FALSE is returned. Depending + * on @allow_invalid, the instance will be modified. + * + * Since: 1.16 + */ +gboolean +nm_wireguard_peer_set_endpoint(NMWireGuardPeer *self, const char *endpoint, gboolean allow_invalid) +{ + NMSockAddrEndpoint *old; + NMSockAddrEndpoint *new; + gboolean is_valid; + + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, FALSE), FALSE); + + if (!endpoint) { + nm_clear_pointer(&self->endpoint, nm_sock_addr_endpoint_unref); + return TRUE; + } + + new = nm_sock_addr_endpoint_new(endpoint); + + is_valid = (nm_sock_addr_endpoint_get_host(new) != NULL); + + if (!allow_invalid && !is_valid) { + nm_sock_addr_endpoint_unref(new); + return FALSE; + } + + old = self->endpoint; + self->endpoint = new; + nm_sock_addr_endpoint_unref(old); + return is_valid; +} + +/** + * nm_wireguard_peer_get_allowed_ips_len: + * @self: the #NMWireGuardPeer instance + * + * Returns: the number of allowed-ips entries. + * + * Since: 1.16 + */ +guint +nm_wireguard_peer_get_allowed_ips_len(const NMWireGuardPeer *self) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), 0); + + return self->allowed_ips ? self->allowed_ips->len : 0u; +} + +/** + * nm_wireguard_peer_get_allowed_ip: + * @self: the #NMWireGuardPeer instance + * @idx: the index from zero to (allowed-ips-len - 1) to + * retrieve. + * @out_is_valid: (allow-none): %TRUE if the returned value is a valid allowed-ip + * setting. + * This parameter is wrongly not marked as (out) argument, it is + * thus not accessible via introspection. This cannot be fixed without + * breaking API for introspection users. + * + * Returns: (transfer none): the allowed-ip setting at index @idx. + * If @idx is out of range, %NULL will be returned. + * + * Since: 1.16 + */ +const char * +nm_wireguard_peer_get_allowed_ip(const NMWireGuardPeer *self, guint idx, gboolean *out_is_valid) +{ + const char *s; + + /* With LTO, the compiler might warn about the g_return_val_if_fail() + * code path not initializing the output argument. Workaround that by + * always setting the out argument. */ + NM_SET_OUT(out_is_valid, FALSE); + + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), NULL); + + if (!self->allowed_ips || idx >= self->allowed_ips->len) + return NULL; + + s = self->allowed_ips->pdata[idx]; + NM_SET_OUT(out_is_valid, s[0] != ALLOWED_IP_INVALID_X); + return s[0] == ALLOWED_IP_INVALID_X ? &s[1] : s; +} + +/** + * nm_wireguard_peer_clear_allowed_ips: + * @self: the unsealed #NMWireGuardPeer instance + * + * Removes all allowed-ip entries. + * + * It is a bug trying to modify a sealed #NMWireGuardPeer instance. + * + * Since: 1.16 + */ +void +nm_wireguard_peer_clear_allowed_ips(NMWireGuardPeer *self) +{ + g_return_if_fail(NM_IS_WIREGUARD_PEER(self, FALSE)); + + if (self->allowed_ips) + g_ptr_array_set_size(self->allowed_ips, 0); +} + +static gboolean +_peer_append_allowed_ip(NMWireGuardPeer *self, const char *allowed_ip, gboolean accept_invalid) +{ + int addr_family; + int prefix; + NMIPAddr addrbin; + char * str; + gboolean is_valid = TRUE; + + nm_assert(NM_IS_WIREGUARD_PEER(self, FALSE)); + nm_assert(allowed_ip); + + /* normalize the address (if it is valid. Otherwise, take it + * as-is (it will render the instance invalid). */ + if (!nm_utils_parse_inaddr_prefix_bin(AF_UNSPEC, allowed_ip, &addr_family, &addrbin, &prefix)) { + if (!accept_invalid) + return FALSE; + /* mark the entry as invalid by having a "X" prefix. */ + str = g_strconcat(ALLOWED_IP_INVALID_X_STR, allowed_ip, NULL); + is_valid = FALSE; + } else { + char addrstr[NM_UTILS_INET_ADDRSTRLEN]; + + nm_assert_addr_family(addr_family); + + nm_utils_inet_ntop(addr_family, &addrbin, addrstr); + if (prefix >= 0) + str = g_strdup_printf("%s/%d", addrstr, prefix); + else + str = g_strdup(addrstr); + nm_assert(str[0] != ALLOWED_IP_INVALID_X); + } + + if (!self->allowed_ips) + self->allowed_ips = g_ptr_array_new_with_free_func(g_free); + + g_ptr_array_add(self->allowed_ips, str); + return is_valid; +} + +/** + * nm_wireguard_peer_append_allowed_ip: + * @self: the unsealed #NMWireGuardPeer instance + * @allowed_ip: the allowed-ip entry to set. + * @accept_invalid: if %TRUE, also invalid @allowed_ip value + * will be appended. Otherwise, the function does nothing + * in face of invalid values and returns %FALSE. + * + * Appends @allowed_ip setting to the list. This does not check + * for duplicates and always appends @allowed_ip to the end of the + * list. If @allowed_ip is valid, it will be normalized and a modified + * for might be appended. If @allowed_ip is invalid, it will still be + * appended, but later verification will fail. + * + * It is a bug trying to modify a sealed #NMWireGuardPeer instance. + * + * Returns: %TRUE if the value is a valid allowed-ips value, %FALSE otherwise. + * Depending on @accept_invalid, also invalid values are added. + * + * Since: 1.16 + */ +gboolean +nm_wireguard_peer_append_allowed_ip(NMWireGuardPeer *self, + const char * allowed_ip, + gboolean accept_invalid) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, FALSE), FALSE); + g_return_val_if_fail(allowed_ip, FALSE); + + return _peer_append_allowed_ip(self, allowed_ip, accept_invalid); +} + +/** + * nm_wireguard_peer_remove_allowed_ip: + * @self: the unsealed #NMWireGuardPeer instance + * @idx: the index from zero to (allowed-ips-len - 1) to + * retrieve. If the index is out of range, %FALSE is returned + * and nothing is done. + * + * Removes the allowed-ip at the given @idx. This shifts all + * following entries one index down. + * + * It is a bug trying to modify a sealed #NMWireGuardPeer instance. + * + * Returns: %TRUE if @idx was valid and the allowed-ip was removed. + * %FALSE otherwise, and the peer will not be changed. + * + * Since: 1.16 + */ +gboolean +nm_wireguard_peer_remove_allowed_ip(NMWireGuardPeer *self, guint idx) +{ + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, FALSE), FALSE); + + if (!self->allowed_ips || idx >= self->allowed_ips->len) + return FALSE; + + g_ptr_array_remove_index(self->allowed_ips, idx); + return TRUE; +} + +/** + * nm_wireguard_peer_is_valid: + * @self: the #NMWireGuardPeer instance + * @check_secrets: if %TRUE, non-secret properties are validated. + * Otherwise, they are ignored for this purpose. + * @check_non_secrets: if %TRUE, secret properties are validated. + * Otherwise, they are ignored for this purpose. + * @error: the #GError location for returning the failure reason. + * + * Returns: %TRUE if the peer is valid or fails with an error + * reason. + * + * Since: 1.16 + */ +gboolean +nm_wireguard_peer_is_valid(const NMWireGuardPeer *self, + gboolean check_non_secrets, + gboolean check_secrets, + GError ** error) +{ + guint i; + + g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + if (check_non_secrets) { + if (!self->public_key) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("missing public-key for peer")); + return FALSE; + } else if (!self->public_key_valid) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid public-key for peer")); + return FALSE; + } + } + + if (check_secrets) { + if (self->preshared_key && !self->preshared_key_valid) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid preshared-key for peer")); + return FALSE; + } + } + + if (check_non_secrets) { + if (!_nm_utils_secret_flags_validate(self->preshared_key_flags, + NULL, + NULL, + NM_SETTING_SECRET_FLAG_NONE, + error)) + return FALSE; + } + + if (check_non_secrets) { + if (self->endpoint && !nm_sock_addr_endpoint_get_host(self->endpoint)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid endpoint for peer")); + return FALSE; + } + + if (self->allowed_ips) { + for (i = 0; i < self->allowed_ips->len; i++) { + const char *s = self->allowed_ips->pdata[i]; + + if (s[0] == ALLOWED_IP_INVALID_X) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid IP address \"%s\" for allowed-ip of peer"), + &s[1]); + return FALSE; + } + } + } + + if (!_nm_setting_secret_flags_valid(self->preshared_key_flags)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid preshared-key-flags for peer")); + return FALSE; + } + } + + return TRUE; +} + +/** + * nm_wireguard_peer_cmp: + * @a: (allow-none): the #NMWireGuardPeer to compare. + * @b: (allow-none): the other #NMWireGuardPeer to compare. + * @compare_flags: #NMSettingCompareFlags to affect the comparison. + * + * Returns: zero of the two instances are equivalent or + * a non-zero integer otherwise. This defines a total ordering + * over the peers. Whether a peer is sealed or not, does not + * affect the comparison. + * + * Since: 1.16 + */ +int +nm_wireguard_peer_cmp(const NMWireGuardPeer *a, + const NMWireGuardPeer *b, + NMSettingCompareFlags compare_flags) +{ + guint i, n; + + NM_CMP_SELF(a, b); + + /* regardless of the @compare_flags, the public-key is the ID of the peer. It must + * always be compared. */ + NM_CMP_FIELD_BOOL(a, b, public_key_valid); + NM_CMP_FIELD_STR0(a, b, public_key); + + if (NM_FLAGS_ANY(compare_flags, + NM_SETTING_COMPARE_FLAG_INFERRABLE | NM_SETTING_COMPARE_FLAG_FUZZY)) + return 0; + + NM_CMP_FIELD_BOOL(a, b, endpoint); + if (a->endpoint) { + NM_CMP_DIRECT_STRCMP0(nm_sock_addr_endpoint_get_endpoint(a->endpoint), + nm_sock_addr_endpoint_get_endpoint(b->endpoint)); + } + + NM_CMP_FIELD(a, b, persistent_keepalive); + + NM_CMP_DIRECT((n = (a->allowed_ips ? a->allowed_ips->len : 0u)), + (b->allowed_ips ? b->allowed_ips->len : 0u)); + for (i = 0; i < n; i++) + NM_CMP_DIRECT_STRCMP0(a->allowed_ips->pdata[i], b->allowed_ips->pdata[i]); + + NM_CMP_FIELD(a, b, preshared_key_flags); + + if (!NM_FLAGS_HAS(compare_flags, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)) { + if (NM_FLAGS_HAS(compare_flags, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS) + && NM_FLAGS_HAS(a->preshared_key_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED)) { + /* pass */ + } else if (NM_FLAGS_HAS(compare_flags, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS) + && NM_FLAGS_HAS(a->preshared_key_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED)) { + /* pass */ + } else { + NM_CMP_FIELD_BOOL(a, b, preshared_key_valid); + NM_CMP_FIELD_STR0(a, b, preshared_key); + } + } + + return 0; +} + +/*****************************************************************************/ + +typedef struct { + const char * public_key; + NMWireGuardPeer *peer; + guint idx; +} PeerData; + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_FWMARK, + PROP_IP4_AUTO_DEFAULT_ROUTE, + PROP_IP6_AUTO_DEFAULT_ROUTE, + PROP_LISTEN_PORT, + PROP_MTU, + PROP_PEER_ROUTES, + PROP_PRIVATE_KEY, + PROP_PRIVATE_KEY_FLAGS, ); + +typedef struct { + char * private_key; + GPtrArray * peers_arr; + GHashTable * peers_hash; + NMSettingSecretFlags private_key_flags; + NMTernary ip4_auto_default_route; + NMTernary ip6_auto_default_route; + guint32 fwmark; + guint32 mtu; + guint16 listen_port; + bool private_key_valid : 1; + bool peer_routes : 1; +} NMSettingWireGuardPrivate; + +/** + * NMSettingWireGuard: + * + * WireGuard Settings + * + * Since: 1.16 + */ +struct _NMSettingWireGuard { + NMSetting parent; + NMSettingWireGuardPrivate _priv; +}; + +struct _NMSettingWireGuardClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingWireGuard, nm_setting_wireguard, NM_TYPE_SETTING) + +#define NM_SETTING_WIREGUARD_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSettingWireGuard, NM_IS_SETTING_WIREGUARD, NMSetting) + +/*****************************************************************************/ + +#define peers_psk_get_secret_name_a(public_key, to_free) \ + nm_construct_name_a(NM_SETTING_WIREGUARD_PEERS ".%s." NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY, \ + (public_key), \ + (to_free)) + +#define peers_psk_get_secret_name_dup(public_key) \ + g_strdup_printf(NM_SETTING_WIREGUARD_PEERS ".%s." NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY, \ + (public_key)) + +#define peers_psk_get_secret_parse_a(secret_public_key, public_key_free) \ + ({ \ + const char *_secret_public_key = (secret_public_key); \ + char ** _public_key_free = (public_key_free); \ + const char *_public_key = NULL; \ + \ + nm_assert(_public_key_free && !*_public_key_free); \ + \ + if (NM_STR_HAS_PREFIX(_secret_public_key, NM_SETTING_WIREGUARD_PEERS ".")) { \ + _secret_public_key += NM_STRLEN(NM_SETTING_WIREGUARD_PEERS "."); \ + if (NM_STR_HAS_SUFFIX(_secret_public_key, "." NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY)) { \ + _public_key = \ + nm_strndup_a(300, \ + _secret_public_key, \ + strlen(_secret_public_key) \ + - NM_STRLEN("." NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY), \ + _public_key_free); \ + } \ + } \ + \ + _public_key; \ + }) + +/*****************************************************************************/ + +/** + * nm_setting_wireguard_get_private_key: + * @self: the #NMSettingWireGuard instance + * + * Returns: (transfer none): the set private-key or %NULL. + * + * Since: 1.16 + */ +const char * +nm_setting_wireguard_get_private_key(NMSettingWireGuard *self) +{ + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), NULL); + + return NM_SETTING_WIREGUARD_GET_PRIVATE(self)->private_key; +} + +/** + * nm_setting_wireguard_get_private_key_flags: + * @self: the #NMSettingWireGuard instance + * + * Returns: the secret-flags for #NMSettingWireGuard:private-key. + * + * Since: 1.16 + */ +NMSettingSecretFlags +nm_setting_wireguard_get_private_key_flags(NMSettingWireGuard *self) +{ + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), 0); + + return NM_SETTING_WIREGUARD_GET_PRIVATE(self)->private_key_flags; +} + +/** + * nm_setting_wireguard_get_fwmark: + * @self: the #NMSettingWireGuard instance + * + * Returns: the set firewall mark. + * + * Since: 1.16 + */ +guint32 +nm_setting_wireguard_get_fwmark(NMSettingWireGuard *self) +{ + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), 0); + + return NM_SETTING_WIREGUARD_GET_PRIVATE(self)->fwmark; +} + +/** + * nm_setting_wireguard_get_listen_port: + * @self: the #NMSettingWireGuard instance + * + * Returns: the set UDP listen port. + * + * Since: 1.16 + */ +guint16 +nm_setting_wireguard_get_listen_port(NMSettingWireGuard *self) +{ + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), 0); + + return NM_SETTING_WIREGUARD_GET_PRIVATE(self)->listen_port; +} + +/** + * nm_setting_wireguard_get_peer_routes: + * @self: the #NMSettingWireGuard instance + * + * Returns: whether automatically add peer routes. + * + * Since: 1.16 + */ +gboolean +nm_setting_wireguard_get_peer_routes(NMSettingWireGuard *self) +{ + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), TRUE); + + return NM_SETTING_WIREGUARD_GET_PRIVATE(self)->peer_routes; +} + +/** + * nm_setting_wireguard_get_mtu: + * @self: the #NMSettingWireGuard instance + * + * Returns: the MTU of the setting. + * + * Since: 1.16 + */ +guint32 +nm_setting_wireguard_get_mtu(NMSettingWireGuard *self) +{ + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), 0); + + return NM_SETTING_WIREGUARD_GET_PRIVATE(self)->mtu; +} + +/** + * nm_setting_wireguard_get_ip4_auto_default_route: + * @self: the #NMSettingWireGuard setting. + * + * Returns: the "ip4-auto-default-route" property of the setting. + * + * Since: 1.20 + */ +NMTernary +nm_setting_wireguard_get_ip4_auto_default_route(NMSettingWireGuard *self) +{ + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), NM_TERNARY_DEFAULT); + + return NM_SETTING_WIREGUARD_GET_PRIVATE(self)->ip4_auto_default_route; +} + +/** + * nm_setting_wireguard_get_ip6_auto_default_route: + * @self: the #NMSettingWireGuard setting. + * + * Returns: the "ip6-auto-default-route" property of the setting. + * + * Since: 1.20 + */ +NMTernary +nm_setting_wireguard_get_ip6_auto_default_route(NMSettingWireGuard *self) +{ + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), NM_TERNARY_DEFAULT); + + return NM_SETTING_WIREGUARD_GET_PRIVATE(self)->ip6_auto_default_route; +} + +/*****************************************************************************/ + +static void +_peer_free(PeerData *pd) +{ + nm_assert(pd); + + nm_wireguard_peer_unref(pd->peer); + g_slice_free(PeerData, pd); +} + +/*****************************************************************************/ + +static void +_peers_notify(gpointer self) +{ + _nm_setting_emit_property_changed(self); +} + +static PeerData * +_peers_get(NMSettingWireGuardPrivate *priv, guint idx) +{ + PeerData *pd; + + nm_assert(priv); + nm_assert(idx < priv->peers_arr->len); + + pd = priv->peers_arr->pdata[idx]; + + nm_assert(pd); + nm_assert(pd->idx == idx); + nm_assert(NM_IS_WIREGUARD_PEER(pd->peer, TRUE)); + nm_assert(nm_wireguard_peer_is_sealed(pd->peer)); + nm_assert(pd->public_key == nm_wireguard_peer_get_public_key(pd->peer)); + nm_assert(g_hash_table_lookup(priv->peers_hash, pd) == pd); + + return pd; +} + +static PeerData * +_peers_get_by_public_key(NMSettingWireGuardPrivate *priv, + const char * public_key, + gboolean try_with_normalized_key) +{ + gs_free char *public_key_normalized = NULL; + PeerData * pd; + +again: + nm_assert(priv); + nm_assert(public_key); + + pd = g_hash_table_lookup(priv->peers_hash, &public_key); + if (pd) { + nm_assert(_peers_get(priv, pd->idx) == pd); + return pd; + } + if (try_with_normalized_key + && nm_utils_base64secret_normalize(public_key, + NM_WIREGUARD_PUBLIC_KEY_LEN, + &public_key_normalized)) { + public_key = public_key_normalized; + try_with_normalized_key = FALSE; + goto again; + } + return NULL; +} + +static void +_peers_remove(NMSettingWireGuardPrivate *priv, PeerData *pd, gboolean do_free) +{ + guint i; + + nm_assert(pd); + nm_assert(_peers_get(priv, pd->idx) == pd); + + for (i = pd->idx + 1; i < priv->peers_arr->len; i++) + _peers_get(priv, i)->idx--; + + g_ptr_array_remove_index(priv->peers_arr, pd->idx); + if (!g_hash_table_remove(priv->peers_hash, pd)) + nm_assert_not_reached(); + if (do_free) + _peer_free(pd); +} + +/** + * nm_setting_wireguard_get_peers_len: + * @self: the #NMSettingWireGuard instance + * + * Returns: the number of registered peers. + * + * Since: 1.16 + */ +guint +nm_setting_wireguard_get_peers_len(NMSettingWireGuard *self) +{ + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), 0); + + return NM_SETTING_WIREGUARD_GET_PRIVATE(self)->peers_arr->len; +} + +/** + * nm_setting_wireguard_get_peer: + * @self: the #NMSettingWireGuard instance + * @idx: the index to lookup. + * + * Returns: (transfer none): the #NMWireGuardPeer entry at + * index @idx. If the index is out of range, %NULL is returned. + * + * Since: 1.16 + */ +NMWireGuardPeer * +nm_setting_wireguard_get_peer(NMSettingWireGuard *self, guint idx) +{ + NMSettingWireGuardPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), NULL); + + priv = NM_SETTING_WIREGUARD_GET_PRIVATE(self); + + if (idx >= priv->peers_arr->len) + return NULL; + + return _peers_get(priv, idx)->peer; +} + +/** + * nm_setting_wireguard_get_peer_by_public_key: + * @self: the #NMSettingWireGuard instance + * @public_key: the public key for looking up the + * peer. + * @out_idx: (out) (allow-none): optional output argument + * for the index of the found peer. If no index is found, + * this is set to the nm_setting_wireguard_get_peers_len(). + * + * Returns: (transfer none): the #NMWireGuardPeer instance with a + * matching public key. If no such peer exists, %NULL is returned. + * + * Since: 1.16 + */ +NMWireGuardPeer * +nm_setting_wireguard_get_peer_by_public_key(NMSettingWireGuard *self, + const char * public_key, + guint * out_idx) +{ + NMSettingWireGuardPrivate *priv; + PeerData * pd; + + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), NULL); + g_return_val_if_fail(public_key, NULL); + + priv = NM_SETTING_WIREGUARD_GET_PRIVATE(self); + + pd = _peers_get_by_public_key(priv, public_key, TRUE); + if (!pd) { + NM_SET_OUT(out_idx, priv->peers_arr->len); + return NULL; + } + NM_SET_OUT(out_idx, pd->idx); + return pd->peer; +} + +static gboolean +_peers_set(NMSettingWireGuardPrivate *priv, + NMWireGuardPeer * peer, + guint idx, + gboolean check_same_key) +{ + PeerData * pd_same_key = NULL; + PeerData * pd_idx = NULL; + const char *public_key; + + nm_assert(idx <= priv->peers_arr->len); + + public_key = nm_wireguard_peer_get_public_key(peer); + + if (idx < priv->peers_arr->len) { + pd_idx = _peers_get(priv, idx); + + if (pd_idx->peer == peer) + return FALSE; + + if (check_same_key && nm_streq(public_key, nm_wireguard_peer_get_public_key(pd_idx->peer))) + check_same_key = FALSE; + } + + nm_wireguard_peer_seal(peer); + nm_wireguard_peer_ref(peer); + + if (check_same_key) { + pd_same_key = _peers_get_by_public_key(priv, public_key, FALSE); + if (pd_same_key) { + if (pd_idx) { + nm_assert(pd_same_key != pd_idx); + _peers_remove(priv, pd_same_key, TRUE); + pd_same_key = NULL; + } else { + if (pd_same_key->peer == peer && pd_same_key->idx == priv->peers_arr->len - 1) { + nm_wireguard_peer_unref(peer); + return FALSE; + } + _peers_remove(priv, pd_same_key, FALSE); + nm_wireguard_peer_unref(pd_same_key->peer); + } + } + } else + nm_assert(_peers_get_by_public_key(priv, public_key, FALSE) == pd_idx); + + if (pd_idx) { + g_hash_table_remove(priv->peers_hash, pd_idx); + nm_wireguard_peer_unref(pd_idx->peer); + pd_idx->public_key = public_key; + pd_idx->peer = peer; + g_hash_table_add(priv->peers_hash, pd_idx); + return TRUE; + } + + if (!pd_same_key) + pd_same_key = g_slice_new(PeerData); + + *pd_same_key = (PeerData){ + .peer = peer, + .public_key = public_key, + .idx = priv->peers_arr->len, + }; + + g_ptr_array_add(priv->peers_arr, pd_same_key); + if (!nm_g_hash_table_add(priv->peers_hash, pd_same_key)) + nm_assert_not_reached(); + + nm_assert(_peers_get(priv, pd_same_key->idx) == pd_same_key); + + return TRUE; +} + +static gboolean +_peers_append(NMSettingWireGuardPrivate *priv, NMWireGuardPeer *peer, gboolean check_same_key) +{ + return _peers_set(priv, peer, priv->peers_arr->len, check_same_key); +} + +/** + * nm_setting_wireguard_set_peer: + * @self: the #NMSettingWireGuard instance + * @peer: the #NMWireGuardPeer instance to set. + * This seals @peer and keeps a reference on the + * instance. + * @idx: the index, in the range of 0 to the number of + * peers (including). That means, if @idx is one past + * the end of the number of peers, this is the same as + * nm_setting_wireguard_append_peer(). Otherwise, the + * peer at this index is replaced. + * + * If @idx is one past the last peer, the behavior is the same + * as nm_setting_wireguard_append_peer(). + * Otherwise, the peer will be at @idx and replace the peer + * instance at that index. Note that if a peer with the same + * public-key exists on another index, then that peer will also + * be replaced. In that case, the number of peers will shrink + * by one (because the one at @idx got replace and then one + * with the same public-key got removed). This also means, + * that the resulting index afterwards may be one less than + * @idx (if another peer with a lower index was dropped). + * + * Since: 1.16 + */ +void +nm_setting_wireguard_set_peer(NMSettingWireGuard *self, NMWireGuardPeer *peer, guint idx) +{ + NMSettingWireGuardPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_WIREGUARD(self)); + g_return_if_fail(NM_IS_WIREGUARD_PEER(peer, TRUE)); + + priv = NM_SETTING_WIREGUARD_GET_PRIVATE(self); + + g_return_if_fail(idx <= priv->peers_arr->len); + + if (_peers_set(priv, peer, idx, TRUE)) + _peers_notify(self); +} + +/** + * nm_setting_wireguard_append_peer: + * @self: the #NMSettingWireGuard instance + * @peer: the #NMWireGuardPeer instance to append. + * This seals @peer and keeps a reference on the + * instance. + * + * If a peer with the same public-key already exists, that + * one is replaced by @peer. The new @peer is always appended + * (or moved to) the end, so in case a peer is replaced, the + * indexes are shifted and the number of peers stays unchanged. + * + * Since: 1.16 + */ +void +nm_setting_wireguard_append_peer(NMSettingWireGuard *self, NMWireGuardPeer *peer) +{ + g_return_if_fail(NM_IS_SETTING_WIREGUARD(self)); + g_return_if_fail(NM_IS_WIREGUARD_PEER(peer, TRUE)); + + if (_peers_append(NM_SETTING_WIREGUARD_GET_PRIVATE(self), peer, TRUE)) + _peers_notify(self); +} + +/** + * nm_setting_wireguard_remove_peer + * @self: the #NMSettingWireGuard instance + * @idx: the index to remove. + * + * Returns: %TRUE if @idx was in range and a peer + * was removed. Otherwise, @self is unchanged. + * + * Since: 1.16 + */ +gboolean +nm_setting_wireguard_remove_peer(NMSettingWireGuard *self, guint idx) +{ + NMSettingWireGuardPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), FALSE); + + priv = NM_SETTING_WIREGUARD_GET_PRIVATE(self); + + if (idx >= priv->peers_arr->len) + return FALSE; + + _peers_remove(priv, _peers_get(priv, idx), TRUE); + _peers_notify(self); + return TRUE; +} + +static guint +_peers_clear(NMSettingWireGuardPrivate *priv) +{ + guint l; + + l = priv->peers_arr->len; + while (priv->peers_arr->len > 0) { + _peers_remove(priv, _peers_get(priv, priv->peers_arr->len - 1), TRUE); + } + return l; +} + +/** + * nm_setting_wireguard_: + * @self: the #NMSettingWireGuard instance + * + * Returns: the number of cleared peers. + * + * Since: 1.16 + */ +guint +nm_setting_wireguard_clear_peers(NMSettingWireGuard *self) +{ + guint l; + + g_return_val_if_fail(NM_IS_SETTING_WIREGUARD(self), 0); + + l = _peers_clear(NM_SETTING_WIREGUARD_GET_PRIVATE(self)); + if (l > 0) + _peers_notify(self); + return l; +} + +/*****************************************************************************/ + +static GVariant * +_peers_dbus_only_synth(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + NMSettingWireGuard * self = NM_SETTING_WIREGUARD(setting); + NMSettingWireGuardPrivate *priv; + gboolean any_peers = FALSE; + GVariantBuilder peers_builder; + guint i_peer, n_peers; + guint i; + + n_peers = nm_setting_wireguard_get_peers_len(self); + if (n_peers == 0) + return NULL; + + priv = NM_SETTING_WIREGUARD_GET_PRIVATE(self); + + for (i_peer = 0; i_peer < n_peers; i_peer++) { + const NMWireGuardPeer *peer = _peers_get(priv, i_peer)->peer; + GVariantBuilder builder; + + if (!peer->public_key) + continue; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + + g_variant_builder_add(&builder, + "{sv}", + NM_WIREGUARD_PEER_ATTR_PUBLIC_KEY, + g_variant_new_string(peer->public_key)); + + if (!NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_ONLY_SECRETS) && peer->endpoint) + g_variant_builder_add( + &builder, + "{sv}", + NM_WIREGUARD_PEER_ATTR_ENDPOINT, + g_variant_new_string(nm_sock_addr_endpoint_get_endpoint(peer->endpoint))); + + if (_nm_connection_serialize_secrets(flags, peer->preshared_key_flags) + && peer->preshared_key) + g_variant_builder_add(&builder, + "{sv}", + NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY, + g_variant_new_string(peer->preshared_key)); + + if (!NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + && peer->preshared_key_flags != NM_SETTING_SECRET_FLAG_NOT_REQUIRED) + g_variant_builder_add(&builder, + "{sv}", + NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY_FLAGS, + g_variant_new_uint32(peer->preshared_key_flags)); + + if (!NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + && peer->persistent_keepalive != 0) + g_variant_builder_add(&builder, + "{sv}", + NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE, + g_variant_new_uint32(peer->persistent_keepalive)); + + if (!NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_ONLY_SECRETS) && peer->allowed_ips + && peer->allowed_ips->len > 0) { + const char *const * strv = (const char *const *) peer->allowed_ips->pdata; + gs_free const char **strv_fixed = NULL; + + for (i = 0; i < peer->allowed_ips->len; i++) { + if (strv[i][0] != ALLOWED_IP_INVALID_X) + continue; + if (!strv_fixed) { + strv_fixed = nm_memdup(strv, sizeof(strv[0]) * peer->allowed_ips->len); + strv = strv_fixed; + } + ((const char **) strv)[i]++; + } + g_variant_builder_add(&builder, + "{sv}", + NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS, + g_variant_new_strv(strv, peer->allowed_ips->len)); + } + + if (!any_peers) { + g_variant_builder_init(&peers_builder, G_VARIANT_TYPE("aa{sv}")); + any_peers = TRUE; + } + g_variant_builder_add(&peers_builder, "a{sv}", &builder); + } + + return any_peers ? g_variant_builder_end(&peers_builder) : NULL; +} + +static gboolean +_peers_dbus_only_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + GVariantIter iter_peers; + GVariant * peer_var; + guint i_peer; + gboolean success = FALSE; + gboolean peers_changed = FALSE; + + nm_assert(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}"))); + + g_variant_iter_init(&iter_peers, value); + + i_peer = 0; + while (g_variant_iter_next(&iter_peers, "@a{sv}", &peer_var)) { + _nm_unused gs_unref_variant GVariant *peer_var_unref = peer_var; + nm_auto_unref_wgpeer NMWireGuardPeer *peer = NULL; + const char * cstr; + guint32 u32; + GVariant * var; + + i_peer++; + + if (!g_variant_lookup(peer_var, NM_WIREGUARD_PEER_ATTR_PUBLIC_KEY, "&s", &cstr)) { + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("peer #%u has no public-key"), + i_peer); + goto out; + } + continue; + } + + peer = nm_wireguard_peer_new(); + if (!nm_wireguard_peer_set_public_key(peer, cstr, TRUE)) { + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("peer #%u has invalid public-key"), + i_peer); + goto out; + } + continue; + } + + if (g_variant_lookup(peer_var, NM_WIREGUARD_PEER_ATTR_ENDPOINT, "&s", &cstr)) { + nm_auto_unref_sockaddrendpoint NMSockAddrEndpoint *ep = NULL; + + ep = nm_sock_addr_endpoint_new(cstr); + if (!nm_sock_addr_endpoint_get_host(ep)) { + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("peer #%u has invalid endpoint"), + i_peer); + goto out; + } + } else + _nm_wireguard_peer_set_endpoint(peer, ep); + } + + if (g_variant_lookup(peer_var, NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY, "&s", &cstr)) + nm_wireguard_peer_set_preshared_key(peer, cstr, TRUE); + + if (g_variant_lookup(peer_var, NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY_FLAGS, "u", &u32)) + nm_wireguard_peer_set_preshared_key_flags(peer, u32); + + if (g_variant_lookup(peer_var, NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE, "u", &u32)) + nm_wireguard_peer_set_persistent_keepalive(peer, u32); + + if (g_variant_lookup(peer_var, NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS, "@as", &var)) { + _nm_unused gs_unref_variant GVariant *var_free = var; + gs_free const char ** allowed_ips = NULL; + gsize i, l; + + allowed_ips = g_variant_get_strv(var, &l); + if (allowed_ips) { + for (i = 0; i < l; i++) { + if (_peer_append_allowed_ip(peer, allowed_ips[i], FALSE)) + continue; + if (!NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) + continue; + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("peer #%u has invalid allowed-ips setting"), + i_peer); + goto out; + } + } + } + + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { + gs_free_error GError *local = NULL; + + if (!nm_wireguard_peer_is_valid(peer, TRUE, FALSE, &local)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("peer #%u is invalid: %s"), + i_peer, + local->message); + goto out; + } + } + + /* we could easily reject duplicate peers (by public-key) or duplicate GVariant attributes. + * However, don't do that. In case of duplicate values, the latter peer overwrite the earlier + * and GVariant attributes are ignored by g_variant_lookup() above. */ + if (_peers_append(NM_SETTING_WIREGUARD_GET_PRIVATE(setting), peer, TRUE)) + peers_changed = TRUE; + } + + success = TRUE; + +out: + if (peers_changed) + _peers_notify(setting); + return success; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWireGuard * s_wg = NM_SETTING_WIREGUARD(setting); + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting); + guint i; + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + if (!_nm_utils_secret_flags_validate(nm_setting_wireguard_get_private_key_flags(s_wg), + NM_SETTING_WIREGUARD_SETTING_NAME, + NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS, + NM_SETTING_SECRET_FLAG_NOT_REQUIRED, + error)) + return FALSE; + + for (i = 0; i < priv->peers_arr->len; i++) { + NMWireGuardPeer *peer = _peers_get(priv, i)->peer; + + if (!nm_wireguard_peer_is_valid(peer, TRUE, FALSE, error)) { + g_prefix_error(error, + "%s.%s[%u]: ", + NM_SETTING_WIREGUARD_SETTING_NAME, + NM_SETTING_WIREGUARD_PEERS, + i); + return FALSE; + } + } + + if (connection) { + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + const char * method; + + /* WireGuard is Layer 3 only. For the moment, we only support a restricted set of + * IP methods. We may relax that later, once we fix the implementations so they + * actually work. */ + + if ((s_ip4 = nm_connection_get_setting_ip4_config(connection)) + && (method = nm_setting_ip_config_get_method(s_ip4)) + && !NM_IN_STRSET(method, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("method \"%s\" is not supported for WireGuard"), + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_METHOD); + return FALSE; + } + + if ((s_ip6 = nm_connection_get_setting_ip6_config(connection)) + && (method = nm_setting_ip_config_get_method(s_ip6)) + && !NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("method \"%s\" is not supported for WireGuard"), + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_METHOD); + return FALSE; + } + } + + /* private-key is a secret, hence we cannot verify it like a regular property. */ + return TRUE; +} + +static gboolean +verify_secrets(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting); + guint i; + + if (priv->private_key && !priv->private_key_valid) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("key must be 32 bytes base64 encoded")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIREGUARD_SETTING_NAME, + NM_SETTING_WIREGUARD_PRIVATE_KEY); + return FALSE; + } + + for (i = 0; i < priv->peers_arr->len; i++) { + NMWireGuardPeer *peer = _peers_get(priv, i)->peer; + + if (!nm_wireguard_peer_is_valid(peer, FALSE, TRUE, error)) { + g_prefix_error(error, + "%s.%s[%u]: ", + NM_SETTING_WIREGUARD_SETTING_NAME, + NM_SETTING_WIREGUARD_PEERS, + i); + return FALSE; + } + } + + return TRUE; +} + +static GPtrArray * +need_secrets(NMSetting *setting) +{ + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting); + GPtrArray * secrets = NULL; + guint i; + + if (!priv->private_key || !priv->private_key_valid) { + secrets = g_ptr_array_new_full(1, g_free); + g_ptr_array_add(secrets, g_strdup(NM_SETTING_WIREGUARD_PRIVATE_KEY)); + } + + for (i = 0; i < priv->peers_arr->len; i++) { + NMWireGuardPeer *peer = _peers_get(priv, i)->peer; + + if (NM_FLAGS_HAS(peer->preshared_key_flags, NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) + continue; + + if (peer->preshared_key_valid) + continue; + + if (!peer->public_key_valid) + continue; + + if (!secrets) + secrets = g_ptr_array_new_full(1, g_free); + g_ptr_array_add(secrets, peers_psk_get_secret_name_dup(peer->public_key)); + } + + return secrets; +} + +static gboolean +clear_secrets(const NMSettInfoSetting * sett_info, + guint property_idx, + NMSetting * setting, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) +{ + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_WIREGUARD_PEERS)) { + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting); + gboolean peers_changed = FALSE; + guint i, j; + + j = 0; + for (i = 0; i < priv->peers_arr->len; i++) { + NMWireGuardPeer *peer = _peers_get(priv, i)->peer; + + if (!peer->preshared_key) + continue; + + if (func) { + gs_free char *name_free = NULL; + const char * name; + + /* only stack-allocate (alloca) a few times. */ + if (j++ < 5) + name = peers_psk_get_secret_name_a(peer->public_key, &name_free); + else { + name_free = peers_psk_get_secret_name_dup(peer->public_key); + name = name_free; + } + + if (!func(setting, name, peer->preshared_key_flags, user_data)) + continue; + } + + { + nm_auto_unref_wgpeer NMWireGuardPeer *peer2 = NULL; + + peer2 = nm_wireguard_peer_new_clone(peer, FALSE); + + if (_peers_set(priv, peer2, i, FALSE)) + peers_changed = TRUE; + } + } + + if (peers_changed) + _peers_notify(setting); + return peers_changed; + } + + return NM_SETTING_CLASS(nm_setting_wireguard_parent_class) + ->clear_secrets(sett_info, property_idx, setting, func, user_data); +} + +static int +update_one_secret(NMSetting *setting, const char *key, GVariant *value, GError **error) +{ + NMSettingWireGuard * self = NM_SETTING_WIREGUARD(setting); + NMSettingWireGuardPrivate *priv; + gboolean has_changes = FALSE; + gboolean has_error = FALSE; + GVariantIter iter_peers; + GVariant * peer_var; + guint i_peer; + + if (!nm_streq(key, NM_SETTING_WIREGUARD_PEERS)) { + return NM_SETTING_CLASS(nm_setting_wireguard_parent_class) + ->update_one_secret(setting, key, value, error); + } + + if (!g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}"))) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, + _("invalid peer secrets")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIREGUARD_SETTING_NAME, + NM_SETTING_WIREGUARD_PEERS); + return NM_SETTING_UPDATE_SECRET_ERROR; + } + + priv = NM_SETTING_WIREGUARD_GET_PRIVATE(self); + + g_variant_iter_init(&iter_peers, value); + + i_peer = 0; + while (g_variant_iter_next(&iter_peers, "@a{sv}", &peer_var)) { + _nm_unused gs_unref_variant GVariant *peer_var_unref = peer_var; + nm_auto_unref_wgpeer NMWireGuardPeer *peer = NULL; + PeerData * pd; + const char * cstr; + + i_peer++; + + if (!g_variant_lookup(peer_var, NM_WIREGUARD_PEER_ATTR_PUBLIC_KEY, "&s", &cstr)) { + if (!has_error) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, + _("peer #%u lacks public-key"), + i_peer - 1); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIREGUARD_SETTING_NAME, + NM_SETTING_WIREGUARD_PEERS); + has_error = TRUE; + } + continue; + } + + pd = _peers_get_by_public_key(priv, cstr, TRUE); + if (!pd) { + if (!has_error) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, + _("non-existing peer '%s'"), + cstr); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIREGUARD_SETTING_NAME, + NM_SETTING_WIREGUARD_PEERS); + has_error = TRUE; + } + continue; + } + + if (!g_variant_lookup(peer_var, NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY, "&s", &cstr)) { + /* no preshared-key. Ignore the rest. + * + * In particular, we don't reject all unknown fields. */ + continue; + } + + if (nm_streq0(cstr, nm_wireguard_peer_get_preshared_key(pd->peer))) + continue; + + peer = nm_wireguard_peer_new_clone(pd->peer, FALSE); + nm_wireguard_peer_set_preshared_key(peer, cstr, TRUE); + + if (!_peers_set(priv, peer, pd->idx, FALSE)) + nm_assert_not_reached(); + has_changes = TRUE; + } + + if (has_error) + return NM_SETTING_UPDATE_SECRET_ERROR; + if (has_changes) + return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; + return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingWireGuardPrivate *a_priv; + NMSettingWireGuardPrivate *b_priv; + guint i; + + if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_WIREGUARD_PEERS)) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; + + if (!set_b) + return TRUE; + + a_priv = NM_SETTING_WIREGUARD_GET_PRIVATE(set_a); + b_priv = NM_SETTING_WIREGUARD_GET_PRIVATE(set_b); + + if (a_priv->peers_arr->len != b_priv->peers_arr->len) + return FALSE; + for (i = 0; i < a_priv->peers_arr->len; i++) { + NMWireGuardPeer *a_peer = _peers_get(a_priv, i)->peer; + NMWireGuardPeer *b_peer = _peers_get(b_priv, i)->peer; + + if (nm_wireguard_peer_cmp(a_peer, b_peer, flags) != 0) + return FALSE; + } + + return TRUE; + } + + return NM_SETTING_CLASS(nm_setting_wireguard_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +static void +duplicate_copy_properties(const NMSettInfoSetting *sett_info, NMSetting *src, NMSetting *dst) +{ + NMSettingWireGuardPrivate *priv_src = NM_SETTING_WIREGUARD_GET_PRIVATE(src); + NMSettingWireGuardPrivate *priv_dst = NM_SETTING_WIREGUARD_GET_PRIVATE(dst); + guint i; + gboolean peers_changed = FALSE; + + NM_SETTING_CLASS(nm_setting_wireguard_parent_class) + ->duplicate_copy_properties(sett_info, src, dst); + + /* We don't bother comparing the existing peers with what we are about to set. + * Always reset all. */ + if (_peers_clear(priv_dst) > 0) + peers_changed = TRUE; + for (i = 0; i < priv_src->peers_arr->len; i++) { + if (_peers_append(priv_dst, _peers_get(priv_src, i)->peer, FALSE)) + peers_changed = TRUE; + } + if (peers_changed) + _peers_notify(dst); +} + +static void +enumerate_values(const NMSettInfoProperty *property_info, + NMSetting * setting, + NMSettingValueIterFn func, + gpointer user_data) +{ + if (nm_streq(property_info->name, NM_SETTING_WIREGUARD_PEERS)) { + NMSettingWireGuardPrivate * priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting); + nm_auto_unset_gvalue GValue value = G_VALUE_INIT; + GPtrArray * ptr = NULL; + guint i; + + if (priv->peers_arr && priv->peers_arr->len > 0) { + ptr = g_ptr_array_new_with_free_func((GDestroyNotify) nm_wireguard_peer_unref); + for (i = 0; i < priv->peers_arr->len; i++) + g_ptr_array_add(ptr, nm_wireguard_peer_ref(_peers_get(priv, i)->peer)); + } + g_value_init(&value, G_TYPE_PTR_ARRAY); + g_value_take_boxed(&value, ptr); + func(setting, property_info->name, &value, 0, user_data); + return; + } + + NM_SETTING_CLASS(nm_setting_wireguard_parent_class) + ->enumerate_values(property_info, setting, func, user_data); +} + +static gboolean +aggregate(NMSetting *setting, int type_i, gpointer arg) +{ + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting); + NMConnectionAggregateType type = type_i; + NMSettingSecretFlags secret_flags; + guint i; + + nm_assert(NM_IN_SET(type, + NM_CONNECTION_AGGREGATE_ANY_SECRETS, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS)); + + switch (type) { + case NM_CONNECTION_AGGREGATE_ANY_SECRETS: + if (priv->private_key) + goto out_done; + for (i = 0; i < priv->peers_arr->len; i++) { + if (nm_wireguard_peer_get_preshared_key(_peers_get(priv, i)->peer)) + goto out_done; + } + break; + + case NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS: +#if NM_MORE_ASSERTS + if (!nm_setting_get_secret_flags(setting, + NM_SETTING_WIREGUARD_PRIVATE_KEY, + &secret_flags, + NULL)) + nm_assert_not_reached(); + nm_assert(secret_flags == priv->private_key_flags); +#endif + if (priv->private_key_flags == NM_SETTING_SECRET_FLAG_NONE) + goto out_done; + for (i = 0; i < priv->peers_arr->len; i++) { + secret_flags = nm_wireguard_peer_get_preshared_key_flags(_peers_get(priv, i)->peer); + if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) + goto out_done; + } + break; + } + + return FALSE; + +out_done: + *((gboolean *) arg) = TRUE; + return TRUE; +} + +static gboolean +get_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags *out_flags, + GError ** error) +{ + if (NM_STR_HAS_PREFIX(secret_name, NM_SETTING_WIREGUARD_PEERS ".")) { + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting); + gs_free char * public_key_free = NULL; + const char * public_key; + PeerData * pd; + + public_key = peers_psk_get_secret_parse_a(secret_name, &public_key_free); + if (public_key && (pd = _peers_get_by_public_key(priv, public_key, FALSE))) { + NM_SET_OUT(out_flags, nm_wireguard_peer_get_preshared_key_flags(pd->peer)); + return TRUE; + } + } + + return NM_SETTING_CLASS(nm_setting_wireguard_parent_class) + ->get_secret_flags(setting, secret_name, out_flags, error); +} + +static gboolean +set_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags flags, + GError ** error) +{ + if (NM_STR_HAS_PREFIX(secret_name, NM_SETTING_WIREGUARD_PEERS ".")) { + NMSettingWireGuard * self = NM_SETTING_WIREGUARD(setting); + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(self); + gs_free char * public_key_free = NULL; + const char * public_key; + PeerData * pd; + + public_key = peers_psk_get_secret_parse_a(secret_name, &public_key_free); + if (public_key && (pd = _peers_get_by_public_key(priv, public_key, FALSE))) { + if (nm_wireguard_peer_get_preshared_key_flags(pd->peer) != flags) { + nm_auto_unref_wgpeer NMWireGuardPeer *peer = NULL; + + peer = nm_wireguard_peer_new_clone(pd->peer, TRUE); + peer->preshared_key_flags = flags; + if (_peers_set(priv, peer, pd->idx, FALSE)) + _peers_notify(self); + } + + return TRUE; + } + } + + return NM_SETTING_CLASS(nm_setting_wireguard_parent_class) + ->set_secret_flags(setting, secret_name, flags, error); +} + +static void +for_each_secret(NMSetting * setting, + const char * data_key, + GVariant * data_val, + gboolean remove_non_secrets, + _NMConnectionForEachSecretFunc callback, + gpointer callback_data, + GVariantBuilder * setting_builder) +{ + NMSettingWireGuard * s_wg; + NMSettingWireGuardPrivate *priv; + GVariantBuilder peers_builder; + GVariantIter * peer_iter; + GVariantIter data_iter; + const char * key; + + if (!nm_streq(data_key, NM_SETTING_WIREGUARD_PEERS)) { + NM_SETTING_CLASS(nm_setting_wireguard_parent_class) + ->for_each_secret(setting, + data_key, + data_val, + remove_non_secrets, + callback, + callback_data, + setting_builder); + return; + } + + if (!g_variant_is_of_type(data_val, G_VARIANT_TYPE("aa{sv}"))) { + /* invalid type. Silently ignore content as we cannot find secret-keys + * here. */ + return; + } + + s_wg = NM_SETTING_WIREGUARD(setting); + priv = NM_SETTING_WIREGUARD_GET_PRIVATE(s_wg); + + g_variant_builder_init(&peers_builder, G_VARIANT_TYPE("aa{sv}")); + g_variant_iter_init(&data_iter, data_val); + while (g_variant_iter_next(&data_iter, "a{sv}", &peer_iter)) { + _nm_unused nm_auto_free_variant_iter GVariantIter *peer_iter_free = peer_iter; + gs_unref_variant GVariant *preshared_key = NULL; + PeerData * pd = NULL; + NMSettingSecretFlags secret_flags; + GVariant * val; + GVariantBuilder peer_builder; + + g_variant_builder_init(&peer_builder, G_VARIANT_TYPE("a{sv}")); + + while (g_variant_iter_next(peer_iter, "{&sv}", &key, &val)) { + _nm_unused gs_unref_variant GVariant *val_free = val; + + if (nm_streq(key, NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY)) { + if (!preshared_key && g_variant_is_of_type(val, G_VARIANT_TYPE_STRING)) + preshared_key = g_variant_ref(val); + continue; + } + + if (nm_streq(key, NM_WIREGUARD_PEER_ATTR_PUBLIC_KEY)) { + if (!pd && g_variant_is_of_type(val, G_VARIANT_TYPE_STRING)) + pd = _peers_get_by_public_key(priv, g_variant_get_string(val, NULL), TRUE); + } else if (remove_non_secrets) + continue; + + g_variant_builder_add(&peer_builder, "{sv}", key, val); + } + + if (pd && preshared_key) { + /* without specifying a public-key of an existing peer, the secret is + * ignored. */ + secret_flags = nm_wireguard_peer_get_preshared_key_flags(pd->peer); + if (callback(secret_flags, callback_data)) + g_variant_builder_add(&peer_builder, + "{sv}", + NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY, + preshared_key); + } + + g_variant_builder_add(&peers_builder, "a{sv}", &peer_builder); + } + + g_variant_builder_add(setting_builder, + "{sv}", + NM_SETTING_WIREGUARD_PEERS, + g_variant_builder_end(&peers_builder)); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingWireGuard * setting = NM_SETTING_WIREGUARD(object); + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_FWMARK: + g_value_set_uint(value, priv->fwmark); + break; + case PROP_IP4_AUTO_DEFAULT_ROUTE: + g_value_set_enum(value, priv->ip4_auto_default_route); + break; + case PROP_IP6_AUTO_DEFAULT_ROUTE: + g_value_set_enum(value, priv->ip6_auto_default_route); + break; + case PROP_LISTEN_PORT: + g_value_set_uint(value, priv->listen_port); + break; + case PROP_MTU: + g_value_set_uint(value, priv->mtu); + break; + case PROP_PEER_ROUTES: + g_value_set_boolean(value, priv->peer_routes); + break; + case PROP_PRIVATE_KEY: + g_value_set_string(value, priv->private_key); + break; + case PROP_PRIVATE_KEY_FLAGS: + g_value_set_flags(value, priv->private_key_flags); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(object); + const char * str; + + switch (prop_id) { + case PROP_FWMARK: + priv->fwmark = g_value_get_uint(value); + break; + case PROP_IP4_AUTO_DEFAULT_ROUTE: + priv->ip4_auto_default_route = g_value_get_enum(value); + break; + case PROP_IP6_AUTO_DEFAULT_ROUTE: + priv->ip6_auto_default_route = g_value_get_enum(value); + break; + case PROP_LISTEN_PORT: + priv->listen_port = g_value_get_uint(value); + break; + case PROP_MTU: + priv->mtu = g_value_get_uint(value); + break; + case PROP_PEER_ROUTES: + priv->peer_routes = g_value_get_boolean(value); + break; + case PROP_PRIVATE_KEY: + nm_clear_pointer(&priv->private_key, nm_free_secret); + str = g_value_get_string(value); + if (str) { + if (nm_utils_base64secret_normalize(str, + NM_WIREGUARD_PUBLIC_KEY_LEN, + &priv->private_key)) + priv->private_key_valid = TRUE; + else { + priv->private_key = g_strdup(str); + priv->private_key_valid = FALSE; + } + } + break; + case PROP_PRIVATE_KEY_FLAGS: + priv->private_key_flags = g_value_get_flags(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_wireguard_init(NMSettingWireGuard *setting) +{ + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting); + + priv->peers_arr = g_ptr_array_new(); + priv->peers_hash = g_hash_table_new(nm_pstr_hash, nm_pstr_equal); + priv->peer_routes = TRUE; + priv->ip4_auto_default_route = NM_TERNARY_DEFAULT; + priv->ip6_auto_default_route = NM_TERNARY_DEFAULT; +} + +/** + * nm_setting_wireguard_new: + * + * Creates a new #NMSettingWireGuard object with default values. + * + * Returns: (transfer full): the new empty #NMSettingWireGuard object + * + * Since: 1.16 + **/ +NMSetting * +nm_setting_wireguard_new(void) +{ + return g_object_new(NM_TYPE_SETTING_WIREGUARD, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(object); + + nm_free_secret(priv->private_key); + + _peers_clear(priv); + g_ptr_array_unref(priv->peers_arr); + g_hash_table_unref(priv->peers_hash); + + G_OBJECT_CLASS(nm_setting_wireguard_parent_class)->finalize(object); +} + +static void +nm_setting_wireguard_class_init(NMSettingWireGuardClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->verify_secrets = verify_secrets; + setting_class->need_secrets = need_secrets; + setting_class->clear_secrets = clear_secrets; + setting_class->update_one_secret = update_one_secret; + setting_class->compare_property = compare_property; + setting_class->duplicate_copy_properties = duplicate_copy_properties; + setting_class->enumerate_values = enumerate_values; + setting_class->aggregate = aggregate; + setting_class->get_secret_flags = get_secret_flags; + setting_class->set_secret_flags = set_secret_flags; + setting_class->for_each_secret = for_each_secret; + + /** + * NMSettingWireGuard:private-key: + * + * The 256 bit private-key in base64 encoding. + * + * Since: 1.16 + **/ + obj_properties[PROP_PRIVATE_KEY] = + g_param_spec_string(NM_SETTING_WIREGUARD_PRIVATE_KEY, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireGuard:private-key-flags: + * + * Flags indicating how to handle the #NMSettingWirelessSecurity:private-key + * property. + * + * Since: 1.16 + **/ + obj_properties[PROP_PRIVATE_KEY_FLAGS] = + g_param_spec_flags(NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireGuard:fwmark: + * + * The use of fwmark is optional and is by default off. Setting it to 0 + * disables it. Otherwise, it is a 32-bit fwmark for outgoing packets. + * + * Note that "ip4-auto-default-route" or "ip6-auto-default-route" enabled, + * implies to automatically choose a fwmark. + * + * Since: 1.16 + **/ + obj_properties[PROP_FWMARK] = + g_param_spec_uint(NM_SETTING_WIREGUARD_FWMARK, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireGuard:listen-port: + * + * The listen-port. If listen-port is not specified, the port will be chosen + * randomly when the interface comes up. + * + * Since: 1.16 + **/ + obj_properties[PROP_LISTEN_PORT] = + g_param_spec_uint(NM_SETTING_WIREGUARD_LISTEN_PORT, + "", + "", + 0, + 65535, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireGuard:peer-routes: + * + * Whether to automatically add routes for the AllowedIPs ranges + * of the peers. If %TRUE (the default), NetworkManager will automatically + * add routes in the routing tables according to ipv4.route-table and + * ipv6.route-table. Usually you want this automatism enabled. + * If %FALSE, no such routes are added automatically. In this case, the + * user may want to configure static routes in ipv4.routes and ipv6.routes, + * respectively. + * + * Note that if the peer's AllowedIPs is "0.0.0.0/0" or "::/0" and the profile's + * ipv4.never-default or ipv6.never-default setting is enabled, the peer route for + * this peer won't be added automatically. + * + * Since: 1.16 + **/ + obj_properties[PROP_PEER_ROUTES] = g_param_spec_boolean( + NM_SETTING_WIREGUARD_PEER_ROUTES, + "", + "", + TRUE, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireGuard:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple fragments. + * + * If zero a default MTU is used. Note that contrary to wg-quick's MTU + * setting, this does not take into account the current routes at the + * time of activation. + * + * Since: 1.16 + **/ + obj_properties[PROP_MTU] = + g_param_spec_uint(NM_SETTING_WIREGUARD_MTU, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireGuard:ip4-auto-default-route: + * + * Whether to enable special handling of the IPv4 default route. + * If enabled, the IPv4 default route from wireguard.peer-routes + * will be placed to a dedicated routing-table and two policy routing rules + * will be added. The fwmark number is also used as routing-table for the default-route, + * and if fwmark is zero, an unused fwmark/table is chosen automatically. + * This corresponds to what wg-quick does with Table=auto and what WireGuard + * calls "Improved Rule-based Routing". + * + * Note that for this automatism to work, you usually don't want to set + * ipv4.gateway, because that will result in a conflicting default route. + * + * Leaving this at the default will enable this option automatically + * if ipv4.never-default is not set and there are any peers that use + * a default-route as allowed-ips. + * + * Since: 1.20 + **/ + obj_properties[PROP_IP4_AUTO_DEFAULT_ROUTE] = g_param_spec_enum( + NM_SETTING_WIREGUARD_IP4_AUTO_DEFAULT_ROUTE, + "", + "", + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireGuard:ip6-auto-default-route: + * + * Like ip4-auto-default-route, but for the IPv6 default route. + * + * Since: 1.20 + **/ + obj_properties[PROP_IP6_AUTO_DEFAULT_ROUTE] = g_param_spec_enum( + NM_SETTING_WIREGUARD_IP6_AUTO_DEFAULT_ROUTE, + "", + "", + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /* ---dbus--- + * property: peers + * format: array of 'a{sv}' + * description: Array of dictionaries for the WireGuard peers. + * ---end--- + */ + _nm_properties_override_dbus( + properties_override, + NM_SETTING_WIREGUARD_PEERS, + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = _peers_dbus_only_synth, + .from_dbus_fcn = _peers_dbus_only_set, )); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_WIREGUARD, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-wireless-security.c b/src/libnm-core-impl/nm-setting-wireless-security.c new file mode 100644 index 0000000..6104aea --- /dev/null +++ b/src/libnm-core-impl/nm-setting-wireless-security.c @@ -0,0 +1,1967 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2017 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-wireless-security.h" + +#include "nm-setting-8021x.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" +#include "nm-setting-wireless.h" +#include "libnm-glib-aux/nm-secret-utils.h" + +/** + * SECTION:nm-setting-wireless-security + * @short_description: Describes connection properties for Wi-Fi networks that + * use WEP, LEAP, WPA or WPA2/RSN security + * + * The #NMSettingWirelessSecurity object is a #NMSetting subclass that describes + * properties necessary for connection to encrypted Wi-Fi networks. + * + * It's a good idea to read up on wpa_supplicant configuration before using this + * setting extensively, since most of the options here correspond closely with + * the relevant wpa_supplicant configuration options. To get a better overview + * of how Wi-Fi security works, you may want to get copies of the following books. + * + * 802.11 Wireless Networks: The Definitive Guide, Second Edition + * Author: Matthew Gast + * ISBN: 978-0596100520 + * + * Cisco Wireless LAN Security + * Authors: Krishna Sankar, Sri Sundaralingam, Darrin Miller, and Andrew Balinsky + * ISBN: 978-1587051548 + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingWirelessSecurity, + PROP_KEY_MGMT, + PROP_WEP_TX_KEYIDX, + PROP_AUTH_ALG, + PROP_PROTO, + PROP_PAIRWISE, + PROP_GROUP, + PROP_PMF, + PROP_LEAP_USERNAME, + PROP_WEP_KEY0, + PROP_WEP_KEY1, + PROP_WEP_KEY2, + PROP_WEP_KEY3, + PROP_WEP_KEY_FLAGS, + PROP_WEP_KEY_TYPE, + PROP_PSK, + PROP_PSK_FLAGS, + PROP_LEAP_PASSWORD, + PROP_LEAP_PASSWORD_FLAGS, + PROP_WPS_METHOD, + PROP_FILS, ); + +typedef struct { + GSList * proto; /* GSList of strings */ + GSList * pairwise; /* GSList of strings */ + GSList * group; /* GSList of strings */ + char * key_mgmt; + char * auth_alg; + char * leap_username; + char * leap_password; + char * wep_key0; + char * wep_key1; + char * wep_key2; + char * wep_key3; + char * psk; + NMSettingSecretFlags leap_password_flags; + NMSettingSecretFlags wep_key_flags; + NMSettingSecretFlags psk_flags; + NMSettingWirelessSecurityPmf pmf; + NMWepKeyType wep_key_type; + NMSettingWirelessSecurityWpsMethod wps_method; + NMSettingWirelessSecurityFils fils; + guint32 wep_tx_keyidx; +} NMSettingWirelessSecurityPrivate; + +G_DEFINE_TYPE(NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING) + +#define NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), \ + NM_TYPE_SETTING_WIRELESS_SECURITY, \ + NMSettingWirelessSecurityPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_wireless_security_get_key_mgmt: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:key-mgmt property of the setting + **/ +const char * +nm_setting_wireless_security_get_key_mgmt(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NULL); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->key_mgmt; +} + +/** + * nm_setting_wireless_security_get_num_protos: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the number of security protocols this connection allows when + * connecting to secure Wi-Fi networks + **/ +guint32 +nm_setting_wireless_security_get_num_protos(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), 0); + + return g_slist_length(NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->proto); +} + +/** + * nm_setting_wireless_security_get_proto: + * @setting: the #NMSettingWirelessSecurity + * @i: an index into the protocol list + * + * Returns: the protocol at index @i + **/ +const char * +nm_setting_wireless_security_get_proto(NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NULL); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + g_return_val_if_fail(i <= g_slist_length(priv->proto), NULL); + + return (const char *) g_slist_nth_data(priv->proto, i); +} + +/** + * nm_setting_wireless_security_add_proto: + * @setting: the #NMSettingWirelessSecurity + * @proto: the protocol to add, one of "wpa" or "rsn" + * + * Adds a Wi-Fi security protocol (one of "wpa" or "rsn") to the allowed list; + * only protocols in this list will be used when finding and connecting to + * the Wi-Fi network specified by this connection. For example, if the + * protocol list contains only "wpa" but the access point for the SSID specified + * by this connection only supports WPA2/RSN, the connection cannot be used + * with the access point. + * + * Returns: %TRUE if the protocol was new and was added to the allowed + * protocol list, or %FALSE if it was already in the list + **/ +gboolean +nm_setting_wireless_security_add_proto(NMSettingWirelessSecurity *setting, const char *proto) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), FALSE); + g_return_val_if_fail(proto != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + for (iter = priv->proto; iter; iter = g_slist_next(iter)) { + if (g_ascii_strcasecmp(proto, (char *) iter->data) == 0) + return FALSE; + } + + priv->proto = g_slist_append(priv->proto, g_ascii_strdown(proto, -1)); + _notify(setting, PROP_PROTO); + return TRUE; +} + +/** + * nm_setting_wireless_security_remove_proto: + * @setting: the #NMSettingWirelessSecurity + * @i: index of the protocol to remove + * + * Removes a protocol from the allowed protocol list. + **/ +void +nm_setting_wireless_security_remove_proto(NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList * elt; + + g_return_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + elt = g_slist_nth(priv->proto, i); + g_return_if_fail(elt != NULL); + + g_free(elt->data); + priv->proto = g_slist_delete_link(priv->proto, elt); + _notify(setting, PROP_PROTO); +} + +/** + * nm_setting_wireless_security_remove_proto_by_value: + * @setting: the #NMSettingWirelessSecurity + * @proto: the protocol to remove, one of "wpa" or "rsn" + * + * Removes a protocol from the allowed protocol list. + * + * Returns: %TRUE if the protocol was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_wireless_security_remove_proto_by_value(NMSettingWirelessSecurity *setting, + const char * proto) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), FALSE); + g_return_val_if_fail(proto != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + for (iter = priv->proto; iter; iter = g_slist_next(iter)) { + if (g_ascii_strcasecmp(proto, (char *) iter->data) == 0) { + priv->proto = g_slist_delete_link(priv->proto, iter); + _notify(setting, PROP_PROTO); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wireless_security_clear_protos: + * @setting: the #NMSettingWirelessSecurity + * + * Removes all protocols from the allowed list. If there are no protocols + * specified then all protocols are allowed. + **/ +void +nm_setting_wireless_security_clear_protos(NMSettingWirelessSecurity *setting) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + g_slist_free_full(priv->proto, g_free); + priv->proto = NULL; + _notify(setting, PROP_PROTO); +} + +/** + * nm_setting_wireless_security_get_num_pairwise: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the number of pairwise encryption algorithms in the allowed list + **/ +guint32 +nm_setting_wireless_security_get_num_pairwise(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), 0); + + return g_slist_length(NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->pairwise); +} + +/** + * nm_setting_wireless_security_get_pairwise: + * @setting: the #NMSettingWirelessSecurity + * @i: index of an item in the allowed pairwise encryption algorithm list + * + * Returns the allowed pairwise encryption algorithm from allowed algorithm + * list. + * + * Returns: the pairwise encryption algorithm at index @i + **/ +const char * +nm_setting_wireless_security_get_pairwise(NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NULL); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + g_return_val_if_fail(i <= g_slist_length(priv->pairwise), NULL); + + return (const char *) g_slist_nth_data(priv->pairwise, i); +} + +/** + * nm_setting_wireless_security_add_pairwise: + * @setting: the #NMSettingWirelessSecurity + * @pairwise: the encryption algorithm to add, one of "tkip" or "ccmp" + * + * Adds an encryption algorithm to the list of allowed pairwise encryption + * algorithms. If the list is not empty, then only access points that support + * one or more of the encryption algorithms in the list will be considered + * compatible with this connection. + * + * Returns: %TRUE if the algorithm was added to the list, %FALSE if it was + * already in the list + **/ +gboolean +nm_setting_wireless_security_add_pairwise(NMSettingWirelessSecurity *setting, const char *pairwise) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), FALSE); + g_return_val_if_fail(pairwise != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + for (iter = priv->pairwise; iter; iter = g_slist_next(iter)) { + if (g_ascii_strcasecmp(pairwise, (char *) iter->data) == 0) + return FALSE; + } + + priv->pairwise = g_slist_append(priv->pairwise, g_ascii_strdown(pairwise, -1)); + _notify(setting, PROP_PAIRWISE); + return TRUE; +} + +/** + * nm_setting_wireless_security_remove_pairwise: + * @setting: the #NMSettingWirelessSecurity + * @i: the index of an item in the allowed pairwise encryption algorithm list + * + * Removes an encryption algorithm from the allowed pairwise encryption + * algorithm list. + **/ +void +nm_setting_wireless_security_remove_pairwise(NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList * elt; + + g_return_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + elt = g_slist_nth(priv->pairwise, i); + g_return_if_fail(elt != NULL); + + g_free(elt->data); + priv->pairwise = g_slist_delete_link(priv->pairwise, elt); + _notify(setting, PROP_PAIRWISE); +} + +/** + * nm_setting_wireless_security_remove_pairwise_by_value: + * @setting: the #NMSettingWirelessSecurity + * @pairwise: the encryption algorithm to remove, one of "tkip" or "ccmp" + * + * Removes an encryption algorithm from the allowed pairwise encryption + * algorithm list. + * + * Returns: %TRUE if the encryption algorithm was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_wireless_security_remove_pairwise_by_value(NMSettingWirelessSecurity *setting, + const char * pairwise) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), FALSE); + g_return_val_if_fail(pairwise != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + for (iter = priv->pairwise; iter; iter = g_slist_next(iter)) { + if (g_ascii_strcasecmp(pairwise, (char *) iter->data) == 0) { + priv->pairwise = g_slist_delete_link(priv->pairwise, iter); + _notify(setting, PROP_PAIRWISE); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wireless_security_clear_pairwise: + * @setting: the #NMSettingWirelessSecurity + * + * Removes all algorithms from the allowed list. If there are no algorithms + * specified then all pairwise encryption algorithms are allowed. + **/ +void +nm_setting_wireless_security_clear_pairwise(NMSettingWirelessSecurity *setting) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + g_slist_free_full(priv->pairwise, g_free); + priv->pairwise = NULL; + _notify(setting, PROP_PAIRWISE); +} + +/** + * nm_setting_wireless_security_get_num_groups: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the number of groupwise encryption algorithms in the allowed list + **/ +guint32 +nm_setting_wireless_security_get_num_groups(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), 0); + + return g_slist_length(NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->group); +} + +/** + * nm_setting_wireless_security_get_group: + * @setting: the #NMSettingWirelessSecurity + * @i: index of an item in the allowed groupwise encryption algorithm list + * + * Returns the allowed groupwise encryption algorithm from allowed algorithm + * list. + * + * Returns: the groupwise encryption algorithm at index @i + **/ +const char * +nm_setting_wireless_security_get_group(NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NULL); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + g_return_val_if_fail(i <= g_slist_length(priv->group), NULL); + + return (const char *) g_slist_nth_data(priv->group, i); +} + +/** + * nm_setting_wireless_security_add_group: + * @setting: the #NMSettingWirelessSecurity + * @group: the encryption algorithm to add, one of "wep40", "wep104", + * "tkip", or "ccmp" + * + * Adds an encryption algorithm to the list of allowed groupwise encryption + * algorithms. If the list is not empty, then only access points that support + * one or more of the encryption algorithms in the list will be considered + * compatible with this connection. + * + * Returns: %TRUE if the algorithm was added to the list, %FALSE if it was + * already in the list + **/ +gboolean +nm_setting_wireless_security_add_group(NMSettingWirelessSecurity *setting, const char *group) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), FALSE); + g_return_val_if_fail(group != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + for (iter = priv->group; iter; iter = g_slist_next(iter)) { + if (g_ascii_strcasecmp(group, (char *) iter->data) == 0) + return FALSE; + } + + priv->group = g_slist_append(priv->group, g_ascii_strdown(group, -1)); + _notify(setting, PROP_GROUP); + return TRUE; +} + +/** + * nm_setting_wireless_security_remove_group: + * @setting: the #NMSettingWirelessSecurity + * @i: the index of an item in the allowed groupwise encryption algorithm list + * + * Removes an encryption algorithm from the allowed groupwise encryption + * algorithm list. + **/ +void +nm_setting_wireless_security_remove_group(NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList * elt; + + g_return_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + elt = g_slist_nth(priv->group, i); + g_return_if_fail(elt != NULL); + + g_free(elt->data); + priv->group = g_slist_delete_link(priv->group, elt); + _notify(setting, PROP_GROUP); +} + +/** + * nm_setting_wireless_security_remove_group_by_value: + * @setting: the #NMSettingWirelessSecurity + * @group: the encryption algorithm to remove, one of "wep40", "wep104", + * "tkip", or "ccmp" + * + * Removes an encryption algorithm from the allowed groupwise encryption + * algorithm list. + * + * Returns: %TRUE if the algorithm was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_wireless_security_remove_group_by_value(NMSettingWirelessSecurity *setting, + const char * group) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList * iter; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), FALSE); + g_return_val_if_fail(group != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + for (iter = priv->group; iter; iter = g_slist_next(iter)) { + if (g_ascii_strcasecmp(group, (char *) iter->data) == 0) { + priv->group = g_slist_delete_link(priv->group, iter); + _notify(setting, PROP_GROUP); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wireless_security_clear_groups: + * @setting: the #NMSettingWirelessSecurity + * + * Removes all algorithms from the allowed list. If there are no algorithms + * specified then all groupwise encryption algorithms are allowed. + **/ +void +nm_setting_wireless_security_clear_groups(NMSettingWirelessSecurity *setting) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + g_slist_free_full(priv->group, g_free); + priv->group = NULL; + _notify(setting, PROP_GROUP); +} + +/* + * nm_setting_wireless_security_get_pmf: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:pmf property of the setting + * + * Since: 1.10 + **/ +NMSettingWirelessSecurityPmf +nm_setting_wireless_security_get_pmf(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), 0); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->pmf; +} + +/** + * nm_setting_wireless_security_get_psk: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:psk property of the setting + **/ +const char * +nm_setting_wireless_security_get_psk(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NULL); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->psk; +} + +/** + * nm_setting_wireless_security_get_psk_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSettingWirelessSecurity:psk + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_psk_flags(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->psk_flags; +} + +/** + * nm_setting_wireless_security_get_leap_username: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:leap-username property of the setting + **/ +const char * +nm_setting_wireless_security_get_leap_username(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NULL); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->leap_username; +} + +/** + * nm_setting_wireless_security_get_leap_password: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:leap-password property of the setting + **/ +const char * +nm_setting_wireless_security_get_leap_password(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NULL); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->leap_password; +} + +/** + * nm_setting_wireless_security_get_leap_password_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSettingWirelessSecurity:leap-password + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_leap_password_flags(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->leap_password_flags; +} + +/** + * nm_setting_wireless_security_get_wep_key: + * @setting: the #NMSettingWirelessSecurity + * @idx: the WEP key index (0..3 inclusive) + * + * Returns: the WEP key at the given index + **/ +const char * +nm_setting_wireless_security_get_wep_key(NMSettingWirelessSecurity *setting, guint32 idx) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NULL); + g_return_val_if_fail(idx < 4, NULL); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + if (idx == 0) + return priv->wep_key0; + else if (idx == 1) + return priv->wep_key1; + else if (idx == 2) + return priv->wep_key2; + else if (idx == 3) + return priv->wep_key3; + + g_assert_not_reached(); + return NULL; +} + +/** + * nm_setting_wireless_security_set_wep_key: + * @setting: the #NMSettingWirelessSecurity + * @idx: the index of the key (0..3 inclusive) + * @key: the WEP key as a string, in either hexadecimal, ASCII, or passphrase + * form as determined by the value of the #NMSettingWirelessSecurity:wep-key-type + * property. + * + * Sets a WEP key in the given index. + **/ +void +nm_setting_wireless_security_set_wep_key(NMSettingWirelessSecurity *setting, + guint32 idx, + const char * key) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting)); + g_return_if_fail(idx < 4); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + switch (idx) { + case 0: + g_free(priv->wep_key0); + priv->wep_key0 = g_strdup(key); + _notify(setting, PROP_WEP_KEY0); + break; + case 1: + g_free(priv->wep_key1); + priv->wep_key1 = g_strdup(key); + _notify(setting, PROP_WEP_KEY1); + break; + case 2: + g_free(priv->wep_key2); + priv->wep_key2 = g_strdup(key); + _notify(setting, PROP_WEP_KEY2); + break; + case 3: + g_free(priv->wep_key3); + priv->wep_key3 = g_strdup(key); + _notify(setting, PROP_WEP_KEY3); + break; + default: + g_assert_not_reached(); + } +} + +/** + * nm_setting_wireless_security_get_wep_tx_keyidx: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:wep-tx-keyidx property of the setting + **/ +guint32 +nm_setting_wireless_security_get_wep_tx_keyidx(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), 0); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->wep_tx_keyidx; +} + +/** + * nm_setting_wireless_security_get_auth_alg: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:auth-alg property of the setting + **/ +const char * +nm_setting_wireless_security_get_auth_alg(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NULL); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->auth_alg; +} + +/** + * nm_setting_wireless_security_get_wep_key_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the all WEP keys + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_wep_key_flags(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->wep_key_flags; +} + +/** + * nm_setting_wireless_security_get_wep_key_type: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:wep-key-type property of the setting + **/ +NMWepKeyType +nm_setting_wireless_security_get_wep_key_type(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), 0); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->wep_key_type; +} + +/** + * nm_setting_wireless_security_get_wps_method: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:wps-method property of the setting + * + * Since: 1.10 + **/ +NMSettingWirelessSecurityWpsMethod +nm_setting_wireless_security_get_wps_method(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DISABLED); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->wps_method; +} + +/* + * nm_setting_wireless_security_get_fils: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:fils property of the setting + * + * Since: 1.12 + **/ +NMSettingWirelessSecurityFils +nm_setting_wireless_security_get_fils(NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS_SECURITY(setting), 0); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting)->fils; +} + +static GPtrArray * +need_secrets(NMSetting *setting) +{ + NMSettingWirelessSecurity * self = NM_SETTING_WIRELESS_SECURITY(setting); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(self); + GPtrArray * secrets; + + secrets = g_ptr_array_sized_new(4); + + g_assert(priv->key_mgmt); + + /* Static WEP */ + if (strcmp(priv->key_mgmt, "none") == 0) { + if ((priv->wep_tx_keyidx == 0) + && !nm_utils_wep_key_valid(priv->wep_key0, priv->wep_key_type)) { + g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + return secrets; + } + if ((priv->wep_tx_keyidx == 1) + && !nm_utils_wep_key_valid(priv->wep_key1, priv->wep_key_type)) { + g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1); + return secrets; + } + if ((priv->wep_tx_keyidx == 2) + && !nm_utils_wep_key_valid(priv->wep_key2, priv->wep_key_type)) { + g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2); + return secrets; + } + if ((priv->wep_tx_keyidx == 3) + && !nm_utils_wep_key_valid(priv->wep_key3, priv->wep_key_type)) { + g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); + return secrets; + } + goto no_secrets; + } + + /* WPA-PSK infrastructure */ + if (strcmp(priv->key_mgmt, "wpa-psk") == 0) { + if (!nm_utils_wpa_psk_valid(priv->psk)) { + g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_PSK); + return secrets; + } + goto no_secrets; + } + + /* SAE, used in MESH and WPA3-Personal */ + if (strcmp(priv->key_mgmt, "sae") == 0) { + if (!priv->psk || !*priv->psk) { + g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_PSK); + return secrets; + } + goto no_secrets; + } + + /* LEAP */ + if (priv->auth_alg && !strcmp(priv->auth_alg, "leap") && !strcmp(priv->key_mgmt, "ieee8021x")) { + if (!priv->leap_password || !*priv->leap_password) { + g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD); + return secrets; + } + goto no_secrets; + } + + if (NM_IN_STRSET(priv->key_mgmt, "ieee8021x", "wpa-eap", "owe", "wpa-eap-suite-b-192")) { + /* Let caller check the 802.1x setting for secrets */ + goto no_secrets; + } + + g_assert_not_reached(); + return secrets; + +no_secrets: + if (secrets) + g_ptr_array_free(secrets, TRUE); + return NULL; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWirelessSecurity * self = NM_SETTING_WIRELESS_SECURITY(setting); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(self); + const char * valid_key_mgmt[] = + {"none", "ieee8021x", "wpa-psk", "wpa-eap", "wpa-eap-suite-b-192", "sae", "owe", NULL}; + const char * valid_auth_algs[] = {"open", "shared", "leap", NULL}; + const char * valid_protos[] = {"wpa", "rsn", NULL}; + const char * valid_pairwise[] = {"tkip", "ccmp", NULL}; + const char * valid_groups[] = {"wep40", "wep104", "tkip", "ccmp", NULL}; + NMSettingWireless *s_wifi; + const char * wifi_mode; + + s_wifi = connection ? nm_connection_get_setting_wireless(connection) : NULL; + wifi_mode = s_wifi ? nm_setting_wireless_get_mode(s_wifi) : NULL; + + if (!priv->key_mgmt) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + + if (g_strcmp0(wifi_mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) { + if ((strcmp(priv->key_mgmt, "none") == 0) || (strcmp(priv->key_mgmt, "sae") == 0)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for '%s' mode connections"), + priv->key_mgmt, + NM_SETTING_WIRELESS_MODE_MESH); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + } else { + if (!g_strv_contains(valid_key_mgmt, priv->key_mgmt)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->key_mgmt); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + } + + if (priv->auth_alg && !strcmp(priv->auth_alg, "leap")) { + /* LEAP must use ieee8021x key management */ + if (strcmp(priv->key_mgmt, "ieee8021x")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' security requires '%s=%s'"), + "leap", + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "ieee8021x"); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + if (!priv->leap_username) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + return FALSE; + } + } else { + if (nm_streq(priv->key_mgmt, "ieee8021x") || nm_streq(priv->key_mgmt, "wpa-eap") + || nm_streq(priv->key_mgmt, "wpa-eap-suite-b-192")) { + /* Need an 802.1x setting too */ + if (connection && !nm_connection_get_setting_802_1x(connection)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("'%s' security requires '%s' setting presence"), + priv->key_mgmt, + NM_SETTING_802_1X_SETTING_NAME); + g_prefix_error(error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + } + } + + if (priv->leap_username && !strlen(priv->leap_username)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + return FALSE; + } + + if (priv->wep_tx_keyidx > 3) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' value is out of range <0-3>"), + priv->wep_tx_keyidx); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX); + return FALSE; + } + + if (priv->wep_key_type > NM_WEP_KEY_TYPE_LAST) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE); + return FALSE; + } + + if (priv->auth_alg && !g_strv_contains(valid_auth_algs, priv->auth_alg)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + + if (priv->proto && !_nm_utils_string_slist_validate(priv->proto, valid_protos)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); + return FALSE; + } + + if (priv->pairwise) { + if (!_nm_utils_string_slist_validate(priv->pairwise, valid_pairwise)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + return FALSE; + } + } + + if (priv->group && !_nm_utils_string_slist_validate(priv->group, valid_groups)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); + return FALSE; + } + + /* Shared Key auth can only be used with WEP */ + if (priv->auth_alg && !strcmp(priv->auth_alg, "shared")) { + if (priv->key_mgmt && strcmp(priv->key_mgmt, "none")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' can only be used with '%s=%s' (WEP)"), + "shared", + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "none"); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + } + + G_STATIC_ASSERT_EXPR(((NMSettingWirelessSecurityPmf) -1) > 0); + if (priv->pmf > NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PMF); + return FALSE; + } + + if (NM_IN_SET(priv->pmf, + NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL, + NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) + && !NM_IN_STRSET(priv->key_mgmt, + "wpa-eap", + "wpa-eap-suite-b-192", + "wpa-psk", + "sae", + "owe")) { + g_set_error( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' can only be used with 'wpa-eap', 'wpa-eap-suite-b-192', 'wpa-psk' or 'sae' key " + "management "), + priv->pmf == NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL ? "optional" : "required"); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PMF); + return FALSE; + } + + if (!_nm_utils_wps_method_validate(priv->wps_method, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD, + FALSE, + error)) + return FALSE; + + return TRUE; +} + +static gboolean +_verify_wep_key(const char * wep_key, + NMWepKeyType wep_key_type, + const char * property, + GError ** error) +{ + if (wep_key && !nm_utils_wep_key_valid(wep_key, wep_key_type)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, property); + return FALSE; + } + return TRUE; +} + +static gboolean +verify_secrets(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWirelessSecurity * self = NM_SETTING_WIRELESS_SECURITY(setting); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(self); + + /* LEAP */ + if (priv->auth_alg && !strcmp(priv->auth_alg, "leap") && !strcmp(priv->key_mgmt, "ieee8021x")) { + if (!_nm_setting_verify_secret_string(priv->leap_password, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + error)) + return FALSE; + } + + /* WEP */ + if (!_verify_wep_key(priv->wep_key0, + priv->wep_key_type, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + error)) + return FALSE; + if (!_verify_wep_key(priv->wep_key1, + priv->wep_key_type, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, + error)) + return FALSE; + if (!_verify_wep_key(priv->wep_key2, + priv->wep_key_type, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, + error)) + return FALSE; + if (!_verify_wep_key(priv->wep_key3, + priv->wep_key_type, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, + error)) + return FALSE; + + /* WPA-PSK */ + if (priv->psk && strcmp(priv->key_mgmt, "sae") != 0 && !nm_utils_wpa_psk_valid(priv->psk)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + return FALSE; + } + + return TRUE; +} + +static gboolean +get_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags *out_flags, + GError ** error) +{ + NMSettingSecretFlags flags; + + if (NM_IN_STRSET(secret_name, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) { + /* There's only one 'flags' property for WEP keys, so alias all the WEP key + * property names to that flags property. */ + nm_assert(_nm_setting_property_is_regular_secret(setting, secret_name)); + nm_assert(_nm_setting_property_is_regular_secret_flags( + setting, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS)); + + g_object_get(G_OBJECT(setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, &flags, NULL); + NM_SET_OUT(out_flags, flags); + return TRUE; + } + + return NM_SETTING_CLASS(nm_setting_wireless_security_parent_class) + ->get_secret_flags(setting, secret_name, out_flags, error); +} + +static gboolean +set_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags flags, + GError ** error) +{ + if (NM_IN_STRSET(secret_name, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) { + /* There's only one 'flags' property for WEP keys, so alias all the WEP key + * property names to that flags property. */ + nm_assert(_nm_setting_property_is_regular_secret(setting, secret_name)); + nm_assert(_nm_setting_property_is_regular_secret_flags( + setting, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS)); + + if (!nm_g_object_set_property_flags(G_OBJECT(setting), + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + NM_TYPE_SETTING_SECRET_FLAGS, + flags, + error)) + g_return_val_if_reached(FALSE); + return TRUE; + } + + return NM_SETTING_CLASS(nm_setting_wireless_security_parent_class) + ->set_secret_flags(setting, secret_name, flags, error); +} + +/* NMSettingWirelessSecurity:wep-key-type is an enum, but needs to be marshalled + * as 'u', not 'i', for backward-compatibility. + */ +static GVariant * +wep_key_type_to_dbus(const GValue *from) +{ + return g_variant_new_uint32(g_value_get_enum(from)); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingWirelessSecurity * setting = NM_SETTING_WIRELESS_SECURITY(object); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_KEY_MGMT: + g_value_set_string(value, priv->key_mgmt); + break; + case PROP_WEP_TX_KEYIDX: + g_value_set_uint(value, priv->wep_tx_keyidx); + break; + case PROP_AUTH_ALG: + g_value_set_string(value, priv->auth_alg); + break; + case PROP_PROTO: + g_value_take_boxed(value, _nm_utils_slist_to_strv(priv->proto, TRUE)); + break; + case PROP_PAIRWISE: + g_value_take_boxed(value, _nm_utils_slist_to_strv(priv->pairwise, TRUE)); + break; + case PROP_GROUP: + g_value_take_boxed(value, _nm_utils_slist_to_strv(priv->group, TRUE)); + break; + case PROP_PMF: + g_value_set_int(value, nm_setting_wireless_security_get_pmf(setting)); + break; + case PROP_LEAP_USERNAME: + g_value_set_string(value, priv->leap_username); + break; + case PROP_WEP_KEY0: + g_value_set_string(value, priv->wep_key0); + break; + case PROP_WEP_KEY1: + g_value_set_string(value, priv->wep_key1); + break; + case PROP_WEP_KEY2: + g_value_set_string(value, priv->wep_key2); + break; + case PROP_WEP_KEY3: + g_value_set_string(value, priv->wep_key3); + break; + case PROP_WEP_KEY_FLAGS: + g_value_set_flags(value, priv->wep_key_flags); + break; + case PROP_PSK: + g_value_set_string(value, priv->psk); + break; + case PROP_PSK_FLAGS: + g_value_set_flags(value, priv->psk_flags); + break; + case PROP_LEAP_PASSWORD: + g_value_set_string(value, priv->leap_password); + break; + case PROP_LEAP_PASSWORD_FLAGS: + g_value_set_flags(value, priv->leap_password_flags); + break; + case PROP_WEP_KEY_TYPE: + g_value_set_enum(value, priv->wep_key_type); + break; + case PROP_WPS_METHOD: + g_value_set_uint(value, priv->wps_method); + break; + case PROP_FILS: + g_value_set_int(value, nm_setting_wireless_security_get_fils(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingWirelessSecurity * setting = NM_SETTING_WIRELESS_SECURITY(object); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(setting); + const char * str; + + switch (prop_id) { + case PROP_KEY_MGMT: + g_free(priv->key_mgmt); + str = g_value_get_string(value); + priv->key_mgmt = str ? g_ascii_strdown(str, -1) : NULL; + break; + case PROP_WEP_TX_KEYIDX: + priv->wep_tx_keyidx = g_value_get_uint(value); + break; + case PROP_AUTH_ALG: + g_free(priv->auth_alg); + str = g_value_get_string(value); + priv->auth_alg = str ? g_ascii_strdown(str, -1) : NULL; + break; + case PROP_PROTO: + g_slist_free_full(priv->proto, g_free); + priv->proto = _nm_utils_strv_to_slist(g_value_get_boxed(value), TRUE); + break; + case PROP_PAIRWISE: + g_slist_free_full(priv->pairwise, g_free); + priv->pairwise = _nm_utils_strv_to_slist(g_value_get_boxed(value), TRUE); + break; + case PROP_GROUP: + g_slist_free_full(priv->group, g_free); + priv->group = _nm_utils_strv_to_slist(g_value_get_boxed(value), TRUE); + break; + case PROP_PMF: + priv->pmf = g_value_get_int(value); + break; + case PROP_LEAP_USERNAME: + g_free(priv->leap_username); + priv->leap_username = g_value_dup_string(value); + break; + case PROP_WEP_KEY0: + nm_free_secret(priv->wep_key0); + priv->wep_key0 = g_value_dup_string(value); + break; + case PROP_WEP_KEY1: + nm_free_secret(priv->wep_key1); + priv->wep_key1 = g_value_dup_string(value); + break; + case PROP_WEP_KEY2: + nm_free_secret(priv->wep_key2); + priv->wep_key2 = g_value_dup_string(value); + break; + case PROP_WEP_KEY3: + nm_free_secret(priv->wep_key3); + priv->wep_key3 = g_value_dup_string(value); + break; + case PROP_WEP_KEY_FLAGS: + priv->wep_key_flags = g_value_get_flags(value); + break; + case PROP_PSK: + nm_free_secret(priv->psk); + priv->psk = g_value_dup_string(value); + break; + case PROP_PSK_FLAGS: + priv->psk_flags = g_value_get_flags(value); + break; + case PROP_LEAP_PASSWORD: + nm_free_secret(priv->leap_password); + priv->leap_password = g_value_dup_string(value); + break; + case PROP_LEAP_PASSWORD_FLAGS: + priv->leap_password_flags = g_value_get_flags(value); + break; + case PROP_WEP_KEY_TYPE: + priv->wep_key_type = g_value_get_enum(value); + break; + case PROP_WPS_METHOD: + priv->wps_method = g_value_get_uint(value); + break; + case PROP_FILS: + priv->fils = g_value_get_int(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_wireless_security_init(NMSettingWirelessSecurity *self) +{ + nm_assert(NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(self)->wep_key_type + == NM_WEP_KEY_TYPE_UNKNOWN); + nm_assert(NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(self)->wps_method + == NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT); +} + +/** + * nm_setting_wireless_security_new: + * + * Creates a new #NMSettingWirelessSecurity object with default values. + * + * Returns: (transfer full): the new empty #NMSettingWirelessSecurity object + **/ +NMSetting * +nm_setting_wireless_security_new(void) +{ + return g_object_new(NM_TYPE_SETTING_WIRELESS_SECURITY, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingWirelessSecurity * self = NM_SETTING_WIRELESS_SECURITY(object); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(self); + + g_free(priv->key_mgmt); + g_free(priv->auth_alg); + g_free(priv->leap_username); + nm_free_secret(priv->wep_key0); + nm_free_secret(priv->wep_key1); + nm_free_secret(priv->wep_key2); + nm_free_secret(priv->wep_key3); + nm_free_secret(priv->psk); + nm_free_secret(priv->leap_password); + + g_slist_free_full(priv->proto, g_free); + g_slist_free_full(priv->pairwise, g_free); + g_slist_free_full(priv->group, g_free); + + G_OBJECT_CLASS(nm_setting_wireless_security_parent_class)->finalize(object); +} + +static void +nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingWirelessSecurityPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->verify_secrets = verify_secrets; + setting_class->need_secrets = need_secrets; + setting_class->get_secret_flags = get_secret_flags; + setting_class->set_secret_flags = set_secret_flags; + + /** + * NMSettingWirelessSecurity:key-mgmt: + * + * Key management used for the connection. One of "none" (WEP), + * "ieee8021x" (Dynamic WEP), "wpa-psk" (infrastructure WPA-PSK), "sae" + * (SAE), "owe" (Opportunistic Wireless Encryption), "wpa-eap" + * (WPA-Enterprise) or "wpa-eap-suite-b-192" (WPA3-Enterprise Suite B). + * This property must be set for any Wi-Fi connection that uses security. + **/ + /* ---ifcfg-rh--- + * property: key-mgmt + * variable: KEY_MGMT(+) + * values: IEEE8021X, WPA-PSK, WPA-EAP, WPA-EAP-SUITE-B-192 + * description: Key management menthod. + * ---end--- + */ + obj_properties[PROP_KEY_MGMT] = + g_param_spec_string(NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_REQUIRED | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:wep-tx-keyidx: + * + * When static WEP is used (ie, key-mgmt = "none") and a non-default WEP key + * index is used by the AP, put that WEP key index here. Valid values are 0 + * (default key) through 3. Note that some consumer access points (like the + * Linksys WRT54G) number the keys 1 - 4. + **/ + /* ---ifcfg-rh--- + * property: wep-tx-keyidx + * variable: DEFAULTKEY + * values: 1, 2, 3, 4 + * default: 1 + * description: Index of active WEP key. + * ---end--- + */ + obj_properties[PROP_WEP_TX_KEYIDX] = + g_param_spec_uint(NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, + "", + "", + 0, + 3, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:auth-alg: + * + * When WEP is used (ie, key-mgmt = "none" or "ieee8021x") indicate the + * 802.11 authentication algorithm required by the AP here. One of "open" + * for Open System, "shared" for Shared Key, or "leap" for Cisco LEAP. When + * using Cisco LEAP (ie, key-mgmt = "ieee8021x" and auth-alg = "leap") the + * "leap-username" and "leap-password" properties must be specified. + **/ + /* ---ifcfg-rh--- + * property: auth-alg + * variable: SECURITYMODE(+) + * values: restricted, open, leap + * description: Authentication algorithm for WEP. + * ---end--- + */ + obj_properties[PROP_AUTH_ALG] = g_param_spec_string(NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:proto: + * + * List of strings specifying the allowed WPA protocol versions to use. + * Each element may be one "wpa" (allow WPA) or "rsn" (allow WPA2/RSN). If + * not specified, both WPA and RSN connections are allowed. + **/ + /* ---ifcfg-rh--- + * property: proto + * variable: WPA_ALLOW_WPA(+), WPA_ALLOW_WPA2(+) + * values: yes, no + * default: no + * description: Allowed WPA protocols, WPA and WPA2 (RSN). + * ---end--- + */ + obj_properties[PROP_PROTO] = g_param_spec_boxed(NM_SETTING_WIRELESS_SECURITY_PROTO, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:pairwise: + * + * A list of pairwise encryption algorithms which prevents connections to + * Wi-Fi networks that do not utilize one of the algorithms in the list. + * For maximum compatibility leave this property empty. Each list element + * may be one of "tkip" or "ccmp". + **/ + /* ---ifcfg-rh--- + * property: pairwise + * variable: CIPHER_PAIRWISE(+) + * values: CCMP, TKIP + * description: Restrict pairwise encryption algorithms, specified as a space + * separated list. + * ---end--- + */ + obj_properties[PROP_PAIRWISE] = g_param_spec_boxed(NM_SETTING_WIRELESS_SECURITY_PAIRWISE, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:group: + * + * A list of group/broadcast encryption algorithms which prevents + * connections to Wi-Fi networks that do not utilize one of the algorithms + * in the list. For maximum compatibility leave this property empty. Each + * list element may be one of "wep40", "wep104", "tkip", or "ccmp". + **/ + /* ---ifcfg-rh--- + * property: group + * variable: CIPHER_GROUP(+) + * values: CCMP, TKIP, WEP40, WEP104 + * description: Restrict group/broadcast encryption algorithms, specified as a space + * separated list. + * ---end--- + */ + obj_properties[PROP_GROUP] = g_param_spec_boxed(NM_SETTING_WIRELESS_SECURITY_GROUP, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:pmf: + * + * Indicates whether Protected Management Frames (802.11w) must be enabled + * for the connection. One of %NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT + * (use global default value), %NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE + * (disable PMF), %NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL (enable PMF if + * the supplicant and the access point support it) or + * %NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED (enable PMF and fail if not + * supported). When set to %NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT and no + * global default is set, PMF will be optionally enabled. + * + * Since: 1.10 + **/ + /* ---ifcfg-rh--- + * property: pmf + * variable: PMF(+) + * values: default, disable, optional, required + * description: Enables or disables PMF (802.11w) + * example: PMF=required + * ---end--- + */ + obj_properties[PROP_PMF] = g_param_spec_int(NM_SETTING_WIRELESS_SECURITY_PMF, + "", + "", + G_MININT32, + G_MAXINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:leap-username: + * + * The login username for legacy LEAP connections (ie, key-mgmt = + * "ieee8021x" and auth-alg = "leap"). + **/ + /* ---ifcfg-rh--- + * property: leap-username + * variable: IEEE_8021X_IDENTITY(+) + * description: Login name for LEAP. + * ---end--- + */ + obj_properties[PROP_LEAP_USERNAME] = + g_param_spec_string(NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:wep-key0: + * + * Index 0 WEP key. This is the WEP key used in most networks. See the + * "wep-key-type" property for a description of how this key is interpreted. + **/ + /* ---ifcfg-rh--- + * property: wep-key0 + * variable: KEY1, KEY_PASSPHRASE1(+) + * description: The first WEP key (used in most networks). See also DEFAULTKEY for key index. + * ---end--- + */ + obj_properties[PROP_WEP_KEY0] = + g_param_spec_string(NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:wep-key1: + * + * Index 1 WEP key. This WEP index is not used by most networks. See the + * "wep-key-type" property for a description of how this key is interpreted. + **/ + /* ---ifcfg-rh--- + * property: wep-key1 + * variable: KEY2, KEY_PASSPHRASE2(+) + * description: WEP key with index 1. See also DEFAULTKEY for key index. + * ---end--- + */ + obj_properties[PROP_WEP_KEY1] = + g_param_spec_string(NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:wep-key2: + * + * Index 2 WEP key. This WEP index is not used by most networks. See the + * "wep-key-type" property for a description of how this key is interpreted. + **/ + /* ---ifcfg-rh--- + * property: wep-key2 + * variable: KEY3, KEY_PASSPHRASE3(+) + * description: WEP key with index 2. See also DEFAULTKEY for key index. + * ---end--- + */ + obj_properties[PROP_WEP_KEY2] = + g_param_spec_string(NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:wep-key3: + * + * Index 3 WEP key. This WEP index is not used by most networks. See the + * "wep-key-type" property for a description of how this key is interpreted. + **/ + /* ---ifcfg-rh--- + * property: wep-key3 + * variable: KEY4, KEY_PASSPHRASE4(+) + * description: WEP key with index 3. See also DEFAULTKEY for key index. + * ---end--- + */ + obj_properties[PROP_WEP_KEY3] = + g_param_spec_string(NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:wep-key-flags: + * + * Flags indicating how to handle the #NMSettingWirelessSecurity:wep-key0, + * #NMSettingWirelessSecurity:wep-key1, #NMSettingWirelessSecurity:wep-key2, + * and #NMSettingWirelessSecurity:wep-key3 properties. + **/ + /* ---ifcfg-rh--- + * property: wep-key-flags + * variable: WEP_KEY_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for KEY, KEY_PASSPHRASE password. + * ---end--- + */ + obj_properties[PROP_WEP_KEY_FLAGS] = + g_param_spec_flags(NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:psk: + * + * Pre-Shared-Key for WPA networks. For WPA-PSK, it's either an ASCII + * passphrase of 8 to 63 characters that is (as specified in the 802.11i + * standard) hashed to derive the actual key, or the key in form of 64 + * hexadecimal character. The WPA3-Personal networks use a passphrase + * of any length for SAE authentication. + **/ + /* ---ifcfg-rh--- + * property: psk + * variable: WPA_PSK + * description: Pre-Shared-Key for WPA networks. + * ---end--- + */ + obj_properties[PROP_PSK] = + g_param_spec_string(NM_SETTING_WIRELESS_SECURITY_PSK, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:psk-flags: + * + * Flags indicating how to handle the #NMSettingWirelessSecurity:psk + * property. + **/ + /* ---ifcfg-rh--- + * property: psk-flags + * variable: WPA_PSK_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for WPA_PSK_FLAGS. + * example: WPA_PSK_FLAGS=user + * ---end--- + */ + obj_properties[PROP_PSK_FLAGS] = g_param_spec_flags(NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:leap-password: + * + * The login password for legacy LEAP connections (ie, key-mgmt = + * "ieee8021x" and auth-alg = "leap"). + **/ + /* ---ifcfg-rh--- + * property: leap-password + * variable: IEEE_8021X_PASSWORD(+) + * description: Password for LEAP. It can also go to "key-" + * lookaside file, or it can be owned by a secret agent. + * ---end--- + */ + obj_properties[PROP_LEAP_PASSWORD] = + g_param_spec_string(NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:leap-password-flags: + * + * Flags indicating how to handle the + * #NMSettingWirelessSecurity:leap-password property. + **/ + /* ---ifcfg-rh--- + * property: leap-password-flags + * variable: IEEE_8021X_PASSWORD_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for IEEE_8021X_PASSWORD_FLAGS. + * ---end--- + */ + obj_properties[PROP_LEAP_PASSWORD_FLAGS] = + g_param_spec_flags(NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, + "", + "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:wep-key-type: + * + * Controls the interpretation of WEP keys. Allowed values are + * %NM_WEP_KEY_TYPE_KEY, in which case the key is either a 10- or + * 26-character hexadecimal string, or a 5- or 13-character ASCII password; + * or %NM_WEP_KEY_TYPE_PASSPHRASE, in which case the passphrase is provided + * as a string and will be hashed using the de-facto MD5 method to derive + * the actual WEP key. + **/ + /* ---ifcfg-rh--- + * property: wep-key-type + * variable: KEY or KEY_PASSPHRASE(+); KEY_TYPE(+) + * description: KEY is used for "key" type (10 or 26 hexadecimal characters, + * or 5 or 13 character string prefixed with "s:"). KEY_PASSPHRASE is used + * for WEP passphrases. KEY_TYPE specifies the key type and can be either + * 'key' or 'passphrase'. KEY_TYPE is redundant and can be omitted. + * example: KEY1=s:ahoj, KEY1=0a1c45bc02, KEY_PASSPHRASE1=mysupersecretkey + * ---end--- + */ + obj_properties[PROP_WEP_KEY_TYPE] = + g_param_spec_enum(NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + "", + "", + NM_TYPE_WEP_KEY_TYPE, + NM_WEP_KEY_TYPE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_WEP_KEY_TYPE], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_UINT32, + .gprop_to_dbus_fcn = wep_key_type_to_dbus, )); + + /** + * NMSettingWirelessSecurity:wps-method: + * + * Flags indicating which mode of WPS is to be used if any. + * + * There's little point in changing the default setting as NetworkManager will + * automatically determine whether it's feasible to start WPS enrollment from + * the Access Point capabilities. + * + * WPS can be disabled by setting this property to a value of 1. + * + * Since: 1.10 + **/ + /* ---ifcfg-rh--- + * property: wps-method + * variable: WPS_METHOD + * description: Used to control the WPS methods to be used + * Valid values are "default", "auto", "disabled", "pin" and "pbc". + * If omitted, whatver the AP announces is used. + * example: WPS_METHOD=disabled, WPS_METHOD="pin pbc" + * ---end--- + */ + obj_properties[PROP_WPS_METHOD] = g_param_spec_uint( + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD, + "", + "", + 0, + G_MAXUINT32, + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWirelessSecurity:fils: + * + * Indicates whether Fast Initial Link Setup (802.11ai) must be enabled for + * the connection. One of %NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (use + * global default value), %NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE + * (disable FILS), %NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL (enable FILS + * if the supplicant and the access point support it) or + * %NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED (enable FILS and fail if not + * supported). When set to %NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT and + * no global default is set, FILS will be optionally enabled. + * + * Since: 1.12 + **/ + /* ---ifcfg-rh--- + * property: fils + * variable: FILS(+) + * values: default, disable, optional, required + * description: Enables or disables FILS (802.11ai) + * example: FILS=required + * ---end--- + */ + obj_properties[PROP_FILS] = g_param_spec_int(NM_SETTING_WIRELESS_SECURITY_FILS, + "", + "", + G_MININT32, + G_MAXINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_WIRELESS_SECURITY, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-wireless.c b/src/libnm-core-impl/nm-setting-wireless.c new file mode 100644 index 0000000..54c12c8 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-wireless.c @@ -0,0 +1,1932 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-wireless.h" + +#include + +#include "nm-utils.h" +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-wireless + * @short_description: Describes connection properties for 802.11 Wi-Fi networks + * + * The #NMSettingWireless object is a #NMSetting subclass that describes properties + * necessary for connection to 802.11 Wi-Fi networks. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingWireless, + PROP_SSID, + PROP_MODE, + PROP_BAND, + PROP_CHANNEL, + PROP_BSSID, + PROP_RATE, + PROP_TX_POWER, + PROP_MAC_ADDRESS, + PROP_CLONED_MAC_ADDRESS, + PROP_GENERATE_MAC_ADDRESS_MASK, + PROP_MAC_ADDRESS_BLACKLIST, + PROP_MTU, + PROP_SEEN_BSSIDS, + PROP_HIDDEN, + PROP_POWERSAVE, + PROP_MAC_ADDRESS_RANDOMIZATION, + PROP_WAKE_ON_WLAN, + PROP_AP_ISOLATION, ); + +typedef struct { + GBytes * ssid; + GArray * mac_address_blacklist; + GPtrArray * seen_bssids; + char * mode; + char * band; + char * bssid; + char * device_mac_address; + char * cloned_mac_address; + char * generate_mac_address_mask; + NMSettingMacRandomization mac_address_randomization; + NMTernary ap_isolation; + guint32 channel; + guint32 rate; + guint32 tx_power; + guint32 mtu; + guint32 powersave; + guint32 wowl; + bool hidden : 1; +} NMSettingWirelessPrivate; + +G_DEFINE_TYPE(NMSettingWireless, nm_setting_wireless, NM_TYPE_SETTING) + +#define NM_SETTING_WIRELESS_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessPrivate)) + +/*****************************************************************************/ + +static gboolean +match_cipher(const char *cipher, + const char *expected, + guint32 wpa_flags, + guint32 rsn_flags, + guint32 flag) +{ + if (strcmp(cipher, expected) != 0) + return FALSE; + + if (!(wpa_flags & flag) && !(rsn_flags & flag)) + return FALSE; + + return TRUE; +} + +/** + * nm_setting_wireless_ap_security_compatible: + * @s_wireless: a #NMSettingWireless + * @s_wireless_sec: a #NMSettingWirelessSecurity or %NULL + * @ap_flags: the %NM80211ApFlags of the given access point + * @ap_wpa: the %NM80211ApSecurityFlags of the given access point's WPA + * capabilities + * @ap_rsn: the %NM80211ApSecurityFlags of the given access point's WPA2/RSN + * capabilities + * @ap_mode: the 802.11 mode of the AP, either Ad-Hoc or Infrastructure + * + * Given a #NMSettingWireless and an optional #NMSettingWirelessSecurity, + * determine if the configuration given by the settings is compatible with + * the security of an access point using that access point's capability flags + * and mode. Useful for clients that wish to filter a set of connections + * against a set of access points and determine which connections are + * compatible with which access points. + * + * Returns: %TRUE if the given settings are compatible with the access point's + * security flags and mode, %FALSE if they are not. + */ +gboolean +nm_setting_wireless_ap_security_compatible(NMSettingWireless * s_wireless, + NMSettingWirelessSecurity *s_wireless_sec, + NM80211ApFlags ap_flags, + NM80211ApSecurityFlags ap_wpa, + NM80211ApSecurityFlags ap_rsn, + NM80211Mode ap_mode) +{ + const char *key_mgmt = NULL, *cipher; + guint32 num, i; + gboolean found = FALSE; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(s_wireless), FALSE); + + if (!s_wireless_sec) { + if ((ap_flags & NM_802_11_AP_FLAGS_PRIVACY) || (ap_wpa != NM_802_11_AP_SEC_NONE) + || (ap_rsn != NM_802_11_AP_SEC_NONE)) + return FALSE; + return TRUE; + } + + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wireless_sec); + if (!key_mgmt) + return FALSE; + + /* Static WEP */ + if (!strcmp(key_mgmt, "none")) { + if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY) || (ap_wpa != NM_802_11_AP_SEC_NONE) + || (ap_rsn != NM_802_11_AP_SEC_NONE)) + return FALSE; + return TRUE; + } + + /* Adhoc WPA2 (ie, RSN IBSS) */ + if (ap_mode == NM_802_11_MODE_ADHOC) { + if (strcmp(key_mgmt, "wpa-psk")) + return FALSE; + + /* Ensure the AP has RSN PSK capability */ + if (!(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK)) + return FALSE; + + /* Fall through and check ciphers in generic WPA-PSK code */ + } + + /* Dynamic WEP or LEAP */ + if (!strcmp(key_mgmt, "ieee8021x")) { + if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)) + return FALSE; + + /* If the AP is advertising a WPA IE, make sure it supports WEP ciphers */ + if (ap_wpa != NM_802_11_AP_SEC_NONE) { + if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + + /* quick check; can't use AP if it doesn't support at least one + * WEP cipher in both pairwise and group suites. + */ + if (!(ap_wpa & (NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104)) + || !(ap_wpa & (NM_802_11_AP_SEC_GROUP_WEP40 | NM_802_11_AP_SEC_GROUP_WEP104))) + return FALSE; + + /* Match at least one pairwise cipher with AP's capability if the + * wireless-security setting explicitly lists pairwise ciphers + */ + num = nm_setting_wireless_security_get_num_pairwise(s_wireless_sec); + for (i = 0, found = FALSE; i < num; i++) { + cipher = nm_setting_wireless_security_get_pairwise(s_wireless_sec, i); + if ((found = match_cipher(cipher, + "wep40", + ap_wpa, + ap_wpa, + NM_802_11_AP_SEC_PAIR_WEP40))) + break; + if ((found = match_cipher(cipher, + "wep104", + ap_wpa, + ap_wpa, + NM_802_11_AP_SEC_PAIR_WEP104))) + break; + } + if (!found && num) + return FALSE; + + /* Match at least one group cipher with AP's capability if the + * wireless-security setting explicitly lists group ciphers + */ + num = nm_setting_wireless_security_get_num_groups(s_wireless_sec); + for (i = 0, found = FALSE; i < num; i++) { + cipher = nm_setting_wireless_security_get_group(s_wireless_sec, i); + if ((found = match_cipher(cipher, + "wep40", + ap_wpa, + ap_wpa, + NM_802_11_AP_SEC_GROUP_WEP40))) + break; + if ((found = match_cipher(cipher, + "wep104", + ap_wpa, + ap_wpa, + NM_802_11_AP_SEC_GROUP_WEP104))) + break; + } + if (!found && num) + return FALSE; + } + return TRUE; + } + + /* WPA[2]-PSK and WPA[2] Enterprise */ + if (!strcmp(key_mgmt, "wpa-psk") || !strcmp(key_mgmt, "wpa-eap") || !strcmp(key_mgmt, "sae") + || !strcmp(key_mgmt, "owe")) { + if (!strcmp(key_mgmt, "wpa-psk")) { + if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) + && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK)) + return FALSE; + } else if (!strcmp(key_mgmt, "wpa-eap")) { + if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X) + && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + } else if (!strcmp(key_mgmt, "sae")) { + if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_SAE) + && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_SAE)) + return FALSE; + } else if (!strcmp(key_mgmt, "owe")) { + if (!NM_FLAGS_ANY(ap_wpa, + NM_802_11_AP_SEC_KEY_MGMT_OWE | NM_802_11_AP_SEC_KEY_MGMT_OWE_TM) + && !NM_FLAGS_ANY(ap_rsn, + NM_802_11_AP_SEC_KEY_MGMT_OWE | NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) + return FALSE; + } + + // FIXME: should handle WPA and RSN separately here to ensure that + // if the Connection only uses WPA we don't match a cipher against + // the AP's RSN IE instead + + /* Match at least one pairwise cipher with AP's capability if the + * wireless-security setting explicitly lists pairwise ciphers + */ + num = nm_setting_wireless_security_get_num_pairwise(s_wireless_sec); + for (i = 0, found = FALSE; i < num; i++) { + cipher = nm_setting_wireless_security_get_pairwise(s_wireless_sec, i); + if ((found = match_cipher(cipher, "tkip", ap_wpa, ap_rsn, NM_802_11_AP_SEC_PAIR_TKIP))) + break; + if ((found = match_cipher(cipher, "ccmp", ap_wpa, ap_rsn, NM_802_11_AP_SEC_PAIR_CCMP))) + break; + } + if (!found && num) + return FALSE; + + /* Match at least one group cipher with AP's capability if the + * wireless-security setting explicitly lists group ciphers + */ + num = nm_setting_wireless_security_get_num_groups(s_wireless_sec); + for (i = 0, found = FALSE; i < num; i++) { + cipher = nm_setting_wireless_security_get_group(s_wireless_sec, i); + + if ((found = + match_cipher(cipher, "wep40", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_WEP40))) + break; + if ((found = + match_cipher(cipher, "wep104", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_WEP104))) + break; + if ((found = match_cipher(cipher, "tkip", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_TKIP))) + break; + if ((found = match_cipher(cipher, "ccmp", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_CCMP))) + break; + } + if (!found && num) + return FALSE; + + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_wireless_get_ssid: + * @setting: the #NMSettingWireless + * + * Returns: (transfer none): the #NMSettingWireless:ssid property of the setting + **/ +GBytes * +nm_setting_wireless_get_ssid(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->ssid; +} + +/** + * nm_setting_wireless_get_mode: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:mode property of the setting + **/ +const char * +nm_setting_wireless_get_mode(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->mode; +} + +/** + * nm_setting_wireless_get_band: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:band property of the setting + **/ +const char * +nm_setting_wireless_get_band(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->band; +} + +/** + * nm_setting_wireless_get_channel: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:channel property of the setting + **/ +guint32 +nm_setting_wireless_get_channel(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->channel; +} + +/** + * nm_setting_wireless_get_bssid: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:bssid property of the setting + **/ +const char * +nm_setting_wireless_get_bssid(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->bssid; +} + +/** + * nm_setting_wireless_get_rate: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:rate property of the setting + **/ +guint32 +nm_setting_wireless_get_rate(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->rate; +} + +/** + * nm_setting_wireless_get_tx_power: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:tx-power property of the setting + **/ +guint32 +nm_setting_wireless_get_tx_power(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->tx_power; +} + +/** + * nm_setting_wireless_get_mac_address: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:mac-address property of the setting + **/ +const char * +nm_setting_wireless_get_mac_address(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->device_mac_address; +} + +/** + * nm_setting_wireless_get_cloned_mac_address: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:cloned-mac-address property of the setting + **/ +const char * +nm_setting_wireless_get_cloned_mac_address(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->cloned_mac_address; +} + +/** + * nm_setting_wireless_get_generate_mac_address_mask: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:generate-mac-address-mask property of the setting + * + * Since: 1.4 + **/ +const char * +nm_setting_wireless_get_generate_mac_address_mask(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->generate_mac_address_mask; +} + +/** + * nm_setting_wireless_get_mac_address_blacklist: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:mac-address-blacklist property of the setting + **/ +const char *const * +nm_setting_wireless_get_mac_address_blacklist(NMSettingWireless *setting) +{ + NMSettingWirelessPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NULL); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + return (const char *const *) priv->mac_address_blacklist->data; +} + +/** + * nm_setting_wireless_get_num_mac_blacklist_items: + * @setting: the #NMSettingWireless + * + * Returns: the number of blacklisted MAC addresses + **/ +guint32 +nm_setting_wireless_get_num_mac_blacklist_items(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->mac_address_blacklist->len; +} + +/** + * nm_setting_wireless_get_mac_blacklist_item: + * @setting: the #NMSettingWireless + * @idx: the zero-based index of the MAC address entry + * + * Returns: the blacklisted MAC address string (hex-digits-and-colons notation) + * at index @idx + **/ +const char * +nm_setting_wireless_get_mac_blacklist_item(NMSettingWireless *setting, guint32 idx) +{ + NMSettingWirelessPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NULL); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + g_return_val_if_fail(idx <= priv->mac_address_blacklist->len, NULL); + + return g_array_index(priv->mac_address_blacklist, const char *, idx); +} + +/** + * nm_setting_wireless_add_mac_blacklist_item: + * @setting: the #NMSettingWireless + * @mac: the MAC address string (hex-digits-and-colons notation) to blacklist + * + * Adds a new MAC address to the #NMSettingWireless:mac-address-blacklist property. + * + * Returns: %TRUE if the MAC address was added; %FALSE if the MAC address + * is invalid or was already present + **/ +gboolean +nm_setting_wireless_add_mac_blacklist_item(NMSettingWireless *setting, const char *mac) +{ + NMSettingWirelessPrivate *priv; + const char * candidate; + int i; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), FALSE); + g_return_val_if_fail(mac != NULL, FALSE); + + if (!nm_utils_hwaddr_valid(mac, ETH_ALEN)) + return FALSE; + + priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + candidate = g_array_index(priv->mac_address_blacklist, char *, i); + if (nm_utils_hwaddr_matches(mac, -1, candidate, -1)) + return FALSE; + } + + mac = nm_utils_hwaddr_canonical(mac, ETH_ALEN); + g_array_append_val(priv->mac_address_blacklist, mac); + _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); + return TRUE; +} + +/** + * nm_setting_wireless_remove_mac_blacklist_item: + * @setting: the #NMSettingWireless + * @idx: index number of the MAC address + * + * Removes the MAC address at index @idx from the blacklist. + **/ +void +nm_setting_wireless_remove_mac_blacklist_item(NMSettingWireless *setting, guint32 idx) +{ + NMSettingWirelessPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_WIRELESS(setting)); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + g_return_if_fail(idx < priv->mac_address_blacklist->len); + + g_array_remove_index(priv->mac_address_blacklist, idx); + _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); +} + +/** + * nm_setting_wireless_remove_mac_blacklist_item_by_value: + * @setting: the #NMSettingWireless + * @mac: the MAC address string (hex-digits-and-colons notation) to remove from + * the blacklist + * + * Removes the MAC address @mac from the blacklist. + * + * Returns: %TRUE if the MAC address was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_wireless_remove_mac_blacklist_item_by_value(NMSettingWireless *setting, const char *mac) +{ + NMSettingWirelessPrivate *priv; + const char * candidate; + int i; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), FALSE); + g_return_val_if_fail(mac != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + candidate = g_array_index(priv->mac_address_blacklist, char *, i); + if (!nm_utils_hwaddr_matches(mac, -1, candidate, -1)) { + g_array_remove_index(priv->mac_address_blacklist, i); + _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wireless_clear_mac_blacklist_items: + * @setting: the #NMSettingWireless + * + * Removes all blacklisted MAC addresses. + **/ +void +nm_setting_wireless_clear_mac_blacklist_items(NMSettingWireless *setting) +{ + g_return_if_fail(NM_IS_SETTING_WIRELESS(setting)); + + g_array_set_size(NM_SETTING_WIRELESS_GET_PRIVATE(setting)->mac_address_blacklist, 0); + _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); +} + +/** + * nm_setting_wireless_get_mtu: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:mtu property of the setting + **/ +guint32 +nm_setting_wireless_get_mtu(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->mtu; +} + +/** + * nm_setting_wireless_get_hidden: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:hidden property of the setting + **/ +gboolean +nm_setting_wireless_get_hidden(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), FALSE); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->hidden; +} + +/** + * nm_setting_wireless_get_powersave: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:powersave property of the setting + * + * Since: 1.2 + **/ +guint32 +nm_setting_wireless_get_powersave(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->powersave; +} + +/** + * nm_setting_wireless_get_mac_address_randomization: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:mac-address-randomization property of the + * setting + * + * Since: 1.2 + **/ +NMSettingMacRandomization +nm_setting_wireless_get_mac_address_randomization(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->mac_address_randomization; +} + +/** + * nm_setting_wireless_add_seen_bssid: + * @setting: the #NMSettingWireless + * @bssid: the new BSSID to add to the list + * + * Adds a new Wi-Fi AP's BSSID to the previously seen BSSID list of the setting. + * NetworkManager now tracks previously seen BSSIDs internally so this function + * no longer has much use. Actually, changes you make using this function will + * not be preserved. + * + * Returns: %TRUE if @bssid was already known, %FALSE if not + **/ +gboolean +nm_setting_wireless_add_seen_bssid(NMSettingWireless *setting, const char *bssid) +{ + NMSettingWirelessPrivate *priv; + gs_free char * lower_bssid = NULL; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), FALSE); + g_return_val_if_fail(bssid != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + + lower_bssid = g_ascii_strdown(bssid, -1); + + if (!priv->seen_bssids) { + priv->seen_bssids = g_ptr_array_new_with_free_func(g_free); + } else { + if (nm_utils_strv_find_first((char **) priv->seen_bssids->pdata, + priv->seen_bssids->len, + lower_bssid) + >= 0) + return FALSE; + } + + g_ptr_array_add(priv->seen_bssids, g_steal_pointer(&lower_bssid)); + _notify(setting, PROP_SEEN_BSSIDS); + return TRUE; +} + +/** + * nm_setting_wireless_get_num_seen_bssids: + * @setting: the #NMSettingWireless + * + * Returns: the number of BSSIDs in the previously seen BSSID list + **/ +guint32 +nm_setting_wireless_get_num_seen_bssids(NMSettingWireless *setting) +{ + NMSettingWirelessPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), 0); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + + return priv->seen_bssids ? priv->seen_bssids->len : 0u; +} + +/** + * nm_setting_wireless_get_seen_bssid: + * @setting: the #NMSettingWireless + * @i: index of a BSSID in the previously seen BSSID list + * + * Returns: the BSSID at index @i + **/ +const char * +nm_setting_wireless_get_seen_bssid(NMSettingWireless *setting, guint32 i) +{ + NMSettingWirelessPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), 0); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + + if (!priv->seen_bssids || i >= priv->seen_bssids->len) + return NULL; + + return priv->seen_bssids->pdata[i]; +} + +static GVariant * +_to_dbus_fcn_seen_bssids(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + NMSettingWirelessPrivate *priv; + + if (options && options->seen_bssids) { + return options->seen_bssids[0] ? g_variant_new_strv(options->seen_bssids, -1) : NULL; + } + + priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + + if (!priv->seen_bssids || priv->seen_bssids->len == 0) + return NULL; + + return g_variant_new_strv((const char *const *) priv->seen_bssids->pdata, + priv->seen_bssids->len); +} + +/** + * nm_setting_wireless_get_ap_isolation: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:ap-isolation property of the setting + * + * Since: 1.28 + */ +NMTernary +nm_setting_wireless_get_ap_isolation(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NM_TERNARY_DEFAULT); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->ap_isolation; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + const char * valid_modes[] = {NM_SETTING_WIRELESS_MODE_INFRA, + NM_SETTING_WIRELESS_MODE_ADHOC, + NM_SETTING_WIRELESS_MODE_AP, + NM_SETTING_WIRELESS_MODE_MESH, + NULL}; + const char * valid_bands[] = {"a", "bg", NULL}; + guint i; + gsize length; + GError * local = NULL; + + if (!priv->ssid) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + return FALSE; + } + + length = g_bytes_get_size(priv->ssid); + if (length == 0 || length > 32) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("SSID length is out of range <1-32> bytes")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + return FALSE; + } + + if (priv->mode && !g_strv_contains(valid_modes, priv->mode)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid Wi-Fi mode"), + priv->mode); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + return FALSE; + } + + if (priv->band && !g_strv_contains(valid_bands, priv->band)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid band"), + priv->band); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BAND); + return FALSE; + } + + if (priv->channel && !priv->band) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("'%s' requires setting '%s' property"), + NM_SETTING_WIRELESS_CHANNEL, + NM_SETTING_WIRELESS_BAND); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BAND); + return FALSE; + } + + if (priv->channel) { + if (!nm_utils_wifi_is_channel_valid(priv->channel, priv->band)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' is not a valid channel"), + priv->channel); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_CHANNEL); + return FALSE; + } + } + + if ((g_strcmp0(priv->mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) + && !(priv->channel && priv->band)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("'%s' requires '%s' and '%s' property"), + priv->mode, + NM_SETTING_WIRELESS_BAND, + NM_SETTING_WIRELESS_CHANNEL); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + return FALSE; + } + + if (priv->bssid && !nm_utils_hwaddr_valid(priv->bssid, ETH_ALEN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID); + return FALSE; + } + + if (priv->device_mac_address && !nm_utils_hwaddr_valid(priv->device_mac_address, ETH_ALEN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS); + return FALSE; + } + + if (priv->cloned_mac_address && !NM_CLONED_MAC_IS_SPECIAL(priv->cloned_mac_address) + && !nm_utils_hwaddr_valid(priv->cloned_mac_address, ETH_ALEN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS); + return FALSE; + } + + /* generate-mac-address-mask only makes sense with cloned-mac-address "random" or + * "stable". Still, let's not be so strict about that and accept the value + * even if it is unused. */ + if (!_nm_utils_generate_mac_address_mask_parse(priv->generate_mac_address_mask, + NULL, + NULL, + NULL, + &local)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + local->message); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK); + g_error_free(local); + return FALSE; + } + + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + const char *mac = g_array_index(priv->mac_address_blacklist, const char *, i); + + if (!nm_utils_hwaddr_valid(mac, ETH_ALEN)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid MAC address"), + mac); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); + return FALSE; + } + } + + if (priv->seen_bssids) { + for (i = 0; i < priv->seen_bssids->len; i++) { + const char *b; + + b = priv->seen_bssids->pdata[i]; + if (!nm_utils_hwaddr_valid(b, ETH_ALEN)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid MAC address"), + b); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEEN_BSSIDS); + return FALSE; + } + } + } + + if (!NM_IN_SET(priv->mac_address_randomization, + NM_SETTING_MAC_RANDOMIZATION_DEFAULT, + NM_SETTING_MAC_RANDOMIZATION_NEVER, + NM_SETTING_MAC_RANDOMIZATION_ALWAYS)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid value")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION); + return FALSE; + } + + if (NM_FLAGS_ANY(priv->wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS)) { + if (!nm_utils_is_power_of_two(priv->wowl)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Wake-on-WLAN mode 'default' and 'ignore' are exclusive flags")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_WAKE_ON_WLAN); + return FALSE; + } + } else if (NM_FLAGS_ANY(priv->wowl, ~NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Wake-on-WLAN trying to set unknown flag")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_WAKE_ON_WLAN); + return FALSE; + } + + if (priv->ap_isolation != NM_TERNARY_DEFAULT + && !nm_streq0(priv->mode, NM_SETTING_WIRELESS_MODE_AP)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("AP isolation can be set only in AP mode")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_AP_ISOLATION); + return FALSE; + } + + /* from here on, check for NM_SETTING_VERIFY_NORMALIZABLE conditions. */ + + if (priv->cloned_mac_address) { + if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS + && nm_streq(priv->cloned_mac_address, "random")) + goto mac_addr_rand_ok; + if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_NEVER + && nm_streq(priv->cloned_mac_address, "permanent")) + goto mac_addr_rand_ok; + if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) + goto mac_addr_rand_ok; + } else if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) + goto mac_addr_rand_ok; + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("conflicting value of mac-address-randomization and cloned-mac-address")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS); + return NM_SETTING_VERIFY_NORMALIZABLE; +mac_addr_rand_ok: + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + if (nm_streq(sett_info->property_infos[property_idx].name, + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS)) { + return !set_b + || nm_streq0(NM_SETTING_WIRELESS_GET_PRIVATE(set_a)->cloned_mac_address, + NM_SETTING_WIRELESS_GET_PRIVATE(set_b)->cloned_mac_address); + } + + return NM_SETTING_CLASS(nm_setting_wireless_parent_class) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +} + +/*****************************************************************************/ + +static GVariant * +nm_setting_wireless_get_security(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + if (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + return NULL; + + if (!connection) + return NULL; + + if (!nm_connection_get_setting_wireless_security(connection)) + return NULL; + + return g_variant_new_string(NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); +} + +/** + * nm_setting_wireless_get_wake_on_wlan: + * @setting: the #NMSettingWireless + * + * Returns the Wake-on-WLAN options enabled for the connection + * + * Returns: the Wake-on-WLAN options + * + * Since: 1.12 + */ +NMSettingWirelessWakeOnWLan +nm_setting_wireless_get_wake_on_wlan(NMSettingWireless *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE); + + return NM_SETTING_WIRELESS_GET_PRIVATE(setting)->wowl; +} + +static void +clear_blacklist_item(char **item_p) +{ + g_free(*item_p); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingWireless * setting = NM_SETTING_WIRELESS(object); + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_SSID: + g_value_set_boxed(value, nm_setting_wireless_get_ssid(setting)); + break; + case PROP_MODE: + g_value_set_string(value, nm_setting_wireless_get_mode(setting)); + break; + case PROP_BAND: + g_value_set_string(value, nm_setting_wireless_get_band(setting)); + break; + case PROP_CHANNEL: + g_value_set_uint(value, nm_setting_wireless_get_channel(setting)); + break; + case PROP_BSSID: + g_value_set_string(value, nm_setting_wireless_get_bssid(setting)); + break; + case PROP_RATE: + g_value_set_uint(value, nm_setting_wireless_get_rate(setting)); + break; + case PROP_TX_POWER: + g_value_set_uint(value, nm_setting_wireless_get_tx_power(setting)); + break; + case PROP_MAC_ADDRESS: + g_value_set_string(value, nm_setting_wireless_get_mac_address(setting)); + break; + case PROP_CLONED_MAC_ADDRESS: + g_value_set_string(value, nm_setting_wireless_get_cloned_mac_address(setting)); + break; + case PROP_GENERATE_MAC_ADDRESS_MASK: + g_value_set_string(value, nm_setting_wireless_get_generate_mac_address_mask(setting)); + break; + case PROP_MAC_ADDRESS_BLACKLIST: + g_value_set_boxed(value, (char **) priv->mac_address_blacklist->data); + break; + case PROP_MTU: + g_value_set_uint(value, nm_setting_wireless_get_mtu(setting)); + break; + case PROP_SEEN_BSSIDS: + g_value_take_boxed(value, + priv->seen_bssids ? nm_utils_strv_dup((char **) priv->seen_bssids->pdata, + priv->seen_bssids->len, + TRUE) + : NULL); + break; + case PROP_HIDDEN: + g_value_set_boolean(value, nm_setting_wireless_get_hidden(setting)); + break; + case PROP_POWERSAVE: + g_value_set_uint(value, nm_setting_wireless_get_powersave(setting)); + break; + case PROP_MAC_ADDRESS_RANDOMIZATION: + g_value_set_uint(value, nm_setting_wireless_get_mac_address_randomization(setting)); + break; + case PROP_WAKE_ON_WLAN: + g_value_set_uint(value, nm_setting_wireless_get_wake_on_wlan(setting)); + break; + case PROP_AP_ISOLATION: + g_value_set_enum(value, priv->ap_isolation); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE(object); + const char *const * blacklist; + const char * mac; + gboolean bool_val; + + switch (prop_id) { + case PROP_SSID: + if (priv->ssid) + g_bytes_unref(priv->ssid); + priv->ssid = g_value_dup_boxed(value); + break; + case PROP_MODE: + g_free(priv->mode); + priv->mode = g_value_dup_string(value); + break; + case PROP_BAND: + g_free(priv->band); + priv->band = g_value_dup_string(value); + break; + case PROP_CHANNEL: + priv->channel = g_value_get_uint(value); + break; + case PROP_BSSID: + g_free(priv->bssid); + priv->bssid = g_value_dup_string(value); + break; + case PROP_RATE: + priv->rate = g_value_get_uint(value); + break; + case PROP_TX_POWER: + priv->tx_power = g_value_get_uint(value); + break; + case PROP_MAC_ADDRESS: + g_free(priv->device_mac_address); + priv->device_mac_address = + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); + break; + case PROP_CLONED_MAC_ADDRESS: + bool_val = !!priv->cloned_mac_address; + g_free(priv->cloned_mac_address); + priv->cloned_mac_address = + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); + if (bool_val && !priv->cloned_mac_address) { + /* cloned-mac-address was set before but was now explicitly cleared. + * In this case, we also clear mac-address-randomization flag */ + if (priv->mac_address_randomization != NM_SETTING_MAC_RANDOMIZATION_DEFAULT) { + priv->mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; + _notify(NM_SETTING_WIRELESS(object), PROP_MAC_ADDRESS_RANDOMIZATION); + } + } + break; + case PROP_GENERATE_MAC_ADDRESS_MASK: + g_free(priv->generate_mac_address_mask); + priv->generate_mac_address_mask = g_value_dup_string(value); + break; + case PROP_MAC_ADDRESS_BLACKLIST: + blacklist = g_value_get_boxed(value); + g_array_set_size(priv->mac_address_blacklist, 0); + if (blacklist && blacklist[0]) { + gsize i; + + for (i = 0; blacklist[i]; i++) { + mac = _nm_utils_hwaddr_canonical_or_invalid(blacklist[i], ETH_ALEN); + g_array_append_val(priv->mac_address_blacklist, mac); + } + } + break; + case PROP_MTU: + priv->mtu = g_value_get_uint(value); + break; + case PROP_SEEN_BSSIDS: + { + gs_unref_ptrarray GPtrArray *arr_old = NULL; + const char *const * strv; + + arr_old = g_steal_pointer(&priv->seen_bssids); + + strv = g_value_get_boxed(value); + if (strv && strv[0]) { + gsize i, l; + + l = NM_PTRARRAY_LEN(strv); + priv->seen_bssids = g_ptr_array_new_full(l, g_free); + for (i = 0; i < l; i++) + g_ptr_array_add(priv->seen_bssids, g_strdup(strv[i])); + } + break; + } + case PROP_HIDDEN: + priv->hidden = g_value_get_boolean(value); + break; + case PROP_POWERSAVE: + priv->powersave = g_value_get_uint(value); + break; + case PROP_MAC_ADDRESS_RANDOMIZATION: + priv->mac_address_randomization = g_value_get_uint(value); + break; + case PROP_WAKE_ON_WLAN: + priv->wowl = g_value_get_uint(value); + break; + case PROP_AP_ISOLATION: + priv->ap_isolation = g_value_get_enum(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_wireless_init(NMSettingWireless *setting) +{ + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); + + /* We use GArray rather than GPtrArray so it will automatically be NULL-terminated */ + priv->mac_address_blacklist = g_array_new(TRUE, FALSE, sizeof(char *)); + g_array_set_clear_func(priv->mac_address_blacklist, (GDestroyNotify) clear_blacklist_item); + + priv->wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT; + priv->ap_isolation = NM_TERNARY_DEFAULT; +} + +/** + * nm_setting_wireless_new: + * + * Creates a new #NMSettingWireless object with default values. + * + * Returns: (transfer full): the new empty #NMSettingWireless object + **/ +NMSetting * +nm_setting_wireless_new(void) +{ + return g_object_new(NM_TYPE_SETTING_WIRELESS, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE(object); + + g_free(priv->mode); + g_free(priv->band); + + if (priv->ssid) + g_bytes_unref(priv->ssid); + g_free(priv->bssid); + g_free(priv->device_mac_address); + g_free(priv->cloned_mac_address); + g_free(priv->generate_mac_address_mask); + g_array_unref(priv->mac_address_blacklist); + nm_clear_pointer(&priv->seen_bssids, g_ptr_array_unref); + + G_OBJECT_CLASS(nm_setting_wireless_parent_class)->finalize(object); +} + +static void +nm_setting_wireless_class_init(NMSettingWirelessClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray * properties_override = _nm_sett_info_property_override_create_array(); + + g_type_class_add_private(klass, sizeof(NMSettingWirelessPrivate)); + + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + setting_class->compare_property = compare_property; + + /** + * NMSettingWireless:ssid: + * + * SSID of the Wi-Fi network. Must be specified. + **/ + /* ---keyfile--- + * property: ssid + * format: string (or decimal-byte list - obsolete) + * description: SSID of Wi-Fi network. + * example: ssid=Quick Net + * ---end--- + * ---ifcfg-rh--- + * property: ssid + * variable: ESSID + * description: SSID of Wi-Fi network. + * example: ESSID="Quick Net" + * ---end--- + */ + obj_properties[PROP_SSID] = g_param_spec_boxed(NM_SETTING_WIRELESS_SSID, + "", + "", + G_TYPE_BYTES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:mode: + * + * Wi-Fi network mode; one of "infrastructure", "mesh", "adhoc" or "ap". If blank, + * infrastructure is assumed. + **/ + /* ---ifcfg-rh--- + * property: mode + * variable: MODE + * values: Ad-Hoc, Managed (Auto) [case insensitive] + * description: Wi-Fi network mode. + * ---end--- + */ + obj_properties[PROP_MODE] = g_param_spec_string(NM_SETTING_WIRELESS_MODE, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:band: + * + * 802.11 frequency band of the network. One of "a" for 5GHz 802.11a or + * "bg" for 2.4GHz 802.11. This will lock associations to the Wi-Fi network + * to the specific band, i.e. if "a" is specified, the device will not + * associate with the same network in the 2.4GHz band even if the network's + * settings are compatible. This setting depends on specific driver + * capability and may not work with all drivers. + **/ + /* ---ifcfg-rh--- + * property: band + * variable: BAND(+) + * values: a, bg + * description: BAND alone is honored, but CHANNEL overrides BAND since it + * implies a band. + * example: BAND=bg + * ---end--- + */ + obj_properties[PROP_BAND] = g_param_spec_string(NM_SETTING_WIRELESS_BAND, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:channel: + * + * Wireless channel to use for the Wi-Fi connection. The device will only + * join (or create for Ad-Hoc networks) a Wi-Fi network on the specified + * channel. Because channel numbers overlap between bands, this property + * also requires the "band" property to be set. + **/ + /* ---ifcfg-rh--- + * property: channel + * variable: CHANNEL + * description: Channel used for the Wi-Fi communication. + * Channels greater than 14 mean "a" band, otherwise the + * band is "bg". + * example: CHANNEL=6 + * ---end--- + */ + obj_properties[PROP_CHANNEL] = g_param_spec_uint(NM_SETTING_WIRELESS_CHANNEL, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:bssid: + * + * If specified, directs the device to only associate with the given access + * point. This capability is highly driver dependent and not supported by + * all devices. Note: this property does not control the BSSID used when + * creating an Ad-Hoc network and is unlikely to in the future. + **/ + /* ---ifcfg-rh--- + * property: bssid + * variable: BSSID(+) + * description: Restricts association only to a single AP. + * example: BSSID=00:1E:BD:64:83:21 + * ---end--- + */ + obj_properties[PROP_BSSID] = g_param_spec_string(NM_SETTING_WIRELESS_BSSID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_BSSID], + &nm_sett_info_propert_type_mac_address); + + /** + * NMSettingWireless:rate: + * + * If non-zero, directs the device to only use the specified bitrate for + * communication with the access point. Units are in Kb/s, ie 5500 = 5.5 + * Mbit/s. This property is highly driver dependent and not all devices + * support setting a static bitrate. + **/ + /* ---ifcfg-rh--- + * property: rate + * variable: (none) + * description: This property is not handled by ifcfg-rh plugin. + * ---end--- + */ + obj_properties[PROP_RATE] = g_param_spec_uint(NM_SETTING_WIRELESS_RATE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:tx-power: + * + * If non-zero, directs the device to use the specified transmit power. + * Units are dBm. This property is highly driver dependent and not all + * devices support setting a static transmit power. + **/ + /* ---ifcfg-rh--- + * property: tx-power + * variable: (none) + * description: This property is not handled by ifcfg-rh plugin. + * ---end--- + */ + obj_properties[PROP_TX_POWER] = g_param_spec_uint( + NM_SETTING_WIRELESS_TX_POWER, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:mac-address: + * + * If specified, this connection will only apply to the Wi-Fi device whose + * permanent MAC address matches. This property does not change the MAC + * address of the device (i.e. MAC spoofing). + **/ + /* ---keyfile--- + * property: mac-address + * format: usual hex-digits-and-colons notation + * description: MAC address in traditional hex-digits-and-colons notation + * (e.g. 00:22:68:12:79:A2), or semicolon separated list of 6 bytes (obsolete) + * (e.g. 0;34;104;18;121;162). + * ---end--- + * ---ifcfg-rh--- + * property: mac-address + * variable: HWADDR + * description: Hardware address of the device in traditional hex-digits-and-colons + * notation (e.g. 00:22:68:14:5A:05). + * Note that for initscripts this is the current MAC address of the device as found + * during ifup. For NetworkManager this is the permanent MAC address. Or in case no + * permanent MAC address exists, the MAC address initially configured on the device. + * ---end--- + */ + obj_properties[PROP_MAC_ADDRESS] = + g_param_spec_string(NM_SETTING_WIRELESS_MAC_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_MAC_ADDRESS], + &nm_sett_info_propert_type_mac_address); + + /** + * NMSettingWireless:cloned-mac-address: + * + * If specified, request that the device use this MAC address instead. + * This is known as MAC cloning or spoofing. + * + * Beside explicitly specifying a MAC address, the special values "preserve", "permanent", + * "random" and "stable" are supported. + * "preserve" means not to touch the MAC address on activation. + * "permanent" means to use the permanent hardware address of the device. + * "random" creates a random MAC address on each connect. + * "stable" creates a hashed MAC address based on connection.stable-id and a + * machine dependent key. + * + * If unspecified, the value can be overwritten via global defaults, see manual + * of NetworkManager.conf. If still unspecified, it defaults to "preserve" + * (older versions of NetworkManager may use a different default value). + * + * On D-Bus, this field is expressed as "assigned-mac-address" or the deprecated + * "cloned-mac-address". + **/ + /* ---keyfile--- + * property: cloned-mac-address + * format: usual hex-digits-and-colons notation + * description: Cloned MAC address in traditional hex-digits-and-colons notation + * (e.g. 00:22:68:12:79:B2), or semicolon separated list of 6 bytes (obsolete) + * (e.g. 0;34;104;18;121;178). + * ---end--- + * ---ifcfg-rh--- + * property: cloned-mac-address + * variable: MACADDR + * description: Cloned (spoofed) MAC address in traditional hex-digits-and-colons + * notation (e.g. 00:22:68:14:5A:99). + * ---end--- + * ---dbus--- + * property: cloned-mac-address + * format: byte array + * description: This D-Bus field is deprecated in favor of "assigned-mac-address" + * which is more flexible and allows specifying special variants like "random". + * For libnm and nmcli, this field is called "cloned-mac-address". + * ---end--- + */ + obj_properties[PROP_CLONED_MAC_ADDRESS] = g_param_spec_string( + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_CLONED_MAC_ADDRESS], + &nm_sett_info_propert_type_cloned_mac_address); + + /* ---dbus--- + * property: assigned-mac-address + * format: string + * description: The new field for the cloned MAC address. It can be either + * a hardware address in ASCII representation, or one of the special values + * "preserve", "permanent", "random" or "stable". + * This field replaces the deprecated "cloned-mac-address" on D-Bus, which + * can only contain explicit hardware addresses. Note that this property + * only exists in D-Bus API. libnm and nmcli continue to call this property + * "cloned-mac-address". + * ---end--- + */ + _nm_properties_override_dbus(properties_override, + "assigned-mac-address", + &nm_sett_info_propert_type_assigned_mac_address); + + /** + * NMSettingWireless:generate-mac-address-mask: + * + * With #NMSettingWireless:cloned-mac-address setting "random" or "stable", + * by default all bits of the MAC address are scrambled and a locally-administered, + * unicast MAC address is created. This property allows to specify that certain bits + * are fixed. Note that the least significant bit of the first MAC address will + * always be unset to create a unicast MAC address. + * + * If the property is %NULL, it is eligible to be overwritten by a default + * connection setting. If the value is still %NULL or an empty string, the + * default is to create a locally-administered, unicast MAC address. + * + * If the value contains one MAC address, this address is used as mask. The set + * bits of the mask are to be filled with the current MAC address of the device, + * while the unset bits are subject to randomization. + * Setting "FE:FF:FF:00:00:00" means to preserve the OUI of the current MAC address + * and only randomize the lower 3 bytes using the "random" or "stable" algorithm. + * + * If the value contains one additional MAC address after the mask, + * this address is used instead of the current MAC address to fill the bits + * that shall not be randomized. For example, a value of + * "FE:FF:FF:00:00:00 68:F7:28:00:00:00" will set the OUI of the MAC address + * to 68:F7:28, while the lower bits are randomized. A value of + * "02:00:00:00:00:00 00:00:00:00:00:00" will create a fully scrambled + * globally-administered, burned-in MAC address. + * + * If the value contains more than one additional MAC addresses, one of + * them is chosen randomly. For example, "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00" + * will create a fully scrambled MAC address, randomly locally or globally + * administered. + **/ + /* ---ifcfg-rh--- + * property: generate-mac-address-mask + * variable: GENERATE_MAC_ADDRESS_MASK(+) + * description: the MAC address mask for generating randomized and stable + * cloned-mac-address. + * ---end--- + */ + obj_properties[PROP_GENERATE_MAC_ADDRESS_MASK] = g_param_spec_string( + NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:mac-address-blacklist: + * + * A list of permanent MAC addresses of Wi-Fi devices to which this + * connection should never apply. Each MAC address should be given in the + * standard hex-digits-and-colons notation (eg "00:11:22:33:44:55"). + **/ + /* ---keyfile--- + * property: mac-address-blacklist + * format: list of MACs (separated with semicolons) + * description: MAC address blacklist. + * example: mac-address-blacklist= 00:22:68:12:79:A6;00:22:68:12:79:78 + * ---end--- + * ---ifcfg-rh--- + * property: mac-address-blacklist + * variable: HWADDR_BLACKLIST(+) + * description: It denies usage of the connection for any device whose address + * is listed. + * ---end--- + */ + obj_properties[PROP_MAC_ADDRESS_BLACKLIST] = g_param_spec_boxed( + NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:seen-bssids: + * + * A list of BSSIDs (each BSSID formatted as a MAC address like + * "00:11:22:33:44:55") that have been detected as part of the Wi-Fi + * network. NetworkManager internally tracks previously seen BSSIDs. The + * property is only meant for reading and reflects the BSSID list of + * NetworkManager. The changes you make to this property will not be + * preserved. + **/ + /* ---ifcfg-rh--- + * property: seen-bssids + * variable: (none) + * description: This property is not handled by ifcfg-rh plugin. + * ---end--- + */ + obj_properties[PROP_SEEN_BSSIDS] = g_param_spec_boxed( + NM_SETTING_WIRELESS_SEEN_BSSIDS, + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_SEEN_BSSIDS], + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING_ARRAY, + .to_dbus_fcn = _to_dbus_fcn_seen_bssids, )); + + /** + * NMSettingWireless:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple Ethernet frames. + **/ + /* ---ifcfg-rh--- + * property: mtu + * variable: MTU + * description: MTU of the wireless interface. + * ---end--- + */ + obj_properties[PROP_MTU] = g_param_spec_uint(NM_SETTING_WIRELESS_MTU, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:hidden: + * + * If %TRUE, indicates that the network is a non-broadcasting network that + * hides its SSID. This works both in infrastructure and AP mode. + * + * In infrastructure mode, various workarounds are used for a more reliable + * discovery of hidden networks, such as probe-scanning the SSID. However, + * these workarounds expose inherent insecurities with hidden SSID networks, + * and thus hidden SSID networks should be used with caution. + * + * In AP mode, the created network does not broadcast its SSID. + * + * Note that marking the network as hidden may be a privacy issue for you + * (in infrastructure mode) or client stations (in AP mode), as the explicit + * probe-scans are distinctly recognizable on the air. + * + **/ + /* ---ifcfg-rh--- + * property: hidden + * variable: SSID_HIDDEN(+) + * description: Whether the network hides the SSID. + * ---end--- + */ + obj_properties[PROP_HIDDEN] = g_param_spec_boolean(NM_SETTING_WIRELESS_HIDDEN, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:powersave: + * + * One of %NM_SETTING_WIRELESS_POWERSAVE_DISABLE (disable Wi-Fi power + * saving), %NM_SETTING_WIRELESS_POWERSAVE_ENABLE (enable Wi-Fi power + * saving), %NM_SETTING_WIRELESS_POWERSAVE_IGNORE (don't touch currently + * configure setting) or %NM_SETTING_WIRELESS_POWERSAVE_DEFAULT (use the + * globally configured value). All other values are reserved. + * + * Since: 1.2 + **/ + /* ---ifcfg-rh--- + * property: powersave + * variable: POWERSAVE(+) + * values: default, ignore, enable, disable + * description: Enables or disables Wi-Fi power saving. + * example: POWERSAVE=enable + * ---end--- + */ + obj_properties[PROP_POWERSAVE] = g_param_spec_uint(NM_SETTING_WIRELESS_POWERSAVE, + "", + "", + 0, + G_MAXUINT32, + NM_SETTING_WIRELESS_POWERSAVE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:mac-address-randomization: + * + * One of %NM_SETTING_MAC_RANDOMIZATION_DEFAULT (never randomize unless + * the user has set a global default to randomize and the supplicant + * supports randomization), %NM_SETTING_MAC_RANDOMIZATION_NEVER (never + * randomize the MAC address), or %NM_SETTING_MAC_RANDOMIZATION_ALWAYS + * (always randomize the MAC address). This property is deprecated for + * 'cloned-mac-address'. + * + * Since: 1.2 + * Deprecated: 1.4: Deprecated by NMSettingWireless:cloned-mac-address property. + **/ + /* ---ifcfg-rh--- + * property: mac-address-randomization + * variable: MAC_ADDRESS_RANDOMIZATION(+) + * values: default, never, always + * description: Enables or disables Wi-Fi MAC address randomization. + * example: MAC_ADDRESS_RANDOMIZATION=always + * ---end--- + */ + obj_properties[PROP_MAC_ADDRESS_RANDOMIZATION] = + g_param_spec_uint(NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, + "", + "", + 0, + G_MAXUINT32, + NM_SETTING_MAC_RANDOMIZATION_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /* Compatibility for deprecated property */ + /* ---ifcfg-rh--- + * property: security + * variable: (none) + * description: This property is deprecated and not handled by ifcfg-rh-plugin. + * ---end--- + * ---dbus--- + * property: security + * description: This property is deprecated, but can be set to the value + * '802-11-wireless-security' when a wireless security setting is also + * present in the connection dictionary, for compatibility with very old + * NetworkManager daemons. + * ---end--- + */ + _nm_properties_override_dbus( + properties_override, + "security", + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING, + .to_dbus_fcn = nm_setting_wireless_get_security, )); + + /** + * NMSettingWireless:wake-on-wlan: + * + * The #NMSettingWirelessWakeOnWLan options to enable. Not all devices support all options. + * May be any combination of %NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY, + * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT, + * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC, + * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE, + * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST, + * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE, + * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE, + * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP or the special values + * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT (to use global settings) and + * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE (to disable management of Wake-on-LAN in + * NetworkManager). + * + * Since: 1.12 + **/ + obj_properties[PROP_WAKE_ON_WLAN] = + g_param_spec_uint(NM_SETTING_WIRELESS_WAKE_ON_WLAN, + "", + "", + 0, + G_MAXUINT32, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWireless:ap-isolation + * + * Configures AP isolation, which prevents communication between + * wireless devices connected to this AP. This property can be set + * to a value different from %NM_TERNARY_DEFAULT only when the + * interface is configured in AP mode. + * + * If set to %NM_TERNARY_TRUE, devices are not able to communicate + * with each other. This increases security because it protects + * devices against attacks from other clients in the network. At + * the same time, it prevents devices to access resources on the + * same wireless networks as file shares, printers, etc. + * + * If set to %NM_TERNARY_FALSE, devices can talk to each other. + * + * When set to %NM_TERNARY_DEFAULT, the global default is used; in + * case the global default is unspecified it is assumed to be + * %NM_TERNARY_FALSE. + * + * Since: 1.28 + **/ + /* ---ifcfg-rh--- + * property: ap-isolation + * variable: AP_ISOLATION(+) + * values: "yes", "no" + * default: missing variable means global default + * description: Whether AP isolation is enabled + * ---end--- + */ + obj_properties[PROP_AP_ISOLATION] = g_param_spec_enum( + NM_SETTING_WIRELESS_AP_ISOLATION, + "", + "", + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit_full(setting_class, + NM_META_SETTING_TYPE_WIRELESS, + NULL, + properties_override); +} diff --git a/src/libnm-core-impl/nm-setting-wpan.c b/src/libnm-core-impl/nm-setting-wpan.c new file mode 100644 index 0000000..28a6478 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-wpan.c @@ -0,0 +1,393 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Lubomir Rintel + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-wpan.h" + +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-wpan + * @short_description: Describes connection properties for IEEE 802.15.4 (WPAN) MAC + * + * The #NMSettingWpan object is a #NMSetting subclass that describes properties + * necessary for configuring IEEE 802.15.4 (WPAN) MAC layer devices. + **/ + +/* Ideally we'll be able to get these from a public header. */ +#ifndef IEEE802154_ADDR_LEN + #define IEEE802154_ADDR_LEN 8 +#endif + +#ifndef IEEE802154_MAX_PAGE + #define IEEE802154_MAX_PAGE 31 +#endif + +#ifndef IEEE802154_MAX_CHANNEL + #define IEEE802154_MAX_CHANNEL 26 +#endif + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_MAC_ADDRESS, + PROP_PAN_ID, + PROP_SHORT_ADDRESS, + PROP_PAGE, + PROP_CHANNEL, ); + +typedef struct { + char * mac_address; + guint16 pan_id; + guint16 short_address; + gint16 page; + gint16 channel; +} NMSettingWpanPrivate; + +/** + * NMSettingWpan: + * + * IEEE 802.15.4 (WPAN) MAC Settings + */ +struct _NMSettingWpan { + NMSetting parent; +}; + +struct _NMSettingWpanClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingWpan, nm_setting_wpan, NM_TYPE_SETTING) + +#define NM_SETTING_WPAN_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_WPAN, NMSettingWpanPrivate)) + +/*****************************************************************************/ + +/** + * nm_setting_wpan_get_mac_address: + * @setting: the #NMSettingWpan + * + * Returns: the #NMSettingWpan:mac-address property of the setting + * + * Since: 1.14 + **/ +const char * +nm_setting_wpan_get_mac_address(NMSettingWpan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WPAN(setting), NULL); + + return NM_SETTING_WPAN_GET_PRIVATE(setting)->mac_address; +} + +/** + * nm_setting_wpan_get_pan_id: + * @setting: the #NMSettingWpan + * + * Returns: the #NMSettingWpan:pan-id property of the setting + * + * Since: 1.14 + **/ +guint16 +nm_setting_wpan_get_pan_id(NMSettingWpan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WPAN(setting), G_MAXUINT16); + + return NM_SETTING_WPAN_GET_PRIVATE(setting)->pan_id; +} + +/** + * nm_setting_wpan_get_short_address: + * @setting: the #NMSettingWpan + * + * Returns: the #NMSettingWpan:short-address property of the setting + * + * Since: 1.14 + **/ +guint16 +nm_setting_wpan_get_short_address(NMSettingWpan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WPAN(setting), G_MAXUINT16); + + return NM_SETTING_WPAN_GET_PRIVATE(setting)->short_address; +} + +/** + * nm_setting_wpan_get_page: + * @setting: the #NMSettingWpan + * + * Returns: the #NMSettingWpan:page property of the setting + * + * Since: 1.16 + **/ +gint16 +nm_setting_wpan_get_page(NMSettingWpan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WPAN(setting), NM_SETTING_WPAN_PAGE_DEFAULT); + + return NM_SETTING_WPAN_GET_PRIVATE(setting)->page; +} + +/** + * nm_setting_wpan_get_channel: + * @setting: the #NMSettingWpan + * + * Returns: the #NMSettingWpan:channel property of the setting + * + * Since: 1.16 + **/ +gint16 +nm_setting_wpan_get_channel(NMSettingWpan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_WPAN(setting), NM_SETTING_WPAN_CHANNEL_DEFAULT); + + return NM_SETTING_WPAN_GET_PRIVATE(setting)->channel; +} + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWpanPrivate *priv = NM_SETTING_WPAN_GET_PRIVATE(setting); + + if (priv->mac_address && !nm_utils_hwaddr_valid(priv->mac_address, IEEE802154_ADDR_LEN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_WPAN_SETTING_NAME, NM_SETTING_WPAN_MAC_ADDRESS); + return FALSE; + } + + if ((priv->page == NM_SETTING_WPAN_PAGE_DEFAULT) + != (priv->channel == NM_SETTING_WPAN_CHANNEL_DEFAULT)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("page must be defined along with a channel")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_WPAN_SETTING_NAME, NM_SETTING_WPAN_PAGE); + return FALSE; + } + + if (priv->page < NM_SETTING_WPAN_PAGE_DEFAULT || priv->page > IEEE802154_MAX_PAGE) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("page must be between %d and %d"), + NM_SETTING_WPAN_PAGE_DEFAULT, + IEEE802154_MAX_PAGE); + g_prefix_error(error, "%s.%s: ", NM_SETTING_WPAN_SETTING_NAME, NM_SETTING_WPAN_PAGE); + return FALSE; + } + + if (priv->channel < NM_SETTING_WPAN_CHANNEL_DEFAULT || priv->channel > IEEE802154_MAX_CHANNEL) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("channel must not be between %d and %d"), + NM_SETTING_WPAN_CHANNEL_DEFAULT, + IEEE802154_MAX_CHANNEL); + g_prefix_error(error, "%s.%s: ", NM_SETTING_WPAN_SETTING_NAME, NM_SETTING_WPAN_CHANNEL); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingWpan *setting = NM_SETTING_WPAN(object); + + switch (prop_id) { + case PROP_MAC_ADDRESS: + g_value_set_string(value, nm_setting_wpan_get_mac_address(setting)); + break; + case PROP_PAN_ID: + g_value_set_uint(value, nm_setting_wpan_get_pan_id(setting)); + break; + case PROP_SHORT_ADDRESS: + g_value_set_uint(value, nm_setting_wpan_get_short_address(setting)); + break; + case PROP_PAGE: + g_value_set_int(value, nm_setting_wpan_get_page(setting)); + break; + case PROP_CHANNEL: + g_value_set_int(value, nm_setting_wpan_get_channel(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingWpanPrivate *priv = NM_SETTING_WPAN_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_MAC_ADDRESS: + g_free(priv->mac_address); + priv->mac_address = + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), IEEE802154_ADDR_LEN); + break; + case PROP_PAN_ID: + priv->pan_id = g_value_get_uint(value); + break; + case PROP_SHORT_ADDRESS: + priv->short_address = g_value_get_uint(value); + break; + case PROP_PAGE: + priv->page = g_value_get_int(value); + break; + case PROP_CHANNEL: + priv->channel = g_value_get_int(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_wpan_init(NMSettingWpan *setting) +{ + NMSettingWpanPrivate *priv = NM_SETTING_WPAN_GET_PRIVATE(setting); + + priv->pan_id = G_MAXUINT16; + priv->short_address = G_MAXUINT16; + priv->page = NM_SETTING_WPAN_PAGE_DEFAULT; + priv->channel = NM_SETTING_WPAN_CHANNEL_DEFAULT; +} + +/** + * nm_setting_wpan_new: + * + * Creates a new #NMSettingWpan object with default values. + * + * Returns: (transfer full): the new empty #NMSettingWpan object + * + * Since: 1.14 + **/ +NMSetting * +nm_setting_wpan_new(void) +{ + return g_object_new(NM_TYPE_SETTING_WPAN, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingWpanPrivate *priv = NM_SETTING_WPAN_GET_PRIVATE(object); + + g_free(priv->mac_address); + + G_OBJECT_CLASS(nm_setting_wpan_parent_class)->finalize(object); +} + +static void +nm_setting_wpan_class_init(NMSettingWpanClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(setting_class, sizeof(NMSettingWpanPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingWpan:mac-address: + * + * If specified, this connection will only apply to the IEEE 802.15.4 (WPAN) + * MAC layer device whose permanent MAC address matches. + **/ + /* ---keyfile--- + * property: mac-address + * format: usual hex-digits-and-colons notation + * description: MAC address in hex-digits-and-colons notation + * (e.g. 76:d8:9b:87:66:60:84:ee). + * ---end--- + */ + obj_properties[PROP_MAC_ADDRESS] = + g_param_spec_string(NM_SETTING_WPAN_MAC_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWpan:pan-id: + * + * IEEE 802.15.4 Personal Area Network (PAN) identifier. + **/ + obj_properties[PROP_PAN_ID] = g_param_spec_uint(NM_SETTING_WPAN_PAN_ID, + "", + "", + 0, + G_MAXUINT16, + G_MAXUINT16, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWpan:short-address: + * + * Short IEEE 802.15.4 address to be used within a restricted environment. + **/ + obj_properties[PROP_SHORT_ADDRESS] = + g_param_spec_uint(NM_SETTING_WPAN_SHORT_ADDRESS, + "", + "", + 0, + G_MAXUINT16, + G_MAXUINT16, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWpan:page: + * + * IEEE 802.15.4 channel page. A positive integer or -1, meaning "do not + * set, use whatever the device is already set to". + * + * Since: 1.16 + **/ + obj_properties[PROP_PAGE] = g_param_spec_int(NM_SETTING_WPAN_PAGE, + "", + "", + G_MININT16, + G_MAXINT16, + NM_SETTING_WPAN_PAGE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingWpan:channel: + * + * IEEE 802.15.4 channel. A positive integer or -1, meaning "do not + * set, use whatever the device is already set to". + * + * Since: 1.16 + **/ + obj_properties[PROP_CHANNEL] = g_param_spec_int(NM_SETTING_WPAN_CHANNEL, + "", + "", + G_MININT16, + G_MAXINT16, + NM_SETTING_WPAN_CHANNEL_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_WPAN); +} diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c new file mode 100644 index 0000000..22ec0f6 --- /dev/null +++ b/src/libnm-core-impl/nm-setting.c @@ -0,0 +1,2834 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting.h" + +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-utils-private.h" +#include "nm-property-compare.h" + +/** + * SECTION:nm-setting + * @short_description: Describes related configuration information + * + * Each #NMSetting contains properties that describe configuration that applies + * to a specific network layer (like IPv4 or IPv6 configuration) or device type + * (like Ethernet, or Wi-Fi). A collection of individual settings together + * make up an #NMConnection. Each property is strongly typed and usually has + * a number of allowed values. See each #NMSetting subclass for a description + * of properties and allowed values. + */ + +/*****************************************************************************/ + +typedef struct { + GHashTable * hash; + const char **names; + GVariant ** values; +} GenData; + +typedef struct { + const char * name; + GType type; + NMSettingPriority priority; +} SettingInfo; + +NM_GOBJECT_PROPERTIES_DEFINE(NMSetting, PROP_NAME, ); + +typedef struct { + GenData *gendata; +} NMSettingPrivate; + +G_DEFINE_ABSTRACT_TYPE(NMSetting, nm_setting, G_TYPE_OBJECT) + +#define NM_SETTING_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING, NMSettingPrivate)) + +/*****************************************************************************/ + +static GenData *_gendata_hash(NMSetting *setting, gboolean create_if_necessary); + +/*****************************************************************************/ + +NMSettingPriority +_nm_setting_get_setting_priority(NMSetting *setting) +{ + const NMMetaSettingInfo *setting_info; + + g_return_val_if_fail(NM_IS_SETTING(setting), NM_SETTING_PRIORITY_INVALID); + + setting_info = NM_SETTING_GET_CLASS(setting)->setting_info; + return setting_info ? setting_info->setting_priority : NM_SETTING_PRIORITY_INVALID; +} + +NMSettingPriority +_nm_setting_get_base_type_priority(NMSetting *setting) +{ + g_return_val_if_fail(NM_IS_SETTING(setting), NM_SETTING_PRIORITY_INVALID); + + return nm_meta_setting_info_get_base_type_priority(NM_SETTING_GET_CLASS(setting)->setting_info, + G_OBJECT_TYPE(setting)); +} + +/** + * nm_setting_lookup_type: + * @name: a setting name + * + * Returns the #GType of the setting's class for a given setting name. + * + * Returns: the #GType of the setting's class, or %G_TYPE_INVALID if + * @name is not recognized. + **/ +GType +nm_setting_lookup_type(const char *name) +{ + const NMMetaSettingInfo *setting_info; + + g_return_val_if_fail(name, G_TYPE_INVALID); + + setting_info = nm_meta_setting_infos_by_name(name); + return setting_info ? setting_info->get_setting_gtype() : G_TYPE_INVALID; +} + +int +_nm_setting_compare_priority(gconstpointer a, gconstpointer b) +{ + NMSettingPriority prio_a, prio_b; + + prio_a = _nm_setting_get_setting_priority((NMSetting *) a); + prio_b = _nm_setting_get_setting_priority((NMSetting *) b); + + if (prio_a < prio_b) + return -1; + else if (prio_a == prio_b) + return 0; + return 1; +} + +/*****************************************************************************/ + +gboolean +_nm_setting_slave_type_is_valid(const char *slave_type, const char **out_port_type) +{ + const char *port_type = NULL; + gboolean found = TRUE; + + if (!slave_type) + found = FALSE; + else if (NM_IN_STRSET(slave_type, NM_SETTING_BOND_SETTING_NAME, NM_SETTING_VRF_SETTING_NAME)) { + /* pass */ + } else if (nm_streq(slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) + port_type = NM_SETTING_BRIDGE_PORT_SETTING_NAME; + else if (nm_streq(slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) + port_type = NM_SETTING_OVS_PORT_SETTING_NAME; + else if (nm_streq(slave_type, NM_SETTING_OVS_PORT_SETTING_NAME)) + port_type = NM_SETTING_OVS_INTERFACE_SETTING_NAME; + else if (nm_streq(slave_type, NM_SETTING_TEAM_SETTING_NAME)) + port_type = NM_SETTING_TEAM_PORT_SETTING_NAME; + else + found = FALSE; + + if (out_port_type) + *out_port_type = port_type; + return found; +} + +/*****************************************************************************/ + +static const NMSettInfoProperty * +_nm_sett_info_property_find_in_array(const NMSettInfoProperty *properties, + guint len, + const char * name) +{ + guint i; + + for (i = 0; i < len; i++) { + if (nm_streq(name, properties[i].name)) + return &properties[i]; + } + return NULL; +} + +static GVariant * +_gprop_to_dbus_fcn_bytes(const GValue *val) +{ + nm_assert(G_VALUE_HOLDS(val, G_TYPE_BYTES)); + return nm_utils_gbytes_to_variant_ay(g_value_get_boxed(val)); +} + +static GVariant * +_gprop_to_dbus_fcn_enum(const GValue *val) +{ + return g_variant_new_int32(g_value_get_enum(val)); +} + +static GVariant * +_gprop_to_dbus_fcn_flags(const GValue *val) +{ + return g_variant_new_uint32(g_value_get_flags(val)); +} + +gboolean +_nm_properties_override_assert(const NMSettInfoProperty *prop_info) +{ + nm_assert(prop_info); + nm_assert((!!prop_info->name) != (!!prop_info->param_spec)); + nm_assert(!prop_info->param_spec || !prop_info->name + || nm_streq0(prop_info->name, prop_info->param_spec->name)); + +#define _PROPERT_EXTRA(prop_info, member) \ + ({ \ + const NMSettInfoProperty *_prop_info = (prop_info); \ + \ + (_prop_info->property_type ? _prop_info->property_type->member : 0); \ + }) + + nm_assert(!_PROPERT_EXTRA(prop_info, gprop_from_dbus_fcn) + || _PROPERT_EXTRA(prop_info, dbus_type)); + nm_assert(!_PROPERT_EXTRA(prop_info, from_dbus_fcn) || _PROPERT_EXTRA(prop_info, dbus_type)); + nm_assert(!_PROPERT_EXTRA(prop_info, to_dbus_fcn) || _PROPERT_EXTRA(prop_info, dbus_type)); + + nm_assert(!_PROPERT_EXTRA(prop_info, to_dbus_fcn) + || !_PROPERT_EXTRA(prop_info, gprop_to_dbus_fcn)); + nm_assert(!_PROPERT_EXTRA(prop_info, from_dbus_fcn) + || !_PROPERT_EXTRA(prop_info, gprop_from_dbus_fcn)); + + nm_assert(!_PROPERT_EXTRA(prop_info, gprop_to_dbus_fcn) || prop_info->param_spec); + nm_assert(!_PROPERT_EXTRA(prop_info, gprop_from_dbus_fcn) || prop_info->param_spec); + +#undef _PROPERT_EXTRA + + return TRUE; +} + +static NMSettInfoSetting _sett_info_settings[_NM_META_SETTING_TYPE_NUM]; + +const NMSettInfoSetting * +nmtst_sett_info_settings(void) +{ + return _sett_info_settings; +} + +static int +_property_infos_sort_cmp_setting_connection(gconstpointer p_a, + gconstpointer p_b, + gpointer user_data) +{ + const NMSettInfoProperty *a = *((const NMSettInfoProperty *const *) p_a); + const NMSettInfoProperty *b = *((const NMSettInfoProperty *const *) p_b); + int c_name; + + c_name = strcmp(a->name, b->name); + nm_assert(c_name != 0); + +#define CMP_AND_RETURN(n_a, n_b, name) \ + G_STMT_START \ + { \ + gboolean _is = nm_streq(n_a, "" name); \ + \ + if (_is || nm_streq(n_b, "" name)) \ + return _is ? -1 : 1; \ + } \ + G_STMT_END + + /* for [connection], report first id, uuid, type in that order. */ + if (c_name != 0) { + CMP_AND_RETURN(a->name, b->name, NM_SETTING_CONNECTION_ID); + CMP_AND_RETURN(a->name, b->name, NM_SETTING_CONNECTION_UUID); + CMP_AND_RETURN(a->name, b->name, NM_SETTING_CONNECTION_TYPE); + } + +#undef CMP_AND_RETURN + + return c_name; +} + +static const NMSettInfoProperty *const * +_property_infos_sort(const NMSettInfoProperty *property_infos, + guint property_infos_len, + NMSettingClass * setting_class) +{ + const NMSettInfoProperty **arr; + guint i; + +#if NM_MORE_ASSERTS > 5 + /* assert that the property names are all unique and sorted. */ + for (i = 0; i < property_infos_len; i++) { + if (property_infos[i].param_spec) + nm_assert(nm_streq(property_infos[i].name, property_infos[i].param_spec->name)); + if (i > 0) + nm_assert(strcmp(property_infos[i - 1].name, property_infos[i].name) < 0); + } +#endif + + if (property_infos_len <= 1) + return NULL; + if (G_TYPE_FROM_CLASS(setting_class) != NM_TYPE_SETTING_CONNECTION) { + /* we only do something special for certain setting types. This one, + * has just alphabetical sorting. */ + return NULL; + } + + arr = g_new(const NMSettInfoProperty *, property_infos_len); + for (i = 0; i < property_infos_len; i++) + arr[i] = &property_infos[i]; + + g_qsort_with_data(arr, + property_infos_len, + sizeof(const NMSettInfoProperty *), + _property_infos_sort_cmp_setting_connection, + NULL); + return arr; +} + +void +_nm_setting_class_commit_full(NMSettingClass * setting_class, + NMMetaSettingType meta_type, + const NMSettInfoSettDetail *detail, + GArray * properties_override) +{ + NMSettInfoSetting *sett_info; + gs_free GParamSpec **property_specs = NULL; + guint i, n_property_specs, override_len; + + nm_assert(NM_IS_SETTING_CLASS(setting_class)); + nm_assert(!setting_class->setting_info); + + nm_assert(meta_type < G_N_ELEMENTS(_sett_info_settings)); + + sett_info = &_sett_info_settings[meta_type]; + + nm_assert(!sett_info->setting_class); + nm_assert(!sett_info->property_infos_len); + nm_assert(!sett_info->property_infos); + + if (!properties_override) { + override_len = 0; + properties_override = _nm_sett_info_property_override_create_array(); + } else + override_len = properties_override->len; + + property_specs = + g_object_class_list_properties(G_OBJECT_CLASS(setting_class), &n_property_specs); + + for (i = 0; i < properties_override->len; i++) { + NMSettInfoProperty *p = &g_array_index(properties_override, NMSettInfoProperty, i); + + nm_assert((!!p->name) != (!!p->param_spec)); + + if (!p->name) { + nm_assert(p->param_spec); + p->name = p->param_spec->name; + } else + nm_assert(!p->param_spec); + } + +#if NM_MORE_ASSERTS > 10 + /* assert that properties_override is constructed consistently. */ + for (i = 0; i < override_len; i++) { + const NMSettInfoProperty *p = &g_array_index(properties_override, NMSettInfoProperty, i); + gboolean found = FALSE; + guint j; + + nm_assert( + !_nm_sett_info_property_find_in_array((NMSettInfoProperty *) properties_override->data, + i, + p->name)); + for (j = 0; j < n_property_specs; j++) { + if (!nm_streq(property_specs[j]->name, p->name)) + continue; + nm_assert(!found); + found = TRUE; + nm_assert(p->param_spec == property_specs[j]); + } + nm_assert(found == (p->param_spec != NULL)); + } +#endif + + for (i = 0; i < n_property_specs; i++) { + const char * name = property_specs[i]->name; + NMSettInfoProperty *p; + + if (_nm_sett_info_property_find_in_array((NMSettInfoProperty *) properties_override->data, + override_len, + name)) + continue; + + g_array_set_size(properties_override, properties_override->len + 1); + p = &g_array_index(properties_override, NMSettInfoProperty, properties_override->len - 1); + memset(p, 0, sizeof(*p)); + p->name = name; + p->param_spec = property_specs[i]; + } + + for (i = 0; i < properties_override->len; i++) { + NMSettInfoProperty *p = &g_array_index(properties_override, NMSettInfoProperty, i); + GType vtype; + + if (p->property_type) + goto has_property_type; + + nm_assert(p->param_spec); + + vtype = p->param_spec->value_type; + if (vtype == G_TYPE_BOOLEAN) + p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_BOOLEAN); + else if (vtype == G_TYPE_UCHAR) + p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_BYTE); + else if (vtype == G_TYPE_INT) + p->property_type = &nm_sett_info_propert_type_plain_i; + else if (vtype == G_TYPE_UINT) + p->property_type = &nm_sett_info_propert_type_plain_u; + else if (vtype == G_TYPE_INT64) + p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_INT64); + else if (vtype == G_TYPE_UINT64) + p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_UINT64); + else if (vtype == G_TYPE_STRING) + p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING); + else if (vtype == G_TYPE_DOUBLE) + p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_DOUBLE); + else if (vtype == G_TYPE_STRV) + p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING_ARRAY); + else if (vtype == G_TYPE_BYTES) { + p->property_type = + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_BYTESTRING, + .gprop_to_dbus_fcn = _gprop_to_dbus_fcn_bytes); + } else if (g_type_is_a(vtype, G_TYPE_ENUM)) { + p->property_type = + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_INT32, + .gprop_to_dbus_fcn = _gprop_to_dbus_fcn_enum); + } else if (g_type_is_a(vtype, G_TYPE_FLAGS)) { + p->property_type = + NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_UINT32, + .gprop_to_dbus_fcn = _gprop_to_dbus_fcn_flags); + } else + nm_assert_not_reached(); + +has_property_type: + nm_assert(p->property_type); + nm_assert(p->property_type->dbus_type); + nm_assert(g_variant_type_string_is_valid((const char *) p->property_type->dbus_type)); + } + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMSettInfoProperty, name) == 0); + g_array_sort(properties_override, nm_strcmp_p); + + setting_class->setting_info = &nm_meta_setting_infos[meta_type]; + sett_info->setting_class = setting_class; + if (detail) + sett_info->detail = *detail; + nm_assert(properties_override->len > 0); + sett_info->property_infos_len = properties_override->len; + sett_info->property_infos = + nm_memdup(properties_override->data, sizeof(NMSettInfoProperty) * properties_override->len); + + sett_info->property_infos_sorted = _property_infos_sort(sett_info->property_infos, + sett_info->property_infos_len, + setting_class); + + g_array_free(properties_override, TRUE); +} + +const NMSettInfoProperty * +_nm_sett_info_setting_get_property_info(const NMSettInfoSetting *sett_info, + const char * property_name) +{ + const NMSettInfoProperty *property; + gssize idx; + + nm_assert(property_name); + + if (!sett_info) + return NULL; + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMSettInfoProperty, name) == 0); + idx = nm_utils_array_find_binary_search(sett_info->property_infos, + sizeof(NMSettInfoProperty), + sett_info->property_infos_len, + &property_name, + nm_strcmp_p_with_data, + NULL); + + if (idx < 0) + return NULL; + + property = &sett_info->property_infos[idx]; + + nm_assert(idx == 0 || strcmp(property[-1].name, property[0].name) < 0); + nm_assert(idx == sett_info->property_infos_len - 1 + || strcmp(property[0].name, property[1].name) < 0); + + return property; +} + +const NMSettInfoSetting * +_nm_setting_class_get_sett_info(NMSettingClass *setting_class) +{ + const NMSettInfoSetting *sett_info; + + if (!NM_IS_SETTING_CLASS(setting_class) || !setting_class->setting_info) + return NULL; + + nm_assert(setting_class->setting_info->meta_type < G_N_ELEMENTS(_sett_info_settings)); + sett_info = &_sett_info_settings[setting_class->setting_info->meta_type]; + nm_assert(sett_info->setting_class == setting_class); + return sett_info; +} + +/*****************************************************************************/ + +void +_nm_setting_emit_property_changed(NMSetting *setting) +{ + /* Some settings have "properties" that are not implemented as GObject properties. + * + * For example: + * + * - gendata-base settings like NMSettingEthtool. Here properties are just + * GVariant values in the gendata hash. + * + * - NMSettingWireGuard's peers are not backed by a GObject property. Instead + * there is C-API to access/modify peers. + * + * We still want to emit property-changed notifications for such properties, + * in particular because NMConnection registers to such signals to re-emit + * it as NM_CONNECTION_CHANGED signal. In fact, there are unlikely any other + * uses of such a property-changed signal, because generally it doesn't make + * too much sense. + * + * So, instead of adding yet another (artificial) signal "setting-changed", + * hijack the "notify" signal and just notify about changes of the "name". + * Of course, the "name" doesn't really ever change, because it's tied to + * the GObject's type. + */ + _notify(setting, PROP_NAME); +} + +/*****************************************************************************/ + +gboolean +_nm_setting_use_legacy_property(NMSetting * setting, + GVariant * connection_dict, + const char *legacy_property, + const char *new_property) +{ + GVariant *setting_dict, *value; + + setting_dict = g_variant_lookup_value(connection_dict, + nm_setting_get_name(NM_SETTING(setting)), + NM_VARIANT_TYPE_SETTING); + g_return_val_if_fail(setting_dict != NULL, FALSE); + + /* If the new property isn't set, we have to use the legacy property. */ + value = g_variant_lookup_value(setting_dict, new_property, NULL); + if (!value) { + g_variant_unref(setting_dict); + return TRUE; + } + g_variant_unref(value); + + /* Otherwise, clients always prefer new properties sent from the daemon. */ + if (!_nm_utils_is_manager_process) { + g_variant_unref(setting_dict); + return FALSE; + } + + /* The daemon prefers the legacy property if it exists. */ + value = g_variant_lookup_value(setting_dict, legacy_property, NULL); + g_variant_unref(setting_dict); + + if (value) { + g_variant_unref(value); + return TRUE; + } else + return FALSE; +} + +/*****************************************************************************/ + +static GVariant * +property_to_dbus(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options, + gboolean ignore_flags, + gboolean ignore_default) +{ + const NMSettInfoProperty *property = &sett_info->property_infos[property_idx]; + GVariant * variant; + + nm_assert(property->property_type->dbus_type); + + if (!property->param_spec) { + if (!property->property_type->to_dbus_fcn) + return NULL; + } else if (!ignore_flags + && !NM_FLAGS_HAS(property->param_spec->flags, + NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS)) { + if (!NM_FLAGS_HAS(property->param_spec->flags, G_PARAM_WRITABLE)) + return NULL; + + if (NM_FLAGS_HAS(property->param_spec->flags, NM_SETTING_PARAM_LEGACY) + && !_nm_utils_is_manager_process) + return NULL; + + if (NM_FLAGS_HAS(property->param_spec->flags, NM_SETTING_PARAM_SECRET)) { + if (NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_NO_SECRETS)) + return NULL; + + if (NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED)) { + NMSettingSecretFlags f; + + /* see also _nm_connection_serialize_secrets() */ + if (!nm_setting_get_secret_flags(setting, property->param_spec->name, &f, NULL)) + return NULL; + if (!NM_FLAGS_HAS(f, NM_SETTING_SECRET_FLAG_AGENT_OWNED)) + return NULL; + } + } else { + if (NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_ONLY_SECRETS)) + return NULL; + } + } + + if (property->property_type->to_dbus_fcn) { + variant = property->property_type + ->to_dbus_fcn(sett_info, property_idx, connection, setting, flags, options); + nm_g_variant_take_ref(variant); + } else { + nm_auto_unset_gvalue GValue prop_value = { + 0, + }; + + nm_assert(property->param_spec); + + g_value_init(&prop_value, property->param_spec->value_type); + + g_object_get_property(G_OBJECT(setting), property->param_spec->name, &prop_value); + + if (ignore_default && g_param_value_defaults(property->param_spec, &prop_value)) + return NULL; + + if (property->property_type->gprop_to_dbus_fcn) { + variant = property->property_type->gprop_to_dbus_fcn(&prop_value); + nm_g_variant_take_ref(variant); + } else + variant = g_dbus_gvalue_to_gvariant(&prop_value, property->property_type->dbus_type); + } + + nm_assert(!variant || !g_variant_is_floating(variant)); + nm_assert(!variant || g_variant_is_of_type(variant, property->property_type->dbus_type)); + + return variant; +} + +static gboolean +set_property_from_dbus(const NMSettInfoProperty *property, GVariant *src_value, GValue *dst_value) +{ + nm_assert(property->param_spec); + nm_assert(property->property_type->dbus_type); + + if (property->property_type->gprop_from_dbus_fcn) { + if (!g_variant_type_equal(g_variant_get_type(src_value), + property->property_type->dbus_type)) + return FALSE; + property->property_type->gprop_from_dbus_fcn(src_value, dst_value); + } else if (dst_value->g_type == G_TYPE_BYTES) { + if (!g_variant_is_of_type(src_value, G_VARIANT_TYPE_BYTESTRING)) + return FALSE; + + _nm_utils_bytes_from_dbus(src_value, dst_value); + } else { + GValue tmp = G_VALUE_INIT; + + g_dbus_gvariant_to_gvalue(src_value, &tmp); + if (G_VALUE_TYPE(&tmp) == G_VALUE_TYPE(dst_value)) + *dst_value = tmp; + else { + gboolean success; + + success = g_value_transform(&tmp, dst_value); + g_value_unset(&tmp); + if (!success) + return FALSE; + } + } + + return TRUE; +} + +/** + * _nm_setting_to_dbus: + * @setting: the #NMSetting + * @connection: the #NMConnection containing @setting + * @flags: hash flags, e.g. %NM_CONNECTION_SERIALIZE_ALL + * @options: the #NMConnectionSerializationOptions options to control + * what/how gets serialized. + * + * Converts the #NMSetting into a #GVariant of type #NM_VARIANT_TYPE_SETTING + * mapping each setting property name to a value describing that property, + * suitable for marshalling over D-Bus or serializing. + * + * Returns: (transfer none): a new floating #GVariant describing the setting's + * properties + **/ +GVariant * +_nm_setting_to_dbus(NMSetting * setting, + NMConnection * connection, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + NMSettingPrivate * priv; + GVariantBuilder builder; + const NMSettInfoSetting *sett_info; + guint n_properties, i; + const char *const * gendata_keys; + + g_return_val_if_fail(NM_IS_SETTING(setting), NULL); + + priv = NM_SETTING_GET_PRIVATE(setting); + + g_variant_builder_init(&builder, NM_VARIANT_TYPE_SETTING); + + n_properties = _nm_setting_option_get_all(setting, &gendata_keys, NULL); + for (i = 0; i < n_properties; i++) { + g_variant_builder_add(&builder, + "{sv}", + gendata_keys[i], + g_hash_table_lookup(priv->gendata->hash, gendata_keys[i])); + } + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); + for (i = 0; i < sett_info->property_infos_len; i++) { + gs_unref_variant GVariant *dbus_value = NULL; + + dbus_value = + property_to_dbus(sett_info, i, connection, setting, flags, options, FALSE, TRUE); + if (dbus_value) { + g_variant_builder_add(&builder, "{sv}", sett_info->property_infos[i].name, dbus_value); + } + } + + return g_variant_builder_end(&builder); +} + +/** + * _nm_setting_new_from_dbus: + * @setting_type: the #NMSetting type which the hash contains properties for + * @setting_dict: the #GVariant containing an %NM_VARIANT_TYPE_SETTING dictionary + * mapping property names to values + * @connection_dict: the #GVariant containing an %NM_VARIANT_TYPE_CONNECTION + * dictionary mapping setting names to dictionaries. + * @parse_flags: flags to determine behavior during parsing. + * @error: location to store error, or %NULL + * + * Creates a new #NMSetting object and populates that object with the properties + * contained in @setting_dict, using each key as the property to set, and each + * value as the value to set that property to. Setting properties are strongly + * typed, thus the #GVariantType of the dict value must be correct. See the + * documentation on each #NMSetting object subclass for the correct property + * names and value types. + * + * Returns: a new #NMSetting object populated with the properties from the + * hash table, or %NULL if @setting_hash could not be deserialized. + **/ +NMSetting * +_nm_setting_new_from_dbus(GType setting_type, + GVariant * setting_dict, + GVariant * connection_dict, + NMSettingParseFlags parse_flags, + GError ** error) +{ + gs_unref_ptrarray GPtrArray *keys_keep_variant = NULL; + gs_unref_object NMSetting *setting = NULL; + gs_unref_hashtable GHashTable *keys = NULL; + + g_return_val_if_fail(G_TYPE_IS_INSTANTIATABLE(setting_type), NULL); + g_return_val_if_fail(g_variant_is_of_type(setting_dict, NM_VARIANT_TYPE_SETTING), NULL); + + nm_assert(!NM_FLAGS_ANY(parse_flags, ~NM_SETTING_PARSE_FLAGS_ALL)); + nm_assert(!NM_FLAGS_ALL(parse_flags, + NM_SETTING_PARSE_FLAGS_STRICT | NM_SETTING_PARSE_FLAGS_BEST_EFFORT)); + + /* connection_dict is not technically optional, but some tests in test-general + * don't bother with it in cases where they know it's not needed. + */ + if (connection_dict) + g_return_val_if_fail(g_variant_is_of_type(connection_dict, NM_VARIANT_TYPE_CONNECTION), + NULL); + + /* Build the setting object from the properties we know about; we assume + * that any propreties in @setting_dict that we don't know about can + * either be ignored or else has a backward-compatibility equivalent + * that we do know about. + */ + setting = g_object_new(setting_type, NULL); + + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { + GVariantIter iter; + GVariant * entry, *entry_key; + const char * key; + + keys_keep_variant = g_ptr_array_new_with_free_func((GDestroyNotify) g_variant_unref); + keys = g_hash_table_new(nm_str_hash, g_str_equal); + + g_variant_iter_init(&iter, setting_dict); + while ((entry = g_variant_iter_next_value(&iter))) { + entry_key = g_variant_get_child_value(entry, 0); + g_ptr_array_add(keys_keep_variant, entry_key); + g_variant_unref(entry); + + key = g_variant_get_string(entry_key, NULL); + if (!g_hash_table_add(keys, (char *) key)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("duplicate property")); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), key); + return NULL; + } + } + } + + if (!NM_SETTING_GET_CLASS(setting) + ->init_from_dbus(setting, keys, setting_dict, connection_dict, parse_flags, error)) + return NULL; + + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT) && g_hash_table_size(keys) > 0) { + GHashTableIter iter; + const char * key; + + g_hash_table_iter_init(&iter, keys); + if (g_hash_table_iter_next(&iter, (gpointer *) &key, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unknown property")); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), key); + return NULL; + } + } + + return g_steal_pointer(&setting); +} + +static gboolean +init_from_dbus(NMSetting * setting, + GHashTable * keys, + GVariant * setting_dict, + GVariant * connection_dict, + guint /* NMSettingParseFlags */ parse_flags, + GError ** error) +{ + const NMSettInfoSetting *sett_info; + + guint i; + + nm_assert(NM_IS_SETTING(setting)); + nm_assert(!NM_FLAGS_ANY(parse_flags, ~NM_SETTING_PARSE_FLAGS_ALL)); + nm_assert(!NM_FLAGS_ALL(parse_flags, + NM_SETTING_PARSE_FLAGS_STRICT | NM_SETTING_PARSE_FLAGS_BEST_EFFORT)); + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); + + if (sett_info->detail.gendata_info) { + GHashTable * hash; + GVariantIter iter; + char * key; + GVariant * val; + + hash = _gendata_hash(setting, TRUE)->hash; + + g_variant_iter_init(&iter, setting_dict); + while (g_variant_iter_next(&iter, "{sv}", &key, &val)) { + g_hash_table_insert(hash, key, val); + if (keys) + g_hash_table_remove(keys, key); + } + + _nm_setting_option_notify(setting, TRUE); + + /* Currently, only NMSettingEthtool supports gendata based options, and + * that one has no other properties (except "name"). That means, we + * consumed all options above. + * + * In the future it may be interesting to have settings that are both + * based on gendata and regular properties. In that case, we would need + * to handle this case differently. */ + nm_assert(nm_streq(G_OBJECT_TYPE_NAME(setting), "NMSettingEthtool")); + nm_assert(sett_info->property_infos_len == 1); + + return TRUE; + } + + for (i = 0; i < sett_info->property_infos_len; i++) { + const NMSettInfoProperty *property_info = &sett_info->property_infos[i]; + gs_unref_variant GVariant *value = NULL; + gs_free_error GError *local = NULL; + + if (property_info->param_spec && !(property_info->param_spec->flags & G_PARAM_WRITABLE)) + continue; + + value = g_variant_lookup_value(setting_dict, property_info->name, NULL); + + if (value && keys) + g_hash_table_remove(keys, property_info->name); + + if (value && property_info->property_type->from_dbus_fcn) { + if (!g_variant_type_equal(g_variant_get_type(value), + property_info->property_type->dbus_type)) { + /* for backward behavior, fail unless best-effort is chosen. */ + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_BEST_EFFORT)) + continue; + g_set_error( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("can't set property of type '%s' from value of type '%s'"), + property_info->property_type->dbus_type + ? g_variant_type_peek_string(property_info->property_type->dbus_type) + : property_info->param_spec ? g_type_name(property_info->param_spec->value_type) + : "(unknown)", + g_variant_get_type_string(value)); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name); + return FALSE; + } + + if (!property_info->property_type->from_dbus_fcn(setting, + connection_dict, + property_info->name, + value, + parse_flags, + &local)) { + if (!NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) + continue; + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("failed to set property: %s"), + local->message); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name); + return FALSE; + } + } else if (!value && property_info->property_type->missing_from_dbus_fcn) { + if (!property_info->property_type->missing_from_dbus_fcn(setting, + connection_dict, + property_info->name, + parse_flags, + &local)) { + if (!NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) + continue; + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("failed to set property: %s"), + local->message); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name); + return FALSE; + } + } else if (value && property_info->param_spec) { + nm_auto_unset_gvalue GValue object_value = G_VALUE_INIT; + + g_value_init(&object_value, property_info->param_spec->value_type); + if (!set_property_from_dbus(property_info, value, &object_value)) { + /* for backward behavior, fail unless best-effort is chosen. */ + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_BEST_EFFORT)) + continue; + g_set_error( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("can't set property of type '%s' from value of type '%s'"), + property_info->property_type->dbus_type + ? g_variant_type_peek_string(property_info->property_type->dbus_type) + : (property_info->param_spec + ? g_type_name(property_info->param_spec->value_type) + : "(unknown)"), + g_variant_get_type_string(value)); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name); + return FALSE; + } + + if (!nm_g_object_set_property(G_OBJECT(setting), + property_info->param_spec->name, + &object_value, + &local)) { + if (!NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) + continue; + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("can not set property: %s"), + local->message); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name); + return FALSE; + } + } + } + + return TRUE; +} + +/** + * nm_setting_get_dbus_property_type: + * @setting: an #NMSetting + * @property_name: the property of @setting to get the type of + * + * Gets the D-Bus marshalling type of a property. @property_name is a D-Bus + * property name, which may not necessarily be a #GObject property. + * + * Returns: the D-Bus marshalling type of @property on @setting. + */ +const GVariantType * +nm_setting_get_dbus_property_type(NMSetting *setting, const char *property_name) +{ + const NMSettInfoProperty *property; + + g_return_val_if_fail(NM_IS_SETTING(setting), NULL); + g_return_val_if_fail(property_name != NULL, NULL); + + property = _nm_setting_class_get_property_info(NM_SETTING_GET_CLASS(setting), property_name); + + g_return_val_if_fail(property != NULL, NULL); + + nm_assert(property->property_type); + nm_assert(g_variant_type_string_is_valid((const char *) property->property_type->dbus_type)); + + return property->property_type->dbus_type; +} + +gboolean +_nm_setting_get_property(NMSetting *setting, const char *property_name, GValue *value) +{ + const NMSettInfoSetting * sett_info; + const NMSettInfoProperty *property_info; + + g_return_val_if_fail(NM_IS_SETTING(setting), FALSE); + g_return_val_if_fail(property_name, FALSE); + g_return_val_if_fail(value, FALSE); + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); + + if (sett_info->detail.gendata_info) { + GVariant *variant; + GenData * gendata = _gendata_hash(setting, FALSE); + + variant = gendata ? g_hash_table_lookup(gendata->hash, property_name) : NULL; + + if (!variant) { + g_value_unset(value); + return FALSE; + } + + g_value_init(value, G_TYPE_VARIANT); + g_value_set_variant(value, variant); + return TRUE; + } + + property_info = _nm_sett_info_setting_get_property_info(sett_info, property_name); + if (!property_info || !property_info->param_spec) { + g_value_unset(value); + return FALSE; + } + + g_value_init(value, property_info->param_spec->value_type); + g_object_get_property(G_OBJECT(setting), property_name, value); + return TRUE; +} + +static void +_gobject_copy_property(GObject *src, GObject *dst, const char *property_name, GType gtype) +{ + nm_auto_unset_gvalue GValue value = G_VALUE_INIT; + + nm_assert(G_IS_OBJECT(src)); + nm_assert(G_IS_OBJECT(dst)); + + g_value_init(&value, gtype); + g_object_get_property(src, property_name, &value); + g_object_set_property(dst, property_name, &value); +} + +static void +duplicate_copy_properties(const NMSettInfoSetting *sett_info, NMSetting *src, NMSetting *dst) +{ + if (sett_info->detail.gendata_info) { + GenData *gendata = _gendata_hash(src, FALSE); + + nm_assert(!_gendata_hash(dst, FALSE)); + + if (gendata && g_hash_table_size(gendata->hash) > 0) { + GHashTableIter iter; + GHashTable * h = _gendata_hash(dst, TRUE)->hash; + const char * key; + GVariant * val; + + g_hash_table_iter_init(&iter, gendata->hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + g_hash_table_insert(h, g_strdup(key), g_variant_ref(val)); + } + } + } + + if (sett_info->property_infos_len > 0) { + gboolean frozen = FALSE; + guint i; + + for (i = 0; i < sett_info->property_infos_len; i++) { + const NMSettInfoProperty *property_info = &sett_info->property_infos[i]; + + if (property_info->param_spec) { + if ((property_info->param_spec->flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)) + != G_PARAM_WRITABLE) + continue; + + if (!frozen) { + g_object_freeze_notify(G_OBJECT(dst)); + frozen = TRUE; + } + _gobject_copy_property(G_OBJECT(src), + G_OBJECT(dst), + property_info->param_spec->name, + G_PARAM_SPEC_VALUE_TYPE(property_info->param_spec)); + continue; + } + } + + if (frozen) + g_object_thaw_notify(G_OBJECT(dst)); + } +} + +/** + * nm_setting_duplicate: + * @setting: the #NMSetting to duplicate + * + * Duplicates a #NMSetting. + * + * Returns: (transfer full): a new #NMSetting containing the same properties and values as the + * source #NMSetting + **/ +NMSetting * +nm_setting_duplicate(NMSetting *setting) +{ + const NMSettInfoSetting *sett_info; + NMSettingClass * klass; + NMSetting * dst; + + g_return_val_if_fail(NM_IS_SETTING(setting), NULL); + + klass = NM_SETTING_GET_CLASS(setting); + nm_assert(NM_IS_SETTING_CLASS(klass)); + nm_assert(klass->duplicate_copy_properties); + + dst = g_object_new(G_TYPE_FROM_CLASS(klass), NULL); + + sett_info = _nm_setting_class_get_sett_info(klass); + nm_assert(sett_info); + + klass->duplicate_copy_properties(sett_info, setting, dst); + return dst; +} + +/** + * nm_setting_get_name: + * @setting: the #NMSetting + * + * Returns the type name of the #NMSetting object + * + * Returns: a string containing the type name of the #NMSetting object, + * like 'ppp' or 'wireless' or 'wired'. + **/ +const char * +nm_setting_get_name(NMSetting *setting) +{ + const NMMetaSettingInfo *setting_info; + + g_return_val_if_fail(NM_IS_SETTING(setting), NULL); + + setting_info = NM_SETTING_GET_CLASS(setting)->setting_info; + return setting_info ? setting_info->setting_name : NULL; +} + +/** + * nm_setting_verify: + * @setting: the #NMSetting to verify + * @connection: (allow-none): the #NMConnection that @setting came from, or + * %NULL if @setting is being verified in isolation. + * @error: location to store error, or %NULL + * + * Validates the setting. Each setting's properties have allowed values, and + * some are dependent on other values (hence the need for @connection). The + * returned #GError contains information about which property of the setting + * failed validation, and in what way that property failed validation. + * + * Returns: %TRUE if the setting is valid, %FALSE if it is not + **/ +gboolean +nm_setting_verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVerifyResult result = _nm_setting_verify(setting, connection, error); + + if (result == NM_SETTING_VERIFY_NORMALIZABLE) + g_clear_error(error); + + return result == NM_SETTING_VERIFY_SUCCESS || result == NM_SETTING_VERIFY_NORMALIZABLE; +} + +NMSettingVerifyResult +_nm_setting_verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + g_return_val_if_fail(NM_IS_SETTING(setting), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail(!connection || NM_IS_CONNECTION(connection), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail(!error || *error == NULL, NM_SETTING_VERIFY_ERROR); + + if (NM_SETTING_GET_CLASS(setting)->verify) + return NM_SETTING_GET_CLASS(setting)->verify(setting, connection, error); + + return NM_SETTING_VERIFY_SUCCESS; +} + +/** + * nm_setting_verify_secrets: + * @setting: the #NMSetting to verify secrets in + * @connection: (allow-none): the #NMConnection that @setting came from, or + * %NULL if @setting is being verified in isolation. + * @error: location to store error, or %NULL + * + * Verifies the secrets in the setting. + * The returned #GError contains information about which secret of the setting + * failed validation, and in what way that secret failed validation. + * The secret validation is done separately from main setting validation, because + * in some cases connection failure is not desired just for the secrets. + * + * Returns: %TRUE if the setting secrets are valid, %FALSE if they are not + * + * Since: 1.2 + **/ +gboolean +nm_setting_verify_secrets(NMSetting *setting, NMConnection *connection, GError **error) +{ + g_return_val_if_fail(NM_IS_SETTING(setting), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail(!connection || NM_IS_CONNECTION(connection), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail(!error || *error == NULL, NM_SETTING_VERIFY_ERROR); + + if (NM_SETTING_GET_CLASS(setting)->verify_secrets) + return NM_SETTING_GET_CLASS(setting)->verify_secrets(setting, connection, error); + + return NM_SETTING_VERIFY_SUCCESS; +} + +gboolean +_nm_setting_verify_secret_string(const char *str, + const char *setting_name, + const char *property, + GError ** error) +{ + if (str && !*str) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error(error, "%s.%s: ", setting_name, property); + return FALSE; + } + return TRUE; +} + +gboolean +_nm_setting_should_compare_secret_property(NMSetting * setting, + NMSetting * other, + const char * secret_name, + NMSettingCompareFlags flags) +{ + NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE; + NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + nm_assert(NM_IS_SETTING(setting)); + nm_assert(!other || G_OBJECT_TYPE(setting) == G_OBJECT_TYPE(other)); + + /* secret_name must be a valid secret for @setting. */ + nm_assert(nm_setting_get_secret_flags(setting, secret_name, NULL, NULL)); + + if (!NM_FLAGS_ANY(flags, + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS + | NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) + return TRUE; + + nm_setting_get_secret_flags(setting, secret_name, &a_secret_flags, NULL); + if (other) { + if (!nm_setting_get_secret_flags(other, secret_name, &b_secret_flags, NULL)) { + /* secret-name may not be a valid secret for @other. That is fine, we ignore that + * and treat @b_secret_flags as NM_SETTING_SECRET_FLAG_NONE. + * + * This can happen with VPN secrets, where the caller knows that @secret_name + * is a secret for setting, but it may not be a secret for @other. Accept that. + * + * Mark @other as missing. */ + other = NULL; + } + } + + /* when @setting has the secret-flags that should be ignored, + * we skip the comparison if: + * + * - @other is not present, + * - @other does not have a secret named @secret_name + * - @other also has the secret flat to be ignored. + * + * This makes the check symmetric (aside the fact that @setting must + * have the secret while @other may not -- which is asymmetric). */ + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS) + && NM_FLAGS_HAS(a_secret_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED) + && (!other || NM_FLAGS_HAS(b_secret_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED))) + return FALSE; + + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS) + && NM_FLAGS_HAS(a_secret_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED) + && (!other || NM_FLAGS_HAS(b_secret_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED))) + return FALSE; + + return TRUE; +} + +static NMTernary +compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + const NMSettInfoProperty *property_info = &sett_info->property_infos[property_idx]; + const GParamSpec * param_spec = property_info->param_spec; + + if (!param_spec) + return NM_TERNARY_DEFAULT; + + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_FUZZY) + && NM_FLAGS_ANY(param_spec->flags, NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET)) + return NM_TERNARY_DEFAULT; + + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE) + && !NM_FLAGS_HAS(param_spec->flags, NM_SETTING_PARAM_INFERRABLE)) + return NM_TERNARY_DEFAULT; + + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY) + && NM_FLAGS_HAS(param_spec->flags, NM_SETTING_PARAM_REAPPLY_IMMEDIATELY)) + return NM_TERNARY_DEFAULT; + + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS) + && NM_FLAGS_HAS(param_spec->flags, NM_SETTING_PARAM_SECRET)) + return NM_TERNARY_DEFAULT; + + if (nm_streq(param_spec->name, NM_SETTING_NAME)) + return NM_TERNARY_DEFAULT; + + if (NM_FLAGS_HAS(param_spec->flags, NM_SETTING_PARAM_SECRET) + && !_nm_setting_should_compare_secret_property(set_a, set_b, param_spec->name, flags)) + return NM_TERNARY_DEFAULT; + + if (set_b) { + gs_unref_variant GVariant *value1 = NULL; + gs_unref_variant GVariant *value2 = NULL; + + value1 = property_to_dbus(sett_info, + property_idx, + con_a, + set_a, + NM_CONNECTION_SERIALIZE_ALL, + NULL, + TRUE, + TRUE); + value2 = property_to_dbus(sett_info, + property_idx, + con_b, + set_b, + NM_CONNECTION_SERIALIZE_ALL, + NULL, + TRUE, + TRUE); + if (nm_property_compare(value1, value2) != 0) + return NM_TERNARY_FALSE; + } + + return NM_TERNARY_TRUE; +} + +static NMTernary +_compare_property(const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMTernary compare_result; + + nm_assert(sett_info); + nm_assert(NM_IS_SETTING_CLASS(sett_info->setting_class)); + nm_assert(property_idx < sett_info->property_infos_len); + nm_assert(NM_SETTING_GET_CLASS(set_a) == sett_info->setting_class); + nm_assert(!set_b || NM_SETTING_GET_CLASS(set_b) == sett_info->setting_class); + + compare_result = + NM_SETTING_GET_CLASS(set_a) + ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + + nm_assert(NM_IN_SET(compare_result, NM_TERNARY_DEFAULT, NM_TERNARY_FALSE, NM_TERNARY_TRUE)); + + /* check that the inferable flag and the GObject property flag corresponds. */ + nm_assert(!NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE) + || !sett_info->property_infos[property_idx].param_spec + || NM_FLAGS_HAS(sett_info->property_infos[property_idx].param_spec->flags, + NM_SETTING_PARAM_INFERRABLE) + || compare_result == NM_TERNARY_DEFAULT); + +#if NM_MORE_ASSERTS > 10 + /* assert that compare_property() is symeric. */ + nm_assert(!set_b + || compare_result + == NM_SETTING_GET_CLASS(set_a)->compare_property(sett_info, + property_idx, + con_b, + set_b, + con_a, + set_a, + flags)); +#endif + + return compare_result; +} + +/** + * nm_setting_compare: + * @a: a #NMSetting + * @b: a second #NMSetting to compare with the first + * @flags: compare flags, e.g. %NM_SETTING_COMPARE_FLAG_EXACT + * + * Compares two #NMSetting objects for similarity, with comparison behavior + * modified by a set of flags. See the documentation for #NMSettingCompareFlags + * for a description of each flag's behavior. + * + * Returns: %TRUE if the comparison succeeds, %FALSE if it does not + **/ +gboolean +nm_setting_compare(NMSetting *a, NMSetting *b, NMSettingCompareFlags flags) +{ + return _nm_setting_compare(NULL, a, NULL, b, flags); +} + +gboolean +_nm_setting_compare(NMConnection * con_a, + NMSetting * a, + NMConnection * con_b, + NMSetting * b, + NMSettingCompareFlags flags) +{ + const NMSettInfoSetting *sett_info; + guint i; + + g_return_val_if_fail(NM_IS_SETTING(a), FALSE); + g_return_val_if_fail(NM_IS_SETTING(b), FALSE); + + nm_assert(!con_a || NM_IS_CONNECTION(con_a)); + nm_assert(!con_b || NM_IS_CONNECTION(con_b)); + + /* First check that both have the same type */ + if (G_OBJECT_TYPE(a) != G_OBJECT_TYPE(b)) + return FALSE; + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(a)); + + if (sett_info->detail.gendata_info) { + GenData *a_gendata = _gendata_hash(a, FALSE); + GenData *b_gendata = _gendata_hash(b, FALSE); + + return nm_utils_hashtable_equal(a_gendata ? a_gendata->hash : NULL, + b_gendata ? b_gendata->hash : NULL, + TRUE, + g_variant_equal); + } + + for (i = 0; i < sett_info->property_infos_len; i++) { + if (_compare_property(sett_info, i, con_a, a, con_b, b, flags) == NM_TERNARY_FALSE) + return FALSE; + } + + return TRUE; +} + +static void +_setting_diff_add_result(GHashTable *results, const char *prop_name, NMSettingDiffResult r) +{ + void *p; + + if (r == NM_SETTING_DIFF_RESULT_UNKNOWN) + return; + + if (g_hash_table_lookup_extended(results, prop_name, NULL, &p)) { + if (!NM_FLAGS_ALL((guint) r, GPOINTER_TO_UINT(p))) + g_hash_table_insert(results, + g_strdup(prop_name), + GUINT_TO_POINTER(((guint) r) | GPOINTER_TO_UINT(p))); + } else + g_hash_table_insert(results, g_strdup(prop_name), GUINT_TO_POINTER(r)); +} + +/** + * nm_setting_diff: + * @a: a #NMSetting + * @b: a second #NMSetting to compare with the first + * @flags: compare flags, e.g. %NM_SETTING_COMPARE_FLAG_EXACT + * @invert_results: this parameter is used internally by libnm and should + * be set to %FALSE. If %TRUE inverts the meaning of the #NMSettingDiffResult. + * @results: (inout) (transfer full) (element-type utf8 guint32): if the + * settings differ, on return a hash table mapping the differing keys to one or + * more %NMSettingDiffResult values OR-ed together. If the settings do not + * differ, any hash table passed in is unmodified. If no hash table is passed + * in and the settings differ, a new one is created and returned. + * + * Compares two #NMSetting objects for similarity, with comparison behavior + * modified by a set of flags. See the documentation for #NMSettingCompareFlags + * for a description of each flag's behavior. If the settings differ, the keys + * of each setting that differ from the other are added to @results, mapped to + * one or more #NMSettingDiffResult values. + * + * Returns: %TRUE if the settings contain the same values, %FALSE if they do not + **/ +gboolean +nm_setting_diff(NMSetting * a, + NMSetting * b, + NMSettingCompareFlags flags, + gboolean invert_results, + GHashTable ** results) +{ + return _nm_setting_diff(NULL, a, NULL, b, flags, invert_results, results); +} + +gboolean +_nm_setting_diff(NMConnection * con_a, + NMSetting * a, + NMConnection * con_b, + NMSetting * b, + NMSettingCompareFlags flags, + gboolean invert_results, + GHashTable ** results) +{ + const NMSettInfoSetting *sett_info; + guint i; + NMSettingDiffResult a_result = NM_SETTING_DIFF_RESULT_IN_A; + NMSettingDiffResult b_result = NM_SETTING_DIFF_RESULT_IN_B; + NMSettingDiffResult a_result_default = NM_SETTING_DIFF_RESULT_IN_A_DEFAULT; + NMSettingDiffResult b_result_default = NM_SETTING_DIFF_RESULT_IN_B_DEFAULT; + gboolean results_created = FALSE; + gboolean compared_any = FALSE; + gboolean diff_found = FALSE; + + g_return_val_if_fail(results != NULL, FALSE); + g_return_val_if_fail(NM_IS_SETTING(a), FALSE); + if (b) { + g_return_val_if_fail(NM_IS_SETTING(b), FALSE); + g_return_val_if_fail(G_OBJECT_TYPE(a) == G_OBJECT_TYPE(b), FALSE); + } + + nm_assert(!con_a || NM_IS_CONNECTION(con_a)); + nm_assert(!con_b || NM_IS_CONNECTION(con_b)); + + if ((flags + & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT + | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) + == (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT + | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) { + /* conflicting flags: default to WITH_DEFAULT (clearing NO_DEFAULT). */ + flags &= ~NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT; + } + + /* If the caller is calling this function in a pattern like this to get + * complete diffs: + * + * nm_setting_diff (A, B, FALSE, &results); + * nm_setting_diff (B, A, TRUE, &results); + * + * and wants us to invert the results so that the second invocation comes + * out correctly, do that here. + */ + if (invert_results) { + a_result = NM_SETTING_DIFF_RESULT_IN_B; + b_result = NM_SETTING_DIFF_RESULT_IN_A; + a_result_default = NM_SETTING_DIFF_RESULT_IN_B_DEFAULT; + b_result_default = NM_SETTING_DIFF_RESULT_IN_A_DEFAULT; + } + + if (*results == NULL) { + *results = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); + results_created = TRUE; + } + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(a)); + + if (sett_info->detail.gendata_info) { + const char * key; + GVariant * val, *val2; + GHashTableIter iter; + GenData * a_gendata = _gendata_hash(a, FALSE); + GenData * b_gendata = b ? _gendata_hash(b, FALSE) : NULL; + + if (!a_gendata || !b_gendata) { + if (a_gendata || b_gendata) { + NMSettingDiffResult one_sided_result; + + one_sided_result = a_gendata ? a_result : b_result; + g_hash_table_iter_init(&iter, a_gendata ? a_gendata->hash : b_gendata->hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, NULL)) { + diff_found = TRUE; + _setting_diff_add_result(*results, key, one_sided_result); + } + } + } else { + g_hash_table_iter_init(&iter, a_gendata->hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + val2 = g_hash_table_lookup(b_gendata->hash, key); + compared_any = TRUE; + if (!val2 || !g_variant_equal(val, val2)) { + diff_found = TRUE; + _setting_diff_add_result(*results, key, a_result); + } + } + g_hash_table_iter_init(&iter, b_gendata->hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + val2 = g_hash_table_lookup(a_gendata->hash, key); + compared_any = TRUE; + if (!val2 || !g_variant_equal(val, val2)) { + diff_found = TRUE; + _setting_diff_add_result(*results, key, b_result); + } + } + } + } else { + for (i = 0; i < sett_info->property_infos_len; i++) { + NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN; + const NMSettInfoProperty *property_info; + NMTernary compare_result; + GParamSpec * prop_spec; + + compare_result = _compare_property(sett_info, i, con_a, a, con_b, b, flags); + if (compare_result == NM_TERNARY_DEFAULT) + continue; + + if (NM_FLAGS_ANY(flags, + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS + | NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS) + && b && compare_result == NM_TERNARY_FALSE) { + /* we have setting @b and the property is not the same. But we also are instructed + * to ignore secrets based on the flags. + * + * Note that compare_property() called with two settings will ignore secrets + * based on the flags, but it will do so if *both* settings have the flag we + * look for. So that is symmetric behavior and good. + * + * But for the purpose of diff(), we do a asymmetric comparison because and + * we want to skip testing the property if setting @a alone indicates to do + * so. + * + * We need to double-check whether the property should be ignored by + * looking at @a alone. */ + if (_compare_property(sett_info, i, con_a, a, NULL, NULL, flags) + == NM_TERNARY_DEFAULT) + continue; + } + + compared_any = TRUE; + + property_info = &sett_info->property_infos[i]; + prop_spec = property_info->param_spec; + + if (b) { + if (compare_result == NM_TERNARY_FALSE) { + if (prop_spec) { + gboolean a_is_default, b_is_default; + GValue value = G_VALUE_INIT; + + g_value_init(&value, prop_spec->value_type); + g_object_get_property(G_OBJECT(a), prop_spec->name, &value); + a_is_default = g_param_value_defaults(prop_spec, &value); + + g_value_reset(&value); + g_object_get_property(G_OBJECT(b), prop_spec->name, &value); + b_is_default = g_param_value_defaults(prop_spec, &value); + + g_value_unset(&value); + if (!NM_FLAGS_HAS(flags, + NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT)) { + if (!a_is_default) + r |= a_result; + if (!b_is_default) + r |= b_result; + } else { + r |= a_result | b_result; + if (a_is_default) + r |= a_result_default; + if (b_is_default) + r |= b_result_default; + } + } else + r |= a_result | b_result; + } + } else if ((flags + & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT + | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) + == 0) + r = a_result; /* only in A */ + else { + if (prop_spec) { + GValue value = G_VALUE_INIT; + + g_value_init(&value, prop_spec->value_type); + g_object_get_property(G_OBJECT(a), prop_spec->name, &value); + if (!g_param_value_defaults(prop_spec, &value)) + r |= a_result; + else if (flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) + r |= a_result | a_result_default; + + g_value_unset(&value); + } else + r |= a_result; + } + + if (r != NM_SETTING_DIFF_RESULT_UNKNOWN) { + diff_found = TRUE; + _setting_diff_add_result(*results, property_info->name, r); + } + } + } + + if (!compared_any && !b) { + /* special case: the setting has no properties, and the opposite + * setting @b is not given. The settings differ, and we signal that + * by returning an empty results hash. */ + diff_found = TRUE; + } + + if (diff_found) { + /* if there is a difference, we always return FALSE. It also means, we might + * have allocated a new @results hash, and return it to the caller. */ + return FALSE; + } else { + if (results_created) { + /* the allocated hash is unused. Clear it again. */ + g_hash_table_destroy(*results); + *results = NULL; + } else { + /* we found no diff, and return false. However, the input + * @result is returned unmodified. */ + } + return TRUE; + } +} + +static void +enumerate_values(const NMSettInfoProperty *property_info, + NMSetting * setting, + NMSettingValueIterFn func, + gpointer user_data) +{ + GValue value = G_VALUE_INIT; + + if (!property_info->param_spec) + return; + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(property_info->param_spec)); + g_object_get_property(G_OBJECT(setting), property_info->param_spec->name, &value); + func(setting, + property_info->param_spec->name, + &value, + property_info->param_spec->flags, + user_data); + g_value_unset(&value); +} + +/** + * nm_setting_enumerate_values: + * @setting: the #NMSetting + * @func: (scope call): user-supplied function called for each property of the setting + * @user_data: user data passed to @func at each invocation + * + * Iterates over each property of the #NMSetting object, calling the supplied + * user function for each property. + **/ +void +nm_setting_enumerate_values(NMSetting *setting, NMSettingValueIterFn func, gpointer user_data) +{ + const NMSettInfoSetting *sett_info; + guint i; + + g_return_if_fail(NM_IS_SETTING(setting)); + g_return_if_fail(func != NULL); + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); + + if (sett_info->detail.gendata_info) { + const char *const *names; + guint n_properties; + + /* the properties of this setting are not real GObject properties. + * Hence, this API makes little sense (or does it?). Still, call + * @func with each value. */ + n_properties = _nm_setting_option_get_all(setting, &names, NULL); + if (n_properties > 0) { + gs_strfreev char **keys = g_strdupv((char **) names); + GHashTable * h = _gendata_hash(setting, FALSE)->hash; + + for (i = 0; i < n_properties; i++) { + GValue value = G_VALUE_INIT; + GVariant *val = g_hash_table_lookup(h, keys[i]); + + if (!val) { + /* was deleted in the meantime? Skip */ + continue; + } + + g_value_init(&value, G_TYPE_VARIANT); + g_value_set_variant(&value, val); + /* call it will GParamFlags 0. It shall indicate that this + * is not a "real" GObject property. */ + func(setting, keys[i], &value, 0, user_data); + g_value_unset(&value); + } + } + return; + } + + for (i = 0; i < sett_info->property_infos_len; i++) { + NM_SETTING_GET_CLASS(setting)->enumerate_values( + _nm_sett_info_property_info_get_sorted(sett_info, i), + setting, + func, + user_data); + } +} + +static gboolean +aggregate(NMSetting *setting, int type_i, gpointer arg) +{ + NMConnectionAggregateType type = type_i; + const NMSettInfoSetting * sett_info; + guint i; + + nm_assert(NM_IN_SET(type, + NM_CONNECTION_AGGREGATE_ANY_SECRETS, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS)); + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); + for (i = 0; i < sett_info->property_infos_len; i++) { + const NMSettInfoProperty * property_info = &sett_info->property_infos[i]; + GParamSpec * prop_spec = property_info->param_spec; + nm_auto_unset_gvalue GValue value = G_VALUE_INIT; + NMSettingSecretFlags secret_flags; + + if (!prop_spec || !NM_FLAGS_HAS(prop_spec->flags, NM_SETTING_PARAM_SECRET)) { + nm_assert(!nm_setting_get_secret_flags(setting, property_info->name, NULL, NULL)); + continue; + } + + /* for the moment, all aggregate types only care about secrets. */ + nm_assert(nm_setting_get_secret_flags(setting, property_info->name, NULL, NULL)); + + switch (type) { + case NM_CONNECTION_AGGREGATE_ANY_SECRETS: + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(prop_spec)); + g_object_get_property(G_OBJECT(setting), prop_spec->name, &value); + if (!g_param_value_defaults(prop_spec, &value)) { + *((gboolean *) arg) = TRUE; + return TRUE; + } + break; + + case NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS: + if (!nm_setting_get_secret_flags(setting, prop_spec->name, &secret_flags, NULL)) + nm_assert_not_reached(); + if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) { + *((gboolean *) arg) = TRUE; + return TRUE; + } + break; + } + } + + return FALSE; +} + +/** + * _nm_setting_aggregate: + * @setting: the #NMSetting to aggregate. + * @type: the #NMConnectionAggregateType aggregate type. + * @arg: the in/out arguments for aggregation. They depend on @type. + * + * This is the implementation detail of _nm_connection_aggregate(). It + * makes no sense to call this function directly outside of _nm_connection_aggregate(). + * + * Returns: %TRUE if afterwards the aggregation is complete. That means, + * the only caller _nm_connection_aggregate() will not visit other settings + * after a setting returns %TRUE (indicating that there is nothing further + * to aggregate). Note that is very different from the boolean return + * argument of _nm_connection_aggregate(), which serves a different purpose. + */ +gboolean +_nm_setting_aggregate(NMSetting *setting, NMConnectionAggregateType type, gpointer arg) +{ + g_return_val_if_fail(NM_IS_SETTING(setting), FALSE); + g_return_val_if_fail(arg, FALSE); + g_return_val_if_fail(NM_IN_SET(type, + NM_CONNECTION_AGGREGATE_ANY_SECRETS, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS), + FALSE); + + return NM_SETTING_GET_CLASS(setting)->aggregate(setting, type, arg); +} + +static gboolean +clear_secrets(const NMSettInfoSetting * sett_info, + guint property_idx, + NMSetting * setting, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) +{ + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + GParamSpec * param_spec = sett_info->property_infos[property_idx].param_spec; + + if (!param_spec) + return FALSE; + + if (!NM_FLAGS_HAS(param_spec->flags, NM_SETTING_PARAM_SECRET)) + return FALSE; + + if (func) { + if (!nm_setting_get_secret_flags(setting, param_spec->name, &flags, NULL)) + nm_assert_not_reached(); + if (!func(setting, param_spec->name, flags, user_data)) + return FALSE; + } else + nm_assert(nm_setting_get_secret_flags(setting, param_spec->name, NULL, NULL)); + + { + nm_auto_unset_gvalue GValue value = G_VALUE_INIT; + + g_value_init(&value, param_spec->value_type); + g_object_get_property(G_OBJECT(setting), param_spec->name, &value); + if (g_param_value_defaults(param_spec, &value)) + return FALSE; + + g_param_value_set_default(param_spec, &value); + g_object_set_property(G_OBJECT(setting), param_spec->name, &value); + } + + return TRUE; +} + +/** + * _nm_setting_clear_secrets: + * @setting: the #NMSetting + * @func: (scope call): function to be called to determine whether a + * specific secret should be cleared or not + * @user_data: caller-supplied data passed to @func + * + * Clears and frees secrets determined by @func. + * + * Returns: %TRUE if the setting changed at all + **/ +gboolean +_nm_setting_clear_secrets(NMSetting * setting, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) +{ + const NMSettInfoSetting *sett_info; + gboolean changed = FALSE; + guint i; + gboolean (*my_clear_secrets)(const struct _NMSettInfoSetting *sett_info, + guint property_idx, + NMSetting * setting, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data); + + g_return_val_if_fail(NM_IS_SETTING(setting), FALSE); + + my_clear_secrets = NM_SETTING_GET_CLASS(setting)->clear_secrets; + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); + for (i = 0; i < sett_info->property_infos_len; i++) { + changed |= my_clear_secrets(sett_info, i, setting, func, user_data); + } + return changed; +} + +/** + * _nm_setting_need_secrets: + * @setting: the #NMSetting + * + * Returns an array of property names for each secret which may be required + * to make a successful connection. The returned hints are only intended as a + * guide to what secrets may be required, because in some circumstances, there + * is no way to conclusively determine exactly which secrets are needed. + * + * Returns: (transfer container) (element-type utf8): a #GPtrArray containing + * the property names of secrets of the #NMSetting which may be required; the + * caller owns the array and must free it with g_ptr_array_free(), but must not + * free the elements. + **/ +GPtrArray * +_nm_setting_need_secrets(NMSetting *setting) +{ + GPtrArray *secrets = NULL; + + g_return_val_if_fail(NM_IS_SETTING(setting), NULL); + + if (NM_SETTING_GET_CLASS(setting)->need_secrets) + secrets = NM_SETTING_GET_CLASS(setting)->need_secrets(setting); + + return secrets; +} + +static int +update_one_secret(NMSetting *setting, const char *key, GVariant *value, GError **error) +{ + const NMSettInfoProperty *property; + GParamSpec * prop_spec; + GValue prop_value = { + 0, + }; + + property = _nm_setting_class_get_property_info(NM_SETTING_GET_CLASS(setting), key); + if (!property) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND, + _("secret not found")); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), key); + return NM_SETTING_UPDATE_SECRET_ERROR; + } + + /* Silently ignore non-secrets */ + prop_spec = property->param_spec; + if (!prop_spec || !(prop_spec->flags & NM_SETTING_PARAM_SECRET)) + return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; + + if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING) && G_IS_PARAM_SPEC_STRING(prop_spec)) { + /* String is expected to be a common case. Handle it specially and check + * whether the value is already set. Otherwise, we just reset the + * property and assume the value got modified. + */ + char *v; + + g_object_get(G_OBJECT(setting), prop_spec->name, &v, NULL); + if (g_strcmp0(v, g_variant_get_string(value, NULL)) == 0) { + g_free(v); + return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; + } + g_free(v); + } + + g_value_init(&prop_value, prop_spec->value_type); + set_property_from_dbus(property, value, &prop_value); + g_object_set_property(G_OBJECT(setting), prop_spec->name, &prop_value); + g_value_unset(&prop_value); + + return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; +} + +/** + * _nm_setting_update_secrets: + * @setting: the #NMSetting + * @secrets: a #GVariant of type #NM_VARIANT_TYPE_SETTING, mapping property + * names to secrets. + * @error: location to store error, or %NULL + * + * Update the setting's secrets, given a dictionary of secrets intended for that + * setting (deserialized from D-Bus for example). + * + * Returns: an #NMSettingUpdateSecretResult + **/ +NMSettingUpdateSecretResult +_nm_setting_update_secrets(NMSetting *setting, GVariant *secrets, GError **error) +{ + GVariantIter iter; + const char * secret_key; + GVariant * secret_value; + GError * tmp_error = NULL; + NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; + + g_return_val_if_fail(NM_IS_SETTING(setting), NM_SETTING_UPDATE_SECRET_ERROR); + g_return_val_if_fail(g_variant_is_of_type(secrets, NM_VARIANT_TYPE_SETTING), + NM_SETTING_UPDATE_SECRET_ERROR); + if (error) + g_return_val_if_fail(*error == NULL, NM_SETTING_UPDATE_SECRET_ERROR); + + g_variant_iter_init(&iter, secrets); + while (g_variant_iter_next(&iter, "{&sv}", &secret_key, &secret_value)) { + int success; + + success = NM_SETTING_GET_CLASS(setting)->update_one_secret(setting, + secret_key, + secret_value, + &tmp_error); + nm_assert(!((success == NM_SETTING_UPDATE_SECRET_ERROR) ^ (!!tmp_error))); + + g_variant_unref(secret_value); + + if (success == NM_SETTING_UPDATE_SECRET_ERROR) { + g_propagate_error(error, tmp_error); + return NM_SETTING_UPDATE_SECRET_ERROR; + } + + if (success == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED) + result = NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; + } + + return result; +} + +static void +for_each_secret(NMSetting * setting, + const char * secret_name, + GVariant * val, + gboolean remove_non_secrets, + _NMConnectionForEachSecretFunc callback, + gpointer callback_data, + GVariantBuilder * setting_builder) +{ + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + if (!nm_setting_get_secret_flags(setting, secret_name, &secret_flags, NULL)) { + if (!remove_non_secrets) + g_variant_builder_add(setting_builder, "{sv}", secret_name, val); + return; + } + if (callback(secret_flags, callback_data)) + g_variant_builder_add(setting_builder, "{sv}", secret_name, val); +} + +static void +_set_error_secret_property_not_found(GError **error, NMSetting *setting, const char *secret_name) +{ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND, + _("not a secret property")); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), secret_name); +} + +gboolean +_nm_setting_property_is_regular_secret(NMSetting *setting, const char *secret_name) +{ + const NMSettInfoProperty *property; + + nm_assert(NM_IS_SETTING(setting)); + nm_assert(secret_name); + + property = _nm_setting_class_get_property_info(NM_SETTING_GET_CLASS(setting), secret_name); + return property && property->param_spec + && NM_FLAGS_HAS(property->param_spec->flags, NM_SETTING_PARAM_SECRET); +} + +gboolean +_nm_setting_property_is_regular_secret_flags(NMSetting *setting, const char *secret_flags_name) +{ + const NMSettInfoProperty *property; + + nm_assert(NM_IS_SETTING(setting)); + nm_assert(secret_flags_name); + + property = + _nm_setting_class_get_property_info(NM_SETTING_GET_CLASS(setting), secret_flags_name); + return property && property->param_spec + && !NM_FLAGS_HAS(property->param_spec->flags, NM_SETTING_PARAM_SECRET) + && G_PARAM_SPEC_VALUE_TYPE(property->param_spec) == NM_TYPE_SETTING_SECRET_FLAGS; +} + +static gboolean +get_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags *out_flags, + GError ** error) +{ + gs_free char * secret_flags_name_free = NULL; + const char * secret_flags_name; + NMSettingSecretFlags flags; + + if (!_nm_setting_property_is_regular_secret(setting, secret_name)) { + _set_error_secret_property_not_found(error, setting, secret_name); + NM_SET_OUT(out_flags, NM_SETTING_SECRET_FLAG_NONE); + return FALSE; + } + + secret_flags_name = nm_construct_name_a("%s-flags", secret_name, &secret_flags_name_free); + + nm_assert(_nm_setting_property_is_regular_secret_flags(setting, secret_flags_name)); + + g_object_get(G_OBJECT(setting), secret_flags_name, &flags, NULL); + NM_SET_OUT(out_flags, flags); + return TRUE; +} + +/** + * nm_setting_get_secret_flags: + * @setting: the #NMSetting + * @secret_name: the secret key name to get flags for + * @out_flags: on success, the #NMSettingSecretFlags for the secret + * @error: location to store error, or %NULL + * + * For a given secret, retrieves the #NMSettingSecretFlags describing how to + * handle that secret. + * + * Returns: %TRUE on success (if the given secret name was a valid property of + * this setting, and if that property is secret), %FALSE if not + **/ +gboolean +nm_setting_get_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags *out_flags, + GError ** error) +{ + g_return_val_if_fail(NM_IS_SETTING(setting), FALSE); + g_return_val_if_fail(secret_name != NULL, FALSE); + + return NM_SETTING_GET_CLASS(setting)->get_secret_flags(setting, secret_name, out_flags, error); +} + +static gboolean +set_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags flags, + GError ** error) +{ + gs_free char *secret_flags_name_free = NULL; + const char * secret_flags_name; + + if (!_nm_setting_property_is_regular_secret(setting, secret_name)) { + _set_error_secret_property_not_found(error, setting, secret_name); + return FALSE; + } + + secret_flags_name = nm_construct_name_a("%s-flags", secret_name, &secret_flags_name_free); + + nm_assert(_nm_setting_property_is_regular_secret_flags(setting, secret_flags_name)); + + if (!nm_g_object_set_property_flags(G_OBJECT(setting), + secret_flags_name, + NM_TYPE_SETTING_SECRET_FLAGS, + flags, + error)) + g_return_val_if_reached(FALSE); + return TRUE; +} + +/** + * nm_setting_set_secret_flags: + * @setting: the #NMSetting + * @secret_name: the secret key name to set flags for + * @flags: the #NMSettingSecretFlags for the secret + * @error: location to store error, or %NULL + * + * For a given secret, stores the #NMSettingSecretFlags describing how to + * handle that secret. + * + * Returns: %TRUE on success (if the given secret name was a valid property of + * this setting, and if that property is secret), %FALSE if not + **/ +gboolean +nm_setting_set_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags flags, + GError ** error) +{ + g_return_val_if_fail(NM_IS_SETTING(setting), FALSE); + g_return_val_if_fail(secret_name != NULL, FALSE); + g_return_val_if_fail(_nm_setting_secret_flags_valid(flags), FALSE); + + return NM_SETTING_GET_CLASS(setting)->set_secret_flags(setting, secret_name, flags, error); +} + +/** + * nm_setting_to_string: + * @setting: the #NMSetting + * + * Convert the setting (including secrets!) into a string. For debugging + * purposes ONLY, should NOT be used for serialization of the setting, + * or machine-parsed in any way. The output format is not guaranteed to + * be stable and may change at any time. + * + * Returns: an allocated string containing a textual representation of the + * setting's properties and values, which the caller should + * free with g_free() + **/ +char * +nm_setting_to_string(NMSetting *setting) +{ + GString * string; + gs_unref_variant GVariant *variant = NULL; + GVariant * child; + GVariantIter iter; + + string = g_string_new(nm_setting_get_name(setting)); + g_string_append_c(string, '\n'); + + variant = _nm_setting_to_dbus(setting, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); + + g_variant_iter_init(&iter, variant); + while ((child = g_variant_iter_next_value(&iter))) { + gs_free char * name = NULL; + gs_free char * value_str = NULL; + gs_unref_variant GVariant *value = NULL; + + g_variant_get(child, "{sv}", &name, &value); + value_str = g_variant_print(value, FALSE); + + g_string_append_printf(string, "\t%s : %s\n", name, value_str); + } + + return g_string_free(string, FALSE); +} + +static GVariant * +_nm_setting_get_deprecated_virtual_interface_name(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + NMSettingConnection *s_con; + + if (!connection) + return NULL; + + s_con = nm_connection_get_setting_connection(connection); + if (!s_con) + return NULL; + + if (nm_setting_connection_get_interface_name(s_con)) + return g_variant_new_string(nm_setting_connection_get_interface_name(s_con)); + else + return NULL; +} + +const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_interface_name = { + .dbus_type = G_VARIANT_TYPE_STRING, + .to_dbus_fcn = _nm_setting_get_deprecated_virtual_interface_name, +}; + +const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_i = { + .dbus_type = G_VARIANT_TYPE_INT32, + /* No functions set. This property type is to silently ignore the value on D-Bus. */ +}; + +const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_u = { + .dbus_type = G_VARIANT_TYPE_UINT32, + /* No functions set. This property type is to silently ignore the value on D-Bus. */ +}; + +const NMSettInfoPropertType nm_sett_info_propert_type_plain_i = { + .dbus_type = G_VARIANT_TYPE_INT32, +}; + +const NMSettInfoPropertType nm_sett_info_propert_type_plain_u = { + .dbus_type = G_VARIANT_TYPE_UINT32, +}; + +/*****************************************************************************/ + +static GenData * +_gendata_hash(NMSetting *setting, gboolean create_if_necessary) +{ + NMSettingPrivate *priv; + + nm_assert(NM_IS_SETTING(setting)); + + priv = NM_SETTING_GET_PRIVATE(setting); + + if (G_UNLIKELY(!priv->gendata)) { + if (!create_if_necessary) + return NULL; + priv->gendata = g_slice_new(GenData); + priv->gendata->hash = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref); + priv->gendata->names = NULL; + priv->gendata->values = NULL; + } + + return priv->gendata; +} + +GHashTable * +_nm_setting_option_hash(NMSetting *setting, gboolean create_if_necessary) +{ + GenData *gendata; + + gendata = _gendata_hash(setting, create_if_necessary); + return gendata ? gendata->hash : NULL; +} + +void +_nm_setting_option_notify(NMSetting *setting, gboolean names_changed) +{ + GenData *gendata; + + gendata = _gendata_hash(setting, FALSE); + if (!gendata) + goto out; + + nm_clear_g_free(&gendata->values); + + if (names_changed) { + /* if only the values changed, it's sufficient to invalidate the + * values cache. Otherwise, the names cache must be invalidated too. */ + nm_clear_g_free(&gendata->names); + } + + /* Note, currently there is no way to notify the subclass when gendata changed. + * gendata is only changed in two situations: + * 1) from within NMSetting itself, for example when creating a NMSetting instance + * from keyfile or a D-Bus GVariant. + * 2) actively from the subclass itself + * For 2), we don't need the notification, because the subclass knows that something + * changed. + * For 1), we currently don't need the notification either, because all that the subclass + * currently would do, is emit a g_object_notify() signal. However, 1) only happens when + * the setting instance is newly created, at that point, nobody listens to the signal. + * + * If we ever need it, then we would need to call a virtual function to notify the subclass + * that gendata changed. */ + +out: + _nm_setting_emit_property_changed(setting); +} + +guint +_nm_setting_option_get_all(NMSetting * setting, + const char *const **out_names, + GVariant *const ** out_values) +{ + GenData * gendata; + GHashTable *hash; + guint i, len; + + nm_assert(NM_IS_SETTING(setting)); + + gendata = _gendata_hash(setting, FALSE); + if (!gendata) + goto out_zero; + + hash = gendata->hash; + len = g_hash_table_size(hash); + if (len == 0) + goto out_zero; + + if (!out_names && !out_values) + return len; + + if (G_UNLIKELY(!gendata->names)) { + gendata->names = nm_utils_strdict_get_keys(hash, TRUE, NULL); + } + + if (out_values) { + if (G_UNLIKELY(!gendata->values)) { + gendata->values = g_new(GVariant *, len + 1); + for (i = 0; i < len; i++) + gendata->values[i] = g_hash_table_lookup(hash, gendata->names[i]); + gendata->values[i] = NULL; + } + *out_values = gendata->values; + } + + NM_SET_OUT(out_names, (const char *const *) gendata->names); + return len; + +out_zero: + NM_SET_OUT(out_names, NULL); + NM_SET_OUT(out_values, NULL); + return 0; +} + +/** + * nm_setting_option_get_all_names: + * @setting: the #NMSetting + * @out_len: (allow-none) (out): + * + * Gives the name of all set options. + * + * Returns: (array length=out_len zero-terminated=1) (transfer none): + * A %NULL terminated array of key names. If no names are present, this returns + * %NULL. The returned array and the names are owned by %NMSetting and might be invalidated + * by the next operation. + * + * Since: 1.26 + **/ +const char *const * +nm_setting_option_get_all_names(NMSetting *setting, guint *out_len) +{ + const char *const *names; + guint len; + + g_return_val_if_fail(NM_IS_SETTING(setting), NULL); + + len = _nm_setting_option_get_all(setting, &names, NULL); + NM_SET_OUT(out_len, len); + return names; +} + +gboolean +_nm_setting_option_clear(NMSetting *setting, const char *optname) +{ + GHashTable *ht; + + nm_assert(NM_IS_SETTING(setting)); + nm_assert(nm_str_not_empty(optname)); + + ht = _nm_setting_option_hash(setting, FALSE); + if (!ht) + return FALSE; + + return g_hash_table_remove(ht, optname); +} + +/** + * nm_setting_option_clear_by_name: + * @setting: the #NMSetting + * @predicate: (allow-none) (scope call): the predicate for which names + * should be clear. + * If the predicate returns %TRUE for an option name, the option + * gets removed. If %NULL, all options will be removed. + * + * Since: 1.26 + */ +void +nm_setting_option_clear_by_name(NMSetting *setting, NMUtilsPredicateStr predicate) +{ + GHashTable * hash; + GHashTableIter iter; + const char * name; + gboolean changed = FALSE; + + g_return_if_fail(NM_IS_SETTING(setting)); + + hash = _nm_setting_option_hash(NM_SETTING(setting), FALSE); + if (!hash) + return; + + if (!predicate) { + changed = (g_hash_table_size(hash) > 0); + if (changed) + g_hash_table_remove_all(hash); + } else { + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, NULL)) { + if (predicate(name)) { + g_hash_table_iter_remove(&iter); + changed = TRUE; + } + } + } + + if (changed) + _nm_setting_option_notify(setting, TRUE); +} + +/*****************************************************************************/ + +/** + * nm_setting_option_get: + * @setting: the #NMSetting + * @opt_name: the option name to request. + * + * Returns: (transfer none): the #GVariant or %NULL if the option + * is not set. + * + * Since: 1.26. + */ +GVariant * +nm_setting_option_get(NMSetting *setting, const char *opt_name) +{ + GenData *gendata; + + g_return_val_if_fail(NM_IS_SETTING(setting), FALSE); + g_return_val_if_fail(opt_name, FALSE); + + gendata = _gendata_hash(setting, FALSE); + return gendata ? g_hash_table_lookup(gendata->hash, opt_name) : NULL; +} + +/** + * nm_setting_option_get_boolean: + * @setting: the #NMSetting + * @opt_name: the option to get + * @out_value: (allow-none) (out): the optional output value. + * If the option is unset, %FALSE will be returned. + * + * Returns: %TRUE if @opt_name is set to a boolean variant. + * + * Since: 1.26 + */ +gboolean +nm_setting_option_get_boolean(NMSetting *setting, const char *opt_name, gboolean *out_value) +{ + GVariant *v; + + v = nm_setting_option_get(NM_SETTING(setting), opt_name); + if (v && g_variant_is_of_type(v, G_VARIANT_TYPE_BOOLEAN)) { + NM_SET_OUT(out_value, g_variant_get_boolean(v)); + return TRUE; + } + NM_SET_OUT(out_value, FALSE); + return FALSE; +} + +/** + * nm_setting_option_get_uint32: + * @setting: the #NMSetting + * @opt_name: the option to get + * @out_value: (allow-none) (out): the optional output value. + * If the option is unset, 0 will be returned. + * + * Returns: %TRUE if @opt_name is set to a uint32 variant. + * + * Since: 1.26 + */ +gboolean +nm_setting_option_get_uint32(NMSetting *setting, const char *opt_name, guint32 *out_value) +{ + GVariant *v; + + v = nm_setting_option_get(NM_SETTING(setting), opt_name); + if (v && g_variant_is_of_type(v, G_VARIANT_TYPE_UINT32)) { + NM_SET_OUT(out_value, g_variant_get_uint32(v)); + return TRUE; + } + NM_SET_OUT(out_value, 0); + return FALSE; +} + +/** + * nm_setting_option_set: + * @setting: the #NMSetting + * @opt_name: the option name to set + * @variant: (allow-none): the variant to set. + * + * If @variant is %NULL, this clears the option if it is set. + * Otherwise, @variant is set as the option. If @variant is + * a floating reference, it will be consumed. + * + * Note that not all setting types support options. It is a bug + * setting a variant to a setting that doesn't support it. + * Currently, only #NMSettingEthtool supports it. + * + * Since: 1.26 + */ +void +nm_setting_option_set(NMSetting *setting, const char *opt_name, GVariant *variant) +{ + GVariant * old_variant; + gboolean changed_name; + gboolean changed_value; + GHashTable *hash; + + g_return_if_fail(NM_IS_SETTING(setting)); + g_return_if_fail(opt_name); + + hash = _nm_setting_option_hash(setting, variant != NULL); + + if (!variant) { + if (hash) { + if (g_hash_table_remove(hash, opt_name)) + _nm_setting_option_notify(setting, TRUE); + } + return; + } + + /* Currently, it is a bug setting any option, unless the setting type supports it. + * And currently, only NMSettingEthtool supports it. + * + * In the future, more setting types may support it. Or we may relax this so + * that options can be attached to all setting types (to indicate "unsupported" + * settings for forward compatibility). + * + * As it is today, internal code will only add gendata options to NMSettingEthtool, + * and there exists not public API to add such options. Still, it is permissible + * to call get(), clear() and set(variant=NULL) also on settings that don't support + * it, as these operations don't add options. + */ + g_return_if_fail( + _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting))->detail.gendata_info); + + old_variant = g_hash_table_lookup(hash, opt_name); + + changed_name = (old_variant == NULL); + changed_value = changed_name || !g_variant_equal(old_variant, variant); + + /* We always want to replace the variant, even if it has + * the same value according to g_variant_equal(). The reason + * is that we want to take a reference on @variant, because + * that is what the user might expect. */ + g_hash_table_insert(hash, g_strdup(opt_name), g_variant_ref_sink(variant)); + + if (changed_value) + _nm_setting_option_notify(setting, !changed_name); +} + +/** + * nm_setting_option_set_boolean: + * @setting: the #NMSetting + * @value: the value to set. + * + * Like nm_setting_option_set() to set a boolean GVariant. + * + * Since: 1.26 + */ +void +nm_setting_option_set_boolean(NMSetting *setting, const char *opt_name, gboolean value) +{ + GVariant * old_variant; + gboolean changed_name; + gboolean changed_value; + GHashTable *hash; + + g_return_if_fail(NM_IS_SETTING(setting)); + g_return_if_fail(opt_name); + + value = (!!value); + + hash = _nm_setting_option_hash(setting, TRUE); + + old_variant = g_hash_table_lookup(hash, opt_name); + + changed_name = (old_variant == NULL); + changed_value = changed_name + || (!g_variant_is_of_type(old_variant, G_VARIANT_TYPE_BOOLEAN) + || g_variant_get_boolean(old_variant) != value); + + g_hash_table_insert(hash, g_strdup(opt_name), g_variant_ref_sink(g_variant_new_boolean(value))); + + if (changed_value) + _nm_setting_option_notify(setting, !changed_name); +} + +/** + * nm_setting_option_set_uint32: + * @setting: the #NMSetting + * @value: the value to set. + * + * Like nm_setting_option_set() to set a uint32 GVariant. + * + * Since: 1.26 + */ +void +nm_setting_option_set_uint32(NMSetting *setting, const char *opt_name, guint32 value) +{ + GVariant * old_variant; + gboolean changed_name; + gboolean changed_value; + GHashTable *hash; + + g_return_if_fail(NM_IS_SETTING(setting)); + g_return_if_fail(opt_name); + + hash = _nm_setting_option_hash(setting, TRUE); + + old_variant = g_hash_table_lookup(hash, opt_name); + + changed_name = (old_variant == NULL); + changed_value = changed_name + || (!g_variant_is_of_type(old_variant, G_VARIANT_TYPE_UINT32) + || g_variant_get_uint32(old_variant) != value); + + g_hash_table_insert(hash, g_strdup(opt_name), g_variant_ref_sink(g_variant_new_uint32(value))); + + if (changed_value) + _nm_setting_option_notify(setting, !changed_name); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSetting *setting = NM_SETTING(object); + + switch (prop_id) { + case PROP_NAME: + g_value_set_string(value, nm_setting_get_name(setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_init(NMSetting *setting) +{} + +static void +finalize(GObject *object) +{ + NMSettingPrivate *priv = NM_SETTING_GET_PRIVATE(object); + + if (priv->gendata) { + g_free(priv->gendata->names); + g_free(priv->gendata->values); + g_hash_table_unref(priv->gendata->hash); + g_slice_free(GenData, priv->gendata); + } + + G_OBJECT_CLASS(nm_setting_parent_class)->finalize(object); +} + +static void +nm_setting_class_init(NMSettingClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(setting_class); + + g_type_class_add_private(setting_class, sizeof(NMSettingPrivate)); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + setting_class->update_one_secret = update_one_secret; + setting_class->get_secret_flags = get_secret_flags; + setting_class->set_secret_flags = set_secret_flags; + setting_class->compare_property = compare_property; + setting_class->clear_secrets = clear_secrets; + setting_class->for_each_secret = for_each_secret; + setting_class->duplicate_copy_properties = duplicate_copy_properties; + setting_class->enumerate_values = enumerate_values; + setting_class->aggregate = aggregate; + setting_class->init_from_dbus = init_from_dbus; + + /** + * NMSetting:name: + * + * The setting's name, which uniquely identifies the setting within the + * connection. Each setting type has a name unique to that type, for + * example "ppp" or "802-11-wireless" or "802-3-ethernet". + **/ + obj_properties[PROP_NAME] = g_param_spec_string(NM_SETTING_NAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} diff --git a/src/libnm-core-impl/nm-simple-connection.c b/src/libnm-core-impl/nm-simple-connection.c new file mode 100644 index 0000000..6834c41 --- /dev/null +++ b/src/libnm-core-impl/nm-simple-connection.c @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2014 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-simple-connection.h" + +#include "nm-setting-private.h" + +/** + * SECTION:nm-simple-connection + * @short_description: An unmanaged connection + * + * An #NMSimpleConnection does not directly represent a D-Bus-exported connection, + * but might be used in the process of creating a new one. + **/ + +/*****************************************************************************/ + +static void nm_simple_connection_interface_init(NMConnectionInterface *iface); + +G_DEFINE_TYPE_WITH_CODE(NMSimpleConnection, + nm_simple_connection, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(NM_TYPE_CONNECTION, + nm_simple_connection_interface_init);) + +/*****************************************************************************/ + +static void +nm_simple_connection_init(NMSimpleConnection *self) +{} + +/** + * nm_simple_connection_new: + * + * Creates a new #NMSimpleConnection object with no #NMSetting objects. + * + * Returns: (transfer full): the new empty #NMConnection object + **/ +NMConnection * +nm_simple_connection_new(void) +{ + return g_object_new(NM_TYPE_SIMPLE_CONNECTION, NULL); +} + +/** + * _nm_simple_connection_new_from_dbus: + * @dict: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION describing the connection + * @error: on unsuccessful return, an error + * + * Creates a new #NMSimpleConnection from a hash table describing the + * connection. See nm_connection_to_dbus() for a description of the expected + * hash table. + * + * Returns: (transfer full): the new #NMSimpleConnection object, populated with + * settings created from the values in the hash table, or %NULL if there was + * an error. + **/ +NMConnection * +_nm_simple_connection_new_from_dbus(GVariant *dict, NMSettingParseFlags parse_flags, GError **error) +{ + NMConnection *connection; + + g_return_val_if_fail(dict != NULL, NULL); + g_return_val_if_fail(g_variant_is_of_type(dict, NM_VARIANT_TYPE_CONNECTION), NULL); + g_return_val_if_fail(!NM_FLAGS_ANY(parse_flags, ~NM_SETTING_PARSE_FLAGS_ALL), NULL); + g_return_val_if_fail( + !NM_FLAGS_ALL(parse_flags, + NM_SETTING_PARSE_FLAGS_STRICT | NM_SETTING_PARSE_FLAGS_BEST_EFFORT), + NULL); + + connection = nm_simple_connection_new(); + if (!_nm_connection_replace_settings(connection, dict, parse_flags, error)) + g_clear_object(&connection); + return connection; +} + +/** + * nm_simple_connection_new_from_dbus: + * @dict: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION describing the connection + * @error: on unsuccessful return, an error + * + * Creates a new #NMSimpleConnection from a hash table describing the + * connection and normalize the connection. See nm_connection_to_dbus() for a + * description of the expected hash table. + * + * Returns: (transfer full): the new #NMSimpleConnection object, populated with + * settings created from the values in the hash table, or %NULL if the + * connection failed to normalize. + **/ +NMConnection * +nm_simple_connection_new_from_dbus(GVariant *dict, GError **error) +{ + return _nm_simple_connection_new_from_dbus(dict, NM_SETTING_PARSE_FLAGS_NORMALIZE, error); +} + +/** + * nm_simple_connection_new_clone: + * @connection: the #NMConnection to clone + * + * Clones an #NMConnection as an #NMSimpleConnection. + * + * Returns: (transfer full): a new #NMConnection containing the same settings + * and properties as the source #NMConnection + **/ +NMConnection * +nm_simple_connection_new_clone(NMConnection *connection) +{ + NMConnection *clone; + const char * path; + + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + + clone = nm_simple_connection_new(); + + path = nm_connection_get_path(connection); + if (path) + nm_connection_set_path(clone, path); + + nm_connection_replace_settings_from_connection(clone, connection); + + return clone; +} + +static void +dispose(GObject *object) +{ +#if NM_MORE_ASSERTS + g_signal_handlers_disconnect_by_data(object, + (gpointer) &_nmtst_connection_unchanging_user_data); +#endif + + nm_connection_clear_secrets(NM_CONNECTION(object)); + + G_OBJECT_CLASS(nm_simple_connection_parent_class)->dispose(object); +} + +static void +nm_simple_connection_class_init(NMSimpleConnectionClass *simple_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(simple_class); + + object_class->dispose = dispose; +} + +static void +nm_simple_connection_interface_init(NMConnectionInterface *iface) +{} diff --git a/src/libnm-core-impl/nm-team-utils.c b/src/libnm-core-impl/nm-team-utils.c new file mode 100644 index 0000000..88983d0 --- /dev/null +++ b/src/libnm-core-impl/nm-team-utils.c @@ -0,0 +1,2866 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#define NM_VALUE_TYPE_DEFINE_FUNCTIONS + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-team-utils.h" + +#include "nm-errors.h" +#include "nm-utils-private.h" +#include "libnm-glib-aux/nm-json-aux.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-setting-team.h" +#include "nm-setting-team-port.h" + +/*****************************************************************************/ + +typedef enum { + SET_FIELD_MODE_UNSET = 0, + SET_FIELD_MODE_SET = 1, + + /* Sets the field as set, unless the field is at the default. + * This is the case for API that is called from NMSettingTeam/NMSettingTeamPort. + * This means, using libnm API to reset the value of a NMSetting to the default, + * will mark the field as unset. + * This is different from initializing the field when parsing JSON/GVariant. In + * that case an explicitly set field (even set to the default value) will be remembered + * to be set. */ + SET_FIELD_MODE_SET_UNLESS_DEFAULT = 2, +} SetFieldModeEnum; + +typedef enum { + RESET_JSON_NO = FALSE, + RESET_JSON_YES = TRUE, +} ResetJsonEnum; + +/* we rely on "config" being the first. At various places we iterate over attribute types, + * starting after "config".*/ +G_STATIC_ASSERT(_NM_TEAM_ATTRIBUTE_0 == 0); +G_STATIC_ASSERT(NM_TEAM_ATTRIBUTE_CONFIG == 1); + +static const char *const _valid_names_runner[] = { + NM_SETTING_TEAM_RUNNER_BROADCAST, + NM_SETTING_TEAM_RUNNER_ROUNDROBIN, + NM_SETTING_TEAM_RUNNER_RANDOM, + NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP, + NM_SETTING_TEAM_RUNNER_LOADBALANCE, + NM_SETTING_TEAM_RUNNER_LACP, + NULL, +}; + +static const char *const _valid_names_runner_hwaddr_policy[] = { + NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL, + NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE, + NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE, + NULL, +}; + +static const char *const _valid_names_runner_tx_balancer[] = { + "basic", + NULL, +}; + +static const char *const _valid_names_runner_tx_hash[] = { + "eth", + "vlan", + "ipv4", + "ipv6", + "ip", + "l3", + "l4", + "tcp", + "udp", + "sctp", + NULL, +}; + +static const char *const _valid_names_runner_agg_select_policy[] = { + "lacp_prio", + "lacp_prio_stable", + "bandwidth", + "count", + "port_config", + NULL, +}; + +typedef struct { + NMTeamAttribute team_attr; + const char *const *valid_runners; +} RunnerCompatElem; + +static const RunnerCompatElem _runner_compat_lst[] = { + { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY, + NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP), + }, + { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, + NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LOADBALANCE, NM_SETTING_TEAM_RUNNER_LACP), + }, + { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER, + NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LOADBALANCE, NM_SETTING_TEAM_RUNNER_LACP), + }, + { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL, + NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LOADBALANCE, NM_SETTING_TEAM_RUNNER_LACP), + }, + { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE, + NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LACP), + }, + { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE, + NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LACP), + }, + { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO, + NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LACP), + }, + { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS, + NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LACP), + }, + { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY, + NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LACP), + }, +}; + +typedef struct { + const char *const *js_keys; + const char * property_name; + NMValueTypUnion default_val; + union { + struct { + gint32 min; + gint32 max; + } r_int32; + struct { + const char *const *valid_names; + } r_string; + } range; + NMTeamAttribute team_attr; + NMValueType value_type; + guint8 field_offset; + guint8 js_keys_len; + bool for_master : 1; + bool for_port : 1; + bool has_range : 1; +} TeamAttrData; + +#define TEAM_ATTR_IDX(_is_port, _team_attr) \ + (((!(_is_port) || (_team_attr) < _NM_TEAM_ATTRIBUTE_START) \ + ? (int) (_team_attr) \ + : (((int) (_NM_TEAM_ATTRIBUTE_MASTER_NUM - _NM_TEAM_ATTRIBUTE_START)) \ + + ((int) (_team_attr)))) \ + - 1) + +#define TEAM_ATTR_IDX_CONFIG (TEAM_ATTR_IDX(FALSE, NM_TEAM_ATTRIBUTE_CONFIG)) + +static const TeamAttrData team_attr_datas[] = { + +#define _JS_KEYS(...) .js_keys = NM_MAKE_STRV(__VA_ARGS__), .js_keys_len = NM_NARG(__VA_ARGS__) + +#define _VAL_BOOL(_default) .default_val.v_bool = (_default) + +#define _VAL_INT32(_default) .default_val.v_int32 = (_default) + +#define _VAL_INT32_RANGE(_default, _min, _max) \ + _VAL_INT32(_default), .has_range = TRUE, \ + .range.r_int32 = { \ + .min = _min, \ + .max = _max, \ + } + +#define _VAL_STRING() .default_val.v_string = NULL + +#define _VAL_STRING_RANGE(_valid_names) \ + _VAL_STRING(), .has_range = TRUE, \ + .range.r_string = { \ + .valid_names = (_valid_names), \ + } + +#define _VAL_UNSPEC() .default_val.v_string = (NULL) + +#define _INIT(_is_port, _team_attr, field, _value_type, _property_name, ...) \ + [TEAM_ATTR_IDX(_is_port, _team_attr)] = { \ + .for_master = (_team_attr) < _NM_TEAM_ATTRIBUTE_START || !(_is_port), \ + .for_port = (_team_attr) < _NM_TEAM_ATTRIBUTE_START || (_is_port), \ + .team_attr = (_team_attr), \ + .field_offset = G_STRUCT_OFFSET(NMTeamSetting, _data_priv.field), \ + .value_type = (_value_type), \ + .property_name = ""_property_name \ + "", \ + __VA_ARGS__} + + _INIT(0, NM_TEAM_ATTRIBUTE_CONFIG, _js_str, NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_CONFIG, ), + + _INIT(0, + NM_TEAM_ATTRIBUTE_LINK_WATCHERS, + link_watchers, + NM_VALUE_TYPE_UNSPEC, + NM_SETTING_TEAM_LINK_WATCHERS, + _JS_KEYS("link_watch"), + _VAL_UNSPEC(), ), + + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT, + master.notify_peers_count, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, + _JS_KEYS("notify_peers", "count"), + _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL, + master.notify_peers_interval, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL, + _JS_KEYS("notify_peers", "interval"), + _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT, + master.mcast_rejoin_count, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_MCAST_REJOIN_COUNT, + _JS_KEYS("mcast_rejoin", "count"), + _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL, + master.mcast_rejoin_interval, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL, + _JS_KEYS("mcast_rejoin", "interval"), + _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER, + master.runner, + NM_VALUE_TYPE_STRING, + NM_SETTING_TEAM_RUNNER, + _JS_KEYS("runner", "name"), + _VAL_STRING_RANGE(_valid_names_runner), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY, + master.runner_hwaddr_policy, + NM_VALUE_TYPE_STRING, + NM_SETTING_TEAM_RUNNER_HWADDR_POLICY, + _JS_KEYS("runner", "hwaddr_policy"), + _VAL_STRING_RANGE(_valid_names_runner_hwaddr_policy), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, + master.runner_tx_hash, + NM_VALUE_TYPE_UNSPEC, + NM_SETTING_TEAM_RUNNER_TX_HASH, + _JS_KEYS("runner", "tx_hash"), + _VAL_UNSPEC(), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER, + master.runner_tx_balancer, + NM_VALUE_TYPE_STRING, + NM_SETTING_TEAM_RUNNER_TX_BALANCER, + _JS_KEYS("runner", "tx_balancer", "name"), + _VAL_STRING_RANGE(_valid_names_runner_tx_balancer), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL, + master.runner_tx_balancer_interval, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, + _JS_KEYS("runner", "tx_balancer", "balancing_interval"), + _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE, + master.runner_active, + NM_VALUE_TYPE_BOOL, + NM_SETTING_TEAM_RUNNER_ACTIVE, + _JS_KEYS("runner", "active"), + _VAL_BOOL(TRUE), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE, + master.runner_fast_rate, + NM_VALUE_TYPE_BOOL, + NM_SETTING_TEAM_RUNNER_FAST_RATE, + _JS_KEYS("runner", "fast_rate"), + _VAL_BOOL(FALSE), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO, + master.runner_sys_prio, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_RUNNER_SYS_PRIO, + _JS_KEYS("runner", "sys_prio"), + _VAL_INT32_RANGE(-1, 0, USHRT_MAX + 1), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS, + master.runner_min_ports, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_RUNNER_MIN_PORTS, + _JS_KEYS("runner", "min_ports"), + _VAL_INT32_RANGE(-1, 1, UCHAR_MAX + 1), ), + _INIT(0, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY, + master.runner_agg_select_policy, + NM_VALUE_TYPE_STRING, + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY, + _JS_KEYS("runner", "agg_select_policy"), + _VAL_STRING_RANGE(_valid_names_runner_agg_select_policy), ), + + _INIT(1, + NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID, + port.queue_id, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_PORT_QUEUE_ID, + _JS_KEYS("queue_id"), + _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ), + _INIT(1, + NM_TEAM_ATTRIBUTE_PORT_PRIO, + port.prio, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_PORT_PRIO, + _JS_KEYS("prio"), + _VAL_INT32(0), ), + _INIT(1, + NM_TEAM_ATTRIBUTE_PORT_STICKY, + port.sticky, + NM_VALUE_TYPE_BOOL, + NM_SETTING_TEAM_PORT_STICKY, + _JS_KEYS("sticky"), + _VAL_BOOL(FALSE), ), + _INIT(1, + NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO, + port.lacp_prio, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_PORT_LACP_PRIO, + _JS_KEYS("lacp_prio"), + _VAL_INT32_RANGE(-1, 0, USHRT_MAX + 1), ), + _INIT(1, + NM_TEAM_ATTRIBUTE_PORT_LACP_KEY, + port.lacp_key, + NM_VALUE_TYPE_INT32, + NM_SETTING_TEAM_PORT_LACP_KEY, + _JS_KEYS("lacp_key"), + _VAL_INT32_RANGE(-1, 0, USHRT_MAX + 1), ), + +#undef _INIT +}; + +/*****************************************************************************/ + +typedef enum { + LINK_WATCHER_ATTRIBUTE_NAME, + LINK_WATCHER_ATTRIBUTE_DELAY_UP, + LINK_WATCHER_ATTRIBUTE_DELAY_DOWN, + LINK_WATCHER_ATTRIBUTE_INTERVAL, + LINK_WATCHER_ATTRIBUTE_INIT_WAIT, + LINK_WATCHER_ATTRIBUTE_MISSED_MAX, + LINK_WATCHER_ATTRIBUTE_SOURCE_HOST, + LINK_WATCHER_ATTRIBUTE_TARGET_HOST, + LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE, + LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE, + LINK_WATCHER_ATTRIBUTE_VLANID, + LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS, +} LinkWatcherAttribute; + +#define _EXPECTED_LINK_WATCHER_ATTRIBUTES_ETHTOOL \ + LINK_WATCHER_ATTRIBUTE_NAME, LINK_WATCHER_ATTRIBUTE_DELAY_UP, LINK_WATCHER_ATTRIBUTE_DELAY_DOWN +#define _EXPECTED_LINK_WATCHER_ATTRIBUTES_NSNA_PING \ + LINK_WATCHER_ATTRIBUTE_NAME, LINK_WATCHER_ATTRIBUTE_INTERVAL, \ + LINK_WATCHER_ATTRIBUTE_INIT_WAIT, LINK_WATCHER_ATTRIBUTE_MISSED_MAX, \ + LINK_WATCHER_ATTRIBUTE_TARGET_HOST +#define _EXPECTED_LINK_WATCHER_ATTRIBUTES_ARP_PING \ + LINK_WATCHER_ATTRIBUTE_NAME, LINK_WATCHER_ATTRIBUTE_INTERVAL, \ + LINK_WATCHER_ATTRIBUTE_INIT_WAIT, LINK_WATCHER_ATTRIBUTE_MISSED_MAX, \ + LINK_WATCHER_ATTRIBUTE_SOURCE_HOST, LINK_WATCHER_ATTRIBUTE_TARGET_HOST, \ + LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE, LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE, \ + LINK_WATCHER_ATTRIBUTE_VLANID, LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS + +typedef struct { + const char * js_key; + const char * dbus_name; + NMValueTypUnion default_val; + LinkWatcherAttribute link_watcher_attr; + NMValueType value_type; +} LinkWatcherAttrData; + +static const LinkWatcherAttrData link_watcher_attr_datas[] = { +#define _INIT(_link_watcher_attr, _js_key, _dbus_name, _value_type, ...) \ + [_link_watcher_attr] = {.link_watcher_attr = (_link_watcher_attr), \ + .value_type = (_value_type), \ + .js_key = (""_js_key \ + ""), \ + .dbus_name = (""_dbus_name \ + ""), \ + __VA_ARGS__} + _INIT(LINK_WATCHER_ATTRIBUTE_NAME, "name", "name", NM_VALUE_TYPE_STRING, ), + _INIT(LINK_WATCHER_ATTRIBUTE_DELAY_UP, "delay_up", "delay-up", NM_VALUE_TYPE_INT, ), + _INIT(LINK_WATCHER_ATTRIBUTE_DELAY_DOWN, "delay_down", "delay-down", NM_VALUE_TYPE_INT, ), + _INIT(LINK_WATCHER_ATTRIBUTE_INTERVAL, "interval", "interval", NM_VALUE_TYPE_INT, ), + _INIT(LINK_WATCHER_ATTRIBUTE_INIT_WAIT, "init_wait", "init-wait", NM_VALUE_TYPE_INT, ), + _INIT(LINK_WATCHER_ATTRIBUTE_MISSED_MAX, + "missed_max", + "missed-max", + NM_VALUE_TYPE_INT, + .default_val.v_int = 3, ), + _INIT(LINK_WATCHER_ATTRIBUTE_SOURCE_HOST, "source_host", "source-host", NM_VALUE_TYPE_STRING, ), + _INIT(LINK_WATCHER_ATTRIBUTE_TARGET_HOST, "target_host", "target-host", NM_VALUE_TYPE_STRING, ), + _INIT(LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE, + "validate_active", + "validate-active", + NM_VALUE_TYPE_BOOL, ), + _INIT(LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE, + "validate_inactive", + "validate-inactive", + NM_VALUE_TYPE_BOOL, ), + _INIT(LINK_WATCHER_ATTRIBUTE_VLANID, + "vlanid", + "vlanid", + NM_VALUE_TYPE_INT, + .default_val.v_int = -1, ), + _INIT(LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS, "send_always", "send-always", NM_VALUE_TYPE_BOOL, ), +#undef _INIT +}; + +/*****************************************************************************/ + +static const TeamAttrData *_team_attr_data_get(gboolean is_port, NMTeamAttribute team_attr); +static gpointer _team_setting_get_field(const NMTeamSetting *self, const TeamAttrData *attr_data); +static void _link_watcher_to_json(const NMTeamLinkWatcher *link_watcher, GString *gstr); + +/*****************************************************************************/ + +static void +_team_attr_data_ASSERT(const TeamAttrData *attr_data) +{ +#if NM_MORE_ASSERTS > 5 + nm_assert(attr_data); + if (attr_data->for_port) + nm_assert(attr_data == _team_attr_data_get(TRUE, attr_data->team_attr)); + if (attr_data->for_master) + nm_assert(attr_data == _team_attr_data_get(FALSE, attr_data->team_attr)); + nm_assert((attr_data - team_attr_datas) + == TEAM_ATTR_IDX(attr_data->for_port, attr_data->team_attr)); + nm_assert(attr_data->value_type > 0); + nm_assert(attr_data->field_offset < sizeof(NMTeamSetting)); + nm_assert(attr_data->js_keys_len == NM_PTRARRAY_LEN(attr_data->js_keys)); + nm_assert(attr_data->property_name); + { + static int checked = 0; + + if (checked == 0) { + checked = 1; + + for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; + attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)]; + attr_data++) + _team_attr_data_ASSERT(attr_data); + } + } +#endif +} + +static gboolean +_team_attr_data_is_relevant(const TeamAttrData *attr_data, gboolean is_port) +{ + return is_port ? attr_data->for_port : attr_data->for_master; +} + +static const TeamAttrData * +_team_attr_data_get(gboolean is_port, NMTeamAttribute team_attr) +{ + const int idx = TEAM_ATTR_IDX(is_port, team_attr); + + nm_assert(idx >= 0 && idx < G_N_ELEMENTS(team_attr_datas)); + nm_assert(team_attr_datas[idx].team_attr == team_attr); + nm_assert(_team_attr_data_is_relevant(&team_attr_datas[idx], is_port)); + + return &team_attr_datas[idx]; +} + +static const TeamAttrData * +_team_attr_data_find_for_property_name(gboolean is_port, const char *property_name) +{ + const TeamAttrData *attr_data; + + for (attr_data = team_attr_datas; attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)]; + attr_data++) { + if (_team_attr_data_is_relevant(attr_data, is_port) + && nm_streq(property_name, attr_data->property_name)) + return attr_data; + } + return NULL; +} + +static int +_team_attr_data_cmp(const TeamAttrData *attr_data, + gboolean is_port, + gconstpointer val_a, + gconstpointer val_b) +{ + const GPtrArray *v_ptrarray_a; + const GPtrArray *v_ptrarray_b; + guint len; + + _team_attr_data_ASSERT(attr_data); + nm_assert(val_a); + nm_assert(val_b); + + if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) + NM_CMP_RETURN(nm_value_type_cmp(attr_data->value_type, val_a, val_b)); + else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) { + v_ptrarray_a = *((const GPtrArray *const *) val_a); + v_ptrarray_b = *((const GPtrArray *const *) val_b); + len = v_ptrarray_a ? v_ptrarray_a->len : 0u; + NM_CMP_DIRECT(len, (v_ptrarray_b ? v_ptrarray_b->len : 0u)); + if (len > 0) { + NM_CMP_RETURN( + nm_team_link_watchers_cmp((const NMTeamLinkWatcher *const *) v_ptrarray_a->pdata, + (const NMTeamLinkWatcher *const *) v_ptrarray_b->pdata, + len, + FALSE)); + } + } else if (!is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) { + v_ptrarray_a = *((const GPtrArray *const *) val_a); + v_ptrarray_b = *((const GPtrArray *const *) val_b); + NM_CMP_RETURN( + nm_utils_strv_cmp_n(v_ptrarray_a ? (const char *const *) v_ptrarray_a->pdata : NULL, + v_ptrarray_a ? v_ptrarray_a->len : 0u, + v_ptrarray_b ? (const char *const *) v_ptrarray_b->pdata : NULL, + v_ptrarray_b ? v_ptrarray_b->len : 0u)); + } else + nm_assert_not_reached(); + return 0; +} + +static gboolean +_team_attr_data_equal(const TeamAttrData *attr_data, + gboolean is_port, + gconstpointer val_a, + gconstpointer val_b) +{ + return _team_attr_data_cmp(attr_data, is_port, val_a, val_b) == 0; +} + +static void +_team_attr_data_copy(const TeamAttrData *attr_data, + gboolean is_port, + gpointer dst, + gconstpointer src) +{ + GPtrArray * v_ptrarray_dst; + const GPtrArray *v_ptrarray_src; + GPtrArray * dst_array; + guint i, len; + + if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) + nm_value_type_copy(attr_data->value_type, dst, src); + else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) { + v_ptrarray_src = *((const GPtrArray *const *) src); + v_ptrarray_dst = *((GPtrArray **) dst); + len = (v_ptrarray_src ? v_ptrarray_src->len : 0u); + + if (len == 0) { + if (v_ptrarray_dst) + g_ptr_array_set_size(v_ptrarray_dst, 0); + } else { + dst_array = g_ptr_array_new_full(len, (GDestroyNotify) nm_team_link_watcher_unref); + for (i = 0; i < len; i++) { + if (v_ptrarray_src->pdata[i]) { + nm_team_link_watcher_ref(v_ptrarray_src->pdata[i]); + g_ptr_array_add(dst_array, v_ptrarray_src->pdata[i]); + } + } + if (v_ptrarray_dst) + g_ptr_array_unref(v_ptrarray_dst); + *((GPtrArray **) dst) = dst_array; + } + } else if (!is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) { + v_ptrarray_src = *((const GPtrArray *const *) src); + v_ptrarray_dst = *((GPtrArray **) dst); + len = (v_ptrarray_src ? v_ptrarray_src->len : 0u); + + if (v_ptrarray_src && v_ptrarray_src->len > 0) { + dst_array = g_ptr_array_new_full(v_ptrarray_src->len, g_free); + for (i = 0; i < v_ptrarray_src->len; i++) + g_ptr_array_add(dst_array, g_strdup(v_ptrarray_src->pdata[i])); + } else + dst_array = NULL; + if (v_ptrarray_dst) + g_ptr_array_unref(v_ptrarray_dst); + *((GPtrArray **) dst) = dst_array; + } else + nm_assert_not_reached(); +} + +static void +_team_attr_data_to_json(const TeamAttrData *attr_data, + gboolean is_port, + GString * gstr, + gconstpointer p_field) +{ + guint i; + + _team_attr_data_ASSERT(attr_data); + nm_assert(p_field); + + nm_json_gstr_append_obj_name(gstr, attr_data->js_keys[attr_data->js_keys_len - 1], '\0'); + + if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) { + nm_value_type_to_json(attr_data->value_type, gstr, p_field); + return; + } + + if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) { + const GPtrArray *v_ptrarray = *((const GPtrArray *const *) p_field); + + if (!v_ptrarray) + g_string_append(gstr, "null"); + else if (v_ptrarray->len == 0) + g_string_append(gstr, "[ ]"); + else if (v_ptrarray->len == 1) + _link_watcher_to_json(v_ptrarray->pdata[0], gstr); + else { + g_string_append(gstr, "[ "); + for (i = 0; i < v_ptrarray->len; i++) { + if (i > 0) + nm_json_gstr_append_delimiter(gstr); + _link_watcher_to_json(v_ptrarray->pdata[i], gstr); + } + g_string_append(gstr, " ]"); + } + return; + } + + if (!is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) { + const GPtrArray *v_ptrarray = *((const GPtrArray *const *) p_field); + + if (!v_ptrarray) + g_string_append(gstr, "null"); + else { + g_string_append(gstr, "[ "); + for (i = 0; i < v_ptrarray->len; i++) { + if (i > 0) + nm_json_gstr_append_delimiter(gstr); + nm_json_gstr_append_string(gstr, v_ptrarray->pdata[i]); + } + g_string_append(gstr, i > 0 ? " ]" : "]"); + } + return; + } + + nm_assert_not_reached(); +} + +/*****************************************************************************/ + +static void +_team_setting_ASSERT(const NMTeamSetting *self) +{ + nm_assert(self); + nm_assert(!self->d._js_str_need_synthetize || !self->d._js_str); +#if NM_MORE_ASSERTS > 2 + if (!self->d.strict_validated) { + nm_assert(!self->d._js_str_need_synthetize); + nm_assert(self->d._js_str); + } + nm_assert(self->d.link_watchers); + nm_assert(self->d.is_port || !self->d.master.runner_tx_hash + || self->d.master.runner_tx_hash->len > 0); +#endif +} + +static gboolean +_team_setting_has_field(const NMTeamSetting *self, const TeamAttrData *attr_data) +{ + _team_setting_ASSERT(self); + return NM_FLAGS_ALL(self->d.has_fields_mask, nm_team_attribute_to_flags(attr_data->team_attr)); +} + +static gboolean +_team_setting_has_fields_any_v(const NMTeamSetting * self, + const NMTeamAttribute *team_attrs, + gsize n_team_attrs) +{ + gsize i; + + for (i = 0; i < n_team_attrs; i++) { + const TeamAttrData *attr_data = _team_attr_data_get(self->d.is_port, team_attrs[i]); + + if (_team_setting_has_field(self, attr_data)) + return TRUE; + } + return FALSE; +} + +#define _team_setting_has_fields_any(self, ...) \ + _team_setting_has_fields_any_v((self), \ + ((const NMTeamAttribute[]){__VA_ARGS__}), \ + NM_NARG(__VA_ARGS__)) + +static void +_team_setting_has_field_set(NMTeamSetting * self, + const TeamAttrData *attr_data, + SetFieldModeEnum set_field_mode) +{ + guint32 mask = nm_team_attribute_to_flags(attr_data->team_attr); + + _team_setting_ASSERT(self); + + switch (set_field_mode) { + case SET_FIELD_MODE_UNSET: + goto do_unset; + case SET_FIELD_MODE_SET: + goto do_set; + case SET_FIELD_MODE_SET_UNLESS_DEFAULT: + if (_team_attr_data_equal(attr_data, + self->d.is_port, + _team_setting_get_field(self, attr_data), + &attr_data->default_val)) + goto do_unset; + goto do_set; + } + nm_assert_not_reached(); + +do_unset: + self->_data_priv.has_fields_mask &= ~mask; + return; +do_set: + self->_data_priv.has_fields_mask |= mask; +} + +static gpointer +_team_setting_get_field(const NMTeamSetting *self, const TeamAttrData *attr_data) +{ + _team_setting_ASSERT(self); + _team_attr_data_ASSERT(attr_data); + nm_assert(_team_attr_data_is_relevant(attr_data, self->d.is_port)); + +#if NM_MORE_ASSERTS > 5 + if (attr_data->for_master && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO) + nm_assert((gpointer)(((char *) self) + attr_data->field_offset) + == &self->d.master.runner_sys_prio); +#endif + + return (((char *) self) + attr_data->field_offset); +} + +static guint32 +_team_setting_attribute_changed(NMTeamSetting * self, + const TeamAttrData *attr_data, + gboolean changed, + SetFieldModeEnum set_field_mode, + ResetJsonEnum reset_json) +{ + guint32 changed_flags; + + _team_setting_has_field_set(self, attr_data, set_field_mode); + + if (!reset_json) { + return changed ? nm_team_attribute_to_flags(attr_data->team_attr) : 0u; + } + + if (!changed) { + /* a regular attribute was set, but the value did not change. + * + * If we previously were in non-strict mode, then + * + * - switch to strict-mode. Clearly the user set a regular attribute + * and hence now we want to validate the setting. + * + * - clear the JSON string. We need to regenerate it. + */ + if (self->_data_priv.strict_validated) + return 0; + changed_flags = nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG); + } else { + changed_flags = nm_team_attribute_to_flags(attr_data->team_attr) + | nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG); + } + + nm_clear_g_free((char **) &self->_data_priv._js_str); + self->_data_priv.strict_validated = TRUE; + self->_data_priv._js_str_need_synthetize = TRUE; + + return changed_flags; +} + +static guint32 +_team_setting_attribute_changed_attr(NMTeamSetting * self, + NMTeamAttribute team_attr, + gboolean changed, + SetFieldModeEnum set_field_mode, + ResetJsonEnum reset_json) +{ + return _team_setting_attribute_changed(self, + _team_attr_data_get(self->d.is_port, team_attr), + changed, + set_field_mode, + reset_json); +} + +static gboolean +_team_setting_field_to_json(const NMTeamSetting *self, + GString * gstr, + gboolean prepend_delimiter, + const TeamAttrData * attr_data) +{ + if (!_team_setting_has_field(self, attr_data)) + return FALSE; + + if (prepend_delimiter) + nm_json_gstr_append_delimiter(gstr); + _team_attr_data_to_json(attr_data, + self->d.is_port, + gstr, + _team_setting_get_field(self, attr_data)); + return TRUE; +} + +static gboolean +_team_setting_fields_to_json_maybe(const NMTeamSetting * self, + GString * gstr, + gboolean prepend_delimiter, + const NMTeamAttribute *team_attrs_lst, + gsize team_attrs_lst_len) +{ + gsize i; + gboolean any_added = FALSE; + + for (i = 0; i < team_attrs_lst_len; i++) { + if (_team_setting_field_to_json(self, + gstr, + prepend_delimiter, + _team_attr_data_get(self->d.is_port, team_attrs_lst[i]))) { + any_added = TRUE; + prepend_delimiter = TRUE; + } + } + return any_added; +} + +static guint32 +_team_setting_set(NMTeamSetting * self, + gboolean modify, + const bool * has_lst, + const NMValueTypUnion *val_lst) +{ + guint32 changed_flags = 0; + const TeamAttrData *attr_data; + + nm_assert((!has_lst) == (!val_lst)); + + for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; + attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)]; + attr_data++) { + const NMValueTypUnion *p_val; + gconstpointer p_field; + gboolean has_field; + + if (!_team_attr_data_is_relevant(attr_data, self->d.is_port)) + continue; + + has_field = (has_lst && has_lst[attr_data->team_attr]); + + p_val = has_field ? &val_lst[attr_data->team_attr] : &attr_data->default_val; + + p_field = _team_setting_get_field(self, attr_data); + + if (!_team_attr_data_equal(attr_data, self->d.is_port, p_val, p_field)) { + if (modify) { + _team_attr_data_copy(attr_data, self->d.is_port, (gpointer) p_field, p_val); + } + changed_flags |= nm_team_attribute_to_flags(attr_data->team_attr); + } + + if (modify) { + _team_setting_has_field_set(self, + attr_data, + has_field ? SET_FIELD_MODE_SET : SET_FIELD_MODE_UNSET); + } + } + + return changed_flags; +} + +static guint32 +_team_setting_check_default(const NMTeamSetting *self) +{ + return _team_setting_set((NMTeamSetting *) self, FALSE, NULL, NULL); +} + +static guint32 +_team_setting_set_default(NMTeamSetting *self) +{ + return _team_setting_set(self, TRUE, NULL, NULL); +} + +/*****************************************************************************/ + +gconstpointer +_nm_team_setting_value_get(const NMTeamSetting *self, + NMTeamAttribute team_attr, + NMValueType value_type) +{ + const TeamAttrData *attr_data = _team_attr_data_get(self->d.is_port, team_attr); + + nm_assert(value_type == attr_data->value_type); + + nm_assert(_team_setting_has_field(self, attr_data) + || _team_attr_data_equal(attr_data, + self->d.is_port, + _team_setting_get_field(self, attr_data), + &attr_data->default_val)); + return _team_setting_get_field(self, attr_data); +} + +static guint32 +_team_setting_value_set(NMTeamSetting * self, + const TeamAttrData *attr_data, + gconstpointer val, + SetFieldModeEnum set_field_mode, + ResetJsonEnum reset_json) +{ + gpointer p_field; + gboolean changed; + + nm_assert(self); + _team_attr_data_ASSERT(attr_data); + nm_assert(val); + + p_field = _team_setting_get_field(self, attr_data); + + changed = !_team_attr_data_equal(attr_data, self->d.is_port, p_field, val); + if (changed) + nm_value_type_copy(attr_data->value_type, p_field, val); + return _team_setting_attribute_changed(self, attr_data, changed, set_field_mode, reset_json); +} + +guint32 +nm_team_setting_value_reset(NMTeamSetting * self, + NMTeamAttribute team_attr, + gboolean to_default /* or else unset */) +{ + const TeamAttrData *attr_data; + + nm_assert(self); + + attr_data = _team_attr_data_get(self->d.is_port, team_attr); + + return _team_setting_value_set(self, + attr_data, + &attr_data->default_val, + to_default ? SET_FIELD_MODE_SET : SET_FIELD_MODE_UNSET, + RESET_JSON_YES); +} + +guint32 +_nm_team_setting_value_set(NMTeamSetting * self, + NMTeamAttribute team_attr, + NMValueType value_type, + gconstpointer val) +{ + const TeamAttrData *attr_data; + + nm_assert(self); + + attr_data = _team_attr_data_get(self->d.is_port, team_attr); + + nm_assert(value_type == attr_data->value_type); + + return _team_setting_value_set(self, + attr_data, + val, + SET_FIELD_MODE_SET_UNLESS_DEFAULT, + RESET_JSON_YES); +} + +guint32 +nm_team_setting_value_link_watchers_add(NMTeamSetting *self, const NMTeamLinkWatcher *link_watcher) +{ + guint i; + gboolean changed; + + for (i = 0; i < self->d.link_watchers->len; i++) { + if (nm_team_link_watcher_equal(self->d.link_watchers->pdata[i], link_watcher)) { + changed = FALSE; + goto out; + } + } + changed = TRUE; + g_ptr_array_add((GPtrArray *) self->d.link_watchers, + _nm_team_link_watcher_ref((NMTeamLinkWatcher *) link_watcher)); +out: + return _team_setting_attribute_changed_attr(self, + NM_TEAM_ATTRIBUTE_LINK_WATCHERS, + changed, + SET_FIELD_MODE_SET_UNLESS_DEFAULT, + RESET_JSON_YES); +} + +guint32 +nm_team_setting_value_link_watchers_remove_by_value(NMTeamSetting * self, + const NMTeamLinkWatcher *link_watcher) +{ + guint i; + + for (i = 0; i < self->d.link_watchers->len; i++) { + if (nm_team_link_watcher_equal(self->d.link_watchers->pdata[i], link_watcher)) + return nm_team_setting_value_link_watchers_remove(self, i); + } + return _team_setting_attribute_changed_attr(self, + NM_TEAM_ATTRIBUTE_LINK_WATCHERS, + FALSE, + SET_FIELD_MODE_SET_UNLESS_DEFAULT, + RESET_JSON_YES); +} + +guint32 +nm_team_setting_value_link_watchers_remove(NMTeamSetting *self, guint idx) +{ + g_ptr_array_remove_index((GPtrArray *) self->d.link_watchers, idx); + return _team_setting_attribute_changed_attr(self, + NM_TEAM_ATTRIBUTE_LINK_WATCHERS, + TRUE, + SET_FIELD_MODE_SET_UNLESS_DEFAULT, + RESET_JSON_YES); +} + +static guint32 +_team_setting_value_link_watchers_set_list(NMTeamSetting * self, + const NMTeamLinkWatcher *const *arr, + guint len, + SetFieldModeEnum set_field_mode, + ResetJsonEnum reset_json) +{ + gboolean changed; + + if (self->d.link_watchers->len == len + && nm_team_link_watchers_cmp( + (const NMTeamLinkWatcher *const *) self->d.link_watchers->pdata, + arr, + len, + FALSE) + == 0) { + changed = FALSE; + goto out; + } + + changed = TRUE; + if (len == 0) + g_ptr_array_set_size((GPtrArray *) self->d.link_watchers, 0); + else { + _nm_unused gs_unref_ptrarray GPtrArray *old_val_destroy = NULL; + guint i; + + old_val_destroy = (GPtrArray *) g_steal_pointer(&self->_data_priv.link_watchers); + + self->_data_priv.link_watchers = + g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref); + + for (i = 0; i < len; i++) { + if (arr[i]) { + g_ptr_array_add((GPtrArray *) self->d.link_watchers, + _nm_team_link_watcher_ref((NMTeamLinkWatcher *) arr[i])); + } + } + } + +out: + return _team_setting_attribute_changed_attr(self, + NM_TEAM_ATTRIBUTE_LINK_WATCHERS, + changed, + set_field_mode, + reset_json); +} + +guint32 +nm_team_setting_value_link_watchers_set_list(NMTeamSetting * self, + const NMTeamLinkWatcher *const *arr, + guint len) +{ + return _team_setting_value_link_watchers_set_list(self, + arr, + len, + SET_FIELD_MODE_SET_UNLESS_DEFAULT, + RESET_JSON_YES); +} + +/*****************************************************************************/ + +guint32 +nm_team_setting_value_master_runner_tx_hash_add(NMTeamSetting *self, const char *txhash) +{ + gboolean changed; + guint i; + + if (!self->d.master.runner_tx_hash) + self->_data_priv.master.runner_tx_hash = g_ptr_array_new_with_free_func(g_free); + else { + for (i = 0; i < self->d.master.runner_tx_hash->len; i++) { + if (nm_streq(txhash, self->d.master.runner_tx_hash->pdata[i])) { + changed = FALSE; + goto out; + } + } + } + changed = TRUE; + g_ptr_array_add((GPtrArray *) self->d.master.runner_tx_hash, g_strdup(txhash)); +out: + return _team_setting_attribute_changed_attr(self, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, + changed, + SET_FIELD_MODE_SET_UNLESS_DEFAULT, + RESET_JSON_YES); +} + +guint32 +nm_team_setting_value_master_runner_tx_hash_remove(NMTeamSetting *self, guint idx) +{ + g_ptr_array_remove_index((GPtrArray *) self->d.master.runner_tx_hash, idx); + return _team_setting_attribute_changed_attr(self, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, + TRUE, + SET_FIELD_MODE_SET_UNLESS_DEFAULT, + RESET_JSON_YES); +} + +static guint32 +_team_setting_value_master_runner_tx_hash_set_list(NMTeamSetting * self, + const char *const *arr, + guint len, + SetFieldModeEnum set_field_mode, + ResetJsonEnum reset_json) +{ + _nm_unused gs_unref_ptrarray GPtrArray *old_val_destroy = NULL; + gboolean changed; + guint i; + + if (nm_utils_strv_cmp_n(self->d.master.runner_tx_hash + ? (const char *const *) self->d.master.runner_tx_hash->pdata + : NULL, + self->d.master.runner_tx_hash ? self->d.master.runner_tx_hash->len : 0u, + arr, + len) + == 0) { + changed = FALSE; + goto out; + } + + changed = TRUE; + + old_val_destroy = (GPtrArray *) g_steal_pointer(&self->_data_priv.master.runner_tx_hash); + + for (i = 0; i < len; i++) { + if (!arr[i]) + continue; + if (!self->d.master.runner_tx_hash) + self->_data_priv.master.runner_tx_hash = g_ptr_array_new_with_free_func(g_free); + g_ptr_array_add((GPtrArray *) self->d.master.runner_tx_hash, g_strdup(arr[i])); + } + +out: + return _team_setting_attribute_changed_attr(self, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, + changed, + set_field_mode, + reset_json); +} + +guint32 +nm_team_setting_value_master_runner_tx_hash_set_list(NMTeamSetting * self, + const char *const *arr, + guint len) +{ + return _team_setting_value_master_runner_tx_hash_set_list(self, + arr, + len, + SET_FIELD_MODE_SET_UNLESS_DEFAULT, + RESET_JSON_YES); +} + +/*****************************************************************************/ + +#define _LINK_WATCHER_ATTR_GET(args, link_watcher_attribute, _value_type) \ + ({ \ + const NMValueTypUnioMaybe *const _args = (args); \ + \ + nm_assert(link_watcher_attr_datas[(link_watcher_attribute)].value_type == (_value_type)); \ + \ + _args[(link_watcher_attribute)].has \ + ? &_args[(link_watcher_attribute)].val \ + : &link_watcher_attr_datas[(link_watcher_attribute)].default_val; \ + }) +#define _LINK_WATCHER_ATTR_GET_BOOL(args, link_watcher_attribute) \ + (_LINK_WATCHER_ATTR_GET(args, link_watcher_attribute, NM_VALUE_TYPE_BOOL)->v_bool) +#define _LINK_WATCHER_ATTR_GET_INT(args, link_watcher_attribute) \ + (_LINK_WATCHER_ATTR_GET(args, link_watcher_attribute, NM_VALUE_TYPE_INT)->v_int) +#define _LINK_WATCHER_ATTR_GET_STRING(args, link_watcher_attribute) \ + (_LINK_WATCHER_ATTR_GET(args, link_watcher_attribute, NM_VALUE_TYPE_STRING)->v_string) + +#define _LINK_WATCHER_ATTR_SET(args, link_watcher_attribute, _value_type, c_type, val) \ + ({ \ + nm_assert(link_watcher_attr_datas[(link_watcher_attribute)].value_type == (_value_type)); \ + \ + NM_VALUE_TYP_UNIO_MAYBE_SET(&(args)[(link_watcher_attribute)], c_type, (val)); \ + }) +#define _LINK_WATCHER_ATTR_SET_BOOL(args, link_watcher_attribute, val) \ + _LINK_WATCHER_ATTR_SET((args), (link_watcher_attribute), NM_VALUE_TYPE_BOOL, v_bool, (val)) +#define _LINK_WATCHER_ATTR_SET_INT(args, link_watcher_attribute, val) \ + _LINK_WATCHER_ATTR_SET((args), (link_watcher_attribute), NM_VALUE_TYPE_INT, v_int, (val)) +#define _LINK_WATCHER_ATTR_SET_STRING(args, link_watcher_attribute, val) \ + _LINK_WATCHER_ATTR_SET((args), (link_watcher_attribute), NM_VALUE_TYPE_STRING, v_string, (val)) + +static void +_link_watcher_unpack(const NMTeamLinkWatcher *link_watcher, + NMValueTypUnioMaybe args[static G_N_ELEMENTS(link_watcher_attr_datas)]) +{ + const char * v_name = nm_team_link_watcher_get_name(link_watcher); + NMTeamLinkWatcherArpPingFlags v_arp_ping_flags; + + memset(args, 0, sizeof(args[0]) * G_N_ELEMENTS(link_watcher_attr_datas)); + + _LINK_WATCHER_ATTR_SET_STRING(args, LINK_WATCHER_ATTRIBUTE_NAME, v_name); + + if (nm_streq(v_name, NM_TEAM_LINK_WATCHER_ETHTOOL)) { + _LINK_WATCHER_ATTR_SET_INT(args, + LINK_WATCHER_ATTRIBUTE_DELAY_UP, + nm_team_link_watcher_get_delay_up(link_watcher)); + _LINK_WATCHER_ATTR_SET_INT(args, + LINK_WATCHER_ATTRIBUTE_DELAY_DOWN, + nm_team_link_watcher_get_delay_down(link_watcher)); + } else if (NM_IN_STRSET(v_name, + NM_TEAM_LINK_WATCHER_NSNA_PING, + NM_TEAM_LINK_WATCHER_ARP_PING)) { + _LINK_WATCHER_ATTR_SET_INT(args, + LINK_WATCHER_ATTRIBUTE_INIT_WAIT, + nm_team_link_watcher_get_init_wait(link_watcher)); + _LINK_WATCHER_ATTR_SET_INT(args, + LINK_WATCHER_ATTRIBUTE_INTERVAL, + nm_team_link_watcher_get_interval(link_watcher)); + _LINK_WATCHER_ATTR_SET_INT(args, + LINK_WATCHER_ATTRIBUTE_MISSED_MAX, + nm_team_link_watcher_get_missed_max(link_watcher)); + _LINK_WATCHER_ATTR_SET_STRING(args, + LINK_WATCHER_ATTRIBUTE_TARGET_HOST, + nm_team_link_watcher_get_target_host(link_watcher)); + if (nm_streq(v_name, NM_TEAM_LINK_WATCHER_ARP_PING)) { + v_arp_ping_flags = nm_team_link_watcher_get_flags(link_watcher); + _LINK_WATCHER_ATTR_SET_INT(args, + LINK_WATCHER_ATTRIBUTE_VLANID, + nm_team_link_watcher_get_vlanid(link_watcher)); + _LINK_WATCHER_ATTR_SET_STRING(args, + LINK_WATCHER_ATTRIBUTE_SOURCE_HOST, + nm_team_link_watcher_get_source_host(link_watcher)); + _LINK_WATCHER_ATTR_SET_BOOL( + args, + LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE, + NM_FLAGS_HAS(v_arp_ping_flags, NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE)); + _LINK_WATCHER_ATTR_SET_BOOL( + args, + LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE, + NM_FLAGS_HAS(v_arp_ping_flags, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE)); + _LINK_WATCHER_ATTR_SET_BOOL( + args, + LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS, + NM_FLAGS_HAS(v_arp_ping_flags, NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS)); + } + } +} + +static void +_link_watcher_to_json(const NMTeamLinkWatcher *link_watcher, GString *gstr) +{ + NMValueTypUnioMaybe args[G_N_ELEMENTS(link_watcher_attr_datas)]; + int i; + gboolean is_first = TRUE; + + if (!link_watcher) { + g_string_append(gstr, "null"); + return; + } + + _link_watcher_unpack(link_watcher, args); + + g_string_append(gstr, "{ "); + + for (i = 0; i < (int) G_N_ELEMENTS(link_watcher_attr_datas); i++) { + const NMValueTypUnioMaybe *p_val = &args[i]; + const LinkWatcherAttrData *attr_data = &link_watcher_attr_datas[i]; + + if (!p_val->has) + continue; + if (nm_value_type_equal(attr_data->value_type, &attr_data->default_val, &p_val->val)) + continue; + + if (is_first) + is_first = FALSE; + else + nm_json_gstr_append_delimiter(gstr); + nm_json_gstr_append_obj_name(gstr, attr_data->js_key, '\0'); + nm_value_type_to_json(attr_data->value_type, gstr, &p_val->val); + } + + g_string_append(gstr, " }"); +} + +static NMTeamLinkWatcher * +_link_watcher_from_json(const NMJsonVt * vt, + const nm_json_t *root_js_obj, + gboolean * out_unrecognized_content) +{ + NMValueTypUnioMaybe args[G_N_ELEMENTS(link_watcher_attr_datas)] = {}; + const char * j_key; + nm_json_t * j_val; + const char * v_name; + NMTeamLinkWatcher * result = NULL; + + if (!nm_json_is_object(root_js_obj)) + goto fail; + + nm_json_object_foreach (vt, (nm_json_t *) root_js_obj, j_key, j_val) { + const LinkWatcherAttrData *attr_data = NULL; + NMValueTypUnioMaybe * parse_result; + + if (j_key) { + int i; + + for (i = 0; i < (int) G_N_ELEMENTS(link_watcher_attr_datas); i++) { + if (nm_streq(link_watcher_attr_datas[i].js_key, j_key)) { + attr_data = &link_watcher_attr_datas[i]; + break; + } + } + } + if (!attr_data) { + *out_unrecognized_content = TRUE; + continue; + } + + parse_result = &args[attr_data->link_watcher_attr]; + + if (parse_result->has) + *out_unrecognized_content = TRUE; + + if (!nm_value_type_from_json(vt, attr_data->value_type, j_val, &parse_result->val)) + *out_unrecognized_content = TRUE; + else + parse_result->has = TRUE; + } + +#define _PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES(_parse_results, ...) \ + ({ \ + int _i; \ + \ + for (_i = 0; _i < (int) G_N_ELEMENTS((_parse_results)); _i++) { \ + if ((_parse_results)[_i].has && !NM_IN_SET((LinkWatcherAttribute) _i, __VA_ARGS__)) \ + break; \ + } \ + \ + (_i == (int) G_N_ELEMENTS((_parse_results))); \ + }) + + v_name = _LINK_WATCHER_ATTR_GET_STRING(args, LINK_WATCHER_ATTRIBUTE_NAME); + + if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_ETHTOOL)) { + if (_PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES(args, + _EXPECTED_LINK_WATCHER_ATTRIBUTES_ETHTOOL)) + *out_unrecognized_content = TRUE; + result = nm_team_link_watcher_new_ethtool( + _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_DELAY_UP), + _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_DELAY_DOWN), + NULL); + } else if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_NSNA_PING)) { + if (_PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES(args, + _EXPECTED_LINK_WATCHER_ATTRIBUTES_NSNA_PING)) + *out_unrecognized_content = TRUE; + result = nm_team_link_watcher_new_nsna_ping( + _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_INIT_WAIT), + _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_INTERVAL), + _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_MISSED_MAX), + _LINK_WATCHER_ATTR_GET_STRING(args, LINK_WATCHER_ATTRIBUTE_TARGET_HOST), + NULL); + } else if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_ARP_PING)) { + NMTeamLinkWatcherArpPingFlags v_flags = NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE; + + if (_PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES(args, + _EXPECTED_LINK_WATCHER_ATTRIBUTES_ARP_PING)) + *out_unrecognized_content = TRUE; + + if (_LINK_WATCHER_ATTR_GET_BOOL(args, LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE)) + v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE; + if (_LINK_WATCHER_ATTR_GET_BOOL(args, LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE)) + v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE; + if (_LINK_WATCHER_ATTR_GET_BOOL(args, LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS)) + v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS; + + result = nm_team_link_watcher_new_arp_ping2( + _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_INIT_WAIT), + _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_INTERVAL), + _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_MISSED_MAX), + _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_VLANID), + _LINK_WATCHER_ATTR_GET_STRING(args, LINK_WATCHER_ATTRIBUTE_TARGET_HOST), + _LINK_WATCHER_ATTR_GET_STRING(args, LINK_WATCHER_ATTRIBUTE_SOURCE_HOST), + v_flags, + NULL); + } + + if (result) + return result; +fail: + *out_unrecognized_content = TRUE; + return NULL; +} + +/*****************************************************************************/ + +static GVariant * +_link_watcher_to_variant(const NMTeamLinkWatcher *link_watcher) +{ + NMValueTypUnioMaybe args[G_N_ELEMENTS(link_watcher_attr_datas)]; + GVariantBuilder builder; + int i; + + if (!link_watcher) + return NULL; + + _link_watcher_unpack(link_watcher, args); + + if (!args[LINK_WATCHER_ATTRIBUTE_NAME].has) + return NULL; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + + for (i = 0; i < (int) G_N_ELEMENTS(link_watcher_attr_datas); i++) { + const NMValueTypUnioMaybe *p_val = &args[i]; + const LinkWatcherAttrData *attr_data = &link_watcher_attr_datas[i]; + GVariant * v; + + if (!p_val->has) + continue; + if (nm_value_type_equal(attr_data->value_type, &attr_data->default_val, &p_val->val)) + continue; + + if (attr_data->value_type == NM_VALUE_TYPE_INT) + v = g_variant_new_int32(p_val->val.v_int); + else { + v = nm_value_type_to_variant(attr_data->value_type, &p_val->val); + } + if (!v) + continue; + + nm_assert(g_variant_is_floating(v)); + g_variant_builder_add(&builder, "{sv}", attr_data->dbus_name, v); + } + + return g_variant_builder_end(&builder); +} + +#define _LINK_WATCHER_ATTR_VARGET(variants, link_watcher_attribute, _value_type, c_type, _cmd) \ + ({ \ + GVariant *const *_variants = (variants); \ + GVariant * _cc; \ + \ + nm_assert(link_watcher_attr_datas[(link_watcher_attribute)].value_type == (_value_type)); \ + \ + (_cc = _variants[(link_watcher_attribute)]) \ + ? (_cmd) \ + : link_watcher_attr_datas[(link_watcher_attribute)].default_val.c_type; \ + }) +#define _LINK_WATCHER_ATTR_VARGET_BOOL(variants, link_watcher_attribute) \ + (_LINK_WATCHER_ATTR_VARGET(variants, \ + link_watcher_attribute, \ + NM_VALUE_TYPE_BOOL, \ + v_bool, \ + g_variant_get_boolean(_cc))) +#define _LINK_WATCHER_ATTR_VARGET_INT(variants, link_watcher_attribute) \ + (_LINK_WATCHER_ATTR_VARGET(variants, \ + link_watcher_attribute, \ + NM_VALUE_TYPE_INT, \ + v_int, \ + g_variant_get_int32(_cc))) +#define _LINK_WATCHER_ATTR_VARGET_STRING(variants, link_watcher_attribute) \ + (_LINK_WATCHER_ATTR_VARGET(variants, \ + link_watcher_attribute, \ + NM_VALUE_TYPE_STRING, \ + v_string, \ + g_variant_get_string(_cc, NULL))) + +static void +_variants_list_link_watcher_unref_auto(GVariant *(*p_variants)[]) +{ + int i; + + for (i = 0; i < (int) G_N_ELEMENTS(link_watcher_attr_datas); i++) + nm_g_variant_unref((*p_variants)[i]); +} + +static NMTeamLinkWatcher * +_link_watcher_from_variant(GVariant *watcher_var, gboolean strict_parsing, GError **error) +{ + nm_auto(_variants_list_link_watcher_unref_auto) + GVariant *variants[G_N_ELEMENTS(link_watcher_attr_datas)] = { + NULL, + }; + const char * v_key; + GVariant * v_val; + const char * v_name; + GVariantIter iter; + + g_return_val_if_fail(g_variant_is_of_type(watcher_var, G_VARIANT_TYPE("a{sv}")), NULL); + + g_variant_iter_init(&iter, watcher_var); + while (g_variant_iter_next(&iter, "{&sv}", &v_key, &v_val)) { + _nm_unused gs_unref_variant GVariant *v_val_free = v_val; + const LinkWatcherAttrData * attr_data = NULL; + const GVariantType * variant_type; + int i; + + for (i = 0; i < (int) G_N_ELEMENTS(link_watcher_attr_datas); i++) { + if (nm_streq(link_watcher_attr_datas[i].dbus_name, v_key)) { + attr_data = &link_watcher_attr_datas[i]; + break; + } + } + if (!attr_data) { + if (strict_parsing) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid D-Bus property \"%s\""), + v_key); + return NULL; + } + continue; + } + + if (attr_data->value_type == NM_VALUE_TYPE_INT) + variant_type = G_VARIANT_TYPE_INT32; + else + variant_type = nm_value_type_get_variant_type(attr_data->value_type); + + if (!g_variant_is_of_type(v_val, variant_type)) { + if (strict_parsing) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid D-Bus property \"%s\""), + v_key); + return NULL; + } + continue; + } + + if (variants[attr_data->link_watcher_attr]) { + if (strict_parsing) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("duplicate D-Bus property \"%s\""), + v_key); + return NULL; + } + g_variant_unref(variants[attr_data->link_watcher_attr]); + } + variants[attr_data->link_watcher_attr] = g_steal_pointer(&v_val_free); + } + +#define _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES(_type, _variants, _error, ...) \ + ({ \ + int _i; \ + gboolean _has_error = FALSE; \ + \ + for (_i = 0; _i < (int) G_N_ELEMENTS((_variants)); _i++) { \ + if ((_variants)[_i] && !NM_IN_SET((LinkWatcherAttribute) _i, __VA_ARGS__)) { \ + _has_error = TRUE; \ + g_set_error(_error, \ + NM_CONNECTION_ERROR, \ + NM_CONNECTION_ERROR_INVALID_PROPERTY, \ + _("invalid D-Bus property \"%s\" for \"%s\""), \ + link_watcher_attr_datas[_i].dbus_name, \ + _type); \ + break; \ + } \ + } \ + \ + _has_error; \ + }) + + v_name = _LINK_WATCHER_ATTR_VARGET_STRING(variants, LINK_WATCHER_ATTRIBUTE_NAME); + + if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_ETHTOOL)) { + if (strict_parsing + && _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES(v_name, + variants, + error, + _EXPECTED_LINK_WATCHER_ATTRIBUTES_ETHTOOL)) + return NULL; + return nm_team_link_watcher_new_ethtool( + _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_DELAY_UP), + _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_DELAY_DOWN), + strict_parsing ? error : NULL); + } + + if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_NSNA_PING)) { + if (strict_parsing + && _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES(v_name, + variants, + error, + _EXPECTED_LINK_WATCHER_ATTRIBUTES_NSNA_PING)) + return NULL; + return nm_team_link_watcher_new_nsna_ping( + _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_INIT_WAIT), + _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_INTERVAL), + _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_MISSED_MAX), + _LINK_WATCHER_ATTR_VARGET_STRING(variants, LINK_WATCHER_ATTRIBUTE_TARGET_HOST), + strict_parsing ? error : NULL); + } + + if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_ARP_PING)) { + NMTeamLinkWatcherArpPingFlags v_flags = NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE; + + if (strict_parsing + && _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES(v_name, + variants, + error, + _EXPECTED_LINK_WATCHER_ATTRIBUTES_ARP_PING)) + return NULL; + + if (_LINK_WATCHER_ATTR_VARGET_BOOL(variants, LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE)) + v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE; + if (_LINK_WATCHER_ATTR_VARGET_BOOL(variants, LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE)) + v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE; + if (_LINK_WATCHER_ATTR_VARGET_BOOL(variants, LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS)) + v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS; + + return nm_team_link_watcher_new_arp_ping2( + _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_INIT_WAIT), + _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_INTERVAL), + _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_MISSED_MAX), + _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_VLANID), + _LINK_WATCHER_ATTR_VARGET_STRING(variants, LINK_WATCHER_ATTRIBUTE_TARGET_HOST), + _LINK_WATCHER_ATTR_VARGET_STRING(variants, LINK_WATCHER_ATTRIBUTE_SOURCE_HOST), + v_flags, + strict_parsing ? error : NULL); + } + + if (strict_parsing) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unknown link-watcher name \"%s\""), + v_name); + } + return NULL; +} + +/*****************************************************************************/ + +/** + * _nm_utils_team_link_watchers_to_variant: + * @link_watchers: (element-type NMTeamLinkWatcher): array of #NMTeamLinkWatcher + * + * Utility function to convert a #GPtrArray of #NMTeamLinkWatcher objects + * representing link watcher configuration for team devices into a #GVariant + * of type 'aa{sv}' representing an array of link watchers. + * + * Returns: (transfer full): a new floating #GVariant representing link watchers. + **/ +GVariant * +_nm_utils_team_link_watchers_to_variant(const GPtrArray *link_watchers) +{ + GVariantBuilder builder; + guint i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + if (link_watchers) { + for (i = 0; i < link_watchers->len; i++) { + g_variant_builder_add(&builder, + "@a{sv}", + _link_watcher_to_variant(link_watchers->pdata[i])); + } + } + return g_variant_builder_end(&builder); +} + +/** + * _nm_utils_team_link_watchers_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * @strict_parsing: whether to parse strictly or ignore everything invalid. + * @error: error reason. + * + * Utility function to convert a #GVariant representing a list of team link + * watchers int a #GPtrArray of #NMTeamLinkWatcher objects. + * + * Returns: (transfer full) (element-type NMTeamLinkWatcher): a newly allocated + * #GPtrArray of #NMTeamLinkWatcher objects. + * + * Note that if you provide an @error, then the function can only fail (and return %NULL) + * or succeed (and not return %NULL). If you don't provide an @error, then the function + * never returns %NULL. + **/ +GPtrArray * +_nm_utils_team_link_watchers_from_variant(GVariant *value, gboolean strict_parsing, GError **error) +{ + gs_unref_ptrarray GPtrArray *link_watchers = NULL; + GVariantIter iter; + GVariant * watcher_var; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), NULL); + + link_watchers = g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref); + + g_variant_iter_init(&iter, value); + while (g_variant_iter_next(&iter, "@a{sv}", &watcher_var)) { + _nm_unused gs_unref_variant GVariant *watcher_var_free = watcher_var; + NMTeamLinkWatcher * watcher; + + watcher = _link_watcher_from_variant(watcher_var, strict_parsing, error); + if (error && *error) + return NULL; + if (watcher) + g_ptr_array_add(link_watchers, watcher); + } + + return g_steal_pointer(&link_watchers); +} + +/*****************************************************************************/ + +const char * +nm_team_setting_config_get(const NMTeamSetting *self) +{ + char *js_str; + + nm_assert(self); + + if (G_LIKELY(!self->d._js_str_need_synthetize)) + return self->d._js_str; + + nm_assert(!self->d._js_str); + nm_assert(self->d.strict_validated); + + if (_team_setting_check_default(self) == 0) { + /* the default is set. We signal this as a NULL JSON string. + * Nothing to do. */ + js_str = NULL; + } else { + gboolean list_is_empty = TRUE; + GString *gstr; + + gstr = g_string_new(NULL); + + g_string_append(gstr, "{ "); + + if (self->d.is_port) { + static const NMTeamAttribute attr_lst_port[] = { + NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID, + NM_TEAM_ATTRIBUTE_PORT_PRIO, + NM_TEAM_ATTRIBUTE_PORT_STICKY, + NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO, + NM_TEAM_ATTRIBUTE_PORT_LACP_KEY, + }; + + if (_team_setting_fields_to_json_maybe(self, + gstr, + !list_is_empty, + attr_lst_port, + G_N_ELEMENTS(attr_lst_port))) + list_is_empty = FALSE; + } else { + static const NMTeamAttribute attr_lst_runner_pt1[] = { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, + }; + static const NMTeamAttribute attr_lst_runner_pt2[] = { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL, + }; + static const NMTeamAttribute attr_lst_runner_pt3[] = { + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY, + }; + static const NMTeamAttribute attr_lst_notify_peers[] = { + NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT, + NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL, + }; + static const NMTeamAttribute attr_lst_mcast_rejoin[] = { + NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT, + NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL, + }; + + if (_team_setting_has_fields_any_v(self, + attr_lst_runner_pt1, + G_N_ELEMENTS(attr_lst_runner_pt1)) + || _team_setting_has_fields_any_v(self, + attr_lst_runner_pt2, + G_N_ELEMENTS(attr_lst_runner_pt2)) + || _team_setting_has_fields_any_v(self, + attr_lst_runner_pt3, + G_N_ELEMENTS(attr_lst_runner_pt3))) { + gboolean list_is_empty2 = TRUE; + + nm_assert(list_is_empty); + + nm_json_gstr_append_obj_name(gstr, "runner", '{'); + + if (_team_setting_fields_to_json_maybe(self, + gstr, + !list_is_empty2, + attr_lst_runner_pt1, + G_N_ELEMENTS(attr_lst_runner_pt1))) + list_is_empty2 = FALSE; + + if (_team_setting_has_fields_any_v(self, + attr_lst_runner_pt2, + G_N_ELEMENTS(attr_lst_runner_pt2))) { + if (!list_is_empty2) + nm_json_gstr_append_delimiter(gstr); + nm_json_gstr_append_obj_name(gstr, "tx_balancer", '{'); + if (!_team_setting_fields_to_json_maybe(self, + gstr, + FALSE, + attr_lst_runner_pt2, + G_N_ELEMENTS(attr_lst_runner_pt2))) + nm_assert_not_reached(); + g_string_append(gstr, " }"); + list_is_empty2 = FALSE; + } + + if (_team_setting_fields_to_json_maybe(self, + gstr, + !list_is_empty2, + attr_lst_runner_pt3, + G_N_ELEMENTS(attr_lst_runner_pt3))) + list_is_empty2 = FALSE; + + nm_assert(!list_is_empty2); + g_string_append(gstr, " }"); + list_is_empty = FALSE; + } + + if (_team_setting_has_fields_any_v(self, + attr_lst_notify_peers, + G_N_ELEMENTS(attr_lst_notify_peers))) { + if (!list_is_empty) + nm_json_gstr_append_delimiter(gstr); + nm_json_gstr_append_obj_name(gstr, "notify_peers", '{'); + if (!_team_setting_fields_to_json_maybe(self, + gstr, + FALSE, + attr_lst_notify_peers, + G_N_ELEMENTS(attr_lst_notify_peers))) + nm_assert_not_reached(); + g_string_append(gstr, " }"); + list_is_empty = FALSE; + } + + if (_team_setting_has_fields_any_v(self, + attr_lst_mcast_rejoin, + G_N_ELEMENTS(attr_lst_mcast_rejoin))) { + if (!list_is_empty) + nm_json_gstr_append_delimiter(gstr); + nm_json_gstr_append_obj_name(gstr, "mcast_rejoin", '{'); + if (!_team_setting_fields_to_json_maybe(self, + gstr, + FALSE, + attr_lst_mcast_rejoin, + G_N_ELEMENTS(attr_lst_mcast_rejoin))) + nm_assert_not_reached(); + g_string_append(gstr, " }"); + list_is_empty = FALSE; + } + } + + if (_team_setting_field_to_json( + self, + gstr, + !list_is_empty, + _team_attr_data_get(self->d.is_port, NM_TEAM_ATTRIBUTE_LINK_WATCHERS))) + list_is_empty = FALSE; + + if (!list_is_empty) + g_string_append(gstr, " }"); + + js_str = g_string_free(gstr, list_is_empty); + } + + /* mutate the constant object. In C++ speak, these fields are "mutable". + * That is because we construct the JSON string lazily/on-demand. */ + *((char **) &self->_data_priv._js_str) = js_str; + *((bool *) &self->_data_priv._js_str_need_synthetize) = FALSE; + + return self->d._js_str; +} + +/*****************************************************************************/ + +static gboolean +_attr_data_match_keys(const TeamAttrData *attr_data, const char *const *keys, guint8 n_keys) +{ + guint8 i; + + _team_attr_data_ASSERT(attr_data); + nm_assert(keys); + nm_assert(n_keys > 0); + nm_assert(({ + gboolean all_non_null = TRUE; + + for (i = 0; i < n_keys; i++) + all_non_null = all_non_null && keys[i] && keys[i][0] != '\0'; + all_non_null; + })); + + if (attr_data->js_keys_len < n_keys) + return FALSE; + for (i = 0; i < n_keys; i++) { + if (!nm_streq(keys[i], attr_data->js_keys[i])) + return FALSE; + } + return TRUE; +} + +static const TeamAttrData * +_attr_data_find_by_json_key(gboolean is_port, const char *const *keys, guint8 n_keys) +{ + const TeamAttrData *attr_data; + + for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; + attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)]; + attr_data++) { + if (_team_attr_data_is_relevant(attr_data, is_port) + && _attr_data_match_keys(attr_data, keys, n_keys)) + return attr_data; + } + + return NULL; +} + +static void +_js_parse_locate_keys(const NMJsonVt *vt, + NMTeamSetting * self, + nm_json_t * root_js_obj, + nm_json_t * found_keys[static _NM_TEAM_ATTRIBUTE_NUM], + gboolean * out_unrecognized_content) +{ + const char *keys[3]; + const char *cur_key1; + const char *cur_key2; + const char *cur_key3; + nm_json_t * cur_val1; + nm_json_t * cur_val2; + nm_json_t * cur_val3; + + nm_assert(vt); + +#define _handle(_self, _cur_key, _cur_val, _keys, _level, _found_keys, _out_unrecognized_content) \ + ({ \ + const TeamAttrData *_attr_data; \ + gboolean _handled = FALSE; \ + \ + (_keys)[(_level) -1] = (_cur_key); \ + _attr_data = _attr_data_find_by_json_key((_self)->d.is_port, (_keys), (_level)); \ + if (_attr_data && _attr_data->js_keys_len == (_level)) { \ + if ((_found_keys)[_attr_data->team_attr]) \ + *(_out_unrecognized_content) = TRUE; \ + (_found_keys)[_attr_data->team_attr] = (_cur_val); \ + _handled = TRUE; \ + } else if (!_attr_data || !nm_json_is_object((_cur_val))) { \ + *(_out_unrecognized_content) = TRUE; \ + _handled = TRUE; \ + } \ + _handled; \ + }) + + nm_json_object_foreach (vt, root_js_obj, cur_key1, cur_val1) { + if (!_handle(self, cur_key1, cur_val1, keys, 1, found_keys, out_unrecognized_content)) { + nm_json_object_foreach (vt, cur_val1, cur_key2, cur_val2) { + if (!_handle(self, + cur_key2, + cur_val2, + keys, + 2, + found_keys, + out_unrecognized_content)) { + nm_json_object_foreach (vt, cur_val2, cur_key3, cur_val3) { + if (!_handle(self, + cur_key3, + cur_val3, + keys, + 3, + found_keys, + out_unrecognized_content)) + *out_unrecognized_content = TRUE; + } + } + } + } + } + +#undef _handle +} + +static void +_js_parse_unpack(const NMJsonVt *vt, + gboolean is_port, + nm_json_t * found_keys[static _NM_TEAM_ATTRIBUTE_NUM], + bool out_has_lst[static _NM_TEAM_ATTRIBUTE_NUM], + NMValueTypUnion out_val_lst[static _NM_TEAM_ATTRIBUTE_NUM], + gboolean * out_unrecognized_content, + GPtrArray ** out_ptr_array_link_watchers_free, + GPtrArray ** out_ptr_array_master_runner_tx_hash_free) +{ + const TeamAttrData *attr_data; + + nm_assert(vt); + + for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; + attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)]; + attr_data++) { + NMValueTypUnion *p_out_val; + gboolean valid = FALSE; + nm_json_t * arg_js_obj; + + if (!_team_attr_data_is_relevant(attr_data, is_port)) + continue; + + nm_assert(!out_has_lst[attr_data->team_attr]); + + arg_js_obj = found_keys[attr_data->team_attr]; + if (!arg_js_obj) + continue; + + p_out_val = &out_val_lst[attr_data->team_attr]; + + if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) + valid = nm_value_type_from_json(vt, attr_data->value_type, arg_js_obj, p_out_val); + else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) { + GPtrArray * link_watchers = NULL; + NMTeamLinkWatcher *link_watcher; + + nm_assert(out_ptr_array_link_watchers_free && !*out_ptr_array_link_watchers_free); + if (nm_json_is_array(arg_js_obj)) { + gsize i, len; + + len = vt->nm_json_array_size(arg_js_obj); + link_watchers = + g_ptr_array_new_full(len, (GDestroyNotify) nm_team_link_watcher_unref); + for (i = 0; i < len; i++) { + link_watcher = _link_watcher_from_json(vt, + vt->nm_json_array_get(arg_js_obj, i), + out_unrecognized_content); + if (link_watcher) + g_ptr_array_add(link_watchers, link_watcher); + } + } else { + link_watcher = _link_watcher_from_json(vt, arg_js_obj, out_unrecognized_content); + if (link_watcher) { + link_watchers = + g_ptr_array_new_full(1, (GDestroyNotify) nm_team_link_watcher_unref); + g_ptr_array_add(link_watchers, link_watcher); + } + } + if (link_watchers) { + valid = TRUE; + p_out_val->v_ptrarray = link_watchers; + *out_ptr_array_link_watchers_free = link_watchers; + } + } else if (!is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) { + GPtrArray *strv = NULL; + + nm_assert(out_ptr_array_master_runner_tx_hash_free + && !*out_ptr_array_master_runner_tx_hash_free); + if (nm_json_is_array(arg_js_obj)) { + gsize i, len; + + len = vt->nm_json_array_size(arg_js_obj); + if (len > 0) { + strv = g_ptr_array_sized_new(len); + for (i = 0; i < len; i++) { + const char *v_string; + + if (nm_jansson_json_as_string(vt, + vt->nm_json_array_get(arg_js_obj, i), + &v_string) + <= 0 + || !v_string || v_string[0] == '\0') { + /* we remember that there was some invalid content, but parts of the + * list could still be parsed. */ + *out_unrecognized_content = TRUE; + continue; + } + g_ptr_array_add(strv, (char *) v_string); + } + } + valid = TRUE; + *out_ptr_array_master_runner_tx_hash_free = strv; + } + p_out_val->v_ptrarray = strv; + } else + nm_assert_not_reached(); + + out_has_lst[attr_data->team_attr] = valid; + if (!valid) + *out_unrecognized_content = TRUE; + } +} + +guint32 +nm_team_setting_config_set(NMTeamSetting *self, const char *js_str) +{ + const NMJsonVt *vt; + guint32 changed_flags = 0; + gboolean do_set_default = TRUE; + gboolean new_js_str_invalid = FALSE; + + _team_setting_ASSERT(self); + + if (!js_str || js_str[0] == '\0') { + changed_flags = _team_setting_set_default(self); + if (changed_flags != 0 || !nm_streq0(js_str, self->d._js_str)) + changed_flags |= nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG); + nm_clear_g_free((char **) &self->_data_priv._js_str); + self->_data_priv._js_str = g_strdup(js_str); + self->_data_priv._js_str_need_synthetize = FALSE; + self->_data_priv.strict_validated = TRUE; + self->_data_priv.js_str_invalid = FALSE; + return changed_flags; + } + + if (self->d._js_str && nm_streq(js_str, self->d._js_str)) { + if (!self->d.strict_validated) { + /* setting the same JSON string twice in a row has no effect. */ + return 0; + } + } else + changed_flags |= nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG); + + if ((vt = nm_json_vt())) { + nm_auto_decref_json nm_json_t *root_js_obj = NULL; + + root_js_obj = vt->nm_json_loads(js_str, 0, NULL); + if (!root_js_obj || !nm_json_is_object(root_js_obj)) + new_js_str_invalid = TRUE; + else { + gboolean unrecognized_content = FALSE; + bool has_lst[_NM_TEAM_ATTRIBUTE_NUM] = { + FALSE, + }; + NMValueTypUnion val_lst[_NM_TEAM_ATTRIBUTE_NUM]; + nm_json_t * found_keys[_NM_TEAM_ATTRIBUTE_NUM] = { + NULL, + }; + gs_unref_ptrarray GPtrArray *ptr_array_master_runner_tx_hash_free = NULL; + gs_unref_ptrarray GPtrArray *ptr_array_link_watchers_free = NULL; + + _js_parse_locate_keys(vt, self, root_js_obj, found_keys, &unrecognized_content); + + _js_parse_unpack(vt, + self->d.is_port, + found_keys, + has_lst, + val_lst, + &unrecognized_content, + &ptr_array_link_watchers_free, + &ptr_array_master_runner_tx_hash_free); + + do_set_default = FALSE; + + changed_flags |= _team_setting_set(self, TRUE, has_lst, val_lst); + } + } + + if (do_set_default) + changed_flags |= _team_setting_set_default(self); + + self->_data_priv.strict_validated = FALSE; + self->_data_priv._js_str_need_synthetize = FALSE; + self->_data_priv.js_str_invalid = new_js_str_invalid; + g_free((char *) self->_data_priv._js_str); + self->_data_priv._js_str = g_strdup(js_str); + + return changed_flags; +} + +/*****************************************************************************/ + +static void +_team_setting_prefix_error_plain(gboolean is_port, const char *property_name, GError **error) +{ + g_prefix_error(error, + "%s.%s: ", + is_port ? NM_SETTING_TEAM_PORT_SETTING_NAME : NM_SETTING_TEAM_SETTING_NAME, + property_name); +} + +static void +_team_setting_prefix_error(const NMTeamSetting *self, + const char * prop_name_master, + const char * prop_name_port, + GError ** error) +{ + _team_setting_ASSERT(self); + nm_assert(self->d.is_port ? (!!prop_name_port) : (!!prop_name_master)); + _team_setting_prefix_error_plain(self->d.is_port, + self->d.is_port ? prop_name_port : prop_name_master, + error); +} + +static gboolean +_team_setting_verify_properties(const NMTeamSetting *self, GError **error) +{ + const TeamAttrData *attr_data; + guint i; + + for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; + attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)]; + attr_data++) { + if (!_team_attr_data_is_relevant(attr_data, self->d.is_port)) + continue; + if (!_team_setting_has_field(self, attr_data)) + continue; + + if (attr_data->has_range) { + gconstpointer p_field; + + p_field = _team_setting_get_field(self, attr_data); + if (attr_data->value_type == NM_VALUE_TYPE_INT32) { + gint32 v = *((const gint32 *) p_field); + + if (v < attr_data->range.r_int32.min || v > attr_data->range.r_int32.max) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("value out or range")); + _team_setting_prefix_error_plain(self->d.is_port, + attr_data->property_name, + error); + return FALSE; + } + } else if (attr_data->value_type == NM_VALUE_TYPE_STRING) { + const char *v = *((const char *const *) p_field); + + if (nm_utils_strv_find_first((char **) attr_data->range.r_string.valid_names, -1, v) + < 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("invalid value")); + _team_setting_prefix_error_plain(self->d.is_port, + attr_data->property_name, + error); + return FALSE; + } + } else + nm_assert_not_reached(); + } + + if (!self->d.is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) { + if (self->d.master.runner_tx_hash) { + for (i = 0; i < self->d.master.runner_tx_hash->len; i++) { + const char *val = self->d.master.runner_tx_hash->pdata[i]; + + if (!val + || (nm_utils_strv_find_first((char **) _valid_names_runner_tx_hash, -1, val) + < 0)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("invalid runner-tx-hash")); + _team_setting_prefix_error_plain(self->d.is_port, + NM_SETTING_TEAM_RUNNER_TX_HASH, + error); + return FALSE; + } + } + } + } + } + + if (!self->d.is_port) { + for (i = 0; i < G_N_ELEMENTS(_runner_compat_lst); i++) { + const RunnerCompatElem *e = &_runner_compat_lst[i]; + + nm_assert(NM_PTRARRAY_LEN(e->valid_runners) > 0); + + attr_data = _team_attr_data_get(FALSE, e->team_attr); + + if (!_team_setting_has_field(self, attr_data)) + continue; + if (self->d.master.runner + && (nm_utils_strv_find_first((char **) e->valid_runners, -1, self->d.master.runner) + >= 0)) + continue; + if (e->valid_runners[1] == NULL) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("%s is only allowed for runner %s"), + attr_data->property_name, + e->valid_runners[0]); + } else { + gs_free char *s = NULL; + + s = g_strjoinv(",", (char **) e->valid_runners); + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("%s is only allowed for runners %s"), + attr_data->property_name, + s); + } + _team_setting_prefix_error_plain(self->d.is_port, NM_SETTING_TEAM_RUNNER, error); + return FALSE; + } + } else { + gboolean has_lacp_attrs; + gboolean has_activebackup_attrs; + + has_lacp_attrs = _team_setting_has_fields_any(self, + NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO, + NM_TEAM_ATTRIBUTE_PORT_LACP_KEY); + has_activebackup_attrs = _team_setting_has_fields_any(self, + NM_TEAM_ATTRIBUTE_PORT_PRIO, + NM_TEAM_ATTRIBUTE_PORT_STICKY); + if (has_lacp_attrs && has_activebackup_attrs) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("cannot set parameters for lacp and activebackup runners together")); + _team_setting_prefix_error(self, + NM_SETTING_TEAM_LINK_WATCHERS, + NM_SETTING_TEAM_PORT_LINK_WATCHERS, + error); + return FALSE; + } + } + + for (i = 0; i < self->d.link_watchers->len; i++) { + if (!self->d.link_watchers->pdata[i]) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("missing link watcher")); + _team_setting_prefix_error(self, + NM_SETTING_TEAM_LINK_WATCHERS, + NM_SETTING_TEAM_PORT_LINK_WATCHERS, + error); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +_team_setting_verify_config(const NMTeamSetting *self, GError **error) +{ + const char *js_str; + + /* we always materialize the JSON string. That is because we want to validate the + * string length of the resulting JSON. */ + js_str = nm_team_setting_config_get(self); + + if (js_str) { + if (strlen(js_str) > 1 * 1024 * 1024) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("team config exceeds size limit")); + _team_setting_prefix_error(self, + NM_SETTING_TEAM_CONFIG, + NM_SETTING_TEAM_PORT_CONFIG, + error); + return FALSE; + } + if (!g_utf8_validate(js_str, -1, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("team config is not valid UTF-8")); + _team_setting_prefix_error(self, + NM_SETTING_TEAM_CONFIG, + NM_SETTING_TEAM_PORT_CONFIG, + error); + return FALSE; + } + if (self->d.js_str_invalid) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid json")); + _team_setting_prefix_error(self, + NM_SETTING_TEAM_CONFIG, + NM_SETTING_TEAM_PORT_CONFIG, + error); + return FALSE; + } + } + + return TRUE; +} + +gboolean +nm_team_setting_verify(const NMTeamSetting *self, GError **error) +{ + if (self->d.strict_validated) { + if (!_team_setting_verify_properties(self, error)) + return FALSE; + } + return _team_setting_verify_config(self, error); +} + +/*****************************************************************************/ + +int +nm_team_setting_cmp(const NMTeamSetting *self_a, + const NMTeamSetting *self_b, + gboolean ignore_js_str) +{ + const TeamAttrData *attr_data; + + NM_CMP_SELF(self_a, self_b); + + NM_CMP_FIELD_UNSAFE(self_a, self_b, d.is_port); + + for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; + attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)]; + attr_data++) { + if (!_team_attr_data_is_relevant(attr_data, self_a->d.is_port)) + continue; + + NM_CMP_RETURN(_team_attr_data_cmp(attr_data, + self_a->d.is_port, + _team_setting_get_field(self_a, attr_data), + _team_setting_get_field(self_b, attr_data))); + } + + if (!ignore_js_str) { + NM_CMP_DIRECT_STRCMP0(nm_team_setting_config_get(self_a), + nm_team_setting_config_get(self_b)); + } + + return 0; +} + +guint32 +nm_team_setting_reset(NMTeamSetting *self, const NMTeamSetting *src) +{ + const TeamAttrData *attr_data; + guint32 changed_flags; + + _team_setting_ASSERT(self); + _team_setting_ASSERT(src); + nm_assert(self->d.is_port == src->d.is_port); + + if (self == src) + return 0; + + changed_flags = 0; + + for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; + attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)]; + attr_data++) { + if (!_team_attr_data_is_relevant(attr_data, self->d.is_port)) + continue; + if (_team_attr_data_equal(attr_data, + self->d.is_port, + _team_setting_get_field(self, attr_data), + _team_setting_get_field(src, attr_data))) + continue; + _team_attr_data_copy(attr_data, + self->d.is_port, + _team_setting_get_field(self, attr_data), + _team_setting_get_field(src, attr_data)); + changed_flags |= nm_team_attribute_to_flags(attr_data->team_attr); + } + + self->_data_priv.has_fields_mask = src->d.has_fields_mask; + + if (!nm_streq0(self->d._js_str, src->d._js_str)) { + g_free((char *) self->_data_priv._js_str); + self->_data_priv._js_str = g_strdup(src->d._js_str); + changed_flags |= nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG); + } else if (changed_flags != 0) + changed_flags |= nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG); + + self->_data_priv._js_str_need_synthetize = src->d._js_str_need_synthetize; + self->_data_priv.strict_validated = src->d.strict_validated; + self->_data_priv.js_str_invalid = src->d.js_str_invalid; + + return changed_flags; +} + +static void +_variants_list_team_unref_auto(GVariant *(*p_variants)[]) +{ + int i; + + for (i = 0; i < _NM_TEAM_ATTRIBUTE_NUM; i++) + nm_g_variant_unref((*p_variants)[i]); +} + +gboolean +nm_team_setting_reset_from_dbus(NMTeamSetting * self, + GVariant * setting_dict, + GHashTable * keys, + guint32 * out_changed, + guint /* NMSettingParseFlags */ parse_flags, + GError ** error) +{ + nm_auto(_variants_list_team_unref_auto) GVariant *variants[_NM_TEAM_ATTRIBUTE_NUM] = { + NULL, + }; + gs_unref_ptrarray GPtrArray *v_link_watchers = NULL; + const TeamAttrData * attr_data; + GVariantIter iter; + const char * v_key; + GVariant * v_val; + const NMJsonVt * vt; + + *out_changed = 0; + + g_variant_iter_init(&iter, setting_dict); + while (g_variant_iter_next(&iter, "{&sv}", &v_key, &v_val)) { + _nm_unused gs_unref_variant GVariant *v_val_free = v_val; + const GVariantType * variant_type = NULL; + + attr_data = _team_attr_data_find_for_property_name(self->d.is_port, v_key); + if (!attr_data) { + /* _nm_setting_new_from_dbus() already checks for unknown keys. Don't + * do that here. */ + continue; + } + + if (keys) + g_hash_table_remove(keys, v_key); + + if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) + variant_type = nm_value_type_get_variant_type(attr_data->value_type); + else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_CONFIG) + variant_type = G_VARIANT_TYPE_STRING; + else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) + variant_type = G_VARIANT_TYPE("aa{sv}"); + else if (!self->d.is_port + && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) + variant_type = G_VARIANT_TYPE_STRING_ARRAY; + else + nm_assert_not_reached(); + + if (!g_variant_is_of_type(v_val, variant_type)) { + if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid D-Bus type \"%s\""), + g_variant_get_type_string(v_val)); + _team_setting_prefix_error_plain(self->d.is_port, attr_data->property_name, error); + return FALSE; + } + continue; + } + + /* _nm_setting_new_from_dbus() already checks for duplicate keys. Don't + * do that here. */ + nm_g_variant_unref(variants[attr_data->team_attr]); + variants[attr_data->team_attr] = g_steal_pointer(&v_val_free); + } + + vt = nm_json_vt(); + + if (variants[NM_TEAM_ATTRIBUTE_LINK_WATCHERS]) { + if (variants[NM_TEAM_ATTRIBUTE_CONFIG] && vt + && !NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { + /* we don't require the content of the "link-watchers" and we also + * don't perform strict validation. No need to parse it. */ + } else { + gs_free_error GError *local = NULL; + + /* We might need the parsed v_link_watchers array below (because there is no JSON + * "config" present or because we don't have json support). + * + * Or we might run with NM_SETTING_PARSE_FLAGS_STRICT. In that mode, we may not necessarily + * require that the entire setting as a whole validates (if a JSON config is present and + * we are not "strict_validated") , but we require that we can at least parse the link watchers + * on their own. */ + v_link_watchers = _nm_utils_team_link_watchers_from_variant( + variants[NM_TEAM_ATTRIBUTE_LINK_WATCHERS], + NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT), + &local); + if (local && NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid link-watchers: %s"), + local->message); + _team_setting_prefix_error(self, + NM_SETTING_TEAM_LINK_WATCHERS, + NM_SETTING_TEAM_PORT_LINK_WATCHERS, + error); + return FALSE; + } + } + } + + *out_changed |= nm_team_setting_config_set( + self, + variants[NM_TEAM_ATTRIBUTE_CONFIG] + ? g_variant_get_string(variants[NM_TEAM_ATTRIBUTE_CONFIG], NULL) + : NULL); + + if (vt && variants[NM_TEAM_ATTRIBUTE_CONFIG]) { + /* for team settings, the JSON must be able to express all possible options. That means, + * if the GVariant contains both the JSON "config" and other options, then the other options + * are silently ignored. */ + } else { + guint32 extra_changed = 0u; + + for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; + attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)]; + attr_data++) { + NMValueTypUnion val; + guint32 changed_flags = 0u; + + if (!_team_attr_data_is_relevant(attr_data, self->d.is_port)) + continue; + if (!variants[attr_data->team_attr]) + continue; + + if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) { + nm_value_type_get_from_variant(attr_data->value_type, + &val, + variants[attr_data->team_attr], + FALSE); + changed_flags = _team_setting_value_set(self, + attr_data, + &val, + SET_FIELD_MODE_SET, + RESET_JSON_NO); + } else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) { + changed_flags = _team_setting_value_link_watchers_set_list( + self, + v_link_watchers ? (const NMTeamLinkWatcher *const *) v_link_watchers->pdata + : NULL, + v_link_watchers ? v_link_watchers->len : 0u, + SET_FIELD_MODE_SET, + RESET_JSON_NO); + } else if (!self->d.is_port + && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) { + gs_free const char **strv = NULL; + gsize len; + + strv = g_variant_get_strv(variants[attr_data->team_attr], &len); + changed_flags = _team_setting_value_master_runner_tx_hash_set_list( + self, + strv, + NM_MIN(len, (gsize) G_MAXUINT), + SET_FIELD_MODE_SET, + RESET_JSON_NO); + } else + nm_assert_not_reached(); + + extra_changed |= changed_flags; + } + + if (!variants[NM_TEAM_ATTRIBUTE_CONFIG]) { + /* clear the JSON string so it can be regenerated. But only if we didn't set + * it above. */ + self->_data_priv.strict_validated = TRUE; + self->_data_priv._js_str_need_synthetize = TRUE; + } + + *out_changed |= extra_changed; + } + + return TRUE; +} + +/*****************************************************************************/ + +gboolean +nm_team_setting_maybe_changed(NMSetting * source, + const GParamSpec *const *obj_properties, + guint32 changed_flags) +{ + NMTeamAttribute team_attr; + int count_flags; + guint32 ch; + + if (changed_flags == 0u) + return FALSE; + + count_flags = 0; + for (ch = changed_flags; ch != 0u; ch >>= 1) { + if (NM_FLAGS_HAS(ch, 0x1u)) + count_flags++; + } + + if (count_flags > 1) + g_object_freeze_notify(G_OBJECT(source)); + + ch = changed_flags; + for (team_attr = 0; team_attr < _NM_TEAM_ATTRIBUTE_NUM; team_attr++) { + if (!NM_FLAGS_ANY(ch, nm_team_attribute_to_flags(team_attr))) + continue; + g_object_notify_by_pspec(G_OBJECT(source), (GParamSpec *) obj_properties[team_attr]); + ch &= ~nm_team_attribute_to_flags(team_attr); + if (ch == 0) + break; + } + + if (count_flags > 1) + g_object_thaw_notify(G_OBJECT(source)); + + return TRUE; +} + +/*****************************************************************************/ + +NMTeamSetting * +_nm_setting_get_team_setting(struct _NMSetting *setting) +{ + if (NM_IS_SETTING_TEAM(setting)) + return _nm_setting_team_get_team_setting(NM_SETTING_TEAM(setting)); + return _nm_setting_team_port_get_team_setting(NM_SETTING_TEAM_PORT(setting)); +} + +static GVariant * +_nm_team_settings_property_to_dbus(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + NMTeamSetting * self = _nm_setting_get_team_setting(setting); + const TeamAttrData *attr_data = + _team_attr_data_get(self->d.is_port, + sett_info->property_infos[property_idx].param_spec->param_id); + + if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_CONFIG) { + const char *config; + + if (self->d.strict_validated && !_nm_utils_is_manager_process) { + /* if we are in strict validating mode on the client side, the JSON is generated + * artificially. In this case, don't send the config via D-Bus to the server. + * + * This also will cause NetworkManager to strictly validate the settings. + * If a JSON "config" is present, strict validation won't be performed. */ + return NULL; + } + + config = nm_team_setting_config_get(self); + return config ? g_variant_new_string(config) : NULL; + } + + if (!_team_setting_has_field(self, attr_data)) + return NULL; + + if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) { + return nm_value_type_to_variant(attr_data->value_type, + _team_setting_get_field(self, attr_data)); + } + if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) + return _nm_utils_team_link_watchers_to_variant(self->d.link_watchers); + if (!self->d.is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) { + return g_variant_new_strv(self->d.master.runner_tx_hash + ? (const char *const *) self->d.master.runner_tx_hash->pdata + : NULL, + self->d.master.runner_tx_hash ? self->d.master.runner_tx_hash->len + : 0u); + } + + nm_assert_not_reached(); + return NULL; +} + +static void +_nm_team_settings_property_from_dbus_link_watchers(GVariant *dbus_value, GValue *prop_value) +{ + g_value_take_boxed(prop_value, + _nm_utils_team_link_watchers_from_variant(dbus_value, FALSE, NULL)); +} + +const NMSettInfoPropertType nm_sett_info_propert_type_team_b = { + .dbus_type = G_VARIANT_TYPE_BOOLEAN, + .to_dbus_fcn = _nm_team_settings_property_to_dbus, +}; + +const NMSettInfoPropertType nm_sett_info_propert_type_team_i = { + .dbus_type = G_VARIANT_TYPE_INT32, + .to_dbus_fcn = _nm_team_settings_property_to_dbus, +}; + +const NMSettInfoPropertType nm_sett_info_propert_type_team_s = { + .dbus_type = G_VARIANT_TYPE_STRING, + .to_dbus_fcn = _nm_team_settings_property_to_dbus, +}; + +const NMSettInfoPropertType nm_sett_info_propert_type_team_as = { + .dbus_type = NM_G_VARIANT_TYPE("as"), + .to_dbus_fcn = _nm_team_settings_property_to_dbus, +}; + +const NMSettInfoPropertType nm_sett_info_propert_type_team_link_watchers = { + .dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = _nm_team_settings_property_to_dbus, + .gprop_from_dbus_fcn = _nm_team_settings_property_from_dbus_link_watchers, +}; + +/*****************************************************************************/ + +NMTeamSetting * +nm_team_setting_new(gboolean is_port, const char *js_str) +{ + NMTeamSetting *self; + gsize l; + + G_STATIC_ASSERT_EXPR(sizeof(*self) == sizeof(self->_data_priv)); + G_STATIC_ASSERT_EXPR(sizeof(*self) + == NM_CONST_MAX(nm_offsetofend(NMTeamSetting, d.master), + nm_offsetofend(NMTeamSetting, d.port))); + + l = is_port ? nm_offsetofend(NMTeamSetting, d.port) : nm_offsetofend(NMTeamSetting, d.master); + + self = g_malloc0(l); + + self->_data_priv.is_port = is_port; + self->_data_priv.strict_validated = TRUE; + self->_data_priv._js_str_need_synthetize = FALSE; + self->_data_priv.link_watchers = + g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref); + + _team_setting_ASSERT(self); + + nm_team_setting_config_set(self, js_str); + + _team_setting_ASSERT(self); + + return self; +} + +void +nm_team_setting_free(NMTeamSetting *self) +{ + if (!self) + return; + + _team_setting_ASSERT(self); + + if (!self->d.is_port) { + nm_clear_pointer(((GPtrArray **) &self->_data_priv.master.runner_tx_hash), + g_ptr_array_unref); + g_free((char *) self->_data_priv.master.runner); + g_free((char *) self->_data_priv.master.runner_hwaddr_policy); + g_free((char *) self->_data_priv.master.runner_tx_balancer); + g_free((char *) self->_data_priv.master.runner_agg_select_policy); + } + g_ptr_array_unref((GPtrArray *) self->_data_priv.link_watchers); + g_free((char *) self->_data_priv._js_str); + g_free(self); +} diff --git a/src/libnm-core-impl/nm-team-utils.h b/src/libnm-core-impl/nm-team-utils.h new file mode 100644 index 0000000..2039c16 --- /dev/null +++ b/src/libnm-core-impl/nm-team-utils.h @@ -0,0 +1,271 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#ifndef __NM_TEAM_UITLS_H__ +#define __NM_TEAM_UITLS_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) + #error Cannot use this header. +#endif + +#include "libnm-glib-aux/nm-value-type.h" +#include "libnm-core-intern/nm-core-internal.h" + +struct _NMSetting; + +struct NMTeamLinkWatcher; + +typedef enum { + + _NM_TEAM_ATTRIBUTE_0 = 0, + NM_TEAM_ATTRIBUTE_CONFIG = 1, + NM_TEAM_ATTRIBUTE_LINK_WATCHERS = 2, + + _NM_TEAM_ATTRIBUTE_START = 3, + + NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT = _NM_TEAM_ATTRIBUTE_START, + NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL, + NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT, + NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS, + NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY, + _NM_TEAM_ATTRIBUTE_MASTER_NUM, + + NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID = _NM_TEAM_ATTRIBUTE_START, + NM_TEAM_ATTRIBUTE_PORT_PRIO, + NM_TEAM_ATTRIBUTE_PORT_STICKY, + NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO, + NM_TEAM_ATTRIBUTE_PORT_LACP_KEY, + _NM_TEAM_ATTRIBUTE_PORT_NUM, + + _NM_TEAM_ATTRIBUTE_NUM = MAX(_NM_TEAM_ATTRIBUTE_MASTER_NUM, _NM_TEAM_ATTRIBUTE_PORT_NUM), + +} NMTeamAttribute; + +static inline guint32 +nm_team_attribute_to_flags(NMTeamAttribute team_attr) +{ + nm_assert(_NM_INT_NOT_NEGATIVE(team_attr)); + nm_assert(team_attr < _NM_TEAM_ATTRIBUTE_NUM); + G_STATIC_ASSERT_EXPR(_NM_TEAM_ATTRIBUTE_NUM < 32); + + return ((guint32) 1) << team_attr; +} + +struct _NMTeamSettingData { + const char *_js_str; + + const GPtrArray *link_watchers; + + /* this means that @_js_str is unset and needs to be created by + * converting the properties to JSON. This flag indicates that + * we need to re-generate the JSON string on-demand (lazily). */ + bool _js_str_need_synthetize; + + bool strict_validated : 1; + + /* indicates tha the JSON is invalid. Usually, we do a very relaxed validation of + * the JSON config, in case !@strict_validated and accept all unknown fields. This + * flag indicates that the JSON value is not even parsable as JSON. nm_connection_verify() + * would reject such a setting. */ + bool js_str_invalid : 1; + + bool is_port : 1; + + guint32 has_fields_mask; + + union { + struct { + const GPtrArray *runner_tx_hash; + const char * runner; + const char * runner_hwaddr_policy; + const char * runner_tx_balancer; + const char * runner_agg_select_policy; + gint32 notify_peers_count; + gint32 notify_peers_interval; + gint32 mcast_rejoin_count; + gint32 mcast_rejoin_interval; + gint32 runner_sys_prio; + gint32 runner_min_ports; + gint32 runner_tx_balancer_interval; + bool runner_active; + bool runner_fast_rate; + } master; + struct { + gint32 queue_id; + gint32 prio; + gint32 lacp_prio; + gint32 lacp_key; + bool sticky; + } port; + }; +}; + +/*****************************************************************************/ + +typedef struct { + union { + const struct _NMTeamSettingData d; + + struct _NMTeamSettingData _data_priv; + }; +} NMTeamSetting; + +NMTeamSetting *nm_team_setting_new(gboolean is_port, const char *js_str); + +void nm_team_setting_free(NMTeamSetting *self); + +NM_AUTO_DEFINE_FCN0(NMTeamSetting *, _nm_auto_free_team_setting, nm_team_setting_free); +#define nm_auto_free_team_setting nm_auto(_nm_auto_free_team_setting) + +/*****************************************************************************/ + +const char *nm_team_setting_config_get(const NMTeamSetting *self); + +guint32 nm_team_setting_config_set(NMTeamSetting *self, const char *js_str); + +/*****************************************************************************/ + +gconstpointer _nm_team_setting_value_get(const NMTeamSetting *self, + NMTeamAttribute team_attr, + NMValueType value_type); + +static inline gboolean +nm_team_setting_value_get_bool(const NMTeamSetting *self, NMTeamAttribute team_attr) +{ + const bool *p; + + p = _nm_team_setting_value_get(self, team_attr, NM_VALUE_TYPE_BOOL); + return p ? *p : 0; +} + +static inline gint32 +nm_team_setting_value_get_int32(const NMTeamSetting *self, NMTeamAttribute team_attr) +{ + const gint32 *p; + + p = _nm_team_setting_value_get(self, team_attr, NM_VALUE_TYPE_INT32); + return p ? *p : 0; +} + +static inline const char * +nm_team_setting_value_get_string(const NMTeamSetting *self, NMTeamAttribute team_attr) +{ + const char *const *p; + + p = _nm_team_setting_value_get(self, team_attr, NM_VALUE_TYPE_STRING); + return p ? *p : NULL; +} + +/*****************************************************************************/ + +guint32 nm_team_setting_value_reset(NMTeamSetting * self, + NMTeamAttribute team_attr, + gboolean to_default /* or else unset */); + +guint32 _nm_team_setting_value_set(NMTeamSetting * self, + NMTeamAttribute team_attr, + NMValueType value_type, + gconstpointer val); + +static inline guint32 +nm_team_setting_value_set_bool(NMTeamSetting *self, NMTeamAttribute team_attr, gboolean val) +{ + const bool bool_val = val; + + return _nm_team_setting_value_set(self, team_attr, NM_VALUE_TYPE_BOOL, &bool_val); +} + +static inline guint32 +nm_team_setting_value_set_int32(NMTeamSetting *self, NMTeamAttribute team_attr, gint32 val) +{ + return _nm_team_setting_value_set(self, team_attr, NM_VALUE_TYPE_INT32, &val); +} + +static inline guint32 +nm_team_setting_value_set_string(NMTeamSetting *self, NMTeamAttribute team_attr, const char *arg) +{ + return _nm_team_setting_value_set(self, team_attr, NM_VALUE_TYPE_STRING, &arg); +} + +/*****************************************************************************/ + +guint32 nm_team_setting_value_link_watchers_add(NMTeamSetting * self, + const struct NMTeamLinkWatcher *link_watcher); + +guint32 nm_team_setting_value_link_watchers_remove(NMTeamSetting *self, guint idx); + +guint32 +nm_team_setting_value_link_watchers_remove_by_value(NMTeamSetting * self, + const struct NMTeamLinkWatcher *link_watcher); + +guint32 nm_team_setting_value_link_watchers_set_list(NMTeamSetting * self, + const struct NMTeamLinkWatcher *const *arr, + guint len); + +/*****************************************************************************/ + +guint32 nm_team_setting_value_master_runner_tx_hash_add(NMTeamSetting *self, const char *txhash); + +guint32 nm_team_setting_value_master_runner_tx_hash_remove(NMTeamSetting *self, guint idx); + +guint32 nm_team_setting_value_master_runner_tx_hash_set_list(NMTeamSetting * self, + const char *const *arr, + guint len); + +/*****************************************************************************/ + +gboolean nm_team_setting_verify(const NMTeamSetting *self, GError **error); + +/*****************************************************************************/ + +int nm_team_setting_cmp(const NMTeamSetting *self_a, + const NMTeamSetting *self_b, + gboolean ignore_js_str); + +guint32 nm_team_setting_reset(NMTeamSetting *self, const NMTeamSetting *src); + +gboolean nm_team_setting_reset_from_dbus(NMTeamSetting * self, + GVariant * setting_dict, + GHashTable * keys, + guint32 * out_changed, + guint /* NMSettingParseFlags */ parse_flags, + GError ** error); + +/*****************************************************************************/ + +GPtrArray * +_nm_utils_team_link_watchers_from_variant(GVariant *value, gboolean strict_parsing, GError **error); +GVariant *_nm_utils_team_link_watchers_to_variant(const GPtrArray *link_watchers); + +/*****************************************************************************/ + +gboolean nm_team_setting_maybe_changed(struct _NMSetting * source, + const GParamSpec *const *obj_properties, + guint32 changed); + +struct _NMSettingTeam; +struct _NMSettingTeamPort; +NMTeamSetting *_nm_setting_team_get_team_setting(struct _NMSettingTeam *setting); +NMTeamSetting *_nm_setting_team_port_get_team_setting(struct _NMSettingTeamPort *setting); +NMTeamSetting *_nm_setting_get_team_setting(struct _NMSetting *setting); + +/*****************************************************************************/ + +extern const NMSettInfoPropertType nm_sett_info_propert_type_team_b; +extern const NMSettInfoPropertType nm_sett_info_propert_type_team_i; +extern const NMSettInfoPropertType nm_sett_info_propert_type_team_s; +extern const NMSettInfoPropertType nm_sett_info_propert_type_team_as; +extern const NMSettInfoPropertType nm_sett_info_propert_type_team_link_watchers; + +#endif /* __NM_TEAM_UITLS_H__ */ diff --git a/src/libnm-core-impl/nm-utils-private.h b/src/libnm-core-impl/nm-utils-private.h new file mode 100644 index 0000000..eb545d0 --- /dev/null +++ b/src/libnm-core-impl/nm-utils-private.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2005 - 2017 Red Hat, Inc. + */ + +#ifndef __NM_UTILS_PRIVATE_H__ +#define __NM_UTILS_PRIVATE_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) + #error Cannot use this header. +#endif + +#include "nm-setting-private.h" +#include "nm-setting-ip-config.h" + +#define NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(_name, _type, ...) \ + (&((const NMVariantAttributeSpec){.name = _name, .type = _type, __VA_ARGS__})) + +gboolean _nm_utils_string_slist_validate(GSList *list, const char **valid_values); + +gboolean _nm_utils_secret_flags_validate(NMSettingSecretFlags secret_flags, + const char * setting_name, + const char * property_name, + NMSettingSecretFlags disallowed_flags, + GError ** error); + +gboolean _nm_utils_wps_method_validate(NMSettingWirelessSecurityWpsMethod wps_method, + const char * setting_name, + const char * property_name, + gboolean wps_required, + GError ** error); + +/* D-Bus transform funcs */ + +extern const NMSettInfoPropertType nm_sett_info_propert_type_strdict; + +extern const NMSettInfoPropertType nm_sett_info_propert_type_mac_address; + +extern const NMSettInfoPropertType nm_sett_info_propert_type_cloned_mac_address; + +extern const NMSettInfoPropertType nm_sett_info_propert_type_assigned_mac_address; + +extern const NMSettInfoPropertType nm_sett_info_propert_type_bridge_vlans; + +void _nm_utils_strdict_from_dbus(GVariant *dbus_value, GValue *prop_value); + +void _nm_utils_bytes_from_dbus(GVariant *dbus_value, GValue *prop_value); + +char *_nm_utils_hwaddr_canonical_or_invalid(const char *mac, gssize length); + +gboolean _nm_utils_hwaddr_link_local_valid(const char *mac); + +gboolean _nm_sriov_vf_parse_vlans(NMSriovVF *vf, const char *str, GError **error); + +gboolean _nm_utils_bridge_vlan_verify_list(GPtrArray * vlans, + gboolean check_normalizable, + GError ** error, + const char *setting, + const char *property); + +#endif diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c new file mode 100644 index 0000000..badae39 --- /dev/null +++ b/src/libnm-core-impl/nm-utils.c @@ -0,0 +1,5952 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2005 - 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libnm-glib-aux/nm-json-aux.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-enum-utils.h" +#include "libnm-glib-aux/nm-time-utils.h" +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" +#include "nm-crypto.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-infiniband.h" +#include "nm-setting-ip6-config.h" +#include "nm-setting-team.h" +#include "nm-setting-vlan.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless.h" + +/** + * SECTION:nm-utils + * @short_description: Utility functions + * + * A collection of utility functions for working with SSIDs, IP addresses, Wi-Fi + * access points and devices, among other things. + */ + +/*****************************************************************************/ + +/** + * NMUtilsPredicateStr: + * @str: the name to check. + * + * This function takes a string argument and returns either %TRUE or %FALSE. + * It is a general purpose predicate, for example used by nm_setting_option_clear_by_name(). + * + * Returns: %TRUE if the predicate function matches. + * + * Since: 1.26 + */ + +/*****************************************************************************/ + +struct _NMSockAddrEndpoint { + const char *host; + guint16 port; + guint refcount; + char endpoint[]; +}; + +static gboolean +NM_IS_SOCK_ADDR_ENDPOINT(const NMSockAddrEndpoint *self) +{ + return self && self->refcount > 0; +} + +static const char * +_parse_endpoint(char *str, guint16 *out_port) +{ + char * s; + const char *s_port; + gint16 port; + + /* Like + * - https://git.zx2c4.com/WireGuard/tree/src/tools/config.c?id=5e99a6d43fe2351adf36c786f5ea2086a8fe7ab8#n192 + * - https://github.com/systemd/systemd/blob/911649fdd43f3a9158b847947724a772a5a45c34/src/network/netdev/wireguard.c#L614 + */ + + g_strstrip(str); + + if (!str[0]) + return NULL; + + if (str[0] == '[') { + str++; + s = strchr(str, ']'); + if (!s) + return NULL; + if (s == str) + return NULL; + if (s[1] != ':') + return NULL; + if (!s[2]) + return NULL; + *s = '\0'; + s_port = &s[2]; + } else { + s = strrchr(str, ':'); + if (!s) + return NULL; + if (s == str) + return NULL; + if (!s[1]) + return NULL; + *s = '\0'; + s_port = &s[1]; + } + + if (!NM_STRCHAR_ALL(s_port, ch, (ch >= '0' && ch <= '9'))) + return NULL; + + port = _nm_utils_ascii_str_to_int64(s_port, 10, 1, G_MAXUINT16, 0); + if (port == 0) + return NULL; + + *out_port = port; + return str; +} + +/** + * nm_sock_addr_endpoint_new: + * @endpoint: the endpoint string. + * + * This function cannot fail, even if the @endpoint is invalid. + * The reason is to allow NMSockAddrEndpoint also to be used + * for tracking invalid endpoints. Use nm_sock_addr_endpoint_get_host() + * to determine whether the endpoint is valid. + * + * Returns: (transfer full): the new #NMSockAddrEndpoint endpoint. + */ +NMSockAddrEndpoint * +nm_sock_addr_endpoint_new(const char *endpoint) +{ + NMSockAddrEndpoint *ep; + gsize l_endpoint; + gsize l_host = 0; + gsize i; + gs_free char * host_clone = NULL; + const char * host; + guint16 port; + + g_return_val_if_fail(endpoint, NULL); + + l_endpoint = strlen(endpoint) + 1; + + host = _parse_endpoint(nm_strndup_a(200, endpoint, l_endpoint - 1, &host_clone), &port); + + if (host) + l_host = strlen(host) + 1; + + ep = g_malloc(sizeof(NMSockAddrEndpoint) + l_endpoint + l_host); + ep->refcount = 1; + memcpy(ep->endpoint, endpoint, l_endpoint); + if (host) { + i = l_endpoint; + memcpy(&ep->endpoint[i], host, l_host); + ep->host = &ep->endpoint[i]; + ep->port = port; + } else { + ep->host = NULL; + ep->port = 0; + } + return ep; +} + +/** + * nm_sock_addr_endpoint_ref: + * @self: (allow-none): the #NMSockAddrEndpoint + */ +NMSockAddrEndpoint * +nm_sock_addr_endpoint_ref(NMSockAddrEndpoint *self) +{ + if (!self) + return NULL; + + g_return_val_if_fail(NM_IS_SOCK_ADDR_ENDPOINT(self), NULL); + + nm_assert(self->refcount < G_MAXUINT); + + self->refcount++; + return self; +} + +/** + * nm_sock_addr_endpoint_unref: + * @self: (allow-none): the #NMSockAddrEndpoint + */ +void +nm_sock_addr_endpoint_unref(NMSockAddrEndpoint *self) +{ + if (!self) + return; + + g_return_if_fail(NM_IS_SOCK_ADDR_ENDPOINT(self)); + + if (--self->refcount == 0) + g_free(self); +} + +/** + * nm_sock_addr_endpoint_get_endpoint: + * @self: the #NMSockAddrEndpoint + * + * Gives the endpoint string. Since #NMSockAddrEndpoint's only + * information is the endpoint string, this can be used for comparing + * to instances for equality and order them lexically. + * + * Returns: (transfer none): the endpoint. + */ +const char * +nm_sock_addr_endpoint_get_endpoint(NMSockAddrEndpoint *self) +{ + g_return_val_if_fail(NM_IS_SOCK_ADDR_ENDPOINT(self), NULL); + + return self->endpoint; +} + +/** + * nm_sock_addr_endpoint_get_host: + * @self: the #NMSockAddrEndpoint + * + * Returns: (transfer none): the parsed host part of the endpoint. + * If the endpoint is invalid, %NULL will be returned. + */ +const char * +nm_sock_addr_endpoint_get_host(NMSockAddrEndpoint *self) +{ + g_return_val_if_fail(NM_IS_SOCK_ADDR_ENDPOINT(self), NULL); + + return self->host; +} + +/** + * nm_sock_addr_endpoint_get_port: + * @self: the #NMSockAddrEndpoint + * + * Returns: the parsed port part of the endpoint (the service). + * If the endpoint is invalid, -1 will be returned. + */ +gint32 +nm_sock_addr_endpoint_get_port(NMSockAddrEndpoint *self) +{ + g_return_val_if_fail(NM_IS_SOCK_ADDR_ENDPOINT(self), -1); + + return self->host ? (int) self->port : -1; +} + +gboolean +nm_sock_addr_endpoint_get_fixed_sockaddr(NMSockAddrEndpoint *self, gpointer sockaddr) +{ + int addr_family; + NMIPAddr addrbin; + const char *s; + guint scope_id = 0; + + g_return_val_if_fail(NM_IS_SOCK_ADDR_ENDPOINT(self), FALSE); + g_return_val_if_fail(sockaddr, FALSE); + + if (!self->host) + return FALSE; + + if (nm_utils_parse_inaddr_bin(AF_UNSPEC, self->host, &addr_family, &addrbin)) + goto good; + + /* See if there is an IPv6 scope-id... + * + * Note that it does not make sense to persist connection profiles to disk, + * that refenrence a scope-id (because the interface's ifindex changes on + * reboot). However, we also support runtime only changes like `nmcli device modify` + * where nothing is persisted to disk. At least in that case, passing a scope-id + * might be reasonable. So, parse that too. */ + s = strchr(self->host, '%'); + if (!s) + return FALSE; + + if (s[1] == '\0' || !NM_STRCHAR_ALL(&s[1], ch, (ch >= '0' && ch <= '9'))) + return FALSE; + + scope_id = _nm_utils_ascii_str_to_int64(&s[1], 10, 0, G_MAXINT32, G_MAXUINT); + if (scope_id == G_MAXUINT && errno) + return FALSE; + + { + gs_free char *tmp_str = NULL; + const char * host_part; + + host_part = nm_strndup_a(200, self->host, s - self->host, &tmp_str); + if (nm_utils_parse_inaddr_bin(AF_INET6, host_part, &addr_family, &addrbin)) + goto good; + } + + return FALSE; + +good: + switch (addr_family) { + case AF_INET: + *((struct sockaddr_in *) sockaddr) = (struct sockaddr_in){ + .sin_family = AF_INET, + .sin_addr = addrbin.addr4_struct, + .sin_port = htons(self->port), + }; + return TRUE; + case AF_INET6: + *((struct sockaddr_in6 *) sockaddr) = (struct sockaddr_in6){ + .sin6_family = AF_INET6, + .sin6_addr = addrbin.addr6, + .sin6_port = htons(self->port), + .sin6_scope_id = scope_id, + .sin6_flowinfo = 0, + }; + return TRUE; + } + + return FALSE; +} + +/*****************************************************************************/ + +struct IsoLangToEncodings { + const char * lang; + const char *const *encodings; +}; + +#define LANG_ENCODINGS(l, ...) \ + { \ + .lang = l, .encodings = NM_MAKE_STRV(__VA_ARGS__), \ + } + +/* 5-letter language codes */ +static const struct IsoLangToEncodings isoLangEntries5[] = { + /* Simplified Chinese */ + LANG_ENCODINGS("zh_cn", "euc-cn", "gb2312", "gb18030"), /* PRC */ + LANG_ENCODINGS("zh_sg", "euc-cn", "gb2312", "gb18030"), /* Singapore */ + + /* Traditional Chinese */ + LANG_ENCODINGS("zh_tw", "big5", "euc-tw"), /* Taiwan */ + LANG_ENCODINGS("zh_hk", "big5", "euc-tw", "big5-hkcs"), /* Hong Kong */ + LANG_ENCODINGS("zh_mo", "big5", "euc-tw"), /* Macau */ + + LANG_ENCODINGS(NULL, NULL)}; + +/* 2-letter language codes; we don't care about the other 3 in this table */ +static const struct IsoLangToEncodings isoLangEntries2[] = { + /* Japanese */ + LANG_ENCODINGS("ja", "euc-jp", "shift_jis", "iso-2022-jp"), + + /* Korean */ + LANG_ENCODINGS("ko", "euc-kr", "iso-2022-kr", "johab"), + + /* Thai */ + LANG_ENCODINGS("th", "iso-8859-11", "windows-874"), + + /* Central European */ + LANG_ENCODINGS("hu", "iso-8859-2", "windows-1250"), /* Hungarian */ + LANG_ENCODINGS("cs", "iso-8859-2", "windows-1250"), /* Czech */ + LANG_ENCODINGS("hr", "iso-8859-2", "windows-1250"), /* Croatian */ + LANG_ENCODINGS("pl", "iso-8859-2", "windows-1250"), /* Polish */ + LANG_ENCODINGS("ro", "iso-8859-2", "windows-1250"), /* Romanian */ + LANG_ENCODINGS("sk", "iso-8859-2", "windows-1250"), /* Slovakian */ + LANG_ENCODINGS("sl", "iso-8859-2", "windows-1250"), /* Slovenian */ + LANG_ENCODINGS("sh", "iso-8859-2", "windows-1250"), /* Serbo-Croatian */ + + /* Cyrillic */ + LANG_ENCODINGS("ru", "koi8-r", "windows-1251", "iso-8859-5"), /* Russian */ + LANG_ENCODINGS("be", "koi8-r", "windows-1251", "iso-8859-5"), /* Belorussian */ + LANG_ENCODINGS("bg", "windows-1251", "koi8-r", "iso-8859-5"), /* Bulgarian */ + LANG_ENCODINGS("mk", "koi8-r", "windows-1251", "iso-8859-5"), /* Macedonian */ + LANG_ENCODINGS("sr", "koi8-r", "windows-1251", "iso-8859-5"), /* Serbian */ + LANG_ENCODINGS("uk", "koi8-u", "koi8-r", "windows-1251"), /* Ukrainian */ + + /* Arabic */ + LANG_ENCODINGS("ar", "iso-8859-6", "windows-1256"), + + /* Baltic */ + LANG_ENCODINGS("et", "iso-8859-4", "windows-1257"), /* Estonian */ + LANG_ENCODINGS("lt", "iso-8859-4", "windows-1257"), /* Lithuanian */ + LANG_ENCODINGS("lv", "iso-8859-4", "windows-1257"), /* Latvian */ + + /* Greek */ + LANG_ENCODINGS("el", "iso-8859-7", "windows-1253"), + + /* Hebrew */ + LANG_ENCODINGS("he", "iso-8859-8", "windows-1255"), + LANG_ENCODINGS("iw", "iso-8859-8", "windows-1255"), + + /* Turkish */ + LANG_ENCODINGS("tr", "iso-8859-9", "windows-1254"), + + /* Table end */ + LANG_ENCODINGS(NULL, NULL)}; + +static GHashTable *langToEncodings5 = NULL; +static GHashTable *langToEncodings2 = NULL; + +static void +init_lang_to_encodings_hash(void) +{ + struct IsoLangToEncodings *enc; + + if (G_UNLIKELY(langToEncodings5 == NULL)) { + /* Five-letter codes */ + enc = (struct IsoLangToEncodings *) &isoLangEntries5[0]; + langToEncodings5 = g_hash_table_new(nm_str_hash, g_str_equal); + while (enc->lang) { + g_hash_table_insert(langToEncodings5, (gpointer) enc->lang, (gpointer) enc->encodings); + enc++; + } + } + + if (G_UNLIKELY(langToEncodings2 == NULL)) { + /* Two-letter codes */ + enc = (struct IsoLangToEncodings *) &isoLangEntries2[0]; + langToEncodings2 = g_hash_table_new(nm_str_hash, g_str_equal); + while (enc->lang) { + g_hash_table_insert(langToEncodings2, (gpointer) enc->lang, (gpointer) enc->encodings); + enc++; + } + } +} + +static gboolean +get_encodings_for_lang(const char *lang, const char *const **encodings) +{ + gs_free char *tmp_lang = NULL; + + g_return_val_if_fail(lang, FALSE); + g_return_val_if_fail(encodings, FALSE); + + init_lang_to_encodings_hash(); + + if ((*encodings = g_hash_table_lookup(langToEncodings5, lang))) + return TRUE; + + /* Truncate tmp_lang to length of 2 */ + if (strlen(lang) > 2) { + tmp_lang = g_strdup(lang); + tmp_lang[2] = '\0'; + if ((*encodings = g_hash_table_lookup(langToEncodings2, tmp_lang))) + return TRUE; + } + + return FALSE; +} + +static const char *const * +get_system_encodings(void) +{ + static const char *const *cached_encodings; + static char * default_encodings[4]; + const char *const * encodings = NULL; + char * lang; + + if (cached_encodings) + return cached_encodings; + + /* Use environment variables as encoding hint */ + lang = getenv("LC_ALL"); + if (!lang) + lang = getenv("LC_CTYPE"); + if (!lang) + lang = getenv("LANG"); + if (lang) { + char *dot; + + lang = g_ascii_strdown(lang, -1); + if ((dot = strchr(lang, '.'))) + *dot = '\0'; + + get_encodings_for_lang(lang, &encodings); + g_free(lang); + } + if (!encodings) { + g_get_charset((const char **) &default_encodings[0]); + default_encodings[1] = "iso-8859-1"; + default_encodings[2] = "windows-1251"; + default_encodings[3] = NULL; + encodings = (const char *const *) default_encodings; + } + + cached_encodings = encodings; + return cached_encodings; +} + +/*****************************************************************************/ + +static void __attribute__((constructor)) _nm_utils_init(void) +{ + static int initialized = 0; + + if (g_atomic_int_get(&initialized) != 0) + return; + + /* we don't expect this code to run multiple times, nor on multiple threads. + * + * In practice, it would not be a problem if two threads concurrently try to + * run the initialization code below, all code below itself is thread-safe, + * Hence, a poor-man guard "initialized" above is more than sufficient, + * although it does not guarantee that the code is not run concurrently. */ + + bindtextdomain(GETTEXT_PACKAGE, NMLOCALEDIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + + _nm_dbus_errors_init(); + + g_atomic_int_set(&initialized, 1); +} + +/*****************************************************************************/ + +gboolean _nm_utils_is_manager_process; + +/* ssid helpers */ + +/** + * nm_utils_ssid_to_utf8: + * @ssid: (array length=len): pointer to a buffer containing the SSID data + * @len: length of the SSID data in @ssid + * + * Wi-Fi SSIDs are byte arrays, they are _not_ strings. Thus, an SSID may + * contain embedded NULLs and other unprintable characters. Often it is + * useful to print the SSID out for debugging purposes, but that should be the + * _only_ use of this function. Do not use this function for any persistent + * storage of the SSID, since the printable SSID returned from this function + * cannot be converted back into the real SSID of the access point. + * + * This function does almost everything humanly possible to convert the input + * into a printable UTF-8 string, using roughly the following procedure: + * + * 1) if the input data is already UTF-8 safe, no conversion is performed + * 2) attempts to get the current system language from the LANG environment + * variable, and depending on the language, uses a table of alternative + * encodings to try. For example, if LANG=hu_HU, the table may first try + * the ISO-8859-2 encoding, and if that fails, try the Windows-1250 encoding. + * If all fallback encodings fail, replaces non-UTF-8 characters with '?'. + * 3) If the system language was unable to be determined, falls back to the + * ISO-8859-1 encoding, then to the Windows-1251 encoding. + * 4) If step 3 fails, replaces non-UTF-8 characters with '?'. + * + * Again, this function should be used for debugging and display purposes + * _only_. + * + * Returns: (transfer full): an allocated string containing a UTF-8 + * representation of the SSID, which must be freed by the caller using g_free(). + * Returns %NULL on errors. + **/ +char * +nm_utils_ssid_to_utf8(const guint8 *ssid, gsize len) +{ + const char *const *encodings; + const char *const *e; + char * converted = NULL; + + g_return_val_if_fail(ssid != NULL, NULL); + + if (g_utf8_validate((const char *) ssid, len, NULL)) + return g_strndup((const char *) ssid, len); + + encodings = get_system_encodings(); + + for (e = encodings; *e; e++) { + converted = g_convert((const char *) ssid, len, "UTF-8", *e, NULL, NULL, NULL); + if (converted) + break; + } + + if (!converted) { + converted = g_convert_with_fallback((const char *) ssid, + len, + "UTF-8", + encodings[0], + "?", + NULL, + NULL, + NULL); + } + + if (!converted) { + /* If there is still no converted string, the SSID probably + * contains characters not valid in the current locale. Convert + * the string to ASCII instead. + */ + + /* Use the printable range of 0x20-0x7E */ + char *valid_chars = " !\"#$%&'()*+,-./0123456789:;<=>?@" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" + "abcdefghijklmnopqrstuvwxyz{|}~"; + + converted = g_strndup((const char *) ssid, len); + g_strcanon(converted, valid_chars, '?'); + } + + return converted; +} + +char * +_nm_utils_ssid_to_utf8(GBytes *ssid) +{ + const guint8 *p; + gsize l; + + g_return_val_if_fail(ssid, NULL); + + p = g_bytes_get_data(ssid, &l); + return nm_utils_ssid_to_utf8(p, l); +} + +/* Shamelessly ripped from the Linux kernel ieee80211 stack */ +/** + * nm_utils_is_empty_ssid: + * @ssid: (array length=len): pointer to a buffer containing the SSID data + * @len: length of the SSID data in @ssid + * + * Different manufacturers use different mechanisms for not broadcasting the + * AP's SSID. This function attempts to detect blank/empty SSIDs using a + * number of known SSID-cloaking methods. + * + * Returns: %TRUE if the SSID is "empty", %FALSE if it is not + **/ +gboolean +nm_utils_is_empty_ssid(const guint8 *ssid, gsize len) +{ + return _nm_utils_is_empty_ssid_arr(ssid, len); +} + +/** + * nm_utils_escape_ssid: + * @ssid: (array length=len): pointer to a buffer containing the SSID data + * @len: length of the SSID data in @ssid + * + * This function does a quick printable character conversion of the SSID, simply + * replacing embedded NULLs and non-printable characters with the hexadecimal + * representation of that character. Intended for debugging only, should not + * be used for display of SSIDs. + * + * Returns: pointer to the escaped SSID, which uses an internal static buffer + * and will be overwritten by subsequent calls to this function + **/ +const char * +nm_utils_escape_ssid(const guint8 *ssid, gsize len) +{ + static char escaped[NM_IW_ESSID_MAX_SIZE * 2 + 1]; + const guint8 *s = ssid; + char * d = escaped; + + if (nm_utils_is_empty_ssid(ssid, len)) { + memcpy(escaped, "", sizeof("")); + return escaped; + } + + len = MIN(len, (guint32) NM_IW_ESSID_MAX_SIZE); + while (len--) { + if (*s == '\0') { + *d++ = '\\'; + *d++ = '0'; + s++; + } else { + *d++ = *s++; + } + } + *d = '\0'; + return escaped; +} + +/** + * nm_utils_same_ssid: + * @ssid1: (array length=len1): the first SSID to compare + * @len1: length of the SSID data in @ssid1 + * @ssid2: (array length=len2): the second SSID to compare + * @len2: length of the SSID data in @ssid2 + * @ignore_trailing_null: %TRUE to ignore one trailing NULL byte + * + * Earlier versions of the Linux kernel added a NULL byte to the end of the + * SSID to enable easy printing of the SSID on the console or in a terminal, + * but this behavior was problematic (SSIDs are simply byte arrays, not strings) + * and thus was changed. This function compensates for that behavior at the + * cost of some compatibility with odd SSIDs that may legitimately have trailing + * NULLs, even though that is functionally pointless. + * + * Returns: %TRUE if the SSIDs are the same, %FALSE if they are not + **/ +gboolean +nm_utils_same_ssid(const guint8 *ssid1, + gsize len1, + const guint8 *ssid2, + gsize len2, + gboolean ignore_trailing_null) +{ + g_return_val_if_fail(ssid1 != NULL || len1 == 0, FALSE); + g_return_val_if_fail(ssid2 != NULL || len2 == 0, FALSE); + + if (ssid1 == ssid2 && len1 == len2) + return TRUE; + if (!ssid1 || !ssid2) + return FALSE; + + if (ignore_trailing_null) { + if (len1 && ssid1[len1 - 1] == '\0') + len1--; + if (len2 && ssid2[len2 - 1] == '\0') + len2--; + } + + if (len1 != len2) + return FALSE; + + return memcmp(ssid1, ssid2, len1) == 0 ? TRUE : FALSE; +} + +gboolean +_nm_utils_string_slist_validate(GSList *list, const char **valid_values) +{ + GSList *iter; + + for (iter = list; iter; iter = iter->next) { + if (!g_strv_contains(valid_values, (char *) iter->data)) + return FALSE; + } + + return TRUE; +} + +/** + * _nm_utils_hash_values_to_slist: + * @hash: a #GHashTable + * + * Utility function to iterate over a hash table and return + * its values as a #GSList. + * + * Returns: (element-type gpointer) (transfer container): a newly allocated #GSList + * containing the values of the hash table. The caller must free the + * returned list with g_slist_free(). The hash values are not owned + * by the returned list. + **/ +GSList * +_nm_utils_hash_values_to_slist(GHashTable *hash) +{ + GSList * list = NULL; + GHashTableIter iter; + void * value; + + g_return_val_if_fail(hash, NULL); + + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, NULL, &value)) + list = g_slist_prepend(list, value); + + return list; +} + +static GVariant * +_nm_utils_strdict_to_dbus(const GValue *prop_value) +{ + return nm_utils_strdict_to_variant_ass(g_value_get_boxed(prop_value)); +} + +void +_nm_utils_strdict_from_dbus(GVariant *dbus_value, GValue *prop_value) +{ + GVariantIter iter; + const char * key, *value; + GHashTable * hash; + + hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + g_variant_iter_init(&iter, dbus_value); + while (g_variant_iter_next(&iter, "{&s&s}", &key, &value)) + g_hash_table_insert(hash, g_strdup(key), g_strdup(value)); + + g_value_take_boxed(prop_value, hash); +} + +const NMSettInfoPropertType nm_sett_info_propert_type_strdict = { + .dbus_type = NM_G_VARIANT_TYPE("a{ss}"), + .gprop_to_dbus_fcn = _nm_utils_strdict_to_dbus, + .gprop_from_dbus_fcn = _nm_utils_strdict_from_dbus, +}; + +GHashTable * +_nm_utils_copy_strdict(GHashTable *strdict) +{ + GHashTable * copy; + GHashTableIter iter; + gpointer key, value; + + copy = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + if (strdict) { + g_hash_table_iter_init(&iter, strdict); + while (g_hash_table_iter_next(&iter, &key, &value)) + g_hash_table_insert(copy, g_strdup(key), g_strdup(value)); + } + return copy; +} + +GPtrArray * +_nm_utils_copy_array(const GPtrArray *array, NMUtilsCopyFunc copy_func, GDestroyNotify free_func) +{ + GPtrArray *copy; + guint i; + + if (!array) + return g_ptr_array_new_with_free_func(free_func); + + copy = g_ptr_array_new_full(array->len, free_func); + for (i = 0; i < array->len; i++) + g_ptr_array_add(copy, copy_func(array->pdata[i])); + return copy; +} + +GPtrArray * +_nm_utils_copy_object_array(const GPtrArray *array) +{ + return _nm_utils_copy_array(array, g_object_ref, g_object_unref); +} + +void +_nm_utils_bytes_from_dbus(GVariant *dbus_value, GValue *prop_value) +{ + GBytes *bytes; + + if (g_variant_n_children(dbus_value)) { + gconstpointer data; + gsize length; + + data = g_variant_get_fixed_array(dbus_value, &length, 1); + bytes = g_bytes_new(data, length); + } else + bytes = NULL; + g_value_take_boxed(prop_value, bytes); +} + +/*****************************************************************************/ + +GSList * +_nm_utils_strv_to_slist(char **strv, gboolean deep_copy) +{ + GSList *list = NULL; + gsize i; + + if (!strv) + return NULL; + + if (deep_copy) { + for (i = 0; strv[i]; i++) + list = g_slist_prepend(list, g_strdup(strv[i])); + } else { + for (i = 0; strv[i]; i++) + list = g_slist_prepend(list, strv[i]); + } + return g_slist_reverse(list); +} + +char ** +_nm_utils_slist_to_strv(const GSList *slist, gboolean deep_copy) +{ + const GSList *iter; + char ** strv; + guint len, i; + + if (!slist) + return NULL; + + len = g_slist_length((GSList *) slist); + + strv = g_new(char *, len + 1); + + if (deep_copy) { + for (i = 0, iter = slist; iter; iter = iter->next, i++) { + nm_assert(iter->data); + strv[i] = g_strdup(iter->data); + } + } else { + for (i = 0, iter = slist; iter; iter = iter->next, i++) { + nm_assert(iter->data); + strv[i] = iter->data; + } + } + strv[i] = NULL; + + return strv; +} + +GPtrArray * +_nm_utils_strv_to_ptrarray(char **strv) +{ + GPtrArray *ptrarray; + gsize i, l; + + l = NM_PTRARRAY_LEN(strv); + + ptrarray = g_ptr_array_new_full(l, g_free); + + if (strv) { + for (i = 0; strv[i]; i++) + g_ptr_array_add(ptrarray, g_strdup(strv[i])); + } + + return ptrarray; +} + +char ** +_nm_utils_ptrarray_to_strv(const GPtrArray *ptrarray) +{ + char **strv; + guint i; + + if (!ptrarray) + return g_new0(char *, 1); + + strv = g_new(char *, ptrarray->len + 1); + + for (i = 0; i < ptrarray->len; i++) + strv[i] = g_strdup(ptrarray->pdata[i]); + strv[i] = NULL; + + return strv; +} + +/*****************************************************************************/ + +static gboolean +device_supports_ap_ciphers(guint32 dev_caps, guint32 ap_flags, gboolean static_wep) +{ + gboolean have_pair = FALSE; + gboolean have_group = FALSE; + /* Device needs to support at least one pairwise and one group cipher */ + + /* Pairwise */ + if (static_wep) { + /* Static WEP only uses group ciphers */ + have_pair = TRUE; + } else { + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP40) + if (ap_flags & NM_802_11_AP_SEC_PAIR_WEP40) + have_pair = TRUE; + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP104) + if (ap_flags & NM_802_11_AP_SEC_PAIR_WEP104) + have_pair = TRUE; + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP) + if (ap_flags & NM_802_11_AP_SEC_PAIR_TKIP) + have_pair = TRUE; + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP) + if (ap_flags & NM_802_11_AP_SEC_PAIR_CCMP) + have_pair = TRUE; + } + + /* Group */ + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP40) + if (ap_flags & NM_802_11_AP_SEC_GROUP_WEP40) + have_group = TRUE; + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP104) + if (ap_flags & NM_802_11_AP_SEC_GROUP_WEP104) + have_group = TRUE; + if (!static_wep) { + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP) + if (ap_flags & NM_802_11_AP_SEC_GROUP_TKIP) + have_group = TRUE; + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP) + if (ap_flags & NM_802_11_AP_SEC_GROUP_CCMP) + have_group = TRUE; + } + + return (have_pair && have_group); +} + +/** + * nm_utils_ap_mode_security_valid: + * @type: the security type to check device capabilities against, + * e.g. #NMU_SEC_STATIC_WEP + * @wifi_caps: bitfield of the capabilities of the specific Wi-Fi device, e.g. + * #NM_WIFI_DEVICE_CAP_CIPHER_WEP40 + * + * Given a set of device capabilities, and a desired security type to check + * against, determines whether the combination of device capabilities and + * desired security type are valid for AP/Hotspot connections. + * + * Returns: %TRUE if the device capabilities are compatible with the desired + * @type, %FALSE if they are not. + **/ +gboolean +nm_utils_ap_mode_security_valid(NMUtilsSecurityType type, NMDeviceWifiCapabilities wifi_caps) +{ + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_AP)) + return FALSE; + + /* Return TRUE for any security that wpa_supplicant's lightweight AP + * mode can handle: which is open, WEP, and WPA/WPA2 PSK. + */ + switch (type) { + case NMU_SEC_NONE: + case NMU_SEC_STATIC_WEP: + case NMU_SEC_WPA_PSK: + case NMU_SEC_WPA2_PSK: + case NMU_SEC_SAE: + case NMU_SEC_OWE: + return TRUE; + case NMU_SEC_LEAP: + case NMU_SEC_DYNAMIC_WEP: + case NMU_SEC_WPA_ENTERPRISE: + case NMU_SEC_WPA2_ENTERPRISE: + case NMU_SEC_WPA3_SUITE_B_192: + return FALSE; + case NMU_SEC_INVALID: + break; + } + return FALSE; +} + +/** + * nm_utils_security_valid: + * @type: the security type to check AP flags and device capabilities against, + * e.g. #NMU_SEC_STATIC_WEP + * @wifi_caps: bitfield of the capabilities of the specific Wi-Fi device, e.g. + * #NM_WIFI_DEVICE_CAP_CIPHER_WEP40 + * @have_ap: whether the @ap_flags, @ap_wpa, and @ap_rsn arguments are valid + * @adhoc: whether the capabilities being tested are from an Ad-Hoc AP (IBSS) + * @ap_flags: bitfield of AP capabilities, e.g. #NM_802_11_AP_FLAGS_PRIVACY + * @ap_wpa: bitfield of AP capabilities derived from the AP's WPA beacon, + * e.g. (#NM_802_11_AP_SEC_PAIR_TKIP | #NM_802_11_AP_SEC_KEY_MGMT_PSK) + * @ap_rsn: bitfield of AP capabilities derived from the AP's RSN/WPA2 beacon, + * e.g. (#NM_802_11_AP_SEC_PAIR_CCMP | #NM_802_11_AP_SEC_PAIR_TKIP) + * + * Given a set of device capabilities, and a desired security type to check + * against, determines whether the combination of device, desired security + * type, and AP capabilities intersect. + * + * NOTE: this function cannot handle checking security for AP/Hotspot mode; + * use nm_utils_ap_mode_security_valid() instead. + * + * Returns: %TRUE if the device capabilities and AP capabilities intersect and are + * compatible with the desired @type, %FALSE if they are not + **/ +gboolean +nm_utils_security_valid(NMUtilsSecurityType type, + NMDeviceWifiCapabilities wifi_caps, + gboolean have_ap, + gboolean adhoc, + NM80211ApFlags ap_flags, + NM80211ApSecurityFlags ap_wpa, + NM80211ApSecurityFlags ap_rsn) +{ + switch (type) { + case NMU_SEC_NONE: + if (!have_ap) + return TRUE; + if (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) + return FALSE; + if (ap_wpa || ap_rsn) + return FALSE; + return TRUE; + case NMU_SEC_LEAP: /* require PRIVACY bit for LEAP? */ + if (adhoc) + return FALSE; + /* fall-through */ + case NMU_SEC_STATIC_WEP: + if (!have_ap) { + if (wifi_caps & (NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104)) + return TRUE; + return FALSE; + } + if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)) + return FALSE; + if (ap_wpa || ap_rsn) { + if (!device_supports_ap_ciphers(wifi_caps, ap_wpa, TRUE)) { + if (!device_supports_ap_ciphers(wifi_caps, ap_rsn, TRUE)) + return FALSE; + } + } + return TRUE; + case NMU_SEC_DYNAMIC_WEP: + if (adhoc) + return FALSE; + if (!have_ap) { + if (wifi_caps & (NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104)) + return TRUE; + return FALSE; + } + if (ap_rsn || !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)) + return FALSE; + /* Some APs broadcast minimal WPA-enabled beacons that must be handled */ + if (ap_wpa) { + if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + if (!device_supports_ap_ciphers(wifi_caps, ap_wpa, FALSE)) + return FALSE; + } + return TRUE; + case NMU_SEC_WPA_PSK: + if (adhoc) + return FALSE; + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_WPA)) + return FALSE; + if (!have_ap) + return TRUE; + if (ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) { + if ((ap_wpa & NM_802_11_AP_SEC_PAIR_TKIP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) + return TRUE; + if ((ap_wpa & NM_802_11_AP_SEC_PAIR_CCMP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + return TRUE; + } + return FALSE; + case NMU_SEC_WPA2_PSK: + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN)) + return FALSE; + if (!have_ap) + return TRUE; + if (adhoc) { + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_IBSS_RSN)) + return FALSE; + if ((ap_rsn & NM_802_11_AP_SEC_PAIR_CCMP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + return TRUE; + return FALSE; + } + if (ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK) { + if ((ap_rsn & NM_802_11_AP_SEC_PAIR_TKIP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) + return TRUE; + if ((ap_rsn & NM_802_11_AP_SEC_PAIR_CCMP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + return TRUE; + } + return FALSE; + case NMU_SEC_WPA_ENTERPRISE: + if (adhoc) + return FALSE; + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_WPA)) + return FALSE; + if (!have_ap) + return TRUE; + if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + /* Ensure at least one WPA cipher is supported */ + if (!device_supports_ap_ciphers(wifi_caps, ap_wpa, FALSE)) + return FALSE; + return TRUE; + case NMU_SEC_WPA2_ENTERPRISE: + if (adhoc) + return FALSE; + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN)) + return FALSE; + if (!have_ap) + return TRUE; + if (!(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + /* Ensure at least one WPA cipher is supported */ + if (!device_supports_ap_ciphers(wifi_caps, ap_rsn, FALSE)) + return FALSE; + return TRUE; + case NMU_SEC_SAE: + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN)) + return FALSE; + if (adhoc) + return FALSE; + if (!have_ap) + return TRUE; + if (ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_SAE) { + if ((ap_rsn & NM_802_11_AP_SEC_PAIR_CCMP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + return TRUE; + } + return FALSE; + case NMU_SEC_OWE: + if (adhoc) + return FALSE; + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN)) + return FALSE; + if (!have_ap) + return TRUE; + if (!NM_FLAGS_ANY(ap_rsn, NM_802_11_AP_SEC_KEY_MGMT_OWE | NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) + return FALSE; + return TRUE; + case NMU_SEC_WPA3_SUITE_B_192: + if (adhoc) + return FALSE; + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN)) + return FALSE; + if (!have_ap) + return TRUE; + if (ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_EAP_SUITE_B_192) + return TRUE; + return FALSE; + case NMU_SEC_INVALID: + break; + } + + return FALSE; +} + +/** + * nm_utils_wep_key_valid: + * @key: a string that might be a WEP key + * @wep_type: the #NMWepKeyType type of the WEP key + * + * Checks if @key is a valid WEP key + * + * Returns: %TRUE if @key is a WEP key, %FALSE if not + */ +gboolean +nm_utils_wep_key_valid(const char *key, NMWepKeyType wep_type) +{ + gsize keylen; + gsize i; + + if (!key) + return FALSE; + + if (wep_type == NM_WEP_KEY_TYPE_UNKNOWN) { + return nm_utils_wep_key_valid(key, NM_WEP_KEY_TYPE_KEY) + || nm_utils_wep_key_valid(key, NM_WEP_KEY_TYPE_PASSPHRASE); + } + + keylen = strlen(key); + if (wep_type == NM_WEP_KEY_TYPE_KEY) { + if (keylen == 10 || keylen == 26) { + /* Hex key */ + for (i = 0; i < keylen; i++) { + if (!g_ascii_isxdigit(key[i])) + return FALSE; + } + } else if (keylen == 5 || keylen == 13) { + /* ASCII key */ + for (i = 0; i < keylen; i++) { + if (!g_ascii_isprint(key[i])) + return FALSE; + } + } else + return FALSE; + } else if (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE) { + if (!keylen || keylen > 64) + return FALSE; + } + + return TRUE; +} + +/** + * nm_utils_wpa_psk_valid: + * @psk: a string that might be a WPA PSK + * + * Checks if @psk is a valid WPA PSK + * + * Returns: %TRUE if @psk is a WPA PSK, %FALSE if not + */ +gboolean +nm_utils_wpa_psk_valid(const char *psk) +{ + gsize psklen; + gsize i; + + if (!psk) + return FALSE; + + psklen = strlen(psk); + if (psklen < 8 || psklen > 64) + return FALSE; + + if (psklen == 64) { + /* Hex PSK */ + for (i = 0; i < psklen; i++) { + if (!g_ascii_isxdigit(psk[i])) + return FALSE; + } + } + + return TRUE; +} + +/** + * nm_utils_ip4_dns_to_variant: + * @dns: (type utf8): an array of IP address strings + * + * Utility function to convert an array of IP address strings int a #GVariant of + * type 'au' representing an array of IPv4 addresses. + * + * Returns: (transfer none): a new floating #GVariant representing @dns. + **/ +GVariant * +nm_utils_ip4_dns_to_variant(char **dns) +{ + GVariantBuilder builder; + gsize i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("au")); + + if (dns) { + for (i = 0; dns[i]; i++) { + guint32 ip = 0; + + inet_pton(AF_INET, dns[i], &ip); + g_variant_builder_add(&builder, "u", ip); + } + } + + return g_variant_builder_end(&builder); +} + +/** + * nm_utils_ip4_dns_from_variant: + * @value: a #GVariant of type 'au' + * + * Utility function to convert a #GVariant of type 'au' representing a list of + * IPv4 addresses into an array of IP address strings. + * + * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address strings. + **/ +char ** +nm_utils_ip4_dns_from_variant(GVariant *value) +{ + const guint32 *array; + gsize length; + char ** dns; + gsize i; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("au")), NULL); + + array = g_variant_get_fixed_array(value, &length, sizeof(guint32)); + dns = g_new(char *, length + 1u); + for (i = 0; i < length; i++) + dns[i] = nm_utils_inet4_ntop_dup(array[i]); + dns[i] = NULL; + + return dns; +} + +/** + * nm_utils_ip4_addresses_to_variant: + * @addresses: (element-type NMIPAddress): an array of #NMIPAddress objects + * @gateway: (allow-none): the gateway IP address + * + * Utility function to convert a #GPtrArray of #NMIPAddress objects representing + * IPv4 addresses into a #GVariant of type 'aau' representing an array of + * NetworkManager IPv4 addresses (which are tuples of address, prefix, and + * gateway). The "gateway" field of the first address will get the value of + * @gateway (if non-%NULL). In all of the other addresses, that field will be 0. + * + * Returns: (transfer none): a new floating #GVariant representing @addresses. + **/ +GVariant * +nm_utils_ip4_addresses_to_variant(GPtrArray *addresses, const char *gateway) +{ + GVariantBuilder builder; + guint i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aau")); + + if (addresses) { + for (i = 0; i < addresses->len; i++) { + NMIPAddress *addr = addresses->pdata[i]; + guint32 array[3]; + in_addr_t gw; + + if (nm_ip_address_get_family(addr) != AF_INET) + continue; + + gw = 0u; + if (gateway) { + in_addr_t a; + + if (inet_pton(AF_INET, gateway, &a) == 1) + gw = a; + gateway = NULL; + } + + nm_ip_address_get_address_binary(addr, &array[0]); + array[1] = nm_ip_address_get_prefix(addr); + array[2] = gw; + + g_variant_builder_add( + &builder, + "@au", + g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, array, 3, sizeof(guint32))); + } + } + + return g_variant_builder_end(&builder); +} + +/** + * nm_utils_ip4_addresses_from_variant: + * @value: a #GVariant of type 'aau' + * @out_gateway: (out) (allow-none) (transfer full): on return, will contain the IP gateway + * + * Utility function to convert a #GVariant of type 'aau' representing a list of + * NetworkManager IPv4 addresses (which are tuples of address, prefix, and + * gateway) into a #GPtrArray of #NMIPAddress objects. The "gateway" field of + * the first address (if set) will be returned in @out_gateway; the "gateway" fields + * of the other addresses are ignored. + * + * Returns: (transfer full) (element-type NMIPAddress): a newly allocated + * #GPtrArray of #NMIPAddress objects + **/ +GPtrArray * +nm_utils_ip4_addresses_from_variant(GVariant *value, char **out_gateway) +{ + GPtrArray * addresses; + GVariantIter iter; + GVariant * addr_var; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aau")), NULL); + + if (out_gateway) + *out_gateway = NULL; + + g_variant_iter_init(&iter, value); + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + + while (g_variant_iter_next(&iter, "@au", &addr_var)) { + const guint32 *addr_array; + gsize length; + NMIPAddress * addr; + GError * error = NULL; + + addr_array = g_variant_get_fixed_array(addr_var, &length, sizeof(guint32)); + if (length < 3) { + g_warning("Ignoring invalid IP4 address"); + g_variant_unref(addr_var); + continue; + } + + addr = nm_ip_address_new_binary(AF_INET, &addr_array[0], addr_array[1], &error); + if (addr) { + g_ptr_array_add(addresses, addr); + + if (addr_array[2] && out_gateway && !*out_gateway) + *out_gateway = nm_utils_inet4_ntop_dup(addr_array[2]); + } else { + g_warning("Ignoring invalid IP4 address: %s", error->message); + g_clear_error(&error); + } + + g_variant_unref(addr_var); + } + + return addresses; +} + +/** + * nm_utils_ip4_routes_to_variant: + * @routes: (element-type NMIPRoute): an array of #NMIP4Route objects + * + * Utility function to convert a #GPtrArray of #NMIPRoute objects representing + * IPv4 routes into a #GVariant of type 'aau' representing an array of + * NetworkManager IPv4 routes (which are tuples of route, prefix, next hop, and + * metric). + * + * Returns: (transfer none): a new floating #GVariant representing @routes. + **/ +GVariant * +nm_utils_ip4_routes_to_variant(GPtrArray *routes) +{ + GVariantBuilder builder; + guint i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aau")); + + if (routes) { + for (i = 0; i < routes->len; i++) { + NMIPRoute *route = routes->pdata[i]; + guint32 array[4]; + + if (nm_ip_route_get_family(route) != AF_INET) + continue; + + nm_ip_route_get_dest_binary(route, &array[0]); + array[1] = nm_ip_route_get_prefix(route); + nm_ip_route_get_next_hop_binary(route, &array[2]); + /* The old routes format uses "0" for default, not "-1" */ + array[3] = MAX(0, nm_ip_route_get_metric(route)); + + g_variant_builder_add( + &builder, + "@au", + g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, array, 4, sizeof(guint32))); + } + } + + return g_variant_builder_end(&builder); +} + +/** + * nm_utils_ip4_routes_from_variant: + * @value: #GVariant of type 'aau' + * + * Utility function to convert a #GVariant of type 'aau' representing an array + * of NetworkManager IPv4 routes (which are tuples of route, prefix, next hop, + * and metric) into a #GPtrArray of #NMIPRoute objects. + * + * Returns: (transfer full) (element-type NMIPRoute): a newly allocated + * #GPtrArray of #NMIPRoute objects + **/ +GPtrArray * +nm_utils_ip4_routes_from_variant(GVariant *value) +{ + GVariantIter iter; + GVariant * route_var; + GPtrArray * routes; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aau")), NULL); + + g_variant_iter_init(&iter, value); + routes = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); + + while (g_variant_iter_next(&iter, "@au", &route_var)) { + const guint32 *route_array; + gsize length; + NMIPRoute * route; + GError * error = NULL; + + route_array = g_variant_get_fixed_array(route_var, &length, sizeof(guint32)); + if (length < 4) { + g_warning("Ignoring invalid IP4 route"); + g_variant_unref(route_var); + continue; + } + + route = nm_ip_route_new_binary(AF_INET, + &route_array[0], + route_array[1], + &route_array[2], + /* The old routes format uses "0" for default, not "-1" */ + route_array[3] ? (gint64) route_array[3] : -1, + &error); + if (route) + g_ptr_array_add(routes, route); + else { + g_warning("Ignoring invalid IP4 route: %s", error->message); + g_clear_error(&error); + } + g_variant_unref(route_var); + } + + return routes; +} + +/** + * nm_utils_ip4_netmask_to_prefix: + * @netmask: an IPv4 netmask in network byte order + * + * Returns: the CIDR prefix represented by the netmask + **/ +guint32 +nm_utils_ip4_netmask_to_prefix(guint32 netmask) +{ + G_STATIC_ASSERT_EXPR(__SIZEOF_INT__ == 4); + G_STATIC_ASSERT_EXPR(sizeof(int) == 4); + G_STATIC_ASSERT_EXPR(sizeof(netmask) == 4); + + return ((netmask != 0u) ? (guint32)(32 - __builtin_ctz(ntohl(netmask))) : 0u); +} + +/** + * nm_utils_ip4_prefix_to_netmask: + * @prefix: a CIDR prefix + * + * Returns: the netmask represented by the prefix, in network byte order + **/ +guint32 +nm_utils_ip4_prefix_to_netmask(guint32 prefix) +{ + return _nm_utils_ip4_prefix_to_netmask(prefix); +} + +/** + * nm_utils_ip4_get_default_prefix: + * @ip: an IPv4 address (in network byte order) + * + * When the Internet was originally set up, various ranges of IP addresses were + * segmented into three network classes: A, B, and C. This function will return + * a prefix that is associated with the IP address specified defining where it + * falls in the predefined classes. + * + * Returns: the default class prefix for the given IP + **/ +/* The function is originally from ipcalc.c of Red Hat's initscripts. */ +guint32 +nm_utils_ip4_get_default_prefix(guint32 ip) +{ + return _nm_utils_ip4_get_default_prefix(ip); +} + +/** + * nm_utils_ip6_dns_to_variant: + * @dns: (type utf8): an array of IP address strings + * + * Utility function to convert an array of IP address strings int a #GVariant of + * type 'aay' representing an array of IPv6 addresses. + * + * If a string cannot be parsed, it will be silently ignored. + * + * Returns: (transfer none): a new floating #GVariant representing @dns. + **/ +GVariant * +nm_utils_ip6_dns_to_variant(char **dns) +{ + GVariantBuilder builder; + gsize i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aay")); + if (dns) { + for (i = 0; dns[i]; i++) { + struct in6_addr ip; + + if (inet_pton(AF_INET6, dns[i], &ip) != 1) + continue; + g_variant_builder_add(&builder, "@ay", nm_g_variant_new_ay_in6addr(&ip)); + } + } + return g_variant_builder_end(&builder); +} + +/** + * nm_utils_ip6_dns_from_variant: + * @value: a #GVariant of type 'aay' + * + * Utility function to convert a #GVariant of type 'aay' representing a list of + * IPv6 addresses into an array of IP address strings. Each "ay" entry must be + * a IPv6 address in binary form (16 bytes long). Invalid entries are silently + * ignored. + * + * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address strings. + **/ +char ** +nm_utils_ip6_dns_from_variant(GVariant *value) +{ + GVariantIter iter; + GVariant * ip_var; + char ** dns; + gsize i; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aay")), NULL); + + dns = g_new(char *, g_variant_n_children(value) + 1); + + g_variant_iter_init(&iter, value); + i = 0; + while (g_variant_iter_next(&iter, "@ay", &ip_var)) { + gsize length; + const struct in6_addr *ip = g_variant_get_fixed_array(ip_var, &length, 1); + + if (length == sizeof(struct in6_addr)) + dns[i++] = nm_utils_inet6_ntop_dup(ip); + + g_variant_unref(ip_var); + } + dns[i] = NULL; + + return dns; +} + +/** + * nm_utils_ip6_addresses_to_variant: + * @addresses: (element-type NMIPAddress): an array of #NMIPAddress objects + * @gateway: (allow-none): the gateway IP address + * + * Utility function to convert a #GPtrArray of #NMIPAddress objects representing + * IPv6 addresses into a #GVariant of type 'a(ayuay)' representing an array of + * NetworkManager IPv6 addresses (which are tuples of address, prefix, and + * gateway). The "gateway" field of the first address will get the value of + * @gateway (if non-%NULL). In all of the other addresses, that field will be + * all 0s. + * + * Returns: (transfer none): a new floating #GVariant representing @addresses. + **/ +GVariant * +nm_utils_ip6_addresses_to_variant(GPtrArray *addresses, const char *gateway) +{ + GVariantBuilder builder; + guint i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a(ayuay)")); + + if (addresses) { + for (i = 0; i < addresses->len; i++) { + NMIPAddress * addr = addresses->pdata[i]; + struct in6_addr address_bin; + struct in6_addr gateway_bin_data; + const struct in6_addr *gateway_bin; + + if (nm_ip_address_get_family(addr) != AF_INET6) + continue; + + nm_ip_address_get_address_binary(addr, &address_bin); + + gateway_bin = &in6addr_any; + if (gateway) { + if (inet_pton(AF_INET6, gateway, &gateway_bin_data) == 1) + gateway_bin = &gateway_bin_data; + gateway = NULL; + } + + g_variant_builder_add(&builder, + "(@ayu@ay)", + nm_g_variant_new_ay_in6addr(&address_bin), + (guint32) nm_ip_address_get_prefix(addr), + nm_g_variant_new_ay_in6addr(gateway_bin)); + } + } + + return g_variant_builder_end(&builder); +} + +/** + * nm_utils_ip6_addresses_from_variant: + * @value: a #GVariant of type 'a(ayuay)' + * @out_gateway: (out) (allow-none) (transfer full): on return, will contain the IP gateway + * + * Utility function to convert a #GVariant of type 'a(ayuay)' representing a + * list of NetworkManager IPv6 addresses (which are tuples of address, prefix, + * and gateway) into a #GPtrArray of #NMIPAddress objects. The "gateway" field + * of the first address (if set) will be returned in @out_gateway; the "gateway" + * fields of the other addresses are ignored. + * + * Returns: (transfer full) (element-type NMIPAddress): a newly allocated + * #GPtrArray of #NMIPAddress objects + **/ +GPtrArray * +nm_utils_ip6_addresses_from_variant(GVariant *value, char **out_gateway) +{ + GVariantIter iter; + GVariant * addr_var, *gateway_var; + guint32 prefix; + GPtrArray * addresses; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("a(ayuay)")), NULL); + + if (out_gateway) + *out_gateway = NULL; + + g_variant_iter_init(&iter, value); + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + + while (g_variant_iter_next(&iter, "(@ayu@ay)", &addr_var, &prefix, &gateway_var)) { + NMIPAddress * addr; + const struct in6_addr *addr_bytes, *gateway_bytes; + gsize addr_len, gateway_len; + GError * error = NULL; + + if (!g_variant_is_of_type(addr_var, G_VARIANT_TYPE_BYTESTRING) + || !g_variant_is_of_type(gateway_var, G_VARIANT_TYPE_BYTESTRING)) { + g_warning("%s: ignoring invalid IP6 address structure", __func__); + goto next; + } + + addr_bytes = g_variant_get_fixed_array(addr_var, &addr_len, 1); + if (addr_len != 16) { + g_warning("%s: ignoring invalid IP6 address of length %d", __func__, (int) addr_len); + goto next; + } + + addr = nm_ip_address_new_binary(AF_INET6, addr_bytes, prefix, &error); + if (addr) { + g_ptr_array_add(addresses, addr); + + if (out_gateway && !*out_gateway) { + gateway_bytes = g_variant_get_fixed_array(gateway_var, &gateway_len, 1); + if (gateway_len != 16) { + g_warning("%s: ignoring invalid IP6 address of length %d", + __func__, + (int) gateway_len); + goto next; + } + if (!IN6_IS_ADDR_UNSPECIFIED(gateway_bytes)) + *out_gateway = nm_utils_inet6_ntop_dup(gateway_bytes); + } + } else { + g_warning("Ignoring invalid IP6 address: %s", error->message); + g_clear_error(&error); + } + +next: + g_variant_unref(addr_var); + g_variant_unref(gateway_var); + } + + return addresses; +} + +/** + * nm_utils_ip6_routes_to_variant: + * @routes: (element-type NMIPRoute): an array of #NMIPRoute objects + * + * Utility function to convert a #GPtrArray of #NMIPRoute objects representing + * IPv6 routes into a #GVariant of type 'a(ayuayu)' representing an array of + * NetworkManager IPv6 routes (which are tuples of route, prefix, next hop, and + * metric). + * + * Returns: (transfer none): a new floating #GVariant representing @routes. + **/ +GVariant * +nm_utils_ip6_routes_to_variant(GPtrArray *routes) +{ + GVariantBuilder builder; + guint i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a(ayuayu)")); + + if (routes) { + for (i = 0; i < routes->len; i++) { + NMIPRoute * route = routes->pdata[i]; + struct in6_addr dest_bytes; + struct in6_addr next_hop_bytes; + guint32 metric; + + if (nm_ip_route_get_family(route) != AF_INET6) + continue; + + nm_ip_route_get_dest_binary(route, &dest_bytes); + nm_ip_route_get_next_hop_binary(route, &next_hop_bytes); + + /* The old routes format uses "0" for default, not "-1" */ + metric = NM_MAX(0, nm_ip_route_get_metric(route)); + + g_variant_builder_add(&builder, + "(@ayu@ayu)", + nm_g_variant_new_ay_in6addr(&dest_bytes), + (guint32) nm_ip_route_get_prefix(route), + nm_g_variant_new_ay_in6addr(&next_hop_bytes), + metric); + } + } + + return g_variant_builder_end(&builder); +} + +/** + * nm_utils_ip6_routes_from_variant: + * @value: #GVariant of type 'a(ayuayu)' + * + * Utility function to convert a #GVariant of type 'a(ayuayu)' representing an + * array of NetworkManager IPv6 routes (which are tuples of route, prefix, next + * hop, and metric) into a #GPtrArray of #NMIPRoute objects. + * + * Returns: (transfer full) (element-type NMIPRoute): a newly allocated + * #GPtrArray of #NMIPRoute objects + **/ +GPtrArray * +nm_utils_ip6_routes_from_variant(GVariant *value) +{ + GPtrArray * routes; + GVariantIter iter; + GVariant * dest_var, *next_hop_var; + const struct in6_addr *dest, *next_hop; + gsize dest_len, next_hop_len; + guint32 prefix, metric; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("a(ayuayu)")), NULL); + + routes = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); + + g_variant_iter_init(&iter, value); + while (g_variant_iter_next(&iter, "(@ayu@ayu)", &dest_var, &prefix, &next_hop_var, &metric)) { + NMIPRoute *route; + GError * error = NULL; + + if (!g_variant_is_of_type(dest_var, G_VARIANT_TYPE_BYTESTRING) + || !g_variant_is_of_type(next_hop_var, G_VARIANT_TYPE_BYTESTRING)) { + g_warning("%s: ignoring invalid IP6 address structure", __func__); + goto next; + } + + dest = g_variant_get_fixed_array(dest_var, &dest_len, 1); + if (dest_len != 16) { + g_warning("%s: ignoring invalid IP6 address of length %d", __func__, (int) dest_len); + goto next; + } + + next_hop = g_variant_get_fixed_array(next_hop_var, &next_hop_len, 1); + if (next_hop_len != 16) { + g_warning("%s: ignoring invalid IP6 address of length %d", + __func__, + (int) next_hop_len); + goto next; + } + + route = nm_ip_route_new_binary(AF_INET6, + dest, + prefix, + next_hop, + metric ? (gint64) metric : -1, + &error); + if (route) + g_ptr_array_add(routes, route); + else { + g_warning("Ignoring invalid IP6 route: %s", error->message); + g_clear_error(&error); + } + +next: + g_variant_unref(dest_var); + g_variant_unref(next_hop_var); + } + + return routes; +} + +/** + * nm_utils_ip_addresses_to_variant: + * @addresses: (element-type NMIPAddress): an array of #NMIPAddress objects + * + * Utility function to convert a #GPtrArray of #NMIPAddress objects representing + * IPv4 or IPv6 addresses into a #GVariant of type 'aa{sv}' representing an + * array of new-style NetworkManager IP addresses. All addresses will include + * "address" (an IP address string), and "prefix" (a uint). Some addresses may + * include additional attributes. + * + * Returns: (transfer none): a new floating #GVariant representing @addresses. + **/ +GVariant * +nm_utils_ip_addresses_to_variant(GPtrArray *addresses) +{ + GVariantBuilder builder; + guint i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + + if (addresses) { + for (i = 0; i < addresses->len; i++) { + NMIPAddress * addr = addresses->pdata[i]; + GVariantBuilder addr_builder; + gs_free const char **names = NULL; + guint j, len; + + g_variant_builder_init(&addr_builder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(&addr_builder, + "{sv}", + "address", + g_variant_new_string(nm_ip_address_get_address(addr))); + g_variant_builder_add(&addr_builder, + "{sv}", + "prefix", + g_variant_new_uint32(nm_ip_address_get_prefix(addr))); + + names = _nm_ip_address_get_attribute_names(addr, TRUE, &len); + for (j = 0; j < len; j++) { + g_variant_builder_add(&addr_builder, + "{sv}", + names[j], + nm_ip_address_get_attribute(addr, names[j])); + } + + g_variant_builder_add(&builder, "a{sv}", &addr_builder); + } + } + + return g_variant_builder_end(&builder); +} + +/** + * nm_utils_ip_addresses_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * @family: an IP address family + * + * Utility function to convert a #GVariant representing a list of new-style + * NetworkManager IPv4 or IPv6 addresses (as described in the documentation for + * nm_utils_ip_addresses_to_variant()) into a #GPtrArray of #NMIPAddress + * objects. + * + * Returns: (transfer full) (element-type NMIPAddress): a newly allocated + * #GPtrArray of #NMIPAddress objects + **/ +GPtrArray * +nm_utils_ip_addresses_from_variant(GVariant *value, int family) +{ + GPtrArray * addresses; + GVariantIter iter, attrs_iter; + GVariant * addr_var; + const char * ip; + guint32 prefix; + const char * attr_name; + GVariant * attr_val; + NMIPAddress *addr; + GError * error = NULL; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), NULL); + + g_variant_iter_init(&iter, value); + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + + while (g_variant_iter_next(&iter, "@a{sv}", &addr_var)) { + if (!g_variant_lookup(addr_var, "address", "&s", &ip) + || !g_variant_lookup(addr_var, "prefix", "u", &prefix)) { + g_warning("Ignoring invalid address"); + g_variant_unref(addr_var); + continue; + } + + addr = nm_ip_address_new(family, ip, prefix, &error); + if (!addr) { + g_warning("Ignoring invalid address: %s", error->message); + g_clear_error(&error); + g_variant_unref(addr_var); + continue; + } + + g_variant_iter_init(&attrs_iter, addr_var); + while (g_variant_iter_next(&attrs_iter, "{&sv}", &attr_name, &attr_val)) { + if (!NM_IN_STRSET(attr_name, "address", "prefix")) + nm_ip_address_set_attribute(addr, attr_name, attr_val); + g_variant_unref(attr_val); + } + + g_variant_unref(addr_var); + g_ptr_array_add(addresses, addr); + } + + return addresses; +} + +/** + * nm_utils_ip_routes_to_variant: + * @routes: (element-type NMIPRoute): an array of #NMIPRoute objects + * + * Utility function to convert a #GPtrArray of #NMIPRoute objects representing + * IPv4 or IPv6 routes into a #GVariant of type 'aa{sv}' representing an array + * of new-style NetworkManager IP routes (which are tuples of destination, + * prefix, next hop, metric, and additional attributes). + * + * Returns: (transfer none): a new floating #GVariant representing @routes. + **/ +GVariant * +nm_utils_ip_routes_to_variant(GPtrArray *routes) +{ + GVariantBuilder builder; + guint i; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + + if (routes) { + for (i = 0; i < routes->len; i++) { + NMIPRoute * route = routes->pdata[i]; + GVariantBuilder route_builder; + gs_free const char **names = NULL; + guint j, len; + + g_variant_builder_init(&route_builder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(&route_builder, + "{sv}", + "dest", + g_variant_new_string(nm_ip_route_get_dest(route))); + g_variant_builder_add(&route_builder, + "{sv}", + "prefix", + g_variant_new_uint32(nm_ip_route_get_prefix(route))); + if (nm_ip_route_get_next_hop(route)) { + g_variant_builder_add(&route_builder, + "{sv}", + "next-hop", + g_variant_new_string(nm_ip_route_get_next_hop(route))); + } + if (nm_ip_route_get_metric(route) != -1) { + g_variant_builder_add( + &route_builder, + "{sv}", + "metric", + g_variant_new_uint32((guint32) nm_ip_route_get_metric(route))); + } + + names = _nm_ip_route_get_attribute_names(route, TRUE, &len); + for (j = 0; j < len; j++) { + g_variant_builder_add(&route_builder, + "{sv}", + names[j], + nm_ip_route_get_attribute(route, names[j])); + } + + g_variant_builder_add(&builder, "a{sv}", &route_builder); + } + } + + return g_variant_builder_end(&builder); +} + +/** + * nm_utils_ip_routes_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * @family: an IP address family + * + * Utility function to convert a #GVariant representing a list of new-style + * NetworkManager IPv4 or IPv6 addresses (which are tuples of destination, + * prefix, next hop, metric, and additional attributes) into a #GPtrArray of + * #NMIPRoute objects. + * + * Returns: (transfer full) (element-type NMIPRoute): a newly allocated + * #GPtrArray of #NMIPRoute objects + **/ +GPtrArray * +nm_utils_ip_routes_from_variant(GVariant *value, int family) +{ + GPtrArray * routes; + GVariantIter iter, attrs_iter; + GVariant * route_var; + const char * dest, *next_hop; + guint32 prefix, metric32; + gint64 metric; + const char * attr_name; + GVariant * attr_val; + NMIPRoute * route; + GError * error = NULL; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), NULL); + + g_variant_iter_init(&iter, value); + routes = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); + + while (g_variant_iter_next(&iter, "@a{sv}", &route_var)) { + if (!g_variant_lookup(route_var, "dest", "&s", &dest) + || !g_variant_lookup(route_var, "prefix", "u", &prefix)) { + g_warning("Ignoring invalid address"); + goto next; + } + if (!g_variant_lookup(route_var, "next-hop", "&s", &next_hop)) + next_hop = NULL; + if (g_variant_lookup(route_var, "metric", "u", &metric32)) + metric = metric32; + else + metric = -1; + + route = nm_ip_route_new(family, dest, prefix, next_hop, metric, &error); + if (!route) { + g_warning("Ignoring invalid route: %s", error->message); + g_clear_error(&error); + goto next; + } + + g_variant_iter_init(&attrs_iter, route_var); + while (g_variant_iter_next(&attrs_iter, "{&sv}", &attr_name, &attr_val)) { + if (!NM_IN_STRSET(attr_name, "dest", "prefix", "next-hop", "metric")) + nm_ip_route_set_attribute(route, attr_name, attr_val); + g_variant_unref(attr_val); + } + + g_ptr_array_add(routes, route); +next: + g_variant_unref(route_var); + } + + return routes; +} + +/*****************************************************************************/ + +static void +_string_append_tc_handle(GString *string, guint32 handle) +{ + g_string_append_printf(string, "%x:", TC_H_MAJ(handle) >> 16); + if (TC_H_MIN(handle) != TC_H_UNSPEC) + g_string_append_printf(string, "%x", TC_H_MIN(handle)); +} + +/** + * _nm_utils_string_append_tc_parent: + * @string: the string to write the parent handle to + * @prefix: optional prefix for the numeric handle + * @parent: the parent handle + * + * This is used to either write out the parent handle to the tc qdisc string + * or to pretty-format (use symbolic name for root) the key in keyfile. + * The presence of prefix determines which one is the case. + * + * Private API due to general ugliness and overall uselessness for anything + * sensible. + */ +void +_nm_utils_string_append_tc_parent(GString *string, const char *prefix, guint32 parent) +{ + if (parent == TC_H_ROOT) { + g_string_append(string, "root"); + } else { + if (prefix) { + if (parent == TC_H_INGRESS) + return; + g_string_append_printf(string, "%s ", prefix); + } + _string_append_tc_handle(string, parent); + } + + if (prefix) + g_string_append_c(string, ' '); +} + +/** + * _nm_utils_parse_tc_handle: + * @str: the string representation of a qdisc handle + * @error: location of the error + * + * Parses tc style handle number into a numeric representation. + * Don't use this, use nm_utils_tc_qdisc_from_str() instead. + */ +guint32 +_nm_utils_parse_tc_handle(const char *str, GError **error) +{ + gint64 maj; + gint64 min = 0; + const char *sep; + + nm_assert(str); + + maj = nm_g_ascii_strtoll(str, (char **) &sep, 0x10); + if (sep == str) + goto fail; + + sep = nm_str_skip_leading_spaces(sep); + + if (sep[0] == ':') { + const char *str2 = &sep[1]; + + min = nm_g_ascii_strtoll(str2, (char **) &sep, 0x10); + sep = nm_str_skip_leading_spaces(sep); + if (sep[0] != '\0') + goto fail; + } else if (sep[0] != '\0') + goto fail; + + if (maj <= 0 || maj > 0xffff || min < 0 || min > 0xffff + || !NM_STRCHAR_ALL(str, ch, (g_ascii_isxdigit(ch) || ch == ':' || g_ascii_isspace(ch)))) { + goto fail; + } + + return TC_H_MAKE(((guint32) maj) << 16, (guint32) min); +fail: + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("'%s' is not a valid handle."), str); + return TC_H_UNSPEC; +} + +static const NMVariantAttributeSpec *const tc_object_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("root", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("parent", G_VARIANT_TYPE_STRING, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("handle", G_VARIANT_TYPE_STRING, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("kind", G_VARIANT_TYPE_STRING, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("", + G_VARIANT_TYPE_STRING, + .no_value = TRUE, + .consumes_rest = TRUE, ), + NULL, +}; + +static const NMVariantAttributeSpec *const tc_qdisc_sfq_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("quantum", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("perturb", G_VARIANT_TYPE_INT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("limit", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("divisor", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("flows", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("depth", G_VARIANT_TYPE_UINT32, ), + NULL, +}; + +static const NMVariantAttributeSpec *const tc_qdisc_tbf_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("rate", G_VARIANT_TYPE_UINT64, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("burst", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("limit", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("latency", G_VARIANT_TYPE_UINT32, ), + NULL, +}; + +static const NMVariantAttributeSpec *const tc_qdisc_fq_codel_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("limit", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("flows", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("target", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("interval", G_VARIANT_TYPE_UINT32, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("quantum", G_VARIANT_TYPE_UINT32, ), + + /* 0x83126E97u is not a valid value (it means "disabled"). We should reject that + * value. Or alternatively, reject all values >= MAX_INT(32). */ + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("ce_threshold", G_VARIANT_TYPE_UINT32, ), + + /* kernel clamps the value at 2^31. Possibly such values should be rejected from configuration + * as they cannot be configured. Leaving the attribute unspecified causes kernel to choose + * a default (currently 32MB). */ + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("memory_limit", G_VARIANT_TYPE_UINT32, ), + + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("ecn", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NULL, +}; + +typedef struct { + const char * kind; + const NMVariantAttributeSpec *const *attrs; +} NMQdiscAttributeSpec; + +static const NMQdiscAttributeSpec *const tc_qdisc_attribute_spec[] = { + &(const NMQdiscAttributeSpec){"fq_codel", tc_qdisc_fq_codel_spec}, + &(const NMQdiscAttributeSpec){"sfq", tc_qdisc_sfq_spec}, + &(const NMQdiscAttributeSpec){"tbf", tc_qdisc_tbf_spec}, + NULL, +}; + +/*****************************************************************************/ + +/** + * _nm_utils_string_append_tc_qdisc_rest: + * @string: the string to write the formatted qdisc to + * @qdisc: the %NMTCQdisc + * + * This formats the rest of the qdisc string but the parent. Useful to format + * the keyfile value and nowhere else. + * Use nm_utils_tc_qdisc_to_str() that also includes the parent instead. + */ +void +_nm_utils_string_append_tc_qdisc_rest(GString *string, NMTCQdisc *qdisc) +{ + guint32 handle = nm_tc_qdisc_get_handle(qdisc); + const char * kind = nm_tc_qdisc_get_kind(qdisc); + gs_free char *str = NULL; + + if (handle != TC_H_UNSPEC && !NM_IN_STRSET(kind, "ingress", "clsact")) { + g_string_append(string, "handle "); + _string_append_tc_handle(string, handle); + g_string_append_c(string, ' '); + } + + g_string_append(string, kind); + + str = nm_utils_format_variant_attributes(_nm_tc_qdisc_get_attributes(qdisc), ' ', ' '); + if (str) { + g_string_append_c(string, ' '); + g_string_append(string, str); + } +} + +/** + * nm_utils_tc_qdisc_to_str: + * @qdisc: the %NMTCQdisc + * @error: location of the error + * + * Turns the %NMTCQdisc into a tc style string representation of the queueing + * discipline. + * + * Returns: formatted string or %NULL + * + * Since: 1.12 + */ +char * +nm_utils_tc_qdisc_to_str(NMTCQdisc *qdisc, GError **error) +{ + GString *string; + + string = g_string_sized_new(60); + + _nm_utils_string_append_tc_parent(string, "parent", nm_tc_qdisc_get_parent(qdisc)); + _nm_utils_string_append_tc_qdisc_rest(string, qdisc); + + return g_string_free(string, FALSE); +} + +static gboolean +_tc_read_common_opts(const char *str, + guint32 * handle, + guint32 * parent, + char ** kind, + char ** rest, + GError ** error) +{ + gs_unref_hashtable GHashTable *ht = NULL; + GVariant * variant; + + ht = nm_utils_parse_variant_attributes(str, ' ', ' ', FALSE, tc_object_attribute_spec, error); + if (!ht) + return FALSE; + + if (g_hash_table_contains(ht, "root")) + *parent = TC_H_ROOT; + + variant = g_hash_table_lookup(ht, "parent"); + if (variant) { + if (*parent != TC_H_UNSPEC) { + g_set_error(error, + 1, + 0, + _("'%s' unexpected: parent already specified."), + g_variant_get_string(variant, NULL)); + return FALSE; + } + *parent = _nm_utils_parse_tc_handle(g_variant_get_string(variant, NULL), error); + if (*parent == TC_H_UNSPEC) + return FALSE; + } + + variant = g_hash_table_lookup(ht, "handle"); + if (variant) { + *handle = _nm_utils_parse_tc_handle(g_variant_get_string(variant, NULL), error); + if (*handle == TC_H_UNSPEC) + return FALSE; + if (TC_H_MIN(*handle)) { + g_set_error(error, + 1, + 0, + _("invalid handle: '%s'"), + g_variant_get_string(variant, NULL)); + return FALSE; + } + } + + variant = g_hash_table_lookup(ht, "kind"); + if (variant) { + *kind = g_variant_dup_string(variant, NULL); + if (NM_IN_STRSET(*kind, "ingress", "clsact")) { + if (*parent == TC_H_UNSPEC) + *parent = TC_H_INGRESS; + if (*handle == TC_H_UNSPEC) + *handle = TC_H_MAKE(TC_H_INGRESS, 0); + } + } + + if (*parent == TC_H_UNSPEC) { + if (*kind) { + g_free(*kind); + *kind = NULL; + } + g_set_error_literal(error, 1, 0, _("parent not specified.")); + return FALSE; + } + + variant = g_hash_table_lookup(ht, ""); + if (variant) + *rest = g_variant_dup_string(variant, NULL); + + return TRUE; +} + +/** + * nm_utils_tc_qdisc_from_str: + * @str: the string representation of a qdisc + * @error: location of the error + * + * Parses the tc style string qdisc representation of the queueing + * discipline to a %NMTCQdisc instance. Supports a subset of the tc language. + * + * Returns: the %NMTCQdisc or %NULL + * + * Since: 1.12 + */ +NMTCQdisc * +nm_utils_tc_qdisc_from_str(const char *str, GError **error) +{ + guint32 handle = TC_H_UNSPEC; + guint32 parent = TC_H_UNSPEC; + gs_free char * kind = NULL; + gs_free char * rest = NULL; + NMTCQdisc * qdisc = NULL; + gs_unref_hashtable GHashTable *options = NULL; + GHashTableIter iter; + gpointer key, value; + guint i; + + nm_assert(str); + nm_assert(!error || !*error); + + if (!_tc_read_common_opts(str, &handle, &parent, &kind, &rest, error)) + return NULL; + + for (i = 0; rest && tc_qdisc_attribute_spec[i]; i++) { + if (nm_streq(tc_qdisc_attribute_spec[i]->kind, kind)) { + options = nm_utils_parse_variant_attributes(rest, + ' ', + ' ', + FALSE, + tc_qdisc_attribute_spec[i]->attrs, + error); + if (!options) + return NULL; + break; + } + } + nm_clear_g_free(&rest); + + if (options) { + value = g_hash_table_lookup(options, ""); + if (value) + rest = g_variant_dup_string(value, NULL); + } + + if (rest) { + g_set_error(error, 1, 0, _("unsupported qdisc option: '%s'."), rest); + return NULL; + } + + qdisc = nm_tc_qdisc_new(kind, parent, error); + if (!qdisc) + return NULL; + + nm_tc_qdisc_set_handle(qdisc, handle); + + if (options) { + g_hash_table_iter_init(&iter, options); + while (g_hash_table_iter_next(&iter, &key, &value)) + nm_tc_qdisc_set_attribute(qdisc, key, g_variant_ref_sink(value)); + } + + return qdisc; +} + +/*****************************************************************************/ + +static const NMVariantAttributeSpec *const tc_action_simple_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("sdata", G_VARIANT_TYPE_BYTESTRING, ), + NULL, +}; + +static const NMVariantAttributeSpec *const tc_action_mirred_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("egress", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("ingress", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("mirror", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("redirect", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("dev", G_VARIANT_TYPE_STRING, ), + NULL, +}; + +static const NMVariantAttributeSpec *const tc_action_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("kind", G_VARIANT_TYPE_STRING, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("", + G_VARIANT_TYPE_STRING, + .no_value = TRUE, + .consumes_rest = TRUE, ), + NULL, +}; + +static gboolean +_string_append_tc_action(GString *string, NMTCAction *action, GError **error) +{ + const char * kind = nm_tc_action_get_kind(action); + gs_free char * str = NULL; + const NMVariantAttributeSpec *const *attrs; + + if (nm_streq(kind, "simple")) + attrs = tc_action_simple_attribute_spec; + else if (nm_streq(kind, "mirred")) + attrs = tc_action_mirred_attribute_spec; + else + attrs = NULL; + + g_string_append(string, kind); + + str = + _nm_utils_format_variant_attributes(_nm_tc_action_get_attributes(action), attrs, ' ', ' '); + if (str) { + g_string_append_c(string, ' '); + g_string_append(string, str); + } + + return TRUE; +} + +/** + * nm_utils_tc_action_to_str: + * @action: the %NMTCAction + * @error: location of the error + * + * Turns the %NMTCAction into a tc style string representation of the queueing + * discipline. + * + * Returns: formatted string or %NULL + * + * Since: 1.12 + */ +char * +nm_utils_tc_action_to_str(NMTCAction *action, GError **error) +{ + GString *string; + + string = g_string_sized_new(60); + if (!_string_append_tc_action(string, action, error)) { + g_string_free(string, TRUE); + return NULL; + } + + return g_string_free(string, FALSE); +} + +/** + * nm_utils_tc_action_from_str: + * @str: the string representation of a action + * @error: location of the error + * + * Parses the tc style string action representation of the queueing + * discipline to a %NMTCAction instance. Supports a subset of the tc language. + * + * Returns: the %NMTCAction or %NULL + * + * Since: 1.12 + */ +NMTCAction * +nm_utils_tc_action_from_str(const char *str, GError **error) +{ + const char * kind = NULL; + const char * rest = NULL; + NMTCAction * action = NULL; + gs_unref_hashtable GHashTable *ht = NULL; + gs_unref_hashtable GHashTable * options = NULL; + GVariant * variant; + const NMVariantAttributeSpec *const *attrs; + + nm_assert(str); + nm_assert(!error || !*error); + + ht = nm_utils_parse_variant_attributes(str, ' ', ' ', FALSE, tc_action_attribute_spec, error); + if (!ht) + return FALSE; + + variant = g_hash_table_lookup(ht, "kind"); + if (variant) { + kind = g_variant_get_string(variant, NULL); + } else { + g_set_error_literal(error, 1, 0, _("action name missing.")); + return NULL; + } + + kind = g_variant_get_string(variant, NULL); + if (nm_streq(kind, "simple")) + attrs = tc_action_simple_attribute_spec; + else if (nm_streq(kind, "mirred")) + attrs = tc_action_mirred_attribute_spec; + else + attrs = NULL; + + variant = g_hash_table_lookup(ht, ""); + if (variant) + rest = g_variant_get_string(variant, NULL); + + action = nm_tc_action_new(kind, error); + if (!action) + return NULL; + + if (rest) { + GHashTableIter iter; + gpointer key, value; + + if (!attrs) { + nm_tc_action_unref(action); + g_set_error(error, 1, 0, _("unsupported action option: '%s'."), rest); + return NULL; + } + + options = nm_utils_parse_variant_attributes(rest, ' ', ' ', FALSE, attrs, error); + if (!options) { + nm_tc_action_unref(action); + return NULL; + } + + g_hash_table_iter_init(&iter, options); + while (g_hash_table_iter_next(&iter, &key, &value)) + nm_tc_action_set_attribute(action, key, g_variant_ref_sink(value)); + } + + return action; +} + +/*****************************************************************************/ + +/** + * _nm_utils_string_append_tc_tfilter_rest: + * @string: the string to write the formatted tfilter to + * @tfilter: the %NMTCTfilter + * + * This formats the rest of the tfilter string but the parent. Useful to format + * the keyfile value and nowhere else. + * Use nm_utils_tc_tfilter_to_str() that also includes the parent instead. + */ +gboolean +_nm_utils_string_append_tc_tfilter_rest(GString *string, NMTCTfilter *tfilter, GError **error) +{ + guint32 handle = nm_tc_tfilter_get_handle(tfilter); + const char *kind = nm_tc_tfilter_get_kind(tfilter); + NMTCAction *action; + + if (handle != TC_H_UNSPEC) { + g_string_append(string, "handle "); + _string_append_tc_handle(string, handle); + g_string_append_c(string, ' '); + } + + g_string_append(string, kind); + + action = nm_tc_tfilter_get_action(tfilter); + if (action) { + g_string_append(string, " action "); + if (!_string_append_tc_action(string, action, error)) + return FALSE; + } + + return TRUE; +} + +/** + * nm_utils_tc_tfilter_to_str: + * @tfilter: the %NMTCTfilter + * @error: location of the error + * + * Turns the %NMTCTfilter into a tc style string representation of the queueing + * discipline. + * + * Returns: formatted string or %NULL + * + * Since: 1.12 + */ +char * +nm_utils_tc_tfilter_to_str(NMTCTfilter *tfilter, GError **error) +{ + GString *string; + + string = g_string_sized_new(60); + + _nm_utils_string_append_tc_parent(string, "parent", nm_tc_tfilter_get_parent(tfilter)); + if (!_nm_utils_string_append_tc_tfilter_rest(string, tfilter, error)) { + g_string_free(string, TRUE); + return NULL; + } + + return g_string_free(string, FALSE); +} + +static const NMVariantAttributeSpec *const tc_tfilter_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("action", G_VARIANT_TYPE_BOOLEAN, .no_value = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("", + G_VARIANT_TYPE_STRING, + .no_value = TRUE, + .consumes_rest = TRUE, ), + NULL, +}; + +/** + * nm_utils_tc_tfilter_from_str: + * @str: the string representation of a tfilter + * @error: location of the error + * + * Parses the tc style string tfilter representation of the queueing + * discipline to a %NMTCTfilter instance. Supports a subset of the tc language. + * + * Returns: the %NMTCTfilter or %NULL + * + * Since: 1.12 + */ +NMTCTfilter * +nm_utils_tc_tfilter_from_str(const char *str, GError **error) +{ + guint32 handle = TC_H_UNSPEC; + guint32 parent = TC_H_UNSPEC; + gs_free char * kind = NULL; + gs_free char * rest = NULL; + NMTCAction * action = NULL; + const char * extra_opts = NULL; + NMTCTfilter * tfilter = NULL; + gs_unref_hashtable GHashTable *ht = NULL; + GVariant * variant; + + nm_assert(str); + nm_assert(!error || !*error); + + if (!_tc_read_common_opts(str, &handle, &parent, &kind, &rest, error)) + return NULL; + + if (rest) { + ht = nm_utils_parse_variant_attributes(rest, + ' ', + ' ', + FALSE, + tc_tfilter_attribute_spec, + error); + if (!ht) + return NULL; + + variant = g_hash_table_lookup(ht, ""); + if (variant) + extra_opts = g_variant_get_string(variant, NULL); + + if (g_hash_table_contains(ht, "action")) { + action = nm_utils_tc_action_from_str(extra_opts, error); + if (!action) { + g_prefix_error(error, _("invalid action: ")); + return NULL; + } + } else { + g_set_error(error, 1, 0, _("unsupported tfilter option: '%s'."), rest); + return NULL; + } + } + + tfilter = nm_tc_tfilter_new(kind, parent, error); + if (!tfilter) + return NULL; + + nm_tc_tfilter_set_handle(tfilter, handle); + if (action) { + nm_tc_tfilter_set_action(tfilter, action); + nm_tc_action_unref(action); + } + + return tfilter; +} + +/*****************************************************************************/ + +extern const NMVariantAttributeSpec *const _nm_sriov_vf_attribute_spec[]; + +/** + * nm_utils_sriov_vf_to_str: + * @vf: the %NMSriovVF + * @omit_index: if %TRUE, the VF index will be omitted from output string + * @error: (out) (allow-none): location to store the error on failure + * + * Converts a SR-IOV virtual function object to its string representation. + * + * Returns: a newly allocated string or %NULL on error + * + * Since: 1.14 + */ +char * +nm_utils_sriov_vf_to_str(const NMSriovVF *vf, gboolean omit_index, GError **error) +{ + gs_free NMUtilsNamedValue *values = NULL; + gs_free const char ** names = NULL; + const guint * vlan_ids; + guint num_vlans, num_attrs; + guint i; + GString * str; + + str = g_string_new(""); + if (!omit_index) + g_string_append_printf(str, "%u", nm_sriov_vf_get_index(vf)); + + names = nm_sriov_vf_get_attribute_names(vf); + num_attrs = names ? g_strv_length((char **) names) : 0; + values = g_new0(NMUtilsNamedValue, num_attrs); + + for (i = 0; i < num_attrs; i++) { + values[i].name = names[i]; + values[i].value_ptr = nm_sriov_vf_get_attribute(vf, names[i]); + } + + if (num_attrs > 0) { + if (!omit_index) + g_string_append_c(str, ' '); + _nm_utils_format_variant_attributes_full(str, values, num_attrs, NULL, ' ', '='); + } + + vlan_ids = nm_sriov_vf_get_vlan_ids(vf, &num_vlans); + if (num_vlans != 0) { + g_string_append(str, " vlans"); + for (i = 0; i < num_vlans; i++) { + guint32 qos; + NMSriovVFVlanProtocol protocol; + + qos = nm_sriov_vf_get_vlan_qos(vf, vlan_ids[i]); + protocol = nm_sriov_vf_get_vlan_protocol(vf, vlan_ids[i]); + + g_string_append_c(str, i == 0 ? '=' : ';'); + + g_string_append_printf(str, "%u", vlan_ids[i]); + + if (qos != 0 || protocol != NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q) { + g_string_append_printf(str, + ".%u%s", + (unsigned) qos, + protocol == NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q ? "" : ".ad"); + } + } + } + + return g_string_free(str, FALSE); +} + +gboolean +_nm_sriov_vf_parse_vlans(NMSriovVF *vf, const char *str, GError **error) +{ + gs_free const char **vlans = NULL; + guint i; + + vlans = nm_utils_strsplit_set(str, ";"); + if (!vlans) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "empty VF VLAN"); + return FALSE; + } + + for (i = 0; vlans[i]; i++) { + gs_strfreev char **params = NULL; + guint id = G_MAXUINT; + gint64 qos = -1; + + /* we accept leading/trailing whitespace around vlans[1]. Hence + * the nm_str_skip_leading_spaces() and g_strchomp() below. + * + * However, we don't accept any whitespace inside the specifier. + * Hence the NM_STRCHAR_ALL() checks. */ + + params = g_strsplit(nm_str_skip_leading_spaces(vlans[i]), ".", 3); + if (!params || !params[0] || *params[0] == '\0') { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "empty VF VLAN"); + return FALSE; + } + + if (!params[1]) + g_strchomp(params[0]); + if (NM_STRCHAR_ALL(params[0], ch, ch == 'x' || g_ascii_isdigit(ch))) + id = _nm_utils_ascii_str_to_int64(params[0], 0, 0, 4095, G_MAXUINT); + if (id == G_MAXUINT) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "invalid VF VLAN id '%s'", + params[0]); + return FALSE; + } + if (!nm_sriov_vf_add_vlan(vf, id)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "duplicate VLAN id %u", + id); + return FALSE; + } + + if (!params[1]) + continue; + + if (!params[2]) + g_strchomp(params[1]); + if (NM_STRCHAR_ALL(params[1], ch, ch == 'x' || g_ascii_isdigit(ch))) + qos = _nm_utils_ascii_str_to_int64(params[1], 0, 0, G_MAXUINT32, -1); + if (qos == -1) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "invalid VF VLAN QoS '%s'", + params[1]); + return FALSE; + } + nm_sriov_vf_set_vlan_qos(vf, id, qos); + + if (!params[2]) + continue; + + g_strchomp(params[2]); + + if (nm_streq(params[2], "ad")) + nm_sriov_vf_set_vlan_protocol(vf, id, NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD); + else if (nm_streq(params[2], "q")) + nm_sriov_vf_set_vlan_protocol(vf, id, NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); + else { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "invalid VF VLAN protocol '%s'", + params[2]); + return FALSE; + } + } + + return TRUE; +} + +/** + * nm_utils_sriov_vf_from_str: + * @str: the input string + * @error: (out) (allow-none): location to store the error on failure + * + * Converts a string to a SR-IOV virtual function object. + * + * Returns: (transfer full): the virtual function object + * + * Since: 1.14 + */ +NMSriovVF * +nm_utils_sriov_vf_from_str(const char *str, GError **error) +{ + gs_free char *index_free = NULL; + const char * detail; + + g_return_val_if_fail(str, NULL); + g_return_val_if_fail(!error || !*error, NULL); + + while (*str == ' ') + str++; + + detail = strchr(str, ' '); + if (detail) { + str = nm_strndup_a(200, str, detail - str, &index_free); + detail++; + } + + return _nm_utils_sriov_vf_from_strparts(str, detail, FALSE, error); +} + +NMSriovVF * +_nm_utils_sriov_vf_from_strparts(const char *index, + const char *detail, + gboolean ignore_unknown, + GError ** error) +{ + NMSriovVF * vf; + guint32 n_index; + GHashTableIter iter; + char * key; + GVariant * variant; + gs_unref_hashtable GHashTable *ht = NULL; + + n_index = _nm_utils_ascii_str_to_int64(index, 10, 0, G_MAXUINT32, 0); + if (errno) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + "invalid index"); + return NULL; + } + + vf = nm_sriov_vf_new(n_index); + if (detail) { + ht = nm_utils_parse_variant_attributes(detail, + ' ', + '=', + ignore_unknown, + _nm_sriov_vf_attribute_spec, + error); + if (!ht) { + nm_sriov_vf_unref(vf); + return NULL; + } + + if ((variant = g_hash_table_lookup(ht, "vlans"))) { + if (!_nm_sriov_vf_parse_vlans(vf, g_variant_get_string(variant, NULL), error)) { + nm_sriov_vf_unref(vf); + return NULL; + } + g_hash_table_remove(ht, "vlans"); + } + + g_hash_table_iter_init(&iter, ht); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &variant)) + nm_sriov_vf_set_attribute(vf, key, g_variant_ref_sink(variant)); + } + + return vf; +} + +/*****************************************************************************/ + +NMUuid * +_nm_utils_uuid_parse(const char *str, NMUuid *out_uuid) +{ + nm_assert(str); + nm_assert(out_uuid); + + if (uuid_parse(str, out_uuid->uuid) != 0) + return NULL; + return out_uuid; +} + +char * +_nm_utils_uuid_unparse(const NMUuid *uuid, char *out_str /*[37]*/) +{ + nm_assert(uuid); + + if (!out_str) { + /* for convenience, allow %NULL to indicate that a new + * string should be allocated. */ + out_str = g_malloc(37); + } + uuid_unparse_lower(uuid->uuid, out_str); + return out_str; +} + +NMUuid * +_nm_utils_uuid_generate_random(NMUuid *out_uuid) +{ + nm_assert(out_uuid); + + uuid_generate_random(out_uuid->uuid); + return out_uuid; +} + +gboolean +nm_utils_uuid_is_null(const NMUuid *uuid) +{ + int i; + + if (!uuid) + return TRUE; + + for (i = 0; i < (int) G_N_ELEMENTS(uuid->uuid); i++) { + if (uuid->uuid[i]) + return FALSE; + } + return TRUE; +} + +/** + * nm_utils_uuid_generate_buf_: + * @buf: input buffer, must contain at least 37 bytes + * + * Returns: generates a new random UUID, writes it to @buf and returns @buf. + **/ +char * +nm_utils_uuid_generate_buf_(char *buf) +{ + NMUuid uuid; + + nm_assert(buf); + + _nm_utils_uuid_generate_random(&uuid); + return _nm_utils_uuid_unparse(&uuid, buf); +} + +/** + * nm_utils_uuid_generate: + * + * Returns: a newly allocated UUID suitable for use as the #NMSettingConnection + * object's #NMSettingConnection:id: property. Should be freed with g_free() + **/ +char * +nm_utils_uuid_generate(void) +{ + return nm_utils_uuid_generate_buf_(g_malloc(37)); +} + +/** + * nm_utils_uuid_generate_from_string_bin: + * @uuid: the UUID to update inplace. This function cannot + * fail to succeed. + * @s: a string to use as the seed for the UUID + * @slen: if negative, treat @s as zero terminated C string. + * Otherwise, assume the length as given (and allow @s to be + * non-null terminated or contain '\0'). + * @uuid_type: a type identifier which UUID format to generate. + * @type_args: additional arguments, depending on the uuid_type + * + * For a given @s, this function will always return the same UUID. + * + * Returns: the input @uuid. This function cannot fail. + **/ +NMUuid * +nm_utils_uuid_generate_from_string_bin(NMUuid * uuid, + const char *s, + gssize slen, + int uuid_type, + gpointer type_args) +{ + g_return_val_if_fail(uuid, FALSE); + g_return_val_if_fail(slen == 0 || s, FALSE); + + if (slen < 0) + slen = s ? strlen(s) : 0; + + switch (uuid_type) { + case NM_UTILS_UUID_TYPE_LEGACY: + g_return_val_if_fail(!type_args, NULL); + nm_crypto_md5_hash(NULL, 0, (guint8 *) s, slen, (guint8 *) uuid, sizeof(*uuid)); + break; + case NM_UTILS_UUID_TYPE_VERSION3: + case NM_UTILS_UUID_TYPE_VERSION5: + { + NMUuid ns_uuid = {}; + + if (type_args) { + /* type_args can be a name space UUID. Interpret it as (char *) */ + if (!_nm_utils_uuid_parse(type_args, &ns_uuid)) + g_return_val_if_reached(NULL); + } + + if (uuid_type == NM_UTILS_UUID_TYPE_VERSION3) { + nm_crypto_md5_hash((guint8 *) s, + slen, + (guint8 *) &ns_uuid, + sizeof(ns_uuid), + (guint8 *) uuid, + sizeof(*uuid)); + } else { + nm_auto_free_checksum GChecksum *sum = NULL; + union { + guint8 sha1[NM_UTILS_CHECKSUM_LENGTH_SHA1]; + NMUuid uuid; + } digest; + + sum = g_checksum_new(G_CHECKSUM_SHA1); + g_checksum_update(sum, (guchar *) &ns_uuid, sizeof(ns_uuid)); + g_checksum_update(sum, (guchar *) s, slen); + nm_utils_checksum_get_digest(sum, digest.sha1); + + G_STATIC_ASSERT_EXPR(sizeof(digest.sha1) > sizeof(digest.uuid)); + *uuid = digest.uuid; + } + + uuid->uuid[6] = (uuid->uuid[6] & 0x0F) | (uuid_type << 4); + uuid->uuid[8] = (uuid->uuid[8] & 0x3F) | 0x80; + break; + } + default: + g_return_val_if_reached(NULL); + } + + return uuid; +} + +/** + * nm_utils_uuid_generate_from_string: + * @s: a string to use as the seed for the UUID + * @slen: if negative, treat @s as zero terminated C string. + * Otherwise, assume the length as given (and allow @s to be + * non-null terminated or contain '\0'). + * @uuid_type: a type identifier which UUID format to generate. + * @type_args: additional arguments, depending on the uuid_type + * + * For a given @s, this function will always return the same UUID. + * + * Returns: a newly allocated UUID suitable for use as the #NMSettingConnection + * object's #NMSettingConnection:id: property + **/ +char * +nm_utils_uuid_generate_from_string(const char *s, gssize slen, int uuid_type, gpointer type_args) +{ + NMUuid uuid; + + nm_utils_uuid_generate_from_string_bin(&uuid, s, slen, uuid_type, type_args); + return _nm_utils_uuid_unparse(&uuid, NULL); +} + +/** + * _nm_utils_uuid_generate_from_strings: + * @string1: a variadic list of strings. Must be NULL terminated. + * + * Returns a variant3 UUID based on the concatenated C strings. + * It does not simply concatenate them, but also includes the + * terminating '\0' character. For example "a", "b", gives + * "a\0b\0". + * + * This has the advantage, that the following invocations + * all give different UUIDs: (NULL), (""), ("",""), ("","a"), ("a",""), + * ("aa"), ("aa", ""), ("", "aa"), ... + */ +char * +_nm_utils_uuid_generate_from_strings(const char *string1, ...) +{ + if (!string1) + return nm_utils_uuid_generate_from_string(NULL, + 0, + NM_UTILS_UUID_TYPE_VERSION3, + NM_UTILS_UUID_NS); + + { + nm_auto_str_buf NMStrBuf str = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE); + va_list args; + const char * s; + + nm_str_buf_append_len(&str, string1, strlen(string1) + 1u); + + va_start(args, string1); + s = va_arg(args, const char *); + while (s) { + nm_str_buf_append_len(&str, s, strlen(s) + 1u); + s = va_arg(args, const char *); + } + va_end(args); + + return nm_utils_uuid_generate_from_string(nm_str_buf_get_str_unsafe(&str), + str.len, + NM_UTILS_UUID_TYPE_VERSION3, + NM_UTILS_UUID_NS); + } +} + +/*****************************************************************************/ + +static gboolean +file_has_extension(const char *filename, const char *extensions[]) +{ + const char *ext; + gsize i; + + ext = strrchr(filename, '.'); + if (!ext) + return FALSE; + + for (i = 0; extensions[i]; i++) { + if (!g_ascii_strcasecmp(ext, extensions[i])) + return TRUE; + } + + return FALSE; +} + +/** + * nm_utils_file_is_certificate: + * @filename: name of the file to test + * + * Tests if @filename has a valid extension for an X.509 certificate file + * (".cer", ".crt", ".der", or ".pem"), and contains a certificate in a format + * recognized by NetworkManager. + * + * Returns: %TRUE if the file is a certificate, %FALSE if it is not + **/ +gboolean +nm_utils_file_is_certificate(const char *filename) +{ + const char * extensions[] = {".der", ".pem", ".crt", ".cer", NULL}; + NMCryptoFileFormat file_format; + + g_return_val_if_fail(filename != NULL, FALSE); + + if (!file_has_extension(filename, extensions)) + return FALSE; + + if (!nm_crypto_load_and_verify_certificate(filename, &file_format, NULL, NULL)) + return FALSE; + return file_format = NM_CRYPTO_FILE_FORMAT_X509; +} + +/** + * nm_utils_file_is_private_key: + * @filename: name of the file to test + * @out_encrypted: (out): on return, whether the file is encrypted + * + * Tests if @filename has a valid extension for an X.509 private key file + * (".der", ".key", ".pem", or ".p12"), and contains a private key in a format + * recognized by NetworkManager. + * + * Returns: %TRUE if the file is a private key, %FALSE if it is not + **/ +gboolean +nm_utils_file_is_private_key(const char *filename, gboolean *out_encrypted) +{ + const char *extensions[] = {".der", ".pem", ".p12", ".key", NULL}; + + g_return_val_if_fail(filename != NULL, FALSE); + + NM_SET_OUT(out_encrypted, FALSE); + if (!file_has_extension(filename, extensions)) + return FALSE; + + return nm_crypto_verify_private_key(filename, NULL, out_encrypted, NULL) + != NM_CRYPTO_FILE_FORMAT_UNKNOWN; +} + +/** + * nm_utils_file_is_pkcs12: + * @filename: name of the file to test + * + * Tests if @filename is a PKCS#12 file. + * + * Returns: %TRUE if the file is PKCS#12, %FALSE if it is not + **/ +gboolean +nm_utils_file_is_pkcs12(const char *filename) +{ + g_return_val_if_fail(filename != NULL, FALSE); + + return nm_crypto_is_pkcs12_file(filename, NULL); +} + +/*****************************************************************************/ + +gboolean +_nm_utils_check_file(const char * filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + struct stat * out_st, + GError ** error) +{ + struct stat st_backup; + + if (!out_st) + out_st = &st_backup; + + if (stat(filename, out_st) != 0) { + int errsv = errno; + + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("failed stat file %s: %s"), + filename, + nm_strerror_native(errsv)); + return FALSE; + } + + /* ignore non-files. */ + if (!S_ISREG(out_st->st_mode)) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("not a file (%s)"), + filename); + return FALSE; + } + + /* with check_owner enabled, check that the file belongs to the + * owner or root. */ + if (check_owner >= 0 && (out_st->st_uid != 0 && (gint64) out_st->st_uid != check_owner)) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("invalid file owner %d for %s"), + out_st->st_uid, + filename); + return FALSE; + } + + /* with check_owner enabled, check that the file cannot be modified + * by other users (except root). */ + if (check_owner >= 0 && NM_FLAGS_ANY(out_st->st_mode, S_IWGRP | S_IWOTH | S_ISUID)) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("file permissions for %s"), + filename); + return FALSE; + } + + if (check_file && !check_file(filename, out_st, user_data, error)) { + if (error && !*error) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("reject %s"), + filename); + } + return FALSE; + } + + return TRUE; +} + +gboolean +_nm_utils_check_module_file(const char * name, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError ** error) +{ + if (!g_path_is_absolute(name)) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("path is not absolute (%s)"), + name); + return FALSE; + } + + /* Set special error code if the file doesn't exist. + * The VPN package might be split into separate packages, + * so it could be correct that the plugin file is missing. + * + * Note that nm-applet checks for this error code to fail + * gracefully. */ + if (!g_file_test(name, G_FILE_TEST_EXISTS)) { + g_set_error(error, + G_FILE_ERROR, + G_FILE_ERROR_NOENT, + _("Plugin file does not exist (%s)"), + name); + return FALSE; + } + + if (!g_file_test(name, G_FILE_TEST_IS_REGULAR)) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("Plugin is not a valid file (%s)"), + name); + return FALSE; + } + + if (g_str_has_suffix(name, ".la")) { + /* g_module_open() treats files that end with .la special. + * We don't want to parse the libtool archive. Just error out. */ + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("libtool archives are not supported (%s)"), + name); + return FALSE; + } + + return _nm_utils_check_file(name, check_owner, check_file, user_data, NULL, error); +} + +/*****************************************************************************/ + +/** + * nm_utils_file_search_in_paths: + * @progname: the helper program name, like "iptables" + * Must be a non-empty string, without path separator (/). + * @try_first: (allow-none): a custom path to try first before searching. + * It is silently ignored if it is empty or not an absolute path. + * @paths: (allow-none): a %NULL terminated list of search paths. + * Can be empty or %NULL, in which case only @try_first is checked. + * @file_test_flags: the flags passed to g_file_test() when searching + * for @progname. Set it to 0 to skip the g_file_test(). + * @predicate: (scope call): if given, pass the file name to this function + * for additional checks. This check is performed after the check for + * @file_test_flags. You cannot omit both @file_test_flags and @predicate. + * @user_data: (closure) (allow-none): user data for @predicate function. + * @error: (allow-none): on failure, set a "not found" error %G_IO_ERROR %G_IO_ERROR_NOT_FOUND. + * + * Searches for a @progname file in a list of search @paths. + * + * Returns: (transfer none): the full path to the helper, if found, or %NULL if not found. + * The returned string is not owned by the caller, but later + * invocations of the function might overwrite it. + */ +const char * +nm_utils_file_search_in_paths(const char * progname, + const char * try_first, + const char *const * paths, + GFileTest file_test_flags, + NMUtilsFileSearchInPathsPredicate predicate, + gpointer user_data, + GError ** error) +{ + g_return_val_if_fail(!error || !*error, NULL); + g_return_val_if_fail(progname && progname[0] && !strchr(progname, '/'), NULL); + g_return_val_if_fail(file_test_flags || predicate, NULL); + + /* Only consider @try_first if it is a valid, absolute path. This makes + * it simpler to pass in a path from configure checks. */ + if (try_first && try_first[0] == '/' + && (file_test_flags == 0 || g_file_test(try_first, file_test_flags)) + && (!predicate || predicate(try_first, user_data))) + return g_intern_string(try_first); + + if (paths && paths[0]) { + nm_auto_str_buf NMStrBuf strbuf = + NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE); + + for (; *paths; paths++) { + const char *path = *paths; + const char *s; + + if (!path[0]) + continue; + + nm_str_buf_reset(&strbuf); + nm_str_buf_append(&strbuf, path); + nm_str_buf_ensure_trailing_c(&strbuf, '/'); + s = nm_str_buf_append0(&strbuf, progname); + + if ((file_test_flags == 0 || g_file_test(s, file_test_flags)) + && (!predicate || predicate(s, user_data))) + return g_intern_string(s); + } + } + + g_set_error(error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Could not find \"%s\" binary"), + progname); + return NULL; +} + +/*****************************************************************************/ + +/* Band, channel/frequency stuff for wireless */ +struct cf_pair { + guint32 chan; + guint32 freq; +}; + +static const struct cf_pair a_table[] = { + /* A band */ + {7, 5035}, {8, 5040}, {9, 5045}, {11, 5055}, {12, 5060}, {16, 5080}, {34, 5170}, + {36, 5180}, {38, 5190}, {40, 5200}, {42, 5210}, {44, 5220}, {46, 5230}, {48, 5240}, + {50, 5250}, {52, 5260}, {56, 5280}, {58, 5290}, {60, 5300}, {64, 5320}, {100, 5500}, + {104, 5520}, {108, 5540}, {112, 5560}, {116, 5580}, {120, 5600}, {124, 5620}, {128, 5640}, + {132, 5660}, {136, 5680}, {140, 5700}, {149, 5745}, {152, 5760}, {153, 5765}, {157, 5785}, + {160, 5800}, {161, 5805}, {165, 5825}, {183, 4915}, {184, 4920}, {185, 4925}, {187, 4935}, + {188, 4945}, {192, 4960}, {196, 4980}, {0, 0}}; + +static const guint a_table_freqs[G_N_ELEMENTS(a_table)] = { + /* A band */ + 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, 5250, 5260, + 5280, 5290, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, + 5760, 5765, 5785, 5800, 5805, 5825, 4915, 4920, 4925, 4935, 4945, 4960, 4980, 0, +}; + +static const struct cf_pair bg_table[] = { + /* B/G band */ + {1, 2412}, + {2, 2417}, + {3, 2422}, + {4, 2427}, + {5, 2432}, + {6, 2437}, + {7, 2442}, + {8, 2447}, + {9, 2452}, + {10, 2457}, + {11, 2462}, + {12, 2467}, + {13, 2472}, + {14, 2484}, + {0, 0}}; + +static const guint bg_table_freqs[G_N_ELEMENTS(bg_table)] = { + /* B/G band */ + 2412, + 2417, + 2422, + 2427, + 2432, + 2437, + 2442, + 2447, + 2452, + 2457, + 2462, + 2467, + 2472, + 2484, + 0, +}; + +/** + * nm_utils_wifi_freq_to_channel: + * @freq: frequency + * + * Utility function to translate a Wi-Fi frequency to its corresponding channel. + * + * Returns: the channel represented by the frequency or 0 + **/ +guint32 +nm_utils_wifi_freq_to_channel(guint32 freq) +{ + int i = 0; + + if (freq > 4900) { + while (a_table[i].freq && (a_table[i].freq != freq)) + i++; + return a_table[i].chan; + } + + while (bg_table[i].freq && (bg_table[i].freq != freq)) + i++; + return bg_table[i].chan; +} + +/** + * nm_utils_wifi_freq_to_band: + * @freq: frequency + * + * Utility function to translate a Wi-Fi frequency to its corresponding band. + * + * Returns: the band containing the frequency or NULL if freq is invalid + **/ +const char * +nm_utils_wifi_freq_to_band(guint32 freq) +{ + if (freq >= 4915 && freq <= 5825) + return "a"; + else if (freq >= 2412 && freq <= 2484) + return "bg"; + + return NULL; +} + +/** + * nm_utils_wifi_channel_to_freq: + * @channel: channel + * @band: frequency band for wireless ("a" or "bg") + * + * Utility function to translate a Wi-Fi channel to its corresponding frequency. + * + * Returns: the frequency represented by the channel of the band, + * or -1 when the freq is invalid, or 0 when the band + * is invalid + **/ +guint32 +nm_utils_wifi_channel_to_freq(guint32 channel, const char *band) +{ + int i; + + g_return_val_if_fail(band, 0); + + if (nm_streq(band, "a")) { + for (i = 0; a_table[i].chan; i++) { + if (a_table[i].chan == channel) + return a_table[i].freq; + } + return ((guint32) -1); + } + + if (nm_streq(band, "bg")) { + for (i = 0; bg_table[i].chan; i++) { + if (bg_table[i].chan == channel) + return bg_table[i].freq; + } + return ((guint32) -1); + } + + return 0; +} + +/** + * nm_utils_wifi_find_next_channel: + * @channel: current channel + * @direction: whether going downward (0 or less) or upward (1 or more) + * @band: frequency band for wireless ("a" or "bg") + * + * Utility function to find out next/previous Wi-Fi channel for a channel. + * + * Returns: the next channel in the specified direction or 0 + **/ +guint32 +nm_utils_wifi_find_next_channel(guint32 channel, int direction, char *band) +{ + size_t a_size = G_N_ELEMENTS(a_table); + size_t bg_size = G_N_ELEMENTS(bg_table); + const struct cf_pair *pair; + + if (nm_streq(band, "a")) { + if (channel < a_table[0].chan) + return a_table[0].chan; + if (channel > a_table[a_size - 2].chan) + return a_table[a_size - 2].chan; + pair = &a_table[0]; + } else if (nm_streq(band, "bg")) { + if (channel < bg_table[0].chan) + return bg_table[0].chan; + if (channel > bg_table[bg_size - 2].chan) + return bg_table[bg_size - 2].chan; + pair = &bg_table[0]; + } else + g_return_val_if_reached(0); + + while (pair->chan) { + if (channel == pair->chan) + return channel; + if ((channel < (pair + 1)->chan) && (channel > pair->chan)) { + if (direction > 0) + return (pair + 1)->chan; + else + return pair->chan; + } + pair++; + } + return 0; +} + +/** + * nm_utils_wifi_is_channel_valid: + * @channel: channel + * @band: frequency band for wireless ("a" or "bg") + * + * Utility function to verify Wi-Fi channel validity. + * + * Returns: %TRUE or %FALSE + **/ +gboolean +nm_utils_wifi_is_channel_valid(guint32 channel, const char *band) +{ + guint32 freq; + + freq = nm_utils_wifi_channel_to_freq(channel, band); + + return !NM_IN_SET(freq, 0u, (guint32) -1); +} + +#define _nm_assert_wifi_freqs(table, table_freqs) \ + G_STMT_START \ + { \ + if (NM_MORE_ASSERT_ONCE(5)) { \ + int i, j; \ + \ + G_STATIC_ASSERT(G_N_ELEMENTS(table) > 0); \ + G_STATIC_ASSERT(G_N_ELEMENTS(table) == G_N_ELEMENTS(table_freqs)); \ + \ + for (i = 0; i < (int) G_N_ELEMENTS(table); i++) { \ + nm_assert((i == G_N_ELEMENTS(table) - 1) == (table[i].chan == 0)); \ + nm_assert((i == G_N_ELEMENTS(table) - 1) == (table[i].freq == 0)); \ + nm_assert(table[i].freq == table_freqs[i]); \ + for (j = 0; j < i; j++) { \ + nm_assert(table[j].chan != table[i].chan); \ + nm_assert(table[j].freq != table[i].freq); \ + } \ + } \ + } \ + } \ + G_STMT_END + +/** + * nm_utils_wifi_2ghz_freqs: + * + * Utility function to return 2.4 GHz Wi-Fi frequencies (802.11bg band). + * + * Returns: zero-terminated array of frequencies numbers (in MHz) + * + * Since: 1.2 + **/ +const guint * +nm_utils_wifi_2ghz_freqs(void) +{ + _nm_assert_wifi_freqs(bg_table, bg_table_freqs); + return bg_table_freqs; +} + +/** + * nm_utils_wifi_5ghz_freqs: + * + * Utility function to return 5 GHz Wi-Fi frequencies (802.11a band). + * + * Returns: zero-terminated array of frequencies numbers (in MHz) + * + * Since: 1.2 + **/ +const guint * +nm_utils_wifi_5ghz_freqs(void) +{ + _nm_assert_wifi_freqs(a_table, a_table_freqs); + return a_table_freqs; +} + +/** + * nm_utils_wifi_strength_bars: + * @strength: the access point strength, from 0 to 100 + * + * Converts @strength into a 4-character-wide graphical representation of + * strength suitable for printing to stdout. + * + * Previous versions used to take a guess at the terminal type and possibly + * return a wide UTF-8 encoded string. Now it always returns a 7-bit + * clean strings of one to 0 to 4 asterisks. Users that actually need + * the functionality are encouraged to make their implementations instead. + * + * Returns: the graphical representation of the access point strength + */ +const char * +nm_utils_wifi_strength_bars(guint8 strength) +{ + if (strength > 80) + return "****"; + else if (strength > 55) + return "*** "; + else if (strength > 30) + return "** "; + else if (strength > 5) + return "* "; + else + return " "; +} + +/** + * nm_utils_hwaddr_len: + * @type: the type of address; either ARPHRD_ETHER or + * ARPHRD_INFINIBAND + * + * Returns the length in octets of a hardware address of type @type. + * + * Before 1.28, it was an error to call this function with any value other than + * ARPHRD_ETHER or ARPHRD_INFINIBAND. + * + * Return value: the length or zero if the type is unrecognized. + */ +gsize +nm_utils_hwaddr_len(int type) +{ + switch (type) { + case ARPHRD_ETHER: + return ETH_ALEN; + case ARPHRD_INFINIBAND: + return INFINIBAND_ALEN; + default: + return 0; + } +} + +/** + * nm_utils_hexstr2bin: + * @hex: a string of hexadecimal characters with optional ':' separators + * + * Converts a hexadecimal string @hex into an array of bytes. The optional + * separator ':' may be used between single or pairs of hexadecimal characters, + * eg "00:11" or "0:1". Any "0x" at the beginning of @hex is ignored. @hex + * may not start or end with ':'. + * + * Return value: (transfer full): the converted bytes, or %NULL on error + */ +GBytes * +nm_utils_hexstr2bin(const char *hex) +{ + guint8 *buffer; + gsize len; + + buffer = nm_utils_hexstr2bin_alloc(hex, TRUE, FALSE, ":", 0, &len); + if (!buffer) + return NULL; + buffer = g_realloc(buffer, len); + return g_bytes_new_take(buffer, len); +} + +/** + * nm_utils_hwaddr_atoba: + * @asc: the ASCII representation of a hardware address + * @length: the expected length in bytes of the result + * + * Parses @asc and converts it to binary form in a #GByteArray. See + * nm_utils_hwaddr_aton() if you don't want a #GByteArray. + * + * Return value: (transfer full): a new #GByteArray, or %NULL if @asc couldn't + * be parsed + */ +GByteArray * +nm_utils_hwaddr_atoba(const char *asc, gsize length) +{ + GByteArray *ba; + + g_return_val_if_fail(asc, NULL); + g_return_val_if_fail(length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX, NULL); + + ba = g_byte_array_sized_new(length); + g_byte_array_set_size(ba, length); + if (!_nm_utils_hwaddr_aton_exact(asc, ba->data, length)) + goto fail; + + return ba; +fail: + g_byte_array_unref(ba); + return NULL; +} + +/** + * nm_utils_hwaddr_aton: + * @asc: the ASCII representation of a hardware address + * @buffer: (type guint8) (array length=length): buffer to store the result into + * @length: the expected length in bytes of the result and + * the size of the buffer in bytes. + * + * Parses @asc and converts it to binary form in @buffer. + * Bytes in @asc can be separated by colons (:), or hyphens (-), but not mixed. + * + * Return value: @buffer, or %NULL if @asc couldn't be parsed + * or would be shorter or longer than @length. + */ +guint8 * +nm_utils_hwaddr_aton(const char *asc, gpointer buffer, gsize length) +{ + g_return_val_if_fail(asc, NULL); + g_return_val_if_fail(buffer, NULL); + g_return_val_if_fail(length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX, NULL); + + return _nm_utils_hwaddr_aton_exact(asc, buffer, length); +} + +/** + * nm_utils_bin2hexstr: + * @src: (type guint8) (array length=len): an array of bytes + * @len: the length of the @src array + * @final_len: an index where to cut off the returned string, or -1 + * + * Converts the byte array @src into a hexadecimal string. If @final_len is + * greater than -1, the returned string is terminated at that index + * (returned_string[final_len] == '\0'), + * + * Return value: (transfer full): the textual form of @bytes + */ +char * +nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len) +{ + char *result; + gsize buflen = (len * 2) + 1; + + g_return_val_if_fail(src != NULL, NULL); + g_return_val_if_fail(len > 0 && (buflen - 1) / 2 == len, NULL); + g_return_val_if_fail(final_len < 0 || (gsize) final_len < buflen, NULL); + + result = g_malloc(buflen); + + nm_utils_bin2hexstr_full(src, len, '\0', FALSE, result); + + /* Cut converted key off at the correct length for this cipher type */ + if (final_len >= 0 && (gsize) final_len < buflen) + result[final_len] = '\0'; + + return result; +} + +/** + * nm_utils_hwaddr_ntoa: + * @addr: (type guint8) (array length=length): a binary hardware address + * @length: the length of @addr + * + * Converts @addr to textual form. + * + * Return value: (transfer full): the textual form of @addr + */ +char * +nm_utils_hwaddr_ntoa(gconstpointer addr, gsize length) +{ + g_return_val_if_fail(addr, g_strdup("")); + g_return_val_if_fail(length > 0, g_strdup("")); + + return nm_utils_bin2hexstr_full(addr, length, ':', TRUE, NULL); +} + +/** + * nm_utils_hwaddr_valid: + * @asc: the ASCII representation of a hardware address + * @length: the length of address that @asc is expected to convert to + * (or -1 to accept any length up to %NM_UTILS_HWADDR_LEN_MAX) + * + * Parses @asc to see if it is a valid hardware address of the given + * length. + * + * Return value: %TRUE if @asc appears to be a valid hardware address + * of the indicated length, %FALSE if not. + */ +gboolean +nm_utils_hwaddr_valid(const char *asc, gssize length) +{ + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + gsize l; + + g_return_val_if_fail(asc != NULL, FALSE); + g_return_val_if_fail(length >= -1 && length <= NM_UTILS_HWADDR_LEN_MAX, FALSE); + + if (length == 0) + return FALSE; + + if (!_nm_utils_hwaddr_aton(asc, buf, sizeof(buf), &l)) + return FALSE; + + return length == -1 || length == (gssize) l; +} + +/** + * nm_utils_hwaddr_canonical: + * @asc: the ASCII representation of a hardware address + * @length: the length of address that @asc is expected to convert to + * (or -1 to accept any length up to %NM_UTILS_HWADDR_LEN_MAX) + * + * Parses @asc to see if it is a valid hardware address of the given + * length, and if so, returns it in canonical form (uppercase, with + * leading 0s as needed, and with colons rather than hyphens). + * + * Return value: (transfer full): the canonicalized address if @asc appears to + * be a valid hardware address of the indicated length, %NULL if not. + */ +char * +nm_utils_hwaddr_canonical(const char *asc, gssize length) +{ + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + gsize l; + + g_return_val_if_fail(asc, NULL); + g_return_val_if_fail(length == -1 || (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX), NULL); + + if (!_nm_utils_hwaddr_aton(asc, buf, sizeof(buf), &l)) + return NULL; + if (length != -1 && length != (gssize) l) + return NULL; + return nm_utils_hwaddr_ntoa(buf, l); +} + +/* This is used to possibly canonicalize values passed to MAC address property + * setters. Unlike nm_utils_hwaddr_canonical(), it accepts %NULL, and if you + * pass it an invalid MAC address, it just returns that string rather than + * returning %NULL (so that we can return a proper error from verify() later). + */ +char * +_nm_utils_hwaddr_canonical_or_invalid(const char *mac, gssize length) +{ + char *canonical; + + if (!mac) + return NULL; + + canonical = nm_utils_hwaddr_canonical(mac, length); + if (canonical) + return canonical; + else + return g_strdup(mac); +} + +/* + * Determine if given Ethernet address is link-local + * + * Return value: %TRUE if @mac is link local + * reserved addr (01:80:c2:00:00:0X) per IEEE 802.1Q 8.6.3 Frame filtering, %FALSE if not. + */ +gboolean +_nm_utils_hwaddr_link_local_valid(const char *mac) +{ + guint8 mac_net[ETH_ALEN]; + static const guint8 eth_reserved_addr_base[] = {0x01, 0x80, 0xc2, 0x00, 0x00}; + + if (!mac) + return FALSE; + + if (!nm_utils_hwaddr_aton(mac, mac_net, ETH_ALEN)) + return FALSE; + + if (memcmp(mac_net, eth_reserved_addr_base, ETH_ALEN - 1) || (mac_net[5] & 0xF0)) + return FALSE; + + if (mac_net[5] == 1 /* 802.3x Pause address */ + || mac_net[5] == 2 /* 802.3ad Slow protocols */ + || mac_net[5] == 3) /* 802.1X PAE address */ + return FALSE; + + return TRUE; +} + +/** + * nm_utils_hwaddr_matches: + * @hwaddr1: (nullable): pointer to a binary or ASCII hardware address, or %NULL + * @hwaddr1_len: size of @hwaddr1, or -1 if @hwaddr1 is ASCII + * @hwaddr2: (nullable): pointer to a binary or ASCII hardware address, or %NULL + * @hwaddr2_len: size of @hwaddr2, or -1 if @hwaddr2 is ASCII + * + * Generalized hardware address comparison function. Tests if @hwaddr1 and + * @hwaddr2 "equal" (or more precisely, "equivalent"), with several advantages + * over a simple memcmp(): + * + * 1. If @hwaddr1_len or @hwaddr2_len is -1, then the corresponding address is + * assumed to be ASCII rather than binary, and will be converted to binary + * before being compared. + * + * 2. If @hwaddr1 or @hwaddr2 is %NULL, it is treated instead as though it was + * a zero-filled buffer @hwaddr1_len or @hwaddr2_len bytes long. + * + * 3. If @hwaddr1 and @hwaddr2 are InfiniBand hardware addresses (that is, if + * they are INFINIBAND_ALEN bytes long in binary form) + * then only the last 8 bytes are compared, since those are the only bytes + * that actually identify the hardware. (The other 12 bytes will change + * depending on the configuration of the InfiniBand fabric that the device + * is connected to.) + * + * If a passed-in ASCII hardware address cannot be parsed, or would parse to an + * address larger than %NM_UTILS_HWADDR_LEN_MAX, then it will silently fail to + * match. (This means that externally-provided address strings do not need to be + * sanity-checked before comparing them against known good addresses; they are + * guaranteed to not match if they are invalid.) + * + * Return value: %TRUE if @hwaddr1 and @hwaddr2 are equivalent, %FALSE if they are + * different (or either of them is invalid). + */ +gboolean +nm_utils_hwaddr_matches(gconstpointer hwaddr1, + gssize hwaddr1_len, + gconstpointer hwaddr2, + gssize hwaddr2_len) +{ + guint8 buf1[NM_UTILS_HWADDR_LEN_MAX], buf2[NM_UTILS_HWADDR_LEN_MAX]; + gsize l; + + if (hwaddr1_len == -1) { + if (hwaddr1 == NULL) { + hwaddr1_len = 0; + } else if (_nm_utils_hwaddr_aton(hwaddr1, buf1, sizeof(buf1), &l)) { + hwaddr1 = buf1; + hwaddr1_len = l; + } else { + g_return_val_if_fail(hwaddr2_len == -1 + || (hwaddr2_len > 0 && hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX), + FALSE); + return FALSE; + } + } else { + g_return_val_if_fail(hwaddr1_len > 0 && hwaddr1_len <= NM_UTILS_HWADDR_LEN_MAX, FALSE); + + if (!hwaddr1) { + memset(buf1, 0, hwaddr1_len); + hwaddr1 = buf1; + } + } + + if (hwaddr2_len == -1) { + if (hwaddr2 == NULL) + l = 0; + else if (!_nm_utils_hwaddr_aton(hwaddr2, buf2, sizeof(buf2), &l)) + return FALSE; + if (l != hwaddr1_len) + return FALSE; + hwaddr2 = buf2; + } else { + g_return_val_if_fail(hwaddr2_len > 0 && hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX, FALSE); + + if (hwaddr2_len != hwaddr1_len) + return FALSE; + + if (!hwaddr2) { + memset(buf2, 0, hwaddr2_len); + hwaddr2 = buf2; + } + } + + if (G_UNLIKELY(hwaddr1_len <= 0 || hwaddr1_len > NM_UTILS_HWADDR_LEN_MAX)) { + /* Only valid addresses can compare equal. In particular, + * addresses that are too long or of zero bytes, never + * compare equal. */ + return FALSE; + } + + if (hwaddr1_len == INFINIBAND_ALEN) { + hwaddr1 = &((guint8 *) hwaddr1)[INFINIBAND_ALEN - 8]; + hwaddr2 = &((guint8 *) hwaddr2)[INFINIBAND_ALEN - 8]; + hwaddr1_len = 8; + } + + return !memcmp(hwaddr1, hwaddr2, hwaddr1_len); +} + +/*****************************************************************************/ + +static GVariant * +_nm_utils_hwaddr_to_dbus_impl(const char *str) +{ + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + gsize len; + + if (!str) + return NULL; + if (!_nm_utils_hwaddr_aton(str, buf, sizeof(buf), &len)) + return NULL; + + return g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, buf, len, 1); +} + +static GVariant * +_nm_utils_hwaddr_cloned_get(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_free char *addr = NULL; + + nm_assert(nm_streq(sett_info->property_infos[property_idx].name, "cloned-mac-address")); + + g_object_get(setting, "cloned-mac-address", &addr, NULL); + return _nm_utils_hwaddr_to_dbus_impl(addr); +} + +static gboolean +_nm_utils_hwaddr_cloned_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + gsize length; + const guint8 *array; + char * str; + + nm_assert(nm_streq0(property, "cloned-mac-address")); + + if (!_nm_setting_use_legacy_property(setting, + connection_dict, + "cloned-mac-address", + "assigned-mac-address")) + return TRUE; + + length = 0; + array = g_variant_get_fixed_array(value, &length, 1); + + if (!length) + return TRUE; + + str = nm_utils_hwaddr_ntoa(array, length); + g_object_set(setting, "cloned-mac-address", str, NULL); + g_free(str); + return TRUE; +} + +static gboolean +_nm_utils_hwaddr_cloned_not_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + NMSettingParseFlags parse_flags, + GError ** error) +{ + nm_assert(nm_streq0(property, "cloned-mac-address")); + return TRUE; +} + +const NMSettInfoPropertType nm_sett_info_propert_type_cloned_mac_address = { + .dbus_type = G_VARIANT_TYPE_BYTESTRING, + .to_dbus_fcn = _nm_utils_hwaddr_cloned_get, + .from_dbus_fcn = _nm_utils_hwaddr_cloned_set, + .missing_from_dbus_fcn = _nm_utils_hwaddr_cloned_not_set, +}; + +static GVariant * +_nm_utils_hwaddr_cloned_data_synth(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_free char *addr = NULL; + + if (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + return NULL; + + nm_assert(nm_streq0(sett_info->property_infos[property_idx].name, "assigned-mac-address")); + + g_object_get(setting, "cloned-mac-address", &addr, NULL); + + /* Before introducing the extended "cloned-mac-address" (and its D-Bus + * field "assigned-mac-address"), libnm's _nm_utils_hwaddr_to_dbus() + * would drop invalid values as it was unable to serialize them. + * + * Now, we would like to send invalid values as "assigned-mac-address" + * over D-Bus and let the server reject them. + * + * However, clients used to set the cloned-mac-address property + * to "" and it just worked as the value was not serialized in + * an ill form. + * + * To preserve that behavior, serialize "" as NULL. + */ + + return addr && addr[0] ? g_variant_new_take_string(g_steal_pointer(&addr)) : NULL; +} + +static gboolean +_nm_utils_hwaddr_cloned_data_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + nm_assert(nm_streq0(property, "assigned-mac-address")); + + if (_nm_setting_use_legacy_property(setting, + connection_dict, + "cloned-mac-address", + "assigned-mac-address")) + return TRUE; + + g_object_set(setting, + "cloned-mac-address", + nm_str_not_empty(g_variant_get_string(value, NULL)), + NULL); + return TRUE; +} + +const NMSettInfoPropertType nm_sett_info_propert_type_assigned_mac_address = { + .dbus_type = G_VARIANT_TYPE_STRING, + .to_dbus_fcn = _nm_utils_hwaddr_cloned_data_synth, + .from_dbus_fcn = _nm_utils_hwaddr_cloned_data_set, +}; + +static GVariant * +_nm_utils_hwaddr_to_dbus(const GValue *prop_value) +{ + return _nm_utils_hwaddr_to_dbus_impl(g_value_get_string(prop_value)); +} + +static void +_nm_utils_hwaddr_from_dbus(GVariant *dbus_value, GValue *prop_value) +{ + gsize length = 0; + const guint8 *array = g_variant_get_fixed_array(dbus_value, &length, 1); + char * str; + + str = length ? nm_utils_hwaddr_ntoa(array, length) : NULL; + g_value_take_string(prop_value, str); +} + +const NMSettInfoPropertType nm_sett_info_propert_type_mac_address = { + .dbus_type = G_VARIANT_TYPE_BYTESTRING, + .gprop_to_dbus_fcn = _nm_utils_hwaddr_to_dbus, + .gprop_from_dbus_fcn = _nm_utils_hwaddr_from_dbus, +}; + +/*****************************************************************************/ + +/* Validate secret-flags. Most settings don't validate them, which is a bug. + * But we possibly cannot enforce a strict validation now. + * + * For new settings, they shall validate the secret-flags strictly. */ +gboolean +_nm_utils_secret_flags_validate(NMSettingSecretFlags secret_flags, + const char * setting_name, + const char * property_name, + NMSettingSecretFlags disallowed_flags, + GError ** error) +{ + if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) + return TRUE; + + if (NM_FLAGS_ANY(secret_flags, ~NM_SETTING_SECRET_FLAG_ALL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unknown secret flags")); + if (setting_name) + g_prefix_error(error, "%s.%s: ", setting_name, property_name); + return FALSE; + } + + if (!nm_utils_is_power_of_two(secret_flags)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("conflicting secret flags")); + if (setting_name) + g_prefix_error(error, "%s.%s: ", setting_name, property_name); + return FALSE; + } + + if (NM_FLAGS_ANY(secret_flags, disallowed_flags)) { + if (NM_FLAGS_HAS(secret_flags, NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("secret flags must not be \"not-required\"")); + if (setting_name) + g_prefix_error(error, "%s.%s: ", setting_name, property_name); + return FALSE; + } + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unsupported secret flags")); + if (setting_name) + g_prefix_error(error, "%s.%s: ", setting_name, property_name); + return FALSE; + } + + return TRUE; +} + +gboolean +_nm_utils_wps_method_validate(NMSettingWirelessSecurityWpsMethod wps_method, + const char * setting_name, + const char * property_name, + gboolean wps_required, + GError ** error) +{ + if (wps_method > NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, "%s.%s: ", setting_name, property_name); + return FALSE; + } + + if (NM_FLAGS_HAS(wps_method, NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DISABLED)) { + if (wps_method != NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DISABLED) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("can't be simultaneously disabled and enabled")); + g_prefix_error(error, "%s.%s: ", setting_name, property_name); + return FALSE; + } + if (wps_required) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPS is required")); + g_prefix_error(error, "%s.%s: ", setting_name, property_name); + return FALSE; + } + } + + return TRUE; +} + +/*****************************************************************************/ + +static char * +_split_word(char *s) +{ + /* takes @s and truncates the string on the first white-space. + * then it returns the first word afterwards (again seeking + * over leading white-space). */ + for (; s[0]; s++) { + if (g_ascii_isspace(s[0])) { + s[0] = '\0'; + s++; + while (g_ascii_isspace(s[0])) + s++; + return s; + } + } + return s; +} + +gboolean +_nm_utils_generate_mac_address_mask_parse(const char * value, + struct ether_addr * out_mask, + struct ether_addr **out_ouis, + gsize * out_ouis_len, + GError ** error) +{ + gs_free char * s_free = NULL; + char * s, *s_next; + struct ether_addr mask; + gs_unref_array GArray *ouis = NULL; + + g_return_val_if_fail(!error || !*error, FALSE); + + if (!value || !*value) { + /* NULL and "" are valid values and both mean the default + * "q */ + if (out_mask) { + memset(out_mask, 0, sizeof(*out_mask)); + out_mask->ether_addr_octet[0] |= 0x02; + } + NM_SET_OUT(out_ouis, NULL); + NM_SET_OUT(out_ouis_len, 0); + return TRUE; + } + + s_free = g_strdup(value); + s = s_free; + + /* skip over leading whitespace */ + while (g_ascii_isspace(s[0])) + s++; + + /* parse the first mask */ + s_next = _split_word(s); + if (!nm_utils_hwaddr_aton(s, &mask, ETH_ALEN)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("not a valid ethernet MAC address for mask at position %lld"), + (long long) (s - s_free)); + return FALSE; + } + + if (s_next[0]) { + ouis = g_array_sized_new(FALSE, FALSE, sizeof(struct ether_addr), 4); + + do { + s = s_next; + s_next = _split_word(s); + + g_array_set_size(ouis, ouis->len + 1); + if (!nm_utils_hwaddr_aton(s, + &g_array_index(ouis, struct ether_addr, ouis->len - 1), + ETH_ALEN)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("not a valid ethernet MAC address #%u at position %lld"), + ouis->len, + (long long) (s - s_free)); + return FALSE; + } + } while (s_next[0]); + } + + NM_SET_OUT(out_mask, mask); + NM_SET_OUT(out_ouis_len, ouis ? ouis->len : 0); + NM_SET_OUT(out_ouis, + ouis ? ((struct ether_addr *) g_array_free(g_steal_pointer(&ouis), FALSE)) : NULL); + return TRUE; +} + +/*****************************************************************************/ + +gboolean +nm_utils_is_valid_iface_name_utf8safe(const char *utf8safe_name) +{ + gs_free gpointer bin_to_free = NULL; + gconstpointer bin; + gsize len; + + g_return_val_if_fail(utf8safe_name, FALSE); + + bin = nm_utils_buf_utf8safe_unescape(utf8safe_name, + NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, + &len, + &bin_to_free); + + if (bin_to_free) { + /* some unescaping happened... */ + + if (len != strlen(bin)) { + /* there are embedded NUL chars. Invalid. */ + return FALSE; + } + } + + return nm_utils_ifname_valid_kernel(bin, NULL); +} + +/** + * nm_utils_is_valid_iface_name: + * @name: (allow-none): Name of interface + * @error: location to store the error occurring, or %NULL to ignore + * + * Validate the network interface name. + * + * This function is a 1:1 copy of the kernel's interface validation + * function in net/core/dev.c. + * + * Returns: %TRUE if interface name is valid, otherwise %FALSE is returned. + * + * Before 1.20, this function did not accept %NULL as @name argument. If you + * want to run against older versions of libnm, don't pass %NULL. + */ +gboolean +nm_utils_is_valid_iface_name(const char *name, GError **error) +{ + g_return_val_if_fail(!error || !*error, FALSE); + + return nm_utils_ifname_valid_kernel(name, error); +} + +/** + * nm_utils_iface_valid_name: + * @name: (allow-none): Name of interface + * + * Validate the network interface name. + * + * Deprecated: 1.6: Use nm_utils_is_valid_iface_name() instead, with better error reporting. + * + * Returns: %TRUE if interface name is valid, otherwise %FALSE is returned. + * + * Before 1.20, this function did not accept %NULL as @name argument. If you + * want to run against older versions of libnm, don't pass %NULL. + */ +gboolean +nm_utils_iface_valid_name(const char *name) +{ + return nm_utils_is_valid_iface_name(name, NULL); +} + +/** + * nm_utils_is_uuid: + * @str: (allow-none): a string that might be a UUID + * + * Checks if @str is a UUID + * + * Returns: %TRUE if @str is a UUID, %FALSE if not + * + * In older versions, nm_utils_is_uuid() did not accept %NULL as @str + * argument. Don't pass %NULL if you run against older versions of libnm. + */ +gboolean +nm_utils_is_uuid(const char *str) +{ + const char *p = str; + int num_dashes = 0; + + if (!p) + return FALSE; + + while (*p) { + if (*p == '-') + num_dashes++; + else if (!g_ascii_isxdigit(*p)) + return FALSE; + p++; + } + + if ((num_dashes == 4) && (p - str == 36)) + return TRUE; + + /* Backwards compat for older configurations */ + if ((num_dashes == 0) && (p - str == 40)) + return TRUE; + + return FALSE; +} + +static _nm_thread_local char _nm_utils_inet_ntop_buffer[NM_UTILS_INET_ADDRSTRLEN]; + +/** + * nm_utils_inet4_ntop: (skip) + * @inaddr: the address that should be converted to string. + * @dst: the destination buffer, it must contain at least + * INET_ADDRSTRLEN or %NM_UTILS_INET_ADDRSTRLEN + * characters. If set to %NULL, it will return a pointer to an internal, static + * buffer (shared with nm_utils_inet6_ntop()). Beware, that the internal + * buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or + * nm_utils_inet6_ntop() that does not provide its own @dst buffer. Since + * 1.28, the internal buffer is thread local and thus thread safe. Before + * it was not thread safe. When in doubt, pass your own + * @dst buffer to avoid these issues. + * + * Wrapper for inet_ntop. + * + * Returns: the input buffer @dst, or a pointer to an + * internal, static buffer. This function cannot fail. + **/ +const char * +nm_utils_inet4_ntop(in_addr_t inaddr, char *dst) +{ + /* relying on the static buffer (by leaving @dst as %NULL) is discouraged. + * Don't do that! + * + * However, still support it to be lenient against mistakes and because + * this is public API of libnm. */ + return _nm_utils_inet4_ntop(inaddr, dst ?: _nm_utils_inet_ntop_buffer); +} + +/** + * nm_utils_inet6_ntop: (skip) + * @in6addr: the address that should be converted to string. + * @dst: the destination buffer, it must contain at least + * INET6_ADDRSTRLEN or %NM_UTILS_INET_ADDRSTRLEN + * characters. If set to %NULL, it will return a pointer to an internal, static + * buffer (shared with nm_utils_inet4_ntop()). Beware, that the internal + * buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or + * nm_utils_inet6_ntop() that does not provide its own @dst buffer. Since + * 1.28, the internal buffer is thread local and thus thread safe. Before + * it was not thread safe. When in doubt, pass your own + * @dst buffer to avoid these issues. + * + * Wrapper for inet_ntop. + * + * Returns: the input buffer @dst, or a pointer to an + * internal, static buffer. %NULL is not allowed as @in6addr, + * otherwise, this function cannot fail. + **/ +const char * +nm_utils_inet6_ntop(const struct in6_addr *in6addr, char *dst) +{ + /* relying on the static buffer (by leaving @dst as %NULL) is discouraged. + * Don't do that! + * + * However, still support it to be lenient against mistakes and because + * this is public API of libnm. */ + g_return_val_if_fail(in6addr, NULL); + return _nm_utils_inet6_ntop(in6addr, dst ?: _nm_utils_inet_ntop_buffer); +} + +/** + * nm_utils_ipaddr_valid: + * @family: AF_INET or AF_INET6, or + * AF_UNSPEC to accept either + * @ip: an IP address + * + * Checks if @ip contains a valid IP address of the given family. + * + * Return value: %TRUE or %FALSE + */ +gboolean +nm_utils_ipaddr_valid(int family, const char *ip) +{ + g_return_val_if_fail(family == AF_INET || family == AF_INET6 || family == AF_UNSPEC, FALSE); + + return nm_utils_ipaddr_is_valid(family, ip); +} + +/** + * _nm_utils_dhcp_duid_valid: + * @duid: the candidate DUID + * + * Checks if @duid string contains either a special duid value ("ll", + * "llt", "lease" or the "stable" variants) or a valid hex DUID. + * + * Return value: %TRUE or %FALSE + */ +gboolean +_nm_utils_dhcp_duid_valid(const char *duid, GBytes **out_duid_bin) +{ + guint8 duid_arr[128 + 2]; + gsize duid_len; + + NM_SET_OUT(out_duid_bin, NULL); + + if (!duid) + return FALSE; + + if (NM_IN_STRSET(duid, "lease", "llt", "ll", "stable-llt", "stable-ll", "stable-uuid")) { + return TRUE; + } + + if (nm_utils_hexstr2bin_full(duid, + FALSE, + FALSE, + FALSE, + ":", + 0, + duid_arr, + sizeof(duid_arr), + &duid_len)) { + /* MAX DUID length is 128 octects + the type code (2 octects). */ + if (duid_len > 2 && duid_len <= (128 + 2)) { + NM_SET_OUT(out_duid_bin, g_bytes_new(duid_arr, duid_len)); + return TRUE; + } + } + + return FALSE; +} + +/** + * nm_utils_check_virtual_device_compatibility: + * @virtual_type: a virtual connection type + * @other_type: a connection type to test against @virtual_type + * + * Determines if a connection of type @virtual_type can (in the + * general case) work with connections of type @other_type. + * + * If @virtual_type is %NM_TYPE_SETTING_VLAN, then this checks if + * @other_type is a valid type for the parent of a VLAN. + * + * If @virtual_type is a "master" type (eg, %NM_TYPE_SETTING_BRIDGE), + * then this checks if @other_type is a valid type for a slave of that + * master. + * + * Note that even if this returns %TRUE it is not guaranteed that + * every connection of type @other_type is + * compatible with @virtual_type; it may depend on the exact + * configuration of the two connections, or on the capabilities of an + * underlying device driver. + * + * Returns: %TRUE or %FALSE + */ +gboolean +nm_utils_check_virtual_device_compatibility(GType virtual_type, GType other_type) +{ + g_return_val_if_fail(_nm_setting_type_get_base_type_priority(virtual_type) + != NM_SETTING_PRIORITY_INVALID, + FALSE); + g_return_val_if_fail(_nm_setting_type_get_base_type_priority(other_type) + != NM_SETTING_PRIORITY_INVALID, + FALSE); + + if (virtual_type == NM_TYPE_SETTING_BOND) { + return (other_type == NM_TYPE_SETTING_INFINIBAND || other_type == NM_TYPE_SETTING_WIRED + || other_type == NM_TYPE_SETTING_BRIDGE || other_type == NM_TYPE_SETTING_BOND + || other_type == NM_TYPE_SETTING_TEAM || other_type == NM_TYPE_SETTING_VLAN); + } else if (virtual_type == NM_TYPE_SETTING_BRIDGE) { + return (other_type == NM_TYPE_SETTING_WIRED || other_type == NM_TYPE_SETTING_BOND + || other_type == NM_TYPE_SETTING_TEAM || other_type == NM_TYPE_SETTING_VLAN); + } else if (virtual_type == NM_TYPE_SETTING_TEAM) { + return (other_type == NM_TYPE_SETTING_WIRED || other_type == NM_TYPE_SETTING_BRIDGE + || other_type == NM_TYPE_SETTING_BOND || other_type == NM_TYPE_SETTING_TEAM + || other_type == NM_TYPE_SETTING_VLAN); + } else if (virtual_type == NM_TYPE_SETTING_VLAN) { + return (other_type == NM_TYPE_SETTING_WIRED || other_type == NM_TYPE_SETTING_WIRELESS + || other_type == NM_TYPE_SETTING_BRIDGE || other_type == NM_TYPE_SETTING_BOND + || other_type == NM_TYPE_SETTING_TEAM || other_type == NM_TYPE_SETTING_VLAN); + } else { + g_warn_if_reached(); + return FALSE; + } +} + +/*****************************************************************************/ + +/** + * nm_utils_bond_mode_int_to_string: + * @mode: bonding mode as a numeric value + * + * Convert bonding mode from integer value to descriptive name. + * See https://www.kernel.org/doc/Documentation/networking/bonding.txt for + * available modes. + * + * Returns: bonding mode string, or NULL on error + * + * Since: 1.2 + */ +const char * +nm_utils_bond_mode_int_to_string(int mode) +{ + return _nm_setting_bond_mode_to_string(mode); +} + +/** + * nm_utils_bond_mode_string_to_int: + * @mode: bonding mode as string + * + * Convert bonding mode from string representation to numeric value. + * See https://www.kernel.org/doc/Documentation/networking/bonding.txt for + * available modes. + * The @mode string can be either a descriptive name or a number (as string). + * + * Returns: numeric bond mode, or -1 on error + * + * Since: 1.2 + */ +int +nm_utils_bond_mode_string_to_int(const char *mode) +{ + return _nm_setting_bond_mode_from_string(mode); +} + +/*****************************************************************************/ + +#define STRSTRDICTKEY_V1_SET 0x01 +#define STRSTRDICTKEY_V2_SET 0x02 +#define STRSTRDICTKEY_ALL_SET 0x03 + +struct _NMUtilsStrStrDictKey { + char type; + char data[1]; +}; + +guint +_nm_utils_strstrdictkey_hash(gconstpointer a) +{ + const NMUtilsStrStrDictKey *k = a; + const char * p; + NMHashState h; + + nm_hash_init(&h, 76642997u); + if (k) { + if (((int) k->type) & ~STRSTRDICTKEY_ALL_SET) + g_return_val_if_reached(0); + + nm_hash_update_val(&h, k->type); + if (k->type & STRSTRDICTKEY_ALL_SET) { + p = strchr(k->data, '\0'); + if (k->type == STRSTRDICTKEY_ALL_SET) { + /* the key contains two strings. Continue... */ + p = strchr(p + 1, '\0'); + } + if (p != k->data) + nm_hash_update(&h, k->data, p - k->data); + } + } + return nm_hash_complete(&h); +} + +gboolean +_nm_utils_strstrdictkey_equal(gconstpointer a, gconstpointer b) +{ + const NMUtilsStrStrDictKey *k1 = a; + const NMUtilsStrStrDictKey *k2 = b; + + if (k1 == k2) + return TRUE; + if (!k1 || !k2) + return FALSE; + + if (k1->type != k2->type) + return FALSE; + + if (k1->type & STRSTRDICTKEY_ALL_SET) { + if (!nm_streq(k1->data, k2->data)) + return FALSE; + + if (k1->type == STRSTRDICTKEY_ALL_SET) { + gsize l = strlen(k1->data) + 1; + + return nm_streq(&k1->data[l], &k2->data[l]); + } + } + + return TRUE; +} + +NMUtilsStrStrDictKey * +_nm_utils_strstrdictkey_create(const char *v1, const char *v2) +{ + char type = 0; + gsize l1 = 0, l2 = 0; + NMUtilsStrStrDictKey *k; + + if (!v1 && !v2) + return g_malloc0(1); + + /* we need to distinguish between ("",NULL) and (NULL,""). + * Thus, in @type we encode which strings we have present + * as not-NULL. */ + if (v1) { + type |= STRSTRDICTKEY_V1_SET; + l1 = strlen(v1) + 1; + } + if (v2) { + type |= STRSTRDICTKEY_V2_SET; + l2 = strlen(v2) + 1; + } + + k = g_malloc(G_STRUCT_OFFSET(NMUtilsStrStrDictKey, data) + l1 + l2); + k->type = type; + if (v1) + memcpy(&k->data[0], v1, l1); + if (v2) + memcpy(&k->data[l1], v2, l2); + + return k; +} + +static gboolean +validate_dns_option(const char * name, + gboolean numeric, + gboolean ipv6, + const NMUtilsDNSOptionDesc *option_descs) +{ + const NMUtilsDNSOptionDesc *desc; + + if (!option_descs) + return !!*name; + + for (desc = option_descs; desc->name; desc++) { + if (nm_streq(name, desc->name) && numeric == desc->numeric && (!desc->ipv6_only || ipv6)) + return TRUE; + } + + return FALSE; +} + +/** + * _nm_utils_dns_option_validate: + * @option: option string + * @out_name: (out) (allow-none): the option name + * @out_value: (out) (allow-none): the option value + * @ipv6: whether the option refers to a IPv6 configuration + * @option_descs: (allow-none): an array of NMUtilsDNSOptionDesc which describes the + * valid options + * + * Parses a DNS option in the form "name" or "name:number" and, if + * @option_descs is not NULL, checks that the option conforms to one + * of the provided descriptors. If @option_descs is NULL @ipv6 is + * not considered. + * + * Returns: %TRUE when the parsing was successful and the option is valid, + * %FALSE otherwise + */ +gboolean +_nm_utils_dns_option_validate(const char * option, + char ** out_name, + long * out_value, + gboolean ipv6, + const NMUtilsDNSOptionDesc *option_descs) +{ + gs_free char *option0_free = NULL; + const char * option0; + const char * option1; + const char * delim; + long option1_num; + + g_return_val_if_fail(option != NULL, FALSE); + + NM_SET_OUT(out_name, NULL); + NM_SET_OUT(out_value, -1); + + if (!option[0]) + return FALSE; + + delim = strchr(option, ':'); + if (!delim) { + if (!validate_dns_option(option, FALSE, ipv6, option_descs)) + return FALSE; + NM_SET_OUT(out_name, g_strdup(option)); + return TRUE; + } + + option1 = &delim[1]; + + if (!option1[0]) + return FALSE; + if (!NM_STRCHAR_ALL(option1, ch, g_ascii_isdigit(ch))) + return FALSE; + + option0 = nm_strndup_a(300, option, delim - option, &option0_free); + + if (!validate_dns_option(option0, TRUE, ipv6, option_descs)) + return FALSE; + + option1_num = _nm_utils_ascii_str_to_int64(option1, 10, 0, G_MAXINT32, -1); + if (option1_num == -1) + return FALSE; + + NM_SET_OUT(out_name, g_steal_pointer(&option0_free) ?: g_strdup(option0)); + NM_SET_OUT(out_value, option1_num); + return TRUE; +} + +/** + * _nm_utils_dns_option_find_idx: + * @array: an array of strings + * @option: a dns option string + * + * Searches for an option in an array of strings. The match is + * performed only the option name; the option value is ignored. + * + * Returns: the index of the option in the array or -1 if was not + * found. + */ +gssize +_nm_utils_dns_option_find_idx(GPtrArray *array, const char *option) +{ + gs_free char *option_name = NULL; + guint i; + + if (!_nm_utils_dns_option_validate(option, &option_name, NULL, FALSE, NULL)) + return -1; + + for (i = 0; i < array->len; i++) { + gs_free char *tmp_name = NULL; + + if (_nm_utils_dns_option_validate(array->pdata[i], &tmp_name, NULL, FALSE, NULL)) { + if (nm_streq(tmp_name, option_name)) + return i; + } + } + + return -1; +} + +/*****************************************************************************/ + +/** + * nm_utils_enum_to_str: + * @type: the %GType of the enum + * @value: the value to be translated + * + * Converts an enum value to its string representation. If the enum is a + * %G_TYPE_FLAGS the function returns a comma-separated list of matching values. + * If the value has no corresponding string representation, it is converted + * to a number. For enums it is converted to a decimal number, for flags + * to an (unsigned) hex number. + * + * Returns: a newly allocated string or %NULL + * + * Since: 1.2 + */ +char * +nm_utils_enum_to_str(GType type, int value) +{ + return _nm_utils_enum_to_str_full(type, value, ", ", NULL); +} + +/** + * nm_utils_enum_from_str: + * @type: the %GType of the enum + * @str: the input string + * @out_value: (out) (allow-none): the output value + * @err_token: (out) (allow-none) (transfer full): location to store the first unrecognized token + * + * Converts a string to the matching enum value. + * + * If the enum is a %G_TYPE_FLAGS the function returns the logical OR of values + * matching the comma-separated tokens in the string; if an unknown token is found + * the function returns %FALSE and stores a pointer to a newly allocated string + * containing the unrecognized token in @err_token. + * + * Returns: %TRUE if the conversion was successful, %FALSE otherwise + * + * Since: 1.2 + */ +gboolean +nm_utils_enum_from_str(GType type, const char *str, int *out_value, char **err_token) +{ + return _nm_utils_enum_from_str_full(type, str, out_value, err_token, NULL); +} + +/** + * nm_utils_enum_get_values: + * @type: the %GType of the enum + * @from: the first element to be returned + * @to: the last element to be returned + * + * Returns the list of possible values for a given enum. + * + * Returns: (transfer container): a NULL-terminated dynamically-allocated array of static strings + * or %NULL on error + * + * Since: 1.2 + */ +const char ** +nm_utils_enum_get_values(GType type, int from, int to) +{ + return _nm_utils_enum_get_values(type, from, to); +} + +/*****************************************************************************/ + +static gboolean +_nm_utils_is_json_object_no_validation(const char *str, GError **error) +{ + nm_assert(str); + + /* libjansson also requires only utf-8 encoding. */ + if (!g_utf8_validate(str, -1, NULL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("not valid utf-8")); + return FALSE; + } + while (g_ascii_isspace(str[0])) + str++; + + /* do some very basic validation to see if this might be a JSON object. */ + if (str[0] == '{') { + gsize l; + + l = strlen(str) - 1; + while (l > 0 && g_ascii_isspace(str[l])) + l--; + + if (str[l] == '}') + return TRUE; + } + + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a JSON object")); + return FALSE; +} + +/** + * nm_utils_is_json_object: + * @str: the JSON string to test + * @error: optional error reason + * + * Returns: whether the passed string is valid JSON. + * If libnm is not compiled with libjansson support, this check will + * also return %TRUE for possibly invalid inputs. If that is a problem + * for you, you must validate the JSON yourself. + * + * Since: 1.6 + */ +gboolean +nm_utils_is_json_object(const char *str, GError **error) +{ + nm_auto_decref_json nm_json_t *json = NULL; + const NMJsonVt * vt; + nm_json_error_t jerror; + + g_return_val_if_fail(!error || !*error, FALSE); + + if (!str || !str[0]) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + str ? _("value is NULL") : _("value is empty")); + return FALSE; + } + + if (!(vt = nm_json_vt())) + return _nm_utils_is_json_object_no_validation(str, error); + + json = vt->nm_json_loads(str, NM_JSON_REJECT_DUPLICATES, &jerror); + if (!json) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid JSON at position %d (%s)"), + jerror.position, + jerror.text); + return FALSE; + } + + /* valid JSON (depending on the definition) can also be a literal. + * Here we only allow objects. */ + if (!nm_json_is_object(json)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a JSON object")); + return FALSE; + } + + return TRUE; +} + +static char * +attribute_unescape(const char *start, const char *end) +{ + char *ret, *dest; + + nm_assert(start <= end); + dest = ret = g_malloc(end - start + 1); + + for (; start < end && *start; start++) { + if (*start == '\\') { + start++; + if (!*start) + break; + } + *dest++ = *start; + } + *dest = '\0'; + + return ret; +} + +gboolean +_nmtst_variant_attribute_spec_assert_sorted(const NMVariantAttributeSpec *const *array, gsize len) +{ + gsize i; + + g_assert(array); + g_assert(len > 0); + g_assert_cmpint(len, ==, NM_PTRARRAY_LEN(array)); + + for (i = 0; i < len; i++) { + nm_assert(array[i]->name); + nm_assert(array[i]->name[0]); + if (i > 0) + nm_assert(strcmp(array[i - 1]->name, array[i]->name) < 0); + } + nm_assert(!array[i]); + + return TRUE; +} + +const NMVariantAttributeSpec * +_nm_variant_attribute_spec_find_binary_search(const NMVariantAttributeSpec *const *array, + gsize len, + const char * name) +{ + gssize idx; + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMVariantAttributeSpec, name) == 0); + + idx = nm_utils_ptrarray_find_binary_search((gconstpointer *) array, + len, + &name, + nm_strcmp_p_with_data, + NULL); + if (idx < 0) + return NULL; + return array[idx]; +} + +/** + * nm_utils_parse_variant_attributes: + * @string: the input string + * @attr_separator: the attribute separator character + * @key_value_separator: character separating key and values + * @ignore_unknown: whether unknown attributes should be ignored + * @spec: the attribute format specifiers + * @error: (out) (allow-none): location to store the error on failure + * + * Parse attributes from a string. + * + * Returns: (transfer full) (element-type utf8 GVariant): a #GHashTable mapping + * attribute names to #GVariant values. Warning: the variant are still floating + * references, owned by the hash table. If you take a reference, ensure to sink + * the one of the hash table first. + * + * Since: 1.8 + */ +GHashTable * +nm_utils_parse_variant_attributes(const char * string, + char attr_separator, + char key_value_separator, + gboolean ignore_unknown, + const NMVariantAttributeSpec *const *spec, + GError ** error) +{ + gs_unref_hashtable GHashTable * ht = NULL; + const char * ptr = string, *start = NULL, *sep; + GVariant * variant; + const NMVariantAttributeSpec *const *s; + + g_return_val_if_fail(string, NULL); + g_return_val_if_fail(attr_separator, NULL); + g_return_val_if_fail(key_value_separator, NULL); + g_return_val_if_fail(!error || !*error, NULL); + + ht = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + + while (TRUE) { + gs_free char *name = NULL, *value = NULL; + + if (!start) + start = ptr; + if (*ptr == '\\') { + ptr++; + if (!*ptr) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("unterminated escape sequence")); + return NULL; + } + goto next; + } + if (*ptr == attr_separator || *ptr == '\0') { + if (ptr == start) { + /* multiple separators */ + start = NULL; + goto next; + } + + /* Find the key-value separator */ + for (sep = start; sep != ptr; sep++) { + if (*sep == '\\') { + sep++; + if (!*sep) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("unterminated escape sequence")); + return NULL; + } + } + if (*sep == key_value_separator) + break; + } + + name = attribute_unescape(start, sep); + + for (s = spec; *s; s++) { + if (g_hash_table_contains(ht, (*s)->name)) + continue; + if (nm_streq(name, (*s)->name)) + break; + if ((*s)->no_value && g_variant_type_equal((*s)->type, G_VARIANT_TYPE_STRING)) + break; + } + + if (!*s) { + if (ignore_unknown) + goto next; + else { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("unknown attribute '%s'"), + name); + return NULL; + } + } + + if ((*s)->no_value) { + if ((*s)->consumes_rest) { + value = g_strdup(start); + ptr = strchr(start, '\0'); + } else { + value = g_steal_pointer(&name); + } + } else { + if (*sep != key_value_separator) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("missing key-value separator '%c' after '%s'"), + key_value_separator, + name); + return NULL; + } + + /* The attribute and key/value separators are the same. Look for the next one. */ + if (ptr == sep) + goto next; + + value = attribute_unescape(sep + 1, ptr); + } + + if (g_variant_type_equal((*s)->type, G_VARIANT_TYPE_UINT32)) { + gint64 num = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT32, -1); + + if (num == -1) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid uint32 value '%s' for attribute '%s'"), + value, + (*s)->name); + return NULL; + } + variant = g_variant_new_uint32(num); + } else if (g_variant_type_equal((*s)->type, G_VARIANT_TYPE_INT32)) { + gint64 num = + _nm_utils_ascii_str_to_int64(value, 10, G_MININT32, G_MAXINT32, G_MAXINT64); + + if (num == G_MAXINT64) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid int32 value '%s' for attribute '%s'"), + value, + (*s)->name); + return NULL; + } + variant = g_variant_new_int32(num); + } else if (g_variant_type_equal((*s)->type, G_VARIANT_TYPE_UINT64)) { + guint64 num = _nm_utils_ascii_str_to_uint64(value, 10, 0, G_MAXUINT64, G_MAXUINT64); + + if (num == G_MAXUINT64 && errno != 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid uint64 value '%s' for attribute '%s'"), + value, + (*s)->name); + return NULL; + } + variant = g_variant_new_uint64(num); + } else if (g_variant_type_equal((*s)->type, G_VARIANT_TYPE_BYTE)) { + gint64 num = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT8, -1); + + if (num == -1) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid uint8 value '%s' for attribute '%s'"), + value, + (*s)->name); + return NULL; + } + variant = g_variant_new_byte((guchar) num); + } else if (g_variant_type_equal((*s)->type, G_VARIANT_TYPE_BOOLEAN)) { + int b; + + b = (*s)->no_value ? TRUE : _nm_utils_ascii_str_to_bool(value, -1); + if (b == -1) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("invalid boolean value '%s' for attribute '%s'"), + value, + (*s)->name); + return NULL; + } + variant = g_variant_new_boolean(b); + } else if (g_variant_type_equal((*s)->type, G_VARIANT_TYPE_STRING)) { + variant = g_variant_new_take_string(g_steal_pointer(&value)); + } else if (g_variant_type_equal((*s)->type, G_VARIANT_TYPE_BYTESTRING)) { + variant = g_variant_new_bytestring(value); + } else { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("unsupported attribute '%s' of type '%s'"), + (*s)->name, + (char *) (*s)->type); + return NULL; + } + + g_hash_table_insert(ht, g_strdup((*s)->name), variant); + start = NULL; + } +next: + if (*ptr == '\0') + break; + ptr++; + } + + return g_steal_pointer(&ht); +} + +/* + * nm_utils_format_variant_attributes: + * @attributes: (element-type utf8 GVariant): a #GHashTable mapping attribute names to #GVariant values + * @attr_separator: the attribute separator character + * @key_value_separator: character separating key and values + * + * Format attributes to a string. + * + * Returns: (transfer full): the string representing attributes, or %NULL + * in case there are no attributes + * + * Since: 1.8 + */ +char * +nm_utils_format_variant_attributes(GHashTable *attributes, + char attr_separator, + char key_value_separator) +{ + return _nm_utils_format_variant_attributes(attributes, + NULL, + attr_separator, + key_value_separator); +} + +/*****************************************************************************/ + +/* + * nm_utils_get_timestamp_msec(): + * + * Gets current time in milliseconds of CLOCK_BOOTTIME. + * + * Returns: time in milliseconds + * + * Since: 1.12 + */ +gint64 +nm_utils_get_timestamp_msec(void) +{ + gint64 ts; + + ts = nm_utils_clock_gettime_msec(CLOCK_BOOTTIME); + if (ts >= 0) + return ts; + + if (ts == -EINVAL) { + /* The fallback to CLOCK_MONOTONIC is taken only if we're running on a + * criminally old kernel, prior to 2.6.39 (released on 18 May, 2011). + * That happens during buildcheck on old builders, we don't expect to + * be actually runs on kernels that old. */ + ts = nm_utils_clock_gettime_msec(CLOCK_MONOTONIC); + if (ts >= 0) + return ts; + } + + g_return_val_if_reached(-1); +} + +/*****************************************************************************/ + +/** + * nm_utils_version: + * + * Returns: the version ID of the libnm version. That is, the %NM_VERSION + * at runtime. + * + * Since: 1.6.0 + */ +guint +nm_utils_version(void) +{ + return NM_VERSION; +} + +/*****************************************************************************/ + +NM_UTILS_FLAGS2STR_DEFINE(nm_bluetooth_capability_to_string, + NMBluetoothCapabilities, + NM_UTILS_FLAGS2STR(NM_BT_CAPABILITY_NONE, "NONE"), + NM_UTILS_FLAGS2STR(NM_BT_CAPABILITY_DUN, "DUN"), + NM_UTILS_FLAGS2STR(NM_BT_CAPABILITY_NAP, "NAP"), ); + +/*****************************************************************************/ + +/** + * nm_utils_base64secret_decode: + * @base64_key: the (possibly invalid) base64 encode key. + * @required_key_len: the expected (binary) length of the key after + * decoding. If the length does not match, the validation fails. + * @out_key: (allow-none): (out): an optional output buffer for the binary + * key. If given, it will be filled with exactly @required_key_len + * bytes. + * + * Returns: %TRUE if the input key is a valid base64 encoded key + * with @required_key_len bytes. + * + * Since: 1.16 + */ +gboolean +nm_utils_base64secret_decode(const char *base64_key, gsize required_key_len, guint8 *out_key) +{ + nm_auto_free guint8 *bin_arr = NULL; + gsize base64_key_len; + gsize bin_len; + int r; + + if (!base64_key) + return FALSE; + + base64_key_len = strlen(base64_key); + + r = nm_sd_utils_unbase64mem(base64_key, base64_key_len, TRUE, &bin_arr, &bin_len); + if (r < 0) + return FALSE; + if (bin_len != required_key_len) { + nm_explicit_bzero(bin_arr, bin_len); + return FALSE; + } + + if (out_key) + memcpy(out_key, bin_arr, required_key_len); + + nm_explicit_bzero(bin_arr, bin_len); + return TRUE; +} + +gboolean +nm_utils_base64secret_normalize(const char *base64_key, + gsize required_key_len, + char ** out_base64_key_norm) +{ + gs_free guint8 *buf_free = NULL; + guint8 buf_static[200]; + guint8 * buf; + + if (required_key_len > sizeof(buf_static)) { + buf_free = g_new(guint8, required_key_len); + buf = buf_free; + } else + buf = buf_static; + + if (!nm_utils_base64secret_decode(base64_key, required_key_len, buf)) { + NM_SET_OUT(out_base64_key_norm, NULL); + return FALSE; + } + + NM_SET_OUT(out_base64_key_norm, g_base64_encode(buf, required_key_len)); + nm_explicit_bzero(buf, required_key_len); + return TRUE; +} + +static GVariant * +_nm_utils_bridge_vlans_to_dbus(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + gs_unref_ptrarray GPtrArray *vlans = NULL; + GVariantBuilder builder; + guint i; + const char * property_name = sett_info->property_infos[property_idx].name; + + nm_assert(property_name); + + g_object_get(setting, property_name, &vlans, NULL); + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + + if (vlans) { + for (i = 0; i < vlans->len; i++) { + NMBridgeVlan * vlan = vlans->pdata[i]; + GVariantBuilder vlan_builder; + guint16 vid_start, vid_end; + + nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end); + + g_variant_builder_init(&vlan_builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add(&vlan_builder, + "{sv}", + "vid-start", + g_variant_new_uint16(vid_start)); + g_variant_builder_add(&vlan_builder, "{sv}", "vid-end", g_variant_new_uint16(vid_end)); + g_variant_builder_add(&vlan_builder, + "{sv}", + "pvid", + g_variant_new_boolean(nm_bridge_vlan_is_pvid(vlan))); + g_variant_builder_add(&vlan_builder, + "{sv}", + "untagged", + g_variant_new_boolean(nm_bridge_vlan_is_untagged(vlan))); + g_variant_builder_add(&builder, "a{sv}", &vlan_builder); + } + } + + return g_variant_builder_end(&builder); +} + +static gboolean +_nm_utils_bridge_vlans_from_dbus(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) +{ + gs_unref_ptrarray GPtrArray *vlans = NULL; + GVariantIter vlan_iter; + GVariant * vlan_var; + + g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), FALSE); + + vlans = g_ptr_array_new_with_free_func((GDestroyNotify) nm_bridge_vlan_unref); + g_variant_iter_init(&vlan_iter, value); + while (g_variant_iter_next(&vlan_iter, "@a{sv}", &vlan_var)) { + _nm_unused gs_unref_variant GVariant *var_unref = vlan_var; + NMBridgeVlan * vlan; + guint16 vid_start, vid_end; + gboolean pvid = FALSE, untagged = FALSE; + + if (!g_variant_lookup(vlan_var, "vid-start", "q", &vid_start)) + continue; + if (vid_start < NM_BRIDGE_VLAN_VID_MIN || vid_start > NM_BRIDGE_VLAN_VID_MAX) + continue; + + if (!g_variant_lookup(vlan_var, "vid-end", "q", &vid_end)) + continue; + if (vid_end < NM_BRIDGE_VLAN_VID_MIN || vid_end > NM_BRIDGE_VLAN_VID_MAX) + continue; + if (vid_start > vid_end) + continue; + + if (!g_variant_lookup(vlan_var, "pvid", "b", &pvid)) + pvid = FALSE; + if (pvid && vid_start != vid_end) + continue; + if (!g_variant_lookup(vlan_var, "untagged", "b", &untagged)) + untagged = FALSE; + + vlan = nm_bridge_vlan_new(vid_start, vid_end); + nm_bridge_vlan_set_untagged(vlan, untagged); + nm_bridge_vlan_set_pvid(vlan, pvid); + g_ptr_array_add(vlans, vlan); + } + + g_object_set(setting, property, vlans, NULL); + + return TRUE; +} + +const NMSettInfoPropertType nm_sett_info_propert_type_bridge_vlans = { + .dbus_type = NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = _nm_utils_bridge_vlans_to_dbus, + .from_dbus_fcn = _nm_utils_bridge_vlans_from_dbus, +}; + +gboolean +_nm_utils_bridge_vlan_verify_list(GPtrArray * vlans, + gboolean check_normalizable, + GError ** error, + const char *setting, + const char *property) +{ + guint i; + gs_unref_hashtable GHashTable *h = NULL; + gboolean pvid_found = FALSE; + + if (!vlans || vlans->len <= 1) + return TRUE; + + if (check_normalizable) { + guint16 vid_prev_end, vid_start, vid_end; + + nm_assert(_nm_utils_bridge_vlan_verify_list(vlans, FALSE, NULL, setting, property)); + + nm_bridge_vlan_get_vid_range(vlans->pdata[0], NULL, &vid_prev_end); + for (i = 1; i < vlans->len; i++) { + const NMBridgeVlan *vlan = vlans->pdata[i]; + + nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end); + + if (vid_prev_end > vid_start) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Bridge VLANs %d and %d are not sorted by ascending vid"), + vid_prev_end, + vid_start); + g_prefix_error(error, "%s.%s: ", setting, property); + return FALSE; + } + + vid_prev_end = vid_end; + } + return TRUE; + } + + h = g_hash_table_new(nm_direct_hash, NULL); + for (i = 0; i < vlans->len; i++) { + NMBridgeVlan *vlan = vlans->pdata[i]; + guint16 v, vid_start, vid_end; + + nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end); + + for (v = vid_start; v <= vid_end; v++) { + if (!nm_g_hash_table_add(h, GUINT_TO_POINTER(v))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("duplicate bridge VLAN vid %u"), + v); + g_prefix_error(error, "%s.%s: ", setting, property); + return FALSE; + } + } + + if (nm_bridge_vlan_is_pvid(vlan)) { + if (vid_start != vid_end || pvid_found) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("only one VLAN can be the PVID")); + g_prefix_error(error, "%s.%s: ", setting, property); + return FALSE; + } + pvid_found = TRUE; + } + } + + return TRUE; +} + +gboolean +_nm_utils_iaid_verify(const char *str, gint64 *out_value) +{ + gint64 iaid; + + NM_SET_OUT(out_value, -1); + + if (!str || !str[0]) + return FALSE; + + if (NM_IAID_IS_SPECIAL(str)) + return TRUE; + + if (NM_STRCHAR_ALL(str, ch, ch >= '0' && ch <= '9') && (str[0] != '0' || str[1] == '\0') + && (iaid = _nm_utils_ascii_str_to_int64(str, 10, 0, G_MAXUINT32, -1)) != -1) { + NM_SET_OUT(out_value, iaid); + return TRUE; + } + + return FALSE; +} + +gboolean +_nm_utils_validate_dhcp_hostname_flags(NMDhcpHostnameFlags flags, int addr_family, GError **error) +{ + NMDhcpHostnameFlags unknown; + + unknown = flags; + unknown &= ~(NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED | NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE + | NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE | NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS); + if (unknown) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unknown flags 0x%x"), + (guint) unknown); + return FALSE; + } + + if (NM_FLAGS_ALL(flags, + NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE + | NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE)) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'fqdn-no-update' and 'fqdn-serv-update' flags cannot be set at the same time")); + return FALSE; + } + + if (NM_FLAGS_HAS(flags, NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS) + && NM_FLAGS_ANY(flags, + NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE | NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED + | NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'fqdn-clear-flags' flag is incompatible with other FQDN flags")); + return FALSE; + } + + if (addr_family == AF_INET6 && (flags & NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("DHCPv6 does not support the E (encoded) FQDN flag")); + return FALSE; + } + + return TRUE; +} diff --git a/src/libnm-core-impl/nm-vpn-editor-plugin.c b/src/libnm-core-impl/nm-vpn-editor-plugin.c new file mode 100644 index 0000000..468ddce --- /dev/null +++ b/src/libnm-core-impl/nm-vpn-editor-plugin.c @@ -0,0 +1,518 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-vpn-editor-plugin.h" + +#include +#include + +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +static void nm_vpn_editor_plugin_default_init(NMVpnEditorPluginInterface *iface); + +G_DEFINE_INTERFACE(NMVpnEditorPlugin, nm_vpn_editor_plugin, G_TYPE_OBJECT) + +static void +nm_vpn_editor_plugin_default_init(NMVpnEditorPluginInterface *iface) +{ + /** + * NMVpnEditorPlugin:name: + * + * Short display name of the VPN plugin. + */ + g_object_interface_install_property( + iface, + g_param_spec_string(NM_VPN_EDITOR_PLUGIN_NAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnEditorPlugin:description: + * + * Longer description of the VPN plugin. + */ + g_object_interface_install_property( + iface, + g_param_spec_string(NM_VPN_EDITOR_PLUGIN_DESCRIPTION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnEditorPlugin:service: + * + * D-Bus service name of the plugin's VPN service. + */ + g_object_interface_install_property( + iface, + g_param_spec_string(NM_VPN_EDITOR_PLUGIN_SERVICE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); +} + +/*****************************************************************************/ + +typedef struct { + NMVpnPluginInfo *plugin_info; +} NMVpnEditorPluginPrivate; + +static void +_private_destroy(gpointer data) +{ + NMVpnEditorPluginPrivate *priv = data; + + if (priv->plugin_info) + g_object_remove_weak_pointer((GObject *) priv->plugin_info, + (gpointer *) &priv->plugin_info); + + g_slice_free(NMVpnEditorPluginPrivate, priv); +} + +static NMVpnEditorPluginPrivate * +_private_get(NMVpnEditorPlugin *plugin, gboolean create) +{ + static GQuark quark = 0; + NMVpnEditorPluginPrivate *priv; + + nm_assert(NM_IS_VPN_EDITOR_PLUGIN(plugin)); + + if (G_UNLIKELY(quark == 0)) + quark = g_quark_from_string("nm-vpn-editor-plugin-private"); + + priv = g_object_get_qdata((GObject *) plugin, quark); + if (G_LIKELY(priv)) + return priv; + if (!create) + return NULL; + priv = g_slice_new0(NMVpnEditorPluginPrivate); + g_object_set_qdata_full((GObject *) plugin, quark, priv, _private_destroy); + return priv; +} + +#define NM_VPN_EDITOR_PLUGIN_GET_PRIVATE(plugin) _private_get(plugin, TRUE) +#define NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE(plugin) _private_get(plugin, FALSE) + +/*****************************************************************************/ + +/** + * nm_vpn_editor_plugin_get_plugin_info: + * @plugin: the #NMVpnEditorPlugin instance + * + * Returns: (transfer none): if set, return the #NMVpnPluginInfo instance. + * + * Since: 1.4 + */ +NMVpnPluginInfo * +nm_vpn_editor_plugin_get_plugin_info(NMVpnEditorPlugin *plugin) +{ + NMVpnEditorPluginPrivate *priv; + + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), NULL); + + priv = NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE(plugin); + return priv ? priv->plugin_info : NULL; +} + +/** + * nm_vpn_editor_plugin_set_plugin_info: + * @plugin: the #NMVpnEditorPlugin instance + * @plugin_info: (allow-none): a #NMVpnPluginInfo instance or %NULL + * + * Set or clear the plugin-info instance. + * This takes a weak reference on @plugin_info, to avoid circular + * reference as the plugin-info might also reference the editor-plugin. + * + * Since: 1.4 + */ +void +nm_vpn_editor_plugin_set_plugin_info(NMVpnEditorPlugin *plugin, NMVpnPluginInfo *plugin_info) +{ + NMVpnEditorPluginInterface *interface; + NMVpnEditorPluginPrivate * priv; + + g_return_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin)); + + if (!plugin_info) { + priv = NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE(plugin); + if (!priv) + return; + } else { + g_return_if_fail(NM_IS_VPN_PLUGIN_INFO(plugin_info)); + priv = NM_VPN_EDITOR_PLUGIN_GET_PRIVATE(plugin); + } + + if (priv->plugin_info == plugin_info) + return; + if (priv->plugin_info) + g_object_remove_weak_pointer((GObject *) priv->plugin_info, + (gpointer *) &priv->plugin_info); + priv->plugin_info = plugin_info; + if (priv->plugin_info) + g_object_add_weak_pointer((GObject *) priv->plugin_info, (gpointer *) &priv->plugin_info); + + if (plugin_info) { + interface = NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin); + if (interface->notify_plugin_info_set) + interface->notify_plugin_info_set(plugin, plugin_info); + } +} + +/*****************************************************************************/ + +/** + * nm_vpn_editor_plugin_get_vt: + * @plugin: the #NMVpnEditorPlugin + * @vt: (out): buffer to be filled with the VT table of the plugin + * @vt_size: the size of the buffer. Can be 0 to only query the + * size of plugin's VT. + * + * Returns an opaque VT function table for the plugin to extend + * functionality. The actual meaning of NMVpnEditorPluginVT is not + * defined in public API of libnm, instead it must be agreed by + * both the plugin and the caller. See the header-only file + * 'nm-vpn-editor-plugin-call.h' which defines the meaning. + * + * Returns: the actual size of the @plugin's virtual function table. + * + * Since: 1.4 + **/ +gsize +nm_vpn_editor_plugin_get_vt(NMVpnEditorPlugin *plugin, NMVpnEditorPluginVT *vt, gsize vt_size) +{ + const NMVpnEditorPluginVT * p_vt = NULL; + gsize p_vt_size = 0; + NMVpnEditorPluginInterface *interface; + + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), 0); + + if (vt_size) { + g_return_val_if_fail(vt, 0); + memset(vt, 0, vt_size); + } + + interface = NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin); + if (interface->get_vt) { + p_vt = interface->get_vt(plugin, &p_vt_size); + if (!p_vt) + p_vt_size = 0; + g_return_val_if_fail(p_vt_size, 0); + memcpy(vt, p_vt, MIN(vt_size, p_vt_size)); + } + + return p_vt_size; +} + +/*****************************************************************************/ + +static NMVpnEditorPlugin * +_nm_vpn_editor_plugin_load(const char * plugin_name, + gboolean do_file_checks, + const char * check_service, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError ** error) +{ + void * dl_module = NULL; + gboolean loaded_before; + NMVpnEditorPluginFactory factory = NULL; + gs_unref_object NMVpnEditorPlugin *editor_plugin = NULL; + gs_free char * plugin_filename_free = NULL; + const char * plugin_filename; + gs_free_error GError *factory_error = NULL; + gs_free char * plug_name = NULL; + gs_free char * plug_service = NULL; + + g_return_val_if_fail(plugin_name && *plugin_name, NULL); + + /* if @do_file_checks is FALSE, we pass plugin_name directly to + * g_module_open(). + * + * Otherwise, we allow for library names without path component. + * In which case, we prepend the plugin directory and form an + * absolute path. In that case, we perform checks on the file. + * + * One exception is that we don't allow for the "la" suffix. The + * reason is that g_module_open() interprets files with this extension + * special and we don't want that. */ + plugin_filename = plugin_name; + if (do_file_checks) { + if (!strchr(plugin_name, '/') && !g_str_has_suffix(plugin_name, ".la")) { + plugin_filename_free = g_module_build_path(NMVPNDIR, plugin_name); + plugin_filename = plugin_filename_free; + } + } + + dl_module = dlopen(plugin_filename, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); + if (!dl_module && do_file_checks) { + /* If the module is already loaded, we skip the file checks. + * + * _nm_utils_check_module_file() fails with ENOENT if the plugin file + * does not exist. That is relevant, because nm-applet checks for that. */ + if (!_nm_utils_check_module_file(plugin_filename, + check_owner, + check_file, + user_data, + error)) + return NULL; + } + + if (dl_module) { + loaded_before = TRUE; + } else { + loaded_before = FALSE; + dl_module = dlopen(plugin_filename, RTLD_LAZY | RTLD_LOCAL); + } + + if (!dl_module) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("cannot load plugin \"%s\": %s"), + plugin_name, + dlerror() ?: "unknown reason"); + return NULL; + } + + factory = dlsym(dl_module, "nm_vpn_editor_plugin_factory"); + if (!factory) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("failed to load nm_vpn_editor_plugin_factory() from %s (%s)"), + plugin_name, + dlerror()); + dlclose(dl_module); + return NULL; + } + + editor_plugin = factory(&factory_error); + + if (loaded_before) { + /* we want to leak the library, because the factory will register glib + * types, which cannot be unregistered. + * + * However, if the library was already loaded before, we want to return + * our part of the reference count. */ + dlclose(dl_module); + } + + if (!editor_plugin) { + if (factory_error) { + g_propagate_error(error, factory_error); + factory_error = NULL; + } else { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("unknown error initializing plugin %s"), + plugin_name); + } + return NULL; + } + + g_return_val_if_fail(G_IS_OBJECT(editor_plugin), NULL); + + /* Validate plugin properties */ + g_object_get(G_OBJECT(editor_plugin), + NM_VPN_EDITOR_PLUGIN_NAME, + &plug_name, + NM_VPN_EDITOR_PLUGIN_SERVICE, + &plug_service, + NULL); + + if (!plug_name || !*plug_name) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("cannot load VPN plugin in '%s': missing plugin name"), + plugin_name); + return NULL; + } + if (check_service && g_strcmp0(plug_service, check_service) != 0) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("cannot load VPN plugin in '%s': invalid service name"), + plugin_name); + return NULL; + } + + return g_steal_pointer(&editor_plugin); +} + +/** + * nm_vpn_editor_plugin_load_from_file: + * @plugin_name: The path or name of the shared library to load. + * The path must either be an absolute filename to an existing file. + * Alternatively, it can be the name (without path) of a library in the + * plugin directory of NetworkManager. + * @check_service: if not-null, check that the loaded plugin advertises + * the given service. + * @check_owner: if non-negative, check whether the file is owned + * by UID @check_owner or by root. In this case also check that + * the file is not writable by anybody else. + * @check_file: (scope call): optional callback to validate the file prior to + * loading the shared library. + * @user_data: user data for @check_file + * @error: on failure the error reason. + * + * Load the shared library @plugin_name and create a new + * #NMVpnEditorPlugin instance via the #NMVpnEditorPluginFactory + * function. + * + * If @plugin_name is not an absolute path name, it assumes the file + * is in the plugin directory of NetworkManager. In any case, the call + * will do certain checks on the file before passing it to dlopen. + * A consequence for that is, that you cannot omit the ".so" suffix + * as you could for nm_vpn_editor_plugin_load(). + * + * Returns: (transfer full): a new plugin instance or %NULL on error. + * + * Since: 1.2 + */ +NMVpnEditorPlugin * +nm_vpn_editor_plugin_load_from_file(const char * plugin_name, + const char * check_service, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError ** error) +{ + return _nm_vpn_editor_plugin_load(plugin_name, + TRUE, + check_service, + check_owner, + check_file, + user_data, + error); +} + +/** + * nm_vpn_editor_plugin_load: + * @plugin_name: The name of the shared library to load. + * This path will be directly passed to dlopen() without + * further checks. + * @check_service: if not-null, check that the loaded plugin advertises + * the given service. + * @error: on failure the error reason. + * + * Load the shared library @plugin_name and create a new + * #NMVpnEditorPlugin instance via the #NMVpnEditorPluginFactory + * function. + * + * This is similar to nm_vpn_editor_plugin_load_from_file(), but + * it does no validation of the plugin name, instead passes it directly + * to dlopen(). If you have the full path to a plugin file, + * nm_vpn_editor_plugin_load_from_file() is preferred. + * + * Returns: (transfer full): a new plugin instance or %NULL on error. + * + * Since: 1.4 + */ +NMVpnEditorPlugin * +nm_vpn_editor_plugin_load(const char *plugin_name, const char *check_service, GError **error) +{ + return _nm_vpn_editor_plugin_load(plugin_name, FALSE, check_service, -1, NULL, NULL, error); +} + +/*****************************************************************************/ + +/** + * nm_vpn_editor_plugin_get_editor: + * @plugin: the #NMVpnEditorPlugin + * @connection: the #NMConnection to be edited + * @error: on return, an error or %NULL + * + * Returns: (transfer full): a new #NMVpnEditor or %NULL on error + */ +NMVpnEditor * +nm_vpn_editor_plugin_get_editor(NMVpnEditorPlugin *plugin, NMConnection *connection, GError **error) +{ + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), NULL); + + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->get_editor(plugin, connection, error); +} + +NMVpnEditorPluginCapability +nm_vpn_editor_plugin_get_capabilities(NMVpnEditorPlugin *plugin) +{ + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), 0); + + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->get_capabilities(plugin); +} + +/** + * nm_vpn_editor_plugin_import: + * @plugin: the #NMVpnEditorPlugin + * @path: full path to the file to attempt to read into a new #NMConnection + * @error: on return, an error or %NULL + * + * Returns: (transfer full): a new #NMConnection imported from @path, or %NULL + * on error or if the file at @path was not recognized by this plugin + */ +NMConnection * +nm_vpn_editor_plugin_import(NMVpnEditorPlugin *plugin, const char *path, GError **error) +{ + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), NULL); + + if (nm_vpn_editor_plugin_get_capabilities(plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT) { + g_return_val_if_fail(NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->import_from_file != NULL, + NULL); + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->import_from_file(plugin, path, error); + } + + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("the plugin does not support import capability")); + return NULL; +} + +gboolean +nm_vpn_editor_plugin_export(NMVpnEditorPlugin *plugin, + const char * path, + NMConnection * connection, + GError ** error) +{ + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), FALSE); + + if (nm_vpn_editor_plugin_get_capabilities(plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT) { + g_return_val_if_fail(NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->export_to_file != NULL, + FALSE); + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->export_to_file(plugin, + path, + connection, + error); + } + + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("the plugin does not support export capability")); + return FALSE; +} + +char * +nm_vpn_editor_plugin_get_suggested_filename(NMVpnEditorPlugin *plugin, NMConnection *connection) +{ + g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), NULL); + + if (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->get_suggested_filename) + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->get_suggested_filename(plugin, + connection); + return NULL; +} diff --git a/src/libnm-core-impl/nm-vpn-plugin-info.c b/src/libnm-core-impl/nm-vpn-plugin-info.c new file mode 100644 index 0000000..dc77dfd --- /dev/null +++ b/src/libnm-core-impl/nm-vpn-plugin-info.c @@ -0,0 +1,1354 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-vpn-plugin-info.h" + +#include + +#include "nm-errors.h" +#include "libnm-core-intern/nm-core-internal.h" + +#define DEFAULT_DIR_ETC NMCONFDIR "/VPN" +#define DEFAULT_DIR_LIB NMLIBDIR "/VPN" + +enum { + PROP_0, + PROP_NAME, + PROP_FILENAME, + PROP_KEYFILE, + + LAST_PROP, +}; + +typedef struct { + char * filename; + char * name; + char * service; + char * auth_dialog; + char ** aliases; + GKeyFile *keyfile; + + /* It is convenient for nm_vpn_plugin_info_lookup_property() to return a const char *, + * contrary to what g_key_file_get_string() does. Hence we must cache the returned + * value somewhere... let's put it in an internal hash table. + * This contains a clone of all the strings in keyfile. */ + GHashTable *keys; + + gboolean editor_plugin_loaded; + NMVpnEditorPlugin *editor_plugin; +} NMVpnPluginInfoPrivate; + +/** + * NMVpnPluginInfo: + */ +struct _NMVpnPluginInfo { + GObject parent; + NMVpnPluginInfoPrivate _priv; +}; + +struct _NMVpnPluginInfoClass { + GObjectClass parent; +}; + +#define NM_VPN_PLUGIN_INFO_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMVpnPluginInfo, NM_IS_VPN_PLUGIN_INFO) + +static void nm_vpn_plugin_info_initable_iface_init(GInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE(NMVpnPluginInfo, + nm_vpn_plugin_info, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE, + nm_vpn_plugin_info_initable_iface_init);) + +/*****************************************************************************/ + +static NMVpnPluginInfo *_list_find_by_service(GSList *list, const char *name, const char *service); + +/*****************************************************************************/ + +/** + * nm_vpn_plugin_info_validate_filename: + * @filename: the filename to check + * + * Regular name files have a certain pattern. That basically means + * they have the file extension "name". Check if @filename + * is valid according to that pattern. + * + * Since: 1.2 + */ +gboolean +nm_vpn_plugin_info_validate_filename(const char *filename) +{ + if (!filename || !g_str_has_suffix(filename, ".name")) + return FALSE; + + /* originally, we didn't do further checks... but here we go. */ + if (filename[0] == '.') { + /* this also rejects name ".name" alone. */ + return FALSE; + } + return TRUE; +} + +static gboolean +nm_vpn_plugin_info_check_file_full(const char * filename, + gboolean check_absolute, + gboolean do_validate_filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + struct stat * out_st, + GError ** error) +{ + if (!filename || !*filename) { + g_set_error(error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED, _("missing filename")); + return FALSE; + } + + if (check_absolute && !g_path_is_absolute(filename)) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("filename must be an absolute path (%s)"), + filename); + return FALSE; + } + + if (do_validate_filename && !nm_vpn_plugin_info_validate_filename(filename)) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("filename has invalid format (%s)"), + filename); + return FALSE; + } + + return _nm_utils_check_file(filename, check_owner, check_file, user_data, out_st, error); +} + +/** + * _nm_vpn_plugin_info_check_file: + * @filename: the file to check + * @check_absolute: if %TRUE, only allow absolute path names. + * @do_validate_filename: if %TRUE, only accept the filename if + * nm_vpn_plugin_info_validate_filename() succeeds. + * @check_owner: if non-negative, only accept the file if the + * owner UID is equal to @check_owner or if the owner is 0. + * In this case, also check that the file is not writable by + * other users. + * @check_file: pass a callback to do your own validation. + * @user_data: user data for @check_file. + * @error: (allow-none) (out): the error reason if the check fails. + * + * Check whether the file exists and is a valid name file (in keyfile format). + * Additionally, also check for file permissions. + * + * Returns: %TRUE if a file @filename exists and has valid permissions. + * + * Since: 1.2 + */ +gboolean +_nm_vpn_plugin_info_check_file(const char * filename, + gboolean check_absolute, + gboolean do_validate_filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError ** error) +{ + return nm_vpn_plugin_info_check_file_full(filename, + check_absolute, + do_validate_filename, + check_owner, + check_file, + user_data, + NULL, + error); +} + +typedef struct { + NMVpnPluginInfo *plugin_info; + struct stat stat; +} LoadDirInfo; + +static int +_sort_files(LoadDirInfo *a, LoadDirInfo *b) +{ + time_t ta, tb; + + ta = MAX(a->stat.st_mtime, a->stat.st_ctime); + tb = MAX(b->stat.st_mtime, b->stat.st_ctime); + if (ta < tb) + return 1; + if (ta > tb) + return -1; + return g_strcmp0(nm_vpn_plugin_info_get_filename(a->plugin_info), + nm_vpn_plugin_info_get_filename(b->plugin_info)); +} + +/** + * _nm_vpn_plugin_info_get_default_dir_etc: + * + * Returns: (transfer none): compile time constant of the default + * VPN plugin directory. + */ +const char * +_nm_vpn_plugin_info_get_default_dir_etc() +{ + return DEFAULT_DIR_ETC; +} + +/** + * _nm_vpn_plugin_info_get_default_dir_lib: + * + * Returns: (transfer none): compile time constant of the default + * VPN plugin directory. + */ +const char * +_nm_vpn_plugin_info_get_default_dir_lib() +{ + return DEFAULT_DIR_LIB; +} + +/** + * _nm_vpn_plugin_info_get_default_dir_user: + * + * Returns: The user can specify a different directory for VPN plugins + * by setting NM_VPN_PLUGIN_DIR environment variable. Return + * that directory. + */ +const char * +_nm_vpn_plugin_info_get_default_dir_user() +{ + return nm_str_not_empty(g_getenv("NM_VPN_PLUGIN_DIR")); +} + +/** + * _nm_vpn_plugin_info_list_load_dir: + * @dirname: the name of the directory to load. + * @do_validate_filename: only consider filenames that have a certain + * pattern (i.e. end with ".name"). + * @check_owner: if set to a non-negative number, check that the file + * owner is either the same uid or 0. In that case, also check + * that the file is not writable by group or other. + * @check_file: (allow-none): callback to check whether the file is valid. + * @user_data: data for @check_file + * + * Iterate over the content of @dirname and load name files. + * + * Returns: (transfer full) (element-type NMVpnPluginInfo): list of loaded plugin infos. + */ +GSList * +_nm_vpn_plugin_info_list_load_dir(const char * dirname, + gboolean do_validate_filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data) +{ + GDir * dir; + const char *fn; + GArray * array; + GSList * res = NULL; + guint i; + + g_return_val_if_fail(dirname, NULL); + + if (!dirname[0]) + return NULL; + + dir = g_dir_open(dirname, 0, NULL); + if (!dir) + return NULL; + + array = g_array_new(FALSE, FALSE, sizeof(LoadDirInfo)); + + while ((fn = g_dir_read_name(dir))) { + gs_free char *filename = NULL; + LoadDirInfo info = {0}; + + filename = g_build_filename(dirname, fn, NULL); + if (nm_vpn_plugin_info_check_file_full(filename, + FALSE, + do_validate_filename, + check_owner, + check_file, + user_data, + &info.stat, + NULL)) { + info.plugin_info = nm_vpn_plugin_info_new_from_file(filename, NULL); + if (info.plugin_info) { + g_array_append_val(array, info); + continue; + } + } + } + g_dir_close(dir); + + /* sort the files so that we have a stable behavior. The directory might contain + * duplicate VPNs, so while nm_vpn_plugin_info_list_load() would load them all, the + * caller probably wants to reject duplicates. Having a stable order means we always + * reject the same files in face of duplicates. */ + g_array_sort(array, (GCompareFunc) _sort_files); + + for (i = 0; i < array->len; i++) + res = g_slist_prepend(res, g_array_index(array, LoadDirInfo, i).plugin_info); + + g_array_unref(array); + + return g_slist_reverse(res); +} + +/** + * nm_vpn_plugin_info_list_load: + * + * Returns: (element-type NMVpnPluginInfo) (transfer full): list of plugins + * loaded from the default directories rejecting duplicates. + * + * Since: 1.2 + */ +GSList * +nm_vpn_plugin_info_list_load() +{ + int i; + gint64 uid; + GSList * list = NULL; + GSList * infos, *info; + const char *const dir[] = { + /* We load plugins from NM_VPN_PLUGIN_DIR *and* DEFAULT_DIR*, with + * preference to the former. + * + * load user directory with highest priority. */ + _nm_vpn_plugin_info_get_default_dir_user(), + + /* lib directory has higher priority then etc. The reason is that + * etc is deprecated and used by old plugins. We expect newer plugins + * to install their file in lib, where they have higher priority. + * + * Optimally, there are no duplicates anyway, so it doesn't really matter. */ + _nm_vpn_plugin_info_get_default_dir_lib(), + _nm_vpn_plugin_info_get_default_dir_etc(), + }; + + uid = getuid(); + + for (i = 0; i < G_N_ELEMENTS(dir); i++) { + if (!dir[i] || nm_utils_strv_find_first((char **) dir, i, dir[i]) >= 0) + continue; + + infos = _nm_vpn_plugin_info_list_load_dir(dir[i], TRUE, uid, NULL, NULL); + + for (info = infos; info; info = info->next) + nm_vpn_plugin_info_list_add(&list, info->data, NULL); + + g_slist_free_full(infos, g_object_unref); + } + return list; +} + +/** + * nm_vpn_plugin_info_new_search_file: + * @name: (allow-none): the name to search for. Either @name or @service + * must be present. + * @service: (allow-none): the service to search for. Either @name or + * @service must be present. + * + * This has the same effect as doing a full nm_vpn_plugin_info_list_load() + * followed by a search for the first matching VPN plugin info that has the + * given @name and/or @service. + * + * Returns: (transfer full): a newly created instance of plugin info + * or %NULL if no matching value was found. + * + * Since: 1.4 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_new_search_file(const char *name, const char *service) +{ + NMVpnPluginInfo *info; + GSList * infos; + + if (!name && !service) + g_return_val_if_reached(NULL); + + infos = nm_vpn_plugin_info_list_load(); + info = nm_g_object_ref(_list_find_by_service(infos, name, service)); + g_slist_free_full(infos, g_object_unref); + return info; +} + +/*****************************************************************************/ + +static gboolean +_check_no_conflict(NMVpnPluginInfo *i1, NMVpnPluginInfo *i2, GError **error) +{ + NMVpnPluginInfoPrivate *priv1, *priv2; + uint i; + struct { + const char *group; + const char *key; + } check_list[] = { + {NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "service"}, + {NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM, "plugin"}, + {NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "properties"}, + }; + + priv1 = NM_VPN_PLUGIN_INFO_GET_PRIVATE(i1); + priv2 = NM_VPN_PLUGIN_INFO_GET_PRIVATE(i2); + + for (i = 0; i < G_N_ELEMENTS(check_list); i++) { + gs_free NMUtilsStrStrDictKey *k = NULL; + const char * s1, *s2; + + k = _nm_utils_strstrdictkey_create(check_list[i].group, check_list[i].key); + s1 = g_hash_table_lookup(priv1->keys, k); + if (!s1) + continue; + s2 = g_hash_table_lookup(priv2->keys, k); + if (!s2) + continue; + + if (strcmp(s1, s2) == 0) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("there exists a conflicting plugin (%s) that has the same %s.%s value"), + priv2->name, + check_list[i].group, + check_list[i].key); + return FALSE; + } + } + return TRUE; +} + +/** + * nm_vpn_plugin_info_list_add: + * @list: (element-type NMVpnPluginInfo): list of plugins + * @plugin_info: instance to add + * @error: failure reason + * + * Returns: %TRUE if the plugin was added to @list. This will fail + * to add duplicate plugins. + * + * Since: 1.2 + */ +gboolean +nm_vpn_plugin_info_list_add(GSList **list, NMVpnPluginInfo *plugin_info, GError **error) +{ + GSList * iter; + const char *name; + + g_return_val_if_fail(list, FALSE); + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(plugin_info), FALSE); + + name = nm_vpn_plugin_info_get_name(plugin_info); + for (iter = *list; iter; iter = iter->next) { + if (iter->data == plugin_info) + return TRUE; + + if (strcmp(nm_vpn_plugin_info_get_name(iter->data), name) == 0) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("there exists a conflicting plugin with the same name (%s)"), + name); + return FALSE; + } + + /* the plugin must have unique values for certain properties. E.g. two different + * plugins cannot share the same service type. */ + if (!_check_no_conflict(plugin_info, iter->data, error)) + return FALSE; + } + + *list = g_slist_append(*list, g_object_ref(plugin_info)); + return TRUE; +} + +/** + * nm_vpn_plugin_info_list_remove: + * @list: (element-type NMVpnPluginInfo): list of plugins + * @plugin_info: instance + * + * Remove @plugin_info from @list. + * + * Returns: %TRUE if @plugin_info was in @list and successfully removed. + * + * Since: 1.2 + */ +gboolean +nm_vpn_plugin_info_list_remove(GSList **list, NMVpnPluginInfo *plugin_info) +{ + g_return_val_if_fail(list, FALSE); + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(plugin_info), FALSE); + + if (!g_slist_find(*list, plugin_info)) + return FALSE; + + *list = g_slist_remove(*list, plugin_info); + g_object_unref(plugin_info); + return TRUE; +} + +/** + * nm_vpn_plugin_info_list_find_by_name: + * @list: (element-type NMVpnPluginInfo): list of plugins + * @name: name to search + * + * Returns: (transfer none): the first plugin with a matching @name (or %NULL). + * + * Since: 1.2 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_list_find_by_name(GSList *list, const char *name) +{ + GSList *iter; + + if (!name) + g_return_val_if_reached(NULL); + + for (iter = list; iter; iter = iter->next) { + if (strcmp(nm_vpn_plugin_info_get_name(iter->data), name) == 0) + return iter->data; + } + return NULL; +} + +/** + * nm_vpn_plugin_info_list_find_by_filename: + * @list: (element-type NMVpnPluginInfo): list of plugins + * @filename: filename to search + * + * Returns: (transfer none): the first plugin with a matching @filename (or %NULL). + * + * Since: 1.2 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_list_find_by_filename(GSList *list, const char *filename) +{ + GSList *iter; + + if (!filename) + g_return_val_if_reached(NULL); + + for (iter = list; iter; iter = iter->next) { + if (g_strcmp0(nm_vpn_plugin_info_get_filename(iter->data), filename) == 0) + return iter->data; + } + return NULL; +} + +static NMVpnPluginInfo * +_list_find_by_service(GSList *list, const char *name, const char *service) +{ + for (; list; list = list->next) { + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(list->data); + + if (name && !nm_streq(name, priv->name)) + continue; + if (service && !nm_streq(priv->service, service) + && (nm_utils_strv_find_first(priv->aliases, -1, service) < 0)) + continue; + + return list->data; + } + return NULL; +} + +/** + * nm_vpn_plugin_info_list_find_by_service: + * @list: (element-type NMVpnPluginInfo): list of plugins + * @service: service to search. This can be the main service-type + * or one of the provided aliases. + * + * Returns: (transfer none): the first plugin with a matching @service (or %NULL). + * + * Since: 1.2 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_list_find_by_service(GSList *list, const char *service) +{ + if (!service) + g_return_val_if_reached(NULL); + return _list_find_by_service(list, NULL, service); +} + +/* known_names are well known short names for the service-type. They all implicitly + * have a prefix "org.freedesktop.NetworkManager." + known_name. */ +static const char *known_names[] = { + "openvpn", + "vpnc", + "pptp", + "openconnect", + "openswan", + "libreswan", + "strongswan", + "ssh", + "l2tp", + "iodine", + "fortisslvpn", +}; + +/** + * nm_vpn_plugin_info_list_find_service_type: + * @list: (element-type NMVpnPluginInfo): a possibly empty #GSList of #NMVpnPluginInfo instances + * @name: a name to lookup the service-type. + * + * A VPN plugin provides one or several service-types, like org.freedesktop.NetworkManager.libreswan + * Certain plugins provide more then one service type, via aliases (org.freedesktop.NetworkManager.openswan). + * This function looks up a service-type (or an alias) based on a name. + * + * Preferably, the name can be a full service-type/alias of an installed + * plugin. Otherwise, it can be the name of a VPN plugin (in which case, the + * primary, non-aliased service-type is returned). Otherwise, it can be + * one of several well known short-names (which is a hard-coded list of + * types in libnm). On success, this returns a full qualified service-type + * (or an alias). It doesn't say, that such an plugin is actually available, + * but it could be retrieved via nm_vpn_plugin_info_list_find_by_service(). + * + * Returns: (transfer full): the resolved service-type or %NULL on failure. + * + * Since: 1.4 + */ +char * +nm_vpn_plugin_info_list_find_service_type(GSList *list, const char *name) +{ + NMVpnPluginInfo *info; + char * n; + + if (!name) + g_return_val_if_reached(NULL); + if (!*name) + return NULL; + + /* First, try to interpret @name as a full service-type (or alias). */ + info = _list_find_by_service(list, NULL, name); + if (info) + return g_strdup(name); + + /* try to interpret @name as plugin name, in which case we return + * the main service-type (not an alias). */ + info = _list_find_by_service(list, name, NULL); + if (info) + return g_strdup(NM_VPN_PLUGIN_INFO_GET_PRIVATE(info)->service); + + /* check the hard-coded list of short-names. They all have the same + * well-known prefix org.freedesktop.NetworkManager and the name. */ + if (nm_utils_strv_find_first((char **) known_names, G_N_ELEMENTS(known_names), name) >= 0) + return g_strdup_printf("%s.%s", NM_DBUS_INTERFACE, name); + + /* try, if there exists a plugin with @name under org.freedesktop.NetworkManager. + * Allow this to be a valid abbreviation. */ + n = g_strdup_printf("%s.%s", NM_DBUS_INTERFACE, name); + if (_list_find_by_service(list, NULL, n)) + return n; + g_free(n); + + /* currently, VPN plugins have no way to define a short-name for their + * alias name, unless the alias name is prefixed by org.freedesktop.NetworkManager. */ + + return NULL; +} + +static const char * +_service_type_get_default_abbreviation(const char *service_type) +{ + if (!g_str_has_prefix(service_type, NM_DBUS_INTERFACE)) + return NULL; + service_type += NM_STRLEN(NM_DBUS_INTERFACE); + if (service_type[0] != '.') + return NULL; + service_type++; + if (!service_type[0]) + return NULL; + return service_type; +} + +/** + * nm_vpn_plugin_info_list_get_service_types: + * @list: (element-type NMVpnPluginInfo): a possibly empty #GSList of #NMVpnPluginInfo + * @only_existing: only include results that are actually in @list. + * Otherwise, the result is extended with a hard-code list or + * well-known plugins + * @with_abbreviations: if %FALSE, only full service types are returned. + * Otherwise, this also includes abbreviated names that can be used + * with nm_vpn_plugin_info_list_find_service_type(). + * + * Returns: (transfer full): a %NULL terminated strv list of strings. + * The list itself and the values must be freed with g_strfreev(). + * + * Since: 1.4 + */ +char ** +nm_vpn_plugin_info_list_get_service_types(GSList * list, + gboolean only_existing, + gboolean with_abbreviations) +{ + GSList * iter; + GPtrArray * l; + guint i, j; + const char *n; + + l = g_ptr_array_sized_new(20); + + for (iter = list; iter; iter = iter->next) { + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(iter->data); + + g_ptr_array_add(l, g_strdup(priv->service)); + if (priv->aliases) { + for (i = 0; priv->aliases[i]; i++) + g_ptr_array_add(l, g_strdup(priv->aliases[i])); + } + + if (with_abbreviations) { + g_ptr_array_add(l, g_strdup(priv->name)); + n = _service_type_get_default_abbreviation(priv->service); + if (n) + g_ptr_array_add(l, g_strdup(n)); + for (i = 0; priv->aliases && priv->aliases[i]; i++) { + n = _service_type_get_default_abbreviation(priv->aliases[i]); + if (n) + g_ptr_array_add(l, g_strdup(n)); + } + } + } + + if (!only_existing) { + for (i = 0; i < G_N_ELEMENTS(known_names); i++) { + g_ptr_array_add(l, g_strdup_printf("%s.%s", NM_DBUS_INTERFACE, known_names[i])); + if (with_abbreviations) + g_ptr_array_add(l, g_strdup(known_names[i])); + } + } + + if (l->len <= 0) { + g_ptr_array_free(l, TRUE); + return g_new0(char *, 1); + } + + /* sort the result and remove duplicates. */ + g_ptr_array_sort(l, nm_strcmp_p); + for (i = 1, j = 1; i < l->len; i++) { + if (nm_streq(l->pdata[j - 1], l->pdata[i])) + g_free(l->pdata[i]); + else + l->pdata[j++] = l->pdata[i]; + } + + if (j == l->len) + g_ptr_array_add(l, NULL); + else + l->pdata[j] = NULL; + return (char **) g_ptr_array_free(l, FALSE); +} + +/*****************************************************************************/ + +/** + * nm_vpn_plugin_info_get_filename: + * @self: plugin info instance + * + * Returns: (transfer none): the filename. Can be %NULL. + * + * Since: 1.2 + */ +const char * +nm_vpn_plugin_info_get_filename(NMVpnPluginInfo *self) +{ + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), NULL); + + return NM_VPN_PLUGIN_INFO_GET_PRIVATE(self)->filename; +} + +/** + * nm_vpn_plugin_info_get_name: + * @self: plugin info instance + * + * Returns: (transfer none): the name. Cannot be %NULL. + * + * Since: 1.2 + */ +const char * +nm_vpn_plugin_info_get_name(NMVpnPluginInfo *self) +{ + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), NULL); + + return NM_VPN_PLUGIN_INFO_GET_PRIVATE(self)->name; +} + +/** + * nm_vpn_plugin_info_get_service: + * @self: plugin info instance + * + * Returns: (transfer none): the service. Cannot be %NULL. + * + * Since: 1.4 + */ +const char * +nm_vpn_plugin_info_get_service(NMVpnPluginInfo *self) +{ + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), NULL); + + return NM_VPN_PLUGIN_INFO_GET_PRIVATE(self)->service; +} + +/** + * nm_vpn_plugin_info_get_auth_dialog: + * @self: plugin info instance + * + * Returns: the absolute path to the auth-dialog helper or %NULL. + * + * Since: 1.4 + **/ +const char * +nm_vpn_plugin_info_get_auth_dialog(NMVpnPluginInfo *self) +{ + NMVpnPluginInfoPrivate *priv; + + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), NULL); + + priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(self); + + if (G_UNLIKELY(priv->auth_dialog == NULL)) { + const char *s; + + s = g_hash_table_lookup( + priv->keys, + _nm_utils_strstrdictkey_static(NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "auth-dialog")); + if (!s || !s[0]) + priv->auth_dialog = g_strdup(""); + else if (g_path_is_absolute(s)) + priv->auth_dialog = g_strdup(s); + else { + /* for relative paths, we take the basename and assume it's in LIBEXECDIR. */ + gs_free char *prog_basename = g_path_get_basename(s); + + priv->auth_dialog = g_build_filename(LIBEXECDIR, prog_basename, NULL); + } + } + + return priv->auth_dialog[0] ? priv->auth_dialog : NULL; +} + +/** + * nm_vpn_plugin_info_supports_hints: + * @self: plugin info instance + * + * Returns: %TRUE if the supports hints for secret requests, otherwise %FALSE + * + * Since: 1.4 + */ +gboolean +nm_vpn_plugin_info_supports_hints(NMVpnPluginInfo *self) +{ + const char *s; + + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), FALSE); + + s = nm_vpn_plugin_info_lookup_property(self, + NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, + "supports-hints"); + return _nm_utils_ascii_str_to_bool(s, FALSE); +} + +/** + * nm_vpn_plugin_info_get_plugin: + * @self: plugin info instance + * + * Returns: (transfer none): the plugin. Can be %NULL. + * + * Since: 1.2 + */ +const char * +nm_vpn_plugin_info_get_plugin(NMVpnPluginInfo *self) +{ + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), NULL); + + return g_hash_table_lookup( + NM_VPN_PLUGIN_INFO_GET_PRIVATE(self)->keys, + _nm_utils_strstrdictkey_static(NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM, "plugin")); +} + +/** + * nm_vpn_plugin_info_get_program: + * @self: plugin info instance + * + * Returns: (transfer none): the program. Can be %NULL. + * + * Since: 1.2 + */ +const char * +nm_vpn_plugin_info_get_program(NMVpnPluginInfo *self) +{ + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), NULL); + + return g_hash_table_lookup( + NM_VPN_PLUGIN_INFO_GET_PRIVATE(self)->keys, + _nm_utils_strstrdictkey_static(NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "program")); +} + +/** + * nm_vpn_plugin_info_supports_multiple: + * @self: plugin info instance + * + * Returns: %TRUE if the service supports multiple instances with different bus names, otherwise %FALSE + * + * Since: 1.2 + */ +gboolean +nm_vpn_plugin_info_supports_multiple(NMVpnPluginInfo *self) +{ + const char *s; + + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), FALSE); + + s = nm_vpn_plugin_info_lookup_property(self, + NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, + "supports-multiple-connections"); + return _nm_utils_ascii_str_to_bool(s, FALSE); +} + +/** + * nm_vpn_plugin_info_get_aliases: + * @self: plugin info instance + * + * Returns: (array zero-terminated=1) (element-type utf8) (transfer none): + * the aliases from the name-file. + * + * Since: 1.4 + */ +const char *const * +nm_vpn_plugin_info_get_aliases(NMVpnPluginInfo *self) +{ + NMVpnPluginInfoPrivate *priv; + + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), NULL); + + priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(self); + if (priv->aliases) + return (const char *const *) priv->aliases; + + /* For convenience, we always want to return non-NULL, even for empty + * aliases. Hack around that, by making a NULL terminated array using + * the NULL of priv->aliases. */ + return (const char *const *) &priv->aliases; +} + +/** + * nm_vpn_plugin_info_lookup_property: + * @self: plugin info instance + * @group: group name + * @key: name of the property + * + * Returns: (transfer none): #NMVpnPluginInfo is internally a #GKeyFile. Returns the matching + * property. + * + * Since: 1.2 + */ +const char * +nm_vpn_plugin_info_lookup_property(NMVpnPluginInfo *self, const char *group, const char *key) +{ + NMVpnPluginInfoPrivate *priv; + gs_free NMUtilsStrStrDictKey *k = NULL; + + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), NULL); + g_return_val_if_fail(group, NULL); + g_return_val_if_fail(key, NULL); + + priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(self); + + k = _nm_utils_strstrdictkey_create(group, key); + return g_hash_table_lookup(priv->keys, k); +} + +/*****************************************************************************/ + +/** + * nm_vpn_plugin_info_get_editor_plugin: + * @self: plugin info instance + * + * Returns: (transfer none): the cached #NMVpnEditorPlugin instance. + * + * Since: 1.2 + */ +NMVpnEditorPlugin * +nm_vpn_plugin_info_get_editor_plugin(NMVpnPluginInfo *self) +{ + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), NULL); + + return NM_VPN_PLUGIN_INFO_GET_PRIVATE(self)->editor_plugin; +} + +/** + * nm_vpn_plugin_info_set_editor_plugin: + * @self: plugin info instance + * @plugin: (allow-none): plugin instance + * + * Set the internal plugin instance. If %NULL, only clear the previous instance. + * + * Since: 1.2 + */ +void +nm_vpn_plugin_info_set_editor_plugin(NMVpnPluginInfo *self, NMVpnEditorPlugin *plugin) +{ + NMVpnPluginInfoPrivate *priv; + NMVpnEditorPlugin * old; + + g_return_if_fail(NM_IS_VPN_PLUGIN_INFO(self)); + g_return_if_fail(!plugin || G_IS_OBJECT(plugin)); + + priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(self); + + if (!plugin) { + priv->editor_plugin_loaded = FALSE; + g_clear_object(&priv->editor_plugin); + } else { + old = priv->editor_plugin; + priv->editor_plugin = g_object_ref(plugin); + priv->editor_plugin_loaded = TRUE; + if (old) + g_object_unref(old); + } +} + +/** + * nm_vpn_plugin_info_load_editor_plugin: + * @self: plugin info instance + * @error: error reason on failure + * + * Returns: (transfer none): loads the plugin and returns the newly created + * instance. The plugin is owned by @self and can be later retrieved again + * via nm_vpn_plugin_info_get_editor_plugin(). You can load the + * plugin only once, unless you reset the state via + * nm_vpn_plugin_info_set_editor_plugin(). + * + * Since: 1.2 + */ +NMVpnEditorPlugin * +nm_vpn_plugin_info_load_editor_plugin(NMVpnPluginInfo *self, GError **error) +{ + NMVpnPluginInfoPrivate *priv; + const char * plugin_filename; + + g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), NULL); + + priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(self); + + if (priv->editor_plugin) + return priv->editor_plugin; + + plugin_filename = nm_vpn_plugin_info_get_plugin(self); + if (!plugin_filename || !*plugin_filename) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("missing \"plugin\" setting")); + return NULL; + } + + /* We only try once to load the plugin. If we previously tried and it was + * unsuccessful, error out immediately. */ + if (priv->editor_plugin_loaded) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("%s: don't retry loading plugin which already failed previously"), + priv->name); + return NULL; + } + + priv->editor_plugin_loaded = TRUE; + priv->editor_plugin = nm_vpn_editor_plugin_load_from_file(plugin_filename, + nm_vpn_plugin_info_get_service(self), + getuid(), + NULL, + NULL, + error); + if (priv->editor_plugin) + nm_vpn_editor_plugin_set_plugin_info(priv->editor_plugin, self); + return priv->editor_plugin; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_NAME: + g_value_set_string(value, priv->name); + break; + case PROP_FILENAME: + g_value_set_string(value, priv->filename); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_FILENAME: + priv->filename = g_value_dup_string(value); + break; + case PROP_KEYFILE: + priv->keyfile = g_value_dup_boxed(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_vpn_plugin_info_init(NMVpnPluginInfo *plugin) +{} + +static gboolean +init_sync(GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMVpnPluginInfo * self = NM_VPN_PLUGIN_INFO(initable); + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(self); + gs_strfreev char ** groups = NULL; + guint i, j; + + if (!priv->keyfile) { + if (!priv->filename) { + g_set_error_literal(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("missing filename to load VPN plugin info")); + return FALSE; + } + priv->keyfile = g_key_file_new(); + if (!g_key_file_load_from_file(priv->keyfile, priv->filename, G_KEY_FILE_NONE, error)) + return FALSE; + } + + /* we reqire at least a "name" */ + priv->name = + g_key_file_get_string(priv->keyfile, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "name", NULL); + if (!priv->name || !priv->name[0]) { + g_set_error_literal(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("missing name for VPN plugin info")); + return FALSE; + } + + /* we also require "service", because that how we associate NMSettingVpn:service-type with the + * NMVpnPluginInfo. */ + priv->service = g_key_file_get_string(priv->keyfile, + NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, + "service", + NULL); + if (!priv->service || !*priv->service) { + g_set_error_literal(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("missing service for VPN plugin info")); + return FALSE; + } + + priv->aliases = g_key_file_get_string_list(priv->keyfile, + NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, + "aliases", + NULL, + NULL); + if (priv->aliases && !priv->aliases[0]) + nm_clear_g_free(&priv->aliases); + + priv->keys = g_hash_table_new_full(_nm_utils_strstrdictkey_hash, + _nm_utils_strstrdictkey_equal, + g_free, + g_free); + groups = g_key_file_get_groups(priv->keyfile, NULL); + for (i = 0; groups && groups[i]; i++) { + gs_strfreev char **keys = NULL; + + keys = g_key_file_get_keys(priv->keyfile, groups[i], NULL, NULL); + for (j = 0; keys && keys[j]; j++) { + char *s; + + /* Lookup the value via get_string(). We want that behavior for all our + * values. */ + s = g_key_file_get_string(priv->keyfile, groups[i], keys[j], NULL); + if (s) + g_hash_table_insert(priv->keys, + _nm_utils_strstrdictkey_create(groups[i], keys[j]), + s); + } + } + + nm_clear_pointer(&priv->keyfile, g_key_file_unref); + + return TRUE; +} + +/** + * nm_vpn_plugin_info_new_from_file: + * @filename: filename to read. + * @error: on failure, the error reason. + * + * Read the plugin info from file @filename. Does not do + * any further verification on the file. You might want to check + * file permissions and ownership of the file. + * + * Returns: %NULL if there is any error or a newly created + * #NMVpnPluginInfo instance. + * + * Since: 1.2 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_new_from_file(const char *filename, GError **error) +{ + g_return_val_if_fail(filename, NULL); + + return NM_VPN_PLUGIN_INFO(g_initable_new(NM_TYPE_VPN_PLUGIN_INFO, + NULL, + error, + NM_VPN_PLUGIN_INFO_FILENAME, + filename, + NULL)); +} + +/** + * nm_vpn_plugin_info_new_with_data: + * @filename: optional filename. + * @keyfile: inject data for the plugin info instance. + * @error: construction may fail if the keyfile lacks mandatory fields. + * In this case, return the error reason. + * + * This constructor does not read any data from file but + * takes instead a @keyfile argument. + * + * Returns: new plugin info instance. + * + * Since: 1.2 + */ +NMVpnPluginInfo * +nm_vpn_plugin_info_new_with_data(const char *filename, GKeyFile *keyfile, GError **error) +{ + g_return_val_if_fail(keyfile, NULL); + + return NM_VPN_PLUGIN_INFO(g_initable_new(NM_TYPE_VPN_PLUGIN_INFO, + NULL, + error, + NM_VPN_PLUGIN_INFO_FILENAME, + filename, + NM_VPN_PLUGIN_INFO_KEYFILE, + keyfile, + NULL)); +} + +static void +dispose(GObject *object) +{ + NMVpnPluginInfo * self = NM_VPN_PLUGIN_INFO(object); + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(self); + + g_clear_object(&priv->editor_plugin); + + G_OBJECT_CLASS(nm_vpn_plugin_info_parent_class)->dispose(object); +} + +static void +finalize(GObject *object) +{ + NMVpnPluginInfo * self = NM_VPN_PLUGIN_INFO(object); + NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE(self); + + g_free(priv->name); + g_free(priv->service); + g_free(priv->auth_dialog); + g_strfreev(priv->aliases); + g_free(priv->filename); + g_hash_table_unref(priv->keys); + + nm_clear_pointer(&priv->keyfile, g_key_file_unref); + + G_OBJECT_CLASS(nm_vpn_plugin_info_parent_class)->finalize(object); +} + +static void +nm_vpn_plugin_info_class_init(NMVpnPluginInfoClass *plugin_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(plugin_class); + + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + /** + * NMVpnPluginInfo:name: + * + * The name of the VPN plugin. + * + * Since: 1.2 + */ + g_object_class_install_property(object_class, + PROP_NAME, + g_param_spec_string(NM_VPN_PLUGIN_INFO_NAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnPluginInfo:filename: + * + * The filename from which the info was loaded. + * Can be %NULL if the instance was not loaded from + * a file (i.e. the keyfile instance was passed to the + * constructor). + * + * Since: 1.2 + */ + g_object_class_install_property( + object_class, + PROP_FILENAME, + g_param_spec_string(NM_VPN_PLUGIN_INFO_FILENAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnPluginInfo:keyfile: + * + * Initialize the instance with a different keyfile instance. + * When passing a keyfile instance, the constructor will not + * try to read from filename. + * + * Since: 1.2 + */ + g_object_class_install_property( + object_class, + PROP_KEYFILE, + g_param_spec_boxed(NM_VPN_PLUGIN_INFO_KEYFILE, + "", + "", + G_TYPE_KEY_FILE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); +} + +static void +nm_vpn_plugin_info_initable_iface_init(GInitableIface *iface) +{ + iface->init = init_sync; +} diff --git a/src/libnm-core-impl/tests/certs/ca-no-ending-newline.pem b/src/libnm-core-impl/tests/certs/ca-no-ending-newline.pem new file mode 100644 index 0000000..664e299 --- /dev/null +++ b/src/libnm-core-impl/tests/certs/ca-no-ending-newline.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv +bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv +b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH +iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS +r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 +04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r +GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 +3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P +lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ +-----END CERTIFICATE----- \ No newline at end of file diff --git a/src/libnm-core-impl/tests/certs/pkcs8-decrypted.der b/src/libnm-core-impl/tests/certs/pkcs8-decrypted.der new file mode 100644 index 0000000..2cbdeb5 Binary files /dev/null and b/src/libnm-core-impl/tests/certs/pkcs8-decrypted.der differ diff --git a/src/libnm-core-impl/tests/certs/pkcs8-enc-key.pem b/src/libnm-core-impl/tests/certs/pkcs8-enc-key.pem new file mode 100644 index 0000000..0d08f2d --- /dev/null +++ b/src/libnm-core-impl/tests/certs/pkcs8-enc-key.pem @@ -0,0 +1,29 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIE6TAbBgkqhkiG9w0BBQMwDgQIwiGFT4Jz6RsCAggABIIEyJNMddDYofbhydUp +J3VyrYIjv3LziJ7dkTXE3+mEYRCQrGLgljWBbib2JOLVCFt8melL6Yv1RcoVR7X7 +vrRqyycu0DumI4f5+Bf4wc234JNVhSaLYsw244fFtcnK2Gyn4IaVmWmrNvrwfX/w +SKcVmO30D5C5PCKzv2bou5FmnJLKdDQV1t816cr9T8pTx7MHvBzSZXbh86334BhF +T3zNwo8j2/+Gq2NBWUn+2GTTV8/r26aIwPcFi4QH6I2ghBwFmFHqU3/PoRm6nkmg +CqJj2Dggy+8zE5qg0iId7lrio0OjCH+Qed6NGwIa2lgv/bhuJVP3FOk4gqamJWHi +WMaq9McmS+03q2iokYeSQGbx85x+I90RTFZKhFx4dkerf6oTC/YoL4F++ff0e91v +sOrQsBkgRhrRtFwa9OFCzbsknlixONdd+ITkyX490xz1wcZTDkKtMDRLIPWa2O0b +MEq75jPYThZ5pF1vc5r+rqPafN7SfI+DDmhzJYEQNRoCWA4pH9Gwv0ayKnOgoj4K +TuFhXvcyWzTnVXmcqEFyf3CRrB0Ti+Z61enupC+FCuYV5lGsx9kJaTumTk2UPD02 +9Ap3asDLozdEPSXBG3+oCM2s01/IJlxtR84C97r9rpmWTc9K6DCBScETe9KnIghW +PU7XFogueG5Gwpe+x+IlTDq+qiyUNVX1uMGDcIaCC3VsoWqZrpnGGBhsovwBaXKt +T9fT2nE27Fd6DRWso4fgos6PPx7RVveu17BTMVQeUq9L8GrV4JNrE3a9aoXdbUhc +6gMiyAqxh/HEyciYoXsR9oVNi+VM0y8q3hL5nIcgDrCZr/c9aQ8+fuQBDXRrmrQd +bR2iwNLCBnbmQmM/vM333VhJ4MSOKd3SGw/j41K+Nr3uP5KRZUwV+5yy3ef/hGxU +i9JjCmSUt2bfWRUFlNaf1hCTYaKD0xnVr1SLFU4snIgh2qKawyqVc9EE2f+FcOM5 +0RtwQ3ku6FOk3cy6/xeKpResCHbWDS6nQaIKYyLukV+gm5MJIhOMkj2z4T1eXGUr +Nu/L7Gz+ps7ct0lM8W82n5lzSEa5/l1eNGM0wtQoAwutFEZp7Nx/IBKK87jVttr6 +82UVJeRk7rO2Mpobfw2LbKwga4rsuLrx3UwVDBWdLx7dNIc1rGoAxhsc72+skFgF +Uztwy4Yv1Uiji4T6v+mObPZD/HiIDL0vF02Pz08rNlgB0DgaTKrpql2FutIuQAdf +AciffQIoh9VGERlJoWuunG/UTxg2XRl2m1vCDrgBMInax+PXCv7/5Vh21AQc3fWP +uf4k6JSy46hYni7VTVKn6C/Di9z7oIrGl/jDkDsaenAbToyX9VWr3s7EBwnhTQ/I +OQ9bkWCagHIQlwJbu4M4/VAbiR26NrcR0C3JXBlPlT0qvFFB8gKbJAQEXtwIFS2h +m2fe0k6mQASMwdbJYXZ/wfsg5PPAWsKtny1aMvi0mTPSD5uRhIfEGEuR+AT4UbEW +BkEIE0lgGly4P1SpunKDQQE6m/e7h8Nl4pi8SMSme3YoX5MJwCP/CNkLBDVenAZI +oBrdoVox86SjwnUozVG192lcEAULlk+3ZGt6T9JXLBQl9hpNtyTC6SFh84R+5RoN +AevNl1bDfO+Vci0uJw== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/src/libnm-core-impl/tests/certs/pkcs8-noenc-key.pem b/src/libnm-core-impl/tests/certs/pkcs8-noenc-key.pem new file mode 100644 index 0000000..f73fb55 --- /dev/null +++ b/src/libnm-core-impl/tests/certs/pkcs8-noenc-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC80HGgFdlFIL2F +W5rHQ99xOkMrWcZ7an9YurDebAE3M0UwqxM24+5mWbxc8FJ8yYugdMzuI5Nq77IA +DwJpv9ZjMfnKC1VDMj3bmmMdPurfx8pLdLw/jhk3wBaYk6vMvh4z66Yvmb7valGq +Pxh6CRTnekNGI9XA7me4JNBlisl0Qasn9g4pl9PiGJAruEamS4Pk6dSWbfw58bs7 +/Yo5ejyt/Mn1n0Q/r3Gv/lAS0qRvmrW6GE1rMtANMfuGRNlAln21TzNcJzykm+sp +RWptxXEI0NY7u9+RP4M3C1mJxWir7AZDbtinpOZH6vF+92yMzgEYOLK/WZVdSPdW +tROv9xtPAgMBAAECggEBAJAfp+vjYZJjuGaYEuAxjdhW+biYcWn5U7V9484TsSXa +i+DnZOZMO8iCjMaAZuZ7zYmwPlE0dK12w29KBbSEy3eySRIRboa5TgBXq3pCcXRZ +g6/vLlZw+AzXIiha6BODt3g4UwUYnWcQx79lJCDa18sNR1a9ucbn8+Har/wiYT3M +JjTbUT6wR6rKEXchB58ZugYGhOTfugSDQg4U/dwEHPIaJ/wme++JUV5B/tjeGCG3 +F43o2Oos5vjfrDSpUKIYZn+2BdhP434jkwj22wQ2sy0ruU/kQx8nogMTRfP1v4GU +9QmNXj/DB24K388ZxcDmcxBJxrGAJ0MohYFo28DqRBECgYEA6hyKEqe2UbJx/+B6 +8mYgHb+pS2j0M4jPl11q9MMLVxLnDY9xZ85IEyWHQEC0GavPSAois0oiDeGAm32c +j6TFyV3/oPTmZSyV93/agWgnH9Xtc481pbNAb0GMfyotvRRE/+6ti9+Cl7oH9Qmm +ldMk7Hn6sK9t2mUOW8idPjKqlqcCgYEAzne25BryLJoIinbRMZg9KTfxfgUE6EKc +Tk5+9CFQn0/AItQJuKbIUyggYH4psWW5hWq6hFlmMYMR48FKv9ry7pZTB0djaoYD +lN+wSuhzUYWXedkAjvPmekITmf6rbnPfwOZvsr8CGMEUekqJPnPLzsQy+Ea2y/fb +QY4SHe7gExkCgYEAr+1scOJpZvFjK7ckjT3jipd6ADpJsORxo7zG4FImFnQU/6K4 +xRpGHWVJQyaccOIkrW04cGUYPDgmrjJx0ZwwKceijvEaphMgS1JgAHklVY4sl3ea +CAAxPqoSi4lFv94Yj/9rmT4IZD6fNivfbJ20FKUBl37tXX4tkRmr2I64lOcCgYEA +x3eqzrclrmdlxvfBZOuScwbkHP6WXhk0TwbQ6eRhsnfmxP8bITSoJoaGuRJKD2Oa +l0WkSobgDwd0uhecsrvBpTS/pDGY32n3fdWZyNTHzEOHMyWtv23tBcJek5ERaBU0 +X3WBBiw4x1eKBBeMfjR6+xhbsbcHlQiw36V05UxJWMkCgYEAhtcYvrfU4K48IJTU +qp03nvd+dMY3IUTdZNOCh8bswLKyn3aq3MfWF9Vp7kDAI3cfyMpSrAQnmg4nVcn6 +Gf3wakG8bpiSRbJnGN+iLm8JsD+3Vw9KzvKOOQVmpT7xt5Kupx1hWvLHQWvfYgOG +qEtTM8/+LD7W3I7midJNt50CD8A= +-----END PRIVATE KEY----- diff --git a/src/libnm-core-impl/tests/certs/test-aes-128-key.pem b/src/libnm-core-impl/tests/certs/test-aes-128-key.pem new file mode 100644 index 0000000..aab8f46 --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test-aes-128-key.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,800391B7DD72364B4C2562E0B6AEA000 + +E9dgNCIATOr4CN5c8o6B+8wdqq/I1BLmPmW2qT7YZepoF7E+RUb8ZLjo1VO2XsJw +Ir4EzuH7837zBD9dP5CjlY8cWfR63gZpEWRY5Jub8kzvqiL4UZ0Qr8IHOZxAkKEz +EL1Pn7e+tYt4kA372LPZHWO3vRCgmL1iSJj2/k3avPWAx7NUie4bzGI+00WNv699 +ClKzsJbWB1eiQvYgOr4aVV26oWfa896JkBoGhgZQ6ckqFpsdAos8m46iOSVZrwgq +Y2/d1CvfQod+87c8LRatwAjf+d6YAJJaeMyxjCGuAY6/JyDsorUkM2OlvbTt6WOA +gSPWO8I+Ov6THb4IuPhpIJ30Sl88tc6MlIByW49EWu2G1jPw3L8iqRzZ50Z85dyz +N9yFP91wEwi5F0Zed4iEpg3NVfklEe/VYqCldc5f9fZ84G5V98ZlAdNSqwd/UNBU +iPTflGqVpp1u+J2isOk+Agpj1MCxh2q0RNuvY9KHzOYBScirfbG4DKNbQgS/5Zw7 +3g9YL5Wbo7BczHLiXf/2adu6T8wI1LKRjkeLV9dK1Vw3ZaGy3mB9oFhCgjh9BNHw +wC78CVcUErjtOXdQagiCQn5k5EGeAB97QFROoAFjAmGvq3xCi4EHd9Sk6fcMm7Oi +1fuVR5EXUubF4Llq06lFzQp01s2F73noH49bs3qwdf0n8nrL2XhKB0XCOV/I3K5c +Y3W+YSl361QGjZ/NUcFLIIy+Uro90MmUBNk6af+wGHRJeflpVnK0ATX1PtpNHziz +jiMiIZicjgfVLxl1a5zTl6KUmGWKlZb533adQ0s6q9Qmi5Vk5L5W/GdMjcFtZbM6 +GU7EOkwihMLb3DVsNbm7vb8tUXqe/e5RmXtij8Yb+2a6/M9yaOHa0VjHzdiKHecr +eEYaKQDj7NCWLslNnRRh9GmgXcu2pqBhqRM3HAt3cEaHKKWHTcoWcz11pFwMHNtn +bU9GjGRVc3lCGhVNRiloO0zrKHmcBpDVLw2+ycXXpj/RaBW2fy0xRLKolyla+jEr +zdLzVI61O50ZMycOtPmE7DVZpkokn32hGer1eCOFnsN1lywi4cWLvU0jbQC+CJyw +T9vS8zB3WgOl8rC1AHsfQ4KYajlKleQm89deurQymnt/Qx49SiQA+TpwG9Xvx2TP +3Vc1NwZfM9ZZ1+6xit/rTuS3LhnmhEnGnV5ZyvAdmkCcV2iHjOnLnQWWQn24MHU3 +8Y9D4AdpI5V7Igwr3vH2NZMiw1W2Yc5EJuPAT8nIs5sgOYhXB/QLPJvulvOQhuNC +NPwJ6A505JrVNfHuEaoGUyA+mPeWuLwQo8y8cM6ZdFMG3RrwFNzuYTrc1Z/9GsmA +C0UfHf5dL0r7oWZ1SbpSvsmHYqc8sIypq0ohuLEbpegS/hWP8b2/XDRTjfTiJOrM +4LsUH9PMOJSxDlwS+7e3FdcGfgXfsMgB3aOjQvNpKEolOuv4A5LVFeMrrwtw4Xo1 +EuhstZwyarUTJenDUXzkakhA+8Yw/g2a7RsnANVTkeBuv2PbqFL4zdlsWvcpkz41 +ESxx1siSeU1E9beOII0zSi8vUD0IAevRHaWSlfU2po600IzX1FN97pa4DJV2ycgn +-----END RSA PRIVATE KEY----- diff --git a/src/libnm-core-impl/tests/certs/test-aes-256-key.pem b/src/libnm-core-impl/tests/certs/test-aes-256-key.pem new file mode 100644 index 0000000..e51bafd --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test-aes-256-key.pem @@ -0,0 +1,54 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,5FF6BD2D4E57E8933D4A6814DEF5305A + +9Br+xw6XOg7qUqfeE5PJ4g/PAm7eTcPMb4FzSKkaEosLo6oj4f37TwXuojJZeAmi +1EytpqM1vdYHCLdjg+qYaTIq6mzMZIyoaREokcOhcNrq5S0J39gJLVV9LjiXhCAH +GQgDBnbRT6HGz70AyTRLcW9aj6uBzTv/m92sLUw2txFeBXK8n2AA1oHJTgsFNYjf +/ZvTCE1VMQHDPx31Vn5WXSUHNc0hx4MTIwpHqWI17ohr8IiWCs5HXVfVaqrNeNEw +haD7fg8oNxjLs46/4dDWmfWXhDsMFSweZv03gZdyVjwn1IOqeVGmTdLpllfgOW7E ++XE8Y/d55s5nkOxu6eXNMtWgjclKBGr2iMxxnODmEsUt2WcV98cPS+25o3hOfy3s +NIcfxtWVRFUtjqf3ragyGLuXFqATkj1slj4LVMeewRJ1g+Z6ti0mwBN+ZrYtKdec +FRNb4zr5FW+3SqkIIJVfxJEYJDB4zODhMg8tySEHLKuT0uz42YQ4aoOHTzO5WDBY +2BI7TjRppXcExPnkAk5jqbKA6BjT9KcAVyypfxDKvCeXKdjDcL6ISOBSm6cQBh8D +HxsFzMy9PF6kKNeiNiEsVPnKYvhvs1hTBtp+IAgJ6KZnCDKplZFxo/mBAlV2KyCT +x+Mhmme3fXdLJkvxlVJAoAhwgXvomVCVTGI3JhcQIqVgxPIKYpqlHVFC7JjG+yQX +tvzCPtr9G9+Ofrm6zXjlDD7zNyl/KfFtEWhO2ePHkQlCEuKJnsnRIf/wQ0viG0yY +MH31Z/84o2pKLBKY5fq8+eYuYoP9Rk4W2LpjGMvdkKhEHL26kZofeFyqD+JcaxHc +kQh7/SbWAsREGb9Jp7I2q1mo749mse1oSFIQa5gN3jB0mgHZd6edRYeW2Up+rqEK +k6Xd6uqs7bZd5W9sP7Cf6yJOFEjqFVLQEVEXWSchgeta/JNrjGr3UzLFN2S+vhvX +XgDa41y2UdXHRqj2s864u0ZDPyGXYZnVbvQn/8xHQ7rvxHowpTn+XXUEf0AQnk3j +9h++3McwP8GuVxkwc6o9TfOL+ell5jup7F3SekwEiE3hqY8x87g6X2zD5VSnfCy3 +0t0LmPGI1b3LABeYjA1WEdhoTlHrNLkwOR4gsudrJ5nxIzfGy+IHaloXLJy4YKfX +pJ+qyGRUR42YD9IhiEmmmO1VoJgVEYfBiz50Jg8emddku6eKdmv9IKjiSb2pTbDS +4oUYKg109OOn+krk67dNXofAXrBa8v7QusC0yz9N25H05Xyou1iqpGk+uBrTqEO6 +lW9lWQo57BQU9og40xMKH/xQgIxfQRktUKsPizj8mKil4izo5KgjPSqBeEbj+Q3c +0FKlrpTXQlXfX5Z5esqMuCSiwQEzoJR+V+SUaSVcg1av0k/CJMin4Cr8roai+OjK +lhaQIvx35Bzd02yERYsfpDjmQCXmIeiDm8JtB6znbQPUJ4d8kzWR+5ACOZW/dUss +YhWJRkZpkIwTY+/sDU4mnP2R37MNo+OH4CwZyUDHjlkRPGW+6JBEpnnlI9a/1Vb1 +pjAGpi/8u/luvZGTzCzxQG2dZc5YQR869U+wFsFbLRiD0aP2SpdOH0QxxPOcdR8+ +HWyL01BJBKyK/wZWJhe+63zlk1L5CA0XYpoNkYpMlPNZkcqR7QzUOATfuBgI2aPM +AXaweaAWhpPCDsc2RypIs9DhTiCCkt8tq8Au15hVUKAoshLeewPtv0t75MEC0hVB +z6FVnNlqq0cqqcSVqvUG6JUGtFOGgG3ifEMXggq5k12+wGzY63DLR8dFPNpOL6/1 +nocOayHJIU9M8PP817PzhAUAePRRUKRg8kkbKKeZnCJxoF7O15AFVEJnl9Vyokkz +bULYhzYVx3xh8THMi+5jsnKWPJyMeYHbHH3C658SIw6Ff9fgEWscv5ZkGYdKMg+l +8hBn+++SoqIO+F3lOGco+s8qlYox106lUwJEtORXcBxmkaHSo/X2AVO8Owt4vYli +mjWnY6V9vooBgOuCMcY780pcoj2lSf9JPHDYK0j8t5VumDUSLyLt+tCj0yv/vl5L +9L++vbu2akZRC9ChijYpfhTvXoG36ePhoT7AGGnhpFjjw1VqG80GY4XSODKzH86w +kUcZoErb8swUPYOtsybtuPb+6c/YofQ8GfpVosPZgSRD4+U7v+zA3/z8xF2B0xt6 +uV8hXbropuni8KmbFuKrPZK3p2v2aZ8F0+GITwS75/hbT6D7ruUSr5q4V0VKeE8G +k3QSI0s6+74stPv3S/ByCxu8q51ffYqVw00wzPpEc4SmHEa0R7IczJKXupmDdZZM +1rASSBNzS5TZDBXP6S7npYQ8nHhgXTdCFO7eM3bp24B/i2o0s7+gkKrz0DkEbv9I +UrCJjTL8OIIP4qSLMILzZ8pB28c+zyM482ZqFY/2b7j6WlTiqa9P1adrD1gLxTQ0 +Sw9xY+sY3PAJqcnPA5NjDZL/h5plgHhCqDa9pEtdBVG2Mxcl9bXbphwD1MIzj4gr +xtlW1HUJ/iOhFcXldOJ1MCt++Bm5av4mL5adQ/oUnL5Q0oZZFwqT09k7xe7lZ98N +uj2Lfl8NN7N3ama9KatgbX5g6IALuk/rJN/4KEiiu24m+lR7c5L0pg/cG6LIFjmk +HlTsc0ANCgeZBhDJ8kvjcXDhFOqoYE/+D2VO6ZEHRsDibQ+kjpaH+DiD01/gh0N0 +HM6GGtm3GbOyZUhw5OFz04xzcyFYo2xaqzgaZieAOcrt2s6XyPVf1gww08/HtTMR +gLg14MUQvRXV6kPJfdu4OLZ//b6J0KnzVyLDRdOrWIj2raLWmKwQN9qv05/yskcD +Y6x7wq3v6iZpFjDc53sslhwp2XRsoWT9X5alVspz8WvP/kqgkTdzpPFdp1vIovOQ +kRXdzzKICDGDJUIcTL8cJ3Dv4XqNR/sVyuB4dfndzQQApbdYTDNpwX0VJDBjMkQy +Up6aiUknxa6Cbp7b1ZfUQY8yNBAIZL+R8dmobT3nAHW61DaASHSxn+elCD2Ja/6b +EiWikskyN6crMAv35ILr5ySsZK97ttNNmRoGFbt8bTjRd83Ie+UfH445kCKsY83x +aDCvWm+bbV6M9rSgjhJ3bWOudiw+EBMGvSamSnS7CYnRmwq4t+4bM2sh2nYKY0qw +-----END RSA PRIVATE KEY----- diff --git a/src/libnm-core-impl/tests/certs/test-ca-cert.pem b/src/libnm-core-impl/tests/certs/test-ca-cert.pem new file mode 100644 index 0000000..ef1be20 --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test-ca-cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjzCCA3egAwIBAgIJAOvnZPt59yIZMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD +VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw +FQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UE +AxMEdGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAzMTAx +NTEyMTRaFw0xOTAzMDgxNTEyMTRaMIGLMQswCQYDVQQGEwJVUzESMBAGA1UECBMJ +QmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55 +IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3 +DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAKot9j+/+CX1/gZLgJHIXCRgCItKLGnf7qGbgqB9T2ACBqR0jllKWwDKrcWU +xjXNIc+GF9Wnv+lX6G0Okn4Zt3/uRNobL+2b/yOF7M3Td3/9W873zdkQQX930YZc +Rr8uxdRPP5bxiCgtcw632y21sSEbG9mjccAUnV/0jdvfmMNj0i8gN6E0fMBiJ9S3 +FkxX/KFvt9JWE9CtoyL7ki7UIDq+6vj7Gd5N0B3dOa1y+rRHZzKlJPcSXQSEYUS4 +HmKDwiKSVahft8c4tDn7KPi0vex91hlgZVd3usL2E/Vq7o5D9FAZ5kZY0AdFXwdm +J4lO4Mj7ac7GE4vNERNcXVIX59sCAwEAAaOB8zCB8DAdBgNVHQ4EFgQUuDU3Mr7P +T3n1e3Sy8hBauoDFahAwgcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDF +ahChgZGkgY4wgYsxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO +BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQL +EwdUZXN0aW5nMQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRl +c3QuY29tggkA6+dk+3n3IhkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC +AQEAVRG4aALIvCXCiKfe7K+iJxjBVRDFPEf7JWA9LGgbFOn6pNvbxonrR+0BETdc +JV1ET4ct2xsE7QNFIkp9GKRC+6J32zCo8qtLCD5+v436r8TUG2/t2JRMkb9I2XVT +p7RJoot6M0Ltf8KNQUPYh756xmKZ4USfQUwc58MOSDGY8VWEXJOYij9Pf0e0c52t +qiCEjXH7uXiS8Pgq9TYm7AkWSOrglYhSa83x0f8mtT8Q15nBESIHZ6o8FAS2bBgn +B0BkrKRjtBUkuJG3vTox+bYINh2Gxi1JZHWSV1tN5z3hd4VFcKqanW5OgQwToBqp +3nniskIjbH0xjgZf/nVMyLnjxg== +-----END CERTIFICATE----- diff --git a/src/libnm-core-impl/tests/certs/test-cert.p12 b/src/libnm-core-impl/tests/certs/test-cert.p12 new file mode 100644 index 0000000..ae4a683 Binary files /dev/null and b/src/libnm-core-impl/tests/certs/test-cert.p12 differ diff --git a/src/libnm-core-impl/tests/certs/test-key-and-cert.pem b/src/libnm-core-impl/tests/certs/test-key-and-cert.pem new file mode 100644 index 0000000..dec9aa1 --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test-key-and-cert.pem @@ -0,0 +1,118 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,4DE0615F23D82107 + +QPNCO5Dobvz9dDhN32KkZRoEifW+HDm2PCbRQhKDiscGwB6LgypvVjHNsZiFKwzz +L4R51UqgQeJx7GSGJqE626e9z9J+UNBhop02aOO2X0eSPdvBzr/uJ6Umiyr1xqD7 +zWf7u9l5kXElDJRhK+87GMBewp4Ie9NeXDjhF8hzC5Kiulen4AH3AYnfH3S7DimU +h8GFMg8inrudrTbcjBhCdPeHG2jCygOxw3InRFz7uaN6LIhOaPQvmvpP4Cc1WRnW +ZPq9o+eU3fPWPD5t+Op/VzYLvKwgBy/yK1rQXUm6ZMO7MhhRJ94ZCsJv+nVWpJlv +QyBlxDKxwfkfYbDELdnnDQdHdMbKatLqa0KhSkgpp8LywBtanPz731tyT0r7b3na +eLdra59lRU7ZQLPEdS3lPZd2O/KQvWf8wbg7MjXS9LxQ7R5HOPu6DNJlwXVZBmmo +cAfu2q8ubU2IePvWLD1GOrBi6hE9TiGvFJkw+wBK+t72sz3njv9Xm/zlxruaEk5m +RW/kybU3FP4PtjriBbskz3/VZaaxuRN7OoOYTkmyHmG1ADgcRUV6fea19qqsBlN8 +xb+SRtoH28oT/JVWU5neE2dbNzk5LeVO+w70NNdR5s5xqkBhbGGaJxvXwNP4ltFr +T06SMh8znOLKwWB00aRtwfU7jOwR3mOleQO4ugIHmau3zp1TqzAHW8XtpuV7qVeI +ESZOZuf0vW43BtNzgLXt1+r+bmsMsRwhnyomL9M0TUyyBdVYY9GkzTG9pOESheRo +RSvAZ8qKGUliTpgBcbt2v1+NqkszcHa6FxuvS8YU4uo5/GqsgTxHTNIB232hIrrZ +EIm6QL9TC5oFXMjy6UNqoCm5Nb8DBJ6aErt7pt7aoktqUW3O3QIzQT3IbZ4nAcTt +lVF4d7j29I9t7bcC8GOVU1neilguZUss4ghJg9x4zI5UZdR7hZ8fbFT47TyxB+j5 +r0YdmjbjVTaSyaN2JGh1wvb4TzawGNVx/U2EJE16HigOtPfsfQRJ3x+FROKBdVa4 +aIFYXkRBeIPxX6n9pcw0lBCsnXo6/5iTjQSk2VqO3rHO/wyWiEjNczhL33dY2A8W +GG5ECMO5SqXZHQQzpABqK94dxe3UC8aEESO5NhEqDuV7qQGol0qPKrUA3wb0jb2e +DrejJ9HS2m1SUDmjpvvmEGy6GN7CRibbKt5rNZdJNNvWArOF5d0F6wkixQLl73oE +lq5gLQQk9n7ClleKLhlQpBCorxilBbzmSUekkJLi0eaZiBBFWBX9udqnUZloXTgO +8qwuO8K/GPR9Jy1/UH2Vh1H+wivaqKTVgEb0NotzgzECgTEFKJafl7rUNs1OZRZ3 +VBjevi6+iDpxVFgF71kXfdUC4ph0E1XDl0ja2rrKQGivMkUhWJ57+4EV5+hBkAnt +G0RV45NwHXLrK2bd8F9PlRk2XHW6mIcFRXsW1DjeBhk/sQjvlO9R01GRSgcXtekJ +tmX17FWrMrzXHpvy1IC3fk4RVnSjpzQ8O+17YE8/la9wVaeZZzHyYFmMT7VXjIhW +QozJQ0vJ2jxJRh5GYn3tpJzdaeRfvTBik0pChNdUTnWP+BJ35xoCTs8iwJbmgVZ1 +-----END RSA PRIVATE KEY----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=Testing, CN=test/emailAddress=test@test.com + Validity + Not Before: Mar 10 15:13:16 2009 GMT + Not After : Mar 8 15:13:16 2019 GMT + Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=Testing, CN=test1/emailAddress=test@test.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:cd:34:b1:2e:b0:04:c6:f4:2b:a2:c0:a0:39:7a: + 82:ed:96:c4:f7:19:83:91:5c:b4:e7:9c:de:ec:48: + ec:2d:e4:51:08:26:42:ac:d3:98:26:7a:72:f7:49: + c2:9e:66:05:c6:47:29:fe:3b:ac:6b:af:6f:5e:a8: + 03:5a:73:33:ba:19:03:00:35:f5:00:bc:a8:be:14: + ce:46:69:e3:6d:ed:34:37:85:55:87:62:b3:b7:c9: + c0:cc:9a:aa:61:05:5b:cd:a2:17:42:d3:e5:6f:1c: + 60:8d:c2:15:41:46:f8:12:54:d0:38:57:e1:fd:8d: + 44:c8:fb:56:b3:b9:6c:e9:f8:9e:21:11:57:1b:8b: + f9:cf:e3:17:e7:d8:fd:ac:d1:01:c6:92:30:f3:2d: + c9:d6:c1:f0:3d:fd:ca:30:dd:75:74:e7:d1:6b:75: + d8:c5:4d:43:61:fe:f6:ad:7e:4c:63:7c:03:17:a2: + 06:8f:d0:8b:69:d3:7a:07:0f:0b:a2:cf:0c:70:38: + ba:cc:55:35:60:84:58:d8:d2:be:1f:ef:76:a9:ba: + ae:6a:dc:08:97:80:de:42:00:b7:d4:ce:9a:b0:36: + 2a:c7:6f:45:04:7c:ea:41:19:d8:b9:19:04:1f:11: + a9:22:80:bd:69:08:15:0d:3c:de:cd:7e:88:6c:0f: + a3:43 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + CE:03:7E:EF:E7:DE:C9:87:BF:DE:56:F4:C8:A3:40:F6:C8:6F:05:8C + X509v3 Authority Key Identifier: + keyid:B8:35:37:32:BE:CF:4F:79:F5:7B:74:B2:F2:10:5A:BA:80:C5:6A:10 + DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=Testing/CN=test/emailAddress=test@test.com + serial:EB:E7:64:FB:79:F7:22:19 + + Signature Algorithm: md5WithRSAEncryption + 7a:20:93:63:40:73:7d:33:01:2e:c0:13:52:a4:a7:e1:4d:82: + f4:fb:b2:7b:d0:2b:5a:3f:0e:3c:28:61:71:ab:01:4d:fe:89: + b5:cd:2f:97:59:93:53:9d:51:86:48:dd:b9:e4:73:5e:22:0b: + 12:0d:25:39:76:16:44:06:0c:40:45:21:6b:a6:b1:e0:bf:76: + 1b:36:f3:1e:41:82:57:d9:59:b7:60:40:43:1c:1d:79:f6:48: + 32:5c:4e:e2:06:89:96:41:d2:54:1f:4a:6f:f6:78:a5:3c:02: + 85:21:e2:65:e1:8a:6d:24:19:95:f8:c0:35:ab:bd:ff:3d:f1: + fb:50:2d:30:1e:67:a6:7c:50:f9:d5:77:66:77:5a:14:0f:5c: + cd:21:09:9b:a3:92:57:19:dd:01:a4:18:c5:f9:70:e4:17:43: + 8d:b1:e6:61:e9:50:89:83:4f:ce:a4:57:68:58:40:70:ae:71: + 1c:47:66:d2:30:54:50:ea:3a:87:32:64:3b:18:42:fe:5a:19: + 07:64:f7:f1:b1:10:07:fd:a7:d2:a7:a8:05:79:5b:25:ba:69: + 7b:1a:3e:b1:3e:e4:17:17:01:ba:eb:54:ae:83:00:ed:66:62: + 8d:c0:3e:8a:b4:27:5f:e9:01:ce:20:c3:34:a9:28:c0:6f:c7: + 3b:65:fe:f9 +-----BEGIN CERTIFICATE----- +MIIEojCCA4qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCVVMx +EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO +TXkgQ29tcGFueSBMdGQxEDAOBgNVBAsTB1Rlc3RpbmcxDTALBgNVBAMTBHRlc3Qx +HDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMzEwMTUxMzE2WhcN +MTkwMzA4MTUxMzE2WjB6MQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJl +MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzEOMAwG +A1UEAxMFdGVzdDExHDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNNLEusATG9CuiwKA5eoLtlsT3GYOR +XLTnnN7sSOwt5FEIJkKs05gmenL3ScKeZgXGRyn+O6xrr29eqANaczO6GQMANfUA +vKi+FM5GaeNt7TQ3hVWHYrO3ycDMmqphBVvNohdC0+VvHGCNwhVBRvgSVNA4V+H9 +jUTI+1azuWzp+J4hEVcbi/nP4xfn2P2s0QHGkjDzLcnWwfA9/cow3XV059FrddjF +TUNh/vatfkxjfAMXogaP0Itp03oHDwuizwxwOLrMVTVghFjY0r4f73apuq5q3AiX +gN5CALfUzpqwNirHb0UEfOpBGdi5GQQfEakigL1pCBUNPN7NfohsD6NDAgMBAAGj +ggEfMIIBGzAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy +YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUzgN+7+feyYe/3lb0yKNA9shvBYww +gcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDFahChgZGkgY4wgYsxCzAJ +BgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkx +FzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQLEwdUZXN0aW5nMQ0wCwYD +VQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA6+dk+3n3 +IhkwDQYJKoZIhvcNAQEEBQADggEBAHogk2NAc30zAS7AE1Kkp+FNgvT7snvQK1o/ +DjwoYXGrAU3+ibXNL5dZk1OdUYZI3bnkc14iCxINJTl2FkQGDEBFIWumseC/dhs2 +8x5BglfZWbdgQEMcHXn2SDJcTuIGiZZB0lQfSm/2eKU8AoUh4mXhim0kGZX4wDWr +vf898ftQLTAeZ6Z8UPnVd2Z3WhQPXM0hCZujklcZ3QGkGMX5cOQXQ42x5mHpUImD +T86kV2hYQHCucRxHZtIwVFDqOocyZDsYQv5aGQdk9/GxEAf9p9KnqAV5WyW6aXsa +PrE+5BcXAbrrVK6DAO1mYo3APoq0J1/pAc4gwzSpKMBvxztl/vk= +-----END CERTIFICATE----- diff --git a/src/libnm-core-impl/tests/certs/test-key-only-decrypted.der b/src/libnm-core-impl/tests/certs/test-key-only-decrypted.der new file mode 100644 index 0000000..c865253 Binary files /dev/null and b/src/libnm-core-impl/tests/certs/test-key-only-decrypted.der differ diff --git a/src/libnm-core-impl/tests/certs/test-key-only-decrypted.pem b/src/libnm-core-impl/tests/certs/test-key-only-decrypted.pem new file mode 100644 index 0000000..1a25da5 --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test-key-only-decrypted.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAztLp+/SkzmaHzIst0sO4+r7qUwiVnidKBHgxoTbS5UL1dvck +cbjTEP23V4ZoKQIb6ZMrr8B+PVgWNBAlhX4oLUL8NH/WTwrntrlAUcjliWDNc1Fj +Z+FZNjFe0IdLXZeKQiLTQvKDYnmERVvYIJfi0TQjXuy/ikF8rYBQ85scUV3kKRzB +xnyhAHAP9nl3AyL1S6t2yiCr4U5TbIZo6dYPbpVLtbXP02zUc9vAPR0gIHKrPiW7 +P81fLXf91wuo6wxzwD90JxdWzzGaqe3BOSfHqul3SPRtVok1XHlb9i+Mn5O8ExzQ +dF8wGxVDcY7/Gt9lZWnCilqrBEqA3iApjUgcgwIDAQABAoIBAQC77HCmepf04ryp +Yhz00NoXG7mWUMqBtXlPrlaKAWKG5dxbiBwZKLK/UYlxgbLK8BuklBCx1Nnfq1Yh +YDp3nTWsSp0WpsF3eJUqNhD3Pu8xcD+9dEo6bUu+LgXUu9oC5Fq/1RzYS7qNk5RX +4Sf0FY4GQLWS3tL7MJ20mE71yg5k7qRbDydOyhTh1m1CpRYONWxSsWVLM8KGRDJp +iF0cdPfD5yoPFpgDk8gwzrnXJH2Wqzv8GvyYykRK5AW7tE50y0rTAM42WZ7YS6aZ +FNMmtYxeyzXLY3LgPP0uko5anz3OXRcqCfHfFANG0y7B9MehbrjMgI6S1BbzFl07 +V1zVQVqhAoGBAPIfrWMlh1fHlRh4iRGXK2Hvxyv2oNz9KvQ4qRaLV9ejRDzdt7Pi +/utbi5LGBuDw9016nXM3I77b6PukHzsHFnWGRnyRSbkMMt6mE17nggmNqcpFWfE8 +E7HcKMhk4gbuo5AHD3Ee1Gac2AUDnzYiE+sS6WI3O9d77cc5ych5jZ+nAoGBANqt +VZCttjY0E+hEyTP37eaE8u0jfdK8AflTJlNUHWKXglES525iu8I/Bso8KaQYsYF3 +SezGRd3KQepQhtMjFKfSpF+tbnboP57Y3XGo8xhbxqV4kRX+XGsVoW3Vg2nPKBrR ++dIY5nMwua+gkHWp9RDcemD2reiIZBVx95fK8dfFAoGAdCSH2pBs/MlrFqLzNTHr +iH4pb0hN39O9YAsx6POMfo79s6izbyHLIID4Ub6WHB7ashrIHjVr+yin+NXAeWMr +/dIcS7Kxx4c3e5/0mMi6kvSWZsWfoF0uIVo3YfEqjyK36OXKHXwpbNN9t+IF5ESy +g0e+FfPiy7nR1Ig+5+CO8+8CgYEAp/75+Ug677FaidouaMpT7gC9UAkwJLFjItQK +YYIBgTi8WOSY/2jCrhwVb1CA/RwrYjbuiARasGUt9oEe0x3kRHnC5e4rKxaJqdMZ +bLRK7a+0EHNrouXiwjG/7s1VQ/ht6wzdS9btVBlezdogoQSMzQNU0SExwa7mlMMV +X3v+B7ECgYAK+Yt4jnLH1LNWoDTU0Ug5hyXsQXV8lVBSnrkvS7GtP6ZA/4OqG7lJ +/bTYFZGoiAGzOnC+YlAqSIu45CEnpr2xBsThQiWUVxspmQD1lEWWFcd77DPUwn3C +59pLgx0AqJE3n6lBOwehiXbFKBdVzX8PfPZpuCK6qc/RiTILktwURA== +-----END RSA PRIVATE KEY----- diff --git a/src/libnm-core-impl/tests/certs/test-key-only.pem b/src/libnm-core-impl/tests/certs/test-key-only.pem new file mode 100644 index 0000000..5ef530e --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test-key-only.pem @@ -0,0 +1,92 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,B29FCA6ECB7C0C48 + +KuRV4sEVQkY0r0E+E81Se2qpm54HeboUMIJcMVqAt/HIeYwpjEzmXHUywXgayA5k +r5Uvru95vymFz80q/rl6i4Mt3ckEQ3/VHmBI4pPj/JeRbiDhqTyLqpB5zMgbuti+ +PsEemlbiaCMZFdJk8rJBWADTkirGbXs5ciLwTJyrJXhkBVTqoHtphSWMELxcrnQj +5bAXZ+rnApWA7LR3yCY1UE0Nj39Yu8lkzDJtbsSXPJVO//OQiGuQRcY6roAUzeS/ +amLdIYqoZm3OF83Ro88XZCIDCG6XjgKoqojtekClVIytB6mHWk+IHhI7DgU/pDBj +yOskzVRMja9ECnqaVX+bmlmJGZBgcd7+XiebCXNY9IAx/ZQDMbDJDoJusvH6npJR +PBgag8QBSzwpFyEP/1LrlyVyggZcGuXDWfUiM2rt2UvLm8QYeT5WGfUI+QwW6JRV +xEz2QwRiPsmj0uK2fXLKHbY0Pv79IMLqgesCAUbndWsi94kjAhpJGa/WfKVb8Dpg +T+mVa2OT0pgewPWJ3h5f47ag27WDJthsIUHAvNZ03uM23DIqDh6o03/B3/4r1Uab +HzsLWhUOzbLihO08qcPk/JqtDVCv579mpgvy7bL2ZsZUzefnmg+ah+1bhLguryZu +Zrt1hTu5WTz27UbYwWNtkxWnWcM9sSF9y+KVwumYhIUGTvg3Jds/jmp/Z5ad8tev +0RQuWmqnXVD51Y92tOXobJH7JwGbQ4GeRNG/UX7DS9Lvb6rPgmmxvGbXMcjEMapB +m5DLjCD7Lz4++sfzhCic3/nL8e8fjoYZmCbL/SpYjGjTrfoNaGYaT0De8MxCSjPf +rNT+ldWFD0oAOTmT0uqOFkeIx3vxczSQUyRfzGOLqtb9mAXk8lvdb8Myb5atfe8f +FNBL5ocz6Szv2AmKmjZE5P6NKSllyryCYl+H2QU0e3OyY8S9aG2aG8fqeVKaA01S +uOOjsK6IKMpkit+VFDP7RWvS8p1FTwTVRdbMZzASW8+D98OHsTlOENtQuuFyvNaN +vPHrbHltTkwDlYVab9UpFr/ZRW3cNJrmcl0hyeCJxk5u8B9UwW6yZmd24hxda2xt +1QjnxfWlX0i5KTmfWFyPmRYt1WH9rdVaH6wqRbGNbMRT7Lez0E/2+LXjFiiEe0Vh +ZuryhyhUXpHY8yyHxFY92XT504Z3wPUaJ1tQxGhdziZ7HcqFT8f4oTNJdBNtzqNw +l63gSTaKUkSB14CBOyR84cqpgSMwZvWZb3RQFYY4GSALWwhnn6PWeRhjWAXPms2v +tRmfEyDUCyPxDarezvS9kUir3XbvnCkoJOrK/lw4a8ygGBCBqRKOdI0SRUf1Nnjm +aZBrKrXHv5vP66fyC7cGMTq35+iiHbE//rRDGPrf9vpmw3ki3FlDMyAXOC5yWDco +0n+cNDyHJDdIW3+3nfZvSgPPMwmTdfNO90X3YczSmMTGjnIuhQMf7FMFmMZOSrqD +u234vYCjIIlph3aVpbzjOqKg3d4nuP9oouyAgRAr+vShgHRmq0jvsAiGH3Q6RqEj +DvkM1NgoloMy5RhKF4hIeaQM/UlgoXrcEx0RGCJHykQcQmVa5cf5EwjrO7b+w2Lg +-----END RSA PRIVATE KEY----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=test, CN=test/emailAddress=test@test.com + Validity + Not Before: Feb 2 02:22:25 2009 GMT + Not After : Jan 31 02:22:25 2019 GMT + Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=test-client, CN=test-client/emailAddress=test-client@test.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:ce:d2:e9:fb:f4:a4:ce:66:87:cc:8b:2d:d2:c3: + b8:fa:be:ea:53:08:95:9e:27:4a:04:78:31:a1:36: + d2:e5:42:f5:76:f7:24:71:b8:d3:10:fd:b7:57:86: + 68:29:02:1b:e9:93:2b:af:c0:7e:3d:58:16:34:10: + 25:85:7e:28:2d:42:fc:34:7f:d6:4f:0a:e7:b6:b9: + 40:51:c8:e5:89:60:cd:73:51:63:67:e1:59:36:31: + 5e:d0:87:4b:5d:97:8a:42:22:d3:42:f2:83:62:79: + 84:45:5b:d8:20:97:e2:d1:34:23:5e:ec:bf:8a:41: + 7c:ad:80:50:f3:9b:1c:51:5d:e4:29:1c:c1:c6:7c: + a1:00:70:0f:f6:79:77:03:22:f5:4b:ab:76:ca:20: + ab:e1:4e:53:6c:86:68:e9:d6:0f:6e:95:4b:b5:b5: + cf:d3:6c:d4:73:db:c0:3d:1d:20:20:72:ab:3e:25: + bb:3f:cd:5f:2d:77:fd:d7:0b:a8:eb:0c:73:c0:3f: + 74:27:17:56:cf:31:9a:a9:ed:c1:39:27:c7:aa:e9: + 77:48:f4:6d:56:89:35:5c:79:5b:f6:2f:8c:9f:93: + bc:13:1c:d0:74:5f:30:1b:15:43:71:8e:ff:1a:df: + 65:65:69:c2:8a:5a:ab:04:4a:80:de:20:29:8d:48: + 1c:83 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 34:E9:5C:D8:FC:C7:AF:F7:5D:F4:13:D3:82:1A:CD:52:0F:4A:BB:0B + X509v3 Authority Key Identifier: + keyid:52:33:2E:22:66:79:82:E5:41:2E:8D:3B:B2:E5:CC:FA:BE:99:33:8E + DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=test/CN=test/emailAddress=test@test.com + serial:E6:4C:5C:96:26:5E:D6:D0 + + Signature Algorithm: md5WithRSAEncryption + 88:c4:dd:c5:4a:a6:8e:1f:36:62:80:31:6b:2b:85:34:0d:6c: + a7:dc:e1:5a:3c:dd:74:57:db:59:be:8b:f2:79:40:2d:bd:9b: + e1:ab:0e:03:75:20:75:2f:ea:97:f9:d4:7e:15:75:c2:82:f5: + b1:37:e4:8b:24:d4:ef:02:3b:19:6a:56:bb:9f:c3:a5:b4:c4: + 39:a0:64:96:5b:c3:a8:19:74:ec:0b:cf:33:df:f3:12:f3:e2: + ab:1d:7d:de:21:64:cd:b1:a0:6f:7a:77:84:d4:62:8a:50:e6: + 76:5d:af:3a:ef:1a:87:0e:1a:38:c4:f9:0d:2f:14:e0:20:32: + 4c:2e:70:d2:71:82:d5:e5:c9:13:2c:4e:b4:c8:63:65:1d:48: + e8:c3:56:6d:88:84:57:65:13:1e:42:48:b4:03:25:71:4e:12: + 9d:1a:88:65:d5:71:21:3b:0e:be:37:1c:f0:88:6b:45:0c:0e: + 6c:e5:60:cb:86:bf:bf:40:30:c4:cf:94:f8:1c:60:d4:1b:df: + 88:02:7a:45:7e:d1:c6:f3:07:b9:b1:8f:2a:55:2f:be:77:9f: + d1:46:64:05:b7:67:c5:b2:ac:8c:42:8f:6a:51:a4:0d:2b:16: + a4:d6:39:a5:f8:25:ed:68:25:13:b5:19:ac:6c:e9:ec:ee:03: + 6b:80:38:6e + diff --git a/src/libnm-core-impl/tests/certs/test-tpm2wrapped-key.pem b/src/libnm-core-impl/tests/certs/test-tpm2wrapped-key.pem new file mode 100644 index 0000000..f3fd271 --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test-tpm2wrapped-key.pem @@ -0,0 +1,14 @@ +-----BEGIN TSS2 PRIVATE KEY----- +MIICEwYGZ4EFCgEDoAMBAQECBQCBAAABBIIBGAEWAAEACwACBEAAAAAQABAIAAAA +AAABAOJdEXw1LO6JWskHBSYQc1NfJAe9DOAyLA4XbXI5asQ8aNbmL51DP9mQQpqq +a1CSRZAIuuorMxyRBBAFpF4OZqjNd/Nskp3iMmifr5yqAYZ3M31MqlBFiiyctqKp +VwIChwsIbKelrsXbty1icP2CH+k4w/nPymPjnfYtgpMe8QW8n6U156ujIdJcISds +QFcl3nrDnD1IumX0/LfanQrRDVSI+m6szvTrdsPMtGeaNMnlz0gx74auo7/CgEjX +69xjPvQpNLHO/nV4EHSdfXH3LamcpWO8aEAVne3MFFA9V0bpv7uKoGhRjssD9kSr +PQzNXfjHpkcOLeH4pzxDMFXDIGUEgeAA3gAgrCL3RRcBryFXToo9ZN3/f4EeeEjK +58ejYomsxqvckhgAEMxbT26fo2h27b4KPlnUpoiL2JPLB0Xz6PJAF8n0YdJUO381 +xhzPTIQop81BxljTLV2C9WGns5bWDPW9ItEbv4UalEwFfxsW4Ma5smLWn3A1UwVN +Z1cW/oUx+3nOCF1TZgbMPszToqCPlpIHd9vO709qpSyULIUkZLHS6PUM7ESY5U81 +f4BITxJR+aYaqErni/FDLsDVP0MQ3CuFHeUDHI0uEzzbfurYFjpp9+caaoWuZzpg +VYV5pjPdgg== +-----END TSS2 PRIVATE KEY----- diff --git a/src/libnm-core-impl/tests/certs/test2-cert.p12 b/src/libnm-core-impl/tests/certs/test2-cert.p12 new file mode 100644 index 0000000..9d5732b Binary files /dev/null and b/src/libnm-core-impl/tests/certs/test2-cert.p12 differ diff --git a/src/libnm-core-impl/tests/certs/test2_ca_cert.pem b/src/libnm-core-impl/tests/certs/test2_ca_cert.pem new file mode 100644 index 0000000..9a487ca --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test2_ca_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEpDCCA4ygAwIBAgIJANDnVhixAO1GMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD +VQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czERMA8GA1UEBxMIV2VzdGZv +cmQxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xFDASBgNVBAsTC0VuZ2luZWVyaW5n +MRAwDgYDVQQDEwdlYXB0ZXN0MRgwFgYJKoZIhvcNAQkBFglpdEBpdC5jb20wHhcN +MDcxMTA5MTU0ODI1WhcNMTcxMTA2MTU0ODI1WjCBkjELMAkGA1UEBhMCVVMxFjAU +BgNVBAgTDU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQK +Ew1SZWQgSGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UEAxMH +ZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAz9zRLSiQyQangDgEliEP8xSpnPJS7GjXzrkZS3sk +gZLuVuwoFeZRq3Hsrq/wGd/vM0KUFNmEaMc+47jnuv0UHQcQ45ZACO7s4/Aflhzj +lkmud/z06hVknIzjXmvS6q2ttCviHsXnfokl+wAxuUhsd+le0xjP9H1jXny4YBuS +jP+yGUz7PL4w1sFFghKIPrlB7m4GkFbQRqvH7FSJg86GWopPwJvNvIzhOZiO1a1D +CAAL4Ru3jxtNFxqWT87C/qUEe/2Qb7jtNyqFcKfwZyZh4u1bo0c8bjErlUZERbWz +zM3hTFypuw+i2v+0h3A8/Xb0hTjcHkUoJgfSdbsOLC5TOwIDAQABo4H6MIH3MB0G +A1UdDgQWBBR+UOaH4e8nrEuMcEXJl7UN5r/wDTCBxwYDVR0jBIG/MIG8gBR+UOaH +4e8nrEuMcEXJl7UN5r/wDaGBmKSBlTCBkjELMAkGA1UEBhMCVVMxFjAUBgNVBAgT +DU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQKEw1SZWQg +SGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UEAxMHZWFwdGVz +dDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tggkA0OdWGLEA7UYwDAYDVR0TBAUw +AwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAmE2jqUymfxN2Vv7bPafoK/EpZwGPxu+z +phRFsgUgWVzidc/GtOxN81LduJ+ow8MEbQIabo4JV/MdKzuPuhAHToAQdeb0LIWa +p59vTIZiVhUt0cMAbQwKcTnfmDnXw9wytvtKgeAXJq0Jd6F+uNXTiR1btlYLZqmF +oSu54cHQlXpUT9z0BnQ8eXd7m0TwfzGQkTHQI7xBa87lZDAkJaTlhv7fR5vPmJYY +0LiXii71ce+4hxdlp7hQfwQ2sb8FPY3RlVboTRD0CvGaWypWhdSZnS790dBXgZOs +NCge6NGuHzW5LtiZE9ppuv8qJysVcIFdAqt8dkx58ksOqFcARCerXw== +-----END CERTIFICATE----- diff --git a/src/libnm-core-impl/tests/certs/test2_key_and_cert.pem b/src/libnm-core-impl/tests/certs/test2_key_and_cert.pem new file mode 100644 index 0000000..a668596 --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test2_key_and_cert.pem @@ -0,0 +1,119 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,5FA2D6D6242C26D0 + +dyNdbh115sczbUEhiaGYJ6fazyvJss5thPFEmkP6aftYlvXY6vPtc++xFCCktiSd +qFVEyi6oDyV4iGPmX7pCJ0e+pSI6uFNXKFtxh5/+/wXZcOEMCvfu7w2IrvYF2LHY +qJDljcISSRxeINuYO7TETD5fLLRKj2X9vwwkwVN02b2N5jsrm6Bt//WbatqSB3ln +FHyQhVKkvdl9Hr1XNmEfgGfZSxxDoPu1DjhtZ5ja2LZj64C2CXdI0oq2wcAVvQNn +rZeeg9sinQJkz9rwsNaWqlYw4X+YD2JRSwZuvwkWRydYMwgb1XS/jCxtuFF8NXWP +RBAOAZZUy7onzohsJHVVa05wCKQ4klo+PEfI3vn7BeuHyciCc0eFqGRvz8eFDybH +ZdPbU/3vGp+mOB7gd27TptttTCQQy9uM5CIyovNSYsAIw1Z583Ea4q8eXgzkgD6D +isCqkGXMfPbNXU3myQGDnQwWRi2CqX+rXM8PJUhdewLAlmHRz/aYSuql2BRixJKx +eASzmFBYdAjrvafda5D+xTyJwXEwdq/HlqMK9cY28ZbNrzA2Kor2X23EKC1+VG8k +B67OsfUhW27j4u6aV5JdLf87OtF3mHFRR+Lzs7i7LYvJ8ACE+jiIi7PboZjK5Oiv +JqTK0BwDaeNYjkd6jiJh8It/ReMbLk65J3eldOklN0VMPYiqcQnHvSPC2DD1YAy+ +Rv/JVj6TvzvgEAj+hgH6MAAF6u3ARj6+10DlvhUubkOC5RztLKReu8B+427TuuDb +T03gFpHD6X9IqSiq/QfYFyHFojCVSrv6wDZOcHc1s71kpJ8R14YIVe+DrrZN/0D4 +M631jdNg3JARMZXcXTHrghGIdPmOtrsRyTTRZuGoVup/DW9MRzOzCTMSNCX8T+eq +13HMSNQEO9lMwy0sYeO5c7sjHY4K1ubZuVE1mvXq4JLz3YxXJIvgp8TUvqDnAsK+ +Fv63bDoTg5Tq63XvnaKc7Lawneyg5ZAMzPN3nM0/1EZcn/2ICI5c4Yepc5t63EI5 +KytuXx86Mcx234enj3uMeuM22POQ1SnKOef6dFzK/CE8J8eUEY/aDhX4eBl/s3nd +U4+aaFKYz3HTazePayt2SC6rP/KKMmS14q59bOQA1DiWxCvmA2ypRyP87fV5DstH +I53RD5xp1P38iaO8U/divD0W2dkv748s9DQqYrHPtWALT9esxNU07CgB8Zt070si +7pzjQ8FDCZ8ygDmwWGNSBz1nA90Cpd6gAFDrep7HAtDE4qgNfokycpaJZkXBei/U +tC4tWYRbqDEsEbeBHvQRJzzqWzk9e/P4fQoelM3aryKzKLG5z7KvywVifKMLECQ+ +tIpzoRp06nuTA/O+iLFdkCy3JEWszfvvOwTwtIIV6+3s8TU0k9MmzEe3rGL+QqT/ +Tf+9/dN5LK+LWyc99BfmCOrBuFtQmHyEXkfe6EuFYEwj0B2ZfnLCon6cdRujjK7H +IJslC1B/cBVqG3KCrbBzjeygKfJ5Ijo72oXZJOCFTLeJefZKGGWJCp9nG9h9Wrcf +fEN/mj3wBvTa90/PYFj9NuaBtrvMF8Rn9XDeYPq2JGL8YkNdPuO8A+2Yko8wcvST +-----END RSA PRIVATE KEY----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Massachusetts, L=Westford, O=Red Hat, Inc., OU=Engineering, CN=eaptest/emailAddress=it@it.com + Validity + Not Before: Nov 9 15:50:14 2007 GMT + Not After : Nov 6 15:50:14 2017 GMT + Subject: C=US, ST=Massachusetts, O=Red Hat, Inc., OU=Engineering, CN=client/emailAddress=it@it.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:b0:8f:4f:1c:93:d4:43:e7:87:b7:22:33:55:a8: + 35:a1:c4:01:b0:f1:ed:26:23:96:ab:65:c2:c2:54: + db:79:22:03:ad:3f:6f:22:e3:63:3f:f4:21:6d:fa: + 88:c8:8f:1a:ce:55:49:7c:98:33:6a:67:8a:8d:d9: + 34:b0:c3:42:f4:72:a4:45:43:05:72:5d:0c:d3:42: + f8:9c:66:3b:b8:f8:77:ea:f6:b6:94:d7:cc:5d:62: + 34:2a:14:48:0a:bc:65:94:f5:7a:63:98:6c:88:4c: + 25:d8:95:f1:40:3d:00:d2:fb:43:28:fa:02:fb:2c: + 80:b3:e1:33:e7:8c:ce:8a:a0:1b:3d:04:4d:bc:a1: + b6:a2:42:8b:8e:f3:5b:4a:72:34:7d:8d:ba:d8:46: + 22:35:da:5c:f8:dd:fc:6d:9e:59:22:b7:6b:e7:78: + 56:54:9f:4c:d1:e2:4a:23:a3:bc:04:ea:46:6b:70: + 8a:fb:fe:8a:73:ca:36:d5:f3:e9:17:e3:22:d5:b3: + 70:05:e7:f7:37:b7:21:b5:90:53:27:27:ea:36:9b: + 00:ff:35:b0:66:3d:dc:a9:2f:95:d2:21:18:98:4f: + 28:07:09:70:20:a8:b1:82:aa:a5:df:ae:0f:e3:36: + be:68:8c:9e:80:d3:33:d0:f5:84:17:d9:0f:eb:9d: + af:0b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 71:AB:BB:91:B7:04:DE:43:35:36:07:8A:35:CA:BE:5C:3E:EB:B1:09 + X509v3 Authority Key Identifier: + keyid:7E:50:E6:87:E1:EF:27:AC:4B:8C:70:45:C9:97:B5:0D:E6:BF:F0:0D + DirName:/C=US/ST=Massachusetts/L=Westford/O=Red Hat, Inc./OU=Engineering/CN=eaptest/emailAddress=it@it.com + serial:D0:E7:56:18:B1:00:ED:46 + + Signature Algorithm: md5WithRSAEncryption + ce:43:6d:f7:f8:4a:66:fd:8a:2c:41:a6:e0:03:0e:60:30:d4: + 41:01:ba:46:ba:81:97:64:68:83:25:9c:e1:2c:03:8b:2d:ca: + 85:cf:bc:fa:ca:22:c4:59:28:23:8f:ff:50:94:60:1c:90:dd: + 75:f4:d4:ea:8c:fa:61:61:08:35:4a:8f:aa:a7:e9:3d:76:e9: + 08:28:55:01:c4:03:42:c7:ad:58:bb:ee:94:f7:09:b3:9a:9b: + 8b:d0:25:95:18:a6:22:d5:2c:fc:b7:bb:91:0c:7c:03:7f:9b: + 85:de:b0:e4:95:a8:73:94:27:0a:11:4e:e3:67:ae:2b:cc:e7: + 51:29:10:23:57:5c:3e:e7:ea:47:e0:f0:8f:5b:a2:9f:26:cf: + 7f:b5:7c:44:b1:7b:83:67:3c:41:ae:c6:66:64:e0:d2:ef:57: + a4:5c:1b:94:11:ce:28:e5:91:51:ef:e1:98:b7:3b:9a:cc:f7: + b9:85:76:eb:a8:2b:15:4a:cc:1a:a3:42:fa:be:1c:ce:b8:eb: + ee:12:d7:2f:e4:a8:cf:eb:2a:8f:78:e8:91:88:fa:c2:98:75: + 6a:4c:92:3f:2e:0d:e1:20:39:36:c6:2c:be:67:30:c3:f3:c3: + 65:81:ac:e3:3c:19:6a:21:ee:ea:f5:22:66:74:b2:07:53:7c: + 9a:0c:24:a6 +-----BEGIN CERTIFICATE----- +MIIEtDCCA5ygAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCVVMx +FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYD +VQQKEw1SZWQgSGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UE +AxMHZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tMB4XDTA3MTEwOTE1 +NTAxNFoXDTE3MTEwNjE1NTAxNFowfjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1h +c3NhY2h1c2V0dHMxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xFDASBgNVBAsTC0Vu +Z2luZWVyaW5nMQ8wDQYDVQQDEwZjbGllbnQxGDAWBgkqhkiG9w0BCQEWCWl0QGl0 +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALCPTxyT1EPnh7ci +M1WoNaHEAbDx7SYjlqtlwsJU23kiA60/byLjYz/0IW36iMiPGs5VSXyYM2pnio3Z +NLDDQvRypEVDBXJdDNNC+JxmO7j4d+r2tpTXzF1iNCoUSAq8ZZT1emOYbIhMJdiV +8UA9ANL7Qyj6AvssgLPhM+eMzoqgGz0ETbyhtqJCi47zW0pyNH2NuthGIjXaXPjd +/G2eWSK3a+d4VlSfTNHiSiOjvATqRmtwivv+inPKNtXz6RfjItWzcAXn9ze3IbWQ +Uycn6jabAP81sGY93KkvldIhGJhPKAcJcCCosYKqpd+uD+M2vmiMnoDTM9D1hBfZ +D+udrwsCAwEAAaOCASYwggEiMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9w +ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRxq7uRtwTeQzU2 +B4o1yr5cPuuxCTCBxwYDVR0jBIG/MIG8gBR+UOaH4e8nrEuMcEXJl7UN5r/wDaGB +mKSBlTCBkjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxETAP +BgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQKEw1SZWQgSGF0LCBJbmMuMRQwEgYDVQQL +EwtFbmdpbmVlcmluZzEQMA4GA1UEAxMHZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJ +aXRAaXQuY29tggkA0OdWGLEA7UYwDQYJKoZIhvcNAQEEBQADggEBAM5Dbff4Smb9 +iixBpuADDmAw1EEBuka6gZdkaIMlnOEsA4styoXPvPrKIsRZKCOP/1CUYByQ3XX0 +1OqM+mFhCDVKj6qn6T126QgoVQHEA0LHrVi77pT3CbOam4vQJZUYpiLVLPy3u5EM +fAN/m4XesOSVqHOUJwoRTuNnrivM51EpECNXXD7n6kfg8I9bop8mz3+1fESxe4Nn +PEGuxmZk4NLvV6RcG5QRzijlkVHv4Zi3O5rM97mFduuoKxVKzBqjQvq+HM646+4S +1y/kqM/rKo946JGI+sKYdWpMkj8uDeEgOTbGLL5nMMPzw2WBrOM8GWoh7ur1ImZ0 +sgdTfJoMJKY= +-----END CERTIFICATE----- diff --git a/src/libnm-core-impl/tests/certs/test_ca_cert.der b/src/libnm-core-impl/tests/certs/test_ca_cert.der new file mode 100644 index 0000000..e844f65 Binary files /dev/null and b/src/libnm-core-impl/tests/certs/test_ca_cert.der differ diff --git a/src/libnm-core-impl/tests/certs/test_ca_cert.pem b/src/libnm-core-impl/tests/certs/test_ca_cert.pem new file mode 100644 index 0000000..faa3fc2 --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test_ca_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEhjCCA26gAwIBAgIJAOZMXJYmXtbQMA0GCSqGSIb3DQEBBQUAMIGIMQswCQYD +VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw +FQYDVQQKEw5NeSBDb21wYW55IEx0ZDENMAsGA1UECxMEdGVzdDENMAsGA1UEAxME +dGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAyMDIwMjIx +NTJaFw0xOTAxMzEwMjIxNTJaMIGIMQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVy +a3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0 +ZDENMAsGA1UECxMEdGVzdDENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3DQEJARYN +dGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZz +iHfFR6Gqdz5Gq1elSaf7J2tznfialPyMkRoqngSItrM3JWlkfBu3ZIpGSYG8+Z8H +JjaKh/zkCCH73HcjADCocm/XtgxlOlccDtBvfDqifb2dBikcmcfh0tX0o4JU9L+z +WP7sVcUkJG7C5811lA5pAsLVooJxrZnrta6XstGvFgTSxI2Y4Jowf0syM5b/AHIQ ++htsVhSyj1DWM9day3QsEMZl55SCxCLTB6ZIJLF6NmTYwdnzWWTQf4k7kcptZJU8 +Fqv60b/ATvvUf7S+ZMGLopFIIlmc1Kkn7VTseIKy4ycYuDpyimQy3Yw4flC00vhl +hTijH+5dlVOUFrRh0bsCAwEAAaOB8DCB7TAdBgNVHQ4EFgQUUjMuImZ5guVBLo07 +suXM+r6ZM44wgb0GA1UdIwSBtTCBsoAUUjMuImZ5guVBLo07suXM+r6ZM46hgY6k +gYswgYgxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcT +B05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQ0wCwYDVQQLEwR0ZXN0 +MQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA +5kxcliZe1tAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAZsWzGp9D +10NWf8ts3A9mhcEb8oDgKNpCOZF9gqr2usZygJjY9MX2n0n81T8XaWDk1wZLlcDW +hzIalCY8rpE57Dj3MEmdCmYr3BrAy6GVlc/MO7ffTHxogl9ouScSYo8ETTtNMKCg +zwkDnXjGzmb1e59DIXMVHBBbTmJXJbM8XP9A2azJkVUyE2fSdWksXMP0XklGbW2p +DksJ+8G1IWkyRhnINV5GZLLNAT5gBA6sUv/iqQKwk8r2dsweMPtLoLWZPAaZErYh +sthGy00Q0GJkmkJpQl8QIlPq5vylNcMUhvc8tmzwk+rDVUj3jTJWqFwMtnHAaNyC +FXl9ynWpe5J28w== +-----END CERTIFICATE----- diff --git a/src/libnm-core-impl/tests/certs/test_key_and_cert.pem b/src/libnm-core-impl/tests/certs/test_key_and_cert.pem new file mode 100644 index 0000000..c00495d --- /dev/null +++ b/src/libnm-core-impl/tests/certs/test_key_and_cert.pem @@ -0,0 +1,119 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,B29FCA6ECB7C0C48 + +KuRV4sEVQkY0r0E+E81Se2qpm54HeboUMIJcMVqAt/HIeYwpjEzmXHUywXgayA5k +r5Uvru95vymFz80q/rl6i4Mt3ckEQ3/VHmBI4pPj/JeRbiDhqTyLqpB5zMgbuti+ +PsEemlbiaCMZFdJk8rJBWADTkirGbXs5ciLwTJyrJXhkBVTqoHtphSWMELxcrnQj +5bAXZ+rnApWA7LR3yCY1UE0Nj39Yu8lkzDJtbsSXPJVO//OQiGuQRcY6roAUzeS/ +amLdIYqoZm3OF83Ro88XZCIDCG6XjgKoqojtekClVIytB6mHWk+IHhI7DgU/pDBj +yOskzVRMja9ECnqaVX+bmlmJGZBgcd7+XiebCXNY9IAx/ZQDMbDJDoJusvH6npJR +PBgag8QBSzwpFyEP/1LrlyVyggZcGuXDWfUiM2rt2UvLm8QYeT5WGfUI+QwW6JRV +xEz2QwRiPsmj0uK2fXLKHbY0Pv79IMLqgesCAUbndWsi94kjAhpJGa/WfKVb8Dpg +T+mVa2OT0pgewPWJ3h5f47ag27WDJthsIUHAvNZ03uM23DIqDh6o03/B3/4r1Uab +HzsLWhUOzbLihO08qcPk/JqtDVCv579mpgvy7bL2ZsZUzefnmg+ah+1bhLguryZu +Zrt1hTu5WTz27UbYwWNtkxWnWcM9sSF9y+KVwumYhIUGTvg3Jds/jmp/Z5ad8tev +0RQuWmqnXVD51Y92tOXobJH7JwGbQ4GeRNG/UX7DS9Lvb6rPgmmxvGbXMcjEMapB +m5DLjCD7Lz4++sfzhCic3/nL8e8fjoYZmCbL/SpYjGjTrfoNaGYaT0De8MxCSjPf +rNT+ldWFD0oAOTmT0uqOFkeIx3vxczSQUyRfzGOLqtb9mAXk8lvdb8Myb5atfe8f +FNBL5ocz6Szv2AmKmjZE5P6NKSllyryCYl+H2QU0e3OyY8S9aG2aG8fqeVKaA01S +uOOjsK6IKMpkit+VFDP7RWvS8p1FTwTVRdbMZzASW8+D98OHsTlOENtQuuFyvNaN +vPHrbHltTkwDlYVab9UpFr/ZRW3cNJrmcl0hyeCJxk5u8B9UwW6yZmd24hxda2xt +1QjnxfWlX0i5KTmfWFyPmRYt1WH9rdVaH6wqRbGNbMRT7Lez0E/2+LXjFiiEe0Vh +ZuryhyhUXpHY8yyHxFY92XT504Z3wPUaJ1tQxGhdziZ7HcqFT8f4oTNJdBNtzqNw +l63gSTaKUkSB14CBOyR84cqpgSMwZvWZb3RQFYY4GSALWwhnn6PWeRhjWAXPms2v +tRmfEyDUCyPxDarezvS9kUir3XbvnCkoJOrK/lw4a8ygGBCBqRKOdI0SRUf1Nnjm +aZBrKrXHv5vP66fyC7cGMTq35+iiHbE//rRDGPrf9vpmw3ki3FlDMyAXOC5yWDco +0n+cNDyHJDdIW3+3nfZvSgPPMwmTdfNO90X3YczSmMTGjnIuhQMf7FMFmMZOSrqD +u234vYCjIIlph3aVpbzjOqKg3d4nuP9oouyAgRAr+vShgHRmq0jvsAiGH3Q6RqEj +DvkM1NgoloMy5RhKF4hIeaQM/UlgoXrcEx0RGCJHykQcQmVa5cf5EwjrO7b+w2Lg +-----END RSA PRIVATE KEY----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=test, CN=test/emailAddress=test@test.com + Validity + Not Before: Feb 2 02:22:25 2009 GMT + Not After : Jan 31 02:22:25 2019 GMT + Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=test-client, CN=test-client/emailAddress=test-client@test.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:ce:d2:e9:fb:f4:a4:ce:66:87:cc:8b:2d:d2:c3: + b8:fa:be:ea:53:08:95:9e:27:4a:04:78:31:a1:36: + d2:e5:42:f5:76:f7:24:71:b8:d3:10:fd:b7:57:86: + 68:29:02:1b:e9:93:2b:af:c0:7e:3d:58:16:34:10: + 25:85:7e:28:2d:42:fc:34:7f:d6:4f:0a:e7:b6:b9: + 40:51:c8:e5:89:60:cd:73:51:63:67:e1:59:36:31: + 5e:d0:87:4b:5d:97:8a:42:22:d3:42:f2:83:62:79: + 84:45:5b:d8:20:97:e2:d1:34:23:5e:ec:bf:8a:41: + 7c:ad:80:50:f3:9b:1c:51:5d:e4:29:1c:c1:c6:7c: + a1:00:70:0f:f6:79:77:03:22:f5:4b:ab:76:ca:20: + ab:e1:4e:53:6c:86:68:e9:d6:0f:6e:95:4b:b5:b5: + cf:d3:6c:d4:73:db:c0:3d:1d:20:20:72:ab:3e:25: + bb:3f:cd:5f:2d:77:fd:d7:0b:a8:eb:0c:73:c0:3f: + 74:27:17:56:cf:31:9a:a9:ed:c1:39:27:c7:aa:e9: + 77:48:f4:6d:56:89:35:5c:79:5b:f6:2f:8c:9f:93: + bc:13:1c:d0:74:5f:30:1b:15:43:71:8e:ff:1a:df: + 65:65:69:c2:8a:5a:ab:04:4a:80:de:20:29:8d:48: + 1c:83 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 34:E9:5C:D8:FC:C7:AF:F7:5D:F4:13:D3:82:1A:CD:52:0F:4A:BB:0B + X509v3 Authority Key Identifier: + keyid:52:33:2E:22:66:79:82:E5:41:2E:8D:3B:B2:E5:CC:FA:BE:99:33:8E + DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=test/CN=test/emailAddress=test@test.com + serial:E6:4C:5C:96:26:5E:D6:D0 + + Signature Algorithm: md5WithRSAEncryption + 88:c4:dd:c5:4a:a6:8e:1f:36:62:80:31:6b:2b:85:34:0d:6c: + a7:dc:e1:5a:3c:dd:74:57:db:59:be:8b:f2:79:40:2d:bd:9b: + e1:ab:0e:03:75:20:75:2f:ea:97:f9:d4:7e:15:75:c2:82:f5: + b1:37:e4:8b:24:d4:ef:02:3b:19:6a:56:bb:9f:c3:a5:b4:c4: + 39:a0:64:96:5b:c3:a8:19:74:ec:0b:cf:33:df:f3:12:f3:e2: + ab:1d:7d:de:21:64:cd:b1:a0:6f:7a:77:84:d4:62:8a:50:e6: + 76:5d:af:3a:ef:1a:87:0e:1a:38:c4:f9:0d:2f:14:e0:20:32: + 4c:2e:70:d2:71:82:d5:e5:c9:13:2c:4e:b4:c8:63:65:1d:48: + e8:c3:56:6d:88:84:57:65:13:1e:42:48:b4:03:25:71:4e:12: + 9d:1a:88:65:d5:71:21:3b:0e:be:37:1c:f0:88:6b:45:0c:0e: + 6c:e5:60:cb:86:bf:bf:40:30:c4:cf:94:f8:1c:60:d4:1b:df: + 88:02:7a:45:7e:d1:c6:f3:07:b9:b1:8f:2a:55:2f:be:77:9f: + d1:46:64:05:b7:67:c5:b2:ac:8c:42:8f:6a:51:a4:0d:2b:16: + a4:d6:39:a5:f8:25:ed:68:25:13:b5:19:ac:6c:e9:ec:ee:03: + 6b:80:38:6e +-----BEGIN CERTIFICATE----- +MIIErjCCA5agAwIBAgIBATANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCVVMx +EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO +TXkgQ29tcGFueSBMdGQxDTALBgNVBAsTBHRlc3QxDTALBgNVBAMTBHRlc3QxHDAa +BgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMjAyMDIyMjI1WhcNMTkw +MTMxMDIyMjI1WjCBizELMAkGA1UEBhMCVVMxEjAQBgNVBAgTCUJlcmtzaGlyZTEX +MBUGA1UEChMOTXkgQ29tcGFueSBMdGQxFDASBgNVBAsTC3Rlc3QtY2xpZW50MRQw +EgYDVQQDEwt0ZXN0LWNsaWVudDEjMCEGCSqGSIb3DQEJARYUdGVzdC1jbGllbnRA +dGVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDO0un79KTO +ZofMiy3Sw7j6vupTCJWeJ0oEeDGhNtLlQvV29yRxuNMQ/bdXhmgpAhvpkyuvwH49 +WBY0ECWFfigtQvw0f9ZPCue2uUBRyOWJYM1zUWNn4Vk2MV7Qh0tdl4pCItNC8oNi +eYRFW9ggl+LRNCNe7L+KQXytgFDzmxxRXeQpHMHGfKEAcA/2eXcDIvVLq3bKIKvh +TlNshmjp1g9ulUu1tc/TbNRz28A9HSAgcqs+Jbs/zV8td/3XC6jrDHPAP3QnF1bP +MZqp7cE5J8eq6XdI9G1WiTVceVv2L4yfk7wTHNB0XzAbFUNxjv8a32VlacKKWqsE +SoDeICmNSByDAgMBAAGjggEcMIIBGDAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQf +Fh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNOlc2PzH +r/dd9BPTghrNUg9Kuwswgb0GA1UdIwSBtTCBsoAUUjMuImZ5guVBLo07suXM+r6Z +M46hgY6kgYswgYgxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO +BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQ0wCwYDVQQL +EwR0ZXN0MQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3Qu +Y29tggkA5kxcliZe1tAwDQYJKoZIhvcNAQEEBQADggEBAIjE3cVKpo4fNmKAMWsr +hTQNbKfc4Vo83XRX21m+i/J5QC29m+GrDgN1IHUv6pf51H4VdcKC9bE35Isk1O8C +OxlqVrufw6W0xDmgZJZbw6gZdOwLzzPf8xLz4qsdfd4hZM2xoG96d4TUYopQ5nZd +rzrvGocOGjjE+Q0vFOAgMkwucNJxgtXlyRMsTrTIY2UdSOjDVm2IhFdlEx5CSLQD +JXFOEp0aiGXVcSE7Dr43HPCIa0UMDmzlYMuGv79AMMTPlPgcYNQb34gCekV+0cbz +B7mxjypVL753n9FGZAW3Z8WyrIxCj2pRpA0rFqTWOaX4Je1oJRO1Gaxs6ezuA2uA +OG4= +-----END CERTIFICATE----- diff --git a/src/libnm-core-impl/tests/meson.build b/src/libnm-core-impl/tests/meson.build new file mode 100644 index 0000000..ca1d1c1 --- /dev/null +++ b/src/libnm-core-impl/tests/meson.build @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +enum_sources = gnome.mkenums_simple( + 'nm-core-tests-enum-types', + sources: 'test-general-enums.h', + identifier_prefix: nm_id_prefix, + body_prefix: '#include "libnm-core-impl/nm-default-libnm-core.h"', +) + +test_units = [ + 'test-compare', + 'test-crypto', + 'test-general', + 'test-keyfile', + 'test-secrets', + 'test-setting', + 'test-settings-defaults', +] + +foreach test_unit: test_units + exe = executable( + 'libnm-core-' + test_unit, + [test_unit + '.c'] + enum_sources, + include_directories: [ + libnm_core_impl_inc, + ], + dependencies: [ + libnm_core_public_dep, + ], + link_with: [ + libnm_core_aux_intern, + libnm_core_impl, + libnm_crypto, + libnm_base, + libnm_log_null, + libnm_systemd_shared, + libnm_glib_aux, + libnm_std_aux, + libc_siphash, + ], + ) + + test( + 'src/libnm-core-impl/tests/' + test_unit, + test_script, + args: test_args + [exe.full_path()], + timeout: default_test_timeout, + ) +endforeach diff --git a/src/libnm-core-impl/tests/nm-core-tests-enum-types.c.template b/src/libnm-core-impl/tests/nm-core-tests-enum-types.c.template new file mode 100644 index 0000000..1160be8 --- /dev/null +++ b/src/libnm-core-impl/tests/nm-core-tests-enum-types.c.template @@ -0,0 +1,35 @@ +/*** BEGIN file-header ***/ +#include "config.h" + +#include "nm-core-tests-enum-types.h" + +#include "test-general-enums.h" +/*** END file-header ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} + +/*** END value-tail ***/ diff --git a/src/libnm-core-impl/tests/nm-core-tests-enum-types.h.template b/src/libnm-core-impl/tests/nm-core-tests-enum-types.h.template new file mode 100644 index 0000000..62e82b7 --- /dev/null +++ b/src/libnm-core-impl/tests/nm-core-tests-enum-types.h.template @@ -0,0 +1,21 @@ +/*** BEGIN file-header ***/ +#ifndef __NM_CORE_TESTS_ENUM_TYPES_H__ +#define __NM_CORE_TESTS_ENUM_TYPES_H__ + +#include + +G_BEGIN_DECLS + +/*** END file-header ***/ + +/*** BEGIN enumeration-production ***/ +GType @enum_name@_get_type (void) G_GNUC_CONST; +#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) + +/*** END enumeration-production ***/ + +/*** BEGIN file-tail ***/ +G_END_DECLS + +#endif /* __NM_CORE_TESTS_ENUM_TYPES_H__ */ +/*** END file-tail ***/ diff --git a/src/libnm-core-impl/tests/test-compare.c b/src/libnm-core-impl/tests/test-compare.c new file mode 100644 index 0000000..3716399 --- /dev/null +++ b/src/libnm-core-impl/tests/test-compare.c @@ -0,0 +1,231 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include +#include + +#include "nm-property-compare.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +static void +compare_ints(void) +{ + GVariant *value1, *value2; + + value1 = g_variant_new_int32(5); + value2 = g_variant_new_int32(5); + g_assert(nm_property_compare(value1, value2) == 0); + + g_variant_unref(value2); + value2 = g_variant_new_int32(10); + g_assert(nm_property_compare(value1, value2) < 0); + + g_variant_unref(value2); + value2 = g_variant_new_int32(-1); + g_assert(nm_property_compare(value1, value2) > 0); + + g_variant_unref(value1); + g_variant_unref(value2); +} + +static void +compare_strings(void) +{ + GVariant * value1, *value2; + const char *str1 = "hello"; + const char *str2 = "world"; + + value1 = g_variant_new_string(str1); + value2 = g_variant_new_string(str1); + g_assert(nm_property_compare(value1, value2) == 0); + + g_variant_unref(value2); + value2 = g_variant_new_string(str2); + g_assert(nm_property_compare(value1, value2) < 0); + + g_assert(nm_property_compare(value2, value1) > 0); + + g_variant_unref(value1); + g_variant_unref(value2); +} + +static void +compare_strv(void) +{ + GVariant * value1, *value2; + const char *const strv1[] = {"foo", "bar", "baz", NULL}; + const char *const strv2[] = {"foo", "bar", "bar", NULL}; + const char *const strv3[] = {"foo", "bar", NULL}; + const char *const strv4[] = {"foo", "bar", "baz", "bam", NULL}; + + value1 = g_variant_new_strv(strv1, -1); + value2 = g_variant_new_strv(strv1, -1); + g_assert(nm_property_compare(value1, value2) == 0); + + g_variant_unref(value2); + value2 = g_variant_new_strv(strv2, -1); + g_assert(nm_property_compare(value1, value2) != 0); + + g_variant_unref(value2); + value2 = g_variant_new_strv(strv3, -1); + g_assert(nm_property_compare(value1, value2) != 0); + + g_variant_unref(value2); + value2 = g_variant_new_strv(strv4, -1); + g_assert(nm_property_compare(value1, value2) != 0); + + g_variant_unref(value1); + g_variant_unref(value2); +} + +static void +compare_arrays(void) +{ + GVariant *value1, *value2; + guint32 array[] = {0, 1, 2, 3, 4}; + + value1 = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, + array, + G_N_ELEMENTS(array), + sizeof(guint32)); + value2 = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, + array, + G_N_ELEMENTS(array), + sizeof(guint32)); + + g_assert(nm_property_compare(value1, value2) == 0); + + g_variant_unref(value2); + value2 = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, + array + 1, + G_N_ELEMENTS(array) - 1, + sizeof(guint32)); + g_assert(nm_property_compare(value1, value2) != 0); + + array[0] = 7; + g_variant_unref(value2); + value2 = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, + array, + G_N_ELEMENTS(array), + sizeof(guint32)); + g_assert(nm_property_compare(value1, value2) != 0); + + g_variant_unref(value1); + g_variant_unref(value2); +} + +static void +compare_str_hash(void) +{ + GVariant * value1, *value2; + GVariantBuilder builder; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}")); + g_variant_builder_add(&builder, "{ss}", "key1", "hello"); + g_variant_builder_add(&builder, "{ss}", "key2", "world"); + g_variant_builder_add(&builder, "{ss}", "key3", "!"); + value1 = g_variant_builder_end(&builder); + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}")); + g_variant_builder_add(&builder, "{ss}", "key3", "!"); + g_variant_builder_add(&builder, "{ss}", "key2", "world"); + g_variant_builder_add(&builder, "{ss}", "key1", "hello"); + value2 = g_variant_builder_end(&builder); + + g_assert(nm_property_compare(value1, value2) == 0); + + g_variant_unref(value2); + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}")); + g_variant_builder_add(&builder, "{ss}", "key1", "hello"); + g_variant_builder_add(&builder, "{ss}", "key3", "!"); + value2 = g_variant_builder_end(&builder); + + g_assert(nm_property_compare(value1, value2) != 0); + g_assert(nm_property_compare(value2, value1) != 0); + + g_variant_unref(value2); + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}")); + g_variant_builder_add(&builder, "{ss}", "key1", "hello"); + g_variant_builder_add(&builder, "{ss}", "key2", "moon"); + g_variant_builder_add(&builder, "{ss}", "key3", "!"); + value2 = g_variant_builder_end(&builder); + + g_assert(nm_property_compare(value1, value2) != 0); + + g_variant_unref(value1); + g_variant_unref(value2); +} + +static void +compare_ip6_addresses(void) +{ + GVariant * value1, *value2; + struct in6_addr addr1; + struct in6_addr addr2; + struct in6_addr addr3; + guint32 prefix1 = 64; + guint32 prefix2 = 64; + guint32 prefix3 = 0; + + inet_pton(AF_INET6, "1:2:3:4:5:6:7:8", &addr1); + inet_pton(AF_INET6, "ffff:2:3:4:5:6:7:8", &addr2); + inet_pton(AF_INET6, "::", &addr3); + + value1 = g_variant_new( + "(@ayu@ay)", + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr1.s6_addr, 16, 1), + prefix1, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr3.s6_addr, 16, 1)); + + value2 = g_variant_new( + "(@ayu@ay)", + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr1.s6_addr, 16, 1), + prefix1, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr3.s6_addr, 16, 1)); + + g_assert(nm_property_compare(value1, value2) == 0); + + g_variant_unref(value2); + value2 = g_variant_new( + "(@ayu@ay)", + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr2.s6_addr, 16, 1), + prefix2, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr3.s6_addr, 16, 1)); + + g_assert(nm_property_compare(value1, value2) != 0); + + g_variant_unref(value2); + value2 = g_variant_new( + "(@ayu@ay)", + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr3.s6_addr, 16, 1), + prefix3, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr3.s6_addr, 16, 1)); + + g_assert(nm_property_compare(value1, value2) != 0); + + g_variant_unref(value1); + g_variant_unref(value2); +} + +NMTST_DEFINE(); + +int +main(int argc, char *argv[]) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_func("/libnm/compare/ints", compare_ints); + g_test_add_func("/libnm/compare/strings", compare_strings); + g_test_add_func("/libnm/compare/strv", compare_strv); + g_test_add_func("/libnm/compare/arrays", compare_arrays); + g_test_add_func("/libnm/compare/str_hash", compare_str_hash); + g_test_add_func("/libnm/compare/ip6_addresses", compare_ip6_addresses); + + return g_test_run(); +} diff --git a/src/libnm-core-impl/tests/test-crypto.c b/src/libnm-core-impl/tests/test-crypto.c new file mode 100644 index 0000000..bdbcd0f --- /dev/null +++ b/src/libnm-core-impl/tests/test-crypto.c @@ -0,0 +1,455 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Dan Williams + * Copyright (C) 2007 - 2011 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include +#include +#include + +#include "nm-crypto-impl.h" +#include "nm-utils.h" +#include "nm-errors.h" +#include "libnm-core-intern/nm-core-internal.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +#define TEST_CERT_DIR NM_BUILD_SRCDIR "/src/libnm-core-impl/tests/certs" + +#if 0 +static const char *pem_rsa_key_begin = "-----BEGIN RSA PRIVATE KEY-----"; +static const char *pem_rsa_key_end = "-----END RSA PRIVATE KEY-----"; + +static const char *pem_dsa_key_begin = "-----BEGIN DSA PRIVATE KEY-----"; +static const char *pem_dsa_key_end = "-----END DSA PRIVATE KEY-----"; + +static void +dump_key_to_pem (const char *key, gsize key_len, int key_type) +{ + char *b64 = NULL; + GString *str = NULL; + const char *start_tag; + const char *end_tag; + char *p; + + switch (key_type) { + case NM_CRYPTO_KEY_TYPE_RSA: + start_tag = pem_rsa_key_begin; + end_tag = pem_rsa_key_end; + break; + case NM_CRYPTO_KEY_TYPE_DSA: + start_tag = pem_dsa_key_begin; + end_tag = pem_dsa_key_end; + break; + default: + g_warning ("Unknown key type %d", key_type); + return; + } + + b64 = g_base64_encode ((const unsigned char *) key, key_len); + if (!b64) { + g_warning ("Couldn't base64 encode the key."); + goto out; + } + + str = g_string_new (NULL); + + g_string_append (str, start_tag); + g_string_append_c (str, '\n'); + + for (p = b64; p < (b64 + strlen (b64)); p += 64) { + g_string_append_len (str, p, strnlen (p, 64)); + g_string_append_c (str, '\n'); + } + + g_string_append (str, end_tag); + g_string_append_c (str, '\n'); + + g_message ("Decrypted private key:\n\n%s", str->str); + +out: + g_free (b64); + if (str) + g_string_free (str, TRUE); +} +#endif + +static void +test_cert(gconstpointer test_data) +{ + gs_free char * path = NULL; + gs_unref_bytes GBytes *cert = NULL; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GError * error = NULL; + gboolean success; + + path = g_build_filename(TEST_CERT_DIR, (const char *) test_data, NULL); + + success = nm_crypto_load_and_verify_certificate(path, &format, &cert, &error); + nmtst_assert_success(success, error); + g_assert_cmpint(format, ==, NM_CRYPTO_FILE_FORMAT_X509); + + g_assert(nm_utils_file_is_certificate(path)); +} + +static void +test_load_private_key(const char *path, + const char *password, + const char *decrypted_path, + int expected_error) +{ + NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + gboolean is_encrypted = FALSE; + gs_unref_bytes GBytes *array = NULL; + GError * error = NULL; + + g_assert(nm_utils_file_is_private_key(path, &is_encrypted)); + g_assert(is_encrypted); + + array = nmtst_crypto_decrypt_openssl_private_key(path, password, &key_type, &error); + /* Even if the password is wrong, we should determine the key type */ + g_assert_cmpint(key_type, ==, NM_CRYPTO_KEY_TYPE_RSA); + + if (expected_error != -1) { + g_assert(array == NULL); + g_assert_error(error, NM_CRYPTO_ERROR, expected_error); + g_clear_error(&error); + return; + } + + if (password == NULL) { + g_assert(array == NULL); + g_assert_no_error(error); + return; + } + + g_assert(array != NULL); + + if (decrypted_path) { + gs_free char *contents = NULL; + gsize length; + + /* Compare the crypto decrypted key against a known-good decryption */ + if (!g_file_get_contents(decrypted_path, &contents, &length, NULL)) + g_assert_not_reached(); + g_assert(nm_utils_gbytes_equal_mem(array, contents, length)); + } +} + +static void +test_load_pkcs12(const char *path, const char *password, int expected_error) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean is_encrypted = FALSE; + GError * error = NULL; + + g_assert(nm_utils_file_is_private_key(path, NULL)); + + format = nm_crypto_verify_private_key(path, password, &is_encrypted, &error); + if (expected_error != -1) { + g_assert_error(error, NM_CRYPTO_ERROR, expected_error); + g_assert_cmpint(format, ==, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + g_clear_error(&error); + } else { + g_assert_no_error(error); + g_assert_cmpint(format, ==, NM_CRYPTO_FILE_FORMAT_PKCS12); + g_assert(is_encrypted); + } +} + +static void +test_load_pkcs12_no_password(const char *path) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean is_encrypted = FALSE; + GError * error = NULL; + + g_assert(nm_utils_file_is_private_key(path, NULL)); + + /* We should still get a valid returned crypto file format */ + format = nm_crypto_verify_private_key(path, NULL, &is_encrypted, &error); + g_assert_no_error(error); + g_assert_cmpint(format, ==, NM_CRYPTO_FILE_FORMAT_PKCS12); + g_assert(is_encrypted); +} + +static void +test_is_pkcs12(const char *path, gboolean expect_fail) +{ + gboolean is_pkcs12; + GError * error = NULL; + + is_pkcs12 = nm_crypto_is_pkcs12_file(path, &error); + + if (expect_fail) { + g_assert_error(error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_INVALID_DATA); + g_assert(!is_pkcs12); + g_clear_error(&error); + } else { + g_assert_no_error(error); + g_assert(is_pkcs12); + } +} + +static void +test_load_pkcs8(const char *path, const char *password, int expected_error) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean is_encrypted = FALSE; + GError * error = NULL; + + g_assert(nm_utils_file_is_private_key(path, NULL)); + + format = nm_crypto_verify_private_key(path, password, &is_encrypted, &error); + if (expected_error != -1) { + g_assert_error(error, NM_CRYPTO_ERROR, expected_error); + g_assert_cmpint(format, ==, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + g_clear_error(&error); + } else { + g_assert_no_error(error); + g_assert_cmpint(format, ==, NM_CRYPTO_FILE_FORMAT_RAW_KEY); + g_assert(is_encrypted); + } +} + +static void +test_encrypt_private_key(const char *path, const char *password) +{ + NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + gs_unref_bytes GBytes *array = NULL; + gs_unref_bytes GBytes *encrypted = NULL; + gs_unref_bytes GBytes *re_decrypted = NULL; + GError * error = NULL; + + array = nmtst_crypto_decrypt_openssl_private_key(path, password, &key_type, &error); + nmtst_assert_success(array, error); + g_assert_cmpint(key_type, ==, NM_CRYPTO_KEY_TYPE_RSA); + + /* Now re-encrypt the private key */ + encrypted = nmtst_crypto_rsa_key_encrypt(g_bytes_get_data(array, NULL), + g_bytes_get_size(array), + password, + NULL, + &error); + nmtst_assert_success(encrypted, error); + + /* Then re-decrypt the private key */ + key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + re_decrypted = nmtst_crypto_decrypt_openssl_private_key_data(g_bytes_get_data(encrypted, NULL), + g_bytes_get_size(encrypted), + password, + &key_type, + &error); + nmtst_assert_success(re_decrypted, error); + g_assert_cmpint(key_type, ==, NM_CRYPTO_KEY_TYPE_RSA); + + /* Compare the original decrypted key with the re-decrypted key */ + g_assert(g_bytes_equal(array, re_decrypted)); +} + +static void +test_key(gconstpointer test_data) +{ + char **parts, *path, *password, *decrypted_path; + int len; + + parts = g_strsplit((const char *) test_data, ", ", -1); + len = g_strv_length(parts); + if (len != 2 && len != 3) + g_error("wrong number of arguments (, , [])"); + + path = g_build_filename(TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + decrypted_path = parts[2] ? g_build_filename(TEST_CERT_DIR, parts[2], NULL) : NULL; + + test_is_pkcs12(path, TRUE); + test_load_private_key(path, password, decrypted_path, -1); + test_load_private_key(path, "blahblahblah", NULL, NM_CRYPTO_ERROR_DECRYPTION_FAILED); + test_load_private_key(path, NULL, NULL, -1); + test_encrypt_private_key(path, password); + + g_free(path); + g_free(decrypted_path); + g_strfreev(parts); +} + +static void +test_key_decrypted(gconstpointer test_data) +{ + const char *file = (const char *) test_data; + gboolean is_encrypted = FALSE; + char * path; + + path = g_build_filename(TEST_CERT_DIR, file, NULL); + + g_assert(nm_utils_file_is_private_key(path, &is_encrypted)); + g_assert(!is_encrypted); + + g_free(path); +} + +static void +test_pkcs12(gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit((const char *) test_data, ", ", -1); + if (g_strv_length(parts) != 2) + g_error("wrong number of arguments (, )"); + + path = g_build_filename(TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + test_is_pkcs12(path, FALSE); + test_load_pkcs12(path, password, -1); + test_load_pkcs12(path, "blahblahblah", NM_CRYPTO_ERROR_DECRYPTION_FAILED); + test_load_pkcs12_no_password(path); + + g_free(path); + g_strfreev(parts); +} + +static void +test_pkcs8(gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit((const char *) test_data, ", ", -1); + if (g_strv_length(parts) != 2) + g_error("wrong number of arguments (, )"); + + path = g_build_filename(TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + test_is_pkcs12(path, TRUE); + /* Note: NSS and gnutls < 3.5.4 don't support all the ciphers that openssl + * can use with PKCS#8 and thus the password can't be actually verified with + * such libraries. + */ + test_load_pkcs8(path, password, -1); + + g_free(path); + g_strfreev(parts); +} + +#define SALT "sodium chloride" +#define SHORT_PASSWORD "short" +#define LONG_PASSWORD "this is a longer password than the short one" +#define SHORT_DIGEST 16 +#define LONG_DIGEST 57 + +struct { + const char *salt, *password; + gsize digest_size; + const char *result; +} md5_tests[] = { + {NULL, SHORT_PASSWORD, SHORT_DIGEST, "4f09daa9d95bcb166a302407a0e0babe"}, + {NULL, + SHORT_PASSWORD, + LONG_DIGEST, + "4f09daa9d95bcb166a302407a0e0babeb7d62e5baf706830d007c253f0fe7584ad7e92dc00a599ec277293c298ae7" + "0ee3904c348e23be61c91"}, + {SALT, SHORT_PASSWORD, SHORT_DIGEST, "774771f7292210233b5724991d1f9894"}, + {SALT, + SHORT_PASSWORD, + LONG_DIGEST, + "774771f7292210233b5724991d1f98941a6ffdb45e4dc7fa04b1fa6aceed379c1ade0577bc8f261d109942ed57369" + "21c052664d72e0d5bade9"}, + {NULL, LONG_PASSWORD, SHORT_DIGEST, "e9c03517f81ff29bb777dac21fb1699c"}, + {NULL, + LONG_PASSWORD, + LONG_DIGEST, + "e9c03517f81ff29bb777dac21fb1699c50968c7ccd8db4f0a59d00ffd87b05876d45f25a927d51a8400c35af60fbd" + "64584349a8b7435d62fd9"}, + {SALT, LONG_PASSWORD, SHORT_DIGEST, "4e5c076e2f85f5e03994acbf3a9e10d6"}, + {SALT, + LONG_PASSWORD, + LONG_DIGEST, + "4e5c076e2f85f5e03994acbf3a9e10d61a6969c9fdf47ae8b1f7e2725b3767b05cc974bfcb5344b630c91761e015e" + "09d7794b5065662533bc9"}, + {NULL, "", SHORT_DIGEST, "d41d8cd98f00b204e9800998ecf8427e"}, + {SALT, "", SHORT_DIGEST, "7df1e0494c977195005d82a1809685e4"}, +}; + +static void +test_md5(void) +{ + char digest[LONG_DIGEST], *hex; + int i; + + for (i = 0; i < G_N_ELEMENTS(md5_tests); i++) { + memset(digest, 0, sizeof(digest)); + nm_crypto_md5_hash((const guint8 *) md5_tests[i].salt, + /* nm_crypto_md5_hash() used to clamp salt_len to 8. It + * doesn't any more, so we need to do it here now to + * get output that matches md5_tests[i].result. + */ + md5_tests[i].salt ? 8 : 0, + (const guint8 *) md5_tests[i].password, + strlen(md5_tests[i].password), + (guint8 *) digest, + md5_tests[i].digest_size); + + hex = nm_utils_bin2hexstr(digest, md5_tests[i].digest_size, -1); + g_assert_cmpstr(hex, ==, md5_tests[i].result); + g_free(hex); + } +} + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + GError * error = NULL; + gboolean success; + int ret; + + nmtst_init(&argc, &argv, TRUE); + + success = _nm_crypto_init(&error); + g_assert_no_error(error); + g_assert(success); + + g_test_add_data_func("/libnm/crypto/cert/pem", "test_ca_cert.pem", test_cert); + g_test_add_data_func("/libnm/crypto/cert/pem-2", "test2_ca_cert.pem", test_cert); + g_test_add_data_func("/libnm/crypto/cert/der", "test_ca_cert.der", test_cert); + g_test_add_data_func("/libnm/crypto/cert/pem-no-ending-newline", + "ca-no-ending-newline.pem", + test_cert); + g_test_add_data_func("/libnm/crypto/cert/pem-combined", "test_key_and_cert.pem", test_cert); + g_test_add_data_func("/libnm/crypto/cert/pem-combined-2", "test2_key_and_cert.pem", test_cert); + + g_test_add_data_func("/libnm/crypto/key/padding-6", + "test_key_and_cert.pem, test, test-key-only-decrypted.der", + test_key); + g_test_add_data_func("/libnm/crypto/key/key-only", + "test-key-only.pem, test, test-key-only-decrypted.der", + test_key); + g_test_add_data_func("/libnm/crypto/key/padding-8", + "test2_key_and_cert.pem, 12345testing", + test_key); + g_test_add_data_func("/libnm/crypto/key/aes-128", + "test-aes-128-key.pem, test-aes-password", + test_key); + g_test_add_data_func("/libnm/crypto/key/aes-256", + "test-aes-256-key.pem, test-aes-password", + test_key); + g_test_add_data_func("/libnm/crypto/key/decrypted", + "test-key-only-decrypted.pem", + test_key_decrypted); + + g_test_add_data_func("/libnm/crypto/PKCS#12/1", "test-cert.p12, test", test_pkcs12); + g_test_add_data_func("/libnm/crypto/PKCS#12/2", "test2-cert.p12, 12345testing", test_pkcs12); + + g_test_add_data_func("/libnm/crypto/PKCS#8", "pkcs8-enc-key.pem, 1234567890", test_pkcs8); + + g_test_add_func("/libnm/crypto/md5", test_md5); + + ret = g_test_run(); + + return ret; +} diff --git a/src/libnm-core-impl/tests/test-general-enums.h b/src/libnm-core-impl/tests/test-general-enums.h new file mode 100644 index 0000000..b3163e2 --- /dev/null +++ b/src/libnm-core-impl/tests/test-general-enums.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef _NM_TEST_GENERAL_ENUMS_H_ +#define _NM_TEST_GENERAL_ENUMS_H_ + +typedef enum { + NM_TEST_GENERAL_BOOL_ENUM_NO = 0, + NM_TEST_GENERAL_BOOL_ENUM_YES = 1, + NM_TEST_GENERAL_BOOL_ENUM_MAYBE = 2, + NM_TEST_GENERAL_BOOL_ENUM_UNKNOWN = 3, + NM_TEST_GENERAL_BOOL_ENUM_INVALID = 4, /*< skip >*/ + NM_TEST_GENERAL_BOOL_ENUM_67 = 67, + NM_TEST_GENERAL_BOOL_ENUM_46 = 64, +} NMTestGeneralBoolEnum; + +typedef enum { + NM_TEST_GENERAL_META_FLAGS_NONE = 0, + NM_TEST_GENERAL_META_FLAGS_FOO = (1 << 0), + NM_TEST_GENERAL_META_FLAGS_BAR = (1 << 1), + NM_TEST_GENERAL_META_FLAGS_BAZ = (1 << 2), + NM_TEST_GENERAL_META_FLAGS_0x8 = (1 << 3), + NM_TEST_GENERAL_META_FLAGS_0x4 = (1 << 4), +} NMTestGeneralMetaFlags; + +typedef enum { /*< flags >*/ + NM_TEST_GENERAL_COLOR_FLAGS_WHITE = 1, /*< skip >*/ + NM_TEST_GENERAL_COLOR_FLAGS_BLUE = 2, + NM_TEST_GENERAL_COLOR_FLAGS_RED = 4, + NM_TEST_GENERAL_COLOR_FLAGS_GREEN = 8, +} NMTestGeneralColorFlags; + +#endif /* _NM_TEST_GENERAL_ENUMS_H_ */ diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c new file mode 100644 index 0000000..f754016 --- /dev/null +++ b/src/libnm-core-impl/tests/test-general.c @@ -0,0 +1,10870 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2008 - 2018 Red Hat, Inc. + */ + +#define NM_GLIB_COMPAT_H_TEST + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include +#include +#include +#include +#include + +#include "libnm-std-aux/c-list-util.h" +#include "libnm-glib-aux/nm-enum-utils.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-json-aux.h" +#include "libnm-base/nm-base.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" + +#include "nm-utils.h" +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-core-tests-enum-types.h" +#include "nm-team-utils.h" + +#include "nm-setting-8021x.h" +#include "nm-setting-adsl.h" +#include "nm-setting-bluetooth.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-ethtool.h" +#include "nm-setting-generic.h" +#include "nm-setting-gsm.h" +#include "nm-setting-infiniband.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" +#include "nm-setting-olpc-mesh.h" +#include "nm-setting-ppp.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-serial.h" +#include "nm-setting-team.h" +#include "nm-setting-team-port.h" +#include "nm-setting-user.h" +#include "nm-setting-vlan.h" +#include "nm-setting-vpn.h" +#include "nm-setting-wimax.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-wpan.h" +#include "nm-simple-connection.h" +#include "libnm-core-intern/nm-keyfile-internal.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-base/nm-ethtool-base.h" +#include "libnm-base/nm-ethtool-utils-base.h" + +#include "test-general-enums.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +/* When passing a "bool" typed argument to a variadic function that + * expects a gboolean, the compiler will promote the integer type + * to have at least size (int). That way: + * g_object_set (obj, PROP_BOOL, bool_val, NULL); + * will just work correctly. */ +G_STATIC_ASSERT(sizeof(gboolean) == sizeof(int)); +G_STATIC_ASSERT(sizeof(bool) <= sizeof(int)); + +/*****************************************************************************/ + +/* NM_UTILS_HWADDR_LEN_MAX is public API of libnm(-core) and _NM_UTILS_HWADDR_LEN_MAX + * is internal API. They are the same, but the latter can be used without including libnm-core. */ +G_STATIC_ASSERT(NM_UTILS_HWADDR_LEN_MAX == _NM_UTILS_HWADDR_LEN_MAX); + +/*****************************************************************************/ + +static void +test_nm_ascii_spaces(void) +{ + int i; + const char *const S = NM_ASCII_SPACES; + + for (i = 0; S[i]; i++) + g_assert(!strchr(&S[i + 1], S[i])); + + for (i = 0; S[i] != '\0'; i++) + g_assert(g_ascii_isspace(S[i])); + + g_assert(!g_ascii_isspace((char) 0)); + for (i = 1; i < 0x100; i++) { + if (g_ascii_isspace((char) i)) + g_assert(strchr(S, (char) i)); + else + g_assert(!strchr(S, (char) i)); + } +} + +/*****************************************************************************/ + +static void +test_wired_wake_on_lan_enum(void) +{ + nm_auto_unref_gtypeclass GFlagsClass *flags_class = NULL; + gs_unref_hashtable GHashTable *vals = g_hash_table_new(nm_direct_hash, NULL); + guint i; + + G_STATIC_ASSERT_EXPR(sizeof(NMSettingWiredWakeOnLan) == sizeof(_NMSettingWiredWakeOnLan)); + G_STATIC_ASSERT_EXPR(sizeof(NMSettingWiredWakeOnLan) < sizeof(gint64)); + + G_STATIC_ASSERT_EXPR(sizeof(NMSettingWiredWakeOnLan) < sizeof(gint64)); + g_assert((((gint64)((NMSettingWiredWakeOnLan) -1)) < 0) + == (((gint64)((_NMSettingWiredWakeOnLan) -1)) < 0)); + +#define _E(n) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT_EXPR(n == (gint64) _##n); \ + G_STATIC_ASSERT_EXPR(_##n == (gint64) n); \ + g_assert(_##n == _NM_SETTING_WIRED_WAKE_ON_LAN_CAST(n)); \ + if (!g_hash_table_add(vals, GUINT_TO_POINTER(n))) \ + g_assert_not_reached(); \ + } \ + G_STMT_END + _E(NM_SETTING_WIRED_WAKE_ON_LAN_NONE); + _E(NM_SETTING_WIRED_WAKE_ON_LAN_PHY); + _E(NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST); + _E(NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST); + _E(NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST); + _E(NM_SETTING_WIRED_WAKE_ON_LAN_ARP); + _E(NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC); + _E(NM_SETTING_WIRED_WAKE_ON_LAN_ALL); + _E(NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT); + _E(NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE); + _E(NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS); +#undef _E + + flags_class = G_FLAGS_CLASS(g_type_class_ref(NM_TYPE_SETTING_WIRED_WAKE_ON_LAN)); + for (i = 0; i < flags_class->n_values; i++) { + const GFlagsValue *value = &flags_class->values[i]; + + if (!g_hash_table_contains(vals, GUINT_TO_POINTER(value->value))) { + g_error("The enum value %s from NMSettingWiredWakeOnLan is not checked for " + "_NMSettingWiredWakeOnLan", + value->value_name); + } + } +} + +/*****************************************************************************/ + +static void +test_wireless_wake_on_wlan_enum(void) +{ + nm_auto_unref_gtypeclass GFlagsClass *flags_class = NULL; + gs_unref_hashtable GHashTable *vals = g_hash_table_new(nm_direct_hash, NULL); + guint i; + + G_STATIC_ASSERT_EXPR(sizeof(NMSettingWirelessWakeOnWLan) + == sizeof(_NMSettingWirelessWakeOnWLan)); + G_STATIC_ASSERT_EXPR(sizeof(NMSettingWirelessWakeOnWLan) < sizeof(gint64)); + + G_STATIC_ASSERT_EXPR(sizeof(NMSettingWirelessWakeOnWLan) < sizeof(gint64)); + g_assert((((gint64)((NMSettingWirelessWakeOnWLan) -1)) < 0) + == (((gint64)((_NMSettingWirelessWakeOnWLan) -1)) < 0)); + +#define _E(n) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT_EXPR(n == (gint64) _##n); \ + G_STATIC_ASSERT_EXPR(_##n == (gint64) n); \ + g_assert(_##n == _NM_SETTING_WIRELESS_WAKE_ON_WLAN_CAST(n)); \ + if (!g_hash_table_add(vals, GUINT_TO_POINTER(n))) \ + g_assert_not_reached(); \ + } \ + G_STMT_END + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE); + _E(NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS); +#undef _E + + flags_class = G_FLAGS_CLASS(g_type_class_ref(NM_TYPE_SETTING_WIRELESS_WAKE_ON_WLAN)); + for (i = 0; i < flags_class->n_values; i++) { + const GFlagsValue *value = &flags_class->values[i]; + + if (!g_hash_table_contains(vals, GUINT_TO_POINTER(value->value))) { + g_error("The enum value %s from NMSettingWirelessWakeOnWLan is not checked for " + "_NMSettingWirelessWakeOnWLan", + value->value_name); + } + } +} + +/*****************************************************************************/ + +static void +test_device_wifi_capabilities(void) +{ + nm_auto_unref_gtypeclass GFlagsClass *flags_class = NULL; + gs_unref_hashtable GHashTable *vals = g_hash_table_new(nm_direct_hash, NULL); + guint i; + + G_STATIC_ASSERT_EXPR(sizeof(NMDeviceWifiCapabilities) == sizeof(_NMDeviceWifiCapabilities)); + G_STATIC_ASSERT_EXPR(sizeof(NMDeviceWifiCapabilities) < sizeof(gint64)); + + G_STATIC_ASSERT_EXPR(sizeof(NMDeviceWifiCapabilities) < sizeof(gint64)); + g_assert((((gint64)((NMDeviceWifiCapabilities) -1)) < 0) + == (((gint64)((_NMDeviceWifiCapabilities) -1)) < 0)); + +#define _E(n) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT_EXPR(n == (gint64) _##n); \ + G_STATIC_ASSERT_EXPR(_##n == (gint64) n); \ + if (!g_hash_table_add(vals, GUINT_TO_POINTER(n))) \ + g_assert_not_reached(); \ + } \ + G_STMT_END + _E(NM_WIFI_DEVICE_CAP_NONE); + _E(NM_WIFI_DEVICE_CAP_CIPHER_WEP40); + _E(NM_WIFI_DEVICE_CAP_CIPHER_WEP104); + _E(NM_WIFI_DEVICE_CAP_CIPHER_TKIP); + _E(NM_WIFI_DEVICE_CAP_CIPHER_CCMP); + _E(NM_WIFI_DEVICE_CAP_WPA); + _E(NM_WIFI_DEVICE_CAP_RSN); + _E(NM_WIFI_DEVICE_CAP_AP); + _E(NM_WIFI_DEVICE_CAP_ADHOC); + _E(NM_WIFI_DEVICE_CAP_FREQ_VALID); + _E(NM_WIFI_DEVICE_CAP_FREQ_2GHZ); + _E(NM_WIFI_DEVICE_CAP_FREQ_5GHZ); + _E(NM_WIFI_DEVICE_CAP_MESH); + _E(NM_WIFI_DEVICE_CAP_IBSS_RSN); +#undef _E + + flags_class = G_FLAGS_CLASS(g_type_class_ref(NM_TYPE_DEVICE_WIFI_CAPABILITIES)); + for (i = 0; i < flags_class->n_values; i++) { + const GFlagsValue *value = &flags_class->values[i]; + + if (!g_hash_table_contains(vals, GUINT_TO_POINTER(value->value))) { + g_error("The enum value %s from NMDeviceWifiCapabilities is not checked for " + "_NMDeviceWifiCapabilities", + value->value_name); + } + } +} + +/*****************************************************************************/ + +static void +test_80211_mode(void) +{ + nm_auto_unref_gtypeclass GEnumClass *enum_class = NULL; + gs_unref_hashtable GHashTable *vals = g_hash_table_new(nm_direct_hash, NULL); + guint i; + + G_STATIC_ASSERT_EXPR(sizeof(NM80211Mode) == sizeof(_NM80211Mode)); + G_STATIC_ASSERT_EXPR(sizeof(NM80211Mode) < sizeof(gint64)); + + G_STATIC_ASSERT_EXPR(sizeof(NM80211Mode) < sizeof(gint64)); + g_assert((((gint64)((NM80211Mode) -1)) < 0) == (((gint64)((_NM80211Mode) -1)) < 0)); + +#define _E(n) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT_EXPR(n == (gint64) _##n); \ + G_STATIC_ASSERT_EXPR(_##n == (gint64) n); \ + g_assert(n == NM_802_11_MODE_CAST(_##n)); \ + if (!g_hash_table_add(vals, GINT_TO_POINTER(n))) \ + g_assert_not_reached(); \ + } \ + G_STMT_END + _E(NM_802_11_MODE_UNKNOWN); + _E(NM_802_11_MODE_ADHOC); + _E(NM_802_11_MODE_INFRA); + _E(NM_802_11_MODE_AP); + _E(NM_802_11_MODE_MESH); +#undef _E + + enum_class = G_ENUM_CLASS(g_type_class_ref(NM_TYPE_802_11_MODE)); + for (i = 0; i < enum_class->n_values; i++) { + const GEnumValue *value = &enum_class->values[i]; + + if (!g_hash_table_contains(vals, GINT_TO_POINTER(value->value))) { + g_error("The enum value %s from NM80211Mode is not checked for " + "_NM80211Mode", + value->value_name); + } + } +} + +/*****************************************************************************/ + +static void +test_vlan_flags(void) +{ + nm_auto_unref_gtypeclass GFlagsClass *flags_class = NULL; + gs_unref_hashtable GHashTable *vals = g_hash_table_new(nm_direct_hash, NULL); + guint i; + + G_STATIC_ASSERT_EXPR(sizeof(NMVlanFlags) == sizeof(_NMVlanFlags)); + G_STATIC_ASSERT_EXPR(sizeof(NMVlanFlags) < sizeof(gint64)); + + G_STATIC_ASSERT_EXPR(sizeof(NMVlanFlags) < sizeof(gint64)); + g_assert((((gint64)((NMVlanFlags) -1)) < 0) == (((gint64)((_NMVlanFlags) -1)) < 0)); + +#define _E(n) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT_EXPR(n == (gint64) _##n); \ + G_STATIC_ASSERT_EXPR(_##n == (gint64) n); \ + g_assert(n == NM_VLAN_FLAGS_CAST(_##n)); \ + if (!g_hash_table_add(vals, GUINT_TO_POINTER(n))) \ + g_assert_not_reached(); \ + } \ + G_STMT_END + _E(NM_VLAN_FLAG_REORDER_HEADERS); + _E(NM_VLAN_FLAG_GVRP); + _E(NM_VLAN_FLAG_LOOSE_BINDING); + _E(NM_VLAN_FLAG_MVRP); + _E(NM_VLAN_FLAGS_ALL); +#undef _E + + flags_class = G_FLAGS_CLASS(g_type_class_ref(NM_TYPE_VLAN_FLAGS)); + for (i = 0; i < flags_class->n_values; i++) { + const GFlagsValue *value = &flags_class->values[i]; + + if (!g_hash_table_contains(vals, GUINT_TO_POINTER(value->value))) { + g_error("The enum value %s from NMVlanFlags is not checked for " + "_NMVlanFlags", + value->value_name); + } + } +} + +/*****************************************************************************/ + +typedef struct _nm_packed { + int v0; + char v1; + double v2; + guint8 v3; +} TestHashStruct; + +static void +_test_hash_struct(int v0, char v1, double v2, guint8 v3) +{ + const TestHashStruct s = { + .v0 = v0, + .v1 = v1, + .v2 = v2, + .v3 = v3, + }; + NMHashState h; + guint hh; + + nm_hash_init(&h, 100); + nm_hash_update(&h, &s, sizeof(s)); + hh = nm_hash_complete(&h); + + nm_hash_init(&h, 100); + nm_hash_update_val(&h, v0); + nm_hash_update_val(&h, v1); + nm_hash_update_val(&h, v2); + nm_hash_update_val(&h, v3); + g_assert_cmpint(hh, ==, nm_hash_complete(&h)); + + nm_hash_init(&h, 100); + nm_hash_update_vals(&h, v0, v1, v2, v3); + g_assert_cmpint(hh, ==, nm_hash_complete(&h)); +} + +static guint +_test_hash_str(const char *str) +{ + NMHashState h; + guint v, v2; + const guint SEED = 10; + + nm_hash_init(&h, SEED); + nm_hash_update_str0(&h, str); + v = nm_hash_complete(&h); + + /* assert that hashing a string and a buffer yields the + * same result. + * + * I think that is a desirable property. */ + nm_hash_init(&h, SEED); + nm_hash_update_mem(&h, str, strlen(str)); + v2 = nm_hash_complete(&h); + + g_assert(v == v2); + return v; +} + +#define _test_hash_vals(type, ...) \ + G_STMT_START \ + { \ + NMHashState h0, h1, h2, h3; \ + const type v[] = {__VA_ARGS__}; \ + guint h; \ + guint i; \ + \ + nm_hash_init(&h0, 10); \ + nm_hash_init(&h1, 10); \ + nm_hash_init(&h2, 10); \ + nm_hash_init(&h3, 10); \ + \ + /* assert that it doesn't matter, whether we hash the values individually, + * or all at once, or via the convenience macros nm_hash_update_val() + * and nm_hash_update_vals(). */ \ + for (i = 0; i < G_N_ELEMENTS(v); i++) { \ + nm_hash_update(&h0, &v[i], sizeof(type)); \ + nm_hash_update_val(&h1, v[i]); \ + } \ + nm_hash_update_vals(&h2, __VA_ARGS__); \ + nm_hash_update(&h3, v, sizeof(v)); \ + \ + h = nm_hash_complete(&h0); \ + g_assert_cmpint(h, ==, nm_hash_complete(&h1)); \ + g_assert_cmpint(h, ==, nm_hash_complete(&h2)); \ + g_assert_cmpint(h, ==, nm_hash_complete(&h3)); \ + } \ + G_STMT_END + +static void +test_nm_hash(void) +{ + g_assert(nm_hash_static(0)); + g_assert(nm_hash_static(777)); + + g_assert(nm_hash_str(NULL)); + g_assert(nm_hash_str("")); + g_assert(nm_hash_str("a")); + + g_assert(nm_hash_ptr(NULL)); + g_assert(nm_hash_ptr("")); + g_assert(nm_hash_ptr("a")); + + _test_hash_str(""); + _test_hash_str("a"); + _test_hash_str("aa"); + _test_hash_str("diceros bicornis longipes"); + + /* assert that nm_hash_update_vals() is the same as calling nm_hash_update_val() multiple times. */ + _test_hash_vals(int, 1); + _test_hash_vals(int, 1, 2); + _test_hash_vals(int, 1, 2, 3); + _test_hash_vals(int, 1, 2, 3, 4); + _test_hash_vals(long, 1l); + _test_hash_vals(long, 1l, 2l, 3l, 4l, 5l); + + _test_hash_struct(10, 'a', 5.4, 7); + _test_hash_struct(-10, '\0', -5.4e49, 255); + + g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint8, 1, 0), ==, 0x002); + g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint8, 1, 1), ==, 0x003); + g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint8, 1, 1, 0, 0, 0, 0), ==, 0x030); + g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint8, 1, 1, 0, 0, 0, 1), ==, 0x031); + g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint8, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x031); + g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint16, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x031); + g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint16, 0, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x031); + g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint16, 1, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x131); +} + +/*****************************************************************************/ + +static void +test_nm_g_slice_free_fcn(void) +{ + gpointer p; + struct { + char a1; + char a2; + } xx; + + p = g_slice_new(gint64); + (nm_g_slice_free_fcn(gint64))(p); + + p = g_slice_new(gint32); + (nm_g_slice_free_fcn(gint32))(p); + + p = g_slice_new(int); + (nm_g_slice_free_fcn(int))(p); + + p = g_slice_new(gint64); + nm_g_slice_free_fcn_gint64(p); + + p = g_slice_alloc(sizeof(xx)); + (nm_g_slice_free_fcn(xx))(p); +} + +/*****************************************************************************/ + +static void +_do_test_nm_utils_strsplit_set_f_one(NMUtilsStrsplitSetFlags flags, + const char * str, + gsize words_len, + const char *const * exp_words) +{ +#define DELIMITERS " \n" +#define DELIMITERS_C ' ', '\n' + + gs_free const char **words = NULL; + gsize i, j, k; + const gboolean f_allow_escaping = + NM_FLAGS_HAS(flags, NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING); + const gboolean f_preserve_empty = + NM_FLAGS_HAS(flags, NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY); + const char * s1; + gsize initial_offset; + gs_strfreev char **words_g = NULL; + + g_assert(!NM_FLAGS_ANY(flags, + ~(NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING + | NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY))); + + /* assert that the expected words are valid (and don't contain unescaped delimiters). */ + for (i = 0; i < words_len; i++) { + const char *w = exp_words[i]; + + g_assert(w); + if (!f_preserve_empty) + g_assert(w[0]); + for (k = 0; w[k];) { + if (f_allow_escaping && w[k] == '\\') { + k++; + if (w[k] == '\0') + break; + k++; + continue; + } + g_assert(!NM_IN_SET(w[k], DELIMITERS_C)); + k++; + } + if (!f_allow_escaping) + g_assert(!NM_STRCHAR_ANY(w, ch, NM_IN_SET(ch, DELIMITERS_C))); + } + + initial_offset = (f_preserve_empty || !str) ? 0u : strspn(str, DELIMITERS); + + /* first compare our expected values with what g_strsplit_set() would + * do. */ + words_g = str ? g_strsplit_set(str, DELIMITERS, -1) : NULL; + if (str == NULL) { + g_assert_cmpint(words_len, ==, 0); + g_assert(!words_g); + } else if (nm_streq0(str, "")) { + g_assert_cmpint(words_len, ==, 0); + g_assert(words_g); + g_assert(!words_g[0]); + } else { + g_assert(words_g); + g_assert(words_g[0]); + if (!f_allow_escaping) { + if (!f_preserve_empty) { + for (i = 0, j = 0; words_g[i]; i++) { + if (words_g[i][0] == '\0') + g_free(words_g[i]); + else + words_g[j++] = words_g[i]; + } + words_g[j] = NULL; + } + if (f_preserve_empty) + g_assert_cmpint(words_len, >, 0); + for (i = 0; i < words_len; i++) { + g_assert(exp_words[i]); + g_assert_cmpstr(exp_words[i], ==, words_g[i]); + } + g_assert(words_g[words_len] == NULL); + g_assert_cmpint(NM_PTRARRAY_LEN(words_g), ==, words_len); + g_assert(nm_utils_strv_cmp_n(exp_words, words_len, words_g, -1) == 0); + } + } + + if (flags == NM_UTILS_STRSPLIT_SET_FLAGS_NONE && nmtst_get_rand_bool()) + words = nm_utils_strsplit_set(str, DELIMITERS); + else if (flags == NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY && nmtst_get_rand_bool()) + words = nm_utils_strsplit_set_with_empty(str, DELIMITERS); + else + words = nm_utils_strsplit_set_full(str, DELIMITERS, flags); + + g_assert_cmpint(NM_PTRARRAY_LEN(words), ==, words_len); + + if (words_len == 0) { + g_assert(!words); + g_assert(!str || NM_STRCHAR_ALL(str, ch, NM_IN_SET(ch, DELIMITERS_C))); + return; + } + + g_assert(words); + for (i = 0; i < words_len; i++) + g_assert_cmpstr(exp_words[i], ==, words[i]); + g_assert(words[words_len] == NULL); + + g_assert(nm_utils_strv_cmp_n(exp_words, words_len, words, -1) == 0); + + s1 = words[0]; + g_assert(s1 >= (char *) &words[words_len + 1]); + s1 = &s1[strlen(str)]; + for (i = 1; i < words_len; i++) { + g_assert(&(words[i - 1])[strlen(words[i - 1])] < words[i]); + g_assert(words[i] <= s1); + } + + /* while strsplit removes all delimiters, we can relatively easily find them + * in the original string. Assert that the original string and the pointer offsets + * of words correspond. In particular, find idx_delim_after and idx_delim_before + * to determine which delimiter was after/before a word. */ + { + gsize idx_word_start; + gsize idx_delim_after_old = G_MAXSIZE; + + idx_word_start = initial_offset; + for (i = 0; i < words_len; i++) { + const gsize l_i = strlen(words[i]); + gsize idx_delim_after; + gsize idx_delim_before; + + /* find the delimiter *after* words[i]. We can do that by looking at the next + * word and calculating the pointer difference. + * + * The delimiter after the very last word is '\0' and requires strlen() to find. */ + idx_delim_after = initial_offset + ((words[i] - words[0]) + l_i); + if (idx_delim_after != idx_word_start + l_i) { + g_assert(!f_preserve_empty); + g_assert_cmpint(idx_word_start + l_i, <, idx_delim_after); + idx_word_start = idx_delim_after - l_i; + } + if (i + 1 < words_len) { + gsize x = initial_offset + ((words[i + 1] - words[0]) - 1); + + if (idx_delim_after != x) { + g_assert(!f_preserve_empty); + g_assert_cmpint(idx_delim_after, <, x); + for (k = idx_delim_after; k <= x; k++) + g_assert(NM_IN_SET(str[k], DELIMITERS_C)); + } + g_assert(NM_IN_SET(str[idx_delim_after], DELIMITERS_C)); + } else { + if (f_preserve_empty) + g_assert(NM_IN_SET(str[idx_delim_after], '\0')); + else + g_assert(NM_IN_SET(str[idx_delim_after], '\0', DELIMITERS_C)); + } + + /* find the delimiter *before* words[i]. */ + if (i == 0) { + /* there is only a delimiter *before*, with !f_preserve_empty and leading + * delimiters. */ + idx_delim_before = G_MAXSIZE; + if (initial_offset > 0) { + g_assert(!f_preserve_empty); + idx_delim_before = initial_offset - 1; + } + } else + idx_delim_before = initial_offset + (words[i] - words[0]) - 1; + if (idx_delim_before != G_MAXSIZE) + g_assert(NM_IN_SET(str[idx_delim_before], DELIMITERS_C)); + if (idx_delim_after_old != idx_delim_before) { + g_assert(!f_preserve_empty); + if (i == 0) { + g_assert_cmpint(initial_offset, >, 0); + g_assert_cmpint(idx_delim_before, !=, G_MAXSIZE); + g_assert_cmpint(idx_delim_before, ==, initial_offset - 1); + } else { + g_assert_cmpint(idx_delim_after_old, !=, G_MAXSIZE); + g_assert_cmpint(idx_delim_before, !=, G_MAXSIZE); + g_assert_cmpint(idx_delim_after_old, <, idx_delim_before); + for (k = idx_delim_after_old; k <= idx_delim_before; k++) + g_assert(NM_IN_SET(str[k], DELIMITERS_C)); + } + } + + for (k = 0; k < l_i;) { + if (f_allow_escaping && str[idx_word_start + k] == '\\') { + k++; + if (k >= l_i) + break; + k++; + continue; + } + g_assert(!NM_IN_SET(str[idx_word_start + k], DELIMITERS_C)); + k++; + } + g_assert(strncmp(words[i], &str[idx_word_start], l_i) == 0); + + if (i > 0) { + const char *s = &(words[i - 1])[strlen(words[i - 1]) + 1]; + + if (s != words[i]) { + g_assert(!f_preserve_empty); + g_assert(s < words[i]); + } + } + + idx_word_start += l_i + 1; + idx_delim_after_old = idx_delim_after; + } + } +} + +static void +_do_test_nm_utils_strsplit_set_f(NMUtilsStrsplitSetFlags flags, + const char * str, + gsize words_len, + const char *const * exp_words) +{ + _do_test_nm_utils_strsplit_set_f_one(flags, str, words_len, exp_words); + + if (NM_FLAGS_HAS(flags, NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY)) { + gs_unref_ptrarray GPtrArray *exp_words2 = NULL; + gsize k; + + exp_words2 = g_ptr_array_new(); + for (k = 0; k < words_len; k++) { + if (exp_words[k][0] != '\0') + g_ptr_array_add(exp_words2, (gpointer) exp_words[k]); + } + + _do_test_nm_utils_strsplit_set_f_one(flags & (~NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY), + str, + exp_words2->len, + (const char *const *) exp_words2->pdata); + } +} + +#define do_test_nm_utils_strsplit_set_f(flags, str, ...) \ + _do_test_nm_utils_strsplit_set_f(flags, str, NM_NARG(__VA_ARGS__), NM_MAKE_STRV(__VA_ARGS__)) + +#define do_test_nm_utils_strsplit_set(allow_escaping, str, ...) \ + do_test_nm_utils_strsplit_set_f((allow_escaping) ? NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING \ + : NM_UTILS_STRSPLIT_SET_FLAGS_NONE, \ + str, \ + ##__VA_ARGS__) + +static void +_do_test_nm_utils_strsplit_set_simple(NMUtilsStrsplitSetFlags flags, + const char * str, + gsize words_len, + const char *const * exp_words) +{ + gs_free const char **tokens = NULL; + gsize n_tokens; + + tokens = nm_utils_strsplit_set_full(str, DELIMITERS, flags); + + if (!tokens) { + g_assert_cmpint(words_len, ==, 0); + return; + } + + g_assert(str && str[0]); + g_assert_cmpint(words_len, >, 0); + n_tokens = NM_PTRARRAY_LEN(tokens); + + if (nm_utils_strv_cmp_n(exp_words, words_len, tokens, -1) != 0) { + gsize i; + + g_print(">>> split \"%s\" (flags %x) got %zu tokens (%zu expected)\n", + str, + (guint) flags, + n_tokens, + words_len); + for (i = 0; i < NM_MAX(n_tokens, words_len); i++) { + const char *s1 = i < n_tokens ? tokens[i] : NULL; + const char *s2 = i < words_len ? exp_words[i] : NULL; + + g_print(">>> [%zu]: %s - %s%s%s vs. %s%s%s\n", + i, + nm_streq0(s1, s2) ? "same" : "diff", + NM_PRINT_FMT_QUOTE_STRING(s1), + NM_PRINT_FMT_QUOTE_STRING(s2)); + } + g_assert_not_reached(); + } + g_assert_cmpint(words_len, ==, NM_PTRARRAY_LEN(tokens)); +} +#define do_test_nm_utils_strsplit_set_simple(flags, str, ...) \ + _do_test_nm_utils_strsplit_set_simple((flags), \ + (str), \ + NM_NARG(__VA_ARGS__), \ + NM_MAKE_STRV(__VA_ARGS__)) + +static void +test_nm_utils_strsplit_set(void) +{ + gs_unref_ptrarray GPtrArray *words_exp = NULL; + guint test_run; + + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_NONE, NULL); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_NONE, ""); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_NONE, " "); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_NONE, "a b", "a", "b"); + + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, NULL); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, ""); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, " ", "", ""); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, " ", "", "", ""); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, "a ", "a", "", ""); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + "a b", + "a", + "", + "b"); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + " ab b", + "", + "ab", + "", + "b"); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + "ab b", + "ab", + "", + "b"); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, "abb", "abb"); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + "abb bb ", + "abb", + "", + "bb", + ""); + do_test_nm_utils_strsplit_set_f(NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + "abb bcb ", + "abb", + "bcb", + ""); + + do_test_nm_utils_strsplit_set(FALSE, NULL); + do_test_nm_utils_strsplit_set(FALSE, ""); + do_test_nm_utils_strsplit_set(FALSE, "\n"); + do_test_nm_utils_strsplit_set(TRUE, " \t\n", "\t"); + do_test_nm_utils_strsplit_set(FALSE, "a", "a"); + do_test_nm_utils_strsplit_set(FALSE, "a b", "a", "b"); + do_test_nm_utils_strsplit_set(FALSE, "a\rb", "a\rb"); + do_test_nm_utils_strsplit_set(FALSE, " a\rb ", "a\rb"); + do_test_nm_utils_strsplit_set(FALSE, " a bbbd afds ere", "a", "bbbd", "afds", "ere"); + do_test_nm_utils_strsplit_set(FALSE, + "1 2 3 4 5 6 7 8 9 0 " + "1 2 3 4 5 6 7 8 9 0 " + "1 2 3 4 5 6 7 8 9 0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0"); + do_test_nm_utils_strsplit_set(TRUE, "\\", "\\"); + do_test_nm_utils_strsplit_set(TRUE, "\\ ", "\\ "); + do_test_nm_utils_strsplit_set(TRUE, "\\\\", "\\\\"); + do_test_nm_utils_strsplit_set(TRUE, "\\\t", "\\\t"); + do_test_nm_utils_strsplit_set(TRUE, "foo\\", "foo\\"); + do_test_nm_utils_strsplit_set(TRUE, "bar foo\\", "bar", "foo\\"); + do_test_nm_utils_strsplit_set(TRUE, "\\ a b\\ \\ c", "\\ a", "b\\ \\ ", "c"); + + words_exp = g_ptr_array_new_with_free_func(g_free); + for (test_run = 0; test_run < 100; test_run++) { + gboolean f_allow_escaping = nmtst_get_rand_bool(); + guint words_len = nmtst_get_rand_uint32() % 100; + gs_free char *str = NULL; + guint i; + + g_ptr_array_set_size(words_exp, 0); + for (i = 0; i < words_len; i++) { + guint word_len; + char *word; + guint j; + + word_len = nmtst_get_rand_uint32(); + if ((word_len % 100) < 30) + word_len = 0; + else + word_len = (word_len >> 10) % 100; + word = g_new(char, word_len + 3); + for (j = 0; j < word_len;) { + guint32 p = nmtst_get_rand_uint32(); + static const char delimiters_arr[] = {DELIMITERS_C}; + static const char regular_chars[] = "abcdefghijklmnopqrstuvwxyz"; + + if (!f_allow_escaping || (p % 1000) < 700) { + if (((p >> 20) % 100) < 20) + word[j++] = '\\'; + word[j++] = regular_chars[(p >> 11) % (G_N_ELEMENTS(regular_chars) - 1)]; + continue; + } + word[j++] = '\\'; + word[j++] = delimiters_arr[(p >> 11) % G_N_ELEMENTS(delimiters_arr)]; + } + word[j] = '\0'; + g_ptr_array_add(words_exp, word); + } + g_ptr_array_add(words_exp, NULL); + + str = g_strjoinv(" ", (char **) words_exp->pdata); + + if (str[0] == '\0' && words_len > 0) { + g_assert(words_len == 1); + g_assert_cmpstr(words_exp->pdata[0], ==, ""); + words_len = 0; + } + + _do_test_nm_utils_strsplit_set_f((f_allow_escaping + ? NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING + : NM_UTILS_STRSPLIT_SET_FLAGS_NONE) + | NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + str, + words_len, + (const char *const *) words_exp->pdata); + } + + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED, "\t", "\t"); + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED + | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP, + "\t"); + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED + | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP + | NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + "\t", + ""); + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED + | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP + | NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + "\t\\\t\t\t\\\t", + "\t\t\t\t"); + + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED, "\ta", "\ta"); + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED + | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP, + "\ta", + "a"); + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED, + "\ta\\ b\t\\ ", + "\ta b\t "); + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED + | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP, + "\ta\\ b\t\\ \t", + "a b\t "); + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED, "a\\ b", "a ", "b"); + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED, + "\ta\\ b", + "\ta ", + "b"); + do_test_nm_utils_strsplit_set_simple(NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED + | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP, + "\ta\\ b", + "a ", + "b"); +} + +/*****************************************************************************/ + +static char * +_escaped_tokens_create_random_word_full(const char *const *tokens, gsize n_tokens, gsize len) +{ + GString *gstr = g_string_new(NULL); + gsize i; + char random_token[2] = {0}; + + for (i = 0; i < len; i++) { + const char *token = tokens[nmtst_get_rand_uint32() % n_tokens]; + + if (!token[0]) { + do { + random_token[0] = nmtst_get_rand_uint32(); + } while (random_token[0] == '\0'); + token = random_token; + } + g_string_append(gstr, token); + } + + /* reallocate the string, so that we don't have any excess memory from + * the GString buffer. This is so that valgrind may better detect an out + * or range access. */ + return nm_str_realloc(g_string_free(gstr, FALSE)); +} + +/* set to 1 to exclude characters that are annoying to see in the debugger + * and printf() output. */ +#define ESCAPED_TOKENS_ONLY_NICE_CHARS 0 + +static char * +_escaped_tokens_create_random_whitespace(void) +{ + static const char *tokens[] = { + " ", +#if !ESCAPED_TOKENS_ONLY_NICE_CHARS + "\n", + "\t", + "\r", + "\f", +#endif + }; + + return _escaped_tokens_create_random_word_full(tokens, + G_N_ELEMENTS(tokens), + nmtst_get_rand_word_length(NULL) / 4u); +} + +static char * +_escaped_tokens_create_random_word(void) +{ + static const char *tokens[] = { + "a", + "b", + "c", + " ", + ",", + "=", + "\\", +#if !ESCAPED_TOKENS_ONLY_NICE_CHARS + "\n", + "\f", + ":", + "", +#endif + }; + + return _escaped_tokens_create_random_word_full(tokens, + G_N_ELEMENTS(tokens), + nmtst_get_rand_word_length(NULL)); +} + +static void +_escaped_tokens_str_append_delimiter(GString *str, gboolean strict, gboolean needs_delimiter) +{ + guint len = nmtst_get_rand_word_length(NULL) / 10u; + char *s; + +again: + if (!strict) { + g_string_append(str, (s = _escaped_tokens_create_random_whitespace())); + nm_clear_g_free(&s); + } + + if (needs_delimiter) + g_string_append_c(str, ','); + + if (!strict) { + g_string_append(str, (s = _escaped_tokens_create_random_whitespace())); + nm_clear_g_free(&s); + if (len-- > 0) { + needs_delimiter = TRUE; + goto again; + } + } +} + +static void +_escaped_tokens_split(char *str, const char **out_key, const char **out_val) +{ + const char *key; + const char *val; + gsize len = strlen(str); + + g_assert(str); + + nm_utils_escaped_tokens_options_split(str, &key, &val); + g_assert(key); + g_assert(key == str); + if (val) { + g_assert(val > str); + g_assert(val > key); + g_assert(val <= &str[len]); + } + NM_SET_OUT(out_key, key); + NM_SET_OUT(out_val, val); +} + +static void +_escaped_tokens_combine(GString * combined, + const char *key, + const char *val, + gboolean strict, + gboolean allow_append_delimiter_before, + gboolean needs_delimiter_after) +{ + gs_free char *escaped_key = NULL; + gs_free char *escaped_val = NULL; + + if (allow_append_delimiter_before) + _escaped_tokens_str_append_delimiter(combined, strict, FALSE); + g_string_append(combined, nm_utils_escaped_tokens_options_escape_key(key, &escaped_key)); + if (val) { + char *s; + + if (!strict) { + g_string_append(combined, (s = _escaped_tokens_create_random_whitespace())); + nm_clear_g_free(&s); + } + g_string_append_c(combined, '='); + if (!strict) { + g_string_append(combined, (s = _escaped_tokens_create_random_whitespace())); + nm_clear_g_free(&s); + } + g_string_append(combined, nm_utils_escaped_tokens_options_escape_val(val, &escaped_val)); + } + _escaped_tokens_str_append_delimiter(combined, strict, needs_delimiter_after); +} + +static void +_escaped_tokens_check_one_impl(const char * expected_key, + const char * expected_val, + const char * expected_combination, + const char *const *other, + gsize n_other) +{ + nm_auto_free_gstring GString *combined = g_string_new(NULL); + gsize i; + + g_assert(expected_key); + g_assert(expected_combination); + g_assert(other); + + _escaped_tokens_combine(combined, expected_key, expected_val, TRUE, TRUE, FALSE); + + g_assert_cmpstr(combined->str, ==, expected_combination); + + for (i = 0; i < n_other + 2u; i++) { + nm_auto_free_gstring GString *str0 = NULL; + gs_free const char ** strv_split = NULL; + gs_free char * strv_split0 = NULL; + const char * comb; + const char * key; + const char * val; + + if (i == 0) + comb = expected_combination; + else if (i == 1) { + _escaped_tokens_combine(nm_gstring_prepare(&str0), + expected_key, + expected_val, + FALSE, + TRUE, + FALSE); + comb = str0->str; + } else + comb = other[i - 2]; + + strv_split = nm_utils_escaped_tokens_options_split_list(comb); + if (!strv_split) { + g_assert_cmpstr(expected_key, ==, ""); + g_assert_cmpstr(expected_val, ==, NULL); + continue; + } + g_assert(expected_val || expected_key[0]); + + g_assert_cmpuint(NM_PTRARRAY_LEN(strv_split), ==, 1u); + + strv_split0 = g_strdup(strv_split[0]); + + _escaped_tokens_split(strv_split0, &key, &val); + g_assert_cmpstr(key, ==, expected_key); + g_assert_cmpstr(val, ==, expected_val); + } +} + +#define _escaped_tokens_check_one(expected_key, expected_val, expected_combination, ...) \ + _escaped_tokens_check_one_impl(expected_key, \ + expected_val, \ + expected_combination, \ + NM_MAKE_STRV(__VA_ARGS__), \ + NM_NARG(__VA_ARGS__)) + +static void +test_nm_utils_escaped_tokens(void) +{ + int i_run; + + for (i_run = 0; i_run < 1000; i_run++) { + const guint num_options = nmtst_get_rand_word_length(NULL); + gs_unref_ptrarray GPtrArray *options = g_ptr_array_new_with_free_func(g_free); + nm_auto_free_gstring GString *combined = g_string_new(NULL); + gs_free const char ** strv_split = NULL; + guint i_option; + guint i; + + /* Generate a list of random words for option key-value pairs. */ + for (i_option = 0; i_option < 2u * num_options; i_option++) { + char *word = NULL; + + if (i_option % 2u == 1 && nmtst_get_rand_uint32() % 5 == 0 + && strlen(options->pdata[options->len - 1]) > 0u) { + /* For some options, leave the value unset and only generate a key. + * + * If key is "", then we cannot do that, because the test below would try + * to append "" to the combined list, which the parser then would drop. + * Only test omitting the value, if strlen() of the key is positive. */ + } else + word = _escaped_tokens_create_random_word(); + g_ptr_array_add(options, word); + } + + /* Combine the options in one comma separated list, with proper escaping. */ + for (i_option = 0; i_option < num_options; i_option++) { + _escaped_tokens_combine(combined, + options->pdata[2u * i_option + 0u], + options->pdata[2u * i_option + 1u], + FALSE, + i_option == 0, + i_option != num_options - 1); + } + + /* ensure that we can split and parse the options without difference. */ + strv_split = nm_utils_escaped_tokens_options_split_list(combined->str); + for (i_option = 0; i_option < num_options; i_option++) { + const char * expected_key = options->pdata[2u * i_option + 0u]; + const char * expected_val = options->pdata[2u * i_option + 1u]; + gs_free char *s_split = + i_option < NM_PTRARRAY_LEN(strv_split) ? g_strdup(strv_split[i_option]) : NULL; + const char *key = NULL; + const char *val = NULL; + + if (s_split) + _escaped_tokens_split(s_split, &key, &val); + + if (!nm_streq0(key, expected_key) || !nm_streq0(val, expected_val)) { + g_print(">>> ASSERTION IS ABOUT TO FAIL for item %5d of %5d\n", + i_option, + num_options); + g_print(">>> combined = \"%s\"\n", combined->str); + g_print(">>> %c parsed[%5d].key = \"%s\"\n", + nm_streq(key, expected_key) ? ' ' : 'X', + i_option, + key); + g_print(">>> %c parsed[%5d].val = %s%s%s\n", + nm_streq0(val, expected_val) ? ' ' : 'X', + i_option, + NM_PRINT_FMT_QUOTE_STRING(val)); + for (i = 0; i < num_options; i++) { + g_print(">>> %c original[%5d].key = \"%s\"\n", + i == i_option ? '*' : ' ', + i, + (char *) options->pdata[2u * i + 0u]); + g_print(">>> %c original[%5d].val = %s%s%s\n", + i == i_option ? '*' : ' ', + i, + NM_PRINT_FMT_QUOTE_STRING((char *) options->pdata[2u * i + 1u])); + } + for (i = 0; i < NM_PTRARRAY_LEN(strv_split); i++) + g_print(">>> split[%5d] = \"%s\"\n", i, strv_split[i]); + } + + g_assert_cmpstr(key, ==, expected_key); + g_assert_cmpstr(val, ==, expected_val); + } + g_assert_cmpint(NM_PTRARRAY_LEN(strv_split), ==, num_options); + + /* Above we show a full round-trip of random option key-value pairs, that they can + * without loss escape, concatenate, split-list, and split. This proofed that every + * option key-value pair can be represented as a combined string and parsed back. + * + * Now, just check that we can also parse arbitrary random words in nm_utils_escaped_tokens_options_split(). + * split() is a non-injective surjective function. As we check the round-trip above for random words, where + * options-split() is the last step, we show that every random word can be the output of the function + * (which shows, the surjective part). + * + * But multiple random input arguments, may map to the same output argument (non-injective). + * Just test whether we can handle random input words without crashing. For that, just use the + * above generate list of random words. + */ + for (i = 0; i < 1u + 2u * i_option; i++) { + gs_free char *str = NULL; + const char * cstr; + + if (i == 0) + cstr = combined->str; + else + cstr = options->pdata[i - 1u]; + if (!cstr) + continue; + + str = g_strdup(cstr); + _escaped_tokens_split(str, NULL, NULL); + } + } + + _escaped_tokens_check_one("", NULL, ""); + _escaped_tokens_check_one("", "", "=", " ="); + _escaped_tokens_check_one("a", "b", "a=b", "a = b"); + _escaped_tokens_check_one("a\\=", "b\\=", "a\\\\\\==b\\\\=", "a\\\\\\==b\\\\\\="); + _escaped_tokens_check_one("\\=", "\\=", "\\\\\\==\\\\=", "\\\\\\==\\\\\\="); + _escaped_tokens_check_one(" ", "bb=", "\\ =bb=", "\\ =bb\\="); + _escaped_tokens_check_one(" ", "bb\\=", "\\ =bb\\\\=", "\\ =bb\\\\\\="); + _escaped_tokens_check_one("a b", "a b", "a b=a b"); + _escaped_tokens_check_one("a b", "a b", "a b=a b"); + _escaped_tokens_check_one("a = b", "a = b", "a \\= b=a = b", "a \\= b=a \\= b"); +} + +/*****************************************************************************/ + +typedef struct { + int val; + CList lst; +} CListSort; + +static int +_c_list_sort_cmp(const CList *lst_a, const CList *lst_b, const void *user_data) +{ + const CListSort *a, *b; + + g_assert(lst_a); + g_assert(lst_b); + g_assert(lst_a != lst_b); + + a = c_list_entry(lst_a, CListSort, lst); + b = c_list_entry(lst_b, CListSort, lst); + + if (a->val < b->val) + return -1; + if (a->val > b->val) + return 1; + return 0; +} + +static void +_do_test_c_list_sort(CListSort *elements, guint n_list, gboolean headless) +{ + CList head, *iter, *iter_prev, *lst; + guint i; + const CListSort *el_prev; + CListSort * el; + + c_list_init(&head); + for (i = 0; i < n_list; i++) { + el = &elements[i]; + el->val = nmtst_get_rand_uint32() % (2 * n_list); + c_list_link_tail(&head, &el->lst); + } + + if (headless) { + lst = head.next; + c_list_unlink_stale(&head); + lst = c_list_sort_headless(lst, _c_list_sort_cmp, NULL); + g_assert(lst); + g_assert(lst->next); + g_assert(lst->prev); + g_assert(c_list_length(lst) == n_list - 1); + iter_prev = lst->prev; + for (iter = lst; iter != lst; iter = iter->next) { + g_assert(iter); + g_assert(iter->next); + g_assert(iter->prev == iter_prev); + } + c_list_link_before(lst, &head); + } else + c_list_sort(&head, _c_list_sort_cmp, NULL); + + g_assert(!c_list_is_empty(&head)); + g_assert(c_list_length(&head) == n_list); + + el_prev = NULL; + c_list_for_each (iter, &head) { + el = c_list_entry(iter, CListSort, lst); + g_assert(el >= elements && el < &elements[n_list]); + if (el_prev) { + if (el_prev->val == el->val) + g_assert(el_prev < el); + else + g_assert(el_prev->val < el->val); + g_assert(iter->prev == &el_prev->lst); + g_assert(el_prev->lst.next == iter); + } + el_prev = el; + } + g_assert(head.prev == &el_prev->lst); +} + +static void +test_c_list_sort(void) +{ + const guint N_ELEMENTS = 10000; + guint n_list, repeat; + gs_free CListSort *elements = NULL; + + { + CList head; + + c_list_init(&head); + c_list_sort(&head, _c_list_sort_cmp, NULL); + g_assert(c_list_length(&head) == 0); + g_assert(c_list_is_empty(&head)); + } + + elements = g_new0(CListSort, N_ELEMENTS); + for (n_list = 1; n_list < N_ELEMENTS; n_list++) { + if (n_list > 150) { + n_list += nmtst_get_rand_uint32() % n_list; + if (n_list >= N_ELEMENTS) + break; + } + { + const guint N_REPEAT = n_list > 50 ? 1 : 5; + + for (repeat = 0; repeat < N_REPEAT; repeat++) + _do_test_c_list_sort(elements, n_list, nmtst_get_rand_uint32() % 2); + } + } +} + +/*****************************************************************************/ + +typedef struct { + NMDedupMultiObj parent; + guint val; + guint other; +} DedupObj; + +static const NMDedupMultiObjClass dedup_obj_class; + +static DedupObj * +_dedup_obj_assert(const NMDedupMultiObj *obj) +{ + DedupObj *o; + + g_assert(obj); + o = (DedupObj *) obj; + g_assert(o->parent.klass == &dedup_obj_class); + g_assert(o->parent._ref_count > 0); + g_assert(o->val > 0); + return o; +} + +static const NMDedupMultiObj * +_dedup_obj_clone(const NMDedupMultiObj *obj) +{ + DedupObj *o, *o2; + + o = _dedup_obj_assert(obj); + o2 = g_slice_new0(DedupObj); + o2->parent.klass = &dedup_obj_class; + o2->parent._ref_count = 1; + o2->val = o->val; + o2->other = o->other; + return (NMDedupMultiObj *) o2; +} + +static void +_dedup_obj_destroy(NMDedupMultiObj *obj) +{ + DedupObj *o = (DedupObj *) obj; + + g_assert(o->parent._ref_count == 0); + o->parent._ref_count = 1; + o = _dedup_obj_assert(obj); + g_slice_free(DedupObj, o); +} + +static void +_dedup_obj_full_hash_update(const NMDedupMultiObj *obj, NMHashState *h) +{ + const DedupObj *o; + + o = _dedup_obj_assert(obj); + nm_hash_update_vals(h, o->val, o->other); +} + +static gboolean +_dedup_obj_full_equal(const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b) +{ + const DedupObj *o_a = _dedup_obj_assert(obj_a); + const DedupObj *o_b = _dedup_obj_assert(obj_b); + + return o_a->val == o_b->val && o_a->other == o_b->other; +} + +static const NMDedupMultiObjClass dedup_obj_class = { + .obj_clone = _dedup_obj_clone, + .obj_destroy = _dedup_obj_destroy, + .obj_full_hash_update = _dedup_obj_full_hash_update, + .obj_full_equal = _dedup_obj_full_equal, +}; + +#define DEDUP_OBJ_INIT(val_val, other_other) \ + (&((DedupObj){ \ + .parent = \ + { \ + .klass = &dedup_obj_class, \ + ._ref_count = NM_OBJ_REF_COUNT_STACKINIT, \ + }, \ + .val = (val_val), \ + .other = (other_other), \ + })) + +typedef struct { + NMDedupMultiIdxType parent; + guint partition_size; + guint val_mod; +} DedupIdxType; + +static const NMDedupMultiIdxTypeClass dedup_idx_type_class; + +static const DedupIdxType * +_dedup_idx_assert(const NMDedupMultiIdxType *idx_type) +{ + DedupIdxType *t; + + g_assert(idx_type); + t = (DedupIdxType *) idx_type; + g_assert(t->parent.klass == &dedup_idx_type_class); + g_assert(t->partition_size > 0); + g_assert(t->val_mod > 0); + return t; +} + +static void +_dedup_idx_obj_id_hash_update(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj, + NMHashState * h) +{ + const DedupIdxType *t; + const DedupObj * o; + + t = _dedup_idx_assert(idx_type); + o = _dedup_obj_assert(obj); + + nm_hash_update_val(h, o->val / t->partition_size); + nm_hash_update_val(h, o->val % t->val_mod); +} + +static gboolean +_dedup_idx_obj_id_equal(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj_a, + const NMDedupMultiObj * obj_b) +{ + const DedupIdxType *t; + const DedupObj * o_a; + const DedupObj * o_b; + + t = _dedup_idx_assert(idx_type); + o_a = _dedup_obj_assert(obj_a); + o_b = _dedup_obj_assert(obj_b); + + return (o_a->val / t->partition_size) == (o_b->val / t->partition_size) + && (o_a->val % t->val_mod) == (o_b->val % t->val_mod); +} + +static void +_dedup_idx_obj_partition_hash_update(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj, + NMHashState * h) +{ + const DedupIdxType *t; + const DedupObj * o; + + t = _dedup_idx_assert(idx_type); + o = _dedup_obj_assert(obj); + + nm_hash_update_val(h, o->val / t->partition_size); +} + +static gboolean +_dedup_idx_obj_partition_equal(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj_a, + const NMDedupMultiObj * obj_b) +{ + const DedupIdxType *t; + const DedupObj * o_a; + const DedupObj * o_b; + + t = _dedup_idx_assert(idx_type); + o_a = _dedup_obj_assert(obj_a); + o_b = _dedup_obj_assert(obj_b); + + return (o_a->val / t->partition_size) == (o_b->val / t->partition_size); +} + +static const NMDedupMultiIdxTypeClass dedup_idx_type_class = { + .idx_obj_id_hash_update = _dedup_idx_obj_id_hash_update, + .idx_obj_id_equal = _dedup_idx_obj_id_equal, + .idx_obj_partition_hash_update = _dedup_idx_obj_partition_hash_update, + .idx_obj_partition_equal = _dedup_idx_obj_partition_equal, +}; + +static const DedupIdxType * +DEDUP_IDX_TYPE_INIT(DedupIdxType *idx_type, guint partition_size, guint val_mod) +{ + nm_dedup_multi_idx_type_init((NMDedupMultiIdxType *) idx_type, &dedup_idx_type_class); + idx_type->val_mod = val_mod; + idx_type->partition_size = partition_size; + return idx_type; +} + +static gboolean +_dedup_idx_add(NMDedupMultiIndex * idx, + const DedupIdxType * idx_type, + const DedupObj * obj, + NMDedupMultiIdxMode mode, + const NMDedupMultiEntry **out_entry) +{ + g_assert(idx); + _dedup_idx_assert((NMDedupMultiIdxType *) idx_type); + if (obj) + _dedup_obj_assert((NMDedupMultiObj *) obj); + return nm_dedup_multi_index_add(idx, + (NMDedupMultiIdxType *) idx_type, + obj, + mode, + out_entry, + NULL); +} + +static void +_dedup_head_entry_assert(const NMDedupMultiHeadEntry *entry) +{ + g_assert(entry); + g_assert(entry->len > 0); + g_assert(entry->len == c_list_length(&entry->lst_entries_head)); + g_assert(entry->idx_type); + g_assert(entry->is_head); +} + +static const DedupObj * +_dedup_entry_assert(const NMDedupMultiEntry *entry) +{ + g_assert(entry); + g_assert(!c_list_is_empty(&entry->lst_entries)); + g_assert(entry->head); + g_assert(!entry->is_head); + g_assert(entry->head != (gpointer) entry); + _dedup_head_entry_assert(entry->head); + return _dedup_obj_assert(entry->obj); +} + +static const DedupIdxType * +_dedup_entry_get_idx_type(const NMDedupMultiEntry *entry) +{ + _dedup_entry_assert(entry); + + g_assert(entry->head); + g_assert(entry->head->idx_type); + return _dedup_idx_assert(entry->head->idx_type); +} + +static void +_dedup_entry_assert_all(const NMDedupMultiEntry *entry, + gssize expected_idx, + const DedupObj *const * expected_obj) +{ + gsize n, i; + CList *iter; + + g_assert(entry); + _dedup_entry_assert(entry); + + g_assert(expected_obj); + n = NM_PTRARRAY_LEN(expected_obj); + + g_assert(n == c_list_length(&entry->lst_entries)); + + g_assert(expected_idx >= -1 && expected_idx < n); + g_assert(entry->head); + if (expected_idx == -1) + g_assert(entry->head == (gpointer) entry); + else + g_assert(entry->head != (gpointer) entry); + + i = 0; + c_list_for_each (iter, &entry->head->lst_entries_head) { + const NMDedupMultiEntry *entry_current = c_list_entry(iter, NMDedupMultiEntry, lst_entries); + const DedupObj * obj_current; + const DedupIdxType * idx_type = _dedup_entry_get_idx_type(entry_current); + + obj_current = _dedup_entry_assert(entry_current); + g_assert(obj_current); + g_assert(i < n); + if (expected_idx == i) + g_assert(entry_current == entry); + g_assert(idx_type->parent.klass->idx_obj_partition_equal( + &idx_type->parent, + entry_current->obj, + c_list_entry(entry->head->lst_entries_head.next, NMDedupMultiEntry, lst_entries)->obj)); + i++; + } +} +#define _dedup_entry_assert_all(entry, expected_idx, ...) \ + _dedup_entry_assert_all(entry, expected_idx, (const DedupObj *const[]){__VA_ARGS__, NULL}) + +static void +test_dedup_multi(void) +{ + NMDedupMultiIndex * idx; + DedupIdxType IDX_20_3_a_stack; + const DedupIdxType *const IDX_20_3_a = DEDUP_IDX_TYPE_INIT(&IDX_20_3_a_stack, 20, 3); + const NMDedupMultiEntry * entry1; + + idx = nm_dedup_multi_index_new(); + + g_assert(_dedup_idx_add(idx, + IDX_20_3_a, + DEDUP_OBJ_INIT(1, 1), + NM_DEDUP_MULTI_IDX_MODE_APPEND, + &entry1)); + _dedup_entry_assert_all(entry1, 0, DEDUP_OBJ_INIT(1, 1)); + + g_assert(nm_dedup_multi_index_obj_find(idx, (NMDedupMultiObj *) DEDUP_OBJ_INIT(1, 1))); + g_assert(!nm_dedup_multi_index_obj_find(idx, (NMDedupMultiObj *) DEDUP_OBJ_INIT(1, 2))); + + g_assert(_dedup_idx_add(idx, + IDX_20_3_a, + DEDUP_OBJ_INIT(1, 2), + NM_DEDUP_MULTI_IDX_MODE_APPEND, + &entry1)); + _dedup_entry_assert_all(entry1, 0, DEDUP_OBJ_INIT(1, 2)); + + g_assert(!nm_dedup_multi_index_obj_find(idx, (NMDedupMultiObj *) DEDUP_OBJ_INIT(1, 1))); + g_assert(nm_dedup_multi_index_obj_find(idx, (NMDedupMultiObj *) DEDUP_OBJ_INIT(1, 2))); + + g_assert(_dedup_idx_add(idx, + IDX_20_3_a, + DEDUP_OBJ_INIT(2, 2), + NM_DEDUP_MULTI_IDX_MODE_APPEND, + &entry1)); + _dedup_entry_assert_all(entry1, 1, DEDUP_OBJ_INIT(1, 2), DEDUP_OBJ_INIT(2, 2)); + + nm_dedup_multi_index_unref(idx); +} + +/*****************************************************************************/ + +static NMConnection * +_connection_new_from_dbus(GVariant *dict, GError **error) +{ + return _nm_simple_connection_new_from_dbus(dict, NM_SETTING_PARSE_FLAGS_NORMALIZE, error); +} + +static void +vpn_check_func(const char *key, const char *value, gpointer user_data) +{ + if (!strcmp(key, "foobar1")) { + g_assert_cmpstr(value, ==, "blahblah1"); + return; + } + + if (!strcmp(key, "foobar2")) { + g_assert_cmpstr(value, ==, "blahblah2"); + return; + } + + if (!strcmp(key, "foobar3")) { + g_assert_cmpstr(value, ==, "blahblah3"); + return; + } + + if (!strcmp(key, "foobar4")) { + g_assert_cmpstr(value, ==, "blahblah4"); + return; + } + + g_assert_not_reached(); +} + +static void +vpn_check_empty_func(const char *key, const char *value, gpointer user_data) +{ + g_assert_not_reached(); +} + +static void +test_setting_vpn_items(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingVpn * s_vpn; + + connection = + nmtst_create_minimal_connection("vpn-items", NULL, NM_SETTING_VPN_SETTING_NAME, NULL); + + s_vpn = nm_connection_get_setting_vpn(connection); + + nm_setting_vpn_add_data_item(s_vpn, "foobar1", "blahblah1"); + nm_setting_vpn_add_data_item(s_vpn, "foobar2", "blahblah2"); + nm_setting_vpn_add_data_item(s_vpn, "foobar3", "blahblah3"); + nm_setting_vpn_add_data_item(s_vpn, "foobar4", "blahblah4"); + + /* Ensure that added values are all present */ + nm_setting_vpn_foreach_data_item(s_vpn, vpn_check_func, NULL); + nm_setting_vpn_remove_data_item(s_vpn, "foobar1"); + nm_setting_vpn_remove_data_item(s_vpn, "foobar2"); + nm_setting_vpn_remove_data_item(s_vpn, "foobar3"); + nm_setting_vpn_remove_data_item(s_vpn, "foobar4"); + + g_assert(!_nm_connection_aggregate(connection, NM_CONNECTION_AGGREGATE_ANY_SECRETS, NULL)); + g_assert(!_nm_connection_aggregate(connection, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, + NULL)); + + nm_setting_vpn_add_secret(s_vpn, "foobar1", "blahblah1"); + + g_assert(_nm_connection_aggregate(connection, NM_CONNECTION_AGGREGATE_ANY_SECRETS, NULL)); + g_assert(_nm_connection_aggregate(connection, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, + NULL)); + + nm_setting_vpn_add_secret(s_vpn, "foobar2", "blahblah2"); + nm_setting_vpn_add_secret(s_vpn, "foobar3", "blahblah3"); + nm_setting_vpn_add_secret(s_vpn, "foobar4", "blahblah4"); + + /* Ensure that added values are all present */ + nm_setting_vpn_foreach_secret(s_vpn, vpn_check_func, NULL); + nm_setting_vpn_remove_secret(s_vpn, "foobar1"); + nm_setting_vpn_remove_secret(s_vpn, "foobar2"); + nm_setting_vpn_remove_secret(s_vpn, "foobar3"); + + g_assert(_nm_connection_aggregate(connection, NM_CONNECTION_AGGREGATE_ANY_SECRETS, NULL)); + g_assert(_nm_connection_aggregate(connection, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, + NULL)); + + nm_setting_vpn_add_data_item(s_vpn, "foobar4-flags", "blahblah4"); + + g_assert(_nm_connection_aggregate(connection, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, + NULL)); + + nm_setting_vpn_add_data_item(s_vpn, "foobar4-flags", "2"); + + g_assert(!_nm_connection_aggregate(connection, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, + NULL)); + + nm_setting_vpn_remove_secret(s_vpn, "foobar4"); + + g_assert(!_nm_connection_aggregate(connection, NM_CONNECTION_AGGREGATE_ANY_SECRETS, NULL)); + g_assert(!_nm_connection_aggregate(connection, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, + NULL)); + + nm_setting_vpn_remove_data_item(s_vpn, "foobar4-flags"); + + /* Try to add some blank values and make sure they are rejected */ + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(key && key[0])); + nm_setting_vpn_add_data_item(s_vpn, NULL, NULL); + g_test_assert_expected_messages(); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(key && key[0])); + nm_setting_vpn_add_data_item(s_vpn, "", ""); + g_test_assert_expected_messages(); + + nm_setting_vpn_add_data_item(s_vpn, "foobar1", ""); + g_assert_cmpstr(nm_setting_vpn_get_data_item(s_vpn, "foobar1"), ==, ""); + + nm_setting_vpn_add_data_item(s_vpn, "foobar1", NULL); + g_assert_cmpstr(nm_setting_vpn_get_data_item(s_vpn, "foobar1"), ==, NULL); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(key && key[0])); + nm_setting_vpn_add_data_item(s_vpn, NULL, "blahblah1"); + g_test_assert_expected_messages(); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(key && key[0])); + nm_setting_vpn_add_data_item(s_vpn, "", "blahblah1"); + g_test_assert_expected_messages(); + + nm_setting_vpn_foreach_data_item(s_vpn, vpn_check_empty_func, NULL); + + /* Try to add some blank secrets and make sure they are rejected */ + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(key && key[0])); + nm_setting_vpn_add_secret(s_vpn, NULL, NULL); + g_test_assert_expected_messages(); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(key && key[0])); + nm_setting_vpn_add_secret(s_vpn, "", ""); + g_test_assert_expected_messages(); + + nm_setting_vpn_add_secret(s_vpn, "foobar1", ""); + + nm_setting_vpn_add_secret(s_vpn, "foobar1", NULL); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(key && key[0])); + nm_setting_vpn_add_secret(s_vpn, NULL, "blahblah1"); + g_test_assert_expected_messages(); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(key && key[0])); + nm_setting_vpn_add_secret(s_vpn, "", "blahblah1"); + g_test_assert_expected_messages(); + + nm_setting_vpn_foreach_secret(s_vpn, vpn_check_empty_func, NULL); +} + +static void +test_setting_vpn_update_secrets(void) +{ + NMConnection * connection; + NMSettingVpn * s_vpn; + GVariantBuilder settings_builder, vpn_builder, secrets_builder; + GVariant * settings; + gboolean success; + GError * error = NULL; + const char * tmp; + const char * key1 = "foobar"; + const char * key2 = "blahblah"; + const char * val1 = "value1"; + const char * val2 = "value2"; + + connection = nm_simple_connection_new(); + s_vpn = (NMSettingVpn *) nm_setting_vpn_new(); + nm_connection_add_setting(connection, NM_SETTING(s_vpn)); + + g_variant_builder_init(&settings_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_init(&vpn_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_init(&secrets_builder, G_VARIANT_TYPE("a{ss}")); + + g_variant_builder_add(&secrets_builder, "{ss}", key1, val1); + g_variant_builder_add(&secrets_builder, "{ss}", key2, val2); + + g_variant_builder_add(&vpn_builder, + "{sv}", + NM_SETTING_VPN_SECRETS, + g_variant_builder_end(&secrets_builder)); + g_variant_builder_add(&settings_builder, "{sa{sv}}", NM_SETTING_VPN_SETTING_NAME, &vpn_builder); + settings = g_variant_builder_end(&settings_builder); + + success = + nm_connection_update_secrets(connection, NM_SETTING_VPN_SETTING_NAME, settings, &error); + g_assert_no_error(error); + g_assert(success); + + /* Read the secrets back out */ + tmp = nm_setting_vpn_get_secret(s_vpn, key1); + g_assert(tmp); + g_assert_cmpstr(tmp, ==, val1); + + tmp = nm_setting_vpn_get_secret(s_vpn, key2); + g_assert(tmp); + g_assert_cmpstr(tmp, ==, val2); + + g_variant_unref(settings); + g_object_unref(connection); +} + +#define TO_DEL_NUM 50 +typedef struct { + NMSettingVpn *s_vpn; + char * to_del[TO_DEL_NUM]; + guint called; +} IterInfo; + +static void +del_iter_func(const char *key, const char *value, gpointer user_data) +{ + IterInfo *info = user_data; + int i; + + /* Record how many times this function gets called; it should get called + * exactly as many times as there are keys in the hash table, regardless + * of what keys we delete from the table. + */ + info->called++; + + /* During the iteration, remove a bunch of stuff from the table */ + if (info->called == 1) { + for (i = 0; i < TO_DEL_NUM; i++) + nm_setting_vpn_remove_data_item(info->s_vpn, info->to_del[i]); + } +} + +static void +test_setting_vpn_modify_during_foreach(void) +{ + NMSettingVpn *s_vpn; + IterInfo info; + char * key, *val; + int i, u = 0; + + s_vpn = (NMSettingVpn *) nm_setting_vpn_new(); + g_assert(s_vpn); + + for (i = 0; i < TO_DEL_NUM * 2; i++) { + key = g_strdup_printf("adsfasdfadf%d", i); + val = g_strdup_printf("42263236236awt%d", i); + nm_setting_vpn_add_data_item(s_vpn, key, val); + + /* Cache some keys to delete */ + if (i % 2) + info.to_del[u++] = g_strdup(key); + + g_free(key); + g_free(val); + } + + /* Iterate over current table keys */ + info.s_vpn = s_vpn; + info.called = 0; + nm_setting_vpn_foreach_data_item(s_vpn, del_iter_func, &info); + + /* Make sure all the things we removed during iteration are really gone */ + for (i = 0; i < TO_DEL_NUM; i++) { + g_assert_cmpstr(nm_setting_vpn_get_data_item(s_vpn, info.to_del[i]), ==, NULL); + g_free(info.to_del[i]); + } + + /* And make sure the foreach callback was called the same number of times + * as there were keys in the table at the beginning of the foreach. + */ + g_assert_cmpint(info.called, ==, TO_DEL_NUM * 2); + + g_object_unref(s_vpn); +} + +static void +test_setting_ip4_config_labels(void) +{ + NMSettingIPConfig *s_ip4; + NMIPAddress * addr; + GVariant * label; + GPtrArray * addrs; + char ** labels; + NMConnection * conn; + GVariant * dict, *dict2, *setting_dict, *value; + GError * error = NULL; + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(G_OBJECT(s_ip4), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + /* addr 1 */ + addr = nm_ip_address_new(AF_INET, "1.2.3.4", 24, &error); + g_assert_no_error(error); + + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + nmtst_assert_setting_verifies(NM_SETTING(s_ip4)); + + addr = nm_setting_ip_config_get_address(s_ip4, 0); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label == NULL); + + /* The 'address-labels' property should be omitted from the serialization if + * there are no non-NULL labels. + */ + conn = nmtst_create_minimal_connection("label test", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_connection_add_setting(conn, nm_setting_duplicate(NM_SETTING(s_ip4))); + dict = nm_connection_to_dbus(conn, NM_CONNECTION_SERIALIZE_ALL); + g_object_unref(conn); + + setting_dict = + g_variant_lookup_value(dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert(setting_dict != NULL); + + value = g_variant_lookup_value(setting_dict, "address-labels", NULL); + g_assert(value == NULL); + + g_variant_unref(setting_dict); + g_variant_unref(dict); + + /* Now back to constructing the original s_ip4... */ + + /* addr 2 */ + addr = nm_ip_address_new(AF_INET, "2.3.4.5", 24, &error); + g_assert_no_error(error); + nm_ip_address_set_attribute(addr, + NM_IP_ADDRESS_ATTRIBUTE_LABEL, + g_variant_new_string("eth0:1")); + + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + nmtst_assert_setting_verifies(NM_SETTING(s_ip4)); + + addr = nm_setting_ip_config_get_address(s_ip4, 1); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label != NULL); + g_assert_cmpstr(g_variant_get_string(label, NULL), ==, "eth0:1"); + + /* addr 3 */ + addr = nm_ip_address_new(AF_INET, "3.4.5.6", 24, &error); + g_assert_no_error(error); + nm_ip_address_set_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL, NULL); + + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + nmtst_assert_setting_verifies(NM_SETTING(s_ip4)); + + addr = nm_setting_ip_config_get_address(s_ip4, 2); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label == NULL); + + /* Remove addr 1 and re-verify remaining addresses */ + nm_setting_ip_config_remove_address(s_ip4, 0); + nmtst_assert_setting_verifies(NM_SETTING(s_ip4)); + + addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label != NULL); + g_assert_cmpstr(g_variant_get_string(label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address(s_ip4, 1); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label == NULL); + + /* If we serialize as the daemon, the labels should appear in the D-Bus + * serialization under both 'address-labels' and 'address-data'. + */ + conn = nmtst_create_minimal_connection("label test", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + _nm_utils_is_manager_process = TRUE; + dict = nm_connection_to_dbus(conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + g_object_unref(conn); + + setting_dict = + g_variant_lookup_value(dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert(setting_dict != NULL); + + value = g_variant_lookup_value(setting_dict, "address-labels", G_VARIANT_TYPE_STRING_ARRAY); + g_assert(value != NULL); + g_variant_get(value, "^as", &labels); + g_assert_cmpint(g_strv_length(labels), ==, 2); + g_assert_cmpstr(labels[0], ==, "eth0:1"); + g_assert_cmpstr(labels[1], ==, ""); + g_variant_unref(value); + g_strfreev(labels); + + value = g_variant_lookup_value(setting_dict, "address-data", G_VARIANT_TYPE("aa{sv}")); + addrs = nm_utils_ip_addresses_from_variant(value, AF_INET); + g_variant_unref(value); + g_assert(addrs != NULL); + g_assert_cmpint(addrs->len, ==, 2); + addr = addrs->pdata[0]; + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label != NULL); + g_assert_cmpstr(g_variant_get_string(label, NULL), ==, "eth0:1"); + addr = addrs->pdata[1]; + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label == NULL); + g_ptr_array_unref(addrs); + + g_variant_unref(setting_dict); + + /* We should be able to deserialize the labels from either 'address-labels' + * or 'address-data'. + */ + dict2 = g_variant_ref(dict); + + NMTST_VARIANT_EDITOR( + dict, NMTST_VARIANT_DROP_PROPERTY(NM_SETTING_IP4_CONFIG_SETTING_NAME, "address-data");); + conn = _connection_new_from_dbus(dict, &error); + g_assert_no_error(error); + g_variant_unref(dict); + + s_ip4 = nm_connection_get_setting_ip4_config(conn); + + addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label != NULL); + g_assert_cmpstr(g_variant_get_string(label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address(s_ip4, 1); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label == NULL); + + g_object_unref(conn); + + NMTST_VARIANT_EDITOR( + dict2, NMTST_VARIANT_DROP_PROPERTY(NM_SETTING_IP4_CONFIG_SETTING_NAME, "address-labels");); + conn = _connection_new_from_dbus(dict2, &error); + g_assert_no_error(error); + g_variant_unref(dict2); + + s_ip4 = nm_connection_get_setting_ip4_config(conn); + + addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert_cmpstr(g_variant_get_string(label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address(s_ip4, 1); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label == NULL); + + /* Test explicit property assignment */ + g_object_get(G_OBJECT(s_ip4), NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL); + + nm_setting_ip_config_clear_addresses(s_ip4); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 0); + + g_object_set(G_OBJECT(s_ip4), NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL); + g_ptr_array_unref(addrs); + nmtst_assert_setting_verifies(NM_SETTING(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 2); + + addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label != NULL); + g_assert_cmpstr(g_variant_get_string(label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address(s_ip4, 1); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + g_assert(label == NULL); + + g_object_unref(conn); +} + +static void +test_setting_ip4_config_address_data(void) +{ + NMSettingIPConfig *s_ip4; + NMIPAddress * addr; + GPtrArray * addrs; + NMConnection * conn; + GVariant * dict, *setting_dict, *value; + GError * error = NULL; + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(G_OBJECT(s_ip4), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + /* addr 1 */ + addr = nm_ip_address_new(AF_INET, "1.2.3.4", 24, &error); + g_assert_no_error(error); + nm_ip_address_set_attribute(addr, "one", g_variant_new_string("foo")); + nm_ip_address_set_attribute(addr, "two", g_variant_new_int32(42)); + + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + nmtst_assert_setting_verifies(NM_SETTING(s_ip4)); + + /* addr 2 */ + addr = nm_ip_address_new(AF_INET, "2.3.4.5", 24, &error); + g_assert_no_error(error); + + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + nmtst_assert_setting_verifies(NM_SETTING(s_ip4)); + + /* The client-side D-Bus serialization should include the attributes in + * "address-data", and should not have an "addresses" property. + */ + conn = nmtst_create_minimal_connection("address-data test", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + dict = nm_connection_to_dbus(conn, NM_CONNECTION_SERIALIZE_ALL); + + setting_dict = + g_variant_lookup_value(dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert(setting_dict != NULL); + + value = g_variant_lookup_value(setting_dict, "addresses", NULL); + g_assert(value == NULL); + + value = g_variant_lookup_value(setting_dict, "address-data", G_VARIANT_TYPE("aa{sv}")); + addrs = nm_utils_ip_addresses_from_variant(value, AF_INET); + g_variant_unref(value); + g_assert(addrs != NULL); + g_assert_cmpint(addrs->len, ==, 2); + + addr = addrs->pdata[0]; + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "1.2.3.4"); + value = nm_ip_address_get_attribute(addr, "one"); + g_assert(value != NULL); + g_assert_cmpstr(g_variant_get_string(value, NULL), ==, "foo"); + value = nm_ip_address_get_attribute(addr, "two"); + g_assert(value != NULL); + g_assert_cmpint(g_variant_get_int32(value), ==, 42); + + g_ptr_array_unref(addrs); + g_variant_unref(setting_dict); + g_variant_unref(dict); + + /* The daemon-side serialization should include both 'addresses' and 'address-data' */ + _nm_utils_is_manager_process = TRUE; + dict = nm_connection_to_dbus(conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + + setting_dict = + g_variant_lookup_value(dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert(setting_dict != NULL); + + value = g_variant_lookup_value(setting_dict, "addresses", G_VARIANT_TYPE("aau")); + g_assert(value != NULL); + g_variant_unref(value); + + value = g_variant_lookup_value(setting_dict, "address-data", G_VARIANT_TYPE("aa{sv}")); + g_assert(value != NULL); + g_variant_unref(value); + + g_variant_unref(setting_dict); + g_object_unref(conn); + + /* When we reserialize that dictionary as a client, 'address-data' will be preferred. */ + conn = _connection_new_from_dbus(dict, &error); + g_assert_no_error(error); + + s_ip4 = nm_connection_get_setting_ip4_config(conn); + + addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "1.2.3.4"); + value = nm_ip_address_get_attribute(addr, "one"); + g_assert(value != NULL); + g_assert_cmpstr(g_variant_get_string(value, NULL), ==, "foo"); + value = nm_ip_address_get_attribute(addr, "two"); + g_assert(value != NULL); + g_assert_cmpint(g_variant_get_int32(value), ==, 42); + + /* But on the server side, 'addresses' will have precedence. */ + _nm_utils_is_manager_process = TRUE; + conn = _connection_new_from_dbus(dict, &error); + _nm_utils_is_manager_process = FALSE; + g_assert_no_error(error); + g_variant_unref(dict); + + s_ip4 = nm_connection_get_setting_ip4_config(conn); + + addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "1.2.3.4"); + value = nm_ip_address_get_attribute(addr, "one"); + g_assert(value == NULL); + value = nm_ip_address_get_attribute(addr, "two"); + g_assert(value == NULL); + + g_object_unref(conn); +} + +static void +test_setting_ip_route_attributes(void) +{ + GVariant *variant; + gboolean res, known; + +#define TEST_ATTR(name, type, value, family, exp_res, exp_known) \ + variant = g_variant_new_##type(value); \ + res = nm_ip_route_attribute_validate(name, variant, family, &known, NULL); \ + g_assert(res == exp_res); \ + g_assert(known == exp_known); \ + g_variant_unref(variant); + + TEST_ATTR("foo", uint32, 12, AF_INET, FALSE, FALSE); + + TEST_ATTR("tos", byte, 127, AF_INET, TRUE, TRUE); + TEST_ATTR("tos", string, "0x28", AF_INET, FALSE, TRUE); + + TEST_ATTR("cwnd", uint32, 10, AF_INET, TRUE, TRUE); + TEST_ATTR("cwnd", string, "11", AF_INET, FALSE, TRUE); + + TEST_ATTR("lock-mtu", boolean, TRUE, AF_INET, TRUE, TRUE); + TEST_ATTR("lock-mtu", uint32, 1, AF_INET, FALSE, TRUE); + + TEST_ATTR("from", string, "fd01::1", AF_INET6, TRUE, TRUE); + TEST_ATTR("from", string, "fd01::1/64", AF_INET6, TRUE, TRUE); + TEST_ATTR("from", string, "fd01::1/128", AF_INET6, TRUE, TRUE); + TEST_ATTR("from", string, "fd01::1/129", AF_INET6, FALSE, TRUE); + TEST_ATTR("from", string, "fd01::1/a", AF_INET6, FALSE, TRUE); + TEST_ATTR("from", string, "abc/64", AF_INET6, FALSE, TRUE); + TEST_ATTR("from", string, "1.2.3.4", AF_INET, FALSE, TRUE); + TEST_ATTR("from", string, "1.2.3.4", AF_INET6, FALSE, TRUE); + + TEST_ATTR("src", string, "1.2.3.4", AF_INET, TRUE, TRUE); + TEST_ATTR("src", string, "1.2.3.4", AF_INET6, FALSE, TRUE); + TEST_ATTR("src", string, "1.2.3.0/24", AF_INET, FALSE, TRUE); + TEST_ATTR("src", string, "fd01::12", AF_INET6, TRUE, TRUE); + + TEST_ATTR("type", string, "local", AF_INET, TRUE, TRUE); + TEST_ATTR("type", string, "local", AF_INET6, TRUE, TRUE); + TEST_ATTR("type", string, "unicast", AF_INET, TRUE, TRUE); + TEST_ATTR("type", string, "unicast", AF_INET6, TRUE, TRUE); + +#undef TEST_ATTR +} + +static void +test_setting_gsm_apn_spaces(void) +{ + gs_unref_object NMSettingGsm *s_gsm = NULL; + const char * tmp; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new(); + g_assert(s_gsm); + + /* Trailing space */ + g_object_set(s_gsm, NM_SETTING_GSM_APN, "foobar ", NULL); + tmp = nm_setting_gsm_get_apn(s_gsm); + g_assert_cmpstr(tmp, ==, "foobar"); + + /* Leading space */ + g_object_set(s_gsm, NM_SETTING_GSM_APN, " foobar", NULL); + tmp = nm_setting_gsm_get_apn(s_gsm); + g_assert_cmpstr(tmp, ==, "foobar"); +} + +static void +test_setting_gsm_apn_bad_chars(void) +{ + gs_unref_object NMSettingGsm *s_gsm = NULL; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new(); + g_assert(s_gsm); + + /* Make sure a valid APN works */ + g_object_set(s_gsm, NM_SETTING_GSM_APN, "foobar123.-baz", NULL); + g_assert(nm_setting_verify(NM_SETTING(s_gsm), NULL, NULL)); + + /* Random invalid chars */ + g_object_set(s_gsm, NM_SETTING_GSM_APN, "@#%$@#%@#%", NULL); + g_assert(!nm_setting_verify(NM_SETTING(s_gsm), NULL, NULL)); + + /* Spaces */ + g_object_set(s_gsm, NM_SETTING_GSM_APN, "foobar baz", NULL); + g_assert(!nm_setting_verify(NM_SETTING(s_gsm), NULL, NULL)); + + /* 0 characters long */ + g_object_set(s_gsm, NM_SETTING_GSM_APN, "", NULL); + g_assert(nm_setting_verify(NM_SETTING(s_gsm), NULL, NULL)); + + /* 65-character long */ + g_object_set(s_gsm, + NM_SETTING_GSM_APN, + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl1", + NULL); + g_assert(!nm_setting_verify(NM_SETTING(s_gsm), NULL, NULL)); +} + +static void +test_setting_gsm_apn_underscore(void) +{ + gs_unref_object NMSettingGsm *s_gsm = NULL; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new(); + g_assert(s_gsm); + + /* 65-character long */ + g_object_set(s_gsm, NM_SETTING_GSM_APN, "foobar_baz", NULL); + nmtst_assert_setting_verifies(NM_SETTING(s_gsm)); +} + +static void +test_setting_gsm_without_number(void) +{ + gs_unref_object NMSettingGsm *s_gsm = NULL; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new(); + g_assert(s_gsm); + + g_object_set(s_gsm, NM_SETTING_GSM_NUMBER, NULL, NULL); + nmtst_assert_setting_verifies(NM_SETTING(s_gsm)); + + g_object_set(s_gsm, NM_SETTING_GSM_NUMBER, "", NULL); + nmtst_assert_setting_verify_fails(NM_SETTING(s_gsm), + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +test_setting_gsm_sim_operator_id(void) +{ + gs_unref_object NMSettingGsm *s_gsm = NULL; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new(); + g_assert(s_gsm); + + /* Valid */ + g_object_set(s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "12345", NULL); + nmtst_assert_setting_verifies(NM_SETTING(s_gsm)); + + g_object_set(s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "123456", NULL); + nmtst_assert_setting_verifies(NM_SETTING(s_gsm)); + + /* Invalid */ + g_object_set(s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "", NULL); + nmtst_assert_setting_verify_fails(NM_SETTING(s_gsm), + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + + g_object_set(s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, " ", NULL); + nmtst_assert_setting_verify_fails(NM_SETTING(s_gsm), + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + + g_object_set(s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "abcdef", NULL); + nmtst_assert_setting_verify_fails(NM_SETTING(s_gsm), + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static NMSettingWirelessSecurity * +make_test_wsec_setting(const char *detail) +{ + NMSettingWirelessSecurity *s_wsec; + + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); + g_assert(s_wsec); + + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "foobarbaz", + NM_SETTING_WIRELESS_SECURITY_PSK, + "random psk", + NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, + NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "aaaaaaaaaa", + NULL); + return s_wsec; +} + +static gboolean +_variant_contains(GVariant *vardict, const char *key) +{ + gs_unref_variant GVariant *value = NULL; + + value = g_variant_lookup_value(vardict, key, NULL); + return !!value; +} + +static void +test_setting_to_dbus_all(void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant * dict; + + s_wsec = make_test_wsec_setting("setting-to-dbus-all"); + + dict = _nm_setting_to_dbus(NM_SETTING(s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); + + /* Make sure all keys are there */ + g_assert(_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT)); + g_assert(_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME)); + g_assert(_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_PSK)); + g_assert(_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0)); + + g_variant_unref(dict); + g_object_unref(s_wsec); +} + +static void +test_setting_to_dbus_no_secrets(void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant * dict; + + s_wsec = make_test_wsec_setting("setting-to-dbus-no-secrets"); + + dict = _nm_setting_to_dbus(NM_SETTING(s_wsec), NULL, NM_CONNECTION_SERIALIZE_NO_SECRETS, NULL); + + /* Make sure non-secret keys are there */ + g_assert(_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT)); + g_assert(_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME)); + + /* Make sure secrets are not there */ + g_assert(!_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_PSK)); + g_assert(!_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0)); + + g_variant_unref(dict); + g_object_unref(s_wsec); +} + +static void +test_setting_to_dbus_only_secrets(void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant * dict; + + s_wsec = make_test_wsec_setting("setting-to-dbus-only-secrets"); + + dict = + _nm_setting_to_dbus(NM_SETTING(s_wsec), NULL, NM_CONNECTION_SERIALIZE_ONLY_SECRETS, NULL); + + /* Make sure non-secret keys are not there */ + g_assert(!_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT)); + g_assert(!_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME)); + + /* Make sure secrets are there */ + g_assert(_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_PSK)); + g_assert(_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0)); + + g_variant_unref(dict); + g_object_unref(s_wsec); +} + +static void +test_setting_to_dbus_transform(void) +{ + NMSetting * s_wired; + GVariant * dict, *val; + const char * test_mac_address = "11:22:33:44:55:66"; + const guint8 *dbus_mac_address; + guint8 cmp_mac_address[ETH_ALEN]; + gsize len; + + s_wired = nm_setting_wired_new(); + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, test_mac_address, NULL); + + g_assert_cmpstr(nm_setting_wired_get_mac_address(NM_SETTING_WIRED(s_wired)), + ==, + test_mac_address); + + dict = _nm_setting_to_dbus(s_wired, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); + g_assert(dict != NULL); + + val = g_variant_lookup_value(dict, NM_SETTING_WIRED_MAC_ADDRESS, G_VARIANT_TYPE_BYTESTRING); + g_assert(val != NULL); + + dbus_mac_address = g_variant_get_fixed_array(val, &len, 1); + g_assert_cmpint(len, ==, ETH_ALEN); + + nm_utils_hwaddr_aton(test_mac_address, cmp_mac_address, ETH_ALEN); + g_assert(memcmp(dbus_mac_address, cmp_mac_address, ETH_ALEN) == 0); + + g_variant_unref(val); + g_variant_unref(dict); + g_object_unref(s_wired); +} + +static void +test_setting_to_dbus_enum(void) +{ + NMSetting *s_ip6, *s_wsec, *s_serial; + GVariant * dict, *val; + + /* enum */ + s_ip6 = nm_setting_ip6_config_new(); + g_object_set(s_ip6, + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NULL); + + dict = _nm_setting_to_dbus(s_ip6, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); + g_assert(dict != NULL); + + val = g_variant_lookup_value(dict, NM_SETTING_IP6_CONFIG_IP6_PRIVACY, G_VARIANT_TYPE_INT32); + g_assert(val != NULL); + g_assert_cmpint(g_variant_get_int32(val), ==, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); + g_variant_unref(val); + + g_variant_unref(dict); + g_object_unref(s_ip6); + + /* flags (and a transformed enum) */ + s_wsec = nm_setting_wireless_security_new(); + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + NM_WEP_KEY_TYPE_KEY, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED), + NULL); + + dict = _nm_setting_to_dbus(s_wsec, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); + g_assert(dict != NULL); + + val = g_variant_lookup_value(dict, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + G_VARIANT_TYPE_UINT32); + g_assert(val != NULL); + g_assert_cmpint(g_variant_get_uint32(val), ==, NM_WEP_KEY_TYPE_KEY); + g_variant_unref(val); + + val = g_variant_lookup_value(dict, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + G_VARIANT_TYPE_UINT32); + g_assert(val != NULL); + g_assert_cmpint(g_variant_get_uint32(val), + ==, + (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED)); + g_variant_unref(val); + + g_variant_unref(dict); + g_object_unref(s_wsec); + + /* another transformed enum */ + s_serial = nm_setting_serial_new(); + g_object_set(s_serial, NM_SETTING_SERIAL_PARITY, NM_SETTING_SERIAL_PARITY_ODD, NULL); + + dict = _nm_setting_to_dbus(s_serial, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); + g_assert(dict != NULL); + + val = g_variant_lookup_value(dict, NM_SETTING_SERIAL_PARITY, G_VARIANT_TYPE_BYTE); + g_assert(val != NULL); + g_assert_cmpint(g_variant_get_byte(val), ==, 'o'); + g_variant_unref(val); + + g_variant_unref(dict); + g_object_unref(s_serial); +} + +static void +test_connection_to_dbus_setting_name(void) +{ + NMConnection * connection; + NMSettingWirelessSecurity *s_wsec; + GVariant * dict; + + connection = nm_simple_connection_new(); + s_wsec = make_test_wsec_setting("connection-to-dbus-setting-name"); + nm_connection_add_setting(connection, NM_SETTING(s_wsec)); + + g_assert(_nm_connection_aggregate(connection, NM_CONNECTION_AGGREGATE_ANY_SECRETS, NULL)); + g_assert(_nm_connection_aggregate(connection, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, + NULL)); + + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, + NM_SETTING_SECRET_FLAG_NOT_SAVED, + NULL); + + g_assert(_nm_connection_aggregate(connection, NM_CONNECTION_AGGREGATE_ANY_SECRETS, NULL)); + g_assert(!_nm_connection_aggregate(connection, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, + NULL)); + + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + NULL); + + g_assert(_nm_connection_aggregate(connection, NM_CONNECTION_AGGREGATE_ANY_SECRETS, NULL)); + g_assert(_nm_connection_aggregate(connection, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, + NULL)); + + dict = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); + + /* Make sure the keys of the first level dict are setting names, not + * the GType name of the setting objects. + */ + g_assert(_variant_contains(dict, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)); + + g_variant_unref(dict); + g_object_unref(connection); +} + +static void +test_connection_to_dbus_deprecated_props(void) +{ + NMConnection * connection; + NMSetting * s_wireless; + GBytes * ssid; + NMSettingWirelessSecurity *s_wsec; + GVariant * dict, *wireless_dict, *sec_val; + + connection = nmtst_create_minimal_connection("test-connection-to-dbus-deprecated-props", + NULL, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + s_wireless = nm_setting_wireless_new(); + ssid = g_bytes_new("1234567", 7); + g_object_set(s_wireless, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_bytes_unref(ssid); + nm_connection_add_setting(connection, s_wireless); + + /* Serialization should not have an 802-11-wireless.security property */ + dict = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert(dict != NULL); + + wireless_dict = + g_variant_lookup_value(dict, NM_SETTING_WIRELESS_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert(wireless_dict != NULL); + + sec_val = g_variant_lookup_value(wireless_dict, "security", NULL); + g_assert(sec_val == NULL); + + g_variant_unref(wireless_dict); + g_variant_unref(dict); + + /* Now add an NMSettingWirelessSecurity and try again */ + s_wsec = make_test_wsec_setting("test-connection-to-dbus-deprecated-props"); + nm_connection_add_setting(connection, NM_SETTING(s_wsec)); + + dict = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert(dict != NULL); + + wireless_dict = + g_variant_lookup_value(dict, NM_SETTING_WIRELESS_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert(wireless_dict != NULL); + + sec_val = g_variant_lookup_value(wireless_dict, "security", NULL); + g_assert(g_variant_is_of_type(sec_val, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr(g_variant_get_string(sec_val, NULL), + ==, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + g_variant_unref(sec_val); + g_variant_unref(wireless_dict); + g_variant_unref(dict); + g_object_unref(connection); +} + +static void +test_setting_new_from_dbus(void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant * dict; + + s_wsec = make_test_wsec_setting("setting-new-from-dbus"); + dict = _nm_setting_to_dbus(NM_SETTING(s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); + g_object_unref(s_wsec); + + s_wsec = + (NMSettingWirelessSecurity *) _nm_setting_new_from_dbus(NM_TYPE_SETTING_WIRELESS_SECURITY, + dict, + NULL, + NM_SETTING_PARSE_FLAGS_NONE, + NULL); + g_variant_unref(dict); + + g_assert(s_wsec); + g_assert_cmpstr(nm_setting_wireless_security_get_key_mgmt(s_wsec), ==, "wpa-psk"); + g_assert_cmpstr(nm_setting_wireless_security_get_leap_username(s_wsec), ==, "foobarbaz"); + g_assert_cmpstr(nm_setting_wireless_security_get_psk(s_wsec), ==, "random psk"); + g_object_unref(s_wsec); +} + +static void +test_setting_new_from_dbus_transform(void) +{ + NMSetting * s_wired; + GVariant * dict; + GVariantBuilder builder; + const char * test_mac_address = "11:22:33:44:55:66"; + guint8 dbus_mac_address[ETH_ALEN]; + GError * error = NULL; + + nm_utils_hwaddr_aton(test_mac_address, dbus_mac_address, ETH_ALEN); + + g_variant_builder_init(&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add( + &builder, + "{sv}", + NM_SETTING_WIRED_MAC_ADDRESS, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, dbus_mac_address, ETH_ALEN, 1)); + dict = g_variant_builder_end(&builder); + + s_wired = _nm_setting_new_from_dbus(NM_TYPE_SETTING_WIRED, + dict, + NULL, + NM_SETTING_PARSE_FLAGS_NONE, + &error); + g_assert_no_error(error); + + g_assert_cmpstr(nm_setting_wired_get_mac_address(NM_SETTING_WIRED(s_wired)), + ==, + test_mac_address); + + g_variant_unref(dict); + g_object_unref(s_wired); +} + +static void +test_setting_new_from_dbus_enum(void) +{ + NMSettingIP6Config * s_ip6; + NMSettingWirelessSecurity *s_wsec; + NMSettingSerial * s_serial; + GVariant * dict; + GVariantBuilder builder; + GError * error = NULL; + + /* enum */ + g_variant_builder_init(&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add(&builder, + "{sv}", + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + g_variant_new_int32(NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR)); + dict = g_variant_builder_end(&builder); + + s_ip6 = (NMSettingIP6Config *) _nm_setting_new_from_dbus(NM_TYPE_SETTING_IP6_CONFIG, + dict, + NULL, + NM_SETTING_PARSE_FLAGS_NONE, + &error); + g_assert_no_error(error); + + g_assert_cmpint(nm_setting_ip6_config_get_ip6_privacy(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); + + g_variant_unref(dict); + g_object_unref(s_ip6); + + /* flags (and a transformed enum) */ + g_variant_builder_init(&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add(&builder, + "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + g_variant_new_uint32(NM_WEP_KEY_TYPE_KEY)); + g_variant_builder_add(&builder, + "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + g_variant_new_uint32(NM_SETTING_SECRET_FLAG_AGENT_OWNED + | NM_SETTING_SECRET_FLAG_NOT_SAVED)); + dict = g_variant_builder_end(&builder); + + s_wsec = + (NMSettingWirelessSecurity *) _nm_setting_new_from_dbus(NM_TYPE_SETTING_WIRELESS_SECURITY, + dict, + NULL, + NM_SETTING_PARSE_FLAGS_NONE, + &error); + g_assert_no_error(error); + + g_assert_cmpint(nm_setting_wireless_security_get_wep_key_type(s_wsec), ==, NM_WEP_KEY_TYPE_KEY); + g_assert_cmpint(nm_setting_wireless_security_get_wep_key_flags(s_wsec), + ==, + (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED)); + + g_variant_unref(dict); + g_object_unref(s_wsec); + + /* another transformed enum */ + g_variant_builder_init(&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add(&builder, "{sv}", NM_SETTING_SERIAL_PARITY, g_variant_new_byte('E')); + dict = g_variant_builder_end(&builder); + + s_serial = (NMSettingSerial *) _nm_setting_new_from_dbus(NM_TYPE_SETTING_SERIAL, + dict, + NULL, + NM_SETTING_PARSE_FLAGS_NONE, + &error); + g_assert_no_error(error); + + g_assert_cmpint(nm_setting_serial_get_parity(s_serial), ==, NM_SETTING_SERIAL_PARITY_EVEN); + + g_variant_unref(dict); + g_object_unref(s_serial); +} + +static void +test_setting_new_from_dbus_bad(void) +{ + NMSetting * setting; + NMConnection *conn; + GBytes * ssid; + GPtrArray * addrs; + GVariant * orig_dict, *dict; + GError * error = NULL; + + /* We want to test: + * - ordinary scalar properties + * - string properties + * - GBytes-valued properties (which are handled specially by set_property_from_dbus()) + * - enum/flags-valued properties + * - overridden properties + * - transformed properties + * + * No single setting class has examples of all of these, so we need two settings. + */ + + conn = nm_simple_connection_new(); + + setting = nm_setting_connection_new(); + g_object_set(setting, + NM_SETTING_CONNECTION_ID, + "test", + NM_SETTING_CONNECTION_UUID, + "83c5a841-1759-4cdb-bfce-8d4087956497", + NULL); + nm_connection_add_setting(conn, setting); + + setting = nm_setting_wireless_new(); + ssid = g_bytes_new("my-ssid", 7); + g_object_set(setting, + /* scalar */ + NM_SETTING_WIRELESS_RATE, + 100, + /* string */ + NM_SETTING_WIRELESS_MODE, + NM_SETTING_WIRELESS_MODE_INFRA, + /* GBytes */ + NM_SETTING_WIRELESS_SSID, + ssid, + /* transformed */ + NM_SETTING_WIRELESS_BSSID, + "00:11:22:33:44:55", + NULL); + g_bytes_unref(ssid); + nm_connection_add_setting(conn, setting); + + setting = nm_setting_ip6_config_new(); + addrs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + g_ptr_array_add(addrs, nm_ip_address_new(AF_INET6, "1234::5678", 64, NULL)); + g_object_set(setting, + /* enum */ + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR, + /* overridden */ + NM_SETTING_IP_CONFIG_ADDRESSES, + addrs, + /* (needed in order to verify()) */ + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NULL); + g_ptr_array_unref(addrs); + nm_connection_add_setting(conn, setting); + + orig_dict = nm_connection_to_dbus(conn, NM_CONNECTION_SERIALIZE_ALL); + g_object_unref(conn); + + /* sanity-check */ + conn = _connection_new_from_dbus(orig_dict, &error); + g_assert_no_error(error); + g_assert(conn); + g_object_unref(conn); + + /* Compatible mismatches */ + + dict = g_variant_ref(orig_dict); + NMTST_VARIANT_EDITOR(dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_RATE, + "i", + 10);); + conn = _connection_new_from_dbus(dict, &error); + g_assert(conn); + g_assert_no_error(error); + setting = nm_connection_get_setting(conn, NM_TYPE_SETTING_WIRELESS); + g_assert(setting); + g_assert_cmpint(nm_setting_wireless_get_rate(NM_SETTING_WIRELESS(setting)), ==, 10); + g_object_unref(conn); + g_variant_unref(dict); + + dict = g_variant_ref(orig_dict); + NMTST_VARIANT_EDITOR( + dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + "i", + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR);); + conn = _connection_new_from_dbus(dict, &error); + g_assert(conn); + g_assert_no_error(error); + setting = nm_connection_get_setting(conn, NM_TYPE_SETTING_IP6_CONFIG); + g_assert(setting); + g_assert_cmpint(nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(setting)), + ==, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); + g_object_unref(conn); + g_variant_unref(dict); + + /* Incompatible mismatches */ + + dict = g_variant_ref(orig_dict); + NMTST_VARIANT_EDITOR(dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_RATE, + "s", + "ten");); + conn = _connection_new_from_dbus(dict, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "802-11-wireless.rate:")); + g_clear_error(&error); + g_variant_unref(dict); + + dict = g_variant_ref(orig_dict); + NMTST_VARIANT_EDITOR(dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE, + "b", + FALSE);); + conn = _connection_new_from_dbus(dict, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "802-11-wireless.mode:")); + g_clear_error(&error); + g_variant_unref(dict); + + dict = g_variant_ref(orig_dict); + NMTST_VARIANT_EDITOR(dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID, + "s", + "fred");); + conn = _connection_new_from_dbus(dict, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "802-11-wireless.ssid:")); + g_clear_error(&error); + g_variant_unref(dict); + + dict = g_variant_ref(orig_dict); + NMTST_VARIANT_EDITOR(dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_BSSID, + "i", + 42);); + conn = _connection_new_from_dbus(dict, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "802-11-wireless.bssid:")); + g_clear_error(&error); + g_variant_unref(dict); + + dict = g_variant_ref(orig_dict); + NMTST_VARIANT_EDITOR(dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + "s", + "private");); + conn = _connection_new_from_dbus(dict, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "ipv6.ip6-privacy:")); + g_clear_error(&error); + g_variant_unref(dict); + + dict = g_variant_ref(orig_dict); + NMTST_VARIANT_EDITOR(dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_ADDRESSES, + "s", + "1234::5678");); + conn = _connection_new_from_dbus(dict, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "ipv6.addresses:")); + g_clear_error(&error); + g_variant_unref(dict); + + g_variant_unref(orig_dict); +} + +static NMConnection * +new_test_connection(void) +{ + NMConnection *connection; + NMSetting * setting; + char * uuid; + guint64 timestamp = time(NULL); + + connection = nm_simple_connection_new(); + + setting = nm_setting_connection_new(); + uuid = nm_utils_uuid_generate(); + g_object_set(G_OBJECT(setting), + NM_SETTING_CONNECTION_ID, + "foobar", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, + timestamp, + NULL); + g_free(uuid); + nm_connection_add_setting(connection, setting); + + setting = nm_setting_wired_new(); + g_object_set(G_OBJECT(setting), NM_SETTING_WIRED_MTU, 1592, NULL); + nm_connection_add_setting(connection, setting); + + setting = nm_setting_ip4_config_new(); + g_object_set(G_OBJECT(setting), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, + "eyeofthetiger", + NULL); + nm_connection_add_setting(connection, setting); + + return connection; +} + +static GVariant * +new_connection_dict(char ** out_uuid, + const char **out_expected_id, + const char **out_expected_ip6_method) +{ + GVariantBuilder conn_builder, setting_builder; + + g_variant_builder_init(&conn_builder, NM_VARIANT_TYPE_CONNECTION); + + *out_uuid = nm_utils_uuid_generate(); + *out_expected_id = "My happy connection"; + *out_expected_ip6_method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; + + /* Connection setting */ + g_variant_builder_init(&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add(&setting_builder, + "{sv}", + NM_SETTING_NAME, + g_variant_new_string(NM_SETTING_CONNECTION_SETTING_NAME)); + g_variant_builder_add(&setting_builder, + "{sv}", + NM_SETTING_CONNECTION_ID, + g_variant_new_string(*out_expected_id)); + g_variant_builder_add(&setting_builder, + "{sv}", + NM_SETTING_CONNECTION_UUID, + g_variant_new_string(*out_uuid)); + g_variant_builder_add(&setting_builder, + "{sv}", + NM_SETTING_CONNECTION_TYPE, + g_variant_new_string(NM_SETTING_WIRED_SETTING_NAME)); + + g_variant_builder_add(&conn_builder, + "{sa{sv}}", + NM_SETTING_CONNECTION_SETTING_NAME, + &setting_builder); + + /* Wired setting */ + g_variant_builder_init(&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add(&conn_builder, + "{sa{sv}}", + NM_SETTING_WIRED_SETTING_NAME, + &setting_builder); + + /* IP6 */ + g_variant_builder_init(&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add(&setting_builder, + "{sv}", + NM_SETTING_IP_CONFIG_METHOD, + g_variant_new_string(*out_expected_ip6_method)); + g_variant_builder_add(&conn_builder, + "{sa{sv}}", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + &setting_builder); + + return g_variant_builder_end(&conn_builder); +} + +static void +test_connection_replace_settings(void) +{ + NMConnection * connection; + GVariant * new_settings; + GError * error = NULL; + gboolean success; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip6; + char * uuid = NULL; + const char * expected_id = NULL, *expected_method = NULL; + + connection = new_test_connection(); + + new_settings = new_connection_dict(&uuid, &expected_id, &expected_method); + g_assert(new_settings); + + /* Replace settings and test */ + success = nm_connection_replace_settings(connection, new_settings, &error); + g_assert_no_error(error); + g_assert(success); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, expected_id); + g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), ==, uuid); + + g_assert(nm_connection_get_setting_wired(connection)); + g_assert(!nm_connection_get_setting_ip4_config(connection)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, expected_method); + + g_free(uuid); + g_variant_unref(new_settings); + g_object_unref(connection); +} + +static void +test_connection_replace_settings_from_connection(void) +{ + NMConnection * connection, *replacement; + NMSettingConnection *s_con; + NMSetting * setting; + GBytes * ssid; + char * uuid = NULL; + const char * expected_id = "Awesome connection"; + + connection = new_test_connection(); + g_assert(connection); + + replacement = nm_simple_connection_new(); + g_assert(replacement); + + /* New connection setting */ + setting = nm_setting_connection_new(); + g_assert(setting); + + uuid = nm_utils_uuid_generate(); + g_object_set(setting, + NM_SETTING_CONNECTION_ID, + expected_id, + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + nm_connection_add_setting(replacement, setting); + + /* New wifi setting */ + setting = nm_setting_wireless_new(); + g_assert(setting); + + ssid = g_bytes_new("1234567", 7); + g_object_set(setting, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + g_bytes_unref(ssid); + nm_connection_add_setting(replacement, setting); + + /* Replace settings and test */ + nm_connection_replace_settings_from_connection(connection, replacement); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, expected_id); + g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), ==, uuid); + + g_assert(!nm_connection_get_setting_wired(connection)); + g_assert(!nm_connection_get_setting_ip6_config(connection)); + g_assert(nm_connection_get_setting_wireless(connection)); + + g_free(uuid); + g_object_unref(replacement); + g_object_unref(connection); +} + +static void +test_connection_replace_settings_bad(void) +{ + NMConnection * connection, *new_connection; + GVariant * new_settings; + GVariantBuilder builder, setting_builder; + GError * error = NULL; + gboolean success; + NMSettingConnection *s_con; + + new_connection = new_test_connection(); + g_assert(nm_connection_verify(new_connection, NULL)); + s_con = nm_connection_get_setting_connection(new_connection); + g_object_set(s_con, + NM_SETTING_CONNECTION_UUID, + NULL, + NM_SETTING_CONNECTION_ID, + "bad-connection", + NULL); + g_assert(!nm_connection_verify(new_connection, NULL)); + + /* nm_connection_replace_settings_from_connection() should succeed */ + connection = new_test_connection(); + nm_connection_replace_settings_from_connection(connection, new_connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "bad-connection"); + g_assert(!nm_connection_verify(connection, NULL)); + g_object_unref(connection); + + /* nm_connection_replace_settings() should succeed */ + new_settings = nm_connection_to_dbus(new_connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert(new_settings != NULL); + + connection = new_test_connection(); + success = nm_connection_replace_settings(connection, new_settings, &error); + g_assert_no_error(error); + g_assert(success); + + g_assert_cmpstr(nm_connection_get_id(connection), ==, "bad-connection"); + g_assert(!nm_connection_verify(connection, NULL)); + g_object_unref(connection); + g_variant_unref(new_settings); + + /* But given an invalid dict, it should fail */ + g_variant_builder_init(&builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_init(&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add(&builder, "{sa{sv}}", "ip-over-avian-carrier", &setting_builder); + new_settings = g_variant_builder_end(&builder); + + connection = new_test_connection(); + success = nm_connection_replace_settings(connection, new_settings, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); + g_clear_error(&error); + g_assert(!success); + + g_assert(nm_connection_verify(connection, NULL)); + g_object_unref(connection); + + g_variant_unref(new_settings); + g_object_unref(new_connection); +} + +static void +test_connection_new_from_dbus(void) +{ + NMConnection * connection; + GVariant * new_settings; + GError * error = NULL; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip6; + char * uuid = NULL; + const char * expected_id = NULL, *expected_method = NULL; + + new_settings = new_connection_dict(&uuid, &expected_id, &expected_method); + g_assert(new_settings); + + /* Replace settings and test */ + connection = _connection_new_from_dbus(new_settings, &error); + g_assert_no_error(error); + g_assert(connection); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, expected_id); + g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), ==, uuid); + + g_assert(nm_connection_get_setting_wired(connection)); + g_assert(nm_connection_get_setting_ip4_config(connection)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, expected_method); + + g_free(uuid); + g_variant_unref(new_settings); + g_object_unref(connection); +} + +static void +check_permission(NMSettingConnection *s_con, guint32 idx, const char *expected_uname) +{ + gboolean success; + const char *ptype = NULL, *pitem = NULL, *detail = NULL; + + success = nm_setting_connection_get_permission(s_con, idx, &ptype, &pitem, &detail); + g_assert(success); + + g_assert_cmpstr(ptype, ==, "user"); + + g_assert(pitem); + g_assert_cmpstr(pitem, ==, expected_uname); + + g_assert(!detail); +} + +#define TEST_UNAME "asdfasfasdf" + +static void +test_setting_connection_permissions_helpers(void) +{ + NMSettingConnection *s_con; + gboolean success; + char buf[9] = {0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00}; + char ** perms; + const char * expected_perm = "user:" TEST_UNAME ":"; + + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + + /* Ensure a bad [type] is rejected */ + success = nm_setting_connection_add_permission(s_con, "foobar", "blah", NULL); + g_assert(!success); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 0); + + /* Ensure a bad [type] is rejected */ + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(ptype)); + success = nm_setting_connection_add_permission(s_con, NULL, "blah", NULL); + g_test_assert_expected_messages(); + g_assert(!success); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 0); + + /* Ensure a bad [item] is rejected */ + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(pitem)); + success = nm_setting_connection_add_permission(s_con, "user", NULL, NULL); + g_test_assert_expected_messages(); + g_assert(!success); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 0); + + /* Ensure a bad [item] is rejected */ + success = nm_setting_connection_add_permission(s_con, "user", "", NULL); + g_assert(!success); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 0); + + /* Ensure an [item] with ':' is rejected */ + success = nm_setting_connection_add_permission(s_con, "user", "ad:asdf", NULL); + g_assert(!success); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 0); + + /* Ensure a non-UTF-8 [item] is rejected */ + success = nm_setting_connection_add_permission(s_con, "user", buf, NULL); + g_assert(!success); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 0); + + /* Ensure a non-NULL [detail] is rejected */ + success = nm_setting_connection_add_permission(s_con, "user", "dafasdf", "asdf"); + g_assert(!success); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 0); + + /* Ensure a valid call results in success */ + success = nm_setting_connection_add_permission(s_con, "user", TEST_UNAME, NULL); + g_assert(success); + + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); + + check_permission(s_con, 0, TEST_UNAME); + + /* Check the actual GObject property just to be paranoid */ + g_object_get(G_OBJECT(s_con), NM_SETTING_CONNECTION_PERMISSIONS, &perms, NULL); + g_assert(perms); + g_assert_cmpint(g_strv_length(perms), ==, 1); + g_assert_cmpstr(perms[0], ==, expected_perm); + g_strfreev(perms); + + /* Now remove that permission and ensure we have 0 permissions */ + nm_setting_connection_remove_permission(s_con, 0); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 0); + + g_object_unref(s_con); +} + +static void +add_permission_property(NMSettingConnection *s_con, + const char * ptype, + const char * pitem, + int pitem_len, + const char * detail) +{ + GString *str; + char * perms[2]; + + str = g_string_sized_new(50); + if (ptype) + g_string_append(str, ptype); + g_string_append_c(str, ':'); + + if (pitem) { + if (pitem_len >= 0) + g_string_append_len(str, pitem, pitem_len); + else + g_string_append(str, pitem); + } + + g_string_append_c(str, ':'); + + if (detail) + g_string_append(str, detail); + + perms[0] = str->str; + perms[1] = NULL; + g_object_set(G_OBJECT(s_con), NM_SETTING_CONNECTION_PERMISSIONS, perms, NULL); + + g_string_free(str, TRUE); +} + +static void +test_setting_connection_permissions_property(void) +{ + gs_unref_object NMSettingConnection *s_con = NULL; + gboolean success; + char buf[9] = {0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00}; + + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + +#define _assert_permission_invalid_at_idx(s_con, idx, expected_item) \ + G_STMT_START \ + { \ + NMSettingConnection *_s_con = (s_con); \ + guint _idx = (idx); \ + const char * _ptype; \ + const char * _pitem; \ + const char * _detail; \ + const char ** _p_ptype = nmtst_get_rand_bool() ? &_ptype : NULL; \ + const char ** _p_pitem = nmtst_get_rand_bool() ? &_pitem : NULL; \ + const char ** _p_detail = nmtst_get_rand_bool() ? &_detail : NULL; \ + \ + g_assert_cmpint(_idx, <, nm_setting_connection_get_num_permissions(_s_con)); \ + g_assert( \ + nm_setting_connection_get_permission(_s_con, _idx, _p_ptype, _p_pitem, _p_detail)); \ + if (_p_ptype) \ + g_assert_cmpstr(_ptype, ==, "invalid"); \ + if (_p_pitem) { \ + const char *_expected_item = (expected_item); \ + \ + if (!_expected_item) \ + g_assert_cmpstr(_pitem, !=, NULL); \ + else \ + g_assert_cmpstr(_pitem, ==, _expected_item); \ + } \ + if (_p_detail) \ + g_assert_cmpstr(_detail, ==, NULL); \ + } \ + G_STMT_END + + /* Ensure a bad [type] is rejected */ + add_permission_property(s_con, "foobar", "blah", -1, NULL); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); + _assert_permission_invalid_at_idx(s_con, 0, "foobar:blah:"); + + /* Ensure a bad [type] is rejected */ + add_permission_property(s_con, NULL, "blah", -1, NULL); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); + _assert_permission_invalid_at_idx(s_con, 0, ":blah:"); + + /* Ensure a bad [item] is rejected */ + add_permission_property(s_con, "user", NULL, -1, NULL); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); + _assert_permission_invalid_at_idx(s_con, 0, "user::"); + + /* Ensure a bad [item] is rejected */ + add_permission_property(s_con, "user", "", -1, NULL); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); + _assert_permission_invalid_at_idx(s_con, 0, "user::"); + + /* Ensure an [item] with ':' in the middle is rejected */ + add_permission_property(s_con, "user", "ad:asdf", -1, NULL); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); + _assert_permission_invalid_at_idx(s_con, 0, "user:ad:asdf:"); + + /* Ensure an [item] with ':' at the end is rejected */ + add_permission_property(s_con, "user", "adasdfaf:", -1, NULL); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); + _assert_permission_invalid_at_idx(s_con, 0, "user:adasdfaf::"); + + /* Ensure a non-UTF-8 [item] is rejected */ + add_permission_property(s_con, "user", buf, (int) sizeof(buf), NULL); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); + _assert_permission_invalid_at_idx(s_con, 0, NULL); + + /* Ensure a non-NULL [detail] is rejected */ + add_permission_property(s_con, "user", "dafasdf", -1, "asdf"); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); + _assert_permission_invalid_at_idx(s_con, 0, "user:dafasdf:asdf"); + + /* Ensure a valid call results in success */ + success = nm_setting_connection_add_permission(s_con, "user", TEST_UNAME, NULL); + g_assert(success); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 2); + _assert_permission_invalid_at_idx(s_con, 0, "user:dafasdf:asdf"); + check_permission(s_con, 1, TEST_UNAME); + + /* Now remove that permission and ensure we have 0 permissions */ + nm_setting_connection_remove_permission(s_con, 0); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); +} + +static void +test_connection_compare_same(void) +{ + NMConnection *a, *b; + + a = new_test_connection(); + b = nm_simple_connection_new_clone(a); + g_assert(nm_connection_compare(a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref(a); + g_object_unref(b); +} + +static void +test_connection_compare_key_only_in_a(void) +{ + NMConnection * a, *b; + NMSettingConnection *s_con; + + a = new_test_connection(); + b = nm_simple_connection_new_clone(a); + s_con = (NMSettingConnection *) nm_connection_get_setting(b, NM_TYPE_SETTING_CONNECTION); + g_assert(s_con); + g_object_set(s_con, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 0, NULL); + + g_assert(!nm_connection_compare(a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref(a); + g_object_unref(b); +} + +static void +test_connection_compare_setting_only_in_a(void) +{ + NMConnection *a, *b; + + a = new_test_connection(); + b = nm_simple_connection_new_clone(a); + nm_connection_remove_setting(b, NM_TYPE_SETTING_IP4_CONFIG); + g_assert(!nm_connection_compare(a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref(a); + g_object_unref(b); +} + +static void +test_connection_compare_key_only_in_b(void) +{ + NMConnection * a, *b; + NMSettingConnection *s_con; + + a = new_test_connection(); + b = nm_simple_connection_new_clone(a); + s_con = (NMSettingConnection *) nm_connection_get_setting(b, NM_TYPE_SETTING_CONNECTION); + g_assert(s_con); + g_object_set(s_con, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 0, NULL); + + g_assert(!nm_connection_compare(a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref(a); + g_object_unref(b); +} + +static void +test_connection_compare_setting_only_in_b(void) +{ + NMConnection *a, *b; + + a = new_test_connection(); + b = nm_simple_connection_new_clone(a); + nm_connection_remove_setting(a, NM_TYPE_SETTING_IP4_CONFIG); + g_assert(!nm_connection_compare(a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref(a); + g_object_unref(b); +} + +typedef struct { + const char *key_name; + guint32 result; +} DiffKey; + +typedef struct { + const char *name; + DiffKey keys[30]; +} DiffSetting; + +#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0])) + +static void +ensure_diffs(GHashTable *diffs, const DiffSetting *check, gsize n_check) +{ + guint i; + + g_assert(g_hash_table_size(diffs) == n_check); + + /* Loop through the settings */ + for (i = 0; i < n_check; i++) { + GHashTable *setting_hash; + guint z = 0; + + setting_hash = g_hash_table_lookup(diffs, check[i].name); + g_assert(setting_hash); + + /* Get the number of keys to check */ + while (check[i].keys[z].key_name) + z++; + g_assert(g_hash_table_size(setting_hash) == z); + + /* Now compare the actual keys */ + for (z = 0; check[i].keys[z].key_name; z++) { + NMSettingDiffResult result; + + result = GPOINTER_TO_UINT(g_hash_table_lookup(setting_hash, check[i].keys[z].key_name)); + g_assert(result == check[i].keys[z].result); + } + } +} + +static void +test_connection_diff_a_only(void) +{ + NMConnection * connection; + GHashTable * out_diffs = NULL; + gboolean same; + const DiffSetting settings[] = { + {NM_SETTING_CONNECTION_SETTING_NAME, + {{NM_SETTING_CONNECTION_ID, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_UUID, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_STABLE_ID, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_TYPE, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_TIMESTAMP, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_AUTOCONNECT, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_MULTI_CONNECT, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_READ_ONLY, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_PERMISSIONS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_ZONE, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_MASTER, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_SECONDARIES, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_METERED, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_LLDP, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_AUTH_RETRIES, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_MDNS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_LLMNR, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_MUD_URL, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A}, + {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}}}, + {NM_SETTING_WIRED_SETTING_NAME, + { + {NM_SETTING_WIRED_PORT, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_SPEED, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_DUPLEX, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_AUTO_NEGOTIATE, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_CLONED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_MTU, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_S390_SUBCHANNELS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_S390_NETTYPE, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_S390_OPTIONS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_WAKE_ON_LAN, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, NM_SETTING_DIFF_RESULT_IN_A}, + {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, + }}, + {NM_SETTING_IP4_CONFIG_SETTING_NAME, + { + {NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DNS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DNS_SEARCH, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DNS_OPTIONS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_ADDRESSES, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_GATEWAY, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_ROUTES, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_ROUTE_METRIC, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_ROUTE_TABLE, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_ROUTING_RULES, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP4_CONFIG_DHCP_FQDN, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_NEVER_DEFAULT, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_MAY_FAIL, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DAD_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DNS_PRIORITY, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DHCP_IAID, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DHCP_REJECT_SERVERS, NM_SETTING_DIFF_RESULT_IN_A}, + {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, + }}, + }; + + connection = new_test_connection(); + + same = nm_connection_diff(connection, NULL, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert(same == FALSE); + g_assert(out_diffs != NULL); + g_assert(g_hash_table_size(out_diffs) > 0); + + ensure_diffs(out_diffs, settings, ARRAY_LEN(settings)); + + g_hash_table_destroy(out_diffs); + g_object_unref(connection); +} + +static void +test_connection_diff_same(void) +{ + NMConnection *a, *b; + GHashTable * out_diffs = NULL; + gboolean same; + + a = new_test_connection(); + b = nm_simple_connection_new_clone(a); + + same = nm_connection_diff(a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert(same == TRUE); + g_assert(out_diffs == NULL); + g_object_unref(a); + g_object_unref(b); +} + +static void +test_connection_diff_different(void) +{ + NMConnection * a, *b; + GHashTable * out_diffs = NULL; + NMSettingIPConfig *s_ip4; + gboolean same; + const DiffSetting settings[] = { + {NM_SETTING_IP4_CONFIG_SETTING_NAME, + { + {NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_DIFF_RESULT_IN_A | NM_SETTING_DIFF_RESULT_IN_B}, + {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, + }}, + }; + + a = new_test_connection(); + b = nm_simple_connection_new_clone(a); + s_ip4 = nm_connection_get_setting_ip4_config(a); + g_assert(s_ip4); + g_object_set(G_OBJECT(s_ip4), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + same = nm_connection_diff(a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert(same == FALSE); + g_assert(out_diffs != NULL); + g_assert(g_hash_table_size(out_diffs) > 0); + + ensure_diffs(out_diffs, settings, ARRAY_LEN(settings)); + + g_hash_table_destroy(out_diffs); + g_object_unref(a); + g_object_unref(b); +} + +static void +test_connection_diff_no_secrets(void) +{ + NMConnection * a, *b; + GHashTable * out_diffs = NULL; + NMSetting * s_pppoe; + gboolean same; + const DiffSetting settings[] = { + {NM_SETTING_PPPOE_SETTING_NAME, + { + {NM_SETTING_PPPOE_PASSWORD, NM_SETTING_DIFF_RESULT_IN_B}, + {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, + }}, + }; + + a = new_test_connection(); + s_pppoe = nm_setting_pppoe_new(); + g_object_set(G_OBJECT(s_pppoe), NM_SETTING_PPPOE_USERNAME, "thomas", NULL); + nm_connection_add_setting(a, s_pppoe); + + b = nm_simple_connection_new_clone(a); + + /* Add a secret to B */ + s_pppoe = NM_SETTING(nm_connection_get_setting_pppoe(b)); + g_assert(s_pppoe); + g_object_set(G_OBJECT(s_pppoe), NM_SETTING_PPPOE_PASSWORD, "secretpassword", NULL); + + /* Make sure the diff returns no results as secrets are ignored */ + same = nm_connection_diff(a, b, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, &out_diffs); + g_assert(same == TRUE); + g_assert(out_diffs == NULL); + + /* Now make sure the diff returns results if secrets are not ignored */ + same = nm_connection_diff(a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert(same == FALSE); + g_assert(out_diffs != NULL); + g_assert(g_hash_table_size(out_diffs) > 0); + + ensure_diffs(out_diffs, settings, ARRAY_LEN(settings)); + + g_hash_table_destroy(out_diffs); + g_object_unref(a); + g_object_unref(b); +} + +static void +test_connection_diff_inferrable(void) +{ + NMConnection * a, *b; + GHashTable * out_diffs = NULL; + gboolean same; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + char * uuid; + const DiffSetting settings[] = { + {NM_SETTING_CONNECTION_SETTING_NAME, + { + {NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A}, + {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, + }}, + }; + + a = new_test_connection(); + b = nm_simple_connection_new_clone(a); + + /* Change the UUID, wired MTU, and set ignore-auto-dns */ + s_con = nm_connection_get_setting_connection(a); + g_assert(s_con); + uuid = nm_utils_uuid_generate(); + g_object_set(G_OBJECT(s_con), + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_ID, + "really neat connection", + NULL); + g_free(uuid); + + s_wired = nm_connection_get_setting_wired(a); + g_assert(s_wired); + g_object_set(G_OBJECT(s_wired), NM_SETTING_WIRED_MTU, 300, NULL); + + s_ip4 = nm_connection_get_setting_ip4_config(a); + g_assert(s_ip4); + g_object_set(G_OBJECT(s_ip4), NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, NULL); + + /* Make sure the diff returns no results as secrets are ignored */ + same = nm_connection_diff(a, b, NM_SETTING_COMPARE_FLAG_INFERRABLE, &out_diffs); + g_assert(same == TRUE); + g_assert(out_diffs == NULL); + + /* And change a INFERRABLE property to ensure that it shows up in the diff results */ + g_object_set(G_OBJECT(s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, "usb0", NULL); + + /* Make sure the diff returns no results as secrets are ignored */ + same = nm_connection_diff(a, b, NM_SETTING_COMPARE_FLAG_INFERRABLE, &out_diffs); + g_assert(same == FALSE); + g_assert(out_diffs != NULL); + g_assert(g_hash_table_size(out_diffs) > 0); + + ensure_diffs(out_diffs, settings, ARRAY_LEN(settings)); + + g_hash_table_destroy(out_diffs); + g_object_unref(a); + g_object_unref(b); +} + +static void +add_generic_settings(NMConnection *connection, const char *ctype) +{ + NMSetting *setting; + char * uuid; + + uuid = nm_utils_uuid_generate(); + + setting = nm_setting_connection_new(); + g_object_set(setting, + NM_SETTING_CONNECTION_ID, + "asdfasdfadf", + NM_SETTING_CONNECTION_TYPE, + ctype, + NM_SETTING_CONNECTION_UUID, + uuid, + NULL); + nm_connection_add_setting(connection, setting); + + g_free(uuid); + + setting = nm_setting_ip4_config_new(); + g_object_set(setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting(connection, setting); + + setting = nm_setting_ip6_config_new(); + g_object_set(setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting(connection, setting); +} + +static void +test_connection_good_base_types(void) +{ + NMConnection *connection; + NMSetting * setting; + gboolean success; + GError * error = NULL; + GBytes * ssid; + const char * bdaddr = "11:22:33:44:55:66"; + + /* Try a basic wired connection */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_WIRED_SETTING_NAME); + setting = nm_setting_wired_new(); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_no_error(error); + g_assert(success); + g_object_unref(connection); + + /* Try a wired PPPoE connection */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_PPPOE_SETTING_NAME); + setting = nm_setting_pppoe_new(); + g_object_set(setting, NM_SETTING_PPPOE_USERNAME, "bob smith", NULL); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_no_error(error); + g_assert(success); + g_object_unref(connection); + + /* Wifi connection */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_WIRELESS_SETTING_NAME); + + setting = nm_setting_wireless_new(); + ssid = g_bytes_new("1234567", 7); + g_object_set(setting, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + g_bytes_unref(ssid); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_no_error(error); + g_assert(success); + g_object_unref(connection); + + /* Bluetooth connection */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_BLUETOOTH_SETTING_NAME); + + setting = nm_setting_bluetooth_new(); + g_object_set(setting, + NM_SETTING_BLUETOOTH_BDADDR, + bdaddr, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_no_error(error); + g_assert(success); + g_object_unref(connection); + + /* WiMAX connection */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_WIMAX_SETTING_NAME); + setting = nm_setting_wimax_new(); + g_object_set(setting, NM_SETTING_WIMAX_NETWORK_NAME, "CLEAR", NULL); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_no_error(error); + g_assert(success); + g_object_unref(connection); + + /* GSM connection */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_GSM_SETTING_NAME); + + setting = nm_setting_gsm_new(); + g_object_set(setting, NM_SETTING_GSM_APN, "metered.billing.sucks", NULL); + nm_connection_add_setting(connection, setting); + + /* CDMA connection */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_CDMA_SETTING_NAME); + + setting = nm_setting_cdma_new(); + g_object_set(setting, + NM_SETTING_CDMA_NUMBER, + "#777", + NM_SETTING_CDMA_USERNAME, + "foobar@vzw.com", + NULL); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_no_error(error); + g_assert(success); + g_object_unref(connection); +} + +static void +test_connection_bad_base_types(void) +{ + NMConnection *connection; + NMSetting * setting; + gboolean success; + GError * error = NULL; + + /* Test various non-base connection types to make sure they are rejected; + * using a fake 'wired' connection so the rest of it verifies + */ + + /* Connection setting */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_CONNECTION_SETTING_NAME); + setting = nm_setting_wired_new(); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "connection.type: ")); + g_assert(success == FALSE); + g_object_unref(connection); + g_clear_error(&error); + + /* PPP setting */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_PPP_SETTING_NAME); + setting = nm_setting_wired_new(); + nm_connection_add_setting(connection, setting); + setting = nm_setting_ppp_new(); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "connection.type: ")); + g_assert(success == FALSE); + g_object_unref(connection); + g_clear_error(&error); + + /* Serial setting */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_SERIAL_SETTING_NAME); + setting = nm_setting_wired_new(); + nm_connection_add_setting(connection, setting); + setting = nm_setting_serial_new(); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "connection.type: ")); + g_assert(success == FALSE); + g_object_unref(connection); + g_clear_error(&error); + + /* IP4 setting */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_IP4_CONFIG_SETTING_NAME); + setting = nm_setting_wired_new(); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "connection.type: ")); + g_assert(success == FALSE); + g_object_unref(connection); + g_clear_error(&error); + + /* IP6 setting */ + connection = nm_simple_connection_new(); + add_generic_settings(connection, NM_SETTING_IP6_CONFIG_SETTING_NAME); + setting = nm_setting_wired_new(); + nm_connection_add_setting(connection, setting); + + success = nm_connection_verify(connection, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(g_str_has_prefix(error->message, "connection.type: ")); + g_assert(success == FALSE); + g_object_unref(connection); + g_clear_error(&error); +} + +static void +test_setting_compare_id(void) +{ + gs_unref_object NMSetting *old = NULL, *new = NULL; + gboolean success; + + old = nm_setting_connection_new(); + g_object_set(old, + NM_SETTING_CONNECTION_ID, + "really awesome cool connection", + NM_SETTING_CONNECTION_UUID, + "fbbd59d5-acab-4e30-8f86-258d272617e7", + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NULL); + + new = nm_setting_duplicate(old); + g_object_set(new, NM_SETTING_CONNECTION_ID, "some different connection id", NULL); + + /* First make sure they are different */ + success = nm_setting_compare(old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert(success == FALSE); + + success = nm_setting_compare(old, new, NM_SETTING_COMPARE_FLAG_IGNORE_ID); + g_assert(success); +} + +static void +test_setting_compare_addresses(void) +{ + gs_unref_object NMSetting *s1 = NULL, *s2 = NULL; + gboolean success; + NMIPAddress * a; + GHashTable * result = NULL; + + s1 = nm_setting_ip4_config_new(); + s2 = nm_setting_ip4_config_new(); + + a = nm_ip_address_new(AF_INET, "192.168.7.5", 24, NULL); + + nm_ip_address_set_attribute(a, NM_IP_ADDRESS_ATTRIBUTE_LABEL, g_variant_new_string("xoxoxo")); + nm_setting_ip_config_add_address((NMSettingIPConfig *) s1, a); + + nm_ip_address_set_attribute(a, NM_IP_ADDRESS_ATTRIBUTE_LABEL, g_variant_new_string("hello")); + nm_setting_ip_config_add_address((NMSettingIPConfig *) s2, a); + + nm_ip_address_unref(a); + + if (nmtst_get_rand_uint32() % 2) + NM_SWAP(&s1, &s2); + + success = nm_setting_compare(s1, s2, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert(!success); + + success = nm_setting_diff(s1, s2, NM_SETTING_COMPARE_FLAG_EXACT, FALSE, &result); + g_assert(!success); + nm_clear_pointer(&result, g_hash_table_unref); +} + +static void +test_setting_compare_routes(void) +{ + gs_unref_object NMSetting *s1 = NULL, *s2 = NULL; + gboolean success; + NMIPRoute * r; + GHashTable * result = NULL; + + s1 = nm_setting_ip4_config_new(); + s2 = nm_setting_ip4_config_new(); + + r = nm_ip_route_new(AF_INET, "192.168.12.0", 24, "192.168.11.1", 473, NULL); + + nm_ip_route_set_attribute(r, NM_IP_ADDRESS_ATTRIBUTE_LABEL, g_variant_new_string("xoxoxo")); + nm_setting_ip_config_add_route((NMSettingIPConfig *) s1, r); + + nm_ip_route_set_attribute(r, NM_IP_ADDRESS_ATTRIBUTE_LABEL, g_variant_new_string("hello")); + nm_setting_ip_config_add_route((NMSettingIPConfig *) s2, r); + + nm_ip_route_unref(r); + + if (nmtst_get_rand_uint32() % 2) + NM_SWAP(&s1, &s2); + + success = nm_setting_compare(s1, s2, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert(!success); + + success = nm_setting_diff(s1, s2, NM_SETTING_COMPARE_FLAG_EXACT, FALSE, &result); + g_assert(!success); + nm_clear_pointer(&result, g_hash_table_unref); +} + +static void +test_setting_compare_wired_cloned_mac_address(void) +{ + gs_unref_object NMSetting *old = NULL, *new = NULL; + gboolean success; + gs_free char * str1 = NULL; + + old = nm_setting_wired_new(); + g_object_set(old, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "stable", NULL); + + g_assert_cmpstr("stable", ==, nm_setting_wired_get_cloned_mac_address((NMSettingWired *) old)); + g_object_get(old, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, &str1, NULL); + g_assert_cmpstr("stable", ==, str1); + nm_clear_g_free(&str1); + + new = nm_setting_duplicate(old); + g_object_set(new, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "11:22:33:44:55:66", NULL); + + g_assert_cmpstr("11:22:33:44:55:66", + ==, + nm_setting_wired_get_cloned_mac_address((NMSettingWired *) new)); + g_object_get(new, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, &str1, NULL); + g_assert_cmpstr("11:22:33:44:55:66", ==, str1); + nm_clear_g_free(&str1); + + success = nm_setting_compare(old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert(!success); + g_clear_object(&new); + + new = nm_setting_duplicate(old); + g_object_set(new, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "stable-bia", NULL); + + g_assert_cmpstr("stable-bia", + ==, + nm_setting_wired_get_cloned_mac_address((NMSettingWired *) new)); + g_object_get(new, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, &str1, NULL); + g_assert_cmpstr("stable-bia", ==, str1); + nm_clear_g_free(&str1); + + success = nm_setting_compare(old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert(!success); + g_clear_object(&new); +} + +static void +test_setting_compare_wireless_cloned_mac_address(void) +{ + gs_unref_object NMSetting *old = NULL, *new = NULL; + gboolean success; + gs_free char * str1 = NULL; + + old = nm_setting_wireless_new(); + g_object_set(old, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "stable", NULL); + + g_assert_cmpstr("stable", + ==, + nm_setting_wireless_get_cloned_mac_address((NMSettingWireless *) old)); + g_object_get(old, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, &str1, NULL); + g_assert_cmpstr("stable", ==, str1); + nm_clear_g_free(&str1); + + new = nm_setting_duplicate(old); + g_object_set(new, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "11:22:33:44:55:66", NULL); + + g_assert_cmpstr("11:22:33:44:55:66", + ==, + nm_setting_wireless_get_cloned_mac_address((NMSettingWireless *) new)); + g_object_get(new, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, &str1, NULL); + g_assert_cmpstr("11:22:33:44:55:66", ==, str1); + nm_clear_g_free(&str1); + + success = nm_setting_compare(old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert(!success); + g_clear_object(&new); + + new = nm_setting_duplicate(old); + g_object_set(new, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "stable-bia", NULL); + + g_assert_cmpstr("stable-bia", + ==, + nm_setting_wireless_get_cloned_mac_address((NMSettingWireless *) new)); + g_object_get(new, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, &str1, NULL); + g_assert_cmpstr("stable-bia", ==, str1); + nm_clear_g_free(&str1); + + success = nm_setting_compare(old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert(!success); + g_clear_object(&new); +} + +static void +test_setting_compare_timestamp(void) +{ + gs_unref_object NMSetting *old = NULL, *new = NULL; + gboolean success; + + old = nm_setting_connection_new(); + g_object_set(old, + NM_SETTING_CONNECTION_ID, + "ignore timestamp connection", + NM_SETTING_CONNECTION_UUID, + "b047a198-0e0a-4f0e-a653-eea09bb35e40", + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_TIMESTAMP, + (guint64) 1234567890, + NULL); + + new = nm_setting_duplicate(old); + g_object_set(new, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 1416316539, NULL); + + /* First make sure they are different */ + success = nm_setting_compare(old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert(success == FALSE); + + success = nm_setting_compare(old, new, NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP); + g_assert(success); +} + +typedef struct { + NMSettingSecretFlags secret_flags; + NMSettingCompareFlags comp_flags; + gboolean remove_secret; +} TestDataCompareSecrets; + +static TestDataCompareSecrets * +test_data_compare_secrets_new(NMSettingSecretFlags secret_flags, + NMSettingCompareFlags comp_flags, + gboolean remove_secret) +{ + TestDataCompareSecrets *data = g_new0(TestDataCompareSecrets, 1); + + data->secret_flags = secret_flags; + data->comp_flags = comp_flags; + data->remove_secret = remove_secret; + return data; +} + +static void +_test_compare_secrets_check_diff(NMSetting * a, + NMSetting * b, + NMSettingCompareFlags flags, + gboolean exp_same_psk, + gboolean exp_same_psk_flags) +{ + gs_unref_hashtable GHashTable *h = NULL; + NMSettingDiffResult _RESULT_IN_A = NM_SETTING_DIFF_RESULT_IN_A; + NMSettingDiffResult _RESULT_IN_B = NM_SETTING_DIFF_RESULT_IN_B; + gboolean invert_results; + gboolean diff_result; + NMSettingSecretFlags a_psk_flags = + nm_setting_wireless_security_get_psk_flags(NM_SETTING_WIRELESS_SECURITY(a)); + NMSettingSecretFlags b_psk_flags = + nm_setting_wireless_security_get_psk_flags(NM_SETTING_WIRELESS_SECURITY(b)); + const char *a_psk = nm_setting_wireless_security_get_psk(NM_SETTING_WIRELESS_SECURITY(a)); + const char *b_psk = nm_setting_wireless_security_get_psk(NM_SETTING_WIRELESS_SECURITY(b)); + + g_assert(NM_IS_SETTING_WIRELESS_SECURITY(a)); + g_assert(NM_IS_SETTING_WIRELESS_SECURITY(b)); + + invert_results = nmtst_get_rand_bool(); + if (invert_results) { + _RESULT_IN_A = NM_SETTING_DIFF_RESULT_IN_B; + _RESULT_IN_B = NM_SETTING_DIFF_RESULT_IN_A; + } + + diff_result = nm_setting_diff(a, b, flags, invert_results, &h); + + g_assert(exp_same_psk_flags == (a_psk_flags == b_psk_flags)); + + if (nm_streq0(a_psk, b_psk)) + g_assert(exp_same_psk); + else { + if (flags == NM_SETTING_COMPARE_FLAG_EXACT) + g_assert(!exp_same_psk); + else if (flags == NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS) { + if (!NM_FLAGS_HAS(a_psk_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED) + && !NM_FLAGS_HAS(b_psk_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED)) + g_assert(!exp_same_psk); + else if (!NM_FLAGS_HAS(a_psk_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED) + && NM_FLAGS_HAS(b_psk_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED)) + g_assert(!exp_same_psk); + else + g_assert(exp_same_psk); + } else if (flags == NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS) { + if (!NM_FLAGS_HAS(a_psk_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED) + && !NM_FLAGS_HAS(b_psk_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED)) + g_assert(!exp_same_psk); + else if (!NM_FLAGS_HAS(a_psk_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED) + && NM_FLAGS_HAS(b_psk_flags, NM_SETTING_SECRET_FLAG_NOT_SAVED)) + g_assert(!exp_same_psk); + else + g_assert(exp_same_psk); + } else if (flags == NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS) + g_assert(exp_same_psk); + else + g_assert_not_reached(); + } + + g_assert(diff_result == (exp_same_psk && exp_same_psk_flags)); + g_assert(diff_result == (!h)); + + if (!diff_result) { + if (flags == NM_SETTING_COMPARE_FLAG_EXACT) + g_assert(!exp_same_psk); + else if (NM_IN_SET(flags, + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS) + && (a_psk_flags != b_psk_flags) + && nm_setting_wireless_security_get_psk_flags(NM_SETTING_WIRELESS_SECURITY(a)) + == NM_SETTING_SECRET_FLAG_NONE) + g_assert(!exp_same_psk); + else + g_assert(exp_same_psk); + + g_assert((!exp_same_psk) == g_hash_table_contains(h, NM_SETTING_WIRELESS_SECURITY_PSK)); + if (!exp_same_psk) { + if (nm_setting_wireless_security_get_psk(NM_SETTING_WIRELESS_SECURITY(a))) + g_assert_cmpint( + GPOINTER_TO_UINT(g_hash_table_lookup(h, NM_SETTING_WIRELESS_SECURITY_PSK)), + ==, + _RESULT_IN_A); + else + g_assert_cmpint( + GPOINTER_TO_UINT(g_hash_table_lookup(h, NM_SETTING_WIRELESS_SECURITY_PSK)), + ==, + _RESULT_IN_B); + } + + g_assert((!exp_same_psk_flags) + == g_hash_table_contains(h, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS)); + if (!exp_same_psk_flags) { + if (nm_setting_wireless_security_get_psk_flags(NM_SETTING_WIRELESS_SECURITY(a)) + != NM_SETTING_SECRET_FLAG_NONE) + g_assert_cmpint(GPOINTER_TO_UINT( + g_hash_table_lookup(h, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS)), + ==, + _RESULT_IN_A); + else + g_assert_cmpint(GPOINTER_TO_UINT( + g_hash_table_lookup(h, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS)), + ==, + _RESULT_IN_B); + } + + g_assert_cmpint(g_hash_table_size(h), ==, (!exp_same_psk) + (!exp_same_psk_flags)); + } + + g_assert(diff_result == nm_setting_compare(a, b, flags)); + g_assert(diff_result == nm_setting_compare(b, a, flags)); +} + +static void +test_setting_compare_secrets(gconstpointer test_data) +{ + const TestDataCompareSecrets *data = test_data; + gs_unref_object NMConnection *conn_old = NULL; + gs_unref_object NMConnection *conn_new = NULL; + gs_unref_object NMSetting *old = NULL; + gs_unref_object NMSetting *new = NULL; + + /* Make sure that a connection with transient/unsaved secrets compares + * successfully to the same connection without those secrets. + */ + + old = nm_setting_wireless_security_new(); + g_object_set(old, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_PSK, + "really cool psk", + NULL); + nm_setting_set_secret_flags(old, NM_SETTING_WIRELESS_SECURITY_PSK, data->secret_flags, NULL); + + new = nm_setting_duplicate(old); + if (data->remove_secret) + g_object_set(new, NM_SETTING_WIRELESS_SECURITY_PSK, NULL, NULL); + + g_assert((!data->remove_secret) == nm_setting_compare(old, new, NM_SETTING_COMPARE_FLAG_EXACT)); + g_assert((!data->remove_secret) == nm_setting_compare(new, old, NM_SETTING_COMPARE_FLAG_EXACT)); + + _test_compare_secrets_check_diff(old, + new, + NM_SETTING_COMPARE_FLAG_EXACT, + !data->remove_secret, + TRUE); + _test_compare_secrets_check_diff(new, + old, + NM_SETTING_COMPARE_FLAG_EXACT, + !data->remove_secret, + TRUE); + + g_assert(nm_setting_compare(old, new, data->comp_flags)); + g_assert(nm_setting_compare(new, old, data->comp_flags)); + + _test_compare_secrets_check_diff(old, new, data->comp_flags, TRUE, TRUE); + _test_compare_secrets_check_diff(new, old, data->comp_flags, TRUE, TRUE); + + /* OK. Try again, but this time not only change the secret, also let the secret flags differ... */ + if (data->secret_flags != NM_SETTING_SECRET_FLAG_NONE) { + nm_setting_set_secret_flags(new, + NM_SETTING_WIRELESS_SECURITY_PSK, + NM_SETTING_SECRET_FLAG_NONE, + NULL); + + _test_compare_secrets_check_diff(old, new, NM_SETTING_COMPARE_FLAG_EXACT, FALSE, FALSE); + _test_compare_secrets_check_diff(new, old, NM_SETTING_COMPARE_FLAG_EXACT, FALSE, FALSE); + + _test_compare_secrets_check_diff(old, new, data->comp_flags, TRUE, FALSE); + _test_compare_secrets_check_diff(new, old, data->comp_flags, FALSE, FALSE); + + nm_setting_set_secret_flags(new, + NM_SETTING_WIRELESS_SECURITY_PSK, + data->secret_flags, + NULL); + } + + conn_old = nmtst_create_minimal_connection("test-compare-secrets", + NULL, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + nm_connection_add_setting(conn_old, nm_setting_duplicate(old)); + conn_new = nm_simple_connection_new_clone(conn_old); + nm_connection_add_setting(conn_new, nm_setting_duplicate(new)); + + g_assert((!data->remove_secret) + == nm_connection_compare(conn_old, conn_new, NM_SETTING_COMPARE_FLAG_EXACT)); + g_assert((!data->remove_secret) + == nm_connection_compare(conn_new, conn_old, NM_SETTING_COMPARE_FLAG_EXACT)); + + g_assert(nm_connection_compare(conn_old, conn_new, data->comp_flags)); + g_assert(nm_connection_compare(conn_new, conn_old, data->comp_flags)); +} + +static void +test_setting_compare_vpn_secrets(gconstpointer test_data) +{ + const TestDataCompareSecrets *data = test_data; + gs_unref_object NMSetting *old = NULL, *new = NULL; + gboolean success; + + /* Make sure that a connection with transient/unsaved secrets compares + * successfully to the same connection without those secrets. + */ + + old = nm_setting_vpn_new(); + nm_setting_vpn_add_secret(NM_SETTING_VPN(old), "foobarbaz", "really secret password"); + nm_setting_vpn_add_secret(NM_SETTING_VPN(old), "asdfasdfasdf", "really adfasdfasdfasdf"); + nm_setting_vpn_add_secret(NM_SETTING_VPN(old), "0123456778", "abcdefghijklmnpqrstuvqxyz"); + nm_setting_vpn_add_secret(NM_SETTING_VPN(old), + "borkbork", + "yet another really secret password"); + nm_setting_set_secret_flags(old, "borkbork", data->secret_flags, NULL); + + /* Clear "borkbork" from the duplicated setting */ + new = nm_setting_duplicate(old); + if (data->remove_secret) { + nm_setting_vpn_remove_secret(NM_SETTING_VPN(new), "borkbork"); + + /* First make sure they are different */ + success = nm_setting_compare(old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert(success == FALSE); + } + + success = nm_setting_compare(old, new, data->comp_flags); + g_assert(success); +} + +static void +test_hwaddr_aton_ether_normal(void) +{ + guint8 buf[100]; + guint8 expected[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; + + g_assert(nm_utils_hwaddr_aton("00:11:22:33:44:55", buf, ETH_ALEN) != NULL); + g_assert(memcmp(buf, expected, sizeof(expected)) == 0); +} + +static void +test_hwaddr_aton_ib_normal(void) +{ + guint8 buf[100]; + const char *source = "00:11:22:33:44:55:66:77:88:99:01:12:23:34:45:56:67:78:89:90"; + guint8 expected[INFINIBAND_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x90}; + + g_assert(nm_utils_hwaddr_aton(source, buf, INFINIBAND_ALEN) != NULL); + g_assert(memcmp(buf, expected, sizeof(expected)) == 0); +} + +static void +test_hwaddr_aton_no_leading_zeros(void) +{ + guint8 buf[100]; + guint8 expected[ETH_ALEN] = {0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05}; + + g_assert(nm_utils_hwaddr_aton("0:1a:2B:3:44:5", buf, ETH_ALEN) != NULL); + g_assert(memcmp(buf, expected, sizeof(expected)) == 0); +} + +static void +test_hwaddr_aton_malformed(void) +{ + guint8 buf[100]; + + g_assert(nm_utils_hwaddr_aton("0:1a:2B:3:a@%%", buf, ETH_ALEN) == NULL); +} + +static void +test_hwaddr_equal(void) +{ + const char * string = "00:1a:2b:03:44:05"; + const char * upper_string = "00:1A:2B:03:44:05"; + const char * bad_string = "0:1a:2b:3:44:5"; + const guint8 binary[ETH_ALEN] = {0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05}; + const char * other_string = "1a:2b:03:44:05:00"; + const guint8 other_binary[ETH_ALEN] = {0x1A, 0x2B, 0x03, 0x44, 0x05, 0x00}; + const char * long_string = "00:1a:2b:03:44:05:06:07"; + const guint8 long_binary[8] = {0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05, 0x06, 0x07}; + const char * null_string = "00:00:00:00:00:00"; + const guint8 null_binary[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + g_assert(nm_utils_hwaddr_matches(string, -1, string, -1)); + g_assert(nm_utils_hwaddr_matches(string, -1, upper_string, -1)); + g_assert(nm_utils_hwaddr_matches(string, -1, bad_string, -1)); + g_assert(nm_utils_hwaddr_matches(string, -1, binary, sizeof(binary))); + g_assert(!nm_utils_hwaddr_matches(string, -1, other_string, -1)); + g_assert(!nm_utils_hwaddr_matches(string, -1, other_binary, sizeof(other_binary))); + g_assert(!nm_utils_hwaddr_matches(string, -1, long_string, -1)); + g_assert(!nm_utils_hwaddr_matches(string, -1, long_binary, sizeof(long_binary))); + g_assert(!nm_utils_hwaddr_matches(string, -1, null_string, -1)); + g_assert(!nm_utils_hwaddr_matches(string, -1, null_binary, sizeof(null_binary))); + g_assert(!nm_utils_hwaddr_matches(string, -1, NULL, ETH_ALEN)); + + g_assert(nm_utils_hwaddr_matches(binary, sizeof(binary), string, -1)); + g_assert(nm_utils_hwaddr_matches(binary, sizeof(binary), upper_string, -1)); + g_assert(nm_utils_hwaddr_matches(binary, sizeof(binary), bad_string, -1)); + g_assert(nm_utils_hwaddr_matches(binary, sizeof(binary), binary, sizeof(binary))); + g_assert(!nm_utils_hwaddr_matches(binary, sizeof(binary), other_string, -1)); + g_assert(!nm_utils_hwaddr_matches(binary, sizeof(binary), other_binary, sizeof(other_binary))); + g_assert(!nm_utils_hwaddr_matches(binary, sizeof(binary), long_string, -1)); + g_assert(!nm_utils_hwaddr_matches(binary, sizeof(binary), long_binary, sizeof(long_binary))); + g_assert(!nm_utils_hwaddr_matches(binary, sizeof(binary), null_string, -1)); + g_assert(!nm_utils_hwaddr_matches(binary, sizeof(binary), null_binary, sizeof(null_binary))); + g_assert(!nm_utils_hwaddr_matches(binary, sizeof(binary), NULL, ETH_ALEN)); + + g_assert(!nm_utils_hwaddr_matches(null_string, -1, string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_string, -1, upper_string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_string, -1, bad_string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_string, -1, binary, sizeof(binary))); + g_assert(!nm_utils_hwaddr_matches(null_string, -1, other_string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_string, -1, other_binary, sizeof(other_binary))); + g_assert(!nm_utils_hwaddr_matches(null_string, -1, long_string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_string, -1, long_binary, sizeof(long_binary))); + g_assert(nm_utils_hwaddr_matches(null_string, -1, null_string, -1)); + g_assert(nm_utils_hwaddr_matches(null_string, -1, null_binary, sizeof(null_binary))); + g_assert(nm_utils_hwaddr_matches(null_string, -1, NULL, ETH_ALEN)); + + g_assert(!nm_utils_hwaddr_matches(null_binary, sizeof(null_binary), string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_binary, sizeof(null_binary), upper_string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_binary, sizeof(null_binary), bad_string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_binary, sizeof(null_binary), binary, sizeof(binary))); + g_assert(!nm_utils_hwaddr_matches(null_binary, sizeof(null_binary), other_string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_binary, + sizeof(null_binary), + other_binary, + sizeof(other_binary))); + g_assert(!nm_utils_hwaddr_matches(null_binary, sizeof(null_binary), long_string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_binary, + sizeof(null_binary), + long_binary, + sizeof(long_binary))); + g_assert(nm_utils_hwaddr_matches(null_binary, sizeof(null_binary), null_string, -1)); + g_assert(nm_utils_hwaddr_matches(null_binary, + sizeof(null_binary), + null_binary, + sizeof(null_binary))); + g_assert(nm_utils_hwaddr_matches(null_binary, sizeof(null_binary), NULL, ETH_ALEN)); + + g_assert(!nm_utils_hwaddr_matches(NULL, -1, NULL, -1)); + g_assert(!nm_utils_hwaddr_matches(NULL, -1, string, -1)); + g_assert(!nm_utils_hwaddr_matches(string, -1, NULL, -1)); + g_assert(!nm_utils_hwaddr_matches(NULL, -1, null_string, -1)); + g_assert(!nm_utils_hwaddr_matches(null_string, -1, NULL, -1)); + g_assert(!nm_utils_hwaddr_matches(NULL, -1, binary, sizeof(binary))); + g_assert(!nm_utils_hwaddr_matches(binary, sizeof(binary), NULL, -1)); + g_assert(!nm_utils_hwaddr_matches(NULL, -1, null_binary, sizeof(null_binary))); + g_assert(!nm_utils_hwaddr_matches(null_binary, sizeof(null_binary), NULL, -1)); +} + +static void +test_hwaddr_canonical(void) +{ + const char *string = "00:1A:2B:03:44:05"; + const char *lower_string = "00:1a:2b:03:44:05"; + const char *short_string = "0:1a:2b:3:44:5"; + const char *hyphen_string = "00-1a-2b-03-44-05"; + const char *invalid_string = "00:1A:2B"; + char * canonical; + + canonical = nm_utils_hwaddr_canonical(string, ETH_ALEN); + g_assert_cmpstr(canonical, ==, string); + g_free(canonical); + + canonical = nm_utils_hwaddr_canonical(lower_string, ETH_ALEN); + g_assert_cmpstr(canonical, ==, string); + g_free(canonical); + + canonical = nm_utils_hwaddr_canonical(short_string, ETH_ALEN); + g_assert_cmpstr(canonical, ==, string); + g_free(canonical); + + canonical = nm_utils_hwaddr_canonical(hyphen_string, ETH_ALEN); + g_assert_cmpstr(canonical, ==, string); + g_free(canonical); + + canonical = nm_utils_hwaddr_canonical(invalid_string, ETH_ALEN); + g_assert_cmpstr(canonical, ==, NULL); + + canonical = nm_utils_hwaddr_canonical(invalid_string, -1); + g_assert_cmpstr(canonical, ==, invalid_string); + g_free(canonical); +} + +static void +test_connection_changed_cb(NMConnection *connection, gboolean *data) +{ + *data = TRUE; +} + +static guint32 +_netmask_to_prefix(guint32 netmask) +{ + guint32 prefix; + guint8 v; + const guint8 *p = (guint8 *) &netmask; + + if (p[3]) { + prefix = 24; + v = p[3]; + } else if (p[2]) { + prefix = 16; + v = p[2]; + } else if (p[1]) { + prefix = 8; + v = p[1]; + } else { + prefix = 0; + v = p[0]; + } + + while (v) { + prefix++; + v <<= 1; + } + + g_assert_cmpint(prefix, <=, 32); + + /* we re-implemented the netmask-to-prefix code differently. Check + * that they agree. */ + g_assert_cmpint(prefix, ==, nm_utils_ip4_netmask_to_prefix(netmask)); + + return prefix; +} + +static void +test_ip4_prefix_to_netmask(void) +{ + int i; + + for (i = 0; i <= 32; i++) { + guint32 netmask = _nm_utils_ip4_prefix_to_netmask(i); + int plen = _netmask_to_prefix(netmask); + + g_assert_cmpint(i, ==, plen); + { + guint32 msk = 0x80000000; + guint32 netmask2 = 0; + guint32 prefix = i; + while (prefix > 0) { + netmask2 |= msk; + msk >>= 1; + prefix--; + } + g_assert_cmpint(netmask, ==, (guint32) htonl(netmask2)); + } + } +} + +static void +test_ip4_netmask_to_prefix(void) +{ + int i, j; + + GRand *rand = g_rand_new(); + + g_rand_set_seed(rand, 1); + + for (i = 2; i <= 32; i++) { + guint32 netmask = _nm_utils_ip4_prefix_to_netmask(i); + guint32 netmask_lowest_bit = netmask & ~_nm_utils_ip4_prefix_to_netmask(i - 1); + + g_assert_cmpint(i, ==, _netmask_to_prefix(netmask)); + + for (j = 0; j < 2 * i; j++) { + guint32 r = g_rand_int(rand); + guint32 netmask_holey; + guint32 prefix_holey; + + netmask_holey = (netmask & r) | netmask_lowest_bit; + + if (netmask_holey == netmask) + continue; + + /* create an invalid netmask with holes and check that the function + * returns the longest prefix. */ + prefix_holey = _netmask_to_prefix(netmask_holey); + + g_assert_cmpint(i, ==, prefix_holey); + } + } + + g_rand_free(rand); +} + +#define ASSERT_CHANGED(statement) \ + G_STMT_START \ + { \ + changed = FALSE; \ + statement; \ + g_assert(changed); \ + } \ + G_STMT_END + +#define ASSERT_UNCHANGED(statement) \ + G_STMT_START \ + { \ + changed = FALSE; \ + statement; \ + g_assert(!changed); \ + } \ + G_STMT_END + +static void +test_connection_changed_signal(void) +{ + NMConnection *connection; + gboolean changed = FALSE; + + connection = new_test_connection(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + /* Add new setting */ + ASSERT_CHANGED(nm_connection_add_setting(connection, nm_setting_vlan_new())); + + /* Remove existing setting */ + ASSERT_CHANGED(nm_connection_remove_setting(connection, NM_TYPE_SETTING_VLAN)); + + /* Remove non-existing setting */ + ASSERT_UNCHANGED(nm_connection_remove_setting(connection, NM_TYPE_SETTING_VLAN)); + + g_object_unref(connection); +} + +static void +test_setting_connection_changed_signal(void) +{ + NMConnection * connection; + gboolean changed = FALSE; + NMSettingConnection *s_con; + gs_free char * uuid = NULL; + + connection = nm_simple_connection_new(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + ASSERT_CHANGED(g_object_set(s_con, NM_SETTING_CONNECTION_ID, "adfadfasdfaf", NULL)); + + ASSERT_CHANGED(nm_setting_connection_add_permission(s_con, "user", "billsmith", NULL)); + ASSERT_CHANGED(nm_setting_connection_remove_permission(s_con, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx < nm_g_array_len(priv->permissions))); + ASSERT_UNCHANGED(nm_setting_connection_remove_permission(s_con, 1)); + g_test_assert_expected_messages(); + + uuid = nm_utils_uuid_generate(); + ASSERT_CHANGED(nm_setting_connection_add_secondary(s_con, uuid)); + ASSERT_CHANGED(nm_setting_connection_remove_secondary(s_con, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(elt != NULL)); + ASSERT_UNCHANGED(nm_setting_connection_remove_secondary(s_con, 1)); + g_test_assert_expected_messages(); + + g_object_unref(connection); +} + +static void +test_setting_bond_changed_signal(void) +{ + NMConnection * connection; + gboolean changed = FALSE; + NMSettingBond *s_bond; + + connection = nm_simple_connection_new(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_bond = (NMSettingBond *) nm_setting_bond_new(); + nm_connection_add_setting(connection, NM_SETTING(s_bond)); + + ASSERT_CHANGED(nm_setting_bond_add_option(s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY, "10")); + ASSERT_CHANGED(nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY)); + ASSERT_UNCHANGED(nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_UPDELAY)); + + g_object_unref(connection); +} + +static void +test_setting_ip4_changed_signal(void) +{ + NMConnection * connection; + gboolean changed = FALSE; + NMSettingIPConfig *s_ip4; + NMIPAddress * addr; + NMIPRoute * route; + GError * error = NULL; + + connection = nm_simple_connection_new(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + ASSERT_CHANGED(nm_setting_ip_config_add_dns(s_ip4, "11.22.0.0")); + ASSERT_CHANGED(nm_setting_ip_config_remove_dns(s_ip4, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->dns->len)); + ASSERT_UNCHANGED(nm_setting_ip_config_remove_dns(s_ip4, 1)); + g_test_assert_expected_messages(); + + nm_setting_ip_config_add_dns(s_ip4, "33.44.0.0"); + ASSERT_CHANGED(nm_setting_ip_config_clear_dns(s_ip4)); + + ASSERT_CHANGED(nm_setting_ip_config_add_dns_search(s_ip4, "foobar.com")); + ASSERT_CHANGED(nm_setting_ip_config_remove_dns_search(s_ip4, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->dns_search->len)); + ASSERT_UNCHANGED(nm_setting_ip_config_remove_dns_search(s_ip4, 1)); + g_test_assert_expected_messages(); + + ASSERT_CHANGED(nm_setting_ip_config_add_dns_search(s_ip4, "foobar.com")); + ASSERT_CHANGED(nm_setting_ip_config_clear_dns_searches(s_ip4)); + + addr = nm_ip_address_new(AF_INET, "22.33.0.0", 24, &error); + g_assert_no_error(error); + ASSERT_CHANGED(nm_setting_ip_config_add_address(s_ip4, addr)); + ASSERT_CHANGED(nm_setting_ip_config_remove_address(s_ip4, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->addresses->len)); + ASSERT_UNCHANGED(nm_setting_ip_config_remove_address(s_ip4, 1)); + g_test_assert_expected_messages(); + + nm_setting_ip_config_add_address(s_ip4, addr); + ASSERT_CHANGED(nm_setting_ip_config_clear_addresses(s_ip4)); + + route = nm_ip_route_new(AF_INET, "22.33.0.0", 24, NULL, 0, &error); + g_assert_no_error(error); + + ASSERT_CHANGED(nm_setting_ip_config_add_route(s_ip4, route)); + ASSERT_CHANGED(nm_setting_ip_config_remove_route(s_ip4, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->routes->len)); + ASSERT_UNCHANGED(nm_setting_ip_config_remove_route(s_ip4, 1)); + g_test_assert_expected_messages(); + + nm_setting_ip_config_add_route(s_ip4, route); + ASSERT_CHANGED(nm_setting_ip_config_clear_routes(s_ip4)); + + ASSERT_CHANGED(nm_setting_ip_config_add_dns_option(s_ip4, "debug")); + ASSERT_CHANGED(nm_setting_ip_config_remove_dns_option(s_ip4, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->dns_options->len)); + ASSERT_UNCHANGED(nm_setting_ip_config_remove_dns_option(s_ip4, 1)); + g_test_assert_expected_messages(); + + nm_ip_address_unref(addr); + nm_ip_route_unref(route); + g_object_unref(connection); +} + +static void +test_setting_ip6_changed_signal(void) +{ + NMConnection * connection; + gboolean changed = FALSE; + NMSettingIPConfig *s_ip6; + NMIPAddress * addr; + NMIPRoute * route; + GError * error = NULL; + + connection = nm_simple_connection_new(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + ASSERT_CHANGED(nm_setting_ip_config_add_dns(s_ip6, "1:2:3::4:5:6")); + ASSERT_CHANGED(nm_setting_ip_config_remove_dns(s_ip6, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->dns->len)); + ASSERT_UNCHANGED(nm_setting_ip_config_remove_dns(s_ip6, 1)); + g_test_assert_expected_messages(); + + nm_setting_ip_config_add_dns(s_ip6, "1:2:3::4:5:6"); + ASSERT_CHANGED(nm_setting_ip_config_clear_dns(s_ip6)); + + ASSERT_CHANGED(nm_setting_ip_config_add_dns_search(s_ip6, "foobar.com")); + ASSERT_CHANGED(nm_setting_ip_config_remove_dns_search(s_ip6, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->dns_search->len)); + ASSERT_UNCHANGED(nm_setting_ip_config_remove_dns_search(s_ip6, 1)); + g_test_assert_expected_messages(); + + nm_setting_ip_config_add_dns_search(s_ip6, "foobar.com"); + ASSERT_CHANGED(nm_setting_ip_config_clear_dns_searches(s_ip6)); + + addr = nm_ip_address_new(AF_INET6, "1:2:3::4:5:6", 64, &error); + g_assert_no_error(error); + + ASSERT_CHANGED(nm_setting_ip_config_add_address(s_ip6, addr)); + ASSERT_CHANGED(nm_setting_ip_config_remove_address(s_ip6, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->addresses->len)); + ASSERT_UNCHANGED(nm_setting_ip_config_remove_address(s_ip6, 1)); + g_test_assert_expected_messages(); + + nm_setting_ip_config_add_address(s_ip6, addr); + ASSERT_CHANGED(nm_setting_ip_config_clear_addresses(s_ip6)); + + route = nm_ip_route_new(AF_INET6, "1:2:3::4:5:6", 128, NULL, 0, &error); + g_assert_no_error(error); + + ASSERT_CHANGED(nm_setting_ip_config_add_route(s_ip6, route)); + ASSERT_CHANGED(nm_setting_ip_config_remove_route(s_ip6, 0)); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->routes->len)); + ASSERT_UNCHANGED(nm_setting_ip_config_remove_route(s_ip6, 1)); + g_test_assert_expected_messages(); + + nm_setting_ip_config_add_route(s_ip6, route); + ASSERT_CHANGED(nm_setting_ip_config_clear_routes(s_ip6)); + + nm_ip_address_unref(addr); + nm_ip_route_unref(route); + g_object_unref(connection); +} + +static void +test_setting_vlan_changed_signal(void) +{ + NMConnection * connection; + gboolean changed = FALSE; + NMSettingVlan *s_vlan; + + connection = nm_simple_connection_new(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_vlan = (NMSettingVlan *) nm_setting_vlan_new(); + nm_connection_add_setting(connection, NM_SETTING(s_vlan)); + + ASSERT_CHANGED(nm_setting_vlan_add_priority(s_vlan, NM_VLAN_INGRESS_MAP, 1, 3)); + ASSERT_CHANGED(nm_setting_vlan_remove_priority(s_vlan, NM_VLAN_INGRESS_MAP, 0)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx < g_slist_length(list))); + ASSERT_UNCHANGED(nm_setting_vlan_remove_priority(s_vlan, NM_VLAN_INGRESS_MAP, 1)); + g_test_assert_expected_messages(); + ASSERT_CHANGED(nm_setting_vlan_add_priority_str(s_vlan, NM_VLAN_INGRESS_MAP, "1:3")); + ASSERT_CHANGED(nm_setting_vlan_clear_priorities(s_vlan, NM_VLAN_INGRESS_MAP)); + + ASSERT_CHANGED(nm_setting_vlan_add_priority(s_vlan, NM_VLAN_EGRESS_MAP, 1, 3)); + ASSERT_CHANGED(nm_setting_vlan_remove_priority(s_vlan, NM_VLAN_EGRESS_MAP, 0)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx < g_slist_length(list))); + ASSERT_UNCHANGED(nm_setting_vlan_remove_priority(s_vlan, NM_VLAN_EGRESS_MAP, 1)); + g_test_assert_expected_messages(); + ASSERT_CHANGED(nm_setting_vlan_add_priority_str(s_vlan, NM_VLAN_EGRESS_MAP, "1:3")); + ASSERT_CHANGED(nm_setting_vlan_clear_priorities(s_vlan, NM_VLAN_EGRESS_MAP)); + + g_object_unref(connection); +} + +static void +test_setting_vpn_changed_signal(void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingVpn *s_vpn; + + connection = nm_simple_connection_new(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_vpn = (NMSettingVpn *) nm_setting_vpn_new(); + nm_connection_add_setting(connection, NM_SETTING(s_vpn)); + + ASSERT_CHANGED(nm_setting_vpn_add_data_item(s_vpn, "foobar", "baz")); + ASSERT_CHANGED(nm_setting_vpn_remove_data_item(s_vpn, "foobar")); + ASSERT_UNCHANGED(nm_setting_vpn_remove_data_item(s_vpn, "not added")); + + ASSERT_CHANGED(nm_setting_vpn_add_secret(s_vpn, "foobar", "baz")); + ASSERT_CHANGED(nm_setting_vpn_remove_secret(s_vpn, "foobar")); + ASSERT_UNCHANGED(nm_setting_vpn_remove_secret(s_vpn, "not added")); + + g_object_unref(connection); +} + +static void +test_setting_wired_changed_signal(void) +{ + NMConnection * connection; + gboolean changed = FALSE; + NMSettingWired *s_wired; + + connection = nm_simple_connection_new(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + ASSERT_CHANGED(nm_setting_wired_add_s390_option(s_wired, "portno", "1")); + ASSERT_CHANGED(nm_setting_wired_remove_s390_option(s_wired, "portno")); + ASSERT_UNCHANGED(nm_setting_wired_remove_s390_option(s_wired, "layer2")); + + g_object_unref(connection); +} + +static void +test_setting_wireless_changed_signal(void) +{ + NMConnection * connection; + gboolean changed = FALSE; + NMSettingWireless *s_wifi; + + connection = nm_simple_connection_new(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ASSERT_CHANGED(nm_setting_wireless_add_seen_bssid(s_wifi, "00:11:22:33:44:55")); + + g_object_unref(connection); +} + +static void +test_setting_wireless_security_changed_signal(void) +{ + NMConnection * connection; + gboolean changed = FALSE; + NMSettingWirelessSecurity *s_wsec; + + connection = nm_simple_connection_new(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wsec)); + + /* Protos */ + ASSERT_CHANGED(nm_setting_wireless_security_add_proto(s_wsec, "wpa")); + ASSERT_CHANGED(nm_setting_wireless_security_remove_proto(s_wsec, 0)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(elt != NULL)); + ASSERT_UNCHANGED(nm_setting_wireless_security_remove_proto(s_wsec, 1)); + g_test_assert_expected_messages(); + + nm_setting_wireless_security_add_proto(s_wsec, "wep"); + ASSERT_CHANGED(nm_setting_wireless_security_clear_protos(s_wsec)); + + /* Pairwise ciphers */ + ASSERT_CHANGED(nm_setting_wireless_security_add_pairwise(s_wsec, "tkip")); + ASSERT_CHANGED(nm_setting_wireless_security_remove_pairwise(s_wsec, 0)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(elt != NULL)); + ASSERT_UNCHANGED(nm_setting_wireless_security_remove_pairwise(s_wsec, 1)); + g_test_assert_expected_messages(); + + nm_setting_wireless_security_add_pairwise(s_wsec, "tkip"); + ASSERT_CHANGED(nm_setting_wireless_security_clear_pairwise(s_wsec)); + + /* Group ciphers */ + ASSERT_CHANGED(nm_setting_wireless_security_add_group(s_wsec, "ccmp")); + ASSERT_CHANGED(nm_setting_wireless_security_remove_group(s_wsec, 0)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(elt != NULL)); + ASSERT_UNCHANGED(nm_setting_wireless_security_remove_group(s_wsec, 1)); + g_test_assert_expected_messages(); + + nm_setting_wireless_security_add_group(s_wsec, "tkip"); + ASSERT_CHANGED(nm_setting_wireless_security_clear_groups(s_wsec)); + + /* WEP key secret flags */ + ASSERT_CHANGED(g_assert(nm_setting_set_secret_flags(NM_SETTING(s_wsec), + "wep-key0", + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NULL))); + ASSERT_CHANGED(g_assert(nm_setting_set_secret_flags(NM_SETTING(s_wsec), + "wep-key1", + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NULL))); + ASSERT_CHANGED(g_assert(nm_setting_set_secret_flags(NM_SETTING(s_wsec), + "wep-key2", + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NULL))); + ASSERT_CHANGED(g_assert(nm_setting_set_secret_flags(NM_SETTING(s_wsec), + "wep-key3", + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NULL))); + + g_object_unref(connection); +} + +static void +test_setting_802_1x_changed_signal(void) +{ + NMConnection * connection; + gboolean changed = FALSE; + NMSetting8021x *s_8021x; + + connection = nm_simple_connection_new(); + g_signal_connect(connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + /* EAP methods */ + ASSERT_CHANGED(nm_setting_802_1x_add_eap_method(s_8021x, "tls")); + ASSERT_CHANGED(nm_setting_802_1x_remove_eap_method(s_8021x, 0)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(elt != NULL)); + ASSERT_UNCHANGED(nm_setting_802_1x_remove_eap_method(s_8021x, 1)); + g_test_assert_expected_messages(); + + nm_setting_802_1x_add_eap_method(s_8021x, "ttls"); + ASSERT_CHANGED(nm_setting_802_1x_clear_eap_methods(s_8021x)); + + /* alternate subject matches */ + ASSERT_CHANGED(nm_setting_802_1x_add_altsubject_match(s_8021x, "EMAIL:server@example.com")); + ASSERT_CHANGED(nm_setting_802_1x_remove_altsubject_match(s_8021x, 0)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(elt != NULL)); + ASSERT_UNCHANGED(nm_setting_802_1x_remove_altsubject_match(s_8021x, 1)); + g_test_assert_expected_messages(); + + nm_setting_802_1x_add_altsubject_match(s_8021x, "EMAIL:server@example.com"); + ASSERT_CHANGED(nm_setting_802_1x_clear_altsubject_matches(s_8021x)); + + /* phase2 alternate subject matches */ + ASSERT_CHANGED( + nm_setting_802_1x_add_phase2_altsubject_match(s_8021x, "EMAIL:server@example.com")); + ASSERT_CHANGED(nm_setting_802_1x_remove_phase2_altsubject_match(s_8021x, 0)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(elt != NULL)); + ASSERT_UNCHANGED(nm_setting_802_1x_remove_phase2_altsubject_match(s_8021x, 1)); + g_test_assert_expected_messages(); + + nm_setting_802_1x_add_phase2_altsubject_match(s_8021x, "EMAIL:server@example.com"); + ASSERT_CHANGED(nm_setting_802_1x_clear_phase2_altsubject_matches(s_8021x)); + + g_object_unref(connection); +} + +static void +test_setting_old_uuid(void) +{ + gs_unref_object NMSetting *setting = NULL; + + /* NetworkManager-0.9.4.0 generated 40-character UUIDs with no dashes, + * like this one. Test that we maintain compatibility. */ + const char *uuid = "f43bec2cdd60e5da381ebb1eb1fa39f3cc52660c"; + + setting = nm_setting_connection_new(); + g_object_set(G_OBJECT(setting), + NM_SETTING_CONNECTION_ID, + "uuidtest", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + nmtst_assert_setting_verifies(NM_SETTING(setting)); +} + +/*****************************************************************************/ + +static void +test_connection_normalize_uuid(void) +{ + gs_unref_object NMConnection *con = NULL; + + con = nmtst_create_minimal_connection("test1", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + + nmtst_assert_connection_verifies_and_normalizable(con); + + g_object_set(nm_connection_get_setting_connection(con), NM_SETTING_CONNECTION_UUID, NULL, NULL); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); +} + +/*****************************************************************************/ + +/* + * Test normalization of interface-name + */ +static void +test_connection_normalize_virtual_iface_name(void) +{ + NMConnection * con = NULL; + NMSettingConnection *s_con; + NMSettingVlan * s_vlan; + GVariant * connection_dict, *setting_dict, *var; + GError * error = NULL; + const char * IFACE_NAME = "iface"; + const char * IFACE_VIRT = "iface-X"; + + con = nmtst_create_minimal_connection("test1", + "22001632-bbb4-4616-b277-363dce3dfb5b", + NM_SETTING_VLAN_SETTING_NAME, + &s_con); + + nm_connection_add_setting(con, + g_object_new(NM_TYPE_SETTING_IP4_CONFIG, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL)); + + nm_connection_add_setting(con, + g_object_new(NM_TYPE_SETTING_IP6_CONFIG, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL)); + + s_vlan = nm_connection_get_setting_vlan(con); + + g_object_set(G_OBJECT(s_vlan), NM_SETTING_VLAN_PARENT, "eth0", NULL); + + g_object_set(G_OBJECT(s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, IFACE_NAME, NULL); + + g_assert_cmpstr(nm_connection_get_interface_name(con), ==, IFACE_NAME); + + connection_dict = nm_connection_to_dbus(con, NM_CONNECTION_SERIALIZE_ALL); + g_object_unref(con); + + /* Serialized form should include vlan.interface-name as well. */ + setting_dict = g_variant_lookup_value(connection_dict, + NM_SETTING_VLAN_SETTING_NAME, + NM_VARIANT_TYPE_SETTING); + g_assert(setting_dict != NULL); + var = g_variant_lookup_value(setting_dict, "interface-name", NULL); + g_assert(var != NULL); + g_assert(g_variant_is_of_type(var, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr(g_variant_get_string(var, NULL), ==, IFACE_NAME); + + g_variant_unref(setting_dict); + g_variant_unref(var); + + /* If vlan.interface-name will be ignored. */ + NMTST_VARIANT_EDITOR( + connection_dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_VLAN_SETTING_NAME, + "interface-name", + "s", + ":::this-is-not-a-valid-interface-name:::");); + + con = _connection_new_from_dbus(connection_dict, &error); + nmtst_assert_success(con, error); + g_assert_cmpstr(nm_connection_get_interface_name(con), ==, IFACE_NAME); + g_clear_object(&con); + + /* If vlan.interface-name is valid, but doesn't match, it will be ignored. */ + NMTST_VARIANT_EDITOR(connection_dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_VLAN_SETTING_NAME, + "interface-name", + "s", + IFACE_VIRT);); + + con = _connection_new_from_dbus(connection_dict, &error); + g_assert_no_error(error); + + g_assert_cmpstr(nm_connection_get_interface_name(con), ==, IFACE_NAME); + s_con = nm_connection_get_setting_connection(con); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, IFACE_NAME); + g_object_unref(con); + + /* But removing connection.interface-name should result in vlan.connection-name + * being "promoted". + */ + NMTST_VARIANT_EDITOR(connection_dict, + NMTST_VARIANT_DROP_PROPERTY(NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME);); + + con = _connection_new_from_dbus(connection_dict, &error); + g_assert_no_error(error); + + g_assert_cmpstr(nm_connection_get_interface_name(con), ==, IFACE_VIRT); + s_con = nm_connection_get_setting_connection(con); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, IFACE_VIRT); + g_object_unref(con); + + g_variant_unref(connection_dict); +} + +static void +_test_connection_normalize_type_normalizable_setting( + const char *type, + void (*prepare_normalizable_fcn)(NMConnection *con)) +{ + NMSettingConnection *s_con; + NMSetting * s_base; + GType base_type; + gs_unref_object NMConnection *con = NULL; + gs_free char * id = g_strdup_printf("%s[%s]", G_STRFUNC, type); + + base_type = nm_setting_lookup_type(type); + g_assert(base_type != G_TYPE_INVALID); + g_assert(_nm_setting_type_get_base_type_priority(base_type) != NM_SETTING_PRIORITY_INVALID); + + con = nmtst_create_minimal_connection(id, NULL, NULL, &s_con); + + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + + g_object_set(s_con, NM_SETTING_CONNECTION_TYPE, type, NULL); + + if (prepare_normalizable_fcn) + prepare_normalizable_fcn(con); + + g_assert(!nm_connection_get_setting_by_name(con, type)); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING); + nmtst_connection_normalize(con); + + s_base = nm_connection_get_setting_by_name(con, type); + g_assert(s_base); + g_assert(G_OBJECT_TYPE(s_base) == base_type); +} + +static void +_test_connection_normalize_type_unnormalizable_setting(const char *type) +{ + NMSettingConnection *s_con; + GType base_type; + gs_unref_object NMConnection *con = NULL; + gs_free char * id = g_strdup_printf("%s[%s]", G_STRFUNC, type); + + base_type = nm_setting_lookup_type(type); + g_assert(base_type != G_TYPE_INVALID); + g_assert(_nm_setting_type_get_base_type_priority(base_type) != NM_SETTING_PRIORITY_INVALID); + + con = nmtst_create_minimal_connection(id, NULL, NULL, &s_con); + + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + + g_object_set(s_con, NM_SETTING_CONNECTION_TYPE, type, NULL); + + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING); +} + +static void +_test_connection_normalize_type_normalizable_type(const char *type, + NMSetting *(*add_setting_fcn)(NMConnection *con)) +{ + NMSettingConnection *s_con; + NMSetting * s_base; + GType base_type; + gs_unref_object NMConnection *con = NULL; + gs_free char * id = g_strdup_printf("%s[%s]", G_STRFUNC, type); + + base_type = nm_setting_lookup_type(type); + g_assert(base_type != G_TYPE_INVALID); + g_assert(_nm_setting_type_get_base_type_priority(base_type) != NM_SETTING_PRIORITY_INVALID); + + con = nmtst_create_minimal_connection(id, NULL, NULL, &s_con); + + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + + if (add_setting_fcn) + s_base = add_setting_fcn(con); + else { + s_base = g_object_new(base_type, NULL); + nm_connection_add_setting(con, s_base); + } + + g_assert(!nm_setting_connection_get_connection_type(s_con)); + g_assert(nm_connection_get_setting_by_name(con, type) == s_base); + + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + nmtst_connection_normalize(con); + + g_assert_cmpstr(nm_connection_get_connection_type(con), ==, type); + g_assert(nm_connection_get_setting_by_name(con, type) == s_base); +} + +static NMSetting * +_add_setting_fcn_adsl(NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new(NM_TYPE_SETTING_ADSL, + NM_SETTING_ADSL_USERNAME, + "test-user", + NM_SETTING_ADSL_PROTOCOL, + NM_SETTING_ADSL_PROTOCOL_PPPOA, + NM_SETTING_ADSL_ENCAPSULATION, + NM_SETTING_ADSL_ENCAPSULATION_VCMUX, + NULL); + + nm_connection_add_setting(con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_bluetooth(NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new(NM_TYPE_SETTING_BLUETOOTH, + NM_SETTING_BLUETOOTH_BDADDR, + "11:22:33:44:55:66", + NM_SETTING_BLUETOOTH_TYPE, + NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + + nm_connection_add_setting(con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_bond(NMConnection *con) +{ + NMSetting * setting; + NMSettingConnection *s_con; + + setting = g_object_new(NM_TYPE_SETTING_BOND, NULL); + + nm_connection_add_setting(con, setting); + + s_con = nm_connection_get_setting_connection(con); + + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "test-bond", NULL); + + return setting; +} + +static NMSetting * +_add_setting_fcn_bridge(NMConnection *con) +{ + NMSetting * setting; + NMSettingConnection *s_con; + + setting = g_object_new(NM_TYPE_SETTING_BRIDGE, NULL); + + nm_connection_add_setting(con, setting); + + s_con = nm_connection_get_setting_connection(con); + + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "test-bridge", NULL); + + return setting; +} + +static NMSetting * +_add_setting_fcn_cdma(NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new(NM_TYPE_SETTING_CDMA, NM_SETTING_CDMA_NUMBER, "test-number", NULL); + + nm_connection_add_setting(con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_infiniband(NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new(NM_TYPE_SETTING_INFINIBAND, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + "connected", + NULL); + + nm_connection_add_setting(con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_olpc_mesh(NMConnection *con) +{ + NMSetting * setting; + const char *ssid_data = "ssid-test"; + GBytes * ssid; + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + setting = g_object_new(NM_TYPE_SETTING_OLPC_MESH, + NM_SETTING_OLPC_MESH_SSID, + ssid, + NM_SETTING_OLPC_MESH_CHANNEL, + 1, + NULL); + g_bytes_unref(ssid); + + nm_connection_add_setting(con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_team(NMConnection *con) +{ + NMSetting * setting; + NMSettingConnection *s_con; + + setting = g_object_new(NM_TYPE_SETTING_TEAM, NULL); + + nm_connection_add_setting(con, setting); + + s_con = nm_connection_get_setting_connection(con); + + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "test-team", NULL); + + return setting; +} + +static NMSetting * +_add_setting_fcn_vlan(NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new(NM_TYPE_SETTING_VLAN, NM_SETTING_VLAN_PARENT, "test-parent", NULL); + + nm_connection_add_setting(con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_vpn(NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new(NM_TYPE_SETTING_VPN, + NM_SETTING_VPN_SERVICE_TYPE, + "test-vpn-service-type", + NULL); + + nm_connection_add_setting(con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_wimax(NMConnection *con) +{ + NMSetting *setting; + + setting = + g_object_new(NM_TYPE_SETTING_WIMAX, NM_SETTING_WIMAX_NETWORK_NAME, "test-network", NULL); + + nm_connection_add_setting(con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_wireless(NMConnection *con) +{ + NMSetting * setting; + const char *ssid_data = "ssid-test"; + GBytes * ssid; + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + setting = g_object_new(NM_TYPE_SETTING_WIRELESS, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_bytes_unref(ssid); + + nm_connection_add_setting(con, setting); + return setting; +} + +static void +_prepare_normalizable_fcn_vlan(NMConnection *con) +{ + nm_connection_add_setting(con, + g_object_new(NM_TYPE_SETTING_WIRED, + NM_SETTING_WIRED_MAC_ADDRESS, + "11:22:33:44:55:66", + NULL)); +} + +static void +test_connection_normalize_type(void) +{ + guint i; + struct { + const char *type; + gboolean normalizable; + NMSetting *(*add_setting_fcn)(NMConnection *con); + void (*prepare_normalizable_fcn)(NMConnection *con); + } types[] = { + {NM_SETTING_GENERIC_SETTING_NAME, TRUE}, + {NM_SETTING_GSM_SETTING_NAME, TRUE}, + {NM_SETTING_WIRED_SETTING_NAME, TRUE}, + {NM_SETTING_VLAN_SETTING_NAME, TRUE, _add_setting_fcn_vlan, _prepare_normalizable_fcn_vlan}, + + {NM_SETTING_ADSL_SETTING_NAME, FALSE, _add_setting_fcn_adsl}, + {NM_SETTING_BLUETOOTH_SETTING_NAME, FALSE, _add_setting_fcn_bluetooth}, + {NM_SETTING_BOND_SETTING_NAME, FALSE, _add_setting_fcn_bond}, + {NM_SETTING_BRIDGE_SETTING_NAME, FALSE, _add_setting_fcn_bridge}, + {NM_SETTING_CDMA_SETTING_NAME, FALSE, _add_setting_fcn_cdma}, + {NM_SETTING_INFINIBAND_SETTING_NAME, FALSE, _add_setting_fcn_infiniband}, + {NM_SETTING_OLPC_MESH_SETTING_NAME, FALSE, _add_setting_fcn_olpc_mesh}, + {NM_SETTING_TEAM_SETTING_NAME, FALSE, _add_setting_fcn_team}, + {NM_SETTING_VLAN_SETTING_NAME, FALSE, _add_setting_fcn_vlan}, + {NM_SETTING_VPN_SETTING_NAME, FALSE, _add_setting_fcn_vpn}, + {NM_SETTING_WIMAX_SETTING_NAME, FALSE, _add_setting_fcn_wimax}, + {NM_SETTING_WIRELESS_SETTING_NAME, FALSE, _add_setting_fcn_wireless}, + {0}, + }; + + for (i = 0; types[i].type; i++) { + const char *type = types[i].type; + + if (types[i].normalizable) + _test_connection_normalize_type_normalizable_setting(type, + types[i].prepare_normalizable_fcn); + else + _test_connection_normalize_type_unnormalizable_setting(type); + _test_connection_normalize_type_normalizable_type(type, types[i].add_setting_fcn); + } +} + +static void +test_connection_normalize_slave_type_1(void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingConnection * s_con; + + con = nmtst_create_minimal_connection("test_connection_normalize_slave_type_1", + "cc4cd5df-45dc-483e-b291-6b76c2338ecb", + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + "invalid-type", + NULL); + + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(!nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + + g_object_set(s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, "bridge", NULL); + + g_assert(!nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING); + nmtst_connection_normalize(con); + g_assert(nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_BRIDGE_SETTING_NAME); +} + +static void +test_connection_normalize_slave_type_2(void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingConnection * s_con; + + con = nmtst_create_minimal_connection("test_connection_normalize_slave_type_2", + "40bea008-ca72-439a-946b-e65f827656f9", + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + "invalid-type", + NULL); + + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(!nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + + g_object_set(s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, NULL, NULL); + nm_connection_add_setting(con, nm_setting_bridge_port_new()); + + g_assert(nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NULL); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + nmtst_connection_normalize(con); + g_assert(nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_BRIDGE_SETTING_NAME); +} + +static void +test_connection_normalize_infiniband_mtu(void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingInfiniband * s_infini; + guint mtu_regular = nmtst_rand_select(2044, 2045, 65520); + + con = nmtst_create_minimal_connection("test_connection_normalize_infiniband_mtu", + NULL, + NM_SETTING_INFINIBAND_SETTING_NAME, + NULL); + + s_infini = nm_connection_get_setting_infiniband(con); + g_object_set(s_infini, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", NULL); + nmtst_assert_connection_verifies_and_normalizable(con); + + g_object_set(s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + "datagram", + NM_SETTING_INFINIBAND_MTU, + (guint) mtu_regular, + NULL); + nmtst_assert_connection_verifies_and_normalizable(con); + nmtst_connection_normalize(con); + g_assert_cmpint(mtu_regular, ==, nm_setting_infiniband_get_mtu(s_infini)); + + g_object_set(s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + "datagram", + NM_SETTING_INFINIBAND_MTU, + (guint) 65521, + NULL); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + nmtst_connection_normalize(con); + g_assert_cmpint(65520, ==, nm_setting_infiniband_get_mtu(s_infini)); + + g_object_set(s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + "connected", + NM_SETTING_INFINIBAND_MTU, + (guint) mtu_regular, + NULL); + nmtst_assert_connection_verifies_without_normalization(con); + g_assert_cmpint(mtu_regular, ==, nm_setting_infiniband_get_mtu(s_infini)); + + g_object_set(s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + "connected", + NM_SETTING_INFINIBAND_MTU, + (guint) 65521, + NULL); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + nmtst_connection_normalize(con); + g_assert_cmpint(65520, ==, nm_setting_infiniband_get_mtu(s_infini)); +} + +static void +test_connection_normalize_gateway_never_default(void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingIPConfig * s_ip4, *s_ip6; + NMIPAddress * addr; + gs_free_error GError *error = NULL; + + con = nmtst_create_minimal_connection("test1", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nmtst_assert_connection_verifies_and_normalizable(con); + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(G_OBJECT(s_ip4), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + addr = nm_ip_address_new(AF_INET, "1.1.1.1", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.254", + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, + FALSE, + NULL); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + + nm_connection_add_setting(con, (NMSetting *) s_ip4); + nm_connection_add_setting(con, (NMSetting *) s_ip6); + nm_connection_add_setting(con, nm_setting_proxy_new()); + + nmtst_assert_connection_verifies_without_normalization(con); + g_assert_cmpstr("1.1.1.254", ==, nm_setting_ip_config_get_gateway(s_ip4)); + + /* Now set never-default to TRUE and check that the gateway is + * removed during normalization + * */ + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_NEVER_DEFAULT, TRUE, NULL); + + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + nmtst_connection_normalize(con); + g_assert_cmpstr(NULL, ==, nm_setting_ip_config_get_gateway(s_ip4)); +} + +static void +test_connection_normalize_may_fail(void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingIPConfig * s_ip4, *s_ip6; + + con = nmtst_create_minimal_connection("test2", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nmtst_assert_connection_verifies_and_normalizable(con); + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(G_OBJECT(s_ip4), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + NULL); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + NULL); + + nm_connection_add_setting(con, (NMSetting *) s_ip4); + nm_connection_add_setting(con, (NMSetting *) s_ip6); + + nmtst_assert_connection_verifies_and_normalizable(con); + + /* Now set method=disabled/ignore and check that may-fail becomes TRUE + * after normalization + * */ + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + nmtst_assert_connection_verifies(con); + nmtst_connection_normalize(con); + g_assert_cmpint(nm_setting_ip_config_get_may_fail(s_ip4), ==, TRUE); + g_assert_cmpint(nm_setting_ip_config_get_may_fail(s_ip6), ==, TRUE); +} + +static void +test_connection_normalize_shared_addresses(void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingIPConfig * s_ip4, *s_ip6; + NMIPAddress * addr; + gs_free_error GError *error = NULL; + + con = nmtst_create_minimal_connection("test1", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nmtst_assert_connection_verifies_and_normalizable(con); + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(G_OBJECT(s_ip4), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_SHARED, + NULL); + + addr = nm_ip_address_new(AF_INET, "1.1.1.1", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + + nm_connection_add_setting(con, (NMSetting *) s_ip4); + nm_connection_add_setting(con, (NMSetting *) s_ip6); + + nmtst_assert_connection_verifies_and_normalizable(con); + + /* Now we add other addresses and check that they are + * removed during normalization + * */ + addr = nm_ip_address_new(AF_INET, "2.2.2.2", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + addr = nm_ip_address_new(AF_INET, "3.3.3.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + nmtst_connection_normalize(con); + g_assert_cmpuint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert_cmpstr(nm_ip_address_get_address(addr), ==, "1.1.1.1"); +} + +static void +test_connection_normalize_ovs_interface_type_system(gconstpointer test_data) +{ + const guint TEST_CASE = GPOINTER_TO_UINT(test_data); + gs_unref_object NMConnection *con = NULL; + NMSettingConnection * s_con; + NMSettingOvsInterface * s_ovs_if; + + con = nmtst_create_minimal_connection("test_connection_normalize_ovs_interface_type_system", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + + switch (TEST_CASE) { + case 1: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING); + + nmtst_connection_normalize(con); + nmtst_assert_connection_has_settings(con, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + s_ovs_if = nm_connection_get_setting_ovs_interface(con); + g_assert(s_ovs_if); + g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "system"); + break; + case 2: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + + s_ovs_if = NM_SETTING_OVS_INTERFACE(nm_setting_ovs_interface_new()); + nm_connection_add_setting(con, NM_SETTING(s_ovs_if)); + + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + + nmtst_connection_normalize(con); + nmtst_assert_connection_has_settings(con, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); + g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "system"); + break; + case 3: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + + s_ovs_if = NM_SETTING_OVS_INTERFACE(nm_setting_ovs_interface_new()); + nm_connection_add_setting(con, NM_SETTING(s_ovs_if)); + + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "system", NULL); + nmtst_assert_connection_verifies_without_normalization(con); + nmtst_assert_connection_has_settings(con, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + break; + case 4: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + + s_ovs_if = NM_SETTING_OVS_INTERFACE(nm_setting_ovs_interface_new()); + nm_connection_add_setting(con, NM_SETTING(s_ovs_if)); + + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "internal", NULL); + /* the setting doesn't verify, because the interface-type must be "system". */ + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + break; + case 5: + g_object_set(s_con, NM_SETTING_CONNECTION_MASTER, "master0", NULL); + + s_ovs_if = NM_SETTING_OVS_INTERFACE(nm_setting_ovs_interface_new()); + nm_connection_add_setting(con, NM_SETTING(s_ovs_if)); + + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "system", NULL); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + nmtst_connection_normalize(con); + nmtst_assert_connection_has_settings(con, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + g_assert(s_con == nm_connection_get_setting_connection(con)); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_OVS_PORT_SETTING_NAME); + break; + case 6: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BRIDGE_SETTING_NAME, + NULL); + + s_ovs_if = NM_SETTING_OVS_INTERFACE(nm_setting_ovs_interface_new()); + nm_connection_add_setting(con, NM_SETTING(s_ovs_if)); + + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "system", NULL); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + break; + case 7: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BRIDGE_SETTING_NAME, + NULL); + + nm_connection_add_setting(con, nm_setting_bridge_port_new()); + + s_ovs_if = NM_SETTING_OVS_INTERFACE(nm_setting_ovs_interface_new()); + nm_connection_add_setting(con, NM_SETTING(s_ovs_if)); + + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "system", NULL); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + break; + default: + g_assert_not_reached(); + break; + } +} + +static void +test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_data) +{ + const guint TEST_CASE = GPOINTER_TO_UINT(test_data); + gs_unref_object NMConnection *con = NULL; + NMSettingConnection * s_con; + NMSettingOvsInterface * s_ovs_if; + NMSettingOvsPatch * s_ovs_patch; + NMSettingIP4Config * s_ip4; + NMSettingIP6Config * s_ip6; + + con = nmtst_create_minimal_connection( + "test_connection_normalize_ovs_interface_type_ovs_interface", + NULL, + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + &s_con); + s_ovs_if = nm_connection_get_setting_ovs_interface(con); + g_assert(s_ovs_if); + + switch (TEST_CASE) { + case 1: + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + break; + case 2: + g_object_set(s_con, NM_SETTING_CONNECTION_MASTER, "master0", NULL); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + nmtst_connection_normalize(con); + nmtst_assert_connection_has_settings(con, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + g_assert(s_con == nm_connection_get_setting_connection(con)); + g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_OVS_PORT_SETTING_NAME); + g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "internal"); + break; + case 3: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + nmtst_connection_normalize(con); + nmtst_assert_connection_has_settings(con, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + g_assert(s_con == nm_connection_get_setting_connection(con)); + g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_OVS_PORT_SETTING_NAME); + g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "internal"); + break; + case 4: + g_object_set(s_con, NM_SETTING_CONNECTION_MASTER, "master0", NULL); + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "internal", NULL); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + nmtst_connection_normalize(con); + nmtst_assert_connection_has_settings(con, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + g_assert(s_con == nm_connection_get_setting_connection(con)); + g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_OVS_PORT_SETTING_NAME); + g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "internal"); + break; + case 5: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "internal", NULL); + nm_connection_add_setting(con, nm_setting_ip4_config_new()); + nm_connection_add_setting(con, nm_setting_ip6_config_new()); + nm_connection_add_setting(con, nm_setting_proxy_new()); + s_ip4 = NM_SETTING_IP4_CONFIG(nm_connection_get_setting_ip4_config(con)); + s_ip6 = NM_SETTING_IP6_CONFIG(nm_connection_get_setting_ip6_config(con)); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, "auto", NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, "auto", NULL); + nmtst_assert_connection_verifies_without_normalization(con); + nmtst_assert_connection_has_settings(con, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + break; + case 6: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "internal", NULL); + nmtst_assert_connection_verifies_and_normalizable(con); + nmtst_connection_normalize(con); + nmtst_assert_connection_has_settings(con, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME); + g_assert(s_con == nm_connection_get_setting_connection(con)); + g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_OVS_PORT_SETTING_NAME); + g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "internal"); + break; + case 7: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "system", NULL); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + break; + case 8: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "bogus", NULL); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + break; + case 9: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "patch", NULL); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING); + break; + case 10: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "patch", NULL); + nm_connection_add_setting(con, nm_setting_ovs_patch_new()); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + break; + case 11: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "adsf", + NULL); + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "patch", NULL); + nm_connection_add_setting(con, nm_setting_ovs_patch_new()); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY); + break; + case 12: + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "adsf", + NULL); + g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "patch", NULL); + s_ovs_patch = NM_SETTING_OVS_PATCH(nm_setting_ovs_patch_new()); + nm_connection_add_setting(con, NM_SETTING(s_ovs_patch)); + g_object_set(s_ovs_patch, NM_SETTING_OVS_PATCH_PEER, "1.2.3.4", NULL); + nmtst_assert_connection_verifies_and_normalizable(con); + nmtst_connection_normalize(con); + nmtst_assert_connection_has_settings(con, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_PATCH_SETTING_NAME); + g_assert(s_con == nm_connection_get_setting_connection(con)); + g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_OVS_PORT_SETTING_NAME); + g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "patch"); + break; + default: + g_assert_not_reached(); + } +} + +static void +test_setting_ip4_gateway(void) +{ + NMConnection * conn; + NMSettingIPConfig *s_ip4; + NMIPAddress * addr; + GVariant * conn_dict, *ip4_dict, *value; + GVariantIter iter; + GVariant * addr_var; + guint32 addr_vals_0[] = {htonl(0xc0a8010a), 0x00000018, htonl(0x00000000)}; + guint32 addr_vals_1[] = {htonl(0xc0a8010b), 0x00000018, htonl(0xc0a80101)}; + GVariantBuilder addrs_builder; + GError * error = NULL; + + nmtst_assert_ip4_address(addr_vals_0[0], "192.168.1.10"); + + /* When serializing on the daemon side, ipv4.gateway is copied to the first + * entry of ipv4.addresses + */ + conn = nmtst_create_minimal_connection("test_setting_ip4_gateway", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "192.168.1.1", + NULL); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + addr = nm_ip_address_new(AF_INET, "192.168.1.10", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + _nm_utils_is_manager_process = TRUE; + conn_dict = nm_connection_to_dbus(conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + g_object_unref(conn); + + ip4_dict = g_variant_lookup_value(conn_dict, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_VARIANT_TYPE_SETTING); + g_assert(ip4_dict != NULL); + + value = g_variant_lookup_value(ip4_dict, NM_SETTING_IP_CONFIG_GATEWAY, G_VARIANT_TYPE_STRING); + g_assert(value != NULL); + g_assert_cmpstr(g_variant_get_string(value, NULL), ==, "192.168.1.1"); + g_variant_unref(value); + + value = g_variant_lookup_value(ip4_dict, NM_SETTING_IP_CONFIG_ADDRESSES, G_VARIANT_TYPE("aau")); + g_assert(value != NULL); + + g_variant_iter_init(&iter, value); + while (g_variant_iter_next(&iter, "@au", &addr_var)) { + const guint32 *addr_array; + gsize length; + + addr_array = g_variant_get_fixed_array(addr_var, &length, sizeof(guint32)); + g_assert_cmpint(length, ==, 3); + nmtst_assert_ip4_address(addr_array[2], "192.168.1.1"); + g_variant_unref(addr_var); + } + g_variant_unref(value); + + g_variant_unref(ip4_dict); + + /* When deserializing an old-style connection, the first non-0 gateway in + * ipv4.addresses is copied to :gateway. + */ + NMTST_VARIANT_EDITOR( + conn_dict, + NMTST_VARIANT_DROP_PROPERTY(NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_GATEWAY); + NMTST_VARIANT_DROP_PROPERTY(NM_SETTING_IP4_CONFIG_SETTING_NAME, "address-data");); + + conn = _connection_new_from_dbus(conn_dict, &error); + g_assert_no_error(error); + + s_ip4 = (NMSettingIPConfig *) nm_connection_get_setting_ip4_config(conn); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.168.1.1"); + + g_object_unref(conn); + + /* Try again with the gateway in the second address. */ + g_variant_builder_init(&addrs_builder, G_VARIANT_TYPE("aau")); + g_variant_builder_add(&addrs_builder, + "@au", + g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, addr_vals_0, 3, 4)); + g_variant_builder_add(&addrs_builder, + "@au", + g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, addr_vals_1, 3, 4)); + + NMTST_VARIANT_EDITOR(conn_dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_IP4_CONFIG_SETTING_NAME, + "addresses", + "aau", + &addrs_builder);); + + conn = _connection_new_from_dbus(conn_dict, &error); + g_assert_no_error(error); + g_variant_unref(conn_dict); + + s_ip4 = (NMSettingIPConfig *) nm_connection_get_setting_ip4_config(conn); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.168.1.1"); + + g_object_unref(conn); +} + +static void +test_setting_ip6_gateway(void) +{ + NMConnection * conn; + NMSettingIPConfig *s_ip6; + NMIPAddress * addr; + GVariant * conn_dict, *ip6_dict, *value; + GVariantIter iter; + GVariant * gateway_var; + GVariantBuilder addrs_builder; + guint8 addr_bytes_0[] = {0xab, + 0xcd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0a}; + guint8 addr_bytes_1[] = {0xab, + 0xcd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0b}; + guint8 gateway_bytes_1[] = {0xab, + 0xcd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01}; + GError * error = NULL; + + /* When serializing on the daemon side, ipv6.gateway is copied to the first + * entry of ipv6.addresses + */ + conn = nmtst_create_minimal_connection("test_setting_ip6_gateway", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "abcd::1", + NULL); + nm_connection_add_setting(conn, NM_SETTING(s_ip6)); + + addr = nm_ip_address_new(AF_INET6, "abcd::10", 64, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip6, addr); + nm_ip_address_unref(addr); + + _nm_utils_is_manager_process = TRUE; + conn_dict = nm_connection_to_dbus(conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + g_object_unref(conn); + + ip6_dict = g_variant_lookup_value(conn_dict, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_VARIANT_TYPE_SETTING); + g_assert(ip6_dict != NULL); + + value = g_variant_lookup_value(ip6_dict, NM_SETTING_IP_CONFIG_GATEWAY, G_VARIANT_TYPE_STRING); + g_assert(value != NULL); + g_assert_cmpstr(g_variant_get_string(value, NULL), ==, "abcd::1"); + g_variant_unref(value); + + value = g_variant_lookup_value(ip6_dict, + NM_SETTING_IP_CONFIG_ADDRESSES, + G_VARIANT_TYPE("a(ayuay)")); + g_assert(value != NULL); + + g_variant_iter_init(&iter, value); + while (g_variant_iter_next(&iter, "(@ayu@ay)", NULL, NULL, &gateway_var)) { + const guint8 *gateway_bytes; + gsize length; + + gateway_bytes = g_variant_get_fixed_array(gateway_var, &length, 1); + g_assert_cmpint(length, ==, 16); + nmtst_assert_ip6_address((struct in6_addr *) gateway_bytes, "abcd::1"); + g_variant_unref(gateway_var); + } + g_variant_unref(value); + + g_variant_unref(ip6_dict); + + /* When deserializing an old-style connection, the first non-0 gateway in + * ipv6.addresses is copied to :gateway. + */ + NMTST_VARIANT_EDITOR( + conn_dict, + NMTST_VARIANT_DROP_PROPERTY(NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_GATEWAY); + NMTST_VARIANT_DROP_PROPERTY(NM_SETTING_IP6_CONFIG_SETTING_NAME, "address-data");); + + conn = _connection_new_from_dbus(conn_dict, &error); + g_assert_no_error(error); + + s_ip6 = (NMSettingIPConfig *) nm_connection_get_setting_ip6_config(conn); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, "abcd::1"); + + g_object_unref(conn); + + /* Try again with the gateway in the second address. */ + g_variant_builder_init(&addrs_builder, G_VARIANT_TYPE("a(ayuay)")); + g_variant_builder_add(&addrs_builder, + "(@ayu@ay)", + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, addr_bytes_0, 16, 1), + 64, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &in6addr_any, 16, 1)); + g_variant_builder_add(&addrs_builder, + "(@ayu@ay)", + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, addr_bytes_1, 16, 1), + 64, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, gateway_bytes_1, 16, 1)); + + NMTST_VARIANT_EDITOR(conn_dict, + NMTST_VARIANT_CHANGE_PROPERTY(NM_SETTING_IP6_CONFIG_SETTING_NAME, + "addresses", + "a(ayuay)", + &addrs_builder);); + + conn = _connection_new_from_dbus(conn_dict, &error); + g_assert_no_error(error); + g_variant_unref(conn_dict); + + s_ip6 = (NMSettingIPConfig *) nm_connection_get_setting_ip6_config(conn); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, "abcd::1"); + + g_object_unref(conn); +} + +typedef struct { + const char * str; + const guint8 expected[20]; + const guint expected_len; +} HexItem; + +static void +test_setting_compare_default_strv(void) +{ + gs_unref_object NMConnection *c1 = NULL, *c2 = NULL; + char ** strv; + NMSettingIPConfig * s_ip2, *s_ip1; + gboolean compare; + GHashTable * out_settings = NULL; + + c1 = nmtst_create_minimal_connection("test_compare_default_strv", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + nmtst_assert_connection_verifies_and_normalizable(c1); + nmtst_connection_normalize(c1); + + c2 = nm_simple_connection_new_clone(c1); + nmtst_assert_connection_verifies_without_normalization(c2); + + nmtst_assert_connection_equals(c1, FALSE, c2, FALSE); + + s_ip1 = nm_connection_get_setting_ip4_config(c1); + s_ip2 = nm_connection_get_setting_ip4_config(c2); + + nm_setting_ip_config_clear_dns_options(s_ip2, FALSE); + g_object_get(G_OBJECT(s_ip2), NM_SETTING_IP_CONFIG_DNS_OPTIONS, &strv, NULL); + g_assert(!strv); + nmtst_assert_connection_equals(c1, FALSE, c2, FALSE); + + nm_setting_ip_config_clear_dns_options(s_ip2, TRUE); + g_object_get(G_OBJECT(s_ip2), NM_SETTING_IP_CONFIG_DNS_OPTIONS, &strv, NULL); + g_assert(strv && !strv[0]); + g_strfreev(strv); + + compare = nm_setting_diff((NMSetting *) s_ip1, + (NMSetting *) s_ip2, + NM_SETTING_COMPARE_FLAG_EXACT, + FALSE, + &out_settings); + g_assert(!compare); + g_assert(out_settings); + g_assert(g_hash_table_contains(out_settings, NM_SETTING_IP_CONFIG_DNS_OPTIONS)); + g_hash_table_unref(out_settings); + out_settings = NULL; + + compare = nm_connection_diff(c1, c2, NM_SETTING_COMPARE_FLAG_EXACT, &out_settings); + g_assert(!compare); + g_assert(out_settings); + g_hash_table_unref(out_settings); + out_settings = NULL; +} + +/*****************************************************************************/ + +static void +test_setting_user_data(void) +{ + gs_unref_object NMSettingUser *s_user = NULL; + + s_user = NM_SETTING_USER(nm_setting_user_new()); +} + +/*****************************************************************************/ + +typedef union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; +} SockAddrUnion; + +static void +_sock_addr_endpoint(const char *endpoint, const char *host, gint32 port) +{ + nm_auto_unref_sockaddrendpoint NMSockAddrEndpoint *ep = NULL; + const char * s_endpoint; + const char * s_host; + gint32 s_port; + SockAddrUnion sockaddr = {}; + + g_assert(endpoint); + g_assert((!host) == (port == -1)); + g_assert(port >= -1 && port <= G_MAXUINT16); + + ep = nm_sock_addr_endpoint_new(endpoint); + g_assert(ep); + + s_endpoint = nm_sock_addr_endpoint_get_endpoint(ep); + s_host = nm_sock_addr_endpoint_get_host(ep); + s_port = nm_sock_addr_endpoint_get_port(ep); + g_assert_cmpstr(endpoint, ==, s_endpoint); + g_assert_cmpstr(host, ==, s_host); + g_assert_cmpint(port, ==, s_port); + + g_assert(!nm_sock_addr_endpoint_get_fixed_sockaddr(ep, &sockaddr)); + + if (endpoint[0] != ' ') { + gs_free char *endpoint2 = NULL; + + /* also test with a leading space */ + endpoint2 = g_strdup_printf(" %s", endpoint); + _sock_addr_endpoint(endpoint2, host, port); + } + + if (endpoint[0] && endpoint[strlen(endpoint) - 1] != ' ') { + gs_free char *endpoint2 = NULL; + + /* also test with a trailing space */ + endpoint2 = g_strdup_printf("%s ", endpoint); + _sock_addr_endpoint(endpoint2, host, port); + } +} + +static void +_sock_addr_endpoint_fixed(const char *endpoint, const char *host, guint16 port, guint scope_id) +{ + nm_auto_unref_sockaddrendpoint NMSockAddrEndpoint *ep = NULL; + const char * s_endpoint; + const char * s_host; + gint32 s_port; + int addr_family; + NMIPAddr addrbin; + SockAddrUnion sockaddr = {}; + + g_assert(endpoint); + g_assert(host); + g_assert(port > 0); + + if (!nm_utils_parse_inaddr_bin(AF_UNSPEC, host, &addr_family, &addrbin)) + g_assert_not_reached(); + + ep = nm_sock_addr_endpoint_new(endpoint); + g_assert(ep); + + s_endpoint = nm_sock_addr_endpoint_get_endpoint(ep); + s_host = nm_sock_addr_endpoint_get_host(ep); + s_port = nm_sock_addr_endpoint_get_port(ep); + g_assert_cmpstr(endpoint, ==, s_endpoint); + g_assert_cmpstr(NULL, !=, s_host); + g_assert_cmpint(port, ==, s_port); + + if (!nm_sock_addr_endpoint_get_fixed_sockaddr(ep, &sockaddr)) + g_assert_not_reached(); + + g_assert_cmpint(sockaddr.sa.sa_family, ==, addr_family); + if (addr_family == AF_INET) { + const SockAddrUnion s = { + .in = + { + .sin_family = AF_INET, + .sin_addr = addrbin.addr4_struct, + .sin_port = htons(port), + }, + }; + + g_assert_cmpint(sockaddr.in.sin_addr.s_addr, ==, addrbin.addr4); + g_assert_cmpint(sockaddr.in.sin_port, ==, htons(port)); + g_assert(memcmp(&s, &sockaddr, sizeof(s.in)) == 0); + } else if (addr_family == AF_INET6) { + const SockAddrUnion s = { + .in6 = + { + .sin6_family = AF_INET6, + .sin6_addr = addrbin.addr6, + .sin6_scope_id = scope_id, + .sin6_port = htons(port), + }, + }; + + g_assert(memcmp(&sockaddr.in6.sin6_addr, &addrbin, sizeof(addrbin.addr6)) == 0); + g_assert_cmpint(sockaddr.in6.sin6_port, ==, htons(port)); + g_assert_cmpint(sockaddr.in6.sin6_scope_id, ==, scope_id); + g_assert_cmpint(sockaddr.in6.sin6_flowinfo, ==, 0); + g_assert(memcmp(&s, &sockaddr, sizeof(s.in6)) == 0); + } else + g_assert_not_reached(); +} + +static void +test_sock_addr_endpoint(void) +{ + _sock_addr_endpoint("", NULL, -1); + _sock_addr_endpoint(":", NULL, -1); + _sock_addr_endpoint("a", NULL, -1); + _sock_addr_endpoint("a:", NULL, -1); + _sock_addr_endpoint(":a", NULL, -1); + _sock_addr_endpoint("[]:a", NULL, -1); + _sock_addr_endpoint("[]a", NULL, -1); + _sock_addr_endpoint("[]:", NULL, -1); + _sock_addr_endpoint("[a]b", NULL, -1); + _sock_addr_endpoint("[a:b", NULL, -1); + _sock_addr_endpoint("[a[:b", NULL, -1); + _sock_addr_endpoint("a:6", "a", 6); + _sock_addr_endpoint("a:6", "a", 6); + _sock_addr_endpoint("[a]:6", "a", 6); + _sock_addr_endpoint("[a]:6", "a", 6); + _sock_addr_endpoint("[a]:655", "a", 655); + _sock_addr_endpoint("[ab]:][6", NULL, -1); + _sock_addr_endpoint("[ab]:]:[6", NULL, -1); + _sock_addr_endpoint("[a[]:b", NULL, -1); + _sock_addr_endpoint("[192.169.6.x]:6", "192.169.6.x", 6); + _sock_addr_endpoint("[192.169.6.x]:0", NULL, -1); + _sock_addr_endpoint("192.169.6.7:0", NULL, -1); + + _sock_addr_endpoint_fixed("192.169.6.7:6", "192.169.6.7", 6, 0); + _sock_addr_endpoint_fixed("[192.169.6.7]:6", "192.169.6.7", 6, 0); + _sock_addr_endpoint_fixed("[a:b::]:6", "a:b::", 6, 0); + _sock_addr_endpoint_fixed("[a:b::%7]:6", "a:b::", 6, 7); + _sock_addr_endpoint_fixed("a:b::1%75:6", "a:b::1", 6, 75); + _sock_addr_endpoint_fixed("a:b::1%0:64", "a:b::1", 64, 0); +} + +/*****************************************************************************/ + +static void +test_hexstr2bin(void) +{ + static const HexItem items[] = { + {"aaBBCCddDD10496a", {0xaa, 0xbb, 0xcc, 0xdd, 0xdd, 0x10, 0x49, 0x6a}, 8}, + {"aa:bb:cc:dd:10:49:6a", {0xaa, 0xbb, 0xcc, 0xdd, 0x10, 0x49, 0x6a}, 7}, + {"0xccddeeff", {0xcc, 0xdd, 0xee, 0xff}, 4}, + {"1:2:66:77:80", {0x01, 0x02, 0x66, 0x77, 0x80}, 5}, + {"e", {0x0e}, 1}, + {"ef", {0xef}, 1}, + {"efa"}, + {"efad", {0xef, 0xad}, 2}, + {"ef:a", {0xef, 0x0a}, 2}, + {"aabb1199:"}, + {":aabb1199"}, + {"aabb$$dd"}, + {"aab:ccc:ddd"}, + {"aab::ccc:ddd"}, + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS(items); i++) { + gs_unref_bytes GBytes *b = NULL; + + b = nm_utils_hexstr2bin(items[i].str); + if (items[i].expected_len) + g_assert(b); + else + g_assert(!b); + g_assert(nm_utils_gbytes_equal_mem(b, items[i].expected, items[i].expected_len)); + } +} + +/*****************************************************************************/ + +static void +_do_strquote(const char *str, gsize buf_len, const char *expected) +{ + char canary = (char) nmtst_get_rand_uint32(); + gs_free char *buf_full = g_malloc(buf_len + 2); + char * buf = &buf_full[1]; + const char * b; + + buf[-1] = canary; + buf[buf_len] = canary; + + if (buf_len == 0) { + b = nm_strquote(NULL, 0, str); + g_assert(b == NULL); + g_assert(expected == NULL); + b = nm_strquote(buf, 0, str); + g_assert(b == buf); + } else { + b = nm_strquote(buf, buf_len, str); + g_assert(b == buf); + g_assert(strlen(b) < buf_len); + g_assert_cmpstr(expected, ==, b); + } + + g_assert(buf[-1] == canary); + g_assert(buf[buf_len] == canary); +} + +static void +test_nm_strquote(void) +{ + _do_strquote(NULL, 0, NULL); + _do_strquote("", 0, NULL); + _do_strquote("a", 0, NULL); + _do_strquote("ab", 0, NULL); + + _do_strquote(NULL, 1, ""); + _do_strquote(NULL, 2, "("); + _do_strquote(NULL, 3, "(n"); + _do_strquote(NULL, 4, "(nu"); + _do_strquote(NULL, 5, "(nul"); + _do_strquote(NULL, 6, "(null"); + _do_strquote(NULL, 7, "(null)"); + _do_strquote(NULL, 8, "(null)"); + _do_strquote(NULL, 100, "(null)"); + + _do_strquote("", 1, ""); + _do_strquote("", 2, "^"); + _do_strquote("", 3, "\"\""); + _do_strquote("", 4, "\"\""); + _do_strquote("", 5, "\"\""); + _do_strquote("", 100, "\"\""); + + _do_strquote("a", 1, ""); + _do_strquote("a", 2, "^"); + _do_strquote("a", 3, "\"^"); + _do_strquote("a", 4, "\"a\""); + _do_strquote("a", 5, "\"a\""); + _do_strquote("a", 6, "\"a\""); + _do_strquote("a", 100, "\"a\""); + + _do_strquote("ab", 1, ""); + _do_strquote("ab", 2, "^"); + _do_strquote("ab", 3, "\"^"); + _do_strquote("ab", 4, "\"a^"); + _do_strquote("ab", 5, "\"ab\""); + _do_strquote("ab", 6, "\"ab\""); + _do_strquote("ab", 7, "\"ab\""); + _do_strquote("ab", 100, "\"ab\""); + + _do_strquote("abc", 1, ""); + _do_strquote("abc", 2, "^"); + _do_strquote("abc", 3, "\"^"); + _do_strquote("abc", 4, "\"a^"); + _do_strquote("abc", 5, "\"ab^"); + _do_strquote("abc", 6, "\"abc\""); + _do_strquote("abc", 7, "\"abc\""); + _do_strquote("abc", 100, "\"abc\""); +} + +/*****************************************************************************/ + +#define UUID_NS_ZERO "00000000-0000-0000-0000-000000000000" +#define UUID_NS_DNS "6ba7b810-9dad-11d1-80b4-00c04fd430c8" +#define UUID_NS_URL "6ba7b811-9dad-11d1-80b4-00c04fd430c8" +#define UUID_NS_OID "6ba7b812-9dad-11d1-80b4-00c04fd430c8" +#define UUID_NS_X500 "6ba7b814-9dad-11d1-80b4-00c04fd430c8" + +static const NMUuid * +_uuid(const char *str) +{ + static NMUuid u; + + g_assert(str); + g_assert(_nm_utils_uuid_parse(str, &u)); + return &u; +} + +static void +_test_uuid(int uuid_type, + const char *expected_uuid, + const char *str, + gssize slen, + gpointer type_args) +{ + gs_free char *uuid_test = NULL; + + uuid_test = nm_utils_uuid_generate_from_string(str, slen, uuid_type, type_args); + + g_assert(uuid_test); + g_assert(nm_utils_is_uuid(uuid_test)); + + if (!nm_streq(uuid_test, expected_uuid)) { + g_error("UUID test failed: type=%d; text=%s, len=%lld, ns=%s, uuid=%s, expected=%s", + uuid_type, + str, + (long long) slen, + NM_IN_SET(uuid_type, NM_UTILS_UUID_TYPE_VERSION3, NM_UTILS_UUID_TYPE_VERSION5) + ? (((const char *) type_args) ?: "(all-zero)") + : (type_args ? "(unknown)" : "(null)"), + uuid_test, + expected_uuid); + } + + if (slen < 0) { + /* also test that passing slen==-1 yields the same result as passing strlen(str). */ + _test_uuid(uuid_type, expected_uuid, str, strlen(str), type_args); + } else if (str && slen == 0) { + /* also test if we accept NULL for slen==0 */ + _test_uuid(uuid_type, expected_uuid, NULL, 0, type_args); + } + + if (NM_IN_SET(uuid_type, NM_UTILS_UUID_TYPE_VERSION3, NM_UTILS_UUID_TYPE_VERSION5) + && !type_args) { + /* For version3 and version5, a missing @type_args is equal to UUID_NS_ZERO */ + _test_uuid(uuid_type, expected_uuid, str, slen, UUID_NS_ZERO); + } +} + +typedef struct { + const char *uuid3; + const char *uuid5; +} ExpectedUuids; + +static void +test_nm_utils_uuid_generate_from_string(void) +{ + const ExpectedUuids zero_uuids[] = { + { + .uuid3 = "19826852-5007-3022-a72a-212f66e9fac3", + .uuid5 = "b6c54489-38a0-5f50-a60a-fd8d76219cae", + }, + { + .uuid3 = "9153af2e-fc8e-34f3-9e8b-81f73b33d0cb", + .uuid5 = "11116e73-1c03-5de6-9130-5f9925ae8ab4", + }, + { + .uuid3 = "2f06a3ae-d78d-30d7-b898-088a0e0b76f6", + .uuid5 = "1087ebe8-1ef8-5d97-8873-735b4949004d", + }, + { + .uuid3 = "aca948e0-1468-3a51-9f2e-c688a484efd7", + .uuid5 = "7e57d004-2b97-5e7a-b45f-5387367791cd", + }, + { + .uuid3 = "b74e537a-53e8-3808-9abd-58546a6542bd", + .uuid5 = "1dd80df1-492c-5dc5-aec2-6bf0e104f923", + }, + { + .uuid3 = "1b00958a-7d76-3d08-8aba-c66c5828658c", + .uuid5 = "f797f61e-a392-5acf-af25-b46057f1c8e8", + }, + { + .uuid3 = "7ba18f7d-c9cf-3b48-a89e-ad79243135cc", + .uuid5 = "e02c9780-2fc5-5d57-b92f-4cc3a64bff16", + }, + { + .uuid3 = "9baf0978-1a60-35c5-9e9b-bec8d259fd4e", + .uuid5 = "94167980-f909-527e-a4af-bc3155f586d3", + }, + { + .uuid3 = "588668c0-7631-39c7-9976-c7d414adf7ba", + .uuid5 = "9e3eefda-b56e-56bd-8a3a-0b8009d4a536", + }, + { + .uuid3 = "8edb3613-9612-3b32-9dd7-0a01aa8ed453", + .uuid5 = "9b75648e-d38c-54e8-adee-1fb295a079c9", + }, + { + .uuid3 = "f3b34394-63a5-3773-9014-1f8a50d765b8", + .uuid5 = "dd56b598-9e74-58c3-b3e8-2c623780b8ed", + }, + { + .uuid3 = "0572965f-05b8-342b-b225-d5c29d449eee", + .uuid5 = "5666449a-fb7e-55b7-ae9f-0552e6513a10", + }, + { + .uuid3 = "6f7177c3-77b0-3f42-82a8-7031e25fcccf", + .uuid5 = "10b38db9-82fc-528e-9ddb-1f09b7dbf907", + }, + { + .uuid3 = "d1e0f845-bc1b-368c-b8c8-49ab0b9e486b", + .uuid5 = "85492596-9468-5845-9c7f-d4ae999cb751", + }, + { + .uuid3 = "46371ea3-c8a3-34d8-b2cf-2fa90bda4378", + .uuid5 = "22b1c0dd-aa5d-54a4-8768-5adfd0d112bd", + }, + { + .uuid3 = "f1e6b499-9b68-343b-a5c5-ece7acc49a68", + .uuid5 = "9cc429f8-200e-52a3-9e3b-ef134afa1e29", + }, + { + .uuid3 = "9ed06458-c712-31dd-aba5-6cf79879fabe", + .uuid5 = "3949f95c-5d76-5ee2-af60-8e2d8fcf649d", + }, + { + .uuid3 = "4ddd5cd7-bc83-36aa-909c-4e660f57c830", + .uuid5 = "0e994a02-069b-58fb-b3a4-d7dc94e90fca", + }, + { + .uuid3 = "335fa537-0909-395d-a696-6f41827dcbeb", + .uuid5 = "17db3a41-de9b-5c6b-904d-833943209b3c", + }, + { + .uuid3 = "dbd58444-05ad-3edd-adc7-4393ecbcb43c", + .uuid5 = "1bd906f2-05f9-5ab5-a39a-4c17a188f886", + }, + { + .uuid3 = "a1c62d82-d13c-361b-8f4e-ca91bc2f7fc5", + .uuid5 = "ce6550fd-95b7-57e4-9aa7-461522666be4", + }, + { + .uuid3 = "e943d83e-3f82-307f-81ed-b7a7bcd0743e", + .uuid5 = "04aa09ee-b420-57ac-8a23-5d99907fb0a1", + }, + { + .uuid3 = "cabf46dd-9f09-375c-8f6e-f2a8cf114709", + .uuid5 = "8ece2c62-0c31-5c55-b7c6-155381e3780e", + }, + { + .uuid3 = "19beddf3-f2fb-340f-96ac-4f394960b7a7", + .uuid5 = "5762a9f9-9a21-59ab-b0d2-2cb90027ef7f", + }, + { + .uuid3 = "08d835c2-f4ca-394c-ba7f-2494d8b60c6c", + .uuid5 = "23c8409d-4b5f-5b6a-b946-41e49bad6c78", + }, + { + .uuid3 = "3b8c6847-5331-35bf-9cd9-ced50e53cd7c", + .uuid5 = "e8e396be-95d5-5569-8edc-e0b64c2b7613", + }, + { + .uuid3 = "e601f160-484b-3254-8f3b-0a25c7203d8a", + .uuid5 = "bc8b3cbc-ad5b-5808-a1b0-e0f7a1ad68a3", + }, + { + .uuid3 = "e5e492ed-5349-379d-b7de-a370a51e44a3", + .uuid5 = "62c5ed3f-9afa-59ad-874f-a9dd8afc69d4", + }, + { + .uuid3 = "c40111f6-fe97-305e-bfce-7db730c3d2ec", + .uuid5 = "66877a72-7243-59ed-b9e3-b5023b6da9c2", + }, + { + .uuid3 = "21e18ea8-95c2-362b-9ca9-25d6a0ff2dff", + .uuid5 = "49a49eee-7e86-5d66-837a-8a8810cb5562", + }, + { + .uuid3 = "adab623b-1343-307f-80d8-58d005376ad9", + .uuid5 = "e4a2a7ed-3bf3-53cf-a2bb-154dbb39a38c", + }, + { + .uuid3 = "67e9fc7c-dafe-356d-ac1a-a63ce3f44813", + .uuid5 = "50cacfc9-f5d2-52dd-897c-a25a0927b816", + }, + { + .uuid3 = "36cc7f20-126c-3e40-94e7-737ac7486547", + .uuid5 = "ca629991-3f2b-5e86-9bb7-37a335f7d809", + }, + { + .uuid3 = "fe282996-ac5e-3d13-b478-5def30007a8e", + .uuid5 = "c1adf8a7-f72a-58ae-82d5-d18807f12e2e", + }, + { + .uuid3 = "3bfe339c-05ae-3233-a1a5-ebf1ead589db", + .uuid5 = "6120c3cd-24e1-5ce4-987b-f8bfee2e4633", + }, + { + .uuid3 = "d1d90bc7-da4a-3cd7-a7c8-a1a89765d8ee", + .uuid5 = "433d6a26-c319-5fcf-9a30-5ec6ad59d109", + }, + { + .uuid3 = "10b88a02-0102-359b-81e9-7e3b0ff7d25e", + .uuid5 = "77d228d9-1b96-59e2-a07e-a8fdd4f62884", + }, + { + .uuid3 = "7da5e4f2-6df0-3aca-a1b0-b7f8b1340e1d", + .uuid5 = "698259bf-a32b-5e00-9ec6-88b12278c4ad", + }, + { + .uuid3 = "cbe24d98-ca20-3058-86b6-24a6b36ceff0", + .uuid5 = "60dbca63-704f-5666-9f64-f4e1a630c4aa", + }, + { + .uuid3 = "04d84e6a-b793-3993-afbf-bae7cfc42b49", + .uuid5 = "79d63ec0-a39d-557d-8299-f4c97acfadc3", + }, + { + .uuid3 = "fdd157d8-a537-350a-9cc9-1930e8666c63", + .uuid5 = "7df7f75e-a146-5a76-828b-bac052db312b", + }, + { + .uuid3 = "0bea36bb-24a7-3ee6-a98d-116433c14cd4", + .uuid5 = "2bcca2e9-2879-53e3-b09d-cbbfd58771b2", + }, + { + .uuid3 = "52b040a4-1b84-32d2-b758-f82386f7e0f0", + .uuid5 = "cb7bdca3-e9f7-50cd-b72e-73cb9ff24f62", + }, + { + .uuid3 = "0f0a4e26-e034-3021-acf2-4e886af43092", + .uuid5 = "8e428e2b-5da3-5368-b760-5ca07ccbd819", + }, + { + .uuid3 = "819d3cd1-afe5-3e4a-9f0c-945e25d09879", + .uuid5 = "f340ef4d-139c-567a-b0fc-7c495336674e", + }, + { + .uuid3 = "e7df1a3b-c9f8-3e5a-88d6-ba72b2a0f27b", + .uuid5 = "7e3f5fd2-3c93-58d6-9f35-6e0192445b11", + }, + { + .uuid3 = "0854bedf-74ba-3f2b-b823-dc2c90d27c76", + .uuid5 = "bc112b6b-c5de-5ee9-b816-808792743a20", + }, + { + .uuid3 = "a1b8c3ba-f821-32ef-a3fd-b97b3855efa8", + .uuid5 = "47f8f82d-9fcd-553c-90c5-3f3cb3ad00ad", + }, + { + .uuid3 = "9458f819-079b-3033-9430-ba10f576c067", + .uuid5 = "bee5c091-5f01-51fa-86bb-e9488fd3b4da", + }, + { + .uuid3 = "8e1f240a-e386-3e00-866a-6f9da1e3503f", + .uuid5 = "8ea92cea-d741-566f-a44a-d51e65b4c5e4", + }, + }; + const ExpectedUuids dns_uuids[] = { + { + .uuid3 = "4385125b-dd1e-3025-880f-3311517cc8d5", + .uuid5 = "6af613b6-569c-5c22-9c37-2ed93f31d3af", + }, + { + .uuid3 = "afd0b036-625a-3aa8-b639-9dc8c8fff0ff", + .uuid5 = "b04965e6-a9bb-591f-8f8a-1adcb2c8dc39", + }, + { + .uuid3 = "9c45c2f1-1761-3daa-ad31-1ff8703ae846", + .uuid5 = "4b166dbe-d99d-5091-abdd-95b83330ed3a", + }, + { + .uuid3 = "15e0ba07-10e4-3d7f-aaff-c00fed873c88", + .uuid5 = "98123fde-012f-5ff3-8b50-881449dac91a", + }, + { + .uuid3 = "bc27b4db-bc0f-34f9-ae8e-4b72f2d51b60", + .uuid5 = "6ed955c6-506a-5343-9be4-2c0afae02eef", + }, + { + .uuid3 = "7586bfed-b8b8-3bb3-9c95-09a4a79dc0f7", + .uuid5 = "c8691da2-158a-5ed6-8537-0e6f140801f2", + }, + { + .uuid3 = "881430b6-8d28-3175-b87d-e81f2f5978c6", + .uuid5 = "a6c4fc8f-6950-51de-a9ae-2c519c465071", + }, + { + .uuid3 = "24075675-98ae-354e-89ca-0126a9ad36e3", + .uuid5 = "a9f96b98-dd44-5216-ab0d-dbfc6b262edf", + }, + { + .uuid3 = "2c269ea4-dbfd-32dd-9bd7-a5c22677d18b", + .uuid5 = "e99caacd-6c45-5906-bd9f-b79e62f25963", + }, + { + .uuid3 = "44eb0948-118f-3f28-87e4-f61c8f889aba", + .uuid5 = "e4d80b30-151e-51b5-9f4f-18a3b82718e6", + }, + { + .uuid3 = "fc72beeb-f790-36ee-a73d-33888c9d8880", + .uuid5 = "0159d6c7-973f-5e7a-a9a0-d195d0ea6fe2", + }, + { + .uuid3 = "1e46afa2-6176-3cd3-9750-3015846723df", + .uuid5 = "7fef88f7-411d-5669-b42d-bf5fc7f9b58b", + }, + { + .uuid3 = "0042b01d-95bd-343f-bd9f-3186bfd63508", + .uuid5 = "52524d6e-10dc-5261-aa36-8b2efcbaa5f0", + }, + { + .uuid3 = "115ff52f-d605-3b4b-98fe-c0ea57f4930c", + .uuid5 = "91c274f2-9a0d-5ce6-ac3d-7529f452df21", + }, + { + .uuid3 = "ed0221e8-ac7d-393b-821d-25183567885b", + .uuid5 = "0ff1e264-520d-543a-87dd-181a491e667e", + }, + { + .uuid3 = "508ef333-85a6-314c-bcf3-17ddc32b2216", + .uuid5 = "23986425-d3a5-5e13-8bab-299745777a8d", + }, + { + .uuid3 = "a4715ee0-524a-37cc-beb2-a0b5030757b7", + .uuid5 = "c15b38c9-9a3e-543c-a703-dd742f25b4d5", + }, + { + .uuid3 = "d1c72756-aaec-3470-a2f2-97415f44d72f", + .uuid5 = "db680066-c83d-5ed7-89a4-1d79466ea62d", + }, + { + .uuid3 = "7aec2f01-586e-3d53-b8f3-6cf7e6b649a4", + .uuid5 = "cadb7952-2bba-5609-88d4-8e47ec4e7920", + }, + { + .uuid3 = "3d234b88-8d6f-319a-91ea-edb6059fc825", + .uuid5 = "35140057-a2a4-5adb-a500-46f8ed8b66a9", + }, + { + .uuid3 = "d2568554-93ec-30c7-9e15-f383be19e5bb", + .uuid5 = "66e549b7-01e2-5d07-98d5-430f74d8d3b2", + }, + { + .uuid3 = "800e59a7-dd0f-3114-8e58-ab7e213895ca", + .uuid5 = "292c8e99-2378-55aa-83d8-350e0ac3f1cc", + }, + { + .uuid3 = "3b7d03f0-e067-3d72-84f4-e410ac36ef57", + .uuid5 = "0e3b230a-0509-55d8-96a0-9875f387a2be", + }, + { + .uuid3 = "8762be68-de95-391a-94a0-c5fd0446e037", + .uuid5 = "4c507660-a83b-55c0-9b2b-83eccb07723d", + }, + { + .uuid3 = "2bd8b4c9-01af-3cd0-aced-94ee6e2004b8", + .uuid5 = "a1b9b633-da11-58be-b1a9-5cfa2848f186", + }, + { + .uuid3 = "a627d6a4-394a-33f5-b68e-22bfb6488d01", + .uuid5 = "c2708a8b-120a-56f5-a30d-990048af87cc", + }, + { + .uuid3 = "6a592510-17d9-3925-b321-4a8d4927f8d0", + .uuid5 = "e7263999-68b6-5a23-b530-af25b7efd632", + }, + { + .uuid3 = "9ee72491-59c4-333c-bb93-fe733a842fdb", + .uuid5 = "ce1ae2d5-3454-5952-97ff-36ff935bcfe9", + }, + { + .uuid3 = "2591c62c-0a9d-3c28-97bc-fa0401556a3c", + .uuid5 = "33677b87-bc8d-5ff6-9a25-fe60225e4bf0", + }, + { + .uuid3 = "7912be1e-4562-373b-92e2-3d6d2123bc8e", + .uuid5 = "ed2305ae-e8f9-5387-b860-3d80ae6c02f7", + }, + { + .uuid3 = "09370cda-89a4-3a48-b592-9c0486e0d5e4", + .uuid5 = "604ed872-ae2d-5d91-8e3e-572f3a3aaaa5", + }, + { + .uuid3 = "de5980d3-a137-373c-850b-ca3e5f100779", + .uuid5 = "8f8173d9-2f8d-5636-a693-24d9f79ba651", + }, + { + .uuid3 = "9441501d-f633-365a-8955-9df443edc762", + .uuid5 = "36eb8d4d-b854-51f1-9fdf-3735964225d5", + }, + { + .uuid3 = "434ada18-13ce-3c08-8b40-a1a1ae030569", + .uuid5 = "3493b6ca-f84b-56a9-97cc-c0bd1c46c4c0", + }, + { + .uuid3 = "a13b6160-bd23-3710-a150-41d800dd30b4", + .uuid5 = "f413ea13-fcd9-5b44-9d22-1fa1f7b063a5", + }, + { + .uuid3 = "73a67c12-c5f0-3288-ad6a-c78aea0917b0", + .uuid5 = "f468d924-d23b-56c2-b90f-3d1cf4b45337", + }, + { + .uuid3 = "a126ee4f-a222-357d-b71b-7d3f226c559f", + .uuid5 = "8828c9d6-ed76-5c09-bf64-ba9e9cd90896", + }, + { + .uuid3 = "48f4f36b-b015-3137-9b6e-351bb175c7f7", + .uuid5 = "facb7618-55ca-5c30-9cba-fd567b6c0611", + }, + { + .uuid3 = "3fe8f6a3-fe4a-3487-89d6-dd06c6ad02e3", + .uuid5 = "96f3de0e-6412-5434-b406-67ef3352ab85", + }, + { + .uuid3 = "d68fa2d4-adc9-3b20-ac77-42585cd1d59f", + .uuid5 = "9ebacb89-40ab-52b3-93a2-9054611d8f55", + }, + { + .uuid3 = "819f86a3-31d5-3e72-a83e-142c3a3e4832", + .uuid5 = "681046ff-9129-5ade-b11c-769864e02184", + }, + { + .uuid3 = "9957b433-ddc8-3113-a3e6-5512cf13dab1", + .uuid5 = "c13d0b5d-1ca3-57b6-a23f-8586bca44928", + }, + { + .uuid3 = "5aab6e0c-b7d3-379c-92e3-2bfbb5572511", + .uuid5 = "7c411b5e-9d3f-50b5-9c28-62096e41c4ed", + }, + { + .uuid3 = "11c8ff30-3a7d-3547-80a7-d61b8abeeda8", + .uuid5 = "f825aafe-6696-5121-b263-6b2c408b7f43", + }, + { + .uuid3 = "98799b9f-1c5e-30b3-930f-e412b862cbe4", + .uuid5 = "f2b4caea-61c3-5bed-8ce7-d8b9d16e129e", + }, + { + .uuid3 = "9bdf2544-31d8-3555-94b0-6a749118a996", + .uuid5 = "3593855a-6557-5736-8cab-172c6987f949", + }, + { + .uuid3 = "ddcfb9b3-e990-3985-9021-546a2711e7e5", + .uuid5 = "36392431-d554-5385-b876-7bc6e1cb26b3", + }, + { + .uuid3 = "190d7a78-1484-3136-80a6-40f28852785c", + .uuid5 = "7e645493-0898-5501-8155-e8578b4f5224", + }, + { + .uuid3 = "6ed693e4-7dc0-3210-856b-a6eb4cc73e13", + .uuid5 = "14dc6a81-0491-5683-baaf-7582a61c5798", + }, + { + .uuid3 = "b6a14b21-e73a-3ce2-9076-a804c434f5c6", + .uuid5 = "883e0a9c-e3b3-5f9c-8073-2913cbbb99ec", + }, + }; + char i_str[30]; + guint i; + + _test_uuid(NM_UTILS_UUID_TYPE_LEGACY, "d41d8cd9-8f00-b204-e980-0998ecf8427e", "", -1, NULL); + _test_uuid(NM_UTILS_UUID_TYPE_LEGACY, "0cc175b9-c0f1-b6a8-31c3-99e269772661", "a", -1, NULL); + _test_uuid(NM_UTILS_UUID_TYPE_LEGACY, "098f6bcd-4621-d373-cade-4e832627b4f6", "test", -1, NULL); + _test_uuid(NM_UTILS_UUID_TYPE_LEGACY, "70350f60-27bc-e371-3f6b-76473084309b", "a\0b", 3, NULL); + _test_uuid(NM_UTILS_UUID_TYPE_LEGACY, + "59c0547b-7fe2-1c15-2cce-e328e8bf6742", + "/etc/NetworkManager/system-connections/em1", + -1, + NULL); + + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, "4ae71336-e44b-39bf-b9d2-752e234818a5", "", -1, NULL); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, "0531103a-d8fc-3dd4-b972-d98e4750994e", "a", -1, NULL); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "96e17d7a-ac89-38cf-95e1-bf5098da34e1", + "test", + -1, + NULL); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "8156568e-4ae6-3f34-a93e-18e2c6cbbf78", + "a\0b", + 3, + NULL); + + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "c87ee674-4ddc-3efe-a74e-dfe25da5d7b3", + "", + -1, + UUID_NS_DNS); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "4c104dd0-4821-30d5-9ce3-0e7a1f8b7c0d", + "a", + -1, + UUID_NS_DNS); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "45a113ac-c7f2-30b0-90a5-a399ab912716", + "test", + -1, + UUID_NS_DNS); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "002a0ada-f547-375a-bab5-896a11d1927e", + "a\0b", + 3, + UUID_NS_DNS); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "9a75f5f2-195e-31a9-9d07-8c18b5d3b285", + "test123", + -1, + UUID_NS_DNS); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "ec794efe-a384-3b11-a0b6-ec8995bc6acc", + "x", + -1, + UUID_NS_DNS); + + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, + "a7650b9f-f19f-5300-8a13-91160ea8de2c", + "a\0b", + 3, + NULL); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, + "4f3f2898-69e3-5a0d-820a-c4e87987dbce", + "a", + -1, + UUID_NS_DNS); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, + "05b16a01-46c6-56dd-bd6e-c6dfb4a1427a", + "x", + -1, + UUID_NS_DNS); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, + "c9ed566a-6b79-5d3a-b2b7-96a936b48cf3", + "test123", + -1, + UUID_NS_DNS); + + for (i = 0; i < G_N_ELEMENTS(zero_uuids); i++) { + nm_sprintf_buf(i_str, "%u", i), + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, zero_uuids[i].uuid3, i_str, -1, NULL); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, zero_uuids[i].uuid5, i_str, -1, NULL); + } + for (i = 0; i < G_N_ELEMENTS(dns_uuids); i++) { + nm_sprintf_buf(i_str, "%u", i), + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, dns_uuids[i].uuid3, i_str, -1, UUID_NS_DNS); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, dns_uuids[i].uuid5, i_str, -1, UUID_NS_DNS); + } + + /* examples from cpython unit tests: */ + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "6fa459ea-ee8a-3ca4-894e-db77e160355e", + "python.org", + -1, + UUID_NS_DNS); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, + "886313e1-3b8a-5372-9b90-0c9aee199e5d", + "python.org", + -1, + UUID_NS_DNS); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "9fe8e8c4-aaa8-32a9-a55c-4535a88b748d", + "http://python.org/", + -1, + UUID_NS_URL); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, + "4c565f0d-3f5a-5890-b41b-20cf47701c5e", + "http://python.org/", + -1, + UUID_NS_URL); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "dd1a1cef-13d5-368a-ad82-eca71acd4cd1", + "1.3.6.1", + -1, + UUID_NS_OID); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, + "1447fa61-5277-5fef-a9b3-fbc6e44f4af3", + "1.3.6.1", + -1, + UUID_NS_OID); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION3, + "658d3002-db6b-3040-a1d1-8ddd7d189a4d", + "c=ca", + -1, + UUID_NS_X500); + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, + "cc957dd1-a972-5349-98cd-874190002798", + "c=ca", + -1, + UUID_NS_X500); + + _test_uuid(NM_UTILS_UUID_TYPE_VERSION5, + "74738ff5-5367-5958-9aee-98fffdcd1876", + "www.example.org", + -1, + UUID_NS_DNS); +} + +/*****************************************************************************/ + +static void +__test_uuid(const char *expected_uuid, const char *str, gssize slen, char *uuid_test) +{ + g_assert(uuid_test); + g_assert(nm_utils_is_uuid(uuid_test)); + + if (strcmp(uuid_test, expected_uuid)) { + g_error("UUID test failed (1): text=%s, len=%lld, expected=%s, uuid_test=%s", + str, + (long long) slen, + expected_uuid, + uuid_test); + } + g_free(uuid_test); + + uuid_test = nm_utils_uuid_generate_from_string(str, + slen, + NM_UTILS_UUID_TYPE_VERSION3, + NM_UTILS_UUID_NS); + + g_assert(uuid_test); + g_assert(nm_utils_is_uuid(uuid_test)); + + if (strcmp(uuid_test, expected_uuid)) { + g_error("UUID test failed (2): text=%s; len=%lld, expected=%s, uuid2=%s", + str, + (long long) slen, + expected_uuid, + uuid_test); + } + g_free(uuid_test); +} + +#define _test_uuid(expected_uuid, str, strlen, ...) \ + __test_uuid(expected_uuid, str, strlen, _nm_utils_uuid_generate_from_strings(__VA_ARGS__, NULL)) + +static void +test_nm_utils_uuid_generate_from_strings(void) +{ + const NMUuid uuid0 = {}; + + g_assert_cmpmem(&uuid0, sizeof(uuid0), _uuid("00000000-0000-0000-0000-000000000000"), 16); + + g_assert(nm_utils_uuid_is_null(NULL)); + g_assert(nm_utils_uuid_is_null(&uuid0)); + g_assert(nm_utils_uuid_is_null(_uuid("00000000-0000-0000-0000-000000000000"))); + g_assert(!nm_utils_uuid_is_null(_uuid("10000000-0000-0000-0000-000000000000"))); + + _test_uuid("b07c334a-399b-32de-8d50-58e4e08f98e3", "", 0, NULL); + _test_uuid("b8a426cb-bcb5-30a3-bd8f-6786fea72df9", "\0", 1, ""); + _test_uuid("12a4a982-7aae-39e1-951e-41aeb1250959", "a\0", 2, "a"); + _test_uuid("69e22c7e-f89f-3a43-b239-1cb52ed8db69", "aa\0", 3, "aa"); + _test_uuid("59829fd3-5ad5-3d90-a7b0-4911747e4088", "\0\0", 2, "", ""); + _test_uuid("01ad0e06-6c50-3384-8d86-ddab81421425", "a\0\0", 3, "a", ""); + _test_uuid("e1ed8647-9ed3-3ec8-8c6d-e8204524d71d", "aa\0\0", 4, "aa", ""); + _test_uuid("fb1c7cd6-275c-3489-9382-83b900da8af0", "\0a\0", 3, "", "a"); + _test_uuid("5d79494e-c4ba-31a6-80a2-d6016ccd7e17", "a\0a\0", 4, "a", "a"); + _test_uuid("fd698d86-1b60-3ebe-855f-7aada9950a8d", "aa\0a\0", 5, "aa", "a"); + _test_uuid("8c573b48-0f01-30ba-bb94-c5f59f4fe517", "\0aa\0", 4, "", "aa"); + _test_uuid("2bdd3d46-eb83-3c53-a41b-a724d04b5544", "a\0aa\0", 5, "a", "aa"); + _test_uuid("13d4b780-07c1-3ba7-b449-81c4844ef039", "aa\0aa\0", 6, "aa", "aa"); + _test_uuid("dd265bf7-c05a-3037-9939-b9629858a477", "a\0b\0", 4, "a", "b"); +} + +/*****************************************************************************/ + +static void +test_nm_utils_ascii_str_to_int64_check(const char *str, + guint base, + gint64 min, + gint64 max, + gint64 fallback, + int exp_errno, + gint64 exp_val) +{ + gint64 v; + + errno = 1; + v = _nm_utils_ascii_str_to_int64(str, base, min, max, fallback); + g_assert_cmpint(errno, ==, exp_errno); + g_assert_cmpint(v, ==, exp_val); +} + +static void +test_nm_utils_ascii_str_to_int64_do(const char *str, + guint base, + gint64 min, + gint64 max, + gint64 fallback, + int exp_errno, + gint64 exp_val) +{ + const char * sign = ""; + const char * val; + static const char *whitespaces[] = { + "", + " ", + "\r\n\t", + " \r\n\t ", + " \r\n\t \t\r\n\t", + NULL, + }; + static const char *nulls[] = { + "", + "0", + "00", + "0000", + "0000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000", + NULL, + }; + const char **ws_pre, **ws_post, **null; + guint i; + + if (str == NULL || exp_errno != 0) { + test_nm_utils_ascii_str_to_int64_check(str, base, min, max, fallback, exp_errno, exp_val); + return; + } + + if (strncmp(str, "-", 1) == 0) + sign = "-"; + + val = str + strlen(sign); + + for (ws_pre = whitespaces; *ws_pre; ws_pre++) { + for (ws_post = whitespaces; *ws_post; ws_post++) { + for (null = nulls; *null; null++) { + for (i = 0;; i++) { + char * s; + const char *str_base = ""; + + if (base == 16) { + if (i == 1) + str_base = "0x"; + else if (i > 1) + break; + } else if (base == 8) { + if (i == 1) + str_base = "0"; + else if (i > 1) + break; + } else if (base == 0) { + if (i > 0) + break; + /* with base==0, a leading zero would be interpreted as octal. Only test without *null */ + if ((*null)[0]) + break; + } else { + if (i > 0) + break; + } + + s = g_strdup_printf("%s%s%s%s%s%s", + *ws_pre, + sign, + str_base, + *null, + val, + *ws_post); + + test_nm_utils_ascii_str_to_int64_check(s, + base, + min, + max, + fallback, + exp_errno, + exp_val); + g_free(s); + } + } + } + } +} + +static void +test_nm_utils_ascii_str_to_int64(void) +{ + test_nm_utils_ascii_str_to_int64_do(NULL, 10, 0, 10000, -1, EINVAL, -1); + test_nm_utils_ascii_str_to_int64_do("", 10, 0, 10000, -1, EINVAL, -1); + test_nm_utils_ascii_str_to_int64_do("1x", 10, 0, 10000, -1, EINVAL, -1); + test_nm_utils_ascii_str_to_int64_do("4711", 10, 0, 10000, -1, 0, 4711); + test_nm_utils_ascii_str_to_int64_do("10000", 10, 0, 10000, -1, 0, 10000); + test_nm_utils_ascii_str_to_int64_do("10001", 10, 0, 10000, -1, ERANGE, -1); + test_nm_utils_ascii_str_to_int64_do("FF", 16, 0, 10000, -1, 0, 255); + test_nm_utils_ascii_str_to_int64_do("FF", 10, 0, 10000, -2, EINVAL, -2); + test_nm_utils_ascii_str_to_int64_do("9223372036854775807", + 10, + 0, + G_MAXINT64, + -2, + 0, + G_MAXINT64); + test_nm_utils_ascii_str_to_int64_do("7FFFFFFFFFFFFFFF", 16, 0, G_MAXINT64, -2, 0, G_MAXINT64); + test_nm_utils_ascii_str_to_int64_do("9223372036854775808", 10, 0, G_MAXINT64, -2, ERANGE, -2); + test_nm_utils_ascii_str_to_int64_do("-9223372036854775808", + 10, + G_MININT64, + 0, + -2, + 0, + G_MININT64); + test_nm_utils_ascii_str_to_int64_do("-9223372036854775808", + 10, + G_MININT64 + 1, + 0, + -2, + ERANGE, + -2); + test_nm_utils_ascii_str_to_int64_do("-9223372036854775809", 10, G_MININT64, 0, -2, ERANGE, -2); + test_nm_utils_ascii_str_to_int64_do("1.0", 10, 1, 1, -1, EINVAL, -1); + test_nm_utils_ascii_str_to_int64_do("1x0", 16, -10, 10, -100, EINVAL, -100); + test_nm_utils_ascii_str_to_int64_do("0", 16, -10, 10, -100, 0, 0); + test_nm_utils_ascii_str_to_int64_do("10001111", 2, -1000, 1000, -100000, 0, 0x8F); + test_nm_utils_ascii_str_to_int64_do("-10001111", 2, -1000, 1000, -100000, 0, -0x8F); + test_nm_utils_ascii_str_to_int64_do("1111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7F); + test_nm_utils_ascii_str_to_int64_do("111111111111111", + 2, + G_MININT64, + G_MAXINT64, + -1, + 0, + 0x7FFF); + test_nm_utils_ascii_str_to_int64_do("11111111111111111111111111111111111111111111111", + 2, + G_MININT64, + G_MAXINT64, + -1, + 0, + 0x7FFFFFFFFFFF); + test_nm_utils_ascii_str_to_int64_do( + "111111111111111111111111111111111111111111111111111111111111111", + 2, + G_MININT64, + G_MAXINT64, + -1, + 0, + 0x7FFFFFFFFFFFFFFF); + test_nm_utils_ascii_str_to_int64_do( + "100000000000000000000000000000000000000000000000000000000000000", + 2, + G_MININT64, + G_MAXINT64, + -1, + 0, + 0x4000000000000000); + test_nm_utils_ascii_str_to_int64_do( + "1000000000000000000000000000000000000000000000000000000000000000", + 2, + G_MININT64, + G_MAXINT64, + -1, + ERANGE, + -1); + test_nm_utils_ascii_str_to_int64_do( + "-100000000000000000000000000000000000000000000000000000000000000", + 2, + G_MININT64, + G_MAXINT64, + -1, + 0, + -0x4000000000000000); + test_nm_utils_ascii_str_to_int64_do( + "111111111111111111111111111111111111111111111111111111111111111", + 2, + G_MININT64, + G_MAXINT64, + -1, + 0, + 0x7FFFFFFFFFFFFFFF); + test_nm_utils_ascii_str_to_int64_do( + "-100000000000000000000000000000000000000000000000000000000000000", + 2, + G_MININT64, + G_MAXINT64, + -1, + 0, + -0x4000000000000000); + test_nm_utils_ascii_str_to_int64_do("0x70", 10, G_MININT64, G_MAXINT64, -1, EINVAL, -1); + test_nm_utils_ascii_str_to_int64_do("4711", 0, G_MININT64, G_MAXINT64, -1, 0, 4711); + test_nm_utils_ascii_str_to_int64_do("04711", 0, G_MININT64, G_MAXINT64, -1, 0, 04711); + test_nm_utils_ascii_str_to_int64_do("0x4711", 0, G_MININT64, G_MAXINT64, -1, 0, 0x4711); + test_nm_utils_ascii_str_to_int64_do("080", 0, G_MININT64, G_MAXINT64, -1, EINVAL, -1); + test_nm_utils_ascii_str_to_int64_do("070", 0, G_MININT64, G_MAXINT64, -1, 0, 7 * 8); + test_nm_utils_ascii_str_to_int64_do("0x70", 0, G_MININT64, G_MAXINT64, -1, 0, 0x70); + + g_assert_cmpint(21, ==, _nm_utils_ascii_str_to_int64("025", 0, 0, 1000, -1)); + g_assert_cmpint(21, ==, _nm_utils_ascii_str_to_int64("0025", 0, 0, 1000, -1)); + g_assert_cmpint(25, ==, _nm_utils_ascii_str_to_int64("025", 10, 0, 1000, -1)); + g_assert_cmpint(25, ==, _nm_utils_ascii_str_to_int64("0025", 10, 0, 1000, -1)); +} + +/*****************************************************************************/ + +static void +test_nm_utils_strstrdictkey(void) +{ +#define _VALUES_STATIC(_v1, _v2) \ + { \ + .v1 = _v1, .v2 = _v2, .v_static = _nm_utils_strstrdictkey_static(_v1, _v2), \ + } + const struct { + const char * v1; + const char * v2; + NMUtilsStrStrDictKey *v_static; + } * val1, *val2, + values[] = { + {NULL, NULL}, + {"", NULL}, + {NULL, ""}, + {"a", NULL}, + {NULL, "a"}, + _VALUES_STATIC("", ""), + _VALUES_STATIC("a", ""), + _VALUES_STATIC("", "a"), + _VALUES_STATIC("a", "b"), + }; + guint i, j; + + for (i = 0; i < G_N_ELEMENTS(values); i++) { + gs_free NMUtilsStrStrDictKey *key1 = NULL; + + val1 = &values[i]; + + key1 = _nm_utils_strstrdictkey_create(val1->v1, val1->v2); + if (val1->v_static) { + g_assert(_nm_utils_strstrdictkey_equal(key1, val1->v_static)); + g_assert(_nm_utils_strstrdictkey_equal(val1->v_static, key1)); + g_assert_cmpint(_nm_utils_strstrdictkey_hash(key1), + ==, + _nm_utils_strstrdictkey_hash(val1->v_static)); + } + + for (j = 0; j < G_N_ELEMENTS(values); j++) { + gs_free NMUtilsStrStrDictKey *key2 = NULL; + + val2 = &values[j]; + key2 = _nm_utils_strstrdictkey_create(val2->v1, val2->v2); + if (i != j) { + g_assert(!_nm_utils_strstrdictkey_equal(key1, key2)); + g_assert(!_nm_utils_strstrdictkey_equal(key2, key1)); + } + } + } +} + +/*****************************************************************************/ + +static guint +_g_strv_length(gconstpointer arr) +{ + return arr ? g_strv_length((char **) arr) : 0; +} + +static void +test_nm_ptrarray_len(void) +{ +#define _PTRARRAY_cmp(len, arr) \ + G_STMT_START \ + { \ + g_assert_cmpint(len, ==, NM_PTRARRAY_LEN(arr)); \ + g_assert_cmpint(len, ==, _g_strv_length(arr)); \ + } \ + G_STMT_END +#define _PTRARRAY_LEN0(T) \ + G_STMT_START \ + { \ + T ** vnull = NULL; \ + T *const * vnull1 = NULL; \ + T *const *const vnull2 = NULL; \ + T * v0[] = {NULL}; \ + T *const * v01 = v0; \ + T *const *const v02 = v0; \ + T **const v03 = v0; \ + \ + _PTRARRAY_cmp(0, vnull); \ + _PTRARRAY_cmp(0, vnull1); \ + _PTRARRAY_cmp(0, vnull2); \ + _PTRARRAY_cmp(0, v0); \ + _PTRARRAY_cmp(0, v01); \ + _PTRARRAY_cmp(0, v02); \ + _PTRARRAY_cmp(0, v03); \ + } \ + G_STMT_END + + _PTRARRAY_LEN0(char); + _PTRARRAY_LEN0(const char); + _PTRARRAY_LEN0(int); + _PTRARRAY_LEN0(const int); + _PTRARRAY_LEN0(void *); + _PTRARRAY_LEN0(void); + _PTRARRAY_LEN0(const void); + +#define _PTRARRAY_LENn(T) \ + G_STMT_START \ + { \ + T x[5] = {0}; \ + \ + T * v1[] = {&x[0], NULL}; \ + T *const * v11 = v1; \ + T *const *const v12 = v1; \ + T **const v13 = v1; \ + \ + T * v2[] = {&x[0], &x[1], NULL}; \ + T *const * v21 = v2; \ + T *const *const v22 = v2; \ + T **const v23 = v2; \ + \ + _PTRARRAY_cmp(1, v1); \ + _PTRARRAY_cmp(1, v11); \ + _PTRARRAY_cmp(1, v12); \ + _PTRARRAY_cmp(1, v13); \ + \ + _PTRARRAY_cmp(2, v2); \ + _PTRARRAY_cmp(2, v21); \ + _PTRARRAY_cmp(2, v22); \ + _PTRARRAY_cmp(2, v23); \ + } \ + G_STMT_END + + _PTRARRAY_LENn(char); + _PTRARRAY_LENn(const char); + _PTRARRAY_LENn(int); + _PTRARRAY_LENn(const int); + _PTRARRAY_LENn(void *); +} + +/*****************************************************************************/ + +static void +test_nm_utils_dns_option_validate_do(char * option, + gboolean ipv6, + const NMUtilsDNSOptionDesc *descs, + gboolean exp_result, + char * exp_name, + gboolean exp_value) +{ + char * name; + long value = 0; + gboolean result; + + result = _nm_utils_dns_option_validate(option, &name, &value, ipv6, descs); + + g_assert(result == exp_result); + g_assert_cmpstr(name, ==, exp_name); + g_assert(value == exp_value); + + g_free(name); +} + +static const NMUtilsDNSOptionDesc opt_descs[] = { + /* name num ipv6 */ + {"opt1", FALSE, FALSE}, + {"opt2", TRUE, FALSE}, + {"opt3", FALSE, TRUE}, + {"opt4", TRUE, TRUE}, + {NULL, FALSE, FALSE}}; + +static void +test_nm_utils_dns_option_validate(void) +{ + /* opt ipv6 descs result name value */ + test_nm_utils_dns_option_validate_do("", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do(":", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do(":1", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do(":val", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt", FALSE, NULL, TRUE, "opt", -1); + test_nm_utils_dns_option_validate_do("opt:", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt:12", FALSE, NULL, TRUE, "opt", 12); + test_nm_utils_dns_option_validate_do("opt:12 ", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt:val", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt:2val", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt:2:3", FALSE, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt-6", FALSE, NULL, TRUE, "opt-6", -1); + + test_nm_utils_dns_option_validate_do("opt1", FALSE, opt_descs, TRUE, "opt1", -1); + test_nm_utils_dns_option_validate_do("opt1", TRUE, opt_descs, TRUE, "opt1", -1); + test_nm_utils_dns_option_validate_do("opt1:3", FALSE, opt_descs, FALSE, NULL, -1); + + test_nm_utils_dns_option_validate_do("opt2", FALSE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt2:5", FALSE, opt_descs, TRUE, "opt2", 5); + + test_nm_utils_dns_option_validate_do("opt3", FALSE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt3", TRUE, opt_descs, TRUE, "opt3", -1); + + test_nm_utils_dns_option_validate_do("opt4", FALSE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt4", TRUE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt4:40", FALSE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt4:40", TRUE, opt_descs, TRUE, "opt4", 40); +} + +static void +test_nm_utils_dns_option_find_idx(void) +{ + GPtrArray *options; + + options = g_ptr_array_new(); + + g_ptr_array_add(options, "debug"); + g_ptr_array_add(options, "timeout:5"); + g_ptr_array_add(options, "edns0"); + + g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "debug"), ==, 0); + g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "debug:1"), ==, 0); + g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "timeout"), ==, 1); + g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "timeout:5"), ==, 1); + g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "timeout:2"), ==, 1); + g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "edns0"), ==, 2); + g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "rotate"), ==, -1); + g_assert_cmpint(_nm_utils_dns_option_find_idx(options, ""), ==, -1); + + g_ptr_array_free(options, TRUE); +} + +/*****************************************************************************/ + +static void +_json_config_check_valid(const char *conf, gboolean expected) +{ + gs_free_error GError *error = NULL; + gboolean res; + + res = nm_utils_is_json_object(conf, &error); + g_assert_cmpint(res, ==, expected); + g_assert(res || error); +} + +static void +test_nm_utils_check_valid_json(void) +{ + _json_config_check_valid(NULL, FALSE); + _json_config_check_valid("", FALSE); + + /* Without JSON library everything except empty string is considered valid */ + nmtst_json_vt_reset(FALSE); + _json_config_check_valid("{ }", TRUE); + _json_config_check_valid("{'%!-a1} ", TRUE); + _json_config_check_valid(" {'%!-a1}", TRUE); + _json_config_check_valid("{'%!-a1", FALSE); + + if (nmtst_json_vt_reset(TRUE)) { + _json_config_check_valid("{ }", TRUE); + _json_config_check_valid("{ \"a\" : 1 }", TRUE); + _json_config_check_valid("{ \"a\" : }", FALSE); + } +} + +static void +_team_config_equal_check(const char *conf1, + const char *conf2, + gboolean port_config, + gboolean expected) +{ + nm_auto_free_team_setting NMTeamSetting *team_a = NULL; + nm_auto_free_team_setting NMTeamSetting *team_b = NULL; + gboolean is_same; + + if (nmtst_get_rand_bool()) + NM_SWAP(&conf1, &conf2); + + if (!nm_streq0(conf1, conf2)) { + _team_config_equal_check(conf1, conf1, port_config, TRUE); + _team_config_equal_check(conf2, conf2, port_config, TRUE); + } + + team_a = nm_team_setting_new(port_config, conf1); + team_b = nm_team_setting_new(port_config, conf2); + + is_same = (nm_team_setting_cmp(team_a, team_b, TRUE) == 0); + g_assert_cmpint(is_same, ==, expected); + + if (nm_streq0(conf1, conf2)) { + g_assert_cmpint(nm_team_setting_cmp(team_a, team_b, FALSE), ==, 0); + g_assert(expected); + } else + g_assert_cmpint(nm_team_setting_cmp(team_a, team_b, FALSE), !=, 0); +} + +static void +test_nm_utils_team_config_equal(void) +{ + int with_json_vt; + + for (with_json_vt = 0; with_json_vt < 2; with_json_vt++) { + const NMJsonVt *vt; + + vt = nmtst_json_vt_reset(!!with_json_vt); + + _team_config_equal_check("", "", TRUE, TRUE); + _team_config_equal_check("", " ", TRUE, TRUE); + _team_config_equal_check("{}", "{ }", TRUE, TRUE); + _team_config_equal_check("{}", "{", TRUE, TRUE); + _team_config_equal_check("{ \"a\": 1 }", "{ \"a\": 1 }", TRUE, TRUE); + _team_config_equal_check("{ \"a\": 1 }", "{ \"a\": 1 }", TRUE, TRUE); + + /* team config */ + _team_config_equal_check("{ }", "{ \"runner\" : { \"name\" : \"random\"} }", FALSE, !vt); + _team_config_equal_check("{ \"runner\" : { \"name\" : \"roundrobin\"} }", + "{ \"runner\" : { \"name\" : \"random\"} }", + FALSE, + !vt); + _team_config_equal_check("{ \"runner\" : { \"name\" : \"random\"} }", + "{ \"runner\" : { \"name\" : \"random\"} }", + FALSE, + TRUE); + _team_config_equal_check("{ \"runner\" : { \"name\" : \"loadbalance\"} }", + "{ \"runner\" : { \"name\" : \"loadbalance\"} }", + FALSE, + TRUE); + _team_config_equal_check( + "{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth0\" : {} } }", + "{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth1\" : {} } }", + FALSE, + TRUE); + _team_config_equal_check("{ \"runner\" : { \"name\" : \"lacp\"} }", + "{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\", " + "\"ipv4\", \"ipv6\" ] } }", + FALSE, + !vt); + _team_config_equal_check("{ \"runner\" : { \"name\" : \"roundrobin\"} }", + "{ \"runner\" : { \"name\" : \"roundrobin\", \"tx_hash\" : [ " + "\"eth\", \"ipv4\", \"ipv6\" ] } }", + FALSE, + !vt); + _team_config_equal_check( + "{ \"runner\" : { \"name\" : \"lacp\"} }", + "{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\" ] } }", + FALSE, + !vt); + + /* team port config */ + _team_config_equal_check("{ }", + "{ \"link_watch\" : { \"name\" : \"ethtool\"} }", + TRUE, + !vt); + _team_config_equal_check("{ }", + "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", + TRUE, + TRUE); + _team_config_equal_check("{ \"link_watch\" : { \"name\" : \"ethtool\"} }", + "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", + TRUE, + !vt); + _team_config_equal_check("{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", + "{ \"link_watch\" : { \"name\" : \"arp_ping\"} }", + TRUE, + TRUE); + _team_config_equal_check( + "{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth0\" : {} } }", + "{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth1\" : {} } }", + TRUE, + TRUE); + } + + nmtst_json_vt_reset(TRUE); +} + +/*****************************************************************************/ + +enum TEST_IS_POWER_OF_TWP_ENUM_SIGNED { + _DUMMY_1 = -1, +}; + +enum TEST_IS_POWER_OF_TWP_ENUM_UNSIGNED { + _DUMMY_2, +}; + +enum TEST_IS_POWER_OF_TWP_ENUM_SIGNED_64 { + _DUMMY_3 = (1LL << 40), +}; + +enum TEST_IS_POWER_OF_TWP_ENUM_UNSIGNED_64 { + _DUMMY_4a = -1, + _DUMMY_4b = (1LL << 40), +}; + +#define test_nm_utils_is_power_of_two_do(type, x, expect) \ + G_STMT_START \ + { \ + typeof(x) x1 = (x); \ + type x2 = (type) x1; \ + gboolean val; \ + \ + val = nm_utils_is_power_of_two(x1); \ + g_assert_cmpint(expect, ==, val); \ + if (x1 != 0) \ + g_assert_cmpint(val, ==, nm_utils_is_power_of_two_or_zero(x1)); \ + else { \ + g_assert(nm_utils_is_power_of_two_or_zero(x1)); \ + g_assert(!val); \ + } \ + if (((typeof(x1)) x2) == x1 && ((typeof(x2)) x1) == x2 && x2 > 0) { \ + /* x2 equals @x, and is positive. Compare to @expect */ \ + g_assert_cmpint(expect, ==, nm_utils_is_power_of_two(x2)); \ + } else if (!(x2 > 0)) { \ + /* a non positive value is always FALSE. */ \ + g_assert_cmpint(FALSE, ==, nm_utils_is_power_of_two(x2)); \ + } \ + if (x2) { \ + x2 = -x2; \ + if (!(x2 > 0)) { \ + /* for negative values, we return FALSE. */ \ + g_assert_cmpint(FALSE, ==, nm_utils_is_power_of_two(x2)); \ + } \ + } \ + } \ + G_STMT_END + +static void +test_nm_utils_is_power_of_two(void) +{ + guint64 xyes, xno; + int i, j; + GRand * rand = nmtst_get_rand(); + int numbits; + + g_assert(!nm_utils_is_power_of_two(0)); + g_assert(nm_utils_is_power_of_two_or_zero(0)); + + for (i = -1; i < 64; i++) { + /* find a (positive) x which is a power of two. */ + if (i == -1) + xyes = 0; + else { + xyes = (((guint64) 1) << i); + g_assert(xyes != 0); + } + + xno = xyes; + if (xyes != 0) { +again: + /* Find another @xno, that is not a power of two. Do that, + * by randomly setting bits. */ + numbits = g_rand_int_range(rand, 1, 65); + while (xno != ~((guint64) 0) && numbits > 0) { + guint64 v = (((guint64) 1) << g_rand_int_range(rand, 0, 64)); + + if ((xno | v) != xno) { + xno |= v; + --numbits; + } + } + if (xno == xyes) + goto again; + } + + for (j = 0; j < 2; j++) { + gboolean expect = j == 0; + guint64 x = expect ? xyes : xno; + + if (expect && xyes == 0) + continue; + + /* check if @x is as @expect, when casted to a certain data type. */ + test_nm_utils_is_power_of_two_do(gint8, x, expect); + test_nm_utils_is_power_of_two_do(guint8, x, expect); + test_nm_utils_is_power_of_two_do(gint16, x, expect); + test_nm_utils_is_power_of_two_do(guint16, x, expect); + test_nm_utils_is_power_of_two_do(gint32, x, expect); + test_nm_utils_is_power_of_two_do(guint32, x, expect); + test_nm_utils_is_power_of_two_do(gint64, x, expect); + test_nm_utils_is_power_of_two_do(guint64, x, expect); + test_nm_utils_is_power_of_two_do(char, x, expect); + test_nm_utils_is_power_of_two_do(unsigned char, x, expect); + test_nm_utils_is_power_of_two_do(signed char, x, expect); + test_nm_utils_is_power_of_two_do(enum TEST_IS_POWER_OF_TWP_ENUM_SIGNED, x, expect); + test_nm_utils_is_power_of_two_do(enum TEST_IS_POWER_OF_TWP_ENUM_UNSIGNED, x, expect); + test_nm_utils_is_power_of_two_do(enum TEST_IS_POWER_OF_TWP_ENUM_SIGNED_64, x, expect); + test_nm_utils_is_power_of_two_do(enum TEST_IS_POWER_OF_TWP_ENUM_UNSIGNED_64, x, expect); + } + } +} + +/*****************************************************************************/ + +static int +_test_find_binary_search_cmp(gconstpointer a, gconstpointer b, gpointer dummy) +{ + int ia, ib; + + ia = GPOINTER_TO_INT(a); + ib = GPOINTER_TO_INT(b); + + if (ia == ib) + return 0; + if (ia < ib) + return -1; + return 1; +} + +static void +_test_find_binary_search_do(const int *array, gsize len) +{ + gsize i; + gssize idx, idx2, idx_first, idx_last; + gs_free gconstpointer *parray = g_new(gconstpointer, len); + const int NEEDLE = 0; + gconstpointer pneedle = GINT_TO_POINTER(NEEDLE); + gssize expected_result; + + for (i = 0; i < len; i++) + parray[i] = GINT_TO_POINTER(array[i]); + + expected_result = nm_utils_ptrarray_find_first(parray, len, pneedle); + + idx = nm_utils_ptrarray_find_binary_search_range(parray, + len, + pneedle, + _test_find_binary_search_cmp, + NULL, + &idx_first, + &idx_last); + + idx2 = nm_utils_ptrarray_find_binary_search(parray, + len, + pneedle, + _test_find_binary_search_cmp, + NULL); + g_assert_cmpint(idx, ==, idx2); + + if (expected_result >= 0) { + g_assert_cmpint(expected_result, ==, idx); + } else { + idx2 = ~idx; + + g_assert_cmpint(idx, <, 0); + + g_assert(idx2 >= 0); + g_assert(idx2 <= len); + g_assert(idx2 - 1 < 0 || _test_find_binary_search_cmp(parray[idx2 - 1], pneedle, NULL) < 0); + g_assert(idx2 >= len || _test_find_binary_search_cmp(parray[idx2], pneedle, NULL) > 0); + } + g_assert_cmpint(idx, ==, idx_first); + g_assert_cmpint(idx, ==, idx_last); + for (i = 0; i < len; i++) { + int cmp; + + cmp = _test_find_binary_search_cmp(parray[i], pneedle, NULL); + if (cmp == 0) { + g_assert(pneedle == parray[i]); + g_assert(idx >= 0); + g_assert(i == idx); + } else { + g_assert(pneedle != parray[i]); + if (cmp < 0) { + if (idx < 0) + g_assert(i < ~idx); + else + g_assert(i < idx); + } else { + if (idx < 0) + g_assert(i >= ~idx); + else + g_assert(i >= idx); + } + } + } +} + +static void +_test_find_binary_search_do_uint32(const int *int_array, gsize len) +{ + gssize idx; + const int OFFSET = 100; + const int NEEDLE = 0 + OFFSET; + gssize expected_result = -1; + guint32 array[30]; + + g_assert(len <= G_N_ELEMENTS(array)); + + /* the test data has negative values. Shift them... */ + for (idx = 0; idx < len; idx++) { + int v = int_array[idx]; + + g_assert(v > -OFFSET); + g_assert(v < OFFSET); + g_assert(idx == 0 || v > int_array[idx - 1]); + array[idx] = (guint32)(int_array[idx] + OFFSET); + if (array[idx] == NEEDLE) + expected_result = idx; + } + + idx = nm_utils_array_find_binary_search(array, + sizeof(guint32), + len, + &NEEDLE, + nm_cmp_uint32_p_with_data, + NULL); + if (expected_result >= 0) + g_assert_cmpint(expected_result, ==, idx); + else { + gssize idx2 = ~idx; + g_assert_cmpint(idx, <, 0); + + g_assert(idx2 >= 0); + g_assert(idx2 <= len); + g_assert(idx2 - 1 < 0 || array[idx2 - 1] < NEEDLE); + g_assert(idx2 >= len || array[idx2] > NEEDLE); + } +} +#define test_find_binary_search_do(...) \ + G_STMT_START \ + { \ + const int _array[] = {__VA_ARGS__}; \ + _test_find_binary_search_do(_array, G_N_ELEMENTS(_array)); \ + _test_find_binary_search_do_uint32(_array, G_N_ELEMENTS(_array)); \ + } \ + G_STMT_END + +static void +test_nm_utils_ptrarray_find_binary_search(void) +{ + test_find_binary_search_do(0); + test_find_binary_search_do(-1, 0); + test_find_binary_search_do(-2, -1, 0); + test_find_binary_search_do(-3, -2, -1, 0); + test_find_binary_search_do(0, 1); + test_find_binary_search_do(0, 1, 2); + test_find_binary_search_do(-1, 0, 1, 2); + test_find_binary_search_do(-2, -1, 0, 1, 2); + test_find_binary_search_do(-3, -2, -1, 0, 1, 2); + test_find_binary_search_do(-3, -2, -1, 0, 1, 2); + test_find_binary_search_do(-3, -2, -1, 0, 1, 2, 3); + test_find_binary_search_do(-3, -2, -1, 0, 1, 2, 3, 4); + + test_find_binary_search_do(-1); + test_find_binary_search_do(-2, -1); + test_find_binary_search_do(-3, -2, -1); + test_find_binary_search_do(1); + test_find_binary_search_do(1, 2); + test_find_binary_search_do(-1, 1, 2); + test_find_binary_search_do(-2, -1, 1, 2); + test_find_binary_search_do(-3, -2, -1, 1, 2); + test_find_binary_search_do(-3, -2, -1, 1, 2); + test_find_binary_search_do(-3, -2, -1, 1, 2, 3); + test_find_binary_search_do(-3, -2, -1, 1, 2, 3, 4); +} + +/*****************************************************************************/ + +#define BIN_SEARCH_W_DUPS_LEN 100 +#define BIN_SEARCH_W_DUPS_JITTER 10 + +static int +_test_bin_search2_cmp(gconstpointer pa, gconstpointer pb, gpointer user_data) +{ + int a = GPOINTER_TO_INT(pa); + int b = GPOINTER_TO_INT(pb); + + g_assert(a >= 0 && a <= BIN_SEARCH_W_DUPS_LEN + BIN_SEARCH_W_DUPS_JITTER); + g_assert(b >= 0 && b <= BIN_SEARCH_W_DUPS_LEN + BIN_SEARCH_W_DUPS_JITTER); + NM_CMP_DIRECT(a, b); + return 0; +} + +static int +_test_bin_search2_cmp_p(gconstpointer pa, gconstpointer pb, gpointer user_data) +{ + return _test_bin_search2_cmp(*((gpointer *) pa), *((gpointer *) pb), NULL); +} + +static void +test_nm_utils_ptrarray_find_binary_search_with_duplicates(void) +{ + gssize idx, idx2, idx_first2, idx_first, idx_last; + int i_test, i_len, i; + gssize j; + gconstpointer arr[BIN_SEARCH_W_DUPS_LEN]; + const int N_TEST = 10; + + for (i_test = 0; i_test < N_TEST; i_test++) { + for (i_len = 0; i_len < BIN_SEARCH_W_DUPS_LEN; i_len++) { + /* fill with random numbers... surely there are some duplicates + * there... or maybe even there are none... */ + for (i = 0; i < i_len; i++) + arr[i] = + GINT_TO_POINTER(nmtst_get_rand_uint32() % (i_len + BIN_SEARCH_W_DUPS_JITTER)); + g_qsort_with_data(arr, i_len, sizeof(gpointer), _test_bin_search2_cmp_p, NULL); + for (i = 0; i < i_len + BIN_SEARCH_W_DUPS_JITTER; i++) { + gconstpointer p = GINT_TO_POINTER(i); + + idx = nm_utils_ptrarray_find_binary_search_range(arr, + i_len, + p, + _test_bin_search2_cmp, + NULL, + &idx_first, + &idx_last); + + idx_first2 = nm_utils_ptrarray_find_first(arr, i_len, p); + + idx2 = nm_utils_array_find_binary_search(arr, + sizeof(gpointer), + i_len, + &p, + _test_bin_search2_cmp_p, + NULL); + g_assert_cmpint(idx, ==, idx2); + + idx2 = nm_utils_ptrarray_find_binary_search(arr, + i_len, + p, + _test_bin_search2_cmp, + NULL); + g_assert_cmpint(idx, ==, idx2); + + if (idx_first2 < 0) { + g_assert_cmpint(idx, <, 0); + g_assert_cmpint(idx, ==, idx_first); + g_assert_cmpint(idx, ==, idx_last); + idx = ~idx; + g_assert_cmpint(idx, >=, 0); + g_assert_cmpint(idx, <=, i_len); + if (i_len == 0) + g_assert_cmpint(idx, ==, 0); + else { + g_assert(idx == i_len || GPOINTER_TO_INT(arr[idx]) > i); + g_assert(idx == 0 || GPOINTER_TO_INT(arr[idx - 1]) < i); + } + } else { + g_assert_cmpint(idx_first, ==, idx_first2); + g_assert_cmpint(idx_first, >=, 0); + g_assert_cmpint(idx_last, <, i_len); + g_assert_cmpint(idx_first, <=, idx_last); + g_assert_cmpint(idx, >=, idx_first); + g_assert_cmpint(idx, <=, idx_last); + for (j = idx_first; j < idx_last; j++) + g_assert(GPOINTER_TO_INT(arr[j]) == i); + g_assert(idx_first == 0 || GPOINTER_TO_INT(arr[idx_first - 1]) < i); + g_assert(idx_last == i_len - 1 || GPOINTER_TO_INT(arr[idx_last + 1]) > i); + } + } + } + } +} + +/*****************************************************************************/ + +static void +_test_nm_utils_enum_to_str_do_full(GType type, + int flags, + const char * exp_str, + const NMUtilsEnumValueInfo *value_infos) +{ + gs_free char *str = NULL; + int flags2; + gs_free char *err_token = NULL; + gboolean result; + + g_assert(exp_str); + + str = _nm_utils_enum_to_str_full(type, flags, ", ", value_infos); + g_assert_cmpstr(str, ==, exp_str); + + if (!value_infos) { + gs_free char *str2 = NULL; + + str2 = nm_utils_enum_to_str(type, flags); + g_assert_cmpstr(str2, ==, exp_str); + } + + result = _nm_utils_enum_from_str_full(type, str, &flags2, &err_token, value_infos); + g_assert(result == TRUE); + g_assert_cmpint(flags2, ==, flags); + g_assert_cmpstr(err_token, ==, NULL); +} + +#define _test_nm_utils_enum_to_str_do(...) _test_nm_utils_enum_to_str_do_full(__VA_ARGS__, NULL) + +static void +_test_nm_utils_enum_from_str_do_full(GType type, + const char * str, + gboolean exp_result, + int exp_flags, + const char * exp_err_token, + const NMUtilsEnumValueInfo *value_infos) +{ + int flags; + gs_free char *err_token = NULL; + gboolean result; + + result = _nm_utils_enum_from_str_full(type, str, &flags, &err_token, value_infos); + + g_assert(result == exp_result); + g_assert_cmpint(flags, ==, exp_flags); + g_assert_cmpstr(err_token, ==, exp_err_token); + + if (!value_infos) { + int flags2; + gs_free char *err_token2 = NULL; + gboolean result2; + + result2 = nm_utils_enum_from_str(type, str, &flags2, &err_token2); + g_assert(result2 == exp_result); + g_assert_cmpint(flags2, ==, exp_flags); + g_assert_cmpstr(err_token2, ==, exp_err_token); + } + + if (result) { + int flags2; + gs_free char *str2 = NULL; + gs_free char *err_token2 = NULL; + + str2 = _nm_utils_enum_to_str_full(type, flags, ", ", value_infos); + g_assert(str2); + + result = _nm_utils_enum_from_str_full(type, str2, &flags2, &err_token2, value_infos); + g_assert(result == TRUE); + g_assert_cmpint(flags2, ==, flags); + g_assert_cmpstr(err_token, ==, NULL); + } +} + +#define _test_nm_utils_enum_from_str_do(...) _test_nm_utils_enum_from_str_do_full(__VA_ARGS__, NULL) + +static void +_test_nm_utils_enum_get_values_do(GType type, int from, int to, const char *exp_str) +{ + gs_free const char **strv = NULL; + gs_free char * str = NULL; + + g_assert(exp_str); + + strv = nm_utils_enum_get_values(type, from, to); + g_assert(strv); + str = g_strjoinv(",", (char **) strv); + g_assert_cmpstr(str, ==, exp_str); +} + +static void +test_nm_utils_enum(void) +{ + GType bool_enum = nm_test_general_bool_enum_get_type(); + GType meta_flags = nm_test_general_meta_flags_get_type(); + GType color_flags = nm_test_general_color_flags_get_type(); + static const NMUtilsEnumValueInfo color_value_infos[] = { + { + .nick = "nick-4d", + .value = 0x4D, + }, + { + .nick = "nick-5", + .value = 5, + }, + { + .nick = "nick-red", + .value = NM_TEST_GENERAL_COLOR_FLAGS_RED, + }, + {0}, + }; + + _test_nm_utils_enum_to_str_do(bool_enum, NM_TEST_GENERAL_BOOL_ENUM_YES, "yes"); + _test_nm_utils_enum_to_str_do(bool_enum, NM_TEST_GENERAL_BOOL_ENUM_UNKNOWN, "unknown"); + _test_nm_utils_enum_to_str_do(bool_enum, NM_TEST_GENERAL_BOOL_ENUM_INVALID, "4"); + _test_nm_utils_enum_to_str_do(bool_enum, NM_TEST_GENERAL_BOOL_ENUM_67, "67"); + _test_nm_utils_enum_to_str_do(bool_enum, NM_TEST_GENERAL_BOOL_ENUM_46, "64"); + + _test_nm_utils_enum_to_str_do(meta_flags, NM_TEST_GENERAL_META_FLAGS_NONE, "none"); + _test_nm_utils_enum_to_str_do(meta_flags, NM_TEST_GENERAL_META_FLAGS_BAZ, "baz"); + _test_nm_utils_enum_to_str_do(meta_flags, + NM_TEST_GENERAL_META_FLAGS_FOO | NM_TEST_GENERAL_META_FLAGS_BAR + | NM_TEST_GENERAL_META_FLAGS_BAZ, + "foo, bar, baz"); + _test_nm_utils_enum_to_str_do(meta_flags, 0xFF, "foo, bar, baz, 0xf8"); + _test_nm_utils_enum_to_str_do(meta_flags, NM_TEST_GENERAL_META_FLAGS_0x8, "0x8"); + _test_nm_utils_enum_to_str_do(meta_flags, NM_TEST_GENERAL_META_FLAGS_0x4, "0x10"); + + _test_nm_utils_enum_to_str_do(color_flags, NM_TEST_GENERAL_COLOR_FLAGS_RED, "red"); + _test_nm_utils_enum_to_str_do(color_flags, NM_TEST_GENERAL_COLOR_FLAGS_WHITE, "0x1"); + _test_nm_utils_enum_to_str_do(color_flags, + NM_TEST_GENERAL_COLOR_FLAGS_RED + | NM_TEST_GENERAL_COLOR_FLAGS_GREEN, + "red, green"); + + _test_nm_utils_enum_to_str_do_full(color_flags, + NM_TEST_GENERAL_COLOR_FLAGS_RED + | NM_TEST_GENERAL_COLOR_FLAGS_GREEN, + "nick-red, green", + color_value_infos); + + _test_nm_utils_enum_to_str_do_full(color_flags, + 0x4D | NM_TEST_GENERAL_COLOR_FLAGS_RED + | NM_TEST_GENERAL_COLOR_FLAGS_GREEN, + "nick-4d", + color_value_infos); + + _test_nm_utils_enum_to_str_do_full(color_flags, + 5 | NM_TEST_GENERAL_COLOR_FLAGS_GREEN, + "nick-5, green", + color_value_infos); + + _test_nm_utils_enum_from_str_do(bool_enum, "", FALSE, 0, NULL); + _test_nm_utils_enum_from_str_do(bool_enum, " ", FALSE, 0, NULL); + _test_nm_utils_enum_from_str_do(bool_enum, "invalid", FALSE, 0, "invalid"); + _test_nm_utils_enum_from_str_do(bool_enum, "yes", TRUE, NM_TEST_GENERAL_BOOL_ENUM_YES, NULL); + _test_nm_utils_enum_from_str_do(bool_enum, "no", TRUE, NM_TEST_GENERAL_BOOL_ENUM_NO, NULL); + _test_nm_utils_enum_from_str_do(bool_enum, "yes,no", FALSE, 0, "yes,no"); + + _test_nm_utils_enum_from_str_do(meta_flags, "", TRUE, 0, NULL); + _test_nm_utils_enum_from_str_do(meta_flags, " ", TRUE, 0, NULL); + _test_nm_utils_enum_from_str_do(meta_flags, "foo", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO, NULL); + _test_nm_utils_enum_from_str_do(meta_flags, + "foo,baz", + TRUE, + NM_TEST_GENERAL_META_FLAGS_FOO | NM_TEST_GENERAL_META_FLAGS_BAZ, + NULL); + _test_nm_utils_enum_from_str_do(meta_flags, + "foo, baz", + TRUE, + NM_TEST_GENERAL_META_FLAGS_FOO | NM_TEST_GENERAL_META_FLAGS_BAZ, + NULL); + _test_nm_utils_enum_from_str_do(meta_flags, + "foo,,bar", + TRUE, + NM_TEST_GENERAL_META_FLAGS_FOO | NM_TEST_GENERAL_META_FLAGS_BAR, + NULL); + _test_nm_utils_enum_from_str_do(meta_flags, "foo,baz,quux,bar", FALSE, 0, "quux"); + _test_nm_utils_enum_from_str_do(meta_flags, + "foo,0x6", + TRUE, + NM_TEST_GENERAL_META_FLAGS_FOO | 0x6, + NULL); + _test_nm_utils_enum_from_str_do(meta_flags, "0x30,0x08,foo", TRUE, 0x39, NULL); + + _test_nm_utils_enum_from_str_do(color_flags, + "green", + TRUE, + NM_TEST_GENERAL_COLOR_FLAGS_GREEN, + NULL); + _test_nm_utils_enum_from_str_do(color_flags, + "blue,red", + TRUE, + NM_TEST_GENERAL_COLOR_FLAGS_BLUE + | NM_TEST_GENERAL_COLOR_FLAGS_RED, + NULL); + _test_nm_utils_enum_from_str_do(color_flags, "blue,white", FALSE, 0, "white"); + + _test_nm_utils_enum_from_str_do_full(color_flags, + "nick-red", + TRUE, + NM_TEST_GENERAL_COLOR_FLAGS_RED, + NULL, + color_value_infos); + + _test_nm_utils_enum_from_str_do_full(color_flags, "0x4D", TRUE, 0x4D, NULL, color_value_infos); + + _test_nm_utils_enum_from_str_do_full(color_flags, + "green,nick-4d", + TRUE, + 0x4D | NM_TEST_GENERAL_COLOR_FLAGS_GREEN, + NULL, + color_value_infos); + + _test_nm_utils_enum_from_str_do_full(color_flags, + "nick-4d,nick-red,nick-5,green,nick-red", + TRUE, + 0x4D | NM_TEST_GENERAL_COLOR_FLAGS_GREEN, + NULL, + color_value_infos); + + _test_nm_utils_enum_from_str_do_full(NM_TYPE_SETTING_CONNECTION_LLMNR, + "-1", + TRUE, + -1, + NULL, + NULL); + + _test_nm_utils_enum_from_str_do_full(NM_TYPE_SETTING_CONNECTION_LLMNR, + "-0x1", + TRUE, + -1, + NULL, + NULL); + + _test_nm_utils_enum_get_values_do(bool_enum, 0, G_MAXINT, "no,yes,maybe,unknown,67,64"); + _test_nm_utils_enum_get_values_do(bool_enum, + NM_TEST_GENERAL_BOOL_ENUM_YES, + NM_TEST_GENERAL_BOOL_ENUM_MAYBE, + "yes,maybe"); + _test_nm_utils_enum_get_values_do(meta_flags, 0, G_MAXINT, "none,foo,bar,baz,0x8,0x10"); + _test_nm_utils_enum_get_values_do(color_flags, 0, G_MAXINT, "blue,red,green"); +} + +/*****************************************************************************/ + +static void +_do_test_utils_str_utf8safe_unescape(const char *str, const char *expected, gsize expected_len) +{ + gsize l; + const char * s; + gs_free gpointer buf_free_1 = NULL; + gs_free char * str_free_1 = NULL; + + s = nm_utils_buf_utf8safe_unescape(str, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, &l, &buf_free_1); + g_assert_cmpint(expected_len, ==, l); + g_assert_cmpstr(s, ==, expected); + + if (str == NULL) { + g_assert(!s); + g_assert(!buf_free_1); + g_assert_cmpint(l, ==, 0); + } else { + g_assert(s); + if (!strchr(str, '\\')) { + g_assert(!buf_free_1); + g_assert(s == str); + g_assert_cmpint(l, ==, strlen(str)); + } else { + g_assert(buf_free_1); + g_assert(s == buf_free_1); + g_assert(memcmp(s, expected, expected_len) == 0); + } + } + + if (expected && l == strlen(expected)) { + /* there are no embedded NULs. Check that nm_utils_str_utf8safe_unescape() yields the same result. */ + s = nm_utils_str_utf8safe_unescape(str, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, &str_free_1); + g_assert_cmpstr(s, ==, expected); + if (strchr(str, '\\')) { + g_assert(str_free_1 != str); + g_assert(s == str_free_1); + } else + g_assert(s == str); + } +} + +#define do_test_utils_str_utf8safe_unescape(str, expected) \ + _do_test_utils_str_utf8safe_unescape("" str "", expected, NM_STRLEN(expected)) + +static void +_do_test_utils_str_utf8safe(const char * str, + gsize str_len, + const char * expected, + NMUtilsStrUtf8SafeFlags flags) +{ + const char * str_safe; + const char * buf_safe; + const char * s; + gs_free char *str_free_1 = NULL; + gs_free char *str_free_2 = NULL; + gs_free char *str_free_3 = NULL; + gs_free char *str_free_4 = NULL; + gs_free char *str_free_5 = NULL; + gs_free char *str_free_6 = NULL; + gs_free char *str_free_7 = NULL; + gs_free char *str_free_8 = NULL; + gboolean str_has_nul = FALSE; +#define RND_FLAG \ + ((nmtst_get_rand_bool()) ? NM_UTILS_STR_UTF8_SAFE_FLAG_NONE \ + : NM_UTILS_STR_UTF8_SAFE_FLAG_SECRET) + + buf_safe = nm_utils_buf_utf8safe_escape(str, str_len, flags | RND_FLAG, &str_free_1); + + str_safe = nm_utils_str_utf8safe_escape(str, flags | RND_FLAG, &str_free_2); + + if (str_len == 0) { + g_assert(buf_safe == NULL); + g_assert(str_free_1 == NULL); + g_assert(str_safe == str); + g_assert(str == NULL || str[0] == '\0'); + g_assert(str_free_2 == NULL); + } else if (str_len == strlen(str)) { + g_assert(buf_safe); + g_assert_cmpstr(buf_safe, ==, str_safe); + + /* nm_utils_buf_utf8safe_escape() can only return a pointer equal to the input string, + * if and only if str_len is negative. Otherwise, the input str won't be NUL terminated + * and cannot be returned. */ + g_assert(buf_safe != str); + g_assert(buf_safe == str_free_1); + } else + str_has_nul = TRUE; + + str_free_3 = nm_utils_str_utf8safe_escape_cp(str, flags | RND_FLAG); + g_assert_cmpstr(str_free_3, ==, str_safe); + g_assert((!str && !str_free_3) || (str != str_free_3)); + + if (str_len > 0) + _do_test_utils_str_utf8safe_unescape(buf_safe, str, str_len); + + if (expected == NULL) { + g_assert(!str_has_nul); + + g_assert(str_safe == str); + g_assert(!str_free_2); + if (str) { + g_assert(!strchr(str, '\\')); + g_assert(g_utf8_validate(str, -1, NULL)); + } + + g_assert(str + == nm_utils_str_utf8safe_unescape(str_safe, + NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, + &str_free_4)); + g_assert(!str_free_4); + + str_free_5 = nm_utils_str_utf8safe_unescape_cp(str_safe, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + if (str) { + g_assert(str_free_5 != str); + g_assert_cmpstr(str_free_5, ==, str); + } else + g_assert(!str_free_5); + return; + } + + if (!str_has_nul) { + g_assert(str); + g_assert(str_safe != str); + g_assert(str_safe == str_free_2); + g_assert(strchr(str, '\\') || !g_utf8_validate(str, -1, NULL) + || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) + && NM_STRCHAR_ANY(str, ch, (guchar) ch >= 127)) + || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) + && NM_STRCHAR_ANY(str, ch, (guchar) ch < ' '))); + g_assert(g_utf8_validate(str_safe, -1, NULL)); + + str_free_6 = g_strcompress(str_safe); + g_assert_cmpstr(str, ==, str_free_6); + + str_free_7 = nm_utils_str_utf8safe_unescape_cp(str_safe, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + g_assert(str_free_7 != str); + g_assert_cmpstr(str_free_7, ==, str); + + s = nm_utils_str_utf8safe_unescape(str_safe, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, &str_free_8); + g_assert(str_free_8 != str); + g_assert(s == str_free_8); + g_assert_cmpstr(str_free_8, ==, str); + + g_assert_cmpstr(str_safe, ==, expected); + + return; + } + + g_assert_cmpstr(buf_safe, ==, expected); +} +#define do_test_utils_str_utf8safe(str, expected, flags) \ + _do_test_utils_str_utf8safe("" str "", NM_STRLEN(str), expected, flags) + +static void +test_utils_str_utf8safe(void) +{ + _do_test_utils_str_utf8safe(NULL, 0, NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + + do_test_utils_str_utf8safe("", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\\", "\\\\", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\\a", "\\\\a", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\314", "\\314", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\314\315x\315\315x", + "\\314\\315x\\315\\315x", + NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\314\315xx", "\\314\\315xx", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\314xx", "\\314xx", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\xa0", "\\240", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\xe2\x91\xa0", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\xe2\xe2\x91\xa0", + "\\342\xe2\x91\xa0", + NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\xe2\xe2\x91\xa0\xa0", + "\\342\xe2\x91\xa0\\240", + NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("a", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("ab", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("ab\314", "ab\\314", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("ab\314adsf", "ab\\314adsf", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("abadsf", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("abäb", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("x\xa0", "x\\240", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("Ä\304ab\\äb", "Ä\\304ab\\\\äb", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("Äab\\äb", "Äab\\\\äb", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("ÄÄab\\äb", "ÄÄab\\\\äb", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("㈞abä㈞b", NULL, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("abäb", + "ab\\303\\244b", + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII); + do_test_utils_str_utf8safe("ab\ab", "ab\\007b", NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL); + + do_test_utils_str_utf8safe("\0", "\\000", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\0a\0", "\\000a\\000", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\\\0", "\\\\\\000", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\n\0", "\n\\000", NM_UTILS_STR_UTF8_SAFE_FLAG_NONE); + do_test_utils_str_utf8safe("\n\0", "\\012\\000", NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL); + + do_test_utils_str_utf8safe_unescape("\n\\0", "\n\0"); + do_test_utils_str_utf8safe_unescape("\n\\01", "\n\01"); + do_test_utils_str_utf8safe_unescape("\n\\012", "\n\012"); + do_test_utils_str_utf8safe_unescape("\n\\.", "\n."); + do_test_utils_str_utf8safe_unescape("\\n\\.3\\r", "\n.3\r"); +} + +/*****************************************************************************/ + +static int +_test_nm_in_set_get(int *call_counter, gboolean allow_called, int value) +{ + g_assert(call_counter); + *call_counter += 1; + if (!allow_called) + g_assert_not_reached(); + return value; +} + +static void +_test_nm_in_set_assert(int *call_counter, int expected) +{ + g_assert(call_counter); + g_assert_cmpint(expected, ==, *call_counter); + *call_counter = 0; +} + +static void +test_nm_in_set(void) +{ + int call_counter = 0; + +#define G(x) _test_nm_in_set_get(&call_counter, TRUE, x) +#define N(x) _test_nm_in_set_get(&call_counter, FALSE, x) +#define _ASSERT(expected, expr) \ + G_STMT_START \ + { \ + _test_nm_in_set_assert(&call_counter, 0); \ + g_assert(expr); \ + _test_nm_in_set_assert(&call_counter, (expected)); \ + } \ + G_STMT_END + _ASSERT(1, !NM_IN_SET(-1, G(1))); + _ASSERT(1, NM_IN_SET(-1, G(-1))); + + _ASSERT(2, !NM_IN_SET(-1, G(1), G(2))); + _ASSERT(1, NM_IN_SET(-1, G(-1), N(2))); + _ASSERT(2, NM_IN_SET(-1, G(1), G(-1))); + _ASSERT(1, NM_IN_SET(-1, G(-1), N(-1))); + + _ASSERT(3, !NM_IN_SET(-1, G(1), G(2), G(3))); + _ASSERT(1, NM_IN_SET(-1, G(-1), N(2), N(3))); + _ASSERT(2, NM_IN_SET(-1, G(1), G(-1), N(3))); + _ASSERT(3, NM_IN_SET(-1, G(1), G(2), G(-1))); + _ASSERT(2, NM_IN_SET(-1, G(1), G(-1), N(-1))); + _ASSERT(1, NM_IN_SET(-1, G(-1), N(2), N(-1))); + _ASSERT(1, NM_IN_SET(-1, G(-1), N(-1), N(3))); + _ASSERT(1, NM_IN_SET(-1, G(-1), N(-1), N(-1))); + + _ASSERT(4, !NM_IN_SET(-1, G(1), G(2), G(3), G(4))); + _ASSERT(1, NM_IN_SET(-1, G(-1), N(2), N(3), N(4))); + _ASSERT(2, NM_IN_SET(-1, G(1), G(-1), N(3), N(4))); + _ASSERT(3, NM_IN_SET(-1, G(1), G(2), G(-1), N(4))); + _ASSERT(4, NM_IN_SET(-1, G(1), G(2), G(3), G(-1))); + + _ASSERT(4, NM_IN_SET(-1, G(1), G(2), G(3), G(-1), G(5))); + _ASSERT(5, NM_IN_SET(-1, G(1), G(2), G(3), G(4), G(-1))); + _ASSERT(6, NM_IN_SET(-1, G(1), G(2), G(3), G(4), G(5), G(-1))); + + _ASSERT(1, !NM_IN_SET_SE(-1, G(1))); + _ASSERT(1, NM_IN_SET_SE(-1, G(-1))); + + _ASSERT(2, !NM_IN_SET_SE(-1, G(1), G(2))); + _ASSERT(2, NM_IN_SET_SE(-1, G(-1), G(2))); + _ASSERT(2, NM_IN_SET_SE(-1, G(1), G(-1))); + _ASSERT(2, NM_IN_SET_SE(-1, G(-1), G(-1))); + + _ASSERT(3, !NM_IN_SET_SE(-1, G(1), G(2), G(3))); + _ASSERT(3, NM_IN_SET_SE(-1, G(-1), G(2), G(3))); + _ASSERT(3, NM_IN_SET_SE(-1, G(1), G(-1), G(3))); + _ASSERT(3, NM_IN_SET_SE(-1, G(1), G(2), G(-1))); + _ASSERT(3, NM_IN_SET_SE(-1, G(1), G(-1), G(-1))); + _ASSERT(3, NM_IN_SET_SE(-1, G(-1), G(2), G(-1))); + _ASSERT(3, NM_IN_SET_SE(-1, G(-1), G(-1), G(3))); + _ASSERT(3, NM_IN_SET_SE(-1, G(-1), G(-1), G(-1))); + + _ASSERT(4, !NM_IN_SET_SE(-1, G(1), G(2), G(3), G(4))); + _ASSERT(4, NM_IN_SET_SE(-1, G(-1), G(2), G(3), G(4))); + _ASSERT(4, NM_IN_SET_SE(-1, G(1), G(-1), G(3), G(4))); + _ASSERT(4, NM_IN_SET_SE(-1, G(1), G(2), G(-1), G(4))); + _ASSERT(4, NM_IN_SET_SE(-1, G(1), G(2), G(3), G(-1))); + + _ASSERT(5, NM_IN_SET_SE(-1, G(1), G(2), G(3), G(-1), G(5))); + _ASSERT(6, NM_IN_SET_SE(-1, G(1), G(2), G(3), G(4), G(5), G(-1))); + + g_assert(!NM_IN_SET(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)); +#undef G +#undef N +#undef _ASSERT +} + +/*****************************************************************************/ + +static const char * +_test_nm_in_set_getstr(int *call_counter, gboolean allow_called, const char *value) +{ + g_assert(call_counter); + *call_counter += 1; + if (!allow_called) + g_assert_not_reached(); + return value; +} + +static void +test_nm_in_strset(void) +{ + int call_counter = 0; + +#define G(x) _test_nm_in_set_getstr(&call_counter, TRUE, x) +#define N(x) _test_nm_in_set_getstr(&call_counter, FALSE, x) +#define _ASSERT(expected, expr) \ + G_STMT_START \ + { \ + _test_nm_in_set_assert(&call_counter, 0); \ + g_assert(expr); \ + _test_nm_in_set_assert(&call_counter, (expected)); \ + } \ + G_STMT_END + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL))); + _ASSERT(1, !NM_IN_STRSET("a", G(NULL))); + _ASSERT(1, !NM_IN_STRSET(NULL, G("a"))); + + _ASSERT(1, NM_IN_STRSET_SE(NULL, G(NULL))); + _ASSERT(1, !NM_IN_STRSET_SE("a", G(NULL))); + _ASSERT(1, !NM_IN_STRSET_SE(NULL, G("a"))); + + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N(NULL))); + _ASSERT(2, !NM_IN_STRSET("a", G(NULL), G(NULL))); + _ASSERT(2, NM_IN_STRSET(NULL, G("a"), G(NULL))); + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N("a"))); + _ASSERT(2, NM_IN_STRSET("a", G(NULL), G("a"))); + _ASSERT(2, !NM_IN_STRSET(NULL, G("a"), G("a"))); + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N("b"))); + _ASSERT(2, !NM_IN_STRSET("a", G(NULL), G("b"))); + _ASSERT(2, !NM_IN_STRSET(NULL, G("a"), G("b"))); + + _ASSERT(2, NM_IN_STRSET_SE(NULL, G(NULL), G(NULL))); + _ASSERT(2, !NM_IN_STRSET_SE("a", G(NULL), G(NULL))); + _ASSERT(2, NM_IN_STRSET_SE(NULL, G("a"), G(NULL))); + _ASSERT(2, NM_IN_STRSET_SE(NULL, G(NULL), G("a"))); + _ASSERT(2, NM_IN_STRSET_SE("a", G(NULL), G("a"))); + _ASSERT(2, !NM_IN_STRSET_SE(NULL, G("a"), G("a"))); + _ASSERT(2, NM_IN_STRSET_SE(NULL, G(NULL), G("b"))); + _ASSERT(2, !NM_IN_STRSET_SE("a", G(NULL), G("b"))); + _ASSERT(2, !NM_IN_STRSET_SE(NULL, G("a"), G("b"))); + + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N(NULL), N(NULL))); + _ASSERT(3, !NM_IN_STRSET("a", G(NULL), G(NULL), G(NULL))); + _ASSERT(2, NM_IN_STRSET(NULL, G("a"), G(NULL), N(NULL))); + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N("a"), N(NULL))); + _ASSERT(2, NM_IN_STRSET("a", G(NULL), G("a"), N(NULL))); + _ASSERT(3, NM_IN_STRSET(NULL, G("a"), G("a"), G(NULL))); + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N("b"), N(NULL))); + _ASSERT(3, !NM_IN_STRSET("a", G(NULL), G("b"), G(NULL))); + _ASSERT(3, NM_IN_STRSET(NULL, G("a"), G("b"), G(NULL))); + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N(NULL), N("a"))); + _ASSERT(3, NM_IN_STRSET("a", G(NULL), G(NULL), G("a"))); + _ASSERT(2, NM_IN_STRSET(NULL, G("a"), G(NULL), N("a"))); + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N("a"), N("a"))); + _ASSERT(2, NM_IN_STRSET("a", G(NULL), G("a"), N("a"))); + _ASSERT(3, !NM_IN_STRSET(NULL, G("a"), G("a"), G("a"))); + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N("b"), N("a"))); + _ASSERT(3, NM_IN_STRSET("a", G(NULL), G("b"), G("a"))); + _ASSERT(3, !NM_IN_STRSET(NULL, G("a"), G("b"), G("a"))); + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N(NULL), N("b"))); + _ASSERT(3, !NM_IN_STRSET("a", G(NULL), G(NULL), G("b"))); + _ASSERT(2, NM_IN_STRSET(NULL, G("a"), G(NULL), N("b"))); + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N("a"), N("b"))); + _ASSERT(2, NM_IN_STRSET("a", G(NULL), G("a"), N("b"))); + _ASSERT(3, !NM_IN_STRSET(NULL, G("a"), G("a"), G("b"))); + _ASSERT(1, NM_IN_STRSET(NULL, G(NULL), N("b"), N("b"))); + _ASSERT(3, !NM_IN_STRSET("a", G(NULL), G("b"), G("b"))); + _ASSERT(3, !NM_IN_STRSET(NULL, G("a"), G("b"), G("b"))); + + _ASSERT(3, NM_IN_STRSET_SE(NULL, G(NULL), G(NULL), G(NULL))); + _ASSERT(3, !NM_IN_STRSET_SE("a", G(NULL), G(NULL), G(NULL))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G("a"), G(NULL), G(NULL))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G(NULL), G("a"), G(NULL))); + _ASSERT(3, NM_IN_STRSET_SE("a", G(NULL), G("a"), G(NULL))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G("a"), G("a"), G(NULL))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G(NULL), G("b"), G(NULL))); + _ASSERT(3, !NM_IN_STRSET_SE("a", G(NULL), G("b"), G(NULL))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G("a"), G("b"), G(NULL))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G(NULL), G(NULL), G("a"))); + _ASSERT(3, NM_IN_STRSET_SE("a", G(NULL), G(NULL), G("a"))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G("a"), G(NULL), G("a"))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G(NULL), G("a"), G("a"))); + _ASSERT(3, NM_IN_STRSET_SE("a", G(NULL), G("a"), G("a"))); + _ASSERT(3, !NM_IN_STRSET_SE(NULL, G("a"), G("a"), G("a"))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G(NULL), G("b"), G("a"))); + _ASSERT(3, NM_IN_STRSET_SE("a", G(NULL), G("b"), G("a"))); + _ASSERT(3, !NM_IN_STRSET_SE(NULL, G("a"), G("b"), G("a"))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G(NULL), G(NULL), G("b"))); + _ASSERT(3, !NM_IN_STRSET_SE("a", G(NULL), G(NULL), G("b"))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G("a"), G(NULL), G("b"))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G(NULL), G("a"), G("b"))); + _ASSERT(3, NM_IN_STRSET_SE("a", G(NULL), G("a"), G("b"))); + _ASSERT(3, !NM_IN_STRSET_SE(NULL, G("a"), G("a"), G("b"))); + _ASSERT(3, NM_IN_STRSET_SE(NULL, G(NULL), G("b"), G("b"))); + _ASSERT(3, !NM_IN_STRSET_SE("a", G(NULL), G("b"), G("b"))); + _ASSERT(3, !NM_IN_STRSET_SE(NULL, G("a"), G("b"), G("b"))); + + _ASSERT(3, NM_IN_STRSET("a", G(NULL), G("b"), G("a"), N("a"))); + _ASSERT(4, NM_IN_STRSET("a", G(NULL), G("b"), G("c"), G("a"))); + _ASSERT(4, !NM_IN_STRSET("a", G(NULL), G("b"), G("c"), G("d"))); + + _ASSERT(4, NM_IN_STRSET("a", G(NULL), G("b"), G("c"), G("a"), N("a"))); + _ASSERT(5, NM_IN_STRSET("a", G(NULL), G("b"), G("c"), G("d"), G("a"))); + _ASSERT(5, !NM_IN_STRSET("a", G(NULL), G("b"), G("c"), G("d"), G("e"))); + + _ASSERT(5, NM_IN_STRSET("a", G(NULL), G("b"), G("c"), G("d"), G("a"), N("a"))); + _ASSERT(6, NM_IN_STRSET("a", G(NULL), G("b"), G("c"), G("d"), G("e"), G("a"))); + _ASSERT(6, !NM_IN_STRSET("a", G(NULL), G("b"), G("c"), G("d"), G("e"), G("f"))); + + g_assert(!NM_IN_STRSET(NULL, + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16")); + g_assert(!NM_IN_STRSET("_", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16")); + g_assert(NM_IN_STRSET("10", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16")); +#undef G +#undef N +#undef _ASSERT +} + +static void +test_route_attributes_parse(void) +{ + GHashTable *ht; + GError * error = NULL; + GVariant * variant; + + ht = nm_utils_parse_variant_attributes("mtu=1400 src=1.2.3.4 cwnd=14", + ' ', + '=', + FALSE, + nm_ip_route_get_variant_attribute_spec(), + &error); + g_assert_no_error(error); + g_assert(ht); + g_hash_table_unref(ht); + + ht = nm_utils_parse_variant_attributes("mtu=1400 src=1.2.3.4 cwnd=14 \\", + ' ', + '=', + FALSE, + nm_ip_route_get_variant_attribute_spec(), + &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED); + g_assert(!ht); + g_clear_error(&error); + + ht = nm_utils_parse_variant_attributes("mtu.1400 src.1\\.2\\.3\\.4 ", + ' ', + '.', + FALSE, + nm_ip_route_get_variant_attribute_spec(), + &error); + g_assert(ht); + g_assert_no_error(error); + variant = g_hash_table_lookup(ht, NM_IP_ROUTE_ATTRIBUTE_MTU); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32)); + g_assert_cmpuint(g_variant_get_uint32(variant), ==, 1400); + + variant = g_hash_table_lookup(ht, NM_IP_ROUTE_ATTRIBUTE_SRC); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr(g_variant_get_string(variant, NULL), ==, "1.2.3.4"); + g_hash_table_unref(ht); + + ht = nm_utils_parse_variant_attributes("from:fd01\\:\\:42\\/64/initrwnd:21", + '/', + ':', + FALSE, + nm_ip_route_get_variant_attribute_spec(), + &error); + g_assert(ht); + g_assert_no_error(error); + variant = g_hash_table_lookup(ht, NM_IP_ROUTE_ATTRIBUTE_INITRWND); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32)); + g_assert_cmpuint(g_variant_get_uint32(variant), ==, 21); + + variant = g_hash_table_lookup(ht, NM_IP_ROUTE_ATTRIBUTE_FROM); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr(g_variant_get_string(variant, NULL), ==, "fd01::42/64"); + g_hash_table_unref(ht); +} + +static void +test_route_attributes_format(void) +{ + gs_unref_hashtable GHashTable *ht = NULL; + char * str; + + ht = g_hash_table_new_full(nm_str_hash, g_str_equal, NULL, (GDestroyNotify) g_variant_unref); + + str = nm_utils_format_variant_attributes(NULL, ' ', '='); + g_assert_cmpstr(str, ==, NULL); + + str = nm_utils_format_variant_attributes(ht, ' ', '='); + g_assert_cmpstr(str, ==, NULL); + + g_hash_table_insert(ht, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32(5000)); + g_hash_table_insert(ht, NM_IP_ROUTE_ATTRIBUTE_INITRWND, g_variant_new_uint32(20)); + g_hash_table_insert(ht, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, g_variant_new_boolean(TRUE)); + g_hash_table_insert(ht, NM_IP_ROUTE_ATTRIBUTE_SRC, g_variant_new_string("aaaa:bbbb::1")); + str = nm_utils_format_variant_attributes(ht, ' ', '='); + g_assert_cmpstr(str, ==, "initrwnd=20 lock-mtu=true mtu=5000 src=aaaa:bbbb::1"); + g_hash_table_remove_all(ht); + g_free(str); + + g_hash_table_insert(ht, NM_IP_ROUTE_ATTRIBUTE_WINDOW, g_variant_new_uint32(30000)); + g_hash_table_insert(ht, NM_IP_ROUTE_ATTRIBUTE_INITCWND, g_variant_new_uint32(21)); + g_hash_table_insert(ht, + NM_IP_ROUTE_ATTRIBUTE_FROM, + g_variant_new_string("aaaa:bbbb:cccc:dddd::/64")); + str = nm_utils_format_variant_attributes(ht, '/', ':'); + g_assert_cmpstr(str, ==, "from:aaaa\\:bbbb\\:cccc\\:dddd\\:\\:\\/64/initcwnd:21/window:30000"); + g_hash_table_remove_all(ht); + g_free(str); +} + +/*****************************************************************************/ + +static void +test_variant_attribute_spec(void) +{ + const NMVariantAttributeSpec *const *const specs_list[] = { + nm_ip_route_get_variant_attribute_spec(), + }; + int i_specs; + + for (i_specs = 0; i_specs < G_N_ELEMENTS(specs_list); i_specs++) { + const NMVariantAttributeSpec *const *const specs = specs_list[i_specs]; + gsize len; + gsize i; + + g_assert(specs); + + len = NM_PTRARRAY_LEN(specs); + g_assert_cmpint(len, >, 0u); + + _nmtst_variant_attribute_spec_assert_sorted(specs, len); + for (i = 0; i < len; i++) + g_assert(specs[i] + == _nm_variant_attribute_spec_find_binary_search(specs, len, specs[i]->name)); + g_assert(!_nm_variant_attribute_spec_find_binary_search(specs, len, "bogus")); + } +} + +/*****************************************************************************/ + +static gboolean +do_test_nm_set_out_called(int *call_count) +{ + (*call_count)++; + return TRUE; +} + +static void +test_nm_set_out(void) +{ + gboolean val; + gboolean *p_val; + int call_count; + + /* NM_SET_OUT() has an unexpected non-function like behavior + * wrt. side-effects of the value argument. Test it */ + + p_val = &val; + call_count = 0; + NM_SET_OUT(p_val, do_test_nm_set_out_called(&call_count)); + g_assert_cmpint(call_count, ==, 1); + + p_val = NULL; + call_count = 0; + NM_SET_OUT(p_val, do_test_nm_set_out_called(&call_count)); + g_assert_cmpint(call_count, ==, 0); + + /* test that we successfully re-defined _G_BOOLEAN_EXPR() */ +#define _T1(a) \ + ({ \ + g_assert(a > 2); \ + a; \ + }) + g_assert(_T1(3) > 1); +#undef _T1 +} + +/*****************************************************************************/ + +static void +test_get_start_time_for_pid(void) +{ + guint64 x_start_time; + char x_state; + pid_t x_ppid; + + x_start_time = nm_utils_get_start_time_for_pid(getpid(), &x_state, &x_ppid); + + g_assert(x_start_time > 0); + g_assert(x_ppid == getppid()); + g_assert(!NM_IN_SET(x_state, '\0', ' ')); +} + +/*****************************************************************************/ + +static void +test_nm_va_args_macros(void) +{ +#define GET_NARG_1(...) NM_NARG(__VA_ARGS__) + + g_assert_cmpint(0, ==, GET_NARG_1()); + g_assert_cmpint(1, ==, GET_NARG_1(x)); + g_assert_cmpint(2, ==, GET_NARG_1(, )); + g_assert_cmpint(2, ==, GET_NARG_1(, x)); + g_assert_cmpint(2, ==, GET_NARG_1(x, )); + g_assert_cmpint(2, ==, GET_NARG_1(x, x)); + g_assert_cmpint(3, ==, GET_NARG_1(, , )); + g_assert_cmpint(3, ==, GET_NARG_1(, , x)); + g_assert_cmpint(3, ==, GET_NARG_1(, x, )); + g_assert_cmpint(3, ==, GET_NARG_1(, x, x)); + g_assert_cmpint(3, ==, GET_NARG_1(x, , )); + g_assert_cmpint(3, ==, GET_NARG_1(x, , x)); + g_assert_cmpint(3, ==, GET_NARG_1(x, x, )); + g_assert_cmpint(3, ==, GET_NARG_1(x, x, x)); + g_assert_cmpint(4, ==, GET_NARG_1(, , , )); + g_assert_cmpint(4, ==, GET_NARG_1(, , , x)); + g_assert_cmpint(4, ==, GET_NARG_1(, , x, )); + g_assert_cmpint(4, ==, GET_NARG_1(, , x, x)); + g_assert_cmpint(4, ==, GET_NARG_1(, x, , )); + g_assert_cmpint(4, ==, GET_NARG_1(, x, , x)); + g_assert_cmpint(4, ==, GET_NARG_1(, x, x, )); + g_assert_cmpint(4, ==, GET_NARG_1(, x, x, x)); + g_assert_cmpint(4, ==, GET_NARG_1(x, , , )); + g_assert_cmpint(4, ==, GET_NARG_1(x, , , x)); + g_assert_cmpint(4, ==, GET_NARG_1(x, , x, )); + g_assert_cmpint(4, ==, GET_NARG_1(x, , x, x)); + g_assert_cmpint(4, ==, GET_NARG_1(x, x, , )); + g_assert_cmpint(4, ==, GET_NARG_1(x, x, , x)); + g_assert_cmpint(4, ==, GET_NARG_1(x, x, x, )); + g_assert_cmpint(4, ==, GET_NARG_1(x, x, x, x)); + + g_assert_cmpint(5, ==, GET_NARG_1(x, x, x, x, x)); + g_assert_cmpint(6, ==, GET_NARG_1(x, x, x, x, x, x)); + g_assert_cmpint(7, ==, GET_NARG_1(x, x, x, x, x, x, x)); + g_assert_cmpint(8, ==, GET_NARG_1(x, x, x, x, x, x, x, x)); + g_assert_cmpint(9, ==, GET_NARG_1(x, x, x, x, x, x, x, x, x)); + g_assert_cmpint(10, ==, GET_NARG_1(x, x, x, x, x, x, x, x, x, x)); + + G_STATIC_ASSERT_EXPR(0 == GET_NARG_1()); + G_STATIC_ASSERT_EXPR(1 == GET_NARG_1(x)); + G_STATIC_ASSERT_EXPR(2 == GET_NARG_1(x, x)); +} + +/*****************************************************************************/ + +static void +test_ethtool_offload(void) +{ + const NMEthtoolData *d; + + g_assert_cmpint(nm_ethtool_id_get_by_name("invalid"), ==, NM_ETHTOOL_ID_UNKNOWN); + g_assert_cmpint(nm_ethtool_id_get_by_name("feature-rx"), ==, NM_ETHTOOL_ID_FEATURE_RX); + + d = nm_ethtool_data_get_by_optname(NM_ETHTOOL_OPTNAME_FEATURE_RXHASH); + g_assert(d); + g_assert_cmpint(d->id, ==, NM_ETHTOOL_ID_FEATURE_RXHASH); + g_assert_cmpstr(d->optname, ==, NM_ETHTOOL_OPTNAME_FEATURE_RXHASH); + + /* these features are NETIF_F_NEVER_CHANGE: */ + g_assert(!nm_ethtool_data_get_by_optname("feature-netns-local")); + g_assert(!nm_ethtool_data_get_by_optname("feature-tx-lockless")); + g_assert(!nm_ethtool_data_get_by_optname("feature-vlan-challenged")); +} + +/*****************************************************************************/ + +typedef struct { + GMainLoop * loop1; + GMainContext *c2; + GSource * extra_sources[2]; + bool got_signal[5]; + int fd_2; +} IntegData; + +static gboolean +_test_integrate_cb_handle(IntegData *d, int signal) +{ + int i; + + g_assert(d); + g_assert(signal >= 0); + g_assert(signal < G_N_ELEMENTS(d->got_signal)); + + g_assert(!d->got_signal[signal]); + d->got_signal[signal] = TRUE; + + for (i = 0; i < G_N_ELEMENTS(d->got_signal); i++) { + if (!d->got_signal[i]) + break; + } + if (i == G_N_ELEMENTS(d->got_signal)) + g_main_loop_quit(d->loop1); + return G_SOURCE_REMOVE; +} + +static gboolean +_test_integrate_cb_timeout_1(gpointer user_data) +{ + return _test_integrate_cb_handle(user_data, 0); +} + +static gboolean +_test_integrate_cb_fd_2(int fd, GIOCondition condition, gpointer user_data) + +{ + IntegData *d = user_data; + + g_assert(d->got_signal[1]); + g_assert(d->got_signal[2]); + g_assert(d->got_signal[3]); + g_assert(d->extra_sources[0]); + g_assert(d->extra_sources[1]); + + return _test_integrate_cb_handle(d, 4); +} + +static gboolean +_test_integrate_cb_idle_2(gpointer user_data) +{ + IntegData *d = user_data; + GSource * extra_source; + + g_assert(d->got_signal[1]); + g_assert(d->got_signal[2]); + g_assert(d->extra_sources[0]); + g_assert(!d->extra_sources[1]); + + extra_source = nm_g_unix_fd_source_new(d->fd_2, + G_IO_IN, + G_PRIORITY_DEFAULT, + _test_integrate_cb_fd_2, + d, + NULL); + g_source_attach(extra_source, d->c2); + + d->extra_sources[1] = extra_source; + + return _test_integrate_cb_handle(d, 3); +} + +static gboolean +_test_integrate_cb_idle_1(gpointer user_data) +{ + IntegData *d = user_data; + GSource * extra_source; + + g_assert(d->got_signal[2]); + g_assert(!d->extra_sources[0]); + + extra_source = g_idle_source_new(); + g_source_set_callback(extra_source, _test_integrate_cb_idle_2, d, NULL); + g_source_attach(extra_source, d->c2); + + d->extra_sources[0] = extra_source; + + return _test_integrate_cb_handle(d, 1); +} + +static gboolean +_test_integrate_cb_fd_1(int fd, GIOCondition condition, gpointer user_data) + +{ + IntegData *d = user_data; + + g_assert(!d->got_signal[1]); + return _test_integrate_cb_handle(d, 2); +} + +static gboolean +_test_integrate_maincontext_cb_idle1(gpointer user_data) +{ + guint32 *p_count = user_data; + + g_assert(*p_count < 5); + (*p_count)++; + return G_SOURCE_CONTINUE; +} + +static void +test_integrate_maincontext(gconstpointer test_data) +{ + const guint TEST_IDX = GPOINTER_TO_UINT(test_data); + GMainContext * c1 = g_main_context_default(); + nm_auto_unref_gmaincontext GMainContext *c2 = g_main_context_new(); + nm_auto_destroy_and_unref_gsource GSource *integ_source = NULL; + + integ_source = nm_utils_g_main_context_create_integrate_source(c2); + g_source_attach(integ_source, c1); + + if (TEST_IDX == 1) { + nm_auto_destroy_and_unref_gsource GSource *idle_source_1 = NULL; + guint32 count = 0; + + idle_source_1 = g_idle_source_new(); + g_source_set_callback(idle_source_1, _test_integrate_maincontext_cb_idle1, &count, NULL); + g_source_attach(idle_source_1, c2); + + nmtst_main_context_iterate_until_assert(c1, 2000, count == 5); + } + + if (TEST_IDX == 2) { + nm_auto_destroy_and_unref_gsource GSource *main_timeout_source = NULL; + nm_auto_destroy_and_unref_gsource GSource *timeout_source_1 = NULL; + nm_auto_destroy_and_unref_gsource GSource *idle_source_1 = NULL; + nm_auto_destroy_and_unref_gsource GSource *fd_source_1 = NULL; + nm_auto_unref_gmainloop GMainLoop *loop1 = NULL; + nm_auto_close int fd_1 = -1; + nm_auto_close int fd_2 = -1; + IntegData d; + int i; + + main_timeout_source = g_timeout_source_new(3000); + g_source_set_callback(main_timeout_source, nmtst_g_source_assert_not_called, NULL, NULL); + g_source_attach(main_timeout_source, c1); + + loop1 = g_main_loop_new(c1, FALSE); + + d = (IntegData){ + .loop1 = loop1, + .c2 = c2, + }; + + fd_1 = open("/dev/null", O_RDONLY | O_CLOEXEC); + g_assert(fd_1 >= 0); + fd_source_1 = nm_g_unix_fd_source_new(fd_1, + G_IO_IN, + G_PRIORITY_DEFAULT, + _test_integrate_cb_fd_1, + &d, + NULL); + g_source_attach(fd_source_1, c2); + + fd_2 = open("/dev/null", O_RDONLY | O_CLOEXEC); + g_assert(fd_2 >= 0); + d.fd_2 = fd_2; + + idle_source_1 = g_idle_source_new(); + g_source_set_callback(idle_source_1, _test_integrate_cb_idle_1, &d, NULL); + g_source_attach(idle_source_1, c2); + + timeout_source_1 = g_timeout_source_new(5); + g_source_set_callback(timeout_source_1, _test_integrate_cb_timeout_1, &d, NULL); + g_source_attach(timeout_source_1, c2); + + g_main_loop_run(loop1); + + for (i = 0; i < G_N_ELEMENTS(d.extra_sources); i++) { + g_assert(d.extra_sources[i]); + nm_clear_pointer(&d.extra_sources[i], nm_g_source_destroy_and_unref); + } + } +} + +/*****************************************************************************/ + +static void +test_nm_ip_addr_zero(void) +{ + in_addr_t a4 = nmtst_inet4_from_string("0.0.0.0"); + struct in6_addr a6 = *nmtst_inet6_from_string("::"); + char buf[NM_UTILS_INET_ADDRSTRLEN]; + NMIPAddr a = NM_IP_ADDR_INIT; + + g_assert(memcmp(&a, &nm_ip_addr_zero, sizeof(a)) == 0); + + g_assert(IN6_IS_ADDR_UNSPECIFIED(&nm_ip_addr_zero.addr6)); + g_assert(memcmp(&nm_ip_addr_zero.addr6, &in6addr_any, sizeof(in6addr_any)) == 0); + + g_assert(memcmp(&nm_ip_addr_zero, &a4, sizeof(a4)) == 0); + g_assert(memcmp(&nm_ip_addr_zero, &a6, sizeof(a6)) == 0); + + g_assert_cmpstr(_nm_utils_inet4_ntop(nm_ip_addr_zero.addr4, buf), ==, "0.0.0.0"); + g_assert_cmpstr(_nm_utils_inet6_ntop(&nm_ip_addr_zero.addr6, buf), ==, "::"); + + g_assert_cmpstr(nm_utils_inet_ntop(AF_INET, &nm_ip_addr_zero, buf), ==, "0.0.0.0"); + g_assert_cmpstr(nm_utils_inet_ntop(AF_INET6, &nm_ip_addr_zero, buf), ==, "::"); + + G_STATIC_ASSERT_EXPR(sizeof(a) == sizeof(a.array)); +} + +static void +test_connection_ovs_ifname(gconstpointer test_data) +{ + const guint TEST_CASE = GPOINTER_TO_UINT(test_data); + gs_unref_object NMConnection *con = NULL; + NMSettingConnection * s_con = NULL; + NMSettingOvsBridge * s_ovs_bridge = NULL; + NMSettingOvsPort * s_ovs_port = NULL; + NMSettingOvsInterface * s_ovs_iface = NULL; + NMSettingOvsPatch * s_ovs_patch = NULL; + const char * ovs_iface_type = NULL; + + switch (TEST_CASE) { + case 1: + con = nmtst_create_minimal_connection("test_connection_ovs_ifname_bridge", + NULL, + NM_SETTING_OVS_BRIDGE_SETTING_NAME, + &s_con); + s_ovs_bridge = nm_connection_get_setting_ovs_bridge(con); + g_assert(s_ovs_bridge); + break; + case 2: + con = nmtst_create_minimal_connection("test_connection_ovs_ifname_port", + NULL, + NM_SETTING_OVS_PORT_SETTING_NAME, + &s_con); + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_BRIDGE_SETTING_NAME, + NULL); + + s_ovs_port = nm_connection_get_setting_ovs_port(con); + g_assert(s_ovs_port); + break; + case 3: + con = nmtst_create_minimal_connection("test_connection_ovs_ifname_interface_patch", + NULL, + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + &s_con); + s_ovs_iface = nm_connection_get_setting_ovs_interface(con); + g_assert(s_ovs_iface); + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + + g_object_set(s_ovs_iface, NM_SETTING_OVS_INTERFACE_TYPE, "patch", NULL); + + s_ovs_patch = NM_SETTING_OVS_PATCH(nm_setting_ovs_patch_new()); + g_assert(s_ovs_patch); + + g_object_set(s_ovs_patch, NM_SETTING_OVS_PATCH_PEER, "1.2.3.4", NULL); + + nm_connection_add_setting(con, NM_SETTING(s_ovs_patch)); + s_ovs_patch = nm_connection_get_setting_ovs_patch(con); + g_assert(s_ovs_patch); + ovs_iface_type = "patch"; + break; + case 4: + con = nmtst_create_minimal_connection("test_connection_ovs_ifname_interface_internal", + NULL, + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + &s_con); + s_ovs_iface = nm_connection_get_setting_ovs_interface(con); + g_assert(s_ovs_iface); + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + + g_object_set(s_ovs_iface, NM_SETTING_OVS_INTERFACE_TYPE, "internal", NULL); + ovs_iface_type = "internal"; + break; + case 5: + con = nmtst_create_minimal_connection("test_connection_ovs_ifname_interface_system", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + + s_ovs_iface = NM_SETTING_OVS_INTERFACE(nm_setting_ovs_interface_new()); + g_assert(s_ovs_iface); + + g_object_set(s_ovs_iface, NM_SETTING_OVS_INTERFACE_TYPE, "system", NULL); + + nm_connection_add_setting(con, NM_SETTING(s_ovs_iface)); + s_ovs_iface = nm_connection_get_setting_ovs_interface(con); + g_assert(s_ovs_iface); + + ovs_iface_type = "system"; + break; + case 6: + con = nmtst_create_minimal_connection("test_connection_ovs_ifname_interface_dpdk", + NULL, + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + &s_con); + s_ovs_iface = nm_connection_get_setting_ovs_interface(con); + g_assert(s_ovs_iface); + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + + g_object_set(s_ovs_iface, NM_SETTING_OVS_INTERFACE_TYPE, "dpdk", NULL); + ovs_iface_type = "dpdk"; + break; + } + + if (!nm_streq0(ovs_iface_type, "system")) { + /* wrong: contains backward slash */ + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs\\0", NULL); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + + /* wrong: contains forward slash */ + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs/0", NULL); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + } + + /* wrong: contains space */ + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs 0", NULL); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + + /* good */ + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs0", NULL); + nmtst_assert_connection_verifies(con); + + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs-br0", NULL); + nmtst_assert_connection_verifies(con); + + /* good if bridge, port, or patch interface */ + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs123123123123130123123", NULL); + + if (!ovs_iface_type || nm_streq(ovs_iface_type, "patch")) + nmtst_assert_connection_verifies(con); + else { + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + } +} + +/*****************************************************************************/ + +static gboolean +_strsplit_quoted_char_needs_escaping(char ch) +{ + return NM_IN_SET(ch, '\'', '\"', '\\') || strchr(NM_ASCII_WHITESPACES, ch); +} + +static char * +_strsplit_quoted_create_str_rand(gssize len) +{ + NMStrBuf strbuf = NM_STR_BUF_INIT(nmtst_get_rand_uint32() % 200, nmtst_get_rand_bool()); + + g_assert(len >= -1); + + if (len == -1) + len = nmtst_get_rand_word_length(NULL); + + while (len-- > 0) { + char ch; + + ch = nmtst_rand_select('a', ' ', '\\', '"', '\'', nmtst_get_rand_uint32() % 255 + 1); + g_assert(ch); + nm_str_buf_append_c(&strbuf, ch); + } + + if (!strbuf.allocated) + nm_str_buf_maybe_expand(&strbuf, 1, nmtst_get_rand_bool()); + return nm_str_buf_finalize(&strbuf, NULL); +} + +static char ** +_strsplit_quoted_create_strv_rand(void) +{ + guint len = nmtst_get_rand_word_length(NULL); + char **ptr; + guint i; + + ptr = g_new(char *, len + 1); + for (i = 0; i < len; i++) + ptr[i] = _strsplit_quoted_create_str_rand(-1); + ptr[i] = NULL; + return ptr; +} + +static char * +_strsplit_quoted_join_strv_rand(const char *const *strv) +{ + NMStrBuf strbuf = NM_STR_BUF_INIT(nmtst_get_rand_uint32() % 200, nmtst_get_rand_bool()); + char * result; + gsize l; + gsize l2; + gsize * p_l2 = nmtst_get_rand_bool() ? &l2 : NULL; + gsize i; + + g_assert(strv); + + nm_str_buf_append_c_repeated(&strbuf, ' ', nmtst_get_rand_word_length(NULL) / 4); + for (i = 0; strv[i]; i++) { + const char *s = strv[i]; + gsize j; + char quote; + + nm_str_buf_append_c_repeated(&strbuf, ' ', 1 + nmtst_get_rand_word_length(NULL) / 4); + + j = 0; + quote = '\0'; + while (TRUE) { + char ch = s[j++]; + + /* extract_first_word*/ + if (quote != '\0') { + if (ch == '\0') { + nm_str_buf_append_c(&strbuf, quote); + break; + } + if (ch == quote || ch == '\\' || nmtst_get_rand_uint32() % 5 == 0) + nm_str_buf_append_c(&strbuf, '\\'); + nm_str_buf_append_c(&strbuf, ch); + if (nmtst_get_rand_uint32() % 3 == 0) { + nm_str_buf_append_c(&strbuf, quote); + quote = '\0'; + goto next_maybe_quote; + } + continue; + } + + if (ch == '\0') { + if (s == strv[i]) { + quote = nmtst_rand_select('\'', '"'); + nm_str_buf_append_c_repeated(&strbuf, quote, 2); + } + break; + } + + if (_strsplit_quoted_char_needs_escaping(ch) || nmtst_get_rand_uint32() % 5 == 0) + nm_str_buf_append_c(&strbuf, '\\'); + + nm_str_buf_append_c(&strbuf, ch); + +next_maybe_quote: + if (nmtst_get_rand_uint32() % 5 == 0) { + quote = nmtst_rand_select('\'', '\"'); + nm_str_buf_append_c(&strbuf, quote); + if (nmtst_get_rand_uint32() % 5 == 0) { + nm_str_buf_append_c(&strbuf, quote); + quote = '\0'; + } + } + } + } + nm_str_buf_append_c_repeated(&strbuf, ' ', nmtst_get_rand_word_length(NULL) / 4); + + nm_str_buf_maybe_expand(&strbuf, 1, nmtst_get_rand_bool()); + + l = strbuf.len; + result = nm_str_buf_finalize(&strbuf, p_l2); + g_assert(!p_l2 || l == *p_l2); + g_assert(strlen(result) == l); + return result; +} + +static void +_strsplit_quoted_assert_strv(const char * topic, + const char * str, + const char *const *strv1, + const char *const *strv2) +{ + nm_auto_str_buf NMStrBuf s1 = {}; + nm_auto_str_buf NMStrBuf s2 = {}; + gs_free char * str_escaped = NULL; + int i; + + g_assert(str); + g_assert(strv1); + g_assert(strv2); + + if (nm_utils_strv_equal(strv1, strv2)) + return; + + for (i = 0; strv1[i]; i++) { + gs_free char *s = g_strescape(strv1[i], NULL); + + g_print(">>> [%s] strv1[%d] = \"%s\"\n", topic, i, s); + if (i > 0) + nm_str_buf_append_c(&s1, ' '); + nm_str_buf_append_printf(&s1, "\"%s\"", s); + } + + for (i = 0; strv2[i]; i++) { + gs_free char *s = g_strescape(strv2[i], NULL); + + g_print(">>> [%s] strv2[%d] = \"%s\"\n", topic, i, s); + if (i > 0) + nm_str_buf_append_c(&s2, ' '); + nm_str_buf_append_printf(&s2, "\"%s\"", s); + } + + nm_str_buf_maybe_expand(&s1, 1, FALSE); + nm_str_buf_maybe_expand(&s2, 1, FALSE); + + str_escaped = g_strescape(str, NULL); + g_error("compared words differs: [%s] str=\"%s\"; strv1=%s; strv2=%s", + topic, + str_escaped, + nm_str_buf_get_str(&s1), + nm_str_buf_get_str(&s2)); +} + +static void +_strsplit_quoted_test(const char *str, const char *const *strv_expected) +{ + gs_strfreev char **strv_systemd = NULL; + gs_strfreev char **strv_nm = NULL; + int r; + + g_assert(str); + + r = nmtst_systemd_extract_first_word_all(str, &strv_systemd); + g_assert_cmpint(r, ==, 1); + g_assert(strv_systemd); + + if (!strv_expected) + strv_expected = (const char *const *) strv_systemd; + + _strsplit_quoted_assert_strv("systemd", str, strv_expected, (const char *const *) strv_systemd); + + strv_nm = nm_utils_strsplit_quoted(str); + g_assert(strv_nm); + _strsplit_quoted_assert_strv("nm", str, strv_expected, (const char *const *) strv_nm); +} + +static void +test_strsplit_quoted(void) +{ + int i_run; + + _strsplit_quoted_test("", NM_MAKE_STRV()); + _strsplit_quoted_test(" ", NM_MAKE_STRV()); + _strsplit_quoted_test(" ", NM_MAKE_STRV()); + _strsplit_quoted_test(" \t", NM_MAKE_STRV()); + _strsplit_quoted_test("a b", NM_MAKE_STRV("a", "b")); + _strsplit_quoted_test("a\\ b", NM_MAKE_STRV("a b")); + _strsplit_quoted_test(" a\\ \"b\"", NM_MAKE_STRV("a b")); + _strsplit_quoted_test(" a\\ \"b\" c \n", NM_MAKE_STRV("a b", "c")); + + for (i_run = 0; i_run < 1000; i_run++) { + gs_strfreev char **strv = NULL; + gs_free char * str = NULL; + + /* create random strv array and join them carefully so that splitting + * them will yield the original value. */ + strv = _strsplit_quoted_create_strv_rand(); + str = _strsplit_quoted_join_strv_rand((const char *const *) strv); + _strsplit_quoted_test(str, (const char *const *) strv); + } + + /* Create random words and assert that systemd and our implementation can + * both split them (and in the exact same way). */ + for (i_run = 0; i_run < 1000; i_run++) { + gs_free char *s = _strsplit_quoted_create_str_rand(nmtst_get_rand_uint32() % 150); + + _strsplit_quoted_test(s, NULL); + } +} + +/*****************************************************************************/ + +static void +_do_wifi_ghz_freqs(const guint *freqs, const char *band) +{ + int len; + int j; + int i; + + g_assert(NM_IN_STRSET(band, "a", "bg")); + g_assert(freqs); + g_assert(freqs[0] != 0); + + for (i = 0; freqs[i]; i++) { + for (j = 0; j < i; j++) + g_assert(freqs[i] != freqs[j]); + } + len = i; + + g_assert(nm_utils_wifi_freq_to_channel(0) == 0); + g_assert(nm_utils_wifi_channel_to_freq(0, "bg") == -1); + g_assert(nm_utils_wifi_channel_to_freq(0, "foo") == 0); + g_assert(!nm_utils_wifi_is_channel_valid(0, "bg")); + g_assert(!nm_utils_wifi_is_channel_valid(0, "foo")); + + for (i = 0; i < len; i++) { + guint freq = freqs[i]; + guint32 chan; + guint32 freq2; + + chan = nm_utils_wifi_freq_to_channel(freq); + g_assert(chan != 0); + + freq2 = nm_utils_wifi_channel_to_freq(chan, band); + g_assert(freq2 == freq); + + g_assert(nm_utils_wifi_is_channel_valid(chan, band)); + } + + g_assert(freqs[len] == 0); +} + +static void +test_nm_utils_wifi_ghz_freqs(void) +{ + _do_wifi_ghz_freqs(nm_utils_wifi_2ghz_freqs(), "bg"); + _do_wifi_ghz_freqs(nm_utils_wifi_5ghz_freqs(), "a"); +} + +/*****************************************************************************/ + +static void +test_vpn_connection_state_reason(void) +{ +#define ASSERT(v1, v2) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT((gint64)(v1) == v2); \ + G_STATIC_ASSERT((gint64)(v2) == v1); \ + \ + nm_assert(((NMActiveConnectionStateReason)(int) (v1)) == v2); \ + nm_assert(((NMVpnConnectionStateReason)(int) (v2)) == v1); \ + } \ + G_STMT_END + + ASSERT(NM_VPN_CONNECTION_STATE_REASON_UNKNOWN, NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_NONE, NM_ACTIVE_CONNECTION_STATE_REASON_NONE); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED, + NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED, + NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED, + NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_STOPPED); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID, + NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, + NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT, + NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED, + NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS, NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED, + NM_ACTIVE_CONNECTION_STATE_REASON_LOGIN_FAILED); + ASSERT(NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED, + NM_ACTIVE_CONNECTION_STATE_REASON_CONNECTION_REMOVED); +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_func("/core/general/test_nm_ascii_spaces", test_nm_ascii_spaces); + g_test_add_func("/core/general/test_wired_wake_on_lan_enum", test_wired_wake_on_lan_enum); + g_test_add_func("/core/general/test_wireless_wake_on_wlan_enum", + test_wireless_wake_on_wlan_enum); + g_test_add_func("/core/general/test_device_wifi_capabilities", test_device_wifi_capabilities); + g_test_add_func("/core/general/test_80211_mode", test_80211_mode); + g_test_add_func("/core/general/test_vlan_flags", test_vlan_flags); + g_test_add_func("/core/general/test_nm_hash", test_nm_hash); + g_test_add_func("/core/general/test_nm_g_slice_free_fcn", test_nm_g_slice_free_fcn); + g_test_add_func("/core/general/test_c_list_sort", test_c_list_sort); + g_test_add_func("/core/general/test_dedup_multi", test_dedup_multi); + g_test_add_func("/core/general/test_utils_str_utf8safe", test_utils_str_utf8safe); + g_test_add_func("/core/general/test_nm_utils_strsplit_set", test_nm_utils_strsplit_set); + g_test_add_func("/core/general/test_nm_utils_escaped_tokens", test_nm_utils_escaped_tokens); + g_test_add_func("/core/general/test_nm_in_set", test_nm_in_set); + g_test_add_func("/core/general/test_nm_in_strset", test_nm_in_strset); + g_test_add_func("/core/general/test_setting_vpn_items", test_setting_vpn_items); + g_test_add_func("/core/general/test_setting_vpn_update_secrets", + test_setting_vpn_update_secrets); + g_test_add_func("/core/general/test_setting_vpn_modify_during_foreach", + test_setting_vpn_modify_during_foreach); + g_test_add_func("/core/general/test_setting_ip4_config_labels", test_setting_ip4_config_labels); + g_test_add_func("/core/general/test_setting_ip4_config_address_data", + test_setting_ip4_config_address_data); + g_test_add_func("/core/general/test_setting_ip_route_attributes", + test_setting_ip_route_attributes); + g_test_add_func("/core/general/test_setting_gsm_apn_spaces", test_setting_gsm_apn_spaces); + g_test_add_func("/core/general/test_setting_gsm_apn_bad_chars", test_setting_gsm_apn_bad_chars); + g_test_add_func("/core/general/test_setting_gsm_apn_underscore", + test_setting_gsm_apn_underscore); + g_test_add_func("/core/general/test_setting_gsm_without_number", + test_setting_gsm_without_number); + g_test_add_func("/core/general/test_setting_gsm_sim_operator_id", + test_setting_gsm_sim_operator_id); + g_test_add_func("/core/general/test_setting_to_dbus_all", test_setting_to_dbus_all); + g_test_add_func("/core/general/test_setting_to_dbus_no_secrets", + test_setting_to_dbus_no_secrets); + g_test_add_func("/core/general/test_setting_to_dbus_only_secrets", + test_setting_to_dbus_only_secrets); + g_test_add_func("/core/general/test_setting_to_dbus_transform", test_setting_to_dbus_transform); + g_test_add_func("/core/general/test_setting_to_dbus_enum", test_setting_to_dbus_enum); + g_test_add_func("/core/general/test_setting_compare_id", test_setting_compare_id); + g_test_add_func("/core/general/test_setting_compare_addresses", test_setting_compare_addresses); + g_test_add_func("/core/general/test_setting_compare_routes", test_setting_compare_routes); + g_test_add_func("/core/general/test_setting_compare_wired_cloned_mac_address", + test_setting_compare_wired_cloned_mac_address); + g_test_add_func("/core/general/test_setting_compare_wirless_cloned_mac_address", + test_setting_compare_wireless_cloned_mac_address); + g_test_add_func("/core/general/test_setting_compare_timestamp", test_setting_compare_timestamp); +#define ADD_FUNC(name, func, secret_flags, comp_flags, remove_secret) \ + g_test_add_data_func_full( \ + "/core/general/" G_STRINGIFY(func) "_" name, \ + test_data_compare_secrets_new(secret_flags, comp_flags, remove_secret), \ + func, \ + g_free) + ADD_FUNC("agent_owned", + test_setting_compare_secrets, + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, + TRUE); + ADD_FUNC("not_saved", + test_setting_compare_secrets, + NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, + TRUE); + ADD_FUNC("secrets", + test_setting_compare_secrets, + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, + TRUE); + ADD_FUNC("exact", + test_setting_compare_secrets, + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_COMPARE_FLAG_EXACT, + FALSE); + ADD_FUNC("agent_owned", + test_setting_compare_vpn_secrets, + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, + TRUE); + ADD_FUNC("not_saved", + test_setting_compare_vpn_secrets, + NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, + TRUE); + ADD_FUNC("secrets", + test_setting_compare_vpn_secrets, + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, + TRUE); + ADD_FUNC("exact", + test_setting_compare_vpn_secrets, + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_COMPARE_FLAG_EXACT, + FALSE); + g_test_add_func("/core/general/test_setting_old_uuid", test_setting_old_uuid); + + g_test_add_func("/core/general/test_connection_to_dbus_setting_name", + test_connection_to_dbus_setting_name); + g_test_add_func("/core/general/test_connection_to_dbus_deprecated_props", + test_connection_to_dbus_deprecated_props); + g_test_add_func("/core/general/test_setting_new_from_dbus", test_setting_new_from_dbus); + g_test_add_func("/core/general/test_setting_new_from_dbus_transform", + test_setting_new_from_dbus_transform); + g_test_add_func("/core/general/test_setting_new_from_dbus_enum", + test_setting_new_from_dbus_enum); + g_test_add_func("/core/general/test_setting_new_from_dbus_bad", test_setting_new_from_dbus_bad); + g_test_add_func("/core/general/test_connection_replace_settings", + test_connection_replace_settings); + g_test_add_func("/core/general/test_connection_replace_settings_from_connection", + test_connection_replace_settings_from_connection); + g_test_add_func("/core/general/test_connection_replace_settings_bad", + test_connection_replace_settings_bad); + g_test_add_func("/core/general/test_connection_new_from_dbus", test_connection_new_from_dbus); + g_test_add_func("/core/general/test_connection_normalize_virtual_iface_name", + test_connection_normalize_virtual_iface_name); + g_test_add_func("/core/general/test_connection_normalize_uuid", test_connection_normalize_uuid); + g_test_add_func("/core/general/test_connection_normalize_type", test_connection_normalize_type); + g_test_add_func("/core/general/test_connection_normalize_slave_type_1", + test_connection_normalize_slave_type_1); + g_test_add_func("/core/general/test_connection_normalize_slave_type_2", + test_connection_normalize_slave_type_2); + g_test_add_func("/core/general/test_connection_normalize_infiniband_mtu", + test_connection_normalize_infiniband_mtu); + g_test_add_func("/core/general/test_connection_normalize_gateway_never_default", + test_connection_normalize_gateway_never_default); + g_test_add_func("/core/general/test_connection_normalize_may_fail", + test_connection_normalize_may_fail); + g_test_add_func("/core/general/test_connection_normalize_shared_addresses", + test_connection_normalize_shared_addresses); + g_test_add_data_func("/core/general/test_connection_normalize_ovs_interface_type_system/1", + GUINT_TO_POINTER(1), + test_connection_normalize_ovs_interface_type_system); + g_test_add_data_func("/core/general/test_connection_normalize_ovs_interface_type_system/2", + GUINT_TO_POINTER(2), + test_connection_normalize_ovs_interface_type_system); + g_test_add_data_func("/core/general/test_connection_normalize_ovs_interface_type_system/3", + GUINT_TO_POINTER(3), + test_connection_normalize_ovs_interface_type_system); + g_test_add_data_func("/core/general/test_connection_normalize_ovs_interface_type_system/4", + GUINT_TO_POINTER(4), + test_connection_normalize_ovs_interface_type_system); + g_test_add_data_func("/core/general/test_connection_normalize_ovs_interface_type_system/5", + GUINT_TO_POINTER(5), + test_connection_normalize_ovs_interface_type_system); + g_test_add_data_func("/core/general/test_connection_normalize_ovs_interface_type_system/6", + GUINT_TO_POINTER(6), + test_connection_normalize_ovs_interface_type_system); + g_test_add_data_func("/core/general/test_connection_normalize_ovs_interface_type_system/7", + GUINT_TO_POINTER(7), + test_connection_normalize_ovs_interface_type_system); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/1", + GUINT_TO_POINTER(1), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/2", + GUINT_TO_POINTER(2), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/3", + GUINT_TO_POINTER(3), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/4", + GUINT_TO_POINTER(4), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/5", + GUINT_TO_POINTER(5), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/6", + GUINT_TO_POINTER(6), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/7", + GUINT_TO_POINTER(7), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/8", + GUINT_TO_POINTER(8), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/9", + GUINT_TO_POINTER(9), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/10", + GUINT_TO_POINTER(10), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/11", + GUINT_TO_POINTER(11), + test_connection_normalize_ovs_interface_type_ovs_interface); + g_test_add_data_func( + "/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/12", + GUINT_TO_POINTER(12), + test_connection_normalize_ovs_interface_type_ovs_interface); + + g_test_add_data_func("/core/general/test_connection_ovs_ifname/1", + GUINT_TO_POINTER(1), + test_connection_ovs_ifname); + g_test_add_data_func("/core/general/test_connection_ovs_ifname/2", + GUINT_TO_POINTER(2), + test_connection_ovs_ifname); + g_test_add_data_func("/core/general/test_connection_ovs_ifname/3", + GUINT_TO_POINTER(3), + test_connection_ovs_ifname); + g_test_add_data_func("/core/general/test_connection_ovs_ifname/4", + GUINT_TO_POINTER(4), + test_connection_ovs_ifname); + g_test_add_data_func("/core/general/test_connection_ovs_ifname/5", + GUINT_TO_POINTER(5), + test_connection_ovs_ifname); + g_test_add_data_func("/core/general/test_connection_ovs_ifname/6", + GUINT_TO_POINTER(6), + test_connection_ovs_ifname); + + g_test_add_func("/core/general/test_setting_connection_permissions_helpers", + test_setting_connection_permissions_helpers); + g_test_add_func("/core/general/test_setting_connection_permissions_property", + test_setting_connection_permissions_property); + + g_test_add_func("/core/general/test_connection_compare_same", test_connection_compare_same); + g_test_add_func("/core/general/test_connection_compare_key_only_in_a", + test_connection_compare_key_only_in_a); + g_test_add_func("/core/general/test_connection_compare_setting_only_in_a", + test_connection_compare_setting_only_in_a); + g_test_add_func("/core/general/test_connection_compare_key_only_in_b", + test_connection_compare_key_only_in_b); + g_test_add_func("/core/general/test_connection_compare_setting_only_in_b", + test_connection_compare_setting_only_in_b); + + g_test_add_func("/core/general/test_connection_diff_a_only", test_connection_diff_a_only); + g_test_add_func("/core/general/test_connection_diff_same", test_connection_diff_same); + g_test_add_func("/core/general/test_connection_diff_different", test_connection_diff_different); + g_test_add_func("/core/general/test_connection_diff_no_secrets", + test_connection_diff_no_secrets); + g_test_add_func("/core/general/test_connection_diff_inferrable", + test_connection_diff_inferrable); + g_test_add_func("/core/general/test_connection_good_base_types", + test_connection_good_base_types); + g_test_add_func("/core/general/test_connection_bad_base_types", test_connection_bad_base_types); + + g_test_add_func("/core/general/test_hwaddr_aton_ether_normal", test_hwaddr_aton_ether_normal); + g_test_add_func("/core/general/test_hwaddr_aton_ib_normal", test_hwaddr_aton_ib_normal); + g_test_add_func("/core/general/test_hwaddr_aton_no_leading_zeros", + test_hwaddr_aton_no_leading_zeros); + g_test_add_func("/core/general/test_hwaddr_aton_malformed", test_hwaddr_aton_malformed); + g_test_add_func("/core/general/test_hwaddr_equal", test_hwaddr_equal); + g_test_add_func("/core/general/test_hwaddr_canonical", test_hwaddr_canonical); + + g_test_add_func("/core/general/test_ip4_prefix_to_netmask", test_ip4_prefix_to_netmask); + g_test_add_func("/core/general/test_ip4_netmask_to_prefix", test_ip4_netmask_to_prefix); + + g_test_add_func("/core/general/test_connection_changed_signal", test_connection_changed_signal); + g_test_add_func("/core/general/test_setting_connection_changed_signal", + test_setting_connection_changed_signal); + g_test_add_func("/core/general/test_setting_bond_changed_signal", + test_setting_bond_changed_signal); + g_test_add_func("/core/general/test_setting_ip4_changed_signal", + test_setting_ip4_changed_signal); + g_test_add_func("/core/general/test_setting_ip6_changed_signal", + test_setting_ip6_changed_signal); + g_test_add_func("/core/general/test_setting_vlan_changed_signal", + test_setting_vlan_changed_signal); + g_test_add_func("/core/general/test_setting_vpn_changed_signal", + test_setting_vpn_changed_signal); + g_test_add_func("/core/general/test_setting_wired_changed_signal", + test_setting_wired_changed_signal); + g_test_add_func("/core/general/test_setting_wireless_changed_signal", + test_setting_wireless_changed_signal); + g_test_add_func("/core/general/test_setting_wireless_security_changed_signal", + test_setting_wireless_security_changed_signal); + g_test_add_func("/core/general/test_setting_802_1x_changed_signal", + test_setting_802_1x_changed_signal); + g_test_add_func("/core/general/test_setting_ip4_gateway", test_setting_ip4_gateway); + g_test_add_func("/core/general/test_setting_ip6_gateway", test_setting_ip6_gateway); + g_test_add_func("/core/general/test_setting_compare_default_strv", + test_setting_compare_default_strv); + g_test_add_func("/core/general/test_setting_user_data", test_setting_user_data); + + g_test_add_func("/core/general/test_sock_addr_endpoint", test_sock_addr_endpoint); + + g_test_add_func("/core/general/hexstr2bin", test_hexstr2bin); + g_test_add_func("/core/general/nm_strquote", test_nm_strquote); + g_test_add_func("/core/general/test_nm_utils_uuid_generate_from_string", + test_nm_utils_uuid_generate_from_string); + g_test_add_func("/core/general/_nm_utils_uuid_generate_from_strings", + test_nm_utils_uuid_generate_from_strings); + + g_test_add_func("/core/general/_nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64); + g_test_add_func("/core/general/nm_utils_is_power_of_two", test_nm_utils_is_power_of_two); + g_test_add_func("/core/general/nm_utils_ptrarray_find_binary_search_range", + test_nm_utils_ptrarray_find_binary_search); + g_test_add_func("/core/general/nm_utils_ptrarray_find_binary_search_with_duplicates", + test_nm_utils_ptrarray_find_binary_search_with_duplicates); + g_test_add_func("/core/general/_nm_utils_strstrdictkey", test_nm_utils_strstrdictkey); + g_test_add_func("/core/general/nm_ptrarray_len", test_nm_ptrarray_len); + + g_test_add_func("/core/general/_nm_utils_dns_option_validate", + test_nm_utils_dns_option_validate); + g_test_add_func("/core/general/_nm_utils_dns_option_find_idx", + test_nm_utils_dns_option_find_idx); + g_test_add_func("/core/general/_nm_utils_validate_json", test_nm_utils_check_valid_json); + g_test_add_func("/core/general/_nm_utils_team_config_equal", test_nm_utils_team_config_equal); + g_test_add_func("/core/general/test_nm_utils_enum", test_nm_utils_enum); + g_test_add_func("/core/general/nm-set-out", test_nm_set_out); + g_test_add_func("/core/general/route_attributes/parse", test_route_attributes_parse); + g_test_add_func("/core/general/route_attributes/format", test_route_attributes_format); + g_test_add_func("/core/general/test_variant_attribute_spec", test_variant_attribute_spec); + + g_test_add_func("/core/general/get_start_time_for_pid", test_get_start_time_for_pid); + g_test_add_func("/core/general/test_nm_va_args_macros", test_nm_va_args_macros); + g_test_add_func("/core/general/test_ethtool_offload", test_ethtool_offload); + + g_test_add_data_func("/core/general/test_integrate_maincontext/1", + GUINT_TO_POINTER(1), + test_integrate_maincontext); + g_test_add_data_func("/core/general/test_integrate_maincontext/2", + GUINT_TO_POINTER(2), + test_integrate_maincontext); + + g_test_add_func("/core/general/test_nm_ip_addr_zero", test_nm_ip_addr_zero); + g_test_add_func("/core/general/test_nm_utils_wifi_ghz_freqs", test_nm_utils_wifi_ghz_freqs); + + g_test_add_func("/core/general/test_strsplit_quoted", test_strsplit_quoted); + g_test_add_func("/core/general/test_vpn_connection_state_reason", + test_vpn_connection_state_reason); + + return g_test_run(); +} diff --git a/src/libnm-core-impl/tests/test-keyfile.c b/src/libnm-core-impl/tests/test-keyfile.c new file mode 100644 index 0000000..2e5483e --- /dev/null +++ b/src/libnm-core-impl/tests/test-keyfile.c @@ -0,0 +1,909 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "libnm-glib-aux/nm-json-aux.h" +#include "libnm-core-intern/nm-keyfile-utils.h" +#include "libnm-core-intern/nm-keyfile-internal.h" +#include "nm-simple-connection.h" +#include "nm-setting-connection.h" +#include "nm-setting-wired.h" +#include "nm-setting-8021x.h" +#include "nm-setting-team.h" +#include "nm-setting-user.h" +#include "nm-setting-proxy.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +#define TEST_CERT_DIR NM_BUILD_SRCDIR "/src/libnm-core-impl/tests/certs" +#define TEST_WIRED_TLS_CA_CERT TEST_CERT_DIR "/test-ca-cert.pem" +#define TEST_WIRED_TLS_PRIVKEY TEST_CERT_DIR "/test-key-and-cert.pem" +#define TEST_WIRED_TLS_TPM2KEY TEST_CERT_DIR "/test-tpm2wrapped-key.pem" + +/*****************************************************************************/ + +static void +do_test_encode_key_full(GKeyFile * kf, + const char *name, + const char *key, + const char *key_decode_encode) +{ + gs_free char *to_free1 = NULL; + gs_free char *to_free2 = NULL; + const char * key2; + const char * name2; + + g_assert(key); + + if (name) { + key2 = nm_keyfile_key_encode(name, &to_free1); + g_assert(key2); + g_assert(NM_STRCHAR_ALL(key2, ch, (guchar) ch < 127)); + g_assert_cmpstr(key2, ==, key); + + /* try to add the encoded key to the keyfile. We expect + * no g_critical warning about invalid key. */ + g_key_file_set_value(kf, "group", key, "dummy"); + } + + name2 = nm_keyfile_key_decode(key, &to_free2); + if (name) + g_assert_cmpstr(name2, ==, name); + else { + key2 = nm_keyfile_key_encode(name2, &to_free1); + g_assert(key2); + g_assert(NM_STRCHAR_ALL(key2, ch, (guchar) ch < 127)); + if (key_decode_encode) + g_assert_cmpstr(key2, ==, key_decode_encode); + g_key_file_set_value(kf, "group", key2, "dummy"); + } +} + +#define do_test_encode_key_bijection(kf, name, key) \ + do_test_encode_key_full(kf, "" name, "" key, NULL) +#define do_test_encode_key_identity(kf, name) do_test_encode_key_full(kf, "" name, "" name, NULL) +#define do_test_encode_key_decode_surjection(kf, key, key_decode_encode) \ + do_test_encode_key_full(kf, NULL, "" key, "" key_decode_encode) + +static void +test_encode_key(void) +{ + nm_auto_unref_keyfile GKeyFile *kf = g_key_file_new(); + + do_test_encode_key_identity(kf, "a"); + do_test_encode_key_bijection(kf, "", "\\00"); + do_test_encode_key_bijection(kf, " ", "\\20"); + do_test_encode_key_bijection(kf, "\\ ", "\\\\20"); + do_test_encode_key_identity(kf, "\\0"); + do_test_encode_key_identity(kf, "\\a"); + do_test_encode_key_identity(kf, "\\0g"); + do_test_encode_key_bijection(kf, "\\0f", "\\5C0f"); + do_test_encode_key_bijection(kf, "\\0f ", "\\5C0f\\20"); + do_test_encode_key_bijection(kf, " \\0f ", "\\20\\5C0f\\20"); + do_test_encode_key_bijection(kf, "\xF5", "\\F5"); + do_test_encode_key_bijection(kf, "\x7F", "\\7F"); + do_test_encode_key_bijection(kf, "\x1f", "\\1F"); + do_test_encode_key_bijection(kf, " ", "\\20\\20"); + do_test_encode_key_bijection(kf, " ", "\\20 \\20"); + do_test_encode_key_decode_surjection(kf, "f\\20c", "f c"); + do_test_encode_key_decode_surjection(kf, "\\20\\20\\20", "\\20 \\20"); + + do_test_encode_key_bijection(kf, "\t", "\\09"); + do_test_encode_key_bijection(kf, "\t=x", "\\09\\3Dx"); + do_test_encode_key_bijection( + kf, + "(nm-openvpn-auth-dialog:10283): GdkPixbuf-DEBUG: \tCopy pixels == false", + "(nm-openvpn-auth-dialog:10283): GdkPixbuf-DEBUG: \\09Copy pixels \\3D\\3D false"); +} + +/*****************************************************************************/ + +#define CLEAR(con, keyfile) \ + G_STMT_START \ + { \ + NMConnection **_con = (con); \ + GKeyFile ** _keyfile = (keyfile); \ + \ + g_clear_object(_con); \ + nm_clear_pointer(_keyfile, g_key_file_unref); \ + } \ + G_STMT_END + +static void +_assert_gbytes(GBytes *bytes, gconstpointer data, gssize len) +{ + g_assert((data && len > 0) || !len || (data && len == -1)); + + if (len == -1) + len = strlen(data); + + if (!len) + g_assert(!bytes); + + g_assert(nm_utils_gbytes_equal_mem(bytes, data, len)); +} + +static GKeyFile * +_keyfile_load_from_data(const char *str) +{ + GError * error = NULL; + gboolean success; + GKeyFile *keyfile; + + g_assert(str); + + keyfile = g_key_file_new(); + success = g_key_file_load_from_data(keyfile, str, strlen(str), G_KEY_FILE_NONE, &error); + g_assert_no_error(error); + g_assert(success); + + return keyfile; +} + +static GKeyFile * +_nm_keyfile_write(NMConnection *connection, NMKeyfileWriteHandler handler, void *user_data) +{ + GError * error = NULL; + GKeyFile *kf; + + g_assert(NM_IS_CONNECTION(connection)); + + kf = nm_keyfile_write(connection, NM_KEYFILE_HANDLER_FLAGS_NONE, handler, user_data, &error); + g_assert_no_error(error); + g_assert(kf); + return kf; +} + +static NMConnection * +_nm_keyfile_read(GKeyFile * keyfile, + const char * keyfile_name, + NMKeyfileReadHandler read_handler, + void * read_data, + gboolean needs_normalization) +{ + GError * error = NULL; + NMConnection *con; + gs_free char *filename = NULL; + gs_free char *base_dir = NULL; + + g_assert(keyfile); + g_assert(!keyfile_name || (keyfile_name[0] == '/')); + + base_dir = g_path_get_dirname(keyfile_name); + filename = g_path_get_basename(keyfile_name); + + con = nm_keyfile_read(keyfile, + base_dir, + NM_KEYFILE_HANDLER_FLAGS_NONE, + read_handler, + read_data, + &error); + g_assert_no_error(error); + g_assert(NM_IS_CONNECTION(con)); + + nm_keyfile_read_ensure_id(con, filename); + nm_keyfile_read_ensure_uuid(con, keyfile_name); + + if (needs_normalization) { + nmtst_assert_connection_verifies_after_normalization(con, 0, 0); + nmtst_connection_normalize(con); + } else { + { + NMSettingConnection *s_con; + + /* a non-slave connection must have a proxy setting, but + * keyfile reader does not add that (unless a [proxy] section + * is present. */ + s_con = nm_connection_get_setting_connection(con); + if (s_con && !nm_setting_connection_get_master(s_con) + && !nm_connection_get_setting_proxy(con)) + nm_connection_add_setting(con, nm_setting_proxy_new()); + } + nmtst_assert_connection_verifies_without_normalization(con); + } + return con; +} + +static void +_keyfile_convert(NMConnection ** con, + GKeyFile ** keyfile, + const char * keyfile_name, + NMKeyfileReadHandler read_handler, + void * read_data, + NMKeyfileWriteHandler write_handler, + void * write_data, + gboolean needs_normalization) +{ + NMConnection * c0; + GKeyFile * k0; + gs_unref_object NMConnection *c0_k1_c2 = NULL, *k0_c1 = NULL, *k0_c1_k2_c3 = NULL; + nm_auto_unref_keyfile GKeyFile *k0_c1_k2 = NULL, *c0_k1 = NULL, *c0_k1_c2_k3 = NULL; + + /* convert from @con to @keyfile and check that we can make + * full round trips and obtaining the same result. */ + + g_assert(con); + g_assert(keyfile); + g_assert(*con || *keyfile); + + c0 = *con; + k0 = *keyfile; + + if (c0) { + c0_k1 = _nm_keyfile_write(c0, write_handler, write_data); + c0_k1_c2 = _nm_keyfile_read(c0_k1, keyfile_name, read_handler, read_data, FALSE); + c0_k1_c2_k3 = _nm_keyfile_write(c0_k1_c2, write_handler, write_data); + + g_assert(_nm_keyfile_equals(c0_k1, c0_k1_c2_k3, TRUE)); + } + if (k0) { + NMSetting8021x *s1, *s2; + + k0_c1 = _nm_keyfile_read(k0, keyfile_name, read_handler, read_data, needs_normalization); + k0_c1_k2 = _nm_keyfile_write(k0_c1, write_handler, write_data); + k0_c1_k2_c3 = _nm_keyfile_read(k0_c1_k2, keyfile_name, read_handler, read_data, FALSE); + + /* It is a expected behavior, that if @k0 contains a relative path ca-cert, @k0_c1 will + * contain that path as relative. But @k0_c1_k2 and @k0_c1_k2_c3 will have absolute paths. + * In this case, hack up @k0_c1_k2_c3 to contain the same relative path. */ + s1 = nm_connection_get_setting_802_1x(k0_c1); + s2 = nm_connection_get_setting_802_1x(k0_c1_k2_c3); + if (s1 || s2) { + g_assert_cmpint(nm_setting_802_1x_get_ca_cert_scheme(s1), + ==, + nm_setting_802_1x_get_ca_cert_scheme(s2)); + switch (nm_setting_802_1x_get_ca_cert_scheme(s1)) { + case NM_SETTING_802_1X_CK_SCHEME_PATH: + { + const char *p1 = nm_setting_802_1x_get_ca_cert_path(s1); + const char *p2 = nm_setting_802_1x_get_ca_cert_path(s2); + + nmtst_assert_resolve_relative_path_equals(p1, p2); + if (strcmp(p1, p2) != 0) { + gs_free char * puri = NULL; + gs_unref_bytes GBytes *pfile = NULL; + + g_assert(p1[0] != '/' && p2[0] == '/'); + + /* one of the paths is a relative path and the other is absolute. This is an + * expected difference. + * Make the paths of s2 identical to s1... */ + puri = g_strconcat(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH, p1, NULL); + pfile = g_bytes_new(puri, strlen(puri) + 1); + g_object_set(s2, NM_SETTING_802_1X_CA_CERT, pfile, NULL); + } + } break; + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + { + GBytes *b1, *b2; + + b1 = nm_setting_802_1x_get_ca_cert_blob(s1); + b2 = nm_setting_802_1x_get_ca_cert_blob(s2); + g_assert(b1); + g_assert(b2); + g_assert(g_bytes_equal(b1, b2)); + break; + } + default: + break; + } + } + + nmtst_assert_connection_equals(k0_c1, FALSE, k0_c1_k2_c3, FALSE); + } + + if (!k0) + *keyfile = g_key_file_ref(c0_k1); + else if (!c0) + *con = g_object_ref(k0_c1); + else { + /* finally, if both a keyfile and a connection are given, assert that they are equal + * after a round of conversion. */ + g_assert(_nm_keyfile_equals(c0_k1, k0_c1_k2, TRUE)); + nmtst_assert_connection_equals(k0_c1, FALSE, c0_k1_c2, FALSE); + } +} + +/*****************************************************************************/ + +static void +_test_8021x_cert_check(NMConnection * con, + NMSetting8021xCKScheme expected_scheme, + const void * value, + gssize val_len) +{ + GKeyFile * keyfile = NULL; + NMSetting8021x *s_8021x; + gs_free char * kval = NULL; + + _keyfile_convert(&con, &keyfile, "/_test_8021x_cert_check/foo", NULL, NULL, NULL, NULL, FALSE); + + s_8021x = nm_connection_get_setting_802_1x(con); + + g_assert(nm_setting_802_1x_get_ca_cert_scheme(s_8021x) == expected_scheme); + + if (expected_scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + const char *path = nm_setting_802_1x_get_ca_cert_path(s_8021x); + + g_assert_cmpstr(path, ==, value); + g_assert(val_len == -1 || strlen(path) == val_len); + + kval = g_key_file_get_string(keyfile, "802-1x", "ca-cert", NULL); + g_assert(kval); + g_assert_cmpstr(kval, ==, value); + } else if (expected_scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + GBytes * blob = nm_setting_802_1x_get_ca_cert_blob(s_8021x); + gs_free char *file_blob = NULL; + + if (val_len == -1) { + gsize l; + gboolean success; + + success = g_file_get_contents(value, &file_blob, &l, NULL); + g_assert(success); + + value = file_blob; + val_len = l; + } + + g_assert(blob); + g_assert(nm_utils_gbytes_equal_mem(blob, value, val_len)); + + kval = g_key_file_get_string(keyfile, "802-1x", "ca-cert", NULL); + g_assert(kval); + g_assert(g_str_has_prefix(kval, NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB)); + } + + g_key_file_unref(keyfile); +} + +static void +_test_8021x_cert_check_blob_full(NMConnection *con, const void *data, gsize len) +{ + GBytes * bytes; + NMSetting8021x *s_8021x = nm_connection_get_setting_802_1x(con); + + bytes = g_bytes_new(data, len); + g_object_set(s_8021x, NM_SETTING_802_1X_CA_CERT, bytes, NULL); + _test_8021x_cert_check(con, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + g_bytes_get_data(bytes, NULL), + g_bytes_get_size(bytes)); + g_bytes_unref(bytes); +} +#define _test_8021x_cert_check_blob(con, data) \ + _test_8021x_cert_check_blob_full(con, data, NM_STRLEN(data)) + +static void +_test_8021x_cert_from_files(const char *cert, const char *key) +{ + NMSetting8021x *s_8021x; + gs_unref_object NMConnection *con = + nmtst_create_minimal_connection("test-cert", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + GError * error = NULL; + gboolean success; + NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_PATH; + gs_free char *full_TEST_WIRED_TLS_CA_CERT = nmtst_file_resolve_relative_path(cert, NULL); + gs_free char *full_TEST_WIRED_TLS_PRIVKEY = nmtst_file_resolve_relative_path(key, NULL); + + /* test writing/reading of certificates of NMSetting8021x */ + + /* create a valid connection with NMSetting8021x */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_setting_802_1x_add_eap_method(s_8021x, "tls"); + g_object_set(s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + success = + nm_setting_802_1x_set_ca_cert(s_8021x, full_TEST_WIRED_TLS_CA_CERT, scheme, NULL, &error); + g_assert_no_error(error); + g_assert(success); + success = nm_setting_802_1x_set_client_cert(s_8021x, + full_TEST_WIRED_TLS_CA_CERT, + scheme, + NULL, + &error); + g_assert_no_error(error); + g_assert(success); + success = nm_setting_802_1x_set_private_key(s_8021x, + full_TEST_WIRED_TLS_PRIVKEY, + "test1", + scheme, + NULL, + &error); + g_assert_no_error(error); + g_assert(success); + + /* test resetting ca-cert to different values and see whether we can write/read. */ + + nm_connection_add_setting(con, NM_SETTING(s_8021x)); + nmtst_assert_connection_verifies_and_normalizable(con); + nmtst_connection_normalize(con); + + _test_8021x_cert_check(con, scheme, full_TEST_WIRED_TLS_CA_CERT, -1); + + scheme = NM_SETTING_802_1X_CK_SCHEME_BLOB; + success = + nm_setting_802_1x_set_ca_cert(s_8021x, full_TEST_WIRED_TLS_CA_CERT, scheme, NULL, &error); + g_assert_no_error(error); + g_assert(success); + _test_8021x_cert_check(con, scheme, full_TEST_WIRED_TLS_CA_CERT, -1); + + _test_8021x_cert_check_blob(con, "a"); + _test_8021x_cert_check_blob(con, "\0"); + _test_8021x_cert_check_blob(con, "10"); + _test_8021x_cert_check_blob(con, "data:;base64,a"); + _test_8021x_cert_check_blob_full(con, "data:;base64,a", NM_STRLEN("data:;base64,a") + 1); + _test_8021x_cert_check_blob(con, "data:;base64,file://a"); + _test_8021x_cert_check_blob(con, "123"); +} + +static void +test_8021x_cert(void) +{ + _test_8021x_cert_from_files(TEST_WIRED_TLS_CA_CERT, TEST_WIRED_TLS_PRIVKEY); +} + +static void +test_8021x_cert_tpm2key(void) +{ + _test_8021x_cert_from_files(TEST_WIRED_TLS_CA_CERT, TEST_WIRED_TLS_TPM2KEY); +} + +/*****************************************************************************/ + +static void +test_8021x_cert_read(void) +{ + GKeyFile * keyfile = NULL; + gs_unref_object NMConnection *con = NULL; + NMSetting8021x * s_8021x; + + con = nmtst_create_connection_from_keyfile("[connection]\n" + "type=ethernet", + "/test_8021x_cert_read/test0"); + CLEAR(&con, &keyfile); + + keyfile = _keyfile_load_from_data("[connection]\n" + "type=ethernet"); + _keyfile_convert(&con, &keyfile, "/test_8021x_cert_read/test1", NULL, NULL, NULL, NULL, TRUE); + CLEAR(&con, &keyfile); + + keyfile = _keyfile_load_from_data( + "[connection]\n" + "type=802-3-ethernet\n" + + "[802-1x]\n" + "eap=tls;\n" + "identity=Bill Smith\n" + "ca-cert=48;130;2;52;48;130;1;161;2;16;2;173;102;126;78;69;254;94;87;111;60;152;25;94;221;" + "192;48;13;6;9;42;134;72;134;247;13;1;1;2;5;0;48;95;49;11;48;9;6;3;85;4;6;19;2;85;83;49;32;" + "48;30;6;3;85;4;10;19;23;82;83;65;32;68;97;116;97;32;83;101;99;117;114;105;116;121;44;32;" + "73;110;99;46;49;46;48;44;6;3;85;4;11;19;37;83;101;99;117;114;101;32;83;101;114;118;101;" + "114;32;67;101;114;116;105;102;105;99;97;116;105;111;110;32;65;117;116;104;111;114;105;116;" + "121;48;30;23;13;57;52;49;49;48;57;48;48;48;48;48;48;90;23;13;49;48;48;49;48;55;50;51;53;" + "57;53;57;90;48;95;49;11;48;9;6;3;85;4;6;19;2;85;83;49;32;48;30;6;3;85;4;10;19;23;82;83;65;" + "32;68;97;116;97;32;83;101;99;117;114;105;116;121;44;32;73;110;99;46;49;46;48;44;6;3;85;4;" + "11;19;37;83;101;99;117;114;101;32;83;101;114;118;101;114;32;67;101;114;116;105;102;105;99;" + "97;116;105;111;110;32;65;117;116;104;111;114;105;116;121;48;129;155;48;13;6;9;42;134;72;" + "134;247;13;1;1;1;5;0;3;129;137;0;48;129;133;2;126;0;146;206;122;193;174;131;62;90;170;137;" + "131;87;172;37;1;118;12;173;174;142;44;55;206;235;53;120;100;84;3;229;132;64;81;201;191;" + "143;8;226;138;130;8;210;22;134;55;85;233;177;33;2;173;118;104;129;154;5;162;75;201;75;37;" + "102;34;86;108;136;7;143;247;129;89;109;132;7;101;112;19;113;118;62;155;119;76;227;80;137;" + "86;152;72;185;29;167;41;26;19;46;74;17;89;156;30;21;213;73;84;44;115;58;105;130;177;151;" + "57;156;109;112;103;72;229;221;45;214;200;30;123;2;3;1;0;1;48;13;6;9;42;134;72;134;247;13;" + "1;1;2;5;0;3;126;0;101;221;126;225;178;236;176;226;58;224;236;113;70;154;25;17;184;211;199;" + "160;180;3;64;38;2;62;9;156;225;18;179;209;90;246;55;165;183;97;3;182;91;22;105;59;198;68;" + "8;12;136;83;12;107;151;73;199;62;53;220;108;185;187;170;223;92;187;58;47;147;96;182;169;" + "75;77;242;32;247;205;95;127;100;123;142;220;0;92;215;250;119;202;57;22;89;111;14;234;211;" + "181;131;127;77;77;66;86;118;180;201;95;4;248;56;248;235;210;95;117;95;205;123;252;229;142;" + "128;124;252;80;\n" + "client-cert=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;" + "107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;" + "109;0;\n" + "private-key=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;" + "107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;" + "109;0;\n" + "private-key-password=12345testing\n"); + _keyfile_convert(&con, &keyfile, "/test_8021x_cert_read/test2", NULL, NULL, NULL, NULL, TRUE); + CLEAR(&con, &keyfile); + + keyfile = + _keyfile_load_from_data("[connection]\n" + "type=802-3-ethernet\n" + + "[802-1x]\n" + "eap=tls;\n" + "identity=Bill Smith\n" + /* unqualified strings are only recognized as path up to 500 chars*/ + "ca-cert=" + "/11111111111111111111111111111111111111111111111111111111111111111" + "1111111111111111111111111111111111" + "/11111111111111111111111111111111111111111111111111111111111111111" + "1111111111111111111111111111111111" + "/11111111111111111111111111111111111111111111111111111111111111111" + "1111111111111111111111111111111111" + "/11111111111111111111111111111111111111111111111111111111111111111" + "1111111111111111111111111111111111" + "/11111111111111111111111111111111111111111111111111111111111111111" + "111111111111111111111111111111111\n" + "client-cert=/" + "222222222222222222222222222222222222222222222222222222222222222222" + "222222222222222222222222222222221" + "/22222222222222222222222222222222222222222222222222222222222222222" + "2222222222222222222222222222222221" + "/22222222222222222222222222222222222222222222222222222222222222222" + "2222222222222222222222222222222221" + "/22222222222222222222222222222222222222222222222222222222222222222" + "2222222222222222222222222222222221" + "/22222222222222222222222222222222222222222222222222222222222222222" + "2222222222222222222222222222222222\n" + "private-key=file://" + "/33333333333333333333333333333333333333333333333333333333333333333" + "3333333333333333333333333333333331" + "/33333333333333333333333333333333333333333333333333333333333333333" + "3333333333333333333333333333333331" + "/33333333333333333333333333333333333333333333333333333333333333333" + "3333333333333333333333333333333331" + "/33333333333333333333333333333333333333333333333333333333333333333" + "3333333333333333333333333333333331" + "/33333333333333333333333333333333333333333333333333333333333333333" + "333333333333333333333333333333333111111\n" + "private-key-password=12345testing\n"); + _keyfile_convert(&con, &keyfile, "/test_8021x_cert_read/test2", NULL, NULL, NULL, NULL, TRUE); + s_8021x = nm_connection_get_setting_802_1x(con); + + g_assert(nm_setting_802_1x_get_ca_cert_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert(g_str_has_prefix(nm_setting_802_1x_get_ca_cert_path(s_8021x), "/111111111111")); + g_assert_cmpint(strlen(nm_setting_802_1x_get_ca_cert_path(s_8021x)), ==, 499); + + g_assert(nm_setting_802_1x_get_client_cert_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_BLOB); + g_assert( + g_str_has_prefix(g_bytes_get_data(nm_setting_802_1x_get_client_cert_blob(s_8021x), NULL), + "/2222222222")); + g_assert_cmpint(g_bytes_get_size(nm_setting_802_1x_get_client_cert_blob(s_8021x)), + ==, + 500 + 1 /* keyfile reader adds a trailing NUL */); + + g_assert(nm_setting_802_1x_get_private_key_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert(g_str_has_prefix(nm_setting_802_1x_get_private_key_path(s_8021x), "/333333333")); + g_assert_cmpint(strlen(nm_setting_802_1x_get_private_key_path(s_8021x)), ==, 505); + CLEAR(&con, &keyfile); + + keyfile = _keyfile_load_from_data("[connection]\n" + "type=802-3-ethernet\n" + + "[802-1x]\n" + "eap=tls;\n" + "identity=Bill Smith\n" + "ca-cert=/\n" + "client-cert=a.pem\n" + "private-key=data:;base64,aGFsbG8=\n" // hallo + "private-key-password=12345testing\n"); + _keyfile_convert(&con, &keyfile, "/test_8021x_cert_read/test2", NULL, NULL, NULL, NULL, TRUE); + s_8021x = nm_connection_get_setting_802_1x(con); + + g_assert(nm_setting_802_1x_get_ca_cert_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert_cmpstr(nm_setting_802_1x_get_ca_cert_path(s_8021x), ==, "/"); + + g_assert(nm_setting_802_1x_get_client_cert_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert_cmpstr(nm_setting_802_1x_get_client_cert_path(s_8021x), + ==, + "/test_8021x_cert_read/a.pem"); + + g_assert(nm_setting_802_1x_get_private_key_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_BLOB); + _assert_gbytes(nm_setting_802_1x_get_private_key_blob(s_8021x), "hallo", -1); + CLEAR(&con, &keyfile); + + keyfile = _keyfile_load_from_data("[connection]\n" + "type=802-3-ethernet\n" + + "[802-1x]\n" + "eap=tls;\n" + "identity=Bill Smith\n" + "ca-cert=file://data:;base64,x\n" + "client-cert=abc.der\n" + "private-key=abc.deR\n" + "private-key-password=12345testing\n"); + _keyfile_convert(&con, &keyfile, "/test_8021x_cert_read/test2", NULL, NULL, NULL, NULL, TRUE); + s_8021x = nm_connection_get_setting_802_1x(con); + + g_assert(nm_setting_802_1x_get_ca_cert_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert_cmpstr(nm_setting_802_1x_get_ca_cert_path(s_8021x), ==, "data:;base64,x"); + + g_assert(nm_setting_802_1x_get_client_cert_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert_cmpstr(nm_setting_802_1x_get_client_cert_path(s_8021x), + ==, + "/test_8021x_cert_read/abc.der"); + + g_assert(nm_setting_802_1x_get_private_key_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_BLOB); + _assert_gbytes(nm_setting_802_1x_get_private_key_blob(s_8021x), "abc.deR\0", 8); + CLEAR(&con, &keyfile); + + keyfile = + _keyfile_load_from_data("[connection]\n" + "type=802-3-ethernet\n" + + "[802-1x]\n" + "eap=tls;\n" + "identity=Bill Smith\n" + "ca-cert=104;97;108;108;111;\n" /* "hallo" without trailing NUL */ + "client-cert=104;097;108;108;111;0;\n" + "private-key=hallo\n" + "private-key-password=12345testing\n"); + _keyfile_convert(&con, &keyfile, "/test_8021x_cert_read/test2", NULL, NULL, NULL, NULL, TRUE); + s_8021x = nm_connection_get_setting_802_1x(con); + + g_assert(nm_setting_802_1x_get_ca_cert_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_BLOB); + _assert_gbytes(nm_setting_802_1x_get_ca_cert_blob(s_8021x), "hallo", 5); + + g_assert(nm_setting_802_1x_get_client_cert_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_BLOB); + _assert_gbytes(nm_setting_802_1x_get_client_cert_blob(s_8021x), "hallo\0", 6); + + g_assert(nm_setting_802_1x_get_private_key_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_BLOB); + _assert_gbytes(nm_setting_802_1x_get_private_key_blob(s_8021x), "hallo\0", 6); + CLEAR(&con, &keyfile); +} + +static void +test_team_conf_read_valid(void) +{ + GKeyFile * keyfile = NULL; + gs_unref_object NMConnection *con = NULL; + NMSettingTeam * s_team; + + con = nmtst_create_connection_from_keyfile("[connection]\n" + "type=team\n" + "interface-name=nm-team1\n" + "[team]\n" + "config={\"foo\":\"bar\"}", + "/test_team_conf_read/valid"); + + g_assert(con); + s_team = nm_connection_get_setting_team(con); + g_assert(s_team); + g_assert_cmpstr(nm_setting_team_get_config(s_team), ==, "{\"foo\":\"bar\"}"); + + CLEAR(&con, &keyfile); +} + +static void +test_team_conf_read_invalid(void) +{ + GKeyFile * keyfile = NULL; + gs_unref_object NMConnection *con = NULL; + NMSettingTeam * s_team; + + if (!nm_json_vt()) { + g_test_skip("team test requires JSON validation"); + return; + } + + con = nmtst_create_connection_from_keyfile("[connection]\n" + "type=team\n" + "interface-name=nm-team1\n" + "[team]\n" + "config={foobar}", + "/test_team_conf_read/invalid"); + + g_assert(con); + s_team = nm_connection_get_setting_team(con); + g_assert(s_team); + g_assert(nm_setting_team_get_config(s_team) == NULL); + + CLEAR(&con, &keyfile); +} + +/*****************************************************************************/ + +static void +test_user_1(void) +{ + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + gs_unref_object NMConnection *con = NULL; + NMSettingUser * s_user; + + con = nmtst_create_connection_from_keyfile("[connection]\n" + "id=t\n" + "type=ethernet\n" + "\n" + "[user]\n" + "my-value.x=value1\n" + "", + "/test_user_1/invalid"); + g_assert(con); + s_user = NM_SETTING_USER(nm_connection_get_setting(con, NM_TYPE_SETTING_USER)); + g_assert(s_user); + g_assert_cmpstr(nm_setting_user_get_data(s_user, "my-value.x"), ==, "value1"); + + CLEAR(&con, &keyfile); + + con = nmtst_create_minimal_connection("user-2", + "8b85fb8d-3070-48ba-93d9-53eee231d9a2", + NM_SETTING_WIRED_SETTING_NAME, + NULL); + s_user = NM_SETTING_USER(nm_setting_user_new()); + +#define _USER_SET_DATA(s_user, key, val) \ + G_STMT_START \ + { \ + GError * _error = NULL; \ + gboolean _success; \ + \ + _success = nm_setting_user_set_data((s_user), (key), (val), &_error); \ + nmtst_assert_success(_success, _error); \ + } \ + G_STMT_END + +#define _USER_SET_DATA_X(s_user, key) _USER_SET_DATA(s_user, key, "val=" key "") + + _USER_SET_DATA(s_user, "my.val1", ""); + _USER_SET_DATA_X(s_user, "my.val2"); + _USER_SET_DATA_X(s_user, "my.v__al3"); + _USER_SET_DATA_X(s_user, "my._v"); + _USER_SET_DATA_X(s_user, "my.v+"); + _USER_SET_DATA_X(s_user, "my.Av"); + _USER_SET_DATA_X(s_user, "MY.AV"); + _USER_SET_DATA_X(s_user, "MY.8V"); + _USER_SET_DATA_X(s_user, "MY.8-V"); + _USER_SET_DATA_X(s_user, "MY.8_V"); + _USER_SET_DATA_X(s_user, "MY.8+V"); + _USER_SET_DATA_X(s_user, "MY.8/V"); + _USER_SET_DATA_X(s_user, "MY.8=V"); + _USER_SET_DATA_X(s_user, "MY.-"); + _USER_SET_DATA_X(s_user, "MY._"); + _USER_SET_DATA_X(s_user, "MY.+"); + _USER_SET_DATA_X(s_user, "MY./"); + _USER_SET_DATA_X(s_user, "MY.="); + _USER_SET_DATA_X(s_user, "my.keys.1"); + _USER_SET_DATA_X(s_user, "my.other.KEY.42"); + + nm_connection_add_setting(con, NM_SETTING(s_user)); + nmtst_connection_normalize(con); + + _keyfile_convert(&con, &keyfile, "/test_user_1/foo", NULL, NULL, NULL, NULL, FALSE); +} + +/*****************************************************************************/ + +static void +test_vpn_1(void) +{ + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + gs_unref_object NMConnection *con = NULL; + NMSettingVpn * s_vpn; + + con = nmtst_create_connection_from_keyfile("[connection]\n" + "id=t\n" + "type=vpn\n" + "\n" + "[vpn]\n" + "service-type=a.b.c\n" + "vpn-key-1=value1\n" + "", + "/test_vpn_1/invalid"); + g_assert(con); + s_vpn = NM_SETTING_VPN(nm_connection_get_setting(con, NM_TYPE_SETTING_VPN)); + g_assert(s_vpn); + g_assert_cmpstr(nm_setting_vpn_get_data_item(s_vpn, "vpn-key-1"), ==, "value1"); + + CLEAR(&con, &keyfile); +} + +/*****************************************************************************/ + +static void +test_bridge_vlans(void) +{ + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + gs_unref_object NMConnection *con = NULL; + NMSettingBridge * s_bridge; + NMBridgeVlan * vlan; + guint16 vid, vid_end; + + con = nmtst_create_connection_from_keyfile("[connection]\n" + "id=t\n" + "type=bridge\n" + "interface-name=br4\n" + "\n" + "[bridge]\n" + "vlans=900 , 1 pvid untagged, 100-123 untagged\n" + "", + "/test_bridge_port/vlans"); + s_bridge = NM_SETTING_BRIDGE(nm_connection_get_setting(con, NM_TYPE_SETTING_BRIDGE)); + g_assert(s_bridge); + g_assert_cmpuint(nm_setting_bridge_get_num_vlans(s_bridge), ==, 3); + + vlan = nm_setting_bridge_get_vlan(s_bridge, 0); + g_assert(vlan); + nm_bridge_vlan_get_vid_range(vlan, &vid, &vid_end); + g_assert_cmpuint(vid, ==, 1); + g_assert_cmpuint(vid_end, ==, 1); + g_assert_cmpint(nm_bridge_vlan_is_pvid(vlan), ==, TRUE); + g_assert_cmpint(nm_bridge_vlan_is_untagged(vlan), ==, TRUE); + + vlan = nm_setting_bridge_get_vlan(s_bridge, 1); + g_assert(vlan); + nm_bridge_vlan_get_vid_range(vlan, &vid, &vid_end); + g_assert_cmpuint(vid, ==, 100); + g_assert_cmpuint(vid_end, ==, 123); + g_assert_cmpint(nm_bridge_vlan_is_pvid(vlan), ==, FALSE); + g_assert_cmpint(nm_bridge_vlan_is_untagged(vlan), ==, TRUE); + + vlan = nm_setting_bridge_get_vlan(s_bridge, 2); + g_assert(vlan); + nm_bridge_vlan_get_vid_range(vlan, &vid, &vid_end); + g_assert_cmpuint(vid, ==, 900); + g_assert_cmpuint(vid_end, ==, 900); + g_assert_cmpint(nm_bridge_vlan_is_pvid(vlan), ==, FALSE); + g_assert_cmpint(nm_bridge_vlan_is_untagged(vlan), ==, FALSE); + + CLEAR(&con, &keyfile); +} + +static void +test_bridge_port_vlans(void) +{ + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + gs_unref_object NMConnection *con = NULL; + NMSettingBridgePort * s_port; + NMBridgeVlan * vlan; + guint16 vid_start, vid_end; + + con = nmtst_create_connection_from_keyfile("[connection]\n" + "id=t\n" + "type=dummy\n" + "interface-name=dummy1\n" + "master=br0\n" + "slave-type=bridge\n" + "\n" + "[bridge-port]\n" + "vlans=4094 pvid , 10-20 untagged\n" + "", + "/test_bridge_port/vlans"); + s_port = NM_SETTING_BRIDGE_PORT(nm_connection_get_setting(con, NM_TYPE_SETTING_BRIDGE_PORT)); + g_assert(s_port); + g_assert_cmpuint(nm_setting_bridge_port_get_num_vlans(s_port), ==, 2); + + vlan = nm_setting_bridge_port_get_vlan(s_port, 0); + g_assert(vlan); + nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end); + g_assert_cmpuint(vid_start, ==, 10); + g_assert_cmpuint(vid_end, ==, 20); + g_assert_cmpint(nm_bridge_vlan_is_pvid(vlan), ==, FALSE); + g_assert_cmpint(nm_bridge_vlan_is_untagged(vlan), ==, TRUE); + + vlan = nm_setting_bridge_port_get_vlan(s_port, 1); + g_assert(vlan); + nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end); + g_assert_cmpuint(vid_start, ==, 4094); + g_assert_cmpuint(vid_end, ==, 4094); + g_assert_cmpint(nm_bridge_vlan_is_pvid(vlan), ==, TRUE); + g_assert_cmpint(nm_bridge_vlan_is_untagged(vlan), ==, FALSE); + + CLEAR(&con, &keyfile); +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_func("/core/keyfile/encode_key", test_encode_key); + g_test_add_func("/core/keyfile/test_8021x_cert", test_8021x_cert); + g_test_add_func("/core/keyfile/test_8021x_cert_tpm2key", test_8021x_cert_tpm2key); + g_test_add_func("/core/keyfile/test_8021x_cert_read", test_8021x_cert_read); + g_test_add_func("/core/keyfile/test_team_conf_read/valid", test_team_conf_read_valid); + g_test_add_func("/core/keyfile/test_team_conf_read/invalid", test_team_conf_read_invalid); + g_test_add_func("/core/keyfile/test_user/1", test_user_1); + g_test_add_func("/core/keyfile/test_vpn/1", test_vpn_1); + g_test_add_func("/core/keyfile/bridge/vlans", test_bridge_vlans); + g_test_add_func("/core/keyfile/bridge-port/vlans", test_bridge_port_vlans); + + return g_test_run(); +} diff --git a/src/libnm-core-impl/tests/test-secrets.c b/src/libnm-core-impl/tests/test-secrets.c new file mode 100644 index 0000000..e371795 --- /dev/null +++ b/src/libnm-core-impl/tests/test-secrets.c @@ -0,0 +1,681 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-8021x.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-gsm.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ppp.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-vpn.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-wireless.h" +#include "nm-simple-connection.h" +#include "nm-utils.h" +#include "libnm-core-intern/nm-core-internal.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +#define TEST_CERT_DIR NM_BUILD_SRCDIR "/src/libnm-core-impl/tests/certs" +#define TEST_NEED_SECRETS_EAP_TLS_CA_CERT TEST_CERT_DIR "/test_ca_cert.pem" +#define TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT TEST_CERT_DIR "/test_key_and_cert.pem" +#define TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY TEST_CERT_DIR "/test_key_and_cert.pem" + +static void +_assert_hints_has(GPtrArray *hints, const char *item) +{ + guint i; + guint found = 0; + + g_assert(hints); + g_assert(item); + for (i = 0; i < hints->len; i++) { + g_assert(hints->pdata[i]); + if (strcmp(hints->pdata[i], item) == 0) + found++; + } + g_assert_cmpint(found, ==, 1); +} + +static NMConnection * +make_tls_connection(const char *detail, NMSetting8021xCKScheme scheme) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSetting8021x * s_8021x; + NMSettingWired * s_wired; + NMSettingIP4Config * s_ip4; + char * uuid; + gboolean success; + GError * error = NULL; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + uuid = nm_utils_uuid_generate(); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Need TLS Secrets", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free(uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + g_object_set(s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + + nm_setting_802_1x_add_eap_method(s_8021x, "tls"); + + success = nm_setting_802_1x_set_ca_cert(s_8021x, + TEST_NEED_SECRETS_EAP_TLS_CA_CERT, + scheme, + NULL, + &error); + nmtst_assert_success(success, error); + + success = nm_setting_802_1x_set_client_cert(s_8021x, + TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, + scheme, + NULL, + &error); + nmtst_assert_success(success, error); + + success = nm_setting_802_1x_set_private_key(s_8021x, + TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, + "test", + scheme, + NULL, + &error); + nmtst_assert_success(success, error); + + success = nm_setting_set_secret_flags(NM_SETTING(s_8021x), + NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + &error); + nmtst_assert_success(success, error); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + nmtst_assert_connection_verifies_and_normalizable(connection); + + return connection; +} + +static void +test_need_tls_secrets_path(void) +{ + NMConnection *connection; + const char * setting_name; + GPtrArray * hints = NULL; + + connection = make_tls_connection("need-tls-secrets-path-key", NM_SETTING_802_1X_CK_SCHEME_PATH); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets(connection, &hints); + g_assert(!setting_name); + g_assert(!hints); + + /* Connection is good; clear secrets and ensure private key password is then required */ + nm_connection_clear_secrets(connection); + + hints = NULL; + setting_name = nm_connection_need_secrets(connection, &hints); + g_assert_cmpstr(setting_name, ==, NM_SETTING_802_1X_SETTING_NAME); + _assert_hints_has(hints, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + + g_ptr_array_free(hints, TRUE); + g_object_unref(connection); +} + +static void +test_need_tls_secrets_blob(void) +{ + NMConnection *connection; + const char * setting_name; + GPtrArray * hints = NULL; + + connection = make_tls_connection("need-tls-secrets-blob-key", NM_SETTING_802_1X_CK_SCHEME_BLOB); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets(connection, &hints); + g_assert(!setting_name); + g_assert(!hints); + + /* Clear secrets and ensure password is again required */ + nm_connection_clear_secrets(connection); + + hints = NULL; + setting_name = nm_connection_need_secrets(connection, &hints); + g_assert_cmpstr(setting_name, ==, NM_SETTING_802_1X_SETTING_NAME); + _assert_hints_has(hints, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + + g_ptr_array_free(hints, TRUE); + g_object_unref(connection); +} + +static NMConnection * +make_tls_phase2_connection(const char *detail, NMSetting8021xCKScheme scheme) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSetting8021x * s_8021x; + NMSettingWired * s_wired; + NMSettingIP4Config * s_ip4; + char * uuid; + gboolean success; + GError * error = NULL; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + uuid = nm_utils_uuid_generate(); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Need TLS Secrets", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free(uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + g_object_set(s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "blahblah", NULL); + g_object_set(s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + + nm_setting_802_1x_add_eap_method(s_8021x, "ttls"); + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL); + + success = nm_setting_802_1x_set_phase2_ca_cert(s_8021x, + TEST_NEED_SECRETS_EAP_TLS_CA_CERT, + scheme, + NULL, + &error); + nmtst_assert_success(success, error); + + success = nm_setting_802_1x_set_phase2_client_cert(s_8021x, + TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, + scheme, + NULL, + &error); + nmtst_assert_success(success, error); + + success = nm_setting_802_1x_set_phase2_private_key(s_8021x, + TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, + "test", + scheme, + NULL, + &error); + nmtst_assert_success(success, error); + + success = nm_setting_set_secret_flags(NM_SETTING(s_8021x), + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + &error); + nmtst_assert_success(success, error); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + nmtst_assert_connection_verifies_and_normalizable(connection); + return connection; +} + +static void +test_need_tls_phase2_secrets_path(void) +{ + NMConnection *connection; + const char * setting_name; + GPtrArray * hints = NULL; + + connection = make_tls_phase2_connection("need-tls-phase2-secrets-path-key", + NM_SETTING_802_1X_CK_SCHEME_PATH); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets(connection, &hints); + g_assert(!setting_name); + g_assert(!hints); + + /* Connection is good; clear secrets and ensure private key password is then required */ + nm_connection_clear_secrets(connection); + + hints = NULL; + setting_name = nm_connection_need_secrets(connection, &hints); + g_assert_cmpstr(setting_name, ==, NM_SETTING_802_1X_SETTING_NAME); + _assert_hints_has(hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); + + g_ptr_array_free(hints, TRUE); + g_object_unref(connection); +} + +static void +test_need_tls_phase2_secrets_blob(void) +{ + NMConnection *connection; + const char * setting_name; + GPtrArray * hints = NULL; + + connection = make_tls_phase2_connection("need-tls-phase2-secrets-blob-key", + NM_SETTING_802_1X_CK_SCHEME_BLOB); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets(connection, &hints); + g_assert(!setting_name); + g_assert(!hints); + + /* Connection is good; clear secrets and ensure private key password is then required */ + nm_connection_clear_secrets(connection); + + hints = NULL; + setting_name = nm_connection_need_secrets(connection, &hints); + g_assert_cmpstr(setting_name, ==, NM_SETTING_802_1X_SETTING_NAME); + _assert_hints_has(hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); + + g_ptr_array_free(hints, TRUE); + g_object_unref(connection); +} + +static NMConnection * +wifi_connection_new(void) +{ + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity *s_wsec; + unsigned char tmpssid[] = {0x31, 0x33, 0x33, 0x37}; + char * uuid; + GBytes * ssid; + + connection = nm_simple_connection_new(); + g_assert(connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + g_assert(s_con); + + uuid = nm_utils_uuid_generate(); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Wireless", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free(uuid); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + /* Wireless setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + g_assert(s_wifi); + + ssid = g_bytes_new(tmpssid, sizeof(tmpssid)); + g_object_set(s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_bytes_unref(ssid); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + /* Wifi security */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); + g_assert(s_wsec); + + g_object_set(G_OBJECT(s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL); + nm_connection_add_setting(connection, NM_SETTING(s_wsec)); + + return connection; +} + +static GVariant * +build_wep_secrets(const char *wepkey) +{ + GVariantBuilder builder; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(&builder, + "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + g_variant_new_string(wepkey)); + g_variant_builder_add(&builder, + "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + g_variant_new_uint32(NM_WEP_KEY_TYPE_KEY)); + + return g_variant_builder_end(&builder); +} + +static void +test_update_secrets_wifi_single_setting(void) +{ + NMConnection * connection; + NMSettingWirelessSecurity *s_wsec; + GVariant * secrets; + GError * error = NULL; + gboolean success; + const char * wepkey = "11111111111111111111111111"; + const char * tmp; + + /* Test update with a hashed setting of 802-11-wireless secrets */ + + connection = wifi_connection_new(); + + secrets = build_wep_secrets(wepkey); + success = nm_connection_update_secrets(connection, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + secrets, + &error); + g_assert_no_error(error); + g_assert(success); + + g_variant_unref(secrets); + + /* Make sure the secret is now in the connection */ + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec); + tmp = nm_setting_wireless_security_get_wep_key(s_wsec, 0); + g_assert_cmpstr(tmp, ==, wepkey); + + g_object_unref(connection); +} + +static void +test_update_secrets_wifi_full_hash(void) +{ + NMConnection * connection; + NMSettingWirelessSecurity *s_wsec; + GVariantBuilder builder; + GVariant * all; + GError * error = NULL; + gboolean success; + const char * wepkey = "11111111111111111111111111"; + const char * tmp; + + /* Test update with a hashed connection containing only 802-11-wireless + * setting and secrets. + */ + + connection = wifi_connection_new(); + + g_variant_builder_init(&builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_add(&builder, + "{s@a{sv}}", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + build_wep_secrets(wepkey)); + all = g_variant_builder_end(&builder); + + success = nm_connection_update_secrets(connection, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + all, + &error); + g_assert_no_error(error); + g_assert(success); + + g_variant_unref(all); + + /* Make sure the secret is now in the connection */ + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec); + tmp = nm_setting_wireless_security_get_wep_key(s_wsec, 0); + g_assert_cmpstr(tmp, ==, wepkey); + + g_object_unref(connection); +} + +static void +test_update_secrets_wifi_bad_setting_name(void) +{ + NMConnection *connection; + GVariant * secrets; + GError * error = NULL; + gboolean success; + const char * wepkey = "11111111111111111111111111"; + + /* Test that passing an invalid setting name to + * nm_connection_update_secrets() fails with the correct error. + */ + + connection = wifi_connection_new(); + + secrets = build_wep_secrets(wepkey); + + success = nm_connection_update_secrets(connection, "asdfasdfasdfasf", secrets, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND); + g_assert(success == FALSE); + + g_clear_error(&error); + g_variant_unref(secrets); + g_object_unref(connection); +} + +static void +test_update_secrets_whole_connection(void) +{ + NMConnection * connection; + NMSettingWirelessSecurity *s_wsec; + GVariant * secrets; + GError * error = NULL; + gboolean success; + const char * wepkey = "11111111111111111111111111"; + + /* Test calling nm_connection_update_secrets() with an entire hashed + * connection including non-secrets. + */ + + connection = wifi_connection_new(); + + /* Build up the secrets dictionary */ + secrets = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); + NMTST_VARIANT_EDITOR(secrets, + NMTST_VARIANT_ADD_PROPERTY(NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "s", + wepkey);); + + success = nm_connection_update_secrets(connection, NULL, secrets, &error); + g_assert_no_error(error); + g_assert(success == TRUE); + + g_variant_unref(secrets); + + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec); + g_assert_cmpstr(nm_setting_wireless_security_get_wep_key(s_wsec, 0), ==, wepkey); + + g_object_unref(connection); +} + +static void +test_update_secrets_whole_connection_empty_hash(void) +{ + NMConnection *connection; + GVariant * secrets; + GError * error = NULL; + gboolean success; + + /* Test that updating secrets with an empty connection hash returns success */ + + connection = wifi_connection_new(); + secrets = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + success = nm_connection_update_secrets(connection, NULL, secrets, &error); + g_assert_no_error(error); + g_assert(success == TRUE); + g_variant_unref(secrets); + g_object_unref(connection); +} + +static void +test_update_secrets_whole_connection_bad_setting(void) +{ + NMConnection * connection; + NMSettingWirelessSecurity *s_wsec; + GVariant * secrets, *copy, *setting_hash; + const char * setting_name; + GVariantBuilder conn_builder; + GVariantIter conn_iter; + GError * error = NULL; + gboolean success; + const char * wepkey = "11111111111111111111111111"; + + /* Test that sending a hashed connection containing an invalid setting + * name fails with the right error. + */ + + connection = wifi_connection_new(); + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec != NULL); + g_object_set(G_OBJECT(s_wsec), NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, wepkey, NULL); + + /* Build up the secrets hash */ + secrets = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); + + /* Copy the dict, renaming the wireless-security setting in the process + * (so we ensure libnm is returning the right error when it finds an entry + * in the connection hash that doesn't match any setting in the connection). + */ + g_variant_builder_init(&conn_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_iter_init(&conn_iter, secrets); + while (g_variant_iter_next(&conn_iter, "{&s@a{sv}}", &setting_name, &setting_hash)) { + if (strcmp(setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0) + setting_name = "asdfasdfasdfasdf"; + + g_variant_builder_add(&conn_builder, "{s@a{sv}}", setting_name, setting_hash); + g_variant_unref(setting_hash); + } + copy = g_variant_builder_end(&conn_builder); + g_variant_unref(secrets); + + success = nm_connection_update_secrets(connection, NULL, copy, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND); + g_assert(success == FALSE); + + g_clear_error(&error); + g_variant_unref(copy); + g_object_unref(connection); +} + +static void +test_update_secrets_whole_connection_empty_base_setting(void) +{ + NMConnection *connection; + GVariant * secrets, *setting; + GError * error = NULL; + gboolean success; + + /* Test that a hashed connection which does not have any hashed secrets + * for the requested setting returns success. + */ + + connection = wifi_connection_new(); + secrets = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + g_assert_cmpint(g_variant_n_children(secrets), ==, 3); + + setting = g_variant_lookup_value(secrets, NM_SETTING_WIRELESS_SETTING_NAME, NULL); + g_assert(setting != NULL); + g_variant_unref(setting); + + success = nm_connection_update_secrets(connection, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + secrets, + &error); + g_assert_no_error(error); + g_assert(success); + + g_variant_unref(secrets); + g_object_unref(connection); +} + +static void +test_update_secrets_null_setting_name_with_setting_hash(void) +{ + NMConnection *connection; + GVariant * secrets; + GError * error = NULL; + gboolean success; + const char * wepkey = "11111111111111111111111111"; + + /* Ensure that a NULL setting name and only a hashed setting fails */ + + connection = wifi_connection_new(); + + secrets = build_wep_secrets(wepkey); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(setting_name || full_connection)); + success = nm_connection_update_secrets(connection, NULL, secrets, &error); + g_test_assert_expected_messages(); + g_assert_no_error(error); + g_assert(!success); + + g_variant_unref(secrets); + g_object_unref(connection); +} + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + /* The tests */ + g_test_add_func("/libnm/need_tls_secrets_path", test_need_tls_secrets_path); + g_test_add_func("/libnm/need_tls_secrets_blob", test_need_tls_secrets_blob); + g_test_add_func("/libnm/need_tls_phase2_secrets_path", test_need_tls_phase2_secrets_path); + g_test_add_func("/libnm/need_tls_phase2_secrets_blob", test_need_tls_phase2_secrets_blob); + + g_test_add_func("/libnm/update_secrets_wifi_single_setting", + test_update_secrets_wifi_single_setting); + g_test_add_func("/libnm/update_secrets_wifi_full_hash", test_update_secrets_wifi_full_hash); + g_test_add_func("/libnm/update_secrets_wifi_bad_setting_name", + test_update_secrets_wifi_bad_setting_name); + + g_test_add_func("/libnm/update_secrets_whole_connection", test_update_secrets_whole_connection); + g_test_add_func("/libnm/update_secrets_whole_connection_empty_hash", + test_update_secrets_whole_connection_empty_hash); + g_test_add_func("/libnm/update_secrets_whole_connection_bad_setting", + test_update_secrets_whole_connection_bad_setting); + g_test_add_func("/libnm/update_secrets_whole_connection_empty_base_setting", + test_update_secrets_whole_connection_empty_base_setting); + g_test_add_func("/libnm/update_secrets_null_setting_name_with_setting_hash", + test_update_secrets_null_setting_name_with_setting_hash); + + return g_test_run(); +} diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c new file mode 100644 index 0000000..0f80826 --- /dev/null +++ b/src/libnm-core-impl/tests/test-setting.c @@ -0,0 +1,4359 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2008 - 2017 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include +#include + +#include "libnm-glib-aux/nm-json-aux.h" +#include "libnm-base/nm-ethtool-utils-base.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-setting-8021x.h" +#include "nm-setting-bond.h" +#include "nm-setting-dcb.h" +#include "nm-setting-ethtool.h" +#include "nm-setting-team.h" +#include "nm-setting-team-port.h" +#include "nm-setting-tc-config.h" +#include "nm-setting-dummy.h" +#include "nm-connection.h" +#include "nm-simple-connection.h" +#include "nm-setting-connection.h" +#include "nm-errors.h" +#include "libnm-core-intern/nm-keyfile-internal.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +#define TEST_CERT_DIR NM_BUILD_SRCDIR "/src/libnm-core-impl/tests/certs" + +/*****************************************************************************/ + +/* converts @dict to a connection. In this case, @dict must be good, without warnings, so that + * NM_SETTING_PARSE_FLAGS_STRICT and NM_SETTING_PARSE_FLAGS_BEST_EFFORT yield the exact same results. */ +static NMConnection * +_connection_new_from_dbus_strict(GVariant *dict, gboolean normalize) +{ + gs_unref_object NMConnection *con_x_0 = NULL; + gs_unref_object NMConnection *con_x_s = NULL; + gs_unref_object NMConnection *con_x_e = NULL; + gs_unref_object NMConnection *con_n_0 = NULL; + gs_unref_object NMConnection *con_n_s = NULL; + gs_unref_object NMConnection *con_n_e = NULL; + gs_free_error GError *error = NULL; + guint i; + + g_assert(g_variant_is_of_type(dict, NM_VARIANT_TYPE_CONNECTION)); + + con_x_0 = _nm_simple_connection_new_from_dbus(dict, NM_SETTING_PARSE_FLAGS_NONE, &error); + nmtst_assert_success(NM_IS_CONNECTION(con_x_0), error); + + con_x_s = _nm_simple_connection_new_from_dbus(dict, NM_SETTING_PARSE_FLAGS_STRICT, &error); + nmtst_assert_success(NM_IS_CONNECTION(con_x_s), error); + + con_x_e = _nm_simple_connection_new_from_dbus(dict, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); + nmtst_assert_success(NM_IS_CONNECTION(con_x_e), error); + + con_n_0 = _nm_simple_connection_new_from_dbus(dict, NM_SETTING_PARSE_FLAGS_NORMALIZE, &error); + nmtst_assert_success(NM_IS_CONNECTION(con_n_0), error); + + con_n_s = _nm_simple_connection_new_from_dbus(dict, + NM_SETTING_PARSE_FLAGS_STRICT + | NM_SETTING_PARSE_FLAGS_NORMALIZE, + &error); + nmtst_assert_success(NM_IS_CONNECTION(con_n_s), error); + + con_n_e = _nm_simple_connection_new_from_dbus(dict, + NM_SETTING_PARSE_FLAGS_BEST_EFFORT + | NM_SETTING_PARSE_FLAGS_NORMALIZE, + &error); + nmtst_assert_success(NM_IS_CONNECTION(con_n_e), error); + + nmtst_assert_connection_verifies(con_x_0); + nmtst_assert_connection_verifies(con_x_e); + nmtst_assert_connection_verifies(con_x_s); + + nmtst_assert_connection_verifies_without_normalization(con_n_0); + nmtst_assert_connection_verifies_without_normalization(con_n_e); + nmtst_assert_connection_verifies_without_normalization(con_n_s); + + /* randomly compare some pairs that we created. They must all be equal, + * after accounting for normalization. */ + for (i = 0; i < 10; i++) { + NMConnection *cons[] = {con_x_0, con_x_s, con_x_e, con_n_0, con_n_s, con_n_e}; + guint idx_a = (nmtst_get_rand_uint32() % G_N_ELEMENTS(cons)); + guint idx_b = (nmtst_get_rand_uint32() % G_N_ELEMENTS(cons)); + gboolean normalize_a, normalize_b; + + if (idx_a <= 2 && idx_b <= 2) { + normalize_a = nmtst_get_rand_bool(); + normalize_b = normalize_a; + } else if (idx_a > 2 && idx_b > 2) { + normalize_a = nmtst_get_rand_bool(); + normalize_b = nmtst_get_rand_bool(); + } else { + normalize_a = (idx_a <= 2) ? TRUE : nmtst_get_rand_bool(); + normalize_b = (idx_b <= 2) ? TRUE : nmtst_get_rand_bool(); + } + nmtst_assert_connection_equals(cons[idx_a], normalize_a, cons[idx_b], normalize_b); + } + + return (normalize) ? g_steal_pointer(&con_x_0) : g_steal_pointer(&con_n_0); +} + +/*****************************************************************************/ + +static char * +_create_random_ipaddr(int addr_family, gboolean as_service) +{ + char delimiter = as_service ? ':' : '/'; + int num; + + if (addr_family == AF_UNSPEC) + addr_family = nmtst_rand_select(AF_INET, AF_INET6); + + g_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + + if (as_service) + num = (nmtst_get_rand_uint32() % 1000) + 30000; + else + num = addr_family == AF_INET ? 32 : 128; + + if (addr_family == AF_INET) + return g_strdup_printf("192.168.%u.%u%c%d", + nmtst_get_rand_uint32() % 256, + nmtst_get_rand_uint32() % 256, + delimiter, + num); + else + return g_strdup_printf("a:b:c::%02x:%02x%c%d", + nmtst_get_rand_uint32() % 256, + nmtst_get_rand_uint32() % 256, + delimiter, + num); +} + +/*****************************************************************************/ + +static void +compare_blob_data(const char *test, const char *key_path, GBytes *key) +{ + gs_free char *contents = NULL; + gsize len = 0; + GError * error = NULL; + gboolean success; + + g_assert(key && g_bytes_get_size(key) > 0); + + success = g_file_get_contents(key_path, &contents, &len, &error); + nmtst_assert_success(success, error); + + g_assert_cmpmem(contents, len, g_bytes_get_data(key, NULL), g_bytes_get_size(key)); +} + +static void +check_scheme_path(GBytes *value, const char *path) +{ + const guint8 *p; + gsize l; + + g_assert(value); + + p = g_bytes_get_data(value, &l); + g_assert_cmpint(l, ==, strlen(path) + NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH) + 1); + g_assert(memcmp(p, + NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH, + strlen(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)) + == 0); + p += strlen(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); + g_assert(memcmp(p, path, strlen(path)) == 0); + p += strlen(path); + g_assert(*p == '\0'); +} + +static void +test_private_key_import(const char *path, const char *password, NMSetting8021xCKScheme scheme) +{ + NMSetting8021x * s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + NMSetting8021xCKFormat tmp_fmt; + GError * error = NULL; + GBytes * tmp_key = NULL, *client_cert = NULL; + const char * pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + g_assert(s_8021x); + + success = nm_setting_802_1x_set_private_key(s_8021x, path, password, scheme, &format, &error); + nmtst_assert_success(success, error); + g_assert(format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + tmp_fmt = nm_setting_802_1x_get_private_key_format(s_8021x); + g_assert(tmp_fmt == format); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_private_key_password(s_8021x); + g_assert(pw != NULL); + g_assert_cmpstr(pw, ==, password); + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + tmp_key = nm_setting_802_1x_get_private_key_blob(s_8021x); + compare_blob_data("private-key-import", path, tmp_key); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + g_object_get(s_8021x, NM_SETTING_802_1X_PRIVATE_KEY, &tmp_key, NULL); + check_scheme_path(tmp_key, path); + g_bytes_unref(tmp_key); + } else + g_assert_not_reached(); + + /* If it's PKCS#12 ensure the client cert is the same value */ + if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + g_object_get(s_8021x, NM_SETTING_802_1X_PRIVATE_KEY, &tmp_key, NULL); + g_assert(tmp_key); + + g_object_get(s_8021x, NM_SETTING_802_1X_CLIENT_CERT, &client_cert, NULL); + g_assert(client_cert); + + /* make sure they are the same */ + g_assert(g_bytes_equal(tmp_key, client_cert)); + + g_bytes_unref(tmp_key); + g_bytes_unref(client_cert); + } + + g_object_unref(s_8021x); +} + +static void +test_phase2_private_key_import(const char * path, + const char * password, + NMSetting8021xCKScheme scheme) +{ + NMSetting8021x * s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + NMSetting8021xCKFormat tmp_fmt; + GError * error = NULL; + GBytes * tmp_key = NULL, *client_cert = NULL; + const char * pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + g_assert(s_8021x); + + success = + nm_setting_802_1x_set_phase2_private_key(s_8021x, path, password, scheme, &format, &error); + nmtst_assert_success(success, error); + g_assert(format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + tmp_fmt = nm_setting_802_1x_get_phase2_private_key_format(s_8021x); + g_assert(tmp_fmt == format); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_phase2_private_key_password(s_8021x); + g_assert(pw); + g_assert_cmpstr(pw, ==, password); + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + tmp_key = nm_setting_802_1x_get_phase2_private_key_blob(s_8021x); + compare_blob_data("phase2-private-key-import", path, tmp_key); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + g_object_get(s_8021x, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, &tmp_key, NULL); + check_scheme_path(tmp_key, path); + g_bytes_unref(tmp_key); + } else + g_assert_not_reached(); + + /* If it's PKCS#12 ensure the client cert is the same value */ + if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + g_object_get(s_8021x, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, &tmp_key, NULL); + g_assert(tmp_key); + + g_object_get(s_8021x, NM_SETTING_802_1X_PHASE2_CLIENT_CERT, &client_cert, NULL); + g_assert(client_cert); + + /* make sure they are the same */ + g_assert(g_bytes_equal(tmp_key, client_cert)); + + g_bytes_unref(tmp_key); + g_bytes_unref(client_cert); + } + + g_object_unref(s_8021x); +} + +static void +test_wrong_password_keeps_data(const char *path, const char *password) +{ + NMSetting8021x * s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError * error = NULL; + const char * pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + g_assert(s_8021x); + + success = nm_setting_802_1x_set_private_key(s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + nmtst_assert_success(success, error); + g_assert(format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + + /* Now try to set it to something that's not a certificate */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_private_key(s_8021x, + "Makefile.am", + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + nmtst_assert_no_success(success, error); + g_assert(format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + g_clear_error(&error); + + /* Make sure the password hasn't changed */ + pw = nm_setting_802_1x_get_private_key_password(s_8021x); + g_assert(pw); + g_assert_cmpstr(pw, ==, password); + + g_object_unref(s_8021x); +} + +static void +test_clear_private_key(const char *path, const char *password) +{ + NMSetting8021x * s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError * error = NULL; + const char * pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + g_assert(s_8021x); + + success = nm_setting_802_1x_set_private_key(s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + nmtst_assert_success(success, error); + g_assert(format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_private_key_password(s_8021x); + g_assert(pw); + g_assert_cmpstr(pw, ==, password); + + /* Now clear it */ + success = nm_setting_802_1x_set_private_key(s_8021x, + NULL, + NULL, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + NULL, + &error); + nmtst_assert_success(success, error); + + /* Ensure the password is also now clear */ + g_assert(!nm_setting_802_1x_get_private_key_password(s_8021x)); + + g_object_unref(s_8021x); +} + +static void +test_wrong_phase2_password_keeps_data(const char *path, const char *password) +{ + NMSetting8021x * s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError * error = NULL; + const char * pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + g_assert(s_8021x); + + success = nm_setting_802_1x_set_phase2_private_key(s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + nmtst_assert_success(success, error); + g_assert(format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + + /* Now try to set it to something that's not a certificate */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_phase2_private_key(s_8021x, + "Makefile.am", + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + nmtst_assert_no_success(success, error); + g_assert(format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + g_clear_error(&error); + + /* Make sure the password hasn't changed */ + pw = nm_setting_802_1x_get_phase2_private_key_password(s_8021x); + g_assert(pw); + g_assert_cmpstr(pw, ==, password); + + g_object_unref(s_8021x); +} + +static void +test_clear_phase2_private_key(const char *path, const char *password) +{ + NMSetting8021x * s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError * error = NULL; + const char * pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + g_assert(s_8021x); + + success = nm_setting_802_1x_set_phase2_private_key(s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + nmtst_assert_success(success, error); + g_assert(format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_phase2_private_key_password(s_8021x); + g_assert(pw); + g_assert_cmpstr(pw, ==, password); + + /* Now clear it */ + success = nm_setting_802_1x_set_phase2_private_key(s_8021x, + NULL, + NULL, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + NULL, + &error); + nmtst_assert_success(success, error); + + /* Ensure the password is also now clear */ + g_assert(!nm_setting_802_1x_get_phase2_private_key_password(s_8021x)); + + g_object_unref(s_8021x); +} + +static void +test_8021x(gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit((const char *) test_data, ", ", -1); + g_assert_cmpint(g_strv_length(parts), ==, 2); + + path = g_build_filename(TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + /* Test phase1 and phase2 path scheme */ + test_private_key_import(path, password, NM_SETTING_802_1X_CK_SCHEME_PATH); + test_phase2_private_key_import(path, password, NM_SETTING_802_1X_CK_SCHEME_PATH); + + /* Test phase1 and phase2 blob scheme */ + test_private_key_import(path, password, NM_SETTING_802_1X_CK_SCHEME_BLOB); + test_phase2_private_key_import(path, password, NM_SETTING_802_1X_CK_SCHEME_BLOB); + + /* Test that using a wrong password does not change existing data */ + test_wrong_password_keeps_data(path, password); + test_wrong_phase2_password_keeps_data(path, password); + + /* Test clearing the private key */ + test_clear_private_key(path, password); + test_clear_phase2_private_key(path, password); + + g_free(path); + g_strfreev(parts); +} + +/*****************************************************************************/ + +static void +create_bond_connection(NMConnection **con, NMSettingBond **s_bond) +{ + NMSettingConnection *s_con; + + g_assert(con); + g_assert(s_bond); + + *con = nmtst_create_minimal_connection("bond", NULL, NM_SETTING_BOND_SETTING_NAME, &s_con); + + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "bond0", NULL); + + *s_bond = (NMSettingBond *) nm_setting_bond_new(); + g_assert(*s_bond); + + nm_connection_add_setting(*con, NM_SETTING(*s_bond)); +} + +#define test_verify_options(exp, ...) _test_verify_options(exp, NM_MAKE_STRV(__VA_ARGS__)) + +static void +_test_verify_options(gboolean expected_result, const char *const *options) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingBond * s_bond; + const char *const * option; + + g_assert(NM_PTRARRAY_LEN(options) % 2 == 0); + + create_bond_connection(&con, &s_bond); + + for (option = options; option[0]; option += 2) + g_assert(nm_setting_bond_add_option(s_bond, option[0], option[1])); + + if (expected_result) { + nmtst_assert_connection_verifies_and_normalizable(con); + } else { + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + } +} + +static void +test_bond_verify(void) +{ + test_verify_options(TRUE, "mode", "3", "arp_interval", "0"); + test_verify_options(FALSE, + /* arp_interval not supported in balance-alb mode */ + "mode", + "balance-alb", + "arp_interval", + "1", + "arp_ip_target", + "1.2.3.4"); + test_verify_options(FALSE, + /* arp_ip_target requires arp_interval */ + "mode", + "balance-rr", + "arp_ip_target", + "1.2.3.4"); + test_verify_options(TRUE, + "mode", + "balance-rr", + "arp_interval", + "1", + "arp_ip_target", + "1.2.3.4"); + test_verify_options(FALSE, + /* num_grat_arp, num_unsol_na cannot be different */ + "mode", + "balance-rr", + "num_grat_arp", + "3", + "num_unsol_na", + "4"); + test_verify_options(TRUE, "mode", "balance-rr", "num_grat_arp", "5", "num_unsol_na", "5"); + test_verify_options(TRUE, "mode", "active-backup", "primary", "eth0"); + test_verify_options(FALSE, + /* primary requires mode=active-backup */ + "mode", + "802.3ad", + "primary", + "eth0"); + test_verify_options(TRUE, "mode", "802.3ad", "lacp_rate", "fast"); + test_verify_options(FALSE, + /* lacp_rate=fast requires mode=802.3ad */ + "mode", + "balance-rr", + "lacp_rate", + "fast"); + test_verify_options(TRUE, "mode", "802.3ad", "ad_actor_system", "ae:00:11:33:44:55"); + test_verify_options(TRUE, "mode", "0", "miimon", "0", "updelay", "0", "downdelay", "0"); + test_verify_options(TRUE, "mode", "0", "downdelay", "0", "updelay", "0"); + test_verify_options(TRUE, + "mode", + "0", + "miimon", + "100", + "arp_ip_target", + "1.1.1.1", + "arp_interval", + "200"); + test_verify_options(TRUE, + "mode", + "0", + "downdelay", + "100", + "arp_ip_target", + "1.1.1.1", + "arp_interval", + "200"); +} + +static void +test_bond_compare_options(gboolean exp_res, const char **opts1, const char **opts2) +{ + gs_unref_object NMSettingBond *s_bond1 = NULL, *s_bond2 = NULL; + const char ** p; + + s_bond1 = (NMSettingBond *) nm_setting_bond_new(); + g_assert(s_bond1); + s_bond2 = (NMSettingBond *) nm_setting_bond_new(); + g_assert(s_bond2); + + for (p = opts1; p[0] && p[1]; p += 2) + g_assert(nm_setting_bond_add_option(s_bond1, p[0], p[1])); + + for (p = opts2; p[0] && p[1]; p += 2) + g_assert(nm_setting_bond_add_option(s_bond2, p[0], p[1])); + + g_assert_cmpint(nm_setting_compare((NMSetting *) s_bond1, + (NMSetting *) s_bond2, + NM_SETTING_COMPARE_FLAG_EXACT), + ==, + exp_res); +} + +static void +test_bond_compare(void) +{ + test_bond_compare_options(TRUE, + ((const char *[]){"mode", "balance-rr", "miimon", "1", NULL}), + ((const char *[]){"mode", "balance-rr", "miimon", "1", NULL})); + test_bond_compare_options(FALSE, + ((const char *[]){"mode", "balance-rr", "miimon", "1", NULL}), + ((const char *[]){"mode", "balance-rr", "miimon", "2", NULL})); + + test_bond_compare_options(FALSE, + ((const char *[]){"miimon", "1", NULL}), + ((const char *[]){"miimon", "1", "updelay", "0", NULL})); + + test_bond_compare_options(FALSE, + ((const char *[]){"num_grat_arp", "2", NULL}), + ((const char *[]){"num_grat_arp", "1", NULL})); + test_bond_compare_options(FALSE, + ((const char *[]){"num_grat_arp", "3", NULL}), + ((const char *[]){"num_unsol_na", "3", NULL})); + test_bond_compare_options(FALSE, + ((const char *[]){"num_grat_arp", "4", NULL}), + ((const char *[]){"num_unsol_na", "4", "num_grat_arp", "4", NULL})); + + test_bond_compare_options(FALSE, + ((const char *[]){"mode", "balance-rr", "miimon", "100", NULL}), + ((const char *[]){"mode", "balance-rr", NULL})); +} + +static void +test_bond_normalize_options(const char **opts1, const char **opts2) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingBond * s_bond; + GError * error = NULL; + gboolean success; + const char ** p; + int num = 0; + + create_bond_connection(&con, &s_bond); + + for (p = opts1; p[0] && p[1]; p += 2) + g_assert(nm_setting_bond_add_option(s_bond, p[0], p[1])); + + nmtst_assert_connection_verifies_and_normalizable(con); + nmtst_connection_normalize(con); + success = nm_setting_verify((NMSetting *) s_bond, con, &error); + nmtst_assert_success(success, error); + + for (p = opts2; p[0] && p[1]; p += 2) { + g_assert_cmpstr(nm_setting_bond_get_option_by_name(s_bond, p[0]), ==, p[1]); + num++; + } + + g_assert_cmpint(num, ==, nm_setting_bond_get_num_options(s_bond)); +} + +static void +test_bond_normalize(void) +{ + test_bond_normalize_options( + ((const char *[]){"mode", "802.3ad", "ad_actor_system", "00:02:03:04:05:06", NULL}), + ((const char *[]){"mode", "802.3ad", "ad_actor_system", "00:02:03:04:05:06", NULL})); + test_bond_normalize_options(((const char *[]){"mode", "1", "miimon", "1", NULL}), + ((const char *[]){"mode", "active-backup", "miimon", "1", NULL})); + test_bond_normalize_options( + ((const char *[]){"mode", "balance-alb", "tlb_dynamic_lb", "1", NULL}), + ((const char *[]){"mode", "balance-alb", NULL})); + test_bond_normalize_options( + ((const char *[]){"mode", "balance-tlb", "tlb_dynamic_lb", "1", NULL}), + ((const char *[]){"mode", "balance-tlb", "tlb_dynamic_lb", "1", NULL})); + test_bond_normalize_options( + ((const char + *[]){"mode", "balance-rr", "ad_actor_sys_prio", "4", "packets_per_slave", "3", NULL}), + ((const char *[]){"mode", "balance-rr", "packets_per_slave", "3", NULL})); +} + +/*****************************************************************************/ + +#define DCB_FLAGS_ALL \ + (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE | NM_SETTING_DCB_FLAG_WILLING) + +static void +test_dcb_flags_valid(void) +{ + gs_unref_object NMSettingDcb *s_dcb = NULL; + GError * error = NULL; + gboolean success; + guint i; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new(); + g_assert(s_dcb); + + g_assert_cmpint(nm_setting_dcb_get_app_fcoe_flags(s_dcb), ==, 0); + g_assert_cmpint(nm_setting_dcb_get_app_iscsi_flags(s_dcb), ==, 0); + g_assert_cmpint(nm_setting_dcb_get_app_fip_flags(s_dcb), ==, 0); + g_assert_cmpint(nm_setting_dcb_get_priority_flow_control_flags(s_dcb), ==, 0); + g_assert_cmpint(nm_setting_dcb_get_priority_group_flags(s_dcb), ==, 0); + + g_object_set(G_OBJECT(s_dcb), + NM_SETTING_DCB_APP_FCOE_FLAGS, + DCB_FLAGS_ALL, + NM_SETTING_DCB_APP_ISCSI_FLAGS, + DCB_FLAGS_ALL, + NM_SETTING_DCB_APP_FIP_FLAGS, + DCB_FLAGS_ALL, + NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, + DCB_FLAGS_ALL, + NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, + DCB_FLAGS_ALL, + NULL); + /* Priority Group Bandwidth must total 100% */ + for (i = 0; i < 7; i++) + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, i, 12); + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 7, 16); + + success = nm_setting_verify(NM_SETTING(s_dcb), NULL, &error); + g_assert_no_error(error); + g_assert(success); + + g_assert_cmpint(nm_setting_dcb_get_app_fcoe_flags(s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint(nm_setting_dcb_get_app_iscsi_flags(s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint(nm_setting_dcb_get_app_fip_flags(s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint(nm_setting_dcb_get_priority_flow_control_flags(s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint(nm_setting_dcb_get_priority_group_flags(s_dcb), ==, DCB_FLAGS_ALL); +} + +#define TEST_FLAG(p, f, v) \ + { \ + /* GObject property min/max should ensure the property does not get set to \ + * the invalid value, so we ensure the value we just tried to set is 0 and \ + * that verify is successful since the property never got set. \ + */ \ + g_object_set(G_OBJECT(s_dcb), p, v, NULL); \ + g_assert_cmpint(f(s_dcb), ==, 0); \ + success = nm_setting_verify(NM_SETTING(s_dcb), NULL, &error); \ + g_assert_no_error(error); \ + g_assert(success); \ + } + +static void +test_dcb_flags_invalid(void) +{ + gs_unref_object NMSettingDcb *s_dcb = NULL; + GError * error = NULL; + gboolean success; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new(); + g_assert(s_dcb); + + NMTST_EXPECT("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG(NM_SETTING_DCB_APP_FCOE_FLAGS, nm_setting_dcb_get_app_fcoe_flags, 0x332523); + g_test_assert_expected_messages(); + + NMTST_EXPECT("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG(NM_SETTING_DCB_APP_ISCSI_FLAGS, nm_setting_dcb_get_app_iscsi_flags, 0xFF); + g_test_assert_expected_messages(); + + NMTST_EXPECT("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG(NM_SETTING_DCB_APP_FIP_FLAGS, nm_setting_dcb_get_app_fip_flags, 0x1111); + g_test_assert_expected_messages(); + + NMTST_EXPECT("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG(NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, + nm_setting_dcb_get_priority_flow_control_flags, + G_MAXUINT32); + g_test_assert_expected_messages(); + + NMTST_EXPECT("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG( + NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, + nm_setting_dcb_get_priority_group_flags, + (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE | NM_SETTING_DCB_FLAG_WILLING) + + 1); + g_test_assert_expected_messages(); +} + +#define TEST_APP_PRIORITY(lcprop, ucprop, v) \ + { \ + g_object_set(G_OBJECT(s_dcb), \ + NM_SETTING_DCB_APP_##ucprop##_FLAGS, \ + NM_SETTING_DCB_FLAG_NONE, \ + NULL); \ + \ + g_object_set(G_OBJECT(s_dcb), NM_SETTING_DCB_APP_##ucprop##_PRIORITY, v, NULL); \ + g_assert_cmpint(nm_setting_dcb_get_app_##lcprop##_priority(s_dcb), ==, v); \ + \ + /* Assert that the setting is invalid while the app is disabled unless v is default */ \ + success = nm_setting_verify(NM_SETTING(s_dcb), NULL, &error); \ + if (v >= 0) { \ + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); \ + g_assert(success == FALSE); \ + } else { \ + g_assert_no_error(error); \ + g_assert(success); \ + } \ + g_clear_error(&error); \ + \ + /* Set the enable flag and re-verify, this time it should be valid */ \ + g_object_set(G_OBJECT(s_dcb), \ + NM_SETTING_DCB_APP_##ucprop##_FLAGS, \ + NM_SETTING_DCB_FLAG_ENABLE, \ + NULL); \ + success = nm_setting_verify(NM_SETTING(s_dcb), NULL, &error); \ + g_assert_no_error(error); \ + g_assert(success); \ + \ + g_object_set(G_OBJECT(s_dcb), NM_SETTING_DCB_APP_##ucprop##_PRIORITY, 0, NULL); \ + } + +static void +test_dcb_app_priorities(void) +{ + gs_unref_object NMSettingDcb *s_dcb = NULL; + GError * error = NULL; + gboolean success; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new(); + g_assert(s_dcb); + + /* Defaults */ + g_assert_cmpint(nm_setting_dcb_get_app_fcoe_priority(s_dcb), ==, -1); + g_assert_cmpint(nm_setting_dcb_get_app_iscsi_priority(s_dcb), ==, -1); + g_assert_cmpint(nm_setting_dcb_get_app_fip_priority(s_dcb), ==, -1); + + TEST_APP_PRIORITY(fcoe, FCOE, 6); + TEST_APP_PRIORITY(iscsi, ISCSI, 5); + TEST_APP_PRIORITY(fip, FIP, 4); + + TEST_APP_PRIORITY(fcoe, FCOE, -1); + TEST_APP_PRIORITY(iscsi, ISCSI, -1); + TEST_APP_PRIORITY(fip, FIP, -1); +} + +#define TEST_PRIORITY_VALID(fn, id, val, flagsprop, verify) \ + { \ + /* Assert that setting the value gets the same value back out */ \ + nm_setting_dcb_set_priority_##fn(s_dcb, id, val); \ + g_assert_cmpint(nm_setting_dcb_get_priority_##fn(s_dcb, id), ==, val); \ + \ + if (verify) { \ + if (val != 0) { \ + /* Assert that verify fails because the flags do not include 'enabled' \ + * and a value has been set. \ + */ \ + success = nm_setting_verify(NM_SETTING(s_dcb), NULL, &error); \ + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); \ + g_assert(success == FALSE); \ + g_clear_error(&error); \ + } \ + \ + /* Assert that adding the 'enabled' flag verifies the setting */ \ + g_object_set(G_OBJECT(s_dcb), \ + NM_SETTING_DCB_PRIORITY_##flagsprop##_FLAGS, \ + NM_SETTING_DCB_FLAG_ENABLE, \ + NULL); \ + success = nm_setting_verify(NM_SETTING(s_dcb), NULL, &error); \ + g_assert_no_error(error); \ + g_assert(success); \ + } \ + \ + /* Reset everything */ \ + g_object_set(G_OBJECT(s_dcb), \ + NM_SETTING_DCB_PRIORITY_##flagsprop##_FLAGS, \ + NM_SETTING_DCB_FLAG_NONE, \ + NULL); \ + nm_setting_dcb_set_priority_##fn(s_dcb, id, 0); \ + } + +/* If Priority Groups are enabled, PG bandwidth must equal 100% */ +#define SET_VALID_PRIORITY_GROUP_BANDWIDTH \ + { \ + guint x; \ + for (x = 0; x < 7; x++) \ + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, x, 12); \ + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 7, 16); \ + } + +static void +test_dcb_priorities_valid(void) +{ + gs_unref_object NMSettingDcb *s_dcb = NULL; + GError * error = NULL; + gboolean success; + guint i; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new(); + g_assert(s_dcb); + + for (i = 0; i < 8; i++) + TEST_PRIORITY_VALID(flow_control, i, TRUE, FLOW_CONTROL, TRUE); + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) { + TEST_PRIORITY_VALID(group_id, i, i, GROUP, TRUE); + TEST_PRIORITY_VALID(group_id, i, 7 - i, GROUP, TRUE); + } + + /* Clear PG bandwidth from earlier tests */ + for (i = 0; i < 8; i++) + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, i, 0); + + /* Priority Group Bandwidth must add up to 100% if enabled, which requires + * some dancing for verifying individual values here. + */ + for (i = 0; i < 8; i++) { + guint other = 7 - (i % 8); + + /* Set another priority group to the remaining bandwidth */ + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, other, 100 - i); + TEST_PRIORITY_VALID(group_bandwidth, i, i, GROUP, TRUE); + + /* Set another priority group to the remaining bandwidth */ + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, other, 100 - (7 - i)); + TEST_PRIORITY_VALID(group_bandwidth, i, 7 - i, GROUP, TRUE); + + /* Clear remaining bandwidth */ + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, other, 0); + } + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) { + TEST_PRIORITY_VALID(bandwidth, i, i, GROUP, TRUE); + TEST_PRIORITY_VALID(bandwidth, i, 7 - i, GROUP, TRUE); + } + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) + TEST_PRIORITY_VALID(strict_bandwidth, i, TRUE, GROUP, TRUE); + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) { + TEST_PRIORITY_VALID(traffic_class, i, i, GROUP, TRUE); + TEST_PRIORITY_VALID(traffic_class, i, 7 - i, GROUP, TRUE); + } +} + +static void +test_dcb_bandwidth_sums(void) +{ + gs_unref_object NMSettingDcb *s_dcb = NULL; + GError * error = NULL; + gboolean success; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new(); + g_assert(s_dcb); + + /* Assert that setting the value gets the same value back out */ + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 0, 9); + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 1, 10); + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 2, 11); + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 3, 12); + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 4, 13); + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 5, 14); + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 6, 15); + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 7, 16); + + /* Assert verify success when sums total 100% */ + g_object_set(G_OBJECT(s_dcb), + NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, + NM_SETTING_DCB_FLAG_ENABLE, + NULL); + success = nm_setting_verify(NM_SETTING(s_dcb), NULL, &error); + g_assert_no_error(error); + g_assert(success); + + /* Assert verify fails when sums do not total 100% */ + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, 4, 20); + success = nm_setting_verify(NM_SETTING(s_dcb), NULL, &error); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(success == FALSE); + g_clear_error(&error); +} + +/*****************************************************************************/ + +static void +test_nm_json(void) +{ + g_assert(NM_IN_SET(WITH_JANSSON, 0, 1)); + +#if WITH_JANSSON + g_assert(nm_json_vt()); +#else + g_assert(!nm_json_vt()); +#endif + +#if WITH_JANSSON != defined(JANSSON_SONAME) + #error "WITH_JANSON and JANSSON_SONAME are defined inconsistently." +#endif +} + +/*****************************************************************************/ + +static void +_test_team_config_sync(const char *team_config, + int notify_peer_count, + int notify_peers_interval, + int mcast_rejoin_count, + int mcast_rejoin_interval, + char * runner, + char * runner_hwaddr_policy, /* activebackup */ + GPtrArray * runner_tx_hash, /* lacp, loadbalance */ + char * runner_tx_balancer, /* lacp, loadbalance */ + int runner_tx_balancer_interval, /* lacp, loadbalance */ + gboolean runner_active, /* lacp */ + gboolean runner_fast_rate, /* lacp */ + int runner_sys_prio, /* lacp */ + int runner_min_ports, /* lacp */ + char * runner_agg_select_policy, /* lacp */ + GPtrArray * link_watchers) +{ + gs_unref_object NMSettingTeam *s_team = NULL; + guint i, j; + gboolean found; + + if (!nm_json_vt()) { + g_test_skip("team test requires JSON validation"); + return; + } + + s_team = (NMSettingTeam *) nm_setting_team_new(); + g_assert(s_team); + + g_object_set(s_team, NM_SETTING_TEAM_CONFIG, team_config, NULL); + g_assert_cmpint(nm_setting_team_get_notify_peers_count(s_team), ==, notify_peer_count); + g_assert_cmpint(nm_setting_team_get_notify_peers_interval(s_team), ==, notify_peers_interval); + g_assert_cmpint(nm_setting_team_get_mcast_rejoin_count(s_team), ==, mcast_rejoin_count); + g_assert_cmpint(nm_setting_team_get_mcast_rejoin_interval(s_team), ==, mcast_rejoin_interval); + g_assert_cmpint(nm_setting_team_get_runner_tx_balancer_interval(s_team), + ==, + runner_tx_balancer_interval); + g_assert_cmpint(nm_setting_team_get_runner_active(s_team), ==, runner_active); + g_assert_cmpint(nm_setting_team_get_runner_fast_rate(s_team), ==, runner_fast_rate); + g_assert_cmpint(nm_setting_team_get_runner_sys_prio(s_team), ==, runner_sys_prio); + g_assert_cmpint(nm_setting_team_get_runner_min_ports(s_team), ==, runner_min_ports); + g_assert_cmpstr(nm_setting_team_get_runner(s_team), ==, runner); + g_assert_cmpstr(nm_setting_team_get_runner_hwaddr_policy(s_team), ==, runner_hwaddr_policy); + g_assert_cmpstr(nm_setting_team_get_runner_tx_balancer(s_team), ==, runner_tx_balancer); + g_assert_cmpstr(nm_setting_team_get_runner_agg_select_policy(s_team), + ==, + runner_agg_select_policy); + + if (runner_tx_hash) { + g_assert_cmpint(runner_tx_hash->len, ==, nm_setting_team_get_num_runner_tx_hash(s_team)); + for (i = 0; i < runner_tx_hash->len; i++) { + found = FALSE; + for (j = 0; j < nm_setting_team_get_num_runner_tx_hash(s_team); j++) { + if (nm_streq0(nm_setting_team_get_runner_tx_hash(s_team, j), + runner_tx_hash->pdata[i])) { + found = TRUE; + break; + } + } + g_assert(found); + } + } + + if (link_watchers) { + g_assert_cmpint(link_watchers->len, ==, nm_setting_team_get_num_link_watchers(s_team)); + for (i = 0; i < link_watchers->len; i++) { + found = FALSE; + for (j = 0; j < nm_setting_team_get_num_link_watchers(s_team); j++) { + if (nm_team_link_watcher_equal(link_watchers->pdata[i], + nm_setting_team_get_link_watcher(s_team, j))) { + found = TRUE; + break; + } + } + g_assert(found); + } + } + + g_assert(nm_setting_verify((NMSetting *) s_team, NULL, NULL)); +} + +static void +test_runner_roundrobin_sync_from_config(void) +{ + _test_team_config_sync("", + -1, + -1, + -1, + -1, + NULL, + NULL, + NULL, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + NULL); +} + +static void +test_runner_broadcast_sync_from_config(void) +{ + _test_team_config_sync("{\"runner\": {\"name\": \"broadcast\"}}", + -1, + -1, + -1, + -1, + NM_SETTING_TEAM_RUNNER_BROADCAST, + NULL, + NULL, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + NULL); +} + +static void +test_runner_random_sync_from_config(void) +{ + _test_team_config_sync("{\"runner\": {\"name\": \"random\"}}", + -1, + -1, + -1, + -1, + NM_SETTING_TEAM_RUNNER_RANDOM, + NULL, + NULL, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + NULL); +} + +static void +test_runner_activebackup_sync_from_config(void) +{ + _test_team_config_sync("{\"runner\": {\"name\": \"activebackup\"}}", + -1, + -1, + -1, + -1, + NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP, + NULL, + NULL, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + NULL); +} + +static void +test_runner_loadbalance_sync_from_config(void) +{ + gs_unref_ptrarray GPtrArray *tx_hash = NULL; + + tx_hash = g_ptr_array_new_with_free_func(g_free); + g_ptr_array_add(tx_hash, g_strdup("eth")); + g_ptr_array_add(tx_hash, g_strdup("ipv4")); + g_ptr_array_add(tx_hash, g_strdup("ipv6")); + + _test_team_config_sync("{\"runner\": {\"name\": \"loadbalance\"}}", + -1, + -1, + -1, + -1, + NM_SETTING_TEAM_RUNNER_LOADBALANCE, + NULL, + NULL, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + NULL); + + _test_team_config_sync("{\"runner\": {\"name\": \"loadbalance\", " + "\"tx_hash\": [\"eth\", \"ipv4\", \"ipv6\"]}}", + -1, + -1, + -1, + -1, + NM_SETTING_TEAM_RUNNER_LOADBALANCE, + NULL, + tx_hash, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + NULL); + + _test_team_config_sync( + "{\"runner\": {\"name\": \"loadbalance\", \"tx_hash\": [\"eth\", \"ipv4\", \"ipv6\"], " + "\"tx_balancer\": {\"name\": \"basic\", \"balancing_interval\": 30}}}", + -1, + -1, + -1, + -1, + NM_SETTING_TEAM_RUNNER_LOADBALANCE, + NULL, + tx_hash, + "basic", + 30, + TRUE, + FALSE, + -1, + -1, + NULL, + NULL); +} + +static void +test_runner_lacp_sync_from_config(void) +{ + gs_unref_ptrarray GPtrArray *tx_hash = NULL; + + tx_hash = g_ptr_array_new_with_free_func(g_free); + g_ptr_array_add(tx_hash, g_strdup("eth")); + g_ptr_array_add(tx_hash, g_strdup("ipv4")); + g_ptr_array_add(tx_hash, g_strdup("ipv6")); + + _test_team_config_sync( + "{\"runner\": {\"name\": \"lacp\", \"tx_hash\": [\"eth\", \"ipv4\", \"ipv6\"]}}", + -1, + -1, + -1, + -1, + NM_SETTING_TEAM_RUNNER_LACP, + NULL, + tx_hash, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + NULL); + + _test_team_config_sync( + "{\"runner\": {\"name\": \"lacp\", \"tx_hash\": [\"eth\", \"ipv4\", \"ipv6\"], " + "\"active\": false, \"fast_rate\": true, \"sys_prio\": 10, \"min_ports\": 5, " + "\"agg_select_policy\": \"port_config\"}}", + -1, + -1, + -1, + -1, + NM_SETTING_TEAM_RUNNER_LACP, + NULL, + tx_hash, + NULL, + -1, + FALSE, + TRUE, + 10, + 5, + "port_config", + NULL); +} + +static void +test_watcher_ethtool_sync_from_config(void) +{ + gs_unref_ptrarray GPtrArray *link_watchers = NULL; + + link_watchers = g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref); + g_ptr_array_add(link_watchers, nm_team_link_watcher_new_ethtool(0, 0, NULL)); + _test_team_config_sync("{\"link_watch\": {\"name\": \"ethtool\"}}", + -1, + -1, + -1, + -1, + NULL, + NULL, + NULL, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + link_watchers); +} + +static void +test_watcher_nsna_ping_sync_from_config(void) +{ + gs_unref_ptrarray GPtrArray *link_watchers = NULL; + + link_watchers = g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref); + g_ptr_array_add(link_watchers, + nm_team_link_watcher_new_nsna_ping(0, 0, 3, "target.host", NULL)); + _test_team_config_sync( + "{\"link_watch\": {\"name\": \"nsna_ping\", \"target_host\": \"target.host\"}}", + -1, + -1, + -1, + -1, + NULL, + NULL, + NULL, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + link_watchers); +} + +static void +test_watcher_arp_ping_sync_from_config(void) +{ + gs_unref_ptrarray GPtrArray *link_watchers = NULL; + + link_watchers = g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref); + g_ptr_array_add( + link_watchers, + nm_team_link_watcher_new_arp_ping(0, 0, 3, "target.host", "source.host", 0, NULL)); + _test_team_config_sync( + "{\"link_watch\": {\"name\": \"arp_ping\", \"target_host\": \"target.host\", " + "\"source_host\": \"source.host\"}}", + -1, + -1, + -1, + -1, + NULL, + NULL, + NULL, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + link_watchers); +} + +static void +test_multiple_watchers_sync_from_config(void) +{ + gs_unref_ptrarray GPtrArray *link_watchers = NULL; + + link_watchers = g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref); + g_ptr_array_add(link_watchers, nm_team_link_watcher_new_ethtool(2, 4, NULL)); + g_ptr_array_add(link_watchers, + nm_team_link_watcher_new_nsna_ping(3, 6, 9, "target.host", NULL)); + g_ptr_array_add( + link_watchers, + nm_team_link_watcher_new_arp_ping(5, + 10, + 15, + "target.host", + "source.host", + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE + | NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE + | NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS, + NULL)); + _test_team_config_sync( + "{\"link_watch\": [" + "{\"name\": \"ethtool\", \"delay_up\": 2, \"delay_down\": 4}, " + "{\"name\": \"arp_ping\", \"init_wait\": 5, \"interval\": 10, \"missed_max\": 15, " + "\"target_host\": \"target.host\", \"source_host\": \"source.host\", " + "\"validate_active\": true, \"validate_inactive\": true, \"send_always\": true}, " + "{\"name\": \"nsna_ping\", \"init_wait\": 3, \"interval\": 6, \"missed_max\": 9, " + "\"target_host\": \"target.host\"}]}", + -1, + -1, + -1, + -1, + NULL, + NULL, + NULL, + NULL, + -1, + TRUE, + FALSE, + -1, + -1, + NULL, + link_watchers); +} + +/*****************************************************************************/ + +static void +_test_team_port_config_sync(const char *team_port_config, + int queue_id, + int prio, + gboolean sticky, + int lacp_prio, + int lacp_key, + GPtrArray * link_watchers) +{ + gs_unref_object NMSettingTeamPort *s_team_port = NULL; + guint i, j; + gboolean found; + + if (!nm_json_vt()) { + g_test_skip("team test requires JSON validation"); + return; + } + + s_team_port = (NMSettingTeamPort *) nm_setting_team_port_new(); + g_assert(s_team_port); + + g_object_set(s_team_port, NM_SETTING_TEAM_CONFIG, team_port_config, NULL); + g_assert(nm_setting_team_port_get_queue_id(s_team_port) == queue_id); + g_assert(nm_setting_team_port_get_prio(s_team_port) == prio); + g_assert(nm_setting_team_port_get_sticky(s_team_port) == sticky); + g_assert(nm_setting_team_port_get_lacp_prio(s_team_port) == lacp_prio); + g_assert(nm_setting_team_port_get_lacp_key(s_team_port) == lacp_key); + + if (link_watchers) { + g_assert(link_watchers->len == nm_setting_team_port_get_num_link_watchers(s_team_port)); + for (i = 0; i < link_watchers->len; i++) { + found = FALSE; + for (j = 0; j < nm_setting_team_port_get_num_link_watchers(s_team_port); j++) { + if (nm_team_link_watcher_equal( + link_watchers->pdata[i], + nm_setting_team_port_get_link_watcher(s_team_port, j))) { + found = TRUE; + break; + } + } + g_assert(found); + } + } + + g_assert(nm_setting_verify((NMSetting *) s_team_port, NULL, NULL)); +} + +static void +test_team_port_default(void) +{ + _test_team_port_config_sync("", -1, 0, FALSE, -1, -1, NULL); +} + +static void +test_team_port_queue_id(void) +{ + _test_team_port_config_sync("{\"queue_id\": 3}", 3, 0, FALSE, -1, -1, NULL); + _test_team_port_config_sync("{\"queue_id\": 0}", 0, 0, FALSE, -1, -1, NULL); +} + +static void +test_team_port_prio(void) +{ + _test_team_port_config_sync("{\"prio\": 6}", -1, 6, FALSE, -1, -1, NULL); + _test_team_port_config_sync("{\"prio\": 0}", -1, 0, FALSE, -1, -1, NULL); +} + +static void +test_team_port_sticky(void) +{ + _test_team_port_config_sync("{\"sticky\": true}", -1, 0, TRUE, -1, -1, NULL); + _test_team_port_config_sync("{\"sticky\": false}", -1, 0, FALSE, -1, -1, NULL); +} + +static void +test_team_port_lacp_prio(void) +{ + _test_team_port_config_sync("{\"lacp_prio\": 9}", -1, 0, FALSE, 9, -1, NULL); + _test_team_port_config_sync("{\"lacp_prio\": 0}", -1, 0, FALSE, 0, -1, NULL); +} + +static void +test_team_port_lacp_key(void) +{ + _test_team_port_config_sync("{\"lacp_key\": 12}", -1, 0, FALSE, -1, 12, NULL); + _test_team_port_config_sync("{\"lacp_key\": 0}", -1, 0, FALSE, -1, 0, NULL); +} + +static void +test_team_port_full_config(void) +{ + gs_unref_ptrarray GPtrArray *link_watchers = NULL; + + link_watchers = g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref); + g_ptr_array_add( + link_watchers, + nm_team_link_watcher_new_arp_ping(0, + 3, + 3, + "1.2.3.2", + "1.2.3.1", + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE, + NULL)); + g_ptr_array_add( + link_watchers, + nm_team_link_watcher_new_arp_ping(1, + 1, + 0, + "1.2.3.4", + "1.2.3.1", + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS, + NULL)); + + _test_team_port_config_sync( + "{\"queue_id\": 10, \"prio\": 20, \"sticky\": true, \"lacp_prio\": 30, " + "\"lacp_key\": 40, \"link_watch\": [" + "{\"name\": \"arp_ping\", \"interval\": 3, \"target_host\": \"1.2.3.2\", " + "\"source_host\": \"1.2.3.1\", \"validate_inactive\": true}, " + "{\"name\": \"arp_ping\", \"init_wait\": 1, \"interval\": 1, " + "\"target_host\": \"1.2.3.4\", \"source_host\": \"1.2.3.1\", " + "\"send_always\": true}]}", + 10, + 20, + true, + 30, + 40, + NULL); +} + +/*****************************************************************************/ + +static void +_check_team_setting(NMSetting *setting) +{ + gs_unref_object NMSetting *setting2 = NULL; + gs_unref_object NMSetting *setting_clone = NULL; + gboolean is_port = NM_IS_SETTING_TEAM_PORT(setting); + gs_unref_variant GVariant *variant2 = NULL; + gs_unref_variant GVariant *variant3 = NULL; + + g_assert(NM_IS_SETTING_TEAM(setting) || is_port); + + setting2 = g_object_new(G_OBJECT_TYPE(setting), + is_port ? NM_SETTING_TEAM_PORT_CONFIG : NM_SETTING_TEAM_CONFIG, + is_port ? nm_setting_team_port_get_config(NM_SETTING_TEAM_PORT(setting)) + : nm_setting_team_get_config(NM_SETTING_TEAM(setting)), + NULL); + + if (nm_json_vt()) + nmtst_assert_setting_is_equal(setting, setting2, NM_SETTING_COMPARE_FLAG_EXACT); + + g_clear_object(&setting2); + + nmtst_assert_setting_dbus_roundtrip(setting); + + /* OK, now parse the setting only from the D-Bus variant, but removing the JSON config. + * For that, we have to "drop" the JSON and we do that by resetting the property. + * This causes JSON to be regenerated and it's in a normalized form that will compare + * equal. */ + setting_clone = nm_setting_duplicate(setting); + setting = setting_clone; + if (is_port) { + g_object_set(setting, + NM_SETTING_TEAM_PORT_STICKY, + nm_setting_team_port_get_sticky(NM_SETTING_TEAM_PORT(setting)), + NULL); + } else { + g_object_set(setting, + NM_SETTING_TEAM_RUNNER_SYS_PRIO, + nm_setting_team_get_runner_sys_prio(NM_SETTING_TEAM(setting)), + NULL); + } + variant2 = _nm_setting_to_dbus(setting, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); + variant3 = nm_utils_gvariant_vardict_filter_drop_one(variant2, "config"); + setting2 = nmtst_assert_setting_dbus_new(G_OBJECT_TYPE(setting), variant3); + nmtst_assert_setting_is_equal(setting, setting2, NM_SETTING_COMPARE_FLAG_EXACT); +} + +static void +test_team_setting(void) +{ + gs_unref_variant GVariant *variant = nmtst_variant_from_string( + G_VARIANT_TYPE_VARDICT, + "{'config': <'{\"link_watch\": {\"name\": \"ethtool\"}}'>, 'interface-name': <'nm-team'>, " + "'link-watchers': <[{'name': <'ethtool'>}]>}"); + gs_free_error GError *error = NULL; + gs_unref_object NMSetting * setting = NULL; + nm_auto_unref_team_link_watcher NMTeamLinkWatcher *watcher1 = + nm_team_link_watcher_new_nsna_ping(1, 3, 4, "bbb", NULL); + nm_auto_unref_team_link_watcher NMTeamLinkWatcher *watcher2 = + nm_team_link_watcher_new_arp_ping2(1, 3, 4, -1, "ccc", "ddd", 0, NULL); + + g_assert(watcher1); + g_assert(watcher2); + + setting = _nm_setting_new_from_dbus(NM_TYPE_SETTING_TEAM, + variant, + NULL, + NM_SETTING_PARSE_FLAGS_STRICT, + &error); + nmtst_assert_success(setting, error); + _check_team_setting(setting); + + g_assert_cmpstr(nm_setting_team_get_config(NM_SETTING_TEAM(setting)), + ==, + "{\"link_watch\": {\"name\": \"ethtool\"}}"); + g_assert_cmpint(nm_setting_team_get_num_link_watchers(NM_SETTING_TEAM(setting)), ==, 1); + + g_object_set(setting, NM_SETTING_TEAM_RUNNER_SYS_PRIO, (int) 10, NULL); + + _check_team_setting(setting); + g_assert_cmpint(nm_setting_team_get_num_link_watchers(NM_SETTING_TEAM(setting)), ==, 1); + g_assert_cmpstr( + nm_setting_team_get_config(NM_SETTING_TEAM(setting)), + ==, + "{ \"runner\": { \"sys_prio\": 10 }, \"link_watch\": { \"name\": \"ethtool\" } }"); + + nm_setting_team_remove_link_watcher(NM_SETTING_TEAM(setting), 0); + + _check_team_setting(setting); + g_assert_cmpint(nm_setting_team_get_num_link_watchers(NM_SETTING_TEAM(setting)), ==, 0); + g_assert_cmpstr(nm_setting_team_get_config(NM_SETTING_TEAM(setting)), + ==, + "{ \"runner\": { \"sys_prio\": 10 } }"); + + nm_setting_team_add_link_watcher(NM_SETTING_TEAM(setting), watcher1); + _check_team_setting(setting); + g_assert_cmpstr( + nm_setting_team_get_config(NM_SETTING_TEAM(setting)), + ==, + "{ \"runner\": { \"sys_prio\": 10 }, \"link_watch\": { \"name\": \"nsna_ping\", " + "\"interval\": 3, \"init_wait\": 1, \"missed_max\": 4, \"target_host\": \"bbb\" } }"); + + nm_setting_team_add_link_watcher(NM_SETTING_TEAM(setting), watcher2); + _check_team_setting(setting); + g_assert_cmpstr( + nm_setting_team_get_config(NM_SETTING_TEAM(setting)), + ==, + "{ \"runner\": { \"sys_prio\": 10 }, \"link_watch\": [ { \"name\": \"nsna_ping\", " + "\"interval\": 3, \"init_wait\": 1, \"missed_max\": 4, \"target_host\": \"bbb\" }, { " + "\"name\": \"arp_ping\", \"interval\": 3, \"init_wait\": 1, \"missed_max\": 4, " + "\"source_host\": \"ddd\", \"target_host\": \"ccc\" } ] }"); + + nm_setting_team_remove_link_watcher(NM_SETTING_TEAM(setting), 0); + nm_setting_team_remove_link_watcher(NM_SETTING_TEAM(setting), 0); + g_object_set(setting, NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, (int) 5, NULL); + g_assert_cmpstr( + nm_setting_team_get_config(NM_SETTING_TEAM(setting)), + ==, + "{ \"runner\": { \"tx_balancer\": { \"balancing_interval\": 5 }, \"sys_prio\": 10 } }"); + + g_object_set(setting, NM_SETTING_TEAM_RUNNER, NULL, NULL); + _check_team_setting(setting); + g_assert_cmpstr( + nm_setting_team_get_config(NM_SETTING_TEAM(setting)), + ==, + "{ \"runner\": { \"tx_balancer\": { \"balancing_interval\": 5 }, \"sys_prio\": 10 } }"); + + g_object_set(setting, + NM_SETTING_TEAM_CONFIG, + "{ \"runner\": { \"tx_hash\": [ \"eth\", \"l3\" ] } }", + NULL); + _check_team_setting(setting); +} + +/*****************************************************************************/ + +static void +_setting_ethtool_set_feature(NMSettingEthtool *s_ethtool, const char *opt_name, NMTernary value) +{ + g_assert(NM_IS_SETTING_ETHTOOL(s_ethtool)); + + if (nmtst_get_rand_bool()) { + nm_setting_ethtool_set_feature(s_ethtool, opt_name, value); + return; + } + + if (value == NM_TERNARY_DEFAULT) { + nm_setting_option_set(NM_SETTING(s_ethtool), opt_name, NULL); + return; + } + + if (nmtst_get_rand_bool()) + nm_setting_option_set_boolean(NM_SETTING(s_ethtool), opt_name, value); + else + nm_setting_option_set(NM_SETTING(s_ethtool), opt_name, g_variant_new_boolean(value)); +} + +static NMTernary +_setting_ethtool_get_feature(NMSettingEthtool *s_ethtool, const char *opt_name) +{ + GVariant *v; + gboolean b; + + switch (nmtst_get_rand_uint32() % 3) { + case 0: + return nm_setting_ethtool_get_feature(s_ethtool, opt_name); + case 1: + if (!nm_setting_option_get_boolean(NM_SETTING(s_ethtool), opt_name, &b)) + return NM_TERNARY_DEFAULT; + return b; + default: + v = nm_setting_option_get(NM_SETTING(s_ethtool), opt_name); + if (!v || !g_variant_is_of_type(v, G_VARIANT_TYPE_BOOLEAN)) + return NM_TERNARY_DEFAULT; + return g_variant_get_boolean(v); + } +} + +static void +test_ethtool_features(void) +{ + gs_unref_object NMConnection *con = NULL; + gs_unref_object NMConnection *con2 = NULL; + gs_unref_object NMConnection *con3 = NULL; + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + NMSettingConnection * s_con; + NMSettingEthtool * s_ethtool; + NMSettingEthtool * s_ethtool2; + NMSettingEthtool * s_ethtool3; + + con = nmtst_create_minimal_connection("ethtool-1", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con); + s_ethtool = NM_SETTING_ETHTOOL(nm_setting_ethtool_new()); + nm_connection_add_setting(con, NM_SETTING(s_ethtool)); + + _setting_ethtool_set_feature(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RX, NM_TERNARY_TRUE); + _setting_ethtool_set_feature(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_LRO, NM_TERNARY_FALSE); + + g_assert_cmpint(_setting_ethtool_get_feature(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RX), + ==, + NM_TERNARY_TRUE); + g_assert_cmpint(_setting_ethtool_get_feature(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_LRO), + ==, + NM_TERNARY_FALSE); + g_assert_cmpint(_setting_ethtool_get_feature(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_SG), + ==, + NM_TERNARY_DEFAULT); + + nmtst_connection_normalize(con); + + variant = nm_connection_to_dbus(con, NM_CONNECTION_SERIALIZE_ALL); + + con2 = nm_simple_connection_new_from_dbus(variant, &error); + nmtst_assert_success(con2, error); + + s_ethtool2 = NM_SETTING_ETHTOOL(nm_connection_get_setting(con2, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_cmpint(_setting_ethtool_get_feature(s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_RX), + ==, + NM_TERNARY_TRUE); + g_assert_cmpint(_setting_ethtool_get_feature(s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_LRO), + ==, + NM_TERNARY_FALSE); + g_assert_cmpint(_setting_ethtool_get_feature(s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_SG), + ==, + NM_TERNARY_DEFAULT); + + nmtst_assert_connection_verifies_without_normalization(con2); + + nmtst_assert_connection_equals(con, FALSE, con2, FALSE); + + keyfile = nm_keyfile_write(con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + nmtst_assert_success(keyfile, error); + + con3 = nm_keyfile_read(keyfile, + "/ignored/current/working/directory/for/loading/relative/paths", + NM_KEYFILE_HANDLER_FLAGS_NONE, + NULL, + NULL, + &error); + nmtst_assert_success(con3, error); + + nm_keyfile_read_ensure_id(con3, "unused-because-already-has-id"); + nm_keyfile_read_ensure_uuid(con3, "unused-because-already-has-uuid"); + + nmtst_connection_normalize(con3); + + nmtst_assert_connection_equals(con, FALSE, con3, FALSE); + + s_ethtool3 = NM_SETTING_ETHTOOL(nm_connection_get_setting(con3, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_cmpint(_setting_ethtool_get_feature(s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_RX), + ==, + NM_TERNARY_TRUE); + g_assert_cmpint(_setting_ethtool_get_feature(s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_LRO), + ==, + NM_TERNARY_FALSE); + g_assert_cmpint(_setting_ethtool_get_feature(s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_SG), + ==, + NM_TERNARY_DEFAULT); +} + +static void +test_ethtool_coalesce(void) +{ + gs_unref_object NMConnection *con = NULL; + gs_unref_object NMConnection *con2 = NULL; + gs_unref_object NMConnection *con3 = NULL; + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + NMSettingConnection * s_con; + NMSettingEthtool * s_ethtool; + NMSettingEthtool * s_ethtool2; + NMSettingEthtool * s_ethtool3; + guint32 u32; + + con = nmtst_create_minimal_connection("ethtool-coalesce", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + s_ethtool = NM_SETTING_ETHTOOL(nm_setting_ethtool_new()); + nm_connection_add_setting(con, NM_SETTING(s_ethtool)); + + nm_setting_option_set_uint32(NM_SETTING(s_ethtool), NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, 4); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, + &u32)); + g_assert_cmpuint(u32, ==, 4); + + nmtst_connection_normalize(con); + + variant = nm_connection_to_dbus(con, NM_CONNECTION_SERIALIZE_ALL); + + con2 = nm_simple_connection_new_from_dbus(variant, &error); + nmtst_assert_success(con2, error); + + s_ethtool2 = NM_SETTING_ETHTOOL(nm_connection_get_setting(con2, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool2), + NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, + &u32)); + g_assert_cmpuint(u32, ==, 4); + + nmtst_assert_connection_verifies_without_normalization(con2); + + nmtst_assert_connection_equals(con, FALSE, con2, FALSE); + + keyfile = nm_keyfile_write(con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + nmtst_assert_success(keyfile, error); + + con3 = nm_keyfile_read(keyfile, + "/ignored/current/working/directory/for/loading/relative/paths", + NM_KEYFILE_HANDLER_FLAGS_NONE, + NULL, + NULL, + &error); + nmtst_assert_success(con3, error); + + nm_keyfile_read_ensure_id(con3, "unused-because-already-has-id"); + nm_keyfile_read_ensure_uuid(con3, "unused-because-already-has-uuid"); + + nmtst_connection_normalize(con3); + + nmtst_assert_connection_equals(con, FALSE, con3, FALSE); + + s_ethtool3 = NM_SETTING_ETHTOOL(nm_connection_get_setting(con3, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool3), + NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, + &u32)); + g_assert_cmpuint(u32, ==, 4); + + nm_setting_option_set(NM_SETTING(s_ethtool), NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, NULL); + g_assert_false(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, + NULL)); + + nm_setting_option_set_uint32(NM_SETTING(s_ethtool), NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES, 8); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES, + &u32)); + g_assert_cmpuint(u32, ==, 8); + + nm_setting_option_clear_by_name(NM_SETTING(s_ethtool), nm_ethtool_optname_is_coalesce); + g_assert_false(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_COALESCE_RX_FRAMES, + NULL)); + g_assert_false(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_COALESCE_TX_FRAMES, + NULL)); + g_assert_false(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS, + NULL)); +} + +static void +test_ethtool_ring(void) +{ + gs_unref_object NMConnection *con = NULL; + gs_unref_object NMConnection *con2 = NULL; + gs_unref_object NMConnection *con3 = NULL; + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + NMSettingConnection * s_con; + NMSettingEthtool * s_ethtool; + NMSettingEthtool * s_ethtool2; + NMSettingEthtool * s_ethtool3; + guint32 out_value; + + con = nmtst_create_minimal_connection("ethtool-ring", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + s_ethtool = NM_SETTING_ETHTOOL(nm_setting_ethtool_new()); + nm_connection_add_setting(con, NM_SETTING(s_ethtool)); + + nm_setting_option_set_uint32(NM_SETTING(s_ethtool), NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, 4); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, + &out_value)); + g_assert_cmpuint(out_value, ==, 4); + + nmtst_connection_normalize(con); + + variant = nm_connection_to_dbus(con, NM_CONNECTION_SERIALIZE_ALL); + + con2 = nm_simple_connection_new_from_dbus(variant, &error); + nmtst_assert_success(con2, error); + + s_ethtool2 = NM_SETTING_ETHTOOL(nm_connection_get_setting(con2, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool2), + NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, + &out_value)); + g_assert_cmpuint(out_value, ==, 4); + + nmtst_assert_connection_verifies_without_normalization(con2); + + nmtst_assert_connection_equals(con, FALSE, con2, FALSE); + + keyfile = nm_keyfile_write(con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + nmtst_assert_success(keyfile, error); + + con3 = nm_keyfile_read(keyfile, + "/ignored/current/working/directory/for/loading/relative/paths", + NM_KEYFILE_HANDLER_FLAGS_NONE, + NULL, + NULL, + &error); + nmtst_assert_success(con3, error); + + nm_keyfile_read_ensure_id(con3, "unused-because-already-has-id"); + nm_keyfile_read_ensure_uuid(con3, "unused-because-already-has-uuid"); + + nmtst_connection_normalize(con3); + + nmtst_assert_connection_equals(con, FALSE, con3, FALSE); + + s_ethtool3 = NM_SETTING_ETHTOOL(nm_connection_get_setting(con3, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool3), + NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, + &out_value)); + g_assert_cmpuint(out_value, ==, 4); + + nm_setting_option_set(NM_SETTING(s_ethtool), NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, NULL); + g_assert_false(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, + NULL)); + + nm_setting_option_set_uint32(NM_SETTING(s_ethtool), NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, 8); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, + &out_value)); + g_assert_cmpuint(out_value, ==, 8); + + nm_setting_option_clear_by_name(NM_SETTING(s_ethtool), nm_ethtool_optname_is_ring); + g_assert_false(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, + NULL)); + g_assert_false( + nm_setting_option_get_uint32(NM_SETTING(s_ethtool), NM_ETHTOOL_OPTNAME_RING_RX, NULL)); + g_assert_false( + nm_setting_option_get_uint32(NM_SETTING(s_ethtool), NM_ETHTOOL_OPTNAME_RING_TX, NULL)); +} + +/*****************************************************************************/ + +static void +test_sriov_vf(void) +{ + NMSriovVF *vf1, *vf2; + GError * error = NULL; + char * str; + + vf1 = nm_sriov_vf_new(1); + nm_sriov_vf_set_attribute(vf1, + NM_SRIOV_VF_ATTRIBUTE_MAC, + g_variant_new_string("00:11:22:33:44:55")); + nm_sriov_vf_set_attribute(vf1, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK, g_variant_new_boolean(TRUE)); + nm_sriov_vf_set_attribute(vf1, NM_SRIOV_VF_ATTRIBUTE_TRUST, g_variant_new_boolean(FALSE)); + nm_sriov_vf_set_attribute(vf1, NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE, g_variant_new_uint32(100)); + nm_sriov_vf_set_attribute(vf1, NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE, g_variant_new_uint32(500)); + + str = nm_utils_sriov_vf_to_str(vf1, FALSE, &error); + g_assert_no_error(error); + g_assert_cmpstr( + str, + ==, + "1 mac=00:11:22:33:44:55 max-tx-rate=500 min-tx-rate=100 spoof-check=true trust=false"); + g_free(str); + + vf2 = nm_utils_sriov_vf_from_str(" 1 mac=00:11:22:33:44:55 max-tx-rate=500 min-tx-rate=100", + &error); + nmtst_assert_success(vf2, error); + nm_sriov_vf_set_attribute(vf2, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK, g_variant_new_boolean(FALSE)); + nm_sriov_vf_set_attribute(vf2, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK, g_variant_new_boolean(TRUE)); + nm_sriov_vf_set_attribute(vf2, NM_SRIOV_VF_ATTRIBUTE_TRUST, g_variant_new_boolean(TRUE)); + nm_sriov_vf_set_attribute(vf2, NM_SRIOV_VF_ATTRIBUTE_TRUST, NULL); + nm_sriov_vf_set_attribute(vf2, NM_SRIOV_VF_ATTRIBUTE_TRUST, g_variant_new_boolean(FALSE)); + + g_assert(nm_sriov_vf_equal(vf1, vf2)); + + nm_sriov_vf_unref(vf1); + nm_sriov_vf_unref(vf2); +} + +static void +test_sriov_vf_dup(void) +{ + NMSriovVF *vf1, *vf2; + + vf1 = nm_sriov_vf_new(1); + nm_sriov_vf_set_attribute(vf1, NM_SRIOV_VF_ATTRIBUTE_MAC, g_variant_new_string("foobar")); + nm_sriov_vf_set_attribute(vf1, NM_SRIOV_VF_ATTRIBUTE_TRUST, g_variant_new_boolean(FALSE)); + nm_sriov_vf_set_attribute(vf1, NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE, g_variant_new_uint32(10)); + nm_sriov_vf_set_attribute(vf1, NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE, g_variant_new_uint32(1000)); + nm_sriov_vf_add_vlan(vf1, 80); + nm_sriov_vf_set_vlan_qos(vf1, 80, NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD); + + vf2 = nm_sriov_vf_dup(vf1); + g_assert(nm_sriov_vf_equal(vf1, vf2)); + + nm_sriov_vf_unref(vf1); + nm_sriov_vf_unref(vf2); +} + +static void +test_sriov_vf_vlan(void) +{ + NMSriovVF * vf; + const guint * vlan_ids; + guint num; + GError * error = NULL; + gs_free char *str = NULL; + + vf = nm_sriov_vf_new(19); + nm_sriov_vf_set_attribute(vf, NM_SRIOV_VF_ATTRIBUTE_MAC, g_variant_new_string("00:11:22")); + g_assert(nm_sriov_vf_add_vlan(vf, 80)); + g_assert(!nm_sriov_vf_add_vlan(vf, 80)); + g_assert(nm_sriov_vf_add_vlan(vf, 82)); + g_assert(nm_sriov_vf_add_vlan(vf, 83)); + g_assert(nm_sriov_vf_add_vlan(vf, 81)); + g_assert(!nm_sriov_vf_remove_vlan(vf, 100)); + g_assert(nm_sriov_vf_remove_vlan(vf, 82)); + nm_sriov_vf_set_vlan_qos(vf, 81, 0xabba); + nm_sriov_vf_set_vlan_protocol(vf, 81, NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD); + + vlan_ids = nm_sriov_vf_get_vlan_ids(vf, &num); + g_assert(vlan_ids); + g_assert_cmpint(num, ==, 3); + g_assert_cmpint(vlan_ids[0], ==, 80); + g_assert_cmpint(vlan_ids[1], ==, 81); + g_assert_cmpint(vlan_ids[2], ==, 83); + g_assert_cmpint(nm_sriov_vf_get_vlan_qos(vf, 80), ==, 0x0); + g_assert_cmpint(nm_sriov_vf_get_vlan_protocol(vf, 80), ==, NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); + g_assert_cmpint(nm_sriov_vf_get_vlan_qos(vf, 81), ==, 0xabba); + g_assert_cmpint(nm_sriov_vf_get_vlan_protocol(vf, 81), ==, NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD); + + nm_sriov_vf_unref(vf); + + vf = nm_utils_sriov_vf_from_str("20 spoof-check=false vlans=85.0.q;4000.0x20.ad;81.10;83", + &error); + nmtst_assert_success(vf, error); + vlan_ids = nm_sriov_vf_get_vlan_ids(vf, &num); + g_assert(vlan_ids); + g_assert_cmpint(num, ==, 4); + g_assert_cmpint(vlan_ids[0], ==, 81); + g_assert_cmpint(nm_sriov_vf_get_vlan_qos(vf, 81), ==, 10); + g_assert_cmpint(nm_sriov_vf_get_vlan_protocol(vf, 81), ==, NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); + g_assert_cmpint(vlan_ids[1], ==, 83); + g_assert_cmpint(nm_sriov_vf_get_vlan_qos(vf, 83), ==, 0); + g_assert_cmpint(nm_sriov_vf_get_vlan_protocol(vf, 83), ==, NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); + g_assert_cmpint(vlan_ids[2], ==, 85); + g_assert_cmpint(nm_sriov_vf_get_vlan_qos(vf, 85), ==, 0); + g_assert_cmpint(nm_sriov_vf_get_vlan_protocol(vf, 85), ==, NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); + g_assert_cmpint(vlan_ids[3], ==, 4000); + g_assert_cmpint(nm_sriov_vf_get_vlan_qos(vf, 4000), ==, 0x20); + g_assert_cmpint(nm_sriov_vf_get_vlan_protocol(vf, 4000), ==, NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD); + + str = nm_utils_sriov_vf_to_str(vf, FALSE, &error); + nmtst_assert_success(str, error); + g_assert_cmpstr(str, ==, "20 spoof-check=false vlans=81.10;83;85;4000.32.ad"); + + nm_sriov_vf_unref(vf); +} + +static void +test_sriov_setting(void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingConnection * s_con; + NMSettingSriov * s_sriov = NULL; + NMSriovVF * vf1, *vf2, *vf3; + GError * error = NULL; + gboolean success; + + con = nm_simple_connection_new(); + + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(con, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test SR-IOV connection", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "eth0", + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + nm_connection_add_setting(con, nm_setting_wired_new()); + + s_sriov = (NMSettingSriov *) nm_setting_sriov_new(); + nm_connection_add_setting(con, NM_SETTING(s_sriov)); + + g_object_set(s_sriov, NM_SETTING_SRIOV_TOTAL_VFS, 16, NULL); + nm_setting_sriov_add_vf(s_sriov, (vf1 = nm_sriov_vf_new(0))); + nm_setting_sriov_add_vf(s_sriov, (vf2 = nm_sriov_vf_new(4))); + nm_setting_sriov_add_vf(s_sriov, (vf3 = nm_sriov_vf_new(10))); + g_assert(nm_setting_sriov_remove_vf_by_index(s_sriov, 4)); + nm_sriov_vf_unref(vf2); + nm_setting_sriov_add_vf(s_sriov, (vf2 = nm_sriov_vf_new(2))); + + nmtst_assert_connection_verifies_and_normalizable(con); + nmtst_connection_normalize(con); + success = nm_setting_verify((NMSetting *) s_sriov, con, &error); + nmtst_assert_success(success, error); + + g_assert_cmpint(nm_setting_sriov_get_num_vfs(s_sriov), ==, 3); + g_assert_cmpint(nm_sriov_vf_get_index(nm_setting_sriov_get_vf(s_sriov, 0)), ==, 0); + g_assert_cmpint(nm_sriov_vf_get_index(nm_setting_sriov_get_vf(s_sriov, 1)), ==, 2); + g_assert_cmpint(nm_sriov_vf_get_index(nm_setting_sriov_get_vf(s_sriov, 2)), ==, 10); + + nm_sriov_vf_unref(vf1); + nm_sriov_vf_unref(vf2); + nm_sriov_vf_unref(vf3); +} + +typedef struct { + guint id; + guint qos; + bool proto_ad; +} VlanData; + +static void +_test_sriov_parse_vlan_one(const char *string, gboolean exp_res, VlanData *data, guint data_length) +{ + NMSriovVF * vf; + gboolean res; + guint i, num_vlans; + const guint *vlan_ids; + + vf = nm_sriov_vf_new(1); + g_assert(vf); + + res = _nm_sriov_vf_parse_vlans(vf, string, NULL); + g_assert_cmpint(res, ==, exp_res); + + if (exp_res) { + vlan_ids = nm_sriov_vf_get_vlan_ids(vf, &num_vlans); + g_assert_cmpint(num_vlans, ==, data_length); + for (i = 0; i < num_vlans; i++) { + g_assert_cmpint(vlan_ids[i], ==, data[i].id); + g_assert_cmpint(nm_sriov_vf_get_vlan_qos(vf, vlan_ids[i]), ==, data[i].qos); + g_assert_cmpint(nm_sriov_vf_get_vlan_protocol(vf, vlan_ids[i]), + ==, + data[i].proto_ad ? NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD + : NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); + } + } + + nm_sriov_vf_unref(vf); +} + +#define test_sriov_parse_vlan_one(string, result, ...) \ + { \ + VlanData _data[] = {__VA_ARGS__}; \ + guint _length = G_N_ELEMENTS(_data); \ + \ + _test_sriov_parse_vlan_one(string, result, _data, _length); \ + } + +static void +test_sriov_parse_vlans(void) +{ + test_sriov_parse_vlan_one("", FALSE, {}); + test_sriov_parse_vlan_one("1", TRUE, {1, 0, 0}); + test_sriov_parse_vlan_one("1;2", TRUE, {1, 0, 0}, {2, 0, 0}); + test_sriov_parse_vlan_one("4095;;2", TRUE, {2, 0, 0}, {4095, 0, 0}); + test_sriov_parse_vlan_one("1 2", FALSE, {}); + test_sriov_parse_vlan_one("4096", FALSE, {}); + test_sriov_parse_vlan_one("1.10", TRUE, {1, 10, 0}); + test_sriov_parse_vlan_one("1.20.ad", TRUE, {1, 20, 1}); + test_sriov_parse_vlan_one("1.21.q", TRUE, {1, 21, 0}); + test_sriov_parse_vlan_one("9.20.foo", FALSE, {}); + test_sriov_parse_vlan_one("1.20.ad.12", FALSE, {}); + test_sriov_parse_vlan_one("1;1.10", FALSE, {}); + test_sriov_parse_vlan_one("1..1;2", FALSE, {}); + test_sriov_parse_vlan_one("1..ad;2", FALSE, {}); + test_sriov_parse_vlan_one("1.2.ad;2.0.q;5;3", TRUE, {1, 2, 1}, {2, 0, 0}, {3, 0, 0}, {5, 0, 0}); +} + +static void +test_bridge_vlans(void) +{ + NMBridgeVlan *v1, *v2; + GError * error = NULL; + guint16 vid_start, vid_end; + char * str; + + v1 = nm_bridge_vlan_from_str("1 foobar", &error); + nmtst_assert_no_success(v1, error); + g_clear_error(&error); + + v1 = nm_bridge_vlan_from_str("4095", &error); + nmtst_assert_no_success(v1, error); + g_clear_error(&error); + + /* test ranges */ + v1 = nm_bridge_vlan_from_str("2-1000 untagged", &error); + nmtst_assert_success(v1, error); + g_assert_cmpint(nm_bridge_vlan_get_vid_range(v1, &vid_start, &vid_end), ==, TRUE); + g_assert_cmpuint(vid_start, ==, 2); + g_assert_cmpuint(vid_end, ==, 1000); + g_assert_cmpint(nm_bridge_vlan_is_pvid(v1), ==, FALSE); + g_assert_cmpint(nm_bridge_vlan_is_untagged(v1), ==, TRUE); + nm_bridge_vlan_unref(v1); + + /* test comparison (1) */ + v1 = nm_bridge_vlan_from_str("10 untagged", &error); + nmtst_assert_success(v1, error); + + g_assert_cmpint(nm_bridge_vlan_get_vid_range(v1, &vid_start, &vid_end), ==, FALSE); + g_assert_cmpuint(vid_start, ==, 10); + g_assert_cmpuint(vid_end, ==, 10); + g_assert_cmpint(nm_bridge_vlan_is_sealed(v1), ==, FALSE); + g_assert_cmpint(nm_bridge_vlan_is_pvid(v1), ==, FALSE); + g_assert_cmpint(nm_bridge_vlan_is_untagged(v1), ==, TRUE); + + nm_bridge_vlan_set_pvid(v1, TRUE); + nm_bridge_vlan_set_untagged(v1, FALSE); + nm_bridge_vlan_seal(v1); + + g_assert_cmpint(nm_bridge_vlan_is_sealed(v1), ==, TRUE); + g_assert_cmpint(nm_bridge_vlan_is_pvid(v1), ==, TRUE); + g_assert_cmpint(nm_bridge_vlan_is_untagged(v1), ==, FALSE); + + str = nm_bridge_vlan_to_str(v1, &error); + nmtst_assert_success(str, error); + g_assert_cmpstr(str, ==, "10 pvid"); + nm_clear_g_free(&str); + + v2 = nm_bridge_vlan_from_str(" 10 pvid ", &error); + nmtst_assert_success(v2, error); + + g_assert_cmpint(nm_bridge_vlan_cmp(v1, v2), ==, 0); + + nm_bridge_vlan_unref(v1); + nm_bridge_vlan_unref(v2); + + /* test comparison (2) */ + v1 = nm_bridge_vlan_from_str("10", &error); + nmtst_assert_success(v1, error); + v2 = nm_bridge_vlan_from_str("20", &error); + nmtst_assert_success(v2, error); + + g_assert_cmpint(nm_bridge_vlan_cmp(v1, v2), <, 0); + + nm_bridge_vlan_unref(v1); + nm_bridge_vlan_unref(v2); +} + +static void +create_bridge_connection(NMConnection **con, NMSettingBridge **s_bridge) +{ + NMSettingConnection *s_con; + + g_assert(con); + g_assert(s_bridge); + + *con = nmtst_create_minimal_connection("bridge", NULL, NM_SETTING_BOND_SETTING_NAME, &s_con); + + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "bridge0", NULL); + + *s_bridge = (NMSettingBridge *) nm_setting_bridge_new(); + g_assert(*s_bridge); + + nm_connection_add_setting(*con, NM_SETTING(*s_bridge)); +} + +#define test_verify_options_bridge(exp, ...) \ + _test_verify_options_bridge(exp, NM_MAKE_STRV(__VA_ARGS__)) + +static void +_test_verify_options_bridge(gboolean expected_result, const char *const *options) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingBridge * s_bridge; + const char *const * option; + + g_assert(NM_PTRARRAY_LEN(options) % 2 == 0); + + create_bridge_connection(&con, &s_bridge); + + for (option = options; option[0]; option += 2) { + const char *option_key = option[0]; + const char *option_val = option[1]; + GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(s_bridge), option_key); + + g_assert(pspec); + g_assert(option_val); + + switch (G_PARAM_SPEC_VALUE_TYPE(pspec)) { + case G_TYPE_UINT: + { + guint uvalue; + + uvalue = _nm_utils_ascii_str_to_uint64(option_val, 10, 0, G_MAXUINT, -1); + g_assert(errno == 0); + g_object_set(s_bridge, option_key, uvalue, NULL); + } break; + case G_TYPE_BOOLEAN: + { + int bvalue; + + bvalue = _nm_utils_ascii_str_to_bool(option_val, -1); + g_assert(bvalue != -1); + g_object_set(s_bridge, option_key, bvalue, NULL); + } break; + case G_TYPE_STRING: + g_object_set(s_bridge, option_key, option_val, NULL); + break; + default: + g_assert_not_reached(); + break; + } + } + + if (expected_result) + nmtst_assert_connection_verifies_and_normalizable(con); + else { + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + } +} + +static void +test_bridge_verify(void) +{ + /* group-address */ + test_verify_options_bridge(FALSE, "group-address", "nonsense"); + test_verify_options_bridge(FALSE, "group-address", "FF:FF:FF:FF:FF:FF"); + test_verify_options_bridge(FALSE, "group-address", "01:02:03:04:05:06"); + test_verify_options_bridge(TRUE, "group-address", "01:80:C2:00:00:00"); + test_verify_options_bridge(FALSE, "group-address", "01:80:C2:00:00:02"); + test_verify_options_bridge(FALSE, "group-address", "01:80:C2:00:00:03"); + test_verify_options_bridge(TRUE, "group-address", "01:80:C2:00:00:00"); + test_verify_options_bridge(TRUE, "group-address", "01:80:C2:00:00:0A"); + /* vlan-protocol */ + test_verify_options_bridge(FALSE, "vlan-protocol", "nonsense124"); + test_verify_options_bridge(FALSE, "vlan-protocol", "802.11"); + test_verify_options_bridge(FALSE, "vlan-protocol", "802.1Q1"); + test_verify_options_bridge(TRUE, "vlan-protocol", "802.1Q"); + test_verify_options_bridge(TRUE, "vlan-protocol", "802.1ad"); + /* multicast-router */ + test_verify_options_bridge(FALSE, "multicast-router", "nonsense"); + test_verify_options_bridge(TRUE, "multicast-snooping", "no", "multicast-router", "auto"); + test_verify_options_bridge(TRUE, "multicast-snooping", "no", "multicast-router", "enabled"); + test_verify_options_bridge(TRUE, "multicast-snooping", "no", "multicast-router", "disabled"); + test_verify_options_bridge(TRUE, "multicast-snooping", "yes", "multicast-router", "enabled"); + test_verify_options_bridge(TRUE, "multicast-snooping", "yes", "multicast-router", "auto"); + test_verify_options_bridge(TRUE, "multicast-snooping", "yes", "multicast-router", "disabled"); + /* multicast-hash-max */ + test_verify_options_bridge(TRUE, "multicast-hash-max", "1024"); + test_verify_options_bridge(TRUE, "multicast-hash-max", "8192"); + test_verify_options_bridge(FALSE, "multicast-hash-max", "3"); +} + +/*****************************************************************************/ + +static void +test_tc_config_qdisc(void) +{ + NMTCQdisc *qdisc1, *qdisc2; + char * str; + GError * error = NULL; + GVariant * variant; + + qdisc1 = nm_tc_qdisc_new("fq_codel", TC_H_ROOT, &error); + nmtst_assert_success(qdisc1, error); + + qdisc2 = nm_tc_qdisc_new("fq_codel", TC_H_ROOT, &error); + nmtst_assert_success(qdisc2, error); + + g_assert(nm_tc_qdisc_equal(qdisc1, qdisc2)); + + nm_tc_qdisc_unref(qdisc2); + qdisc2 = nm_tc_qdisc_dup(qdisc1); + + g_assert(nm_tc_qdisc_equal(qdisc1, qdisc2)); + + g_assert_cmpstr(nm_tc_qdisc_get_kind(qdisc1), ==, "fq_codel"); + g_assert(nm_tc_qdisc_get_handle(qdisc1) == TC_H_UNSPEC); + g_assert(nm_tc_qdisc_get_parent(qdisc1) == TC_H_ROOT); + + str = nm_utils_tc_qdisc_to_str(qdisc1, &error); + nmtst_assert_success(str, error); + g_assert_cmpstr(str, ==, "root fq_codel"); + g_free(str); + + nm_tc_qdisc_unref(qdisc1); + qdisc1 = nm_tc_qdisc_new("ingress", TC_H_INGRESS, &error); + nmtst_assert_success(qdisc1, error); + + g_assert(!nm_tc_qdisc_equal(qdisc1, qdisc2)); + + str = nm_utils_tc_qdisc_to_str(qdisc1, &error); + nmtst_assert_success(str, error); + g_assert_cmpstr(str, ==, "ingress"); + g_free(str); + + nm_tc_qdisc_unref(qdisc1); + qdisc1 = nm_utils_tc_qdisc_from_str("narodil sa kristus pan", &error); + nmtst_assert_no_success(qdisc1, error); + g_clear_error(&error); + + qdisc1 = nm_utils_tc_qdisc_from_str("handle 1234 parent fff1:1 pfifo_fast", &error); + nmtst_assert_success(qdisc1, error); + + g_assert_cmpstr(nm_tc_qdisc_get_kind(qdisc1), ==, "pfifo_fast"); + g_assert(nm_tc_qdisc_get_handle(qdisc1) == TC_H_MAKE(0x1234u << 16, 0x0000u)); + g_assert(nm_tc_qdisc_get_parent(qdisc1) == TC_H_MAKE(0xfff1u << 16, 0x0001u)); + + str = nm_utils_tc_qdisc_to_str(qdisc1, &error); + nmtst_assert_success(str, error); + g_assert_cmpstr(str, ==, "parent fff1:1 handle 1234: pfifo_fast"); + g_free(str); + + nm_tc_qdisc_unref(qdisc2); + str = nm_utils_tc_qdisc_to_str(qdisc1, &error); + nmtst_assert_success(str, error); + qdisc2 = nm_utils_tc_qdisc_from_str(str, &error); + nmtst_assert_success(qdisc2, error); + g_free(str); + + g_assert(nm_tc_qdisc_equal(qdisc1, qdisc2)); + + nm_tc_qdisc_unref(qdisc1); + nm_tc_qdisc_unref(qdisc2); + + qdisc1 = nm_utils_tc_qdisc_from_str("clsact", &error); + nmtst_assert_success(qdisc1, error); + str = nm_utils_tc_qdisc_to_str(qdisc1, &error); + nmtst_assert_success(str, error); + g_assert_cmpstr(str, ==, "clsact"); + nm_tc_qdisc_unref(qdisc1); + g_free(str); + +#define CHECK_ATTRIBUTE(qdisc, name, vtype, type, value) \ + variant = nm_tc_qdisc_get_attribute(qdisc, name); \ + g_assert(variant); \ + g_assert(g_variant_is_of_type(variant, vtype)); \ + g_assert_cmpint(g_variant_get_##type(variant), ==, value); + + qdisc1 = nm_utils_tc_qdisc_from_str("handle 1235 root sfq perturb 10 quantum 1480 " + "limit 9000 flows 1024 divisor 500 depth 12", + &error); + nmtst_assert_success(qdisc1, error); + + g_assert_cmpstr(nm_tc_qdisc_get_kind(qdisc1), ==, "sfq"); + g_assert(nm_tc_qdisc_get_handle(qdisc1) == TC_H_MAKE(0x1235u << 16, 0x0000u)); + g_assert(nm_tc_qdisc_get_parent(qdisc1) == TC_H_ROOT); + CHECK_ATTRIBUTE(qdisc1, "perturb", G_VARIANT_TYPE_INT32, int32, 10); + CHECK_ATTRIBUTE(qdisc1, "quantum", G_VARIANT_TYPE_UINT32, uint32, 1480); + CHECK_ATTRIBUTE(qdisc1, "limit", G_VARIANT_TYPE_UINT32, uint32, 9000); + CHECK_ATTRIBUTE(qdisc1, "flows", G_VARIANT_TYPE_UINT32, uint32, 1024); + CHECK_ATTRIBUTE(qdisc1, "divisor", G_VARIANT_TYPE_UINT32, uint32, 500); + CHECK_ATTRIBUTE(qdisc1, "depth", G_VARIANT_TYPE_UINT32, uint32, 12); + nm_tc_qdisc_unref(qdisc1); + + qdisc1 = nm_utils_tc_qdisc_from_str("handle 1235 root tbf rate 1000000 burst 5000 limit 10000", + &error); + nmtst_assert_success(qdisc1, error); + + g_assert_cmpstr(nm_tc_qdisc_get_kind(qdisc1), ==, "tbf"); + g_assert(nm_tc_qdisc_get_handle(qdisc1) == TC_H_MAKE(0x1235u << 16, 0x0000u)); + g_assert(nm_tc_qdisc_get_parent(qdisc1) == TC_H_ROOT); + CHECK_ATTRIBUTE(qdisc1, "rate", G_VARIANT_TYPE_UINT64, uint64, 1000000); + CHECK_ATTRIBUTE(qdisc1, "burst", G_VARIANT_TYPE_UINT32, uint32, 5000); + CHECK_ATTRIBUTE(qdisc1, "limit", G_VARIANT_TYPE_UINT32, uint32, 10000); + nm_tc_qdisc_unref(qdisc1); + +#undef CHECK_ATTRIBUTE +} + +static void +test_tc_config_action(void) +{ + NMTCAction *action1, *action2; + char * str; + GError * error = NULL; + + action1 = nm_tc_action_new("drop", &error); + nmtst_assert_success(action1, error); + action2 = nm_tc_action_new("drop", &error); + nmtst_assert_success(action2, error); + + g_assert(nm_tc_action_equal(action1, action2)); + g_assert_cmpstr(nm_tc_action_get_kind(action1), ==, "drop"); + + nm_tc_action_unref(action1); + action1 = nm_tc_action_new("simple", &error); + nmtst_assert_success(action1, error); + nm_tc_action_set_attribute(action1, "sdata", g_variant_new_bytestring("Hello")); + + g_assert(!nm_tc_action_equal(action1, action2)); + + str = nm_utils_tc_action_to_str(action1, &error); + nmtst_assert_success(str, error); + g_assert_cmpstr(str, ==, "simple sdata Hello"); + g_free(str); + + str = nm_utils_tc_action_to_str(action2, &error); + nmtst_assert_success(str, error); + g_assert_cmpstr(str, ==, "drop"); + g_free(str); + + nm_tc_action_unref(action2); + action2 = nm_tc_action_dup(action1); + + g_assert(nm_tc_action_equal(action1, action2)); + + nm_tc_action_unref(action1); + action1 = nm_utils_tc_action_from_str("narodil sa kristus pan", &error); + nmtst_assert_no_success(action1, error); + g_clear_error(&error); + + action1 = nm_utils_tc_action_from_str("simple sdata Hello", &error); + nmtst_assert_success(action1, error); + + g_assert_cmpstr(nm_tc_action_get_kind(action1), ==, "simple"); + g_assert_cmpstr(g_variant_get_bytestring(nm_tc_action_get_attribute(action1, "sdata")), + ==, + "Hello"); + + nm_tc_action_unref(action1); + nm_tc_action_unref(action2); +} + +static void +test_tc_config_tfilter_matchall_sdata(void) +{ + NMTCAction * action1; + NMTCTfilter *tfilter1, *tfilter2; + char * str; + GError * error = NULL; + + tfilter1 = nm_tc_tfilter_new("matchall", TC_H_MAKE(0x1234u << 16, 0x0000u), &error); + nmtst_assert_success(tfilter1, error); + + tfilter2 = nm_tc_tfilter_new("matchall", TC_H_MAKE(0x1234u << 16, 0x0000u), &error); + nmtst_assert_success(tfilter2, error); + + g_assert(nm_tc_tfilter_equal(tfilter1, tfilter2)); + + action1 = nm_tc_action_new("simple", &error); + nmtst_assert_success(action1, error); + nm_tc_action_set_attribute(action1, "sdata", g_variant_new_bytestring("Hello")); + nm_tc_tfilter_set_action(tfilter1, action1); + nm_tc_action_unref(action1); + + g_assert(!nm_tc_tfilter_equal(tfilter1, tfilter2)); + + str = nm_utils_tc_tfilter_to_str(tfilter1, &error); + nmtst_assert_success(str, error); + g_assert_cmpstr(str, ==, "parent 1234: matchall action simple sdata Hello"); + g_free(str); + + nm_tc_tfilter_unref(tfilter2); + tfilter2 = nm_tc_tfilter_dup(tfilter1); + + g_assert(nm_tc_tfilter_equal(tfilter1, tfilter2)); + + nm_tc_tfilter_unref(tfilter1); + tfilter1 = nm_utils_tc_tfilter_from_str("narodil sa kristus pan", &error); + nmtst_assert_no_success(tfilter1, error); + g_clear_error(&error); + + str = nm_utils_tc_tfilter_to_str(tfilter2, &error); + nmtst_assert_success(str, error); + tfilter1 = nm_utils_tc_tfilter_from_str(str, &error); + nmtst_assert_success(tfilter1, error); + g_free(str); + + g_assert(nm_tc_tfilter_equal(tfilter1, tfilter2)); + + nm_tc_tfilter_unref(tfilter1); + nm_tc_tfilter_unref(tfilter2); +} + +static void +test_tc_config_tfilter_matchall_mirred(void) +{ + NMTCAction * action; + NMTCTfilter * tfilter1; + GError * error = NULL; + gs_strfreev char **attr_names = NULL; + gs_free char * str; + GVariant * variant; + + tfilter1 = + nm_utils_tc_tfilter_from_str("parent ffff: matchall action mirred ingress mirror dev eth0", + &error); + nmtst_assert_success(tfilter1, error); + g_assert_cmpint(nm_tc_tfilter_get_parent(tfilter1), ==, TC_H_MAKE(0xffff << 16, 0)); + g_assert_cmpstr(nm_tc_tfilter_get_kind(tfilter1), ==, "matchall"); + + action = nm_tc_tfilter_get_action(tfilter1); + nm_assert(action); + g_assert_cmpstr(nm_tc_action_get_kind(action), ==, "mirred"); + attr_names = nm_tc_action_get_attribute_names(action); + g_assert(attr_names); + g_assert_cmpint(g_strv_length(attr_names), ==, 3); + + variant = nm_tc_action_get_attribute(action, "ingress"); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)); + g_assert(g_variant_get_boolean(variant)); + + variant = nm_tc_action_get_attribute(action, "mirror"); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)); + g_assert(g_variant_get_boolean(variant)); + + variant = nm_tc_action_get_attribute(action, "dev"); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr(g_variant_get_string(variant, NULL), ==, "eth0"); + + str = nm_utils_tc_tfilter_to_str(tfilter1, &error); + nmtst_assert_success(str, error); + g_assert_cmpstr(str, ==, "parent ffff: matchall action mirred dev eth0 ingress mirror"); + + nm_tc_tfilter_unref(tfilter1); +} + +static void +test_tc_config_setting_valid(void) +{ + gs_unref_object NMSettingTCConfig *s_tc = NULL; + NMTCQdisc * qdisc1, *qdisc2; + GError * error = NULL; + + s_tc = (NMSettingTCConfig *) nm_setting_tc_config_new(); + + qdisc1 = nm_tc_qdisc_new("fq_codel", TC_H_ROOT, &error); + nmtst_assert_success(qdisc1, error); + + qdisc2 = nm_tc_qdisc_new("pfifo_fast", TC_H_MAKE(0xfff1u << 16, 0x0001u), &error); + nmtst_assert_success(qdisc2, error); + nm_tc_qdisc_set_handle(qdisc2, TC_H_MAKE(0x1234u << 16, 0x0000u)); + + g_assert(nm_setting_tc_config_get_num_qdiscs(s_tc) == 0); + g_assert(nm_setting_tc_config_add_qdisc(s_tc, qdisc1) == TRUE); + g_assert(nm_setting_tc_config_get_num_qdiscs(s_tc) == 1); + g_assert(nm_setting_tc_config_get_qdisc(s_tc, 0) != NULL); + g_assert(nm_setting_tc_config_remove_qdisc_by_value(s_tc, qdisc2) == FALSE); + g_assert(nm_setting_tc_config_add_qdisc(s_tc, qdisc2) == TRUE); + g_assert(nm_setting_tc_config_get_num_qdiscs(s_tc) == 2); + g_assert(nm_setting_tc_config_remove_qdisc_by_value(s_tc, qdisc1) == TRUE); + g_assert(nm_setting_tc_config_get_num_qdiscs(s_tc) == 1); + nm_setting_tc_config_clear_qdiscs(s_tc); + g_assert(nm_setting_tc_config_get_num_qdiscs(s_tc) == 0); + + nm_tc_qdisc_unref(qdisc1); + nm_tc_qdisc_unref(qdisc2); +} + +static void +test_tc_config_setting_duplicates(void) +{ + gs_unref_ptrarray GPtrArray *qdiscs = NULL; + gs_unref_ptrarray GPtrArray *tfilters = NULL; + NMSettingConnection * s_con; + NMConnection * con; + NMSetting * s_tc; + NMTCQdisc * qdisc; + NMTCTfilter * tfilter; + GError * error = NULL; + + con = nmtst_create_minimal_connection("dummy", NULL, NM_SETTING_DUMMY_SETTING_NAME, &s_con); + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "dummy1", NULL); + + s_tc = nm_setting_tc_config_new(); + nm_connection_add_setting(con, s_tc); + qdiscs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_tc_qdisc_unref); + tfilters = g_ptr_array_new_with_free_func((GDestroyNotify) nm_tc_tfilter_unref); + + /* 1. add duplicate qdiscs */ + qdisc = nm_utils_tc_qdisc_from_str("handle 1234 parent fff1:1 pfifo_fast", &error); + nmtst_assert_success(qdisc, error); + g_ptr_array_add(qdiscs, qdisc); + + qdisc = nm_utils_tc_qdisc_from_str("handle 1234 parent fff1:1 pfifo_fast", &error); + nmtst_assert_success(qdisc, error); + g_ptr_array_add(qdiscs, qdisc); + + g_object_set(s_tc, NM_SETTING_TC_CONFIG_QDISCS, qdiscs, NULL); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + + /* 2. make qdiscs unique */ + g_ptr_array_remove_index(qdiscs, 0); + g_object_set(s_tc, NM_SETTING_TC_CONFIG_QDISCS, qdiscs, NULL); + nmtst_assert_connection_verifies_and_normalizable(con); + + /* 3. add duplicate filters */ + tfilter = + nm_utils_tc_tfilter_from_str("parent 1234: matchall action simple sdata Hello", &error); + nmtst_assert_success(tfilter, error); + g_ptr_array_add(tfilters, tfilter); + + tfilter = + nm_utils_tc_tfilter_from_str("parent 1234: matchall action simple sdata Hello", &error); + nmtst_assert_success(tfilter, error); + g_ptr_array_add(tfilters, tfilter); + + g_object_set(s_tc, NM_SETTING_TC_CONFIG_TFILTERS, tfilters, NULL); + nmtst_assert_connection_unnormalizable(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + + /* 4. make filters unique */ + g_ptr_array_remove_index(tfilters, 0); + g_object_set(s_tc, NM_SETTING_TC_CONFIG_TFILTERS, tfilters, NULL); + nmtst_assert_connection_verifies_and_normalizable(con); +} + +static void +test_tc_config_dbus(void) +{ + NMConnection *connection1, *connection2; + NMSetting * s_tc; + NMTCQdisc * qdisc1, *qdisc2; + NMTCTfilter * tfilter1, *tfilter2; + NMTCAction * action; + GVariant * dbus, *tc_dbus, *var1, *var2; + GError * error = NULL; + gboolean success; + + connection1 = + nmtst_create_minimal_connection("dummy", NULL, NM_SETTING_DUMMY_SETTING_NAME, NULL); + + s_tc = nm_setting_tc_config_new(); + + qdisc1 = nm_tc_qdisc_new("fq_codel", TC_H_ROOT, &error); + nmtst_assert_success(qdisc1, error); + nm_tc_qdisc_set_handle(qdisc1, TC_H_MAKE(0x1234u << 16, 0x0000u)); + nm_setting_tc_config_add_qdisc(NM_SETTING_TC_CONFIG(s_tc), qdisc1); + + qdisc2 = nm_tc_qdisc_new("ingress", TC_H_INGRESS, &error); + nmtst_assert_success(qdisc2, error); + nm_tc_qdisc_set_handle(qdisc2, TC_H_MAKE(TC_H_INGRESS, 0u)); + nm_setting_tc_config_add_qdisc(NM_SETTING_TC_CONFIG(s_tc), qdisc2); + + tfilter1 = nm_tc_tfilter_new("matchall", TC_H_MAKE(0x1234u << 16, 0x0000u), &error); + nmtst_assert_success(tfilter1, error); + action = nm_tc_action_new("drop", &error); + nmtst_assert_success(action, error); + nm_tc_tfilter_set_action(tfilter1, action); + nm_tc_action_unref(action); + nm_setting_tc_config_add_tfilter(NM_SETTING_TC_CONFIG(s_tc), tfilter1); + nm_tc_tfilter_unref(tfilter1); + + tfilter2 = nm_tc_tfilter_new("matchall", TC_H_MAKE(TC_H_INGRESS, 0u), &error); + nmtst_assert_success(tfilter2, error); + action = nm_tc_action_new("simple", &error); + nmtst_assert_success(action, error); + nm_tc_action_set_attribute(action, "sdata", g_variant_new_bytestring("Hello")); + nm_tc_tfilter_set_action(tfilter2, action); + nm_tc_action_unref(action); + nm_setting_tc_config_add_tfilter(NM_SETTING_TC_CONFIG(s_tc), tfilter2); + nm_tc_tfilter_unref(tfilter2); + + nm_connection_add_setting(connection1, s_tc); + + dbus = nm_connection_to_dbus(connection1, NM_CONNECTION_SERIALIZE_ALL); + + tc_dbus = g_variant_lookup_value(dbus, "tc", G_VARIANT_TYPE_VARDICT); + g_assert(tc_dbus); + + var1 = g_variant_lookup_value(tc_dbus, "qdiscs", G_VARIANT_TYPE("aa{sv}")); + var2 = g_variant_new_parsed("[{'kind': <'fq_codel'>," + " 'handle': ," + " 'parent': }," + " {'kind': <'ingress'>," + " 'handle': ," + " 'parent': }]"); + g_assert(g_variant_equal(var1, var2)); + g_variant_unref(var1); + g_variant_unref(var2); + + var1 = g_variant_lookup_value(tc_dbus, "tfilters", G_VARIANT_TYPE("aa{sv}")); + var2 = g_variant_new_parsed("[{'kind': <'matchall'>," + " 'handle': ," + " 'parent': ," + " 'action': <{'kind': <'drop'>}>}," + " {'kind': <'matchall'>," + " 'handle': ," + " 'parent': ," + " 'action': <{'kind': <'simple'>," + " 'sdata': }>}]"); + g_variant_unref(var1); + g_variant_unref(var2); + + g_variant_unref(tc_dbus); + + connection2 = nm_simple_connection_new(); + success = nm_connection_replace_settings(connection2, dbus, &error); + nmtst_assert_success(success, error); + + g_assert(nm_connection_diff(connection1, connection2, NM_SETTING_COMPARE_FLAG_EXACT, NULL)); + + g_variant_unref(dbus); + + nm_tc_qdisc_unref(qdisc1); + nm_tc_qdisc_unref(qdisc2); + + g_object_unref(connection1); + g_object_unref(connection2); +} + +/*****************************************************************************/ + +static void +_rndt_wired_add_s390_options(NMSettingWired *s_wired, char **out_keyfile_entries) +{ + gsize n_opts; + gsize i, j; + const char *const * option_names; + gs_free const char **opt_keys = NULL; + gs_strfreev char ** opt_vals = NULL; + gs_free bool * opt_found = NULL; + GString * keyfile_entries; + nm_auto_free_gstring GString *str_tmp = NULL; + + option_names = nm_setting_wired_get_valid_s390_options(nmtst_get_rand_bool() ? NULL : s_wired); + + n_opts = NM_PTRARRAY_LEN(option_names); + opt_keys = g_new(const char *, (n_opts + 1)); + nmtst_rand_perm(NULL, opt_keys, option_names, sizeof(const char *), n_opts); + n_opts = nmtst_get_rand_uint32() % (n_opts + 1); + opt_keys[n_opts] = NULL; + + opt_vals = g_new0(char *, n_opts + 1); + opt_found = g_new0(bool, n_opts + 1); + for (i = 0; i < n_opts; i++) { + if (nm_streq(opt_keys[i], "bridge_role")) + opt_vals[i] = g_strdup(nmtst_rand_select_str("primary", "secondary", "none")); + else { + guint p = nmtst_get_rand_uint32() % 1000; + if (p < 200) + opt_vals[i] = nm_strdup_int(i); + else { + opt_vals[i] = g_strdup_printf("%s%s%s%s-%zu", + ((p % 5) % 2) ? "\n" : "", + ((p % 7) % 2) ? "\t" : "", + ((p % 11) % 2) ? "x" : "", + ((p % 13) % 2) ? "=" : "", + i); + } + } + } + + if (nmtst_get_rand_bool()) { + gs_unref_hashtable GHashTable *hash = NULL; + + hash = g_hash_table_new(nm_str_hash, g_str_equal); + for (i = 0; i < n_opts; i++) + g_hash_table_insert(hash, (char *) opt_keys[i], opt_vals[i]); + g_object_set(s_wired, NM_SETTING_WIRED_S390_OPTIONS, hash, NULL); + } else { + _nm_setting_wired_clear_s390_options(s_wired); + for (i = 0; i < n_opts; i++) { + if (!nm_setting_wired_add_s390_option(s_wired, opt_keys[i], opt_vals[i])) + g_assert_not_reached(); + } + } + + g_assert_cmpint(nm_setting_wired_get_num_s390_options(s_wired), ==, n_opts); + + keyfile_entries = g_string_new(NULL); + str_tmp = g_string_new(NULL); + if (n_opts > 0) + g_string_append_printf(keyfile_entries, "[ethernet-s390-options]\n"); + for (i = 0; i < n_opts; i++) { + gssize idx; + const char *k, *v; + + nm_setting_wired_get_s390_option(s_wired, i, &k, &v); + g_assert(k); + g_assert(v); + + idx = nm_utils_strv_find_first((char **) opt_keys, n_opts, k); + g_assert(idx >= 0); + g_assert(!opt_found[idx]); + opt_found[idx] = TRUE; + g_assert_cmpstr(opt_keys[idx], ==, k); + g_assert_cmpstr(opt_vals[idx], ==, v); + + g_string_truncate(str_tmp, 0); + for (j = 0; v[j] != '\0'; j++) { + if (v[j] == '\n') + g_string_append(str_tmp, "\\n"); + else if (v[j] == '\t') + g_string_append(str_tmp, "\\t"); + else + g_string_append_c(str_tmp, v[j]); + } + + g_string_append_printf(keyfile_entries, "%s=%s\n", k, str_tmp->str); + } + for (i = 0; i < n_opts; i++) + g_assert(opt_found[i]); + if (n_opts > 0) + g_string_append_printf(keyfile_entries, "\n"); + *out_keyfile_entries = g_string_free(keyfile_entries, FALSE); +} + +static GPtrArray * +_rndt_wg_peers_create(void) +{ + GPtrArray *wg_peers; + guint i, n; + + wg_peers = g_ptr_array_new_with_free_func((GDestroyNotify) nm_wireguard_peer_unref); + + n = nmtst_get_rand_uint32() % 10; + for (i = 0; i < n; i++) { + NMWireGuardPeer *peer; + guint8 public_key_buf[NM_WIREGUARD_PUBLIC_KEY_LEN]; + guint8 preshared_key_buf[NM_WIREGUARD_SYMMETRIC_KEY_LEN]; + gs_free char * public_key = NULL; + gs_free char * preshared_key = NULL; + gs_free char * s_endpoint = NULL; + guint i_aip, n_aip; + + /* we don't bother to create a valid curve25519 public key. Of course, libnm cannot + * check whether the public key is bogus or not. Hence, for our purpose a random + * bogus key is good enough. */ + public_key = g_base64_encode(nmtst_rand_buf(NULL, public_key_buf, sizeof(public_key_buf)), + sizeof(public_key_buf)); + + preshared_key = + g_base64_encode(nmtst_rand_buf(NULL, preshared_key_buf, sizeof(preshared_key_buf)), + sizeof(preshared_key_buf)); + + s_endpoint = _create_random_ipaddr(AF_UNSPEC, TRUE); + + peer = nm_wireguard_peer_new(); + if (!nm_wireguard_peer_set_public_key(peer, public_key, TRUE)) + g_assert_not_reached(); + + if (!nm_wireguard_peer_set_preshared_key(peer, + nmtst_rand_select(NULL, preshared_key), + TRUE)) + g_assert_not_reached(); + + nm_wireguard_peer_set_preshared_key_flags( + peer, + nmtst_rand_select(NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING_SECRET_FLAG_AGENT_OWNED)); + + nm_wireguard_peer_set_persistent_keepalive( + peer, + nmtst_rand_select((guint32) 0, nmtst_get_rand_uint32())); + + if (!nm_wireguard_peer_set_endpoint(peer, nmtst_rand_select(s_endpoint, NULL), TRUE)) + g_assert_not_reached(); + + n_aip = nmtst_rand_select(0, nmtst_get_rand_uint32() % 10); + for (i_aip = 0; i_aip < n_aip; i_aip++) { + gs_free char *aip = NULL; + + aip = _create_random_ipaddr(AF_UNSPEC, FALSE); + if (!nm_wireguard_peer_append_allowed_ip(peer, aip, FALSE)) + g_assert_not_reached(); + } + + g_assert(nm_wireguard_peer_is_valid(peer, TRUE, TRUE, NULL)); + + nm_wireguard_peer_seal(peer); + g_ptr_array_add(wg_peers, peer); + } + + return wg_peers; +} + +static const char * +_rndt_wg_peers_to_keyfile(GPtrArray *wg_peers, gboolean strict, char **out_str) +{ + nm_auto_free_gstring GString *gstr = NULL; + nm_auto_free_gstring GString *gstr_aip = NULL; + guint i, j; + + g_assert(wg_peers); + g_assert(out_str && !*out_str); + + nm_gstring_prepare(&gstr); + for (i = 0; i < wg_peers->len; i++) { + const NMWireGuardPeer *peer = wg_peers->pdata[i]; + gs_free char * s_endpoint = NULL; + gs_free char * s_preshared_key = NULL; + gs_free char * s_preshared_key_flags = NULL; + gs_free char * s_persistent_keepalive = NULL; + gs_free char * s_allowed_ips = NULL; + + if (nm_wireguard_peer_get_endpoint(peer)) + s_endpoint = g_strdup_printf("endpoint=%s\n", nm_wireguard_peer_get_endpoint(peer)); + else if (!strict) + s_endpoint = g_strdup_printf("endpoint=\n"); + + if (nm_wireguard_peer_get_preshared_key(peer) || !strict) { + if (nm_wireguard_peer_get_preshared_key_flags(peer) == NM_SETTING_SECRET_FLAG_NONE) + s_preshared_key = g_strdup_printf("preshared-key=%s\n", + nm_wireguard_peer_get_preshared_key(peer) ?: ""); + } + + if (nm_wireguard_peer_get_preshared_key_flags(peer) != NM_SETTING_SECRET_FLAG_NOT_REQUIRED + || !strict) + s_preshared_key_flags = + g_strdup_printf("preshared-key-flags=%d\n", + (int) nm_wireguard_peer_get_preshared_key_flags(peer)); + + if (nm_wireguard_peer_get_persistent_keepalive(peer) != 0 || !strict) + s_persistent_keepalive = + g_strdup_printf("persistent-keepalive=%u\n", + nm_wireguard_peer_get_persistent_keepalive(peer)); + + if (nm_wireguard_peer_get_allowed_ips_len(peer) > 0 || !strict) { + nm_gstring_prepare(&gstr_aip); + for (j = 0; j < nm_wireguard_peer_get_allowed_ips_len(peer); j++) + g_string_append_printf(gstr_aip, + "%s;", + nm_wireguard_peer_get_allowed_ip(peer, j, NULL)); + s_allowed_ips = g_strdup_printf("allowed-ips=%s\n", gstr_aip->str); + } + + if (!s_endpoint && !s_preshared_key && !s_preshared_key_flags && !s_persistent_keepalive + && !s_allowed_ips) + s_endpoint = g_strdup_printf("endpoint=\n"); + + g_string_append_printf(gstr, + "\n" + "[wireguard-peer.%s]\n" + "%s" /* endpoint */ + "%s" /* preshared-key */ + "%s" /* preshared-key-flags */ + "%s" /* persistent-keepalive */ + "%s" /* allowed-ips */ + "", + nm_wireguard_peer_get_public_key(peer), + s_endpoint ?: "", + s_preshared_key ?: "", + s_preshared_key_flags ?: "", + s_persistent_keepalive ?: "", + s_allowed_ips ?: ""); + } + + return (*out_str = g_string_free(g_steal_pointer(&gstr), FALSE)); +} + +static void +_rndt_wg_peers_assert_equal(NMSettingWireGuard *s_wg, + GPtrArray * peers, + gboolean consider_persistent_secrets, + gboolean consider_all_secrets, + gboolean expect_no_secrets) +{ + guint i; + + g_assert(NM_IS_SETTING_WIREGUARD(s_wg)); + g_assert(peers); + + g_assert_cmpint(peers->len, ==, nm_setting_wireguard_get_peers_len(s_wg)); + + for (i = 0; i < peers->len; i++) { + const NMWireGuardPeer *a = peers->pdata[i]; + const NMWireGuardPeer *b = nm_setting_wireguard_get_peer(s_wg, i); + gboolean consider_secrets; + + g_assert(a); + g_assert(b); + + g_assert_cmpint(nm_wireguard_peer_cmp(a, b, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS), ==, 0); + + if (consider_all_secrets || !nm_wireguard_peer_get_preshared_key(a)) + consider_secrets = TRUE; + else if (nm_wireguard_peer_get_preshared_key(b)) + consider_secrets = TRUE; + else if (consider_persistent_secrets + && nm_wireguard_peer_get_preshared_key_flags(b) == NM_SETTING_SECRET_FLAG_NONE) + consider_secrets = TRUE; + else + consider_secrets = FALSE; + + if (consider_secrets) { + g_assert_cmpstr(nm_wireguard_peer_get_preshared_key(a), + ==, + nm_wireguard_peer_get_preshared_key(b)); + g_assert_cmpint(nm_wireguard_peer_cmp(a, b, NM_SETTING_COMPARE_FLAG_EXACT), ==, 0); + } + + if (expect_no_secrets) + g_assert_cmpstr(nm_wireguard_peer_get_preshared_key(b), ==, NULL); + } +} + +static void +_rndt_wg_peers_fix_secrets(NMSettingWireGuard *s_wg, GPtrArray *peers) +{ + guint i; + + g_assert(NM_IS_SETTING_WIREGUARD(s_wg)); + g_assert(peers); + + g_assert_cmpint(peers->len, ==, nm_setting_wireguard_get_peers_len(s_wg)); + + for (i = 0; i < peers->len; i++) { + const NMWireGuardPeer *a = peers->pdata[i]; + const NMWireGuardPeer *b = nm_setting_wireguard_get_peer(s_wg, i); + nm_auto_unref_wgpeer NMWireGuardPeer *b_clone = NULL; + + g_assert(a); + g_assert(b); + + g_assert_cmpint(nm_wireguard_peer_get_preshared_key_flags(a), + ==, + nm_wireguard_peer_get_preshared_key_flags(b)); + g_assert_cmpint(nm_wireguard_peer_cmp(a, b, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS), ==, 0); + + if (!nm_streq0(nm_wireguard_peer_get_preshared_key(a), + nm_wireguard_peer_get_preshared_key(b))) { + g_assert_cmpstr(nm_wireguard_peer_get_preshared_key(a), !=, NULL); + g_assert_cmpstr(nm_wireguard_peer_get_preshared_key(b), ==, NULL); + g_assert(NM_IN_SET(nm_wireguard_peer_get_preshared_key_flags(a), + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NM_SETTING_SECRET_FLAG_NOT_SAVED)); + b_clone = nm_wireguard_peer_new_clone(b, TRUE); + if (!nm_wireguard_peer_set_preshared_key(b_clone, + nm_wireguard_peer_get_preshared_key(a), + TRUE)) + g_assert_not_reached(); + nm_setting_wireguard_set_peer(s_wg, b_clone, i); + b = nm_setting_wireguard_get_peer(s_wg, i); + g_assert(b == b_clone); + } else { + if (nm_wireguard_peer_get_preshared_key(a)) { + g_assert(NM_IN_SET(nm_wireguard_peer_get_preshared_key_flags(a), + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAG_NOT_REQUIRED)); + } else { + g_assert(NM_IN_SET(nm_wireguard_peer_get_preshared_key_flags(a), + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING_SECRET_FLAG_NOT_REQUIRED)); + } + } + + g_assert_cmpstr(nm_wireguard_peer_get_preshared_key(a), + ==, + nm_wireguard_peer_get_preshared_key(b)); + g_assert_cmpint(nm_wireguard_peer_cmp(a, b, NM_SETTING_COMPARE_FLAG_EXACT), ==, 0); + } +} + +static void +test_roundtrip_conversion(gconstpointer test_data) +{ + const int MODE = GPOINTER_TO_INT(test_data); + const char *ID = nm_sprintf_bufa(100, "roundtrip-conversion-%d", MODE); + const char *UUID = "63376701-b61e-4318-bf7e-664a1c1eeaab"; + const char *INTERFACE_NAME = nm_sprintf_bufa(100, "ifname%d", MODE); + guint32 ETH_MTU = nmtst_rand_select((guint32) 0u, nmtst_get_rand_uint32()); + const char *WG_PRIVATE_KEY = + nmtst_get_rand_bool() ? "yGXGK+5bVnxSJUejH4vbpXbq+ZtaG4NB8IHRK/aVtE0=" : NULL; + const NMSettingSecretFlags WG_PRIVATE_KEY_FLAGS = + nmtst_rand_select(NM_SETTING_SECRET_FLAG_NONE, + NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING_SECRET_FLAG_AGENT_OWNED); + const guint WG_LISTEN_PORT = nmtst_rand_select(0u, nmtst_get_rand_uint32() % 0x10000); + const guint WG_FWMARK = nmtst_rand_select(0u, nmtst_get_rand_uint32()); + gs_unref_ptrarray GPtrArray *kf_data_arr = g_ptr_array_new_with_free_func(g_free); + gs_unref_ptrarray GPtrArray * wg_peers = NULL; + const NMConnectionSerializationFlags dbus_serialization_flags[] = { + NM_CONNECTION_SERIALIZE_ALL, + NM_CONNECTION_SERIALIZE_NO_SECRETS, + NM_CONNECTION_SERIALIZE_ONLY_SECRETS, + }; + guint dbus_serialization_flags_idx; + gs_unref_object NMConnection *con = NULL; + gs_free_error GError *error = NULL; + gs_free char * tmp_str = NULL; + guint kf_data_idx; + NMSettingConnection * s_con = NULL; + NMSettingWired * s_eth = NULL; + NMSettingWireGuard * s_wg = NULL; + union { + struct { + NMSettingIPConfig *s_6; + NMSettingIPConfig *s_4; + }; + NMSettingIPConfig *s_x[2]; + } s_ip; + int is_ipv4; + guint i; + gboolean success; + gs_free char *s390_keyfile_entries = NULL; + + switch (MODE) { + case 0: + con = nmtst_create_minimal_connection(ID, UUID, NM_SETTING_WIRED_SETTING_NAME, &s_con); + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, INTERFACE_NAME, NULL); + nmtst_connection_normalize(con); + + s_eth = NM_SETTING_WIRED(nm_connection_get_setting(con, NM_TYPE_SETTING_WIRED)); + g_assert(NM_IS_SETTING_WIRED(s_eth)); + + g_object_set(s_eth, NM_SETTING_WIRED_MTU, ETH_MTU, NULL); + + _rndt_wired_add_s390_options(s_eth, &s390_keyfile_entries); + + g_ptr_array_add( + kf_data_arr, + g_strdup_printf("[connection]\n" + "id=%s\n" + "uuid=%s\n" + "type=ethernet\n" + "interface-name=%s\n" + "permissions=\n" + "\n" + "[ethernet]\n" + "mac-address-blacklist=\n" + "%s" /* mtu */ + "\n" + "%s" /* [ethernet-s390-options] */ + "[ipv4]\n" + "dns-search=\n" + "method=auto\n" + "\n" + "[ipv6]\n" + "addr-gen-mode=stable-privacy\n" + "dns-search=\n" + "method=auto\n" + "\n" + "[proxy]\n" + "", + ID, + UUID, + INTERFACE_NAME, + (ETH_MTU != 0) ? nm_sprintf_bufa(100, "mtu=%u\n", ETH_MTU) : "", + s390_keyfile_entries)); + + g_ptr_array_add( + kf_data_arr, + g_strdup_printf("[connection]\n" + "id=%s\n" + "uuid=%s\n" + "type=ethernet\n" + "interface-name=%s\n" + "permissions=\n" + "\n" + "[ethernet]\n" + "mac-address-blacklist=\n" + "%s" /* mtu */ + "\n" + "%s" /* [ethernet-s390-options] */ + "[ipv4]\n" + "dns-search=\n" + "method=auto\n" + "\n" + "[ipv6]\n" + "addr-gen-mode=stable-privacy\n" + "dns-search=\n" + "method=auto\n" + "", + ID, + UUID, + INTERFACE_NAME, + (ETH_MTU != 0) ? nm_sprintf_bufa(100, "mtu=%d\n", (int) ETH_MTU) : "", + s390_keyfile_entries)); + + break; + + case 1: + con = nmtst_create_minimal_connection(ID, UUID, "wireguard", &s_con); + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, INTERFACE_NAME, NULL); + nmtst_connection_normalize(con); + + s_wg = NM_SETTING_WIREGUARD(nm_connection_get_setting(con, NM_TYPE_SETTING_WIREGUARD)); + + g_ptr_array_add(kf_data_arr, + g_strdup_printf("[connection]\n" + "id=%s\n" + "uuid=%s\n" + "type=wireguard\n" + "interface-name=%s\n" + "permissions=\n" + "\n" + "[wireguard]\n" + "\n" + "[ipv4]\n" + "dns-search=\n" + "method=disabled\n" + "\n" + "[ipv6]\n" + "addr-gen-mode=stable-privacy\n" + "dns-search=\n" + "method=ignore\n" + "\n" + "[proxy]\n" + "", + ID, + UUID, + INTERFACE_NAME)); + break; + + case 2: + con = nmtst_create_minimal_connection(ID, UUID, "wireguard", &s_con); + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, INTERFACE_NAME, NULL); + nmtst_connection_normalize(con); + + s_wg = NM_SETTING_WIREGUARD(nm_connection_get_setting(con, NM_TYPE_SETTING_WIREGUARD)); + g_object_set(s_wg, + NM_SETTING_WIREGUARD_PRIVATE_KEY, + WG_PRIVATE_KEY, + NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS, + WG_PRIVATE_KEY_FLAGS, + NM_SETTING_WIREGUARD_LISTEN_PORT, + WG_LISTEN_PORT, + NM_SETTING_WIREGUARD_FWMARK, + WG_FWMARK, + NULL); + + wg_peers = _rndt_wg_peers_create(); + + for (i = 0; i < wg_peers->len; i++) + nm_setting_wireguard_append_peer(s_wg, wg_peers->pdata[i]); + + nm_clear_g_free(&tmp_str); + + g_ptr_array_add( + kf_data_arr, + g_strdup_printf( + "[connection]\n" + "id=%s\n" + "uuid=%s\n" + "type=wireguard\n" + "interface-name=%s\n" + "permissions=\n" + "\n" + "[wireguard]\n" + "%s" /* fwmark */ + "%s" /* listen-port */ + "%s" /* private-key-flags */ + "%s" /* private-key */ + "%s" /* [wireguard-peers*] */ + "\n" + "[ipv4]\n" + "dns-search=\n" + "method=disabled\n" + "\n" + "[ipv6]\n" + "addr-gen-mode=stable-privacy\n" + "dns-search=\n" + "method=ignore\n" + "\n" + "[proxy]\n" + "", + ID, + UUID, + INTERFACE_NAME, + ((WG_FWMARK != 0) ? nm_sprintf_bufa(100, "fwmark=%u\n", WG_FWMARK) : ""), + ((WG_LISTEN_PORT != 0) ? nm_sprintf_bufa(100, "listen-port=%u\n", WG_LISTEN_PORT) + : ""), + ((WG_PRIVATE_KEY_FLAGS != NM_SETTING_SECRET_FLAG_NONE) + ? nm_sprintf_bufa(100, "private-key-flags=%u\n", (guint) WG_PRIVATE_KEY_FLAGS) + : ""), + ((WG_PRIVATE_KEY && WG_PRIVATE_KEY_FLAGS == NM_SETTING_SECRET_FLAG_NONE) + ? nm_sprintf_bufa(100, "private-key=%s\n", WG_PRIVATE_KEY) + : ""), + _rndt_wg_peers_to_keyfile(wg_peers, TRUE, &tmp_str))); + + _rndt_wg_peers_assert_equal(s_wg, wg_peers, TRUE, TRUE, FALSE); + break; + + case 3: + con = nmtst_create_minimal_connection(ID, UUID, NM_SETTING_WIRED_SETTING_NAME, &s_con); + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, INTERFACE_NAME, NULL); + nmtst_connection_normalize(con); + + s_eth = NM_SETTING_WIRED(nm_connection_get_setting(con, NM_TYPE_SETTING_WIRED)); + g_assert(NM_IS_SETTING_WIRED(s_eth)); + + g_object_set(s_eth, NM_SETTING_WIRED_MTU, ETH_MTU, NULL); + + s_ip.s_4 = NM_SETTING_IP_CONFIG(nm_connection_get_setting(con, NM_TYPE_SETTING_IP4_CONFIG)); + g_assert(NM_IS_SETTING_IP4_CONFIG(s_ip.s_4)); + + s_ip.s_6 = NM_SETTING_IP_CONFIG(nm_connection_get_setting(con, NM_TYPE_SETTING_IP6_CONFIG)); + g_assert(NM_IS_SETTING_IP6_CONFIG(s_ip.s_6)); + + for (is_ipv4 = 0; is_ipv4 < 2; is_ipv4++) { + g_assert(NM_IS_SETTING_IP_CONFIG(s_ip.s_x[is_ipv4])); + for (i = 0; i < 3; i++) { + char addrstr[NM_UTILS_INET_ADDRSTRLEN]; + + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rr = NULL; + + rr = nm_ip_routing_rule_new(is_ipv4 ? AF_INET : AF_INET6); + nm_ip_routing_rule_set_priority(rr, i + 1); + if (i > 0) { + if (is_ipv4) + nm_sprintf_buf(addrstr, "192.168.%u.0", i); + else + nm_sprintf_buf(addrstr, "1:2:3:%x::", 10 + i); + nm_ip_routing_rule_set_from(rr, addrstr, is_ipv4 ? 24 + i : 64 + i); + } + nm_ip_routing_rule_set_table(rr, 1000 + i); + + success = nm_ip_routing_rule_validate(rr, &error); + nmtst_assert_success(success, error); + + nm_setting_ip_config_add_routing_rule(s_ip.s_x[is_ipv4], rr); + } + } + + g_ptr_array_add( + kf_data_arr, + g_strdup_printf("[connection]\n" + "id=%s\n" + "uuid=%s\n" + "type=ethernet\n" + "interface-name=%s\n" + "permissions=\n" + "\n" + "[ethernet]\n" + "mac-address-blacklist=\n" + "%s" /* mtu */ + "\n" + "[ipv4]\n" + "dns-search=\n" + "method=auto\n" + "routing-rule1=priority 1 from 0.0.0.0/0 table 1000\n" + "routing-rule2=priority 2 from 192.168.1.0/25 table 1001\n" + "routing-rule3=priority 3 from 192.168.2.0/26 table 1002\n" + "\n" + "[ipv6]\n" + "addr-gen-mode=stable-privacy\n" + "dns-search=\n" + "method=auto\n" + "routing-rule1=priority 1 from ::/0 table 1000\n" + "routing-rule2=priority 2 from 1:2:3:b::/65 table 1001\n" + "routing-rule3=priority 3 from 1:2:3:c::/66 table 1002\n" + "\n" + "[proxy]\n" + "", + ID, + UUID, + INTERFACE_NAME, + (ETH_MTU != 0) ? nm_sprintf_bufa(100, "mtu=%u\n", ETH_MTU) : "")); + + break; + + default: + g_assert_not_reached(); + } + + /* the first kf_data_arr entry is special: it is the exact result of what we expect + * when converting @con to keyfile. Write @con to keyfile and compare the expected result + * literally. */ + { + nm_auto_unref_keyfile GKeyFile *kf = NULL; + + kf = nm_keyfile_write(con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + nmtst_assert_success(kf, error); + + /* the first kf_data_arr entry is special: it must be what the writer would + * produce again. */ + nmtst_keyfile_assert_data(kf, kf_data_arr->pdata[0], -1); + } + + /* check that reading any of kf_data_arr yields the same result that we expect. */ + for (kf_data_idx = 0; kf_data_idx < kf_data_arr->len; kf_data_idx++) { + gs_unref_object NMConnection *con2 = NULL; + NMSettingWireGuard * s_wg2 = NULL; + NMSettingWired * s_eth2 = NULL; + + con2 = nmtst_create_connection_from_keyfile(kf_data_arr->pdata[kf_data_idx], + "/no/where/file.nmconnection"); + + switch (MODE) { + case 0: + s_eth2 = NM_SETTING_WIRED(nm_connection_get_setting(con2, NM_TYPE_SETTING_WIRED)); + g_assert(NM_IS_SETTING_WIRED(s_eth2)); + + if (ETH_MTU > (guint32) G_MAXINT && kf_data_idx == 1) { + /* older versions wrote values > 2^21 as signed integers, but the reader would + * always reject such negative values for G_TYPE_UINT. + * + * The test case kf_data_idx #1 still writes the values in the old style. + * The behavior was fixed, but such values are still rejected as invalid. + * + * Patch the setting so that the comparison below succeeds are usual. */ + g_assert_cmpint(nm_setting_wired_get_mtu(s_eth2), ==, 0); + g_object_set(s_eth2, NM_SETTING_WIRED_MTU, ETH_MTU, NULL); + } + + g_assert_cmpint(nm_setting_wired_get_mtu(s_eth), ==, ETH_MTU); + g_assert_cmpint(nm_setting_wired_get_mtu(s_eth2), ==, ETH_MTU); + + g_assert_cmpint(nm_setting_wired_get_num_s390_options(s_eth2), + ==, + nm_setting_wired_get_num_s390_options(s_eth)); + + break; + + case 1: + s_wg2 = + NM_SETTING_WIREGUARD(nm_connection_get_setting(con2, NM_TYPE_SETTING_WIREGUARD)); + g_assert(NM_IS_SETTING_WIREGUARD(s_wg2)); + + g_assert_cmpstr(nm_setting_wireguard_get_private_key(s_wg), ==, NULL); + g_assert_cmpstr(nm_setting_wireguard_get_private_key(s_wg2), ==, NULL); + break; + + case 2: + s_wg2 = + NM_SETTING_WIREGUARD(nm_connection_get_setting(con2, NM_TYPE_SETTING_WIREGUARD)); + g_assert(NM_IS_SETTING_WIREGUARD(s_wg2)); + + /* the private key was lost due to the secret-flags. Patch it. */ + if (WG_PRIVATE_KEY_FLAGS != NM_SETTING_SECRET_FLAG_NONE) { + g_assert_cmpstr(nm_setting_wireguard_get_private_key(s_wg2), ==, NULL); + g_object_set(s_wg2, NM_SETTING_WIREGUARD_PRIVATE_KEY, WG_PRIVATE_KEY, NULL); + } + + g_assert_cmpstr(nm_setting_wireguard_get_private_key(s_wg), ==, WG_PRIVATE_KEY); + g_assert_cmpstr(nm_setting_wireguard_get_private_key(s_wg2), ==, WG_PRIVATE_KEY); + + _rndt_wg_peers_assert_equal(s_wg2, wg_peers, TRUE, FALSE, FALSE); + _rndt_wg_peers_fix_secrets(s_wg2, wg_peers); + _rndt_wg_peers_assert_equal(s_wg2, wg_peers, TRUE, TRUE, FALSE); + break; + } + + nmtst_assert_connection_equals(con, nmtst_get_rand_bool(), con2, nmtst_get_rand_bool()); + } + + for (dbus_serialization_flags_idx = 0; + dbus_serialization_flags_idx < G_N_ELEMENTS(dbus_serialization_flags); + dbus_serialization_flags_idx++) { + NMConnectionSerializationFlags flag = + dbus_serialization_flags[dbus_serialization_flags_idx]; + gs_unref_variant GVariant *con_var = NULL; + gs_unref_object NMConnection *con2 = NULL; + NMSettingWireGuard * s_wg2 = NULL; + + con_var = nm_connection_to_dbus(con, flag); + g_assert(g_variant_is_of_type(con_var, NM_VARIANT_TYPE_CONNECTION)); + g_assert(g_variant_is_floating(con_var)); + g_variant_ref_sink(con_var); + + if (flag == NM_CONNECTION_SERIALIZE_ALL) { + con2 = _connection_new_from_dbus_strict(con_var, TRUE); + nmtst_assert_connection_equals(con, nmtst_get_rand_bool(), con2, nmtst_get_rand_bool()); + + { + nm_auto_unref_keyfile GKeyFile *kf = NULL; + + kf = nm_keyfile_write(con2, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + nmtst_assert_success(kf, error); + nmtst_keyfile_assert_data(kf, kf_data_arr->pdata[0], -1); + } + } + + switch (MODE) { + case 2: + if (flag == NM_CONNECTION_SERIALIZE_ALL) { + s_wg2 = NM_SETTING_WIREGUARD( + nm_connection_get_setting(con2, NM_TYPE_SETTING_WIREGUARD)); + + if (flag == NM_CONNECTION_SERIALIZE_ALL) + _rndt_wg_peers_assert_equal(s_wg2, wg_peers, TRUE, TRUE, FALSE); + else if (flag == NM_CONNECTION_SERIALIZE_NO_SECRETS) + _rndt_wg_peers_assert_equal(s_wg2, wg_peers, FALSE, FALSE, TRUE); + else + g_assert_not_reached(); + } + break; + } + } +} + +/*****************************************************************************/ + +static NMIPRoutingRule * +_rr_from_str_get_impl(const char *str, const char *const *aliases) +{ + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rr = NULL; + gs_free_error GError * error = NULL; + gboolean vbool; + int addr_family; + int i; + NMIPRoutingRuleAsStringFlags to_string_flags; + + rr = nm_ip_routing_rule_from_string(str, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE, + NULL, + &error); + nmtst_assert_success(rr, error); + + addr_family = nm_ip_routing_rule_get_addr_family(rr); + g_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + + if (addr_family == AF_INET) + to_string_flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET; + else + to_string_flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6; + + for (i = 0; TRUE; i++) { + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rr2 = NULL; + gs_free char * str1 = NULL; + gs_unref_variant GVariant *variant1 = NULL; + const char * cstr1; + + switch (i) { + case 0: + rr2 = nm_ip_routing_rule_ref(rr); + break; + + case 1: + rr2 = nm_ip_routing_rule_from_string( + str, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (nmtst_get_rand_bool() ? to_string_flags + : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE), + NULL, + &error); + nmtst_assert_success(rr, error); + break; + + case 2: + str1 = nm_ip_routing_rule_to_string( + rr, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (nmtst_get_rand_bool() ? to_string_flags + : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE), + NULL, + &error); + nmtst_assert_success(str1 && str1[0], error); + + g_assert_cmpstr(str, ==, str1); + + rr2 = nm_ip_routing_rule_from_string( + str1, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (nmtst_get_rand_bool() ? to_string_flags + : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE), + NULL, + &error); + nmtst_assert_success(rr, error); + break; + + case 3: + variant1 = nm_ip_routing_rule_to_dbus(rr); + g_assert(variant1); + g_assert(g_variant_is_floating(variant1)); + g_assert(g_variant_is_of_type(variant1, G_VARIANT_TYPE_VARDICT)); + + rr2 = nm_ip_routing_rule_from_dbus(variant1, TRUE, &error); + nmtst_assert_success(rr, error); + break; + + default: + if (!aliases || !aliases[0]) + goto done; + cstr1 = (aliases++)[0]; + rr2 = nm_ip_routing_rule_from_string( + cstr1, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (nmtst_get_rand_bool() ? to_string_flags + : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE), + NULL, + &error); + nmtst_assert_success(rr, error); + break; + } + + g_assert(rr2); + vbool = nm_ip_routing_rule_validate(rr, &error); + nmtst_assert_success(vbool, error); + vbool = nm_ip_routing_rule_validate(rr2, &error); + nmtst_assert_success(vbool, error); + + g_assert_cmpint(nm_ip_routing_rule_cmp(rr, rr2), ==, 0); + g_assert_cmpint(nm_ip_routing_rule_cmp(rr2, rr), ==, 0); + } + +done: + return g_steal_pointer(&rr); +} +#define _rr_from_str_get(a, ...) _rr_from_str_get_impl(a, &(NM_MAKE_STRV(NULL, ##__VA_ARGS__))[1]) + +#define _rr_from_str(...) \ + G_STMT_START \ + { \ + nm_auto_unref_ip_routing_rule NMIPRoutingRule *_rr = NULL; \ + \ + _rr = _rr_from_str_get(__VA_ARGS__); \ + g_assert(_rr); \ + } \ + G_STMT_END + +static void +test_routing_rule(gconstpointer test_data) +{ + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rr1 = NULL; + gboolean success; + char ifname_buf[16]; + + _rr_from_str("priority 5 from 0.0.0.0 table 1", " from 0.0.0.0 priority 5 lookup 1 "); + _rr_from_str("priority 5 from 0.0.0.0/0 table 4"); + _rr_from_str("priority 5 to 0.0.0.0 table 6"); + _rr_from_str("priority 5 to 0.0.0.0 table 254", "priority 5 to 0.0.0.0/32"); + _rr_from_str("priority 5 from 1.2.3.4 table 15", + "priority 5 from 1.2.3.4/32 table 0xF ", + "priority 5 from 1.2.3.4/32 to 0.0.0.0/0 lookup 15 "); + _rr_from_str("priority 5 from 1.2.3.4 to 0.0.0.0 table 8"); + _rr_from_str("priority 5 to a:b:c:: tos 0x16 table 25", + "priority 5 to a:b:c::/128 table 0x19 tos 16", + "priority 5 to a:b:c::/128 lookup 0x19 dsfield 16", + "priority 5 to a:b:c::/128 lookup 0x19 dsfield 16 fwmark 0/0x00", + "priority 5 to a:b:c:: from all lookup 0x19 dsfield 16 fwmark 0x0/0"); + _rr_from_str("priority 5 from :: fwmark 0 table 25", + "priority 5 from ::/128 to all table 0x19 fwmark 0/0xFFFFFFFF", + "priority 5 from :: to ::/0 table 0x19 fwmark 0x00/4294967295"); + _rr_from_str("priority 5 from :: iif aab table 25"); + _rr_from_str("priority 5 from :: iif aab oif er table 25", + "priority 5 from :: table 0x19 dev aab oif er"); + _rr_from_str("priority 5 from :: iif a\\\\303b table 25"); + _rr_from_str("priority 5 to 0.0.0.0 sport 10 table 6", + "priority 5 to 0.0.0.0 sport 10-10 table 6"); + _rr_from_str("priority 5 not to 0.0.0.0 dport 10-133 table 6", + "not priority 5 to 0.0.0.0 dport 10-133 table 6", + "not priority 5 not to 0.0.0.0 dport 10-133 table 6", + "priority 5 to 0.0.0.0 not dport 10-133 not table 6", + "priority 5 to 0.0.0.0 not dport 10-\\ 133 not table 6"); + _rr_from_str("priority 5 to 0.0.0.0 ipproto 10 sport 10 table 6"); + + rr1 = _rr_from_str_get("priority 5 from :: iif aab table 25"); + g_assert_cmpstr(nm_ip_routing_rule_get_iifname(rr1), ==, "aab"); + success = nm_ip_routing_rule_get_xifname_bin(rr1, FALSE, ifname_buf); + g_assert(!success); + success = nm_ip_routing_rule_get_xifname_bin(rr1, TRUE, ifname_buf); + g_assert_cmpstr(ifname_buf, ==, "aab"); + g_assert(success); + nm_clear_pointer(&rr1, nm_ip_routing_rule_unref); + + rr1 = _rr_from_str_get("priority 5 from :: iif a\\\\303\\\\261xb table 254"); + g_assert_cmpstr(nm_ip_routing_rule_get_iifname(rr1), ==, "a\\303\\261xb"); + success = nm_ip_routing_rule_get_xifname_bin(rr1, FALSE, ifname_buf); + g_assert(!success); + success = nm_ip_routing_rule_get_xifname_bin(rr1, TRUE, ifname_buf); + g_assert_cmpstr(ifname_buf, ==, "a\303\261xb"); + g_assert(success); + nm_clear_pointer(&rr1, nm_ip_routing_rule_unref); + + rr1 = _rr_from_str_get("priority 5 from :: oif \\\\101=\\\\303\\\\261xb table 7"); + g_assert_cmpstr(nm_ip_routing_rule_get_oifname(rr1), ==, "\\101=\\303\\261xb"); + success = nm_ip_routing_rule_get_xifname_bin(rr1, FALSE, ifname_buf); + g_assert_cmpstr(ifname_buf, ==, "A=\303\261xb"); + g_assert(success); + success = nm_ip_routing_rule_get_xifname_bin(rr1, TRUE, ifname_buf); + g_assert(!success); + nm_clear_pointer(&rr1, nm_ip_routing_rule_unref); + + rr1 = _rr_from_str_get("priority 5 to 0.0.0.0 tos 0x10 table 7"); + g_assert_cmpstr(NULL, ==, nm_ip_routing_rule_get_from(rr1)); + g_assert(!nm_ip_routing_rule_get_from_bin(rr1)); + g_assert_cmpint(0, ==, nm_ip_routing_rule_get_from_len(rr1)); + g_assert_cmpstr("0.0.0.0", ==, nm_ip_routing_rule_get_to(rr1)); + g_assert(nm_ip_addr_is_null(AF_INET, nm_ip_routing_rule_get_to_bin(rr1))); + g_assert_cmpint(32, ==, nm_ip_routing_rule_get_to_len(rr1)); + g_assert_cmpint(7, ==, nm_ip_routing_rule_get_table(rr1)); + g_assert_cmpint(0x10, ==, nm_ip_routing_rule_get_tos(rr1)); + nm_clear_pointer(&rr1, nm_ip_routing_rule_unref); + + rr1 = _rr_from_str_get("priority 5 from :: iif a\\\\303\\\\261,x;b table 254", + "priority 5 from :: iif a\\\\303\\\\261,x;b table 254"); + g_assert_cmpstr(nm_ip_routing_rule_get_iifname(rr1), ==, "a\\303\\261,x;b"); + success = nm_ip_routing_rule_get_xifname_bin(rr1, FALSE, ifname_buf); + g_assert(!success); + success = nm_ip_routing_rule_get_xifname_bin(rr1, TRUE, ifname_buf); + g_assert_cmpstr(ifname_buf, ==, "a\303\261,x;b"); + g_assert(success); + nm_clear_pointer(&rr1, nm_ip_routing_rule_unref); +} + +/*****************************************************************************/ + +static void +test_parse_tc_handle(void) +{ +#define _parse_tc_handle(str, exp) \ + G_STMT_START \ + { \ + gs_free_error GError *_error = NULL; \ + GError ** _perror = nmtst_get_rand_bool() ? &_error : NULL; \ + guint32 _v; \ + const guint32 _v_exp = (exp); \ + \ + _v = _nm_utils_parse_tc_handle("" str "", _perror); \ + \ + if (_v != _v_exp) \ + g_error("%s:%d: \"%s\" gave %08x but %08x expected.", \ + __FILE__, \ + __LINE__, \ + "" str "", \ + _v, \ + _v_exp); \ + \ + if (_v == TC_H_UNSPEC) \ + g_assert(!_perror || *_perror); \ + else \ + g_assert(!_perror || !*_perror); \ + } \ + G_STMT_END + +#define _parse_tc_handle_inval(str) _parse_tc_handle(str, TC_H_UNSPEC) +#define _parse_tc_handle_valid(str, maj, min) \ + _parse_tc_handle(str, TC_H_MAKE(((guint32)(maj)) << 16, ((guint16)(min)))) + + _parse_tc_handle_inval(""); + _parse_tc_handle_inval(" "); + _parse_tc_handle_inval(" \n"); + _parse_tc_handle_valid("1", 1, 0); + _parse_tc_handle_valid(" 1 ", 1, 0); + _parse_tc_handle_valid("1:", 1, 0); + _parse_tc_handle_valid("1: ", 1, 0); + _parse_tc_handle_valid("1:0", 1, 0); + _parse_tc_handle_valid("1 :0", 1, 0); + _parse_tc_handle_valid("1 \t\n\f\r:0", 1, 0); + _parse_tc_handle_inval("1 \t\n\f\r\v:0"); + _parse_tc_handle_valid(" 1 : 0 ", 1, 0); + _parse_tc_handle_inval(" \t\v\n1: 0"); + _parse_tc_handle_valid("1:2", 1, 2); + _parse_tc_handle_valid("01:02", 1, 2); + _parse_tc_handle_inval("0x01:0x02"); + _parse_tc_handle_valid(" 01: 02", 1, 2); + _parse_tc_handle_valid("019: 020", 0x19, 0x20); + _parse_tc_handle_valid("FFFF: 020", 0xFFFF, 0x20); + _parse_tc_handle_valid("FfFF: ffff", 0xFFFF, 0xFFFF); + _parse_tc_handle_valid("FFFF", 0xFFFF, 0); + _parse_tc_handle_inval("0xFFFF"); + _parse_tc_handle_inval("10000"); + _parse_tc_handle_valid("\t\n\f\r FFFF", 0xFFFF, 0); + _parse_tc_handle_inval("\t\n\f\r \vFFFF"); +} + +/*****************************************************************************/ + +static void +test_empty_setting(void) +{ + gs_unref_object NMConnection *con = NULL; + gs_unref_object NMConnection *con2 = NULL; + NMSettingBluetooth * s_bt; + NMSettingGsm * s_gsm; + nm_auto_unref_keyfile GKeyFile *kf = NULL; + gs_free_error GError *error = NULL; + + con = nmtst_create_minimal_connection("bt-empty-gsm", + "dca3192a-f2dc-48eb-b806-d0ff788f122c", + NM_SETTING_BLUETOOTH_SETTING_NAME, + NULL); + + s_bt = _nm_connection_get_setting(con, NM_TYPE_SETTING_BLUETOOTH); + g_object_set(s_bt, + NM_SETTING_BLUETOOTH_TYPE, + "dun", + NM_SETTING_BLUETOOTH_BDADDR, + "aa:bb:cc:dd:ee:ff", + NULL); + + s_gsm = NM_SETTING_GSM(nm_setting_gsm_new()); + nm_connection_add_setting(con, NM_SETTING(s_gsm)); + + nmtst_connection_normalize(con); + + nmtst_assert_connection_verifies_without_normalization(con); + + kf = nm_keyfile_write(con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + nmtst_assert_success(kf, error); + + g_assert(g_key_file_has_group(kf, "gsm")); + g_assert_cmpint(nmtst_keyfile_get_num_keys(kf, "gsm"), ==, 0); + + con2 = nm_keyfile_read(kf, + "/ignored/current/working/directory/for/loading/relative/paths", + NM_KEYFILE_HANDLER_FLAGS_NONE, + NULL, + NULL, + &error); + nmtst_assert_success(con2, error); + + g_assert(nm_connection_get_setting(con2, NM_TYPE_SETTING_GSM)); + + nmtst_assert_connection_verifies_without_normalization(con2); +} + +/*****************************************************************************/ + +static guint +_PROP_IDX_PACK(NMMetaSettingType meta_type, guint idx) +{ + return (((guint) meta_type) & 0xFFu) | (idx << 8); +} + +static const char * +_PROP_IDX_OWNER(GHashTable *h_property_types, const NMSettInfoPropertType *property_type) +{ + const NMSettInfoSetting *sett_info_settings = nmtst_sett_info_settings(); + const NMSettInfoSetting *sis; + const NMMetaSettingInfo *msi; + GArray * arr; + guint idx; + NMMetaSettingType meta_type; + guint prop_idx; + char sbuf[300]; + + g_assert(h_property_types); + g_assert(property_type); + + arr = g_hash_table_lookup(h_property_types, property_type); + + g_assert(arr); + g_assert(arr->len > 0); + + idx = g_array_index(arr, guint, 0); + + meta_type = (idx & 0xFFu); + prop_idx = idx >> 8; + + g_assert(meta_type < _NM_META_SETTING_TYPE_NUM); + + sis = &sett_info_settings[meta_type]; + msi = &nm_meta_setting_infos[meta_type]; + + g_assert(prop_idx < sis->property_infos_len); + + nm_sprintf_buf(sbuf, "%s.%s", msi->setting_name, sis->property_infos[prop_idx].name); + + return g_intern_string(sbuf); +} + +static void +test_setting_metadata(void) +{ + const NMSettInfoSetting *sett_info_settings = nmtst_sett_info_settings(); + NMMetaSettingType meta_type; + gs_unref_hashtable GHashTable *h_property_types = NULL; + + G_STATIC_ASSERT(_NM_META_SETTING_TYPE_NUM == NM_META_SETTING_TYPE_UNKNOWN); + + h_property_types = + g_hash_table_new_full(nm_direct_hash, NULL, NULL, (GDestroyNotify) g_array_unref); + + for (meta_type = 0; meta_type < _NM_META_SETTING_TYPE_NUM; meta_type++) { + const NMMetaSettingInfo *msi = &nm_meta_setting_infos[meta_type]; + nm_auto_unref_gtypeclass NMSettingClass *klass = NULL; + GType gtype; + + g_assert(msi->setting_name); + g_assert(msi->get_setting_gtype); + g_assert(msi->meta_type == meta_type); + g_assert(msi->setting_priority >= NM_SETTING_PRIORITY_CONNECTION); + g_assert(msi->setting_priority <= NM_SETTING_PRIORITY_USER); + + if (meta_type > 0) + g_assert_cmpint( + strcmp(nm_meta_setting_infos[meta_type - 1].setting_name, msi->setting_name), + <, + 0); + + gtype = msi->get_setting_gtype(); + + g_assert(g_type_is_a(gtype, NM_TYPE_SETTING)); + g_assert(gtype != NM_TYPE_SETTING); + + klass = g_type_class_ref(gtype); + g_assert(klass); + g_assert(NM_IS_SETTING_CLASS(klass)); + + g_assert(msi == klass->setting_info); + } + + g_assert(sett_info_settings); + + for (meta_type = 0; meta_type < _NM_META_SETTING_TYPE_NUM; meta_type++) { + const NMSettInfoSetting *sis = &sett_info_settings[meta_type]; + const NMMetaSettingInfo *msi = &nm_meta_setting_infos[meta_type]; + gs_unref_hashtable GHashTable *h_properties = NULL; + GType gtype; + gs_unref_object NMSetting *setting = NULL; + guint prop_idx; + gs_free GParamSpec **property_specs = NULL; + guint n_property_specs; + + g_assert(sis); + + g_assert(NM_IS_SETTING_CLASS(sis->setting_class)); + + gtype = msi->get_setting_gtype(); + + g_assert(G_TYPE_FROM_CLASS(sis->setting_class) == gtype); + + setting = g_object_new(gtype, NULL); + + g_assert(NM_IS_SETTING(setting)); + + g_assert_cmpint(sis->property_infos_len, >, 0); + g_assert(sis->property_infos); + + h_properties = g_hash_table_new(nm_str_hash, g_str_equal); + + for (prop_idx = 0; prop_idx < sis->property_infos_len; prop_idx++) { + const NMSettInfoProperty *sip = &sis->property_infos[prop_idx]; + GArray * property_types_data; + guint prop_idx_val; + + g_assert(sip->name); + + if (prop_idx > 0) + g_assert_cmpint(strcmp(sis->property_infos[prop_idx - 1].name, sip->name), <, 0); + + g_assert(sip->property_type); + g_assert(sip->property_type->dbus_type); + g_assert(g_variant_type_string_is_valid((const char *) sip->property_type->dbus_type)); + + g_assert(!sip->property_type->to_dbus_fcn || !sip->property_type->gprop_to_dbus_fcn); + g_assert(!sip->property_type->from_dbus_fcn + || !sip->property_type->gprop_from_dbus_fcn); + + if (!g_hash_table_insert(h_properties, (char *) sip->name, sip->param_spec)) + g_assert_not_reached(); + + property_types_data = g_hash_table_lookup(h_property_types, sip->property_type); + if (!property_types_data) { + property_types_data = g_array_new(FALSE, FALSE, sizeof(guint)); + if (!g_hash_table_insert(h_property_types, + (gpointer) sip->property_type, + property_types_data)) + g_assert_not_reached(); + } + prop_idx_val = _PROP_IDX_PACK(meta_type, prop_idx); + g_array_append_val(property_types_data, prop_idx_val); + + if (sip->param_spec) { + nm_auto_unset_gvalue GValue val = G_VALUE_INIT; + + g_assert_cmpstr(sip->name, ==, sip->param_spec->name); + + g_value_init(&val, sip->param_spec->value_type); + g_object_get_property(G_OBJECT(setting), sip->name, &val); + + if (sip->param_spec->value_type == G_TYPE_STRING) { + const char *default_value; + + default_value = ((const GParamSpecString *) sip->param_spec)->default_value; + if (default_value) { + /* having a string property with a default != NULL is really ugly. They + * should be best avoided... */ + if (meta_type == NM_META_SETTING_TYPE_DCB + && nm_streq(sip->name, NM_SETTING_DCB_APP_FCOE_MODE)) { + /* Whitelist the properties that have a non-NULL default value. */ + g_assert_cmpstr(default_value, ==, NM_SETTING_DCB_FCOE_MODE_FABRIC); + } else + g_assert_not_reached(); + } + + if (nm_streq(sip->name, NM_SETTING_NAME)) + g_assert_cmpstr(g_value_get_string(&val), ==, msi->setting_name); + else + g_assert_cmpstr(g_value_get_string(&val), ==, default_value); + } + + if (NM_FLAGS_HAS(sip->param_spec->flags, NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS)) + g_assert(sip->property_type->to_dbus_fcn); + } + } + + /* check that all GObject based properties are tracked by the settings. */ + property_specs = + g_object_class_list_properties(G_OBJECT_CLASS(sis->setting_class), &n_property_specs); + g_assert(property_specs); + g_assert_cmpint(n_property_specs, >, 0); + for (prop_idx = 0; prop_idx < n_property_specs; prop_idx++) { + const GParamSpec *pip = property_specs[prop_idx]; + + g_assert(g_hash_table_lookup(h_properties, pip->name) == pip); + } + + /* check that property_infos_sorted is as expected. */ + if (sis->property_infos_sorted) { + gs_unref_hashtable GHashTable *h = g_hash_table_new(nm_direct_hash, NULL); + + /* property_infos_sorted is only implemented for [connection] type */ + g_assert_cmpint(meta_type, ==, NM_META_SETTING_TYPE_CONNECTION); + + /* ensure that there are no duplicates, and that all properties are also + * tracked by sis->property_infos. */ + for (prop_idx = 0; prop_idx < sis->property_infos_len; prop_idx++) { + const NMSettInfoProperty *sip = sis->property_infos_sorted[prop_idx]; + + if (!g_hash_table_add(h, (gpointer) sip)) + g_assert_not_reached(); + } + for (prop_idx = 0; prop_idx < sis->property_infos_len; prop_idx++) { + const NMSettInfoProperty *sip = &sis->property_infos[prop_idx]; + + g_assert(g_hash_table_contains(h, sip)); + } + } else + g_assert_cmpint(meta_type, !=, NM_META_SETTING_TYPE_CONNECTION); + + /* consistency check for gendata-info. */ + if (sis->detail.gendata_info) { + g_assert_cmpint(meta_type, ==, NM_META_SETTING_TYPE_ETHTOOL); + g_assert(sis->detail.gendata_info->get_variant_type); + + /* the gendata info based setting has only one regular property: the "name". */ + g_assert_cmpint(sis->property_infos_len, ==, 1); + g_assert_cmpstr(sis->property_infos[0].name, ==, NM_SETTING_NAME); + } else + g_assert_cmpint(meta_type, !=, NM_META_SETTING_TYPE_ETHTOOL); + } + + { + gs_free NMSettInfoPropertType **a_property_types = NULL; + guint a_property_types_len; + guint prop_idx; + guint prop_idx_2; + + a_property_types = + (NMSettInfoPropertType **) g_hash_table_get_keys_as_array(h_property_types, + &a_property_types_len); + + for (prop_idx = 0; prop_idx < a_property_types_len; prop_idx++) { + const NMSettInfoPropertType *pt = a_property_types[prop_idx]; + + for (prop_idx_2 = prop_idx + 1; prop_idx_2 < a_property_types_len; prop_idx_2++) { + const NMSettInfoPropertType *pt_2 = a_property_types[prop_idx_2]; + + if (!g_variant_type_equal(pt->dbus_type, pt_2->dbus_type) + || pt->to_dbus_fcn != pt_2->to_dbus_fcn + || pt->from_dbus_fcn != pt_2->from_dbus_fcn + || pt->missing_from_dbus_fcn != pt_2->missing_from_dbus_fcn + || pt->gprop_to_dbus_fcn != pt_2->gprop_to_dbus_fcn + || pt->gprop_from_dbus_fcn != pt_2->gprop_from_dbus_fcn) + continue; + + if ((pt == &nm_sett_info_propert_type_plain_i + && pt_2 == &nm_sett_info_propert_type_deprecated_ignore_i) + || (pt_2 == &nm_sett_info_propert_type_plain_i + && pt == &nm_sett_info_propert_type_deprecated_ignore_i) + || (pt == &nm_sett_info_propert_type_plain_u + && pt_2 == &nm_sett_info_propert_type_deprecated_ignore_u) + || (pt_2 == &nm_sett_info_propert_type_plain_u + && pt == &nm_sett_info_propert_type_deprecated_ignore_u)) { + /* These are known to be duplicated. This is the case for + * "gsm.network-type" and plain properties like "802-11-wireless-security.fils" ("i" D-Bus type) + * "gsm.allowed-bands" and plain properties like "802-11-olpc-mesh.channel" ("u" D-Bus type) + * While the content/behaviour of the property types are identical, their purpose + * is different. So allow them. + */ + continue; + } + + /* the property-types with same content should all be shared. Here we have two that + * are the same content, but different instances. Bug. */ + g_error("The identical property type for D-Bus type \"%s\" is used by: %s and %s", + (const char *) pt->dbus_type, + _PROP_IDX_OWNER(h_property_types, pt), + _PROP_IDX_OWNER(h_property_types, pt_2)); + } + } + } +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_data_func("/libnm/setting-8021x/key-and-cert", + "test_key_and_cert.pem, test", + test_8021x); + g_test_add_data_func("/libnm/setting-8021x/key-only", "test-key-only.pem, test", test_8021x); + g_test_add_data_func("/libnm/setting-8021x/pkcs8-enc-key", + "pkcs8-enc-key.pem, 1234567890", + test_8021x); + g_test_add_data_func("/libnm/setting-8021x/pkcs12", "test-cert.p12, test", test_8021x); + + g_test_add_func("/libnm/settings/bond/verify", test_bond_verify); + g_test_add_func("/libnm/settings/bond/compare", test_bond_compare); + g_test_add_func("/libnm/settings/bond/normalize", test_bond_normalize); + + g_test_add_func("/libnm/settings/dcb/flags-valid", test_dcb_flags_valid); + g_test_add_func("/libnm/settings/dcb/flags-invalid", test_dcb_flags_invalid); + g_test_add_func("/libnm/settings/dcb/app-priorities", test_dcb_app_priorities); + g_test_add_func("/libnm/settings/dcb/priorities", test_dcb_priorities_valid); + g_test_add_func("/libnm/settings/dcb/bandwidth-sums", test_dcb_bandwidth_sums); + + g_test_add_func("/libnm/settings/ethtool/features", test_ethtool_features); + g_test_add_func("/libnm/settings/ethtool/coalesce", test_ethtool_coalesce); + g_test_add_func("/libnm/settings/ethtool/ring", test_ethtool_ring); + + g_test_add_func("/libnm/settings/sriov/vf", test_sriov_vf); + g_test_add_func("/libnm/settings/sriov/vf-dup", test_sriov_vf_dup); + g_test_add_func("/libnm/settings/sriov/vf-vlan", test_sriov_vf_vlan); + g_test_add_func("/libnm/settings/sriov/setting", test_sriov_setting); + g_test_add_func("/libnm/settings/sriov/vlans", test_sriov_parse_vlans); + + g_test_add_func("/libnm/settings/tc_config/qdisc", test_tc_config_qdisc); + g_test_add_func("/libnm/settings/tc_config/action", test_tc_config_action); + g_test_add_func("/libnm/settings/tc_config/tfilter/matchall_sdata", + test_tc_config_tfilter_matchall_sdata); + g_test_add_func("/libnm/settings/tc_config/tfilter/matchall_mirred", + test_tc_config_tfilter_matchall_mirred); + g_test_add_func("/libnm/settings/tc_config/setting/valid", test_tc_config_setting_valid); + g_test_add_func("/libnm/settings/tc_config/setting/duplicates", + test_tc_config_setting_duplicates); + g_test_add_func("/libnm/settings/tc_config/dbus", test_tc_config_dbus); + + g_test_add_func("/libnm/settings/bridge/vlans", test_bridge_vlans); + g_test_add_func("/libnm/settings/bridge/verify", test_bridge_verify); + + g_test_add_func("/libnm/test_nm_json", test_nm_json); + g_test_add_func("/libnm/settings/team/sync_runner_from_config_roundrobin", + test_runner_roundrobin_sync_from_config); + g_test_add_func("/libnm/settings/team/sync_runner_from_config_broadcast", + test_runner_broadcast_sync_from_config); + g_test_add_func("/libnm/settings/team/sync_runner_from_config_random", + test_runner_random_sync_from_config); + g_test_add_func("/libnm/settings/team/sync_runner_from_config_activebackup", + test_runner_activebackup_sync_from_config); + g_test_add_func("/libnm/settings/team/sync_runner_from_config_loadbalance", + test_runner_loadbalance_sync_from_config); + g_test_add_func("/libnm/settings/team/sync_runner_from_config_lacp", + test_runner_lacp_sync_from_config); + g_test_add_func("/libnm/settings/team/sync_watcher_from_config_ethtool", + test_watcher_ethtool_sync_from_config); + g_test_add_func("/libnm/settings/team/sync_watcher_from_config_nsna_ping", + test_watcher_nsna_ping_sync_from_config); + g_test_add_func("/libnm/settings/team/sync_watcher_from_config_arp_ping", + test_watcher_arp_ping_sync_from_config); + g_test_add_func("/libnm/settings/team/sync_watcher_from_config_all", + test_multiple_watchers_sync_from_config); + + g_test_add_func("/libnm/settings/team-port/sync_from_config_defaults", test_team_port_default); + g_test_add_func("/libnm/settings/team-port/sync_from_config_queue_id", test_team_port_queue_id); + g_test_add_func("/libnm/settings/team-port/sync_from_config_prio", test_team_port_prio); + g_test_add_func("/libnm/settings/team-port/sync_from_config_sticky", test_team_port_sticky); + g_test_add_func("/libnm/settings/team-port/sync_from_config_lacp_prio", + test_team_port_lacp_prio); + g_test_add_func("/libnm/settings/team-port/sync_from_config_lacp_key", test_team_port_lacp_key); + g_test_add_func("/libnm/settings/team-port/sycn_from_config_full", test_team_port_full_config); + + g_test_add_data_func("/libnm/settings/roundtrip-conversion/general/0", + GINT_TO_POINTER(0), + test_roundtrip_conversion); + g_test_add_data_func("/libnm/settings/roundtrip-conversion/wireguard/1", + GINT_TO_POINTER(1), + test_roundtrip_conversion); + g_test_add_data_func("/libnm/settings/roundtrip-conversion/wireguard/2", + GINT_TO_POINTER(2), + test_roundtrip_conversion); + g_test_add_data_func("/libnm/settings/roundtrip-conversion/general/3", + GINT_TO_POINTER(3), + test_roundtrip_conversion); + + g_test_add_data_func("/libnm/settings/routing-rule/1", GINT_TO_POINTER(0), test_routing_rule); + + g_test_add_func("/libnm/parse-tc-handle", test_parse_tc_handle); + + g_test_add_func("/libnm/test_team_setting", test_team_setting); + + g_test_add_func("/libnm/test_empty_setting", test_empty_setting); + + g_test_add_func("/libnm/test_setting_metadata", test_setting_metadata); + + return g_test_run(); +} diff --git a/src/libnm-core-impl/tests/test-settings-defaults.c b/src/libnm-core-impl/tests/test-settings-defaults.c new file mode 100644 index 0000000..b9db710 --- /dev/null +++ b/src/libnm-core-impl/tests/test-settings-defaults.c @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2008 - 2011 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-utils.h" +#include "nm-setting-8021x.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-gsm.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" +#include "nm-setting-ppp.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-serial.h" +#include "nm-setting-vpn.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wireless-security.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +static void +test_defaults(GType type, const char *name) +{ + GParamSpec **property_specs; + guint n_property_specs; + GObject * setting; + int i; + + setting = g_object_new(type, NULL); + + property_specs = g_object_class_list_properties(G_OBJECT_GET_CLASS(setting), &n_property_specs); + g_assert(property_specs); + + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + GValue value = G_VALUE_INIT; + GValue defvalue = G_VALUE_INIT; + char * actual, *expected; + gboolean ok = FALSE; + + /* Ignore non-fundamental types since they won't really have + * defaults. + */ + if (!G_TYPE_IS_FUNDAMENTAL(prop_spec->value_type)) + continue; + + g_value_init(&value, prop_spec->value_type); + g_object_get_property(G_OBJECT(setting), prop_spec->name, &value); + + g_value_init(&defvalue, prop_spec->value_type); + g_param_value_set_default(prop_spec, &defvalue); + + actual = g_strdup_value_contents(&value); + expected = g_strdup_value_contents(&defvalue); + + if (!strcmp(prop_spec->name, NM_SETTING_NAME)) { + /* 'name' is always the setting name, not the default value */ + ok = !strcmp(nm_setting_get_name(NM_SETTING(setting)), name); + g_free(expected); + expected = g_strdup(name); + } else + ok = g_param_value_defaults(prop_spec, &value); + + g_assert(ok); + + g_free(actual); + g_free(expected); + g_value_unset(&value); + g_value_unset(&defvalue); + } + + g_free(property_specs); + g_object_unref(setting); +} + +static void +defaults(void) +{ + /* The tests */ + test_defaults(NM_TYPE_SETTING_CONNECTION, NM_SETTING_CONNECTION_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_802_1X, NM_SETTING_802_1X_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_CDMA, NM_SETTING_CDMA_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_GSM, NM_SETTING_GSM_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_IP4_CONFIG, NM_SETTING_IP4_CONFIG_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_IP6_CONFIG, NM_SETTING_IP6_CONFIG_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_PPP, NM_SETTING_PPP_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_PPPOE, NM_SETTING_PPPOE_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_SERIAL, NM_SETTING_SERIAL_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_VPN, NM_SETTING_VPN_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_WIRED, NM_SETTING_WIRED_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_WIRELESS, NM_SETTING_WIRELESS_SETTING_NAME); + test_defaults(NM_TYPE_SETTING_WIRELESS_SECURITY, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); +} + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_func("/libnm/defaults", defaults); + + return g_test_run(); +} diff --git a/src/libnm-core-intern/README.md b/src/libnm-core-intern/README.md new file mode 100644 index 0000000..f17cf4d --- /dev/null +++ b/src/libnm-core-intern/README.md @@ -0,0 +1,19 @@ +libnm-core-intern +================= + +This contains header files only, which are also part of +the internal API of [`libnm-core-impl`](../libnm-core-impl). + +[`libnm-core-impl`](../libnm-core-impl) is a static library that (among others) implements +[`libnm-core-public`](../libnm-core-public) (which is a part of the public API of [`libnm`](../../libnm)). +This library gets statically linked into [`libnm`](../../libnm) and `NetworkManager`. +Hence, those components can also access internal (but not private) API of +[`libnm-core-impl`](../libnm-core-impl), and this API is in [`libnm-core-intern`](../libnm-core-intern). + +These headers can thus be included by anybody who statically links with +[`libnm-core-impl`](../libnm-core-impl) (including [`libnm-core-impl`](../libnm-core-impl) itself). + +The directory should not be added to the include search path, instead +users should explicitly `#include "libnm-core-intern/nm-core-internal.h"`) + +There is no source code here and no static library to link against. diff --git a/src/libnm-core-intern/meson.build b/src/libnm-core-intern/meson.build new file mode 100644 index 0000000..841a0ae --- /dev/null +++ b/src/libnm-core-intern/meson.build @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_core_intern_inc = include_directories('.') diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h new file mode 100644 index 0000000..bd607b4 --- /dev/null +++ b/src/libnm-core-intern/nm-core-internal.h @@ -0,0 +1,863 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 - 2018 Red Hat, Inc. + */ + +#ifndef NM_CORE_NM_INTERNAL_H +#define NM_CORE_NM_INTERNAL_H + +/* This header file contain functions that are provided as private API + * by libnm-core. It will contain functions to give privileged access to + * libnm-core. This can be useful for NetworkManager and libnm.so + * which both are special users of libnm-core. + * It also exposes some utility functions for reuse. + * + * These functions are not exported and are only available to components that link + * statically against libnm-core. This basically means libnm-core, libnm, NetworkManager + * and some test programs. + **/ +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL) + #error Cannot use this header. +#endif + +#include "libnm-base/nm-base.h" +#include "nm-connection.h" +#include "nm-core-enum-types.h" +#include "nm-meta-setting-base.h" +#include "nm-setting-6lowpan.h" +#include "nm-setting-8021x.h" +#include "nm-setting-adsl.h" +#include "nm-setting-bluetooth.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-bridge.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-dcb.h" +#include "nm-setting-dummy.h" +#include "nm-setting-generic.h" +#include "nm-setting-gsm.h" +#include "nm-setting-hostname.h" +#include "nm-setting-infiniband.h" +#include "nm-setting-ip-tunnel.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" +#include "nm-setting-macsec.h" +#include "nm-setting-macvlan.h" +#include "nm-setting-match.h" +#include "nm-setting-olpc-mesh.h" +#include "nm-setting-ovs-bridge.h" +#include "nm-setting-ovs-interface.h" +#include "nm-setting-ovs-dpdk.h" +#include "nm-setting-ovs-patch.h" +#include "nm-setting-ovs-port.h" +#include "nm-setting-ppp.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-proxy.h" +#include "nm-setting-serial.h" +#include "nm-setting-sriov.h" +#include "nm-setting-tc-config.h" +#include "nm-setting-team-port.h" +#include "nm-setting-team.h" +#include "nm-setting-tun.h" +#include "nm-setting-veth.h" +#include "nm-setting-vlan.h" +#include "nm-setting-vpn.h" +#include "nm-setting-vrf.h" +#include "nm-setting-vxlan.h" +#include "nm-setting-wifi-p2p.h" +#include "nm-setting-wimax.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireguard.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wpan.h" +#include "nm-setting.h" +#include "nm-simple-connection.h" +#include "nm-utils.h" +#include "nm-vpn-dbus-interface.h" +#include "nm-vpn-editor-plugin.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" + +/* NM_SETTING_COMPARE_FLAG_INFERRABLE: check whether a device-generated + * connection can be replaced by a already-defined connection. This flag only + * takes into account properties marked with the %NM_SETTING_PARAM_INFERRABLE + * flag. + */ +#define NM_SETTING_COMPARE_FLAG_INFERRABLE ((NMSettingCompareFlags) 0x80000000) + +/* NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY: this flag is used for properties + * that automatically get re-applied on an active connection when the settings + * connection is modified. For most properties, the applied-connection is distinct + * from the setting-connection and changes don't propagate. Exceptions are the + * firewall-zone and the metered property. + */ +#define NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY ((NMSettingCompareFlags) 0x40000000) + +/* NM_SETTING_COMPARE_FLAG_NONE: for convenience, define a special flag NONE -- which + * equals to numeric zero (NM_SETTING_COMPARE_FLAG_EXACT). + */ +#define NM_SETTING_COMPARE_FLAG_NONE ((NMSettingCompareFlags) 0) + +/*****************************************************************************/ + +#define NM_SETTING_SECRET_FLAG_ALL \ + ((NMSettingSecretFlags)(NM_SETTING_SECRET_FLAG_NONE | NM_SETTING_SECRET_FLAG_AGENT_OWNED \ + | NM_SETTING_SECRET_FLAG_NOT_SAVED \ + | NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) + +static inline gboolean +_nm_setting_secret_flags_valid(NMSettingSecretFlags flags) +{ + return !NM_FLAGS_ANY(flags, ~NM_SETTING_SECRET_FLAG_ALL); +} + +/*****************************************************************************/ + +const char * +nm_bluetooth_capability_to_string(NMBluetoothCapabilities capabilities, char *buf, gsize len); + +/*****************************************************************************/ + +#define NM_DHCP_HOSTNAME_FLAGS_FQDN_MASK \ + (NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED | NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE \ + | NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE | NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS) + +#define NM_DHCP_HOSTNAME_FLAGS_FQDN_DEFAULT_IP4 \ + (NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED | NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE) + +#define NM_DHCP_HOSTNAME_FLAGS_FQDN_DEFAULT_IP6 NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE + +/*****************************************************************************/ + +static inline _NMSettingWiredWakeOnLan +_NM_SETTING_WIRED_WAKE_ON_LAN_CAST(NMSettingWiredWakeOnLan v) +{ + /* _NMSettingWiredWakeOnLan and NMSettingWiredWakeOnLan enums are really + * the same. + * + * The former is used by libnm-platform (which should have no libnm-core* dependency), + * the latter is public API in libnm-core-public. A unit test ensures they are exactly the same, + * so we can just cast them. */ + return (_NMSettingWiredWakeOnLan) v; +} + +static inline _NMSettingWirelessWakeOnWLan +_NM_SETTING_WIRELESS_WAKE_ON_WLAN_CAST(NMSettingWirelessWakeOnWLan v) +{ + return (_NMSettingWirelessWakeOnWLan) v; +} + +static inline NM80211Mode +NM_802_11_MODE_CAST(_NM80211Mode v) +{ + return (NM80211Mode) v; +} + +static inline NMVlanFlags +NM_VLAN_FLAGS_CAST(_NMVlanFlags v) +{ + return (NMVlanFlags) v; +} + +/*****************************************************************************/ + +static inline NMTernary +NM_TERNARY_FROM_OPTION_BOOL(NMOptionBool v) +{ + nm_assert(NM_IN_SET(v, NM_OPTION_BOOL_DEFAULT, NM_OPTION_BOOL_TRUE, NM_OPTION_BOOL_FALSE)); + + return (NMTernary) v; +} + +static inline NMOptionBool +NM_TERNARY_TO_OPTION_BOOL(NMTernary v) +{ + nm_assert(NM_IN_SET(v, NM_TERNARY_DEFAULT, NM_TERNARY_TRUE, NM_TERNARY_FALSE)); + + return (NMOptionBool) v; +} + +/*****************************************************************************/ + +typedef enum { /*< skip >*/ + NM_SETTING_PARSE_FLAGS_NONE = 0, + NM_SETTING_PARSE_FLAGS_STRICT = 1LL << 0, + NM_SETTING_PARSE_FLAGS_BEST_EFFORT = 1LL << 1, + NM_SETTING_PARSE_FLAGS_NORMALIZE = 1LL << 2, + + _NM_SETTING_PARSE_FLAGS_LAST, + NM_SETTING_PARSE_FLAGS_ALL = ((_NM_SETTING_PARSE_FLAGS_LAST - 1) << 1) - 1, +} NMSettingParseFlags; + +gboolean _nm_connection_replace_settings(NMConnection * connection, + GVariant * new_settings, + NMSettingParseFlags parse_flags, + GError ** error); + +gpointer _nm_connection_check_main_setting(NMConnection *connection, + const char * setting_name, + GError ** error); + +typedef struct { + struct { + guint64 val; + bool has; + } timestamp; + + const char **seen_bssids; + +} NMConnectionSerializationOptions; + +GVariant *nm_connection_to_dbus_full(NMConnection * connection, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); + +typedef enum { + /* whether the connection has any secrets. + * + * @arg may be %NULL or a pointer to a gboolean for the result. The return + * value of _nm_connection_aggregate() is likewise the boolean result. */ + NM_CONNECTION_AGGREGATE_ANY_SECRETS, + + /* whether the connection has any secret with flags NM_SETTING_SECRET_FLAG_NONE. + * Note that this only cares about the flags, not whether the secret is actually + * present. + * + * @arg may be %NULL or a pointer to a gboolean for the result. The return + * value of _nm_connection_aggregate() is likewise the boolean result. */ + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, +} NMConnectionAggregateType; + +gboolean +_nm_connection_aggregate(NMConnection *connection, NMConnectionAggregateType type, gpointer arg); + +/** + * NMSettingVerifyResult: + * @NM_SETTING_VERIFY_SUCCESS: the setting verifies successfully + * @NM_SETTING_VERIFY_ERROR: the setting has a serious misconfiguration + * @NM_SETTING_VERIFY_NORMALIZABLE: the setting is valid but has properties + * that should be normalized + * @NM_SETTING_VERIFY_NORMALIZABLE_ERROR: the setting is invalid but the + * errors can be fixed by nm_connection_normalize(). + */ +typedef enum { + NM_SETTING_VERIFY_SUCCESS = TRUE, + NM_SETTING_VERIFY_ERROR = FALSE, + NM_SETTING_VERIFY_NORMALIZABLE = 2, + NM_SETTING_VERIFY_NORMALIZABLE_ERROR = 3, +} NMSettingVerifyResult; + +NMSettingVerifyResult _nm_connection_verify(NMConnection *connection, GError **error); + +gboolean _nm_connection_ensure_normalized(NMConnection * connection, + gboolean allow_modify, + const char * expected_uuid, + gboolean coerce_uuid, + NMConnection **out_connection_clone, + GError ** error); + +gboolean _nm_connection_remove_setting(NMConnection *connection, GType setting_type); + +#if NM_MORE_ASSERTS +extern const char _nmtst_connection_unchanging_user_data; +void nmtst_connection_assert_unchanging(NMConnection *connection); +#else +static inline void +nmtst_connection_assert_unchanging(NMConnection *connection) +{} +#endif + +NMConnection *_nm_simple_connection_new_from_dbus(GVariant * dict, + NMSettingParseFlags parse_flags, + GError ** error); + +NMSettingPriority _nm_setting_get_setting_priority(NMSetting *setting); + +gboolean _nm_setting_get_property(NMSetting *setting, const char *name, GValue *value); + +/*****************************************************************************/ + +GHashTable *_nm_setting_option_hash(NMSetting *setting, gboolean create_if_necessary); + +void _nm_setting_option_notify(NMSetting *setting, gboolean keys_changed); + +guint _nm_setting_option_get_all(NMSetting * setting, + const char *const **out_names, + GVariant *const ** out_values); + +gboolean _nm_setting_option_clear(NMSetting *setting, const char *optname); + +/*****************************************************************************/ + +guint nm_setting_ethtool_init_features( + NMSettingEthtool *setting, + NMOptionBool * requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */); + +/*****************************************************************************/ + +#define NM_UTILS_HWADDR_LEN_MAX_STR (NM_UTILS_HWADDR_LEN_MAX * 3) + +gboolean nm_utils_is_valid_iface_name_utf8safe(const char *utf8safe_name); + +GSList *_nm_utils_hash_values_to_slist(GHashTable *hash); + +GHashTable *_nm_utils_copy_strdict(GHashTable *strdict); + +typedef gpointer (*NMUtilsCopyFunc)(gpointer); + +const char ** +_nm_ip_address_get_attribute_names(const NMIPAddress *addr, gboolean sorted, guint *out_length); + +#define NM_SETTING_WIRED_S390_OPTION_MAX_LEN 200u + +void _nm_setting_wired_clear_s390_options(NMSettingWired *setting); +gboolean _nm_setting_wired_is_valid_s390_option(const char *option); +gboolean _nm_setting_wired_is_valid_s390_option_value(const char *name, const char *option); + +gboolean _nm_ip_route_attribute_validate_all(const NMIPRoute *route, GError **error); +const char ** +_nm_ip_route_get_attribute_names(const NMIPRoute *route, gboolean sorted, guint *out_length); +GHashTable *_nm_ip_route_get_attributes(NMIPRoute *route); + +NMSriovVF *_nm_utils_sriov_vf_from_strparts(const char *index, + const char *detail, + gboolean ignore_unknown, + GError ** error); +gboolean _nm_sriov_vf_attribute_validate_all(const NMSriovVF *vf, GError **error); + +GPtrArray * +_nm_utils_copy_array(const GPtrArray *array, NMUtilsCopyFunc copy_func, GDestroyNotify free_func); +GPtrArray *_nm_utils_copy_object_array(const GPtrArray *array); + +GSList *_nm_utils_strv_to_slist(char **strv, gboolean deep_copy); +char ** _nm_utils_slist_to_strv(const GSList *slist, gboolean deep_copy); + +GPtrArray *_nm_utils_strv_to_ptrarray(char **strv); +char ** _nm_utils_ptrarray_to_strv(const GPtrArray *ptrarray); + +gboolean _nm_utils_check_file(const char * filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + struct stat * out_st, + GError ** error); + +gboolean _nm_utils_check_module_file(const char * name, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError ** error); + +/*****************************************************************************/ + +typedef struct _NMUuid { + guchar uuid[16]; +} NMUuid; + +NMUuid *_nm_utils_uuid_parse(const char *str, NMUuid *uuid); +char * _nm_utils_uuid_unparse(const NMUuid *uuid, char *out_str /*[37]*/); +NMUuid *_nm_utils_uuid_generate_random(NMUuid *out_uuid); + +gboolean nm_utils_uuid_is_null(const NMUuid *uuid); + +#define NM_UTILS_UUID_TYPE_LEGACY 0 +#define NM_UTILS_UUID_TYPE_VERSION3 3 +#define NM_UTILS_UUID_TYPE_VERSION5 5 + +NMUuid *nm_utils_uuid_generate_from_string_bin(NMUuid * uuid, + const char *s, + gssize slen, + int uuid_type, + gpointer type_args); + +char * +nm_utils_uuid_generate_from_string(const char *s, gssize slen, int uuid_type, gpointer type_args); + +/* arbitrarily chosen namespace UUID for _nm_utils_uuid_generate_from_strings() */ +#define NM_UTILS_UUID_NS "b425e9fb-7598-44b4-9e3b-5a2e3aaa4905" + +char *_nm_utils_uuid_generate_from_strings(const char *string1, ...) G_GNUC_NULL_TERMINATED; + +char *nm_utils_uuid_generate_buf_(char *buf); +#define nm_utils_uuid_generate_buf(buf) \ + ({ \ + G_STATIC_ASSERT(sizeof(buf) == G_N_ELEMENTS(buf) && sizeof(buf) >= 37); \ + nm_utils_uuid_generate_buf_(buf); \ + }) +#define nm_utils_uuid_generate_a() (nm_utils_uuid_generate_buf_(g_alloca(37))) + +void _nm_dbus_errors_init(void); + +extern gboolean _nm_utils_is_manager_process; + +gboolean +_nm_dbus_typecheck_response(GVariant *response, const GVariantType *reply_type, GError **error); + +gulong _nm_dbus_signal_connect_data(GDBusProxy * proxy, + const char * signal_name, + const GVariantType *signature, + GCallback c_handler, + gpointer data, + GClosureNotify destroy_data, + GConnectFlags connect_flags); +#define _nm_dbus_signal_connect(proxy, name, signature, handler, data) \ + _nm_dbus_signal_connect_data(proxy, name, signature, handler, data, NULL, (GConnectFlags) 0) + +GVariant *_nm_dbus_proxy_call_finish(GDBusProxy * proxy, + GAsyncResult * res, + const GVariantType *reply_type, + GError ** error); + +GVariant *_nm_dbus_connection_call_finish(GDBusConnection * dbus_connection, + GAsyncResult * result, + const GVariantType *reply_type, + GError ** error); + +gboolean _nm_dbus_error_has_name(GError *error, const char *dbus_error_name); + +/*****************************************************************************/ + +char *_nm_utils_ssid_to_utf8(GBytes *ssid); + +/*****************************************************************************/ + +gboolean _nm_vpn_plugin_info_check_file(const char * filename, + gboolean check_absolute, + gboolean do_validate_filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError ** error); + +const char *_nm_vpn_plugin_info_get_default_dir_etc(void); +const char *_nm_vpn_plugin_info_get_default_dir_lib(void); +const char *_nm_vpn_plugin_info_get_default_dir_user(void); + +GSList *_nm_vpn_plugin_info_list_load_dir(const char * dirname, + gboolean do_validate_filename, + gint64 check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data); + +/*****************************************************************************/ + +GHashTable *_nm_setting_ovs_external_ids_get_data(NMSettingOvsExternalIDs *self); + +/*****************************************************************************/ + +typedef struct { + const char *name; + gboolean numeric; + gboolean ipv6_only; +} NMUtilsDNSOptionDesc; + +extern const NMUtilsDNSOptionDesc _nm_utils_dns_option_descs[]; + +gboolean _nm_utils_dns_option_validate(const char * option, + char ** out_name, + long * out_value, + gboolean ipv6, + const NMUtilsDNSOptionDesc *option_descs); +gssize _nm_utils_dns_option_find_idx(GPtrArray *array, const char *option); + +int nm_setting_ip_config_next_valid_dns_option(NMSettingIPConfig *setting, guint idx); + +/*****************************************************************************/ + +typedef struct _NMUtilsStrStrDictKey NMUtilsStrStrDictKey; +guint _nm_utils_strstrdictkey_hash(gconstpointer a); +gboolean _nm_utils_strstrdictkey_equal(gconstpointer a, gconstpointer b); +NMUtilsStrStrDictKey *_nm_utils_strstrdictkey_create(const char *v1, const char *v2); + +#define _nm_utils_strstrdictkey_static(v1, v2) ((NMUtilsStrStrDictKey *) ("\03" v1 "\0" v2 "")) + +/*****************************************************************************/ + +gboolean _nm_setting_vlan_set_priorities(NMSettingVlan * setting, + NMVlanPriorityMap map, + const NMVlanQosMapping *qos_map, + guint n_qos_map); +void _nm_setting_vlan_get_priorities(NMSettingVlan * setting, + NMVlanPriorityMap map, + NMVlanQosMapping **out_qos_map, + guint * out_n_qos_map); + +/*****************************************************************************/ + +struct ether_addr; + +gboolean _nm_utils_generate_mac_address_mask_parse(const char * value, + struct ether_addr * out_mask, + struct ether_addr **out_ouis, + gsize * out_ouis_len, + GError ** error); + +/*****************************************************************************/ + +static inline gpointer +_nm_connection_get_setting(NMConnection *connection, GType type) +{ + return (gpointer) nm_connection_get_setting(connection, type); +} + +NMSettingIPConfig *nm_connection_get_setting_ip_config(NMConnection *connection, int addr_family); + +/*****************************************************************************/ + +typedef enum { + NM_BOND_OPTION_TYPE_INT, + NM_BOND_OPTION_TYPE_BOTH, + NM_BOND_OPTION_TYPE_IP, + NM_BOND_OPTION_TYPE_MAC, + NM_BOND_OPTION_TYPE_IFNAME, +} NMBondOptionType; + +NMBondOptionType _nm_setting_bond_get_option_type(NMSettingBond *setting, const char *name); + +const char *nm_setting_bond_get_option_or_default(NMSettingBond *self, const char *option); + +#define NM_BOND_AD_ACTOR_SYSTEM_DEFAULT "00:00:00:00:00:00" + +/*****************************************************************************/ + +/* nm_connection_get_uuid() asserts against NULL, which is the right thing to + * do in order to catch bugs. However, sometimes that behavior is inconvenient. + * Just try or return NULL. */ + +static inline const char * +_nm_connection_get_id(NMConnection *connection) +{ + return connection ? nm_connection_get_id(connection) : NULL; +} + +static inline const char * +_nm_connection_get_uuid(NMConnection *connection) +{ + return connection ? nm_connection_get_uuid(connection) : NULL; +} + +NMConnectionMultiConnect _nm_connection_get_multi_connect(NMConnection *connection); + +/*****************************************************************************/ + +gboolean _nm_setting_bond_option_supported(const char *option, NMBondMode mode); + +/*****************************************************************************/ + +NMSettingBluetooth *_nm_connection_get_setting_bluetooth_for_nap(NMConnection *connection); + +/*****************************************************************************/ + +NMTeamLinkWatcher *_nm_team_link_watcher_ref(NMTeamLinkWatcher *watcher); + +int nm_team_link_watcher_cmp(const NMTeamLinkWatcher *watcher, const NMTeamLinkWatcher *other); + +int nm_team_link_watchers_cmp(const NMTeamLinkWatcher *const *a, + const NMTeamLinkWatcher *const *b, + gsize len, + gboolean ignore_order); + +gboolean nm_team_link_watchers_equal(const GPtrArray *a, const GPtrArray *b, gboolean ignore_order); + +/*****************************************************************************/ + +guint32 _nm_utils_parse_tc_handle(const char *str, GError **error); +void _nm_utils_string_append_tc_parent(GString *string, const char *prefix, guint32 parent); +void _nm_utils_string_append_tc_qdisc_rest(GString *string, NMTCQdisc *qdisc); +gboolean +_nm_utils_string_append_tc_tfilter_rest(GString *string, NMTCTfilter *tfilter, GError **error); + +GHashTable *_nm_tc_qdisc_get_attributes(NMTCQdisc *qdisc); +GHashTable *_nm_tc_action_get_attributes(NMTCAction *action); + +/*****************************************************************************/ + +static inline gboolean +_nm_connection_type_is_master(const char *type) +{ + return (NM_IN_STRSET(type, + NM_SETTING_BOND_SETTING_NAME, + NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_TEAM_SETTING_NAME, + NM_SETTING_OVS_BRIDGE_SETTING_NAME, + NM_SETTING_OVS_PORT_SETTING_NAME)); +} + +/*****************************************************************************/ + +gboolean _nm_utils_dhcp_duid_valid(const char *duid, GBytes **out_duid_bin); + +/*****************************************************************************/ + +gboolean _nm_setting_sriov_sort_vfs(NMSettingSriov *setting); +gboolean _nm_setting_bridge_port_sort_vlans(NMSettingBridgePort *setting); +gboolean _nm_setting_bridge_sort_vlans(NMSettingBridge *setting); + +/*****************************************************************************/ + +typedef struct _NMSockAddrEndpoint NMSockAddrEndpoint; + +NMSockAddrEndpoint *nm_sock_addr_endpoint_new(const char *endpoint); + +NMSockAddrEndpoint *nm_sock_addr_endpoint_ref(NMSockAddrEndpoint *self); +void nm_sock_addr_endpoint_unref(NMSockAddrEndpoint *self); + +const char *nm_sock_addr_endpoint_get_endpoint(NMSockAddrEndpoint *self); +const char *nm_sock_addr_endpoint_get_host(NMSockAddrEndpoint *self); +gint32 nm_sock_addr_endpoint_get_port(NMSockAddrEndpoint *self); + +gboolean nm_sock_addr_endpoint_get_fixed_sockaddr(NMSockAddrEndpoint *self, gpointer sockaddr); + +#define nm_auto_unref_sockaddrendpoint nm_auto(_nm_auto_unref_sockaddrendpoint) +NM_AUTO_DEFINE_FCN0(NMSockAddrEndpoint *, + _nm_auto_unref_sockaddrendpoint, + nm_sock_addr_endpoint_unref); + +/*****************************************************************************/ + +NMSockAddrEndpoint *_nm_wireguard_peer_get_endpoint(const NMWireGuardPeer *self); +void _nm_wireguard_peer_set_endpoint(NMWireGuardPeer *self, NMSockAddrEndpoint *endpoint); + +void +_nm_wireguard_peer_set_public_key_bin(NMWireGuardPeer *self, + const guint8 public_key[static NM_WIREGUARD_PUBLIC_KEY_LEN]); + +/*****************************************************************************/ + +const NMIPAddr *nm_ip_routing_rule_get_from_bin(const NMIPRoutingRule *self); +void nm_ip_routing_rule_set_from_bin(NMIPRoutingRule *self, gconstpointer from, guint8 len); + +const NMIPAddr *nm_ip_routing_rule_get_to_bin(const NMIPRoutingRule *self); +void nm_ip_routing_rule_set_to_bin(NMIPRoutingRule *self, gconstpointer to, guint8 len); + +gboolean nm_ip_routing_rule_get_xifname_bin(const NMIPRoutingRule *self, + gboolean iif /* or else oif */, + char out_xifname[static 16]); + +#define NM_IP_ROUTING_RULE_ATTR_ACTION "action" +#define NM_IP_ROUTING_RULE_ATTR_DPORT_END "dport-end" +#define NM_IP_ROUTING_RULE_ATTR_DPORT_START "dport-start" +#define NM_IP_ROUTING_RULE_ATTR_FAMILY "family" +#define NM_IP_ROUTING_RULE_ATTR_FROM "from" +#define NM_IP_ROUTING_RULE_ATTR_FROM_LEN "from-len" +#define NM_IP_ROUTING_RULE_ATTR_FWMARK "fwmark" +#define NM_IP_ROUTING_RULE_ATTR_FWMASK "fwmask" +#define NM_IP_ROUTING_RULE_ATTR_IIFNAME "iifname" +#define NM_IP_ROUTING_RULE_ATTR_INVERT "invert" +#define NM_IP_ROUTING_RULE_ATTR_IPPROTO "ipproto" +#define NM_IP_ROUTING_RULE_ATTR_OIFNAME "oifname" +#define NM_IP_ROUTING_RULE_ATTR_PRIORITY "priority" +#define NM_IP_ROUTING_RULE_ATTR_SPORT_END "sport-end" +#define NM_IP_ROUTING_RULE_ATTR_SPORT_START "sport-start" +#define NM_IP_ROUTING_RULE_ATTR_SUPPRESS_PREFIXLENGTH "suppress-prefixlength" +#define NM_IP_ROUTING_RULE_ATTR_TABLE "table" +#define NM_IP_ROUTING_RULE_ATTR_TO "to" +#define NM_IP_ROUTING_RULE_ATTR_TOS "tos" +#define NM_IP_ROUTING_RULE_ATTR_TO_LEN "to-len" +#define NM_IP_ROUTING_RULE_ATTR_UID_RANGE_START "uid-range-start" +#define NM_IP_ROUTING_RULE_ATTR_UID_RANGE_END "uid-range-end" + +NMIPRoutingRule *nm_ip_routing_rule_from_dbus(GVariant *variant, gboolean strict, GError **error); +GVariant * nm_ip_routing_rule_to_dbus(const NMIPRoutingRule *self); + +/*****************************************************************************/ + +typedef struct _NMSettInfoSetting NMSettInfoSetting; +typedef struct _NMSettInfoProperty NMSettInfoProperty; + +typedef GVariant *(*NMSettInfoPropToDBusFcn)(const NMSettInfoSetting * sett_info, + guint property_idx, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); +typedef gboolean (*NMSettInfoPropFromDBusFcn)(NMSetting * setting, + GVariant * connection_dict, + const char * property, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error); +typedef gboolean (*NMSettInfoPropMissingFromDBusFcn)(NMSetting * setting, + GVariant * connection_dict, + const char * property, + NMSettingParseFlags parse_flags, + GError ** error); +typedef GVariant *(*NMSettInfoPropGPropToDBusFcn)(const GValue *from); +typedef void (*NMSettInfoPropGPropFromDBusFcn)(GVariant *from, GValue *to); + +const NMSettInfoSetting *nmtst_sett_info_settings(void); + +typedef struct { + const GVariantType *dbus_type; + + NMSettInfoPropToDBusFcn to_dbus_fcn; + NMSettInfoPropFromDBusFcn from_dbus_fcn; + NMSettInfoPropMissingFromDBusFcn missing_from_dbus_fcn; + + /* Simpler variants of @to_dbus_fcn/@from_dbus_fcn that operate solely + * on the GValue value of the GObject property. */ + NMSettInfoPropGPropToDBusFcn gprop_to_dbus_fcn; + NMSettInfoPropGPropFromDBusFcn gprop_from_dbus_fcn; +} NMSettInfoPropertType; + +struct _NMSettInfoProperty { + const char *name; + + GParamSpec *param_spec; + + const NMSettInfoPropertType *property_type; +}; + +typedef struct { + const GVariantType *(*get_variant_type)(const struct _NMSettInfoSetting *sett_info, + const char * name, + GError ** error); +} NMSettInfoSettGendata; + +typedef struct { + /* if set, then this setting class has no own fields. Instead, its + * data is entirely based on gendata. Meaning: it tracks all data + * as native GVariants. + * It might have some GObject properties, but these are merely accessors + * to the underlying gendata. + * + * Note, that at the moment there are few hooks, to customize the behavior + * of the setting further. They are currently unneeded. This is desired, + * but could be added when there is a good reason. + * + * However, a few hooks there are... see NMSettInfoSettGendata. */ + const NMSettInfoSettGendata *gendata_info; +} NMSettInfoSettDetail; + +struct _NMSettInfoSetting { + NMSettingClass *setting_class; + + /* the properties, sorted by property name. */ + const NMSettInfoProperty *property_infos; + + /* the @property_infos list is sorted by property name. For some uses we need + * a different sort order. If @property_infos_sorted is set, this is the order + * instead. It is used for: + * + * - nm_setting_enumerate_values() + * - keyfile writer adding keys to the group. + * + * Note that currently only NMSettingConnection implements here a sort order + * that differs from alphabetical sort of the property names. + */ + const NMSettInfoProperty *const *property_infos_sorted; + + guint property_infos_len; + NMSettInfoSettDetail detail; +}; + +static inline const NMSettInfoProperty * +_nm_sett_info_property_info_get_sorted(const NMSettInfoSetting *sett_info, guint idx) +{ + nm_assert(sett_info); + nm_assert(idx < sett_info->property_infos_len); + nm_assert(!sett_info->property_infos_sorted || sett_info->property_infos_sorted[idx]); + + return sett_info->property_infos_sorted ? sett_info->property_infos_sorted[idx] + : &sett_info->property_infos[idx]; +} + +const NMSettInfoProperty * +_nm_sett_info_setting_get_property_info(const NMSettInfoSetting *sett_info, + const char * property_name); + +const NMSettInfoSetting *_nm_setting_class_get_sett_info(NMSettingClass *setting_class); + +static inline const NMSettInfoProperty * +_nm_setting_class_get_property_info(NMSettingClass *setting_class, const char *property_name) +{ + return _nm_sett_info_setting_get_property_info(_nm_setting_class_get_sett_info(setting_class), + property_name); +} + +/*****************************************************************************/ + +gboolean _nm_setting_compare(NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags); + +gboolean _nm_setting_diff(NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags, + gboolean invert_results, + GHashTable ** results); + +NMSetting8021xCKScheme _nm_setting_802_1x_cert_get_scheme(GBytes *bytes, GError **error); + +GBytes *_nm_setting_802_1x_cert_value_to_bytes(NMSetting8021xCKScheme scheme, + const guint8 * val_bin, + gssize val_len, + GError ** error); + +/*****************************************************************************/ + +static inline gboolean +_nm_connection_serialize_secrets(NMConnectionSerializationFlags flags, + NMSettingSecretFlags secret_flags) +{ + if (NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_NO_SECRETS)) + return FALSE; + if (NM_FLAGS_HAS(flags, NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED) + && !NM_FLAGS_HAS(secret_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED)) + return FALSE; + return TRUE; +} + +void _nm_connection_clear_secrets_by_secret_flags(NMConnection * self, + NMSettingSecretFlags filter_flags); + +GVariant *_nm_connection_for_each_secret(NMConnection * self, + GVariant * secrets, + gboolean remove_non_secrets, + _NMConnectionForEachSecretFunc callback, + gpointer callback_data); + +typedef gboolean (*NMConnectionFindSecretFunc)(NMSettingSecretFlags flags, gpointer user_data); + +gboolean _nm_connection_find_secret(NMConnection * self, + GVariant * secrets, + NMConnectionFindSecretFunc callback, + gpointer callback_data); + +/*****************************************************************************/ + +gboolean nm_utils_base64secret_normalize(const char *base64_key, + gsize required_key_len, + char ** out_base64_key_norm); + +/*****************************************************************************/ + +gboolean nm_utils_connection_is_adhoc_wpa(NMConnection *connection); + +const char *nm_utils_wifi_freq_to_band(guint32 freq); + +gboolean _nm_utils_iaid_verify(const char *str, gint64 *out_value); + +gboolean +_nm_utils_validate_dhcp_hostname_flags(NMDhcpHostnameFlags flags, int addr_family, GError **error); + +/*****************************************************************************/ + +gboolean _nmtst_variant_attribute_spec_assert_sorted(const NMVariantAttributeSpec *const *array, + gsize len); + +const NMVariantAttributeSpec * +_nm_variant_attribute_spec_find_binary_search(const NMVariantAttributeSpec *const *array, + gsize len, + const char * name); + +/*****************************************************************************/ + +gboolean _nm_ip_tunnel_mode_is_layer2(NMIPTunnelMode mode); + +#endif diff --git a/src/libnm-core-intern/nm-keyfile-internal.h b/src/libnm-core-intern/nm-keyfile-internal.h new file mode 100644 index 0000000..5140d8e --- /dev/null +++ b/src/libnm-core-intern/nm-keyfile-internal.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_KEYFILE_INTERNAL_H__ +#define __NM_KEYFILE_INTERNAL_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL) + #error Cannot use this header. +#endif + +#include + +#include "nm-keyfile.h" + +#include "nm-connection.h" +#include "nm-setting-8021x.h" + +#include "libnm-core-intern/nm-core-internal.h" + +/*****************************************************************************/ + +#define NM_KEYFILE_CERT_SCHEME_PREFIX_PATH "file://" +#define NM_KEYFILE_CERT_SCHEME_PREFIX_PKCS11 "pkcs11:" +#define NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB "data:;base64," + +char *nm_keyfile_detect_unqualified_path_scheme(const char * base_dir, + gconstpointer pdata, + gsize data_len, + gboolean consider_exists, + gboolean * out_exists); + +gboolean nm_keyfile_read_ensure_id(NMConnection *connection, const char *fallback_id); + +gboolean nm_keyfile_read_ensure_uuid(NMConnection *connection, const char *fallback_uuid_seed); + +/*****************************************************************************/ + +/** + * NMKeyfileHandlerDataWarn: + * + * this struct is passed as @handler_data for the @NMKeyfileReadHandler of + * type %NM_KEYFILE_HANDLER_TYPE_WARN. + */ +typedef struct { + NMKeyfileWarnSeverity severity; + char * message; + const char * fmt; + va_list ap; +} NMKeyfileHandlerDataWarn; + +/** + * NMKeyfileHandlerDataWriteCert: + * + * this struct is passed as @handler_data for the @NMKeyfileWriteHandler of + * type %NM_KEYFILE_HANDLER_TYPE_WRITE_CERT. + */ +typedef struct { + const NMSetting8021xSchemeVtable *vtable; +} NMKeyfileHandlerDataWriteCert; + +struct _NMKeyfileHandlerData { + NMKeyfileHandlerType type; + + GError **p_error; + + const char *kf_group_name; + const char *kf_key; + + NMSetting * cur_setting; + const char *cur_property; + + union { + NMKeyfileHandlerDataWarn warn; + NMKeyfileHandlerDataWriteCert write_cert; + }; +}; + +/*****************************************************************************/ + +const char *_nm_keyfile_handler_data_warn_get_message(const NMKeyfileHandlerData *handler_data); + +/*****************************************************************************/ + +char * +nm_keyfile_plugin_kf_get_string(GKeyFile *kf, const char *group, const char *key, GError **error); +void nm_keyfile_plugin_kf_set_string(GKeyFile * kf, + const char *group, + const char *key, + const char *value); + +int nm_key_file_get_boolean(GKeyFile *kf, const char *group, const char *key, int default_value); + +void _nm_keyfile_copy(GKeyFile *dst, GKeyFile *src); +gboolean _nm_keyfile_a_contains_all_in_b(GKeyFile *kf_a, GKeyFile *kf_b); +gboolean _nm_keyfile_equals(GKeyFile *kf_a, GKeyFile *kf_b, gboolean consider_order); +gboolean _nm_keyfile_has_values(GKeyFile *keyfile); + +/*****************************************************************************/ + +#define NM_KEYFILE_GROUP_NMMETA ".nmmeta" +#define NM_KEYFILE_KEY_NMMETA_NM_GENERATED "nm-generated" +#define NM_KEYFILE_KEY_NMMETA_VOLATILE "volatile" +#define NM_KEYFILE_KEY_NMMETA_EXTERNAL "external" +#define NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE "shadowed-storage" +#define NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED "shadowed-owned" + +#define NM_KEYFILE_PATH_NAME_LIB NMLIBDIR "/system-connections" +#define NM_KEYFILE_PATH_NAME_ETC_DEFAULT NMCONFDIR "/system-connections" +#define NM_KEYFILE_PATH_NAME_RUN NMRUNDIR "/system-connections" + +#define NM_KEYFILE_PATH_SUFFIX_NMCONNECTION ".nmconnection" + +#define NM_KEYFILE_PATH_SUFFIX_NMMETA ".nmmeta" + +#define NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL "/dev/null" + +gboolean nm_keyfile_utils_ignore_filename(const char *filename, gboolean require_extension); + +char *nm_keyfile_utils_create_filename(const char *filename, gboolean with_extension); + +#endif /* __NM_KEYFILE_INTERNAL_H__ */ diff --git a/src/libnm-core-intern/nm-keyfile-utils.h b/src/libnm-core-intern/nm-keyfile-utils.h new file mode 100644 index 0000000..450cc81 --- /dev/null +++ b/src/libnm-core-intern/nm-keyfile-utils.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2010 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_KEYFILE_UTILS_H__ +#define __NM_KEYFILE_UTILS_H__ + +#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL) + #error Cannot use this header. +#endif + +/*****************************************************************************/ + +#include "libnm-glib-aux/nm-shared-utils.h" + +/*****************************************************************************/ + +#define NM_KEYFILE_GROUP_VPN_SECRETS "vpn-secrets" +#define NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER "wireguard-peer." + +#define nm_keyfile_error_is_not_found(error) \ + nm_g_error_matches(error, \ + G_KEY_FILE_ERROR, \ + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, \ + G_KEY_FILE_ERROR_KEY_NOT_FOUND) + +const char *nm_keyfile_plugin_get_alias_for_setting_name(const char *setting_name); + +const char *nm_keyfile_plugin_get_setting_name_for_alias(const char *alias); + +/*****************************************************************************/ + +guint *nm_keyfile_plugin_kf_get_integer_list_uint(GKeyFile * kf, + const char *group, + const char *key, + gsize * out_length, + GError ** error); +char **nm_keyfile_plugin_kf_get_string_list(GKeyFile * kf, + const char *group, + const char *key, + gsize * out_length, + GError ** error); +char * +nm_keyfile_plugin_kf_get_string(GKeyFile *kf, const char *group, const char *key, GError **error); +gboolean +nm_keyfile_plugin_kf_get_boolean(GKeyFile *kf, const char *group, const char *key, GError **error); +char * +nm_keyfile_plugin_kf_get_value(GKeyFile *kf, const char *group, const char *key, GError **error); + +void nm_keyfile_plugin_kf_set_integer_list_uint8(GKeyFile * kf, + const char * group, + const char * key, + const guint8 *list, + gsize length); +void nm_keyfile_plugin_kf_set_integer_list_uint(GKeyFile * kf, + const char * group, + const char * key, + const guint *list, + gsize length); +void nm_keyfile_plugin_kf_set_string_list(GKeyFile * kf, + const char * group, + const char * key, + const char *const *list, + gsize length); + +void nm_keyfile_plugin_kf_set_string(GKeyFile * kf, + const char *group, + const char *key, + const char *value); +void +nm_keyfile_plugin_kf_set_boolean(GKeyFile *kf, const char *group, const char *key, gboolean value); +void +nm_keyfile_plugin_kf_set_value(GKeyFile *kf, const char *group, const char *key, const char *value); + +gint64 nm_keyfile_plugin_kf_get_int64(GKeyFile * kf, + const char *group, + const char *key, + guint base, + gint64 min, + gint64 max, + gint64 fallback, + GError ** error); + +char ** +nm_keyfile_plugin_kf_get_keys(GKeyFile *kf, const char *group, gsize *out_length, GError **error); + +gboolean +nm_keyfile_plugin_kf_has_key(GKeyFile *kf, const char *group, const char *key, GError **error); + +const char *nm_keyfile_key_encode(const char *name, char **out_to_free); + +const char *nm_keyfile_key_decode(const char *key, char **out_to_free); + +#endif /* __NM_KEYFILE_UTILS_H__ */ diff --git a/src/libnm-core-intern/nm-meta-setting-base-impl.h b/src/libnm-core-intern/nm-meta-setting-base-impl.h new file mode 100644 index 0000000..94b14e8 --- /dev/null +++ b/src/libnm-core-intern/nm-meta-setting-base-impl.h @@ -0,0 +1,187 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 - 2018 Red Hat, Inc. + */ + +#ifndef __NM_META_SETTING_BASE_IMPL_H__ +#define __NM_META_SETTING_BASE_IMPL_H__ + +#include "nm-setting-8021x.h" + +/*****************************************************************************/ + +/* + * A setting's priority should roughly follow the OSI layer model, but it also + * controls which settings get asked for secrets first. Thus settings which + * relate to things that must be working first, like hardware, should get a + * higher priority than things which layer on top of the hardware. For example, + * the GSM/CDMA settings should provide secrets before the PPP setting does, + * because a PIN is required to unlock the device before PPP can even start. + * Even settings without secrets should be assigned the right priority. + * + * 0: reserved for invalid + * + * 1: reserved for the Connection setting + * + * 2,3: hardware-related settings like Ethernet, Wi-Fi, InfiniBand, Bridge, etc. + * These priority 1 settings are also "base types", which means that at least + * one of them is required for the connection to be valid, and their name is + * valid in the 'type' property of the Connection setting. + * + * 4: hardware-related auxiliary settings that require a base setting to be + * successful first, like Wi-Fi security, 802.1x, etc. + * + * 5: hardware-independent settings that are required before IP connectivity + * can be established, like PPP, PPPoE, etc. + * + * 6: IP-level stuff + * + * 10: NMSettingUser + */ +typedef enum { /*< skip >*/ + NM_SETTING_PRIORITY_INVALID = 0, + NM_SETTING_PRIORITY_CONNECTION = 1, + NM_SETTING_PRIORITY_HW_BASE = 2, + NM_SETTING_PRIORITY_HW_NON_BASE = 3, + NM_SETTING_PRIORITY_HW_AUX = 4, + NM_SETTING_PRIORITY_AUX = 5, + NM_SETTING_PRIORITY_IP = 6, + NM_SETTING_PRIORITY_USER = 10, +} NMSettingPriority; + +/*****************************************************************************/ + +typedef enum { + NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT, + NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT, + NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT, + NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT, + NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY, + NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY, + + NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN, + + _NM_SETTING_802_1X_SCHEME_TYPE_NUM = NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN, +} NMSetting8021xSchemeType; + +typedef struct { + const char *setting_key; + NMSetting8021xCKScheme (*scheme_func)(NMSetting8021x *setting); + NMSetting8021xCKFormat (*format_func)(NMSetting8021x *setting); + const char *(*path_func)(NMSetting8021x *setting); + GBytes *(*blob_func)(NMSetting8021x *setting); + const char *(*uri_func)(NMSetting8021x *setting); + const char *(*passwd_func)(NMSetting8021x *setting); + NMSettingSecretFlags (*pwflag_func)(NMSetting8021x *setting); + gboolean (*set_cert_func)(NMSetting8021x * setting, + const char * value, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error); + gboolean (*set_private_key_func)(NMSetting8021x * setting, + const char * value, + const char * password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error); + const char * file_suffix; + NMSetting8021xSchemeType scheme_type; + bool is_secret : 1; +} NMSetting8021xSchemeVtable; + +extern const NMSetting8021xSchemeVtable + nm_setting_8021x_scheme_vtable[_NM_SETTING_802_1X_SCHEME_TYPE_NUM + 1]; + +/*****************************************************************************/ + +typedef enum { + /* the enum (and their numeric values) are internal API. Do not assign + * any meaning the numeric values, because they already have one: + * + * they are sorted in a way, that corresponds to the asciibetical sort + * order of the corresponding setting-name. */ + + NM_META_SETTING_TYPE_6LOWPAN, + NM_META_SETTING_TYPE_OLPC_MESH, + NM_META_SETTING_TYPE_WIRELESS, + NM_META_SETTING_TYPE_WIRELESS_SECURITY, + NM_META_SETTING_TYPE_802_1X, + NM_META_SETTING_TYPE_WIRED, + NM_META_SETTING_TYPE_ADSL, + NM_META_SETTING_TYPE_BLUETOOTH, + NM_META_SETTING_TYPE_BOND, + NM_META_SETTING_TYPE_BRIDGE, + NM_META_SETTING_TYPE_BRIDGE_PORT, + NM_META_SETTING_TYPE_CDMA, + NM_META_SETTING_TYPE_CONNECTION, + NM_META_SETTING_TYPE_DCB, + NM_META_SETTING_TYPE_DUMMY, + NM_META_SETTING_TYPE_ETHTOOL, + NM_META_SETTING_TYPE_GENERIC, + NM_META_SETTING_TYPE_GSM, + NM_META_SETTING_TYPE_HOSTNAME, + NM_META_SETTING_TYPE_INFINIBAND, + NM_META_SETTING_TYPE_IP_TUNNEL, + NM_META_SETTING_TYPE_IP4_CONFIG, + NM_META_SETTING_TYPE_IP6_CONFIG, + NM_META_SETTING_TYPE_MACSEC, + NM_META_SETTING_TYPE_MACVLAN, + NM_META_SETTING_TYPE_MATCH, + NM_META_SETTING_TYPE_OVS_BRIDGE, + NM_META_SETTING_TYPE_OVS_DPDK, + NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS, + NM_META_SETTING_TYPE_OVS_INTERFACE, + NM_META_SETTING_TYPE_OVS_PATCH, + NM_META_SETTING_TYPE_OVS_PORT, + NM_META_SETTING_TYPE_PPP, + NM_META_SETTING_TYPE_PPPOE, + NM_META_SETTING_TYPE_PROXY, + NM_META_SETTING_TYPE_SERIAL, + NM_META_SETTING_TYPE_SRIOV, + NM_META_SETTING_TYPE_TC_CONFIG, + NM_META_SETTING_TYPE_TEAM, + NM_META_SETTING_TYPE_TEAM_PORT, + NM_META_SETTING_TYPE_TUN, + NM_META_SETTING_TYPE_USER, + NM_META_SETTING_TYPE_VETH, + NM_META_SETTING_TYPE_VLAN, + NM_META_SETTING_TYPE_VPN, + NM_META_SETTING_TYPE_VRF, + NM_META_SETTING_TYPE_VXLAN, + NM_META_SETTING_TYPE_WIFI_P2P, + NM_META_SETTING_TYPE_WIMAX, + NM_META_SETTING_TYPE_WIREGUARD, + NM_META_SETTING_TYPE_WPAN, + + NM_META_SETTING_TYPE_UNKNOWN, + + _NM_META_SETTING_TYPE_NUM = NM_META_SETTING_TYPE_UNKNOWN, +} NMMetaSettingType; + +#if _NM_META_SETTING_BASE_IMPL_LIBNM + #define _NMMetaSettingInfo_Alias _NMMetaSettingInfo +#else + #define _NMMetaSettingInfo_Alias _NMMetaSettingInfoCli +#endif + +struct _NMMetaSettingInfo_Alias { + const char *setting_name; + GType (*get_setting_gtype)(void); + NMMetaSettingType meta_type; + NMSettingPriority setting_priority; +}; + +typedef struct _NMMetaSettingInfo_Alias NMMetaSettingInfo; + +extern const NMMetaSettingInfo nm_meta_setting_infos[_NM_META_SETTING_TYPE_NUM + 1]; + +const NMMetaSettingInfo *nm_meta_setting_infos_by_name(const char *name); +const NMMetaSettingInfo *nm_meta_setting_infos_by_gtype(GType gtype); + +/*****************************************************************************/ + +NMSettingPriority nm_meta_setting_info_get_base_type_priority(const NMMetaSettingInfo *setting_info, + GType gtype); +NMSettingPriority _nm_setting_type_get_base_type_priority(GType type); + +#endif /* __NM_META_SETTING_BASE_IMPL_H__ */ diff --git a/src/libnm-core-intern/nm-meta-setting-base.h b/src/libnm-core-intern/nm-meta-setting-base.h new file mode 100644 index 0000000..72fa8e6 --- /dev/null +++ b/src/libnm-core-intern/nm-meta-setting-base.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_META_SETTING_BASE_H__ +#define __NM_META_SETTING_BASE_H__ + +#define _NM_META_SETTING_BASE_IMPL_LIBNM 1 + +#include "nm-meta-setting-base-impl.h" + +#endif /* __NM_META_SETTING_BASE_H__ */ diff --git a/src/libnm-core-public/README.md b/src/libnm-core-public/README.md new file mode 100644 index 0000000..0737269 --- /dev/null +++ b/src/libnm-core-public/README.md @@ -0,0 +1,24 @@ +libnm-core-public +================= + +This contains (mostly) header files only, which are also part of +the public API of [`libnm`](../../libnm). + +Also, this API is implemented by the static library [`libnm-core-impl`](../libnm-core-impl), +which in turn is statically linked into NetworkManager core and [`libnm`](../../libnm). + +These headers can be used by anybody who either: + +- links (statically) against [`libnm-core-impl`](../libnm-core-impl). +- links dynamically against [`libnm`](../../libnm). + +Note that there is also one source file: `nm-core-enum-types.c`. +This source file really belongs to [`libnm-core-impl`](../libnm-core-impl) but it is here +because it's a generated file and so far I couldn't figure out how +to generate `nm-core-enum-types.h` here while moving `nm-core-enum-types.c` +to [`libnm-core-impl`](../libnm-core-impl). + +Aside `nm-core-enum-types.c`, this directory only provides header files. +Users should add this directory (both srcdir and builddir) to the include +search path, because libnm users are used to include these headers unqualified +(like `#include "nm-setting.h`). diff --git a/src/libnm-core-public/meson.build b/src/libnm-core-public/meson.build new file mode 100644 index 0000000..6b8dad0 --- /dev/null +++ b/src/libnm-core-public/meson.build @@ -0,0 +1,128 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_core_public_inc = include_directories('.') + +libnm_core_headers = files( + 'nm-connection.h', + 'nm-core-types.h', + 'nm-dbus-interface.h', + 'nm-errors.h', + 'nm-keyfile.h', + 'nm-setting-6lowpan.h', + 'nm-setting-8021x.h', + 'nm-setting-adsl.h', + 'nm-setting-bluetooth.h', + 'nm-setting-bond.h', + 'nm-setting-bridge-port.h', + 'nm-setting-bridge.h', + 'nm-setting-cdma.h', + 'nm-setting-connection.h', + 'nm-setting-dcb.h', + 'nm-setting-dummy.h', + 'nm-setting-ethtool.h', + 'nm-setting-generic.h', + 'nm-setting-gsm.h', + 'nm-setting-hostname.h', + 'nm-setting-infiniband.h', + 'nm-setting-ip-config.h', + 'nm-setting-ip-tunnel.h', + 'nm-setting-ip4-config.h', + 'nm-setting-ip6-config.h', + 'nm-setting-macsec.h', + 'nm-setting-macvlan.h', + 'nm-setting-match.h', + 'nm-setting-olpc-mesh.h', + 'nm-setting-ovs-bridge.h', + 'nm-setting-ovs-dpdk.h', + 'nm-setting-ovs-external-ids.h', + 'nm-setting-ovs-interface.h', + 'nm-setting-ovs-patch.h', + 'nm-setting-ovs-port.h', + 'nm-setting-ppp.h', + 'nm-setting-pppoe.h', + 'nm-setting-proxy.h', + 'nm-setting-serial.h', + 'nm-setting-sriov.h', + 'nm-setting-tc-config.h', + 'nm-setting-team-port.h', + 'nm-setting-team.h', + 'nm-setting-tun.h', + 'nm-setting-user.h', + 'nm-setting-veth.h', + 'nm-setting-vlan.h', + 'nm-setting-vpn.h', + 'nm-setting-vrf.h', + 'nm-setting-vxlan.h', + 'nm-setting-wifi-p2p.h', + 'nm-setting-wimax.h', + 'nm-setting-wired.h', + 'nm-setting-wireguard.h', + 'nm-setting-wireless-security.h', + 'nm-setting-wireless.h', + 'nm-setting-wpan.h', + 'nm-setting.h', + 'nm-simple-connection.h', + 'nm-utils.h', + 'nm-version.h', + 'nm-vpn-dbus-interface.h', + 'nm-vpn-editor-plugin.h', + 'nm-vpn-plugin-info.h', +) + +nm_version_macro_header = configure_file( + input: 'nm-version-macros.h.in', + output: '@BASENAME@', + configuration: data_conf, +) + +libnm_core_public_enum_sources = gnome.mkenums_simple( + 'nm-core-enum-types', + sources: libnm_core_headers + [nm_version_macro_header], + identifier_prefix: nm_id_prefix, + body_prefix: '#include "libnm-core-impl/nm-default-libnm-core.h"', + install_header: true, + install_dir: libnm_pkgincludedir, +) + +libnm_core_public_dep = declare_dependency( + sources: libnm_core_headers + [ + libnm_core_public_enum_sources[1], + nm_version_macro_header, + ], + include_directories: [ + libnm_core_public_inc, + src_inc, + top_inc, + ], + dependencies: [ + glib_dep, + ], +) + +docbooks = [ + ['nm-dbus-types', 'nm-dbus-interface.h', 'NetworkManager D-Bus API Types'], + ['nm-vpn-dbus-types', 'nm-vpn-dbus-interface.h', 'VPN Plugin D-Bus API Types'], +] + +foreach docbook: docbooks + output = docbook[0] + '.xml' + + xml = custom_target( + output, + input: docbook[1], + output: output, + capture: true, + command: [ + perl, + join_paths(source_root, 'tools', 'enums-to-docbook.pl'), + docbook[0], + docbook[2], + '@INPUT@', + ], + # FIXME: gtkdoc does not depend directly on this. + # https://github.com/mesonbuild/meson/pull/2806 + build_by_default: true, + ) + + content_files += xml.full_path() +endforeach diff --git a/src/libnm-core-public/nm-connection.h b/src/libnm-core-public/nm-connection.h new file mode 100644 index 0000000..19034e7 --- /dev/null +++ b/src/libnm-core-public/nm-connection.h @@ -0,0 +1,224 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2018 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_CONNECTION_H__ +#define __NM_CONNECTION_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-core-types.h" +#include "nm-setting.h" +#include "nm-errors.h" + +G_BEGIN_DECLS + +#define NM_TYPE_CONNECTION (nm_connection_get_type()) +#define NM_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_CONNECTION, NMConnection)) +#define NM_IS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_CONNECTION)) +#define NM_CONNECTION_GET_INTERFACE(obj) \ + (G_TYPE_INSTANCE_GET_INTERFACE((obj), NM_TYPE_CONNECTION, NMConnectionClass)) + +/* Signals */ +#define NM_CONNECTION_SECRETS_UPDATED "secrets-updated" +#define NM_CONNECTION_SECRETS_CLEARED "secrets-cleared" +#define NM_CONNECTION_CHANGED "changed" + +/* + * NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD: overwrite the ip6 method + * when normalizing ip6 configuration. If omitted, this defaults to + * @NM_SETTING_IP6_CONFIG_METHOD_AUTO. + */ +#define NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD "ip6-config-method" + +/** + * NMConnection: + * + * NMConnection is the interface implemented by #NMRemoteConnection on the + * client side, and #NMSettingsConnection on the daemon side. + */ + +/** + * NMConnectionInterface: + * @parent: the parent interface struct + * @secrets_updated: emitted when the connection's secrets are updated + * @secrets_cleared: emitted when the connection's secrets are cleared + * @changed: emitted when any change to the connection's settings occurs + */ +typedef struct { + GTypeInterface parent; + + /* Signals */ + void (*secrets_updated)(NMConnection *connection, const char *setting); + void (*secrets_cleared)(NMConnection *connection); + void (*changed)(NMConnection *connection); + +} NMConnectionInterface; + +GType nm_connection_get_type(void); + +void nm_connection_add_setting(NMConnection *connection, NMSetting *setting); + +void nm_connection_remove_setting(NMConnection *connection, GType setting_type); + +NMSetting *nm_connection_get_setting(NMConnection *connection, GType setting_type); + +NMSetting *nm_connection_get_setting_by_name(NMConnection *connection, const char *name); + +/** + * NM_VARIANT_TYPE_CONNECTION: + * + * #GVariantType for a dictionary mapping from setting names to + * %NM_VARIANT_TYPE_SETTING variants. This is used to represent an + * #NMConnection, and is the type taken by nm_simple_connection_new_from_dbus() + * and returned from nm_connection_to_dbus(). + */ +#define NM_VARIANT_TYPE_CONNECTION (G_VARIANT_TYPE("a{sa{sv}}")) + +/** + * NM_VARIANT_TYPE_SETTING: + * + * #GVariantType for a dictionary mapping from property names to values. This is + * an alias for %G_VARIANT_TYPE_VARDICT, and is the type of each element of + * an %NM_VARIANT_TYPE_CONNECTION dictionary. + */ +#define NM_VARIANT_TYPE_SETTING G_VARIANT_TYPE_VARDICT + +/** + * NMConnectionSerializationFlags: + * @NM_CONNECTION_SERIALIZE_ALL: serialize all properties (including secrets) + * @NM_CONNECTION_SERIALIZE_NO_SECRETS: do not include secrets + * @NM_CONNECTION_SERIALIZE_ONLY_SECRETS: only serialize secrets + * @NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED: if set, only secrets that + * are agent owned will be serialized. Since: 1.20. + * + * These flags determine which properties are serialized when calling when + * calling nm_connection_to_dbus(). + **/ +typedef enum { /*< flags >*/ + NM_CONNECTION_SERIALIZE_ALL = 0x00000000, + NM_CONNECTION_SERIALIZE_NO_SECRETS = 0x00000001, + NM_CONNECTION_SERIALIZE_ONLY_SECRETS = 0x00000002, + NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED = 0x00000004, +} NMConnectionSerializationFlags; + +GVariant *nm_connection_to_dbus(NMConnection *connection, NMConnectionSerializationFlags flags); + +gboolean +nm_connection_replace_settings(NMConnection *connection, GVariant *new_settings, GError **error); + +void nm_connection_replace_settings_from_connection(NMConnection *connection, + NMConnection *new_connection); + +void nm_connection_clear_settings(NMConnection *connection); + +gboolean nm_connection_compare(NMConnection *a, NMConnection *b, NMSettingCompareFlags flags); + +gboolean nm_connection_diff(NMConnection * a, + NMConnection * b, + NMSettingCompareFlags flags, + GHashTable ** out_settings); + +gboolean nm_connection_verify(NMConnection *connection, GError **error); +NM_AVAILABLE_IN_1_2 +gboolean nm_connection_verify_secrets(NMConnection *connection, GError **error); +gboolean nm_connection_normalize(NMConnection *connection, + GHashTable * parameters, + gboolean * modified, + GError ** error); + +const char *nm_connection_need_secrets(NMConnection *connection, GPtrArray **hints); + +void nm_connection_clear_secrets(NMConnection *connection); + +void nm_connection_clear_secrets_with_flags(NMConnection * connection, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data); + +gboolean nm_connection_update_secrets(NMConnection *connection, + const char * setting_name, + GVariant * secrets, + GError ** error); + +void nm_connection_set_path(NMConnection *connection, const char *path); + +const char *nm_connection_get_path(NMConnection *connection); + +const char *nm_connection_get_interface_name(NMConnection *connection); + +gboolean nm_connection_is_type(NMConnection *connection, const char *type); + +void nm_connection_for_each_setting_value(NMConnection * connection, + NMSettingValueIterFn func, + gpointer user_data); + +NM_AVAILABLE_IN_1_10 +NMSetting **nm_connection_get_settings(NMConnection *connection, guint *out_length); + +void nm_connection_dump(NMConnection *connection); + +/* Helpers */ +const char *nm_connection_get_uuid(NMConnection *connection); +const char *nm_connection_get_id(NMConnection *connection); +const char *nm_connection_get_connection_type(NMConnection *connection); + +gboolean nm_connection_is_virtual(NMConnection *connection); +char * nm_connection_get_virtual_device_description(NMConnection *connection); + +NMSetting8021x * nm_connection_get_setting_802_1x(NMConnection *connection); +NMSettingBluetooth * nm_connection_get_setting_bluetooth(NMConnection *connection); +NMSettingBond * nm_connection_get_setting_bond(NMConnection *connection); +NMSettingTeam * nm_connection_get_setting_team(NMConnection *connection); +NMSettingTeamPort * nm_connection_get_setting_team_port(NMConnection *connection); +NMSettingBridge * nm_connection_get_setting_bridge(NMConnection *connection); +NMSettingBridgePort *nm_connection_get_setting_bridge_port(NMConnection *connection); +NMSettingCdma * nm_connection_get_setting_cdma(NMConnection *connection); +NMSettingConnection *nm_connection_get_setting_connection(NMConnection *connection); +NMSettingDcb * nm_connection_get_setting_dcb(NMConnection *connection); +NM_AVAILABLE_IN_1_8 +NMSettingDummy * nm_connection_get_setting_dummy(NMConnection *connection); +NMSettingGeneric * nm_connection_get_setting_generic(NMConnection *connection); +NMSettingGsm * nm_connection_get_setting_gsm(NMConnection *connection); +NMSettingInfiniband *nm_connection_get_setting_infiniband(NMConnection *connection); +NM_AVAILABLE_IN_1_2 +NMSettingIPTunnel *nm_connection_get_setting_ip_tunnel(NMConnection *connection); +NMSettingIPConfig *nm_connection_get_setting_ip4_config(NMConnection *connection); +NMSettingIPConfig *nm_connection_get_setting_ip6_config(NMConnection *connection); +NM_AVAILABLE_IN_1_6 +NMSettingMacsec *nm_connection_get_setting_macsec(NMConnection *connection); +NM_AVAILABLE_IN_1_2 +NMSettingMacvlan * nm_connection_get_setting_macvlan(NMConnection *connection); +NMSettingOlpcMesh *nm_connection_get_setting_olpc_mesh(NMConnection *connection); +NM_AVAILABLE_IN_1_10 +NMSettingOvsBridge *nm_connection_get_setting_ovs_bridge(NMConnection *connection); +NM_AVAILABLE_IN_1_10 +NMSettingOvsInterface *nm_connection_get_setting_ovs_interface(NMConnection *connection); +NMSettingOvsPatch * nm_connection_get_setting_ovs_patch(NMConnection *connection); +NM_AVAILABLE_IN_1_10 +NMSettingOvsPort *nm_connection_get_setting_ovs_port(NMConnection *connection); +NMSettingPpp * nm_connection_get_setting_ppp(NMConnection *connection); +NMSettingPppoe * nm_connection_get_setting_pppoe(NMConnection *connection); +NM_AVAILABLE_IN_1_6 +NMSettingProxy * nm_connection_get_setting_proxy(NMConnection *connection); +NMSettingSerial *nm_connection_get_setting_serial(NMConnection *connection); +NM_AVAILABLE_IN_1_12 +NMSettingTCConfig *nm_connection_get_setting_tc_config(NMConnection *connection); +NM_AVAILABLE_IN_1_2 +NMSettingTun * nm_connection_get_setting_tun(NMConnection *connection); +NMSettingVpn * nm_connection_get_setting_vpn(NMConnection *connection); +NMSettingWimax * nm_connection_get_setting_wimax(NMConnection *connection); +NMSettingAdsl * nm_connection_get_setting_adsl(NMConnection *connection); +NMSettingWired * nm_connection_get_setting_wired(NMConnection *connection); +NMSettingWireless * nm_connection_get_setting_wireless(NMConnection *connection); +NMSettingWirelessSecurity *nm_connection_get_setting_wireless_security(NMConnection *connection); +NMSettingVlan * nm_connection_get_setting_vlan(NMConnection *connection); +NM_AVAILABLE_IN_1_2 +NMSettingVxlan *nm_connection_get_setting_vxlan(NMConnection *connection); + +G_END_DECLS + +#endif /* __NM_CONNECTION_H__ */ diff --git a/src/libnm-core-public/nm-core-types.h b/src/libnm-core-public/nm-core-types.h new file mode 100644 index 0000000..bf0c2a9 --- /dev/null +++ b/src/libnm-core-public/nm-core-types.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 - 2018 Red Hat, Inc. + */ + +#ifndef __NM_CORE_TYPES_H__ +#define __NM_CORE_TYPES_H__ + +#include + +#include "nm-version.h" +#include "nm-dbus-interface.h" +#include "nm-core-enum-types.h" + +typedef struct _NMConnection NMConnection; +typedef struct _NMSetting NMSetting; +typedef struct _NMSetting6Lowpan NMSetting6Lowpan; +typedef struct _NMSetting8021x NMSetting8021x; +typedef struct _NMSettingAdsl NMSettingAdsl; +typedef struct _NMSettingBluetooth NMSettingBluetooth; +typedef struct _NMSettingBond NMSettingBond; +typedef struct _NMSettingBridge NMSettingBridge; +typedef struct _NMSettingBridgePort NMSettingBridgePort; +typedef struct _NMSettingCdma NMSettingCdma; +typedef struct _NMSettingConnection NMSettingConnection; +typedef struct _NMSettingDcb NMSettingDcb; +typedef struct _NMSettingDummy NMSettingDummy; +typedef struct _NMSettingEthtool NMSettingEthtool; +typedef struct _NMSettingGeneric NMSettingGeneric; +typedef struct _NMSettingGsm NMSettingGsm; +typedef struct _NMSettingHostname NMSettingHostname; +typedef struct _NMSettingIP4Config NMSettingIP4Config; +typedef struct _NMSettingIP6Config NMSettingIP6Config; +typedef struct _NMSettingIPConfig NMSettingIPConfig; +typedef struct _NMSettingIPTunnel NMSettingIPTunnel; +typedef struct _NMSettingInfiniband NMSettingInfiniband; +typedef struct _NMSettingMacsec NMSettingMacsec; +typedef struct _NMSettingMacvlan NMSettingMacvlan; +typedef struct _NMSettingMatch NMSettingMatch; +typedef struct _NMSettingOlpcMesh NMSettingOlpcMesh; +typedef struct _NMSettingOvsBridge NMSettingOvsBridge; +typedef struct _NMSettingOvsDpdk NMSettingOvsDpdk; +typedef struct _NMSettingOvsExternalIDs NMSettingOvsExternalIDs; +typedef struct _NMSettingOvsInterface NMSettingOvsInterface; +typedef struct _NMSettingOvsPatch NMSettingOvsPatch; +typedef struct _NMSettingOvsPort NMSettingOvsPort; +typedef struct _NMSettingPpp NMSettingPpp; +typedef struct _NMSettingPppoe NMSettingPppoe; +typedef struct _NMSettingProxy NMSettingProxy; +typedef struct _NMSettingSerial NMSettingSerial; +typedef struct _NMSettingSriov NMSettingSriov; +typedef struct _NMSettingTCConfig NMSettingTCConfig; +typedef struct _NMSettingTeam NMSettingTeam; +typedef struct _NMSettingTeamPort NMSettingTeamPort; +typedef struct _NMSettingTun NMSettingTun; +typedef struct _NMSettingUser NMSettingUser; +typedef struct _NMSettingVeth NMSettingVeth; +typedef struct _NMSettingVlan NMSettingVlan; +typedef struct _NMSettingVpn NMSettingVpn; +typedef struct _NMSettingVrf NMSettingVrf; +typedef struct _NMSettingVxlan NMSettingVxlan; +typedef struct _NMSettingWifiP2P NMSettingWifiP2P; +typedef struct _NMSettingWimax NMSettingWimax; +typedef struct _NMSettingWired NMSettingWired; +typedef struct _NMSettingWireGuard NMSettingWireGuard; +typedef struct _NMSettingWireless NMSettingWireless; +typedef struct _NMSettingWirelessSecurity NMSettingWirelessSecurity; +typedef struct _NMSettingWpan NMSettingWpan; +typedef struct _NMSimpleConnection NMSimpleConnection; + +typedef gboolean (*NMUtilsPredicateStr)(const char *str); + +#endif /* __NM_CORE_TYPES_H__ */ diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h new file mode 100644 index 0000000..295a22a --- /dev/null +++ b/src/libnm-core-public/nm-dbus-interface.h @@ -0,0 +1,1284 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2004 - 2018 Red Hat, Inc. + */ + +/* Definitions related to NetworkManager's D-Bus interfaces. + * + * Note that although this header is installed as part of libnm, it is also + * used by some external code that does not link to libnm. + */ + +#ifndef __NM_DBUS_INTERFACE_H__ +#define __NM_DBUS_INTERFACE_H__ + +/* This header must not include glib or libnm. */ + +#ifndef NM_VERSION_H + #define NM_AVAILABLE_IN_1_2 + #define NM_AVAILABLE_IN_1_8 +#endif + +/* + * dbus services details + */ +#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager" + +#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager" +#define NM_DBUS_INTERFACE_ACCESS_POINT NM_DBUS_INTERFACE ".AccessPoint" +#define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active" +#define NM_DBUS_INTERFACE_CHECKPOINT NM_DBUS_INTERFACE ".Checkpoint" +#define NM_DBUS_INTERFACE_DEVICE NM_DBUS_INTERFACE ".Device" +#define NM_DBUS_INTERFACE_DEVICE_6LOWPAN NM_DBUS_INTERFACE_DEVICE ".Lowpan" +#define NM_DBUS_INTERFACE_DEVICE_ADSL NM_DBUS_INTERFACE_DEVICE ".Adsl" +#define NM_DBUS_INTERFACE_DEVICE_BLUETOOTH NM_DBUS_INTERFACE_DEVICE ".Bluetooth" +#define NM_DBUS_INTERFACE_DEVICE_BOND NM_DBUS_INTERFACE_DEVICE ".Bond" +#define NM_DBUS_INTERFACE_DEVICE_BRIDGE NM_DBUS_INTERFACE_DEVICE ".Bridge" +#define NM_DBUS_INTERFACE_DEVICE_DUMMY NM_DBUS_INTERFACE_DEVICE ".Dummy" +#define NM_DBUS_INTERFACE_DEVICE_GENERIC NM_DBUS_INTERFACE_DEVICE ".Generic" +#define NM_DBUS_INTERFACE_DEVICE_GRE NM_DBUS_INTERFACE_DEVICE ".Gre" +#define NM_DBUS_INTERFACE_DEVICE_INFINIBAND NM_DBUS_INTERFACE_DEVICE ".Infiniband" +#define NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL NM_DBUS_INTERFACE_DEVICE ".IPTunnel" +#define NM_DBUS_INTERFACE_DEVICE_MACSEC NM_DBUS_INTERFACE_DEVICE ".Macsec" +#define NM_DBUS_INTERFACE_DEVICE_MACVLAN NM_DBUS_INTERFACE_DEVICE ".Macvlan" +#define NM_DBUS_INTERFACE_DEVICE_MODEM NM_DBUS_INTERFACE_DEVICE ".Modem" +#define NM_DBUS_INTERFACE_DEVICE_OLPC_MESH NM_DBUS_INTERFACE_DEVICE ".OlpcMesh" +#define NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE NM_DBUS_INTERFACE_DEVICE ".OvsBridge" +#define NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE NM_DBUS_INTERFACE_DEVICE ".OvsInterface" +#define NM_DBUS_INTERFACE_DEVICE_OVS_PORT NM_DBUS_INTERFACE_DEVICE ".OvsPort" +#define NM_DBUS_INTERFACE_DEVICE_PPP NM_DBUS_INTERFACE_DEVICE ".Ppp" +#define NM_DBUS_INTERFACE_DEVICE_STATISTICS NM_DBUS_INTERFACE_DEVICE ".Statistics" +#define NM_DBUS_INTERFACE_DEVICE_TEAM NM_DBUS_INTERFACE_DEVICE ".Team" +#define NM_DBUS_INTERFACE_DEVICE_TUN NM_DBUS_INTERFACE_DEVICE ".Tun" +#define NM_DBUS_INTERFACE_DEVICE_VETH NM_DBUS_INTERFACE_DEVICE ".Veth" +#define NM_DBUS_INTERFACE_DEVICE_VLAN NM_DBUS_INTERFACE_DEVICE ".Vlan" +#define NM_DBUS_INTERFACE_DEVICE_VRF NM_DBUS_INTERFACE_DEVICE ".Vrf" +#define NM_DBUS_INTERFACE_DEVICE_VXLAN NM_DBUS_INTERFACE_DEVICE ".Vxlan" +#define NM_DBUS_INTERFACE_DEVICE_WIFI_P2P NM_DBUS_INTERFACE_DEVICE ".WifiP2P" +#define NM_DBUS_INTERFACE_DEVICE_WIMAX NM_DBUS_INTERFACE_DEVICE ".WiMax" +#define NM_DBUS_INTERFACE_DEVICE_WIRED NM_DBUS_INTERFACE_DEVICE ".Wired" +#define NM_DBUS_INTERFACE_DEVICE_WIREGUARD NM_DBUS_INTERFACE_DEVICE ".WireGuard" +#define NM_DBUS_INTERFACE_DEVICE_WIRELESS NM_DBUS_INTERFACE_DEVICE ".Wireless" +#define NM_DBUS_INTERFACE_DEVICE_WPAN NM_DBUS_INTERFACE_DEVICE ".Wpan" +#define NM_DBUS_INTERFACE_DHCP4_CONFIG NM_DBUS_INTERFACE ".DHCP4Config" +#define NM_DBUS_INTERFACE_DHCP6_CONFIG NM_DBUS_INTERFACE ".DHCP6Config" +#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config" +#define NM_DBUS_INTERFACE_IP6_CONFIG NM_DBUS_INTERFACE ".IP6Config" +#define NM_DBUS_INTERFACE_WIFI_P2P_PEER NM_DBUS_INTERFACE ".WifiP2PPeer" +#define NM_DBUS_INTERFACE_WIMAX_NSP NM_DBUS_INTERFACE ".WiMax.Nsp" + +#define NM_DBUS_PATH "/org/freedesktop/NetworkManager" +#define NM_DBUS_PATH_ACCESS_POINT NM_DBUS_PATH "/AccessPoint" +#define NM_DBUS_PATH_WIFI_P2P_PEER NM_DBUS_PATH "/WifiP2PPeer" +#define NM_DBUS_PATH_WIMAX_NSP NM_DBUS_PATH "/Nsp" + +#define NM_DBUS_INTERFACE_SETTINGS "org.freedesktop.NetworkManager.Settings" +#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManager/Settings" + +#define NM_DBUS_INTERFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManager.Settings.Connection" +#define NM_DBUS_PATH_SETTINGS_CONNECTION "/org/freedesktop/NetworkManager/Settings/Connection" +#define NM_DBUS_INTERFACE_SETTINGS_CONNECTION_SECRETS \ + "org.freedesktop.NetworkManager.Settings.Connection.Secrets" + +#define NM_DBUS_INTERFACE_AGENT_MANAGER NM_DBUS_INTERFACE ".AgentManager" +#define NM_DBUS_PATH_AGENT_MANAGER "/org/freedesktop/NetworkManager/AgentManager" + +#define NM_DBUS_INTERFACE_SECRET_AGENT NM_DBUS_INTERFACE ".SecretAgent" +#define NM_DBUS_PATH_SECRET_AGENT "/org/freedesktop/NetworkManager/SecretAgent" + +#define NM_DBUS_INTERFACE_DNS_MANAGER "org.freedesktop.NetworkManager.DnsManager" +#define NM_DBUS_PATH_DNS_MANAGER "/org/freedesktop/NetworkManager/DnsManager" + +/** + * NMCapability: + * @NM_CAPABILITY_TEAM: Teams can be managed. This means the team device plugin + * is loaded. + * @NM_CAPABILITY_OVS: OpenVSwitch can be managed. This means the OVS device plugin + * is loaded. Since: 1.24. + * + * #NMCapability names the numbers in the Capabilities property. + * Capabilities are positive numbers. They are part of stable API + * and a certain capability number is guaranteed not to change. + * + * The range 0x7000 - 0x7FFF of capabilities is guaranteed not to be + * used by upstream NetworkManager. It could thus be used for downstream + * extensions. + */ +typedef enum { + NM_CAPABILITY_TEAM = 1, + NM_CAPABILITY_OVS = 2, +} NMCapability; + +/** + * NMState: + * @NM_STATE_UNKNOWN: Networking state is unknown. This indicates a daemon error + * that makes it unable to reasonably assess the state. In such event the + * applications are expected to assume Internet connectivity might be present + * and not disable controls that require network access. + * The graphical shells may hide the network accessibility indicator altogether + * since no meaningful status indication can be provided. + * @NM_STATE_ASLEEP: Networking is not enabled, the system is being suspended or + * resumed from suspend. + * @NM_STATE_DISCONNECTED: There is no active network connection. + * The graphical shell should indicate no network connectivity and the + * applications should not attempt to access the network. + * @NM_STATE_DISCONNECTING: Network connections are being cleaned up. + * The applications should tear down their network sessions. + * @NM_STATE_CONNECTING: A network connection is being started + * The graphical shell should indicate the network is being connected while + * the applications should still make no attempts to connect the network. + * @NM_STATE_CONNECTED_LOCAL: There is only local IPv4 and/or IPv6 connectivity, + * but no default route to access the Internet. The graphical shell should + * indicate no network connectivity. + * @NM_STATE_CONNECTED_SITE: There is only site-wide IPv4 and/or IPv6 connectivity. + * This means a default route is available, but the Internet connectivity check + * (see "Connectivity" property) did not succeed. The graphical shell should + * indicate limited network connectivity. + * @NM_STATE_CONNECTED_GLOBAL: There is global IPv4 and/or IPv6 Internet connectivity + * This means the Internet connectivity check succeeded, the graphical shell should + * indicate full network connectivity. + * + * #NMState values indicate the current overall networking state. + **/ +typedef enum { + NM_STATE_UNKNOWN = 0, + NM_STATE_ASLEEP = 10, + NM_STATE_DISCONNECTED = 20, + NM_STATE_DISCONNECTING = 30, + NM_STATE_CONNECTING = 40, + NM_STATE_CONNECTED_LOCAL = 50, + NM_STATE_CONNECTED_SITE = 60, + NM_STATE_CONNECTED_GLOBAL = 70, +} NMState; + +/** + * NMConnectivityState: + * @NM_CONNECTIVITY_UNKNOWN: Network connectivity is unknown. This means the + * connectivity checks are disabled (e.g. on server installations) or has + * not run yet. The graphical shell should assume the Internet connection + * might be available and not present a captive portal window. + * @NM_CONNECTIVITY_NONE: The host is not connected to any network. There's + * no active connection that contains a default route to the internet and + * thus it makes no sense to even attempt a connectivity check. The graphical + * shell should use this state to indicate the network connection is unavailable. + * @NM_CONNECTIVITY_PORTAL: The Internet connection is hijacked by a captive + * portal gateway. The graphical shell may open a sandboxed web browser window + * (because the captive portals typically attempt a man-in-the-middle attacks + * against the https connections) for the purpose of authenticating to a gateway + * and retrigger the connectivity check with CheckConnectivity() when the + * browser window is dismissed. + * @NM_CONNECTIVITY_LIMITED: The host is connected to a network, does not appear + * to be able to reach the full Internet, but a captive portal has not been + * detected. + * @NM_CONNECTIVITY_FULL: The host is connected to a network, and + * appears to be able to reach the full Internet. + */ +typedef enum { + NM_CONNECTIVITY_UNKNOWN = 0, + NM_CONNECTIVITY_NONE = 1, + NM_CONNECTIVITY_PORTAL = 2, + NM_CONNECTIVITY_LIMITED = 3, + NM_CONNECTIVITY_FULL = 4, +} NMConnectivityState; + +/** + * NMDeviceType: + * @NM_DEVICE_TYPE_UNKNOWN: unknown device + * @NM_DEVICE_TYPE_GENERIC: generic support for unrecognized device types + * @NM_DEVICE_TYPE_ETHERNET: a wired ethernet device + * @NM_DEVICE_TYPE_WIFI: an 802.11 Wi-Fi device + * @NM_DEVICE_TYPE_UNUSED1: not used + * @NM_DEVICE_TYPE_UNUSED2: not used + * @NM_DEVICE_TYPE_BT: a Bluetooth device supporting PAN or DUN access protocols + * @NM_DEVICE_TYPE_OLPC_MESH: an OLPC XO mesh networking device + * @NM_DEVICE_TYPE_WIMAX: an 802.16e Mobile WiMAX broadband device + * @NM_DEVICE_TYPE_MODEM: a modem supporting analog telephone, CDMA/EVDO, + * GSM/UMTS, or LTE network access protocols + * @NM_DEVICE_TYPE_INFINIBAND: an IP-over-InfiniBand device + * @NM_DEVICE_TYPE_BOND: a bond master interface + * @NM_DEVICE_TYPE_VLAN: an 802.1Q VLAN interface + * @NM_DEVICE_TYPE_ADSL: ADSL modem + * @NM_DEVICE_TYPE_BRIDGE: a bridge master interface + * @NM_DEVICE_TYPE_TEAM: a team master interface + * @NM_DEVICE_TYPE_TUN: a TUN or TAP interface + * @NM_DEVICE_TYPE_IP_TUNNEL: a IP tunnel interface + * @NM_DEVICE_TYPE_MACVLAN: a MACVLAN interface + * @NM_DEVICE_TYPE_VXLAN: a VXLAN interface + * @NM_DEVICE_TYPE_VETH: a VETH interface + * @NM_DEVICE_TYPE_MACSEC: a MACsec interface + * @NM_DEVICE_TYPE_DUMMY: a dummy interface + * @NM_DEVICE_TYPE_PPP: a PPP interface + * @NM_DEVICE_TYPE_OVS_INTERFACE: a Open vSwitch interface + * @NM_DEVICE_TYPE_OVS_PORT: a Open vSwitch port + * @NM_DEVICE_TYPE_OVS_BRIDGE: a Open vSwitch bridge + * @NM_DEVICE_TYPE_WPAN: a IEEE 802.15.4 (WPAN) MAC Layer Device + * @NM_DEVICE_TYPE_6LOWPAN: 6LoWPAN interface + * @NM_DEVICE_TYPE_WIREGUARD: a WireGuard interface + * @NM_DEVICE_TYPE_WIFI_P2P: an 802.11 Wi-Fi P2P device. Since: 1.16. + * @NM_DEVICE_TYPE_VRF: A VRF (Virtual Routing and Forwarding) interface. Since: 1.24. + * + * #NMDeviceType values indicate the type of hardware represented by a + * device object. + **/ +typedef enum { + NM_DEVICE_TYPE_UNKNOWN = 0, + NM_DEVICE_TYPE_ETHERNET = 1, + NM_DEVICE_TYPE_WIFI = 2, + NM_DEVICE_TYPE_UNUSED1 = 3, + NM_DEVICE_TYPE_UNUSED2 = 4, + NM_DEVICE_TYPE_BT = 5, /* Bluetooth */ + NM_DEVICE_TYPE_OLPC_MESH = 6, + NM_DEVICE_TYPE_WIMAX = 7, + NM_DEVICE_TYPE_MODEM = 8, + NM_DEVICE_TYPE_INFINIBAND = 9, + NM_DEVICE_TYPE_BOND = 10, + NM_DEVICE_TYPE_VLAN = 11, + NM_DEVICE_TYPE_ADSL = 12, + NM_DEVICE_TYPE_BRIDGE = 13, + NM_DEVICE_TYPE_GENERIC = 14, + NM_DEVICE_TYPE_TEAM = 15, + NM_DEVICE_TYPE_TUN = 16, + NM_DEVICE_TYPE_IP_TUNNEL = 17, + NM_DEVICE_TYPE_MACVLAN = 18, + NM_DEVICE_TYPE_VXLAN = 19, + NM_DEVICE_TYPE_VETH = 20, + NM_DEVICE_TYPE_MACSEC = 21, + NM_DEVICE_TYPE_DUMMY = 22, + NM_DEVICE_TYPE_PPP = 23, + NM_DEVICE_TYPE_OVS_INTERFACE = 24, + NM_DEVICE_TYPE_OVS_PORT = 25, + NM_DEVICE_TYPE_OVS_BRIDGE = 26, + NM_DEVICE_TYPE_WPAN = 27, + NM_DEVICE_TYPE_6LOWPAN = 28, + NM_DEVICE_TYPE_WIREGUARD = 29, + NM_DEVICE_TYPE_WIFI_P2P = 30, + NM_DEVICE_TYPE_VRF = 31, +} NMDeviceType; + +/** + * NMDeviceCapabilities: + * @NM_DEVICE_CAP_NONE: device has no special capabilities + * @NM_DEVICE_CAP_NM_SUPPORTED: NetworkManager supports this device + * @NM_DEVICE_CAP_CARRIER_DETECT: this device can indicate carrier status + * @NM_DEVICE_CAP_IS_SOFTWARE: this device is a software device + * @NM_DEVICE_CAP_SRIOV: this device supports single-root I/O virtualization + * + * General device capability flags. + **/ +typedef enum { /*< flags >*/ + NM_DEVICE_CAP_NONE = 0x00000000, + NM_DEVICE_CAP_NM_SUPPORTED = 0x00000001, + NM_DEVICE_CAP_CARRIER_DETECT = 0x00000002, + NM_DEVICE_CAP_IS_SOFTWARE = 0x00000004, + NM_DEVICE_CAP_SRIOV = 0x00000008, +} NMDeviceCapabilities; + +/** + * NMDeviceWifiCapabilities: + * @NM_WIFI_DEVICE_CAP_NONE: device has no encryption/authentication capabilities + * @NM_WIFI_DEVICE_CAP_CIPHER_WEP40: device supports 40/64-bit WEP encryption + * @NM_WIFI_DEVICE_CAP_CIPHER_WEP104: device supports 104/128-bit WEP encryption + * @NM_WIFI_DEVICE_CAP_CIPHER_TKIP: device supports TKIP encryption + * @NM_WIFI_DEVICE_CAP_CIPHER_CCMP: device supports AES/CCMP encryption + * @NM_WIFI_DEVICE_CAP_WPA: device supports WPA1 authentication + * @NM_WIFI_DEVICE_CAP_RSN: device supports WPA2/RSN authentication + * @NM_WIFI_DEVICE_CAP_AP: device supports Access Point mode + * @NM_WIFI_DEVICE_CAP_ADHOC: device supports Ad-Hoc mode + * @NM_WIFI_DEVICE_CAP_FREQ_VALID: device reports frequency capabilities + * @NM_WIFI_DEVICE_CAP_FREQ_2GHZ: device supports 2.4GHz frequencies + * @NM_WIFI_DEVICE_CAP_FREQ_5GHZ: device supports 5GHz frequencies + * @NM_WIFI_DEVICE_CAP_MESH: device supports acting as a mesh point. Since: 1.20. + * @NM_WIFI_DEVICE_CAP_IBSS_RSN: device supports WPA2/RSN in an IBSS network. Since: 1.22. + * + * 802.11 specific device encryption and authentication capabilities. + **/ +typedef enum { /*< flags >*/ + NM_WIFI_DEVICE_CAP_NONE = 0x00000000, + NM_WIFI_DEVICE_CAP_CIPHER_WEP40 = 0x00000001, + NM_WIFI_DEVICE_CAP_CIPHER_WEP104 = 0x00000002, + NM_WIFI_DEVICE_CAP_CIPHER_TKIP = 0x00000004, + NM_WIFI_DEVICE_CAP_CIPHER_CCMP = 0x00000008, + NM_WIFI_DEVICE_CAP_WPA = 0x00000010, + NM_WIFI_DEVICE_CAP_RSN = 0x00000020, + NM_WIFI_DEVICE_CAP_AP = 0x00000040, + NM_WIFI_DEVICE_CAP_ADHOC = 0x00000080, + NM_WIFI_DEVICE_CAP_FREQ_VALID = 0x00000100, + NM_WIFI_DEVICE_CAP_FREQ_2GHZ = 0x00000200, + NM_WIFI_DEVICE_CAP_FREQ_5GHZ = 0x00000400, + NM_WIFI_DEVICE_CAP_MESH = 0x00001000, + NM_WIFI_DEVICE_CAP_IBSS_RSN = 0x00002000, +} NMDeviceWifiCapabilities; + +/** + * NM80211ApFlags: + * @NM_802_11_AP_FLAGS_NONE: access point has no special capabilities + * @NM_802_11_AP_FLAGS_PRIVACY: access point requires authentication and + * encryption (usually means WEP) + * @NM_802_11_AP_FLAGS_WPS: access point supports some WPS method + * @NM_802_11_AP_FLAGS_WPS_PBC: access point supports push-button WPS + * @NM_802_11_AP_FLAGS_WPS_PIN: access point supports PIN-based WPS + * + * 802.11 access point flags. + **/ +typedef enum { /*< underscore_name=nm_802_11_ap_flags, flags >*/ + NM_802_11_AP_FLAGS_NONE = 0x00000000, + NM_802_11_AP_FLAGS_PRIVACY = 0x00000001, + NM_802_11_AP_FLAGS_WPS = 0x00000002, + NM_802_11_AP_FLAGS_WPS_PBC = 0x00000004, + NM_802_11_AP_FLAGS_WPS_PIN = 0x00000008, +} NM80211ApFlags; + +/** + * NM80211ApSecurityFlags: + * @NM_802_11_AP_SEC_NONE: the access point has no special security requirements + * @NM_802_11_AP_SEC_PAIR_WEP40: 40/64-bit WEP is supported for + * pairwise/unicast encryption + * @NM_802_11_AP_SEC_PAIR_WEP104: 104/128-bit WEP is supported for + * pairwise/unicast encryption + * @NM_802_11_AP_SEC_PAIR_TKIP: TKIP is supported for pairwise/unicast encryption + * @NM_802_11_AP_SEC_PAIR_CCMP: AES/CCMP is supported for pairwise/unicast encryption + * @NM_802_11_AP_SEC_GROUP_WEP40: 40/64-bit WEP is supported for group/broadcast + * encryption + * @NM_802_11_AP_SEC_GROUP_WEP104: 104/128-bit WEP is supported for + * group/broadcast encryption + * @NM_802_11_AP_SEC_GROUP_TKIP: TKIP is supported for group/broadcast encryption + * @NM_802_11_AP_SEC_GROUP_CCMP: AES/CCMP is supported for group/broadcast + * encryption + * @NM_802_11_AP_SEC_KEY_MGMT_PSK: WPA/RSN Pre-Shared Key encryption is + * supported + * @NM_802_11_AP_SEC_KEY_MGMT_802_1X: 802.1x authentication and key management + * is supported + * @NM_802_11_AP_SEC_KEY_MGMT_SAE: WPA/RSN Simultaneous Authentication of Equals is + * supported + * @NM_802_11_AP_SEC_KEY_MGMT_OWE: WPA/RSN Opportunistic Wireless Encryption is + * supported + * @NM_802_11_AP_SEC_KEY_MGMT_OWE_TM: WPA/RSN Opportunistic Wireless Encryption + * transition mode is supported. Since: 1.26. + * @NM_802_11_AP_SEC_KEY_MGMT_EAP_SUITE_B_192: WPA3 Enterprise Suite-B 192 bit mode + * is supported. Since: 1.30. + * + * 802.11 access point security and authentication flags. These flags describe + * the current security requirements of an access point as determined from the + * access point's beacon. + **/ +typedef enum { /*< underscore_name=nm_802_11_ap_security_flags, flags >*/ + NM_802_11_AP_SEC_NONE = 0x00000000, + NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001, + NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002, + NM_802_11_AP_SEC_PAIR_TKIP = 0x00000004, + NM_802_11_AP_SEC_PAIR_CCMP = 0x00000008, + NM_802_11_AP_SEC_GROUP_WEP40 = 0x00000010, + NM_802_11_AP_SEC_GROUP_WEP104 = 0x00000020, + NM_802_11_AP_SEC_GROUP_TKIP = 0x00000040, + NM_802_11_AP_SEC_GROUP_CCMP = 0x00000080, + NM_802_11_AP_SEC_KEY_MGMT_PSK = 0x00000100, + NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x00000200, + NM_802_11_AP_SEC_KEY_MGMT_SAE = 0x00000400, + NM_802_11_AP_SEC_KEY_MGMT_OWE = 0x00000800, + NM_802_11_AP_SEC_KEY_MGMT_OWE_TM = 0x00001000, + NM_802_11_AP_SEC_KEY_MGMT_EAP_SUITE_B_192 = 0x00002000, +} NM80211ApSecurityFlags; + +/** + * NM80211Mode: + * @NM_802_11_MODE_UNKNOWN: the device or access point mode is unknown + * @NM_802_11_MODE_ADHOC: for both devices and access point objects, indicates + * the object is part of an Ad-Hoc 802.11 network without a central + * coordinating access point. + * @NM_802_11_MODE_INFRA: the device or access point is in infrastructure mode. + * For devices, this indicates the device is an 802.11 client/station. For + * access point objects, this indicates the object is an access point that + * provides connectivity to clients. + * @NM_802_11_MODE_AP: the device is an access point/hotspot. Not valid for + * access point objects; used only for hotspot mode on the local machine. + * @NM_802_11_MODE_MESH: the device is a 802.11s mesh point. Since: 1.20. + * + * Indicates the 802.11 mode an access point or device is currently in. + **/ +typedef enum { /*< underscore_name=nm_802_11_mode >*/ + NM_802_11_MODE_UNKNOWN = 0, + NM_802_11_MODE_ADHOC = 1, + NM_802_11_MODE_INFRA = 2, + NM_802_11_MODE_AP = 3, + NM_802_11_MODE_MESH = 4, +} NM80211Mode; + +/** + * NMBluetoothCapabilities: + * @NM_BT_CAPABILITY_NONE: device has no usable capabilities + * @NM_BT_CAPABILITY_DUN: device provides Dial-Up Networking capability + * @NM_BT_CAPABILITY_NAP: device provides Network Access Point capability + * + * #NMBluetoothCapabilities values indicate the usable capabilities of a + * Bluetooth device. + **/ +typedef enum { /*< flags >*/ + NM_BT_CAPABILITY_NONE = 0x00000000, + NM_BT_CAPABILITY_DUN = 0x00000001, + NM_BT_CAPABILITY_NAP = 0x00000002, +} NMBluetoothCapabilities; + +/** + * NMDeviceModemCapabilities: + * @NM_DEVICE_MODEM_CAPABILITY_NONE: modem has no usable capabilities + * @NM_DEVICE_MODEM_CAPABILITY_POTS: modem uses the analog wired telephone + * network and is not a wireless/cellular device + * @NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO: modem supports at least one of CDMA + * 1xRTT, EVDO revision 0, EVDO revision A, or EVDO revision B + * @NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS: modem supports at least one of GSM, + * GPRS, EDGE, UMTS, HSDPA, HSUPA, or HSPA+ packet switched data capability + * @NM_DEVICE_MODEM_CAPABILITY_LTE: modem has LTE data capability + * + * #NMDeviceModemCapabilities values indicate the generic radio access + * technology families a modem device supports. For more information on the + * specific access technologies the device supports use the ModemManager D-Bus + * API. + **/ +typedef enum { /*< flags >*/ + NM_DEVICE_MODEM_CAPABILITY_NONE = 0x00000000, + NM_DEVICE_MODEM_CAPABILITY_POTS = 0x00000001, + NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO = 0x00000002, + NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS = 0x00000004, + NM_DEVICE_MODEM_CAPABILITY_LTE = 0x00000008, +} NMDeviceModemCapabilities; + +/** + * NMWimaxNspNetworkType: + * @NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN: unknown network type + * @NM_WIMAX_NSP_NETWORK_TYPE_HOME: home network + * @NM_WIMAX_NSP_NETWORK_TYPE_PARTNER: partner network + * @NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER: roaming partner network + * + * WiMAX network type. + */ +typedef enum { + NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN = 0, + NM_WIMAX_NSP_NETWORK_TYPE_HOME = 1, + NM_WIMAX_NSP_NETWORK_TYPE_PARTNER = 2, + NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER = 3, +} NMWimaxNspNetworkType; + +/** + * NMDeviceState: + * @NM_DEVICE_STATE_UNKNOWN: the device's state is unknown + * @NM_DEVICE_STATE_UNMANAGED: the device is recognized, but not managed by + * NetworkManager + * @NM_DEVICE_STATE_UNAVAILABLE: the device is managed by NetworkManager, but + * is not available for use. Reasons may include the wireless switched off, + * missing firmware, no ethernet carrier, missing supplicant or modem manager, + * etc. + * @NM_DEVICE_STATE_DISCONNECTED: the device can be activated, but is currently + * idle and not connected to a network. + * @NM_DEVICE_STATE_PREPARE: the device is preparing the connection to the + * network. This may include operations like changing the MAC address, + * setting physical link properties, and anything else required to connect + * to the requested network. + * @NM_DEVICE_STATE_CONFIG: the device is connecting to the requested network. + * This may include operations like associating with the Wi-Fi AP, dialing + * the modem, connecting to the remote Bluetooth device, etc. + * @NM_DEVICE_STATE_NEED_AUTH: the device requires more information to continue + * connecting to the requested network. This includes secrets like WiFi + * passphrases, login passwords, PIN codes, etc. + * @NM_DEVICE_STATE_IP_CONFIG: the device is requesting IPv4 and/or IPv6 + * addresses and routing information from the network. + * @NM_DEVICE_STATE_IP_CHECK: the device is checking whether further action is + * required for the requested network connection. This may include checking + * whether only local network access is available, whether a captive portal + * is blocking access to the Internet, etc. + * @NM_DEVICE_STATE_SECONDARIES: the device is waiting for a secondary + * connection (like a VPN) which must activated before the device can be + * activated + * @NM_DEVICE_STATE_ACTIVATED: the device has a network connection, either local + * or global. + * @NM_DEVICE_STATE_DEACTIVATING: a disconnection from the current network + * connection was requested, and the device is cleaning up resources used for + * that connection. The network connection may still be valid. + * @NM_DEVICE_STATE_FAILED: the device failed to connect to the requested + * network and is cleaning up the connection request + **/ +typedef enum { + NM_DEVICE_STATE_UNKNOWN = 0, + NM_DEVICE_STATE_UNMANAGED = 10, + NM_DEVICE_STATE_UNAVAILABLE = 20, + NM_DEVICE_STATE_DISCONNECTED = 30, + NM_DEVICE_STATE_PREPARE = 40, + NM_DEVICE_STATE_CONFIG = 50, + NM_DEVICE_STATE_NEED_AUTH = 60, + NM_DEVICE_STATE_IP_CONFIG = 70, + NM_DEVICE_STATE_IP_CHECK = 80, + NM_DEVICE_STATE_SECONDARIES = 90, + NM_DEVICE_STATE_ACTIVATED = 100, + NM_DEVICE_STATE_DEACTIVATING = 110, + NM_DEVICE_STATE_FAILED = 120, +} NMDeviceState; + +/** + * NMDeviceStateReason: + * @NM_DEVICE_STATE_REASON_NONE: No reason given + * @NM_DEVICE_STATE_REASON_UNKNOWN: Unknown error + * @NM_DEVICE_STATE_REASON_NOW_MANAGED: Device is now managed + * @NM_DEVICE_STATE_REASON_NOW_UNMANAGED: Device is now unmanaged + * @NM_DEVICE_STATE_REASON_CONFIG_FAILED: The device could not be readied for configuration + * @NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE: IP configuration could not be reserved (no available address, timeout, etc) + * @NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED: The IP config is no longer valid + * @NM_DEVICE_STATE_REASON_NO_SECRETS: Secrets were required, but not provided + * @NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT: 802.1x supplicant disconnected + * @NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED: 802.1x supplicant configuration failed + * @NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED: 802.1x supplicant failed + * @NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT: 802.1x supplicant took too long to authenticate + * @NM_DEVICE_STATE_REASON_PPP_START_FAILED: PPP service failed to start + * @NM_DEVICE_STATE_REASON_PPP_DISCONNECT: PPP service disconnected + * @NM_DEVICE_STATE_REASON_PPP_FAILED: PPP failed + * @NM_DEVICE_STATE_REASON_DHCP_START_FAILED: DHCP client failed to start + * @NM_DEVICE_STATE_REASON_DHCP_ERROR: DHCP client error + * @NM_DEVICE_STATE_REASON_DHCP_FAILED: DHCP client failed + * @NM_DEVICE_STATE_REASON_SHARED_START_FAILED: Shared connection service failed to start + * @NM_DEVICE_STATE_REASON_SHARED_FAILED: Shared connection service failed + * @NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED: AutoIP service failed to start + * @NM_DEVICE_STATE_REASON_AUTOIP_ERROR: AutoIP service error + * @NM_DEVICE_STATE_REASON_AUTOIP_FAILED: AutoIP service failed + * @NM_DEVICE_STATE_REASON_MODEM_BUSY: The line is busy + * @NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE: No dial tone + * @NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER: No carrier could be established + * @NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT: The dialing request timed out + * @NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED: The dialing attempt failed + * @NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: Modem initialization failed + * @NM_DEVICE_STATE_REASON_GSM_APN_FAILED: Failed to select the specified APN + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING: Not searching for networks + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED: Network registration denied + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT: Network registration timed out + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED: Failed to register with the requested network + * @NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED: PIN check failed + * @NM_DEVICE_STATE_REASON_FIRMWARE_MISSING: Necessary firmware for the device may be missing + * @NM_DEVICE_STATE_REASON_REMOVED: The device was removed + * @NM_DEVICE_STATE_REASON_SLEEPING: NetworkManager went to sleep + * @NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: The device's active connection disappeared + * @NM_DEVICE_STATE_REASON_USER_REQUESTED: Device disconnected by user or client + * @NM_DEVICE_STATE_REASON_CARRIER: Carrier/link changed + * @NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: The device's existing connection was assumed + * @NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE: The supplicant is now available + * @NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND: The modem could not be found + * @NM_DEVICE_STATE_REASON_BT_FAILED: The Bluetooth connection failed or timed out + * @NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: GSM Modem's SIM Card not inserted + * @NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: GSM Modem's SIM Pin required + * @NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: GSM Modem's SIM Puk required + * @NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: GSM Modem's SIM wrong + * @NM_DEVICE_STATE_REASON_INFINIBAND_MODE: InfiniBand device does not support connected mode + * @NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: A dependency of the connection failed + * @NM_DEVICE_STATE_REASON_BR2684_FAILED: Problem with the RFC 2684 Ethernet over ADSL bridge + * @NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE: ModemManager not running + * @NM_DEVICE_STATE_REASON_SSID_NOT_FOUND: The Wi-Fi network could not be found + * @NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED: A secondary connection of the base connection failed + * @NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED: DCB or FCoE setup failed + * @NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED: teamd control failed + * @NM_DEVICE_STATE_REASON_MODEM_FAILED: Modem failed or no longer available + * @NM_DEVICE_STATE_REASON_MODEM_AVAILABLE: Modem now ready and available + * @NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: SIM PIN was incorrect + * @NM_DEVICE_STATE_REASON_NEW_ACTIVATION: New connection activation was enqueued + * @NM_DEVICE_STATE_REASON_PARENT_CHANGED: the device's parent changed + * @NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED: the device parent's management changed + * @NM_DEVICE_STATE_REASON_OVSDB_FAILED: problem communicating with Open vSwitch database + * @NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE: a duplicate IP address was detected + * @NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED: The selected IP method is not supported + * @NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED: configuration of SR-IOV parameters failed + * @NM_DEVICE_STATE_REASON_PEER_NOT_FOUND: The Wi-Fi P2P peer could not be found + * + * Device state change reason codes + */ +typedef enum { + NM_DEVICE_STATE_REASON_NONE = 0, + NM_DEVICE_STATE_REASON_UNKNOWN = 1, + NM_DEVICE_STATE_REASON_NOW_MANAGED = 2, + NM_DEVICE_STATE_REASON_NOW_UNMANAGED = 3, + NM_DEVICE_STATE_REASON_CONFIG_FAILED = 4, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE = 5, + NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED = 6, + NM_DEVICE_STATE_REASON_NO_SECRETS = 7, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT = 8, + NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED = 9, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED = 10, + NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT = 11, + NM_DEVICE_STATE_REASON_PPP_START_FAILED = 12, + NM_DEVICE_STATE_REASON_PPP_DISCONNECT = 13, + NM_DEVICE_STATE_REASON_PPP_FAILED = 14, + NM_DEVICE_STATE_REASON_DHCP_START_FAILED = 15, + NM_DEVICE_STATE_REASON_DHCP_ERROR = 16, + NM_DEVICE_STATE_REASON_DHCP_FAILED = 17, + NM_DEVICE_STATE_REASON_SHARED_START_FAILED = 18, + NM_DEVICE_STATE_REASON_SHARED_FAILED = 19, + NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED = 20, + NM_DEVICE_STATE_REASON_AUTOIP_ERROR = 21, + NM_DEVICE_STATE_REASON_AUTOIP_FAILED = 22, + NM_DEVICE_STATE_REASON_MODEM_BUSY = 23, + NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE = 24, + NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER = 25, + NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT = 26, + NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED = 27, + NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED = 28, + NM_DEVICE_STATE_REASON_GSM_APN_FAILED = 29, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING = 30, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED = 31, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT = 32, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED = 33, + NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED = 34, + NM_DEVICE_STATE_REASON_FIRMWARE_MISSING = 35, + NM_DEVICE_STATE_REASON_REMOVED = 36, + NM_DEVICE_STATE_REASON_SLEEPING = 37, + NM_DEVICE_STATE_REASON_CONNECTION_REMOVED = 38, + NM_DEVICE_STATE_REASON_USER_REQUESTED = 39, + NM_DEVICE_STATE_REASON_CARRIER = 40, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED = 41, + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE = 42, + NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND = 43, + NM_DEVICE_STATE_REASON_BT_FAILED = 44, + NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED = 45, + NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED = 46, + NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED = 47, + NM_DEVICE_STATE_REASON_GSM_SIM_WRONG = 48, + NM_DEVICE_STATE_REASON_INFINIBAND_MODE = 49, + NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED = 50, + NM_DEVICE_STATE_REASON_BR2684_FAILED = 51, + NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE = 52, + NM_DEVICE_STATE_REASON_SSID_NOT_FOUND = 53, + NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED = 54, + NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED = 55, + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED = 56, + NM_DEVICE_STATE_REASON_MODEM_FAILED = 57, + NM_DEVICE_STATE_REASON_MODEM_AVAILABLE = 58, + NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT = 59, + NM_DEVICE_STATE_REASON_NEW_ACTIVATION = 60, + NM_DEVICE_STATE_REASON_PARENT_CHANGED = 61, + NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED = 62, + NM_DEVICE_STATE_REASON_OVSDB_FAILED = 63, + NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE = 64, + NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED = 65, + NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED = 66, + NM_DEVICE_STATE_REASON_PEER_NOT_FOUND = 67, +} NMDeviceStateReason; + +/** + * NMMetered: + * @NM_METERED_UNKNOWN: The metered status is unknown + * @NM_METERED_YES: Metered, the value was explicitly configured + * @NM_METERED_NO: Not metered, the value was explicitly configured + * @NM_METERED_GUESS_YES: Metered, the value was guessed + * @NM_METERED_GUESS_NO: Not metered, the value was guessed + * + * The NMMetered enum has two different purposes: one is to configure + * "connection.metered" setting of a connection profile in #NMSettingConnection, and + * the other is to express the actual metered state of the #NMDevice at a given moment. + * + * For the connection profile only #NM_METERED_UNKNOWN, #NM_METERED_NO + * and #NM_METERED_YES are allowed. + * + * The device's metered state at runtime is determined by the profile + * which is currently active. If the profile explicitly specifies #NM_METERED_NO + * or #NM_METERED_YES, then the device's metered state is as such. + * If the connection profile leaves it undecided at #NM_METERED_UNKNOWN (the default), + * then NetworkManager tries to guess the metered state, for example based on the + * device type or on DHCP options (like Android devices exposing a "ANDROID_METERED" + * DHCP vendor option). This then leads to either #NM_METERED_GUESS_NO or #NM_METERED_GUESS_YES. + * + * Most applications probably should treat the runtime state #NM_METERED_GUESS_YES + * like #NM_METERED_YES, and all other states as not metered. + * + * Note that the per-device metered states are then combined to a global metered + * state. This is basically the metered state of the device with the best default + * route. However, that generalization of a global metered state may not be correct + * if the default routes for IPv4 and IPv6 are on different devices, or if policy + * routing is configured. In general, the global metered state tries to express whether + * the traffic is likely metered, but since that depends on the traffic itself, + * there is not one answer in all cases. Hence, an application may want to consider + * the per-device's metered states. + * + * Since: 1.2 + **/ +NM_AVAILABLE_IN_1_2 +typedef enum { + NM_METERED_UNKNOWN = 0, + NM_METERED_YES = 1, + NM_METERED_NO = 2, + NM_METERED_GUESS_YES = 3, + NM_METERED_GUESS_NO = 4, +} NMMetered; + +/** + * NMConnectionMultiConnect: + * @NM_CONNECTION_MULTI_CONNECT_DEFAULT: indicates that the per-connection + * setting is unspecified. In this case, it will fallback to the default + * value, which is %NM_CONNECTION_MULTI_CONNECT_SINGLE. + * @NM_CONNECTION_MULTI_CONNECT_SINGLE: the connection profile can only + * be active once at each moment. Activating a profile that is already active, + * will first deactivate it. + * @NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE: the profile can + * be manually activated multiple times on different devices. However, + * regarding autoconnect, the profile will autoconnect only if it is + * currently not connected otherwise. + * @NM_CONNECTION_MULTI_CONNECT_MULTIPLE: the profile can autoactivate + * and be manually activated multiple times together. + * + * Since: 1.14 + */ +typedef enum { + NM_CONNECTION_MULTI_CONNECT_DEFAULT = 0, + NM_CONNECTION_MULTI_CONNECT_SINGLE = 1, + NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE = 2, + NM_CONNECTION_MULTI_CONNECT_MULTIPLE = 3, +} NMConnectionMultiConnect; + +/** + * NMActiveConnectionState: + * @NM_ACTIVE_CONNECTION_STATE_UNKNOWN: the state of the connection is unknown + * @NM_ACTIVE_CONNECTION_STATE_ACTIVATING: a network connection is being prepared + * @NM_ACTIVE_CONNECTION_STATE_ACTIVATED: there is a connection to the network + * @NM_ACTIVE_CONNECTION_STATE_DEACTIVATING: the network connection is being + * torn down and cleaned up + * @NM_ACTIVE_CONNECTION_STATE_DEACTIVATED: the network connection is disconnected + * and will be removed + * + * #NMActiveConnectionState values indicate the state of a connection to a + * specific network while it is starting, connected, or disconnecting from that + * network. + **/ +typedef enum { + NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0, + NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1, + NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2, + NM_ACTIVE_CONNECTION_STATE_DEACTIVATING = 3, + NM_ACTIVE_CONNECTION_STATE_DEACTIVATED = 4, +} NMActiveConnectionState; + +/** + * NMActiveConnectionStateReason: + * @NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN: The reason for the active connection + * state change is unknown. + * @NM_ACTIVE_CONNECTION_STATE_REASON_NONE: No reason was given for the active + * connection state change. + * @NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED: The active connection changed + * state because the user disconnected it. + * @NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED: The active connection + * changed state because the device it was using was disconnected. + * @NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_STOPPED: The service providing the + * VPN connection was stopped. + * @NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID: The IP config of the active + * connection was invalid. + * @NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT: The connection attempt to + * the VPN service timed out. + * @NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT: A timeout occurred + * while starting the service providing the VPN connection. + * @NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED: Starting the service + * providing the VPN connection failed. + * @NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS: Necessary secrets for the + * connection were not provided. + * @NM_ACTIVE_CONNECTION_STATE_REASON_LOGIN_FAILED: Authentication to the + * server failed. + * @NM_ACTIVE_CONNECTION_STATE_REASON_CONNECTION_REMOVED: The connection was + * deleted from settings. + * @NM_ACTIVE_CONNECTION_STATE_REASON_DEPENDENCY_FAILED: Master connection of this + * connection failed to activate. + * @NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REALIZE_FAILED: Could not create the + * software device link. + * @NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REMOVED: The device this connection + * depended on disappeared. + * + * Active connection state reasons. + * + * Since: 1.8 + */ +NM_AVAILABLE_IN_1_8 +typedef enum { + NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN = 0, + NM_ACTIVE_CONNECTION_STATE_REASON_NONE = 1, + NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED = 2, + NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED = 3, + NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_STOPPED = 4, + NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID = 5, + NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT = 6, + NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT = 7, + NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED = 8, + NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS = 9, + NM_ACTIVE_CONNECTION_STATE_REASON_LOGIN_FAILED = 10, + NM_ACTIVE_CONNECTION_STATE_REASON_CONNECTION_REMOVED = 11, + NM_ACTIVE_CONNECTION_STATE_REASON_DEPENDENCY_FAILED = 12, + NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REALIZE_FAILED = 13, + NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REMOVED = 14, +} NMActiveConnectionStateReason; + +/** + * NMSecretAgentGetSecretsFlags: + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE: no special behavior; by default no + * user interaction is allowed and requests for secrets are fulfilled from + * persistent storage, or if no secrets are available an error is returned. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION: allows the request to + * interact with the user, possibly prompting via UI for secrets if any are + * required, or if none are found in persistent storage. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW: explicitly prompt for new + * secrets from the user. This flag signals that NetworkManager thinks any + * existing secrets are invalid or wrong. This flag implies that interaction + * is allowed. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED: set if the request was + * initiated by user-requested action via the D-Bus interface, as opposed to + * automatically initiated by NetworkManager in response to (for example) scan + * results or carrier changes. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_WPS_PBC_ACTIVE: indicates that WPS enrollment + * is active with PBC method. The agent may suggest that the user pushes a button + * on the router instead of supplying a PSK. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM: Internal flag, not part of + * the D-Bus API. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS: Internal flag, not part of + * the D-Bus API. + * + * #NMSecretAgentGetSecretsFlags values modify the behavior of a GetSecrets request. + */ +typedef enum { /*< flags >*/ + NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE = 0x0, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1, + NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW = 0x2, + NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED = 0x4, + NM_SECRET_AGENT_GET_SECRETS_FLAG_WPS_PBC_ACTIVE = 0x8, + + /* Internal to NM; not part of the D-Bus API */ + NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM = 0x80000000, + NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS = 0x40000000, +} NMSecretAgentGetSecretsFlags; + +/** + * NMSecretAgentCapabilities: + * @NM_SECRET_AGENT_CAPABILITY_NONE: the agent supports no special capabilities + * @NM_SECRET_AGENT_CAPABILITY_VPN_HINTS: the agent supports passing hints to + * VPN plugin authentication dialogs. + * @NM_SECRET_AGENT_CAPABILITY_LAST: bounds checking value; should not be used. + * + * #NMSecretAgentCapabilities indicate various capabilities of the agent. + */ +typedef enum /*< flags >*/ { + NM_SECRET_AGENT_CAPABILITY_NONE = 0x0, + NM_SECRET_AGENT_CAPABILITY_VPN_HINTS = 0x1, + + /* boundary value */ + NM_SECRET_AGENT_CAPABILITY_LAST = NM_SECRET_AGENT_CAPABILITY_VPN_HINTS, +} NMSecretAgentCapabilities; + +#ifndef NM_VERSION_H + #undef NM_AVAILABLE_IN_1_2 + #undef NM_AVAILABLE_IN_1_8 +#endif + +#define NM_LLDP_ATTR_RAW "raw" +#define NM_LLDP_ATTR_DESTINATION "destination" +#define NM_LLDP_ATTR_CHASSIS_ID_TYPE "chassis-id-type" +#define NM_LLDP_ATTR_CHASSIS_ID "chassis-id" +#define NM_LLDP_ATTR_PORT_ID_TYPE "port-id-type" +#define NM_LLDP_ATTR_PORT_ID "port-id" +#define NM_LLDP_ATTR_PORT_DESCRIPTION "port-description" +#define NM_LLDP_ATTR_SYSTEM_NAME "system-name" +#define NM_LLDP_ATTR_SYSTEM_DESCRIPTION "system-description" +#define NM_LLDP_ATTR_SYSTEM_CAPABILITIES "system-capabilities" +#define NM_LLDP_ATTR_MANAGEMENT_ADDRESSES "management-addresses" + +#define NM_LLDP_ATTR_IEEE_802_1_PVID "ieee-802-1-pvid" +#define NM_LLDP_ATTR_IEEE_802_1_VLANS "ieee-802-1-vlans" +#define NM_LLDP_ATTR_IEEE_802_1_PPVIDS "ieee-802-1-ppvids" + +#define NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF "ieee-802-3-mac-phy-conf" +#define NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI "ieee-802-3-power-via-mdi" +#define NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE "ieee-802-3-max-frame-size" + +#define NM_LLDP_ATTR_MUD_URL "mud-url" + +/* These are deprecated in favor of NM_LLDP_ATTR_IEEE_802_1_VLANS, + * which can report multiple VLANs */ +#define NM_LLDP_ATTR_IEEE_802_1_VID "ieee-802-1-vid" +#define NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME "ieee-802-1-vlan-name" + +/* These are deprecated in favor of NM_LLDP_ATTR_IEEE_802_1_PPVIDS, + * which can report multiple PPVIDs */ +#define NM_LLDP_ATTR_IEEE_802_1_PPVID "ieee-802-1-ppvid" +#define NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS "ieee-802-1-ppvid-flags" + +#define NM_LLDP_DEST_NEAREST_BRIDGE "nearest-bridge" +#define NM_LLDP_DEST_NEAREST_NON_TPMR_BRIDGE "nearest-non-tpmr-bridge" +#define NM_LLDP_DEST_NEAREST_CUSTOMER_BRIDGE "nearest-customer-bridge" + +/** + * NMIPTunnelMode: + * @NM_IP_TUNNEL_MODE_UNKNOWN: Unknown/unset tunnel mode + * @NM_IP_TUNNEL_MODE_IPIP: IP in IP tunnel + * @NM_IP_TUNNEL_MODE_GRE: GRE tunnel + * @NM_IP_TUNNEL_MODE_SIT: SIT tunnel + * @NM_IP_TUNNEL_MODE_ISATAP: ISATAP tunnel + * @NM_IP_TUNNEL_MODE_VTI: VTI tunnel + * @NM_IP_TUNNEL_MODE_IP6IP6: IPv6 in IPv6 tunnel + * @NM_IP_TUNNEL_MODE_IPIP6: IPv4 in IPv6 tunnel + * @NM_IP_TUNNEL_MODE_IP6GRE: IPv6 GRE tunnel + * @NM_IP_TUNNEL_MODE_VTI6: IPv6 VTI tunnel + * @NM_IP_TUNNEL_MODE_GRETAP: GRETAP tunnel + * @NM_IP_TUNNEL_MODE_IP6GRETAP: IPv6 GRETAP tunnel + * + * The tunneling mode. + * + * Since: 1.2 + */ +typedef enum { + NM_IP_TUNNEL_MODE_UNKNOWN = 0, + NM_IP_TUNNEL_MODE_IPIP = 1, + NM_IP_TUNNEL_MODE_GRE = 2, + NM_IP_TUNNEL_MODE_SIT = 3, + NM_IP_TUNNEL_MODE_ISATAP = 4, + NM_IP_TUNNEL_MODE_VTI = 5, + NM_IP_TUNNEL_MODE_IP6IP6 = 6, + NM_IP_TUNNEL_MODE_IPIP6 = 7, + NM_IP_TUNNEL_MODE_IP6GRE = 8, + NM_IP_TUNNEL_MODE_VTI6 = 9, + NM_IP_TUNNEL_MODE_GRETAP = 10, + NM_IP_TUNNEL_MODE_IP6GRETAP = 11, +} NMIPTunnelMode; + +/** + * NMCheckpointCreateFlags: + * @NM_CHECKPOINT_CREATE_FLAG_NONE: no flags + * @NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL: when creating + * a new checkpoint, destroy all existing ones. + * @NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS: upon rollback, + * delete any new connection added after the checkpoint. Since: 1.6. + * @NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES: upon rollback, + * disconnect any new device appeared after the checkpoint. Since: 1.6. + * @NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING: by default, creating + * a checkpoint fails if there are already existing checkoints that + * reference the same devices. With this flag, creation of such + * checkpoints is allowed, however, if an older checkpoint + * that references overlapping devices gets rolled back, it will + * automatically destroy this checkpoint during rollback. This + * allows to create several overlapping checkpoints in parallel, + * and rollback to them at will. With the special case that + * rolling back to an older checkpoint will invalidate all + * overlapping younger checkpoints. This opts-in that the + * checkpoint can be automatically destroyed by the rollback + * of an older checkpoint. Since: 1.12. + * + * The flags for CheckpointCreate call + * + * Since: 1.4 (gi flags generated since 1.12) + */ +typedef enum { /*< flags >*/ + NM_CHECKPOINT_CREATE_FLAG_NONE = 0, + NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL = 0x01, + NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS = 0x02, + NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES = 0x04, + NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING = 0x08, +} NMCheckpointCreateFlags; + +/** + * NMRollbackResult: + * @NM_ROLLBACK_RESULT_OK: the rollback succeeded. + * @NM_ROLLBACK_RESULT_ERR_NO_DEVICE: the device no longer exists. + * @NM_ROLLBACK_RESULT_ERR_DEVICE_UNMANAGED: the device is now unmanaged. + * @NM_ROLLBACK_RESULT_ERR_FAILED: other errors during rollback. + * + * The result of a checkpoint Rollback() operation for a specific device. + * + * Since: 1.4 + **/ +typedef enum { /*< skip >*/ + NM_ROLLBACK_RESULT_OK = 0, + NM_ROLLBACK_RESULT_ERR_NO_DEVICE = 1, + NM_ROLLBACK_RESULT_ERR_DEVICE_UNMANAGED = 2, + NM_ROLLBACK_RESULT_ERR_FAILED = 3, +} NMRollbackResult; + +/** + * NMSettingsConnectionFlags: + * @NM_SETTINGS_CONNECTION_FLAG_NONE: an alias for numeric zero, no flags set. + * @NM_SETTINGS_CONNECTION_FLAG_UNSAVED: the connection is not saved to disk. + * That either means, that the connection is in-memory only and currently + * is not backed by a file. Or, that the connection is backed by a file, + * but has modifications in-memory that were not persisted to disk. + * @NM_SETTINGS_CONNECTION_FLAG_NM_GENERATED: A connection is "nm-generated" if + * it was generated by NetworkManger. If the connection gets modified or saved + * by the user, the flag gets cleared. A nm-generated is also unsaved + * and has no backing file as it is in-memory only. + * @NM_SETTINGS_CONNECTION_FLAG_VOLATILE: The connection will be deleted + * when it disconnects. That is for in-memory connections (unsaved), which are + * currently active but deleted on disconnect. Volatile connections are + * always unsaved, but they are also no backing file on disk and are entirely + * in-memory only. + * @NM_SETTINGS_CONNECTION_FLAG_EXTERNAL: the profile was generated to represent + * an external configuration of a networking device. Since: 1.26. + * + * Flags describing the current activation state. + * + * Since: 1.12 + **/ +typedef enum { /*< flags >*/ + NM_SETTINGS_CONNECTION_FLAG_NONE = 0, + NM_SETTINGS_CONNECTION_FLAG_UNSAVED = 0x01, + NM_SETTINGS_CONNECTION_FLAG_NM_GENERATED = 0x02, + NM_SETTINGS_CONNECTION_FLAG_VOLATILE = 0x04, + NM_SETTINGS_CONNECTION_FLAG_EXTERNAL = 0x08, +} NMSettingsConnectionFlags; + +/** + * NMActivationStateFlags: + * @NM_ACTIVATION_STATE_FLAG_NONE: an alias for numeric zero, no flags set. + * @NM_ACTIVATION_STATE_FLAG_IS_MASTER: the device is a master. + * @NM_ACTIVATION_STATE_FLAG_IS_SLAVE: the device is a slave. + * @NM_ACTIVATION_STATE_FLAG_LAYER2_READY: layer2 is activated and ready. + * @NM_ACTIVATION_STATE_FLAG_IP4_READY: IPv4 setting is completed. + * @NM_ACTIVATION_STATE_FLAG_IP6_READY: IPv6 setting is completed. + * @NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES: The master has any slave devices attached. + * This only makes sense if the device is a master. + * @NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY: the lifetime + * of the activation is bound to the visibility of the connection profile, + * which in turn depends on "connection.permissions" and whether a session + * for the user exists. Since: 1.16. + * @NM_ACTIVATION_STATE_FLAG_EXTERNAL: the active connection was generated to + * represent an external configuration of a networking device. Since: 1.26. + * + * Flags describing the current activation state. + * + * Since: 1.10 + **/ +typedef enum { /*< flags >*/ + NM_ACTIVATION_STATE_FLAG_NONE = 0, + + NM_ACTIVATION_STATE_FLAG_IS_MASTER = 0x1, + NM_ACTIVATION_STATE_FLAG_IS_SLAVE = 0x2, + NM_ACTIVATION_STATE_FLAG_LAYER2_READY = 0x4, + NM_ACTIVATION_STATE_FLAG_IP4_READY = 0x8, + NM_ACTIVATION_STATE_FLAG_IP6_READY = 0x10, + NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES = 0x20, + NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY = 0x40, + NM_ACTIVATION_STATE_FLAG_EXTERNAL = 0x80, +} NMActivationStateFlags; + +/** + * NMSettingsAddConnection2Flags: + * @NM_SETTINGS_ADD_CONNECTION2_FLAG_NONE: an alias for numeric zero, no flags set. + * @NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK: to persist the connection to disk. + * @NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY: to make the connection in-memory only. + * @NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT: usually, when the connection + * has autoconnect enabled and gets added, it becomes eligible to autoconnect + * right away. Setting this flag, disables autoconnect until the connection + * is manually activated. + * + * Numeric flags for the "flags" argument of AddConnection2() D-Bus API. + * + * Since: 1.20 + */ +typedef enum { /*< flags >*/ + NM_SETTINGS_ADD_CONNECTION2_FLAG_NONE = 0, + NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK = 0x1, + NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY = 0x2, + NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT = 0x20, +} NMSettingsAddConnection2Flags; + +/** + * NMSettingsUpdate2Flags: + * @NM_SETTINGS_UPDATE2_FLAG_NONE: an alias for numeric zero, no flags set. + * @NM_SETTINGS_UPDATE2_FLAG_TO_DISK: to persist the connection to disk. + * @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY: makes the profile in-memory. + * Note that such profiles are stored in keyfile format under /run. + * If the file is already in-memory, the file in /run is updated in-place. + * Otherwise, the previous storage for the profile is left unchanged + * on disk, and the in-memory copy shadows it. + * Note that the original filename of the previous persistent storage (if any) + * is remembered. That means, when later persisting the profile again to disk, + * the file on disk will be overwritten again. + * Likewise, when finally deleting the profile, both the storage from /run + * and persistent storage are deleted (or if the persistent storage does not + * allow deletion, and nmmeta file is written to mark the UUID as deleted). + * @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED: this is almost the same + * as %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY, with one difference: when later deleting + * the profile, the original profile will not be deleted. Instead a nmmeta + * file is written to /run to indicate that the profile is gone. + * Note that if such a nmmeta tombstone file exists and hides a file in persistent + * storage, then when re-adding the profile with the same UUID, then the original + * storage is taken over again. + * @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY: this is like %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY, + * but if the connection has a corresponding file on persistent storage, the file + * will be deleted right away. If the profile is later again persisted to disk, + * a new, unused filename will be chosen. + * @NM_SETTINGS_UPDATE2_FLAG_VOLATILE: This can be specified with either + * %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY, %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED + * or %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY. + * After making the connection in-memory only, the connection is marked + * as volatile. That means, if the connection is currently not active + * it will be deleted right away. Otherwise, it is marked to for deletion + * once the connection deactivates. A volatile connection cannot autoactivate + * again (because it's about to be deleted), but a manual activation will + * clear the volatile flag. + * @NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT: usually, when the connection + * has autoconnect enabled and is modified, it becomes eligible to autoconnect + * right away. Setting this flag, disables autoconnect until the connection + * is manually activated. + * @NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY: when a profile gets modified that is + * currently active, then these changes don't take effect for the active + * device unless the profile gets reactivated or the configuration reapplied. + * There are two exceptions: by default "connection.zone" and "connection.metered" + * properties take effect immediately. Specify this flag to prevent these + * properties to take effect, so that the change is restricted to modify + * the profile. Since: 1.20. + * + * Since: 1.12 + */ +typedef enum { /*< flags >*/ + NM_SETTINGS_UPDATE2_FLAG_NONE = 0, + NM_SETTINGS_UPDATE2_FLAG_TO_DISK = 0x1, + NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY = 0x2, + NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED = 0x4, + NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY = 0x8, + NM_SETTINGS_UPDATE2_FLAG_VOLATILE = 0x10, + NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT = 0x20, + NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY = 0x40, +} NMSettingsUpdate2Flags; + +/** + * NMTernary: + * @NM_TERNARY_DEFAULT: use the globally-configured default value. + * @NM_TERNARY_FALSE: the option is disabled. + * @NM_TERNARY_TRUE: the option is enabled. + * + * An boolean value that can be overridden by a default. + * + * Since: 1.14 + **/ +typedef enum { + NM_TERNARY_DEFAULT = -1, + NM_TERNARY_FALSE = 0, + NM_TERNARY_TRUE = 1, +} NMTernary; + +/** + * NMManagerReloadFlags: + * @NM_MANAGER_RELOAD_FLAG_NONE: an alias for numeric zero, no flags set. This + * reloads everything that is supported and is identical to a SIGHUP. + * @NM_MANAGER_RELOAD_FLAG_CONF: reload the NetworkManager.conf configuration + * from disk. Note that this does not include connections, which can be + * reloaded via Setting's ReloadConnections(). + * @NM_MANAGER_RELOAD_FLAG_DNS_RC: update DNS configuration, which usually + * involves writing /etc/resolv.conf anew. + * @NM_MANAGER_RELOAD_FLAG_DNS_FULL: means to restart the DNS plugin. This + * is for example useful when using dnsmasq plugin, which uses additional + * configuration in /etc/NetworkManager/dnsmasq.d. If you edit those files, + * you can restart the DNS plugin. This action shortly interrupts name + * resolution. + * @NM_MANAGER_RELOAD_FLAG_ALL: all flags. + * + * Flags for the manager Reload() call. + * + * Since: 1.22 + */ +typedef enum { /*< flags >*/ + NM_MANAGER_RELOAD_FLAG_NONE = 0, /*< skip >*/ + NM_MANAGER_RELOAD_FLAG_CONF = 0x1, + NM_MANAGER_RELOAD_FLAG_DNS_RC = 0x2, + NM_MANAGER_RELOAD_FLAG_DNS_FULL = 0x4, + NM_MANAGER_RELOAD_FLAG_ALL = 0x7, /*< skip >*/ +} NMManagerReloadFlags; + +/** + * NMDeviceInterfaceFlags: + * @NM_DEVICE_INTERFACE_FLAG_NONE: an alias for numeric zero, no flags set. + * @NM_DEVICE_INTERFACE_FLAG_UP: the interface is enabled from the + * administrative point of view. Corresponds to kernel IFF_UP. + * @NM_DEVICE_INTERFACE_FLAG_LOWER_UP: the physical link is up. Corresponds + * to kernel IFF_LOWER_UP. + * @NM_DEVICE_INTERFACE_FLAG_CARRIER: the interface has carrier. In most + * cases this is equal to the value of @NM_DEVICE_INTERFACE_FLAG_LOWER_UP. + * However some devices have a non-standard carrier detection mechanism. + * + * Flags for a network interface. + * + * Since: 1.22 + */ +typedef enum { /*< flags >*/ + /* kernel flags */ + NM_DEVICE_INTERFACE_FLAG_NONE = 0, /*< skip >*/ + NM_DEVICE_INTERFACE_FLAG_UP = 0x1, + NM_DEVICE_INTERFACE_FLAG_LOWER_UP = 0x2, + /* NM-specific flags */ + NM_DEVICE_INTERFACE_FLAG_CARRIER = 0x10000, +} NMDeviceInterfaceFlags; + +/** + * NMClientPermission: + * @NM_CLIENT_PERMISSION_NONE: unknown or no permission + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK: controls whether networking + * can be globally enabled or disabled + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI: controls whether Wi-Fi can be + * globally enabled or disabled + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN: controls whether WWAN (3G) can be + * globally enabled or disabled + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX: controls whether WiMAX can be + * globally enabled or disabled + * @NM_CLIENT_PERMISSION_SLEEP_WAKE: controls whether the client can ask + * NetworkManager to sleep and wake + * @NM_CLIENT_PERMISSION_NETWORK_CONTROL: controls whether networking connections + * can be started, stopped, and changed + * @NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED: controls whether a password + * protected Wi-Fi hotspot can be created + * @NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN: controls whether an open Wi-Fi hotspot + * can be created + * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM: controls whether connections + * that are available to all users can be modified + * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN: controls whether connections + * owned by the current user can be modified + * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME: controls whether the + * persistent hostname can be changed + * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS: modify persistent global + * DNS configuration + * @NM_CLIENT_PERMISSION_RELOAD: controls access to Reload. + * @NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK: permission to create checkpoints. + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS: controls whether device + * statistics can be globally enabled or disabled + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK: controls whether + * connectivity check can be enabled or disabled + * @NM_CLIENT_PERMISSION_WIFI_SCAN: controls whether wifi scans can be performed + * @NM_CLIENT_PERMISSION_LAST: a reserved boundary value + * + * #NMClientPermission values indicate various permissions that NetworkManager + * clients can obtain to perform certain tasks on behalf of the current user. + **/ +typedef enum { + NM_CLIENT_PERMISSION_NONE = 0, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK = 1, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI = 2, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN = 3, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX = 4, + NM_CLIENT_PERMISSION_SLEEP_WAKE = 5, + NM_CLIENT_PERMISSION_NETWORK_CONTROL = 6, + NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED = 7, + NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN = 8, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM = 9, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN = 10, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME = 11, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS = 12, + NM_CLIENT_PERMISSION_RELOAD = 13, + NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK = 14, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS = 15, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK = 16, + NM_CLIENT_PERMISSION_WIFI_SCAN = 17, + + NM_CLIENT_PERMISSION_LAST = 17, +} NMClientPermission; + +/** + * NMClientPermissionResult: + * @NM_CLIENT_PERMISSION_RESULT_UNKNOWN: unknown or no authorization + * @NM_CLIENT_PERMISSION_RESULT_YES: the permission is available + * @NM_CLIENT_PERMISSION_RESULT_AUTH: authorization is necessary before the + * permission is available + * @NM_CLIENT_PERMISSION_RESULT_NO: permission to perform the operation is + * denied by system policy + * + * #NMClientPermissionResult values indicate what authorizations and permissions + * the user requires to obtain a given #NMClientPermission + **/ +typedef enum { + NM_CLIENT_PERMISSION_RESULT_UNKNOWN = 0, + NM_CLIENT_PERMISSION_RESULT_YES, + NM_CLIENT_PERMISSION_RESULT_AUTH, + NM_CLIENT_PERMISSION_RESULT_NO +} NMClientPermissionResult; + +#endif /* __NM_DBUS_INTERFACE_H__ */ diff --git a/src/libnm-core-public/nm-dbus-types.xml b/src/libnm-core-public/nm-dbus-types.xml new file mode 100644 index 0000000..04ea87e --- /dev/null +++ b/src/libnm-core-public/nm-dbus-types.xml @@ -0,0 +1,2171 @@ + + + + + + + NetworkManager D-Bus API Types + 3 + NetworkManager D-Bus API Types + + + NetworkManager D-Bus API Types + + + + + enum NMCapability + + NMCapability + + NMCapability names the numbers in the Capabilities property. Capabilities are positive numbers. They are part of stable API and a certain capability number is guaranteed not to change.The range 0x7000 - 0x7FFF of capabilities is guaranteed not to be used by upstream NetworkManager. It could thus be used for downstream extensions. + + Values + + + + + + + + NM_CAPABILITY_TEAM + = 1 + Teams can be managed. This means the team device plugin is loaded. + + + NM_CAPABILITY_OVS + = 2 + OpenVSwitch can be managed. This means the OVS device plugin is loaded. Since: 1.24. + + + + + + + + + enum NMState + + NMState + + NMState values indicate the current overall networking state. + + Values + + + + + + + + NM_STATE_UNKNOWN + = 0 + Networking state is unknown. This indicates a daemon error that makes it unable to reasonably assess the state. In such event the applications are expected to assume Internet connectivity might be present and not disable controls that require network access. The graphical shells may hide the network accessibility indicator altogether since no meaningful status indication can be provided. + + + NM_STATE_ASLEEP + = 10 + Networking is not enabled, the system is being suspended or resumed from suspend. + + + NM_STATE_DISCONNECTED + = 20 + There is no active network connection. The graphical shell should indicate no network connectivity and the applications should not attempt to access the network. + + + NM_STATE_DISCONNECTING + = 30 + Network connections are being cleaned up. The applications should tear down their network sessions. + + + NM_STATE_CONNECTING + = 40 + A network connection is being started The graphical shell should indicate the network is being connected while the applications should still make no attempts to connect the network. + + + NM_STATE_CONNECTED_LOCAL + = 50 + There is only local IPv4 and/or IPv6 connectivity, but no default route to access the Internet. The graphical shell should indicate no network connectivity. + + + NM_STATE_CONNECTED_SITE + = 60 + There is only site-wide IPv4 and/or IPv6 connectivity. This means a default route is available, but the Internet connectivity check (see "Connectivity" property) did not succeed. The graphical shell should indicate limited network connectivity. + + + NM_STATE_CONNECTED_GLOBAL + = 70 + There is global IPv4 and/or IPv6 Internet connectivity This means the Internet connectivity check succeeded, the graphical shell should indicate full network connectivity. + + + + + + + + + enum NMConnectivityState + + NMConnectivityState + + + + Values + + + + + + + + NM_CONNECTIVITY_UNKNOWN + = 0 + Network connectivity is unknown. This means the connectivity checks are disabled (e.g. on server installations) or has not run yet. The graphical shell should assume the Internet connection might be available and not present a captive portal window. + + + NM_CONNECTIVITY_NONE + = 1 + The host is not connected to any network. There's no active connection that contains a default route to the internet and thus it makes no sense to even attempt a connectivity check. The graphical shell should use this state to indicate the network connection is unavailable. + + + NM_CONNECTIVITY_PORTAL + = 2 + The Internet connection is hijacked by a captive portal gateway. The graphical shell may open a sandboxed web browser window (because the captive portals typically attempt a man-in-the-middle attacks against the https connections) for the purpose of authenticating to a gateway and retrigger the connectivity check with CheckConnectivity() when the browser window is dismissed. + + + NM_CONNECTIVITY_LIMITED + = 3 + The host is connected to a network, does not appear to be able to reach the full Internet, but a captive portal has not been detected. + + + NM_CONNECTIVITY_FULL + = 4 + The host is connected to a network, and appears to be able to reach the full Internet. + + + + + + + + + enum NMDeviceType + + NMDeviceType + + NMDeviceType values indicate the type of hardware represented by a device object. + + Values + + + + + + + + NM_DEVICE_TYPE_UNKNOWN + = 0 + unknown device + + + NM_DEVICE_TYPE_GENERIC + = 14 + generic support for unrecognized device types + + + NM_DEVICE_TYPE_ETHERNET + = 1 + a wired ethernet device + + + NM_DEVICE_TYPE_WIFI + = 2 + an 802.11 Wi-Fi device + + + NM_DEVICE_TYPE_UNUSED1 + = 3 + not used + + + NM_DEVICE_TYPE_UNUSED2 + = 4 + not used + + + NM_DEVICE_TYPE_BT + = 5 + a Bluetooth device supporting PAN or DUN access protocols + + + NM_DEVICE_TYPE_OLPC_MESH + = 6 + an OLPC XO mesh networking device + + + NM_DEVICE_TYPE_WIMAX + = 7 + an 802.16e Mobile WiMAX broadband device + + + NM_DEVICE_TYPE_MODEM + = 8 + a modem supporting analog telephone, CDMA/EVDO, GSM/UMTS, or LTE network access protocols + + + NM_DEVICE_TYPE_INFINIBAND + = 9 + an IP-over-InfiniBand device + + + NM_DEVICE_TYPE_BOND + = 10 + a bond master interface + + + NM_DEVICE_TYPE_VLAN + = 11 + an 802.1Q VLAN interface + + + NM_DEVICE_TYPE_ADSL + = 12 + ADSL modem + + + NM_DEVICE_TYPE_BRIDGE + = 13 + a bridge master interface + + + NM_DEVICE_TYPE_TEAM + = 15 + a team master interface + + + NM_DEVICE_TYPE_TUN + = 16 + a TUN or TAP interface + + + NM_DEVICE_TYPE_IP_TUNNEL + = 17 + a IP tunnel interface + + + NM_DEVICE_TYPE_MACVLAN + = 18 + a MACVLAN interface + + + NM_DEVICE_TYPE_VXLAN + = 19 + a VXLAN interface + + + NM_DEVICE_TYPE_VETH + = 20 + a VETH interface + + + NM_DEVICE_TYPE_MACSEC + = 21 + a MACsec interface + + + NM_DEVICE_TYPE_DUMMY + = 22 + a dummy interface + + + NM_DEVICE_TYPE_PPP + = 23 + a PPP interface + + + NM_DEVICE_TYPE_OVS_INTERFACE + = 24 + a Open vSwitch interface + + + NM_DEVICE_TYPE_OVS_PORT + = 25 + a Open vSwitch port + + + NM_DEVICE_TYPE_OVS_BRIDGE + = 26 + a Open vSwitch bridge + + + NM_DEVICE_TYPE_WPAN + = 27 + a IEEE 802.15.4 (WPAN) MAC Layer Device + + + NM_DEVICE_TYPE_6LOWPAN + = 28 + 6LoWPAN interface + + + NM_DEVICE_TYPE_WIREGUARD + = 29 + a WireGuard interface + + + NM_DEVICE_TYPE_WIFI_P2P + = 30 + an 802.11 Wi-Fi P2P device. Since: 1.16. + + + NM_DEVICE_TYPE_VRF + = 31 + A VRF (Virtual Routing and Forwarding) interface. Since: 1.24. + + + + + + + + + enum NMDeviceCapabilities + + NMDeviceCapabilities + + General device capability flags. + + Values + + + + + + + + NM_DEVICE_CAP_NONE + = 0x00000000 + device has no special capabilities + + + NM_DEVICE_CAP_NM_SUPPORTED + = 0x00000001 + NetworkManager supports this device + + + NM_DEVICE_CAP_CARRIER_DETECT + = 0x00000002 + this device can indicate carrier status + + + NM_DEVICE_CAP_IS_SOFTWARE + = 0x00000004 + this device is a software device + + + NM_DEVICE_CAP_SRIOV + = 0x00000008 + this device supports single-root I/O virtualization + + + + + + + + + enum NMDeviceWifiCapabilities + + NMDeviceWifiCapabilities + + 802.11 specific device encryption and authentication capabilities. + + Values + + + + + + + + NM_WIFI_DEVICE_CAP_NONE + = 0x00000000 + device has no encryption/authentication capabilities + + + NM_WIFI_DEVICE_CAP_CIPHER_WEP40 + = 0x00000001 + device supports 40/64-bit WEP encryption + + + NM_WIFI_DEVICE_CAP_CIPHER_WEP104 + = 0x00000002 + device supports 104/128-bit WEP encryption + + + NM_WIFI_DEVICE_CAP_CIPHER_TKIP + = 0x00000004 + device supports TKIP encryption + + + NM_WIFI_DEVICE_CAP_CIPHER_CCMP + = 0x00000008 + device supports AES/CCMP encryption + + + NM_WIFI_DEVICE_CAP_WPA + = 0x00000010 + device supports WPA1 authentication + + + NM_WIFI_DEVICE_CAP_RSN + = 0x00000020 + device supports WPA2/RSN authentication + + + NM_WIFI_DEVICE_CAP_AP + = 0x00000040 + device supports Access Point mode + + + NM_WIFI_DEVICE_CAP_ADHOC + = 0x00000080 + device supports Ad-Hoc mode + + + NM_WIFI_DEVICE_CAP_FREQ_VALID + = 0x00000100 + device reports frequency capabilities + + + NM_WIFI_DEVICE_CAP_FREQ_2GHZ + = 0x00000200 + device supports 2.4GHz frequencies + + + NM_WIFI_DEVICE_CAP_FREQ_5GHZ + = 0x00000400 + device supports 5GHz frequencies + + + NM_WIFI_DEVICE_CAP_MESH + = 0x00001000 + device supports acting as a mesh point. Since: 1.20. + + + NM_WIFI_DEVICE_CAP_IBSS_RSN + = 0x00002000 + device supports WPA2/RSN in an IBSS network. Since: 1.22. + + + + + + + + + enum NM80211ApFlags + + NM80211ApFlags + + 802.11 access point flags. + + Values + + + + + + + + NM_802_11_AP_FLAGS_NONE + = 0x00000000 + access point has no special capabilities + + + NM_802_11_AP_FLAGS_PRIVACY + = 0x00000001 + access point requires authentication and encryption (usually means WEP) + + + NM_802_11_AP_FLAGS_WPS + = 0x00000002 + access point supports some WPS method + + + NM_802_11_AP_FLAGS_WPS_PBC + = 0x00000004 + access point supports push-button WPS + + + NM_802_11_AP_FLAGS_WPS_PIN + = 0x00000008 + access point supports PIN-based WPS + + + + + + + + + enum NM80211ApSecurityFlags + + NM80211ApSecurityFlags + + 802.11 access point security and authentication flags. These flags describe the current security requirements of an access point as determined from the access point's beacon. + + Values + + + + + + + + NM_802_11_AP_SEC_NONE + = 0x00000000 + the access point has no special security requirements + + + NM_802_11_AP_SEC_PAIR_WEP40 + = 0x00000001 + 40/64-bit WEP is supported for pairwise/unicast encryption + + + NM_802_11_AP_SEC_PAIR_WEP104 + = 0x00000002 + 104/128-bit WEP is supported for pairwise/unicast encryption + + + NM_802_11_AP_SEC_PAIR_TKIP + = 0x00000004 + TKIP is supported for pairwise/unicast encryption + + + NM_802_11_AP_SEC_PAIR_CCMP + = 0x00000008 + AES/CCMP is supported for pairwise/unicast encryption + + + NM_802_11_AP_SEC_GROUP_WEP40 + = 0x00000010 + 40/64-bit WEP is supported for group/broadcast encryption + + + NM_802_11_AP_SEC_GROUP_WEP104 + = 0x00000020 + 104/128-bit WEP is supported for group/broadcast encryption + + + NM_802_11_AP_SEC_GROUP_TKIP + = 0x00000040 + TKIP is supported for group/broadcast encryption + + + NM_802_11_AP_SEC_GROUP_CCMP + = 0x00000080 + AES/CCMP is supported for group/broadcast encryption + + + NM_802_11_AP_SEC_KEY_MGMT_PSK + = 0x00000100 + WPA/RSN Pre-Shared Key encryption is supported + + + NM_802_11_AP_SEC_KEY_MGMT_802_1X + = 0x00000200 + 802.1x authentication and key management is supported + + + NM_802_11_AP_SEC_KEY_MGMT_SAE + = 0x00000400 + WPA/RSN Simultaneous Authentication of Equals is supported + + + NM_802_11_AP_SEC_KEY_MGMT_OWE + = 0x00000800 + WPA/RSN Opportunistic Wireless Encryption is supported + + + NM_802_11_AP_SEC_KEY_MGMT_OWE_TM + = 0x00001000 + WPA/RSN Opportunistic Wireless Encryption transition mode is supported. Since: 1.26. + + + NM_802_11_AP_SEC_KEY_MGMT_EAP_SUITE_B_192 + = 0x00002000 + WPA3 Enterprise Suite-B 192 bit mode is supported. Since: 1.30. + + + + + + + + + enum NM80211Mode + + NM80211Mode + + Indicates the 802.11 mode an access point or device is currently in. + + Values + + + + + + + + NM_802_11_MODE_UNKNOWN + = 0 + the device or access point mode is unknown + + + NM_802_11_MODE_ADHOC + = 1 + for both devices and access point objects, indicates the object is part of an Ad-Hoc 802.11 network without a central coordinating access point. + + + NM_802_11_MODE_INFRA + = 2 + the device or access point is in infrastructure mode. For devices, this indicates the device is an 802.11 client/station. For access point objects, this indicates the object is an access point that provides connectivity to clients. + + + NM_802_11_MODE_AP + = 3 + the device is an access point/hotspot. Not valid for access point objects; used only for hotspot mode on the local machine. + + + NM_802_11_MODE_MESH + = 4 + the device is a 802.11s mesh point. Since: 1.20. + + + + + + + + + enum NMBluetoothCapabilities + + NMBluetoothCapabilities + + NMBluetoothCapabilities values indicate the usable capabilities of a Bluetooth device. + + Values + + + + + + + + NM_BT_CAPABILITY_NONE + = 0x00000000 + device has no usable capabilities + + + NM_BT_CAPABILITY_DUN + = 0x00000001 + device provides Dial-Up Networking capability + + + NM_BT_CAPABILITY_NAP + = 0x00000002 + device provides Network Access Point capability + + + + + + + + + enum NMDeviceModemCapabilities + + NMDeviceModemCapabilities + + NMDeviceModemCapabilities values indicate the generic radio access technology families a modem device supports. For more information on the specific access technologies the device supports use the ModemManager D-Bus API. + + Values + + + + + + + + NM_DEVICE_MODEM_CAPABILITY_NONE + = 0x00000000 + modem has no usable capabilities + + + NM_DEVICE_MODEM_CAPABILITY_POTS + = 0x00000001 + modem uses the analog wired telephone network and is not a wireless/cellular device + + + NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO + = 0x00000002 + modem supports at least one of CDMA 1xRTT, EVDO revision 0, EVDO revision A, or EVDO revision B + + + NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS + = 0x00000004 + modem supports at least one of GSM, GPRS, EDGE, UMTS, HSDPA, HSUPA, or HSPA+ packet switched data capability + + + NM_DEVICE_MODEM_CAPABILITY_LTE + = 0x00000008 + modem has LTE data capability + + + + + + + + + enum NMWimaxNspNetworkType + + NMWimaxNspNetworkType + + WiMAX network type. + + Values + + + + + + + + NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN + = 0 + unknown network type + + + NM_WIMAX_NSP_NETWORK_TYPE_HOME + = 1 + home network + + + NM_WIMAX_NSP_NETWORK_TYPE_PARTNER + = 2 + partner network + + + NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER + = 3 + roaming partner network + + + + + + + + + enum NMDeviceState + + NMDeviceState + + + + Values + + + + + + + + NM_DEVICE_STATE_UNKNOWN + = 0 + the device's state is unknown + + + NM_DEVICE_STATE_UNMANAGED + = 10 + the device is recognized, but not managed by NetworkManager + + + NM_DEVICE_STATE_UNAVAILABLE + = 20 + the device is managed by NetworkManager, but is not available for use. Reasons may include the wireless switched off, missing firmware, no ethernet carrier, missing supplicant or modem manager, etc. + + + NM_DEVICE_STATE_DISCONNECTED + = 30 + the device can be activated, but is currently idle and not connected to a network. + + + NM_DEVICE_STATE_PREPARE + = 40 + the device is preparing the connection to the network. This may include operations like changing the MAC address, setting physical link properties, and anything else required to connect to the requested network. + + + NM_DEVICE_STATE_CONFIG + = 50 + the device is connecting to the requested network. This may include operations like associating with the Wi-Fi AP, dialing the modem, connecting to the remote Bluetooth device, etc. + + + NM_DEVICE_STATE_NEED_AUTH + = 60 + the device requires more information to continue connecting to the requested network. This includes secrets like WiFi passphrases, login passwords, PIN codes, etc. + + + NM_DEVICE_STATE_IP_CONFIG + = 70 + the device is requesting IPv4 and/or IPv6 addresses and routing information from the network. + + + NM_DEVICE_STATE_IP_CHECK + = 80 + the device is checking whether further action is required for the requested network connection. This may include checking whether only local network access is available, whether a captive portal is blocking access to the Internet, etc. + + + NM_DEVICE_STATE_SECONDARIES + = 90 + the device is waiting for a secondary connection (like a VPN) which must activated before the device can be activated + + + NM_DEVICE_STATE_ACTIVATED + = 100 + the device has a network connection, either local or global. + + + NM_DEVICE_STATE_DEACTIVATING + = 110 + a disconnection from the current network connection was requested, and the device is cleaning up resources used for that connection. The network connection may still be valid. + + + NM_DEVICE_STATE_FAILED + = 120 + the device failed to connect to the requested network and is cleaning up the connection request + + + + + + + + + enum NMDeviceStateReason + + NMDeviceStateReason + + Device state change reason codes + + Values + + + + + + + + NM_DEVICE_STATE_REASON_NONE + = 0 + No reason given + + + NM_DEVICE_STATE_REASON_UNKNOWN + = 1 + Unknown error + + + NM_DEVICE_STATE_REASON_NOW_MANAGED + = 2 + Device is now managed + + + NM_DEVICE_STATE_REASON_NOW_UNMANAGED + = 3 + Device is now unmanaged + + + NM_DEVICE_STATE_REASON_CONFIG_FAILED + = 4 + The device could not be readied for configuration + + + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE + = 5 + IP configuration could not be reserved (no available address, timeout, etc) + + + NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED + = 6 + The IP config is no longer valid + + + NM_DEVICE_STATE_REASON_NO_SECRETS + = 7 + Secrets were required, but not provided + + + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT + = 8 + 802.1x supplicant disconnected + + + NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED + = 9 + 802.1x supplicant configuration failed + + + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED + = 10 + 802.1x supplicant failed + + + NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT + = 11 + 802.1x supplicant took too long to authenticate + + + NM_DEVICE_STATE_REASON_PPP_START_FAILED + = 12 + PPP service failed to start + + + NM_DEVICE_STATE_REASON_PPP_DISCONNECT + = 13 + PPP service disconnected + + + NM_DEVICE_STATE_REASON_PPP_FAILED + = 14 + PPP failed + + + NM_DEVICE_STATE_REASON_DHCP_START_FAILED + = 15 + DHCP client failed to start + + + NM_DEVICE_STATE_REASON_DHCP_ERROR + = 16 + DHCP client error + + + NM_DEVICE_STATE_REASON_DHCP_FAILED + = 17 + DHCP client failed + + + NM_DEVICE_STATE_REASON_SHARED_START_FAILED + = 18 + Shared connection service failed to start + + + NM_DEVICE_STATE_REASON_SHARED_FAILED + = 19 + Shared connection service failed + + + NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED + = 20 + AutoIP service failed to start + + + NM_DEVICE_STATE_REASON_AUTOIP_ERROR + = 21 + AutoIP service error + + + NM_DEVICE_STATE_REASON_AUTOIP_FAILED + = 22 + AutoIP service failed + + + NM_DEVICE_STATE_REASON_MODEM_BUSY + = 23 + The line is busy + + + NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE + = 24 + No dial tone + + + NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER + = 25 + No carrier could be established + + + NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT + = 26 + The dialing request timed out + + + NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED + = 27 + The dialing attempt failed + + + NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED + = 28 + Modem initialization failed + + + NM_DEVICE_STATE_REASON_GSM_APN_FAILED + = 29 + Failed to select the specified APN + + + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING + = 30 + Not searching for networks + + + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED + = 31 + Network registration denied + + + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT + = 32 + Network registration timed out + + + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED + = 33 + Failed to register with the requested network + + + NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED + = 34 + PIN check failed + + + NM_DEVICE_STATE_REASON_FIRMWARE_MISSING + = 35 + Necessary firmware for the device may be missing + + + NM_DEVICE_STATE_REASON_REMOVED + = 36 + The device was removed + + + NM_DEVICE_STATE_REASON_SLEEPING + = 37 + NetworkManager went to sleep + + + NM_DEVICE_STATE_REASON_CONNECTION_REMOVED + = 38 + The device's active connection disappeared + + + NM_DEVICE_STATE_REASON_USER_REQUESTED + = 39 + Device disconnected by user or client + + + NM_DEVICE_STATE_REASON_CARRIER + = 40 + Carrier/link changed + + + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED + = 41 + The device's existing connection was assumed + + + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE + = 42 + The supplicant is now available + + + NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND + = 43 + The modem could not be found + + + NM_DEVICE_STATE_REASON_BT_FAILED + = 44 + The Bluetooth connection failed or timed out + + + NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED + = 45 + GSM Modem's SIM Card not inserted + + + NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED + = 46 + GSM Modem's SIM Pin required + + + NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED + = 47 + GSM Modem's SIM Puk required + + + NM_DEVICE_STATE_REASON_GSM_SIM_WRONG + = 48 + GSM Modem's SIM wrong + + + NM_DEVICE_STATE_REASON_INFINIBAND_MODE + = 49 + InfiniBand device does not support connected mode + + + NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED + = 50 + A dependency of the connection failed + + + NM_DEVICE_STATE_REASON_BR2684_FAILED + = 51 + Problem with the RFC 2684 Ethernet over ADSL bridge + + + NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE + = 52 + ModemManager not running + + + NM_DEVICE_STATE_REASON_SSID_NOT_FOUND + = 53 + The Wi-Fi network could not be found + + + NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED + = 54 + A secondary connection of the base connection failed + + + NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED + = 55 + DCB or FCoE setup failed + + + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED + = 56 + teamd control failed + + + NM_DEVICE_STATE_REASON_MODEM_FAILED + = 57 + Modem failed or no longer available + + + NM_DEVICE_STATE_REASON_MODEM_AVAILABLE + = 58 + Modem now ready and available + + + NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT + = 59 + SIM PIN was incorrect + + + NM_DEVICE_STATE_REASON_NEW_ACTIVATION + = 60 + New connection activation was enqueued + + + NM_DEVICE_STATE_REASON_PARENT_CHANGED + = 61 + the device's parent changed + + + NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED + = 62 + the device parent's management changed + + + NM_DEVICE_STATE_REASON_OVSDB_FAILED + = 63 + problem communicating with Open vSwitch database + + + NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE + = 64 + a duplicate IP address was detected + + + NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED + = 65 + The selected IP method is not supported + + + NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED + = 66 + configuration of SR-IOV parameters failed + + + NM_DEVICE_STATE_REASON_PEER_NOT_FOUND + = 67 + The Wi-Fi P2P peer could not be found + + + + + + + + + enum NMMetered + + NMMetered + + The NMMetered enum has two different purposes: one is to configure "connection.metered" setting of a connection profile in NMSettingConnection, and the other is to express the actual metered state of the NMDevice at a given moment.For the connection profile only NM_METERED_UNKNOWN, NM_METERED_NO and NM_METERED_YES are allowed.The device's metered state at runtime is determined by the profile which is currently active. If the profile explicitly specifies NM_METERED_NO or NM_METERED_YES, then the device's metered state is as such. If the connection profile leaves it undecided at NM_METERED_UNKNOWN (the default), then NetworkManager tries to guess the metered state, for example based on the device type or on DHCP options (like Android devices exposing a "ANDROID_METERED" DHCP vendor option). This then leads to either NM_METERED_GUESS_NO or NM_METERED_GUESS_YES.Most applications probably should treat the runtime state NM_METERED_GUESS_YES like NM_METERED_YES, and all other states as not metered.Note that the per-device metered states are then combined to a global metered state. This is basically the metered state of the device with the best default route. However, that generalization of a global metered state may not be correct if the default routes for IPv4 and IPv6 are on different devices, or if policy routing is configured. In general, the global metered state tries to express whether the traffic is likely metered, but since that depends on the traffic itself, there is not one answer in all cases. Hence, an application may want to consider the per-device's metered states.Since: 1.2 + + Values + + + + + + + + NM_METERED_UNKNOWN + = 0 + The metered status is unknown + + + NM_METERED_YES + = 1 + Metered, the value was explicitly configured + + + NM_METERED_NO + = 2 + Not metered, the value was explicitly configured + + + NM_METERED_GUESS_YES + = 3 + Metered, the value was guessed + + + NM_METERED_GUESS_NO + = 4 + Not metered, the value was guessed + + + + + + + + + enum NMConnectionMultiConnect + + NMConnectionMultiConnect + + Since: 1.14 + + Values + + + + + + + + NM_CONNECTION_MULTI_CONNECT_DEFAULT + = 0 + indicates that the per-connection setting is unspecified. In this case, it will fallback to the default value, which is %NM_CONNECTION_MULTI_CONNECT_SINGLE. + + + NM_CONNECTION_MULTI_CONNECT_SINGLE + = 1 + the connection profile can only be active once at each moment. Activating a profile that is already active, will first deactivate it. + + + NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE + = 2 + the profile can be manually activated multiple times on different devices. However, regarding autoconnect, the profile will autoconnect only if it is currently not connected otherwise. + + + NM_CONNECTION_MULTI_CONNECT_MULTIPLE + = 3 + the profile can autoactivate and be manually activated multiple times together. + + + + + + + + + enum NMActiveConnectionState + + NMActiveConnectionState + + NMActiveConnectionState values indicate the state of a connection to a specific network while it is starting, connected, or disconnecting from that network. + + Values + + + + + + + + NM_ACTIVE_CONNECTION_STATE_UNKNOWN + = 0 + the state of the connection is unknown + + + NM_ACTIVE_CONNECTION_STATE_ACTIVATING + = 1 + a network connection is being prepared + + + NM_ACTIVE_CONNECTION_STATE_ACTIVATED + = 2 + there is a connection to the network + + + NM_ACTIVE_CONNECTION_STATE_DEACTIVATING + = 3 + the network connection is being torn down and cleaned up + + + NM_ACTIVE_CONNECTION_STATE_DEACTIVATED + = 4 + the network connection is disconnected and will be removed + + + + + + + + + enum NMActiveConnectionStateReason + + NMActiveConnectionStateReason + + Active connection state reasons.Since: 1.8 + + Values + + + + + + + + NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN + = 0 + The reason for the active connection state change is unknown. + + + NM_ACTIVE_CONNECTION_STATE_REASON_NONE + = 1 + No reason was given for the active connection state change. + + + NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED + = 2 + The active connection changed state because the user disconnected it. + + + NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED + = 3 + The active connection changed state because the device it was using was disconnected. + + + NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_STOPPED + = 4 + The service providing the VPN connection was stopped. + + + NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID + = 5 + The IP config of the active connection was invalid. + + + NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT + = 6 + The connection attempt to the VPN service timed out. + + + NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT + = 7 + A timeout occurred while starting the service providing the VPN connection. + + + NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED + = 8 + Starting the service providing the VPN connection failed. + + + NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS + = 9 + Necessary secrets for the connection were not provided. + + + NM_ACTIVE_CONNECTION_STATE_REASON_LOGIN_FAILED + = 10 + Authentication to the server failed. + + + NM_ACTIVE_CONNECTION_STATE_REASON_CONNECTION_REMOVED + = 11 + The connection was deleted from settings. + + + NM_ACTIVE_CONNECTION_STATE_REASON_DEPENDENCY_FAILED + = 12 + Master connection of this connection failed to activate. + + + NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REALIZE_FAILED + = 13 + Could not create the software device link. + + + NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REMOVED + = 14 + The device this connection depended on disappeared. + + + + + + + + + enum NMSecretAgentGetSecretsFlags + + NMSecretAgentGetSecretsFlags + + NMSecretAgentGetSecretsFlags values modify the behavior of a GetSecrets request. + + Values + + + + + + + + NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE + = 0x0 + no special behavior; by default no user interaction is allowed and requests for secrets are fulfilled from persistent storage, or if no secrets are available an error is returned. + + + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION + = 0x1 + allows the request to interact with the user, possibly prompting via UI for secrets if any are required, or if none are found in persistent storage. + + + NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW + = 0x2 + explicitly prompt for new secrets from the user. This flag signals that NetworkManager thinks any existing secrets are invalid or wrong. This flag implies that interaction is allowed. + + + NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED + = 0x4 + set if the request was initiated by user-requested action via the D-Bus interface, as opposed to automatically initiated by NetworkManager in response to (for example) scan results or carrier changes. + + + NM_SECRET_AGENT_GET_SECRETS_FLAG_WPS_PBC_ACTIVE + = 0x8 + indicates that WPS enrollment is active with PBC method. The agent may suggest that the user pushes a button on the router instead of supplying a PSK. + + + NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM + = 0x80000000 + Internal flag, not part of the D-Bus API. + + + NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS + = 0x40000000 + Internal flag, not part of the D-Bus API. + + + + + + + + + enum NMSecretAgentCapabilities + + NMSecretAgentCapabilities + + NMSecretAgentCapabilities indicate various capabilities of the agent. + + Values + + + + + + + + NM_SECRET_AGENT_CAPABILITY_NONE + = 0x0 + the agent supports no special capabilities + + + NM_SECRET_AGENT_CAPABILITY_VPN_HINTS + = 0x1 + the agent supports passing hints to VPN plugin authentication dialogs. + + + + + + + + + enum NMIPTunnelMode + + NMIPTunnelMode + + The tunneling mode.Since: 1.2 + + Values + + + + + + + + NM_IP_TUNNEL_MODE_UNKNOWN + = 0 + Unknown/unset tunnel mode + + + NM_IP_TUNNEL_MODE_IPIP + = 1 + IP in IP tunnel + + + NM_IP_TUNNEL_MODE_GRE + = 2 + GRE tunnel + + + NM_IP_TUNNEL_MODE_SIT + = 3 + SIT tunnel + + + NM_IP_TUNNEL_MODE_ISATAP + = 4 + ISATAP tunnel + + + NM_IP_TUNNEL_MODE_VTI + = 5 + VTI tunnel + + + NM_IP_TUNNEL_MODE_IP6IP6 + = 6 + IPv6 in IPv6 tunnel + + + NM_IP_TUNNEL_MODE_IPIP6 + = 7 + IPv4 in IPv6 tunnel + + + NM_IP_TUNNEL_MODE_IP6GRE + = 8 + IPv6 GRE tunnel + + + NM_IP_TUNNEL_MODE_VTI6 + = 9 + IPv6 VTI tunnel + + + NM_IP_TUNNEL_MODE_GRETAP + = 10 + GRETAP tunnel + + + NM_IP_TUNNEL_MODE_IP6GRETAP + = 11 + IPv6 GRETAP tunnel + + + + + + + + + enum NMCheckpointCreateFlags + + NMCheckpointCreateFlags + + The flags for CheckpointCreate callSince: 1.4 (gi flags generated since 1.12) + + Values + + + + + + + + NM_CHECKPOINT_CREATE_FLAG_NONE + = 0 + no flags + + + NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL + = 0x01 + when creating a new checkpoint, destroy all existing ones. + + + NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS + = 0x02 + upon rollback, delete any new connection added after the checkpoint. Since: 1.6. + + + NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES + = 0x04 + upon rollback, disconnect any new device appeared after the checkpoint. Since: 1.6. + + + NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING + = 0x08 + by default, creating a checkpoint fails if there are already existing checkoints that reference the same devices. With this flag, creation of such checkpoints is allowed, however, if an older checkpoint that references overlapping devices gets rolled back, it will automatically destroy this checkpoint during rollback. This allows to create several overlapping checkpoints in parallel, and rollback to them at will. With the special case that rolling back to an older checkpoint will invalidate all overlapping younger checkpoints. This opts-in that the checkpoint can be automatically destroyed by the rollback of an older checkpoint. Since: 1.12. + + + + + + + + + enum NMRollbackResult + + NMRollbackResult + + The result of a checkpoint Rollback() operation for a specific device.Since: 1.4 + + Values + + + + + + + + NM_ROLLBACK_RESULT_OK + = 0 + the rollback succeeded. + + + NM_ROLLBACK_RESULT_ERR_NO_DEVICE + = 1 + the device no longer exists. + + + NM_ROLLBACK_RESULT_ERR_DEVICE_UNMANAGED + = 2 + the device is now unmanaged. + + + NM_ROLLBACK_RESULT_ERR_FAILED + = 3 + other errors during rollback. + + + + + + + + + enum NMSettingsConnectionFlags + + NMSettingsConnectionFlags + + Flags describing the current activation state.Since: 1.12 + + Values + + + + + + + + NM_SETTINGS_CONNECTION_FLAG_NONE + = 0 + an alias for numeric zero, no flags set. + + + NM_SETTINGS_CONNECTION_FLAG_UNSAVED + = 0x01 + the connection is not saved to disk. That either means, that the connection is in-memory only and currently is not backed by a file. Or, that the connection is backed by a file, but has modifications in-memory that were not persisted to disk. + + + NM_SETTINGS_CONNECTION_FLAG_NM_GENERATED + = 0x02 + A connection is "nm-generated" if it was generated by NetworkManger. If the connection gets modified or saved by the user, the flag gets cleared. A nm-generated is also unsaved and has no backing file as it is in-memory only. + + + NM_SETTINGS_CONNECTION_FLAG_VOLATILE + = 0x04 + The connection will be deleted when it disconnects. That is for in-memory connections (unsaved), which are currently active but deleted on disconnect. Volatile connections are always unsaved, but they are also no backing file on disk and are entirely in-memory only. + + + NM_SETTINGS_CONNECTION_FLAG_EXTERNAL + = 0x08 + the profile was generated to represent an external configuration of a networking device. Since: 1.26. + + + + + + + + + enum NMActivationStateFlags + + NMActivationStateFlags + + Flags describing the current activation state.Since: 1.10 + + Values + + + + + + + + NM_ACTIVATION_STATE_FLAG_NONE + = 0 + an alias for numeric zero, no flags set. + + + NM_ACTIVATION_STATE_FLAG_IS_MASTER + = 0x1 + the device is a master. + + + NM_ACTIVATION_STATE_FLAG_IS_SLAVE + = 0x2 + the device is a slave. + + + NM_ACTIVATION_STATE_FLAG_LAYER2_READY + = 0x4 + layer2 is activated and ready. + + + NM_ACTIVATION_STATE_FLAG_IP4_READY + = 0x8 + IPv4 setting is completed. + + + NM_ACTIVATION_STATE_FLAG_IP6_READY + = 0x10 + IPv6 setting is completed. + + + NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES + = 0x20 + The master has any slave devices attached. This only makes sense if the device is a master. + + + NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY + = 0x40 + the lifetime of the activation is bound to the visibility of the connection profile, which in turn depends on "connection.permissions" and whether a session for the user exists. Since: 1.16. + + + NM_ACTIVATION_STATE_FLAG_EXTERNAL + = 0x80 + the active connection was generated to represent an external configuration of a networking device. Since: 1.26. + + + + + + + + + enum NMSettingsAddConnection2Flags + + NMSettingsAddConnection2Flags + + Numeric flags for the "flags" argument of AddConnection2() D-Bus API.Since: 1.20 + + Values + + + + + + + + NM_SETTINGS_ADD_CONNECTION2_FLAG_NONE + = 0 + an alias for numeric zero, no flags set. + + + NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK + = 0x1 + to persist the connection to disk. + + + NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY + = 0x2 + to make the connection in-memory only. + + + NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT + = 0x20 + usually, when the connection has autoconnect enabled and gets added, it becomes eligible to autoconnect right away. Setting this flag, disables autoconnect until the connection is manually activated. + + + + + + + + + enum NMSettingsUpdate2Flags + + NMSettingsUpdate2Flags + + Since: 1.12 + + Values + + + + + + + + NM_SETTINGS_UPDATE2_FLAG_NONE + = 0 + an alias for numeric zero, no flags set. + + + NM_SETTINGS_UPDATE2_FLAG_TO_DISK + = 0x1 + to persist the connection to disk. + + + NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY + = 0x2 + makes the profile in-memory. Note that such profiles are stored in keyfile format under /run. If the file is already in-memory, the file in /run is updated in-place. Otherwise, the previous storage for the profile is left unchanged on disk, and the in-memory copy shadows it. Note that the original filename of the previous persistent storage (if any) is remembered. That means, when later persisting the profile again to disk, the file on disk will be overwritten again. Likewise, when finally deleting the profile, both the storage from /run and persistent storage are deleted (or if the persistent storage does not allow deletion, and nmmeta file is written to mark the UUID as deleted). + + + NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED + = 0x4 + this is almost the same as %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY, with one difference: when later deleting the profile, the original profile will not be deleted. Instead a nmmeta file is written to /run to indicate that the profile is gone. Note that if such a nmmeta tombstone file exists and hides a file in persistent storage, then when re-adding the profile with the same UUID, then the original storage is taken over again. + + + NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY + = 0x8 + this is like %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY, but if the connection has a corresponding file on persistent storage, the file will be deleted right away. If the profile is later again persisted to disk, a new, unused filename will be chosen. + + + NM_SETTINGS_UPDATE2_FLAG_VOLATILE + = 0x10 + This can be specified with either %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY, %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED or %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY. After making the connection in-memory only, the connection is marked as volatile. That means, if the connection is currently not active it will be deleted right away. Otherwise, it is marked to for deletion once the connection deactivates. A volatile connection cannot autoactivate again (because it's about to be deleted), but a manual activation will clear the volatile flag. + + + NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT + = 0x20 + usually, when the connection has autoconnect enabled and is modified, it becomes eligible to autoconnect right away. Setting this flag, disables autoconnect until the connection is manually activated. + + + NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY + = 0x40 + when a profile gets modified that is currently active, then these changes don't take effect for the active device unless the profile gets reactivated or the configuration reapplied. There are two exceptions: by default "connection.zone" and "connection.metered" properties take effect immediately. Specify this flag to prevent these properties to take effect, so that the change is restricted to modify the profile. Since: 1.20. + + + + + + + + + enum NMTernary + + NMTernary + + An boolean value that can be overridden by a default.Since: 1.14 + + Values + + + + + + + + NM_TERNARY_DEFAULT + = -1 + use the globally-configured default value. + + + NM_TERNARY_FALSE + = 0 + the option is disabled. + + + NM_TERNARY_TRUE + = 1 + the option is enabled. + + + + + + + + + enum NMManagerReloadFlags + + NMManagerReloadFlags + + Flags for the manager Reload() call.Since: 1.22 + + Values + + + + + + + + NM_MANAGER_RELOAD_FLAG_NONE + = 0 + an alias for numeric zero, no flags set. This reloads everything that is supported and is identical to a SIGHUP. + + + NM_MANAGER_RELOAD_FLAG_CONF + = 0x1 + reload the NetworkManager.conf configuration from disk. Note that this does not include connections, which can be reloaded via Setting's ReloadConnections(). + + + NM_MANAGER_RELOAD_FLAG_DNS_RC + = 0x2 + update DNS configuration, which usually involves writing /etc/resolv.conf anew. + + + NM_MANAGER_RELOAD_FLAG_DNS_FULL + = 0x4 + means to restart the DNS plugin. This is for example useful when using dnsmasq plugin, which uses additional configuration in /etc/NetworkManager/dnsmasq.d. If you edit those files, you can restart the DNS plugin. This action shortly interrupts name resolution. + + + NM_MANAGER_RELOAD_FLAG_ALL + = 0x7 + all flags. + + + + + + + + + enum NMDeviceInterfaceFlags + + NMDeviceInterfaceFlags + + Flags for a network interface.Since: 1.22 + + Values + + + + + + + + NM_DEVICE_INTERFACE_FLAG_NONE + = 0 + an alias for numeric zero, no flags set. + + + NM_DEVICE_INTERFACE_FLAG_UP + = 0x1 + the interface is enabled from the administrative point of view. Corresponds to kernel IFF_UP. + + + NM_DEVICE_INTERFACE_FLAG_LOWER_UP + = 0x2 + the physical link is up. Corresponds to kernel IFF_LOWER_UP. + + + NM_DEVICE_INTERFACE_FLAG_CARRIER + = 0x10000 + the interface has carrier. In most cases this is equal to the value of @NM_DEVICE_INTERFACE_FLAG_LOWER_UP. However some devices have a non-standard carrier detection mechanism. + + + + + + + + + enum NMClientPermission + + NMClientPermission + + NMClientPermission values indicate various permissions that NetworkManager clients can obtain to perform certain tasks on behalf of the current user. + + Values + + + + + + + + NM_CLIENT_PERMISSION_NONE + = 0 + unknown or no permission + + + NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK + = 1 + controls whether networking can be globally enabled or disabled + + + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI + = 2 + controls whether Wi-Fi can be globally enabled or disabled + + + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN + = 3 + controls whether WWAN (3G) can be globally enabled or disabled + + + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX + = 4 + controls whether WiMAX can be globally enabled or disabled + + + NM_CLIENT_PERMISSION_SLEEP_WAKE + = 5 + controls whether the client can ask NetworkManager to sleep and wake + + + NM_CLIENT_PERMISSION_NETWORK_CONTROL + = 6 + controls whether networking connections can be started, stopped, and changed + + + NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED + = 7 + controls whether a password protected Wi-Fi hotspot can be created + + + NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN + = 8 + controls whether an open Wi-Fi hotspot can be created + + + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM + = 9 + controls whether connections that are available to all users can be modified + + + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN + = 10 + controls whether connections owned by the current user can be modified + + + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME + = 11 + controls whether the persistent hostname can be changed + + + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS + = 12 + modify persistent global DNS configuration + + + NM_CLIENT_PERMISSION_RELOAD + = 13 + controls access to Reload. + + + NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK + = 14 + permission to create checkpoints. + + + NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS + = 15 + controls whether device statistics can be globally enabled or disabled + + + NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK + = 16 + controls whether connectivity check can be enabled or disabled + + + NM_CLIENT_PERMISSION_WIFI_SCAN + = 17 + controls whether wifi scans can be performed + + + + + + + + + enum NMClientPermissionResult + + NMClientPermissionResult + + NMClientPermissionResult values indicate what authorizations and permissions the user requires to obtain a given NMClientPermission + + Values + + + + + + + + NM_CLIENT_PERMISSION_RESULT_UNKNOWN + = 0 + unknown or no authorization + + + NM_CLIENT_PERMISSION_RESULT_YES + = 1 + the permission is available + + + NM_CLIENT_PERMISSION_RESULT_AUTH + = 2 + authorization is necessary before the permission is available + + + NM_CLIENT_PERMISSION_RESULT_NO + = 3 + permission to perform the operation is denied by system policy + + + + + + + + diff --git a/src/libnm-core-public/nm-errors.h b/src/libnm-core-public/nm-errors.h new file mode 100644 index 0000000..639c508 --- /dev/null +++ b/src/libnm-core-public/nm-errors.h @@ -0,0 +1,319 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2004 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_ERRORS_H__ +#define __NM_ERRORS_H__ + +/** + * NMAgentManagerError: + * @NM_AGENT_MANAGER_ERROR_FAILED: unknown or unspecified error + * @NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED: The caller does not have permission + * to register a secret agent, or is trying to register the same secret agent + * twice. + * @NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER: The identifier is not a valid + * secret agent identifier. + * @NM_AGENT_MANAGER_ERROR_NOT_REGISTERED: The caller tried to unregister an agent + * that was not registered. + * @NM_AGENT_MANAGER_ERROR_NO_SECRETS: No secret agent returned secrets for this + * request + * @NM_AGENT_MANAGER_ERROR_USER_CANCELED: The user canceled the secrets request. + * + * Errors returned from the secret-agent manager. + * + * These errors may be returned from operations that could cause secrets to be + * requested (such as nm_client_activate_connection()), and correspond to D-Bus + * errors in the "org.freedesktop.NetworkManager.AgentManager" namespace. + */ +typedef enum { + NM_AGENT_MANAGER_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, /*< nick=InvalidIdentifier >*/ + NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, /*< nick=NotRegistered >*/ + NM_AGENT_MANAGER_ERROR_NO_SECRETS, /*< nick=NoSecrets >*/ + NM_AGENT_MANAGER_ERROR_USER_CANCELED, /*< nick=UserCanceled >*/ +} NMAgentManagerError; + +GQuark nm_agent_manager_error_quark(void); +#define NM_AGENT_MANAGER_ERROR (nm_agent_manager_error_quark()) + +/** + * NMConnectionError: + * @NM_CONNECTION_ERROR_FAILED: unknown or unclassified error + * @NM_CONNECTION_ERROR_SETTING_NOT_FOUND: the #NMConnection object + * did not contain the specified #NMSetting object + * @NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND: the #NMConnection did not contain the + * requested #NMSetting property + * @NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET: an operation which requires a secret + * was attempted on a non-secret property + * @NM_CONNECTION_ERROR_MISSING_SETTING: the #NMConnection object is missing an + * #NMSetting which is required for its configuration. The error message will + * always be prefixed with "<setting-name>: ", where "<setting-name>" is the + * name of the setting that is missing. + * @NM_CONNECTION_ERROR_INVALID_SETTING: the #NMConnection object contains an + * invalid or inappropriate #NMSetting. The error message will always be + * prefixed with "<setting-name>: ", where "<setting-name>" is the name of the + * setting that is invalid. + * @NM_CONNECTION_ERROR_MISSING_PROPERTY: the #NMConnection object is invalid + * because it is missing a required property. The error message will always be + * prefixed with "<setting-name>.<property-name>: ", where "<setting-name>" is + * the name of the setting with the missing property, and "<property-name>" is + * the property that is missing. + * @NM_CONNECTION_ERROR_INVALID_PROPERTY: the #NMConnection object is invalid + * because a property has an invalid value. The error message will always be + * prefixed with "<setting-name>.<property-name>: ", where "<setting-name>" is + * the name of the setting with the invalid property, and "<property-name>" is + * the property that is invalid. + * + * Describes errors that may result from operations involving a #NMConnection + * or its #NMSettings. + * + * These errors may be returned directly from #NMConnection and #NMSetting + * methods, or may be returned from D-Bus operations (eg on #NMClient or + * #NMDevice), where they correspond to errors in the + * "org.freedesktop.NetworkManager.Settings.Connection" namespace. + */ +typedef enum { + NM_CONNECTION_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, /*< nick=SettingNotFound >*/ + NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND, /*< nick=PropertyNotFound >*/ + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, /*< nick=PropertyNotSecret >*/ + NM_CONNECTION_ERROR_MISSING_SETTING, /*< nick=MissingSetting >*/ + NM_CONNECTION_ERROR_INVALID_SETTING, /*< nick=InvalidSetting >*/ + NM_CONNECTION_ERROR_MISSING_PROPERTY, /*< nick=MissingProperty >*/ + NM_CONNECTION_ERROR_INVALID_PROPERTY, /*< nick=InvalidProperty >*/ +} NMConnectionError; + +#define NM_CONNECTION_ERROR nm_connection_error_quark() +GQuark nm_connection_error_quark(void); + +/** + * NMCryptoError: + * @NM_CRYPTO_ERROR_FAILED: generic failure + * @NM_CRYPTO_ERROR_INVALID_DATA: the certificate or key data provided + * was invalid + * @NM_CRYPTO_ERROR_INVALID_PASSWORD: the password was invalid + * @NM_CRYPTO_ERROR_UNKNOWN_CIPHER: the data uses an unknown cipher + * @NM_CRYPTO_ERROR_DECRYPTION_FAILED: decryption failed + * @NM_CRYPTO_ERROR_ENCRYPTION_FAILED: encryption failed + * + * Cryptography-related errors that can be returned from some nm-utils methods, + * and some #NMSetting8021x operations. + */ +typedef enum { + NM_CRYPTO_ERROR_FAILED = 0, + NM_CRYPTO_ERROR_INVALID_DATA, + NM_CRYPTO_ERROR_INVALID_PASSWORD, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, +} NMCryptoError; + +#define NM_CRYPTO_ERROR nm_crypto_error_quark() +GQuark nm_crypto_error_quark(void); + +/** + * NMDeviceError: + * @NM_DEVICE_ERROR_FAILED: unknown or unclassified error + * @NM_DEVICE_ERROR_CREATION_FAILED: NetworkManager failed to create the device + * @NM_DEVICE_ERROR_INVALID_CONNECTION: the specified connection is not valid + * @NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION: the specified connection is not + * compatible with this device. + * @NM_DEVICE_ERROR_NOT_ACTIVE: the device does not have an active connection + * @NM_DEVICE_ERROR_NOT_SOFTWARE: the requested operation is only valid on + * software devices. + * @NM_DEVICE_ERROR_NOT_ALLOWED: the requested operation is not allowed at + * this time. + * @NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND: the "specific object" in the + * activation request (eg, the #NMAccessPoint or #NMWimaxNsp) was not + * found. + * @NM_DEVICE_ERROR_VERSION_ID_MISMATCH: the version id did not match. + * @NM_DEVICE_ERROR_MISSING_DEPENDENCIES: the requested operation could not + * be completed due to missing dependencies. + * @NM_DEVICE_ERROR_INVALID_ARGUMENT: invalid argument. Since: 1.16. + * + * Device-related errors. + * + * These errors may be returned directly from #NMDevice methods, or may be + * returned from D-Bus operations (where they correspond to errors in the + * "org.freedesktop.NetworkManager.Device" namespace). + */ +typedef enum { + NM_DEVICE_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_DEVICE_ERROR_CREATION_FAILED, /*< nick=CreationFailed >*/ + NM_DEVICE_ERROR_INVALID_CONNECTION, /*< nick=InvalidConnection >*/ + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, /*< nick=IncompatibleConnection >*/ + NM_DEVICE_ERROR_NOT_ACTIVE, /*< nick=NotActive >*/ + NM_DEVICE_ERROR_NOT_SOFTWARE, /*< nick=NotSoftware >*/ + NM_DEVICE_ERROR_NOT_ALLOWED, /*< nick=NotAllowed >*/ + NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, /*< nick=SpecificObjectNotFound >*/ + NM_DEVICE_ERROR_VERSION_ID_MISMATCH, /*< nick=VersionIdMismatch >*/ + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, /*< nick=MissingDependencies >*/ + NM_DEVICE_ERROR_INVALID_ARGUMENT, /*< nick=InvalidArgument >*/ +} NMDeviceError; + +#define NM_DEVICE_ERROR nm_device_error_quark() +GQuark nm_device_error_quark(void); + +/** + * NMManagerError: + * @NM_MANAGER_ERROR_FAILED: unknown or unclassified error + * @NM_MANAGER_ERROR_PERMISSION_DENIED: Permission denied. + * @NM_MANAGER_ERROR_UNKNOWN_CONNECTION: The requested connection is not known. + * @NM_MANAGER_ERROR_UNKNOWN_DEVICE: The requested device is not known. + * @NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE: The requested connection cannot be + * activated at this time. + * @NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE: The request could not be completed + * because a required connection is not active. + * @NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE: The connection to be activated was + * already active on another device. + * @NM_MANAGER_ERROR_DEPENDENCY_FAILED: An activation request failed due to a + * dependency being unavailable. + * @NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE: The manager is already in the requested + * sleep/wake state. + * @NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED: The network is already + * enabled/disabled. + * @NM_MANAGER_ERROR_UNKNOWN_LOG_LEVEL: Unknown log level in SetLogging + * @NM_MANAGER_ERROR_UNKNOWN_LOG_DOMAIN: Unknown log domain in SetLogging + * @NM_MANAGER_ERROR_INVALID_ARGUMENTS: Invalid arguments for D-Bus request + * @NM_MANAGER_ERROR_MISSING_PLUGIN: A plug-in was needed to complete the + * activation but is not available. + * + * Errors related to the main "network management" interface of NetworkManager. + * These may be returned from #NMClient methods that invoke D-Bus operations on + * the "org.freedesktop.NetworkManager" interface, and correspond to D-Bus + * errors in that namespace. + */ +typedef enum { + NM_MANAGER_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_MANAGER_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_MANAGER_ERROR_UNKNOWN_CONNECTION, /*< nick=UnknownConnection >*/ + NM_MANAGER_ERROR_UNKNOWN_DEVICE, /*< nick=UnknownDevice >*/ + NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE, /*< nick=ConnectionNotAvailable >*/ + NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, /*< nick=ConnectionNotActive >*/ + NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE, /*< nick=ConnectionAlreadyActive >*/ + NM_MANAGER_ERROR_DEPENDENCY_FAILED, /*< nick=DependencyFailed >*/ + NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, /*< nick=AlreadyAsleepOrAwake >*/ + NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, /*< nick=AlreadyEnabledOrDisabled >*/ + NM_MANAGER_ERROR_UNKNOWN_LOG_LEVEL, /*< nick=UnknownLogLevel >*/ + NM_MANAGER_ERROR_UNKNOWN_LOG_DOMAIN, /*< nick=UnknownLogDomain >*/ + NM_MANAGER_ERROR_INVALID_ARGUMENTS, /*< nick=InvalidArguments >*/ + NM_MANAGER_ERROR_MISSING_PLUGIN, /*< nick=MissingPlugin >*/ +} NMManagerError; + +GQuark nm_manager_error_quark(void); +#define NM_MANAGER_ERROR (nm_manager_error_quark()) + +/** + * NMSecretAgentError: + * @NM_SECRET_AGENT_ERROR_FAILED: unknown or unclassified error + * @NM_SECRET_AGENT_ERROR_PERMISSION_DENIED: the caller (ie, NetworkManager) is + * not authorized to make this request + * @NM_SECRET_AGENT_ERROR_INVALID_CONNECTION: the connection for which secrets + * were requested is invalid + * @NM_SECRET_AGENT_ERROR_USER_CANCELED: the request was canceled by the user + * @NM_SECRET_AGENT_ERROR_AGENT_CANCELED: the agent canceled the request + * because it was requested to do so by NetworkManager + * @NM_SECRET_AGENT_ERROR_NO_SECRETS: the agent cannot find any secrets for this + * connection + * + * #NMSecretAgentError values are passed by secret agents back to NetworkManager + * when they encounter problems retrieving secrets on behalf of NM. They + * correspond to errors in the "org.freedesktop.NetworkManager.SecretManager" + * namespace. + * + * Client APIs such as nm_client_activate_connection() will not see these error + * codes; instead, the secret agent manager will translate them to the + * corresponding #NMAgentManagerError codes. + */ +typedef enum { + NM_SECRET_AGENT_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, /*< nick=InvalidConnection >*/ + NM_SECRET_AGENT_ERROR_USER_CANCELED, /*< nick=UserCanceled >*/ + NM_SECRET_AGENT_ERROR_AGENT_CANCELED, /*< nick=AgentCanceled >*/ + NM_SECRET_AGENT_ERROR_NO_SECRETS, /*< nick=NoSecrets >*/ +} NMSecretAgentError; + +GQuark nm_secret_agent_error_quark(void); +#define NM_SECRET_AGENT_ERROR (nm_secret_agent_error_quark()) + +/** + * NMSettingsError: + * @NM_SETTINGS_ERROR_FAILED: unknown or unclassified error + * @NM_SETTINGS_ERROR_PERMISSION_DENIED: permission denied + * @NM_SETTINGS_ERROR_NOT_SUPPORTED: the requested operation is not supported by any + * active settings backend + * @NM_SETTINGS_ERROR_INVALID_CONNECTION: the connection was invalid + * @NM_SETTINGS_ERROR_READ_ONLY_CONNECTION: attempted to modify a read-only connection + * @NM_SETTINGS_ERROR_UUID_EXISTS: a connection with that UUID already exists + * @NM_SETTINGS_ERROR_INVALID_HOSTNAME: attempted to set an invalid hostname + * @NM_SETTINGS_ERROR_INVALID_ARGUMENTS: invalid arguments + * + * Errors related to the settings/persistent configuration interface of + * NetworkManager. + * + * These may be returned from #NMClient methods that invoke D-Bus operations on + * the "org.freedesktop.NetworkManager.Settings" interface, and correspond to + * D-Bus errors in that namespace. + */ +typedef enum { + NM_SETTINGS_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_SETTINGS_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_SETTINGS_ERROR_NOT_SUPPORTED, /*< nick=NotSupported >*/ + NM_SETTINGS_ERROR_INVALID_CONNECTION, /*< nick=InvalidConnection >*/ + NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, /*< nick=ReadOnlyConnection >*/ + NM_SETTINGS_ERROR_UUID_EXISTS, /*< nick=UuidExists >*/ + NM_SETTINGS_ERROR_INVALID_HOSTNAME, /*< nick=InvalidHostname >*/ + NM_SETTINGS_ERROR_INVALID_ARGUMENTS, /*< nick=InvalidArguments >*/ +} NMSettingsError; + +GQuark nm_settings_error_quark(void); +#define NM_SETTINGS_ERROR (nm_settings_error_quark()) + +/** + * NMVpnPluginError: + * @NM_VPN_PLUGIN_ERROR_FAILED: unknown or unclassified error + * @NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS: the plugin is already starting, + * and another connect request was received + * @NM_VPN_PLUGIN_ERROR_ALREADY_STARTED: the plugin is already connected, and + * another connect request was received + * @NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS: the plugin is already stopping, + * and another stop request was received + * @NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED: the plugin is already stopped, and + * another disconnect request was received + * @NM_VPN_PLUGIN_ERROR_WRONG_STATE: the operation could not be performed in + * this state + * @NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS: the operation could not be performed as + * the request contained malformed arguments, or arguments of unexpected type. + * Usually means that one of the VPN setting data items or secrets was not of + * the expected type (ie int, string, bool, etc). + * @NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED: a child process failed to launch + * @NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION: the operation could not be performed + * because the connection was invalid. Usually means that the connection's + * VPN setting was missing some required data item or secret. + * @NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED: the operation could not be + * performed as the plugin does not support interactive operations, such as + * ConnectInteractive() or NewSecrets() + * + * Returned by the VPN service plugin to indicate errors. These codes correspond + * to errors in the "org.freedesktop.NetworkManager.VPN.Error" namespace. + **/ +typedef enum { + NM_VPN_PLUGIN_ERROR_FAILED, /*< nick=Failed >*/ + NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS, /*< nick=StartingInProgress >*/ + NM_VPN_PLUGIN_ERROR_ALREADY_STARTED, /*< nick=AlreadyStarted >*/ + NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, /*< nick=StoppingInProgress >*/ + NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, /*< nick=AlreadyStopped >*/ + NM_VPN_PLUGIN_ERROR_WRONG_STATE, /*< nick=WrongState >*/ + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, /*< nick=BadArguments >*/ + NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, /*< nick=LaunchFailed >*/ + NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION, /*< nick=InvalidConnection >*/ + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, /*< nick=InteractiveNotSupported >*/ +} NMVpnPluginError; + +#define NM_VPN_PLUGIN_ERROR (nm_vpn_plugin_error_quark()) +GQuark nm_vpn_plugin_error_quark(void); + +#endif /* __NM_ERRORS_H__ */ diff --git a/src/libnm-core-public/nm-keyfile.h b/src/libnm-core-public/nm-keyfile.h new file mode 100644 index 0000000..28c052f --- /dev/null +++ b/src/libnm-core-public/nm-keyfile.h @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_KEYFILE_H__ +#define __NM_KEYFILE_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-core-types.h" + +G_BEGIN_DECLS + +/** + * NMKeyfileHandlerFlags: + * @NM_KEYFILE_HANDLER_FLAGS_NONE: no flags set. + * + * Flags for customizing nm_keyfile_read() and nm_keyfile_write(). + * + * Currently no flags are implemented. + * + * Since: 1.30 + */ +typedef enum { /*< flags >*/ + NM_KEYFILE_HANDLER_FLAGS_NONE = 0, +} NMKeyfileHandlerFlags; + +/** + * NMKeyfileHandlerType: + * @NM_KEYFILE_HANDLER_TYPE_WARN: a warning. + * @NM_KEYFILE_HANDLER_TYPE_WRITE_CERT: for handling certificates while writing + * a connection to keyfile. + * + * The type of the callback for %NMKeyfileReadHandler and %NMKeyfileWriteHandler. + * Depending on the type, you can interpret %NMKeyfileHandlerData. + * + * Since: 1.30 + */ +typedef enum { + NM_KEYFILE_HANDLER_TYPE_WARN = 1, + NM_KEYFILE_HANDLER_TYPE_WRITE_CERT = 2, +} NMKeyfileHandlerType; + +/** + * NMKeyfileHandlerData: + * + * Opaque type with parameters for the callback. The actual content + * depends on the %NMKeyfileHandlerType. + * + * Since: 1.30 + */ +typedef struct _NMKeyfileHandlerData NMKeyfileHandlerData; + +/** + * NMKeyfileReadHandler: + * @keyfile: the #GKeyFile that is currently read + * @connection: the #NMConnection that is being constructed. + * @handler_type: the %NMKeyfileHandlerType that indicates which type + * the request is. + * @handler_data: the #NMKeyfileHandlerData. What you can do with it + * depends on the @handler_type. + * @user_data: the user-data argument to nm_keyfile_read(). + * + * Hook to nm_keyfile_read(). + * + * The callee may abort the reading by setting an error via nm_keyfile_handler_data_fail_with_error(). + * + * Returns: the callee should return TRUE, if the event was handled and/or recognized. + * Otherwise, a default action will be performed that depends on the @type. + * For %NM_KEYFILE_HANDLER_TYPE_WARN type, the default action is doing nothing. + * + * Since: 1.30 + */ +typedef gboolean (*NMKeyfileReadHandler)(GKeyFile * keyfile, + NMConnection * connection, + NMKeyfileHandlerType handler_type, + NMKeyfileHandlerData *handler_data, + void * user_data); + +NM_AVAILABLE_IN_1_30 +NMConnection *nm_keyfile_read(GKeyFile * keyfile, + const char * base_dir, + NMKeyfileHandlerFlags handler_flags, + NMKeyfileReadHandler handler, + void * user_data, + GError ** error); + +/** + * NMKeyfileWriteHandler: + * @connection: the #NMConnection that is currently written. + * @keyfile: the #GKeyFile that is currently constructed. + * @handler_type: the %NMKeyfileHandlerType that indicates which type + * the request is. + * @handler_data: the #NMKeyfileHandlerData. What you can do with it + * depends on the @handler_type. + * @user_data: the user-data argument to nm_keyfile_read(). + * + * This is a hook to tweak the serialization. + * + * Handler for certain properties or events that are not entirely contained + * within the keyfile or that might be serialized differently. The @type and + * @handler_data arguments tell which kind of argument we have at hand. + * + * Currently only the type %NM_KEYFILE_HANDLER_TYPE_WRITE_CERT is supported. + * + * The callee may call nm_keyfile_handler_data_fail_with_error() to abort + * the writing with error. + * + * Returns: the callee should return %TRUE if the event was handled. If the + * event was unhandled, a default action will be performed that depends on + * the @handler_type. + * + * Since: 1.30 + */ +typedef gboolean (*NMKeyfileWriteHandler)(NMConnection * connection, + GKeyFile * keyfile, + NMKeyfileHandlerType handler_type, + NMKeyfileHandlerData *handler_data, + void * user_data); + +NM_AVAILABLE_IN_1_30 +GKeyFile *nm_keyfile_write(NMConnection * connection, + NMKeyfileHandlerFlags handler_flags, + NMKeyfileWriteHandler handler, + void * user_data, + GError ** error); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_30 +void nm_keyfile_handler_data_fail_with_error(NMKeyfileHandlerData *handler_data, GError *src); + +NM_AVAILABLE_IN_1_30 +void nm_keyfile_handler_data_get_context(const NMKeyfileHandlerData *handler_data, + const char ** out_kf_group_name, + const char ** out_kf_key_name, + NMSetting ** out_cur_setting, + const char ** out_cur_property_name); + +/** + * NMKeyfileWarnSeverity: + * @NM_KEYFILE_WARN_SEVERITY_DEBUG: debug message + * @NM_KEYFILE_WARN_SEVERITY_INFO: info message + * @NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE: info message about a missing file + * @NM_KEYFILE_WARN_SEVERITY_WARN: a warning message + * + * The severity level of %NM_KEYFILE_HANDLER_TYPE_WARN events. + * + * Since: 1.30 + */ +typedef enum { + NM_KEYFILE_WARN_SEVERITY_DEBUG = 1000, + NM_KEYFILE_WARN_SEVERITY_INFO = 2000, + NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE = 2901, + NM_KEYFILE_WARN_SEVERITY_WARN = 3000, +} NMKeyfileWarnSeverity; + +NM_AVAILABLE_IN_1_30 +void nm_keyfile_handler_data_warn_get(const NMKeyfileHandlerData *handler_data, + const char ** out_message, + NMKeyfileWarnSeverity * out_severity); + +G_END_DECLS + +#endif /* __NM_KEYFILE_H__ */ diff --git a/src/libnm-core-public/nm-setting-6lowpan.h b/src/libnm-core-public/nm-setting-6lowpan.h new file mode 100644 index 0000000..5a7c398 --- /dev/null +++ b/src/libnm-core-public/nm-setting-6lowpan.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_6LOWPAN_H__ +#define __NM_SETTING_6LOWPAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_6LOWPAN (nm_setting_6lowpan_get_type()) +#define NM_SETTING_6LOWPAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_6LOWPAN, NMSetting6Lowpan)) +#define NM_SETTING_6LOWPAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_6LOWPANCONFIG, NMSetting6LowpanClass)) +#define NM_IS_SETTING_6LOWPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_6LOWPAN)) +#define NM_IS_SETTING_6LOWPAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_6LOWPAN)) +#define NM_SETTING_6LOWPAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_6LOWPAN, NMSetting6LowpanClass)) + +#define NM_SETTING_6LOWPAN_SETTING_NAME "6lowpan" + +#define NM_SETTING_6LOWPAN_PARENT "parent" + +typedef struct _NMSetting6LowpanClass NMSetting6LowpanClass; + +NM_AVAILABLE_IN_1_14 +GType nm_setting_6lowpan_get_type(void); +NM_AVAILABLE_IN_1_14 +NMSetting *nm_setting_6lowpan_new(void); + +NM_AVAILABLE_IN_1_14 +const char *nm_setting_6lowpan_get_parent(NMSetting6Lowpan *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_6LOWPAN_H__ */ diff --git a/src/libnm-core-public/nm-setting-8021x.h b/src/libnm-core-public/nm-setting-8021x.h new file mode 100644 index 0000000..30b725b --- /dev/null +++ b/src/libnm-core-public/nm-setting-8021x.h @@ -0,0 +1,366 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_8021X_H__ +#define __NM_SETTING_8021X_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH "file://" +#define NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11 "pkcs11:" + +/** + * NMSetting8021xCKFormat: + * @NM_SETTING_802_1X_CK_FORMAT_UNKNOWN: unknown file format + * @NM_SETTING_802_1X_CK_FORMAT_X509: file contains an X.509 format certificate + * @NM_SETTING_802_1X_CK_FORMAT_RAW_KEY: file contains an old-style OpenSSL PEM + * or DER private key + * @NM_SETTING_802_1X_CK_FORMAT_PKCS12: file contains a PKCS#12 certificate + * and private key + * + * #NMSetting8021xCKFormat values indicate the general type of a certificate + * or private key + */ +typedef enum { /*< underscore_name=nm_setting_802_1x_ck_format >*/ + NM_SETTING_802_1X_CK_FORMAT_UNKNOWN = 0, + NM_SETTING_802_1X_CK_FORMAT_X509, + NM_SETTING_802_1X_CK_FORMAT_RAW_KEY, + NM_SETTING_802_1X_CK_FORMAT_PKCS12 +} NMSetting8021xCKFormat; + +/** + * NMSetting8021xCKScheme: + * @NM_SETTING_802_1X_CK_SCHEME_UNKNOWN: unknown certificate or private key + * scheme + * @NM_SETTING_802_1X_CK_SCHEME_BLOB: certificate or key is stored as the raw + * item data + * @NM_SETTING_802_1X_CK_SCHEME_PATH: certificate or key is stored as a path + * to a file containing the certificate or key data + * @NM_SETTING_802_1X_CK_SCHEME_PKCS11: certificate or key is stored as a + * URI of an object on a PKCS#11 token + * + * #NMSetting8021xCKScheme values indicate how a certificate or private key is + * stored in the setting properties, either as a blob of the item's data, or as + * a path to a certificate or private key file on the filesystem + */ +typedef enum { /*< underscore_name=nm_setting_802_1x_ck_scheme >*/ + NM_SETTING_802_1X_CK_SCHEME_UNKNOWN = 0, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NM_SETTING_802_1X_CK_SCHEME_PKCS11, +} NMSetting8021xCKScheme; + +/** + * NMSetting8021xAuthFlags: + * @NM_SETTING_802_1X_AUTH_FLAGS_NONE: No flags + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_DISABLE: Disable TLSv1.0 + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_1_DISABLE: Disable TLSv1.1 + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_2_DISABLE: Disable TLSv1.2 + * @NM_SETTING_802_1X_AUTH_FLAGS_ALL: All supported flags + * + * #NMSetting8021xAuthFlags values indicate which authentication settings + * should be used. + * + * Before 1.22, this was wrongly marked as a enum and not as a flags + * type. + * + * Since: 1.8 + */ +typedef enum { /*< flags, underscore_name=nm_setting_802_1x_auth_flags >*/ + NM_SETTING_802_1X_AUTH_FLAGS_NONE = 0, + NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_DISABLE = 0x1, + NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_1_DISABLE = 0x2, + NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_2_DISABLE = 0x4, + + NM_SETTING_802_1X_AUTH_FLAGS_ALL = 0x7, +} NMSetting8021xAuthFlags; + +#define NM_TYPE_SETTING_802_1X (nm_setting_802_1x_get_type()) +#define NM_SETTING_802_1X(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_802_1X, NMSetting8021x)) +#define NM_SETTING_802_1X_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_802_1X, NMSetting8021xClass)) +#define NM_IS_SETTING_802_1X(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_802_1X)) +#define NM_IS_SETTING_802_1X_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_802_1X)) +#define NM_SETTING_802_1X_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_802_1X, NMSetting8021xClass)) + +#define NM_SETTING_802_1X_SETTING_NAME "802-1x" + +#define NM_SETTING_802_1X_EAP "eap" +#define NM_SETTING_802_1X_IDENTITY "identity" +#define NM_SETTING_802_1X_ANONYMOUS_IDENTITY "anonymous-identity" +#define NM_SETTING_802_1X_PAC_FILE "pac-file" +#define NM_SETTING_802_1X_CA_CERT "ca-cert" +#define NM_SETTING_802_1X_CA_CERT_PASSWORD "ca-cert-password" +#define NM_SETTING_802_1X_CA_CERT_PASSWORD_FLAGS "ca-cert-password-flags" +#define NM_SETTING_802_1X_CA_PATH "ca-path" +#define NM_SETTING_802_1X_SUBJECT_MATCH "subject-match" +#define NM_SETTING_802_1X_ALTSUBJECT_MATCHES "altsubject-matches" +#define NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH "domain-suffix-match" +#define NM_SETTING_802_1X_DOMAIN_MATCH "domain-match" +#define NM_SETTING_802_1X_CLIENT_CERT "client-cert" +#define NM_SETTING_802_1X_CLIENT_CERT_PASSWORD "client-cert-password" +#define NM_SETTING_802_1X_CLIENT_CERT_PASSWORD_FLAGS "client-cert-password-flags" +#define NM_SETTING_802_1X_PHASE1_PEAPVER "phase1-peapver" +#define NM_SETTING_802_1X_PHASE1_PEAPLABEL "phase1-peaplabel" +#define NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING "phase1-fast-provisioning" +#define NM_SETTING_802_1X_PHASE1_AUTH_FLAGS "phase1-auth-flags" +#define NM_SETTING_802_1X_PHASE2_AUTH "phase2-auth" +#define NM_SETTING_802_1X_PHASE2_AUTHEAP "phase2-autheap" +#define NM_SETTING_802_1X_PHASE2_CA_CERT "phase2-ca-cert" +#define NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD "phase2-ca-cert-password" +#define NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD_FLAGS "phase2-ca-cert-password-flags" +#define NM_SETTING_802_1X_PHASE2_CA_PATH "phase2-ca-path" +#define NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH "phase2-subject-match" +#define NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES "phase2-altsubject-matches" +#define NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH "phase2-domain-suffix-match" +#define NM_SETTING_802_1X_PHASE2_DOMAIN_MATCH "phase2-domain-match" +#define NM_SETTING_802_1X_PHASE2_CLIENT_CERT "phase2-client-cert" +#define NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD "phase2-client-cert-password" +#define NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS "phase2-client-cert-password-flags" +#define NM_SETTING_802_1X_PASSWORD "password" +#define NM_SETTING_802_1X_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_802_1X_PASSWORD_RAW "password-raw" +#define NM_SETTING_802_1X_PASSWORD_RAW_FLAGS "password-raw-flags" +#define NM_SETTING_802_1X_PRIVATE_KEY "private-key" +#define NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD "private-key-password" +#define NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS "private-key-password-flags" +#define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY "phase2-private-key" +#define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD "phase2-private-key-password" +#define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS "phase2-private-key-password-flags" +#define NM_SETTING_802_1X_PIN "pin" +#define NM_SETTING_802_1X_PIN_FLAGS "pin-flags" +#define NM_SETTING_802_1X_SYSTEM_CA_CERTS "system-ca-certs" +#define NM_SETTING_802_1X_AUTH_TIMEOUT "auth-timeout" +#define NM_SETTING_802_1X_OPTIONAL "optional" + +/* PRIVATE KEY NOTE: when setting PKCS#12 private keys directly via properties + * using the "blob" scheme, the data must be passed in PKCS#12 binary format. + * In this case, the appropriate "client-cert" (or "phase2-client-cert") + * property of the NMSetting8021x object must also contain the exact same + * PKCS#12 binary data that the private key does. This is because the + * PKCS#12 file contains both the private key and client certificate, so both + * properties need to be set to the same thing. When using the "path" scheme, + * just set both the private-key and client-cert properties to the same path. + * + * When setting OpenSSL-derived "traditional" format (ie S/MIME style, not + * PKCS#8) RSA and DSA keys directly via properties with the "blob" scheme, they + * should be passed to NetworkManager in PEM format with the "DEK-Info" and + * "Proc-Type" tags intact. Decrypted private keys should not be used as this + * is insecure and could allow unprivileged users to access the decrypted + * private key data. + * + * When using the "path" scheme, just set the private-key and client-cert + * properties to the paths to their respective objects. + */ + +/** + * NMSetting8021x: + * + * IEEE 802.1x Authentication Settings + */ +struct _NMSetting8021x { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSetting8021xClass; + +GType nm_setting_802_1x_get_type(void); + +NMSetting *nm_setting_802_1x_new(void); + +NM_AVAILABLE_IN_1_2 +NMSetting8021xCKScheme +nm_setting_802_1x_check_cert_scheme(gconstpointer pdata, gsize length, GError **error); + +guint32 nm_setting_802_1x_get_num_eap_methods(NMSetting8021x *setting); +const char *nm_setting_802_1x_get_eap_method(NMSetting8021x *setting, guint32 i); +gboolean nm_setting_802_1x_add_eap_method(NMSetting8021x *setting, const char *eap); +void nm_setting_802_1x_remove_eap_method(NMSetting8021x *setting, guint32 i); +gboolean nm_setting_802_1x_remove_eap_method_by_value(NMSetting8021x *setting, const char *eap); +void nm_setting_802_1x_clear_eap_methods(NMSetting8021x *setting); + +const char *nm_setting_802_1x_get_identity(NMSetting8021x *setting); + +const char *nm_setting_802_1x_get_anonymous_identity(NMSetting8021x *setting); + +const char *nm_setting_802_1x_get_pac_file(NMSetting8021x *setting); + +gboolean nm_setting_802_1x_get_system_ca_certs(NMSetting8021x *setting); +const char *nm_setting_802_1x_get_ca_path(NMSetting8021x *setting); +const char *nm_setting_802_1x_get_phase2_ca_path(NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_ca_cert_scheme(NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_ca_cert_blob(NMSetting8021x *setting); +const char * nm_setting_802_1x_get_ca_cert_path(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_6 +const char *nm_setting_802_1x_get_ca_cert_uri(NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_ca_cert(NMSetting8021x * setting, + const char * value, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error); + +NM_AVAILABLE_IN_1_8 +const char *nm_setting_802_1x_get_ca_cert_password(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_8 +NMSettingSecretFlags nm_setting_802_1x_get_ca_cert_password_flags(NMSetting8021x *setting); + +const char *nm_setting_802_1x_get_subject_match(NMSetting8021x *setting); + +guint32 nm_setting_802_1x_get_num_altsubject_matches(NMSetting8021x *setting); +const char *nm_setting_802_1x_get_altsubject_match(NMSetting8021x *setting, guint32 i); +gboolean nm_setting_802_1x_add_altsubject_match(NMSetting8021x *setting, + const char * altsubject_match); +void nm_setting_802_1x_remove_altsubject_match(NMSetting8021x *setting, guint32 i); +gboolean nm_setting_802_1x_remove_altsubject_match_by_value(NMSetting8021x *setting, + const char * altsubject_match); +void nm_setting_802_1x_clear_altsubject_matches(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_802_1x_get_domain_suffix_match(NMSetting8021x *setting); + +NM_AVAILABLE_IN_1_24 +const char *nm_setting_802_1x_get_domain_match(NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_client_cert_scheme(NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_client_cert_blob(NMSetting8021x *setting); +const char * nm_setting_802_1x_get_client_cert_path(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_6 +const char *nm_setting_802_1x_get_client_cert_uri(NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_client_cert(NMSetting8021x * setting, + const char * value, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error); + +NM_AVAILABLE_IN_1_8 +const char *nm_setting_802_1x_get_client_cert_password(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_8 +NMSettingSecretFlags nm_setting_802_1x_get_client_cert_password_flags(NMSetting8021x *setting); + +const char *nm_setting_802_1x_get_phase1_peapver(NMSetting8021x *setting); + +const char *nm_setting_802_1x_get_phase1_peaplabel(NMSetting8021x *setting); + +const char *nm_setting_802_1x_get_phase1_fast_provisioning(NMSetting8021x *setting); + +const char *nm_setting_802_1x_get_phase2_auth(NMSetting8021x *setting); + +const char *nm_setting_802_1x_get_phase2_autheap(NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_phase2_ca_cert_scheme(NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_phase2_ca_cert_blob(NMSetting8021x *setting); +const char * nm_setting_802_1x_get_phase2_ca_cert_path(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_6 +const char *nm_setting_802_1x_get_phase2_ca_cert_uri(NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_phase2_ca_cert(NMSetting8021x * setting, + const char * value, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error); + +NM_AVAILABLE_IN_1_8 +const char *nm_setting_802_1x_get_phase2_ca_cert_password(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_8 +NMSettingSecretFlags nm_setting_802_1x_get_phase2_ca_cert_password_flags(NMSetting8021x *setting); + +const char *nm_setting_802_1x_get_phase2_subject_match(NMSetting8021x *setting); + +guint32 nm_setting_802_1x_get_num_phase2_altsubject_matches(NMSetting8021x *setting); +const char *nm_setting_802_1x_get_phase2_altsubject_match(NMSetting8021x *setting, guint32 i); +gboolean nm_setting_802_1x_add_phase2_altsubject_match(NMSetting8021x *setting, + const char * phase2_altsubject_match); +void nm_setting_802_1x_remove_phase2_altsubject_match(NMSetting8021x *setting, guint32 i); +gboolean + nm_setting_802_1x_remove_phase2_altsubject_match_by_value(NMSetting8021x *setting, + const char * phase2_altsubject_match); +void nm_setting_802_1x_clear_phase2_altsubject_matches(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_802_1x_get_phase2_domain_suffix_match(NMSetting8021x *setting); + +NM_AVAILABLE_IN_1_24 +const char *nm_setting_802_1x_get_phase2_domain_match(NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_phase2_client_cert_scheme(NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_phase2_client_cert_blob(NMSetting8021x *setting); +const char * nm_setting_802_1x_get_phase2_client_cert_path(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_6 +const char *nm_setting_802_1x_get_phase2_client_cert_uri(NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_phase2_client_cert(NMSetting8021x * setting, + const char * value, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error); + +NM_AVAILABLE_IN_1_8 +const char *nm_setting_802_1x_get_phase2_client_cert_password(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_8 +NMSettingSecretFlags +nm_setting_802_1x_get_phase2_client_cert_password_flags(NMSetting8021x *setting); + +const char * nm_setting_802_1x_get_password(NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_password_flags(NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_password_raw(NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_password_raw_flags(NMSetting8021x *setting); + +const char * nm_setting_802_1x_get_pin(NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_pin_flags(NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_private_key_scheme(NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_private_key_blob(NMSetting8021x *setting); +const char * nm_setting_802_1x_get_private_key_path(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_6 +const char * nm_setting_802_1x_get_private_key_uri(NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_private_key(NMSetting8021x * setting, + const char * value, + const char * password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error); +const char * nm_setting_802_1x_get_private_key_password(NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_private_key_password_flags(NMSetting8021x *setting); + +NMSetting8021xCKFormat nm_setting_802_1x_get_private_key_format(NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_phase2_private_key_scheme(NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_phase2_private_key_blob(NMSetting8021x *setting); +const char * nm_setting_802_1x_get_phase2_private_key_path(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_6 +const char *nm_setting_802_1x_get_phase2_private_key_uri(NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_phase2_private_key(NMSetting8021x * setting, + const char * value, + const char * password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error); +const char *nm_setting_802_1x_get_phase2_private_key_password(NMSetting8021x *setting); +NMSettingSecretFlags +nm_setting_802_1x_get_phase2_private_key_password_flags(NMSetting8021x *setting); + +NMSetting8021xCKFormat nm_setting_802_1x_get_phase2_private_key_format(NMSetting8021x *setting); + +NM_AVAILABLE_IN_1_8 +NMSetting8021xAuthFlags nm_setting_802_1x_get_phase1_auth_flags(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_8 +int nm_setting_802_1x_get_auth_timeout(NMSetting8021x *setting); +NM_AVAILABLE_IN_1_22 +gboolean nm_setting_802_1x_get_optional(NMSetting8021x *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_8021X_H__ */ diff --git a/src/libnm-core-public/nm-setting-adsl.h b/src/libnm-core-public/nm-setting-adsl.h new file mode 100644 index 0000000..3d8e99c --- /dev/null +++ b/src/libnm-core-public/nm-setting-adsl.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_ADSL_H__ +#define __NM_SETTING_ADSL_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_ADSL (nm_setting_adsl_get_type()) +#define NM_SETTING_ADSL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_ADSL, NMSettingAdsl)) +#define NM_SETTING_ADSL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_ADSL, NMSettingAdslClass)) +#define NM_IS_SETTING_ADSL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_ADSL)) +#define NM_IS_SETTING_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_ADSL)) +#define NM_SETTING_ADSL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_ADSL, NMSettingAdslClass)) + +#define NM_SETTING_ADSL_SETTING_NAME "adsl" + +#define NM_SETTING_ADSL_USERNAME "username" +#define NM_SETTING_ADSL_PASSWORD "password" +#define NM_SETTING_ADSL_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_ADSL_PROTOCOL "protocol" +#define NM_SETTING_ADSL_ENCAPSULATION "encapsulation" +#define NM_SETTING_ADSL_VPI "vpi" +#define NM_SETTING_ADSL_VCI "vci" + +#define NM_SETTING_ADSL_PROTOCOL_PPPOA "pppoa" +#define NM_SETTING_ADSL_PROTOCOL_PPPOE "pppoe" +#define NM_SETTING_ADSL_PROTOCOL_IPOATM "ipoatm" + +#define NM_SETTING_ADSL_ENCAPSULATION_VCMUX "vcmux" +#define NM_SETTING_ADSL_ENCAPSULATION_LLC "llc" + +/** + * NMSettingAdsl: + * + * ADSL Settings + */ +struct _NMSettingAdsl { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingAdslClass; + +GType nm_setting_adsl_get_type(void); + +NMSetting * nm_setting_adsl_new(void); +const char * nm_setting_adsl_get_username(NMSettingAdsl *setting); +const char * nm_setting_adsl_get_password(NMSettingAdsl *setting); +const char * nm_setting_adsl_get_protocol(NMSettingAdsl *setting); +const char * nm_setting_adsl_get_encapsulation(NMSettingAdsl *setting); +guint32 nm_setting_adsl_get_vpi(NMSettingAdsl *setting); +guint32 nm_setting_adsl_get_vci(NMSettingAdsl *setting); +NMSettingSecretFlags nm_setting_adsl_get_password_flags(NMSettingAdsl *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_ADSL_H__ */ diff --git a/src/libnm-core-public/nm-setting-bluetooth.h b/src/libnm-core-public/nm-setting-bluetooth.h new file mode 100644 index 0000000..4f001ef --- /dev/null +++ b/src/libnm-core-public/nm-setting-bluetooth.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2009 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_BLUETOOTH_H__ +#define __NM_SETTING_BLUETOOTH_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_BLUETOOTH (nm_setting_bluetooth_get_type()) +#define NM_SETTING_BLUETOOTH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetooth)) +#define NM_SETTING_BLUETOOTH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetoothClass)) +#define NM_IS_SETTING_BLUETOOTH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_BLUETOOTH)) +#define NM_IS_SETTING_BLUETOOTH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_BLUETOOTH)) +#define NM_SETTING_BLUETOOTH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetoothClass)) + +#define NM_SETTING_BLUETOOTH_SETTING_NAME "bluetooth" + +#define NM_SETTING_BLUETOOTH_BDADDR "bdaddr" +#define NM_SETTING_BLUETOOTH_TYPE "type" + +/** + * NM_SETTING_BLUETOOTH_TYPE_DUN: + * + * Connection type describing a connection to devices that support the Bluetooth + * DUN profile. + */ +#define NM_SETTING_BLUETOOTH_TYPE_DUN "dun" + +/** + * NM_SETTING_BLUETOOTH_TYPE_PANU: + * + * Connection type describing PANU connection to a Bluetooth NAP (Network + * Access Point). + */ +#define NM_SETTING_BLUETOOTH_TYPE_PANU "panu" + +/** + * NM_SETTING_BLUETOOTH_TYPE_NAP: + * + * Connection type describing a Bluetooth NAP (Network Access Point), + * which accepts PANU clients. + */ +#define NM_SETTING_BLUETOOTH_TYPE_NAP "nap" + +/** + * NMSettingBluetooth: + * + * Bluetooth Settings + */ +struct _NMSettingBluetooth { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingBluetoothClass; + +GType nm_setting_bluetooth_get_type(void); + +NMSetting * nm_setting_bluetooth_new(void); +const char *nm_setting_bluetooth_get_bdaddr(NMSettingBluetooth *setting); +const char *nm_setting_bluetooth_get_connection_type(NMSettingBluetooth *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_BLUETOOTH_H__ */ diff --git a/src/libnm-core-public/nm-setting-bond.h b/src/libnm-core-public/nm-setting-bond.h new file mode 100644 index 0000000..25ae8c3 --- /dev/null +++ b/src/libnm-core-public/nm-setting-bond.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2013 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_BOND_H__ +#define __NM_SETTING_BOND_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_BOND (nm_setting_bond_get_type()) +#define NM_SETTING_BOND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_BOND, NMSettingBond)) +#define NM_SETTING_BOND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_BOND, NMSettingBondClass)) +#define NM_IS_SETTING_BOND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_BOND)) +#define NM_IS_SETTING_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_BOND)) +#define NM_SETTING_BOND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_BOND, NMSettingBondClass)) + +#define NM_SETTING_BOND_SETTING_NAME "bond" + +#define NM_SETTING_BOND_OPTIONS "options" + +/* Valid options for the 'options' property */ +#define NM_SETTING_BOND_OPTION_MODE "mode" +#define NM_SETTING_BOND_OPTION_MIIMON "miimon" +#define NM_SETTING_BOND_OPTION_DOWNDELAY "downdelay" +#define NM_SETTING_BOND_OPTION_UPDELAY "updelay" +#define NM_SETTING_BOND_OPTION_ARP_INTERVAL "arp_interval" +#define NM_SETTING_BOND_OPTION_ARP_IP_TARGET "arp_ip_target" +#define NM_SETTING_BOND_OPTION_ARP_VALIDATE "arp_validate" +#define NM_SETTING_BOND_OPTION_PRIMARY "primary" +#define NM_SETTING_BOND_OPTION_PRIMARY_RESELECT "primary_reselect" +#define NM_SETTING_BOND_OPTION_FAIL_OVER_MAC "fail_over_mac" +#define NM_SETTING_BOND_OPTION_USE_CARRIER "use_carrier" +#define NM_SETTING_BOND_OPTION_AD_SELECT "ad_select" +#define NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY "xmit_hash_policy" +#define NM_SETTING_BOND_OPTION_RESEND_IGMP "resend_igmp" +#define NM_SETTING_BOND_OPTION_LACP_RATE "lacp_rate" +#define NM_SETTING_BOND_OPTION_ACTIVE_SLAVE "active_slave" +#define NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO "ad_actor_sys_prio" +#define NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM "ad_actor_system" +#define NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY "ad_user_port_key" +#define NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE "all_slaves_active" +#define NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS "arp_all_targets" +#define NM_SETTING_BOND_OPTION_MIN_LINKS "min_links" +#define NM_SETTING_BOND_OPTION_NUM_GRAT_ARP "num_grat_arp" +#define NM_SETTING_BOND_OPTION_NUM_UNSOL_NA "num_unsol_na" +#define NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE "packets_per_slave" +#define NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB "tlb_dynamic_lb" +#define NM_SETTING_BOND_OPTION_LP_INTERVAL "lp_interval" + +/** + * NMSettingBond: + * + * Bonding Settings + */ +struct _NMSettingBond { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingBondClass; + +GType nm_setting_bond_get_type(void); + +NMSetting * nm_setting_bond_new(void); +guint32 nm_setting_bond_get_num_options(NMSettingBond *setting); +gboolean nm_setting_bond_get_option(NMSettingBond *setting, + guint32 idx, + const char ** out_name, + const char ** out_value); +const char *nm_setting_bond_get_option_by_name(NMSettingBond *setting, const char *name); +gboolean nm_setting_bond_add_option(NMSettingBond *setting, const char *name, const char *value); +gboolean nm_setting_bond_remove_option(NMSettingBond *setting, const char *name); + +gboolean nm_setting_bond_validate_option(const char *name, const char *value); + +const char **nm_setting_bond_get_valid_options(NMSettingBond *setting); + +const char *nm_setting_bond_get_option_default(NMSettingBond *setting, const char *name); + +NM_AVAILABLE_IN_1_24 +const char *nm_setting_bond_get_option_normalized(NMSettingBond *setting, const char *name); + +G_END_DECLS + +#endif /* __NM_SETTING_BOND_H__ */ diff --git a/src/libnm-core-public/nm-setting-bridge-port.h b/src/libnm-core-public/nm-setting-bridge-port.h new file mode 100644 index 0000000..679131d --- /dev/null +++ b/src/libnm-core-public/nm-setting-bridge-port.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_BRIDGE_PORT_H__ +#define __NM_SETTING_BRIDGE_PORT_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" +#include "nm-setting-bridge.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_BRIDGE_PORT (nm_setting_bridge_port_get_type()) +#define NM_SETTING_BRIDGE_PORT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePort)) +#define NM_SETTING_BRIDGE_PORT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePortClass)) +#define NM_IS_SETTING_BRIDGE_PORT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_BRIDGE_PORT)) +#define NM_IS_SETTING_BRIDGE_PORT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_BRIDGE_PORT)) +#define NM_SETTING_BRIDGE_PORT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePortClass)) + +#define NM_SETTING_BRIDGE_PORT_SETTING_NAME "bridge-port" + +#define NM_SETTING_BRIDGE_PORT_PRIORITY "priority" +#define NM_SETTING_BRIDGE_PORT_PATH_COST "path-cost" +#define NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE "hairpin-mode" +#define NM_SETTING_BRIDGE_PORT_VLANS "vlans" + +/** + * NMSettingBridgePort: + * + * Bridge Port Settings + */ +struct _NMSettingBridgePort { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingBridgePortClass; + +GType nm_setting_bridge_port_get_type(void); + +NMSetting *nm_setting_bridge_port_new(void); + +guint16 nm_setting_bridge_port_get_priority(NMSettingBridgePort *setting); + +guint16 nm_setting_bridge_port_get_path_cost(NMSettingBridgePort *setting); + +gboolean nm_setting_bridge_port_get_hairpin_mode(NMSettingBridgePort *setting); + +NM_AVAILABLE_IN_1_18 +void nm_setting_bridge_port_add_vlan(NMSettingBridgePort *setting, NMBridgeVlan *vlan); +NM_AVAILABLE_IN_1_18 +guint nm_setting_bridge_port_get_num_vlans(NMSettingBridgePort *setting); +NM_AVAILABLE_IN_1_18 +NMBridgeVlan *nm_setting_bridge_port_get_vlan(NMSettingBridgePort *setting, guint idx); +NM_AVAILABLE_IN_1_18 +void nm_setting_bridge_port_remove_vlan(NMSettingBridgePort *setting, guint idx); +NM_AVAILABLE_IN_1_18 +gboolean nm_setting_bridge_port_remove_vlan_by_vid(NMSettingBridgePort *setting, + guint16 vid_start, + guint16 vid_end); +NM_AVAILABLE_IN_1_18 +void nm_setting_bridge_port_clear_vlans(NMSettingBridgePort *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_BRIDGE_PORT_H__ */ diff --git a/src/libnm-core-public/nm-setting-bridge.h b/src/libnm-core-public/nm-setting-bridge.h new file mode 100644 index 0000000..cda1861 --- /dev/null +++ b/src/libnm-core-public/nm-setting-bridge.h @@ -0,0 +1,183 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_BRIDGE_H__ +#define __NM_SETTING_BRIDGE_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_BRIDGE (nm_setting_bridge_get_type()) +#define NM_SETTING_BRIDGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_BRIDGE, NMSettingBridge)) +#define NM_SETTING_BRIDGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_BRIDGE, NMSettingBridgeClass)) +#define NM_IS_SETTING_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_BRIDGE)) +#define NM_IS_SETTING_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_BRIDGE)) +#define NM_SETTING_BRIDGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_BRIDGE, NMSettingBridgeClass)) + +#define NM_SETTING_BRIDGE_SETTING_NAME "bridge" + +#define NM_SETTING_BRIDGE_MAC_ADDRESS "mac-address" +#define NM_SETTING_BRIDGE_STP "stp" +#define NM_SETTING_BRIDGE_PRIORITY "priority" +#define NM_SETTING_BRIDGE_FORWARD_DELAY "forward-delay" +#define NM_SETTING_BRIDGE_HELLO_TIME "hello-time" +#define NM_SETTING_BRIDGE_MAX_AGE "max-age" +#define NM_SETTING_BRIDGE_AGEING_TIME "ageing-time" +#define NM_SETTING_BRIDGE_GROUP_FORWARD_MASK "group-forward-mask" +#define NM_SETTING_BRIDGE_MULTICAST_HASH_MAX "multicast-hash-max" +#define NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT "multicast-last-member-count" +#define NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL "multicast-last-member-interval" +#define NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL "multicast-membership-interval" +#define NM_SETTING_BRIDGE_MULTICAST_SNOOPING "multicast-snooping" +#define NM_SETTING_BRIDGE_MULTICAST_ROUTER "multicast-router" +#define NM_SETTING_BRIDGE_MULTICAST_QUERIER "multicast-querier" +#define NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL "multicast-querier-interval" +#define NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL "multicast-query-interval" +#define NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL "multicast-query-response-interval" +#define NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR "multicast-query-use-ifaddr" +#define NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT "multicast-startup-query-count" +#define NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL "multicast-startup-query-interval" +#define NM_SETTING_BRIDGE_VLAN_FILTERING "vlan-filtering" +#define NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID "vlan-default-pvid" +#define NM_SETTING_BRIDGE_VLANS "vlans" +#define NM_SETTING_BRIDGE_GROUP_ADDRESS "group-address" +#define NM_SETTING_BRIDGE_VLAN_PROTOCOL "vlan-protocol" +#define NM_SETTING_BRIDGE_VLAN_STATS_ENABLED "vlan-stats-enabled" + +#define NM_BRIDGE_VLAN_VID_MIN 1 +#define NM_BRIDGE_VLAN_VID_MAX 4094 + +typedef struct _NMSettingBridgeClass NMSettingBridgeClass; + +typedef struct _NMBridgeVlan NMBridgeVlan; + +GType nm_setting_bridge_get_type(void); + +NMSetting *nm_setting_bridge_new(void); + +const char *nm_setting_bridge_get_mac_address(NMSettingBridge *setting); + +gboolean nm_setting_bridge_get_stp(NMSettingBridge *setting); + +guint16 nm_setting_bridge_get_priority(NMSettingBridge *setting); + +guint16 nm_setting_bridge_get_forward_delay(NMSettingBridge *setting); + +guint16 nm_setting_bridge_get_hello_time(NMSettingBridge *setting); + +guint16 nm_setting_bridge_get_max_age(NMSettingBridge *setting); + +guint32 nm_setting_bridge_get_ageing_time(NMSettingBridge *setting); +NM_AVAILABLE_IN_1_10 +guint16 nm_setting_bridge_get_group_forward_mask(NMSettingBridge *setting); + +gboolean nm_setting_bridge_get_multicast_snooping(NMSettingBridge *setting); +NM_AVAILABLE_IN_1_18 +gboolean nm_setting_bridge_get_vlan_filtering(NMSettingBridge *setting); +NM_AVAILABLE_IN_1_18 +guint16 nm_setting_bridge_get_vlan_default_pvid(NMSettingBridge *setting); +NM_AVAILABLE_IN_1_18 +void nm_setting_bridge_add_vlan(NMSettingBridge *setting, NMBridgeVlan *vlan); +NM_AVAILABLE_IN_1_18 +guint nm_setting_bridge_get_num_vlans(NMSettingBridge *setting); +NM_AVAILABLE_IN_1_18 +NMBridgeVlan *nm_setting_bridge_get_vlan(NMSettingBridge *setting, guint idx); +NM_AVAILABLE_IN_1_18 +void nm_setting_bridge_remove_vlan(NMSettingBridge *setting, guint idx); +NM_AVAILABLE_IN_1_18 +gboolean +nm_setting_bridge_remove_vlan_by_vid(NMSettingBridge *setting, guint16 vid_start, guint16 vid_end); +NM_AVAILABLE_IN_1_18 +void nm_setting_bridge_clear_vlans(NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_18 +GType nm_bridge_vlan_get_type(void); +NM_AVAILABLE_IN_1_18 +NMBridgeVlan *nm_bridge_vlan_new(guint16 vid_start, guint16 vid_end); +NM_AVAILABLE_IN_1_18 +NMBridgeVlan *nm_bridge_vlan_ref(NMBridgeVlan *vlan); +NM_AVAILABLE_IN_1_18 +void nm_bridge_vlan_unref(NMBridgeVlan *vlan); +NM_AVAILABLE_IN_1_18 +NMBridgeVlan *nm_bridge_vlan_new_clone(const NMBridgeVlan *vlan); +NM_AVAILABLE_IN_1_18 +int nm_bridge_vlan_cmp(const NMBridgeVlan *a, const NMBridgeVlan *b); +NM_AVAILABLE_IN_1_18 +void nm_bridge_vlan_seal(NMBridgeVlan *vlan); +NM_AVAILABLE_IN_1_18 +gboolean nm_bridge_vlan_is_sealed(const NMBridgeVlan *vlan); +NM_AVAILABLE_IN_1_18 +void nm_bridge_vlan_set_untagged(NMBridgeVlan *vlan, gboolean value); +NM_AVAILABLE_IN_1_18 +void nm_bridge_vlan_set_pvid(NMBridgeVlan *vlan, gboolean value); +NM_AVAILABLE_IN_1_18 +gboolean +nm_bridge_vlan_get_vid_range(const NMBridgeVlan *vlan, guint16 *vid_start, guint16 *vid_end); +NM_AVAILABLE_IN_1_18 +gboolean nm_bridge_vlan_is_untagged(const NMBridgeVlan *vlan); +NM_AVAILABLE_IN_1_18 +gboolean nm_bridge_vlan_is_pvid(const NMBridgeVlan *vlan); + +NM_AVAILABLE_IN_1_18 +char *nm_bridge_vlan_to_str(const NMBridgeVlan *vlan, GError **error); +NM_AVAILABLE_IN_1_18 +NMBridgeVlan *nm_bridge_vlan_from_str(const char *str, GError **error); + +NM_AVAILABLE_IN_1_24 +const char *nm_setting_bridge_get_group_address(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_24 +const char *nm_setting_bridge_get_vlan_protocol(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_24 +gboolean nm_setting_bridge_get_vlan_stats_enabled(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_24 +const char *nm_setting_bridge_get_multicast_router(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_24 +gboolean nm_setting_bridge_get_multicast_query_use_ifaddr(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_24 +gboolean nm_setting_bridge_get_multicast_querier(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_26 +guint32 nm_setting_bridge_get_multicast_hash_max(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_26 +guint32 nm_setting_bridge_get_multicast_last_member_count(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_26 +guint64 nm_setting_bridge_get_multicast_last_member_interval(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_26 +guint64 nm_setting_bridge_get_multicast_membership_interval(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_26 +guint64 nm_setting_bridge_get_multicast_querier_interval(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_26 +guint64 nm_setting_bridge_get_multicast_query_interval(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_26 +guint64 nm_setting_bridge_get_multicast_query_response_interval(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_26 +guint32 nm_setting_bridge_get_multicast_startup_query_count(const NMSettingBridge *setting); + +NM_AVAILABLE_IN_1_26 +guint64 nm_setting_bridge_get_multicast_startup_query_interval(const NMSettingBridge *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_BRIDGE_H__ */ diff --git a/src/libnm-core-public/nm-setting-cdma.h b/src/libnm-core-public/nm-setting-cdma.h new file mode 100644 index 0000000..67784e8 --- /dev/null +++ b/src/libnm-core-public/nm-setting-cdma.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_CDMA_H__ +#define __NM_SETTING_CDMA_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_CDMA (nm_setting_cdma_get_type()) +#define NM_SETTING_CDMA(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_CDMA, NMSettingCdma)) +#define NM_SETTING_CDMA_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_CDMA, NMSettingCdmaClass)) +#define NM_IS_SETTING_CDMA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_CDMA)) +#define NM_IS_SETTING_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_CDMA)) +#define NM_SETTING_CDMA_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_CDMA, NMSettingCdmaClass)) + +#define NM_SETTING_CDMA_SETTING_NAME "cdma" + +#define NM_SETTING_CDMA_NUMBER "number" +#define NM_SETTING_CDMA_USERNAME "username" +#define NM_SETTING_CDMA_PASSWORD "password" +#define NM_SETTING_CDMA_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_CDMA_MTU "mtu" + +/** + * NMSettingCdma: + * + * CDMA-based Mobile Broadband Settings + */ +struct _NMSettingCdma { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingCdmaClass; + +GType nm_setting_cdma_get_type(void); + +NMSetting * nm_setting_cdma_new(void); +const char * nm_setting_cdma_get_number(NMSettingCdma *setting); +const char * nm_setting_cdma_get_username(NMSettingCdma *setting); +const char * nm_setting_cdma_get_password(NMSettingCdma *setting); +NMSettingSecretFlags nm_setting_cdma_get_password_flags(NMSettingCdma *setting); + +NM_AVAILABLE_IN_1_8 +guint32 nm_setting_cdma_get_mtu(NMSettingCdma *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_CDMA_H__ */ diff --git a/src/libnm-core-public/nm-setting-connection.h b/src/libnm-core-public/nm-setting-connection.h new file mode 100644 index 0000000..34b40a4 --- /dev/null +++ b/src/libnm-core-public/nm-setting-connection.h @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_CONNECTION_H__ +#define __NM_SETTING_CONNECTION_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_CONNECTION (nm_setting_connection_get_type()) +#define NM_SETTING_CONNECTION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_CONNECTION, NMSettingConnection)) +#define NM_SETTING_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionClass)) +#define NM_IS_SETTING_CONNECTION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_CONNECTION)) +#define NM_IS_SETTING_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_CONNECTION)) +#define NM_SETTING_CONNECTION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionClass)) + +#define NM_SETTING_CONNECTION_SETTING_NAME "connection" + +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN -999 +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX 999 +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT 0 + +#define NM_SETTING_CONNECTION_ID "id" +#define NM_SETTING_CONNECTION_UUID "uuid" +#define NM_SETTING_CONNECTION_STABLE_ID "stable-id" +#define NM_SETTING_CONNECTION_INTERFACE_NAME "interface-name" +#define NM_SETTING_CONNECTION_TYPE "type" +#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY "autoconnect-priority" +#define NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES "autoconnect-retries" +#define NM_SETTING_CONNECTION_MULTI_CONNECT "multi-connect" +#define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" +#define NM_SETTING_CONNECTION_READ_ONLY "read-only" +#define NM_SETTING_CONNECTION_PERMISSIONS "permissions" +#define NM_SETTING_CONNECTION_ZONE "zone" +#define NM_SETTING_CONNECTION_MASTER "master" +#define NM_SETTING_CONNECTION_SLAVE_TYPE "slave-type" +#define NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES "autoconnect-slaves" +#define NM_SETTING_CONNECTION_SECONDARIES "secondaries" +#define NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT "gateway-ping-timeout" +#define NM_SETTING_CONNECTION_METERED "metered" +#define NM_SETTING_CONNECTION_LLDP "lldp" +#define NM_SETTING_CONNECTION_AUTH_RETRIES "auth-retries" +#define NM_SETTING_CONNECTION_MDNS "mdns" +#define NM_SETTING_CONNECTION_LLMNR "llmnr" +#define NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT "wait-device-timeout" +#define NM_SETTING_CONNECTION_MUD_URL "mud-url" + +/* Types for property values */ +/** + * NMSettingConnectionAutoconnectSlaves: + * @NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT: default value + * @NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO: slaves are not brought up when + * master is activated + * @NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES: slaves are brought up when + * master is activated + * + * #NMSettingConnectionAutoconnectSlaves values indicate whether slave connections + * should be activated when master is activated. + */ +typedef enum { + NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT = -1, + NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO = 0, + NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES = 1, +} NMSettingConnectionAutoconnectSlaves; + +/** + * NMSettingConnectionLldp: + * @NM_SETTING_CONNECTION_LLDP_DEFAULT: default value + * @NM_SETTING_CONNECTION_LLDP_DISABLE: disable LLDP + * @NM_SETTING_CONNECTION_LLDP_ENABLE_RX: enable reception of LLDP frames + * + * #NMSettingConnectionLldp values indicate whether LLDP should be enabled. + */ +typedef enum { + NM_SETTING_CONNECTION_LLDP_DEFAULT = -1, + NM_SETTING_CONNECTION_LLDP_DISABLE = 0, + NM_SETTING_CONNECTION_LLDP_ENABLE_RX = 1, +} NMSettingConnectionLldp; + +/** + * NMSettingConnectionMdns: + * @NM_SETTING_CONNECTION_MDNS_DEFAULT: default value + * @NM_SETTING_CONNECTION_MDNS_NO: disable mDNS + * @NM_SETTING_CONNECTION_MDNS_RESOLVE: support only resolving, do not register hostname + * @NM_SETTING_CONNECTION_MDNS_YES: enable mDNS + * + * #NMSettingConnectionMdns values indicate whether mDNS should be enabled. + * + * Since: 1.12 + */ +typedef enum { + NM_SETTING_CONNECTION_MDNS_DEFAULT = -1, + NM_SETTING_CONNECTION_MDNS_NO = 0, + NM_SETTING_CONNECTION_MDNS_RESOLVE = 1, + NM_SETTING_CONNECTION_MDNS_YES = 2, +} NMSettingConnectionMdns; + +/** + * NMSettingConnectionLlmnr: + * @NM_SETTING_CONNECTION_LLMNR_DEFAULT: default value + * @NM_SETTING_CONNECTION_LLMNR_NO: disable LLMNR + * @NM_SETTING_CONNECTION_LLMNR_RESOLVE: support only resolving, do not register hostname + * @NM_SETTING_CONNECTION_LLMNR_YES: enable LLMNR + * + * #NMSettingConnectionLlmnr values indicate whether LLMNR should be enabled. + * + * Since: 1.14 + */ +typedef enum { + NM_SETTING_CONNECTION_LLMNR_DEFAULT = -1, + NM_SETTING_CONNECTION_LLMNR_NO = 0, + NM_SETTING_CONNECTION_LLMNR_RESOLVE = 1, + NM_SETTING_CONNECTION_LLMNR_YES = 2, +} NMSettingConnectionLlmnr; + +/** + * NMSettingConnection: + * + * General Connection Profile Settings + */ +struct _NMSettingConnection { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingConnectionClass; + +GType nm_setting_connection_get_type(void); + +NMSetting * nm_setting_connection_new(void); +const char *nm_setting_connection_get_id(NMSettingConnection *setting); +const char *nm_setting_connection_get_uuid(NMSettingConnection *setting); +NM_AVAILABLE_IN_1_4 +const char *nm_setting_connection_get_stable_id(NMSettingConnection *setting); +const char *nm_setting_connection_get_interface_name(NMSettingConnection *setting); +const char *nm_setting_connection_get_connection_type(NMSettingConnection *setting); +gboolean nm_setting_connection_get_autoconnect(NMSettingConnection *setting); +int nm_setting_connection_get_autoconnect_priority(NMSettingConnection *setting); +NM_AVAILABLE_IN_1_6 +int nm_setting_connection_get_autoconnect_retries(NMSettingConnection *setting); +NM_AVAILABLE_IN_1_14 +NMConnectionMultiConnect nm_setting_connection_get_multi_connect(NMSettingConnection *setting); +guint64 nm_setting_connection_get_timestamp(NMSettingConnection *setting); +gboolean nm_setting_connection_get_read_only(NMSettingConnection *setting); + +guint32 nm_setting_connection_get_num_permissions(NMSettingConnection *setting); +gboolean nm_setting_connection_get_permission(NMSettingConnection *setting, + guint32 idx, + const char ** out_ptype, + const char ** out_pitem, + const char ** out_detail); +const char *nm_setting_connection_get_zone(NMSettingConnection *setting); +gboolean nm_setting_connection_permissions_user_allowed(NMSettingConnection *setting, + const char * uname); +gboolean nm_setting_connection_add_permission(NMSettingConnection *setting, + const char * ptype, + const char * pitem, + const char * detail); +void nm_setting_connection_remove_permission(NMSettingConnection *setting, guint32 idx); +gboolean nm_setting_connection_remove_permission_by_value(NMSettingConnection *setting, + const char * ptype, + const char * pitem, + const char * detail); + +const char *nm_setting_connection_get_master(NMSettingConnection *setting); +gboolean nm_setting_connection_is_slave_type(NMSettingConnection *setting, const char *type); +const char *nm_setting_connection_get_slave_type(NMSettingConnection *setting); +NM_AVAILABLE_IN_1_2 +NMSettingConnectionAutoconnectSlaves +nm_setting_connection_get_autoconnect_slaves(NMSettingConnection *setting); + +guint32 nm_setting_connection_get_num_secondaries(NMSettingConnection *setting); +const char *nm_setting_connection_get_secondary(NMSettingConnection *setting, guint32 idx); +gboolean nm_setting_connection_add_secondary(NMSettingConnection *setting, const char *sec_uuid); +void nm_setting_connection_remove_secondary(NMSettingConnection *setting, guint32 idx); +gboolean nm_setting_connection_remove_secondary_by_value(NMSettingConnection *setting, + const char * sec_uuid); + +guint32 nm_setting_connection_get_gateway_ping_timeout(NMSettingConnection *setting); +NM_AVAILABLE_IN_1_2 +NMMetered nm_setting_connection_get_metered(NMSettingConnection *setting); +NM_AVAILABLE_IN_1_2 +NMSettingConnectionLldp nm_setting_connection_get_lldp(NMSettingConnection *setting); + +NM_AVAILABLE_IN_1_10 +int nm_setting_connection_get_auth_retries(NMSettingConnection *setting); + +NM_AVAILABLE_IN_1_12 +NMSettingConnectionMdns nm_setting_connection_get_mdns(NMSettingConnection *setting); +NM_AVAILABLE_IN_1_14 +NMSettingConnectionLlmnr nm_setting_connection_get_llmnr(NMSettingConnection *setting); + +NM_AVAILABLE_IN_1_20 +gint32 nm_setting_connection_get_wait_device_timeout(NMSettingConnection *setting); + +NM_AVAILABLE_IN_1_26 +const char *nm_setting_connection_get_mud_url(NMSettingConnection *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_CONNECTION_H__ */ diff --git a/src/libnm-core-public/nm-setting-dcb.h b/src/libnm-core-public/nm-setting-dcb.h new file mode 100644 index 0000000..a33c13a --- /dev/null +++ b/src/libnm-core-public/nm-setting-dcb.h @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_DCB_H__ +#define __NM_SETTING_DCB_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_DCB (nm_setting_dcb_get_type()) +#define NM_SETTING_DCB(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_DCB, NMSettingDcb)) +#define NM_SETTING_DCB_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_DCB, NMSettingDcbClass)) +#define NM_IS_SETTING_DCB(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_DCB)) +#define NM_IS_SETTING_DCB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_DCB)) +#define NM_SETTING_DCB_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_DCB, NMSettingDcbClass)) + +#define NM_SETTING_DCB_SETTING_NAME "dcb" + +/** + * NMSettingDcbFlags: + * @NM_SETTING_DCB_FLAG_NONE: no flag + * @NM_SETTING_DCB_FLAG_ENABLE: the feature is enabled + * @NM_SETTING_DCB_FLAG_ADVERTISE: the feature is advertised + * @NM_SETTING_DCB_FLAG_WILLING: the feature is willing to change based on + * peer configuration advertisements + * + * DCB feature flags. + **/ +typedef enum { /*< flags >*/ + NM_SETTING_DCB_FLAG_NONE = 0x00000000, + NM_SETTING_DCB_FLAG_ENABLE = 0x00000001, + NM_SETTING_DCB_FLAG_ADVERTISE = 0x00000002, + NM_SETTING_DCB_FLAG_WILLING = 0x00000004 +} NMSettingDcbFlags; + +/** + * NM_SETTING_DCB_FCOE_MODE_FABRIC: + * + * Indicates that the FCoE controller should use "fabric" mode (default) + */ +#define NM_SETTING_DCB_FCOE_MODE_FABRIC "fabric" + +/** + * NM_SETTING_DCB_FCOE_MODE_VN2VN: + * + * Indicates that the FCoE controller should use "VN2VN" mode. + */ +#define NM_SETTING_DCB_FCOE_MODE_VN2VN "vn2vn" + +/* Properties */ +#define NM_SETTING_DCB_APP_FCOE_FLAGS "app-fcoe-flags" +#define NM_SETTING_DCB_APP_FCOE_PRIORITY "app-fcoe-priority" +#define NM_SETTING_DCB_APP_FCOE_MODE "app-fcoe-mode" + +#define NM_SETTING_DCB_APP_ISCSI_FLAGS "app-iscsi-flags" +#define NM_SETTING_DCB_APP_ISCSI_PRIORITY "app-iscsi-priority" + +#define NM_SETTING_DCB_APP_FIP_FLAGS "app-fip-flags" +#define NM_SETTING_DCB_APP_FIP_PRIORITY "app-fip-priority" + +#define NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS "priority-flow-control-flags" +#define NM_SETTING_DCB_PRIORITY_FLOW_CONTROL "priority-flow-control" + +#define NM_SETTING_DCB_PRIORITY_GROUP_FLAGS "priority-group-flags" +#define NM_SETTING_DCB_PRIORITY_GROUP_ID "priority-group-id" +#define NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH "priority-group-bandwidth" +#define NM_SETTING_DCB_PRIORITY_BANDWIDTH "priority-bandwidth" +#define NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH "priority-strict-bandwidth" +#define NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS "priority-traffic-class" + +/** + * NMSettingDcb: + * + * Data Center Bridging Settings + */ +struct _NMSettingDcb { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingDcbClass; + +GType nm_setting_dcb_get_type(void); + +NMSetting *nm_setting_dcb_new(void); + +NMSettingDcbFlags nm_setting_dcb_get_app_fcoe_flags(NMSettingDcb *setting); +int nm_setting_dcb_get_app_fcoe_priority(NMSettingDcb *setting); +const char * nm_setting_dcb_get_app_fcoe_mode(NMSettingDcb *setting); + +NMSettingDcbFlags nm_setting_dcb_get_app_iscsi_flags(NMSettingDcb *setting); +int nm_setting_dcb_get_app_iscsi_priority(NMSettingDcb *setting); + +NMSettingDcbFlags nm_setting_dcb_get_app_fip_flags(NMSettingDcb *setting); +int nm_setting_dcb_get_app_fip_priority(NMSettingDcb *setting); + +/* Priority Flow Control */ +NMSettingDcbFlags nm_setting_dcb_get_priority_flow_control_flags(NMSettingDcb *setting); +gboolean nm_setting_dcb_get_priority_flow_control(NMSettingDcb *setting, guint user_priority); +void nm_setting_dcb_set_priority_flow_control(NMSettingDcb *setting, + guint user_priority, + gboolean enabled); + +/* Priority Groups */ +NMSettingDcbFlags nm_setting_dcb_get_priority_group_flags(NMSettingDcb *setting); + +guint nm_setting_dcb_get_priority_group_id(NMSettingDcb *setting, guint user_priority); +void +nm_setting_dcb_set_priority_group_id(NMSettingDcb *setting, guint user_priority, guint group_id); + +guint nm_setting_dcb_get_priority_group_bandwidth(NMSettingDcb *setting, guint group_id); +void nm_setting_dcb_set_priority_group_bandwidth(NMSettingDcb *setting, + guint group_id, + guint bandwidth_percent); + +guint nm_setting_dcb_get_priority_bandwidth(NMSettingDcb *setting, guint user_priority); +void nm_setting_dcb_set_priority_bandwidth(NMSettingDcb *setting, + guint user_priority, + guint bandwidth_percent); + +gboolean nm_setting_dcb_get_priority_strict_bandwidth(NMSettingDcb *setting, guint user_priority); +void nm_setting_dcb_set_priority_strict_bandwidth(NMSettingDcb *setting, + guint user_priority, + gboolean strict); + +guint nm_setting_dcb_get_priority_traffic_class(NMSettingDcb *setting, guint user_priority); +void nm_setting_dcb_set_priority_traffic_class(NMSettingDcb *setting, + guint user_priority, + guint traffic_class); + +G_END_DECLS + +#endif /* __NM_SETTING_DCB_H__ */ diff --git a/src/libnm-core-public/nm-setting-dummy.h b/src/libnm-core-public/nm-setting-dummy.h new file mode 100644 index 0000000..504428e --- /dev/null +++ b/src/libnm-core-public/nm-setting-dummy.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_DUMMY_H__ +#define __NM_SETTING_DUMMY_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_DUMMY (nm_setting_dummy_get_type()) +#define NM_SETTING_DUMMY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_DUMMY, NMSettingDummy)) +#define NM_SETTING_DUMMY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_DUMMYCONFIG, NMSettingDummyClass)) +#define NM_IS_SETTING_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_DUMMY)) +#define NM_IS_SETTING_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_DUMMY)) +#define NM_SETTING_DUMMY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_DUMMY, NMSettingDummyClass)) + +#define NM_SETTING_DUMMY_SETTING_NAME "dummy" + +/** + * NMSettingDummy: + * + * Dummy Link Settings + */ +struct _NMSettingDummy { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingDummyClass; + +NM_AVAILABLE_IN_1_8 +GType nm_setting_dummy_get_type(void); +NM_AVAILABLE_IN_1_8 +NMSetting *nm_setting_dummy_new(void); + +G_END_DECLS + +#endif /* __NM_SETTING_DUMMY_H__ */ diff --git a/src/libnm-core-public/nm-setting-ethtool.h b/src/libnm-core-public/nm-setting-ethtool.h new file mode 100644 index 0000000..d2310b4 --- /dev/null +++ b/src/libnm-core-public/nm-setting-ethtool.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_ETHTOOL_H__ +#define __NM_SETTING_ETHTOOL_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +NM_AVAILABLE_IN_1_20 +gboolean nm_ethtool_optname_is_feature(const char *optname); + +NM_AVAILABLE_IN_1_26 +gboolean nm_ethtool_optname_is_coalesce(const char *optname); + +NM_AVAILABLE_IN_1_26 +gboolean nm_ethtool_optname_is_ring(const char *optname); + +/*****************************************************************************/ + +#define NM_TYPE_SETTING_ETHTOOL (nm_setting_ethtool_get_type()) +#define NM_SETTING_ETHTOOL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_ETHTOOL, NMSettingEthtool)) +#define NM_SETTING_ETHTOOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_ETHTOOL, NMSettingEthtoolClass)) +#define NM_IS_SETTING_ETHTOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_ETHTOOL)) +#define NM_IS_SETTING_ETHTOOL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_ETHTOOL)) +#define NM_SETTING_ETHTOOL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_ETHTOOL, NMSettingEthtoolClass)) + +#define NM_SETTING_ETHTOOL_SETTING_NAME "ethtool" + +/*****************************************************************************/ + +typedef struct _NMSettingEthtoolClass NMSettingEthtoolClass; + +NM_AVAILABLE_IN_1_14 +GType nm_setting_ethtool_get_type(void); + +NM_AVAILABLE_IN_1_14 +NMSetting *nm_setting_ethtool_new(void); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_20 +NM_DEPRECATED_IN_1_26 +const char **nm_setting_ethtool_get_optnames(NMSettingEthtool *setting, guint *out_length); + +NM_AVAILABLE_IN_1_14 +NM_DEPRECATED_IN_1_26 +NMTernary nm_setting_ethtool_get_feature(NMSettingEthtool *setting, const char *optname); +NM_AVAILABLE_IN_1_14 +NM_DEPRECATED_IN_1_26 +void +nm_setting_ethtool_set_feature(NMSettingEthtool *setting, const char *optname, NMTernary value); +NM_AVAILABLE_IN_1_14 +NM_DEPRECATED_IN_1_26 +void nm_setting_ethtool_clear_features(NMSettingEthtool *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_ETHTOOL_H__ */ diff --git a/src/libnm-core-public/nm-setting-generic.h b/src/libnm-core-public/nm-setting-generic.h new file mode 100644 index 0000000..5c0195f --- /dev/null +++ b/src/libnm-core-public/nm-setting-generic.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_GENERIC_H__ +#define __NM_SETTING_GENERIC_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_GENERIC (nm_setting_generic_get_type()) +#define NM_SETTING_GENERIC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_GENERIC, NMSettingGeneric)) +#define NM_SETTING_GENERIC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_GENERIC, NMSettingGenericClass)) +#define NM_IS_SETTING_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_GENERIC)) +#define NM_IS_SETTING_GENERIC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_GENERIC)) +#define NM_SETTING_GENERIC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_GENERIC, NMSettingGenericClass)) + +#define NM_SETTING_GENERIC_SETTING_NAME "generic" + +/** + * NMSettingGeneric: + * + * Generic Link Settings + */ +struct _NMSettingGeneric { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingGenericClass; + +GType nm_setting_generic_get_type(void); + +NMSetting *nm_setting_generic_new(void); + +G_END_DECLS + +#endif /* __NM_SETTING_GENERIC_H__ */ diff --git a/src/libnm-core-public/nm-setting-gsm.h b/src/libnm-core-public/nm-setting-gsm.h new file mode 100644 index 0000000..ed939e7 --- /dev/null +++ b/src/libnm-core-public/nm-setting-gsm.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_GSM_H__ +#define __NM_SETTING_GSM_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_GSM (nm_setting_gsm_get_type()) +#define NM_SETTING_GSM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_GSM, NMSettingGsm)) +#define NM_SETTING_GSM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_GSM, NMSettingGsmClass)) +#define NM_IS_SETTING_GSM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_GSM)) +#define NM_IS_SETTING_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_GSM)) +#define NM_SETTING_GSM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_GSM, NMSettingGsmClass)) + +#define NM_SETTING_GSM_SETTING_NAME "gsm" + +#define NM_SETTING_GSM_AUTO_CONFIG "auto-config" +#define NM_SETTING_GSM_USERNAME "username" +#define NM_SETTING_GSM_PASSWORD "password" +#define NM_SETTING_GSM_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_GSM_APN "apn" +#define NM_SETTING_GSM_NETWORK_ID "network-id" +#define NM_SETTING_GSM_PIN "pin" +#define NM_SETTING_GSM_PIN_FLAGS "pin-flags" +#define NM_SETTING_GSM_HOME_ONLY "home-only" +#define NM_SETTING_GSM_DEVICE_ID "device-id" +#define NM_SETTING_GSM_SIM_ID "sim-id" +#define NM_SETTING_GSM_SIM_OPERATOR_ID "sim-operator-id" +#define NM_SETTING_GSM_MTU "mtu" + +/* Deprecated */ +#define NM_SETTING_GSM_NUMBER "number" + +/** + * NMSettingGsm: + * + * GSM-based Mobile Broadband Settings + */ +struct _NMSettingGsm { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingGsmClass; + +GType nm_setting_gsm_get_type(void); + +NMSetting *nm_setting_gsm_new(void); + +NM_AVAILABLE_IN_1_22 +gboolean nm_setting_gsm_get_auto_config(NMSettingGsm *setting); + +const char *nm_setting_gsm_get_username(NMSettingGsm *setting); +const char *nm_setting_gsm_get_password(NMSettingGsm *setting); +const char *nm_setting_gsm_get_apn(NMSettingGsm *setting); +const char *nm_setting_gsm_get_network_id(NMSettingGsm *setting); +const char *nm_setting_gsm_get_pin(NMSettingGsm *setting); +gboolean nm_setting_gsm_get_home_only(NMSettingGsm *setting); + +NM_AVAILABLE_IN_1_2 +const char *nm_setting_gsm_get_device_id(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_gsm_get_sim_id(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_gsm_get_sim_operator_id(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_8 +guint32 nm_setting_gsm_get_mtu(NMSettingGsm *setting); + +NM_DEPRECATED_IN_1_16 +const char *nm_setting_gsm_get_number(NMSettingGsm *setting); + +NMSettingSecretFlags nm_setting_gsm_get_pin_flags(NMSettingGsm *setting); +NMSettingSecretFlags nm_setting_gsm_get_password_flags(NMSettingGsm *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_GSM_H__ */ diff --git a/src/libnm-core-public/nm-setting-hostname.h b/src/libnm-core-public/nm-setting-hostname.h new file mode 100644 index 0000000..02b4e37 --- /dev/null +++ b/src/libnm-core-public/nm-setting-hostname.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#ifndef NM_SETTING_HOSTNAME_H +#define NM_SETTING_HOSTNAME_H + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_HOSTNAME (nm_setting_hostname_get_type()) +#define NM_SETTING_HOSTNAME(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_HOSTNAME, NMSettingHostname)) +#define NM_SETTING_HOSTNAME_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_HOSTNAME, NMSettingHostnameClass)) +#define NM_IS_SETTING_HOSTNAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_HOSTNAME)) +#define NM_IS_SETTING_HOSTNAME_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_HOSTNAME)) +#define NM_SETTING_HOSTNAME_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_HOSTNAME, NMSettingHostnameClass)) + +#define NM_SETTING_HOSTNAME_SETTING_NAME "hostname" + +#define NM_SETTING_HOSTNAME_PRIORITY "priority" +#define NM_SETTING_HOSTNAME_FROM_DHCP "from-dhcp" +#define NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP "from-dns-lookup" +#define NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT "only-from-default" + +typedef struct _NMSettingHostnameClass NMSettingHostnameClass; + +NM_AVAILABLE_IN_1_30 +GType nm_setting_hostname_get_type(void); +NM_AVAILABLE_IN_1_30 +NMSetting *nm_setting_hostname_new(void); + +NM_AVAILABLE_IN_1_30 +int nm_setting_hostname_get_priority(NMSettingHostname *setting); +NM_AVAILABLE_IN_1_30 +NMTernary nm_setting_hostname_get_from_dhcp(NMSettingHostname *setting); +NM_AVAILABLE_IN_1_30 +NMTernary nm_setting_hostname_get_from_dns_lookup(NMSettingHostname *setting); +NM_AVAILABLE_IN_1_30 +NMTernary nm_setting_hostname_get_only_from_default(NMSettingHostname *setting); + +G_END_DECLS + +#endif /* NM_SETTING_HOSTNAME_H */ diff --git a/src/libnm-core-public/nm-setting-infiniband.h b/src/libnm-core-public/nm-setting-infiniband.h new file mode 100644 index 0000000..4a771ae --- /dev/null +++ b/src/libnm-core-public/nm-setting-infiniband.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_INFINIBAND_H__ +#define __NM_SETTING_INFINIBAND_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_INFINIBAND (nm_setting_infiniband_get_type()) +#define NM_SETTING_INFINIBAND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_INFINIBAND, NMSettingInfiniband)) +#define NM_SETTING_INFINIBAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_INFINIBAND, NMSettingInfinibandClass)) +#define NM_IS_SETTING_INFINIBAND(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_INFINIBAND)) +#define NM_IS_SETTING_INFINIBAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_INFINIBAND)) +#define NM_SETTING_INFINIBAND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_INFINIBAND, NMSettingInfinibandClass)) + +#define NM_SETTING_INFINIBAND_SETTING_NAME "infiniband" + +#define NM_SETTING_INFINIBAND_MAC_ADDRESS "mac-address" +#define NM_SETTING_INFINIBAND_MTU "mtu" +#define NM_SETTING_INFINIBAND_TRANSPORT_MODE "transport-mode" +#define NM_SETTING_INFINIBAND_P_KEY "p-key" +#define NM_SETTING_INFINIBAND_PARENT "parent" + +/** + * NMSettingInfiniband: + * + * Infiniband Settings + */ +struct _NMSettingInfiniband { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingInfinibandClass; + +GType nm_setting_infiniband_get_type(void); + +NMSetting * nm_setting_infiniband_new(void); +const char *nm_setting_infiniband_get_mac_address(NMSettingInfiniband *setting); +guint32 nm_setting_infiniband_get_mtu(NMSettingInfiniband *setting); +const char *nm_setting_infiniband_get_transport_mode(NMSettingInfiniband *setting); +int nm_setting_infiniband_get_p_key(NMSettingInfiniband *setting); +const char *nm_setting_infiniband_get_parent(NMSettingInfiniband *setting); + +const char *nm_setting_infiniband_get_virtual_interface_name(NMSettingInfiniband *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_INFINIBAND_H__ */ diff --git a/src/libnm-core-public/nm-setting-ip-config.h b/src/libnm-core-public/nm-setting-ip-config.h new file mode 100644 index 0000000..f4e0f60 --- /dev/null +++ b/src/libnm-core-public/nm-setting-ip-config.h @@ -0,0 +1,503 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef NM_SETTING_IP_CONFIG_H +#define NM_SETTING_IP_CONFIG_H + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" +#include "nm-utils.h" + +G_BEGIN_DECLS + +#define NM_IP_ADDRESS_ATTRIBUTE_LABEL "label" + +/** + * NMIPAddressCmpFlags: + * @NM_IP_ADDRESS_CMP_FLAGS_NONE: no flags. + * @NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS: when comparing two addresses, + * also consider their attributes. Warning: note that attributes are GVariants + * and they don't have a total order. In other words, if the address differs only + * by their attributes, the returned compare order is not total. In that case, + * the return value merely indicates equality (zero) or inequality. + * + * Compare flags for nm_ip_address_cmp_full(). + * + * Since: 1.22 + */ +typedef enum { /*< flags >*/ + NM_IP_ADDRESS_CMP_FLAGS_NONE = 0, + NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS = 0x1, +} NMIPAddressCmpFlags; + +typedef struct NMIPAddress NMIPAddress; + +GType nm_ip_address_get_type(void); + +NMIPAddress *nm_ip_address_new(int family, const char *addr, guint prefix, GError **error); +NMIPAddress *nm_ip_address_new_binary(int family, gconstpointer addr, guint prefix, GError **error); + +void nm_ip_address_ref(NMIPAddress *address); +void nm_ip_address_unref(NMIPAddress *address); +gboolean nm_ip_address_equal(NMIPAddress *address, NMIPAddress *other); +NM_AVAILABLE_IN_1_22 +int +nm_ip_address_cmp_full(const NMIPAddress *a, const NMIPAddress *b, NMIPAddressCmpFlags cmp_flags); +NMIPAddress *nm_ip_address_dup(NMIPAddress *address); + +int nm_ip_address_get_family(NMIPAddress *address); +const char *nm_ip_address_get_address(NMIPAddress *address); +void nm_ip_address_set_address(NMIPAddress *address, const char *addr); +void nm_ip_address_get_address_binary(NMIPAddress *address, gpointer addr); +void nm_ip_address_set_address_binary(NMIPAddress *address, gconstpointer addr); +guint nm_ip_address_get_prefix(NMIPAddress *address); +void nm_ip_address_set_prefix(NMIPAddress *address, guint prefix); + +char ** nm_ip_address_get_attribute_names(NMIPAddress *address); +GVariant *nm_ip_address_get_attribute(NMIPAddress *address, const char *name); +void nm_ip_address_set_attribute(NMIPAddress *address, const char *name, GVariant *value); + +typedef struct NMIPRoute NMIPRoute; + +GType nm_ip_route_get_type(void); + +NMIPRoute *nm_ip_route_new(int family, + const char *dest, + guint prefix, + const char *next_hop, + gint64 metric, + GError ** error); +NMIPRoute *nm_ip_route_new_binary(int family, + gconstpointer dest, + guint prefix, + gconstpointer next_hop, + gint64 metric, + GError ** error); + +void nm_ip_route_ref(NMIPRoute *route); +void nm_ip_route_unref(NMIPRoute *route); +gboolean nm_ip_route_equal(NMIPRoute *route, NMIPRoute *other); + +enum { /*< flags >*/ + NM_IP_ROUTE_EQUAL_CMP_FLAGS_NONE = 0, + NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS = 0x1, +}; + +NM_AVAILABLE_IN_1_10 +gboolean nm_ip_route_equal_full(NMIPRoute *route, NMIPRoute *other, guint cmp_flags); + +NMIPRoute *nm_ip_route_dup(NMIPRoute *route); + +int nm_ip_route_get_family(NMIPRoute *route); +const char *nm_ip_route_get_dest(NMIPRoute *route); +void nm_ip_route_set_dest(NMIPRoute *route, const char *dest); +void nm_ip_route_get_dest_binary(NMIPRoute *route, gpointer dest); +void nm_ip_route_set_dest_binary(NMIPRoute *route, gconstpointer dest); +guint nm_ip_route_get_prefix(NMIPRoute *route); +void nm_ip_route_set_prefix(NMIPRoute *route, guint prefix); +const char *nm_ip_route_get_next_hop(NMIPRoute *route); +void nm_ip_route_set_next_hop(NMIPRoute *route, const char *next_hop); +gboolean nm_ip_route_get_next_hop_binary(NMIPRoute *route, gpointer next_hop); +void nm_ip_route_set_next_hop_binary(NMIPRoute *route, gconstpointer next_hop); +gint64 nm_ip_route_get_metric(NMIPRoute *route); +void nm_ip_route_set_metric(NMIPRoute *route, gint64 metric); + +char ** nm_ip_route_get_attribute_names(NMIPRoute *route); +GVariant *nm_ip_route_get_attribute(NMIPRoute *route, const char *name); +void nm_ip_route_set_attribute(NMIPRoute *route, const char *name, GVariant *value); +NM_AVAILABLE_IN_1_8 +const NMVariantAttributeSpec *const *nm_ip_route_get_variant_attribute_spec(void); +NM_AVAILABLE_IN_1_8 +gboolean nm_ip_route_attribute_validate(const char *name, + GVariant * value, + int family, + gboolean * known, + GError ** error); + +#define NM_IP_ROUTE_ATTRIBUTE_CWND "cwnd" +#define NM_IP_ROUTE_ATTRIBUTE_FROM "from" +#define NM_IP_ROUTE_ATTRIBUTE_INITCWND "initcwnd" +#define NM_IP_ROUTE_ATTRIBUTE_INITRWND "initrwnd" +#define NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND "lock-cwnd" +#define NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND "lock-initcwnd" +#define NM_IP_ROUTE_ATTRIBUTE_LOCK_INITRWND "lock-initrwnd" +#define NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU "lock-mtu" +#define NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW "lock-window" +#define NM_IP_ROUTE_ATTRIBUTE_MTU "mtu" +#define NM_IP_ROUTE_ATTRIBUTE_ONLINK "onlink" +#define NM_IP_ROUTE_ATTRIBUTE_SCOPE "scope" +#define NM_IP_ROUTE_ATTRIBUTE_SRC "src" +#define NM_IP_ROUTE_ATTRIBUTE_TABLE "table" +#define NM_IP_ROUTE_ATTRIBUTE_TOS "tos" +#define NM_IP_ROUTE_ATTRIBUTE_TYPE "type" +#define NM_IP_ROUTE_ATTRIBUTE_WINDOW "window" + +/*****************************************************************************/ + +typedef struct NMIPRoutingRule NMIPRoutingRule; + +NM_AVAILABLE_IN_1_18 +GType nm_ip_routing_rule_get_type(void); + +NM_AVAILABLE_IN_1_18 +NMIPRoutingRule *nm_ip_routing_rule_new(int addr_family); + +NM_AVAILABLE_IN_1_18 +NMIPRoutingRule *nm_ip_routing_rule_new_clone(const NMIPRoutingRule *rule); + +NM_AVAILABLE_IN_1_18 +NMIPRoutingRule *nm_ip_routing_rule_ref(NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_unref(NMIPRoutingRule *self); + +NM_AVAILABLE_IN_1_18 +gboolean nm_ip_routing_rule_is_sealed(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_seal(NMIPRoutingRule *self); + +NM_AVAILABLE_IN_1_18 +int nm_ip_routing_rule_get_addr_family(const NMIPRoutingRule *self); + +NM_AVAILABLE_IN_1_18 +gboolean nm_ip_routing_rule_get_invert(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_invert(NMIPRoutingRule *self, gboolean invert); + +NM_AVAILABLE_IN_1_18 +gint64 nm_ip_routing_rule_get_priority(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_priority(NMIPRoutingRule *self, gint64 priority); + +NM_AVAILABLE_IN_1_18 +guint8 nm_ip_routing_rule_get_tos(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_tos(NMIPRoutingRule *self, guint8 tos); + +NM_AVAILABLE_IN_1_18 +guint8 nm_ip_routing_rule_get_ipproto(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_ipproto(NMIPRoutingRule *self, guint8 ipproto); + +NM_AVAILABLE_IN_1_18 +guint16 nm_ip_routing_rule_get_source_port_start(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +guint16 nm_ip_routing_rule_get_source_port_end(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_source_port(NMIPRoutingRule *self, guint16 start, guint16 end); + +NM_AVAILABLE_IN_1_18 +guint16 nm_ip_routing_rule_get_destination_port_start(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +guint16 nm_ip_routing_rule_get_destination_port_end(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_destination_port(NMIPRoutingRule *self, guint16 start, guint16 end); + +NM_AVAILABLE_IN_1_18 +guint32 nm_ip_routing_rule_get_fwmark(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +guint32 nm_ip_routing_rule_get_fwmask(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_fwmark(NMIPRoutingRule *self, guint32 fwmark, guint32 fwmask); + +NM_AVAILABLE_IN_1_18 +guint8 nm_ip_routing_rule_get_from_len(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +const char *nm_ip_routing_rule_get_from(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_from(NMIPRoutingRule *self, const char *from, guint8 len); + +NM_AVAILABLE_IN_1_18 +guint8 nm_ip_routing_rule_get_to_len(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +const char *nm_ip_routing_rule_get_to(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_to(NMIPRoutingRule *self, const char *to, guint8 len); + +NM_AVAILABLE_IN_1_18 +const char *nm_ip_routing_rule_get_iifname(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_iifname(NMIPRoutingRule *self, const char *iifname); + +NM_AVAILABLE_IN_1_18 +const char *nm_ip_routing_rule_get_oifname(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_oifname(NMIPRoutingRule *self, const char *oifname); + +NM_AVAILABLE_IN_1_18 +guint8 nm_ip_routing_rule_get_action(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_action(NMIPRoutingRule *self, guint8 action); + +NM_AVAILABLE_IN_1_18 +guint32 nm_ip_routing_rule_get_table(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_18 +void nm_ip_routing_rule_set_table(NMIPRoutingRule *self, guint32 table); + +NM_AVAILABLE_IN_1_20 +gint32 nm_ip_routing_rule_get_suppress_prefixlength(const NMIPRoutingRule *self); +NM_AVAILABLE_IN_1_20 +void nm_ip_routing_rule_set_suppress_prefixlength(NMIPRoutingRule *self, + gint32 suppress_prefixlength); + +NM_AVAILABLE_IN_1_32 +gboolean nm_ip_routing_rule_get_uid_range(const NMIPRoutingRule *self, + guint32 * out_range_start, + guint32 * out_range_end); +NM_AVAILABLE_IN_1_32 +void nm_ip_routing_rule_set_uid_range(NMIPRoutingRule *self, + guint32 uid_range_start, + guint32 uid_range_end); + +NM_AVAILABLE_IN_1_18 +int nm_ip_routing_rule_cmp(const NMIPRoutingRule *rule, const NMIPRoutingRule *other); + +NM_AVAILABLE_IN_1_18 +gboolean nm_ip_routing_rule_validate(const NMIPRoutingRule *self, GError **error); + +/** + * NMIPRoutingRuleAsStringFlags: + * @NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE: no flags selected. + * @NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET: whether to allow parsing + * IPv4 addresses. + * @NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6: whether to allow parsing + * IPv6 addresses. If both @NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET and + * @NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6 are unset, it's the same + * as setting them both. + * @NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE: if set, ensure that the + * rule verfies or fail. + * + * Since: 1.18 + */ +typedef enum { /*< flags >*/ + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE = 0, + + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET = 0x1, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6 = 0x2, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE = 0x4, +} NMIPRoutingRuleAsStringFlags; + +NM_AVAILABLE_IN_1_18 +NMIPRoutingRule *nm_ip_routing_rule_from_string(const char * str, + NMIPRoutingRuleAsStringFlags to_string_flags, + GHashTable * extra_args, + GError ** error); + +NM_AVAILABLE_IN_1_18 +char *nm_ip_routing_rule_to_string(const NMIPRoutingRule * self, + NMIPRoutingRuleAsStringFlags to_string_flags, + GHashTable * extra_args, + GError ** error); + +/*****************************************************************************/ + +#define NM_TYPE_SETTING_IP_CONFIG (nm_setting_ip_config_get_type()) +#define NM_SETTING_IP_CONFIG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_IP_CONFIG, NMSettingIPConfig)) +#define NM_SETTING_IP_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_IPCONFIG, NMSettingIPConfigClass)) +#define NM_IS_SETTING_IP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_IP_CONFIG)) +#define NM_IS_SETTING_IP_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_IP_CONFIG)) +#define NM_SETTING_IP_CONFIG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_IP_CONFIG, NMSettingIPConfigClass)) + +#define NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX 30000 + +#define NM_SETTING_IP_CONFIG_METHOD "method" +#define NM_SETTING_IP_CONFIG_DNS "dns" +#define NM_SETTING_IP_CONFIG_DNS_SEARCH "dns-search" +#define NM_SETTING_IP_CONFIG_DNS_OPTIONS "dns-options" +#define NM_SETTING_IP_CONFIG_DNS_PRIORITY "dns-priority" +#define NM_SETTING_IP_CONFIG_ADDRESSES "addresses" +#define NM_SETTING_IP_CONFIG_GATEWAY "gateway" +#define NM_SETTING_IP_CONFIG_ROUTES "routes" +#define NM_SETTING_IP_CONFIG_ROUTE_METRIC "route-metric" +#define NM_SETTING_IP_CONFIG_ROUTE_TABLE "route-table" +#define NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES "ignore-auto-routes" +#define NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS "ignore-auto-dns" +#define NM_SETTING_IP_CONFIG_DHCP_HOSTNAME "dhcp-hostname" +#define NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME "dhcp-send-hostname" +#define NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS "dhcp-hostname-flags" +#define NM_SETTING_IP_CONFIG_NEVER_DEFAULT "never-default" +#define NM_SETTING_IP_CONFIG_MAY_FAIL "may-fail" +#define NM_SETTING_IP_CONFIG_DAD_TIMEOUT "dad-timeout" +#define NM_SETTING_IP_CONFIG_DHCP_TIMEOUT "dhcp-timeout" +#define NM_SETTING_IP_CONFIG_DHCP_IAID "dhcp-iaid" +#define NM_SETTING_IP_CONFIG_DHCP_REJECT_SERVERS "dhcp-reject-servers" + +/* these are not real GObject properties. */ +#define NM_SETTING_IP_CONFIG_ROUTING_RULES "routing-rules" + +#define NM_SETTING_DNS_OPTION_DEBUG "debug" +#define NM_SETTING_DNS_OPTION_NDOTS "ndots" +#define NM_SETTING_DNS_OPTION_TIMEOUT "timeout" +#define NM_SETTING_DNS_OPTION_ATTEMPTS "attempts" +#define NM_SETTING_DNS_OPTION_ROTATE "rotate" +#define NM_SETTING_DNS_OPTION_NO_CHECK_NAMES "no-check-names" +#define NM_SETTING_DNS_OPTION_INET6 "inet6" +#define NM_SETTING_DNS_OPTION_IP6_BYTESTRING "ip6-bytestring" +#define NM_SETTING_DNS_OPTION_IP6_DOTINT "ip6-dotint" +#define NM_SETTING_DNS_OPTION_NO_IP6_DOTINT "no-ip6-dotint" +#define NM_SETTING_DNS_OPTION_EDNS0 "edns0" +#define NM_SETTING_DNS_OPTION_SINGLE_REQUEST "single-request" +#define NM_SETTING_DNS_OPTION_SINGLE_REQUEST_REOPEN "single-request-reopen" +#define NM_SETTING_DNS_OPTION_NO_TLD_QUERY "no-tld-query" +#define NM_SETTING_DNS_OPTION_USE_VC "use-vc" +#define NM_SETTING_DNS_OPTION_NO_RELOAD "no-reload" +#define NM_SETTING_DNS_OPTION_TRUST_AD "trust-ad" + +/** + * NMSettingIPConfig: + */ +struct _NMSettingIPConfig { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /* Padding for future expansion */ + gpointer padding[8]; +} NMSettingIPConfigClass; + +/** + * NMDhcpHostnameFlags: + * @NM_DHCP_HOSTNAME_FLAG_NONE: no flag set. The default value from + * Networkmanager global configuration is used. If such value is unset + * or still zero, the DHCP request will use standard FQDN flags, i.e. + * %NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE and + * %NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED for IPv4 and + * %NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE for IPv6. + * @NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE: whether the server should + * do the A RR (FQDN-to-address) DNS updates. + * @NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED: if set, the FQDN is encoded + * using canonical wire format. Otherwise it uses the deprecated + * ASCII encoding. This flag is allowed only for DHCPv4. + * @NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE: when not set, request the + * server to perform updates (the PTR RR and possibly the A RR + * based on the %NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE flag). If + * this is set, the %NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE flag + * should be cleared. + * @NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS: when set, no FQDN flags are + * sent in the DHCP FQDN option. When cleared and all other FQDN + * flags are zero, standard FQDN flags are sent. This flag is + * incompatible with any other FQDN flag. + * + * #NMDhcpHostnameFlags describe flags related to the DHCP hostname and + * FQDN. + * + * Since: 1.22 + */ +typedef enum { /*< flags >*/ + NM_DHCP_HOSTNAME_FLAG_NONE = 0x0, + + NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE = 0x1, + NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED = 0x2, + NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE = 0x4, + + NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS = 0x8, + +} NMDhcpHostnameFlags; + +GType nm_setting_ip_config_get_type(void); + +const char *nm_setting_ip_config_get_method(NMSettingIPConfig *setting); + +guint nm_setting_ip_config_get_num_dns(NMSettingIPConfig *setting); +const char *nm_setting_ip_config_get_dns(NMSettingIPConfig *setting, int idx); +gboolean nm_setting_ip_config_add_dns(NMSettingIPConfig *setting, const char *dns); +void nm_setting_ip_config_remove_dns(NMSettingIPConfig *setting, int idx); +gboolean nm_setting_ip_config_remove_dns_by_value(NMSettingIPConfig *setting, const char *dns); +void nm_setting_ip_config_clear_dns(NMSettingIPConfig *setting); + +guint nm_setting_ip_config_get_num_dns_searches(NMSettingIPConfig *setting); +const char *nm_setting_ip_config_get_dns_search(NMSettingIPConfig *setting, int idx); +gboolean nm_setting_ip_config_add_dns_search(NMSettingIPConfig *setting, const char *dns_search); +void nm_setting_ip_config_remove_dns_search(NMSettingIPConfig *setting, int idx); +gboolean nm_setting_ip_config_remove_dns_search_by_value(NMSettingIPConfig *setting, + const char * dns_search); +void nm_setting_ip_config_clear_dns_searches(NMSettingIPConfig *setting); + +guint nm_setting_ip_config_get_num_dns_options(NMSettingIPConfig *setting); +gboolean nm_setting_ip_config_has_dns_options(NMSettingIPConfig *setting); +const char *nm_setting_ip_config_get_dns_option(NMSettingIPConfig *setting, guint idx); +gboolean nm_setting_ip_config_add_dns_option(NMSettingIPConfig *setting, const char *dns_option); +void nm_setting_ip_config_remove_dns_option(NMSettingIPConfig *setting, int idx); +gboolean nm_setting_ip_config_remove_dns_option_by_value(NMSettingIPConfig *setting, + const char * dns_option); +void nm_setting_ip_config_clear_dns_options(NMSettingIPConfig *setting, gboolean is_set); + +NM_AVAILABLE_IN_1_4 +int nm_setting_ip_config_get_dns_priority(NMSettingIPConfig *setting); + +guint nm_setting_ip_config_get_num_addresses(NMSettingIPConfig *setting); +NMIPAddress *nm_setting_ip_config_get_address(NMSettingIPConfig *setting, int idx); +gboolean nm_setting_ip_config_add_address(NMSettingIPConfig *setting, NMIPAddress *address); +void nm_setting_ip_config_remove_address(NMSettingIPConfig *setting, int idx); +gboolean nm_setting_ip_config_remove_address_by_value(NMSettingIPConfig *setting, + NMIPAddress * address); +void nm_setting_ip_config_clear_addresses(NMSettingIPConfig *setting); + +const char *nm_setting_ip_config_get_gateway(NMSettingIPConfig *setting); + +guint nm_setting_ip_config_get_num_routes(NMSettingIPConfig *setting); +NMIPRoute *nm_setting_ip_config_get_route(NMSettingIPConfig *setting, int idx); +gboolean nm_setting_ip_config_add_route(NMSettingIPConfig *setting, NMIPRoute *route); +void nm_setting_ip_config_remove_route(NMSettingIPConfig *setting, int idx); +gboolean nm_setting_ip_config_remove_route_by_value(NMSettingIPConfig *setting, NMIPRoute *route); +void nm_setting_ip_config_clear_routes(NMSettingIPConfig *setting); + +gint64 nm_setting_ip_config_get_route_metric(NMSettingIPConfig *setting); + +NM_AVAILABLE_IN_1_10 +guint32 nm_setting_ip_config_get_route_table(NMSettingIPConfig *setting); + +NM_AVAILABLE_IN_1_18 +guint nm_setting_ip_config_get_num_routing_rules(NMSettingIPConfig *setting); +NM_AVAILABLE_IN_1_18 +NMIPRoutingRule *nm_setting_ip_config_get_routing_rule(NMSettingIPConfig *setting, guint idx); +NM_AVAILABLE_IN_1_18 +void nm_setting_ip_config_add_routing_rule(NMSettingIPConfig *setting, + NMIPRoutingRule * routing_rule); +NM_AVAILABLE_IN_1_18 +void nm_setting_ip_config_remove_routing_rule(NMSettingIPConfig *setting, guint idx); +NM_AVAILABLE_IN_1_18 +void nm_setting_ip_config_clear_routing_rules(NMSettingIPConfig *setting); + +gboolean nm_setting_ip_config_get_ignore_auto_routes(NMSettingIPConfig *setting); +gboolean nm_setting_ip_config_get_ignore_auto_dns(NMSettingIPConfig *setting); + +const char *nm_setting_ip_config_get_dhcp_hostname(NMSettingIPConfig *setting); +gboolean nm_setting_ip_config_get_dhcp_send_hostname(NMSettingIPConfig *setting); + +gboolean nm_setting_ip_config_get_never_default(NMSettingIPConfig *setting); +gboolean nm_setting_ip_config_get_may_fail(NMSettingIPConfig *setting); +NM_AVAILABLE_IN_1_2 +int nm_setting_ip_config_get_dad_timeout(NMSettingIPConfig *setting); +NM_AVAILABLE_IN_1_2 +int nm_setting_ip_config_get_dhcp_timeout(NMSettingIPConfig *setting); +NM_AVAILABLE_IN_1_22 +const char *nm_setting_ip_config_get_dhcp_iaid(NMSettingIPConfig *setting); + +NM_AVAILABLE_IN_1_22 +NMDhcpHostnameFlags nm_setting_ip_config_get_dhcp_hostname_flags(NMSettingIPConfig *setting); + +NM_AVAILABLE_IN_1_28 +const char *const *nm_setting_ip_config_get_dhcp_reject_servers(NMSettingIPConfig *setting, + guint * out_len); +NM_AVAILABLE_IN_1_28 +void nm_setting_ip_config_add_dhcp_reject_server(NMSettingIPConfig *setting, const char *server); +NM_AVAILABLE_IN_1_28 +void nm_setting_ip_config_remove_dhcp_reject_server(NMSettingIPConfig *setting, guint idx); +NM_AVAILABLE_IN_1_28 +void nm_setting_ip_config_clear_dhcp_reject_servers(NMSettingIPConfig *setting); + +G_END_DECLS + +#endif /* NM_SETTING_IP_CONFIG_H */ diff --git a/src/libnm-core-public/nm-setting-ip-tunnel.h b/src/libnm-core-public/nm-setting-ip-tunnel.h new file mode 100644 index 0000000..802f81e --- /dev/null +++ b/src/libnm-core-public/nm-setting-ip-tunnel.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_IP_TUNNEL_H__ +#define __NM_SETTING_IP_TUNNEL_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_IP_TUNNEL (nm_setting_ip_tunnel_get_type()) +#define NM_SETTING_IP_TUNNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnel)) +#define NM_SETTING_IP_TUNNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnelClass)) +#define NM_IS_SETTING_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_IP_TUNNEL)) +#define NM_IS_SETTING_IP_TUNNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_IP_TUNNEL)) +#define NM_SETTING_IP_TUNNEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnelClass)) + +#define NM_SETTING_IP_TUNNEL_SETTING_NAME "ip-tunnel" + +#define NM_SETTING_IP_TUNNEL_PARENT "parent" +#define NM_SETTING_IP_TUNNEL_MODE "mode" +#define NM_SETTING_IP_TUNNEL_LOCAL "local" +#define NM_SETTING_IP_TUNNEL_REMOTE "remote" +#define NM_SETTING_IP_TUNNEL_TTL "ttl" +#define NM_SETTING_IP_TUNNEL_TOS "tos" +#define NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY "path-mtu-discovery" +#define NM_SETTING_IP_TUNNEL_INPUT_KEY "input-key" +#define NM_SETTING_IP_TUNNEL_OUTPUT_KEY "output-key" +#define NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT "encapsulation-limit" +#define NM_SETTING_IP_TUNNEL_FLOW_LABEL "flow-label" +#define NM_SETTING_IP_TUNNEL_MTU "mtu" +#define NM_SETTING_IP_TUNNEL_FLAGS "flags" + +/** + * NMSettingIPTunnel: + * + * IP Tunneling Settings + */ +struct _NMSettingIPTunnel { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingIPTunnelClass; + +/* + * NMIPTunnelFlags: + * @NM_IP_TUNNEL_FLAG_NONE: no flag + * @NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT: don't add encapsulation limit + * if one isn't present in inner packet + * @NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS: copy the traffic class field + * from the inner packet + * @NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL: copy the flowlabel from the + * inner packet + * @NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV: used for Mobile IPv6 + * @NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY: copy DSCP from the outer packet + * @NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK: copy fwmark from inner packet + * + * IP tunnel flags. + * + * Since: 1.12 + */ +typedef enum { /*< flags, prefix=NM_IP_TUNNEL_FLAG >*/ + NM_IP_TUNNEL_FLAG_NONE = 0x0, + NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT = 0x1, + NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS = 0x2, + NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL = 0x4, + NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV = 0x8, + NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY = 0x10, + NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK = 0x20, +} NMIPTunnelFlags; + +NM_AVAILABLE_IN_1_2 +GType nm_setting_ip_tunnel_get_type(void); + +NM_AVAILABLE_IN_1_2 +NMSetting *nm_setting_ip_tunnel_new(void); + +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip_tunnel_get_parent(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +NMIPTunnelMode nm_setting_ip_tunnel_get_mode(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip_tunnel_get_local(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip_tunnel_get_remote(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_ttl(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_tos(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_ip_tunnel_get_path_mtu_discovery(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip_tunnel_get_input_key(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip_tunnel_get_output_key(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_encapsulation_limit(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_flow_label(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_mtu(NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_12 +NMIPTunnelFlags nm_setting_ip_tunnel_get_flags(NMSettingIPTunnel *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_IP_TUNNEL_H__ */ diff --git a/src/libnm-core-public/nm-setting-ip4-config.h b/src/libnm-core-public/nm-setting-ip4-config.h new file mode 100644 index 0000000..b1c63a4 --- /dev/null +++ b/src/libnm-core-public/nm-setting-ip4-config.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_IP4_CONFIG_H__ +#define __NM_SETTING_IP4_CONFIG_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting-ip-config.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_IP4_CONFIG (nm_setting_ip4_config_get_type()) +#define NM_SETTING_IP4_CONFIG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4Config)) +#define NM_SETTING_IP4_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_IP4CONFIG, NMSettingIP4ConfigClass)) +#define NM_IS_SETTING_IP4_CONFIG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_IP4_CONFIG)) +#define NM_IS_SETTING_IP4_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_IP4_CONFIG)) +#define NM_SETTING_IP4_CONFIG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4ConfigClass)) + +#define NM_SETTING_IP4_CONFIG_SETTING_NAME "ipv4" + +#define NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID "dhcp-client-id" +#define NM_SETTING_IP4_CONFIG_DHCP_FQDN "dhcp-fqdn" +#define NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER "dhcp-vendor-class-identifier" + +/** + * NM_SETTING_IP4_CONFIG_METHOD_AUTO: + * + * IPv4 configuration should be automatically determined via a method appropriate + * for the hardware interface, ie DHCP or PPP or some other device-specific + * manner. + */ +#define NM_SETTING_IP4_CONFIG_METHOD_AUTO "auto" + +/** + * NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL: + * + * IPv4 configuration should be automatically configured for link-local-only + * operation. + */ +#define NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL "link-local" + +/** + * NM_SETTING_IP4_CONFIG_METHOD_MANUAL: + * + * All necessary IPv4 configuration (addresses, prefix, DNS, etc) is specified + * in the setting's properties. + */ +#define NM_SETTING_IP4_CONFIG_METHOD_MANUAL "manual" + +/** + * NM_SETTING_IP4_CONFIG_METHOD_SHARED: + * + * This connection specifies configuration that allows other computers to + * connect through it to the default network (usually the Internet). The + * connection's interface will be assigned a private address, and a DHCP server, + * caching DNS server, and Network Address Translation (NAT) functionality will + * be started on this connection's interface to allow other devices to connect + * through that interface to the default network. + */ +#define NM_SETTING_IP4_CONFIG_METHOD_SHARED "shared" + +/** + * NM_SETTING_IP4_CONFIG_METHOD_DISABLED: + * + * This connection does not use or require IPv4 address and it should be disabled. + */ +#define NM_SETTING_IP4_CONFIG_METHOD_DISABLED "disabled" + +/** + * NMSettingIP4Config: + * + * IPv4 Settings + */ +struct _NMSettingIP4Config { + NMSettingIPConfig parent; +}; + +typedef struct { + NMSettingIPConfigClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingIP4ConfigClass; + +GType nm_setting_ip4_config_get_type(void); + +NMSetting *nm_setting_ip4_config_new(void); + +const char *nm_setting_ip4_config_get_dhcp_client_id(NMSettingIP4Config *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_ip4_config_get_dhcp_fqdn(NMSettingIP4Config *setting); + +NM_AVAILABLE_IN_1_28 +const char *nm_setting_ip4_config_get_dhcp_vendor_class_identifier(NMSettingIP4Config *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_IP4_CONFIG_H__ */ diff --git a/src/libnm-core-public/nm-setting-ip6-config.h b/src/libnm-core-public/nm-setting-ip6-config.h new file mode 100644 index 0000000..fca6961 --- /dev/null +++ b/src/libnm-core-public/nm-setting-ip6-config.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_IP6_CONFIG_H__ +#define __NM_SETTING_IP6_CONFIG_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting-ip-config.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_IP6_CONFIG (nm_setting_ip6_config_get_type()) +#define NM_SETTING_IP6_CONFIG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6Config)) +#define NM_SETTING_IP6_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_IP6CONFIG, NMSettingIP6ConfigClass)) +#define NM_IS_SETTING_IP6_CONFIG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_IP6_CONFIG)) +#define NM_IS_SETTING_IP6_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_IP6_CONFIG)) +#define NM_SETTING_IP6_CONFIG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6ConfigClass)) + +#define NM_SETTING_IP6_CONFIG_SETTING_NAME "ipv6" + +#define NM_SETTING_IP6_CONFIG_IP6_PRIVACY "ip6-privacy" + +#define NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE "addr-gen-mode" + +#define NM_SETTING_IP6_CONFIG_TOKEN "token" + +#define NM_SETTING_IP6_CONFIG_DHCP_DUID "dhcp-duid" + +#define NM_SETTING_IP6_CONFIG_RA_TIMEOUT "ra-timeout" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_IGNORE: + * + * IPv6 is not required or is handled by some other mechanism, and NetworkManager + * should not configure IPv6 for this connection. + */ +#define NM_SETTING_IP6_CONFIG_METHOD_IGNORE "ignore" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_AUTO: + * + * IPv6 configuration should be automatically determined via a method appropriate + * for the hardware interface, ie router advertisements, DHCP, or PPP or some + * other device-specific manner. + */ +#define NM_SETTING_IP6_CONFIG_METHOD_AUTO "auto" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_DHCP: + * + * IPv6 configuration should be automatically determined via DHCPv6 only and + * router advertisements should be ignored. + */ +#define NM_SETTING_IP6_CONFIG_METHOD_DHCP "dhcp" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL: + * + * IPv6 configuration should be automatically configured for link-local-only + * operation. + */ +#define NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL "link-local" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_MANUAL: + * + * All necessary IPv6 configuration (addresses, prefix, DNS, etc) is specified + * in the setting's properties. + */ +#define NM_SETTING_IP6_CONFIG_METHOD_MANUAL "manual" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_SHARED: + * + * This connection specifies configuration that allows other computers to + * connect through it to the default network (usually the Internet). The + * connection's interface will be assigned a private address, and router + * advertisements, a caching DNS server, and Network Address Translation (NAT) + * functionality will be started on this connection's interface to allow other + * devices to connect through that interface to the default network. (not yet + * supported for IPv6) + */ +#define NM_SETTING_IP6_CONFIG_METHOD_SHARED "shared" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_DISABLED: + * + * IPv6 is disabled for the connection. + * + * Since: 1.20 + */ +#define NM_SETTING_IP6_CONFIG_METHOD_DISABLED "disabled" + +/** + * NMSettingIP6ConfigPrivacy: + * @NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN: unknown or no value specified + * @NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: IPv6 Privacy Extensions are disabled + * @NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: IPv6 Privacy Extensions + * are enabled, but public addresses are preferred over temporary addresses + * @NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: IPv6 Privacy Extensions + * are enabled and temporary addresses are preferred over public addresses + * + * #NMSettingIP6ConfigPrivacy values indicate if and how IPv6 Privacy + * Extensions are used (RFC4941). + */ +typedef enum { + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN = -1, + NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED = 0, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR = 1, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR = 2 +} NMSettingIP6ConfigPrivacy; + +/** + * NMSettingIP6ConfigAddrGenMode: + * @NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64: The Interface Identifier is derived + * from the interface hardware address. + * @NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY: The Interface Identifier + * is created by using a cryptographically secure hash of a secret host-specific + * key along with the connection identification and the network address as + * specified by RFC7217. + * + * #NMSettingIP6ConfigAddrGenMode controls how the Interface Identifier for + * RFC4862 Stateless Address Autoconfiguration is created. + * + * Since: 1.2 + */ +typedef enum { + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 = 0, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY = 1, +} NMSettingIP6ConfigAddrGenMode; + +/** + * NMSettingIP6Config: + * + * IPv6 Settings + */ +struct _NMSettingIP6Config { + NMSettingIPConfig parent; +}; + +typedef struct { + NMSettingIPConfigClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingIP6ConfigClass; + +GType nm_setting_ip6_config_get_type(void); + +NMSetting *nm_setting_ip6_config_new(void); + +NMSettingIP6ConfigPrivacy nm_setting_ip6_config_get_ip6_privacy(NMSettingIP6Config *setting); +NM_AVAILABLE_IN_1_2 +NMSettingIP6ConfigAddrGenMode nm_setting_ip6_config_get_addr_gen_mode(NMSettingIP6Config *setting); +NM_AVAILABLE_IN_1_4 +const char *nm_setting_ip6_config_get_token(NMSettingIP6Config *setting); +NM_AVAILABLE_IN_1_12 +const char *nm_setting_ip6_config_get_dhcp_duid(NMSettingIP6Config *setting); +NM_AVAILABLE_IN_1_24 +gint32 nm_setting_ip6_config_get_ra_timeout(NMSettingIP6Config *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_IP6_CONFIG_H__ */ diff --git a/src/libnm-core-public/nm-setting-macsec.h b/src/libnm-core-public/nm-setting-macsec.h new file mode 100644 index 0000000..bc33dd9 --- /dev/null +++ b/src/libnm-core-public/nm-setting-macsec.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_MACSEC_H__ +#define __NM_SETTING_MACSEC_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_MACSEC (nm_setting_macsec_get_type()) +#define NM_SETTING_MACSEC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_MACSEC, NMSettingMacsec)) +#define NM_SETTING_MACSEC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_MACSECCONFIG, NMSettingMacsecClass)) +#define NM_IS_SETTING_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_MACSEC)) +#define NM_IS_SETTING_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_MACSEC)) +#define NM_SETTING_MACSEC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_MACSEC, NMSettingMacsecClass)) + +#define NM_SETTING_MACSEC_SETTING_NAME "macsec" + +#define NM_SETTING_MACSEC_PARENT "parent" +#define NM_SETTING_MACSEC_MODE "mode" +#define NM_SETTING_MACSEC_ENCRYPT "encrypt" +#define NM_SETTING_MACSEC_MKA_CAK "mka-cak" +#define NM_SETTING_MACSEC_MKA_CAK_FLAGS "mka-cak-flags" +#define NM_SETTING_MACSEC_MKA_CKN "mka-ckn" +#define NM_SETTING_MACSEC_PORT "port" +#define NM_SETTING_MACSEC_VALIDATION "validation" +#define NM_SETTING_MACSEC_SEND_SCI "send-sci" + +/** + * NMSettingMacsec: + * + * MACSec Settings + */ +struct _NMSettingMacsec { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingMacsecClass; + +/** + * NMSettingMacsecMode: + * @NM_SETTING_MACSEC_MODE_PSK: The CAK is pre-shared + * @NM_SETTING_MACSEC_MODE_EAP: The CAK is the result of participation in EAP + * + * #NMSettingMacsecMode controls how the CAK (Connectivity Association Key) used + * in MKA (MACsec Key Agreement) is obtained. + * + * Since: 1.6 + */ +typedef enum { + NM_SETTING_MACSEC_MODE_PSK = 0, + NM_SETTING_MACSEC_MODE_EAP = 1, +} NMSettingMacsecMode; + +/** + * NMSettingMacsecValidation: + * @NM_SETTING_MACSEC_VALIDATION_DISABLE: All incoming frames are accepted if + * possible + * @NM_SETTING_MACSEC_VALIDATION_CHECK: Non protected, invalid, or impossible to + * verify frames are accepted and counted as "invalid" + * @NM_SETTING_MACSEC_VALIDATION_STRICT: Non protected, invalid, or impossible to + * verify frames are dropped + * + * #NMSettingMacsecValidation specifies a validation mode for incoming frames. + * + * Since: 1.6 + */ +typedef enum { + NM_SETTING_MACSEC_VALIDATION_DISABLE = 0, + NM_SETTING_MACSEC_VALIDATION_CHECK = 1, + NM_SETTING_MACSEC_VALIDATION_STRICT = 2, +} NMSettingMacsecValidation; + +#define NM_SETTING_MACSEC_MKA_CAK_LENGTH 32 +#define NM_SETTING_MACSEC_MKA_CKN_LENGTH 64 + +NM_AVAILABLE_IN_1_6 +GType nm_setting_macsec_get_type(void); +NM_AVAILABLE_IN_1_6 +NMSetting *nm_setting_macsec_new(void); + +NM_AVAILABLE_IN_1_6 +const char *nm_setting_macsec_get_parent(NMSettingMacsec *setting); +NM_AVAILABLE_IN_1_6 +NMSettingMacsecMode nm_setting_macsec_get_mode(NMSettingMacsec *setting); +NM_AVAILABLE_IN_1_6 +gboolean nm_setting_macsec_get_encrypt(NMSettingMacsec *setting); +NM_AVAILABLE_IN_1_6 +const char *nm_setting_macsec_get_mka_cak(NMSettingMacsec *setting); +NM_AVAILABLE_IN_1_6 +NMSettingSecretFlags nm_setting_macsec_get_mka_cak_flags(NMSettingMacsec *setting); +NM_AVAILABLE_IN_1_6 +const char *nm_setting_macsec_get_mka_ckn(NMSettingMacsec *setting); +NM_AVAILABLE_IN_1_6 +int nm_setting_macsec_get_port(NMSettingMacsec *setting); +NM_AVAILABLE_IN_1_6 +NMSettingMacsecValidation nm_setting_macsec_get_validation(NMSettingMacsec *setting); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_macsec_get_send_sci(NMSettingMacsec *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_MACSEC_H__ */ diff --git a/src/libnm-core-public/nm-setting-macvlan.h b/src/libnm-core-public/nm-setting-macvlan.h new file mode 100644 index 0000000..05c0b36 --- /dev/null +++ b/src/libnm-core-public/nm-setting-macvlan.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_MACVLAN_H__ +#define __NM_SETTING_MACVLAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_MACVLAN (nm_setting_macvlan_get_type()) +#define NM_SETTING_MACVLAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlan)) +#define NM_SETTING_MACVLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_MACVLANCONFIG, NMSettingMacvlanClass)) +#define NM_IS_SETTING_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_MACVLAN)) +#define NM_IS_SETTING_MACVLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_MACVLAN)) +#define NM_SETTING_MACVLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanClass)) + +#define NM_SETTING_MACVLAN_SETTING_NAME "macvlan" + +#define NM_SETTING_MACVLAN_PARENT "parent" +#define NM_SETTING_MACVLAN_MODE "mode" +#define NM_SETTING_MACVLAN_PROMISCUOUS "promiscuous" +#define NM_SETTING_MACVLAN_TAP "tap" + +/** + * NMSettingMacvlan: + * + * MAC VLAN Settings + */ +struct _NMSettingMacvlan { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingMacvlanClass; + +/** + * NMSettingMacvlanMode: + * @NM_SETTING_MACVLAN_MODE_UNKNOWN: unknown/unset mode + * @NM_SETTING_MACVLAN_MODE_VEPA: Virtual Ethernet Port Aggregator mode + * @NM_SETTING_MACVLAN_MODE_BRIDGE: bridge mode + * @NM_SETTING_MACVLAN_MODE_PRIVATE: private mode + * @NM_SETTING_MACVLAN_MODE_PASSTHRU: passthru mode + * @NM_SETTING_MACVLAN_MODE_SOURCE: source mode + **/ +typedef enum { + NM_SETTING_MACVLAN_MODE_UNKNOWN = 0, + NM_SETTING_MACVLAN_MODE_VEPA = 1, + NM_SETTING_MACVLAN_MODE_BRIDGE = 2, + NM_SETTING_MACVLAN_MODE_PRIVATE = 3, + NM_SETTING_MACVLAN_MODE_PASSTHRU = 4, + NM_SETTING_MACVLAN_MODE_SOURCE = 5, + _NM_SETTING_MACVLAN_MODE_NUM, /*< skip >*/ + NM_SETTING_MACVLAN_MODE_LAST = _NM_SETTING_MACVLAN_MODE_NUM - 1, /*< skip >*/ +} NMSettingMacvlanMode; + +NM_AVAILABLE_IN_1_2 +GType nm_setting_macvlan_get_type(void); +NM_AVAILABLE_IN_1_2 +NMSetting *nm_setting_macvlan_new(void); + +NM_AVAILABLE_IN_1_2 +const char *nm_setting_macvlan_get_parent(NMSettingMacvlan *setting); +NM_AVAILABLE_IN_1_2 +NMSettingMacvlanMode nm_setting_macvlan_get_mode(NMSettingMacvlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_macvlan_get_promiscuous(NMSettingMacvlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_macvlan_get_tap(NMSettingMacvlan *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_MACVLAN_H__ */ diff --git a/src/libnm-core-public/nm-setting-match.h b/src/libnm-core-public/nm-setting-match.h new file mode 100644 index 0000000..40d12b6 --- /dev/null +++ b/src/libnm-core-public/nm-setting-match.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef NM_SETTING_MATCH_H +#define NM_SETTING_MATCH_H + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_MATCH (nm_setting_match_get_type()) +#define NM_SETTING_MATCH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_MATCH, NMSettingMatch)) +#define NM_SETTING_MATCH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_MATCH, NMSettingMatchClass)) +#define NM_IS_SETTING_MATCH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_MATCH)) +#define NM_IS_SETTING_MATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_MATCH)) +#define NM_SETTING_MATCH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_MATCH, NMSettingMatchClass)) + +#define NM_SETTING_MATCH_SETTING_NAME "match" + +#define NM_SETTING_MATCH_INTERFACE_NAME "interface-name" +#define NM_SETTING_MATCH_KERNEL_COMMAND_LINE "kernel-command-line" +#define NM_SETTING_MATCH_DRIVER "driver" +#define NM_SETTING_MATCH_PATH "path" + +typedef struct _NMSettingMatchClass NMSettingMatchClass; + +NM_AVAILABLE_IN_1_14 +GType nm_setting_match_get_type(void); +NM_AVAILABLE_IN_1_32 +NMSetting *nm_setting_match_new(void); + +NM_AVAILABLE_IN_1_14 +guint nm_setting_match_get_num_interface_names(NMSettingMatch *setting); +NM_AVAILABLE_IN_1_14 +const char *nm_setting_match_get_interface_name(NMSettingMatch *setting, int idx); +NM_AVAILABLE_IN_1_14 +void nm_setting_match_remove_interface_name(NMSettingMatch *setting, int idx); +NM_AVAILABLE_IN_1_14 +gboolean nm_setting_match_remove_interface_name_by_value(NMSettingMatch *setting, + const char * interface_name); +NM_AVAILABLE_IN_1_14 +void nm_setting_match_add_interface_name(NMSettingMatch *setting, const char *interface_name); +NM_AVAILABLE_IN_1_14 +void nm_setting_match_clear_interface_names(NMSettingMatch *setting); +NM_AVAILABLE_IN_1_14 +const char *const *nm_setting_match_get_interface_names(NMSettingMatch *setting, guint *length); + +NM_AVAILABLE_IN_1_26 +guint nm_setting_match_get_num_kernel_command_lines(NMSettingMatch *setting); +NM_AVAILABLE_IN_1_26 +const char *nm_setting_match_get_kernel_command_line(NMSettingMatch *setting, guint idx); +NM_AVAILABLE_IN_1_26 +void nm_setting_match_remove_kernel_command_line(NMSettingMatch *setting, guint idx); +NM_AVAILABLE_IN_1_26 +gboolean nm_setting_match_remove_kernel_command_line_by_value(NMSettingMatch *setting, + const char * kernel_command_line); +NM_AVAILABLE_IN_1_26 +void nm_setting_match_add_kernel_command_line(NMSettingMatch *setting, + const char * kernel_command_line); +NM_AVAILABLE_IN_1_26 +void nm_setting_match_clear_kernel_command_lines(NMSettingMatch *setting); +NM_AVAILABLE_IN_1_26 +const char *const *nm_setting_match_get_kernel_command_lines(NMSettingMatch *setting, + guint * length); + +NM_AVAILABLE_IN_1_26 +guint nm_setting_match_get_num_drivers(NMSettingMatch *setting); +NM_AVAILABLE_IN_1_26 +const char *nm_setting_match_get_driver(NMSettingMatch *setting, guint idx); +NM_AVAILABLE_IN_1_26 +void nm_setting_match_remove_driver(NMSettingMatch *setting, guint idx); +NM_AVAILABLE_IN_1_26 +gboolean nm_setting_match_remove_driver_by_value(NMSettingMatch *setting, const char *driver); +NM_AVAILABLE_IN_1_26 +void nm_setting_match_add_driver(NMSettingMatch *setting, const char *driver); +NM_AVAILABLE_IN_1_26 +void nm_setting_match_clear_drivers(NMSettingMatch *setting); +NM_AVAILABLE_IN_1_26 +const char *const *nm_setting_match_get_drivers(NMSettingMatch *setting, guint *length); + +NM_AVAILABLE_IN_1_26 +guint nm_setting_match_get_num_paths(NMSettingMatch *setting); +NM_AVAILABLE_IN_1_26 +const char *nm_setting_match_get_path(NMSettingMatch *setting, guint idx); +NM_AVAILABLE_IN_1_26 +void nm_setting_match_remove_path(NMSettingMatch *setting, guint idx); +NM_AVAILABLE_IN_1_26 +gboolean nm_setting_match_remove_path_by_value(NMSettingMatch *setting, const char *path); +NM_AVAILABLE_IN_1_26 +void nm_setting_match_add_path(NMSettingMatch *setting, const char *path); +NM_AVAILABLE_IN_1_26 +void nm_setting_match_clear_paths(NMSettingMatch *setting); +NM_AVAILABLE_IN_1_26 +const char *const *nm_setting_match_get_paths(NMSettingMatch *setting, guint *length); + +G_END_DECLS + +#endif /* NM_SETTING_MATCH_H */ diff --git a/src/libnm-core-public/nm-setting-olpc-mesh.h b/src/libnm-core-public/nm-setting-olpc-mesh.h new file mode 100644 index 0000000..fdba4a4 --- /dev/null +++ b/src/libnm-core-public/nm-setting-olpc-mesh.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2009 One Laptop per Child + */ + +#ifndef __NM_SETTING_OLPC_MESH_H__ +#define __NM_SETTING_OLPC_MESH_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_OLPC_MESH (nm_setting_olpc_mesh_get_type()) +#define NM_SETTING_OLPC_MESH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_OLPC_MESH, NMSettingOlpcMesh)) +#define NM_SETTING_OLPC_MESH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_OLPC_MESH, NMSettingOlpcMeshClass)) +#define NM_IS_SETTING_OLPC_MESH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_OLPC_MESH)) +#define NM_IS_SETTING_OLPC_MESH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_OLPC_MESH)) +#define NM_SETTING_OLPC_MESH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_OLPC_MESH, NMSettingOlpcMeshClass)) + +#define NM_SETTING_OLPC_MESH_SETTING_NAME "802-11-olpc-mesh" + +#define NM_SETTING_OLPC_MESH_SSID "ssid" +#define NM_SETTING_OLPC_MESH_CHANNEL "channel" +#define NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS "dhcp-anycast-address" + +/** + * NMSettingOlpcMesh: + * + * OLPC Wireless Mesh Settings + */ +struct _NMSettingOlpcMesh { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingOlpcMeshClass; + +GType nm_setting_olpc_mesh_get_type(void); + +NMSetting * nm_setting_olpc_mesh_new(void); +GBytes * nm_setting_olpc_mesh_get_ssid(NMSettingOlpcMesh *setting); +guint32 nm_setting_olpc_mesh_get_channel(NMSettingOlpcMesh *setting); +const char *nm_setting_olpc_mesh_get_dhcp_anycast_address(NMSettingOlpcMesh *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_OLPC_MESH_H__ */ diff --git a/src/libnm-core-public/nm-setting-ovs-bridge.h b/src/libnm-core-public/nm-setting-ovs-bridge.h new file mode 100644 index 0000000..b307871 --- /dev/null +++ b/src/libnm-core-public/nm-setting-ovs-bridge.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_OVS_BRIDGE_H__ +#define __NM_SETTING_OVS_BRIDGE_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_OVS_BRIDGE (nm_setting_ovs_bridge_get_type()) +#define NM_SETTING_OVS_BRIDGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_OVS_BRIDGE, NMSettingOvsBridge)) +#define NM_SETTING_OVS_BRIDGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_OVS_BRIDGECONFIG, NMSettingOvsBridgeClass)) +#define NM_IS_SETTING_OVS_BRIDGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_OVS_BRIDGE)) +#define NM_IS_SETTING_OVS_BRIDGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_OVS_BRIDGE)) +#define NM_SETTING_OVS_BRIDGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_OVS_BRIDGE, NMSettingOvsBridgeClass)) + +#define NM_SETTING_OVS_BRIDGE_SETTING_NAME "ovs-bridge" + +#define NM_SETTING_OVS_BRIDGE_FAIL_MODE "fail-mode" +#define NM_SETTING_OVS_BRIDGE_MCAST_SNOOPING_ENABLE "mcast-snooping-enable" +#define NM_SETTING_OVS_BRIDGE_RSTP_ENABLE "rstp-enable" +#define NM_SETTING_OVS_BRIDGE_STP_ENABLE "stp-enable" +#define NM_SETTING_OVS_BRIDGE_DATAPATH_TYPE "datapath-type" + +typedef struct _NMSettingOvsBridgeClass NMSettingOvsBridgeClass; + +NM_AVAILABLE_IN_1_10 +GType nm_setting_ovs_bridge_get_type(void); +NM_AVAILABLE_IN_1_10 +NMSetting *nm_setting_ovs_bridge_new(void); + +NM_AVAILABLE_IN_1_10 +const char *nm_setting_ovs_bridge_get_fail_mode(NMSettingOvsBridge *self); +NM_AVAILABLE_IN_1_10 +gboolean nm_setting_ovs_bridge_get_mcast_snooping_enable(NMSettingOvsBridge *self); +NM_AVAILABLE_IN_1_10 +gboolean nm_setting_ovs_bridge_get_rstp_enable(NMSettingOvsBridge *self); +NM_AVAILABLE_IN_1_10 +gboolean nm_setting_ovs_bridge_get_stp_enable(NMSettingOvsBridge *self); +NM_AVAILABLE_IN_1_20 +const char *nm_setting_ovs_bridge_get_datapath_type(NMSettingOvsBridge *self); + +G_END_DECLS + +#endif /* __NM_SETTING_OVS_BRIDGE_H__ */ diff --git a/src/libnm-core-public/nm-setting-ovs-dpdk.h b/src/libnm-core-public/nm-setting-ovs-dpdk.h new file mode 100644 index 0000000..72de224 --- /dev/null +++ b/src/libnm-core-public/nm-setting-ovs-dpdk.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_OVS_DPDK_H__ +#define __NM_SETTING_OVS_DPDK_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_OVS_DPDK (nm_setting_ovs_dpdk_get_type()) +#define NM_SETTING_OVS_DPDK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_OVS_DPDK, NMSettingOvsDpdk)) +#define NM_SETTING_OVS_DPDK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_OVS_DPDKCONFIG, NMSettingOvsDpdkClass)) +#define NM_IS_SETTING_OVS_DPDK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_OVS_DPDK)) +#define NM_IS_SETTING_OVS_DPDK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_OVS_DPDK)) +#define NM_SETTING_OVS_DPDK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_OVS_DPDK, NMSettingOvsDpdkClass)) + +#define NM_SETTING_OVS_DPDK_SETTING_NAME "ovs-dpdk" + +#define NM_SETTING_OVS_DPDK_DEVARGS "devargs" + +typedef struct _NMSettingOvsDpdkClass NMSettingOvsDpdkClass; + +NM_AVAILABLE_IN_1_20 +GType nm_setting_ovs_dpdk_get_type(void); +NM_AVAILABLE_IN_1_20 +NMSetting *nm_setting_ovs_dpdk_new(void); + +NM_AVAILABLE_IN_1_20 +const char *nm_setting_ovs_dpdk_get_devargs(NMSettingOvsDpdk *self); + +G_END_DECLS + +#endif /* __NM_SETTING_OVS_DPDK_H__ */ diff --git a/src/libnm-core-public/nm-setting-ovs-external-ids.h b/src/libnm-core-public/nm-setting-ovs-external-ids.h new file mode 100644 index 0000000..906db39 --- /dev/null +++ b/src/libnm-core-public/nm-setting-ovs-external-ids.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 - 2020 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_OVS_EXTERNAL_IDS_H__ +#define __NM_SETTING_OVS_EXTERNAL_IDS_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_OVS_EXTERNAL_IDS (nm_setting_ovs_external_ids_get_type()) +#define NM_SETTING_OVS_EXTERNAL_IDS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_OVS_EXTERNAL_IDS, NMSettingOvsExternalIDs)) +#define NM_SETTING_OVS_EXTERNAL_IDS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + NM_TYPE_SETTING_OVS_EXTERNAL_IDS, \ + NMSettingOvsExternalIDsClass)) +#define NM_IS_SETTING_OVS_EXTERNAL_IDS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_OVS_EXTERNAL_IDS)) +#define NM_IS_SETTING_OVS_EXTERNAL_IDS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_OVS_EXTERNAL_IDS)) +#define NM_SETTING_OVS_EXTERNAL_IDS_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + NM_TYPE_SETTING_OVS_EXTERNAL_IDS, \ + NMSettingOvsExternalIDsClass)) + +#define NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME "ovs-external-ids" + +#define NM_SETTING_OVS_EXTERNAL_IDS_DATA "data" + +typedef struct _NMSettingOvsExternalIDsClass NMSettingOvsExternalIDsClass; + +NM_AVAILABLE_IN_1_30 +GType nm_setting_ovs_external_ids_get_type(void); + +NM_AVAILABLE_IN_1_30 +NMSetting *nm_setting_ovs_external_ids_new(void); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_30 +const char *const *nm_setting_ovs_external_ids_get_data_keys(NMSettingOvsExternalIDs *setting, + guint * out_len); + +NM_AVAILABLE_IN_1_30 +const char *nm_setting_ovs_external_ids_get_data(NMSettingOvsExternalIDs *setting, const char *key); + +NM_AVAILABLE_IN_1_30 +void nm_setting_ovs_external_ids_set_data(NMSettingOvsExternalIDs *setting, + const char * key, + const char * val); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_30 +gboolean nm_setting_ovs_external_ids_check_key(const char *key, GError **error); +NM_AVAILABLE_IN_1_30 +gboolean nm_setting_ovs_external_ids_check_val(const char *val, GError **error); + +G_END_DECLS + +#endif /* __NM_SETTING_OVS_EXTERNAL_IDS_H__ */ diff --git a/src/libnm-core-public/nm-setting-ovs-interface.h b/src/libnm-core-public/nm-setting-ovs-interface.h new file mode 100644 index 0000000..47ad581 --- /dev/null +++ b/src/libnm-core-public/nm-setting-ovs-interface.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_OVS_INTERFACE_H__ +#define __NM_SETTING_OVS_INTERFACE_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_get_type()) +#define NM_SETTING_OVS_INTERFACE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_OVS_INTERFACE, NMSettingOvsInterface)) +#define NM_SETTING_OVS_INTERFACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + NM_TYPE_SETTING_OVS_INTERFACECONFIG, \ + NMSettingOvsInterfaceClass)) +#define NM_IS_SETTING_OVS_INTERFACE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_OVS_INTERFACE)) +#define NM_IS_SETTING_OVS_INTERFACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_OVS_INTERFACE)) +#define NM_SETTING_OVS_INTERFACE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_OVS_INTERFACE, NMSettingOvsInterfaceClass)) + +#define NM_SETTING_OVS_INTERFACE_SETTING_NAME "ovs-interface" + +#define NM_SETTING_OVS_INTERFACE_TYPE "type" + +typedef struct _NMSettingOvsInterfaceClass NMSettingOvsInterfaceClass; + +NM_AVAILABLE_IN_1_10 +GType nm_setting_ovs_interface_get_type(void); +NM_AVAILABLE_IN_1_10 +NMSetting *nm_setting_ovs_interface_new(void); + +NM_AVAILABLE_IN_1_10 +const char *nm_setting_ovs_interface_get_interface_type(NMSettingOvsInterface *self); + +G_END_DECLS + +#endif /* __NM_SETTING_OVS_INTERFACE_H__ */ diff --git a/src/libnm-core-public/nm-setting-ovs-patch.h b/src/libnm-core-public/nm-setting-ovs-patch.h new file mode 100644 index 0000000..fd80d45 --- /dev/null +++ b/src/libnm-core-public/nm-setting-ovs-patch.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_OVS_PATCH_H__ +#define __NM_SETTING_OVS_PATCH_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_OVS_PATCH (nm_setting_ovs_patch_get_type()) +#define NM_SETTING_OVS_PATCH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_OVS_PATCH, NMSettingOvsPatch)) +#define NM_SETTING_OVS_PATCH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_OVS_PATCHCONFIG, NMSettingOvsPatchClass)) +#define NM_IS_SETTING_OVS_PATCH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_OVS_PATCH)) +#define NM_IS_SETTING_OVS_PATCH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_OVS_PATCH)) +#define NM_SETTING_OVS_PATCH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_OVS_PATCH, NMSettingOvsPatchClass)) + +#define NM_SETTING_OVS_PATCH_SETTING_NAME "ovs-patch" + +#define NM_SETTING_OVS_PATCH_PEER "peer" + +typedef struct _NMSettingOvsPatchClass NMSettingOvsPatchClass; + +NM_AVAILABLE_IN_1_10 +GType nm_setting_ovs_patch_get_type(void); +NM_AVAILABLE_IN_1_10 +NMSetting *nm_setting_ovs_patch_new(void); + +NM_AVAILABLE_IN_1_10 +const char *nm_setting_ovs_patch_get_peer(NMSettingOvsPatch *self); + +G_END_DECLS + +#endif /* __NM_SETTING_OVS_PATCH_H__ */ diff --git a/src/libnm-core-public/nm-setting-ovs-port.h b/src/libnm-core-public/nm-setting-ovs-port.h new file mode 100644 index 0000000..06d3a2a --- /dev/null +++ b/src/libnm-core-public/nm-setting-ovs-port.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_OVS_PORT_H__ +#define __NM_SETTING_OVS_PORT_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_OVS_PORT (nm_setting_ovs_port_get_type()) +#define NM_SETTING_OVS_PORT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_OVS_PORT, NMSettingOvsPort)) +#define NM_SETTING_OVS_PORT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_OVS_PORTCONFIG, NMSettingOvsPortClass)) +#define NM_IS_SETTING_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_OVS_PORT)) +#define NM_IS_SETTING_OVS_PORT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_OVS_PORT)) +#define NM_SETTING_OVS_PORT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_OVS_PORT, NMSettingOvsPortClass)) + +#define NM_SETTING_OVS_PORT_SETTING_NAME "ovs-port" + +#define NM_SETTING_OVS_PORT_VLAN_MODE "vlan-mode" +#define NM_SETTING_OVS_PORT_TAG "tag" +#define NM_SETTING_OVS_PORT_LACP "lacp" +#define NM_SETTING_OVS_PORT_BOND_MODE "bond-mode" +#define NM_SETTING_OVS_PORT_BOND_UPDELAY "bond-updelay" +#define NM_SETTING_OVS_PORT_BOND_DOWNDELAY "bond-downdelay" + +typedef struct _NMSettingOvsPortClass NMSettingOvsPortClass; + +NM_AVAILABLE_IN_1_10 +GType nm_setting_ovs_port_get_type(void); +NM_AVAILABLE_IN_1_10 +NMSetting *nm_setting_ovs_port_new(void); + +NM_AVAILABLE_IN_1_10 +const char *nm_setting_ovs_port_get_vlan_mode(NMSettingOvsPort *self); +NM_AVAILABLE_IN_1_10 +guint nm_setting_ovs_port_get_tag(NMSettingOvsPort *self); +NM_AVAILABLE_IN_1_10 +const char *nm_setting_ovs_port_get_lacp(NMSettingOvsPort *self); +NM_AVAILABLE_IN_1_10 +const char *nm_setting_ovs_port_get_bond_mode(NMSettingOvsPort *self); +NM_AVAILABLE_IN_1_10 +guint nm_setting_ovs_port_get_bond_updelay(NMSettingOvsPort *self); +NM_AVAILABLE_IN_1_10 +guint nm_setting_ovs_port_get_bond_downdelay(NMSettingOvsPort *self); + +G_END_DECLS + +#endif /* __NM_SETTING_OVS_PORT_H__ */ diff --git a/src/libnm-core-public/nm-setting-ppp.h b/src/libnm-core-public/nm-setting-ppp.h new file mode 100644 index 0000000..91c5347 --- /dev/null +++ b/src/libnm-core-public/nm-setting-ppp.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_PPP_H__ +#define __NM_SETTING_PPP_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_PPP (nm_setting_ppp_get_type()) +#define NM_SETTING_PPP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_PPP, NMSettingPpp)) +#define NM_SETTING_PPP_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_PPP, NMSettingPppClass)) +#define NM_IS_SETTING_PPP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_PPP)) +#define NM_IS_SETTING_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_PPP)) +#define NM_SETTING_PPP_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_PPP, NMSettingPppClass)) + +#define NM_SETTING_PPP_SETTING_NAME "ppp" + +#define NM_SETTING_PPP_NOAUTH "noauth" +#define NM_SETTING_PPP_REFUSE_EAP "refuse-eap" +#define NM_SETTING_PPP_REFUSE_PAP "refuse-pap" +#define NM_SETTING_PPP_REFUSE_CHAP "refuse-chap" +#define NM_SETTING_PPP_REFUSE_MSCHAP "refuse-mschap" +#define NM_SETTING_PPP_REFUSE_MSCHAPV2 "refuse-mschapv2" +#define NM_SETTING_PPP_NOBSDCOMP "nobsdcomp" +#define NM_SETTING_PPP_NODEFLATE "nodeflate" +#define NM_SETTING_PPP_NO_VJ_COMP "no-vj-comp" +#define NM_SETTING_PPP_REQUIRE_MPPE "require-mppe" +#define NM_SETTING_PPP_REQUIRE_MPPE_128 "require-mppe-128" +#define NM_SETTING_PPP_MPPE_STATEFUL "mppe-stateful" +#define NM_SETTING_PPP_CRTSCTS "crtscts" +#define NM_SETTING_PPP_BAUD "baud" +#define NM_SETTING_PPP_MRU "mru" +#define NM_SETTING_PPP_MTU "mtu" +#define NM_SETTING_PPP_LCP_ECHO_FAILURE "lcp-echo-failure" +#define NM_SETTING_PPP_LCP_ECHO_INTERVAL "lcp-echo-interval" + +/** + * NMSettingPpp: + * + * Point-to-Point Protocol Settings + */ +struct _NMSettingPpp { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingPppClass; + +GType nm_setting_ppp_get_type(void); + +NMSetting *nm_setting_ppp_new(void); +gboolean nm_setting_ppp_get_noauth(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_refuse_eap(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_refuse_pap(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_refuse_chap(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_refuse_mschap(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_refuse_mschapv2(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_nobsdcomp(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_nodeflate(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_no_vj_comp(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_require_mppe(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_require_mppe_128(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_mppe_stateful(NMSettingPpp *setting); +gboolean nm_setting_ppp_get_crtscts(NMSettingPpp *setting); +guint32 nm_setting_ppp_get_baud(NMSettingPpp *setting); +guint32 nm_setting_ppp_get_mru(NMSettingPpp *setting); +guint32 nm_setting_ppp_get_mtu(NMSettingPpp *setting); +guint32 nm_setting_ppp_get_lcp_echo_failure(NMSettingPpp *setting); +guint32 nm_setting_ppp_get_lcp_echo_interval(NMSettingPpp *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_PPP_H__ */ diff --git a/src/libnm-core-public/nm-setting-pppoe.h b/src/libnm-core-public/nm-setting-pppoe.h new file mode 100644 index 0000000..0a30f5a --- /dev/null +++ b/src/libnm-core-public/nm-setting-pppoe.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_PPPOE_H__ +#define __NM_SETTING_PPPOE_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_PPPOE (nm_setting_pppoe_get_type()) +#define NM_SETTING_PPPOE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_PPPOE, NMSettingPppoe)) +#define NM_SETTING_PPPOE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_PPPOE, NMSettingPppoeClass)) +#define NM_IS_SETTING_PPPOE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_PPPOE)) +#define NM_IS_SETTING_PPPOE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_PPPOE)) +#define NM_SETTING_PPPOE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_PPPOE, NMSettingPppoeClass)) + +#define NM_SETTING_PPPOE_SETTING_NAME "pppoe" + +#define NM_SETTING_PPPOE_PARENT "parent" +#define NM_SETTING_PPPOE_SERVICE "service" +#define NM_SETTING_PPPOE_USERNAME "username" +#define NM_SETTING_PPPOE_PASSWORD "password" +#define NM_SETTING_PPPOE_PASSWORD_FLAGS "password-flags" + +/** + * NMSettingPppoe: + * + * PPP-over-Ethernet Settings + */ +struct _NMSettingPppoe { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingPppoeClass; + +GType nm_setting_pppoe_get_type(void); + +NMSetting *nm_setting_pppoe_new(void); +NM_AVAILABLE_IN_1_10 +const char * nm_setting_pppoe_get_parent(NMSettingPppoe *setting); +const char * nm_setting_pppoe_get_service(NMSettingPppoe *setting); +const char * nm_setting_pppoe_get_username(NMSettingPppoe *setting); +const char * nm_setting_pppoe_get_password(NMSettingPppoe *setting); +NMSettingSecretFlags nm_setting_pppoe_get_password_flags(NMSettingPppoe *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_PPPOE_H__ */ diff --git a/src/libnm-core-public/nm-setting-proxy.h b/src/libnm-core-public/nm-setting-proxy.h new file mode 100644 index 0000000..70227df --- /dev/null +++ b/src/libnm-core-public/nm-setting-proxy.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Atul Anand . + */ + +#ifndef __NM_SETTING_PROXY_H__ +#define __NM_SETTING_PROXY_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +/** + * NMSettingProxyMethod: + * @NM_SETTING_PROXY_METHOD_NONE: No Proxy for the Connection + * @NM_SETTING_PROXY_METHOD_AUTO: DHCP obtained Proxy/ Manual override + * + * The Proxy method. + * + * Since: 1.6 + */ +typedef enum { + NM_SETTING_PROXY_METHOD_NONE = 0, + NM_SETTING_PROXY_METHOD_AUTO = 1, +} NMSettingProxyMethod; + +#define NM_TYPE_SETTING_PROXY (nm_setting_proxy_get_type()) +#define NM_SETTING_PROXY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_PROXY, NMSettingProxy)) +#define NM_SETTING_PROXY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_PROXY, NMSettingProxyClass)) +#define NM_IS_SETTING_PROXY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_PROXY)) +#define NM_IS_SETTING_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_PROXY)) +#define NM_SETTING_PROXY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_PROXY, NMSettingProxyClass)) + +#define NM_SETTING_PROXY_SETTING_NAME "proxy" + +#define NM_SETTING_PROXY_METHOD "method" +#define NM_SETTING_PROXY_BROWSER_ONLY "browser-only" +#define NM_SETTING_PROXY_PAC_URL "pac-url" +#define NM_SETTING_PROXY_PAC_SCRIPT "pac-script" + +/** + * NMSettingProxy: + * + * WWW Proxy Settings + */ +struct _NMSettingProxy { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + gpointer padding[4]; +} NMSettingProxyClass; + +NM_AVAILABLE_IN_1_6 +GType nm_setting_proxy_get_type(void); + +NM_AVAILABLE_IN_1_6 +NMSetting *nm_setting_proxy_new(void); + +NM_AVAILABLE_IN_1_6 +NMSettingProxyMethod nm_setting_proxy_get_method(NMSettingProxy *setting); +NM_AVAILABLE_IN_1_6 +gboolean nm_setting_proxy_get_browser_only(NMSettingProxy *setting); +NM_AVAILABLE_IN_1_6 +const char *nm_setting_proxy_get_pac_url(NMSettingProxy *setting); +NM_AVAILABLE_IN_1_6 +const char *nm_setting_proxy_get_pac_script(NMSettingProxy *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_PROXY_H__ */ diff --git a/src/libnm-core-public/nm-setting-serial.h b/src/libnm-core-public/nm-setting-serial.h new file mode 100644 index 0000000..abd232e --- /dev/null +++ b/src/libnm-core-public/nm-setting-serial.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_SERIAL_H__ +#define __NM_SETTING_SERIAL_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_SERIAL (nm_setting_serial_get_type()) +#define NM_SETTING_SERIAL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_SERIAL, NMSettingSerial)) +#define NM_SETTING_SERIAL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_SERIAL, NMSettingSerialClass)) +#define NM_IS_SETTING_SERIAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_SERIAL)) +#define NM_IS_SETTING_SERIAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_SERIAL)) +#define NM_SETTING_SERIAL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_SERIAL, NMSettingSerialClass)) + +#define NM_SETTING_SERIAL_SETTING_NAME "serial" + +/** + * NMSettingSerialParity: + * @NM_SETTING_SERIAL_PARITY_NONE: No parity bits (default) + * @NM_SETTING_SERIAL_PARITY_EVEN: Even parity + * @NM_SETTING_SERIAL_PARITY_ODD: Odd parity + * + * The parity setting of a serial port. + */ +typedef enum { + NM_SETTING_SERIAL_PARITY_NONE = 0, + NM_SETTING_SERIAL_PARITY_EVEN, + NM_SETTING_SERIAL_PARITY_ODD +} NMSettingSerialParity; + +#define NM_SETTING_SERIAL_BAUD "baud" +#define NM_SETTING_SERIAL_BITS "bits" +#define NM_SETTING_SERIAL_PARITY "parity" +#define NM_SETTING_SERIAL_STOPBITS "stopbits" +#define NM_SETTING_SERIAL_SEND_DELAY "send-delay" + +/** + * NMSettingSerial: + * + * Serial Link Settings + */ +struct _NMSettingSerial { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingSerialClass; + +GType nm_setting_serial_get_type(void); + +NMSetting * nm_setting_serial_new(void); +guint nm_setting_serial_get_baud(NMSettingSerial *setting); +guint nm_setting_serial_get_bits(NMSettingSerial *setting); +NMSettingSerialParity nm_setting_serial_get_parity(NMSettingSerial *setting); +guint nm_setting_serial_get_stopbits(NMSettingSerial *setting); +guint64 nm_setting_serial_get_send_delay(NMSettingSerial *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_SERIAL_H__ */ diff --git a/src/libnm-core-public/nm-setting-sriov.h b/src/libnm-core-public/nm-setting-sriov.h new file mode 100644 index 0000000..fe5fc37 --- /dev/null +++ b/src/libnm-core-public/nm-setting-sriov.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef NM_SETTING_SRIOV_H +#define NM_SETTING_SRIOV_H + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_SRIOV (nm_setting_sriov_get_type()) +#define NM_SETTING_SRIOV(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_SRIOV, NMSettingSriov)) +#define NM_SETTING_SRIOV_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_SRIOV, NMSettingSriovClass)) +#define NM_IS_SETTING_SRIOV(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_SRIOV)) +#define NM_IS_SETTING_SRIOV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_SRIOV)) +#define NM_SETTING_SRIOV_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_SRIOV, NMSettingSriovClass)) + +#define NM_SETTING_SRIOV_SETTING_NAME "sriov" + +#define NM_SETTING_SRIOV_TOTAL_VFS "total-vfs" +#define NM_SETTING_SRIOV_VFS "vfs" +#define NM_SETTING_SRIOV_AUTOPROBE_DRIVERS "autoprobe-drivers" + +#define NM_SRIOV_VF_ATTRIBUTE_MAC "mac" +#define NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK "spoof-check" +#define NM_SRIOV_VF_ATTRIBUTE_TRUST "trust" +#define NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE "min-tx-rate" +#define NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE "max-tx-rate" + +typedef struct _NMSettingSriovClass NMSettingSriovClass; +typedef struct _NMSriovVF NMSriovVF; + +/** + * NMSriovVFVlanProtocol: + * @NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q: use 802.1Q + * @NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD: use 802.1ad + * + * #NMSriovVFVlanProtocol indicates the VLAN protocol to use. + * + * Since: 1.14 + */ +typedef enum { + NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q = 0, + NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD = 1, +} NMSriovVFVlanProtocol; + +NM_AVAILABLE_IN_1_14 +GType nm_setting_sriov_get_type(void); +NM_AVAILABLE_IN_1_14 +NMSetting *nm_setting_sriov_new(void); +NM_AVAILABLE_IN_1_14 +guint nm_setting_sriov_get_total_vfs(NMSettingSriov *setting); +NM_AVAILABLE_IN_1_14 +guint nm_setting_sriov_get_num_vfs(NMSettingSriov *setting); +NM_AVAILABLE_IN_1_14 +NMSriovVF *nm_setting_sriov_get_vf(NMSettingSriov *setting, guint idx); +NM_AVAILABLE_IN_1_14 +void nm_setting_sriov_add_vf(NMSettingSriov *setting, NMSriovVF *vf); +NM_AVAILABLE_IN_1_14 +void nm_setting_sriov_remove_vf(NMSettingSriov *setting, guint idx); +NM_AVAILABLE_IN_1_14 +gboolean nm_setting_sriov_remove_vf_by_index(NMSettingSriov *setting, guint index); +NM_AVAILABLE_IN_1_14 +void nm_setting_sriov_clear_vfs(NMSettingSriov *setting); +NM_AVAILABLE_IN_1_14 +NMTernary nm_setting_sriov_get_autoprobe_drivers(NMSettingSriov *setting); + +NM_AVAILABLE_IN_1_14 +gboolean nm_sriov_vf_add_vlan(NMSriovVF *vf, guint vlan_id); +NM_AVAILABLE_IN_1_14 +gboolean nm_sriov_vf_remove_vlan(NMSriovVF *vf, guint vlan_id); +NM_AVAILABLE_IN_1_14 +const guint *nm_sriov_vf_get_vlan_ids(const NMSriovVF *vf, guint *length); +NM_AVAILABLE_IN_1_14 +void nm_sriov_vf_set_vlan_qos(NMSriovVF *vf, guint vlan_id, guint32 qos); +NM_AVAILABLE_IN_1_14 +void nm_sriov_vf_set_vlan_protocol(NMSriovVF *vf, guint vlan_id, NMSriovVFVlanProtocol protocol); +NM_AVAILABLE_IN_1_14 +guint32 nm_sriov_vf_get_vlan_qos(const NMSriovVF *vf, guint vlan_id); +NM_AVAILABLE_IN_1_14 +NMSriovVFVlanProtocol nm_sriov_vf_get_vlan_protocol(const NMSriovVF *vf, guint vlan_id); + +NM_AVAILABLE_IN_1_14 +GType nm_sriov_vf_get_type(void); +NM_AVAILABLE_IN_1_14 +NMSriovVF *nm_sriov_vf_new(guint index); +NM_AVAILABLE_IN_1_14 +void nm_sriov_vf_ref(NMSriovVF *vf); +NM_AVAILABLE_IN_1_14 +void nm_sriov_vf_unref(NMSriovVF *vf); +NM_AVAILABLE_IN_1_14 +gboolean nm_sriov_vf_equal(const NMSriovVF *vf, const NMSriovVF *other); +NM_AVAILABLE_IN_1_14 +NMSriovVF *nm_sriov_vf_dup(const NMSriovVF *vf); +NM_AVAILABLE_IN_1_14 +guint nm_sriov_vf_get_index(const NMSriovVF *vf); +NM_AVAILABLE_IN_1_14 +void nm_sriov_vf_set_attribute(NMSriovVF *vf, const char *name, GVariant *value); +NM_AVAILABLE_IN_1_14 +const char **nm_sriov_vf_get_attribute_names(const NMSriovVF *vf); +NM_AVAILABLE_IN_1_14 +GVariant *nm_sriov_vf_get_attribute(const NMSriovVF *vf, const char *name); +NM_AVAILABLE_IN_1_14 +gboolean +nm_sriov_vf_attribute_validate(const char *name, GVariant *value, gboolean *known, GError **error); + +G_END_DECLS + +#endif /* NM_SETTING_SRIOV_H */ diff --git a/src/libnm-core-public/nm-setting-tc-config.h b/src/libnm-core-public/nm-setting-tc-config.h new file mode 100644 index 0000000..a2bc9a0 --- /dev/null +++ b/src/libnm-core-public/nm-setting-tc-config.h @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef NM_SETTING_TC_CONFIG_H +#define NM_SETTING_TC_CONFIG_H + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +typedef struct NMTCQdisc NMTCQdisc; + +NM_AVAILABLE_IN_1_12 +GType nm_tc_qdisc_get_type(void); + +NM_AVAILABLE_IN_1_12 +NMTCQdisc *nm_tc_qdisc_new(const char *kind, guint32 parent, GError **error); + +NM_AVAILABLE_IN_1_12 +void nm_tc_qdisc_ref(NMTCQdisc *qdisc); +NM_AVAILABLE_IN_1_12 +void nm_tc_qdisc_unref(NMTCQdisc *qdisc); +NM_AVAILABLE_IN_1_12 +gboolean nm_tc_qdisc_equal(NMTCQdisc *qdisc, NMTCQdisc *other); + +NM_AVAILABLE_IN_1_12 +NMTCQdisc *nm_tc_qdisc_dup(NMTCQdisc *qdisc); + +NM_AVAILABLE_IN_1_12 +const char *nm_tc_qdisc_get_kind(NMTCQdisc *qdisc); +NM_AVAILABLE_IN_1_12 +guint32 nm_tc_qdisc_get_handle(NMTCQdisc *qdisc); +NM_AVAILABLE_IN_1_12 +void nm_tc_qdisc_set_handle(NMTCQdisc *qdisc, guint32 handle); +NM_AVAILABLE_IN_1_12 +guint32 nm_tc_qdisc_get_parent(NMTCQdisc *qdisc); + +NM_AVAILABLE_IN_1_18 +const char **nm_tc_qdisc_get_attribute_names(NMTCQdisc *qdisc); +NM_AVAILABLE_IN_1_18 +GVariant *nm_tc_qdisc_get_attribute(NMTCQdisc *qdisc, const char *name); +NM_AVAILABLE_IN_1_18 +void nm_tc_qdisc_set_attribute(NMTCQdisc *qdisc, const char *name, GVariant *value); + +typedef struct NMTCAction NMTCAction; + +NM_AVAILABLE_IN_1_12 +GType nm_tc_action_get_type(void); + +NM_AVAILABLE_IN_1_12 +NMTCAction *nm_tc_action_new(const char *kind, GError **error); + +NM_AVAILABLE_IN_1_12 +void nm_tc_action_ref(NMTCAction *action); +NM_AVAILABLE_IN_1_12 +void nm_tc_action_unref(NMTCAction *action); +NM_AVAILABLE_IN_1_12 +gboolean nm_tc_action_equal(NMTCAction *action, NMTCAction *other); + +NM_AVAILABLE_IN_1_12 +NMTCAction *nm_tc_action_dup(NMTCAction *action); + +NM_AVAILABLE_IN_1_12 +const char *nm_tc_action_get_kind(NMTCAction *action); + +NM_AVAILABLE_IN_1_12 +char **nm_tc_action_get_attribute_names(NMTCAction *action); +NM_AVAILABLE_IN_1_12 +GVariant *nm_tc_action_get_attribute(NMTCAction *action, const char *name); +NM_AVAILABLE_IN_1_12 +void nm_tc_action_set_attribute(NMTCAction *action, const char *name, GVariant *value); + +typedef struct NMTCTfilter NMTCTfilter; + +NM_AVAILABLE_IN_1_12 +GType nm_tc_tfilter_get_type(void); + +NM_AVAILABLE_IN_1_12 +NMTCTfilter *nm_tc_tfilter_new(const char *kind, guint32 parent, GError **error); + +NM_AVAILABLE_IN_1_12 +void nm_tc_tfilter_ref(NMTCTfilter *tfilter); +NM_AVAILABLE_IN_1_12 +void nm_tc_tfilter_unref(NMTCTfilter *tfilter); +NM_AVAILABLE_IN_1_12 +gboolean nm_tc_tfilter_equal(NMTCTfilter *tfilter, NMTCTfilter *other); + +NM_AVAILABLE_IN_1_12 +NMTCTfilter *nm_tc_tfilter_dup(NMTCTfilter *tfilter); + +NM_AVAILABLE_IN_1_12 +const char *nm_tc_tfilter_get_kind(NMTCTfilter *tfilter); +NM_AVAILABLE_IN_1_12 +guint32 nm_tc_tfilter_get_handle(NMTCTfilter *tfilter); +NM_AVAILABLE_IN_1_12 +void nm_tc_tfilter_set_handle(NMTCTfilter *tfilter, guint32 handle); +NM_AVAILABLE_IN_1_12 +guint32 nm_tc_tfilter_get_parent(NMTCTfilter *tfilter); +NM_AVAILABLE_IN_1_12 +NMTCAction *nm_tc_tfilter_get_action(NMTCTfilter *tfilter); +NM_AVAILABLE_IN_1_12 +void nm_tc_tfilter_set_action(NMTCTfilter *tfilter, NMTCAction *action); + +#define NM_TYPE_SETTING_TC_CONFIG (nm_setting_tc_config_get_type()) +#define NM_SETTING_TC_CONFIG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_TC_CONFIG, NMSettingTCConfig)) +#define NM_SETTING_TC_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_TC_CONFIG, NMSettingTCConfigClass)) +#define NM_IS_SETTING_TC_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_TC_CONFIG)) +#define NM_IS_SETTING_TC_CONFIG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_TC_CONFIG)) +#define NM_SETTING_TC_CONFIG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_TC_CONFIG, NMSettingTCConfigClass)) + +#define NM_SETTING_TC_CONFIG_SETTING_NAME "tc" + +#define NM_SETTING_TC_CONFIG_QDISCS "qdiscs" +#define NM_SETTING_TC_CONFIG_TFILTERS "tfilters" + +typedef struct _NMSettingTCConfigClass NMSettingTCConfigClass; + +GType nm_setting_tc_config_get_type(void); + +NM_AVAILABLE_IN_1_12 +NMSetting *nm_setting_tc_config_new(void); + +NM_AVAILABLE_IN_1_12 +guint nm_setting_tc_config_get_num_qdiscs(NMSettingTCConfig *setting); +NM_AVAILABLE_IN_1_12 +NMTCQdisc *nm_setting_tc_config_get_qdisc(NMSettingTCConfig *setting, guint idx); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_tc_config_add_qdisc(NMSettingTCConfig *setting, NMTCQdisc *qdisc); +NM_AVAILABLE_IN_1_12 +void nm_setting_tc_config_remove_qdisc(NMSettingTCConfig *setting, guint idx); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_tc_config_remove_qdisc_by_value(NMSettingTCConfig *setting, NMTCQdisc *qdisc); +NM_AVAILABLE_IN_1_12 +void nm_setting_tc_config_clear_qdiscs(NMSettingTCConfig *setting); + +NM_AVAILABLE_IN_1_12 +guint nm_setting_tc_config_get_num_tfilters(NMSettingTCConfig *setting); +NM_AVAILABLE_IN_1_12 +NMTCTfilter *nm_setting_tc_config_get_tfilter(NMSettingTCConfig *setting, guint idx); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_tc_config_add_tfilter(NMSettingTCConfig *setting, NMTCTfilter *tfilter); +NM_AVAILABLE_IN_1_12 +void nm_setting_tc_config_remove_tfilter(NMSettingTCConfig *setting, guint idx); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_tc_config_remove_tfilter_by_value(NMSettingTCConfig *setting, + NMTCTfilter * tfilter); +NM_AVAILABLE_IN_1_12 +void nm_setting_tc_config_clear_tfilters(NMSettingTCConfig *setting); + +G_END_DECLS + +#endif /* NM_SETTING_TC_CONFIG_H */ diff --git a/src/libnm-core-public/nm-setting-team-port.h b/src/libnm-core-public/nm-setting-team-port.h new file mode 100644 index 0000000..4d4d9bd --- /dev/null +++ b/src/libnm-core-public/nm-setting-team-port.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Jiri Pirko + */ + +#ifndef __NM_SETTING_TEAM_PORT_H__ +#define __NM_SETTING_TEAM_PORT_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" +#include "nm-setting-team.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_TEAM_PORT (nm_setting_team_port_get_type()) +#define NM_SETTING_TEAM_PORT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPort)) +#define NM_SETTING_TEAM_PORT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPortClass)) +#define NM_IS_SETTING_TEAM_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_TEAM_PORT)) +#define NM_IS_SETTING_TEAM_PORT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_TEAM_PORT)) +#define NM_SETTING_TEAM_PORT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPortClass)) + +#define NM_SETTING_TEAM_PORT_SETTING_NAME "team-port" + +#define NM_SETTING_TEAM_PORT_CONFIG "config" +#define NM_SETTING_TEAM_PORT_QUEUE_ID "queue-id" +#define NM_SETTING_TEAM_PORT_PRIO "prio" +#define NM_SETTING_TEAM_PORT_STICKY "sticky" +#define NM_SETTING_TEAM_PORT_LACP_PRIO "lacp-prio" +#define NM_SETTING_TEAM_PORT_LACP_KEY "lacp-key" +#define NM_SETTING_TEAM_PORT_LINK_WATCHERS "link-watchers" + +#define NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT -1 +#define NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT 255 + +/** + * NMSettingTeamPort: + * + * Team Port Settings + */ +struct _NMSettingTeamPort { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingTeamPortClass; + +GType nm_setting_team_port_get_type(void); + +NMSetting *nm_setting_team_port_new(void); + +const char *nm_setting_team_port_get_config(NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_port_get_queue_id(NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_port_get_prio(NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_team_port_get_sticky(NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_port_get_lacp_prio(NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_port_get_lacp_key(NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_12 +guint nm_setting_team_port_get_num_link_watchers(NMSettingTeamPort *setting); +NM_AVAILABLE_IN_1_12 +NMTeamLinkWatcher *nm_setting_team_port_get_link_watcher(NMSettingTeamPort *setting, guint idx); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_team_port_add_link_watcher(NMSettingTeamPort *setting, + NMTeamLinkWatcher *link_watcher); +NM_AVAILABLE_IN_1_12 +void nm_setting_team_port_remove_link_watcher(NMSettingTeamPort *setting, guint idx); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_team_port_remove_link_watcher_by_value(NMSettingTeamPort *setting, + NMTeamLinkWatcher *link_watcher); +NM_AVAILABLE_IN_1_12 +void nm_setting_team_port_clear_link_watchers(NMSettingTeamPort *setting); +G_END_DECLS + +#endif /* __NM_SETTING_TEAM_PORT_H__ */ diff --git a/src/libnm-core-public/nm-setting-team.h b/src/libnm-core-public/nm-setting-team.h new file mode 100644 index 0000000..3f40c8c --- /dev/null +++ b/src/libnm-core-public/nm-setting-team.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2013 Jiri Pirko + */ + +#ifndef __NM_SETTING_TEAM_H__ +#define __NM_SETTING_TEAM_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +/** + * NMTeamLinkWatcherArpPingFlags: + * @NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE: no one among the arp_ping link watcher + * boolean options ('validate_active', 'validate_inactive', 'send_always') is + * enabled (set to true). + * @NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE: the arp_ping link watcher + * option 'validate_active' is enabled (set to true). + * @NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE: the arp_ping link watcher + * option 'validate_inactive' is enabled (set to true). + * @NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS: the arp_ping link watcher option + * 'send_always' is enabled (set to true). + */ +typedef enum { /*< flags >*/ + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE = 0, /*< skip >*/ + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE = 0x2, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE = 0x4, + NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS = 0x8, +} NMTeamLinkWatcherArpPingFlags; + +#define NM_TEAM_LINK_WATCHER_ETHTOOL "ethtool" +#define NM_TEAM_LINK_WATCHER_ARP_PING "arp_ping" +#define NM_TEAM_LINK_WATCHER_NSNA_PING "nsna_ping" + +typedef struct NMTeamLinkWatcher NMTeamLinkWatcher; + +GType nm_team_link_watcher_get_type(void); + +NM_AVAILABLE_IN_1_12 +NMTeamLinkWatcher *nm_team_link_watcher_new_ethtool(int delay_up, int delay_down, GError **error); +NM_AVAILABLE_IN_1_12 +NMTeamLinkWatcher *nm_team_link_watcher_new_nsna_ping(int init_wait, + int interval, + int missed_max, + const char *target_host, + GError ** error); +NM_AVAILABLE_IN_1_12 +NMTeamLinkWatcher *nm_team_link_watcher_new_arp_ping(int init_wait, + int interval, + int missed_max, + const char * target_host, + const char * source_host, + NMTeamLinkWatcherArpPingFlags flags, + GError ** error); +NM_AVAILABLE_IN_1_16 +NMTeamLinkWatcher *nm_team_link_watcher_new_arp_ping2(int init_wait, + int interval, + int missed_max, + int vlanid, + const char * target_host, + const char * source_host, + NMTeamLinkWatcherArpPingFlags flags, + GError ** error); +NM_AVAILABLE_IN_1_12 +void nm_team_link_watcher_ref(NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +void nm_team_link_watcher_unref(NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +gboolean nm_team_link_watcher_equal(const NMTeamLinkWatcher *watcher, + const NMTeamLinkWatcher *other); +NM_AVAILABLE_IN_1_12 +NMTeamLinkWatcher *nm_team_link_watcher_dup(const NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +const char *nm_team_link_watcher_get_name(const NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +int nm_team_link_watcher_get_delay_up(const NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +int nm_team_link_watcher_get_delay_down(const NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +int nm_team_link_watcher_get_init_wait(const NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +int nm_team_link_watcher_get_interval(const NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +int nm_team_link_watcher_get_missed_max(const NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +const char *nm_team_link_watcher_get_target_host(const NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +const char *nm_team_link_watcher_get_source_host(const NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_12 +NMTeamLinkWatcherArpPingFlags nm_team_link_watcher_get_flags(const NMTeamLinkWatcher *watcher); +NM_AVAILABLE_IN_1_16 +int nm_team_link_watcher_get_vlanid(const NMTeamLinkWatcher *watcher); + +#define NM_TYPE_SETTING_TEAM (nm_setting_team_get_type()) +#define NM_SETTING_TEAM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_TEAM, NMSettingTeam)) +#define NM_SETTING_TEAM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_TEAM, NMSettingTeamClass)) +#define NM_IS_SETTING_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_TEAM)) +#define NM_IS_SETTING_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_TEAM)) +#define NM_SETTING_TEAM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_TEAM, NMSettingTeamClass)) + +#define NM_SETTING_TEAM_SETTING_NAME "team" + +#define NM_SETTING_TEAM_CONFIG "config" +#define NM_SETTING_TEAM_NOTIFY_PEERS_COUNT "notify-peers-count" +#define NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL "notify-peers-interval" +#define NM_SETTING_TEAM_MCAST_REJOIN_COUNT "mcast-rejoin-count" +#define NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL "mcast-rejoin-interval" +#define NM_SETTING_TEAM_RUNNER "runner" +#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY "runner-hwaddr-policy" +#define NM_SETTING_TEAM_RUNNER_TX_HASH "runner-tx-hash" +#define NM_SETTING_TEAM_RUNNER_TX_BALANCER "runner-tx-balancer" +#define NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL "runner-tx-balancer-interval" +#define NM_SETTING_TEAM_RUNNER_ACTIVE "runner-active" +#define NM_SETTING_TEAM_RUNNER_FAST_RATE "runner-fast-rate" +#define NM_SETTING_TEAM_RUNNER_SYS_PRIO "runner-sys-prio" +#define NM_SETTING_TEAM_RUNNER_MIN_PORTS "runner-min-ports" +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY "runner-agg-select-policy" +#define NM_SETTING_TEAM_LINK_WATCHERS "link-watchers" + +#define NM_SETTING_TEAM_RUNNER_BROADCAST "broadcast" +#define NM_SETTING_TEAM_RUNNER_ROUNDROBIN "roundrobin" +#define NM_SETTING_TEAM_RUNNER_RANDOM "random" +#define NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP "activebackup" +#define NM_SETTING_TEAM_RUNNER_LOADBALANCE "loadbalance" +#define NM_SETTING_TEAM_RUNNER_LACP "lacp" + +#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL "same_all" +#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE "by_active" +#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE "only_active" + +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO "lacp_prio" +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO_STABLE "lacp_prio_stable" +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_BANDWIDTH "bandwidth" +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_COUNT "count" +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_PORT_CONFIG "port_config" + +#define NM_SETTING_TEAM_NOTIFY_PEERS_COUNT_ACTIVEBACKUP_DEFAULT 1 +#define NM_SETTING_TEAM_NOTIFY_MCAST_COUNT_ACTIVEBACKUP_DEFAULT 1 +#define NM_SETTING_TEAM_RUNNER_DEFAULT NM_SETTING_TEAM_RUNNER_ROUNDROBIN +#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_DEFAULT NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL +#define NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT 50 +#define NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT 65535 +#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_DEFAULT \ + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO + +/** + * NMSettingTeam: + * + * Teaming Settings + */ +struct _NMSettingTeam { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingTeamClass; + +GType nm_setting_team_get_type(void); + +NMSetting *nm_setting_team_new(void); + +const char *nm_setting_team_get_config(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_get_notify_peers_count(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_get_notify_peers_interval(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_get_mcast_rejoin_count(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_get_mcast_rejoin_interval(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +const char *nm_setting_team_get_runner(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +const char *nm_setting_team_get_runner_hwaddr_policy(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +const char *nm_setting_team_get_runner_tx_balancer(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_get_runner_tx_balancer_interval(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_team_get_runner_active(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_team_get_runner_fast_rate(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_get_runner_sys_prio(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +int nm_setting_team_get_runner_min_ports(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +const char *nm_setting_team_get_runner_agg_select_policy(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_team_remove_runner_tx_hash_by_value(NMSettingTeam *setting, const char *txhash); +NM_AVAILABLE_IN_1_12 +guint nm_setting_team_get_num_runner_tx_hash(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +const char *nm_setting_team_get_runner_tx_hash(NMSettingTeam *setting, guint idx); +NM_AVAILABLE_IN_1_12 +void nm_setting_team_remove_runner_tx_hash(NMSettingTeam *setting, guint idx); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_team_add_runner_tx_hash(NMSettingTeam *setting, const char *txhash); +NM_AVAILABLE_IN_1_12 +guint nm_setting_team_get_num_link_watchers(NMSettingTeam *setting); +NM_AVAILABLE_IN_1_12 +NMTeamLinkWatcher *nm_setting_team_get_link_watcher(NMSettingTeam *setting, guint idx); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_team_add_link_watcher(NMSettingTeam *setting, NMTeamLinkWatcher *link_watcher); +NM_AVAILABLE_IN_1_12 +void nm_setting_team_remove_link_watcher(NMSettingTeam *setting, guint idx); +NM_AVAILABLE_IN_1_12 +gboolean nm_setting_team_remove_link_watcher_by_value(NMSettingTeam * setting, + NMTeamLinkWatcher *link_watcher); +NM_AVAILABLE_IN_1_12 +void nm_setting_team_clear_link_watchers(NMSettingTeam *setting); +G_END_DECLS + +#endif /* __NM_SETTING_TEAM_H__ */ diff --git a/src/libnm-core-public/nm-setting-tun.h b/src/libnm-core-public/nm-setting-tun.h new file mode 100644 index 0000000..3fbbf08 --- /dev/null +++ b/src/libnm-core-public/nm-setting-tun.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_TUN_H__ +#define __NM_SETTING_TUN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_TUN (nm_setting_tun_get_type()) +#define NM_SETTING_TUN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_TUN, NMSettingTun)) +#define NM_SETTING_TUN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_TUNCONFIG, NMSettingTunClass)) +#define NM_IS_SETTING_TUN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_TUN)) +#define NM_IS_SETTING_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_TUN)) +#define NM_SETTING_TUN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_TUN, NMSettingTunClass)) + +#define NM_SETTING_TUN_SETTING_NAME "tun" + +#define NM_SETTING_TUN_MODE "mode" +#define NM_SETTING_TUN_OWNER "owner" +#define NM_SETTING_TUN_GROUP "group" +#define NM_SETTING_TUN_PI "pi" +#define NM_SETTING_TUN_VNET_HDR "vnet-hdr" +#define NM_SETTING_TUN_MULTI_QUEUE "multi-queue" + +/** + * NMSettingTunMode: + * @NM_SETTING_TUN_MODE_UNKNOWN: an unknown device type + * @NM_SETTING_TUN_MODE_TUN: a TUN device + * @NM_SETTING_TUN_MODE_TAP: a TAP device + * + * #NMSettingTunMode values indicate the device type (TUN/TAP) + */ +typedef enum { + NM_SETTING_TUN_MODE_UNKNOWN = 0, + NM_SETTING_TUN_MODE_TUN = 1, + NM_SETTING_TUN_MODE_TAP = 2, +} NMSettingTunMode; + +/** + * NMSettingTun: + * + * Tunnel Settings + */ +struct _NMSettingTun { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingTunClass; + +NM_AVAILABLE_IN_1_2 +GType nm_setting_tun_get_type(void); +NM_AVAILABLE_IN_1_2 +NMSetting *nm_setting_tun_new(void); + +NM_AVAILABLE_IN_1_2 +NMSettingTunMode nm_setting_tun_get_mode(NMSettingTun *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_tun_get_owner(NMSettingTun *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_tun_get_group(NMSettingTun *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_tun_get_pi(NMSettingTun *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_tun_get_vnet_hdr(NMSettingTun *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_tun_get_multi_queue(NMSettingTun *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_TUN_H__ */ diff --git a/src/libnm-core-public/nm-setting-user.h b/src/libnm-core-public/nm-setting-user.h new file mode 100644 index 0000000..b151cd3 --- /dev/null +++ b/src/libnm-core-public/nm-setting-user.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_USER_H__ +#define __NM_SETTING_USER_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_USER (nm_setting_user_get_type()) +#define NM_SETTING_USER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_USER, NMSettingUser)) +#define NM_SETTING_USER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_USER, NMSettingUserClass)) +#define NM_IS_SETTING_USER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_USER)) +#define NM_IS_SETTING_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_USER)) +#define NM_SETTING_USER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_USER, NMSettingUserClass)) + +#define NM_SETTING_USER_SETTING_NAME "user" + +#define NM_SETTING_USER_DATA "data" + +typedef struct _NMSettingUserClass NMSettingUserClass; + +NM_AVAILABLE_IN_1_8 +GType nm_setting_user_get_type(void); + +NM_AVAILABLE_IN_1_8 +NMSetting *nm_setting_user_new(void); + +NM_AVAILABLE_IN_1_8 +const char *const *nm_setting_user_get_keys(NMSettingUser *setting, guint *out_len); + +NM_AVAILABLE_IN_1_8 +const char *nm_setting_user_get_data(NMSettingUser *setting, const char *key); +NM_AVAILABLE_IN_1_8 +gboolean +nm_setting_user_set_data(NMSettingUser *setting, const char *key, const char *val, GError **error); + +NM_AVAILABLE_IN_1_8 +gboolean nm_setting_user_check_key(const char *key, GError **error); +NM_AVAILABLE_IN_1_8 +gboolean nm_setting_user_check_val(const char *val, GError **error); + +G_END_DECLS + +#endif /* __NM_SETTING_USER_H__ */ diff --git a/src/libnm-core-public/nm-setting-veth.h b/src/libnm-core-public/nm-setting-veth.h new file mode 100644 index 0000000..5dbc192 --- /dev/null +++ b/src/libnm-core-public/nm-setting-veth.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_VETH_H__ +#define __NM_SETTING_VETH_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_VETH (nm_setting_veth_get_type()) +#define NM_SETTING_VETH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_VETH, NMSettingVeth)) +#define NM_IS_SETTING_VETH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_VETH)) +#define NM_IS_SETTING_VETH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_VETH)) +#define NM_SETTING_VETH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_VETH, NMSettingVethClass)) + +#define NM_SETTING_VETH_SETTING_NAME "veth" + +#define NM_SETTING_VETH_PEER "peer" + +typedef struct _NMSettingVethClass NMSettingVethClass; + +NM_AVAILABLE_IN_1_30 +GType nm_setting_veth_get_type(void); +NM_AVAILABLE_IN_1_30 +NMSetting *nm_setting_veth_new(void); + +NM_AVAILABLE_IN_1_30 +const char *nm_setting_veth_get_peer(NMSettingVeth *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_VETH_H__ */ diff --git a/src/libnm-core-public/nm-setting-vlan.h b/src/libnm-core-public/nm-setting-vlan.h new file mode 100644 index 0000000..af781ee --- /dev/null +++ b/src/libnm-core-public/nm-setting-vlan.h @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_VLAN_H__ +#define __NM_SETTING_VLAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_VLAN (nm_setting_vlan_get_type()) +#define NM_SETTING_VLAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_VLAN, NMSettingVlan)) +#define NM_SETTING_VLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_VLANCONFIG, NMSettingVlanClass)) +#define NM_IS_SETTING_VLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_VLAN)) +#define NM_IS_SETTING_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_VLAN)) +#define NM_SETTING_VLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_VLAN, NMSettingVlanClass)) + +#define NM_SETTING_VLAN_SETTING_NAME "vlan" + +#define NM_SETTING_VLAN_PARENT "parent" +#define NM_SETTING_VLAN_ID "id" +#define NM_SETTING_VLAN_FLAGS "flags" +#define NM_SETTING_VLAN_INGRESS_PRIORITY_MAP "ingress-priority-map" +#define NM_SETTING_VLAN_EGRESS_PRIORITY_MAP "egress-priority-map" + +/** + * NMSettingVlan: + * + * VLAN Settings + */ +struct _NMSettingVlan { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingVlanClass; + +/** + * NMVlanPriorityMap: + * @NM_VLAN_INGRESS_MAP: map for incoming data + * @NM_VLAN_EGRESS_MAP: map for outgoing data + * + * A selector for traffic priority maps; these map Linux SKB priorities + * to 802.1p priorities used in VLANs. + **/ +/* clang-format off */ +typedef enum { + NM_VLAN_INGRESS_MAP, + NM_VLAN_EGRESS_MAP +} NMVlanPriorityMap; +/* clang-format on */ + +/** + * NMVlanFlags: + * @NM_VLAN_FLAG_REORDER_HEADERS: indicates that this interface should reorder + * outgoing packet headers to look more like a non-VLAN Ethernet interface + * @NM_VLAN_FLAG_GVRP: indicates that this interface should use GVRP to register + * itself with its switch + * @NM_VLAN_FLAG_LOOSE_BINDING: indicates that this interface's operating + * state is tied to the underlying network interface but other details + * (like routing) are not. + * @NM_VLAN_FLAG_MVRP: indicates that this interface should use MVRP to register + * itself with its switch + * + * #NMVlanFlags values control the behavior of the VLAN interface. + **/ +typedef enum { /*< flags >*/ + + NM_VLAN_FLAG_REORDER_HEADERS = 0x1, + NM_VLAN_FLAG_GVRP = 0x2, + NM_VLAN_FLAG_LOOSE_BINDING = 0x4, + NM_VLAN_FLAG_MVRP = 0x8, + + /* NOTE: if adding flags update nm-setting-vlan.c::verify() */ + + /* NOTE: these flags must correspond to the value from the kernel + * header files. */ +} NMVlanFlags; + +#define NM_VLAN_FLAGS_ALL \ + (NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP | NM_VLAN_FLAG_LOOSE_BINDING \ + | NM_VLAN_FLAG_MVRP) + +GType nm_setting_vlan_get_type(void); +NMSetting *nm_setting_vlan_new(void); + +const char *nm_setting_vlan_get_parent(NMSettingVlan *setting); +guint32 nm_setting_vlan_get_id(NMSettingVlan *setting); +guint32 nm_setting_vlan_get_flags(NMSettingVlan *setting); + +gint32 nm_setting_vlan_get_num_priorities(NMSettingVlan *setting, NMVlanPriorityMap map); + +gboolean nm_setting_vlan_get_priority(NMSettingVlan * setting, + NMVlanPriorityMap map, + guint32 idx, + guint32 * out_from, + guint32 * out_to); + +gboolean nm_setting_vlan_add_priority(NMSettingVlan * setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to); + +void nm_setting_vlan_remove_priority(NMSettingVlan *setting, NMVlanPriorityMap map, guint32 idx); + +gboolean nm_setting_vlan_remove_priority_by_value(NMSettingVlan * setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to); + +gboolean nm_setting_vlan_remove_priority_str_by_value(NMSettingVlan * setting, + NMVlanPriorityMap map, + const char * str); + +void nm_setting_vlan_clear_priorities(NMSettingVlan *setting, NMVlanPriorityMap map); + +gboolean +nm_setting_vlan_add_priority_str(NMSettingVlan *setting, NMVlanPriorityMap map, const char *str); + +G_END_DECLS + +#endif /* __NM_SETTING_VLAN_H__ */ diff --git a/src/libnm-core-public/nm-setting-vpn.h b/src/libnm-core-public/nm-setting-vpn.h new file mode 100644 index 0000000..9e5d6e4 --- /dev/null +++ b/src/libnm-core-public/nm-setting-vpn.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_VPN_H__ +#define __NM_SETTING_VPN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_VPN (nm_setting_vpn_get_type()) +#define NM_SETTING_VPN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_VPN, NMSettingVpn)) +#define NM_SETTING_VPN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_VPN, NMSettingVpnClass)) +#define NM_IS_SETTING_VPN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_VPN)) +#define NM_IS_SETTING_VPN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_VPN)) +#define NM_SETTING_VPN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_VPN, NMSettingVpnClass)) + +#define NM_SETTING_VPN_SETTING_NAME "vpn" + +#define NM_SETTING_VPN_SERVICE_TYPE "service-type" +#define NM_SETTING_VPN_USER_NAME "user-name" +#define NM_SETTING_VPN_PERSISTENT "persistent" +#define NM_SETTING_VPN_DATA "data" +#define NM_SETTING_VPN_SECRETS "secrets" +#define NM_SETTING_VPN_TIMEOUT "timeout" + +/** + * NMSettingVpn: + * + * VPN Settings + */ +struct _NMSettingVpn { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingVpnClass; + +/** + * NMVpnIterFunc: + * @key: the name of the data or secret item + * @value: the value of the data or secret item + * @user_data: User data passed to nm_setting_vpn_foreach_data_item() or + * nm_setting_vpn_foreach_secret() + **/ +typedef void (*NMVpnIterFunc)(const char *key, const char *value, gpointer user_data); + +GType nm_setting_vpn_get_type(void); + +NMSetting * nm_setting_vpn_new(void); +const char *nm_setting_vpn_get_service_type(NMSettingVpn *setting); +const char *nm_setting_vpn_get_user_name(NMSettingVpn *setting); +gboolean nm_setting_vpn_get_persistent(NMSettingVpn *setting); + +guint32 nm_setting_vpn_get_num_data_items(NMSettingVpn *setting); +void nm_setting_vpn_add_data_item(NMSettingVpn *setting, const char *key, const char *item); +const char *nm_setting_vpn_get_data_item(NMSettingVpn *setting, const char *key); +gboolean nm_setting_vpn_remove_data_item(NMSettingVpn *setting, const char *key); +void +nm_setting_vpn_foreach_data_item(NMSettingVpn *setting, NMVpnIterFunc func, gpointer user_data); +NM_AVAILABLE_IN_1_12 +const char **nm_setting_vpn_get_data_keys(NMSettingVpn *setting, guint *out_length); + +guint32 nm_setting_vpn_get_num_secrets(NMSettingVpn *setting); +void nm_setting_vpn_add_secret(NMSettingVpn *setting, const char *key, const char *secret); +const char *nm_setting_vpn_get_secret(NMSettingVpn *setting, const char *key); +gboolean nm_setting_vpn_remove_secret(NMSettingVpn *setting, const char *key); +void nm_setting_vpn_foreach_secret(NMSettingVpn *setting, NMVpnIterFunc func, gpointer user_data); +NM_AVAILABLE_IN_1_12 +const char **nm_setting_vpn_get_secret_keys(NMSettingVpn *setting, guint *out_length); + +NM_AVAILABLE_IN_1_2 +guint32 nm_setting_vpn_get_timeout(NMSettingVpn *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_VPN_H__ */ diff --git a/src/libnm-core-public/nm-setting-vrf.h b/src/libnm-core-public/nm-setting-vrf.h new file mode 100644 index 0000000..afa044b --- /dev/null +++ b/src/libnm-core-public/nm-setting-vrf.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_SETTING_VRF_H__ +#define __NM_SETTING_VRF_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_VRF (nm_setting_vrf_get_type()) +#define NM_SETTING_VRF(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_VRF, NMSettingVrf)) +#define NM_SETTING_VRF_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_VRFCONFIG, NMSettingVrfClass)) +#define NM_IS_SETTING_VRF(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_VRF)) +#define NM_IS_SETTING_VRF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_VRF)) +#define NM_SETTING_VRF_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_VRF, NMSettingVrfClass)) + +#define NM_SETTING_VRF_SETTING_NAME "vrf" + +#define NM_SETTING_VRF_TABLE "table" + +typedef struct _NMSettingVrfClass NMSettingVrfClass; + +NM_AVAILABLE_IN_1_24 +GType nm_setting_vrf_get_type(void); +NM_AVAILABLE_IN_1_24 +NMSetting *nm_setting_vrf_new(void); +NM_AVAILABLE_IN_1_24 +guint32 nm_setting_vrf_get_table(NMSettingVrf *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_VRF_H__ */ diff --git a/src/libnm-core-public/nm-setting-vxlan.h b/src/libnm-core-public/nm-setting-vxlan.h new file mode 100644 index 0000000..9b987b6 --- /dev/null +++ b/src/libnm-core-public/nm-setting-vxlan.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_VXLAN_H__ +#define __NM_SETTING_VXLAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_VXLAN (nm_setting_vxlan_get_type()) +#define NM_SETTING_VXLAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_VXLAN, NMSettingVxlan)) +#define NM_SETTING_VXLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_VXLANCONFIG, NMSettingVxlanClass)) +#define NM_IS_SETTING_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_VXLAN)) +#define NM_IS_SETTING_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_VXLAN)) +#define NM_SETTING_VXLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_VXLAN, NMSettingVxlanClass)) + +#define NM_SETTING_VXLAN_SETTING_NAME "vxlan" + +#define NM_SETTING_VXLAN_PARENT "parent" +#define NM_SETTING_VXLAN_ID "id" +#define NM_SETTING_VXLAN_LOCAL "local" +#define NM_SETTING_VXLAN_REMOTE "remote" +#define NM_SETTING_VXLAN_SOURCE_PORT_MIN "source-port-min" +#define NM_SETTING_VXLAN_SOURCE_PORT_MAX "source-port-max" +#define NM_SETTING_VXLAN_DESTINATION_PORT "destination-port" +#define NM_SETTING_VXLAN_TOS "tos" +#define NM_SETTING_VXLAN_TTL "ttl" +#define NM_SETTING_VXLAN_AGEING "ageing" +#define NM_SETTING_VXLAN_LIMIT "limit" +#define NM_SETTING_VXLAN_PROXY "proxy" +#define NM_SETTING_VXLAN_LEARNING "learning" +#define NM_SETTING_VXLAN_RSC "rsc" +#define NM_SETTING_VXLAN_L2_MISS "l2-miss" +#define NM_SETTING_VXLAN_L3_MISS "l3-miss" + +/** + * NMSettingVxlan: + * + * VXLAN Settings + */ +struct _NMSettingVxlan { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingVxlanClass; + +NM_AVAILABLE_IN_1_2 +GType nm_setting_vxlan_get_type(void); +NM_AVAILABLE_IN_1_2 +NMSetting *nm_setting_vxlan_new(void); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_vxlan_get_parent(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_id(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_vxlan_get_local(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +const char *nm_setting_vxlan_get_remote(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_source_port_min(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_source_port_max(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_destination_port(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_tos(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_ttl(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_ageing(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_vxlan_get_limit(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_vxlan_get_proxy(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_vxlan_get_learning(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_vxlan_get_rsc(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_vxlan_get_l2_miss(NMSettingVxlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_vxlan_get_l3_miss(NMSettingVxlan *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_VXLAN_H__ */ diff --git a/src/libnm-core-public/nm-setting-wifi-p2p.h b/src/libnm-core-public/nm-setting-wifi-p2p.h new file mode 100644 index 0000000..029b75f --- /dev/null +++ b/src/libnm-core-public/nm-setting-wifi-p2p.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_WIFI_P2P_H__ +#define __NM_SETTING_WIFI_P2P_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" +#include "nm-setting-wireless-security.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIFI_P2P (nm_setting_wifi_p2p_get_type()) +#define NM_SETTING_WIFI_P2P(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_WIFI_P2P, NMSettingWifiP2P)) +#define NM_SETTING_WIFI_P2P_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_WIFI_P2P, NMSettingWifiP2PClass)) +#define NM_IS_SETTING_WIFI_P2P(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_WIFI_P2P)) +#define NM_IS_SETTING_WIFI_P2P_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_WIFI_P2P)) +#define NM_SETTING_WIFI_P2P_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_WIFI_P2P, NMSettingWifiP2PClass)) + +#define NM_SETTING_WIFI_P2P_SETTING_NAME "wifi-p2p" + +/** + * NM_SETTING_WIFI_P2P_PEER: + * + * The mac address of the peer to connect to. + */ +#define NM_SETTING_WIFI_P2P_PEER "peer" +#define NM_SETTING_WIFI_P2P_WPS_METHOD "wps-method" +#define NM_SETTING_WIFI_P2P_WFD_IES "wfd-ies" + +typedef struct _NMSettingWifiP2PClass NMSettingWifiP2PClass; + +NM_AVAILABLE_IN_1_16 +GType nm_setting_wifi_p2p_get_type(void); + +NM_AVAILABLE_IN_1_16 +NMSetting *nm_setting_wifi_p2p_new(void); + +NM_AVAILABLE_IN_1_16 +const char *nm_setting_wifi_p2p_get_peer(NMSettingWifiP2P *setting); + +NM_AVAILABLE_IN_1_16 +NMSettingWirelessSecurityWpsMethod nm_setting_wifi_p2p_get_wps_method(NMSettingWifiP2P *setting); + +NM_AVAILABLE_IN_1_16 +GBytes *nm_setting_wifi_p2p_get_wfd_ies(NMSettingWifiP2P *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_WIFI_P2P_H__ */ diff --git a/src/libnm-core-public/nm-setting-wimax.h b/src/libnm-core-public/nm-setting-wimax.h new file mode 100644 index 0000000..7279e04 --- /dev/null +++ b/src/libnm-core-public/nm-setting-wimax.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2009 Novell, Inc. + */ + +#ifndef __NM_SETTING_WIMAX_H__ +#define __NM_SETTING_WIMAX_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIMAX (nm_setting_wimax_get_type()) +#define NM_SETTING_WIMAX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_WIMAX, NMSettingWimax)) +#define NM_SETTING_WIMAX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_WIMAX, NMSettingWimaxClass)) +#define NM_IS_SETTING_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_WIMAX)) +#define NM_IS_SETTING_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_WIMAX)) +#define NM_SETTING_WIMAX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_WIMAX, NMSettingWimaxClass)) + +#define NM_SETTING_WIMAX_SETTING_NAME "wimax" + +#define NM_SETTING_WIMAX_NETWORK_NAME "network-name" +#define NM_SETTING_WIMAX_MAC_ADDRESS "mac-address" + +/** + * NMSettingWimax: + * + * WiMax Settings + */ +struct _NMSettingWimax { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingWimaxClass; + +NM_DEPRECATED_IN_1_2 +GType nm_setting_wimax_get_type(void); + +NM_DEPRECATED_IN_1_2 +NMSetting *nm_setting_wimax_new(void); +NM_DEPRECATED_IN_1_2 +const char *nm_setting_wimax_get_network_name(NMSettingWimax *setting); +NM_DEPRECATED_IN_1_2 +const char *nm_setting_wimax_get_mac_address(NMSettingWimax *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_WIMAX_H__ */ diff --git a/src/libnm-core-public/nm-setting-wired.h b/src/libnm-core-public/nm-setting-wired.h new file mode 100644 index 0000000..acabd70 --- /dev/null +++ b/src/libnm-core-public/nm-setting-wired.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_WIRED_H__ +#define __NM_SETTING_WIRED_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIRED (nm_setting_wired_get_type()) +#define NM_SETTING_WIRED(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_WIRED, NMSettingWired)) +#define NM_SETTING_WIRED_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_WIRED, NMSettingWiredClass)) +#define NM_IS_SETTING_WIRED(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_WIRED)) +#define NM_IS_SETTING_WIRED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_WIRED)) +#define NM_SETTING_WIRED_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_WIRED, NMSettingWiredClass)) + +#define NM_SETTING_WIRED_SETTING_NAME "802-3-ethernet" + +/** + * NMSettingWiredWakeOnLan: + * @NM_SETTING_WIRED_WAKE_ON_LAN_NONE: Wake-on-LAN disabled + * @NM_SETTING_WIRED_WAKE_ON_LAN_PHY: Wake on PHY activity + * @NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST: Wake on unicast messages + * @NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST: Wake on multicast messages + * @NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST: Wake on broadcast messages + * @NM_SETTING_WIRED_WAKE_ON_LAN_ARP: Wake on ARP + * @NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC: Wake on magic packet + * @NM_SETTING_WIRED_WAKE_ON_LAN_ALL: Wake on all events. This does not + * include the exclusive flags @NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT or + * @NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE. + * @NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT: Use the default value + * @NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE: Don't change configured settings + * @NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS: Mask of flags that are + * incompatible with other flags + * + * Options for #NMSettingWired:wake-on-lan. Note that not all options + * are supported by all devices. + * + * Since: 1.2 + */ +typedef enum { /*< flags >*/ + NM_SETTING_WIRED_WAKE_ON_LAN_NONE = 0, /*< skip >*/ + NM_SETTING_WIRED_WAKE_ON_LAN_PHY = 0x2, + NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST = 0x4, + NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST = 0x8, + NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST = 0x10, + NM_SETTING_WIRED_WAKE_ON_LAN_ARP = 0x20, + NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC = 0x40, + + NM_SETTING_WIRED_WAKE_ON_LAN_ALL = 0x7E, /*< skip >*/ + + NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT = 0x1, + NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE = 0x8000, + NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS = 0x8001, /*< skip >*/ +} NMSettingWiredWakeOnLan; + +#define NM_SETTING_WIRED_PORT "port" +#define NM_SETTING_WIRED_SPEED "speed" +#define NM_SETTING_WIRED_DUPLEX "duplex" +#define NM_SETTING_WIRED_AUTO_NEGOTIATE "auto-negotiate" +#define NM_SETTING_WIRED_MAC_ADDRESS "mac-address" +#define NM_SETTING_WIRED_CLONED_MAC_ADDRESS "cloned-mac-address" +#define NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK "generate-mac-address-mask" +#define NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST "mac-address-blacklist" +#define NM_SETTING_WIRED_MTU "mtu" +#define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels" +#define NM_SETTING_WIRED_S390_NETTYPE "s390-nettype" +#define NM_SETTING_WIRED_S390_OPTIONS "s390-options" +#define NM_SETTING_WIRED_WAKE_ON_LAN "wake-on-lan" +#define NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD "wake-on-lan-password" + +/** + * NMSettingWired: + * + * Wired Ethernet Settings + */ +struct _NMSettingWired { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingWiredClass; + +GType nm_setting_wired_get_type(void); + +NMSetting * nm_setting_wired_new(void); +const char *nm_setting_wired_get_port(NMSettingWired *setting); +guint32 nm_setting_wired_get_speed(NMSettingWired *setting); +const char *nm_setting_wired_get_duplex(NMSettingWired *setting); +gboolean nm_setting_wired_get_auto_negotiate(NMSettingWired *setting); +const char *nm_setting_wired_get_mac_address(NMSettingWired *setting); +const char *nm_setting_wired_get_cloned_mac_address(NMSettingWired *setting); + +NM_AVAILABLE_IN_1_4 +const char *nm_setting_wired_get_generate_mac_address_mask(NMSettingWired *setting); + +const char *const *nm_setting_wired_get_mac_address_blacklist(NMSettingWired *setting); +guint32 nm_setting_wired_get_num_mac_blacklist_items(NMSettingWired *setting); +const char * nm_setting_wired_get_mac_blacklist_item(NMSettingWired *setting, guint32 idx); +gboolean nm_setting_wired_add_mac_blacklist_item(NMSettingWired *setting, const char *mac); +void nm_setting_wired_remove_mac_blacklist_item(NMSettingWired *setting, guint32 idx); +gboolean nm_setting_wired_remove_mac_blacklist_item_by_value(NMSettingWired *setting, + const char * mac); +void nm_setting_wired_clear_mac_blacklist_items(NMSettingWired *setting); + +guint32 nm_setting_wired_get_mtu(NMSettingWired *setting); + +const char *const *nm_setting_wired_get_s390_subchannels(NMSettingWired *setting); +const char * nm_setting_wired_get_s390_nettype(NMSettingWired *setting); + +guint32 nm_setting_wired_get_num_s390_options(NMSettingWired *setting); +gboolean nm_setting_wired_get_s390_option(NMSettingWired *setting, + guint32 idx, + const char ** out_key, + const char ** out_value); +const char *nm_setting_wired_get_s390_option_by_key(NMSettingWired *setting, const char *key); +gboolean +nm_setting_wired_add_s390_option(NMSettingWired *setting, const char *key, const char *value); +gboolean nm_setting_wired_remove_s390_option(NMSettingWired *setting, const char *key); +const char **nm_setting_wired_get_valid_s390_options(NMSettingWired *setting); + +NMSettingWiredWakeOnLan nm_setting_wired_get_wake_on_lan(NMSettingWired *setting); +const char * nm_setting_wired_get_wake_on_lan_password(NMSettingWired *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_WIRED_H__ */ diff --git a/src/libnm-core-public/nm-setting-wireguard.h b/src/libnm-core-public/nm-setting-wireguard.h new file mode 100644 index 0000000..3f046fc --- /dev/null +++ b/src/libnm-core-public/nm-setting-wireguard.h @@ -0,0 +1,202 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 - 2019 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_WIREGUARD_H__ +#define __NM_SETTING_WIREGUARD_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" +#include "nm-utils.h" + +G_BEGIN_DECLS + +/*****************************************************************************/ + +#define NM_WIREGUARD_PUBLIC_KEY_LEN 32 +#define NM_WIREGUARD_SYMMETRIC_KEY_LEN 32 + +/*****************************************************************************/ + +typedef struct _NMWireGuardPeer NMWireGuardPeer; + +NM_AVAILABLE_IN_1_16 +GType nm_wireguard_peer_get_type(void); + +NM_AVAILABLE_IN_1_16 +NMWireGuardPeer *nm_wireguard_peer_new(void); + +NM_AVAILABLE_IN_1_16 +NMWireGuardPeer *nm_wireguard_peer_new_clone(const NMWireGuardPeer *self, gboolean with_secrets); + +NM_AVAILABLE_IN_1_16 +NMWireGuardPeer *nm_wireguard_peer_ref(NMWireGuardPeer *self); +NM_AVAILABLE_IN_1_16 +void nm_wireguard_peer_unref(NMWireGuardPeer *self); + +NM_AVAILABLE_IN_1_16 +void nm_wireguard_peer_seal(NMWireGuardPeer *self); +NM_AVAILABLE_IN_1_16 +gboolean nm_wireguard_peer_is_sealed(const NMWireGuardPeer *self); + +NM_AVAILABLE_IN_1_16 +const char *nm_wireguard_peer_get_public_key(const NMWireGuardPeer *self); +NM_AVAILABLE_IN_1_16 +gboolean nm_wireguard_peer_set_public_key(NMWireGuardPeer *self, + const char * public_key, + gboolean accept_invalid); + +NM_AVAILABLE_IN_1_16 +const char *nm_wireguard_peer_get_preshared_key(const NMWireGuardPeer *self); +NM_AVAILABLE_IN_1_16 +gboolean nm_wireguard_peer_set_preshared_key(NMWireGuardPeer *self, + const char * preshared_key, + gboolean accept_invalid); + +NM_AVAILABLE_IN_1_16 +NMSettingSecretFlags nm_wireguard_peer_get_preshared_key_flags(const NMWireGuardPeer *self); +NM_AVAILABLE_IN_1_16 +void nm_wireguard_peer_set_preshared_key_flags(NMWireGuardPeer * self, + NMSettingSecretFlags preshared_key_flags); + +NM_AVAILABLE_IN_1_16 +guint16 nm_wireguard_peer_get_persistent_keepalive(const NMWireGuardPeer *self); +NM_AVAILABLE_IN_1_16 +void nm_wireguard_peer_set_persistent_keepalive(NMWireGuardPeer *self, + guint16 persistent_keepalive); + +NM_AVAILABLE_IN_1_16 +const char *nm_wireguard_peer_get_endpoint(const NMWireGuardPeer *self); +NM_AVAILABLE_IN_1_16 +gboolean +nm_wireguard_peer_set_endpoint(NMWireGuardPeer *self, const char *endpoint, gboolean allow_invalid); + +NM_AVAILABLE_IN_1_16 +guint nm_wireguard_peer_get_allowed_ips_len(const NMWireGuardPeer *self); +NM_AVAILABLE_IN_1_16 +const char * +nm_wireguard_peer_get_allowed_ip(const NMWireGuardPeer *self, guint idx, gboolean *out_is_valid); +NM_AVAILABLE_IN_1_16 +void nm_wireguard_peer_clear_allowed_ips(NMWireGuardPeer *self); +NM_AVAILABLE_IN_1_16 +gboolean nm_wireguard_peer_append_allowed_ip(NMWireGuardPeer *self, + const char * allowed_ip, + gboolean accept_invalid); +NM_AVAILABLE_IN_1_16 +gboolean nm_wireguard_peer_remove_allowed_ip(NMWireGuardPeer *self, guint idx); + +NM_AVAILABLE_IN_1_16 +gboolean nm_wireguard_peer_is_valid(const NMWireGuardPeer *self, + gboolean check_non_secrets, + gboolean check_secrets, + GError ** error); + +NM_AVAILABLE_IN_1_16 +int nm_wireguard_peer_cmp(const NMWireGuardPeer *a, + const NMWireGuardPeer *b, + NMSettingCompareFlags compare_flags); + +/*****************************************************************************/ + +#define NM_TYPE_SETTING_WIREGUARD (nm_setting_wireguard_get_type()) +#define NM_SETTING_WIREGUARD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_WIREGUARD, NMSettingWireGuard)) +#define NM_SETTING_WIREGUARD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_WIREGUARD, NMSettingWireGuardClass)) +#define NM_IS_SETTING_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_WIREGUARD)) +#define NM_IS_SETTING_WIREGUARD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_WIREGUARD)) +#define NM_SETTING_WIREGUARD_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_WIREGUARD, NMSettingWireGuardClass)) + +#define NM_SETTING_WIREGUARD_SETTING_NAME "wireguard" + +#define NM_SETTING_WIREGUARD_FWMARK "fwmark" +#define NM_SETTING_WIREGUARD_LISTEN_PORT "listen-port" +#define NM_SETTING_WIREGUARD_PRIVATE_KEY "private-key" +#define NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS "private-key-flags" + +#define NM_SETTING_WIREGUARD_PEERS "peers" + +#define NM_SETTING_WIREGUARD_MTU "mtu" +#define NM_SETTING_WIREGUARD_PEER_ROUTES "peer-routes" +#define NM_SETTING_WIREGUARD_IP4_AUTO_DEFAULT_ROUTE "ip4-auto-default-route" +#define NM_SETTING_WIREGUARD_IP6_AUTO_DEFAULT_ROUTE "ip6-auto-default-route" + +#define NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS "allowed-ips" +#define NM_WIREGUARD_PEER_ATTR_ENDPOINT "endpoint" +#define NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE "persistent-keepalive" +#define NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY "preshared-key" +#define NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY_FLAGS "preshared-key-flags" +#define NM_WIREGUARD_PEER_ATTR_PUBLIC_KEY "public-key" + +/*****************************************************************************/ + +typedef struct _NMSettingWireGuardClass NMSettingWireGuardClass; + +NM_AVAILABLE_IN_1_16 +GType nm_setting_wireguard_get_type(void); + +NM_AVAILABLE_IN_1_16 +NMSetting *nm_setting_wireguard_new(void); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_16 +const char *nm_setting_wireguard_get_private_key(NMSettingWireGuard *self); + +NM_AVAILABLE_IN_1_16 +NMSettingSecretFlags nm_setting_wireguard_get_private_key_flags(NMSettingWireGuard *self); + +NM_AVAILABLE_IN_1_16 +guint16 nm_setting_wireguard_get_listen_port(NMSettingWireGuard *self); + +NM_AVAILABLE_IN_1_16 +guint32 nm_setting_wireguard_get_fwmark(NMSettingWireGuard *self); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_16 +guint nm_setting_wireguard_get_peers_len(NMSettingWireGuard *self); + +NM_AVAILABLE_IN_1_16 +NMWireGuardPeer *nm_setting_wireguard_get_peer(NMSettingWireGuard *self, guint idx); + +NM_AVAILABLE_IN_1_16 +NMWireGuardPeer *nm_setting_wireguard_get_peer_by_public_key(NMSettingWireGuard *self, + const char * public_key, + guint * out_idx); + +NM_AVAILABLE_IN_1_16 +void nm_setting_wireguard_set_peer(NMSettingWireGuard *self, NMWireGuardPeer *peer, guint idx); + +NM_AVAILABLE_IN_1_16 +void nm_setting_wireguard_append_peer(NMSettingWireGuard *self, NMWireGuardPeer *peer); + +NM_AVAILABLE_IN_1_16 +gboolean nm_setting_wireguard_remove_peer(NMSettingWireGuard *self, guint idx); + +NM_AVAILABLE_IN_1_16 +guint nm_setting_wireguard_clear_peers(NMSettingWireGuard *self); + +NM_AVAILABLE_IN_1_16 +gboolean nm_setting_wireguard_get_peer_routes(NMSettingWireGuard *self); + +NM_AVAILABLE_IN_1_16 +guint32 nm_setting_wireguard_get_mtu(NMSettingWireGuard *self); + +NM_AVAILABLE_IN_1_20 +NMTernary nm_setting_wireguard_get_ip4_auto_default_route(NMSettingWireGuard *self); + +NM_AVAILABLE_IN_1_20 +NMTernary nm_setting_wireguard_get_ip6_auto_default_route(NMSettingWireGuard *self); + +/*****************************************************************************/ + +G_END_DECLS + +#endif /* __NM_SETTING_WIREGUARD_H__ */ diff --git a/src/libnm-core-public/nm-setting-wireless-security.h b/src/libnm-core-public/nm-setting-wireless-security.h new file mode 100644 index 0000000..62a3c6e --- /dev/null +++ b/src/libnm-core-public/nm-setting-wireless-security.h @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2017 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_WIRELESS_SECURITY_H__ +#define __NM_SETTING_WIRELESS_SECURITY_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_get_type()) +#define NM_SETTING_WIRELESS_SECURITY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + NM_TYPE_SETTING_WIRELESS_SECURITY, \ + NMSettingWirelessSecurity)) +#define NM_SETTING_WIRELESS_SECURITY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + NM_TYPE_SETTING_WIRELESS_SECURITY, \ + NMSettingWirelessSecurityClass)) +#define NM_IS_SETTING_WIRELESS_SECURITY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_WIRELESS_SECURITY)) +#define NM_IS_SETTING_WIRELESS_SECURITY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_WIRELESS_SECURITY)) +#define NM_SETTING_WIRELESS_SECURITY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + NM_TYPE_SETTING_WIRELESS_SECURITY, \ + NMSettingWirelessSecurityClass)) + +#define NM_SETTING_WIRELESS_SECURITY_SETTING_NAME "802-11-wireless-security" + +/** + * NMWepKeyType: + * @NM_WEP_KEY_TYPE_UNKNOWN: unknown WEP key type + * @NM_WEP_KEY_TYPE_KEY: indicates a hexadecimal or ASCII formatted WEP key. + * Hex keys are either 10 or 26 hexadecimal characters (ie "5f782f2f5f" or + * "732f2d712e4a394a375d366931"), while ASCII keys are either 5 or 13 ASCII + * characters (ie "abcde" or "blahblah99$*1"). + * @NM_WEP_KEY_TYPE_PASSPHRASE: indicates a WEP passphrase (ex "I bought a duck + * on my way back from the market 235Q&^%^*%") instead of a hexadecimal or ASCII + * key. Passphrases are between 8 and 64 characters inclusive and are hashed + * the actual WEP key using the MD5 hash algorithm. + * @NM_WEP_KEY_TYPE_LAST: placeholder value for bounds-checking + * + * The #NMWepKeyType values specify how any WEP keys present in the setting + * are interpreted. There are no standards governing how to hash the various WEP + * key/passphrase formats into the actual WEP key. Unfortunately some WEP keys + * can be interpreted in multiple ways, requiring the setting to specify how to + * interpret the any WEP keys. For example, the key "732f2d712e4a394a375d366931" + * is both a valid Hexadecimal WEP key and a WEP passphrase. Further, many + * ASCII keys are also valid WEP passphrases, but since passphrases and ASCII + * keys are hashed differently to determine the actual WEP key the type must be + * specified. + */ +typedef enum { + NM_WEP_KEY_TYPE_UNKNOWN = 0, + NM_WEP_KEY_TYPE_KEY = 1, /* Hex or ASCII */ + NM_WEP_KEY_TYPE_PASSPHRASE = 2, /* 104/128-bit Passphrase */ + + NM_WEP_KEY_TYPE_LAST = NM_WEP_KEY_TYPE_PASSPHRASE, /*< skip >*/ +} NMWepKeyType; + +/** + * NMSettingWirelessSecurityPmf: + * @NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT: use the default value + * @NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE: disable PMF + * @NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL: enable PMF if the supplicant and the AP support it + * @NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED: require PMF and fail if not available + * + * These flags indicate whether PMF must be enabled. + **/ +typedef enum { + NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT = 0, + NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE = 1, + NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL = 2, + NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED = 3, + _NM_SETTING_WIRELESS_SECURITY_PMF_NUM, /*< skip >*/ + NM_SETTING_WIRELESS_SECURITY_PMF_LAST = _NM_SETTING_WIRELESS_SECURITY_PMF_NUM - 1, /*< skip >*/ +} NMSettingWirelessSecurityPmf; + +/** + * NMSettingWirelessSecurityWpsMethod: + * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT: Attempt whichever method AP supports + * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DISABLED: WPS can not be used. + * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_AUTO: Use WPS, any method + * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PBC: use WPS push-button method + * @NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN: use PIN method + * + * Configure the use of WPS by a connection while it activates. + * + * Note: prior to 1.16, this was a GEnum type instead of a GFlags type + * although, with the same numeric values. + * + * Since: 1.10 + **/ +typedef enum { /*< flags >*/ + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT = 0x00000000, + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DISABLED = 0x00000001, + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_AUTO = 0x00000002, + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PBC = 0x00000004, + NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN = 0x00000008, +} NMSettingWirelessSecurityWpsMethod; + +/** + * NMSettingWirelessSecurityFils: + * @NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT: use the default value + * @NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE: disable FILS + * @NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL: enable FILS if the supplicant and the AP support it + * @NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED: require FILS and fail if not available + * @_NM_SETTING_WIRELESS_SECURITY_FILS_NUM: placeholder value for bounds-checking + * @NM_SETTING_WIRELESS_SECURITY_FILS_LAST: placeholder value for bounds-checking + * + * These flags indicate whether FILS must be enabled. + * + * Since: 1.12 + **/ +/* clang-format off */ +typedef enum { + NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT = 0, + NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE = 1, + NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL = 2, + NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED = 3, + _NM_SETTING_WIRELESS_SECURITY_FILS_NUM, /*< skip >*/ + NM_SETTING_WIRELESS_SECURITY_FILS_LAST = _NM_SETTING_WIRELESS_SECURITY_FILS_NUM - 1, /*< skip >*/ +} NMSettingWirelessSecurityFils; +/* clang-format on */ + +#define NM_SETTING_WIRELESS_SECURITY_KEY_MGMT "key-mgmt" +#define NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX "wep-tx-keyidx" +#define NM_SETTING_WIRELESS_SECURITY_AUTH_ALG "auth-alg" +#define NM_SETTING_WIRELESS_SECURITY_PROTO "proto" +#define NM_SETTING_WIRELESS_SECURITY_PAIRWISE "pairwise" +#define NM_SETTING_WIRELESS_SECURITY_GROUP "group" +#define NM_SETTING_WIRELESS_SECURITY_PMF "pmf" +#define NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME "leap-username" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY0 "wep-key0" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY1 "wep-key1" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY2 "wep-key2" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY3 "wep-key3" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS "wep-key-flags" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE "wep-key-type" +#define NM_SETTING_WIRELESS_SECURITY_PSK "psk" +#define NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS "psk-flags" +#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD "leap-password" +#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS "leap-password-flags" +#define NM_SETTING_WIRELESS_SECURITY_WPS_METHOD "wps-method" +#define NM_SETTING_WIRELESS_SECURITY_FILS "fils" + +/** + * NMSettingWirelessSecurity: + * + * Wi-Fi Security Settings + */ +struct _NMSettingWirelessSecurity { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingWirelessSecurityClass; + +GType nm_setting_wireless_security_get_type(void); + +NMSetting *nm_setting_wireless_security_new(void); + +const char *nm_setting_wireless_security_get_key_mgmt(NMSettingWirelessSecurity *setting); + +guint32 nm_setting_wireless_security_get_num_protos(NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_proto(NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_add_proto(NMSettingWirelessSecurity *setting, + const char * proto); +void nm_setting_wireless_security_remove_proto(NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_remove_proto_by_value(NMSettingWirelessSecurity *setting, + const char * proto); +void nm_setting_wireless_security_clear_protos(NMSettingWirelessSecurity *setting); + +guint32 nm_setting_wireless_security_get_num_pairwise(NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_pairwise(NMSettingWirelessSecurity *setting, + guint32 i); +gboolean nm_setting_wireless_security_add_pairwise(NMSettingWirelessSecurity *setting, + const char * pairwise); +void nm_setting_wireless_security_remove_pairwise(NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_remove_pairwise_by_value(NMSettingWirelessSecurity *setting, + const char * pairwise); +void nm_setting_wireless_security_clear_pairwise(NMSettingWirelessSecurity *setting); + +guint32 nm_setting_wireless_security_get_num_groups(NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_group(NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_add_group(NMSettingWirelessSecurity *setting, + const char * group); +void nm_setting_wireless_security_remove_group(NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_remove_group_by_value(NMSettingWirelessSecurity *setting, + const char * group); +void nm_setting_wireless_security_clear_groups(NMSettingWirelessSecurity *setting); + +NM_AVAILABLE_IN_1_10 +NMSettingWirelessSecurityPmf +nm_setting_wireless_security_get_pmf(NMSettingWirelessSecurity *setting); + +const char * nm_setting_wireless_security_get_psk(NMSettingWirelessSecurity *setting); +NMSettingSecretFlags nm_setting_wireless_security_get_psk_flags(NMSettingWirelessSecurity *setting); + +const char *nm_setting_wireless_security_get_leap_username(NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_leap_password(NMSettingWirelessSecurity *setting); +NMSettingSecretFlags +nm_setting_wireless_security_get_leap_password_flags(NMSettingWirelessSecurity *setting); + +const char *nm_setting_wireless_security_get_wep_key(NMSettingWirelessSecurity *setting, + guint32 idx); +void nm_setting_wireless_security_set_wep_key(NMSettingWirelessSecurity *setting, + guint32 idx, + const char * key); +guint32 nm_setting_wireless_security_get_wep_tx_keyidx(NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_auth_alg(NMSettingWirelessSecurity *setting); + +NMSettingSecretFlags + nm_setting_wireless_security_get_wep_key_flags(NMSettingWirelessSecurity *setting); +NMWepKeyType nm_setting_wireless_security_get_wep_key_type(NMSettingWirelessSecurity *setting); + +NM_AVAILABLE_IN_1_10 +NMSettingWirelessSecurityWpsMethod +nm_setting_wireless_security_get_wps_method(NMSettingWirelessSecurity *setting); + +NM_AVAILABLE_IN_1_12 +NMSettingWirelessSecurityFils +nm_setting_wireless_security_get_fils(NMSettingWirelessSecurity *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_WIRELESS_SECURITY_H__ */ diff --git a/src/libnm-core-public/nm-setting-wireless.h b/src/libnm-core-public/nm-setting-wireless.h new file mode 100644 index 0000000..f97e236 --- /dev/null +++ b/src/libnm-core-public/nm-setting-wireless.h @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2014 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_WIRELESS_H__ +#define __NM_SETTING_WIRELESS_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" +#include "nm-setting-wireless-security.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIRELESS (nm_setting_wireless_get_type()) +#define NM_SETTING_WIRELESS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_WIRELESS, NMSettingWireless)) +#define NM_SETTING_WIRELESS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessClass)) +#define NM_IS_SETTING_WIRELESS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_WIRELESS)) +#define NM_IS_SETTING_WIRELESS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_WIRELESS)) +#define NM_SETTING_WIRELESS_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessClass)) + +#define NM_SETTING_WIRELESS_SETTING_NAME "802-11-wireless" + +/** + * NMSettingWirelessWakeOnWLan: + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE: Wake-on-WLAN disabled + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY: Wake on any activity + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT: Wake on disconnect + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC: Wake on magic packet + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE: Wake on GTK rekey failure + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST: Wake on EAP identity request + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE: Wake on 4way handshake + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE: Wake on rfkill release + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL: Wake on all events. This does not + * include the exclusive flags @NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT or + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE. + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT: Use the default value + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE: Don't change configured settings + * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS: Mask of flags that are + * incompatible with other flags + * + * Options for #NMSettingWireless:wake-on-wlan. Note that not all options + * are supported by all devices. + * + * Since: 1.12 + */ +/* clang-format off */ +typedef enum { /*< flags >*/ + NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE = 0, /*< skip >*/ + NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY = 0x2, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT = 0x4, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC = 0x8, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE = 0x10, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST = 0x20, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE = 0x40, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE = 0x80, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP = 0x100, + + NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL = 0x1FE, + + NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT = 0x1, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE = 0x8000, + + NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT | NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE, /*< skip >*/ +} NMSettingWirelessWakeOnWLan; +/* clang-format on */ + +#define NM_SETTING_WIRELESS_SSID "ssid" +#define NM_SETTING_WIRELESS_MODE "mode" +#define NM_SETTING_WIRELESS_BAND "band" +#define NM_SETTING_WIRELESS_CHANNEL "channel" +#define NM_SETTING_WIRELESS_BSSID "bssid" +#define NM_SETTING_WIRELESS_RATE "rate" +#define NM_SETTING_WIRELESS_TX_POWER "tx-power" +#define NM_SETTING_WIRELESS_MAC_ADDRESS "mac-address" +#define NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS "cloned-mac-address" +#define NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK "generate-mac-address-mask" +#define NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST "mac-address-blacklist" +#define NM_SETTING_WIRELESS_MTU "mtu" +#define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids" +#define NM_SETTING_WIRELESS_HIDDEN "hidden" +#define NM_SETTING_WIRELESS_POWERSAVE "powersave" +#define NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION "mac-address-randomization" +#define NM_SETTING_WIRELESS_WAKE_ON_WLAN "wake-on-wlan" +#define NM_SETTING_WIRELESS_AP_ISOLATION "ap-isolation" + +/** + * NM_SETTING_WIRELESS_MODE_ADHOC: + * + * Indicates Ad-Hoc mode where no access point is expected to be present. + */ +#define NM_SETTING_WIRELESS_MODE_ADHOC "adhoc" + +/** + * NM_SETTING_WIRELESS_MODE_AP: + * + * Indicates AP/master mode where the wireless device is started as an access + * point/hotspot. + */ +#define NM_SETTING_WIRELESS_MODE_AP "ap" + +/** + * NM_SETTING_WIRELESS_MODE_INFRA: + * + * Indicates infrastructure mode where an access point is expected to be present + * for this connection. + */ +#define NM_SETTING_WIRELESS_MODE_INFRA "infrastructure" + +/** + * NM_SETTING_WIRELESS_MODE_MESH: + * + * Indicates that the connection should create a mesh point. + * + * Since: 1.20 + */ +#define NM_SETTING_WIRELESS_MODE_MESH "mesh" + +/** + * NMSettingWirelessPowersave: + * @NM_SETTING_WIRELESS_POWERSAVE_DEFAULT: use the default value + * @NM_SETTING_WIRELESS_POWERSAVE_IGNORE: don't touch existing setting + * @NM_SETTING_WIRELESS_POWERSAVE_DISABLE: disable powersave + * @NM_SETTING_WIRELESS_POWERSAVE_ENABLE: enable powersave + * + * These flags indicate whether wireless powersave must be enabled. + **/ +typedef enum { + NM_SETTING_WIRELESS_POWERSAVE_DEFAULT = 0, + NM_SETTING_WIRELESS_POWERSAVE_IGNORE = 1, + NM_SETTING_WIRELESS_POWERSAVE_DISABLE = 2, + NM_SETTING_WIRELESS_POWERSAVE_ENABLE = 3, + _NM_SETTING_WIRELESS_POWERSAVE_NUM, /*< skip >*/ + NM_SETTING_WIRELESS_POWERSAVE_LAST = _NM_SETTING_WIRELESS_POWERSAVE_NUM - 1, /*< skip >*/ +} NMSettingWirelessPowersave; + +/** + * NMSettingWireless: + * + * Wi-Fi Settings + */ +struct _NMSettingWireless { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingWirelessClass; + +GType nm_setting_wireless_get_type(void); + +NMSetting *nm_setting_wireless_new(void); + +GBytes * nm_setting_wireless_get_ssid(NMSettingWireless *setting); +const char *nm_setting_wireless_get_mode(NMSettingWireless *setting); +const char *nm_setting_wireless_get_band(NMSettingWireless *setting); +guint32 nm_setting_wireless_get_channel(NMSettingWireless *setting); +const char *nm_setting_wireless_get_bssid(NMSettingWireless *setting); +guint32 nm_setting_wireless_get_rate(NMSettingWireless *setting); +guint32 nm_setting_wireless_get_tx_power(NMSettingWireless *setting); +const char *nm_setting_wireless_get_mac_address(NMSettingWireless *setting); +const char *nm_setting_wireless_get_cloned_mac_address(NMSettingWireless *setting); + +NM_AVAILABLE_IN_1_4 +const char *nm_setting_wireless_get_generate_mac_address_mask(NMSettingWireless *setting); + +const char *const *nm_setting_wireless_get_mac_address_blacklist(NMSettingWireless *setting); +guint32 nm_setting_wireless_get_num_mac_blacklist_items(NMSettingWireless *setting); +const char *nm_setting_wireless_get_mac_blacklist_item(NMSettingWireless *setting, guint32 idx); +gboolean nm_setting_wireless_add_mac_blacklist_item(NMSettingWireless *setting, const char *mac); +void nm_setting_wireless_remove_mac_blacklist_item(NMSettingWireless *setting, guint32 idx); +gboolean nm_setting_wireless_remove_mac_blacklist_item_by_value(NMSettingWireless *setting, + const char * mac); +void nm_setting_wireless_clear_mac_blacklist_items(NMSettingWireless *setting); + +guint32 nm_setting_wireless_get_mtu(NMSettingWireless *setting); +gboolean nm_setting_wireless_get_hidden(NMSettingWireless *setting); +NM_AVAILABLE_IN_1_2 +guint32 nm_setting_wireless_get_powersave(NMSettingWireless *setting); + +NM_AVAILABLE_IN_1_2 +NMSettingMacRandomization +nm_setting_wireless_get_mac_address_randomization(NMSettingWireless *setting); + +gboolean nm_setting_wireless_add_seen_bssid(NMSettingWireless *setting, const char *bssid); + +guint32 nm_setting_wireless_get_num_seen_bssids(NMSettingWireless *setting); +const char *nm_setting_wireless_get_seen_bssid(NMSettingWireless *setting, guint32 i); + +gboolean nm_setting_wireless_ap_security_compatible(NMSettingWireless * s_wireless, + NMSettingWirelessSecurity *s_wireless_sec, + NM80211ApFlags ap_flags, + NM80211ApSecurityFlags ap_wpa, + NM80211ApSecurityFlags ap_rsn, + NM80211Mode ap_mode); + +NM_AVAILABLE_IN_1_12 +NMSettingWirelessWakeOnWLan nm_setting_wireless_get_wake_on_wlan(NMSettingWireless *setting); + +NM_AVAILABLE_IN_1_28 +NMTernary nm_setting_wireless_get_ap_isolation(NMSettingWireless *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_WIRELESS_H__ */ diff --git a/src/libnm-core-public/nm-setting-wpan.h b/src/libnm-core-public/nm-setting-wpan.h new file mode 100644 index 0000000..2a09d49 --- /dev/null +++ b/src/libnm-core-public/nm-setting-wpan.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Lubomir Rintel + */ + +#ifndef __NM_SETTING_WPAN_H__ +#define __NM_SETTING_WPAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WPAN (nm_setting_wpan_get_type()) +#define NM_SETTING_WPAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_WPAN, NMSettingWpan)) +#define NM_SETTING_WPAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_WPANCONFIG, NMSettingWpanClass)) +#define NM_IS_SETTING_WPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_WPAN)) +#define NM_IS_SETTING_WPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_WPAN)) +#define NM_SETTING_WPAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_WPAN, NMSettingWpanClass)) + +#define NM_SETTING_WPAN_SETTING_NAME "wpan" +#define NM_SETTING_WPAN_MAC_ADDRESS "mac-address" +#define NM_SETTING_WPAN_PAN_ID "pan-id" +#define NM_SETTING_WPAN_SHORT_ADDRESS "short-address" +#define NM_SETTING_WPAN_PAGE "page" +#define NM_SETTING_WPAN_CHANNEL "channel" + +#define NM_SETTING_WPAN_PAGE_DEFAULT -1 +#define NM_SETTING_WPAN_CHANNEL_DEFAULT -1 + +typedef struct _NMSettingWpanClass NMSettingWpanClass; + +NM_AVAILABLE_IN_1_14 +GType nm_setting_wpan_get_type(void); +NM_AVAILABLE_IN_1_14 +NMSetting *nm_setting_wpan_new(void); + +NM_AVAILABLE_IN_1_14 +const char *nm_setting_wpan_get_mac_address(NMSettingWpan *setting); +NM_AVAILABLE_IN_1_14 +guint16 nm_setting_wpan_get_pan_id(NMSettingWpan *setting); +NM_AVAILABLE_IN_1_14 +guint16 nm_setting_wpan_get_short_address(NMSettingWpan *setting); +NM_AVAILABLE_IN_1_16 +gint16 nm_setting_wpan_get_page(NMSettingWpan *setting); +NM_AVAILABLE_IN_1_16 +gint16 nm_setting_wpan_get_channel(NMSettingWpan *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_WPAN_H__ */ diff --git a/src/libnm-core-public/nm-setting.h b/src/libnm-core-public/nm-setting.h new file mode 100644 index 0000000..e5cf753 --- /dev/null +++ b/src/libnm-core-public/nm-setting.h @@ -0,0 +1,353 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_H__ +#define __NM_SETTING_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-core-types.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING (nm_setting_get_type()) +#define NM_SETTING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING, NMSetting)) +#define NM_SETTING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING, NMSettingClass)) +#define NM_IS_SETTING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING)) +#define NM_IS_SETTING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING)) +#define NM_SETTING_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING, NMSettingClass)) + +/* The property of the #NMSetting is required for the setting to be valid */ +#define NM_SETTING_PARAM_REQUIRED (1 << (1 + G_PARAM_USER_SHIFT)) + +/* The property of the #NMSetting is a secret */ +#define NM_SETTING_PARAM_SECRET (1 << (2 + G_PARAM_USER_SHIFT)) + +/* The property of the #NMSetting should be ignored during comparisons that + * use the %NM_SETTING_COMPARE_FLAG_FUZZY flag. + */ +#define NM_SETTING_PARAM_FUZZY_IGNORE (1 << (3 + G_PARAM_USER_SHIFT)) + +/* Note: all non-glib GParamFlags bits are reserved by NetworkManager */ + +#define NM_SETTING_NAME "name" + +/** + * NMSettingSecretFlags: + * @NM_SETTING_SECRET_FLAG_NONE: the system is responsible for providing and + * storing this secret (default) + * @NM_SETTING_SECRET_FLAG_AGENT_OWNED: a user secret agent is responsible + * for providing and storing this secret; when it is required agents will be + * asked to retrieve it + * @NM_SETTING_SECRET_FLAG_NOT_SAVED: this secret should not be saved, but + * should be requested from the user each time it is needed + * @NM_SETTING_SECRET_FLAG_NOT_REQUIRED: in situations where it cannot be + * automatically determined that the secret is required (some VPNs and PPP + * providers don't require all secrets) this flag indicates that the specific + * secret is not required + * + * These flags indicate specific behavior related to handling of a secret. Each + * secret has a corresponding set of these flags which indicate how the secret + * is to be stored and/or requested when it is needed. + * + **/ +typedef enum { /*< flags >*/ + NM_SETTING_SECRET_FLAG_NONE = 0x00000000, + NM_SETTING_SECRET_FLAG_AGENT_OWNED = 0x00000001, + NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002, + NM_SETTING_SECRET_FLAG_NOT_REQUIRED = 0x00000004 + + /* NOTE: if adding flags, update nm-core-internal.h as well */ +} NMSettingSecretFlags; + +/** + * NMSettingCompareFlags: + * @NM_SETTING_COMPARE_FLAG_EXACT: match all properties exactly + * @NM_SETTING_COMPARE_FLAG_FUZZY: match only important attributes, like SSID, + * type, security settings, etc. Does not match, for example, connection ID + * or UUID. + * @NM_SETTING_COMPARE_FLAG_IGNORE_ID: ignore the connection's ID + * @NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS: ignore all secrets + * @NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS: ignore secrets for which + * the secret's flags indicate the secret is owned by a user secret agent + * (ie, the secret's flag includes @NM_SETTING_SECRET_FLAG_AGENT_OWNED) + * @NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS: ignore secrets for which + * the secret's flags indicate the secret should not be saved to persistent + * storage (ie, the secret's flag includes @NM_SETTING_SECRET_FLAG_NOT_SAVED) + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT: if this flag is set, + * nm_setting_diff() and nm_connection_diff() will also include properties that + * are set to their default value. See also @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT. + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT: if this flag is set, + * nm_setting_diff() and nm_connection_diff() will not include properties that + * are set to their default value. This is the opposite of + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT. If both flags are set together, + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT wins. If both flags are unset, + * this means to exclude default properties if there is a setting to compare, + * but include all properties, if the setting 'b' is missing. This is the legacy + * behaviour of libnm-util, where nm_setting_diff() behaved differently depending + * on whether the setting 'b' was available. If @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT + * is set, nm_setting_diff() will also set the flags @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT + * and @NM_SETTING_DIFF_RESULT_IN_B_DEFAULT, if the values are default values. + * @NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP: ignore the connection's timestamp + * + * These flags modify the comparison behavior when comparing two settings or + * two connections. + * + **/ +typedef enum { + NM_SETTING_COMPARE_FLAG_EXACT = 0x00000000, + NM_SETTING_COMPARE_FLAG_FUZZY = 0x00000001, + NM_SETTING_COMPARE_FLAG_IGNORE_ID = 0x00000002, + NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS = 0x00000004, + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS = 0x00000008, + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS = 0x00000010, + NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT = 0x00000020, + NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT = 0x00000040, + NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP = 0x00000080, + + /* Higher flags like 0x80000000 and 0x40000000 are used internally as private flags */ +} NMSettingCompareFlags; + +/** + * NMSettingMacRandomization: + * @NM_SETTING_MAC_RANDOMIZATION_DEFAULT: the default value, which unless + * overridden by user-controlled defaults configuration, is "never". + * @NM_SETTING_MAC_RANDOMIZATION_NEVER: the device's MAC address is always used. + * @NM_SETTING_MAC_RANDOMIZATION_ALWAYS: a random MAC address is used. + * + * Controls if and how the MAC address of a device is randomzied. + **/ +typedef enum { + NM_SETTING_MAC_RANDOMIZATION_DEFAULT = 0, + NM_SETTING_MAC_RANDOMIZATION_NEVER, + NM_SETTING_MAC_RANDOMIZATION_ALWAYS, +} NMSettingMacRandomization; + +/** + * NMSetting: + * + * The NMSetting struct contains only private data. + * It should only be accessed through the functions described below. + */ +struct _NMSetting { + GObject parent; +}; + +/** + * NMSettingClearSecretsWithFlagsFn: + * @setting: The setting for which secrets are being iterated + * @secret: The secret's name + * @flags: The secret's flags, eg %NM_SETTING_SECRET_FLAG_AGENT_OWNED + * @user_data: User data passed to nm_connection_clear_secrets_with_flags() + * + * Returns: %TRUE to clear the secret, %FALSE to not clear the secret + */ +typedef gboolean (*NMSettingClearSecretsWithFlagsFn)(NMSetting * setting, + const char * secret, + NMSettingSecretFlags flags, + gpointer user_data); + +struct _NMMetaSettingInfo; +struct _NMSettInfoSetting; +struct _NMSettInfoProperty; + +/** + * NMSettingValueIterFn: + * @setting: The setting for which properties are being iterated, given to + * nm_setting_enumerate_values() + * @key: The value/property name + * @value: The property's value + * @flags: The property's flags, like %NM_SETTING_PARAM_SECRET + * @user_data: User data passed to nm_setting_enumerate_values() + */ +typedef void (*NMSettingValueIterFn)(NMSetting * setting, + const char * key, + const GValue *value, + GParamFlags flags, + gpointer user_data); + +/*< private >*/ +typedef gboolean (*_NMConnectionForEachSecretFunc)(NMSettingSecretFlags flags, gpointer user_data); + +typedef struct { + GObjectClass parent; + + /* Virtual functions */ + int (*verify)(NMSetting *setting, NMConnection *connection, GError **error); + + gboolean (*verify_secrets)(NMSetting *setting, NMConnection *connection, GError **error); + + GPtrArray *(*need_secrets)(NMSetting *setting); + + int (*update_one_secret)(NMSetting *setting, const char *key, GVariant *value, GError **error); + + gboolean (*get_secret_flags)(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags *out_flags, + GError ** error); + + gboolean (*set_secret_flags)(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags flags, + GError ** error); + + /*< private >*/ + gboolean (*clear_secrets)(const struct _NMSettInfoSetting *sett_info, + guint property_idx, + NMSetting * setting, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data); + + /* compare_property() returns a ternary, where DEFAULT means that the property should not + * be compared due to the compare @flags. A TRUE/FALSE result means that the property is + * equal/not-equal. + * + * @other may be %NULL, in which case the function only determines whether + * the setting should be compared (TRUE) or not (DEFAULT). */ + /*< private >*/ + NMTernary (*compare_property)(const struct _NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags); + + /*< private >*/ + void (*duplicate_copy_properties)(const struct _NMSettInfoSetting *sett_info, + NMSetting * src, + NMSetting * dst); + + /*< private >*/ + void (*enumerate_values)(const struct _NMSettInfoProperty *property_info, + NMSetting * setting, + NMSettingValueIterFn func, + gpointer user_data); + + /*< private >*/ + gboolean (*aggregate)(NMSetting *setting, int type_i, gpointer arg); + + /*< private >*/ + void (*for_each_secret)(NMSetting * setting, + const char * secret_name, + GVariant * val, + gboolean remove_non_secrets, + _NMConnectionForEachSecretFunc callback, + gpointer callback_data, + GVariantBuilder * setting_builder); + + /*< private >*/ + gboolean (*init_from_dbus)(NMSetting * setting, + GHashTable * keys, + GVariant * setting_dict, + GVariant * connection_dict, + guint /* NMSettingParseFlags */ parse_flags, + GError ** error); + + /*< private >*/ + gpointer padding[1]; + + /*< private >*/ + const struct _NMMetaSettingInfo *setting_info; +} NMSettingClass; + +GType nm_setting_get_type(void); + +GType nm_setting_lookup_type(const char *name); + +NMSetting *nm_setting_duplicate(NMSetting *setting); + +const char *nm_setting_get_name(NMSetting *setting); + +gboolean nm_setting_verify(NMSetting *setting, NMConnection *connection, GError **error); + +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_verify_secrets(NMSetting *setting, NMConnection *connection, GError **error); + +gboolean nm_setting_compare(NMSetting *a, NMSetting *b, NMSettingCompareFlags flags); + +/** + * NMSettingDiffResult: + * @NM_SETTING_DIFF_RESULT_UNKNOWN: unknown result + * @NM_SETTING_DIFF_RESULT_IN_A: the property is present in setting A + * @NM_SETTING_DIFF_RESULT_IN_B: the property is present in setting B + * @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT: the property is present in + * setting A but is set to the default value. This flag is only set, + * if you specify @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT. + * @NM_SETTING_DIFF_RESULT_IN_B_DEFAULT: analog to @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT. + * + * These values indicate the result of a setting difference operation. + **/ +typedef enum { + NM_SETTING_DIFF_RESULT_UNKNOWN = 0x00000000, + NM_SETTING_DIFF_RESULT_IN_A = 0x00000001, + NM_SETTING_DIFF_RESULT_IN_B = 0x00000002, + NM_SETTING_DIFF_RESULT_IN_A_DEFAULT = 0x00000004, + NM_SETTING_DIFF_RESULT_IN_B_DEFAULT = 0x00000008, +} NMSettingDiffResult; + +gboolean nm_setting_diff(NMSetting * a, + NMSetting * b, + NMSettingCompareFlags flags, + gboolean invert_results, + GHashTable ** results); + +void nm_setting_enumerate_values(NMSetting *setting, NMSettingValueIterFn func, gpointer user_data); + +char *nm_setting_to_string(NMSetting *setting); + +/*****************************************************************************/ + +gboolean nm_setting_get_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags *out_flags, + GError ** error); + +gboolean nm_setting_set_secret_flags(NMSetting * setting, + const char * secret_name, + NMSettingSecretFlags flags, + GError ** error); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_26 +GVariant *nm_setting_option_get(NMSetting *setting, const char *opt_name); + +NM_AVAILABLE_IN_1_26 +gboolean +nm_setting_option_get_boolean(NMSetting *setting, const char *opt_name, gboolean *out_value); + +NM_AVAILABLE_IN_1_26 +gboolean nm_setting_option_get_uint32(NMSetting *setting, const char *opt_name, guint32 *out_value); + +NM_AVAILABLE_IN_1_26 +void nm_setting_option_set(NMSetting *setting, const char *opt_name, GVariant *variant); + +NM_AVAILABLE_IN_1_26 +void nm_setting_option_set_uint32(NMSetting *setting, const char *opt_name, guint32 value); + +NM_AVAILABLE_IN_1_26 +void nm_setting_option_set_boolean(NMSetting *setting, const char *opt_name, gboolean value); + +NM_AVAILABLE_IN_1_26 +const char *const *nm_setting_option_get_all_names(NMSetting *setting, guint *out_len); + +NM_AVAILABLE_IN_1_26 +void nm_setting_option_clear_by_name(NMSetting *setting, NMUtilsPredicateStr predicate); + +/*****************************************************************************/ + +const GVariantType *nm_setting_get_dbus_property_type(NMSetting * setting, + const char *property_name); + +/*****************************************************************************/ + +G_END_DECLS + +#endif /* __NM_SETTING_H__ */ diff --git a/src/libnm-core-public/nm-simple-connection.h b/src/libnm-core-public/nm-simple-connection.h new file mode 100644 index 0000000..38473b6 --- /dev/null +++ b/src/libnm-core-public/nm-simple-connection.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NM_SIMPLE_CONNECTION_H__ +#define __NM_SIMPLE_CONNECTION_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include "nm-connection.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SIMPLE_CONNECTION (nm_simple_connection_get_type()) +#define NM_SIMPLE_CONNECTION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SIMPLE_CONNECTION, NMSimpleConnection)) +#define NM_SIMPLE_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SIMPLE_CONNECTION, NMSimpleConnectionClass)) +#define NM_IS_SIMPLE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SIMPLE_CONNECTION)) +#define NM_IS_SIMPLE_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SIMPLE_CONNECTION)) +#define NM_SIMPLE_CONNECTION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SIMPLE_CONNECTION, NMSimpleConnectionClass)) + +/** + * NMSimpleConnection: + */ +struct _NMSimpleConnection { + GObject parent; +}; + +typedef struct { + GObjectClass parent_class; + + /*< private >*/ + gpointer padding[4]; +} NMSimpleConnectionClass; + +GType nm_simple_connection_get_type(void); + +NMConnection *nm_simple_connection_new(void); + +NMConnection *nm_simple_connection_new_from_dbus(GVariant *dict, GError **error); + +NMConnection *nm_simple_connection_new_clone(NMConnection *connection); + +G_END_DECLS + +#endif /* __NM_SIMPLE_CONNECTION__ */ diff --git a/src/libnm-core-public/nm-utils.h b/src/libnm-core-public/nm-utils.h new file mode 100644 index 0000000..0f8dcda --- /dev/null +++ b/src/libnm-core-public/nm-utils.h @@ -0,0 +1,259 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2005 - 2017 Red Hat, Inc. + */ + +#ifndef __NM_UTILS_H__ +#define __NM_UTILS_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include + +#include "nm-core-enum-types.h" +#include "nm-setting-sriov.h" +#include "nm-setting-tc-config.h" +#include "nm-setting-wireless-security.h" + +G_BEGIN_DECLS + +/*****************************************************************************/ + +typedef struct _NMVariantAttributeSpec NMVariantAttributeSpec; + +/* SSID helpers */ +gboolean nm_utils_is_empty_ssid(const guint8 *ssid, gsize len); +const char *nm_utils_escape_ssid(const guint8 *ssid, gsize len); +gboolean nm_utils_same_ssid(const guint8 *ssid1, + gsize len1, + const guint8 *ssid2, + gsize len2, + gboolean ignore_trailing_null); +char * nm_utils_ssid_to_utf8(const guint8 *ssid, gsize len); + +/** + * NMUtilsSecurityType: + * @NMU_SEC_INVALID: unknown or invalid security, placeholder and not used + * @NMU_SEC_NONE: unencrypted and open + * @NMU_SEC_STATIC_WEP: static WEP keys are used for encryption + * @NMU_SEC_LEAP: Cisco LEAP is used for authentication and for generating the + * dynamic WEP keys automatically + * @NMU_SEC_DYNAMIC_WEP: standard 802.1x is used for authentication and + * generating the dynamic WEP keys automatically + * @NMU_SEC_WPA_PSK: WPA1 is used with Pre-Shared Keys (PSK) + * @NMU_SEC_WPA_ENTERPRISE: WPA1 is used with 802.1x authentication + * @NMU_SEC_WPA2_PSK: WPA2/RSN is used with Pre-Shared Keys (PSK) + * @NMU_SEC_WPA2_ENTERPRISE: WPA2 is used with 802.1x authentication + * @NMU_SEC_SAE: is used with WPA3 Enterprise + * @NMU_SEC_OWE: is used with Enhanced Open + * @NMU_SEC_WPA3_SUITE_B_192: is used with WPA3 Enterprise Suite-B 192 bit mode. Since: 1.30. + * + * Describes generic security mechanisms that 802.11 access points may offer. + * Used with nm_utils_security_valid() for checking whether a given access + * point is compatible with a network device. + **/ +typedef enum { + NMU_SEC_INVALID = 0, + NMU_SEC_NONE, + NMU_SEC_STATIC_WEP, + NMU_SEC_LEAP, + NMU_SEC_DYNAMIC_WEP, + NMU_SEC_WPA_PSK, + NMU_SEC_WPA_ENTERPRISE, + NMU_SEC_WPA2_PSK, + NMU_SEC_WPA2_ENTERPRISE, + NMU_SEC_SAE, + NMU_SEC_OWE, + NMU_SEC_WPA3_SUITE_B_192, +} NMUtilsSecurityType; + +gboolean nm_utils_security_valid(NMUtilsSecurityType type, + NMDeviceWifiCapabilities wifi_caps, + gboolean have_ap, + gboolean adhoc, + NM80211ApFlags ap_flags, + NM80211ApSecurityFlags ap_wpa, + NM80211ApSecurityFlags ap_rsn); + +gboolean nm_utils_ap_mode_security_valid(NMUtilsSecurityType type, + NMDeviceWifiCapabilities wifi_caps); + +gboolean nm_utils_wep_key_valid(const char *key, NMWepKeyType wep_type); +gboolean nm_utils_wpa_psk_valid(const char *psk); + +NM_AVAILABLE_IN_1_6 +gboolean nm_utils_is_json_object(const char *str, GError **error); + +GVariant * nm_utils_ip4_dns_to_variant(char **dns); +char ** nm_utils_ip4_dns_from_variant(GVariant *value); +GVariant * nm_utils_ip4_addresses_to_variant(GPtrArray *addresses, const char *gateway); +GPtrArray *nm_utils_ip4_addresses_from_variant(GVariant *value, char **out_gateway); +GVariant * nm_utils_ip4_routes_to_variant(GPtrArray *routes); +GPtrArray *nm_utils_ip4_routes_from_variant(GVariant *value); + +guint32 nm_utils_ip4_netmask_to_prefix(guint32 netmask); +guint32 nm_utils_ip4_prefix_to_netmask(guint32 prefix); +guint32 nm_utils_ip4_get_default_prefix(guint32 ip); + +GVariant * nm_utils_ip6_dns_to_variant(char **dns); +char ** nm_utils_ip6_dns_from_variant(GVariant *value); +GVariant * nm_utils_ip6_addresses_to_variant(GPtrArray *addresses, const char *gateway); +GPtrArray *nm_utils_ip6_addresses_from_variant(GVariant *value, char **out_gateway); +GVariant * nm_utils_ip6_routes_to_variant(GPtrArray *routes); +GPtrArray *nm_utils_ip6_routes_from_variant(GVariant *value); + +GVariant * nm_utils_ip_addresses_to_variant(GPtrArray *addresses); +GPtrArray *nm_utils_ip_addresses_from_variant(GVariant *value, int family); +GVariant * nm_utils_ip_routes_to_variant(GPtrArray *routes); +GPtrArray *nm_utils_ip_routes_from_variant(GVariant *value, int family); + +char *nm_utils_uuid_generate(void); + +gboolean nm_utils_file_is_certificate(const char *filename); +gboolean nm_utils_file_is_private_key(const char *filename, gboolean *out_encrypted); +gboolean nm_utils_file_is_pkcs12(const char *filename); + +typedef gboolean (*NMUtilsFileSearchInPathsPredicate)(const char *filename, gpointer user_data); + +struct stat; + +typedef gboolean (*NMUtilsCheckFilePredicate)(const char * filename, + const struct stat *stat, + gpointer user_data, + GError ** error); + +const char *nm_utils_file_search_in_paths(const char * progname, + const char * try_first, + const char *const * paths, + GFileTest file_test_flags, + NMUtilsFileSearchInPathsPredicate predicate, + gpointer user_data, + GError ** error); + +guint32 nm_utils_wifi_freq_to_channel(guint32 freq); +guint32 nm_utils_wifi_channel_to_freq(guint32 channel, const char *band); +guint32 nm_utils_wifi_find_next_channel(guint32 channel, int direction, char *band); +gboolean nm_utils_wifi_is_channel_valid(guint32 channel, const char *band); +NM_AVAILABLE_IN_1_2 +const guint *nm_utils_wifi_2ghz_freqs(void); +NM_AVAILABLE_IN_1_2 +const guint *nm_utils_wifi_5ghz_freqs(void); + +const char *nm_utils_wifi_strength_bars(guint8 strength); + +/** + * NM_UTILS_HWADDR_LEN_MAX: + * + * The maximum length of hardware addresses handled by NetworkManager itself, + * nm_utils_hwaddr_len(), and nm_utils_hwaddr_aton(). + */ +#define NM_UTILS_HWADDR_LEN_MAX 20 /* INFINIBAND_ALEN */ + +gsize nm_utils_hwaddr_len(int type) G_GNUC_PURE; + +char * nm_utils_hwaddr_ntoa(gconstpointer addr, gsize length); +GByteArray *nm_utils_hwaddr_atoba(const char *asc, gsize length); +guint8 * nm_utils_hwaddr_aton(const char *asc, gpointer buffer, gsize length); + +gboolean nm_utils_hwaddr_valid(const char *asc, gssize length); +char * nm_utils_hwaddr_canonical(const char *asc, gssize length); +gboolean nm_utils_hwaddr_matches(gconstpointer hwaddr1, + gssize hwaddr1_len, + gconstpointer hwaddr2, + gssize hwaddr2_len); + +char * nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len); +GBytes *nm_utils_hexstr2bin(const char *hex); + +NM_DEPRECATED_IN_1_6_FOR(nm_utils_is_valid_iface_name) +gboolean nm_utils_iface_valid_name(const char *name); +NM_AVAILABLE_IN_1_6 +gboolean nm_utils_is_valid_iface_name(const char *name, GError **error); + +gboolean nm_utils_is_uuid(const char *str); + +/** + * NM_UTILS_INET_ADDRSTRLEN: + * + * Defines the minimal length for a char buffer that is suitable as @dst argument + * for both nm_utils_inet4_ntop() and nm_utils_inet6_ntop(). + **/ +#define NM_UTILS_INET_ADDRSTRLEN INET6_ADDRSTRLEN + +const char *nm_utils_inet4_ntop(guint32 inaddr, char *dst); + +struct in6_addr; +const char *nm_utils_inet6_ntop(const struct in6_addr *in6addr, char *dst); + +gboolean nm_utils_ipaddr_valid(int family, const char *ip); + +gboolean nm_utils_check_virtual_device_compatibility(GType virtual_type, GType other_type); + +NM_AVAILABLE_IN_1_2 +int nm_utils_bond_mode_string_to_int(const char *mode); +NM_AVAILABLE_IN_1_2 +const char *nm_utils_bond_mode_int_to_string(int mode); + +NM_AVAILABLE_IN_1_2 +char *nm_utils_enum_to_str(GType type, int value); + +NM_AVAILABLE_IN_1_2 +gboolean nm_utils_enum_from_str(GType type, const char *str, int *out_value, char **err_token); + +NM_AVAILABLE_IN_1_2 +const char **nm_utils_enum_get_values(GType type, int from, int to); + +NM_AVAILABLE_IN_1_6 +guint nm_utils_version(void); + +NM_AVAILABLE_IN_1_8 +GHashTable *nm_utils_parse_variant_attributes(const char *string, + char attr_separator, + char key_value_separator, + gboolean ignore_unknown, + const NMVariantAttributeSpec *const *spec, + GError ** error); + +NM_AVAILABLE_IN_1_8 +char *nm_utils_format_variant_attributes(GHashTable *attributes, + char attr_separator, + char key_value_separator); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_12 +NMTCQdisc *nm_utils_tc_qdisc_from_str(const char *str, GError **error); +NM_AVAILABLE_IN_1_12 +char *nm_utils_tc_qdisc_to_str(NMTCQdisc *qdisc, GError **error); + +NM_AVAILABLE_IN_1_12 +NMTCAction *nm_utils_tc_action_from_str(const char *str, GError **error); +NM_AVAILABLE_IN_1_12 +char *nm_utils_tc_action_to_str(NMTCAction *action, GError **error); + +NM_AVAILABLE_IN_1_12 +NMTCTfilter *nm_utils_tc_tfilter_from_str(const char *str, GError **error); +NM_AVAILABLE_IN_1_12 +char *nm_utils_tc_tfilter_to_str(NMTCTfilter *tfilter, GError **error); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_14 +char *nm_utils_sriov_vf_to_str(const NMSriovVF *vf, gboolean omit_index, GError **error); +NM_AVAILABLE_IN_1_14 +NMSriovVF *nm_utils_sriov_vf_from_str(const char *str, GError **error); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_12 +gint64 nm_utils_get_timestamp_msec(void); + +NM_AVAILABLE_IN_1_16 +gboolean +nm_utils_base64secret_decode(const char *base64_key, gsize required_key_len, guint8 *out_key); + +G_END_DECLS + +#endif /* __NM_UTILS_H__ */ diff --git a/src/libnm-core-public/nm-version-macros.h b/src/libnm-core-public/nm-version-macros.h new file mode 100644 index 0000000..bdec397 --- /dev/null +++ b/src/libnm-core-public/nm-version-macros.h @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011, 2015 Red Hat, Inc. + */ + +#ifndef __NM_VERSION_MACROS_H__ +#define __NM_VERSION_MACROS_H__ + +/* This header must not include glib or libnm. */ + +/** + * NM_MAJOR_VERSION: + * + * Evaluates to the major version number of NetworkManager which this source + * is compiled against. + */ +#define NM_MAJOR_VERSION (1) + +/** + * NM_MINOR_VERSION: + * + * Evaluates to the minor version number of NetworkManager which this source + * is compiled against. + */ +#define NM_MINOR_VERSION (31) + +/** + * NM_MICRO_VERSION: + * + * Evaluates to the micro version number of NetworkManager which this source + * compiled against. + */ +#define NM_MICRO_VERSION (2) + +/** + * NM_CHECK_VERSION: + * @major: major version (e.g. 1 for version 1.2.5) + * @minor: minor version (e.g. 2 for version 1.2.5) + * @micro: micro version (e.g. 5 for version 1.2.5) + * + * Returns: %TRUE if the version of the NetworkManager header files + * is the same as or newer than the passed-in version. + */ +#define NM_CHECK_VERSION(major,minor,micro) \ + (NM_MAJOR_VERSION > (major) || \ + (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION > (minor)) || \ + (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION == (minor) && NM_MICRO_VERSION >= (micro))) + + +#define NM_ENCODE_VERSION(major,minor,micro) ((major) << 16 | (minor) << 8 | (micro)) + +#define NM_VERSION_0_9_8 (NM_ENCODE_VERSION (0, 9, 8)) +#define NM_VERSION_0_9_10 (NM_ENCODE_VERSION (0, 9, 10)) +#define NM_VERSION_1_0 (NM_ENCODE_VERSION (1, 0, 0)) +#define NM_VERSION_1_2 (NM_ENCODE_VERSION (1, 2, 0)) +#define NM_VERSION_1_4 (NM_ENCODE_VERSION (1, 4, 0)) +#define NM_VERSION_1_6 (NM_ENCODE_VERSION (1, 6, 0)) +#define NM_VERSION_1_8 (NM_ENCODE_VERSION (1, 8, 0)) +#define NM_VERSION_1_10 (NM_ENCODE_VERSION (1, 10, 0)) +#define NM_VERSION_1_12 (NM_ENCODE_VERSION (1, 12, 0)) +#define NM_VERSION_1_14 (NM_ENCODE_VERSION (1, 14, 0)) +#define NM_VERSION_1_16 (NM_ENCODE_VERSION (1, 16, 0)) +#define NM_VERSION_1_18 (NM_ENCODE_VERSION (1, 18, 0)) +#define NM_VERSION_1_20 (NM_ENCODE_VERSION (1, 20, 0)) +#define NM_VERSION_1_22 (NM_ENCODE_VERSION (1, 22, 0)) +#define NM_VERSION_1_24 (NM_ENCODE_VERSION (1, 24, 0)) +#define NM_VERSION_1_26 (NM_ENCODE_VERSION (1, 26, 0)) +#define NM_VERSION_1_28 (NM_ENCODE_VERSION (1, 28, 0)) +#define NM_VERSION_1_30 (NM_ENCODE_VERSION (1, 30, 0)) +#define NM_VERSION_1_32 (NM_ENCODE_VERSION (1, 32, 0)) + +/* For releases, NM_API_VERSION is equal to NM_VERSION. + * + * For development builds, NM_API_VERSION is the next + * stable API after NM_VERSION. When you run a development + * version, you are already using the future API, even if + * it is not yet release. Hence, the currently used API + * version is the future one. */ +#define NM_API_VERSION \ + (((NM_MINOR_VERSION % 2) == 1) \ + ? NM_ENCODE_VERSION (NM_MAJOR_VERSION, NM_MINOR_VERSION + 1, 0 ) \ + : NM_ENCODE_VERSION (NM_MAJOR_VERSION, NM_MINOR_VERSION , ((NM_MICRO_VERSION + 1) / 2) * 2)) + +/* deprecated. */ +#define NM_VERSION_CUR_STABLE NM_API_VERSION + +/* deprecated. */ +#define NM_VERSION_NEXT_STABLE NM_API_VERSION + +#define NM_VERSION NM_ENCODE_VERSION (NM_MAJOR_VERSION, NM_MINOR_VERSION, NM_MICRO_VERSION) + +#endif /* __NM_VERSION_MACROS_H__ */ diff --git a/src/libnm-core-public/nm-version-macros.h.in b/src/libnm-core-public/nm-version-macros.h.in new file mode 100644 index 0000000..58e877d --- /dev/null +++ b/src/libnm-core-public/nm-version-macros.h.in @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011, 2015 Red Hat, Inc. + */ + +#ifndef __NM_VERSION_MACROS_H__ +#define __NM_VERSION_MACROS_H__ + +/* This header must not include glib or libnm. */ + +/** + * NM_MAJOR_VERSION: + * + * Evaluates to the major version number of NetworkManager which this source + * is compiled against. + */ +#define NM_MAJOR_VERSION (@NM_MAJOR_VERSION@) + +/** + * NM_MINOR_VERSION: + * + * Evaluates to the minor version number of NetworkManager which this source + * is compiled against. + */ +#define NM_MINOR_VERSION (@NM_MINOR_VERSION@) + +/** + * NM_MICRO_VERSION: + * + * Evaluates to the micro version number of NetworkManager which this source + * compiled against. + */ +#define NM_MICRO_VERSION (@NM_MICRO_VERSION@) + +/** + * NM_CHECK_VERSION: + * @major: major version (e.g. 1 for version 1.2.5) + * @minor: minor version (e.g. 2 for version 1.2.5) + * @micro: micro version (e.g. 5 for version 1.2.5) + * + * Returns: %TRUE if the version of the NetworkManager header files + * is the same as or newer than the passed-in version. + */ +#define NM_CHECK_VERSION(major,minor,micro) \ + (NM_MAJOR_VERSION > (major) || \ + (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION > (minor)) || \ + (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION == (minor) && NM_MICRO_VERSION >= (micro))) + + +#define NM_ENCODE_VERSION(major,minor,micro) ((major) << 16 | (minor) << 8 | (micro)) + +#define NM_VERSION_0_9_8 (NM_ENCODE_VERSION (0, 9, 8)) +#define NM_VERSION_0_9_10 (NM_ENCODE_VERSION (0, 9, 10)) +#define NM_VERSION_1_0 (NM_ENCODE_VERSION (1, 0, 0)) +#define NM_VERSION_1_2 (NM_ENCODE_VERSION (1, 2, 0)) +#define NM_VERSION_1_4 (NM_ENCODE_VERSION (1, 4, 0)) +#define NM_VERSION_1_6 (NM_ENCODE_VERSION (1, 6, 0)) +#define NM_VERSION_1_8 (NM_ENCODE_VERSION (1, 8, 0)) +#define NM_VERSION_1_10 (NM_ENCODE_VERSION (1, 10, 0)) +#define NM_VERSION_1_12 (NM_ENCODE_VERSION (1, 12, 0)) +#define NM_VERSION_1_14 (NM_ENCODE_VERSION (1, 14, 0)) +#define NM_VERSION_1_16 (NM_ENCODE_VERSION (1, 16, 0)) +#define NM_VERSION_1_18 (NM_ENCODE_VERSION (1, 18, 0)) +#define NM_VERSION_1_20 (NM_ENCODE_VERSION (1, 20, 0)) +#define NM_VERSION_1_22 (NM_ENCODE_VERSION (1, 22, 0)) +#define NM_VERSION_1_24 (NM_ENCODE_VERSION (1, 24, 0)) +#define NM_VERSION_1_26 (NM_ENCODE_VERSION (1, 26, 0)) +#define NM_VERSION_1_28 (NM_ENCODE_VERSION (1, 28, 0)) +#define NM_VERSION_1_30 (NM_ENCODE_VERSION (1, 30, 0)) +#define NM_VERSION_1_32 (NM_ENCODE_VERSION (1, 32, 0)) + +/* For releases, NM_API_VERSION is equal to NM_VERSION. + * + * For development builds, NM_API_VERSION is the next + * stable API after NM_VERSION. When you run a development + * version, you are already using the future API, even if + * it is not yet release. Hence, the currently used API + * version is the future one. */ +#define NM_API_VERSION \ + (((NM_MINOR_VERSION % 2) == 1) \ + ? NM_ENCODE_VERSION (NM_MAJOR_VERSION, NM_MINOR_VERSION + 1, 0 ) \ + : NM_ENCODE_VERSION (NM_MAJOR_VERSION, NM_MINOR_VERSION , ((NM_MICRO_VERSION + 1) / 2) * 2)) + +/* deprecated. */ +#define NM_VERSION_CUR_STABLE NM_API_VERSION + +/* deprecated. */ +#define NM_VERSION_NEXT_STABLE NM_API_VERSION + +#define NM_VERSION NM_ENCODE_VERSION (NM_MAJOR_VERSION, NM_MINOR_VERSION, NM_MICRO_VERSION) + +#endif /* __NM_VERSION_MACROS_H__ */ diff --git a/src/libnm-core-public/nm-version.h b/src/libnm-core-public/nm-version.h new file mode 100644 index 0000000..516870d --- /dev/null +++ b/src/libnm-core-public/nm-version.h @@ -0,0 +1,315 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2011, 2015 Red Hat, Inc. + */ + +#ifndef NM_VERSION_H +#define NM_VERSION_H + +#include + +#include "nm-version-macros.h" + +/* Deprecation / Availability macros */ + +#if !defined(NM_VERSION_MIN_REQUIRED) || (NM_VERSION_MIN_REQUIRED == 0) + #undef NM_VERSION_MIN_REQUIRED + #define NM_VERSION_MIN_REQUIRED (NM_API_VERSION) +#endif + +#if !defined(NM_VERSION_MAX_ALLOWED) || (NM_VERSION_MAX_ALLOWED == 0) + #undef NM_VERSION_MAX_ALLOWED + #define NM_VERSION_MAX_ALLOWED (NM_API_VERSION) +#endif + +/* sanity checks */ +#if NM_VERSION_MIN_REQUIRED > NM_API_VERSION + #error "NM_VERSION_MIN_REQUIRED must be <= NM_API_VERSION" +#endif +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_MIN_REQUIRED + #error "NM_VERSION_MAX_ALLOWED must be >= NM_VERSION_MIN_REQUIRED" +#endif +#if NM_VERSION_MIN_REQUIRED < NM_VERSION_0_9_8 + #error "NM_VERSION_MIN_REQUIRED must be >= NM_VERSION_0_9_8" +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_0_9_10 + #define NM_DEPRECATED_IN_0_9_10 G_DEPRECATED + #define NM_DEPRECATED_IN_0_9_10_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_0_9_10 + #define NM_DEPRECATED_IN_0_9_10_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_0_9_10 + #define NM_AVAILABLE_IN_0_9_10 G_UNAVAILABLE(0.9, 10) +#else + #define NM_AVAILABLE_IN_0_9_10 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_0 + #define NM_DEPRECATED_IN_1_0 G_DEPRECATED + #define NM_DEPRECATED_IN_1_0_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_0 + #define NM_DEPRECATED_IN_1_0_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_0 + #define NM_AVAILABLE_IN_1_0 G_UNAVAILABLE(1, 0) +#else + #define NM_AVAILABLE_IN_1_0 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_2 + #define NM_DEPRECATED_IN_1_2 G_DEPRECATED + #define NM_DEPRECATED_IN_1_2_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_2 + #define NM_DEPRECATED_IN_1_2_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_2 + #define NM_AVAILABLE_IN_1_2 G_UNAVAILABLE(1, 2) +#else + #define NM_AVAILABLE_IN_1_2 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_4 + #define NM_DEPRECATED_IN_1_4 G_DEPRECATED + #define NM_DEPRECATED_IN_1_4_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_4 + #define NM_DEPRECATED_IN_1_4_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_4 + #define NM_AVAILABLE_IN_1_4 G_UNAVAILABLE(1, 4) +#else + #define NM_AVAILABLE_IN_1_4 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_6 + #define NM_DEPRECATED_IN_1_6 G_DEPRECATED + #define NM_DEPRECATED_IN_1_6_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_6 + #define NM_DEPRECATED_IN_1_6_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_6 + #define NM_AVAILABLE_IN_1_6 G_UNAVAILABLE(1, 6) +#else + #define NM_AVAILABLE_IN_1_6 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_8 + #define NM_DEPRECATED_IN_1_8 G_DEPRECATED + #define NM_DEPRECATED_IN_1_8_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_8 + #define NM_DEPRECATED_IN_1_8_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_8 + #define NM_AVAILABLE_IN_1_8 G_UNAVAILABLE(1, 8) +#else + #define NM_AVAILABLE_IN_1_8 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_10 + #define NM_DEPRECATED_IN_1_10 G_DEPRECATED + #define NM_DEPRECATED_IN_1_10_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_10 + #define NM_DEPRECATED_IN_1_10_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_10 + #define NM_AVAILABLE_IN_1_10 G_UNAVAILABLE(1, 10) +#else + #define NM_AVAILABLE_IN_1_10 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_12 + #define NM_DEPRECATED_IN_1_12 G_DEPRECATED + #define NM_DEPRECATED_IN_1_12_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_12 + #define NM_DEPRECATED_IN_1_12_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_12 + #define NM_AVAILABLE_IN_1_12 G_UNAVAILABLE(1, 12) +#else + #define NM_AVAILABLE_IN_1_12 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_14 + #define NM_DEPRECATED_IN_1_14 G_DEPRECATED + #define NM_DEPRECATED_IN_1_14_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_14 + #define NM_DEPRECATED_IN_1_14_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_14 + #define NM_AVAILABLE_IN_1_14 G_UNAVAILABLE(1, 14) +#else + #define NM_AVAILABLE_IN_1_14 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_16 + #define NM_DEPRECATED_IN_1_16 G_DEPRECATED + #define NM_DEPRECATED_IN_1_16_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_16 + #define NM_DEPRECATED_IN_1_16_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_16 + #define NM_AVAILABLE_IN_1_16 G_UNAVAILABLE(1, 16) +#else + #define NM_AVAILABLE_IN_1_16 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_18 + #define NM_DEPRECATED_IN_1_18 G_DEPRECATED + #define NM_DEPRECATED_IN_1_18_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_18 + #define NM_DEPRECATED_IN_1_18_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_18 + #define NM_AVAILABLE_IN_1_18 G_UNAVAILABLE(1, 18) +#else + #define NM_AVAILABLE_IN_1_18 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_20 + #define NM_DEPRECATED_IN_1_20 G_DEPRECATED + #define NM_DEPRECATED_IN_1_20_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_20 + #define NM_DEPRECATED_IN_1_20_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_20 + #define NM_AVAILABLE_IN_1_20 G_UNAVAILABLE(1, 20) +#else + #define NM_AVAILABLE_IN_1_20 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_22 + #define NM_DEPRECATED_IN_1_22 G_DEPRECATED + #define NM_DEPRECATED_IN_1_22_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_22 + #define NM_DEPRECATED_IN_1_22_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_22 + #define NM_AVAILABLE_IN_1_22 G_UNAVAILABLE(1, 22) +#else + #define NM_AVAILABLE_IN_1_22 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_24 + #define NM_DEPRECATED_IN_1_24 G_DEPRECATED + #define NM_DEPRECATED_IN_1_24_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_24 + #define NM_DEPRECATED_IN_1_24_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_24 + #define NM_AVAILABLE_IN_1_24 G_UNAVAILABLE(1, 24) +#else + #define NM_AVAILABLE_IN_1_24 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_26 + #define NM_DEPRECATED_IN_1_26 G_DEPRECATED + #define NM_DEPRECATED_IN_1_26_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_26 + #define NM_DEPRECATED_IN_1_26_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_26 + #define NM_AVAILABLE_IN_1_26 G_UNAVAILABLE(1, 26) +#else + #define NM_AVAILABLE_IN_1_26 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_28 + #define NM_DEPRECATED_IN_1_28 G_DEPRECATED + #define NM_DEPRECATED_IN_1_28_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_28 + #define NM_DEPRECATED_IN_1_28_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_28 + #define NM_AVAILABLE_IN_1_28 G_UNAVAILABLE(1, 28) +#else + #define NM_AVAILABLE_IN_1_28 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_30 + #define NM_DEPRECATED_IN_1_30 G_DEPRECATED + #define NM_DEPRECATED_IN_1_30_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_30 + #define NM_DEPRECATED_IN_1_30_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_30 + #define NM_AVAILABLE_IN_1_30 G_UNAVAILABLE(1, 30) +#else + #define NM_AVAILABLE_IN_1_30 +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_32 + #define NM_DEPRECATED_IN_1_32 G_DEPRECATED + #define NM_DEPRECATED_IN_1_32_FOR(f) G_DEPRECATED_FOR(f) +#else + #define NM_DEPRECATED_IN_1_32 + #define NM_DEPRECATED_IN_1_32_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_32 + #define NM_AVAILABLE_IN_1_32 G_UNAVAILABLE(1, 32) +#else + #define NM_AVAILABLE_IN_1_32 +#endif + +/* + * Synchronous API for calling D-Bus in libnm is deprecated. See + * https://developer.gnome.org/libnm/stable/usage.html#sync-api + * + * Note that "deprecated" here does not really mean that the API is going + * to be removed. We don't break API. Just comment that it is awkward and + * discouraged. The user may: + * + * - continue to use this API. It's deprecated, awkward and discouraged, + * but if it works for you, that's fine. + * + * - use asynchronous API. That's the only sensible way to use D-Bus. + * If libnm lacks a certain asynchronous counterpart, it should be + * added. + * + * - use GDBusConnection directly. There really isn't anything wrong + * with D-Bus or GDBusConnection. This deprecated API is just a wrapper + * around g_dbus_connection_call_sync(). You may call it directly + * without feeling dirty. + * + * The API is marked as deprecated since 1.22, however the macro only starts + * complaining in 1.24. That's intentional, because in 1.22 the asynchronous + * alternative was not yet available. + */ +#define _NM_DEPRECATED_SYNC_METHOD NM_DEPRECATED_IN_1_24 +#define _NM_DEPRECATED_SYNC_WRITABLE_PROPERTY /* NM_DEPRECATED_IN_1_22 */ + +#endif /* NM_VERSION_H */ diff --git a/src/libnm-core-public/nm-vpn-dbus-interface.h b/src/libnm-core-public/nm-vpn-dbus-interface.h new file mode 100644 index 0000000..c0e23f6 --- /dev/null +++ b/src/libnm-core-public/nm-vpn-dbus-interface.h @@ -0,0 +1,302 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2004 Red Hat, Inc. + */ + +/* D-Bus-related definitions for NetworkManager VPN plugins. + * + * Note that although this header is installed as part of libnm, it is also + * used by some external code that does not link to libnm. + */ + +#ifndef __NM_VPN_DBUS_INTERFACE_H__ +#define __NM_VPN_DBUS_INTERFACE_H__ + +#include "nm-dbus-interface.h" + +#ifndef NM_VERSION_H + #define NM_DEPRECATED_IN_1_8_FOR(n) +#endif + +/* + * dbus services details + */ +#define NM_DBUS_PATH_VPN "/org/freedesktop/NetworkManager/VPN/Manager" +#define NM_DBUS_INTERFACE_VPN "org.freedesktop.NetworkManager.VPN.Manager" + +#define NM_DBUS_PATH_VPN_CONNECTION "/org/freedesktop/NetworkManager/VPN/Connection" +#define NM_DBUS_INTERFACE_VPN_CONNECTION "org.freedesktop.NetworkManager.VPN.Connection" + +#define NM_VPN_DBUS_PLUGIN_PATH "/org/freedesktop/NetworkManager/VPN/Plugin" +#define NM_VPN_DBUS_PLUGIN_INTERFACE "org.freedesktop.NetworkManager.VPN.Plugin" + +/* + * VPN Errors + */ +#define NM_DBUS_NO_ACTIVE_VPN_CONNECTION \ + "org.freedesktop.NetworkManager.VPNConnections.NoActiveVPNConnection" +#define NM_DBUS_NO_VPN_CONNECTIONS "org.freedesktop.NetworkManager.VPNConnections.NoVPNConnections" +#define NM_DBUS_INVALID_VPN_CONNECTION \ + "org.freedesktop.NetworkManager.VPNConnections.InvalidVPNConnection" + +#define NM_DBUS_VPN_ERROR_PREFIX "org.freedesktop.NetworkManager.VPN.Error" +#define NM_DBUS_VPN_STARTING_IN_PROGRESS "StartingInProgress" +#define NM_DBUS_VPN_ALREADY_STARTED "AlreadyStarted" +#define NM_DBUS_VPN_STOPPING_IN_PROGRESS "StoppingInProgress" +#define NM_DBUS_VPN_ALREADY_STOPPED "AlreadyStopped" +#define NM_DBUS_VPN_WRONG_STATE "WrongState" +#define NM_DBUS_VPN_BAD_ARGUMENTS "BadArguments" +#define NM_DBUS_VPN_INTERACTIVE_NOT_SUPPORTED "InteractiveNotSupported" + +/* + * VPN daemon signals + */ +#define NM_DBUS_VPN_SIGNAL_LOGIN_BANNER "LoginBanner" +#define NM_DBUS_VPN_SIGNAL_LOGIN_FAILED "LoginFailed" +#define NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED "LaunchFailed" +#define NM_DBUS_VPN_SIGNAL_CONNECT_FAILED "ConnectFailed" +#define NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD "VPNConfigBad" +#define NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD "IPConfigBad" +#define NM_DBUS_VPN_SIGNAL_STATE_CHANGE "StateChange" +#define NM_DBUS_VPN_SIGNAL_IP4_CONFIG "IP4Config" + +/** + * NMVpnServiceState: + * @NM_VPN_SERVICE_STATE_UNKNOWN: The state of the VPN plugin is unknown. + * @NM_VPN_SERVICE_STATE_INIT: The VPN plugin is initialized. + * @NM_VPN_SERVICE_STATE_SHUTDOWN: Not used. + * @NM_VPN_SERVICE_STATE_STARTING: The plugin is attempting to connect to a VPN server. + * @NM_VPN_SERVICE_STATE_STARTED: The plugin has connected to a VPN server. + * @NM_VPN_SERVICE_STATE_STOPPING: The plugin is disconnecting from the VPN server. + * @NM_VPN_SERVICE_STATE_STOPPED: The plugin has disconnected from the VPN server. + * + * VPN daemon states + */ +typedef enum { + NM_VPN_SERVICE_STATE_UNKNOWN = 0, + NM_VPN_SERVICE_STATE_INIT, + NM_VPN_SERVICE_STATE_SHUTDOWN, + NM_VPN_SERVICE_STATE_STARTING, + NM_VPN_SERVICE_STATE_STARTED, + NM_VPN_SERVICE_STATE_STOPPING, + NM_VPN_SERVICE_STATE_STOPPED +} NMVpnServiceState; + +/** + * NMVpnConnectionState: + * @NM_VPN_CONNECTION_STATE_UNKNOWN: The state of the VPN connection is + * unknown. + * @NM_VPN_CONNECTION_STATE_PREPARE: The VPN connection is preparing to + * connect. + * @NM_VPN_CONNECTION_STATE_NEED_AUTH: The VPN connection needs authorization + * credentials. + * @NM_VPN_CONNECTION_STATE_CONNECT: The VPN connection is being established. + * @NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: The VPN connection is getting an IP + * address. + * @NM_VPN_CONNECTION_STATE_ACTIVATED: The VPN connection is active. + * @NM_VPN_CONNECTION_STATE_FAILED: The VPN connection failed. + * @NM_VPN_CONNECTION_STATE_DISCONNECTED: The VPN connection is disconnected. + * + * VPN connection states + */ +typedef enum { + NM_VPN_CONNECTION_STATE_UNKNOWN = 0, + NM_VPN_CONNECTION_STATE_PREPARE, + NM_VPN_CONNECTION_STATE_NEED_AUTH, + NM_VPN_CONNECTION_STATE_CONNECT, + NM_VPN_CONNECTION_STATE_IP_CONFIG_GET, + NM_VPN_CONNECTION_STATE_ACTIVATED, + NM_VPN_CONNECTION_STATE_FAILED, + NM_VPN_CONNECTION_STATE_DISCONNECTED +} NMVpnConnectionState; + +/** + * NMVpnConnectionStateReason: + * @NM_VPN_CONNECTION_STATE_REASON_UNKNOWN: The reason for the VPN connection + * state change is unknown. + * @NM_VPN_CONNECTION_STATE_REASON_NONE: No reason was given for the VPN + * connection state change. + * @NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED: The VPN connection changed + * state because the user disconnected it. + * @NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED: The VPN connection + * changed state because the device it was using was disconnected. + * @NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED: The service providing the + * VPN connection was stopped. + * @NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID: The IP config of the VPN + * connection was invalid. + * @NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT: The connection attempt to + * the VPN service timed out. + * @NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT: A timeout occurred + * while starting the service providing the VPN connection. + * @NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED: Starting the service + * starting the service providing the VPN connection failed. + * @NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS: Necessary secrets for the VPN + * connection were not provided. + * @NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED: Authentication to the VPN + * server failed. + * @NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED: The connection was + * deleted from settings. + * + * VPN connection state reasons + */ +NM_DEPRECATED_IN_1_8_FOR(NMActiveConnectionStateReason) +typedef enum { + NM_VPN_CONNECTION_STATE_REASON_UNKNOWN = 0, + NM_VPN_CONNECTION_STATE_REASON_NONE = 1, + NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED = 2, + NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED = 3, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED = 4, + NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID = 5, + NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT = 6, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT = 7, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED = 8, + NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS = 9, + NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED = 10, + NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED = 11, +} NMVpnConnectionStateReason; + +/** + * NMVpnPluginFailure: + * @NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED: Login failed. + * @NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED: Connect failed. + * @NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG: Invalid IP configuration returned from + * the VPN plugin. + * + * VPN plugin failure reasons + */ +typedef enum { + NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED, + NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED, + NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG +} NMVpnPluginFailure; + +#ifndef NM_VERSION_H + #undef NM_DEPRECATED_IN_1_8_FOR +#endif + +/*** Generic config ***/ + +/* string: VPN interface name (tun0, tap0, etc) */ +#define NM_VPN_PLUGIN_CONFIG_TUNDEV "tundev" + +/* string: Proxy PAC */ +#define NM_VPN_PLUGIN_CONFIG_PROXY_PAC "pac" + +/* string: Login message */ +#define NM_VPN_PLUGIN_CONFIG_BANNER "banner" + +/* uint32 / array of uint8: IP address of the public external VPN gateway (network byte order) */ +#define NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY "gateway" + +/* uint32: Maximum Transfer Unit that the VPN interface should use */ +#define NM_VPN_PLUGIN_CONFIG_MTU "mtu" + +/* boolean: Has IP4 configuration? */ +#define NM_VPN_PLUGIN_CONFIG_HAS_IP4 "has-ip4" + +/* boolean: Has IP6 configuration? */ +#define NM_VPN_PLUGIN_CONFIG_HAS_IP6 "has-ip6" + +/* boolean: If %TRUE the VPN plugin can persist/reconnect the connection over + * link changes and VPN server dropouts. + */ +#define NM_VPN_PLUGIN_CAN_PERSIST "can-persist" + +/*** Ip4Config ***/ + +/* uint32: IP address of the internal gateway of the subnet the VPN interface is + * on, if the VPN uses subnet configuration (network byte order) + */ +#define NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY "internal-gateway" + +/* uint32: internal IP address of the local VPN interface (network byte order) */ +#define NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS "address" + +/* uint32: IP address of the other side of Point-to-Point connection if the VPN + * uses Point-to-Point configuration. (network byte order) + */ +#define NM_VPN_PLUGIN_IP4_CONFIG_PTP "ptp" + +/* uint32: IP prefix of the VPN interface; 1 - 32 inclusive */ +#define NM_VPN_PLUGIN_IP4_CONFIG_PREFIX "prefix" + +/* array of uint32: IP addresses of DNS servers for the VPN (network byte order) */ +#define NM_VPN_PLUGIN_IP4_CONFIG_DNS "dns" + +/* array of uint32: IP addresses of NBNS/WINS servers for the VPN (network byte order) */ +#define NM_VPN_PLUGIN_IP4_CONFIG_NBNS "nbns" + +/* uint32: Message Segment Size that the VPN interface should use */ +#define NM_VPN_PLUGIN_IP4_CONFIG_MSS "mss" + +/* string: DNS domain name */ +#define NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN "domain" + +/* array of strings: DNS domain names */ +#define NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS "domains" + +/* [ip4 routes]: custom routes the client should apply, in the format used + * by nm_utils_ip4_routes_to/from_gvalue + */ +#define NM_VPN_PLUGIN_IP4_CONFIG_ROUTES "routes" + +/* whether the previous IP4 routing configuration should be preserved. */ +#define NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES "preserve-routes" + +/* boolean: prevent this VPN connection from ever getting the default route */ +#define NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT "never-default" + +/* Deprecated */ +#define NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY + +/* Legacy IP4 items; these are included in the IP4 config by older plugins, + * but in the generic config by newer plugins. + */ + +#define NM_VPN_PLUGIN_IP4_CONFIG_BANNER NM_VPN_PLUGIN_CONFIG_BANNER +#define NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY +#define NM_VPN_PLUGIN_IP4_CONFIG_MTU NM_VPN_PLUGIN_CONFIG_MTU +#define NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV NM_VPN_PLUGIN_CONFIG_TUNDEV + +/*** Ip6Config ***/ + +/* array of uint8: IP address of the internal gateway of the subnet the VPN interface is + * on, if the VPN uses subnet configuration (network byte order) + */ +#define NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY "internal-gateway" + +/* array of uint8: internal IP address of the local VPN interface (network byte order) */ +#define NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS "address" + +/* array of uint8: IP address of the other side of Point-to-Point connection if the VPN + * uses Point-to-Point configuration. (network byte order) + */ +#define NM_VPN_PLUGIN_IP6_CONFIG_PTP "ptp" + +/* uint32: prefix length of the VPN interface; 1 - 128 inclusive */ +#define NM_VPN_PLUGIN_IP6_CONFIG_PREFIX "prefix" + +/* array of array of uint8: IP addresses of DNS servers for the VPN (network byte order) */ +#define NM_VPN_PLUGIN_IP6_CONFIG_DNS "dns" + +/* uint32: Message Segment Size that the VPN interface should use */ +#define NM_VPN_PLUGIN_IP6_CONFIG_MSS "mss" + +/* string: DNS domain name */ +#define NM_VPN_PLUGIN_IP6_CONFIG_DOMAIN "domain" + +/* array of strings: DNS domain names */ +#define NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS "domains" + +/* [ip6 routes]: custom routes the client should apply, in the format used + * by nm_utils_ip6_routes_to/from_gvalue + */ +#define NM_VPN_PLUGIN_IP6_CONFIG_ROUTES "routes" + +/* whether the previous IP6 routing configuration should be preserved. */ +#define NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES "preserve-routes" + +/* boolean: prevent this VPN connection from ever getting the default route */ +#define NM_VPN_PLUGIN_IP6_CONFIG_NEVER_DEFAULT "never-default" + +#endif /* __NM_VPN_DBUS_INTERFACE_H__ */ diff --git a/src/libnm-core-public/nm-vpn-dbus-types.xml b/src/libnm-core-public/nm-vpn-dbus-types.xml new file mode 100644 index 0000000..5da0242 --- /dev/null +++ b/src/libnm-core-public/nm-vpn-dbus-types.xml @@ -0,0 +1,246 @@ + + + + + + + VPN Plugin D-Bus API Types + 3 + VPN Plugin D-Bus API Types + + + VPN Plugin D-Bus API Types + + + + + enum NMVpnServiceState + + NMVpnServiceState + + VPN daemon states + + Values + + + + + + + + NM_VPN_SERVICE_STATE_UNKNOWN + = 0 + The state of the VPN plugin is unknown. + + + NM_VPN_SERVICE_STATE_INIT + = 1 + The VPN plugin is initialized. + + + NM_VPN_SERVICE_STATE_SHUTDOWN + = 2 + Not used. + + + NM_VPN_SERVICE_STATE_STARTING + = 3 + The plugin is attempting to connect to a VPN server. + + + NM_VPN_SERVICE_STATE_STARTED + = 4 + The plugin has connected to a VPN server. + + + NM_VPN_SERVICE_STATE_STOPPING + = 5 + The plugin is disconnecting from the VPN server. + + + NM_VPN_SERVICE_STATE_STOPPED + = 6 + The plugin has disconnected from the VPN server. + + + + + + + + + enum NMVpnConnectionState + + NMVpnConnectionState + + VPN connection states + + Values + + + + + + + + NM_VPN_CONNECTION_STATE_UNKNOWN + = 0 + The state of the VPN connection is unknown. + + + NM_VPN_CONNECTION_STATE_PREPARE + = 1 + The VPN connection is preparing to connect. + + + NM_VPN_CONNECTION_STATE_NEED_AUTH + = 2 + The VPN connection needs authorization credentials. + + + NM_VPN_CONNECTION_STATE_CONNECT + = 3 + The VPN connection is being established. + + + NM_VPN_CONNECTION_STATE_IP_CONFIG_GET + = 4 + The VPN connection is getting an IP address. + + + NM_VPN_CONNECTION_STATE_ACTIVATED + = 5 + The VPN connection is active. + + + NM_VPN_CONNECTION_STATE_FAILED + = 6 + The VPN connection failed. + + + NM_VPN_CONNECTION_STATE_DISCONNECTED + = 7 + The VPN connection is disconnected. + + + + + + + + + enum NMVpnConnectionStateReason + + NMVpnConnectionStateReason + + VPN connection state reasons + + Values + + + + + + + + NM_VPN_CONNECTION_STATE_REASON_UNKNOWN + = 0 + The reason for the VPN connection state change is unknown. + + + NM_VPN_CONNECTION_STATE_REASON_NONE + = 1 + No reason was given for the VPN connection state change. + + + NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED + = 2 + The VPN connection changed state because the user disconnected it. + + + NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED + = 3 + The VPN connection changed state because the device it was using was disconnected. + + + NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED + = 4 + The service providing the VPN connection was stopped. + + + NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID + = 5 + The IP config of the VPN connection was invalid. + + + NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT + = 6 + The connection attempt to the VPN service timed out. + + + NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT + = 7 + A timeout occurred while starting the service providing the VPN connection. + + + NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED + = 8 + Starting the service starting the service providing the VPN connection failed. + + + NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS + = 9 + Necessary secrets for the VPN connection were not provided. + + + NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED + = 10 + Authentication to the VPN server failed. + + + NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED + = 11 + The connection was deleted from settings. + + + + + + + + + enum NMVpnPluginFailure + + NMVpnPluginFailure + + VPN plugin failure reasons + + Values + + + + + + + + NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED + = 0 + Login failed. + + + NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED + = 1 + Connect failed. + + + NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG + = 2 + Invalid IP configuration returned from the VPN plugin. + + + + + + + + diff --git a/src/libnm-core-public/nm-vpn-editor-plugin.h b/src/libnm-core-public/nm-vpn-editor-plugin.h new file mode 100644 index 0000000..e318da0 --- /dev/null +++ b/src/libnm-core-public/nm-vpn-editor-plugin.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_VPN_EDITOR_PLUGIN_H__ +#define __NM_VPN_EDITOR_PLUGIN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) + #error "Only can be included directly." +#endif + +#include +#include + +#include "nm-connection.h" +#include "nm-utils.h" + +G_BEGIN_DECLS + +typedef struct _NMVpnPluginInfo NMVpnPluginInfo; + +typedef struct _NMVpnEditorPlugin NMVpnEditorPlugin; +typedef struct _NMVpnEditor NMVpnEditor; + +/* Plugin's factory function that returns a GObject that implements + * NMVpnEditorPlugin. + */ +#ifndef __GI_SCANNER__ +typedef NMVpnEditorPlugin *(*NMVpnEditorPluginFactory)(GError **error); +NMVpnEditorPlugin *nm_vpn_editor_plugin_factory(GError **error); +#endif + +/*****************************************************************************/ +/* Editor plugin interface */ +/*****************************************************************************/ + +#define NM_TYPE_VPN_EDITOR_PLUGIN (nm_vpn_editor_plugin_get_type()) +#define NM_VPN_EDITOR_PLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_VPN_EDITOR_PLUGIN, NMVpnEditorPlugin)) +#define NM_IS_VPN_EDITOR_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_VPN_EDITOR_PLUGIN)) +#define NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(obj) \ + (G_TYPE_INSTANCE_GET_INTERFACE((obj), NM_TYPE_VPN_EDITOR_PLUGIN, NMVpnEditorPluginInterface)) + +/** + * NMVpnEditorPluginCapability: + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE: unknown or no capability + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT: the plugin can import new connections + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT: the plugin can export connections + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6: the plugin supports IPv6 addressing + * + * Flags that indicate certain capabilities of the plugin to editor programs. + **/ +typedef enum /*< flags >*/ { + NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE = 0x00, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT = 0x01, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT = 0x02, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6 = 0x04 +} NMVpnEditorPluginCapability; + +/* Short display name of the VPN plugin */ +#define NM_VPN_EDITOR_PLUGIN_NAME "name" + +/* Longer description of the VPN plugin */ +#define NM_VPN_EDITOR_PLUGIN_DESCRIPTION "description" + +/* D-Bus service name of the plugin's VPN service */ +#define NM_VPN_EDITOR_PLUGIN_SERVICE "service" + +typedef struct _NMVpnEditorPluginVT NMVpnEditorPluginVT; + +/** + * NMVpnEditorPluginInterface: + * @g_iface: the parent interface + * @get_editor: returns an #NMVpnEditor, pre-filled with values from @connection + * if non-%NULL. + * @get_capabilities: returns a bitmask of capabilities. + * @import_from_file: Try to import a connection from the specified path. On + * success, return a partial #NMConnection object. On error, return %NULL and + * set @error with additional information. Note that @error can be %NULL, in + * which case no additional error information should be provided. + * @export_to_file: Export the given connection to the specified path. Return + * %TRUE on success. On error, return %FALSE and set @error with additional + * error information. Note that @error can be %NULL, in which case no + * additional error information should be provided. + * @get_suggested_filename: For a given connection, return a suggested file + * name. Returned value will be %NULL or a suggested file name to be freed by + * the caller. + * @notify_plugin_info_set: A callback to be called when the plugin info is set. + * @get_vt: return a virtual function table to implement further functions in + * the plugin, without requiring to update libnm. Used by nm_vpn_editor_plugin_get_vt(). + * + * Interface for VPN editor plugins. + */ +typedef struct { + GTypeInterface g_iface; + + NMVpnEditor *(*get_editor)(NMVpnEditorPlugin *plugin, NMConnection *connection, GError **error); + + NMVpnEditorPluginCapability (*get_capabilities)(NMVpnEditorPlugin *plugin); + + NMConnection *(*import_from_file)(NMVpnEditorPlugin *plugin, const char *path, GError **error); + + gboolean (*export_to_file)(NMVpnEditorPlugin *plugin, + const char * path, + NMConnection * connection, + GError ** error); + + char *(*get_suggested_filename)(NMVpnEditorPlugin *plugin, NMConnection *connection); + + void (*notify_plugin_info_set)(NMVpnEditorPlugin *plugin, NMVpnPluginInfo *plugin_info); + + const NMVpnEditorPluginVT *(*get_vt)(NMVpnEditorPlugin *plugin, gsize *out_vt_size); +} NMVpnEditorPluginInterface; + +GType nm_vpn_editor_plugin_get_type(void); + +NMVpnEditor *nm_vpn_editor_plugin_get_editor(NMVpnEditorPlugin *plugin, + NMConnection * connection, + GError ** error); + +NMVpnEditorPluginCapability nm_vpn_editor_plugin_get_capabilities(NMVpnEditorPlugin *plugin); + +NM_AVAILABLE_IN_1_4 +gsize +nm_vpn_editor_plugin_get_vt(NMVpnEditorPlugin *plugin, NMVpnEditorPluginVT *vt, gsize vt_size); + +NMConnection * + nm_vpn_editor_plugin_import(NMVpnEditorPlugin *plugin, const char *path, GError **error); +gboolean nm_vpn_editor_plugin_export(NMVpnEditorPlugin *plugin, + const char * path, + NMConnection * connection, + GError ** error); +char * nm_vpn_editor_plugin_get_suggested_filename(NMVpnEditorPlugin *plugin, + NMConnection * connection); + +NM_AVAILABLE_IN_1_2 +NMVpnEditorPlugin *nm_vpn_editor_plugin_load_from_file(const char * plugin_name, + const char * check_service, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError ** error); + +NM_AVAILABLE_IN_1_4 +NMVpnEditorPlugin * +nm_vpn_editor_plugin_load(const char *plugin_name, const char *check_service, GError **error); + +NM_AVAILABLE_IN_1_4 +NMVpnPluginInfo *nm_vpn_editor_plugin_get_plugin_info(NMVpnEditorPlugin *plugin); +NM_AVAILABLE_IN_1_4 +void nm_vpn_editor_plugin_set_plugin_info(NMVpnEditorPlugin *plugin, NMVpnPluginInfo *plugin_info); + +#include "nm-vpn-plugin-info.h" + +G_END_DECLS + +#endif /* __NM_VPN_EDITOR_PLUGIN_H__ */ diff --git a/src/libnm-core-public/nm-vpn-plugin-info.h b/src/libnm-core-public/nm-vpn-plugin-info.h new file mode 100644 index 0000000..1e9870c --- /dev/null +++ b/src/libnm-core-public/nm-vpn-plugin-info.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_VPN_PLUGIN_INFO_H__ +#define __NM_VPN_PLUGIN_INFO_H__ + +#include +#include + +#include "nm-utils.h" +#include "nm-vpn-editor-plugin.h" + +G_BEGIN_DECLS + +#define NM_TYPE_VPN_PLUGIN_INFO (nm_vpn_plugin_info_get_type()) +#define NM_VPN_PLUGIN_INFO(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_VPN_PLUGIN_INFO, NMVpnPluginInfo)) +#define NM_VPN_PLUGIN_INFO_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_VPN_PLUGIN_INFO, NMVpnPluginInfoClass)) +#define NM_IS_VPN_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_VPN_PLUGIN_INFO)) +#define NM_IS_VPN_PLUGIN_INFO_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_VPN_PLUGIN_INFO)) +#define NM_VPN_PLUGIN_INFO_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_VPN_PLUGIN_INFO, NMVpnPluginInfoClass)) + +#define NM_VPN_PLUGIN_INFO_NAME "name" +#define NM_VPN_PLUGIN_INFO_FILENAME "filename" +#define NM_VPN_PLUGIN_INFO_KEYFILE "keyfile" + +#define NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION "VPN Connection" +#define NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM "libnm" +#define NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME "GNOME" + +typedef struct _NMVpnPluginInfoClass NMVpnPluginInfoClass; + +NM_AVAILABLE_IN_1_2 +GType nm_vpn_plugin_info_get_type(void); + +NM_AVAILABLE_IN_1_2 +NMVpnPluginInfo *nm_vpn_plugin_info_new_from_file(const char *filename, GError **error); + +NM_AVAILABLE_IN_1_2 +NMVpnPluginInfo * +nm_vpn_plugin_info_new_with_data(const char *filename, GKeyFile *keyfile, GError **error); + +NM_AVAILABLE_IN_1_4 +NMVpnPluginInfo *nm_vpn_plugin_info_new_search_file(const char *name, const char *service); + +NM_AVAILABLE_IN_1_2 +const char *nm_vpn_plugin_info_get_name(NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +const char *nm_vpn_plugin_info_get_filename(NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_4 +const char *nm_vpn_plugin_info_get_service(NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +const char *nm_vpn_plugin_info_get_plugin(NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +const char *nm_vpn_plugin_info_get_program(NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_4 +const char *nm_vpn_plugin_info_get_auth_dialog(NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_4 +gboolean nm_vpn_plugin_info_supports_hints(NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_plugin_info_supports_multiple(NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_4 +const char *const *nm_vpn_plugin_info_get_aliases(NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +const char * +nm_vpn_plugin_info_lookup_property(NMVpnPluginInfo *self, const char *group, const char *key); + +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_plugin_info_validate_filename(const char *filename); + +NM_AVAILABLE_IN_1_2 +GSList *nm_vpn_plugin_info_list_load(void); +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_plugin_info_list_add(GSList **list, NMVpnPluginInfo *plugin_info, GError **error); +NM_AVAILABLE_IN_1_2 +gboolean nm_vpn_plugin_info_list_remove(GSList **list, NMVpnPluginInfo *plugin_info); +NM_AVAILABLE_IN_1_2 +NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_name(GSList *list, const char *name); +NM_AVAILABLE_IN_1_2 +NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_filename(GSList *list, const char *filename); +NM_AVAILABLE_IN_1_2 +NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_service(GSList *list, const char *service); + +NM_AVAILABLE_IN_1_4 +char *nm_vpn_plugin_info_list_find_service_type(GSList *list, const char *name); +NM_AVAILABLE_IN_1_4 +char **nm_vpn_plugin_info_list_get_service_types(GSList * list, + gboolean only_existing, + gboolean with_abbreviations); + +NM_AVAILABLE_IN_1_2 +NMVpnEditorPlugin *nm_vpn_plugin_info_get_editor_plugin(NMVpnPluginInfo *self); +NM_AVAILABLE_IN_1_2 +void nm_vpn_plugin_info_set_editor_plugin(NMVpnPluginInfo *self, NMVpnEditorPlugin *plugin); +NM_AVAILABLE_IN_1_2 +NMVpnEditorPlugin *nm_vpn_plugin_info_load_editor_plugin(NMVpnPluginInfo *self, GError **error); + +G_END_DECLS + +#endif /* __NM_VPN_PLUGIN_INFO_H__ */ diff --git a/src/libnm-glib-aux/meson.build b/src/libnm-glib-aux/meson.build new file mode 100644 index 0000000..39eccbd --- /dev/null +++ b/src/libnm-glib-aux/meson.build @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_glib_aux = static_library( + 'nm-glib-aux', + sources: files( + 'nm-dbus-aux.c', + 'nm-dedup-multi.c', + 'nm-enum-utils.c', + 'nm-errno.c', + 'nm-hash-utils.c', + 'nm-io-utils.c', + 'nm-json-aux.c', + 'nm-keyfile-aux.c', + 'nm-logging-base.c', + 'nm-random-utils.c', + 'nm-ref-string.c', + 'nm-secret-utils.c', + 'nm-shared-utils.c', + 'nm-time-utils.c', + ), + include_directories: [ + src_inc, + top_inc, + ], + dependencies: glib_dep, +) diff --git a/src/libnm-glib-aux/nm-c-list.h b/src/libnm-glib-aux/nm-c-list.h new file mode 100644 index 0000000..6dd3ac7 --- /dev/null +++ b/src/libnm-glib-aux/nm-c-list.h @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NM_C_LIST_H__ +#define __NM_C_LIST_H__ + +#include "c-list/src/c-list.h" + +/*****************************************************************************/ + +#define nm_c_list_contains_entry(list, what, member) \ + ({ \ + typeof(what) _what = (what); \ + \ + _what &&c_list_contains(list, &_what->member); \ + }) + +/*****************************************************************************/ + +typedef struct { + CList lst; + void *data; +} NMCListElem; + +static inline NMCListElem * +nm_c_list_elem_new_stale(void *data) +{ + NMCListElem *elem; + + elem = g_slice_new(NMCListElem); + elem->data = data; + return elem; +} + +static inline gboolean +nm_c_list_elem_free_full(NMCListElem *elem, GDestroyNotify free_fcn) +{ + if (!elem) + return FALSE; + c_list_unlink_stale(&elem->lst); + if (free_fcn) + free_fcn(elem->data); + g_slice_free(NMCListElem, elem); + return TRUE; +} + +static inline gboolean +nm_c_list_elem_free(NMCListElem *elem) +{ + return nm_c_list_elem_free_full(elem, NULL); +} + +static inline void * +nm_c_list_elem_free_steal(NMCListElem *elem) +{ + gpointer data; + + if (!elem) + return NULL; + data = elem->data; + nm_c_list_elem_free_full(elem, NULL); + return data; +} + +static inline void +nm_c_list_elem_free_all(CList *head, GDestroyNotify free_fcn) +{ + NMCListElem *elem; + + while ((elem = c_list_first_entry(head, NMCListElem, lst))) + nm_c_list_elem_free_full(elem, free_fcn); +} + +#define nm_c_list_elem_find_first(head, arg, predicate) \ + ({ \ + CList *const _head = (head); \ + NMCListElem *_result = NULL; \ + NMCListElem *_elem; \ + \ + c_list_for_each_entry (_elem, _head, lst) { \ + void *const arg = _elem->data; \ + \ + if (predicate) { \ + _result = _elem; \ + break; \ + } \ + } \ + _result; \ + }) + +/** + * nm_c_list_elem_find_first_ptr: + * @head: the @CList head of a list containing #NMCListElem elements. + * Note that the head is not itself part of the list. + * @needle: the needle pointer. + * + * Iterates the list and returns the first #NMCListElem with the matching @needle, + * using pointer equality. + * + * Returns: the found list element or %NULL if not found. + */ +static inline NMCListElem * +nm_c_list_elem_find_first_ptr(CList *head, gconstpointer needle) +{ + return nm_c_list_elem_find_first(head, x, x == needle); +} + +/*****************************************************************************/ + +/** + * nm_c_list_move_before: + * @lst: the list element to which @elem will be prepended. + * @elem: the list element to move. + * + * This unlinks @elem from the current list and linkes it before + * @lst. This is like c_list_link_before(), except that @elem must + * be initialized and linked. Note that @elem may be linked in @lst + * or in another list. In both cases it gets moved. + * + * Returns: %TRUE if there were any changes. %FALSE if elem was already + * linked at the right place. + */ +static inline gboolean +nm_c_list_move_before(CList *lst, CList *elem) +{ + nm_assert(lst); + nm_assert(elem); + + if (lst != elem && lst->prev != elem) { + c_list_unlink_stale(elem); + c_list_link_before(lst, elem); + return TRUE; + } + return FALSE; +} +#define nm_c_list_move_tail(lst, elem) nm_c_list_move_before(lst, elem) + +/** + * nm_c_list_move_after: + * @lst: the list element to which @elem will be prepended. + * @elem: the list element to move. + * + * This unlinks @elem from the current list and linkes it after + * @lst. This is like c_list_link_after(), except that @elem must + * be initialized and linked. Note that @elem may be linked in @lst + * or in another list. In both cases it gets moved. + * + * Returns: %TRUE if there were any changes. %FALSE if elem was already + * linked at the right place. + */ +static inline gboolean +nm_c_list_move_after(CList *lst, CList *elem) +{ + nm_assert(lst); + nm_assert(elem); + + if (lst != elem && lst->next != elem) { + c_list_unlink_stale(elem); + c_list_link_after(lst, elem); + return TRUE; + } + return FALSE; +} +#define nm_c_list_move_front(lst, elem) nm_c_list_move_after(lst, elem) + +#define nm_c_list_free_all(lst, type, member, destroy_fcn) \ + G_STMT_START \ + { \ + CList *const _lst = (lst); \ + type * _elem; \ + \ + while ((_elem = c_list_first_entry(_lst, type, member))) { \ + destroy_fcn(_elem); \ + } \ + } \ + G_STMT_END + +#endif /* __NM_C_LIST_H__ */ diff --git a/src/libnm-glib-aux/nm-dbus-aux.c b/src/libnm-glib-aux/nm-dbus-aux.c new file mode 100644 index 0000000..48864a0 --- /dev/null +++ b/src/libnm-glib-aux/nm-dbus-aux.c @@ -0,0 +1,292 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-dbus-aux.h" + +/*****************************************************************************/ + +static void +_nm_dbus_connection_call_get_name_owner_cb(GObject *source, GAsyncResult *res, gpointer user_data) +{ + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError * error = NULL; + const char * owner = NULL; + gpointer orig_user_data; + NMDBusConnectionCallGetNameOwnerCb callback; + + nm_utils_user_data_unpack(user_data, &orig_user_data, &callback); + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error); + if (ret) + g_variant_get(ret, "(&s)", &owner); + + callback(owner, error, orig_user_data); +} + +void +nm_dbus_connection_call_get_name_owner(GDBusConnection * dbus_connection, + const char * service_name, + int timeout_msec, + GCancellable * cancellable, + NMDBusConnectionCallGetNameOwnerCb callback, + gpointer user_data) +{ + nm_assert(callback); + + g_dbus_connection_call(dbus_connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetNameOwner", + g_variant_new("(s)", service_name), + G_VARIANT_TYPE("(s)"), + G_DBUS_CALL_FLAGS_NONE, + timeout_msec, + cancellable, + _nm_dbus_connection_call_get_name_owner_cb, + nm_utils_user_data_pack(user_data, callback)); +} + +/*****************************************************************************/ + +static void +_nm_dbus_connection_call_default_cb(GObject *source, GAsyncResult *res, gpointer user_data) +{ + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError * error = NULL; + gpointer orig_user_data; + NMDBusConnectionCallDefaultCb callback; + + nm_utils_user_data_unpack(user_data, &orig_user_data, &callback); + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error); + + nm_assert((!!ret) != (!!error)); + + callback(ret, error, orig_user_data); +} + +void +nm_dbus_connection_call_get_all(GDBusConnection * dbus_connection, + const char * bus_name, + const char * object_path, + const char * interface_name, + int timeout_msec, + GCancellable * cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data) +{ + nm_assert(callback); + + g_dbus_connection_call(dbus_connection, + bus_name, + object_path, + DBUS_INTERFACE_PROPERTIES, + "GetAll", + g_variant_new("(s)", interface_name), + G_VARIANT_TYPE("(a{sv})"), + G_DBUS_CALL_FLAGS_NONE, + timeout_msec, + cancellable, + _nm_dbus_connection_call_default_cb, + nm_utils_user_data_pack(user_data, callback)); +} + +void +nm_dbus_connection_call_set(GDBusConnection * dbus_connection, + const char * bus_name, + const char * object_path, + const char * interface_name, + const char * property_name, + GVariant * value, + int timeout_msec, + GCancellable * cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data) +{ + g_dbus_connection_call(dbus_connection, + bus_name, + object_path, + DBUS_INTERFACE_PROPERTIES, + "Set", + g_variant_new("(ssv)", interface_name, property_name, value), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + timeout_msec, + cancellable, + callback ? _nm_dbus_connection_call_default_cb : NULL, + callback ? nm_utils_user_data_pack(user_data, callback) : NULL); +} + +/*****************************************************************************/ + +static void +_nm_dbus_connection_call_get_managed_objects_cb(GObject * source, + GAsyncResult *res, + gpointer user_data) +{ + gs_unref_variant GVariant *ret = NULL; + gs_unref_variant GVariant *arg = NULL; + gs_free_error GError * error = NULL; + gpointer orig_user_data; + NMDBusConnectionCallDefaultCb callback; + + nm_utils_user_data_unpack(user_data, &orig_user_data, &callback); + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error); + + nm_assert((!!ret) != (!!error)); + + if (ret) { + nm_assert(g_variant_is_of_type(ret, G_VARIANT_TYPE("(a{oa{sa{sv}}})"))); + arg = g_variant_get_child_value(ret, 0); + } + + callback(arg, error, orig_user_data); +} + +void +nm_dbus_connection_call_get_managed_objects(GDBusConnection * dbus_connection, + const char * bus_name, + const char * object_path, + GDBusCallFlags flags, + int timeout_msec, + GCancellable * cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data) +{ + nm_assert(callback); + + g_dbus_connection_call(dbus_connection, + bus_name, + object_path, + DBUS_INTERFACE_OBJECT_MANAGER, + "GetManagedObjects", + NULL, + G_VARIANT_TYPE("(a{oa{sa{sv}}})"), + flags, + timeout_msec, + cancellable, + _nm_dbus_connection_call_get_managed_objects_cb, + nm_utils_user_data_pack(user_data, callback)); +} + +/*****************************************************************************/ + +static void +_call_finish_cb(GObject * source, + GAsyncResult *result, + gpointer user_data, + gboolean return_void, + gboolean strip_dbus_error) +{ + gs_unref_object GTask *task = user_data; + gs_unref_variant GVariant *ret = NULL; + GError * error = NULL; + + nm_assert(G_IS_DBUS_CONNECTION(source)); + nm_assert(G_IS_TASK(user_data)); + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error); + if (!ret) { + if (strip_dbus_error) + g_dbus_error_strip_remote_error(error); + g_task_return_error(task, error); + return; + } + + if (!return_void) + g_task_return_pointer(task, g_steal_pointer(&ret), (GDestroyNotify) g_variant_unref); + else { + nm_assert(g_variant_is_of_type(ret, G_VARIANT_TYPE("()"))); + g_task_return_boolean(task, TRUE); + } +} + +/** + * nm_dbus_connection_call_finish_void_cb: + * + * A default callback to pass as callback to g_dbus_connection_call(). + * + * - user_data must be a GTask, whose reference will be consumed by the + * callback. + * - the return GVariant must be a empty tuple "()". + * - the GTask is returned either with error or TRUE boolean. + */ +void +nm_dbus_connection_call_finish_void_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + _call_finish_cb(source, result, user_data, TRUE, FALSE); +} + +/** + * nm_dbus_connection_call_finish_void_strip_dbus_error_cb: + * + * Like nm_dbus_connection_call_finish_void_cb(). The difference + * is that on error this will first call g_dbus_error_strip_remote_error() on the error. + */ +void +nm_dbus_connection_call_finish_void_strip_dbus_error_cb(GObject * source, + GAsyncResult *result, + gpointer user_data) +{ + _call_finish_cb(source, result, user_data, TRUE, TRUE); +} + +/** + * nm_dbus_connection_call_finish_variant_cb: + * + * A default callback to pass as callback to g_dbus_connection_call(). + * + * - user_data must be a GTask, whose reference will be consumed by the + * callback. + * - the GTask is returned either with error or with a pointer containing the GVariant. + */ +void +nm_dbus_connection_call_finish_variant_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + _call_finish_cb(source, result, user_data, FALSE, FALSE); +} + +/** + * nm_dbus_connection_call_finish_variant_strip_dbus_error_cb: + * + * Like nm_dbus_connection_call_finish_variant_strip_dbus_error_cb(). The difference + * is that on error this will first call g_dbus_error_strip_remote_error() on the error. + */ +void +nm_dbus_connection_call_finish_variant_strip_dbus_error_cb(GObject * source, + GAsyncResult *result, + gpointer user_data) +{ + _call_finish_cb(source, result, user_data, FALSE, TRUE); +} + +/*****************************************************************************/ + +gboolean +_nm_dbus_error_is(GError *error, ...) +{ + gs_free char *dbus_error = NULL; + const char * name; + va_list ap; + + dbus_error = g_dbus_error_get_remote_error(error); + if (!dbus_error) + return FALSE; + + va_start(ap, error); + while ((name = va_arg(ap, const char *))) { + if (nm_streq(dbus_error, name)) { + va_end(ap); + return TRUE; + } + } + va_end(ap); + + return FALSE; +} diff --git a/src/libnm-glib-aux/nm-dbus-aux.h b/src/libnm-glib-aux/nm-dbus-aux.h new file mode 100644 index 0000000..744d3b7 --- /dev/null +++ b/src/libnm-glib-aux/nm-dbus-aux.h @@ -0,0 +1,202 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#ifndef __NM_DBUS_AUX_H__ +#define __NM_DBUS_AUX_H__ + +#include "libnm-std-aux/nm-dbus-compat.h" + +/*****************************************************************************/ + +static inline gboolean +nm_clear_g_dbus_connection_signal(GDBusConnection *dbus_connection, guint *id) +{ + guint v; + + if (id && (v = *id)) { + *id = 0; + g_dbus_connection_signal_unsubscribe(dbus_connection, v); + return TRUE; + } + return FALSE; +} + +/*****************************************************************************/ + +typedef void (*NMDBusConnectionCallDefaultCb)(GVariant *result, GError *error, gpointer user_data); + +/*****************************************************************************/ + +static inline void +nm_dbus_connection_call_start_service_by_name(GDBusConnection * dbus_connection, + const char * name, + int timeout_msec, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_dbus_connection_call(dbus_connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "StartServiceByName", + g_variant_new("(su)", name, 0u), + G_VARIANT_TYPE("(u)"), + G_DBUS_CALL_FLAGS_NONE, + timeout_msec, + cancellable, + callback, + user_data); +} + +/*****************************************************************************/ + +static inline guint +nm_dbus_connection_signal_subscribe_name_owner_changed(GDBusConnection * dbus_connection, + const char * service_name, + GDBusSignalCallback callback, + gpointer user_data, + GDestroyNotify user_data_free_func) + +{ + return g_dbus_connection_signal_subscribe(dbus_connection, + DBUS_SERVICE_DBUS, + DBUS_INTERFACE_DBUS, + "NameOwnerChanged", + DBUS_PATH_DBUS, + service_name, + G_DBUS_SIGNAL_FLAGS_NONE, + callback, + user_data, + user_data_free_func); +} + +typedef void (*NMDBusConnectionCallGetNameOwnerCb)(const char *name_owner, + GError * error, + gpointer user_data); + +void nm_dbus_connection_call_get_name_owner(GDBusConnection * dbus_connection, + const char * service_name, + int timeout_msec, + GCancellable * cancellable, + NMDBusConnectionCallGetNameOwnerCb callback, + gpointer user_data); + +static inline guint +nm_dbus_connection_signal_subscribe_properties_changed(GDBusConnection * dbus_connection, + const char * bus_name, + const char * object_path, + const char * interface_name, + GDBusSignalCallback callback, + gpointer user_data, + GDestroyNotify user_data_free_func) + +{ + nm_assert(bus_name); + + /* it seems that using a non-unique name causes problems that we get signals + * also from unrelated senders. Usually, you are anyway monitoring the name-owner, + * so you should have the unique name at hand. + * + * If not, investigate this, ensure that it works, and lift this restriction. */ + nm_assert(g_dbus_is_unique_name(bus_name)); + + return g_dbus_connection_signal_subscribe(dbus_connection, + bus_name, + DBUS_INTERFACE_PROPERTIES, + "PropertiesChanged", + object_path, + interface_name, + G_DBUS_SIGNAL_FLAGS_NONE, + callback, + user_data, + user_data_free_func); +} + +void nm_dbus_connection_call_get_all(GDBusConnection * dbus_connection, + const char * bus_name, + const char * object_path, + const char * interface_name, + int timeout_msec, + GCancellable * cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data); + +void nm_dbus_connection_call_set(GDBusConnection * dbus_connection, + const char * bus_name, + const char * object_path, + const char * interface_name, + const char * property_name, + GVariant * value, + int timeout_msec, + GCancellable * cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data); + +/*****************************************************************************/ + +static inline guint +nm_dbus_connection_signal_subscribe_object_manager(GDBusConnection * dbus_connection, + const char * service_name, + const char * object_path, + const char * signal_name, + GDBusSignalCallback callback, + gpointer user_data, + GDestroyNotify user_data_free_func) +{ + return g_dbus_connection_signal_subscribe(dbus_connection, + service_name, + DBUS_INTERFACE_OBJECT_MANAGER, + signal_name, + object_path, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + callback, + user_data, + user_data_free_func); +} + +void nm_dbus_connection_call_get_managed_objects(GDBusConnection * dbus_connection, + const char * bus_name, + const char * object_path, + GDBusCallFlags flags, + int timeout_msec, + GCancellable * cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data); + +/*****************************************************************************/ + +void +nm_dbus_connection_call_finish_void_cb(GObject *source, GAsyncResult *result, gpointer user_data); + +void nm_dbus_connection_call_finish_void_strip_dbus_error_cb(GObject * source, + GAsyncResult *result, + gpointer user_data); + +void nm_dbus_connection_call_finish_variant_cb(GObject * source, + GAsyncResult *result, + gpointer user_data); + +void nm_dbus_connection_call_finish_variant_strip_dbus_error_cb(GObject * source, + GAsyncResult *result, + gpointer user_data); + +/*****************************************************************************/ + +gboolean _nm_dbus_error_is(GError *error, ...) G_GNUC_NULL_TERMINATED; + +#define nm_dbus_error_is(error, ...) \ + ({ \ + GError *const _error = (error); \ + \ + _error &&_nm_dbus_error_is(_error, __VA_ARGS__, NULL); \ + }) + +#define NM_DBUS_ERROR_NAME_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod" + +/*****************************************************************************/ + +#endif /* __NM_DBUS_AUX_H__ */ diff --git a/src/libnm-glib-aux/nm-dedup-multi.c b/src/libnm-glib-aux/nm-dedup-multi.c new file mode 100644 index 0000000..f77bb3c --- /dev/null +++ b/src/libnm-glib-aux/nm-dedup-multi.c @@ -0,0 +1,1065 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-dedup-multi.h" + +#include "nm-hash-utils.h" +#include "nm-c-list.h" + +/*****************************************************************************/ + +typedef struct { + /* the stack-allocated lookup entry. It has a compatible + * memory layout with NMDedupMultiEntry and NMDedupMultiHeadEntry. + * + * It is recognizable by having lst_entries_sentinel.next set to NULL. + * Contrary to the other entries, which have lst_entries.next + * always non-NULL. + * */ + CList lst_entries_sentinel; + const NMDedupMultiObj * obj; + const NMDedupMultiIdxType *idx_type; + bool lookup_head; +} LookupEntry; + +struct _NMDedupMultiIndex { + int ref_count; + GHashTable *idx_entries; + GHashTable *idx_objs; +}; + +/*****************************************************************************/ + +static void +ASSERT_idx_type(const NMDedupMultiIdxType *idx_type) +{ + nm_assert(idx_type); +#if NM_MORE_ASSERTS > 10 + nm_assert(idx_type->klass); + nm_assert(idx_type->klass->idx_obj_id_hash_update); + nm_assert(idx_type->klass->idx_obj_id_equal); + nm_assert(!!idx_type->klass->idx_obj_partition_hash_update + == !!idx_type->klass->idx_obj_partition_equal); + nm_assert(idx_type->lst_idx_head.next); +#endif +} + +void +nm_dedup_multi_idx_type_init(NMDedupMultiIdxType *idx_type, const NMDedupMultiIdxTypeClass *klass) +{ + nm_assert(idx_type); + nm_assert(klass); + + *idx_type = (NMDedupMultiIdxType){ + .klass = klass, + .lst_idx_head = C_LIST_INIT(idx_type->lst_idx_head), + }; + + ASSERT_idx_type(idx_type); +} + +/*****************************************************************************/ + +static NMDedupMultiEntry * +_entry_lookup_obj(const NMDedupMultiIndex * self, + const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj) +{ + const LookupEntry stack_entry = { + .obj = obj, + .idx_type = idx_type, + .lookup_head = FALSE, + }; + + ASSERT_idx_type(idx_type); + return g_hash_table_lookup(self->idx_entries, &stack_entry); +} + +static NMDedupMultiHeadEntry * +_entry_lookup_head(const NMDedupMultiIndex * self, + const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj) +{ + NMDedupMultiHeadEntry *head_entry; + const LookupEntry stack_entry = { + .obj = obj, + .idx_type = idx_type, + .lookup_head = TRUE, + }; + + ASSERT_idx_type(idx_type); + + if (!idx_type->klass->idx_obj_partition_equal) { + if (c_list_is_empty(&idx_type->lst_idx_head)) + head_entry = NULL; + else { + nm_assert(c_list_length(&idx_type->lst_idx_head) == 1); + head_entry = c_list_entry(idx_type->lst_idx_head.next, NMDedupMultiHeadEntry, lst_idx); + } + nm_assert(head_entry == g_hash_table_lookup(self->idx_entries, &stack_entry)); + return head_entry; + } + + return g_hash_table_lookup(self->idx_entries, &stack_entry); +} + +static void +_entry_unpack(const NMDedupMultiEntry * entry, + const NMDedupMultiIdxType **out_idx_type, + const NMDedupMultiObj ** out_obj, + gboolean * out_lookup_head) +{ + const NMDedupMultiHeadEntry *head_entry; + const LookupEntry * lookup_entry; + + nm_assert(entry); + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(LookupEntry, lst_entries_sentinel) + == G_STRUCT_OFFSET(NMDedupMultiEntry, lst_entries)); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMDedupMultiEntry, lst_entries) + == G_STRUCT_OFFSET(NMDedupMultiHeadEntry, lst_entries_head)); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMDedupMultiEntry, obj) + == G_STRUCT_OFFSET(NMDedupMultiHeadEntry, idx_type)); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMDedupMultiEntry, is_head) + == G_STRUCT_OFFSET(NMDedupMultiHeadEntry, is_head)); + + if (!entry->lst_entries.next) { + /* the entry is stack-allocated by _entry_lookup(). */ + lookup_entry = (LookupEntry *) entry; + *out_obj = lookup_entry->obj; + *out_idx_type = lookup_entry->idx_type; + *out_lookup_head = lookup_entry->lookup_head; + } else if (entry->is_head) { + head_entry = (NMDedupMultiHeadEntry *) entry; + nm_assert(!c_list_is_empty(&head_entry->lst_entries_head)); + *out_obj = + c_list_entry(head_entry->lst_entries_head.next, NMDedupMultiEntry, lst_entries)->obj; + *out_idx_type = head_entry->idx_type; + *out_lookup_head = TRUE; + } else { + *out_obj = entry->obj; + *out_idx_type = entry->head->idx_type; + *out_lookup_head = FALSE; + } + + nm_assert(NM_IN_SET(*out_lookup_head, FALSE, TRUE)); + ASSERT_idx_type(*out_idx_type); + + /* for lookup of the head, we allow to omit object, but only + * if the idx_type does not partition the objects. Otherwise, we + * require a obj to compare. */ + nm_assert(!*out_lookup_head || (*out_obj || !(*out_idx_type)->klass->idx_obj_partition_equal)); + + /* lookup of the object requires always an object. */ + nm_assert(*out_lookup_head || *out_obj); +} + +static guint +_dict_idx_entries_hash(const NMDedupMultiEntry *entry) +{ + const NMDedupMultiIdxType *idx_type; + const NMDedupMultiObj * obj; + gboolean lookup_head; + NMHashState h; + + _entry_unpack(entry, &idx_type, &obj, &lookup_head); + + nm_hash_init(&h, 1914869417u); + if (idx_type->klass->idx_obj_partition_hash_update) { + nm_assert(obj); + idx_type->klass->idx_obj_partition_hash_update(idx_type, obj, &h); + } + + if (!lookup_head) + idx_type->klass->idx_obj_id_hash_update(idx_type, obj, &h); + + nm_hash_update_val(&h, idx_type); + return nm_hash_complete(&h); +} + +static gboolean +_dict_idx_entries_equal(const NMDedupMultiEntry *entry_a, const NMDedupMultiEntry *entry_b) +{ + const NMDedupMultiIdxType *idx_type_a, *idx_type_b; + const NMDedupMultiObj * obj_a, *obj_b; + gboolean lookup_head_a, lookup_head_b; + + _entry_unpack(entry_a, &idx_type_a, &obj_a, &lookup_head_a); + _entry_unpack(entry_b, &idx_type_b, &obj_b, &lookup_head_b); + + if (idx_type_a != idx_type_b || lookup_head_a != lookup_head_b) + return FALSE; + if (!nm_dedup_multi_idx_type_partition_equal(idx_type_a, obj_a, obj_b)) + return FALSE; + if (!lookup_head_a && !nm_dedup_multi_idx_type_id_equal(idx_type_a, obj_a, obj_b)) + return FALSE; + return TRUE; +} + +/*****************************************************************************/ + +static gboolean +_add(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + const NMDedupMultiObj * obj, + NMDedupMultiEntry * entry, + NMDedupMultiIdxMode mode, + const NMDedupMultiEntry * entry_order, + NMDedupMultiHeadEntry * head_existing, + const NMDedupMultiEntry **out_entry, + const NMDedupMultiObj ** out_obj_old) +{ + NMDedupMultiHeadEntry *head_entry; + const NMDedupMultiObj *obj_new, *obj_old; + gboolean add_head_entry = FALSE; + + nm_assert(self); + ASSERT_idx_type(idx_type); + nm_assert(obj); + nm_assert(NM_IN_SET(mode, + NM_DEDUP_MULTI_IDX_MODE_PREPEND, + NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE, + NM_DEDUP_MULTI_IDX_MODE_APPEND, + NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE)); + nm_assert(!head_existing || head_existing->idx_type == idx_type); + nm_assert(({ + const NMDedupMultiHeadEntry *_h; + gboolean _ok = TRUE; + if (head_existing) { + _h = nm_dedup_multi_index_lookup_head(self, idx_type, obj); + if (head_existing == NM_DEDUP_MULTI_HEAD_ENTRY_MISSING) + _ok = (_h == NULL); + else + _ok = (_h == head_existing); + } + _ok; + })); + + if (entry) { + gboolean changed = FALSE; + + nm_dedup_multi_entry_set_dirty(entry, FALSE); + + nm_assert(!head_existing || entry->head == head_existing); + nm_assert(!entry_order || entry_order->head == entry->head); + nm_assert(!entry_order || c_list_contains(&entry->lst_entries, &entry_order->lst_entries)); + nm_assert(!entry_order || c_list_contains(&entry_order->lst_entries, &entry->lst_entries)); + + switch (mode) { + case NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE: + if (entry_order) { + if (nm_c_list_move_before((CList *) &entry_order->lst_entries, &entry->lst_entries)) + changed = TRUE; + } else { + if (nm_c_list_move_front((CList *) &entry->head->lst_entries_head, + &entry->lst_entries)) + changed = TRUE; + } + break; + case NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE: + if (entry_order) { + if (nm_c_list_move_after((CList *) &entry_order->lst_entries, &entry->lst_entries)) + changed = TRUE; + } else { + if (nm_c_list_move_tail((CList *) &entry->head->lst_entries_head, + &entry->lst_entries)) + changed = TRUE; + } + break; + case NM_DEDUP_MULTI_IDX_MODE_PREPEND: + case NM_DEDUP_MULTI_IDX_MODE_APPEND: + break; + }; + + nm_assert(obj->klass == ((const NMDedupMultiObj *) entry->obj)->klass); + if (obj == entry->obj || obj->klass->obj_full_equal(obj, entry->obj)) { + NM_SET_OUT(out_entry, entry); + NM_SET_OUT(out_obj_old, nm_dedup_multi_obj_ref(entry->obj)); + return changed; + } + + obj_new = nm_dedup_multi_index_obj_intern(self, obj); + + obj_old = entry->obj; + entry->obj = obj_new; + + NM_SET_OUT(out_entry, entry); + if (out_obj_old) + *out_obj_old = obj_old; + else + nm_dedup_multi_obj_unref(obj_old); + return TRUE; + } + + if (idx_type->klass->idx_obj_partitionable + && !idx_type->klass->idx_obj_partitionable(idx_type, obj)) { + /* this object cannot be partitioned by this idx_type. */ + nm_assert(!head_existing || head_existing == NM_DEDUP_MULTI_HEAD_ENTRY_MISSING); + NM_SET_OUT(out_entry, NULL); + NM_SET_OUT(out_obj_old, NULL); + return FALSE; + } + + obj_new = nm_dedup_multi_index_obj_intern(self, obj); + + if (!head_existing) + head_entry = _entry_lookup_head(self, idx_type, obj_new); + else if (head_existing == NM_DEDUP_MULTI_HEAD_ENTRY_MISSING) + head_entry = NULL; + else + head_entry = head_existing; + + if (!head_entry) { + head_entry = g_slice_new0(NMDedupMultiHeadEntry); + head_entry->is_head = TRUE; + head_entry->idx_type = idx_type; + c_list_init(&head_entry->lst_entries_head); + c_list_link_tail(&idx_type->lst_idx_head, &head_entry->lst_idx); + add_head_entry = TRUE; + } else + nm_assert(c_list_contains(&idx_type->lst_idx_head, &head_entry->lst_idx)); + + if (entry_order) { + nm_assert(!add_head_entry); + nm_assert(entry_order->head == head_entry); + nm_assert(c_list_contains(&head_entry->lst_entries_head, &entry_order->lst_entries)); + nm_assert(c_list_contains(&entry_order->lst_entries, &head_entry->lst_entries_head)); + } + + entry = g_slice_new0(NMDedupMultiEntry); + entry->obj = obj_new; + entry->head = head_entry; + + switch (mode) { + case NM_DEDUP_MULTI_IDX_MODE_PREPEND: + case NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE: + if (entry_order) + c_list_link_before((CList *) &entry_order->lst_entries, &entry->lst_entries); + else + c_list_link_front(&head_entry->lst_entries_head, &entry->lst_entries); + break; + default: + if (entry_order) + c_list_link_after((CList *) &entry_order->lst_entries, &entry->lst_entries); + else + c_list_link_tail(&head_entry->lst_entries_head, &entry->lst_entries); + break; + }; + + idx_type->len++; + head_entry->len++; + + if (add_head_entry && !g_hash_table_add(self->idx_entries, head_entry)) + nm_assert_not_reached(); + + if (!g_hash_table_add(self->idx_entries, entry)) + nm_assert_not_reached(); + + NM_SET_OUT(out_entry, entry); + NM_SET_OUT(out_obj_old, NULL); + return TRUE; +} + +gboolean +nm_dedup_multi_index_add(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj, + NMDedupMultiIdxMode mode, + const NMDedupMultiEntry ** out_entry, + /* const NMDedupMultiObj ** */ gpointer out_obj_old) +{ + NMDedupMultiEntry *entry; + + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(idx_type, FALSE); + g_return_val_if_fail(obj, FALSE); + g_return_val_if_fail(NM_IN_SET(mode, + NM_DEDUP_MULTI_IDX_MODE_PREPEND, + NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE, + NM_DEDUP_MULTI_IDX_MODE_APPEND, + NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE), + FALSE); + + entry = _entry_lookup_obj(self, idx_type, obj); + return _add(self, idx_type, obj, entry, mode, NULL, NULL, out_entry, out_obj_old); +} + +/* nm_dedup_multi_index_add_full: + * @self: the index instance. + * @idx_type: the index handle for storing @obj. + * @obj: the NMDedupMultiObj instance to add. + * @mode: whether to append or prepend the new item. If @entry_order is given, + * the entry will be sorted after/before, instead of appending/prepending to + * the entire list. If a comparable object is already tracked, then it may + * still be resorted by specifying one of the "FORCE" modes. + * @entry_order: if not NULL, the new entry will be sorted before or after @entry_order. + * If given, @entry_order MUST be tracked by @self, and the object it points to MUST + * be in the same partition tracked by @idx_type. That is, they must have the same + * head_entry and it means, you must ensure that @entry_order and the created/modified + * entry will share the same head. + * @entry_existing: if not NULL, it safes a hash lookup of the entry where the + * object will be placed in. You can omit this, and it will be automatically + * detected (at the expense of an additional hash lookup). + * Basically, this is the result of nm_dedup_multi_index_lookup_obj(), + * with the peculiarity that if you know that @obj is not yet tracked, + * you may specify %NM_DEDUP_MULTI_ENTRY_MISSING. + * @head_existing: an optional argument to safe a lookup for the head. If specified, + * it must be identical to nm_dedup_multi_index_lookup_head(), with the peculiarity + * that if the head is not yet tracked, you may specify %NM_DEDUP_MULTI_HEAD_ENTRY_MISSING + * @out_entry: if give, return the added entry. This entry may have already exists (update) + * or be newly created. If @obj is not partitionable according to @idx_type, @obj + * is not to be added and it returns %NULL. + * @out_obj_old: if given, return the previously contained object. It only + * returns a object, if a matching entry was tracked previously, not if a + * new entry was created. Note that when passing @out_obj_old you obtain a reference + * to the boxed object and MUST return it with nm_dedup_multi_obj_unref(). + * + * Adds and object to the index. + * + * Return: %TRUE if anything changed, %FALSE if nothing changed. + */ +gboolean +nm_dedup_multi_index_add_full(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj, + NMDedupMultiIdxMode mode, + const NMDedupMultiEntry * entry_order, + const NMDedupMultiEntry * entry_existing, + const NMDedupMultiHeadEntry * head_existing, + const NMDedupMultiEntry ** out_entry, + /* const NMDedupMultiObj ** */ gpointer out_obj_old) +{ + NMDedupMultiEntry *entry; + + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(idx_type, FALSE); + g_return_val_if_fail(obj, FALSE); + g_return_val_if_fail(NM_IN_SET(mode, + NM_DEDUP_MULTI_IDX_MODE_PREPEND, + NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE, + NM_DEDUP_MULTI_IDX_MODE_APPEND, + NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE), + FALSE); + + if (entry_existing == NULL) + entry = _entry_lookup_obj(self, idx_type, obj); + else if (entry_existing == NM_DEDUP_MULTI_ENTRY_MISSING) { + nm_assert(!_entry_lookup_obj(self, idx_type, obj)); + entry = NULL; + } else { + nm_assert(entry_existing == _entry_lookup_obj(self, idx_type, obj)); + entry = (NMDedupMultiEntry *) entry_existing; + } + return _add(self, + idx_type, + obj, + entry, + mode, + entry_order, + (NMDedupMultiHeadEntry *) head_existing, + out_entry, + out_obj_old); +} + +/*****************************************************************************/ + +static void +_remove_entry(NMDedupMultiIndex *self, NMDedupMultiEntry *entry, gboolean *out_head_entry_removed) +{ + const NMDedupMultiObj *obj; + NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIdxType * idx_type; + + nm_assert(self); + nm_assert(entry); + nm_assert(entry->obj); + nm_assert(entry->head); + nm_assert(!c_list_is_empty(&entry->lst_entries)); + nm_assert(g_hash_table_lookup(self->idx_entries, entry) == entry); + + head_entry = (NMDedupMultiHeadEntry *) entry->head; + obj = entry->obj; + + nm_assert(head_entry); + nm_assert(head_entry->len > 0); + nm_assert(g_hash_table_lookup(self->idx_entries, head_entry) == head_entry); + + idx_type = (NMDedupMultiIdxType *) head_entry->idx_type; + ASSERT_idx_type(idx_type); + + nm_assert(idx_type->len >= head_entry->len); + if (--head_entry->len > 0) { + nm_assert(idx_type->len > 1); + idx_type->len--; + head_entry = NULL; + } + + NM_SET_OUT(out_head_entry_removed, head_entry != NULL); + + if (!g_hash_table_remove(self->idx_entries, entry)) + nm_assert_not_reached(); + + if (head_entry && !g_hash_table_remove(self->idx_entries, head_entry)) + nm_assert_not_reached(); + + c_list_unlink_stale(&entry->lst_entries); + g_slice_free(NMDedupMultiEntry, entry); + + if (head_entry) { + nm_assert(c_list_is_empty(&head_entry->lst_entries_head)); + c_list_unlink_stale(&head_entry->lst_idx); + g_slice_free(NMDedupMultiHeadEntry, head_entry); + } + + nm_dedup_multi_obj_unref(obj); +} + +static guint +_remove_head(NMDedupMultiIndex * self, + NMDedupMultiHeadEntry *head_entry, + gboolean remove_all /* otherwise just dirty ones */, + gboolean mark_survivors_dirty) +{ + guint n; + gboolean head_entry_removed; + CList * iter_entry, *iter_entry_safe; + + nm_assert(self); + nm_assert(head_entry); + nm_assert(head_entry->len > 0); + nm_assert(head_entry->len == c_list_length(&head_entry->lst_entries_head)); + nm_assert(g_hash_table_lookup(self->idx_entries, head_entry) == head_entry); + + n = 0; + c_list_for_each_safe (iter_entry, iter_entry_safe, &head_entry->lst_entries_head) { + NMDedupMultiEntry *entry; + + entry = c_list_entry(iter_entry, NMDedupMultiEntry, lst_entries); + if (remove_all || entry->dirty) { + _remove_entry(self, entry, &head_entry_removed); + n++; + if (head_entry_removed) + break; + } else if (mark_survivors_dirty) + nm_dedup_multi_entry_set_dirty(entry, TRUE); + } + + return n; +} + +static guint +_remove_idx_entry(NMDedupMultiIndex * self, + NMDedupMultiIdxType *idx_type, + gboolean remove_all /* otherwise just dirty ones */, + gboolean mark_survivors_dirty) +{ + guint n; + CList *iter_idx, *iter_idx_safe; + + nm_assert(self); + ASSERT_idx_type(idx_type); + + n = 0; + c_list_for_each_safe (iter_idx, iter_idx_safe, &idx_type->lst_idx_head) { + n += _remove_head(self, + c_list_entry(iter_idx, NMDedupMultiHeadEntry, lst_idx), + remove_all, + mark_survivors_dirty); + } + return n; +} + +guint +nm_dedup_multi_index_remove_entry(NMDedupMultiIndex *self, gconstpointer entry) +{ + g_return_val_if_fail(self, 0); + + nm_assert(entry); + + if (!((NMDedupMultiEntry *) entry)->is_head) { + _remove_entry(self, (NMDedupMultiEntry *) entry, NULL); + return 1; + } + return _remove_head(self, (NMDedupMultiHeadEntry *) entry, TRUE, FALSE); +} + +guint +nm_dedup_multi_index_remove_obj(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj, + /*const NMDedupMultiObj ** */ gconstpointer *out_obj) +{ + const NMDedupMultiEntry *entry; + + entry = nm_dedup_multi_index_lookup_obj(self, idx_type, obj); + if (!entry) { + NM_SET_OUT(out_obj, NULL); + return 0; + } + + /* since we are about to remove the object, we obviously pass + * a reference to @out_obj, the caller MUST unref the object, + * if he chooses to provide @out_obj. */ + NM_SET_OUT(out_obj, nm_dedup_multi_obj_ref(entry->obj)); + + _remove_entry(self, (NMDedupMultiEntry *) entry, NULL); + return 1; +} + +guint +nm_dedup_multi_index_remove_head(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj) +{ + const NMDedupMultiHeadEntry *entry; + + entry = nm_dedup_multi_index_lookup_head(self, idx_type, obj); + return entry ? _remove_head(self, (NMDedupMultiHeadEntry *) entry, TRUE, FALSE) : 0; +} + +guint +nm_dedup_multi_index_remove_idx(NMDedupMultiIndex *self, NMDedupMultiIdxType *idx_type) +{ + g_return_val_if_fail(self, 0); + g_return_val_if_fail(idx_type, 0); + + return _remove_idx_entry(self, idx_type, TRUE, FALSE); +} + +/*****************************************************************************/ + +/** + * nm_dedup_multi_index_lookup_obj: + * @self: the index cache + * @idx_type: the lookup index type + * @obj: the object to lookup. This means the match is performed + * according to NMDedupMultiIdxTypeClass's idx_obj_id_equal() + * of @idx_type. + * + * Returns: the cache entry or %NULL if the entry wasn't found. + */ +const NMDedupMultiEntry * +nm_dedup_multi_index_lookup_obj(const NMDedupMultiIndex * self, + const NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj) +{ + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(idx_type, FALSE); + g_return_val_if_fail(obj, FALSE); + + nm_assert(idx_type && idx_type->klass); + return _entry_lookup_obj(self, idx_type, obj); +} + +/** + * nm_dedup_multi_index_lookup_head: + * @self: the index cache + * @idx_type: the lookup index type + * @obj: the object to lookup, of type "const NMDedupMultiObj *". + * Depending on the idx_type, you *must* also provide a selector + * object, even when looking up the list head. That is, because + * the idx_type implementation may choose to partition the objects + * in distinct list, so you need a selector object to know which + * list head to lookup. + * + * Returns: the cache entry or %NULL if the entry wasn't found. + */ +const NMDedupMultiHeadEntry * +nm_dedup_multi_index_lookup_head(const NMDedupMultiIndex * self, + const NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj) +{ + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(idx_type, FALSE); + + return _entry_lookup_head(self, idx_type, obj); +} + +/*****************************************************************************/ + +void +nm_dedup_multi_index_dirty_set_head(NMDedupMultiIndex * self, + const NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj) +{ + NMDedupMultiHeadEntry *head_entry; + CList * iter_entry; + + g_return_if_fail(self); + g_return_if_fail(idx_type); + + head_entry = _entry_lookup_head(self, idx_type, obj); + if (!head_entry) + return; + + c_list_for_each (iter_entry, &head_entry->lst_entries_head) { + NMDedupMultiEntry *entry; + + entry = c_list_entry(iter_entry, NMDedupMultiEntry, lst_entries); + nm_dedup_multi_entry_set_dirty(entry, TRUE); + } +} + +void +nm_dedup_multi_index_dirty_set_idx(NMDedupMultiIndex *self, const NMDedupMultiIdxType *idx_type) +{ + CList *iter_idx, *iter_entry; + + g_return_if_fail(self); + g_return_if_fail(idx_type); + + c_list_for_each (iter_idx, &idx_type->lst_idx_head) { + NMDedupMultiHeadEntry *head_entry; + + head_entry = c_list_entry(iter_idx, NMDedupMultiHeadEntry, lst_idx); + c_list_for_each (iter_entry, &head_entry->lst_entries_head) { + NMDedupMultiEntry *entry; + + entry = c_list_entry(iter_entry, NMDedupMultiEntry, lst_entries); + nm_dedup_multi_entry_set_dirty(entry, TRUE); + } + } +} + +/** + * nm_dedup_multi_index_dirty_remove_idx: + * @self: the index instance + * @idx_type: the index-type to select the objects. + * @mark_survivors_dirty: while the function removes all entries that are + * marked as dirty, if @set_dirty is true, the surviving objects + * will be marked dirty right away. + * + * Deletes all entries for @idx_type that are marked dirty. Only + * non-dirty objects survive. If @mark_survivors_dirty is set to TRUE, the survivors + * are marked as dirty right away. + * + * Returns: number of deleted entries. + */ +guint +nm_dedup_multi_index_dirty_remove_idx(NMDedupMultiIndex * self, + NMDedupMultiIdxType *idx_type, + gboolean mark_survivors_dirty) +{ + g_return_val_if_fail(self, 0); + g_return_val_if_fail(idx_type, 0); + + return _remove_idx_entry(self, idx_type, FALSE, mark_survivors_dirty); +} + +/*****************************************************************************/ + +static guint +_dict_idx_objs_hash(const NMDedupMultiObj *obj) +{ + NMHashState h; + + nm_hash_init(&h, 1748638583u); + obj->klass->obj_full_hash_update(obj, &h); + return nm_hash_complete(&h); +} + +static gboolean +_dict_idx_objs_equal(const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b) +{ + return obj_a == obj_b + || (obj_a->klass == obj_b->klass && obj_a->klass->obj_full_equal(obj_a, obj_b)); +} + +void +nm_dedup_multi_index_obj_release(NMDedupMultiIndex * self, + /* const NMDedupMultiObj * */ gconstpointer obj) +{ + nm_assert(self); + nm_assert(obj); + nm_assert(g_hash_table_lookup(self->idx_objs, obj) == obj); + nm_assert(((const NMDedupMultiObj *) obj)->_multi_idx == self); + + ((NMDedupMultiObj *) obj)->_multi_idx = NULL; + if (!g_hash_table_remove(self->idx_objs, obj)) + nm_assert_not_reached(); +} + +gconstpointer +nm_dedup_multi_index_obj_find(NMDedupMultiIndex * self, + /* const NMDedupMultiObj * */ gconstpointer obj) +{ + g_return_val_if_fail(self, NULL); + g_return_val_if_fail(obj, NULL); + + return g_hash_table_lookup(self->idx_objs, obj); +} + +gconstpointer +nm_dedup_multi_index_obj_intern(NMDedupMultiIndex * self, + /* const NMDedupMultiObj * */ gconstpointer obj) +{ + const NMDedupMultiObj *obj_new = obj; + const NMDedupMultiObj *obj_old; + + nm_assert(self); + nm_assert(obj_new); + + if (obj_new->_multi_idx == self) { + nm_assert(g_hash_table_lookup(self->idx_objs, obj_new) == obj_new); + nm_dedup_multi_obj_ref(obj_new); + return obj_new; + } + + obj_old = g_hash_table_lookup(self->idx_objs, obj_new); + nm_assert(obj_old != obj_new); + + if (obj_old) { + nm_assert(obj_old->_multi_idx == self); + nm_dedup_multi_obj_ref(obj_old); + return obj_old; + } + + if (nm_dedup_multi_obj_needs_clone(obj_new)) + obj_new = nm_dedup_multi_obj_clone(obj_new); + else + obj_new = nm_dedup_multi_obj_ref(obj_new); + + nm_assert(obj_new); + nm_assert(!obj_new->_multi_idx); + + if (!g_hash_table_add(self->idx_objs, (gpointer) obj_new)) + nm_assert_not_reached(); + + ((NMDedupMultiObj *) obj_new)->_multi_idx = self; + return obj_new; +} + +void +nm_dedup_multi_obj_unref(const NMDedupMultiObj *obj) +{ + if (obj) { + nm_assert(obj->_ref_count > 0); + nm_assert(obj->_ref_count != NM_OBJ_REF_COUNT_STACKINIT); + +again: + if (--(((NMDedupMultiObj *) obj)->_ref_count) <= 0) { + if (obj->_multi_idx) { + /* restore the ref-count to 1 and release the object first + * from the index. Then, retry again to unref. */ + ((NMDedupMultiObj *) obj)->_ref_count++; + nm_dedup_multi_index_obj_release(obj->_multi_idx, obj); + nm_assert(obj->_ref_count == 1); + nm_assert(!obj->_multi_idx); + goto again; + } + + obj->klass->obj_destroy((NMDedupMultiObj *) obj); + } + } +} + +gboolean +nm_dedup_multi_obj_needs_clone(const NMDedupMultiObj *obj) +{ + nm_assert(obj); + + if (obj->_multi_idx || obj->_ref_count == NM_OBJ_REF_COUNT_STACKINIT) + return TRUE; + + if (obj->klass->obj_needs_clone && obj->klass->obj_needs_clone(obj)) + return TRUE; + + return FALSE; +} + +const NMDedupMultiObj * +nm_dedup_multi_obj_clone(const NMDedupMultiObj *obj) +{ + const NMDedupMultiObj *o; + + nm_assert(obj); + + o = obj->klass->obj_clone(obj); + nm_assert(o); + nm_assert(o->_ref_count == 1); + return o; +} + +gconstpointer * +nm_dedup_multi_objs_to_array_head(const NMDedupMultiHeadEntry * head_entry, + NMDedupMultiFcnSelectPredicate predicate, + gpointer user_data, + guint * out_len) +{ + gconstpointer *result; + CList * iter; + guint i; + + if (!head_entry) { + NM_SET_OUT(out_len, 0); + return NULL; + } + + result = g_new(gconstpointer, head_entry->len + 1); + i = 0; + c_list_for_each (iter, &head_entry->lst_entries_head) { + const NMDedupMultiObj *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; + + if (!predicate || predicate(obj, user_data)) { + nm_assert(i < head_entry->len); + result[i++] = obj; + } + } + + if (i == 0) { + g_free(result); + NM_SET_OUT(out_len, 0); + return NULL; + } + + nm_assert(i <= head_entry->len); + NM_SET_OUT(out_len, i); + result[i++] = NULL; + return result; +} + +GPtrArray * +nm_dedup_multi_objs_to_ptr_array_head(const NMDedupMultiHeadEntry * head_entry, + NMDedupMultiFcnSelectPredicate predicate, + gpointer user_data) +{ + GPtrArray *result; + CList * iter; + + if (!head_entry) + return NULL; + + result = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nm_dedup_multi_obj_unref); + c_list_for_each (iter, &head_entry->lst_entries_head) { + const NMDedupMultiObj *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; + + if (!predicate || predicate(obj, user_data)) + g_ptr_array_add(result, (gpointer) nm_dedup_multi_obj_ref(obj)); + } + + if (result->len == 0) { + g_ptr_array_unref(result); + return NULL; + } + return result; +} + +/** + * nm_dedup_multi_entry_reorder: + * @entry: the entry to reorder. It must not be NULL (and tracked in an index). + * @entry_order: (allow-none): an optional other entry. It MUST be in the same + * list as entry. If given, @entry will be ordered after/before @entry_order. + * If left at %NULL, @entry will be moved to the front/end of the list. + * @order_after: if @entry_order is given, %TRUE means to move @entry after + * @entry_order (otherwise before). + * If @entry_order is %NULL, %TRUE means to move @entry to the tail of the list + * (otherwise the beginning). Note that "tail of the list" here means that @entry + * will be linked before the head of the circular list. + * + * Returns: %TRUE, if anything was changed. Otherwise, @entry was already at the + * right place and nothing was done. + */ +gboolean +nm_dedup_multi_entry_reorder(const NMDedupMultiEntry *entry, + const NMDedupMultiEntry *entry_order, + gboolean order_after) +{ + nm_assert(entry); + + if (!entry_order) { + const NMDedupMultiHeadEntry *head_entry = entry->head; + + if (order_after) { + if (nm_c_list_move_tail((CList *) &head_entry->lst_entries_head, + (CList *) &entry->lst_entries)) + return TRUE; + } else { + if (nm_c_list_move_front((CList *) &head_entry->lst_entries_head, + (CList *) &entry->lst_entries)) + return TRUE; + } + } else { + if (order_after) { + if (nm_c_list_move_after((CList *) &entry_order->lst_entries, + (CList *) &entry->lst_entries)) + return TRUE; + } else { + if (nm_c_list_move_before((CList *) &entry_order->lst_entries, + (CList *) &entry->lst_entries)) + return TRUE; + } + } + + return FALSE; +} + +/*****************************************************************************/ + +NMDedupMultiIndex * +nm_dedup_multi_index_new(void) +{ + NMDedupMultiIndex *self; + + self = g_slice_new0(NMDedupMultiIndex); + self->ref_count = 1; + self->idx_entries = + g_hash_table_new((GHashFunc) _dict_idx_entries_hash, (GEqualFunc) _dict_idx_entries_equal); + self->idx_objs = + g_hash_table_new((GHashFunc) _dict_idx_objs_hash, (GEqualFunc) _dict_idx_objs_equal); + return self; +} + +NMDedupMultiIndex * +nm_dedup_multi_index_ref(NMDedupMultiIndex *self) +{ + g_return_val_if_fail(self, NULL); + g_return_val_if_fail(self->ref_count > 0, NULL); + + self->ref_count++; + return self; +} + +NMDedupMultiIndex * +nm_dedup_multi_index_unref(NMDedupMultiIndex *self) +{ + GHashTableIter iter; + const NMDedupMultiIdxType *idx_type; + NMDedupMultiEntry * entry; + const NMDedupMultiObj * obj; + + g_return_val_if_fail(self, NULL); + g_return_val_if_fail(self->ref_count > 0, NULL); + + if (--self->ref_count > 0) + return NULL; + +more: + g_hash_table_iter_init(&iter, self->idx_entries); + while (g_hash_table_iter_next(&iter, (gpointer *) &entry, NULL)) { + if (entry->is_head) + idx_type = ((NMDedupMultiHeadEntry *) entry)->idx_type; + else + idx_type = entry->head->idx_type; + _remove_idx_entry(self, (NMDedupMultiIdxType *) idx_type, TRUE, FALSE); + goto more; + } + + nm_assert(g_hash_table_size(self->idx_entries) == 0); + + g_hash_table_iter_init(&iter, self->idx_objs); + while (g_hash_table_iter_next(&iter, (gpointer *) &obj, NULL)) { + nm_assert(obj->_multi_idx == self); + ((NMDedupMultiObj *) obj)->_multi_idx = NULL; + } + g_hash_table_remove_all(self->idx_objs); + + g_hash_table_unref(self->idx_entries); + g_hash_table_unref(self->idx_objs); + + g_slice_free(NMDedupMultiIndex, self); + return NULL; +} diff --git a/src/libnm-glib-aux/nm-dedup-multi.h b/src/libnm-glib-aux/nm-dedup-multi.h new file mode 100644 index 0000000..9a995ec --- /dev/null +++ b/src/libnm-glib-aux/nm-dedup-multi.h @@ -0,0 +1,407 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_DEDUP_MULTI_H__ +#define __NM_DEDUP_MULTI_H__ + +#include "nm-obj.h" +#include "libnm-std-aux/c-list-util.h" + +/*****************************************************************************/ + +struct _NMHashState; + +typedef struct _NMDedupMultiObj NMDedupMultiObj; +typedef struct _NMDedupMultiObjClass NMDedupMultiObjClass; +typedef struct _NMDedupMultiIdxType NMDedupMultiIdxType; +typedef struct _NMDedupMultiIdxTypeClass NMDedupMultiIdxTypeClass; +typedef struct _NMDedupMultiEntry NMDedupMultiEntry; +typedef struct _NMDedupMultiHeadEntry NMDedupMultiHeadEntry; +typedef struct _NMDedupMultiIndex NMDedupMultiIndex; + +typedef enum _NMDedupMultiIdxMode { + NM_DEDUP_MULTI_IDX_MODE_PREPEND, + + NM_DEDUP_MULTI_IDX_MODE_PREPEND_FORCE, + + /* append new objects to the end of the list. + * If the object is already in the cache, don't move it. */ + NM_DEDUP_MULTI_IDX_MODE_APPEND, + + /* like NM_DEDUP_MULTI_IDX_MODE_APPEND, but if the object + * is already in the cache, move it to the end. */ + NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE, +} NMDedupMultiIdxMode; + +/*****************************************************************************/ + +struct _NMDedupMultiObj { + union { + NMObjBaseInst parent; + const NMDedupMultiObjClass *klass; + }; + NMDedupMultiIndex *_multi_idx; + guint _ref_count; +}; + +struct _NMDedupMultiObjClass { + NMObjBaseClass parent; + + const NMDedupMultiObj *(*obj_clone)(const NMDedupMultiObj *obj); + + gboolean (*obj_needs_clone)(const NMDedupMultiObj *obj); + + void (*obj_destroy)(NMDedupMultiObj *obj); + + /* the NMDedupMultiObj can be deduplicated. For that the obj_full_hash_update() + * and obj_full_equal() compare *all* fields of the object, even minor ones. */ + void (*obj_full_hash_update)(const NMDedupMultiObj *obj, struct _NMHashState *h); + gboolean (*obj_full_equal)(const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b); +}; + +/*****************************************************************************/ + +static inline const NMDedupMultiObj * +nm_dedup_multi_obj_ref(const NMDedupMultiObj *obj) +{ + /* ref and unref accept const pointers. Objects is supposed to be shared + * and kept immutable. Disallowing to take/return a reference to a const + * NMPObject is cumbersome, because callers are precisely expected to + * keep a ref on the otherwise immutable object. */ + + nm_assert(obj); + nm_assert(obj->_ref_count != NM_OBJ_REF_COUNT_STACKINIT); + nm_assert(obj->_ref_count > 0); + + ((NMDedupMultiObj *) obj)->_ref_count++; + return obj; +} + +void nm_dedup_multi_obj_unref(const NMDedupMultiObj *obj); +const NMDedupMultiObj *nm_dedup_multi_obj_clone(const NMDedupMultiObj *obj); +gboolean nm_dedup_multi_obj_needs_clone(const NMDedupMultiObj *obj); + +gconstpointer nm_dedup_multi_index_obj_intern(NMDedupMultiIndex * self, + /* const NMDedupMultiObj * */ gconstpointer obj); + +void nm_dedup_multi_index_obj_release(NMDedupMultiIndex * self, + /* const NMDedupMultiObj * */ gconstpointer obj); + +/* const NMDedupMultiObj * */ gconstpointer +nm_dedup_multi_index_obj_find(NMDedupMultiIndex * self, + /* const NMDedupMultiObj * */ gconstpointer obj); + +/*****************************************************************************/ + +/* the NMDedupMultiIdxType is an access handle under which you can store and + * retrieve NMDedupMultiObj instances in NMDedupMultiIndex. + * + * The NMDedupMultiIdxTypeClass determines its behavior, but you can have + * multiple instances (of the same class). + * + * For example, NMIP4Config can have idx-type to put there all IPv4 Routes. + * This idx-type instance is private to the NMIP4Config instance. Basically, + * the NMIP4Config instance uses the idx-type to maintain an ordered list + * of routes in NMDedupMultiIndex. + * + * However, a NMDedupMultiIdxType may also partition the set of objects + * in multiple distinct lists. NMIP4Config doesn't do that (because instead + * of creating one idx-type for IPv4 and IPv6 routes, it just cretaes + * to distinct idx-types, one for each address family. + * This partitioning is used by NMPlatform to maintain a lookup index for + * routes by ifindex. As the ifindex is dynamic, it does not create an + * idx-type instance for each ifindex. Instead, it has one idx-type for + * all routes. But whenever accessing NMDedupMultiIndex with an NMDedupMultiObj, + * the partitioning NMDedupMultiIdxType takes into account the NMDedupMultiObj + * instance to associate it with the right list. + * + * Hence, a NMDedupMultiIdxEntry has a list of possibly multiple NMDedupMultiHeadEntry + * instances, which each is the head for a list of NMDedupMultiEntry instances. + * In the platform example, the NMDedupMultiHeadEntry partition the indexed objects + * by their ifindex. */ +struct _NMDedupMultiIdxType { + union { + NMObjBaseInst parent; + const NMDedupMultiIdxTypeClass *klass; + }; + + CList lst_idx_head; + + guint len; +}; + +void nm_dedup_multi_idx_type_init(NMDedupMultiIdxType * idx_type, + const NMDedupMultiIdxTypeClass *klass); + +struct _NMDedupMultiIdxTypeClass { + NMObjBaseClass parent; + + void (*idx_obj_id_hash_update)(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj, + struct _NMHashState * h); + gboolean (*idx_obj_id_equal)(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj_a, + const NMDedupMultiObj * obj_b); + + /* an NMDedupMultiIdxTypeClass which implements partitioning of the + * tracked objects, must implement the idx_obj_partition*() functions. + * + * idx_obj_partitionable() may return NULL if the object cannot be tracked. + * For example, a index for routes by ifindex, may not want to track any + * routes that don't have a valid ifindex. If the idx-type says that the + * object is not partitionable, it is never added to the NMDedupMultiIndex. */ + gboolean (*idx_obj_partitionable)(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj); + void (*idx_obj_partition_hash_update)(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj, + struct _NMHashState * h); + gboolean (*idx_obj_partition_equal)(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj_a, + const NMDedupMultiObj * obj_b); +}; + +static inline gboolean +nm_dedup_multi_idx_type_id_equal(const NMDedupMultiIdxType * idx_type, + /* const NMDedupMultiObj * */ gconstpointer obj_a, + /* const NMDedupMultiObj * */ gconstpointer obj_b) +{ + nm_assert(idx_type); + return obj_a == obj_b || idx_type->klass->idx_obj_id_equal(idx_type, obj_a, obj_b); +} + +static inline gboolean +nm_dedup_multi_idx_type_partition_equal(const NMDedupMultiIdxType * idx_type, + /* const NMDedupMultiObj * */ gconstpointer obj_a, + /* const NMDedupMultiObj * */ gconstpointer obj_b) +{ + nm_assert(idx_type); + if (idx_type->klass->idx_obj_partition_equal) { + nm_assert(obj_a); + nm_assert(obj_b); + return obj_a == obj_b || idx_type->klass->idx_obj_partition_equal(idx_type, obj_a, obj_b); + } + return TRUE; +} + +/*****************************************************************************/ + +struct _NMDedupMultiEntry { + /* this is the list of all entries that share the same head entry. + * All entries compare equal according to idx_obj_partition_equal(). */ + CList lst_entries; + + /* const NMDedupMultiObj * */ gconstpointer obj; + + bool is_head; + bool dirty; + + const NMDedupMultiHeadEntry *head; +}; + +struct _NMDedupMultiHeadEntry { + /* this is the list of all entries that share the same head entry. + * All entries compare equal according to idx_obj_partition_equal(). */ + CList lst_entries_head; + + const NMDedupMultiIdxType *idx_type; + + bool is_head; + + guint len; + + CList lst_idx; +}; + +/*****************************************************************************/ + +static inline gconstpointer +nm_dedup_multi_entry_get_obj(const NMDedupMultiEntry *entry) +{ + /* convenience method that allows to skip the %NULL check on + * @entry. Think of the NULL-conditional operator ?. of C# */ + return entry ? entry->obj : NULL; +} + +/*****************************************************************************/ + +static inline void +nm_dedup_multi_entry_set_dirty(const NMDedupMultiEntry *entry, gboolean dirty) +{ + /* NMDedupMultiEntry is always exposed as a const object, because it is not + * supposed to be modified outside NMDedupMultiIndex API. Except the "dirty" + * flag. In C++ speak, it is a mutable field. + * + * Add this inline function, to cast-away constness and set the dirty flag. */ + nm_assert(entry); + ((NMDedupMultiEntry *) entry)->dirty = dirty; +} + +/*****************************************************************************/ + +NMDedupMultiIndex *nm_dedup_multi_index_new(void); +NMDedupMultiIndex *nm_dedup_multi_index_ref(NMDedupMultiIndex *self); +NMDedupMultiIndex *nm_dedup_multi_index_unref(NMDedupMultiIndex *self); + +static inline void +_nm_auto_unref_dedup_multi_index(NMDedupMultiIndex **v) +{ + if (*v) + nm_dedup_multi_index_unref(*v); +} +#define nm_auto_unref_dedup_multi_index nm_auto(_nm_auto_unref_dedup_multi_index) + +#define NM_DEDUP_MULTI_ENTRY_MISSING ((const NMDedupMultiEntry *) GUINT_TO_POINTER(1)) +#define NM_DEDUP_MULTI_HEAD_ENTRY_MISSING ((const NMDedupMultiHeadEntry *) GUINT_TO_POINTER(1)) + +gboolean nm_dedup_multi_index_add_full(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj, + NMDedupMultiIdxMode mode, + const NMDedupMultiEntry * entry_order, + const NMDedupMultiEntry * entry_existing, + const NMDedupMultiHeadEntry * head_existing, + const NMDedupMultiEntry ** out_entry, + /* const NMDedupMultiObj ** */ gpointer out_obj_old); + +gboolean nm_dedup_multi_index_add(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj, + NMDedupMultiIdxMode mode, + const NMDedupMultiEntry ** out_entry, + /* const NMDedupMultiObj ** */ gpointer out_obj_old); + +const NMDedupMultiEntry * +nm_dedup_multi_index_lookup_obj(const NMDedupMultiIndex * self, + const NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj); + +const NMDedupMultiHeadEntry * +nm_dedup_multi_index_lookup_head(const NMDedupMultiIndex * self, + const NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj); + +guint nm_dedup_multi_index_remove_entry(NMDedupMultiIndex *self, gconstpointer entry); + +guint nm_dedup_multi_index_remove_obj(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj, + /*const NMDedupMultiObj ** */ gconstpointer *out_obj); + +guint nm_dedup_multi_index_remove_head(NMDedupMultiIndex * self, + NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj); + +guint nm_dedup_multi_index_remove_idx(NMDedupMultiIndex *self, NMDedupMultiIdxType *idx_type); + +void nm_dedup_multi_index_dirty_set_head(NMDedupMultiIndex * self, + const NMDedupMultiIdxType * idx_type, + /*const NMDedupMultiObj * */ gconstpointer obj); + +void nm_dedup_multi_index_dirty_set_idx(NMDedupMultiIndex * self, + const NMDedupMultiIdxType *idx_type); + +guint nm_dedup_multi_index_dirty_remove_idx(NMDedupMultiIndex * self, + NMDedupMultiIdxType *idx_type, + gboolean mark_survivors_dirty); + +/*****************************************************************************/ + +typedef struct _NMDedupMultiIter { + const CList * _head; + const CList * _next; + const NMDedupMultiEntry *current; +} NMDedupMultiIter; + +static inline void +nm_dedup_multi_iter_init(NMDedupMultiIter *iter, const NMDedupMultiHeadEntry *head) +{ + g_return_if_fail(iter); + + if (head && !c_list_is_empty(&head->lst_entries_head)) { + iter->_head = &head->lst_entries_head; + iter->_next = head->lst_entries_head.next; + } else { + iter->_head = NULL; + iter->_next = NULL; + } + iter->current = NULL; +} + +static inline gboolean +nm_dedup_multi_iter_next(NMDedupMultiIter *iter) +{ + g_return_val_if_fail(iter, FALSE); + + if (!iter->_next) + return FALSE; + + /* we always look ahead for the next. This way, the user + * may delete the current entry (but no other entries). */ + iter->current = c_list_entry(iter->_next, NMDedupMultiEntry, lst_entries); + if (iter->_next->next == iter->_head) + iter->_next = NULL; + else + iter->_next = iter->_next->next; + return TRUE; +} + +#define nm_dedup_multi_iter_for_each(iter, head_entry) \ + for (nm_dedup_multi_iter_init((iter), (head_entry)); nm_dedup_multi_iter_next((iter));) + +/*****************************************************************************/ + +typedef gboolean (*NMDedupMultiFcnSelectPredicate)(/* const NMDedupMultiObj * */ gconstpointer obj, + gpointer user_data); + +gconstpointer *nm_dedup_multi_objs_to_array_head(const NMDedupMultiHeadEntry * head_entry, + NMDedupMultiFcnSelectPredicate predicate, + gpointer user_data, + guint * out_len); +GPtrArray * nm_dedup_multi_objs_to_ptr_array_head(const NMDedupMultiHeadEntry * head_entry, + NMDedupMultiFcnSelectPredicate predicate, + gpointer user_data); + +static inline const NMDedupMultiEntry * +nm_dedup_multi_head_entry_get_idx(const NMDedupMultiHeadEntry *head_entry, int idx) +{ + CList *iter; + + if (head_entry) { + if (idx >= 0) { + c_list_for_each (iter, &head_entry->lst_entries_head) { + if (idx-- == 0) + return c_list_entry(iter, NMDedupMultiEntry, lst_entries); + } + } else { + for (iter = head_entry->lst_entries_head.prev; iter != &head_entry->lst_entries_head; + iter = iter->prev) { + if (++idx == 0) + return c_list_entry(iter, NMDedupMultiEntry, lst_entries); + } + } + } + return NULL; +} + +static inline void +nm_dedup_multi_head_entry_sort(const NMDedupMultiHeadEntry *head_entry, + CListSortCmp cmp, + gconstpointer user_data) +{ + if (head_entry) { + /* the head entry can be sorted directly without messing up the + * index to which it belongs. Of course, this does mess up any + * NMDedupMultiIter instances. */ + c_list_sort((CList *) &head_entry->lst_entries_head, cmp, user_data); + } +} + +gboolean nm_dedup_multi_entry_reorder(const NMDedupMultiEntry *entry, + const NMDedupMultiEntry *entry_order, + gboolean order_after); + +/*****************************************************************************/ + +#endif /* __NM_DEDUP_MULTI_H__ */ diff --git a/src/libnm-glib-aux/nm-default-glib-i18n-lib.h b/src/libnm-glib-aux/nm-default-glib-i18n-lib.h new file mode 100644 index 0000000..4b04da9 --- /dev/null +++ b/src/libnm-glib-aux/nm-default-glib-i18n-lib.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEFAULT_GLIB_I18N_LIB_H__ +#define __NM_DEFAULT_GLIB_I18N_LIB_H__ + +/*****************************************************************************/ + +#define _NETWORKMANAGER_COMPILATION_GLIB_I18N_LIB + +#include "libnm-glib-aux/nm-default-glib.h" + +#undef NETWORKMANAGER_COMPILATION +#define NETWORKMANAGER_COMPILATION \ + (NM_NETWORKMANAGER_COMPILATION_GLIB | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB) + +/*****************************************************************************/ + +#endif /* __NM_DEFAULT_GLIB_I18N_LIB_H__ */ diff --git a/src/libnm-glib-aux/nm-default-glib-i18n-prog.h b/src/libnm-glib-aux/nm-default-glib-i18n-prog.h new file mode 100644 index 0000000..ebd31f9 --- /dev/null +++ b/src/libnm-glib-aux/nm-default-glib-i18n-prog.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEFAULT_GLIB_I18N_PROG_H__ +#define __NM_DEFAULT_GLIB_I18N_PROG_H__ + +/*****************************************************************************/ + +#define _NETWORKMANAGER_COMPILATION_GLIB_I18N_PROG + +#include "libnm-glib-aux/nm-default-glib.h" + +#undef NETWORKMANAGER_COMPILATION +#define NETWORKMANAGER_COMPILATION \ + (NM_NETWORKMANAGER_COMPILATION_GLIB | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG) + +/*****************************************************************************/ + +#endif /* __NM_DEFAULT_GLIB_I18N_PROG_H__ */ diff --git a/src/libnm-glib-aux/nm-default-glib.h b/src/libnm-glib-aux/nm-default-glib.h new file mode 100644 index 0000000..e5ccd47 --- /dev/null +++ b/src/libnm-glib-aux/nm-default-glib.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEFAULT_GLIB_H__ +#define __NM_DEFAULT_GLIB_H__ + +/*****************************************************************************/ + +#include "libnm-std-aux/nm-default-std.h" + +#undef NETWORKMANAGER_COMPILATION +#define NETWORKMANAGER_COMPILATION NM_NETWORKMANAGER_COMPILATION_WITH_GLIB + +/*****************************************************************************/ + +#include + +#if defined(_NETWORKMANAGER_COMPILATION_GLIB_I18N_PROG) + #if defined(_NETWORKMANAGER_COMPILATION_GLIB_I18N_LIB) + #error Cannot define _NETWORKMANAGER_COMPILATION_GLIB_I18N_LIB and _NETWORKMANAGER_COMPILATION_GLIB_I18N_PROG together + #endif + #undef _NETWORKMANAGER_COMPILATION_GLIB_I18N_PROG + #include +#elif defined(_NETWORKMANAGER_COMPILATION_GLIB_I18N_LIB) + #undef _NETWORKMANAGER_COMPILATION_GLIB_I18N_LIB + #include +#endif + +/*****************************************************************************/ + +#if NM_MORE_ASSERTS == 0 + #ifndef G_DISABLE_CAST_CHECKS + /* Unless compiling with G_DISABLE_CAST_CHECKS, glib performs type checking + * during G_VARIANT_TYPE() via g_variant_type_checked_(). This is not necessary + * because commonly this cast is needed during something like + * + * g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); + * + * Note that in if the variant type would be invalid, the check still + * wouldn't make the buggy code magically work. Instead of passing a + * bogus type string (bad), it would pass %NULL to g_variant_builder_init() + * (also bad). + * + * Also, a function like g_variant_builder_init() already validates + * the input type via something like + * + * g_return_if_fail (g_variant_type_is_container (type)); + * + * So, by having G_VARIANT_TYPE() also validate the type, we validate + * twice, whereas the first validation is rather pointless because it + * doesn't prevent the function to be called with invalid arguments. + * + * Just patch G_VARIANT_TYPE() to perform no check. + */ + #undef G_VARIANT_TYPE + #define G_VARIANT_TYPE(type_string) ((const GVariantType *) (type_string)) + #endif +#endif + +/*****************************************************************************/ + +#include "nm-gassert-patch.h" + +#include "libnm-std-aux/nm-std-aux.h" +#include "libnm-std-aux/nm-std-utils.h" +#include "libnm-glib-aux/nm-macros-internal.h" +#include "libnm-glib-aux/nm-shared-utils.h" +#include "libnm-glib-aux/nm-errno.h" +#include "libnm-glib-aux/nm-hash-utils.h" + +/*****************************************************************************/ + +#endif /* __NM_DEFAULT_GLIB_H__ */ diff --git a/src/libnm-glib-aux/nm-enum-utils.c b/src/libnm-glib-aux/nm-enum-utils.c new file mode 100644 index 0000000..f97cdfc --- /dev/null +++ b/src/libnm-glib-aux/nm-enum-utils.c @@ -0,0 +1,368 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-enum-utils.h" +#include "nm-str-buf.h" + +/*****************************************************************************/ + +#define IS_FLAGS_SEPARATOR(ch) (NM_IN_SET((ch), ' ', '\t', ',', '\n', '\r')) + +static void +_ASSERT_enum_values_info(GType type, const NMUtilsEnumValueInfo *value_infos) +{ +#if NM_MORE_ASSERTS > 5 + nm_auto_unref_gtypeclass GTypeClass *klass = NULL; + gs_unref_hashtable GHashTable *ht = NULL; + + klass = g_type_class_ref(type); + + g_assert(G_IS_ENUM_CLASS(klass) || G_IS_FLAGS_CLASS(klass)); + + if (!value_infos) + return; + + ht = g_hash_table_new(g_str_hash, g_str_equal); + + for (; value_infos->nick; value_infos++) { + g_assert(value_infos->nick[0]); + + /* duplicate nicks make no sense!! */ + g_assert(!g_hash_table_contains(ht, value_infos->nick)); + g_hash_table_add(ht, (gpointer) value_infos->nick); + + if (G_IS_ENUM_CLASS(klass)) { + GEnumValue *enum_value; + + enum_value = g_enum_get_value_by_nick(G_ENUM_CLASS(klass), value_infos->nick); + if (enum_value) { + /* we do allow specifying the same name via @value_infos and @type. + * That might make sense, if @type comes from a library where older versions + * of the library don't yet support the value. In this case, the caller can + * provide the nick via @value_infos, to support the older library version. + * And then, when actually running against a newer library version where + * @type knows the nick, we have this situation. + * + * Another reason for specifying a nick both in @value_infos and @type, + * is to specify an alias which is not used with highest preference. For + * example, if you add an alias "disabled" for "none" (both numerically + * equal), then the first alias in @value_infos will be preferred over + * the name from @type. So, to still use "none" as preferred name, you may + * explicitly specify the "none" alias in @value_infos before "disabled". + * + * However, what never is allowed, is to use a name (nick) to re-number + * the value. That is, if both @value_infos and @type contain a particular + * nick, their numeric values must agree as well. + * Allowing this, would be very confusing, because the name would have a different + * value from the regular GLib GEnum API. + */ + g_assert(enum_value->value == value_infos->value); + } + } else { + GFlagsValue *flags_value; + + flags_value = g_flags_get_value_by_nick(G_FLAGS_CLASS(klass), value_infos->nick); + if (flags_value) { + /* see ENUM case above. */ + g_assert(flags_value->value == (guint) value_infos->value); + } + } + } +#endif +} + +static gboolean +_is_hex_string(const char *str, gboolean allow_sign) +{ + if (allow_sign && str[0] == '-') + str++; + return str[0] == '0' && str[1] == 'x' && str[2] + && NM_STRCHAR_ALL(&str[2], ch, g_ascii_isxdigit(ch)); +} + +static gboolean +_is_dec_string(const char *str, gboolean allow_sign) +{ + if (allow_sign && str[0] == '-') + str++; + return str[0] && NM_STRCHAR_ALL(&str[0], ch, g_ascii_isdigit(ch)); +} + +static gboolean +_enum_is_valid_enum_nick(const char *str) +{ + return str[0] && !NM_STRCHAR_ANY(str, ch, g_ascii_isspace(ch)) && !_is_dec_string(str, TRUE) + && !_is_hex_string(str, TRUE); +} + +static gboolean +_enum_is_valid_flags_nick(const char *str) +{ + return str[0] && !NM_STRCHAR_ANY(str, ch, IS_FLAGS_SEPARATOR(ch)) && !_is_dec_string(str, FALSE) + && !_is_hex_string(str, FALSE); +} + +char * +_nm_utils_enum_to_str_full(GType type, + int value, + const char * flags_separator, + const NMUtilsEnumValueInfo *value_infos) +{ + nm_auto_unref_gtypeclass GTypeClass *klass = NULL; + + _ASSERT_enum_values_info(type, value_infos); + + if (flags_separator + && (!flags_separator[0] || NM_STRCHAR_ANY(flags_separator, ch, !IS_FLAGS_SEPARATOR(ch)))) + g_return_val_if_reached(NULL); + + klass = g_type_class_ref(type); + + if (G_IS_ENUM_CLASS(klass)) { + GEnumValue *enum_value; + + for (; value_infos && value_infos->nick; value_infos++) { + if (value_infos->value == value) + return g_strdup(value_infos->nick); + } + + enum_value = g_enum_get_value(G_ENUM_CLASS(klass), value); + if (!enum_value || !_enum_is_valid_enum_nick(enum_value->value_nick)) + return g_strdup_printf("%d", value); + else + return g_strdup(enum_value->value_nick); + } else if (G_IS_FLAGS_CLASS(klass)) { + unsigned uvalue = (unsigned) value; + GFlagsValue *flags_value; + NMStrBuf strbuf; + + flags_separator = flags_separator ?: " "; + + nm_str_buf_init(&strbuf, 16, FALSE); + + for (; value_infos && value_infos->nick; value_infos++) { + nm_assert(_enum_is_valid_flags_nick(value_infos->nick)); + + if (uvalue == 0) { + if (value_infos->value != 0) + continue; + } else { + if (!NM_FLAGS_ALL(uvalue, (unsigned) value_infos->value)) + continue; + } + + if (strbuf.len) + nm_str_buf_append(&strbuf, flags_separator); + nm_str_buf_append(&strbuf, value_infos->nick); + uvalue &= ~((unsigned) value_infos->value); + if (uvalue == 0) { + /* we printed all flags. Done. */ + goto flags_done; + } + } + + do { + flags_value = g_flags_get_first_value(G_FLAGS_CLASS(klass), uvalue); + if (strbuf.len) + nm_str_buf_append(&strbuf, flags_separator); + if (!flags_value || !_enum_is_valid_flags_nick(flags_value->value_nick)) { + if (uvalue) + nm_str_buf_append_printf(&strbuf, "0x%x", uvalue); + break; + } + nm_str_buf_append(&strbuf, flags_value->value_nick); + uvalue &= ~flags_value->value; + } while (uvalue); + +flags_done: + return nm_str_buf_finalize(&strbuf, NULL); + } + + g_return_val_if_reached(NULL); +} + +static const NMUtilsEnumValueInfo * +_find_value_info(const NMUtilsEnumValueInfo *value_infos, const char *needle) +{ + if (value_infos) { + for (; value_infos->nick; value_infos++) { + if (nm_streq(needle, value_infos->nick)) + return value_infos; + } + } + return NULL; +} + +gboolean +_nm_utils_enum_from_str_full(GType type, + const char * str, + int * out_value, + char ** err_token, + const NMUtilsEnumValueInfo *value_infos) +{ + nm_auto_unref_gtypeclass GTypeClass *klass = NULL; + gboolean ret = FALSE; + int value = 0; + gs_free char * str_clone = NULL; + char * s; + gint64 v64; + const NMUtilsEnumValueInfo * nick; + + g_return_val_if_fail(str, FALSE); + + _ASSERT_enum_values_info(type, value_infos); + + s = nm_strdup_maybe_a(300, nm_str_skip_leading_spaces(str), &str_clone); + g_strchomp(s); + + klass = g_type_class_ref(type); + + if (G_IS_ENUM_CLASS(klass)) { + GEnumValue *enum_value; + + G_STATIC_ASSERT(G_MAXINT < G_MAXINT64); + G_STATIC_ASSERT(G_MININT > G_MININT64); + + if (s[0]) { + if (_is_hex_string(s, TRUE)) { + if (s[0] == '-') { + v64 = _nm_utils_ascii_str_to_int64(&s[3], + 16, + -((gint64) G_MAXINT), + -((gint64) G_MININT), + G_MAXINT64); + if (v64 != G_MAXINT64) { + value = (int) (-v64); + ret = TRUE; + } + } else { + v64 = _nm_utils_ascii_str_to_int64(&s[2], 16, G_MININT, G_MAXINT, G_MAXINT64); + if (v64 != G_MAXINT64) { + value = (int) v64; + ret = TRUE; + } + } + } else if (_is_dec_string(s, TRUE)) { + v64 = _nm_utils_ascii_str_to_int64(s, 10, G_MININT, G_MAXINT, G_MAXINT64); + if (v64 != G_MAXINT64) { + value = (int) v64; + ret = TRUE; + } + } else if ((nick = _find_value_info(value_infos, s))) { + value = nick->value; + ret = TRUE; + } else if ((enum_value = g_enum_get_value_by_nick(G_ENUM_CLASS(klass), s))) { + value = enum_value->value; + ret = TRUE; + } + } + } else if (G_IS_FLAGS_CLASS(klass)) { + GFlagsValue *flags_value; + unsigned uvalue = 0; + + ret = TRUE; + while (s[0]) { + char *s_end; + + for (s_end = s; s_end[0]; s_end++) { + if (IS_FLAGS_SEPARATOR(s_end[0])) { + s_end[0] = '\0'; + s_end++; + break; + } + } + + if (s[0]) { + if (_is_hex_string(s, FALSE)) { + v64 = _nm_utils_ascii_str_to_int64(&s[2], 16, 0, G_MAXUINT, -1); + if (v64 == -1) { + ret = FALSE; + break; + } + uvalue |= (unsigned) v64; + } else if (_is_dec_string(s, FALSE)) { + v64 = _nm_utils_ascii_str_to_int64(s, 10, 0, G_MAXUINT, -1); + if (v64 == -1) { + ret = FALSE; + break; + } + uvalue |= (unsigned) v64; + } else if ((nick = _find_value_info(value_infos, s))) + uvalue |= (unsigned) nick->value; + else if ((flags_value = g_flags_get_value_by_nick(G_FLAGS_CLASS(klass), s))) + uvalue |= flags_value->value; + else { + ret = FALSE; + break; + } + } + + s = s_end; + } + + value = (int) uvalue; + } else + g_return_val_if_reached(FALSE); + + NM_SET_OUT(err_token, !ret && s[0] ? g_strdup(s) : NULL); + NM_SET_OUT(out_value, ret ? value : 0); + return ret; +} + +const char ** +_nm_utils_enum_get_values(GType type, int from, int to) +{ + GTypeClass *klass; + GPtrArray * array; + int i; + char sbuf[64]; + + klass = g_type_class_ref(type); + array = g_ptr_array_new(); + + if (G_IS_ENUM_CLASS(klass)) { + GEnumClass *enum_class = G_ENUM_CLASS(klass); + GEnumValue *enum_value; + + for (i = 0; i < enum_class->n_values; i++) { + enum_value = &enum_class->values[i]; + if (enum_value->value >= from && enum_value->value <= to) { + if (_enum_is_valid_enum_nick(enum_value->value_nick)) + g_ptr_array_add(array, (gpointer) enum_value->value_nick); + else + g_ptr_array_add( + array, + (gpointer) g_intern_string(nm_sprintf_buf(sbuf, "%d", enum_value->value))); + } + } + } else if (G_IS_FLAGS_CLASS(klass)) { + GFlagsClass *flags_class = G_FLAGS_CLASS(klass); + GFlagsValue *flags_value; + + for (i = 0; i < flags_class->n_values; i++) { + flags_value = &flags_class->values[i]; + if (flags_value->value >= (guint) from && flags_value->value <= (guint) to) { + if (_enum_is_valid_flags_nick(flags_value->value_nick)) + g_ptr_array_add(array, (gpointer) flags_value->value_nick); + else + g_ptr_array_add( + array, + (gpointer) g_intern_string( + nm_sprintf_buf(sbuf, "0x%x", (unsigned) flags_value->value))); + } + } + } else { + g_type_class_unref(klass); + g_ptr_array_free(array, TRUE); + g_return_val_if_reached(NULL); + } + + g_type_class_unref(klass); + g_ptr_array_add(array, NULL); + + return (const char **) g_ptr_array_free(array, FALSE); +} diff --git a/src/libnm-glib-aux/nm-enum-utils.h b/src/libnm-glib-aux/nm-enum-utils.h new file mode 100644 index 0000000..89be54e --- /dev/null +++ b/src/libnm-glib-aux/nm-enum-utils.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_ENUM_UTILS_H__ +#define __NM_ENUM_UTILS_H__ + +/*****************************************************************************/ + +typedef struct _NMUtilsEnumValueInfo { + /* currently, this is only used for _nm_utils_enum_from_str_full() to + * declare additional aliases for values. */ + const char *nick; + int value; +} NMUtilsEnumValueInfo; + +char * _nm_utils_enum_to_str_full(GType type, + int value, + const char * sep, + const NMUtilsEnumValueInfo *value_infos); +gboolean _nm_utils_enum_from_str_full(GType type, + const char * str, + int * out_value, + char ** err_token, + const NMUtilsEnumValueInfo *value_infos); + +const char **_nm_utils_enum_get_values(GType type, int from, int to); + +/*****************************************************************************/ + +#endif /* __NM_ENUM_UTILS_H__ */ diff --git a/src/libnm-glib-aux/nm-errno.c b/src/libnm-glib-aux/nm-errno.c new file mode 100644 index 0000000..283173e --- /dev/null +++ b/src/libnm-glib-aux/nm-errno.c @@ -0,0 +1,181 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-errno.h" + +#include + +/*****************************************************************************/ + +static NM_UTILS_LOOKUP_STR_DEFINE( + _geterror, +#if 0 + enum _NMErrno, +#else + int, +#endif + NM_UTILS_LOOKUP_DEFAULT(NULL), + + NM_UTILS_LOOKUP_STR_ITEM(NME_ERRNO_SUCCESS, "NME_ERRNO_SUCCESS"), + NM_UTILS_LOOKUP_STR_ITEM(NME_ERRNO_OUT_OF_RANGE, "NME_ERRNO_OUT_OF_RANGE"), + + NM_UTILS_LOOKUP_STR_ITEM(NME_UNSPEC, "NME_UNSPEC"), + NM_UTILS_LOOKUP_STR_ITEM(NME_BUG, "NME_BUG"), + NM_UTILS_LOOKUP_STR_ITEM(NME_NATIVE_ERRNO, "NME_NATIVE_ERRNO"), + + NM_UTILS_LOOKUP_STR_ITEM(NME_NL_ATTRSIZE, "NME_NL_ATTRSIZE"), + NM_UTILS_LOOKUP_STR_ITEM(NME_NL_BAD_SOCK, "NME_NL_BAD_SOCK"), + NM_UTILS_LOOKUP_STR_ITEM(NME_NL_DUMP_INTR, "NME_NL_DUMP_INTR"), + NM_UTILS_LOOKUP_STR_ITEM(NME_NL_MSG_OVERFLOW, "NME_NL_MSG_OVERFLOW"), + NM_UTILS_LOOKUP_STR_ITEM(NME_NL_MSG_TOOSHORT, "NME_NL_MSG_TOOSHORT"), + NM_UTILS_LOOKUP_STR_ITEM(NME_NL_MSG_TRUNC, "NME_NL_MSG_TRUNC"), + NM_UTILS_LOOKUP_STR_ITEM(NME_NL_SEQ_MISMATCH, "NME_NL_SEQ_MISMATCH"), + NM_UTILS_LOOKUP_STR_ITEM(NME_NL_NOADDR, "NME_NL_NOADDR"), + + NM_UTILS_LOOKUP_STR_ITEM(NME_PL_NOT_FOUND, "not-found"), + NM_UTILS_LOOKUP_STR_ITEM(NME_PL_EXISTS, "exists"), + NM_UTILS_LOOKUP_STR_ITEM(NME_PL_WRONG_TYPE, "wrong-type"), + NM_UTILS_LOOKUP_STR_ITEM(NME_PL_NOT_SLAVE, "not-slave"), + NM_UTILS_LOOKUP_STR_ITEM(NME_PL_NO_FIRMWARE, "no-firmware"), + NM_UTILS_LOOKUP_STR_ITEM(NME_PL_OPNOTSUPP, "not-supported"), + NM_UTILS_LOOKUP_STR_ITEM(NME_PL_NETLINK, "netlink"), + NM_UTILS_LOOKUP_STR_ITEM(NME_PL_CANT_SET_MTU, "cant-set-mtu"), + + NM_UTILS_LOOKUP_ITEM_IGNORE(_NM_ERRNO_MININT), + NM_UTILS_LOOKUP_ITEM_IGNORE(_NM_ERRNO_RESERVED_LAST_PLUS_1), ); + +/** + * nm_strerror(): + * @nmerr: the NetworkManager specific errno to be converted + * to string. + * + * NetworkManager specific error numbers reserve a range in "errno.h" with + * our own defines. For numbers that don't fall into this range, the numbers + * are identical to the common error numbers. + * + * Identical to strerror(), g_strerror(), nm_strerror_native() for error numbers + * that are not in the reserved range of NetworkManager specific errors. + * + * Returns: (transfer none): the string representation of the error number. + */ +const char * +nm_strerror(int nmerr) +{ + const char *s; + + nmerr = nm_errno(nmerr); + + if (nmerr >= _NM_ERRNO_RESERVED_FIRST) { + s = _geterror(nmerr); + if (s) + return s; + } + return nm_strerror_native(nmerr); +} + +/*****************************************************************************/ + +/** + * nm_strerror_native_r: + * @errsv: the errno to convert to string. + * @buf: the output buffer where to write the string to. + * @buf_size: the length of buffer. + * + * This is like strerror_r(), with one difference: depending on the + * locale, the returned string is guaranteed to be valid UTF-8. + * Also, there is some confusion as to whether to use glibc's + * strerror_r() or the POXIX/XSI variant. This is abstracted + * by the function. + * + * Note that the returned buffer may also be a statically allocated + * buffer, and not the input buffer @buf. Consequently, the returned + * string may be longer than @buf_size. + * + * Returns: (transfer none): a NUL terminated error message. This is either a static + * string (that is never freed), or the provided @buf argument. + */ +const char * +nm_strerror_native_r(int errsv, char *buf, gsize buf_size) +{ + char *buf2; + + nm_assert(buf); + nm_assert(buf_size > 0); + +#if (!defined(__GLIBC__) && !defined(__UCLIBC__)) || ((_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE) + /* XSI-compliant */ + { + int errno_saved = errno; + + if (strerror_r(errsv, buf, buf_size) != 0) { + g_snprintf(buf, buf_size, "Unspecified errno %d", errsv); + errno = errno_saved; + } + buf2 = buf; + } +#else + /* GNU-specific */ + buf2 = strerror_r(errsv, buf, buf_size); +#endif + + /* like g_strerror(), ensure that the error message is UTF-8. */ + if (!g_get_charset(NULL) && !g_utf8_validate(buf2, -1, NULL)) { + gs_free char *msg = NULL; + + msg = g_locale_to_utf8(buf2, -1, NULL, NULL, NULL); + if (msg) { + g_strlcpy(buf, msg, buf_size); + buf2 = buf; + } + } + + return buf2; +} + +/** + * nm_strerror_native: + * @errsv: the errno integer from + * + * Like strerror(), but strerror() is not thread-safe and not guaranteed + * to be UTF-8. + * + * g_strerror() is a thread-safe variant of strerror(), however it caches + * all returned strings in a dictionary. That means, using this on untrusted + * error numbers can result in this cache to grow without limits. + * + * Instead, return a tread-local buffer. This way, it's thread-safe. + * + * There is a downside to this: subsequent calls of nm_strerror_native() + * overwrite the error message. + * + * Returns: (transfer none): the text representation of the error number. + */ +const char * +nm_strerror_native(int errsv) +{ + static _nm_thread_local char *buf_static = NULL; + char * buf; + + buf = buf_static; + if (G_UNLIKELY(!buf)) { + int errno_saved = errno; + pthread_key_t key; + + buf = g_malloc(NM_STRERROR_BUFSIZE); + buf_static = buf; + + if (pthread_key_create(&key, g_free) != 0 || pthread_setspecific(key, buf) != 0) { + /* Failure. We will leak the buffer when the thread exits. + * + * Nothing we can do about it really. For Debug builds we fail with an assertion. */ + nm_assert_not_reached(); + } + errno = errno_saved; + } + + return nm_strerror_native_r(errsv, buf, NM_STRERROR_BUFSIZE); +} diff --git a/src/libnm-glib-aux/nm-errno.h b/src/libnm-glib-aux/nm-errno.h new file mode 100644 index 0000000..62c8379 --- /dev/null +++ b/src/libnm-glib-aux/nm-errno.h @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_ERRNO_H__ +#define __NM_ERRNO_H__ + +#include + +/*****************************************************************************/ + +enum _NMErrno { + _NM_ERRNO_MININT = G_MININT, + _NM_ERRNO_MAXINT = G_MAXINT, + _NM_ERRNO_RESERVED_FIRST = 100000, + + /* when we cannot represent a number as positive number, we resort to this + * number. Basically, the values G_MININT, -NME_ERRNO_SUCCESS, NME_ERRNO_SUCCESS + * and G_MAXINT all map to the same value. */ + NME_ERRNO_OUT_OF_RANGE = G_MAXINT, + + /* Indicate that the original errno was zero. Zero denotes *no error*, but we know something + * went wrong and we want to report some error. This is a placeholder to mean, something + * was wrong, but errno was zero. */ + NME_ERRNO_SUCCESS = G_MAXINT - 1, + + /* an unspecified error. */ + NME_UNSPEC = _NM_ERRNO_RESERVED_FIRST, + + /* A bug, for example when an assertion failed. + * Should never happen. */ + NME_BUG, + + /* a native error number (from ) cannot be mapped as + * an nm-error, because it is in the range [_NM_ERRNO_RESERVED_FIRST, + * _NM_ERRNO_RESERVED_LAST]. */ + NME_NATIVE_ERRNO, + + /* netlink errors. */ + NME_NL_SEQ_MISMATCH, + NME_NL_MSG_TRUNC, + NME_NL_MSG_TOOSHORT, + NME_NL_DUMP_INTR, + NME_NL_ATTRSIZE, + NME_NL_BAD_SOCK, + NME_NL_NOADDR, + NME_NL_MSG_OVERFLOW, + + /* platform errors. */ + NME_PL_NOT_FOUND, + NME_PL_EXISTS, + NME_PL_WRONG_TYPE, + NME_PL_NOT_SLAVE, + NME_PL_NO_FIRMWARE, + NME_PL_OPNOTSUPP, + NME_PL_NETLINK, + NME_PL_CANT_SET_MTU, + + _NM_ERRNO_RESERVED_LAST_PLUS_1, + _NM_ERRNO_RESERVED_LAST = _NM_ERRNO_RESERVED_LAST_PLUS_1 - 1, +}; + +/*****************************************************************************/ + +/* When we receive an errno from a system function, we can safely assume + * that the error number is not negative. We rely on that, and possibly just + * "return -errsv;" to signal an error. We also rely on that, because libc + * is our trusted base: meaning, if it cannot even succeed at setting errno + * according to specification, all bets are off. + * + * This macro returns the input argument, and asserts that the error variable + * is positive. + * + * In a sense, the macro is related to nm_errno_native() function, but the difference + * is that this macro asserts that @errsv is positive, while nm_errno_native() coerces + * negative values to be non-negative. */ +#define NM_ERRNO_NATIVE(errsv) \ + ({ \ + const int _errsv_x = (errsv); \ + \ + nm_assert(_errsv_x > 0); \ + _errsv_x; \ + }) + +/* Normalize native errno. + * + * Our API may return native error codes () as negative values. This function + * takes such an errno, and normalizes it to their positive value. + * + * The special values G_MININT and zero are coerced to NME_ERRNO_OUT_OF_RANGE and NME_ERRNO_SUCCESS + * respectively. + * Other values are coerced to their inverse. + * Other positive values are returned unchanged. + * + * Basically, this normalizes errsv to be positive (taking care of two pathological cases). + */ +static inline int +nm_errno_native(int errsv) +{ + switch (errsv) { + case 0: + return NME_ERRNO_SUCCESS; + case G_MININT: + return NME_ERRNO_OUT_OF_RANGE; + default: + return errsv >= 0 ? errsv : -errsv; + } +} + +/* Normalizes an nm-error to be positive. + * + * Various API returns negative error codes, and this function converts the negative + * value to its positive. + * + * Note that @nmerr is on the domain of NetworkManager specific error numbers, + * which is not the same as the native error numbers (errsv from ). But + * as far as normalizing goes, nm_errno() does exactly the same remapping as + * nm_errno_native(). */ +static inline int +nm_errno(int nmerr) +{ + return nm_errno_native(nmerr); +} + +/* this maps a native errno to a (always non-negative) nm-error number. + * + * Note that nm-error numbers are embedded into the range of regular + * errno. The only difference is, that nm-error numbers reserve a + * range (_NM_ERRNO_RESERVED_FIRST, _NM_ERRNO_RESERVED_LAST) for their + * own purpose. + * + * That means, converting an errno to nm-error number means in + * most cases just returning itself. + * Only pathological cases need special handling: + * + * - 0 is mapped to NME_ERRNO_SUCCESS; + * - G_MININT is mapped to NME_ERRNO_OUT_OF_RANGE; + * - values in the range of (+/-) [_NM_ERRNO_RESERVED_FIRST, _NM_ERRNO_RESERVED_LAST] + * are mapped to NME_NATIVE_ERRNO + * - all other values are their (positive) absolute value. + */ +static inline int +nm_errno_from_native(int errsv) +{ + switch (errsv) { + case 0: + return NME_ERRNO_SUCCESS; + case G_MININT: + return NME_ERRNO_OUT_OF_RANGE; + default: + if (errsv < 0) + errsv = -errsv; + return G_UNLIKELY(errsv >= _NM_ERRNO_RESERVED_FIRST && errsv <= _NM_ERRNO_RESERVED_LAST) + ? NME_NATIVE_ERRNO + : errsv; + } +} + +const char *nm_strerror(int nmerr); + +/*****************************************************************************/ + +#define NM_STRERROR_BUFSIZE 1024 + +const char *nm_strerror_native_r(int errsv, char *buf, gsize buf_size); +const char *nm_strerror_native(int errsv); + +/*****************************************************************************/ + +#endif /* __NM_ERRNO_H__ */ diff --git a/src/libnm-glib-aux/nm-gassert-patch.h b/src/libnm-glib-aux/nm-gassert-patch.h new file mode 100644 index 0000000..bac8697 --- /dev/null +++ b/src/libnm-glib-aux/nm-gassert-patch.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_GASSERT_PATCH_H__ +#define __NM_GASSERT_PATCH_H__ + +/*****************************************************************************/ + +#if NM_MORE_ASSERTS == 0 + +/* glib assertions (g_return_*(), g_assert*()) contain a textual representation + * of the checked statement. This part of the assertion blows up the size of the + * binary. Unless we compile a debug-build with NM_MORE_ASSERTS, drop these + * parts. Note that the failed assertion still prints the file and line where the + * assertion fails. That shall suffice. */ + +static inline void +_nm_g_return_if_fail_warning(const char *log_domain, const char *file, int line) +{ + char file_buf[256 + 15]; + + g_snprintf(file_buf, sizeof(file_buf), "((%s:%d))", file, line); + g_return_if_fail_warning(log_domain, file_buf, ""); +} + + #define g_return_if_fail_warning(log_domain, pretty_function, expression) \ + _nm_g_return_if_fail_warning(log_domain, __FILE__, __LINE__) + + #define g_assertion_message_expr(domain, file, line, func, expr) \ + g_assertion_message_expr(domain, file, line, "", (expr) ? "" : NULL) + + #undef g_return_val_if_reached + #define g_return_val_if_reached(val) \ + G_STMT_START \ + { \ + g_log(G_LOG_DOMAIN, \ + G_LOG_LEVEL_CRITICAL, \ + "file %s: line %d (%s): should not be reached", \ + __FILE__, \ + __LINE__, \ + ""); \ + return (val); \ + } \ + G_STMT_END + + #undef g_return_if_reached + #define g_return_if_reached() \ + G_STMT_START \ + { \ + g_log(G_LOG_DOMAIN, \ + G_LOG_LEVEL_CRITICAL, \ + "file %s: line %d (%s): should not be reached", \ + __FILE__, \ + __LINE__, \ + ""); \ + return; \ + } \ + G_STMT_END +#endif + +/*****************************************************************************/ + +#if NM_MORE_ASSERTS == 0 + #define NM_ASSERT_G_RETURN_EXPR(expr) "" + #define NM_ASSERT_NO_MSG 1 + +#else + #define NM_ASSERT_G_RETURN_EXPR(expr) "" expr "" + #define NM_ASSERT_NO_MSG 0 +#endif + +/*****************************************************************************/ + +#endif /* __NM_GASSERT_PATCH_H__ */ diff --git a/src/libnm-glib-aux/nm-glib.h b/src/libnm-glib-aux/nm-glib.h new file mode 100644 index 0000000..befb8d9 --- /dev/null +++ b/src/libnm-glib-aux/nm-glib.h @@ -0,0 +1,707 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2008 - 2018 Red Hat, Inc. + */ + +#ifndef __NM_GLIB_H__ +#define __NM_GLIB_H__ + +/*****************************************************************************/ + +#ifndef __NM_MACROS_INTERNAL_H__ + #error "nm-glib.h requires nm-macros-internal.h. Do not include this directly" +#endif + +/*****************************************************************************/ + +#ifdef __clang__ + + #undef G_GNUC_BEGIN_IGNORE_DEPRECATIONS + #undef G_GNUC_END_IGNORE_DEPRECATIONS + + #define G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") + + #define G_GNUC_END_IGNORE_DEPRECATIONS _Pragma("clang diagnostic pop") + +#endif + +/*****************************************************************************/ + +static inline void +__g_type_ensure(GType type) +{ +#if !GLIB_CHECK_VERSION(2, 34, 0) + if (G_UNLIKELY(type == (GType) -1)) + g_error("can't happen"); +#else + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + g_type_ensure(type); + G_GNUC_END_IGNORE_DEPRECATIONS; +#endif +} +#define g_type_ensure __g_type_ensure + +/*****************************************************************************/ + +#if !GLIB_CHECK_VERSION(2, 34, 0) + + #define g_clear_pointer(pp, destroy) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT(sizeof *(pp) == sizeof(gpointer)); \ + /* Only one access, please */ \ + gpointer *_pp = (gpointer *) (pp); \ + gpointer _p; \ + /* This assignment is needed to avoid a gcc warning */ \ + GDestroyNotify _destroy = (GDestroyNotify)(destroy); \ + \ + _p = *_pp; \ + if (_p) { \ + *_pp = NULL; \ + _destroy(_p); \ + } \ + } \ + G_STMT_END + +#endif + +/*****************************************************************************/ + +#if !GLIB_CHECK_VERSION(2, 34, 0) + + /* These are used to clean up the output of test programs; we can just let + * them no-op in older glib. + */ + #define g_test_expect_message(log_domain, log_level, pattern) + #define g_test_assert_expected_messages() + +#else + + /* We build with -DGLIB_MAX_ALLOWED_VERSION set to 2.32 to make sure we don't + * accidentally use new API that we shouldn't. But we don't want warnings for + * the APIs that we emulate above. + */ + + #define g_test_expect_message(domain, level, format...) \ + G_STMT_START \ + { \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + g_test_expect_message(domain, level, format); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + } \ + G_STMT_END + + #define g_test_assert_expected_messages_internal(domain, file, line, func) \ + G_STMT_START \ + { \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + g_test_assert_expected_messages_internal(domain, file, line, func); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + } \ + G_STMT_END + +#endif + +/*****************************************************************************/ + +#if GLIB_CHECK_VERSION(2, 35, 0) + /* For glib >= 2.36, g_type_init() is deprecated. + * But since 2.35.1 (7c42ab23b55c43ab96d0ac2124b550bf1f49c1ec) this function + * does nothing. Replace the call with empty statement. */ + #define nm_g_type_init() \ + G_STMT_START \ + { \ + (void) 0; \ + } \ + G_STMT_END +#else + #define nm_g_type_init() \ + G_STMT_START \ + { \ + g_type_init(); \ + } \ + G_STMT_END +#endif + +/*****************************************************************************/ + +/* g_test_initialized() is only available since glib 2.36. */ +#if !GLIB_CHECK_VERSION(2, 36, 0) + #define g_test_initialized() (g_test_config_vars->test_initialized) +#endif + +/*****************************************************************************/ + +/* g_assert_cmpmem() is only available since glib 2.46. */ +#if !GLIB_CHECK_VERSION(2, 45, 7) + #define g_assert_cmpmem(m1, l1, m2, l2) \ + G_STMT_START \ + { \ + gconstpointer __m1 = m1, __m2 = m2; \ + int __l1 = l1, __l2 = l2; \ + if (__l1 != __l2) \ + g_assertion_message_cmpnum(G_LOG_DOMAIN, \ + __FILE__, \ + __LINE__, \ + G_STRFUNC, \ + #l1 " (len(" #m1 ")) == " #l2 " (len(" #m2 "))", \ + __l1, \ + "==", \ + __l2, \ + 'i'); \ + else if (memcmp(__m1, __m2, __l1) != 0) \ + g_assertion_message(G_LOG_DOMAIN, \ + __FILE__, \ + __LINE__, \ + G_STRFUNC, \ + "assertion failed (" #m1 " == " #m2 ")"); \ + } \ + G_STMT_END +#endif + +/*****************************************************************************/ + +/* Rumtime check for glib version. First do a compile time check which + * (if satisfied) shortcuts the runtime check. */ +static inline gboolean +nm_glib_check_version(guint major, guint minor, guint micro) +{ + return GLIB_CHECK_VERSION(major, minor, micro) + || ((glib_major_version > major) + || (glib_major_version == major && glib_minor_version > minor) + || (glib_major_version == major && glib_minor_version == minor + && glib_micro_version < micro)); +} + +/*****************************************************************************/ + +/* g_test_skip() is only available since glib 2.38. Add a compatibility wrapper. */ +static inline void +__nmtst_g_test_skip(const char *msg) +{ +#if GLIB_CHECK_VERSION(2, 38, 0) + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_test_skip(msg); + G_GNUC_END_IGNORE_DEPRECATIONS +#else + g_debug("%s", msg); +#endif +} +#define g_test_skip __nmtst_g_test_skip + +/*****************************************************************************/ + +/* g_test_add_data_func_full() is only available since glib 2.34. Add a compatibility wrapper. */ +static inline void +__g_test_add_data_func_full(const char * testpath, + gpointer test_data, + GTestDataFunc test_func, + GDestroyNotify data_free_func) +{ +#if GLIB_CHECK_VERSION(2, 34, 0) + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_test_add_data_func_full(testpath, test_data, test_func, data_free_func); + G_GNUC_END_IGNORE_DEPRECATIONS +#else + g_return_if_fail(testpath != NULL); + g_return_if_fail(testpath[0] == '/'); + g_return_if_fail(test_func != NULL); + + g_test_add_vtable(testpath, + 0, + test_data, + NULL, + (GTestFixtureFunc) test_func, + (GTestFixtureFunc) data_free_func); +#endif +} +#define g_test_add_data_func_full __g_test_add_data_func_full + +/*****************************************************************************/ + +static inline gboolean +nm_g_hash_table_replace(GHashTable *hash, gpointer key, gpointer value) +{ + /* glib 2.40 added a return value indicating whether the key already existed + * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ +#if GLIB_CHECK_VERSION(2, 40, 0) + return g_hash_table_replace(hash, key, value); +#else + gboolean contained = g_hash_table_contains(hash, key); + + g_hash_table_replace(hash, key, value); + return !contained; +#endif +} + +static inline gboolean +nm_g_hash_table_insert(GHashTable *hash, gpointer key, gpointer value) +{ + /* glib 2.40 added a return value indicating whether the key already existed + * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ +#if GLIB_CHECK_VERSION(2, 40, 0) + return g_hash_table_insert(hash, key, value); +#else + gboolean contained = g_hash_table_contains(hash, key); + + g_hash_table_insert(hash, key, value); + return !contained; +#endif +} + +static inline gboolean +nm_g_hash_table_add(GHashTable *hash, gpointer key) +{ + /* glib 2.40 added a return value indicating whether the key already existed + * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ +#if GLIB_CHECK_VERSION(2, 40, 0) + return g_hash_table_add(hash, key); +#else + gboolean contained = g_hash_table_contains(hash, key); + + g_hash_table_add(hash, key); + return !contained; +#endif +} + +/*****************************************************************************/ + +#if !GLIB_CHECK_VERSION(2, 40, 0) || defined(NM_GLIB_COMPAT_H_TEST) +static inline void +_nm_g_ptr_array_insert(GPtrArray *array, int index_, gpointer data) +{ + g_return_if_fail(array); + g_return_if_fail(index_ >= -1); + g_return_if_fail(index_ <= (int) array->len); + + g_ptr_array_add(array, data); + + if (index_ != -1 && index_ != (int) (array->len - 1)) { + memmove(&(array->pdata[index_ + 1]), + &(array->pdata[index_]), + (array->len - index_ - 1) * sizeof(gpointer)); + array->pdata[index_] = data; + } +} +#endif + +#if !GLIB_CHECK_VERSION(2, 40, 0) + #define g_ptr_array_insert(array, index, data) \ + G_STMT_START \ + { \ + _nm_g_ptr_array_insert(array, index, data); \ + } \ + G_STMT_END +#else + #define g_ptr_array_insert(array, index, data) \ + G_STMT_START \ + { \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + g_ptr_array_insert(array, index, data); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + } \ + G_STMT_END +#endif + +/*****************************************************************************/ + +#if !GLIB_CHECK_VERSION(2, 40, 0) +static inline gboolean +_g_key_file_save_to_file(GKeyFile *key_file, const char *filename, GError **error) +{ + char * contents; + gboolean success; + gsize length; + + g_return_val_if_fail(key_file != NULL, FALSE); + g_return_val_if_fail(filename != NULL, FALSE); + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + + contents = g_key_file_to_data(key_file, &length, NULL); + g_assert(contents != NULL); + + success = g_file_set_contents(filename, contents, length, error); + g_free(contents); + + return success; +} + #define g_key_file_save_to_file(key_file, filename, error) \ + _g_key_file_save_to_file(key_file, filename, error) +#else + #define g_key_file_save_to_file(key_file, filename, error) \ + ({ \ + gboolean _success; \ + \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + _success = g_key_file_save_to_file(key_file, filename, error); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + _success; \ + }) +#endif + +/*****************************************************************************/ + +#if GLIB_CHECK_VERSION(2, 36, 0) + #define g_credentials_get_unix_pid(creds, error) \ + ({ \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS(g_credentials_get_unix_pid)((creds), (error)); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + }) +#else + #define g_credentials_get_unix_pid(creds, error) \ + ({ \ + struct ucred *native_creds; \ + \ + native_creds = g_credentials_get_native((creds), G_CREDENTIALS_TYPE_LINUX_UCRED); \ + g_assert(native_creds); \ + native_creds->pid; \ + }) +#endif + +/*****************************************************************************/ + +#if !GLIB_CHECK_VERSION(2, 40, 0) || defined(NM_GLIB_COMPAT_H_TEST) +static inline gpointer * +_nm_g_hash_table_get_keys_as_array(GHashTable *hash_table, guint *length) +{ + GHashTableIter iter; + gpointer key, *ret; + guint i = 0; + + g_return_val_if_fail(hash_table, NULL); + + ret = g_new0(gpointer, g_hash_table_size(hash_table) + 1); + g_hash_table_iter_init(&iter, hash_table); + + while (g_hash_table_iter_next(&iter, &key, NULL)) + ret[i++] = key; + + ret[i] = NULL; + + if (length) + *length = i; + + return ret; +} +#endif +#if !GLIB_CHECK_VERSION(2, 40, 0) + #define g_hash_table_get_keys_as_array(hash_table, length) \ + ({ _nm_g_hash_table_get_keys_as_array(hash_table, length); }) +#else + #define g_hash_table_get_keys_as_array(hash_table, length) \ + ({ \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS(g_hash_table_get_keys_as_array) \ + ((hash_table), (length)); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + }) +#endif + +/*****************************************************************************/ + +#ifndef g_info + /* g_info was only added with 2.39.2 */ + #define g_info(...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__) +#endif + +/*****************************************************************************/ + +static inline gpointer +_nm_g_steal_pointer(gpointer pp) +{ + gpointer *ptr = (gpointer *) pp; + gpointer ref; + + ref = *ptr; + *ptr = NULL; + + return ref; +} + +#if !GLIB_CHECK_VERSION(2, 44, 0) +static inline gpointer +g_steal_pointer(gpointer pp) +{ + return _nm_g_steal_pointer(pp); +} +#endif + +#ifdef g_steal_pointer + #undef g_steal_pointer +#endif +#define g_steal_pointer(pp) ((typeof(*(pp))) _nm_g_steal_pointer(pp)) + +/*****************************************************************************/ + +static inline gboolean +_nm_g_strv_contains(const char *const *strv, const char *str) +{ +#if !GLIB_CHECK_VERSION(2, 44, 0) + g_return_val_if_fail(strv != NULL, FALSE); + g_return_val_if_fail(str != NULL, FALSE); + + for (; *strv != NULL; strv++) { + if (g_str_equal(str, *strv)) + return TRUE; + } + + return FALSE; +#else + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + return g_strv_contains(strv, str); + G_GNUC_END_IGNORE_DEPRECATIONS +#endif +} +#define g_strv_contains _nm_g_strv_contains + +/*****************************************************************************/ + +static inline GVariant * +_nm_g_variant_new_take_string(char *string) +{ +#if !GLIB_CHECK_VERSION(2, 36, 0) + GVariant *value; + + g_return_val_if_fail(string != NULL, NULL); + g_return_val_if_fail(g_utf8_validate(string, -1, NULL), NULL); + + value = g_variant_new_string(string); + g_free(string); + return value; +#elif !GLIB_CHECK_VERSION(2, 38, 0) + GVariant *value; + GBytes * bytes; + + g_return_val_if_fail(string != NULL, NULL); + g_return_val_if_fail(g_utf8_validate(string, -1, NULL), NULL); + + bytes = g_bytes_new_take(string, strlen(string) + 1); + value = g_variant_new_from_bytes(G_VARIANT_TYPE_STRING, bytes, TRUE); + g_bytes_unref(bytes); + + return value; +#else + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + return g_variant_new_take_string(string); + G_GNUC_END_IGNORE_DEPRECATIONS +#endif +} +#define g_variant_new_take_string _nm_g_variant_new_take_string + +/*****************************************************************************/ + +#if !GLIB_CHECK_VERSION(2, 38, 0) +_nm_printf(1, 2) static inline GVariant *_nm_g_variant_new_printf(const char *format_string, ...) +{ + char * string; + va_list ap; + + g_return_val_if_fail(format_string, NULL); + + va_start(ap, format_string); + string = g_strdup_vprintf(format_string, ap); + va_end(ap); + + return g_variant_new_take_string(string); +} + #define g_variant_new_printf(...) _nm_g_variant_new_printf(__VA_ARGS__) +#else + #define g_variant_new_printf(...) \ + ({ \ + GVariant *_v; \ + \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + _v = g_variant_new_printf(__VA_ARGS__); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + _v; \ + }) +#endif + +/*****************************************************************************/ + +/* Recent glib also casts the results to typeof(Obj), but only if + * + * ( defined(g_has_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_56 ) + * + * Since we build NetworkManager with older GLIB_VERSION_MAX_ALLOWED, it's + * not taking effect. + * + * Override this. */ +#undef g_object_ref +#undef g_object_ref_sink +#define g_object_ref(Obj) ((typeof(Obj)) g_object_ref(Obj)) +#define g_object_ref_sink(Obj) ((typeof(Obj)) g_object_ref_sink(Obj)) + +/*****************************************************************************/ + +#ifndef g_autofree + /* we still don't rely on recent glib to provide g_autofree. Hence, we continue + * to use our gs_* free macros that we took from libgsystem. + * + * To ease migration towards g_auto*, add a compat define for g_autofree. */ + #define g_autofree gs_free +#endif + +/*****************************************************************************/ + +#if !GLIB_CHECK_VERSION(2, 47, 1) +/* Older versions of g_value_unset() only allowed to unset a GValue which + * was initialized previously. This was relaxed ([1], [2], [3]). + * + * Our nm_auto_unset_gvalue macro requires to be able to call g_value_unset(). + * Also, it is our general practice to allow for that. Add a compat implementation. + * + * [1] https://gitlab.gnome.org/GNOME/glib/commit/4b2d92a864f1505f1b08eb639d74293fa32681da + * [2] commit "Allow passing unset GValues to g_value_unset()" + * [3] https://bugzilla.gnome.org/show_bug.cgi?id=755766 + */ +static inline void +_nm_g_value_unset(GValue *value) +{ + g_return_if_fail(value); + + if (value->g_type != 0) + g_value_unset(value); +} + #define g_value_unset _nm_g_value_unset +#endif + +/* G_PID_FORMAT was added only in 2.53.5. Define it ourself. + * + * If this was about "pid_t", we would check SIZEOF_PID_T, and set + * PRIi32/PRIi16, like systemd does. But it's actually about + * GPid, which glib typedefs as an "int". + * + * There is a test_gpid() that check that GPid is really a typedef + * for int. */ +#undef G_PID_FORMAT +#define G_PID_FORMAT "i" + +/*****************************************************************************/ + +/* G_SOURCE_FUNC was added in 2.57.2. */ +#undef G_SOURCE_FUNC +#define G_SOURCE_FUNC(f) ((GSourceFunc)(void (*)(void))(f)) + +/*****************************************************************************/ + +/* g_atomic_pointer_get() is implemented as a macro, and it is also used for + * (gsize *) arguments. However, that leads to compiler warnings in certain + * configurations. Work around it, by redefining the macro. */ +static inline gpointer +_g_atomic_pointer_get(void **atomic) +{ + return g_atomic_pointer_get(atomic); +} +#undef g_atomic_pointer_get +#define g_atomic_pointer_get(atomic) \ + ({ \ + typeof(*atomic) *const _atomic = (atomic); \ + \ + /* g_atomic_pointer_get() is used by glib also for (gsize *) pointers, + * not only pointers to pointers. We thus don't enforce that (*atomic) + * is a pointer, but of suitable size/alignment. */ \ + \ + G_STATIC_ASSERT(sizeof(*_atomic) == sizeof(gpointer)); \ + G_STATIC_ASSERT(_nm_alignof(*_atomic) == _nm_alignof(gpointer)); \ + (void) (0 ? (gpointer) * (_atomic) : NULL); \ + \ + (typeof(*_atomic)) _g_atomic_pointer_get((void **) _atomic); \ + }) + +/* Reimplement g_atomic_pointer_set() macro too. Our variant does more type + * checks. */ +static inline void +_g_atomic_pointer_set(void **atomic, void *newval) +{ + return g_atomic_pointer_set(atomic, newval); +} +#undef g_atomic_pointer_set +#define g_atomic_pointer_set(atomic, newval) \ + ({ \ + typeof(*atomic) *const _atomic = (atomic); \ + typeof(*_atomic) const _newval = (newval); \ + _nm_unused gconstpointer const _val_type_check = _newval; \ + \ + (void) (0 ? (gpointer) * (_atomic) : NULL); \ + \ + _g_atomic_pointer_set((void **) _atomic, (void *) _newval); \ + }) + +/* Glib implements g_atomic_pointer_compare_and_exchange() as a macro. + * For one, to inline the atomic operation and also to perform some type checks + * on the arguments. + * Depending on compiler and glib version, glib passes the arguments as they + * are to __atomic_compare_exchange_n(). Some clang version don't accept const + * pointers there. Reimplement the macro to get that right, but with stronger + * type checks (as we use typeof()). Had one job. */ +static inline gboolean +_g_atomic_pointer_compare_and_exchange(void **atomic, void *oldval, void *newval) +{ + return g_atomic_pointer_compare_and_exchange(atomic, oldval, newval); +} +#undef g_atomic_pointer_compare_and_exchange +#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ + ({ \ + typeof(*atomic) *const _atomic = (atomic); \ + typeof(*_atomic) const _oldval = (oldval); \ + typeof(*_atomic) const _newval = (newval); \ + _nm_unused gconstpointer const _val_type_check = _oldval; \ + \ + (void) (0 ? (gpointer) * (_atomic) : NULL); \ + \ + _g_atomic_pointer_compare_and_exchange((void **) _atomic, \ + (void *) _oldval, \ + (void *) _newval); \ + }) + +/*****************************************************************************/ + +#if !GLIB_CHECK_VERSION(2, 58, 0) +static inline gboolean +g_hash_table_steal_extended(GHashTable * hash_table, + gconstpointer lookup_key, + gpointer * stolen_key, + gpointer * stolen_value) +{ + g_assert(stolen_key); + g_assert(stolen_value); + + if (g_hash_table_lookup_extended(hash_table, lookup_key, stolen_key, stolen_value)) { + g_hash_table_steal(hash_table, lookup_key); + return TRUE; + } + *stolen_key = NULL; + *stolen_value = NULL; + return FALSE; +} +#else + #define g_hash_table_steal_extended(hash_table, lookup_key, stolen_key, stolen_value) \ + ({ \ + gpointer *_stolen_key = (stolen_key); \ + gpointer *_stolen_value = (stolen_value); \ + \ + /* we cannot allow NULL arguments, because then we would leak the values in + * the compat implementation. */ \ + g_assert(_stolen_key); \ + g_assert(_stolen_value); \ + \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + g_hash_table_steal_extended(hash_table, lookup_key, _stolen_key, _stolen_value); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + }) +#endif + +/*****************************************************************************/ + +__attribute__(( + __deprecated__("Don't use g_cancellable_reset(). Create a new cancellable instead."))) void +_nm_g_cancellable_reset(GCancellable *cancellable); + +#undef g_cancellable_reset +#define g_cancellable_reset(cancellable) _nm_g_cancellable_reset(cancellable) + +/*****************************************************************************/ + +#endif /* __NM_GLIB_H__ */ diff --git a/src/libnm-glib-aux/nm-hash-utils.c b/src/libnm-glib-aux/nm-hash-utils.c new file mode 100644 index 0000000..9e168dc --- /dev/null +++ b/src/libnm-glib-aux/nm-hash-utils.c @@ -0,0 +1,286 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-hash-utils.h" + +#include + +#include "nm-shared-utils.h" +#include "nm-random-utils.h" + +/*****************************************************************************/ + +#define HASH_KEY_SIZE 16u +#define HASH_KEY_SIZE_GUINT ((HASH_KEY_SIZE + sizeof(guint) - 1) / sizeof(guint)) + +G_STATIC_ASSERT(sizeof(guint) * HASH_KEY_SIZE_GUINT >= HASH_KEY_SIZE); + +static const guint8 *volatile global_seed = NULL; + +static const guint8 * +_get_hash_key_init(void) +{ + /* the returned hash is aligned to guin64, hence, it is safe + * to use it as guint* or guint64* pointer. */ + static union { + guint8 v8[HASH_KEY_SIZE]; + guint _align_as_uint; + guint32 _align_as_uint32; + guint64 _align_as_uint64; + } g_arr; + const guint8 *g; + +again: + g = g_atomic_pointer_get(&global_seed); + if (!G_UNLIKELY(g)) { + static gsize g_lock; + uint64_t h; + union { + guint vuint; + guint8 v8[HASH_KEY_SIZE]; + guint8 _extra_entropy[3 * HASH_KEY_SIZE]; + } t_arr; + + nm_utils_random_bytes(&t_arr, sizeof(t_arr)); + + /* We only initialize one random hash key. So we can spend some effort + * of getting this right. For one, we collect more random bytes than + * necessary. + * + * Then, the first guint of the seed should have all the entropy that we could + * obtain in sizeof(t_arr). For that, siphash(t_arr) and xor the first guint + * with hash. + * The first guint is especially interesting for nm_hash_static() below that + * doesn't use siphash itself. */ + h = c_siphash_hash(t_arr.v8, (const guint8 *) &t_arr, sizeof(t_arr)); + if (sizeof(h) > sizeof(guint)) + t_arr.vuint = t_arr.vuint ^ ((guint)(h & G_MAXUINT)) ^ ((guint)(h >> 32)); + else + t_arr.vuint = t_arr.vuint ^ ((guint)(h & G_MAXUINT)); + + if (!g_once_init_enter(&g_lock)) { + /* lost a race. The random key is already initialized. */ + goto again; + } + + memcpy(g_arr.v8, t_arr.v8, HASH_KEY_SIZE); + g = g_arr.v8; + g_atomic_pointer_set(&global_seed, g); + g_once_init_leave(&g_lock, 1); + } + + nm_assert(g == g_arr.v8); + return g; +} + +#define _get_hash_key() \ + ({ \ + const guint8 *_g; \ + \ + _g = g_atomic_pointer_get(&global_seed); \ + if (G_UNLIKELY(!_g)) \ + _g = _get_hash_key_init(); \ + _g; \ + }) + +guint +nm_hash_static(guint static_seed) +{ + /* Note that we only xor the static_seed with the first guint of the key. + * + * We don't use siphash, which would mix the bits better with _get_hash_key(). + * Note that nm_hash_static() isn't used to hash the static_seed. Instead, it + * is used to get a unique hash value in a static context. That means, every + * caller is responsible to choose a static_seed that is sufficiently + * distinct from all other callers. In other words, static_seed should be a + * unique constant with good entropy. + * + * Note that _get_hash_key_init() already xored the first guint of the + * key with the siphash of the entire static key. That means, even if + * we got bad randomness for the first guint, the first guint is also + * mixed with the randomness of the entire random key. + * + * Also, ensure that we don't return zero (like for nm_hash_complete()). + */ + return ((*((const guint *) _get_hash_key())) ^ static_seed) ?: 3679500967u; +} + +void +nm_hash_siphash42_init(CSipHash *h, guint static_seed) +{ + const guint8 *g; + union { + guint64 _align_as_uint64; + guint arr[HASH_KEY_SIZE_GUINT]; + } seed; + + nm_assert(h); + + g = _get_hash_key(); + memcpy(&seed, g, HASH_KEY_SIZE); + seed.arr[0] ^= static_seed; + c_siphash_init(h, (const guint8 *) &seed); +} + +guint +nm_hash_str(const char *str) +{ + NMHashState h; + + if (!str) + return nm_hash_static(1867854211u); + nm_hash_init(&h, 1867854211u); + nm_hash_update_str(&h, str); + return nm_hash_complete(&h); +} + +guint +nm_str_hash(gconstpointer str) +{ + return nm_hash_str(str); +} + +guint +nm_hash_ptr(gconstpointer ptr) +{ + NMHashState h; + + if (!ptr) + return nm_hash_static(2907677551u); + nm_hash_init(&h, 2907677551u); + nm_hash_update(&h, &ptr, sizeof(ptr)); + return nm_hash_complete(&h); +} + +guint +nm_direct_hash(gconstpointer ptr) +{ + return nm_hash_ptr(ptr); +} + +/*****************************************************************************/ + +guint +nm_pstr_hash(gconstpointer p) +{ + const char *const *s = p; + + if (!s) + return nm_hash_static(101061439u); + return nm_hash_str(*s); +} + +gboolean +nm_pstr_equal(gconstpointer a, gconstpointer b) +{ + const char *const *s1 = a; + const char *const *s2 = b; + + return (s1 == s2) || (s1 && s2 && nm_streq0(*s1, *s2)); +} + +guint +nm_pint_hash(gconstpointer p) +{ + const int *s = p; + + if (!s) + return nm_hash_static(298377461u); + return nm_hash_val(1208815757u, *s); +} + +gboolean +nm_pint_equals(gconstpointer a, gconstpointer b) +{ + const int *s1 = a; + const int *s2 = a; + + return s1 == s2 || (s1 && s2 && *s1 == *s2); +} + +guint +nm_pdirect_hash(gconstpointer p) +{ + const void *const *s = p; + + if (!s) + return nm_hash_static(1852748873u); + return nm_direct_hash(*s); +} + +gboolean +nm_pdirect_equal(gconstpointer a, gconstpointer b) +{ + const void *const *s1 = a; + const void *const *s2 = b; + + return (s1 == s2) || (s1 && s2 && *s1 == *s2); +} + +guint +nm_ppdirect_hash(gconstpointer p) +{ + const void *const *const *s = p; + + if (!s) + return nm_hash_static(396534869u); + if (!*s) + return nm_hash_static(1476102263u); + return nm_direct_hash(**s); +} + +gboolean +nm_ppdirect_equal(gconstpointer a, gconstpointer b) +{ + const void *const *const *s1 = a; + const void *const *const *s2 = b; + + if (s1 == s2) + return TRUE; + if (!s1 || !s2) + return FALSE; + + if (*s1 == *s2) + return TRUE; + if (!*s1 || !*s2) + return FALSE; + + return **s1 == **s2; +} + +/*****************************************************************************/ + +guint +nm_gbytes_hash(gconstpointer p) +{ + GBytes * ptr = (GBytes *) p; + gconstpointer arr; + gsize len; + + arr = g_bytes_get_data(ptr, &len); + return nm_hash_mem(792701303u, arr, len); +} + +guint +nm_pgbytes_hash(gconstpointer p) +{ + GBytes *const *ptr = p; + gconstpointer arr; + gsize len; + + arr = g_bytes_get_data(*ptr, &len); + return nm_hash_mem(1470631313u, arr, len); +} + +gboolean +nm_pgbytes_equal(gconstpointer a, gconstpointer b) +{ + GBytes *const *ptr_a = a; + GBytes *const *ptr_b = b; + + return g_bytes_equal(*ptr_a, *ptr_b); +} diff --git a/src/libnm-glib-aux/nm-hash-utils.h b/src/libnm-glib-aux/nm-hash-utils.h new file mode 100644 index 0000000..a7b8677 --- /dev/null +++ b/src/libnm-glib-aux/nm-hash-utils.h @@ -0,0 +1,442 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_HASH_UTILS_H__ +#define __NM_HASH_UTILS_H__ + +#include "c-siphash/src/c-siphash.h" +#include "nm-macros-internal.h" + +/*****************************************************************************/ + +#define NM_HASH_SEED_16(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af) \ + ((const guint8[16]){a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af}) + +void nm_hash_siphash42_init(CSipHash *h, guint static_seed); + +/* Siphash24 of binary buffer @arr and @len, using the randomized seed from + * other NMHash functions. + * + * Note, that this is guaranteed to use siphash42 under the hood (contrary to + * all other NMHash API, which leave this undefined). That matters at the point, + * where the caller needs to be sure that a reasonably strong hashing algorithm + * is used. (Yes, NMHash is all about siphash24, but otherwise that is not promised + * anywhere). + * + * Another difference is, that this returns guint64 (not guint like other NMHash functions). + * + * Another difference is, that this may also return zero (not like nm_hash_complete()). + * + * Then, why not use c_siphash_hash() directly? Because this also uses the randomized, + * per-run hash-seed like nm_hash_init(). So, you get siphash24 with a random + * seed (which is cached for the current run of the program). + */ +static inline guint64 +nm_hash_siphash42(guint static_seed, const void *ptr, gsize n) +{ + CSipHash h; + + nm_hash_siphash42_init(&h, static_seed); + c_siphash_append(&h, ptr, n); + return c_siphash_finalize(&h); +} + +/*****************************************************************************/ + +struct _NMHashState { + CSipHash _state; +}; + +typedef struct _NMHashState NMHashState; + +guint nm_hash_static(guint static_seed); + +static inline void +nm_hash_init(NMHashState *state, guint static_seed) +{ + nm_assert(state); + + nm_hash_siphash42_init(&state->_state, static_seed); +} + +static inline guint64 +nm_hash_complete_u64(NMHashState *state) +{ + nm_assert(state); + + /* this returns the native u64 hash value. Note that this differs + * from nm_hash_complete() in two ways: + * + * - the type, guint64 vs. guint. + * - nm_hash_complete() never returns zero. + * + * In practice, nm_hash*() API is implemented via siphash24, so this returns + * the siphash24 value. But that is not guaranteed by the API, and if you need + * siphash24 directly, use c_siphash_*() and nm_hash_siphash42*() API. */ + return c_siphash_finalize(&state->_state); +} + +static inline guint +nm_hash_complete(NMHashState *state) +{ + guint64 h; + + h = nm_hash_complete_u64(state); + + /* we don't ever want to return a zero hash. + * + * NMPObject requires that in _idx_obj_part(), and it's just a good idea. */ + return (((guint)(h >> 32)) ^ ((guint) h)) ?: 1396707757u; +} + +static inline void +nm_hash_update(NMHashState *state, const void *ptr, gsize n) +{ + nm_assert(state); + nm_assert(n == 0 || ptr); + + /* Note: the data passed in here might be sensitive data (secrets), + * that we should nm_explicit_bzero() afterwards. However, since + * we are using siphash24 with a random key, that is not really + * necessary. Something to keep in mind, if we ever move away from + * this hash implementation. */ + c_siphash_append(&state->_state, ptr, n); +} + +#define nm_hash_update_val(state, val) \ + G_STMT_START \ + { \ + typeof(val) _val = (val); \ + \ + nm_hash_update((state), &_val, sizeof(_val)); \ + } \ + G_STMT_END + +#define nm_hash_update_valp(state, val) nm_hash_update((state), (val), sizeof(*(val))) + +static inline void +nm_hash_update_bool(NMHashState *state, bool val) +{ + nm_hash_update(state, &val, sizeof(val)); +} + +#define _NM_HASH_COMBINE_BOOLS_x_1(t, y) ((y) ? ((t)(1ull << 0)) : ((t) 0ull)) +#define _NM_HASH_COMBINE_BOOLS_x_2(t, y, ...) \ + ((y) ? ((t)(1ull << 1)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_1(t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_3(t, y, ...) \ + ((y) ? ((t)(1ull << 2)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_2(t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_4(t, y, ...) \ + ((y) ? ((t)(1ull << 3)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_3(t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_5(t, y, ...) \ + ((y) ? ((t)(1ull << 4)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_4(t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_6(t, y, ...) \ + ((y) ? ((t)(1ull << 5)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_5(t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_7(t, y, ...) \ + ((y) ? ((t)(1ull << 6)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_6(t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_8(t, y, ...) \ + ((y) ? ((t)(1ull << 7)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_7(t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_9(t, y, ...) \ + ((y) ? ((t)(1ull << 8)) : ((t) 0ull)) \ + | (G_STATIC_ASSERT_EXPR(sizeof(t) >= 2), (_NM_HASH_COMBINE_BOOLS_x_8(t, __VA_ARGS__))) +#define _NM_HASH_COMBINE_BOOLS_x_10(t, y, ...) \ + ((y) ? ((t)(1ull << 9)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_9(t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_x_11(t, y, ...) \ + ((y) ? ((t)(1ull << 10)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_10(t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_n2(t, n, ...) _NM_HASH_COMBINE_BOOLS_x_##n(t, __VA_ARGS__) +#define _NM_HASH_COMBINE_BOOLS_n(t, n, ...) _NM_HASH_COMBINE_BOOLS_n2(t, n, __VA_ARGS__) + +#define NM_HASH_COMBINE_BOOLS(type, ...) \ + ((type)(_NM_HASH_COMBINE_BOOLS_n(type, NM_NARG(__VA_ARGS__), __VA_ARGS__))) + +#define nm_hash_update_bools(state, ...) \ + nm_hash_update_val(state, NM_HASH_COMBINE_BOOLS(guint8, __VA_ARGS__)) + +#define _NM_HASH_COMBINE_VALS_typ_x_1(y) typeof(y) _v1; +#define _NM_HASH_COMBINE_VALS_typ_x_2(y, ...) \ + typeof(y) _v2; \ + _NM_HASH_COMBINE_VALS_typ_x_1(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_3(y, ...) \ + typeof(y) _v3; \ + _NM_HASH_COMBINE_VALS_typ_x_2(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_4(y, ...) \ + typeof(y) _v4; \ + _NM_HASH_COMBINE_VALS_typ_x_3(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_5(y, ...) \ + typeof(y) _v5; \ + _NM_HASH_COMBINE_VALS_typ_x_4(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_6(y, ...) \ + typeof(y) _v6; \ + _NM_HASH_COMBINE_VALS_typ_x_5(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_7(y, ...) \ + typeof(y) _v7; \ + _NM_HASH_COMBINE_VALS_typ_x_6(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_8(y, ...) \ + typeof(y) _v8; \ + _NM_HASH_COMBINE_VALS_typ_x_7(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_9(y, ...) \ + typeof(y) _v9; \ + _NM_HASH_COMBINE_VALS_typ_x_8(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_10(y, ...) \ + typeof(y) _v10; \ + _NM_HASH_COMBINE_VALS_typ_x_9(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_11(y, ...) \ + typeof(y) _v11; \ + _NM_HASH_COMBINE_VALS_typ_x_10(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_12(y, ...) \ + typeof(y) _v12; \ + _NM_HASH_COMBINE_VALS_typ_x_11(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_13(y, ...) \ + typeof(y) _v13; \ + _NM_HASH_COMBINE_VALS_typ_x_12(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_14(y, ...) \ + typeof(y) _v14; \ + _NM_HASH_COMBINE_VALS_typ_x_13(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_15(y, ...) \ + typeof(y) _v15; \ + _NM_HASH_COMBINE_VALS_typ_x_14(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_16(y, ...) \ + typeof(y) _v16; \ + _NM_HASH_COMBINE_VALS_typ_x_15(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_17(y, ...) \ + typeof(y) _v17; \ + _NM_HASH_COMBINE_VALS_typ_x_16(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_18(y, ...) \ + typeof(y) _v18; \ + _NM_HASH_COMBINE_VALS_typ_x_17(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_19(y, ...) \ + typeof(y) _v19; \ + _NM_HASH_COMBINE_VALS_typ_x_18(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_x_20(y, ...) \ + typeof(y) _v20; \ + _NM_HASH_COMBINE_VALS_typ_x_19(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_n2(n, ...) _NM_HASH_COMBINE_VALS_typ_x_##n(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_typ_n(n, ...) _NM_HASH_COMBINE_VALS_typ_n2(n, __VA_ARGS__) + +#define _NM_HASH_COMBINE_VALS_val_x_1(y) ._v1 = (y), +#define _NM_HASH_COMBINE_VALS_val_x_2(y, ...) ._v2 = (y), _NM_HASH_COMBINE_VALS_val_x_1(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_3(y, ...) ._v3 = (y), _NM_HASH_COMBINE_VALS_val_x_2(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_4(y, ...) ._v4 = (y), _NM_HASH_COMBINE_VALS_val_x_3(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_5(y, ...) ._v5 = (y), _NM_HASH_COMBINE_VALS_val_x_4(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_6(y, ...) ._v6 = (y), _NM_HASH_COMBINE_VALS_val_x_5(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_7(y, ...) ._v7 = (y), _NM_HASH_COMBINE_VALS_val_x_6(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_8(y, ...) ._v8 = (y), _NM_HASH_COMBINE_VALS_val_x_7(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_9(y, ...) ._v9 = (y), _NM_HASH_COMBINE_VALS_val_x_8(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_10(y, ...) \ + ._v10 = (y), _NM_HASH_COMBINE_VALS_val_x_9(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_11(y, ...) \ + ._v11 = (y), _NM_HASH_COMBINE_VALS_val_x_10(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_12(y, ...) \ + ._v12 = (y), _NM_HASH_COMBINE_VALS_val_x_11(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_13(y, ...) \ + ._v13 = (y), _NM_HASH_COMBINE_VALS_val_x_12(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_14(y, ...) \ + ._v14 = (y), _NM_HASH_COMBINE_VALS_val_x_13(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_15(y, ...) \ + ._v15 = (y), _NM_HASH_COMBINE_VALS_val_x_14(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_16(y, ...) \ + ._v16 = (y), _NM_HASH_COMBINE_VALS_val_x_15(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_17(y, ...) \ + ._v17 = (y), _NM_HASH_COMBINE_VALS_val_x_16(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_18(y, ...) \ + ._v18 = (y), _NM_HASH_COMBINE_VALS_val_x_17(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_19(y, ...) \ + ._v19 = (y), _NM_HASH_COMBINE_VALS_val_x_18(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_x_20(y, ...) \ + ._v20 = (y), _NM_HASH_COMBINE_VALS_val_x_19(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_n2(n, ...) _NM_HASH_COMBINE_VALS_val_x_##n(__VA_ARGS__) +#define _NM_HASH_COMBINE_VALS_val_n(n, ...) _NM_HASH_COMBINE_VALS_val_n2(n, __VA_ARGS__) + +/* NM_HASH_COMBINE_VALS() is faster then nm_hash_update_val() as it combines multiple + * calls to nm_hash_update() using a packed structure. */ +#define NM_HASH_COMBINE_VALS(var, ...) \ + const struct _nm_packed { \ + _NM_HASH_COMBINE_VALS_typ_n(NM_NARG(__VA_ARGS__), __VA_ARGS__) \ + } var _nm_alignas(guint64) = {_NM_HASH_COMBINE_VALS_val_n(NM_NARG(__VA_ARGS__), __VA_ARGS__)} + +/* nm_hash_update_vals() is faster then nm_hash_update_val() as it combines multiple + * calls to nm_hash_update() using a packed structure. */ +#define nm_hash_update_vals(state, ...) \ + G_STMT_START \ + { \ + NM_HASH_COMBINE_VALS(_val, __VA_ARGS__); \ + \ + nm_hash_update((state), &_val, sizeof(_val)); \ + } \ + G_STMT_END + +static inline void +nm_hash_update_mem(NMHashState *state, const void *ptr, gsize n) +{ + /* This also hashes the length of the data. That means, + * hashing two consecutive binary fields (of arbitrary + * length), will hash differently. That is, + * [[1,1], []] differs from [[1],[1]]. + * + * If you have a constant length (sizeof), use nm_hash_update() + * instead. */ + nm_hash_update(state, &n, sizeof(n)); + if (n > 0) + nm_hash_update(state, ptr, n); +} + +static inline void +nm_hash_update_str0(NMHashState *state, const char *str) +{ + if (str) + nm_hash_update_mem(state, str, strlen(str)); + else { + gsize n = G_MAXSIZE; + + nm_hash_update(state, &n, sizeof(n)); + } +} + +static inline void +nm_hash_update_str(NMHashState *state, const char *str) +{ + nm_assert(str); + nm_hash_update(state, str, strlen(str) + 1); +} + +#if _NM_CC_SUPPORT_GENERIC + /* Like nm_hash_update_str(), but restricted to arrays only. nm_hash_update_str() only works + * with a @str argument that cannot be NULL. If you have a string pointer, that is never NULL, use + * nm_hash_update() instead. */ + #define nm_hash_update_strarr(state, str) \ + (_Generic(&(str), const char(*)[sizeof(str)] \ + : nm_hash_update_str((state), (str)), char(*)[sizeof(str)] \ + : nm_hash_update_str((state), (str)))) +#else + #define nm_hash_update_strarr(state, str) nm_hash_update_str((state), (str)) +#endif + +guint nm_hash_ptr(gconstpointer ptr); +guint nm_direct_hash(gconstpointer str); + +guint nm_hash_str(const char *str); +guint nm_str_hash(gconstpointer str); + +#define nm_hash_val(static_seed, val) \ + ({ \ + NMHashState _h; \ + \ + nm_hash_init(&_h, (static_seed)); \ + nm_hash_update_val(&_h, (val)); \ + nm_hash_complete(&_h); \ + }) + +static inline guint +nm_hash_mem(guint static_seed, const void *ptr, gsize n) +{ + NMHashState h; + + if (n == 0) + return nm_hash_static(static_seed); + nm_hash_init(&h, static_seed); + nm_hash_update(&h, ptr, n); + return nm_hash_complete(&h); +} + +/*****************************************************************************/ + +/* nm_pstr_*() are for hashing keys that are pointers to strings, + * that is, "const char *const*" types, using strcmp(). */ + +guint nm_pstr_hash(gconstpointer p); + +gboolean nm_pstr_equal(gconstpointer a, gconstpointer b); + +/*****************************************************************************/ + +/* nm_pint_*() are for hashing keys that are pointers to int values, + * that is, "const int *" types. */ + +guint nm_pint_hash(gconstpointer p); +gboolean nm_pint_equals(gconstpointer a, gconstpointer b); + +G_STATIC_ASSERT(sizeof(int) == sizeof(guint32)); +#define nm_puint32_hash nm_pint_hash +#define nm_puint32_equals nm_pint_equals + +/*****************************************************************************/ + +/* this hashes/compares the pointer value that we point to. Basically, + * (*((const void *const*) a) == *((const void *const*) b)). */ + +guint nm_pdirect_hash(gconstpointer p); + +gboolean nm_pdirect_equal(gconstpointer a, gconstpointer b); + +/* this hashes/compares the direct pointer value by following pointers to + * pointers 2 times. + * (**((const void *const*const*) a) == **((const void *const*const*) b)). */ + +guint nm_ppdirect_hash(gconstpointer p); + +gboolean nm_ppdirect_equal(gconstpointer a, gconstpointer b); + +/*****************************************************************************/ + +guint nm_gbytes_hash(gconstpointer p); +#define nm_gbytes_equal g_bytes_equal + +guint nm_pgbytes_hash(gconstpointer p); +gboolean nm_pgbytes_equal(gconstpointer a, gconstpointer b); + +/*****************************************************************************/ + +#define NM_HASH_OBFUSCATE_PTR_FMT "%016" G_GINT64_MODIFIER "x" + +/* sometimes we want to log a pointer directly, for providing context/information about + * the message that get logged. Logging pointer values directly defeats ASLR, so we should + * not do that. This returns a "unsigned long long" value that can be used + * instead. + * + * Note that there is a chance that two different pointer values hash to the same obfuscated + * value. So beware of that when reviewing logs. However, such a collision is very unlikely. */ +static inline guint64 +nm_hash_obfuscate_ptr(guint static_seed, gconstpointer val) +{ + NMHashState h; + + nm_hash_init(&h, static_seed); + nm_hash_update_val(&h, val); + return nm_hash_complete_u64(&h); +} + +/* if you want to log obfuscated pointer for a certain context (like, NMPRuleManager + * logging user-tags), then you are advised to use nm_hash_obfuscate_ptr() with your + * own, unique static-seed. + * + * However, for example the singleton constructors log the obfuscated pointer values + * for all singletons, so they must all be obfuscated with the same seed. So, this + * macro uses a particular static seed that should be used by when comparing pointer + * values in a global context. */ +#define NM_HASH_OBFUSCATE_PTR(ptr) (nm_hash_obfuscate_ptr(1678382159u, ptr)) + +#define NM_HASH_OBFUSCATE_PTR_STR(ptr, buf) \ + ({ \ + gconstpointer _ptr = (ptr); \ + \ + _ptr ? nm_sprintf_buf(buf, "[" NM_HASH_OBFUSCATE_PTR_FMT "]", NM_HASH_OBFUSCATE_PTR(_ptr)) \ + : "(null)"; \ + }) + +static inline const char * +nm_hash_obfuscated_ptr_str(gconstpointer ptr, char buf[static 17]) +{ + int l; + + nm_assert(buf); + l = g_snprintf(buf, 17, NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(ptr)); + nm_assert(l < 17); + return buf; +} + +#define nm_hash_obfuscated_ptr_str_a(ptr) (nm_hash_obfuscated_ptr_str((ptr), g_alloca(17))) + +/*****************************************************************************/ + +#endif /* __NM_HASH_UTILS_H__ */ diff --git a/src/libnm-glib-aux/nm-io-utils.c b/src/libnm-glib-aux/nm-io-utils.c new file mode 100644 index 0000000..e02049a --- /dev/null +++ b/src/libnm-glib-aux/nm-io-utils.c @@ -0,0 +1,480 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-io-utils.h" + +#include +#include +#include + +#include "nm-str-buf.h" +#include "nm-shared-utils.h" +#include "nm-secret-utils.h" +#include "nm-errno.h" + +/*****************************************************************************/ + +_nm_printf(4, 5) static int _get_contents_error(GError ** error, + int errsv, + int * out_errsv, + const char *format, + ...) +{ + nm_assert(NM_ERRNO_NATIVE(errsv)); + + if (error) { + gs_free char *msg = NULL; + va_list args; + char bstrerr[NM_STRERROR_BUFSIZE]; + + va_start(args, format); + msg = g_strdup_vprintf(format, args); + va_end(args); + g_set_error(error, + G_FILE_ERROR, + g_file_error_from_errno(errsv), + "%s: %s", + msg, + nm_strerror_native_r(errsv, bstrerr, sizeof(bstrerr))); + } + + nm_assert(errsv > 0); + NM_SET_OUT(out_errsv, errsv); + + return FALSE; +} +#define _get_contents_error_errno(error, out_errsv, ...) \ + ({ \ + int _errsv = (errno); \ + \ + _get_contents_error(error, _errsv, out_errsv, __VA_ARGS__); \ + }) + +/** + * nm_utils_fd_get_contents: + * @fd: open file descriptor to read. The fd will not be closed, + * but don't rely on its state afterwards. + * @close_fd: if %TRUE, @fd will be closed by the function. + * Passing %TRUE here might safe a syscall for dup(). + * @max_length: allocate at most @max_length bytes. If the + * file is larger, reading will fail. Set to zero to use + * a very large default. + * WARNING: @max_length is here to avoid a crash for huge/unlimited files. + * For example, stat(/sys/class/net/enp0s25/ifindex) gives a filesize of + * 4K, although the actual real is small. @max_length is the memory + * allocated in the process of reading the file, thus it must be at least + * the size reported by fstat. + * If you set it to 1K, read will fail because fstat() claims the + * file is larger. + * @flags: %NMUtilsFileGetContentsFlags for reading the file. + * @contents: the output buffer with the file read. It is always + * NUL terminated. The buffer is at most @max_length long, including + * the NUL byte. That is, it reads only files up to a length of + * @max_length - 1 bytes. + * @length: optional output argument of the read file size. + * @out_errsv: (allow-none) (out): on error, a positive errno. or zero. + * @error: + * + * + * A reimplementation of g_file_get_contents() with a few differences: + * - accepts an open fd, instead of a path name. This allows you to + * use openat(). + * - limits the maximum filesize to max_length. + * + * Returns: TRUE on success. + */ +gboolean +nm_utils_fd_get_contents(int fd, + gboolean close_fd, + gsize max_length, + NMUtilsFileGetContentsFlags flags, + char ** contents, + gsize * length, + int * out_errsv, + GError ** error) +{ + nm_auto_close int fd_keeper = close_fd ? fd : -1; + struct stat stat_buf; + gs_free char * str = NULL; + const bool do_bzero_mem = NM_FLAGS_HAS(flags, NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET); + int errsv; + + g_return_val_if_fail(fd >= 0, FALSE); + g_return_val_if_fail(contents && !*contents, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + NM_SET_OUT(length, 0); + + if (fstat(fd, &stat_buf) < 0) + return _get_contents_error_errno(error, out_errsv, "failure during fstat"); + + if (!max_length) { + /* default to a very large size, but not extreme */ + max_length = 2 * 1024 * 1024; + } + + if (stat_buf.st_size > 0 && S_ISREG(stat_buf.st_mode)) { + const gsize n_stat = stat_buf.st_size; + ssize_t n_read; + + if (n_stat > max_length - 1) + return _get_contents_error(error, + EMSGSIZE, + out_errsv, + "file too large (%zu+1 bytes with maximum %zu bytes)", + n_stat, + max_length); + + str = g_try_malloc(n_stat + 1); + if (!str) + return _get_contents_error(error, + ENOMEM, + out_errsv, + "failure to allocate buffer of %zu+1 bytes", + n_stat); + + n_read = nm_utils_fd_read_loop(fd, str, n_stat, TRUE); + if (n_read < 0) { + if (do_bzero_mem) + nm_explicit_bzero(str, n_stat); + return _get_contents_error(error, + -n_read, + out_errsv, + "error reading %zu bytes from file descriptor", + n_stat); + } + str[n_read] = '\0'; + + if (n_read < n_stat) { + if (!(str = nm_secret_mem_try_realloc_take(str, do_bzero_mem, n_stat + 1, n_read + 1))) + return _get_contents_error(error, + ENOMEM, + out_errsv, + "failure to reallocate buffer with %zu bytes", + n_read + 1); + } + NM_SET_OUT(length, n_read); + } else { + nm_auto_fclose FILE *f = NULL; + char buf[4096]; + gsize n_have, n_alloc; + int fd2; + + if (fd_keeper >= 0) + fd2 = nm_steal_fd(&fd_keeper); + else { + fd2 = fcntl(fd, F_DUPFD_CLOEXEC, 0); + if (fd2 < 0) + return _get_contents_error_errno(error, out_errsv, "error during dup"); + } + + if (!(f = fdopen(fd2, "r"))) { + errsv = errno; + nm_close(fd2); + return _get_contents_error(error, errsv, out_errsv, "failure during fdopen"); + } + + n_have = 0; + n_alloc = 0; + + while (!feof(f)) { + gsize n_read; + + n_read = fread(buf, 1, sizeof(buf), f); + errsv = errno; + if (ferror(f)) { + if (do_bzero_mem) + nm_explicit_bzero(buf, sizeof(buf)); + return _get_contents_error(error, errsv, out_errsv, "error during fread"); + } + + if (n_have > G_MAXSIZE - 1 - n_read || n_have + n_read + 1 > max_length) { + if (do_bzero_mem) + nm_explicit_bzero(buf, sizeof(buf)); + return _get_contents_error( + error, + EMSGSIZE, + out_errsv, + "file stream too large (%zu+1 bytes with maximum %zu bytes)", + (n_have > G_MAXSIZE - 1 - n_read) ? G_MAXSIZE : n_have + n_read, + max_length); + } + + if (n_have + n_read + 1 >= n_alloc) { + gsize old_n_alloc = n_alloc; + + if (n_alloc != 0) { + nm_assert(str); + if (n_alloc >= max_length / 2) + n_alloc = max_length; + else + n_alloc *= 2; + } else { + nm_assert(!str); + n_alloc = NM_MIN(n_read + 1, sizeof(buf)); + } + + if (!(str = nm_secret_mem_try_realloc_take(str, + do_bzero_mem, + old_n_alloc, + n_alloc))) { + if (do_bzero_mem) + nm_explicit_bzero(buf, sizeof(buf)); + return _get_contents_error(error, + ENOMEM, + out_errsv, + "failure to allocate buffer of %zu bytes", + n_alloc); + } + } + + memcpy(str + n_have, buf, n_read); + n_have += n_read; + } + + if (do_bzero_mem) + nm_explicit_bzero(buf, sizeof(buf)); + + if (n_alloc == 0) + str = g_new0(char, 1); + else { + str[n_have] = '\0'; + if (n_have + 1 < n_alloc) { + if (!(str = nm_secret_mem_try_realloc_take(str, do_bzero_mem, n_alloc, n_have + 1))) + return _get_contents_error(error, + ENOMEM, + out_errsv, + "failure to truncate buffer to %zu bytes", + n_have + 1); + } + } + + NM_SET_OUT(length, n_have); + } + + *contents = g_steal_pointer(&str); + NM_SET_OUT(out_errsv, 0); + return TRUE; +} + +/** + * nm_utils_file_get_contents: + * @dirfd: optional file descriptor to use openat(). If negative, use plain open(). + * @filename: the filename to open. Possibly relative to @dirfd. + * @max_length: allocate at most @max_length bytes. + * WARNING: see nm_utils_fd_get_contents() hint about @max_length. + * @flags: %NMUtilsFileGetContentsFlags for reading the file. + * @contents: the output buffer with the file read. It is always + * NUL terminated. The buffer is at most @max_length long, including + * the NUL byte. That is, it reads only files up to a length of + * @max_length - 1 bytes. + * @length: optional output argument of the read file size. + * @out_errsv: (allow-none) (out): on error, a positive errno. or zero. + * @error: + * + * A reimplementation of g_file_get_contents() with a few differences: + * - accepts an @dirfd to open @filename relative to that path via openat(). + * - limits the maximum filesize to max_length. + * - uses O_CLOEXEC on internal file descriptor + * - optionally returns the native errno on failure. + * + * Returns: TRUE on success. + */ +gboolean +nm_utils_file_get_contents(int dirfd, + const char * filename, + gsize max_length, + NMUtilsFileGetContentsFlags flags, + char ** contents, + gsize * length, + int * out_errsv, + GError ** error) +{ + int fd; + + g_return_val_if_fail(filename && filename[0], FALSE); + g_return_val_if_fail(contents && !*contents, FALSE); + + NM_SET_OUT(length, 0); + + if (dirfd >= 0) { + fd = openat(dirfd, filename, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + return _get_contents_error_errno(error, + out_errsv, + "Failed to open file \"%s\" with openat", + filename); + } + } else { + fd = open(filename, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + return _get_contents_error_errno(error, + out_errsv, + "Failed to open file \"%s\"", + filename); + } + } + return nm_utils_fd_get_contents(fd, + TRUE, + max_length, + flags, + contents, + length, + out_errsv, + error); +} + +/*****************************************************************************/ + +/* + * Copied from GLib's g_file_set_contents() et al., but allows + * specifying a mode for the new file. + */ +gboolean +nm_utils_file_set_contents(const char *filename, + const char *contents, + gssize length, + mode_t mode, + int * out_errsv, + GError ** error) +{ + gs_free char *tmp_name = NULL; + struct stat statbuf; + int errsv; + gssize s; + int fd; + + g_return_val_if_fail(filename, FALSE); + g_return_val_if_fail(contents || !length, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + g_return_val_if_fail(length >= -1, FALSE); + + if (length == -1) + length = strlen(contents); + + tmp_name = g_strdup_printf("%s.XXXXXX", filename); + fd = g_mkstemp_full(tmp_name, O_RDWR | O_CLOEXEC, mode); + if (fd < 0) { + return _get_contents_error_errno(error, out_errsv, "failed to create file %s", tmp_name); + } + + while (length > 0) { + s = write(fd, contents, length); + if (s < 0) { + errsv = NM_ERRNO_NATIVE(errno); + if (errsv == EINTR) + continue; + + nm_close(fd); + unlink(tmp_name); + return _get_contents_error(error, + errsv, + out_errsv, + "failed to write to file %s", + tmp_name); + } + + g_assert(s <= length); + + contents += s; + length -= s; + } + + /* If the final destination exists and is > 0 bytes, we want to sync the + * newly written file to ensure the data is on disk when we rename over + * the destination. Otherwise, if we get a system crash we can lose both + * the new and the old file on some filesystems. (I.E. those that don't + * guarantee the data is written to the disk before the metadata.) + */ + if (lstat(filename, &statbuf) == 0 && statbuf.st_size > 0) { + if (fsync(fd) != 0) { + errsv = NM_ERRNO_NATIVE(errno); + nm_close(fd); + unlink(tmp_name); + return _get_contents_error(error, errsv, out_errsv, "failed to fsync %s", tmp_name); + } + } + + nm_close(fd); + + if (rename(tmp_name, filename)) { + errsv = NM_ERRNO_NATIVE(errno); + unlink(tmp_name); + return _get_contents_error(error, + errsv, + out_errsv, + "failed rename %s to %s", + tmp_name, + filename); + } + + return TRUE; +} + +/** + * nm_utils_file_stat: + * @filename: the filename to stat. + * @out_st: (allow-none) (out): if given, this will be passed to stat(). + * + * Just wraps stat() and gives the errno number as function result instead + * of setting the errno (though, errno is also set). It's only for convenience + * with + * + * if (nm_utils_file_stat (filename, NULL) == -ENOENT) { + * } + * + * Returns: 0 on success a negative errno on failure. */ +int +nm_utils_file_stat(const char *filename, struct stat *out_st) +{ + struct stat st; + + if (stat(filename, out_st ?: &st) != 0) + return -NM_ERRNO_NATIVE(errno); + return 0; +} + +/** + * nm_utils_fd_read: + * @fd: the fd to read from. + * @out_string: (out): output string where read bytes will be stored. + * + * Returns: <0 on failure, which is -(errno). + * 0 on EOF. + * >0 on success, which is the number of bytes read. */ +gssize +nm_utils_fd_read(int fd, NMStrBuf *out_string) +{ + gsize buf_available; + gssize n_read; + int errsv; + + g_return_val_if_fail(fd >= 0, -1); + g_return_val_if_fail(out_string, -1); + + /* If the buffer size is 0, we allocate NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 (1000 bytes) + * the first time. Afterwards, the buffer grows exponentially. + * + * Note that with @buf_available, we always would read as much buffer as we actually + * have reserved. */ + nm_str_buf_maybe_expand(out_string, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, FALSE); + + buf_available = out_string->allocated - out_string->len; + + n_read = read(fd, &((nm_str_buf_get_str_unsafe(out_string))[out_string->len]), buf_available); + if (n_read < 0) { + errsv = errno; + return -NM_ERRNO_NATIVE(errsv); + } + + if (n_read > 0) { + nm_assert((gsize) n_read <= buf_available); + nm_str_buf_set_size(out_string, out_string->len + (gsize) n_read, TRUE, FALSE); + } + + return n_read; +} diff --git a/src/libnm-glib-aux/nm-io-utils.h b/src/libnm-glib-aux/nm-io-utils.h new file mode 100644 index 0000000..8182f5c --- /dev/null +++ b/src/libnm-glib-aux/nm-io-utils.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_IO_UTILS_H__ +#define __NM_IO_UTILS_H__ + +#include "nm-macros-internal.h" + +/*****************************************************************************/ + +/** + * NMUtilsFileGetContentsFlags: + * @NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE: no flag + * @NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET: if present, ensure that no + * data is left in memory. Essentially, it means to call nm_explicit_bzero() + * to not leave key material on the heap (when reading secrets). + */ +typedef enum { + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE = 0, + NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET = (1 << 0), +} NMUtilsFileGetContentsFlags; + +gboolean nm_utils_fd_get_contents(int fd, + gboolean close_fd, + gsize max_length, + NMUtilsFileGetContentsFlags flags, + char ** contents, + gsize * length, + int * out_errsv, + GError ** error); + +gboolean nm_utils_file_get_contents(int dirfd, + const char * filename, + gsize max_length, + NMUtilsFileGetContentsFlags flags, + char ** contents, + gsize * length, + int * out_errsv, + GError ** error); + +gboolean nm_utils_file_set_contents(const char *filename, + const char *contents, + gssize length, + mode_t mode, + int * out_errsv, + GError ** error); + +struct _NMStrBuf; + +gssize nm_utils_fd_read(int fd, struct _NMStrBuf *out_string); + +struct stat; + +int nm_utils_file_stat(const char *filename, struct stat *out_st); + +#endif /* __NM_IO_UTILS_H__ */ diff --git a/src/libnm-glib-aux/nm-jansson.h b/src/libnm-glib-aux/nm-jansson.h new file mode 100644 index 0000000..6173a7a --- /dev/null +++ b/src/libnm-glib-aux/nm-jansson.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_JANSSON_H__ +#define __NM_JANSSON_H__ + +/* you need to include at least "config.h" first, possibly "nm-default.h". */ + +#if WITH_JANSSON + + #include + + /* Added in Jansson v2.8 */ + #ifndef json_object_foreach_safe + #define json_object_foreach_safe(object, n, key, value) \ + for (key = json_object_iter_key(json_object_iter(object)), \ + n = json_object_iter_next(object, json_object_key_to_iter(key)); \ + key && (value = json_object_iter_value(json_object_key_to_iter(key))); \ + key = json_object_iter_key(n), \ + n = json_object_iter_next(object, json_object_key_to_iter(key))) + #endif + +NM_AUTO_DEFINE_FCN0(json_t *, _nm_auto_decref_json, json_decref); + #define nm_auto_decref_json nm_auto(_nm_auto_decref_json) + +#endif /* WITH_JANSON */ + +#endif /* __NM_JANSSON_H__ */ diff --git a/src/libnm-glib-aux/nm-json-aux.c b/src/libnm-glib-aux/nm-json-aux.c new file mode 100644 index 0000000..dc67d6d --- /dev/null +++ b/src/libnm-glib-aux/nm-json-aux.c @@ -0,0 +1,286 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 - 2019 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-json-aux.h" + +#include + +/*****************************************************************************/ + +/* If RTLD_DEEPBIND isn't available just ignore it. This can cause problems + * with jansson, json-glib, and cjson symbols clashing (and as such crashing the + * program). But that needs to be fixed by the json libraries, and it is by adding + * symbol versioning in recent versions. */ +#ifndef RTLD_DEEPBIND + #define RTLD_DEEPBIND 0 +#endif + +/*****************************************************************************/ + +static void +_gstr_append_string_len(GString *gstr, const char *str, gsize len) +{ + g_string_append_c(gstr, '\"'); + + while (len > 0) { + gsize n; + const char *end; + gboolean valid; + + nm_assert(len > 0); + + valid = g_utf8_validate(str, len, &end); + + nm_assert(end && end >= str && end <= &str[len]); + + if (end > str) { + const char *s; + + for (s = str; s < end; s++) { + nm_assert(s[0] != '\0'); + + if (s[0] < 0x20) { + const char *text; + + switch (s[0]) { + case '\\': + text = "\\\\"; + break; + case '\"': + text = "\\\""; + break; + case '\b': + text = "\\b"; + break; + case '\f': + text = "\\f"; + break; + case '\n': + text = "\\n"; + break; + case '\r': + text = "\\r"; + break; + case '\t': + text = "\\t"; + break; + default: + g_string_append_printf(gstr, "\\u%04X", (guint) s[0]); + continue; + } + g_string_append(gstr, text); + continue; + } + + if (NM_IN_SET(s[0], '\\', '\"')) + g_string_append_c(gstr, '\\'); + g_string_append_c(gstr, s[0]); + } + } else + nm_assert(!valid); + + if (valid) { + nm_assert(end == &str[len]); + break; + } + + nm_assert(end < &str[len]); + + if (end[0] == '\0') { + /* there is a NUL byte in the string. Technically this is valid UTF-8, so we + * encode it there. However, this will likely result in a truncated string when + * parsing. */ + g_string_append(gstr, "\\u0000"); + } else { + /* the character is not valid UTF-8. There is nothing we can do about it, because + * JSON can only contain UTF-8 and even the escape sequences can only escape Unicode + * codepoints (but not binary). + * + * The argument is not a string (in any known encoding), hence we cannot represent + * it as a JSON string (which are unicode strings). + * + * Print an underscore instead of the invalid char :) */ + g_string_append_c(gstr, '_'); + } + + n = str - end; + nm_assert(n < len); + n++; + str += n; + len -= n; + } + + g_string_append_c(gstr, '\"'); +} + +void +nm_json_gstr_append_string_len(GString *gstr, const char *str, gsize n) +{ + g_return_if_fail(gstr); + + _gstr_append_string_len(gstr, str, n); +} + +void +nm_json_gstr_append_string(GString *gstr, const char *str) +{ + g_return_if_fail(gstr); + + if (!str) + g_string_append(gstr, "null"); + else + _gstr_append_string_len(gstr, str, strlen(str)); +} + +void +nm_json_gstr_append_obj_name(GString *gstr, const char *key, char start_container) +{ + g_return_if_fail(gstr); + g_return_if_fail(key); + + nm_json_gstr_append_string(gstr, key); + + if (start_container != '\0') { + nm_assert(NM_IN_SET(start_container, '[', '{')); + g_string_append_printf(gstr, ": %c ", start_container); + } else + g_string_append(gstr, ": "); +} + +/*****************************************************************************/ + +typedef struct { + NMJsonVt vt; + void * dl_handle; +} NMJsonVtInternal; + +static NMJsonVtInternal * +_nm_json_vt_internal_load(void) +{ + NMJsonVtInternal *v; + const char * soname; + void * handle; + + v = g_new0(NMJsonVtInternal, 1); + +#if WITH_JANSSON && defined(JANSSON_SONAME) + G_STATIC_ASSERT_EXPR(NM_STRLEN(JANSSON_SONAME) > 0); + nm_assert(strlen(JANSSON_SONAME) > 0); + soname = JANSSON_SONAME; +#elif !WITH_JANSSON && !defined(JANSSON_SONAME) + soname = NULL; +#else + #error "WITH_JANSON and JANSSON_SONAME are defined inconsistently." +#endif + + if (!soname) + return v; + + handle = dlopen(soname, + RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE +#if !defined(ASAN_BUILD) + | RTLD_DEEPBIND +#endif + | 0); + if (!handle) + return v; + +#define TRY_BIND_SYMBOL(symbol) \ + G_STMT_START \ + { \ + void *_sym = dlsym(handle, #symbol); \ + \ + if (!_sym) \ + goto fail_symbol; \ + v->vt.nm_##symbol = _sym; \ + } \ + G_STMT_END + + TRY_BIND_SYMBOL(json_array); + TRY_BIND_SYMBOL(json_array_append_new); + TRY_BIND_SYMBOL(json_array_get); + TRY_BIND_SYMBOL(json_array_size); + TRY_BIND_SYMBOL(json_delete); + TRY_BIND_SYMBOL(json_dumps); + TRY_BIND_SYMBOL(json_false); + TRY_BIND_SYMBOL(json_integer); + TRY_BIND_SYMBOL(json_integer_value); + TRY_BIND_SYMBOL(json_loads); + TRY_BIND_SYMBOL(json_object); + TRY_BIND_SYMBOL(json_object_del); + TRY_BIND_SYMBOL(json_object_get); + TRY_BIND_SYMBOL(json_object_iter); + TRY_BIND_SYMBOL(json_object_iter_key); + TRY_BIND_SYMBOL(json_object_iter_next); + TRY_BIND_SYMBOL(json_object_iter_value); + TRY_BIND_SYMBOL(json_object_key_to_iter); + TRY_BIND_SYMBOL(json_object_set_new); + TRY_BIND_SYMBOL(json_object_size); + TRY_BIND_SYMBOL(json_string); + TRY_BIND_SYMBOL(json_string_value); + TRY_BIND_SYMBOL(json_true); + + v->vt.loaded = TRUE; + v->dl_handle = handle; + return v; + +fail_symbol: + dlclose(&handle); + *v = (NMJsonVtInternal){}; + return v; +} + +const NMJsonVt *_nm_json_vt_ptr = NULL; + +const NMJsonVt * +_nm_json_vt_init(void) +{ + NMJsonVtInternal *v; + +again: + v = g_atomic_pointer_get((gpointer *) &_nm_json_vt_ptr); + if (G_UNLIKELY(!v)) { + v = _nm_json_vt_internal_load(); + if (!g_atomic_pointer_compare_and_exchange((gpointer *) &_nm_json_vt_ptr, NULL, v)) { + if (v->dl_handle) + dlclose(v->dl_handle); + g_free(v); + goto again; + } + + /* we transfer ownership. */ + } + + nm_assert(v && v == g_atomic_pointer_get((gpointer *) &_nm_json_vt_ptr)); + return &v->vt; +} + +const NMJsonVt * +nmtst_json_vt_reset(gboolean loaded) +{ + NMJsonVtInternal *v_old; + NMJsonVtInternal *v; + + v_old = g_atomic_pointer_get((gpointer *) &_nm_json_vt_ptr); + + if (!loaded) { + /* load a fake instance for testing. */ + v = g_new0(NMJsonVtInternal, 1); + } else + v = _nm_json_vt_internal_load(); + + if (!g_atomic_pointer_compare_and_exchange((gpointer *) &_nm_json_vt_ptr, v_old, v)) + g_assert_not_reached(); + + if (v_old) { + if (v_old->dl_handle) + dlclose(v_old->dl_handle); + g_free((gpointer *) v_old); + } + + return v->vt.loaded ? &v->vt : NULL; +} diff --git a/src/libnm-glib-aux/nm-json-aux.h b/src/libnm-glib-aux/nm-json-aux.h new file mode 100644 index 0000000..99759a8 --- /dev/null +++ b/src/libnm-glib-aux/nm-json-aux.h @@ -0,0 +1,312 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 - 2019 Red Hat, Inc. + */ + +#ifndef __NM_JSON_AUX_H__ +#define __NM_JSON_AUX_H__ + +#include "nm-value-type.h" + +/*****************************************************************************/ + +static inline GString * +nm_json_gstr_append_delimiter(GString *gstr) +{ + g_string_append(gstr, ", "); + return gstr; +} + +void nm_json_gstr_append_string_len(GString *gstr, const char *str, gsize n); + +void nm_json_gstr_append_string(GString *gstr, const char *str); + +static inline void +nm_json_gstr_append_bool(GString *gstr, gboolean v) +{ + g_string_append(gstr, v ? "true" : "false"); +} + +static inline void +nm_json_gstr_append_int64(GString *gstr, gint64 v) +{ + g_string_append_printf(gstr, "%" G_GINT64_FORMAT, v); +} + +void nm_json_gstr_append_obj_name(GString *gstr, const char *key, char start_container); + +/*****************************************************************************/ + +#define NM_JSON_REJECT_DUPLICATES 0x1 + +typedef enum { + NM_JSON_OBJECT, + NM_JSON_ARRAY, + NM_JSON_STRING, + NM_JSON_INTEGER, + NM_JSON_REAL, + NM_JSON_TRUE, + NM_JSON_FALSE, + NM_JSON_NULL, +} nm_json_type; + +typedef struct nm_json_t { + nm_json_type type; + volatile size_t refcount; +} nm_json_t; + +typedef long long nm_json_int_t; + +#define NM_JSON_ERROR_TEXT_LENGTH 160 +#define NM_JSON_ERROR_SOURCE_LENGTH 80 + +typedef struct nm_json_error_t { + int line; + int column; + int position; + char source[NM_JSON_ERROR_SOURCE_LENGTH]; + char text[NM_JSON_ERROR_TEXT_LENGTH]; +} nm_json_error_t; + +typedef struct { + gboolean loaded; + char *(*nm_json_dumps)(const nm_json_t *json, size_t flags); + const char *(*nm_json_object_iter_key)(void *iter); + const char *(*nm_json_string_value)(const nm_json_t *json); + int (*nm_json_array_append_new)(nm_json_t *json, nm_json_t *value); + int (*nm_json_object_del)(nm_json_t *json, const char *key); + int (*nm_json_object_set_new)(nm_json_t *json, const char *key, nm_json_t *value); + nm_json_int_t (*nm_json_integer_value)(const nm_json_t *json); + nm_json_t *(*nm_json_array)(void); + nm_json_t *(*nm_json_array_get)(const nm_json_t *json, size_t index); + nm_json_t *(*nm_json_false)(void); + nm_json_t *(*nm_json_integer)(nm_json_int_t value); + nm_json_t *(*nm_json_loads)(const char *string, size_t flags, nm_json_error_t *error); + nm_json_t *(*nm_json_object)(void); + nm_json_t *(*nm_json_object_get)(const nm_json_t *json, const char *key); + nm_json_t *(*nm_json_object_iter_value)(void *); + nm_json_t *(*nm_json_string)(const char *value); + nm_json_t *(*nm_json_true)(void); + size_t (*nm_json_array_size)(const nm_json_t *json); + size_t (*nm_json_object_size)(const nm_json_t *json); + void (*nm_json_delete)(nm_json_t *json); + void *(*nm_json_object_iter)(nm_json_t *json); + void *(*nm_json_object_iter_next)(nm_json_t *json, void *iter); + void *(*nm_json_object_key_to_iter)(const char *key); +} NMJsonVt; + +extern const NMJsonVt *_nm_json_vt_ptr; + +const NMJsonVt *_nm_json_vt_init(void); + +static inline const NMJsonVt * +_nm_json_vt(void) +{ + const NMJsonVt *vt; + + vt = g_atomic_pointer_get((gpointer *) &_nm_json_vt_ptr); + if (G_UNLIKELY(!vt)) { + vt = _nm_json_vt_init(); + nm_assert(vt); + } + return vt; +} + +static inline const NMJsonVt * +nm_json_vt(void) +{ + const NMJsonVt *vt; + + vt = _nm_json_vt(); + return vt->loaded ? vt : NULL; +} + +static inline const NMJsonVt * +nm_json_vt_assert(void) +{ + const NMJsonVt *vt; + + vt = _nm_json_vt(); + nm_assert(vt->loaded); + return vt; +} + +const NMJsonVt *nmtst_json_vt_reset(gboolean loaded); + +/*****************************************************************************/ + +#define nm_json_boolean(vt, val) ((val) ? (vt)->nm_json_true() : (vt)->nm_json_false()) + +static inline void +nm_json_decref(const NMJsonVt *vt, nm_json_t *json) +{ + /* Our ref-counting is not threadsafe, unlike libjansson's. But we never + * share one json_t instance between threads, and if we would, we would very likely + * wrap a mutex around it. */ + if (json && json->refcount != (size_t) -1 && --json->refcount == 0) + vt->nm_json_delete(json); +} + +static inline void +_nm_auto_decref_json(nm_json_t **p_json) +{ + if (*p_json && (*p_json)->refcount != (size_t) -1 && --(*p_json)->refcount == 0) + nm_json_vt()->nm_json_delete(*p_json); +} + +#define nm_auto_decref_json nm_auto(_nm_auto_decref_json) + +/*****************************************************************************/ + +/* the following are implemented as pure macros in jansson.h. + * They can be used directly, however, add a nm_json* variant, + * to make it explict we don't accidentally use jansson ABI. */ + +#define nm_json_typeof(json) ((json)->type) +#define nm_json_is_object(json) ((json) && nm_json_typeof(json) == NM_JSON_OBJECT) +#define nm_json_is_array(json) ((json) && nm_json_typeof(json) == NM_JSON_ARRAY) +#define nm_json_is_string(json) ((json) && nm_json_typeof(json) == NM_JSON_STRING) +#define nm_json_is_integer(json) ((json) && nm_json_typeof(json) == NM_JSON_INTEGER) +#define nm_json_is_real(json) ((json) && nm_json_typeof(json) == NM_JSON_REAL) +#define nm_json_is_number(json) (nm_json_is_integer(json) || nm_json_is_real(json)) +#define nm_json_is_true(json) ((json) && nm_json_typeof(json) == NM_JSON_TRUE) +#define nm_json_is_false(json) ((json) && nm_json_typeof(json) == NM_JSON_FALSE) +#define nm_json_boolean_value nm_json_is_true +#define nm_json_is_boolean(json) (nm_json_is_true(json) || nm_json_is_false(json)) +#define nm_json_is_null(json) ((json) && nm_json_typeof(json) == NM_JSON_NULL) + +#define nm_json_array_foreach(vt, array, index, value) \ + for (index = 0; \ + index < vt->nm_json_array_size(array) && (value = vt->nm_json_array_get(array, index)); \ + index++) + +#define nm_json_object_foreach(vt, object, key, value) \ + for (key = vt->nm_json_object_iter_key(vt->nm_json_object_iter(object)); \ + key && (value = vt->nm_json_object_iter_value(vt->nm_json_object_key_to_iter(key))); \ + key = vt->nm_json_object_iter_key( \ + vt->nm_json_object_iter_next(object, vt->nm_json_object_key_to_iter(key)))) + +/*****************************************************************************/ + +static inline int +nm_jansson_json_as_bool(const nm_json_t *elem, bool *out_val) +{ + if (!elem) + return 0; + + if (!nm_json_is_boolean(elem)) + return -EINVAL; + + NM_SET_OUT(out_val, nm_json_boolean_value(elem)); + return 1; +} + +static inline int +nm_jansson_json_as_int32(const NMJsonVt *vt, const nm_json_t *elem, gint32 *out_val) +{ + nm_json_int_t v; + + if (!elem) + return 0; + + if (!nm_json_is_integer(elem)) + return -EINVAL; + + v = vt->nm_json_integer_value(elem); + if (v < (gint64) G_MININT32 || v > (gint64) G_MAXINT32) + return -ERANGE; + + NM_SET_OUT(out_val, v); + return 1; +} + +static inline int +nm_jansson_json_as_int(const NMJsonVt *vt, const nm_json_t *elem, int *out_val) +{ + nm_json_int_t v; + + if (!elem) + return 0; + + if (!nm_json_is_integer(elem)) + return -EINVAL; + + v = vt->nm_json_integer_value(elem); + if (v < (gint64) G_MININT || v > (gint64) G_MAXINT) + return -ERANGE; + + NM_SET_OUT(out_val, v); + return 1; +} + +static inline int +nm_jansson_json_as_string(const NMJsonVt *vt, const nm_json_t *elem, const char **out_val) +{ + if (!elem) + return 0; + + if (!nm_json_is_string(elem)) + return -EINVAL; + + NM_SET_OUT(out_val, vt->nm_json_string_value(elem)); + return 1; +} + +/*****************************************************************************/ + +#ifdef NM_VALUE_TYPE_DEFINE_FUNCTIONS + +static inline void +nm_value_type_to_json(NMValueType value_type, GString *gstr, gconstpointer p_field) +{ + nm_assert(p_field); + nm_assert(gstr); + + switch (value_type) { + case NM_VALUE_TYPE_BOOL: + nm_json_gstr_append_bool(gstr, *((const bool *) p_field)); + return; + case NM_VALUE_TYPE_INT32: + nm_json_gstr_append_int64(gstr, *((const gint32 *) p_field)); + return; + case NM_VALUE_TYPE_INT: + nm_json_gstr_append_int64(gstr, *((const int *) p_field)); + return; + case NM_VALUE_TYPE_STRING: + nm_json_gstr_append_string(gstr, *((const char *const *) p_field)); + return; + case NM_VALUE_TYPE_UNSPEC: + break; + } + nm_assert_not_reached(); +} + +static inline gboolean +nm_value_type_from_json(const NMJsonVt * vt, + NMValueType value_type, + const nm_json_t *elem, + gpointer out_val) +{ + switch (value_type) { + case NM_VALUE_TYPE_BOOL: + return (nm_jansson_json_as_bool(elem, out_val) > 0); + case NM_VALUE_TYPE_INT32: + return (nm_jansson_json_as_int32(vt, elem, out_val) > 0); + case NM_VALUE_TYPE_INT: + return (nm_jansson_json_as_int(vt, elem, out_val) > 0); + + /* warning: this overwrites/leaks the previous value. You better have *out_val + * point to uninitialized memory or NULL. */ + case NM_VALUE_TYPE_STRING: + return (nm_jansson_json_as_string(vt, elem, out_val) > 0); + + case NM_VALUE_TYPE_UNSPEC: + break; + } + nm_assert_not_reached(); + return FALSE; +} + +#endif /* NM_VALUE_TYPE_DEFINE_FUNCTIONS */ + +#endif /* __NM_JSON_AUX_H__ */ diff --git a/src/libnm-glib-aux/nm-keyfile-aux.c b/src/libnm-glib-aux/nm-keyfile-aux.c new file mode 100644 index 0000000..75abe53 --- /dev/null +++ b/src/libnm-glib-aux/nm-keyfile-aux.c @@ -0,0 +1,373 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-keyfile-aux.h" + +#include +#include +#include + +#include "nm-io-utils.h" + +/*****************************************************************************/ + +struct _NMKeyFileDB { + NMKeyFileDBLogFcn log_fcn; + NMKeyFileDBGotDirtyFcn got_dirty_fcn; + gpointer user_data; + const char * group_name; + GKeyFile * kf; + guint ref_count; + + bool is_started : 1; + bool dirty : 1; + bool destroyed : 1; + + char filename[]; +}; + +#define _NMLOG(self, syslog_level, fmt, ...) \ + G_STMT_START \ + { \ + NMKeyFileDB *_self = (self); \ + \ + nm_assert(_self); \ + nm_assert(!_self->destroyed); \ + \ + if (_self->log_fcn) { \ + _self->log_fcn(_self, (syslog_level), _self->user_data, "" fmt "", ##__VA_ARGS__); \ + }; \ + } \ + G_STMT_END + +#define _LOGD(...) _NMLOG(self, LOG_DEBUG, __VA_ARGS__) + +static gboolean +_IS_KEY_FILE_DB(NMKeyFileDB *self, gboolean require_is_started, gboolean allow_destroyed) +{ + if (self == NULL) + return FALSE; + if (self->ref_count <= 0) { + nm_assert_not_reached(); + return FALSE; + } + if (require_is_started && !self->is_started) + return FALSE; + if (!allow_destroyed && self->destroyed) + return FALSE; + return TRUE; +} + +/*****************************************************************************/ + +NMKeyFileDB * +nm_key_file_db_new(const char * filename, + const char * group_name, + NMKeyFileDBLogFcn log_fcn, + NMKeyFileDBGotDirtyFcn got_dirty_fcn, + gpointer user_data) +{ + NMKeyFileDB *self; + gsize l_filename; + gsize l_group; + + g_return_val_if_fail(filename && filename[0], NULL); + g_return_val_if_fail(group_name && group_name[0], NULL); + + l_filename = strlen(filename); + l_group = strlen(group_name); + + self = g_malloc0(sizeof(NMKeyFileDB) + l_filename + 1 + l_group + 1); + self->ref_count = 1; + self->log_fcn = log_fcn; + self->got_dirty_fcn = got_dirty_fcn; + self->user_data = user_data; + self->kf = g_key_file_new(); + g_key_file_set_list_separator(self->kf, ','); + memcpy(self->filename, filename, l_filename + 1); + self->group_name = &self->filename[l_filename + 1]; + memcpy((char *) self->group_name, group_name, l_group + 1); + + return self; +} + +NMKeyFileDB * +nm_key_file_db_ref(NMKeyFileDB *self) +{ + if (!self) + return NULL; + + g_return_val_if_fail(_IS_KEY_FILE_DB(self, FALSE, TRUE), NULL); + + nm_assert(self->ref_count < G_MAXUINT); + self->ref_count++; + return self; +} + +void +nm_key_file_db_unref(NMKeyFileDB *self) +{ + if (!self) + return; + + g_return_if_fail(_IS_KEY_FILE_DB(self, FALSE, TRUE)); + + if (--self->ref_count > 0) + return; + + g_key_file_unref(self->kf); + + g_free(self); +} + +/* destroy() is like unref, but it also makes the instance unusable. + * All changes afterwards fail with an assertion. + * + * The point is that NMKeyFileDB is ref-counted in principle. But there + * is a primary owner who also provides the log_fcn(). + * + * When the primary owner goes out of scope and gives up the reference, it does + * not want to receive any log notifications anymore. + * + * The way NMKeyFileDB is intended to be used is in a very strict context: + * NMSettings owns the NMKeyFileDB instance and receives logging notifications. + * It's also the last one to persist the data to disk. Afterwards, no other user + * is supposed to be around and do anything with NMKeyFileDB. But since NMKeyFileDB + * is ref-counted it's hard to ensure that this is truly honored. So we start + * asserting at that point. + */ +void +nm_key_file_db_destroy(NMKeyFileDB *self) +{ + if (!self) + return; + + g_return_if_fail(_IS_KEY_FILE_DB(self, FALSE, FALSE)); + g_return_if_fail(!self->destroyed); + + self->destroyed = TRUE; + nm_key_file_db_unref(self); +} + +/*****************************************************************************/ + +/* nm_key_file_db_start() is supposed to be called right away, after creating the + * instance. + * + * It's not done as separate step after nm_key_file_db_new(), because we want to log, + * and the log_fcn returns the self pointer (which we should not expose before + * nm_key_file_db_new() returns. */ +void +nm_key_file_db_start(NMKeyFileDB *self) +{ + gs_free char *contents = NULL; + gsize contents_len; + gs_free_error GError *error = NULL; + + g_return_if_fail(_IS_KEY_FILE_DB(self, FALSE, FALSE)); + g_return_if_fail(!self->is_started); + + self->is_started = TRUE; + + if (!nm_utils_file_get_contents(-1, + self->filename, + 20 * 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, + &contents, + &contents_len, + NULL, + &error)) { + _LOGD("failed to read \"%s\": %s", self->filename, error->message); + return; + } + + if (!g_key_file_load_from_data(self->kf, + contents, + contents_len, + G_KEY_FILE_KEEP_COMMENTS, + &error)) { + _LOGD("failed to load keyfile \"%s\": %s", self->filename, error->message); + return; + } + + _LOGD("loaded keyfile-db for \"%s\"", self->filename); +} + +/*****************************************************************************/ + +const char * +nm_key_file_db_get_filename(NMKeyFileDB *self) +{ + g_return_val_if_fail(_IS_KEY_FILE_DB(self, FALSE, TRUE), NULL); + + return self->filename; +} + +gboolean +nm_key_file_db_is_dirty(NMKeyFileDB *self) +{ + g_return_val_if_fail(_IS_KEY_FILE_DB(self, FALSE, TRUE), FALSE); + + return self->dirty; +} + +/*****************************************************************************/ + +char * +nm_key_file_db_get_value(NMKeyFileDB *self, const char *key) +{ + g_return_val_if_fail(_IS_KEY_FILE_DB(self, TRUE, TRUE), NULL); + + return g_key_file_get_value(self->kf, self->group_name, key, NULL); +} + +char ** +nm_key_file_db_get_string_list(NMKeyFileDB *self, const char *key, gsize *out_len) +{ + g_return_val_if_fail(_IS_KEY_FILE_DB(self, TRUE, TRUE), NULL); + + return g_key_file_get_string_list(self->kf, self->group_name, key, out_len, NULL); +} + +/*****************************************************************************/ + +static void +_got_dirty(NMKeyFileDB *self, const char *key) +{ + nm_assert(_IS_KEY_FILE_DB(self, TRUE, FALSE)); + nm_assert(!self->dirty); + + _LOGD("updated entry for %s.%s", self->group_name, key); + + self->dirty = TRUE; + if (self->got_dirty_fcn) + self->got_dirty_fcn(self, self->user_data); +} + +/*****************************************************************************/ + +void +nm_key_file_db_remove_key(NMKeyFileDB *self, const char *key) +{ + gboolean got_dirty = FALSE; + + g_return_if_fail(_IS_KEY_FILE_DB(self, TRUE, FALSE)); + + if (!key) + return; + + if (!self->dirty) { + gs_free_error GError *error = NULL; + + g_key_file_has_key(self->kf, self->group_name, key, &error); + got_dirty = (error != NULL); + } + g_key_file_remove_key(self->kf, self->group_name, key, NULL); + + if (got_dirty) + _got_dirty(self, key); +} + +void +nm_key_file_db_set_value(NMKeyFileDB *self, const char *key, const char *value) +{ + gs_free char *old_value = NULL; + gboolean got_dirty = FALSE; + + g_return_if_fail(_IS_KEY_FILE_DB(self, TRUE, FALSE)); + g_return_if_fail(key); + + if (!value) { + nm_key_file_db_remove_key(self, key); + return; + } + + if (!self->dirty) { + gs_free_error GError *error = NULL; + + old_value = g_key_file_get_value(self->kf, self->group_name, key, &error); + if (error) + got_dirty = TRUE; + } + + g_key_file_set_value(self->kf, self->group_name, key, value); + + if (!self->dirty && !got_dirty) { + gs_free_error GError *error = NULL; + gs_free char * new_value = NULL; + + new_value = g_key_file_get_value(self->kf, self->group_name, key, &error); + if (error || !new_value || !nm_streq0(old_value, new_value)) + got_dirty = TRUE; + } + + if (got_dirty) + _got_dirty(self, key); +} + +void +nm_key_file_db_set_string_list(NMKeyFileDB * self, + const char * key, + const char *const *value, + gssize len) +{ + gs_free char *old_value = NULL; + gboolean got_dirty = FALSE; + + g_return_if_fail(_IS_KEY_FILE_DB(self, TRUE, FALSE)); + g_return_if_fail(key); + + if (!value) { + nm_key_file_db_remove_key(self, key); + return; + } + + if (!self->dirty) { + gs_free_error GError *error = NULL; + + old_value = g_key_file_get_value(self->kf, self->group_name, key, &error); + if (error) + got_dirty = TRUE; + } + + if (len < 0) + len = NM_PTRARRAY_LEN(value); + + g_key_file_set_string_list(self->kf, self->group_name, key, value, len); + + if (!self->dirty && !got_dirty) { + gs_free_error GError *error = NULL; + gs_free char * new_value = NULL; + + new_value = g_key_file_get_value(self->kf, self->group_name, key, &error); + if (error || !new_value || !nm_streq0(old_value, new_value)) + got_dirty = TRUE; + } + + if (got_dirty) + _got_dirty(self, key); +} + +/*****************************************************************************/ + +void +nm_key_file_db_to_file(NMKeyFileDB *self, gboolean force) +{ + gs_free_error GError *error = NULL; + + g_return_if_fail(_IS_KEY_FILE_DB(self, TRUE, FALSE)); + + if (!force && !self->dirty) + return; + + self->dirty = FALSE; + + if (!g_key_file_save_to_file(self->kf, self->filename, &error)) { + _LOGD("failure to write keyfile \"%s\": %s", self->filename, error->message); + } else + _LOGD("write keyfile: \"%s\"", self->filename); +} diff --git a/src/libnm-glib-aux/nm-keyfile-aux.h b/src/libnm-glib-aux/nm-keyfile-aux.h new file mode 100644 index 0000000..72d2f41 --- /dev/null +++ b/src/libnm-glib-aux/nm-keyfile-aux.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#ifndef __NM_KEYFILE_AUX_H__ +#define __NM_KEYFILE_AUX_H__ + +/*****************************************************************************/ + +typedef struct _NMKeyFileDB NMKeyFileDB; + +typedef void (*NMKeyFileDBLogFcn)(NMKeyFileDB *self, + int syslog_level, + gpointer user_data, + const char * fmt, + ...) G_GNUC_PRINTF(4, 5); + +typedef void (*NMKeyFileDBGotDirtyFcn)(NMKeyFileDB *self, gpointer user_data); + +NMKeyFileDB *nm_key_file_db_new(const char * filename, + const char * group, + NMKeyFileDBLogFcn log_fcn, + NMKeyFileDBGotDirtyFcn got_dirty_fcn, + gpointer user_data); + +void nm_key_file_db_start(NMKeyFileDB *self); + +NMKeyFileDB *nm_key_file_db_ref(NMKeyFileDB *self); +void nm_key_file_db_unref(NMKeyFileDB *self); + +void nm_key_file_db_destroy(NMKeyFileDB *self); + +const char *nm_key_file_db_get_filename(NMKeyFileDB *self); + +gboolean nm_key_file_db_is_dirty(NMKeyFileDB *self); + +char *nm_key_file_db_get_value(NMKeyFileDB *self, const char *key); + +char **nm_key_file_db_get_string_list(NMKeyFileDB *self, const char *key, gsize *out_len); + +void nm_key_file_db_remove_key(NMKeyFileDB *self, const char *key); + +void nm_key_file_db_set_value(NMKeyFileDB *self, const char *key, const char *value); + +void nm_key_file_db_set_string_list(NMKeyFileDB * self, + const char * key, + const char *const *value, + gssize len); + +void nm_key_file_db_to_file(NMKeyFileDB *self, gboolean force); + +/*****************************************************************************/ + +#endif /* __NM_KEYFILE_AUX_H__ */ diff --git a/src/libnm-glib-aux/nm-logging-base.c b/src/libnm-glib-aux/nm-logging-base.c new file mode 100644 index 0000000..e11bd9f --- /dev/null +++ b/src/libnm-glib-aux/nm-logging-base.c @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-logging-base.h" + +#include + +/*****************************************************************************/ + +const LogLevelDesc nm_log_level_desc[_LOGL_N] = { + [LOGL_TRACE] = + { + "TRACE", + "", + LOG_DEBUG, + G_LOG_LEVEL_DEBUG, + }, + [LOGL_DEBUG] = + { + "DEBUG", + "", + LOG_DEBUG, + G_LOG_LEVEL_DEBUG, + }, + [LOGL_INFO] = + { + "INFO", + "", + LOG_INFO, + G_LOG_LEVEL_INFO, + }, + [LOGL_WARN] = + { + "WARN", + "", + LOG_WARNING, + G_LOG_LEVEL_MESSAGE, + }, + [LOGL_ERR] = + { + "ERR", + "", + LOG_ERR, + G_LOG_LEVEL_MESSAGE, + }, + [_LOGL_OFF] = + { + "OFF", + NULL, + 0, + 0, + }, + [_LOGL_KEEP] = + { + "KEEP", + NULL, + 0, + 0, + }, +}; + +gboolean +_nm_log_parse_level(const char *level, NMLogLevel *out_level) +{ + int i; + + if (!level) + return FALSE; + + for (i = 0; i < (int) G_N_ELEMENTS(nm_log_level_desc); i++) { + if (!g_ascii_strcasecmp(nm_log_level_desc[i].name, level)) { + NM_SET_OUT(out_level, i); + return TRUE; + } + } + + return FALSE; +} diff --git a/src/libnm-glib-aux/nm-logging-base.h b/src/libnm-glib-aux/nm-logging-base.h new file mode 100644 index 0000000..136f0c0 --- /dev/null +++ b/src/libnm-glib-aux/nm-logging-base.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_LOGGING_BASE_H__ +#define __NM_LOGGING_BASE_H__ + +#include "nm-logging-fwd.h" + +typedef struct { + const char *name; + const char *level_str; + + /* nm-logging uses syslog internally. Note that the three most-verbose syslog levels + * are LOG_DEBUG, LOG_INFO and LOG_NOTICE. Journal already highlights LOG_NOTICE + * as special. + * + * On the other hand, we have three levels LOGL_TRACE, LOGL_DEBUG and LOGL_INFO, + * which are regular messages not to be highlighted. For that reason, we must map + * LOGL_TRACE and LOGL_DEBUG both to syslog level LOG_DEBUG. */ + int syslog_level; + + GLogLevelFlags g_log_level; +} LogLevelDesc; + +extern const LogLevelDesc nm_log_level_desc[_LOGL_N]; + +gboolean _nm_log_parse_level(const char *level, NMLogLevel *out_level); + +#endif /* __NM_LOGGING_BASE_H__ */ diff --git a/src/libnm-glib-aux/nm-logging-fwd.h b/src/libnm-glib-aux/nm-logging-fwd.h new file mode 100644 index 0000000..df0bb16 --- /dev/null +++ b/src/libnm-glib-aux/nm-logging-fwd.h @@ -0,0 +1,308 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2006 - 2018 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#ifndef __NM_LOGGING_FWD_H__ +#define __NM_LOGGING_FWD_H__ + +/* Log domains */ + +typedef enum { /*< skip >*/ + LOGD_NONE = 0LL, + LOGD_PLATFORM = (1LL << 0), /* Platform services */ + LOGD_RFKILL = (1LL << 1), + LOGD_ETHER = (1LL << 2), + LOGD_WIFI = (1LL << 3), + LOGD_BT = (1LL << 4), + LOGD_MB = (1LL << 5), /* mobile broadband */ + LOGD_DHCP4 = (1LL << 6), + LOGD_DHCP6 = (1LL << 7), + LOGD_PPP = (1LL << 8), + LOGD_WIFI_SCAN = (1LL << 9), + LOGD_IP4 = (1LL << 10), + LOGD_IP6 = (1LL << 11), + LOGD_AUTOIP4 = (1LL << 12), + LOGD_DNS = (1LL << 13), + LOGD_VPN = (1LL << 14), + LOGD_SHARING = (1LL << 15), /* Connection sharing/dnsmasq */ + LOGD_SUPPLICANT = (1LL << 16), /* Wi-Fi and 802.1x */ + LOGD_AGENTS = (1LL << 17), /* Secret agents */ + LOGD_SETTINGS = (1LL << 18), /* Settings */ + LOGD_SUSPEND = (1LL << 19), /* Suspend/Resume */ + LOGD_CORE = (1LL << 20), /* Core daemon and policy stuff */ + LOGD_DEVICE = (1LL << 21), /* Device state and activation */ + LOGD_OLPC = (1LL << 22), + LOGD_INFINIBAND = (1LL << 23), + LOGD_FIREWALL = (1LL << 24), + LOGD_ADSL = (1LL << 25), + LOGD_BOND = (1LL << 26), + LOGD_VLAN = (1LL << 27), + LOGD_BRIDGE = (1LL << 28), + LOGD_DBUS_PROPS = (1LL << 29), + LOGD_TEAM = (1LL << 30), + LOGD_CONCHECK = (1LL << 31), + LOGD_DCB = (1LL << 32), /* Data Center Bridging */ + LOGD_DISPATCH = (1LL << 33), + LOGD_AUDIT = (1LL << 34), + LOGD_SYSTEMD = (1LL << 35), + LOGD_VPN_PLUGIN = (1LL << 36), + LOGD_PROXY = (1LL << 37), + + __LOGD_MAX, + LOGD_ALL = (((__LOGD_MAX - 1LL) << 1) - 1LL), + LOGD_DEFAULT = LOGD_ALL & ~(LOGD_DBUS_PROPS | LOGD_WIFI_SCAN | LOGD_VPN_PLUGIN | 0), + + /* aliases: */ + LOGD_DHCP = LOGD_DHCP4 | LOGD_DHCP6, + LOGD_IP = LOGD_IP4 | LOGD_IP6, + +#define LOGD_DHCPX(is_ipv4) ((is_ipv4) ? LOGD_DHCP4 : LOGD_DHCP6) +#define LOGD_IPX(is_ipv4) ((is_ipv4) ? LOGD_IP4 : LOGD_IP6) + +} NMLogDomain; + +/* Log levels */ +typedef enum { /*< skip >*/ + LOGL_TRACE, + LOGL_DEBUG, + LOGL_INFO, + LOGL_WARN, + LOGL_ERR, + + _LOGL_N_REAL, /* the number of actual logging levels */ + + _LOGL_OFF = _LOGL_N_REAL, /* special logging level that is always disabled. */ + _LOGL_KEEP, /* special logging level to indicate that the logging level should not be changed. */ + + _LOGL_N, /* the number of logging levels including "OFF" */ +} NMLogLevel; + +gboolean _nm_log_enabled_impl(gboolean mt_require_locking, NMLogLevel level, NMLogDomain domain); + +void _nm_log_impl(const char *file, + guint line, + const char *func, + gboolean mt_require_locking, + NMLogLevel level, + NMLogDomain domain, + int error, + const char *ifname, + const char *con_uuid, + const char *fmt, + ...) _nm_printf(10, 11); + +static inline NMLogLevel +nm_log_level_from_syslog(int syslog_level) +{ + switch (syslog_level) { + case 0 /* LOG_EMERG */: + return LOGL_ERR; + case 1 /* LOG_ALERT */: + return LOGL_ERR; + case 2 /* LOG_CRIT */: + return LOGL_ERR; + case 3 /* LOG_ERR */: + return LOGL_ERR; + case 4 /* LOG_WARNING */: + return LOGL_WARN; + case 5 /* LOG_NOTICE */: + return LOGL_INFO; + case 6 /* LOG_INFO */: + return LOGL_DEBUG; + case 7 /* LOG_DEBUG */: + return LOGL_TRACE; + default: + return syslog_level >= 0 ? LOGL_TRACE : LOGL_ERR; + } +} + +static inline int +nm_log_level_to_syslog(NMLogLevel nm_level) +{ + switch (nm_level) { + case LOGL_ERR: + return 3; /* LOG_ERR */ + case LOGL_WARN: + return 4; /* LOG_WARN */ + case LOGL_INFO: + return 5; /* LOG_NOTICE */ + case LOGL_DEBUG: + return 6; /* LOG_INFO */ + case LOGL_TRACE: + return 7; /* LOG_DEBUG */ + default: + return 0; /* LOG_EMERG */ + } +} + +/*****************************************************************************/ + +struct timespec; + +/* this function must be implemented to handle the notification when + * the first monotonic-timestamp is fetched. */ +extern void _nm_utils_monotonic_timestamp_initialized(const struct timespec *tp, + gint64 offset_sec, + gboolean is_boottime); + +/*****************************************************************************/ + +#define _LOGL_TRACE LOGL_TRACE +#define _LOGL_DEBUG LOGL_DEBUG +#define _LOGL_INFO LOGL_INFO +#define _LOGL_WARN LOGL_WARN +#define _LOGL_ERR LOGL_ERR + +/* This is the default definition of _NMLOG_ENABLED(). Special implementations + * might want to undef this and redefine it. */ +#define _NMLOG_ENABLED(level) (nm_logging_enabled((level), (_NMLOG_DOMAIN))) + +#define _LOGT(...) _NMLOG(_LOGL_TRACE, __VA_ARGS__) +#define _LOGD(...) _NMLOG(_LOGL_DEBUG, __VA_ARGS__) +#define _LOGI(...) _NMLOG(_LOGL_INFO, __VA_ARGS__) +#define _LOGW(...) _NMLOG(_LOGL_WARN, __VA_ARGS__) +#define _LOGE(...) _NMLOG(_LOGL_ERR, __VA_ARGS__) + +#define _LOGT_ENABLED(...) _NMLOG_ENABLED(_LOGL_TRACE, ##__VA_ARGS__) +#define _LOGD_ENABLED(...) _NMLOG_ENABLED(_LOGL_DEBUG, ##__VA_ARGS__) +#define _LOGI_ENABLED(...) _NMLOG_ENABLED(_LOGL_INFO, ##__VA_ARGS__) +#define _LOGW_ENABLED(...) _NMLOG_ENABLED(_LOGL_WARN, ##__VA_ARGS__) +#define _LOGE_ENABLED(...) _NMLOG_ENABLED(_LOGL_ERR, ##__VA_ARGS__) + +#define _LOGT_err(errsv, ...) _NMLOG_err(errsv, _LOGL_TRACE, __VA_ARGS__) +#define _LOGD_err(errsv, ...) _NMLOG_err(errsv, _LOGL_DEBUG, __VA_ARGS__) +#define _LOGI_err(errsv, ...) _NMLOG_err(errsv, _LOGL_INFO, __VA_ARGS__) +#define _LOGW_err(errsv, ...) _NMLOG_err(errsv, _LOGL_WARN, __VA_ARGS__) +#define _LOGE_err(errsv, ...) _NMLOG_err(errsv, _LOGL_ERR, __VA_ARGS__) + +/* _LOGT() and _LOGt() both log with level TRACE, but the latter is disabled by default, + * unless building with --with-more-logging. */ +#if NM_MORE_LOGGING + #define _LOGt_ENABLED(...) _NMLOG_ENABLED(_LOGL_TRACE, ##__VA_ARGS__) + #define _LOGt(...) _NMLOG(_LOGL_TRACE, __VA_ARGS__) + #define _LOGt_err(errsv, ...) _NMLOG_err(errsv, _LOGL_TRACE, __VA_ARGS__) +#else + /* still call the logging macros to get compile time checks, but they will be optimized out. */ + #define _LOGt_ENABLED(...) (FALSE && (_NMLOG_ENABLED(_LOGL_TRACE, ##__VA_ARGS__))) + #define _LOGt(...) \ + G_STMT_START \ + { \ + if (FALSE) { \ + _NMLOG(_LOGL_TRACE, __VA_ARGS__); \ + } \ + } \ + G_STMT_END + #define _LOGt_err(errsv, ...) \ + G_STMT_START \ + { \ + if (FALSE) { \ + _NMLOG_err(errsv, _LOGL_TRACE, __VA_ARGS__); \ + } \ + } \ + G_STMT_END +#endif + +/*****************************************************************************/ + +/* Some implementation define a second set of logging macros, for a separate + * use. As with the _LOGD() macro family above, the exact implementation + * depends on the file that uses them. + * Still, it encourages a common pattern to have the common set of macros + * like _LOG2D(), _LOG2I(), etc. and have _LOG2t() which by default + * is disabled at compile time. */ + +#define _NMLOG2_ENABLED(level) (nm_logging_enabled((level), (_NMLOG2_DOMAIN))) + +#define _LOG2T(...) _NMLOG2(_LOGL_TRACE, __VA_ARGS__) +#define _LOG2D(...) _NMLOG2(_LOGL_DEBUG, __VA_ARGS__) +#define _LOG2I(...) _NMLOG2(_LOGL_INFO, __VA_ARGS__) +#define _LOG2W(...) _NMLOG2(_LOGL_WARN, __VA_ARGS__) +#define _LOG2E(...) _NMLOG2(_LOGL_ERR, __VA_ARGS__) + +#define _LOG2T_ENABLED(...) _NMLOG2_ENABLED(_LOGL_TRACE, ##__VA_ARGS__) +#define _LOG2D_ENABLED(...) _NMLOG2_ENABLED(_LOGL_DEBUG, ##__VA_ARGS__) +#define _LOG2I_ENABLED(...) _NMLOG2_ENABLED(_LOGL_INFO, ##__VA_ARGS__) +#define _LOG2W_ENABLED(...) _NMLOG2_ENABLED(_LOGL_WARN, ##__VA_ARGS__) +#define _LOG2E_ENABLED(...) _NMLOG2_ENABLED(_LOGL_ERR, ##__VA_ARGS__) + +#define _LOG2T_err(errsv, ...) _NMLOG2_err(errsv, _LOGL_TRACE, __VA_ARGS__) +#define _LOG2D_err(errsv, ...) _NMLOG2_err(errsv, _LOGL_DEBUG, __VA_ARGS__) +#define _LOG2I_err(errsv, ...) _NMLOG2_err(errsv, _LOGL_INFO, __VA_ARGS__) +#define _LOG2W_err(errsv, ...) _NMLOG2_err(errsv, _LOGL_WARN, __VA_ARGS__) +#define _LOG2E_err(errsv, ...) _NMLOG2_err(errsv, _LOGL_ERR, __VA_ARGS__) + +#if NM_MORE_LOGGING + #define _LOG2t_ENABLED(...) _NMLOG2_ENABLED(_LOGL_TRACE, ##__VA_ARGS__) + #define _LOG2t(...) _NMLOG2(_LOGL_TRACE, __VA_ARGS__) + #define _LOG2t_err(errsv, ...) _NMLOG2_err(errsv, _LOGL_TRACE, __VA_ARGS__) +#else + /* still call the logging macros to get compile time checks, but they will be optimized out. */ + #define _LOG2t_ENABLED(...) (FALSE && (_NMLOG2_ENABLED(_LOGL_TRACE, ##__VA_ARGS__))) + #define _LOG2t(...) \ + G_STMT_START \ + { \ + if (FALSE) { \ + _NMLOG2(_LOGL_TRACE, __VA_ARGS__); \ + } \ + } \ + G_STMT_END + #define _LOG2t_err(errsv, ...) \ + G_STMT_START \ + { \ + if (FALSE) { \ + _NMLOG2_err(errsv, _LOGL_TRACE, __VA_ARGS__); \ + } \ + } \ + G_STMT_END +#endif + +#define _NMLOG3_ENABLED(level) (nm_logging_enabled((level), (_NMLOG3_DOMAIN))) + +#define _LOG3T(...) _NMLOG3(_LOGL_TRACE, __VA_ARGS__) +#define _LOG3D(...) _NMLOG3(_LOGL_DEBUG, __VA_ARGS__) +#define _LOG3I(...) _NMLOG3(_LOGL_INFO, __VA_ARGS__) +#define _LOG3W(...) _NMLOG3(_LOGL_WARN, __VA_ARGS__) +#define _LOG3E(...) _NMLOG3(_LOGL_ERR, __VA_ARGS__) + +#define _LOG3T_ENABLED(...) _NMLOG3_ENABLED(_LOGL_TRACE, ##__VA_ARGS__) +#define _LOG3D_ENABLED(...) _NMLOG3_ENABLED(_LOGL_DEBUG, ##__VA_ARGS__) +#define _LOG3I_ENABLED(...) _NMLOG3_ENABLED(_LOGL_INFO, ##__VA_ARGS__) +#define _LOG3W_ENABLED(...) _NMLOG3_ENABLED(_LOGL_WARN, ##__VA_ARGS__) +#define _LOG3E_ENABLED(...) _NMLOG3_ENABLED(_LOGL_ERR, ##__VA_ARGS__) + +#define _LOG3T_err(errsv, ...) _NMLOG3_err(errsv, _LOGL_TRACE, __VA_ARGS__) +#define _LOG3D_err(errsv, ...) _NMLOG3_err(errsv, _LOGL_DEBUG, __VA_ARGS__) +#define _LOG3I_err(errsv, ...) _NMLOG3_err(errsv, _LOGL_INFO, __VA_ARGS__) +#define _LOG3W_err(errsv, ...) _NMLOG3_err(errsv, _LOGL_WARN, __VA_ARGS__) +#define _LOG3E_err(errsv, ...) _NMLOG3_err(errsv, _LOGL_ERR, __VA_ARGS__) + +#if NM_MORE_LOGGING + #define _LOG3t_ENABLED(...) _NMLOG3_ENABLED(_LOGL_TRACE, ##__VA_ARGS__) + #define _LOG3t(...) _NMLOG3(_LOGL_TRACE, __VA_ARGS__) + #define _LOG3t_err(errsv, ...) _NMLOG3_err(errsv, _LOGL_TRACE, __VA_ARGS__) +#else + /* still call the logging macros to get compile time checks, but they will be optimized out. */ + #define _LOG3t_ENABLED(...) (FALSE && (_NMLOG3_ENABLED(_LOGL_TRACE, ##__VA_ARGS__))) + #define _LOG3t(...) \ + G_STMT_START \ + { \ + if (FALSE) { \ + _NMLOG3(_LOGL_TRACE, __VA_ARGS__); \ + } \ + } \ + G_STMT_END + #define _LOG3t_err(errsv, ...) \ + G_STMT_START \ + { \ + if (FALSE) { \ + _NMLOG3_err(errsv, _LOGL_TRACE, __VA_ARGS__); \ + } \ + } \ + G_STMT_END +#endif + +/*****************************************************************************/ + +#endif /* __NM_LOGGING_FWD_H__ */ diff --git a/src/libnm-glib-aux/nm-logging-syslog.h b/src/libnm-glib-aux/nm-logging-syslog.h new file mode 100644 index 0000000..1d23086 --- /dev/null +++ b/src/libnm-glib-aux/nm-logging-syslog.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#ifndef __NM_LOGGING_SYSLOG_H__ +#define __NM_LOGGING_SYSLOG_H__ + +#include + +static inline int +nm_utils_syslog_coerce_from_nm(int syslog_level) +{ + /* NetworkManager uses internally NMLogLevel levels. When spawning + * the VPN plugin, it maps those levels to syslog levels as follows: + * + * LOGL_INFO = LOG_NOTICE, + * LOGL_DEBUG = LOG_INFO, + * LOGL_TRACE = LOG_DEBUG, + * + * However, when actually printing to syslog, we don't want to print messages + * with LOGL_INFO level as LOG_NOTICE, because they are *not* to be highlighted. + * + * In other words: NetworkManager has 3 levels that should not require highlighting: + * LOGL_INFO, LOGL_DEBUG, LOGL_TRACE. syslog on the other hand has only LOG_INFO and LOG_DEBUG. + * + * So, coerce those values before printing to syslog. When you receive the syslog_level + * from NetworkManager, instead of calling + * syslog(syslog_level, ...) + * you should call + * syslog(nm_utils_syslog_coerce_from_nm(syslog_level), ...) + */ + switch (syslog_level) { + case LOG_INFO: + return LOG_DEBUG; + case LOG_NOTICE: + return LOG_INFO; + default: + return syslog_level; + } +} + +static inline const char * +nm_utils_syslog_to_str(int syslog_level) +{ + /* Maps the levels the same way as NetworkManager's nm-logging.c does */ + if (syslog_level >= LOG_DEBUG) + return ""; + if (syslog_level >= LOG_INFO) + return ""; + if (syslog_level >= LOG_NOTICE) + return ""; + if (syslog_level >= LOG_WARNING) + return ""; + return ""; +} + +/*****************************************************************************/ + +#endif /* __NM_LOGGING_SYSLOG_H__ */ diff --git a/src/libnm-glib-aux/nm-macros-internal.h b/src/libnm-glib-aux/nm-macros-internal.h new file mode 100644 index 0000000..fb16ddc --- /dev/null +++ b/src/libnm-glib-aux/nm-macros-internal.h @@ -0,0 +1,1871 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2012 Colin Walters . + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NM_MACROS_INTERNAL_H__ +#define __NM_MACROS_INTERNAL_H__ + +#include +#include +#include +#include + +#include + +/*****************************************************************************/ + +/* most of our code is single-threaded with a mainloop. Hence, we usually don't need + * any thread-safety. Sometimes, we do need thread-safety (nm-logging), but we can + * avoid locking if we are on the main-thread by: + * + * - modifications of shared data is done infrequently and only from the + * main-thread (nm_logging_setup()) + * - read-only access is done frequently (nm_logging_enabled()) + * - from the main-thread, we can do that without locking (because + * all modifications are also done on the main thread. + * - from other threads, we need locking. But this is expected to be + * done infrequently too. Important is the lock-free fast-path on the + * main-thread. + * + * By defining NM_THREAD_SAFE_ON_MAIN_THREAD you indicate that this code runs + * on the main-thread. It is by default defined to "1". If you have code that + * is also used on another thread, redefine the define to 0 (to opt in into + * the slow-path). + */ +#define NM_THREAD_SAFE_ON_MAIN_THREAD 1 + +/*****************************************************************************/ + +#include "nm-glib.h" + +/*****************************************************************************/ + +#define nm_offsetofend(t, m) (G_STRUCT_OFFSET(t, m) + sizeof(((t *) NULL)->m)) + +/*****************************************************************************/ + +#define gs_free nm_auto_g_free +#define gs_unref_object nm_auto_unref_object +#define gs_unref_variant nm_auto_unref_variant +#define gs_unref_array nm_auto_unref_array +#define gs_unref_ptrarray nm_auto_unref_ptrarray +#define gs_unref_hashtable nm_auto_unref_hashtable +#define gs_unref_bytes nm_auto_unref_bytes +#define gs_strfreev nm_auto_strfreev +#define gs_free_error nm_auto_free_error + +/*****************************************************************************/ + +NM_AUTO_DEFINE_FCN_VOID0(void *, _nm_auto_g_free, g_free); +#define nm_auto_g_free nm_auto(_nm_auto_g_free) + +NM_AUTO_DEFINE_FCN_VOID0(GObject *, _nm_auto_unref_object, g_object_unref); +#define nm_auto_unref_object nm_auto(_nm_auto_unref_object) + +NM_AUTO_DEFINE_FCN0(GVariant *, _nm_auto_unref_variant, g_variant_unref); +#define nm_auto_unref_variant nm_auto(_nm_auto_unref_variant) + +NM_AUTO_DEFINE_FCN0(GArray *, _nm_auto_unref_array, g_array_unref); +#define nm_auto_unref_array nm_auto(_nm_auto_unref_array) + +NM_AUTO_DEFINE_FCN0(GPtrArray *, _nm_auto_unref_ptrarray, g_ptr_array_unref); +#define nm_auto_unref_ptrarray nm_auto(_nm_auto_unref_ptrarray) + +NM_AUTO_DEFINE_FCN0(GHashTable *, _nm_auto_unref_hashtable, g_hash_table_unref); +#define nm_auto_unref_hashtable nm_auto(_nm_auto_unref_hashtable) + +NM_AUTO_DEFINE_FCN0(GSList *, _nm_auto_free_slist, g_slist_free); +#define nm_auto_free_slist nm_auto(_nm_auto_free_slist) + +NM_AUTO_DEFINE_FCN0(GBytes *, _nm_auto_unref_bytes, g_bytes_unref); +#define nm_auto_unref_bytes nm_auto(_nm_auto_unref_bytes) + +NM_AUTO_DEFINE_FCN0(char **, _nm_auto_strfreev, g_strfreev); +#define nm_auto_strfreev nm_auto(_nm_auto_strfreev) + +NM_AUTO_DEFINE_FCN0(GError *, _nm_auto_free_error, g_error_free); +#define nm_auto_free_error nm_auto(_nm_auto_free_error) + +NM_AUTO_DEFINE_FCN0(GKeyFile *, _nm_auto_unref_keyfile, g_key_file_unref); +#define nm_auto_unref_keyfile nm_auto(_nm_auto_unref_keyfile) + +NM_AUTO_DEFINE_FCN0(GVariantIter *, _nm_auto_free_variant_iter, g_variant_iter_free); +#define nm_auto_free_variant_iter nm_auto(_nm_auto_free_variant_iter) + +NM_AUTO_DEFINE_FCN0(GVariantBuilder *, _nm_auto_unref_variant_builder, g_variant_builder_unref); +#define nm_auto_unref_variant_builder nm_auto(_nm_auto_unref_variant_builder) + +#define nm_auto_clear_variant_builder nm_auto(g_variant_builder_clear) + +NM_AUTO_DEFINE_FCN0(GList *, _nm_auto_free_list, g_list_free); +#define nm_auto_free_list nm_auto(_nm_auto_free_list) + +NM_AUTO_DEFINE_FCN0(GChecksum *, _nm_auto_checksum_free, g_checksum_free); +#define nm_auto_free_checksum nm_auto(_nm_auto_checksum_free) + +#define nm_auto_unset_gvalue nm_auto(g_value_unset) + +NM_AUTO_DEFINE_FCN_VOID0(void *, _nm_auto_unref_gtypeclass, g_type_class_unref); +#define nm_auto_unref_gtypeclass nm_auto(_nm_auto_unref_gtypeclass) + +NM_AUTO_DEFINE_FCN0(GByteArray *, _nm_auto_unref_bytearray, g_byte_array_unref); +#define nm_auto_unref_bytearray nm_auto(_nm_auto_unref_bytearray) + +static inline void +_nm_auto_free_gstring(GString **str) +{ + if (*str) + g_string_free(*str, TRUE); +} +#define nm_auto_free_gstring nm_auto(_nm_auto_free_gstring) + +static inline void +_nm_auto_protect_errno(const int *p_saved_errno) +{ + errno = *p_saved_errno; +} +#define NM_AUTO_PROTECT_ERRNO(errsv_saved) \ + nm_auto(_nm_auto_protect_errno) _nm_unused const int errsv_saved = (errno) + +NM_AUTO_DEFINE_FCN0(GSource *, _nm_auto_unref_gsource, g_source_unref); +#define nm_auto_unref_gsource nm_auto(_nm_auto_unref_gsource) + +NM_AUTO_DEFINE_FCN0(guint, _nm_auto_remove_source, g_source_remove); +#define nm_auto_remove_source nm_auto(_nm_auto_remove_source) + +NM_AUTO_DEFINE_FCN0(GIOChannel *, _nm_auto_unref_io_channel, g_io_channel_unref); +#define nm_auto_unref_io_channel nm_auto(_nm_auto_unref_io_channel) + +NM_AUTO_DEFINE_FCN0(GMainLoop *, _nm_auto_unref_gmainloop, g_main_loop_unref); +#define nm_auto_unref_gmainloop nm_auto(_nm_auto_unref_gmainloop) + +NM_AUTO_DEFINE_FCN0(GOptionContext *, _nm_auto_free_option_context, g_option_context_free); +#define nm_auto_free_option_context nm_auto(_nm_auto_free_option_context) + +static inline void +_nm_auto_freev(gpointer ptr) +{ + gpointer **p = ptr; + gpointer * _ptr; + + if (*p) { + for (_ptr = *p; *_ptr; _ptr++) + g_free(*_ptr); + g_free(*p); + } +} +/* g_free a NULL terminated array of pointers, with also freeing each + * pointer with g_free(). It essentially does the same as + * gs_strfreev / g_strfreev(), but not restricted to strv arrays. */ +#define nm_auto_freev nm_auto(_nm_auto_freev) + +/*****************************************************************************/ + +#define _NM_MACRO_SELECT_ARG_64(_1, \ + _2, \ + _3, \ + _4, \ + _5, \ + _6, \ + _7, \ + _8, \ + _9, \ + _10, \ + _11, \ + _12, \ + _13, \ + _14, \ + _15, \ + _16, \ + _17, \ + _18, \ + _19, \ + _20, \ + _21, \ + _22, \ + _23, \ + _24, \ + _25, \ + _26, \ + _27, \ + _28, \ + _29, \ + _30, \ + _31, \ + _32, \ + _33, \ + _34, \ + _35, \ + _36, \ + _37, \ + _38, \ + _39, \ + _40, \ + _41, \ + _42, \ + _43, \ + _44, \ + _45, \ + _46, \ + _47, \ + _48, \ + _49, \ + _50, \ + _51, \ + _52, \ + _53, \ + _54, \ + _55, \ + _56, \ + _57, \ + _58, \ + _59, \ + _60, \ + _61, \ + _62, \ + _63, \ + N, \ + ...) \ + N + +/* http://stackoverflow.com/a/2124385/354393 + * https://stackoverflow.com/questions/11317474/macro-to-count-number-of-arguments + */ + +#define NM_NARG(...) \ + _NM_MACRO_SELECT_ARG_64(, \ + ##__VA_ARGS__, \ + 62, \ + 61, \ + 60, \ + 59, \ + 58, \ + 57, \ + 56, \ + 55, \ + 54, \ + 53, \ + 52, \ + 51, \ + 50, \ + 49, \ + 48, \ + 47, \ + 46, \ + 45, \ + 44, \ + 43, \ + 42, \ + 41, \ + 40, \ + 39, \ + 38, \ + 37, \ + 36, \ + 35, \ + 34, \ + 33, \ + 32, \ + 31, \ + 30, \ + 29, \ + 28, \ + 27, \ + 26, \ + 25, \ + 24, \ + 23, \ + 22, \ + 21, \ + 20, \ + 19, \ + 18, \ + 17, \ + 16, \ + 15, \ + 14, \ + 13, \ + 12, \ + 11, \ + 10, \ + 9, \ + 8, \ + 7, \ + 6, \ + 5, \ + 4, \ + 3, \ + 2, \ + 1, \ + 0) +#define NM_NARG_MAX1(...) \ + _NM_MACRO_SELECT_ARG_64(, \ + ##__VA_ARGS__, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 1, \ + 0) +#define NM_NARG_MAX2(...) \ + _NM_MACRO_SELECT_ARG_64(, \ + ##__VA_ARGS__, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 2, \ + 1, \ + 0) + +#define _NM_MACRO_CALL(macro, ...) macro(__VA_ARGS__) + +/*****************************************************************************/ + +#define _NM_MACRO_COMMA_IF_ARGS(...) \ + _NM_MACRO_CALL(G_PASTE(__NM_MACRO_COMMA_IF_ARGS_, NM_NARG_MAX1(__VA_ARGS__)), __VA_ARGS__) +#define __NM_MACRO_COMMA_IF_ARGS_0() +#define __NM_MACRO_COMMA_IF_ARGS_1(...) , + +/*****************************************************************************/ + +/* http://stackoverflow.com/a/11172679 */ +#define _NM_UTILS_MACRO_FIRST(...) __NM_UTILS_MACRO_FIRST_HELPER(__VA_ARGS__, throwaway) +#define __NM_UTILS_MACRO_FIRST_HELPER(first, ...) first + +#define _NM_UTILS_MACRO_REST(...) \ + _NM_MACRO_CALL(G_PASTE(__NM_UTILS_MACRO_REST_, NM_NARG_MAX2(__VA_ARGS__)), __VA_ARGS__) +#define __NM_UTILS_MACRO_REST_0() +#define __NM_UTILS_MACRO_REST_1(first) +#define __NM_UTILS_MACRO_REST_2(first, ...) , __VA_ARGS__ + +/*****************************************************************************/ + +#if defined(__GNUC__) + #define _NM_PRAGMA_WARNING_DO(warning) G_STRINGIFY(GCC diagnostic ignored warning) +#elif defined(__clang__) + #define _NM_PRAGMA_WARNING_DO(warning) G_STRINGIFY(clang diagnostic ignored warning) +#endif + +/* you can only suppress a specific warning that the compiler + * understands. Otherwise you will get another compiler warning + * about invalid pragma option. + * It's not that bad however, because gcc and clang often have the + * same name for the same warning. */ + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) + #define NM_PRAGMA_WARNING_DISABLE(warning) \ + _Pragma("GCC diagnostic push") _Pragma(_NM_PRAGMA_WARNING_DO(warning)) +#elif defined(__clang__) + #define NM_PRAGMA_WARNING_DISABLE(warning) \ + _Pragma("clang diagnostic push") \ + _Pragma(_NM_PRAGMA_WARNING_DO("-Wunknown-warning-option")) \ + _Pragma(_NM_PRAGMA_WARNING_DO(warning)) +#else + #define NM_PRAGMA_WARNING_DISABLE(warning) +#endif + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) + #define NM_PRAGMA_WARNING_REENABLE _Pragma("GCC diagnostic pop") +#elif defined(__clang__) + #define NM_PRAGMA_WARNING_REENABLE _Pragma("clang diagnostic pop") +#else + #define NM_PRAGMA_WARNING_REENABLE +#endif + +/*****************************************************************************/ + +/** + * NM_G_ERROR_MSG: + * @error: (allow-none): the #GError instance + * + * All functions must follow the convention that when they + * return a failure, they must also set the GError to a valid + * message. For external API however, we want to be extra + * careful before accessing the error instance. Use NM_G_ERROR_MSG() + * which is safe to use on NULL. + * + * Returns: the error message. + **/ +static inline const char * +NM_G_ERROR_MSG(GError *error) +{ + return error ? (error->message ?: "(null)") : "(no-error)"; +} + +/*****************************************************************************/ + +#ifndef _NM_CC_SUPPORT_AUTO_TYPE + #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))) + #define _NM_CC_SUPPORT_AUTO_TYPE 1 + #else + #define _NM_CC_SUPPORT_AUTO_TYPE 0 + #endif +#endif + +#ifndef _NM_CC_SUPPORT_GENERIC + /* In the meantime, NetworkManager requires C11 and _Generic() should always be available. + * However, shared/nm-utils may also be used in VPN/applet, which possibly did not yet + * bump the C standard requirement. Leave this for the moment, but eventually we can + * drop it. + * + * Technically, gcc 4.9 already has some support for _Generic(). But there seems + * to be issues with propagating "const char *[5]" to "const char **". Only assume + * we have _Generic() since gcc 5. */ + #if (defined(__GNUC__) && __GNUC__ >= 5) || (defined(__clang__)) + #define _NM_CC_SUPPORT_GENERIC 1 + #else + #define _NM_CC_SUPPORT_GENERIC 0 + #endif +#endif + +#if _NM_CC_SUPPORT_AUTO_TYPE + #define _nm_auto_type __auto_type +#endif + +#if _NM_CC_SUPPORT_GENERIC + #define _NM_CONSTCAST_FULL_1(type, obj_expr, obj) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) + #define _NM_CONSTCAST_FULL_2(type, obj_expr, obj, alias_type2) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const alias_type2 *const: ((const type *) (obj)), \ + const alias_type2 * : ((const type *) (obj)), \ + alias_type2 *const: (( type *) (obj)), \ + alias_type2 * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) + #define _NM_CONSTCAST_FULL_3(type, obj_expr, obj, alias_type2, alias_type3) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const alias_type2 *const: ((const type *) (obj)), \ + const alias_type2 * : ((const type *) (obj)), \ + alias_type2 *const: (( type *) (obj)), \ + alias_type2 * : (( type *) (obj)), \ + const alias_type3 *const: ((const type *) (obj)), \ + const alias_type3 * : ((const type *) (obj)), \ + alias_type3 *const: (( type *) (obj)), \ + alias_type3 * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) + #define _NM_CONSTCAST_FULL_4(type, obj_expr, obj, alias_type2, alias_type3, alias_type4) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const alias_type2 *const: ((const type *) (obj)), \ + const alias_type2 * : ((const type *) (obj)), \ + alias_type2 *const: (( type *) (obj)), \ + alias_type2 * : (( type *) (obj)), \ + const alias_type3 *const: ((const type *) (obj)), \ + const alias_type3 * : ((const type *) (obj)), \ + alias_type3 *const: (( type *) (obj)), \ + alias_type3 * : (( type *) (obj)), \ + const alias_type4 *const: ((const type *) (obj)), \ + const alias_type4 * : ((const type *) (obj)), \ + alias_type4 *const: (( type *) (obj)), \ + alias_type4 * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) + #define _NM_CONSTCAST_FULL_x(type, obj_expr, obj, n, ...) \ + (_NM_CONSTCAST_FULL_##n(type, obj_expr, obj, ##__VA_ARGS__)) + #define _NM_CONSTCAST_FULL_y(type, obj_expr, obj, n, ...) \ + (_NM_CONSTCAST_FULL_x(type, obj_expr, obj, n, ##__VA_ARGS__)) + #define NM_CONSTCAST_FULL(type, obj_expr, obj, ...) \ + (_NM_CONSTCAST_FULL_y(type, obj_expr, obj, NM_NARG(dummy, ##__VA_ARGS__), ##__VA_ARGS__)) +#else + #define NM_CONSTCAST_FULL(type, obj_expr, obj, ...) ((type *) (obj)) +#endif + +#define NM_CONSTCAST(type, obj, ...) NM_CONSTCAST_FULL(type, (obj), (obj), ##__VA_ARGS__) + +#if _NM_CC_SUPPORT_GENERIC + #define NM_UNCONST_PTR(type, arg) \ + _Generic((arg), const type * : ((type *) (arg)), type * : ((type *) (arg))) +#else + #define NM_UNCONST_PTR(type, arg) ((type *) (arg)) +#endif + +#if _NM_CC_SUPPORT_GENERIC + #define NM_UNCONST_PPTR(type, arg) \ + _Generic ((arg), \ + const type * *: ((type **) (arg)), \ + type * *: ((type **) (arg)), \ + const type *const*: ((type **) (arg)), \ + type *const*: ((type **) (arg))) +#else + #define NM_UNCONST_PPTR(type, arg) ((type **) (arg)) +#endif + +#define NM_GOBJECT_CAST(type, obj, is_check, ...) \ + ({ \ + const void *_obj = (obj); \ + \ + nm_assert(_obj || (is_check(_obj))); \ + NM_CONSTCAST_FULL(type, (obj), _obj, GObject, ##__VA_ARGS__); \ + }) + +#define NM_GOBJECT_CAST_NON_NULL(type, obj, is_check, ...) \ + ({ \ + const void *_obj = (obj); \ + \ + nm_assert(is_check(_obj)); \ + NM_CONSTCAST_FULL(type, (obj), _obj, GObject, ##__VA_ARGS__); \ + }) + +#define NM_ENSURE_NOT_NULL(ptr) \ + ({ \ + typeof(ptr) _ptr = (ptr); \ + \ + nm_assert(_ptr != NULL); \ + _ptr; \ + }) + +#if _NM_CC_SUPPORT_GENERIC + /* returns @value, if the type of @value matches @type. + * This requires support for C11 _Generic(). If no support is + * present, this returns @value directly. + * + * It's useful to check the let the compiler ensure that @value is + * of a certain type. */ + #define _NM_ENSURE_TYPE(type, value) (_Generic((value), type : (value))) + #define _NM_ENSURE_TYPE_CONST(type, value) \ + (_Generic((value), const type \ + : ((const type)(value)), const type const \ + : ((const type)(value)), type \ + : ((const type)(value)), type const \ + : ((const type)(value)))) +#else + #define _NM_ENSURE_TYPE(type, value) (value) + #define _NM_ENSURE_TYPE_CONST(type, value) ((const type)(value)) +#endif + +#if _NM_CC_SUPPORT_GENERIC && (!defined(__clang__) || __clang_major__ > 3) + #define NM_STRUCT_OFFSET_ENSURE_TYPE(type, container, field) \ + (_Generic((&(((container *) NULL)->field))[0], type : G_STRUCT_OFFSET(container, field))) +#else + #define NM_STRUCT_OFFSET_ENSURE_TYPE(type, container, field) G_STRUCT_OFFSET(container, field) +#endif + +#if _NM_CC_SUPPORT_GENERIC + /* these macros cast (value) to + * - "const char **" (for "MC", mutable-const) + * - "const char *const*" (for "CC", const-const) + * The point is to do this cast, but only accepting pointers + * that are compatible already. + * + * The problem is, if you add a function like g_strdupv(), the input + * argument is not modified (CC), but you want to make it work also + * for "char **". C doesn't allow this form of casting (for good reasons), + * so the function makes a choice like g_strdupv(char**). That means, + * every time you want to call it with a const argument, you need to + * explicitly cast it. + * + * These macros do the cast, but they only accept a compatible input + * type, otherwise they will fail compilation. + */ + #define NM_CAST_STRV_MC(value) \ + (_Generic ((value), \ + const char * *: (const char * *) (value), \ + char * *: (const char * *) (value), \ + void *: (const char * *) (value))) + #define NM_CAST_STRV_CC(value) \ + (_Generic ((value), \ + const char *const*: (const char *const*) (value), \ + const char * *: (const char *const*) (value), \ + char *const*: (const char *const*) (value), \ + char * *: (const char *const*) (value), \ + const void *: (const char *const*) (value), \ + void *: (const char *const*) (value), \ + const char *const*const: (const char *const*) (value), \ + const char * *const: (const char *const*) (value), \ + char *const*const: (const char *const*) (value), \ + char * *const: (const char *const*) (value), \ + const void *const: (const char *const*) (value), \ + void *const: (const char *const*) (value))) +#else + #define NM_CAST_STRV_MC(value) ((const char **) (value)) + #define NM_CAST_STRV_CC(value) ((const char *const *) (value)) +#endif + +#if _NM_CC_SUPPORT_GENERIC + #define NM_PROPAGATE_CONST(test_expr, ptr) \ + (_Generic ((test_expr), \ + const typeof (*(test_expr)) *: ((const typeof (*(ptr)) *) (ptr)), \ + default: (_Generic ((test_expr), \ + typeof (*(test_expr)) *: (ptr))))) +#else + #define NM_PROPAGATE_CONST(test_expr, ptr) (ptr) +#endif + +/* with the way it is implemented, the caller may or may not pass a trailing + * ',' and it will work. However, this makes the macro unsuitable for initializing + * an array. */ +#define NM_MAKE_STRV(...) \ + ((const char *const[(sizeof(((const char *const[]){__VA_ARGS__})) / sizeof(const char *)) \ + + 1]){__VA_ARGS__}) + +/*****************************************************************************/ + +/* NM_CACHED_QUARK() returns the GQuark for @string, but caches + * it in a static variable to speed up future lookups. + * + * @string must be a string literal. + */ +#define NM_CACHED_QUARK(string) \ + ({ \ + static GQuark _nm_cached_quark = 0; \ + \ + (G_LIKELY(_nm_cached_quark != 0) \ + ? _nm_cached_quark \ + : (_nm_cached_quark = g_quark_from_static_string("" string ""))); \ + }) + +/* NM_CACHED_QUARK_FCN() is essentially the same as G_DEFINE_QUARK + * with two differences: + * - @string must be a quoted string-literal + * - @fcn must be the full function name, while G_DEFINE_QUARK() appends + * "_quark" to the function name. + * Both properties of G_DEFINE_QUARK() are non favorable, because you can no + * longer grep for string/fcn -- unless you are aware that you are searching + * for G_DEFINE_QUARK() and omit quotes / append _quark(). With NM_CACHED_QUARK_FCN(), + * ctags/cscope can locate the use of @fcn (though it doesn't recognize that + * NM_CACHED_QUARK_FCN() defines it). + */ +#define NM_CACHED_QUARK_FCN(string, fcn) \ + GQuark fcn(void) \ + { \ + return NM_CACHED_QUARK(string); \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +/*****************************************************************************/ + +static inline GString * +nm_gstring_prepare(GString **l) +{ + if (*l) + g_string_set_size(*l, 0); + else + *l = g_string_sized_new(30); + return *l; +} + +static inline GString * +nm_gstring_add_space_delimiter(GString *str) +{ + if (str->len > 0) + g_string_append_c(str, ' '); + return str; +} + +static inline gboolean +nm_str_is_empty(const char *str) +{ + /* %NULL is also accepted, and also "empty". */ + return !str || !str[0]; +} + +static inline const char * +nm_str_not_empty(const char *str) +{ + return !nm_str_is_empty(str) ? str : NULL; +} + +static inline char * +nm_strdup_not_empty(const char *str) +{ + return !nm_str_is_empty(str) ? g_strdup(str) : NULL; +} + +static inline char * +nm_str_realloc(char *str) +{ + gs_free char *s = str; + + /* Returns a new clone of @str and frees @str. The point is that @str + * possibly points to a larger chunck of memory. We want to freshly allocate + * a buffer. + * + * We could use realloc(), but that might not do anything or leave + * @str in its memory pool for chunks of a different size (bad for + * fragmentation). + * + * This is only useful when we want to keep the buffer around for a long + * time and want to re-allocate a more optimal buffer. */ + + return g_strdup(s); +} + +/*****************************************************************************/ + +#define NM_PRINT_FMT_QUOTED2(cond, prefix, str, str_else) \ + (cond) ? (prefix) : "", (cond) ? (str) : (str_else) +#define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \ + (cond) ? (prefix) : "", (cond) ? (str) : (str_else), (cond) ? (suffix) : "" +#define NM_PRINT_FMT_QUOTE_STRING(arg) NM_PRINT_FMT_QUOTED((arg), "\"", (arg), "\"", "(null)") +#define NM_PRINT_FMT_QUOTE_REF_STRING(arg) \ + NM_PRINT_FMT_QUOTED((arg), "\"", (arg)->str, "\"", "(null)") + +/*****************************************************************************/ + +/* redefine assertions to use g_assert*() */ +#undef _nm_assert_call +#undef _nm_assert_call_not_reached +#define _nm_assert_call(cond) g_assert(cond) +#define _nm_assert_call_not_reached() g_assert_not_reached() + +/* Usage: + * + * if (NM_MORE_ASSERT_ONCE (5)) { extra_check (); } + * + * This will only run the check once, and only if NM_MORE_ASSERT is >= than + * more_assert_level. + */ +#define NM_MORE_ASSERT_ONCE(more_assert_level) \ + ((NM_MORE_ASSERTS >= (more_assert_level)) && ({ \ + static volatile int _assert_once = 0; \ + \ + G_STATIC_ASSERT_EXPR((more_assert_level) > 0); \ + \ + G_UNLIKELY(_assert_once == 0 && g_atomic_int_compare_and_exchange(&_assert_once, 0, 1)); \ + })) + +/*****************************************************************************/ + +#define NM_GOBJECT_PROPERTIES_DEFINE_BASE_FULL(suffix, ...) \ + typedef enum { \ + PROP_0##suffix, \ + __VA_ARGS__ _PROPERTY_ENUMS_LAST##suffix, \ + } _PropertyEnums##suffix; \ + static GParamSpec *obj_properties##suffix[_PROPERTY_ENUMS_LAST##suffix] = { \ + NULL, \ + } + +#define NM_GOBJECT_PROPERTIES_DEFINE_NOTIFY(suffix, obj_type) \ + static inline void _nm_gobject_notify_together_impl##suffix( \ + obj_type * obj, \ + guint n, \ + const _PropertyEnums##suffix *props) \ + { \ + GObject *const gobj = (GObject *) obj; \ + GParamSpec * pspec_first = NULL; \ + gboolean frozen = FALSE; \ + \ + nm_assert(G_IS_OBJECT(obj)); \ + nm_assert(n > 0); \ + \ + while (n-- > 0) { \ + const _PropertyEnums##suffix prop = *props++; \ + GParamSpec * pspec; \ + \ + if (prop == PROP_0##suffix) \ + continue; \ + \ + nm_assert((gsize) prop < G_N_ELEMENTS(obj_properties##suffix)); \ + pspec = obj_properties##suffix[prop]; \ + nm_assert(pspec); \ + \ + if (!frozen) { \ + if (!pspec_first) { \ + pspec_first = pspec; \ + continue; \ + } \ + frozen = TRUE; \ + g_object_freeze_notify(gobj); \ + g_object_notify_by_pspec(gobj, pspec_first); \ + } \ + g_object_notify_by_pspec(gobj, pspec); \ + } \ + \ + if (frozen) \ + g_object_thaw_notify(gobj); \ + else if (pspec_first) \ + g_object_notify_by_pspec(gobj, pspec_first); \ + } \ + \ + _nm_unused static inline void _notify##suffix(obj_type *obj, _PropertyEnums##suffix prop) \ + { \ + _nm_gobject_notify_together_impl##suffix(obj, 1, &prop); \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +#define NM_GOBJECT_PROPERTIES_DEFINE_BASE(...) \ + NM_GOBJECT_PROPERTIES_DEFINE_BASE_FULL(, __VA_ARGS__); + +#define NM_GOBJECT_PROPERTIES_DEFINE_FULL(suffix, obj_type, ...) \ + NM_GOBJECT_PROPERTIES_DEFINE_BASE_FULL(suffix, __VA_ARGS__); \ + NM_GOBJECT_PROPERTIES_DEFINE_NOTIFY(suffix, obj_type) + +#define NM_GOBJECT_PROPERTIES_DEFINE(obj_type, ...) \ + NM_GOBJECT_PROPERTIES_DEFINE_FULL(, obj_type, __VA_ARGS__) + +/* invokes _notify() for all arguments (of type _PropertyEnums). Note, that if + * there are more than one prop arguments, this will involve a freeze/thaw + * of GObject property notifications. */ +#define nm_gobject_notify_together_full(suffix, obj, ...) \ + _nm_gobject_notify_together_impl##suffix(obj, \ + NM_NARG(__VA_ARGS__), \ + (const _PropertyEnums##suffix[]){__VA_ARGS__}) + +#define nm_gobject_notify_together(obj, ...) nm_gobject_notify_together_full(, obj, __VA_ARGS__) + +/*****************************************************************************/ + +#define _NM_GET_PRIVATE(self, type, is_check, ...) \ + (&(NM_GOBJECT_CAST_NON_NULL(type, (self), is_check, ##__VA_ARGS__)->_priv)) +#if _NM_CC_SUPPORT_AUTO_TYPE + #define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) \ + ({ \ + _nm_auto_type _self_get_private = \ + NM_GOBJECT_CAST_NON_NULL(type, (self), is_check, ##__VA_ARGS__); \ + \ + NM_PROPAGATE_CONST(_self_get_private, _self_get_private->_priv); \ + }) +#else + #define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) \ + (NM_GOBJECT_CAST_NON_NULL(type, (self), is_check, ##__VA_ARGS__)->_priv) +#endif + +/*****************************************************************************/ + +static inline gpointer +nm_g_object_ref(gpointer obj) +{ + /* g_object_ref() doesn't accept NULL. */ + if (obj) + g_object_ref(obj); + return obj; +} +#define nm_g_object_ref(obj) ((typeof(obj)) nm_g_object_ref(obj)) + +static inline void +nm_g_object_unref(gpointer obj) +{ + /* g_object_unref() doesn't accept NULL. Usually, we workaround that + * by using g_clear_object(), but sometimes that is not convenient + * (for example as destroy function for a hash table that can contain + * NULL values). */ + if (obj) + g_object_unref(obj); +} + +/* Assigns GObject @obj to destination @pp, and takes an additional ref. + * The previous value of @pp is unrefed. + * + * It makes sure to first increase the ref-count of @obj, and handles %NULL + * @obj correctly. + * */ +#define nm_g_object_ref_set(pp, obj) \ + ({ \ + typeof(*(pp)) *const _pp = (pp); \ + typeof(*_pp) const _obj = (obj); \ + typeof(*_pp) _p; \ + gboolean _changed = FALSE; \ + \ + nm_assert(!_pp || !*_pp || G_IS_OBJECT(*_pp)); \ + nm_assert(!_obj || G_IS_OBJECT(_obj)); \ + \ + if (_pp && ((_p = *_pp) != _obj)) { \ + nm_g_object_ref(_obj); \ + *_pp = _obj; \ + nm_g_object_unref(_p); \ + _changed = TRUE; \ + } \ + _changed; \ + }) + +#define nm_g_object_ref_set_take(pp, obj) \ + ({ \ + typeof(*(pp)) *const _pp = (pp); \ + typeof(*_pp) const _obj = (obj); \ + typeof(*_pp) _p; \ + gboolean _changed = FALSE; \ + \ + nm_assert(!_pp || !*_pp || G_IS_OBJECT(*_pp)); \ + nm_assert(!_obj || G_IS_OBJECT(_obj)); \ + \ + if (_pp && ((_p = *_pp) != _obj)) { \ + *_pp = _obj; \ + nm_g_object_unref(_p); \ + _changed = TRUE; \ + } else \ + nm_g_object_unref(_obj); \ + _changed; \ + }) + +/* basically, replaces + * g_clear_pointer (&location, g_free) + * with + * nm_clear_g_free (&location) + * + * Another advantage is that by using a macro and typeof(), it is more + * typesafe and gives you for example a compiler warning when pp is a const + * pointer or points to a const-pointer. + */ +#define nm_clear_g_free(pp) nm_clear_pointer(pp, g_free) + +/* Our nm_clear_pointer() is more typesafe than g_clear_pointer() and + * should be preferred. + * + * For g_clear_object() that is not the case (because g_object_unref() + * anyway takes a void pointer). So using g_clear_object() is fine. + * + * Still have a nm_clear_g_object() because that returns a boolean + * indication whether anything was cleared. */ +#define nm_clear_g_object(pp) nm_clear_pointer(pp, g_object_unref) + +/** + * nm_clear_error: + * @err: a pointer to pointer to a #GError. + * + * This is like g_clear_error(). The only difference is + * that this is an inline function. + */ +static inline void +nm_clear_error(GError **err) +{ + if (err && *err) { + g_error_free(*err); + *err = NULL; + } +} + +/* Patch g_clear_error() to use nm_clear_error(), which is inlineable + * and visible to the compiler. For example gs_free_error attribute only + * frees the error after checking that it's not %NULL. So, in many cases + * the compiler knows that gs_free_error has no effect and can optimize + * the call away. By making g_clear_error() inlineable, we give the compiler + * more chance to detect that the function actually has no effect. */ +#define g_clear_error(ptr) nm_clear_error(ptr) + +static inline gboolean +nm_clear_g_source(guint *id) +{ + guint v; + + if (id && (v = *id)) { + *id = 0; + g_source_remove(v); + return TRUE; + } + return FALSE; +} + +static inline gboolean +nm_clear_g_signal_handler(gpointer self, gulong *id) +{ + gulong v; + + if (id && (v = *id)) { + *id = 0; + g_signal_handler_disconnect(self, v); + return TRUE; + } + return FALSE; +} + +static inline gboolean +nm_clear_g_variant(GVariant **variant) +{ + GVariant *v; + + if (variant && (v = *variant)) { + *variant = NULL; + g_variant_unref(v); + return TRUE; + } + return FALSE; +} + +static inline gboolean +nm_clear_g_cancellable(GCancellable **cancellable) +{ + GCancellable *v; + + if (cancellable && (v = *cancellable)) { + *cancellable = NULL; + g_cancellable_cancel(v); + g_object_unref(v); + return TRUE; + } + return FALSE; +} + +/* If @cancellable_id is not 0, clear it and call g_cancellable_disconnect(). + * @cancellable may be %NULL, if there is nothing to disconnect. + * + * It's like nm_clear_g_signal_handler(), except that it uses g_cancellable_disconnect() + * instead of g_signal_handler_disconnect(). + * + * Note the warning in glib documentation about dead-lock and what g_cancellable_disconnect() + * actually does. */ +static inline gboolean +nm_clear_g_cancellable_disconnect(GCancellable *cancellable, gulong *cancellable_id) +{ + gulong id; + + if (cancellable_id && (id = *cancellable_id) != 0) { + *cancellable_id = 0; + g_cancellable_disconnect(cancellable, id); + return TRUE; + } + return FALSE; +} + +/*****************************************************************************/ + +static inline const char * +nm_dbus_path_not_empty(const char *str) +{ + nm_assert(!str || str[0] == '/'); + return !str || (str[0] == '/' && str[1] == '\0') ? NULL : str; +} + +/*****************************************************************************/ + +/* GVariantType is basically a C string. But G_VARIANT_TYPE() is not suitable + * to initialize a static variable (because it evaluates a function check that + * the string is valid). Add an alternative macro that does the plain cast. + * + * Here you loose the assertion check that G_VARIANT_TYPE() to ensure the + * string is valid. */ +#define NM_G_VARIANT_TYPE(fmt) ((const GVariantType *) ("" fmt "")) + +static inline GVariant * +nm_g_variant_ref(GVariant *v) +{ + if (v) + g_variant_ref(v); + return v; +} + +static inline GVariant * +nm_g_variant_ref_sink(GVariant *v) +{ + if (v) + g_variant_ref_sink(v); + return v; +} + +static inline void +nm_g_variant_unref(GVariant *v) +{ + if (v) + g_variant_unref(v); +} + +static inline GVariant * +nm_g_variant_take_ref(GVariant *v) +{ + if (v) + g_variant_take_ref(v); + return v; +} + +/*****************************************************************************/ + +#define NM_DIV_ROUND_UP(x, y) \ + ({ \ + const typeof(x) _x = (x); \ + const typeof(y) _y = (y); \ + \ + (_x / _y + !!(_x % _y)); \ + }) + +/*****************************************************************************/ + +#define NM_UTILS_LOOKUP_DEFAULT(v) return (v) +#define NM_UTILS_LOOKUP_DEFAULT_WARN(v) g_return_val_if_reached(v) +#define NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT(v) \ + { \ + nm_assert_not_reached(); \ + return (v); \ + } +#define NM_UTILS_LOOKUP_ITEM(v, n) \ + (void) 0; \ +case v: \ + return (n); \ + (void) 0 +#define NM_UTILS_LOOKUP_STR_ITEM(v, n) NM_UTILS_LOOKUP_ITEM(v, "" n "") +#define NM_UTILS_LOOKUP_ITEM_IGNORE(v) \ + (void) 0; \ +case v: \ + break; \ + (void) 0 +#define NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER() \ + (void) 0; \ +default: \ + break; \ + (void) 0 + +#define NM_UTILS_LOOKUP_DEFINE(fcn_name, lookup_type, result_type, unknown_val, ...) \ + result_type fcn_name(lookup_type val) \ + { \ + switch (val) { \ + (void) 0, __VA_ARGS__(void) 0; \ + }; \ + { \ + unknown_val; \ + } \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +#define NM_UTILS_LOOKUP_STR_DEFINE(fcn_name, lookup_type, unknown_val, ...) \ + NM_UTILS_LOOKUP_DEFINE(fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__) + +/* Call the string-lookup-table function @fcn_name. If the function returns + * %NULL, the numeric index is converted to string using a alloca() buffer. + * Beware: this macro uses alloca(). */ +#define NM_UTILS_LOOKUP_STR_A(fcn_name, idx) \ + ({ \ + typeof(idx) _idx = (idx); \ + const char *_s; \ + \ + _s = fcn_name(_idx); \ + if (!_s) { \ + _s = g_alloca(30); \ + \ + g_snprintf((char *) _s, 30, "(%lld)", (long long) _idx); \ + } \ + _s; \ + }) + +/*****************************************************************************/ + +/* check if @flags has exactly one flag (@check) set. You should call this + * only with @check being a compile time constant and a power of two. */ +#define NM_FLAGS_HAS(flags, check) \ + (G_STATIC_ASSERT_EXPR((check) > 0 && ((check) & ((check) -1)) == 0), \ + NM_FLAGS_ANY((flags), (check))) + +#define NM_FLAGS_ANY(flags, check) ((((flags) & (check)) != 0) ? TRUE : FALSE) +#define NM_FLAGS_ALL(flags, check) ((((flags) & (check)) == (check)) ? TRUE : FALSE) + +#define NM_FLAGS_SET(flags, val) \ + ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _val = (val); \ + \ + _flags | _val; \ + }) + +#define NM_FLAGS_UNSET(flags, val) \ + ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _val = (val); \ + \ + _flags &(~_val); \ + }) + +#define NM_FLAGS_ASSIGN(flags, val, assign) \ + ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _val = (val); \ + \ + (assign) ? _flags | (_val) : _flags &(~_val); \ + }) + +#define NM_FLAGS_ASSIGN_MASK(flags, mask, val) \ + ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _mask = (mask); \ + const typeof(flags) _val = (val); \ + \ + ((_flags & ~_mask) | (_mask & _val)); \ + }) + +/*****************************************************************************/ + +#define _NM_BACKPORT_SYMBOL_IMPL(version, \ + return_type, \ + orig_func, \ + versioned_func, \ + args_typed, \ + args) \ + return_type versioned_func args_typed; \ + _nm_externally_visible return_type versioned_func args_typed \ + { \ + return orig_func args; \ + } \ + return_type orig_func args_typed; \ + __asm__(".symver " G_STRINGIFY(versioned_func) ", " G_STRINGIFY(orig_func) "@" G_STRINGIFY( \ + version)) + +#define NM_BACKPORT_SYMBOL(version, return_type, func, args_typed, args) \ + _NM_BACKPORT_SYMBOL_IMPL(version, return_type, func, _##func##_##version, args_typed, args) + +/*****************************************************************************/ + +/* mirrors g_ascii_isspace() and what we consider spaces in general. */ +#define NM_ASCII_SPACES " \n\t\r\f" + +/* Like NM_ASCII_SPACES, but without "\f" (0x0c, Formfeed Page Break). + * This is what for example systemd calls WHITESPACE and what it uses to tokenize + * the kernel command line. */ +#define NM_ASCII_WHITESPACES " \n\t\r" + +#define nm_str_skip_leading_spaces(str) \ + ({ \ + typeof(*(str)) * _str_sls = (str); \ + _nm_unused const char *const _str_type_check = _str_sls; \ + \ + if (_str_sls) { \ + while (g_ascii_isspace(_str_sls[0])) \ + _str_sls++; \ + } \ + _str_sls; \ + }) + +static inline char * +nm_strstrip(char *str) +{ + /* g_strstrip doesn't like NULL. */ + return str ? g_strstrip(str) : NULL; +} + +static inline const char * +nm_strstrip_avoid_copy(const char *str, char **str_free) +{ + gsize l; + char *s; + + nm_assert(str_free && !*str_free); + + if (!str) + return NULL; + + str = nm_str_skip_leading_spaces(str); + l = strlen(str); + if (l == 0 || !g_ascii_isspace(str[l - 1])) + return str; + while (l > 0 && g_ascii_isspace(str[l - 1])) + l--; + + s = g_new(char, l + 1); + memcpy(s, str, l); + s[l] = '\0'; + *str_free = s; + return s; +} + +#define nm_strstrip_avoid_copy_a(alloca_maxlen, str, out_str_free) \ + ({ \ + const char *_str_ssac = (str); \ + char ** _out_str_free_ssac = (out_str_free); \ + \ + G_STATIC_ASSERT_EXPR((alloca_maxlen) > 0); \ + \ + nm_assert(_out_str_free_ssac || ((alloca_maxlen) > (str ? strlen(str) : 0u))); \ + nm_assert(!_out_str_free_ssac || !*_out_str_free_ssac); \ + \ + if (_str_ssac) { \ + _str_ssac = nm_str_skip_leading_spaces(_str_ssac); \ + if (_str_ssac[0] != '\0') { \ + gsize _l = strlen(_str_ssac); \ + \ + if (g_ascii_isspace(_str_ssac[--_l])) { \ + while (_l > 0 && g_ascii_isspace(_str_ssac[_l - 1])) { \ + _l--; \ + } \ + _str_ssac = nm_strndup_a((alloca_maxlen), _str_ssac, _l, _out_str_free_ssac); \ + } \ + } \ + } \ + \ + _str_ssac; \ + }) + +static inline gboolean +nm_str_is_stripped(const char *str) +{ + if (str && str[0]) { + if (g_ascii_isspace(str[0]) || g_ascii_isspace(str[strlen(str) - 1])) + return FALSE; + } + return TRUE; +} + +/* g_ptr_array_sort()'s compare function takes pointers to the + * value. Thus, you cannot use strcmp directly. You can use + * nm_strcmp_p(). + * + * Like strcmp(), this function is not forgiving to accept %NULL. */ +static inline int +nm_strcmp_p(gconstpointer a, gconstpointer b) +{ + const char *s1 = *((const char **) a); + const char *s2 = *((const char **) b); + + return strcmp(s1, s2); +} + +/*****************************************************************************/ + +static inline int +_NM_IN_STRSET_ASCII_CASE_op_streq(const char *x, const char *s) +{ + return s && g_ascii_strcasecmp(x, s) == 0; +} + +#define NM_IN_STRSET_ASCII_CASE(x, ...) \ + _NM_IN_STRSET_EVAL_N(||, \ + _NM_IN_STRSET_ASCII_CASE_op_streq, \ + x, \ + NM_NARG(__VA_ARGS__), \ + __VA_ARGS__) + +#define NM_STR_HAS_SUFFIX_ASCII_CASE(str, suffix) \ + ({ \ + const char *const _str_has_suffix = (str); \ + size_t _l; \ + \ + nm_assert(strlen(suffix) == NM_STRLEN(suffix)); \ + \ + (_str_has_suffix && ((_l = strlen(_str_has_suffix)) >= NM_STRLEN(suffix)) \ + && (g_ascii_strcasecmp(&_str_has_suffix[_l - NM_STRLEN(suffix)], "" suffix "") == 0)); \ + }) + +#define NM_STR_HAS_SUFFIX_ASCII_CASE_WITH_MORE(str, suffix) \ + ({ \ + const char *const _str_has_suffix = (str); \ + size_t _l; \ + \ + nm_assert(strlen(suffix) == NM_STRLEN(suffix)); \ + \ + (_str_has_suffix && ((_l = strlen(_str_has_suffix)) > NM_STRLEN(suffix)) \ + && (g_ascii_strcasecmp(&_str_has_suffix[_l - NM_STRLEN(suffix)], "" suffix "") == 0)); \ + }) + +/*****************************************************************************/ + +#define nm_g_slice_free(ptr) g_slice_free(typeof(*(ptr)), ptr) + +/*****************************************************************************/ + +/* like g_memdup(). The difference is that the @size argument is of type + * gsize, while g_memdup() has type guint. Since, the size of container types + * like GArray is guint as well, this means trying to g_memdup() an + * array, + * g_memdup (array->data, array->len * sizeof (ElementType)) + * will lead to integer overflow, if there are more than G_MAXUINT/sizeof(ElementType) + * bytes. That seems unnecessarily dangerous to me. + * nm_memdup() avoids that, because its size argument is always large enough + * to contain all data that a GArray can hold. + * + * Another minor difference to g_memdup() is that the glib version also + * returns %NULL if @data is %NULL. E.g. g_memdup(NULL, 1) + * gives %NULL, but nm_memdup(NULL, 1) crashes. I think that + * is desirable, because @size MUST be correct at all times. @size + * may be zero, but one must not claim to have non-zero bytes when + * passing a %NULL @data pointer. + */ +static inline gpointer +nm_memdup(gconstpointer data, gsize size) +{ + gpointer p; + + if (size == 0) + return NULL; + p = g_malloc(size); + memcpy(p, data, size); + return p; +} + +#define nm_malloc_maybe_a(alloca_maxlen, bytes, to_free) \ + ({ \ + const gsize _bytes = (bytes); \ + typeof(to_free) _to_free = (to_free); \ + typeof(*_to_free) _ptr; \ + \ + G_STATIC_ASSERT_EXPR((alloca_maxlen) <= 500u); \ + G_STATIC_ASSERT_EXPR((alloca_maxlen) > 0u); \ + nm_assert(_to_free && !*_to_free); \ + \ + if (G_LIKELY(_bytes <= (alloca_maxlen))) { \ + _ptr = _bytes > 0u ? g_alloca(_bytes) : NULL; \ + } else { \ + _ptr = g_malloc(_bytes); \ + *_to_free = _ptr; \ + }; \ + \ + _ptr; \ + }) + +#define nm_malloc0_maybe_a(alloca_maxlen, bytes, to_free) \ + ({ \ + const gsize _bytes = (bytes); \ + typeof(to_free) _to_free = (to_free); \ + typeof(*_to_free) _ptr; \ + \ + G_STATIC_ASSERT_EXPR((alloca_maxlen) <= 500u); \ + G_STATIC_ASSERT_EXPR((alloca_maxlen) > 0u); \ + nm_assert(_to_free && !*_to_free); \ + \ + if (G_LIKELY(_bytes <= (alloca_maxlen))) { \ + if (_bytes > 0u) { \ + _ptr = g_alloca(_bytes); \ + memset(_ptr, 0, _bytes); \ + } else \ + _ptr = NULL; \ + } else { \ + _ptr = g_malloc0(_bytes); \ + *_to_free = _ptr; \ + }; \ + \ + _ptr; \ + }) + +#define nm_memdup_maybe_a(alloca_maxlen, data, size, to_free) \ + ({ \ + const gsize _size = (size); \ + typeof(to_free) _to_free_md = (to_free); \ + typeof(*_to_free_md) _ptr_md = NULL; \ + \ + nm_assert(_to_free_md && !*_to_free_md); \ + \ + if (_size > 0u) { \ + _ptr_md = nm_malloc_maybe_a((alloca_maxlen), _size, _to_free_md); \ + memcpy(_ptr_md, (data), _size); \ + } \ + \ + _ptr_md; \ + }) + +static inline char * +_nm_strndup_a_step(char *s, const char *str, gsize len) +{ + NM_PRAGMA_WARNING_DISABLE("-Wstringop-truncation"); + NM_PRAGMA_WARNING_DISABLE("-Wstringop-overflow"); + if (len > 0) + strncpy(s, str, len); + s[len] = '\0'; + return s; + NM_PRAGMA_WARNING_REENABLE; + NM_PRAGMA_WARNING_REENABLE; +} + +/* Similar to g_strndup(), however, if the string (including the terminating + * NUL char) fits into alloca_maxlen, this will alloca() the memory. + * + * It's a mix of strndup() and strndupa(), but deciding based on @alloca_maxlen + * which one to use. + * + * In case malloc() is necessary, @out_str_free will be set (this string + * must be freed afterwards). It is permissible to pass %NULL as @out_str_free, + * if you ensure that len < alloca_maxlen. + * + * Note that just like g_strndup(), this always returns a buffer with @len + 1 + * bytes, even if strlen(@str) is shorter than that (NUL terminated early). We fill + * the buffer with strncpy(), which means, that @str is copied up to the first + * NUL character and then filled with NUL characters. */ +#define nm_strndup_a(alloca_maxlen, str, len, out_str_free) \ + ({ \ + const gsize _alloca_maxlen_snd = (alloca_maxlen); \ + const char *const _str_snd = (str); \ + const gsize _len_snd = (len); \ + char **const _out_str_free_snd = (out_str_free); \ + char * _s_snd; \ + \ + G_STATIC_ASSERT_EXPR((alloca_maxlen) <= 300); \ + \ + if (_out_str_free_snd && _len_snd >= _alloca_maxlen_snd) { \ + _s_snd = g_malloc(_len_snd + 1); \ + *_out_str_free_snd = _s_snd; \ + } else { \ + g_assert(_len_snd < _alloca_maxlen_snd); \ + _s_snd = g_alloca(_len_snd + 1); \ + } \ + _nm_strndup_a_step(_s_snd, _str_snd, _len_snd); \ + }) + +#define nm_strdup_maybe_a(alloca_maxlen, str, out_str_free) \ + ({ \ + const char *const _str_snd = (str); \ + \ + (char *) nm_memdup_maybe_a(alloca_maxlen, \ + _str_snd, \ + _str_snd ? strlen(_str_snd) + 1u : 0u, \ + out_str_free); \ + }) + +/*****************************************************************************/ + +/* generic macro to convert an int to a (heap allocated) string. + * + * Usually, an inline function nm_strdup_int64() would be enough. However, + * that cannot be used for guint64. So, we would also need nm_strdup_uint64(). + * This causes subtle error potential, because the caller needs to ensure to + * use the right one (and compiler isn't going to help as it silently casts). + * + * Instead, this generic macro is supposed to handle all integers correctly. */ +#if _NM_CC_SUPPORT_GENERIC + #define nm_strdup_int(val) \ + _Generic((val), char \ + : g_strdup_printf("%d", (int) (val)), \ + \ + signed char \ + : g_strdup_printf("%d", (signed) (val)), signed short \ + : g_strdup_printf("%d", (signed) (val)), signed \ + : g_strdup_printf("%d", (signed) (val)), signed long \ + : g_strdup_printf("%ld", (signed long) (val)), signed long long \ + : g_strdup_printf("%lld", (signed long long) (val)), \ + \ + unsigned char \ + : g_strdup_printf("%u", (unsigned) (val)), unsigned short \ + : g_strdup_printf("%u", (unsigned) (val)), unsigned \ + : g_strdup_printf("%u", (unsigned) (val)), unsigned long \ + : g_strdup_printf("%lu", (unsigned long) (val)), unsigned long long \ + : g_strdup_printf("%llu", (unsigned long long) (val))) +#else + #define nm_strdup_int(val) \ + ((sizeof(val) == sizeof(guint64) && ((typeof(val)) - 1) > 0) \ + ? g_strdup_printf("%" G_GUINT64_FORMAT, (guint64)(val)) \ + : g_strdup_printf("%" G_GINT64_FORMAT, (gint64)(val))) +#endif + +/*****************************************************************************/ + +static inline guint +nm_encode_version(guint major, guint minor, guint micro) +{ + /* analog to the preprocessor macro NM_ENCODE_VERSION(). */ + return (major << 16) | (minor << 8) | micro; +} + +static inline void +nm_decode_version(guint version, guint *major, guint *minor, guint *micro) +{ + *major = (version & 0xFFFF0000u) >> 16; + *minor = (version & 0x0000FF00u) >> 8; + *micro = (version & 0x000000FFu); +} + +/*****************************************************************************/ + +/* taken from systemd's DECIMAL_STR_MAX() + * + * Returns the number of chars needed to format variables of the + * specified type as a decimal string. Adds in extra space for a + * negative '-' prefix (hence works correctly on signed + * types). Includes space for the trailing NUL. */ +#define NM_DECIMAL_STR_MAX(type) \ + (2 \ + + (sizeof(type) <= 1 ? 3 \ + : sizeof(type) <= 2 ? 5 \ + : sizeof(type) <= 4 ? 10 \ + : sizeof(type) <= 8 ? 20 \ + : sizeof(int[-2 * (sizeof(type) > 8)]))) + +/*****************************************************************************/ + +/* if @str is NULL, return "(null)". Otherwise, allocate a buffer using + * alloca() of and fill it with @str. @str will be quoted with double quote. + * If @str is longer then @trunc_at, the string is truncated and the closing + * quote is instead '^' to indicate truncation. + * + * Thus, the maximum stack allocated buffer will be @trunc_at+3. The maximum + * buffer size must be a constant and not larger than 300. */ +#define nm_strquote_a(trunc_at, str) \ + ({ \ + const char *const _str = (str); \ + \ + (_str ? ({ \ + const gsize _trunc_at = (trunc_at); \ + const gsize _strlen_trunc = NM_MIN(strlen(_str), _trunc_at); \ + char * _buf; \ + \ + G_STATIC_ASSERT_EXPR((trunc_at) <= 300); \ + \ + _buf = g_alloca(_strlen_trunc + 3); \ + _buf[0] = '"'; \ + memcpy(&_buf[1], _str, _strlen_trunc); \ + _buf[_strlen_trunc + 1] = _str[_strlen_trunc] ? '^' : '"'; \ + _buf[_strlen_trunc + 2] = '\0'; \ + _buf; \ + }) \ + : "(null)"); \ + }) + +#define nm_sprintf_buf(buf, format, ...) \ + ({ \ + char *_buf = (buf); \ + int _buf_len; \ + \ + /* some static assert trying to ensure that the buffer is statically allocated. + * It disallows a buffer size of sizeof(gpointer) to catch that. */ \ + G_STATIC_ASSERT(G_N_ELEMENTS(buf) == sizeof(buf) && sizeof(buf) != sizeof(char *)); \ + _buf_len = g_snprintf(_buf, sizeof(buf), "" format "", ##__VA_ARGS__); \ + nm_assert(_buf_len < sizeof(buf)); \ + _buf; \ + }) + +#define nm_vsprintf_buf_or_alloc(format, va_last_arg, sbuf_stack, out_sbuf_heap, out_len) \ + ({ \ + const char *const _format = (format); \ + char *const _sbuf_stack = (sbuf_stack); \ + char **const _out_sbuf_heap = (out_sbuf_heap); \ + gsize *const _out_len = (out_len); \ + const char * _msg; \ + va_list _va_args; \ + int _l; \ + \ + G_STATIC_ASSERT_EXPR(G_N_ELEMENTS(sbuf_stack) > sizeof(_sbuf_stack)); \ + \ + va_start(_va_args, va_last_arg); \ + _l = g_vsnprintf(_sbuf_stack, sizeof(sbuf_stack), _format, _va_args); \ + va_end(_va_args); \ + \ + nm_assert(_l >= 0 && _l < G_MAXINT); \ + \ + if ((gsize) _l >= sizeof(sbuf_stack)) { \ + const gsize _l2 = ((gsize) _l) + 1u; \ + char * _sbuf_heap; \ + \ + /* Don't use g_strdup_vprintf() here either, because that also needs + * to first determine the length (which is commonly does by printing + * to a stack allocated buffer of size 1. We already know the required + * size. */ \ + \ + _sbuf_heap = g_malloc(_l2); \ + \ + va_start(_va_args, va_last_arg); \ + _l = g_vsnprintf(_sbuf_heap, _l2, _format, _va_args); \ + va_end(_va_args); \ + \ + nm_assert(_l >= 0 && ((gsize) _l) == _l2 - 1u); \ + \ + _msg = _sbuf_heap; \ + *_out_sbuf_heap = _sbuf_heap; \ + } else { \ + _msg = _sbuf_stack; \ + *_out_sbuf_heap = NULL; \ + } \ + \ + nm_assert(strlen(_msg) == (gsize) _l); \ + NM_SET_OUT(_out_len, (gsize) _l); \ + \ + _msg; \ + }) + +/* it is "unsafe" because @bufsize must not be a constant expression and + * there is no check at compiletime. Regardless of that, the buffer size + * must not be larger than 300 bytes, as this gets stack allocated. */ +#define nm_sprintf_buf_unsafe_a(bufsize, format, ...) \ + ({ \ + char *_buf; \ + int _buf_len; \ + typeof(bufsize) _bufsize = (bufsize); \ + \ + nm_assert(_bufsize <= 300); \ + \ + _buf = g_alloca(_bufsize); \ + _buf_len = g_snprintf(_buf, _bufsize, "" format "", ##__VA_ARGS__); \ + nm_assert(_buf_len >= 0 && _buf_len < _bufsize); \ + _buf; \ + }) + +#define nm_sprintf_bufa(bufsize, format, ...) \ + ({ \ + G_STATIC_ASSERT_EXPR((bufsize) <= 300); \ + nm_sprintf_buf_unsafe_a((bufsize), format, ##__VA_ARGS__); \ + }) + +/* aims to alloca() a buffer and fill it with printf(format, name). + * Note that format must not contain any format specifier except + * "%s". + * If the resulting string would be too large for stack allocation, + * it allocates a buffer with g_malloc() and assigns it to *p_val_to_free. */ +#define nm_construct_name_a(format, name, p_val_to_free) \ + ({ \ + const char *const _name = (name); \ + char **const _p_val_to_free = (p_val_to_free); \ + const gsize _name_len = strlen(_name); \ + char * _buf2; \ + \ + nm_assert(_p_val_to_free && !*_p_val_to_free); \ + if (NM_STRLEN(format) <= 290 && _name_len < (gsize)(290 - NM_STRLEN(format))) \ + _buf2 = nm_sprintf_buf_unsafe_a(NM_STRLEN(format) + _name_len, format, _name); \ + else { \ + _buf2 = g_strdup_printf(format, _name); \ + *_p_val_to_free = _buf2; \ + } \ + (const char *) _buf2; \ + }) + +/*****************************************************************************/ + +#ifdef _G_BOOLEAN_EXPR + /* g_assert() uses G_LIKELY(), which in turn uses _G_BOOLEAN_EXPR(). + * As glib's implementation uses a local variable _g_boolean_var_, + * we cannot do + * g_assert (some_macro ()); + * where some_macro() itself expands to ({g_assert(); ...}). + * In other words, you cannot have a g_assert() inside a g_assert() + * without getting a -Werror=shadow failure. + * + * Workaround that by re-defining _G_BOOLEAN_EXPR() + **/ + #undef _G_BOOLEAN_EXPR + #define _G_BOOLEAN_EXPR(expr) NM_BOOLEAN_EXPR(expr) +#endif + +/*****************************************************************************/ + +#define NM_PID_T_INVAL ((pid_t) -1) + +/*****************************************************************************/ + +NM_AUTO_DEFINE_FCN_VOID0(GMutex *, _nm_auto_unlock_g_mutex, g_mutex_unlock); + +#define nm_auto_unlock_g_mutex nm_auto(_nm_auto_unlock_g_mutex) + +#define _NM_G_MUTEX_LOCKED(lock, uniq) \ + _nm_unused nm_auto_unlock_g_mutex GMutex *NM_UNIQ_T(nm_lock, uniq) = ({ \ + GMutex *const _lock = (lock); \ + \ + g_mutex_lock(_lock); \ + _lock; \ + }) + +#define NM_G_MUTEX_LOCKED(lock) _NM_G_MUTEX_LOCKED(lock, NM_UNIQ) + +/*****************************************************************************/ + +#endif /* __NM_MACROS_INTERNAL_H__ */ diff --git a/src/libnm-glib-aux/nm-obj.h b/src/libnm-glib-aux/nm-obj.h new file mode 100644 index 0000000..2062f66 --- /dev/null +++ b/src/libnm-glib-aux/nm-obj.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_OBJ_H__ +#define __NM_OBJ_H__ + +/*****************************************************************************/ + +#define NM_OBJ_REF_COUNT_STACKINIT (G_MAXINT) + +typedef struct _NMObjBaseInst NMObjBaseInst; +typedef struct _NMObjBaseClass NMObjBaseClass; + +struct _NMObjBaseInst { + /* The first field of NMObjBaseInst is compatible with GObject. + * Basically, NMObjBaseInst is an abstract base type of GTypeInstance. + * + * If you do it right, you may derive a type of NMObjBaseInst as a proper GTypeInstance. + * That involves allocating a GType for it, which can be inconvenient because + * a GType is dynamically created (and the class can no longer be immutable + * memory). + * + * Even if your implementation of NMObjBaseInst is not a full fledged GType(Instance), + * you still can use GTypeInstances in the same context as you can decide based on the + * NMObjBaseClass with what kind of object you are dealing with. + * + * Basically, the only thing NMObjBaseInst gives you is access to an + * NMObjBaseClass instance. + */ + union { + const NMObjBaseClass *klass; + GTypeInstance g_type_instance; + }; +}; + +struct _NMObjBaseClass { + /* NMObjBaseClass is the base class of all NMObjBaseInst implementations. + * Note that it is also an abstract super class of GTypeInstance, that means + * you may implement a NMObjBaseClass as a subtype of GTypeClass. + * + * For that to work, you must properly set the GTypeClass instance (and its + * GType). + * + * Note that to implement a NMObjBaseClass that is *not* a GTypeClass, you wouldn't + * set the GType. Hence, this field is only useful for type implementations that actually + * extend GTypeClass. + * + * In a way it is wrong that NMObjBaseClass has the GType member, because it is + * a base class of GTypeClass and doesn't necessarily use the GType. However, + * it is here so that G_TYPE_CHECK_INSTANCE_TYPE() and friends work correctly + * on any NMObjectClass. That means, while not necessary, it is convenient that + * a NMObjBaseClass has all members of GTypeClass. + * Also note that usually you have only one instance of a certain type, so this + * wastes just a few bytes for the unneeded GType. + */ + union { + GType g_type; + GTypeClass g_type_class; + }; +}; + +/*****************************************************************************/ + +#endif /* __NM_OBJ_H__ */ diff --git a/src/libnm-glib-aux/nm-random-utils.c b/src/libnm-glib-aux/nm-random-utils.c new file mode 100644 index 0000000..56b99d5 --- /dev/null +++ b/src/libnm-glib-aux/nm-random-utils.c @@ -0,0 +1,148 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-random-utils.h" + +#include + +#if USE_SYS_RANDOM_H + #include +#else + #include +#endif + +#include "nm-shared-utils.h" + +/*****************************************************************************/ + +/** + * nm_utils_random_bytes: + * @p: the buffer to fill + * @n: the number of bytes to write to @p. + * + * Uses getrandom() or reads /dev/urandom to fill the buffer + * with random data. If all fails, as last fallback it uses + * GRand to fill the buffer with pseudo random numbers. + * The function always succeeds in writing some random numbers + * to the buffer. The return value of FALSE indicates that the + * obtained bytes are probably not of good randomness. + * + * Returns: whether the written bytes are good. If you + * don't require good randomness, you can ignore the return + * value. + * + * Note that if calling getrandom() fails because there is not enough + * entropy (at early boot), the function will read /dev/urandom. + * Which of course, still has low entropy, and cause kernel to log + * a warning. + */ +gboolean +nm_utils_random_bytes(void *p, size_t n) +{ + int fd; + int r; + gboolean has_high_quality = TRUE; + gboolean urandom_success; + guint8 * buf = p; + gboolean avoid_urandom = FALSE; + + g_return_val_if_fail(p, FALSE); + g_return_val_if_fail(n > 0, FALSE); + +#if HAVE_GETRANDOM + { + static gboolean have_syscall = TRUE; + + if (have_syscall) { + r = getrandom(buf, n, GRND_NONBLOCK); + if (r > 0) { + if ((size_t) r == n) + return TRUE; + + /* no or partial read. There is not enough entropy. + * Fill the rest reading from urandom, and remember that + * some bits are not high quality. */ + nm_assert(r < n); + buf += r; + n -= r; + has_high_quality = FALSE; + + /* At this point, we don't want to read /dev/urandom, because + * the entropy pool is low (early boot?), and asking for more + * entropy causes kernel messages to be logged. + * + * We use our fallback via GRand. Note that g_rand_new() also + * tries to seed itself with data from /dev/urandom, but since + * we reuse the instance, it shouldn't matter. */ + avoid_urandom = TRUE; + } else { + if (errno == ENOSYS) { + /* no support for getrandom(). We don't know whether + * we urandom will give us good quality. Assume yes. */ + have_syscall = FALSE; + } else { + /* unknown error. We'll read urandom below, but we don't have + * high-quality randomness. */ + has_high_quality = FALSE; + } + } + } + } +#endif + + urandom_success = FALSE; + if (!avoid_urandom) { +fd_open: + fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY); + if (fd < 0) { + r = errno; + if (r == EINTR) + goto fd_open; + } else { + r = nm_utils_fd_read_loop_exact(fd, buf, n, TRUE); + nm_close(fd); + if (r >= 0) + urandom_success = TRUE; + } + } + + if (!urandom_success) { + static _nm_thread_local GRand *rand = NULL; + gsize i; + int j; + + /* we failed to fill the bytes reading from urandom. + * Fill the bits using GRand pseudo random numbers. + * + * We don't have good quality. + */ + has_high_quality = FALSE; + + if (G_UNLIKELY(!rand)) + rand = g_rand_new(); + + nm_assert(n > 0); + i = 0; + for (;;) { + const union { + guint32 v32; + guint8 v8[4]; + } v = { + .v32 = g_rand_int(rand), + }; + + for (j = 0; j < 4;) { + buf[i++] = v.v8[j++]; + if (i >= n) + goto done; + } + } +done:; + } + + return has_high_quality; +} diff --git a/src/libnm-glib-aux/nm-random-utils.h b/src/libnm-glib-aux/nm-random-utils.h new file mode 100644 index 0000000..d0eae10 --- /dev/null +++ b/src/libnm-glib-aux/nm-random-utils.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_RANDOM_UTILS_H__ +#define __NM_RANDOM_UTILS_H__ + +gboolean nm_utils_random_bytes(void *p, size_t n); + +#endif /* __NM_RANDOM_UTILS_H__ */ diff --git a/src/libnm-glib-aux/nm-ref-string.c b/src/libnm-glib-aux/nm-ref-string.c new file mode 100644 index 0000000..93e97c7 --- /dev/null +++ b/src/libnm-glib-aux/nm-ref-string.c @@ -0,0 +1,190 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-ref-string.h" + +/*****************************************************************************/ + +G_LOCK_DEFINE_STATIC(gl_lock); +static GHashTable *gl_hash; + +/*****************************************************************************/ + +static void +_ref_string_get(const NMRefString *rstr, const char **out_str, gsize *out_len) +{ + if (rstr->len == G_MAXSIZE) { + *out_len = rstr->_priv_lookup.l_len; + *out_str = rstr->_priv_lookup.l_str; + } else { + *out_len = rstr->len; + *out_str = rstr->str; + } +} + +static guint +_ref_string_hash(gconstpointer ptr) +{ + const char *cstr; + gsize len; + + _ref_string_get(ptr, &cstr, &len); + return nm_hash_mem(1463435489u, cstr, len); +} + +static gboolean +_ref_string_equal(gconstpointer ptr_a, gconstpointer ptr_b) +{ + const char *cstr_a; + const char *cstr_b; + gsize len_a; + gsize len_b; + + _ref_string_get(ptr_a, &cstr_a, &len_a); + _ref_string_get(ptr_b, &cstr_b, &len_b); + + /* memcmp() accepts "n=0" argument, but it's not clear whether in that case + * all pointers must still be valid. The input pointer might be provided by + * the user via nm_ref_string_new_len(), and for len=0 we want to allow + * also invalid pointers. Hence, this extra "len_a==0" check. */ + return len_a == len_b && (len_a == 0 || (memcmp(cstr_a, cstr_b, len_a) == 0)); +} + +/*****************************************************************************/ + +void +_nm_assert_nm_ref_string(NMRefString *rstr) +{ + int r; + + nm_assert(rstr); + + if (NM_MORE_ASSERTS > 0) { + r = g_atomic_int_get(&rstr->_ref_count); + nm_assert(r > 0); + nm_assert(r < G_MAXINT); + } + + nm_assert(rstr->str[rstr->len] == '\0'); + + if (NM_MORE_ASSERTS > 10) { + G_LOCK(gl_lock); + r = g_atomic_int_get(&rstr->_ref_count); + nm_assert(r > 0); + nm_assert(r < G_MAXINT); + + nm_assert(rstr == g_hash_table_lookup(gl_hash, rstr)); + G_UNLOCK(gl_lock); + } +} + +/** + * nm_ref_string_new_len: + * @cstr: the string to intern. Must contain @len bytes. + * If @len is zero, @cstr may be %NULL. Note that it is + * acceptable that the string contains a NUL character + * within the first @len bytes. That is, the string is + * not treated as a NUL terminated string, but as binary. + * Also, contrary to strncpy(), this will read all the + * first @len bytes. It won't stop at the first NUL. + * @len: the length of the string (usually there is no NUL character + * within the first @len bytes, but that would be acceptable as well + * to add binary data). + * + * Note that the resulting NMRefString instance will always be NUL terminated + * (at position @len). + * + * Note that NMRefString are always interned/deduplicated. If such a string + * already exists, the existing instance will be referred and returned. + * + * + * Since all NMRefString are shared and interned, you may use + * pointer equality to compare them. Note that if a NMRefString contains + * a NUL character (meaning, if + * + * strlen (nm_ref_string_get_str (str)) != nm_ref_string_get_len (str) + * + * ), then pointer in-equality does not mean that the NUL terminated strings + * are also unequal. In other words, for strings that contain NUL characters, + * + * if (str1 != str2) + * assert (!nm_streq0 (nm_ref_string_get_str (str1), nm_ref_string_get_str (str2))); + * + * might not hold! + * + * + * NMRefString is thread-safe. + * + * Returns: (transfer full): the interned string. This is + * never %NULL, but note that %NULL is also a valid NMRefString. + * The result must be unrefed with nm_ref_string_unref(). + */ +NMRefString * +nm_ref_string_new_len(const char *cstr, gsize len) +{ + NMRefString *rstr; + + /* @len cannot be close to G_MAXSIZE. For one, that would mean our call + * to malloc() below overflows. Also, we use G_MAXSIZE as special length + * to indicate using _priv_lookup. */ + nm_assert(len < G_MAXSIZE - G_STRUCT_OFFSET(NMRefString, str) - 1u); + + G_LOCK(gl_lock); + + if (G_UNLIKELY(!gl_hash)) { + gl_hash = g_hash_table_new_full(_ref_string_hash, _ref_string_equal, g_free, NULL); + rstr = NULL; + } else { + NMRefString rr_lookup = { + .len = G_MAXSIZE, + ._priv_lookup = + { + .l_len = len, + .l_str = cstr, + }, + }; + + rstr = g_hash_table_lookup(gl_hash, &rr_lookup); + } + + if (rstr) { + nm_assert(({ + int r = g_atomic_int_get(&rstr->_ref_count); + + (r >= 0 && r < G_MAXINT); + })); + g_atomic_int_inc(&rstr->_ref_count); + } else { + rstr = g_malloc((G_STRUCT_OFFSET(NMRefString, str) + 1u) + len); + if (len > 0) + memcpy((char *) rstr->str, cstr, len); + ((char *) rstr->str)[len] = '\0'; + *((gsize *) &rstr->len) = len; + rstr->_ref_count = 1; + + if (!g_hash_table_add(gl_hash, rstr)) + nm_assert_not_reached(); + } + + G_UNLOCK(gl_lock); + + return rstr; +} + +void +_nm_ref_string_unref_slow_path(NMRefString *rstr) +{ + G_LOCK(gl_lock); + + nm_assert(g_hash_table_lookup(gl_hash, rstr) == rstr); + + if (G_LIKELY(g_atomic_int_dec_and_test(&rstr->_ref_count))) { + if (!g_hash_table_remove(gl_hash, rstr)) + nm_assert_not_reached(); + } + + G_UNLOCK(gl_lock); +} + +/*****************************************************************************/ diff --git a/src/libnm-glib-aux/nm-ref-string.h b/src/libnm-glib-aux/nm-ref-string.h new file mode 100644 index 0000000..8ef44d4 --- /dev/null +++ b/src/libnm-glib-aux/nm-ref-string.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_REF_STRING_H__ +#define __NM_REF_STRING_H__ + +/*****************************************************************************/ + +typedef struct _NMRefString { + const gsize len; + union { + struct { + volatile int _ref_count; + const char str[]; + }; + struct { + /* This union field is only used during lookup by external string. + * In that case, len will be set to G_MAXSIZE, and the actual len/str values + * are set in _priv_lookup. */ + gsize l_len; + const char *l_str; + } _priv_lookup; + }; +} NMRefString; + +/*****************************************************************************/ + +void _nm_assert_nm_ref_string(NMRefString *rstr); + +static inline void +nm_assert_nm_ref_string(NMRefString *rstr) +{ +#if NM_MORE_ASSERTS + _nm_assert_nm_ref_string(rstr); +#endif +} + +/*****************************************************************************/ + +NMRefString *nm_ref_string_new_len(const char *cstr, gsize len); + +static inline NMRefString * +nm_ref_string_new(const char *cstr) +{ + return cstr ? nm_ref_string_new_len(cstr, strlen(cstr)) : NULL; +} + +/*****************************************************************************/ + +static inline NMRefString * +nm_ref_string_ref(NMRefString *rstr) +{ + if (rstr) { + nm_assert_nm_ref_string(rstr); + g_atomic_int_inc(&rstr->_ref_count); + } + return rstr; +} + +void _nm_ref_string_unref_slow_path(NMRefString *rstr); + +static inline void +nm_ref_string_unref(NMRefString *rstr) +{ + int r; + + if (!rstr) + return; + + nm_assert_nm_ref_string(rstr); + + /* fast-path: first try to decrement the ref-count without bringing it + * to zero. */ + r = rstr->_ref_count; + if (G_LIKELY(r > 1 && g_atomic_int_compare_and_exchange(&rstr->_ref_count, r, r - 1))) + return; + + _nm_ref_string_unref_slow_path(rstr); +} + +NM_AUTO_DEFINE_FCN_VOID(NMRefString *, _nm_auto_ref_string, nm_ref_string_unref); +#define nm_auto_ref_string nm_auto(_nm_auto_ref_string) + +/*****************************************************************************/ + +static inline const char * +nm_ref_string_get_str(NMRefString *rstr) +{ + return rstr ? rstr->str : NULL; +} + +static inline gsize +nm_ref_string_get_len(NMRefString *rstr) +{ + return rstr ? rstr->len : 0u; +} + +static inline gboolean +nm_ref_string_equals_str(NMRefString *rstr, const char *s) +{ + /* Note that rstr->len might be greater than strlen(rstr->str). This function does + * not cover that and would ignore everything after the first NUL byte. If you need + * that distinction, this function is not for you. */ + + return rstr ? (s && nm_streq(rstr->str, s)) : (s == NULL); +} + +static inline gboolean +NM_IS_REF_STRING(NMRefString *rstr) +{ + if (rstr) + nm_assert_nm_ref_string(rstr); + + /* Technically, %NULL is also a valid NMRefString (according to nm_ref_string_new(), + * nm_ref_string_get_str() and nm_ref_string_unref()). However, NM_IS_REF_STRING() + * does not think so. If callers want to allow %NULL, they need to check + * separately. */ + return !!rstr; +} + +static inline NMRefString * +NM_REF_STRING_UPCAST(const char *str) +{ + NMRefString *rstr; + + if (!str) + return NULL; + + rstr = (gpointer)(((char *) str) - G_STRUCT_OFFSET(NMRefString, str)); + nm_assert_nm_ref_string(rstr); + return rstr; +} + +#endif /* __NM_REF_STRING_H__ */ diff --git a/src/libnm-glib-aux/nm-secret-utils.c b/src/libnm-glib-aux/nm-secret-utils.c new file mode 100644 index 0000000..c764b6e --- /dev/null +++ b/src/libnm-glib-aux/nm-secret-utils.c @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + * Copyright (C) 2015 - 2019 Jason A. Donenfeld . All Rights Reserved. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-secret-utils.h" + +#include + +/*****************************************************************************/ + +void +nm_explicit_bzero(void *s, gsize n) +{ + /* gracefully handle n == 0. This is important, callers rely on it. */ + if (G_UNLIKELY(n == 0)) + return; + + nm_assert(s); + +#if defined(HAVE_DECL_EXPLICIT_BZERO) && HAVE_DECL_EXPLICIT_BZERO + explicit_bzero(s, n); +#else + { + volatile guint8 *p = s; + + memset(s, '\0', n); + while (n-- > 0) + *(p++) = '\0'; + } +#endif +} + +void +nm_free_secret(char *secret) +{ + gsize len; + + if (!secret) + return; + +#if GLIB_CHECK_VERSION(2, 44, 0) + /* Here we mix malloc() and g_malloc() API. Usually we avoid this, + * however since glib 2.44.0 we are in fact guaranteed that g_malloc()/g_free() + * just wraps malloc()/free(), so this is actually fine. + * + * See https://gitlab.gnome.org/GNOME/glib/commit/3be6ed60aa58095691bd697344765e715a327fc1 + */ + len = malloc_usable_size(secret); +#else + len = strlen(secret); +#endif + + nm_explicit_bzero(secret, len); + g_free(secret); +} + +/*****************************************************************************/ + +char * +nm_secret_strchomp(char *secret) +{ + gsize len; + + g_return_val_if_fail(secret, NULL); + + /* it's actually identical to g_strchomp(). However, + * the glib function does not document, that it clears the + * memory. For @secret, we don't only want to truncate trailing + * spaces, we want to overwrite them with NUL. */ + + len = strlen(secret); + while (len--) { + if (g_ascii_isspace((guchar) secret[len])) + secret[len] = '\0'; + else + break; + } + + return secret; +} + +/*****************************************************************************/ + +GBytes * +nm_secret_copy_to_gbytes(gconstpointer mem, gsize mem_len) +{ + NMSecretBuf *b; + + if (mem_len == 0) + return g_bytes_new_static("", 0); + + nm_assert(mem); + + /* NUL terminate the buffer. + * + * The entire buffer is already malloc'ed and likely has some room for padding. + * Thus, in many situations, this additional byte will cause no overhead in + * practice. + * + * Even if it causes an overhead, do it just for safety. Yes, the returned + * bytes is not a NUL terminated string and no user must rely on this. Do + * not treat binary data as NUL terminated strings, unless you know what + * you are doing. Anyway, defensive FTW. + */ + + b = nm_secret_buf_new(mem_len + 1); + memcpy(b->bin, mem, mem_len); + b->bin[mem_len] = 0; + return nm_secret_buf_to_gbytes_take(b, mem_len); +} + +/*****************************************************************************/ + +NMSecretBuf * +nm_secret_buf_new(gsize len) +{ + NMSecretBuf *secret; + + nm_assert(len > 0); + + secret = g_malloc(sizeof(NMSecretBuf) + len); + *((gsize *) &(secret->len)) = len; + return secret; +} + +static void +_secret_buf_free(gpointer user_data) +{ + NMSecretBuf *secret = user_data; + + nm_assert(secret); + nm_assert(secret->len > 0); + + nm_explicit_bzero(secret->bin, secret->len); + g_free(user_data); +} + +GBytes * +nm_secret_buf_to_gbytes_take(NMSecretBuf *secret, gssize actual_len) +{ + nm_assert(secret); + nm_assert(secret->len > 0); + nm_assert(actual_len == -1 || (actual_len >= 0 && actual_len <= secret->len)); + return g_bytes_new_with_free_func(secret->bin, + actual_len >= 0 ? (gsize) actual_len : secret->len, + _secret_buf_free, + secret); +} + +/*****************************************************************************/ + +/** + * nm_utils_memeqzero_secret: + * @data: the data pointer to check (may be %NULL if @length is zero). + * @length: the number of bytes to check. + * + * Checks that all bytes are zero. This always takes the same amount + * of time to prevent timing attacks. + * + * Returns: whether all bytes are zero. + */ +gboolean +nm_utils_memeqzero_secret(gconstpointer data, gsize length) +{ + const guint8 *const key = data; + volatile guint8 acc = 0; + gsize i; + + for (i = 0; i < length; i++) { + acc |= key[i]; + asm volatile("" : "=r"(acc) : "0"(acc)); + } + return 1 & ((acc - 1) >> 8); +} diff --git a/src/libnm-glib-aux/nm-secret-utils.h b/src/libnm-glib-aux/nm-secret-utils.h new file mode 100644 index 0000000..ac27963 --- /dev/null +++ b/src/libnm-glib-aux/nm-secret-utils.h @@ -0,0 +1,273 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_SECRET_UTILS_H__ +#define __NM_SECRET_UTILS_H__ + +#include "nm-macros-internal.h" + +/*****************************************************************************/ + +void nm_explicit_bzero(void *s, gsize n); + +/*****************************************************************************/ + +char *nm_secret_strchomp(char *secret); + +/*****************************************************************************/ + +void nm_free_secret(char *secret); + +NM_AUTO_DEFINE_FCN0(char *, _nm_auto_free_secret, nm_free_secret); +/** + * nm_auto_free_secret: + * + * Call g_free() on a variable location when it goes out of scope. + * Also, previously, calls memset(loc, 0, strlen(loc)) to clear out + * the secret. + */ +#define nm_auto_free_secret nm_auto(_nm_auto_free_secret) + +/*****************************************************************************/ + +GBytes *nm_secret_copy_to_gbytes(gconstpointer mem, gsize mem_len); + +/*****************************************************************************/ + +/* NMSecretPtr is a pair of malloc'ed data pointer and the length of the + * data. The purpose is to use it in combination with nm_auto_clear_secret_ptr + * which ensures that the data pointer (with all len bytes) is cleared upon + * cleanup. */ +typedef struct { + gsize len; + + /* the data pointer. This pointer must be allocated with malloc (at least + * when used with nm_secret_ptr_clear()). */ + union { + char * str; + void * ptr; + guint8 *bin; + }; +} NMSecretPtr; + +static inline void +nm_secret_ptr_bzero(NMSecretPtr *secret) +{ + if (secret) { + if (secret->len > 0) { + if (secret->ptr) + nm_explicit_bzero(secret->ptr, secret->len); + } + } +} + +#define nm_auto_bzero_secret_ptr nm_auto(nm_secret_ptr_bzero) + +static inline void +nm_secret_ptr_clear(NMSecretPtr *secret) +{ + if (secret) { + if (secret->len > 0) { + if (secret->ptr) + nm_explicit_bzero(secret->ptr, secret->len); + secret->len = 0; + } + nm_clear_g_free(&secret->ptr); + } +} + +#define nm_auto_clear_secret_ptr nm_auto(nm_secret_ptr_clear) + +#define NM_SECRET_PTR_INIT() \ + ((const NMSecretPtr){ \ + .len = 0, \ + .ptr = NULL, \ + }) + +#define NM_SECRET_PTR_STATIC(_len) \ + ((const NMSecretPtr){ \ + .len = _len, \ + .ptr = ((guint8[_len]){}), \ + }) + +#define NM_SECRET_PTR_ARRAY(_arr) \ + ((const NMSecretPtr){ \ + .len = G_N_ELEMENTS(_arr) * sizeof((_arr)[0]), \ + .ptr = &((_arr)[0]), \ + }) + +static inline void +nm_secret_ptr_clear_static(const NMSecretPtr *secret) +{ + if (secret) { + if (secret->len > 0) { + nm_assert(secret->ptr); + nm_explicit_bzero(secret->ptr, secret->len); + } + } +} + +#define nm_auto_clear_static_secret_ptr nm_auto(nm_secret_ptr_clear_static) + +static inline void +nm_secret_ptr_move(NMSecretPtr *dst, NMSecretPtr *src) +{ + if (dst && dst != src) { + *dst = *src; + src->len = 0; + src->ptr = NULL; + } +} + +/*****************************************************************************/ + +typedef struct { + const gsize len; + union { + char str[0]; + guint8 bin[0]; + }; +} NMSecretBuf; + +static inline void +_nm_auto_free_secret_buf(NMSecretBuf **ptr) +{ + NMSecretBuf *b = *ptr; + + if (b) { + nm_assert(b->len > 0); + nm_explicit_bzero(b->bin, b->len); + g_free(b); + } +} +#define nm_auto_free_secret_buf nm_auto(_nm_auto_free_secret_buf) + +NMSecretBuf *nm_secret_buf_new(gsize len); + +GBytes *nm_secret_buf_to_gbytes_take(NMSecretBuf *secret, gssize actual_len); + +/*****************************************************************************/ + +gboolean nm_utils_memeqzero_secret(gconstpointer data, gsize length); + +/*****************************************************************************/ + +/** + * nm_secret_mem_realloc: + * @m_old: the current buffer of length @cur_len. + * @do_bzero_mem: if %TRUE, bzero the old buffer + * @cur_len: the current buffer length of @m_old. It is necessary for bzero. + * @new_len: the desired new length + * + * If @do_bzero_mem is false, this is like g_realloc(). + * Otherwise, this will allocate a new buffer of the desired size, copy over the + * old data, and bzero the old buffer before freeing it. As such, it also behaves + * similar to g_realloc(), with the overhead of nm_explicit_bzero() and using + * malloc/free instead of realloc(). + * + * Returns: the new allocated buffer. Think of it behaving like g_realloc(). + */ +static inline gpointer +nm_secret_mem_realloc(gpointer m_old, gboolean do_bzero_mem, gsize cur_len, gsize new_len) +{ + gpointer m_new; + + nm_assert(m_old || cur_len == 0); + + if (do_bzero_mem && G_LIKELY(cur_len > 0)) { + m_new = g_malloc(new_len); + if (G_LIKELY(new_len > 0)) + memcpy(m_new, m_old, NM_MIN(cur_len, new_len)); + nm_explicit_bzero(m_old, cur_len); + g_free(m_old); + } else + m_new = g_realloc(m_old, new_len); + + return m_new; +} + +/** + * nm_secret_mem_try_realloc: + * @m_old: the current buffer of length @cur_len. + * @do_bzero_mem: if %TRUE, bzero the old buffer + * @cur_len: the current buffer length of @m_old. It is necessary for bzero. + * @new_len: the desired new length + * + * If @do_bzero_mem is false, this is like g_try_realloc(). + * Otherwise, this will try to allocate a new buffer of the desired size, copy over the + * old data, and bzero the old buffer before freeing it. As such, it also behaves + * similar to g_try_realloc(), with the overhead of nm_explicit_bzero() and using + * malloc/free instead of realloc(). + * + * Returns: the new allocated buffer or NULL. Think of it behaving like g_try_realloc(). + */ +static inline gpointer +nm_secret_mem_try_realloc(gpointer m_old, gboolean do_bzero_mem, gsize cur_len, gsize new_len) +{ + gpointer m_new; + + nm_assert(m_old || cur_len == 0); + + if (do_bzero_mem && G_LIKELY(cur_len > 0)) { + if (G_UNLIKELY(new_len == 0)) + m_new = NULL; + else { + m_new = g_try_malloc(new_len); + if (!m_new) + return NULL; + memcpy(m_new, m_old, NM_MIN(cur_len, new_len)); + } + nm_explicit_bzero(m_old, cur_len); + g_free(m_old); + return m_new; + } + + return g_try_realloc(m_old, new_len); +} + +/** + * nm_secret_mem_try_realloc_take: + * @m_old: the current buffer of length @cur_len. + * @do_bzero_mem: if %TRUE, bzero the old buffer + * @cur_len: the current buffer length of @m_old. It is necessary for bzero. + * @new_len: the desired new length + * + * This works like nm_secret_mem_try_realloc(), which is not unlike g_try_realloc(). + * The difference is, if we fail to allocate a new buffer, then @m_old will be + * freed (and possibly cleared). This differs from plain realloc(), where the + * old buffer is unchanged if the operation fails. + * + * Returns: the new allocated buffer or NULL. Think of it behaving like g_try_realloc() + * but it will always free @m_old. + */ +static inline gpointer +nm_secret_mem_try_realloc_take(gpointer m_old, gboolean do_bzero_mem, gsize cur_len, gsize new_len) +{ + gpointer m_new; + + nm_assert(m_old || cur_len == 0); + + if (do_bzero_mem && G_LIKELY(cur_len > 0)) { + if (G_UNLIKELY(new_len == 0)) + m_new = NULL; + else { + m_new = g_try_malloc(new_len); + if (G_LIKELY(m_new)) + memcpy(m_new, m_old, NM_MIN(cur_len, new_len)); + } + nm_explicit_bzero(m_old, cur_len); + g_free(m_old); + return m_new; + } + + m_new = g_try_realloc(m_old, new_len); + if (G_UNLIKELY(!m_new && new_len > 0)) + g_free(m_old); + return m_new; +} + +/*****************************************************************************/ + +#endif /* __NM_SECRET_UTILS_H__ */ diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c new file mode 100644 index 0000000..6271354 --- /dev/null +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -0,0 +1,6115 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-shared-utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nm-errno.h" +#include "nm-str-buf.h" + +G_STATIC_ASSERT(sizeof(NMEtherAddr) == 6); +G_STATIC_ASSERT(_nm_alignof(NMEtherAddr) == 1); + +G_STATIC_ASSERT(sizeof(NMUtilsNamedEntry) == sizeof(const char *)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMUtilsNamedValue, value_ptr) == sizeof(const char *)); + +/*****************************************************************************/ + +const char _nm_hexchar_table_lower[16] = "0123456789abcdef"; +const char _nm_hexchar_table_upper[16] = "0123456789ABCDEF"; + +const void *const _NM_PTRARRAY_EMPTY[1] = {NULL}; + +/*****************************************************************************/ + +const NMIPAddr nm_ip_addr_zero = {}; + +/* this initializes a struct in_addr/in6_addr and allows for untrusted + * arguments (like unsuitable @addr_family or @src_len). It's almost safe + * in the sense that it verifies input arguments strictly. Also, it + * uses memcpy() to access @src, so alignment is not an issue. + * + * Only potential pitfalls: + * + * - it allows for @addr_family to be AF_UNSPEC. If that is the case (and the + * caller allows for that), the caller MUST provide @out_addr_family. + * - when setting @dst to an IPv4 address, the trailing bytes are not touched. + * Meaning, if @dst is an NMIPAddr union, only the first bytes will be set. + * If that matter to you, clear @dst before. */ +gboolean +nm_ip_addr_set_from_untrusted(int addr_family, + gpointer dst, + gconstpointer src, + gsize src_len, + int * out_addr_family) +{ + nm_assert(dst); + + switch (addr_family) { + case AF_UNSPEC: + if (!out_addr_family) { + /* when the callers allow undefined @addr_family, they must provide + * an @out_addr_family argument. */ + nm_assert_not_reached(); + return FALSE; + } + switch (src_len) { + case sizeof(struct in_addr): + addr_family = AF_INET; + break; + case sizeof(struct in6_addr): + addr_family = AF_INET6; + break; + default: + return FALSE; + } + break; + case AF_INET: + if (src_len != sizeof(struct in_addr)) + return FALSE; + break; + case AF_INET6: + if (src_len != sizeof(struct in6_addr)) + return FALSE; + break; + default: + /* when the callers allow undefined @addr_family, they must provide + * an @out_addr_family argument. */ + nm_assert(out_addr_family); + return FALSE; + } + + nm_assert(src); + + memcpy(dst, src, src_len); + NM_SET_OUT(out_addr_family, addr_family); + return TRUE; +} + +/*****************************************************************************/ + +G_STATIC_ASSERT(ETH_ALEN == sizeof(struct ether_addr)); +G_STATIC_ASSERT(ETH_ALEN == 6); + +/*****************************************************************************/ + +/** + * nm_utils_inet6_is_token: + * @in6addr: the AF_INET6 address structure + * + * Checks if only the bottom 64bits of the address are set. + * + * Return value: %TRUE or %FALSE + */ +gboolean +_nm_utils_inet6_is_token(const struct in6_addr *in6addr) +{ + if (in6addr->s6_addr[0] || in6addr->s6_addr[1] || in6addr->s6_addr[2] || in6addr->s6_addr[3] + || in6addr->s6_addr[4] || in6addr->s6_addr[5] || in6addr->s6_addr[6] || in6addr->s6_addr[7]) + return FALSE; + + if (in6addr->s6_addr[8] || in6addr->s6_addr[9] || in6addr->s6_addr[10] || in6addr->s6_addr[11] + || in6addr->s6_addr[12] || in6addr->s6_addr[13] || in6addr->s6_addr[14] + || in6addr->s6_addr[15]) + return TRUE; + + return FALSE; +} + +/** + * nm_utils_ipv6_addr_set_interface_identifier: + * @addr: output token encoded as %in6_addr + * @iid: %NMUtilsIPv6IfaceId interface identifier + * + * Converts the %NMUtilsIPv6IfaceId to an %in6_addr (suitable for use + * with Linux platform). This only copies the lower 8 bytes, ignoring + * the /64 network prefix which is expected to be all-zero for a valid + * token. + */ +void +nm_utils_ipv6_addr_set_interface_identifier(struct in6_addr *addr, const NMUtilsIPv6IfaceId iid) +{ + memcpy(addr->s6_addr + 8, &iid.id_u8, 8); +} + +/** + * nm_utils_ipv6_interface_identifier_get_from_addr: + * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token + * @addr: token encoded as %in6_addr + * + * Converts the %in6_addr encoded token (as used by Linux platform) to + * the interface identifier. + */ +void +nm_utils_ipv6_interface_identifier_get_from_addr(NMUtilsIPv6IfaceId * iid, + const struct in6_addr *addr) +{ + memcpy(iid, addr->s6_addr + 8, 8); +} + +/** + * nm_utils_ipv6_interface_identifier_get_from_token: + * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token + * @token: token encoded as string + * + * Converts the %in6_addr encoded token (as used in ip6 settings) to + * the interface identifier. + * + * Returns: %TRUE if the @token is a valid token, %FALSE otherwise + */ +gboolean +nm_utils_ipv6_interface_identifier_get_from_token(NMUtilsIPv6IfaceId *iid, const char *token) +{ + struct in6_addr i6_token; + + g_return_val_if_fail(token, FALSE); + + if (!inet_pton(AF_INET6, token, &i6_token)) + return FALSE; + + if (!_nm_utils_inet6_is_token(&i6_token)) + return FALSE; + + nm_utils_ipv6_interface_identifier_get_from_addr(iid, &i6_token); + return TRUE; +} + +/** + * nm_utils_inet6_interface_identifier_to_token: + * @iid: %NMUtilsIPv6IfaceId interface identifier + * @buf: the destination buffer of at least %NM_UTILS_INET_ADDRSTRLEN + * bytes. + * + * Converts the interface identifier to a string token. + * + * Returns: the input buffer filled with the id as string. + */ +const char * +nm_utils_inet6_interface_identifier_to_token(NMUtilsIPv6IfaceId iid, + char buf[static INET6_ADDRSTRLEN]) +{ + struct in6_addr i6_token = {.s6_addr = { + 0, + }}; + + nm_assert(buf); + nm_utils_ipv6_addr_set_interface_identifier(&i6_token, iid); + return _nm_utils_inet6_ntop(&i6_token, buf); +} + +/*****************************************************************************/ + +pid_t +nm_utils_gettid(void) +{ + return (pid_t) syscall(SYS_gettid); +} + +/* Used for asserting that this function is called on the main-thread. + * The main-thread is determined by remembering the thread-id + * of when the function was called the first time. + * + * When forking, the thread-id is again reset upon first call. */ +gboolean +_nm_assert_on_main_thread(void) +{ + G_LOCK_DEFINE_STATIC(lock); + static pid_t seen_tid; + static pid_t seen_pid; + pid_t tid; + pid_t pid; + gboolean success = FALSE; + + tid = nm_utils_gettid(); + nm_assert(tid != 0); + + G_LOCK(lock); + + if (G_LIKELY(tid == seen_tid)) { + /* we don't care about false positives (when the process forked, and the thread-id + * is accidentally re-used) . It's for assertions only. */ + success = TRUE; + } else { + pid = getpid(); + nm_assert(pid != 0); + + if (seen_tid == 0 || seen_pid != pid) { + /* either this is the first time we call the function, or the process + * forked. In both cases, remember the thread-id. */ + seen_tid = tid; + seen_pid = pid; + success = TRUE; + } + } + + G_UNLOCK(lock); + + return success; +} + +/*****************************************************************************/ + +void +nm_utils_strbuf_append_c(char **buf, gsize *len, char c) +{ + switch (*len) { + case 0: + return; + case 1: + (*buf)[0] = '\0'; + *len = 0; + (*buf)++; + return; + default: + (*buf)[0] = c; + (*buf)[1] = '\0'; + (*len)--; + (*buf)++; + return; + } +} + +void +nm_utils_strbuf_append_bin(char **buf, gsize *len, gconstpointer str, gsize str_len) +{ + switch (*len) { + case 0: + return; + case 1: + if (str_len == 0) { + (*buf)[0] = '\0'; + return; + } + (*buf)[0] = '\0'; + *len = 0; + (*buf)++; + return; + default: + if (str_len == 0) { + (*buf)[0] = '\0'; + return; + } + if (str_len >= *len) { + memcpy(*buf, str, *len - 1); + (*buf)[*len - 1] = '\0'; + *buf = &(*buf)[*len]; + *len = 0; + } else { + memcpy(*buf, str, str_len); + *buf = &(*buf)[str_len]; + (*buf)[0] = '\0'; + *len -= str_len; + } + return; + } +} + +void +nm_utils_strbuf_append_str(char **buf, gsize *len, const char *str) +{ + gsize src_len; + + switch (*len) { + case 0: + return; + case 1: + if (!str || !*str) { + (*buf)[0] = '\0'; + return; + } + (*buf)[0] = '\0'; + *len = 0; + (*buf)++; + return; + default: + if (!str || !*str) { + (*buf)[0] = '\0'; + return; + } + src_len = g_strlcpy(*buf, str, *len); + if (src_len >= *len) { + *buf = &(*buf)[*len]; + *len = 0; + } else { + *buf = &(*buf)[src_len]; + *len -= src_len; + } + return; + } +} + +void +nm_utils_strbuf_append(char **buf, gsize *len, const char *format, ...) +{ + char * p = *buf; + va_list args; + int retval; + + if (*len == 0) + return; + + va_start(args, format); + retval = g_vsnprintf(p, *len, format, args); + va_end(args); + + if ((gsize) retval >= *len) { + *buf = &p[*len]; + *len = 0; + } else { + *buf = &p[retval]; + *len -= retval; + } +} + +/** + * nm_utils_strbuf_seek_end: + * @buf: the input/output buffer + * @len: the input/output length of the buffer. + * + * Commonly, one uses nm_utils_strbuf_append*(), to incrementally + * append strings to the buffer. However, sometimes we need to use + * existing API to write to the buffer. + * After doing so, we want to adjust the buffer counter. + * Essentially, + * + * g_snprintf (buf, len, ...); + * nm_utils_strbuf_seek_end (&buf, &len); + * + * is almost the same as + * + * nm_utils_strbuf_append (&buf, &len, ...); + * + * The only difference is the behavior when the string got truncated: + * nm_utils_strbuf_append() will recognize that and set the remaining + * length to zero. + * + * In general, the behavior is: + * + * - if *len is zero, do nothing + * - if the buffer contains a NUL byte within the first *len characters, + * the buffer is pointed to the NUL byte and len is adjusted. In this + * case, the remaining *len is always >= 1. + * In particular, that is also the case if the NUL byte is at the very last + * position ((*buf)[*len -1]). That happens, when the previous operation + * either fit the string exactly into the buffer or the string was truncated + * by g_snprintf(). The difference cannot be determined. + * - if the buffer contains no NUL bytes within the first *len characters, + * write NUL at the last position, set *len to zero, and point *buf past + * the NUL byte. This would happen with + * + * strncpy (buf, long_str, len); + * nm_utils_strbuf_seek_end (&buf, &len). + * + * where strncpy() does truncate the string and not NUL terminate it. + * nm_utils_strbuf_seek_end() would then NUL terminate it. + */ +void +nm_utils_strbuf_seek_end(char **buf, gsize *len) +{ + gsize l; + char *end; + + nm_assert(len); + nm_assert(buf && *buf); + + if (*len <= 1) { + if (*len == 1 && (*buf)[0]) + goto truncate; + return; + } + + end = memchr(*buf, 0, *len); + if (end) { + l = end - *buf; + nm_assert(l < *len); + + *buf = end; + *len -= l; + return; + } + +truncate: + /* hm, no NUL character within len bytes. + * Just NUL terminate the array and consume them + * all. */ + *buf += *len; + (*buf)[-1] = '\0'; + *len = 0; + return; +} + +/*****************************************************************************/ + +GBytes * +nm_gbytes_get_empty(void) +{ + static GBytes *bytes = NULL; + GBytes * b; + +again: + b = g_atomic_pointer_get(&bytes); + if (G_UNLIKELY(!b)) { + b = g_bytes_new_static("", 0); + if (!g_atomic_pointer_compare_and_exchange(&bytes, NULL, b)) { + g_bytes_unref(b); + goto again; + } + } + return b; +} + +GBytes * +nm_g_bytes_new_from_str(const char *str) +{ + gsize l; + + if (!str) + return NULL; + + /* the returned array is guaranteed to have a trailing '\0' + * character *after* the length. */ + + l = strlen(str); + return g_bytes_new_take(nm_memdup(str, l + 1u), l); +} + +/** + * nm_utils_gbytes_equals: + * @bytes: (allow-none): a #GBytes array to compare. Note that + * %NULL is treated like an #GBytes array of length zero. + * @mem_data: the data pointer with @mem_len bytes + * @mem_len: the length of the data pointer + * + * Returns: %TRUE if @bytes contains the same data as @mem_data. As a + * special case, a %NULL @bytes is treated like an empty array. + */ +gboolean +nm_utils_gbytes_equal_mem(GBytes *bytes, gconstpointer mem_data, gsize mem_len) +{ + gconstpointer p; + gsize l; + + if (!bytes) { + /* as a special case, let %NULL GBytes compare identical + * to an empty array. */ + return (mem_len == 0); + } + + p = g_bytes_get_data(bytes, &l); + return l == mem_len + && (mem_len == 0 /* allow @mem_data to be %NULL */ + || memcmp(p, mem_data, mem_len) == 0); +} + +GVariant * +nm_utils_gbytes_to_variant_ay(GBytes *bytes) +{ + const guint8 *p; + gsize l; + + if (!bytes) { + /* for convenience, accept NULL to return an empty variant */ + return g_variant_new_array(G_VARIANT_TYPE_BYTE, NULL, 0); + } + + p = g_bytes_get_data(bytes, &l); + return g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, p, l, 1); +} + +/*****************************************************************************/ + +#define _variant_singleton_get(create_variant) \ + ({ \ + static GVariant *_singleton = NULL; \ + GVariant * _v; \ + \ +again: \ + _v = g_atomic_pointer_get(&_singleton); \ + if (G_UNLIKELY(!_v)) { \ + _v = (create_variant); \ + nm_assert(_v); \ + nm_assert(g_variant_is_floating(_v)); \ + g_variant_ref_sink(_v); \ + if (!g_atomic_pointer_compare_and_exchange(&_singleton, NULL, _v)) { \ + g_variant_unref(_v); \ + goto again; \ + } \ + } \ + _v; \ + }) + +GVariant * +nm_g_variant_singleton_u_0(void) +{ + return _variant_singleton_get(g_variant_new_uint32(0)); +} + +/*****************************************************************************/ + +GHashTable * +nm_utils_strdict_clone(GHashTable *src) +{ + GHashTable * dst; + GHashTableIter iter; + const char * key; + const char * val; + + if (!src) + return NULL; + + dst = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + g_hash_table_iter_init(&iter, src); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) + g_hash_table_insert(dst, g_strdup(key), g_strdup(val)); + return dst; +} + +/* Convert a hash table with "char *" keys and values to an "a{ss}" GVariant. + * The keys will be sorted asciibetically. + * Returns a floating reference. + */ +GVariant * +nm_utils_strdict_to_variant_ass(GHashTable *strdict) +{ + gs_free NMUtilsNamedValue *values_free = NULL; + NMUtilsNamedValue values_prepared[20]; + const NMUtilsNamedValue * values; + GVariantBuilder builder; + guint i; + guint n; + + values = nm_utils_named_values_from_strdict(strdict, &n, values_prepared, &values_free); + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}")); + for (i = 0; i < n; i++) { + g_variant_builder_add(&builder, "{ss}", values[i].name, values[i].value_str); + } + return g_variant_builder_end(&builder); +} + +/*****************************************************************************/ + +GVariant * +nm_utils_strdict_to_variant_asv(GHashTable *strdict) +{ + gs_free NMUtilsNamedValue *values_free = NULL; + NMUtilsNamedValue values_prepared[20]; + const NMUtilsNamedValue * values; + GVariantBuilder builder; + guint i; + guint n; + + values = nm_utils_named_values_from_strdict(strdict, &n, values_prepared, &values_free); + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + for (i = 0; i < n; i++) { + g_variant_builder_add(&builder, + "{sv}", + values[i].name, + g_variant_new_string(values[i].value_str)); + } + return g_variant_builder_end(&builder); +} + +/*****************************************************************************/ + +/** + * nm_strquote: + * @buf: the output buffer of where to write the quoted @str argument. + * @buf_len: the size of @buf. + * @str: (allow-none): the string to quote. + * + * Writes @str to @buf with quoting. The resulting buffer + * is always NUL terminated, unless @buf_len is zero. + * If @str is %NULL, it writes "(null)". + * + * If @str needs to be truncated, the closing quote is '^' instead + * of '"'. + * + * This is similar to nm_strquote_a(), which however uses alloca() + * to allocate a new buffer. Also, here @buf_len is the size of @buf, + * while nm_strquote_a() has the number of characters to print. The latter + * doesn't include the quoting. + * + * Returns: the input buffer with the quoted string. + */ +const char * +nm_strquote(char *buf, gsize buf_len, const char *str) +{ + const char *const buf0 = buf; + + if (!str) { + nm_utils_strbuf_append_str(&buf, &buf_len, "(null)"); + goto out; + } + + if (G_UNLIKELY(buf_len <= 2)) { + switch (buf_len) { + case 2: + *(buf++) = '^'; + /* fall-through */ + case 1: + *(buf++) = '\0'; + break; + } + goto out; + } + + *(buf++) = '"'; + buf_len--; + + nm_utils_strbuf_append_str(&buf, &buf_len, str); + + /* if the string was too long we indicate truncation with a + * '^' instead of a closing quote. */ + if (G_UNLIKELY(buf_len <= 1)) { + switch (buf_len) { + case 1: + buf[-1] = '^'; + break; + case 0: + buf[-2] = '^'; + break; + default: + nm_assert_not_reached(); + break; + } + } else { + nm_assert(buf_len >= 2); + *(buf++) = '"'; + *(buf++) = '\0'; + } + +out: + return buf0; +} + +/*****************************************************************************/ + +char _nm_utils_to_string_buffer[]; + +void +nm_utils_to_string_buffer_init(char **buf, gsize *len) +{ + if (!*buf) { + *buf = _nm_utils_to_string_buffer; + *len = sizeof(_nm_utils_to_string_buffer); + } +} + +gboolean +nm_utils_to_string_buffer_init_null(gconstpointer obj, char **buf, gsize *len) +{ + nm_utils_to_string_buffer_init(buf, len); + if (!obj) { + g_strlcpy(*buf, "(null)", *len); + return FALSE; + } + return TRUE; +} + +/*****************************************************************************/ + +const char * +nm_utils_flags2str(const NMUtilsFlags2StrDesc *descs, + gsize n_descs, + unsigned flags, + char * buf, + gsize len) +{ + gsize i; + char *p; + +#if NM_MORE_ASSERTS > 10 + nm_assert(descs); + nm_assert(n_descs > 0); + for (i = 0; i < n_descs; i++) { + gsize j; + + nm_assert(descs[i].name && descs[i].name[0]); + for (j = 0; j < i; j++) + nm_assert(descs[j].flag != descs[i].flag); + } +#endif + + nm_utils_to_string_buffer_init(&buf, &len); + + if (!len) + return buf; + + buf[0] = '\0'; + p = buf; + if (!flags) { + for (i = 0; i < n_descs; i++) { + if (!descs[i].flag) { + nm_utils_strbuf_append_str(&p, &len, descs[i].name); + break; + } + } + return buf; + } + + for (i = 0; flags && i < n_descs; i++) { + if (descs[i].flag && NM_FLAGS_ALL(flags, descs[i].flag)) { + flags &= ~descs[i].flag; + + if (buf[0] != '\0') + nm_utils_strbuf_append_c(&p, &len, ','); + nm_utils_strbuf_append_str(&p, &len, descs[i].name); + } + } + if (flags) { + if (buf[0] != '\0') + nm_utils_strbuf_append_c(&p, &len, ','); + nm_utils_strbuf_append(&p, &len, "0x%x", flags); + } + return buf; +}; + +/*****************************************************************************/ + +/** + * _nm_utils_ip4_prefix_to_netmask: + * @prefix: a CIDR prefix + * + * Returns: the netmask represented by the prefix, in network byte order + **/ +guint32 +_nm_utils_ip4_prefix_to_netmask(guint32 prefix) +{ + return prefix < 32 ? ~htonl(0xFFFFFFFFu >> prefix) : 0xFFFFFFFFu; +} + +/*****************************************************************************/ + +guint32 +_nm_utils_ip4_get_default_prefix0(in_addr_t ip) +{ + /* The function is originally from ipcalc.c of Red Hat's initscripts. */ + switch (ntohl(ip) >> 24) { + case 0 ... 127: + return 8; /* Class A */ + case 128 ... 191: + return 16; /* Class B */ + case 192 ... 223: + return 24; /* Class C */ + } + return 0; +} + +guint32 +_nm_utils_ip4_get_default_prefix(in_addr_t ip) +{ + return _nm_utils_ip4_get_default_prefix0(ip) ?: 24; +} + +gboolean +nm_utils_ip_is_site_local(int addr_family, const void *address) +{ + in_addr_t addr4; + + switch (addr_family) { + case AF_INET: + /* RFC1918 private addresses + * 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 */ + addr4 = ntohl(*((const in_addr_t *) address)); + return (addr4 & 0xff000000) == 0x0a000000 || (addr4 & 0xfff00000) == 0xac100000 + || (addr4 & 0xffff0000) == 0xc0a80000; + case AF_INET6: + return IN6_IS_ADDR_SITELOCAL(address); + default: + g_return_val_if_reached(FALSE); + } +} + +/*****************************************************************************/ + +static gboolean +_parse_legacy_addr4(const char *text, in_addr_t *out_addr, GError **error) +{ + gs_free char * s_free = NULL; + struct in_addr a1; + guint8 bin[sizeof(a1)]; + char * s; + int i; + + if (inet_aton(text, &a1) != 1) { + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + "address invalid according to inet_aton()"); + return FALSE; + } + + /* OK, inet_aton() accepted the format. That's good, because we want + * to accept IPv4 addresses in octal format, like 255.255.000.000. + * That's what "legacy" means here. inet_pton() doesn't accept those. + * + * But inet_aton() also ignores trailing garbage and formats with fewer than + * 4 digits. That is just too crazy and we don't do that. Perform additional checks + * and reject some forms that inet_aton() accepted. + * + * Note that we still should (of course) accept everything that inet_pton() + * accepts. However this code never gets called if inet_pton() succeeds + * (see below, aside the assertion code). */ + + if (NM_STRCHAR_ANY(text, ch, (!(ch >= '0' && ch <= '9') && !NM_IN_SET(ch, '.', 'x')))) { + /* We only accepts '.', digits, and 'x' for "0x". */ + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + "contains an invalid character"); + return FALSE; + } + + s = nm_memdup_maybe_a(300, text, strlen(text) + 1, &s_free); + + for (i = 0; i < G_N_ELEMENTS(bin); i++) { + char * current_token = s; + gint32 v; + + s = strchr(s, '.'); + if (s) { + s[0] = '\0'; + s++; + } + + if ((i == G_N_ELEMENTS(bin) - 1) != (s == NULL)) { + /* Exactly for the last digit, we expect to have no more following token. + * But this isn't the case. Abort. */ + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + "wrong number of tokens (index %d, token '%s')", + i, + s); + return FALSE; + } + + v = _nm_utils_ascii_str_to_int64(current_token, 0, 0, 0xFF, -1); + if (v == -1) { + int errsv = errno; + + /* we do accept octal and hex (even with leading "0x"). But something + * about this token is wrong. */ + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + "invalid token '%s': %s (%d)", + current_token, + nm_strerror_native(errsv), + errsv); + return FALSE; + } + + bin[i] = v; + } + + if (memcmp(bin, &a1, sizeof(bin)) != 0) { + /* our parsing did not agree with what inet_aton() gave. Something + * is wrong. Abort. */ + g_set_error( + error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + "inet_aton() result 0x%08x differs from computed value 0x%02hhx%02hhx%02hhx%02hhx", + a1.s_addr, + bin[0], + bin[1], + bin[2], + bin[3]); + return FALSE; + } + + *out_addr = a1.s_addr; + return TRUE; +} + +gboolean +nm_utils_parse_inaddr_bin_full(int addr_family, + gboolean accept_legacy, + const char *text, + int * out_addr_family, + gpointer out_addr) +{ + NMIPAddr addrbin; + + g_return_val_if_fail(text, FALSE); + + if (addr_family == AF_UNSPEC) { + g_return_val_if_fail(!out_addr || out_addr_family, FALSE); + addr_family = strchr(text, ':') ? AF_INET6 : AF_INET; + } else + g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), FALSE); + + if (inet_pton(addr_family, text, &addrbin) != 1) { + if (accept_legacy && addr_family == AF_INET + && _parse_legacy_addr4(text, &addrbin.addr4, NULL)) { + /* The address is in some legacy format which inet_aton() accepts, but not inet_pton(). + * Most likely octal digits (leading zeros). We accept the address. */ + } else + return FALSE; + } + +#if NM_MORE_ASSERTS > 10 + if (addr_family == AF_INET) { + gs_free_error GError *error = NULL; + in_addr_t a; + + /* The legacy parser should accept everything that inet_pton() accepts too. Meaning, + * it should strictly parse *more* formats. And of course, parse it the same way. */ + if (!_parse_legacy_addr4(text, &a, &error)) { + char buf[INET_ADDRSTRLEN]; + + g_error("unexpected assertion failure: could parse \"%s\" as %s, but not accepted by " + "legacy parser: %s", + text, + _nm_utils_inet4_ntop(addrbin.addr4, buf), + error->message); + } + nm_assert(addrbin.addr4 == a); + } +#endif + + NM_SET_OUT(out_addr_family, addr_family); + if (out_addr) + nm_ip_addr_set(addr_family, out_addr, &addrbin); + return TRUE; +} + +gboolean +nm_utils_parse_inaddr(int addr_family, const char *text, char **out_addr) +{ + NMIPAddr addrbin; + char addrstr_buf[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)]; + + g_return_val_if_fail(text, FALSE); + + if (addr_family == AF_UNSPEC) + addr_family = strchr(text, ':') ? AF_INET6 : AF_INET; + else + g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), FALSE); + + if (inet_pton(addr_family, text, &addrbin) != 1) + return FALSE; + + NM_SET_OUT(out_addr, + g_strdup(inet_ntop(addr_family, &addrbin, addrstr_buf, sizeof(addrstr_buf)))); + return TRUE; +} + +gboolean +nm_utils_parse_inaddr_prefix_bin(int addr_family, + const char *text, + int * out_addr_family, + gpointer out_addr, + int * out_prefix) +{ + gs_free char *addrstr_free = NULL; + int prefix = -1; + const char * slash; + const char * addrstr; + NMIPAddr addrbin; + + g_return_val_if_fail(text, FALSE); + + if (addr_family == AF_UNSPEC) { + g_return_val_if_fail(!out_addr || out_addr_family, FALSE); + addr_family = strchr(text, ':') ? AF_INET6 : AF_INET; + } else + g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), FALSE); + + slash = strchr(text, '/'); + if (slash) + addrstr = nm_strndup_a(300, text, slash - text, &addrstr_free); + else + addrstr = text; + + if (inet_pton(addr_family, addrstr, &addrbin) != 1) + return FALSE; + + if (slash) { + /* For IPv4, `ip addr add` supports the prefix-length as a netmask. We don't + * do that. */ + prefix = + _nm_utils_ascii_str_to_int64(&slash[1], 10, 0, addr_family == AF_INET ? 32 : 128, -1); + if (prefix == -1) + return FALSE; + } + + NM_SET_OUT(out_addr_family, addr_family); + if (out_addr) + nm_ip_addr_set(addr_family, out_addr, &addrbin); + NM_SET_OUT(out_prefix, prefix); + return TRUE; +} + +gboolean +nm_utils_parse_inaddr_prefix(int addr_family, const char *text, char **out_addr, int *out_prefix) +{ + NMIPAddr addrbin; + char addrstr_buf[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)]; + + if (!nm_utils_parse_inaddr_prefix_bin(addr_family, text, &addr_family, &addrbin, out_prefix)) + return FALSE; + NM_SET_OUT(out_addr, + g_strdup(inet_ntop(addr_family, &addrbin, addrstr_buf, sizeof(addrstr_buf)))); + return TRUE; +} + +gboolean +nm_utils_parse_next_line(const char **inout_ptr, + gsize * inout_len, + const char **out_line, + gsize * out_line_len) +{ + gboolean eol_is_carriage_return; + const char *line_start; + gsize line_len; + + nm_assert(inout_ptr); + nm_assert(inout_len); + nm_assert(*inout_len == 0 || *inout_ptr); + nm_assert(out_line); + nm_assert(out_line_len); + + if (G_UNLIKELY(*inout_len == 0)) + return FALSE; + + line_start = *inout_ptr; + + eol_is_carriage_return = FALSE; + for (line_len = 0;; line_len++) { + if (line_len >= *inout_len) { + /* if we consumed the entire line, we place the pointer at + * one character after the end. */ + *inout_ptr = &line_start[line_len]; + *inout_len = 0; + goto done; + } + switch (line_start[line_len]) { + case '\r': + eol_is_carriage_return = TRUE; + /* fall-through*/ + case '\0': + case '\n': + *inout_ptr = &line_start[line_len + 1]; + *inout_len = *inout_len - line_len - 1u; + if (eol_is_carriage_return && *inout_len > 0 && (*inout_ptr)[0] == '\n') { + /* also consume "\r\n" as one. */ + (*inout_len)--; + (*inout_ptr)++; + } + goto done; + } + } + +done: + *out_line = line_start; + *out_line_len = line_len; + return TRUE; +} + +/*****************************************************************************/ + +gboolean +nm_utils_ipaddr_is_valid(int addr_family, const char *str_addr) +{ + nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); + + return str_addr && nm_utils_parse_inaddr_bin(addr_family, str_addr, NULL, NULL); +} + +gboolean +nm_utils_ipaddr_is_normalized(int addr_family, const char *str_addr) +{ + NMIPAddr addr; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); + + if (!str_addr) + return FALSE; + + if (!nm_utils_parse_inaddr_bin(addr_family, str_addr, &addr_family, &addr)) + return FALSE; + + nm_utils_inet_ntop(addr_family, &addr, sbuf); + return nm_streq(sbuf, str_addr); +} + +/*****************************************************************************/ + +NM_UTILS_ENUM2STR_DEFINE(nm_icmpv6_router_pref_to_string, + NMIcmpv6RouterPref, + NM_UTILS_ENUM2STR(NM_ICMPV6_ROUTER_PREF_LOW, "low"), + NM_UTILS_ENUM2STR(NM_ICMPV6_ROUTER_PREF_MEDIUM, "medium"), + NM_UTILS_ENUM2STR(NM_ICMPV6_ROUTER_PREF_HIGH, "high"), + NM_UTILS_ENUM2STR(NM_ICMPV6_ROUTER_PREF_INVALID, "invalid"), ); + +/*****************************************************************************/ + +/** + * nm_g_ascii_strtoll() + * @nptr: the string to parse + * @endptr: the pointer on the first invalid chars + * @base: the base. + * + * This wraps g_ascii_strtoll() and should in almost all cases behave identical + * to it. + * + * However, it seems there are situations where g_ascii_strtoll() might set + * errno to some unexpected value EAGAIN. Possibly this is related to creating + * the C locale during + * + * #ifdef USE_XLOCALE + * return strtoll_l (nptr, endptr, base, get_C_locale ()); + * + * This wrapper tries to workaround that condition. + */ +gint64 +nm_g_ascii_strtoll(const char *nptr, char **endptr, guint base) +{ + int try_count = 2; + gint64 v; + const int errsv_orig = errno; + int errsv; + + nm_assert(nptr); + nm_assert(base == 0u || (base >= 2u && base <= 36u)); + +again: + errno = 0; + v = g_ascii_strtoll(nptr, endptr, base); + errsv = errno; + + if (errsv == 0) { + if (errsv_orig != 0) + errno = errsv_orig; + return v; + } + + if (errsv == ERANGE && NM_IN_SET(v, G_MININT64, G_MAXINT64)) + return v; + + if (errsv == EINVAL && v == 0 && nptr && nptr[0] == '\0') + return v; + + if (try_count-- > 0) + goto again; + +#if NM_MORE_ASSERTS + g_critical("g_ascii_strtoll() for \"%s\" failed with errno=%d (%s) and v=%" G_GINT64_FORMAT, + nptr, + errsv, + nm_strerror_native(errsv), + v); +#endif + + return v; +} + +/* See nm_g_ascii_strtoll() */ +guint64 +nm_g_ascii_strtoull(const char *nptr, char **endptr, guint base) +{ + int try_count = 2; + guint64 v; + const int errsv_orig = errno; + int errsv; + + nm_assert(nptr); + nm_assert(base == 0u || (base >= 2u && base <= 36u)); + +again: + errno = 0; + v = g_ascii_strtoull(nptr, endptr, base); + errsv = errno; + + if (errsv == 0) { + if (errsv_orig != 0) + errno = errsv_orig; + return v; + } + + if (errsv == ERANGE && NM_IN_SET(v, G_MAXUINT64)) + return v; + + if (errsv == EINVAL && v == 0 && nptr && nptr[0] == '\0') + return v; + + if (try_count-- > 0) + goto again; + +#if NM_MORE_ASSERTS + g_critical("g_ascii_strtoull() for \"%s\" failed with errno=%d (%s) and v=%" G_GUINT64_FORMAT, + nptr, + errsv, + nm_strerror_native(errsv), + v); +#endif + + return v; +} + +/* see nm_g_ascii_strtoll(). */ +double +nm_g_ascii_strtod(const char *nptr, char **endptr) +{ + int try_count = 2; + double v; + int errsv; + + nm_assert(nptr); + +again: + v = g_ascii_strtod(nptr, endptr); + errsv = errno; + + if (errsv == 0) + return v; + + if (errsv == ERANGE) + return v; + + if (try_count-- > 0) + goto again; + +#if NM_MORE_ASSERTS + g_critical("g_ascii_strtod() for \"%s\" failed with errno=%d (%s) and v=%f", + nptr, + errsv, + nm_strerror_native(errsv), + v); +#endif + + /* Not really much else to do. Return the parsed value and leave errno set + * to the unexpected value. */ + return v; +} + +/* _nm_utils_ascii_str_to_int64: + * + * A wrapper for g_ascii_strtoll, that checks whether the whole string + * can be successfully converted to a number and is within a given + * range. On any error, @fallback will be returned and %errno will be set + * to a non-zero value. On success, %errno will be set to zero, check %errno + * for errors. Any trailing or leading (ascii) white space is ignored and the + * functions is locale independent. + * + * The function is guaranteed to return a value between @min and @max + * (inclusive) or @fallback. Also, the parsing is rather strict, it does + * not allow for any unrecognized characters, except leading and trailing + * white space. + **/ +gint64 +_nm_utils_ascii_str_to_int64(const char *str, guint base, gint64 min, gint64 max, gint64 fallback) +{ + gint64 v; + const char *s = NULL; + + str = nm_str_skip_leading_spaces(str); + if (!str || !str[0]) { + errno = EINVAL; + return fallback; + } + + errno = 0; + v = nm_g_ascii_strtoll(str, (char **) &s, base); + + if (errno != 0) + return fallback; + + if (s[0] != '\0') { + s = nm_str_skip_leading_spaces(s); + if (s[0] != '\0') { + errno = EINVAL; + return fallback; + } + } + if (v > max || v < min) { + errno = ERANGE; + return fallback; + } + + return v; +} + +guint64 +_nm_utils_ascii_str_to_uint64(const char *str, + guint base, + guint64 min, + guint64 max, + guint64 fallback) +{ + guint64 v; + const char *s = NULL; + + if (str) { + while (g_ascii_isspace(str[0])) + str++; + } + if (!str || !str[0]) { + errno = EINVAL; + return fallback; + } + + errno = 0; + v = nm_g_ascii_strtoull(str, (char **) &s, base); + + if (errno != 0) + return fallback; + if (s[0] != '\0') { + while (g_ascii_isspace(s[0])) + s++; + if (s[0] != '\0') { + errno = EINVAL; + return fallback; + } + } + if (v > max || v < min) { + errno = ERANGE; + return fallback; + } + + if (v != 0 && str[0] == '-') { + /* As documented, g_ascii_strtoull() accepts negative values, and returns their + * absolute value. We don't. */ + errno = ERANGE; + return fallback; + } + + return v; +} + +/*****************************************************************************/ + +int +nm_strcmp_with_data(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const char *s1 = a; + const char *s2 = b; + + return strcmp(s1, s2); +} + +/* like nm_strcmp_p(), suitable for g_ptr_array_sort_with_data(). + * g_ptr_array_sort() just casts nm_strcmp_p() to a function of different + * signature. I guess, in glib there are knowledgeable people that ensure + * that this additional argument doesn't cause problems due to different ABI + * for every architecture that glib supports. + * For NetworkManager, we'd rather avoid such stunts. + **/ +int +nm_strcmp_p_with_data(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const char *s1 = *((const char **) a); + const char *s2 = *((const char **) b); + + return strcmp(s1, s2); +} + +int +nm_strcmp0_p_with_data(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const char *s1 = *((const char **) a); + const char *s2 = *((const char **) b); + + return nm_strcmp0(s1, s2); +} + +int +nm_strcmp_ascii_case_with_data(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const char *s1 = a; + const char *s2 = b; + + return g_ascii_strcasecmp(s1, s2); +} + +int +nm_cmp_uint32_p_with_data(gconstpointer p_a, gconstpointer p_b, gpointer user_data) +{ + const guint32 a = *((const guint32 *) p_a); + const guint32 b = *((const guint32 *) p_b); + + if (a < b) + return -1; + if (a > b) + return 1; + return 0; +} + +int +nm_cmp_int2ptr_p_with_data(gconstpointer p_a, gconstpointer p_b, gpointer user_data) +{ + /* p_a and p_b are two pointers to a pointer, where the pointer is + * interpreted as a integer using GPOINTER_TO_INT(). + * + * That is the case of a hash-table that uses GINT_TO_POINTER() to + * convert integers as pointers, and the resulting keys-as-array + * array. */ + const int a = GPOINTER_TO_INT(*((gconstpointer *) p_a)); + const int b = GPOINTER_TO_INT(*((gconstpointer *) p_b)); + + if (a < b) + return -1; + if (a > b) + return 1; + return 0; +} + +/*****************************************************************************/ + +const char * +nm_utils_dbus_path_get_last_component(const char *dbus_path) +{ + if (dbus_path) { + dbus_path = strrchr(dbus_path, '/'); + if (dbus_path) + return dbus_path + 1; + } + return NULL; +} + +static gint64 +_dbus_path_component_as_num(const char *p) +{ + gint64 n; + + /* no odd stuff. No leading zeros, only a non-negative, decimal integer. + * + * Otherwise, there would be multiple ways to encode the same number "10" + * and "010". That is just confusing. A number has no leading zeros, + * if it has, it's not a number (as far as we are concerned here). */ + if (p[0] == '0') { + if (p[1] != '\0') + return -1; + else + return 0; + } + if (!(p[0] >= '1' && p[0] <= '9')) + return -1; + if (!NM_STRCHAR_ALL(&p[1], ch, (ch >= '0' && ch <= '9'))) + return -1; + n = _nm_utils_ascii_str_to_int64(p, 10, 0, G_MAXINT64, -1); + nm_assert(n == -1 || nm_streq0(p, nm_sprintf_bufa(100, "%" G_GINT64_FORMAT, n))); + return n; +} + +int +nm_utils_dbus_path_cmp(const char *dbus_path_a, const char *dbus_path_b) +{ + const char *l_a, *l_b; + gsize plen; + gint64 n_a, n_b; + + /* compare function for two D-Bus paths. It behaves like + * strcmp(), except, if both paths have the same prefix, + * and both end in a (positive) number, then the paths + * will be sorted by number. */ + + NM_CMP_SELF(dbus_path_a, dbus_path_b); + + /* if one or both paths have no slash (and no last component) + * compare the full paths directly. */ + if (!(l_a = nm_utils_dbus_path_get_last_component(dbus_path_a)) + || !(l_b = nm_utils_dbus_path_get_last_component(dbus_path_b))) + goto comp_full; + + /* check if both paths have the same prefix (up to the last-component). */ + plen = l_a - dbus_path_a; + if (plen != (l_b - dbus_path_b)) + goto comp_full; + NM_CMP_RETURN(strncmp(dbus_path_a, dbus_path_b, plen)); + + n_a = _dbus_path_component_as_num(l_a); + n_b = _dbus_path_component_as_num(l_b); + if (n_a == -1 && n_b == -1) + goto comp_l; + + /* both components must be convertible to a number. If they are not, + * (and only one of them is), then we must always strictly sort numeric parts + * after non-numeric components. If we wouldn't, we wouldn't have + * a total order. + * + * An example of a not total ordering would be: + * "8" < "010" (numeric) + * "0x" < "8" (lexical) + * "0x" > "010" (lexical) + * We avoid this, by forcing that a non-numeric entry "0x" always sorts + * before numeric entries. + * + * Additionally, _dbus_path_component_as_num() would also reject "010" as + * not a valid number. + */ + if (n_a == -1) + return -1; + if (n_b == -1) + return 1; + + NM_CMP_DIRECT(n_a, n_b); + nm_assert(nm_streq(dbus_path_a, dbus_path_b)); + return 0; + +comp_full: + NM_CMP_DIRECT_STRCMP0(dbus_path_a, dbus_path_b); + return 0; +comp_l: + NM_CMP_DIRECT_STRCMP0(l_a, l_b); + nm_assert(nm_streq(dbus_path_a, dbus_path_b)); + return 0; +} + +/*****************************************************************************/ + +typedef struct { + union { + guint8 table[256]; + guint64 _dummy_for_alignment; + }; +} CharLookupTable; + +static void +_char_lookup_table_set_one(CharLookupTable *lookup, char ch) +{ + lookup->table[(guint8) ch] = 1; +} + +static void +_char_lookup_table_set_all(CharLookupTable *lookup, const char *candidates) +{ + while (candidates[0] != '\0') + _char_lookup_table_set_one(lookup, (candidates++)[0]); +} + +static void +_char_lookup_table_init(CharLookupTable *lookup, const char *candidates) +{ + *lookup = (CharLookupTable){ + .table = {0}, + }; + if (candidates) + _char_lookup_table_set_all(lookup, candidates); +} + +static gboolean +_char_lookup_has(const CharLookupTable *lookup, char ch) +{ + /* with some optimization levels, the compiler thinks this code + * might access uninitialized @lookup. It is not -- when you look at the + * callers of this function. */ + NM_PRAGMA_WARNING_DISABLE("-Wmaybe-uninitialized") + nm_assert(lookup->table[(guint8) '\0'] == 0); + return lookup->table[(guint8) ch] != 0; + NM_PRAGMA_WARNING_REENABLE +} + +static gboolean +_char_lookup_has_all(const CharLookupTable *lookup, const char *candidates) +{ + if (candidates) { + while (candidates[0] != '\0') { + if (!_char_lookup_has(lookup, (candidates++)[0])) + return FALSE; + } + } + return TRUE; +} + +/** + * nm_utils_strsplit_set_full: + * @str: the string to split. + * @delimiters: the set of delimiters. + * @flags: additional flags for controlling the operation. + * + * This is a replacement for g_strsplit_set() which avoids copying + * each word once (the entire strv array), but instead copies it once + * and all words point into that internal copy. + * + * Note that for @str %NULL and "", this always returns %NULL too. That differs + * from g_strsplit_set(), which would return an empty strv array for "". + * This never returns an empty array. + * + * Returns: %NULL if @str is %NULL or "". + * If @str only contains delimiters and %NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY + * is not set, it also returns %NULL. + * Otherwise, a %NULL terminated strv array containing the split words. + * (delimiter characters are removed). + * The strings to which the result strv array points to are allocated + * after the returned result itself. Don't free the strings themself, + * but free everything with g_free(). + * It is however safe and allowed to modify the individual strings in-place, + * like "g_strstrip((char *) iter[0])". + */ +const char ** +nm_utils_strsplit_set_full(const char *str, const char *delimiters, NMUtilsStrsplitSetFlags flags) +{ + const char ** ptr; + gsize num_tokens; + gsize i_token; + gsize str_len_p1; + const char * c_str; + char * s; + CharLookupTable ch_lookup; + const gboolean f_escaped = NM_FLAGS_HAS(flags, NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED); + const gboolean f_allow_escaping = + f_escaped || NM_FLAGS_HAS(flags, NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING); + const gboolean f_preserve_empty = + NM_FLAGS_HAS(flags, NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY); + const gboolean f_strstrip = NM_FLAGS_HAS(flags, NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); + + if (!str) + return NULL; + + if (!delimiters) { + nm_assert_not_reached(); + delimiters = " \t\n"; + } + _char_lookup_table_init(&ch_lookup, delimiters); + + nm_assert(!f_allow_escaping || !_char_lookup_has(&ch_lookup, '\\')); + + if (!f_preserve_empty) { + while (_char_lookup_has(&ch_lookup, str[0])) + str++; + } + + if (!str[0]) { + /* We return %NULL here, also with NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY. + * That makes nm_utils_strsplit_set_full() with NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY + * different from g_strsplit_set(), which would in this case return an empty array. + * If you need to handle %NULL, and "" specially, then check the input string first. */ + return NULL; + } + +#define _char_is_escaped(str_start, str_cur) \ + ({ \ + const char *const _str_start = (str_start); \ + const char *const _str_cur = (str_cur); \ + const char * _str_i = (_str_cur); \ + \ + while (_str_i > _str_start && _str_i[-1] == '\\') \ + _str_i--; \ + (((_str_cur - _str_i) % 2) != 0); \ + }) + + num_tokens = 1; + c_str = str; + while (TRUE) { + while (G_LIKELY(!_char_lookup_has(&ch_lookup, c_str[0]))) { + if (c_str[0] == '\0') + goto done1; + c_str++; + } + + /* we assume escapings are not frequent. After we found + * this delimiter, check whether it was escaped by counting + * the backslashed before. */ + if (f_allow_escaping && _char_is_escaped(str, c_str)) { + /* the delimiter is escaped. This was not an accepted delimiter. */ + c_str++; + continue; + } + + c_str++; + + /* if we drop empty tokens, then we now skip over all consecutive delimiters. */ + if (!f_preserve_empty) { + while (_char_lookup_has(&ch_lookup, c_str[0])) + c_str++; + if (c_str[0] == '\0') + break; + } + + num_tokens++; + } + +done1: + + nm_assert(c_str[0] == '\0'); + + str_len_p1 = (c_str - str) + 1; + + nm_assert(str[str_len_p1 - 1] == '\0'); + + ptr = g_malloc((sizeof(const char *) * (num_tokens + 1)) + str_len_p1); + s = (char *) &ptr[num_tokens + 1]; + memcpy(s, str, str_len_p1); + + i_token = 0; + + while (TRUE) { + nm_assert(i_token < num_tokens); + ptr[i_token++] = s; + + if (s[0] == '\0') { + nm_assert(f_preserve_empty); + goto done2; + } + nm_assert(f_preserve_empty || !_char_lookup_has(&ch_lookup, s[0])); + + while (!_char_lookup_has(&ch_lookup, s[0])) { + if (G_UNLIKELY(s[0] == '\\' && f_allow_escaping)) { + s++; + if (s[0] == '\0') + goto done2; + s++; + } else if (s[0] == '\0') + goto done2; + else + s++; + } + + nm_assert(_char_lookup_has(&ch_lookup, s[0])); + s[0] = '\0'; + s++; + + if (!f_preserve_empty) { + while (_char_lookup_has(&ch_lookup, s[0])) + s++; + if (s[0] == '\0') + goto done2; + } + } + +done2: + nm_assert(i_token == num_tokens); + ptr[i_token] = NULL; + + if (f_strstrip) { + gsize i; + + i_token = 0; + for (i = 0; ptr[i]; i++) { + s = (char *) nm_str_skip_leading_spaces(ptr[i]); + if (s[0] != '\0') { + char *s_last; + + s_last = &s[strlen(s) - 1]; + while (s_last > s && g_ascii_isspace(s_last[0]) + && (!f_allow_escaping || !_char_is_escaped(s, s_last))) + (s_last--)[0] = '\0'; + } + + if (!f_preserve_empty && s[0] == '\0') + continue; + + ptr[i_token++] = s; + } + + if (i_token == 0) { + g_free(ptr); + return NULL; + } + ptr[i_token] = NULL; + } + + if (f_escaped) { + gsize i, j; + + /* We no longer need ch_lookup for its original purpose. Modify it, so it + * can detect the delimiters, '\\', and (optionally) whitespaces. */ + _char_lookup_table_set_one(&ch_lookup, '\\'); + if (f_strstrip) + _char_lookup_table_set_all(&ch_lookup, NM_ASCII_SPACES); + + for (i_token = 0; ptr[i_token]; i_token++) { + s = (char *) ptr[i_token]; + j = 0; + for (i = 0; s[i] != '\0';) { + if (s[i] == '\\' && _char_lookup_has(&ch_lookup, s[i + 1])) + i++; + s[j++] = s[i++]; + } + s[j] = '\0'; + } + } + + nm_assert(ptr && ptr[0]); + return ptr; +} + +/*****************************************************************************/ + +const char * +nm_utils_escaped_tokens_escape_full(const char * str, + const char * delimiters, + const char * delimiters_as_needed, + NMUtilsEscapedTokensEscapeFlags flags, + char ** out_to_free) +{ + CharLookupTable ch_lookup; + CharLookupTable ch_lookup_as_needed; + gboolean has_ch_lookup_as_needed = FALSE; + char * ret; + gsize str_len; + gsize alloc_len; + gsize n_escapes; + gsize i, j; + gboolean escape_leading_space; + gboolean escape_trailing_space; + gboolean escape_backslash_as_needed; + + nm_assert( + !delimiters_as_needed + || (delimiters_as_needed[0] + && NM_FLAGS_HAS(flags, + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_BACKSLASH_AS_NEEDED))); + + if (!str || str[0] == '\0') { + *out_to_free = NULL; + return str; + } + + str_len = strlen(str); + + _char_lookup_table_init(&ch_lookup, delimiters); + if (!delimiters || NM_FLAGS_HAS(flags, NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_SPACES)) { + flags &= ~(NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_LEADING_SPACE + | NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_TRAILING_SPACE); + _char_lookup_table_set_all(&ch_lookup, NM_ASCII_SPACES); + } + + if (NM_FLAGS_HAS(flags, NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_BACKSLASH_ALWAYS)) { + _char_lookup_table_set_one(&ch_lookup, '\\'); + escape_backslash_as_needed = FALSE; + } else if (_char_lookup_has(&ch_lookup, '\\')) + escape_backslash_as_needed = FALSE; + else { + escape_backslash_as_needed = + NM_FLAGS_HAS(flags, NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_BACKSLASH_AS_NEEDED); + if (escape_backslash_as_needed) { + if (NM_FLAGS_ANY(flags, + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_LEADING_SPACE + | NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_TRAILING_SPACE) + && !_char_lookup_has_all(&ch_lookup, NM_ASCII_SPACES)) { + /* ESCAPE_LEADING_SPACE and ESCAPE_TRAILING_SPACE implies that we escape backslash + * before whitespaces. */ + if (!has_ch_lookup_as_needed) { + has_ch_lookup_as_needed = TRUE; + _char_lookup_table_init(&ch_lookup_as_needed, NULL); + } + _char_lookup_table_set_all(&ch_lookup_as_needed, NM_ASCII_SPACES); + } + if (delimiters_as_needed && !_char_lookup_has_all(&ch_lookup, delimiters_as_needed)) { + if (!has_ch_lookup_as_needed) { + has_ch_lookup_as_needed = TRUE; + _char_lookup_table_init(&ch_lookup_as_needed, NULL); + } + _char_lookup_table_set_all(&ch_lookup_as_needed, delimiters_as_needed); + } + } + } + + escape_leading_space = + NM_FLAGS_HAS(flags, NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_LEADING_SPACE) + && g_ascii_isspace(str[0]) && !_char_lookup_has(&ch_lookup, str[0]); + if (str_len == 1) + escape_trailing_space = FALSE; + else { + escape_trailing_space = + NM_FLAGS_HAS(flags, NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_TRAILING_SPACE) + && g_ascii_isspace(str[str_len - 1]) && !_char_lookup_has(&ch_lookup, str[str_len - 1]); + } + + n_escapes = 0; + for (i = 0; str[i] != '\0'; i++) { + if (_char_lookup_has(&ch_lookup, str[i])) + n_escapes++; + else if (str[i] == '\\' && escape_backslash_as_needed + && (_char_lookup_has(&ch_lookup, str[i + 1]) || NM_IN_SET(str[i + 1], '\0', '\\') + || (has_ch_lookup_as_needed + && _char_lookup_has(&ch_lookup_as_needed, str[i + 1])))) + n_escapes++; + } + if (escape_leading_space) + n_escapes++; + if (escape_trailing_space) + n_escapes++; + + if (n_escapes == 0u) { + *out_to_free = NULL; + return str; + } + + alloc_len = str_len + n_escapes + 1u; + ret = g_new(char, alloc_len); + + j = 0; + i = 0; + + if (escape_leading_space) { + ret[j++] = '\\'; + ret[j++] = str[i++]; + } + for (; str[i] != '\0'; i++) { + if (_char_lookup_has(&ch_lookup, str[i])) + ret[j++] = '\\'; + else if (str[i] == '\\' && escape_backslash_as_needed + && (_char_lookup_has(&ch_lookup, str[i + 1]) || NM_IN_SET(str[i + 1], '\0', '\\') + || (has_ch_lookup_as_needed + && _char_lookup_has(&ch_lookup_as_needed, str[i + 1])))) + ret[j++] = '\\'; + ret[j++] = str[i]; + } + if (escape_trailing_space) { + nm_assert(!_char_lookup_has(&ch_lookup, ret[j - 1]) && g_ascii_isspace(ret[j - 1])); + ret[j] = ret[j - 1]; + ret[j - 1] = '\\'; + j++; + } + + nm_assert(j == alloc_len - 1); + ret[j] = '\0'; + nm_assert(strlen(ret) == j); + + *out_to_free = ret; + return ret; +} + +/** + * nm_utils_escaped_tokens_options_split: + * @str: the src string. This string will be modified in-place. + * The output values will point into @str. + * @out_key: (allow-none): the returned output key. This will always be set to @str + * itself. @str will be modified to contain only the unescaped, truncated + * key name. + * @out_val: returns the parsed (and unescaped) value or %NULL, if @str contains + * no '=' delimiter. + * + * Honors backslash escaping to parse @str as "key=value" pairs. Optionally, if no '=' + * is present, @out_val will be returned as %NULL. Backslash can be used to escape + * '=', ',', '\\', and ascii whitespace. Other backslash sequences are taken verbatim. + * + * For keys, '=' obviously must be escaped. For values, that is optional because an + * unescaped '=' is just taken verbatim. For example, in a key, the sequence "\\=" + * must be escaped as "\\\\\\=". For the value, that works too, but "\\\\=" is also + * accepted. + * + * Unescaped Space around the key and value are also removed. Space in general must + * not be escaped, unless they are at the beginning or the end of key/value. + */ +void +nm_utils_escaped_tokens_options_split(char *str, const char **out_key, const char **out_val) +{ + const char *val = NULL; + gsize i; + gsize j; + gsize last_space_idx; + gboolean last_space_has; + + nm_assert(str); + + i = 0; + while (g_ascii_isspace(str[i])) + i++; + + j = 0; + last_space_idx = 0; + last_space_has = FALSE; + while (str[i] != '\0') { + if (g_ascii_isspace(str[i])) { + if (!last_space_has) { + last_space_has = TRUE; + last_space_idx = j; + } + } else { + if (str[i] == '\\') { + if (NM_IN_SET(str[i + 1u], '\\', ',', '=') || g_ascii_isspace(str[i + 1u])) + i++; + } else if (str[i] == '=') { + /* Encounter an unescaped '=' character. When we still parse the key, this + * is the separator we were waiting for. If we are parsing the value, + * we take the character verbatim. */ + if (!val) { + if (last_space_has) { + str[last_space_idx] = '\0'; + j = last_space_idx + 1; + last_space_has = FALSE; + } else + str[j++] = '\0'; + val = &str[j]; + i++; + while (g_ascii_isspace(str[i])) + i++; + continue; + } + } + last_space_has = FALSE; + } + str[j++] = str[i++]; + } + + if (last_space_has) + str[last_space_idx] = '\0'; + else + str[j] = '\0'; + + *out_key = str; + *out_val = val; +} + +/*****************************************************************************/ + +/** + * nm_utils_strsplit_quoted: + * @str: the string to split (e.g. from /proc/cmdline). + * + * This basically does that systemd's extract_first_word() does + * with the flags "EXTRACT_UNQUOTE | EXTRACT_RELAX". This is what + * systemd uses to parse /proc/cmdline, and we do too. + * + * Splits the string. We have nm_utils_strsplit_set() which + * supports a variety of flags. However, extending that already + * complex code to also support quotation and escaping is hard. + * Instead, add a naive implementation. + * + * Returns: (transfer full): the split string. + */ +char ** +nm_utils_strsplit_quoted(const char *str) +{ + gs_unref_ptrarray GPtrArray *arr = NULL; + gs_free char * str_out = NULL; + CharLookupTable ch_lookup; + + nm_assert(str); + + _char_lookup_table_init(&ch_lookup, NM_ASCII_WHITESPACES); + + for (;;) { + char quote; + gsize j; + + while (_char_lookup_has(&ch_lookup, str[0])) + str++; + + if (str[0] == '\0') + break; + + if (!str_out) + str_out = g_new(char, strlen(str) + 1); + + quote = '\0'; + j = 0; + for (;;) { + if (str[0] == '\\') { + str++; + if (str[0] == '\0') + break; + str_out[j++] = str[0]; + str++; + continue; + } + if (quote) { + if (str[0] == '\0') + break; + if (str[0] == quote) { + quote = '\0'; + str++; + continue; + } + str_out[j++] = str[0]; + str++; + continue; + } + if (str[0] == '\0') + break; + if (NM_IN_SET(str[0], '\'', '"')) { + quote = str[0]; + str++; + continue; + } + if (_char_lookup_has(&ch_lookup, str[0])) { + str++; + break; + } + str_out[j++] = str[0]; + str++; + } + + if (!arr) + arr = g_ptr_array_new(); + g_ptr_array_add(arr, g_strndup(str_out, j)); + } + + if (!arr) + return g_new0(char *, 1); + + g_ptr_array_add(arr, NULL); + + /* We want to return an optimally sized strv array, with no excess + * memory allocated. Hence, clone once more. */ + return nm_memdup(arr->pdata, sizeof(char *) * arr->len); +} + +/*****************************************************************************/ + +/** + * nm_utils_strv_find_first: + * @list: the strv list to search + * @len: the length of the list, or a negative value if @list is %NULL terminated. + * @needle: the value to search for. The search is done using strcmp(). + * + * Searches @list for @needle and returns the index of the first match (based + * on strcmp()). + * + * For convenience, @list has type 'char**' instead of 'const char **'. + * + * Returns: index of first occurrence or -1 if @needle is not found in @list. + */ +gssize +nm_utils_strv_find_first(char **list, gssize len, const char *needle) +{ + gssize i; + + if (len > 0) { + g_return_val_if_fail(list, -1); + + if (!needle) { + /* if we search a list with known length, %NULL is a valid @needle. */ + for (i = 0; i < len; i++) { + if (!list[i]) + return i; + } + } else { + for (i = 0; i < len; i++) { + if (list[i] && !strcmp(needle, list[i])) + return i; + } + } + } else if (len < 0) { + g_return_val_if_fail(needle, -1); + + if (list) { + for (i = 0; list[i]; i++) { + if (strcmp(needle, list[i]) == 0) + return i; + } + } + } + return -1; +} + +char ** +_nm_utils_strv_cleanup(char ** strv, + gboolean strip_whitespace, + gboolean skip_empty, + gboolean skip_repeated) +{ + guint i, j; + + if (!strv || !*strv) + return strv; + + if (strip_whitespace) { + /* we only modify the strings pointed to by @strv if @strip_whitespace is + * requested. Otherwise, the strings themselves are untouched. */ + for (i = 0; strv[i]; i++) + g_strstrip(strv[i]); + } + if (!skip_empty && !skip_repeated) + return strv; + j = 0; + for (i = 0; strv[i]; i++) { + if ((skip_empty && !*strv[i]) + || (skip_repeated && nm_utils_strv_find_first(strv, j, strv[i]) >= 0)) + g_free(strv[i]); + else + strv[j++] = strv[i]; + } + strv[j] = NULL; + return strv; +} + +/*****************************************************************************/ + +GPtrArray * +_nm_g_ptr_array_copy(GPtrArray * array, + GCopyFunc func, + gpointer user_data, + GDestroyNotify element_free_func) +{ + GPtrArray *new_array; + guint i; + + g_return_val_if_fail(array, NULL); + + new_array = g_ptr_array_new_full(array->len, element_free_func); + for (i = 0; i < array->len; i++) { + g_ptr_array_add(new_array, func ? func(array->pdata[i], user_data) : array->pdata[i]); + } + return new_array; +} + +/*****************************************************************************/ + +int +_nm_utils_ascii_str_to_bool(const char *str, int default_value) +{ + gs_free char *str_free = NULL; + + if (!str) + return default_value; + + str = nm_strstrip_avoid_copy_a(300, str, &str_free); + if (str[0] == '\0') + return default_value; + + if (!g_ascii_strcasecmp(str, "true") || !g_ascii_strcasecmp(str, "yes") + || !g_ascii_strcasecmp(str, "on") || !g_ascii_strcasecmp(str, "1")) + return TRUE; + + if (!g_ascii_strcasecmp(str, "false") || !g_ascii_strcasecmp(str, "no") + || !g_ascii_strcasecmp(str, "off") || !g_ascii_strcasecmp(str, "0")) + return FALSE; + + return default_value; +} + +/*****************************************************************************/ + +NM_CACHED_QUARK_FCN("nm-manager-error-quark", nm_manager_error_quark); + +NM_CACHED_QUARK_FCN("nm-utils-error-quark", nm_utils_error_quark); + +void +nm_utils_error_set_cancelled(GError **error, gboolean is_disposing, const char *instance_name) +{ + if (is_disposing) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_CANCELLED_DISPOSING, + "Disposing %s instance", + instance_name && *instance_name ? instance_name : "source"); + } else { + g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Request cancelled"); + } +} + +gboolean +nm_utils_error_is_cancelled_or_disposing(GError *error) +{ + if (error) { + if (error->domain == G_IO_ERROR) + return NM_IN_SET(error->code, G_IO_ERROR_CANCELLED); + if (error->domain == NM_UTILS_ERROR) + return NM_IN_SET(error->code, NM_UTILS_ERROR_CANCELLED_DISPOSING); + } + return FALSE; +} + +gboolean +nm_utils_error_is_notfound(GError *error) +{ + if (error) { + if (error->domain == G_IO_ERROR) + return NM_IN_SET(error->code, G_IO_ERROR_NOT_FOUND); + if (error->domain == G_FILE_ERROR) + return NM_IN_SET(error->code, G_FILE_ERROR_NOENT); + } + return FALSE; +} + +/*****************************************************************************/ + +/** + * nm_g_object_set_property: + * @object: the target object + * @property_name: the property name + * @value: the #GValue to set + * @error: (allow-none): optional error argument + * + * A reimplementation of g_object_set_property(), but instead + * returning an error instead of logging a warning. All g_object_set*() + * versions in glib require you to not pass invalid types or they will + * log a g_warning() -- without reporting an error. We don't want that, + * so we need to hack error checking around it. + * + * Returns: whether the value was successfully set. + */ +gboolean +nm_g_object_set_property(GObject * object, + const char * property_name, + const GValue *value, + GError ** error) +{ + GParamSpec * pspec; + nm_auto_unset_gvalue GValue tmp_value = G_VALUE_INIT; + GObjectClass * klass; + + g_return_val_if_fail(G_IS_OBJECT(object), FALSE); + g_return_val_if_fail(property_name != NULL, FALSE); + g_return_val_if_fail(G_IS_VALUE(value), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + /* g_object_class_find_property() does g_param_spec_get_redirect_target(), + * where we differ from a plain g_object_set_property(). */ + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(object), property_name); + + if (!pspec) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("object class '%s' has no property named '%s'"), + G_OBJECT_TYPE_NAME(object), + property_name); + return FALSE; + } + if (!(pspec->flags & G_PARAM_WRITABLE)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("property '%s' of object class '%s' is not writable"), + pspec->name, + G_OBJECT_TYPE_NAME(object)); + return FALSE; + } + if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("construct property \"%s\" for object '%s' can't be set after construction"), + pspec->name, + G_OBJECT_TYPE_NAME(object)); + return FALSE; + } + + klass = g_type_class_peek(pspec->owner_type); + if (klass == NULL) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("'%s::%s' is not a valid property name; '%s' is not a GObject subtype"), + g_type_name(pspec->owner_type), + pspec->name, + g_type_name(pspec->owner_type)); + return FALSE; + } + + /* provide a copy to work from, convert (if necessary) and validate */ + g_value_init(&tmp_value, pspec->value_type); + if (!g_value_transform(value, &tmp_value)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("unable to set property '%s' of type '%s' from value of type '%s'"), + pspec->name, + g_type_name(pspec->value_type), + G_VALUE_TYPE_NAME(value)); + return FALSE; + } + if (g_param_value_validate(pspec, &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION)) { + gs_free char *contents = g_strdup_value_contents(value); + + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("value \"%s\" of type '%s' is invalid or out of range for property '%s' of " + "type '%s'"), + contents, + G_VALUE_TYPE_NAME(value), + pspec->name, + g_type_name(pspec->value_type)); + return FALSE; + } + + g_object_set_property(object, property_name, &tmp_value); + return TRUE; +} + +#define _set_property(object, property_name, gtype, gtype_set, value, error) \ + G_STMT_START \ + { \ + nm_auto_unset_gvalue GValue gvalue = {0}; \ + \ + g_value_init(&gvalue, gtype); \ + gtype_set(&gvalue, (value)); \ + return nm_g_object_set_property((object), (property_name), &gvalue, (error)); \ + } \ + G_STMT_END + +gboolean +nm_g_object_set_property_string(GObject * object, + const char *property_name, + const char *value, + GError ** error) +{ + _set_property(object, property_name, G_TYPE_STRING, g_value_set_string, value, error); +} + +gboolean +nm_g_object_set_property_string_static(GObject * object, + const char *property_name, + const char *value, + GError ** error) +{ + _set_property(object, property_name, G_TYPE_STRING, g_value_set_static_string, value, error); +} + +gboolean +nm_g_object_set_property_string_take(GObject * object, + const char *property_name, + char * value, + GError ** error) +{ + _set_property(object, property_name, G_TYPE_STRING, g_value_take_string, value, error); +} + +gboolean +nm_g_object_set_property_boolean(GObject * object, + const char *property_name, + gboolean value, + GError ** error) +{ + _set_property(object, property_name, G_TYPE_BOOLEAN, g_value_set_boolean, !!value, error); +} + +gboolean +nm_g_object_set_property_char(GObject * object, + const char *property_name, + gint8 value, + GError ** error) +{ + /* glib says about G_TYPE_CHAR: + * + * The type designated by G_TYPE_CHAR is unconditionally an 8-bit signed integer. + * + * This is always a (signed!) char. */ + _set_property(object, property_name, G_TYPE_CHAR, g_value_set_schar, value, error); +} + +gboolean +nm_g_object_set_property_uchar(GObject * object, + const char *property_name, + guint8 value, + GError ** error) +{ + _set_property(object, property_name, G_TYPE_UCHAR, g_value_set_uchar, value, error); +} + +gboolean +nm_g_object_set_property_int(GObject *object, const char *property_name, int value, GError **error) +{ + _set_property(object, property_name, G_TYPE_INT, g_value_set_int, value, error); +} + +gboolean +nm_g_object_set_property_int64(GObject * object, + const char *property_name, + gint64 value, + GError ** error) +{ + _set_property(object, property_name, G_TYPE_INT64, g_value_set_int64, value, error); +} + +gboolean +nm_g_object_set_property_uint(GObject * object, + const char *property_name, + guint value, + GError ** error) +{ + _set_property(object, property_name, G_TYPE_UINT, g_value_set_uint, value, error); +} + +gboolean +nm_g_object_set_property_uint64(GObject * object, + const char *property_name, + guint64 value, + GError ** error) +{ + _set_property(object, property_name, G_TYPE_UINT64, g_value_set_uint64, value, error); +} + +gboolean +nm_g_object_set_property_flags(GObject * object, + const char *property_name, + GType gtype, + guint value, + GError ** error) +{ + nm_assert(({ + nm_auto_unref_gtypeclass GTypeClass *gtypeclass = g_type_class_ref(gtype); + G_IS_FLAGS_CLASS(gtypeclass); + })); + _set_property(object, property_name, gtype, g_value_set_flags, value, error); +} + +gboolean +nm_g_object_set_property_enum(GObject * object, + const char *property_name, + GType gtype, + int value, + GError ** error) +{ + nm_assert(({ + nm_auto_unref_gtypeclass GTypeClass *gtypeclass = g_type_class_ref(gtype); + G_IS_ENUM_CLASS(gtypeclass); + })); + _set_property(object, property_name, gtype, g_value_set_enum, value, error); +} + +GParamSpec * +nm_g_object_class_find_property_from_gtype(GType gtype, const char *property_name) +{ + nm_auto_unref_gtypeclass GObjectClass *gclass = NULL; + + gclass = g_type_class_ref(gtype); + return g_object_class_find_property(gclass, property_name); +} + +/*****************************************************************************/ + +/** + * nm_g_type_find_implementing_class_for_property: + * @gtype: the GObject type which has a property @pname + * @pname: the name of the property to look up + * + * This is only a helper function for printf debugging. It's not + * used in actual code. Hence, the function just asserts that + * @pname and @gtype arguments are suitable. It cannot fail. + * + * Returns: the most ancestor type of @gtype, that + * implements the property @pname. It means, it + * searches the type hierarchy to find the type + * that added @pname. + */ +GType +nm_g_type_find_implementing_class_for_property(GType gtype, const char *pname) +{ + nm_auto_unref_gtypeclass GObjectClass *klass = NULL; + GParamSpec * pspec; + + g_return_val_if_fail(pname, G_TYPE_INVALID); + + klass = g_type_class_ref(gtype); + g_return_val_if_fail(G_IS_OBJECT_CLASS(klass), G_TYPE_INVALID); + + pspec = g_object_class_find_property(klass, pname); + g_return_val_if_fail(pspec, G_TYPE_INVALID); + + gtype = G_TYPE_FROM_CLASS(klass); + + while (TRUE) { + nm_auto_unref_gtypeclass GObjectClass *k = NULL; + + k = g_type_class_ref(g_type_parent(gtype)); + + g_return_val_if_fail(G_IS_OBJECT_CLASS(k), G_TYPE_INVALID); + + if (g_object_class_find_property(k, pname) != pspec) + return gtype; + + gtype = G_TYPE_FROM_CLASS(k); + } +} + +/*****************************************************************************/ + +static void +_str_buf_append_c_escape_octal(NMStrBuf *strbuf, char ch) +{ + nm_str_buf_append_c4(strbuf, + '\\', + '0' + ((char) ((((guchar) ch) >> 6) & 07)), + '0' + ((char) ((((guchar) ch) >> 3) & 07)), + '0' + ((char) ((((guchar) ch)) & 07))); +} + +/** + * nm_utils_buf_utf8safe_unescape: + * @str: (allow-none): the string to unescape. The string itself is a NUL terminated + * ASCII string, that can have C-style backslash escape sequences (which + * are to be unescaped). Non-ASCII characters (e.g. UTF-8) are taken verbatim, so + * it doesn't care that this string is UTF-8. However, usually this is a UTF-8 encoded + * string. + * @flags: flags for unescaping. The following flags are supported. + * %NM_UTILS_STR_UTF8_SAFE_UNESCAPE_STRIP_SPACES performs a g_strstrip() on the input string, + * but preserving escaped spaces. For example, "a\\t " gives "a\t" (that is, the escaped space does + * not get stripped). Likewise, the invalid escape sequence "a\\ " results in "a " (stripping + * the unescaped space, but preserving the escaped one). + * @out_len: (out): the length of the parsed string. + * @to_free: (out): if @str requires unescaping, the function will clone the string. In + * that case, the allocated buffer will be returned here. + * + * See C-style escapes at https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences. + * Note that hex escapes ("\\xhh") and unicode escapes ("\\uhhhh", "\\Uhhhhhhhh") are not supported. + * + * Also, this function is very similar to g_strcompress() but without issuing g_warning() + * assertions and proper handling of "\\000" escape sequences. + * + * Invalid escape sequences (or non-UTF-8 input) are gracefully accepted. For example "\\ " + * is an invalid escape sequence, in this case the backslash is removed and " " gets returned. + * + * The function never leaks secrets in memory. + * + * Returns: the unescaped buffer of length @out_len. If @str is %NULL, this returns %NULL + * and sets @out_len to 0. Otherwise, a non-%NULL binary buffer is returned with + * @out_len bytes. Note that the binary buffer is guaranteed to be NUL terminated. That + * is @result[@out_len] is NUL. + * Note that the result is binary, and may have embedded NUL characters and non-UTF-8. + * If the function can avoid cloning the input string, it will return a pointer inside + * the input @str. For example, if there is no backslash, no cloning is necessary. In that + * case, @to_free will be %NULL. Otherwise, @to_free is set to a newly allocated buffer + * containing the unescaped string and returned. + */ +gconstpointer +nm_utils_buf_utf8safe_unescape(const char * str, + NMUtilsStrUtf8SafeFlags flags, + gsize * out_len, + gpointer * to_free) +{ + gboolean strip_spaces = NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_UNESCAPE_STRIP_SPACES); + NMStrBuf strbuf; + const char *s; + gsize len; + + g_return_val_if_fail(to_free, NULL); + g_return_val_if_fail(out_len, NULL); + + if (!str) { + *out_len = 0; + *to_free = NULL; + return NULL; + } + + if (strip_spaces) + str = nm_str_skip_leading_spaces(str); + + len = strlen(str); + + s = memchr(str, '\\', len); + if (!s) { + if (strip_spaces && len > 0 && g_ascii_isspace(str[len - 1])) { + len--; + while (len > 0 && g_ascii_isspace(str[len - 1])) + len--; + *out_len = len; + return (*to_free = g_strndup(str, len)); + } + *out_len = len; + *to_free = NULL; + return str; + } + + nm_str_buf_init(&strbuf, len + 1u, FALSE); + + nm_str_buf_append_len(&strbuf, str, s - str); + str = s; + + for (;;) { + char ch; + guint v; + + nm_assert(str[0] == '\\'); + + ch = (++str)[0]; + + if (ch == '\0') { + /* error. Trailing '\\' */ + break; + } + + if (ch >= '0' && ch <= '9') { + v = ch - '0'; + ch = (++str)[0]; + if (ch >= '0' && ch <= '7') { + v = v * 8 + (ch - '0'); + ch = (++str)[0]; + if (ch >= '0' && ch <= '7') { + /* technically, escape sequences larger than \3FF are out of range + * and invalid. We don't check for that, and do the same as + * g_strcompress(): silently clip the value with & 0xFF. */ + v = v * 8 + (ch - '0'); + ++str; + } + } + ch = v; + } else { + switch (ch) { + case 'b': + ch = '\b'; + break; + case 'f': + ch = '\f'; + break; + case 'n': + ch = '\n'; + break; + case 'r': + ch = '\r'; + break; + case 't': + ch = '\t'; + break; + case 'v': + ch = '\v'; + break; + default: + /* Here we handle "\\\\", but all other unexpected escape sequences are really a bug. + * Take them literally, after removing the escape character */ + break; + } + str++; + } + + nm_str_buf_append_c(&strbuf, ch); + + s = strchr(str, '\\'); + if (!s) { + gsize l = strlen(str); + + if (strip_spaces) { + while (l > 0 && g_ascii_isspace(str[l - 1])) + l--; + } + nm_str_buf_append_len(&strbuf, str, l); + break; + } + + nm_str_buf_append_len(&strbuf, str, s - str); + str = s; + } + + /* assert that no reallocation was necessary. For one, unescaping should + * never result in a longer string than the input. Also, when unescaping + * secrets, we want to ensure that we don't leak secrets in memory. */ + nm_assert(strbuf.allocated == len + 1u); + + return (*to_free = nm_str_buf_finalize(&strbuf, out_len)); +} + +/** + * nm_utils_buf_utf8safe_escape: + * @buf: byte array, possibly in utf-8 encoding, may have NUL characters. + * @buflen: the length of @buf in bytes, or -1 if @buf is a NUL terminated + * string. + * @flags: #NMUtilsStrUtf8SafeFlags flags + * @to_free: (out): return the pointer location of the string + * if a copying was necessary. + * + * Based on the assumption, that @buf contains UTF-8 encoded bytes, + * this will return valid UTF-8 sequence, and invalid sequences + * will be escaped with backslash (C escaping, like g_strescape()). + * This is sanitize non UTF-8 characters. The result is valid + * UTF-8. + * + * The operation can be reverted with nm_utils_buf_utf8safe_unescape(). + * Note that if, and only if @buf contains no NUL bytes, the operation + * can also be reverted with g_strcompress(). + * + * Depending on @flags, valid UTF-8 characters are not escaped at all + * (except the escape character '\\'). This is the difference to g_strescape(), + * which escapes all non-ASCII characters. This allows to pass on + * valid UTF-8 characters as-is and can be directly shown to the user + * as UTF-8 -- with exception of the backslash escape character, + * invalid UTF-8 sequences, and other (depending on @flags). + * + * Returns: the escaped input buffer, as valid UTF-8. If no escaping + * is necessary, it returns the input @buf. Otherwise, an allocated + * string @to_free is returned which must be freed by the caller + * with g_free. The escaping can be reverted by g_strcompress(). + **/ +const char * +nm_utils_buf_utf8safe_escape(gconstpointer buf, + gssize buflen, + NMUtilsStrUtf8SafeFlags flags, + char ** to_free) +{ + const char *const str = buf; + const char * p = NULL; + const char * s; + gboolean nul_terminated = FALSE; + NMStrBuf strbuf; + + g_return_val_if_fail(to_free, NULL); + + *to_free = NULL; + + if (buflen == 0) + return NULL; + + if (buflen < 0) { + if (!str) + return NULL; + buflen = strlen(str); + if (buflen == 0) + return str; + nul_terminated = TRUE; + } + + if (g_utf8_validate(str, buflen, &p) && nul_terminated) { + /* note that g_utf8_validate() does not allow NUL character inside @str. Good. + * We can treat @str like a NUL terminated string. */ + if (!NM_STRCHAR_ANY( + str, + ch, + (ch == '\\' + || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) && ch < ' ') + || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) + && ((guchar) ch) >= 127)))) + return str; + } + + nm_str_buf_init(&strbuf, buflen + 5, NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_SECRET)); + + s = str; + do { + buflen -= p - s; + nm_assert(buflen >= 0); + + for (; s < p; s++) { + char ch = s[0]; + + nm_assert(ch); + if (ch == '\\') + nm_str_buf_append_c2(&strbuf, '\\', '\\'); + else if ((NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) && ch < ' ') + || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) + && ((guchar) ch) >= 127)) + _str_buf_append_c_escape_octal(&strbuf, ch); + else + nm_str_buf_append_c(&strbuf, ch); + } + + if (buflen <= 0) + break; + + _str_buf_append_c_escape_octal(&strbuf, p[0]); + + buflen--; + if (buflen == 0) + break; + + s = &p[1]; + (void) g_utf8_validate(s, buflen, &p); + } while (TRUE); + + return (*to_free = nm_str_buf_finalize(&strbuf, NULL)); +} + +const char * +nm_utils_buf_utf8safe_escape_bytes(GBytes *bytes, NMUtilsStrUtf8SafeFlags flags, char **to_free) +{ + gconstpointer p; + gsize l; + + if (bytes) + p = g_bytes_get_data(bytes, &l); + else { + p = NULL; + l = 0; + } + + return nm_utils_buf_utf8safe_escape(p, l, flags, to_free); +} + +char * +nm_utils_buf_utf8safe_escape_cp(gconstpointer buf, gssize buflen, NMUtilsStrUtf8SafeFlags flags) +{ + const char *s_const; + char * s; + + s_const = nm_utils_buf_utf8safe_escape(buf, buflen, flags, &s); + nm_assert(!s || s == s_const); + return s ?: g_strdup(s_const); +} + +/*****************************************************************************/ + +const char * +nm_utils_str_utf8safe_unescape(const char *str, NMUtilsStrUtf8SafeFlags flags, char **to_free) +{ + const char *res; + gsize len; + + g_return_val_if_fail(to_free, NULL); + + res = nm_utils_buf_utf8safe_unescape(str, flags, &len, (gpointer *) to_free); + + nm_assert((!res && len == 0) || (strlen(res) <= len)); + + return res; +} + +/** + * nm_utils_str_utf8safe_escape: + * @str: NUL terminated input string, possibly in utf-8 encoding + * @flags: #NMUtilsStrUtf8SafeFlags flags + * @to_free: (out): return the pointer location of the string + * if a copying was necessary. + * + * Returns the possible non-UTF-8 NUL terminated string @str + * and uses backslash escaping (C escaping, like g_strescape()) + * to sanitize non UTF-8 characters. The result is valid + * UTF-8. + * + * The operation can be reverted with g_strcompress() or + * nm_utils_str_utf8safe_unescape(). + * + * Depending on @flags, valid UTF-8 characters are not escaped at all + * (except the escape character '\\'). This is the difference to g_strescape(), + * which escapes all non-ASCII characters. This allows to pass on + * valid UTF-8 characters as-is and can be directly shown to the user + * as UTF-8 -- with exception of the backslash escape character, + * invalid UTF-8 sequences, and other (depending on @flags). + * + * Returns: the escaped input string, as valid UTF-8. If no escaping + * is necessary, it returns the input @str. Otherwise, an allocated + * string @to_free is returned which must be freed by the caller + * with g_free. The escaping can be reverted by g_strcompress(). + **/ +const char * +nm_utils_str_utf8safe_escape(const char *str, NMUtilsStrUtf8SafeFlags flags, char **to_free) +{ + return nm_utils_buf_utf8safe_escape(str, -1, flags, to_free); +} + +/** + * nm_utils_str_utf8safe_escape_cp: + * @str: NUL terminated input string, possibly in utf-8 encoding + * @flags: #NMUtilsStrUtf8SafeFlags flags + * + * Like nm_utils_str_utf8safe_escape(), except the returned value + * is always a copy of the input and must be freed by the caller. + * + * Returns: the escaped input string in UTF-8 encoding. The returned + * value should be freed with g_free(). + * The escaping can be reverted by g_strcompress(). + **/ +char * +nm_utils_str_utf8safe_escape_cp(const char *str, NMUtilsStrUtf8SafeFlags flags) +{ + char *s; + + nm_utils_str_utf8safe_escape(str, flags, &s); + return s ?: g_strdup(str); +} + +char * +nm_utils_str_utf8safe_unescape_cp(const char *str, NMUtilsStrUtf8SafeFlags flags) +{ + char *s; + + str = nm_utils_str_utf8safe_unescape(str, flags, &s); + return s ?: g_strdup(str); +} + +char * +nm_utils_str_utf8safe_escape_take(char *str, NMUtilsStrUtf8SafeFlags flags) +{ + char *str_to_free; + + nm_utils_str_utf8safe_escape(str, flags, &str_to_free); + if (str_to_free) { + g_free(str); + return str_to_free; + } + return str; +} + +/*****************************************************************************/ + +/* taken from systemd's fd_wait_for_event(). Note that the timeout + * is here in nano-seconds, not micro-seconds. */ +int +nm_utils_fd_wait_for_event(int fd, int event, gint64 timeout_nsec) +{ + struct pollfd pollfd = { + .fd = fd, + .events = event, + }; + struct timespec ts, *pts; + int r; + + if (timeout_nsec < 0) + pts = NULL; + else { + ts.tv_sec = (time_t)(timeout_nsec / NM_UTILS_NSEC_PER_SEC); + ts.tv_nsec = (long int) (timeout_nsec % NM_UTILS_NSEC_PER_SEC); + pts = &ts; + } + + r = ppoll(&pollfd, 1, pts, NULL); + if (r < 0) + return -NM_ERRNO_NATIVE(errno); + if (r == 0) + return 0; + return pollfd.revents; +} + +/* taken from systemd's loop_read() */ +ssize_t +nm_utils_fd_read_loop(int fd, void *buf, size_t nbytes, bool do_poll) +{ + uint8_t *p = buf; + ssize_t n = 0; + + g_return_val_if_fail(fd >= 0, -EINVAL); + g_return_val_if_fail(buf, -EINVAL); + + /* If called with nbytes == 0, let's call read() at least + * once, to validate the operation */ + + if (nbytes > (size_t) SSIZE_MAX) + return -EINVAL; + + do { + ssize_t k; + + k = read(fd, p, nbytes); + if (k < 0) { + int errsv = errno; + + if (errsv == EINTR) + continue; + + if (errsv == EAGAIN && do_poll) { + /* We knowingly ignore any return value here, + * and expect that any error/EOF is reported + * via read() */ + + (void) nm_utils_fd_wait_for_event(fd, POLLIN, -1); + continue; + } + + return n > 0 ? n : -NM_ERRNO_NATIVE(errsv); + } + + if (k == 0) + return n; + + g_assert((size_t) k <= nbytes); + + p += k; + nbytes -= k; + n += k; + } while (nbytes > 0); + + return n; +} + +/* taken from systemd's loop_read_exact() */ +int +nm_utils_fd_read_loop_exact(int fd, void *buf, size_t nbytes, bool do_poll) +{ + ssize_t n; + + n = nm_utils_fd_read_loop(fd, buf, nbytes, do_poll); + if (n < 0) + return (int) n; + if ((size_t) n != nbytes) + return -EIO; + + return 0; +} + +/*****************************************************************************/ + +void +nm_utils_named_value_clear_with_g_free(NMUtilsNamedValue *val) +{ + if (val) { + gs_free gpointer x_name = NULL; + gs_free gpointer x_value = NULL; + + x_name = (gpointer) g_steal_pointer(&val->name); + x_value = g_steal_pointer(&val->value_ptr); + } +} + +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMUtilsNamedValue, name) == 0); + +NMUtilsNamedValue * +nm_utils_named_values_from_strdict_full(GHashTable * hash, + guint * out_len, + GCompareDataFunc compare_func, + gpointer user_data, + NMUtilsNamedValue * provided_buffer, + guint provided_buffer_len, + NMUtilsNamedValue **out_allocated_buffer) +{ + GHashTableIter iter; + NMUtilsNamedValue *values; + guint i, len; + + nm_assert(provided_buffer_len == 0 || provided_buffer); + nm_assert(!out_allocated_buffer || !*out_allocated_buffer); + + if (!hash || !(len = g_hash_table_size(hash))) { + NM_SET_OUT(out_len, 0); + return NULL; + } + + if (provided_buffer_len >= len + 1) { + /* the buffer provided by the caller is large enough. Use it. */ + values = provided_buffer; + } else { + /* allocate a new buffer. */ + values = g_new(NMUtilsNamedValue, len + 1); + NM_SET_OUT(out_allocated_buffer, values); + } + + i = 0; + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &values[i].name, &values[i].value_ptr)) + i++; + nm_assert(i == len); + values[i].name = NULL; + values[i].value_ptr = NULL; + + if (compare_func) + nm_utils_named_value_list_sort(values, len, compare_func, user_data); + + NM_SET_OUT(out_len, len); + return values; +} + +gssize +nm_utils_named_value_list_find(const NMUtilsNamedValue *arr, + gsize len, + const char * name, + gboolean sorted) +{ + gsize i; + + nm_assert(name); + +#if NM_MORE_ASSERTS > 5 + { + for (i = 0; i < len; i++) { + const NMUtilsNamedValue *v = &arr[i]; + + nm_assert(v->name); + if (sorted && i > 0) + nm_assert(strcmp(arr[i - 1].name, v->name) < 0); + } + } + + nm_assert(!sorted || nm_utils_named_value_list_is_sorted(arr, len, FALSE, NULL, NULL)); +#endif + + if (sorted) { + return nm_utils_array_find_binary_search(arr, + sizeof(NMUtilsNamedValue), + len, + &name, + nm_strcmp_p_with_data, + NULL); + } + for (i = 0; i < len; i++) { + if (nm_streq(arr[i].name, name)) + return i; + } + return ~((gssize) len); +} + +gboolean +nm_utils_named_value_list_is_sorted(const NMUtilsNamedValue *arr, + gsize len, + gboolean accept_duplicates, + GCompareDataFunc compare_func, + gpointer user_data) +{ + gsize i; + int c_limit; + + if (len == 0) + return TRUE; + + g_return_val_if_fail(arr, FALSE); + + if (!compare_func) + compare_func = nm_strcmp_p_with_data; + + c_limit = accept_duplicates ? 0 : -1; + + for (i = 1; i < len; i++) { + int c; + + c = compare_func(&arr[i - 1], &arr[i], user_data); + if (c > c_limit) + return FALSE; + } + return TRUE; +} + +void +nm_utils_named_value_list_sort(NMUtilsNamedValue *arr, + gsize len, + GCompareDataFunc compare_func, + gpointer user_data) +{ + if (len == 0) + return; + + g_return_if_fail(arr); + + if (len == 1) + return; + + g_qsort_with_data(arr, + len, + sizeof(NMUtilsNamedValue), + compare_func ?: nm_strcmp_p_with_data, + user_data); +} + +/*****************************************************************************/ + +gpointer * +nm_utils_hash_keys_to_array(GHashTable * hash, + GCompareDataFunc compare_func, + gpointer user_data, + guint * out_len) +{ + guint len; + gpointer *keys; + + /* by convention, we never return an empty array. In that + * case, always %NULL. */ + if (!hash || g_hash_table_size(hash) == 0) { + NM_SET_OUT(out_len, 0); + return NULL; + } + + keys = g_hash_table_get_keys_as_array(hash, &len); + if (len > 1 && compare_func) { + g_qsort_with_data(keys, len, sizeof(gpointer), compare_func, user_data); + } + NM_SET_OUT(out_len, len); + return keys; +} + +gpointer * +nm_utils_hash_values_to_array(GHashTable * hash, + GCompareDataFunc compare_func, + gpointer user_data, + guint * out_len) +{ + GHashTableIter iter; + gpointer value; + gpointer * arr; + guint i, len; + + if (!hash || (len = g_hash_table_size(hash)) == 0u) { + NM_SET_OUT(out_len, 0); + return NULL; + } + + arr = g_new(gpointer, ((gsize) len) + 1); + i = 0; + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &value)) + arr[i++] = value; + + nm_assert(i == len); + arr[len] = NULL; + + if (len > 1 && compare_func) { + g_qsort_with_data(arr, len, sizeof(gpointer), compare_func, user_data); + } + + NM_SET_OUT(out_len, len); + return arr; +} + +/*****************************************************************************/ + +/** + * nm_utils_hashtable_equal: + * @a: one #GHashTable + * @b: other #GHashTable + * @treat_null_as_empty: if %TRUE, when either @a or @b is %NULL, it is + * treated like an empty hash. It means, a %NULL hash will compare equal + * to an empty hash. + * @equal_func: the equality function, for comparing the values. + * If %NULL, the values are not compared. In that case, the function + * only checks, if both dictionaries have the same keys -- according + * to @b's key equality function. + * Note that the values of @a will be passed as first argument + * to @equal_func. + * + * Compares two hash tables, whether they have equal content. + * This only makes sense, if @a and @b have the same key types and + * the same key compare-function. + * + * Returns: %TRUE, if both dictionaries have the same content. + */ +gboolean +nm_utils_hashtable_equal(const GHashTable *a, + const GHashTable *b, + gboolean treat_null_as_empty, + GEqualFunc equal_func) +{ + guint n; + GHashTableIter iter; + gconstpointer key, v_a, v_b; + + if (a == b) + return TRUE; + if (!treat_null_as_empty) { + if (!a || !b) + return FALSE; + } + + n = a ? g_hash_table_size((GHashTable *) a) : 0; + if (n != (b ? g_hash_table_size((GHashTable *) b) : 0)) + return FALSE; + + if (n > 0) { + g_hash_table_iter_init(&iter, (GHashTable *) a); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &v_a)) { + if (!g_hash_table_lookup_extended((GHashTable *) b, key, NULL, (gpointer *) &v_b)) + return FALSE; + if (equal_func && !equal_func(v_a, v_b)) + return FALSE; + } + } + + return TRUE; +} + +static gboolean +_utils_hashtable_equal(GHashTable * hash_a, + GHashTable * hash_b, + GCompareDataFunc cmp_values, + gpointer user_data) +{ + GHashTableIter h; + gpointer a_key; + gpointer a_val; + gpointer b_val; + + nm_assert(hash_a); + nm_assert(hash_b); + nm_assert(hash_a != hash_b); + nm_assert(g_hash_table_size(hash_a) == g_hash_table_size(hash_b)); + + /* We rely on both hashes to have the same hash/equal function. Otherwise, we would have to iterate + * both hashes and check whether all keys/values are present in the respective other hash (which + * would be O(n^2), since we couldn't use the plain lookup function. That is not a useful thing + * for this function. */ + + g_hash_table_iter_init(&h, hash_a); + while (g_hash_table_iter_next(&h, &a_key, &a_val)) { + if (!g_hash_table_lookup_extended(hash_b, a_key, NULL, &b_val)) + return FALSE; + + if (!cmp_values) { + /* we accept %NULL compare function to indicate that we don't care about the key. */ + continue; + } + + if (cmp_values(a_val, b_val, user_data) != 0) + return FALSE; + } + + return TRUE; +} + +/** + * nm_utils_hashtable_cmp_equal: + * @a: (allow-none): the hash table or %NULL + * @b: (allow-none): the other hash table or %NULL + * @cmp_values: (allow-none): if %NULL, only the keys + * will be compared. Otherwise, this function is used to + * check whether all keys are equal. + * @user_data: the argument for @cmp_values. + * + * It is required that both @a and @b have the same hash and equals + * function. + * + * Returns: %TRUE, if both keys have the same keys and (if + * @cmp_values is given) all values are the same. + */ +gboolean +nm_utils_hashtable_cmp_equal(const GHashTable *a, + const GHashTable *b, + GCompareDataFunc cmp_values, + gpointer user_data) +{ + GHashTable *hash_a = (GHashTable *) a; + GHashTable *hash_b = (GHashTable *) b; + gboolean same; + guint size; + + if (hash_a == hash_b) + return TRUE; + + if (!hash_a || !hash_b) + return FALSE; + + size = g_hash_table_size(hash_a); + if (size != g_hash_table_size(hash_b)) + return FALSE; + + if (size == 0) + return TRUE; + + same = _utils_hashtable_equal(hash_a, hash_b, cmp_values, user_data); + +#if NM_MORE_ASSERTS > 5 + nm_assert(same == _utils_hashtable_equal(hash_b, hash_a, cmp_values, user_data)); +#endif + + return same; +} + +typedef struct { + gpointer key; + gpointer val; +} HashTableCmpData; + +typedef struct { + GCompareDataFunc cmp_keys; + gpointer user_data; +} HashTableUserData; + +static int +_hashtable_cmp_func(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const HashTableUserData *d = user_data; + const HashTableCmpData * d_a = *((const HashTableCmpData *const *) a); + const HashTableCmpData * d_b = *((const HashTableCmpData *const *) b); + + NM_CMP_RETURN(d->cmp_keys(d_a, d_b, d->user_data)); + return 0; +} + +/** + * nm_utils_hashtable_cmp: + * @a: (allow-none): the hash to compare. May be %NULL. + * @b: (allow-none): the other hash to compare. May be %NULL. + * @do_fast_precheck: if %TRUE, assume that the hashes are equal + * and that it is worth calling nm_utils_hashtable_cmp_equal() first. + * That requires, that both hashes have the same equals function + * which is compatible with the @cmp_keys function. + * @cmp_keys: the compare function for keys. Usually, the hash/equal function + * of both hashes corresponds to this function. If you set @do_fast_precheck + * to false, then this is not a requirement. + * @cmp_values: (allow-none): if %NULL, only the keys are compared. + * Otherwise, the values must are also compared with this function. + * + * Both hashes must have keys/values of the same domain, so that + * they can be effectively compared with @cmp_keys and @cmp_values. + * + * %NULL hashes compare equal to %NULL, but not to empty hashes. + * + * Returns: 0 if both hashes are equal, or -1 or 1 if one of the hashes + * sorts before/after. + */ +int +nm_utils_hashtable_cmp(const GHashTable *a, + const GHashTable *b, + gboolean do_fast_precheck, + GCompareDataFunc cmp_keys, + GCompareDataFunc cmp_values, + gpointer user_data) +{ + GHashTable *hash_a = (GHashTable *) a; + GHashTable *hash_b = (GHashTable *) b; + gs_free HashTableCmpData *cmp_array_free = NULL; + HashTableCmpData * cmp_array_a; + HashTableCmpData * cmp_array_b; + GHashTableIter h; + gpointer i_key; + gpointer i_val; + gsize size2; + guint size; + guint i; + + nm_assert(cmp_keys); + + NM_CMP_SELF(hash_a, hash_b); + + size = g_hash_table_size(hash_a); + + NM_CMP_DIRECT(size, g_hash_table_size(hash_b)); + + if (size == 0) + return 0; + + if (do_fast_precheck) { + gboolean same; + + /* we expect that the hashes are equal and the caller ensures us that they + * use the same hash/equal functions. Do a fast path check first... + * + * It's unclear whether this is worth it. The full comparison is O(n*ln(n)), + * while the fast check (using the hash lookup) is O(n). But then, the pre-check + * makes additional requirements on the hash's hash/equal functions -- the + * full comparison does not make such requirements. */ + same = _utils_hashtable_equal(hash_a, hash_b, cmp_values, user_data); +#if NM_MORE_ASSERTS > 5 + nm_assert(same == _utils_hashtable_equal(hash_b, hash_a, cmp_values, user_data)); +#endif + if (same) + return 0; + } + + size2 = ((gsize) size) * 2u; + if (size2 > 600u / sizeof(HashTableCmpData)) { + cmp_array_free = g_new(HashTableCmpData, size2); + cmp_array_a = cmp_array_free; + } else + cmp_array_a = g_newa(HashTableCmpData, size2); + cmp_array_b = &cmp_array_a[size]; + + i = 0; + g_hash_table_iter_init(&h, hash_a); + while (g_hash_table_iter_next(&h, &i_key, &i_val)) { + nm_assert(i < size); + cmp_array_a[i++] = (HashTableCmpData){ + .key = i_key, + .val = i_val, + }; + } + nm_assert(i == size); + + i = 0; + g_hash_table_iter_init(&h, hash_b); + while (g_hash_table_iter_next(&h, &i_key, &i_val)) { + nm_assert(i < size); + cmp_array_b[i++] = (HashTableCmpData){ + .key = i_key, + .val = i_val, + }; + } + nm_assert(i == size); + + g_qsort_with_data(cmp_array_a, + size, + sizeof(HashTableCmpData), + _hashtable_cmp_func, + &((HashTableUserData){ + .cmp_keys = cmp_keys, + .user_data = user_data, + })); + + g_qsort_with_data(cmp_array_b, + size, + sizeof(HashTableCmpData), + _hashtable_cmp_func, + &((HashTableUserData){ + .cmp_keys = cmp_keys, + .user_data = user_data, + })); + + for (i = 0; i < size; i++) { + NM_CMP_RETURN(cmp_keys(cmp_array_a[i].key, cmp_array_b[i].key, user_data)); + } + + if (cmp_values) { + for (i = 0; i < size; i++) { + NM_CMP_RETURN(cmp_values(cmp_array_a[i].val, cmp_array_b[i].val, user_data)); + } + } + + /* the fast-precheck should have already told that the arrays are equal. */ + nm_assert(!do_fast_precheck); + + return 0; +} + +char ** +nm_utils_strv_make_deep_copied(const char **strv) +{ + gsize i; + + /* it takes a strv list, and copies each + * strings. Note that this updates @strv *in-place* + * and returns it. */ + + if (!strv) + return NULL; + for (i = 0; strv[i]; i++) + strv[i] = g_strdup(strv[i]); + + return (char **) strv; +} + +char ** +nm_utils_strv_make_deep_copied_n(const char **strv, gsize len) +{ + gsize i; + + /* it takes a strv array with len elements, and copies each + * strings. Note that this updates @strv *in-place* + * and returns it. */ + + if (!strv) + return NULL; + for (i = 0; i < len; i++) + strv[i] = g_strdup(strv[i]); + + return (char **) strv; +} + +/** + * @strv: the strv array to copy. It may be %NULL if @len + * is negative or zero (in which case %NULL will be returned). + * @len: the length of strings in @str. If negative, strv is assumed + * to be a NULL terminated array. + * @deep_copied: if %TRUE, clones the individual strings. In that case, + * the returned array must be freed with g_strfreev(). Otherwise, the + * strings themself are not copied. You must take care of who owns the + * strings yourself. + * + * Like g_strdupv(), with two differences: + * + * - accepts a @len parameter for non-null terminated strv array. + * + * - this never returns an empty strv array, but always %NULL if + * there are no strings. + * + * Note that if @len is non-negative, then it still must not + * contain any %NULL pointers within the first @len elements. + * Otherwise, you would leak elements if you try to free the + * array with g_strfreev(). Allowing that would be error prone. + * + * Returns: (transfer full): a clone of the strv array. Always + * %NULL terminated. Depending on @deep_copied, the strings are + * cloned or not. + */ +char ** +_nm_utils_strv_dup(const char *const *strv, gssize len, gboolean deep_copied) +{ + gsize i, l; + char **v; + + if (len < 0) + l = NM_PTRARRAY_LEN(strv); + else + l = len; + if (l == 0) { + /* this function never returns an empty strv array. If you + * need that, handle it yourself. */ + return NULL; + } + + v = g_new(char *, l + 1); + for (i = 0; i < l; i++) { + if (G_UNLIKELY(!strv[i])) { + /* NULL strings are not allowed. Clear the remainder of the array + * and return it (with assertion failure). */ + l++; + for (; i < l; i++) + v[i] = NULL; + g_return_val_if_reached(v); + } + + if (deep_copied) + v[i] = g_strdup(strv[i]); + else + v[i] = (char *) strv[i]; + } + v[l] = NULL; + return v; +} + +const char ** +_nm_utils_strv_dup_packed(const char *const *strv, gssize len) + +{ + gs_free gsize *str_len_free = NULL; + gsize * str_len; + const char ** result; + gsize mem_len; + gsize pre_len; + gsize len2; + char * sbuf; + gsize i; + + nm_assert(len >= -1); + + if (G_LIKELY(len < 0)) { + if (!strv || !strv[0]) { + /* This function never returns an empty strv array. If you need that, handle it + * yourself. */ + return NULL; + } + len2 = NM_PTRARRAY_LEN(strv); + } else { + if (len == 0) + return NULL; + len2 = len; + } + + if (len2 > 300u / sizeof(gsize)) { + str_len_free = g_new(gsize, len2); + str_len = str_len_free; + } else + str_len = g_newa(gsize, len2); + + mem_len = 0; + for (i = 0; i < len2; i++) { + gsize l; + + if (G_LIKELY(strv[i])) + l = strlen(strv[i]) + 1u; + else + l = 0; + str_len[i] = l; + mem_len += l; + } + + pre_len = sizeof(const char *) * (len2 + 1u); + + result = g_malloc(pre_len + mem_len); + sbuf = &(((char *) result)[pre_len]); + for (i = 0; i < len2; i++) { + gsize l; + + if (G_UNLIKELY(!strv[i])) { + /* Technically there is no problem with accepting NULL strings. But that + * does not really result in a strv array, and likely this only happens due + * to a bug. We want to catch such bugs by asserting. + * + * We clear the remainder of the buffer and fail with an assertion. */ + len2++; + for (; i < len2; i++) + result[i] = NULL; + g_return_val_if_reached(result); + } + + result[i] = sbuf; + + l = str_len[i]; + memcpy(sbuf, strv[i], l); + sbuf += l; + } + result[i] = NULL; + nm_assert(i == len2); + nm_assert(sbuf == (&((const char *) result)[pre_len]) + mem_len); + + return result; +} + +/*****************************************************************************/ + +gssize +nm_utils_ptrarray_find_first(gconstpointer *list, gssize len, gconstpointer needle) +{ + gssize i; + + if (len == 0) + return -1; + + if (len > 0) { + g_return_val_if_fail(list, -1); + for (i = 0; i < len; i++) { + if (list[i] == needle) + return i; + } + } else { + g_return_val_if_fail(needle, -1); + for (i = 0; list && list[i]; i++) { + if (list[i] == needle) + return i; + } + } + return -1; +} + +/*****************************************************************************/ + +gssize +nm_utils_ptrarray_find_binary_search(gconstpointer * list, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data) +{ + gssize imin, imax, imid; + int cmp; + + g_return_val_if_fail(list || !len, ~((gssize) 0)); + g_return_val_if_fail(cmpfcn, ~((gssize) 0)); + + imin = 0; + if (len > 0) { + imax = len - 1; + + while (imin <= imax) { + imid = imin + (imax - imin) / 2; + + cmp = cmpfcn(list[imid], needle, user_data); + if (cmp == 0) + return imid; + + if (cmp < 0) + imin = imid + 1; + else + imax = imid - 1; + } + } + + /* return the inverse of @imin. This is a negative number, but + * also is ~imin the position where the value should be inserted. */ + imin = ~imin; + return imin; +} + +gssize +nm_utils_ptrarray_find_binary_search_range(gconstpointer * list, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data, + gssize * out_idx_first, + gssize * out_idx_last) +{ + gssize imin, imax, imid, i2min, i2max, i2mid; + int cmp; + + g_return_val_if_fail(list || !len, ~((gssize) 0)); + g_return_val_if_fail(cmpfcn, ~((gssize) 0)); + + imin = 0; + if (len > 0) { + imax = len - 1; + + while (imin <= imax) { + imid = imin + (imax - imin) / 2; + + cmp = cmpfcn(list[imid], needle, user_data); + if (cmp == 0) { + /* we found a matching entry at index imid. + * + * Does the caller request the first/last index as well (in case that + * there are multiple entries which compare equal). */ + + if (out_idx_first) { + i2min = imin; + i2max = imid + 1; + while (i2min <= i2max) { + i2mid = i2min + (i2max - i2min) / 2; + + cmp = cmpfcn(list[i2mid], needle, user_data); + if (cmp == 0) + i2max = i2mid - 1; + else { + nm_assert(cmp < 0); + i2min = i2mid + 1; + } + } + *out_idx_first = i2min; + } + if (out_idx_last) { + i2min = imid + 1; + i2max = imax; + while (i2min <= i2max) { + i2mid = i2min + (i2max - i2min) / 2; + + cmp = cmpfcn(list[i2mid], needle, user_data); + if (cmp == 0) + i2min = i2mid + 1; + else { + nm_assert(cmp > 0); + i2max = i2mid - 1; + } + } + *out_idx_last = i2min - 1; + } + return imid; + } + + if (cmp < 0) + imin = imid + 1; + else + imax = imid - 1; + } + } + + /* return the inverse of @imin. This is a negative number, but + * also is ~imin the position where the value should be inserted. */ + imin = ~imin; + NM_SET_OUT(out_idx_first, imin); + NM_SET_OUT(out_idx_last, imin); + return imin; +} + +/*****************************************************************************/ + +/** + * nm_utils_array_find_binary_search: + * @list: the list to search. It must be sorted according to @cmpfcn ordering. + * @elem_size: the size in bytes of each element in the list + * @len: the number of elements in @list + * @needle: the value that is searched + * @cmpfcn: the compare function. The elements @list are passed as first + * argument to @cmpfcn, while @needle is passed as second. Usually, the + * needle is the same data type as inside the list, however, that is + * not necessary, as long as @cmpfcn takes care to cast the two arguments + * accordingly. + * @user_data: optional argument passed to @cmpfcn + * + * Performs binary search for @needle in @list. On success, returns the + * (non-negative) index where the compare function found the searched element. + * On success, it returns a negative value. Note that the return negative value + * is the bitwise inverse of the position where the element should be inserted. + * + * If the list contains multiple matching elements, an arbitrary index is + * returned. + * + * Returns: the index to the element in the list, or the (negative, bitwise inverted) + * position where it should be. + */ +gssize +nm_utils_array_find_binary_search(gconstpointer list, + gsize elem_size, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data) +{ + gssize imin, imax, imid; + int cmp; + + g_return_val_if_fail(list || !len, ~((gssize) 0)); + g_return_val_if_fail(cmpfcn, ~((gssize) 0)); + g_return_val_if_fail(elem_size > 0, ~((gssize) 0)); + + imin = 0; + if (len == 0) + return ~imin; + + imax = len - 1; + + while (imin <= imax) { + imid = imin + (imax - imin) / 2; + + cmp = cmpfcn(&((const char *) list)[elem_size * imid], needle, user_data); + if (cmp == 0) + return imid; + + if (cmp < 0) + imin = imid + 1; + else + imax = imid - 1; + } + + /* return the inverse of @imin. This is a negative number, but + * also is ~imin the position where the value should be inserted. */ + return ~imin; +} + +/*****************************************************************************/ + +/** + * nm_utils_get_start_time_for_pid: + * @pid: the process identifier + * @out_state: return the state character, like R, S, Z. See `man 5 proc`. + * @out_ppid: parent process id + * + * Originally copied from polkit source (src/polkit/polkitunixprocess.c) + * and adjusted. + * + * Returns: the timestamp when the process started (by parsing /proc/$PID/stat). + * If an error occurs (e.g. the process does not exist), 0 is returned. + * + * The returned start time counts since boot, in the unit HZ (with HZ usually being (1/100) seconds) + **/ +guint64 +nm_utils_get_start_time_for_pid(pid_t pid, char *out_state, pid_t *out_ppid) +{ + guint64 start_time; + char filename[256]; + gs_free char * contents = NULL; + size_t length; + gs_free const char **tokens = NULL; + char * p; + char state = ' '; + gint64 ppid = 0; + + start_time = 0; + contents = NULL; + + g_return_val_if_fail(pid > 0, 0); + + G_STATIC_ASSERT_EXPR(sizeof(GPid) >= sizeof(pid_t)); + + nm_sprintf_buf(filename, "/proc/%" G_PID_FORMAT "/stat", (GPid) pid); + + if (!g_file_get_contents(filename, &contents, &length, NULL)) + goto fail; + + /* start time is the token at index 19 after the '(process name)' entry - since only this + * field can contain the ')' character, search backwards for this to avoid malicious + * processes trying to fool us + */ + p = strrchr(contents, ')'); + if (!p) + goto fail; + p += 2; /* skip ') ' */ + if (p - contents >= (int) length) + goto fail; + + state = p[0]; + + tokens = nm_utils_strsplit_set(p, " "); + + if (NM_PTRARRAY_LEN(tokens) < 20) + goto fail; + + if (out_ppid) { + ppid = _nm_utils_ascii_str_to_int64(tokens[1], 10, 1, G_MAXINT, 0); + if (ppid == 0) + goto fail; + } + + start_time = _nm_utils_ascii_str_to_int64(tokens[19], 10, 1, G_MAXINT64, 0); + if (start_time == 0) + goto fail; + + NM_SET_OUT(out_state, state); + NM_SET_OUT(out_ppid, ppid); + return start_time; + +fail: + NM_SET_OUT(out_state, ' '); + NM_SET_OUT(out_ppid, 0); + return 0; +} + +/*****************************************************************************/ + +/** + * _nm_utils_strv_sort: + * @strv: pointer containing strings that will be sorted + * in-place, %NULL is allowed, unless @len indicates + * that there are more elements. + * @len: the number of elements in strv. If negative, + * strv must be a NULL terminated array and the length + * will be calculated first. If @len is a positive + * number, @strv is allowed to contain %NULL strings + * too. + * + * Ascending sort of the array @strv inplace, using plain strcmp() string + * comparison. + */ +void +_nm_utils_strv_sort(const char **strv, gssize len) +{ + GCompareDataFunc cmp; + gsize l; + + if (len < 0) { + l = NM_PTRARRAY_LEN(strv); + cmp = nm_strcmp_p_with_data; + } else { + l = len; + cmp = nm_strcmp0_p_with_data; + } + + if (l <= 1) + return; + + nm_assert(l <= (gsize) G_MAXINT); + + g_qsort_with_data(strv, l, sizeof(const char *), cmp, NULL); +} + +/** + * _nm_utils_strv_cmp_n: + * @strv1: a string array + * @len1: the length of @strv1, or -1 for NULL terminated array. + * @strv2: a string array + * @len2: the length of @strv2, or -1 for NULL terminated array. + * + * Note that + * - len == -1 && strv == NULL + * is treated like a %NULL argument and compares differently from + * other arrays. + * + * Note that an empty array can be represented as + * - len == -1 && strv && !strv[0] + * - len == 0 && !strv + * - len == 0 && strv + * These 3 forms all compare equal. + * It also means, if length is 0, then it is permissible for strv to be %NULL. + * + * The strv arrays may contain %NULL strings (if len is positive). + * + * Returns: 0 if the arrays are equal (using strcmp). + **/ +int +_nm_utils_strv_cmp_n(const char *const *strv1, gssize len1, const char *const *strv2, gssize len2) +{ + gsize n, n2; + + if (len1 < 0) { + if (!strv1) + return (len2 < 0 && !strv2) ? 0 : -1; + n = NM_PTRARRAY_LEN(strv1); + } else + n = len1; + + if (len2 < 0) { + if (!strv2) + return 1; + n2 = NM_PTRARRAY_LEN(strv2); + } else + n2 = len2; + + NM_CMP_DIRECT(n, n2); + for (; n > 0; n--, strv1++, strv2++) + NM_CMP_DIRECT_STRCMP0(*strv1, *strv2); + return 0; +} + +/*****************************************************************************/ + +/** + * nm_utils_g_slist_find_str: + * @list: the #GSList with NUL terminated strings to search + * @needle: the needle string to look for. + * + * Search the list for @needle and return the first found match + * (or %NULL if not found). Uses strcmp() for finding the first matching + * element. + * + * Returns: the #GSList element with @needle as string value or + * %NULL if not found. + */ +GSList * +nm_utils_g_slist_find_str(const GSList *list, const char *needle) +{ + nm_assert(needle); + + for (; list; list = list->next) { + nm_assert(list->data); + if (nm_streq(list->data, needle)) + return (GSList *) list; + } + return NULL; +} + +/** + * nm_utils_g_slist_strlist_cmp: + * @a: the left #GSList of strings + * @b: the right #GSList of strings to compare. + * + * Compares two string lists. The data elements are compared with + * strcmp(), allowing %NULL elements. + * + * Returns: 0, 1, or -1, depending on how the lists compare. + */ +int +nm_utils_g_slist_strlist_cmp(const GSList *a, const GSList *b) +{ + while (TRUE) { + if (!a) + return !b ? 0 : -1; + if (!b) + return 1; + NM_CMP_DIRECT_STRCMP0(a->data, b->data); + a = a->next; + b = b->next; + } +} + +char * +nm_utils_g_slist_strlist_join(const GSList *a, const char *separator) +{ + GString *str = NULL; + + if (!a) + return NULL; + + for (; a; a = a->next) { + if (!str) + str = g_string_new(NULL); + else + g_string_append(str, separator); + g_string_append(str, a->data); + } + return g_string_free(str, FALSE); +} + +/*****************************************************************************/ + +NMUtilsUserData * +_nm_utils_user_data_pack(int nargs, gconstpointer *args) +{ + int i; + gpointer *data; + + nm_assert(nargs > 0); + nm_assert(args); + + data = g_slice_alloc(((gsize) nargs) * sizeof(gconstpointer)); + for (i = 0; i < nargs; i++) + data[i] = (gpointer) args[i]; + return (NMUtilsUserData *) data; +} + +void +_nm_utils_user_data_unpack(NMUtilsUserData *user_data, int nargs, ...) +{ + gpointer *data = (gpointer *) user_data; + va_list ap; + int i; + + nm_assert(data); + nm_assert(nargs > 0); + + va_start(ap, nargs); + for (i = 0; i < nargs; i++) { + gpointer *dst; + + dst = va_arg(ap, gpointer *); + nm_assert(dst); + + *dst = data[i]; + } + va_end(ap); + + g_slice_free1(((gsize) nargs) * sizeof(gconstpointer), data); +} + +/*****************************************************************************/ + +typedef struct { + gpointer callback_user_data; + GCancellable * cancellable; + GSource * source; + NMUtilsInvokeOnIdleCallback callback; + gulong cancelled_id; +} InvokeOnIdleData; + +static void +_nm_utils_invoke_on_idle_complete(InvokeOnIdleData *data) +{ + nm_clear_g_signal_handler(data->cancellable, &data->cancelled_id); + + data->callback(data->callback_user_data, data->cancellable); + + nm_g_object_unref(data->cancellable); + g_source_destroy(data->source); + nm_g_slice_free(data); +} + +static gboolean +_nm_utils_invoke_on_idle_cb_idle(gpointer user_data) +{ + _nm_utils_invoke_on_idle_complete(user_data); + return G_SOURCE_REMOVE; +} + +static void +_nm_utils_invoke_on_idle_cb_cancelled(GCancellable *cancellable, InvokeOnIdleData *data) +{ + if (data->cancelled_id == 0) { + /* this can only happen during _nm_utils_invoke_on_idle_start(). Don't do anything, + * we still schedule an idle action. */ + return; + } + + /* On cancellation, we invoke the callback synchronously. + * + * Note that this is not thread-safe, meaning: you can only cancel the cancellable + * while not iterating the GMainContext (that has the idle/timeout source attached). + * Making this thread safe would be complicated, and it's simply not used by our + * callers. */ + _nm_utils_invoke_on_idle_complete(data); +} + +static void +_nm_utils_invoke_on_idle_start(gboolean use_timeout, + guint timeout_msec, + GCancellable * cancellable, + NMUtilsInvokeOnIdleCallback callback, + gpointer callback_user_data) +{ + InvokeOnIdleData *data; + GSource * source; + + g_return_if_fail(callback); + + data = g_slice_new(InvokeOnIdleData); + *data = (InvokeOnIdleData){ + .callback = callback, + .callback_user_data = callback_user_data, + .cancellable = nm_g_object_ref(cancellable), + .cancelled_id = 0, + }; + + if (cancellable) { + gulong cancelled_id; + + cancelled_id = g_cancellable_connect(cancellable, + G_CALLBACK(_nm_utils_invoke_on_idle_cb_cancelled), + data, + NULL); + if (cancelled_id == 0) { + /* the cancellable is already cancelled. We still schedule an idle action. */ + use_timeout = FALSE; + } else + data->cancelled_id = cancelled_id; + } + + if (use_timeout) { + source = nm_g_timeout_source_new(timeout_msec, + G_PRIORITY_DEFAULT, + _nm_utils_invoke_on_idle_cb_idle, + data, + NULL); + } else { + source = + nm_g_idle_source_new(G_PRIORITY_DEFAULT, _nm_utils_invoke_on_idle_cb_idle, data, NULL); + } + + /* use the current thread default context. */ + g_source_attach(source, g_main_context_get_thread_default()); + + data->source = source; +} + +void +nm_utils_invoke_on_idle(GCancellable * cancellable, + NMUtilsInvokeOnIdleCallback callback, + gpointer callback_user_data) +{ + _nm_utils_invoke_on_idle_start(FALSE, 0, cancellable, callback, callback_user_data); +} + +void +nm_utils_invoke_on_timeout(guint timeout_msec, + GCancellable * cancellable, + NMUtilsInvokeOnIdleCallback callback, + gpointer callback_user_data) +{ + _nm_utils_invoke_on_idle_start(TRUE, timeout_msec, cancellable, callback, callback_user_data); +} + +/*****************************************************************************/ + +int +nm_utils_getpagesize(void) +{ + static volatile int val = 0; + long l; + int v; + + v = g_atomic_int_get(&val); + + if (G_UNLIKELY(v == 0)) { + l = sysconf(_SC_PAGESIZE); + + g_return_val_if_fail(l > 0 && l < G_MAXINT, 4 * 1024); + + v = (int) l; + if (!g_atomic_int_compare_and_exchange(&val, 0, v)) { + v = g_atomic_int_get(&val); + g_return_val_if_fail(v > 0, 4 * 1024); + } + } + + nm_assert(v > 0); +#if NM_MORE_ASSERTS > 5 + nm_assert(v == getpagesize()); + nm_assert(v == sysconf(_SC_PAGESIZE)); +#endif + + return v; +} + +gboolean +nm_utils_memeqzero(gconstpointer data, gsize length) +{ + const unsigned char *p = data; + int len; + + /* Taken from https://github.com/rustyrussell/ccan/blob/9d2d2c49f053018724bcc6e37029da10b7c3d60d/ccan/mem/mem.c#L92, + * CC-0 licensed. */ + + /* Check first 16 bytes manually */ + for (len = 0; len < 16; len++) { + if (!length) + return TRUE; + if (*p) + return FALSE; + p++; + length--; + } + + /* Now we know that's zero, memcmp with self. */ + return memcmp(data, p, length) == 0; +} + +/** + * nm_utils_bin2hexstr_full: + * @addr: pointer of @length bytes. If @length is zero, this may + * also be %NULL. + * @length: number of bytes in @addr. May also be zero, in which + * case this will return an empty string. + * @delimiter: either '\0', otherwise the output string will have the + * given delimiter character between each two hex numbers. + * @upper_case: if TRUE, use upper case ASCII characters for hex. + * @out: if %NULL, the function will allocate a new buffer of + * either (@length*2+1) or (@length*3) bytes, depending on whether + * a @delimiter is specified. In that case, the allocated buffer will + * be returned and must be freed by the caller. + * If not %NULL, the buffer must already be preallocated and contain + * at least (@length*2+1) or (@length*3) bytes, depending on the delimiter. + * If @length is zero, then of course at least one byte will be allocated + * or @out (if given) must contain at least room for the trailing NUL byte. + * + * Returns: the binary value converted to a hex string. If @out is given, + * this always returns @out. If @out is %NULL, a newly allocated string + * is returned. This never returns %NULL, for buffers of length zero + * an empty string is returned. + */ +char * +nm_utils_bin2hexstr_full(gconstpointer addr, + gsize length, + char delimiter, + gboolean upper_case, + char * out) +{ + const guint8 *in = addr; + const char * LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef"; + char * out0; + + if (out) + out0 = out; + else { + out0 = out = + g_new(char, length == 0 ? 1u : (delimiter == '\0' ? length * 2u + 1u : length * 3u)); + } + + /* @out must contain at least @length*3 bytes if @delimiter is set, + * otherwise, @length*2+1. */ + + if (length > 0) { + nm_assert(in); + for (;;) { + const guint8 v = *in++; + + *out++ = LOOKUP[v >> 4]; + *out++ = LOOKUP[v & 0x0F]; + length--; + if (!length) + break; + if (delimiter) + *out++ = delimiter; + } + } + + *out = '\0'; + return out0; +} + +guint8 * +nm_utils_hexstr2bin_full(const char *hexstr, + gboolean allow_0x_prefix, + gboolean delimiter_required, + gboolean hexdigit_pairs_required, + const char *delimiter_candidates, + gsize required_len, + guint8 * buffer, + gsize buffer_len, + gsize * out_len) +{ + const char *in = hexstr; + guint8 * out = buffer; + gboolean delimiter_has = TRUE; + guint8 delimiter = '\0'; + gsize len; + + nm_assert(hexstr); + nm_assert(buffer); + nm_assert(required_len > 0 || out_len); + + if (allow_0x_prefix && in[0] == '0' && in[1] == 'x') + in += 2; + + while (TRUE) { + const guint8 d1 = in[0]; + guint8 d2; + int i1, i2; + + i1 = nm_utils_hexchar_to_int(d1); + if (i1 < 0) + goto fail; + + /* If there's no leading zero (ie "aa:b:cc") then fake it */ + d2 = in[1]; + if (d2 && (i2 = nm_utils_hexchar_to_int(d2)) >= 0) { + *out++ = (i1 << 4) + i2; + d2 = in[2]; + if (!d2) + break; + in += 2; + } else { + /* Fake leading zero */ + *out++ = i1; + if (!d2) { + if (!delimiter_has || hexdigit_pairs_required) { + /* when using no delimiter, there must be pairs of hex chars */ + goto fail; + } + break; + } else if (hexdigit_pairs_required) + goto fail; + in += 1; + } + + if (--buffer_len == 0) + goto fail; + + if (delimiter_has) { + if (d2 != delimiter) { + if (delimiter) + goto fail; + if (delimiter_candidates) { + while (delimiter_candidates[0]) { + if (delimiter_candidates++[0] == d2) + delimiter = d2; + } + } + if (!delimiter) { + if (delimiter_required) + goto fail; + delimiter_has = FALSE; + continue; + } + } + in++; + } + } + + len = out - buffer; + if (required_len == 0 || len == required_len) { + NM_SET_OUT(out_len, len); + return buffer; + } + +fail: + NM_SET_OUT(out_len, 0); + return NULL; +} + +guint8 * +nm_utils_hexstr2bin_alloc(const char *hexstr, + gboolean allow_0x_prefix, + gboolean delimiter_required, + const char *delimiter_candidates, + gsize required_len, + gsize * out_len) +{ + guint8 *buffer; + gsize buffer_len, len; + + if (G_UNLIKELY(!hexstr)) { + NM_SET_OUT(out_len, 0); + g_return_val_if_fail(hexstr, NULL); + } + + nm_assert(required_len > 0 || out_len); + + if (allow_0x_prefix && hexstr[0] == '0' && hexstr[1] == 'x') + hexstr += 2; + + if (!hexstr[0]) + goto fail; + + if (required_len > 0) + buffer_len = required_len; + else + buffer_len = strlen(hexstr) / 2 + 3; + + buffer = g_malloc(buffer_len); + + if (nm_utils_hexstr2bin_full(hexstr, + FALSE, + delimiter_required, + FALSE, + delimiter_candidates, + required_len, + buffer, + buffer_len, + &len)) { + NM_SET_OUT(out_len, len); + return buffer; + } + + g_free(buffer); + +fail: + NM_SET_OUT(out_len, 0); + return NULL; +} + +/*****************************************************************************/ + +GVariant * +nm_utils_gvariant_vardict_filter(GVariant *src, + gboolean (*filter_fcn)(const char *key, + GVariant * val, + char ** out_key, + GVariant ** out_val, + gpointer user_data), + gpointer user_data) +{ + GVariantIter iter; + GVariantBuilder builder; + const char * key; + GVariant * val; + + g_return_val_if_fail(src && g_variant_is_of_type(src, G_VARIANT_TYPE_VARDICT), NULL); + g_return_val_if_fail(filter_fcn, NULL); + + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + + g_variant_iter_init(&iter, src); + while (g_variant_iter_next(&iter, "{&sv}", &key, &val)) { + _nm_unused gs_unref_variant GVariant *val_free = val; + gs_free char * key2 = NULL; + gs_unref_variant GVariant *val2 = NULL; + + if (filter_fcn(key, val, &key2, &val2, user_data)) { + g_variant_builder_add(&builder, "{sv}", key2 ?: key, val2 ?: val); + } + } + + return g_variant_builder_end(&builder); +} + +static gboolean +_gvariant_vardict_filter_drop_one(const char *key, + GVariant * val, + char ** out_key, + GVariant ** out_val, + gpointer user_data) +{ + return !nm_streq(key, user_data); +} + +GVariant * +nm_utils_gvariant_vardict_filter_drop_one(GVariant *src, const char *key) +{ + return nm_utils_gvariant_vardict_filter(src, _gvariant_vardict_filter_drop_one, (gpointer) key); +} + +/*****************************************************************************/ + +static gboolean +debug_key_matches(const char *key, const char *token, guint length) +{ + /* may not call GLib functions: see note in g_parse_debug_string() */ + for (; length; length--, key++, token++) { + char k = (*key == '_') ? '-' : g_ascii_tolower(*key); + char t = (*token == '_') ? '-' : g_ascii_tolower(*token); + + if (k != t) + return FALSE; + } + + return *key == '\0'; +} + +/** + * nm_utils_parse_debug_string: + * @string: the string to parse + * @keys: the debug keys + * @nkeys: number of entries in @keys + * + * Similar to g_parse_debug_string(), but does not special + * case "help" or "all". + * + * Returns: the flags + */ +guint +nm_utils_parse_debug_string(const char *string, const GDebugKey *keys, guint nkeys) +{ + guint i; + guint result = 0; + const char *q; + + if (string == NULL) + return 0; + + while (*string) { + q = strpbrk(string, ":;, \t"); + if (!q) + q = string + strlen(string); + + for (i = 0; i < nkeys; i++) { + if (debug_key_matches(keys[i].key, string, q - string)) + result |= keys[i].value; + } + + string = q; + if (*string) + string++; + } + + return result; +} + +/*****************************************************************************/ + +GSource * +nm_g_idle_source_new(int priority, + GSourceFunc func, + gpointer user_data, + GDestroyNotify destroy_notify) +{ + GSource *source; + + source = g_idle_source_new(); + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority(source, priority); + g_source_set_callback(source, func, user_data, destroy_notify); + return source; +} + +GSource * +nm_g_timeout_source_new(guint timeout_msec, + int priority, + GSourceFunc func, + gpointer user_data, + GDestroyNotify destroy_notify) +{ + GSource *source; + + source = g_timeout_source_new(timeout_msec); + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority(source, priority); + g_source_set_callback(source, func, user_data, destroy_notify); + return source; +} + +GSource * +nm_g_timeout_source_new_seconds(guint timeout_sec, + int priority, + GSourceFunc func, + gpointer user_data, + GDestroyNotify destroy_notify) +{ + GSource *source; + + source = g_timeout_source_new_seconds(timeout_sec); + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority(source, priority); + g_source_set_callback(source, func, user_data, destroy_notify); + return source; +} + +GSource * +nm_g_unix_signal_source_new(int signum, + int priority, + GSourceFunc handler, + gpointer user_data, + GDestroyNotify notify) +{ + GSource *source; + + source = g_unix_signal_source_new(signum); + + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority(source, priority); + g_source_set_callback(source, handler, user_data, notify); + return source; +} + +GSource * +nm_g_unix_fd_source_new(int fd, + GIOCondition io_condition, + int priority, + gboolean (*source_func)(int fd, GIOCondition condition, gpointer user_data), + gpointer user_data, + GDestroyNotify destroy_notify) +{ + GSource *source; + + source = g_unix_fd_source_new(fd, io_condition); + + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority(source, priority); + g_source_set_callback(source, G_SOURCE_FUNC(source_func), user_data, destroy_notify); + return source; +} + +/*****************************************************************************/ + +#define _CTX_LOG(fmt, ...) \ + G_STMT_START \ + { \ + if (FALSE) { \ + gint64 _ts = g_get_monotonic_time() / 100; \ + \ + g_printerr(">>>> [%" G_GINT64_FORMAT ".%05" G_GINT64_FORMAT "] [src:%p]: " fmt "\n", \ + _ts / 10000, \ + _ts % 10000, \ + (ctx_src), \ + ##__VA_ARGS__); \ + } \ + } \ + G_STMT_END + +typedef struct { + int fd; + guint events; + guint registered_events; + union { + int one; + int *many; + } idx; + gpointer tag; + bool stale : 1; + bool has_many_idx : 1; +} PollData; + +typedef struct { + GSource source; + GMainContext *context; + GHashTable * fds; + GPollFD * fds_arr; + guint fds_len; + int max_priority; + bool acquired : 1; +} CtxIntegSource; + +static void +_poll_data_free(gpointer user_data) +{ + PollData *poll_data = user_data; + + if (poll_data->has_many_idx) + g_free(poll_data->idx.many); + nm_g_slice_free(poll_data); +} + +static void +_ctx_integ_source_reacquire(CtxIntegSource *ctx_src) +{ + if (G_LIKELY(ctx_src->acquired && g_main_context_is_owner(ctx_src->context))) + return; + + /* the parent context now iterates on a different thread. + * We need to release and reacquire the inner context. */ + + if (ctx_src->acquired) + g_main_context_release(ctx_src->context); + + if (G_UNLIKELY(!g_main_context_acquire(ctx_src->context))) { + /* Nobody is supposed to reacquire the context while we use it. This is a bug + * of the user. */ + ctx_src->acquired = FALSE; + g_return_if_reached(); + } + ctx_src->acquired = TRUE; +} + +static gboolean +_ctx_integ_source_prepare(GSource *source, int *out_timeout) +{ + CtxIntegSource *ctx_src = ((CtxIntegSource *) source); + int max_priority; + int timeout = -1; + gboolean any_ready; + GHashTableIter h_iter; + PollData * poll_data; + gboolean fds_changed; + GPollFD new_fds_stack[300u / sizeof(GPollFD)]; + gs_free GPollFD *new_fds_heap = NULL; + GPollFD * new_fds; + guint new_fds_len; + guint new_fds_alloc; + guint i; + + _CTX_LOG("prepare..."); + + _ctx_integ_source_reacquire(ctx_src); + + any_ready = g_main_context_prepare(ctx_src->context, &max_priority); + + new_fds_alloc = NM_MAX(G_N_ELEMENTS(new_fds_stack), ctx_src->fds_len); + + if (new_fds_alloc > G_N_ELEMENTS(new_fds_stack)) { + new_fds_heap = g_new(GPollFD, new_fds_alloc); + new_fds = new_fds_heap; + } else + new_fds = new_fds_stack; + + for (;;) { + int l; + + nm_assert(new_fds_alloc <= (guint) G_MAXINT); + + l = g_main_context_query(ctx_src->context, + max_priority, + &timeout, + new_fds, + (int) new_fds_alloc); + nm_assert(l >= 0); + + new_fds_len = (guint) l; + + if (G_LIKELY(new_fds_len <= new_fds_alloc)) + break; + + new_fds_alloc = new_fds_len; + g_free(new_fds_heap); + new_fds_heap = g_new(GPollFD, new_fds_alloc); + new_fds = new_fds_heap; + } + + fds_changed = FALSE; + if (new_fds_len != ctx_src->fds_len) + fds_changed = TRUE; + else { + for (i = 0; i < new_fds_len; i++) { + if (new_fds[i].fd != ctx_src->fds_arr[i].fd + || new_fds[i].events != ctx_src->fds_arr[i].events) { + fds_changed = TRUE; + break; + } + } + } + + if (G_UNLIKELY(fds_changed)) { + g_free(ctx_src->fds_arr); + ctx_src->fds_len = new_fds_len; + if (G_LIKELY(new_fds == new_fds_stack) || new_fds_alloc != new_fds_len) + ctx_src->fds_arr = nm_memdup(new_fds, sizeof(*new_fds) * new_fds_len); + else + ctx_src->fds_arr = g_steal_pointer(&new_fds_heap); + + g_hash_table_iter_init(&h_iter, ctx_src->fds); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &poll_data, NULL)) + poll_data->stale = TRUE; + + for (i = 0; i < ctx_src->fds_len; i++) { + const GPollFD *fd = &ctx_src->fds_arr[i]; + + poll_data = g_hash_table_lookup(ctx_src->fds, &fd->fd); + + if (G_UNLIKELY(!poll_data)) { + poll_data = g_slice_new(PollData); + *poll_data = (PollData){ + .fd = fd->fd, + .idx.one = i, + .has_many_idx = FALSE, + .events = fd->events, + .registered_events = 0, + .tag = NULL, + .stale = FALSE, + }; + g_hash_table_add(ctx_src->fds, poll_data); + nm_assert(poll_data == g_hash_table_lookup(ctx_src->fds, &fd->fd)); + continue; + } + + if (G_LIKELY(poll_data->stale)) { + if (poll_data->has_many_idx) { + g_free(poll_data->idx.many); + poll_data->has_many_idx = FALSE; + } + poll_data->events = fd->events; + poll_data->idx.one = i; + poll_data->stale = FALSE; + continue; + } + + /* How odd. We have duplicate FDs. In fact, currently g_main_context_query() always + * coalesces the FDs and this cannot happen. However, that is not documented behavior, + * so we should not rely on that. So we need to keep a list of indexes... */ + poll_data->events |= fd->events; + if (!poll_data->has_many_idx) { + int idx0; + + idx0 = poll_data->idx.one; + poll_data->has_many_idx = TRUE; + poll_data->idx.many = g_new(int, 4); + poll_data->idx.many[0] = 2; /* number allocated */ + poll_data->idx.many[1] = 2; /* number used */ + poll_data->idx.many[2] = idx0; + poll_data->idx.many[3] = i; + } else { + if (poll_data->idx.many[0] == poll_data->idx.many[1]) { + poll_data->idx.many[0] *= 2; + poll_data->idx.many = + g_realloc(poll_data->idx.many, sizeof(int) * (2 + poll_data->idx.many[0])); + } + poll_data->idx.many[2 + poll_data->idx.many[1]] = i; + poll_data->idx.many[1]++; + } + } + + g_hash_table_iter_init(&h_iter, ctx_src->fds); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &poll_data, NULL)) { + if (poll_data->stale) { + nm_assert(poll_data->tag); + nm_assert(poll_data->events == poll_data->registered_events); + _CTX_LOG("prepare: remove poll fd=%d, events=0x%x", + poll_data->fd, + poll_data->events); + g_source_remove_unix_fd(&ctx_src->source, poll_data->tag); + g_hash_table_iter_remove(&h_iter); + continue; + } + if (!poll_data->tag) { + _CTX_LOG("prepare: add poll fd=%d, events=0x%x", poll_data->fd, poll_data->events); + poll_data->registered_events = poll_data->events; + poll_data->tag = g_source_add_unix_fd(&ctx_src->source, + poll_data->fd, + poll_data->registered_events); + continue; + } + if (poll_data->registered_events != poll_data->events) { + _CTX_LOG("prepare: update poll fd=%d, events=0x%x", + poll_data->fd, + poll_data->events); + poll_data->registered_events = poll_data->events; + g_source_modify_unix_fd(&ctx_src->source, + poll_data->tag, + poll_data->registered_events); + } + } + } + + NM_SET_OUT(out_timeout, timeout); + ctx_src->max_priority = max_priority; + + _CTX_LOG("prepare: done, any-ready=%d, timeout=%d, max-priority=%d", + any_ready, + timeout, + max_priority); + + /* we always need to poll, because we have some file descriptors. */ + return FALSE; +} + +static gboolean +_ctx_integ_source_check(GSource *source) +{ + CtxIntegSource *ctx_src = ((CtxIntegSource *) source); + GHashTableIter h_iter; + gboolean some_ready; + PollData * poll_data; + + nm_assert(ctx_src->context); + + _CTX_LOG("check"); + + _ctx_integ_source_reacquire(ctx_src); + + g_hash_table_iter_init(&h_iter, ctx_src->fds); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &poll_data, NULL)) { + guint revents; + + revents = g_source_query_unix_fd(&ctx_src->source, poll_data->tag); + if (G_UNLIKELY(poll_data->has_many_idx)) { + int num = poll_data->idx.many[1]; + int *p_idx = &poll_data->idx.many[2]; + + for (; num > 0; num--, p_idx++) + ctx_src->fds_arr[*p_idx].revents = revents; + } else + ctx_src->fds_arr[poll_data->idx.one].revents = revents; + } + + nm_assert(ctx_src->fds_len <= (guint) G_MAXINT); + + some_ready = g_main_context_check(ctx_src->context, + ctx_src->max_priority, + ctx_src->fds_arr, + (int) ctx_src->fds_len); + + _CTX_LOG("check (some-ready=%d)...", some_ready); + + return some_ready; +} + +static gboolean +_ctx_integ_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) +{ + CtxIntegSource *ctx_src = ((CtxIntegSource *) source); + + nm_assert(ctx_src->context); + + _ctx_integ_source_reacquire(ctx_src); + + _CTX_LOG("dispatch"); + + g_main_context_dispatch(ctx_src->context); + + return G_SOURCE_CONTINUE; +} + +static void +_ctx_integ_source_finalize(GSource *source) +{ + CtxIntegSource *ctx_src = ((CtxIntegSource *) source); + GHashTableIter h_iter; + PollData * poll_data; + + g_return_if_fail(ctx_src->context); + + _CTX_LOG("finalize..."); + + g_hash_table_iter_init(&h_iter, ctx_src->fds); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &poll_data, NULL)) { + nm_assert(poll_data->tag); + _CTX_LOG("prepare: remove poll fd=%d, events=0x%x", poll_data->fd, poll_data->events); + g_source_remove_unix_fd(&ctx_src->source, poll_data->tag); + g_hash_table_iter_remove(&h_iter); + } + + nm_clear_pointer(&ctx_src->fds, g_hash_table_unref); + nm_clear_g_free(&ctx_src->fds_arr); + ctx_src->fds_len = 0; + + if (ctx_src->acquired) { + ctx_src->acquired = FALSE; + g_main_context_release(ctx_src->context); + } + + nm_clear_pointer(&ctx_src->context, g_main_context_unref); +} + +static GSourceFuncs ctx_integ_source_funcs = { + .prepare = _ctx_integ_source_prepare, + .check = _ctx_integ_source_check, + .dispatch = _ctx_integ_source_dispatch, + .finalize = _ctx_integ_source_finalize, +}; + +/** + * nm_utils_g_main_context_create_integrate_source: + * @inner_context: the inner context that will be integrated to an + * outer #GMainContext. + * + * By integrating the inner context with an outer context, when iterating the outer + * context sources on the inner context will be dispatched. Note that while the + * created source exists, the @inner_context will be acquired. The user gets restricted + * what to do with the inner context. In particular while the inner context is integrated, + * the user should not acquire the inner context again or explicitly iterate it. What + * the user of course still can (and wants to) do is attaching new sources to the inner + * context. + * + * Note that GSource has a priority. While each context dispatches events based on + * their source's priorities, the outer context dispatches to the inner context + * only with one priority (the priority of the created source). That is, the sources + * from the two contexts are kept separate and are not sorted by their priorities. + * + * Returns: a newly created GSource that should be attached to the + * outer context. + */ +GSource * +nm_utils_g_main_context_create_integrate_source(GMainContext *inner_context) +{ + CtxIntegSource *ctx_src; + + g_return_val_if_fail(inner_context, NULL); + + if (!g_main_context_acquire(inner_context)) { + /* We require to acquire the context while it's integrated. We need to keep it acquired + * for the entire duration. + * + * This is also necessary because g_source_attach() only wakes up the context, if + * the context is currently acquired. */ + g_return_val_if_reached(NULL); + } + + ctx_src = (CtxIntegSource *) g_source_new(&ctx_integ_source_funcs, sizeof(CtxIntegSource)); + + g_source_set_name(&ctx_src->source, "ContextIntegrateSource"); + + ctx_src->context = g_main_context_ref(inner_context); + ctx_src->fds = g_hash_table_new_full(nm_pint_hash, nm_pint_equals, _poll_data_free, NULL); + ctx_src->fds_len = 0; + ctx_src->fds_arr = NULL; + ctx_src->acquired = TRUE; + ctx_src->max_priority = G_MAXINT; + + _CTX_LOG("create new integ-source for %p", inner_context); + + return &ctx_src->source; +} + +/*****************************************************************************/ + +void +nm_utils_ifname_cpy(char *dst, const char *name) +{ + int i; + + g_return_if_fail(dst); + g_return_if_fail(name && name[0]); + + nm_assert(nm_utils_ifname_valid_kernel(name, NULL)); + + /* ensures NUL padding of the entire IFNAMSIZ buffer. */ + + for (i = 0; i < (int) IFNAMSIZ && name[i] != '\0'; i++) + dst[i] = name[i]; + + nm_assert(name[i] == '\0'); + + for (; i < (int) IFNAMSIZ; i++) + dst[i] = '\0'; +} + +/*****************************************************************************/ + +gboolean +nm_utils_ifname_valid_kernel(const char *name, GError **error) +{ + int i; + + /* This function follows kernel's interface validation + * function dev_valid_name() in net/core/dev.c. + */ + + if (!name) { + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("interface name is missing")); + return FALSE; + } + + if (name[0] == '\0') { + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("interface name is too short")); + return FALSE; + } + + if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) { + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("interface name is reserved")); + return FALSE; + } + + for (i = 0; i < IFNAMSIZ; i++) { + char ch = name[i]; + + if (ch == '\0') + return TRUE; + if (NM_IN_SET(ch, '/', ':') || g_ascii_isspace(ch)) { + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("interface name contains an invalid character")); + return FALSE; + } + } + + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("interface name is longer than 15 characters")); + return FALSE; +} + +/*****************************************************************************/ + +static gboolean +_nm_utils_ifname_valid_kernel(const char *name, GError **error) +{ + if (!nm_utils_ifname_valid_kernel(name, error)) + return FALSE; + + if (strchr(name, '%')) { + /* Kernel's dev_valid_name() accepts (almost) any binary up to 15 chars. + * However, '%' is treated special as a format specifier. Try + * + * ip link add 'dummy%dx' type dummy + * + * Don't allow that for "connection.interface-name", which either + * matches an existing netdev name (thus, it cannot have a '%') or + * is used to configure a name (in which case we don't want kernel + * to replace the format specifier). */ + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("'%%' is not allowed in interface names")); + return FALSE; + } + + if (NM_IN_STRSET(name, "all", "default", "bonding_masters")) { + /* Certain names are not allowed. The "all" and "default" names are reserved + * due to their directories in "/proc/sys/net/ipv4/conf/" and "/proc/sys/net/ipv6/conf/". + * + * Also, there is "/sys/class/net/bonding_masters" file. + */ + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("'%s' is not allowed as interface name"), + name); + return FALSE; + } + + return TRUE; +} + +static gboolean +_nm_utils_ifname_valid_ovs(const char *name, GError **error) +{ + const char *ch; + + /* OVS actually accepts a wider range of chars (all printable UTF-8 chars), + * NetworkManager restricts this to ASCII char as it's a safer option for + * now since OVS is not well documented on this matter. + **/ + for (ch = name; *ch; ++ch) { + if (*ch == '\\' || *ch == '/' || !g_ascii_isgraph(*ch)) { + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("interface name must be alphanumerical with " + "no forward or backward slashes")); + return FALSE; + } + }; + return TRUE; +} + +gboolean +nm_utils_ifname_valid(const char *name, NMUtilsIfaceType type, GError **error) +{ + g_return_val_if_fail(!error || !(*error), FALSE); + + if (!name || !(name[0])) { + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("interface name must not be empty")); + return FALSE; + } + + if (!g_utf8_validate(name, -1, NULL)) { + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("interface name must be UTF-8 encoded")); + return FALSE; + } + + switch (type) { + case NMU_IFACE_KERNEL: + return _nm_utils_ifname_valid_kernel(name, error); + case NMU_IFACE_OVS: + return _nm_utils_ifname_valid_ovs(name, error); + case NMU_IFACE_OVS_AND_KERNEL: + return _nm_utils_ifname_valid_kernel(name, error) + && _nm_utils_ifname_valid_ovs(name, error); + case NMU_IFACE_ANY: + { + gs_free_error GError *local = NULL; + + if (_nm_utils_ifname_valid_kernel(name, error ? &local : NULL)) + return TRUE; + if (_nm_utils_ifname_valid_ovs(name, NULL)) + return TRUE; + if (error) + g_propagate_error(error, g_steal_pointer(&local)); + return FALSE; + } + } + + g_return_val_if_reached(FALSE); +} + +/*****************************************************************************/ + +void +_nm_str_buf_ensure_size(NMStrBuf *strbuf, gsize new_size, gboolean reserve_exact) +{ + _nm_str_buf_assert(strbuf); + + /* Currently, this only supports strictly growing the buffer. */ + nm_assert(new_size > strbuf->_priv_allocated); + + if (!reserve_exact) { + new_size = nm_utils_get_next_realloc_size(!strbuf->_priv_do_bzero_mem, new_size); + } + + strbuf->_priv_str = nm_secret_mem_realloc(strbuf->_priv_str, + strbuf->_priv_do_bzero_mem, + strbuf->_priv_allocated, + new_size); + strbuf->_priv_allocated = new_size; +} + +void +nm_str_buf_append_printf(NMStrBuf *strbuf, const char *format, ...) +{ + va_list args; + gsize available; + int l; + + _nm_str_buf_assert(strbuf); + + available = strbuf->_priv_allocated - strbuf->_priv_len; + + nm_assert(available < G_MAXULONG); + + va_start(args, format); + l = g_vsnprintf(&strbuf->_priv_str[strbuf->_priv_len], available, format, args); + va_end(args); + + nm_assert(l >= 0); + nm_assert(l < G_MAXINT); + + if ((gsize) l >= available) { + gsize l2; + + if (l == 0) + return; + + l2 = ((gsize) l) + 1u; + + nm_str_buf_maybe_expand(strbuf, l2, FALSE); + + va_start(args, format); + l = g_vsnprintf(&strbuf->_priv_str[strbuf->_priv_len], l2, format, args); + va_end(args); + + nm_assert(l >= 0); + nm_assert((gsize) l == l2 - 1u); + } + + strbuf->_priv_len += (gsize) l; +} + +/*****************************************************************************/ + +/** + * nm_indirect_g_free: + * @arg: a pointer to a pointer that is to be freed. + * + * This does the same as nm_clear_g_free(arg) (g_clear_pointer (arg, g_free)). + * This is for example useful when you have a GArray with pointers and a + * clear function to free them. g_array_set_clear_func()'s destroy notify + * function gets a pointer to the array location, so we have to follow + * the first pointer. + */ +void +nm_indirect_g_free(gpointer arg) +{ + gpointer *p = arg; + + nm_clear_g_free(p); +} + +/*****************************************************************************/ + +static char * +attribute_escape(const char *src, char c1, char c2) +{ + char *ret, *dest; + + dest = ret = g_malloc(strlen(src) * 2 + 1); + + while (*src) { + if (*src == c1 || *src == c2 || *src == '\\') + *dest++ = '\\'; + *dest++ = *src++; + } + *dest++ = '\0'; + + return ret; +} + +void +_nm_utils_format_variant_attributes_full(GString * str, + const NMUtilsNamedValue * values, + guint num_values, + const NMVariantAttributeSpec *const *spec, + char attr_separator, + char key_value_separator) +{ + const NMVariantAttributeSpec *const *s; + const char * name, *value; + GVariant * variant; + char * escaped; + char buf[64]; + char sep = 0; + guint i; + + for (i = 0; i < num_values; i++) { + name = values[i].name; + variant = values[i].value_ptr; + value = NULL; + s = NULL; + + if (spec) { + for (s = spec; *s; s++) { + if (nm_streq0((*s)->name, name)) + break; + } + + if (!*s) + continue; + } + + if (g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32)) + value = nm_sprintf_buf(buf, "%u", g_variant_get_uint32(variant)); + else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_INT32)) + value = nm_sprintf_buf(buf, "%d", (int) g_variant_get_int32(variant)); + else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT64)) + value = nm_sprintf_buf(buf, "%" G_GUINT64_FORMAT, g_variant_get_uint64(variant)); + else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_BYTE)) + value = nm_sprintf_buf(buf, "%hhu", g_variant_get_byte(variant)); + else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)) + value = g_variant_get_boolean(variant) ? "true" : "false"; + else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) + value = g_variant_get_string(variant, NULL); + else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_BYTESTRING)) { + /* FIXME: there is no guarantee that the byte array + * is valid UTF-8.*/ + value = g_variant_get_bytestring(variant); + } else + continue; + + if (sep) + g_string_append_c(str, sep); + + escaped = attribute_escape(name, attr_separator, key_value_separator); + g_string_append(str, escaped); + g_free(escaped); + + if (!s || !*s || !(*s)->no_value) { + g_string_append_c(str, key_value_separator); + + escaped = attribute_escape(value, attr_separator, key_value_separator); + g_string_append(str, escaped); + g_free(escaped); + } + + sep = attr_separator; + } +} + +char * +_nm_utils_format_variant_attributes(GHashTable * attributes, + const NMVariantAttributeSpec *const *spec, + char attr_separator, + char key_value_separator) +{ + gs_free NMUtilsNamedValue *values_free = NULL; + NMUtilsNamedValue values_prepared[20]; + const NMUtilsNamedValue * values; + GString * str = NULL; + guint len; + + g_return_val_if_fail(attr_separator, NULL); + g_return_val_if_fail(key_value_separator, NULL); + + if (!attributes) + return NULL; + + values = nm_utils_named_values_from_strdict(attributes, &len, values_prepared, &values_free); + if (len == 0) + return NULL; + + str = g_string_new(""); + _nm_utils_format_variant_attributes_full(str, + values, + len, + spec, + attr_separator, + key_value_separator); + return g_string_free(str, FALSE); +} + +/*****************************************************************************/ + +gboolean +nm_utils_is_localhost(const char *name) +{ + static const char *const NAMES[] = { + "localhost", + "localhost4", + "localhost6", + "localhost.localdomain", + "localhost4.localdomain4", + "localhost6.localdomain6", + }; + gsize name_len; + int i; + + if (!name) + return FALSE; + + /* This tries to identify local host and domain names + * described in RFC6761 plus the redhatism of localdomain. + * + * Similar to systemd's is_localhost(). */ + + name_len = strlen(name); + + if (name_len == 0) + return FALSE; + + if (name[name_len - 1] == '.') { + /* one trailing dot is fine. Hide it. */ + name_len--; + } + + for (i = 0; i < (int) G_N_ELEMENTS(NAMES); i++) { + const char *n = NAMES[i]; + gsize l = strlen(n); + gsize s; + + if (name_len < l) + continue; + + s = name_len - l; + + if (g_ascii_strncasecmp(&name[s], n, l) != 0) + continue; + + /* we accept the name if it is equal to one of the well-known names, + * or if it is some prefix, a '.' and the well-known name. */ + if (s == 0) + return TRUE; + if (name[s - 1] == '.') + return TRUE; + } + + return FALSE; +} + +gboolean +nm_utils_is_specific_hostname(const char *name) +{ + if (nm_str_is_empty(name)) + return FALSE; + + if (nm_streq(name, "(none)")) { + /* This is not a special hostname. Probably an artefact by somebody wrongly + * printing NULL. */ + return FALSE; + } + + if (nm_utils_is_localhost(name)) + return FALSE; + + /* FIXME: properly validate the hostname, like systemd's hostname_is_valid() */ + + return TRUE; +} + +/*****************************************************************************/ + +/* taken from systemd's uid_to_name(). */ +char * +nm_utils_uid_to_name(uid_t uid) +{ + gs_free char *buf_heap = NULL; + char buf_stack[4096]; + gsize bufsize; + char * buf; + + bufsize = sizeof(buf_stack); + buf = buf_stack; + + for (;;) { + struct passwd pwbuf; + struct passwd *pw = NULL; + int r; + + r = getpwuid_r(uid, &pwbuf, buf, bufsize, &pw); + if (r == 0 && pw) + return nm_strdup_not_empty(pw->pw_name); + + if (r != ERANGE) + return NULL; + + if (bufsize > G_MAXSIZE / 2u) + return NULL; + + bufsize *= 2u; + g_free(buf_heap); + buf_heap = g_malloc(bufsize); + buf = buf_heap; + } +} + +/* taken from systemd's nss_user_record_by_name() */ +gboolean +nm_utils_name_to_uid(const char *name, uid_t *out_uid) +{ + gs_free char *buf_heap = NULL; + char buf_stack[4096]; + gsize bufsize; + char * buf; + + if (!name) + return nm_assert_unreachable_val(FALSE); + + bufsize = sizeof(buf_stack); + buf = buf_stack; + + for (;;) { + struct passwd *result; + struct passwd pwd; + int r; + + r = getpwnam_r(name, &pwd, buf, bufsize, &result); + if (r == 0) { + if (!result) + return FALSE; + NM_SET_OUT(out_uid, pwd.pw_uid); + return TRUE; + } + + if (r != ERANGE) + return FALSE; + + if (bufsize > G_MAXSIZE / 2u) + return FALSE; + + bufsize *= 2u; + g_free(buf_heap); + buf_heap = g_malloc(bufsize); + buf = buf_heap; + } +} + +/*****************************************************************************/ + +static double +_exp10(guint16 ex) +{ + double v; + + if (ex == 0) + return 1.0; + + v = _exp10(ex / 2); + v = v * v; + if (ex % 2) + v *= 10; + return v; +} + +/* + * nm_utils_exp10: + * @ex: the exponent + * + * Returns: 10^ex, or pow(10, ex), or exp10(ex). + */ +double +nm_utils_exp10(gint16 ex) +{ + if (ex >= 0) + return _exp10(ex); + return 1.0 / _exp10(-((gint32) ex)); +} + +/*****************************************************************************/ + +gboolean +_nm_utils_is_empty_ssid_arr(const guint8 *ssid, gsize len) +{ + /* Single white space is for Linksys APs */ + if (len == 1 && ssid[0] == ' ') + return TRUE; + + /* Otherwise, if the entire ssid is 0, we assume it is hidden */ + while (len--) { + if (ssid[len] != '\0') + return FALSE; + } + return TRUE; +} + +gboolean +_nm_utils_is_empty_ssid_gbytes(GBytes *ssid) +{ + const guint8 *p; + gsize l; + + g_return_val_if_fail(ssid, FALSE); + + p = g_bytes_get_data(ssid, &l); + return _nm_utils_is_empty_ssid_arr(p, l); +} + +char * +_nm_utils_ssid_to_string_arr(const guint8 *ssid, gsize len) +{ + gs_free char *s_copy = NULL; + const char * s_cnst; + + if (len == 0) + return g_strdup("(empty)"); + + s_cnst = + nm_utils_buf_utf8safe_escape(ssid, len, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &s_copy); + nm_assert(s_cnst); + + if (_nm_utils_is_empty_ssid_arr(ssid, len)) + return g_strdup_printf("\"%s\" (hidden)", s_cnst); + + return g_strdup_printf("\"%s\"", s_cnst); +} + +char * +_nm_utils_ssid_to_string_gbytes(GBytes *ssid) +{ + gconstpointer p; + gsize l; + + if (!ssid) + return g_strdup("(none)"); + + p = g_bytes_get_data(ssid, &l); + return _nm_utils_ssid_to_string_arr(p, l); +} + +/*****************************************************************************/ + +gconstpointer +nm_utils_ipx_address_clear_host_address(int family, gpointer dst, gconstpointer src, guint8 plen) +{ + g_return_val_if_fail(dst, NULL); + + switch (family) { + case AF_INET: + g_return_val_if_fail(plen <= 32, NULL); + + if (!src) { + /* allow "self-assignment", by specifying %NULL as source. */ + src = dst; + } + + *((guint32 *) dst) = nm_utils_ip4_address_clear_host_address(*((guint32 *) src), plen); + break; + case AF_INET6: + nm_utils_ip6_address_clear_host_address(dst, src, plen); + break; + default: + g_return_val_if_reached(NULL); + } + return dst; +} + +/* nm_utils_ip4_address_clear_host_address: + * @addr: source ip6 address + * @plen: prefix length of network + * + * returns: the input address, with the host address set to 0. + */ +in_addr_t +nm_utils_ip4_address_clear_host_address(in_addr_t addr, guint8 plen) +{ + return addr & _nm_utils_ip4_prefix_to_netmask(plen); +} + +/* nm_utils_ip6_address_clear_host_address: + * @dst: destination output buffer, will contain the network part of the @src address + * @src: source ip6 address + * @plen: prefix length of network + * + * Note: this function is self assignment safe, to update @src inplace, set both + * @dst and @src to the same destination or set @src NULL. + */ +const struct in6_addr * +nm_utils_ip6_address_clear_host_address(struct in6_addr * dst, + const struct in6_addr *src, + guint8 plen) +{ + g_return_val_if_fail(plen <= 128, NULL); + g_return_val_if_fail(dst, NULL); + + if (!src) + src = dst; + + if (plen < 128) { + guint nbytes = plen / 8; + guint nbits = plen % 8; + + if (nbytes && dst != src) + memcpy(dst, src, nbytes); + if (nbits) { + dst->s6_addr[nbytes] = (src->s6_addr[nbytes] & (0xFF << (8 - nbits))); + nbytes++; + } + if (nbytes <= 15) + memset(&dst->s6_addr[nbytes], 0, 16 - nbytes); + } else if (src != dst) + *dst = *src; + + return dst; +} + +int +nm_utils_ip6_address_same_prefix_cmp(const struct in6_addr *addr_a, + const struct in6_addr *addr_b, + guint8 plen) +{ + int nbytes; + guint8 va, vb, m; + + if (plen >= 128) + NM_CMP_DIRECT_MEMCMP(addr_a, addr_b, sizeof(struct in6_addr)); + else { + nbytes = plen / 8; + if (nbytes) + NM_CMP_DIRECT_MEMCMP(addr_a, addr_b, nbytes); + + plen = plen % 8; + if (plen != 0) { + m = ~((1 << (8 - plen)) - 1); + va = ((((const guint8 *) addr_a))[nbytes]) & m; + vb = ((((const guint8 *) addr_b))[nbytes]) & m; + NM_CMP_DIRECT(va, vb); + } + } + return 0; +} + +/*****************************************************************************/ + +#define IPV6_PROPERTY_DIR "/proc/sys/net/ipv6/conf/" +#define IPV4_PROPERTY_DIR "/proc/sys/net/ipv4/conf/" + +G_STATIC_ASSERT(sizeof(IPV4_PROPERTY_DIR) == sizeof(IPV6_PROPERTY_DIR)); +G_STATIC_ASSERT(NM_STRLEN(IPV6_PROPERTY_DIR) + IFNAMSIZ + 60 + == NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE); + +/** + * nm_utils_sysctl_ip_conf_path: + * @addr_family: either AF_INET or AF_INET6. + * @buf: the output buffer where to write the path. It + * must be at least NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE bytes + * long. + * @ifname: an interface name + * @property: a property name + * + * Returns: the path to IPv6 property @property on @ifname. Note that + * this returns the input argument @buf. + */ +const char * +nm_utils_sysctl_ip_conf_path(int addr_family, char *buf, const char *ifname, const char *property) +{ + int len; + + nm_assert(buf); + nm_assert_addr_family(addr_family); + + g_assert(nm_utils_ifname_valid_kernel(ifname, NULL)); + property = NM_ASSERT_VALID_PATH_COMPONENT(property); + + len = g_snprintf(buf, + NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE, + "%s%s/%s", + addr_family == AF_INET6 ? IPV6_PROPERTY_DIR : IPV4_PROPERTY_DIR, + ifname, + property); + g_assert(len < NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE - 1); + return buf; +} + +gboolean +nm_utils_sysctl_ip_conf_is_path(int addr_family, + const char *path, + const char *ifname, + const char *property) +{ + g_return_val_if_fail(path, FALSE); + NM_ASSERT_VALID_PATH_COMPONENT(property); + g_assert(!ifname || nm_utils_ifname_valid_kernel(ifname, NULL)); + + if (addr_family == AF_INET) { + if (!g_str_has_prefix(path, IPV4_PROPERTY_DIR)) + return FALSE; + path += NM_STRLEN(IPV4_PROPERTY_DIR); + } else if (addr_family == AF_INET6) { + if (!g_str_has_prefix(path, IPV6_PROPERTY_DIR)) + return FALSE; + path += NM_STRLEN(IPV6_PROPERTY_DIR); + } else + g_return_val_if_reached(FALSE); + + if (ifname) { + if (!g_str_has_prefix(path, ifname)) + return FALSE; + path += strlen(ifname); + if (path[0] != '/') + return FALSE; + path++; + } else { + const char *slash; + char buf[IFNAMSIZ]; + gsize l; + + slash = strchr(path, '/'); + if (!slash) + return FALSE; + l = slash - path; + if (l >= IFNAMSIZ) + return FALSE; + memcpy(buf, path, l); + buf[l] = '\0'; + if (!nm_utils_ifname_valid_kernel(buf, NULL)) + return FALSE; + path = slash + 1; + } + + if (!nm_streq(path, property)) + return FALSE; + + return TRUE; +} + +gboolean +nm_utils_is_valid_path_component(const char *name) +{ + const char *n; + + if (name == NULL || name[0] == '\0') + return FALSE; + + if (name[0] == '.') { + if (name[1] == '\0') + return FALSE; + if (name[1] == '.' && name[2] == '\0') + return FALSE; + } + n = name; + do { + if (*n == '/') + return FALSE; + } while (*(++n) != '\0'); + + return TRUE; +} + +const char * +NM_ASSERT_VALID_PATH_COMPONENT(const char *name) +{ + if (G_LIKELY(nm_utils_is_valid_path_component(name))) + return name; + + g_error("FATAL: Failed asserting path component: %s%s%s", + NM_PRINT_FMT_QUOTED(name, "\"", name, "\"", "(null)")); + g_assert_not_reached(); +} diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h new file mode 100644 index 0000000..9ea6973 --- /dev/null +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -0,0 +1,2771 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#ifndef __NM_SHARED_UTILS_H__ +#define __NM_SHARED_UTILS_H__ + +#include + +/*****************************************************************************/ + +/* An optional boolean (like NMTernary, with identical numerical + * enum values). Note that this enum type is _nm_packed! */ +typedef enum _nm_packed { + NM_OPTION_BOOL_DEFAULT = -1, + NM_OPTION_BOOL_FALSE = 0, + NM_OPTION_BOOL_TRUE = 1, +} NMOptionBool; + +/*****************************************************************************/ + +static inline gboolean +nm_is_ascii(char ch) +{ + return ((uint8_t) ch) < 128; +} + +/*****************************************************************************/ + +pid_t nm_utils_gettid(void); + +gboolean _nm_assert_on_main_thread(void); + +#if NM_MORE_ASSERTS > 5 + #define NM_ASSERT_ON_MAIN_THREAD() \ + G_STMT_START \ + { \ + nm_assert(_nm_assert_on_main_thread()); \ + } \ + G_STMT_END +#else + #define NM_ASSERT_ON_MAIN_THREAD() \ + G_STMT_START \ + { \ + ; \ + } \ + G_STMT_END +#endif + +/*****************************************************************************/ + +static inline gboolean +_NM_INT_NOT_NEGATIVE(gssize val) +{ + /* whether an enum (without negative values) is a signed int, depends on compiler options + * and compiler implementation. + * + * When using such an enum for accessing an array, one naturally wants to check + * that the enum is not negative. However, the compiler doesn't like a plain + * comparison "enum_val >= 0", because (if the enum is unsigned), it will warn + * that the expression is always true *duh*. Not even a cast to a signed + * type helps to avoid the compiler warning in any case. + * + * The sole purpose of this function is to avoid a compiler warning, when checking + * that an enum is not negative. */ + return val >= 0; +} + +/* check whether the integer value is smaller than G_MAXINT32. This macro exists + * for the sole purpose, that a plain "((int) value <= G_MAXINT32)" comparison + * may cause the compiler or coverity that this check is always TRUE. But the + * check depends on compile time and the size of C type "int". Of course, most + * of the time in is gint32 and an int value is always <= G_MAXINT32. The check + * exists to catch cases where that is not true. + * + * Together with the G_STATIC_ASSERT(), we make sure that this is always satisfied. */ +G_STATIC_ASSERT(sizeof(int) == sizeof(gint32)); +#if _NM_CC_SUPPORT_GENERIC + #define _NM_INT_LE_MAXINT32(value) \ + ({ \ + _nm_unused typeof(value) _value = (value); \ + \ + _Generic((value), int : TRUE); \ + }) +#else + #define _NM_INT_LE_MAXINT32(value) \ + ({ \ + _nm_unused typeof(value) _value = (value); \ + _nm_unused const int *_p_value = &_value; \ + \ + TRUE; \ + }) +#endif + +/*****************************************************************************/ + +typedef enum { + + /* No type, used as error value */ + NM_LINK_TYPE_NONE, + + NM_LINK_TYPE_UNKNOWN, + + NM_LINK_TYPE_ANY, + +#define _NM_LINK_TYPE_REAL_FIRST NM_LINK_TYPE_ETHERNET + +/* Hardware types */ +#define _NM_LINK_TYPE_HW_FIRST NM_LINK_TYPE_ETHERNET + NM_LINK_TYPE_ETHERNET, + NM_LINK_TYPE_INFINIBAND, + NM_LINK_TYPE_OLPC_MESH, + NM_LINK_TYPE_WIFI, + NM_LINK_TYPE_WWAN_NET, /* WWAN kernel netdevice */ + NM_LINK_TYPE_WIMAX, + NM_LINK_TYPE_WPAN, + NM_LINK_TYPE_6LOWPAN, + NM_LINK_TYPE_WIFI_P2P, +#define _NM_LINK_TYPE_HW_LAST NM_LINK_TYPE_WIFI_P2P + +/* Software types */ +#define _NM_LINK_TYPE_SW_FIRST NM_LINK_TYPE_BNEP + NM_LINK_TYPE_BNEP, /* Bluetooth Ethernet emulation */ + NM_LINK_TYPE_DUMMY, + NM_LINK_TYPE_GRE, + NM_LINK_TYPE_GRETAP, + NM_LINK_TYPE_IFB, + NM_LINK_TYPE_IP6TNL, + NM_LINK_TYPE_IP6GRE, + NM_LINK_TYPE_IP6GRETAP, + NM_LINK_TYPE_IPIP, + NM_LINK_TYPE_LOOPBACK, + NM_LINK_TYPE_MACSEC, + NM_LINK_TYPE_MACVLAN, + NM_LINK_TYPE_MACVTAP, + NM_LINK_TYPE_OPENVSWITCH, + NM_LINK_TYPE_PPP, + NM_LINK_TYPE_SIT, + NM_LINK_TYPE_TUN, + NM_LINK_TYPE_VETH, + NM_LINK_TYPE_VLAN, + NM_LINK_TYPE_VRF, + NM_LINK_TYPE_VXLAN, + NM_LINK_TYPE_WIREGUARD, +#define _NM_LINK_TYPE_SW_LAST NM_LINK_TYPE_WIREGUARD + +/* Software types with slaves */ +#define _NM_LINK_TYPE_SW_MASTER_FIRST NM_LINK_TYPE_BRIDGE + NM_LINK_TYPE_BRIDGE, + NM_LINK_TYPE_BOND, + NM_LINK_TYPE_TEAM, +#define _NM_LINK_TYPE_SW_MASTER_LAST NM_LINK_TYPE_TEAM + +#define _NM_LINK_TYPE_REAL_LAST NM_LINK_TYPE_TEAM + +#define _NM_LINK_TYPE_REAL_NUM ((int) (_NM_LINK_TYPE_REAL_LAST - _NM_LINK_TYPE_REAL_FIRST + 1)) + +} NMLinkType; + +static inline gboolean +nm_link_type_is_software(NMLinkType link_type) +{ + G_STATIC_ASSERT(_NM_LINK_TYPE_SW_LAST + 1 == _NM_LINK_TYPE_SW_MASTER_FIRST); + + return link_type >= _NM_LINK_TYPE_SW_FIRST && link_type <= _NM_LINK_TYPE_SW_MASTER_LAST; +} + +static inline gboolean +nm_link_type_supports_slaves(NMLinkType link_type) +{ + return link_type >= _NM_LINK_TYPE_SW_MASTER_FIRST && link_type <= _NM_LINK_TYPE_SW_MASTER_LAST; +} + +/*****************************************************************************/ + +gboolean _nm_utils_inet6_is_token(const struct in6_addr *in6addr); + +typedef struct { + guint8 ether_addr_octet[6 /*ETH_ALEN*/]; +} NMEtherAddr; + +#define NM_ETHER_ADDR_FORMAT_STR "%02X:%02X:%02X:%02X:%02X:%02X" + +#define NM_ETHER_ADDR_FORMAT_VAL(x) \ + (x)->ether_addr_octet[0], (x)->ether_addr_octet[1], (x)->ether_addr_octet[2], \ + (x)->ether_addr_octet[3], (x)->ether_addr_octet[4], (x)->ether_addr_octet[5] + +#define _NM_ETHER_ADDR_INIT(a0, a1, a2, a3, a4, a5) \ + { \ + .ether_addr_octet = { \ + (a0), \ + (a1), \ + (a2), \ + (a3), \ + (a4), \ + (a5), \ + }, \ + } + +#define NM_ETHER_ADDR_INIT(...) ((NMEtherAddr) _NM_ETHER_ADDR_INIT(__VA_ARGS__)) + +static inline int +nm_ether_addr_cmp(const NMEtherAddr *a, const NMEtherAddr *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_DIRECT_MEMCMP(a, b, sizeof(NMEtherAddr)); + return 0; +} + +static inline gboolean +nm_ether_addr_equal(const NMEtherAddr *a, const NMEtherAddr *b) +{ + return nm_ether_addr_cmp(a, b) == 0; +} + +/*****************************************************************************/ + +typedef struct { + union { + guint8 addr_ptr[1]; + in_addr_t addr4; + struct in_addr addr4_struct; + struct in6_addr addr6; + + /* NMIPAddr is really a union for IP addresses. + * However, as ethernet addresses fit in here nicely, use + * it also for an ethernet MAC address. */ + guint8 ether_addr_octet[6 /*ETH_ALEN*/]; + NMEtherAddr ether_addr; + + guint8 array[sizeof(struct in6_addr)]; + }; +} NMIPAddr; + +#define NM_IP_ADDR_INIT \ + { \ + .array = { 0 } \ + } + +extern const NMIPAddr nm_ip_addr_zero; + +#define nm_ether_addr_zero (nm_ip_addr_zero.ether_addr) + +static inline int +nm_ip_addr_cmp(int addr_family, gconstpointer a, gconstpointer b) +{ + nm_assert_addr_family(addr_family); + nm_assert(a); + nm_assert(b); + + return memcmp(a, b, nm_utils_addr_family_to_size(addr_family)); +} + +static inline gboolean +nm_ip_addr_equal(int addr_family, gconstpointer a, gconstpointer b) +{ + return nm_ip_addr_cmp(addr_family, a, b) == 0; +} + +static inline gboolean +nm_ip_addr_is_null(int addr_family, gconstpointer addr) +{ + nm_assert(addr); + if (addr_family == AF_INET6) + return IN6_IS_ADDR_UNSPECIFIED((const struct in6_addr *) addr); + nm_assert(addr_family == AF_INET); + return ((const struct in_addr *) addr)->s_addr == 0; +} + +static inline void +nm_ip_addr_set(int addr_family, gpointer dst, gconstpointer src) +{ + nm_assert_addr_family(addr_family); + nm_assert(dst); + nm_assert(src); + + memcpy(dst, src, (addr_family != AF_INET6) ? sizeof(in_addr_t) : sizeof(struct in6_addr)); +} + +gboolean nm_ip_addr_set_from_untrusted(int addr_family, + gpointer dst, + gconstpointer src, + gsize src_len, + int * out_addr_family); + +static inline gboolean +nm_ip4_addr_is_localhost(in_addr_t addr4) +{ + return (addr4 & htonl(0xFF000000u)) == htonl(0x7F000000u); +} + +/*****************************************************************************/ + +struct ether_addr; + +static inline int +nm_utils_ether_addr_cmp(const struct ether_addr *a1, const struct ether_addr *a2) +{ + nm_assert(a1); + nm_assert(a2); + return memcmp(a1, a2, 6 /*ETH_ALEN*/); +} + +static inline gboolean +nm_utils_ether_addr_equal(const struct ether_addr *a1, const struct ether_addr *a2) +{ + return nm_utils_ether_addr_cmp(a1, a2) == 0; +} + +/*****************************************************************************/ + +/** + * NMUtilsIPv6IfaceId: + * @id: convenience member for validity checking; never use directly + * @id_u8: the 64-bit Interface Identifier + * + * Holds a 64-bit IPv6 Interface Identifier. The IID is a sequence of bytes + * and should not normally be treated as a %guint64, but this is done for + * convenience of validity checking and initialization. + */ +typedef struct _NMUtilsIPv6IfaceId { + union { + guint64 id; + guint8 id_u8[8]; + }; +} NMUtilsIPv6IfaceId; + +#define NM_UTILS_IPV6_IFACE_ID_INIT \ + { \ + { \ + .id = 0 \ + } \ + } + +void nm_utils_ipv6_addr_set_interface_identifier(struct in6_addr * addr, + const NMUtilsIPv6IfaceId iid); + +void nm_utils_ipv6_interface_identifier_get_from_addr(NMUtilsIPv6IfaceId * iid, + const struct in6_addr *addr); + +gboolean nm_utils_ipv6_interface_identifier_get_from_token(NMUtilsIPv6IfaceId *iid, + const char * token); + +const char *nm_utils_inet6_interface_identifier_to_token(NMUtilsIPv6IfaceId iid, + char buf[static INET6_ADDRSTRLEN]); + +gboolean nm_utils_get_ipv6_interface_identifier(NMLinkType link_type, + const guint8 * hwaddr, + guint len, + guint dev_id, + NMUtilsIPv6IfaceId *out_iid); + +/*****************************************************************************/ + +gconstpointer +nm_utils_ipx_address_clear_host_address(int family, gpointer dst, gconstpointer src, guint8 plen); +in_addr_t nm_utils_ip4_address_clear_host_address(in_addr_t addr, guint8 plen); +const struct in6_addr *nm_utils_ip6_address_clear_host_address(struct in6_addr * dst, + const struct in6_addr *src, + guint8 plen); + +static inline int +nm_utils_ip4_address_same_prefix_cmp(in_addr_t addr_a, in_addr_t addr_b, guint8 plen) +{ + NM_CMP_DIRECT(htonl(nm_utils_ip4_address_clear_host_address(addr_a, plen)), + htonl(nm_utils_ip4_address_clear_host_address(addr_b, plen))); + return 0; +} + +int nm_utils_ip6_address_same_prefix_cmp(const struct in6_addr *addr_a, + const struct in6_addr *addr_b, + guint8 plen); + +static inline int +nm_utils_ip_address_same_prefix_cmp(int addr_family, + gconstpointer addr_a, + gconstpointer addr_b, + guint8 plen) +{ + nm_assert_addr_family(addr_family); + + NM_CMP_SELF(addr_a, addr_b); + + if (NM_IS_IPv4(addr_family)) { + return nm_utils_ip4_address_same_prefix_cmp(*((const in_addr_t *) addr_a), + *((const in_addr_t *) addr_b), + plen); + } + + return nm_utils_ip6_address_same_prefix_cmp(addr_a, addr_b, plen); +} + +static inline gboolean +nm_utils_ip4_address_same_prefix(in_addr_t addr_a, in_addr_t addr_b, guint8 plen) +{ + return nm_utils_ip4_address_same_prefix_cmp(addr_a, addr_b, plen) == 0; +} + +static inline gboolean +nm_utils_ip6_address_same_prefix(const struct in6_addr *addr_a, + const struct in6_addr *addr_b, + guint8 plen) +{ + return nm_utils_ip6_address_same_prefix_cmp(addr_a, addr_b, plen) == 0; +} + +static inline gboolean +nm_utils_ip_address_same_prefix(int addr_family, + gconstpointer addr_a, + gconstpointer addr_b, + guint8 plen) +{ + return nm_utils_ip_address_same_prefix_cmp(addr_family, addr_a, addr_b, plen) == 0; +} + +#define NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(a, b, plen) \ + NM_CMP_RETURN(nm_utils_ip4_address_same_prefix_cmp((a), (b), (plen))) + +#define NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(a, b, plen) \ + NM_CMP_RETURN(nm_utils_ip6_address_same_prefix_cmp((a), (b), (plen))) + +/*****************************************************************************/ + +#define NM_IPV4LL_NETWORK ((in_addr_t)(htonl(0xA9FE0000lu))) +#define NM_IPV4LL_NETMASK ((in_addr_t)(htonl(0xFFFF0000lu))) + +static inline gboolean +nm_utils_ip4_address_is_link_local(in_addr_t addr) +{ + return (addr & NM_IPV4LL_NETMASK) == NM_IPV4LL_NETWORK; +} + +static inline gboolean +nm_utils_ip4_address_is_zeronet(in_addr_t network) +{ + /* Same as ipv4_is_zeronet() from kernel's include/linux/in.h. */ + return (network & htonl(0xFF000000u)) == htonl(0x00000000u); +} + +/*****************************************************************************/ + +#define NM_UTILS_INET_ADDRSTRLEN INET6_ADDRSTRLEN + +static inline const char * +nm_utils_inet_ntop(int addr_family, gconstpointer addr, char *dst) +{ + const char *s; + + const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); + + nm_assert_addr_family(addr_family); + nm_assert(addr); + nm_assert(dst); + + s = inet_ntop(addr_family, + addr, + dst, + addr_family == AF_INET6 ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN); + nm_assert(s); + return s; +} + +static inline const char * +_nm_utils_inet4_ntop(in_addr_t addr, char dst[static INET_ADDRSTRLEN]) +{ + return nm_utils_inet_ntop(AF_INET, &addr, dst); +} + +static inline const char * +_nm_utils_inet6_ntop(const struct in6_addr *addr, char dst[static INET6_ADDRSTRLEN]) +{ + return nm_utils_inet_ntop(AF_INET6, addr, dst); +} + +static inline char * +nm_utils_inet_ntop_dup(int addr_family, gconstpointer addr) +{ + char buf[NM_UTILS_INET_ADDRSTRLEN]; + + return g_strdup(nm_utils_inet_ntop(addr_family, addr, buf)); +} + +static inline char * +nm_utils_inet4_ntop_dup(in_addr_t addr) +{ + return nm_utils_inet_ntop_dup(AF_INET, &addr); +} + +static inline char * +nm_utils_inet6_ntop_dup(const struct in6_addr *addr) +{ + return nm_utils_inet_ntop_dup(AF_INET6, addr); +} + +/*****************************************************************************/ + +gboolean nm_utils_ipaddr_is_valid(int addr_family, const char *str_addr); + +gboolean nm_utils_ipaddr_is_normalized(int addr_family, const char *str_addr); + +/*****************************************************************************/ + +/* this enum is compatible with ICMPV6_ROUTER_PREF_* (from , + * the values for netlink attribute RTA_PREF) and "enum ndp_route_preference" + * from . */ +typedef enum _nm_packed { + NM_ICMPV6_ROUTER_PREF_MEDIUM = 0x0, /* ICMPV6_ROUTER_PREF_MEDIUM */ + NM_ICMPV6_ROUTER_PREF_LOW = 0x3, /* ICMPV6_ROUTER_PREF_LOW */ + NM_ICMPV6_ROUTER_PREF_HIGH = 0x1, /* ICMPV6_ROUTER_PREF_HIGH */ + NM_ICMPV6_ROUTER_PREF_INVALID = 0x2, /* ICMPV6_ROUTER_PREF_INVALID */ +} NMIcmpv6RouterPref; + +const char *nm_icmpv6_router_pref_to_string(NMIcmpv6RouterPref pref, char *buf, gsize len); + +/*****************************************************************************/ + +gboolean nm_utils_memeqzero(gconstpointer data, gsize length); + +/*****************************************************************************/ + +extern const void *const _NM_PTRARRAY_EMPTY[1]; + +#define NM_PTRARRAY_EMPTY(type) ((type const *) _NM_PTRARRAY_EMPTY) + +static inline void +_nm_utils_strbuf_init(char *buf, gsize len, char **p_buf_ptr, gsize *p_buf_len) +{ + NM_SET_OUT(p_buf_len, len); + NM_SET_OUT(p_buf_ptr, buf); + buf[0] = '\0'; +} + +#define nm_utils_strbuf_init(buf, p_buf_ptr, p_buf_len) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT(G_N_ELEMENTS(buf) == sizeof(buf) && sizeof(buf) > sizeof(char *)); \ + _nm_utils_strbuf_init((buf), sizeof(buf), (p_buf_ptr), (p_buf_len)); \ + } \ + G_STMT_END +void nm_utils_strbuf_append(char **buf, gsize *len, const char *format, ...) _nm_printf(3, 4); +void nm_utils_strbuf_append_c(char **buf, gsize *len, char c); +void nm_utils_strbuf_append_str(char **buf, gsize *len, const char *str); +void nm_utils_strbuf_append_bin(char **buf, gsize *len, gconstpointer str, gsize str_len); +void nm_utils_strbuf_seek_end(char **buf, gsize *len); + +const char *nm_strquote(char *buf, gsize buf_len, const char *str); + +static inline gboolean +nm_utils_is_separator(const char c) +{ + return NM_IN_SET(c, ' ', '\t'); +} + +/*****************************************************************************/ + +GBytes *nm_gbytes_get_empty(void); + +GBytes *nm_g_bytes_new_from_str(const char *str); + +static inline gboolean +nm_gbytes_equal0(GBytes *a, GBytes *b) +{ + return a == b || (a && b && g_bytes_equal(a, b)); +} + +gboolean nm_utils_gbytes_equal_mem(GBytes *bytes, gconstpointer mem_data, gsize mem_len); + +GVariant *nm_utils_gbytes_to_variant_ay(GBytes *bytes); + +GHashTable *nm_utils_strdict_clone(GHashTable *src); + +GVariant *nm_utils_strdict_to_variant_ass(GHashTable *strdict); +GVariant *nm_utils_strdict_to_variant_asv(GHashTable *strdict); + +/*****************************************************************************/ + +GVariant *nm_utils_gvariant_vardict_filter(GVariant *src, + gboolean (*filter_fcn)(const char *key, + GVariant * val, + char ** out_key, + GVariant ** out_val, + gpointer user_data), + gpointer user_data); + +GVariant *nm_utils_gvariant_vardict_filter_drop_one(GVariant *src, const char *key); + +/*****************************************************************************/ + +static inline int +nm_utils_hexchar_to_int(char ch) +{ + G_STATIC_ASSERT_EXPR('0' < 'A'); + G_STATIC_ASSERT_EXPR('A' < 'a'); + + if (ch >= '0') { + if (ch <= '9') + return ch - '0'; + if (ch >= 'A') { + if (ch <= 'F') + return ((int) ch) + (10 - (int) 'A'); + if (ch >= 'a' && ch <= 'f') + return ((int) ch) + (10 - (int) 'a'); + } + } + return -1; +} + +/*****************************************************************************/ + +const char *nm_utils_dbus_path_get_last_component(const char *dbus_path); + +int nm_utils_dbus_path_cmp(const char *dbus_path_a, const char *dbus_path_b); + +/*****************************************************************************/ + +typedef enum { + NM_UTILS_STRSPLIT_SET_FLAGS_NONE = 0, + + /* by default, strsplit will coalesce consecutive delimiters and remove + * them from the result. If this flag is present, empty values are preserved + * and returned. + * + * When combined with %NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP, if a value gets + * empty after strstrip(), it also gets removed. */ + NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY = (1u << 0), + + /* %NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING means that delimiters prefixed + * by a backslash are not treated as a separator. Such delimiters and their escape + * character are copied to the current word without unescaping them. In general, + * nm_utils_strsplit_set_full() does not remove any backslash escape characters + * and does no unescaping. It only considers them for skipping to split at + * an escaped delimiter. + * + * If this is combined with (or implied by %NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED), then + * the backslash escapes are removed from the result. + */ + NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING = (1u << 1), + + /* If flag is set, does the same as g_strstrip() on the returned tokens. + * This will remove leading and trailing ascii whitespaces (g_ascii_isspace() + * and NM_ASCII_SPACES). + * + * - when combined with !%NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY, + * empty tokens will be removed (and %NULL will be returned if that + * results in an empty string array). + * - when combined with %NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING, + * trailing whitespace escaped by backslash are not stripped. */ + NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP = (1u << 2), + + /* This implies %NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING. + * + * This will do a final run over all tokens and remove all backslash + * escape characters that + * - precede a delimiter. + * - precede a backslash. + * - preceed a whitespace (with %NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP). + * + * Note that with %NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP, it is only + * necessary to escape the very last whitespace (if the delimiters + * are not whitespace themself). So, technically, it would be sufficient + * to only unescape a backslash before the last whitespace and the user + * still could express everything. However, such a rule would be complicated + * to understand, so when using backslash escaping with nm_utils_strsplit_set_full(), + * then all characters (including backslash) are treated verbatim, except: + * + * - "\\$DELIMITER" (escaped delimiter) + * - "\\\\" (escaped backslash) + * - "\\$SPACE" (escaped space) (with %NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP). + * + * Note that all other escapes like "\\n" or "\\001" are left alone. + * That makes the escaping/unescaping rules simple. Also, for the most part + * a text is just taken as-is, with little additional rules. Only backslashes + * need extra care, and then only if they proceed one of the relevant characters. + */ + NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED = (1u << 3), + +} NMUtilsStrsplitSetFlags; + +const char ** +nm_utils_strsplit_set_full(const char *str, const char *delimiter, NMUtilsStrsplitSetFlags flags); + +static inline const char ** +nm_utils_strsplit_set_with_empty(const char *str, const char *delimiters) +{ + /* this returns the same result as g_strsplit_set(str, delimiters, -1), except + * it does not deep-clone the strv array. + * Also, for @str == "", this returns %NULL while g_strsplit_set() would return + * an empty strv array. */ + return nm_utils_strsplit_set_full(str, delimiters, NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY); +} + +static inline const char ** +nm_utils_strsplit_set(const char *str, const char *delimiters) +{ + return nm_utils_strsplit_set_full(str, delimiters, NM_UTILS_STRSPLIT_SET_FLAGS_NONE); +} + +gssize nm_utils_strv_find_first(char **list, gssize len, const char *needle); + +char **_nm_utils_strv_cleanup(char ** strv, + gboolean strip_whitespace, + gboolean skip_empty, + gboolean skip_repeated); + +/*****************************************************************************/ + +static inline gpointer +nm_copy_func_g_strdup(gconstpointer arg, gpointer user_data) +{ + return g_strdup(arg); +} + +/*****************************************************************************/ + +static inline const char ** +nm_utils_escaped_tokens_split(const char *str, const char *delimiters) +{ + return nm_utils_strsplit_set_full(str, + delimiters, + NM_UTILS_STRSPLIT_SET_FLAGS_ESCAPED + | NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); +} + +typedef enum { + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_NONE = 0, + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_SPACES = (1ull << 0), + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_LEADING_SPACE = (1ull << 1), + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_TRAILING_SPACE = (1ull << 2), + + /* Backslash characters will be escaped as "\\\\" if they precede another + * character that makes it necessary. Such characters are: + * + * 1) before another '\\' backslash. + * 2) before any delimiter in @delimiters. + * 3) before any delimiter in @delimiters_as_needed. + * 4) before a white space, if ESCAPE_LEADING_SPACE or ESCAPE_TRAILING_SPACE is set. + * 5) before the end of the word + * + * Rule 4) is an extension. It's not immediately clear why with ESCAPE_LEADING_SPACE + * and ESCAPE_TRAILING_SPACE we want *all* backslashes before a white space escaped. + * The reason is, that we obviously want to use ESCAPE_LEADING_SPACE and ESCAPE_TRAILING_SPACE + * in cases, where we later parse the backslash escaped strings back, but allowing to strip + * unescaped white spaces. That means, we want that " a " gets escaped as "\\ a\\ ". + * On the other hand, we also want that " a\\ b " gets escaped as "\\ a\\\\ b\\ ", + * and not "\\ a\\ b\\ ". Because otherwise, the parser would need to treat "\\ " + * differently depending on whether the sequence is at the beginning, end or middle + * of the word. + * + * Rule 5) is also not immediately obvious. When used with ESCAPE_TRAILING_SPACE, + * we clearly want to allow that an escaped word can have arbitrary + * whitespace suffixes. That's why this mode exists. So we must escape "a\\" as + * "a\\\\", so that appending " " does not change the meaning. + * Also without ESCAPE_TRAILING_SPACE, we want in general that we can concatenate + * two escaped words without changing their meaning. If the words would be "a\\" + * and "," (with ',' being a delimiter), then the result must be "a\\\\" and "\\," + * so that the concatenated word ("a\\\\\\,") is still the same. If we would escape + * them instead as "a\\" + "\\,", then the concatenated word would be "a\\\\," and + * different. + * */ + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_BACKSLASH_AS_NEEDED = (1ull << 3), + + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_BACKSLASH_ALWAYS = (1ull << 4), +} NMUtilsEscapedTokensEscapeFlags; + +const char *nm_utils_escaped_tokens_escape_full(const char *str, + const char *delimiters, + const char *delimiters_as_needed, + NMUtilsEscapedTokensEscapeFlags flags, + char ** out_to_free); + +static inline const char * +nm_utils_escaped_tokens_escape(const char *str, const char *delimiters, char **out_to_free) +{ + return nm_utils_escaped_tokens_escape_full( + str, + delimiters, + NULL, + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_BACKSLASH_ALWAYS + | NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_TRAILING_SPACE, + out_to_free); +} + +/** + * nm_utils_escaped_tokens_escape_unnecessary: + * @str: the string to check for "escape" + * @delimiters: the delimiters + * + * This asserts that calling nm_utils_escaped_tokens_escape() + * on @str has no effect and returns @str directly. This is only + * for asserting that @str is safe to not require any escaping. + * + * Returns: @str + */ +static inline const char * +nm_utils_escaped_tokens_escape_unnecessary(const char *str, const char *delimiters) +{ +#if NM_MORE_ASSERTS > 0 + + nm_assert(str); + nm_assert(delimiters); + + { + gs_free char *str_to_free = NULL; + const char * str0; + + str0 = nm_utils_escaped_tokens_escape(str, delimiters, &str_to_free); + nm_assert(str0 == str); + nm_assert(!str_to_free); + } +#endif + + return str; +} + +static inline void +nm_utils_escaped_tokens_escape_gstr_assert(const char *str, + const char *delimiters, + GString * gstring) +{ + g_string_append(gstring, nm_utils_escaped_tokens_escape_unnecessary(str, delimiters)); +} + +static inline GString * +nm_utils_escaped_tokens_escape_gstr(const char *str, const char *delimiters, GString *gstring) +{ + gs_free char *str_to_free = NULL; + + nm_assert(str); + nm_assert(gstring); + + g_string_append(gstring, nm_utils_escaped_tokens_escape(str, delimiters, &str_to_free)); + return gstring; +} + +/*****************************************************************************/ + +char **nm_utils_strsplit_quoted(const char *str); + +/*****************************************************************************/ + +static inline const char ** +nm_utils_escaped_tokens_options_split_list(const char *str) +{ + return nm_utils_strsplit_set_full(str, + ",", + NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP + | NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING); +} + +void nm_utils_escaped_tokens_options_split(char *str, const char **out_key, const char **out_val); + +static inline const char * +nm_utils_escaped_tokens_options_escape_key(const char *key, char **out_to_free) +{ + return nm_utils_escaped_tokens_escape_full( + key, + ",=", + NULL, + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_BACKSLASH_AS_NEEDED + | NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_LEADING_SPACE + | NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_TRAILING_SPACE, + out_to_free); +} + +static inline const char * +nm_utils_escaped_tokens_options_escape_val(const char *val, char **out_to_free) +{ + return nm_utils_escaped_tokens_escape_full( + val, + ",", + "=", + NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_BACKSLASH_AS_NEEDED + | NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_LEADING_SPACE + | NM_UTILS_ESCAPED_TOKENS_ESCAPE_FLAGS_ESCAPE_TRAILING_SPACE, + out_to_free); +} + +/*****************************************************************************/ + +#define NM_UTILS_CHECKSUM_LENGTH_MD5 16 +#define NM_UTILS_CHECKSUM_LENGTH_SHA1 20 +#define NM_UTILS_CHECKSUM_LENGTH_SHA256 32 + +#define nm_utils_checksum_get_digest(sum, arr) \ + G_STMT_START \ + { \ + GChecksum *const _sum = (sum); \ + gsize _len; \ + \ + G_STATIC_ASSERT_EXPR(sizeof(arr) == NM_UTILS_CHECKSUM_LENGTH_MD5 \ + || sizeof(arr) == NM_UTILS_CHECKSUM_LENGTH_SHA1 \ + || sizeof(arr) == NM_UTILS_CHECKSUM_LENGTH_SHA256); \ + G_STATIC_ASSERT_EXPR(sizeof(arr) == G_N_ELEMENTS(arr)); \ + \ + nm_assert(_sum); \ + \ + _len = G_N_ELEMENTS(arr); \ + \ + g_checksum_get_digest(_sum, (arr), &_len); \ + nm_assert(_len == G_N_ELEMENTS(arr)); \ + } \ + G_STMT_END + +#define nm_utils_checksum_get_digest_len(sum, buf, len) \ + G_STMT_START \ + { \ + GChecksum *const _sum = (sum); \ + const gsize _len0 = (len); \ + gsize _len; \ + \ + nm_assert(NM_IN_SET(_len0, \ + NM_UTILS_CHECKSUM_LENGTH_MD5, \ + NM_UTILS_CHECKSUM_LENGTH_SHA1, \ + NM_UTILS_CHECKSUM_LENGTH_SHA256)); \ + nm_assert(_sum); \ + \ + _len = _len0; \ + g_checksum_get_digest(_sum, (buf), &_len); \ + nm_assert(_len == _len0); \ + } \ + G_STMT_END + +/*****************************************************************************/ + +guint32 _nm_utils_ip4_prefix_to_netmask(guint32 prefix); +guint32 _nm_utils_ip4_get_default_prefix0(in_addr_t ip); +guint32 _nm_utils_ip4_get_default_prefix(in_addr_t ip); + +gconstpointer +nm_utils_ipx_address_clear_host_address(int family, gpointer dst, gconstpointer src, guint8 plen); +in_addr_t nm_utils_ip4_address_clear_host_address(in_addr_t addr, guint8 plen); +const struct in6_addr *nm_utils_ip6_address_clear_host_address(struct in6_addr * dst, + const struct in6_addr *src, + guint8 plen); +int nm_utils_ip6_address_same_prefix_cmp(const struct in6_addr *addr_a, + const struct in6_addr *addr_b, + guint8 plen); + +gboolean nm_utils_ip_is_site_local(int addr_family, const void *address); + +/*****************************************************************************/ + +gboolean nm_utils_parse_inaddr_bin_full(int addr_family, + gboolean accept_legacy, + const char *text, + int * out_addr_family, + gpointer out_addr); +static inline gboolean +nm_utils_parse_inaddr_bin(int addr_family, + const char *text, + int * out_addr_family, + gpointer out_addr) +{ + return nm_utils_parse_inaddr_bin_full(addr_family, FALSE, text, out_addr_family, out_addr); +} + +gboolean nm_utils_parse_inaddr(int addr_family, const char *text, char **out_addr); + +gboolean nm_utils_parse_inaddr_prefix_bin(int addr_family, + const char *text, + int * out_addr_family, + gpointer out_addr, + int * out_prefix); + +gboolean +nm_utils_parse_inaddr_prefix(int addr_family, const char *text, char **out_addr, int *out_prefix); + +gboolean nm_utils_parse_next_line(const char **inout_ptr, + gsize * inout_len, + const char **out_line, + gsize * out_line_len); + +gint64 nm_g_ascii_strtoll(const char *nptr, char **endptr, guint base); + +guint64 nm_g_ascii_strtoull(const char *nptr, char **endptr, guint base); + +double nm_g_ascii_strtod(const char *nptr, char **endptr); + +gint64 +_nm_utils_ascii_str_to_int64(const char *str, guint base, gint64 min, gint64 max, gint64 fallback); +guint64 _nm_utils_ascii_str_to_uint64(const char *str, + guint base, + guint64 min, + guint64 max, + guint64 fallback); + +int _nm_utils_ascii_str_to_bool(const char *str, int default_value); + +/*****************************************************************************/ + +extern char _nm_utils_to_string_buffer[2096]; + +void nm_utils_to_string_buffer_init(char **buf, gsize *len); +gboolean nm_utils_to_string_buffer_init_null(gconstpointer obj, char **buf, gsize *len); + +/*****************************************************************************/ + +typedef struct { + unsigned flag; + const char *name; +} NMUtilsFlags2StrDesc; + +#define NM_UTILS_FLAGS2STR(f, n) \ + { \ + .flag = f, .name = "" n, \ + } + +#define NM_UTILS_FLAGS2STR_DEFINE(fcn_name, flags_type, ...) \ + const char *fcn_name(flags_type flags, char *buf, gsize len) \ + { \ + static const NMUtilsFlags2StrDesc descs[] = {__VA_ARGS__}; \ + G_STATIC_ASSERT(sizeof(flags_type) <= sizeof(unsigned)); \ + \ + return nm_utils_flags2str(descs, G_N_ELEMENTS(descs), flags, buf, len); \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +const char *nm_utils_flags2str(const NMUtilsFlags2StrDesc *descs, + gsize n_descs, + unsigned flags, + char * buf, + gsize len); + +/*****************************************************************************/ + +#define NM_UTILS_ENUM2STR(v, n) \ + (void) 0; \ +case v: \ + s = "" n ""; \ + break; \ + (void) 0 +#define NM_UTILS_ENUM2STR_IGNORE(v) \ + (void) 0; \ +case v: \ + break; \ + (void) 0 + +#define NM_UTILS_ENUM2STR_DEFINE_FULL(fcn_name, lookup_type, int_fmt, ...) \ + const char *fcn_name(lookup_type val, char *buf, gsize len) \ + { \ + nm_utils_to_string_buffer_init(&buf, &len); \ + if (len) { \ + const char *s = NULL; \ + switch (val) { \ + (void) 0, __VA_ARGS__(void) 0; \ + }; \ + if (s) \ + g_strlcpy(buf, s, len); \ + else \ + g_snprintf(buf, len, "(%" int_fmt ")", val); \ + } \ + return buf; \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +#define NM_UTILS_ENUM2STR_DEFINE(fcn_name, lookup_type, ...) \ + NM_UTILS_ENUM2STR_DEFINE_FULL(fcn_name, lookup_type, "d", __VA_ARGS__) + +/*****************************************************************************/ + +#define _nm_g_slice_free_fcn_define(mem_size) \ + static inline void _nm_g_slice_free_fcn_##mem_size(gpointer mem_block) \ + { \ + g_slice_free1(mem_size, mem_block); \ + } + +_nm_g_slice_free_fcn_define(1) _nm_g_slice_free_fcn_define(2) _nm_g_slice_free_fcn_define(4) + _nm_g_slice_free_fcn_define(8) _nm_g_slice_free_fcn_define(10) _nm_g_slice_free_fcn_define(12) + _nm_g_slice_free_fcn_define(16) _nm_g_slice_free_fcn_define(32) + +#define nm_g_slice_free_fcn1(mem_size) \ + ({ \ + void (*_fcn)(gpointer); \ + \ + /* If mem_size is a compile time constant, the compiler + * will be able to optimize this. Hence, you don't want + * to call this with a non-constant size argument. */ \ + G_STATIC_ASSERT_EXPR(((mem_size) == 1) || ((mem_size) == 2) || ((mem_size) == 4) \ + || ((mem_size) == 8) || ((mem_size) == 10) || ((mem_size) == 12) \ + || ((mem_size) == 16) || ((mem_size) == 32)); \ + switch ((mem_size)) { \ + case 1: \ + _fcn = _nm_g_slice_free_fcn_1; \ + break; \ + case 2: \ + _fcn = _nm_g_slice_free_fcn_2; \ + break; \ + case 4: \ + _fcn = _nm_g_slice_free_fcn_4; \ + break; \ + case 8: \ + _fcn = _nm_g_slice_free_fcn_8; \ + break; \ + case 10: \ + _fcn = _nm_g_slice_free_fcn_10; \ + break; \ + case 12: \ + _fcn = _nm_g_slice_free_fcn_12; \ + break; \ + case 16: \ + _fcn = _nm_g_slice_free_fcn_16; \ + break; \ + case 32: \ + _fcn = _nm_g_slice_free_fcn_32; \ + break; \ + default: \ + g_assert_not_reached(); \ + _fcn = NULL; \ + break; \ + } \ + _fcn; \ + }) + +/** + * nm_g_slice_free_fcn: + * @type: type argument for sizeof() operator that you would + * pass to g_slice_new(). + * + * Returns: a function pointer with GDestroyNotify signature + * for g_slice_free(type,*). + * + * Only certain types are implemented. You'll get a compile time + * error for the wrong types. */ +#define nm_g_slice_free_fcn(type) (nm_g_slice_free_fcn1(sizeof(type))) + +#define nm_g_slice_free_fcn_gint64 (nm_g_slice_free_fcn(gint64)) + +/*****************************************************************************/ + +/* Like g_error_matches() however: + * - as macro it is always inlined. + * - the @domain is usually a error quark getter function that cannot + * be inlined. This macro calls the getter only if there is an error (lazy). + * - accept a list of allowed codes, instead of only one. + */ +#define nm_g_error_matches(error, err_domain, ...) \ + ({ \ + const GError *const _error = (error); \ + \ + _error && _error->domain == (err_domain) && NM_IN_SET(_error->code, __VA_ARGS__); \ + }) + + static inline void nm_g_set_error_take(GError **error, GError *error_take) +{ + if (!error_take) + g_return_if_reached(); + if (!error) { + g_error_free(error_take); + return; + } + if (*error) { + g_error_free(error_take); + g_return_if_reached(); + } + *error = error_take; +} + +#define nm_g_set_error_take_lazy(error, error_take_lazy) \ + G_STMT_START \ + { \ + GError **_error = (error); \ + \ + if (_error) \ + nm_g_set_error_take(_error, (error_take_lazy)); \ + } \ + G_STMT_END + +/** + * NMUtilsError: + * @NM_UTILS_ERROR_UNKNOWN: unknown or unclassified error + * @NM_UTILS_ERROR_CANCELLED_DISPOSING: when disposing an object that has + * pending asynchronous operations, the operation is cancelled with this + * error reason. Depending on the usage, this might indicate a bug because + * usually the target object should stay alive as long as there are pending + * operations. + * @NM_UTILS_ERROR_NOT_READY: the failure is related to being currently + * not ready to perform the operation. + * + * @NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE: used for a very particular + * purpose during nm_device_check_connection_compatible() to indicate that + * the profile does not match the device already because their type differs. + * That is, there is a fundamental reason of trying to check a profile that + * cannot possibly match on this device. + * @NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE: used for a very particular + * purpose during nm_device_check_connection_available(), to indicate that the + * device is not available because it is unmanaged. + * @NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY: the profile is currently not + * available/compatible with the device, but this may be only temporary. + * + * @NM_UTILS_ERROR_SETTING_MISSING: the setting is missing + * + * @NM_UTILS_ERROR_INVALID_ARGUMENT: invalid argument. + */ +typedef enum { + NM_UTILS_ERROR_UNKNOWN = 0, /*< nick=Unknown >*/ + NM_UTILS_ERROR_CANCELLED_DISPOSING, /*< nick=CancelledDisposing >*/ + NM_UTILS_ERROR_INVALID_ARGUMENT, /*< nick=InvalidArgument >*/ + NM_UTILS_ERROR_NOT_READY, /*< nick=NotReady >*/ + + /* the following codes have a special meaning and are exactly used for + * nm_device_check_connection_compatible() and nm_device_check_connection_available(). + * + * Actually, their meaning is not very important (so, don't think too + * hard about the name of these error codes). What is important, is their + * relative order (i.e. the integer value of the codes). When manager + * searches for a suitable device, it will check all devices whether + * a profile can be activated. If they all fail, it will pick the error + * message from the device that returned the *highest* error code, + * in the hope that this message makes the most sense for the caller. + * */ + NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + + NM_UTILS_ERROR_SETTING_MISSING, + +} NMUtilsError; + +#define NM_UTILS_ERROR (nm_utils_error_quark()) +GQuark nm_utils_error_quark(void); + +GQuark nm_manager_error_quark(void); +#define _NM_MANAGER_ERROR (nm_manager_error_quark()) + +#define _NM_MANAGER_ERROR_UNKNOWN_LOG_LEVEL 10 +#define _NM_MANAGER_ERROR_UNKNOWN_LOG_DOMAIN 11 + +void nm_utils_error_set_cancelled(GError **error, gboolean is_disposing, const char *instance_name); + +static inline GError * +nm_utils_error_new_cancelled(gboolean is_disposing, const char *instance_name) +{ + GError *error = NULL; + + nm_utils_error_set_cancelled(&error, is_disposing, instance_name); + return error; +} + +gboolean nm_utils_error_is_cancelled_or_disposing(GError *error); + +static inline gboolean +nm_utils_error_is_cancelled(GError *error) +{ + return error && error->code == G_IO_ERROR_CANCELLED && error->domain == G_IO_ERROR; +} + +gboolean nm_utils_error_is_notfound(GError *error); + +static inline void +nm_utils_error_set_literal(GError **error, int error_code, const char *literal) +{ + g_set_error_literal(error, NM_UTILS_ERROR, error_code, literal); +} + +#define nm_utils_error_set(error, error_code, ...) \ + G_STMT_START \ + { \ + if (NM_NARG(__VA_ARGS__) == 1) { \ + g_set_error_literal((error), \ + NM_UTILS_ERROR, \ + (error_code), \ + _NM_UTILS_MACRO_FIRST(__VA_ARGS__)); \ + } else { \ + g_set_error((error), NM_UTILS_ERROR, (error_code), __VA_ARGS__); \ + } \ + } \ + G_STMT_END + +#define nm_utils_error_set_errno(error, errsv, fmt, ...) \ + G_STMT_START \ + { \ + char _bstrerr[NM_STRERROR_BUFSIZE]; \ + \ + g_set_error((error), \ + NM_UTILS_ERROR, \ + NM_UTILS_ERROR_UNKNOWN, \ + fmt, \ + ##__VA_ARGS__, \ + nm_strerror_native_r( \ + ({ \ + const int _errsv = (errsv); \ + \ + (_errsv >= 0 ? _errsv \ + : (G_UNLIKELY(_errsv == G_MININT) ? G_MAXINT : -errsv)); \ + }), \ + _bstrerr, \ + sizeof(_bstrerr))); \ + } \ + G_STMT_END + +#define nm_utils_error_new(error_code, ...) \ + ((NM_NARG(__VA_ARGS__) == 1) \ + ? g_error_new_literal(NM_UTILS_ERROR, (error_code), _NM_UTILS_MACRO_FIRST(__VA_ARGS__)) \ + : g_error_new(NM_UTILS_ERROR, (error_code), __VA_ARGS__)) + +/*****************************************************************************/ + +gboolean nm_g_object_set_property(GObject * object, + const char * property_name, + const GValue *value, + GError ** error); + +gboolean nm_g_object_set_property_string(GObject * object, + const char *property_name, + const char *value, + GError ** error); + +gboolean nm_g_object_set_property_string_static(GObject * object, + const char *property_name, + const char *value, + GError ** error); + +gboolean nm_g_object_set_property_string_take(GObject * object, + const char *property_name, + char * value, + GError ** error); + +gboolean nm_g_object_set_property_boolean(GObject * object, + const char *property_name, + gboolean value, + GError ** error); + +gboolean nm_g_object_set_property_char(GObject * object, + const char *property_name, + gint8 value, + GError ** error); + +gboolean nm_g_object_set_property_uchar(GObject * object, + const char *property_name, + guint8 value, + GError ** error); + +gboolean +nm_g_object_set_property_int(GObject *object, const char *property_name, int value, GError **error); + +gboolean nm_g_object_set_property_int64(GObject * object, + const char *property_name, + gint64 value, + GError ** error); + +gboolean nm_g_object_set_property_uint(GObject * object, + const char *property_name, + guint value, + GError ** error); + +gboolean nm_g_object_set_property_uint64(GObject * object, + const char *property_name, + guint64 value, + GError ** error); + +gboolean nm_g_object_set_property_flags(GObject * object, + const char *property_name, + GType gtype, + guint value, + GError ** error); + +gboolean nm_g_object_set_property_enum(GObject * object, + const char *property_name, + GType gtype, + int value, + GError ** error); + +GParamSpec *nm_g_object_class_find_property_from_gtype(GType gtype, const char *property_name); + +/*****************************************************************************/ + +#define _NM_G_PARAM_SPEC_CAST(param_spec, _value_type, _c_type) \ + ({ \ + const GParamSpec *const _param_spec = (param_spec); \ + \ + nm_assert(!_param_spec || _param_spec->value_type == (_value_type)); \ + ((const _c_type *) _param_spec); \ + }) + +#define NM_G_PARAM_SPEC_CAST_BOOLEAN(param_spec) \ + _NM_G_PARAM_SPEC_CAST(param_spec, G_TYPE_BOOLEAN, GParamSpecBoolean) +#define NM_G_PARAM_SPEC_CAST_UINT(param_spec) \ + _NM_G_PARAM_SPEC_CAST(param_spec, G_TYPE_UINT, GParamSpecUInt) +#define NM_G_PARAM_SPEC_CAST_UINT64(param_spec) \ + _NM_G_PARAM_SPEC_CAST(param_spec, G_TYPE_UINT64, GParamSpecUInt64) + +#define NM_G_PARAM_SPEC_GET_DEFAULT_BOOLEAN(param_spec) \ + (NM_G_PARAM_SPEC_CAST_BOOLEAN(NM_ENSURE_NOT_NULL(param_spec))->default_value) +#define NM_G_PARAM_SPEC_GET_DEFAULT_UINT(param_spec) \ + (NM_G_PARAM_SPEC_CAST_UINT(NM_ENSURE_NOT_NULL(param_spec))->default_value) +#define NM_G_PARAM_SPEC_GET_DEFAULT_UINT64(param_spec) \ + (NM_G_PARAM_SPEC_CAST_UINT64(NM_ENSURE_NOT_NULL(param_spec))->default_value) + +/*****************************************************************************/ + +GType nm_g_type_find_implementing_class_for_property(GType gtype, const char *pname); + +/*****************************************************************************/ + +typedef enum { + NM_UTILS_STR_UTF8_SAFE_FLAG_NONE = 0, + + /* This flag only has an effect during escaping. */ + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL = 0x0001, + + /* This flag only has an effect during escaping. */ + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII = 0x0002, + + /* This flag only has an effect during escaping to ensure we + * don't leak secrets in memory. Note that during unescape we + * know the maximum result size from the beginning, and no + * reallocation happens. Thus, unescape always avoids leaking + * secrets already. */ + NM_UTILS_STR_UTF8_SAFE_FLAG_SECRET = 0x0004, + + /* This flag only has an effect during unescaping. It means + * that non-escaped whitespaces (g_ascii_isspace()) will be + * stripped from the front and end of the string. Note that + * this flag is only useful for gracefully accepting user input + * with spaces. With this flag, escape and unescape may no longer + * yield the original input. */ + NM_UTILS_STR_UTF8_SAFE_UNESCAPE_STRIP_SPACES = 0x0008, +} NMUtilsStrUtf8SafeFlags; + +const char *nm_utils_buf_utf8safe_escape(gconstpointer buf, + gssize buflen, + NMUtilsStrUtf8SafeFlags flags, + char ** to_free); +char * +nm_utils_buf_utf8safe_escape_cp(gconstpointer buf, gssize buflen, NMUtilsStrUtf8SafeFlags flags); +const char * +nm_utils_buf_utf8safe_escape_bytes(GBytes *bytes, NMUtilsStrUtf8SafeFlags flags, char **to_free); +gconstpointer nm_utils_buf_utf8safe_unescape(const char * str, + NMUtilsStrUtf8SafeFlags flags, + gsize * out_len, + gpointer * to_free); + +const char * +nm_utils_str_utf8safe_escape(const char *str, NMUtilsStrUtf8SafeFlags flags, char **to_free); +const char * +nm_utils_str_utf8safe_unescape(const char *str, NMUtilsStrUtf8SafeFlags flags, char **to_free); + +char *nm_utils_str_utf8safe_escape_cp(const char *str, NMUtilsStrUtf8SafeFlags flags); +char *nm_utils_str_utf8safe_unescape_cp(const char *str, NMUtilsStrUtf8SafeFlags flags); + +char *nm_utils_str_utf8safe_escape_take(char *str, NMUtilsStrUtf8SafeFlags flags); + +GVariant *nm_g_variant_singleton_u_0(void); + +static inline void +nm_g_variant_unref_floating(GVariant *var) +{ + /* often a function wants to keep a reference to an input variant. + * It uses g_variant_ref_sink() to either increase the ref-count, + * or take ownership of a possibly floating reference. + * + * If the function doesn't actually want to do anything with the + * input variant, it still must make sure that a passed in floating + * reference is consumed. Hence, this helper which: + * + * - does nothing if @var is not floating + * - unrefs (consumes) @var if it is floating. */ + if (g_variant_is_floating(var)) + g_variant_unref(var); +} + +#define nm_g_variant_lookup(dictionary, ...) \ + ({ \ + GVariant *const _dictionary = (dictionary); \ + \ + (_dictionary && g_variant_lookup(_dictionary, __VA_ARGS__)); \ + }) + +static inline GVariant * +nm_g_variant_lookup_value(GVariant *dictionary, const char *key, const GVariantType *expected_type) +{ + return dictionary ? g_variant_lookup_value(dictionary, key, expected_type) : NULL; +} + +static inline gboolean +nm_g_variant_is_of_type(GVariant *value, const GVariantType *type) +{ + return value && g_variant_is_of_type(value, type); +} + +static inline GVariant * +nm_g_variant_new_ay_inaddr(int addr_family, gconstpointer addr) +{ + return g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, + addr ?: &nm_ip_addr_zero, + nm_utils_addr_family_to_size(addr_family), + 1); +} + +static inline GVariant * +nm_g_variant_new_ay_in4addr(in_addr_t addr) +{ + return nm_g_variant_new_ay_inaddr(AF_INET, &addr); +} + +static inline GVariant * +nm_g_variant_new_ay_in6addr(const struct in6_addr *addr) +{ + return nm_g_variant_new_ay_inaddr(AF_INET6, addr); +} + +static inline void +nm_g_variant_builder_add_sv(GVariantBuilder *builder, const char *key, GVariant *val) +{ + g_variant_builder_add(builder, "{sv}", key, val); +} + +static inline void +nm_g_variant_builder_add_sv_bytearray(GVariantBuilder *builder, + const char * key, + const guint8 * arr, + gsize len) +{ + g_variant_builder_add(builder, + "{sv}", + key, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, arr, len, 1)); +} + +static inline void +nm_g_variant_builder_add_sv_uint32(GVariantBuilder *builder, const char *key, guint32 val) +{ + nm_g_variant_builder_add_sv(builder, key, g_variant_new_uint32(val)); +} + +static inline void +nm_g_variant_builder_add_sv_str(GVariantBuilder *builder, const char *key, const char *str) +{ + nm_g_variant_builder_add_sv(builder, key, g_variant_new_string(str)); +} + +static inline void +nm_g_source_destroy_and_unref(GSource *source) +{ + g_source_destroy(source); + g_source_unref(source); +} + +#define nm_clear_g_source_inst(ptr) (nm_clear_pointer((ptr), nm_g_source_destroy_and_unref)) + +NM_AUTO_DEFINE_FCN0(GSource *, _nm_auto_destroy_and_unref_gsource, nm_g_source_destroy_and_unref); +#define nm_auto_destroy_and_unref_gsource nm_auto(_nm_auto_destroy_and_unref_gsource) + +NM_AUTO_DEFINE_FCN0(GMainContext *, _nm_auto_pop_gmaincontext, g_main_context_pop_thread_default); +#define nm_auto_pop_gmaincontext nm_auto(_nm_auto_pop_gmaincontext) + +static inline gboolean +nm_source_func_unref_gobject(gpointer user_data) +{ + nm_assert(G_IS_OBJECT(user_data)); + g_object_unref(user_data); + return G_SOURCE_REMOVE; +} + +GSource *nm_g_idle_source_new(int priority, + GSourceFunc func, + gpointer user_data, + GDestroyNotify destroy_notify); + +GSource *nm_g_timeout_source_new(guint timeout_msec, + int priority, + GSourceFunc func, + gpointer user_data, + GDestroyNotify destroy_notify); + +GSource *nm_g_timeout_source_new_seconds(guint timeout_sec, + int priority, + GSourceFunc func, + gpointer user_data, + GDestroyNotify destroy_notify); + +GSource * + nm_g_unix_fd_source_new(int fd, + GIOCondition io_condition, + int priority, + gboolean (*source_func)(int fd, GIOCondition condition, gpointer user_data), + gpointer user_data, + GDestroyNotify destroy_notify); +GSource *nm_g_unix_signal_source_new(int signum, + int priority, + GSourceFunc handler, + gpointer user_data, + GDestroyNotify notify); + +static inline GSource * +nm_g_source_attach(GSource *source, GMainContext *context) +{ + g_source_attach(source, context); + return source; +} + +static inline GSource * +nm_g_idle_add_source(GSourceFunc func, gpointer user_data) +{ + /* G convenience function to attach a new timeout source to the default GMainContext. + * In that sense it's very similar to g_idle_add() except that it returns a + * reference to the new source. */ + return nm_g_source_attach(nm_g_idle_source_new(G_PRIORITY_DEFAULT, func, user_data, NULL), + NULL); +} + +static inline GSource * +nm_g_timeout_add_source(guint timeout_msec, GSourceFunc func, gpointer user_data) +{ + /* G convenience function to attach a new timeout source to the default GMainContext. + * In that sense it's very similar to g_timeout_add() except that it returns a + * reference to the new source. */ + return nm_g_source_attach( + nm_g_timeout_source_new(timeout_msec, G_PRIORITY_DEFAULT, func, user_data, NULL), + NULL); +} + +static inline GSource * +nm_g_timeout_add_source_seconds(guint timeout_sec, GSourceFunc func, gpointer user_data) +{ + /* G convenience function to attach a new timeout source to the default GMainContext. + * In that sense it's very similar to g_timeout_add_seconds() except that it returns a + * reference to the new source. */ + return nm_g_source_attach( + nm_g_timeout_source_new_seconds(timeout_sec, G_PRIORITY_DEFAULT, func, user_data, NULL), + NULL); +} + +static inline GSource * +nm_g_timeout_add_source_approx(guint timeout_msec, + guint timeout_sec_threshold, + GSourceFunc func, + gpointer user_data) +{ + GSource *source; + + /* If timeout_msec is larger or equal than a threshold, then we use g_timeout_source_new_seconds() + * instead. */ + if (timeout_msec / 1000u >= timeout_sec_threshold) + source = nm_g_timeout_source_new_seconds(timeout_msec / 1000u, + G_PRIORITY_DEFAULT, + func, + user_data, + NULL); + else + source = nm_g_timeout_source_new(timeout_msec, G_PRIORITY_DEFAULT, func, user_data, NULL); + return nm_g_source_attach(source, NULL); +} + +NM_AUTO_DEFINE_FCN0(GMainContext *, _nm_auto_unref_gmaincontext, g_main_context_unref); +#define nm_auto_unref_gmaincontext nm_auto(_nm_auto_unref_gmaincontext) + +static inline GMainContext * +nm_g_main_context_push_thread_default(GMainContext *context) +{ + /* This function is to work together with nm_auto_pop_gmaincontext. */ + if (G_UNLIKELY(!context)) + context = g_main_context_default(); + g_main_context_push_thread_default(context); + return context; +} + +static inline gboolean +nm_g_main_context_is_thread_default(GMainContext *context) +{ + GMainContext *cur_context; + + cur_context = g_main_context_get_thread_default(); + if (cur_context == context) + return TRUE; + + if (G_UNLIKELY(!cur_context)) + cur_context = g_main_context_default(); + else if (G_UNLIKELY(!context)) + context = g_main_context_default(); + else + return FALSE; + + return (cur_context == context); +} + +static inline GMainContext * +nm_g_main_context_push_thread_default_if_necessary(GMainContext *context) +{ + GMainContext *cur_context; + + cur_context = g_main_context_get_thread_default(); + if (cur_context == context) + return NULL; + + if (G_UNLIKELY(!cur_context)) { + cur_context = g_main_context_default(); + if (cur_context == context) + return NULL; + } else if (G_UNLIKELY(!context)) { + context = g_main_context_default(); + if (cur_context == context) + return NULL; + } + + g_main_context_push_thread_default(context); + return context; +} + +/*****************************************************************************/ + +static inline int +nm_utf8_collate0(const char *a, const char *b) +{ + if (!a) + return !b ? 0 : -1; + if (!b) + return 1; + return g_utf8_collate(a, b); +} + +int nm_strcmp_with_data(gconstpointer a, gconstpointer b, gpointer user_data); +int nm_strcmp_p_with_data(gconstpointer a, gconstpointer b, gpointer user_data); +int nm_strcmp0_p_with_data(gconstpointer a, gconstpointer b, gpointer user_data); +int nm_strcmp_ascii_case_with_data(gconstpointer a, gconstpointer b, gpointer user_data); +int nm_cmp_uint32_p_with_data(gconstpointer p_a, gconstpointer p_b, gpointer user_data); +int nm_cmp_int2ptr_p_with_data(gconstpointer p_a, gconstpointer p_b, gpointer user_data); + +/*****************************************************************************/ + +typedef struct { + const char *name; +} NMUtilsNamedEntry; + +typedef struct { + union { + NMUtilsNamedEntry named_entry; + const char * name; + char * name_mutable; + }; + union { + const char *value_str; + char * value_str_mutable; + gpointer value_ptr; + }; +} NMUtilsNamedValue; + +#define NM_UTILS_NAMED_VALUE_INIT(n, v) \ + { \ + .name = (n), .value_ptr = (v) \ + } + +NMUtilsNamedValue * +nm_utils_named_values_from_strdict_full(GHashTable * hash, + guint * out_len, + GCompareDataFunc compare_func, + gpointer user_data, + NMUtilsNamedValue * provided_buffer, + guint provided_buffer_len, + NMUtilsNamedValue **out_allocated_buffer); + +#define nm_utils_named_values_from_strdict(hash, out_len, array, out_allocated_buffer) \ + nm_utils_named_values_from_strdict_full((hash), \ + (out_len), \ + nm_strcmp_p_with_data, \ + NULL, \ + (array), \ + G_N_ELEMENTS(array), \ + (out_allocated_buffer)) + +gssize nm_utils_named_value_list_find(const NMUtilsNamedValue *arr, + gsize len, + const char * name, + gboolean sorted); + +gboolean nm_utils_named_value_list_is_sorted(const NMUtilsNamedValue *arr, + gsize len, + gboolean accept_duplicates, + GCompareDataFunc compare_func, + gpointer user_data); + +void nm_utils_named_value_list_sort(NMUtilsNamedValue *arr, + gsize len, + GCompareDataFunc compare_func, + gpointer user_data); + +void nm_utils_named_value_clear_with_g_free(NMUtilsNamedValue *val); + +/*****************************************************************************/ + +gpointer *nm_utils_hash_keys_to_array(GHashTable * hash, + GCompareDataFunc compare_func, + gpointer user_data, + guint * out_len); + +gpointer *nm_utils_hash_values_to_array(GHashTable * hash, + GCompareDataFunc compare_func, + gpointer user_data, + guint * out_len); + +static inline const char ** +nm_utils_strdict_get_keys(const GHashTable *hash, gboolean sorted, guint *out_length) +{ + return (const char **) nm_utils_hash_keys_to_array((GHashTable *) hash, + sorted ? nm_strcmp_p_with_data : NULL, + NULL, + out_length); +} + +gboolean nm_utils_hashtable_equal(const GHashTable *a, + const GHashTable *b, + gboolean treat_null_as_empty, + GEqualFunc equal_func); + +gboolean nm_utils_hashtable_cmp_equal(const GHashTable *a, + const GHashTable *b, + GCompareDataFunc cmp_values, + gpointer user_data); + +static inline gboolean +nm_utils_hashtable_same_keys(const GHashTable *a, const GHashTable *b) +{ + return nm_utils_hashtable_cmp_equal(a, b, NULL, NULL); +} + +int nm_utils_hashtable_cmp(const GHashTable *a, + const GHashTable *b, + gboolean do_fast_precheck, + GCompareDataFunc cmp_keys, + GCompareDataFunc cmp_values, + gpointer user_data); + +char **nm_utils_strv_make_deep_copied(const char **strv); + +char **nm_utils_strv_make_deep_copied_n(const char **strv, gsize len); + +static inline char ** +nm_utils_strv_make_deep_copied_nonnull(const char **strv) +{ + return nm_utils_strv_make_deep_copied(strv) ?: g_new0(char *, 1); +} + +char **_nm_utils_strv_dup(const char *const *strv, gssize len, gboolean deep_copied); + +#define nm_utils_strv_dup(strv, len, deep_copied) \ + _nm_utils_strv_dup(NM_CAST_STRV_CC(strv), (len), (deep_copied)) + +const char **_nm_utils_strv_dup_packed(const char *const *strv, gssize len); + +#define nm_utils_strv_dup_packed(strv, len) _nm_utils_strv_dup_packed(NM_CAST_STRV_CC(strv), (len)) + +/*****************************************************************************/ + +GSList *nm_utils_g_slist_find_str(const GSList *list, const char *needle); + +int nm_utils_g_slist_strlist_cmp(const GSList *a, const GSList *b); + +char *nm_utils_g_slist_strlist_join(const GSList *a, const char *separator); + +/*****************************************************************************/ + +static inline guint +nm_g_array_len(const GArray *arr) +{ + return arr ? arr->len : 0u; +} + +static inline void +nm_g_array_unref(GArray *arr) +{ + if (arr) + g_array_unref(arr); +} + +#define nm_g_array_append_new(arr, type) \ + ({ \ + GArray *const _arr = (arr); \ + guint _len; \ + \ + nm_assert(_arr); \ + _len = _arr->len; \ + nm_assert(_len < G_MAXUINT); \ + g_array_set_size(_arr, _len + 1u); \ + &g_array_index(arr, type, _len); \ + }) + +/*****************************************************************************/ + +static inline GPtrArray * +nm_g_ptr_array_ref(GPtrArray *arr) +{ + return arr ? g_ptr_array_ref(arr) : NULL; +} + +static inline void +nm_g_ptr_array_unref(GPtrArray *arr) +{ + if (arr) + g_ptr_array_unref(arr); +} + +#define nm_g_ptr_array_set(pdst, val) \ + ({ \ + GPtrArray **_pdst = (pdst); \ + GPtrArray * _val = (val); \ + gboolean _changed = FALSE; \ + \ + nm_assert(_pdst); \ + \ + if (*_pdst != _val) { \ + _nm_unused gs_unref_ptrarray GPtrArray *_old = *_pdst; \ + \ + *_pdst = nm_g_ptr_array_ref(_val); \ + _changed = TRUE; \ + } \ + _changed; \ + }) + +#define nm_g_ptr_array_set_take(pdst, val) \ + ({ \ + GPtrArray **_pdst = (pdst); \ + GPtrArray * _val = (val); \ + gboolean _changed = FALSE; \ + \ + nm_assert(_pdst); \ + \ + if (*_pdst != _val) { \ + _nm_unused gs_unref_ptrarray GPtrArray *_old = *_pdst; \ + \ + *_pdst = _val; \ + _changed = TRUE; \ + } else { \ + nm_g_ptr_array_unref(_val); \ + } \ + _changed; \ + }) + +static inline guint +nm_g_ptr_array_len(const GPtrArray *arr) +{ + return arr ? arr->len : 0u; +} + +static inline gpointer * +nm_g_ptr_array_pdata(const GPtrArray *arr) +{ + return arr ? arr->pdata : NULL; +} + +GPtrArray *_nm_g_ptr_array_copy(GPtrArray * array, + GCopyFunc func, + gpointer user_data, + GDestroyNotify element_free_func); + +/** + * nm_g_ptr_array_copy: + * @array: the #GPtrArray to clone. + * @func: the copy function. + * @user_data: the user data for the copy function + * @element_free_func: the free function of the elements. @array MUST have + * the same element_free_func. This argument is only used on older + * glib, that doesn't support g_ptr_array_copy(). + * + * This is a replacement for g_ptr_array_copy(), which is not available + * before glib 2.62. Since GPtrArray does not allow to access the internal + * element_free_func, we cannot add a compatibility implementation of g_ptr_array_copy() + * and the user must provide a suitable destroy function. + * + * Note that the @element_free_func MUST correspond to free function set in @array. + */ +#if GLIB_CHECK_VERSION(2, 62, 0) + #define nm_g_ptr_array_copy(array, func, user_data, element_free_func) \ + ({ \ + _nm_unused GDestroyNotify const _element_free_func = (element_free_func); \ + \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; \ + g_ptr_array_copy((array), (func), (user_data)); \ + G_GNUC_END_IGNORE_DEPRECATIONS; \ + }) +#else + #define nm_g_ptr_array_copy(array, func, user_data, element_free_func) \ + _nm_g_ptr_array_copy((array), (func), (user_data), (element_free_func)) +#endif + +/*****************************************************************************/ + +static inline GHashTable * +nm_g_hash_table_ref(GHashTable *hash) +{ + return hash ? g_hash_table_ref(hash) : NULL; +} + +static inline void +nm_g_hash_table_unref(GHashTable *hash) +{ + if (hash) + g_hash_table_unref(hash); +} + +static inline guint +nm_g_hash_table_size(GHashTable *hash) +{ + return hash ? g_hash_table_size(hash) : 0u; +} + +static inline gpointer +nm_g_hash_table_lookup(GHashTable *hash, gconstpointer key) +{ + return hash ? g_hash_table_lookup(hash, key) : NULL; +} + +static inline gboolean +nm_g_hash_table_contains(GHashTable *hash, gconstpointer key) +{ + return hash ? g_hash_table_contains(hash, key) : FALSE; +} + +static inline gboolean +nm_g_hash_table_remove(GHashTable *hash, gconstpointer key) +{ + return hash ? g_hash_table_remove(hash, key) : FALSE; +} + +/*****************************************************************************/ + +gssize nm_utils_ptrarray_find_binary_search(gconstpointer * list, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data); + +gssize nm_utils_ptrarray_find_binary_search_range(gconstpointer * list, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data, + gssize * out_idx_first, + gssize * out_idx_last); + +#define nm_utils_strv_find_binary_search(strv, len, needle) \ + ({ \ + const char *const *const _strv = NM_CAST_STRV_CC(strv); \ + const gsize _len = (len); \ + const char *const _needle = (needle); \ + \ + nm_assert(_len == 0 || _strv); \ + nm_assert(_needle); \ + \ + nm_utils_ptrarray_find_binary_search((gconstpointer *) _strv, \ + _len, \ + _needle, \ + nm_strcmp_with_data, \ + NULL); \ + }) + +gssize nm_utils_array_find_binary_search(gconstpointer list, + gsize elem_size, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data); + +gssize nm_utils_ptrarray_find_first(gconstpointer *list, gssize len, gconstpointer needle); + +/*****************************************************************************/ + +void _nm_utils_strv_sort(const char **strv, gssize len); +#define nm_utils_strv_sort(strv, len) _nm_utils_strv_sort(NM_CAST_STRV_MC(strv), len) + +int +_nm_utils_strv_cmp_n(const char *const *strv1, gssize len1, const char *const *strv2, gssize len2); + +#define nm_utils_strv_cmp_n(strv1, len1, strv2, len2) \ + _nm_utils_strv_cmp_n(NM_CAST_STRV_CC(strv1), (len1), NM_CAST_STRV_CC(strv2), (len2)) + +#define nm_utils_strv_equal(strv1, strv2) (nm_utils_strv_cmp_n((strv1), -1, (strv2), -1) == 0) + +/*****************************************************************************/ + +#define NM_UTILS_NSEC_PER_SEC ((gint64) 1000000000) +#define NM_UTILS_USEC_PER_SEC ((gint64) 1000000) +#define NM_UTILS_MSEC_PER_SEC ((gint64) 1000) +#define NM_UTILS_NSEC_PER_MSEC ((gint64) 1000000) + +static inline gint64 +NM_UTILS_NSEC_TO_MSEC_CEIL(gint64 nsec) +{ + return (nsec + (NM_UTILS_NSEC_PER_MSEC - 1)) / NM_UTILS_NSEC_PER_MSEC; +} + +/*****************************************************************************/ + +int nm_utils_fd_wait_for_event(int fd, int event, gint64 timeout_nsec); +ssize_t nm_utils_fd_read_loop(int fd, void *buf, size_t nbytes, bool do_poll); +int nm_utils_fd_read_loop_exact(int fd, void *buf, size_t nbytes, bool do_poll); + +/*****************************************************************************/ + +#define NM_DEFINE_GDBUS_ARG_INFO_FULL(name_, ...) \ + ((GDBusArgInfo *) (&((const GDBusArgInfo){.ref_count = -1, .name = name_, __VA_ARGS__}))) + +#define NM_DEFINE_GDBUS_ARG_INFO(name_, a_signature) \ + NM_DEFINE_GDBUS_ARG_INFO_FULL(name_, .signature = a_signature, ) + +#define NM_DEFINE_GDBUS_ARG_INFOS(...) \ + ((GDBusArgInfo **) ((const GDBusArgInfo *[]){ \ + __VA_ARGS__ NULL, \ + })) + +#define NM_DEFINE_GDBUS_PROPERTY_INFO(name_, ...) \ + ((GDBusPropertyInfo *) (&( \ + (const GDBusPropertyInfo){.ref_count = -1, .name = name_, __VA_ARGS__}))) + +#define NM_DEFINE_GDBUS_PROPERTY_INFO_READABLE(name_, m_signature) \ + NM_DEFINE_GDBUS_PROPERTY_INFO(name_, \ + .signature = m_signature, \ + .flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE, ) + +#define NM_DEFINE_GDBUS_PROPERTY_INFOS(...) \ + ((GDBusPropertyInfo **) ((const GDBusPropertyInfo *[]){ \ + __VA_ARGS__ NULL, \ + })) + +#define NM_DEFINE_GDBUS_SIGNAL_INFO_INIT(name_, ...) \ + { \ + .ref_count = -1, .name = name_, __VA_ARGS__ \ + } + +#define NM_DEFINE_GDBUS_SIGNAL_INFO(name_, ...) \ + ((GDBusSignalInfo *) (&( \ + (const GDBusSignalInfo) NM_DEFINE_GDBUS_SIGNAL_INFO_INIT(name_, __VA_ARGS__)))) + +#define NM_DEFINE_GDBUS_SIGNAL_INFOS(...) \ + ((GDBusSignalInfo **) ((const GDBusSignalInfo *[]){ \ + __VA_ARGS__ NULL, \ + })) + +#define NM_DEFINE_GDBUS_METHOD_INFO_INIT(name_, ...) \ + { \ + .ref_count = -1, .name = name_, __VA_ARGS__ \ + } + +#define NM_DEFINE_GDBUS_METHOD_INFO(name_, ...) \ + ((GDBusMethodInfo *) (&( \ + (const GDBusMethodInfo) NM_DEFINE_GDBUS_METHOD_INFO_INIT(name_, __VA_ARGS__)))) + +#define NM_DEFINE_GDBUS_METHOD_INFOS(...) \ + ((GDBusMethodInfo **) ((const GDBusMethodInfo *[]){ \ + __VA_ARGS__ NULL, \ + })) + +#define NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(name_, ...) \ + { \ + .ref_count = -1, .name = name_, __VA_ARGS__ \ + } + +#define NM_DEFINE_GDBUS_INTERFACE_INFO(name_, ...) \ + ((GDBusInterfaceInfo *) (&( \ + (const GDBusInterfaceInfo) NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(name_, __VA_ARGS__)))) + +#define NM_DEFINE_GDBUS_INTERFACE_VTABLE(...) \ + ((GDBusInterfaceVTable *) (&((const GDBusInterfaceVTable){__VA_ARGS__}))) + +/*****************************************************************************/ + +guint64 nm_utils_get_start_time_for_pid(pid_t pid, char *out_state, pid_t *out_ppid); + +static inline gboolean +nm_utils_process_state_is_dead(char pstate) +{ + /* "/proc/[pid]/stat" returns a state as the 3rd fields (see `man 5 proc`). + * Some of these states indicate the process is effectively dead (or a zombie). + */ + return NM_IN_SET(pstate, 'Z', 'x', 'X'); +} + +/*****************************************************************************/ + +typedef struct _NMUtilsUserData NMUtilsUserData; + +NMUtilsUserData *_nm_utils_user_data_pack(int nargs, gconstpointer *args); + +#define nm_utils_user_data_pack(...) \ + _nm_utils_user_data_pack(NM_NARG(__VA_ARGS__), (gconstpointer[]){__VA_ARGS__}) + +void _nm_utils_user_data_unpack(NMUtilsUserData *user_data, int nargs, ...); + +#define nm_utils_user_data_unpack(user_data, ...) \ + _nm_utils_user_data_unpack(user_data, NM_NARG(__VA_ARGS__), __VA_ARGS__) + +/*****************************************************************************/ + +typedef void (*NMUtilsInvokeOnIdleCallback)(gpointer user_data, GCancellable *cancellable); + +void nm_utils_invoke_on_idle(GCancellable * cancellable, + NMUtilsInvokeOnIdleCallback callback, + gpointer callback_user_data); + +void nm_utils_invoke_on_timeout(guint timeout_msec, + GCancellable * cancellable, + NMUtilsInvokeOnIdleCallback callback, + gpointer callback_user_data); + +/*****************************************************************************/ + +GSource *nm_utils_g_main_context_create_integrate_source(GMainContext *internal); + +/*****************************************************************************/ + +static inline GPtrArray * +nm_strv_ptrarray_ensure(GPtrArray **p_arr) +{ + nm_assert(p_arr); + + if (G_UNLIKELY(!*p_arr)) + *p_arr = g_ptr_array_new_with_free_func(g_free); + + return *p_arr; +} + +static inline const char *const * +nm_strv_ptrarray_get_unsafe(GPtrArray *arr, guint *out_len) +{ + /* warning: the GPtrArray is not NULL terminated. So, it + * isn't really a strv array (sorry the misnomer). That's why + * the function is potentially "unsafe" and you must provide a + * out_len parameter. */ + if (!arr || arr->len == 0) { + *out_len = 0; + return NULL; + } + *out_len = arr->len; + return (const char *const *) arr->pdata; +} + +static inline GPtrArray * +nm_strv_ptrarray_clone(const GPtrArray *src, gboolean null_if_empty) +{ + if (!src || (null_if_empty && src->len == 0)) + return NULL; + return nm_g_ptr_array_copy((GPtrArray *) src, nm_copy_func_g_strdup, NULL, g_free); +} + +static inline void +nm_strv_ptrarray_add_string_take(GPtrArray *cmd, char *str) +{ + nm_assert(cmd); + nm_assert(str); + + g_ptr_array_add(cmd, str); +} + +static inline void +nm_strv_ptrarray_add_string_dup(GPtrArray *cmd, const char *str) +{ + nm_strv_ptrarray_add_string_take(cmd, g_strdup(str)); +} + +#define nm_strv_ptrarray_add_string_concat(cmd, ...) \ + nm_strv_ptrarray_add_string_take((cmd), g_strconcat(__VA_ARGS__, NULL)) + +#define nm_strv_ptrarray_add_string_printf(cmd, ...) \ + nm_strv_ptrarray_add_string_take((cmd), g_strdup_printf(__VA_ARGS__)) + +#define nm_strv_ptrarray_add_int(cmd, val) \ + nm_strv_ptrarray_add_string_take((cmd), nm_strdup_int(val)) + +static inline void +nm_strv_ptrarray_take_gstring(GPtrArray *cmd, GString **gstr) +{ + nm_assert(gstr && *gstr); + + nm_strv_ptrarray_add_string_take(cmd, g_string_free(g_steal_pointer(gstr), FALSE)); +} + +static inline gssize +nm_strv_ptrarray_find_first(const GPtrArray *strv, const char *str) +{ + if (!strv) + return -1; + return nm_utils_strv_find_first((char **) strv->pdata, strv->len, str); +} + +static inline gboolean +nm_strv_ptrarray_contains(const GPtrArray *strv, const char *str) +{ + return nm_strv_ptrarray_find_first(strv, str) >= 0; +} + +static inline int +nm_strv_ptrarray_cmp(const GPtrArray *a, const GPtrArray *b) +{ + /* nm_utils_strv_cmp_n() will treat NULL and empty arrays the same. + * That means, an empty strv array can both be represented by NULL + * and an array of length zero. + * If you need to distinguish between these case, do that yourself. */ + return nm_utils_strv_cmp_n((const char *const *) nm_g_ptr_array_pdata(a), + nm_g_ptr_array_len(a), + (const char *const *) nm_g_ptr_array_pdata(b), + nm_g_ptr_array_len(b)); +} + +/*****************************************************************************/ + +int nm_utils_getpagesize(void); + +/*****************************************************************************/ + +extern const char _nm_hexchar_table_lower[16]; +extern const char _nm_hexchar_table_upper[16]; + +static inline char +nm_hexchar(int x, gboolean upper_case) +{ + return upper_case ? _nm_hexchar_table_upper[x & 15] : _nm_hexchar_table_lower[x & 15]; +} + +char *nm_utils_bin2hexstr_full(gconstpointer addr, + gsize length, + char delimiter, + gboolean upper_case, + char * out); + +#define nm_utils_bin2hexstr_a(addr, length, delimiter, upper_case, str_to_free) \ + ({ \ + gconstpointer _addr = (addr); \ + gsize _length = (length); \ + char _delimiter = (delimiter); \ + char ** _str_to_free = (str_to_free); \ + char * _s; \ + gsize _s_len; \ + \ + nm_assert(_str_to_free); \ + \ + _s_len = _length == 0 ? 1u : (_delimiter == '\0' ? _length * 2u + 1u : _length * 3u); \ + if (_s_len < 100) \ + _s = g_alloca(_s_len); \ + else { \ + _s = g_malloc(_s_len); \ + *_str_to_free = _s; \ + } \ + nm_utils_bin2hexstr_full(_addr, _length, _delimiter, (upper_case), _s); \ + }) + +static inline const char * +nm_ether_addr_to_string(const NMEtherAddr *ether_addr, char sbuf[static(sizeof(NMEtherAddr) * 3)]) +{ + nm_assert(ether_addr); + nm_assert(sbuf); + + return nm_utils_bin2hexstr_full(ether_addr, sizeof(NMEtherAddr), ':', TRUE, sbuf); +} + +#define nm_ether_addr_to_string_a(ether_addr) \ + nm_ether_addr_to_string((ether_addr), g_alloca(sizeof(NMEtherAddr) * 3)) + +guint8 *nm_utils_hexstr2bin_full(const char *hexstr, + gboolean allow_0x_prefix, + gboolean delimiter_required, + gboolean hexdigit_pairs_required, + const char *delimiter_candidates, + gsize required_len, + guint8 * buffer, + gsize buffer_len, + gsize * out_len); + +#define nm_utils_hexstr2bin_buf(hexstr, \ + allow_0x_prefix, \ + delimiter_required, \ + delimiter_candidates, \ + buffer) \ + nm_utils_hexstr2bin_full((hexstr), \ + (allow_0x_prefix), \ + (delimiter_required), \ + FALSE, \ + (delimiter_candidates), \ + G_N_ELEMENTS(buffer), \ + (buffer), \ + G_N_ELEMENTS(buffer), \ + NULL) + +guint8 *nm_utils_hexstr2bin_alloc(const char *hexstr, + gboolean allow_0x_prefix, + gboolean delimiter_required, + const char *delimiter_candidates, + gsize required_len, + gsize * out_len); + +/** + * _nm_utils_hwaddr_aton: + * @asc: the ASCII representation of a hardware address + * @buffer: buffer to store the result into. Must have + * at least a size of @buffer_length. + * @buffer_length: the length of the input buffer @buffer. + * The result must fit into that buffer, otherwise + * the function fails and returns %NULL. + * @out_length: the output length in case of success. + * + * Parses @asc and converts it to binary form in @buffer. + * Bytes in @asc can be separated by colons (:), or hyphens (-), but not mixed. + * + * It is like nm_utils_hwaddr_aton(), but contrary to that it + * can parse addresses of any length. That is, you don't need + * to know the length before-hand. + * + * Return value: @buffer, or %NULL if @asc couldn't be parsed. + */ +static inline guint8 * +_nm_utils_hwaddr_aton(const char *asc, gpointer buffer, gsize buffer_length, gsize *out_length) +{ + g_return_val_if_fail(asc, NULL); + g_return_val_if_fail(buffer, NULL); + g_return_val_if_fail(buffer_length > 0, NULL); + g_return_val_if_fail(out_length, NULL); + + return nm_utils_hexstr2bin_full(asc, + FALSE, + TRUE, + FALSE, + ":-", + 0, + buffer, + buffer_length, + out_length); +} + +static inline guint8 * +_nm_utils_hwaddr_aton_exact(const char *asc, gpointer buffer, gsize buffer_length) +{ + g_return_val_if_fail(asc, NULL); + g_return_val_if_fail(buffer, NULL); + g_return_val_if_fail(buffer_length > 0, NULL); + + return nm_utils_hexstr2bin_full(asc, + FALSE, + TRUE, + FALSE, + ":-", + buffer_length, + buffer, + buffer_length, + NULL); +} + +static inline const char * +_nm_utils_hwaddr_ntoa(gconstpointer addr, + gsize addr_len, + gboolean upper_case, + char * buf, + gsize buf_len) +{ + g_return_val_if_fail(addr, NULL); + g_return_val_if_fail(addr_len > 0, NULL); + g_return_val_if_fail(buf, NULL); + if (buf_len < addr_len * 3) + g_return_val_if_reached(NULL); + + return nm_utils_bin2hexstr_full(addr, addr_len, ':', upper_case, buf); +} + +#define _nm_utils_hwaddr_ntoa_maybe_a(addr, addr_len, buf_to_free) \ + ({ \ + gconstpointer const _addr = (addr); \ + const gsize _addr_len = (addr_len); \ + char **const _buf_to_free = (buf_to_free); \ + \ + nm_utils_bin2hexstr_full( \ + _addr, \ + _addr_len, \ + ':', \ + TRUE, \ + nm_malloc_maybe_a(3 * 20, _addr_len ? (_addr_len * 3u) : 1u, _buf_to_free)); \ + }) + +/*****************************************************************************/ + +#define _NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(fcn_name, \ + value_type, \ + value_type_result, \ + entry_cmd, \ + unknown_val_cmd, \ + get_operator, \ + ...) \ + value_type_result fcn_name(const char *name) \ + { \ + static const struct { \ + const char *name; \ + value_type value; \ + } LIST[] = {__VA_ARGS__}; \ + \ + if (NM_MORE_ASSERT_ONCE(5)) { \ + int i; \ + \ + for (i = 0; i < G_N_ELEMENTS(LIST); i++) { \ + nm_assert(LIST[i].name); \ + if (i > 0) \ + nm_assert(strcmp(LIST[i - 1].name, LIST[i].name) < 0); \ + } \ + } \ + \ + { \ + entry_cmd; \ + } \ + \ + if (G_LIKELY(name)) { \ + G_STATIC_ASSERT(G_N_ELEMENTS(LIST) > 1); \ + G_STATIC_ASSERT(G_N_ELEMENTS(LIST) < G_MAXINT / 2 - 10); \ + int imin = 0; \ + int imax = (G_N_ELEMENTS(LIST) - 1); \ + int imid = (G_N_ELEMENTS(LIST) - 1) / 2; \ + \ + for (;;) { \ + const int cmp = strcmp(LIST[imid].name, name); \ + \ + if (G_UNLIKELY(cmp == 0)) \ + return get_operator(LIST[imid].value); \ + \ + if (cmp < 0) \ + imin = imid + 1; \ + else \ + imax = imid - 1; \ + \ + if (G_UNLIKELY(imin > imax)) \ + break; \ + \ + /* integer overflow cannot happen, because LIST is shorter than G_MAXINT/2. */ \ + imid = (imin + imax) / 2; \ + } \ + } \ + \ + { \ + unknown_val_cmd; \ + } \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +#define NM_UTILS_STRING_TABLE_LOOKUP_STRUCT_DEFINE(fcn_name, \ + result_type, \ + entry_cmd, \ + unknown_val_cmd, \ + ...) \ + _NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(fcn_name, \ + result_type, \ + const result_type *, \ + entry_cmd, \ + unknown_val_cmd, \ + &, \ + __VA_ARGS__) + +#define NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(fcn_name, \ + result_type, \ + entry_cmd, \ + unknown_val_cmd, \ + ...) \ + _NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(fcn_name, \ + result_type, \ + result_type, \ + entry_cmd, \ + unknown_val_cmd, \ + , \ + __VA_ARGS__) + +/*****************************************************************************/ + +static inline GTask * +nm_g_task_new(gpointer source_object, + GCancellable * cancellable, + gpointer source_tag, + GAsyncReadyCallback callback, + gpointer callback_data) +{ + GTask *task; + + task = g_task_new(source_object, cancellable, callback, callback_data); + if (source_tag) + g_task_set_source_tag(task, source_tag); + return task; +} + +static inline gboolean +nm_g_task_is_valid(gpointer task, gpointer source_object, gpointer source_tag) +{ + return g_task_is_valid(task, source_object) && g_task_get_source_tag(task) == source_tag; +} + +guint nm_utils_parse_debug_string(const char *string, const GDebugKey *keys, guint nkeys); + +/*****************************************************************************/ + +static inline gboolean +nm_utils_strdup_reset(char **dst, const char *src) +{ + char *old; + + nm_assert(dst); + + if (nm_streq0(*dst, src)) + return FALSE; + old = *dst; + *dst = g_strdup(src); + g_free(old); + return TRUE; +} + +static inline gboolean +nm_utils_strdup_reset_take(char **dst, char *src) +{ + char *old; + + nm_assert(dst); + nm_assert(src != *dst); + + if (nm_streq0(*dst, src)) { + if (src) + g_free(src); + return FALSE; + } + old = *dst; + *dst = src; + g_free(old); + return TRUE; +} + +void nm_indirect_g_free(gpointer arg); + +/*****************************************************************************/ + +void nm_utils_ifname_cpy(char *dst, const char *name); + +typedef enum { + NMU_IFACE_ANY, + NMU_IFACE_KERNEL, + NMU_IFACE_OVS, + NMU_IFACE_OVS_AND_KERNEL, +} NMUtilsIfaceType; + +gboolean nm_utils_ifname_valid_kernel(const char *name, GError **error); + +gboolean nm_utils_ifname_valid(const char *name, NMUtilsIfaceType type, GError **error); + +/*****************************************************************************/ + +static inline GArray * +nm_strvarray_ensure(GArray **p) +{ + if (!*p) { + *p = g_array_new(TRUE, FALSE, sizeof(char *)); + g_array_set_clear_func(*p, nm_indirect_g_free); + } + return *p; +} + +static inline void +nm_strvarray_add(GArray *array, const char *str) +{ + char *s; + + s = g_strdup(str); + g_array_append_val(array, s); +} + +static inline const char *const * +nm_strvarray_get_strv_non_empty(GArray *arr, guint *length) +{ + if (!arr || arr->len == 0) { + NM_SET_OUT(length, 0); + return NULL; + } + + NM_SET_OUT(length, arr->len); + return &g_array_index(arr, const char *, 0); +} + +static inline const char *const * +nm_strvarray_get_strv(GArray **arr, guint *length) +{ + if (!*arr) { + NM_SET_OUT(length, 0); + return (const char *const *) arr; + } + + NM_SET_OUT(length, (*arr)->len); + return &g_array_index(*arr, const char *, 0); +} + +static inline void +nm_strvarray_set_strv(GArray **array, const char *const *strv) +{ + gs_unref_array GArray *array_old = NULL; + + array_old = g_steal_pointer(array); + + if (!strv || !strv[0]) + return; + + nm_strvarray_ensure(array); + for (; strv[0]; strv++) + nm_strvarray_add(*array, strv[0]); +} + +static inline gboolean +nm_strvarray_remove_first(GArray *strv, const char *needle) +{ + guint i; + + nm_assert(needle); + + if (strv) { + for (i = 0; i < strv->len; i++) { + if (nm_streq(needle, g_array_index(strv, const char *, i))) { + g_array_remove_index(strv, i); + return TRUE; + } + } + } + return FALSE; +} + +/*****************************************************************************/ + +struct _NMVariantAttributeSpec { + char * name; + const GVariantType *type; + bool v4 : 1; + bool v6 : 1; + bool no_value : 1; + bool consumes_rest : 1; + char str_type; +}; + +typedef struct _NMVariantAttributeSpec NMVariantAttributeSpec; + +void _nm_utils_format_variant_attributes_full(GString * str, + const NMUtilsNamedValue * values, + guint num_values, + const NMVariantAttributeSpec *const *spec, + char attr_separator, + char key_value_separator); + +char *_nm_utils_format_variant_attributes(GHashTable * attributes, + const NMVariantAttributeSpec *const *spec, + char attr_separator, + char key_value_separator); + +/*****************************************************************************/ + +gboolean nm_utils_is_localhost(const char *name); + +gboolean nm_utils_is_specific_hostname(const char *name); + +char * nm_utils_uid_to_name(uid_t uid); +gboolean nm_utils_name_to_uid(const char *name, uid_t *out_uid); + +/*****************************************************************************/ + +double nm_utils_exp10(gint16 e); + +/*****************************************************************************/ + +gboolean _nm_utils_is_empty_ssid_arr(const guint8 *ssid, gsize len); +gboolean _nm_utils_is_empty_ssid_gbytes(GBytes *ssid); +char * _nm_utils_ssid_to_string_arr(const guint8 *ssid, gsize len); +char * _nm_utils_ssid_to_string_gbytes(GBytes *ssid); + +/*****************************************************************************/ + +gboolean nm_utils_is_valid_path_component(const char *name); +const char *NM_ASSERT_VALID_PATH_COMPONENT(const char *name); + +#define NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE 100 + +const char * +nm_utils_sysctl_ip_conf_path(int addr_family, char *buf, const char *ifname, const char *property); + +gboolean nm_utils_sysctl_ip_conf_is_path(int addr_family, + const char *path, + const char *ifname, + const char *property); + +#endif /* __NM_SHARED_UTILS_H__ */ diff --git a/src/libnm-glib-aux/nm-str-buf.h b/src/libnm-glib-aux/nm-str-buf.h new file mode 100644 index 0000000..cb0d3fb --- /dev/null +++ b/src/libnm-glib-aux/nm-str-buf.h @@ -0,0 +1,488 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_STR_BUF_H__ +#define __NM_STR_BUF_H__ + +#include "nm-shared-utils.h" +#include "nm-secret-utils.h" + +/*****************************************************************************/ + +/* NMStrBuf is not unlike GString. The main difference is that it can use + * nm_explicit_bzero() when growing the buffer. */ +typedef struct _NMStrBuf { + char *_priv_str; + + /* The unions only exist because we allow/encourage read-only access + * to the "len" and "allocated" fields, but modifying the fields is + * only allowed to the NMStrBuf implementation itself. */ + union { + /*const*/ gsize len; + gsize _priv_len; + }; + union { + /*const*/ gsize allocated; + gsize _priv_allocated; + }; + + bool _priv_do_bzero_mem; +} NMStrBuf; + +/*****************************************************************************/ + +static inline void +_nm_str_buf_assert(const NMStrBuf *strbuf) +{ + nm_assert(strbuf); + nm_assert((!!strbuf->_priv_str) == (strbuf->_priv_allocated > 0)); + nm_assert(strbuf->_priv_len <= strbuf->_priv_allocated); +} + +static inline NMStrBuf +NM_STR_BUF_INIT(gsize allocated, gboolean do_bzero_mem) +{ + NMStrBuf strbuf = { + ._priv_str = allocated ? g_malloc(allocated) : NULL, + ._priv_allocated = allocated, + ._priv_len = 0, + ._priv_do_bzero_mem = do_bzero_mem, + }; + + return strbuf; +} + +static inline void +nm_str_buf_init(NMStrBuf *strbuf, gsize len, bool do_bzero_mem) +{ + nm_assert(strbuf); + *strbuf = NM_STR_BUF_INIT(len, do_bzero_mem); + _nm_str_buf_assert(strbuf); +} + +void _nm_str_buf_ensure_size(NMStrBuf *strbuf, gsize new_size, gboolean reserve_exact); + +static inline void +nm_str_buf_maybe_expand(NMStrBuf *strbuf, gsize reserve, gboolean reserve_exact) +{ + _nm_str_buf_assert(strbuf); + nm_assert(strbuf->_priv_len < G_MAXSIZE - reserve); + + /* @reserve is the extra space that we require. */ + if (G_UNLIKELY(reserve > strbuf->_priv_allocated - strbuf->_priv_len)) + _nm_str_buf_ensure_size(strbuf, strbuf->_priv_len + reserve, reserve_exact); +} + +/*****************************************************************************/ + +/** + * nm_str_buf_set_size: + * @strbuf: the initialized #NMStrBuf + * @new_len: the new length + * @honor_do_bzero_mem: if %TRUE, the shrunk memory will be cleared, if + * do_bzero_mem is set. This should be usually set to %TRUE, unless + * you know that the shrunk memory does not contain data that requires to be + * cleared. When growing the size, this value has no effect. + * @reserve_exact: when growing the buffer, reserve the exact amount of bytes. + * If %FALSE, the buffer may allocate more memory than requested to grow + * exponentially. + * + * This is like g_string_set_size(). If new_len is smaller than the + * current length, the string gets truncated (excess memory will be cleared). + * + * When extending the length, the added bytes are undefined (like with + * g_string_set_size(). Likewise, if you first pre-allocate a buffer with + * nm_str_buf_maybe_expand(), then write to the bytes, and finally set + * the appropriate size, then that works as expected (by not clearing the + * pre-existing, grown buffer). + */ +static inline void +nm_str_buf_set_size(NMStrBuf *strbuf, + gsize new_len, + gboolean honor_do_bzero_mem, + gboolean reserve_exact) +{ + _nm_str_buf_assert(strbuf); + + if (new_len < strbuf->_priv_len) { + if (honor_do_bzero_mem && strbuf->_priv_do_bzero_mem) { + /* we only clear the memory that we wrote to. */ + nm_explicit_bzero(&strbuf->_priv_str[new_len], strbuf->_priv_len - new_len); + } + } else if (new_len > strbuf->_priv_len) { + nm_str_buf_maybe_expand(strbuf, + new_len - strbuf->_priv_len + (reserve_exact ? 0u : 1u), + reserve_exact); + } else + return; + + strbuf->_priv_len = new_len; +} + +/*****************************************************************************/ + +static inline void +nm_str_buf_erase(NMStrBuf *strbuf, gsize pos, gssize len, gboolean honor_do_bzero_mem) +{ + gsize new_len; + + _nm_str_buf_assert(strbuf); + + nm_assert(pos <= strbuf->_priv_len); + + if (len == 0) + return; + + if (len < 0) { + /* truncate the string before pos */ + nm_assert(len == -1); + new_len = pos; + } else { + gsize l = len; + + nm_assert(l <= strbuf->_priv_len - pos); + + new_len = strbuf->_priv_len - l; + if (pos + l < strbuf->_priv_len) { + memmove(&strbuf->_priv_str[pos], + &strbuf->_priv_str[pos + l], + strbuf->_priv_len - (pos + l)); + } + } + + nm_assert(new_len <= strbuf->_priv_len); + nm_str_buf_set_size(strbuf, new_len, honor_do_bzero_mem, TRUE); +} + +/*****************************************************************************/ + +static inline void +nm_str_buf_append_c_repeated(NMStrBuf *strbuf, char ch, guint len) +{ + if (len > 0) { + nm_str_buf_maybe_expand(strbuf, len + 1, FALSE); + do { + strbuf->_priv_str[strbuf->_priv_len++] = ch; + } while (--len > 0); + } +} + +static inline void +nm_str_buf_append_c(NMStrBuf *strbuf, char ch) +{ + nm_str_buf_maybe_expand(strbuf, 2, FALSE); + strbuf->_priv_str[strbuf->_priv_len++] = ch; +} + +static inline void +nm_str_buf_append_c2(NMStrBuf *strbuf, char ch0, char ch1) +{ + nm_str_buf_maybe_expand(strbuf, 3, FALSE); + strbuf->_priv_str[strbuf->_priv_len++] = ch0; + strbuf->_priv_str[strbuf->_priv_len++] = ch1; +} + +static inline void +nm_str_buf_append_c4(NMStrBuf *strbuf, char ch0, char ch1, char ch2, char ch3) +{ + nm_str_buf_maybe_expand(strbuf, 5, FALSE); + strbuf->_priv_str[strbuf->_priv_len++] = ch0; + strbuf->_priv_str[strbuf->_priv_len++] = ch1; + strbuf->_priv_str[strbuf->_priv_len++] = ch2; + strbuf->_priv_str[strbuf->_priv_len++] = ch3; +} + +static inline void +nm_str_buf_append_c_hex(NMStrBuf *strbuf, char ch, gboolean upper_case) +{ + nm_str_buf_maybe_expand(strbuf, 3, FALSE); + strbuf->_priv_str[strbuf->_priv_len++] = nm_hexchar(((guchar) ch) >> 4, upper_case); + strbuf->_priv_str[strbuf->_priv_len++] = nm_hexchar((guchar) ch, upper_case); +} + +static inline void +nm_str_buf_append_len(NMStrBuf *strbuf, const char *str, gsize len) +{ + _nm_str_buf_assert(strbuf); + + if (len > 0) { + nm_str_buf_maybe_expand(strbuf, len + 1, FALSE); + memcpy(&strbuf->_priv_str[strbuf->_priv_len], str, len); + strbuf->_priv_len += len; + } +} + +static inline char * +nm_str_buf_append_len0(NMStrBuf *strbuf, const char *str, gsize len) +{ + _nm_str_buf_assert(strbuf); + + /* this is basically like nm_str_buf_append_len() and + * nm_str_buf_get_str() in one. */ + + nm_str_buf_maybe_expand(strbuf, len + 1u, FALSE); + if (len > 0) { + memcpy(&strbuf->_priv_str[strbuf->_priv_len], str, len); + strbuf->_priv_len += len; + } + strbuf->_priv_str[strbuf->_priv_len] = '\0'; + return strbuf->_priv_str; +} + +static inline void +nm_str_buf_append(NMStrBuf *strbuf, const char *str) +{ + nm_assert(str); + + nm_str_buf_append_len(strbuf, str, strlen(str)); +} + +static inline char * +nm_str_buf_append0(NMStrBuf *strbuf, const char *str) +{ + nm_assert(str); + + return nm_str_buf_append_len0(strbuf, str, strlen(str)); +} + +void nm_str_buf_append_printf(NMStrBuf *strbuf, const char *format, ...) _nm_printf(2, 3); + +static inline void +nm_str_buf_ensure_trailing_c(NMStrBuf *strbuf, char ch) +{ + _nm_str_buf_assert(strbuf); + + if (strbuf->_priv_len == 0 || strbuf->_priv_str[strbuf->_priv_len - 1] != ch) + nm_str_buf_append_c(strbuf, ch); +} + +static inline NMStrBuf * +nm_str_buf_append_required_delimiter(NMStrBuf *strbuf, char delimiter) +{ + _nm_str_buf_assert(strbuf); + + /* appends the @delimiter if it is required (that is, if the + * string is not empty). */ + if (strbuf->len > 0) + nm_str_buf_append_c(strbuf, delimiter); + return strbuf; +} + +static inline void +nm_str_buf_append_dirty(NMStrBuf *strbuf, gsize len) +{ + _nm_str_buf_assert(strbuf); + + /* this append @len bytes to the buffer, but it does not + * initialize them! */ + if (len > 0) { + nm_str_buf_maybe_expand(strbuf, len, FALSE); + strbuf->_priv_len += len; + } +} + +static inline void +nm_str_buf_append_c_len(NMStrBuf *strbuf, char ch, gsize len) +{ + _nm_str_buf_assert(strbuf); + + if (len > 0) { + nm_str_buf_maybe_expand(strbuf, len, FALSE); + memset(&strbuf->_priv_str[strbuf->_priv_len], ch, len); + strbuf->_priv_len += len; + } +} + +/*****************************************************************************/ + +static inline NMStrBuf * +nm_str_buf_reset(NMStrBuf *strbuf) +{ + _nm_str_buf_assert(strbuf); + + if (strbuf->_priv_len > 0) { + if (strbuf->_priv_do_bzero_mem) { + /* we only clear the memory that we wrote to. */ + nm_explicit_bzero(strbuf->_priv_str, strbuf->_priv_len); + } + strbuf->_priv_len = 0; + } + + return strbuf; +} + +/*****************************************************************************/ + +/* Calls nm_utils_escaped_tokens_escape() on @str and appends the + * result to @strbuf. */ +static inline void +nm_utils_escaped_tokens_escape_strbuf(const char *str, const char *delimiters, NMStrBuf *strbuf) +{ + gs_free char *str_to_free = NULL; + + nm_assert(str); + + nm_str_buf_append(strbuf, nm_utils_escaped_tokens_escape(str, delimiters, &str_to_free)); +} + +/* Calls nm_utils_escaped_tokens_escape_unnecessary() on @str and appends the + * string to @strbuf. */ +static inline void +nm_utils_escaped_tokens_escape_strbuf_assert(const char *str, + const char *delimiters, + NMStrBuf * strbuf) +{ + nm_str_buf_append(strbuf, nm_utils_escaped_tokens_escape_unnecessary(str, delimiters)); +} + +/*****************************************************************************/ + +static inline gboolean +nm_str_buf_is_initalized(NMStrBuf *strbuf) +{ + nm_assert(strbuf); +#if NM_MORE_ASSERTS + if (strbuf->_priv_str) + _nm_str_buf_assert(strbuf); +#endif + return !!strbuf->_priv_str; +} + +/** + * nm_str_buf_get_str: + * @strbuf: the #NMStrBuf instance + * + * Returns the NUL terminated internal string. + * + * While constructing the string, the intermediate buffer + * is not NUL terminated (this makes it different from GString). + * Usually, one would build the string and retrieve it at the + * end with nm_str_buf_finalize(). This returns the NUL terminated + * buffer that was appended so far. Contrary to nm_str_buf_finalize(), you + * can still append more data to the buffer and this does not transfer ownership + * of the string. + * + * Returns: (transfer none): the internal string. The string + * is of length "strbuf->len", which may be larger if the + * returned string contains NUL characters (binary). The terminating + * NUL character is always present after "strbuf->len" characters. + * If currently no buffer is allocated, this will return %NULL. + */ +static inline char * +nm_str_buf_get_str(NMStrBuf *strbuf) +{ + _nm_str_buf_assert(strbuf); + + if (!strbuf->_priv_str) + return NULL; + + nm_str_buf_maybe_expand(strbuf, 1, FALSE); + strbuf->_priv_str[strbuf->_priv_len] = '\0'; + return strbuf->_priv_str; +} + +static inline char * +nm_str_buf_get_str_unsafe(NMStrBuf *strbuf) +{ + _nm_str_buf_assert(strbuf); + return strbuf->_priv_str; +} + +static inline char * +nm_str_buf_get_str_at_unsafe(NMStrBuf *strbuf, gsize index) +{ + _nm_str_buf_assert(strbuf); + + /* it is acceptable to ask for a pointer at the end of the buffer -- even + * if there is no data there. The caller is anyway required to take care + * of the length (that's the "unsafe" part), and in that case, the length + * is merely zero. */ + nm_assert(index <= strbuf->allocated); + + if (!strbuf->_priv_str) + return NULL; + + return &strbuf->_priv_str[index]; +} + +static inline char +nm_str_buf_get_char(const NMStrBuf *strbuf, gsize index) +{ + _nm_str_buf_assert(strbuf); + nm_assert(index < strbuf->allocated); + return strbuf->_priv_str[index]; +} + +/** + * nm_str_buf_finalize: + * @strbuf: an initilized #NMStrBuf + * @out_len: (out): (allow-none): optional output + * argument with the length of the returned string. + * + * Returns: (transfer full): the string of the buffer + * which must be freed by the caller. The @strbuf + * is afterwards in undefined state, though it can be + * reused after nm_str_buf_init(). + * Note that if no string is allocated yet (after nm_str_buf_init() with + * length zero), this will return %NULL. */ +static inline char * +nm_str_buf_finalize(NMStrBuf *strbuf, gsize *out_len) +{ + _nm_str_buf_assert(strbuf); + + NM_SET_OUT(out_len, strbuf->_priv_len); + + if (!strbuf->_priv_str) + return NULL; + + nm_str_buf_maybe_expand(strbuf, 1, TRUE); + strbuf->_priv_str[strbuf->_priv_len] = '\0'; + + /* the buffer is in invalid state afterwards, however, we clear it + * so far, that nm_auto_str_buf and nm_str_buf_destroy() is happy. */ + return g_steal_pointer(&strbuf->_priv_str); +} + +static inline GBytes * +nm_str_buf_finalize_to_gbytes(NMStrBuf *strbuf) +{ + char *s; + gsize l; + + /* this always returns a non-NULL, newly allocated GBytes instance. + * The data buffer always has an additional NUL character after + * the data, and the data is allocated with malloc. + * + * That means, the caller who takes ownership of the GBytes can + * safely modify the content of the buffer (including the additional + * NUL sentinel). */ + s = nm_str_buf_finalize(strbuf, &l); + return g_bytes_new_take(s ?: g_new0(char, 1), l); +} + +/** + * nm_str_buf_destroy: + * @strbuf: an initialized #NMStrBuf + * + * Frees the associated memory of @strbuf. The buffer + * afterwards is in undefined state, but can be re-initialized + * with nm_str_buf_init(). + */ +static inline void +nm_str_buf_destroy(NMStrBuf *strbuf) +{ + if (!strbuf->_priv_str) + return; + _nm_str_buf_assert(strbuf); + if (strbuf->_priv_do_bzero_mem) + nm_explicit_bzero(strbuf->_priv_str, strbuf->_priv_len); + g_free(strbuf->_priv_str); + + /* the buffer is in invalid state afterwards, however, we clear it + * so far, that nm_auto_str_buf is happy when calling + * nm_str_buf_destroy() again. */ + strbuf->_priv_str = NULL; +} + +#define nm_auto_str_buf nm_auto(nm_str_buf_destroy) + +#endif /* __NM_STR_BUF_H__ */ diff --git a/src/libnm-glib-aux/nm-test-utils.h b/src/libnm-glib-aux/nm-test-utils.h new file mode 100644 index 0000000..61e4ef6 --- /dev/null +++ b/src/libnm-glib-aux/nm-test-utils.h @@ -0,0 +1,2860 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NM_TEST_UTILS_H__ +#define __NM_TEST_UTILS_H__ + +/******************************************************************************* + * HOWTO run tests. + * + * Our tests (make check) include this header-only file nm-test-utils.h. + * + * You should always include this header *as last*. Reason is, that depending on + * previous includes, functionality will be enabled. + * + * Logging: + * In tests, nm-logging redirects to glib logging. By default, glib suppresses all debug + * messages unless you set G_MESSAGES_DEBUG. To enable debug logging, you can explicitly set + * G_MESSAGES_DEBUG. Otherwise, nm-test will set G_MESSAGES_DEBUG=all in debug mode (see below). + * For nm-logging, you can configure the log-level and domains via NMTST_DEBUG environment + * variable. + * + * Assert-logging: + * Some tests assert against logged messages (g_test_expect_message()). + * By specifying no-expect-message in NMTST_DEBUG, you can disable assert logging + * and g_test_assert_expected_messages() will not fail. + * + * NMTST_SEED_RAND environment variable: + * Tests that use random numbers from nmtst_get_rand() get seeded at each start. + * You can specify the seed by setting NMTST_SEED_RAND to a particular number or empty ("") + * for a random one. If NMTST_SEED_RAND is not set (default) a stable seed gets chosen. + * Tests will print the seed to stdout, so that you know which one was chosen or generated. + * + * + * NMTST_DEBUG environment variable: + * + * "debug", "no-debug": when at test is run in debug mode, it might behave differently, + * depending on the test. See nmtst_is_debug(). + * Known differences: + * - a test might leave the logging level unspecified. In this case, running in + * debug mode, will turn on DEBUG logging, otherwise WARN logging only. + * - if G_MESSAGES_DEBUG is unset, nm-test will set G_MESSAGES_DEBUG=all + * for tests that don't do assert-logging. + * Debug mode is determined as follows (highest priority first): + * - command line option --debug/--no-debug + * - NMTST_DEBUG=debug/no-debug + * - setting NMTST_DEBUG implies debugging turned on + * - g_test_verbose() + * + * "no-expect-message": for tests that would assert against log messages, disable + * those asserts. + * + * "log-level=LEVEL", "log-domains=DOMAIN": reset the log level and domain for tests. + * It only has an effect for nm-logging messages. + * This has no effect if the test asserts against logging (unless no-expect-message), + * otherwise, changing the logging would break tests. + * If you set the level to DEBUG or TRACE, it also sets G_MESSAGES_DEBUG=all (unless + * in assert-logging mode and unless G_MESSAGES_DEBUG is already defined). + * + * "TRACE", this is shorthand for "log-level=TRACE". + * + * "D", this is shorthand for "log-level=TRACE,no-expect-message". + * + * "sudo-cmd=PATH": when running root tests as normal user, the test will execute + * itself by invoking sudo at PATH. + * For example + * NMTST_DEBUG="sudo-cmd=$PWD/tools/test-sudo-wrapper.sh" make -C src/platform/tests/ check + * + * "slow|quick|thorough": enable/disable long-running tests. This sets nmtst_test_quick(). + * Whether long-running tests are enabled is determined as follows (highest priority first): + * - specifying the value in NMTST_DEBUG has highest priority + * - respect g_test_quick(), if the command line contains '-mslow', '-mquick', '-mthorough'. + * - use compile time default (CFLAGS=-DNMTST_TEST_QUICK=TRUE) + * - enable slow tests by default + * + * "p=PATH"|"s=PATH": passes the path to g_test_init() as "-p" and "-s", respectively. + * Unfortunately, these options conflict with "--tap" which our makefile passes to the + * tests, thus it's only useful outside of `make check`. + * + *******************************************************************************/ + +#if defined(NM_ASSERT_NO_MSG) && NM_ASSERT_NO_MSG + #undef g_return_if_fail_warning + #undef g_assertion_message_expr +#endif + +#include +#include +#include +#include +#include +#include + +/*****************************************************************************/ + +#define NMTST_G_RETURN_MSG_S(expr) "*: assertion '" NM_ASSERT_G_RETURN_EXPR(expr) "' failed" +#define NMTST_G_RETURN_MSG(expr) NMTST_G_RETURN_MSG_S(#expr) + +/*****************************************************************************/ + +/* general purpose functions that have no dependency on other nmtst functions */ + +#define nmtst_assert_error(error, expect_error_domain, expect_error_code, expect_error_pattern) \ + G_STMT_START \ + { \ + GError * _error = (error); \ + GQuark _expect_error_domain = (expect_error_domain); \ + const char *_expect_error_pattern = (expect_error_pattern); \ + \ + if (_expect_error_domain) \ + g_assert_error(_error, _expect_error_domain, (expect_error_code)); \ + else \ + g_assert(_error); \ + g_assert(_error->message); \ + if (_expect_error_pattern \ + && !g_pattern_match_simple(_expect_error_pattern, _error->message)) { \ + g_error("%s:%d: error message does not have expected pattern '%s'. Instead it is " \ + "'%s' (%s, %d)", \ + __FILE__, \ + __LINE__, \ + _expect_error_pattern, \ + _error->message, \ + g_quark_to_string(_error->domain), \ + _error->code); \ + } \ + } \ + G_STMT_END + +#define NMTST_WAIT(max_wait_ms, wait) \ + ({ \ + gboolean _not_expired = TRUE; \ + const gint64 nmtst_wait_start_us = g_get_monotonic_time(); \ + const gint64 nmtst_wait_duration_us = (max_wait_ms) *1000L; \ + const gint64 nmtst_wait_end_us = nmtst_wait_start_us + nmtst_wait_duration_us; \ + gint64 _nmtst_wait_remaining_us = nmtst_wait_duration_us; \ + int _nmtst_wait_iteration = 0; \ + \ + while (TRUE) { \ + _nm_unused const gint64 nmtst_wait_remaining_us = _nmtst_wait_remaining_us; \ + _nm_unused int nmtst_wait_iteration = _nmtst_wait_iteration++; \ + \ + {wait}; \ + _nmtst_wait_remaining_us = (nmtst_wait_end_us - g_get_monotonic_time()); \ + if (_nmtst_wait_remaining_us <= 0) { \ + _not_expired = FALSE; \ + break; \ + } \ + } \ + _not_expired; \ + }) + +#define NMTST_WAIT_ASSERT(max_wait_ms, wait) \ + G_STMT_START \ + { \ + if (!(NMTST_WAIT(max_wait_ms, wait))) \ + g_assert_not_reached(); \ + } \ + G_STMT_END + +#define nmtst_assert_nonnull(command) \ + ({ \ + typeof(*(command)) *_ptr = (command); \ + \ + g_assert(_ptr && (TRUE || (command))); \ + _ptr; \ + }) + +#define nmtst_assert_success(success, error) \ + G_STMT_START \ + { \ + g_assert_no_error(error); \ + g_assert((success)); \ + } \ + G_STMT_END + +#define nmtst_assert_no_success(success, error) \ + G_STMT_START \ + { \ + g_assert(error); \ + g_assert(!(success)); \ + } \ + G_STMT_END + +/*****************************************************************************/ + +/* Our nm-error error numbers use negative values to signal failure. + * A non-negative value signals success. Hence, the correct way for checking + * is always (r < 0) vs. (r >= 0). Never (r == 0). + * + * For assertions in tests, we also want to assert that no positive values + * are returned. For a lot of functions, positive return values are unexpected + * and a bug. This macro evaluates @r to success or failure, while asserting + * that @r is not positive. */ +#define NMTST_NM_ERR_SUCCESS(r) \ + ({ \ + const int _r = (r); \ + \ + if (_r >= 0) \ + g_assert_cmpint(_r, ==, 0); \ + (_r >= 0); \ + }) + +/*****************************************************************************/ + +struct __nmtst_internal { + GRand * rand0; + guint32 rand_seed; + GRand * rand; + gboolean is_debug; + gboolean assert_logging; + gboolean no_expect_message; + gboolean test_quick; + gboolean test_tap_log; + char * sudo_cmd; + char ** orig_argv; +}; + +extern struct __nmtst_internal __nmtst_internal; + +#define NMTST_DEFINE() \ + struct __nmtst_internal __nmtst_internal = {0}; \ + \ + __attribute__((destructor)) static void _nmtst_exit(void) \ + { \ + __nmtst_internal.assert_logging = FALSE; \ + g_test_assert_expected_messages(); \ + nmtst_free(); \ + } + +static inline gboolean +nmtst_initialized(void) +{ + return !!__nmtst_internal.rand0; +} + +#define __NMTST_LOG(cmd, ...) \ + G_STMT_START \ + { \ + g_assert(nmtst_initialized()); \ + if (!__nmtst_internal.assert_logging || __nmtst_internal.no_expect_message) { \ + cmd(__VA_ARGS__); \ + } else { \ + printf(_NM_UTILS_MACRO_FIRST(__VA_ARGS__) "\n" _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END + +/* split the string inplace at specific delimiters, allowing escaping with '\\'. + * Returns a zero terminated array of pointers into @str. + * + * The caller must g_free() the returned argv array. + **/ +static inline char ** +nmtst_str_split(char *str, const char *delimiters) +{ + const char *d; + GArray * result = g_array_sized_new(TRUE, FALSE, sizeof(char *), 3); + + g_assert(str); + g_assert(delimiters && !strchr(delimiters, '\\')); + + while (*str) { + gsize i = 0, j = 0; + + while (TRUE) { + char c = str[i]; + + if (c == '\0') { + str[j++] = 0; + break; + } else if (c == '\\') { + str[j++] = str[++i]; + if (!str[i]) + break; + } else { + for (d = delimiters; *d; d++) { + if (c == *d) { + str[j++] = 0; + i++; + goto BREAK_INNER_LOOPS; + } + } + str[j++] = c; + } + i++; + } + +BREAK_INNER_LOOPS: + g_array_append_val(result, str); + str = &str[i]; + } + + return (char **) g_array_free(result, FALSE); +} + +/* free instances allocated by nmtst (especially nmtst_init()) on shutdown + * to release memory. After nmtst_free(), the test is uninitialized again. */ +static inline void +nmtst_free(void) +{ + if (!nmtst_initialized()) + return; + + g_rand_free(__nmtst_internal.rand0); + if (__nmtst_internal.rand) + g_rand_free(__nmtst_internal.rand); + g_free(__nmtst_internal.sudo_cmd); + g_strfreev(__nmtst_internal.orig_argv); + + memset(&__nmtst_internal, 0, sizeof(__nmtst_internal)); +} + +static inline void +_nmtst_log_handler(const char * log_domain, + GLogLevelFlags log_level, + const char * message, + gpointer user_data) +{ + g_print("%s\n", message); +} + +static inline void +__nmtst_init(int * argc, + char *** argv, + gboolean assert_logging, + const char *log_level, + const char *log_domains, + gboolean * out_set_logging) +{ + const char * nmtst_debug; + gboolean is_debug = FALSE; + char * c_log_level = NULL, *c_log_domains = NULL; + char * sudo_cmd = NULL; + GArray * debug_messages = g_array_new(TRUE, FALSE, sizeof(char *)); + int i; + gboolean no_expect_message = FALSE; + gboolean _out_set_logging; + gboolean test_quick = FALSE; + gboolean test_quick_set = FALSE; + gboolean test_quick_argv = FALSE; + gs_unref_ptrarray GPtrArray *p_tests = NULL; + gs_unref_ptrarray GPtrArray *s_tests = NULL; + + if (!out_set_logging) + out_set_logging = &_out_set_logging; + *out_set_logging = FALSE; + + g_assert(!nmtst_initialized()); + + g_assert(!((!!argc) ^ (!!argv))); + g_assert(!argc || (g_strv_length(*argv) == *argc)); + g_assert(!assert_logging || (!log_level && !log_domains)); + +#ifdef __NETWORKMANAGER_UTILS_H__ + if (!nm_utils_get_testing_initialized()) + _nm_utils_set_testing(_NM_UTILS_TEST_GENERAL); +#endif + + if (argc) + __nmtst_internal.orig_argv = g_strdupv(*argv); + + __nmtst_internal.assert_logging = !!assert_logging; + + nm_g_type_init(); + + is_debug = g_test_verbose(); + + nmtst_debug = g_getenv("NMTST_DEBUG"); + if (nmtst_debug) { + char **d_argv, **i_argv, *nmtst_debug_copy; + + /* By setting then NMTST_DEBUG variable, @is_debug is set automatically. + * This can be reverted with no-debug (on command line or environment variable). */ + is_debug = TRUE; + + nmtst_debug_copy = g_strdup(nmtst_debug); + d_argv = nmtst_str_split(nmtst_debug_copy, ",; \t\r\n"); + + for (i_argv = d_argv; *i_argv; i_argv++) { + const char *debug = *i_argv; + + if (!g_ascii_strcasecmp(debug, "debug")) + is_debug = TRUE; + else if (!g_ascii_strcasecmp(debug, "no-debug")) { + /* when specifying the NMTST_DEBUG variable, we set is_debug to true. Use this flag to disable this + * (e.g. for only setting the log-level, but not is_debug). */ + is_debug = FALSE; + } else if (!g_ascii_strncasecmp(debug, "log-level=", strlen("log-level="))) { + g_free(c_log_level); + log_level = c_log_level = g_strdup(&debug[strlen("log-level=")]); + } else if (!g_ascii_strcasecmp(debug, "D")) { + /* shorthand for "log-level=TRACE,no-expect-message" */ + g_free(c_log_level); + log_level = c_log_level = g_strdup("TRACE"); + no_expect_message = TRUE; + } else if (!g_ascii_strcasecmp(debug, "TRACE")) { + g_free(c_log_level); + log_level = c_log_level = g_strdup("TRACE"); + } else if (!g_ascii_strncasecmp(debug, "log-domains=", strlen("log-domains="))) { + g_free(c_log_domains); + log_domains = c_log_domains = g_strdup(&debug[strlen("log-domains=")]); + } else if (!g_ascii_strncasecmp(debug, "sudo-cmd=", strlen("sudo-cmd="))) { + g_free(sudo_cmd); + sudo_cmd = g_strdup(&debug[strlen("sudo-cmd=")]); + } else if (!g_ascii_strcasecmp(debug, "no-expect-message")) { + no_expect_message = TRUE; + } else if (!g_ascii_strncasecmp(debug, "p=", strlen("p="))) { + if (!p_tests) + p_tests = g_ptr_array_new_with_free_func(g_free); + g_ptr_array_add(p_tests, g_strdup(&debug[strlen("p=")])); + } else if (!g_ascii_strncasecmp(debug, "s=", strlen("s="))) { + if (!s_tests) + s_tests = g_ptr_array_new_with_free_func(g_free); + g_ptr_array_add(s_tests, g_strdup(&debug[strlen("s=")])); + } else if (!g_ascii_strcasecmp(debug, "slow") + || !g_ascii_strcasecmp(debug, "thorough")) { + test_quick = FALSE; + test_quick_set = TRUE; + } else if (!g_ascii_strcasecmp(debug, "quick")) { + test_quick = TRUE; + test_quick_set = TRUE; + } else { + char *msg = + g_strdup_printf(">>> nmtst: ignore unrecognized NMTST_DEBUG option \"%s\"", + debug); + + g_array_append_val(debug_messages, msg); + } + } + + g_free(d_argv); + g_free(nmtst_debug_copy); + } + + if (__nmtst_internal.orig_argv) { + char **a = __nmtst_internal.orig_argv; + + for (; *a; a++) { + if (!g_ascii_strcasecmp(*a, "--debug")) + is_debug = TRUE; + else if (!g_ascii_strcasecmp(*a, "--no-debug")) + is_debug = FALSE; + else if (!strcmp(*a, "-m=slow") || !strcmp(*a, "-m=thorough") || !strcmp(*a, "-m=quick") + || (!strcmp(*a, "-m") && *(a + 1) + && (!strcmp(*(a + 1), "quick") || !strcmp(*(a + 1), "slow") + || !strcmp(*(a + 1), "thorough")))) + test_quick_argv = TRUE; + else if (strcmp(*a, "--tap") == 0) + __nmtst_internal.test_tap_log = TRUE; + } + } + + if (!argc || g_test_initialized()) { + if (p_tests || s_tests) { + char *msg = g_strdup_printf( + ">>> nmtst: ignore -p and -s options for test which calls g_test_init() itself"); + + g_array_append_val(debug_messages, msg); + } + } else { + /* We're intentionally assigning a value to static variables + * s_tests_x and p_tests_x without using it afterwards, just + * so that valgrind doesn't complain about the leak. */ + NM_PRAGMA_WARNING_DISABLE("-Wunused-but-set-variable") + + /* g_test_init() is a variadic function, so we cannot pass it + * (variadic) arguments. If you need to pass additional parameters, + * call nmtst_init() with argc==NULL and call g_test_init() yourself. */ + + /* g_test_init() sets g_log_set_always_fatal() for G_LOG_LEVEL_WARNING + * and G_LOG_LEVEL_CRITICAL. So, beware that the test will fail if you + * have any WARN or ERR log messages -- unless you g_test_expect_message(). */ + GPtrArray * arg_array = g_ptr_array_new(); + gs_free char **arg_array_c = NULL; + int arg_array_n, j; + static char ** s_tests_x, **p_tests_x; + + if (*argc) { + for (i = 0; i < *argc; i++) + g_ptr_array_add(arg_array, (*argv)[i]); + } else + g_ptr_array_add(arg_array, "./test"); + + if (test_quick_set && !test_quick_argv) + g_ptr_array_add(arg_array, "-m=quick"); + + if (!__nmtst_internal.test_tap_log) { + for (i = 0; p_tests && i < p_tests->len; i++) { + g_ptr_array_add(arg_array, "-p"); + g_ptr_array_add(arg_array, p_tests->pdata[i]); + } + for (i = 0; s_tests && i < s_tests->len; i++) { + g_ptr_array_add(arg_array, "-s"); + g_ptr_array_add(arg_array, s_tests->pdata[i]); + } + } else if (p_tests || s_tests) { + char *msg = g_strdup_printf(">>> nmtst: ignore -p and -s options for tap-tests"); + + g_array_append_val(debug_messages, msg); + } + + g_ptr_array_add(arg_array, NULL); + + arg_array_n = arg_array->len - 1; + arg_array_c = (char **) g_ptr_array_free(arg_array, FALSE); + + g_test_init(&arg_array_n, &arg_array_c, NULL); + + if (*argc > 1) { + /* collaps argc/argv by removing the arguments detected + * by g_test_init(). */ + for (i = 1, j = 1; i < *argc; i++) { + if ((*argv)[i] == arg_array_c[j]) + j++; + else + (*argv)[i] = NULL; + } + for (i = 1, j = 1; i < *argc; i++) { + if ((*argv)[i]) { + (*argv)[j++] = (*argv)[i]; + if (i >= j) + (*argv)[i] = NULL; + } + } + *argc = j; + } + + /* we must "leak" the test paths because they are not cloned by g_test_init(). */ + if (!__nmtst_internal.test_tap_log) { + if (p_tests) { + p_tests_x = (char **) g_ptr_array_free(p_tests, FALSE); + p_tests = NULL; + } + if (s_tests) { + s_tests_x = (char **) g_ptr_array_free(s_tests, FALSE); + s_tests = NULL; + } + } + + NM_PRAGMA_WARNING_REENABLE + } + + if (test_quick_set) + __nmtst_internal.test_quick = test_quick; + else if (test_quick_argv) + __nmtst_internal.test_quick = g_test_quick(); + else { +#ifdef NMTST_TEST_QUICK + __nmtst_internal.test_quick = NMTST_TEST_QUICK; +#else + __nmtst_internal.test_quick = FALSE; +#endif + } + + __nmtst_internal.is_debug = is_debug; + __nmtst_internal.rand0 = g_rand_new_with_seed(0); + __nmtst_internal.sudo_cmd = sudo_cmd; + __nmtst_internal.no_expect_message = no_expect_message; + + if (!log_level && log_domains) { + /* if the log level is not specified (but the domain is), we assume + * the caller wants to set it depending on is_debug */ + log_level = is_debug ? "DEBUG" : "WARN"; + } + + if (!__nmtst_internal.assert_logging) { + gboolean success = TRUE; +#ifdef _NMTST_INSIDE_CORE + success = nm_logging_setup(log_level, log_domains, NULL, NULL); + *out_set_logging = TRUE; +#endif + g_assert(success); +#if GLIB_CHECK_VERSION(2, 34, 0) + if (__nmtst_internal.no_expect_message) + g_log_set_always_fatal(G_LOG_FATAL_MASK); +#else + /* g_test_expect_message() is a NOP, so allow any messages */ + g_log_set_always_fatal(G_LOG_FATAL_MASK); +#endif + } else if (__nmtst_internal.no_expect_message) { + /* We have a test that would be assert_logging, but the user specified no_expect_message. + * This transforms g_test_expect_message() into a NOP, but we also have to relax + * g_log_set_always_fatal(), which was set by g_test_init(). */ + g_log_set_always_fatal(G_LOG_FATAL_MASK); +#ifdef _NMTST_INSIDE_CORE + if (c_log_domains || c_log_level) { + /* Normally, tests with assert_logging do not overwrite the logging level/domains because + * the logging statements are part of the assertions. But if the test is run with + * no-expect-message *and* the logging is set explicitly via environment variables, + * we still reset the logging. */ + gboolean success; + + success = nm_logging_setup(log_level, log_domains, NULL, NULL); + *out_set_logging = TRUE; + g_assert(success); + } +#endif + } else { +#if GLIB_CHECK_VERSION(2, 34, 0) + /* We were called not to set logging levels. This means, that the user + * expects to assert against (all) messages. + * Any uncaught message on >debug level is fatal. */ + g_log_set_always_fatal(G_LOG_LEVEL_MASK & ~G_LOG_LEVEL_DEBUG); +#else + /* g_test_expect_message() is a NOP, so allow any messages */ + g_log_set_always_fatal(G_LOG_FATAL_MASK); +#endif + } + + if ((!__nmtst_internal.assert_logging + || (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message)) + && (is_debug + || (c_log_level + && (!g_ascii_strcasecmp(c_log_level, "DEBUG") + || !g_ascii_strcasecmp(c_log_level, "TRACE")))) + && !g_getenv("G_MESSAGES_DEBUG")) { + /* if we are @is_debug or @log_level=="DEBUG" and + * G_MESSAGES_DEBUG is unset, we set G_MESSAGES_DEBUG=all. + * To disable this default behaviour, set G_MESSAGES_DEBUG='' */ + + /* Note that g_setenv is not thread safe, but you should anyway call + * nmtst_init() at the very start. */ + g_setenv("G_MESSAGES_DEBUG", "all", TRUE); + } + + /* "tc" is in /sbin, which might not be in $PATH of a regular user. Unconditionally + * add "/bin" and "/sbin" to $PATH for all tests. */ + { + static char *path_new; + const char * path_old; + + g_assert(!path_new); + + path_old = g_getenv("PATH"); + path_new = g_strjoin("", + path_old ?: "", + (nm_str_is_empty(path_old) ? "" : ":"), + "/bin:/sbin", + NULL); + g_setenv("PATH", path_new, TRUE); + } + + /* Delay messages until we setup logging. */ + for (i = 0; i < debug_messages->len; i++) + __NMTST_LOG(g_message, "%s", g_array_index(debug_messages, const char *, i)); + + g_strfreev((char **) g_array_free(debug_messages, FALSE)); + g_free(c_log_level); + g_free(c_log_domains); + +#ifdef __NETWORKMANAGER_UTILS_H__ + /* ensure that monotonic timestamp is called (because it initially logs a line) */ + nm_utils_get_monotonic_timestamp_sec(); +#endif + +#ifdef NM_UTILS_H + { + gs_free_error GError *error = NULL; + + if (!nm_utils_init(&error)) + g_assert_not_reached(); + g_assert_no_error(error); + } +#endif + + g_log_set_handler(G_LOG_DOMAIN, + G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + _nmtst_log_handler, + NULL); +} + +#ifndef _NMTST_INSIDE_CORE +static inline void +nmtst_init(int *argc, char ***argv, gboolean assert_logging) +{ + __nmtst_init(argc, argv, assert_logging, NULL, NULL, NULL); +} +#endif + +static inline gboolean +nmtst_is_debug(void) +{ + g_assert(nmtst_initialized()); + return __nmtst_internal.is_debug; +} + +static inline gboolean +nmtst_test_quick(void) +{ + g_assert(nmtst_initialized()); + return __nmtst_internal.test_quick; +} + +#if GLIB_CHECK_VERSION(2, 34, 0) + #undef g_test_expect_message + #define g_test_expect_message(...) \ + G_STMT_START \ + { \ + g_assert(nmtst_initialized()); \ + if (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message) { \ + g_debug("nmtst: assert-logging: g_test_expect_message %s", \ + G_STRINGIFY((__VA_ARGS__))); \ + } else { \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + g_test_expect_message(__VA_ARGS__); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + } \ + } \ + G_STMT_END + #undef g_test_assert_expected_messages_internal + #define g_test_assert_expected_messages_internal(domain, file, line, func) \ + G_STMT_START \ + { \ + const char *_domain = (domain); \ + const char *_file = (file); \ + const char *_func = (func); \ + int _line = (line); \ + \ + if (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message) \ + g_debug("nmtst: assert-logging: g_test_assert_expected_messages(%s, %s:%d, %s)", \ + _domain ?: "", \ + _file ?: "", \ + _line, \ + _func ?: ""); \ + \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + g_test_assert_expected_messages_internal(_domain, _file, _line, _func); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + } \ + G_STMT_END +#endif + +#define NMTST_EXPECT(domain, level, msg) g_test_expect_message(domain, level, msg) + +#define NMTST_EXPECT_LIBNM(level, msg) NMTST_EXPECT("nm", level, msg) + +#define NMTST_EXPECT_LIBNM_WARNING(msg) NMTST_EXPECT_LIBNM(G_LOG_LEVEL_WARNING, msg) +#define NMTST_EXPECT_LIBNM_CRITICAL(msg) NMTST_EXPECT_LIBNM(G_LOG_LEVEL_CRITICAL, msg) + +/*****************************************************************************/ + +typedef struct _NmtstTestData NmtstTestData; + +typedef void (*NmtstTestHandler)(const NmtstTestData *test_data); + +struct _NmtstTestData { + union { + const char *testpath; + char * _testpath; + }; + gsize n_args; + gpointer * args; + NmtstTestHandler _func_setup; + GTestDataFunc _func_test; + NmtstTestHandler _func_teardown; +}; + +static inline void +_nmtst_test_data_unpack(const NmtstTestData *test_data, gsize n_args, ...) +{ + gsize i; + va_list ap; + gpointer *p; + + g_assert(test_data); + g_assert_cmpint(n_args, ==, test_data->n_args); + + va_start(ap, n_args); + for (i = 0; i < n_args; i++) { + p = va_arg(ap, gpointer *); + + if (p) + *p = test_data->args[i]; + } + va_end(ap); +} +#define nmtst_test_data_unpack(test_data, ...) \ + _nmtst_test_data_unpack(test_data, NM_NARG(__VA_ARGS__), ##__VA_ARGS__) + +static inline void +_nmtst_test_data_free(gpointer data) +{ + NmtstTestData *test_data = data; + + g_assert(test_data); + + g_free(test_data->_testpath); + g_free(test_data); +} + +static inline void +_nmtst_test_run(gconstpointer data) +{ + const NmtstTestData *test_data = data; + + if (test_data->_func_setup) + test_data->_func_setup(test_data); + + test_data->_func_test(test_data); + + if (test_data->_func_teardown) + test_data->_func_teardown(test_data); +} + +static inline void +_nmtst_add_test_func_full(const char * testpath, + GTestDataFunc func_test, + NmtstTestHandler func_setup, + NmtstTestHandler func_teardown, + gsize n_args, + ...) +{ + gsize i; + NmtstTestData *data; + va_list ap; + + g_assert(testpath && testpath[0]); + g_assert(func_test); + + data = g_malloc0(sizeof(NmtstTestData) + (sizeof(gpointer) * (n_args + 1))); + + data->_testpath = g_strdup(testpath); + data->_func_test = func_test; + data->_func_setup = func_setup; + data->_func_teardown = func_teardown; + data->n_args = n_args; + data->args = (gpointer) &data[1]; + va_start(ap, n_args); + for (i = 0; i < n_args; i++) + data->args[i] = va_arg(ap, gpointer); + data->args[i] = NULL; + va_end(ap); + + g_test_add_data_func_full(testpath, data, _nmtst_test_run, _nmtst_test_data_free); +} +#define nmtst_add_test_func_full(testpath, func_test, func_setup, func_teardown, ...) \ + _nmtst_add_test_func_full(testpath, \ + func_test, \ + func_setup, \ + func_teardown, \ + NM_NARG(__VA_ARGS__), \ + ##__VA_ARGS__) +#define nmtst_add_test_func(testpath, func_test, ...) \ + nmtst_add_test_func_full(testpath, func_test, NULL, NULL, ##__VA_ARGS__) + +/*****************************************************************************/ + +static inline GRand * +nmtst_get_rand0(void) +{ + g_assert(nmtst_initialized()); + return __nmtst_internal.rand0; +} + +static inline GRand * +nmtst_get_rand(void) +{ + g_assert(nmtst_initialized()); + + if (G_UNLIKELY(!__nmtst_internal.rand)) { + guint32 seed; + const char *str = g_getenv("NMTST_SEED_RAND"); + + if (!str) { + /* No NMTST_SEED_RAND. Pick a stable one. */ + seed = 0; + __nmtst_internal.rand = g_rand_new_with_seed(seed); + } else if (str[0] == '\0') { + /* NMTST_SEED_RAND is set but empty. Pick a random one. */ + __nmtst_internal.rand = g_rand_new(); + + seed = g_rand_int(__nmtst_internal.rand); + g_rand_set_seed(__nmtst_internal.rand, seed); + } else { + /* NMTST_SEED_RAND is set. Use it as a seed. */ + char * s; + gint64 i; + + i = g_ascii_strtoll(str, &s, 0); + g_assert(s[0] == '\0' && i >= 0 && i < G_MAXUINT32); + + seed = i; + __nmtst_internal.rand = g_rand_new_with_seed(seed); + } + __nmtst_internal.rand_seed = seed; + + g_print("\nnmtst: initialize nmtst_get_rand() with NMTST_SEED_RAND=%u\n", seed); + } + return __nmtst_internal.rand; +} + +static inline guint32 +nmtst_get_rand_uint32(void) +{ + return g_rand_int(nmtst_get_rand()); +} + +static inline guint64 +nmtst_get_rand_uint64(void) +{ + GRand *rand = nmtst_get_rand(); + + return (((guint64) g_rand_int(rand))) | (((guint64) g_rand_int(rand)) << 32); +} + +static inline guint +nmtst_get_rand_uint(void) +{ + G_STATIC_ASSERT_EXPR((sizeof(guint) == sizeof(guint32) || (sizeof(guint) == sizeof(guint64)))); + if (sizeof(guint32) == sizeof(guint)) + return nmtst_get_rand_uint32(); + return nmtst_get_rand_uint64(); +} + +static inline gsize +nmtst_get_rand_size(void) +{ + G_STATIC_ASSERT_EXPR((sizeof(gsize) == sizeof(guint32) || (sizeof(gsize) == sizeof(guint64)))); + if (sizeof(gsize) == sizeof(guint32)) + return nmtst_get_rand_uint32(); + return nmtst_get_rand_uint64(); +} + +static inline gboolean +nmtst_get_rand_bool(void) +{ + return nmtst_get_rand_uint32() % 2; +} + +static inline gboolean +nmtst_get_rand_one_case_in(guint32 num) +{ + /* num=1 doesn't make much sense, because it will always return %TRUE. + * Still accept it, it might be that @num is calculated, so 1 might be + * a valid edge case. */ + g_assert(num > 0); + + return (nmtst_get_rand_uint32() % num) == 0; +} + +static inline gpointer +nmtst_rand_buf(GRand *rand, gpointer buffer, gsize buffer_length) +{ + guint32 v; + guint8 *b = buffer; + + if (!buffer_length) + return buffer; + + g_assert(buffer); + + if (!rand) + rand = nmtst_get_rand(); + + for (; buffer_length >= sizeof(guint32); + buffer_length -= sizeof(guint32), b += sizeof(guint32)) { + v = g_rand_int(rand); + memcpy(b, &v, sizeof(guint32)); + } + if (buffer_length > 0) { + v = g_rand_int(rand); + do { + *(b++) = v & 0xFF; + v >>= 8; + } while (--buffer_length > 0); + } + return buffer; +} + +#define _nmtst_rand_select(uniq, v0, ...) \ + ({ \ + typeof(v0) NM_UNIQ_T(UNIQ, uniq)[1 + NM_NARG(__VA_ARGS__)] = {(v0), __VA_ARGS__}; \ + \ + NM_UNIQ_T(UNIQ, uniq)[nmtst_get_rand_uint32() % G_N_ELEMENTS(NM_UNIQ_T(UNIQ, uniq))]; \ + }) + +#define nmtst_rand_select(...) _nmtst_rand_select(NM_UNIQ, __VA_ARGS__) + +#define nmtst_rand_select_str(x, ...) nmtst_rand_select((const char *) (x), ##__VA_ARGS__) + +static inline void * +nmtst_rand_perm(GRand *rand, void *dst, const void *src, gsize elmt_size, gsize n_elmt) +{ + gsize i, j; + char *p_, *pj; + char *bu; + + g_assert(dst); + g_assert(elmt_size > 0); + g_assert(n_elmt < G_MAXINT32); + + if (n_elmt == 0) + return dst; + + if (src && dst != src) + memcpy(dst, src, elmt_size * n_elmt); + + if (!rand) + rand = nmtst_get_rand(); + + bu = g_slice_alloc(elmt_size); + + p_ = dst; + for (i = n_elmt; i > 1; i--) { + j = g_rand_int_range(rand, 0, i); + + if (j != 0) { + pj = &p_[j * elmt_size]; + + /* swap */ + memcpy(bu, p_, elmt_size); + memcpy(p_, pj, elmt_size); + memcpy(pj, bu, elmt_size); + } + p_ += elmt_size; + } + + g_slice_free1(elmt_size, bu); + return dst; +} + +static inline const char ** +nmtst_rand_perm_strv(const char *const *strv) +{ + const char **res; + gsize n; + + if (!strv) + return NULL; + + /* this returns a (scrambled) SHALLOW copy of the strv array! */ + + n = NM_PTRARRAY_LEN(strv); + res = (const char **) (nm_utils_strv_dup(strv, n, FALSE) ?: g_new0(char *, 1)); + nmtst_rand_perm(NULL, res, res, sizeof(char *), n); + return res; +} + +static inline GSList * +nmtst_rand_perm_gslist(GRand *rand, GSList *list) +{ + GSList *result; + guint l; + + if (!rand) + rand = nmtst_get_rand(); + + /* no need for an efficient implementation :) */ + + result = 0; + for (l = g_slist_length(list); l > 0; l--) { + GSList *tmp; + + tmp = g_slist_nth(list, g_rand_int(rand) % l); + g_assert(tmp); + + list = g_slist_remove_link(list, tmp); + result = g_slist_concat(tmp, result); + } + g_assert(!list); + return result; +} + +static inline void +nmtst_stable_rand(guint64 seed, gpointer buf, gsize len) +{ + const guint64 C = 1442695040888963407llu; + const guint64 A = 6364136223846793005llu; + guint8 * b; + union { + guint8 a[sizeof(guint64)]; + guint64 n; + } n; + + /* We want a stable random generator that is in our control and does not + * depend on glibc/glib versions. + * Use a linear congruential generator (x[n+1] = (A * x[n] + C) % M) + * https://en.wikipedia.org/wiki/Linear_congruential_generator + * + * We choose (Knuth’s LCG MMIX) + * A = 6364136223846793005llu + * C = 1442695040888963407llu + * M = 2^64 + */ + + g_assert(len == 0 || buf); + + n.n = seed; + b = buf; + for (; len > 0; len--, b++) { + n.n = (A * n.n + C); + + /* let's combine the 64 bits randomness in one byte. By xor-ing, it's + * also independent of endianness. */ + b[0] = n.a[0] ^ n.a[1] ^ n.a[2] ^ n.a[3] ^ n.a[4] ^ n.a[5] ^ n.a[6] ^ n.a[7]; + } +} + +/*****************************************************************************/ + +/** + * nmtst_get_rand_word_length: + * @rand: (allow-none): #GRand instance or %NULL to use the singleton. + * + * Returns: a random integer >= 0, that most frequently is somewhere between + * 0 and 16, but (with decreasing) probability, it can be larger. This can + * be used when we generate random input for unit tests. + */ +static inline guint +nmtst_get_rand_word_length(GRand *rand) +{ + guint n; + + if (!rand) + rand = nmtst_get_rand(); + + n = 0; + while (TRUE) { + guint32 rnd = g_rand_int(rand); + guint probability; + + /* The following python code implements a random sample with this + * distribution: + * + * def random_histogram(n_tries, scale = None): + * def probability(n_tok): + * import math + * return max(2, math.floor(100 / (2*(n_tok+1)))) + * def n_tokens(): + * import random + * n_tok = 0 + * while True: + * if random.randint(0, 0xFFFFFFFF) % probability(n_tok) == 0: + * return n_tok + * n_tok += 1 + * hist = [] + * i = 0; + * while i < n_tries: + * n_tok = n_tokens() + * while n_tok >= len(hist): + * hist.append(0) + * hist[n_tok] = hist[n_tok] + 1 + * i += 1 + * if scale is not None: + * hist = list([round(x / n_tries * scale) for x in hist]) + * return hist + * + * For example, random_histogram(n_tries = 1000000, scale = 1000) may give + * + * IDX: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] + * SEEN: [20, 39, 59, 73, 80, 91, 92, 90, 91, 73, 73, 54, 55, 36, 24, 16, 16, 8, 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0] + * + * which give a sense of the probability with this individual results are returned. + */ + probability = NM_MAX(2u, (100u / (2u * (n + 1u)))); + if ((rnd % probability) == 0) + return n; + n++; + } +} + +/*****************************************************************************/ + +static inline gboolean +nmtst_g_source_assert_not_called(gpointer user_data) +{ + g_assert_not_reached(); + return G_SOURCE_CONTINUE; +} + +static inline gboolean +nmtst_g_source_nop(gpointer user_data) +{ + g_assert(!user_data); + return G_SOURCE_CONTINUE; +} + +static inline gboolean +nmtst_g_source_set_boolean_true(gpointer user_data) +{ + gboolean *ptr = user_data; + + g_assert(ptr); + g_assert(!*ptr); + *ptr = TRUE; + return G_SOURCE_CONTINUE; +} + +/*****************************************************************************/ + +static inline gboolean +_nmtst_main_loop_run_timeout(gpointer user_data) +{ + GMainLoop **p_loop = user_data; + + g_assert(p_loop && *p_loop); + g_main_loop_quit(g_steal_pointer(p_loop)); + return G_SOURCE_REMOVE; +} + +static inline gboolean +nmtst_main_loop_run(GMainLoop *loop, guint timeout_msec) +{ + nm_auto_unref_gsource GSource *source = NULL; + GMainLoop * loopx = loop; + + if (timeout_msec > 0) { + source = g_timeout_source_new(timeout_msec); + g_source_set_callback(source, _nmtst_main_loop_run_timeout, &loopx, NULL); + g_source_attach(source, g_main_loop_get_context(loop)); + } + + g_main_loop_run(loop); + + if (source) + g_source_destroy(source); + + /* if the timeout was reached, return FALSE. */ + return loopx != NULL; +} + +#define nmtst_main_loop_run_assert(loop, timeout_msec) \ + G_STMT_START \ + { \ + if (!nmtst_main_loop_run((loop), (timeout_msec))) \ + g_assert_not_reached(); \ + } \ + G_STMT_END + +static inline void +_nmtst_main_loop_quit_on_notify(GObject *object, GParamSpec *pspec, gpointer user_data) +{ + GMainLoop *loop = user_data; + + g_assert(G_IS_OBJECT(object)); + g_assert(loop); + + g_main_loop_quit(loop); +} +#define nmtst_main_loop_quit_on_notify ((GCallback) _nmtst_main_loop_quit_on_notify) + +#define nmtst_main_context_iterate_until_full(context, timeout_msec, poll_msec, condition) \ + ({ \ + nm_auto_destroy_and_unref_gsource GSource *_source_timeout = NULL; \ + nm_auto_destroy_and_unref_gsource GSource *_source_poll = NULL; \ + GMainContext * _context = (context); \ + gboolean _had_timeout = FALSE; \ + typeof(timeout_msec) _timeout_msec0 = (timeout_msec); \ + typeof(poll_msec) _poll_msec0 = (poll_msec); \ + gint64 _timeout_msec = _timeout_msec0; \ + guint _poll_msec = _poll_msec0; \ + \ + g_assert_cmpint(_timeout_msec0, ==, _timeout_msec); \ + g_assert_cmpint(_poll_msec0, ==, _poll_msec); \ + \ + _source_timeout = g_timeout_source_new(NM_CLAMP(_timeout_msec, 0, (gint64) G_MAXUINT)); \ + g_source_set_callback(_source_timeout, \ + nmtst_g_source_set_boolean_true, \ + &_had_timeout, \ + NULL); \ + g_source_attach(_source_timeout, _context); \ + \ + if (_poll_msec > 0) { \ + _source_poll = g_timeout_source_new(_poll_msec); \ + g_source_set_callback(_source_poll, nmtst_g_source_nop, NULL, NULL); \ + g_source_attach(_source_poll, _context); \ + } \ + \ + while (TRUE) { \ + if (condition) \ + break; \ + g_main_context_iteration(_context, TRUE); \ + if (_had_timeout) \ + break; \ + } \ + \ + !_had_timeout; \ + }) + +#define nmtst_main_context_iterate_until(context, timeout_msec, condition) \ + nmtst_main_context_iterate_until_full((context), (timeout_msec), 0, condition) + +#define nmtst_main_context_iterate_until_assert_full(context, timeout_msec, poll_msec, condition) \ + G_STMT_START \ + { \ + if (!nmtst_main_context_iterate_until_full((context), \ + (timeout_msec), \ + (poll_msec), \ + condition)) \ + g_assert(FALSE &&#condition); \ + } \ + G_STMT_END + +#define nmtst_main_context_iterate_until_assert(context, timeout_msec, condition) \ + nmtst_main_context_iterate_until_assert_full((context), (timeout_msec), 0, condition) + +/*****************************************************************************/ + +static inline void +nmtst_main_context_assert_no_dispatch(GMainContext *context, guint timeout_msec) +{ + nm_auto_destroy_and_unref_gsource GSource *source = NULL; + gboolean timeout_hit = FALSE; + + source = g_timeout_source_new(timeout_msec); + g_source_set_callback(source, nmtst_g_source_set_boolean_true, &timeout_hit, NULL); + g_source_attach(source, context); + + while (g_main_context_iteration(context, TRUE)) { + if (timeout_hit) + return; + g_assert_not_reached(); + } +} + +/*****************************************************************************/ + +typedef struct { + GMainLoop *_main_loop; + union { + GSList * _list; + const void *const is_waiting; + }; +} NMTstContextBusyWatcherData; + +static inline void +_nmtst_context_busy_watcher_add_cb(gpointer data, GObject *where_the_object_was) +{ + NMTstContextBusyWatcherData *watcher_data = data; + GSList * l; + + g_assert(watcher_data); + + l = g_slist_find(watcher_data->_list, where_the_object_was); + g_assert(l); + + watcher_data->_list = g_slist_delete_link(watcher_data->_list, l); + if (!watcher_data->_list) + g_main_loop_quit(watcher_data->_main_loop); +} + +static inline void +nmtst_context_busy_watcher_add(NMTstContextBusyWatcherData *watcher_data, GObject *object) +{ + g_assert(watcher_data); + g_assert(G_IS_OBJECT(object)); + + if (!watcher_data->_main_loop) { + watcher_data->_main_loop = g_main_loop_new(g_main_context_get_thread_default(), FALSE); + g_assert(!watcher_data->_list); + } else { + g_assert(g_main_loop_get_context(watcher_data->_main_loop) + == (g_main_context_get_thread_default() ?: g_main_context_default())); + } + + g_object_weak_ref(object, _nmtst_context_busy_watcher_add_cb, watcher_data); + watcher_data->_list = g_slist_prepend(watcher_data->_list, object); +} + +static inline void +nmtst_context_busy_watcher_wait(NMTstContextBusyWatcherData *watcher_data) +{ + g_assert(watcher_data); + + if (!watcher_data->_main_loop) { + g_assert(!watcher_data->_list); + return; + } + + if (watcher_data->_list) { + if (!nmtst_main_loop_run(watcher_data->_main_loop, 5000)) + g_error("timeout running mainloop waiting for GObject to destruct"); + } + + g_assert(!watcher_data->_list); + nm_clear_pointer(&watcher_data->_main_loop, g_main_loop_unref); +} + +/*****************************************************************************/ + +static inline const char * +nmtst_get_sudo_cmd(void) +{ + g_assert(nmtst_initialized()); + return __nmtst_internal.sudo_cmd; +} + +static inline void +nmtst_reexec_sudo(void) +{ + char * str; + char **argv; + int i; + int errsv; + + g_assert(nmtst_initialized()); + g_assert(__nmtst_internal.orig_argv); + + if (!__nmtst_internal.sudo_cmd) + return; + + str = g_strjoinv(" ", __nmtst_internal.orig_argv); + __NMTST_LOG(g_message, ">> exec %s %s", __nmtst_internal.sudo_cmd, str); + + argv = g_new0(char *, 1 + g_strv_length(__nmtst_internal.orig_argv) + 1); + argv[0] = __nmtst_internal.sudo_cmd; + for (i = 0; __nmtst_internal.orig_argv[i]; i++) + argv[i + 1] = __nmtst_internal.orig_argv[i]; + + execvp(__nmtst_internal.sudo_cmd, argv); + + errsv = errno; + g_error(">> exec %s failed: %d - %s", + __nmtst_internal.sudo_cmd, + errsv, + nm_strerror_native(errsv)); +} + +/*****************************************************************************/ + +static inline gsize +nmtst_find_all_indexes(gpointer *elements, + gsize n_elements, + gpointer *needles, + gsize n_needles, + gboolean (*equal_fcn)(gpointer element, gpointer needle, gpointer user_data), + gpointer user_data, + gssize * out_idx) +{ + gsize i, j, k; + gsize found = 0; + + for (i = 0; i < n_needles; i++) { + gssize idx = -1; + + for (j = 0; j < n_elements; j++) { + /* no duplicates */ + for (k = 0; k < i; k++) { + if (out_idx[k] == j) + goto next; + } + + if (equal_fcn(elements[j], needles[i], user_data)) { + idx = j; + break; + } +next:; + } + + out_idx[i] = idx; + if (idx >= 0) + found++; + } + + return found; +} + +/*****************************************************************************/ + +#define __define_nmtst_static(NUM, SIZE) \ + static inline const char *nmtst_static_##SIZE##_##NUM(const char *str) \ + { \ + gsize l; \ + static _nm_thread_local char buf[SIZE]; \ + \ + if (!str) \ + return NULL; \ + l = g_strlcpy(buf, str, sizeof(buf)); \ + g_assert(l < sizeof(buf)); \ + return buf; \ + } +__define_nmtst_static(01, 1024) __define_nmtst_static(02, 1024) __define_nmtst_static(03, 1024) +#undef __define_nmtst_static + +#if defined(__NM_UTILS_H__) || defined(NM_UTILS_H) + + #define NMTST_UUID_INIT(uuid) \ + gs_free char * _nmtst_hidden_##uuid = nm_utils_uuid_generate(); \ + const char *const uuid = _nmtst_hidden_##uuid + + static inline const char *nmtst_uuid_generate(void) +{ + static _nm_thread_local char u[37]; + gs_free char * m = NULL; + + m = nm_utils_uuid_generate(); + g_assert(m && strlen(m) == sizeof(u) - 1); + memcpy(u, m, sizeof(u)); + return u; +} + +#endif + +#define nmtst_assert_str_has_substr(str, substr) \ + G_STMT_START \ + { \ + const char *__str = (str); \ + const char *__substr = (substr); \ + \ + g_assert(__str); \ + g_assert(__substr); \ + if (strstr(__str, __substr) == NULL) \ + g_error("%s:%d: Expects \"%s\" but got \"%s\"", __FILE__, __LINE__, __substr, __str); \ + } \ + G_STMT_END + +static inline in_addr_t +nmtst_inet4_from_string(const char *str) +{ + in_addr_t addr; + int success; + + if (!str) + return 0; + + success = inet_pton(AF_INET, str, &addr); + + g_assert(success == 1); + + return addr; +} + +static inline const struct in6_addr * +nmtst_inet6_from_string(const char *str) +{ + static _nm_thread_local struct in6_addr addr; + int success; + + if (!str) + addr = in6addr_any; + else { + success = inet_pton(AF_INET6, str, &addr); + g_assert(success == 1); + } + + return &addr; +} + +static inline gconstpointer +nmtst_inet_from_string(int addr_family, const char *str) +{ + if (addr_family == AF_INET) { + static in_addr_t a; + + a = nmtst_inet4_from_string(str); + return &a; + } + if (addr_family == AF_INET6) + return nmtst_inet6_from_string(str); + + g_assert_not_reached(); + return NULL; +} + +static inline const char * +nmtst_inet_to_string(int addr_family, gconstpointer addr) +{ + static _nm_thread_local char buf[NM_CONST_MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)]; + + g_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + g_assert(addr); + + if (inet_ntop(addr_family, addr, buf, sizeof(buf)) != buf) + g_assert_not_reached(); + + return buf; +} + +static inline const char * +nmtst_inet4_to_string(in_addr_t addr) +{ + return nmtst_inet_to_string(AF_INET, &addr); +} + +static inline const char * +nmtst_inet6_to_string(const struct in6_addr *addr) +{ + return nmtst_inet_to_string(AF_INET6, addr); +} + +static inline void +_nmtst_assert_ip4_address(const char *file, int line, in_addr_t addr, const char *str_expected) +{ + if (nmtst_inet4_from_string(str_expected) != addr) { + char buf[100]; + + g_error("%s:%d: Unexpected IPv4 address: expected %s, got %s", + file, + line, + str_expected ?: "0.0.0.0", + inet_ntop(AF_INET, &addr, buf, sizeof(buf))); + } +} +#define nmtst_assert_ip4_address(addr, str_expected) \ + _nmtst_assert_ip4_address(__FILE__, __LINE__, addr, str_expected) + +static inline void +_nmtst_assert_ip6_address(const char * file, + int line, + const struct in6_addr *addr, + const char * str_expected) +{ + struct in6_addr any = in6addr_any; + + if (!addr) + addr = &any; + + if (memcmp(nmtst_inet6_from_string(str_expected), addr, sizeof(*addr)) != 0) { + char buf[100]; + + g_error("%s:%d: Unexpected IPv6 address: expected %s, got %s", + file, + line, + str_expected ?: "::", + inet_ntop(AF_INET6, addr, buf, sizeof(buf))); + } +} +#define nmtst_assert_ip6_address(addr, str_expected) \ + _nmtst_assert_ip6_address(__FILE__, __LINE__, addr, str_expected) + +#define nmtst_assert_ip_address(addr_family, addr, str_expected) \ + G_STMT_START \ + { \ + if (NM_IS_IPv4(addr_family)) \ + nmtst_assert_ip4_address(*((const in_addr_t *) (addr)), (str_expected)); \ + else \ + nmtst_assert_ip6_address((const struct in6_addr *) (addr), (str_expected)); \ + } \ + G_STMT_END + +#define nmtst_spawn_sync(working_directory, standard_out, standard_err, assert_exit_status, ...) \ + __nmtst_spawn_sync(working_directory, \ + standard_out, \ + standard_err, \ + assert_exit_status, \ + ##__VA_ARGS__, \ + NULL) +static inline int __nmtst_spawn_sync(const char *working_directory, + char ** standard_out, + char ** standard_err, + int assert_exit_status, + ...) G_GNUC_NULL_TERMINATED; +static inline int +__nmtst_spawn_sync(const char *working_directory, + char ** standard_out, + char ** standard_err, + int assert_exit_status, + ...) +{ + int exit_status = 0; + GError * error = NULL; + char * arg; + va_list va_args; + GPtrArray *argv = g_ptr_array_new(); + gboolean success; + + va_start(va_args, assert_exit_status); + while ((arg = va_arg(va_args, char *))) + g_ptr_array_add(argv, arg); + va_end(va_args); + + g_assert(argv->len >= 1); + g_ptr_array_add(argv, NULL); + + success = g_spawn_sync(working_directory, + (char **) argv->pdata, + NULL, + 0 /*G_SPAWN_DEFAULT*/, + NULL, + NULL, + standard_out, + standard_err, + &exit_status, + &error); + if (!success) + g_error("nmtst_spawn_sync(%s): %s", ((char **) argv->pdata)[0], error->message); + g_assert(!error); + + g_assert(!standard_out || *standard_out); + g_assert(!standard_err || *standard_err); + + if (assert_exit_status != -1) { + /* exit status is a guint8 on success. Set @assert_exit_status to -1 + * not to check for the exit status. */ + g_assert(WIFEXITED(exit_status)); + g_assert_cmpint(WEXITSTATUS(exit_status), ==, assert_exit_status); + } + + g_ptr_array_free(argv, TRUE); + return exit_status; +} + +/*****************************************************************************/ + +static inline char * +nmtst_file_resolve_relative_path(const char *rel, const char *cwd) +{ + gs_free char *cwd_free = NULL; + + g_assert(rel && *rel); + + if (g_path_is_absolute(rel)) + return g_strdup(rel); + + if (!cwd) + cwd = cwd_free = g_get_current_dir(); + return g_build_filename(cwd, rel, NULL); +} + +static inline char * +nmtst_file_get_contents(const char *filename) +{ + GError * error = NULL; + gboolean success; + char * contents = NULL; + gsize len; + + success = g_file_get_contents(filename, &contents, &len, &error); + nmtst_assert_success(success && contents, error); + g_assert_cmpint(strlen(contents), ==, len); + return contents; +} + +#define nmtst_file_set_contents_size(filename, content, size) \ + G_STMT_START \ + { \ + GError * _error = NULL; \ + gboolean _success; \ + const char *_content = (content); \ + gssize _size = (size); \ + \ + g_assert(_content); \ + \ + if (_size < 0) { \ + g_assert(_size == -1); \ + _size = strlen(_content); \ + } \ + \ + _success = g_file_set_contents((filename), _content, _size, &_error); \ + nmtst_assert_success(_success, _error); \ + } \ + G_STMT_END + +#define nmtst_file_set_contents(filename, content) \ + nmtst_file_set_contents_size(filename, content, -1) + +/*****************************************************************************/ + +static inline void +nmtst_file_unlink_if_exists(const char *name) +{ + int errsv; + + g_assert(name && name[0]); + + if (unlink(name) != 0) { + errsv = errno; + if (errsv != ENOENT) + g_error("nmtst_file_unlink_if_exists(%s): failed with %s", + name, + nm_strerror_native(errsv)); + } +} + +static inline void +nmtst_file_unlink(const char *name) +{ + int errsv; + + g_assert(name && name[0]); + + if (unlink(name) != 0) { + errsv = errno; + g_error("nmtst_file_unlink(%s): failed with %s", name, nm_strerror_native(errsv)); + } +} + +static inline void +_nmtst_auto_unlinkfile(char **p_name) +{ + if (*p_name) { + nmtst_file_unlink(*p_name); + nm_clear_g_free(p_name); + } +} + +#define nmtst_auto_unlinkfile nm_auto(_nmtst_auto_unlinkfile) + +/*****************************************************************************/ + +static inline void +_nmtst_assert_resolve_relative_path_equals(const char *f1, + const char *f2, + const char *file, + int line) +{ + gs_free char *p1 = NULL, *p2 = NULL; + + p1 = nmtst_file_resolve_relative_path(f1, NULL); + p2 = nmtst_file_resolve_relative_path(f2, NULL); + g_assert(p1 && *p1); + + /* Fixme: later we might need to coalesce repeated '/', "./", and "../". + * For now, it's good enough. */ + if (g_strcmp0(p1, p2) != 0) + g_error("%s:%d : filenames don't match \"%s\" vs. \"%s\" // \"%s\" - \"%s\"", + file, + line, + f1, + f2, + p1, + p2); +} +#define nmtst_assert_resolve_relative_path_equals(f1, f2) \ + _nmtst_assert_resolve_relative_path_equals(f1, f2, __FILE__, __LINE__); + +/*****************************************************************************/ + +#ifdef __NETWORKMANAGER_LOGGING_H__ + + #define NMTST_EXPECT_NM(level, msg) NMTST_EXPECT("NetworkManager", level, msg) + + #define NMTST_EXPECT_NM_ERROR(msg) NMTST_EXPECT_NM(G_LOG_LEVEL_MESSAGE, "* [*] " msg) + #define NMTST_EXPECT_NM_WARN(msg) NMTST_EXPECT_NM(G_LOG_LEVEL_MESSAGE, "* [*] " msg) + #define NMTST_EXPECT_NM_INFO(msg) NMTST_EXPECT_NM(G_LOG_LEVEL_INFO, "* [*] " msg) + #define NMTST_EXPECT_NM_DEBUG(msg) NMTST_EXPECT_NM(G_LOG_LEVEL_DEBUG, "* [*] " msg) + #define NMTST_EXPECT_NM_TRACE(msg) NMTST_EXPECT_NM(G_LOG_LEVEL_DEBUG, "* [*] " msg) + +static inline void +nmtst_init_with_logging(int *argc, char ***argv, const char *log_level, const char *log_domains) +{ + __nmtst_init(argc, argv, FALSE, log_level, log_domains, NULL); +} +static inline void +nmtst_init_assert_logging(int *argc, char ***argv, const char *log_level, const char *log_domains) +{ + gboolean set_logging; + + __nmtst_init(argc, argv, TRUE, NULL, NULL, &set_logging); + + if (!set_logging) { + gboolean success; + + success = nm_logging_setup(log_level, log_domains, NULL, NULL); + g_assert(success); + } +} + +#endif + +/*****************************************************************************/ + +#ifdef __NETWORKMANAGER_LOGGING_H__ +static inline gpointer +nmtst_logging_disable(gboolean always) +{ + gpointer p; + + g_assert(nmtst_initialized()); + if (!always && __nmtst_internal.no_expect_message) { + /* The caller does not want to @always suppress logging. Instead, + * the caller wants to suppress unexpected log messages that would + * fail assertions (since we possibly assert against all unexpected + * log messages). + * + * If the test is run with no-expect-message, then don't suppress + * the loggings, because they also wouldn't fail assertions. */ + return NULL; + } + + p = g_memdup(_nm_logging_enabled_state, sizeof(_nm_logging_enabled_state)); + memset(_nm_logging_enabled_state, 0, sizeof(_nm_logging_enabled_state)); + return p; +} + +static inline void +nmtst_logging_reenable(gpointer old_state) +{ + g_assert(nmtst_initialized()); + if (old_state) { + memcpy(_nm_logging_enabled_state, old_state, sizeof(_nm_logging_enabled_state)); + g_free(old_state); + } +} +#endif + +/*****************************************************************************/ + +#ifdef NM_SETTING_IP_CONFIG_H +static inline void +nmtst_setting_ip_config_add_address(NMSettingIPConfig *s_ip, const char *address, guint prefix) +{ + NMIPAddress *addr; + int family; + + g_assert(s_ip); + + if (nm_utils_ipaddr_is_valid(AF_INET, address)) + family = AF_INET; + else if (nm_utils_ipaddr_is_valid(AF_INET6, address)) + family = AF_INET6; + else + g_assert_not_reached(); + + addr = nm_ip_address_new(family, address, prefix, NULL); + g_assert(addr); + g_assert(nm_setting_ip_config_add_address(s_ip, addr)); + nm_ip_address_unref(addr); +} + +static inline void +nmtst_setting_ip_config_add_route(NMSettingIPConfig *s_ip, + const char * dest, + guint prefix, + const char * next_hop, + gint64 metric) +{ + NMIPRoute *route; + int family; + + g_assert(s_ip); + + if (nm_utils_ipaddr_is_valid(AF_INET, dest)) + family = AF_INET; + else if (nm_utils_ipaddr_is_valid(AF_INET6, dest)) + family = AF_INET6; + else + g_assert_not_reached(); + + route = nm_ip_route_new(family, dest, prefix, next_hop, metric, NULL); + g_assert(route); + g_assert(nm_setting_ip_config_add_route(s_ip, route)); + nm_ip_route_unref(route); +} + +static inline void +nmtst_assert_route_attribute_string(NMIPRoute *route, const char *name, const char *value) +{ + GVariant *variant; + + variant = nm_ip_route_get_attribute(route, name); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr(g_variant_get_string(variant, NULL), ==, value); +} + +static inline void +nmtst_assert_route_attribute_byte(NMIPRoute *route, const char *name, guchar value) +{ + GVariant *variant; + + variant = nm_ip_route_get_attribute(route, name); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_BYTE)); + g_assert_cmpint(g_variant_get_byte(variant), ==, value); +} + +static inline void +nmtst_assert_route_attribute_uint32(NMIPRoute *route, const char *name, guint32 value) +{ + GVariant *variant; + + variant = nm_ip_route_get_attribute(route, name); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32)); + g_assert_cmpint(g_variant_get_uint32(variant), ==, value); +} + +static inline void +nmtst_assert_route_attribute_boolean(NMIPRoute *route, const char *name, gboolean value) +{ + GVariant *variant; + + variant = nm_ip_route_get_attribute(route, name); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)); + g_assert_cmpint(g_variant_get_boolean(variant), ==, value); +} +#endif /* NM_SETTING_IP_CONFIG_H */ + +#if (defined(__NM_SIMPLE_CONNECTION_H__) && defined(__NM_SETTING_CONNECTION_H__)) \ + || (defined(NM_CONNECTION_H)) + +static inline NMConnection * +nmtst_clone_connection(NMConnection *connection) +{ + g_assert(NM_IS_CONNECTION(connection)); + + #if defined(__NM_SIMPLE_CONNECTION_H__) + return nm_simple_connection_new_clone(connection); + #else + return nm_connection_duplicate(connection); + #endif +} + +static inline NMConnection * +nmtst_create_minimal_connection(const char * id, + const char * uuid, + const char * type, + NMSettingConnection **out_s_con) +{ + NMConnection * con; + NMSetting * s_base = NULL; + NMSettingConnection *s_con; + gs_free char * uuid_free = NULL; + + g_assert(id); + + if (uuid) + g_assert(nm_utils_is_uuid(uuid)); + else + uuid = uuid_free = nm_utils_uuid_generate(); + + if (type) { + GType type_g; + + #if defined(__NM_SIMPLE_CONNECTION_H__) + type_g = nm_setting_lookup_type(type); + #else + type_g = nm_connection_lookup_setting_type(type); + #endif + + g_assert(type_g != G_TYPE_INVALID); + + s_base = g_object_new(type_g, NULL); + g_assert(NM_IS_SETTING(s_base)); + } + + #if defined(__NM_SIMPLE_CONNECTION_H__) + con = nm_simple_connection_new(); + #else + con = nm_connection_new(); + #endif + + g_assert(con); + + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + + g_assert(s_con); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + id, + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + type, + NULL); + nm_connection_add_setting(con, NM_SETTING(s_con)); + + if (s_base) + nm_connection_add_setting(con, s_base); + + if (out_s_con) + *out_s_con = s_con; + return con; +} + +static inline gboolean +_nmtst_connection_normalize_v(NMConnection *connection, va_list args) +{ + GError * error = NULL; + gboolean success; + gboolean was_modified = FALSE; + GHashTable *parameters = NULL; + const char *p_name; + + g_assert(NM_IS_CONNECTION(connection)); + + while ((p_name = va_arg(args, const char *))) { + if (!parameters) + parameters = g_hash_table_new(g_str_hash, g_str_equal); + g_hash_table_insert(parameters, (gpointer *) p_name, va_arg(args, gpointer)); + } + + success = nm_connection_normalize(connection, parameters, &was_modified, &error); + g_assert_no_error(error); + g_assert(success); + + if (parameters) + g_hash_table_destroy(parameters); + + return was_modified; +} + +static inline gboolean +_nmtst_connection_normalize(NMConnection *connection, ...) +{ + gboolean was_modified; + va_list args; + + va_start(args, connection); + was_modified = _nmtst_connection_normalize_v(connection, args); + va_end(args); + + return was_modified; +} + #define nmtst_connection_normalize(connection, ...) \ + _nmtst_connection_normalize(connection, ##__VA_ARGS__, NULL) + +static inline NMConnection * +_nmtst_connection_duplicate_and_normalize(NMConnection *connection, ...) +{ + va_list args; + + connection = nmtst_clone_connection(connection); + + va_start(args, connection); + _nmtst_connection_normalize_v(connection, args); + va_end(args); + + return connection; +} + #define nmtst_connection_duplicate_and_normalize(connection, ...) \ + _nmtst_connection_duplicate_and_normalize(connection, ##__VA_ARGS__, NULL) + +static inline void +nmtst_assert_connection_equals(NMConnection *a, + gboolean normalize_a, + NMConnection *b, + gboolean normalize_b) +{ + gboolean compare; + gs_unref_object NMConnection *a2 = NULL; + gs_unref_object NMConnection *b2 = NULL; + GHashTable * out_settings = NULL; + + g_assert(NM_IS_CONNECTION(a)); + g_assert(NM_IS_CONNECTION(b)); + + if (normalize_a) + a = a2 = nmtst_connection_duplicate_and_normalize(a); + if (normalize_b) + b = b2 = nmtst_connection_duplicate_and_normalize(b); + + compare = nm_connection_diff(a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_settings); + if (!compare || out_settings) { + const char * name, *pname; + GHashTable * setting; + GHashTableIter iter, iter2; + + __NMTST_LOG(g_message, ">>> ASSERTION nmtst_assert_connection_equals() fails"); + if (out_settings) { + g_hash_table_iter_init(&iter, out_settings); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &setting)) { + __NMTST_LOG(g_message, ">>> differences in setting '%s':", name); + + g_hash_table_iter_init(&iter2, setting); + while (g_hash_table_iter_next(&iter2, (gpointer *) &pname, NULL)) + __NMTST_LOG(g_message, ">>> differences in setting '%s.%s'", name, pname); + } + } + + #ifdef __NM_KEYFILE_INTERNAL_H__ + { + nm_auto_unref_keyfile GKeyFile *kf_a = NULL, *kf_b = NULL; + gs_free char * str_a = NULL, *str_b = NULL; + + kf_a = nm_keyfile_write(a, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, NULL); + kf_b = nm_keyfile_write(b, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, NULL); + + if (kf_a) + str_a = g_key_file_to_data(kf_a, NULL, NULL); + if (kf_b) + str_b = g_key_file_to_data(kf_b, NULL, NULL); + + __NMTST_LOG(g_message, + ">>> Connection A as kf (*WARNING: keyfile representation might not show " + "the difference*):\n%s", + str_a); + __NMTST_LOG(g_message, + ">>> Connection B as kf (*WARNING: keyfile representation might not show " + "the difference*):\n%s", + str_b); + } + #endif + } + g_assert(compare); + g_assert(!out_settings); + + compare = nm_connection_compare(a, b, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert(compare); +} + +static inline void +nmtst_assert_connection_verifies(NMConnection *con) +{ + /* assert that the connection does verify, it might be normaliziable or not */ + GError * error = NULL; + gboolean success; + + g_assert(NM_IS_CONNECTION(con)); + + success = nm_connection_verify(con, &error); + g_assert_no_error(error); + g_assert(success); +} + +static inline void +nmtst_assert_connection_verifies_without_normalization(NMConnection *con) +{ + /* assert that the connection verifies and does not need any normalization */ + GError * error = NULL; + gboolean success; + gboolean was_modified = FALSE; + gs_unref_object NMConnection *clone = NULL; + + clone = nmtst_clone_connection(con); + + nmtst_assert_connection_verifies(con); + + success = nm_connection_normalize(clone, NULL, &was_modified, &error); + g_assert_no_error(error); + g_assert(success); + nmtst_assert_connection_equals(con, FALSE, clone, FALSE); + g_assert(!was_modified); +} + +static inline void +nmtst_assert_connection_verifies_and_normalizable(NMConnection *con) +{ + /* assert that the connection does verify, but normalization still modifies it */ + GError * error = NULL; + gboolean success; + gboolean was_modified = FALSE; + gs_unref_object NMConnection *clone = NULL; + + clone = nmtst_clone_connection(con); + + nmtst_assert_connection_verifies(con); + + success = nm_connection_normalize(clone, NULL, &was_modified, &error); + g_assert_no_error(error); + g_assert(success); + g_assert(was_modified); + + /* again! */ + nmtst_assert_connection_verifies_without_normalization(clone); +} + +static inline void +nmtst_assert_connection_verifies_after_normalization(NMConnection *con, + GQuark expect_error_domain, + int expect_error_code) +{ + /* assert that the connection does not verify, but normalization does fix it */ + GError * error = NULL; + gboolean success; + gboolean was_modified = FALSE; + gs_unref_object NMConnection *clone = NULL; + + clone = nmtst_clone_connection(con); + + success = nm_connection_verify(con, &error); + nmtst_assert_error(error, expect_error_domain, expect_error_code, NULL); + g_assert(!success); + g_clear_error(&error); + + success = nm_connection_normalize(clone, NULL, &was_modified, &error); + g_assert_no_error(error); + g_assert(success); + g_assert(was_modified); + + /* again! */ + nmtst_assert_connection_verifies_without_normalization(clone); +} + +static inline void +nmtst_assert_connection_unnormalizable(NMConnection *con, + GQuark expect_error_domain, + int expect_error_code) +{ + /* assert that the connection does not verify, and it cannot be fixed by normalization */ + + GError * error = NULL; + gboolean success; + gboolean was_modified = FALSE; + gs_unref_object NMConnection *clone = NULL; + + clone = nmtst_clone_connection(con); + + success = nm_connection_verify(con, &error); + nmtst_assert_error(error, expect_error_domain, expect_error_code, NULL); + g_assert(!success); + g_clear_error(&error); + + success = nm_connection_normalize(clone, NULL, &was_modified, &error); + nmtst_assert_error(error, expect_error_domain, expect_error_code, NULL); + g_assert(!success); + g_assert(!was_modified); + nmtst_assert_connection_equals(con, FALSE, clone, FALSE); + g_clear_error(&error); +} + +static inline void +nmtst_assert_setting_verifies(NMSetting *setting) +{ + /* assert that the setting verifies without an error */ + + GError * error = NULL; + gboolean success; + + g_assert(NM_IS_SETTING(setting)); + + success = nm_setting_verify(setting, NULL, &error); + g_assert_no_error(error); + g_assert(success); +} + + #if defined(__NM_SIMPLE_CONNECTION_H__) && NM_CHECK_VERSION(1, 10, 0) \ + && (!defined(NM_VERSION_MAX_ALLOWED) || NM_VERSION_MAX_ALLOWED >= NM_VERSION_1_10) +static inline void +_nmtst_assert_connection_has_settings(NMConnection *connection, + gboolean has_at_least, + gboolean has_at_most, + ...) +{ + gs_unref_hashtable GHashTable *names = NULL; + gs_free NMSetting **settings = NULL; + va_list ap; + const char * name; + guint i, len; + gs_unref_ptrarray GPtrArray *names_arr = NULL; + + g_assert(NM_IS_CONNECTION(connection)); + + names = g_hash_table_new(g_str_hash, g_str_equal); + names_arr = g_ptr_array_new(); + + va_start(ap, has_at_most); + while ((name = va_arg(ap, const char *))) { + if (!nm_g_hash_table_add(names, (gpointer) name)) + g_assert_not_reached(); + g_ptr_array_add(names_arr, (gpointer) name); + } + va_end(ap); + + g_ptr_array_add(names_arr, NULL); + + settings = nm_connection_get_settings(connection, &len); + for (i = 0; i < len; i++) { + if (!g_hash_table_remove(names, nm_setting_get_name(settings[i])) && has_at_most) { + g_error( + "nmtst_assert_connection_has_settings(): has setting \"%s\" which is not expected", + nm_setting_get_name(settings[i])); + } + } + if (g_hash_table_size(names) > 0 && has_at_least) { + gs_free char * expected_str = g_strjoinv(" ", (char **) names_arr->pdata); + gs_free const char **settings_names = NULL; + gs_free char * has_str = NULL; + + settings_names = g_new0(const char *, len + 1); + for (i = 0; i < len; i++) + settings_names[i] = nm_setting_get_name(settings[i]); + has_str = g_strjoinv(" ", (char **) settings_names); + + g_error("nmtst_assert_connection_has_settings(): the setting lacks %u expected settings " + "(expected: [%s] vs. has: [%s])", + g_hash_table_size(names), + expected_str, + has_str); + } +} + #define nmtst_assert_connection_has_settings(connection, ...) \ + _nmtst_assert_connection_has_settings((connection), TRUE, TRUE, __VA_ARGS__, NULL) + #define nmtst_assert_connection_has_settings_at_least(connection, ...) \ + _nmtst_assert_connection_has_settings((connection), TRUE, FALSE, __VA_ARGS__, NULL) + #define nmtst_assert_connection_has_settings_at_most(connection, ...) \ + _nmtst_assert_connection_has_settings((connection), FALSE, TRUE, __VA_ARGS__, NULL) + #endif + +static inline void +nmtst_assert_setting_verify_fails(NMSetting *setting, + GQuark expect_error_domain, + int expect_error_code) +{ + /* assert that the setting verification fails */ + + GError * error = NULL; + gboolean success; + + g_assert(NM_IS_SETTING(setting)); + + success = nm_setting_verify(setting, NULL, &error); + nmtst_assert_error(error, expect_error_domain, expect_error_code, NULL); + g_assert(!success); + g_clear_error(&error); +} + +static inline void +nmtst_assert_setting_is_equal(gconstpointer /* const NMSetting * */ a, + gconstpointer /* const NMSetting * */ b, + NMSettingCompareFlags flags) +{ + gs_unref_hashtable GHashTable *hash = NULL; + guint32 r = nmtst_get_rand_uint32(); + + g_assert(NM_IS_SETTING(a)); + g_assert(NM_IS_SETTING(b)); + + if (NM_FLAGS_HAS(r, 0x4)) + NM_SWAP(&a, &b); + + g_assert(nm_setting_compare((NMSetting *) a, (NMSetting *) b, flags)); + + if (NM_FLAGS_HAS(r, 0x8)) + NM_SWAP(&a, &b); + + g_assert(nm_setting_diff((NMSetting *) a, (NMSetting *) b, flags, NM_FLAGS_HAS(r, 0x1), &hash)); + g_assert(!hash); +} +#endif + +#ifdef __NM_SETTING_PRIVATE_H__ +static inline NMSetting * +nmtst_assert_setting_dbus_new(GType gtype, GVariant *variant) +{ + NMSetting * setting; + gs_free_error GError *error = NULL; + + g_assert(g_type_is_a(gtype, NM_TYPE_SETTING)); + g_assert(gtype != NM_TYPE_SETTING); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, NM_VARIANT_TYPE_SETTING)); + + setting = + _nm_setting_new_from_dbus(gtype, variant, NULL, NM_SETTING_PARSE_FLAGS_STRICT, &error); + nmtst_assert_success(setting, error); + return setting; +} + +static inline void +nmtst_assert_setting_dbus_roundtrip(gconstpointer /* const NMSetting * */ setting) +{ + gs_unref_object NMSetting *setting2 = NULL; + gs_unref_variant GVariant *variant = NULL; + + g_assert(NM_IS_SETTING(setting)); + + variant = _nm_setting_to_dbus((NMSetting *) setting, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); + setting2 = nmtst_assert_setting_dbus_new(G_OBJECT_TYPE(setting), variant); + nmtst_assert_setting_is_equal(setting, setting2, NM_SETTING_COMPARE_FLAG_EXACT); +} +#endif + +#ifdef __NM_UTILS_H__ +static inline void +nmtst_assert_hwaddr_equals(gconstpointer hwaddr1, + gssize hwaddr1_len, + const char * expected, + const char * file, + int line) +{ + guint8 buf2[NM_UTILS_HWADDR_LEN_MAX]; + gsize hwaddr2_len = 1; + const char *p; + gboolean success; + + g_assert(hwaddr1_len > 0 && hwaddr1_len <= NM_UTILS_HWADDR_LEN_MAX); + + g_assert(expected); + for (p = expected; *p; p++) { + if (*p == ':' || *p == '-') + hwaddr2_len++; + } + g_assert(hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX); + g_assert(nm_utils_hwaddr_aton(expected, buf2, hwaddr2_len)); + + /* Manually check the entire hardware address instead of using + * nm_utils_hwaddr_matches() because that function doesn't compare + * entire InfiniBand addresses for various (legitimate) reasons. + */ + success = (hwaddr1_len == hwaddr2_len); + if (success) + success = !memcmp(hwaddr1, buf2, hwaddr1_len); + if (!success) { + g_error("assert: %s:%d: hwaddr '%s' (%zd) expected, but got %s (%zd)", + file, + line, + expected, + hwaddr2_len, + nm_utils_hwaddr_ntoa(hwaddr1, hwaddr1_len), + hwaddr1_len); + } +} + #define nmtst_assert_hwaddr_equals(hwaddr1, hwaddr1_len, expected) \ + nmtst_assert_hwaddr_equals(hwaddr1, hwaddr1_len, expected, __FILE__, __LINE__) +#endif + +#if defined(__NM_SIMPLE_CONNECTION_H__) && defined(__NM_SETTING_CONNECTION_H__) \ + && defined(__NM_KEYFILE_INTERNAL_H__) + +static inline NMConnection * +nmtst_create_connection_from_keyfile(const char *keyfile_str, const char *full_filename) +{ + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + gs_free_error GError *error = NULL; + gboolean success; + NMConnection * con; + gs_free char * filename = g_path_get_basename(full_filename); + gs_free char * base_dir = g_path_get_dirname(full_filename); + + g_assert(keyfile_str); + g_assert(full_filename && full_filename[0] == '/'); + + keyfile = g_key_file_new(); + success = g_key_file_load_from_data(keyfile, + keyfile_str, + strlen(keyfile_str), + G_KEY_FILE_NONE, + &error); + nmtst_assert_success(success, error); + + con = nm_keyfile_read(keyfile, base_dir, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + nmtst_assert_success(NM_IS_CONNECTION(con), error); + + nm_keyfile_read_ensure_id(con, filename); + nm_keyfile_read_ensure_uuid(con, full_filename); + + nmtst_connection_normalize(con); + + return con; +} + +#endif + +#ifdef __NM_CONNECTION_H__ + +static inline GVariant * +_nmtst_variant_new_vardict(int dummy, ...) +{ + GVariantBuilder builder; + va_list ap; + const char * name; + GVariant * variant; + + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + + va_start(ap, dummy); + while ((name = va_arg(ap, const char *))) { + variant = va_arg(ap, GVariant *); + g_variant_builder_add(&builder, "{sv}", name, variant); + } + va_end(ap); + + return g_variant_builder_end(&builder); +} + #define nmtst_variant_new_vardict(...) _nmtst_variant_new_vardict(0, __VA_ARGS__, NULL) + + #define nmtst_assert_variant_is_of_type(variant, type) \ + G_STMT_START \ + { \ + GVariant *_variantx = (variant); \ + \ + g_assert(_variantx); \ + g_assert(g_variant_is_of_type(_variantx, (type))); \ + } \ + G_STMT_END + + #define nmtst_assert_variant_uint32(variant, val) \ + G_STMT_START \ + { \ + GVariant *_variant = (variant); \ + \ + nmtst_assert_variant_is_of_type(_variant, G_VARIANT_TYPE_UINT32); \ + g_assert_cmpint(g_variant_get_uint32(_variant), ==, (val)); \ + } \ + G_STMT_END + + #define nmtst_assert_variant_string(variant, str) \ + G_STMT_START \ + { \ + gsize _l; \ + GVariant * _variant = (variant); \ + const char *_str = (str); \ + \ + nmtst_assert_variant_is_of_type(_variant, G_VARIANT_TYPE_STRING); \ + g_assert(_str); \ + g_assert_cmpstr(g_variant_get_string(_variant, &_l), ==, _str); \ + g_assert_cmpint(_l, ==, strlen(_str)); \ + } \ + G_STMT_END + + #ifdef __NM_SHARED_UTILS_H__ + #define _nmtst_assert_variant_bytestring_cmp_str(_ptr, _ptr2, _len) \ + G_STMT_START \ + { \ + if (memcmp(_ptr2, _ptr, _len) != 0) { \ + gs_free char *_x1 = NULL; \ + gs_free char *_x2 = NULL; \ + const char * _xx1; \ + const char * _xx2; \ + \ + _xx1 = nm_utils_buf_utf8safe_escape(_ptr, \ + _len, \ + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, \ + &_x1); \ + _xx2 = nm_utils_buf_utf8safe_escape(_ptr2, \ + _len, \ + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, \ + &_x2); \ + g_assert_cmpstr(_xx1, ==, _xx2); \ + g_assert_not_reached(); \ + } \ + } \ + G_STMT_END + #else + #define _nmtst_assert_variant_bytestring_cmp_str(_ptr, _ptr2, _len) \ + G_STMT_START {} \ + G_STMT_END + #endif + + #define nmtst_assert_variant_bytestring(variant, ptr, len) \ + G_STMT_START \ + { \ + GVariant * _variant = (variant); \ + gconstpointer _ptr = (ptr); \ + gconstpointer _ptr2; \ + gsize _len = (len); \ + gsize _len2; \ + \ + nmtst_assert_variant_is_of_type(_variant, G_VARIANT_TYPE_BYTESTRING); \ + _ptr2 = g_variant_get_fixed_array(_variant, &_len2, 1); \ + g_assert_cmpint(_len2, ==, _len); \ + if (_len != 0 && _ptr) { \ + _nmtst_assert_variant_bytestring_cmp_str(_ptr, _ptr2, _len); \ + g_assert_cmpmem(_ptr2, _len2, _ptr, _len); \ + } \ + } \ + G_STMT_END + +typedef enum { + NMTST_VARIANT_EDITOR_CONNECTION, + NMTST_VARIANT_EDITOR_SETTING, + NMTST_VARIANT_EDITOR_PROPERTY +} NmtstVariantEditorPhase; + + #define NMTST_VARIANT_EDITOR(__connection_variant, __code) \ + G_STMT_START \ + { \ + GVariantIter __connection_iter, *__setting_iter; \ + GVariantBuilder __connection_builder, __setting_builder; \ + const char * __cur_setting_name, *__cur_property_name; \ + GVariant * __property_val; \ + NmtstVariantEditorPhase __phase; \ + \ + g_variant_builder_init(&__connection_builder, NM_VARIANT_TYPE_CONNECTION); \ + g_variant_iter_init(&__connection_iter, __connection_variant); \ + \ + __phase = NMTST_VARIANT_EDITOR_CONNECTION; \ + __cur_setting_name = NULL; \ + __cur_property_name = NULL; \ + __code; \ + while (g_variant_iter_next(&__connection_iter, \ + "{&sa{sv}}", \ + &__cur_setting_name, \ + &__setting_iter)) { \ + g_variant_builder_init(&__setting_builder, NM_VARIANT_TYPE_SETTING); \ + __phase = NMTST_VARIANT_EDITOR_SETTING; \ + __cur_property_name = NULL; \ + __code; \ + \ + while (__cur_setting_name \ + && g_variant_iter_next(__setting_iter, \ + "{&sv}", \ + &__cur_property_name, \ + &__property_val)) { \ + __phase = NMTST_VARIANT_EDITOR_PROPERTY; \ + __code; \ + \ + if (__cur_property_name) { \ + g_variant_builder_add(&__setting_builder, \ + "{sv}", \ + __cur_property_name, \ + __property_val); \ + } \ + g_variant_unref(__property_val); \ + } \ + \ + if (__cur_setting_name) \ + g_variant_builder_add(&__connection_builder, \ + "{sa{sv}}", \ + __cur_setting_name, \ + &__setting_builder); \ + else \ + g_variant_builder_clear(&__setting_builder); \ + g_variant_iter_free(__setting_iter); \ + } \ + \ + g_variant_unref(__connection_variant); \ + \ + __connection_variant = g_variant_builder_end(&__connection_builder); \ + } \ + G_STMT_END; + + #define NMTST_VARIANT_ADD_SETTING(__setting_name, __setting_variant) \ + G_STMT_START \ + { \ + if (__phase == NMTST_VARIANT_EDITOR_CONNECTION) \ + g_variant_builder_add(&__connection_builder, \ + "{s@a{sv}}", \ + __setting_name, \ + __setting_variant); \ + } \ + G_STMT_END + + #define NMTST_VARIANT_DROP_SETTING(__setting_name) \ + G_STMT_START \ + { \ + if (__phase == NMTST_VARIANT_EDITOR_SETTING && __cur_setting_name) { \ + if (!strcmp(__cur_setting_name, __setting_name)) \ + __cur_setting_name = NULL; \ + } \ + } \ + G_STMT_END + + #define NMTST_VARIANT_ADD_PROPERTY(__setting_name, __property_name, __format_string, __value) \ + G_STMT_START \ + { \ + if (__phase == NMTST_VARIANT_EDITOR_SETTING) { \ + if (!strcmp(__cur_setting_name, __setting_name)) { \ + g_variant_builder_add(&__setting_builder, \ + "{sv}", \ + __property_name, \ + g_variant_new(__format_string, __value)); \ + } \ + } \ + } \ + G_STMT_END + + #define NMTST_VARIANT_DROP_PROPERTY(__setting_name, __property_name) \ + G_STMT_START \ + { \ + if (__phase == NMTST_VARIANT_EDITOR_PROPERTY && __cur_property_name) { \ + if (!strcmp(__cur_setting_name, __setting_name) \ + && !strcmp(__cur_property_name, __property_name)) \ + __cur_property_name = NULL; \ + } \ + } \ + G_STMT_END + + #define NMTST_VARIANT_CHANGE_PROPERTY(__setting_name, \ + __property_name, \ + __format_string, \ + __value) \ + G_STMT_START \ + { \ + NMTST_VARIANT_DROP_PROPERTY(__setting_name, __property_name); \ + NMTST_VARIANT_ADD_PROPERTY(__setting_name, __property_name, __format_string, __value); \ + } \ + G_STMT_END + +#endif /* __NM_CONNECTION_H__ */ + +static inline GVariant * +nmtst_variant_from_string(const GVariantType *variant_type, const char *variant_str) +{ + GVariant *variant; + GError * error = NULL; + + g_assert(variant_type); + g_assert(variant_str); + + variant = g_variant_parse(variant_type, variant_str, NULL, NULL, &error); + nmtst_assert_success(variant, error); + return variant; +} + +/*****************************************************************************/ + +static inline void +nmtst_keyfile_assert_data(GKeyFile *kf, const char *data, gssize data_len) +{ + nm_auto_unref_keyfile GKeyFile *kf2 = NULL; + gs_free_error GError *error = NULL; + gs_free char * d1 = NULL; + gs_free char * d2 = NULL; + gboolean success; + gsize d1_len; + gsize d2_len; + + g_assert(kf); + g_assert(data || data_len == 0); + g_assert(data_len >= -1); + + d1 = g_key_file_to_data(kf, &d1_len, &error); + nmtst_assert_success(d1, error); + + if (data_len == -1) { + g_assert_cmpint(strlen(d1), ==, d1_len); + data_len = strlen(data); + g_assert_cmpstr(d1, ==, data); + } + + g_assert_cmpmem(d1, d1_len, data, (gsize) data_len); + + /* also check that we can re-generate the same keyfile from the data. */ + + kf2 = g_key_file_new(); + success = g_key_file_load_from_data(kf2, d1, d1_len, G_KEY_FILE_NONE, &error); + nmtst_assert_success(success, error); + + d2 = g_key_file_to_data(kf2, &d2_len, &error); + nmtst_assert_success(d2, error); + + g_assert_cmpmem(d2, d2_len, d1, d1_len); +} + +static inline gssize +nmtst_keyfile_get_num_keys(GKeyFile *keyfile, const char *group_name) +{ + gs_strfreev char **keys = NULL; + gs_free_error GError *error = NULL; + gsize l; + + g_assert(keyfile); + g_assert(group_name); + + if (!g_key_file_has_group(keyfile, group_name)) + return -1; + + keys = g_key_file_get_keys(keyfile, group_name, &l, &error); + + nmtst_assert_success(keys, error); + + g_assert_cmpint(NM_PTRARRAY_LEN(keys), ==, l); + + return l; +} + +/*****************************************************************************/ + +#if defined(NM_SETTING_IP_CONFIG_H) && defined(__NM_SHARED_UTILS_H__) + +static inline NMIPAddress * +nmtst_ip_address_new(int addr_family, const char *str) +{ + NMIPAddr addr; + int plen; + GError * error = NULL; + NMIPAddress *a; + + if (!nm_utils_parse_inaddr_prefix_bin(addr_family, str, &addr_family, &addr, &plen)) + g_assert_not_reached(); + + if (plen == -1) + plen = addr_family == AF_INET ? 32 : 128; + + a = nm_ip_address_new_binary(addr_family, &addr, plen, &error); + nmtst_assert_success(a, error); + return a; +} + +#endif + +/*****************************************************************************/ + +#endif /* __NM_TEST_UTILS_H__ */ diff --git a/src/libnm-glib-aux/nm-time-utils.c b/src/libnm-glib-aux/nm-time-utils.c new file mode 100644 index 0000000..f30e6a1 --- /dev/null +++ b/src/libnm-glib-aux/nm-time-utils.c @@ -0,0 +1,328 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-time-utils.h" + +#include "nm-logging-fwd.h" + +/*****************************************************************************/ + +typedef struct { + /* the offset to the native clock, in seconds. */ + gint64 offset_sec; + clockid_t clk_id; +} GlobalState; + +static const GlobalState *volatile p_global_state; + +static const GlobalState * +_t_init_global_state(void) +{ + static GlobalState global_state = {}; + static gsize init_once = 0; + const GlobalState *p; + clockid_t clk_id; + struct timespec tp; + gint64 offset_sec; + int r; + + clk_id = CLOCK_BOOTTIME; + r = clock_gettime(clk_id, &tp); + if (r == -1 && errno == EINVAL) { + clk_id = CLOCK_MONOTONIC; + r = clock_gettime(clk_id, &tp); + } + + /* The only failure we tolerate is that CLOCK_BOOTTIME is not supported. + * Other than that, we rely on kernel to not fail on this. */ + g_assert(r == 0); + g_assert(tp.tv_nsec >= 0 && tp.tv_nsec < NM_UTILS_NSEC_PER_SEC); + + /* Calculate an offset for the time stamp. + * + * We always want positive values, because then we can initialize + * a timestamp with 0 and be sure, that it will be less then any + * value nm_utils_get_monotonic_timestamp_*() might return. + * For this to be true also for nm_utils_get_monotonic_timestamp_sec() at + * early boot, we have to shift the timestamp to start counting at + * least from 1 second onward. + * + * Another advantage of shifting is, that this way we make use of the whole 31 bit + * range of signed int, before the time stamp for nm_utils_get_monotonic_timestamp_sec() + * wraps (~68 years). + **/ + offset_sec = (-((gint64) tp.tv_sec)) + 1; + + if (!g_once_init_enter(&init_once)) { + /* there was a race. We expect the pointer to be fully initialized now. */ + p = g_atomic_pointer_get(&p_global_state); + g_assert(p); + return p; + } + + global_state.offset_sec = offset_sec; + global_state.clk_id = clk_id; + p = &global_state; + g_atomic_pointer_set(&p_global_state, p); + g_once_init_leave(&init_once, 1); + + _nm_utils_monotonic_timestamp_initialized(&tp, p->offset_sec, p->clk_id == CLOCK_BOOTTIME); + + return p; +} + +#define _t_get_global_state() \ + ({ \ + const GlobalState *_p; \ + \ + _p = g_atomic_pointer_get(&p_global_state); \ + (G_LIKELY(_p) ? _p : _t_init_global_state()); \ + }) + +#define _t_clock_gettime_eval(p, tp) \ + ({ \ + struct timespec *const _tp = (tp); \ + const GlobalState *const _p2 = (p); \ + int _r; \ + \ + nm_assert(_tp); \ + \ + _r = clock_gettime(_p2->clk_id, _tp); \ + \ + nm_assert(_r == 0); \ + nm_assert(_tp->tv_nsec >= 0 && _tp->tv_nsec < NM_UTILS_NSEC_PER_SEC); \ + \ + _p2; \ + }) + +#define _t_clock_gettime(tp) _t_clock_gettime_eval(_t_get_global_state(), tp); + +/*****************************************************************************/ + +/** + * nm_utils_get_monotonic_timestamp_nsec: + * + * Returns: a monotonically increasing time stamp in nanoseconds, + * starting at an unspecified offset. See clock_gettime(), %CLOCK_BOOTTIME. + * + * The returned value will start counting at an undefined point + * in the past and will always be positive. + * + * All the nm_utils_get_monotonic_timestamp_*sec functions return the same + * timestamp but in different scales (nsec, usec, msec, sec). + **/ +gint64 +nm_utils_get_monotonic_timestamp_nsec(void) +{ + const GlobalState *p; + struct timespec tp; + + p = _t_clock_gettime(&tp); + + /* Although the result will always be positive, we return a signed + * integer, which makes it easier to calculate time differences (when + * you want to subtract signed values). + **/ + return (((gint64) tp.tv_sec) + p->offset_sec) * NM_UTILS_NSEC_PER_SEC + tp.tv_nsec; +} + +/** + * nm_utils_get_monotonic_timestamp_usec: + * + * Returns: a monotonically increasing time stamp in microseconds, + * starting at an unspecified offset. See clock_gettime(), %CLOCK_BOOTTIME. + * + * The returned value will start counting at an undefined point + * in the past and will always be positive. + * + * All the nm_utils_get_monotonic_timestamp_*sec functions return the same + * timestamp but in different scales (nsec, usec, msec, sec). + **/ +gint64 +nm_utils_get_monotonic_timestamp_usec(void) +{ + const GlobalState *p; + struct timespec tp; + + p = _t_clock_gettime(&tp); + + /* Although the result will always be positive, we return a signed + * integer, which makes it easier to calculate time differences (when + * you want to subtract signed values). + **/ + return (((gint64) tp.tv_sec) + p->offset_sec) * ((gint64) G_USEC_PER_SEC) + + (tp.tv_nsec / (NM_UTILS_NSEC_PER_SEC / G_USEC_PER_SEC)); +} + +/** + * nm_utils_get_monotonic_timestamp_msec: + * + * Returns: a monotonically increasing time stamp in milliseconds, + * starting at an unspecified offset. See clock_gettime(), %CLOCK_BOOTTIME. + * + * The returned value will start counting at an undefined point + * in the past and will always be positive. + * + * All the nm_utils_get_monotonic_timestamp_*sec functions return the same + * timestamp but in different scales (nsec, usec, msec, sec). + **/ +gint64 +nm_utils_get_monotonic_timestamp_msec(void) +{ + const GlobalState *p; + struct timespec tp; + + p = _t_clock_gettime(&tp); + + /* Although the result will always be positive, we return a signed + * integer, which makes it easier to calculate time differences (when + * you want to subtract signed values). + **/ + return (((gint64) tp.tv_sec) + p->offset_sec) * ((gint64) 1000) + + (tp.tv_nsec / (NM_UTILS_NSEC_PER_SEC / 1000)); +} + +/** + * nm_utils_get_monotonic_timestamp_sec: + * + * Returns: nm_utils_get_monotonic_timestamp_msec() in seconds (throwing + * away sub second parts). The returned value will always be positive. + * + * This value wraps after roughly 68 years which should be fine for any + * practical purpose. + * + * All the nm_utils_get_monotonic_timestamp_*sec functions return the same + * timestamp but in different scales (nsec, usec, msec, sec). + **/ +gint32 +nm_utils_get_monotonic_timestamp_sec(void) +{ + const GlobalState *p; + struct timespec tp; + + p = _t_clock_gettime(&tp); + + return (((gint64) tp.tv_sec) + p->offset_sec); +} + +/** + * nm_utils_monotonic_timestamp_as_boottime: + * @timestamp: the monotonic-timestamp that should be converted into CLOCK_BOOTTIME. + * @timestamp_nsec_per_tick: How many nanoseconds make one unit of @timestamp? E.g. if + * @timestamp is in unit seconds, pass %NM_UTILS_NSEC_PER_SEC; if @timestamp is + * in nanoseconds, pass 1; if @timestamp is in milliseconds, pass %NM_UTILS_NSEC_PER_SEC/1000. + * This must be a multiple of 10, and between 1 and %NM_UTILS_NSEC_PER_SEC. + * + * Returns: the monotonic-timestamp as CLOCK_BOOTTIME, as returned by clock_gettime(). + * The unit is the same as the passed in @timestamp based on @timestamp_nsec_per_tick. + * E.g. if you passed @timestamp in as seconds, it will return boottime in seconds. + * + * Note that valid monotonic-timestamps are always positive numbers (counting roughly since + * the application is running). However, it might make sense to calculate a timestamp from + * before the application was running, hence negative @timestamp is allowed. The result + * in that case might also be a negative timestamp (in CLOCK_BOOTTIME), which would indicate + * that the timestamp lies in the past before the machine was booted. + * + * On older kernels that don't support CLOCK_BOOTTIME, the returned time is instead CLOCK_MONOTONIC. + **/ +gint64 +nm_utils_monotonic_timestamp_as_boottime(gint64 timestamp, gint64 timestamp_nsec_per_tick) +{ + const GlobalState *p; + gint64 offset; + + /* only support nsec-per-tick being a multiple of 10. */ + g_return_val_if_fail(timestamp_nsec_per_tick == 1 + || (timestamp_nsec_per_tick > 0 + && timestamp_nsec_per_tick <= NM_UTILS_NSEC_PER_SEC + && timestamp_nsec_per_tick % 10 == 0), + -1); + + /* if the caller didn't yet ever fetch a monotonic-timestamp, he cannot pass any meaningful + * value (because he has no idea what these timestamps would be). That would be a bug. */ + nm_assert(g_atomic_pointer_get(&p_global_state)); + + p = _t_get_global_state(); + + nm_assert(p->offset_sec <= 0); + + /* calculate the offset of monotonic-timestamp to boottime. offset_s is <= 1. */ + offset = p->offset_sec * (NM_UTILS_NSEC_PER_SEC / timestamp_nsec_per_tick); + + nm_assert(offset <= 0 && offset > G_MININT64); + + /* check for overflow (note that offset is non-positive). */ + g_return_val_if_fail(timestamp < G_MAXINT64 + offset, G_MAXINT64); + + return timestamp - offset; +} + +/** + * nm_utils_monotonic_timestamp_from_boottime: + * @boottime: the timestamp from CLOCK_BOOTTIME (or CLOCK_MONOTONIC, if + * kernel does not support CLOCK_BOOTTIME and monotonic timestamps are based + * on CLOCK_MONOTONIC). + * @timestamp_nsec_per_tick: the scale in which @boottime is. If @boottime is in + * nano seconds, this should be 1. If it is in milli seconds, this should be + * %NM_UTILS_NSEC_PER_SEC/1000, etc. + * + * Returns: the same timestamp in monotonic timestamp scale. + * + * Note that commonly monotonic timestamps are positive. But they may not + * be positive in this case. That's when boottime is taken from a time before + * the monotonic timestamps started counting. So, that means a zero or negative + * value is still a valid timestamp. + * + * This is the inverse of nm_utils_monotonic_timestamp_as_boottime(). + */ +gint64 +nm_utils_monotonic_timestamp_from_boottime(guint64 boottime, gint64 timestamp_nsec_per_tick) +{ + const GlobalState *p; + gint64 offset; + + /* only support nsec-per-tick being a multiple of 10. */ + g_return_val_if_fail(timestamp_nsec_per_tick == 1 + || (timestamp_nsec_per_tick > 0 + && timestamp_nsec_per_tick <= NM_UTILS_NSEC_PER_SEC + && timestamp_nsec_per_tick % 10 == 0), + -1); + + p = _t_get_global_state(); + + nm_assert(p->offset_sec <= 0); + + /* calculate the offset of monotonic-timestamp to boottime. offset_s is <= 1. */ + offset = p->offset_sec * (NM_UTILS_NSEC_PER_SEC / timestamp_nsec_per_tick); + + nm_assert(offset <= 0 && offset > G_MININT64); + + /* check for overflow (note that offset is non-positive). */ + g_return_val_if_fail(boottime < G_MAXINT64, G_MAXINT64); + + return (gint64) boottime + offset; +} + +gint64 +nm_utils_clock_gettime_nsec(clockid_t clockid) +{ + struct timespec tp; + + if (clock_gettime(clockid, &tp) != 0) + return -NM_ERRNO_NATIVE(errno); + return nm_utils_timespec_to_nsec(&tp); +} + +gint64 +nm_utils_clock_gettime_msec(clockid_t clockid) +{ + struct timespec tp; + + if (clock_gettime(clockid, &tp) != 0) + return -NM_ERRNO_NATIVE(errno); + return nm_utils_timespec_to_msec(&tp); +} diff --git a/src/libnm-glib-aux/nm-time-utils.h b/src/libnm-glib-aux/nm-time-utils.h new file mode 100644 index 0000000..3c3e935 --- /dev/null +++ b/src/libnm-glib-aux/nm-time-utils.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_TIME_UTILS_H__ +#define __NM_TIME_UTILS_H__ + +#include + +static inline gint64 +nm_utils_timespec_to_nsec(const struct timespec *ts) +{ + return (((gint64) ts->tv_sec) * ((gint64) NM_UTILS_NSEC_PER_SEC)) + ((gint64) ts->tv_nsec); +} + +static inline gint64 +nm_utils_timespec_to_msec(const struct timespec *ts) +{ + return (((gint64) ts->tv_sec) * ((gint64) 1000)) + + (((gint64) ts->tv_nsec) / ((gint64) NM_UTILS_NSEC_PER_SEC / 1000)); +} + +gint64 nm_utils_get_monotonic_timestamp_nsec(void); +gint64 nm_utils_get_monotonic_timestamp_usec(void); +gint64 nm_utils_get_monotonic_timestamp_msec(void); +gint32 nm_utils_get_monotonic_timestamp_sec(void); + +gint64 nm_utils_monotonic_timestamp_as_boottime(gint64 timestamp, gint64 timestamp_ticks_per_nsec); +gint64 nm_utils_monotonic_timestamp_from_boottime(guint64 boottime, gint64 timestamp_nsec_per_tick); + +static inline gint64 +nm_utils_get_monotonic_timestamp_nsec_cached(gint64 *cache_now) +{ + return (*cache_now) ?: (*cache_now = nm_utils_get_monotonic_timestamp_nsec()); +} + +static inline gint64 +nm_utils_get_monotonic_timestamp_msec_cached(gint64 *cache_now) +{ + return (*cache_now) ?: (*cache_now = nm_utils_get_monotonic_timestamp_msec()); +} + +gint64 nm_utils_clock_gettime_nsec(clockid_t clockid); +gint64 nm_utils_clock_gettime_msec(clockid_t clockid); + +#endif /* __NM_TIME_UTILS_H__ */ diff --git a/src/libnm-glib-aux/nm-value-type.h b/src/libnm-glib-aux/nm-value-type.h new file mode 100644 index 0000000..f9edebd --- /dev/null +++ b/src/libnm-glib-aux/nm-value-type.h @@ -0,0 +1,209 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#ifndef __NM_VALUE_TYPE_H__ +#define __NM_VALUE_TYPE_H__ + +typedef enum { + NM_VALUE_TYPE_UNSPEC = 1, + NM_VALUE_TYPE_BOOL = 2, + NM_VALUE_TYPE_INT32 = 3, + NM_VALUE_TYPE_INT = 4, + NM_VALUE_TYPE_STRING = 5, +} NMValueType; + +/*****************************************************************************/ + +#ifdef NM_VALUE_TYPE_DEFINE_FUNCTIONS + +typedef union { + bool v_bool; + gint32 v_int32; + int v_int; + const char *v_string; + + /* for convenience, also let the union contain other pointer types. These are + * for NM_VALUE_TYPE_UNSPEC. */ + gconstpointer * v_ptr; + const GPtrArray *v_ptrarray; + +} NMValueTypUnion; + + /* Set the NMValueTypUnion. You can also assign the member directly. + * The only purpose of this is that it also returns a pointer to the + * union. So, you can do + * + * ptr = NM_VALUE_TYP_UNION_SET (&value_typ_union_storage, v_bool, TRUE); + */ + #define NM_VALUE_TYP_UNION_SET(_arg, _type, _val) \ + ({ \ + NMValueTypUnion *const _arg2 = (_arg); \ + \ + *_arg2 = (NMValueTypUnion){ \ + ._type = (_val), \ + }; \ + _arg2; \ + }) + +typedef struct { + bool has; + NMValueTypUnion val; +} NMValueTypUnioMaybe; + + #define NM_VALUE_TYP_UNIO_MAYBE_SET(_arg, _type, _val) \ + ({ \ + NMValueTypUnioMaybe *const _arg2 = (_arg); \ + \ + *_arg2 = (NMValueTypUnioMaybe){ \ + .has = TRUE, \ + .val._type = (_val), \ + }; \ + _arg2; \ + }) + +/*****************************************************************************/ + +static inline int +nm_value_type_cmp(NMValueType value_type, gconstpointer p_a, gconstpointer p_b) +{ + switch (value_type) { + case NM_VALUE_TYPE_BOOL: + NM_CMP_DIRECT(*((const bool *) p_a), *((const bool *) p_b)); + return 0; + case NM_VALUE_TYPE_INT32: + NM_CMP_DIRECT(*((const gint32 *) p_a), *((const gint32 *) p_b)); + return 0; + case NM_VALUE_TYPE_INT: + NM_CMP_DIRECT(*((const int *) p_a), *((const int *) p_b)); + return 0; + case NM_VALUE_TYPE_STRING: + return nm_strcmp0(*((const char *const *) p_a), *((const char *const *) p_b)); + case NM_VALUE_TYPE_UNSPEC: + break; + } + nm_assert_not_reached(); + return 0; +} + +static inline gboolean +nm_value_type_equal(NMValueType value_type, gconstpointer p_a, gconstpointer p_b) +{ + return nm_value_type_cmp(value_type, p_a, p_b) == 0; +} + +static inline void +nm_value_type_copy(NMValueType value_type, gpointer dst, gconstpointer src) +{ + switch (value_type) { + case NM_VALUE_TYPE_BOOL: + (*((bool *) dst) = *((const bool *) src)); + return; + case NM_VALUE_TYPE_INT32: + (*((gint32 *) dst) = *((const gint32 *) src)); + return; + case NM_VALUE_TYPE_INT: + (*((int *) dst) = *((const int *) src)); + return; + case NM_VALUE_TYPE_STRING: + /* self assignment safe! */ + if (*((char **) dst) != *((const char *const *) src)) { + g_free(*((char **) dst)); + *((char **) dst) = g_strdup(*((const char *const *) src)); + } + return; + case NM_VALUE_TYPE_UNSPEC: + break; + } + nm_assert_not_reached(); +} + +static inline void +nm_value_type_get_from_variant(NMValueType value_type, + gpointer dst, + GVariant * variant, + gboolean clone) +{ + switch (value_type) { + case NM_VALUE_TYPE_BOOL: + *((bool *) dst) = g_variant_get_boolean(variant); + return; + case NM_VALUE_TYPE_INT32: + *((gint32 *) dst) = g_variant_get_int32(variant); + return; + case NM_VALUE_TYPE_STRING: + if (clone) { + g_free(*((char **) dst)); + *((char **) dst) = g_variant_dup_string(variant, NULL); + } else { + /* we don't clone the string, nor free the previous value. */ + *((const char **) dst) = g_variant_get_string(variant, NULL); + } + return; + + case NM_VALUE_TYPE_INT: + /* "int" also does not have a define variant type, because it's not + * clear how many bits we would need. */ + + /* fall-through */ + case NM_VALUE_TYPE_UNSPEC: + break; + } + nm_assert_not_reached(); +} + +static inline GVariant * +nm_value_type_to_variant(NMValueType value_type, gconstpointer src) +{ + const char *v_string; + + switch (value_type) { + case NM_VALUE_TYPE_BOOL: + return g_variant_new_boolean(*((const bool *) src)); + case NM_VALUE_TYPE_INT32: + return g_variant_new_int32(*((const gint32 *) src)); + case NM_VALUE_TYPE_STRING: + v_string = *((const char *const *) src); + return v_string ? g_variant_new_string(v_string) : NULL; + + case NM_VALUE_TYPE_INT: + /* "int" also does not have a define variant type, because it's not + * clear how many bits we would need. */ + + /* fall-through */ + case NM_VALUE_TYPE_UNSPEC: + break; + } + nm_assert_not_reached(); + return NULL; +} + +static inline const GVariantType * +nm_value_type_get_variant_type(NMValueType value_type) +{ + switch (value_type) { + case NM_VALUE_TYPE_BOOL: + return G_VARIANT_TYPE_BOOLEAN; + case NM_VALUE_TYPE_INT32: + return G_VARIANT_TYPE_INT32; + case NM_VALUE_TYPE_STRING: + return G_VARIANT_TYPE_STRING; + + case NM_VALUE_TYPE_INT: + /* "int" also does not have a define variant type, because it's not + * clear how many bits we would need. */ + + /* fall-through */ + case NM_VALUE_TYPE_UNSPEC: + break; + } + nm_assert_not_reached(); + return NULL; +} + + /*****************************************************************************/ + +#endif /* NM_VALUE_TYPE_DEFINE_FUNCTIONS */ + +#endif /* __NM_VALUE_TYPE_H__ */ diff --git a/src/libnm-glib-aux/tests/meson.build b/src/libnm-glib-aux/tests/meson.build new file mode 100644 index 0000000..0ec4ad3 --- /dev/null +++ b/src/libnm-glib-aux/tests/meson.build @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +exe = executable( + 'test-shared-general', + 'test-shared-general.c', + include_directories: [ + src_inc, + top_inc, + ], + dependencies: [ + glib_dep, + ], + link_with: [ + libnm_log_null, + libnm_glib_aux, + libnm_std_aux, + libc_siphash, + ], +) + +test( + 'src/libnm-glib-aux/tests/test-shared-general', + test_script, + args: test_args + [exe.full_path()], + timeout: default_test_timeout, +) + +if jansson_dep.found() + exe = executable( + 'test-json-aux', + 'test-json-aux.c', + dependencies: [ + glib_dep, + jansson_dep, + dl_dep, + ], + include_directories: [ + src_inc, + top_inc, + ], + link_with: [ + libnm_log_null, + libnm_glib_aux, + libnm_std_aux, + libc_siphash, + ], + ) + + test( + 'src/libnm-glib-aux/tests/test-json-aux', + test_script, + args: test_args + [exe.full_path()], + timeout: default_test_timeout, + ) +endif diff --git a/src/libnm-glib-aux/tests/test-json-aux.c b/src/libnm-glib-aux/tests/test-json-aux.c new file mode 100644 index 0000000..5f33f4f --- /dev/null +++ b/src/libnm-glib-aux/tests/test-json-aux.c @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-glib-aux/nm-default-glib-i18n-prog.h" + +#include + +#include "libnm-glib-aux/nm-json-aux.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +/*****************************************************************************/ + +static void +test_jansson(void) +{ + const NMJsonVt * vt; + nm_auto_decref_json nm_json_t *js1 = NULL; + nm_auto_decref_json nm_json_t *js2 = NULL; + +#define _ASSERT_FIELD(type1, type2, field) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT_EXPR(sizeof(((type1 *) NULL)->field) == sizeof(((type2 *) NULL)->field)); \ + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(type1, field) == G_STRUCT_OFFSET(type2, field)); \ + } \ + G_STMT_END + + G_STATIC_ASSERT_EXPR(NM_JSON_REJECT_DUPLICATES == JSON_REJECT_DUPLICATES); + + G_STATIC_ASSERT_EXPR(sizeof(nm_json_type) == sizeof(json_type)); + + G_STATIC_ASSERT_EXPR((int) NM_JSON_OBJECT == JSON_OBJECT); + G_STATIC_ASSERT_EXPR((int) NM_JSON_ARRAY == JSON_ARRAY); + G_STATIC_ASSERT_EXPR((int) NM_JSON_STRING == JSON_STRING); + G_STATIC_ASSERT_EXPR((int) NM_JSON_INTEGER == JSON_INTEGER); + G_STATIC_ASSERT_EXPR((int) NM_JSON_REAL == JSON_REAL); + G_STATIC_ASSERT_EXPR((int) NM_JSON_TRUE == JSON_TRUE); + G_STATIC_ASSERT_EXPR((int) NM_JSON_FALSE == JSON_FALSE); + G_STATIC_ASSERT_EXPR((int) NM_JSON_NULL == JSON_NULL); + + G_STATIC_ASSERT_EXPR(sizeof(nm_json_int_t) == sizeof(json_int_t)); + + G_STATIC_ASSERT_EXPR(sizeof(nm_json_t) == sizeof(json_t)); + _ASSERT_FIELD(nm_json_t, json_t, refcount); + _ASSERT_FIELD(nm_json_t, json_t, type); + + G_STATIC_ASSERT_EXPR(NM_JSON_ERROR_TEXT_LENGTH == JSON_ERROR_TEXT_LENGTH); + G_STATIC_ASSERT_EXPR(NM_JSON_ERROR_SOURCE_LENGTH == JSON_ERROR_SOURCE_LENGTH); + + G_STATIC_ASSERT_EXPR(sizeof(nm_json_error_t) == sizeof(json_error_t)); + _ASSERT_FIELD(nm_json_error_t, json_error_t, line); + _ASSERT_FIELD(nm_json_error_t, json_error_t, column); + _ASSERT_FIELD(nm_json_error_t, json_error_t, position); + _ASSERT_FIELD(nm_json_error_t, json_error_t, source); + _ASSERT_FIELD(nm_json_error_t, json_error_t, text); + + vt = nm_json_vt(); + + g_assert(vt); + g_assert(vt->loaded); + + js1 = vt->nm_json_loads("{ \"a\": 5 }", 0, NULL); + g_assert(js1); + nm_json_decref(vt, g_steal_pointer(&js1)); + + js2 = vt->nm_json_loads("{ \"a\": 6 }", 0, NULL); + g_assert(js2); + +#define CHECK_FCN(vt, fcn, nm_type, js_type) \ + G_STMT_START \ + { \ + const NMJsonVt *const _vt = (vt); \ + _nm_unused nm_type = (_vt->nm_##fcn); \ + _nm_unused js_type = (fcn); \ + \ + g_assert(_vt->nm_##fcn); \ + g_assert(_f_nm); \ + g_assert(_f_js); \ + g_assert(_f_nm == _vt->nm_##fcn); \ + } \ + G_STMT_END + + CHECK_FCN(vt, json_array, nm_json_t * (*_f_nm)(void), json_t * (*_f_js)(void) ); + CHECK_FCN(vt, + json_array_append_new, + int (*_f_nm)(nm_json_t *, nm_json_t *), + int (*_f_js)(json_t *, json_t *)); + CHECK_FCN(vt, + json_array_get, + nm_json_t * (*_f_nm)(const nm_json_t *, gsize), + json_t * (*_f_js)(const json_t *, size_t)); + CHECK_FCN(vt, + json_array_size, + gsize(*_f_nm)(const nm_json_t *), + size_t(*_f_js)(const json_t *)); + CHECK_FCN(vt, json_delete, void (*_f_nm)(nm_json_t *), void (*_f_js)(json_t *)); + CHECK_FCN(vt, + json_dumps, + char *(*_f_nm)(const nm_json_t *, gsize), + char *(*_f_js)(const json_t *, size_t)); + CHECK_FCN(vt, json_false, nm_json_t * (*_f_nm)(void), json_t * (*_f_js)(void) ); + CHECK_FCN(vt, json_integer, nm_json_t * (*_f_nm)(nm_json_int_t), json_t * (*_f_js)(json_int_t)); + CHECK_FCN(vt, + json_integer_value, + nm_json_int_t(*_f_nm)(const nm_json_t *), + json_int_t(*_f_js)(const json_t *)); + CHECK_FCN(vt, + json_loads, + nm_json_t * (*_f_nm)(const char *, gsize, nm_json_error_t *), + json_t * (*_f_js)(const char *, size_t, json_error_t *) ); + CHECK_FCN(vt, json_object, nm_json_t * (*_f_nm)(void), json_t * (*_f_js)(void) ); + CHECK_FCN(vt, + json_object_del, + int (*_f_nm)(nm_json_t *, const char *), + int (*_f_js)(json_t *, const char *)); + CHECK_FCN(vt, + json_object_get, + nm_json_t * (*_f_nm)(const nm_json_t *, const char *), + json_t * (*_f_js)(const json_t *, const char *) ); + CHECK_FCN(vt, json_object_iter, void *(*_f_nm)(nm_json_t *), void *(*_f_js)(json_t *) ); + CHECK_FCN(vt, + json_object_iter_key, + const char *(*_f_nm)(void *), + const char *(*_f_js)(void *) ); + CHECK_FCN(vt, + json_object_iter_next, + void *(*_f_nm)(nm_json_t *, void *), + void *(*_f_js)(json_t *, void *) ); + CHECK_FCN(vt, json_object_iter_value, nm_json_t * (*_f_nm)(void *), json_t * (*_f_js)(void *) ); + CHECK_FCN(vt, + json_object_key_to_iter, + void *(*_f_nm)(const char *), + void *(*_f_js)(const char *) ); + CHECK_FCN(vt, + json_object_set_new, + int (*_f_nm)(nm_json_t *, const char *, nm_json_t *), + int (*_f_js)(json_t *, const char *, json_t *)); + CHECK_FCN(vt, + json_object_size, + gsize(*_f_nm)(const nm_json_t *), + size_t(*_f_js)(const json_t *)); + CHECK_FCN(vt, + json_string, + nm_json_t * (*_f_nm)(const char *), + json_t * (*_f_js)(const char *) ); + CHECK_FCN(vt, + json_string_value, + const char *(*_f_nm)(const nm_json_t *), + const char *(*_f_js)(const json_t *) ); + CHECK_FCN(vt, json_true, nm_json_t * (*_f_nm)(void), json_t * (*_f_js)(void) ); +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_func("/general/test_jansson", test_jansson); + + return g_test_run(); +} diff --git a/src/libnm-glib-aux/tests/test-shared-general.c b/src/libnm-glib-aux/tests/test-shared-general.c new file mode 100644 index 0000000..f30240b --- /dev/null +++ b/src/libnm-glib-aux/tests/test-shared-general.c @@ -0,0 +1,1292 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-prog.h" + +#include "libnm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-random-utils.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-time-utils.h" +#include "libnm-glib-aux/nm-ref-string.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +/*****************************************************************************/ + +G_STATIC_ASSERT(NM_AF_UNSPEC == AF_UNSPEC); +G_STATIC_ASSERT(NM_AF_INET == AF_INET); +G_STATIC_ASSERT(NM_AF_INET6 == AF_INET6); + +G_STATIC_ASSERT(NM_AF_INET_SIZE == sizeof(in_addr_t)); +G_STATIC_ASSERT(NM_AF_INET_SIZE == sizeof(struct in_addr)); +G_STATIC_ASSERT(NM_AF_INET6_SIZE == sizeof(struct in6_addr)); + +G_STATIC_ASSERT(4 == _nm_alignof(in_addr_t)); +G_STATIC_ASSERT(4 == _nm_alignof(struct in_addr)); +G_STATIC_ASSERT(4 == _nm_alignof(struct in6_addr)); +G_STATIC_ASSERT(4 == _nm_alignof(NMIPAddr)); + +/*****************************************************************************/ + +static void +test_gpid(void) +{ + const int *int_ptr; + GPid pid = 42; + + /* We redefine G_PID_FORMAT, because it's only available since glib 2.53.5. + * + * Also, this is the format for GPid, which for glib is always a typedef + * for "int". Add a check for that here. + * + * G_PID_FORMAT is not about pid_t, which might be a smaller int, and which we would + * check with SIZEOF_PID_T. */ + G_STATIC_ASSERT(sizeof(GPid) == sizeof(int)); + + g_assert_cmpstr("" G_PID_FORMAT, ==, "i"); + + /* check that it's really "int". We will get a compiler warning, if that's not + * the case. */ + int_ptr = &pid; + g_assert_cmpint(*int_ptr, ==, 42); +} + +/*****************************************************************************/ + +static void +test_monotonic_timestamp(void) +{ + g_assert(nm_utils_get_monotonic_timestamp_sec() > 0); +} + +/*****************************************************************************/ + +static void +test_nmhash(void) +{ + int rnd; + + nm_utils_random_bytes(&rnd, sizeof(rnd)); + + g_assert(nm_hash_val(555, 4) != 0); +} + +/*****************************************************************************/ + +static const char * +_make_strv_foo(void) +{ + return "foo"; +} + +static const char *const *const _tst_make_strv_1 = NM_MAKE_STRV("1", "2"); + +static void +test_make_strv(void) +{ + const char *const *v1a = NM_MAKE_STRV("a"); + const char *const *v1b = NM_MAKE_STRV("a", ); + const char *const *v2a = NM_MAKE_STRV("a", "b"); + const char *const *v2b = NM_MAKE_STRV("a", "b", ); + const char *const v3[] = { + "a", + "b", + }; + const char *const *v4b = NM_MAKE_STRV("a", _make_strv_foo(), ); + + g_assert(NM_PTRARRAY_LEN(v1a) == 1); + g_assert(NM_PTRARRAY_LEN(v1b) == 1); + g_assert(NM_PTRARRAY_LEN(v2a) == 2); + g_assert(NM_PTRARRAY_LEN(v2b) == 2); + + g_assert(NM_PTRARRAY_LEN(_tst_make_strv_1) == 2); + g_assert_cmpstr(_tst_make_strv_1[0], ==, "1"); + g_assert_cmpstr(_tst_make_strv_1[1], ==, "2"); + /* writing the static read-only variable leads to crash .*/ + //((char **) _tst_make_strv_1)[0] = NULL; + //((char **) _tst_make_strv_1)[2] = "c"; + + G_STATIC_ASSERT_EXPR(G_N_ELEMENTS(v3) == 2); + + g_assert(NM_PTRARRAY_LEN(v4b) == 2); + + G_STATIC_ASSERT_EXPR(G_N_ELEMENTS(NM_MAKE_STRV("a", "b")) == 3); + G_STATIC_ASSERT_EXPR(G_N_ELEMENTS(NM_MAKE_STRV("a", "b", )) == 3); + + nm_strquote_a(300, ""); +} + +/*****************************************************************************/ + +typedef enum { + TEST_NM_STRDUP_ENUM_m1 = -1, + TEST_NM_STRDUP_ENUM_3 = 3, +} TestNMStrdupIntEnum; + +static void +test_nm_strdup_int(void) +{ +#define _NM_STRDUP_INT_TEST(num, str) \ + G_STMT_START \ + { \ + gs_free char *_s1 = NULL; \ + \ + _s1 = nm_strdup_int((num)); \ + \ + g_assert(_s1); \ + g_assert_cmpstr(_s1, ==, str); \ + } \ + G_STMT_END + +#define _NM_STRDUP_INT_TEST_TYPED(type, num) \ + G_STMT_START \ + { \ + type _num = ((type) num); \ + \ + _NM_STRDUP_INT_TEST(_num, G_STRINGIFY(num)); \ + } \ + G_STMT_END + + _NM_STRDUP_INT_TEST_TYPED(char, 0); + _NM_STRDUP_INT_TEST_TYPED(char, 1); + _NM_STRDUP_INT_TEST_TYPED(guint8, 0); + _NM_STRDUP_INT_TEST_TYPED(gint8, 25); + _NM_STRDUP_INT_TEST_TYPED(char, 47); + _NM_STRDUP_INT_TEST_TYPED(short, 47); + _NM_STRDUP_INT_TEST_TYPED(int, 47); + _NM_STRDUP_INT_TEST_TYPED(long, 47); + _NM_STRDUP_INT_TEST_TYPED(unsigned char, 47); + _NM_STRDUP_INT_TEST_TYPED(unsigned short, 47); + _NM_STRDUP_INT_TEST_TYPED(unsigned, 47); + _NM_STRDUP_INT_TEST_TYPED(unsigned long, 47); + _NM_STRDUP_INT_TEST_TYPED(gint64, 9223372036854775807); + _NM_STRDUP_INT_TEST_TYPED(gint64, -9223372036854775807); + _NM_STRDUP_INT_TEST_TYPED(guint64, 0); + _NM_STRDUP_INT_TEST_TYPED(guint64, 9223372036854775807); + + _NM_STRDUP_INT_TEST(TEST_NM_STRDUP_ENUM_m1, "-1"); + _NM_STRDUP_INT_TEST(TEST_NM_STRDUP_ENUM_3, "3"); +} + +/*****************************************************************************/ + +static void +test_nm_strndup_a(void) +{ + int run; + + for (run = 0; run < 20; run++) { + gs_free char *input = NULL; + char ch; + gsize i, l; + + input = g_strnfill(nmtst_get_rand_uint32() % 20, 'x'); + + for (i = 0; input[i]; i++) { + while ((ch = ((char) nmtst_get_rand_uint32())) == '\0') { + /* repeat. */ + } + input[i] = ch; + } + + { + gs_free char *dup_free = NULL; + const char * dup; + + l = strlen(input) + 1; + dup = nm_strndup_a(10, input, l - 1, &dup_free); + g_assert_cmpstr(dup, ==, input); + if (strlen(dup) < 10) + g_assert(!dup_free); + else + g_assert(dup == dup_free); + } + + { + gs_free char *dup_free = NULL; + const char * dup; + + l = nmtst_get_rand_uint32() % 23; + dup = nm_strndup_a(10, input, l, &dup_free); + g_assert(strncmp(dup, input, l) == 0); + g_assert(strlen(dup) <= l); + if (l < 10) + g_assert(!dup_free); + else + g_assert(dup == dup_free); + if (strlen(input) < l) + g_assert(nm_utils_memeqzero(&dup[strlen(input)], l - strlen(input))); + } + } +} + +/*****************************************************************************/ + +static void +test_nm_ip4_addr_is_localhost(void) +{ + g_assert(nm_ip4_addr_is_localhost(nmtst_inet4_from_string("127.0.0.0"))); + g_assert(nm_ip4_addr_is_localhost(nmtst_inet4_from_string("127.0.0.1"))); + g_assert(nm_ip4_addr_is_localhost(nmtst_inet4_from_string("127.5.0.1"))); + g_assert(!nm_ip4_addr_is_localhost(nmtst_inet4_from_string("126.5.0.1"))); + g_assert(!nm_ip4_addr_is_localhost(nmtst_inet4_from_string("128.5.0.1"))); + g_assert(!nm_ip4_addr_is_localhost(nmtst_inet4_from_string("129.5.0.1"))); +} + +/*****************************************************************************/ + +static void +test_unaligned(void) +{ + int shift; + + for (shift = 0; shift <= 32; shift++) { + guint8 buf[100] = {}; + guint8 val = 0; + + while (val == 0) + val = nmtst_get_rand_uint32() % 256; + + buf[shift] = val; + + g_assert_cmpint(unaligned_read_le64(&buf[shift]), ==, (guint64) val); + g_assert_cmpint(unaligned_read_be64(&buf[shift]), ==, ((guint64) val) << 56); + g_assert_cmpint(unaligned_read_ne64(&buf[shift]), !=, 0); + + g_assert_cmpint(unaligned_read_le32(&buf[shift]), ==, (guint32) val); + g_assert_cmpint(unaligned_read_be32(&buf[shift]), ==, ((guint32) val) << 24); + g_assert_cmpint(unaligned_read_ne32(&buf[shift]), !=, 0); + + g_assert_cmpint(unaligned_read_le16(&buf[shift]), ==, (guint16) val); + g_assert_cmpint(unaligned_read_be16(&buf[shift]), ==, ((guint16) val) << 8); + g_assert_cmpint(unaligned_read_ne16(&buf[shift]), !=, 0); + } +} + +/*****************************************************************************/ + +static void +_strv_cmp_fuzz_input(const char *const * in, + gssize l, + const char *** out_strv_free_shallow, + char *** out_strv_free_deep, + const char *const **out_s1, + const char *const **out_s2) +{ + const char **strv; + gsize i; + + /* Fuzz the input argument. It will return two output arrays that are semantically + * equal the input. */ + + if (nmtst_get_rand_bool()) { + char **ss; + + if (l < 0) + ss = g_strdupv((char **) in); + else if (l == 0) { + ss = nmtst_get_rand_bool() ? NULL : g_new0(char *, 1); + } else { + ss = nm_memdup(in, sizeof(const char *) * l); + for (i = 0; i < (gsize) l; i++) + ss[i] = g_strdup(ss[i]); + } + strv = (const char **) ss; + *out_strv_free_deep = ss; + } else { + if (l < 0) { + strv = in ? nm_memdup(in, sizeof(const char *) * (NM_PTRARRAY_LEN(in) + 1)) : NULL; + } else if (l == 0) { + strv = nmtst_get_rand_bool() ? NULL : g_new0(const char *, 1); + } else + strv = nm_memdup(in, sizeof(const char *) * l); + *out_strv_free_shallow = strv; + } + + *out_s1 = in; + *out_s2 = strv; + + if (nmtst_get_rand_bool()) { + /* randomly swap the original and the clone. That means, out_s1 is either + * the input argument (as-is) or the sementically equal clone. */ + NM_SWAP(out_s1, out_s2); + } + if (nmtst_get_rand_bool()) { + /* randomly make s1 and s2 the same. This is for testing that + * comparing two identical pointers yields the same result. */ + *out_s2 = *out_s1; + } +} + +static void +_strv_cmp_free_deep(char **strv, gssize len) +{ + gssize i; + + if (strv) { + if (len < 0) + g_strfreev(strv); + else { + for (i = 0; i < len; i++) + g_free(strv[i]); + g_free(strv); + } + } +} + +static void +test_strv_cmp(void) +{ + const char *const strv0[1] = {}; + const char *const strv1[2] = { + "", + }; + +#define _STRV_CMP(a1, l1, a2, l2, equal) \ + G_STMT_START \ + { \ + gssize _l1 = (l1); \ + gssize _l2 = (l2); \ + const char *const * _a1; \ + const char *const * _a2; \ + const char *const * _a1x; \ + const char *const * _a2x; \ + char ** _a1_free_deep = NULL; \ + char ** _a2_free_deep = NULL; \ + gs_free const char **_a1_free_shallow = NULL; \ + gs_free const char **_a2_free_shallow = NULL; \ + int _c1, _c2; \ + \ + _strv_cmp_fuzz_input((a1), _l1, &_a1_free_shallow, &_a1_free_deep, &_a1, &_a1x); \ + _strv_cmp_fuzz_input((a2), _l2, &_a2_free_shallow, &_a2_free_deep, &_a2, &_a2x); \ + \ + _c1 = nm_utils_strv_cmp_n(_a1, _l1, _a2, _l2); \ + _c2 = nm_utils_strv_cmp_n(_a2, _l2, _a1, _l1); \ + if (equal) { \ + g_assert_cmpint(_c1, ==, 0); \ + g_assert_cmpint(_c2, ==, 0); \ + } else { \ + g_assert_cmpint(_c1, ==, -1); \ + g_assert_cmpint(_c2, ==, 1); \ + } \ + \ + /* Compare with self. _strv_cmp_fuzz_input() randomly swapped the arguments (_a1 and _a1x). + * Either way, the arrays must compare equal to their semantically equal alternative. */ \ + g_assert_cmpint(nm_utils_strv_cmp_n(_a1, _l1, _a1x, _l1), ==, 0); \ + g_assert_cmpint(nm_utils_strv_cmp_n(_a2, _l2, _a2x, _l2), ==, 0); \ + \ + _strv_cmp_free_deep(_a1_free_deep, _l1); \ + _strv_cmp_free_deep(_a2_free_deep, _l2); \ + } \ + G_STMT_END + + _STRV_CMP(NULL, -1, NULL, -1, TRUE); + + _STRV_CMP(NULL, -1, NULL, 0, FALSE); + _STRV_CMP(NULL, -1, strv0, 0, FALSE); + _STRV_CMP(NULL, -1, strv0, -1, FALSE); + + _STRV_CMP(NULL, 0, NULL, 0, TRUE); + _STRV_CMP(NULL, 0, strv0, 0, TRUE); + _STRV_CMP(NULL, 0, strv0, -1, TRUE); + _STRV_CMP(strv0, 0, strv0, 0, TRUE); + _STRV_CMP(strv0, 0, strv0, -1, TRUE); + _STRV_CMP(strv0, -1, strv0, -1, TRUE); + + _STRV_CMP(NULL, 0, strv1, -1, FALSE); + _STRV_CMP(NULL, 0, strv1, 1, FALSE); + _STRV_CMP(strv0, 0, strv1, -1, FALSE); + _STRV_CMP(strv0, 0, strv1, 1, FALSE); + _STRV_CMP(strv0, -1, strv1, -1, FALSE); + _STRV_CMP(strv0, -1, strv1, 1, FALSE); + + _STRV_CMP(strv1, -1, strv1, 1, TRUE); + _STRV_CMP(strv1, 1, strv1, 1, TRUE); +} + +/*****************************************************************************/ + +static void +_do_strstrip_avoid_copy(const char *str) +{ + gs_free char *str1 = g_strdup(str); + gs_free char *str2 = g_strdup(str); + gs_free char *str3 = NULL; + gs_free char *str4 = NULL; + const char * s3; + const char * s4; + + if (str1) + g_strstrip(str1); + + nm_strstrip(str2); + + g_assert_cmpstr(str1, ==, str2); + + s3 = nm_strstrip_avoid_copy(str, &str3); + g_assert_cmpstr(str1, ==, s3); + + s4 = nm_strstrip_avoid_copy_a(10, str, &str4); + g_assert_cmpstr(str1, ==, s4); + g_assert(!str == !s4); + g_assert(!s4 || strlen(s4) <= strlen(str)); + if (s4 && s4 == &str[strlen(str) - strlen(s4)]) { + g_assert(!str4); + g_assert(s3 == s4); + } else if (s4 && strlen(s4) >= 10) { + g_assert(str4); + g_assert(s4 == str4); + } else + g_assert(!str4); + + if (!nm_streq0(str1, str)) + _do_strstrip_avoid_copy(str1); +} + +static void +test_strstrip_avoid_copy(void) +{ + _do_strstrip_avoid_copy(NULL); + _do_strstrip_avoid_copy(""); + _do_strstrip_avoid_copy(" "); + _do_strstrip_avoid_copy(" a "); + _do_strstrip_avoid_copy(" 012345678 "); + _do_strstrip_avoid_copy(" 0123456789 "); + _do_strstrip_avoid_copy(" 01234567890 "); + _do_strstrip_avoid_copy(" 012345678901 "); +} + +/*****************************************************************************/ + +static void +test_nm_utils_bin2hexstr(void) +{ + int n_run; + + for (n_run = 0; n_run < 500; n_run++) { + guint8 buf[100]; + guint8 buf2[G_N_ELEMENTS(buf) + 1]; + gsize len = nmtst_get_rand_uint32() % (G_N_ELEMENTS(buf) + 1); + char strbuf1[G_N_ELEMENTS(buf) * 3]; + gboolean allocate = nmtst_get_rand_bool(); + char delimiter = nmtst_get_rand_bool() ? ':' : '\0'; + gboolean upper_case = nmtst_get_rand_bool(); + gboolean hexdigit_pairs_mangled; + gsize expected_strlen; + char * str_hex; + gsize required_len; + gboolean outlen_set; + gsize outlen; + guint8 * bin2; + guint i, j; + + nmtst_rand_buf(NULL, buf, len); + + if (len == 0) + expected_strlen = 0; + else if (delimiter != '\0') + expected_strlen = (len * 3u) - 1; + else + expected_strlen = len * 2u; + + g_assert_cmpint(expected_strlen, <, G_N_ELEMENTS(strbuf1)); + + str_hex = + nm_utils_bin2hexstr_full(buf, len, delimiter, upper_case, !allocate ? strbuf1 : NULL); + + g_assert(str_hex); + if (!allocate) + g_assert(str_hex == strbuf1); + g_assert_cmpint(strlen(str_hex), ==, expected_strlen); + + g_assert(NM_STRCHAR_ALL( + str_hex, + ch, + (ch >= '0' && ch <= '9') || ch == delimiter + || (upper_case ? (ch >= 'A' && ch <= 'F') : (ch >= 'a' && ch <= 'f')))); + + hexdigit_pairs_mangled = FALSE; + if (delimiter && len > 1 && nmtst_get_rand_bool()) { + /* randomly convert "0?" sequences to single digits, so we can get hexdigit_pairs_required + * parameter. */ + g_assert(strlen(str_hex) >= 5); + g_assert(str_hex[2] == delimiter); + i = 0; + j = 0; + for (;;) { + g_assert(g_ascii_isxdigit(str_hex[i])); + g_assert(g_ascii_isxdigit(str_hex[i + 1])); + g_assert(NM_IN_SET(str_hex[i + 2], delimiter, '\0')); + if (str_hex[i] == '0' && nmtst_get_rand_bool()) { + i++; + str_hex[j++] = str_hex[i++]; + hexdigit_pairs_mangled = TRUE; + } else { + str_hex[j++] = str_hex[i++]; + str_hex[j++] = str_hex[i++]; + } + if (str_hex[i] == '\0') { + str_hex[j] = '\0'; + break; + } + g_assert(str_hex[i] == delimiter); + str_hex[j++] = str_hex[i++]; + } + } + + required_len = nmtst_get_rand_bool() ? len : 0u; + + outlen_set = required_len == 0 || nmtst_get_rand_bool(); + + memset(buf2, 0, sizeof(buf2)); + + bin2 = nm_utils_hexstr2bin_full(str_hex, + nmtst_get_rand_bool(), + delimiter != '\0' && nmtst_get_rand_bool(), + !hexdigit_pairs_mangled && nmtst_get_rand_bool(), + delimiter != '\0' + ? nmtst_rand_select((const char *) ":", ":-") + : nmtst_rand_select((const char *) ":", ":-", "", NULL), + required_len, + buf2, + len, + outlen_set ? &outlen : NULL); + if (len > 0) { + g_assert(bin2); + g_assert(bin2 == buf2); + } else + g_assert(!bin2); + + if (outlen_set) + g_assert_cmpint(outlen, ==, len); + + g_assert_cmpmem(buf, len, buf2, len); + + g_assert(buf2[len] == '\0'); + + if (hexdigit_pairs_mangled) { + /* we mangled the hexstr to contain single digits. Trying to parse with + * hexdigit_pairs_required must now fail. */ + bin2 = nm_utils_hexstr2bin_full( + str_hex, + nmtst_get_rand_bool(), + delimiter != '\0' && nmtst_get_rand_bool(), + TRUE, + delimiter != '\0' ? nmtst_rand_select((const char *) ":", ":-") + : nmtst_rand_select((const char *) ":", ":-", "", NULL), + required_len, + buf2, + len, + outlen_set ? &outlen : NULL); + g_assert(!bin2); + } + + if (allocate) + g_free(str_hex); + } +} + +/*****************************************************************************/ + +static void +test_nm_ref_string(void) +{ + nm_auto_ref_string NMRefString *s1 = NULL; + NMRefString * s2; + + g_assert(NULL == NM_REF_STRING_UPCAST(NULL)); + + s1 = nm_ref_string_new("hallo"); + g_assert(s1); + g_assert_cmpstr(s1->str, ==, "hallo"); + g_assert_cmpint(s1->len, ==, strlen("hallo")); + g_assert(s1 == NM_REF_STRING_UPCAST(s1->str)); + + s2 = nm_ref_string_new("hallo"); + g_assert(s2 == s1); + nm_ref_string_unref(s2); + + s2 = nm_ref_string_new(NULL); + g_assert(!s2); + nm_ref_string_unref(s2); + +#define STR_WITH_NUL "hallo\0test\0" + s2 = nm_ref_string_new_len(STR_WITH_NUL, NM_STRLEN(STR_WITH_NUL)); + g_assert(s2); + g_assert_cmpstr(s2->str, ==, "hallo"); + g_assert_cmpint(s2->len, ==, NM_STRLEN(STR_WITH_NUL)); + g_assert_cmpint(s2->len, >, strlen(s2->str)); + g_assert_cmpmem(s2->str, s2->len, STR_WITH_NUL, NM_STRLEN(STR_WITH_NUL)); + g_assert(s2->str[s2->len] == '\0'); + nm_ref_string_unref(s2); +} + +/*****************************************************************************/ + +static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( + _do_string_table_lookup, + int, + { ; }, + { return -1; }, + {"0", 0}, + {"1", 1}, + {"2", 2}, + {"3", 3}, ); + +static void +test_string_table_lookup(void) +{ + const char *const args[] = { + NULL, + "0", + "1", + "2", + "3", + "x", + }; + int i; + + for (i = 0; i < G_N_ELEMENTS(args); i++) { + const char *needle = args[i]; + const int val2 = _nm_utils_ascii_str_to_int64(needle, 10, 0, 100, -1); + int val; + + val = _do_string_table_lookup(needle); + g_assert_cmpint(val, ==, val2); + } +} + +/*****************************************************************************/ + +static void +test_nm_utils_get_next_realloc_size(void) +{ + static const struct { + gsize requested; + gsize reserved_true; + gsize reserved_false; + } test_data[] = { + {0, 8, 8}, + {1, 8, 8}, + {8, 8, 8}, + {9, 16, 16}, + {16, 16, 16}, + {17, 32, 32}, + {32, 32, 32}, + {33, 40, 40}, + {40, 40, 40}, + {41, 104, 104}, + {104, 104, 104}, + {105, 232, 232}, + {232, 232, 232}, + {233, 488, 488}, + {488, 488, 488}, + {489, 1000, 1000}, + {1000, 1000, 1000}, + {1001, 2024, 2024}, + {2024, 2024, 2024}, + {2025, 4072, 4072}, + {4072, 4072, 4072}, + {4073, 8168, 8168}, + {8168, 8168, 8168}, + {8169, 12264, 16360}, + {12263, 12264, 16360}, + {12264, 12264, 16360}, + {12265, 16360, 16360}, + {16360, 16360, 16360}, + {16361, 20456, 32744}, + {20456, 20456, 32744}, + {20457, 24552, 32744}, + {24552, 24552, 32744}, + {24553, 28648, 32744}, + {28648, 28648, 32744}, + {28649, 32744, 32744}, + {32744, 32744, 32744}, + {32745, 36840, 65512}, + {36840, 36840, 65512}, + {G_MAXSIZE - 0x1000u, G_MAXSIZE, G_MAXSIZE}, + {G_MAXSIZE - 25u, G_MAXSIZE, G_MAXSIZE}, + {G_MAXSIZE - 24u, G_MAXSIZE, G_MAXSIZE}, + {G_MAXSIZE - 1u, G_MAXSIZE, G_MAXSIZE}, + {G_MAXSIZE, G_MAXSIZE, G_MAXSIZE}, + {NM_UTILS_GET_NEXT_REALLOC_SIZE_32, + NM_UTILS_GET_NEXT_REALLOC_SIZE_32, + NM_UTILS_GET_NEXT_REALLOC_SIZE_32}, + {NM_UTILS_GET_NEXT_REALLOC_SIZE_40, + NM_UTILS_GET_NEXT_REALLOC_SIZE_40, + NM_UTILS_GET_NEXT_REALLOC_SIZE_40}, + {NM_UTILS_GET_NEXT_REALLOC_SIZE_104, + NM_UTILS_GET_NEXT_REALLOC_SIZE_104, + NM_UTILS_GET_NEXT_REALLOC_SIZE_104}, + {NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, + NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, + NM_UTILS_GET_NEXT_REALLOC_SIZE_1000}, + }; + guint i; + + G_STATIC_ASSERT_EXPR(NM_UTILS_GET_NEXT_REALLOC_SIZE_104 == 104u); + G_STATIC_ASSERT_EXPR(NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 == 1000u); + + for (i = 0; i < G_N_ELEMENTS(test_data) + 5000u; i++) { + gsize requested0; + + if (i < G_N_ELEMENTS(test_data)) + requested0 = test_data[i].requested; + else { + /* find some interesting random values for testing. */ + switch (nmtst_get_rand_uint32() % 5) { + case 0: + requested0 = nmtst_get_rand_size(); + break; + case 1: + /* values close to G_MAXSIZE. */ + requested0 = G_MAXSIZE - (nmtst_get_rand_uint32() % 12000u); + break; + case 2: + /* values around G_MAXSIZE/2. */ + requested0 = (G_MAXSIZE / 2u) + 6000u - (nmtst_get_rand_uint32() % 12000u); + break; + case 3: + /* values around powers of 2. */ + requested0 = (((gsize) 1) << (nmtst_get_rand_uint32() % (sizeof(gsize) * 8u))) + + 6000u - (nmtst_get_rand_uint32() % 12000u); + break; + case 4: + /* values around 4k borders. */ + requested0 = (nmtst_get_rand_size() & ~((gsize) 0xFFFu)) + 30u + - (nmtst_get_rand_uint32() % 60u); + break; + default: + g_assert_not_reached(); + } + } + + { + const gsize requested = requested0; + gsize reserved_true; + gsize reserved_false; + bool truncated_true = FALSE; + bool truncated_false = FALSE; + + if (sizeof(gsize) > 4 && requested > SIZE_MAX / 2u - 24u) { + reserved_false = G_MAXSSIZE; + truncated_false = TRUE; + } else + reserved_false = nm_utils_get_next_realloc_size(FALSE, requested); + + if (sizeof(gsize) > 4 && requested > SIZE_MAX - 0x1000u - 24u) { + reserved_true = G_MAXSSIZE; + truncated_true = TRUE; + } else + reserved_true = nm_utils_get_next_realloc_size(TRUE, requested); + + g_assert_cmpuint(reserved_true, >, 0); + g_assert_cmpuint(reserved_false, >, 0); + if (!truncated_true) + g_assert_cmpuint(reserved_true, >=, requested); + if (!truncated_false) + g_assert_cmpuint(reserved_false, >=, requested); + if (!truncated_true && !truncated_false) + g_assert_cmpuint(reserved_false, >=, reserved_true); + + if (i < G_N_ELEMENTS(test_data)) { + if (!truncated_true) + g_assert_cmpuint(reserved_true, ==, test_data[i].reserved_true); + if (!truncated_false) + g_assert_cmpuint(reserved_false, ==, test_data[i].reserved_false); + } + + /* reserved_false is generally the next power of two - 24. */ + if (reserved_false == G_MAXSIZE) + g_assert_cmpuint(requested, >, G_MAXSIZE / 2u - 24u); + else if (!reserved_false) { + g_assert_cmpuint(reserved_false, <=, G_MAXSIZE - 24u); + if (reserved_false >= 40) { + const gsize _pow2 = reserved_false + 24u; + + /* reserved_false must always be a power of two minus 24. */ + g_assert_cmpuint(_pow2, >=, 64u); + g_assert_cmpuint(_pow2, >, requested); + g_assert(nm_utils_is_power_of_two(_pow2)); + + /* but _pow2/2 must also be smaller than what we requested. */ + g_assert_cmpuint(_pow2 / 2u - 24u, <, requested); + } else { + /* smaller values are hard-coded. */ + } + } + + /* reserved_true is generally the next 4k border - 24. */ + if (reserved_true == G_MAXSIZE) + g_assert_cmpuint(requested, >, G_MAXSIZE - 0x1000u - 24u); + else if (!truncated_true) { + g_assert_cmpuint(reserved_true, <=, G_MAXSIZE - 24u); + if (reserved_true > 8168u) { + const gsize page_border = reserved_true + 24u; + + /* reserved_true must always be aligned to 4k (minus 24). */ + g_assert_cmpuint(page_border % 0x1000u, ==, 0); + if (requested > 0x1000u - 24u) { + /* page_border not be more than 4k above requested. */ + g_assert_cmpuint(page_border, >=, 0x1000u - 24u); + g_assert_cmpuint(page_border - 0x1000u - 24u, <, requested); + } + } else { + /* for smaller sizes, reserved_true and reserved_false are the same. */ + g_assert_cmpuint(reserved_true, ==, reserved_false); + } + } + } + } +} + +/*****************************************************************************/ + +static void +test_nm_str_buf(void) +{ + guint i_run; + + for (i_run = 0; TRUE; i_run++) { + nm_auto_str_buf NMStrBuf strbuf = {}; + nm_auto_free_gstring GString *gstr = NULL; + int i, j, k; + int c; + + nm_str_buf_init(&strbuf, nmtst_get_rand_uint32() % 200u + 1u, nmtst_get_rand_bool()); + + if (i_run < 1000) { + c = nmtst_get_rand_word_length(NULL); + for (i = 0; i < c; i++) + nm_str_buf_append_c(&strbuf, '0' + (i % 10)); + gstr = g_string_new(nm_str_buf_get_str(&strbuf)); + j = nmtst_get_rand_uint32() % (strbuf.len + 1); + k = nmtst_get_rand_uint32() % (strbuf.len - j + 2) - 1; + + nm_str_buf_erase(&strbuf, j, k, nmtst_get_rand_bool()); + g_string_erase(gstr, j, k); + g_assert_cmpstr(gstr->str, ==, nm_str_buf_get_str(&strbuf)); + } else + return; + } +} + +/*****************************************************************************/ + +static void +test_nm_utils_parse_next_line(void) +{ + const char *data; + const char *data0; + gsize data_len; + const char *line_start; + gsize line_len; + int i_run; + gsize j, k; + + data = NULL; + data_len = 0; + g_assert(!nm_utils_parse_next_line(&data, &data_len, &line_start, &line_len)); + + for (i_run = 0; i_run < 1000; i_run++) { + gs_unref_ptrarray GPtrArray *strv = g_ptr_array_new_with_free_func(g_free); + gs_unref_ptrarray GPtrArray *strv2 = g_ptr_array_new_with_free_func(g_free); + gsize strv_len = nmtst_get_rand_word_length(NULL); + nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT(0, nmtst_get_rand_bool()); + + /* create a list of random words. */ + for (j = 0; j < strv_len; j++) { + gsize w_len = nmtst_get_rand_word_length(NULL); + NMStrBuf w_buf = + NM_STR_BUF_INIT(nmtst_get_rand_uint32() % (w_len + 1), nmtst_get_rand_bool()); + + for (k = 0; k < w_len; k++) + nm_str_buf_append_c(&w_buf, '0' + (k % 10)); + nm_str_buf_maybe_expand(&w_buf, 1, TRUE); + g_ptr_array_add(strv, nm_str_buf_finalize(&w_buf, NULL)); + } + + /* join the list of random words with (random) line delimiters + * ("\0", "\n", "\r" or EOF). */ + for (j = 0; j < strv_len; j++) { + nm_str_buf_append(&strbuf, strv->pdata[j]); +again: + switch (nmtst_get_rand_uint32() % 5) { + case 0: + nm_str_buf_append_c(&strbuf, '\0'); + break; + case 1: + if (strbuf.len > 0 + && (nm_str_buf_get_str_unsafe(&strbuf))[strbuf.len - 1] == '\r') { + /* the previous line was empty and terminated by "\r". We + * must not join with "\n". Retry. */ + goto again; + } + nm_str_buf_append_c(&strbuf, '\n'); + break; + case 2: + nm_str_buf_append_c(&strbuf, '\r'); + break; + case 3: + nm_str_buf_append(&strbuf, "\r\n"); + break; + case 4: + /* the last word randomly is delimited or not, but not if the last + * word is "". */ + if (j + 1 < strv_len) { + /* it's not the last word. Retry. */ + goto again; + } + g_assert(j == strv_len - 1); + if (((const char *) strv->pdata[j])[0] == '\0') { + /* if the last word was "", we need a delimiter (to parse it back). + * Retry. */ + goto again; + } + /* The final delimiter gets omitted. It's EOF. */ + break; + } + } + + data0 = nm_str_buf_get_str_unsafe(&strbuf); + if (!data0 && nmtst_get_rand_bool()) { + nm_str_buf_maybe_expand(&strbuf, 1, TRUE); + data0 = nm_str_buf_get_str_unsafe(&strbuf); + g_assert(data0); + } + data_len = strbuf.len; + g_assert((data_len > 0 && data0) || data_len == 0); + data = data0; + while (nm_utils_parse_next_line(&data, &data_len, &line_start, &line_len)) { + g_assert(line_start); + g_assert(line_start >= data0); + g_assert(line_start < &data0[strbuf.len]); + g_assert(!memchr(line_start, '\0', line_len)); + g_ptr_array_add(strv2, g_strndup(line_start, line_len)); + } + g_assert(data_len == 0); + if (data0) + g_assert(data == &data0[strbuf.len]); + else + g_assert(!data); + + g_assert(nm_utils_strv_cmp_n((const char *const *) strv->pdata, + strv->len, + (const char *const *) strv2->pdata, + strv2->len) + == 0); + } +} + +/*****************************************************************************/ + +static void +test_in_strset_ascii_case(void) +{ + const char *x; + + x = NULL; + g_assert(NM_IN_STRSET_ASCII_CASE(x, NULL)); + g_assert(NM_IN_STRSET_ASCII_CASE(x, NULL, "b")); + g_assert(!NM_IN_STRSET_ASCII_CASE(x, "b")); + + x = "b"; + g_assert(NM_IN_STRSET(x, "b")); + g_assert(NM_IN_STRSET_ASCII_CASE(x, "b")); + g_assert(!NM_IN_STRSET(x, "B")); + g_assert(NM_IN_STRSET_ASCII_CASE(x, "B")); +} + +/*****************************************************************************/ + +static void +test_is_specific_hostname(void) +{ + g_assert(!nm_utils_is_specific_hostname(NULL)); + g_assert(!nm_utils_is_specific_hostname("")); + g_assert(!nm_utils_is_specific_hostname("(none)")); + g_assert(nm_utils_is_specific_hostname("(NONE)")); + + g_assert(!nm_utils_is_specific_hostname("localhost")); + g_assert(!nm_utils_is_specific_hostname("lOcalHost")); + g_assert(!nm_utils_is_specific_hostname("LOCALHOST")); + + g_assert(!nm_utils_is_specific_hostname("LOCALHOST.localdomain")); + + g_assert(nm_utils_is_specific_hostname("xlocalhost")); + g_assert(nm_utils_is_specific_hostname("lOcalHxost")); + g_assert(nm_utils_is_specific_hostname("LOCALxHOST")); + + g_assert(!nm_utils_is_specific_hostname("foo.LOCALHOST")); + g_assert(!nm_utils_is_specific_hostname("foo.LOCALHOsT6.")); + g_assert(!nm_utils_is_specific_hostname("foo.LOCALHOsT6.localdomain6")); + g_assert(!nm_utils_is_specific_hostname(".LOCALHOsT6.localdomain6")); + g_assert(!nm_utils_is_specific_hostname("LOCALHOsT6.localdomain6")); + g_assert(!nm_utils_is_specific_hostname("LOCALHOsT6.localdomain6.")); + g_assert(nm_utils_is_specific_hostname("LOCALHOsT6.localdomain.")); + + g_assert(nm_utils_is_specific_hostname(" ")); +} + +/*****************************************************************************/ + +static void +test_strv_dup_packed(void) +{ + gs_unref_ptrarray GPtrArray *src = NULL; + int i_run; + + src = g_ptr_array_new_with_free_func(g_free); + + for (i_run = 0; i_run < 500; i_run++) { + const int strv_len = nmtst_get_rand_word_length(NULL); + gs_free const char **strv_cpy = NULL; + const char *const * strv_src; + int i, j; + + g_ptr_array_set_size(src, 0); + for (i = 0; i < strv_len; i++) { + const int word_len = nmtst_get_rand_word_length(NULL); + NMStrBuf sbuf = NM_STR_BUF_INIT(0, nmtst_get_rand_bool()); + + for (j = 0; j < word_len; j++) + nm_str_buf_append_c(&sbuf, 'a' + (nmtst_get_rand_uint32() % 20)); + + g_ptr_array_add(src, nm_str_buf_finalize(&sbuf, NULL) ?: g_new0(char, 1)); + } + g_ptr_array_add(src, NULL); + + strv_src = (const char *const *) src->pdata; + g_assert(strv_src); + g_assert(NM_PTRARRAY_LEN(strv_src) == strv_len); + + strv_cpy = + nm_utils_strv_dup_packed(strv_src, + nmtst_get_rand_bool() ? (gssize) strv_len : (gssize) -1); + if (strv_len == 0) + g_assert(!strv_cpy); + else + g_assert(strv_cpy); + g_assert(NM_PTRARRAY_LEN(strv_cpy) == strv_len); + if (strv_cpy) + g_assert(nm_utils_strv_equal(strv_cpy, strv_src)); + } +} + +/*****************************************************************************/ + +static int +_hash_func_cmp_direct(gconstpointer a, gconstpointer b, gpointer user_data) +{ + NM_CMP_DIRECT(GPOINTER_TO_INT(a), GPOINTER_TO_INT(b)); + return 0; +} + +static void +test_utils_hashtable_cmp(void) +{ + static struct { + int val_i; + const char *val_s; + } vals[] = { + { + 0, + "0", + }, + { + 1, + "1", + }, + { + 2, + "2", + }, + { + 3, + "3", + }, + { + 4, + "4", + }, + { + 5, + "5", + }, + { + 6, + "6", + }, + { + 7, + "7", + }, + { + 8, + "8", + }, + { + 9, + "9", + }, + { + 0, + "a", + }, + { + 1, + "a", + }, + { + 2, + "a", + }, + { + 3, + "a", + }, + { + 4, + "a", + }, + { + 5, + "a", + }, + { + 0, + "0", + }, + { + 0, + "1", + }, + { + 0, + "2", + }, + { + 0, + "3", + }, + { + 0, + "4", + }, + { + 0, + "5", + }, + }; + guint test_run; + int is_num_key; + + for (test_run = 0; test_run < 30; test_run++) { + for (is_num_key = 0; is_num_key < 2; is_num_key++) { + GHashFunc func_key_hash = is_num_key ? nm_direct_hash : nm_str_hash; + GEqualFunc func_key_equal = is_num_key ? g_direct_equal : g_str_equal; + GCompareDataFunc func_key_cmp = + is_num_key ? _hash_func_cmp_direct : (GCompareDataFunc) nm_strcmp_with_data; + GCompareDataFunc func_val_cmp = + !is_num_key ? _hash_func_cmp_direct : (GCompareDataFunc) nm_strcmp_with_data; + gs_unref_hashtable GHashTable *h1 = NULL; + gs_unref_hashtable GHashTable *h2 = NULL; + gboolean has_same_keys; + guint i, n; + + h1 = g_hash_table_new(func_key_hash, func_key_equal); + h2 = g_hash_table_new(func_key_hash, func_key_equal); + + n = nmtst_get_rand_word_length(NULL); + for (i = 0; i < n; i++) { + typeof(vals[0]) *v = &vals[nmtst_get_rand_uint32() % G_N_ELEMENTS(vals)]; + gconstpointer v_key = is_num_key ? GINT_TO_POINTER(v->val_i) : v->val_s; + gconstpointer v_val = !is_num_key ? GINT_TO_POINTER(v->val_i) : v->val_s; + + g_hash_table_insert(h1, (gpointer) v_key, (gpointer) v_val); + g_hash_table_insert(h2, (gpointer) v_key, (gpointer) v_val); + } + + g_assert(nm_utils_hashtable_same_keys(h1, h2)); + g_assert(nm_utils_hashtable_cmp_equal(h1, h2, NULL, NULL)); + g_assert(nm_utils_hashtable_cmp_equal(h1, h2, func_val_cmp, NULL)); + g_assert(nm_utils_hashtable_cmp(h1, h2, FALSE, func_key_cmp, NULL, NULL) == 0); + g_assert(nm_utils_hashtable_cmp(h1, h2, TRUE, func_key_cmp, NULL, NULL) == 0); + g_assert(nm_utils_hashtable_cmp(h1, h2, FALSE, func_key_cmp, func_val_cmp, NULL) == 0); + g_assert(nm_utils_hashtable_cmp(h1, h2, TRUE, func_key_cmp, func_val_cmp, NULL) == 0); + + n = nmtst_get_rand_word_length(NULL) + 1; + has_same_keys = TRUE; + for (i = 0; i < n; i++) { +again: +{ + typeof(vals[0]) *v = &vals[nmtst_get_rand_uint32() % G_N_ELEMENTS(vals)]; + gconstpointer v_key = is_num_key ? GINT_TO_POINTER(v->val_i) : v->val_s; + gconstpointer v_val = !is_num_key ? GINT_TO_POINTER(v->val_i) : v->val_s; + gpointer v_key2; + gpointer v_val2; + + if (g_hash_table_lookup_extended(h1, v_key, &v_key2, &v_val2)) { + g_assert(func_key_cmp(v_key, v_key2, NULL) == 0); + if (func_val_cmp(v_val, v_val2, NULL) == 0) + goto again; + } else + has_same_keys = FALSE; + + g_hash_table_insert(h2, (gpointer) v_key, (gpointer) v_val); +} + } + + if (has_same_keys) { + g_assert(nm_utils_hashtable_same_keys(h1, h2)); + g_assert(nm_utils_hashtable_cmp_equal(h1, h2, NULL, NULL)); + g_assert(nm_utils_hashtable_cmp(h1, h2, FALSE, func_key_cmp, NULL, NULL) == 0); + g_assert(nm_utils_hashtable_cmp(h1, h2, TRUE, func_key_cmp, NULL, NULL) == 0); + } else { + g_assert(!nm_utils_hashtable_same_keys(h1, h2)); + g_assert(!nm_utils_hashtable_cmp_equal(h1, h2, NULL, NULL)); + g_assert(nm_utils_hashtable_cmp(h1, h2, FALSE, func_key_cmp, NULL, NULL) != 0); + g_assert(nm_utils_hashtable_cmp(h1, h2, TRUE, func_key_cmp, NULL, NULL) != 0); + } + g_assert(!nm_utils_hashtable_cmp_equal(h1, h2, func_val_cmp, NULL)); + g_assert(nm_utils_hashtable_cmp(h1, h2, FALSE, func_key_cmp, func_val_cmp, NULL) != 0); + g_assert(nm_utils_hashtable_cmp(h1, h2, TRUE, func_key_cmp, func_val_cmp, NULL) != 0); + } + } +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_func("/general/test_gpid", test_gpid); + g_test_add_func("/general/test_monotonic_timestamp", test_monotonic_timestamp); + g_test_add_func("/general/test_nmhash", test_nmhash); + g_test_add_func("/general/test_nm_make_strv", test_make_strv); + g_test_add_func("/general/test_nm_strdup_int", test_nm_strdup_int); + g_test_add_func("/general/test_nm_strndup_a", test_nm_strndup_a); + g_test_add_func("/general/test_nm_ip4_addr_is_localhost", test_nm_ip4_addr_is_localhost); + g_test_add_func("/general/test_unaligned", test_unaligned); + g_test_add_func("/general/test_strv_cmp", test_strv_cmp); + g_test_add_func("/general/test_strstrip_avoid_copy", test_strstrip_avoid_copy); + g_test_add_func("/general/test_nm_utils_bin2hexstr", test_nm_utils_bin2hexstr); + g_test_add_func("/general/test_nm_ref_string", test_nm_ref_string); + g_test_add_func("/general/test_string_table_lookup", test_string_table_lookup); + g_test_add_func("/general/test_nm_utils_get_next_realloc_size", + test_nm_utils_get_next_realloc_size); + g_test_add_func("/general/test_nm_str_buf", test_nm_str_buf); + g_test_add_func("/general/test_nm_utils_parse_next_line", test_nm_utils_parse_next_line); + g_test_add_func("/general/test_in_strset_ascii_case", test_in_strset_ascii_case); + g_test_add_func("/general/test_is_specific_hostname", test_is_specific_hostname); + g_test_add_func("/general/test_strv_dup_packed", test_strv_dup_packed); + g_test_add_func("/general/test_utils_hashtable_cmp", test_utils_hashtable_cmp); + + return g_test_run(); +} diff --git a/src/libnm-log-core/meson.build b/src/libnm-log-core/meson.build new file mode 100644 index 0000000..e1b30ba --- /dev/null +++ b/src/libnm-log-core/meson.build @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_log_core = static_library( + 'nm-log-core', + sources: 'nm-logging.c', + include_directories: [ + src_inc, + top_inc, + ], + dependencies: [ + libsystemd_dep, + glib_dep, + ], +) diff --git a/src/libnm-log-core/nm-logging.c b/src/libnm-log-core/nm-logging.c new file mode 100644 index 0000000..2ab0d92 --- /dev/null +++ b/src/libnm-log-core/nm-logging.c @@ -0,0 +1,1038 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2006 - 2012 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-logging.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#if SYSTEMD_JOURNAL + #define SD_JOURNAL_SUPPRESS_LOCATION + #include +#endif + +#include "libnm-glib-aux/nm-logging-base.h" +#include "libnm-glib-aux/nm-time-utils.h" +#include "libnm-glib-aux/nm-str-buf.h" + +/*****************************************************************************/ + +/* Notes about thread-safety: + * + * NetworkManager generally is single-threaded and uses a (GLib) mainloop. + * However, nm-logging is in parts thread-safe. That means: + * + * - functions that configure logging (nm_logging_init(), nm_logging_setup()) and + * most other functions MUST be called only from the main-thread. These functions + * are expected to be called infrequently, so they may or may not use a mutex + * (but the overhead is negligible here). + * + * - functions that do the actual logging logging (nm_log(), nm_logging_enabled()) are + * thread-safe and may be used from multiple threads. + * - When called from the not-main-thread, @mt_require_locking must be set to %TRUE. + * In this case, a Mutex will be used for accessing the global state. + * - When called from the main-thread, they may optionally pass @mt_require_locking %FALSE. + * This avoids extra locking and is in particular interesting for nm_logging_enabled(), + * which is expected to be called frequently and from the main-thread. + * + * Note that the logging macros honor %NM_THREAD_SAFE_ON_MAIN_THREAD define, to automatically + * set @mt_require_locking. That means, by default %NM_THREAD_SAFE_ON_MAIN_THREAD is "1", + * and code that only runs on the main-thread (which is the majority), can get away + * without locking. + */ + +/*****************************************************************************/ + +G_STATIC_ASSERT(LOG_EMERG == 0); +G_STATIC_ASSERT(LOG_ALERT == 1); +G_STATIC_ASSERT(LOG_CRIT == 2); +G_STATIC_ASSERT(LOG_ERR == 3); +G_STATIC_ASSERT(LOG_WARNING == 4); +G_STATIC_ASSERT(LOG_NOTICE == 5); +G_STATIC_ASSERT(LOG_INFO == 6); +G_STATIC_ASSERT(LOG_DEBUG == 7); + +/* We have more then 32 logging domains. Assert that it compiles to a 64 bit sized enum */ +G_STATIC_ASSERT(sizeof(NMLogDomain) >= sizeof(guint64)); + +/* Combined domains */ +#define LOGD_ALL_STRING "ALL" +#define LOGD_DEFAULT_STRING "DEFAULT" +#define LOGD_DHCP_STRING "DHCP" +#define LOGD_IP_STRING "IP" + +/*****************************************************************************/ + +typedef enum { + LOG_BACKEND_GLIB, + LOG_BACKEND_SYSLOG, + LOG_BACKEND_JOURNAL, +} LogBackend; + +typedef struct { + NMLogDomain num; + const char *name; +} LogDesc; + +typedef struct { + char *logging_domains_to_string; +} GlobalMain; + +typedef struct { + NMLogLevel log_level; + bool uses_syslog : 1; + bool init_pre_done : 1; + bool init_done : 1; + bool debug_stderr : 1; + const char *prefix; + const char *syslog_identifier; + + /* before we setup syslog (during start), the backend defaults to GLIB, meaning: + * we use g_log() for all logging. At that point, the application is not yet supposed + * to do any logging and doing so indicates a bug. + * + * Afterwards, the backend is either SYSLOG or JOURNAL. From that point, also + * g_log() is redirected to this backend via a logging handler. */ + LogBackend log_backend; +} Global; + +/*****************************************************************************/ + +G_LOCK_DEFINE_STATIC(log); + +/* This data must only be accessed from the main-thread (and as + * such does not need any lock). */ +static GlobalMain gl_main = {}; + +static union { + /* a union with an immutable and a mutable alias for the Global. + * Since nm-logging must be thread-safe, we must take care at which + * places we only read value ("imm") and where we modify them ("mut"). */ + Global mut; + const Global imm; +} gl = { + .imm = + { + /* nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL); */ + .log_level = LOGL_INFO, + .log_backend = LOG_BACKEND_GLIB, + .syslog_identifier = "SYSLOG_IDENTIFIER=NetworkManager", + .prefix = "", + }, +}; + +NMLogDomain _nm_logging_enabled_state[_LOGL_N_REAL] = { + /* nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL); + * + * Note: LOGD_VPN_PLUGIN is special and must be disabled for + * DEBUG and TRACE levels. */ + [LOGL_INFO] = LOGD_DEFAULT, + [LOGL_WARN] = LOGD_DEFAULT, + [LOGL_ERR] = LOGD_DEFAULT, +}; + +/*****************************************************************************/ + +static const LogDesc domain_desc[] = { + {LOGD_PLATFORM, "PLATFORM"}, + {LOGD_RFKILL, "RFKILL"}, + {LOGD_ETHER, "ETHER"}, + {LOGD_WIFI, "WIFI"}, + {LOGD_BT, "BT"}, + {LOGD_MB, "MB"}, + {LOGD_DHCP4, "DHCP4"}, + {LOGD_DHCP6, "DHCP6"}, + {LOGD_PPP, "PPP"}, + {LOGD_WIFI_SCAN, "WIFI_SCAN"}, + {LOGD_IP4, "IP4"}, + {LOGD_IP6, "IP6"}, + {LOGD_AUTOIP4, "AUTOIP4"}, + {LOGD_DNS, "DNS"}, + {LOGD_VPN, "VPN"}, + {LOGD_SHARING, "SHARING"}, + {LOGD_SUPPLICANT, "SUPPLICANT"}, + {LOGD_AGENTS, "AGENTS"}, + {LOGD_SETTINGS, "SETTINGS"}, + {LOGD_SUSPEND, "SUSPEND"}, + {LOGD_CORE, "CORE"}, + {LOGD_DEVICE, "DEVICE"}, + {LOGD_OLPC, "OLPC"}, + {LOGD_INFINIBAND, "INFINIBAND"}, + {LOGD_FIREWALL, "FIREWALL"}, + {LOGD_ADSL, "ADSL"}, + {LOGD_BOND, "BOND"}, + {LOGD_VLAN, "VLAN"}, + {LOGD_BRIDGE, "BRIDGE"}, + {LOGD_DBUS_PROPS, "DBUS_PROPS"}, + {LOGD_TEAM, "TEAM"}, + {LOGD_CONCHECK, "CONCHECK"}, + {LOGD_DCB, "DCB"}, + {LOGD_DISPATCH, "DISPATCH"}, + {LOGD_AUDIT, "AUDIT"}, + {LOGD_SYSTEMD, "SYSTEMD"}, + {LOGD_VPN_PLUGIN, "VPN_PLUGIN"}, + {LOGD_PROXY, "PROXY"}, + {0}, +}; + +/*****************************************************************************/ + +static char *_domains_to_string(gboolean include_level_override, + NMLogLevel log_level, + const NMLogDomain log_state[static _LOGL_N_REAL]); + +/*****************************************************************************/ + +static gboolean +_syslog_identifier_valid_domain(const char *domain) +{ + char c; + + if (!domain || !domain[0]) + return FALSE; + + /* we pass the syslog identifier as format string. No funny stuff. */ + + for (; (c = domain[0]); domain++) { + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') + || NM_IN_SET(c, '-', '_')) + continue; + return FALSE; + } + return TRUE; +} + +static gboolean +_syslog_identifier_assert(const char *syslog_identifier) +{ + g_assert(syslog_identifier); + g_assert(g_str_has_prefix(syslog_identifier, "SYSLOG_IDENTIFIER=")); + g_assert(_syslog_identifier_valid_domain(&syslog_identifier[NM_STRLEN("SYSLOG_IDENTIFIER=")])); + return TRUE; +} + +static const char * +syslog_identifier_domain(const char *syslog_identifier) +{ + nm_assert(_syslog_identifier_assert(syslog_identifier)); + return &syslog_identifier[NM_STRLEN("SYSLOG_IDENTIFIER=")]; +} + +#if SYSTEMD_JOURNAL +static const char * +syslog_identifier_full(const char *syslog_identifier) +{ + nm_assert(_syslog_identifier_assert(syslog_identifier)); + return &syslog_identifier[0]; +} +#endif + +/*****************************************************************************/ + +static gboolean +match_log_level(const char *level, NMLogLevel *out_level, GError **error) +{ + if (_nm_log_parse_level(level, out_level)) + return TRUE; + + g_set_error(error, + _NM_MANAGER_ERROR, + _NM_MANAGER_ERROR_UNKNOWN_LOG_LEVEL, + _("Unknown log level '%s'"), + level); + return FALSE; +} + +gboolean +nm_logging_setup(const char *level, const char *domains, char **bad_domains, GError **error) +{ + GString * unrecognized = NULL; + NMLogDomain cur_log_state[_LOGL_N_REAL]; + NMLogDomain new_log_state[_LOGL_N_REAL]; + NMLogLevel cur_log_level; + NMLogLevel new_log_level; + gs_free const char **domains_v = NULL; + gsize i_d; + int i; + gboolean had_platform_debug; + gs_free char * domains_free = NULL; + + NM_ASSERT_ON_MAIN_THREAD(); + + g_return_val_if_fail(!bad_domains || !*bad_domains, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + cur_log_level = gl.imm.log_level; + memcpy(cur_log_state, _nm_logging_enabled_state, sizeof(cur_log_state)); + + new_log_level = cur_log_level; + + if (!domains || !*domains) { + domains_free = _domains_to_string(FALSE, cur_log_level, cur_log_state); + domains = domains_free; + } + + for (i = 0; i < G_N_ELEMENTS(new_log_state); i++) + new_log_state[i] = 0; + + if (level && *level) { + if (!match_log_level(level, &new_log_level, error)) + return FALSE; + if (new_log_level == _LOGL_KEEP) { + new_log_level = cur_log_level; + for (i = 0; i < G_N_ELEMENTS(new_log_state); i++) + new_log_state[i] = cur_log_state[i]; + } + } + + domains_v = nm_utils_strsplit_set(domains, ", "); + for (i_d = 0; domains_v && domains_v[i_d]; i_d++) { + const char * s = domains_v[i_d]; + const char * p; + const LogDesc *diter; + NMLogLevel domain_log_level; + NMLogDomain bits; + + /* LOGD_VPN_PLUGIN is protected, that is, when setting ALL or DEFAULT, + * it does not enable the verbose levels DEBUG and TRACE, because that + * may expose sensitive data. */ + NMLogDomain protect = LOGD_NONE; + + p = strchr(s, ':'); + if (p) { + *((char *) p) = '\0'; + if (!match_log_level(p + 1, &domain_log_level, error)) + return FALSE; + } else + domain_log_level = new_log_level; + + bits = 0; + + if (domains_free) { + /* The caller didn't provide any domains to set (`nmcli general logging level DEBUG`). + * We reset all domains that were previously set, but we still want to protect + * VPN_PLUGIN domain. */ + protect = LOGD_VPN_PLUGIN; + } + + /* Check for combined domains */ + if (!g_ascii_strcasecmp(s, LOGD_ALL_STRING)) { + bits = LOGD_ALL; + protect = LOGD_VPN_PLUGIN; + } else if (!g_ascii_strcasecmp(s, LOGD_DEFAULT_STRING)) { + bits = LOGD_DEFAULT; + protect = LOGD_VPN_PLUGIN; + } else if (!g_ascii_strcasecmp(s, LOGD_DHCP_STRING)) + bits = LOGD_DHCP; + else if (!g_ascii_strcasecmp(s, LOGD_IP_STRING)) + bits = LOGD_IP; + + /* Check for compatibility domains */ + else if (!g_ascii_strcasecmp(s, "HW")) + bits = LOGD_PLATFORM; + else if (!g_ascii_strcasecmp(s, "WIMAX")) + continue; + + else { + for (diter = &domain_desc[0]; diter->name; diter++) { + if (!g_ascii_strcasecmp(diter->name, s)) { + bits = diter->num; + break; + } + } + + if (!bits) { + if (!bad_domains) { + g_set_error(error, + _NM_MANAGER_ERROR, + _NM_MANAGER_ERROR_UNKNOWN_LOG_DOMAIN, + _("Unknown log domain '%s'"), + s); + return FALSE; + } + + if (unrecognized) + g_string_append(unrecognized, ", "); + else + unrecognized = g_string_new(NULL); + g_string_append(unrecognized, s); + continue; + } + } + + if (domain_log_level == _LOGL_KEEP) { + for (i = 0; i < G_N_ELEMENTS(new_log_state); i++) + new_log_state[i] = (new_log_state[i] & ~bits) | (cur_log_state[i] & bits); + } else { + for (i = 0; i < G_N_ELEMENTS(new_log_state); i++) { + if (i < domain_log_level) + new_log_state[i] &= ~bits; + else { + new_log_state[i] |= bits; + if ((protect & bits) && i < LOGL_INFO) + new_log_state[i] &= ~protect; + } + } + } + } + + nm_clear_g_free(&gl_main.logging_domains_to_string); + + had_platform_debug = _nm_logging_enabled_lockfree(LOGL_DEBUG, LOGD_PLATFORM); + + G_LOCK(log); + + gl.mut.log_level = new_log_level; + for (i = 0; i < G_N_ELEMENTS(new_log_state); i++) + _nm_logging_enabled_state[i] = new_log_state[i]; + + G_UNLOCK(log); + + if (had_platform_debug && !_nm_logging_enabled_lockfree(LOGL_DEBUG, LOGD_PLATFORM)) { + /* when debug logging is enabled, platform will cache all access to + * sysctl. When the user disables debug-logging, we want to clear that + * cache right away. + * + * It's important that we call this without having a lock on "log", because + * otherwise we might deadlock. */ + _nm_logging_clear_platform_logging_cache(); + } + + if (unrecognized) + *bad_domains = g_string_free(unrecognized, FALSE); + + return TRUE; +} + +const char * +nm_logging_level_to_string(void) +{ + NM_ASSERT_ON_MAIN_THREAD(); + + return nm_log_level_desc[gl.imm.log_level].name; +} + +const char * +nm_logging_all_levels_to_string(void) +{ + static GString *str; + + if (G_UNLIKELY(!str)) { + int i; + + str = g_string_new(NULL); + for (i = 0; i < G_N_ELEMENTS(nm_log_level_desc); i++) { + if (str->len) + g_string_append_c(str, ','); + g_string_append(str, nm_log_level_desc[i].name); + } + } + + return str->str; +} + +const char * +nm_logging_domains_to_string(void) +{ + NM_ASSERT_ON_MAIN_THREAD(); + + if (G_UNLIKELY(!gl_main.logging_domains_to_string)) { + gl_main.logging_domains_to_string = + _domains_to_string(TRUE, gl.imm.log_level, _nm_logging_enabled_state); + } + + return gl_main.logging_domains_to_string; +} + +static char * +_domains_to_string(gboolean include_level_override, + NMLogLevel log_level, + const NMLogDomain log_state[static _LOGL_N_REAL]) +{ + const LogDesc *diter; + NMStrBuf sbuf; + int i; + + /* We don't just return g_strdup() the logging domains that were set during + * nm_logging_setup(), because we want to expand "DEFAULT" and "ALL". + */ + + nm_str_buf_init(&sbuf, NM_UTILS_GET_NEXT_REALLOC_SIZE_40, FALSE); + + for (diter = &domain_desc[0]; diter->name; diter++) { + /* If it's set for any lower level, it will also be set for LOGL_ERR */ + if (!(diter->num & log_state[LOGL_ERR])) + continue; + + nm_str_buf_append_required_delimiter(&sbuf, ','); + nm_str_buf_append(&sbuf, diter->name); + + if (!include_level_override) + continue; + + /* Check if it's logging at a lower level than the default. */ + for (i = 0; i < log_level; i++) { + if (diter->num & log_state[i]) { + nm_str_buf_append_c(&sbuf, ':'); + nm_str_buf_append(&sbuf, nm_log_level_desc[i].name); + break; + } + } + /* Check if it's logging at a higher level than the default. */ + if (!(diter->num & log_state[log_level])) { + for (i = log_level + 1; i < _LOGL_N_REAL; i++) { + if (diter->num & log_state[i]) { + nm_str_buf_append_c(&sbuf, ':'); + nm_str_buf_append(&sbuf, nm_log_level_desc[i].name); + break; + } + } + } + } + return nm_str_buf_finalize(&sbuf, NULL); +} + +static char _all_logging_domains_to_str[273]; + +const char * +nm_logging_all_domains_to_string(void) +{ + static const char *volatile str = NULL; + const char *s; + +again: + s = g_atomic_pointer_get(&str); + if (G_UNLIKELY(!s)) { + static gsize once = 0; + const LogDesc *diter; + gsize buf_l; + char * buf_p; + + if (!g_once_init_enter(&once)) + goto again; + + buf_p = _all_logging_domains_to_str; + buf_l = sizeof(_all_logging_domains_to_str); + + nm_utils_strbuf_append_str(&buf_p, &buf_l, LOGD_DEFAULT_STRING); + for (diter = &domain_desc[0]; diter->name; diter++) { + nm_utils_strbuf_append_c(&buf_p, &buf_l, ','); + nm_utils_strbuf_append_str(&buf_p, &buf_l, diter->name); + if (diter->num == LOGD_DHCP6) + nm_utils_strbuf_append_str(&buf_p, &buf_l, "," LOGD_DHCP_STRING); + else if (diter->num == LOGD_IP6) + nm_utils_strbuf_append_str(&buf_p, &buf_l, "," LOGD_IP_STRING); + } + nm_utils_strbuf_append_str(&buf_p, &buf_l, LOGD_ALL_STRING); + + /* Did you modify the logging domains (or their names)? Adjust the size of + * _all_logging_domains_to_str buffer above to have the exact size. */ + nm_assert(strlen(_all_logging_domains_to_str) == sizeof(_all_logging_domains_to_str) - 1); + nm_assert(buf_l == 1); + + s = _all_logging_domains_to_str; + g_atomic_pointer_set(&str, s); + g_once_init_leave(&once, 1); + } + + return s; +} + +/** + * nm_logging_get_level: + * @domain: find the lowest enabled logging level for the + * given domain. If this is a set of multiple + * domains, the most verbose level will be returned. + * + * Returns: the lowest (most verbose) logging level for the + * give @domain, or %_LOGL_OFF if it is disabled. + **/ +NMLogLevel +nm_logging_get_level(NMLogDomain domain) +{ + NMLogLevel sl = _LOGL_OFF; + + G_STATIC_ASSERT(LOGL_TRACE == 0); + while (sl > LOGL_TRACE && _nm_logging_enabled_lockfree(sl - 1, domain)) + sl--; + return sl; +} + +gboolean +_nm_logging_enabled_locking(NMLogLevel level, NMLogDomain domain) +{ + gboolean v; + + G_LOCK(log); + v = _nm_logging_enabled_lockfree(level, domain); + G_UNLOCK(log); + return v; +} + +gboolean +_nm_log_enabled_impl(gboolean mt_require_locking, NMLogLevel level, NMLogDomain domain) +{ + return nm_logging_enabled_mt(mt_require_locking, level, domain); +} + +#if SYSTEMD_JOURNAL +static void +_iovec_set(struct iovec *iov, const void *str, gsize len) +{ + iov->iov_base = (void *) str; + iov->iov_len = len; +} + +static void +_iovec_set_string(struct iovec *iov, const char *str) +{ + _iovec_set(iov, str, strlen(str)); +} + + #define _iovec_set_string_literal(iov, str) _iovec_set((iov), "" str "", NM_STRLEN(str)) + +_nm_printf(3, 4) static void _iovec_set_format(struct iovec *iov, + char ** iov_free, + const char * format, + ...) +{ + va_list ap; + char * str; + + va_start(ap, format); + str = g_strdup_vprintf(format, ap); + va_end(ap); + + _iovec_set_string(iov, str); + *iov_free = str; +} + + #define _iovec_set_format_a(iov, reserve_extra, format, ...) \ + G_STMT_START \ + { \ + const gsize _size = (reserve_extra) + (NM_STRLEN(format) + 3); \ + char *const _buf = g_alloca(_size); \ + int _len; \ + \ + G_STATIC_ASSERT_EXPR((reserve_extra) + (NM_STRLEN(format) + 3) <= 96); \ + \ + _len = g_snprintf(_buf, _size, "" format "", ##__VA_ARGS__); \ + \ + nm_assert(_len >= 0); \ + nm_assert(_len < _size); \ + nm_assert(_len == strlen(_buf)); \ + \ + _iovec_set((iov), _buf, _len); \ + } \ + G_STMT_END + + #define _iovec_set_format_str_a(iov, max_str_len, format, str_arg) \ + G_STMT_START \ + { \ + const char *_str_arg = (str_arg); \ + \ + nm_assert(_str_arg &&strlen(_str_arg) < (max_str_len)); \ + _iovec_set_format_a((iov), (max_str_len), format, str_arg); \ + } \ + G_STMT_END + +#endif + +void +_nm_log_impl(const char *file, + guint line, + const char *func, + gboolean mt_require_locking, + NMLogLevel level, + NMLogDomain domain, + int error, + const char *ifname, + const char *conn_uuid, + const char *fmt, + ...) +{ + char msg_stack[400]; + gs_free char * msg_heap = NULL; + const char * msg; + GTimeVal tv; + int errsv; + const NMLogDomain *cur_log_state; + NMLogDomain cur_log_state_copy[_LOGL_N_REAL]; + Global g_copy; + const Global * g; + + if (G_UNLIKELY(mt_require_locking)) { + G_LOCK(log); + /* we evaluate logging-enabled under lock. There is still a race that + * we might log the message below *after* logging was disabled. That means, + * when disabling logging, we might still log messages. */ + if (!_nm_logging_enabled_lockfree(level, domain)) { + G_UNLOCK(log); + return; + } + g_copy = gl.imm; + memcpy(cur_log_state_copy, _nm_logging_enabled_state, sizeof(cur_log_state_copy)); + G_UNLOCK(log); + g = &g_copy; + cur_log_state = cur_log_state_copy; + } else { + NM_ASSERT_ON_MAIN_THREAD(); + if (!_nm_logging_enabled_lockfree(level, domain)) + return; + g = &gl.imm; + cur_log_state = _nm_logging_enabled_state; + } + + (void) cur_log_state; + + errsv = errno; + + /* Make sure that %m maps to the specified error */ + if (error != 0) { + if (error < 0) + error = -error; + errno = error; + } + + msg = nm_vsprintf_buf_or_alloc(fmt, fmt, msg_stack, &msg_heap, NULL); + +#define MESSAGE_FMT "%s%-7s [%ld.%04ld] %s" +#define MESSAGE_ARG(prefix, tv, msg) \ + prefix, nm_log_level_desc[level].level_str, (tv).tv_sec, ((tv).tv_usec / 100), (msg) + + g_get_current_time(&tv); + + if (g->debug_stderr) + g_printerr(MESSAGE_FMT "\n", MESSAGE_ARG(g->prefix, tv, msg)); + + switch (g->log_backend) { +#if SYSTEMD_JOURNAL + case LOG_BACKEND_JOURNAL: + { + gint64 now, boottime; + struct iovec iov_data[15]; + struct iovec * iov = iov_data; + char * iov_free_data[5]; + char ** iov_free = iov_free_data; + const LogDesc *diter; + NMLogDomain dom_all; + char s_log_domains_buf[NM_STRLEN("NM_LOG_DOMAINS=") + sizeof(_all_logging_domains_to_str)]; + char *s_log_domains; + gsize l_log_domains; + + now = nm_utils_get_monotonic_timestamp_nsec(); + boottime = nm_utils_monotonic_timestamp_as_boottime(now, 1); + + _iovec_set_format_a(iov++, 30, "PRIORITY=%d", nm_log_level_desc[level].syslog_level); + _iovec_set_format(iov++, + iov_free++, + "MESSAGE=" MESSAGE_FMT, + MESSAGE_ARG(g->prefix, tv, msg)); + _iovec_set_string(iov++, syslog_identifier_full(g->syslog_identifier)); + _iovec_set_format_a(iov++, 30, "SYSLOG_PID=%ld", (long) getpid()); + + dom_all = domain; + s_log_domains = s_log_domains_buf; + l_log_domains = sizeof(s_log_domains_buf); + + nm_utils_strbuf_append_str(&s_log_domains, &l_log_domains, "NM_LOG_DOMAINS="); + for (diter = &domain_desc[0]; dom_all != 0 && diter->name; diter++) { + if (!NM_FLAGS_ANY(dom_all, diter->num)) + continue; + if (dom_all != domain) + nm_utils_strbuf_append_c(&s_log_domains, &l_log_domains, ','); + nm_utils_strbuf_append_str(&s_log_domains, &l_log_domains, diter->name); + dom_all &= ~diter->num; + } + nm_assert(l_log_domains > 0); + _iovec_set(iov++, s_log_domains_buf, s_log_domains - s_log_domains_buf); + + G_STATIC_ASSERT_EXPR(LOG_FAC(LOG_DAEMON) == 3); + _iovec_set_string_literal(iov++, "SYSLOG_FACILITY=3"); + _iovec_set_format_str_a(iov++, 15, "NM_LOG_LEVEL=%s", nm_log_level_desc[level].name); + if (func) + _iovec_set_format(iov++, iov_free++, "CODE_FUNC=%s", func); + _iovec_set_format(iov++, iov_free++, "CODE_FILE=%s", file ?: ""); + _iovec_set_format_a(iov++, 20, "CODE_LINE=%u", line); + _iovec_set_format_a(iov++, + 60, + "TIMESTAMP_MONOTONIC=%lld.%06lld", + (long long) (now / NM_UTILS_NSEC_PER_SEC), + (long long) ((now % NM_UTILS_NSEC_PER_SEC) / 1000)); + _iovec_set_format_a(iov++, + 60, + "TIMESTAMP_BOOTTIME=%lld.%06lld", + (long long) (boottime / NM_UTILS_NSEC_PER_SEC), + (long long) ((boottime % NM_UTILS_NSEC_PER_SEC) / 1000)); + if (error != 0) + _iovec_set_format_a(iov++, 30, "ERRNO=%d", error); + if (ifname) + _iovec_set_format(iov++, iov_free++, "NM_DEVICE=%s", ifname); + if (conn_uuid) + _iovec_set_format(iov++, iov_free++, "NM_CONNECTION=%s", conn_uuid); + + nm_assert(iov <= &iov_data[G_N_ELEMENTS(iov_data)]); + nm_assert(iov_free <= &iov_free_data[G_N_ELEMENTS(iov_free_data)]); + + sd_journal_sendv(iov_data, iov - iov_data); + + for (; --iov_free >= iov_free_data;) + g_free(*iov_free); + } break; +#endif + case LOG_BACKEND_SYSLOG: + syslog(nm_log_level_desc[level].syslog_level, MESSAGE_FMT, MESSAGE_ARG(g->prefix, tv, msg)); + break; + default: + g_log(syslog_identifier_domain(g->syslog_identifier), + nm_log_level_desc[level].g_log_level, + MESSAGE_FMT, + MESSAGE_ARG(g->prefix, tv, msg)); + break; + } + + errno = errsv; +} + +/*****************************************************************************/ + +void +_nm_utils_monotonic_timestamp_initialized(const struct timespec *tp, + gint64 offset_sec, + gboolean is_boottime) +{ + NM_ASSERT_ON_MAIN_THREAD(); + + if (_nm_logging_enabled_lockfree(LOGL_DEBUG, LOGD_CORE)) { + time_t now = time(NULL); + struct tm tm; + char s[255]; + + strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime_r(&now, &tm)); + nm_log_dbg(LOGD_CORE, + "monotonic timestamp started counting 1.%09ld seconds ago with " + "an offset of %lld.0 seconds to %s (local time is %s)", + tp->tv_nsec, + (long long) -offset_sec, + is_boottime ? "CLOCK_BOOTTIME" : "CLOCK_MONOTONIC", + s); + } +} + +/*****************************************************************************/ + +static void +nm_log_handler(const char *log_domain, GLogLevelFlags level, const char *message, gpointer ignored) +{ + int syslog_priority; + + switch (level & G_LOG_LEVEL_MASK) { + case G_LOG_LEVEL_ERROR: + syslog_priority = LOG_CRIT; + break; + case G_LOG_LEVEL_CRITICAL: + syslog_priority = LOG_ERR; + break; + case G_LOG_LEVEL_WARNING: + syslog_priority = LOG_WARNING; + break; + case G_LOG_LEVEL_MESSAGE: + syslog_priority = LOG_NOTICE; + break; + case G_LOG_LEVEL_DEBUG: + syslog_priority = LOG_DEBUG; + break; + case G_LOG_LEVEL_INFO: + default: + syslog_priority = LOG_INFO; + break; + } + + /* we don't need any locking here. The glib log handler gets only registered + * once during nm_logging_init() and the global data is not modified afterwards. */ + nm_assert(gl.imm.init_done); + + if (gl.imm.debug_stderr) + g_printerr("%s%s\n", gl.imm.prefix, message ?: ""); + + switch (gl.imm.log_backend) { +#if SYSTEMD_JOURNAL + case LOG_BACKEND_JOURNAL: + { + gint64 now, boottime; + + now = nm_utils_get_monotonic_timestamp_nsec(); + boottime = nm_utils_monotonic_timestamp_as_boottime(now, 1); + + sd_journal_send("PRIORITY=%d", + syslog_priority, + "MESSAGE=%s%s", + gl.imm.prefix, + message ?: "", + syslog_identifier_full(gl.imm.syslog_identifier), + "SYSLOG_PID=%ld", + (long) getpid(), + "SYSLOG_FACILITY=3", + "GLIB_DOMAIN=%s", + log_domain ?: "", + "GLIB_LEVEL=%d", + (int) (level & G_LOG_LEVEL_MASK), + "TIMESTAMP_MONOTONIC=%lld.%06lld", + (long long) (now / NM_UTILS_NSEC_PER_SEC), + (long long) ((now % NM_UTILS_NSEC_PER_SEC) / 1000), + "TIMESTAMP_BOOTTIME=%lld.%06lld", + (long long) (boottime / NM_UTILS_NSEC_PER_SEC), + (long long) ((boottime % NM_UTILS_NSEC_PER_SEC) / 1000), + NULL); + } break; +#endif + default: + syslog(syslog_priority, "%s%s", gl.imm.prefix, message ?: ""); + break; + } +} + +gboolean +nm_logging_syslog_enabled(void) +{ + NM_ASSERT_ON_MAIN_THREAD(); + + return gl.imm.uses_syslog; +} + +void +nm_logging_init_pre(const char *syslog_identifier, char *prefix_take) +{ + /* this function may be called zero or one times, and only + * - on the main thread + * - not after nm_logging_init(). */ + + NM_ASSERT_ON_MAIN_THREAD(); + + if (gl.imm.init_pre_done) + g_return_if_reached(); + + if (gl.imm.init_done) + g_return_if_reached(); + + if (!_syslog_identifier_valid_domain(syslog_identifier)) + g_return_if_reached(); + + if (!prefix_take || !prefix_take[0]) + g_return_if_reached(); + + G_LOCK(log); + + gl.mut.init_pre_done = TRUE; + + gl.mut.syslog_identifier = g_strdup_printf("SYSLOG_IDENTIFIER=%s", syslog_identifier); + nm_assert(_syslog_identifier_assert(gl.imm.syslog_identifier)); + + /* we pass the allocated string on and never free it. */ + gl.mut.prefix = prefix_take; + + G_UNLOCK(log); +} + +void +nm_logging_init(const char *logging_backend, gboolean debug) +{ + gboolean fetch_monotonic_timestamp = FALSE; + gboolean obsolete_debug_backend = FALSE; + LogBackend x_log_backend; + + /* this function may be called zero or one times, and only on the + * main thread. */ + + NM_ASSERT_ON_MAIN_THREAD(); + + nm_assert(NM_IN_STRSET("" NM_CONFIG_DEFAULT_LOGGING_BACKEND, + NM_LOG_CONFIG_BACKEND_JOURNAL, + NM_LOG_CONFIG_BACKEND_SYSLOG)); + + if (gl.imm.init_done) + g_return_if_reached(); + + if (!logging_backend) + logging_backend = "" NM_CONFIG_DEFAULT_LOGGING_BACKEND; + + if (nm_streq(logging_backend, NM_LOG_CONFIG_BACKEND_DEBUG)) { + /* "debug" was wrongly documented as a valid logging backend. It makes no sense however, + * because printing to stderr only makes sense when not demonizing. Whether to daemonize + * is only controlled via command line arguments (--no-daemon, --debug) and not via the + * logging backend from configuration. + * + * Fall back to the default. */ + logging_backend = "" NM_CONFIG_DEFAULT_LOGGING_BACKEND; + obsolete_debug_backend = TRUE; + } + + G_LOCK(log); + +#if SYSTEMD_JOURNAL + if (!nm_streq(logging_backend, NM_LOG_CONFIG_BACKEND_SYSLOG)) { + x_log_backend = LOG_BACKEND_JOURNAL; + + /* We only log the monotonic-timestamp with structured logging (journal). + * Only in this case, fetch the timestamp. */ + fetch_monotonic_timestamp = TRUE; + } else +#endif + { + x_log_backend = LOG_BACKEND_SYSLOG; + openlog(syslog_identifier_domain(gl.imm.syslog_identifier), LOG_PID, LOG_DAEMON); + } + + gl.mut.init_done = TRUE; + gl.mut.log_backend = x_log_backend; + gl.mut.uses_syslog = TRUE; + gl.mut.debug_stderr = debug; + + g_log_set_handler(syslog_identifier_domain(gl.imm.syslog_identifier), + G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + nm_log_handler, + NULL); + + G_UNLOCK(log); + + if (fetch_monotonic_timestamp) { + /* ensure we read a monotonic timestamp. Reading the timestamp the first + * time causes a logging message. We don't want to do that during _nm_log_impl. */ + nm_utils_get_monotonic_timestamp_nsec(); + } + + if (obsolete_debug_backend) + nm_log_dbg(LOGD_CORE, + "config: ignore deprecated logging backend 'debug', fallback to '%s'", + logging_backend); + + if (nm_streq(logging_backend, NM_LOG_CONFIG_BACKEND_SYSLOG)) { + /* good */ + } else if (nm_streq(logging_backend, NM_LOG_CONFIG_BACKEND_JOURNAL)) { +#if !SYSTEMD_JOURNAL + nm_log_warn(LOGD_CORE, + "config: logging backend 'journal' is not available, fallback to 'syslog'"); +#endif + } else { + nm_log_warn(LOGD_CORE, + "config: invalid logging backend '%s', fallback to '%s'", + logging_backend, +#if SYSTEMD_JOURNAL + NM_LOG_CONFIG_BACKEND_JOURNAL +#else + NM_LOG_CONFIG_BACKEND_SYSLOG +#endif + ); + } +} diff --git a/src/libnm-log-core/nm-logging.h b/src/libnm-log-core/nm-logging.h new file mode 100644 index 0000000..574c225 --- /dev/null +++ b/src/libnm-log-core/nm-logging.h @@ -0,0 +1,189 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2006 - 2012 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#ifndef __NETWORKMANAGER_LOGGING_H__ +#define __NETWORKMANAGER_LOGGING_H__ + +#ifdef __NM_TEST_UTILS_H__ + #error nm-test-utils.h must be included as last header +#endif + +#include "libnm-glib-aux/nm-logging-fwd.h" + +#define NM_LOG_CONFIG_BACKEND_DEBUG "debug" +#define NM_LOG_CONFIG_BACKEND_SYSLOG "syslog" +#define NM_LOG_CONFIG_BACKEND_JOURNAL "journal" + +#define nm_log_err(domain, ...) nm_log(LOGL_ERR, (domain), NULL, NULL, __VA_ARGS__) +#define nm_log_warn(domain, ...) nm_log(LOGL_WARN, (domain), NULL, NULL, __VA_ARGS__) +#define nm_log_info(domain, ...) nm_log(LOGL_INFO, (domain), NULL, NULL, __VA_ARGS__) +#define nm_log_dbg(domain, ...) nm_log(LOGL_DEBUG, (domain), NULL, NULL, __VA_ARGS__) +#define nm_log_trace(domain, ...) nm_log(LOGL_TRACE, (domain), NULL, NULL, __VA_ARGS__) + +//#define _NM_LOG_FUNC G_STRFUNC +#define _NM_LOG_FUNC NULL + +/* A wrapper for the _nm_log_impl() function that adds call site information. + * Contrary to nm_log(), it unconditionally calls the function without + * checking whether logging for the given level and domain is enabled. */ +#define _nm_log_mt(mt_require_locking, level, domain, error, ifname, con_uuid, ...) \ + G_STMT_START \ + { \ + _nm_log_impl(__FILE__, \ + __LINE__, \ + _NM_LOG_FUNC, \ + (mt_require_locking), \ + (level), \ + (domain), \ + (error), \ + (ifname), \ + (con_uuid), \ + ""__VA_ARGS__); \ + } \ + G_STMT_END + +#define _nm_log(level, domain, error, ifname, con_uuid, ...) \ + _nm_log_mt(!(NM_THREAD_SAFE_ON_MAIN_THREAD), \ + level, \ + domain, \ + error, \ + ifname, \ + con_uuid, \ + __VA_ARGS__) + +/* nm_log() only evaluates its argument list after checking + * whether logging for the given level/domain is enabled. */ +#define nm_log(level, domain, ifname, con_uuid, ...) \ + G_STMT_START \ + { \ + if (nm_logging_enabled((level), (domain))) { \ + _nm_log(level, domain, 0, ifname, con_uuid, __VA_ARGS__); \ + } \ + } \ + G_STMT_END + +#define _nm_log_ptr(level, domain, ifname, con_uuid, self, prefix, ...) \ + nm_log((level), \ + (domain), \ + (ifname), \ + (con_uuid), \ + "%s[" NM_HASH_OBFUSCATE_PTR_FMT "] " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + (prefix) ?: "", \ + NM_HASH_OBFUSCATE_PTR(self) _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +static inline gboolean +_nm_log_ptr_is_debug(NMLogLevel level) +{ + return level <= LOGL_DEBUG; +} + +/* log a message for an object (with providing a generic @self pointer) */ +#define nm_log_ptr(level, domain, ifname, con_uuid, self, prefix, ...) \ + G_STMT_START \ + { \ + if (_nm_log_ptr_is_debug(level)) { \ + _nm_log_ptr((level), (domain), (ifname), (con_uuid), (self), (prefix), __VA_ARGS__); \ + } else { \ + const char *__prefix = (prefix); \ + \ + nm_log((level), \ + (domain), \ + (ifname), \ + (con_uuid), \ + "%s%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __prefix ?: "", \ + __prefix ? " " : "" _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END + +#define _nm_log_obj(level, domain, ifname, con_uuid, self, prefix, ...) \ + _nm_log_ptr((level), (domain), (ifname), (con_uuid), (self), prefix, __VA_ARGS__) + +/* log a message for an object (with providing a @self pointer to a GObject). + * Contrary to nm_log_ptr(), @self must be a GObject type (or %NULL). + * As of now, nm_log_obj() is identical to nm_log_ptr(), but we might change that */ +#define nm_log_obj(level, domain, ifname, con_uuid, self, prefix, ...) \ + nm_log_ptr((level), (domain), (ifname), (con_uuid), (self), prefix, __VA_ARGS__) + +const char *nm_logging_level_to_string(void); +const char *nm_logging_domains_to_string(void); + +/*****************************************************************************/ + +extern NMLogDomain _nm_logging_enabled_state[_LOGL_N_REAL]; + +static inline gboolean +_nm_logging_enabled_lockfree(NMLogLevel level, NMLogDomain domain) +{ + nm_assert(((guint) level) < G_N_ELEMENTS(_nm_logging_enabled_state)); + return (((guint) level) < G_N_ELEMENTS(_nm_logging_enabled_state)) + && !!(_nm_logging_enabled_state[level] & domain); +} + +gboolean _nm_logging_enabled_locking(NMLogLevel level, NMLogDomain domain); + +static inline gboolean +nm_logging_enabled_mt(gboolean mt_require_locking, NMLogLevel level, NMLogDomain domain) +{ + if (mt_require_locking) + return _nm_logging_enabled_locking(level, domain); + + NM_ASSERT_ON_MAIN_THREAD(); + return _nm_logging_enabled_lockfree(level, domain); +} + +#define nm_logging_enabled(level, domain) \ + nm_logging_enabled_mt(!(NM_THREAD_SAFE_ON_MAIN_THREAD), level, domain) + +/*****************************************************************************/ + +NMLogLevel nm_logging_get_level(NMLogDomain domain); + +const char *nm_logging_all_levels_to_string(void); +const char *nm_logging_all_domains_to_string(void); + +gboolean +nm_logging_setup(const char *level, const char *domains, char **bad_domains, GError **error); + +void nm_logging_init_pre(const char *syslog_identifier, char *prefix_take); + +void nm_logging_init(const char *logging_backend, gboolean debug); + +gboolean nm_logging_syslog_enabled(void); + +/*****************************************************************************/ + +#define __NMLOG_DEFAULT(level, domain, prefix, ...) \ + G_STMT_START \ + { \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + (prefix) _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END + +#define __NMLOG_DEFAULT_WITH_ADDR(level, domain, prefix, ...) \ + G_STMT_START \ + { \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "%s[" NM_HASH_OBFUSCATE_PTR_FMT "]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + (prefix), \ + NM_HASH_OBFUSCATE_PTR(self) _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END + +/*****************************************************************************/ + +extern void _nm_logging_clear_platform_logging_cache(void); + +#endif /* __NETWORKMANAGER_LOGGING_H__ */ diff --git a/src/libnm-log-null/meson.build b/src/libnm-log-null/meson.build new file mode 100644 index 0000000..cd35304 --- /dev/null +++ b/src/libnm-log-null/meson.build @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_log_null = static_library( + 'nm-log-null', + sources: 'nm-logging-null.c', + include_directories: [ + src_inc, + top_inc, + ], + dependencies: glib_dep, +) diff --git a/src/libnm-log-null/nm-logging-null.c b/src/libnm-log-null/nm-logging-null.c new file mode 100644 index 0000000..a454c5b --- /dev/null +++ b/src/libnm-log-null/nm-logging-null.c @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "libnm-glib-aux/nm-logging-fwd.h" + +/*****************************************************************************/ + +gboolean +_nm_log_enabled_impl(gboolean mt_require_locking, NMLogLevel level, NMLogDomain domain) +{ + return FALSE; +} + +void +_nm_log_impl(const char *file, + guint line, + const char *func, + gboolean mt_require_locking, + NMLogLevel level, + NMLogDomain domain, + int error, + const char *ifname, + const char *con_uuid, + const char *fmt, + ...) +{} + +void +_nm_utils_monotonic_timestamp_initialized(const struct timespec *tp, + gint64 offset_sec, + gboolean is_boottime) +{} diff --git a/src/libnm-platform/meson.build b/src/libnm-platform/meson.build new file mode 100644 index 0000000..3e4f41a --- /dev/null +++ b/src/libnm-platform/meson.build @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_platform = static_library( + 'nm-platform', + sources: [ + 'nm-linux-platform.c', + 'nm-netlink.c', + 'nm-platform-utils.c', + 'nm-platform.c', + 'nmp-netns.c', + 'nmp-object.c', + 'nmp-rules-manager.c', + 'wifi/nm-wifi-utils-nl80211.c', + 'wifi/nm-wifi-utils.c', + 'wpan/nm-wpan-utils.c', + ] + (enable_wext ? [ 'wifi/nm-wifi-utils-wext.c' ] : []), + include_directories: [ + src_inc, + top_inc, + ], + dependencies: [ + glib_dep, + libudev_dep, + ], +) diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c new file mode 100644 index 0000000..0ee3a22 --- /dev/null +++ b/src/libnm-platform/nm-linux-platform.c @@ -0,0 +1,9740 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2012 - 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-linux-platform.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-glib-aux/nm-time-utils.h" +#include "libnm-log-core/nm-logging.h" +#include "libnm-platform/nm-netlink.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-platform/nmp-netns.h" +#include "libnm-platform/wifi/nm-wifi-utils-wext.h" +#include "libnm-platform/wifi/nm-wifi-utils.h" +#include "libnm-platform/wpan/nm-wpan-utils.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-udev-aux/nm-udev-utils.h" +#include "nm-platform-private.h" +#include "nmp-object.h" + +/*****************************************************************************/ + +/* re-implement to build against kernel + * headers that lack this. */ + +#include + +struct tc_defact { + tc_gen; +}; + +enum { TCA_DEF_UNSPEC, TCA_DEF_TM, TCA_DEF_PARMS, TCA_DEF_DATA, TCA_DEF_PAD, __TCA_DEF_MAX }; +#define TCA_DEF_MAX (__TCA_DEF_MAX - 1) + +/*****************************************************************************/ + +/* Compat with older kernels. */ + +#define TCA_FQ_CODEL_CE_THRESHOLD 7 +#define TCA_FQ_CODEL_MEMORY_LIMIT 9 + +/*****************************************************************************/ + +#define VLAN_FLAG_MVRP 0x8 + +/*****************************************************************************/ + +#define IFQDISCSIZ 32 + +/*****************************************************************************/ + +#ifndef IFLA_PROMISCUITY + #define IFLA_PROMISCUITY 30 +#endif +#define IFLA_NUM_TX_QUEUES 31 +#define IFLA_NUM_RX_QUEUES 32 +#define IFLA_CARRIER 33 +#define IFLA_PHYS_PORT_ID 34 +#define IFLA_LINK_NETNSID 37 +#define __IFLA_MAX 39 + +#define IFLA_INET6_TOKEN 7 +#define IFLA_INET6_ADDR_GEN_MODE 8 +#define __IFLA_INET6_MAX 9 + +#define IFLA_VLAN_PROTOCOL 5 +#define __IFLA_VLAN_MAX 6 + +#define IFA_FLAGS 8 +#define __IFA_MAX 9 + +#define IFLA_MACVLAN_FLAGS 2 +#define __IFLA_MACVLAN_MAX 3 + +#define IFLA_IPTUN_LINK 1 +#define IFLA_IPTUN_LOCAL 2 +#define IFLA_IPTUN_REMOTE 3 +#define IFLA_IPTUN_TTL 4 +#define IFLA_IPTUN_TOS 5 +#define IFLA_IPTUN_ENCAP_LIMIT 6 +#define IFLA_IPTUN_FLOWINFO 7 +#define IFLA_IPTUN_FLAGS 8 +#define IFLA_IPTUN_PROTO 9 +#define IFLA_IPTUN_PMTUDISC 10 +#define __IFLA_IPTUN_MAX 19 +#ifndef IFLA_IPTUN_MAX + #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) +#endif + +#define IFLA_TUN_UNSPEC 0 +#define IFLA_TUN_OWNER 1 +#define IFLA_TUN_GROUP 2 +#define IFLA_TUN_TYPE 3 +#define IFLA_TUN_PI 4 +#define IFLA_TUN_VNET_HDR 5 +#define IFLA_TUN_PERSIST 6 +#define IFLA_TUN_MULTI_QUEUE 7 +#define IFLA_TUN_NUM_QUEUES 8 +#define IFLA_TUN_NUM_DISABLED_QUEUES 9 +#define __IFLA_TUN_MAX 10 +#define IFLA_TUN_MAX (__IFLA_TUN_MAX - 1) + +G_STATIC_ASSERT(RTA_MAX == (__RTA_MAX - 1)); +#define RTA_PREF 20 +#undef RTA_MAX +#define RTA_MAX (MAX((__RTA_MAX - 1), RTA_PREF)) + +#ifndef MACVLAN_FLAG_NOPROMISC + #define MACVLAN_FLAG_NOPROMISC 1 +#endif + +#define IP6_FLOWINFO_TCLASS_MASK 0x0FF00000 +#define IP6_FLOWINFO_TCLASS_SHIFT 20 +#define IP6_FLOWINFO_FLOWLABEL_MASK 0x000FFFFF + +#define IFLA_BR_VLAN_STATS_ENABLED 41 + +/*****************************************************************************/ + +/* Appeared in the kernel prior to 3.13 dated 19 January, 2014 */ +#ifndef ARPHRD_6LOWPAN + #define ARPHRD_6LOWPAN 825 +#endif + +/*****************************************************************************/ + +#define FRA_TUN_ID 12 +#define FRA_SUPPRESS_IFGROUP 13 +#define FRA_SUPPRESS_PREFIXLEN 14 +#define FRA_PAD 18 +#define FRA_L3MDEV 19 +#define FRA_UID_RANGE 20 +#define FRA_PROTOCOL 21 +#define FRA_IP_PROTO 22 +#define FRA_SPORT_RANGE 23 +#define FRA_DPORT_RANGE 24 + +/*****************************************************************************/ + +#define IFLA_MACSEC_UNSPEC 0 +#define IFLA_MACSEC_SCI 1 +#define IFLA_MACSEC_PORT 2 +#define IFLA_MACSEC_ICV_LEN 3 +#define IFLA_MACSEC_CIPHER_SUITE 4 +#define IFLA_MACSEC_WINDOW 5 +#define IFLA_MACSEC_ENCODING_SA 6 +#define IFLA_MACSEC_ENCRYPT 7 +#define IFLA_MACSEC_PROTECT 8 +#define IFLA_MACSEC_INC_SCI 9 +#define IFLA_MACSEC_ES 10 +#define IFLA_MACSEC_SCB 11 +#define IFLA_MACSEC_REPLAY_PROTECT 12 +#define IFLA_MACSEC_VALIDATION 13 +#define IFLA_MACSEC_PAD 14 +#define __IFLA_MACSEC_MAX 15 + +/*****************************************************************************/ + +#define WG_CMD_GET_DEVICE 0 +#define WG_CMD_SET_DEVICE 1 + +#define WGDEVICE_F_REPLACE_PEERS ((guint32)(1U << 0)) + +#define WGPEER_F_REMOVE_ME ((guint32)(1U << 0)) +#define WGPEER_F_REPLACE_ALLOWEDIPS ((guint32)(1U << 1)) + +#define WGDEVICE_A_UNSPEC 0 +#define WGDEVICE_A_IFINDEX 1 +#define WGDEVICE_A_IFNAME 2 +#define WGDEVICE_A_PRIVATE_KEY 3 +#define WGDEVICE_A_PUBLIC_KEY 4 +#define WGDEVICE_A_FLAGS 5 +#define WGDEVICE_A_LISTEN_PORT 6 +#define WGDEVICE_A_FWMARK 7 +#define WGDEVICE_A_PEERS 8 +#define WGDEVICE_A_MAX 8 + +#define WGPEER_A_UNSPEC 0 +#define WGPEER_A_PUBLIC_KEY 1 +#define WGPEER_A_PRESHARED_KEY 2 +#define WGPEER_A_FLAGS 3 +#define WGPEER_A_ENDPOINT 4 +#define WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL 5 +#define WGPEER_A_LAST_HANDSHAKE_TIME 6 +#define WGPEER_A_RX_BYTES 7 +#define WGPEER_A_TX_BYTES 8 +#define WGPEER_A_ALLOWEDIPS 9 +#define WGPEER_A_MAX 9 + +#define WGALLOWEDIP_A_UNSPEC 0 +#define WGALLOWEDIP_A_FAMILY 1 +#define WGALLOWEDIP_A_IPADDR 2 +#define WGALLOWEDIP_A_CIDR_MASK 3 +#define WGALLOWEDIP_A_MAX 3 + +/*****************************************************************************/ + +/* Redefine VF enums and structures that are not available on older kernels. */ + +#define IFLA_VF_UNSPEC 0 +#define IFLA_VF_MAC 1 +#define IFLA_VF_VLAN 2 +#define IFLA_VF_TX_RATE 3 +#define IFLA_VF_SPOOFCHK 4 +#define IFLA_VF_LINK_STATE 5 +#define IFLA_VF_RATE 6 +#define IFLA_VF_RSS_QUERY_EN 7 +#define IFLA_VF_STATS 8 +#define IFLA_VF_TRUST 9 +#define IFLA_VF_IB_NODE_GUID 10 +#define IFLA_VF_IB_PORT_GUID 11 +#define IFLA_VF_VLAN_LIST 12 + +#define IFLA_VF_VLAN_INFO_UNSPEC 0 +#define IFLA_VF_VLAN_INFO 1 + +/* valid for TRUST, SPOOFCHK, LINK_STATE, RSS_QUERY_EN */ +struct _ifla_vf_setting { + guint32 vf; + guint32 setting; +}; + +struct _ifla_vf_rate { + guint32 vf; + guint32 min_tx_rate; + guint32 max_tx_rate; +}; + +struct _ifla_vf_vlan_info { + guint32 vf; + guint32 vlan; /* 0 - 4095, 0 disables VLAN filter */ + guint32 qos; + guint16 vlan_proto; /* VLAN protocol, either 802.1Q or 802.1ad */ +}; + +/*****************************************************************************/ + +/* Appeared in the kernel 4.0 dated April 12, 2015 */ +#ifndef BRIDGE_VLAN_INFO_RANGE_BEGIN + #define BRIDGE_VLAN_INFO_RANGE_BEGIN (1 << 3) /* VLAN is start of vlan range */ + #define BRIDGE_VLAN_INFO_RANGE_END (1 << 4) /* VLAN is end of vlan range */ +#endif + +/*****************************************************************************/ + +#define PSCHED_TIME_UNITS_PER_SEC 1000000 + +/*****************************************************************************/ + +typedef enum { + INFINIBAND_ACTION_CREATE_CHILD, + INFINIBAND_ACTION_DELETE_CHILD, +} InfinibandAction; + +typedef enum { + CHANGE_LINK_TYPE_UNSPEC, + CHANGE_LINK_TYPE_SET_MTU, + CHANGE_LINK_TYPE_SET_ADDRESS, +} ChangeLinkType; + +typedef struct { + union { + struct { + gconstpointer address; + gsize length; + } set_address; + }; +} ChangeLinkData; + +typedef enum { + _REFRESH_ALL_TYPE_FIRST = 0, + + REFRESH_ALL_TYPE_LINKS = 0, + REFRESH_ALL_TYPE_IP4_ADDRESSES = 1, + REFRESH_ALL_TYPE_IP6_ADDRESSES = 2, + REFRESH_ALL_TYPE_IP4_ROUTES = 3, + REFRESH_ALL_TYPE_IP6_ROUTES = 4, + REFRESH_ALL_TYPE_ROUTING_RULES_IP4 = 5, + REFRESH_ALL_TYPE_ROUTING_RULES_IP6 = 6, + REFRESH_ALL_TYPE_QDISCS = 7, + REFRESH_ALL_TYPE_TFILTERS = 8, + + _REFRESH_ALL_TYPE_NUM, +} RefreshAllType; + +typedef struct { + NMPObjectType obj_type; + + /* for NLM_F_DUMP, which address family to request. */ + int addr_family; +} RefreshAllInfo; + +typedef enum { + DELAYED_ACTION_TYPE_NONE = 0, + +#define F(val, name) ((sizeof(char[(((val)) == (name)) ? 1 : -1]) * 0) + (val)) + DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS = 1 << F(0, REFRESH_ALL_TYPE_LINKS), + DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES = 1 << F(1, REFRESH_ALL_TYPE_IP4_ADDRESSES), + DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES = 1 << F(2, REFRESH_ALL_TYPE_IP6_ADDRESSES), + DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES = 1 << F(3, REFRESH_ALL_TYPE_IP4_ROUTES), + DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES = 1 << F(4, REFRESH_ALL_TYPE_IP6_ROUTES), + DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4 = 1 + << F(5, REFRESH_ALL_TYPE_ROUTING_RULES_IP4), + DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6 = 1 + << F(6, REFRESH_ALL_TYPE_ROUTING_RULES_IP6), + DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS = 1 << F(7, REFRESH_ALL_TYPE_QDISCS), + DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS = 1 << F(8, REFRESH_ALL_TYPE_TFILTERS), +#undef F + + DELAYED_ACTION_TYPE_REFRESH_LINK = 1 << 9, + DELAYED_ACTION_TYPE_MASTER_CONNECTED = 1 << 10, + DELAYED_ACTION_TYPE_READ_NETLINK = 1 << 11, + DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE = 1 << 12, + + __DELAYED_ACTION_TYPE_MAX, + + DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_ALL = + DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4 + | DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6, + + DELAYED_ACTION_TYPE_REFRESH_ALL = + DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS | DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES | DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES + | DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_ALL | DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS + | DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS, + + DELAYED_ACTION_TYPE_MAX = __DELAYED_ACTION_TYPE_MAX - 1, +} DelayedActionType; + +#define FOR_EACH_DELAYED_ACTION(iflags, flags_all) \ + for ((iflags) = (DelayedActionType) 0x1LL; ({ \ + gboolean _good = FALSE; \ + \ + nm_assert(nm_utils_is_power_of_two(iflags)); \ + \ + while ((iflags) <= DELAYED_ACTION_TYPE_MAX) { \ + if (NM_FLAGS_ANY((flags_all), (iflags))) { \ + _good = TRUE; \ + break; \ + } \ + (iflags) <<= 1; \ + } \ + _good; \ + }); \ + (iflags) <<= 1) + +typedef enum { + /* Negative values are errors from kernel. Add dummy member to + * make enum signed. */ + _WAIT_FOR_NL_RESPONSE_RESULT_SYSTEM_ERROR = G_MININT, + + WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN = 0, + WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK, + WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_UNKNOWN, + WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC, + WAIT_FOR_NL_RESPONSE_RESULT_FAILED_POLL, + WAIT_FOR_NL_RESPONSE_RESULT_FAILED_TIMEOUT, + WAIT_FOR_NL_RESPONSE_RESULT_FAILED_DISPOSING, + WAIT_FOR_NL_RESPONSE_RESULT_FAILED_SETNS, +} WaitForNlResponseResult; + +typedef enum { + DELAYED_ACTION_RESPONSE_TYPE_VOID = 0, + DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS = 1, + DELAYED_ACTION_RESPONSE_TYPE_ROUTE_GET = 2, +} DelayedActionWaitForNlResponseType; + +typedef struct { + guint32 seq_number; + WaitForNlResponseResult seq_result; + DelayedActionWaitForNlResponseType response_type; + gint64 timeout_abs_ns; + WaitForNlResponseResult * out_seq_result; + char ** out_errmsg; + union { + int * out_refresh_all_in_progress; + NMPObject **out_route_get; + gpointer out_data; + } response; +} DelayedActionWaitForNlResponseData; + +/*****************************************************************************/ + +typedef struct { + struct nl_sock *genl; + + struct nl_sock *nlh; + + GSource *event_source; + + guint32 nlh_seq_next; +#if NM_MORE_LOGGING + guint32 nlh_seq_last_handled; +#endif + guint32 nlh_seq_last_seen; + + guint32 pruning[_REFRESH_ALL_TYPE_NUM]; + + GHashTable *sysctl_get_prev_values; + CList sysctl_list; + CList sysctl_clear_cache_lst; + + NMUdevClient *udev_client; + + struct { + /* which delayed actions are scheduled, as marked in @flags. + * Some types have additional arguments in the fields below. */ + DelayedActionType flags; + + /* counter that a refresh all action is in progress, separated + * by type. */ + int refresh_all_in_progress[_REFRESH_ALL_TYPE_NUM]; + + GPtrArray *list_master_connected; + GPtrArray *list_refresh_link; + GArray * list_wait_for_nl_response; + + int is_handling; + } delayed_action; + +} NMLinuxPlatformPrivate; + +struct _NMLinuxPlatform { + NMPlatform parent; + NMLinuxPlatformPrivate _priv; +}; + +struct _NMLinuxPlatformClass { + NMPlatformClass parent; +}; + +G_DEFINE_TYPE(NMLinuxPlatform, nm_linux_platform, NM_TYPE_PLATFORM) + +#define NM_LINUX_PLATFORM_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMLinuxPlatform, NM_IS_LINUX_PLATFORM, NMPlatform) + +static NMPlatform * +NM_LINUX_PLATFORM_FROM_PRIVATE(NMLinuxPlatformPrivate *priv) +{ + gpointer self; + + nm_assert(priv); + + self = (((char *) priv) - G_STRUCT_OFFSET(NMLinuxPlatform, _priv)); + nm_assert(NM_IS_LINUX_PLATFORM(self)); + return self; +} + +/*****************************************************************************/ + +#define _NMLOG_PREFIX_NAME "platform-linux" +#define _NMLOG_DOMAIN LOGD_PLATFORM +#define _NMLOG2_DOMAIN LOGD_PLATFORM +#define _NMLOG(level, ...) _LOG(level, _NMLOG_DOMAIN, platform, __VA_ARGS__) +#define _NMLOG_err(errsv, level, ...) _LOG_err(errsv, level, _NMLOG_DOMAIN, platform, __VA_ARGS__) +#define _NMLOG2(level, ...) _LOG(level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) +#define _NMLOG2_err(errsv, level, ...) _LOG_err(errsv, level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) + +#define _LOG_print(__level, __domain, __errsv, self, ...) \ + G_STMT_START \ + { \ + char __prefix[32]; \ + const char * __p_prefix = _NMLOG_PREFIX_NAME; \ + NMPlatform *const __self = (self); \ + \ + if (__self && nm_platform_get_log_with_ptr(__self)) { \ + g_snprintf(__prefix, sizeof(__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ + __p_prefix = __prefix; \ + } \ + _nm_log(__level, \ + __domain, \ + __errsv, \ + NULL, \ + NULL, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __p_prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END + +#define _LOG(level, domain, self, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + const NMLogDomain __domain = (domain); \ + \ + if (nm_logging_enabled(__level, __domain)) { \ + _LOG_print(__level, __domain, 0, self, __VA_ARGS__); \ + } \ + } \ + G_STMT_END + +#define _LOG_err(errsv, level, domain, self, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + const NMLogDomain __domain = (domain); \ + \ + if (nm_logging_enabled(__level, __domain)) { \ + int __errsv = (errsv); \ + \ + /* The %m format specifier (GNU extension) would already allow you to specify the error + * message conveniently (and nm_log would get that right too). But we don't want to depend + * on that, so instead append the message at the end. + * Currently, users are expected not to use %m in the format string. */ \ + _LOG_print( \ + __level, \ + __domain, \ + __errsv, \ + self, \ + _NM_UTILS_MACRO_FIRST(__VA_ARGS__) ": %s (%d)" _NM_UTILS_MACRO_REST(__VA_ARGS__), \ + nm_strerror_native(__errsv), \ + __errsv); \ + } \ + } \ + G_STMT_END + +/*****************************************************************************/ + +static void +delayed_action_schedule(NMPlatform *platform, DelayedActionType action_type, gpointer user_data); +static gboolean delayed_action_handle_all(NMPlatform *platform, gboolean read_netlink); +static void do_request_link_no_delayed_actions(NMPlatform *platform, int ifindex, const char *name); +static void do_request_all_no_delayed_actions(NMPlatform *platform, DelayedActionType action_type); +static void cache_on_change(NMPlatform * platform, + NMPCacheOpsType cache_op, + const NMPObject *obj_old, + const NMPObject *obj_new); +static void cache_prune_all(NMPlatform *platform); +static gboolean event_handler_read_netlink(NMPlatform *platform, gboolean wait_for_acks); +static struct nl_sock *_genl_sock(NMLinuxPlatform *platform); + +/*****************************************************************************/ + +static int +wait_for_nl_response_to_nmerr(WaitForNlResponseResult seq_result) +{ + if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) + return 0; + if (seq_result < 0) + return (int) seq_result; + return -NME_PL_NETLINK; +} + +static const char * +wait_for_nl_response_to_string(WaitForNlResponseResult seq_result, + const char * errmsg, + char * buf, + gsize buf_size) +{ + char *buf0 = buf; + + switch (seq_result) { + case WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN: + nm_utils_strbuf_append_str(&buf, &buf_size, "unknown"); + break; + case WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK: + nm_utils_strbuf_append_str(&buf, &buf_size, "success"); + break; + case WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_UNKNOWN: + nm_utils_strbuf_append_str(&buf, &buf_size, "failure"); + break; + default: + if (seq_result < 0) { + nm_utils_strbuf_append(&buf, + &buf_size, + "failure %d (%s%s%s)", + -((int) seq_result), + nm_strerror_native(-((int) seq_result)), + errmsg ? " - " : "", + errmsg ?: ""); + } else + nm_utils_strbuf_append(&buf, &buf_size, "internal failure %d", (int) seq_result); + break; + } + return buf0; +} + +/****************************************************************** + * Various utilities + ******************************************************************/ + +static int +_vlan_qos_mapping_cmp_from(gconstpointer a, gconstpointer b, gpointer user_data) +{ + const NMVlanQosMapping *map_a = a; + const NMVlanQosMapping *map_b = b; + + if (map_a->from != map_b->from) + return map_a->from < map_b->from ? -1 : 1; + return 0; +} + +static int +_vlan_qos_mapping_cmp_from_ptr(gconstpointer a, gconstpointer b, gpointer user_data) +{ + return _vlan_qos_mapping_cmp_from(*((const NMVlanQosMapping **) a), + *((const NMVlanQosMapping **) b), + NULL); +} + +/****************************************************************** + * NMLinkType functions + ******************************************************************/ + +typedef struct { + const char *type_string; + + /* IFLA_INFO_KIND / rtnl_link_get_type() where applicable; the rtnl type + * should only be specified if the device type can be created without + * additional parameters, and if the device type can be determined from + * the rtnl_type. eg, tun/tap should not be specified since both + * tun and tap devices use "tun", and InfiniBand should not be + * specified because a PKey is required at creation. Drivers set this + * value from their 'struct rtnl_link_ops' structure. + */ + const char *rtnl_type; + + /* uevent DEVTYPE where applicable, from /sys/class/net//uevent; + * drivers set this value from their SET_NETDEV_DEV() call and the + * 'struct device_type' name member. + */ + const char *devtype; +} LinkDesc; + +static const LinkDesc link_descs[] = { + [NM_LINK_TYPE_NONE] = {"none", NULL, NULL}, + [NM_LINK_TYPE_UNKNOWN] = {"unknown", NULL, NULL}, + [NM_LINK_TYPE_ANY] = {"any", NULL, NULL}, + + [NM_LINK_TYPE_ETHERNET] = {"ethernet", NULL, NULL}, + [NM_LINK_TYPE_INFINIBAND] = {"infiniband", NULL, NULL}, + [NM_LINK_TYPE_OLPC_MESH] = {"olpc-mesh", NULL, NULL}, + [NM_LINK_TYPE_WIFI] = {"wifi", NULL, "wlan"}, + [NM_LINK_TYPE_WWAN_NET] = {"wwan", NULL, "wwan"}, + [NM_LINK_TYPE_WIMAX] = {"wimax", "wimax", "wimax"}, + [NM_LINK_TYPE_WPAN] = {"wpan", NULL, NULL}, + [NM_LINK_TYPE_6LOWPAN] = {"6lowpan", NULL, NULL}, + + [NM_LINK_TYPE_BNEP] = {"bluetooth", NULL, "bluetooth"}, + [NM_LINK_TYPE_DUMMY] = {"dummy", "dummy", NULL}, + [NM_LINK_TYPE_GRE] = {"gre", "gre", NULL}, + [NM_LINK_TYPE_GRETAP] = {"gretap", "gretap", NULL}, + [NM_LINK_TYPE_IFB] = {"ifb", "ifb", NULL}, + [NM_LINK_TYPE_IP6TNL] = {"ip6tnl", "ip6tnl", NULL}, + [NM_LINK_TYPE_IP6GRE] = {"ip6gre", "ip6gre", NULL}, + [NM_LINK_TYPE_IP6GRETAP] = {"ip6gretap", "ip6gretap", NULL}, + [NM_LINK_TYPE_IPIP] = {"ipip", "ipip", NULL}, + [NM_LINK_TYPE_LOOPBACK] = {"loopback", NULL, NULL}, + [NM_LINK_TYPE_MACSEC] = {"macsec", "macsec", NULL}, + [NM_LINK_TYPE_MACVLAN] = {"macvlan", "macvlan", NULL}, + [NM_LINK_TYPE_MACVTAP] = {"macvtap", "macvtap", NULL}, + [NM_LINK_TYPE_OPENVSWITCH] = {"openvswitch", "openvswitch", NULL}, + [NM_LINK_TYPE_PPP] = {"ppp", NULL, "ppp"}, + [NM_LINK_TYPE_SIT] = {"sit", "sit", NULL}, + [NM_LINK_TYPE_TUN] = {"tun", "tun", NULL}, + [NM_LINK_TYPE_VETH] = {"veth", "veth", NULL}, + [NM_LINK_TYPE_VLAN] = {"vlan", "vlan", "vlan"}, + [NM_LINK_TYPE_VRF] = {"vrf", "vrf", "vrf"}, + [NM_LINK_TYPE_VXLAN] = {"vxlan", "vxlan", "vxlan"}, + [NM_LINK_TYPE_WIREGUARD] = {"wireguard", "wireguard", "wireguard"}, + + [NM_LINK_TYPE_BRIDGE] = {"bridge", "bridge", "bridge"}, + [NM_LINK_TYPE_BOND] = {"bond", "bond", "bond"}, + [NM_LINK_TYPE_TEAM] = {"team", "team", NULL}, +}; + +static const LinkDesc * +_link_desc_from_link_type(NMLinkType link_type) +{ + nm_assert(_NM_INT_NOT_NEGATIVE(link_type)); + nm_assert(link_type < G_N_ELEMENTS(link_descs)); + nm_assert(link_descs[link_type].type_string); + + return &link_descs[link_type]; +} + +static NMLinkType +_link_type_from_rtnl_type(const char *name) +{ + static const NMLinkType LIST[] = { + NM_LINK_TYPE_BOND, /* "bond" */ + NM_LINK_TYPE_BRIDGE, /* "bridge" */ + NM_LINK_TYPE_DUMMY, /* "dummy" */ + NM_LINK_TYPE_GRE, /* "gre" */ + NM_LINK_TYPE_GRETAP, /* "gretap" */ + NM_LINK_TYPE_IFB, /* "ifb" */ + NM_LINK_TYPE_IP6GRE, /* "ip6gre" */ + NM_LINK_TYPE_IP6GRETAP, /* "ip6gretap" */ + NM_LINK_TYPE_IP6TNL, /* "ip6tnl" */ + NM_LINK_TYPE_IPIP, /* "ipip" */ + NM_LINK_TYPE_MACSEC, /* "macsec" */ + NM_LINK_TYPE_MACVLAN, /* "macvlan" */ + NM_LINK_TYPE_MACVTAP, /* "macvtap" */ + NM_LINK_TYPE_OPENVSWITCH, /* "openvswitch" */ + NM_LINK_TYPE_SIT, /* "sit" */ + NM_LINK_TYPE_TEAM, /* "team" */ + NM_LINK_TYPE_TUN, /* "tun" */ + NM_LINK_TYPE_VETH, /* "veth" */ + NM_LINK_TYPE_VLAN, /* "vlan" */ + NM_LINK_TYPE_VRF, /* "vrf" */ + NM_LINK_TYPE_VXLAN, /* "vxlan" */ + NM_LINK_TYPE_WIMAX, /* "wimax" */ + NM_LINK_TYPE_WIREGUARD, /* "wireguard" */ + }; + + nm_assert(name); + + if (NM_MORE_ASSERT_ONCE(5)) { + int i, j, k; + + for (i = 0; i < G_N_ELEMENTS(LIST); i++) { + nm_assert(_link_desc_from_link_type(LIST[i]) == &link_descs[LIST[i]]); + nm_assert(link_descs[LIST[i]].rtnl_type); + if (i > 0) + nm_assert(strcmp(link_descs[LIST[i - 1]].rtnl_type, link_descs[LIST[i]].rtnl_type) + < 0); + } + for (i = 0; i < G_N_ELEMENTS(link_descs); i++) { + if (!link_descs[i].rtnl_type) + continue; + for (j = 0, k = 0; j < G_N_ELEMENTS(LIST); j++) + k += (LIST[j] == i); + nm_assert(k == 1); + } + } + + { + int imin = 0; + int imax = (G_N_ELEMENTS(LIST) - 1); + int imid = (G_N_ELEMENTS(LIST) - 1) / 2; + + for (;;) { + const int cmp = strcmp(link_descs[LIST[imid]].rtnl_type, name); + + if (G_UNLIKELY(cmp == 0)) + return LIST[imid]; + + if (cmp < 0) + imin = imid + 1; + else + imax = imid - 1; + + if (G_UNLIKELY(imin > imax)) + return NM_LINK_TYPE_NONE; + + imid = (imin + imax) / 2; + } + } +} + +static NMLinkType +_link_type_from_devtype(const char *name) +{ + static const NMLinkType LIST[] = { + NM_LINK_TYPE_BNEP, /* "bluetooth" */ + NM_LINK_TYPE_BOND, /* "bond" */ + NM_LINK_TYPE_BRIDGE, /* "bridge" */ + NM_LINK_TYPE_PPP, /* "ppp" */ + NM_LINK_TYPE_VLAN, /* "vlan" */ + NM_LINK_TYPE_VRF, /* "vrf" */ + NM_LINK_TYPE_VXLAN, /* "vxlan" */ + NM_LINK_TYPE_WIMAX, /* "wimax" */ + NM_LINK_TYPE_WIREGUARD, /* "wireguard" */ + NM_LINK_TYPE_WIFI, /* "wlan" */ + NM_LINK_TYPE_WWAN_NET, /* "wwan" */ + }; + + nm_assert(name); + + if (NM_MORE_ASSERT_ONCE(5)) { + int i, j, k; + + for (i = 0; i < G_N_ELEMENTS(LIST); i++) { + nm_assert(_link_desc_from_link_type(LIST[i]) == &link_descs[LIST[i]]); + nm_assert(link_descs[LIST[i]].devtype); + if (i > 0) + nm_assert(strcmp(link_descs[LIST[i - 1]].devtype, link_descs[LIST[i]].devtype) < 0); + } + for (i = 0; i < G_N_ELEMENTS(link_descs); i++) { + if (!link_descs[i].devtype) + continue; + for (j = 0, k = 0; j < G_N_ELEMENTS(LIST); j++) + k += (LIST[j] == i); + nm_assert(k == 1); + } + } + + { + int imin = 0; + int imax = (G_N_ELEMENTS(LIST) - 1); + int imid = (G_N_ELEMENTS(LIST) - 1) / 2; + + for (;;) { + const int cmp = strcmp(link_descs[LIST[imid]].devtype, name); + + if (G_UNLIKELY(cmp == 0)) + return LIST[imid]; + + if (cmp < 0) + imin = imid + 1; + else + imax = imid - 1; + + if (G_UNLIKELY(imin > imax)) + return NM_LINK_TYPE_NONE; + + imid = (imin + imax) / 2; + } + } +} + +static const char * +nm_link_type_to_rtnl_type_string(NMLinkType link_type) +{ + return _link_desc_from_link_type(link_type)->rtnl_type; +} + +const char * +nm_link_type_to_string(NMLinkType link_type) +{ + return _link_desc_from_link_type(link_type)->type_string; +} + +/****************************************************************** + * Utilities + ******************************************************************/ + +/* _timestamp_nl_to_ms: + * @timestamp_nl: a timestamp from ifa_cacheinfo. + * @monotonic_ms: *now* in CLOCK_MONOTONIC. Needed to estimate the current + * uptime and how often timestamp_nl wrapped. + * + * Convert the timestamp from ifa_cacheinfo to CLOCK_MONOTONIC milliseconds. + * The ifa_cacheinfo fields tstamp and cstamp contains timestamps that counts + * with in 1/100th of a second of clock_gettime(CLOCK_MONOTONIC). However, + * the uint32 counter wraps every 497 days of uptime, so we have to compensate + * for that. */ +static gint64 +_timestamp_nl_to_ms(guint32 timestamp_nl, gint64 monotonic_ms) +{ + const gint64 WRAP_INTERVAL = (((gint64) G_MAXUINT32) + 1) * (1000 / 100); + gint64 timestamp_nl_ms; + + /* convert timestamp from 1/100th of a second to msec. */ + timestamp_nl_ms = ((gint64) timestamp_nl) * (1000 / 100); + + /* timestamp wraps every 497 days. Try to compensate for that.*/ + if (timestamp_nl_ms > monotonic_ms) { + /* timestamp_nl_ms is in the future. Truncate it to *now* */ + timestamp_nl_ms = monotonic_ms; + } else if (monotonic_ms >= WRAP_INTERVAL) { + timestamp_nl_ms += (monotonic_ms / WRAP_INTERVAL) * WRAP_INTERVAL; + if (timestamp_nl_ms > monotonic_ms) + timestamp_nl_ms -= WRAP_INTERVAL; + } + + return timestamp_nl_ms; +} + +static guint32 +_addrtime_timestamp_to_nm(guint32 timestamp, gint32 *out_now_nm) +{ + gint64 now_nl; + gint64 now_nm; + gint64 result; + + /* timestamp is unset. Default to 1. */ + if (!timestamp) { + NM_SET_OUT(out_now_nm, 0); + return 1; + } + + /* do all the calculations in milliseconds scale */ + + now_nm = nm_utils_get_monotonic_timestamp_msec(); + now_nl = nm_utils_clock_gettime_msec(CLOCK_MONOTONIC); + + nm_assert(now_nm >= 1000); + nm_assert(now_nl >= 0); + + result = now_nm - (now_nl - _timestamp_nl_to_ms(timestamp, now_nl)); + + NM_SET_OUT(out_now_nm, now_nm / 1000); + + /* converting the timestamp into nm_utils_get_monotonic_timestamp_msec() scale is + * a good guess but fails in the following situations: + * + * - If the address existed before start of the process, the timestamp in nm scale would + * be negative or zero. In this case we default to 1. + * - during hibernation, the CLOCK_MONOTONIC/timestamp drifts from + * nm_utils_get_monotonic_timestamp_msec() scale. + */ + if (result <= 1000) + return 1; + + if (result > now_nm) + return now_nm / 1000; + + return result / 1000; +} + +static guint32 +_addrtime_extend_lifetime(guint32 lifetime, guint32 seconds) +{ + guint64 v; + + if (lifetime == NM_PLATFORM_LIFETIME_PERMANENT || seconds == 0) + return lifetime; + + v = (guint64) lifetime + (guint64) seconds; + return MIN(v, NM_PLATFORM_LIFETIME_PERMANENT - 1); +} + +/* The rtnl_addr object contains relative lifetimes @valid and @preferred + * that count in seconds, starting from the moment when the kernel constructed + * the netlink message. + * + * There is also a field rtnl_addr_last_update_time(), which is the absolute + * time in 1/100th of a second of clock_gettime (CLOCK_MONOTONIC) when the address + * was modified (wrapping every 497 days). + * Immediately at the time when the address was last modified, #NOW and @last_update_time + * are the same, so (only) in that case @valid and @preferred are anchored at @last_update_time. + * However, this is not true in general. As time goes by, whenever kernel sends a new address + * via netlink, the lifetimes keep counting down. + **/ +static void +_addrtime_get_lifetimes(guint32 timestamp, + guint32 lifetime, + guint32 preferred, + guint32 *out_timestamp, + guint32 *out_lifetime, + guint32 *out_preferred) +{ + gint32 now; + + if (lifetime != NM_PLATFORM_LIFETIME_PERMANENT || preferred != NM_PLATFORM_LIFETIME_PERMANENT) { + if (preferred > lifetime) + preferred = lifetime; + timestamp = _addrtime_timestamp_to_nm(timestamp, &now); + + if (now == 0) { + /* strange. failed to detect the last-update time and assumed that timestamp is 1. */ + nm_assert(timestamp == 1); + now = nm_utils_get_monotonic_timestamp_sec(); + } + if (timestamp < now) { + guint32 diff = now - timestamp; + + lifetime = _addrtime_extend_lifetime(lifetime, diff); + preferred = _addrtime_extend_lifetime(preferred, diff); + } else + nm_assert(timestamp == now); + } else + timestamp = 0; + *out_timestamp = timestamp; + *out_lifetime = lifetime; + *out_preferred = preferred; +} + +/*****************************************************************************/ + +static const NMPObject * +_lookup_cached_link(const NMPCache * cache, + int ifindex, + gboolean * completed_from_cache, + const NMPObject **link_cached) +{ + const NMPObject *obj; + + nm_assert(completed_from_cache && link_cached); + + if (!*completed_from_cache) { + obj = ifindex > 0 && cache ? nmp_cache_lookup_link(cache, ifindex) : NULL; + + *link_cached = obj; + *completed_from_cache = TRUE; + } + return *link_cached; +} + +/*****************************************************************************/ + +#define DEVTYPE_PREFIX "DEVTYPE=" + +static char * +_linktype_read_devtype(int dirfd) +{ + gs_free char *contents = NULL; + char * cont, *end; + + nm_assert(dirfd >= 0); + + if (!nm_utils_file_get_contents(dirfd, + "uevent", + 1 * 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, + &contents, + NULL, + NULL, + NULL)) + return NULL; + for (cont = contents; cont; cont = end) { + end = strpbrk(cont, "\r\n"); + if (end) + *end++ = '\0'; + if (strncmp(cont, DEVTYPE_PREFIX, NM_STRLEN(DEVTYPE_PREFIX)) == 0) { + cont += NM_STRLEN(DEVTYPE_PREFIX); + memmove(contents, cont, strlen(cont) + 1); + return g_steal_pointer(&contents); + } + } + return NULL; +} + +static NMLinkType +_linktype_get_type(NMPlatform * platform, + const NMPCache * cache, + const char * kind, + int ifindex, + const char * ifname, + unsigned flags, + unsigned arptype, + gboolean * completed_from_cache, + const NMPObject **link_cached, + const char ** out_kind) +{ + NMLinkType link_type; + + NMTST_ASSERT_PLATFORM_NETNS_CURRENT(platform); + nm_assert(ifname); + nm_assert(_link_type_from_devtype("wlan") == NM_LINK_TYPE_WIFI); + nm_assert(_link_type_from_rtnl_type("bond") == NM_LINK_TYPE_BOND); + + if (completed_from_cache) { + const NMPObject *obj; + + obj = _lookup_cached_link(cache, ifindex, completed_from_cache, link_cached); + + /* If we detected the link type before, we stick to that + * decision unless the "kind" or "name" changed. If "name" changed, + * it means that their type may not have been determined correctly + * due to race conditions while accessing sysfs. + * + * This way, we save additional ethtool/sysctl lookups, but moreover, + * we keep the linktype stable and don't change it as long as the link + * exists. + * + * Note that kernel *can* reuse the ifindex (on integer overflow, and + * when moving interface to other netns). Thus here there is a tiny potential + * of messing stuff up. */ + if (obj && obj->_link.netlink.is_in_netlink + && !NM_IN_SET(obj->link.type, NM_LINK_TYPE_UNKNOWN, NM_LINK_TYPE_NONE) + && nm_streq(ifname, obj->link.name) && (!kind || nm_streq0(kind, obj->link.kind))) { + nm_assert(obj->link.kind == g_intern_string(obj->link.kind)); + *out_kind = obj->link.kind; + return obj->link.type; + } + } + + /* we intern kind to not require us to keep the pointer alive. Essentially + * leaking it in a global cache. That should be safe enough, because the + * kind comes only from kernel messages, which depend on the number of + * available drivers. So, there is not the danger that we leak uncontrolled + * many kinds. */ + *out_kind = g_intern_string(kind); + + if (kind) { + link_type = _link_type_from_rtnl_type(kind); + if (link_type != NM_LINK_TYPE_NONE) + return link_type; + } + + if (arptype == ARPHRD_LOOPBACK) + return NM_LINK_TYPE_LOOPBACK; + else if (arptype == ARPHRD_INFINIBAND) + return NM_LINK_TYPE_INFINIBAND; + else if (arptype == ARPHRD_SIT) + return NM_LINK_TYPE_SIT; + else if (arptype == ARPHRD_TUNNEL6) + return NM_LINK_TYPE_IP6TNL; + else if (arptype == ARPHRD_PPP) + return NM_LINK_TYPE_PPP; + else if (arptype == ARPHRD_IEEE802154) + return NM_LINK_TYPE_WPAN; + else if (arptype == ARPHRD_6LOWPAN) + return NM_LINK_TYPE_6LOWPAN; + + { + NMPUtilsEthtoolDriverInfo driver_info; + + /* Fallback OVS detection for kernel <= 3.16 */ + if (nmp_utils_ethtool_get_driver_info(ifindex, &driver_info)) { + if (nm_streq(driver_info.driver, "openvswitch")) + return NM_LINK_TYPE_OPENVSWITCH; + + if (arptype == 256) { + /* Some s390 CTC-type devices report 256 for the encapsulation type + * for some reason, but we need to call them Ethernet. + */ + if (nm_streq(driver_info.driver, "ctcm")) + return NM_LINK_TYPE_ETHERNET; + } + } + } + + { + nm_auto_close int dirfd = -1; + gs_free char * devtype = NULL; + char ifname_verified[IFNAMSIZ]; + + dirfd = nmp_utils_sysctl_open_netdir(ifindex, ifname, ifname_verified); + if (dirfd >= 0) { + if (faccessat(dirfd, "anycast_mask", F_OK, 0) == 0) + return NM_LINK_TYPE_OLPC_MESH; + + devtype = _linktype_read_devtype(dirfd); + if (devtype) { + link_type = _link_type_from_devtype(devtype); + if (link_type != NM_LINK_TYPE_NONE) { + if (link_type == NM_LINK_TYPE_BNEP && arptype != ARPHRD_ETHER) { + /* Both BNEP and 6lowpan use DEVTYPE=bluetooth, so we must + * use arptype to distinguish between them. + */ + } else + return link_type; + } + } + + /* Fallback for drivers that don't call SET_NETDEV_DEVTYPE() */ + if (nm_wifi_utils_is_wifi(dirfd, ifname_verified)) + return NM_LINK_TYPE_WIFI; + } + + if (arptype == ARPHRD_ETHER) { + /* Misc non-upstream WWAN drivers. rmnet is Qualcomm's proprietary + * modem interface, ccmni is MediaTek's. FIXME: these drivers should + * really set devtype=WWAN. + */ + if (g_str_has_prefix(ifname, "rmnet") || g_str_has_prefix(ifname, "rev_rmnet") + || g_str_has_prefix(ifname, "ccmni")) + return NM_LINK_TYPE_WWAN_NET; + + /* Standard wired ethernet interfaces don't report an rtnl_link_type, so + * only allow fallback to Ethernet if no type is given. This should + * prevent future virtual network drivers from being treated as Ethernet + * when they should be Generic instead. + */ + if (!kind && !devtype) + return NM_LINK_TYPE_ETHERNET; + + /* The USB gadget interfaces behave and look like ordinary ethernet devices + * aside from the DEVTYPE. */ + if (nm_streq0(devtype, "gadget")) + return NM_LINK_TYPE_ETHERNET; + + /* Distributed Switch Architecture switch chips */ + if (nm_streq0(devtype, "dsa")) + return NM_LINK_TYPE_ETHERNET; + } + } + + return NM_LINK_TYPE_UNKNOWN; +} + +/****************************************************************** + * libnl unility functions and wrappers + ******************************************************************/ + +#define NLMSG_TAIL(nmsg) ((struct rtattr *) (((char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) + +/* copied from iproute2's addattr_l(). */ +static gboolean +_nl_addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen) +{ + int len = RTA_LENGTH(alen); + struct rtattr *rta; + + if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) + return FALSE; + + rta = NLMSG_TAIL(n); + rta->rta_type = type; + rta->rta_len = len; + memcpy(RTA_DATA(rta), data, alen); + n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); + return TRUE; +} + +/****************************************************************** + * NMPObject/netlink functions + ******************************************************************/ + +#define _check_addr_or_return_val(tb, attr, addr_len, ret_val) \ + ({ \ + const struct nlattr *__t = (tb)[(attr)]; \ + \ + if (__t) { \ + if (nla_len(__t) != (addr_len)) { \ + return ret_val; \ + } \ + } \ + !!__t; \ + }) + +#define _check_addr_or_return_null(tb, attr, addr_len) \ + _check_addr_or_return_val(tb, attr, addr_len, NULL) + +/*****************************************************************************/ + +/* Copied and heavily modified from libnl3's inet6_parse_protinfo(). */ +static gboolean +_parse_af_inet6(NMPlatform * platform, + struct nlattr * attr, + NMUtilsIPv6IfaceId *out_token, + gboolean * out_token_valid, + guint8 * out_addr_gen_mode_inv, + gboolean * out_addr_gen_mode_valid) +{ + static const struct nla_policy policy[] = { + [IFLA_INET6_FLAGS] = {.type = NLA_U32}, + [IFLA_INET6_CACHEINFO] = {.minlen = nm_offsetofend(struct ifla_cacheinfo, retrans_time)}, + [IFLA_INET6_CONF] = {.minlen = 4}, + [IFLA_INET6_STATS] = {.minlen = 8}, + [IFLA_INET6_ICMP6STATS] = {.minlen = 8}, + [IFLA_INET6_TOKEN] = {.minlen = sizeof(struct in6_addr)}, + [IFLA_INET6_ADDR_GEN_MODE] = {.type = NLA_U8}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + struct in6_addr i6_token; + gboolean token_valid = FALSE; + gboolean addr_gen_mode_valid = FALSE; + guint8 i6_addr_gen_mode_inv = 0; + + if (nla_parse_nested_arr(tb, attr, policy) < 0) + return FALSE; + + if (tb[IFLA_INET6_CONF] && nla_len(tb[IFLA_INET6_CONF]) % 4) + return FALSE; + if (tb[IFLA_INET6_STATS] && nla_len(tb[IFLA_INET6_STATS]) % 8) + return FALSE; + if (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) % 8) + return FALSE; + + if (_check_addr_or_return_val(tb, IFLA_INET6_TOKEN, sizeof(struct in6_addr), FALSE)) { + nla_memcpy(&i6_token, tb[IFLA_INET6_TOKEN], sizeof(struct in6_addr)); + token_valid = TRUE; + } + + /* Hack to detect support addrgenmode of the kernel. We only parse + * netlink messages that we receive from kernel, hence this check + * is valid. */ + if (!_nm_platform_kernel_support_detected(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) { + /* IFLA_INET6_ADDR_GEN_MODE was added in kernel 3.17, dated 5 October, 2014. */ + _nm_platform_kernel_support_init(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL, + tb[IFLA_INET6_ADDR_GEN_MODE] ? 1 : -1); + } + + if (tb[IFLA_INET6_ADDR_GEN_MODE]) { + i6_addr_gen_mode_inv = _nm_platform_uint8_inv(nla_get_u8(tb[IFLA_INET6_ADDR_GEN_MODE])); + if (i6_addr_gen_mode_inv == 0) { + /* an inverse addrgenmode of zero is unexpected. We need to reserve zero + * to signal "unset". */ + return FALSE; + } + addr_gen_mode_valid = TRUE; + } + + if (token_valid) { + *out_token_valid = token_valid; + nm_utils_ipv6_interface_identifier_get_from_addr(out_token, &i6_token); + } + if (addr_gen_mode_valid) { + *out_addr_gen_mode_valid = addr_gen_mode_valid; + *out_addr_gen_mode_inv = i6_addr_gen_mode_inv; + } + return TRUE; +} + +/*****************************************************************************/ + +static NMPObject * +_parse_lnk_bridge(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_BR_FORWARD_DELAY] = {.type = NLA_U32}, + [IFLA_BR_HELLO_TIME] = {.type = NLA_U32}, + [IFLA_BR_MAX_AGE] = {.type = NLA_U32}, + [IFLA_BR_AGEING_TIME] = {.type = NLA_U32}, + [IFLA_BR_STP_STATE] = {.type = NLA_U32}, + [IFLA_BR_PRIORITY] = {.type = NLA_U16}, + [IFLA_BR_VLAN_PROTOCOL] = {.type = NLA_U16}, + [IFLA_BR_VLAN_STATS_ENABLED] = {.type = NLA_U8}, + [IFLA_BR_GROUP_FWD_MASK] = {.type = NLA_U16}, + [IFLA_BR_GROUP_ADDR] = {.minlen = sizeof(NMEtherAddr)}, + [IFLA_BR_MCAST_SNOOPING] = {.type = NLA_U8}, + [IFLA_BR_MCAST_ROUTER] = {.type = NLA_U8}, + [IFLA_BR_MCAST_QUERY_USE_IFADDR] = {.type = NLA_U8}, + [IFLA_BR_MCAST_QUERIER] = {.type = NLA_U8}, + [IFLA_BR_MCAST_HASH_MAX] = {.type = NLA_U32}, + [IFLA_BR_MCAST_LAST_MEMBER_CNT] = {.type = NLA_U32}, + [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = {.type = NLA_U32}, + [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = {.type = NLA_U64}, + [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = {.type = NLA_U64}, + [IFLA_BR_MCAST_QUERIER_INTVL] = {.type = NLA_U64}, + [IFLA_BR_MCAST_QUERY_INTVL] = {.type = NLA_U64}, + [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = {.type = NLA_U64}, + [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = {.type = NLA_U64}, + }; + NMPlatformLnkBridge *props; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + + if (!info_data || !nm_streq0(kind, "bridge")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_BRIDGE, NULL); + + props = &obj->lnk_bridge; + *props = nm_platform_lnk_bridge_default; + + if (!_nm_platform_kernel_support_detected( + NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED)) { + /* IFLA_BR_VLAN_STATS_ENABLED was added in kernel 4.10 on April 30, 2016. + * See commit 6dada9b10a0818ba72c249526a742c8c41274a73. */ + _nm_platform_kernel_support_init(NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED, + tb[IFLA_BR_VLAN_STATS_ENABLED] ? 1 : -1); + } + + if (tb[IFLA_BR_FORWARD_DELAY]) + props->forward_delay = nla_get_u32(tb[IFLA_BR_FORWARD_DELAY]); + if (tb[IFLA_BR_HELLO_TIME]) + props->hello_time = nla_get_u32(tb[IFLA_BR_HELLO_TIME]); + if (tb[IFLA_BR_MAX_AGE]) + props->max_age = nla_get_u32(tb[IFLA_BR_MAX_AGE]); + if (tb[IFLA_BR_AGEING_TIME]) + props->ageing_time = nla_get_u32(tb[IFLA_BR_AGEING_TIME]); + if (tb[IFLA_BR_STP_STATE]) + props->stp_state = !!nla_get_u32(tb[IFLA_BR_STP_STATE]); + if (tb[IFLA_BR_PRIORITY]) + props->priority = nla_get_u16(tb[IFLA_BR_PRIORITY]); + if (tb[IFLA_BR_VLAN_PROTOCOL]) + props->vlan_protocol = ntohs(nla_get_u16(tb[IFLA_BR_VLAN_PROTOCOL])); + if (tb[IFLA_BR_VLAN_STATS_ENABLED]) + props->vlan_stats_enabled = nla_get_u8(tb[IFLA_BR_VLAN_STATS_ENABLED]); + if (tb[IFLA_BR_GROUP_FWD_MASK]) + props->group_fwd_mask = nla_get_u16(tb[IFLA_BR_GROUP_FWD_MASK]); + if (tb[IFLA_BR_GROUP_ADDR]) + props->group_addr = *nla_data_as(NMEtherAddr, tb[IFLA_BR_GROUP_ADDR]); + if (tb[IFLA_BR_MCAST_SNOOPING]) + props->mcast_snooping = !!nla_get_u8(tb[IFLA_BR_MCAST_SNOOPING]); + if (tb[IFLA_BR_MCAST_ROUTER]) + props->mcast_router = nla_get_u8(tb[IFLA_BR_MCAST_ROUTER]); + if (tb[IFLA_BR_MCAST_QUERY_USE_IFADDR]) + props->mcast_query_use_ifaddr = !!nla_get_u8(tb[IFLA_BR_MCAST_QUERY_USE_IFADDR]); + if (tb[IFLA_BR_MCAST_QUERIER]) + props->mcast_querier = nla_get_u8(tb[IFLA_BR_MCAST_QUERIER]); + if (tb[IFLA_BR_MCAST_HASH_MAX]) + props->mcast_hash_max = nla_get_u32(tb[IFLA_BR_MCAST_HASH_MAX]); + if (tb[IFLA_BR_MCAST_LAST_MEMBER_CNT]) + props->mcast_last_member_count = nla_get_u32(tb[IFLA_BR_MCAST_LAST_MEMBER_CNT]); + if (tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT]) + props->mcast_startup_query_count = nla_get_u32(tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT]); + if (tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL]) + props->mcast_last_member_interval = nla_get_u64(tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL]); + if (tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL]) + props->mcast_membership_interval = nla_get_u64(tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL]); + if (tb[IFLA_BR_MCAST_QUERIER_INTVL]) + props->mcast_querier_interval = nla_get_u64(tb[IFLA_BR_MCAST_QUERIER_INTVL]); + if (tb[IFLA_BR_MCAST_QUERY_INTVL]) + props->mcast_query_interval = nla_get_u64(tb[IFLA_BR_MCAST_QUERY_INTVL]); + if (tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]) + props->mcast_query_response_interval = nla_get_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]); + if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]) + props->mcast_startup_query_interval = nla_get_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]); + + return obj; +} + +/***********************************************************************************/ + +static NMPObject * +_parse_lnk_gre(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_GRE_LINK] = {.type = NLA_U32}, + [IFLA_GRE_IFLAGS] = {.type = NLA_U16}, + [IFLA_GRE_OFLAGS] = {.type = NLA_U16}, + [IFLA_GRE_IKEY] = {.type = NLA_U32}, + [IFLA_GRE_OKEY] = {.type = NLA_U32}, + [IFLA_GRE_LOCAL] = {.type = NLA_U32}, + [IFLA_GRE_REMOTE] = {.type = NLA_U32}, + [IFLA_GRE_TTL] = {.type = NLA_U8}, + [IFLA_GRE_TOS] = {.type = NLA_U8}, + [IFLA_GRE_PMTUDISC] = {.type = NLA_U8}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + NMPlatformLnkGre *props; + gboolean is_tap; + + if (!info_data || !kind) + return NULL; + + if (nm_streq(kind, "gretap")) + is_tap = TRUE; + else if (nm_streq(kind, "gre")) + is_tap = FALSE; + else + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + obj = nmp_object_new(is_tap ? NMP_OBJECT_TYPE_LNK_GRETAP : NMP_OBJECT_TYPE_LNK_GRE, NULL); + props = &obj->lnk_gre; + + props->parent_ifindex = tb[IFLA_GRE_LINK] ? nla_get_u32(tb[IFLA_GRE_LINK]) : 0; + props->input_flags = tb[IFLA_GRE_IFLAGS] ? ntohs(nla_get_u16(tb[IFLA_GRE_IFLAGS])) : 0; + props->output_flags = tb[IFLA_GRE_OFLAGS] ? ntohs(nla_get_u16(tb[IFLA_GRE_OFLAGS])) : 0; + props->input_key = tb[IFLA_GRE_IKEY] ? ntohl(nla_get_u32(tb[IFLA_GRE_IKEY])) : 0; + props->output_key = tb[IFLA_GRE_OKEY] ? ntohl(nla_get_u32(tb[IFLA_GRE_OKEY])) : 0; + props->local = tb[IFLA_GRE_LOCAL] ? nla_get_u32(tb[IFLA_GRE_LOCAL]) : 0; + props->remote = tb[IFLA_GRE_REMOTE] ? nla_get_u32(tb[IFLA_GRE_REMOTE]) : 0; + props->tos = tb[IFLA_GRE_TOS] ? nla_get_u8(tb[IFLA_GRE_TOS]) : 0; + props->ttl = tb[IFLA_GRE_TTL] ? nla_get_u8(tb[IFLA_GRE_TTL]) : 0; + props->path_mtu_discovery = !tb[IFLA_GRE_PMTUDISC] || !!nla_get_u8(tb[IFLA_GRE_PMTUDISC]); + props->is_tap = is_tap; + + return obj; +} + +/*****************************************************************************/ + +/* IFLA_IPOIB_* were introduced in the 3.7 kernel, but the kernel headers + * we're building against might not have those properties even though the + * running kernel might. + */ +#define IFLA_IPOIB_UNSPEC 0 +#define IFLA_IPOIB_PKEY 1 +#define IFLA_IPOIB_MODE 2 +#define IFLA_IPOIB_UMCAST 3 +#undef IFLA_IPOIB_MAX +#define IFLA_IPOIB_MAX IFLA_IPOIB_UMCAST + +#define IPOIB_MODE_DATAGRAM 0 /* using unreliable datagram QPs */ +#define IPOIB_MODE_CONNECTED 1 /* using connected QPs */ + +static NMPObject * +_parse_lnk_infiniband(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_IPOIB_PKEY] = {.type = NLA_U16}, + [IFLA_IPOIB_MODE] = {.type = NLA_U16}, + [IFLA_IPOIB_UMCAST] = {.type = NLA_U16}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPlatformLnkInfiniband *info; + NMPObject * obj; + const char * mode; + + if (!info_data || !nm_streq0(kind, "ipoib")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + if (!tb[IFLA_IPOIB_PKEY] || !tb[IFLA_IPOIB_MODE]) + return NULL; + + switch (nla_get_u16(tb[IFLA_IPOIB_MODE])) { + case IPOIB_MODE_DATAGRAM: + mode = "datagram"; + break; + case IPOIB_MODE_CONNECTED: + mode = "connected"; + break; + default: + return NULL; + } + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_INFINIBAND, NULL); + info = &obj->lnk_infiniband; + + info->p_key = nla_get_u16(tb[IFLA_IPOIB_PKEY]); + info->mode = mode; + + return obj; +} + +/*****************************************************************************/ + +static NMPObject * +_parse_lnk_ip6tnl(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_IPTUN_LINK] = {.type = NLA_U32}, + [IFLA_IPTUN_LOCAL] = {.minlen = sizeof(struct in6_addr)}, + [IFLA_IPTUN_REMOTE] = {.minlen = sizeof(struct in6_addr)}, + [IFLA_IPTUN_TTL] = {.type = NLA_U8}, + [IFLA_IPTUN_ENCAP_LIMIT] = {.type = NLA_U8}, + [IFLA_IPTUN_FLOWINFO] = {.type = NLA_U32}, + [IFLA_IPTUN_PROTO] = {.type = NLA_U8}, + [IFLA_IPTUN_FLAGS] = {.type = NLA_U32}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + NMPlatformLnkIp6Tnl *props; + guint32 flowinfo; + + if (!info_data || !nm_streq0(kind, "ip6tnl")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_IP6TNL, NULL); + props = &obj->lnk_ip6tnl; + + if (tb[IFLA_IPTUN_LINK]) + props->parent_ifindex = nla_get_u32(tb[IFLA_IPTUN_LINK]); + if (tb[IFLA_IPTUN_LOCAL]) + props->local = *nla_data_as(struct in6_addr, tb[IFLA_IPTUN_LOCAL]); + if (tb[IFLA_IPTUN_REMOTE]) + props->remote = *nla_data_as(struct in6_addr, tb[IFLA_IPTUN_REMOTE]); + if (tb[IFLA_IPTUN_TTL]) + props->ttl = nla_get_u8(tb[IFLA_IPTUN_TTL]); + if (tb[IFLA_IPTUN_ENCAP_LIMIT]) + props->encap_limit = nla_get_u8(tb[IFLA_IPTUN_ENCAP_LIMIT]); + if (tb[IFLA_IPTUN_FLOWINFO]) { + flowinfo = ntohl(nla_get_u32(tb[IFLA_IPTUN_FLOWINFO])); + props->flow_label = flowinfo & IP6_FLOWINFO_FLOWLABEL_MASK; + props->tclass = (flowinfo & IP6_FLOWINFO_TCLASS_MASK) >> IP6_FLOWINFO_TCLASS_SHIFT; + } + if (tb[IFLA_IPTUN_PROTO]) + props->proto = nla_get_u8(tb[IFLA_IPTUN_PROTO]); + if (tb[IFLA_IPTUN_FLAGS]) + props->flags = nla_get_u32(tb[IFLA_IPTUN_FLAGS]); + + return obj; +} + +static NMPObject * +_parse_lnk_ip6gre(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_GRE_LINK] = {.type = NLA_U32}, + [IFLA_GRE_IFLAGS] = {.type = NLA_U16}, + [IFLA_GRE_OFLAGS] = {.type = NLA_U16}, + [IFLA_GRE_IKEY] = {.type = NLA_U32}, + [IFLA_GRE_OKEY] = {.type = NLA_U32}, + [IFLA_GRE_LOCAL] = {.type = NLA_UNSPEC, .minlen = sizeof(struct in6_addr)}, + [IFLA_GRE_REMOTE] = {.type = NLA_UNSPEC, .minlen = sizeof(struct in6_addr)}, + [IFLA_GRE_TTL] = {.type = NLA_U8}, + [IFLA_GRE_ENCAP_LIMIT] = {.type = NLA_U8}, + [IFLA_GRE_FLOWINFO] = {.type = NLA_U32}, + [IFLA_GRE_FLAGS] = {.type = NLA_U32}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + NMPlatformLnkIp6Tnl *props; + guint32 flowinfo; + gboolean is_tap; + + if (!info_data || !kind) + return NULL; + + if (nm_streq(kind, "ip6gre")) + is_tap = FALSE; + else if (nm_streq(kind, "ip6gretap")) + is_tap = TRUE; + else + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + obj = nmp_object_new(is_tap ? NMP_OBJECT_TYPE_LNK_IP6GRETAP : NMP_OBJECT_TYPE_LNK_IP6GRE, NULL); + props = &obj->lnk_ip6tnl; + props->is_gre = TRUE; + props->is_tap = is_tap; + + if (tb[IFLA_GRE_LINK]) + props->parent_ifindex = nla_get_u32(tb[IFLA_GRE_LINK]); + if (tb[IFLA_GRE_IFLAGS]) + props->input_flags = ntohs(nla_get_u16(tb[IFLA_GRE_IFLAGS])); + if (tb[IFLA_GRE_OFLAGS]) + props->output_flags = ntohs(nla_get_u16(tb[IFLA_GRE_OFLAGS])); + if (tb[IFLA_GRE_IKEY]) + props->input_key = ntohl(nla_get_u32(tb[IFLA_GRE_IKEY])); + if (tb[IFLA_GRE_OKEY]) + props->output_key = ntohl(nla_get_u32(tb[IFLA_GRE_OKEY])); + if (tb[IFLA_GRE_LOCAL]) + props->local = *nla_data_as(struct in6_addr, tb[IFLA_GRE_LOCAL]); + if (tb[IFLA_GRE_REMOTE]) + props->remote = *nla_data_as(struct in6_addr, tb[IFLA_GRE_REMOTE]); + if (tb[IFLA_GRE_TTL]) + props->ttl = nla_get_u8(tb[IFLA_GRE_TTL]); + if (tb[IFLA_GRE_ENCAP_LIMIT]) + props->encap_limit = nla_get_u8(tb[IFLA_GRE_ENCAP_LIMIT]); + if (tb[IFLA_GRE_FLOWINFO]) { + flowinfo = ntohl(nla_get_u32(tb[IFLA_GRE_FLOWINFO])); + props->flow_label = flowinfo & IP6_FLOWINFO_FLOWLABEL_MASK; + props->tclass = (flowinfo & IP6_FLOWINFO_TCLASS_MASK) >> IP6_FLOWINFO_TCLASS_SHIFT; + } + if (tb[IFLA_GRE_FLAGS]) + props->flags = nla_get_u32(tb[IFLA_GRE_FLAGS]); + + return obj; +} + +/*****************************************************************************/ + +static NMPObject * +_parse_lnk_ipip(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_IPTUN_LINK] = {.type = NLA_U32}, + [IFLA_IPTUN_LOCAL] = {.type = NLA_U32}, + [IFLA_IPTUN_REMOTE] = {.type = NLA_U32}, + [IFLA_IPTUN_TTL] = {.type = NLA_U8}, + [IFLA_IPTUN_TOS] = {.type = NLA_U8}, + [IFLA_IPTUN_PMTUDISC] = {.type = NLA_U8}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + NMPlatformLnkIpIp *props; + + if (!info_data || !nm_streq0(kind, "ipip")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_IPIP, NULL); + props = &obj->lnk_ipip; + + props->parent_ifindex = tb[IFLA_IPTUN_LINK] ? nla_get_u32(tb[IFLA_IPTUN_LINK]) : 0; + props->local = tb[IFLA_IPTUN_LOCAL] ? nla_get_u32(tb[IFLA_IPTUN_LOCAL]) : 0; + props->remote = tb[IFLA_IPTUN_REMOTE] ? nla_get_u32(tb[IFLA_IPTUN_REMOTE]) : 0; + props->tos = tb[IFLA_IPTUN_TOS] ? nla_get_u8(tb[IFLA_IPTUN_TOS]) : 0; + props->ttl = tb[IFLA_IPTUN_TTL] ? nla_get_u8(tb[IFLA_IPTUN_TTL]) : 0; + props->path_mtu_discovery = !tb[IFLA_IPTUN_PMTUDISC] || !!nla_get_u8(tb[IFLA_IPTUN_PMTUDISC]); + + return obj; +} + +/*****************************************************************************/ + +static NMPObject * +_parse_lnk_macvlan(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_MACVLAN_MODE] = {.type = NLA_U32}, + [IFLA_MACVLAN_FLAGS] = {.type = NLA_U16}, + }; + NMPlatformLnkMacvlan *props; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + gboolean tap; + + if (!info_data || !kind) + return NULL; + + if (nm_streq(kind, "macvlan")) + tap = FALSE; + else if (nm_streq(kind, "macvtap")) + tap = TRUE; + else + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + if (!tb[IFLA_MACVLAN_MODE]) + return NULL; + + obj = nmp_object_new(tap ? NMP_OBJECT_TYPE_LNK_MACVTAP : NMP_OBJECT_TYPE_LNK_MACVLAN, NULL); + props = &obj->lnk_macvlan; + props->mode = nla_get_u32(tb[IFLA_MACVLAN_MODE]); + props->tap = tap; + + if (tb[IFLA_MACVLAN_FLAGS]) + props->no_promisc = + NM_FLAGS_HAS(nla_get_u16(tb[IFLA_MACVLAN_FLAGS]), MACVLAN_FLAG_NOPROMISC); + + return obj; +} + +/*****************************************************************************/ + +static NMPObject * +_parse_lnk_macsec(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_MACSEC_SCI] = {.type = NLA_U64}, + [IFLA_MACSEC_ICV_LEN] = {.type = NLA_U8}, + [IFLA_MACSEC_CIPHER_SUITE] = {.type = NLA_U64}, + [IFLA_MACSEC_WINDOW] = {.type = NLA_U32}, + [IFLA_MACSEC_ENCODING_SA] = {.type = NLA_U8}, + [IFLA_MACSEC_ENCRYPT] = {.type = NLA_U8}, + [IFLA_MACSEC_PROTECT] = {.type = NLA_U8}, + [IFLA_MACSEC_INC_SCI] = {.type = NLA_U8}, + [IFLA_MACSEC_ES] = {.type = NLA_U8}, + [IFLA_MACSEC_SCB] = {.type = NLA_U8}, + [IFLA_MACSEC_REPLAY_PROTECT] = {.type = NLA_U8}, + [IFLA_MACSEC_VALIDATION] = {.type = NLA_U8}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + NMPlatformLnkMacsec *props; + + if (!info_data || !nm_streq0(kind, "macsec")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_MACSEC, NULL); + props = &obj->lnk_macsec; + + if (tb[IFLA_MACSEC_SCI]) { + props->sci = nla_get_be64(tb[IFLA_MACSEC_SCI]); + } + if (tb[IFLA_MACSEC_ICV_LEN]) { + props->icv_length = nla_get_u8(tb[IFLA_MACSEC_ICV_LEN]); + } + if (tb[IFLA_MACSEC_CIPHER_SUITE]) { + props->cipher_suite = nla_get_u64(tb[IFLA_MACSEC_CIPHER_SUITE]); + } + if (tb[IFLA_MACSEC_WINDOW]) { + props->window = nla_get_u32(tb[IFLA_MACSEC_WINDOW]); + } + if (tb[IFLA_MACSEC_ENCODING_SA]) { + props->encoding_sa = !!nla_get_u8(tb[IFLA_MACSEC_ENCODING_SA]); + } + if (tb[IFLA_MACSEC_ENCRYPT]) { + props->encrypt = !!nla_get_u8(tb[IFLA_MACSEC_ENCRYPT]); + } + if (tb[IFLA_MACSEC_PROTECT]) { + props->protect = !!nla_get_u8(tb[IFLA_MACSEC_PROTECT]); + } + if (tb[IFLA_MACSEC_INC_SCI]) { + props->include_sci = !!nla_get_u8(tb[IFLA_MACSEC_INC_SCI]); + } + if (tb[IFLA_MACSEC_ES]) { + props->es = !!nla_get_u8(tb[IFLA_MACSEC_ES]); + } + if (tb[IFLA_MACSEC_SCB]) { + props->scb = !!nla_get_u8(tb[IFLA_MACSEC_SCB]); + } + if (tb[IFLA_MACSEC_REPLAY_PROTECT]) { + props->replay_protect = !!nla_get_u8(tb[IFLA_MACSEC_REPLAY_PROTECT]); + } + if (tb[IFLA_MACSEC_VALIDATION]) { + props->validation = nla_get_u8(tb[IFLA_MACSEC_VALIDATION]); + } + + return obj; +} + +/*****************************************************************************/ + +static NMPObject * +_parse_lnk_sit(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_IPTUN_LINK] = {.type = NLA_U32}, + [IFLA_IPTUN_LOCAL] = {.type = NLA_U32}, + [IFLA_IPTUN_REMOTE] = {.type = NLA_U32}, + [IFLA_IPTUN_TTL] = {.type = NLA_U8}, + [IFLA_IPTUN_TOS] = {.type = NLA_U8}, + [IFLA_IPTUN_PMTUDISC] = {.type = NLA_U8}, + [IFLA_IPTUN_FLAGS] = {.type = NLA_U16}, + [IFLA_IPTUN_PROTO] = {.type = NLA_U8}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + NMPlatformLnkSit *props; + + if (!info_data || !nm_streq0(kind, "sit")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_SIT, NULL); + props = &obj->lnk_sit; + + props->parent_ifindex = tb[IFLA_IPTUN_LINK] ? nla_get_u32(tb[IFLA_IPTUN_LINK]) : 0; + props->local = tb[IFLA_IPTUN_LOCAL] ? nla_get_u32(tb[IFLA_IPTUN_LOCAL]) : 0; + props->remote = tb[IFLA_IPTUN_REMOTE] ? nla_get_u32(tb[IFLA_IPTUN_REMOTE]) : 0; + props->tos = tb[IFLA_IPTUN_TOS] ? nla_get_u8(tb[IFLA_IPTUN_TOS]) : 0; + props->ttl = tb[IFLA_IPTUN_TTL] ? nla_get_u8(tb[IFLA_IPTUN_TTL]) : 0; + props->path_mtu_discovery = !tb[IFLA_IPTUN_PMTUDISC] || !!nla_get_u8(tb[IFLA_IPTUN_PMTUDISC]); + props->flags = tb[IFLA_IPTUN_FLAGS] ? nla_get_u16(tb[IFLA_IPTUN_FLAGS]) : 0; + props->proto = tb[IFLA_IPTUN_PROTO] ? nla_get_u8(tb[IFLA_IPTUN_PROTO]) : 0; + + return obj; +} + +/*****************************************************************************/ + +static NMPObject * +_parse_lnk_tun(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_TUN_OWNER] = {.type = NLA_U32}, + [IFLA_TUN_GROUP] = {.type = NLA_U32}, + [IFLA_TUN_TYPE] = {.type = NLA_U8}, + [IFLA_TUN_PI] = {.type = NLA_U8}, + [IFLA_TUN_VNET_HDR] = {.type = NLA_U8}, + [IFLA_TUN_PERSIST] = {.type = NLA_U8}, + [IFLA_TUN_MULTI_QUEUE] = {.type = NLA_U8}, + [IFLA_TUN_NUM_QUEUES] = {.type = NLA_U32}, + [IFLA_TUN_NUM_DISABLED_QUEUES] = {.type = NLA_U32}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + NMPlatformLnkTun *props; + + if (!info_data || !nm_streq0(kind, "tun")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + if (!tb[IFLA_TUN_TYPE]) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_TUN, NULL); + props = &obj->lnk_tun; + + props->type = nla_get_u8(tb[IFLA_TUN_TYPE]); + + props->pi = !!nla_get_u8_cond(tb, IFLA_TUN_PI, FALSE); + props->vnet_hdr = !!nla_get_u8_cond(tb, IFLA_TUN_VNET_HDR, FALSE); + props->multi_queue = !!nla_get_u8_cond(tb, IFLA_TUN_MULTI_QUEUE, FALSE); + props->persist = !!nla_get_u8_cond(tb, IFLA_TUN_PERSIST, FALSE); + + if (tb[IFLA_TUN_OWNER]) { + props->owner_valid = TRUE; + props->owner = nla_get_u32(tb[IFLA_TUN_OWNER]); + } + if (tb[IFLA_TUN_GROUP]) { + props->group_valid = TRUE; + props->group = nla_get_u32(tb[IFLA_TUN_GROUP]); + } + return obj; +} + +/*****************************************************************************/ + +static gboolean +_vlan_qos_mapping_from_nla(struct nlattr * nlattr, + const NMVlanQosMapping **out_map, + guint * out_n_map) +{ + struct nlattr * nla; + int remaining; + gs_unref_ptrarray GPtrArray *array = NULL; + + G_STATIC_ASSERT(sizeof(NMVlanQosMapping) == sizeof(struct ifla_vlan_qos_mapping)); + G_STATIC_ASSERT(sizeof(((NMVlanQosMapping *) 0)->to) + == sizeof(((struct ifla_vlan_qos_mapping *) 0)->to)); + G_STATIC_ASSERT(sizeof(((NMVlanQosMapping *) 0)->from) + == sizeof(((struct ifla_vlan_qos_mapping *) 0)->from)); + G_STATIC_ASSERT(sizeof(NMVlanQosMapping) + == sizeof(((NMVlanQosMapping *) 0)->from) + + sizeof(((NMVlanQosMapping *) 0)->to)); + + nm_assert(out_map && !*out_map); + nm_assert(out_n_map && !*out_n_map); + + if (!nlattr) + return TRUE; + + array = g_ptr_array_new(); + nla_for_each_nested (nla, nlattr, remaining) { + if (nla_len(nla) < sizeof(NMVlanQosMapping)) + return FALSE; + g_ptr_array_add(array, nla_data(nla)); + } + + if (array->len > 0) { + NMVlanQosMapping *list; + guint i, j; + + /* The sorting is necessary, because for egress mapping, kernel + * doesn't sent the items strictly sorted by the from field. */ + g_ptr_array_sort_with_data(array, _vlan_qos_mapping_cmp_from_ptr, NULL); + + list = g_new(NMVlanQosMapping, array->len); + + for (i = 0, j = 0; i < array->len; i++) { + NMVlanQosMapping *map; + + map = array->pdata[i]; + + /* kernel doesn't really send us duplicates. Just be extra cautious + * because we want strong guarantees about the sort order and uniqueness + * of our mapping list (for simpler equality comparison). */ + if (j > 0 && list[j - 1].from == map->from) + list[j - 1] = *map; + else + list[j++] = *map; + } + + *out_n_map = j; + *out_map = list; + } + + return TRUE; +} + +/* Copied and heavily modified from libnl3's vlan_parse() */ +static NMPObject * +_parse_lnk_vlan(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_VLAN_ID] = {.type = NLA_U16}, + [IFLA_VLAN_FLAGS] = {.minlen = nm_offsetofend(struct ifla_vlan_flags, flags)}, + [IFLA_VLAN_INGRESS_QOS] = {.type = NLA_NESTED}, + [IFLA_VLAN_EGRESS_QOS] = {.type = NLA_NESTED}, + [IFLA_VLAN_PROTOCOL] = {.type = NLA_U16}, + }; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + nm_auto_nmpobj NMPObject *obj = NULL; + NMPObject * obj_result; + + if (!info_data || !nm_streq0(kind, "vlan")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + if (!tb[IFLA_VLAN_ID]) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_VLAN, NULL); + obj->lnk_vlan.id = nla_get_u16(tb[IFLA_VLAN_ID]); + + if (tb[IFLA_VLAN_FLAGS]) { + struct ifla_vlan_flags flags; + + nla_memcpy(&flags, tb[IFLA_VLAN_FLAGS], sizeof(flags)); + + obj->lnk_vlan.flags = flags.flags; + } + + if (!_vlan_qos_mapping_from_nla(tb[IFLA_VLAN_INGRESS_QOS], + &obj->_lnk_vlan.ingress_qos_map, + &obj->_lnk_vlan.n_ingress_qos_map)) + return NULL; + + if (!_vlan_qos_mapping_from_nla(tb[IFLA_VLAN_EGRESS_QOS], + &obj->_lnk_vlan.egress_qos_map, + &obj->_lnk_vlan.n_egress_qos_map)) + return NULL; + + obj_result = obj; + obj = NULL; + return obj_result; +} + +/*****************************************************************************/ + +/* The installed kernel headers might not have VXLAN stuff at all, or + * they might have the original properties, but not PORT, GROUP6, or LOCAL6. + * So until we depend on kernel >= 3.11, we just ignore the actual enum + * in if_link.h and define the values ourselves. + */ +#define IFLA_VXLAN_UNSPEC 0 +#define IFLA_VXLAN_ID 1 +#define IFLA_VXLAN_GROUP 2 +#define IFLA_VXLAN_LINK 3 +#define IFLA_VXLAN_LOCAL 4 +#define IFLA_VXLAN_TTL 5 +#define IFLA_VXLAN_TOS 6 +#define IFLA_VXLAN_LEARNING 7 +#define IFLA_VXLAN_AGEING 8 +#define IFLA_VXLAN_LIMIT 9 +#define IFLA_VXLAN_PORT_RANGE 10 +#define IFLA_VXLAN_PROXY 11 +#define IFLA_VXLAN_RSC 12 +#define IFLA_VXLAN_L2MISS 13 +#define IFLA_VXLAN_L3MISS 14 +#define IFLA_VXLAN_PORT 15 +#define IFLA_VXLAN_GROUP6 16 +#define IFLA_VXLAN_LOCAL6 17 +#undef IFLA_VXLAN_MAX +#define IFLA_VXLAN_MAX IFLA_VXLAN_LOCAL6 + +#define IFLA_VRF_TABLE 1 + +/* older kernel header might not contain 'struct ifla_vxlan_port_range'. + * Redefine it. */ +struct nm_ifla_vxlan_port_range { + guint16 low; + guint16 high; +}; + +static NMPObject * +_parse_lnk_vxlan(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_VXLAN_ID] = {.type = NLA_U32}, + [IFLA_VXLAN_GROUP] = {.type = NLA_U32}, + [IFLA_VXLAN_GROUP6] = {.type = NLA_UNSPEC, .minlen = sizeof(struct in6_addr)}, + [IFLA_VXLAN_LINK] = {.type = NLA_U32}, + [IFLA_VXLAN_LOCAL] = {.type = NLA_U32}, + [IFLA_VXLAN_LOCAL6] = {.type = NLA_UNSPEC, .minlen = sizeof(struct in6_addr)}, + [IFLA_VXLAN_TOS] = {.type = NLA_U8}, + [IFLA_VXLAN_TTL] = {.type = NLA_U8}, + [IFLA_VXLAN_LEARNING] = {.type = NLA_U8}, + [IFLA_VXLAN_AGEING] = {.type = NLA_U32}, + [IFLA_VXLAN_LIMIT] = {.type = NLA_U32}, + [IFLA_VXLAN_PORT_RANGE] = {.type = NLA_UNSPEC, + .minlen = sizeof(struct nm_ifla_vxlan_port_range)}, + [IFLA_VXLAN_PROXY] = {.type = NLA_U8}, + [IFLA_VXLAN_RSC] = {.type = NLA_U8}, + [IFLA_VXLAN_L2MISS] = {.type = NLA_U8}, + [IFLA_VXLAN_L3MISS] = {.type = NLA_U8}, + [IFLA_VXLAN_PORT] = {.type = NLA_U16}, + }; + NMPlatformLnkVxlan *props; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + + if (!info_data || !nm_streq0(kind, "vxlan")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_VXLAN, NULL); + + props = &obj->lnk_vxlan; + + if (tb[IFLA_VXLAN_LINK]) + props->parent_ifindex = nla_get_u32(tb[IFLA_VXLAN_LINK]); + if (tb[IFLA_VXLAN_ID]) + props->id = nla_get_u32(tb[IFLA_VXLAN_ID]); + if (tb[IFLA_VXLAN_GROUP]) + props->group = nla_get_u32(tb[IFLA_VXLAN_GROUP]); + if (tb[IFLA_VXLAN_LOCAL]) + props->local = nla_get_u32(tb[IFLA_VXLAN_LOCAL]); + if (tb[IFLA_VXLAN_LOCAL6]) + props->local6 = *nla_data_as(struct in6_addr, tb[IFLA_VXLAN_LOCAL6]); + if (tb[IFLA_VXLAN_GROUP6]) + props->group6 = *nla_data_as(struct in6_addr, tb[IFLA_VXLAN_GROUP6]); + + if (tb[IFLA_VXLAN_AGEING]) + props->ageing = nla_get_u32(tb[IFLA_VXLAN_AGEING]); + if (tb[IFLA_VXLAN_LIMIT]) + props->limit = nla_get_u32(tb[IFLA_VXLAN_LIMIT]); + if (tb[IFLA_VXLAN_TOS]) + props->tos = nla_get_u8(tb[IFLA_VXLAN_TOS]); + if (tb[IFLA_VXLAN_TTL]) + props->ttl = nla_get_u8(tb[IFLA_VXLAN_TTL]); + + if (tb[IFLA_VXLAN_PORT]) + props->dst_port = ntohs(nla_get_u16(tb[IFLA_VXLAN_PORT])); + + if (tb[IFLA_VXLAN_PORT_RANGE]) { + struct nm_ifla_vxlan_port_range *range; + + range = nla_data_as(struct nm_ifla_vxlan_port_range, tb[IFLA_VXLAN_PORT_RANGE]); + props->src_port_min = ntohs(range->low); + props->src_port_max = ntohs(range->high); + } + + if (tb[IFLA_VXLAN_LEARNING]) + props->learning = !!nla_get_u8(tb[IFLA_VXLAN_LEARNING]); + if (tb[IFLA_VXLAN_PROXY]) + props->proxy = !!nla_get_u8(tb[IFLA_VXLAN_PROXY]); + if (tb[IFLA_VXLAN_RSC]) + props->rsc = !!nla_get_u8(tb[IFLA_VXLAN_RSC]); + if (tb[IFLA_VXLAN_L2MISS]) + props->l2miss = !!nla_get_u8(tb[IFLA_VXLAN_L2MISS]); + if (tb[IFLA_VXLAN_L3MISS]) + props->l3miss = !!nla_get_u8(tb[IFLA_VXLAN_L3MISS]); + + return obj; +} + +static NMPObject * +_parse_lnk_vrf(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_VRF_TABLE] = {.type = NLA_U32}, + }; + NMPlatformLnkVrf *props; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj; + + if (!info_data || !nm_streq0(kind, "vrf")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_VRF, NULL); + + props = &obj->lnk_vrf; + + if (tb[IFLA_VRF_TABLE]) + props->table = nla_get_u32(tb[IFLA_VRF_TABLE]); + + return obj; +} + +/*****************************************************************************/ + +static gboolean +_wireguard_update_from_allowed_ips_nla(NMPWireGuardAllowedIP *allowed_ip, struct nlattr *nlattr) +{ + static const struct nla_policy policy[] = { + [WGALLOWEDIP_A_FAMILY] = {.type = NLA_U16}, + [WGALLOWEDIP_A_IPADDR] = {.minlen = sizeof(struct in_addr)}, + [WGALLOWEDIP_A_CIDR_MASK] = {.type = NLA_U8}, + }; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + int family; + int addr_len; + + if (nla_parse_nested_arr(tb, nlattr, policy) < 0) + return FALSE; + + if (!tb[WGALLOWEDIP_A_FAMILY]) + return FALSE; + + family = nla_get_u16(tb[WGALLOWEDIP_A_FAMILY]); + if (family == AF_INET) + addr_len = sizeof(in_addr_t); + else if (family == AF_INET6) + addr_len = sizeof(struct in6_addr); + else + return FALSE; + + _check_addr_or_return_val(tb, WGALLOWEDIP_A_IPADDR, addr_len, FALSE); + + *allowed_ip = (NMPWireGuardAllowedIP){ + .family = family, + }; + + nm_assert((int) allowed_ip->family == family); + + if (tb[WGALLOWEDIP_A_IPADDR]) + nla_memcpy(&allowed_ip->addr, tb[WGALLOWEDIP_A_IPADDR], addr_len); + if (tb[WGALLOWEDIP_A_CIDR_MASK]) + allowed_ip->mask = nla_get_u8(tb[WGALLOWEDIP_A_CIDR_MASK]); + + return TRUE; +} + +typedef struct { + CList lst; + NMPWireGuardPeer data; +} WireGuardPeerConstruct; + +static gboolean +_wireguard_update_from_peers_nla(CList *peers, GArray **p_allowed_ips, struct nlattr *peer_attr) +{ + static const struct nla_policy policy[] = { + [WGPEER_A_PUBLIC_KEY] = {.minlen = NMP_WIREGUARD_PUBLIC_KEY_LEN}, + [WGPEER_A_PRESHARED_KEY] = {}, + [WGPEER_A_FLAGS] = {.type = NLA_U32}, + [WGPEER_A_ENDPOINT] = {}, + [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = {.type = NLA_U16}, + [WGPEER_A_LAST_HANDSHAKE_TIME] = {}, + [WGPEER_A_RX_BYTES] = {.type = NLA_U64}, + [WGPEER_A_TX_BYTES] = {.type = NLA_U64}, + [WGPEER_A_ALLOWEDIPS] = {.type = NLA_NESTED}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + WireGuardPeerConstruct *peer_c; + + if (nla_parse_nested_arr(tb, peer_attr, policy) < 0) + return FALSE; + + if (!tb[WGPEER_A_PUBLIC_KEY]) + return FALSE; + + /* a peer with the same public key as last peer is just a continuation for extra AllowedIPs */ + peer_c = c_list_last_entry(peers, WireGuardPeerConstruct, lst); + if (peer_c + && !memcmp(nla_data(tb[WGPEER_A_PUBLIC_KEY]), + peer_c->data.public_key, + NMP_WIREGUARD_PUBLIC_KEY_LEN)) { + G_STATIC_ASSERT_EXPR(NMP_WIREGUARD_PUBLIC_KEY_LEN == sizeof(peer_c->data.public_key)); + /* this message is a continuation of the previous peer. + * Only parse WGPEER_A_ALLOWEDIPS below. */ + } else { + /* otherwise, start a new peer */ + peer_c = g_slice_new0(WireGuardPeerConstruct); + c_list_link_tail(peers, &peer_c->lst); + + nla_memcpy(&peer_c->data.public_key, + tb[WGPEER_A_PUBLIC_KEY], + sizeof(peer_c->data.public_key)); + + if (tb[WGPEER_A_PRESHARED_KEY]) { + nla_memcpy(&peer_c->data.preshared_key, + tb[WGPEER_A_PRESHARED_KEY], + sizeof(peer_c->data.preshared_key)); + /* FIXME(netlink-bzero-secret) */ + nm_explicit_bzero(nla_data(tb[WGPEER_A_PRESHARED_KEY]), + nla_len(tb[WGPEER_A_PRESHARED_KEY])); + } + + nm_sock_addr_union_cpy_untrusted( + &peer_c->data.endpoint, + tb[WGPEER_A_ENDPOINT] ? nla_data(tb[WGPEER_A_ENDPOINT]) : NULL, + tb[WGPEER_A_ENDPOINT] ? nla_len(tb[WGPEER_A_ENDPOINT]) : 0); + + if (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]) + peer_c->data.persistent_keepalive_interval = + nla_get_u16(tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]); + if (tb[WGPEER_A_LAST_HANDSHAKE_TIME]) { + if (nla_len(tb[WGPEER_A_LAST_HANDSHAKE_TIME]) + >= sizeof(peer_c->data.last_handshake_time)) + nla_memcpy(&peer_c->data.last_handshake_time, + tb[WGPEER_A_LAST_HANDSHAKE_TIME], + sizeof(peer_c->data.last_handshake_time)); + } + if (tb[WGPEER_A_RX_BYTES]) + peer_c->data.rx_bytes = nla_get_u64(tb[WGPEER_A_RX_BYTES]); + if (tb[WGPEER_A_TX_BYTES]) + peer_c->data.tx_bytes = nla_get_u64(tb[WGPEER_A_TX_BYTES]); + } + + if (tb[WGPEER_A_ALLOWEDIPS]) { + struct nlattr *attr; + int rem; + GArray * allowed_ips = *p_allowed_ips; + + nla_for_each_nested (attr, tb[WGPEER_A_ALLOWEDIPS], rem) { + if (!allowed_ips) { + allowed_ips = g_array_new(FALSE, FALSE, sizeof(NMPWireGuardAllowedIP)); + *p_allowed_ips = allowed_ips; + g_array_set_size(allowed_ips, 1); + } else + g_array_set_size(allowed_ips, allowed_ips->len + 1); + + if (!_wireguard_update_from_allowed_ips_nla( + &g_array_index(allowed_ips, NMPWireGuardAllowedIP, allowed_ips->len - 1), + attr)) { + /* we ignore the error of parsing one allowed-ip. */ + g_array_set_size(allowed_ips, allowed_ips->len - 1); + continue; + } + + if (!peer_c->data._construct_idx_end) + peer_c->data._construct_idx_start = allowed_ips->len - 1; + peer_c->data._construct_idx_end = allowed_ips->len; + } + } + + return TRUE; +} + +typedef struct { + const int ifindex; + NMPObject *obj; + CList peers; + GArray * allowed_ips; +} WireGuardParseData; + +static int +_wireguard_get_device_cb(struct nl_msg *msg, void *arg) +{ + static const struct nla_policy policy[] = { + [WGDEVICE_A_IFINDEX] = {.type = NLA_U32}, + [WGDEVICE_A_IFNAME] = {.type = NLA_NUL_STRING, .maxlen = IFNAMSIZ}, + [WGDEVICE_A_PRIVATE_KEY] = {}, + [WGDEVICE_A_PUBLIC_KEY] = {}, + [WGDEVICE_A_FLAGS] = {.type = NLA_U32}, + [WGDEVICE_A_LISTEN_PORT] = {.type = NLA_U16}, + [WGDEVICE_A_FWMARK] = {.type = NLA_U32}, + [WGDEVICE_A_PEERS] = {.type = NLA_NESTED}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + WireGuardParseData *parse_data = arg; + + if (genlmsg_parse_arr(nlmsg_hdr(msg), 0, tb, policy) < 0) + return NL_SKIP; + + if (tb[WGDEVICE_A_IFINDEX]) { + int ifindex; + + ifindex = (int) nla_get_u32(tb[WGDEVICE_A_IFINDEX]); + if (ifindex <= 0 || parse_data->ifindex != ifindex) + return NL_SKIP; + } else { + if (!parse_data->obj) + return NL_SKIP; + } + + if (parse_data->obj) { + /* we already have an object instance. This means the netlink message + * is a continuation, only providing more WGDEVICE_A_PEERS data below. */ + } else { + NMPObject * obj; + NMPlatformLnkWireGuard *props; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_WIREGUARD, NULL); + props = &obj->lnk_wireguard; + + if (tb[WGDEVICE_A_PRIVATE_KEY]) { + nla_memcpy(props->private_key, tb[WGDEVICE_A_PRIVATE_KEY], sizeof(props->private_key)); + /* FIXME(netlink-bzero-secret): extend netlink library to wipe memory. For now, + * just hack it here (yes, this does not cover all places where the + * private key was copied). */ + nm_explicit_bzero(nla_data(tb[WGDEVICE_A_PRIVATE_KEY]), + nla_len(tb[WGDEVICE_A_PRIVATE_KEY])); + } + if (tb[WGDEVICE_A_PUBLIC_KEY]) + nla_memcpy(props->public_key, tb[WGDEVICE_A_PUBLIC_KEY], sizeof(props->public_key)); + if (tb[WGDEVICE_A_LISTEN_PORT]) + props->listen_port = nla_get_u16(tb[WGDEVICE_A_LISTEN_PORT]); + if (tb[WGDEVICE_A_FWMARK]) + props->fwmark = nla_get_u32(tb[WGDEVICE_A_FWMARK]); + + parse_data->obj = obj; + } + + if (tb[WGDEVICE_A_PEERS]) { + struct nlattr *attr; + int rem; + + nla_for_each_nested (attr, tb[WGDEVICE_A_PEERS], rem) { + if (!_wireguard_update_from_peers_nla(&parse_data->peers, + &parse_data->allowed_ips, + attr)) { + /* we ignore the error of parsing one peer. + * _wireguard_update_from_peers_nla() leaves the @peers array in the + * desired state. */ + } + } + } + + return NL_OK; +} + +static const NMPObject * +_wireguard_read_info(NMPlatform * platform /* used only as logging context */, + struct nl_sock *genl, + int wireguard_family_id, + int ifindex) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + NMPObject * obj = NULL; + WireGuardPeerConstruct * peer_c; + WireGuardPeerConstruct * peer_c_safe; + gs_unref_array GArray *allowed_ips = NULL; + WireGuardParseData parse_data = { + .ifindex = ifindex, + }; + guint i; + + nm_assert(genl); + nm_assert(wireguard_family_id >= 0); + nm_assert(ifindex > 0); + + _LOGT("wireguard: fetching information for ifindex %d (genl-id %d)...", + ifindex, + wireguard_family_id); + + msg = nlmsg_alloc(); + + if (!genlmsg_put(msg, + NL_AUTO_PORT, + NL_AUTO_SEQ, + wireguard_family_id, + 0, + NLM_F_DUMP, + WG_CMD_GET_DEVICE, + 1)) + return NULL; + + NLA_PUT_U32(msg, WGDEVICE_A_IFINDEX, (guint32) ifindex); + + if (nl_send_auto(genl, msg) < 0) + return NULL; + + c_list_init(&parse_data.peers); + + /* we ignore errors, and return whatever we could successfully + * parse. */ + nl_recvmsgs(genl, + &((const struct nl_cb){ + .valid_cb = _wireguard_get_device_cb, + .valid_arg = (gpointer) &parse_data, + })); + + /* unpack: transfer ownership */ + obj = parse_data.obj; + allowed_ips = parse_data.allowed_ips; + + if (!obj) { + while ((peer_c = c_list_first_entry(&parse_data.peers, WireGuardPeerConstruct, lst))) { + c_list_unlink_stale(&peer_c->lst); + nm_explicit_bzero(&peer_c->data.preshared_key, sizeof(peer_c->data.preshared_key)); + g_slice_free(WireGuardPeerConstruct, peer_c); + } + return NULL; + } + + /* we receive peers/allowed-ips possibly in separate netlink messages. Hence, while + * parsing the dump, we don't know upfront how many peers/allowed-ips we will receive. + * + * We solve that, by collecting all peers with a CList. It's done this way, + * because a GArray would require growing the array, but we want to bzero() + * the preshared-key of each peer while reallocating. The CList apprach avoids + * that. + * + * For allowed-ips, we instead track one GArray, which are all appended + * there. The realloc/resize of the GArray is fine there. However, + * while we build the GArray, we don't yet have the final pointers. + * Hence, while constructing, we track the indexes with peer->_construct_idx_* + * fields. These indexes must be converted to actual pointers blow. + * + * This is all done during parsing. In the final NMPObjectLnkWireGuard we + * don't want the CList anymore and repackage the NMPObject tightly. The + * reason is, that NMPObject instances are immutable and long-living. Spend + * a bit effort below during construction to obtain a most suitable representation + * in this regard. */ + obj->_lnk_wireguard.peers_len = c_list_length(&parse_data.peers); + obj->_lnk_wireguard.peers = obj->_lnk_wireguard.peers_len > 0 + ? g_new(NMPWireGuardPeer, obj->_lnk_wireguard.peers_len) + : NULL; + + /* duplicate allowed_ips instead of using the pointer. The GArray possibly has more + * space allocated then we need, and we want to get rid of this excess buffer. + * Note that NMPObject instance is possibly put into the cache and long-living. */ + obj->_lnk_wireguard._allowed_ips_buf_len = allowed_ips ? allowed_ips->len : 0u; + obj->_lnk_wireguard._allowed_ips_buf = + obj->_lnk_wireguard._allowed_ips_buf_len > 0 + ? (NMPWireGuardAllowedIP *) nm_memdup(allowed_ips->data, + sizeof(NMPWireGuardAllowedIP) * allowed_ips->len) + : NULL; + + i = 0; + c_list_for_each_entry_safe (peer_c, peer_c_safe, &parse_data.peers, lst) { + NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &obj->_lnk_wireguard.peers[i++]; + + *peer = peer_c->data; + + c_list_unlink_stale(&peer_c->lst); + nm_explicit_bzero(&peer_c->data.preshared_key, sizeof(peer_c->data.preshared_key)); + g_slice_free(WireGuardPeerConstruct, peer_c); + + if (peer->_construct_idx_end != 0) { + guint len; + + nm_assert(obj->_lnk_wireguard._allowed_ips_buf); + nm_assert(peer->_construct_idx_end > peer->_construct_idx_start); + nm_assert(peer->_construct_idx_start < obj->_lnk_wireguard._allowed_ips_buf_len); + nm_assert(peer->_construct_idx_end <= obj->_lnk_wireguard._allowed_ips_buf_len); + + len = peer->_construct_idx_end - peer->_construct_idx_start; + peer->allowed_ips = &obj->_lnk_wireguard._allowed_ips_buf[peer->_construct_idx_start]; + peer->allowed_ips_len = len; + } else { + nm_assert(!peer->_construct_idx_start); + nm_assert(!peer->_construct_idx_end); + peer->allowed_ips = NULL; + peer->allowed_ips_len = 0; + } + } + + return obj; + +nla_put_failure: + g_return_val_if_reached(NULL); +} + +static int +_wireguard_get_family_id(NMPlatform *platform, int ifindex_try) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + int wireguard_family_id = -1; + + if (ifindex_try > 0) { + const NMPlatformLink *plink; + + if (nm_platform_link_get_lnk_wireguard(platform, ifindex_try, &plink)) + wireguard_family_id = NMP_OBJECT_UP_CAST(plink)->_link.wireguard_family_id; + } + if (wireguard_family_id < 0) + wireguard_family_id = genl_ctrl_resolve(priv->genl, "wireguard"); + return wireguard_family_id; +} + +static const NMPObject * +_wireguard_refresh_link(NMPlatform *platform, int wireguard_family_id, int ifindex) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + nm_auto_nmpobj const NMPObject *obj_old = NULL; + nm_auto_nmpobj const NMPObject *obj_new = NULL; + nm_auto_nmpobj const NMPObject *lnk_new = NULL; + NMPCacheOpsType cache_op; + const NMPObject * plink = NULL; + nm_auto_nmpobj NMPObject *obj = NULL; + + nm_assert(wireguard_family_id >= 0); + nm_assert(ifindex > 0); + + nm_platform_process_events(platform); + + plink = nm_platform_link_get_obj(platform, ifindex, TRUE); + + if (!plink || plink->link.type != NM_LINK_TYPE_WIREGUARD) { + nm_platform_link_refresh(platform, ifindex); + plink = nm_platform_link_get_obj(platform, ifindex, TRUE); + if (!plink || plink->link.type != NM_LINK_TYPE_WIREGUARD) + return NULL; + if (NMP_OBJECT_GET_TYPE(plink->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_WIREGUARD) + lnk_new = nmp_object_ref(plink->_link.netlink.lnk); + } else { + lnk_new = _wireguard_read_info(platform, priv->genl, wireguard_family_id, ifindex); + if (!lnk_new) { + if (NMP_OBJECT_GET_TYPE(plink->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_WIREGUARD) + lnk_new = nmp_object_ref(plink->_link.netlink.lnk); + } else if (nmp_object_equal(plink->_link.netlink.lnk, lnk_new)) { + nmp_object_unref(lnk_new); + lnk_new = nmp_object_ref(plink->_link.netlink.lnk); + } + } + + if (plink->_link.wireguard_family_id == wireguard_family_id + && plink->_link.netlink.lnk == lnk_new) + return plink; + + /* we use nmp_cache_update_netlink() to re-inject the new object into the cache. + * For that, we need to clone it, and tweak it so that it's suitable. It's a bit + * of a hack, in particular that we need to clear driver and udev-device. */ + obj = nmp_object_clone(plink, FALSE); + obj->_link.wireguard_family_id = wireguard_family_id; + nmp_object_unref(obj->_link.netlink.lnk); + obj->_link.netlink.lnk = g_steal_pointer(&lnk_new); + obj->link.driver = NULL; + nm_clear_pointer(&obj->_link.udev.device, udev_device_unref); + + cache_op = + nmp_cache_update_netlink(nm_platform_get_cache(platform), obj, FALSE, &obj_old, &obj_new); + nm_assert(NM_IN_SET(cache_op, NMP_CACHE_OPS_UPDATED)); + if (cache_op != NMP_CACHE_OPS_UNCHANGED) { + cache_on_change(platform, cache_op, obj_old, obj_new); + nm_platform_cache_update_emit_signal(platform, cache_op, obj_old, obj_new); + } + + nm_assert(!obj_new + || (NMP_OBJECT_GET_TYPE(obj_new) == NMP_OBJECT_TYPE_LINK + && obj_new->link.type == NM_LINK_TYPE_WIREGUARD + && (!obj_new->_link.netlink.lnk + || NMP_OBJECT_GET_TYPE(obj_new->_link.netlink.lnk) + == NMP_OBJECT_TYPE_LNK_WIREGUARD))); + return obj_new; +} + +static int +_wireguard_create_change_nlmsgs(NMPlatform * platform, + int ifindex, + int wireguard_family_id, + const NMPlatformLnkWireGuard * lnk_wireguard, + const NMPWireGuardPeer * peers, + const NMPlatformWireGuardChangePeerFlags *peer_flags, + guint peers_len, + NMPlatformWireGuardChangeFlags change_flags, + GPtrArray ** out_msgs) +{ + gs_unref_ptrarray GPtrArray * msgs = NULL; + nm_auto_nlmsg struct nl_msg * msg = NULL; + const guint IDX_NIL = G_MAXUINT; + guint idx_peer_curr; + guint idx_allowed_ips_curr; + struct nlattr * nest_peers; + struct nlattr * nest_curr_peer; + struct nlattr * nest_allowed_ips; + struct nlattr * nest_curr_allowed_ip; + NMPlatformWireGuardChangePeerFlags p_flags = NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_DEFAULT; + +#define _nla_nest_end(msg, nest_start) \ + G_STMT_START \ + { \ + if (nla_nest_end((msg), (nest_start)) < 0) \ + g_return_val_if_reached(-NME_BUG); \ + } \ + G_STMT_END + + /* Adapted from LGPL-2.1+ code [1]. + * + * [1] https://git.zx2c4.com/WireGuard/tree/contrib/examples/embeddable-wg-library/wireguard.c?id=5e99a6d43fe2351adf36c786f5ea2086a8fe7ab8#n1073 */ + + idx_peer_curr = IDX_NIL; + idx_allowed_ips_curr = IDX_NIL; + + /* TODO: for the moment, we always reset all peers and allowed-ips (WGDEVICE_F_REPLACE_PEERS, WGPEER_F_REPLACE_ALLOWEDIPS). + * The platform API should be extended to also support partial updates. In particular, configuring the same configuration + * multiple times, should not clear and re-add all settings, but rather sync the existing settings with the desired configuration. */ + +again: + + msg = nlmsg_alloc(); + if (!genlmsg_put(msg, + NL_AUTO_PORT, + NL_AUTO_SEQ, + wireguard_family_id, + 0, + NLM_F_REQUEST, + WG_CMD_SET_DEVICE, + 1)) + g_return_val_if_reached(-NME_BUG); + + NLA_PUT_U32(msg, WGDEVICE_A_IFINDEX, (guint32) ifindex); + + if (idx_peer_curr == IDX_NIL) { + guint32 flags; + + if (NM_FLAGS_HAS(change_flags, NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY)) + NLA_PUT(msg, + WGDEVICE_A_PRIVATE_KEY, + sizeof(lnk_wireguard->private_key), + lnk_wireguard->private_key); + if (NM_FLAGS_HAS(change_flags, NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_LISTEN_PORT)) + NLA_PUT_U16(msg, WGDEVICE_A_LISTEN_PORT, lnk_wireguard->listen_port); + if (NM_FLAGS_HAS(change_flags, NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK)) + NLA_PUT_U32(msg, WGDEVICE_A_FWMARK, lnk_wireguard->fwmark); + + flags = 0; + if (NM_FLAGS_HAS(change_flags, NM_PLATFORM_WIREGUARD_CHANGE_FLAG_REPLACE_PEERS)) + flags |= WGDEVICE_F_REPLACE_PEERS; + NLA_PUT_U32(msg, WGDEVICE_A_FLAGS, flags); + } + + if (peers_len == 0) + goto send; + + nest_curr_peer = NULL; + nest_allowed_ips = NULL; + nest_curr_allowed_ip = NULL; + + nest_peers = nla_nest_start(msg, WGDEVICE_A_PEERS); + if (!nest_peers) + g_return_val_if_reached(-NME_BUG); + + if (idx_peer_curr == IDX_NIL) + idx_peer_curr = 0; + for (; idx_peer_curr < peers_len; idx_peer_curr++) { + const NMPWireGuardPeer *p = &peers[idx_peer_curr]; + + if (peer_flags) { + p_flags = peer_flags[idx_peer_curr]; + if (!NM_FLAGS_ANY(p_flags, + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REMOVE_ME + | NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_PRESHARED_KEY + | NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_KEEPALIVE_INTERVAL + | NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ENDPOINT + | NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ALLOWEDIPS + | NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REPLACE_ALLOWEDIPS)) { + /* no flags set. We take that as indication to skip configuring the peer + * entirely. */ + nm_assert(p_flags == NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_NONE); + continue; + } + } + + nest_curr_peer = nla_nest_start(msg, 0); + if (!nest_curr_peer) + goto toobig_peers; + + if (nla_put(msg, WGPEER_A_PUBLIC_KEY, NMP_WIREGUARD_PUBLIC_KEY_LEN, p->public_key) < 0) + goto toobig_peers; + + if (NM_FLAGS_HAS(p_flags, NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REMOVE_ME)) { + /* all other p_flags are silently ignored. */ + if (nla_put_uint32(msg, WGPEER_A_FLAGS, WGPEER_F_REMOVE_ME) < 0) + goto toobig_peers; + } else { + if (idx_allowed_ips_curr == IDX_NIL) { + if (NM_FLAGS_HAS(p_flags, NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_PRESHARED_KEY) + && nla_put(msg, + WGPEER_A_PRESHARED_KEY, + sizeof(p->preshared_key), + p->preshared_key) + < 0) + goto toobig_peers; + + if (NM_FLAGS_HAS(p_flags, + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_KEEPALIVE_INTERVAL) + && nla_put_uint16(msg, + WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, + p->persistent_keepalive_interval) + < 0) + goto toobig_peers; + + if (NM_FLAGS_HAS(p_flags, NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REPLACE_ALLOWEDIPS) + && nla_put_uint32(msg, WGPEER_A_FLAGS, WGPEER_F_REPLACE_ALLOWEDIPS) < 0) + goto toobig_peers; + + if (NM_FLAGS_HAS(p_flags, NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ENDPOINT)) { + if (NM_IN_SET(p->endpoint.sa.sa_family, AF_INET, AF_INET6)) { + if (nla_put(msg, + WGPEER_A_ENDPOINT, + p->endpoint.sa.sa_family == AF_INET ? sizeof(p->endpoint.in) + : sizeof(p->endpoint.in6), + &p->endpoint) + < 0) + goto toobig_peers; + } else { + /* I think there is no way to clear an endpoint, though there should be. */ + nm_assert(p->endpoint.sa.sa_family == AF_UNSPEC); + } + } + } + + if (NM_FLAGS_HAS(p_flags, NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ALLOWEDIPS) + && p->allowed_ips_len > 0) { + if (idx_allowed_ips_curr == IDX_NIL) + idx_allowed_ips_curr = 0; + + nest_allowed_ips = nla_nest_start(msg, WGPEER_A_ALLOWEDIPS); + if (!nest_allowed_ips) + goto toobig_allowedips; + + for (; idx_allowed_ips_curr < p->allowed_ips_len; idx_allowed_ips_curr++) { + const NMPWireGuardAllowedIP *aip = &p->allowed_ips[idx_allowed_ips_curr]; + + nest_curr_allowed_ip = nla_nest_start(msg, 0); + if (!nest_curr_allowed_ip) + goto toobig_allowedips; + + g_return_val_if_fail(NM_IN_SET(aip->family, AF_INET, AF_INET6), -NME_BUG); + + if (nla_put_uint16(msg, WGALLOWEDIP_A_FAMILY, aip->family) < 0) + goto toobig_allowedips; + if (nla_put(msg, + WGALLOWEDIP_A_IPADDR, + nm_utils_addr_family_to_size(aip->family), + &aip->addr) + < 0) + goto toobig_allowedips; + if (nla_put_uint8(msg, WGALLOWEDIP_A_CIDR_MASK, aip->mask) < 0) + goto toobig_allowedips; + + _nla_nest_end(msg, nest_curr_allowed_ip); + nest_curr_allowed_ip = NULL; + } + idx_allowed_ips_curr = IDX_NIL; + + _nla_nest_end(msg, nest_allowed_ips); + nest_allowed_ips = NULL; + } + } + + _nla_nest_end(msg, nest_curr_peer); + nest_curr_peer = NULL; + } + + _nla_nest_end(msg, nest_peers); + goto send; + +toobig_allowedips: + if (nest_curr_allowed_ip) + nla_nest_cancel(msg, nest_curr_allowed_ip); + if (nest_allowed_ips) + _nla_nest_end(msg, nest_allowed_ips); + _nla_nest_end(msg, nest_curr_peer); + _nla_nest_end(msg, nest_peers); + goto send; + +toobig_peers: + if (nest_curr_peer) + nla_nest_cancel(msg, nest_curr_peer); + _nla_nest_end(msg, nest_peers); + goto send; + +send: + if (!msgs) + msgs = g_ptr_array_new_with_free_func((GDestroyNotify) nlmsg_free); + g_ptr_array_add(msgs, g_steal_pointer(&msg)); + + if (idx_peer_curr != IDX_NIL && idx_peer_curr < peers_len) + goto again; + + NM_SET_OUT(out_msgs, g_steal_pointer(&msgs)); + return 0; + +nla_put_failure: + g_return_val_if_reached(-NME_BUG); + +#undef _nla_nest_end +} + +static int +link_wireguard_change(NMPlatform * platform, + int ifindex, + const NMPlatformLnkWireGuard * lnk_wireguard, + const NMPWireGuardPeer * peers, + const NMPlatformWireGuardChangePeerFlags *peer_flags, + guint peers_len, + NMPlatformWireGuardChangeFlags change_flags) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + gs_unref_ptrarray GPtrArray *msgs = NULL; + int wireguard_family_id; + guint i; + int r; + + wireguard_family_id = _wireguard_get_family_id(platform, ifindex); + if (wireguard_family_id < 0) + return -NME_PL_NO_FIRMWARE; + + r = _wireguard_create_change_nlmsgs(platform, + ifindex, + wireguard_family_id, + lnk_wireguard, + peers, + peer_flags, + peers_len, + change_flags, + &msgs); + if (r < 0) { + _LOGW("wireguard: set-device, cannot construct netlink message: %s", nm_strerror(r)); + return r; + } + + for (i = 0; i < msgs->len; i++) { + r = nl_send_auto(priv->genl, msgs->pdata[i]); + if (r < 0) { + _LOGW("wireguard: set-device, send netlink message #%u failed: %s", i, nm_strerror(r)); + return r; + } + + do { + r = nl_recvmsgs(priv->genl, NULL); + } while (r == -EAGAIN); + if (r < 0) { + _LOGW("wireguard: set-device, message #%u was rejected: %s", i, nm_strerror(r)); + return r; + } + + _LOGT("wireguard: set-device, message #%u sent and confirmed", i); + } + + _wireguard_refresh_link(platform, wireguard_family_id, ifindex); + + return 0; +} + +/*****************************************************************************/ + +static void +_nmp_link_address_set(NMPLinkAddress *dst, const struct nlattr *nla) +{ + *dst = (NMPLinkAddress){ + .len = 0, + }; + if (nla) { + int l = nla_len(nla); + + if (l > 0 && l <= _NM_UTILS_HWADDR_LEN_MAX) { + G_STATIC_ASSERT_EXPR(sizeof(dst->data) == _NM_UTILS_HWADDR_LEN_MAX); + memcpy(dst->data, nla_data(nla), l); + dst->len = l; + } + } +} + +/* Copied and heavily modified from libnl3's link_msg_parser(). */ +static NMPObject * +_new_from_nl_link(NMPlatform * platform, + const NMPCache * cache, + struct nlmsghdr *nlh, + gboolean id_only) +{ + static const struct nla_policy policy[] = { + [IFLA_IFNAME] = {.type = NLA_STRING, .maxlen = IFNAMSIZ}, + [IFLA_MTU] = {.type = NLA_U32}, + [IFLA_TXQLEN] = {.type = NLA_U32}, + [IFLA_LINK] = {.type = NLA_U32}, + [IFLA_WEIGHT] = {.type = NLA_U32}, + [IFLA_MASTER] = {.type = NLA_U32}, + [IFLA_OPERSTATE] = {.type = NLA_U8}, + [IFLA_LINKMODE] = {.type = NLA_U8}, + [IFLA_LINKINFO] = {.type = NLA_NESTED}, + [IFLA_QDISC] = {.type = NLA_STRING, .maxlen = IFQDISCSIZ}, + [IFLA_STATS] = {.minlen = nm_offsetofend(struct rtnl_link_stats, tx_compressed)}, + [IFLA_STATS64] = {.minlen = nm_offsetofend(struct rtnl_link_stats64, tx_compressed)}, + [IFLA_MAP] = {.minlen = nm_offsetofend(struct rtnl_link_ifmap, port)}, + [IFLA_IFALIAS] = {.type = NLA_STRING, .maxlen = IFALIASZ}, + [IFLA_NUM_VF] = {.type = NLA_U32}, + [IFLA_AF_SPEC] = {.type = NLA_NESTED}, + [IFLA_PROMISCUITY] = {.type = NLA_U32}, + [IFLA_NUM_TX_QUEUES] = {.type = NLA_U32}, + [IFLA_NUM_RX_QUEUES] = {.type = NLA_U32}, + [IFLA_GROUP] = {.type = NLA_U32}, + [IFLA_CARRIER] = {.type = NLA_U8}, + [IFLA_PHYS_PORT_ID] = {.type = NLA_UNSPEC}, + [IFLA_NET_NS_PID] = {.type = NLA_U32}, + [IFLA_NET_NS_FD] = {.type = NLA_U32}, + [IFLA_LINK_NETNSID] = {}, + }; + const struct ifinfomsg *ifi; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + struct nlattr * nl_info_data = NULL; + const char * nl_info_kind = NULL; + nm_auto_nmpobj NMPObject *obj = NULL; + gboolean completed_from_cache_val = FALSE; + gboolean * completed_from_cache = cache ? &completed_from_cache_val : NULL; + const NMPObject * link_cached = NULL; + const NMPObject * lnk_data = NULL; + gboolean address_complete_from_cache = TRUE; + gboolean broadcast_complete_from_cache = TRUE; + gboolean lnk_data_complete_from_cache = TRUE; + gboolean need_ext_data = FALSE; + gboolean af_inet6_token_valid = FALSE; + gboolean af_inet6_addr_gen_mode_valid = FALSE; + + if (!nlmsg_valid_hdr(nlh, sizeof(*ifi))) + return NULL; + + ifi = nlmsg_data(nlh); + + if (ifi->ifi_family != AF_UNSPEC) + return NULL; + if (ifi->ifi_index <= 0) + return NULL; + + obj = nmp_object_new_link(ifi->ifi_index); + + if (id_only) + return g_steal_pointer(&obj); + + if (nlmsg_parse_arr(nlh, sizeof(*ifi), tb, policy) < 0) + return NULL; + + if (!tb[IFLA_IFNAME]) + return NULL; + nla_strlcpy(obj->link.name, tb[IFLA_IFNAME], IFNAMSIZ); + if (!obj->link.name[0]) + return NULL; + + if (!tb[IFLA_MTU]) { + /* Kernel has two places that send RTM_GETLINK messages: + * net/core/rtnetlink.c and net/wireless/ext-core.c. + * Unfortunately ext-core.c sets only IFLA_WIRELESS and + * IFLA_IFNAME. This confuses code in this function, because + * it cannot get complete set of data for the interface and + * later incomplete object this function creates is used to + * overwrite existing data in NM's cache. + * Since ext-core.c doesn't set IFLA_MTU we can use it as a + * signal to ignore incoming message. + * To some extent this is a hack and correct approach is to + * merge objects per-field. + */ + return NULL; + } + obj->link.mtu = nla_get_u32(tb[IFLA_MTU]); + + if (tb[IFLA_LINKINFO]) { + static const struct nla_policy policy_link_info[] = { + [IFLA_INFO_KIND] = {.type = NLA_STRING}, + [IFLA_INFO_DATA] = {.type = NLA_NESTED}, + [IFLA_INFO_XSTATS] = {.type = NLA_NESTED}, + }; + struct nlattr *li[G_N_ELEMENTS(policy_link_info)]; + + if (nla_parse_nested_arr(li, tb[IFLA_LINKINFO], policy_link_info) < 0) + return NULL; + + if (li[IFLA_INFO_KIND]) + nl_info_kind = nla_get_string(li[IFLA_INFO_KIND]); + + nl_info_data = li[IFLA_INFO_DATA]; + } + + if (tb[IFLA_STATS64]) { + const char *stats = nla_data(tb[IFLA_STATS64]); + + obj->link.rx_packets = + unaligned_read_ne64(&stats[G_STRUCT_OFFSET(struct rtnl_link_stats64, rx_packets)]); + obj->link.rx_bytes = + unaligned_read_ne64(&stats[G_STRUCT_OFFSET(struct rtnl_link_stats64, rx_bytes)]); + obj->link.tx_packets = + unaligned_read_ne64(&stats[G_STRUCT_OFFSET(struct rtnl_link_stats64, tx_packets)]); + obj->link.tx_bytes = + unaligned_read_ne64(&stats[G_STRUCT_OFFSET(struct rtnl_link_stats64, tx_bytes)]); + } + + obj->link.n_ifi_flags = ifi->ifi_flags; + obj->link.connected = NM_FLAGS_HAS(obj->link.n_ifi_flags, IFF_LOWER_UP); + obj->link.arptype = ifi->ifi_type; + + obj->link.type = _linktype_get_type(platform, + cache, + nl_info_kind, + obj->link.ifindex, + obj->link.name, + obj->link.n_ifi_flags, + obj->link.arptype, + completed_from_cache, + &link_cached, + &obj->link.kind); + + if (tb[IFLA_MASTER]) + obj->link.master = nla_get_u32(tb[IFLA_MASTER]); + + if (tb[IFLA_LINK]) { + if (!tb[IFLA_LINK_NETNSID]) + obj->link.parent = nla_get_u32(tb[IFLA_LINK]); + else + obj->link.parent = NM_PLATFORM_LINK_OTHER_NETNS; + } + + if (tb[IFLA_ADDRESS]) { + _nmp_link_address_set(&obj->link.l_address, tb[IFLA_ADDRESS]); + address_complete_from_cache = FALSE; + } + + if (tb[IFLA_BROADCAST]) { + _nmp_link_address_set(&obj->link.l_broadcast, tb[IFLA_BROADCAST]); + broadcast_complete_from_cache = FALSE; + } + + if (tb[IFLA_AF_SPEC]) { + struct nlattr *af_attr; + int remaining; + + nla_for_each_nested (af_attr, tb[IFLA_AF_SPEC], remaining) { + switch (nla_type(af_attr)) { + case AF_INET6: + _parse_af_inet6(platform, + af_attr, + &obj->link.inet6_token, + &af_inet6_token_valid, + &obj->link.inet6_addr_gen_mode_inv, + &af_inet6_addr_gen_mode_valid); + break; + } + } + } + + switch (obj->link.type) { + case NM_LINK_TYPE_BRIDGE: + lnk_data = _parse_lnk_bridge(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_GRE: + case NM_LINK_TYPE_GRETAP: + lnk_data = _parse_lnk_gre(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_INFINIBAND: + lnk_data = _parse_lnk_infiniband(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_IP6TNL: + lnk_data = _parse_lnk_ip6tnl(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_IP6GRE: + case NM_LINK_TYPE_IP6GRETAP: + lnk_data = _parse_lnk_ip6gre(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_IPIP: + lnk_data = _parse_lnk_ipip(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_MACSEC: + lnk_data = _parse_lnk_macsec(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_MACVLAN: + case NM_LINK_TYPE_MACVTAP: + lnk_data = _parse_lnk_macvlan(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_SIT: + lnk_data = _parse_lnk_sit(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_TUN: + lnk_data = _parse_lnk_tun(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_VLAN: + lnk_data = _parse_lnk_vlan(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_VRF: + lnk_data = _parse_lnk_vrf(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_VXLAN: + lnk_data = _parse_lnk_vxlan(nl_info_kind, nl_info_data); + break; + case NM_LINK_TYPE_WIFI: + case NM_LINK_TYPE_OLPC_MESH: + case NM_LINK_TYPE_WPAN: + need_ext_data = TRUE; + lnk_data_complete_from_cache = FALSE; + break; + case NM_LINK_TYPE_WIREGUARD: + lnk_data_complete_from_cache = TRUE; + break; + default: + lnk_data_complete_from_cache = FALSE; + break; + } + + if (completed_from_cache + && (lnk_data_complete_from_cache || need_ext_data || address_complete_from_cache + || broadcast_complete_from_cache || !af_inet6_token_valid + || !af_inet6_addr_gen_mode_valid || !tb[IFLA_STATS64])) { + _lookup_cached_link(cache, obj->link.ifindex, completed_from_cache, &link_cached); + if (link_cached && link_cached->_link.netlink.is_in_netlink) { + if (lnk_data_complete_from_cache && link_cached->link.type == obj->link.type + && link_cached->_link.netlink.lnk + && (!lnk_data || nmp_object_equal(lnk_data, link_cached->_link.netlink.lnk))) { + /* We always try to look into the cache and reuse the object there. + * We do that, because we consider the lnk object as immutable and don't + * modify it after creating. Hence we can share it and reuse. + * + * Also, sometimes the info-data is missing for updates. In this case + * we want to keep the previously received lnk_data. */ + nmp_object_unref(lnk_data); + lnk_data = nmp_object_ref(link_cached->_link.netlink.lnk); + } + + if (need_ext_data && link_cached->link.type == obj->link.type + && link_cached->_link.ext_data) { + /* Prefer reuse of existing ext_data object */ + obj->_link.ext_data = g_object_ref(link_cached->_link.ext_data); + } + + if (address_complete_from_cache) + obj->link.l_address = link_cached->link.l_address; + if (broadcast_complete_from_cache) + obj->link.l_broadcast = link_cached->link.l_broadcast; + if (!af_inet6_token_valid) + obj->link.inet6_token = link_cached->link.inet6_token; + if (!af_inet6_addr_gen_mode_valid) + obj->link.inet6_addr_gen_mode_inv = link_cached->link.inet6_addr_gen_mode_inv; + if (!tb[IFLA_STATS64]) { + obj->link.rx_packets = link_cached->link.rx_packets; + obj->link.rx_bytes = link_cached->link.rx_bytes; + obj->link.tx_packets = link_cached->link.tx_packets; + obj->link.tx_bytes = link_cached->link.tx_bytes; + } + } + } + + obj->_link.netlink.lnk = lnk_data; + + if (need_ext_data && obj->_link.ext_data == NULL) { + switch (obj->link.type) { + case NM_LINK_TYPE_WIFI: + case NM_LINK_TYPE_OLPC_MESH: + obj->_link.ext_data = + (GObject *) nm_wifi_utils_new(ifi->ifi_index, + _genl_sock(NM_LINUX_PLATFORM(platform)), + TRUE); + break; + case NM_LINK_TYPE_WPAN: + obj->_link.ext_data = + (GObject *) nm_wpan_utils_new(ifi->ifi_index, + _genl_sock(NM_LINUX_PLATFORM(platform)), + TRUE); + break; + default: + g_assert_not_reached(); + } + } + + if (obj->link.type == NM_LINK_TYPE_WIREGUARD) { + const NMPObject *lnk_data_new = NULL; + struct nl_sock * genl = NM_LINUX_PLATFORM_GET_PRIVATE(platform)->genl; + + /* The WireGuard kernel module does not yet send link update + * notifications, so we don't actually update the cache. For + * now, always refetch link data here. */ + + _lookup_cached_link(cache, obj->link.ifindex, completed_from_cache, &link_cached); + if (link_cached && link_cached->_link.netlink.is_in_netlink + && link_cached->link.type == NM_LINK_TYPE_WIREGUARD) + obj->_link.wireguard_family_id = link_cached->_link.wireguard_family_id; + else + obj->_link.wireguard_family_id = -1; + + if (obj->_link.wireguard_family_id < 0) + obj->_link.wireguard_family_id = genl_ctrl_resolve(genl, "wireguard"); + + if (obj->_link.wireguard_family_id >= 0) { + lnk_data_new = _wireguard_read_info(platform, + genl, + obj->_link.wireguard_family_id, + obj->link.ifindex); + } + + if (lnk_data_new && obj->_link.netlink.lnk + && nmp_object_equal(obj->_link.netlink.lnk, lnk_data_new)) + nmp_object_unref(lnk_data_new); + else { + nmp_object_unref(obj->_link.netlink.lnk); + obj->_link.netlink.lnk = lnk_data_new; + } + } + + obj->_link.netlink.is_in_netlink = TRUE; + return g_steal_pointer(&obj); +} + +/* Copied and heavily modified from libnl3's addr_msg_parser(). */ +static NMPObject * +_new_from_nl_addr(struct nlmsghdr *nlh, gboolean id_only) +{ + static const struct nla_policy policy[] = { + [IFA_LABEL] = {.type = NLA_STRING, .maxlen = IFNAMSIZ}, + [IFA_CACHEINFO] = {.minlen = nm_offsetofend(struct ifa_cacheinfo, tstamp)}, + [IFA_FLAGS] = {}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + const struct ifaddrmsg *ifa; + gboolean is_v4; + nm_auto_nmpobj NMPObject *obj = NULL; + int addr_len; + guint32 lifetime, preferred, timestamp; + + if (!nlmsg_valid_hdr(nlh, sizeof(*ifa))) + return NULL; + + ifa = nlmsg_data(nlh); + + if (!NM_IN_SET(ifa->ifa_family, AF_INET, AF_INET6)) + return NULL; + + is_v4 = ifa->ifa_family == AF_INET; + + if (nlmsg_parse_arr(nlh, sizeof(*ifa), tb, policy) < 0) + return NULL; + + addr_len = is_v4 ? sizeof(in_addr_t) : sizeof(struct in6_addr); + + if (ifa->ifa_prefixlen > (is_v4 ? 32 : 128)) + return NULL; + + /*****************************************************************/ + + obj = nmp_object_new(is_v4 ? NMP_OBJECT_TYPE_IP4_ADDRESS : NMP_OBJECT_TYPE_IP6_ADDRESS, NULL); + + obj->ip_address.ifindex = ifa->ifa_index; + obj->ip_address.plen = ifa->ifa_prefixlen; + + _check_addr_or_return_null(tb, IFA_ADDRESS, addr_len); + _check_addr_or_return_null(tb, IFA_LOCAL, addr_len); + if (is_v4) { + /* For IPv4, kernel omits IFA_LOCAL/IFA_ADDRESS if (and only if) they + * are effectively 0.0.0.0 (all-zero). */ + if (tb[IFA_LOCAL]) + memcpy(&obj->ip4_address.address, nla_data(tb[IFA_LOCAL]), addr_len); + if (tb[IFA_ADDRESS]) + memcpy(&obj->ip4_address.peer_address, nla_data(tb[IFA_ADDRESS]), addr_len); + + _check_addr_or_return_null(tb, IFA_BROADCAST, addr_len); + obj->ip4_address.broadcast_address = + tb[IFA_BROADCAST] ? nla_get_u32(tb[IFA_BROADCAST]) : 0u; + obj->ip4_address.use_ip4_broadcast_address = TRUE; + } else { + /* For IPv6, IFA_ADDRESS is always present. + * + * If IFA_LOCAL is missing, IFA_ADDRESS is @address and @peer_address + * is :: (all-zero). + * + * If unexpectedly IFA_ADDRESS is missing, make the best of it -- but it _should_ + * actually be there. */ + if (tb[IFA_ADDRESS] || tb[IFA_LOCAL]) { + if (tb[IFA_LOCAL]) { + memcpy(&obj->ip6_address.address, nla_data(tb[IFA_LOCAL]), addr_len); + if (tb[IFA_ADDRESS]) + memcpy(&obj->ip6_address.peer_address, nla_data(tb[IFA_ADDRESS]), addr_len); + else + obj->ip6_address.peer_address = obj->ip6_address.address; + } else + memcpy(&obj->ip6_address.address, nla_data(tb[IFA_ADDRESS]), addr_len); + } + } + + obj->ip_address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; + + obj->ip_address.n_ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifa->ifa_flags; + + if (is_v4) { + if (tb[IFA_LABEL]) { + char label[IFNAMSIZ]; + + nla_strlcpy(label, tb[IFA_LABEL], IFNAMSIZ); + + /* Check for ':'; we're only interested in labels used as interface aliases */ + if (strchr(label, ':')) + g_strlcpy(obj->ip4_address.label, label, sizeof(obj->ip4_address.label)); + } + } + + lifetime = NM_PLATFORM_LIFETIME_PERMANENT; + preferred = NM_PLATFORM_LIFETIME_PERMANENT; + timestamp = 0; + /* IPv6 only */ + if (tb[IFA_CACHEINFO]) { + const struct ifa_cacheinfo *ca; + + ca = nla_data_as(struct ifa_cacheinfo, tb[IFA_CACHEINFO]); + lifetime = ca->ifa_valid; + preferred = ca->ifa_prefered; + timestamp = ca->tstamp; + } + _addrtime_get_lifetimes(timestamp, + lifetime, + preferred, + &obj->ip_address.timestamp, + &obj->ip_address.lifetime, + &obj->ip_address.preferred); + + return g_steal_pointer(&obj); +} + +/* Copied and heavily modified from libnl3's rtnl_route_parse() and parse_multipath(). */ +static NMPObject * +_new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only) +{ + static const struct nla_policy policy[] = { + [RTA_TABLE] = {.type = NLA_U32}, + [RTA_IIF] = {.type = NLA_U32}, + [RTA_OIF] = {.type = NLA_U32}, + [RTA_PRIORITY] = {.type = NLA_U32}, + [RTA_PREF] = {.type = NLA_U8}, + [RTA_FLOW] = {.type = NLA_U32}, + [RTA_CACHEINFO] = {.minlen = nm_offsetofend(struct rta_cacheinfo, rta_tsage)}, + [RTA_METRICS] = {.type = NLA_NESTED}, + [RTA_MULTIPATH] = {.type = NLA_NESTED}, + }; + const struct rtmsg *rtm; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + gboolean is_v4; + nm_auto_nmpobj NMPObject *obj = NULL; + int addr_len; + struct { + gboolean is_present; + int ifindex; + NMIPAddr gateway; + } nh = { + .is_present = FALSE, + }; + guint32 mss; + guint32 window = 0; + guint32 cwnd = 0; + guint32 initcwnd = 0; + guint32 initrwnd = 0; + guint32 mtu = 0; + guint32 lock = 0; + + if (!nlmsg_valid_hdr(nlh, sizeof(*rtm))) + return NULL; + + rtm = nlmsg_data(nlh); + + /***************************************************************** + * only handle ~supported~ routes. + *****************************************************************/ + + if (!NM_IN_SET(rtm->rtm_family, AF_INET, AF_INET6)) + return NULL; + + if (!NM_IN_SET(rtm->rtm_type, RTN_UNICAST, RTN_LOCAL)) + return NULL; + + if (nlmsg_parse_arr(nlh, sizeof(struct rtmsg), tb, policy) < 0) + return NULL; + + /*****************************************************************/ + + is_v4 = rtm->rtm_family == AF_INET; + addr_len = is_v4 ? sizeof(in_addr_t) : sizeof(struct in6_addr); + + if (rtm->rtm_dst_len > (is_v4 ? 32 : 128)) + return NULL; + + /***************************************************************** + * parse nexthops. Only handle routes with one nh. + *****************************************************************/ + + if (tb[RTA_MULTIPATH]) { + size_t tlen = nla_len(tb[RTA_MULTIPATH]); + struct rtnexthop *rtnh; + + if (tlen < sizeof(*rtnh)) + goto rta_multipath_done; + + rtnh = nla_data_as(struct rtnexthop, tb[RTA_MULTIPATH]); + + if (tlen < rtnh->rtnh_len) + goto rta_multipath_done; + + while (TRUE) { + if (nh.is_present) { + /* we don't support multipath routes. */ + return NULL; + } + + nh.is_present = TRUE; + nh.ifindex = rtnh->rtnh_ifindex; + + if (rtnh->rtnh_len > sizeof(*rtnh)) { + struct nlattr *ntb[G_N_ELEMENTS(policy)]; + + if (nla_parse_arr(ntb, + (struct nlattr *) RTNH_DATA(rtnh), + rtnh->rtnh_len - sizeof(*rtnh), + policy) + < 0) + return NULL; + + if (_check_addr_or_return_null(ntb, RTA_GATEWAY, addr_len)) + memcpy(&nh.gateway, nla_data(ntb[RTA_GATEWAY]), addr_len); + } + + if (tlen < RTNH_ALIGN(rtnh->rtnh_len) + sizeof(*rtnh)) + goto rta_multipath_done; + + tlen -= RTNH_ALIGN(rtnh->rtnh_len); + rtnh = RTNH_NEXT(rtnh); + } +rta_multipath_done:; + } + + if (tb[RTA_OIF] || tb[RTA_GATEWAY] || tb[RTA_FLOW]) { + int ifindex = 0; + NMIPAddr gateway = {}; + + if (tb[RTA_OIF]) + ifindex = nla_get_u32(tb[RTA_OIF]); + if (_check_addr_or_return_null(tb, RTA_GATEWAY, addr_len)) + memcpy(&gateway, nla_data(tb[RTA_GATEWAY]), addr_len); + + if (!nh.is_present) { + /* If no nexthops have been provided via RTA_MULTIPATH + * we add it as regular nexthop to maintain backwards + * compatibility */ + nh.ifindex = ifindex; + nh.gateway = gateway; + } else { + /* Kernel supports new style nexthop configuration, + * verify that it is a duplicate and ignore old-style nexthop. */ + if (nh.ifindex != ifindex || memcmp(&nh.gateway, &gateway, addr_len) != 0) + return NULL; + } + } else if (!nh.is_present) + return NULL; + + /*****************************************************************/ + + mss = 0; + if (tb[RTA_METRICS]) { + static const struct nla_policy rtax_policy[] = { + [RTAX_LOCK] = {.type = NLA_U32}, + [RTAX_ADVMSS] = {.type = NLA_U32}, + [RTAX_WINDOW] = {.type = NLA_U32}, + [RTAX_CWND] = {.type = NLA_U32}, + [RTAX_INITCWND] = {.type = NLA_U32}, + [RTAX_INITRWND] = {.type = NLA_U32}, + [RTAX_MTU] = {.type = NLA_U32}, + }; + struct nlattr *mtb[G_N_ELEMENTS(rtax_policy)]; + + if (nla_parse_nested_arr(mtb, tb[RTA_METRICS], rtax_policy) < 0) + return NULL; + + if (mtb[RTAX_LOCK]) + lock = nla_get_u32(mtb[RTAX_LOCK]); + if (mtb[RTAX_ADVMSS]) + mss = nla_get_u32(mtb[RTAX_ADVMSS]); + if (mtb[RTAX_WINDOW]) + window = nla_get_u32(mtb[RTAX_WINDOW]); + if (mtb[RTAX_CWND]) + cwnd = nla_get_u32(mtb[RTAX_CWND]); + if (mtb[RTAX_INITCWND]) + initcwnd = nla_get_u32(mtb[RTAX_INITCWND]); + if (mtb[RTAX_INITRWND]) + initrwnd = nla_get_u32(mtb[RTAX_INITRWND]); + if (mtb[RTAX_MTU]) + mtu = nla_get_u32(mtb[RTAX_MTU]); + } + + /*****************************************************************/ + + obj = nmp_object_new(is_v4 ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE, NULL); + + obj->ip_route.type_coerced = nm_platform_route_type_coerce(rtm->rtm_type); + obj->ip_route.table_coerced = nm_platform_route_table_coerce( + tb[RTA_TABLE] ? nla_get_u32(tb[RTA_TABLE]) : (guint32) rtm->rtm_table); + + obj->ip_route.ifindex = nh.ifindex; + + if (_check_addr_or_return_null(tb, RTA_DST, addr_len)) + memcpy(obj->ip_route.network_ptr, nla_data(tb[RTA_DST]), addr_len); + + obj->ip_route.plen = rtm->rtm_dst_len; + + if (tb[RTA_PRIORITY]) + obj->ip_route.metric = nla_get_u32(tb[RTA_PRIORITY]); + + if (is_v4) + obj->ip4_route.gateway = nh.gateway.addr4; + else + obj->ip6_route.gateway = nh.gateway.addr6; + + if (is_v4) + obj->ip4_route.scope_inv = nm_platform_route_scope_inv(rtm->rtm_scope); + + if (_check_addr_or_return_null(tb, RTA_PREFSRC, addr_len)) { + if (is_v4) + memcpy(&obj->ip4_route.pref_src, nla_data(tb[RTA_PREFSRC]), addr_len); + else + memcpy(&obj->ip6_route.pref_src, nla_data(tb[RTA_PREFSRC]), addr_len); + } + + if (is_v4) + obj->ip4_route.tos = rtm->rtm_tos; + else { + if (tb[RTA_SRC]) { + _check_addr_or_return_null(tb, RTA_SRC, addr_len); + memcpy(&obj->ip6_route.src, nla_data(tb[RTA_SRC]), addr_len); + } + obj->ip6_route.src_plen = rtm->rtm_src_len; + } + + obj->ip_route.mss = mss; + obj->ip_route.window = window; + obj->ip_route.cwnd = cwnd; + obj->ip_route.initcwnd = initcwnd; + obj->ip_route.initrwnd = initrwnd; + obj->ip_route.mtu = mtu; + obj->ip_route.lock_window = NM_FLAGS_HAS(lock, 1 << RTAX_WINDOW); + obj->ip_route.lock_cwnd = NM_FLAGS_HAS(lock, 1 << RTAX_CWND); + obj->ip_route.lock_initcwnd = NM_FLAGS_HAS(lock, 1 << RTAX_INITCWND); + obj->ip_route.lock_initrwnd = NM_FLAGS_HAS(lock, 1 << RTAX_INITRWND); + obj->ip_route.lock_mtu = NM_FLAGS_HAS(lock, 1 << RTAX_MTU); + + if (!is_v4) { + if (!_nm_platform_kernel_support_detected(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)) { + /* Detect support for RTA_PREF by inspecting the netlink message. + * RTA_PREF was added in kernel 4.1, dated 21 June, 2015. */ + _nm_platform_kernel_support_init(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF, + tb[RTA_PREF] ? 1 : -1); + } + + if (tb[RTA_PREF]) + obj->ip6_route.rt_pref = nla_get_u8(tb[RTA_PREF]); + } + + obj->ip_route.r_rtm_flags = rtm->rtm_flags; + obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot(rtm->rtm_protocol); + + return g_steal_pointer(&obj); +} + +static NMPObject * +_new_from_nl_routing_rule(struct nlmsghdr *nlh, gboolean id_only) +{ + static const struct nla_policy policy[] = { + [FRA_UNSPEC] = {}, + [FRA_DST] = {/* struct in_addr, struct in6_addr */}, + [FRA_SRC] = {/* struct in_addr, struct in6_addr */}, + [FRA_IIFNAME] = + { + .type = NLA_STRING, + .maxlen = IFNAMSIZ, + }, + [FRA_GOTO] = + { + .type = NLA_U32, + }, + [FRA_UNUSED2] = {}, + [FRA_PRIORITY] = + { + .type = NLA_U32, + }, + [FRA_UNUSED3] = {}, + [FRA_UNUSED4] = {}, + [FRA_UNUSED5] = {}, + [FRA_FWMARK] = + { + .type = NLA_U32, + }, + [FRA_FLOW] = + { + .type = NLA_U32, + }, + [FRA_TUN_ID] = + { + .type = NLA_U64, + }, + [FRA_SUPPRESS_IFGROUP] = + { + .type = NLA_U32, + }, + [FRA_SUPPRESS_PREFIXLEN] = + { + .type = NLA_U32, + }, + [FRA_TABLE] = + { + .type = NLA_U32, + }, + [FRA_FWMASK] = + { + .type = NLA_U32, + }, + [FRA_OIFNAME] = + { + .type = NLA_STRING, + .maxlen = IFNAMSIZ, + }, + [FRA_PAD] = + { + .type = NLA_U32, + }, + [FRA_L3MDEV] = + { + .type = NLA_U8, + }, + [FRA_UID_RANGE] = + { + .minlen = sizeof(NMFibRuleUidRange), + .maxlen = sizeof(NMFibRuleUidRange), + }, + [FRA_PROTOCOL] = + { + .type = NLA_U8, + }, + [FRA_IP_PROTO] = + { + .type = NLA_U8, + }, + [FRA_SPORT_RANGE] = + { + .minlen = sizeof(NMFibRulePortRange), + .maxlen = sizeof(NMFibRulePortRange), + }, + [FRA_DPORT_RANGE] = + { + .minlen = sizeof(NMFibRulePortRange), + .maxlen = sizeof(NMFibRulePortRange), + }, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + const struct fib_rule_hdr *frh; + NMPlatformRoutingRule * props; + nm_auto_nmpobj NMPObject *obj = NULL; + int addr_family; + guint8 addr_size; + + if (nlmsg_parse_arr(nlh, sizeof(*frh), tb, policy) < 0) + return NULL; + + frh = nlmsg_data(nlh); + + addr_family = frh->family; + + if (!NM_IN_SET(addr_family, AF_INET, AF_INET6)) { + /* we don't care about other address families. */ + return NULL; + } + + addr_size = nm_utils_addr_family_to_size(addr_family); + + obj = nmp_object_new(NMP_OBJECT_TYPE_ROUTING_RULE, NULL); + props = &obj->routing_rule; + + props->addr_family = addr_family; + props->action = frh->action; + props->flags = frh->flags; + props->tos = frh->tos; + + props->table = tb[FRA_TABLE] ? nla_get_u32(tb[FRA_TABLE]) : frh->table; + + if (tb[FRA_SUPPRESS_PREFIXLEN]) + props->suppress_prefixlen_inverse = ~nla_get_u32(tb[FRA_SUPPRESS_PREFIXLEN]); + + if (tb[FRA_SUPPRESS_IFGROUP]) + props->suppress_ifgroup_inverse = ~nla_get_u32(tb[FRA_SUPPRESS_IFGROUP]); + + if (tb[FRA_IIFNAME]) + nla_strlcpy(props->iifname, tb[FRA_IIFNAME], sizeof(props->iifname)); + + if (tb[FRA_OIFNAME]) + nla_strlcpy(props->oifname, tb[FRA_OIFNAME], sizeof(props->oifname)); + + if (tb[FRA_PRIORITY]) + props->priority = nla_get_u32(tb[FRA_PRIORITY]); + + if (tb[FRA_FWMARK]) + props->fwmark = nla_get_u32(tb[FRA_FWMARK]); + + if (tb[FRA_FWMASK]) + props->fwmask = nla_get_u32(tb[FRA_FWMASK]); + + if (tb[FRA_GOTO]) + props->goto_target = nla_get_u32(tb[FRA_GOTO]); + + props->src_len = frh->src_len; + if (props->src_len > addr_size * 8) + return NULL; + if (!tb[FRA_SRC]) { + if (props->src_len > 0) + return NULL; + } else if (!nm_ip_addr_set_from_untrusted(addr_family, + &props->src, + nla_data(tb[FRA_SRC]), + nla_len(tb[FRA_SRC]), + NULL)) + return NULL; + + props->dst_len = frh->dst_len; + if (props->dst_len > addr_size * 8) + return NULL; + if (!tb[FRA_DST]) { + if (props->dst_len > 0) + return NULL; + } else if (!nm_ip_addr_set_from_untrusted(addr_family, + &props->dst, + nla_data(tb[FRA_DST]), + nla_len(tb[FRA_DST]), + NULL)) + return NULL; + + if (tb[FRA_FLOW]) + props->flow = nla_get_u32(tb[FRA_FLOW]); + + if (tb[FRA_TUN_ID]) + props->tun_id = nla_get_be64(tb[FRA_TUN_ID]); + + if (tb[FRA_L3MDEV]) { + if (!_nm_platform_kernel_support_detected(NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV)) { + /* support for FRA_L3MDEV was added in 96c63fa7393d0a346acfe5a91e0c7d4c7782641b, + * kernel 4.8, 3 October 2017. + * + * We can only detect support if the attribute is present. A missing attribute + * is not conclusive. */ + _nm_platform_kernel_support_init(NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV, 1); + } + + /* actually, kernel only allows this attribute to be missing or + * "1". Still, encode it as full uint8. + * + * Note that FRA_L3MDEV and FRA_TABLE are mutally exclusive. */ + props->l3mdev = nla_get_u8(tb[FRA_L3MDEV]); + } + + if (tb[FRA_PROTOCOL]) + props->protocol = nla_get_u8(tb[FRA_PROTOCOL]); + else + nm_assert(props->protocol == RTPROT_UNSPEC); + + if (!_nm_platform_kernel_support_detected(NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL)) { + /* FRA_PROTOCOL was added in kernel 4.17, dated 3 June, 2018. + * See commit 1b71af6053af1bd2f849e9fda4f71c1e3f145dcf. */ + _nm_platform_kernel_support_init(NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL, + tb[FRA_PROTOCOL] ? 1 : -1); + } + + if (tb[FRA_IP_PROTO]) + props->ip_proto = nla_get_u8(tb[FRA_IP_PROTO]); + + G_STATIC_ASSERT_EXPR(sizeof(NMFibRulePortRange) == 4); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMFibRulePortRange, start) == 0); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMFibRulePortRange, end) == 2); + + nla_memcpy_checked_size(&props->sport_range, tb[FRA_SPORT_RANGE], sizeof(props->sport_range)); + nla_memcpy_checked_size(&props->dport_range, tb[FRA_DPORT_RANGE], sizeof(props->dport_range)); + + if (!_nm_platform_kernel_support_detected(NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO)) { + /* support for FRA_IP_PROTO, FRA_SPORT_RANGE, and FRA_DPORT_RANGE was added together + * by bfff4862653bb96001ab57c1edd6d03f48e5f035, kernel 4.17, 4 June 2018. + * + * Unfortunately, a missing attribute does not tell us anything about support. + * We can only tell for sure when we have support, but not when we don't have. */ + if (tb[FRA_IP_PROTO] || tb[FRA_SPORT_RANGE] || tb[FRA_DPORT_RANGE]) + _nm_platform_kernel_support_init(NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO, 1); + } + + G_STATIC_ASSERT_EXPR(sizeof(NMFibRuleUidRange) == 8); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMFibRuleUidRange, start) == 0); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMFibRuleUidRange, end) == 4); + + if (tb[FRA_UID_RANGE]) { + if (!_nm_platform_kernel_support_detected(NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE)) { + /* support for FRA_UID_RANGE was added in 622ec2c9d52405973c9f1ca5116eb1c393adfc7d, + * kernel 4.10, 19 February 2017. + * + * We can only detect support if the attribute is present. A missing attribute + * is not conclusive. */ + _nm_platform_kernel_support_init(NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE, 1); + } + + nla_memcpy_checked_size(&props->uid_range, tb[FRA_UID_RANGE], sizeof(props->uid_range)); + props->uid_range_has = TRUE; + } + + return g_steal_pointer(&obj); +} + +static guint32 +psched_tick_to_time(NMPlatform *platform, guint32 tick) +{ + static gboolean initialized; + static double tick_in_usec = 1; + + if (!initialized) { + gs_free char *params = NULL; + double clock_factor = 1; + guint32 clock_res; + guint32 t2us; + guint32 us2t; + + initialized = TRUE; + params = nm_platform_sysctl_get(platform, NMP_SYSCTL_PATHID_ABSOLUTE("/proc/net/psched")); + if (!params || sscanf(params, "%08x%08x%08x", &t2us, &us2t, &clock_res) != 3) { + _LOGW("packet scheduler parameters not available"); + } else { + /* See tc_core_init() in iproute2 */ + if (clock_res == 1000000000) + t2us = us2t; + + clock_factor = (double) clock_res / PSCHED_TIME_UNITS_PER_SEC; + tick_in_usec = (double) t2us / us2t * clock_factor; + } + } + + return tick / tick_in_usec; +} + +static NMPObject * +_new_from_nl_qdisc(NMPlatform *platform, struct nlmsghdr *nlh, gboolean id_only) +{ + static const struct nla_policy policy[] = { + [TCA_KIND] = {.type = NLA_STRING}, + [TCA_OPTIONS] = {.type = NLA_NESTED}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + const struct tcmsg *tcm; + nm_auto_nmpobj NMPObject *obj = NULL; + + if (nlmsg_parse_arr(nlh, sizeof(*tcm), tb, policy) < 0) + return NULL; + + if (!tb[TCA_KIND]) + return NULL; + + tcm = nlmsg_data(nlh); + + obj = nmp_object_new(NMP_OBJECT_TYPE_QDISC, NULL); + + obj->qdisc.kind = g_intern_string(nla_get_string(tb[TCA_KIND])); + obj->qdisc.ifindex = tcm->tcm_ifindex; + obj->qdisc.addr_family = tcm->tcm_family; + obj->qdisc.handle = tcm->tcm_handle; + obj->qdisc.parent = tcm->tcm_parent; + obj->qdisc.info = tcm->tcm_info; + + if (nm_streq0(obj->qdisc.kind, "fq_codel")) { + obj->qdisc.fq_codel.memory_limit = NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET; + obj->qdisc.fq_codel.ce_threshold = NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED; + } + + if (tb[TCA_OPTIONS]) { + struct nlattr *options_attr; + int remaining; + + if (nm_streq0(obj->qdisc.kind, "sfq")) { + struct tc_sfq_qopt_v1 opt; + + if (tb[TCA_OPTIONS]->nla_len >= nla_attr_size(sizeof(opt))) { + memcpy(&opt, nla_data(tb[TCA_OPTIONS]), sizeof(opt)); + obj->qdisc.sfq.quantum = opt.v0.quantum; + obj->qdisc.sfq.perturb_period = opt.v0.perturb_period; + obj->qdisc.sfq.limit = opt.v0.limit; + obj->qdisc.sfq.divisor = opt.v0.divisor; + obj->qdisc.sfq.flows = opt.v0.flows; + obj->qdisc.sfq.depth = opt.depth; + } + } else if (nm_streq0(obj->qdisc.kind, "tbf")) { + static const struct nla_policy tbf_policy[] = { + [TCA_TBF_PARMS] = {.minlen = sizeof(struct tc_tbf_qopt)}, + [TCA_TBF_RATE64] = {.type = NLA_U64}, + }; + struct nlattr * tbf_tb[G_N_ELEMENTS(tbf_policy)]; + struct tc_tbf_qopt opt; + + if (nla_parse_nested_arr(tbf_tb, tb[TCA_OPTIONS], tbf_policy) < 0) + return NULL; + if (!tbf_tb[TCA_TBF_PARMS]) + return NULL; + + nla_memcpy_checked_size(&opt, tbf_tb[TCA_TBF_PARMS], sizeof(opt)); + obj->qdisc.tbf.rate = opt.rate.rate; + if (tbf_tb[TCA_TBF_RATE64]) + obj->qdisc.tbf.rate = nla_get_u64(tbf_tb[TCA_TBF_RATE64]); + obj->qdisc.tbf.burst = + ((double) obj->qdisc.tbf.rate * psched_tick_to_time(platform, opt.buffer)) + / PSCHED_TIME_UNITS_PER_SEC; + obj->qdisc.tbf.limit = opt.limit; + } else { + nla_for_each_nested (options_attr, tb[TCA_OPTIONS], remaining) { + if (nla_len(options_attr) < sizeof(uint32_t)) + continue; + + if (nm_streq0(obj->qdisc.kind, "fq_codel")) { + switch (nla_type(options_attr)) { + case TCA_FQ_CODEL_LIMIT: + obj->qdisc.fq_codel.limit = nla_get_u32(options_attr); + break; + case TCA_FQ_CODEL_FLOWS: + obj->qdisc.fq_codel.flows = nla_get_u32(options_attr); + break; + case TCA_FQ_CODEL_TARGET: + obj->qdisc.fq_codel.target = nla_get_u32(options_attr); + break; + case TCA_FQ_CODEL_INTERVAL: + obj->qdisc.fq_codel.interval = nla_get_u32(options_attr); + break; + case TCA_FQ_CODEL_QUANTUM: + obj->qdisc.fq_codel.quantum = nla_get_u32(options_attr); + break; + case TCA_FQ_CODEL_CE_THRESHOLD: + obj->qdisc.fq_codel.ce_threshold = nla_get_u32(options_attr); + break; + case TCA_FQ_CODEL_MEMORY_LIMIT: + obj->qdisc.fq_codel.memory_limit = nla_get_u32(options_attr); + break; + case TCA_FQ_CODEL_ECN: + obj->qdisc.fq_codel.ecn = !!nla_get_u32(options_attr); + break; + } + } + } + } + } + + return g_steal_pointer(&obj); +} + +static NMPObject * +_new_from_nl_tfilter(struct nlmsghdr *nlh, gboolean id_only) +{ + static const struct nla_policy policy[] = { + [TCA_KIND] = {.type = NLA_STRING}, + }; + struct nlattr * tb[G_N_ELEMENTS(policy)]; + NMPObject * obj = NULL; + const struct tcmsg *tcm; + + if (nlmsg_parse_arr(nlh, sizeof(*tcm), tb, policy) < 0) + return NULL; + + if (!tb[TCA_KIND]) + return NULL; + + tcm = nlmsg_data(nlh); + + obj = nmp_object_new(NMP_OBJECT_TYPE_TFILTER, NULL); + + obj->tfilter.kind = g_intern_string(nla_get_string(tb[TCA_KIND])); + obj->tfilter.ifindex = tcm->tcm_ifindex; + obj->tfilter.addr_family = tcm->tcm_family; + obj->tfilter.handle = tcm->tcm_handle; + obj->tfilter.parent = tcm->tcm_parent; + obj->tfilter.info = tcm->tcm_info; + + return obj; +} + +/** + * nmp_object_new_from_nl: + * @platform: (allow-none): for creating certain objects, the constructor wants to check + * sysfs. For this the platform instance is needed. If missing, the object might not + * be correctly detected. + * @cache: (allow-none): for certain objects, the netlink message doesn't contain all the information. + * If a cache is given, the object is completed with information from the cache. + * @nlh: the netlink message header + * @id_only: whether only to create an empty object with only the ID fields set. + * + * Returns: %NULL or a newly created NMPObject instance. + **/ +static NMPObject * +nmp_object_new_from_nl(NMPlatform * platform, + const NMPCache *cache, + struct nl_msg * msg, + gboolean id_only) +{ + struct nlmsghdr *msghdr; + + if (nlmsg_get_proto(msg) != NETLINK_ROUTE) + return NULL; + + msghdr = nlmsg_hdr(msg); + + switch (msghdr->nlmsg_type) { + case RTM_NEWLINK: + case RTM_DELLINK: + case RTM_GETLINK: + case RTM_SETLINK: + return _new_from_nl_link(platform, cache, msghdr, id_only); + case RTM_NEWADDR: + case RTM_DELADDR: + case RTM_GETADDR: + return _new_from_nl_addr(msghdr, id_only); + case RTM_NEWROUTE: + case RTM_DELROUTE: + case RTM_GETROUTE: + return _new_from_nl_route(msghdr, id_only); + case RTM_NEWRULE: + case RTM_DELRULE: + case RTM_GETRULE: + return _new_from_nl_routing_rule(msghdr, id_only); + case RTM_NEWQDISC: + case RTM_DELQDISC: + case RTM_GETQDISC: + return _new_from_nl_qdisc(platform, msghdr, id_only); + case RTM_NEWTFILTER: + case RTM_DELTFILTER: + case RTM_GETTFILTER: + return _new_from_nl_tfilter(msghdr, id_only); + default: + return NULL; + } +} + +/*****************************************************************************/ + +static gboolean +_nl_msg_new_link_set_afspec(struct nl_msg *msg, int addr_gen_mode, NMUtilsIPv6IfaceId *iid) +{ + struct nlattr *af_spec; + struct nlattr *af_attr; + + nm_assert(msg); + + if (!(af_spec = nla_nest_start(msg, IFLA_AF_SPEC))) + goto nla_put_failure; + + if (addr_gen_mode >= 0 || iid) { + if (!(af_attr = nla_nest_start(msg, AF_INET6))) + goto nla_put_failure; + + if (addr_gen_mode >= 0) + NLA_PUT_U8(msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode); + + if (iid) { + struct in6_addr i6_token = {.s6_addr = { + 0, + }}; + + nm_utils_ipv6_addr_set_interface_identifier(&i6_token, *iid); + NLA_PUT(msg, IFLA_INET6_TOKEN, sizeof(struct in6_addr), &i6_token); + } + + nla_nest_end(msg, af_attr); + } + + nla_nest_end(msg, af_spec); + + return TRUE; +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static gboolean +_nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpointer extra_data) +{ + struct nlattr *info; + struct nlattr *data = NULL; + const char * kind; + + nm_assert(msg); + + kind = nm_link_type_to_rtnl_type_string(link_type); + if (!kind) + goto nla_put_failure; + + if (!(info = nla_nest_start(msg, IFLA_LINKINFO))) + goto nla_put_failure; + + NLA_PUT_STRING(msg, IFLA_INFO_KIND, kind); + + switch (link_type) { + case NM_LINK_TYPE_BRIDGE: + { + const NMPlatformLnkBridge *props = extra_data; + + nm_assert(extra_data); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + NLA_PUT_U32(msg, IFLA_BR_FORWARD_DELAY, props->forward_delay); + NLA_PUT_U32(msg, IFLA_BR_HELLO_TIME, props->hello_time); + NLA_PUT_U32(msg, IFLA_BR_MAX_AGE, props->max_age); + NLA_PUT_U32(msg, IFLA_BR_AGEING_TIME, props->ageing_time); + NLA_PUT_U32(msg, IFLA_BR_STP_STATE, !!props->stp_state); + NLA_PUT_U16(msg, IFLA_BR_PRIORITY, props->priority); + NLA_PUT_U16(msg, IFLA_BR_VLAN_PROTOCOL, htons(props->vlan_protocol)); + if (props->vlan_stats_enabled) + NLA_PUT_U8(msg, IFLA_BR_VLAN_STATS_ENABLED, !!props->vlan_stats_enabled); + NLA_PUT_U16(msg, IFLA_BR_GROUP_FWD_MASK, props->group_fwd_mask); + NLA_PUT(msg, IFLA_BR_GROUP_ADDR, sizeof(props->group_addr), &props->group_addr); + NLA_PUT_U8(msg, IFLA_BR_MCAST_SNOOPING, !!props->mcast_snooping); + NLA_PUT_U8(msg, IFLA_BR_MCAST_ROUTER, props->mcast_router); + NLA_PUT_U8(msg, IFLA_BR_MCAST_QUERY_USE_IFADDR, !!props->mcast_query_use_ifaddr); + NLA_PUT_U8(msg, IFLA_BR_MCAST_QUERIER, !!props->mcast_querier); + NLA_PUT_U32(msg, IFLA_BR_MCAST_HASH_MAX, props->mcast_hash_max); + NLA_PUT_U32(msg, IFLA_BR_MCAST_LAST_MEMBER_CNT, props->mcast_last_member_count); + NLA_PUT_U32(msg, IFLA_BR_MCAST_STARTUP_QUERY_CNT, props->mcast_startup_query_count); + NLA_PUT_U64(msg, IFLA_BR_MCAST_LAST_MEMBER_INTVL, props->mcast_last_member_interval); + NLA_PUT_U64(msg, IFLA_BR_MCAST_MEMBERSHIP_INTVL, props->mcast_membership_interval); + NLA_PUT_U64(msg, IFLA_BR_MCAST_QUERIER_INTVL, props->mcast_querier_interval); + NLA_PUT_U64(msg, IFLA_BR_MCAST_QUERY_INTVL, props->mcast_query_interval); + NLA_PUT_U64(msg, IFLA_BR_MCAST_QUERY_RESPONSE_INTVL, props->mcast_query_response_interval); + NLA_PUT_U64(msg, IFLA_BR_MCAST_STARTUP_QUERY_INTVL, props->mcast_startup_query_interval); + break; + } + case NM_LINK_TYPE_VLAN: + { + const NMPlatformLnkVlan *props = extra_data; + + nm_assert(extra_data); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + NLA_PUT_U16(msg, IFLA_VLAN_ID, props->id); + + { + struct ifla_vlan_flags flags = { + .flags = props->flags & _NM_VLAN_FLAGS_ALL, + .mask = _NM_VLAN_FLAGS_ALL, + }; + + NLA_PUT(msg, IFLA_VLAN_FLAGS, sizeof(flags), &flags); + } + break; + } + case NM_LINK_TYPE_VRF: + { + const NMPlatformLnkVrf *props = extra_data; + + nm_assert(extra_data); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + NLA_PUT_U32(msg, IFLA_VRF_TABLE, props->table); + break; + } + case NM_LINK_TYPE_VXLAN: + { + const NMPlatformLnkVxlan *props = extra_data; + + nm_assert(extra_data); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + NLA_PUT_U32(msg, IFLA_VXLAN_ID, props->id); + + if (props->group) + NLA_PUT(msg, IFLA_VXLAN_GROUP, sizeof(props->group), &props->group); + else if (!IN6_IS_ADDR_UNSPECIFIED(&props->group6)) + NLA_PUT(msg, IFLA_VXLAN_GROUP6, sizeof(props->group6), &props->group6); + + if (props->local) + NLA_PUT(msg, IFLA_VXLAN_LOCAL, sizeof(props->local), &props->local); + else if (!IN6_IS_ADDR_UNSPECIFIED(&props->local6)) + NLA_PUT(msg, IFLA_VXLAN_LOCAL6, sizeof(props->local6), &props->local6); + + if (props->parent_ifindex >= 0) + NLA_PUT_U32(msg, IFLA_VXLAN_LINK, props->parent_ifindex); + + if (props->src_port_min || props->src_port_max) { + struct nm_ifla_vxlan_port_range port_range = { + .low = htons(props->src_port_min), + .high = htons(props->src_port_max), + }; + + NLA_PUT(msg, IFLA_VXLAN_PORT_RANGE, sizeof(port_range), &port_range); + } + + NLA_PUT_U16(msg, IFLA_VXLAN_PORT, htons(props->dst_port)); + NLA_PUT_U8(msg, IFLA_VXLAN_TOS, props->tos); + NLA_PUT_U8(msg, IFLA_VXLAN_TTL, props->ttl); + NLA_PUT_U32(msg, IFLA_VXLAN_AGEING, props->ageing); + NLA_PUT_U32(msg, IFLA_VXLAN_LIMIT, props->limit); + NLA_PUT_U8(msg, IFLA_VXLAN_LEARNING, !!props->learning); + NLA_PUT_U8(msg, IFLA_VXLAN_PROXY, !!props->proxy); + NLA_PUT_U8(msg, IFLA_VXLAN_RSC, !!props->rsc); + NLA_PUT_U8(msg, IFLA_VXLAN_L2MISS, !!props->l2miss); + NLA_PUT_U8(msg, IFLA_VXLAN_L3MISS, !!props->l3miss); + break; + } + case NM_LINK_TYPE_VETH: + { + const char * veth_peer = extra_data; + const struct ifinfomsg ifi = {}; + struct nlattr * info_peer; + + nm_assert(veth_peer); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + if (!(info_peer = nla_nest_start(msg, 1 /*VETH_INFO_PEER*/))) + goto nla_put_failure; + if (nlmsg_append_struct(msg, &ifi) < 0) + goto nla_put_failure; + NLA_PUT_STRING(msg, IFLA_IFNAME, veth_peer); + nla_nest_end(msg, info_peer); + break; + } + case NM_LINK_TYPE_GRE: + case NM_LINK_TYPE_GRETAP: + { + const NMPlatformLnkGre *props = extra_data; + + nm_assert(props); + nm_assert(props->is_tap == (link_type == NM_LINK_TYPE_GRETAP)); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + if (props->parent_ifindex) + NLA_PUT_U32(msg, IFLA_GRE_LINK, props->parent_ifindex); + NLA_PUT_U32(msg, IFLA_GRE_LOCAL, props->local); + NLA_PUT_U32(msg, IFLA_GRE_REMOTE, props->remote); + NLA_PUT_U8(msg, IFLA_GRE_TTL, props->ttl); + NLA_PUT_U8(msg, IFLA_GRE_TOS, props->tos); + NLA_PUT_U8(msg, IFLA_GRE_PMTUDISC, !!props->path_mtu_discovery); + NLA_PUT_U32(msg, IFLA_GRE_IKEY, htonl(props->input_key)); + NLA_PUT_U32(msg, IFLA_GRE_OKEY, htonl(props->output_key)); + NLA_PUT_U16(msg, IFLA_GRE_IFLAGS, htons(props->input_flags)); + NLA_PUT_U16(msg, IFLA_GRE_OFLAGS, htons(props->output_flags)); + break; + } + case NM_LINK_TYPE_SIT: + { + const NMPlatformLnkSit *props = extra_data; + + nm_assert(props); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + if (props->parent_ifindex) + NLA_PUT_U32(msg, IFLA_IPTUN_LINK, props->parent_ifindex); + NLA_PUT_U32(msg, IFLA_IPTUN_LOCAL, props->local); + NLA_PUT_U32(msg, IFLA_IPTUN_REMOTE, props->remote); + NLA_PUT_U8(msg, IFLA_IPTUN_TTL, props->ttl); + NLA_PUT_U8(msg, IFLA_IPTUN_TOS, props->tos); + NLA_PUT_U8(msg, IFLA_IPTUN_PMTUDISC, !!props->path_mtu_discovery); + break; + } + case NM_LINK_TYPE_IP6TNL: + { + const NMPlatformLnkIp6Tnl *props = extra_data; + guint32 flowinfo; + + nm_assert(props); + nm_assert(!props->is_gre); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + if (props->parent_ifindex) + NLA_PUT_U32(msg, IFLA_IPTUN_LINK, props->parent_ifindex); + + if (!IN6_IS_ADDR_UNSPECIFIED(&props->local)) + NLA_PUT(msg, IFLA_IPTUN_LOCAL, sizeof(props->local), &props->local); + if (!IN6_IS_ADDR_UNSPECIFIED(&props->remote)) + NLA_PUT(msg, IFLA_IPTUN_REMOTE, sizeof(props->remote), &props->remote); + + NLA_PUT_U8(msg, IFLA_IPTUN_TTL, props->ttl); + NLA_PUT_U8(msg, IFLA_IPTUN_ENCAP_LIMIT, props->encap_limit); + + flowinfo = props->flow_label & IP6_FLOWINFO_FLOWLABEL_MASK; + flowinfo |= (props->tclass << IP6_FLOWINFO_TCLASS_SHIFT) & IP6_FLOWINFO_TCLASS_MASK; + NLA_PUT_U32(msg, IFLA_IPTUN_FLOWINFO, htonl(flowinfo)); + NLA_PUT_U8(msg, IFLA_IPTUN_PROTO, props->proto); + NLA_PUT_U32(msg, IFLA_IPTUN_FLAGS, props->flags); + break; + } + case NM_LINK_TYPE_IP6GRE: + case NM_LINK_TYPE_IP6GRETAP: + { + const NMPlatformLnkIp6Tnl *props = extra_data; + guint32 flowinfo; + + nm_assert(props); + nm_assert(props->is_gre); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + if (props->parent_ifindex) + NLA_PUT_U32(msg, IFLA_GRE_LINK, props->parent_ifindex); + + NLA_PUT_U32(msg, IFLA_GRE_IKEY, htonl(props->input_key)); + NLA_PUT_U32(msg, IFLA_GRE_OKEY, htonl(props->output_key)); + NLA_PUT_U16(msg, IFLA_GRE_IFLAGS, htons(props->input_flags)); + NLA_PUT_U16(msg, IFLA_GRE_OFLAGS, htons(props->output_flags)); + + if (!IN6_IS_ADDR_UNSPECIFIED(&props->local)) + NLA_PUT(msg, IFLA_GRE_LOCAL, sizeof(props->local), &props->local); + if (!IN6_IS_ADDR_UNSPECIFIED(&props->local)) + NLA_PUT(msg, IFLA_GRE_REMOTE, sizeof(props->remote), &props->remote); + + NLA_PUT_U8(msg, IFLA_GRE_TTL, props->ttl); + NLA_PUT_U8(msg, IFLA_GRE_ENCAP_LIMIT, props->encap_limit); + + flowinfo = props->flow_label & IP6_FLOWINFO_FLOWLABEL_MASK; + flowinfo |= (props->tclass << IP6_FLOWINFO_TCLASS_SHIFT) & IP6_FLOWINFO_TCLASS_MASK; + NLA_PUT_U32(msg, IFLA_GRE_FLOWINFO, htonl(flowinfo)); + NLA_PUT_U32(msg, IFLA_GRE_FLAGS, props->flags); + break; + } + case NM_LINK_TYPE_IPIP: + { + const NMPlatformLnkIpIp *props = extra_data; + + nm_assert(props); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + if (props->parent_ifindex) + NLA_PUT_U32(msg, IFLA_IPTUN_LINK, props->parent_ifindex); + NLA_PUT_U32(msg, IFLA_IPTUN_LOCAL, props->local); + NLA_PUT_U32(msg, IFLA_IPTUN_REMOTE, props->remote); + NLA_PUT_U8(msg, IFLA_IPTUN_TTL, props->ttl); + NLA_PUT_U8(msg, IFLA_IPTUN_TOS, props->tos); + NLA_PUT_U8(msg, IFLA_IPTUN_PMTUDISC, !!props->path_mtu_discovery); + break; + } + case NM_LINK_TYPE_MACSEC: + { + const NMPlatformLnkMacsec *props = extra_data; + + nm_assert(props); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + if (props->icv_length) + NLA_PUT_U8(msg, IFLA_MACSEC_ICV_LEN, 16); + if (props->cipher_suite) + NLA_PUT_U64(msg, IFLA_MACSEC_CIPHER_SUITE, props->cipher_suite); + if (props->replay_protect) + NLA_PUT_U32(msg, IFLA_MACSEC_WINDOW, props->window); + + NLA_PUT_U64(msg, IFLA_MACSEC_SCI, htobe64(props->sci)); + NLA_PUT_U8(msg, IFLA_MACSEC_ENCODING_SA, props->encoding_sa); + NLA_PUT_U8(msg, IFLA_MACSEC_ENCRYPT, props->encrypt); + NLA_PUT_U8(msg, IFLA_MACSEC_PROTECT, props->protect); + NLA_PUT_U8(msg, IFLA_MACSEC_INC_SCI, props->include_sci); + NLA_PUT_U8(msg, IFLA_MACSEC_ES, props->es); + NLA_PUT_U8(msg, IFLA_MACSEC_SCB, props->scb); + NLA_PUT_U8(msg, IFLA_MACSEC_REPLAY_PROTECT, props->replay_protect); + NLA_PUT_U8(msg, IFLA_MACSEC_VALIDATION, props->validation); + break; + }; + case NM_LINK_TYPE_MACVTAP: + case NM_LINK_TYPE_MACVLAN: + { + const NMPlatformLnkMacvlan *props = extra_data; + + nm_assert(props); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + NLA_PUT_U32(msg, IFLA_MACVLAN_MODE, props->mode); + NLA_PUT_U16(msg, IFLA_MACVLAN_FLAGS, props->no_promisc ? MACVLAN_FLAG_NOPROMISC : 0); + break; + } + default: + nm_assert(!extra_data); + break; + } + + if (data) + nla_nest_end(msg, data); + + nla_nest_end(msg, info); + + return TRUE; +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static gboolean +_nl_msg_new_link_set_linkinfo_vlan(struct nl_msg * msg, + int vlan_id, + guint32 flags_mask, + guint32 flags_set, + const NMVlanQosMapping *ingress_qos, + int ingress_qos_len, + const NMVlanQosMapping *egress_qos, + int egress_qos_len) +{ + struct nlattr *info; + struct nlattr *data; + guint i; + gboolean has_any_vlan_properties = FALSE; + + G_STATIC_ASSERT(_NM_VLAN_FLAG_REORDER_HEADERS == (guint32) VLAN_FLAG_REORDER_HDR); + G_STATIC_ASSERT(_NM_VLAN_FLAG_GVRP == (guint32) VLAN_FLAG_GVRP); + G_STATIC_ASSERT(_NM_VLAN_FLAG_LOOSE_BINDING == (guint32) VLAN_FLAG_LOOSE_BINDING); + G_STATIC_ASSERT(_NM_VLAN_FLAG_MVRP == (guint32) VLAN_FLAG_MVRP); + +#define VLAN_XGRESS_PRIO_VALID(from) (((from) & ~(guint32) 0x07) == 0) + + nm_assert(msg); + + /* We must not create an empty IFLA_LINKINFO section. Otherwise, kernel + * rejects the request as invalid. */ + if (flags_mask != 0 || vlan_id >= 0) + has_any_vlan_properties = TRUE; + if (!has_any_vlan_properties && ingress_qos && ingress_qos_len > 0) { + for (i = 0; i < ingress_qos_len; i++) { + if (VLAN_XGRESS_PRIO_VALID(ingress_qos[i].from)) { + has_any_vlan_properties = TRUE; + break; + } + } + } + if (!has_any_vlan_properties && egress_qos && egress_qos_len > 0) { + for (i = 0; i < egress_qos_len; i++) { + if (VLAN_XGRESS_PRIO_VALID(egress_qos[i].to)) { + has_any_vlan_properties = TRUE; + break; + } + } + } + if (!has_any_vlan_properties) + return TRUE; + + if (!(info = nla_nest_start(msg, IFLA_LINKINFO))) + goto nla_put_failure; + + NLA_PUT_STRING(msg, IFLA_INFO_KIND, "vlan"); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + if (vlan_id >= 0) + NLA_PUT_U16(msg, IFLA_VLAN_ID, vlan_id); + + if (flags_mask != 0) { + struct ifla_vlan_flags flags = { + .flags = flags_mask & flags_set, + .mask = flags_mask, + }; + + NLA_PUT(msg, IFLA_VLAN_FLAGS, sizeof(flags), &flags); + } + + if (ingress_qos && ingress_qos_len > 0) { + struct nlattr *qos = NULL; + + for (i = 0; i < ingress_qos_len; i++) { + /* Silently ignore invalid mappings. Kernel would truncate + * them and modify the wrong mapping. */ + if (VLAN_XGRESS_PRIO_VALID(ingress_qos[i].from)) { + if (!qos) { + if (!(qos = nla_nest_start(msg, IFLA_VLAN_INGRESS_QOS))) + goto nla_put_failure; + } + NLA_PUT(msg, i, sizeof(ingress_qos[i]), &ingress_qos[i]); + } + } + + if (qos) + nla_nest_end(msg, qos); + } + + if (egress_qos && egress_qos_len > 0) { + struct nlattr *qos = NULL; + + for (i = 0; i < egress_qos_len; i++) { + if (VLAN_XGRESS_PRIO_VALID(egress_qos[i].to)) { + if (!qos) { + if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS))) + goto nla_put_failure; + } + NLA_PUT(msg, i, sizeof(egress_qos[i]), &egress_qos[i]); + } + } + + if (qos) + nla_nest_end(msg, qos); + } + + nla_nest_end(msg, data); + nla_nest_end(msg, info); + + return TRUE; +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static struct nl_msg * +_nl_msg_new_link_full(int nlmsg_type, + int nlmsg_flags, + int ifindex, + const char *ifname, + guint8 family, + unsigned flags_mask, + unsigned flags_set) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + const struct ifinfomsg ifi = { + .ifi_family = family, + .ifi_change = flags_mask, + .ifi_flags = flags_set, + .ifi_index = ifindex, + }; + + nm_assert(NM_IN_SET(nlmsg_type, RTM_DELLINK, RTM_NEWLINK, RTM_GETLINK, RTM_SETLINK)); + + msg = nlmsg_alloc_simple(nlmsg_type, nlmsg_flags); + + if (nlmsg_append_struct(msg, &ifi) < 0) + goto nla_put_failure; + + if (ifname) + NLA_PUT_STRING(msg, IFLA_IFNAME, ifname); + + return g_steal_pointer(&msg); + +nla_put_failure: + g_return_val_if_reached(NULL); +} + +static struct nl_msg * +_nl_msg_new_link(int nlmsg_type, int nlmsg_flags, int ifindex, const char *ifname) +{ + return _nl_msg_new_link_full(nlmsg_type, nlmsg_flags, ifindex, ifname, AF_UNSPEC, 0, 0); +} + +/* Copied and modified from libnl3's build_addr_msg(). */ +static struct nl_msg * +_nl_msg_new_address(int nlmsg_type, + int nlmsg_flags, + int family, + int ifindex, + gconstpointer address, + guint8 plen, + gconstpointer peer_address, + guint32 flags, + int scope, + guint32 lifetime, + guint32 preferred, + in_addr_t ip4_broadcast_address, + const char * label) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + struct ifaddrmsg am = { + .ifa_family = family, + .ifa_index = ifindex, + .ifa_prefixlen = plen, + .ifa_flags = flags, + }; + gsize addr_len; + + nm_assert(NM_IN_SET(family, AF_INET, AF_INET6)); + nm_assert(NM_IN_SET(nlmsg_type, RTM_NEWADDR, RTM_DELADDR)); + + msg = nlmsg_alloc_simple(nlmsg_type, nlmsg_flags); + + if (scope == -1) { + /* Allow having scope unset, and detect the scope (including IPv4 compatibility hack). */ + if (family == AF_INET && address && *((char *) address) == 127) + scope = RT_SCOPE_HOST; + else + scope = RT_SCOPE_UNIVERSE; + } + am.ifa_scope = scope, + + addr_len = family == AF_INET ? sizeof(in_addr_t) : sizeof(struct in6_addr); + + if (nlmsg_append_struct(msg, &am) < 0) + goto nla_put_failure; + + if (address) + NLA_PUT(msg, IFA_LOCAL, addr_len, address); + + if (peer_address) + NLA_PUT(msg, IFA_ADDRESS, addr_len, peer_address); + else if (address) + NLA_PUT(msg, IFA_ADDRESS, addr_len, address); + + if (label && label[0]) + NLA_PUT_STRING(msg, IFA_LABEL, label); + + if (ip4_broadcast_address != 0) + NLA_PUT(msg, IFA_BROADCAST, sizeof(in_addr_t), &ip4_broadcast_address); + + if (lifetime != NM_PLATFORM_LIFETIME_PERMANENT || preferred != NM_PLATFORM_LIFETIME_PERMANENT) { + struct ifa_cacheinfo ca = { + .ifa_valid = lifetime, + .ifa_prefered = preferred, + }; + + NLA_PUT(msg, IFA_CACHEINFO, sizeof(ca), &ca); + } + + if (flags & ~((guint32) 0xFF)) { + /* only set the IFA_FLAGS attribute, if they actually contain additional + * flags that are not already set to am.ifa_flags. + * + * Older kernels refuse RTM_NEWADDR and RTM_NEWROUTE messages with EINVAL + * if they contain unknown netlink attributes. See net/core/rtnetlink.c, which + * was fixed by kernel commit 661d2967b3f1b34eeaa7e212e7b9bbe8ee072b59. */ + NLA_PUT_U32(msg, IFA_FLAGS, flags); + } + + return g_steal_pointer(&msg); + +nla_put_failure: + g_return_val_if_reached(NULL); +} + +static guint32 +ip_route_get_lock_flag(const NMPlatformIPRoute *route) +{ + return (((guint32) route->lock_window) << RTAX_WINDOW) + | (((guint32) route->lock_cwnd) << RTAX_CWND) + | (((guint32) route->lock_initcwnd) << RTAX_INITCWND) + | (((guint32) route->lock_initrwnd) << RTAX_INITRWND) + | (((guint32) route->lock_mtu) << RTAX_MTU); +} + +/* Copied and modified from libnl3's build_route_msg() and rtnl_route_build_msg(). */ +static struct nl_msg * +_nl_msg_new_route(int nlmsg_type, guint16 nlmsgflags, const NMPObject *obj) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + const NMPClass * klass = NMP_OBJECT_GET_CLASS(obj); + gboolean is_v4 = klass->addr_family == AF_INET; + const guint32 lock = ip_route_get_lock_flag(NMP_OBJECT_CAST_IP_ROUTE(obj)); + const guint32 table = + nm_platform_route_table_uncoerce(NMP_OBJECT_CAST_IP_ROUTE(obj)->table_coerced, TRUE); + const struct rtmsg rtmsg = { + .rtm_family = klass->addr_family, + .rtm_tos = is_v4 ? obj->ip4_route.tos : 0, + .rtm_table = table <= 0xFF ? table : RT_TABLE_UNSPEC, + .rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot(obj->ip_route.rt_source), + .rtm_scope = + is_v4 ? nm_platform_route_scope_inv(obj->ip4_route.scope_inv) : RT_SCOPE_NOWHERE, + .rtm_type = nm_platform_route_type_uncoerce(NMP_OBJECT_CAST_IP_ROUTE(obj)->type_coerced), + .rtm_flags = obj->ip_route.r_rtm_flags & ((unsigned) (RTNH_F_ONLINK)), + .rtm_dst_len = obj->ip_route.plen, + .rtm_src_len = is_v4 ? 0 : NMP_OBJECT_CAST_IP6_ROUTE(obj)->src_plen, + }; + + gsize addr_len; + + nm_assert( + NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); + nm_assert(NM_IN_SET(nlmsg_type, RTM_NEWROUTE, RTM_DELROUTE)); + + msg = nlmsg_alloc_simple(nlmsg_type, (int) nlmsgflags); + + if (nlmsg_append_struct(msg, &rtmsg) < 0) + goto nla_put_failure; + + addr_len = is_v4 ? sizeof(in_addr_t) : sizeof(struct in6_addr); + + NLA_PUT(msg, + RTA_DST, + addr_len, + is_v4 ? (gconstpointer) &obj->ip4_route.network + : (gconstpointer) &obj->ip6_route.network); + + if (!is_v4) { + if (!IN6_IS_ADDR_UNSPECIFIED(&NMP_OBJECT_CAST_IP6_ROUTE(obj)->src)) + NLA_PUT(msg, RTA_SRC, addr_len, &obj->ip6_route.src); + } + + NLA_PUT_U32(msg, + RTA_PRIORITY, + is_v4 ? nm_platform_ip4_route_get_effective_metric(&obj->ip4_route) + : nm_platform_ip6_route_get_effective_metric(&obj->ip6_route)); + + if (table > 0xFF) + NLA_PUT_U32(msg, RTA_TABLE, table); + + if (is_v4) { + if (NMP_OBJECT_CAST_IP4_ROUTE(obj)->pref_src) + NLA_PUT(msg, RTA_PREFSRC, addr_len, &obj->ip4_route.pref_src); + } else { + if (!IN6_IS_ADDR_UNSPECIFIED(&NMP_OBJECT_CAST_IP6_ROUTE(obj)->pref_src)) + NLA_PUT(msg, RTA_PREFSRC, addr_len, &obj->ip6_route.pref_src); + } + + if (obj->ip_route.mss || obj->ip_route.window || obj->ip_route.cwnd || obj->ip_route.initcwnd + || obj->ip_route.initrwnd || obj->ip_route.mtu || lock) { + struct nlattr *metrics; + + metrics = nla_nest_start(msg, RTA_METRICS); + if (!metrics) + goto nla_put_failure; + + if (obj->ip_route.mss) + NLA_PUT_U32(msg, RTAX_ADVMSS, obj->ip_route.mss); + if (obj->ip_route.window) + NLA_PUT_U32(msg, RTAX_WINDOW, obj->ip_route.window); + if (obj->ip_route.cwnd) + NLA_PUT_U32(msg, RTAX_CWND, obj->ip_route.cwnd); + if (obj->ip_route.initcwnd) + NLA_PUT_U32(msg, RTAX_INITCWND, obj->ip_route.initcwnd); + if (obj->ip_route.initrwnd) + NLA_PUT_U32(msg, RTAX_INITRWND, obj->ip_route.initrwnd); + if (obj->ip_route.mtu) + NLA_PUT_U32(msg, RTAX_MTU, obj->ip_route.mtu); + if (lock) + NLA_PUT_U32(msg, RTAX_LOCK, lock); + + nla_nest_end(msg, metrics); + } + + /* We currently don't have need for multi-hop routes... */ + if (is_v4) { + NLA_PUT(msg, RTA_GATEWAY, addr_len, &obj->ip4_route.gateway); + } else { + if (!IN6_IS_ADDR_UNSPECIFIED(&obj->ip6_route.gateway)) + NLA_PUT(msg, RTA_GATEWAY, addr_len, &obj->ip6_route.gateway); + } + NLA_PUT_U32(msg, RTA_OIF, obj->ip_route.ifindex); + + if (!is_v4 && obj->ip6_route.rt_pref != NM_ICMPV6_ROUTER_PREF_MEDIUM) + NLA_PUT_U8(msg, RTA_PREF, obj->ip6_route.rt_pref); + + return g_steal_pointer(&msg); + +nla_put_failure: + g_return_val_if_reached(NULL); +} + +static struct nl_msg * +_nl_msg_new_routing_rule(int nlmsg_type, int nlmsg_flags, const NMPlatformRoutingRule *routing_rule) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + const guint8 addr_size = nm_utils_addr_family_to_size(routing_rule->addr_family); + guint32 table; + + msg = nlmsg_alloc_simple(nlmsg_type, nlmsg_flags); + + table = routing_rule->table; + + if (NM_IN_SET(routing_rule->addr_family, AF_INET, AF_INET6) + && routing_rule->action == FR_ACT_TO_TBL && routing_rule->l3mdev == 0 + && table == RT_TABLE_UNSPEC) { + /* for IPv6, this setting is invalid and rejected by kernel. That's fine. + * + * for IPv4, kernel will automatically assign an unused table. That's not + * fine, because we don't know what we will get. + * + * The caller must not allow that to happen. */ + nm_assert_not_reached(); + } + + { + const struct fib_rule_hdr frh = { + .family = routing_rule->addr_family, + .src_len = routing_rule->src_len, + .dst_len = routing_rule->dst_len, + .tos = routing_rule->tos, + .table = table < 0x100u ? (guint8) table : (guint8) RT_TABLE_UNSPEC, + .action = routing_rule->action, + + /* we only allow setting the "not" flag. */ + .flags = routing_rule->flags & ((guint32) FIB_RULE_INVERT), + }; + + if (nlmsg_append_struct(msg, &frh) < 0) + goto nla_put_failure; + } + + if (table > G_MAXINT8) + NLA_PUT_U32(msg, FRA_TABLE, table); + + if (routing_rule->suppress_prefixlen_inverse != 0) + NLA_PUT_U32(msg, FRA_SUPPRESS_PREFIXLEN, ~routing_rule->suppress_prefixlen_inverse); + + if (routing_rule->suppress_ifgroup_inverse != 0) + NLA_PUT_U32(msg, FRA_SUPPRESS_IFGROUP, ~routing_rule->suppress_ifgroup_inverse); + + if (routing_rule->iifname[0] != '\0') + NLA_PUT_STRING(msg, FRA_IIFNAME, routing_rule->iifname); + + if (routing_rule->oifname[0] != '\0') + NLA_PUT_STRING(msg, FRA_OIFNAME, routing_rule->oifname); + + /* we always set the priority and don't support letting kernel pick one. */ + NLA_PUT_U32(msg, FRA_PRIORITY, routing_rule->priority); + + if (routing_rule->fwmark != 0 || routing_rule->fwmask != 0) { + NLA_PUT_U32(msg, FRA_FWMARK, routing_rule->fwmark); + NLA_PUT_U32(msg, FRA_FWMASK, routing_rule->fwmask); + } + + if (routing_rule->src_len > 0) + NLA_PUT(msg, FRA_SRC, addr_size, &routing_rule->src); + + if (routing_rule->dst_len > 0) + NLA_PUT(msg, FRA_DST, addr_size, &routing_rule->dst); + + if (routing_rule->flow != 0) { + /* only relevant for IPv4. */ + NLA_PUT_U32(msg, FRA_FLOW, routing_rule->flow); + } + + if (routing_rule->tun_id != 0) + NLA_PUT_U64(msg, FRA_TUN_ID, htobe64(routing_rule->tun_id)); + + if (routing_rule->l3mdev) + NLA_PUT_U8(msg, FRA_L3MDEV, routing_rule->l3mdev); + + if (routing_rule->protocol != RTPROT_UNSPEC) + NLA_PUT_U8(msg, FRA_PROTOCOL, routing_rule->protocol); + + if (routing_rule->ip_proto != 0) + NLA_PUT_U8(msg, FRA_IP_PROTO, routing_rule->ip_proto); + + if (routing_rule->sport_range.start || routing_rule->sport_range.end) + NLA_PUT(msg, + FRA_SPORT_RANGE, + sizeof(routing_rule->sport_range), + &routing_rule->sport_range); + + if (routing_rule->dport_range.start || routing_rule->dport_range.end) + NLA_PUT(msg, + FRA_DPORT_RANGE, + sizeof(routing_rule->dport_range), + &routing_rule->dport_range); + + if (routing_rule->uid_range_has) + NLA_PUT(msg, FRA_UID_RANGE, sizeof(routing_rule->uid_range), &routing_rule->uid_range); + + switch (routing_rule->action) { + case FR_ACT_GOTO: + NLA_PUT_U32(msg, FRA_GOTO, routing_rule->goto_target); + break; + } + + return g_steal_pointer(&msg); + +nla_put_failure: + g_return_val_if_reached(NULL); +} + +static struct nl_msg * +_nl_msg_new_qdisc(int nlmsg_type, int nlmsg_flags, const NMPlatformQdisc *qdisc) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nlattr * tc_options; + const struct tcmsg tcm = { + .tcm_family = qdisc->addr_family, + .tcm_ifindex = qdisc->ifindex, + .tcm_handle = qdisc->handle, + .tcm_parent = qdisc->parent, + .tcm_info = qdisc->info, + }; + + msg = nlmsg_alloc_simple(nlmsg_type, nlmsg_flags | NMP_NLM_FLAG_F_ECHO); + + if (nlmsg_append_struct(msg, &tcm) < 0) + goto nla_put_failure; + + NLA_PUT_STRING(msg, TCA_KIND, qdisc->kind); + + if (nm_streq(qdisc->kind, "sfq")) { + struct tc_sfq_qopt_v1 opt = {}; + + opt.v0.quantum = qdisc->sfq.quantum; + opt.v0.limit = qdisc->sfq.limit; + opt.v0.perturb_period = qdisc->sfq.perturb_period; + opt.v0.flows = qdisc->sfq.flows; + opt.v0.divisor = qdisc->sfq.divisor; + opt.depth = qdisc->sfq.depth; + + NLA_PUT(msg, TCA_OPTIONS, sizeof(opt), &opt); + } else if (nm_streq(qdisc->kind, "tbf")) { + struct tc_tbf_qopt opt = {}; + + if (!(tc_options = nla_nest_start(msg, TCA_OPTIONS))) + goto nla_put_failure; + + opt.rate.rate = (qdisc->tbf.rate >= (1ULL << 32)) ? ~0U : (guint32) qdisc->tbf.rate; + if (qdisc->tbf.limit) + opt.limit = qdisc->tbf.limit; + else if (qdisc->tbf.latency) { + opt.limit = qdisc->tbf.rate * (double) qdisc->tbf.latency / PSCHED_TIME_UNITS_PER_SEC + + qdisc->tbf.burst; + } + + NLA_PUT(msg, TCA_TBF_PARMS, sizeof(opt), &opt); + if (qdisc->tbf.rate >= (1ULL << 32)) + NLA_PUT_U64(msg, TCA_TBF_RATE64, qdisc->tbf.rate); + NLA_PUT_U32(msg, TCA_TBF_BURST, qdisc->tbf.burst); + + nla_nest_end(msg, tc_options); + } else if (nm_streq(qdisc->kind, "prio")) { + struct tc_prio_qopt opt = {3, {1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}}; + + NLA_PUT(msg, TCA_OPTIONS, sizeof(opt), &opt); + } else { + if (!(tc_options = nla_nest_start(msg, TCA_OPTIONS))) + goto nla_put_failure; + + if (nm_streq(qdisc->kind, "fq_codel")) { + if (qdisc->fq_codel.limit) + NLA_PUT_U32(msg, TCA_FQ_CODEL_LIMIT, qdisc->fq_codel.limit); + if (qdisc->fq_codel.flows) + NLA_PUT_U32(msg, TCA_FQ_CODEL_FLOWS, qdisc->fq_codel.flows); + if (qdisc->fq_codel.target) + NLA_PUT_U32(msg, TCA_FQ_CODEL_TARGET, qdisc->fq_codel.target); + if (qdisc->fq_codel.interval) + NLA_PUT_U32(msg, TCA_FQ_CODEL_INTERVAL, qdisc->fq_codel.interval); + if (qdisc->fq_codel.quantum) + NLA_PUT_U32(msg, TCA_FQ_CODEL_QUANTUM, qdisc->fq_codel.quantum); + if (qdisc->fq_codel.ce_threshold != NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED) + NLA_PUT_U32(msg, TCA_FQ_CODEL_CE_THRESHOLD, qdisc->fq_codel.ce_threshold); + if (qdisc->fq_codel.memory_limit != NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET) + NLA_PUT_U32(msg, TCA_FQ_CODEL_MEMORY_LIMIT, qdisc->fq_codel.memory_limit); + if (qdisc->fq_codel.ecn) + NLA_PUT_U32(msg, TCA_FQ_CODEL_ECN, qdisc->fq_codel.ecn); + } + + nla_nest_end(msg, tc_options); + } + + return g_steal_pointer(&msg); + +nla_put_failure: + g_return_val_if_reached(NULL); +} + +static struct nl_msg * +_nl_msg_new_tfilter(int nlmsg_type, int nlmsg_flags, const NMPlatformTfilter *tfilter) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nlattr * tc_options; + struct nlattr * act_tab; + const struct tcmsg tcm = { + .tcm_family = tfilter->addr_family, + .tcm_ifindex = tfilter->ifindex, + .tcm_handle = tfilter->handle, + .tcm_parent = tfilter->parent, + .tcm_info = tfilter->info, + }; + + msg = nlmsg_alloc_simple(nlmsg_type, nlmsg_flags | NMP_NLM_FLAG_F_ECHO); + + if (nlmsg_append_struct(msg, &tcm) < 0) + goto nla_put_failure; + + NLA_PUT_STRING(msg, TCA_KIND, tfilter->kind); + + if (!(tc_options = nla_nest_start(msg, TCA_OPTIONS))) + goto nla_put_failure; + + if (!(act_tab = nla_nest_start(msg, TCA_OPTIONS))) // 3 TCA_ACT_KIND TCA_ACT_KIND + goto nla_put_failure; + + if (tfilter->action.kind) { + const NMPlatformAction *action = &tfilter->action; + struct nlattr * prio; + struct nlattr * act_options; + + if (!(prio = nla_nest_start(msg, 1 /* priority */))) + goto nla_put_failure; + + NLA_PUT_STRING(msg, TCA_ACT_KIND, action->kind); + + if (nm_streq(action->kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) { + const NMPlatformActionSimple *simple = &action->simple; + struct tc_defact sel = { + 0, + }; + + if (!(act_options = nla_nest_start(msg, TCA_ACT_OPTIONS))) + goto nla_put_failure; + + NLA_PUT(msg, TCA_DEF_PARMS, sizeof(sel), &sel); + NLA_PUT(msg, TCA_DEF_DATA, sizeof(simple->sdata), simple->sdata); + + nla_nest_end(msg, act_options); + + } else if (nm_streq(action->kind, NM_PLATFORM_ACTION_KIND_MIRRED)) { + const NMPlatformActionMirred *mirred = &action->mirred; + struct tc_mirred sel = { + 0, + }; + + if (!(act_options = nla_nest_start(msg, TCA_ACT_OPTIONS))) + goto nla_put_failure; + + if (mirred->egress && mirred->redirect) + sel.eaction = TCA_EGRESS_REDIR; + else if (mirred->egress && mirred->mirror) + sel.eaction = TCA_EGRESS_MIRROR; + else if (mirred->ingress && mirred->redirect) + sel.eaction = TCA_INGRESS_REDIR; + else if (mirred->ingress && mirred->mirror) + sel.eaction = TCA_INGRESS_MIRROR; + sel.ifindex = mirred->ifindex; + + NLA_PUT(msg, TCA_MIRRED_PARMS, sizeof(sel), &sel); + + nla_nest_end(msg, act_options); + } + + nla_nest_end(msg, prio); + } + + nla_nest_end(msg, tc_options); + + nla_nest_end(msg, act_tab); + + return g_steal_pointer(&msg); + +nla_put_failure: + g_return_val_if_reached(NULL); +} + +/*****************************************************************************/ + +static struct nl_sock * +_genl_sock(NMLinuxPlatform *platform) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + + return priv->genl; +} + +#define ASSERT_SYSCTL_ARGS(pathid, dirfd, path) \ + G_STMT_START \ + { \ + const char *const _pathid = (pathid); \ + const int _dirfd = (dirfd); \ + const char *const _path = (path); \ + \ + nm_assert(_path &&_path[0]); \ + g_assert(!strstr(_path, "/../")); \ + if (_dirfd < 0) { \ + nm_assert(!_pathid); \ + nm_assert(_path[0] == '/'); \ + nm_assert(g_str_has_prefix(_path, "/proc/sys/") || g_str_has_prefix(_path, "/sys/") \ + || g_str_has_prefix(_path, "/proc/net")); \ + } else { \ + nm_assert(_pathid &&_pathid[0] && _pathid[0] != '/'); \ + nm_assert(_path[0] != '/'); \ + } \ + } \ + G_STMT_END + +/*****************************************************************************/ + +/* core sysctl-set functions can be called from a non-main thread. + * Hence, we require locking from nm-logging. Indicate that by + * setting NM_THREAD_SAFE_ON_MAIN_THREAD to zero. */ +#undef NM_THREAD_SAFE_ON_MAIN_THREAD +#define NM_THREAD_SAFE_ON_MAIN_THREAD 0 + +static void +_log_dbg_sysctl_set_impl(NMPlatform *platform, + const char *pathid, + int dirfd, + const char *path, + const char *value) +{ + GError * error = NULL; + gs_free char *contents = NULL; + gs_free char *value_escaped = g_strescape(value, NULL); + + if (!nm_utils_file_get_contents(dirfd, + path, + 1 * 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, + &contents, + NULL, + NULL, + &error)) { + _LOGD("sysctl: setting '%s' to '%s' (current value cannot be read: %s)", + pathid ?: path, + value_escaped, + error->message); + g_clear_error(&error); + return; + } + + g_strstrip(contents); + if (nm_streq(contents, value)) + _LOGD("sysctl: setting '%s' to '%s' (current value is identical)", + pathid ?: path, + value_escaped); + else { + gs_free char *contents_escaped = g_strescape(contents, NULL); + + _LOGD("sysctl: setting '%s' to '%s' (current value is '%s')", + pathid ?: path, + value_escaped, + contents_escaped); + } +} + +#define _log_dbg_sysctl_set(platform, pathid, dirfd, path, value) \ + G_STMT_START \ + { \ + if (_LOGD_ENABLED()) { \ + _log_dbg_sysctl_set_impl(platform, pathid, dirfd, path, value); \ + } \ + } \ + G_STMT_END + +static gboolean +sysctl_set_internal(NMPlatform *platform, + const char *pathid, + int dirfd, + const char *path, + const char *value) +{ + int fd, tries; + gssize nwrote; + gssize len; + char * actual; + gs_free char *actual_free = NULL; + int errsv; + + if (dirfd < 0) { + pathid = path; + + fd = open(path, O_WRONLY | O_TRUNC | O_CLOEXEC); + if (fd == -1) { + errsv = errno; + if (errsv == ENOENT) { + _LOGD("sysctl: failed to open '%s': (%d) %s", + pathid, + errsv, + nm_strerror_native(errsv)); + } else { + _LOGE("sysctl: failed to open '%s': (%d) %s", + pathid, + errsv, + nm_strerror_native(errsv)); + } + errno = errsv; + return FALSE; + } + } else { + fd = openat(dirfd, path, O_WRONLY | O_TRUNC | O_CLOEXEC); + if (fd == -1) { + errsv = errno; + if (errsv == ENOENT) { + _LOGD("sysctl: failed to openat '%s': (%d) %s", + pathid, + errsv, + nm_strerror_native(errsv)); + } else { + _LOGE("sysctl: failed to openat '%s': (%d) %s", + pathid, + errsv, + nm_strerror_native(errsv)); + } + errno = errsv; + return FALSE; + } + } + + _log_dbg_sysctl_set(platform, pathid, dirfd, path, value); + + /* Most sysfs and sysctl options don't care about a trailing LF, while some + * (like infiniband) do. So always add the LF. Also, neither sysfs nor + * sysctl support partial writes so the LF must be added to the string we're + * about to write. + */ + len = strlen(value) + 1; + nm_assert(len > 0); + if (len > 512) + actual = actual_free = g_malloc(len + 1); + else + actual = g_alloca(len + 1); + memcpy(actual, value, len - 1); + actual[len - 1] = '\n'; + actual[len] = '\0'; + + /* Try to write the entire value three times if a partial write occurs */ + errsv = 0; + for (tries = 0, nwrote = 0; tries < 3 && nwrote < len - 1; tries++) { + nwrote = write(fd, actual, len); + if (nwrote == -1) { + errsv = errno; + if (errsv == EINTR) { + _LOGD("sysctl: interrupted, will try again"); + continue; + } + break; + } + } + if (nwrote == -1) { + NMLogLevel level = LOGL_ERR; + + if (errsv == EEXIST) { + level = LOGL_DEBUG; + } else if (errsv == EINVAL + && nm_utils_sysctl_ip_conf_is_path(AF_INET6, path, NULL, "mtu")) { + /* setting the MTU can fail under regular conditions. Suppress + * logging a warning. */ + level = LOGL_DEBUG; + } + + _NMLOG(level, + "sysctl: failed to set '%s' to '%s': (%d) %s", + path, + value, + errsv, + nm_strerror_native(errsv)); + } else if (nwrote < len - 1) { + _LOGE("sysctl: failed to set '%s' to '%s' after three attempts", path, value); + } + + if (nwrote < len - 1) { + if (nm_close(fd) != 0) { + if (errsv != 0) + errno = errsv; + } else if (errsv != 0) + errno = errsv; + else + errno = EIO; + return FALSE; + } + if (nm_close(fd) != 0) { + /* errno is already properly set. */ + return FALSE; + } + + /* success. errno is undefined (no need to set). */ + return TRUE; +} + +#undef NM_THREAD_SAFE_ON_MAIN_THREAD +#define NM_THREAD_SAFE_ON_MAIN_THREAD 1 + +/*****************************************************************************/ + +static gboolean +sysctl_set(NMPlatform *platform, const char *pathid, int dirfd, const char *path, const char *value) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + + g_return_val_if_fail(path, FALSE); + g_return_val_if_fail(value, FALSE); + + ASSERT_SYSCTL_ARGS(pathid, dirfd, path); + + if (dirfd < 0 && !nm_platform_netns_push(platform, &netns)) { + errno = ENETDOWN; + return FALSE; + } + + return sysctl_set_internal(platform, pathid, dirfd, path, value); +} + +typedef struct { + NMPlatform * platform; + char * pathid; + int dirfd; + char * path; + char ** values; + GCancellable * cancellable; + NMPlatformAsyncCallback callback; + gpointer callback_data; +} SysctlAsyncInfo; + +static void +sysctl_async_info_free(SysctlAsyncInfo *info) +{ + g_object_unref(info->platform); + g_free(info->pathid); + if (info->dirfd >= 0) + nm_close(info->dirfd); + g_free(info->path); + g_strfreev(info->values); + g_object_unref(info->cancellable); + g_slice_free(SysctlAsyncInfo, info); +} + +static void +sysctl_async_cb(GObject *object, GAsyncResult *res, gpointer user_data) +{ + NMPlatform * platform; + GTask * task = G_TASK(res); + SysctlAsyncInfo *info; + gs_free_error GError *error = NULL; + gs_free char * values_str = NULL; + + info = g_task_get_task_data(task); + + if (g_task_propagate_boolean(task, &error)) { + platform = info->platform; + _LOGD("sysctl: successfully set-async '%s' to values '%s'", + info->pathid ?: info->path, + (values_str = g_strjoinv(", ", info->values))); + } + + if (info->callback) + info->callback(error, info->callback_data); +} + +static void +sysctl_async_thread_fn(GTask * task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + SysctlAsyncInfo * info = task_data; + GError * error = NULL; + char ** value; + + if (g_task_return_error_if_cancelled(task)) + return; + + if (info->dirfd < 0 && !nm_platform_netns_push(info->platform, &netns)) { + g_set_error_literal(&error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "sysctl: failed changing namespace"); + g_task_return_error(task, error); + return; + } + + for (value = info->values; *value; value++) { + if (!sysctl_set_internal(info->platform, info->pathid, info->dirfd, info->path, *value)) { + g_set_error(&error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "sysctl: failed setting '%s' to value '%s': %s", + info->pathid ?: info->path, + *value, + nm_strerror_native(errno)); + g_task_return_error(task, error); + return; + } + if (g_task_return_error_if_cancelled(task)) + return; + } + g_task_return_boolean(task, TRUE); +} + +static void +sysctl_set_async_return_idle(gpointer user_data, GCancellable *cancellable) +{ + gs_unref_object NMPlatform *platform = NULL; + gs_free_error GError *cancelled_error = NULL; + gs_free_error GError * error = NULL; + NMPlatformAsyncCallback callback; + gpointer callback_data; + + nm_utils_user_data_unpack(user_data, &platform, &callback, &callback_data, &error); + g_cancellable_set_error_if_cancelled(cancellable, &cancelled_error); + callback(cancelled_error ?: error, callback_data); +} + +static void +sysctl_set_async(NMPlatform * platform, + const char * pathid, + int dirfd, + const char * path, + const char *const * values, + NMPlatformAsyncCallback callback, + gpointer data, + GCancellable * cancellable) +{ + SysctlAsyncInfo *info; + GTask * task; + int dirfd_dup, errsv; + gpointer packed; + GError * error = NULL; + + g_return_if_fail(platform); + g_return_if_fail(path); + g_return_if_fail(values && values[0]); + g_return_if_fail(cancellable); + g_return_if_fail(!data || callback); + + ASSERT_SYSCTL_ARGS(pathid, dirfd, path); + + if (dirfd >= 0) { + dirfd_dup = fcntl(dirfd, F_DUPFD_CLOEXEC, 0); + if (dirfd_dup < 0) { + if (!callback) + return; + errsv = errno; + g_set_error(&error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "sysctl: failure duplicating directory fd: %s", + nm_strerror_native(errsv)); + packed = nm_utils_user_data_pack(g_object_ref(platform), callback, data, error); + nm_utils_invoke_on_idle(cancellable, sysctl_set_async_return_idle, packed); + return; + } + } else + dirfd_dup = -1; + + info = g_slice_new0(SysctlAsyncInfo); + info->platform = g_object_ref(platform); + info->pathid = g_strdup(pathid); + info->dirfd = dirfd_dup; + info->path = g_strdup(path); + info->values = g_strdupv((char **) values); + info->callback = callback; + info->callback_data = data; + info->cancellable = g_object_ref(cancellable); + + task = g_task_new(platform, cancellable, sysctl_async_cb, NULL); + g_task_set_task_data(task, info, (GDestroyNotify) sysctl_async_info_free); + g_task_set_return_on_cancel(task, FALSE); + g_task_run_in_thread(task, sysctl_async_thread_fn); + g_object_unref(task); +} + +static CList sysctl_clear_cache_lst_head = C_LIST_INIT(sysctl_clear_cache_lst_head); +static GMutex sysctl_clear_cache_lock; + +void +_nm_logging_clear_platform_logging_cache(void) +{ + NM_G_MUTEX_LOCKED(&sysctl_clear_cache_lock); + + while (TRUE) { + NMLinuxPlatformPrivate *priv; + + priv = c_list_first_entry(&sysctl_clear_cache_lst_head, + NMLinuxPlatformPrivate, + sysctl_clear_cache_lst); + if (!priv) + return; + + nm_assert(NM_IS_LINUX_PLATFORM(NM_LINUX_PLATFORM_FROM_PRIVATE(priv))); + + c_list_unlink(&priv->sysctl_clear_cache_lst); + + nm_clear_pointer(&priv->sysctl_get_prev_values, g_hash_table_destroy); + } +} + +typedef struct { + const char *path; + CList lst; + char * value; + char path_data[]; +} SysctlCacheEntry; + +static void +sysctl_cache_entry_free(SysctlCacheEntry *entry) +{ + c_list_unlink_stale(&entry->lst); + g_free(entry->value); + g_free(entry); +} + +static void +_log_dbg_sysctl_get_impl(NMPlatform *platform, const char *pathid, const char *contents) +{ + /* Note that we only have on global mutex for all NMPlatform instances. But in general + * we hardly run with concurrent threads and there are few NMPlatform instances. So + * this is acceptable. + * + * Note that there are only three functions that touch + * - sysctl_clear_cache_lst_head + * - priv->sysctl_get_prev_values + * - priv->sysctl_list + * - priv->sysctl_clear_cache_lst + * these are: + * 1) _nm_logging_clear_platform_logging_cache() + * 2) _log_dbg_sysctl_get_impl() + * 3) finalize() + * + * Note that 2) keeps the lock while also log! Logging itself may take a lock + * and it may even call back into our code again (like g_log() handlers + * and _nm_logging_clear_platform_logging_cache() which is called by logging). + * + * But in practice this is safe because logging code releases its lock before + * calling _nm_logging_clear_platform_logging_cache(). + **/ + NM_G_MUTEX_LOCKED(&sysctl_clear_cache_lock); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + SysctlCacheEntry * entry = NULL; + + if (!priv->sysctl_get_prev_values) { + c_list_link_tail(&sysctl_clear_cache_lst_head, &priv->sysctl_clear_cache_lst); + c_list_init(&priv->sysctl_list); + priv->sysctl_get_prev_values = + g_hash_table_new_full(nm_pstr_hash, + nm_pstr_equal, + (GDestroyNotify) sysctl_cache_entry_free, + NULL); + } else + entry = g_hash_table_lookup(priv->sysctl_get_prev_values, &pathid); + + if (entry) { + if (!nm_streq(entry->value, contents)) { + gs_free char *contents_escaped = g_strescape(contents, NULL); + gs_free char *prev_value_escaped = g_strescape(entry->value, NULL); + + _LOGD("sysctl: reading '%s': '%s' (changed from '%s' on last read)", + pathid, + contents_escaped, + prev_value_escaped); + g_free(entry->value); + entry->value = g_strdup(contents); + } + + nm_c_list_move_front(&priv->sysctl_list, &entry->lst); + } else { + gs_free char * contents_escaped = g_strescape(contents, NULL); + SysctlCacheEntry *old; + size_t len; + + len = strlen(pathid); + entry = g_malloc(sizeof(SysctlCacheEntry) + len + 1); + entry->value = g_strdup(contents); + entry->path = entry->path_data; + memcpy(entry->path_data, pathid, len + 1); + + /* Remove oldest entry when the cache becomes too big */ + if (g_hash_table_size(priv->sysctl_get_prev_values) > 1000u) { + old = c_list_last_entry(&priv->sysctl_list, SysctlCacheEntry, lst); + g_hash_table_remove(priv->sysctl_get_prev_values, old); + } + + _LOGD("sysctl: reading '%s': '%s'", pathid, contents_escaped); + + g_hash_table_add(priv->sysctl_get_prev_values, entry); + c_list_link_front(&priv->sysctl_list, &entry->lst); + } +} + +#define _log_dbg_sysctl_get(platform, pathid, contents) \ + G_STMT_START \ + { \ + if (_LOGD_ENABLED()) \ + _log_dbg_sysctl_get_impl(platform, pathid, contents); \ + } \ + G_STMT_END + +static char * +sysctl_get(NMPlatform *platform, const char *pathid, int dirfd, const char *path) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + GError * error = NULL; + gs_free char * contents = NULL; + + ASSERT_SYSCTL_ARGS(pathid, dirfd, path); + + if (dirfd < 0) { + if (!nm_platform_netns_push(platform, &netns)) { + errno = EBUSY; + return NULL; + } + pathid = path; + } + + if (!nm_utils_file_get_contents(dirfd, + path, + 1 * 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, + &contents, + NULL, + NULL, + &error)) { + NMLogLevel log_level = LOGL_ERR; + int errsv = EBUSY; + + if (g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { + errsv = ENOENT; + log_level = LOGL_DEBUG; + } else if (g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NODEV) + || g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_FAILED)) { + /* We assume FAILED means EOPNOTSUP and don't log a error message. */ + log_level = LOGL_DEBUG; + } + + _NMLOG(log_level, "error reading %s: %s", pathid, error->message); + g_clear_error(&error); + errno = errsv; + return NULL; + } + + g_strstrip(contents); + + _log_dbg_sysctl_get(platform, pathid, contents); + + /* errno is left undefined (as we don't return NULL). */ + return g_steal_pointer(&contents); +} + +/*****************************************************************************/ + +static void +process_events(NMPlatform *platform) +{ + delayed_action_handle_all(platform, TRUE); +} + +/*****************************************************************************/ + +static const RefreshAllInfo * +refresh_all_type_get_info(RefreshAllType refresh_all_type) +{ + static const RefreshAllInfo infos[] = { +#define R(_refresh_all_type, _obj_type, _addr_family) \ + [_refresh_all_type] = { \ + .obj_type = _obj_type, \ + .addr_family = _addr_family, \ + } + R(REFRESH_ALL_TYPE_LINKS, NMP_OBJECT_TYPE_LINK, AF_UNSPEC), + R(REFRESH_ALL_TYPE_IP4_ADDRESSES, NMP_OBJECT_TYPE_IP4_ADDRESS, AF_UNSPEC), + R(REFRESH_ALL_TYPE_IP6_ADDRESSES, NMP_OBJECT_TYPE_IP6_ADDRESS, AF_UNSPEC), + R(REFRESH_ALL_TYPE_IP4_ROUTES, NMP_OBJECT_TYPE_IP4_ROUTE, AF_UNSPEC), + R(REFRESH_ALL_TYPE_IP6_ROUTES, NMP_OBJECT_TYPE_IP6_ROUTE, AF_UNSPEC), + R(REFRESH_ALL_TYPE_ROUTING_RULES_IP4, NMP_OBJECT_TYPE_ROUTING_RULE, AF_INET), + R(REFRESH_ALL_TYPE_ROUTING_RULES_IP6, NMP_OBJECT_TYPE_ROUTING_RULE, AF_INET6), + R(REFRESH_ALL_TYPE_QDISCS, NMP_OBJECT_TYPE_QDISC, AF_UNSPEC), + R(REFRESH_ALL_TYPE_TFILTERS, NMP_OBJECT_TYPE_TFILTER, AF_UNSPEC), +#undef R + }; + + nm_assert(_NM_INT_NOT_NEGATIVE(refresh_all_type)); + nm_assert(refresh_all_type < G_N_ELEMENTS(infos)); + nm_assert(nmp_class_from_type(infos[refresh_all_type].obj_type)); + + return &infos[refresh_all_type]; +} + +static NM_UTILS_LOOKUP_DEFINE( + delayed_action_type_to_refresh_all_type, + DelayedActionType, + RefreshAllType, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT(0), + NM_UTILS_LOOKUP_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS, REFRESH_ALL_TYPE_LINKS), + NM_UTILS_LOOKUP_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES, + REFRESH_ALL_TYPE_IP4_ADDRESSES), + NM_UTILS_LOOKUP_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES, + REFRESH_ALL_TYPE_IP6_ADDRESSES), + NM_UTILS_LOOKUP_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES, REFRESH_ALL_TYPE_IP4_ROUTES), + NM_UTILS_LOOKUP_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, REFRESH_ALL_TYPE_IP6_ROUTES), + NM_UTILS_LOOKUP_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4, + REFRESH_ALL_TYPE_ROUTING_RULES_IP4), + NM_UTILS_LOOKUP_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6, + REFRESH_ALL_TYPE_ROUTING_RULES_IP6), + NM_UTILS_LOOKUP_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS, REFRESH_ALL_TYPE_QDISCS), + NM_UTILS_LOOKUP_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS, REFRESH_ALL_TYPE_TFILTERS), + NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER(), ); + +static DelayedActionType +delayed_action_type_from_refresh_all_type(RefreshAllType refresh_all_type) +{ + DelayedActionType t; + + nm_assert(refresh_all_type_get_info(refresh_all_type)); + + t = (((DelayedActionType) 1) << refresh_all_type); + + nm_assert(refresh_all_type == delayed_action_type_to_refresh_all_type(t)); + + return t; +} + +static RefreshAllType +refresh_all_type_from_needle_object(const NMPObject *obj_needle) +{ + switch (NMP_OBJECT_GET_TYPE(obj_needle)) { + case NMP_OBJECT_TYPE_LINK: + return REFRESH_ALL_TYPE_LINKS; + case NMP_OBJECT_TYPE_IP4_ADDRESS: + return REFRESH_ALL_TYPE_IP4_ADDRESSES; + case NMP_OBJECT_TYPE_IP6_ADDRESS: + return REFRESH_ALL_TYPE_IP6_ADDRESSES; + case NMP_OBJECT_TYPE_IP4_ROUTE: + return REFRESH_ALL_TYPE_IP4_ROUTES; + case NMP_OBJECT_TYPE_IP6_ROUTE: + return REFRESH_ALL_TYPE_IP6_ROUTES; + case NMP_OBJECT_TYPE_QDISC: + return REFRESH_ALL_TYPE_QDISCS; + case NMP_OBJECT_TYPE_TFILTER: + return REFRESH_ALL_TYPE_TFILTERS; + case NMP_OBJECT_TYPE_ROUTING_RULE: + switch (NMP_OBJECT_CAST_ROUTING_RULE(obj_needle)->addr_family) { + case AF_INET: + return REFRESH_ALL_TYPE_ROUTING_RULES_IP4; + case AF_INET6: + return REFRESH_ALL_TYPE_ROUTING_RULES_IP6; + } + nm_assert_not_reached(); + return 0; + default: + nm_assert_not_reached(); + return 0; + } +} + +static const NMPLookup * +refresh_all_type_init_lookup(RefreshAllType refresh_all_type, NMPLookup *lookup) +{ + const RefreshAllInfo *refresh_all_info; + + nm_assert(lookup); + + refresh_all_info = refresh_all_type_get_info(refresh_all_type); + + nm_assert(refresh_all_info); + + if (NM_IN_SET(refresh_all_info->obj_type, NMP_OBJECT_TYPE_ROUTING_RULE)) { + return nmp_lookup_init_object_by_addr_family(lookup, + refresh_all_info->obj_type, + refresh_all_info->addr_family); + } + + /* not yet implemented. */ + nm_assert(refresh_all_info->addr_family == AF_UNSPEC); + + return nmp_lookup_init_obj_type(lookup, refresh_all_info->obj_type); +} + +static DelayedActionType +delayed_action_refresh_from_needle_object(const NMPObject *obj_needle) +{ + return delayed_action_type_from_refresh_all_type( + refresh_all_type_from_needle_object(obj_needle)); +} + +static NM_UTILS_LOOKUP_STR_DEFINE( + delayed_action_to_string, + DelayedActionType, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS, "refresh-all-links"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES, + "refresh-all-ip4-addresses"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES, + "refresh-all-ip6-addresses"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES, "refresh-all-ip4-routes"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, "refresh-all-ip6-routes"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP4, + "refresh-all-routing-rules-ip4"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_IP6, + "refresh-all-routing-rules-ip6"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS, "refresh-all-qdiscs"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS, "refresh-all-tfilters"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_REFRESH_LINK, "refresh-link"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_MASTER_CONNECTED, "master-connected"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_READ_NETLINK, "read-netlink"), + NM_UTILS_LOOKUP_STR_ITEM(DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE, "wait-for-nl-response"), + NM_UTILS_LOOKUP_ITEM_IGNORE(DELAYED_ACTION_TYPE_NONE), + NM_UTILS_LOOKUP_ITEM_IGNORE(DELAYED_ACTION_TYPE_REFRESH_ALL), + NM_UTILS_LOOKUP_ITEM_IGNORE(DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_ALL), + NM_UTILS_LOOKUP_ITEM_IGNORE(__DELAYED_ACTION_TYPE_MAX), ); + +static const char * +delayed_action_to_string_full(DelayedActionType action_type, + gpointer user_data, + char * buf, + gsize buf_size) +{ + char * buf0 = buf; + const DelayedActionWaitForNlResponseData *data; + + nm_utils_strbuf_append_str(&buf, &buf_size, delayed_action_to_string(action_type)); + switch (action_type) { + case DELAYED_ACTION_TYPE_MASTER_CONNECTED: + nm_utils_strbuf_append(&buf, &buf_size, " (master-ifindex %d)", GPOINTER_TO_INT(user_data)); + break; + case DELAYED_ACTION_TYPE_REFRESH_LINK: + nm_utils_strbuf_append(&buf, &buf_size, " (ifindex %d)", GPOINTER_TO_INT(user_data)); + break; + case DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE: + data = user_data; + + if (data) { + gint64 timeout = data->timeout_abs_ns - nm_utils_get_monotonic_timestamp_nsec(); + char b[255]; + + nm_utils_strbuf_append( + &buf, + &buf_size, + " (seq %u, timeout in %s%" G_GINT64_FORMAT ".%09" G_GINT64_FORMAT + ", response-type %d%s%s)", + data->seq_number, + timeout < 0 ? "-" : "", + (timeout < 0 ? -timeout : timeout) / NM_UTILS_NSEC_PER_SEC, + (timeout < 0 ? -timeout : timeout) % NM_UTILS_NSEC_PER_SEC, + (int) data->response_type, + data->seq_result ? ", " : "", + data->seq_result + ? wait_for_nl_response_to_string(data->seq_result, NULL, b, sizeof(b)) + : ""); + } else + nm_utils_strbuf_append_str(&buf, &buf_size, " (any)"); + break; + default: + nm_assert(!user_data); + break; + } + return buf0; +} + +#define _LOGt_delayed_action(action_type, user_data, operation) \ + G_STMT_START \ + { \ + char _buf[255]; \ + \ + _LOGt("delayed-action: %s %s", \ + "" operation, \ + delayed_action_to_string_full(action_type, user_data, _buf, sizeof(_buf))); \ + } \ + G_STMT_END + +/*****************************************************************************/ + +static gboolean +delayed_action_refresh_all_in_progress(NMPlatform *platform, DelayedActionType action_type) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + RefreshAllType refresh_all_type; + + nm_assert(nm_utils_is_power_of_two(action_type)); + nm_assert(NM_FLAGS_ANY(action_type, DELAYED_ACTION_TYPE_REFRESH_ALL)); + nm_assert(!NM_FLAGS_ANY(action_type, ~DELAYED_ACTION_TYPE_REFRESH_ALL)); + + if (NM_FLAGS_ANY(priv->delayed_action.flags, action_type)) + return TRUE; + + refresh_all_type = delayed_action_type_to_refresh_all_type(action_type); + return (priv->delayed_action.refresh_all_in_progress[refresh_all_type] > 0); +} + +static void +delayed_action_wait_for_nl_response_complete(NMPlatform * platform, + guint idx, + WaitForNlResponseResult seq_result) +{ + NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + DelayedActionWaitForNlResponseData *data; + + nm_assert(NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)); + nm_assert(idx < priv->delayed_action.list_wait_for_nl_response->len); + nm_assert(seq_result); + + data = &g_array_index(priv->delayed_action.list_wait_for_nl_response, + DelayedActionWaitForNlResponseData, + idx); + + _LOGt_delayed_action(DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE, data, "complete"); + + if (priv->delayed_action.list_wait_for_nl_response->len <= 1) + priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE; + if (data->out_seq_result) + *data->out_seq_result = seq_result; + switch (data->response_type) { + case DELAYED_ACTION_RESPONSE_TYPE_VOID: + break; + case DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS: + if (data->response.out_refresh_all_in_progress) { + nm_assert(*data->response.out_refresh_all_in_progress > 0); + *data->response.out_refresh_all_in_progress -= 1; + data->response.out_refresh_all_in_progress = NULL; + } + break; + case DELAYED_ACTION_RESPONSE_TYPE_ROUTE_GET: + if (data->response.out_route_get) { + nm_assert(!*data->response.out_route_get); + data->response.out_route_get = NULL; + } + break; + } + + g_array_remove_index_fast(priv->delayed_action.list_wait_for_nl_response, idx); +} + +static void +delayed_action_wait_for_nl_response_complete_check(NMPlatform * platform, + WaitForNlResponseResult force_result, + guint32 * out_next_seq_number, + gint64 * out_next_timeout_abs_ns, + gint64 * p_now_ns) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + guint i; + guint32 next_seq_number = 0; + gint64 next_timeout_abs_ns = 0; + int now_ns = 0; + + for (i = 0; i < priv->delayed_action.list_wait_for_nl_response->len;) { + const DelayedActionWaitForNlResponseData *data = + &g_array_index(priv->delayed_action.list_wait_for_nl_response, + DelayedActionWaitForNlResponseData, + i); + + if (data->seq_result) + delayed_action_wait_for_nl_response_complete(platform, i, data->seq_result); + else if (p_now_ns + && ((now_ns ?: (now_ns = nm_utils_get_monotonic_timestamp_nsec())) + >= data->timeout_abs_ns)) { + /* the caller can optionally check for timeout by providing a p_now_ns argument. */ + delayed_action_wait_for_nl_response_complete( + platform, + i, + WAIT_FOR_NL_RESPONSE_RESULT_FAILED_TIMEOUT); + } else if (force_result != WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN) + delayed_action_wait_for_nl_response_complete(platform, i, force_result); + else { + if (next_seq_number == 0 || next_timeout_abs_ns > data->timeout_abs_ns) { + next_seq_number = data->seq_number; + next_timeout_abs_ns = data->timeout_abs_ns; + } + i++; + } + } + + if (force_result != WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN) { + nm_assert( + !NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)); + nm_assert(priv->delayed_action.list_wait_for_nl_response->len == 0); + } + + NM_SET_OUT(out_next_seq_number, next_seq_number); + NM_SET_OUT(out_next_timeout_abs_ns, next_timeout_abs_ns); + NM_SET_OUT(p_now_ns, now_ns); +} + +static void +delayed_action_wait_for_nl_response_complete_all(NMPlatform * platform, + WaitForNlResponseResult fallback_result) +{ + delayed_action_wait_for_nl_response_complete_check(platform, fallback_result, NULL, NULL, NULL); +} + +/*****************************************************************************/ + +static void +delayed_action_handle_MASTER_CONNECTED(NMPlatform *platform, int master_ifindex) +{ + nm_auto_nmpobj const NMPObject *obj_old = NULL; + nm_auto_nmpobj const NMPObject *obj_new = NULL; + NMPCacheOpsType cache_op; + + cache_op = nmp_cache_update_link_master_connected(nm_platform_get_cache(platform), + master_ifindex, + &obj_old, + &obj_new); + if (cache_op == NMP_CACHE_OPS_UNCHANGED) + return; + cache_on_change(platform, cache_op, obj_old, obj_new); + nm_platform_cache_update_emit_signal(platform, cache_op, obj_old, obj_new); +} + +static void +delayed_action_handle_REFRESH_LINK(NMPlatform *platform, int ifindex) +{ + do_request_link_no_delayed_actions(platform, ifindex, NULL); +} + +static void +delayed_action_handle_REFRESH_ALL(NMPlatform *platform, DelayedActionType flags) +{ + do_request_all_no_delayed_actions(platform, flags); +} + +static void +delayed_action_handle_READ_NETLINK(NMPlatform *platform) +{ + event_handler_read_netlink(platform, FALSE); +} + +static void +delayed_action_handle_WAIT_FOR_NL_RESPONSE(NMPlatform *platform) +{ + event_handler_read_netlink(platform, TRUE); +} + +static gboolean +delayed_action_handle_one(NMPlatform *platform) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + gpointer user_data; + + if (priv->delayed_action.flags == DELAYED_ACTION_TYPE_NONE) + return FALSE; + + /* First process DELAYED_ACTION_TYPE_MASTER_CONNECTED actions. + * This type of action is entirely cache-internal and is here to resolve a + * cache inconsistency. It should be fixed right away. */ + if (NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_MASTER_CONNECTED)) { + nm_assert(priv->delayed_action.list_master_connected->len > 0); + + user_data = priv->delayed_action.list_master_connected->pdata[0]; + g_ptr_array_remove_index_fast(priv->delayed_action.list_master_connected, 0); + if (priv->delayed_action.list_master_connected->len == 0) + priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_MASTER_CONNECTED; + nm_assert(nm_utils_ptrarray_find_first( + (gconstpointer *) priv->delayed_action.list_master_connected->pdata, + priv->delayed_action.list_master_connected->len, + user_data) + < 0); + + _LOGt_delayed_action(DELAYED_ACTION_TYPE_MASTER_CONNECTED, user_data, "handle"); + delayed_action_handle_MASTER_CONNECTED(platform, GPOINTER_TO_INT(user_data)); + return TRUE; + } + nm_assert(priv->delayed_action.list_master_connected->len == 0); + + /* Next we prefer read-netlink, because the buffer size is limited and we want to process events + * from netlink early. */ + if (NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_READ_NETLINK)) { + _LOGt_delayed_action(DELAYED_ACTION_TYPE_READ_NETLINK, NULL, "handle"); + priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_READ_NETLINK; + delayed_action_handle_READ_NETLINK(platform); + return TRUE; + } + + if (NM_FLAGS_ANY(priv->delayed_action.flags, DELAYED_ACTION_TYPE_REFRESH_ALL)) { + DelayedActionType flags, iflags; + + flags = priv->delayed_action.flags & DELAYED_ACTION_TYPE_REFRESH_ALL; + + priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_ALL; + + if (_LOGt_ENABLED()) { + FOR_EACH_DELAYED_ACTION(iflags, flags) + _LOGt_delayed_action(iflags, NULL, "handle"); + } + + delayed_action_handle_REFRESH_ALL(platform, flags); + return TRUE; + } + + if (NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_REFRESH_LINK)) { + nm_assert(priv->delayed_action.list_refresh_link->len > 0); + + user_data = priv->delayed_action.list_refresh_link->pdata[0]; + g_ptr_array_remove_index_fast(priv->delayed_action.list_refresh_link, 0); + if (priv->delayed_action.list_refresh_link->len == 0) + priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK; + nm_assert(nm_utils_ptrarray_find_first( + (gconstpointer *) priv->delayed_action.list_refresh_link->pdata, + priv->delayed_action.list_refresh_link->len, + user_data) + < 0); + + _LOGt_delayed_action(DELAYED_ACTION_TYPE_REFRESH_LINK, user_data, "handle"); + + delayed_action_handle_REFRESH_LINK(platform, GPOINTER_TO_INT(user_data)); + + return TRUE; + } + + if (NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) { + nm_assert(priv->delayed_action.list_wait_for_nl_response->len > 0); + _LOGt_delayed_action(DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE, NULL, "handle"); + delayed_action_handle_WAIT_FOR_NL_RESPONSE(platform); + return TRUE; + } + + return FALSE; +} + +static gboolean +delayed_action_handle_all(NMPlatform *platform, gboolean read_netlink) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + gboolean any = FALSE; + + g_return_val_if_fail(priv->delayed_action.is_handling == 0, FALSE); + + priv->delayed_action.is_handling++; + if (read_netlink) + delayed_action_schedule(platform, DELAYED_ACTION_TYPE_READ_NETLINK, NULL); + while (delayed_action_handle_one(platform)) + any = TRUE; + priv->delayed_action.is_handling--; + + cache_prune_all(platform); + + return any; +} + +static void +delayed_action_schedule(NMPlatform *platform, DelayedActionType action_type, gpointer user_data) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + DelayedActionType iflags; + + nm_assert(action_type != DELAYED_ACTION_TYPE_NONE); + + switch (action_type) { + case DELAYED_ACTION_TYPE_REFRESH_LINK: + if (nm_utils_ptrarray_find_first( + (gconstpointer *) priv->delayed_action.list_refresh_link->pdata, + priv->delayed_action.list_refresh_link->len, + user_data) + < 0) + g_ptr_array_add(priv->delayed_action.list_refresh_link, user_data); + break; + case DELAYED_ACTION_TYPE_MASTER_CONNECTED: + if (nm_utils_ptrarray_find_first( + (gconstpointer *) priv->delayed_action.list_master_connected->pdata, + priv->delayed_action.list_master_connected->len, + user_data) + < 0) + g_ptr_array_add(priv->delayed_action.list_master_connected, user_data); + break; + case DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE: + g_array_append_vals(priv->delayed_action.list_wait_for_nl_response, user_data, 1); + break; + default: + nm_assert(!user_data); + nm_assert(!NM_FLAGS_HAS(action_type, DELAYED_ACTION_TYPE_REFRESH_LINK)); + nm_assert(!NM_FLAGS_HAS(action_type, DELAYED_ACTION_TYPE_MASTER_CONNECTED)); + nm_assert(!NM_FLAGS_HAS(action_type, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)); + break; + } + + priv->delayed_action.flags |= action_type; + + if (_LOGt_ENABLED()) { + FOR_EACH_DELAYED_ACTION(iflags, action_type) + _LOGt_delayed_action(iflags, user_data, "schedule"); + } +} + +static void +delayed_action_schedule_WAIT_FOR_NL_RESPONSE(NMPlatform * platform, + guint32 seq_number, + WaitForNlResponseResult * out_seq_result, + char ** out_errmsg, + DelayedActionWaitForNlResponseType response_type, + gpointer response_out_data) +{ + DelayedActionWaitForNlResponseData data = { + .seq_number = seq_number, + .timeout_abs_ns = + nm_utils_get_monotonic_timestamp_nsec() + (200 * (NM_UTILS_NSEC_PER_SEC / 1000)), + .out_seq_result = out_seq_result, + .out_errmsg = out_errmsg, + .response_type = response_type, + .response.out_data = response_out_data, + }; + + delayed_action_schedule(platform, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE, &data); +} + +/*****************************************************************************/ + +static void +cache_prune_one_type(NMPlatform *platform, const NMPLookup *lookup) +{ + NMDedupMultiIter iter; + const NMPObject *obj; + NMPCacheOpsType cache_op; + NMPCache * cache = nm_platform_get_cache(platform); + + nm_dedup_multi_iter_init(&iter, nmp_cache_lookup(cache, lookup)); + while (nm_dedup_multi_iter_next(&iter)) { + const NMDedupMultiEntry *main_entry; + + /* we only track the dirty flag for the OBJECT-TYPE index. That means, + * for other lookup types we need to check the dirty flag of the main-entry. */ + main_entry = nmp_cache_reresolve_main_entry(cache, iter.current, lookup); + if (!main_entry->dirty) + continue; + + obj = main_entry->obj; + + _LOGt("cache-prune: prune %s", + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_ALL, NULL, 0)); + + { + nm_auto_nmpobj const NMPObject *obj_old = NULL; + + cache_op = nmp_cache_remove(cache, obj, TRUE, TRUE, &obj_old); + nm_assert(cache_op == NMP_CACHE_OPS_REMOVED); + cache_on_change(platform, cache_op, obj_old, NULL); + nm_platform_cache_update_emit_signal(platform, cache_op, obj_old, NULL); + } + } +} + +static void +cache_prune_all(NMPlatform *platform) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + RefreshAllType refresh_all_type; + + for (refresh_all_type = _REFRESH_ALL_TYPE_FIRST; refresh_all_type < _REFRESH_ALL_TYPE_NUM; + refresh_all_type++) { + NMPLookup lookup; + + if (priv->pruning[refresh_all_type] == 0) + continue; + priv->pruning[refresh_all_type] -= 1; + if (priv->pruning[refresh_all_type] > 0) + continue; + refresh_all_type_init_lookup(refresh_all_type, &lookup); + cache_prune_one_type(platform, &lookup); + } +} + +static void +cache_on_change(NMPlatform * platform, + NMPCacheOpsType cache_op, + const NMPObject *obj_old, + const NMPObject *obj_new) +{ + const NMPClass *klass; + char str_buf[sizeof(_nm_utils_to_string_buffer)]; + char str_buf2[sizeof(_nm_utils_to_string_buffer)]; + NMPCache * cache = nm_platform_get_cache(platform); + + ASSERT_nmp_cache_ops(cache, cache_op, obj_old, obj_new); + nm_assert(cache_op != NMP_CACHE_OPS_UNCHANGED); + + klass = obj_old ? NMP_OBJECT_GET_CLASS(obj_old) : NMP_OBJECT_GET_CLASS(obj_new); + + _LOGt( + "update-cache-%s: %s: %s%s%s", + klass->obj_type_name, + (cache_op == NMP_CACHE_OPS_UPDATED ? "UPDATE" + : (cache_op == NMP_CACHE_OPS_REMOVED ? "REMOVE" + : (cache_op == NMP_CACHE_OPS_ADDED) ? "ADD" + : "???")), + (cache_op != NMP_CACHE_OPS_ADDED + ? nmp_object_to_string(obj_old, NMP_OBJECT_TO_STRING_ALL, str_buf2, sizeof(str_buf2)) + : nmp_object_to_string(obj_new, NMP_OBJECT_TO_STRING_ALL, str_buf2, sizeof(str_buf2))), + (cache_op == NMP_CACHE_OPS_UPDATED) ? " -> " : "", + (cache_op == NMP_CACHE_OPS_UPDATED + ? nmp_object_to_string(obj_new, NMP_OBJECT_TO_STRING_ALL, str_buf, sizeof(str_buf)) + : "")); + + switch (klass->obj_type) { + case NMP_OBJECT_TYPE_LINK: + { + /* check whether changing a slave link can cause a master link (bridge or bond) to go up/down */ + if (obj_old + && nmp_cache_link_connected_needs_toggle_by_ifindex(cache, + obj_old->link.master, + obj_new, + obj_old)) + delayed_action_schedule(platform, + DELAYED_ACTION_TYPE_MASTER_CONNECTED, + GINT_TO_POINTER(obj_old->link.master)); + if (obj_new && (!obj_old || obj_old->link.master != obj_new->link.master) + && nmp_cache_link_connected_needs_toggle_by_ifindex(cache, + obj_new->link.master, + obj_new, + obj_old)) + delayed_action_schedule(platform, + DELAYED_ACTION_TYPE_MASTER_CONNECTED, + GINT_TO_POINTER(obj_new->link.master)); + } + { + /* check whether we are about to change a master link that needs toggling connected state. */ + if (obj_new /* <-- nonsensical, make coverity happy */ + && nmp_cache_link_connected_needs_toggle(cache, obj_new, obj_new, obj_old)) + delayed_action_schedule(platform, + DELAYED_ACTION_TYPE_MASTER_CONNECTED, + GINT_TO_POINTER(obj_new->link.ifindex)); + } + { + int ifindex = 0; + + /* if we remove a link (from netlink), we must refresh the addresses, routes, qdiscs and tfilters */ + if (cache_op == NMP_CACHE_OPS_REMOVED + && obj_old /* <-- nonsensical, make coverity happy */) + ifindex = obj_old->link.ifindex; + else if (cache_op == NMP_CACHE_OPS_UPDATED && obj_old + && obj_new /* <-- nonsensical, make coverity happy */ + && !obj_new->_link.netlink.is_in_netlink + && obj_new->_link.netlink.is_in_netlink + != obj_old->_link.netlink.is_in_netlink) + ifindex = obj_new->link.ifindex; + + if (ifindex > 0) { + delayed_action_schedule(platform, + DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES + | DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_ALL + | DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS + | DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS, + NULL); + } + } + { + int ifindex = -1; + + /* removal of a link could be caused by moving the link to another netns. + * In this case, we potentially have to update other links that have this link as parent. + * Currently, kernel misses to sent us a notification in this case + * (https://bugzilla.redhat.com/show_bug.cgi?id=1262908). */ + + if (cache_op == NMP_CACHE_OPS_REMOVED + && obj_old /* <-- nonsensical, make coverity happy */ + && obj_old->_link.netlink.is_in_netlink) + ifindex = obj_old->link.ifindex; + else if (cache_op == NMP_CACHE_OPS_UPDATED && obj_old + && obj_new /* <-- nonsensical, make coverity happy */ + && obj_old->_link.netlink.is_in_netlink + && !obj_new->_link.netlink.is_in_netlink) + ifindex = obj_new->link.ifindex; + + if (ifindex > 0) { + NMPLookup lookup; + NMDedupMultiIter iter; + const NMPlatformLink *l; + + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK); + nmp_cache_iter_for_each_link (&iter, nmp_cache_lookup(cache, &lookup), &l) { + if (l->parent == ifindex) + delayed_action_schedule(platform, + DELAYED_ACTION_TYPE_REFRESH_LINK, + GINT_TO_POINTER(l->ifindex)); + } + } + } + { + /* if a link goes down, we must refresh routes */ + if (cache_op == NMP_CACHE_OPS_UPDATED && obj_old + && obj_new /* <-- nonsensical, make coverity happy */ + && obj_old->_link.netlink.is_in_netlink && obj_new->_link.netlink.is_in_netlink + && ((NM_FLAGS_HAS(obj_old->link.n_ifi_flags, IFF_UP) + && !NM_FLAGS_HAS(obj_new->link.n_ifi_flags, IFF_UP)) + || (NM_FLAGS_HAS(obj_old->link.n_ifi_flags, IFF_LOWER_UP) + && !NM_FLAGS_HAS(obj_new->link.n_ifi_flags, IFF_LOWER_UP)))) { + /* FIXME: I suspect that IFF_LOWER_UP must not be considered, and I + * think kernel does send RTM_DELROUTE events for IPv6 routes, so + * we might not need to refresh IPv6 routes. */ + delayed_action_schedule(platform, + DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, + NULL); + } + } + if (NM_IN_SET(cache_op, NMP_CACHE_OPS_ADDED, NMP_CACHE_OPS_UPDATED) + && (obj_new && obj_new->_link.netlink.is_in_netlink) + && (!obj_old || !obj_old->_link.netlink.is_in_netlink)) { + gboolean re_request_link = FALSE; + const NMPlatformLnkTun *lnk_tun; + + if (!obj_new->_link.netlink.lnk + && NM_IN_SET(obj_new->link.type, + NM_LINK_TYPE_GRE, + NM_LINK_TYPE_GRETAP, + NM_LINK_TYPE_IP6TNL, + NM_LINK_TYPE_IP6GRE, + NM_LINK_TYPE_IP6GRETAP, + NM_LINK_TYPE_INFINIBAND, + NM_LINK_TYPE_MACVLAN, + NM_LINK_TYPE_MACVLAN, + NM_LINK_TYPE_SIT, + NM_LINK_TYPE_TUN, + NM_LINK_TYPE_VLAN, + NM_LINK_TYPE_VXLAN)) { + /* certain link-types also come with a IFLA_INFO_DATA/lnk_data. It may happen that + * kernel didn't send this notification, thus when we first learn about a link + * that lacks an lnk_data we re-request it again. + * + * For example https://bugzilla.redhat.com/show_bug.cgi?id=1284001 */ + re_request_link = TRUE; + } else if (obj_new->link.type == NM_LINK_TYPE_TUN && obj_new->_link.netlink.lnk + && (lnk_tun = &(obj_new->_link.netlink.lnk)->lnk_tun) && !lnk_tun->persist + && lnk_tun->pi && !lnk_tun->vnet_hdr && !lnk_tun->multi_queue + && !lnk_tun->owner_valid && !lnk_tun->group_valid) { + /* kernel has/had a know issue that the first notification for TUN device would + * be sent with invalid parameters. The message looks like that kind, so refetch + * it. */ + re_request_link = TRUE; + } else if (obj_new->link.type == NM_LINK_TYPE_VETH && obj_new->link.parent == 0) { + /* the initial notification when adding a veth pair can lack the parent/IFLA_LINK + * (https://bugzilla.redhat.com/show_bug.cgi?id=1285827). + * Request it again. */ + re_request_link = TRUE; + } else if (obj_new->link.type == NM_LINK_TYPE_ETHERNET + && obj_new->link.l_address.len == 0) { + /* Due to a kernel bug, we sometimes receive spurious NEWLINK + * messages after a wifi interface has disappeared. Since the + * link is not present anymore we can't determine its type and + * thus it will show up as a Ethernet one, with no address + * specified. Request the link again to check if it really + * exists. https://bugzilla.redhat.com/show_bug.cgi?id=1302037 + */ + re_request_link = TRUE; + } + if (re_request_link) { + delayed_action_schedule(platform, + DELAYED_ACTION_TYPE_REFRESH_LINK, + GINT_TO_POINTER(obj_new->link.ifindex)); + } + } + { + /* on enslave/release, we also refresh the master. */ + int ifindex1 = 0, ifindex2 = 0; + gboolean changed_master, changed_connected; + + changed_master = + (obj_new && obj_new->_link.netlink.is_in_netlink && obj_new->link.master > 0 + ? obj_new->link.master + : 0) + != (obj_old && obj_old->_link.netlink.is_in_netlink && obj_old->link.master > 0 + ? obj_old->link.master + : 0); + changed_connected = (obj_new && obj_new->_link.netlink.is_in_netlink + ? NM_FLAGS_HAS(obj_new->link.n_ifi_flags, IFF_LOWER_UP) + : 2) + != (obj_old && obj_old->_link.netlink.is_in_netlink + ? NM_FLAGS_HAS(obj_old->link.n_ifi_flags, IFF_LOWER_UP) + : 2); + + if (changed_master || changed_connected) { + ifindex1 = + (obj_old && obj_old->_link.netlink.is_in_netlink && obj_old->link.master > 0) + ? obj_old->link.master + : 0; + ifindex2 = + (obj_new && obj_new->_link.netlink.is_in_netlink && obj_new->link.master > 0) + ? obj_new->link.master + : 0; + + if (ifindex1 > 0) + delayed_action_schedule(platform, + DELAYED_ACTION_TYPE_REFRESH_LINK, + GINT_TO_POINTER(ifindex1)); + if (ifindex2 > 0 && ifindex1 != ifindex2) + delayed_action_schedule(platform, + DELAYED_ACTION_TYPE_REFRESH_LINK, + GINT_TO_POINTER(ifindex2)); + } + } + break; + case NMP_OBJECT_TYPE_IP4_ADDRESS: + case NMP_OBJECT_TYPE_IP6_ADDRESS: + { + /* Address deletion is sometimes accompanied by route deletion. We need to + * check all routes belonging to the same interface. */ + if (cache_op == NMP_CACHE_OPS_REMOVED) { + delayed_action_schedule(platform, + (klass->obj_type == NMP_OBJECT_TYPE_IP4_ADDRESS) + ? DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES + : DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, + NULL); + } + } break; + default: + break; + } +} + +/*****************************************************************************/ + +static guint32 +_nlh_seq_next_get(NMLinuxPlatformPrivate *priv) +{ + /* generate a new sequence number, but never return zero. + * Wrapping numbers are not a problem, because we don't rely + * on strictly increasing sequence numbers. */ + return (++priv->nlh_seq_next) ?: (++priv->nlh_seq_next); +} + +/** + * _nl_send_nlmsghdr: + * @platform: + * @nlhdr: + * @out_seq_result: + * @response_type: + * @response_out_data: + * + * Returns: 0 on success or a negative errno. + */ +static int +_nl_send_nlmsghdr(NMPlatform * platform, + struct nlmsghdr * nlhdr, + WaitForNlResponseResult * out_seq_result, + char ** out_errmsg, + DelayedActionWaitForNlResponseType response_type, + gpointer response_out_data) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + guint32 seq; + int errsv; + + nm_assert(nlhdr); + + seq = _nlh_seq_next_get(priv); + nlhdr->nlmsg_seq = seq; + + { + struct sockaddr_nl nladdr = { + .nl_family = AF_NETLINK, + }; + struct iovec iov = {.iov_base = nlhdr, .iov_len = nlhdr->nlmsg_len}; + struct msghdr msg = { + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + int try_count; + + if (!nlhdr->nlmsg_pid) + nlhdr->nlmsg_pid = nl_socket_get_local_port(priv->nlh); + nlhdr->nlmsg_flags |= (NLM_F_REQUEST | NLM_F_ACK); + + try_count = 0; +again: + errsv = sendmsg(nl_socket_get_fd(priv->nlh), &msg, 0); + if (errsv < 0) { + errsv = errno; + if (errsv == EINTR && try_count++ < 100) + goto again; + _LOGD("netlink: nl-send-nlmsghdr: failed sending message: %s (%d)", + nm_strerror_native(errsv), + errsv); + return -nm_errno_from_native(errsv); + } + } + + delayed_action_schedule_WAIT_FOR_NL_RESPONSE(platform, + seq, + out_seq_result, + out_errmsg, + response_type, + response_out_data); + return 0; +} + +/** + * _nl_send_nlmsg: + * @platform: + * @nlmsg: + * @out_seq_result: + * @response_type: + * @response_out_data: + * + * Returns: 0 on success, or a negative libnl3 error code (beware, it's not an errno). + */ +static int +_nl_send_nlmsg(NMPlatform * platform, + struct nl_msg * nlmsg, + WaitForNlResponseResult * out_seq_result, + char ** out_errmsg, + DelayedActionWaitForNlResponseType response_type, + gpointer response_out_data) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + struct nlmsghdr * nlhdr; + guint32 seq; + int nle; + + nlhdr = nlmsg_hdr(nlmsg); + seq = _nlh_seq_next_get(priv); + nlhdr->nlmsg_seq = seq; + + nle = nl_send_auto(priv->nlh, nlmsg); + if (nle < 0) { + _LOGD("netlink: nl-send-nlmsg: failed sending message: %s (%d)", nm_strerror(nle), nle); + return nle; + } + + delayed_action_schedule_WAIT_FOR_NL_RESPONSE(platform, + seq, + out_seq_result, + out_errmsg, + response_type, + response_out_data); + return 0; +} + +static void +do_request_link_no_delayed_actions(NMPlatform *platform, int ifindex, const char *name) +{ + NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + int nle; + + if (name && !name[0]) + name = NULL; + + g_return_if_fail(ifindex > 0 || name); + + _LOGD("do-request-link: %d %s", ifindex, name ?: ""); + + if (ifindex > 0) { + const NMDedupMultiEntry *entry; + + entry = nmp_cache_lookup_entry_link(nm_platform_get_cache(platform), ifindex); + if (entry) { + priv->pruning[REFRESH_ALL_TYPE_LINKS] += 1; + nm_dedup_multi_entry_set_dirty(entry, TRUE); + } + } + + event_handler_read_netlink(platform, FALSE); + + nlmsg = _nl_msg_new_link(RTM_GETLINK, 0, ifindex, name); + if (nlmsg) { + nle = _nl_send_nlmsg(platform, nlmsg, NULL, NULL, DELAYED_ACTION_RESPONSE_TYPE_VOID, NULL); + if (nle < 0) { + _LOGE("do-request-link: %d %s: failed sending netlink request \"%s\" (%d)", + ifindex, + name ?: "", + nm_strerror(nle), + -nle); + return; + } + } +} + +static void +do_request_link(NMPlatform *platform, int ifindex, const char *name) +{ + do_request_link_no_delayed_actions(platform, ifindex, name); + delayed_action_handle_all(platform, FALSE); +} + +static struct nl_msg * +_nl_msg_new_dump(NMPObjectType obj_type, int preferred_addr_family) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + const NMPClass * klass; + + klass = nmp_class_from_type(obj_type); + + nm_assert(klass); + nm_assert(klass->rtm_gettype > 0); + + nlmsg = nlmsg_alloc_simple(klass->rtm_gettype, NLM_F_DUMP); + + if (klass->addr_family != AF_UNSPEC) { + /* if the class specifies a particular address family, then it is preferred. */ + nm_assert(NM_IN_SET(preferred_addr_family, AF_UNSPEC, klass->addr_family)); + preferred_addr_family = klass->addr_family; + } + + switch (klass->obj_type) { + case NMP_OBJECT_TYPE_QDISC: + case NMP_OBJECT_TYPE_TFILTER: + { + const struct tcmsg tcmsg = { + .tcm_family = preferred_addr_family, + }; + + if (nlmsg_append_struct(nlmsg, &tcmsg) < 0) + g_return_val_if_reached(NULL); + } break; + case NMP_OBJECT_TYPE_LINK: + case NMP_OBJECT_TYPE_IP4_ADDRESS: + case NMP_OBJECT_TYPE_IP6_ADDRESS: + case NMP_OBJECT_TYPE_IP4_ROUTE: + case NMP_OBJECT_TYPE_IP6_ROUTE: + case NMP_OBJECT_TYPE_ROUTING_RULE: + { + const struct rtgenmsg gmsg = { + .rtgen_family = preferred_addr_family, + }; + + if (nlmsg_append_struct(nlmsg, &gmsg) < 0) + g_return_val_if_reached(NULL); + } break; + default: + g_return_val_if_reached(NULL); + } + + return g_steal_pointer(&nlmsg); +} + +static void +do_request_all_no_delayed_actions(NMPlatform *platform, DelayedActionType action_type) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + DelayedActionType action_type_prune; + DelayedActionType iflags; + + nm_assert(!NM_FLAGS_ANY(action_type, ~DELAYED_ACTION_TYPE_REFRESH_ALL)); + action_type &= DELAYED_ACTION_TYPE_REFRESH_ALL; + + action_type_prune = action_type; + + /* calling nmp_cache_dirty_set_all_main() with a non-main lookup-index requires an extra + * cache lookup for every entry. + * + * Avoid that, by special casing routing-rules here. */ + if (NM_FLAGS_ALL(action_type_prune, DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_ALL)) { + NMPLookup lookup; + + priv->pruning[REFRESH_ALL_TYPE_ROUTING_RULES_IP4] += 1; + priv->pruning[REFRESH_ALL_TYPE_ROUTING_RULES_IP6] += 1; + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); + nmp_cache_dirty_set_all_main(nm_platform_get_cache(platform), &lookup); + action_type_prune &= ~DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_ALL; + } + + FOR_EACH_DELAYED_ACTION(iflags, action_type_prune) + { + RefreshAllType refresh_all_type = delayed_action_type_to_refresh_all_type(iflags); + NMPLookup lookup; + + priv->pruning[refresh_all_type] += 1; + refresh_all_type_init_lookup(refresh_all_type, &lookup); + nmp_cache_dirty_set_all_main(nm_platform_get_cache(platform), &lookup); + } + + FOR_EACH_DELAYED_ACTION(iflags, action_type) + { + RefreshAllType refresh_all_type = delayed_action_type_to_refresh_all_type(iflags); + const RefreshAllInfo *refresh_all_info = refresh_all_type_get_info(refresh_all_type); + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + int * out_refresh_all_in_progress; + + out_refresh_all_in_progress = + &priv->delayed_action.refresh_all_in_progress[refresh_all_type]; + nm_assert(*out_refresh_all_in_progress >= 0); + *out_refresh_all_in_progress += 1; + + /* clear any delayed action that request a refresh of this object type. */ + priv->delayed_action.flags &= ~iflags; + _LOGt_delayed_action(iflags, NULL, "handle (do-request-all)"); + + if (refresh_all_type == REFRESH_ALL_TYPE_LINKS) { + nm_assert( + (priv->delayed_action.list_refresh_link->len > 0) + == NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_REFRESH_LINK)); + if (NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_REFRESH_LINK)) { + _LOGt_delayed_action(DELAYED_ACTION_TYPE_REFRESH_LINK, + NULL, + "clear (do-request-all)"); + priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK; + g_ptr_array_set_size(priv->delayed_action.list_refresh_link, 0); + } + } + + event_handler_read_netlink(platform, FALSE); + + nlmsg = _nl_msg_new_dump(refresh_all_info->obj_type, refresh_all_info->addr_family); + if (!nlmsg) + goto next_after_fail; + + if (_nl_send_nlmsg(platform, + nlmsg, + NULL, + NULL, + DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS, + out_refresh_all_in_progress) + < 0) + goto next_after_fail; + + continue; + +next_after_fail: + nm_assert(*out_refresh_all_in_progress > 0); + *out_refresh_all_in_progress -= 1; + } +} + +static void +do_request_one_type_by_needle_object(NMPlatform *platform, const NMPObject *obj_needle) +{ + do_request_all_no_delayed_actions(platform, + delayed_action_refresh_from_needle_object(obj_needle)); + delayed_action_handle_all(platform, FALSE); +} + +static void +event_seq_check_refresh_all(NMPlatform *platform, guint32 seq_number) +{ + NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + DelayedActionWaitForNlResponseData *data; + guint i; + + if (NM_IN_SET(seq_number, 0, priv->nlh_seq_last_seen)) + return; + + if (NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) { + nm_assert(priv->delayed_action.list_wait_for_nl_response->len > 0); + + for (i = 0; i < priv->delayed_action.list_wait_for_nl_response->len; i++) { + data = &g_array_index(priv->delayed_action.list_wait_for_nl_response, + DelayedActionWaitForNlResponseData, + i); + + if (data->response_type == DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS + && data->response.out_refresh_all_in_progress + && data->seq_number == priv->nlh_seq_last_seen) { + *data->response.out_refresh_all_in_progress -= 1; + data->response.out_refresh_all_in_progress = NULL; + break; + } + } + } + + priv->nlh_seq_last_seen = seq_number; +} + +static void +event_seq_check(NMPlatform * platform, + guint32 seq_number, + WaitForNlResponseResult seq_result, + const char * msg) +{ + NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + DelayedActionWaitForNlResponseData *data; + guint i; + + if (seq_number == 0) + return; + + if (NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) { + nm_assert(priv->delayed_action.list_wait_for_nl_response->len > 0); + + for (i = 0; i < priv->delayed_action.list_wait_for_nl_response->len; i++) { + data = &g_array_index(priv->delayed_action.list_wait_for_nl_response, + DelayedActionWaitForNlResponseData, + i); + + if (data->seq_number == seq_number) { + /* We potentially receive many parts partial responses for the same sequence number. + * Thus, we only remember the result, and collect it later. */ + if (data->seq_result < 0) { + /* we already saw an error for this sequence number. + * Preserve it. */ + } else if (seq_result != WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_UNKNOWN + || data->seq_result == WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN) + data->seq_result = seq_result; + if (data->out_errmsg && !*data->out_errmsg) + *data->out_errmsg = g_strdup(msg); + return; + } + } + } + +#if NM_MORE_LOGGING + if (seq_number != priv->nlh_seq_last_handled) + _LOGt("netlink: recvmsg: unwaited sequence number %u", seq_number); + priv->nlh_seq_last_handled = seq_number; +#endif +} + +static void +event_valid_msg(NMPlatform *platform, struct nl_msg *msg, gboolean handle_events) +{ + NMLinuxPlatformPrivate *priv; + nm_auto_nmpobj NMPObject *obj = NULL; + NMPCacheOpsType cache_op; + struct nlmsghdr * msghdr; + char buf_nlmsghdr[400]; + gboolean is_del = FALSE; + gboolean is_dump = FALSE; + NMPCache * cache = nm_platform_get_cache(platform); + + msghdr = nlmsg_hdr(msg); + + if (!_nm_platform_kernel_support_detected(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS) + && msghdr->nlmsg_type == RTM_NEWADDR) { + /* IFA_FLAGS is set for IPv4 and IPv6 addresses. It was added first to IPv6, + * but if we encounter an IPv4 address with IFA_FLAGS, we surely have support. */ + if (nlmsg_valid_hdr(msghdr, sizeof(struct ifaddrmsg)) + && NM_IN_SET(((struct ifaddrmsg *) nlmsg_data(msghdr))->ifa_family, + AF_INET, + AF_INET6)) { + /* see if the nl_msg contains the IFA_FLAGS attribute. If it does, + * we assume, that the kernel supports extended flags, IFA_F_MANAGETEMPADDR + * and IFA_F_NOPREFIXROUTE for IPv6. They were added together in kernel 3.14, + * dated 30 March, 2014. + * + * For IPv4, IFA_F_NOPREFIXROUTE was added later, but there is no easy + * way to detect kernel support. */ + _nm_platform_kernel_support_init( + NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS, + !!nlmsg_find_attr(msghdr, sizeof(struct ifaddrmsg), IFA_FLAGS) ? 1 : -1); + } + } + + if (!handle_events) + return; + + if (NM_IN_SET(msghdr->nlmsg_type, + RTM_DELLINK, + RTM_DELADDR, + RTM_DELROUTE, + RTM_DELRULE, + RTM_DELQDISC, + RTM_DELTFILTER)) { + /* The event notifies about a deleted object. We don't need to initialize all + * fields of the object. */ + is_del = TRUE; + } + + obj = nmp_object_new_from_nl(platform, cache, msg, is_del); + if (!obj) { + _LOGT("event-notification: %s: ignore", + nl_nlmsghdr_to_str(msghdr, buf_nlmsghdr, sizeof(buf_nlmsghdr))); + return; + } + + if (!is_del + && NM_IN_SET(msghdr->nlmsg_type, + RTM_NEWADDR, + RTM_NEWLINK, + RTM_NEWROUTE, + RTM_NEWRULE, + RTM_NEWQDISC, + RTM_NEWTFILTER)) { + is_dump = + delayed_action_refresh_all_in_progress(platform, + delayed_action_refresh_from_needle_object(obj)); + } + + _LOGT("event-notification: %s%s: %s", + nl_nlmsghdr_to_str(msghdr, buf_nlmsghdr, sizeof(buf_nlmsghdr)), + is_dump ? ", in-dump" : "", + nmp_object_to_string(obj, + is_del ? NMP_OBJECT_TO_STRING_ID : NMP_OBJECT_TO_STRING_PUBLIC, + NULL, + 0)); + + { + nm_auto_nmpobj const NMPObject *obj_old = NULL; + nm_auto_nmpobj const NMPObject *obj_new = NULL; + + switch (msghdr->nlmsg_type) { + case RTM_GETLINK: + case RTM_NEWADDR: + case RTM_NEWLINK: + case RTM_NEWQDISC: + case RTM_NEWRULE: + case RTM_NEWTFILTER: + cache_op = nmp_cache_update_netlink(cache, obj, is_dump, &obj_old, &obj_new); + if (cache_op != NMP_CACHE_OPS_UNCHANGED) { + cache_on_change(platform, cache_op, obj_old, obj_new); + nm_platform_cache_update_emit_signal(platform, cache_op, obj_old, obj_new); + } + break; + + case RTM_NEWROUTE: + { + nm_auto_nmpobj const NMPObject *obj_replace = NULL; + gboolean resync_required = FALSE; + gboolean only_dirty = FALSE; + gboolean is_ipv6; + + /* IPv4 routes that are a response to RTM_GETROUTE must have + * the cloned flag while IPv6 routes don't have to. */ + is_ipv6 = NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_IP6_ROUTE; + if (is_ipv6 || NM_FLAGS_HAS(obj->ip_route.r_rtm_flags, RTM_F_CLONED)) { + nm_assert(is_ipv6 || !nmp_object_is_alive(obj)); + priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + if (NM_FLAGS_HAS(priv->delayed_action.flags, + DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) { + guint i; + + nm_assert(priv->delayed_action.list_wait_for_nl_response->len > 0); + for (i = 0; i < priv->delayed_action.list_wait_for_nl_response->len; i++) { + DelayedActionWaitForNlResponseData *data = + &g_array_index(priv->delayed_action.list_wait_for_nl_response, + DelayedActionWaitForNlResponseData, + i); + + if (data->response_type == DELAYED_ACTION_RESPONSE_TYPE_ROUTE_GET + && data->response.out_route_get) { + nm_assert(!*data->response.out_route_get); + if (data->seq_number == nlmsg_hdr(msg)->nlmsg_seq) { + *data->response.out_route_get = nmp_object_clone(obj, FALSE); + data->response.out_route_get = NULL; + break; + } + } + } + } + } + + cache_op = nmp_cache_update_netlink_route(cache, + obj, + is_dump, + msghdr->nlmsg_flags, + &obj_old, + &obj_new, + &obj_replace, + &resync_required); + if (cache_op != NMP_CACHE_OPS_UNCHANGED) { + if (obj_replace) { + const NMDedupMultiEntry *entry_replace; + + /* we found an object that is to be replaced by the RTM_NEWROUTE message. + * While we invoke the signal, the platform cache might change and invalidate + * the findings. Mitigate that (for the most part), by marking the entry as + * dirty and only delete @obj_replace if it is still dirty afterwards. + * + * Yes, there is a tiny tiny chance for still getting it wrong. But in practice, + * the signal handlers do not cause to call the platform again, so the cache + * is not really changing. -- if they would, it would anyway be dangerous to overflow + * the stack and it's not ensured that the processing of netlink messages is + * reentrant (maybe it is). + */ + entry_replace = nmp_cache_lookup_entry(cache, obj_replace); + nm_assert(entry_replace && entry_replace->obj == obj_replace); + nm_dedup_multi_entry_set_dirty(entry_replace, TRUE); + only_dirty = TRUE; + } + cache_on_change(platform, cache_op, obj_old, obj_new); + nm_platform_cache_update_emit_signal(platform, cache_op, obj_old, obj_new); + } + + if (obj_replace) { + /* the RTM_NEWROUTE message indicates that another route was replaced. + * Remove it now. */ + cache_op = nmp_cache_remove(cache, obj_replace, TRUE, only_dirty, NULL); + if (cache_op != NMP_CACHE_OPS_UNCHANGED) { + nm_assert(cache_op == NMP_CACHE_OPS_REMOVED); + cache_on_change(platform, cache_op, obj_replace, NULL); + nm_platform_cache_update_emit_signal(platform, cache_op, obj_replace, NULL); + } + } + + if (resync_required) { + /* we'd like to avoid such resyncs as they are expensive and we should only rely on the + * netlink events. This needs investigation. */ + _LOGT("schedule resync of routes after RTM_NEWROUTE"); + delayed_action_schedule(platform, + delayed_action_refresh_from_needle_object(obj), + NULL); + } + break; + } + + case RTM_DELADDR: + case RTM_DELLINK: + case RTM_DELQDISC: + case RTM_DELROUTE: + case RTM_DELRULE: + case RTM_DELTFILTER: + cache_op = nmp_cache_remove_netlink(cache, obj, &obj_old, &obj_new); + if (cache_op != NMP_CACHE_OPS_UNCHANGED) { + cache_on_change(platform, cache_op, obj_old, obj_new); + nm_platform_cache_update_emit_signal(platform, cache_op, obj_old, obj_new); + } + break; + default: + break; + } + } +} + +/*****************************************************************************/ + +static int +do_add_link_with_lookup(NMPlatform * platform, + NMLinkType link_type, + const char * name, + struct nl_msg * nlmsg, + const NMPlatformLink **out_link) +{ + const NMPObject * obj = NULL; + WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; + gs_free char * errmsg = NULL; + int nle; + char s_buf[256]; + NMPCache * cache = nm_platform_get_cache(platform); + + event_handler_read_netlink(platform, FALSE); + + nle = _nl_send_nlmsg(platform, + nlmsg, + &seq_result, + &errmsg, + DELAYED_ACTION_RESPONSE_TYPE_VOID, + NULL); + if (nle < 0) { + _LOGE("do-add-link[%s/%s]: failed sending netlink request \"%s\" (%d)", + name, + nm_link_type_to_string(link_type), + nm_strerror(nle), + -nle); + NM_SET_OUT(out_link, NULL); + return nle; + } + + delayed_action_handle_all(platform, FALSE); + + nm_assert(seq_result); + + _NMLOG(seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK ? LOGL_DEBUG : LOGL_WARN, + "do-add-link[%s/%s]: %s", + name, + nm_link_type_to_string(link_type), + wait_for_nl_response_to_string(seq_result, errmsg, s_buf, sizeof(s_buf))); + + if (out_link) { + obj = nmp_cache_lookup_link_full(cache, 0, name, FALSE, link_type, NULL, NULL); + *out_link = NMP_OBJECT_CAST_LINK(obj); + } + + return wait_for_nl_response_to_nmerr(seq_result); +} + +static int +do_add_addrroute(NMPlatform * platform, + const NMPObject *obj_id, + struct nl_msg * nlmsg, + gboolean suppress_netlink_failure) +{ + WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; + gs_free char * errmsg = NULL; + int nle; + char s_buf[256]; + + nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_id), + NMP_OBJECT_TYPE_IP4_ADDRESS, + NMP_OBJECT_TYPE_IP6_ADDRESS, + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE)); + + event_handler_read_netlink(platform, FALSE); + + nle = _nl_send_nlmsg(platform, + nlmsg, + &seq_result, + &errmsg, + DELAYED_ACTION_RESPONSE_TYPE_VOID, + NULL); + if (nle < 0) { + _LOGE("do-add-%s[%s]: failure sending netlink request \"%s\" (%d)", + NMP_OBJECT_GET_CLASS(obj_id)->obj_type_name, + nmp_object_to_string(obj_id, NMP_OBJECT_TO_STRING_ID, NULL, 0), + nm_strerror(nle), + -nle); + return -NME_PL_NETLINK; + } + + delayed_action_handle_all(platform, FALSE); + + nm_assert(seq_result); + + _NMLOG((seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK + || (suppress_netlink_failure && seq_result < 0)) + ? LOGL_DEBUG + : LOGL_WARN, + "do-add-%s[%s]: %s", + NMP_OBJECT_GET_CLASS(obj_id)->obj_type_name, + nmp_object_to_string(obj_id, NMP_OBJECT_TO_STRING_ID, NULL, 0), + wait_for_nl_response_to_string(seq_result, errmsg, s_buf, sizeof(s_buf))); + + if (NMP_OBJECT_GET_TYPE(obj_id) == NMP_OBJECT_TYPE_IP6_ADDRESS) { + /* In rare cases, the object is not yet ready as we received the ACK from + * kernel. Need to refetch. + * + * We want to safe the expensive refetch, thus we look first into the cache + * whether the object exists. + * + * rh#1484434 */ + if (!nmp_cache_lookup_obj(nm_platform_get_cache(platform), obj_id)) + do_request_one_type_by_needle_object(platform, obj_id); + } + + return wait_for_nl_response_to_nmerr(seq_result); +} + +static gboolean +do_delete_object(NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *nlmsg) +{ + WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; + gs_free char * errmsg = NULL; + int nle; + char s_buf[256]; + gboolean success; + const char * log_detail = ""; + + event_handler_read_netlink(platform, FALSE); + + nle = _nl_send_nlmsg(platform, + nlmsg, + &seq_result, + &errmsg, + DELAYED_ACTION_RESPONSE_TYPE_VOID, + NULL); + if (nle < 0) { + _LOGE("do-delete-%s[%s]: failure sending netlink request \"%s\" (%d)", + NMP_OBJECT_GET_CLASS(obj_id)->obj_type_name, + nmp_object_to_string(obj_id, NMP_OBJECT_TO_STRING_ID, NULL, 0), + nm_strerror(nle), + -nle); + return FALSE; + } + + delayed_action_handle_all(platform, FALSE); + + nm_assert(seq_result); + + success = TRUE; + if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) { + /* ok */ + } else if (NM_IN_SET(-((int) seq_result), ESRCH, ENOENT)) + log_detail = ", meaning the object was already removed"; + else if (NM_IN_SET(-((int) seq_result), ENXIO) + && NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_id), NMP_OBJECT_TYPE_IP6_ADDRESS)) { + /* On RHEL7 kernel, deleting a non existing address fails with ENXIO */ + log_detail = ", meaning the address was already removed"; + } else if (NM_IN_SET(-((int) seq_result), EADDRNOTAVAIL) + && NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_id), + NMP_OBJECT_TYPE_IP4_ADDRESS, + NMP_OBJECT_TYPE_IP6_ADDRESS)) + log_detail = ", meaning the address was already removed"; + else + success = FALSE; + + _NMLOG(success ? LOGL_DEBUG : LOGL_WARN, + "do-delete-%s[%s]: %s%s", + NMP_OBJECT_GET_CLASS(obj_id)->obj_type_name, + nmp_object_to_string(obj_id, NMP_OBJECT_TO_STRING_ID, NULL, 0), + wait_for_nl_response_to_string(seq_result, errmsg, s_buf, sizeof(s_buf)), + log_detail); + + if (NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_id), + NMP_OBJECT_TYPE_IP6_ADDRESS, + NMP_OBJECT_TYPE_QDISC, + NMP_OBJECT_TYPE_TFILTER)) { + /* In rare cases, the object is still there after we receive the ACK from + * kernel. Need to refetch. + * + * We want to safe the expensive refetch, thus we look first into the cache + * whether the object exists. + * + * rh#1484434 */ + if (nmp_cache_lookup_obj(nm_platform_get_cache(platform), obj_id)) + do_request_one_type_by_needle_object(platform, obj_id); + } + + return success; +} + +static int +do_change_link(NMPlatform * platform, + ChangeLinkType change_link_type, + int ifindex, + struct nl_msg * nlmsg, + const ChangeLinkData *data) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + int nle; + WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; + gs_free char * errmsg = NULL; + char s_buf[256]; + int result = 0; + NMLogLevel log_level = LOGL_DEBUG; + const char * log_result = "failure"; + const char * log_detail = ""; + gs_free char * log_detail_free = NULL; + const NMPObject * obj_cache; + + if (!nm_platform_netns_push(platform, &netns)) { + log_level = LOGL_ERR; + log_detail = ", failure to change network namespace"; + goto out; + } + +retry: + nle = _nl_send_nlmsg(platform, + nlmsg, + &seq_result, + &errmsg, + DELAYED_ACTION_RESPONSE_TYPE_VOID, + NULL); + if (nle < 0) { + log_level = LOGL_ERR; + log_detail_free = + g_strdup_printf(", failure sending netlink request: %s (%d)", nm_strerror(nle), -nle); + log_detail = log_detail_free; + goto out; + } + + /* always refetch the link after changing it. There seems to be issues + * and we sometimes lack events. Nuke it from the orbit... */ + delayed_action_schedule(platform, DELAYED_ACTION_TYPE_REFRESH_LINK, GINT_TO_POINTER(ifindex)); + + delayed_action_handle_all(platform, FALSE); + + nm_assert(seq_result); + + if (NM_IN_SET(-((int) seq_result), EOPNOTSUPP) && nlmsg_hdr(nlmsg)->nlmsg_type == RTM_NEWLINK) { + nlmsg_hdr(nlmsg)->nlmsg_type = RTM_SETLINK; + goto retry; + } + + if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) { + log_result = "success"; + } else if (NM_IN_SET(-((int) seq_result), EEXIST, EADDRINUSE)) { + /* */ + } else if (NM_IN_SET(-((int) seq_result), ESRCH, ENOENT)) { + log_detail = ", firmware not found"; + result = -NME_PL_NO_FIRMWARE; + } else if (NM_IN_SET(-((int) seq_result), ERANGE) + && change_link_type == CHANGE_LINK_TYPE_SET_MTU) { + log_detail = ", setting MTU to requested size is not possible"; + result = -NME_PL_CANT_SET_MTU; + } else if (NM_IN_SET(-((int) seq_result), ENFILE) + && change_link_type == CHANGE_LINK_TYPE_SET_ADDRESS + && (obj_cache = nmp_cache_lookup_link(nm_platform_get_cache(platform), ifindex)) + && obj_cache->link.l_address.len == data->set_address.length + && memcmp(obj_cache->link.l_address.data, + data->set_address.address, + data->set_address.length) + == 0) { + /* workaround ENFILE which may be wrongly returned (bgo #770456). + * If the MAC address is as expected, assume success? */ + log_result = "success"; + log_detail = " (assume success changing address)"; + result = 0; + } else if (NM_IN_SET(-((int) seq_result), ENODEV)) { + log_level = LOGL_DEBUG; + result = -NME_PL_NOT_FOUND; + } else if (-((int) seq_result) == EAFNOSUPPORT) { + log_level = LOGL_DEBUG; + result = -NME_PL_OPNOTSUPP; + } else { + log_level = LOGL_WARN; + result = -NME_UNSPEC; + } + +out: + _NMLOG(log_level, + "do-change-link[%d]: %s changing link: %s%s", + ifindex, + log_result, + wait_for_nl_response_to_string(seq_result, errmsg, s_buf, sizeof(s_buf)), + log_detail); + return result; +} + +static int +link_add(NMPlatform * platform, + NMLinkType type, + const char * name, + int parent, + const void * address, + size_t address_len, + guint32 mtu, + gconstpointer extra_data, + const NMPlatformLink **out_link) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + if (type == NM_LINK_TYPE_BOND) { + /* When the kernel loads the bond module, either via explicit modprobe + * or automatically in response to creating a bond master, it will also + * create a 'bond0' interface. Since the bond we're about to create may + * or may not be named 'bond0' prevent potential confusion about a bond + * that the user didn't want by telling the bonding module not to create + * bond0 automatically. + */ + if (!g_file_test("/sys/class/net/bonding_masters", G_FILE_TEST_EXISTS)) + (void) nmp_utils_modprobe(NULL, TRUE, "bonding", "max_bonds=0", NULL); + } + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, 0, name); + if (!nlmsg) + return -NME_UNSPEC; + + if (parent > 0) + NLA_PUT_U32(nlmsg, IFLA_LINK, parent); + + if (address && address_len) + NLA_PUT(nlmsg, IFLA_ADDRESS, address_len, address); + + if (mtu) + NLA_PUT_U32(nlmsg, IFLA_MTU, mtu); + + if (!_nl_msg_new_link_set_linkinfo(nlmsg, type, extra_data)) + return -NME_UNSPEC; + + return do_add_link_with_lookup(platform, type, name, nlmsg, out_link); +nla_put_failure: + g_return_val_if_reached(-NME_BUG); +} + +static gboolean +link_delete(NMPlatform *platform, int ifindex) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + NMPObject obj_id; + const NMPObject * obj; + + obj = nmp_cache_lookup_link(nm_platform_get_cache(platform), ifindex); + if (!obj || !obj->_link.netlink.is_in_netlink) + return FALSE; + + nlmsg = _nl_msg_new_link(RTM_DELLINK, 0, ifindex, NULL); + + nmp_object_stackinit_id_link(&obj_id, ifindex); + return do_delete_object(platform, &obj_id, nlmsg); +} + +static gboolean +link_refresh(NMPlatform *platform, int ifindex) +{ + do_request_link(platform, ifindex, NULL); + return !!nm_platform_link_get_obj(platform, ifindex, TRUE); +} + +static gboolean +link_set_netns(NMPlatform *platform, int ifindex, int netns_fd) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); + if (!nlmsg) + return FALSE; + + NLA_PUT(nlmsg, IFLA_NET_NS_FD, 4, &netns_fd); + return (do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); + +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static int +link_change_flags(NMPlatform *platform, int ifindex, unsigned flags_mask, unsigned flags_set) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + char s_flags[100]; + + _LOGD("link: change %d: flags: set 0x%x/0x%x ([%s] / [%s])", + ifindex, + flags_set, + flags_mask, + nm_platform_link_flags2str(flags_set, s_flags, sizeof(s_flags)), + nm_platform_link_flags2str(flags_mask, NULL, 0)); + + nlmsg = _nl_msg_new_link_full(RTM_NEWLINK, 0, ifindex, NULL, AF_UNSPEC, flags_mask, flags_set); + if (!nlmsg) + return -NME_UNSPEC; + return do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL); +} + +static gboolean +link_set_up(NMPlatform *platform, int ifindex, gboolean *out_no_firmware) +{ + int r; + + r = link_change_flags(platform, ifindex, IFF_UP, IFF_UP); + NM_SET_OUT(out_no_firmware, (r == -NME_PL_NO_FIRMWARE)); + return r >= 0; +} + +static gboolean +link_set_down(NMPlatform *platform, int ifindex) +{ + return (link_change_flags(platform, ifindex, IFF_UP, 0) >= 0); +} + +static gboolean +link_set_arp(NMPlatform *platform, int ifindex) +{ + return (link_change_flags(platform, ifindex, IFF_NOARP, 0) >= 0); +} + +static gboolean +link_set_noarp(NMPlatform *platform, int ifindex) +{ + return (link_change_flags(platform, ifindex, IFF_NOARP, IFF_NOARP) >= 0); +} + +static int +link_set_user_ipv6ll_enabled(NMPlatform *platform, int ifindex, gboolean enabled) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + guint8 mode = enabled ? NM_IN6_ADDR_GEN_MODE_NONE : NM_IN6_ADDR_GEN_MODE_EUI64; + + _LOGD("link: change %d: user-ipv6ll: set IPv6 address generation mode to %s", + ifindex, + nm_platform_link_inet6_addrgenmode2str(mode, NULL, 0)); + + if (!nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) { + _LOGD("link: change %d: user-ipv6ll: not supported", ifindex); + return -NME_PL_OPNOTSUPP; + } + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); + if (!nlmsg || !_nl_msg_new_link_set_afspec(nlmsg, mode, NULL)) + g_return_val_if_reached(-NME_BUG); + + return do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL); +} + +static gboolean +link_set_token(NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + _LOGD("link: change %d: token: set IPv6 address generation token to %s", + ifindex, + nm_utils_inet6_interface_identifier_to_token(iid, sbuf)); + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); + if (!nlmsg || !_nl_msg_new_link_set_afspec(nlmsg, -1, &iid)) + g_return_val_if_reached(FALSE); + + return (do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); +} + +static gboolean +link_supports_carrier_detect(NMPlatform *platform, int ifindex) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + + if (!nm_platform_netns_push(platform, &netns)) + return FALSE; + + /* We use netlink for the actual carrier detection, but netlink can't tell + * us whether the device actually supports carrier detection in the first + * place. We assume any device that does implements one of these two APIs. + */ + return nmp_utils_ethtool_supports_carrier_detect(ifindex) + || nmp_utils_mii_supports_carrier_detect(ifindex); +} + +static gboolean +link_supports_vlans(NMPlatform *platform, int ifindex) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + const NMPObject * obj; + + obj = nm_platform_link_get_obj(platform, ifindex, TRUE); + + /* Only ARPHRD_ETHER links can possibly support VLANs. */ + if (!obj || obj->link.arptype != ARPHRD_ETHER) + return FALSE; + + if (!nm_platform_netns_push(platform, &netns)) + return FALSE; + + return nmp_utils_ethtool_supports_vlans(ifindex); +} + +static gboolean +link_supports_sriov(NMPlatform *platform, int ifindex) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + nm_auto_close int dirfd = -1; + char ifname[IFNAMSIZ]; + int num = -1; + + if (!nm_platform_netns_push(platform, &netns)) + return FALSE; + + dirfd = nm_platform_sysctl_open_netdir(platform, ifindex, ifname); + if (dirfd < 0) + return FALSE; + + num = + nm_platform_sysctl_get_int32(platform, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "device/sriov_numvfs"), + -1); + + return num != -1; +} + +static int +link_set_address(NMPlatform *platform, int ifindex, gconstpointer address, size_t length) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + const ChangeLinkData d = { + .set_address = + { + .address = address, + .length = length, + }, + }; + + if (!address || !length) + g_return_val_if_reached(-NME_BUG); + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); + if (!nlmsg) + g_return_val_if_reached(-NME_BUG); + + NLA_PUT(nlmsg, IFLA_ADDRESS, length, address); + + return do_change_link(platform, CHANGE_LINK_TYPE_SET_ADDRESS, ifindex, nlmsg, &d); +nla_put_failure: + g_return_val_if_reached(-NME_BUG); +} + +static int +link_set_name(NMPlatform *platform, int ifindex, const char *name) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); + if (!nlmsg) + g_return_val_if_reached(-NME_BUG); + + NLA_PUT(nlmsg, IFLA_IFNAME, strlen(name) + 1, name); + + return (do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static gboolean +link_get_permanent_address(NMPlatform *platform, int ifindex, guint8 *buf, size_t *length) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + + if (!nm_platform_netns_push(platform, &netns)) + return FALSE; + + return nmp_utils_ethtool_get_permanent_address(ifindex, buf, length); +} + +static int +link_set_mtu(NMPlatform *platform, int ifindex, guint32 mtu) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); + if (!nlmsg) + return FALSE; + + NLA_PUT_U32(nlmsg, IFLA_MTU, mtu); + + return do_change_link(platform, CHANGE_LINK_TYPE_SET_MTU, ifindex, nlmsg, NULL); +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static void +sriov_idle_cb(gpointer user_data, GCancellable *cancellable) +{ + gs_unref_object NMPlatform *platform = NULL; + gs_free_error GError *cancelled_error = NULL; + gs_free_error GError * error = NULL; + NMPlatformAsyncCallback callback; + gpointer callback_data; + + g_cancellable_set_error_if_cancelled(cancellable, &cancelled_error); + nm_utils_user_data_unpack(user_data, &platform, &error, &callback, &callback_data); + callback(cancelled_error ?: error, callback_data); +} + +static void +link_set_sriov_params_async(NMPlatform * platform, + int ifindex, + guint num_vfs, + NMOptionBool autoprobe, + NMPlatformAsyncCallback callback, + gpointer data, + GCancellable * cancellable) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + gs_free_error GError *error = NULL; + nm_auto_close int dirfd = -1; + int current_autoprobe; + guint i, total; + gint64 current_num; + char ifname[IFNAMSIZ]; + gpointer packed; + const char * values[3]; + char buf[64]; + + g_return_if_fail(callback || !data); + g_return_if_fail(cancellable); + + if (!nm_platform_netns_push(platform, &netns)) { + g_set_error_literal(&error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "couldn't change namespace"); + goto out_idle; + } + + dirfd = nm_platform_sysctl_open_netdir(platform, ifindex, ifname); + if (!dirfd) { + g_set_error_literal(&error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "couldn't open netdir"); + goto out_idle; + } + + total = nm_platform_sysctl_get_int_checked( + platform, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "device/sriov_totalvfs"), + 10, + 0, + G_MAXUINT, + 0); + if (!errno && num_vfs > total) { + _LOGW("link: %d only supports %u VFs (requested %u)", ifindex, total, num_vfs); + num_vfs = total; + } + + /* + * Take special care when setting new values: + * - don't touch anything if the right values are already set + * - to change the number of VFs or autoprobe we need to destroy existing VFs + * - the autoprobe setting is irrelevant when numvfs is zero + */ + current_num = nm_platform_sysctl_get_int_checked( + platform, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "device/sriov_numvfs"), + 10, + 0, + G_MAXUINT, + -1); + current_autoprobe = nm_platform_sysctl_get_int_checked( + platform, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "device/sriov_drivers_autoprobe"), + 10, + 0, + 1, + -1); + + if (current_autoprobe == -1 && errno == ENOENT) { + /* older kernel versions don't have this sysctl. Assume the value is + * "1". */ + current_autoprobe = 1; + } + + if (current_num == num_vfs + && (autoprobe == NM_OPTION_BOOL_DEFAULT || current_autoprobe == autoprobe)) + goto out_idle; + + if (NM_IN_SET(autoprobe, NM_OPTION_BOOL_TRUE, NM_OPTION_BOOL_FALSE) + && current_autoprobe != autoprobe + && !nm_platform_sysctl_set( + platform, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "device/sriov_drivers_autoprobe"), + nm_sprintf_buf(buf, "%d", (int) autoprobe))) { + g_set_error(&error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "couldn't set SR-IOV drivers-autoprobe to %d: %s", + (int) autoprobe, + nm_strerror_native(errno)); + goto out_idle; + } + + if (current_num == 0 && num_vfs == 0) + goto out_idle; + + i = 0; + if (current_num != 0) + values[i++] = "0"; + if (num_vfs != 0) + values[i++] = nm_sprintf_bufa(32, "%u", num_vfs); + values[i++] = NULL; + + sysctl_set_async(platform, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "device/sriov_numvfs"), + values, + callback, + data, + cancellable); + return; + +out_idle: + if (callback) { + packed = nm_utils_user_data_pack(g_object_ref(platform), + g_steal_pointer(&error), + callback, + data); + nm_utils_invoke_on_idle(cancellable, sriov_idle_cb, packed); + } +} + +static gboolean +link_set_sriov_vfs(NMPlatform *platform, int ifindex, const NMPlatformVF *const *vfs) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + struct nlattr * list, *info, *vlan_list; + guint i; + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); + if (!nlmsg) + g_return_val_if_reached(-NME_BUG); + + if (!(list = nla_nest_start(nlmsg, IFLA_VFINFO_LIST))) + goto nla_put_failure; + + for (i = 0; vfs[i]; i++) { + const NMPlatformVF *vf = vfs[i]; + + if (!(info = nla_nest_start(nlmsg, IFLA_VF_INFO))) + goto nla_put_failure; + + if (vf->spoofchk >= 0) { + struct _ifla_vf_setting ivs = {0}; + + ivs.vf = vf->index; + ivs.setting = vf->spoofchk; + NLA_PUT(nlmsg, IFLA_VF_SPOOFCHK, sizeof(ivs), &ivs); + } + + if (vf->trust >= 0) { + struct _ifla_vf_setting ivs = {0}; + + ivs.vf = vf->index; + ivs.setting = vf->trust; + NLA_PUT(nlmsg, IFLA_VF_TRUST, sizeof(ivs), &ivs); + } + + if (vf->mac.len) { + struct ifla_vf_mac ivm = {0}; + + ivm.vf = vf->index; + memcpy(ivm.mac, vf->mac.data, vf->mac.len); + NLA_PUT(nlmsg, IFLA_VF_MAC, sizeof(ivm), &ivm); + } + + if (vf->min_tx_rate || vf->max_tx_rate) { + struct _ifla_vf_rate ivr = {0}; + + ivr.vf = vf->index; + ivr.min_tx_rate = vf->min_tx_rate; + ivr.max_tx_rate = vf->max_tx_rate; + NLA_PUT(nlmsg, IFLA_VF_RATE, sizeof(ivr), &ivr); + } + + /* Kernel only supports one VLAN per VF now. If this + * changes in the future, we need to figure out how to + * clear existing VLANs and set new ones in one message + * with the new API.*/ + if (vf->num_vlans > 1) { + _LOGW("multiple VLANs per VF are not supported at the moment"); + return FALSE; + } else { + struct _ifla_vf_vlan_info ivvi = {0}; + + if (!(vlan_list = nla_nest_start(nlmsg, IFLA_VF_VLAN_LIST))) + goto nla_put_failure; + + ivvi.vf = vf->index; + if (vf->num_vlans == 1) { + ivvi.vlan = vf->vlans[0].id; + ivvi.qos = vf->vlans[0].qos; + ivvi.vlan_proto = htons(vf->vlans[0].proto_ad ? ETH_P_8021AD : ETH_P_8021Q); + } else { + /* Clear existing VLAN */ + ivvi.vlan = 0; + ivvi.qos = 0; + ivvi.vlan_proto = htons(ETH_P_8021Q); + } + + NLA_PUT(nlmsg, IFLA_VF_VLAN_INFO, sizeof(ivvi), &ivvi); + nla_nest_end(nlmsg, vlan_list); + } + nla_nest_end(nlmsg, info); + } + nla_nest_end(nlmsg, list); + + return (do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static gboolean +link_set_bridge_vlans(NMPlatform * platform, + int ifindex, + gboolean on_master, + const NMPlatformBridgeVlan *const *vlans) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + struct nlattr * list; + struct bridge_vlan_info vinfo = {}; + guint i; + + nlmsg = + _nl_msg_new_link_full(vlans ? RTM_SETLINK : RTM_DELLINK, 0, ifindex, NULL, AF_BRIDGE, 0, 0); + if (!nlmsg) + g_return_val_if_reached(-NME_BUG); + + if (!(list = nla_nest_start(nlmsg, IFLA_AF_SPEC))) + goto nla_put_failure; + + NLA_PUT_U16(nlmsg, IFLA_BRIDGE_FLAGS, on_master ? BRIDGE_FLAGS_MASTER : BRIDGE_FLAGS_SELF); + + if (vlans) { + /* Add VLANs */ + for (i = 0; vlans[i]; i++) { + const NMPlatformBridgeVlan *vlan = vlans[i]; + gboolean is_range = vlan->vid_start != vlan->vid_end; + + vinfo.vid = vlan->vid_start; + vinfo.flags = is_range ? BRIDGE_VLAN_INFO_RANGE_BEGIN : 0; + + if (vlan->untagged) + vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED; + if (vlan->pvid) + vinfo.flags |= BRIDGE_VLAN_INFO_PVID; + + NLA_PUT(nlmsg, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo); + + if (is_range) { + vinfo.vid = vlan->vid_end; + vinfo.flags = BRIDGE_VLAN_INFO_RANGE_END; + NLA_PUT(nlmsg, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo); + } + } + } else { + /* Flush existing VLANs */ + vinfo.vid = 1; + vinfo.flags = BRIDGE_VLAN_INFO_RANGE_BEGIN; + NLA_PUT(nlmsg, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo); + + vinfo.vid = 4094; + vinfo.flags = BRIDGE_VLAN_INFO_RANGE_END; + NLA_PUT(nlmsg, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo); + } + + nla_nest_end(nlmsg, list); + + return (do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static char * +link_get_physical_port_id(NMPlatform *platform, int ifindex) +{ + nm_auto_close int dirfd = -1; + char ifname_verified[IFNAMSIZ]; + + dirfd = nm_platform_sysctl_open_netdir(platform, ifindex, ifname_verified); + if (dirfd < 0) + return NULL; + return sysctl_get(platform, NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname_verified, "phys_port_id")); +} + +static guint +link_get_dev_id(NMPlatform *platform, int ifindex) +{ + nm_auto_close int dirfd = -1; + char ifname_verified[IFNAMSIZ]; + + dirfd = nm_platform_sysctl_open_netdir(platform, ifindex, ifname_verified); + if (dirfd < 0) + return 0; + return nm_platform_sysctl_get_int_checked( + platform, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname_verified, "dev_id"), + 16, + 0, + G_MAXUINT16, + 0); +} + +static gboolean +link_tun_add(NMPlatform * platform, + const char * name, + const NMPlatformLnkTun *props, + const NMPlatformLink ** out_link, + int * out_fd) +{ + const NMPObject * obj; + struct ifreq ifr = {}; + nm_auto_close int fd = -1; + + nm_assert(NM_IN_SET(props->type, IFF_TAP, IFF_TUN)); + nm_assert(props->persist || out_fd); + + fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC); + if (fd < 0) + return FALSE; + + nm_utils_ifname_cpy(ifr.ifr_name, name); + ifr.ifr_flags = ((short) props->type) | ((short) IFF_TUN_EXCL) + | (!props->pi ? (short) IFF_NO_PI : (short) 0) + | (props->vnet_hdr ? (short) IFF_VNET_HDR : (short) 0) + | (props->multi_queue ? (short) NM_IFF_MULTI_QUEUE : (short) 0); + if (ioctl(fd, TUNSETIFF, &ifr)) + return FALSE; + + if (props->owner_valid) { + if (ioctl(fd, TUNSETOWNER, (uid_t) props->owner)) + return FALSE; + } + + if (props->group_valid) { + if (ioctl(fd, TUNSETGROUP, (gid_t) props->group)) + return FALSE; + } + + if (props->persist) { + if (ioctl(fd, TUNSETPERSIST, 1)) + return FALSE; + } + + do_request_link(platform, 0, name); + obj = nmp_cache_lookup_link_full(nm_platform_get_cache(platform), + 0, + name, + FALSE, + NM_LINK_TYPE_TUN, + NULL, + NULL); + + if (!obj) + return FALSE; + + NM_SET_OUT(out_link, &obj->link); + NM_SET_OUT(out_fd, nm_steal_fd(&fd)); + return TRUE; +} + +static void +_vlan_change_vlan_qos_mapping_create(gboolean is_ingress_map, + gboolean reset_all, + const NMVlanQosMapping *current_map, + guint current_n_map, + const NMVlanQosMapping *set_map, + guint set_n_map, + NMVlanQosMapping ** out_map, + guint * out_n_map) +{ + NMVlanQosMapping *map; + guint i, j, len; + const guint INGRESS_RANGE_LEN = 8; + + nm_assert(out_map && !*out_map); + nm_assert(out_n_map && !*out_n_map); + + if (!reset_all) + current_n_map = 0; + else if (is_ingress_map) + current_n_map = INGRESS_RANGE_LEN; + + len = current_n_map + set_n_map; + + if (len == 0) + return; + + map = g_new(NMVlanQosMapping, len); + + if (current_n_map) { + if (is_ingress_map) { + /* For the ingress-map, there are only 8 entries (0 to 7). + * When the user requests to reset all entries, we don't actually + * need the cached entries, we can just explicitly clear all possible + * ones. + * + * That makes only a real difference in case our cache is out-of-date. + * + * For the egress map we cannot do that, because there are far too + * many. There we can only clear the entries that we know about. */ + for (i = 0; i < INGRESS_RANGE_LEN; i++) { + map[i].from = i; + map[i].to = 0; + } + } else { + for (i = 0; i < current_n_map; i++) { + map[i].from = current_map[i].from; + map[i].to = 0; + } + } + } + if (set_n_map) + memcpy(&map[current_n_map], set_map, sizeof(*set_map) * set_n_map); + + g_qsort_with_data(map, len, sizeof(*map), _vlan_qos_mapping_cmp_from, NULL); + + for (i = 0, j = 0; i < len; i++) { + if ((is_ingress_map && !VLAN_XGRESS_PRIO_VALID(map[i].from)) + || (!is_ingress_map && !VLAN_XGRESS_PRIO_VALID(map[i].to))) + continue; + if (j > 0 && map[j - 1].from == map[i].from) + map[j - 1] = map[i]; + else + map[j++] = map[i]; + } + + *out_map = map; + *out_n_map = j; +} + +static gboolean +link_vlan_change(NMPlatform * platform, + int ifindex, + _NMVlanFlags flags_mask, + _NMVlanFlags flags_set, + gboolean ingress_reset_all, + const NMVlanQosMapping *ingress_map, + gsize n_ingress_map, + gboolean egress_reset_all, + const NMVlanQosMapping *egress_map, + gsize n_egress_map) +{ + const NMPObject * obj_cache; + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + const NMPObjectLnkVlan * lnk; + guint new_n_ingress_map = 0; + guint new_n_egress_map = 0; + gs_free NMVlanQosMapping *new_ingress_map = NULL; + gs_free NMVlanQosMapping *new_egress_map = NULL; + + obj_cache = nmp_cache_lookup_link(nm_platform_get_cache(platform), ifindex); + if (!obj_cache || !obj_cache->_link.netlink.is_in_netlink) { + _LOGD("link: change %d: %s: link does not exist", ifindex, "vlan"); + return FALSE; + } + + lnk = obj_cache->_link.netlink.lnk ? &obj_cache->_link.netlink.lnk->_lnk_vlan : NULL; + + flags_set &= flags_mask; + + _vlan_change_vlan_qos_mapping_create(TRUE, + ingress_reset_all, + lnk ? lnk->ingress_qos_map : NULL, + lnk ? lnk->n_ingress_qos_map : 0, + ingress_map, + n_ingress_map, + &new_ingress_map, + &new_n_ingress_map); + + _vlan_change_vlan_qos_mapping_create(FALSE, + egress_reset_all, + lnk ? lnk->egress_qos_map : NULL, + lnk ? lnk->n_egress_qos_map : 0, + egress_map, + n_egress_map, + &new_egress_map, + &new_n_egress_map); + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); + if (!nlmsg + || !_nl_msg_new_link_set_linkinfo_vlan(nlmsg, + -1, + flags_mask, + flags_set, + new_ingress_map, + new_n_ingress_map, + new_egress_map, + new_n_egress_map)) + g_return_val_if_reached(FALSE); + + return (do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); +} + +static gboolean +link_enslave(NMPlatform *platform, int master, int slave) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + int ifindex = slave; + + nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); + if (!nlmsg) + return FALSE; + + NLA_PUT_U32(nlmsg, IFLA_MASTER, master); + + return (do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static gboolean +link_release(NMPlatform *platform, int master, int slave) +{ + return link_enslave(platform, 0, slave); +} + +/*****************************************************************************/ + +static gboolean +_infiniband_partition_action(NMPlatform * platform, + InfinibandAction action, + int parent, + int p_key, + const NMPlatformLink **out_link) +{ + nm_auto_close int dirfd = -1; + char ifname_parent[IFNAMSIZ]; + const NMPObject * obj; + char id[20]; + char name[IFNAMSIZ]; + gboolean success; + + nm_assert(NM_IN_SET(action, INFINIBAND_ACTION_CREATE_CHILD, INFINIBAND_ACTION_DELETE_CHILD)); + nm_assert(p_key > 0 && p_key <= 0xffff && p_key != 0x8000); + + dirfd = nm_platform_sysctl_open_netdir(platform, parent, ifname_parent); + if (dirfd < 0) { + errno = ENOENT; + return FALSE; + } + + nm_sprintf_buf(id, "0x%04x", p_key); + if (action == INFINIBAND_ACTION_CREATE_CHILD) + success = + nm_platform_sysctl_set(platform, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname_parent, "create_child"), + id); + else + success = + nm_platform_sysctl_set(platform, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname_parent, "delete_child"), + id); + + if (!success) { + if (action == INFINIBAND_ACTION_DELETE_CHILD && errno == ENODEV) + return TRUE; + return FALSE; + } + + nmp_utils_new_infiniband_name(name, ifname_parent, p_key); + do_request_link(platform, 0, name); + + if (action == INFINIBAND_ACTION_DELETE_CHILD) + return TRUE; + + obj = nmp_cache_lookup_link_full(nm_platform_get_cache(platform), + 0, + name, + FALSE, + NM_LINK_TYPE_INFINIBAND, + NULL, + NULL); + if (out_link) + *out_link = obj ? &obj->link : NULL; + return !!obj; +} + +static gboolean +infiniband_partition_add(NMPlatform * platform, + int parent, + int p_key, + const NMPlatformLink **out_link) +{ + return _infiniband_partition_action(platform, + INFINIBAND_ACTION_CREATE_CHILD, + parent, + p_key, + out_link); +} + +static gboolean +infiniband_partition_delete(NMPlatform *platform, int parent, int p_key) +{ + return _infiniband_partition_action(platform, + INFINIBAND_ACTION_DELETE_CHILD, + parent, + p_key, + NULL); +} + +/*****************************************************************************/ + +static GObject * +get_ext_data(NMPlatform *platform, int ifindex) +{ + const NMPObject *obj; + + obj = nmp_cache_lookup_link(nm_platform_get_cache(platform), ifindex); + if (!obj) + return NULL; + + return obj->_link.ext_data; +} + +/*****************************************************************************/ + +#define WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, retval) \ + nm_auto_pop_netns NMPNetns *netns = NULL; \ + NMWifiUtils * wifi_data; \ + if (!nm_platform_netns_push(platform, &netns)) \ + return retval; \ + wifi_data = NM_WIFI_UTILS(get_ext_data(platform, ifindex)); \ + if (!wifi_data) \ + return retval; + +static gboolean +wifi_get_capabilities(NMPlatform *platform, int ifindex, _NMDeviceWifiCapabilities *caps) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE); + if (caps) + *caps = nm_wifi_utils_get_caps(wifi_data); + return TRUE; +} + +static guint32 +wifi_get_frequency(NMPlatform *platform, int ifindex) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, 0); + return nm_wifi_utils_get_freq(wifi_data); +} + +static gboolean +wifi_get_station(NMPlatform * platform, + int ifindex, + NMEtherAddr *out_bssid, + int * out_quality, + guint32 * out_rate) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE); + return nm_wifi_utils_get_station(wifi_data, out_bssid, out_quality, out_rate); +} + +static _NM80211Mode +wifi_get_mode(NMPlatform *platform, int ifindex) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, _NM_802_11_MODE_UNKNOWN); + return nm_wifi_utils_get_mode(wifi_data); +} + +static void +wifi_set_mode(NMPlatform *platform, int ifindex, _NM80211Mode mode) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, ); + nm_wifi_utils_set_mode(wifi_data, mode); +} + +static void +wifi_set_powersave(NMPlatform *platform, int ifindex, guint32 powersave) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, ); + nm_wifi_utils_set_powersave(wifi_data, powersave); +} + +static guint32 +wifi_find_frequency(NMPlatform *platform, int ifindex, const guint32 *freqs) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, 0); + return nm_wifi_utils_find_freq(wifi_data, freqs); +} + +static void +wifi_indicate_addressing_running(NMPlatform *platform, int ifindex, gboolean running) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, ); + nm_wifi_utils_indicate_addressing_running(wifi_data, running); +} + +static _NMSettingWirelessWakeOnWLan +wifi_get_wake_on_wlan(NMPlatform *platform, int ifindex) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE); + return nm_wifi_utils_get_wake_on_wlan(wifi_data); +} + +static gboolean +wifi_set_wake_on_wlan(NMPlatform *platform, int ifindex, _NMSettingWirelessWakeOnWLan wowl) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE); + return nm_wifi_utils_set_wake_on_wlan(wifi_data, wowl); +} + +/*****************************************************************************/ + +static gboolean +link_can_assume(NMPlatform *platform, int ifindex) +{ + NMPLookup lookup; + const NMPObject *link, *o; + NMDedupMultiIter iter; + NMPCache * cache = nm_platform_get_cache(platform); + + if (ifindex <= 0) + return FALSE; + + link = nm_platform_link_get_obj(platform, ifindex, TRUE); + if (!link) + return FALSE; + + if (!NM_FLAGS_HAS(link->link.n_ifi_flags, IFF_UP)) + return FALSE; + + if (link->link.master > 0) + return TRUE; + + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex); + if (nmp_cache_lookup(cache, &lookup)) + return TRUE; + + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP6_ADDRESS, ifindex); + nmp_cache_iter_for_each (&iter, nmp_cache_lookup(cache, &lookup), &o) { + nm_assert(NMP_OBJECT_GET_TYPE(o) == NMP_OBJECT_TYPE_IP6_ADDRESS); + if (!IN6_IS_ADDR_LINKLOCAL(&o->ip6_address.address)) + return TRUE; + } + return FALSE; +} + +/*****************************************************************************/ + +static guint32 +mesh_get_channel(NMPlatform *platform, int ifindex) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, 0); + return nm_wifi_utils_get_mesh_channel(wifi_data); +} + +static gboolean +mesh_set_channel(NMPlatform *platform, int ifindex, guint32 channel) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE); + return nm_wifi_utils_set_mesh_channel(wifi_data, channel); +} + +static gboolean +mesh_set_ssid(NMPlatform *platform, int ifindex, const guint8 *ssid, gsize len) +{ + WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE); + return nm_wifi_utils_set_mesh_ssid(wifi_data, ssid, len); +} + +/*****************************************************************************/ + +#define WPAN_GET_WPAN_DATA(wpan_data, platform, ifindex, retval) \ + NMWpanUtils *wpan_data = NM_WPAN_UTILS(get_ext_data(platform, ifindex)); \ + if (!wpan_data) \ + return retval; + +static guint16 +wpan_get_pan_id(NMPlatform *platform, int ifindex) +{ + WPAN_GET_WPAN_DATA(wpan_data, platform, ifindex, G_MAXINT16); + return nm_wpan_utils_get_pan_id(wpan_data); +} + +static gboolean +wpan_set_pan_id(NMPlatform *platform, int ifindex, guint16 pan_id) +{ + WPAN_GET_WPAN_DATA(wpan_data, platform, ifindex, FALSE); + return nm_wpan_utils_set_pan_id(wpan_data, pan_id); +} + +static guint16 +wpan_get_short_addr(NMPlatform *platform, int ifindex) +{ + WPAN_GET_WPAN_DATA(wpan_data, platform, ifindex, G_MAXINT16); + return nm_wpan_utils_get_short_addr(wpan_data); +} + +static gboolean +wpan_set_short_addr(NMPlatform *platform, int ifindex, guint16 short_addr) +{ + WPAN_GET_WPAN_DATA(wpan_data, platform, ifindex, FALSE); + return nm_wpan_utils_set_short_addr(wpan_data, short_addr); +} + +static gboolean +wpan_set_channel(NMPlatform *platform, int ifindex, guint8 page, guint8 channel) +{ + WPAN_GET_WPAN_DATA(wpan_data, platform, ifindex, FALSE); + return nm_wpan_utils_set_channel(wpan_data, page, channel); +} + +/*****************************************************************************/ + +static gboolean +link_get_wake_on_lan(NMPlatform *platform, int ifindex) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + NMLinkType type = nm_platform_link_get_type(platform, ifindex); + + if (!nm_platform_netns_push(platform, &netns)) + return FALSE; + + if (type == NM_LINK_TYPE_ETHERNET) + return nmp_utils_ethtool_get_wake_on_lan(ifindex); + else if (type == NM_LINK_TYPE_WIFI) { + NMWifiUtils *wifi_data = NM_WIFI_UTILS(get_ext_data(platform, ifindex)); + + if (!wifi_data) + return FALSE; + + return !NM_IN_SET(nm_wifi_utils_get_wake_on_wlan(wifi_data), + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE, + _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE); + + } else + return FALSE; +} + +static gboolean +link_get_driver_info(NMPlatform *platform, + int ifindex, + char ** out_driver_name, + char ** out_driver_version, + char ** out_fw_version) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + NMPUtilsEthtoolDriverInfo driver_info; + + if (!nm_platform_netns_push(platform, &netns)) + return FALSE; + + if (!nmp_utils_ethtool_get_driver_info(ifindex, &driver_info)) + return FALSE; + NM_SET_OUT(out_driver_name, g_strdup(driver_info.driver)); + NM_SET_OUT(out_driver_version, g_strdup(driver_info.version)); + NM_SET_OUT(out_fw_version, g_strdup(driver_info.fw_version)); + return TRUE; +} + +/*****************************************************************************/ + +static gboolean +ip4_address_add(NMPlatform *platform, + int ifindex, + in_addr_t addr, + guint8 plen, + in_addr_t peer_addr, + in_addr_t broadcast_address, + guint32 lifetime, + guint32 preferred, + guint32 flags, + const char *label) +{ + NMPObject obj_id; + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + nlmsg = _nl_msg_new_address(RTM_NEWADDR, + NLM_F_CREATE | NLM_F_REPLACE, + AF_INET, + ifindex, + &addr, + plen, + &peer_addr, + flags, + nm_utils_ip4_address_is_link_local(addr) ? RT_SCOPE_LINK + : RT_SCOPE_UNIVERSE, + lifetime, + preferred, + broadcast_address, + label); + + nmp_object_stackinit_id_ip4_address(&obj_id, ifindex, addr, plen, peer_addr); + return (do_add_addrroute(platform, &obj_id, nlmsg, FALSE) >= 0); +} + +static gboolean +ip6_address_add(NMPlatform * platform, + int ifindex, + struct in6_addr addr, + guint8 plen, + struct in6_addr peer_addr, + guint32 lifetime, + guint32 preferred, + guint32 flags) +{ + NMPObject obj_id; + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + nlmsg = _nl_msg_new_address(RTM_NEWADDR, + NLM_F_CREATE | NLM_F_REPLACE, + AF_INET6, + ifindex, + &addr, + plen, + IN6_IS_ADDR_UNSPECIFIED(&peer_addr) ? NULL : &peer_addr, + flags, + RT_SCOPE_UNIVERSE, + lifetime, + preferred, + 0, + NULL); + + nmp_object_stackinit_id_ip6_address(&obj_id, ifindex, &addr); + return (do_add_addrroute(platform, &obj_id, nlmsg, FALSE) >= 0); +} + +static gboolean +ip4_address_delete(NMPlatform *platform, + int ifindex, + in_addr_t addr, + guint8 plen, + in_addr_t peer_address) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + NMPObject obj_id; + + nlmsg = _nl_msg_new_address(RTM_DELADDR, + 0, + AF_INET, + ifindex, + &addr, + plen, + &peer_address, + 0, + RT_SCOPE_NOWHERE, + NM_PLATFORM_LIFETIME_PERMANENT, + NM_PLATFORM_LIFETIME_PERMANENT, + 0, + NULL); + if (!nlmsg) + g_return_val_if_reached(FALSE); + + nmp_object_stackinit_id_ip4_address(&obj_id, ifindex, addr, plen, peer_address); + return do_delete_object(platform, &obj_id, nlmsg); +} + +static gboolean +ip6_address_delete(NMPlatform *platform, int ifindex, struct in6_addr addr, guint8 plen) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + NMPObject obj_id; + + nlmsg = _nl_msg_new_address(RTM_DELADDR, + 0, + AF_INET6, + ifindex, + &addr, + plen, + NULL, + 0, + RT_SCOPE_NOWHERE, + NM_PLATFORM_LIFETIME_PERMANENT, + NM_PLATFORM_LIFETIME_PERMANENT, + 0, + NULL); + if (!nlmsg) + g_return_val_if_reached(FALSE); + + nmp_object_stackinit_id_ip6_address(&obj_id, ifindex, &addr); + return do_delete_object(platform, &obj_id, nlmsg); +} + +/*****************************************************************************/ + +static int +ip_route_add(NMPlatform * platform, + NMPNlmFlags flags, + int addr_family, + const NMPlatformIPRoute *route) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + NMPObject obj; + + nmp_object_stackinit(&obj, + NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family)), + (const NMPlatformObject *) route); + + nm_platform_ip_route_normalize(addr_family, NMP_OBJECT_CAST_IP_ROUTE(&obj)); + + nlmsg = _nl_msg_new_route(RTM_NEWROUTE, flags & NMP_NLM_FLAG_FMASK, &obj); + if (!nlmsg) + g_return_val_if_reached(-NME_BUG); + return do_add_addrroute(platform, + &obj, + nlmsg, + NM_FLAGS_HAS(flags, NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE)); +} + +static gboolean +object_delete(NMPlatform *platform, const NMPObject *obj) +{ + nm_auto_nmpobj const NMPObject *obj_keep_alive = NULL; + nm_auto_nlmsg struct nl_msg * nlmsg = NULL; + + if (!NMP_OBJECT_IS_STACKINIT(obj)) + obj_keep_alive = nmp_object_ref(obj); + + switch (NMP_OBJECT_GET_TYPE(obj)) { + case NMP_OBJECT_TYPE_IP4_ROUTE: + case NMP_OBJECT_TYPE_IP6_ROUTE: + nlmsg = _nl_msg_new_route(RTM_DELROUTE, 0, obj); + break; + case NMP_OBJECT_TYPE_ROUTING_RULE: + nlmsg = _nl_msg_new_routing_rule(RTM_DELRULE, 0, NMP_OBJECT_CAST_ROUTING_RULE(obj)); + break; + case NMP_OBJECT_TYPE_QDISC: + nlmsg = _nl_msg_new_qdisc(RTM_DELQDISC, 0, NMP_OBJECT_CAST_QDISC(obj)); + break; + case NMP_OBJECT_TYPE_TFILTER: + nlmsg = _nl_msg_new_tfilter(RTM_DELTFILTER, 0, NMP_OBJECT_CAST_TFILTER(obj)); + break; + default: + break; + } + + if (!nlmsg) + g_return_val_if_reached(FALSE); + return do_delete_object(platform, obj, nlmsg); +} + +/*****************************************************************************/ + +static int +ip_route_get(NMPlatform * platform, + int addr_family, + gconstpointer address, + int oif_ifindex, + NMPObject ** out_route) +{ + const gboolean is_v4 = (addr_family == AF_INET); + const int addr_len = is_v4 ? 4 : 16; + int try_count = 0; + WaitForNlResponseResult seq_result; + int nle; + nm_auto_nmpobj NMPObject *route = NULL; + + nm_assert(NM_IS_LINUX_PLATFORM(platform)); + nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + nm_assert(address); + + do { + struct { + struct nlmsghdr n; + struct rtmsg r; + char buf[64]; + } req = { + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)), + .n.nlmsg_flags = NLM_F_REQUEST, + .n.nlmsg_type = RTM_GETROUTE, + .r.rtm_family = addr_family, + .r.rtm_tos = 0, + .r.rtm_dst_len = is_v4 ? 32 : 128, + .r.rtm_flags = 0x1000 /* RTM_F_LOOKUP_TABLE */, + }; + + nm_clear_pointer(&route, nmp_object_unref); + + if (!_nl_addattr_l(&req.n, sizeof(req), RTA_DST, address, addr_len)) + nm_assert_not_reached(); + + if (oif_ifindex > 0) { + gint32 ii = oif_ifindex; + + if (!_nl_addattr_l(&req.n, sizeof(req), RTA_OIF, &ii, sizeof(ii))) + nm_assert_not_reached(); + } + + seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; + nle = _nl_send_nlmsghdr(platform, + &req.n, + &seq_result, + NULL, + DELAYED_ACTION_RESPONSE_TYPE_ROUTE_GET, + &route); + if (nle < 0) { + _LOGE("get-route: failure sending netlink request \"%s\" (%d)", + nm_strerror_native(-nle), + -nle); + return -NME_UNSPEC; + } + + delayed_action_handle_all(platform, FALSE); + + /* Retry, if we failed due to a cache resync. That can happen when the netlink + * socket fills up and we lost the response. */ + } while (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC && ++try_count < 10); + + if (seq_result < 0) { + /* negative seq_result is an errno from kernel. Map it to negative + * int (which are also errno). */ + return (int) seq_result; + } + + if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) { + if (route) { + NM_SET_OUT(out_route, g_steal_pointer(&route)); + return 0; + } + seq_result = WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_UNKNOWN; + } + + return -NME_UNSPEC; +} + +/*****************************************************************************/ + +static int +routing_rule_add(NMPlatform *platform, NMPNlmFlags flags, const NMPlatformRoutingRule *routing_rule) +{ + WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; + nm_auto_nlmsg struct nl_msg *msg = NULL; + gs_free char * errmsg = NULL; + char s_buf[256]; + int nle; + + msg = _nl_msg_new_routing_rule(RTM_NEWRULE, flags, routing_rule); + + event_handler_read_netlink(platform, FALSE); + + nle = _nl_send_nlmsg(platform, + msg, + &seq_result, + &errmsg, + DELAYED_ACTION_RESPONSE_TYPE_VOID, + NULL); + if (nle < 0) { + _LOGE("do-add-rule: failed sending netlink request \"%s\" (%d)", nm_strerror(nle), -nle); + return -NME_PL_NETLINK; + } + + delayed_action_handle_all(platform, FALSE); + + nm_assert(seq_result); + + _NMLOG(seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK ? LOGL_DEBUG : LOGL_WARN, + "do-add-rule: %s", + wait_for_nl_response_to_string(seq_result, errmsg, s_buf, sizeof(s_buf))); + + if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) + return 0; + if (seq_result < 0) + return seq_result; + return -NME_UNSPEC; +} + +/*****************************************************************************/ + +static int +qdisc_add(NMPlatform *platform, NMPNlmFlags flags, const NMPlatformQdisc *qdisc) +{ + WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; + gs_free char * errmsg = NULL; + int nle; + char s_buf[256]; + nm_auto_nlmsg struct nl_msg *msg = NULL; + + /* Note: @qdisc must not be copied or kept alive because the lifetime of qdisc.kind + * is undefined. */ + + msg = _nl_msg_new_qdisc(RTM_NEWQDISC, flags, qdisc); + + event_handler_read_netlink(platform, FALSE); + + nle = _nl_send_nlmsg(platform, + msg, + &seq_result, + &errmsg, + DELAYED_ACTION_RESPONSE_TYPE_VOID, + NULL); + if (nle < 0) { + _LOGE("do-add-qdisc: failed sending netlink request \"%s\" (%d)", nm_strerror(nle), -nle); + return -NME_PL_NETLINK; + } + + delayed_action_handle_all(platform, FALSE); + + nm_assert(seq_result); + + _NMLOG(seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK ? LOGL_DEBUG : LOGL_WARN, + "do-add-qdisc: %s", + wait_for_nl_response_to_string(seq_result, errmsg, s_buf, sizeof(s_buf))); + + if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) + return 0; + if (seq_result < 0) + return seq_result; + return -NME_UNSPEC; +} + +/*****************************************************************************/ + +static int +tfilter_add(NMPlatform *platform, NMPNlmFlags flags, const NMPlatformTfilter *tfilter) +{ + WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; + gs_free char * errmsg = NULL; + int nle; + char s_buf[256]; + nm_auto_nlmsg struct nl_msg *msg = NULL; + + /* Note: @tfilter must not be copied or kept alive because the lifetime of tfilter.kind + * and tfilter.action.kind is undefined. */ + + msg = _nl_msg_new_tfilter(RTM_NEWTFILTER, flags, tfilter); + + event_handler_read_netlink(platform, FALSE); + + nle = _nl_send_nlmsg(platform, + msg, + &seq_result, + &errmsg, + DELAYED_ACTION_RESPONSE_TYPE_VOID, + NULL); + if (nle < 0) { + _LOGE("do-add-tfilter: failed sending netlink request \"%s\" (%d)", nm_strerror(nle), -nle); + return -NME_PL_NETLINK; + } + + delayed_action_handle_all(platform, FALSE); + + nm_assert(seq_result); + + _NMLOG(seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK ? LOGL_DEBUG : LOGL_WARN, + "do-add-tfilter: %s", + wait_for_nl_response_to_string(seq_result, errmsg, s_buf, sizeof(s_buf))); + + if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) + return 0; + + return -NME_UNSPEC; +} + +/*****************************************************************************/ + +static gboolean +event_handler(int fd, GIOCondition io_condition, gpointer user_data) +{ + delayed_action_handle_all(NM_PLATFORM(user_data), TRUE); + return TRUE; +} + +/*****************************************************************************/ + +/* copied from libnl3's recvmsgs() */ +static int +event_handler_recvmsgs(NMPlatform *platform, gboolean handle_events) +{ + NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + struct nl_sock * sk = priv->nlh; + int n; + int err = 0; + gboolean multipart = 0; + gboolean interrupted = FALSE; + struct nlmsghdr * hdr; + WaitForNlResponseResult seq_result; + struct sockaddr_nl nla = {0}; + struct ucred creds; + gboolean creds_has; + nm_auto_free unsigned char *buf = NULL; + +continue_reading: + nm_clear_pointer(&buf, free); + n = nl_recv(sk, &nla, &buf, &creds, &creds_has); + + if (n <= 0) { + if (n == -NME_NL_MSG_TRUNC) { + int buf_size; + + /* the message receive buffer was too small. We lost one message, which + * is unfortunate. Try to double the buffer size for the next time. */ + buf_size = nl_socket_get_msg_buf_size(sk); + if (buf_size < 512 * 1024) { + buf_size *= 2; + _LOGT("netlink: recvmsg: increase message buffer size for recvmsg() to %d bytes", + buf_size); + if (nl_socket_set_msg_buf_size(sk, buf_size) < 0) + nm_assert_not_reached(); + if (!handle_events) + goto continue_reading; + } + } + + return n; + } + + hdr = (struct nlmsghdr *) buf; + while (nlmsg_ok(hdr, n)) { + nm_auto_nlmsg struct nl_msg *msg = NULL; + gboolean abort_parsing = FALSE; + gboolean process_valid_msg = FALSE; + guint32 seq_number; + char buf_nlmsghdr[400]; + const char * extack_msg = NULL; + + msg = nlmsg_alloc_convert(hdr); + + nlmsg_set_proto(msg, NETLINK_ROUTE); + nlmsg_set_src(msg, &nla); + + if (!creds_has || creds.pid) { + if (!creds_has) + _LOGT("netlink: recvmsg: received message without credentials"); + else + _LOGT("netlink: recvmsg: received non-kernel message (pid %d)", creds.pid); + err = 0; + goto stop; + } + + _LOGt("netlink: recvmsg: new message %s", + nl_nlmsghdr_to_str(hdr, buf_nlmsghdr, sizeof(buf_nlmsghdr))); + + nlmsg_set_creds(msg, &creds); + + if (hdr->nlmsg_flags & NLM_F_MULTI) + multipart = TRUE; + + if (hdr->nlmsg_flags & NLM_F_DUMP_INTR) { + /* + * We have to continue reading to clear + * all messages until a NLMSG_DONE is + * received and report the inconsistency. + */ + interrupted = TRUE; + } + + /* Other side wishes to see an ack for this message */ + if (hdr->nlmsg_flags & NLM_F_ACK) { + /* FIXME: implement */ + } + + seq_result = WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_UNKNOWN; + + if (hdr->nlmsg_type == NLMSG_DONE) { + /* messages terminates a multipart message, this is + * usually the end of a message and therefore we slip + * out of the loop by default. the user may overrule + * this action by skipping this packet. */ + multipart = FALSE; + seq_result = WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK; + } else if (hdr->nlmsg_type == NLMSG_NOOP) { + /* Message to be ignored, the default action is to + * skip this message if no callback is specified. The + * user may overrule this action by returning + * NL_PROCEED. */ + } else if (hdr->nlmsg_type == NLMSG_OVERRUN) { + /* Data got lost, report back to user. The default action is to + * quit parsing. The user may overrule this action by returning + * NL_SKIP or NL_PROCEED (dangerous) */ + err = -NME_NL_MSG_OVERFLOW; + abort_parsing = TRUE; + } else if (hdr->nlmsg_type == NLMSG_ERROR) { + /* Message carries a nlmsgerr */ + struct nlmsgerr *e = nlmsg_data(hdr); + + if (hdr->nlmsg_len < nlmsg_size(sizeof(*e))) { + /* Truncated error message, the default action + * is to stop parsing. The user may overrule + * this action by returning NL_SKIP or + * NL_PROCEED (dangerous) */ + err = -NME_NL_MSG_TRUNC; + abort_parsing = TRUE; + } else if (e->error) { + int errsv = nm_errno_native(e->error); + + if (NM_FLAGS_HAS(hdr->nlmsg_flags, NLM_F_ACK_TLVS) + && hdr->nlmsg_len >= sizeof(*e) + e->msg.nlmsg_len) { + static const struct nla_policy policy[] = { + [NLMSGERR_ATTR_MSG] = {.type = NLA_STRING}, + [NLMSGERR_ATTR_OFFS] = {.type = NLA_U32}, + }; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + struct nlattr *tlvs; + + tlvs = (struct nlattr *) ((char *) e + sizeof(*e) + e->msg.nlmsg_len + - NLMSG_HDRLEN); + if (nla_parse_arr(tb, + tlvs, + hdr->nlmsg_len - sizeof(*e) - e->msg.nlmsg_len, + policy) + >= 0) { + if (tb[NLMSGERR_ATTR_MSG]) + extack_msg = nla_get_string(tb[NLMSGERR_ATTR_MSG]); + } + } + + /* Error message reported back from kernel. */ + _LOGD("netlink: recvmsg: error message from kernel: %s (%d)%s%s%s for request %d", + nm_strerror_native(errsv), + errsv, + NM_PRINT_FMT_QUOTED(extack_msg, " \"", extack_msg, "\"", ""), + nlmsg_hdr(msg)->nlmsg_seq); + seq_result = -NM_ERRNO_NATIVE(errsv); + } else + seq_result = WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK; + } else + process_valid_msg = TRUE; + + seq_number = nlmsg_hdr(msg)->nlmsg_seq; + + /* check whether the seq number is different from before, and + * whether the previous number (@nlh_seq_last_seen) is a pending + * refresh-all request. In that case, the pending request is thereby + * completed. + * + * We must do that before processing the message with event_valid_msg(), + * because we must track the completion of the pending request before that. */ + event_seq_check_refresh_all(platform, seq_number); + + if (process_valid_msg) { + /* Valid message (not checking for MULTIPART bit to + * get along with broken kernels. NL_SKIP has no + * effect on this. */ + + event_valid_msg(platform, msg, handle_events); + + seq_result = WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK; + } + + event_seq_check(platform, seq_number, seq_result, extack_msg); + + if (abort_parsing) + goto stop; + + err = 0; + hdr = nlmsg_next(hdr, &n); + } + + if (multipart) { + /* Multipart message not yet complete, continue reading */ + goto continue_reading; + } +stop: + if (!handle_events) { + /* when we don't handle events, we want to drain all messages from the socket + * without handling the messages (but still check for sequence numbers). + * Repeat reading. */ + goto continue_reading; + } + + if (interrupted) + return -NME_NL_DUMP_INTR; + return err; +} + +/*****************************************************************************/ + +static gboolean +event_handler_read_netlink(NMPlatform *platform, gboolean wait_for_acks) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + NMLinuxPlatformPrivate * priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + int r; + struct pollfd pfd; + gboolean any = FALSE; + int timeout_msec; + struct { + guint32 seq_number; + gint64 timeout_abs_ns; + gint64 now_ns; + } next; + + if (!nm_platform_netns_push(platform, &netns)) { + delayed_action_wait_for_nl_response_complete_all(platform, + WAIT_FOR_NL_RESPONSE_RESULT_FAILED_SETNS); + return FALSE; + } + + for (;;) { + for (;;) { + int nle; + + nle = event_handler_recvmsgs(platform, TRUE); + + if (nle < 0) { + switch (nle) { + case -EAGAIN: + goto after_read; + case -NME_NL_DUMP_INTR: + _LOGD("netlink: read: uncritical failure to retrieve incoming events: %s (%d)", + nm_strerror(nle), + nle); + break; + case -NME_NL_MSG_TRUNC: + case -ENOBUFS: + _LOGI("netlink: read: %s. Need to resynchronize platform cache", ({ + const char *_reason = "unknown"; + switch (nle) { + case -NME_NL_MSG_TRUNC: + _reason = "message truncated"; + break; + case -ENOBUFS: + _reason = "too many netlink events"; + break; + } + _reason; + })); + event_handler_recvmsgs(platform, FALSE); + delayed_action_wait_for_nl_response_complete_all( + platform, + WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC); + + delayed_action_schedule(platform, + DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES + | DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_ALL + | DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS + | DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS, + NULL); + break; + default: + _LOGE("netlink: read: failed to retrieve incoming events: %s (%d)", + nm_strerror(nle), + nle); + break; + } + } + any = TRUE; + } + +after_read: + + if (!NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) + return any; + + delayed_action_wait_for_nl_response_complete_check(platform, + WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN, + &next.seq_number, + &next.timeout_abs_ns, + &next.now_ns); + + if (!wait_for_acks + || !NM_FLAGS_HAS(priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) + return any; + + nm_assert(next.seq_number); + nm_assert(next.now_ns > 0); + nm_assert(next.timeout_abs_ns > next.now_ns); + + _LOGT("netlink: read: wait for ACK for sequence number %u...", next.seq_number); + + timeout_msec = (next.timeout_abs_ns - next.now_ns) / (NM_UTILS_NSEC_PER_SEC / 1000); + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = nl_socket_get_fd(priv->nlh); + pfd.events = POLLIN; + r = poll(&pfd, 1, MAX(1, timeout_msec)); + + if (r == 0) { + /* timeout and there is nothing to read. */ + goto after_read; + } + + if (r < 0) { + int errsv = errno; + + if (errsv != EINTR) { + _LOGE("netlink: read: poll failed with %s", nm_strerror_native(errsv)); + delayed_action_wait_for_nl_response_complete_all( + platform, + WAIT_FOR_NL_RESPONSE_RESULT_FAILED_POLL); + return any; + } + /* Continue to read again, even if there might be nothing to read after EINTR. */ + } + } +} + +/*****************************************************************************/ + +static void +cache_update_link_udev(NMPlatform *platform, int ifindex, struct udev_device *udevice) +{ + nm_auto_nmpobj const NMPObject *obj_old = NULL; + nm_auto_nmpobj const NMPObject *obj_new = NULL; + NMPCacheOpsType cache_op; + + cache_op = nmp_cache_update_link_udev(nm_platform_get_cache(platform), + ifindex, + udevice, + &obj_old, + &obj_new); + + if (cache_op != NMP_CACHE_OPS_UNCHANGED) { + nm_auto_pop_netns NMPNetns *netns = NULL; + + cache_on_change(platform, cache_op, obj_old, obj_new); + if (!nm_platform_netns_push(platform, &netns)) + return; + nm_platform_cache_update_emit_signal(platform, cache_op, obj_old, obj_new); + } +} + +static void +udev_device_added(NMPlatform *platform, struct udev_device *udevice) +{ + const char *ifname; + const char *ifindex_s; + int ifindex; + + ifname = udev_device_get_sysname(udevice); + if (!ifname) { + _LOGD("udev-add: failed to get device's interface"); + return; + } + + ifindex_s = udev_device_get_property_value(udevice, "IFINDEX"); + if (!ifindex_s) { + _LOGW("udev-add[%s]failed to get device's ifindex", ifname); + return; + } + ifindex = _nm_utils_ascii_str_to_int64(ifindex_s, 10, 1, G_MAXINT, 0); + if (ifindex <= 0) { + _LOGW("udev-add[%s]: retrieved invalid IFINDEX=%d", ifname, ifindex); + return; + } + + if (!udev_device_get_syspath(udevice)) { + _LOGD("udev-add[%s,%d]: couldn't determine device path; ignoring...", ifname, ifindex); + return; + } + + _LOGT("udev-add[%s,%d]: device added", ifname, ifindex); + cache_update_link_udev(platform, ifindex, udevice); +} + +static gboolean +_udev_device_removed_match_link(const NMPObject *obj, gpointer udevice) +{ + return obj->_link.udev.device == udevice; +} + +static void +udev_device_removed(NMPlatform *platform, struct udev_device *udevice) +{ + const char *ifindex_s; + int ifindex = 0; + + ifindex_s = udev_device_get_property_value(udevice, "IFINDEX"); + ifindex = _nm_utils_ascii_str_to_int64(ifindex_s, 10, 1, G_MAXINT, 0); + if (ifindex <= 0) { + const NMPObject *obj; + + obj = nmp_cache_lookup_link_full(nm_platform_get_cache(platform), + 0, + NULL, + FALSE, + NM_LINK_TYPE_NONE, + _udev_device_removed_match_link, + udevice); + if (obj) + ifindex = obj->link.ifindex; + } + + _LOGD("udev-remove: IFINDEX=%d", ifindex); + if (ifindex <= 0) + return; + + cache_update_link_udev(platform, ifindex, NULL); +} + +static void +handle_udev_event(NMUdevClient *udev_client, struct udev_device *udevice, gpointer user_data) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + NMPlatform * platform = NM_PLATFORM(user_data); + const char * subsys; + const char * ifindex; + guint64 seqnum; + const char * action; + + action = udev_device_get_action(udevice); + g_return_if_fail(action); + + subsys = udev_device_get_subsystem(udevice); + g_return_if_fail(nm_streq0(subsys, "net")); + + if (!nm_platform_netns_push(platform, &netns)) + return; + + ifindex = udev_device_get_property_value(udevice, "IFINDEX"); + seqnum = udev_device_get_seqnum(udevice); + _LOGD("UDEV event: action '%s' subsys '%s' device '%s' (%s); seqnum=%" G_GUINT64_FORMAT, + action, + subsys, + udev_device_get_sysname(udevice), + ifindex ?: "unknown", + seqnum); + + if (NM_IN_STRSET(action, "add", "move")) + udev_device_added(platform, udevice); + else if (NM_IN_STRSET(action, "remove")) + udev_device_removed(platform, udevice); +} + +/*****************************************************************************/ + +static void +nm_linux_platform_init(NMLinuxPlatform *self) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(self); + + c_list_init(&priv->sysctl_clear_cache_lst); + c_list_init(&priv->sysctl_list); + + priv->delayed_action.list_master_connected = g_ptr_array_new(); + priv->delayed_action.list_refresh_link = g_ptr_array_new(); + priv->delayed_action.list_wait_for_nl_response = + g_array_new(FALSE, TRUE, sizeof(DelayedActionWaitForNlResponseData)); +} + +static void +constructed(GObject *_object) +{ + NMPlatform * platform = NM_PLATFORM(_object); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + int nle; + int fd; + + nm_assert(!platform->_netns || platform->_netns == nmp_netns_get_current()); + + if (nm_platform_get_use_udev(platform)) { + priv->udev_client = nm_udev_client_new(NM_MAKE_STRV("net"), handle_udev_event, platform); + } + + _LOGD("create (%s netns, %s, %s udev)", + !platform->_netns ? "ignore" : "use", + !platform->_netns && nmp_netns_is_initial() + ? "initial netns" + : (!nmp_netns_get_current() + ? "no netns support" + : nm_sprintf_bufa(100, + "in netns[%p]%s", + nmp_netns_get_current(), + nmp_netns_get_current() == nmp_netns_get_initial() ? "/main" + : "")), + nm_platform_get_use_udev(platform) ? "use" : "no"); + + priv->genl = nl_socket_alloc(); + g_assert(priv->genl); + + nle = nl_connect(priv->genl, NETLINK_GENERIC); + if (nle) { + _LOGE("unable to connect the generic netlink socket \"%s\" (%d)", nm_strerror(nle), -nle); + nl_socket_free(priv->genl); + priv->genl = NULL; + } + + priv->nlh = nl_socket_alloc(); + g_assert(priv->nlh); + + nle = nl_connect(priv->nlh, NETLINK_ROUTE); + g_assert(!nle); + nle = nl_socket_set_passcred(priv->nlh, 1); + g_assert(!nle); + + /* No blocking for event socket, so that we can drain it safely. */ + nle = nl_socket_set_nonblocking(priv->nlh); + g_assert(!nle); + + /* use 8 MB for receive socket kernel queue. */ + nle = nl_socket_set_buffer_size(priv->nlh, 8 * 1024 * 1024, 0); + g_assert(!nle); + + nle = nl_socket_set_ext_ack(priv->nlh, TRUE); + if (nle) + _LOGD("could not enable extended acks on netlink socket"); + + /* explicitly set the msg buffer size and disable MSG_PEEK. + * If we later encounter NME_NL_MSG_TRUNC, we will adjust the buffer size. */ + nl_socket_disable_msg_peek(priv->nlh); + nle = nl_socket_set_msg_buf_size(priv->nlh, 32 * 1024); + g_assert(!nle); + + nle = nl_socket_add_memberships(priv->nlh, + RTNLGRP_IPV4_IFADDR, + RTNLGRP_IPV4_ROUTE, + RTNLGRP_IPV4_RULE, + RTNLGRP_IPV6_RULE, + RTNLGRP_IPV6_IFADDR, + RTNLGRP_IPV6_ROUTE, + RTNLGRP_LINK, + RTNLGRP_TC, + 0); + g_assert(!nle); + + fd = nl_socket_get_fd(priv->nlh); + + _LOGD("Netlink socket for events established: port=%u, fd=%d", + nl_socket_get_local_port(priv->nlh), + fd); + + priv->event_source = + nm_g_unix_fd_source_new(fd, + G_IO_IN | G_IO_NVAL | G_IO_PRI | G_IO_ERR | G_IO_HUP, + G_PRIORITY_DEFAULT, + event_handler, + platform, + NULL); + g_source_attach(priv->event_source, NULL); + + /* complete construction of the GObject instance before populating the cache. */ + G_OBJECT_CLASS(nm_linux_platform_parent_class)->constructed(_object); + + _LOGD("populate platform cache"); + delayed_action_schedule( + platform, + DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS | DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES + | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES + | DELAYED_ACTION_TYPE_REFRESH_ALL_ROUTING_RULES_ALL + | DELAYED_ACTION_TYPE_REFRESH_ALL_QDISCS | DELAYED_ACTION_TYPE_REFRESH_ALL_TFILTERS, + NULL); + + delayed_action_handle_all(platform, FALSE); + + /* Set up udev monitoring */ + if (priv->udev_client) { + struct udev_enumerate * enumerator; + struct udev_list_entry *devices, *l; + + /* And read initial device list */ + enumerator = nm_udev_client_enumerate_new(priv->udev_client); + + udev_enumerate_add_match_is_initialized(enumerator); + + udev_enumerate_scan_devices(enumerator); + + devices = udev_enumerate_get_list_entry(enumerator); + for (l = devices; l; l = udev_list_entry_get_next(l)) { + struct udev_device *udevice; + + udevice = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerator), + udev_list_entry_get_name(l)); + if (!udevice) + continue; + + udev_device_added(platform, udevice); + udev_device_unref(udevice); + } + + udev_enumerate_unref(enumerator); + } +} + +/* Similar to systemd's path_is_read_only_fs(), at + * https://github.com/systemd/systemd/blob/v246/src/basic/stat-util.c#L132 */ +static int +path_is_read_only_fs(const char *path) +{ + struct statvfs st; + + if (statvfs(path, &st) < 0) + return -errno; + + if (st.f_flag & ST_RDONLY) + return TRUE; + + /* On NFS, statvfs() might not reflect whether we can actually + * write to the remote share. Let's try again with + * access(W_OK) which is more reliable, at least sometimes. */ + if (access(path, W_OK) < 0 && errno == EROFS) + return TRUE; + + return FALSE; +} + +NMPlatform * +nm_linux_platform_new(gboolean log_with_ptr, gboolean netns_support) +{ + gboolean use_udev = FALSE; + + if (nmp_netns_is_initial() && path_is_read_only_fs("/sys") == FALSE) + use_udev = TRUE; + + return g_object_new(NM_TYPE_LINUX_PLATFORM, + NM_PLATFORM_LOG_WITH_PTR, + log_with_ptr, + NM_PLATFORM_USE_UDEV, + use_udev, + NM_PLATFORM_NETNS_SUPPORT, + netns_support, + NULL); +} + +static void +dispose(GObject *object) +{ + NMPlatform * platform = NM_PLATFORM(object); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform); + + _LOGD("dispose"); + + delayed_action_wait_for_nl_response_complete_all(platform, + WAIT_FOR_NL_RESPONSE_RESULT_FAILED_DISPOSING); + + priv->delayed_action.flags = DELAYED_ACTION_TYPE_NONE; + g_ptr_array_set_size(priv->delayed_action.list_master_connected, 0); + g_ptr_array_set_size(priv->delayed_action.list_refresh_link, 0); + + G_OBJECT_CLASS(nm_linux_platform_parent_class)->dispose(object); +} + +static void +finalize(GObject *object) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(object); + + g_ptr_array_unref(priv->delayed_action.list_master_connected); + g_ptr_array_unref(priv->delayed_action.list_refresh_link); + g_array_unref(priv->delayed_action.list_wait_for_nl_response); + + nl_socket_free(priv->genl); + + nm_clear_g_source_inst(&priv->event_source); + + nl_socket_free(priv->nlh); + + { + NM_G_MUTEX_LOCKED(&sysctl_clear_cache_lock); + + if (priv->sysctl_get_prev_values) { + c_list_unlink(&priv->sysctl_clear_cache_lst); + g_hash_table_destroy(priv->sysctl_get_prev_values); + } + + nm_assert(c_list_is_empty(&priv->sysctl_clear_cache_lst)); + nm_assert(c_list_is_empty(&priv->sysctl_list)); + } + + priv->udev_client = nm_udev_client_destroy(priv->udev_client); + + G_OBJECT_CLASS(nm_linux_platform_parent_class)->finalize(object); +} + +static void +nm_linux_platform_class_init(NMLinuxPlatformClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMPlatformClass *platform_class = NM_PLATFORM_CLASS(klass); + + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->finalize = finalize; + + platform_class->sysctl_set = sysctl_set; + platform_class->sysctl_set_async = sysctl_set_async; + platform_class->sysctl_get = sysctl_get; + + platform_class->link_add = link_add; + platform_class->link_delete = link_delete; + + platform_class->link_refresh = link_refresh; + + platform_class->link_set_netns = link_set_netns; + + platform_class->link_set_up = link_set_up; + platform_class->link_set_down = link_set_down; + platform_class->link_set_arp = link_set_arp; + platform_class->link_set_noarp = link_set_noarp; + + platform_class->link_set_user_ipv6ll_enabled = link_set_user_ipv6ll_enabled; + platform_class->link_set_token = link_set_token; + + platform_class->link_set_address = link_set_address; + platform_class->link_get_permanent_address = link_get_permanent_address; + platform_class->link_set_mtu = link_set_mtu; + platform_class->link_set_name = link_set_name; + platform_class->link_set_sriov_params_async = link_set_sriov_params_async; + platform_class->link_set_sriov_vfs = link_set_sriov_vfs; + platform_class->link_set_bridge_vlans = link_set_bridge_vlans; + + platform_class->link_get_physical_port_id = link_get_physical_port_id; + platform_class->link_get_dev_id = link_get_dev_id; + platform_class->link_get_wake_on_lan = link_get_wake_on_lan; + platform_class->link_get_driver_info = link_get_driver_info; + + platform_class->link_supports_carrier_detect = link_supports_carrier_detect; + platform_class->link_supports_vlans = link_supports_vlans; + platform_class->link_supports_sriov = link_supports_sriov; + + platform_class->link_enslave = link_enslave; + platform_class->link_release = link_release; + + platform_class->link_can_assume = link_can_assume; + + platform_class->link_vlan_change = link_vlan_change; + platform_class->link_wireguard_change = link_wireguard_change; + + platform_class->infiniband_partition_add = infiniband_partition_add; + platform_class->infiniband_partition_delete = infiniband_partition_delete; + + platform_class->wifi_get_capabilities = wifi_get_capabilities; + platform_class->wifi_get_frequency = wifi_get_frequency; + platform_class->wifi_get_station = wifi_get_station; + platform_class->wifi_get_mode = wifi_get_mode; + platform_class->wifi_set_mode = wifi_set_mode; + platform_class->wifi_set_powersave = wifi_set_powersave; + platform_class->wifi_find_frequency = wifi_find_frequency; + platform_class->wifi_indicate_addressing_running = wifi_indicate_addressing_running; + platform_class->wifi_get_wake_on_wlan = wifi_get_wake_on_wlan; + platform_class->wifi_set_wake_on_wlan = wifi_set_wake_on_wlan; + + platform_class->mesh_get_channel = mesh_get_channel; + platform_class->mesh_set_channel = mesh_set_channel; + platform_class->mesh_set_ssid = mesh_set_ssid; + + platform_class->wpan_get_pan_id = wpan_get_pan_id; + platform_class->wpan_set_pan_id = wpan_set_pan_id; + platform_class->wpan_get_short_addr = wpan_get_short_addr; + platform_class->wpan_set_short_addr = wpan_set_short_addr; + platform_class->wpan_set_channel = wpan_set_channel; + + platform_class->link_tun_add = link_tun_add; + + platform_class->object_delete = object_delete; + platform_class->ip4_address_add = ip4_address_add; + platform_class->ip6_address_add = ip6_address_add; + platform_class->ip4_address_delete = ip4_address_delete; + platform_class->ip6_address_delete = ip6_address_delete; + + platform_class->ip_route_add = ip_route_add; + platform_class->ip_route_get = ip_route_get; + + platform_class->routing_rule_add = routing_rule_add; + + platform_class->qdisc_add = qdisc_add; + platform_class->tfilter_add = tfilter_add; + + platform_class->process_events = process_events; +} diff --git a/src/libnm-platform/nm-linux-platform.h b/src/libnm-platform/nm-linux-platform.h new file mode 100644 index 0000000..26c31e3 --- /dev/null +++ b/src/libnm-platform/nm-linux-platform.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2012 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_LINUX_PLATFORM_H__ +#define __NETWORKMANAGER_LINUX_PLATFORM_H__ + +#include "nm-platform.h" + +#define NM_TYPE_LINUX_PLATFORM (nm_linux_platform_get_type()) +#define NM_LINUX_PLATFORM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_LINUX_PLATFORM, NMLinuxPlatform)) +#define NM_LINUX_PLATFORM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_LINUX_PLATFORM, NMLinuxPlatformClass)) +#define NM_IS_LINUX_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_LINUX_PLATFORM)) +#define NM_IS_LINUX_PLATFORM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_LINUX_PLATFORM)) +#define NM_LINUX_PLATFORM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_LINUX_PLATFORM, NMLinuxPlatformClass)) + +typedef struct _NMLinuxPlatform NMLinuxPlatform; +typedef struct _NMLinuxPlatformClass NMLinuxPlatformClass; + +GType nm_linux_platform_get_type(void); + +NMPlatform *nm_linux_platform_new(gboolean log_with_ptr, gboolean netns_support); + +#endif /* __NETWORKMANAGER_LINUX_PLATFORM_H__ */ diff --git a/src/libnm-platform/nm-netlink.c b/src/libnm-platform/nm-netlink.c new file mode 100644 index 0000000..95010c0 --- /dev/null +++ b/src/libnm-platform/nm-netlink.c @@ -0,0 +1,1518 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-netlink.h" + +#include +#include + +/*****************************************************************************/ + +#ifndef SOL_NETLINK + #define SOL_NETLINK 270 +#endif + +/*****************************************************************************/ + +#define NL_SOCK_PASSCRED (1 << 1) +#define NL_MSG_PEEK (1 << 3) +#define NL_MSG_PEEK_EXPLICIT (1 << 4) +#define NL_NO_AUTO_ACK (1 << 5) + +#ifndef NETLINK_EXT_ACK + #define NETLINK_EXT_ACK 11 +#endif + +struct nl_msg { + int nm_protocol; + struct sockaddr_nl nm_src; + struct sockaddr_nl nm_dst; + struct ucred nm_creds; + struct nlmsghdr * nm_nlh; + size_t nm_size; + bool nm_creds_has : 1; +}; + +struct nl_sock { + struct sockaddr_nl s_local; + struct sockaddr_nl s_peer; + int s_fd; + int s_proto; + unsigned int s_seq_next; + unsigned int s_seq_expect; + int s_flags; + size_t s_bufsize; +}; + +/*****************************************************************************/ + +NM_UTILS_ENUM2STR_DEFINE(nl_nlmsgtype2str, + int, + NM_UTILS_ENUM2STR(NLMSG_NOOP, "NOOP"), + NM_UTILS_ENUM2STR(NLMSG_ERROR, "ERROR"), + NM_UTILS_ENUM2STR(NLMSG_DONE, "DONE"), + NM_UTILS_ENUM2STR(NLMSG_OVERRUN, "OVERRUN"), ); + +NM_UTILS_FLAGS2STR_DEFINE(nl_nlmsg_flags2str, + int, + NM_UTILS_FLAGS2STR(NLM_F_REQUEST, "REQUEST"), + NM_UTILS_FLAGS2STR(NLM_F_MULTI, "MULTI"), + NM_UTILS_FLAGS2STR(NLM_F_ACK, "ACK"), + NM_UTILS_FLAGS2STR(NLM_F_ECHO, "ECHO"), + NM_UTILS_FLAGS2STR(NLM_F_ROOT, "ROOT"), + NM_UTILS_FLAGS2STR(NLM_F_MATCH, "MATCH"), + NM_UTILS_FLAGS2STR(NLM_F_ATOMIC, "ATOMIC"), + NM_UTILS_FLAGS2STR(NLM_F_REPLACE, "REPLACE"), + NM_UTILS_FLAGS2STR(NLM_F_EXCL, "EXCL"), + NM_UTILS_FLAGS2STR(NLM_F_CREATE, "CREATE"), + NM_UTILS_FLAGS2STR(NLM_F_APPEND, "APPEND"), ); + +/*****************************************************************************/ + +const char * +nl_nlmsghdr_to_str(const struct nlmsghdr *hdr, char *buf, gsize len) +{ + const char *b; + const char *s; + guint flags, flags_before; + const char *prefix; + + if (!nm_utils_to_string_buffer_init_null(hdr, &buf, &len)) + return buf; + + b = buf; + + switch (hdr->nlmsg_type) { + case RTM_GETLINK: + s = "RTM_GETLINK"; + break; + case RTM_NEWLINK: + s = "RTM_NEWLINK"; + break; + case RTM_DELLINK: + s = "RTM_DELLINK"; + break; + case RTM_SETLINK: + s = "RTM_SETLINK"; + break; + case RTM_GETADDR: + s = "RTM_GETADDR"; + break; + case RTM_NEWADDR: + s = "RTM_NEWADDR"; + break; + case RTM_DELADDR: + s = "RTM_DELADDR"; + break; + case RTM_GETROUTE: + s = "RTM_GETROUTE"; + break; + case RTM_NEWROUTE: + s = "RTM_NEWROUTE"; + break; + case RTM_DELROUTE: + s = "RTM_DELROUTE"; + break; + case RTM_GETRULE: + s = "RTM_GETRULE"; + break; + case RTM_NEWRULE: + s = "RTM_NEWRULE"; + break; + case RTM_DELRULE: + s = "RTM_DELRULE"; + break; + case RTM_GETQDISC: + s = "RTM_GETQDISC"; + break; + case RTM_NEWQDISC: + s = "RTM_NEWQDISC"; + break; + case RTM_DELQDISC: + s = "RTM_DELQDISC"; + break; + case RTM_GETTFILTER: + s = "RTM_GETTFILTER"; + break; + case RTM_NEWTFILTER: + s = "RTM_NEWTFILTER"; + break; + case RTM_DELTFILTER: + s = "RTM_DELTFILTER"; + break; + case NLMSG_NOOP: + s = "NLMSG_NOOP"; + break; + case NLMSG_ERROR: + s = "NLMSG_ERROR"; + break; + case NLMSG_DONE: + s = "NLMSG_DONE"; + break; + case NLMSG_OVERRUN: + s = "NLMSG_OVERRUN"; + break; + default: + s = NULL; + break; + } + + if (s) + nm_utils_strbuf_append_str(&buf, &len, s); + else + nm_utils_strbuf_append(&buf, &len, "(%u)", (unsigned) hdr->nlmsg_type); + + flags = hdr->nlmsg_flags; + + if (!flags) { + nm_utils_strbuf_append_str(&buf, &len, ", flags 0"); + goto flags_done; + } + +#define _F(f, n) \ + G_STMT_START \ + { \ + if (NM_FLAGS_ALL(flags, f)) { \ + flags &= ~(f); \ + nm_utils_strbuf_append(&buf, &len, "%s%s", prefix, n); \ + if (!flags) \ + goto flags_done; \ + prefix = ","; \ + } \ + } \ + G_STMT_END + + prefix = ", flags "; + flags_before = flags; + _F(NLM_F_REQUEST, "request"); + _F(NLM_F_MULTI, "multi"); + _F(NLM_F_ACK, "ack"); + _F(NLM_F_ECHO, "echo"); + _F(NLM_F_DUMP_INTR, "dump_intr"); + _F(0x20 /*NLM_F_DUMP_FILTERED*/, "dump_filtered"); + + if (flags_before != flags) + prefix = ";"; + + switch (hdr->nlmsg_type) { + case RTM_NEWLINK: + case RTM_NEWADDR: + case RTM_NEWROUTE: + case RTM_NEWQDISC: + case RTM_NEWTFILTER: + _F(NLM_F_REPLACE, "replace"); + _F(NLM_F_EXCL, "excl"); + _F(NLM_F_CREATE, "create"); + _F(NLM_F_APPEND, "append"); + break; + case RTM_GETLINK: + case RTM_GETADDR: + case RTM_GETROUTE: + case RTM_DELQDISC: + case RTM_DELTFILTER: + _F(NLM_F_DUMP, "dump"); + _F(NLM_F_ROOT, "root"); + _F(NLM_F_MATCH, "match"); + _F(NLM_F_ATOMIC, "atomic"); + break; + } + +#undef _F + + if (flags_before != flags) + prefix = ";"; + nm_utils_strbuf_append(&buf, &len, "%s0x%04x", prefix, flags); + +flags_done: + + nm_utils_strbuf_append(&buf, &len, ", seq %u", (unsigned) hdr->nlmsg_seq); + + return b; +} + +/*****************************************************************************/ + +struct nlmsghdr * +nlmsg_hdr(struct nl_msg *n) +{ + return n->nm_nlh; +} + +void * +nlmsg_reserve(struct nl_msg *n, size_t len, int pad) +{ + char * buf = (char *) n->nm_nlh; + size_t nlmsg_len = n->nm_nlh->nlmsg_len; + size_t tlen; + + nm_assert(pad >= 0); + + if (len > n->nm_size) + return NULL; + + tlen = pad ? ((len + (pad - 1)) & ~(pad - 1)) : len; + + if ((tlen + nlmsg_len) > n->nm_size) + return NULL; + + buf += nlmsg_len; + n->nm_nlh->nlmsg_len += tlen; + + if (tlen > len) + memset(buf + len, 0, tlen - len); + + return buf; +} + +/*****************************************************************************/ + +struct nlattr * +nla_reserve(struct nl_msg *msg, int attrtype, int attrlen) +{ + struct nlattr *nla; + int tlen; + + if (attrlen < 0) + return NULL; + + tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen); + + if (tlen > msg->nm_size) + return NULL; + + nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh); + nla->nla_type = attrtype; + nla->nla_len = nla_attr_size(attrlen); + + if (attrlen) + memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen)); + msg->nm_nlh->nlmsg_len = tlen; + + return nla; +} + +/*****************************************************************************/ + +struct nl_msg * +nlmsg_alloc_size(size_t len) +{ + struct nl_msg *nm; + + if (len < sizeof(struct nlmsghdr)) + len = sizeof(struct nlmsghdr); + + nm = g_slice_new(struct nl_msg); + *nm = (struct nl_msg){ + .nm_protocol = -1, + .nm_size = len, + .nm_nlh = g_malloc0(len), + }; + nm->nm_nlh->nlmsg_len = nlmsg_total_size(0); + return nm; +} + +/** + * Allocate a new netlink message with the default maximum payload size. + * + * Allocates a new netlink message without any further payload. The + * maximum payload size defaults to PAGESIZE or as otherwise specified + * with nlmsg_set_default_size(). + * + * @return Newly allocated netlink message or NULL. + */ +struct nl_msg * +nlmsg_alloc(void) +{ + return nlmsg_alloc_size(nm_utils_getpagesize()); +} + +struct nl_msg * +nlmsg_alloc_convert(struct nlmsghdr *hdr) +{ + struct nl_msg *nm; + + nm = nlmsg_alloc_size(NLMSG_ALIGN(hdr->nlmsg_len)); + memcpy(nm->nm_nlh, hdr, hdr->nlmsg_len); + return nm; +} + +struct nl_msg * +nlmsg_alloc_simple(int nlmsgtype, int flags) +{ + struct nl_msg *nm; + struct nlmsghdr *new; + + nm = nlmsg_alloc(); + new = nm->nm_nlh; + new->nlmsg_type = nlmsgtype; + new->nlmsg_flags = flags; + return nm; +} + +void +nlmsg_free(struct nl_msg *msg) +{ + if (!msg) + return; + + g_free(msg->nm_nlh); + g_slice_free(struct nl_msg, msg); +} + +/*****************************************************************************/ + +int +nlmsg_append(struct nl_msg *n, const void *data, size_t len, int pad) +{ + void *tmp; + + nm_assert(n); + nm_assert(data); + nm_assert(len > 0); + nm_assert(pad >= 0); + + tmp = nlmsg_reserve(n, len, pad); + if (tmp == NULL) + return -ENOMEM; + + memcpy(tmp, data, len); + return 0; +} + +/*****************************************************************************/ + +int +nlmsg_parse(struct nlmsghdr * nlh, + int hdrlen, + struct nlattr * tb[], + int maxtype, + const struct nla_policy *policy) +{ + if (!nlmsg_valid_hdr(nlh, hdrlen)) + return -NME_NL_MSG_TOOSHORT; + + return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen), policy); +} + +struct nlmsghdr * +nlmsg_put(struct nl_msg *n, uint32_t pid, uint32_t seq, int type, int payload, int flags) +{ + struct nlmsghdr *nlh; + + if (n->nm_nlh->nlmsg_len < NLMSG_HDRLEN) + g_return_val_if_reached(NULL); + + nlh = (struct nlmsghdr *) n->nm_nlh; + nlh->nlmsg_type = type; + nlh->nlmsg_flags = flags; + nlh->nlmsg_pid = pid; + nlh->nlmsg_seq = seq; + + if (payload > 0 && nlmsg_reserve(n, payload, NLMSG_ALIGNTO) == NULL) + return NULL; + + return nlh; +} + +size_t +nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize) +{ + const char *src; + size_t srclen; + size_t len; + + /* - Always writes @dstsize bytes to @dst + * - Copies the first non-NUL characters to @dst. + * Any characters after the first NUL bytes in @nla are ignored. + * - If the string @nla is longer than @dstsize, the string + * gets truncated. @dst will always be NUL terminated. */ + + if (G_UNLIKELY(dstsize <= 1)) { + if (dstsize == 1) + dst[0] = '\0'; + if (nla && (srclen = nla_len(nla)) > 0) + return strnlen(nla_data(nla), srclen); + return 0; + } + + nm_assert(dst); + + if (nla) { + srclen = nla_len(nla); + if (srclen > 0) { + src = nla_data(nla); + srclen = strnlen(src, srclen); + if (srclen > 0) { + len = NM_MIN(dstsize - 1, srclen); + memcpy(dst, src, len); + memset(&dst[len], 0, dstsize - len); + return srclen; + } + } + } + + memset(dst, 0, dstsize); + return 0; +} + +size_t +nla_memcpy(void *dst, const struct nlattr *nla, size_t dstsize) +{ + size_t len; + int srclen; + + if (!nla) + return 0; + + srclen = nla_len(nla); + + if (srclen <= 0) { + nm_assert(srclen == 0); + return 0; + } + + len = NM_MIN((size_t) srclen, dstsize); + if (len > 0) { + /* there is a crucial difference between nla_strlcpy() and nla_memcpy(). + * The former always write @dstsize bytes (akin to strncpy()), here, we only + * write the bytes that we actually have (leaving the remainder undefined). */ + memcpy(dst, nla_data(nla), len); + } + + return srclen; +} + +int +nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data) +{ + struct nlattr *nla; + + nla = nla_reserve(msg, attrtype, datalen); + if (!nla) { + if (datalen < 0) + g_return_val_if_reached(-NME_BUG); + + return -ENOMEM; + } + + if (datalen > 0) + memcpy(nla_data(nla), data, datalen); + + return 0; +} + +struct nlattr * +nla_find(const struct nlattr *head, int len, int attrtype) +{ + const struct nlattr *nla; + int rem; + + nla_for_each_attr (nla, head, len, rem) { + if (nla_type(nla) == attrtype) + return (struct nlattr *) nla; + } + + return NULL; +} + +void +nla_nest_cancel(struct nl_msg *msg, const struct nlattr *attr) +{ + ssize_t len; + + len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) attr; + if (len < 0) + g_return_if_reached(); + else if (len > 0) { + msg->nm_nlh->nlmsg_len -= len; + memset(nlmsg_tail(msg->nm_nlh), 0, len); + } +} + +struct nlattr * +nla_nest_start(struct nl_msg *msg, int attrtype) +{ + struct nlattr *start = (struct nlattr *) nlmsg_tail(msg->nm_nlh); + + if (nla_put(msg, NLA_F_NESTED | attrtype, 0, NULL) < 0) + return NULL; + + return start; +} + +static int +_nest_end(struct nl_msg *msg, struct nlattr *start, int keep_empty) +{ + size_t pad, len; + + len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) start; + + if (len > USHRT_MAX || (!keep_empty && len == NLA_HDRLEN)) { + /* + * Max nlattr size exceeded or empty nested attribute, trim the + * attribute header again + */ + nla_nest_cancel(msg, start); + + /* Return error only if nlattr size was exceeded */ + return (len == NLA_HDRLEN) ? 0 : -NME_NL_ATTRSIZE; + } + + start->nla_len = len; + + pad = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len; + if (pad > 0) { + /* + * Data inside attribute does not end at a alignment boundary. + * Pad accordingly and account for the additional space in + * the message. nlmsg_reserve() may never fail in this situation, + * the allocate message buffer must be a multiple of NLMSG_ALIGNTO. + */ + if (!nlmsg_reserve(msg, pad, 0)) + g_return_val_if_reached(-NME_BUG); + } + + return 0; +} + +int +nla_nest_end(struct nl_msg *msg, struct nlattr *start) +{ + return _nest_end(msg, start, 0); +} + +static const uint16_t nla_attr_minlen[NLA_TYPE_MAX + 1] = { + [NLA_U8] = sizeof(uint8_t), + [NLA_U16] = sizeof(uint16_t), + [NLA_U32] = sizeof(uint32_t), + [NLA_U64] = sizeof(uint64_t), + [NLA_STRING] = 1, + [NLA_FLAG] = 0, +}; + +static int +validate_nla(const struct nlattr *nla, int maxtype, const struct nla_policy *policy) +{ + const struct nla_policy *pt; + unsigned int minlen = 0; + int type = nla_type(nla); + + if (type < 0 || type > maxtype) + return 0; + + pt = &policy[type]; + + if (pt->type > NLA_TYPE_MAX) + g_return_val_if_reached(-NME_BUG); + + if (pt->minlen) + minlen = pt->minlen; + else if (pt->type != NLA_UNSPEC) + minlen = nla_attr_minlen[pt->type]; + + if (nla_len(nla) < minlen) + return -NME_UNSPEC; + + if (pt->maxlen && nla_len(nla) > pt->maxlen) + return -NME_UNSPEC; + + if (pt->type == NLA_STRING) { + const char *data; + + nm_assert(minlen > 0); + + data = nla_data(nla); + if (data[nla_len(nla) - 1] != '\0') + return -NME_UNSPEC; + } + + return 0; +} + +int +nla_parse(struct nlattr * tb[], + int maxtype, + struct nlattr * head, + int len, + const struct nla_policy *policy) +{ + struct nlattr *nla; + int rem, nmerr; + + memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1)); + + nla_for_each_attr (nla, head, len, rem) { + int type = nla_type(nla); + + if (type > maxtype) + continue; + + if (policy) { + nmerr = validate_nla(nla, maxtype, policy); + if (nmerr < 0) + return nmerr; + } + + tb[type] = nla; + } + + return 0; +} + +/*****************************************************************************/ + +int +nlmsg_get_proto(struct nl_msg *msg) +{ + return msg->nm_protocol; +} + +void +nlmsg_set_proto(struct nl_msg *msg, int protocol) +{ + msg->nm_protocol = protocol; +} + +void +nlmsg_set_src(struct nl_msg *msg, struct sockaddr_nl *addr) +{ + memcpy(&msg->nm_src, addr, sizeof(*addr)); +} + +struct ucred * +nlmsg_get_creds(struct nl_msg *msg) +{ + if (msg->nm_creds_has) + return &msg->nm_creds; + return NULL; +} + +void +nlmsg_set_creds(struct nl_msg *msg, struct ucred *creds) +{ + if (creds) { + memcpy(&msg->nm_creds, creds, sizeof(*creds)); + msg->nm_creds_has = TRUE; + } else + msg->nm_creds_has = FALSE; +} + +/*****************************************************************************/ + +void * +genlmsg_put(struct nl_msg *msg, + uint32_t port, + uint32_t seq, + int family, + int hdrlen, + int flags, + uint8_t cmd, + uint8_t version) +{ + struct nlmsghdr * nlh; + struct genlmsghdr hdr = { + .cmd = cmd, + .version = version, + }; + + nlh = nlmsg_put(msg, port, seq, family, GENL_HDRLEN + hdrlen, flags); + if (nlh == NULL) + return NULL; + + memcpy(nlmsg_data(nlh), &hdr, sizeof(hdr)); + + return (char *) nlmsg_data(nlh) + GENL_HDRLEN; +} + +void * +genlmsg_data(const struct genlmsghdr *gnlh) +{ + return ((unsigned char *) gnlh + GENL_HDRLEN); +} + +void * +genlmsg_user_hdr(const struct genlmsghdr *gnlh) +{ + return genlmsg_data(gnlh); +} + +struct genlmsghdr * +genlmsg_hdr(struct nlmsghdr *nlh) +{ + return nlmsg_data(nlh); +} + +void * +genlmsg_user_data(const struct genlmsghdr *gnlh, const int hdrlen) +{ + return (char *) genlmsg_user_hdr(gnlh) + NLMSG_ALIGN(hdrlen); +} + +struct nlattr * +genlmsg_attrdata(const struct genlmsghdr *gnlh, int hdrlen) +{ + return genlmsg_user_data(gnlh, hdrlen); +} + +int +genlmsg_len(const struct genlmsghdr *gnlh) +{ + const struct nlmsghdr *nlh; + + nlh = (const struct nlmsghdr *) ((const unsigned char *) gnlh - NLMSG_HDRLEN); + return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN); +} + +int +genlmsg_attrlen(const struct genlmsghdr *gnlh, int hdrlen) +{ + return genlmsg_len(gnlh) - NLMSG_ALIGN(hdrlen); +} + +int +genlmsg_valid_hdr(struct nlmsghdr *nlh, int hdrlen) +{ + struct genlmsghdr *ghdr; + + if (!nlmsg_valid_hdr(nlh, GENL_HDRLEN)) + return 0; + + ghdr = nlmsg_data(nlh); + if (genlmsg_len(ghdr) < NLMSG_ALIGN(hdrlen)) + return 0; + + return 1; +} + +int +genlmsg_parse(struct nlmsghdr * nlh, + int hdrlen, + struct nlattr * tb[], + int maxtype, + const struct nla_policy *policy) +{ + struct genlmsghdr *ghdr; + + if (!genlmsg_valid_hdr(nlh, hdrlen)) + return -NME_NL_MSG_TOOSHORT; + + ghdr = nlmsg_data(nlh); + return nla_parse(tb, + maxtype, + genlmsg_attrdata(ghdr, hdrlen), + genlmsg_attrlen(ghdr, hdrlen), + policy); +} + +static int +_genl_parse_getfamily(struct nl_msg *msg, void *arg) +{ + static const struct nla_policy ctrl_policy[] = { + [CTRL_ATTR_FAMILY_ID] = {.type = NLA_U16}, + [CTRL_ATTR_FAMILY_NAME] = {.type = NLA_STRING, .maxlen = GENL_NAMSIZ}, + [CTRL_ATTR_VERSION] = {.type = NLA_U32}, + [CTRL_ATTR_HDRSIZE] = {.type = NLA_U32}, + [CTRL_ATTR_MAXATTR] = {.type = NLA_U32}, + [CTRL_ATTR_OPS] = {.type = NLA_NESTED}, + [CTRL_ATTR_MCAST_GROUPS] = {.type = NLA_NESTED}, + }; + struct nlattr * tb[G_N_ELEMENTS(ctrl_policy)]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + gint32 * response_data = arg; + + if (genlmsg_parse_arr(nlh, 0, tb, ctrl_policy) < 0) + return NL_SKIP; + + if (tb[CTRL_ATTR_FAMILY_ID]) + *response_data = nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]); + + return NL_STOP; +} + +int +genl_ctrl_resolve(struct nl_sock *sk, const char *name) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + int nmerr; + gint32 response_data = -1; + const struct nl_cb cb = { + .valid_cb = _genl_parse_getfamily, + .valid_arg = &response_data, + }; + + msg = nlmsg_alloc(); + + if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL, 0, 0, CTRL_CMD_GETFAMILY, 1)) + return -ENOMEM; + + nmerr = nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, name); + if (nmerr < 0) + return nmerr; + + nmerr = nl_send_auto(sk, msg); + if (nmerr < 0) + return nmerr; + + nmerr = nl_recvmsgs(sk, &cb); + if (nmerr < 0) + return nmerr; + + /* If search was successful, request may be ACKed after data */ + nmerr = nl_wait_for_ack(sk, NULL); + if (nmerr < 0) + return nmerr; + + if (response_data < 0) + return -NME_UNSPEC; + + return response_data; +} + +/*****************************************************************************/ + +struct nl_sock * +nl_socket_alloc(void) +{ + struct nl_sock *sk; + + sk = g_slice_new0(struct nl_sock); + + sk->s_fd = -1; + sk->s_local.nl_family = AF_NETLINK; + sk->s_peer.nl_family = AF_NETLINK; + sk->s_seq_expect = sk->s_seq_next = time(NULL); + + return sk; +} + +void +nl_socket_free(struct nl_sock *sk) +{ + if (!sk) + return; + + if (sk->s_fd >= 0) + nm_close(sk->s_fd); + g_slice_free(struct nl_sock, sk); +} + +int +nl_socket_get_fd(const struct nl_sock *sk) +{ + return sk->s_fd; +} + +uint32_t +nl_socket_get_local_port(const struct nl_sock *sk) +{ + return sk->s_local.nl_pid; +} + +size_t +nl_socket_get_msg_buf_size(struct nl_sock *sk) +{ + return sk->s_bufsize; +} + +int +nl_socket_set_passcred(struct nl_sock *sk, int state) +{ + int err; + + if (sk->s_fd == -1) + return -NME_NL_BAD_SOCK; + + err = setsockopt(sk->s_fd, SOL_SOCKET, SO_PASSCRED, &state, sizeof(state)); + if (err < 0) + return -nm_errno_from_native(errno); + + if (state) + sk->s_flags |= NL_SOCK_PASSCRED; + else + sk->s_flags &= ~NL_SOCK_PASSCRED; + + return 0; +} + +int +nl_socket_set_msg_buf_size(struct nl_sock *sk, size_t bufsize) +{ + sk->s_bufsize = bufsize; + + return 0; +} + +struct sockaddr_nl * +nlmsg_get_dst(struct nl_msg *msg) +{ + return &msg->nm_dst; +} + +int +nl_socket_set_nonblocking(const struct nl_sock *sk) +{ + if (sk->s_fd == -1) + return -NME_NL_BAD_SOCK; + + if (fcntl(sk->s_fd, F_SETFL, O_NONBLOCK) < 0) + return -nm_errno_from_native(errno); + + return 0; +} + +int +nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf) +{ + int err; + + if (rxbuf <= 0) + rxbuf = 32768; + + if (txbuf <= 0) + txbuf = 32768; + + if (sk->s_fd == -1) + return -NME_NL_BAD_SOCK; + + err = setsockopt(sk->s_fd, SOL_SOCKET, SO_SNDBUF, &txbuf, sizeof(txbuf)); + if (err < 0) { + return -nm_errno_from_native(errno); + } + + err = setsockopt(sk->s_fd, SOL_SOCKET, SO_RCVBUF, &rxbuf, sizeof(rxbuf)); + if (err < 0) { + return -nm_errno_from_native(errno); + } + + return 0; +} + +int +nl_socket_add_memberships(struct nl_sock *sk, int group, ...) +{ + int err; + va_list ap; + + if (sk->s_fd == -1) + return -NME_NL_BAD_SOCK; + + va_start(ap, group); + + while (group != 0) { + if (group < 0) { + va_end(ap); + g_return_val_if_reached(-NME_BUG); + } + + err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group)); + if (err < 0) { + int errsv = errno; + + va_end(ap); + return -nm_errno_from_native(errsv); + } + + group = va_arg(ap, int); + } + + va_end(ap); + + return 0; +} + +int +nl_socket_set_ext_ack(struct nl_sock *sk, gboolean enable) +{ + int err, val; + + if (sk->s_fd == -1) + return -NME_NL_BAD_SOCK; + + val = !!enable; + err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_EXT_ACK, &val, sizeof(val)); + if (err < 0) + return -nm_errno_from_native(errno); + + return 0; +} + +void +nl_socket_disable_msg_peek(struct nl_sock *sk) +{ + sk->s_flags |= NL_MSG_PEEK_EXPLICIT; + sk->s_flags &= ~NL_MSG_PEEK; +} + +int +nl_connect(struct nl_sock *sk, int protocol) +{ + int err, nmerr; + socklen_t addrlen; + struct sockaddr_nl local = {0}; + + if (sk->s_fd != -1) + return -NME_NL_BAD_SOCK; + + sk->s_fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol); + if (sk->s_fd < 0) { + nmerr = -nm_errno_from_native(errno); + goto errout; + } + + nmerr = nl_socket_set_buffer_size(sk, 0, 0); + if (nmerr < 0) + goto errout; + + nm_assert(sk->s_local.nl_pid == 0); + + err = bind(sk->s_fd, (struct sockaddr *) &sk->s_local, sizeof(sk->s_local)); + if (err != 0) { + nmerr = -nm_errno_from_native(errno); + goto errout; + } + + addrlen = sizeof(local); + err = getsockname(sk->s_fd, (struct sockaddr *) &local, &addrlen); + if (err < 0) { + nmerr = -nm_errno_from_native(errno); + goto errout; + } + + if (addrlen != sizeof(local)) { + nmerr = -NME_UNSPEC; + goto errout; + } + + if (local.nl_family != AF_NETLINK) { + nmerr = -NME_UNSPEC; + goto errout; + } + + sk->s_local = local; + sk->s_proto = protocol; + + return 0; + +errout: + if (sk->s_fd != -1) { + close(sk->s_fd); + sk->s_fd = -1; + } + return nmerr; +} + +/*****************************************************************************/ + +static void +_cb_init(struct nl_cb *dst, const struct nl_cb *src) +{ + nm_assert(dst); + + if (src) + *dst = *src; + else + memset(dst, 0, sizeof(*dst)); +} + +static int +ack_wait_handler(struct nl_msg *msg, void *arg) +{ + return NL_STOP; +} + +int +nl_wait_for_ack(struct nl_sock *sk, const struct nl_cb *cb) +{ + struct nl_cb cb2; + + _cb_init(&cb2, cb); + cb2.ack_cb = ack_wait_handler; + return nl_recvmsgs(sk, &cb2); +} + +#define NL_CB_CALL(cb, type, msg) \ + do { \ + const struct nl_cb *_cb = (cb); \ + \ + if (_cb && _cb->type##_cb) { \ + /* the returned value here must be either a negative + * netlink error number, or one of NL_SKIP, NL_STOP, NL_OK. */ \ + nmerr = _cb->type##_cb((msg), _cb->type##_arg); \ + switch (nmerr) { \ + case NL_OK: \ + nm_assert(nmerr == 0); \ + break; \ + case NL_SKIP: \ + goto skip; \ + case NL_STOP: \ + goto stop; \ + default: \ + if (nmerr >= 0) { \ + nm_assert_not_reached(); \ + nmerr = -NME_BUG; \ + } \ + goto out; \ + } \ + } \ + } while (0) + +int +nl_recvmsgs(struct nl_sock *sk, const struct nl_cb *cb) +{ + int n, nmerr = 0, multipart = 0, interrupted = 0, nrecv = 0; + gs_free unsigned char *buf = NULL; + struct nlmsghdr * hdr; + struct sockaddr_nl nla = {0}; + struct ucred creds; + gboolean creds_has; + +continue_reading: + n = nl_recv(sk, &nla, &buf, &creds, &creds_has); + if (n <= 0) + return n; + + hdr = (struct nlmsghdr *) buf; + while (nlmsg_ok(hdr, n)) { + nm_auto_nlmsg struct nl_msg *msg = NULL; + + msg = nlmsg_alloc_convert(hdr); + + nlmsg_set_proto(msg, sk->s_proto); + nlmsg_set_src(msg, &nla); + nlmsg_set_creds(msg, creds_has ? &creds : NULL); + + nrecv++; + + /* Only do sequence checking if auto-ack mode is enabled */ + if (!(sk->s_flags & NL_NO_AUTO_ACK)) { + if (hdr->nlmsg_seq != sk->s_seq_expect) { + nmerr = -NME_NL_SEQ_MISMATCH; + goto out; + } + } + + if (hdr->nlmsg_type == NLMSG_DONE || hdr->nlmsg_type == NLMSG_ERROR + || hdr->nlmsg_type == NLMSG_NOOP || hdr->nlmsg_type == NLMSG_OVERRUN) { + /* We can't check for !NLM_F_MULTI since some netlink + * users in the kernel are broken. */ + sk->s_seq_expect++; + } + + if (hdr->nlmsg_flags & NLM_F_MULTI) + multipart = 1; + + if (hdr->nlmsg_flags & NLM_F_DUMP_INTR) { + /* + * We have to continue reading to clear + * all messages until a NLMSG_DONE is + * received and report the inconsistency. + */ + interrupted = 1; + } + + /* messages terminates a multipart message, this is + * usually the end of a message and therefore we slip + * out of the loop by default. the user may overrule + * this action by skipping this packet. */ + if (hdr->nlmsg_type == NLMSG_DONE) { + multipart = 0; + NL_CB_CALL(cb, finish, msg); + } + + /* Message to be ignored, the default action is to + * skip this message if no callback is specified. The + * user may overrule this action by returning + * NL_PROCEED. */ + else if (hdr->nlmsg_type == NLMSG_NOOP) + goto skip; + + /* Data got lost, report back to user. The default action is to + * quit parsing. The user may overrule this action by returning + * NL_SKIP or NL_PROCEED (dangerous) */ + else if (hdr->nlmsg_type == NLMSG_OVERRUN) { + nmerr = -NME_NL_MSG_OVERFLOW; + goto out; + } + + /* Message carries a nlmsgerr */ + else if (hdr->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *e = nlmsg_data(hdr); + + if (hdr->nlmsg_len < nlmsg_size(sizeof(*e))) { + /* Truncated error message, the default action + * is to stop parsing. The user may overrule + * this action by returning NL_SKIP or + * NL_PROCEED (dangerous) */ + nmerr = -NME_NL_MSG_TRUNC; + goto out; + } + if (e->error) { + /* Error message reported back from kernel. */ + if (cb && cb->err_cb) { + /* the returned value here must be either a negative + * netlink error number, or one of NL_SKIP, NL_STOP, NL_OK. */ + nmerr = cb->err_cb(&nla, e, cb->err_arg); + if (nmerr < 0) + goto out; + else if (nmerr == NL_SKIP) + goto skip; + else if (nmerr == NL_STOP) { + nmerr = -nm_errno_from_native(e->error); + goto out; + } + nm_assert(nmerr == NL_OK); + } else { + nmerr = -nm_errno_from_native(e->error); + goto out; + } + } else + NL_CB_CALL(cb, ack, msg); + } else { + /* Valid message (not checking for MULTIPART bit to + * get along with broken kernels. NL_SKIP has no + * effect on this. */ + NL_CB_CALL(cb, valid, msg); + } +skip: + nmerr = 0; + hdr = nlmsg_next(hdr, &n); + } + + if (multipart) { + /* Multipart message not yet complete, continue reading */ + nm_clear_g_free(&buf); + + nmerr = 0; + goto continue_reading; + } + +stop: + nmerr = 0; + +out: + if (interrupted) + nmerr = -NME_NL_DUMP_INTR; + + nm_assert(nmerr <= 0); + return nmerr ?: nrecv; +} + +int +nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr) +{ + int ret; + + if (sk->s_fd < 0) + return -NME_NL_BAD_SOCK; + + nlmsg_set_src(msg, &sk->s_local); + + ret = sendmsg(sk->s_fd, hdr, 0); + if (ret < 0) + return -nm_errno_from_native(errno); + + return ret; +} + +int +nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen) +{ + struct sockaddr_nl *dst; + struct ucred * creds; + struct msghdr hdr = { + .msg_name = (void *) &sk->s_peer, + .msg_namelen = sizeof(struct sockaddr_nl), + .msg_iov = iov, + .msg_iovlen = iovlen, + }; + char buf[CMSG_SPACE(sizeof(struct ucred))]; + + /* Overwrite destination if specified in the message itself, defaults + * to the peer address of the socket. + */ + dst = nlmsg_get_dst(msg); + if (dst->nl_family == AF_NETLINK) + hdr.msg_name = dst; + + /* Add credentials if present. */ + creds = nlmsg_get_creds(msg); + if (creds != NULL) { + struct cmsghdr *cmsg; + + hdr.msg_control = buf; + hdr.msg_controllen = sizeof(buf); + + cmsg = CMSG_FIRSTHDR(&hdr); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred)); + memcpy(CMSG_DATA(cmsg), creds, sizeof(struct ucred)); + } + + return nl_sendmsg(sk, msg, &hdr); +} + +void +nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg) +{ + struct nlmsghdr *nlh; + + nlh = nlmsg_hdr(msg); + if (nlh->nlmsg_pid == NL_AUTO_PORT) + nlh->nlmsg_pid = nl_socket_get_local_port(sk); + + if (nlh->nlmsg_seq == NL_AUTO_SEQ) + nlh->nlmsg_seq = sk->s_seq_next++; + + if (msg->nm_protocol == -1) + msg->nm_protocol = sk->s_proto; + + nlh->nlmsg_flags |= NLM_F_REQUEST; + + if (!(sk->s_flags & NL_NO_AUTO_ACK)) + nlh->nlmsg_flags |= NLM_F_ACK; +} + +int +nl_send(struct nl_sock *sk, struct nl_msg *msg) +{ + struct iovec iov = { + .iov_base = (void *) nlmsg_hdr(msg), + .iov_len = nlmsg_hdr(msg)->nlmsg_len, + }; + + return nl_send_iovec(sk, msg, &iov, 1); +} + +int +nl_send_auto(struct nl_sock *sk, struct nl_msg *msg) +{ + nl_complete_msg(sk, msg); + + return nl_send(sk, msg); +} + +int +nl_recv(struct nl_sock * sk, + struct sockaddr_nl *nla, + unsigned char ** buf, + struct ucred * out_creds, + gboolean * out_creds_has) +{ + ssize_t n; + int flags = 0; + struct iovec iov; + struct msghdr msg = { + .msg_name = (void *) nla, + .msg_namelen = sizeof(struct sockaddr_nl), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + struct ucred tmpcreds; + gboolean tmpcreds_has = FALSE; + int retval; + int errsv; + + nm_assert(nla); + nm_assert(buf && !*buf); + nm_assert(!out_creds_has == !out_creds); + + if ((sk->s_flags & NL_MSG_PEEK) + || (!(sk->s_flags & NL_MSG_PEEK_EXPLICIT) && sk->s_bufsize == 0)) + flags |= MSG_PEEK | MSG_TRUNC; + + iov.iov_len = sk->s_bufsize ?: (((size_t) nm_utils_getpagesize()) * 4u); + iov.iov_base = g_malloc(iov.iov_len); + + if (out_creds && (sk->s_flags & NL_SOCK_PASSCRED)) { + msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred)); + msg.msg_control = g_malloc(msg.msg_controllen); + } + +retry: + n = recvmsg(sk->s_fd, &msg, flags); + if (!n) { + retval = 0; + goto abort; + } + + if (n < 0) { + errsv = errno; + if (errsv == EINTR) + goto retry; + retval = -nm_errno_from_native(errsv); + goto abort; + } + + if (msg.msg_flags & MSG_CTRUNC) { + if (msg.msg_controllen == 0) { + retval = -NME_NL_MSG_TRUNC; + goto abort; + } + + msg.msg_controllen *= 2; + msg.msg_control = g_realloc(msg.msg_control, msg.msg_controllen); + goto retry; + } + + if (iov.iov_len < n || (msg.msg_flags & MSG_TRUNC)) { + /* respond with error to an incomplete message */ + if (flags == 0) { + retval = -NME_NL_MSG_TRUNC; + goto abort; + } + + /* Provided buffer is not long enough, enlarge it + * to size of n (which should be total length of the message) + * and try again. */ + iov.iov_base = g_realloc(iov.iov_base, n); + iov.iov_len = n; + flags = 0; + goto retry; + } + + if (flags != 0) { + /* Buffer is big enough, do the actual reading */ + flags = 0; + goto retry; + } + + if (msg.msg_namelen != sizeof(struct sockaddr_nl)) { + retval = -NME_UNSPEC; + goto abort; + } + + if (out_creds && (sk->s_flags & NL_SOCK_PASSCRED)) { + struct cmsghdr *cmsg; + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level != SOL_SOCKET) + continue; + if (cmsg->cmsg_type != SCM_CREDENTIALS) + continue; + memcpy(&tmpcreds, CMSG_DATA(cmsg), sizeof(tmpcreds)); + tmpcreds_has = TRUE; + break; + } + } + + retval = n; + +abort: + g_free(msg.msg_control); + + if (retval <= 0) { + g_free(iov.iov_base); + return retval; + } + + *buf = iov.iov_base; + if (out_creds && tmpcreds_has) + *out_creds = tmpcreds; + NM_SET_OUT(out_creds_has, tmpcreds_has); + return retval; +} diff --git a/src/libnm-platform/nm-netlink.h b/src/libnm-platform/nm-netlink.h new file mode 100644 index 0000000..ab355f7 --- /dev/null +++ b/src/libnm-platform/nm-netlink.h @@ -0,0 +1,616 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_NETLINK_H__ +#define __NM_NETLINK_H__ + +#include +#include +#include + +#include "libnm-std-aux/unaligned.h" + +/*****************************************************************************/ + +#define NLMSGERR_ATTR_UNUSED 0 +#define NLMSGERR_ATTR_MSG 1 +#define NLMSGERR_ATTR_OFFS 2 +#define NLMSGERR_ATTR_COOKIE 3 +#define NLMSGERR_ATTR_MAX 3 + +#ifndef NLM_F_ACK_TLVS + #define NLM_F_ACK_TLVS 0x200 +#endif + +/*****************************************************************************/ + +/* Basic attribute data types */ +enum { + NLA_UNSPEC, /* Unspecified type, binary data chunk */ + NLA_U8, /* 8 bit integer */ + NLA_U16, /* 16 bit integer */ + NLA_U32, /* 32 bit integer */ + NLA_U64, /* 64 bit integer */ + NLA_STRING, /* NUL terminated character string */ + NLA_FLAG, /* Flag */ + NLA_MSECS, /* Micro seconds (64bit) */ + NLA_NESTED, /* Nested attributes */ + NLA_NESTED_COMPAT, + NLA_NUL_STRING, + NLA_BINARY, + NLA_S8, + NLA_S16, + NLA_S32, + NLA_S64, + __NLA_TYPE_MAX, +}; + +#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1) + +struct nl_msg; + +/*****************************************************************************/ + +const char *nl_nlmsgtype2str(int type, char *buf, size_t size); + +const char *nl_nlmsg_flags2str(int flags, char *buf, size_t len); + +const char *nl_nlmsghdr_to_str(const struct nlmsghdr *hdr, char *buf, gsize len); + +/*****************************************************************************/ + +struct nla_policy { + /* Type of attribute or NLA_UNSPEC */ + uint16_t type; + + /* Minimal length of payload required */ + uint16_t minlen; + + /* Maximal length of payload allowed */ + uint16_t maxlen; +}; + +/*****************************************************************************/ + +/* static asserts that @tb and @policy are suitable arguments to nla_parse(). */ +#define _nl_static_assert_tb(tb, policy) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT_EXPR(G_N_ELEMENTS(tb) > 0); \ + \ + /* We allow @policy to be either a C array or NULL. The sizeof() + * must either match the expected array size or the sizeof(NULL), + * but not both. */ \ + G_STATIC_ASSERT_EXPR((sizeof(policy) == G_N_ELEMENTS(tb) * sizeof(struct nla_policy)) \ + ^ (sizeof(policy) == sizeof(NULL))); \ + } \ + G_STMT_END + +/*****************************************************************************/ + +static inline int +nla_attr_size(int payload) +{ + nm_assert(payload >= 0); + + return NLA_HDRLEN + payload; +} + +static inline int +nla_total_size(int payload) +{ + return NLA_ALIGN(nla_attr_size(payload)); +} + +static inline int +nla_padlen(int payload) +{ + return nla_total_size(payload) - nla_attr_size(payload); +} + +struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int attrlen); + +static inline int +nla_len(const struct nlattr *nla) +{ + nm_assert(nla); + nm_assert(nla->nla_len >= NLA_HDRLEN); + + return ((int) nla->nla_len) - NLA_HDRLEN; +} + +static inline int +nla_type(const struct nlattr *nla) +{ + nm_assert(nla_len(nla) >= 0); + + return nla->nla_type & NLA_TYPE_MASK; +} + +static inline void * +nla_data(const struct nlattr *nla) +{ + nm_assert(nla_len(nla) >= 0); + + return &(((char *) nla)[NLA_HDRLEN]); +} + +#define nla_data_as(type, nla) \ + ({ \ + const struct nlattr *_nla = (nla); \ + \ + nm_assert(nla_len(_nla) >= sizeof(type)); \ + \ + /* note that casting the pointer is undefined behavior in C, if + * the data has wrong alignment. Netlink data is aligned to 4 bytes, + * that means, if the alignment is larger than 4, this is invalid. */ \ + G_STATIC_ASSERT_EXPR(_nm_alignof(type) <= NLA_ALIGNTO); \ + \ + (type *) nla_data(_nla); \ + }) + +static inline uint8_t +nla_get_u8(const struct nlattr *nla) +{ + nm_assert(nla_len(nla) >= sizeof(uint8_t)); + + return *((const uint8_t *) nla_data(nla)); +} + +static inline int8_t +nla_get_s8(const struct nlattr *nla) +{ + nm_assert(nla_len(nla) >= sizeof(int8_t)); + + return *((const int8_t *) nla_data(nla)); +} + +static inline uint8_t +nla_get_u8_cond(/*const*/ struct nlattr *const *tb, int attr, uint8_t default_val) +{ + nm_assert(tb); + nm_assert(attr >= 0); + + return tb[attr] ? nla_get_u8(tb[attr]) : default_val; +} + +static inline uint16_t +nla_get_u16(const struct nlattr *nla) +{ + nm_assert(nla_len(nla) >= sizeof(uint16_t)); + + return *((const uint16_t *) nla_data(nla)); +} + +static inline uint32_t +nla_get_u32(const struct nlattr *nla) +{ + nm_assert(nla_len(nla) >= sizeof(uint32_t)); + + return *((const uint32_t *) nla_data(nla)); +} + +static inline int32_t +nla_get_s32(const struct nlattr *nla) +{ + nm_assert(nla_len(nla) >= sizeof(int32_t)); + + return *((const int32_t *) nla_data(nla)); +} + +static inline uint64_t +nla_get_u64(const struct nlattr *nla) +{ + nm_assert(nla_len(nla) >= sizeof(uint64_t)); + + return unaligned_read_ne64(nla_data(nla)); +} + +static inline uint64_t +nla_get_be64(const struct nlattr *nla) +{ + nm_assert(nla_len(nla) >= sizeof(uint64_t)); + + return unaligned_read_be64(nla_data(nla)); +} + +static inline char * +nla_get_string(const struct nlattr *nla) +{ + nm_assert(nla_len(nla) >= 0); + + return (char *) nla_data(nla); +} + +size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize); + +size_t nla_memcpy(void *dst, const struct nlattr *nla, size_t dstsize); + +#define nla_memcpy_checked_size(dst, nla, dstsize) \ + G_STMT_START \ + { \ + void *const _dst = (dst); \ + const struct nlattr *const _nla = (nla); \ + const size_t _dstsize = (dstsize); \ + size_t _srcsize; \ + \ + /* assert that, if @nla is given, that it has the exact expected + * size. This implies that the caller previously verified the length + * of the attribute (via minlen/maxlen at nla_parse()). */ \ + \ + if (_nla) { \ + _srcsize = nla_memcpy(_dst, _nla, _dstsize); \ + nm_assert(_srcsize == _dstsize); \ + } \ + } \ + G_STMT_END + +int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data); + +static inline int +nla_put_string(struct nl_msg *msg, int attrtype, const char *str) +{ + nm_assert(str); + + return nla_put(msg, attrtype, strlen(str) + 1, str); +} + +static inline int +nla_put_uint8(struct nl_msg *msg, int attrtype, uint8_t val) +{ + return nla_put(msg, attrtype, sizeof(val), &val); +} + +static inline int +nla_put_uint16(struct nl_msg *msg, int attrtype, uint16_t val) +{ + return nla_put(msg, attrtype, sizeof(val), &val); +} + +static inline int +nla_put_uint32(struct nl_msg *msg, int attrtype, uint32_t val) +{ + return nla_put(msg, attrtype, sizeof(val), &val); +} + +#define NLA_PUT(msg, attrtype, attrlen, data) \ + G_STMT_START \ + { \ + if (nla_put(msg, attrtype, attrlen, data) < 0) \ + goto nla_put_failure; \ + } \ + G_STMT_END + +#define NLA_PUT_TYPE(msg, type, attrtype, value) \ + G_STMT_START \ + { \ + type __nla_tmp = value; \ + NLA_PUT(msg, attrtype, sizeof(type), &__nla_tmp); \ + } \ + G_STMT_END + +#define NLA_PUT_U8(msg, attrtype, value) NLA_PUT_TYPE(msg, uint8_t, attrtype, value) + +#define NLA_PUT_S8(msg, attrtype, value) NLA_PUT_TYPE(msg, int8_t, attrtype, value) + +#define NLA_PUT_U16(msg, attrtype, value) NLA_PUT_TYPE(msg, uint16_t, attrtype, value) + +#define NLA_PUT_U32(msg, attrtype, value) NLA_PUT_TYPE(msg, uint32_t, attrtype, value) + +#define NLA_PUT_S32(msg, attrtype, value) NLA_PUT_TYPE(msg, int32_t, attrtype, value) + +#define NLA_PUT_U64(msg, attrtype, value) NLA_PUT_TYPE(msg, uint64_t, attrtype, value) + +#define NLA_PUT_STRING(msg, attrtype, value) NLA_PUT(msg, attrtype, (int) strlen(value) + 1, value) + +#define NLA_PUT_FLAG(msg, attrtype) NLA_PUT(msg, attrtype, 0, NULL) + +struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype); + +static inline int +nla_ok(const struct nlattr *nla, int remaining) +{ + return remaining >= (int) sizeof(*nla) && nla->nla_len >= sizeof(*nla) + && nla->nla_len <= remaining; +} + +static inline struct nlattr * +nla_next(const struct nlattr *nla, int *remaining) +{ + int totlen = NLA_ALIGN(nla->nla_len); + + *remaining -= totlen; + return (struct nlattr *) ((char *) nla + totlen); +} + +#define nla_for_each_attr(pos, head, len, rem) \ + for (pos = head, rem = len; nla_ok(pos, rem); pos = nla_next(pos, &(rem))) + +#define nla_for_each_nested(pos, nla, rem) \ + for (pos = (struct nlattr *) nla_data(nla), rem = nla_len(nla); nla_ok(pos, rem); \ + pos = nla_next(pos, &(rem))) + +void nla_nest_cancel(struct nl_msg *msg, const struct nlattr *attr); +struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype); +int nla_nest_end(struct nl_msg *msg, struct nlattr *start); + +int nla_parse(struct nlattr * tb[], + int maxtype, + struct nlattr * head, + int len, + const struct nla_policy *policy); + +#define nla_parse_arr(tb, head, len, policy) \ + ({ \ + _nl_static_assert_tb((tb), (policy)); \ + \ + nla_parse((tb), G_N_ELEMENTS(tb) - 1, (head), (len), (policy)); \ + }) + +static inline int +nla_parse_nested(struct nlattr * tb[], + int maxtype, + struct nlattr * nla, + const struct nla_policy *policy) +{ + return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); +} + +#define nla_parse_nested_arr(tb, nla, policy) \ + ({ \ + _nl_static_assert_tb((tb), (policy)); \ + \ + nla_parse_nested((tb), G_N_ELEMENTS(tb) - 1, (nla), (policy)); \ + }) + +/*****************************************************************************/ + +struct nl_msg *nlmsg_alloc(void); + +struct nl_msg *nlmsg_alloc_size(size_t max); + +struct nl_msg *nlmsg_alloc_convert(struct nlmsghdr *hdr); + +struct nl_msg *nlmsg_alloc_simple(int nlmsgtype, int flags); + +void *nlmsg_reserve(struct nl_msg *n, size_t len, int pad); + +int nlmsg_append(struct nl_msg *n, const void *data, size_t len, int pad); + +#define nlmsg_append_struct(n, data) nlmsg_append(n, (data), sizeof(*(data)), NLMSG_ALIGNTO) + +void nlmsg_free(struct nl_msg *msg); + +static inline int +nlmsg_size(int payload) +{ + nm_assert(payload >= 0 && payload < G_MAXINT - NLMSG_HDRLEN - 4); + return NLMSG_HDRLEN + payload; +} + +static inline int +nlmsg_total_size(int payload) +{ + return NLMSG_ALIGN(nlmsg_size(payload)); +} + +static inline int +nlmsg_ok(const struct nlmsghdr *nlh, int remaining) +{ + return (remaining >= (int) sizeof(struct nlmsghdr) && nlh->nlmsg_len >= sizeof(struct nlmsghdr) + && nlh->nlmsg_len <= remaining); +} + +static inline struct nlmsghdr * +nlmsg_next(struct nlmsghdr *nlh, int *remaining) +{ + int totlen = NLMSG_ALIGN(nlh->nlmsg_len); + + *remaining -= totlen; + + return (struct nlmsghdr *) ((unsigned char *) nlh + totlen); +} + +int nlmsg_get_proto(struct nl_msg *msg); +void nlmsg_set_proto(struct nl_msg *msg, int protocol); + +void nlmsg_set_src(struct nl_msg *msg, struct sockaddr_nl *addr); + +struct ucred *nlmsg_get_creds(struct nl_msg *msg); +void nlmsg_set_creds(struct nl_msg *msg, struct ucred *creds); + +static inline void +_nm_auto_nl_msg_cleanup(struct nl_msg **ptr) +{ + nlmsg_free(*ptr); +} +#define nm_auto_nlmsg nm_auto(_nm_auto_nl_msg_cleanup) + +static inline void * +nlmsg_data(const struct nlmsghdr *nlh) +{ + return (unsigned char *) nlh + NLMSG_HDRLEN; +} + +static inline void * +nlmsg_tail(const struct nlmsghdr *nlh) +{ + return (unsigned char *) nlh + NLMSG_ALIGN(nlh->nlmsg_len); +} + +struct nlmsghdr *nlmsg_hdr(struct nl_msg *n); + +static inline int +nlmsg_valid_hdr(const struct nlmsghdr *nlh, int hdrlen) +{ + if (nlh->nlmsg_len < nlmsg_size(hdrlen)) + return 0; + + return 1; +} + +static inline int +nlmsg_datalen(const struct nlmsghdr *nlh) +{ + return nlh->nlmsg_len - NLMSG_HDRLEN; +} + +static inline int +nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen) +{ + return NM_MAX((int) (nlmsg_datalen(nlh) - NLMSG_ALIGN(hdrlen)), 0); +} + +static inline struct nlattr * +nlmsg_attrdata(const struct nlmsghdr *nlh, int hdrlen) +{ + unsigned char *data = nlmsg_data(nlh); + return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen)); +} + +static inline struct nlattr * +nlmsg_find_attr(struct nlmsghdr *nlh, int hdrlen, int attrtype) +{ + return nla_find(nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen), attrtype); +} + +int nlmsg_parse(struct nlmsghdr * nlh, + int hdrlen, + struct nlattr * tb[], + int maxtype, + const struct nla_policy *policy); + +#define nlmsg_parse_arr(nlh, hdrlen, tb, policy) \ + ({ \ + _nl_static_assert_tb((tb), (policy)); \ + G_STATIC_ASSERT_EXPR((hdrlen) >= 0); \ + \ + nlmsg_parse((nlh), (hdrlen), (tb), G_N_ELEMENTS(tb) - 1, (policy)); \ + }) + +struct nlmsghdr * +nlmsg_put(struct nl_msg *n, uint32_t pid, uint32_t seq, int type, int payload, int flags); + +/*****************************************************************************/ + +#define NL_AUTO_PORT 0 +#define NL_AUTO_SEQ 0 + +struct nl_sock; + +struct nl_sock *nl_socket_alloc(void); + +void nl_socket_free(struct nl_sock *sk); + +int nl_socket_get_fd(const struct nl_sock *sk); + +struct sockaddr_nl *nlmsg_get_dst(struct nl_msg *msg); + +size_t nl_socket_get_msg_buf_size(struct nl_sock *sk); +int nl_socket_set_msg_buf_size(struct nl_sock *sk, size_t bufsize); + +int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf); + +int nl_socket_set_passcred(struct nl_sock *sk, int state); + +int nl_socket_set_nonblocking(const struct nl_sock *sk); + +void nl_socket_disable_msg_peek(struct nl_sock *sk); + +uint32_t nl_socket_get_local_port(const struct nl_sock *sk); + +int nl_socket_add_memberships(struct nl_sock *sk, int group, ...); + +int nl_connect(struct nl_sock *sk, int protocol); + +int nl_recv(struct nl_sock * sk, + struct sockaddr_nl *nla, + unsigned char ** buf, + struct ucred * out_creds, + gboolean * out_creds_has); + +int nl_send(struct nl_sock *sk, struct nl_msg *msg); + +int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg); + +/*****************************************************************************/ + +enum nl_cb_action { + /* Proceed with wathever would come next */ + NL_OK, + /* Skip this message */ + NL_SKIP, + /* Stop parsing altogether and discard remaining messages */ + NL_STOP, +}; + +typedef int (*nl_recvmsg_msg_cb_t)(struct nl_msg *msg, void *arg); + +typedef int (*nl_recvmsg_err_cb_t)(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg); + +struct nl_cb { + nl_recvmsg_msg_cb_t valid_cb; + void * valid_arg; + + nl_recvmsg_msg_cb_t finish_cb; + void * finish_arg; + + nl_recvmsg_msg_cb_t ack_cb; + void * ack_arg; + + nl_recvmsg_err_cb_t err_cb; + void * err_arg; +}; + +int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr); + +int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen); + +void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg); + +int nl_recvmsgs(struct nl_sock *sk, const struct nl_cb *cb); + +int nl_wait_for_ack(struct nl_sock *sk, const struct nl_cb *cb); + +int nl_socket_set_ext_ack(struct nl_sock *sk, gboolean enable); + +/*****************************************************************************/ + +void * genlmsg_put(struct nl_msg *msg, + uint32_t port, + uint32_t seq, + int family, + int hdrlen, + int flags, + uint8_t cmd, + uint8_t version); +void * genlmsg_data(const struct genlmsghdr *gnlh); +void * genlmsg_user_hdr(const struct genlmsghdr *gnlh); +struct genlmsghdr *genlmsg_hdr(struct nlmsghdr *nlh); +void * genlmsg_user_data(const struct genlmsghdr *gnlh, const int hdrlen); +struct nlattr * genlmsg_attrdata(const struct genlmsghdr *gnlh, int hdrlen); +int genlmsg_len(const struct genlmsghdr *gnlh); +int genlmsg_attrlen(const struct genlmsghdr *gnlh, int hdrlen); +int genlmsg_valid_hdr(struct nlmsghdr *nlh, int hdrlen); + +int genlmsg_parse(struct nlmsghdr * nlh, + int hdrlen, + struct nlattr * tb[], + int maxtype, + const struct nla_policy *policy); + +#define genlmsg_parse_arr(nlh, hdrlen, tb, policy) \ + ({ \ + _nl_static_assert_tb((tb), (policy)); \ + G_STATIC_ASSERT_EXPR((hdrlen) >= 0); \ + \ + genlmsg_parse((nlh), (hdrlen), (tb), G_N_ELEMENTS(tb) - 1, (policy)); \ + }) + +int genl_ctrl_resolve(struct nl_sock *sk, const char *name); + +/*****************************************************************************/ + +#endif /* __NM_NETLINK_H__ */ diff --git a/src/libnm-platform/nm-platform-private.h b/src/libnm-platform/nm-platform-private.h new file mode 100644 index 0000000..cf80568 --- /dev/null +++ b/src/libnm-platform/nm-platform-private.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_PLATFORM_PRIVATE_H__ +#define __NM_PLATFORM_PRIVATE_H__ + +#include "nm-platform.h" +#include "nmp-object.h" + +NMPCache *nm_platform_get_cache(NMPlatform *self); + +#define NMTST_ASSERT_PLATFORM_NETNS_CURRENT(platform) \ + G_STMT_START \ + { \ + NMPlatform *_platform = (platform); \ + \ + nm_assert(NM_IS_PLATFORM(_platform)); \ + nm_assert(NM_IN_SET(nm_platform_netns_get(_platform), NULL, nmp_netns_get_current())); \ + } \ + G_STMT_END + +void nm_platform_cache_update_emit_signal(NMPlatform * platform, + NMPCacheOpsType cache_op, + const NMPObject *obj_old, + const NMPObject *obj_new); + +#endif /* __NM_PLATFORM_PRIVATE_H__ */ diff --git a/src/libnm-platform/nm-platform-utils.c b/src/libnm-platform/nm-platform-utils.c new file mode 100644 index 0000000..a46deb5 --- /dev/null +++ b/src/libnm-platform/nm-platform-utils.c @@ -0,0 +1,2035 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-platform-utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libnm-base/nm-ethtool-base.h" +#include "libnm-log-core/nm-logging.h" +#include "libnm-glib-aux/nm-time-utils.h" + +/*****************************************************************************/ + +#define ONOFF(bool_val) ((bool_val) ? "on" : "off") + +/****************************************************************************** + * utils + *****************************************************************************/ + +extern char *if_indextoname(unsigned __ifindex, char *__ifname); +unsigned if_nametoindex(const char *__ifname); + +const char * +nmp_utils_if_indextoname(int ifindex, char *out_ifname /*IFNAMSIZ*/) +{ + g_return_val_if_fail(ifindex > 0, NULL); + g_return_val_if_fail(out_ifname, NULL); + + return if_indextoname(ifindex, out_ifname); +} + +int +nmp_utils_if_nametoindex(const char *ifname) +{ + g_return_val_if_fail(ifname, 0); + + return if_nametoindex(ifname); +} + +/*****************************************************************************/ + +NM_UTILS_LOOKUP_STR_DEFINE(nm_platform_link_duplex_type_to_string, + NMPlatformLinkDuplexType, + NM_UTILS_LOOKUP_DEFAULT_WARN(NULL), + NM_UTILS_LOOKUP_STR_ITEM(NM_PLATFORM_LINK_DUPLEX_UNKNOWN, "unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_PLATFORM_LINK_DUPLEX_FULL, "full"), + NM_UTILS_LOOKUP_STR_ITEM(NM_PLATFORM_LINK_DUPLEX_HALF, "half"), ); + +/*****************************************************************************/ + +typedef struct { + int fd; + const int ifindex; + char ifname[IFNAMSIZ]; +} SocketHandle; + +#define SOCKET_HANDLE_INIT(_ifindex) \ + { \ + .fd = -1, .ifindex = (_ifindex), \ + } + +static void +_nm_auto_socket_handle(SocketHandle *shandle) +{ + if (shandle->fd >= 0) + nm_close(shandle->fd); +} + +#define nm_auto_socket_handle nm_auto(_nm_auto_socket_handle) + +/*****************************************************************************/ + +typedef enum { + IOCTL_CALL_DATA_TYPE_NONE, + IOCTL_CALL_DATA_TYPE_IFRDATA, + IOCTL_CALL_DATA_TYPE_IFRU, +} IoctlCallDataType; + +static int +_ioctl_call(const char * log_ioctl_type, + const char * log_subtype, + unsigned long int ioctl_request, + int ifindex, + int * inout_fd, + char * inout_ifname, + IoctlCallDataType edata_type, + gpointer edata, + gsize edata_size, + struct ifreq * out_ifreq) +{ + nm_auto_close int fd_close = -1; + int fd; + int r; + gpointer edata_backup = NULL; + gs_free gpointer edata_backup_free = NULL; + guint try_count; + char known_ifnames[2][IFNAMSIZ]; + const char * failure_reason = NULL; + struct ifreq ifr; + + nm_assert(ifindex > 0); + nm_assert(NM_IN_SET(edata_type, + IOCTL_CALL_DATA_TYPE_NONE, + IOCTL_CALL_DATA_TYPE_IFRDATA, + IOCTL_CALL_DATA_TYPE_IFRU)); + nm_assert(edata_type != IOCTL_CALL_DATA_TYPE_NONE || edata_size == 0); + nm_assert(edata_type != IOCTL_CALL_DATA_TYPE_IFRDATA || edata_size > 0); + nm_assert(edata_type != IOCTL_CALL_DATA_TYPE_IFRU + || (edata_size > 0 && edata_size <= sizeof(ifr.ifr_ifru))); + nm_assert(edata_size == 0 || edata); + + /* open a file descriptor (or use the one provided). */ + if (inout_fd && *inout_fd >= 0) + fd = *inout_fd; + else { + fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + r = -NM_ERRNO_NATIVE(errno); + failure_reason = "failed creating socket or ioctl"; + goto out; + } + if (inout_fd) + *inout_fd = fd; + else + fd_close = fd; + } + + /* resolve the ifindex to name (or use the one provided). */ + if (inout_ifname && inout_ifname[0]) + nm_utils_ifname_cpy(known_ifnames[0], inout_ifname); + else { + if (!nmp_utils_if_indextoname(ifindex, known_ifnames[0])) { + failure_reason = "cannot resolve ifindex"; + r = -ENODEV; + goto out; + } + if (inout_ifname) + nm_utils_ifname_cpy(inout_ifname, known_ifnames[0]); + } + + /* we might need to retry the request. Backup edata so that we can + * restore it on retry. */ + if (edata_size > 0) + edata_backup = nm_memdup_maybe_a(500, edata, edata_size, &edata_backup_free); + + try_count = 0; + +again: +{ + const char *ifname = known_ifnames[try_count % 2]; + + nm_assert(ifindex > 0); + nm_assert(ifname && nm_utils_ifname_valid_kernel(ifname, NULL)); + nm_assert(fd >= 0); + + memset(&ifr, 0, sizeof(ifr)); + nm_utils_ifname_cpy(ifr.ifr_name, ifname); + if (edata_type == IOCTL_CALL_DATA_TYPE_IFRDATA) + ifr.ifr_data = edata; + else if (edata_type == IOCTL_CALL_DATA_TYPE_IFRU) + memcpy(&ifr.ifr_ifru, edata, NM_MIN(edata_size, sizeof(ifr.ifr_ifru))); + + if (ioctl(fd, ioctl_request, &ifr) < 0) { + r = -NM_ERRNO_NATIVE(errno); + nm_log_trace(LOGD_PLATFORM, + "%s[%d]: %s, %s: failed: %s", + log_ioctl_type, + ifindex, + log_subtype, + ifname, + nm_strerror_native(-r)); + } else { + r = 0; + nm_log_trace(LOGD_PLATFORM, + "%s[%d]: %s, %s: success", + log_ioctl_type, + ifindex, + log_subtype, + ifname); + } +} + + try_count++; + + /* resolve the name again to see whether the ifindex still has the same name. */ + if (!nmp_utils_if_indextoname(ifindex, known_ifnames[try_count % 2])) { + /* we could not find the ifindex again. Probably the device just got + * removed. + * + * In both cases we return the error code we got from ioctl above. + * Either it failed because the device was gone already or it still + * managed to complete the call. In both cases, the error code is good. */ + failure_reason = + "cannot resolve ifindex after ioctl call. Probably the device was just removed"; + goto out; + } + + /* check whether the ifname changed in the meantime. If yes, would render the result + * invalid. Note that this cannot detect every race regarding renames, for example: + * + * - if_indextoname(#10) gives eth0 + * - rename(#10) => eth0_tmp + * - rename(#11) => eth0 + * - ioctl(eth0) (wrongly fetching #11, formerly eth1) + * - rename(#11) => eth_something + * - rename(#10) => eth0 + * - if_indextoname(#10) gives eth0 + */ + if (!nm_streq(known_ifnames[0], known_ifnames[1])) { + gboolean retry; + + /* we detected a possible(!) rename. + * + * For getters it's straight forward to just retry the call. + * + * For setters we also always retry. If our previous call operated on the right device, + * calling it again should have no bad effect (just setting the same thing more than once). + * + * The only potential bad thing is if there was a race involving swapping names, and we just + * set the ioctl option on the wrong device. But then the bad thing already happenned and + * we cannot detect it (nor do anything about it). At least, we can retry and set the + * option on the right interface. */ + retry = (try_count < 5); + + nm_log_trace(LOGD_PLATFORM, + "%s[%d]: %s: rename detected from \"%s\" to \"%s\". %s", + log_ioctl_type, + ifindex, + log_subtype, + known_ifnames[(try_count - 1) % 2], + known_ifnames[try_count % 2], + retry ? "Retry" : "No retry"); + if (inout_ifname) + nm_utils_ifname_cpy(inout_ifname, known_ifnames[try_count % 2]); + if (retry) { + if (edata_size > 0) + memcpy(edata, edata_backup, edata_size); + goto again; + } + } + +out: + if (failure_reason) { + nm_log_trace(LOGD_PLATFORM, + "%s[%d]: %s: %s: %s", + log_ioctl_type, + ifindex, + log_subtype, + failure_reason, + r < 0 ? nm_strerror_native(-r) : "assume success"); + } + if (r >= 0) + NM_SET_OUT(out_ifreq, ifr); + return r; +} + +/****************************************************************************** + * ethtool + *****************************************************************************/ + +static NM_UTILS_ENUM2STR_DEFINE(_ethtool_cmd_to_string, + guint32, + NM_UTILS_ENUM2STR(ETHTOOL_GCOALESCE, "ETHTOOL_GCOALESCE"), + NM_UTILS_ENUM2STR(ETHTOOL_GDRVINFO, "ETHTOOL_GDRVINFO"), + NM_UTILS_ENUM2STR(ETHTOOL_GFEATURES, "ETHTOOL_GFEATURES"), + NM_UTILS_ENUM2STR(ETHTOOL_GLINK, "ETHTOOL_GLINK"), + NM_UTILS_ENUM2STR(ETHTOOL_GPERMADDR, "ETHTOOL_GPERMADDR"), + NM_UTILS_ENUM2STR(ETHTOOL_GRINGPARAM, "ETHTOOL_GRINGPARAM"), + NM_UTILS_ENUM2STR(ETHTOOL_GSET, "ETHTOOL_GSET"), + NM_UTILS_ENUM2STR(ETHTOOL_GSSET_INFO, "ETHTOOL_GSSET_INFO"), + NM_UTILS_ENUM2STR(ETHTOOL_GSTATS, "ETHTOOL_GSTATS"), + NM_UTILS_ENUM2STR(ETHTOOL_GSTRINGS, "ETHTOOL_GSTRINGS"), + NM_UTILS_ENUM2STR(ETHTOOL_GWOL, "ETHTOOL_GWOL"), + NM_UTILS_ENUM2STR(ETHTOOL_SCOALESCE, "ETHTOOL_SCOALESCE"), + NM_UTILS_ENUM2STR(ETHTOOL_SFEATURES, "ETHTOOL_SFEATURES"), + NM_UTILS_ENUM2STR(ETHTOOL_SRINGPARAM, "ETHTOOL_SRINGPARAM"), + NM_UTILS_ENUM2STR(ETHTOOL_SSET, "ETHTOOL_SSET"), + NM_UTILS_ENUM2STR(ETHTOOL_SWOL, "ETHTOOL_SWOL"), ); + +static const char * +_ethtool_edata_to_string(gpointer edata, gsize edata_size, char *sbuf, gsize sbuf_len) +{ + nm_assert(edata); + nm_assert(edata_size >= sizeof(guint32)); + nm_assert((((intptr_t) edata) % _nm_alignof(guint32)) == 0); + + return _ethtool_cmd_to_string(*((guint32 *) edata), sbuf, sbuf_len); +} + +/*****************************************************************************/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) + #define ethtool_cmd_speed(pedata) ((pedata)->speed) + + #define ethtool_cmd_speed_set(pedata, speed) \ + G_STMT_START \ + { \ + (pedata)->speed = (guint16)(speed); \ + } \ + G_STMT_END +#endif + +static int +_ethtool_call_handle(SocketHandle *shandle, gpointer edata, gsize edata_size) +{ + char sbuf[50]; + + return _ioctl_call("ethtool", + _ethtool_edata_to_string(edata, edata_size, sbuf, sizeof(sbuf)), + SIOCETHTOOL, + shandle->ifindex, + &shandle->fd, + shandle->ifname, + IOCTL_CALL_DATA_TYPE_IFRDATA, + edata, + edata_size, + NULL); +} + +static int +_ethtool_call_once(int ifindex, gpointer edata, gsize edata_size) +{ + char sbuf[50]; + + return _ioctl_call("ethtool", + _ethtool_edata_to_string(edata, edata_size, sbuf, sizeof(sbuf)), + SIOCETHTOOL, + ifindex, + NULL, + NULL, + IOCTL_CALL_DATA_TYPE_IFRDATA, + edata, + edata_size, + NULL); +} + +/*****************************************************************************/ + +static struct ethtool_gstrings * +ethtool_get_stringset(SocketHandle *shandle, int stringset_id) +{ + struct { + struct ethtool_sset_info info; + guint32 sentinel; + } sset_info = { + .info.cmd = ETHTOOL_GSSET_INFO, + .info.reserved = 0, + .info.sset_mask = (1ULL << stringset_id), + }; + const guint32 * pdata; + gs_free struct ethtool_gstrings *gstrings = NULL; + gsize gstrings_len; + guint32 i, len; + + if (_ethtool_call_handle(shandle, &sset_info, sizeof(sset_info)) < 0) + return NULL; + if (!sset_info.info.sset_mask) + return NULL; + + pdata = (guint32 *) sset_info.info.data; + + len = *pdata; + + gstrings_len = sizeof(*gstrings) + (len * ETH_GSTRING_LEN); + gstrings = g_malloc0(gstrings_len); + gstrings->cmd = ETHTOOL_GSTRINGS; + gstrings->string_set = stringset_id; + gstrings->len = len; + if (gstrings->len > 0) { + if (_ethtool_call_handle(shandle, gstrings, gstrings_len) < 0) + return NULL; + for (i = 0; i < gstrings->len; i++) { + /* ensure NUL terminated */ + gstrings->data[i * ETH_GSTRING_LEN + (ETH_GSTRING_LEN - 1)] = '\0'; + } + } + + return g_steal_pointer(&gstrings); +} + +static int +ethtool_gstrings_find(const struct ethtool_gstrings *gstrings, const char *needle) +{ + guint32 i; + + /* ethtool_get_stringset() always ensures NUL terminated strings at ETH_GSTRING_LEN. + * that means, we cannot possibly request longer names. */ + nm_assert(needle && strlen(needle) < ETH_GSTRING_LEN); + + for (i = 0; i < gstrings->len; i++) { + if (nm_streq((char *) &gstrings->data[i * ETH_GSTRING_LEN], needle)) + return i; + } + return -1; +} + +static int +ethtool_get_stringset_index(SocketHandle *shandle, int stringset_id, const char *needle) +{ + gs_free struct ethtool_gstrings *gstrings = NULL; + + /* ethtool_get_stringset() always ensures NUL terminated strings at ETH_GSTRING_LEN. + * that means, we cannot possibly request longer names. */ + nm_assert(needle && strlen(needle) < ETH_GSTRING_LEN); + + gstrings = ethtool_get_stringset(shandle, stringset_id); + if (gstrings) + return ethtool_gstrings_find(gstrings, needle); + return -1; +} + +/*****************************************************************************/ + +static const NMEthtoolFeatureInfo _ethtool_feature_infos[_NM_ETHTOOL_ID_FEATURE_NUM] = { +#define ETHT_FEAT(eid, ...) \ + { \ + .ethtool_id = eid, .n_kernel_names = NM_NARG(__VA_ARGS__), \ + .kernel_names = ((const char *const[]){__VA_ARGS__}), \ + } + + /* the order does only matter for one thing: if it happens that more than one NMEthtoolID + * reference the same kernel-name, then the one that is mentioned *later* will win in + * case these NMEthtoolIDs are set. That mostly only makes sense for ethtool-ids which + * refer to multiple features ("feature-tso"), while also having more specific ids + * ("feature-tx-tcp-segmentation"). */ + + /* names from ethtool utility, which are aliases for multiple features. */ + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_SG, "tx-scatter-gather", "tx-scatter-gather-fraglist"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TSO, + "tx-tcp-segmentation", + "tx-tcp-ecn-segmentation", + "tx-tcp-mangleid-segmentation", + "tx-tcp6-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX, + "tx-checksum-ipv4", + "tx-checksum-ip-generic", + "tx-checksum-ipv6", + "tx-checksum-fcoe-crc", + "tx-checksum-sctp"), + + /* names from ethtool utility, which are aliases for one feature. */ + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert"), + + /* names of features, as known by kernel. */ + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, "esp-hw-offload"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, "esp-tx-csum-hw-offload"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_FCOE_MTU, "fcoe-mtu"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_HIGHDMA, "highdma"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, "hw-tc-offload"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, "l2-fwd-offload"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_LOOPBACK, "loopback"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_MACSEC_HW_OFFLOAD, "macsec-hw-offload"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RX_ALL, "rx-all"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RX_FCS, "rx-fcs"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, "rx-gro-hw"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RX_GRO_LIST, "rx-gro-list"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RX_UDP_GRO_FORWARDING, "rx-udp-gro-forwarding"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, "rx-udp_tunnel-port-offload"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, "rx-vlan-filter"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, "rx-vlan-stag-filter"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, "rx-vlan-stag-hw-parse"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, "tls-hw-record"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TLS_HW_RX_OFFLOAD, "tls-hw-rx-offload"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, "tls-hw-tx-offload"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, "tx-checksum-fcoe-crc"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, "tx-checksum-ipv4"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, "tx-checksum-ipv6"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, "tx-checksum-ip-generic"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, "tx-checksum-sctp"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, "tx-esp-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, "tx-fcoe-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, "tx-gre-csum-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, "tx-gre-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_GSO_LIST, "tx-gso-list"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, "tx-gso-partial"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, "tx-gso-robust"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, "tx-ipxip4-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, "tx-ipxip6-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, "tx-nocache-copy"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, "tx-scatter-gather"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, "tx-scatter-gather-fraglist"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, "tx-sctp-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, "tx-tcp-ecn-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, "tx-tcp-mangleid-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_TUNNEL_REMCSUM_SEGMENTATION, + "tx-tunnel-remcsum-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, "tx-udp-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, "tx-udp_tnl-csum-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, "tx-udp_tnl-segmentation"), + ETHT_FEAT(NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"), +}; + +/* the number of kernel features that we handle. It essentially is the sum of all + * kernel_names. So, all ethtool-ids that reference exactly one kernel-name + * (_NM_ETHTOOL_ID_FEATURE_NUM) + some extra, for ethtool-ids that are aliases + * for multiple kernel-names. */ +#define N_ETHTOOL_KERNEL_FEATURES (((guint) _NM_ETHTOOL_ID_FEATURE_NUM) + 8u) + +static void +_ASSERT_ethtool_feature_infos(void) +{ +#if NM_MORE_ASSERTS > 10 + guint i, k, n; + bool found[_NM_ETHTOOL_ID_FEATURE_NUM] = {}; + + G_STATIC_ASSERT_EXPR(G_N_ELEMENTS(_ethtool_feature_infos) == _NM_ETHTOOL_ID_FEATURE_NUM); + + n = 0; + for (i = 0; i < G_N_ELEMENTS(_ethtool_feature_infos); i++) { + NMEthtoolFeatureState kstate; + const NMEthtoolFeatureInfo *inf = &_ethtool_feature_infos[i]; + + g_assert(inf->ethtool_id >= _NM_ETHTOOL_ID_FEATURE_FIRST); + g_assert(inf->ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST); + g_assert(inf->n_kernel_names > 0); + + for (k = 0; k < i; k++) + g_assert(inf->ethtool_id != _ethtool_feature_infos[k].ethtool_id); + + g_assert(!found[_NM_ETHTOOL_ID_FEATURE_AS_IDX(inf->ethtool_id)]); + found[_NM_ETHTOOL_ID_FEATURE_AS_IDX(inf->ethtool_id)] = TRUE; + + kstate.idx_kernel_name = inf->n_kernel_names - 1; + g_assert((guint) kstate.idx_kernel_name == (guint)(inf->n_kernel_names - 1)); + + n += inf->n_kernel_names; + for (k = 0; k < inf->n_kernel_names; k++) { + const char *name = inf->kernel_names[k]; + + g_assert(nm_utils_strv_find_first((char **) inf->kernel_names, k, name) < 0); + + /* these offload features are only informational and cannot be set from user-space + * (NETIF_F_NEVER_CHANGE). We should not track them in _ethtool_feature_infos. */ + g_assert(!nm_streq(name, "netns-local")); + g_assert(!nm_streq(name, "tx-lockless")); + g_assert(!nm_streq(name, "vlan-challenged")); + } + } + + for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) + g_assert(found[i]); + + g_assert(n == N_ETHTOOL_KERNEL_FEATURES); +#endif +} + +static NMEthtoolFeatureStates * +ethtool_get_features(SocketHandle *shandle) +{ + gs_free NMEthtoolFeatureStates * states = NULL; + gs_free struct ethtool_gstrings *ss_features = NULL; + + _ASSERT_ethtool_feature_infos(); + + ss_features = ethtool_get_stringset(shandle, ETH_SS_FEATURES); + if (!ss_features) + return NULL; + + if (ss_features->len > 0) { + gs_free struct ethtool_gfeatures * gfeatures_free = NULL; + struct ethtool_gfeatures * gfeatures; + gsize gfeatures_len; + guint idx; + const NMEthtoolFeatureState * states_list0 = NULL; + const NMEthtoolFeatureState *const *states_plist0 = NULL; + guint states_plist_n = 0; + + gfeatures_len = sizeof(struct ethtool_gfeatures) + + (NM_DIV_ROUND_UP(ss_features->len, 32u) * sizeof(gfeatures->features[0])); + gfeatures = nm_malloc0_maybe_a(300, gfeatures_len, &gfeatures_free); + gfeatures->cmd = ETHTOOL_GFEATURES; + gfeatures->size = NM_DIV_ROUND_UP(ss_features->len, 32u); + if (_ethtool_call_handle(shandle, gfeatures, gfeatures_len) < 0) + return NULL; + + for (idx = 0; idx < G_N_ELEMENTS(_ethtool_feature_infos); idx++) { + const NMEthtoolFeatureInfo *info = &_ethtool_feature_infos[idx]; + guint idx_kernel_name; + + for (idx_kernel_name = 0; idx_kernel_name < info->n_kernel_names; idx_kernel_name++) { + NMEthtoolFeatureState *kstate; + const char * kernel_name = info->kernel_names[idx_kernel_name]; + int i_feature; + guint i_block; + guint32 i_flag; + + i_feature = ethtool_gstrings_find(ss_features, kernel_name); + if (i_feature < 0) + continue; + + i_block = ((guint) i_feature) / 32u; + i_flag = (guint32)(1u << (((guint) i_feature) % 32u)); + + if (!states) { + states = g_malloc0( + sizeof(NMEthtoolFeatureStates) + + (N_ETHTOOL_KERNEL_FEATURES * sizeof(NMEthtoolFeatureState)) + + ((N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS(_ethtool_feature_infos)) + * sizeof(NMEthtoolFeatureState *))); + states_list0 = &states->states_list[0]; + states_plist0 = (gpointer) &states_list0[N_ETHTOOL_KERNEL_FEATURES]; + states->n_ss_features = ss_features->len; + } + + nm_assert(states->n_states < N_ETHTOOL_KERNEL_FEATURES); + kstate = (NMEthtoolFeatureState *) &states_list0[states->n_states]; + states->n_states++; + + kstate->info = info; + kstate->idx_ss_features = i_feature; + kstate->idx_kernel_name = idx_kernel_name; + kstate->available = !!(gfeatures->features[i_block].available & i_flag); + kstate->requested = !!(gfeatures->features[i_block].requested & i_flag); + kstate->active = !!(gfeatures->features[i_block].active & i_flag); + kstate->never_changed = !!(gfeatures->features[i_block].never_changed & i_flag); + + nm_assert(states_plist_n + < N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS(_ethtool_feature_infos)); + + if (!states->states_indexed[_NM_ETHTOOL_ID_FEATURE_AS_IDX(info->ethtool_id)]) + states->states_indexed[_NM_ETHTOOL_ID_FEATURE_AS_IDX(info->ethtool_id)] = + &states_plist0[states_plist_n]; + ((const NMEthtoolFeatureState **) states_plist0)[states_plist_n] = kstate; + states_plist_n++; + } + + if (states && states->states_indexed[_NM_ETHTOOL_ID_FEATURE_AS_IDX(info->ethtool_id)]) { + nm_assert(states_plist_n + < N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS(_ethtool_feature_infos)); + nm_assert(!states_plist0[states_plist_n]); + states_plist_n++; + } + } + } + + return g_steal_pointer(&states); +} + +NMEthtoolFeatureStates * +nmp_utils_ethtool_get_features(int ifindex) +{ + nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); + NMEthtoolFeatureStates * features; + + g_return_val_if_fail(ifindex > 0, 0); + + features = ethtool_get_features(&shandle); + + if (!features) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: failure getting features", + ifindex, + "get-features"); + return NULL; + } + + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: retrieved kernel features", + ifindex, + "get-features"); + return features; +} + +static const char * +_ethtool_feature_state_to_string(char * buf, + gsize buf_size, + const NMEthtoolFeatureState *s, + const char * prefix) +{ + int l; + + l = g_snprintf(buf, + buf_size, + "%s %s%s", + prefix ?: "", + ONOFF(s->active), + (!s->available || s->never_changed) + ? ", [fixed]" + : ((s->requested != s->active) + ? (s->requested ? ", [requested on]" : ", [requested off]") + : "")); + nm_assert(l < buf_size); + return buf; +} + +gboolean +nmp_utils_ethtool_set_features( + int ifindex, + const NMEthtoolFeatureStates *features, + const NMOptionBool *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, + gboolean do_set /* or reset */) +{ + nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); + gs_free struct ethtool_sfeatures * sfeatures_free = NULL; + struct ethtool_sfeatures * sfeatures; + gsize sfeatures_len; + int r; + guint i, j; + struct { + const NMEthtoolFeatureState *f_state; + NMOptionBool requested; + } set_states[N_ETHTOOL_KERNEL_FEATURES]; + guint set_states_n = 0; + gboolean success = TRUE; + + g_return_val_if_fail(ifindex > 0, 0); + g_return_val_if_fail(features, 0); + g_return_val_if_fail(requested, 0); + + nm_assert(features->n_states <= N_ETHTOOL_KERNEL_FEATURES); + + for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) { + const NMEthtoolFeatureState *const *states_indexed; + + if (requested[i] == NM_OPTION_BOOL_DEFAULT) + continue; + + if (!(states_indexed = features->states_indexed[i])) { + if (do_set) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: set feature %s: skip (not found)", + ifindex, + "set-features", + nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname); + success = FALSE; + } + continue; + } + + for (j = 0; states_indexed[j]; j++) { + const NMEthtoolFeatureState *s = states_indexed[j]; + char sbuf[255]; + + if (set_states_n >= G_N_ELEMENTS(set_states)) + g_return_val_if_reached(FALSE); + + if (s->never_changed) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: %s feature %s (%s): %s, %s (skip feature marked as " + "never changed)", + ifindex, + "set-features", + do_set ? "set" : "reset", + nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, + s->info->kernel_names[s->idx_kernel_name], + ONOFF(do_set ? requested[i] == NM_OPTION_BOOL_TRUE : s->active), + _ethtool_feature_state_to_string(sbuf, + sizeof(sbuf), + s, + do_set ? " currently:" : " before:")); + continue; + } + + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: %s feature %s (%s): %s, %s", + ifindex, + "set-features", + do_set ? "set" : "reset", + nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, + s->info->kernel_names[s->idx_kernel_name], + ONOFF(do_set ? requested[i] == NM_OPTION_BOOL_TRUE : s->active), + _ethtool_feature_state_to_string(sbuf, + sizeof(sbuf), + s, + do_set ? " currently:" : " before:")); + + if (do_set && (!s->available || s->never_changed) + && (s->active != (requested[i] == NM_OPTION_BOOL_TRUE))) { + /* we request to change a flag which kernel reported as fixed. + * While the ethtool operation will silently succeed, mark the request + * as failure. */ + success = FALSE; + } + + set_states[set_states_n].f_state = s; + set_states[set_states_n].requested = requested[i]; + set_states_n++; + } + } + + if (set_states_n == 0) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: no feature requested", + ifindex, + "set-features"); + return TRUE; + } + + sfeatures_len = + sizeof(struct ethtool_sfeatures) + + (NM_DIV_ROUND_UP(features->n_ss_features, 32U) * sizeof(sfeatures->features[0])); + sfeatures = nm_malloc0_maybe_a(300, sfeatures_len, &sfeatures_free); + sfeatures->cmd = ETHTOOL_SFEATURES; + sfeatures->size = NM_DIV_ROUND_UP(features->n_ss_features, 32U); + + for (i = 0; i < set_states_n; i++) { + const NMEthtoolFeatureState *s = set_states[i].f_state; + guint i_block; + guint32 i_flag; + gboolean is_requested; + + i_block = s->idx_ss_features / 32u; + i_flag = (guint32)(1u << (s->idx_ss_features % 32u)); + + sfeatures->features[i_block].valid |= i_flag; + + if (do_set) + is_requested = (set_states[i].requested == NM_OPTION_BOOL_TRUE); + else + is_requested = s->active; + + if (is_requested) + sfeatures->features[i_block].requested |= i_flag; + else + sfeatures->features[i_block].requested &= ~i_flag; + } + + r = _ethtool_call_handle(&shandle, sfeatures, sfeatures_len); + if (r < 0) { + success = FALSE; + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: failure setting features (%s)", + ifindex, + "set-features", + nm_strerror_native(-r)); + return FALSE; + } + + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: %s", + ifindex, + "set-features", + success ? "successfully setting features" + : "at least some of the features were not successfully set"); + return success; +} + +static gboolean +ethtool_get_coalesce(SocketHandle *shandle, NMEthtoolCoalesceState *coalesce) +{ + struct ethtool_coalesce eth_data; + + eth_data.cmd = ETHTOOL_GCOALESCE; + + if (_ethtool_call_handle(shandle, ð_data, sizeof(struct ethtool_coalesce)) != 0) + return FALSE; + + *coalesce = (NMEthtoolCoalesceState){ + .s = { + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_USECS)] = + eth_data.rx_coalesce_usecs, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_FRAMES)] = + eth_data.rx_max_coalesced_frames, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ)] = + eth_data.rx_coalesce_usecs_irq, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ)] = + eth_data.rx_max_coalesced_frames_irq, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_USECS)] = + eth_data.tx_coalesce_usecs, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_FRAMES)] = + eth_data.tx_max_coalesced_frames, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ)] = + eth_data.tx_coalesce_usecs_irq, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ)] = + eth_data.tx_max_coalesced_frames_irq, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS)] = + eth_data.stats_block_coalesce_usecs, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX)] = + eth_data.use_adaptive_rx_coalesce, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX)] = + eth_data.use_adaptive_tx_coalesce, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW)] = + eth_data.pkt_rate_low, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW)] = + eth_data.rx_coalesce_usecs_low, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW)] = + eth_data.rx_max_coalesced_frames_low, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW)] = + eth_data.tx_coalesce_usecs_low, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW)] = + eth_data.tx_max_coalesced_frames_low, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH)] = + eth_data.pkt_rate_high, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH)] = + eth_data.rx_coalesce_usecs_high, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH)] = + eth_data.rx_max_coalesced_frames_high, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH)] = + eth_data.tx_coalesce_usecs_high, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH)] = + eth_data.tx_max_coalesced_frames_high, + [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL)] = + eth_data.rate_sample_interval, + }}; + return TRUE; +} + +gboolean +nmp_utils_ethtool_get_coalesce(int ifindex, NMEthtoolCoalesceState *coalesce) +{ + nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(coalesce, FALSE); + + if (!ethtool_get_coalesce(&shandle, coalesce)) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: failure getting coalesce settings", + ifindex, + "get-coalesce"); + return FALSE; + } + + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: retrieved kernel coalesce settings", + ifindex, + "get-coalesce"); + return TRUE; +} + +static gboolean +ethtool_set_coalesce(SocketHandle *shandle, const NMEthtoolCoalesceState *coalesce) +{ + struct ethtool_coalesce eth_data; + gboolean success; + + nm_assert(shandle); + nm_assert(coalesce); + + eth_data = (struct ethtool_coalesce){ + .cmd = ETHTOOL_SCOALESCE, + .rx_coalesce_usecs = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_USECS)], + .rx_max_coalesced_frames = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_FRAMES)], + .rx_coalesce_usecs_irq = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ)], + .rx_max_coalesced_frames_irq = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ)], + .tx_coalesce_usecs = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_USECS)], + .tx_max_coalesced_frames = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_FRAMES)], + .tx_coalesce_usecs_irq = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ)], + .tx_max_coalesced_frames_irq = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ)], + .stats_block_coalesce_usecs = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS)], + .use_adaptive_rx_coalesce = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX)], + .use_adaptive_tx_coalesce = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX)], + .pkt_rate_low = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW)], + .rx_coalesce_usecs_low = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW)], + .rx_max_coalesced_frames_low = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW)], + .tx_coalesce_usecs_low = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW)], + .tx_max_coalesced_frames_low = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW)], + .pkt_rate_high = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH)], + .rx_coalesce_usecs_high = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH)], + .rx_max_coalesced_frames_high = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH)], + .tx_coalesce_usecs_high = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH)], + .tx_max_coalesced_frames_high = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH)], + .rate_sample_interval = + coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL)], + }; + + success = (_ethtool_call_handle(shandle, ð_data, sizeof(struct ethtool_coalesce)) == 0); + return success; +} + +gboolean +nmp_utils_ethtool_set_coalesce(int ifindex, const NMEthtoolCoalesceState *coalesce) +{ + nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(coalesce, FALSE); + + if (!ethtool_set_coalesce(&shandle, coalesce)) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: failure setting coalesce settings", + ifindex, + "set-coalesce"); + return FALSE; + } + + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: set kernel coalesce settings", + ifindex, + "set-coalesce"); + return TRUE; +} + +static gboolean +ethtool_get_ring(SocketHandle *shandle, NMEthtoolRingState *ring) +{ + struct ethtool_ringparam eth_data; + + eth_data.cmd = ETHTOOL_GRINGPARAM; + + if (_ethtool_call_handle(shandle, ð_data, sizeof(struct ethtool_ringparam)) != 0) + return FALSE; + + ring->rx_pending = eth_data.rx_pending; + ring->rx_jumbo_pending = eth_data.rx_jumbo_pending; + ring->rx_mini_pending = eth_data.rx_mini_pending; + ring->tx_pending = eth_data.tx_pending; + + return TRUE; +} + +gboolean +nmp_utils_ethtool_get_ring(int ifindex, NMEthtoolRingState *ring) +{ + nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(ring, FALSE); + + if (!ethtool_get_ring(&shandle, ring)) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: failure getting ring settings", + ifindex, + "get-ring"); + return FALSE; + } + + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: retrieved kernel ring settings", + ifindex, + "get-ring"); + return TRUE; +} + +static gboolean +ethtool_set_ring(SocketHandle *shandle, const NMEthtoolRingState *ring) +{ + gboolean success; + struct ethtool_ringparam eth_data; + + g_return_val_if_fail(shandle, FALSE); + g_return_val_if_fail(ring, FALSE); + + eth_data = (struct ethtool_ringparam){ + .cmd = ETHTOOL_SRINGPARAM, + .rx_pending = ring->rx_pending, + .rx_jumbo_pending = ring->rx_jumbo_pending, + .rx_mini_pending = ring->rx_mini_pending, + .tx_pending = ring->tx_pending, + }; + + success = (_ethtool_call_handle(shandle, ð_data, sizeof(struct ethtool_ringparam)) == 0); + return success; +} + +gboolean +nmp_utils_ethtool_set_ring(int ifindex, const NMEthtoolRingState *ring) +{ + nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(ring, FALSE); + + if (!ethtool_set_ring(&shandle, ring)) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: failure setting ring settings", + ifindex, + "set-ring"); + return FALSE; + } + + nm_log_trace(LOGD_PLATFORM, "ethtool[%d]: %s: set kernel ring settings", ifindex, "set-ring"); + return TRUE; +} + +/*****************************************************************************/ + +gboolean +nmp_utils_ethtool_get_driver_info(int ifindex, NMPUtilsEthtoolDriverInfo *data) +{ + struct ethtool_drvinfo *drvinfo; + + G_STATIC_ASSERT_EXPR(sizeof(*data) == sizeof(*drvinfo)); + G_STATIC_ASSERT_EXPR(offsetof(NMPUtilsEthtoolDriverInfo, driver) + == offsetof(struct ethtool_drvinfo, driver)); + G_STATIC_ASSERT_EXPR(offsetof(NMPUtilsEthtoolDriverInfo, version) + == offsetof(struct ethtool_drvinfo, version)); + G_STATIC_ASSERT_EXPR(offsetof(NMPUtilsEthtoolDriverInfo, fw_version) + == offsetof(struct ethtool_drvinfo, fw_version)); + G_STATIC_ASSERT_EXPR(sizeof(data->driver) == sizeof(drvinfo->driver)); + G_STATIC_ASSERT_EXPR(sizeof(data->version) == sizeof(drvinfo->version)); + G_STATIC_ASSERT_EXPR(sizeof(data->fw_version) == sizeof(drvinfo->fw_version)); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(data, FALSE); + + drvinfo = (struct ethtool_drvinfo *) data; + *drvinfo = (struct ethtool_drvinfo){ + .cmd = ETHTOOL_GDRVINFO, + }; + return _ethtool_call_once(ifindex, drvinfo, sizeof(*drvinfo)) >= 0; +} + +gboolean +nmp_utils_ethtool_get_permanent_address(int ifindex, guint8 *buf, size_t *length) +{ + struct { + struct ethtool_perm_addr e; + guint8 _extra_data[_NM_UTILS_HWADDR_LEN_MAX + 1]; + } edata = { + .e.cmd = ETHTOOL_GPERMADDR, + .e.size = _NM_UTILS_HWADDR_LEN_MAX, + }; + const guint8 *pdata; + + guint i; + + g_return_val_if_fail(ifindex > 0, FALSE); + + if (_ethtool_call_once(ifindex, &edata, sizeof(edata)) < 0) + return FALSE; + + if (edata.e.size > _NM_UTILS_HWADDR_LEN_MAX) + return FALSE; + if (edata.e.size < 1) + return FALSE; + + pdata = (const guint8 *) edata.e.data; + + if (NM_IN_SET(pdata[0], 0, 0xFF)) { + /* Some drivers might return a permanent address of all zeros. + * Reject that (rh#1264024) + * + * Some drivers return a permanent address of all ones. Reject that too */ + for (i = 1; i < edata.e.size; i++) { + if (pdata[0] != pdata[i]) + goto not_all_0or1; + } + return FALSE; + } + +not_all_0or1: + memcpy(buf, pdata, edata.e.size); + *length = edata.e.size; + return TRUE; +} + +gboolean +nmp_utils_ethtool_supports_carrier_detect(int ifindex) +{ + struct ethtool_cmd edata = {.cmd = ETHTOOL_GLINK}; + + g_return_val_if_fail(ifindex > 0, FALSE); + + /* We ignore the result. If the ETHTOOL_GLINK call succeeded, then we + * assume the device supports carrier-detect, otherwise we assume it + * doesn't. + */ + return _ethtool_call_once(ifindex, &edata, sizeof(edata)) >= 0; +} + +gboolean +nmp_utils_ethtool_supports_vlans(int ifindex) +{ + nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); + gs_free struct ethtool_gfeatures * features_free = NULL; + struct ethtool_gfeatures * features; + gsize features_len; + int idx, block, bit, size; + + g_return_val_if_fail(ifindex > 0, FALSE); + + idx = ethtool_get_stringset_index(&shandle, ETH_SS_FEATURES, "vlan-challenged"); + if (idx < 0) { + nm_log_dbg(LOGD_PLATFORM, + "ethtool[%d]: vlan-challenged ethtool feature does not exist?", + ifindex); + return FALSE; + } + + block = idx / 32; + bit = idx % 32; + size = block + 1; + + features_len = sizeof(*features) + (size * sizeof(struct ethtool_get_features_block)); + features = nm_malloc0_maybe_a(300, features_len, &features_free); + features->cmd = ETHTOOL_GFEATURES; + features->size = size; + + if (_ethtool_call_handle(&shandle, features, features_len) < 0) + return FALSE; + + return !(features->features[block].active & (1 << bit)); +} + +int +nmp_utils_ethtool_get_peer_ifindex(int ifindex) +{ + nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); + gsize stats_len; + gs_free struct ethtool_stats * stats_free = NULL; + struct ethtool_stats * stats; + int peer_ifindex_stat; + + g_return_val_if_fail(ifindex > 0, 0); + + peer_ifindex_stat = ethtool_get_stringset_index(&shandle, ETH_SS_STATS, "peer_ifindex"); + if (peer_ifindex_stat < 0) { + nm_log_dbg(LOGD_PLATFORM, "ethtool[%d]: peer_ifindex stat does not exist?", ifindex); + return FALSE; + } + + stats_len = sizeof(*stats) + (peer_ifindex_stat + 1) * sizeof(guint64); + stats = nm_malloc0_maybe_a(300, stats_len, &stats_free); + stats->cmd = ETHTOOL_GSTATS; + stats->n_stats = peer_ifindex_stat + 1; + if (_ethtool_call_handle(&shandle, stats, stats_len) < 0) + return 0; + + return stats->data[peer_ifindex_stat]; +} + +gboolean +nmp_utils_ethtool_get_wake_on_lan(int ifindex) +{ + struct ethtool_wolinfo wol = { + .cmd = ETHTOOL_GWOL, + }; + + g_return_val_if_fail(ifindex > 0, FALSE); + + if (_ethtool_call_once(ifindex, &wol, sizeof(wol)) < 0) + return FALSE; + + return wol.wolopts != 0; +} + +gboolean +nmp_utils_ethtool_get_link_settings(int ifindex, + gboolean * out_autoneg, + guint32 * out_speed, + NMPlatformLinkDuplexType *out_duplex) +{ + struct ethtool_cmd edata = { + .cmd = ETHTOOL_GSET, + }; + + g_return_val_if_fail(ifindex > 0, FALSE); + + if (_ethtool_call_once(ifindex, &edata, sizeof(edata)) < 0) + return FALSE; + + NM_SET_OUT(out_autoneg, (edata.autoneg == AUTONEG_ENABLE)); + + if (out_speed) { + guint32 speed; + + speed = ethtool_cmd_speed(&edata); + if (speed == G_MAXUINT16 || speed == G_MAXUINT32) + speed = 0; + + *out_speed = speed; + } + + if (out_duplex) { + switch (edata.duplex) { + case DUPLEX_HALF: + *out_duplex = NM_PLATFORM_LINK_DUPLEX_HALF; + break; + case DUPLEX_FULL: + *out_duplex = NM_PLATFORM_LINK_DUPLEX_FULL; + break; + default: /* DUPLEX_UNKNOWN */ + *out_duplex = NM_PLATFORM_LINK_DUPLEX_UNKNOWN; + break; + } + } + + return TRUE; +} + +#define ADVERTISED_INVALID 0 +#define BASET_ALL_MODES \ + (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Half \ + | ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full \ + | ADVERTISED_10000baseT_Full) + +static guint32 +get_baset_mode(guint32 speed, NMPlatformLinkDuplexType duplex) +{ + if (duplex == NM_PLATFORM_LINK_DUPLEX_UNKNOWN) + return ADVERTISED_INVALID; + + if (duplex == NM_PLATFORM_LINK_DUPLEX_HALF) { + switch (speed) { + case 10: + return ADVERTISED_10baseT_Half; + case 100: + return ADVERTISED_100baseT_Half; + case 1000: + return ADVERTISED_1000baseT_Half; + default: + return ADVERTISED_INVALID; + } + } else { + switch (speed) { + case 10: + return ADVERTISED_10baseT_Full; + case 100: + return ADVERTISED_100baseT_Full; + case 1000: + return ADVERTISED_1000baseT_Full; + case 10000: + return ADVERTISED_10000baseT_Full; + default: + return ADVERTISED_INVALID; + } + } +} + +gboolean +nmp_utils_ethtool_set_link_settings(int ifindex, + gboolean autoneg, + guint32 speed, + NMPlatformLinkDuplexType duplex) +{ + nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); + struct ethtool_cmd edata = { + .cmd = ETHTOOL_GSET, + }; + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail((speed && duplex != NM_PLATFORM_LINK_DUPLEX_UNKNOWN) + || (!speed && duplex == NM_PLATFORM_LINK_DUPLEX_UNKNOWN), + FALSE); + + /* retrieve first current settings */ + if (_ethtool_call_handle(&shandle, &edata, sizeof(edata)) < 0) + return FALSE; + + /* FIXME: try first new ETHTOOL_GLINKSETTINGS/SLINKSETTINGS API + * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3f1ac7a700d039c61d8d8b99f28d605d489a60cf + */ + + /* then change the needed ones */ + edata.cmd = ETHTOOL_SSET; + if (autoneg) { + edata.autoneg = AUTONEG_ENABLE; + if (!speed) + edata.advertising = edata.supported; + else { + guint32 mode; + + mode = get_baset_mode(speed, duplex); + + if (!mode) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %uBASE-T %s duplex mode cannot be advertised", + ifindex, + speed, + nm_platform_link_duplex_type_to_string(duplex)); + return FALSE; + } + if (!(edata.supported & mode)) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: device does not support %uBASE-T %s duplex mode", + ifindex, + speed, + nm_platform_link_duplex_type_to_string(duplex)); + return FALSE; + } + edata.advertising = (edata.supported & ~BASET_ALL_MODES) | mode; + } + } else { + edata.autoneg = AUTONEG_DISABLE; + + if (speed) + ethtool_cmd_speed_set(&edata, speed); + + switch (duplex) { + case NM_PLATFORM_LINK_DUPLEX_HALF: + edata.duplex = DUPLEX_HALF; + break; + case NM_PLATFORM_LINK_DUPLEX_FULL: + edata.duplex = DUPLEX_FULL; + break; + case NM_PLATFORM_LINK_DUPLEX_UNKNOWN: + break; + default: + g_return_val_if_reached(FALSE); + } + } + + return _ethtool_call_handle(&shandle, &edata, sizeof(edata)) >= 0; +} + +gboolean +nmp_utils_ethtool_set_wake_on_lan(int ifindex, + _NMSettingWiredWakeOnLan wol, + const char * wol_password) +{ + struct ethtool_wolinfo wol_info = { + .cmd = ETHTOOL_SWOL, + .wolopts = 0, + }; + + g_return_val_if_fail(ifindex > 0, FALSE); + + if (wol == _NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE) + return TRUE; + + nm_log_dbg(LOGD_PLATFORM, + "ethtool[%d]: setting Wake-on-LAN options 0x%x, password '%s'", + ifindex, + (unsigned) wol, + wol_password); + + if (NM_FLAGS_HAS(wol, _NM_SETTING_WIRED_WAKE_ON_LAN_PHY)) + wol_info.wolopts |= WAKE_PHY; + if (NM_FLAGS_HAS(wol, _NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST)) + wol_info.wolopts |= WAKE_UCAST; + if (NM_FLAGS_HAS(wol, _NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST)) + wol_info.wolopts |= WAKE_MCAST; + if (NM_FLAGS_HAS(wol, _NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST)) + wol_info.wolopts |= WAKE_BCAST; + if (NM_FLAGS_HAS(wol, _NM_SETTING_WIRED_WAKE_ON_LAN_ARP)) + wol_info.wolopts |= WAKE_ARP; + if (NM_FLAGS_HAS(wol, _NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) + wol_info.wolopts |= WAKE_MAGIC; + + if (wol_password) { + if (!_nm_utils_hwaddr_aton_exact(wol_password, wol_info.sopass, ETH_ALEN)) { + nm_log_dbg(LOGD_PLATFORM, + "ethtool[%d]: couldn't parse Wake-on-LAN password '%s'", + ifindex, + wol_password); + return FALSE; + } + wol_info.wolopts |= WAKE_MAGICSECURE; + } + + return _ethtool_call_once(ifindex, &wol_info, sizeof(wol_info)) >= 0; +} + +/****************************************************************************** + * mii + *****************************************************************************/ + +gboolean +nmp_utils_mii_supports_carrier_detect(int ifindex) +{ + nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT(ifindex); + int r; + struct ifreq ifr; + struct mii_ioctl_data * mii; + + g_return_val_if_fail(ifindex > 0, FALSE); + + r = _ioctl_call("mii", + "SIOCGMIIPHY", + SIOCGMIIPHY, + shandle.ifindex, + &shandle.fd, + shandle.ifname, + IOCTL_CALL_DATA_TYPE_NONE, + NULL, + 0, + &ifr); + if (r < 0) + return FALSE; + + /* If we can read the BMSR register, we assume that the card supports MII link detection */ + mii = (struct mii_ioctl_data *) &ifr.ifr_ifru; + mii->reg_num = MII_BMSR; + + r = _ioctl_call("mii", + "SIOCGMIIREG", + SIOCGMIIREG, + shandle.ifindex, + &shandle.fd, + shandle.ifname, + IOCTL_CALL_DATA_TYPE_IFRU, + mii, + sizeof(*mii), + &ifr); + if (r < 0) + return FALSE; + + mii = (struct mii_ioctl_data *) &ifr.ifr_ifru; + nm_log_trace(LOGD_PLATFORM, + "mii[%d,%s]: carrier-detect yes: SIOCGMIIREG result 0x%X", + ifindex, + shandle.ifname, + mii->val_out); + return TRUE; +} + +/****************************************************************************** + * udev + *****************************************************************************/ + +const char * +nmp_utils_udev_get_driver(struct udev_device *udevice) +{ + struct udev_device *parent = NULL, *grandparent = NULL; + const char * driver, *subsys; + + driver = udev_device_get_driver(udevice); + if (driver) + goto out; + + /* Try the parent */ + parent = udev_device_get_parent(udevice); + if (parent) { + driver = udev_device_get_driver(parent); + if (!driver) { + /* Try the grandparent if it's an ibmebus device or if the + * subsys is NULL which usually indicates some sort of + * platform device like a 'gadget' net interface. + */ + subsys = udev_device_get_subsystem(parent); + if ((g_strcmp0(subsys, "ibmebus") == 0) || (subsys == NULL)) { + grandparent = udev_device_get_parent(parent); + if (grandparent) + driver = udev_device_get_driver(grandparent); + } + } + } + +out: + /* Intern the string so we don't have to worry about memory + * management in NMPlatformLink. */ + return g_intern_string(driver); +} + +/****************************************************************************** + * utils + *****************************************************************************/ + +NMIPConfigSource +nmp_utils_ip_config_source_from_rtprot(guint8 rtprot) +{ + return ((int) rtprot) + 1; +} + +NMIPConfigSource +nmp_utils_ip_config_source_round_trip_rtprot(NMIPConfigSource source) +{ + /* when adding a route to kernel for a give @source, the resulting route + * will be put into the cache with a source of NM_IP_CONFIG_SOURCE_RTPROT_*. + * This function returns that. */ + return nmp_utils_ip_config_source_from_rtprot( + nmp_utils_ip_config_source_coerce_to_rtprot(source)); +} + +guint8 +nmp_utils_ip_config_source_coerce_to_rtprot(NMIPConfigSource source) +{ + /* when adding a route to kernel, we coerce the @source field + * to rtm_protocol. This is not lossless as we map different + * source values to the same RTPROT uint8 value. */ + if (source <= NM_IP_CONFIG_SOURCE_UNKNOWN) + return RTPROT_UNSPEC; + + if (source <= _NM_IP_CONFIG_SOURCE_RTPROT_LAST) + return source - 1; + + switch (source) { + case NM_IP_CONFIG_SOURCE_KERNEL: + return RTPROT_KERNEL; + case NM_IP_CONFIG_SOURCE_IP6LL: + return RTPROT_KERNEL; + case NM_IP_CONFIG_SOURCE_DHCP: + return RTPROT_DHCP; + case NM_IP_CONFIG_SOURCE_NDISC: + return RTPROT_RA; + + default: + return RTPROT_STATIC; + } +} + +NMIPConfigSource +nmp_utils_ip_config_source_coerce_from_rtprot(NMIPConfigSource source) +{ + /* When we receive a route from kernel and put it into the platform cache, + * we preserve the protocol field by converting it to a NMIPConfigSource + * via nmp_utils_ip_config_source_from_rtprot(). + * + * However, that is not the inverse of nmp_utils_ip_config_source_coerce_to_rtprot(). + * Instead, to go back to the original value, you need another step: + * nmp_utils_ip_config_source_coerce_from_rtprot (nmp_utils_ip_config_source_from_rtprot (rtprot)). + * + * This might partly restore the original source value, but of course that + * is not really possible because nmp_utils_ip_config_source_coerce_to_rtprot() + * is not injective. + * */ + switch (source) { + case NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC: + return NM_IP_CONFIG_SOURCE_UNKNOWN; + + case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: + case NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT: + return NM_IP_CONFIG_SOURCE_KERNEL; + + case NM_IP_CONFIG_SOURCE_RTPROT_RA: + return NM_IP_CONFIG_SOURCE_NDISC; + + case NM_IP_CONFIG_SOURCE_RTPROT_DHCP: + return NM_IP_CONFIG_SOURCE_DHCP; + + default: + return NM_IP_CONFIG_SOURCE_USER; + } +} + +const char * +nmp_utils_ip_config_source_to_string(NMIPConfigSource source, char *buf, gsize len) +{ + const char *s = NULL; + nm_utils_to_string_buffer_init(&buf, &len); + + if (!len) + return buf; + + switch (source) { + case NM_IP_CONFIG_SOURCE_UNKNOWN: + s = "unknown"; + break; + + case NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC: + s = "rt-unspec"; + break; + case NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT: + s = "rt-redirect"; + break; + case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: + s = "rt-kernel"; + break; + case NM_IP_CONFIG_SOURCE_RTPROT_BOOT: + s = "rt-boot"; + break; + case NM_IP_CONFIG_SOURCE_RTPROT_STATIC: + s = "rt-static"; + break; + case NM_IP_CONFIG_SOURCE_RTPROT_DHCP: + s = "rt-dhcp"; + break; + case NM_IP_CONFIG_SOURCE_RTPROT_RA: + s = "rt-ra"; + break; + + case NM_IP_CONFIG_SOURCE_KERNEL: + s = "kernel"; + break; + case NM_IP_CONFIG_SOURCE_SHARED: + s = "shared"; + break; + case NM_IP_CONFIG_SOURCE_IP4LL: + s = "ipv4ll"; + break; + case NM_IP_CONFIG_SOURCE_IP6LL: + s = "ipv6ll"; + break; + case NM_IP_CONFIG_SOURCE_PPP: + s = "ppp"; + break; + case NM_IP_CONFIG_SOURCE_WWAN: + s = "wwan"; + break; + case NM_IP_CONFIG_SOURCE_VPN: + s = "vpn"; + break; + case NM_IP_CONFIG_SOURCE_DHCP: + s = "dhcp"; + break; + case NM_IP_CONFIG_SOURCE_NDISC: + s = "ndisc"; + break; + case NM_IP_CONFIG_SOURCE_USER: + s = "user"; + break; + default: + break; + } + + if (source >= 1 && source <= 0x100) { + if (s) + g_snprintf(buf, len, "%s", s); + else + g_snprintf(buf, len, "rt-%d", ((int) source) - 1); + } else { + if (s) + g_strlcpy(buf, s, len); + else + g_snprintf(buf, len, "(%d)", source); + } + return buf; +} + +/** + * nmp_utils_sysctl_open_netdir: + * @ifindex: the ifindex for which to open "/sys/class/net/%s" + * @ifname_guess: (allow-none): optional argument, if present used as initial + * guess as the current name for @ifindex. If guessed right, + * it saves an additional if_indextoname() call. + * @out_ifname: (allow-none): if present, must be at least IFNAMSIZ + * characters. On success, this will contain the actual ifname + * found while opening the directory. + * + * Returns: a negative value on failure, on success returns the open fd + * to the "/sys/class/net/%s" directory for @ifindex. + */ +int +nmp_utils_sysctl_open_netdir(int ifindex, const char *ifname_guess, char *out_ifname) +{ +#define SYS_CLASS_NET "/sys/class/net/" + const char *ifname = ifname_guess; + char ifname_buf_last_try[IFNAMSIZ]; + char ifname_buf[IFNAMSIZ]; + guint try_count = 0; + char sysdir[NM_STRLEN(SYS_CLASS_NET) + IFNAMSIZ] = SYS_CLASS_NET; + char fd_buf[256]; + ssize_t nn; + + g_return_val_if_fail(ifindex >= 0, -1); + + ifname_buf_last_try[0] = '\0'; + + for (try_count = 0; try_count < 10; try_count++, ifname = NULL) { + nm_auto_close int fd_dir = -1; + nm_auto_close int fd_ifindex = -1; + + if (!ifname) { + ifname = nmp_utils_if_indextoname(ifindex, ifname_buf); + if (!ifname) + return -1; + } + + nm_assert(nm_utils_ifname_valid_kernel(ifname, NULL)); + + if (g_strlcpy(&sysdir[NM_STRLEN(SYS_CLASS_NET)], ifname, IFNAMSIZ) >= IFNAMSIZ) + g_return_val_if_reached(-1); + + /* we only retry, if the name changed since previous attempt. + * Hence, it is extremely unlikely that this loop runes until the + * end of the @try_count. */ + if (nm_streq(ifname, ifname_buf_last_try)) + return -1; + strcpy(ifname_buf_last_try, ifname); + + fd_dir = open(sysdir, O_DIRECTORY | O_CLOEXEC); + if (fd_dir < 0) + continue; + + fd_ifindex = openat(fd_dir, "ifindex", O_CLOEXEC); + if (fd_ifindex < 0) + continue; + + nn = nm_utils_fd_read_loop(fd_ifindex, fd_buf, sizeof(fd_buf) - 2, FALSE); + if (nn <= 0) + continue; + fd_buf[nn] = '\0'; + + if (ifindex != (int) _nm_utils_ascii_str_to_int64(fd_buf, 10, 1, G_MAXINT, -1)) + continue; + + if (out_ifname) + strcpy(out_ifname, ifname); + + return nm_steal_fd(&fd_dir); + } + + return -1; +} + +/*****************************************************************************/ + +char * +nmp_utils_new_vlan_name(const char *parent_iface, guint32 vlan_id) +{ + guint id_len; + gsize parent_len; + char *ifname; + + g_return_val_if_fail(parent_iface && *parent_iface, NULL); + + if (vlan_id < 10) + id_len = 2; + else if (vlan_id < 100) + id_len = 3; + else if (vlan_id < 1000) + id_len = 4; + else { + g_return_val_if_fail(vlan_id < 4095, NULL); + id_len = 5; + } + + ifname = g_new(char, IFNAMSIZ); + + parent_len = strlen(parent_iface); + parent_len = MIN(parent_len, IFNAMSIZ - 1 - id_len); + memcpy(ifname, parent_iface, parent_len); + g_snprintf(&ifname[parent_len], IFNAMSIZ - parent_len, ".%u", vlan_id); + + return ifname; +} + +/*****************************************************************************/ + +/* nmp_utils_new_infiniband_name: + * @name: the output-buffer where the value will be written. Must be + * not %NULL and point to a string buffer of at least IFNAMSIZ bytes. + * @parent_name: the parent interface name + * @p_key: the partition key. + * + * Returns: the infiniband name will be written to @name and @name + * is returned. + */ +const char * +nmp_utils_new_infiniband_name(char *name, const char *parent_name, int p_key) +{ + g_return_val_if_fail(name, NULL); + g_return_val_if_fail(parent_name && parent_name[0], NULL); + g_return_val_if_fail(strlen(parent_name) < IFNAMSIZ, NULL); + + /* technically, p_key of 0x0000 and 0x8000 is not allowed either. But we don't + * want to assert against that in nmp_utils_new_infiniband_name(). So be more + * resilient here, and accept those. */ + g_return_val_if_fail(p_key >= 0 && p_key <= 0xffff, NULL); + + /* If parent+suffix is too long, kernel would just truncate + * the name. We do the same. See ipoib_vlan_add(). */ + g_snprintf(name, IFNAMSIZ, "%s.%04x", parent_name, p_key); + return name; +} + +/*****************************************************************************/ + +/** + * Takes a pair @timestamp and @duration, and returns the remaining duration based + * on the new timestamp @now. + */ +guint32 +nmp_utils_lifetime_rebase_relative_time_on_now(guint32 timestamp, guint32 duration, gint32 now) +{ + gint64 t; + + nm_assert(now >= 0); + + if (duration == NM_PLATFORM_LIFETIME_PERMANENT) + return NM_PLATFORM_LIFETIME_PERMANENT; + + if (timestamp == 0) { + /* if the @timestamp is zero, assume it was just left unset and that the relative + * @duration starts counting from @now. This is convenient to construct an address + * and print it in nm_platform_ip4_address_to_string(). + * + * In general it does not make sense to set the @duration without anchoring at + * @timestamp because you don't know the absolute expiration time when looking + * at the address at a later moment. */ + timestamp = now; + } + + /* For timestamp > now, just accept it and calculate the expected(?) result. */ + t = (gint64) timestamp + (gint64) duration - (gint64) now; + + if (t <= 0) + return 0; + if (t >= NM_PLATFORM_LIFETIME_PERMANENT) + return NM_PLATFORM_LIFETIME_PERMANENT - 1; + return t; +} + +guint32 +nmp_utils_lifetime_get(guint32 timestamp, + guint32 lifetime, + guint32 preferred, + gint32 now, + guint32 *out_preferred) +{ + guint32 t_lifetime, t_preferred; + + nm_assert(now >= 0); + + if (timestamp == 0 && lifetime == 0) { + /* We treat lifetime==0 && timestamp==0 addresses as permanent addresses to allow easy + * creation of such addresses (without requiring to set the lifetime fields to + * NM_PLATFORM_LIFETIME_PERMANENT). The real lifetime==0 addresses (E.g. DHCP6 telling us + * to drop an address will have timestamp set. + */ + NM_SET_OUT(out_preferred, NM_PLATFORM_LIFETIME_PERMANENT); + g_return_val_if_fail(preferred == 0, NM_PLATFORM_LIFETIME_PERMANENT); + return NM_PLATFORM_LIFETIME_PERMANENT; + } + + if (now <= 0) + now = nm_utils_get_monotonic_timestamp_sec(); + + t_lifetime = nmp_utils_lifetime_rebase_relative_time_on_now(timestamp, lifetime, now); + if (!t_lifetime) { + NM_SET_OUT(out_preferred, 0); + return 0; + } + + t_preferred = nmp_utils_lifetime_rebase_relative_time_on_now(timestamp, preferred, now); + + NM_SET_OUT(out_preferred, MIN(t_preferred, t_lifetime)); + + /* Assert that non-permanent addresses have a (positive) @timestamp. nmp_utils_lifetime_rebase_relative_time_on_now() + * treats addresses with timestamp 0 as *now*. Addresses passed to _address_get_lifetime() always + * should have a valid @timestamp, otherwise on every re-sync, their lifetime will be extended anew. + */ + g_return_val_if_fail(timestamp != 0 + || (lifetime == NM_PLATFORM_LIFETIME_PERMANENT + && preferred == NM_PLATFORM_LIFETIME_PERMANENT), + t_lifetime); + g_return_val_if_fail(t_preferred <= t_lifetime, t_lifetime); + + return t_lifetime; +} + +/*****************************************************************************/ + +static const char * +_trunk_first_line(char *str) +{ + char *s; + + s = strchr(str, '\n'); + if (s) + s[0] = '\0'; + return str; +} + +int +nmp_utils_modprobe(GError **error, gboolean suppress_error_logging, const char *arg1, ...) +{ + gs_unref_ptrarray GPtrArray *argv = NULL; + int exit_status; + gs_free char * _log_str = NULL; +#define ARGV_TO_STR(argv) \ + (_log_str ? _log_str : (_log_str = g_strjoinv(" ", (char **) argv->pdata))) + GError * local = NULL; + va_list ap; + NMLogLevel llevel = suppress_error_logging ? LOGL_DEBUG : LOGL_ERR; + gs_free char *std_out = NULL, *std_err = NULL; + + g_return_val_if_fail(!error || !*error, -1); + g_return_val_if_fail(arg1, -1); + + /* construct the argument list */ + argv = g_ptr_array_sized_new(4); + g_ptr_array_add(argv, "/sbin/modprobe"); + g_ptr_array_add(argv, "--use-blacklist"); + g_ptr_array_add(argv, (char *) arg1); + + va_start(ap, arg1); + while ((arg1 = va_arg(ap, const char *))) + g_ptr_array_add(argv, (char *) arg1); + va_end(ap); + + g_ptr_array_add(argv, NULL); + + nm_log_dbg(LOGD_CORE, "modprobe: '%s'", ARGV_TO_STR(argv)); + if (!g_spawn_sync(NULL, + (char **) argv->pdata, + NULL, + 0, + NULL, + NULL, + &std_out, + &std_err, + &exit_status, + &local)) { + nm_log(llevel, + LOGD_CORE, + NULL, + NULL, + "modprobe: '%s' failed: %s", + ARGV_TO_STR(argv), + local->message); + g_propagate_error(error, local); + return -1; + } else if (exit_status != 0) { + nm_log(llevel, + LOGD_CORE, + NULL, + NULL, + "modprobe: '%s' exited with error %d%s%s%s%s%s%s", + ARGV_TO_STR(argv), + exit_status, + std_out && *std_out ? " (" : "", + std_out && *std_out ? _trunk_first_line(std_out) : "", + std_out && *std_out ? ")" : "", + std_err && *std_err ? " (" : "", + std_err && *std_err ? _trunk_first_line(std_err) : "", + std_err && *std_err ? ")" : ""); + } + + return exit_status; +} diff --git a/src/libnm-platform/nm-platform-utils.h b/src/libnm-platform/nm-platform-utils.h new file mode 100644 index 0000000..52fcf8d --- /dev/null +++ b/src/libnm-platform/nm-platform-utils.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_PLATFORM_UTILS_H__ +#define __NM_PLATFORM_UTILS_H__ + +#include "libnm-base/nm-base.h" +#include "libnm-platform/nmp-base.h" + +/*****************************************************************************/ + +const char *nmp_utils_ethtool_get_driver(int ifindex); +gboolean nmp_utils_ethtool_supports_carrier_detect(int ifindex); +gboolean nmp_utils_ethtool_supports_vlans(int ifindex); +int nmp_utils_ethtool_get_peer_ifindex(int ifindex); +gboolean nmp_utils_ethtool_get_wake_on_lan(int ifindex); +gboolean nmp_utils_ethtool_set_wake_on_lan(int ifindex, + _NMSettingWiredWakeOnLan wol, + const char * wol_password); + +const char *nm_platform_link_duplex_type_to_string(NMPlatformLinkDuplexType duplex); + +gboolean nmp_utils_ethtool_get_link_settings(int ifindex, + gboolean * out_autoneg, + guint32 * out_speed, + NMPlatformLinkDuplexType *out_duplex); +gboolean nmp_utils_ethtool_set_link_settings(int ifindex, + gboolean autoneg, + guint32 speed, + NMPlatformLinkDuplexType duplex); + +gboolean nmp_utils_ethtool_get_permanent_address(int ifindex, guint8 *buf, size_t *length); + +gboolean nmp_utils_ethtool_get_driver_info(int ifindex, NMPUtilsEthtoolDriverInfo *data); + +NMEthtoolFeatureStates *nmp_utils_ethtool_get_features(int ifindex); + +gboolean nmp_utils_ethtool_set_features( + int ifindex, + const NMEthtoolFeatureStates *features, + const NMOptionBool *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, + gboolean do_set /* or reset */); + +gboolean nmp_utils_ethtool_get_coalesce(int ifindex, NMEthtoolCoalesceState *coalesce); + +gboolean nmp_utils_ethtool_set_coalesce(int ifindex, const NMEthtoolCoalesceState *coalesce); + +gboolean nmp_utils_ethtool_get_ring(int ifindex, NMEthtoolRingState *ring); + +gboolean nmp_utils_ethtool_set_ring(int ifindex, const NMEthtoolRingState *ring); + +/*****************************************************************************/ + +gboolean nmp_utils_mii_supports_carrier_detect(int ifindex); + +struct udev_device; + +const char *nmp_utils_udev_get_driver(struct udev_device *udevice); + +NMIPConfigSource nmp_utils_ip_config_source_from_rtprot(guint8 rtprot) _nm_const; +guint8 nmp_utils_ip_config_source_coerce_to_rtprot(NMIPConfigSource source) _nm_const; +NMIPConfigSource nmp_utils_ip_config_source_coerce_from_rtprot(NMIPConfigSource source) _nm_const; +NMIPConfigSource nmp_utils_ip_config_source_round_trip_rtprot(NMIPConfigSource source) _nm_const; +const char *nmp_utils_ip_config_source_to_string(NMIPConfigSource source, char *buf, gsize len); + +const char *nmp_utils_if_indextoname(int ifindex, char *out_ifname /*IFNAMSIZ*/); +int nmp_utils_if_nametoindex(const char *ifname); + +int nmp_utils_sysctl_open_netdir(int ifindex, const char *ifname_guess, char *out_ifname); + +char * nmp_utils_new_vlan_name(const char *parent_iface, guint32 vlan_id); +const char *nmp_utils_new_infiniband_name(char *name, const char *parent_name, int p_key); + +guint32 +nmp_utils_lifetime_rebase_relative_time_on_now(guint32 timestamp, guint32 duration, gint32 now); + +guint32 nmp_utils_lifetime_get(guint32 timestamp, + guint32 lifetime, + guint32 preferred, + gint32 now, + guint32 *out_preferred); + +int nmp_utils_modprobe(GError **error, gboolean suppress_error_logging, const char *arg1, ...) + G_GNUC_NULL_TERMINATED; + +#endif /* __NM_PLATFORM_UTILS_H__ */ diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c new file mode 100644 index 0000000..9eee50f --- /dev/null +++ b/src/libnm-platform/nm-platform.c @@ -0,0 +1,8979 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2012 - 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-platform.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libnm-base/nm-net-aux.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-glib-aux/nm-time-utils.h" +#include "libnm-log-core/nm-logging.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-platform/nmp-netns.h" +#include "libnm-udev-aux/nm-udev-utils.h" +#include "nm-platform-private.h" +#include "nmp-object.h" + +/*****************************************************************************/ + +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPAddress, address_ptr) + == G_STRUCT_OFFSET(NMPlatformIP4Address, address)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPAddress, address_ptr) + == G_STRUCT_OFFSET(NMPlatformIP6Address, address)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPRoute, network_ptr) + == G_STRUCT_OFFSET(NMPlatformIP4Route, network)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPRoute, network_ptr) + == G_STRUCT_OFFSET(NMPlatformIP6Route, network)); + +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPRoute) == _nm_alignof(NMPlatformIP4Route)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPRoute) == _nm_alignof(NMPlatformIP6Route)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPRoute) == _nm_alignof(NMPlatformIPXRoute)); + +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPAddress) == _nm_alignof(NMPlatformIP4Address)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPAddress) == _nm_alignof(NMPlatformIP6Address)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformIPAddress) == _nm_alignof(NMPlatformIPXAddress)); + +/*****************************************************************************/ + +G_STATIC_ASSERT(sizeof(((NMPLinkAddress *) NULL)->data) == _NM_UTILS_HWADDR_LEN_MAX); +G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_address.data) == _NM_UTILS_HWADDR_LEN_MAX); +G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_broadcast.data) == _NM_UTILS_HWADDR_LEN_MAX); + +static const char * +_nmp_link_address_to_string(const NMPLinkAddress *addr, + char buf[static(_NM_UTILS_HWADDR_LEN_MAX * 3)]) +{ + nm_assert(addr); + + if (addr->len > 0) { + if (!_nm_utils_hwaddr_ntoa(addr->data, + addr->len, + TRUE, + buf, + _NM_UTILS_HWADDR_LEN_MAX * 3)) { + buf[0] = '\0'; + g_return_val_if_reached(buf); + } + } else + buf[0] = '\0'; + + return buf; +} + +gconstpointer +nmp_link_address_get(const NMPLinkAddress *addr, size_t *length) +{ + if (!addr || addr->len <= 0) { + NM_SET_OUT(length, 0); + return NULL; + } + + if (addr->len > _NM_UTILS_HWADDR_LEN_MAX) { + NM_SET_OUT(length, 0); + g_return_val_if_reached(NULL); + } + + NM_SET_OUT(length, addr->len); + return addr->data; +} + +GBytes * +nmp_link_address_get_as_bytes(const NMPLinkAddress *addr) +{ + gconstpointer data; + size_t length; + + data = nmp_link_address_get(addr, &length); + + return length > 0 ? g_bytes_new(data, length) : NULL; +} + +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_PLATFORM +#define _NMLOG_PREFIX_NAME "platform" + +#define NMLOG_COMMON(level, name, ...) \ + char __prefix[32]; \ + const char * __p_prefix = _NMLOG_PREFIX_NAME; \ + const NMPlatform *const __self = (self); \ + const char * __name = name; \ + \ + if (__self && NM_PLATFORM_GET_PRIVATE(__self)->log_with_ptr) { \ + g_snprintf(__prefix, sizeof(__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ + __p_prefix = __prefix; \ + } \ + _nm_log(__level, \ + _NMLOG_DOMAIN, \ + 0, \ + __name, \ + NULL, \ + "%s: %s%s%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __p_prefix, \ + NM_PRINT_FMT_QUOTED(__name, "(", __name, ") ", "") _NM_UTILS_MACRO_REST(__VA_ARGS__)); + +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + NMLOG_COMMON(level, NULL, __VA_ARGS__); \ + } \ + } \ + G_STMT_END + +#define _NMLOG2(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + NMLOG_COMMON(level, name, __VA_ARGS__); \ + } \ + } \ + G_STMT_END + +#define _NMLOG3(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + NMLOG_COMMON(level, \ + ifindex > 0 ? nm_platform_link_get_name(self, ifindex) : NULL, \ + __VA_ARGS__); \ + } \ + } \ + G_STMT_END + +/*****************************************************************************/ + +static guint signals[_NM_PLATFORM_SIGNAL_ID_LAST] = {0}; + +enum { + PROP_0, + PROP_NETNS_SUPPORT, + PROP_USE_UDEV, + PROP_LOG_WITH_PTR, + LAST_PROP, +}; + +typedef struct _NMPlatformPrivate { + bool use_udev : 1; + bool log_with_ptr : 1; + + guint ip4_dev_route_blacklist_check_id; + guint ip4_dev_route_blacklist_gc_timeout_id; + GHashTable * ip4_dev_route_blacklist_hash; + NMDedupMultiIndex *multi_idx; + NMPCache * cache; +} NMPlatformPrivate; + +G_DEFINE_TYPE(NMPlatform, nm_platform, G_TYPE_OBJECT) + +#define NM_PLATFORM_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMPlatform, NM_IS_PLATFORM) + +/*****************************************************************************/ + +static void _ip4_dev_route_blacklist_schedule(NMPlatform *self); + +/*****************************************************************************/ + +gboolean +nm_platform_get_use_udev(NMPlatform *self) +{ + return NM_PLATFORM_GET_PRIVATE(self)->use_udev; +} + +gboolean +nm_platform_get_log_with_ptr(NMPlatform *self) +{ + return NM_PLATFORM_GET_PRIVATE(self)->log_with_ptr; +} + +/*****************************************************************************/ + +guint +_nm_platform_signal_id_get(NMPlatformSignalIdType signal_type) +{ + nm_assert(signal_type > 0 && signal_type != NM_PLATFORM_SIGNAL_ID_NONE + && signal_type < _NM_PLATFORM_SIGNAL_ID_LAST); + + return signals[signal_type]; +} + +/*****************************************************************************/ + +/* Just always initialize a @klass instance. NM_PLATFORM_GET_CLASS() + * is only a plain read on the self instance, which the compiler + * like can optimize out. + */ +#define _CHECK_SELF_VOID(self, klass) \ + NMPlatformClass *klass; \ + do { \ + g_return_if_fail(NM_IS_PLATFORM(self)); \ + klass = NM_PLATFORM_GET_CLASS(self); \ + (void) klass; \ + } while (0) + +#define _CHECK_SELF(self, klass, err_val) \ + NMPlatformClass *klass; \ + do { \ + g_return_val_if_fail(NM_IS_PLATFORM(self), err_val); \ + klass = NM_PLATFORM_GET_CLASS(self); \ + (void) klass; \ + } while (0) + +#define _CHECK_SELF_NETNS(self, klass, netns, err_val) \ + nm_auto_pop_netns NMPNetns *netns = NULL; \ + NMPlatformClass * klass; \ + do { \ + g_return_val_if_fail(NM_IS_PLATFORM(self), err_val); \ + klass = NM_PLATFORM_GET_CLASS(self); \ + (void) klass; \ + if (!nm_platform_netns_push(self, &netns)) \ + return (err_val); \ + } while (0) + +/*****************************************************************************/ + +NMDedupMultiIndex * +nm_platform_get_multi_idx(NMPlatform *self) +{ + g_return_val_if_fail(NM_IS_PLATFORM(self), NULL); + + return NM_PLATFORM_GET_PRIVATE(self)->multi_idx; +} + +/*****************************************************************************/ + +static NM_UTILS_LOOKUP_STR_DEFINE( + _nmp_nlm_flag_to_string_lookup, + NMPNlmFlags, + NM_UTILS_LOOKUP_DEFAULT(NULL), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_ADD, "add"), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_CHANGE, "change"), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_REPLACE, "replace"), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_PREPEND, "prepend"), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_APPEND, "append"), + NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_TEST, "test"), + NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_F_APPEND), + NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_FMASK), + NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE), + NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_F_ECHO), ); + +#define _nmp_nlm_flag_to_string(flags) \ + ({ \ + NMPNlmFlags _flags = (flags); \ + \ + _nmp_nlm_flag_to_string_lookup(flags) \ + ?: nm_sprintf_bufa(100, "new[0x%x]", (unsigned) _flags); \ + }) + +/*****************************************************************************/ + +volatile int _nm_platform_kernel_support_state[_NM_PLATFORM_KERNEL_SUPPORT_NUM] = {}; + +static const struct { + bool compile_time_default; + const char *name; + const char *desc; +} _nm_platform_kernel_support_info[_NM_PLATFORM_KERNEL_SUPPORT_NUM] = { + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS] = + { + .compile_time_default = TRUE, + .name = "EXTENDED_IFA_FLAGS", + .desc = "IPv6 temporary addresses support", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL] = + { + .compile_time_default = TRUE, + .name = "USER_IPV6LL", + .desc = "IFLA_INET6_ADDR_GEN_MODE support", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF] = + { + .compile_time_default = (RTA_MAX >= 20 /* RTA_PREF */), + .name = "RTA_PREF", + .desc = "ability to set router preference for IPv6 routes", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV] = + { + .compile_time_default = (FRA_MAX >= 19 /* FRA_L3MDEV */), + .name = "FRA_L3MDEV", + .desc = "FRA_L3MDEV attribute for policy routing rules", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE] = + { + .compile_time_default = (FRA_MAX >= 20 /* FRA_UID_RANGE */), + .name = "FRA_UID_RANGE", + .desc = "FRA_UID_RANGE attribute for policy routing rules", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL] = + { + .compile_time_default = (FRA_MAX >= 21 /* FRA_PROTOCOL */), + .name = "FRA_PROTOCOL", + .desc = "FRA_PROTOCOL attribute for policy routing rules", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO] = + { + .compile_time_default = (FRA_MAX >= 22 /* FRA_IP_PROTO */), + .name = "FRA_IP_PROTO", + .desc = "FRA_IP_PROTO, FRA_SPORT_RANGE, FRA_DPORT_RANGE attributes for policy routing " + "rules", + }, + [NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED] = + { + .compile_time_default = (IFLA_BR_MAX >= 41 /* IFLA_BR_VLAN_STATS_ENABLED */), + .name = "IFLA_BR_VLAN_STATS_ENABLE", + .desc = "IFLA_BR_VLAN_STATS_ENABLE bridge link attribute", + }, +}; + +int +_nm_platform_kernel_support_init(NMPlatformKernelSupportType type, int value) +{ + volatile int *p_state; + gboolean set_default = FALSE; + + nm_assert(_NM_INT_NOT_NEGATIVE(type) && type < G_N_ELEMENTS(_nm_platform_kernel_support_state)); + + p_state = &_nm_platform_kernel_support_state[type]; + + if (value == 0) { + set_default = TRUE; + value = _nm_platform_kernel_support_info[type].compile_time_default ? 1 : -1; + } + + nm_assert(NM_IN_SET(value, -1, 1)); + + if (!g_atomic_int_compare_and_exchange(p_state, 0, value)) { + value = g_atomic_int_get(p_state); + nm_assert(NM_IN_SET(value, -1, 1)); + return value; + } + +#undef NM_THREAD_SAFE_ON_MAIN_THREAD +#define NM_THREAD_SAFE_ON_MAIN_THREAD 0 + + if (set_default) { + nm_log_dbg(LOGD_PLATFORM, + "platform: kernel-support for %s (%s) not detected: assume %ssupported", + _nm_platform_kernel_support_info[type].name, + _nm_platform_kernel_support_info[type].desc, + value >= 0 ? "" : "not "); + } else { + nm_log_dbg(LOGD_PLATFORM, + "platform: kernel-support for %s (%s) detected: %ssupported", + _nm_platform_kernel_support_info[type].name, + _nm_platform_kernel_support_info[type].desc, + value >= 0 ? "" : "not "); + } + +#undef NM_THREAD_SAFE_ON_MAIN_THREAD +#define NM_THREAD_SAFE_ON_MAIN_THREAD 1 + + return value; +} + +/*****************************************************************************/ + +/** + * nm_platform_process_events: + * @self: platform instance + * + * Process pending events or handle pending delayed-actions. + * Effectively, this reads the netlink socket and processes + * new netlink messages. Possibly it will raise change signals. + */ +void +nm_platform_process_events(NMPlatform *self) +{ + _CHECK_SELF_VOID(self, klass); + + if (klass->process_events) + klass->process_events(self); +} + +const NMPlatformLink * +nm_platform_process_events_ensure_link(NMPlatform *self, int ifindex, const char *ifname) +{ + const NMPObject *obj; + gboolean refreshed = FALSE; + + g_return_val_if_fail(NM_IS_PLATFORM(self), NULL); + + if (ifindex <= 0 && !ifname) + return NULL; + + /* we look into the cache, whether a link for given ifindex/ifname + * exits. If not, we poll the netlink socket, maybe the event + * with the link is waiting. + * + * Then we try again to find the object. + * + * If the link is already cached the first time, we avoid polling + * the netlink socket. */ +again: + obj = nmp_cache_lookup_link_full( + nm_platform_get_cache(self), + ifindex, + ifname, + FALSE, /* also invisible. We don't care here whether udev is ready */ + NM_LINK_TYPE_NONE, + NULL, + NULL); + if (obj) + return NMP_OBJECT_CAST_LINK(obj); + if (!refreshed) { + refreshed = TRUE; + nm_platform_process_events(self); + goto again; + } + + return NULL; +} + +/*****************************************************************************/ + +/** + * nm_platform_sysctl_open_netdir: + * @self: platform instance + * @ifindex: the ifindex for which to open /sys/class/net/%s + * @out_ifname: optional output argument of the found ifname. + * + * Wraps nmp_utils_sysctl_open_netdir() by first changing into the right + * network-namespace. + * + * Returns: on success, the open file descriptor to the /sys/class/net/%s + * directory. + */ +int +nm_platform_sysctl_open_netdir(NMPlatform *self, int ifindex, char *out_ifname) +{ + const char *ifname_guess; + _CHECK_SELF_NETNS(self, klass, netns, -1); + + g_return_val_if_fail(ifindex > 0, -1); + + /* we don't have an @ifname_guess argument to make the API nicer. + * But still do a cache-lookup first. Chances are good that we have + * the right ifname cached and save if_indextoname() */ + ifname_guess = nm_platform_link_get_name(self, ifindex); + + return nmp_utils_sysctl_open_netdir(ifindex, ifname_guess, out_ifname); +} + +/** + * nm_platform_sysctl_set: + * @self: platform instance + * @pathid: if @dirfd is present, this must be the full path that is looked up. + * It is required for logging. + * @dirfd: optional file descriptor for parent directory for openat() + * @path: Absolute option path + * @value: Value to write + * + * This function is intended to be used for writing values to sysctl-style + * virtual runtime configuration files. This includes not only /proc/sys + * but also for example /sys/class. + * + * Returns: %TRUE on success. + */ +gboolean +nm_platform_sysctl_set(NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + const char *value) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(path, FALSE); + g_return_val_if_fail(value, FALSE); + + return klass->sysctl_set(self, pathid, dirfd, path, value); +} + +/** + * nm_platform_sysctl_set_async: + * @self: platform instance + * @pathid: if @dirfd is present, this must be the full path that is looked up + * @dirfd: optional file descriptor for parent directory for openat() + * @path: absolute option path + * @values: NULL-terminated array of strings to be written + * @callback: function called on termination + * @data: data passed to callback function + * @cancellable: to cancel the operation + * + * This function is intended to be used for writing values to sysctl-style + * virtual runtime configuration files. This includes not only /proc/sys + * but also for example /sys/class. The function does not block and returns + * immediately. The callback is always invoked, and asynchronously. The file + * is closed after writing each value and reopened to write the next one so + * that the function can be used safely on all /proc and /sys files, + * independently of how /proc/sys/kernel/sysctl_writes_strict is configured. + */ +void +nm_platform_sysctl_set_async(NMPlatform * self, + const char * pathid, + int dirfd, + const char * path, + const char *const * values, + NMPlatformAsyncCallback callback, + gpointer data, + GCancellable * cancellable) +{ + _CHECK_SELF_VOID(self, klass); + + klass->sysctl_set_async(self, pathid, dirfd, path, values, callback, data, cancellable); +} + +gboolean +nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe(NMPlatform *self, const char *iface, int value) +{ + const char *path; + gint64 cur; + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + + _CHECK_SELF(self, klass, FALSE); + + /* the hop-limit provided via RA is uint8. */ + if (value > 0xFF) + return FALSE; + + /* don't allow unreasonable small values */ + if (value < 10) + return FALSE; + + path = nm_utils_sysctl_ip_conf_path(AF_INET6, buf, iface, "hop_limit"); + cur = nm_platform_sysctl_get_int_checked(self, + NMP_SYSCTL_PATHID_ABSOLUTE(path), + 10, + 1, + G_MAXINT32, + -1); + + /* only allow increasing the hop-limit to avoid DOS by an attacker + * setting a low hop-limit (CVE-2015-2924, rh#1209902) */ + + if (value < cur) + return FALSE; + if (value != cur) { + char svalue[20]; + + sprintf(svalue, "%d", value); + nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), svalue); + } + + return TRUE; +} + +gboolean +nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time(NMPlatform *self, + const char *iface, + guint value_ms) +{ + char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + char str[128]; + guint clamped; + + _CHECK_SELF(self, klass, FALSE); + + if (!value_ms) + return TRUE; + + /* RFC 4861 says the value can't be greater than one hour. + * Also use a reasonable lower threshold. */ + clamped = NM_CLAMP(value_ms, 100, 3600000); + nm_sprintf_buf(path, "/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms", iface); + nm_sprintf_buf(str, "%u", clamped); + if (!nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), str)) + return FALSE; + + /* Set stale time in the same way as kernel */ + nm_sprintf_buf(path, "/proc/sys/net/ipv6/neigh/%s/gc_stale_time", iface); + nm_sprintf_buf(str, "%u", clamped * 3 / 1000); + + return nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), str); +} + +gboolean +nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time(NMPlatform *self, + const char *iface, + guint value_ms) +{ + char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + char str[128]; + + _CHECK_SELF(self, klass, FALSE); + + if (!value_ms) + return TRUE; + + nm_sprintf_buf(path, "/proc/sys/net/ipv6/neigh/%s/retrans_time_ms", iface); + nm_sprintf_buf(str, "%u", NM_CLAMP(value_ms, 10, 3600000)); + + return nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), str); +} + +/** + * nm_platform_sysctl_get: + * @self: platform instance + * @dirfd: if non-negative, used to lookup the path via openat(). + * @pathid: if @dirfd is present, this must be the full path that is looked up. + * It is required for logging. + * @path: Absolute path to sysctl + * + * Returns: (transfer full): Contents of the virtual sysctl file. + * + * If the path does not exist, %NULL is returned and %errno set to %ENOENT. + */ +char * +nm_platform_sysctl_get(NMPlatform *self, const char *pathid, int dirfd, const char *path) +{ + _CHECK_SELF(self, klass, NULL); + + g_return_val_if_fail(path, NULL); + + return klass->sysctl_get(self, pathid, dirfd, path); +} + +/** + * nm_platform_sysctl_get_int32: + * @self: platform instance + * @pathid: if @dirfd is present, this must be the full path that is looked up. + * It is required for logging. + * @dirfd: if non-negative, used to lookup the path via openat(). + * @path: Absolute path to sysctl + * @fallback: default value, if the content of path could not be read + * as decimal integer. + * + * Returns: contents of the sysctl file parsed as s32 integer, or + * @fallback on error. On error, %errno will be set to a non-zero + * value, on success %errno will be set to zero. + */ +gint32 +nm_platform_sysctl_get_int32(NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + gint32 fallback) +{ + return nm_platform_sysctl_get_int_checked(self, + pathid, + dirfd, + path, + 10, + G_MININT32, + G_MAXINT32, + fallback); +} + +/** + * nm_platform_sysctl_get_int_checked: + * @self: platform instance + * @pathid: if @dirfd is present, this must be the full path that is looked up. + * It is required for logging. + * @dirfd: if non-negative, used to lookup the path via openat(). + * @path: Absolute path to sysctl + * @base: base of numeric conversion + * @min: minimal value that is still valid + * @max: maximal value that is still valid + * @fallback: default value, if the content of path could not be read + * as valid integer. + * + * Returns: contents of the sysctl file parsed as s64 integer, or + * @fallback on error. On error, %errno will be set to a non-zero + * value. On success, %errno will be set to zero. The returned value + * will always be in the range between @min and @max + * (inclusive) or @fallback. + * If the file does not exist, the fallback is returned and %errno + * is set to ENOENT. + */ +gint64 +nm_platform_sysctl_get_int_checked(NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + guint base, + gint64 min, + gint64 max, + gint64 fallback) +{ + char * value = NULL; + gint32 ret; + int errsv; + + _CHECK_SELF(self, klass, fallback); + + g_return_val_if_fail(path, fallback); + + if (!path) { + errno = EINVAL; + return fallback; + } + + value = nm_platform_sysctl_get(self, pathid, dirfd, path); + if (!value) { + /* nm_platform_sysctl_get() set errno to ENOENT if the file does not exist. + * Propagate/preserve that. */ + if (errno != ENOENT) + errno = EINVAL; + return fallback; + } + + ret = _nm_utils_ascii_str_to_int64(value, base, min, max, fallback); + errsv = errno; + g_free(value); + errno = errsv; + return ret; +} + +/*****************************************************************************/ + +char * +nm_platform_sysctl_ip_conf_get(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property) +{ + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + + return nm_platform_sysctl_get( + self, + NMP_SYSCTL_PATHID_ABSOLUTE( + nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property))); +} + +gint64 +nm_platform_sysctl_ip_conf_get_int_checked(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property, + guint base, + gint64 min, + gint64 max, + gint64 fallback) +{ + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + + return nm_platform_sysctl_get_int_checked( + self, + NMP_SYSCTL_PATHID_ABSOLUTE( + nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property)), + base, + min, + max, + fallback); +} + +gboolean +nm_platform_sysctl_ip_conf_set(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property, + const char *value) +{ + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + + return nm_platform_sysctl_set( + self, + NMP_SYSCTL_PATHID_ABSOLUTE( + nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property)), + value); +} + +gboolean +nm_platform_sysctl_ip_conf_set_int64(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property, + gint64 value) +{ + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + char s[64]; + + return nm_platform_sysctl_set( + self, + NMP_SYSCTL_PATHID_ABSOLUTE( + nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property)), + nm_sprintf_buf(s, "%" G_GINT64_FORMAT, value)); +} + +int +nm_platform_sysctl_ip_conf_get_rp_filter_ipv4(NMPlatform *self, + const char *ifname, + gboolean consider_all, + gboolean * out_due_to_all) +{ + int val, val_all; + + NM_SET_OUT(out_due_to_all, FALSE); + + if (!ifname) + return -1; + + val = nm_platform_sysctl_ip_conf_get_int_checked(self, + AF_INET, + ifname, + "rp_filter", + 10, + 0, + 2, + -1); + if (val == -1) + return -1; + + /* the effectively used value is the rp_filter sysctl value of MAX(all,ifname). + * Note that this is the numerical MAX(), despite rp_filter "1" being more strict + * than "2". */ + if (val < 2 && consider_all && !nm_streq(ifname, "all")) { + val_all = nm_platform_sysctl_ip_conf_get_int_checked(self, + AF_INET, + "all", + "rp_filter", + 10, + 0, + 2, + val); + if (val_all > val) { + val = val_all; + NM_SET_OUT(out_due_to_all, TRUE); + } + } + + return val; +} + +/*****************************************************************************/ + +static int +_link_get_all_presort(gconstpointer p_a, gconstpointer p_b, gpointer sort_by_name) +{ + const NMPlatformLink *a = NMP_OBJECT_CAST_LINK(*((const NMPObject **) p_a)); + const NMPlatformLink *b = NMP_OBJECT_CAST_LINK(*((const NMPObject **) p_b)); + + /* Loopback always first */ + if (a->ifindex == 1) + return -1; + if (b->ifindex == 1) + return 1; + + if (GPOINTER_TO_INT(sort_by_name)) { + /* Initialized links first */ + if (a->initialized > b->initialized) + return -1; + if (a->initialized < b->initialized) + return 1; + + return strcmp(a->name, b->name); + } else + return a->ifindex - b->ifindex; +} + +/** + * nm_platform_link_get_all: + * @self: platform instance + * @sort_by_name: whether to sort by name or ifindex. + * + * Retrieve a snapshot of configuration for all links at once. The result is + * owned by the caller and should be freed with g_ptr_array_unref(). + */ +GPtrArray * +nm_platform_link_get_all(NMPlatform *self, gboolean sort_by_name) +{ + gs_unref_ptrarray GPtrArray *links = NULL; + GPtrArray * result; + guint i, nresult; + gs_unref_hashtable GHashTable *unseen = NULL; + const NMPlatformLink * item; + NMPLookup lookup; + + _CHECK_SELF(self, klass, NULL); + + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK); + links = nm_dedup_multi_objs_to_ptr_array_head(nm_platform_lookup(self, &lookup), NULL, NULL); + if (!links) + return NULL; + + for (i = 0; i < links->len;) { + if (!nmp_object_is_visible(links->pdata[i])) + g_ptr_array_remove_index_fast(links, i); + else + i++; + } + + if (links->len == 0) + return NULL; + + /* first sort the links by their ifindex or name. Below we will sort + * further by moving children/slaves to the end. */ + g_ptr_array_sort_with_data(links, _link_get_all_presort, GINT_TO_POINTER(sort_by_name)); + + unseen = g_hash_table_new(nm_direct_hash, NULL); + for (i = 0; i < links->len; i++) { + item = NMP_OBJECT_CAST_LINK(links->pdata[i]); + nm_assert(item->ifindex > 0); + if (!g_hash_table_insert(unseen, GINT_TO_POINTER(item->ifindex), NULL)) + nm_assert_not_reached(); + } + +#if NM_MORE_ASSERTS + /* Ensure that link_get_all returns a consistent and valid result. */ + for (i = 0; i < links->len; i++) { + item = NMP_OBJECT_CAST_LINK(links->pdata[i]); + + if (!item->ifindex) + continue; + if (item->master != 0) { + g_warn_if_fail(item->master > 0); + g_warn_if_fail(item->master != item->ifindex); + g_warn_if_fail(g_hash_table_contains(unseen, GINT_TO_POINTER(item->master))); + } + if (item->parent != 0) { + if (item->parent != NM_PLATFORM_LINK_OTHER_NETNS) { + g_warn_if_fail(item->parent > 0); + g_warn_if_fail(item->parent != item->ifindex); + g_warn_if_fail(g_hash_table_contains(unseen, GINT_TO_POINTER(item->parent))); + } + } + } +#endif + + /* Re-order the links list such that children/slaves come after all ancestors */ + nm_assert(g_hash_table_size(unseen) == links->len); + nresult = links->len; + result = g_ptr_array_new_full(nresult, (GDestroyNotify) nmp_object_unref); + + while (TRUE) { + gboolean found_something = FALSE; + guint first_idx = G_MAXUINT; + + for (i = 0; i < links->len; i++) { + item = NMP_OBJECT_CAST_LINK(links->pdata[i]); + + if (!item) + continue; + + g_assert(g_hash_table_contains(unseen, GINT_TO_POINTER(item->ifindex))); + + if (item->master > 0 && g_hash_table_contains(unseen, GINT_TO_POINTER(item->master))) + goto skip; + if (item->parent > 0 && g_hash_table_contains(unseen, GINT_TO_POINTER(item->parent))) + goto skip; + + g_hash_table_remove(unseen, GINT_TO_POINTER(item->ifindex)); + g_ptr_array_add(result, links->pdata[i]); + links->pdata[i] = NULL; + found_something = TRUE; + continue; +skip: + if (first_idx == G_MAXUINT) + first_idx = i; + } + + if (found_something) { + if (first_idx == G_MAXUINT) + break; + } else { + nm_assert(first_idx != G_MAXUINT); + /* There is a loop, pop the first (remaining) element from the list. + * This can happen for veth pairs where each peer is parent of the other end. */ + item = NMP_OBJECT_CAST_LINK(links->pdata[first_idx]); + nm_assert(item); + g_hash_table_remove(unseen, GINT_TO_POINTER(item->ifindex)); + g_ptr_array_add(result, links->pdata[first_idx]); + links->pdata[first_idx] = NULL; + } + nm_assert(result->len < nresult); + } + nm_assert(result->len == nresult); + + return result; +} + +/*****************************************************************************/ + +const NMPObject * +nm_platform_link_get_obj(NMPlatform *self, int ifindex, gboolean visible_only) +{ + const NMPObject *obj_cache; + + _CHECK_SELF(self, klass, NULL); + + obj_cache = nmp_cache_lookup_link(nm_platform_get_cache(self), ifindex); + if (!obj_cache || (visible_only && !nmp_object_is_visible(obj_cache))) + return NULL; + return obj_cache; +} + +/*****************************************************************************/ + +/** + * nm_platform_link_get: + * @self: platform instance + * @ifindex: ifindex of the link + * + * Lookup the internal NMPlatformLink object. + * + * Returns: %NULL, if such a link exists or the internal + * platform link object. Do not modify the returned value. + * Also, be aware that any subsequent platform call might + * invalidate/modify the returned instance. + **/ +const NMPlatformLink * +nm_platform_link_get(NMPlatform *self, int ifindex) +{ + return NMP_OBJECT_CAST_LINK(nm_platform_link_get_obj(self, ifindex, TRUE)); +} + +/** + * nm_platform_link_get_by_ifname: + * @self: platform instance + * @ifname: the ifname + * + * Returns: the first #NMPlatformLink instance with the given name. + **/ +const NMPlatformLink * +nm_platform_link_get_by_ifname(NMPlatform *self, const char *ifname) +{ + const NMPObject *obj; + + _CHECK_SELF(self, klass, NULL); + + if (!ifname || !*ifname) + return NULL; + + obj = nmp_cache_lookup_link_full(nm_platform_get_cache(self), + 0, + ifname, + TRUE, + NM_LINK_TYPE_NONE, + NULL, + NULL); + return NMP_OBJECT_CAST_LINK(obj); +} + +struct _nm_platform_link_get_by_address_data { + gconstpointer data; + guint8 len; +}; + +static gboolean +_nm_platform_link_get_by_address_match_link(const NMPObject * obj, + struct _nm_platform_link_get_by_address_data *d) +{ + return obj->link.l_address.len == d->len && !memcmp(obj->link.l_address.data, d->data, d->len); +} + +/** + * nm_platform_link_get_by_address: + * @self: platform instance + * @address: a pointer to the binary hardware address + * @length: the size of @address in bytes + * + * Returns: the first #NMPlatformLink object with a matching + * address. + **/ +const NMPlatformLink * +nm_platform_link_get_by_address(NMPlatform * self, + NMLinkType link_type, + gconstpointer address, + size_t length) +{ + const NMPObject * obj; + struct _nm_platform_link_get_by_address_data d = { + .data = address, + .len = length, + }; + + _CHECK_SELF(self, klass, NULL); + + if (length == 0) + return NULL; + + if (length > _NM_UTILS_HWADDR_LEN_MAX) + g_return_val_if_reached(NULL); + if (!address) + g_return_val_if_reached(NULL); + + obj = nmp_cache_lookup_link_full(nm_platform_get_cache(self), + 0, + NULL, + TRUE, + link_type, + (NMPObjectMatchFn) _nm_platform_link_get_by_address_match_link, + &d); + return NMP_OBJECT_CAST_LINK(obj); +} + +static int +_link_add_check_existing(NMPlatform * self, + const char * name, + NMLinkType type, + const NMPlatformLink **out_link) +{ + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get_by_ifname(self, name); + if (pllink) { + gboolean wrong_type; + + wrong_type = type != NM_LINK_TYPE_NONE && pllink->type != type; + _LOG2D("link: skip adding link due to existing interface of type %s%s%s", + nm_link_type_to_string(pllink->type), + wrong_type ? ", expected " : "", + wrong_type ? nm_link_type_to_string(type) : ""); + if (out_link) + *out_link = pllink; + if (wrong_type) + return -NME_PL_WRONG_TYPE; + return -NME_PL_EXISTS; + } + if (out_link) + *out_link = NULL; + return 0; +} + +/** + * nm_platform_link_add: + * @self: platform instance + * @type: Interface type + * @name: Interface name + * @parent: the IFLA_LINK parameter or 0. + * @address: (allow-none): set the mac address of the link + * @address_len: the length of the @address + * @extra_data: depending on @type, additional data. + * @out_link: on success, the link object + * + * Add a software interface. If the interface already exists and is of type + * @type, return -NME_PL_EXISTS and returns the link + * in @out_link. If the interface already exists and is not of type @type, + * return -NME_PL_WRONG_TYPE. + * + * Any link-changed ADDED signal will be emitted directly, before this + * function finishes. + * + * Returns: the negative nm-error on failure. + */ +int +nm_platform_link_add(NMPlatform * self, + NMLinkType type, + const char * name, + int parent, + const void * address, + size_t address_len, + guint32 mtu, + gconstpointer extra_data, + const NMPlatformLink **out_link) +{ + int r; + char addr_buf[_NM_UTILS_HWADDR_LEN_MAX * 3]; + char mtu_buf[16]; + char parent_buf[64]; + char buf[512]; + + _CHECK_SELF(self, klass, -NME_BUG); + + g_return_val_if_fail(name, -NME_BUG); + g_return_val_if_fail((address != NULL) ^ (address_len == 0), -NME_BUG); + g_return_val_if_fail(address_len <= _NM_UTILS_HWADDR_LEN_MAX, -NME_BUG); + g_return_val_if_fail(parent >= 0, -NME_BUG); + + r = _link_add_check_existing(self, name, type, out_link); + if (r < 0) + return r; + + _LOG2D("link: adding link: " + "%s " /* type */ + "\"%s\"" /* name */ + "%s%s" /* parent */ + "%s%s" /* address */ + "%s%s" /* mtu */ + "%s" /* extra_data */ + "", + nm_link_type_to_string(type), + name, + parent > 0 ? ", parent " : "", + parent > 0 ? nm_sprintf_buf(parent_buf, "%d", parent) : "", + address ? ", address: " : "", + address ? _nm_utils_hwaddr_ntoa(address, address_len, FALSE, addr_buf, sizeof(addr_buf)) + : "", + mtu ? ", mtu: " : "", + mtu ? nm_sprintf_buf(mtu_buf, "%u", mtu) : "", + ({ + char *buf_p = buf; + gsize buf_len = sizeof(buf); + + buf[0] = '\0'; + + switch (type) { + case NM_LINK_TYPE_BRIDGE: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_bridge_to_string((const NMPlatformLnkBridge *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_VLAN: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_vlan_to_string((const NMPlatformLnkVlan *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_VRF: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_vrf_to_string((const NMPlatformLnkVrf *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_VXLAN: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_vxlan_to_string((const NMPlatformLnkVxlan *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_VETH: + nm_sprintf_buf(buf, ", veth-peer \"%s\"", (const char *) extra_data); + break; + case NM_LINK_TYPE_GRE: + case NM_LINK_TYPE_GRETAP: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_gre_to_string((const NMPlatformLnkGre *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_SIT: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_sit_to_string((const NMPlatformLnkSit *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_IP6TNL: + case NM_LINK_TYPE_IP6GRE: + case NM_LINK_TYPE_IP6GRETAP: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_ip6tnl_to_string((const NMPlatformLnkIp6Tnl *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_IPIP: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_ipip_to_string((const NMPlatformLnkIpIp *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_MACSEC: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_macsec_to_string((const NMPlatformLnkMacsec *) extra_data, + buf_p, + buf_len); + break; + case NM_LINK_TYPE_MACVLAN: + case NM_LINK_TYPE_MACVTAP: + nm_utils_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_macvlan_to_string((const NMPlatformLnkMacvlan *) extra_data, + buf_p, + buf_len); + break; + default: + nm_assert(!extra_data); + break; + } + + buf; + })); + + return klass + ->link_add(self, type, name, parent, address, address_len, mtu, extra_data, out_link); +} + +/** + * nm_platform_link_delete: + * @self: platform instance + * @ifindex: Interface index + */ +gboolean +nm_platform_link_delete(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + _LOG3D("link: deleting"); + return klass->link_delete(self, ifindex); +} + +/** + * nm_platform_link_set_netns: + * @self: platform instance + * @ifindex: Interface index + * @netns_fd: the file descriptor for the new netns. + * + * Returns: %TRUE on success. + */ +gboolean +nm_platform_link_set_netns(NMPlatform *self, int ifindex, int netns_fd) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(netns_fd > 0, FALSE); + + _LOG3D("link: move link to network namespace with fd %d", netns_fd); + return klass->link_set_netns(self, ifindex, netns_fd); +} + +/** + * nm_platform_link_get_index: + * @self: platform instance + * @name: Interface name + * + * Returns: The interface index corresponding to the given interface name + * or 0. Interface name is owned by #NMPlatform, don't free it. + */ +int +nm_platform_link_get_ifindex(NMPlatform *self, const char *name) +{ + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get_by_ifname(self, name); + return pllink ? pllink->ifindex : 0; +} + +const char * +nm_platform_if_indextoname(NMPlatform *self, int ifindex, char out_ifname[static 16 /* IFNAMSIZ */]) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + return nmp_utils_if_indextoname(ifindex, out_ifname); +} + +int +nm_platform_if_nametoindex(NMPlatform *self, const char *ifname) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + return nmp_utils_if_nametoindex(ifname); +} + +/** + * nm_platform_link_get_name: + * @self: platform instance + * @name: Interface name + * + * Returns: The interface name corresponding to the given interface index + * or %NULL. + */ +const char * +nm_platform_link_get_name(NMPlatform *self, int ifindex) +{ + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get(self, ifindex); + return pllink ? pllink->name : NULL; +} + +/** + * nm_platform_link_get_type: + * @self: platform instance + * @ifindex: Interface index. + * + * Returns: Link type constant as defined in nm-platform.h. On error, + * NM_LINK_TYPE_NONE is returned. + */ +NMLinkType +nm_platform_link_get_type(NMPlatform *self, int ifindex) +{ + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get(self, ifindex); + return pllink ? pllink->type : NM_LINK_TYPE_NONE; +} + +/** + * nm_platform_link_get_type_name: + * @self: platform instance + * @ifindex: Interface index. + * + * Returns: A string describing the type of link. In some cases this + * may be more specific than nm_platform_link_get_type(), but in + * other cases it may not. On error, %NULL is returned. + */ +const char * +nm_platform_link_get_type_name(NMPlatform *self, int ifindex) +{ + const NMPObject *obj; + + obj = nm_platform_link_get_obj(self, ifindex, TRUE); + if (!obj) + return NULL; + + if (obj->link.type != NM_LINK_TYPE_UNKNOWN) { + /* We could detect the @link_type. In this case the function returns + * our internal module names, which differs from rtnl_link_get_type(): + * - NM_LINK_TYPE_INFINIBAND (gives "infiniband", instead of "ipoib") + * - NM_LINK_TYPE_TAP (gives "tap", instead of "tun"). + * Note that this functions is only used by NMDeviceGeneric to + * set type_description. */ + return nm_link_type_to_string(obj->link.type); + } + /* Link type not detected. Fallback to rtnl_link_get_type()/IFLA_INFO_KIND. */ + return obj->link.kind ?: "unknown"; +} + +static gboolean +link_get_udev_property(NMPlatform *self, int ifindex, const char *name, const char **out_value) +{ + struct udev_device *udevice = NULL; + const char * uproperty; + + udevice = nm_platform_link_get_udev_device(self, ifindex); + if (!udevice) + return FALSE; + + uproperty = udev_device_get_property_value(udevice, name); + if (!uproperty) + return FALSE; + + NM_SET_OUT(out_value, uproperty); + return TRUE; +} + +/** + * nm_platform_link_get_unmanaged: + * @self: platform instance + * @ifindex: interface index + * @unmanaged: management status (in case %TRUE is returned) + * + * Returns: %TRUE if platform overrides NM default-unmanaged status, + * %FALSE otherwise (with @unmanaged unmodified). + */ +gboolean +nm_platform_link_get_unmanaged(NMPlatform *self, int ifindex, gboolean *unmanaged) +{ + const char *value; + + if (link_get_udev_property(self, ifindex, "NM_UNMANAGED", &value)) { + NM_SET_OUT(unmanaged, nm_udev_utils_property_as_boolean(value)); + return TRUE; + } + + return FALSE; +} + +/** + * nm_platform_link_is_software: + * @self: platform instance + * @ifindex: Interface index. + * + * Returns: %TRUE if ifindex belongs to a software interface, not backed by + * a physical device. + */ +gboolean +nm_platform_link_is_software(NMPlatform *self, int ifindex) +{ + return nm_link_type_is_software(nm_platform_link_get_type(self, ifindex)); +} + +/** + * nm_platform_link_supports_slaves: + * @self: platform instance + * @ifindex: Interface index. + * + * Returns: %TRUE if ifindex belongs to an interface capable of enslaving + * other interfaces. + */ +gboolean +nm_platform_link_supports_slaves(NMPlatform *self, int ifindex) +{ + return nm_link_type_supports_slaves(nm_platform_link_get_type(self, ifindex)); +} + +/** + * nm_platform_link_refresh: + * @self: platform instance + * @ifindex: Interface index + * + * Reload the cache for ifindex synchronously. + */ +gboolean +nm_platform_link_refresh(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + if (klass->link_refresh) + return klass->link_refresh(self, ifindex); + + return TRUE; +} + +int +nm_platform_link_get_ifi_flags(NMPlatform *self, int ifindex, guint requested_flags) +{ + const NMPlatformLink *pllink; + + /* include invisible links (only in netlink, not udev). */ + pllink = NMP_OBJECT_CAST_LINK(nm_platform_link_get_obj(self, ifindex, FALSE)); + if (!pllink) + return -ENODEV; + + /* Errors are signaled as negative values. That means, you cannot request + * the most significant bit (2^31) with this API. Assert against that. */ + nm_assert((int) requested_flags >= 0); + nm_assert(requested_flags < (guint) G_MAXINT); + + return (int) (pllink->n_ifi_flags & requested_flags); +} + +/** + * nm_platform_link_is_up: + * @self: platform instance + * @ifindex: Interface index + * + * Check if the interface is up. + */ +gboolean +nm_platform_link_is_up(NMPlatform *self, int ifindex) +{ + return nm_platform_link_get_ifi_flags(self, ifindex, IFF_UP) == IFF_UP; +} + +/** + * nm_platform_link_is_connected: + * @self: platform instance + * @ifindex: Interface index + * + * Check if the interface is connected. + */ +gboolean +nm_platform_link_is_connected(NMPlatform *self, int ifindex) +{ + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get(self, ifindex); + return pllink ? pllink->connected : FALSE; +} + +/** + * nm_platform_link_uses_arp: + * @self: platform instance + * @ifindex: Interface index + * + * Check if the interface is configured to use ARP. + */ +gboolean +nm_platform_link_uses_arp(NMPlatform *self, int ifindex) +{ + int f; + + f = nm_platform_link_get_ifi_flags(self, ifindex, IFF_NOARP); + + if (f < 0) + return FALSE; + if (f == IFF_NOARP) + return FALSE; + return TRUE; +} + +/** + * nm_platform_link_set_ipv6_token: + * @self: platform instance + * @ifindex: Interface index + * @iid: Tokenized interface identifier + * + * Sets then IPv6 tokenized interface identifier. + * + * Returns: %TRUE a tokenized identifier was available + */ +gboolean +nm_platform_link_set_ipv6_token(NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + + if (klass->link_set_token) + return klass->link_set_token(self, ifindex, iid); + return FALSE; +} + +const char * +nm_platform_link_get_udi(NMPlatform *self, int ifindex) +{ + struct udev_device *device; + + device = nm_platform_link_get_udev_device(self, ifindex); + return device ? udev_device_get_syspath(device) : NULL; +} + +const char * +nm_platform_link_get_path(NMPlatform *self, int ifindex) +{ + const char *value = NULL; + + link_get_udev_property(self, ifindex, "ID_PATH", &value); + + return value; +} + +struct udev_device * +nm_platform_link_get_udev_device(NMPlatform *self, int ifindex) +{ + const NMPObject *obj_cache; + + obj_cache = nm_platform_link_get_obj(self, ifindex, FALSE); + return obj_cache ? obj_cache->_link.udev.device : NULL; +} + +/** + * nm_platform_link_get_user_ip6vll_enabled: + * @self: platform instance + * @ifindex: Interface index + * + * Check whether NM handles IPv6LL address creation for the link. If the + * platform or OS doesn't support changing the IPv6LL address mode, this call + * will fail and return %FALSE. + * + * Returns: %TRUE if NM handles the IPv6LL address for @ifindex + */ +gboolean +nm_platform_link_get_user_ipv6ll_enabled(NMPlatform *self, int ifindex) +{ + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get(self, ifindex); + if (pllink && pllink->inet6_addr_gen_mode_inv) + return _nm_platform_uint8_inv(pllink->inet6_addr_gen_mode_inv) == NM_IN6_ADDR_GEN_MODE_NONE; + return FALSE; +} + +/** + * nm_platform_link_set_user_ip6vll_enabled: + * @self: platform instance + * @ifindex: Interface index + * + * Set whether NM handles IPv6LL address creation for the link. If the + * platform or OS doesn't support changing the IPv6LL address mode, this call + * will fail and return %FALSE. + * + * Returns: the negative nm-error on failure. + */ +int +nm_platform_link_set_user_ipv6ll_enabled(NMPlatform *self, int ifindex, gboolean enabled) +{ + _CHECK_SELF(self, klass, -NME_BUG); + + g_return_val_if_fail(ifindex > 0, -NME_BUG); + + return klass->link_set_user_ipv6ll_enabled(self, ifindex, enabled); +} + +/** + * nm_platform_link_set_address: + * @self: platform instance + * @ifindex: Interface index + * @address: The new MAC address + * + * Set interface MAC address. + */ +int +nm_platform_link_set_address(NMPlatform *self, int ifindex, gconstpointer address, size_t length) +{ + gs_free char *mac = NULL; + + _CHECK_SELF(self, klass, -NME_BUG); + + g_return_val_if_fail(ifindex > 0, -NME_BUG); + g_return_val_if_fail(address, -NME_BUG); + g_return_val_if_fail(length > 0, -NME_BUG); + + _LOG3D("link: setting hardware address to %s", + _nm_utils_hwaddr_ntoa_maybe_a(address, length, &mac)); + + return klass->link_set_address(self, ifindex, address, length); +} + +/** + * nm_platform_link_get_address: + * @self: platform instance + * @ifindex: Interface index + * @length: Pointer to a variable to store address length + * + * Returns: the interface hardware address as an array of bytes of + * length @length. + */ +gconstpointer +nm_platform_link_get_address(NMPlatform *self, int ifindex, size_t *length) +{ + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get(self, ifindex); + return nmp_link_address_get(pllink ? &pllink->l_address : NULL, length); +} + +/** + * nm_platform_link_get_permanent_address: + * @self: platform instance + * @ifindex: Interface index + * @buf: buffer of at least %_NM_UTILS_HWADDR_LEN_MAX bytes, on success + * the permanent hardware address + * @length: Pointer to a variable to store address length + * + * Returns: %TRUE on success, %FALSE on failure to read the permanent hardware + * address. + */ +gboolean +nm_platform_link_get_permanent_address(NMPlatform *self, int ifindex, guint8 *buf, size_t *length) +{ + _CHECK_SELF(self, klass, FALSE); + + if (length) + *length = 0; + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(buf, FALSE); + g_return_val_if_fail(length, FALSE); + + if (klass->link_get_permanent_address) + return klass->link_get_permanent_address(self, ifindex, buf, length); + return FALSE; +} + +gboolean +nm_platform_link_supports_carrier_detect(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + + return klass->link_supports_carrier_detect(self, ifindex); +} + +gboolean +nm_platform_link_supports_vlans(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + + return klass->link_supports_vlans(self, ifindex); +} + +gboolean +nm_platform_link_supports_sriov(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + + return klass->link_supports_sriov(self, ifindex); +} + +/** + * nm_platform_link_set_sriov_params: + * @self: platform instance + * @ifindex: the index of the interface to change + * @num_vfs: the number of VFs to create + * @autoprobe: the new autoprobe-drivers value (pass + * %NM_OPTION_BOOL_DEFAULT to keep current value) + * @callback: called when the operation finishes + * @callback_data: data passed to @callback + * @cancellable: cancellable to abort the operation + * + * Sets SR-IOV parameters asynchronously without + * blocking the main thread. The callback function is + * always invoked, and asynchronously. + */ +void +nm_platform_link_set_sriov_params_async(NMPlatform * self, + int ifindex, + guint num_vfs, + NMOptionBool autoprobe, + NMPlatformAsyncCallback callback, + gpointer callback_data, + GCancellable * cancellable) +{ + _CHECK_SELF_VOID(self, klass); + + g_return_if_fail(ifindex > 0); + + _LOG3D("link: setting %u total VFs and autoprobe %d", num_vfs, (int) autoprobe); + klass->link_set_sriov_params_async(self, + ifindex, + num_vfs, + autoprobe, + callback, + callback_data, + cancellable); +} + +gboolean +nm_platform_link_set_sriov_vfs(NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs) +{ + guint i; + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + _LOG3D("link: setting VFs"); + for (i = 0; vfs[i]; i++) { + const NMPlatformVF *vf = vfs[i]; + + _LOG3D("link: VF %s", nm_platform_vf_to_string(vf, NULL, 0)); + } + + return klass->link_set_sriov_vfs(self, ifindex, vfs); +} + +gboolean +nm_platform_link_set_bridge_vlans(NMPlatform * self, + int ifindex, + gboolean on_master, + const NMPlatformBridgeVlan *const *vlans) +{ + guint i; + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + _LOG3D("link: %s bridge VLANs on %s", + vlans ? "setting" : "clearing", + on_master ? "master" : "self"); + if (vlans) { + for (i = 0; vlans[i]; i++) { + const NMPlatformBridgeVlan *vlan = vlans[i]; + + _LOG3D("link: bridge VLAN %s", nm_platform_bridge_vlan_to_string(vlan, NULL, 0)); + } + } + + return klass->link_set_bridge_vlans(self, ifindex, on_master, vlans); +} + +/** + * nm_platform_link_set_up: + * @self: platform instance + * @ifindex: Interface index + * @out_no_firmware: (allow-none): if the failure reason is due to missing firmware. + * + * Bring the interface up. + */ +gboolean +nm_platform_link_set_up(NMPlatform *self, int ifindex, gboolean *out_no_firmware) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + _LOG3D("link: setting up"); + return klass->link_set_up(self, ifindex, out_no_firmware); +} + +/** + * nm_platform_link_set_down: + * @self: platform instance + * @ifindex: Interface index + * + * Take the interface down. + */ +gboolean +nm_platform_link_set_down(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + _LOG3D("link: setting down"); + return klass->link_set_down(self, ifindex); +} + +/** + * nm_platform_link_set_arp: + * @self: platform instance + * @ifindex: Interface index + * + * Enable ARP on the interface. + */ +gboolean +nm_platform_link_set_arp(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + + _LOG3D("link: setting arp"); + return klass->link_set_arp(self, ifindex); +} + +/** + * nm_platform_link_set_noarp: + * @self: platform instance + * @ifindex: Interface index + * + * Disable ARP on the interface. + */ +gboolean +nm_platform_link_set_noarp(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + + _LOG3D("link: setting noarp"); + return klass->link_set_noarp(self, ifindex); +} + +/** + * nm_platform_link_set_mtu: + * @self: platform instance + * @ifindex: Interface index + * @mtu: The new MTU value + * + * Set interface MTU. + */ +int +nm_platform_link_set_mtu(NMPlatform *self, int ifindex, guint32 mtu) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + g_return_val_if_fail(mtu > 0, FALSE); + + _LOG3D("link: setting mtu %" G_GUINT32_FORMAT, mtu); + return klass->link_set_mtu(self, ifindex, mtu); +} + +/** + * nm_platform_link_get_mtu: + * @self: platform instance + * @ifindex: Interface index + * + * Returns: MTU value for the interface or 0 on error. + */ +guint32 +nm_platform_link_get_mtu(NMPlatform *self, int ifindex) +{ + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get(self, ifindex); + return pllink ? pllink->mtu : 0; +} + +/** + * nm_platform_link_set_name: + * @self: platform instance + * @ifindex: Interface index + * @name: The new interface name + * + * Set interface name. + */ +gboolean +nm_platform_link_set_name(NMPlatform *self, int ifindex, const char *name) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + g_return_val_if_fail(name, FALSE); + + _LOG3D("link: setting name %s", name); + + if (strlen(name) + 1 > IFNAMSIZ) + return FALSE; + + return klass->link_set_name(self, ifindex, name); +} + +/** + * nm_platform_link_get_physical_port_id: + * @self: platform instance + * @ifindex: Interface index + * + * The physical port ID, if present, indicates some unique identifier of + * the parent interface (eg, the physical port of which this link is a child). + * Two links that report the same physical port ID can be assumed to be + * children of the same physical port and may share resources that limit + * their abilities. + * + * Returns: physical port ID for the interface, or %NULL on error + * or if the interface has no physical port ID. + */ +char * +nm_platform_link_get_physical_port_id(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, NULL); + + g_return_val_if_fail(ifindex >= 0, NULL); + + if (klass->link_get_physical_port_id) + return klass->link_get_physical_port_id(self, ifindex); + return NULL; +} + +/** + * nm_platform_link_get_dev_id: + * @self: platform instance + * @ifindex: Interface index + * + * In contrast to the physical device ID (which indicates which parent a + * child has) the device ID differentiates sibling devices that may share + * the same MAC address. + * + * Returns: device ID for the interface, or 0 on error or if the + * interface has no device ID. + */ +guint +nm_platform_link_get_dev_id(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, 0); + + g_return_val_if_fail(ifindex >= 0, 0); + + if (klass->link_get_dev_id) + return klass->link_get_dev_id(self, ifindex); + return 0; +} + +/** + * nm_platform_link_get_wake_onlan: + * @self: platform instance + * @ifindex: Interface index + * + * Returns: the "Wake-on-LAN" status for @ifindex. + */ +gboolean +nm_platform_link_get_wake_on_lan(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + + if (klass->link_get_wake_on_lan) + return klass->link_get_wake_on_lan(self, ifindex); + return FALSE; +} + +/** + * nm_platform_link_get_driver_info: + * @self: platform instance + * @ifindex: Interface index + * @out_driver_name: (transfer full): on success, the driver name if available + * @out_driver_version: (transfer full): on success, the driver version if available + * @out_fw_version: (transfer full): on success, the firmware version if available + * + * Returns: %TRUE on success (though @out_driver_name, @out_driver_version and + * @out_fw_version can be %NULL if no information was available), %FALSE on + * failure. + */ +gboolean +nm_platform_link_get_driver_info(NMPlatform *self, + int ifindex, + char ** out_driver_name, + char ** out_driver_version, + char ** out_fw_version) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); + + return klass->link_get_driver_info(self, + ifindex, + out_driver_name, + out_driver_version, + out_fw_version); +} + +/** + * nm_platform_link_enslave: + * @self: platform instance + * @master: Interface index of the master + * @ifindex: Interface index of the slave + * + * Enslave @ifindex to @master. + */ +gboolean +nm_platform_link_enslave(NMPlatform *self, int master, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(master > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + + _LOG3D("link: enslaving to master '%s'", nm_platform_link_get_name(self, master)); + return klass->link_enslave(self, master, ifindex); +} + +/** + * nm_platform_link_release: + * @self: platform instance + * @master: Interface index of the master + * @ifindex: Interface index of the slave + * + * Release @slave from @master. + */ +gboolean +nm_platform_link_release(NMPlatform *self, int master, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(master > 0, FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + + if (nm_platform_link_get_master(self, ifindex) != master) + return FALSE; + + _LOG3D("link: releasing from master '%s'", nm_platform_link_get_name(self, master)); + return klass->link_release(self, master, ifindex); +} + +/** + * nm_platform_link_get_master: + * @self: platform instance + * @slave: Interface index of the slave. + * + * Returns: Interface index of the slave's master. + */ +int +nm_platform_link_get_master(NMPlatform *self, int slave) +{ + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get(self, slave); + return pllink ? pllink->master : 0; +} + +/*****************************************************************************/ + +gboolean +nm_platform_link_can_assume(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + if (klass->link_can_assume) + return klass->link_can_assume(self, ifindex); + g_return_val_if_reached(FALSE); +} + +/*****************************************************************************/ + +/** + * nm_platform_link_get_lnk: + * @self: the platform instance + * @ifindex: the link ifindex to lookup + * @link_type: filter by link-type. + * @out_link: (allow-none): returns the platform link instance + * + * If the function returns %NULL, that could mean that no such ifindex + * exists, of that the link has no lnk data. You can find that out + * by checking @out_link. @out_link will always be set if a link + * with @ifindex exists. + * + * If @link_type is %NM_LINK_TYPE_NONE, the function returns the lnk + * object if it is present. If you set link-type, you can be sure + * that only a link type of the matching type is returned (or %NULL). + * + * Returns: the internal link lnk object. The returned object + * is owned by the platform cache and must not be modified. Note + * however, that the object is guaranteed to be immutable, so + * you can safely take a reference and keep it for yourself + * (but don't modify it). + */ +const NMPObject * +nm_platform_link_get_lnk(NMPlatform * self, + int ifindex, + NMLinkType link_type, + const NMPlatformLink **out_link) +{ + const NMPObject *obj; + + obj = nm_platform_link_get_obj(self, ifindex, TRUE); + if (!obj) { + NM_SET_OUT(out_link, NULL); + return NULL; + } + + NM_SET_OUT(out_link, &obj->link); + + if (!obj->_link.netlink.lnk) + return NULL; + if (link_type != NM_LINK_TYPE_NONE + && (link_type != obj->link.type + || link_type != NMP_OBJECT_GET_CLASS(obj->_link.netlink.lnk)->lnk_link_type)) + return NULL; + + return obj->_link.netlink.lnk; +} + +static gconstpointer +_link_get_lnk(NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link) +{ + const NMPObject *lnk; + + lnk = nm_platform_link_get_lnk(self, ifindex, link_type, out_link); + return lnk ? &lnk->object : NULL; +} + +const NMPlatformLnkBridge * +nm_platform_link_get_lnk_bridge(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_BRIDGE, out_link); +} + +const NMPlatformLnkGre * +nm_platform_link_get_lnk_gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_GRE, out_link); +} + +const NMPlatformLnkGre * +nm_platform_link_get_lnk_gretap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_GRETAP, out_link); +} + +const NMPlatformLnkInfiniband * +nm_platform_link_get_lnk_infiniband(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_INFINIBAND, out_link); +} + +const NMPlatformLnkIp6Tnl * +nm_platform_link_get_lnk_ip6tnl(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IP6TNL, out_link); +} + +const NMPlatformLnkIp6Tnl * +nm_platform_link_get_lnk_ip6gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IP6GRE, out_link); +} + +const NMPlatformLnkIp6Tnl * +nm_platform_link_get_lnk_ip6gretap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IP6GRETAP, out_link); +} + +const NMPlatformLnkIpIp * +nm_platform_link_get_lnk_ipip(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IPIP, out_link); +} + +const NMPlatformLnkMacsec * +nm_platform_link_get_lnk_macsec(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_MACSEC, out_link); +} + +const NMPlatformLnkMacvlan * +nm_platform_link_get_lnk_macvlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_MACVLAN, out_link); +} + +const NMPlatformLnkMacvlan * +nm_platform_link_get_lnk_macvtap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_MACVTAP, out_link); +} + +const NMPlatformLnkSit * +nm_platform_link_get_lnk_sit(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_SIT, out_link); +} + +const NMPlatformLnkTun * +nm_platform_link_get_lnk_tun(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_TUN, out_link); +} + +const NMPlatformLnkVlan * +nm_platform_link_get_lnk_vlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VLAN, out_link); +} + +const NMPlatformLnkVrf * +nm_platform_link_get_lnk_vrf(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VRF, out_link); +} + +const NMPlatformLnkVxlan * +nm_platform_link_get_lnk_vxlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VXLAN, out_link); +} + +const NMPlatformLnkWireGuard * +nm_platform_link_get_lnk_wireguard(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_WIREGUARD, out_link); +} + +/*****************************************************************************/ + +static NM_UTILS_FLAGS2STR_DEFINE( + _wireguard_change_flags_to_string, + NMPlatformWireGuardChangeFlags, + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_NONE, "none"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_REPLACE_PEERS, "replace-peers"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY, "has-private-key"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_LISTEN_PORT, "has-listen-port"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK, "has-fwmark"), ); + +static NM_UTILS_FLAGS2STR_DEFINE( + _wireguard_change_peer_flags_to_string, + NMPlatformWireGuardChangePeerFlags, + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_NONE, "none"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REMOVE_ME, "remove"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_PRESHARED_KEY, "psk"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_KEEPALIVE_INTERVAL, "ka"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ENDPOINT, "ep"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ALLOWEDIPS, "aips"), + NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REPLACE_ALLOWEDIPS, "remove-aips"), ); + +int +nm_platform_link_wireguard_change(NMPlatform * self, + int ifindex, + const NMPlatformLnkWireGuard * lnk_wireguard, + const NMPWireGuardPeer * peers, + const NMPlatformWireGuardChangePeerFlags *peer_flags, + guint peers_len, + NMPlatformWireGuardChangeFlags change_flags) +{ + _CHECK_SELF(self, klass, -NME_BUG); + + nm_assert(klass->link_wireguard_change); + + if (_LOGD_ENABLED()) { + char buf_lnk[256]; + char buf_peers[512]; + char buf_change_flags[100]; + + buf_peers[0] = '\0'; + if (peers_len > 0) { + char *b = buf_peers; + gsize len = sizeof(buf_peers); + guint i; + + nm_utils_strbuf_append_str(&b, &len, " { "); + for (i = 0; i < peers_len; i++) { + nm_utils_strbuf_append_str(&b, &len, " { "); + nm_platform_wireguard_peer_to_string(&peers[i], b, len); + nm_utils_strbuf_seek_end(&b, &len); + if (peer_flags) { + nm_utils_strbuf_append( + &b, + &len, + " (%s)", + _wireguard_change_peer_flags_to_string(peer_flags[i], + buf_change_flags, + sizeof(buf_change_flags))); + } + nm_utils_strbuf_append_str(&b, &len, " } "); + } + nm_utils_strbuf_append_str(&b, &len, "}"); + } + + _LOG3D("link: change wireguard ifindex %d, %s, (%s), %u peers%s", + ifindex, + nm_platform_lnk_wireguard_to_string(lnk_wireguard, buf_lnk, sizeof(buf_lnk)), + _wireguard_change_flags_to_string(change_flags, + buf_change_flags, + sizeof(buf_change_flags)), + peers_len, + buf_peers); + } + + return klass->link_wireguard_change(self, + ifindex, + lnk_wireguard, + peers, + peer_flags, + peers_len, + change_flags); +} + +/*****************************************************************************/ + +/** + * nm_platform_link_tun_add: + * @self: platform instance + * @name: new interface name + * @tap: whether the interface is a TAP + * @owner: interface owner or -1 + * @group: interface group or -1 + * @pi: whether to clear the IFF_NO_PI flag + * @vnet_hdr: whether to set the IFF_VNET_HDR flag + * @multi_queue: whether to set the IFF_MULTI_QUEUE flag + * @out_link: on success, the link object + * @out_fd: (allow-none): if give, return the file descriptor for the + * created device. Note that when creating a non-persistent device, + * this argument is mandatory, otherwise it makes no sense + * to create such an interface. + * The caller is responsible for closing this file descriptor. + * + * Create a TUN or TAP interface. + */ +int +nm_platform_link_tun_add(NMPlatform * self, + const char * name, + const NMPlatformLnkTun *props, + const NMPlatformLink ** out_link, + int * out_fd) +{ + char b[255]; + int r; + + _CHECK_SELF(self, klass, -NME_BUG); + + g_return_val_if_fail(name, -NME_BUG); + g_return_val_if_fail(props, -NME_BUG); + g_return_val_if_fail(NM_IN_SET(props->type, IFF_TUN, IFF_TAP), -NME_BUG); + + /* creating a non-persistent device requires that the caller handles + * the file descriptor. */ + g_return_val_if_fail(props->persist || out_fd, -NME_BUG); + + NM_SET_OUT(out_fd, -1); + + r = _link_add_check_existing(self, name, NM_LINK_TYPE_TUN, out_link); + if (r < 0) + return r; + + _LOG2D("link: adding link %s", nm_platform_lnk_tun_to_string(props, b, sizeof(b))); + + if (!klass->link_tun_add(self, name, props, out_link, out_fd)) + return -NME_UNSPEC; + return 0; +} + +gboolean +nm_platform_link_6lowpan_get_properties(NMPlatform *self, int ifindex, int *out_parent) +{ + const NMPlatformLink *plink; + + plink = nm_platform_link_get(self, ifindex); + if (!plink) + return FALSE; + + if (plink->type != NM_LINK_TYPE_6LOWPAN) + return FALSE; + + if (plink->parent != 0) { + NM_SET_OUT(out_parent, plink->parent); + return TRUE; + } + + /* As of 4.16 kernel does not expose the peer_ifindex as IFA_LINK. + * Find the WPAN device with the same MAC address. */ + if (out_parent) { + const NMPlatformLink *parent_plink; + + parent_plink = nm_platform_link_get_by_address(self, + NM_LINK_TYPE_WPAN, + plink->l_address.data, + plink->l_address.len); + NM_SET_OUT(out_parent, parent_plink ? parent_plink->ifindex : -1); + } + + return TRUE; +} + +/*****************************************************************************/ + +static gboolean +link_set_option(NMPlatform *self, + int ifindex, + const char *category, + const char *option, + const char *value) +{ + nm_auto_close int dirfd = -1; + char ifname_verified[IFNAMSIZ]; + const char * path; + + if (!category || !option) + return FALSE; + + dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname_verified); + if (dirfd < 0) + return FALSE; + + path = + nm_sprintf_buf_unsafe_a(strlen(category) + strlen(option) + 2, "%s/%s", category, option); + return nm_platform_sysctl_set(self, + NMP_SYSCTL_PATHID_NETDIR_unsafe(dirfd, ifname_verified, path), + value); +} + +static char * +link_get_option(NMPlatform *self, int ifindex, const char *category, const char *option) +{ + nm_auto_close int dirfd = -1; + char ifname_verified[IFNAMSIZ]; + const char * path; + + if (!category || !option) + return NULL; + + dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname_verified); + if (dirfd < 0) + return NULL; + + path = + nm_sprintf_buf_unsafe_a(strlen(category) + strlen(option) + 2, "%s/%s", category, option); + return nm_platform_sysctl_get(self, + NMP_SYSCTL_PATHID_NETDIR_unsafe(dirfd, ifname_verified, path)); +} + +static const char * +master_category(NMPlatform *self, int master) +{ + switch (nm_platform_link_get_type(self, master)) { + case NM_LINK_TYPE_BRIDGE: + return "bridge"; + case NM_LINK_TYPE_BOND: + return "bonding"; + default: + return NULL; + } +} + +static const char * +slave_category(NMPlatform *self, int slave) +{ + int master = nm_platform_link_get_master(self, slave); + + if (master <= 0) + return NULL; + + switch (nm_platform_link_get_type(self, master)) { + case NM_LINK_TYPE_BRIDGE: + return "brport"; + default: + return NULL; + } +} + +gboolean +nm_platform_sysctl_master_set_option(NMPlatform *self, + int ifindex, + const char *option, + const char *value) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(option, FALSE); + g_return_val_if_fail(value, FALSE); + + return link_set_option(self, ifindex, master_category(self, ifindex), option, value); +} + +char * +nm_platform_sysctl_master_get_option(NMPlatform *self, int ifindex, const char *option) +{ + _CHECK_SELF(self, klass, NULL); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(option, FALSE); + + return link_get_option(self, ifindex, master_category(self, ifindex), option); +} + +gboolean +nm_platform_sysctl_slave_set_option(NMPlatform *self, + int ifindex, + const char *option, + const char *value) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(option, FALSE); + g_return_val_if_fail(value, FALSE); + + return link_set_option(self, ifindex, slave_category(self, ifindex), option, value); +} + +char * +nm_platform_sysctl_slave_get_option(NMPlatform *self, int ifindex, const char *option) +{ + _CHECK_SELF(self, klass, NULL); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(option, FALSE); + + return link_get_option(self, ifindex, slave_category(self, ifindex), option); +} + +/*****************************************************************************/ + +gboolean +nm_platform_link_vlan_change(NMPlatform * self, + int ifindex, + _NMVlanFlags flags_mask, + _NMVlanFlags flags_set, + gboolean ingress_reset_all, + const NMVlanQosMapping *ingress_map, + gsize n_ingress_map, + gboolean egress_reset_all, + const NMVlanQosMapping *egress_map, + gsize n_egress_map) +{ + _CHECK_SELF(self, klass, FALSE); + + nm_assert(klass->link_vlan_change); + + g_return_val_if_fail(!n_ingress_map || ingress_map, FALSE); + g_return_val_if_fail(!n_egress_map || egress_map, FALSE); + + flags_set &= flags_mask; + + if (_LOGD_ENABLED()) { + char buf[512]; + char *b = buf; + gsize len, i; + + b[0] = '\0'; + len = sizeof(buf); + + if (flags_mask) + nm_utils_strbuf_append(&b, + &len, + " flags 0x%x/0x%x", + (unsigned) flags_set, + (unsigned) flags_mask); + + if (ingress_reset_all || n_ingress_map) { + nm_utils_strbuf_append_str(&b, &len, " ingress-qos-map"); + nm_platform_vlan_qos_mapping_to_string("", ingress_map, n_ingress_map, b, len); + i = strlen(b); + b += i; + len -= i; + if (ingress_reset_all) + nm_utils_strbuf_append_str(&b, &len, " (reset-all)"); + } + + if (egress_reset_all || n_egress_map) { + nm_utils_strbuf_append_str(&b, &len, " egress-qos-map"); + nm_platform_vlan_qos_mapping_to_string("", egress_map, n_egress_map, b, len); + i = strlen(b); + b += i; + len -= i; + if (egress_reset_all) + nm_utils_strbuf_append_str(&b, &len, " (reset-all)"); + } + + _LOG3D("link: change vlan %s", buf); + } + return klass->link_vlan_change(self, + ifindex, + flags_mask, + flags_set, + ingress_reset_all, + ingress_map, + n_ingress_map, + egress_reset_all, + egress_map, + n_egress_map); +} + +gboolean +nm_platform_link_vlan_set_ingress_map(NMPlatform *self, int ifindex, int from, int to) +{ + NMVlanQosMapping map = { + .from = from, + .to = to, + }; + + return nm_platform_link_vlan_change(self, ifindex, 0, 0, FALSE, &map, 1, FALSE, NULL, 0); +} + +gboolean +nm_platform_link_vlan_set_egress_map(NMPlatform *self, int ifindex, int from, int to) +{ + NMVlanQosMapping map = { + .from = from, + .to = to, + }; + + return nm_platform_link_vlan_change(self, ifindex, 0, 0, FALSE, NULL, 0, FALSE, &map, 1); +} + +static int +_infiniband_add_add_or_delete(NMPlatform * self, + int ifindex, + int p_key, + gboolean add, + const NMPlatformLink **out_link) +{ + char name[IFNAMSIZ]; + const NMPlatformLink *parent_link; + int r; + + _CHECK_SELF(self, klass, -NME_BUG); + + g_return_val_if_fail(ifindex >= 0, -NME_BUG); + g_return_val_if_fail(p_key >= 0 && p_key <= 0xffff, -NME_BUG); + + /* the special keys 0x0000 and 0x8000 are not allowed. */ + if (NM_IN_SET(p_key, 0, 0x8000)) + return -NME_UNSPEC; + + parent_link = nm_platform_link_get(self, ifindex); + if (!parent_link) + return -NME_PL_NOT_FOUND; + + if (parent_link->type != NM_LINK_TYPE_INFINIBAND) + return -NME_PL_WRONG_TYPE; + + nmp_utils_new_infiniband_name(name, parent_link->name, p_key); + + if (add) { + r = _link_add_check_existing(self, name, NM_LINK_TYPE_INFINIBAND, out_link); + if (r < 0) + return r; + + _LOG3D("link: adding infiniband partition %s, key %d", name, p_key); + if (!klass->infiniband_partition_add(self, ifindex, p_key, out_link)) + return -NME_UNSPEC; + } else { + _LOG3D("link: deleting infiniband partition %s, key %d", name, p_key); + + if (!klass->infiniband_partition_delete(self, ifindex, p_key)) + return -NME_UNSPEC; + } + + return 0; +} + +int +nm_platform_link_infiniband_add(NMPlatform * self, + int parent, + int p_key, + const NMPlatformLink **out_link) +{ + return _infiniband_add_add_or_delete(self, parent, p_key, TRUE, out_link); +} + +int +nm_platform_link_infiniband_delete(NMPlatform *self, int parent, int p_key) +{ + return _infiniband_add_add_or_delete(self, parent, p_key, FALSE, NULL); +} + +gboolean +nm_platform_link_infiniband_get_properties(NMPlatform * self, + int ifindex, + int * out_parent, + int * out_p_key, + const char **out_mode) +{ + nm_auto_close int dirfd = -1; + char ifname_verified[IFNAMSIZ]; + const NMPlatformLnkInfiniband *plnk; + const NMPlatformLink * plink; + char * contents; + const char * mode; + int p_key = 0; + + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + plnk = nm_platform_link_get_lnk_infiniband(self, ifindex, &plink); + + if (!plink || plink->type != NM_LINK_TYPE_INFINIBAND) + return FALSE; + + if (plnk) { + NM_SET_OUT(out_parent, plink->parent); + NM_SET_OUT(out_p_key, plnk->p_key); + NM_SET_OUT(out_mode, plnk->mode); + return TRUE; + } + + /* Could not get the link information via netlink. To support older kernels, + * fallback to reading sysfs. */ + + dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname_verified); + if (dirfd < 0) + return FALSE; + + contents = + nm_platform_sysctl_get(self, NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname_verified, "mode")); + if (!contents) + return FALSE; + if (strstr(contents, "datagram")) + mode = "datagram"; + else if (strstr(contents, "connected")) + mode = "connected"; + else + mode = NULL; + g_free(contents); + + p_key = + nm_platform_sysctl_get_int_checked(self, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname_verified, "pkey"), + 16, + 0, + 0xFFFF, + -1); + if (p_key < 0) + return FALSE; + + NM_SET_OUT(out_parent, plink->parent); + NM_SET_OUT(out_p_key, p_key); + NM_SET_OUT(out_mode, mode); + return TRUE; +} + +gboolean +nm_platform_link_veth_get_properties(NMPlatform *self, int ifindex, int *out_peer_ifindex) +{ + const NMPlatformLink *plink; + int peer_ifindex; + + plink = nm_platform_link_get(self, ifindex); + if (!plink) + return FALSE; + + if (plink->type != NM_LINK_TYPE_VETH) + return FALSE; + + if (plink->parent != 0) { + NM_SET_OUT(out_peer_ifindex, plink->parent); + return TRUE; + } + + /* Pre-4.1 kernel did not expose the peer_ifindex as IFA_LINK. Lookup via ethtool. */ + if (out_peer_ifindex) { + nm_auto_pop_netns NMPNetns *netns = NULL; + + if (!nm_platform_netns_push(self, &netns)) + return FALSE; + peer_ifindex = nmp_utils_ethtool_get_peer_ifindex(plink->ifindex); + if (peer_ifindex <= 0) + return FALSE; + + *out_peer_ifindex = peer_ifindex; + } + return TRUE; +} + +/** + * nm_platform_link_tun_get_properties: + * @self: the #NMPlatform instance + * @ifindex: the ifindex to look up + * @out_properties: (out) (allow-none): return the read properties + * + * Only recent versions of kernel export tun properties via netlink. + * So, if that's the case, then we have the NMPlatformLnkTun instance + * in the platform cache ready to return. Otherwise, this function + * falls back reading sysctl to obtain the tun properties. That + * is racy, because querying sysctl means that the object might + * be already removed from cache (while NM didn't yet process the + * netlink message). + * + * Hence, to lookup the tun properties, you always need to use this + * function, and use it with care knowing that it might obtain its + * data by reading sysctl. Note that we don't want to add this workaround + * to the platform cache itself, because the cache should (mainly) + * contain data from netlink. To access the sysctl side channel, the + * user needs to do explicitly. + * + * Returns: #TRUE, if the properties could be read. */ +gboolean +nm_platform_link_tun_get_properties(NMPlatform *self, int ifindex, NMPlatformLnkTun *out_properties) +{ + const NMPObject *plobj; + const NMPObject *pllnk; + char ifname[IFNAMSIZ]; + gint64 owner; + gint64 group; + gint64 flags; + + /* we consider also invisible links (those that are not yet in udev). */ + plobj = nm_platform_link_get_obj(self, ifindex, FALSE); + if (!plobj) + return FALSE; + + if (NMP_OBJECT_CAST_LINK(plobj)->type != NM_LINK_TYPE_TUN) + return FALSE; + + pllnk = plobj->_link.netlink.lnk; + if (pllnk) { + nm_assert(NMP_OBJECT_GET_TYPE(pllnk) == NMP_OBJECT_TYPE_LNK_TUN); + nm_assert(NMP_OBJECT_GET_CLASS(pllnk)->lnk_link_type == NM_LINK_TYPE_TUN); + + /* recent kernels expose tun properties via netlink and thus we have them + * in the platform cache. */ + NM_SET_OUT(out_properties, pllnk->lnk_tun); + return TRUE; + } + + /* fallback to reading sysctl. */ + { + nm_auto_close int dirfd = -1; + + dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname); + if (dirfd < 0) + return FALSE; + + owner = nm_platform_sysctl_get_int_checked(self, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "owner"), + 10, + -1, + G_MAXUINT32, + -2); + if (owner == -2) + return FALSE; + + group = nm_platform_sysctl_get_int_checked(self, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "group"), + 10, + -1, + G_MAXUINT32, + -2); + if (group == -2) + return FALSE; + + flags = + nm_platform_sysctl_get_int_checked(self, + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, "tun_flags"), + 16, + 0, + G_MAXINT64, + -1); + if (flags == -1) + return FALSE; + } + + if (out_properties) { + memset(out_properties, 0, sizeof(*out_properties)); + if (owner != -1) { + out_properties->owner_valid = TRUE; + out_properties->owner = owner; + } + if (group != -1) { + out_properties->group_valid = TRUE; + out_properties->group = group; + } + out_properties->type = (flags & TUN_TYPE_MASK); + out_properties->pi = !(flags & IFF_NO_PI); + out_properties->vnet_hdr = !!(flags & IFF_VNET_HDR); + out_properties->multi_queue = !!(flags & NM_IFF_MULTI_QUEUE); + out_properties->persist = !!(flags & IFF_PERSIST); + } + return TRUE; +} + +gboolean +nm_platform_wifi_get_capabilities(NMPlatform *self, int ifindex, _NMDeviceWifiCapabilities *caps) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return klass->wifi_get_capabilities(self, ifindex, caps); +} + +guint32 +nm_platform_wifi_get_frequency(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, 0); + + g_return_val_if_fail(ifindex > 0, 0); + + return klass->wifi_get_frequency(self, ifindex); +} + +gboolean +nm_platform_wifi_get_station(NMPlatform * self, + int ifindex, + NMEtherAddr *out_bssid, + int * out_quality, + guint32 * out_rate) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return klass->wifi_get_station(self, ifindex, out_bssid, out_quality, out_rate); +} + +_NM80211Mode +nm_platform_wifi_get_mode(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, _NM_802_11_MODE_UNKNOWN); + + g_return_val_if_fail(ifindex > 0, _NM_802_11_MODE_UNKNOWN); + + return klass->wifi_get_mode(self, ifindex); +} + +void +nm_platform_wifi_set_mode(NMPlatform *self, int ifindex, _NM80211Mode mode) +{ + _CHECK_SELF_VOID(self, klass); + + g_return_if_fail(ifindex > 0); + + klass->wifi_set_mode(self, ifindex, mode); +} + +static void +wifi_set_powersave(NMPlatform *p, int ifindex, guint32 powersave) +{ + /* empty */ +} + +void +nm_platform_wifi_set_powersave(NMPlatform *self, int ifindex, guint32 powersave) +{ + _CHECK_SELF_VOID(self, klass); + + g_return_if_fail(ifindex > 0); + + klass->wifi_set_powersave(self, ifindex, powersave); +} + +guint32 +nm_platform_wifi_find_frequency(NMPlatform *self, int ifindex, const guint32 *freqs) +{ + _CHECK_SELF(self, klass, 0); + + g_return_val_if_fail(ifindex > 0, 0); + g_return_val_if_fail(freqs != NULL, 0); + + return klass->wifi_find_frequency(self, ifindex, freqs); +} + +void +nm_platform_wifi_indicate_addressing_running(NMPlatform *self, int ifindex, gboolean running) +{ + _CHECK_SELF_VOID(self, klass); + + g_return_if_fail(ifindex > 0); + + klass->wifi_indicate_addressing_running(self, ifindex, running); +} + +_NMSettingWirelessWakeOnWLan +nm_platform_wifi_get_wake_on_wlan(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return klass->wifi_get_wake_on_wlan(self, ifindex); +} + +gboolean +nm_platform_wifi_set_wake_on_wlan(NMPlatform *self, int ifindex, _NMSettingWirelessWakeOnWLan wowl) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return klass->wifi_set_wake_on_wlan(self, ifindex, wowl); +} + +guint32 +nm_platform_mesh_get_channel(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, 0); + + g_return_val_if_fail(ifindex > 0, 0); + + return klass->mesh_get_channel(self, ifindex); +} + +gboolean +nm_platform_mesh_set_channel(NMPlatform *self, int ifindex, guint32 channel) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return klass->mesh_set_channel(self, ifindex, channel); +} + +gboolean +nm_platform_mesh_set_ssid(NMPlatform *self, int ifindex, const guint8 *ssid, gsize len) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(ssid != NULL, FALSE); + + return klass->mesh_set_ssid(self, ifindex, ssid, len); +} + +guint16 +nm_platform_wpan_get_pan_id(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return klass->wpan_get_pan_id(self, ifindex); +} + +gboolean +nm_platform_wpan_set_pan_id(NMPlatform *self, int ifindex, guint16 pan_id) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return klass->wpan_set_pan_id(self, ifindex, pan_id); +} + +guint16 +nm_platform_wpan_get_short_addr(NMPlatform *self, int ifindex) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return klass->wpan_get_short_addr(self, ifindex); +} + +gboolean +nm_platform_wpan_set_short_addr(NMPlatform *self, int ifindex, guint16 short_addr) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return klass->wpan_set_short_addr(self, ifindex, short_addr); +} + +gboolean +nm_platform_wpan_set_channel(NMPlatform *self, int ifindex, guint8 page, guint8 channel) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return klass->wpan_set_channel(self, ifindex, page, channel); +} + +#define TO_STRING_DEV_BUF_SIZE (5 + 15 + 1) +static const char * +_to_string_dev(NMPlatform *self, int ifindex, char *buf, size_t size) +{ + g_assert(buf && size >= TO_STRING_DEV_BUF_SIZE); + + if (ifindex) { + const char *name = ifindex > 0 && self ? nm_platform_link_get_name(self, ifindex) : NULL; + char * buf2; + + strcpy(buf, " dev "); + buf2 = buf + 5; + size -= 5; + + if (name) + g_strlcpy(buf2, name, size); + else + g_snprintf(buf2, size, "%d", ifindex); + } else + buf[0] = 0; + + return buf; +} + +#define TO_STRING_IFA_FLAGS_BUF_SIZE 256 + +static const char * +_to_string_ifa_flags(guint32 ifa_flags, char *buf, gsize size) +{ +#define S_FLAGS_PREFIX " flags " + nm_assert(buf && size >= TO_STRING_IFA_FLAGS_BUF_SIZE && size > NM_STRLEN(S_FLAGS_PREFIX)); + + if (!ifa_flags) + buf[0] = '\0'; + else { + nm_platform_addr_flags2str(ifa_flags, + &buf[NM_STRLEN(S_FLAGS_PREFIX)], + size - NM_STRLEN(S_FLAGS_PREFIX)); + if (buf[NM_STRLEN(S_FLAGS_PREFIX)] == '\0') + buf[0] = '\0'; + else + memcpy(buf, S_FLAGS_PREFIX, NM_STRLEN(S_FLAGS_PREFIX)); + } + return buf; +} + +/*****************************************************************************/ + +gboolean +nm_platform_ethtool_set_wake_on_lan(NMPlatform * self, + int ifindex, + _NMSettingWiredWakeOnLan wol, + const char * wol_password) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return nmp_utils_ethtool_set_wake_on_lan(ifindex, wol, wol_password); +} + +gboolean +nm_platform_ethtool_set_link_settings(NMPlatform * self, + int ifindex, + gboolean autoneg, + guint32 speed, + NMPlatformLinkDuplexType duplex) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return nmp_utils_ethtool_set_link_settings(ifindex, autoneg, speed, duplex); +} + +gboolean +nm_platform_ethtool_get_link_settings(NMPlatform * self, + int ifindex, + gboolean * out_autoneg, + guint32 * out_speed, + NMPlatformLinkDuplexType *out_duplex) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return nmp_utils_ethtool_get_link_settings(ifindex, out_autoneg, out_speed, out_duplex); +} + +/*****************************************************************************/ + +NMEthtoolFeatureStates * +nm_platform_ethtool_get_link_features(NMPlatform *self, int ifindex) +{ + _CHECK_SELF_NETNS(self, klass, netns, NULL); + + g_return_val_if_fail(ifindex > 0, NULL); + + return nmp_utils_ethtool_get_features(ifindex); +} + +gboolean +nm_platform_ethtool_set_features( + NMPlatform * self, + int ifindex, + const NMEthtoolFeatureStates *features, + const NMOptionBool *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, + gboolean do_set /* or reset */) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return nmp_utils_ethtool_set_features(ifindex, features, requested, do_set); +} + +gboolean +nm_platform_ethtool_get_link_coalesce(NMPlatform * self, + int ifindex, + NMEthtoolCoalesceState *coalesce) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(coalesce, FALSE); + + return nmp_utils_ethtool_get_coalesce(ifindex, coalesce); +} + +gboolean +nm_platform_ethtool_set_coalesce(NMPlatform * self, + int ifindex, + const NMEthtoolCoalesceState *coalesce) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return nmp_utils_ethtool_set_coalesce(ifindex, coalesce); +} + +gboolean +nm_platform_ethtool_get_link_ring(NMPlatform *self, int ifindex, NMEthtoolRingState *ring) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(ring, FALSE); + + return nmp_utils_ethtool_get_ring(ifindex, ring); +} + +gboolean +nm_platform_ethtool_set_ring(NMPlatform *self, int ifindex, const NMEthtoolRingState *ring) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return nmp_utils_ethtool_set_ring(ifindex, ring); +} + +/*****************************************************************************/ + +const NMDedupMultiHeadEntry * +nm_platform_lookup_all(NMPlatform *self, NMPCacheIdType cache_id_type, const NMPObject *obj) +{ + return nmp_cache_lookup_all(nm_platform_get_cache(self), cache_id_type, obj); +} + +const NMDedupMultiEntry * +nm_platform_lookup_entry(NMPlatform *self, NMPCacheIdType cache_id_type, const NMPObject *obj) +{ + return nmp_cache_lookup_entry_with_idx_type(nm_platform_get_cache(self), cache_id_type, obj); +} + +const NMDedupMultiHeadEntry * +nm_platform_lookup(NMPlatform *self, const NMPLookup *lookup) +{ + return nmp_cache_lookup(nm_platform_get_cache(self), lookup); +} + +gboolean +nm_platform_lookup_predicate_routes_main(const NMPObject *obj, gpointer user_data) +{ + nm_assert( + NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); + return nm_platform_route_table_is_main( + nm_platform_ip_route_get_effective_table(&obj->ip_route)); +} + +gboolean +nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel(const NMPObject *obj, + gpointer user_data) +{ + nm_assert( + NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); + return nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&obj->ip_route)) + && obj->ip_route.rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL; +} + +/** + * nm_platform_lookup_clone: + * @self: + * @lookup: + * @predicate: if given, only objects for which @predicate returns %TRUE are included + * in the result. + * @user_data: user data for @predicate + * + * Returns the result of lookup in a GPtrArray. The result array contains + * references objects from the cache, its destroy function will unref them. + * + * The user must unref the GPtrArray, which will also unref the NMPObject + * elements. + * + * The elements in the array *must* not be modified. + * + * Returns: the result of the lookup. + */ +GPtrArray * +nm_platform_lookup_clone(NMPlatform * self, + const NMPLookup * lookup, + NMPObjectPredicateFunc predicate, + gpointer user_data) +{ + return nm_dedup_multi_objs_to_ptr_array_head(nm_platform_lookup(self, lookup), + (NMDedupMultiFcnSelectPredicate) predicate, + user_data); +} + +void +nm_platform_ip4_address_set_addr(NMPlatformIP4Address *addr, in_addr_t address, guint8 plen) +{ + nm_assert(plen <= 32); + + addr->address = address; + addr->peer_address = address; + addr->plen = plen; +} + +const struct in6_addr * +nm_platform_ip6_address_get_peer(const NMPlatformIP6Address *addr) +{ + if (IN6_IS_ADDR_UNSPECIFIED(&addr->peer_address) + || IN6_ARE_ADDR_EQUAL(&addr->peer_address, &addr->address)) + return &addr->address; + return &addr->peer_address; +} + +gboolean +nm_platform_ip6_address_match(const NMPlatformIP6Address *addr, NMPlatformMatchFlags match_flag) +{ + nm_assert(!NM_FLAGS_ANY( + match_flag, + ~(NM_PLATFORM_MATCH_WITH_ADDRTYPE__ANY | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY))); + nm_assert(NM_FLAGS_ANY(match_flag, NM_PLATFORM_MATCH_WITH_ADDRTYPE__ANY)); + nm_assert(NM_FLAGS_ANY(match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY)); + + if (IN6_IS_ADDR_LINKLOCAL(&addr->address)) { + if (!NM_FLAGS_HAS(match_flag, NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL)) + return FALSE; + } else { + if (!NM_FLAGS_HAS(match_flag, NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL)) + return FALSE; + } + + if (NM_FLAGS_HAS(addr->n_ifa_flags, IFA_F_DADFAILED)) { + if (!NM_FLAGS_HAS(match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE_DADFAILED)) + return FALSE; + } else if (NM_FLAGS_HAS(addr->n_ifa_flags, IFA_F_TENTATIVE) + && !NM_FLAGS_HAS(addr->n_ifa_flags, IFA_F_OPTIMISTIC)) { + if (!NM_FLAGS_HAS(match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE)) + return FALSE; + } else { + if (!NM_FLAGS_HAS(match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) + return FALSE; + } + + return TRUE; +} + +gboolean +nm_platform_ip4_address_add(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address, + in_addr_t broadcast_address, + guint32 lifetime, + guint32 preferred, + guint32 flags, + const char *label) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(plen <= 32, FALSE); + g_return_val_if_fail(lifetime > 0, FALSE); + g_return_val_if_fail(preferred <= lifetime, FALSE); + g_return_val_if_fail(!label || strlen(label) < sizeof(((NMPlatformIP4Address *) NULL)->label), + FALSE); + + if (_LOGD_ENABLED()) { + NMPlatformIP4Address addr; + + addr = (NMPlatformIP4Address){ + .ifindex = ifindex, + .address = address, + .peer_address = peer_address, + .plen = plen, + .timestamp = 0, /* set it at zero, which to_string will treat as *now* */ + .lifetime = lifetime, + .preferred = preferred, + .n_ifa_flags = flags, + .broadcast_address = broadcast_address, + .use_ip4_broadcast_address = TRUE, + }; + if (label) + g_strlcpy(addr.label, label, sizeof(addr.label)); + + _LOG3D("address: adding or updating IPv4 address: %s", + nm_platform_ip4_address_to_string(&addr, NULL, 0)); + } + return klass->ip4_address_add(self, + ifindex, + address, + plen, + peer_address, + broadcast_address, + lifetime, + preferred, + flags, + label); +} + +gboolean +nm_platform_ip6_address_add(NMPlatform * self, + int ifindex, + struct in6_addr address, + guint8 plen, + struct in6_addr peer_address, + guint32 lifetime, + guint32 preferred, + guint32 flags) +{ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(plen <= 128, FALSE); + g_return_val_if_fail(lifetime > 0, FALSE); + g_return_val_if_fail(preferred <= lifetime, FALSE); + + if (_LOGD_ENABLED()) { + NMPlatformIP6Address addr = {0}; + + addr.ifindex = ifindex; + addr.address = address; + addr.peer_address = peer_address; + addr.plen = plen; + addr.timestamp = 0; /* set it to zero, which to_string will treat as *now* */ + addr.lifetime = lifetime; + addr.preferred = preferred; + addr.n_ifa_flags = flags; + + _LOG3D("address: adding or updating IPv6 address: %s", + nm_platform_ip6_address_to_string(&addr, NULL, 0)); + } + return klass + ->ip6_address_add(self, ifindex, address, plen, peer_address, lifetime, preferred, flags); +} + +gboolean +nm_platform_ip4_address_delete(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address) +{ + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + char str_peer[INET_ADDRSTRLEN + 50]; + + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(plen <= 32, FALSE); + + _LOG3D("address: deleting IPv4 address %s/%d, %s%s", + _nm_utils_inet4_ntop(address, b1), + plen, + peer_address != address + ? nm_sprintf_buf(str_peer, "peer %s, ", _nm_utils_inet4_ntop(peer_address, b2)) + : "", + _to_string_dev(self, ifindex, str_dev, sizeof(str_dev))); + return klass->ip4_address_delete(self, ifindex, address, plen, peer_address); +} + +gboolean +nm_platform_ip6_address_delete(NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen) +{ + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(plen <= 128, FALSE); + + _LOG3D("address: deleting IPv6 address %s/%d, %s", + _nm_utils_inet6_ntop(&address, sbuf), + plen, + _to_string_dev(self, ifindex, str_dev, sizeof(str_dev))); + return klass->ip6_address_delete(self, ifindex, address, plen); +} + +const NMPlatformIP4Address * +nm_platform_ip4_address_get(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address) +{ + NMPObject obj_id; + const NMPObject *obj; + + _CHECK_SELF(self, klass, NULL); + + g_return_val_if_fail(plen <= 32, NULL); + + nmp_object_stackinit_id_ip4_address(&obj_id, ifindex, address, plen, peer_address); + obj = nmp_cache_lookup_obj(nm_platform_get_cache(self), &obj_id); + nm_assert(!obj || nmp_object_is_visible(obj)); + return NMP_OBJECT_CAST_IP4_ADDRESS(obj); +} + +const NMPlatformIP6Address * +nm_platform_ip6_address_get(NMPlatform *self, int ifindex, const struct in6_addr *address) +{ + NMPObject obj_id; + const NMPObject *obj; + + _CHECK_SELF(self, klass, NULL); + + nm_assert(address); + + nmp_object_stackinit_id_ip6_address(&obj_id, ifindex, address); + obj = nmp_cache_lookup_obj(nm_platform_get_cache(self), &obj_id); + nm_assert(!obj || nmp_object_is_visible(obj)); + return NMP_OBJECT_CAST_IP6_ADDRESS(obj); +} + +static gboolean +_addr_array_clean_expired(int addr_family, + int ifindex, + GPtrArray * array, + guint32 now, + GHashTable **idx) +{ + guint i; + gboolean any_addrs = FALSE; + + nm_assert_addr_family(addr_family); + nm_assert(ifindex > 0); + nm_assert(now > 0); + + if (!array) + return FALSE; + + /* remove all addresses that are already expired. */ + for (i = 0; i < array->len; i++) { + const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS(array->pdata[i]); + +#if NM_MORE_ASSERTS > 10 + nm_assert(a); + nm_assert(a->ifindex == ifindex); + { + const NMPObject *o = NMP_OBJECT_UP_CAST(a); + guint j; + + nm_assert(NMP_OBJECT_GET_CLASS(o)->addr_family == addr_family); + for (j = i + 1; j < array->len; j++) { + const NMPObject *o2 = array->pdata[j]; + + nm_assert(NMP_OBJECT_GET_TYPE(o) == NMP_OBJECT_GET_TYPE(o2)); + nm_assert(!nmp_object_id_equal(o, o2)); + } + } +#endif + + if (!NM_IS_IPv4(addr_family) && NM_FLAGS_HAS(a->n_ifa_flags, IFA_F_TEMPORARY)) { + /* temporary addresses are never added explicitly by NetworkManager but + * kernel adds them via mngtempaddr flag. + * + * We drop them from this list. */ + goto clear_and_next; + } + + if (!nmp_utils_lifetime_get(a->timestamp, a->lifetime, a->preferred, now, NULL)) + goto clear_and_next; + + if (idx) { + if (G_UNLIKELY(!*idx)) { + *idx = g_hash_table_new((GHashFunc) nmp_object_id_hash, + (GEqualFunc) nmp_object_id_equal); + } + if (!g_hash_table_add(*idx, (gpointer) NMP_OBJECT_UP_CAST(a))) + nm_assert_not_reached(); + } + any_addrs = TRUE; + continue; + +clear_and_next: + nmp_object_unref(g_steal_pointer(&array->pdata[i])); + } + + return any_addrs; +} + +static gboolean +ip4_addr_subnets_is_plain_address(const GPtrArray *addresses, gconstpointer needle) +{ + return needle >= (gconstpointer) &addresses->pdata[0] + && needle < (gconstpointer) &addresses->pdata[addresses->len]; +} + +static const NMPObject ** +ip4_addr_subnets_addr_list_get(const GPtrArray *addr_list, guint idx) +{ + nm_assert(addr_list); + nm_assert(addr_list->len > 1); + nm_assert(idx < addr_list->len); + nm_assert(addr_list->pdata[idx]); + nm_assert(!(*((gpointer *) addr_list->pdata[idx])) + || NMP_OBJECT_CAST_IP4_ADDRESS(*((gpointer *) addr_list->pdata[idx]))); + nm_assert(idx == 0 || ip4_addr_subnets_addr_list_get(addr_list, idx - 1)); + return addr_list->pdata[idx]; +} + +static void +ip4_addr_subnets_destroy_index(GHashTable *subnets, const GPtrArray *addresses) +{ + GHashTableIter iter; + gpointer p; + + if (!subnets) + return; + + g_hash_table_iter_init(&iter, subnets); + while (g_hash_table_iter_next(&iter, NULL, &p)) { + if (!ip4_addr_subnets_is_plain_address(addresses, p)) + g_ptr_array_free((GPtrArray *) p, TRUE); + } + + g_hash_table_unref(subnets); +} + +static GHashTable * +ip4_addr_subnets_build_index(const GPtrArray *addresses, + gboolean consider_flags, + gboolean full_index) +{ + GHashTable *subnets; + guint i; + + nm_assert(addresses && addresses->len); + + subnets = g_hash_table_new(nm_direct_hash, NULL); + + /* Build a hash table of all addresses per subnet */ + for (i = 0; i < addresses->len; i++) { + const NMPlatformIP4Address *address; + gpointer p_address; + GPtrArray * addr_list; + guint32 net; + int position; + gpointer p; + + if (!addresses->pdata[i]) + continue; + + p_address = &addresses->pdata[i]; + address = NMP_OBJECT_CAST_IP4_ADDRESS(addresses->pdata[i]); + + net = address->address & _nm_utils_ip4_prefix_to_netmask(address->plen); + if (!g_hash_table_lookup_extended(subnets, GUINT_TO_POINTER(net), NULL, &p)) { + g_hash_table_insert(subnets, GUINT_TO_POINTER(net), p_address); + continue; + } + nm_assert(p); + + if (full_index) { + if (ip4_addr_subnets_is_plain_address(addresses, p)) { + addr_list = g_ptr_array_new(); + g_hash_table_insert(subnets, GUINT_TO_POINTER(net), addr_list); + g_ptr_array_add(addr_list, p); + } else + addr_list = p; + + if (!consider_flags || NM_FLAGS_HAS(address->n_ifa_flags, IFA_F_SECONDARY)) + position = -1; /* append */ + else + position = 0; /* prepend */ + g_ptr_array_insert(addr_list, position, p_address); + } else { + /* we only care about the primary. No need to track the secondaries + * as a GPtrArray. */ + nm_assert(ip4_addr_subnets_is_plain_address(addresses, p)); + if (consider_flags && !NM_FLAGS_HAS(address->n_ifa_flags, IFA_F_SECONDARY)) { + g_hash_table_insert(subnets, GUINT_TO_POINTER(net), p_address); + } + } + } + + return subnets; +} + +/** + * ip4_addr_subnets_is_secondary: + * @address: an address + * @subnets: the hash table mapping subnets to addresses + * @addresses: array of addresses in the hash table + * @out_addr_list: array of addresses belonging to the same subnet + * + * Checks whether @address is secondary and returns in @out_addr_list the list of addresses + * belonging to the same subnet, if it contains other elements. + * + * Returns: %TRUE if the address is secondary, %FALSE otherwise + */ +static gboolean +ip4_addr_subnets_is_secondary(const NMPObject * address, + GHashTable * subnets, + const GPtrArray * addresses, + const GPtrArray **out_addr_list) +{ + const NMPlatformIP4Address *a; + const GPtrArray * addr_list; + gconstpointer p; + guint32 net; + const NMPObject ** o; + + a = NMP_OBJECT_CAST_IP4_ADDRESS(address); + + net = a->address & _nm_utils_ip4_prefix_to_netmask(a->plen); + p = g_hash_table_lookup(subnets, GUINT_TO_POINTER(net)); + nm_assert(p); + if (!ip4_addr_subnets_is_plain_address(addresses, p)) { + addr_list = p; + nm_assert(addr_list->len > 1); + NM_SET_OUT(out_addr_list, addr_list); + o = ip4_addr_subnets_addr_list_get(addr_list, 0); + nm_assert(o && *o); + if (*o != address) + return TRUE; + } else { + NM_SET_OUT(out_addr_list, NULL); + return address != *((gconstpointer *) p); + } + return FALSE; +} + +typedef enum { + IP6_ADDR_SCOPE_LOOPBACK, + IP6_ADDR_SCOPE_LINKLOCAL, + IP6_ADDR_SCOPE_SITELOCAL, + IP6_ADDR_SCOPE_OTHER, +} IP6AddrScope; + +static IP6AddrScope +ip6_address_scope(const NMPlatformIP6Address *a) +{ + if (IN6_IS_ADDR_LOOPBACK(&a->address)) + return IP6_ADDR_SCOPE_LOOPBACK; + if (IN6_IS_ADDR_LINKLOCAL(&a->address)) + return IP6_ADDR_SCOPE_LINKLOCAL; + if (IN6_IS_ADDR_SITELOCAL(&a->address)) + return IP6_ADDR_SCOPE_SITELOCAL; + return IP6_ADDR_SCOPE_OTHER; +} + +static int +ip6_address_scope_cmp(gconstpointer p_a, gconstpointer p_b, gpointer increasing) +{ + const NMPlatformIP6Address *a; + const NMPlatformIP6Address *b; + + if (!increasing) + NM_SWAP(&p_a, &p_b); + + a = NMP_OBJECT_CAST_IP6_ADDRESS(*(const NMPObject *const *) p_a); + b = NMP_OBJECT_CAST_IP6_ADDRESS(*(const NMPObject *const *) p_b); + + NM_CMP_DIRECT(ip6_address_scope(a), ip6_address_scope(b)); + return 0; +} + +/** + * nm_platform_ip_address_sync: + * @self: platform instance + * @addr_family: the address family AF_INET or AF_INET6. + * @ifindex: Interface index + * @known_addresses: List of addresses. The list will be modified and only + * addresses that were successfully added will be kept in the list. + * That means, expired addresses and addresses that could not be added + * will be dropped. + * Hence, the input argument @known_addresses is also an output argument + * telling which addresses were successfully added. + * Addresses are removed by unrefing the instance via nmp_object_unref() + * and leaving a NULL tombstone. + * @addresses_prune: (allow-none): the list of addresses to delete. + * If platform has such an address configured, it will be deleted + * at the beginning of the sync. Note that the array will be modified + * by the function. + * Note that the addresses must be properly sorted, by their priority. + * Create this list with nm_platform_ip_address_get_prune_list() which + * gets the sorting right. + * + * A convenience function to synchronize addresses for a specific interface + * with the least possible disturbance. It simply removes addresses that are + * not listed and adds addresses that are. + * + * Returns: %TRUE on success. + */ +gboolean +nm_platform_ip_address_sync(NMPlatform *self, + int addr_family, + int ifindex, + GPtrArray * known_addresses, + GPtrArray * addresses_prune) +{ + const gint32 now = nm_utils_get_monotonic_timestamp_sec(); + const int IS_IPv4 = NM_IS_IPv4(addr_family); + gs_unref_hashtable GHashTable *known_addresses_idx = NULL; + GPtrArray * plat_addresses; + GHashTable * known_subnets = NULL; + guint32 ifa_flags; + guint i_plat; + guint i_know; + guint i; + guint j; + + _CHECK_SELF(self, klass, FALSE); + + /* The order we want to enforce is only among addresses with the same + * scope, as the kernel keeps addresses sorted by scope. Therefore, + * apply the same sorting to known addresses, so that we don't try to + * unnecessary change the order of addresses with different scopes. */ + if (!IS_IPv4) { + if (known_addresses) + g_ptr_array_sort_with_data(known_addresses, + ip6_address_scope_cmp, + GINT_TO_POINTER(TRUE)); + } + + if (!_addr_array_clean_expired(addr_family, + ifindex, + known_addresses, + now, + &known_addresses_idx)) + known_addresses = NULL; + + /* @plat_addresses must be sorted in decreasing priority order (highest priority addresses first), contrary to + * @known_addresses which is in increasing priority order (lowest priority addresses first). */ + plat_addresses = addresses_prune; + + if (nm_g_ptr_array_len(plat_addresses) > 0) { + /* Delete unknown addresses */ + if (IS_IPv4) { + GHashTable *plat_subnets; + + plat_subnets = ip4_addr_subnets_build_index(plat_addresses, TRUE, TRUE); + + for (i = 0; i < plat_addresses->len; i++) { + const NMPObject * plat_obj; + const NMPlatformIP4Address *plat_address; + const GPtrArray * addr_list; + + plat_obj = plat_addresses->pdata[i]; + if (!plat_obj) { + /* Already deleted */ + continue; + } + + plat_address = NMP_OBJECT_CAST_IP4_ADDRESS(plat_obj); + + if (known_addresses) { + const NMPObject *o; + + o = g_hash_table_lookup(known_addresses_idx, plat_obj); + if (o) { + gboolean secondary; + + if (!known_subnets) + known_subnets = + ip4_addr_subnets_build_index(known_addresses, FALSE, FALSE); + + secondary = + ip4_addr_subnets_is_secondary(o, known_subnets, known_addresses, NULL); + if (secondary == NM_FLAGS_HAS(plat_address->n_ifa_flags, IFA_F_SECONDARY)) { + /* if we have an existing known-address, with matching secondary role, + * do not delete the platform-address. */ + continue; + } + } + } + + nm_platform_ip4_address_delete(self, + ifindex, + plat_address->address, + plat_address->plen, + plat_address->peer_address); + + if (!ip4_addr_subnets_is_secondary(plat_obj, + plat_subnets, + plat_addresses, + &addr_list) + && addr_list) { + /* If we just deleted a primary addresses and there were + * secondary ones the kernel can do two things, depending on + * version and sysctl setting: delete also secondary addresses + * or promote a secondary to primary. Ensure that secondary + * addresses are deleted, so that we can start with a clean + * slate and add addresses in the right order. */ + for (j = 1; j < addr_list->len; j++) { + const NMPObject **o; + + o = ip4_addr_subnets_addr_list_get(addr_list, j); + nm_assert(o); + + if (*o) { + const NMPlatformIP4Address *a; + + a = NMP_OBJECT_CAST_IP4_ADDRESS(*o); + nm_platform_ip4_address_delete(self, + ifindex, + a->address, + a->plen, + a->peer_address); + nmp_object_unref(*o); + *o = NULL; + } + } + } + } + ip4_addr_subnets_destroy_index(plat_subnets, plat_addresses); + } else { + guint known_addresses_len; + IP6AddrScope cur_scope; + gboolean delete_remaining_addrs; + + g_ptr_array_sort_with_data(plat_addresses, + ip6_address_scope_cmp, + GINT_TO_POINTER(FALSE)); + + known_addresses_len = known_addresses ? known_addresses->len : 0; + + /* First, compare every address whether it is still a "known address", that is, whether + * to keep it or to delete it. + * + * If we don't find a matching valid address in @known_addresses, we will delete + * plat_addr. + * + * Certain addresses, like temporary addresses, are ignored by this function + * if not run with full_sync. These addresses are usually not managed by NetworkManager + * directly, or at least, they are not managed via nm_platform_ip6_address_sync(). + * Only in full_sync mode, we really want to get rid of them (usually, when we take + * the interface down). + * + * Note that we mark handled addresses by setting it to %NULL in @plat_addresses array. */ + for (i_plat = 0; i_plat < plat_addresses->len; i_plat++) { + const NMPObject * plat_obj = plat_addresses->pdata[i_plat]; + const NMPObject * know_obj; + const NMPlatformIP6Address *plat_addr = NMP_OBJECT_CAST_IP6_ADDRESS(plat_obj); + + if (known_addresses_idx) { + know_obj = g_hash_table_lookup(known_addresses_idx, plat_obj); + if (know_obj + && plat_addr->plen == NMP_OBJECT_CAST_IP6_ADDRESS(know_obj)->plen) { + /* technically, plen is not part of the ID for IPv6 addresses and thus + * @plat_addr is essentially the same address as @know_addr (regrading + * its identity, not its other attributes). + * However, we cannot modify an existing addresses' plen without + * removing and readding it. Thus, only keep plat_addr, if the plen + * matches. + * + * keep this one, and continue */ + continue; + } + } + + nm_platform_ip6_address_delete(self, ifindex, plat_addr->address, plat_addr->plen); + nmp_object_unref(g_steal_pointer(&plat_addresses->pdata[i_plat])); + } + + /* Next, we must preserve the priority of the routes. That is, source address + * selection will choose addresses in the order as they are reported by kernel. + * Note that the order in @plat_addresses of the remaining matches is highest + * priority first. + * We need to compare this to the order of addresses with same scope in + * @known_addresses (which has lowest priority first). + * + * If we find a first discrepancy, we need to delete all remaining addresses + * with same scope from that point on, because below we must re-add all the + * addresses in the right order to get their priority right. */ + cur_scope = IP6_ADDR_SCOPE_LOOPBACK; + delete_remaining_addrs = FALSE; + i_plat = plat_addresses->len; + i_know = 0; + while (i_plat > 0) { + const NMPlatformIP6Address *plat_addr = + NMP_OBJECT_CAST_IP6_ADDRESS(plat_addresses->pdata[--i_plat]); + IP6AddrScope plat_scope; + + if (!plat_addr) + continue; + + plat_scope = ip6_address_scope(plat_addr); + if (cur_scope != plat_scope) { + nm_assert(cur_scope < plat_scope); + delete_remaining_addrs = FALSE; + cur_scope = plat_scope; + } + + if (!delete_remaining_addrs) { + delete_remaining_addrs = TRUE; + for (; i_know < known_addresses_len; i_know++) { + const NMPlatformIP6Address *know_addr = + NMP_OBJECT_CAST_IP6_ADDRESS(known_addresses->pdata[i_know]); + IP6AddrScope know_scope; + + if (!know_addr) + continue; + + know_scope = ip6_address_scope(know_addr); + if (know_scope < plat_scope) + continue; + + if (IN6_ARE_ADDR_EQUAL(&plat_addr->address, &know_addr->address)) { + /* we have a match. Mark address as handled. */ + i_know++; + delete_remaining_addrs = FALSE; + goto next_plat; + } + + /* plat_address has no match. Now delete_remaining_addrs is TRUE and we will + * delete all the remaining addresses with cur_scope. */ + break; + } + } + + nm_platform_ip6_address_delete(self, ifindex, plat_addr->address, plat_addr->plen); +next_plat:; + } + } + } + + if (!known_addresses) + return TRUE; + + if (IS_IPv4) + ip4_addr_subnets_destroy_index(known_subnets, known_addresses); + + ifa_flags = nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS) + ? IFA_F_NOPREFIXROUTE + : 0; + + /* Add missing addresses. New addresses are added by kernel with top + * priority. + */ + for (i_know = 0; i_know < known_addresses->len; i_know++) { + const NMPlatformIPXAddress *known_address; + const NMPObject * o; + guint32 lifetime; + guint32 preferred; + + o = known_addresses->pdata[i_know]; + if (!o) + continue; + + nm_assert(NMP_OBJECT_GET_TYPE(o) == NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4)); + + known_address = NMP_OBJECT_CAST_IPX_ADDRESS(o); + + lifetime = nmp_utils_lifetime_get(known_address->ax.timestamp, + known_address->ax.lifetime, + known_address->ax.preferred, + now, + &preferred); + nm_assert(lifetime > 0); + + if (IS_IPv4) { + if (!nm_platform_ip4_address_add( + self, + ifindex, + known_address->a4.address, + known_address->a4.plen, + known_address->a4.peer_address, + nm_platform_ip4_broadcast_address_from_addr(&known_address->a4), + lifetime, + preferred, + ifa_flags, + known_address->a4.label)) { + /* ignore error, for unclear reasons. */ + } + } else { + if (!nm_platform_ip6_address_add(self, + ifindex, + known_address->a6.address, + known_address->a6.plen, + known_address->a6.peer_address, + lifetime, + preferred, + ifa_flags | known_address->a6.n_ifa_flags)) + return FALSE; + } + } + + return TRUE; +} + +gboolean +nm_platform_ip_address_flush(NMPlatform *self, int addr_family, int ifindex) +{ + gboolean success = TRUE; + + _CHECK_SELF(self, klass, FALSE); + + nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); + + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) + success &= nm_platform_ip4_address_sync(self, ifindex, NULL); + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) + success &= nm_platform_ip6_address_sync(self, ifindex, NULL, TRUE); + return success; +} + +/*****************************************************************************/ + +static gboolean +_err_inval_due_to_ipv6_tentative_pref_src(NMPlatform *self, const NMPObject *obj) +{ + const NMPlatformIP6Route * r; + const NMPlatformIP6Address *a; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(NMP_OBJECT_IS_VALID(obj)); + + /* trying to add an IPv6 route with pref-src fails, if the address is + * still tentative (rh#1452684). We need to hack around that. + * + * Detect it, by guessing whether that's the case. */ + + if (NMP_OBJECT_GET_TYPE(obj) != NMP_OBJECT_TYPE_IP6_ROUTE) + return FALSE; + + r = NMP_OBJECT_CAST_IP6_ROUTE(obj); + + /* we only allow this workaround for routes added manually by the user. */ + if (r->rt_source != NM_IP_CONFIG_SOURCE_USER) + return FALSE; + + if (IN6_IS_ADDR_UNSPECIFIED(&r->pref_src)) + return FALSE; + + a = nm_platform_ip6_address_get(self, r->ifindex, &r->pref_src); + if (!a) + return FALSE; + if (!NM_FLAGS_HAS(a->n_ifa_flags, IFA_F_TENTATIVE) + || NM_FLAGS_HAS(a->n_ifa_flags, IFA_F_DADFAILED)) + return FALSE; + + return TRUE; +} + +GPtrArray * +nm_platform_ip_address_get_prune_list(NMPlatform *self, + int addr_family, + int ifindex, + gboolean exclude_ipv6_temporary_addrs) +{ + const int IS_IPv4 = NM_IS_IPv4(addr_family); + const NMDedupMultiHeadEntry *head_entry; + NMPLookup lookup; + GPtrArray * result; + CList * iter; + + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(NM_IS_IPv4(addr_family)), ifindex); + + head_entry = nm_platform_lookup(self, &lookup); + + if (!head_entry) + return NULL; + + result = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nmp_object_unref); + + c_list_for_each (iter, &head_entry->lst_entries_head) { + const NMPObject *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; + + if (!IS_IPv4) { + if (exclude_ipv6_temporary_addrs + && NM_FLAGS_HAS(NMP_OBJECT_CAST_IP_ADDRESS(obj)->n_ifa_flags, IFA_F_TEMPORARY)) + continue; + } + + g_ptr_array_add(result, (gpointer) nmp_object_ref(obj)); + } + + if (result->len == 0) { + g_ptr_array_unref(result); + return NULL; + } + return result; +} + +GPtrArray * +nm_platform_ip_route_get_prune_list(NMPlatform * self, + int addr_family, + int ifindex, + NMIPRouteTableSyncMode route_table_sync) +{ + NMPLookup lookup; + GPtrArray * routes_prune; + const NMDedupMultiHeadEntry *head_entry; + CList * iter; + NMPlatformIP4Route rt_local4; + NMPlatformIP6Route rt_local6; + const NMPlatformLink * pllink; + const NMPlatformLnkVrf * lnk_vrf; + guint32 local_table; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + nm_assert(NM_IN_SET(route_table_sync, + NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN, + NM_IP_ROUTE_TABLE_SYNC_MODE_FULL, + NM_IP_ROUTE_TABLE_SYNC_MODE_ALL, + NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE)); + + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family)), ifindex); + head_entry = nm_platform_lookup(self, &lookup); + if (!head_entry) + return NULL; + + lnk_vrf = nm_platform_link_get_lnk_vrf(self, ifindex, &pllink); + if (!lnk_vrf && pllink && pllink->master > 0) + lnk_vrf = nm_platform_link_get_lnk_vrf(self, pllink->master, NULL); + local_table = lnk_vrf ? lnk_vrf->table : RT_TABLE_LOCAL; + + rt_local4.plen = 0; + rt_local6.plen = 0; + + routes_prune = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nm_dedup_multi_obj_unref); + + c_list_for_each (iter, &head_entry->lst_entries_head) { + const NMPObject * obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; + const NMPlatformIPXRoute *rt = NMP_OBJECT_CAST_IPX_ROUTE(obj); + + switch (route_table_sync) { + case NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN: + if (!nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&rt->rx))) + continue; + break; + case NM_IP_ROUTE_TABLE_SYNC_MODE_FULL: + if (nm_platform_ip_route_get_effective_table(&rt->rx) == RT_TABLE_LOCAL) + continue; + break; + case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL: + + /* FIXME: we should better handle routes that are automatically added by kernel. + * + * For now, make a good guess which are those routes and exclude them from + * pruning them. */ + + if (NM_IS_IPv4(addr_family)) { + /* for each IPv4 address kernel adds a route like + * + * local $ADDR dev $IFACE table local proto kernel scope host src $PRIMARY_ADDR + * + * Check whether route could be of that kind. */ + if (nm_platform_ip_route_get_effective_table(&rt->rx) == local_table + && rt->rx.plen == 32 && rt->rx.rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL + && rt->rx.metric == 0 + && rt->r4.scope_inv == nm_platform_route_scope_inv(RT_SCOPE_HOST) + && rt->r4.gateway == INADDR_ANY) { + if (rt_local4.plen == 0) { + rt_local4 = (NMPlatformIP4Route){ + .ifindex = ifindex, + .type_coerced = nm_platform_route_type_coerce(RTN_LOCAL), + .plen = 32, + .rt_source = NM_IP_CONFIG_SOURCE_RTPROT_KERNEL, + .metric = 0, + .table_coerced = nm_platform_route_table_coerce(local_table), + .scope_inv = nm_platform_route_scope_inv(RT_SCOPE_HOST), + .gateway = INADDR_ANY, + }; + } + + /* the possible "network" depends on the addresses we have. We don't check that + * carefully. If the other parameters match, we assume that this route is the one + * generated by kernel. */ + rt_local4.network = rt->r4.network; + rt_local4.pref_src = rt->r4.pref_src; + + /* to be more confident about comparing the value, use our nm_platform_ip4_route_cmp() + * implementation. That will also consider parameters that we leave unspecified here. */ + if (nm_platform_ip4_route_cmp(&rt->r4, + &rt_local4, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + == 0) + continue; + } + } else { + /* for each IPv6 address (that is no longer tentative) kernel adds a route like + * + * local $ADDR dev $IFACE table local proto kernel metric 0 pref medium + * + * Same as for the IPv4 case. */ + if (nm_platform_ip_route_get_effective_table(&rt->rx) == local_table + && rt->rx.plen == 128 && rt->rx.rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL + && rt->rx.metric == 0 && rt->r6.rt_pref == NM_ICMPV6_ROUTER_PREF_MEDIUM + && IN6_IS_ADDR_UNSPECIFIED(&rt->r6.gateway)) { + if (rt_local6.plen == 0) { + rt_local6 = (NMPlatformIP6Route){ + .ifindex = ifindex, + .type_coerced = nm_platform_route_type_coerce(RTN_LOCAL), + .plen = 128, + .rt_source = NM_IP_CONFIG_SOURCE_RTPROT_KERNEL, + .metric = 0, + .table_coerced = nm_platform_route_table_coerce(local_table), + .rt_pref = NM_ICMPV6_ROUTER_PREF_MEDIUM, + .gateway = IN6ADDR_ANY_INIT, + }; + } + + rt_local6.network = rt->r6.network; + + if (nm_platform_ip6_route_cmp(&rt->r6, + &rt_local6, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + == 0) + continue; + } + } + break; + + case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE: + break; + + default: + nm_assert_not_reached(); + break; + } + + g_ptr_array_add(routes_prune, (gpointer) nmp_object_ref(obj)); + } + + if (routes_prune->len == 0) { + g_ptr_array_unref(routes_prune); + return NULL; + } + return routes_prune; +} + +/** + * nm_platform_ip_route_sync: + * @self: the #NMPlatform instance. + * @addr_family: AF_INET or AF_INET6. + * @ifindex: the @ifindex for which the routes are to be added. + * @routes: (allow-none): a list of routes to configure. Must contain + * NMPObject instances of routes, according to @addr_family. + * @routes_prune: (allow-none): the list of routes to delete. + * If platform has such a route configured, it will be deleted + * at the end of the operation. Note that if @routes contains + * the same route, then it will not be deleted. @routes overrules + * @routes_prune list. + * @out_temporary_not_available: (allow-none) (out): routes that could + * currently not be synced. The caller shall keep them and try later again. + * + * Returns: %TRUE on success. + */ +gboolean +nm_platform_ip_route_sync(NMPlatform *self, + int addr_family, + int ifindex, + GPtrArray * routes, + GPtrArray * routes_prune, + GPtrArray **out_temporary_not_available) +{ + const int IS_IPv4 = NM_IS_IPv4(addr_family); + const NMPlatformVTableRoute *vt; + gs_unref_hashtable GHashTable *routes_idx = NULL; + const NMPObject * conf_o; + const NMDedupMultiEntry * plat_entry; + guint i; + int i_type; + gboolean success = TRUE; + char sbuf1[sizeof(_nm_utils_to_string_buffer)]; + char sbuf2[sizeof(_nm_utils_to_string_buffer)]; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(ifindex > 0); + + vt = &nm_platform_vtable_route.vx[IS_IPv4]; + + for (i_type = 0; routes && i_type < 2; i_type++) { + for (i = 0; i < routes->len; i++) { + int r, r2; + gboolean gateway_route_added = FALSE; + + conf_o = routes->pdata[i]; + +#define VTABLE_IS_DEVICE_ROUTE(vt, o) \ + (vt->is_ip4 ? (NMP_OBJECT_CAST_IP4_ROUTE(o)->gateway == 0) \ + : IN6_IS_ADDR_UNSPECIFIED(&NMP_OBJECT_CAST_IP6_ROUTE(o)->gateway)) + + if ((i_type == 0 && !VTABLE_IS_DEVICE_ROUTE(vt, conf_o)) + || (i_type == 1 && VTABLE_IS_DEVICE_ROUTE(vt, conf_o))) { + /* we add routes in two runs over @i_type. + * + * First device routes, then gateway routes. */ + continue; + } + + if (!routes_idx) { + routes_idx = g_hash_table_new((GHashFunc) nmp_object_id_hash, + (GEqualFunc) nmp_object_id_equal); + } + if (!g_hash_table_insert(routes_idx, (gpointer) conf_o, (gpointer) conf_o)) { + _LOG3D("route-sync: skip adding duplicate route %s", + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1))); + continue; + } + + if (!IS_IPv4 + && nm_platform_ip6_route_get_effective_metric(NMP_OBJECT_CAST_IP6_ROUTE(conf_o)) + == 0) { + /* User space cannot add routes with metric 0. However, kernel can, and we might track such + * routes in @route as they are present external. Skip them silently. */ + continue; + } + + plat_entry = nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, conf_o); + if (plat_entry) { + const NMPObject *plat_o; + + plat_o = plat_entry->obj; + + if (vt->route_cmp(NMP_OBJECT_CAST_IPX_ROUTE(conf_o), + NMP_OBJECT_CAST_IPX_ROUTE(plat_o), + NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + == 0) + continue; + + /* we need to replace the existing route with a (slightly) different + * one. Delete it first. */ + if (!nm_platform_object_delete(self, plat_o)) { + /* ignore error. */ + } + } + +sync_route_add: + r = nm_platform_ip_route_add(self, + NMP_NLM_FLAG_APPEND + | NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE, + conf_o); + if (r < 0) { + if (r == -EEXIST) { + /* Don't fail for EEXIST. It's not clear that the existing route + * is identical to the one that we were about to add. However, + * above we should have deleted conflicting (non-identical) routes. */ + if (_LOGD_ENABLED()) { + plat_entry = + nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, conf_o); + if (!plat_entry) { + _LOG3D("route-sync: adding route %s failed with EEXIST, however we " + "cannot find such a route", + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1))); + } else if (vt->route_cmp(NMP_OBJECT_CAST_IPX_ROUTE(conf_o), + NMP_OBJECT_CAST_IPX_ROUTE(plat_entry->obj), + NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + != 0) { + _LOG3D("route-sync: adding route %s failed due to existing " + "(different!) route %s", + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nmp_object_to_string(plat_entry->obj, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf2, + sizeof(sbuf2))); + } + } + } else if (NMP_OBJECT_CAST_IP_ROUTE(conf_o)->rt_source < NM_IP_CONFIG_SOURCE_USER) { + _LOG3D("route-sync: ignore failure to add IPv%c route: %s: %s", + vt->is_ip4 ? '4' : '6', + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nm_strerror(r)); + } else if (r == -EINVAL && out_temporary_not_available + && _err_inval_due_to_ipv6_tentative_pref_src(self, conf_o)) { + _LOG3D("route-sync: ignore failure to add IPv6 route with tentative IPv6 " + "pref-src: %s: %s", + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nm_strerror(r)); + if (!*out_temporary_not_available) + *out_temporary_not_available = + g_ptr_array_new_full(0, (GDestroyNotify) nmp_object_unref); + g_ptr_array_add(*out_temporary_not_available, + (gpointer) nmp_object_ref(conf_o)); + } else if (!gateway_route_added + && ((r == -ENETUNREACH && vt->is_ip4 + && !!NMP_OBJECT_CAST_IP4_ROUTE(conf_o)->gateway) + || (r == -EHOSTUNREACH && !vt->is_ip4 + && !IN6_IS_ADDR_UNSPECIFIED( + &NMP_OBJECT_CAST_IP6_ROUTE(conf_o)->gateway)))) { + NMPObject oo; + + if (vt->is_ip4) { + const NMPlatformIP4Route *rt = NMP_OBJECT_CAST_IP4_ROUTE(conf_o); + + nmp_object_stackinit( + &oo, + NMP_OBJECT_TYPE_IP4_ROUTE, + &((NMPlatformIP4Route){ + .ifindex = rt->ifindex, + .network = rt->gateway, + .plen = 32, + .metric = nm_platform_ip4_route_get_effective_metric(rt), + .rt_source = rt->rt_source, + .table_coerced = nm_platform_ip_route_get_effective_table( + NM_PLATFORM_IP_ROUTE_CAST(rt)), + })); + } else { + const NMPlatformIP6Route *rt = NMP_OBJECT_CAST_IP6_ROUTE(conf_o); + + nmp_object_stackinit( + &oo, + NMP_OBJECT_TYPE_IP6_ROUTE, + &((NMPlatformIP6Route){ + .ifindex = rt->ifindex, + .network = rt->gateway, + .plen = 128, + .metric = nm_platform_ip6_route_get_effective_metric(rt), + .rt_source = rt->rt_source, + .table_coerced = nm_platform_ip_route_get_effective_table( + NM_PLATFORM_IP_ROUTE_CAST(rt)), + })); + } + + _LOG3D("route-sync: failure to add IPv%c route: %s: %s; try adding direct " + "route to gateway %s", + vt->is_ip4 ? '4' : '6', + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nm_strerror(r), + nmp_object_to_string(&oo, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf2, + sizeof(sbuf2))); + + r2 = nm_platform_ip_route_add(self, + NMP_NLM_FLAG_APPEND + | NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE, + &oo); + + if (r2 < 0) { + _LOG3D("route-sync: failure to add gateway IPv%c route: %s: %s", + vt->is_ip4 ? '4' : '6', + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nm_strerror(r2)); + } + + gateway_route_added = TRUE; + goto sync_route_add; + } else { + _LOG3W("route-sync: failure to add IPv%c route: %s: %s", + vt->is_ip4 ? '4' : '6', + nmp_object_to_string(conf_o, + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf1, + sizeof(sbuf1)), + nm_strerror(r)); + success = FALSE; + } + } + } + } + + if (routes_prune) { + for (i = 0; i < routes_prune->len; i++) { + const NMPObject *prune_o; + + prune_o = routes_prune->pdata[i]; + + nm_assert((NM_IS_IPv4(addr_family) + && NMP_OBJECT_GET_TYPE(prune_o) == NMP_OBJECT_TYPE_IP4_ROUTE) + || (!NM_IS_IPv4(addr_family) + && NMP_OBJECT_GET_TYPE(prune_o) == NMP_OBJECT_TYPE_IP6_ROUTE)); + + if (routes_idx && g_hash_table_lookup(routes_idx, prune_o)) + continue; + + if (!nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, prune_o)) + continue; + + if (!nm_platform_object_delete(self, prune_o)) { + /* ignore error... */ + } + } + } + + return success; +} + +gboolean +nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex) +{ + gboolean success = TRUE; + + _CHECK_SELF(self, klass, FALSE); + + nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); + + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) { + gs_unref_ptrarray GPtrArray *routes_prune = NULL; + + routes_prune = nm_platform_ip_route_get_prune_list(self, + AF_INET, + ifindex, + NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE); + success &= nm_platform_ip_route_sync(self, AF_INET, ifindex, NULL, routes_prune, NULL); + } + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) { + gs_unref_ptrarray GPtrArray *routes_prune = NULL; + + routes_prune = nm_platform_ip_route_get_prune_list(self, + AF_INET6, + ifindex, + NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE); + success &= nm_platform_ip_route_sync(self, AF_INET6, ifindex, NULL, routes_prune, NULL); + } + return success; +} + +/*****************************************************************************/ + +static guint8 +_ip_route_scope_inv_get_normalized(const NMPlatformIP4Route *route) +{ + /* in kernel, you cannot set scope to RT_SCOPE_NOWHERE (255). + * That means, in NM, we treat RT_SCOPE_NOWHERE as unset, and detect + * it based on the presence of the gateway. In other words, when adding + * a route with scope RT_SCOPE_NOWHERE (in NetworkManager) to kernel, + * the resulting scope will be either "link" or "universe" (depending + * on the gateway). + * + * Note that internally, we track @scope_inv is the inverse of scope, + * so that the default equals zero (~(RT_SCOPE_NOWHERE)). + **/ + if (route->scope_inv == 0) { + if (route->type_coerced == nm_platform_route_type_coerce(RTN_LOCAL)) + return nm_platform_route_scope_inv(RT_SCOPE_HOST); + else { + return nm_platform_route_scope_inv(!route->gateway ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE); + } + } + return route->scope_inv; +} + +static guint8 +_route_pref_normalize(guint8 pref) +{ + /* for kernel (and ICMPv6) pref can only have one of 3 values. Normalize. */ + return NM_IN_SET(pref, NM_ICMPV6_ROUTER_PREF_LOW, NM_ICMPV6_ROUTER_PREF_HIGH) + ? pref + : NM_ICMPV6_ROUTER_PREF_MEDIUM; +} + +/** + * nm_platform_ip_route_normalize: + * @addr_family: AF_INET or AF_INET6 + * @route: an NMPlatformIP4Route or NMPlatformIP6Route instance, depending on @addr_family. + * + * Adding a route to kernel via nm_platform_ip_route_add() will normalize/coerce some + * properties of the route. This function modifies (normalizes) the route like it + * would be done by adding the route in kernel. + * + * Note that this function is related to NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY + * in that if two routes compare semantically equal, after normalizing they also shall + * compare equal with NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL. + */ +void +nm_platform_ip_route_normalize(int addr_family, NMPlatformIPRoute *route) +{ + NMPlatformIP4Route *r4; + NMPlatformIP6Route *r6; + + route->table_coerced = + nm_platform_route_table_coerce(nm_platform_ip_route_get_effective_table(route)); + route->table_any = FALSE; + + route->rt_source = nmp_utils_ip_config_source_round_trip_rtprot(route->rt_source); + + switch (addr_family) { + case AF_INET: + r4 = (NMPlatformIP4Route *) route; + route->metric = nm_platform_ip4_route_get_effective_metric(r4); + route->metric_any = FALSE; + r4->network = nm_utils_ip4_address_clear_host_address(r4->network, r4->plen); + r4->scope_inv = _ip_route_scope_inv_get_normalized(r4); + break; + case AF_INET6: + r6 = (NMPlatformIP6Route *) route; + route->metric = nm_platform_ip6_route_get_effective_metric(r6); + route->metric_any = FALSE; + nm_utils_ip6_address_clear_host_address(&r6->network, &r6->network, r6->plen); + nm_utils_ip6_address_clear_host_address(&r6->src, &r6->src, r6->src_plen); + break; + default: + nm_assert_not_reached(); + break; + } +} + +static int +_ip_route_add(NMPlatform *self, NMPNlmFlags flags, int addr_family, gconstpointer route) +{ + char sbuf[sizeof(_nm_utils_to_string_buffer)]; + int ifindex; + + _CHECK_SELF(self, klass, FALSE); + + nm_assert(route); + nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + + ifindex = ((const NMPlatformIPRoute *) route)->ifindex; + _LOG3D("route: %-10s IPv%c route: %s", + _nmp_nlm_flag_to_string(flags & NMP_NLM_FLAG_FMASK), + nm_utils_addr_family_to_char(addr_family), + NM_IS_IPv4(addr_family) ? nm_platform_ip4_route_to_string(route, sbuf, sizeof(sbuf)) + : nm_platform_ip6_route_to_string(route, sbuf, sizeof(sbuf))); + + return klass->ip_route_add(self, flags, addr_family, route); +} + +int +nm_platform_ip_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPObject *route) +{ + int addr_family; + + switch (NMP_OBJECT_GET_TYPE(route)) { + case NMP_OBJECT_TYPE_IP4_ROUTE: + addr_family = AF_INET; + break; + case NMP_OBJECT_TYPE_IP6_ROUTE: + addr_family = AF_INET6; + break; + default: + g_return_val_if_reached(FALSE); + } + + return _ip_route_add(self, flags, addr_family, NMP_OBJECT_CAST_IP_ROUTE(route)); +} + +int +nm_platform_ip4_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP4Route *route) +{ + return _ip_route_add(self, flags, AF_INET, route); +} + +int +nm_platform_ip6_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP6Route *route) +{ + return _ip_route_add(self, flags, AF_INET6, route); +} + +gboolean +nm_platform_object_delete(NMPlatform *self, const NMPObject *obj) +{ + int ifindex; + + _CHECK_SELF(self, klass, FALSE); + + switch (NMP_OBJECT_GET_TYPE(obj)) { + case NMP_OBJECT_TYPE_ROUTING_RULE: + _LOGD("%s: delete %s", + NMP_OBJECT_GET_CLASS(obj)->obj_type_name, + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + break; + case NMP_OBJECT_TYPE_IP4_ROUTE: + case NMP_OBJECT_TYPE_IP6_ROUTE: + case NMP_OBJECT_TYPE_QDISC: + case NMP_OBJECT_TYPE_TFILTER: + ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj)->ifindex; + _LOG3D("%s: delete %s", + NMP_OBJECT_GET_CLASS(obj)->obj_type_name, + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + break; + default: + g_return_val_if_reached(FALSE); + } + + return klass->object_delete(self, obj); +} + +/*****************************************************************************/ + +int +nm_platform_ip_route_get(NMPlatform * self, + int addr_family, + gconstpointer address /* in_addr_t or struct in6_addr */, + int oif_ifindex, + NMPObject ** out_route) +{ + nm_auto_nmpobj NMPObject *route = NULL; + int result; + char buf[NM_UTILS_INET_ADDRSTRLEN]; + char buf_oif[64]; + + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(address, -NME_BUG); + g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), -NME_BUG); + + _LOGT("route: get IPv%c route for: %s%s", + nm_utils_addr_family_to_char(addr_family), + inet_ntop(addr_family, address, buf, sizeof(buf)), + oif_ifindex > 0 ? nm_sprintf_buf(buf_oif, " oif %d", oif_ifindex) : ""); + + if (!klass->ip_route_get) + result = -NME_PL_OPNOTSUPP; + else { + result = klass->ip_route_get(self, addr_family, address, oif_ifindex, &route); + } + + if (result < 0) { + nm_assert(!route); + _LOGW("route: get IPv%c route for: %s failed with %s", + nm_utils_addr_family_to_char(addr_family), + inet_ntop(addr_family, address, buf, sizeof(buf)), + nm_strerror(result)); + } else { + nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(route), + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE)); + nm_assert(!NMP_OBJECT_IS_STACKINIT(route)); + nm_assert(route->parent._ref_count == 1); + _LOGD("route: get IPv%c route for: %s succeeded: %s", + nm_utils_addr_family_to_char(addr_family), + inet_ntop(addr_family, address, buf, sizeof(buf)), + nmp_object_to_string(route, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + NM_SET_OUT(out_route, g_steal_pointer(&route)); + } + return result; +} + +/*****************************************************************************/ + +#define IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS ((int) 1500) +#define IP4_DEV_ROUTE_BLACKLIST_GC_TIMEOUT_S \ + ((int) (((IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS + 999) * 3) / 1000)) + +static gint64 +_ip4_dev_route_blacklist_timeout_ms_get(gint64 timeout_msec) +{ + return timeout_msec >> 1; +} + +static gint64 +_ip4_dev_route_blacklist_timeout_ms_marked(gint64 timeout_msec) +{ + return !!(timeout_msec & ((gint64) 1)); +} + +static gboolean +_ip4_dev_route_blacklist_check_cb(gpointer user_data) +{ + NMPlatform * self = user_data; + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); + GHashTableIter iter; + const NMPObject * p_obj; + gint64 * p_timeout_ms; + gint64 now_ms; + + priv->ip4_dev_route_blacklist_check_id = 0; + +again: + if (!priv->ip4_dev_route_blacklist_hash) + goto out; + + now_ms = nm_utils_get_monotonic_timestamp_msec(); + + g_hash_table_iter_init(&iter, priv->ip4_dev_route_blacklist_hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) { + if (!_ip4_dev_route_blacklist_timeout_ms_marked(*p_timeout_ms)) + continue; + + /* unmark because we checked it. */ + *p_timeout_ms = *p_timeout_ms & ~((gint64) 1); + + if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get(*p_timeout_ms)) + continue; + + if (!nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, p_obj)) + continue; + + _LOGT("ip4-dev-route: delete %s", + nmp_object_to_string(p_obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + nm_platform_object_delete(self, p_obj); + goto again; + } + +out: + return G_SOURCE_REMOVE; +} + +static void +_ip4_dev_route_blacklist_check_schedule(NMPlatform *self) +{ + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); + + if (!priv->ip4_dev_route_blacklist_check_id) { + priv->ip4_dev_route_blacklist_check_id = + g_idle_add_full(G_PRIORITY_HIGH, _ip4_dev_route_blacklist_check_cb, self, NULL); + } +} + +static void +_ip4_dev_route_blacklist_notify_route(NMPlatform *self, const NMPObject *obj) +{ + NMPlatformPrivate *priv; + const NMPObject * p_obj; + gint64 * p_timeout_ms; + gint64 now_ms; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_IP4_ROUTE); + + priv = NM_PLATFORM_GET_PRIVATE(self); + + nm_assert(priv->ip4_dev_route_blacklist_gc_timeout_id); + + if (!g_hash_table_lookup_extended(priv->ip4_dev_route_blacklist_hash, + obj, + (gpointer *) &p_obj, + (gpointer *) &p_timeout_ms)) + return; + + now_ms = nm_utils_get_monotonic_timestamp_msec(); + if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get(*p_timeout_ms)) { + /* already expired. Wait for gc. */ + return; + } + + if (_ip4_dev_route_blacklist_timeout_ms_marked(*p_timeout_ms)) { + nm_assert(priv->ip4_dev_route_blacklist_check_id); + return; + } + + /* We cannot delete it right away because we are in the process of receiving netlink messages. + * It may be possible to do so, but complicated and error prone. + * + * Instead, we mark the entry and schedule an idle action (with high priority). */ + *p_timeout_ms = (*p_timeout_ms) | ((gint64) 1); + _ip4_dev_route_blacklist_check_schedule(self); +} + +static gboolean +_ip4_dev_route_blacklist_gc_timeout_handle(gpointer user_data) +{ + NMPlatform * self = user_data; + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); + GHashTableIter iter; + const NMPObject * p_obj; + gint64 * p_timeout_ms; + gint64 now_ms; + + nm_assert(priv->ip4_dev_route_blacklist_gc_timeout_id); + + now_ms = nm_utils_get_monotonic_timestamp_msec(); + + g_hash_table_iter_init(&iter, priv->ip4_dev_route_blacklist_hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) { + if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get(*p_timeout_ms)) { + _LOGT("ip4-dev-route: cleanup %s", + nmp_object_to_string(p_obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + g_hash_table_iter_remove(&iter); + } + } + + _ip4_dev_route_blacklist_schedule(self); + return G_SOURCE_CONTINUE; +} + +static void +_ip4_dev_route_blacklist_schedule(NMPlatform *self) +{ + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); + + if (!priv->ip4_dev_route_blacklist_hash + || g_hash_table_size(priv->ip4_dev_route_blacklist_hash) == 0) { + nm_clear_pointer(&priv->ip4_dev_route_blacklist_hash, g_hash_table_unref); + nm_clear_g_source(&priv->ip4_dev_route_blacklist_gc_timeout_id); + } else { + if (!priv->ip4_dev_route_blacklist_gc_timeout_id) { + /* this timeout is only to garbage collect the expired entries from priv->ip4_dev_route_blacklist_hash. + * It can run infrequently, and it doesn't hurt if expired entries linger around a bit + * longer then necessary. */ + priv->ip4_dev_route_blacklist_gc_timeout_id = + g_timeout_add_seconds(IP4_DEV_ROUTE_BLACKLIST_GC_TIMEOUT_S, + _ip4_dev_route_blacklist_gc_timeout_handle, + self); + } + } +} + +/** + * nm_platform_ip4_dev_route_blacklist_set: + * @self: + * @ifindex: + * @ip4_dev_route_blacklist: + * + * When adding an IP address, kernel automatically adds a device route. + * This can be suppressed via the IFA_F_NOPREFIXROUTE address flag. For proper + * IPv6 support, we require kernel support for IFA_F_NOPREFIXROUTE and always + * add the device route manually. + * + * For IPv4, this flag is rather new and we don't rely on it yet. We want to use + * it (but currently still don't). So, for IPv4, kernel possibly adds a device + * route, however it has a wrong metric of zero. We add our own device route (with + * proper metric), but need to delete the route that kernel adds. + * + * The problem is, that kernel does not immediately add the route, when adding + * the address. It only shows up some time later. So, we register here a list + * of blacklisted routes, and when they show up within a time out, we assume it's + * the kernel generated one, and we delete it. + * + * Eventually, we want to get rid of this and use IFA_F_NOPREFIXROUTE for IPv4 + * routes as well. + */ +void +nm_platform_ip4_dev_route_blacklist_set(NMPlatform *self, + int ifindex, + GPtrArray * ip4_dev_route_blacklist) +{ + NMPlatformPrivate *priv; + GHashTableIter iter; + const NMPObject * p_obj; + guint i; + gint64 timeout_msec; + gint64 timeout_msec_val; + gint64 * p_timeout_ms; + gboolean needs_check = FALSE; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(ifindex > 0); + + /* TODO: the blacklist should be maintained by NML3Cfg. */ + + priv = NM_PLATFORM_GET_PRIVATE(self); + + /* first, expire all for current ifindex... */ + if (priv->ip4_dev_route_blacklist_hash) { + g_hash_table_iter_init(&iter, priv->ip4_dev_route_blacklist_hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) { + if (NMP_OBJECT_CAST_IP4_ROUTE(p_obj)->ifindex == ifindex) { + /* we could g_hash_table_iter_remove(&iter) the current entry. + * Instead, just expire it and let _ip4_dev_route_blacklist_gc_timeout_handle() + * handle it. + * + * The assumption is, that ip4_dev_route_blacklist contains the very same entry + * again, with a new timeout. So, we can un-expire it below. */ + *p_timeout_ms = 0; + } + } + } + + if (ip4_dev_route_blacklist && ip4_dev_route_blacklist->len > 0) { + if (!priv->ip4_dev_route_blacklist_hash) { + priv->ip4_dev_route_blacklist_hash = + g_hash_table_new_full((GHashFunc) nmp_object_id_hash, + (GEqualFunc) nmp_object_id_equal, + (GDestroyNotify) nmp_object_unref, + nm_g_slice_free_fcn_gint64); + } + + timeout_msec = nm_utils_get_monotonic_timestamp_msec() + IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS; + timeout_msec_val = (timeout_msec << 1) | ((gint64) 1); + for (i = 0; i < ip4_dev_route_blacklist->len; i++) { + const NMPObject *o; + + needs_check = TRUE; + o = ip4_dev_route_blacklist->pdata[i]; + if (g_hash_table_lookup_extended(priv->ip4_dev_route_blacklist_hash, + o, + (gpointer *) &p_obj, + (gpointer *) &p_timeout_ms)) { + if (nmp_object_equal(p_obj, o)) { + /* un-expire and reuse the entry. */ + _LOGT("ip4-dev-route: register %s (update)", + nmp_object_to_string(p_obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + *p_timeout_ms = timeout_msec_val; + continue; + } + } + + _LOGT("ip4-dev-route: register %s", + nmp_object_to_string(o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + p_timeout_ms = g_slice_new(gint64); + *p_timeout_ms = timeout_msec_val; + g_hash_table_replace(priv->ip4_dev_route_blacklist_hash, + (gpointer) nmp_object_ref(o), + p_timeout_ms); + } + } + + _ip4_dev_route_blacklist_schedule(self); + + if (needs_check) + _ip4_dev_route_blacklist_check_schedule(self); +} + +/*****************************************************************************/ + +int +nm_platform_routing_rule_add(NMPlatform * self, + NMPNlmFlags flags, + const NMPlatformRoutingRule *routing_rule) +{ + _CHECK_SELF(self, klass, -NME_BUG); + + g_return_val_if_fail(routing_rule, -NME_BUG); + + _LOGD("routing-rule: adding or updating: %s", + nm_platform_routing_rule_to_string(routing_rule, NULL, 0)); + return klass->routing_rule_add(self, flags, routing_rule); +} + +/*****************************************************************************/ + +int +nm_platform_qdisc_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformQdisc *qdisc) +{ + int ifindex = qdisc->ifindex; + _CHECK_SELF(self, klass, -NME_BUG); + + /* Note: @qdisc must not be copied or kept alive because the lifetime of qdisc.kind + * is undefined. */ + + _LOG3D("adding or updating a qdisc: %s", nm_platform_qdisc_to_string(qdisc, NULL, 0)); + return klass->qdisc_add(self, flags, qdisc); +} + +/** + * nm_platform_qdisc_sync: + * @self: the #NMPlatform instance + * @ifindex: the ifindex where to configure the qdiscs. + * @known_qdiscs: the list of qdiscs (#NMPObject). + * + * The function promises not to take any reference to the qdisc + * instances from @known_qdiscs, nor to keep them around after + * the function returns. This is important, because it allows the + * caller to pass NMPlatformQdisc instances which "kind" string + * have a limited lifetime. + * + * Returns: %TRUE on success. + */ +gboolean +nm_platform_qdisc_sync(NMPlatform *self, int ifindex, GPtrArray *known_qdiscs) +{ + gs_unref_ptrarray GPtrArray *plat_qdiscs = NULL; + NMPLookup lookup; + guint i; + gboolean success = TRUE; + gs_unref_hashtable GHashTable *known_qdiscs_idx = NULL; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(ifindex > 0); + + known_qdiscs_idx = + g_hash_table_new((GHashFunc) nmp_object_id_hash, (GEqualFunc) nmp_object_id_equal); + if (known_qdiscs) { + for (i = 0; i < known_qdiscs->len; i++) { + const NMPObject *q = g_ptr_array_index(known_qdiscs, i); + + if (!g_hash_table_insert(known_qdiscs_idx, (gpointer) q, (gpointer) q)) { + _LOGW("duplicate qdisc %s", nm_platform_qdisc_to_string(&q->qdisc, NULL, 0)); + return FALSE; + } + } + } + + plat_qdiscs = + nm_platform_lookup_clone(self, + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_QDISC, ifindex), + NULL, + NULL); + if (plat_qdiscs) { + for (i = 0; i < plat_qdiscs->len; i++) { + const NMPObject *p = g_ptr_array_index(plat_qdiscs, i); + const NMPObject *k; + + /* look up known qdisc with same parent */ + k = g_hash_table_lookup(known_qdiscs_idx, p); + + if (k) { + const NMPlatformQdisc *qdisc_k = NMP_OBJECT_CAST_QDISC(k); + const NMPlatformQdisc *qdisc_p = NMP_OBJECT_CAST_QDISC(p); + + /* check other fields */ + if (nm_platform_qdisc_cmp_full(qdisc_k, qdisc_p, FALSE) != 0 + || (qdisc_k->handle != qdisc_p->handle && qdisc_k != 0)) { + k = NULL; + } + } + + if (k) { + g_hash_table_remove(known_qdiscs_idx, k); + } else { + /* can't delete qdisc with zero handle */ + if (TC_H_MAJ(p->qdisc.handle) != 0) { + success &= nm_platform_object_delete(self, p); + } + } + } + } + + if (known_qdiscs) { + for (i = 0; i < known_qdiscs->len; i++) { + const NMPObject *q = g_ptr_array_index(known_qdiscs, i); + + if (g_hash_table_contains(known_qdiscs_idx, q)) { + success &= + (nm_platform_qdisc_add(self, NMP_NLM_FLAG_ADD, NMP_OBJECT_CAST_QDISC(q)) >= 0); + } + } + } + + return success; +} + +/*****************************************************************************/ + +int +nm_platform_tfilter_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformTfilter *tfilter) +{ + int ifindex = tfilter->ifindex; + _CHECK_SELF(self, klass, -NME_BUG); + + /* Note: @tfilter must not be copied or kept alive because the lifetime of tfilter.kind + * and tfilter.action.kind is undefined. */ + + _LOG3D("adding or updating a tfilter: %s", nm_platform_tfilter_to_string(tfilter, NULL, 0)); + return klass->tfilter_add(self, flags, tfilter); +} + +/** + * nm_platform_qdisc_sync: + * @self: the #NMPlatform instance + * @ifindex: the ifindex where to configure the qdiscs. + * @known_tfilters: the list of tfilters (#NMPObject). + * + * The function promises not to take any reference to the tfilter + * instances from @known_tfilters, nor to keep them around after + * the function returns. This is important, because it allows the + * caller to pass NMPlatformTfilter instances which "kind" string + * have a limited lifetime. + * + * Returns: %TRUE on success. + */ +gboolean +nm_platform_tfilter_sync(NMPlatform *self, int ifindex, GPtrArray *known_tfilters) +{ + gs_unref_ptrarray GPtrArray *plat_tfilters = NULL; + NMPLookup lookup; + guint i; + gboolean success = TRUE; + gs_unref_hashtable GHashTable *known_tfilters_idx = NULL; + + nm_assert(NM_IS_PLATFORM(self)); + nm_assert(ifindex > 0); + + known_tfilters_idx = + g_hash_table_new((GHashFunc) nmp_object_id_hash, (GEqualFunc) nmp_object_id_equal); + + if (known_tfilters) { + for (i = 0; i < known_tfilters->len; i++) { + const NMPObject *q = g_ptr_array_index(known_tfilters, i); + + g_hash_table_insert(known_tfilters_idx, (gpointer) q, (gpointer) q); + } + } + + plat_tfilters = + nm_platform_lookup_clone(self, + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_TFILTER, ifindex), + NULL, + NULL); + + if (plat_tfilters) { + for (i = 0; i < plat_tfilters->len; i++) { + const NMPObject *q = g_ptr_array_index(plat_tfilters, i); + + if (!g_hash_table_lookup(known_tfilters_idx, q)) + success &= nm_platform_object_delete(self, q); + } + } + + if (known_tfilters) { + for (i = 0; i < known_tfilters->len; i++) { + const NMPObject *q = g_ptr_array_index(known_tfilters, i); + + success &= + (nm_platform_tfilter_add(self, NMP_NLM_FLAG_ADD, NMP_OBJECT_CAST_TFILTER(q)) >= 0); + } + } + + return success; +} + +/*****************************************************************************/ + +const char * +nm_platform_vlan_qos_mapping_to_string(const char * name, + const NMVlanQosMapping *map, + gsize n_map, + char * buf, + gsize len) +{ + gsize i; + char *b; + + nm_utils_to_string_buffer_init(&buf, &len); + + if (!n_map) { + nm_utils_strbuf_append_str(&buf, &len, ""); + return buf; + } + + if (!map) + g_return_val_if_reached(""); + + b = buf; + + if (name) { + nm_utils_strbuf_append_str(&b, &len, name); + nm_utils_strbuf_append_str(&b, &len, " {"); + } else + nm_utils_strbuf_append_c(&b, &len, '{'); + + for (i = 0; i < n_map; i++) + nm_utils_strbuf_append(&b, &len, " %u:%u", map[i].from, map[i].to); + nm_utils_strbuf_append_str(&b, &len, " }"); + return buf; +} + +static const char * +_lifetime_to_string(guint32 timestamp, guint32 lifetime, gint32 now, char *buf, size_t buf_size) +{ + if (lifetime == NM_PLATFORM_LIFETIME_PERMANENT) + return "forever"; + + g_snprintf(buf, + buf_size, + "%usec", + nmp_utils_lifetime_rebase_relative_time_on_now(timestamp, lifetime, now)); + return buf; +} + +static const char * +_lifetime_summary_to_string(gint32 now, + guint32 timestamp, + guint32 preferred, + guint32 lifetime, + char * buf, + size_t buf_size) +{ + g_snprintf(buf, + buf_size, + " lifetime %d-%u[%u,%u]", + (signed) now, + (unsigned) timestamp, + (unsigned) preferred, + (unsigned) lifetime); + return buf; +} + +/** + * nm_platform_link_to_string: + * @route: pointer to NMPlatformLink address structure + * @buf: (allow-none): an optional buffer. If %NULL, a static buffer is used. + * @len: the size of the @buf. If @buf is %NULL, this argument is ignored. + * + * A method for converting an link struct into a string representation. + * + * Returns: a string representation of the link. + */ +const char * +nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len) +{ + char master[20]; + char parent[20]; + char str_flags[1 + NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN + 1]; + char str_highlighted_flags[50]; + char * s; + gsize l; + char str_addrmode[30]; + char str_address[_NM_UTILS_HWADDR_LEN_MAX * 3]; + char str_broadcast[_NM_UTILS_HWADDR_LEN_MAX * 3]; + char str_inet6_token[NM_UTILS_INET_ADDRSTRLEN]; + const char *str_link_type; + + if (!nm_utils_to_string_buffer_init_null(link, &buf, &len)) + return buf; + + s = str_highlighted_flags; + l = sizeof(str_highlighted_flags); + if (NM_FLAGS_HAS(link->n_ifi_flags, IFF_NOARP)) + nm_utils_strbuf_append_str(&s, &l, "NOARP,"); + if (NM_FLAGS_HAS(link->n_ifi_flags, IFF_UP)) + nm_utils_strbuf_append_str(&s, &l, "UP"); + else + nm_utils_strbuf_append_str(&s, &l, "DOWN"); + if (link->connected) + nm_utils_strbuf_append_str(&s, &l, ",LOWER_UP"); + nm_assert(s > str_highlighted_flags && l > 0); + + if (link->n_ifi_flags) { + str_flags[0] = ';'; + nm_platform_link_flags2str(link->n_ifi_flags, &str_flags[1], sizeof(str_flags) - 1); + } else + str_flags[0] = '\0'; + + if (link->master) + g_snprintf(master, sizeof(master), " master %d", link->master); + else + master[0] = 0; + + if (link->parent > 0) + g_snprintf(parent, sizeof(parent), "@%d", link->parent); + else if (link->parent == NM_PLATFORM_LINK_OTHER_NETNS) + g_strlcpy(parent, "@other-netns", sizeof(parent)); + else + parent[0] = 0; + + _nmp_link_address_to_string(&link->l_address, str_address); + _nmp_link_address_to_string(&link->l_broadcast, str_broadcast); + + str_link_type = nm_link_type_to_string(link->type); + + g_snprintf( + buf, + len, + "%d: " /* ifindex */ + "%s" /* name */ + "%s" /* parent */ + " <%s%s>" /* flags */ + " mtu %d" + "%s" /* master */ + " arp %u" /* arptype */ + " %s" /* link->type */ + "%s%s" /* kind */ + "%s" /* is-in-udev */ + "%s%s" /* addr-gen-mode */ + "%s%s" /* l_address */ + "%s%s" /* l_broadcast */ + "%s%s" /* inet6_token */ + "%s%s" /* driver */ + " rx:%" G_GUINT64_FORMAT ",%" G_GUINT64_FORMAT " tx:%" G_GUINT64_FORMAT + ",%" G_GUINT64_FORMAT, + link->ifindex, + link->name, + parent, + str_highlighted_flags, + str_flags, + link->mtu, + master, + link->arptype, + str_link_type ?: "???", + link->kind ? (g_strcmp0(str_link_type, link->kind) ? "/" : "*") : "?", + link->kind && g_strcmp0(str_link_type, link->kind) ? link->kind : "", + link->initialized ? " init" : " not-init", + link->inet6_addr_gen_mode_inv ? " addrgenmode " : "", + link->inet6_addr_gen_mode_inv ? nm_platform_link_inet6_addrgenmode2str( + _nm_platform_uint8_inv(link->inet6_addr_gen_mode_inv), + str_addrmode, + sizeof(str_addrmode)) + : "", + str_address[0] ? " addr " : "", + str_address[0] ? str_address : "", + str_broadcast[0] ? " brd " : "", + str_broadcast[0] ? str_broadcast : "", + link->inet6_token.id ? " inet6token " : "", + link->inet6_token.id + ? nm_utils_inet6_interface_identifier_to_token(link->inet6_token, str_inet6_token) + : "", + link->driver ? " driver " : "", + link->driver ?: "", + link->rx_packets, + link->rx_bytes, + link->tx_packets, + link->tx_bytes); + return buf; +} + +const NMPlatformLnkBridge nm_platform_lnk_bridge_default = { + .forward_delay = NM_BRIDGE_FORWARD_DELAY_DEF_SYS, + .hello_time = NM_BRIDGE_HELLO_TIME_DEF_SYS, + .max_age = NM_BRIDGE_MAX_AGE_DEF_SYS, + .ageing_time = NM_BRIDGE_AGEING_TIME_DEF_SYS, + .stp_state = FALSE, + .priority = NM_BRIDGE_PRIORITY_DEF, + .vlan_protocol = 0x8100, + .vlan_stats_enabled = NM_BRIDGE_VLAN_STATS_ENABLED_DEF, + .group_fwd_mask = 0, + .group_addr = NM_ETHER_ADDR_INIT(NM_BRIDGE_GROUP_ADDRESS_DEF_BIN), + .mcast_snooping = NM_BRIDGE_MULTICAST_SNOOPING_DEF, + .mcast_router = 1, + .mcast_query_use_ifaddr = NM_BRIDGE_MULTICAST_QUERY_USE_IFADDR_DEF, + .mcast_querier = NM_BRIDGE_MULTICAST_QUERIER_DEF, + .mcast_hash_max = NM_BRIDGE_MULTICAST_HASH_MAX_DEF, + .mcast_last_member_count = NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF, + .mcast_startup_query_count = NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF, + .mcast_last_member_interval = NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF, + .mcast_membership_interval = NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF, + .mcast_querier_interval = NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF, + .mcast_query_interval = NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF, + .mcast_query_response_interval = NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF, + .mcast_startup_query_interval = NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF, +}; + +const char * +nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsize len) +{ + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf(buf, + len, + "forward_delay %u" + " hello_time %u" + " max_age %u" + " ageing_time %u" + " stp_state %d" + " priority %u" + " vlan_protocol %u" + " vlan_stats_enabled %d" + " group_fwd_mask %#x" + " group_address " NM_ETHER_ADDR_FORMAT_STR " mcast_snooping %d" + " mcast_router %u" + " mcast_query_use_ifaddr %d" + " mcast_querier %d" + " mcast_hash_max %u" + " mcast_last_member_count %u" + " mcast_startup_query_count %u" + " mcast_last_member_interval %" G_GUINT64_FORMAT + " mcast_membership_interval %" G_GUINT64_FORMAT + " mcast_querier_interval %" G_GUINT64_FORMAT + " mcast_query_interval %" G_GUINT64_FORMAT + " mcast_query_response_interval %" G_GUINT64_FORMAT + " mcast_startup_query_interval %" G_GUINT64_FORMAT "", + lnk->forward_delay, + lnk->hello_time, + lnk->max_age, + lnk->ageing_time, + (int) lnk->stp_state, + lnk->priority, + lnk->vlan_protocol, + (int) lnk->vlan_stats_enabled, + lnk->group_fwd_mask, + NM_ETHER_ADDR_FORMAT_VAL(&lnk->group_addr), + (int) lnk->mcast_snooping, + lnk->mcast_router, + (int) lnk->mcast_query_use_ifaddr, + (int) lnk->mcast_querier, + lnk->mcast_hash_max, + lnk->mcast_last_member_count, + lnk->mcast_startup_query_count, + lnk->mcast_last_member_interval, + lnk->mcast_membership_interval, + lnk->mcast_querier_interval, + lnk->mcast_query_interval, + lnk->mcast_query_response_interval, + lnk->mcast_startup_query_interval); + return buf; +} + +const char * +nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len) +{ + char str_local[30]; + char str_local1[NM_UTILS_INET_ADDRSTRLEN]; + char str_remote[30]; + char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; + char str_ttl[30]; + char str_tos[30]; + char str_parent_ifindex[30]; + char str_input_flags[30]; + char str_output_flags[30]; + char str_input_key[30]; + char str_input_key1[NM_UTILS_INET_ADDRSTRLEN]; + char str_output_key[30]; + char str_output_key1[NM_UTILS_INET_ADDRSTRLEN]; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf( + buf, + len, + "gre%s" /* is_tap */ + "%s" /* remote */ + "%s" /* local */ + "%s" /* parent_ifindex */ + "%s" /* ttl */ + "%s" /* tos */ + "%s" /* path_mtu_discovery */ + "%s" /* iflags */ + "%s" /* oflags */ + "%s" /* ikey */ + "%s" /* okey */ + "", + lnk->is_tap ? "tap" : "", + lnk->remote ? nm_sprintf_buf(str_remote, + " remote %s", + _nm_utils_inet4_ntop(lnk->remote, str_remote1)) + : "", + lnk->local + ? nm_sprintf_buf(str_local, " local %s", _nm_utils_inet4_ntop(lnk->local, str_local1)) + : "", + lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex) + : "", + lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", + lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos 0x%x", lnk->tos)) + : "", + lnk->path_mtu_discovery ? "" : " nopmtudisc", + lnk->input_flags ? nm_sprintf_buf(str_input_flags, " iflags 0x%x", lnk->input_flags) : "", + lnk->output_flags ? nm_sprintf_buf(str_output_flags, " oflags 0x%x", lnk->output_flags) + : "", + NM_FLAGS_HAS(lnk->input_flags, GRE_KEY) || lnk->input_key + ? nm_sprintf_buf(str_input_key, + " ikey %s", + _nm_utils_inet4_ntop(lnk->input_key, str_input_key1)) + : "", + NM_FLAGS_HAS(lnk->output_flags, GRE_KEY) || lnk->output_key + ? nm_sprintf_buf(str_output_key, + " okey %s", + _nm_utils_inet4_ntop(lnk->output_key, str_output_key1)) + : ""); + return buf; +} + +const char * +nm_platform_lnk_infiniband_to_string(const NMPlatformLnkInfiniband *lnk, char *buf, gsize len) +{ + char str_p_key[64]; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf(buf, + len, + "infiniband" + "%s" /* p_key */ + "%s%s" /* mode */ + "", + lnk->p_key ? nm_sprintf_buf(str_p_key, " pkey %d", lnk->p_key) : "", + lnk->mode ? " mode " : "", + lnk->mode ?: ""); + return buf; +} + +const char * +nm_platform_lnk_ip6tnl_to_string(const NMPlatformLnkIp6Tnl *lnk, char *buf, gsize len) +{ + char str_local[30]; + char str_local1[NM_UTILS_INET_ADDRSTRLEN]; + char str_remote[30]; + char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; + char str_ttl[30]; + char str_tclass[30]; + char str_flow[30]; + char str_encap[30]; + char str_proto[30]; + char str_parent_ifindex[30]; + char *str_type; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + if (lnk->is_gre) + str_type = lnk->is_tap ? "ip6gretap" : "ip6gre"; + else + str_type = "ip6tnl"; + + g_snprintf( + buf, + len, + "%s" /* type */ + "%s" /* remote */ + "%s" /* local */ + "%s" /* parent_ifindex */ + "%s" /* ttl */ + "%s" /* tclass */ + "%s" /* encap limit */ + "%s" /* flow label */ + "%s" /* proto */ + " flags 0x%x" + "", + str_type, + nm_sprintf_buf(str_remote, " remote %s", _nm_utils_inet6_ntop(&lnk->remote, str_remote1)), + nm_sprintf_buf(str_local, " local %s", _nm_utils_inet6_ntop(&lnk->local, str_local1)), + lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex) + : "", + lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", + lnk->tclass == 1 ? " tclass inherit" + : nm_sprintf_buf(str_tclass, " tclass 0x%x", lnk->tclass), + nm_sprintf_buf(str_encap, " encap-limit %u", lnk->encap_limit), + nm_sprintf_buf(str_flow, " flow-label 0x05%x", lnk->flow_label), + nm_sprintf_buf(str_proto, " proto %u", lnk->proto), + (guint) lnk->flags); + return buf; +} + +const char * +nm_platform_lnk_ipip_to_string(const NMPlatformLnkIpIp *lnk, char *buf, gsize len) +{ + char str_local[30]; + char str_local1[NM_UTILS_INET_ADDRSTRLEN]; + char str_remote[30]; + char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; + char str_ttl[30]; + char str_tos[30]; + char str_parent_ifindex[30]; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf( + buf, + len, + "ipip" + "%s" /* remote */ + "%s" /* local */ + "%s" /* parent_ifindex */ + "%s" /* ttl */ + "%s" /* tos */ + "%s" /* path_mtu_discovery */ + "", + lnk->remote ? nm_sprintf_buf(str_remote, + " remote %s", + _nm_utils_inet4_ntop(lnk->remote, str_remote1)) + : "", + lnk->local + ? nm_sprintf_buf(str_local, " local %s", _nm_utils_inet4_ntop(lnk->local, str_local1)) + : "", + lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex) + : "", + lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", + lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos 0x%x", lnk->tos)) + : "", + lnk->path_mtu_discovery ? "" : " nopmtudisc"); + return buf; +} + +const char * +nm_platform_lnk_macsec_to_string(const NMPlatformLnkMacsec *lnk, char *buf, gsize len) +{ + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf(buf, + len, + "macsec " + "sci %016llx " + "protect %s " + "cipher %016llx " + "icvlen %u " + "encodingsa %u " + "validate %u " + "encrypt %s " + "send_sci %s " + "end_station %s " + "scb %s " + "replay %s", + (unsigned long long) lnk->sci, + lnk->protect ? "on" : "off", + (unsigned long long) lnk->cipher_suite, + lnk->icv_length, + lnk->encoding_sa, + lnk->validation, + lnk->encrypt ? "on" : "off", + lnk->include_sci ? "on" : "off", + lnk->es ? "on" : "off", + lnk->scb ? "on" : "off", + lnk->replay_protect ? "on" : "off"); + return buf; +} + +const char * +nm_platform_lnk_macvlan_to_string(const NMPlatformLnkMacvlan *lnk, char *buf, gsize len) +{ + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf(buf, + len, + "%s mode %u %s", + lnk->tap ? "macvtap" : "macvlan", + lnk->mode, + lnk->no_promisc ? "not-promisc" : "promisc"); + return buf; +} + +const char * +nm_platform_lnk_sit_to_string(const NMPlatformLnkSit *lnk, char *buf, gsize len) +{ + char str_local[30]; + char str_local1[NM_UTILS_INET_ADDRSTRLEN]; + char str_remote[30]; + char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; + char str_ttl[30]; + char str_tos[30]; + char str_flags[30]; + char str_proto[30]; + char str_parent_ifindex[30]; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf( + buf, + len, + "sit" + "%s" /* remote */ + "%s" /* local */ + "%s" /* parent_ifindex */ + "%s" /* ttl */ + "%s" /* tos */ + "%s" /* path_mtu_discovery */ + "%s" /* flags */ + "%s" /* proto */ + "", + lnk->remote ? nm_sprintf_buf(str_remote, + " remote %s", + _nm_utils_inet4_ntop(lnk->remote, str_remote1)) + : "", + lnk->local + ? nm_sprintf_buf(str_local, " local %s", _nm_utils_inet4_ntop(lnk->local, str_local1)) + : "", + lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex) + : "", + lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", + lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos 0x%x", lnk->tos)) + : "", + lnk->path_mtu_discovery ? "" : " nopmtudisc", + lnk->flags ? nm_sprintf_buf(str_flags, " flags 0x%x", lnk->flags) : "", + lnk->proto ? nm_sprintf_buf(str_proto, " proto 0x%x", lnk->proto) : ""); + return buf; +} + +const char * +nm_platform_lnk_tun_to_string(const NMPlatformLnkTun *lnk, char *buf, gsize len) +{ + char str_owner[50]; + char str_group[50]; + char str_type[50]; + const char *type; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + if (lnk->type == IFF_TUN) + type = "tun"; + else if (lnk->type == IFF_TAP) + type = "tap"; + else + type = nm_sprintf_buf(str_type, "tun type %u", (guint) lnk->type); + + g_snprintf(buf, + len, + "%s" /* type */ + "%s" /* pi */ + "%s" /* vnet_hdr */ + "%s" /* multi_queue */ + "%s" /* persist */ + "%s" /* owner */ + "%s" /* group */ + "", + type, + lnk->pi ? " pi" : "", + lnk->vnet_hdr ? " vnet_hdr" : "", + lnk->multi_queue ? " multi_queue" : "", + lnk->persist ? " persist" : "", + lnk->owner_valid ? nm_sprintf_buf(str_owner, " owner %u", (guint) lnk->owner) : "", + lnk->group_valid ? nm_sprintf_buf(str_group, " group %u", (guint) lnk->group) : ""); + return buf; +} + +const char * +nm_platform_lnk_vlan_to_string(const NMPlatformLnkVlan *lnk, char *buf, gsize len) +{ + char *b; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + b = buf; + + nm_utils_strbuf_append(&b, &len, "vlan %u", lnk->id); + if (lnk->flags) + nm_utils_strbuf_append(&b, &len, " flags 0x%x", lnk->flags); + return buf; +} + +const char * +nm_platform_lnk_vrf_to_string(const NMPlatformLnkVrf *lnk, char *buf, gsize len) +{ + char *b; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + b = buf; + + nm_utils_strbuf_append(&b, &len, "table %u", lnk->table); + return buf; +} + +const char * +nm_platform_lnk_vxlan_to_string(const NMPlatformLnkVxlan *lnk, char *buf, gsize len) +{ + char str_group[100]; + char str_group6[100]; + char str_local[100]; + char str_local6[100]; + char str_dev[25]; + char str_limit[25]; + char str_src_port[35]; + char str_dst_port[25]; + char str_tos[25]; + char str_ttl[25]; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + if (lnk->group == 0) + str_group[0] = '\0'; + else { + g_snprintf(str_group, + sizeof(str_group), + " %s %s", + IN_MULTICAST(ntohl(lnk->group)) ? "group" : "remote", + _nm_utils_inet4_ntop(lnk->group, sbuf)); + } + if (IN6_IS_ADDR_UNSPECIFIED(&lnk->group6)) + str_group6[0] = '\0'; + else { + g_snprintf(str_group6, + sizeof(str_group6), + " %s%s %s", + IN6_IS_ADDR_MULTICAST(&lnk->group6) ? "group" : "remote", + str_group[0] ? "6" : "", /* usually, a vxlan has either v4 or v6 only. */ + _nm_utils_inet6_ntop(&lnk->group6, sbuf)); + } + + if (lnk->local == 0) + str_local[0] = '\0'; + else { + g_snprintf(str_local, + sizeof(str_local), + " local %s", + _nm_utils_inet4_ntop(lnk->local, sbuf)); + } + if (IN6_IS_ADDR_UNSPECIFIED(&lnk->local6)) + str_local6[0] = '\0'; + else { + g_snprintf(str_local6, + sizeof(str_local6), + " local%s %s", + str_local[0] ? "6" : "", /* usually, a vxlan has either v4 or v6 only. */ + _nm_utils_inet6_ntop(&lnk->local6, sbuf)); + } + + g_snprintf( + buf, + len, + "vxlan" + " id %u" /* id */ + "%s%s" /* group/group6 */ + "%s%s" /* local/local6 */ + "%s" /* dev */ + "%s" /* src_port_min/src_port_max */ + "%s" /* dst_port */ + "%s" /* learning */ + "%s" /* proxy */ + "%s" /* rsc */ + "%s" /* l2miss */ + "%s" /* l3miss */ + "%s" /* tos */ + "%s" /* ttl */ + " ageing %u" /* ageing */ + "%s" /* limit */ + "", + (guint) lnk->id, + str_group, + str_group6, + str_local, + str_local6, + lnk->parent_ifindex ? nm_sprintf_buf(str_dev, " dev %d", lnk->parent_ifindex) : "", + lnk->src_port_min || lnk->src_port_max + ? nm_sprintf_buf(str_src_port, " srcport %u %u", lnk->src_port_min, lnk->src_port_max) + : "", + lnk->dst_port ? nm_sprintf_buf(str_dst_port, " dstport %u", lnk->dst_port) : "", + !lnk->learning ? " nolearning" : "", + lnk->proxy ? " proxy" : "", + lnk->rsc ? " rsc" : "", + lnk->l2miss ? " l2miss" : "", + lnk->l3miss ? " l3miss" : "", + lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos %#x", lnk->tos), + lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : "", + lnk->ageing, + lnk->limit ? nm_sprintf_buf(str_limit, " maxaddr %u", lnk->limit) : ""); + return buf; +} + +const char * +nm_platform_wireguard_peer_to_string(const NMPWireGuardPeer *peer, char *buf, gsize len) +{ + char * buf0 = buf; + gs_free char *public_key_b64 = NULL; + char s_sockaddr[NM_UTILS_INET_ADDRSTRLEN + 100]; + char s_endpoint[20 + sizeof(s_sockaddr)]; + char s_addr[NM_UTILS_INET_ADDRSTRLEN]; + char s_keepalive[100]; + guint i; + + nm_utils_to_string_buffer_init(&buf, &len); + + public_key_b64 = g_base64_encode(peer->public_key, sizeof(peer->public_key)); + + if (peer->endpoint.sa.sa_family != AF_UNSPEC) { + nm_sprintf_buf( + s_endpoint, + " endpoint %s", + nm_sock_addr_union_to_string(&peer->endpoint, s_sockaddr, sizeof(s_sockaddr))); + } else + s_endpoint[0] = '\0'; + + nm_utils_strbuf_append( + &buf, + &len, + "public-key %s" + "%s" /* preshared-key */ + "%s" /* endpoint */ + " rx %" G_GUINT64_FORMAT " tx %" G_GUINT64_FORMAT "%s" /* persistent-keepalive */ + "%s", /* allowed-ips */ + public_key_b64, + nm_utils_memeqzero_secret(peer->preshared_key, sizeof(peer->preshared_key)) + ? "" + : " preshared-key (hidden)", + s_endpoint, + peer->rx_bytes, + peer->tx_bytes, + peer->persistent_keepalive_interval > 0 + ? nm_sprintf_buf(s_keepalive, + " keepalive %u", + (guint) peer->persistent_keepalive_interval) + : "", + peer->allowed_ips_len > 0 ? " allowed-ips" : ""); + + for (i = 0; i < peer->allowed_ips_len; i++) { + const NMPWireGuardAllowedIP *allowed_ip = &peer->allowed_ips[i]; + + nm_utils_strbuf_append(&buf, + &len, + " %s/%u", + nm_utils_inet_ntop(allowed_ip->family, &allowed_ip->addr, s_addr), + allowed_ip->mask); + } + + return buf0; +} + +const char * +nm_platform_lnk_wireguard_to_string(const NMPlatformLnkWireGuard *lnk, char *buf, gsize len) +{ + gs_free char *public_b64 = NULL; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + if (!nm_utils_memeqzero(lnk->public_key, sizeof(lnk->public_key))) + public_b64 = g_base64_encode(lnk->public_key, sizeof(lnk->public_key)); + + g_snprintf(buf, + len, + "wireguard" + "%s%s" /* public-key */ + "%s" /* private-key */ + " listen-port %u" + " fwmark 0x%x", + public_b64 ? " public-key " : "", + public_b64 ?: "", + nm_utils_memeqzero_secret(lnk->private_key, sizeof(lnk->private_key)) + ? "" + : " private-key (hidden)", + lnk->listen_port, + lnk->fwmark); + + return buf; +} + +/** + * nm_platform_ip4_address_to_string: + * @route: pointer to NMPlatformIP4Address address structure + * @buf: (allow-none): an optional buffer. If %NULL, a static buffer is used. + * @len: the size of the @buf. If @buf is %NULL, this argument is ignored. + * + * A method for converting an address struct into a string representation. + * + * Example output: "" + * + * Returns: a string representation of the address. + */ +const char * +nm_platform_ip4_address_to_string(const NMPlatformIP4Address *address, char *buf, gsize len) +{ + char s_flags[TO_STRING_IFA_FLAGS_BUF_SIZE]; + char s_address[INET_ADDRSTRLEN]; + char s_peer[INET_ADDRSTRLEN]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_label[32]; + char str_lft[30], str_pref[30], str_time[50], s_source[50]; + char * str_peer = NULL; + const char *str_lft_p, *str_pref_p, *str_time_p; + gint32 now = nm_utils_get_monotonic_timestamp_sec(); + in_addr_t broadcast_address; + char str_broadcast[INET_ADDRSTRLEN]; + + if (!nm_utils_to_string_buffer_init_null(address, &buf, &len)) + return buf; + + inet_ntop(AF_INET, &address->address, s_address, sizeof(s_address)); + + if (address->peer_address != address->address) { + inet_ntop(AF_INET, &address->peer_address, s_peer, sizeof(s_peer)); + str_peer = g_strconcat(" ptp ", s_peer, NULL); + } + + _to_string_dev(NULL, address->ifindex, str_dev, sizeof(str_dev)); + + if (*address->label) + g_snprintf(str_label, sizeof(str_label), " label %s", address->label); + else + str_label[0] = 0; + + str_lft_p = _lifetime_to_string(address->timestamp, + address->lifetime ?: NM_PLATFORM_LIFETIME_PERMANENT, + now, + str_lft, + sizeof(str_lft)), + str_pref_p = + (address->lifetime == address->preferred) + ? str_lft_p + : (_lifetime_to_string(address->timestamp, + address->lifetime ? MIN(address->preferred, address->lifetime) + : NM_PLATFORM_LIFETIME_PERMANENT, + now, + str_pref, + sizeof(str_pref))); + str_time_p = _lifetime_summary_to_string(now, + address->timestamp, + address->preferred, + address->lifetime, + str_time, + sizeof(str_time)); + + broadcast_address = nm_platform_ip4_broadcast_address_from_addr(address); + + g_snprintf( + buf, + len, + "%s/%d" + "%s%s" /* broadcast */ + " lft %s" + " pref %s" + "%s" /* time */ + "%s" /* peer */ + "%s" /* dev */ + "%s" /* flags */ + "%s" /* label */ + " src %s" + "%s" /* external */ + "%s" /* ip4acd_not_ready */ + "", + s_address, + address->plen, + broadcast_address != 0u || address->use_ip4_broadcast_address + ? (address->use_ip4_broadcast_address ? " brd " : " brd* ") + : "", + broadcast_address != 0u || address->use_ip4_broadcast_address + ? _nm_utils_inet4_ntop(broadcast_address, str_broadcast) + : "", + str_lft_p, + str_pref_p, + str_time_p, + str_peer ?: "", + str_dev, + _to_string_ifa_flags(address->n_ifa_flags, s_flags, sizeof(s_flags)), + str_label, + nmp_utils_ip_config_source_to_string(address->addr_source, s_source, sizeof(s_source)), + address->external ? " ext" : "", + address->ip4acd_not_ready ? " ip4acd-not-ready" : ""); + g_free(str_peer); + return buf; +} + +NM_UTILS_FLAGS2STR_DEFINE(nm_platform_link_flags2str, + unsigned, + NM_UTILS_FLAGS2STR(IFF_LOOPBACK, "loopback"), + NM_UTILS_FLAGS2STR(IFF_BROADCAST, "broadcast"), + NM_UTILS_FLAGS2STR(IFF_POINTOPOINT, "pointopoint"), + NM_UTILS_FLAGS2STR(IFF_MULTICAST, "multicast"), + NM_UTILS_FLAGS2STR(IFF_NOARP, "noarp"), + NM_UTILS_FLAGS2STR(IFF_ALLMULTI, "allmulti"), + NM_UTILS_FLAGS2STR(IFF_PROMISC, "promisc"), + NM_UTILS_FLAGS2STR(IFF_MASTER, "master"), + NM_UTILS_FLAGS2STR(IFF_SLAVE, "slave"), + NM_UTILS_FLAGS2STR(IFF_DEBUG, "debug"), + NM_UTILS_FLAGS2STR(IFF_DYNAMIC, "dynamic"), + NM_UTILS_FLAGS2STR(IFF_AUTOMEDIA, "automedia"), + NM_UTILS_FLAGS2STR(IFF_PORTSEL, "portsel"), + NM_UTILS_FLAGS2STR(IFF_NOTRAILERS, "notrailers"), + NM_UTILS_FLAGS2STR(IFF_UP, "up"), + NM_UTILS_FLAGS2STR(IFF_RUNNING, "running"), + NM_UTILS_FLAGS2STR(IFF_LOWER_UP, "lowerup"), + NM_UTILS_FLAGS2STR(IFF_DORMANT, "dormant"), + NM_UTILS_FLAGS2STR(IFF_ECHO, "echo"), ); + +NM_UTILS_ENUM2STR_DEFINE(nm_platform_link_inet6_addrgenmode2str, + guint8, + NM_UTILS_ENUM2STR(NM_IN6_ADDR_GEN_MODE_NONE, "none"), + NM_UTILS_ENUM2STR(NM_IN6_ADDR_GEN_MODE_EUI64, "eui64"), + NM_UTILS_ENUM2STR(NM_IN6_ADDR_GEN_MODE_STABLE_PRIVACY, "stable-privacy"), + NM_UTILS_ENUM2STR(NM_IN6_ADDR_GEN_MODE_RANDOM, "random"), ); + +NM_UTILS_FLAGS2STR_DEFINE(nm_platform_addr_flags2str, + unsigned, + NM_UTILS_FLAGS2STR(IFA_F_SECONDARY, "secondary"), + NM_UTILS_FLAGS2STR(IFA_F_NODAD, "nodad"), + NM_UTILS_FLAGS2STR(IFA_F_OPTIMISTIC, "optimistic"), + NM_UTILS_FLAGS2STR(IFA_F_HOMEADDRESS, "homeaddress"), + NM_UTILS_FLAGS2STR(IFA_F_DEPRECATED, "deprecated"), + NM_UTILS_FLAGS2STR(IFA_F_PERMANENT, "permanent"), + NM_UTILS_FLAGS2STR(IFA_F_MANAGETEMPADDR, "mngtmpaddr"), + NM_UTILS_FLAGS2STR(IFA_F_NOPREFIXROUTE, "noprefixroute"), + NM_UTILS_FLAGS2STR(IFA_F_TENTATIVE, "tentative"), ); + +NM_UTILS_ENUM2STR_DEFINE(nm_platform_route_scope2str, + int, + NM_UTILS_ENUM2STR(RT_SCOPE_NOWHERE, "nowhere"), + NM_UTILS_ENUM2STR(RT_SCOPE_HOST, "host"), + NM_UTILS_ENUM2STR(RT_SCOPE_LINK, "link"), + NM_UTILS_ENUM2STR(RT_SCOPE_SITE, "site"), + NM_UTILS_ENUM2STR(RT_SCOPE_UNIVERSE, "global"), ); + +/** + * nm_platform_ip6_address_to_string: + * @route: pointer to NMPlatformIP6Address address structure + * @buf: (allow-none): an optional buffer. If %NULL, a static buffer is used. + * @len: the size of the @buf. If @buf is %NULL, this argument is ignored. + * + * A method for converting an address struct into a string representation. + * + * Example output: "2001:db8:0:f101::1/64 lft 4294967295 pref 4294967295 time 16922666 on dev em1" + * + * Returns: a string representation of the address. + */ +const char * +nm_platform_ip6_address_to_string(const NMPlatformIP6Address *address, char *buf, gsize len) +{ + char s_flags[TO_STRING_IFA_FLAGS_BUF_SIZE]; + char s_address[INET6_ADDRSTRLEN]; + char s_peer[INET6_ADDRSTRLEN]; + char str_lft[30], str_pref[30], str_time[50], s_source[50]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char * str_peer = NULL; + const char *str_lft_p, *str_pref_p, *str_time_p; + gint32 now = nm_utils_get_monotonic_timestamp_sec(); + + if (!nm_utils_to_string_buffer_init_null(address, &buf, &len)) + return buf; + + inet_ntop(AF_INET6, &address->address, s_address, sizeof(s_address)); + + if (!IN6_IS_ADDR_UNSPECIFIED(&address->peer_address)) { + inet_ntop(AF_INET6, &address->peer_address, s_peer, sizeof(s_peer)); + str_peer = g_strconcat(" ptp ", s_peer, NULL); + } + + _to_string_dev(NULL, address->ifindex, str_dev, sizeof(str_dev)); + + str_lft_p = _lifetime_to_string(address->timestamp, + address->lifetime ?: NM_PLATFORM_LIFETIME_PERMANENT, + now, + str_lft, + sizeof(str_lft)), + str_pref_p = + (address->lifetime == address->preferred) + ? str_lft_p + : (_lifetime_to_string(address->timestamp, + address->lifetime ? MIN(address->preferred, address->lifetime) + : NM_PLATFORM_LIFETIME_PERMANENT, + now, + str_pref, + sizeof(str_pref))); + str_time_p = _lifetime_summary_to_string(now, + address->timestamp, + address->preferred, + address->lifetime, + str_time, + sizeof(str_time)); + + g_snprintf( + buf, + len, + "%s/%d lft %s pref %s%s%s%s%s src %s%s", + s_address, + address->plen, + str_lft_p, + str_pref_p, + str_time_p, + str_peer ?: "", + str_dev, + _to_string_ifa_flags(address->n_ifa_flags, s_flags, sizeof(s_flags)), + nmp_utils_ip_config_source_to_string(address->addr_source, s_source, sizeof(s_source)), + address->external ? " ext" : ""); + g_free(str_peer); + return buf; +} + +static NM_UTILS_FLAGS2STR_DEFINE(_rtm_flags_to_string, + unsigned, + NM_UTILS_FLAGS2STR(RTNH_F_DEAD, "dead"), + NM_UTILS_FLAGS2STR(RTNH_F_PERVASIVE, "pervasive"), + NM_UTILS_FLAGS2STR(RTNH_F_ONLINK, "onlink"), + NM_UTILS_FLAGS2STR(8 /*RTNH_F_OFFLOAD*/, "offload"), + NM_UTILS_FLAGS2STR(16 /*RTNH_F_LINKDOWN*/, "linkdown"), + NM_UTILS_FLAGS2STR(32 /*RTNH_F_UNRESOLVED*/, "unresolved"), + + NM_UTILS_FLAGS2STR(RTM_F_NOTIFY, "notify"), + NM_UTILS_FLAGS2STR(RTM_F_CLONED, "cloned"), + NM_UTILS_FLAGS2STR(RTM_F_EQUALIZE, "equalize"), + NM_UTILS_FLAGS2STR(RTM_F_PREFIX, "prefix"), + NM_UTILS_FLAGS2STR(0x1000 /*RTM_F_LOOKUP_TABLE*/, "lookup-table"), + NM_UTILS_FLAGS2STR(0x2000 /*RTM_F_FIB_MATCH*/, "fib-match"), ); + +#define _RTM_FLAGS_TO_STRING_MAXLEN 200 + +static const char * +_rtm_flags_to_string_full(char *buf, gsize buf_size, unsigned rtm_flags) +{ + const char *buf0 = buf; + + nm_assert(buf_size >= _RTM_FLAGS_TO_STRING_MAXLEN); + + if (!rtm_flags) + return ""; + + nm_utils_strbuf_append_str(&buf, &buf_size, " rtm_flags "); + _rtm_flags_to_string(rtm_flags, buf, buf_size); + nm_assert(strlen(buf) < buf_size); + return buf0; +} + +/** + * nm_platform_ip4_route_to_string: + * @route: pointer to NMPlatformIP4Route route structure + * @buf: (allow-none): an optional buffer. If %NULL, a static buffer is used. + * @len: the size of the @buf. If @buf is %NULL, this argument is ignored. + * + * A method for converting a route struct into a string representation. + * + * Example output: "192.168.1.0/24 via 0.0.0.0 dev em1 metric 0 mss 0" + * + * Returns: a string representation of the route. + */ +const char * +nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsize len) +{ + char s_network[INET_ADDRSTRLEN], s_gateway[INET_ADDRSTRLEN]; + char s_pref_src[INET_ADDRSTRLEN]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_table[30]; + char str_scope[30], s_source[50]; + char str_tos[32], str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32]; + char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN]; + char str_type[30]; + char str_metric[30]; + + if (!nm_utils_to_string_buffer_init_null(route, &buf, &len)) + return buf; + + inet_ntop(AF_INET, &route->network, s_network, sizeof(s_network)); + inet_ntop(AF_INET, &route->gateway, s_gateway, sizeof(s_gateway)); + + _to_string_dev(NULL, route->ifindex, str_dev, sizeof(str_dev)); + + g_snprintf( + buf, + len, + "type %s " /* type */ + "%s" /* table */ + "%s/%d" + " via %s" + "%s" + " metric %s" + " mss %" G_GUINT32_FORMAT " rt-src %s" /* protocol */ + "%s" /* rtm_flags */ + "%s%s" /* scope */ + "%s%s" /* pref-src */ + "%s" /* tos */ + "%s" /* window */ + "%s" /* cwnd */ + "%s" /* initcwnd */ + "%s" /* initrwnd */ + "%s" /* mtu */ + "", + nm_net_aux_rtnl_rtntype_n2a_maybe_buf(nm_platform_route_type_uncoerce(route->type_coerced), + str_type), + route->table_any + ? "table ?? " + : (route->table_coerced + ? nm_sprintf_buf(str_table, + "table %u ", + nm_platform_route_table_uncoerce(route->table_coerced, FALSE)) + : ""), + s_network, + route->plen, + s_gateway, + str_dev, + route->metric_any + ? (route->metric ? nm_sprintf_buf(str_metric, "??+%u", route->metric) : "??") + : nm_sprintf_buf(str_metric, "%u", route->metric), + route->mss, + nmp_utils_ip_config_source_to_string(route->rt_source, s_source, sizeof(s_source)), + _rtm_flags_to_string_full(str_rtm_flags, sizeof(str_rtm_flags), route->r_rtm_flags), + route->scope_inv ? " scope " : "", + route->scope_inv + ? (nm_platform_route_scope2str(nm_platform_route_scope_inv(route->scope_inv), + str_scope, + sizeof(str_scope))) + : "", + route->pref_src ? " pref-src " : "", + route->pref_src ? inet_ntop(AF_INET, &route->pref_src, s_pref_src, sizeof(s_pref_src)) : "", + route->tos ? nm_sprintf_buf(str_tos, " tos 0x%x", (unsigned) route->tos) : "", + route->window || route->lock_window ? nm_sprintf_buf(str_window, + " window %s%" G_GUINT32_FORMAT, + route->lock_window ? "lock " : "", + route->window) + : "", + route->cwnd || route->lock_cwnd ? nm_sprintf_buf(str_cwnd, + " cwnd %s%" G_GUINT32_FORMAT, + route->lock_cwnd ? "lock " : "", + route->cwnd) + : "", + route->initcwnd || route->lock_initcwnd + ? nm_sprintf_buf(str_initcwnd, + " initcwnd %s%" G_GUINT32_FORMAT, + route->lock_initcwnd ? "lock " : "", + route->initcwnd) + : "", + route->initrwnd || route->lock_initrwnd + ? nm_sprintf_buf(str_initrwnd, + " initrwnd %s%" G_GUINT32_FORMAT, + route->lock_initrwnd ? "lock " : "", + route->initrwnd) + : "", + route->mtu || route->lock_mtu ? nm_sprintf_buf(str_mtu, + " mtu %s%" G_GUINT32_FORMAT, + route->lock_mtu ? "lock " : "", + route->mtu) + : ""); + return buf; +} + +/** + * nm_platform_ip6_route_to_string: + * @route: pointer to NMPlatformIP6Route route structure + * @buf: (allow-none): an optional buffer. If %NULL, a static buffer is used. + * @len: the size of the @buf. If @buf is %NULL, this argument is ignored. + * + * A method for converting a route struct into a string representation. + * + * Example output: "ff02::fb/128 via :: dev em1 metric 0" + * + * Returns: a string representation of the route. + */ +const char * +nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsize len) +{ + char s_network[INET6_ADDRSTRLEN]; + char s_gateway[INET6_ADDRSTRLEN]; + char s_pref_src[INET6_ADDRSTRLEN]; + char s_src_all[INET6_ADDRSTRLEN + 40]; + char s_src[INET6_ADDRSTRLEN]; + char str_type[30]; + char str_table[30]; + char str_pref[40]; + char str_pref2[30]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char s_source[50]; + char str_window[32]; + char str_cwnd[32]; + char str_initcwnd[32]; + char str_initrwnd[32]; + char str_mtu[32]; + char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN]; + char str_metric[30]; + + if (!nm_utils_to_string_buffer_init_null(route, &buf, &len)) + return buf; + + inet_ntop(AF_INET6, &route->network, s_network, sizeof(s_network)); + inet_ntop(AF_INET6, &route->gateway, s_gateway, sizeof(s_gateway)); + + if (IN6_IS_ADDR_UNSPECIFIED(&route->pref_src)) + s_pref_src[0] = 0; + else + inet_ntop(AF_INET6, &route->pref_src, s_pref_src, sizeof(s_pref_src)); + + _to_string_dev(NULL, route->ifindex, str_dev, sizeof(str_dev)); + + g_snprintf( + buf, + len, + "type %s " /* type */ + "%s" /* table */ + "%s/%d" + " via %s" + "%s" + " metric %s" + " mss %" G_GUINT32_FORMAT " rt-src %s" /* protocol */ + "%s" /* source */ + "%s" /* rtm_flags */ + "%s%s" /* pref-src */ + "%s" /* window */ + "%s" /* cwnd */ + "%s" /* initcwnd */ + "%s" /* initrwnd */ + "%s" /* mtu */ + "%s" /* pref */ + "", + nm_net_aux_rtnl_rtntype_n2a_maybe_buf(nm_platform_route_type_uncoerce(route->type_coerced), + str_type), + route->table_any + ? "table ?? " + : (route->table_coerced + ? nm_sprintf_buf(str_table, + "table %u ", + nm_platform_route_table_uncoerce(route->table_coerced, FALSE)) + : ""), + s_network, + route->plen, + s_gateway, + str_dev, + route->metric_any + ? (route->metric ? nm_sprintf_buf(str_metric, "??+%u", route->metric) : "??") + : nm_sprintf_buf(str_metric, "%u", route->metric), + route->mss, + nmp_utils_ip_config_source_to_string(route->rt_source, s_source, sizeof(s_source)), + route->src_plen || !IN6_IS_ADDR_UNSPECIFIED(&route->src) + ? nm_sprintf_buf(s_src_all, + " src %s/%u", + _nm_utils_inet6_ntop(&route->src, s_src), + (unsigned) route->src_plen) + : "", + _rtm_flags_to_string_full(str_rtm_flags, sizeof(str_rtm_flags), route->r_rtm_flags), + s_pref_src[0] ? " pref-src " : "", + s_pref_src[0] ? s_pref_src : "", + route->window || route->lock_window ? nm_sprintf_buf(str_window, + " window %s%" G_GUINT32_FORMAT, + route->lock_window ? "lock " : "", + route->window) + : "", + route->cwnd || route->lock_cwnd ? nm_sprintf_buf(str_cwnd, + " cwnd %s%" G_GUINT32_FORMAT, + route->lock_cwnd ? "lock " : "", + route->cwnd) + : "", + route->initcwnd || route->lock_initcwnd + ? nm_sprintf_buf(str_initcwnd, + " initcwnd %s%" G_GUINT32_FORMAT, + route->lock_initcwnd ? "lock " : "", + route->initcwnd) + : "", + route->initrwnd || route->lock_initrwnd + ? nm_sprintf_buf(str_initrwnd, + " initrwnd %s%" G_GUINT32_FORMAT, + route->lock_initrwnd ? "lock " : "", + route->initrwnd) + : "", + route->mtu || route->lock_mtu ? nm_sprintf_buf(str_mtu, + " mtu %s%" G_GUINT32_FORMAT, + route->lock_mtu ? "lock " : "", + route->mtu) + : "", + route->rt_pref ? nm_sprintf_buf( + str_pref, + " pref %s", + nm_icmpv6_router_pref_to_string(route->rt_pref, str_pref2, sizeof(str_pref2))) + : ""); + + return buf; +} + +static void +_routing_rule_addr_to_string(char ** buf, + gsize * len, + int addr_family, + const NMIPAddr *addr, + guint8 plen, + gboolean is_src) +{ + char s_addr[NM_UTILS_INET_ADDRSTRLEN]; + gboolean is_zero; + gsize addr_size; + + nm_assert_addr_family(addr_family); + nm_assert(addr); + + addr_size = nm_utils_addr_family_to_size(addr_family); + + is_zero = nm_utils_memeqzero(addr, addr_size); + + if (plen == 0 && is_zero) { + if (is_src) + nm_utils_strbuf_append_str(buf, len, " from all"); + else + nm_utils_strbuf_append_str(buf, len, ""); + return; + } + + nm_utils_strbuf_append_str(buf, len, is_src ? " from " : " to "); + + nm_utils_strbuf_append_str(buf, len, nm_utils_inet_ntop(addr_family, addr, s_addr)); + + if (plen != (addr_size * 8)) + nm_utils_strbuf_append(buf, len, "/%u", plen); +} + +static void +_routing_rule_port_range_to_string(char ** buf, + gsize * len, + const NMFibRulePortRange *port_range, + const char * name) +{ + if (port_range->start == 0 && port_range->end == 0) + nm_utils_strbuf_append_str(buf, len, ""); + else { + nm_utils_strbuf_append(buf, len, " %s %u", name, port_range->start); + if (port_range->start != port_range->end) + nm_utils_strbuf_append(buf, len, "-%u", port_range->end); + } +} + +const char * +nm_platform_routing_rule_to_string(const NMPlatformRoutingRule *routing_rule, char *buf, gsize len) +{ + const char *buf0; + guint32 rr_flags; + + if (!nm_utils_to_string_buffer_init_null(routing_rule, &buf, &len)) + return buf; + + if (!NM_IN_SET(routing_rule->addr_family, AF_INET, AF_INET6)) { + /* invalid addr-family. The other fields are undefined. */ + if (routing_rule->addr_family == AF_UNSPEC) + g_snprintf(buf, len, "[routing-rule]"); + else + g_snprintf(buf, len, "[routing-rule family:%u]", routing_rule->addr_family); + return buf; + } + + buf0 = buf; + + rr_flags = routing_rule->flags; + + rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_INVERT); + nm_utils_strbuf_append(&buf, + &len, + "[%c] " /* addr-family */ + "%u:" /* priority */ + "%s", /* not/FIB_RULE_INVERT */ + nm_utils_addr_family_to_char(routing_rule->addr_family), + routing_rule->priority, + (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_INVERT) ? " not" : "")); + + _routing_rule_addr_to_string(&buf, + &len, + routing_rule->addr_family, + &routing_rule->src, + routing_rule->src_len, + TRUE); + + _routing_rule_addr_to_string(&buf, + &len, + routing_rule->addr_family, + &routing_rule->dst, + routing_rule->dst_len, + FALSE); + + if (routing_rule->tos) + nm_utils_strbuf_append(&buf, &len, " tos 0x%02x", routing_rule->tos); + + if (routing_rule->fwmark != 0 || routing_rule->fwmask != 0) { + nm_utils_strbuf_append(&buf, &len, " fwmark %#x", (unsigned) routing_rule->fwmark); + if (routing_rule->fwmark != 0xFFFFFFFFu) + nm_utils_strbuf_append(&buf, &len, "/%#x", (unsigned) routing_rule->fwmask); + } + + if (routing_rule->iifname[0]) { + nm_utils_strbuf_append(&buf, &len, " iif %s", routing_rule->iifname); + rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_IIF_DETACHED); + if (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_IIF_DETACHED)) + nm_utils_strbuf_append_str(&buf, &len, " [detached]"); + } + + if (routing_rule->oifname[0]) { + nm_utils_strbuf_append(&buf, &len, " oif %s", routing_rule->oifname); + rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_OIF_DETACHED); + if (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_OIF_DETACHED)) + nm_utils_strbuf_append_str(&buf, &len, " [detached]"); + } + + if (routing_rule->l3mdev != 0) { + if (routing_rule->l3mdev == 1) + nm_utils_strbuf_append_str(&buf, &len, " lookup [l3mdev-table]"); + else { + nm_utils_strbuf_append(&buf, + &len, + " lookup [l3mdev-table/%u]", + (unsigned) routing_rule->l3mdev); + } + } + + if (routing_rule->uid_range_has || routing_rule->uid_range.start + || routing_rule->uid_range.end) { + nm_utils_strbuf_append(&buf, + &len, + " uidrange %u-%u%s", + routing_rule->uid_range.start, + routing_rule->uid_range.end, + routing_rule->uid_range_has ? "" : "(?)"); + } + + if (routing_rule->ip_proto != 0) { + /* we don't call getprotobynumber(), just print the numeric value. + * This differs from what ip-rule prints. */ + nm_utils_strbuf_append(&buf, &len, " ipproto %u", routing_rule->ip_proto); + } + + _routing_rule_port_range_to_string(&buf, &len, &routing_rule->sport_range, "sport"); + + _routing_rule_port_range_to_string(&buf, &len, &routing_rule->dport_range, "dport"); + + if (routing_rule->tun_id != 0) { + nm_utils_strbuf_append(&buf, &len, " tun_id %" G_GUINT64_FORMAT, routing_rule->tun_id); + } + + if (routing_rule->table != 0) { + nm_utils_strbuf_append(&buf, &len, " lookup %u", routing_rule->table); + } + + if (routing_rule->suppress_prefixlen_inverse != 0) { + nm_utils_strbuf_append(&buf, + &len, + " suppress_prefixlen %d", + (int) (~routing_rule->suppress_prefixlen_inverse)); + } + + if (routing_rule->suppress_ifgroup_inverse != 0) { + nm_utils_strbuf_append(&buf, + &len, + " suppress_ifgroup %d", + (int) (~routing_rule->suppress_ifgroup_inverse)); + } + + if (routing_rule->flow) { + /* FRA_FLOW is only for IPv4, but we want to print the value for all address-families, + * to see when it is set. In practice, this should not be set except for IPv4. + * + * We don't follow the style how ip-rule prints flow/realms. It's confusing. Just + * print the value hex. */ + nm_utils_strbuf_append(&buf, &len, " realms 0x%08x", routing_rule->flow); + } + + if (routing_rule->action == RTN_NAT) { + G_STATIC_ASSERT_EXPR(RTN_NAT == 10); + + /* NAT is deprecated for many years. We don't support RTA_GATEWAY/FRA_UNUSED2 + * for the gateway, and so do recent kernels ignore that parameter. */ + nm_utils_strbuf_append_str(&buf, &len, " masquerade"); + } else if (routing_rule->action == FR_ACT_GOTO) { + if (routing_rule->goto_target != 0) + nm_utils_strbuf_append(&buf, &len, " goto %u", routing_rule->goto_target); + else + nm_utils_strbuf_append_str(&buf, &len, " goto none"); + rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_UNRESOLVED); + if (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_UNRESOLVED)) + nm_utils_strbuf_append_str(&buf, &len, " unresolved"); + } else if (routing_rule->action != FR_ACT_TO_TBL) { + char ss_buf[60]; + + nm_utils_strbuf_append(&buf, + &len, + " %s", + nm_net_aux_rtnl_rtntype_n2a(routing_rule->action) + ?: nm_sprintf_buf(ss_buf, "action-%u", routing_rule->action)); + } + + if (routing_rule->protocol != RTPROT_UNSPEC) + nm_utils_strbuf_append(&buf, &len, " protocol %u", routing_rule->protocol); + + if (routing_rule->goto_target != 0 && routing_rule->action != FR_ACT_GOTO) { + /* a trailing target is set for an unexpected action. Print it. */ + nm_utils_strbuf_append(&buf, &len, " goto-target %u", routing_rule->goto_target); + } + + if (rr_flags != 0) { + /* we have some flags we didn't print about yet. */ + nm_utils_strbuf_append(&buf, &len, " remaining-flags %x", rr_flags); + } + + return buf0; +} + +const char * +nm_platform_qdisc_to_string(const NMPlatformQdisc *qdisc, char *buf, gsize len) +{ + char str_dev[TO_STRING_DEV_BUF_SIZE]; + const char *buf0; + + if (!nm_utils_to_string_buffer_init_null(qdisc, &buf, &len)) + return buf; + + buf0 = buf; + + nm_utils_strbuf_append(&buf, + &len, + "%s%s family %u handle %x parent %x info %x", + qdisc->kind, + _to_string_dev(NULL, qdisc->ifindex, str_dev, sizeof(str_dev)), + qdisc->addr_family, + qdisc->handle, + qdisc->parent, + qdisc->info); + + if (nm_streq0(qdisc->kind, "fq_codel")) { + if (qdisc->fq_codel.limit) + nm_utils_strbuf_append(&buf, &len, " limit %u", qdisc->fq_codel.limit); + if (qdisc->fq_codel.flows) + nm_utils_strbuf_append(&buf, &len, " flows %u", qdisc->fq_codel.flows); + if (qdisc->fq_codel.target) + nm_utils_strbuf_append(&buf, &len, " target %u", qdisc->fq_codel.target); + if (qdisc->fq_codel.interval) + nm_utils_strbuf_append(&buf, &len, " interval %u", qdisc->fq_codel.interval); + if (qdisc->fq_codel.quantum) + nm_utils_strbuf_append(&buf, &len, " quantum %u", qdisc->fq_codel.quantum); + if (qdisc->fq_codel.ce_threshold != NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED) + nm_utils_strbuf_append(&buf, &len, " ce_threshold %u", qdisc->fq_codel.ce_threshold); + if (qdisc->fq_codel.memory_limit != NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET) + nm_utils_strbuf_append(&buf, &len, " memory_limit %u", qdisc->fq_codel.memory_limit); + if (qdisc->fq_codel.ecn) + nm_utils_strbuf_append(&buf, &len, " ecn"); + } else if (nm_streq0(qdisc->kind, "sfq")) { + if (qdisc->sfq.quantum) + nm_utils_strbuf_append(&buf, &len, " quantum %u", qdisc->sfq.quantum); + if (qdisc->sfq.perturb_period) + nm_utils_strbuf_append(&buf, &len, " perturb %d", qdisc->sfq.perturb_period); + if (qdisc->sfq.limit) + nm_utils_strbuf_append(&buf, &len, " limit %u", (guint) qdisc->sfq.limit); + if (qdisc->sfq.divisor) + nm_utils_strbuf_append(&buf, &len, " divisor %u", qdisc->sfq.divisor); + if (qdisc->sfq.flows) + nm_utils_strbuf_append(&buf, &len, " flows %u", qdisc->sfq.flows); + if (qdisc->sfq.depth) + nm_utils_strbuf_append(&buf, &len, " depth %u", qdisc->sfq.depth); + } else if (nm_streq0(qdisc->kind, "tbf")) { + nm_utils_strbuf_append(&buf, &len, " rate %" G_GUINT64_FORMAT, qdisc->tbf.rate); + nm_utils_strbuf_append(&buf, &len, " burst %u", qdisc->tbf.burst); + if (qdisc->tbf.limit) + nm_utils_strbuf_append(&buf, &len, " limit %u", qdisc->tbf.limit); + if (qdisc->tbf.latency) + nm_utils_strbuf_append(&buf, &len, " latency %uns", qdisc->tbf.latency); + } + + return buf0; +} + +void +nm_platform_qdisc_hash_update(const NMPlatformQdisc *obj, NMHashState *h) +{ + nm_hash_update_str0(h, obj->kind); + nm_hash_update_vals(h, obj->ifindex, obj->addr_family, obj->handle, obj->parent, obj->info); + if (nm_streq0(obj->kind, "fq_codel")) { + nm_hash_update_vals(h, + obj->fq_codel.limit, + obj->fq_codel.flows, + obj->fq_codel.target, + obj->fq_codel.interval, + obj->fq_codel.quantum, + obj->fq_codel.ce_threshold, + obj->fq_codel.memory_limit, + NM_HASH_COMBINE_BOOLS(guint8, obj->fq_codel.ecn)); + } else if (nm_streq0(obj->kind, "sfq")) { + nm_hash_update_vals(h, + obj->sfq.quantum, + obj->sfq.perturb_period, + obj->sfq.limit, + obj->sfq.divisor, + obj->sfq.flows, + obj->sfq.depth); + } else if (nm_streq0(obj->kind, "tbf")) { + nm_hash_update_vals(h, obj->tbf.rate, obj->tbf.burst, obj->tbf.limit, obj->tbf.latency); + } +} + +int +nm_platform_qdisc_cmp_full(const NMPlatformQdisc *a, + const NMPlatformQdisc *b, + gboolean compare_handle) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, parent); + NM_CMP_FIELD_STR_INTERNED(a, b, kind); + NM_CMP_FIELD(a, b, addr_family); + if (compare_handle) + NM_CMP_FIELD(a, b, handle); + NM_CMP_FIELD(a, b, info); + + if (nm_streq0(a->kind, "fq_codel")) { + NM_CMP_FIELD(a, b, fq_codel.limit); + NM_CMP_FIELD(a, b, fq_codel.flows); + NM_CMP_FIELD(a, b, fq_codel.target); + NM_CMP_FIELD(a, b, fq_codel.interval); + NM_CMP_FIELD(a, b, fq_codel.quantum); + NM_CMP_FIELD(a, b, fq_codel.ce_threshold); + NM_CMP_FIELD(a, b, fq_codel.memory_limit); + NM_CMP_FIELD_UNSAFE(a, b, fq_codel.ecn); + } else if (nm_streq0(a->kind, "sfq")) { + NM_CMP_FIELD(a, b, sfq.quantum); + NM_CMP_FIELD(a, b, sfq.perturb_period); + NM_CMP_FIELD(a, b, sfq.limit); + NM_CMP_FIELD(a, b, sfq.flows); + NM_CMP_FIELD(a, b, sfq.divisor); + NM_CMP_FIELD(a, b, sfq.depth); + } else if (nm_streq0(a->kind, "tbf")) { + NM_CMP_FIELD(a, b, tbf.rate); + NM_CMP_FIELD(a, b, tbf.burst); + NM_CMP_FIELD(a, b, tbf.limit); + NM_CMP_FIELD(a, b, tbf.latency); + } + + return 0; +} + +int +nm_platform_qdisc_cmp(const NMPlatformQdisc *a, const NMPlatformQdisc *b) +{ + return nm_platform_qdisc_cmp_full(a, b, TRUE); +} + +const char * +nm_platform_tfilter_to_string(const NMPlatformTfilter *tfilter, char *buf, gsize len) +{ + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char act_buf[300]; + char *p; + gsize l; + + if (!nm_utils_to_string_buffer_init_null(tfilter, &buf, &len)) + return buf; + + if (tfilter->action.kind) { + p = act_buf; + l = sizeof(act_buf); + + nm_utils_strbuf_append(&p, &l, " \"%s\"", tfilter->action.kind); + if (nm_streq(tfilter->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) { + gs_free char *t = NULL; + + nm_utils_strbuf_append( + &p, + &l, + " (\"%s\")", + nm_utils_str_utf8safe_escape(tfilter->action.kind, + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL + | NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII, + &t)); + } else if (nm_streq(tfilter->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) { + nm_utils_strbuf_append(&p, + &l, + "%s%s%s%s dev %d", + tfilter->action.mirred.ingress ? " ingress" : "", + tfilter->action.mirred.egress ? " egress" : "", + tfilter->action.mirred.mirror ? " mirror" : "", + tfilter->action.mirred.redirect ? " redirect" : "", + tfilter->action.mirred.ifindex); + } + } else + act_buf[0] = '\0'; + + g_snprintf(buf, + len, + "%s%s family %u handle %x parent %x info %x%s", + tfilter->kind, + _to_string_dev(NULL, tfilter->ifindex, str_dev, sizeof(str_dev)), + tfilter->addr_family, + tfilter->handle, + tfilter->parent, + tfilter->info, + act_buf); + + return buf; +} + +void +nm_platform_tfilter_hash_update(const NMPlatformTfilter *obj, NMHashState *h) +{ + nm_hash_update_str0(h, obj->kind); + nm_hash_update_vals(h, obj->ifindex, obj->addr_family, obj->handle, obj->parent, obj->info); + if (obj->action.kind) { + nm_hash_update_str(h, obj->action.kind); + if (nm_streq(obj->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) { + nm_hash_update_strarr(h, obj->action.simple.sdata); + } else if (nm_streq(obj->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) { + nm_hash_update_vals(h, + obj->action.mirred.ifindex, + NM_HASH_COMBINE_BOOLS(guint8, + obj->action.mirred.ingress, + obj->action.mirred.egress, + obj->action.mirred.mirror, + obj->action.mirred.redirect)); + } + } +} + +int +nm_platform_tfilter_cmp(const NMPlatformTfilter *a, const NMPlatformTfilter *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, parent); + NM_CMP_FIELD_STR_INTERNED(a, b, kind); + NM_CMP_FIELD(a, b, addr_family); + NM_CMP_FIELD(a, b, handle); + NM_CMP_FIELD(a, b, info); + + NM_CMP_FIELD_STR_INTERNED(a, b, action.kind); + if (a->action.kind) { + if (nm_streq(a->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) { + NM_CMP_FIELD_STR(a, b, action.simple.sdata); + } else if (nm_streq(a->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) { + NM_CMP_FIELD(a, b, action.mirred.ifindex); + NM_CMP_FIELD_UNSAFE(a, b, action.mirred.ingress); + NM_CMP_FIELD_UNSAFE(a, b, action.mirred.egress); + NM_CMP_FIELD_UNSAFE(a, b, action.mirred.mirror); + NM_CMP_FIELD_UNSAFE(a, b, action.mirred.redirect); + } + } + + return 0; +} + +const char * +nm_platform_vf_to_string(const NMPlatformVF *vf, char *buf, gsize len) +{ + char str_mac[128], mac[128]; + char str_spoof_check[64]; + char str_trust[64]; + char str_min_tx_rate[64]; + char str_max_tx_rate[64]; + nm_auto_free_gstring GString *gstr_vlans = NULL; + guint i; + + if (!nm_utils_to_string_buffer_init_null(vf, &buf, &len)) + return buf; + + if (vf->mac.len) { + _nm_utils_hwaddr_ntoa(vf->mac.data, vf->mac.len, TRUE, mac, sizeof(mac)); + nm_sprintf_buf(str_mac, " mac %s", mac); + } else + str_mac[0] = '\0'; + + if (vf->num_vlans) { + gstr_vlans = g_string_new(""); + for (i = 0; i < vf->num_vlans; i++) { + g_string_append_printf(gstr_vlans, " vlan %u", (unsigned) vf->vlans[i].id); + if (vf->vlans[i].qos) + g_string_append_printf(gstr_vlans, " qos %u", (unsigned) vf->vlans[i].qos); + if (vf->vlans[i].proto_ad) + g_string_append(gstr_vlans, " proto 802.1ad"); + } + } + + g_snprintf(buf, + len, + "%u" /* index */ + "%s" /* MAC */ + "%s" /* spoof check */ + "%s" /* trust */ + "%s" /* min tx rate */ + "%s" /* max tx rate */ + "%s", /* VLANs */ + vf->index, + str_mac, + vf->spoofchk >= 0 ? nm_sprintf_buf(str_spoof_check, " spoofchk %d", vf->spoofchk) + : "", + vf->trust >= 0 ? nm_sprintf_buf(str_trust, " trust %d", vf->trust) : "", + vf->min_tx_rate + ? nm_sprintf_buf(str_min_tx_rate, " min_tx_rate %u", (unsigned) vf->min_tx_rate) + : "", + vf->max_tx_rate + ? nm_sprintf_buf(str_max_tx_rate, " max_tx_rate %u", (unsigned) vf->max_tx_rate) + : "", + gstr_vlans ? gstr_vlans->str : ""); + + return buf; +} + +const char * +nm_platform_bridge_vlan_to_string(const NMPlatformBridgeVlan *vlan, char *buf, gsize len) +{ + char str_vid_end[64]; + + if (!nm_utils_to_string_buffer_init_null(vlan, &buf, &len)) + return buf; + + g_snprintf(buf, + len, + "%u" + "%s" + "%s" + "%s", + vlan->vid_start, + vlan->vid_start != vlan->vid_end ? nm_sprintf_buf(str_vid_end, "-%u", vlan->vid_end) + : "", + vlan->pvid ? " PVID" : "", + vlan->untagged ? " untagged" : ""); + + return buf; +} + +void +nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->ifindex, + obj->master, + obj->parent, + obj->n_ifi_flags, + obj->mtu, + obj->type, + obj->arptype, + obj->inet6_addr_gen_mode_inv, + obj->inet6_token, + obj->rx_packets, + obj->rx_bytes, + obj->tx_packets, + obj->tx_bytes, + NM_HASH_COMBINE_BOOLS(guint8, obj->connected, obj->initialized)); + nm_hash_update_strarr(h, obj->name); + nm_hash_update_str0(h, obj->kind); + nm_hash_update_str0(h, obj->driver); + /* nm_hash_update_mem() also hashes the length obj->addr.len */ + nm_hash_update_mem(h, + obj->l_address.data, + NM_MIN(obj->l_address.len, sizeof(obj->l_address.data))); + nm_hash_update_mem(h, + obj->l_broadcast.data, + NM_MIN(obj->l_broadcast.len, sizeof(obj->l_broadcast.data))); +} + +int +nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, type); + NM_CMP_FIELD_STR(a, b, name); + NM_CMP_FIELD(a, b, master); + NM_CMP_FIELD(a, b, parent); + NM_CMP_FIELD(a, b, n_ifi_flags); + NM_CMP_FIELD_UNSAFE(a, b, connected); + NM_CMP_FIELD(a, b, mtu); + NM_CMP_FIELD_BOOL(a, b, initialized); + NM_CMP_FIELD(a, b, arptype); + NM_CMP_FIELD(a, b, l_address.len); + NM_CMP_FIELD(a, b, l_broadcast.len); + NM_CMP_FIELD(a, b, inet6_addr_gen_mode_inv); + NM_CMP_FIELD_STR_INTERNED(a, b, kind); + NM_CMP_FIELD_STR_INTERNED(a, b, driver); + if (a->l_address.len) + NM_CMP_FIELD_MEMCMP_LEN(a, b, l_address.data, a->l_address.len); + if (a->l_broadcast.len) + NM_CMP_FIELD_MEMCMP_LEN(a, b, l_broadcast.data, a->l_broadcast.len); + NM_CMP_FIELD_MEMCMP(a, b, inet6_token); + NM_CMP_FIELD(a, b, rx_packets); + NM_CMP_FIELD(a, b, rx_bytes); + NM_CMP_FIELD(a, b, tx_packets); + NM_CMP_FIELD(a, b, tx_bytes); + return 0; +} + +void +nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->forward_delay, + obj->hello_time, + obj->max_age, + obj->ageing_time, + obj->priority, + obj->vlan_protocol, + obj->group_fwd_mask, + obj->group_addr, + obj->mcast_hash_max, + obj->mcast_last_member_count, + obj->mcast_startup_query_count, + obj->mcast_last_member_interval, + obj->mcast_membership_interval, + obj->mcast_querier_interval, + obj->mcast_query_interval, + obj->mcast_router, + obj->mcast_query_response_interval, + obj->mcast_startup_query_interval, + NM_HASH_COMBINE_BOOLS(guint8, + obj->stp_state, + obj->mcast_querier, + obj->mcast_query_use_ifaddr, + obj->mcast_snooping, + obj->vlan_stats_enabled)); +} + +int +nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, forward_delay); + NM_CMP_FIELD(a, b, hello_time); + NM_CMP_FIELD(a, b, max_age); + NM_CMP_FIELD(a, b, ageing_time); + NM_CMP_FIELD_BOOL(a, b, stp_state); + NM_CMP_FIELD(a, b, priority); + NM_CMP_FIELD(a, b, vlan_protocol); + NM_CMP_FIELD_BOOL(a, b, vlan_stats_enabled); + NM_CMP_FIELD(a, b, group_fwd_mask); + NM_CMP_FIELD_MEMCMP(a, b, group_addr); + NM_CMP_FIELD_BOOL(a, b, mcast_snooping); + NM_CMP_FIELD(a, b, mcast_router); + NM_CMP_FIELD_BOOL(a, b, mcast_query_use_ifaddr); + NM_CMP_FIELD_BOOL(a, b, mcast_querier); + NM_CMP_FIELD(a, b, mcast_hash_max); + NM_CMP_FIELD(a, b, mcast_last_member_count); + NM_CMP_FIELD(a, b, mcast_startup_query_count); + NM_CMP_FIELD(a, b, mcast_last_member_interval); + NM_CMP_FIELD(a, b, mcast_membership_interval); + NM_CMP_FIELD(a, b, mcast_querier_interval); + NM_CMP_FIELD(a, b, mcast_query_interval); + NM_CMP_FIELD(a, b, mcast_query_response_interval); + NM_CMP_FIELD(a, b, mcast_startup_query_interval); + + return 0; +} + +void +nm_platform_lnk_gre_hash_update(const NMPlatformLnkGre *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->input_flags, + obj->output_flags, + obj->input_key, + obj->output_key, + obj->ttl, + obj->tos, + (bool) obj->path_mtu_discovery, + (bool) obj->is_tap); +} + +int +nm_platform_lnk_gre_cmp(const NMPlatformLnkGre *a, const NMPlatformLnkGre *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD(a, b, input_flags); + NM_CMP_FIELD(a, b, output_flags); + NM_CMP_FIELD(a, b, input_key); + NM_CMP_FIELD(a, b, output_key); + NM_CMP_FIELD(a, b, local); + NM_CMP_FIELD(a, b, remote); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD_BOOL(a, b, path_mtu_discovery); + NM_CMP_FIELD_BOOL(a, b, is_tap); + return 0; +} + +void +nm_platform_lnk_infiniband_hash_update(const NMPlatformLnkInfiniband *obj, NMHashState *h) +{ + nm_hash_update_val(h, obj->p_key); + nm_hash_update_str0(h, obj->mode); +} + +int +nm_platform_lnk_infiniband_cmp(const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, p_key); + NM_CMP_FIELD_STR_INTERNED(a, b, mode); + return 0; +} + +void +nm_platform_lnk_ip6tnl_hash_update(const NMPlatformLnkIp6Tnl *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->ttl, + obj->tclass, + obj->encap_limit, + obj->proto, + obj->flow_label, + obj->flags, + obj->input_flags, + obj->output_flags, + obj->input_key, + obj->output_key, + (bool) obj->is_gre, + (bool) obj->is_tap); +} + +int +nm_platform_lnk_ip6tnl_cmp(const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6Tnl *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD_MEMCMP(a, b, local); + NM_CMP_FIELD_MEMCMP(a, b, remote); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD(a, b, tclass); + NM_CMP_FIELD(a, b, encap_limit); + NM_CMP_FIELD(a, b, flow_label); + NM_CMP_FIELD(a, b, proto); + NM_CMP_FIELD(a, b, flags); + NM_CMP_FIELD(a, b, input_flags); + NM_CMP_FIELD(a, b, output_flags); + NM_CMP_FIELD(a, b, input_key); + NM_CMP_FIELD(a, b, output_key); + NM_CMP_FIELD_BOOL(a, b, is_gre); + NM_CMP_FIELD_BOOL(a, b, is_tap); + return 0; +} + +void +nm_platform_lnk_ipip_hash_update(const NMPlatformLnkIpIp *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->ttl, + obj->tos, + (bool) obj->path_mtu_discovery); +} + +int +nm_platform_lnk_ipip_cmp(const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD(a, b, local); + NM_CMP_FIELD(a, b, remote); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD_BOOL(a, b, path_mtu_discovery); + return 0; +} + +void +nm_platform_lnk_macsec_hash_update(const NMPlatformLnkMacsec *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->parent_ifindex, + obj->sci, + obj->cipher_suite, + obj->window, + obj->icv_length, + obj->encoding_sa, + obj->validation, + NM_HASH_COMBINE_BOOLS(guint8, + obj->encrypt, + obj->protect, + obj->include_sci, + obj->es, + obj->scb, + obj->replay_protect)); +} + +int +nm_platform_lnk_macsec_cmp(const NMPlatformLnkMacsec *a, const NMPlatformLnkMacsec *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD(a, b, sci); + NM_CMP_FIELD(a, b, icv_length); + NM_CMP_FIELD(a, b, cipher_suite); + NM_CMP_FIELD(a, b, window); + NM_CMP_FIELD(a, b, encoding_sa); + NM_CMP_FIELD(a, b, validation); + NM_CMP_FIELD_UNSAFE(a, b, encrypt); + NM_CMP_FIELD_UNSAFE(a, b, protect); + NM_CMP_FIELD_UNSAFE(a, b, include_sci); + NM_CMP_FIELD_UNSAFE(a, b, es); + NM_CMP_FIELD_UNSAFE(a, b, scb); + NM_CMP_FIELD_UNSAFE(a, b, replay_protect); + return 0; +} + +void +nm_platform_lnk_macvlan_hash_update(const NMPlatformLnkMacvlan *obj, NMHashState *h) +{ + nm_hash_update_vals(h, obj->mode, NM_HASH_COMBINE_BOOLS(guint8, obj->no_promisc, obj->tap)); +} + +int +nm_platform_lnk_macvlan_cmp(const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, mode); + NM_CMP_FIELD_UNSAFE(a, b, no_promisc); + NM_CMP_FIELD_UNSAFE(a, b, tap); + return 0; +} + +void +nm_platform_lnk_sit_hash_update(const NMPlatformLnkSit *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->local, + obj->remote, + obj->parent_ifindex, + obj->flags, + obj->ttl, + obj->tos, + obj->proto, + (bool) obj->path_mtu_discovery); +} + +int +nm_platform_lnk_sit_cmp(const NMPlatformLnkSit *a, const NMPlatformLnkSit *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD(a, b, local); + NM_CMP_FIELD(a, b, remote); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD_BOOL(a, b, path_mtu_discovery); + NM_CMP_FIELD(a, b, flags); + NM_CMP_FIELD(a, b, proto); + return 0; +} + +void +nm_platform_lnk_tun_hash_update(const NMPlatformLnkTun *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->type, + obj->owner, + obj->group, + NM_HASH_COMBINE_BOOLS(guint8, + obj->owner_valid, + obj->group_valid, + obj->pi, + obj->vnet_hdr, + obj->multi_queue, + obj->persist)); +} + +int +nm_platform_lnk_tun_cmp(const NMPlatformLnkTun *a, const NMPlatformLnkTun *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, type); + NM_CMP_FIELD(a, b, owner); + NM_CMP_FIELD(a, b, group); + NM_CMP_FIELD_BOOL(a, b, owner_valid); + NM_CMP_FIELD_BOOL(a, b, group_valid); + NM_CMP_FIELD_BOOL(a, b, pi); + NM_CMP_FIELD_BOOL(a, b, vnet_hdr); + NM_CMP_FIELD_BOOL(a, b, multi_queue); + NM_CMP_FIELD_BOOL(a, b, persist); + return 0; +} + +void +nm_platform_lnk_vlan_hash_update(const NMPlatformLnkVlan *obj, NMHashState *h) +{ + nm_hash_update_vals(h, obj->id, obj->flags); +} + +int +nm_platform_lnk_vlan_cmp(const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, id); + NM_CMP_FIELD(a, b, flags); + return 0; +} + +void +nm_platform_lnk_vrf_hash_update(const NMPlatformLnkVrf *obj, NMHashState *h) +{ + nm_hash_update_vals(h, obj->table); +} + +int +nm_platform_lnk_vrf_cmp(const NMPlatformLnkVrf *a, const NMPlatformLnkVrf *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, table); + return 0; +} + +void +nm_platform_lnk_vxlan_hash_update(const NMPlatformLnkVxlan *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->group6, + obj->local6, + obj->group, + obj->local, + obj->parent_ifindex, + obj->id, + obj->ageing, + obj->limit, + obj->dst_port, + obj->src_port_min, + obj->src_port_max, + obj->tos, + obj->ttl, + NM_HASH_COMBINE_BOOLS(guint8, + obj->learning, + obj->proxy, + obj->rsc, + obj->l2miss, + obj->l3miss)); +} + +int +nm_platform_lnk_vxlan_cmp(const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, parent_ifindex); + NM_CMP_FIELD(a, b, id); + NM_CMP_FIELD(a, b, group); + NM_CMP_FIELD(a, b, local); + NM_CMP_FIELD_MEMCMP(a, b, group6); + NM_CMP_FIELD_MEMCMP(a, b, local6); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD_BOOL(a, b, learning); + NM_CMP_FIELD(a, b, ageing); + NM_CMP_FIELD(a, b, limit); + NM_CMP_FIELD(a, b, dst_port); + NM_CMP_FIELD(a, b, src_port_min); + NM_CMP_FIELD(a, b, src_port_max); + NM_CMP_FIELD_BOOL(a, b, proxy); + NM_CMP_FIELD_BOOL(a, b, rsc); + NM_CMP_FIELD_BOOL(a, b, l2miss); + NM_CMP_FIELD_BOOL(a, b, l3miss); + return 0; +} + +void +nm_platform_lnk_wireguard_hash_update(const NMPlatformLnkWireGuard *obj, NMHashState *h) +{ + nm_hash_update_vals(h, obj->listen_port, obj->fwmark); + nm_hash_update(h, obj->private_key, sizeof(obj->private_key)); + nm_hash_update(h, obj->public_key, sizeof(obj->public_key)); +} + +int +nm_platform_lnk_wireguard_cmp(const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, listen_port); + NM_CMP_FIELD(a, b, fwmark); + NM_CMP_FIELD_MEMCMP(a, b, private_key); + NM_CMP_FIELD_MEMCMP(a, b, public_key); + return 0; +} + +static int +_address_pretty_sort_get_prio_4(in_addr_t addr) +{ + if (nm_utils_ip4_address_is_link_local(addr)) + return 0; + return 1; +} + +int +nm_platform_ip4_address_pretty_sort_cmp(const NMPlatformIP4Address *a1, + const NMPlatformIP4Address *a2) +{ + in_addr_t n1; + in_addr_t n2; + + nm_assert(a1); + nm_assert(a2); + + /* Sort by address type. For example link local will + * be sorted *after* a global address. */ + NM_CMP_DIRECT(_address_pretty_sort_get_prio_4(a2->address), + _address_pretty_sort_get_prio_4(a1->address)); + + /* Sort the addresses based on their source. */ + NM_CMP_DIRECT(a2->addr_source, a1->addr_source); + + NM_CMP_DIRECT((a2->label[0] == '\0'), (a1->label[0] == '\0')); + + /* Finally, sort addresses lexically. We compare only the + * network part so that the order of addresses in the same + * subnet (and thus also the primary/secondary role) is + * preserved. + */ + n1 = a1->address & _nm_utils_ip4_prefix_to_netmask(a1->plen); + n2 = a2->address & _nm_utils_ip4_prefix_to_netmask(a2->plen); + NM_CMP_DIRECT_MEMCMP(&n1, &n2, sizeof(guint32)); + return 0; +} + +static int +_address_pretty_sort_get_prio_6(const struct in6_addr *addr) +{ + if (IN6_IS_ADDR_V4MAPPED(addr)) + return 0; + if (IN6_IS_ADDR_V4COMPAT(addr)) + return 1; + if (IN6_IS_ADDR_UNSPECIFIED(addr)) + return 2; + if (IN6_IS_ADDR_LOOPBACK(addr)) + return 3; + if (IN6_IS_ADDR_LINKLOCAL(addr)) + return 4; + if (IN6_IS_ADDR_SITELOCAL(addr)) + return 5; + return 6; +} + +int +nm_platform_ip6_address_pretty_sort_cmp(const NMPlatformIP6Address *a1, + const NMPlatformIP6Address *a2, + gboolean prefer_temp) +{ + gboolean ipv6_privacy1; + gboolean ipv6_privacy2; + + nm_assert(a1); + nm_assert(a2); + + /* tentative addresses are always sorted back... */ + /* sort tentative addresses after non-tentative. */ + NM_CMP_DIRECT(NM_FLAGS_HAS(a1->n_ifa_flags, IFA_F_TENTATIVE), + NM_FLAGS_HAS(a2->n_ifa_flags, IFA_F_TENTATIVE)); + + /* Sort by address type. For example link local will + * be sorted *after* site local or global. */ + NM_CMP_DIRECT(_address_pretty_sort_get_prio_6(&a2->address), + _address_pretty_sort_get_prio_6(&a1->address)); + + ipv6_privacy1 = NM_FLAGS_ANY(a1->n_ifa_flags, IFA_F_MANAGETEMPADDR | IFA_F_TEMPORARY); + ipv6_privacy2 = NM_FLAGS_ANY(a2->n_ifa_flags, IFA_F_MANAGETEMPADDR | IFA_F_TEMPORARY); + if (ipv6_privacy1 || ipv6_privacy2) { + gboolean public1 = TRUE; + gboolean public2 = TRUE; + + if (ipv6_privacy1) { + if (a1->n_ifa_flags & IFA_F_TEMPORARY) + public1 = prefer_temp; + else + public1 = !prefer_temp; + } + if (ipv6_privacy2) { + if (a2->n_ifa_flags & IFA_F_TEMPORARY) + public2 = prefer_temp; + else + public2 = !prefer_temp; + } + + NM_CMP_DIRECT(public2, public1); + } + + /* Sort the addresses based on their source. */ + NM_CMP_DIRECT(a2->addr_source, a1->addr_source); + + /* sort permanent addresses before non-permanent. */ + NM_CMP_DIRECT(NM_FLAGS_HAS(a2->n_ifa_flags, IFA_F_PERMANENT), + NM_FLAGS_HAS(a1->n_ifa_flags, IFA_F_PERMANENT)); + + /* finally sort addresses lexically */ + NM_CMP_DIRECT_IN6ADDR(&a1->address, &a2->address); + NM_CMP_DIRECT_MEMCMP(a1, a2, sizeof(*a1)); + return 0; +} + +void +nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->ifindex, + obj->addr_source, + obj->use_ip4_broadcast_address ? obj->broadcast_address : ((in_addr_t) 0u), + obj->timestamp, + obj->lifetime, + obj->preferred, + obj->n_ifa_flags, + obj->plen, + obj->address, + obj->peer_address, + NM_HASH_COMBINE_BOOLS(guint8, + obj->external, + obj->use_ip4_broadcast_address, + obj->ip4acd_not_ready)); + nm_hash_update_strarr(h, obj->label); +} + +int +nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a, const NMPlatformIP4Address *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, address); + NM_CMP_FIELD(a, b, plen); + NM_CMP_FIELD(a, b, peer_address); + NM_CMP_FIELD_UNSAFE(a, b, use_ip4_broadcast_address); + if (a->use_ip4_broadcast_address) + NM_CMP_FIELD(a, b, broadcast_address); + NM_CMP_FIELD(a, b, addr_source); + NM_CMP_FIELD(a, b, timestamp); + NM_CMP_FIELD(a, b, lifetime); + NM_CMP_FIELD(a, b, preferred); + NM_CMP_FIELD(a, b, n_ifa_flags); + NM_CMP_FIELD_STR(a, b, label); + NM_CMP_FIELD_UNSAFE(a, b, external); + NM_CMP_FIELD_UNSAFE(a, b, ip4acd_not_ready); + return 0; +} + +void +nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->ifindex, + obj->addr_source, + obj->timestamp, + obj->lifetime, + obj->preferred, + obj->n_ifa_flags, + obj->plen, + obj->address, + obj->peer_address, + NM_HASH_COMBINE_BOOLS(guint8, obj->external)); +} + +int +nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a, const NMPlatformIP6Address *b) +{ + const struct in6_addr *p_a, *p_b; + + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD_MEMCMP(a, b, address); + NM_CMP_FIELD(a, b, plen); + p_a = nm_platform_ip6_address_get_peer(a); + p_b = nm_platform_ip6_address_get_peer(b); + NM_CMP_DIRECT_MEMCMP(p_a, p_b, sizeof(*p_a)); + NM_CMP_FIELD(a, b, addr_source); + NM_CMP_FIELD(a, b, timestamp); + NM_CMP_FIELD(a, b, lifetime); + NM_CMP_FIELD(a, b, preferred); + NM_CMP_FIELD(a, b, n_ifa_flags); + NM_CMP_FIELD_UNSAFE(a, b, external); + return 0; +} + +void +nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, + NMPlatformIPRouteCmpType cmp_type, + NMHashState * h) +{ + switch (cmp_type) { + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: + nm_hash_update_vals( + h, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + nm_utils_ip4_address_clear_host_address(obj->network, obj->plen), + obj->plen, + obj->metric, + obj->tos, + NM_HASH_COMBINE_BOOLS(guint8, obj->metric_any, obj->table_any)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + nm_hash_update_vals( + h, + obj->type_coerced, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + nm_utils_ip4_address_clear_host_address(obj->network, obj->plen), + obj->plen, + obj->metric, + obj->tos, + /* on top of WEAK_ID: */ + obj->ifindex, + nmp_utils_ip_config_source_round_trip_rtprot(obj->rt_source), + _ip_route_scope_inv_get_normalized(obj), + obj->gateway, + obj->mss, + obj->pref_src, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + obj->r_rtm_flags & RTNH_F_ONLINK, + NM_HASH_COMBINE_BOOLS(guint8, + obj->metric_any, + obj->table_any, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: + nm_hash_update_vals( + h, + obj->type_coerced, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + obj->ifindex, + nm_utils_ip4_address_clear_host_address(obj->network, obj->plen), + obj->plen, + obj->metric, + obj->gateway, + nmp_utils_ip_config_source_round_trip_rtprot(obj->rt_source), + _ip_route_scope_inv_get_normalized(obj), + obj->tos, + obj->mss, + obj->pref_src, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + obj->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK), + NM_HASH_COMBINE_BOOLS(guint8, + obj->metric_any, + obj->table_any, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + nm_hash_update_vals(h, + obj->type_coerced, + obj->table_coerced, + obj->ifindex, + obj->network, + obj->plen, + obj->metric, + obj->gateway, + obj->rt_source, + obj->scope_inv, + obj->tos, + obj->mss, + obj->pref_src, + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + obj->r_rtm_flags, + NM_HASH_COMBINE_BOOLS(guint8, + obj->metric_any, + obj->table_any, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu)); + break; + } +} + +int +nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a, + const NMPlatformIP4Route *b, + NMPlatformIPRouteCmpType cmp_type) +{ + NM_CMP_SELF(a, b); + switch (cmp_type) { + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + NM_CMP_FIELD_UNSAFE(a, b, table_any); + NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)), + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b))); + NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(a->network, b->network, MIN(a->plen, b->plen)); + NM_CMP_FIELD(a, b, plen); + NM_CMP_FIELD_UNSAFE(a, b, metric_any); + NM_CMP_FIELD(a, b, metric); + NM_CMP_FIELD(a, b, tos); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, type_coerced); + NM_CMP_DIRECT(nmp_utils_ip_config_source_round_trip_rtprot(a->rt_source), + nmp_utils_ip_config_source_round_trip_rtprot(b->rt_source)); + NM_CMP_DIRECT(_ip_route_scope_inv_get_normalized(a), + _ip_route_scope_inv_get_normalized(b)); + NM_CMP_FIELD(a, b, gateway); + NM_CMP_FIELD(a, b, mss); + NM_CMP_FIELD(a, b, pref_src); + NM_CMP_FIELD(a, b, window); + NM_CMP_FIELD(a, b, cwnd); + NM_CMP_FIELD(a, b, initcwnd); + NM_CMP_FIELD(a, b, initrwnd); + NM_CMP_FIELD(a, b, mtu); + NM_CMP_DIRECT(a->r_rtm_flags & RTNH_F_ONLINK, b->r_rtm_flags & RTNH_F_ONLINK); + NM_CMP_FIELD_UNSAFE(a, b, lock_window); + NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_mtu); + } + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + NM_CMP_FIELD(a, b, type_coerced); + NM_CMP_FIELD_UNSAFE(a, b, table_any); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)), + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b))); + } else + NM_CMP_FIELD(a, b, table_coerced); + NM_CMP_FIELD(a, b, ifindex); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(a->network, b->network, MIN(a->plen, b->plen)); + else + NM_CMP_FIELD(a, b, network); + NM_CMP_FIELD(a, b, plen); + NM_CMP_FIELD_UNSAFE(a, b, metric_any); + NM_CMP_FIELD(a, b, metric); + NM_CMP_FIELD(a, b, gateway); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT(nmp_utils_ip_config_source_round_trip_rtprot(a->rt_source), + nmp_utils_ip_config_source_round_trip_rtprot(b->rt_source)); + NM_CMP_DIRECT(_ip_route_scope_inv_get_normalized(a), + _ip_route_scope_inv_get_normalized(b)); + } else { + NM_CMP_FIELD(a, b, rt_source); + NM_CMP_FIELD(a, b, scope_inv); + } + NM_CMP_FIELD(a, b, mss); + NM_CMP_FIELD(a, b, pref_src); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT(a->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK), + b->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK)); + } else + NM_CMP_FIELD(a, b, r_rtm_flags); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD_UNSAFE(a, b, lock_window); + NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_mtu); + NM_CMP_FIELD(a, b, window); + NM_CMP_FIELD(a, b, cwnd); + NM_CMP_FIELD(a, b, initcwnd); + NM_CMP_FIELD(a, b, initrwnd); + NM_CMP_FIELD(a, b, mtu); + break; + } + return 0; +} + +void +nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj, + NMPlatformIPRouteCmpType cmp_type, + NMHashState * h) +{ + struct in6_addr a1, a2; + + switch (cmp_type) { + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: + nm_hash_update_vals( + h, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + *nm_utils_ip6_address_clear_host_address(&a1, &obj->network, obj->plen), + obj->plen, + obj->metric, + *nm_utils_ip6_address_clear_host_address(&a2, &obj->src, obj->src_plen), + obj->src_plen, + NM_HASH_COMBINE_BOOLS(guint8, obj->metric_any, obj->table_any)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + nm_hash_update_vals( + h, + obj->type_coerced, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + *nm_utils_ip6_address_clear_host_address(&a1, &obj->network, obj->plen), + obj->plen, + obj->metric, + *nm_utils_ip6_address_clear_host_address(&a2, &obj->src, obj->src_plen), + obj->src_plen, + NM_HASH_COMBINE_BOOLS(guint8, obj->metric_any, obj->table_any), + /* on top of WEAK_ID: */ + obj->ifindex, + obj->gateway); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: + nm_hash_update_vals( + h, + obj->type_coerced, + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)), + obj->ifindex, + *nm_utils_ip6_address_clear_host_address(&a1, &obj->network, obj->plen), + obj->plen, + obj->metric, + obj->gateway, + obj->pref_src, + *nm_utils_ip6_address_clear_host_address(&a2, &obj->src, obj->src_plen), + obj->src_plen, + nmp_utils_ip_config_source_round_trip_rtprot(obj->rt_source), + obj->mss, + obj->r_rtm_flags & RTM_F_CLONED, + NM_HASH_COMBINE_BOOLS(guint8, + obj->metric_any, + obj->table_any, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu), + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + _route_pref_normalize(obj->rt_pref)); + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + nm_hash_update_vals(h, + obj->type_coerced, + obj->table_coerced, + obj->ifindex, + obj->network, + obj->metric, + obj->gateway, + obj->pref_src, + obj->src, + obj->src_plen, + obj->rt_source, + obj->mss, + obj->r_rtm_flags, + NM_HASH_COMBINE_BOOLS(guint8, + obj->metric_any, + obj->table_any, + obj->lock_window, + obj->lock_cwnd, + obj->lock_initcwnd, + obj->lock_initrwnd, + obj->lock_mtu), + obj->window, + obj->cwnd, + obj->initcwnd, + obj->initrwnd, + obj->mtu, + obj->rt_pref); + break; + } +} + +int +nm_platform_ip6_route_cmp(const NMPlatformIP6Route *a, + const NMPlatformIP6Route *b, + NMPlatformIPRouteCmpType cmp_type) +{ + NM_CMP_SELF(a, b); + switch (cmp_type) { + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + NM_CMP_FIELD_UNSAFE(a, b, table_any); + NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)), + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b))); + NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(&a->network, &b->network, MIN(a->plen, b->plen)); + NM_CMP_FIELD(a, b, plen); + NM_CMP_FIELD_UNSAFE(a, b, metric_any); + NM_CMP_FIELD(a, b, metric); + NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(&a->src, &b->src, MIN(a->src_plen, b->src_plen)); + NM_CMP_FIELD(a, b, src_plen); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, type_coerced); + NM_CMP_FIELD_IN6ADDR(a, b, gateway); + } + break; + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: + case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + NM_CMP_FIELD(a, b, type_coerced); + NM_CMP_FIELD_UNSAFE(a, b, table_any); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)), + nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b))); + } else + NM_CMP_FIELD(a, b, table_coerced); + NM_CMP_FIELD(a, b, ifindex); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(&a->network, &b->network, MIN(a->plen, b->plen)); + else + NM_CMP_FIELD_IN6ADDR(a, b, network); + NM_CMP_FIELD(a, b, plen); + NM_CMP_FIELD_UNSAFE(a, b, metric_any); + NM_CMP_FIELD(a, b, metric); + NM_CMP_FIELD_IN6ADDR(a, b, gateway); + NM_CMP_FIELD_IN6ADDR(a, b, pref_src); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(&a->src, &b->src, MIN(a->src_plen, b->src_plen)); + NM_CMP_FIELD(a, b, src_plen); + NM_CMP_DIRECT(nmp_utils_ip_config_source_round_trip_rtprot(a->rt_source), + nmp_utils_ip_config_source_round_trip_rtprot(b->rt_source)); + } else { + NM_CMP_FIELD_IN6ADDR(a, b, src); + NM_CMP_FIELD(a, b, src_plen); + NM_CMP_FIELD(a, b, rt_source); + } + NM_CMP_FIELD(a, b, mss); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { + NM_CMP_DIRECT(a->r_rtm_flags & RTM_F_CLONED, b->r_rtm_flags & RTM_F_CLONED); + } else + NM_CMP_FIELD(a, b, r_rtm_flags); + NM_CMP_FIELD_UNSAFE(a, b, lock_window); + NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd); + NM_CMP_FIELD_UNSAFE(a, b, lock_mtu); + NM_CMP_FIELD(a, b, window); + NM_CMP_FIELD(a, b, cwnd); + NM_CMP_FIELD(a, b, initcwnd); + NM_CMP_FIELD(a, b, initrwnd); + NM_CMP_FIELD(a, b, mtu); + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) + NM_CMP_DIRECT(_route_pref_normalize(a->rt_pref), _route_pref_normalize(b->rt_pref)); + else + NM_CMP_FIELD(a, b, rt_pref); + break; + } + return 0; +} + +#define _ROUTING_RULE_FLAGS_IGNORE \ + (FIB_RULE_UNRESOLVED | FIB_RULE_IIF_DETACHED | FIB_RULE_OIF_DETACHED) + +#define _routing_rule_compare(cmp_type, kernel_support_type) \ + ((cmp_type) == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL \ + || nm_platform_kernel_support_get(kernel_support_type)) + +void +nm_platform_routing_rule_hash_update(const NMPlatformRoutingRule *obj, + NMPlatformRoutingRuleCmpType cmp_type, + NMHashState * h) +{ + gboolean cmp_full = TRUE; + gsize addr_size; + guint32 flags_mask = G_MAXUINT32; + + if (G_UNLIKELY(!NM_IN_SET(obj->addr_family, AF_INET, AF_INET6))) { + /* the address family is not one of the supported ones. That means, the + * instance will only compare equal to itself (pointer-equality). */ + nm_hash_update_val(h, (gconstpointer) obj); + return; + } + + switch (cmp_type) { + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID: + + flags_mask &= ~_ROUTING_RULE_FLAGS_IGNORE; + + /* fall-through */ + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY: + + cmp_full = FALSE; + + /* fall-through */ + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL: + + nm_hash_update_vals( + h, + obj->addr_family, + obj->tun_id, + obj->table, + obj->flags & flags_mask, + obj->priority, + obj->fwmark, + obj->fwmask, + ((cmp_full + || (cmp_type == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY + && obj->action == FR_ACT_GOTO)) + ? obj->goto_target + : (guint32) 0u), + ((cmp_full || obj->addr_family == AF_INET) ? obj->flow : (guint32) 0u), + NM_HASH_COMBINE_BOOLS( + guint8, + (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE) + ? obj->uid_range_has + : FALSE)), + obj->suppress_prefixlen_inverse, + obj->suppress_ifgroup_inverse, + (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV) + ? (cmp_full ? (guint16) obj->l3mdev : (guint16) !!obj->l3mdev) + : G_MAXUINT16), + obj->action, + obj->tos, + obj->src_len, + obj->dst_len, + (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL) + ? (guint16) obj->protocol + : G_MAXUINT16)); + addr_size = nm_utils_addr_family_to_size(obj->addr_family); + if (cmp_full || obj->src_len > 0) + nm_hash_update(h, &obj->src, addr_size); + if (cmp_full || obj->dst_len > 0) + nm_hash_update(h, &obj->dst, addr_size); + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE)) { + if (cmp_full || obj->uid_range_has) + nm_hash_update_valp(h, &obj->uid_range); + } + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO)) { + nm_hash_update_val(h, obj->ip_proto); + nm_hash_update_valp(h, &obj->sport_range); + nm_hash_update_valp(h, &obj->dport_range); + } + nm_hash_update_str(h, obj->iifname); + nm_hash_update_str(h, obj->oifname); + return; + } + + nm_assert_not_reached(); +} + +int +nm_platform_routing_rule_cmp(const NMPlatformRoutingRule *a, + const NMPlatformRoutingRule *b, + NMPlatformRoutingRuleCmpType cmp_type) +{ + gboolean cmp_full = TRUE; + gsize addr_size; + bool valid; + guint32 flags_mask = G_MAXUINT32; + + NM_CMP_SELF(a, b); + + valid = NM_IN_SET(a->addr_family, AF_INET, AF_INET6); + NM_CMP_DIRECT(valid, (bool) NM_IN_SET(b->addr_family, AF_INET, AF_INET6)); + + if (G_UNLIKELY(!valid)) { + /* the address family is not one of the supported ones. That means, the + * instance will only compare equal to itself. */ + NM_CMP_DIRECT((uintptr_t) a, (uintptr_t) b); + nm_assert_not_reached(); + return 0; + } + + switch (cmp_type) { + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID: + + flags_mask &= ~_ROUTING_RULE_FLAGS_IGNORE; + + /* fall-through */ + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY: + + cmp_full = FALSE; + + /* fall-through */ + case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL: + NM_CMP_FIELD(a, b, addr_family); + NM_CMP_FIELD(a, b, action); + NM_CMP_FIELD(a, b, priority); + NM_CMP_FIELD(a, b, tun_id); + + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV)) { + if (cmp_full) + NM_CMP_FIELD(a, b, l3mdev); + else + NM_CMP_FIELD_BOOL(a, b, l3mdev); + } + + NM_CMP_FIELD(a, b, table); + + NM_CMP_DIRECT(a->flags & flags_mask, b->flags & flags_mask); + + NM_CMP_FIELD(a, b, fwmark); + NM_CMP_FIELD(a, b, fwmask); + + if (cmp_full + || (cmp_type == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY + && a->action == FR_ACT_GOTO)) + NM_CMP_FIELD(a, b, goto_target); + + NM_CMP_FIELD(a, b, suppress_prefixlen_inverse); + NM_CMP_FIELD(a, b, suppress_ifgroup_inverse); + NM_CMP_FIELD(a, b, tos); + + if (cmp_full || a->addr_family == AF_INET) + NM_CMP_FIELD(a, b, flow); + + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL)) + NM_CMP_FIELD(a, b, protocol); + + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO)) { + NM_CMP_FIELD(a, b, ip_proto); + NM_CMP_FIELD(a, b, sport_range.start); + NM_CMP_FIELD(a, b, sport_range.end); + NM_CMP_FIELD(a, b, dport_range.start); + NM_CMP_FIELD(a, b, dport_range.end); + } + + addr_size = nm_utils_addr_family_to_size(a->addr_family); + + NM_CMP_FIELD(a, b, src_len); + if (cmp_full || a->src_len > 0) + NM_CMP_FIELD_MEMCMP_LEN(a, b, src, addr_size); + + NM_CMP_FIELD(a, b, dst_len); + if (cmp_full || a->dst_len > 0) + NM_CMP_FIELD_MEMCMP_LEN(a, b, dst, addr_size); + + if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE)) { + NM_CMP_FIELD_UNSAFE(a, b, uid_range_has); + if (cmp_full || a->uid_range_has) { + NM_CMP_FIELD(a, b, uid_range.start); + NM_CMP_FIELD(a, b, uid_range.end); + } + } + + NM_CMP_FIELD_STR(a, b, iifname); + NM_CMP_FIELD_STR(a, b, oifname); + return 0; + } + + nm_assert_not_reached(); + return 0; +} + +/** + * nm_platform_ip_address_cmp_expiry: + * @a: a NMPlatformIPAddress to compare + * @b: the other NMPlatformIPAddress to compare + * + * Compares two addresses and returns which one has a longer remaining lifetime. + * If both addresses have the same lifetime, look at the remaining preferred time. + * + * For comparison, only the timestamp, lifetime and preferred fields are considered. + * If they compare equal (== 0), their other fields were not considered. + * + * Returns: -1, 0, or 1 according to the comparison + **/ +int +nm_platform_ip_address_cmp_expiry(const NMPlatformIPAddress *a, const NMPlatformIPAddress *b) +{ + gint64 ta = 0, tb = 0; + + NM_CMP_SELF(a, b); + + if (a->lifetime == NM_PLATFORM_LIFETIME_PERMANENT || a->lifetime == 0) + ta = G_MAXINT64; + else if (a->timestamp) + ta = ((gint64) a->timestamp) + a->lifetime; + + if (b->lifetime == NM_PLATFORM_LIFETIME_PERMANENT || b->lifetime == 0) + tb = G_MAXINT64; + else if (b->timestamp) + tb = ((gint64) b->timestamp) + b->lifetime; + + if (ta == tb) { + /* if the lifetime is equal, compare the preferred time. */ + ta = tb = 0; + + if (a->preferred == NM_PLATFORM_LIFETIME_PERMANENT + || a->lifetime == 0 /* lifetime==0 means permanent! */) + ta = G_MAXINT64; + else if (a->timestamp) + ta = ((gint64) a->timestamp) + a->preferred; + + if (b->preferred == NM_PLATFORM_LIFETIME_PERMANENT || b->lifetime == 0) + tb = G_MAXINT64; + else if (b->timestamp) + tb = ((gint64) b->timestamp) + b->preferred; + + if (ta == tb) + return 0; + } + + return ta < tb ? -1 : 1; +} + +/*****************************************************************************/ + +GHashTable * +nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex) +{ + const NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIter iter; + const NMPObject * obj; + NMPLookup lookup; + GHashTable * hash; + + g_return_val_if_fail(NM_IS_PLATFORM(self), NULL); + g_return_val_if_fail(ifindex > 0, NULL); + + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex); + + head_entry = nmp_cache_lookup(NM_PLATFORM_GET_PRIVATE(self)->cache, &lookup); + + if (!head_entry) + return NULL; + + hash = g_hash_table_new(nm_direct_hash, NULL); + + nmp_cache_iter_for_each (&iter, head_entry, &obj) { + const NMPlatformIP4Address *a = NMP_OBJECT_CAST_IP4_ADDRESS(obj); + + g_hash_table_add(hash, GUINT_TO_POINTER(a->address)); + } + + return hash; +} + +/*****************************************************************************/ + +const char * +nm_platform_signal_change_type_to_string(NMPlatformSignalChangeType change_type) +{ + switch (change_type) { + case NM_PLATFORM_SIGNAL_ADDED: + return "added"; + case NM_PLATFORM_SIGNAL_CHANGED: + return "changed"; + case NM_PLATFORM_SIGNAL_REMOVED: + return "removed"; + default: + g_return_val_if_reached("UNKNOWN"); + } +} + +static void +log_link(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformLink * device, + NMPlatformSignalChangeType change_type, + gpointer user_data) +{ + _LOG3D("signal: link %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_link_to_string(device, NULL, 0)); +} + +static void +log_ip4_address(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformIP4Address * address, + NMPlatformSignalChangeType change_type, + gpointer user_data) +{ + _LOG3D("signal: address 4 %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_ip4_address_to_string(address, NULL, 0)); +} + +static void +log_ip6_address(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformIP6Address * address, + NMPlatformSignalChangeType change_type, + gpointer user_data) +{ + _LOG3D("signal: address 6 %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_ip6_address_to_string(address, NULL, 0)); +} + +static void +log_ip4_route(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformIP4Route * route, + NMPlatformSignalChangeType change_type, + gpointer user_data) +{ + _LOG3D("signal: route 4 %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_ip4_route_to_string(route, NULL, 0)); +} + +static void +log_ip6_route(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformIP6Route * route, + NMPlatformSignalChangeType change_type, + gpointer user_data) +{ + _LOG3D("signal: route 6 %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_ip6_route_to_string(route, NULL, 0)); +} + +static void +log_routing_rule(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformRoutingRule * routing_rule, + NMPlatformSignalChangeType change_type, + gpointer user_data) +{ + /* routing rules don't have an ifindex. We probably should refactor the signals that are emitted for platform changes. */ + _LOG3D("signal: rt-rule %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_routing_rule_to_string(routing_rule, NULL, 0)); +} + +static void +log_qdisc(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformQdisc * qdisc, + NMPlatformSignalChangeType change_type, + gpointer user_data) +{ + _LOG3D("signal: qdisc %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_qdisc_to_string(qdisc, NULL, 0)); +} + +static void +log_tfilter(NMPlatform * self, + NMPObjectType obj_type, + int ifindex, + NMPlatformTfilter * tfilter, + NMPlatformSignalChangeType change_type, + gpointer user_data) +{ + _LOG3D("signal: tfilter %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_tfilter_to_string(tfilter, NULL, 0)); +} + +/*****************************************************************************/ + +void +nm_platform_cache_update_emit_signal(NMPlatform * self, + NMPCacheOpsType cache_op, + const NMPObject *obj_old, + const NMPObject *obj_new) +{ + gboolean visible_new; + gboolean visible_old; + const NMPObject *o; + const NMPClass * klass; + int ifindex; + + nm_assert(NM_IN_SET((NMPlatformSignalChangeType) cache_op, + NM_PLATFORM_SIGNAL_NONE, + NM_PLATFORM_SIGNAL_ADDED, + NM_PLATFORM_SIGNAL_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED)); + + ASSERT_nmp_cache_ops(nm_platform_get_cache(self), cache_op, obj_old, obj_new); + + NMTST_ASSERT_PLATFORM_NETNS_CURRENT(self); + + switch (cache_op) { + case NMP_CACHE_OPS_ADDED: + if (!nmp_object_is_visible(obj_new)) + return; + o = obj_new; + break; + case NMP_CACHE_OPS_UPDATED: + visible_old = nmp_object_is_visible(obj_old); + visible_new = nmp_object_is_visible(obj_new); + if (!visible_old && visible_new) { + o = obj_new; + cache_op = NMP_CACHE_OPS_ADDED; + } else if (visible_old && !visible_new) { + o = obj_old; + cache_op = NMP_CACHE_OPS_REMOVED; + } else if (!visible_new) { + /* it was invisible and stayed invisible. Nothing to do. */ + return; + } else + o = obj_new; + break; + case NMP_CACHE_OPS_REMOVED: + if (!nmp_object_is_visible(obj_old)) + return; + o = obj_old; + break; + default: + nm_assert(cache_op == NMP_CACHE_OPS_UNCHANGED); + return; + } + + klass = NMP_OBJECT_GET_CLASS(o); + + if (klass->obj_type == NMP_OBJECT_TYPE_ROUTING_RULE) + ifindex = 0; + else + ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(o)->ifindex; + + if (klass->obj_type == NMP_OBJECT_TYPE_IP4_ROUTE + && NM_PLATFORM_GET_PRIVATE(self)->ip4_dev_route_blacklist_gc_timeout_id + && NM_IN_SET(cache_op, NMP_CACHE_OPS_ADDED, NMP_CACHE_OPS_UPDATED)) + _ip4_dev_route_blacklist_notify_route(self, o); + + _LOG3t("emit signal %s %s: %s", + klass->signal_type, + nm_platform_signal_change_type_to_string((NMPlatformSignalChangeType) cache_op), + nmp_object_to_string(o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + + nmp_object_ref(o); + g_signal_emit(self, + _nm_platform_signal_id_get(klass->signal_type_id), + 0, + (int) klass->obj_type, + ifindex, + &o->object, + (int) cache_op); + nmp_object_unref(o); +} + +/*****************************************************************************/ + +NMPCache * +nm_platform_get_cache(NMPlatform *self) +{ + return NM_PLATFORM_GET_PRIVATE(self)->cache; +} + +NMPNetns * +nm_platform_netns_get(NMPlatform *self) +{ + _CHECK_SELF(self, klass, NULL); + + return self->_netns; +} + +gboolean +nm_platform_netns_push(NMPlatform *self, NMPNetns **netns) +{ + g_return_val_if_fail(NM_IS_PLATFORM(self), FALSE); + + if (self->_netns && !nmp_netns_push(self->_netns)) { + NM_SET_OUT(netns, NULL); + return FALSE; + } + + NM_SET_OUT(netns, self->_netns); + return TRUE; +} + +/*****************************************************************************/ + +const _NMPlatformVTableRouteUnion nm_platform_vtable_route = { + .v4 = + { + .is_ip4 = TRUE, + .obj_type = NMP_OBJECT_TYPE_IP4_ROUTE, + .addr_family = AF_INET, + .sizeof_route = sizeof(NMPlatformIP4Route), + .route_cmp = (int (*)(const NMPlatformIPXRoute *a, + const NMPlatformIPXRoute *b, + NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip4_route_cmp, + .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, + char * buf, + gsize len)) nm_platform_ip4_route_to_string, + }, + .v6 = + { + .is_ip4 = FALSE, + .obj_type = NMP_OBJECT_TYPE_IP6_ROUTE, + .addr_family = AF_INET6, + .sizeof_route = sizeof(NMPlatformIP6Route), + .route_cmp = (int (*)(const NMPlatformIPXRoute *a, + const NMPlatformIPXRoute *b, + NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip6_route_cmp, + .route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, + char * buf, + gsize len)) nm_platform_ip6_route_to_string, + }, +}; + +/*****************************************************************************/ + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMPlatform * self = NM_PLATFORM(object); + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_NETNS_SUPPORT: + /* construct-only */ + if (g_value_get_boolean(value)) { + NMPNetns *netns; + + netns = nmp_netns_get_current(); + if (netns) + self->_netns = g_object_ref(netns); + } + break; + case PROP_USE_UDEV: + /* construct-only */ + priv->use_udev = g_value_get_boolean(value); + break; + case PROP_LOG_WITH_PTR: + /* construct-only */ + priv->log_with_ptr = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +nm_platform_init(NMPlatform *self) +{ + self->_priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_PLATFORM, NMPlatformPrivate); +} + +static GObject * +constructor(GType type, guint n_construct_params, GObjectConstructParam *construct_params) +{ + GObject * object; + NMPlatform * self; + NMPlatformPrivate *priv; + + object = G_OBJECT_CLASS(nm_platform_parent_class) + ->constructor(type, n_construct_params, construct_params); + self = NM_PLATFORM(object); + priv = NM_PLATFORM_GET_PRIVATE(self); + + priv->multi_idx = nm_dedup_multi_index_new(); + + priv->cache = nmp_cache_new(priv->multi_idx, priv->use_udev); + + return object; +} + +static void +finalize(GObject *object) +{ + NMPlatform * self = NM_PLATFORM(object); + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self); + + nm_clear_g_source(&priv->ip4_dev_route_blacklist_check_id); + nm_clear_g_source(&priv->ip4_dev_route_blacklist_gc_timeout_id); + nm_clear_pointer(&priv->ip4_dev_route_blacklist_hash, g_hash_table_unref); + g_clear_object(&self->_netns); + nm_dedup_multi_index_unref(priv->multi_idx); + nmp_cache_free(priv->cache); +} + +static void +nm_platform_class_init(NMPlatformClass *platform_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(platform_class); + + g_type_class_add_private(object_class, sizeof(NMPlatformPrivate)); + + object_class->constructor = constructor; + object_class->set_property = set_property; + object_class->finalize = finalize; + + platform_class->wifi_set_powersave = wifi_set_powersave; + + g_object_class_install_property( + object_class, + PROP_NETNS_SUPPORT, + g_param_spec_boolean(NM_PLATFORM_NETNS_SUPPORT, + "", + "", + NM_PLATFORM_NETNS_SUPPORT_DEFAULT, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property( + object_class, + PROP_USE_UDEV, + g_param_spec_boolean(NM_PLATFORM_USE_UDEV, + "", + "", + FALSE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property( + object_class, + PROP_LOG_WITH_PTR, + g_param_spec_boolean(NM_PLATFORM_LOG_WITH_PTR, + "", + "", + TRUE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + +#define SIGNAL(signal, signal_id, method) \ + G_STMT_START \ + { \ + signals[signal] = \ + g_signal_new_class_handler("" signal_id "", \ + G_OBJECT_CLASS_TYPE(object_class), \ + G_SIGNAL_RUN_FIRST, \ + G_CALLBACK(method), \ + NULL, \ + NULL, \ + NULL, \ + G_TYPE_NONE, \ + 4, \ + G_TYPE_INT, /* (int) NMPObjectType */ \ + G_TYPE_INT, /* ifindex */ \ + G_TYPE_POINTER /* const NMPObject * */, \ + G_TYPE_INT /* (int) NMPlatformSignalChangeType */ \ + ); \ + } \ + G_STMT_END + + /* Signals */ + SIGNAL(NM_PLATFORM_SIGNAL_ID_LINK, NM_PLATFORM_SIGNAL_LINK_CHANGED, log_link); + SIGNAL(NM_PLATFORM_SIGNAL_ID_IP4_ADDRESS, + NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + log_ip4_address); + SIGNAL(NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS, + NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + log_ip6_address); + SIGNAL(NM_PLATFORM_SIGNAL_ID_IP4_ROUTE, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, log_ip4_route); + SIGNAL(NM_PLATFORM_SIGNAL_ID_IP6_ROUTE, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, log_ip6_route); + SIGNAL(NM_PLATFORM_SIGNAL_ID_ROUTING_RULE, + NM_PLATFORM_SIGNAL_ROUTING_RULE_CHANGED, + log_routing_rule); + SIGNAL(NM_PLATFORM_SIGNAL_ID_QDISC, NM_PLATFORM_SIGNAL_QDISC_CHANGED, log_qdisc); + SIGNAL(NM_PLATFORM_SIGNAL_ID_TFILTER, NM_PLATFORM_SIGNAL_TFILTER_CHANGED, log_tfilter); +} diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h new file mode 100644 index 0000000..981465b --- /dev/null +++ b/src/libnm-platform/nm-platform.h @@ -0,0 +1,2358 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2009 - 2018 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_PLATFORM_H__ +#define __NETWORKMANAGER_PLATFORM_H__ + +#include "libnm-platform/nmp-base.h" +#include "libnm-base/nm-base.h" + +#define NM_TYPE_PLATFORM (nm_platform_get_type()) +#define NM_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_PLATFORM, NMPlatform)) +#define NM_PLATFORM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_PLATFORM, NMPlatformClass)) +#define NM_IS_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_PLATFORM)) +#define NM_IS_PLATFORM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_PLATFORM)) +#define NM_PLATFORM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_PLATFORM, NMPlatformClass)) + +#define NM_PLATFORM_NETNS_SUPPORT_DEFAULT FALSE + +/*****************************************************************************/ + +#define NM_PLATFORM_NETNS_SUPPORT "netns-support" +#define NM_PLATFORM_USE_UDEV "use-udev" +#define NM_PLATFORM_LOG_WITH_PTR "log-with-ptr" + +/*****************************************************************************/ + +/* IFNAMSIZ is both defined in and . In the past, these + * headers conflicted, so we cannot simply include either of them in a header-file.*/ +#define NMP_IFNAMSIZ 16 + +/*****************************************************************************/ + +struct _NMPWireGuardPeer; + +struct udev_device; + +typedef gboolean (*NMPObjectPredicateFunc)(const NMPObject *obj, gpointer user_data); + +/* workaround for older libnl version, that does not define these flags. */ +#ifndef IFA_F_MANAGETEMPADDR + #define IFA_F_MANAGETEMPADDR 0x100 +#endif +#ifndef IFA_F_NOPREFIXROUTE + #define IFA_F_NOPREFIXROUTE 0x200 +#endif + +#define NM_RT_SCOPE_LINK 253 /* RT_SCOPE_LINK */ + +/* Define of the IN6_ADDR_GEN_MODE_* values to workaround old kernel headers + * that don't define it. */ +#define NM_IN6_ADDR_GEN_MODE_UNKNOWN 255 /* no corresponding value. */ +#define NM_IN6_ADDR_GEN_MODE_EUI64 0 /* IN6_ADDR_GEN_MODE_EUI64 */ +#define NM_IN6_ADDR_GEN_MODE_NONE 1 /* IN6_ADDR_GEN_MODE_NONE */ +#define NM_IN6_ADDR_GEN_MODE_STABLE_PRIVACY 2 /* IN6_ADDR_GEN_MODE_STABLE_PRIVACY */ +#define NM_IN6_ADDR_GEN_MODE_RANDOM 3 /* IN6_ADDR_GEN_MODE_RANDOM */ + +#define NM_IFF_MULTI_QUEUE 0x0100 /* IFF_MULTI_QUEUE */ + +/* Redefine this in host's endianness */ +#define NM_GRE_KEY 0x2000 + +typedef enum { + NMP_NLM_FLAG_F_ECHO = 0x08, /* NLM_F_ECHO, Echo this request */ + + /* use our own platform enum for the nlmsg-flags. Otherwise, we'd have + * to include */ + NMP_NLM_FLAG_F_REPLACE = 0x100, /* NLM_F_REPLACE, Override existing */ + NMP_NLM_FLAG_F_EXCL = 0x200, /* NLM_F_EXCL, Do not touch, if it exists */ + NMP_NLM_FLAG_F_CREATE = 0x400, /* NLM_F_CREATE, Create, if it does not exist */ + NMP_NLM_FLAG_F_APPEND = 0x800, /* NLM_F_APPEND, Add to end of list */ + + NMP_NLM_FLAG_FMASK = 0xFFFF, /* a mask for all NMP_NLM_FLAG_F_* flags */ + + /* instructs NM to suppress logging an error message for any failures + * received from kernel. + * + * It will still log with debug-level, and it will still log + * other failures aside the kernel response. */ + NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE = 0x10000, + + /* the following aliases correspond to iproute2's `ip route CMD` for + * RTM_NEWROUTE, with CMD being one of add, change, replace, prepend, + * append and test. */ + NMP_NLM_FLAG_ADD = NMP_NLM_FLAG_F_CREATE | NMP_NLM_FLAG_F_EXCL, + NMP_NLM_FLAG_CHANGE = NMP_NLM_FLAG_F_REPLACE, + NMP_NLM_FLAG_REPLACE = NMP_NLM_FLAG_F_CREATE | NMP_NLM_FLAG_F_REPLACE, + NMP_NLM_FLAG_PREPEND = NMP_NLM_FLAG_F_CREATE, + NMP_NLM_FLAG_APPEND = NMP_NLM_FLAG_F_CREATE | NMP_NLM_FLAG_F_APPEND, + NMP_NLM_FLAG_TEST = NMP_NLM_FLAG_F_EXCL, +} NMPNlmFlags; + +typedef enum { + /* compare fields which kernel considers as similar routes. + * It is a looser comparisong then NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID + * and means that `ip route add` would fail to add two routes + * that have the same NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID. + * On the other hand, `ip route append` would allow that, as + * long as NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID differs. */ + NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, + + /* compare two routes as kernel would allow to add them with + * `ip route append`. In other words, kernel does not allow you to + * add two routes (at the same time) which compare equal according + * to NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID. + * + * For the ID we can only recognize route fields that we actually implement. + * However, kernel supports more routing options, some of them also part of + * the ID. NetworkManager is oblivious to these options and will wrongly think + * that two routes are identical, while they are not. That can lead to an + * inconsistent platform cache. Not much what we can do about that, except + * implementing all options that kernel supports *sigh*. See rh#1337860. + */ + NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, + + /* compare all fields as they make sense for kernel. For example, + * a route destination 192.168.1.5/24 is not accepted by kernel and + * we treat it identical to 192.168.1.0/24. Semantically these + * routes are identical, but NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL will + * report them as different. + * + * The result shall be identical to call first nm_platform_ip_route_normalize() + * on both routes and then doing a full comparison. */ + NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY, + + /* compare all fields. This should have the same effect as memcmp(), + * except allowing for undefined data in holes between field alignment. + */ + NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL, + +} NMPlatformIPRouteCmpType; + +typedef enum { + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID, + + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY, + + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL, +} NMPlatformRoutingRuleCmpType; + +typedef struct { + union { + guint8 data[20 /* _NM_UTILS_HWADDR_LEN_MAX */]; + NMEtherAddr ether_addr; + }; + guint8 len; +} NMPLinkAddress; + +/* assert that NMEtherAddr does not affect the alignment of NMPLinkAddress struct. */ +G_STATIC_ASSERT(_nm_alignof(NMEtherAddr) == 1); +G_STATIC_ASSERT(_nm_alignof(NMPLinkAddress) == 1); + +gconstpointer nmp_link_address_get(const NMPLinkAddress *addr, size_t *length); +GBytes * nmp_link_address_get_as_bytes(const NMPLinkAddress *addr); + +typedef enum { + + /* match-flags are strictly inclusive. That means, + * by default nothing is matched, but if you enable a particular + * flag, a candidate that matches passes the check. + * + * In other words: adding more flags can only extend the result + * set of matching objects. + * + * Also, the flags form partitions. Like, an address can be either of + * ADDRTYPE_NORMAL or ADDRTYPE_LINKLOCAL, but never both. Same for + * the ADDRSTATE match types. + */ + NM_PLATFORM_MATCH_WITH_NONE = 0, + + NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL = (1LL << 0), + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL = (1LL << 1), + NM_PLATFORM_MATCH_WITH_ADDRTYPE__ANY = + NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL | NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL, + + NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL = (1LL << 2), + NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE = (1LL << 3), + NM_PLATFORM_MATCH_WITH_ADDRSTATE_DADFAILED = (1LL << 4), + NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY = NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_DADFAILED, +} NMPlatformMatchFlags; + +#define NM_PLATFORM_LINK_OTHER_NETNS (-1) + +struct _NMPlatformObject { + /* the object type has no fields of its own, it is only used to having + * a special pointer type that can be used to indicate "any" type. */ + char _dummy_don_t_use_me; +}; + +#define __NMPlatformObjWithIfindex_COMMON \ + int ifindex; \ + ; + +struct _NMPlatformObjWithIfindex { + __NMPlatformObjWithIfindex_COMMON; +}; + +struct _NMPlatformLink { + __NMPlatformObjWithIfindex_COMMON; + char name[NMP_IFNAMSIZ]; + NMLinkType type; + + /* rtnl_link_get_type(), IFLA_INFO_KIND. */ + /* NMPlatform initializes this field with a static string. */ + const char *kind; + + /* NMPlatform initializes this field with a static string. */ + const char *driver; + + int master; + + /* rtnl_link_get_link(), IFLA_LINK. + * If IFLA_LINK_NETNSID indicates that the parent is in another namespace, + * this field be set to (negative) NM_PLATFORM_LINK_OTHER_NETNS. */ + int parent; + + /* IFF_* flags. Note that the flags in 'struct ifinfomsg' are declared as 'unsigned'. */ + guint n_ifi_flags; + + guint mtu; + + /* rtnl_link_get_arptype(), ifinfomsg.ifi_type. */ + guint32 arptype; + + /* IFLA_ADDRESS */ + NMPLinkAddress l_address; + + /* IFLA_BROADCAST */ + NMPLinkAddress l_broadcast; + + /* rtnl_link_inet6_get_token(), IFLA_INET6_TOKEN */ + NMUtilsIPv6IfaceId inet6_token; + + /* The bitwise inverse of rtnl_link_inet6_get_addr_gen_mode(). It is inverse + * to have a default of 0 -- meaning: unspecified. That way, a struct + * initialized with memset(0) has and unset value.*/ + guint8 inet6_addr_gen_mode_inv; + + /* Statistics */ + guint64 rx_packets; + guint64 rx_bytes; + guint64 tx_packets; + guint64 tx_bytes; + + /* @connected is mostly identical to (@n_ifi_flags & IFF_UP). Except for bridge/bond masters, + * where we coerce the link as disconnect if it has no slaves. */ + bool connected : 1; + + bool initialized : 1; +}; + +typedef enum { /*< skip >*/ + NM_PLATFORM_SIGNAL_ID_NONE, + NM_PLATFORM_SIGNAL_ID_LINK, + NM_PLATFORM_SIGNAL_ID_IP4_ADDRESS, + NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS, + NM_PLATFORM_SIGNAL_ID_IP4_ROUTE, + NM_PLATFORM_SIGNAL_ID_IP6_ROUTE, + NM_PLATFORM_SIGNAL_ID_ROUTING_RULE, + NM_PLATFORM_SIGNAL_ID_QDISC, + NM_PLATFORM_SIGNAL_ID_TFILTER, + _NM_PLATFORM_SIGNAL_ID_LAST, +} NMPlatformSignalIdType; + +guint _nm_platform_signal_id_get(NMPlatformSignalIdType signal_type); + +typedef enum { + NM_PLATFORM_SIGNAL_NONE, + NM_PLATFORM_SIGNAL_ADDED, + NM_PLATFORM_SIGNAL_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, +} NMPlatformSignalChangeType; + +#define NM_PLATFORM_IP_ADDRESS_CAST(address) \ + NM_CONSTCAST(NMPlatformIPAddress, \ + (address), \ + NMPlatformIPXAddress, \ + NMPlatformIP4Address, \ + NMPlatformIP6Address) + +#define __NMPlatformIPAddress_COMMON \ + __NMPlatformObjWithIfindex_COMMON; \ + NMIPConfigSource addr_source; \ + \ + /* Timestamp in seconds in the reference system of nm_utils_get_monotonic_timestamp_*(). + * + * The rules are: + * 1 @lifetime==0: @timestamp and @preferred is irrelevant (but mostly set to 0 too). Such addresses + * are permanent. This rule is so that unset addresses (calloc) are permanent by default. + * 2 @lifetime==@preferred==NM_PLATFORM_LIFETIME_PERMANENT: @timestamp is irrelevant (but mostly + * set to 0). Such addresses are permanent. + * 3 Non permanent addresses should (almost) always have @timestamp > 0. 0 is not a valid timestamp + * and never returned by nm_utils_get_monotonic_timestamp_sec(). In this case @valid/@preferred + * is anchored at @timestamp. + * 4 Non permanent addresses with @timestamp == 0 are implicitly anchored at *now*, thus the time + * moves as time goes by. This is usually not useful, except e.g. nm_platform_ip[46]_address_add(). + * + * Non permanent addresses from DHCP/RA might have the @timestamp set to the moment of when the + * lease was received. Addresses from kernel might have the @timestamp based on the last modification + * time of the addresses. But don't rely on this behaviour, the @timestamp is only defined for anchoring + * @lifetime and @preferred. + */ \ + guint32 timestamp; \ + guint32 lifetime; /* seconds since timestamp */ \ + guint32 preferred; /* seconds since timestamp */ \ + \ + /* ifa_flags in 'struct ifaddrmsg' from , extended to 32 bit by + * IFA_FLAGS attribute. */ \ + guint32 n_ifa_flags; \ + \ + guint8 plen; \ + \ + /* FIXME(l3cfg): the external marker won't be necessary anymore, because we only + * merge addresses we care about, and ignore (don't remove) external addresses. */ \ + bool external : 1; \ + \ + bool use_ip4_broadcast_address : 1; \ + \ + /* Whether the address is ready to be configured. By default, an address is, but this + * flag may indicate that the address is just for tracking purpose only, but the ACD + * state is not yet ready for the address to be configured. */ \ + bool ip4acd_not_ready : 1; \ + ; + +/** + * NMPlatformIPAddress: + * + * Common parts of NMPlatformIP4Address and NMPlatformIP6Address. + **/ +typedef struct { + __NMPlatformIPAddress_COMMON; + union { + guint8 address_ptr[1]; + guint32 __dummy_for_32bit_alignment; + }; +} NMPlatformIPAddress; + +/** + * NMPlatformIP4Address: + * @timestamp: timestamp as returned by nm_utils_get_monotonic_timestamp_sec() + **/ +struct _NMPlatformIP4Address { + __NMPlatformIPAddress_COMMON; + + /* The local address IFA_LOCAL. */ + in_addr_t address; + + /* The IFA_ADDRESS PTP peer address. This field is rather important, because + * it constitutes the identifier for the IPv4 address (e.g. you can add two + * addresses that only differ by their peer's network-part. + * + * Beware that for most cases, NetworkManager doesn't want to set an explicit + * peer-address. However, that corresponds to setting the peer address to @address + * itself. Leaving peer-address unset/zero, means explicitly setting the peer + * address to 0.0.0.0, which you probably don't want. + * */ + in_addr_t peer_address; /* PTP peer address */ + + /* IFA_BROADCAST. + * + * This parameter is ignored unless use_ip4_broadcast_address is TRUE. + * See nm_platform_ip4_broadcast_address_from_addr(). */ + in_addr_t broadcast_address; + + char label[NMP_IFNAMSIZ]; +}; + +/** + * NMPlatformIP6Address: + * @timestamp: timestamp as returned by nm_utils_get_monotonic_timestamp_sec() + **/ +struct _NMPlatformIP6Address { + __NMPlatformIPAddress_COMMON; + struct in6_addr address; + struct in6_addr peer_address; +}; + +typedef union { + NMPlatformIPAddress ax; + NMPlatformIP4Address a4; + NMPlatformIP6Address a6; +} NMPlatformIPXAddress; + +#undef __NMPlatformIPAddress_COMMON + +#define NM_PLATFORM_IP4_ADDRESS_INIT(...) (&((const NMPlatformIP4Address){__VA_ARGS__})) + +#define NM_PLATFORM_IP6_ADDRESS_INIT(...) (&((const NMPlatformIP6Address){__VA_ARGS__})) + +/* Default value for adding an IPv4 route. This is also what iproute2 does. + * Note that contrary to IPv6, you can add routes with metric 0 and it is even + * the default. + */ +#define NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4 ((guint32) 0u) + +/* Default value for adding an IPv6 route. This is also what iproute2 does. + * Adding an IPv6 route with metric 0, kernel translates to IP6_RT_PRIO_USER (1024). + * + * Note that kernel doesn't allow adding IPv6 routes with metric zero via netlink. + * It however can itself add routes with metric zero. */ +#define NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6 ((guint32) 1024u) + +/* For IPv4, kernel adds a device route (subnet routes) with metric 0 when user + * configures addresses. */ +#define NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE ((guint32) 0u) + +#define __NMPlatformIPRoute_COMMON \ + __NMPlatformObjWithIfindex_COMMON; \ + \ + /* The NMIPConfigSource. For routes that we receive from cache this corresponds + * to the rtm_protocol field (and is one of the NM_IP_CONFIG_SOURCE_RTPROT_* values). + * When adding a route, the source will be coerced to the protocol using + * nmp_utils_ip_config_source_coerce_to_rtprot(). + * + * rtm_protocol is part of the primary key of an IPv4 route (meaning, you can add + * two IPv4 routes that only differ in their rtm_protocol. For IPv6, that is not + * the case. + * + * When deleting an IPv4/IPv6 route, the rtm_protocol field must match (even + * if it is not part of the primary key for IPv6) -- unless rtm_protocol is set + * to zero, in which case the first matching route (with proto ignored) is deleted. */ \ + NMIPConfigSource rt_source; \ + \ + guint8 plen; \ + \ + /* RTA_METRICS: + * + * For IPv4 routes, these properties are part of their + * ID (meaning: you can add otherwise identical IPv4 routes that + * only differ by the metric property). + * On the other hand, for IPv6 you cannot add two IPv6 routes that only differ + * by an RTA_METRICS property. + * + * When deleting a route, kernel seems to ignore the RTA_METRICS properties. + * That is a problem/bug for IPv4 because you cannot explicitly select which + * route to delete. Kernel just picks the first. See rh#1475642. */ \ + \ + /* RTA_METRICS.RTAX_LOCK (iproute2: "lock" arguments) */ \ + bool lock_window : 1; \ + bool lock_cwnd : 1; \ + bool lock_initcwnd : 1; \ + bool lock_initrwnd : 1; \ + bool lock_mtu : 1; \ + \ + /* if TRUE, the "metric" field is interpreted as an offset that is added to a default + * metric. For example, form a DHCP lease we don't know the actually used metric, because + * that is determined by upper layers (the configuration). However, we have a default + * metric that should be used. So we set "metric_any" to %TRUE, which means to use + * the default metric. However, we still treat the "metric" field as an offset that + * will be added to the default metric. In most case, you want that "metric" is zero + * when setting "metric_any". */ \ + bool metric_any : 1; \ + \ + /* like "metric_any", the table is determined by other layers of the code. + * This field overrides "table_coerced" field. If "table_any" is true, then + * the "table_coerced" field is ignored (unlike for the metric). */ \ + bool table_any : 1; \ + \ + /* rtnh_flags + * + * Routes with rtm_flags RTM_F_CLONED are hidden by platform and + * do not exist from the point-of-view of platform users. + * Such a route is not alive, according to nmp_object_is_alive(). + * + * NOTE: currently we ignore all flags except RTM_F_CLONED + * and RTNH_F_ONLINK. + * We also may not properly consider the flags as part of the ID + * in route-cmp. */ \ + unsigned r_rtm_flags; \ + \ + /* RTA_METRICS.RTAX_ADVMSS (iproute2: advmss) */ \ + guint32 mss; \ + \ + /* RTA_METRICS.RTAX_WINDOW (iproute2: window) */ \ + guint32 window; \ + \ + /* RTA_METRICS.RTAX_CWND (iproute2: cwnd) */ \ + guint32 cwnd; \ + \ + /* RTA_METRICS.RTAX_INITCWND (iproute2: initcwnd) */ \ + guint32 initcwnd; \ + \ + /* RTA_METRICS.RTAX_INITRWND (iproute2: initrwnd) */ \ + guint32 initrwnd; \ + \ + /* RTA_METRICS.RTAX_MTU (iproute2: mtu) */ \ + guint32 mtu; \ + \ + /* RTA_PRIORITY (iproute2: metric) + * If "metric_any" is %TRUE, then this is interpreted as an offset that will be + * added to a default base metric. In such cases, the offset is usually zero. */ \ + guint32 metric; \ + \ + /* rtm_table, RTA_TABLE. + * + * This is not the original table ID. Instead, 254 (RT_TABLE_MAIN) and + * zero (RT_TABLE_UNSPEC) are swapped, so that the default is the main + * table. Use nm_platform_route_table_coerce()/nm_platform_route_table_uncoerce(). */ \ + guint32 table_coerced; \ + \ + /* rtm_type. + * + * This is not the original type, if type_coerced is 0 then + * it means RTN_UNSPEC otherwise the type value is preserved. + * */ \ + guint8 type_coerced; \ + \ + /*end*/ + +typedef struct { + __NMPlatformIPRoute_COMMON; + union { + guint8 network_ptr[1]; + guint32 __dummy_for_32bit_alignment; + }; +} NMPlatformIPRoute; + +#define NM_PLATFORM_IP_ROUTE_CAST(route) \ + NM_CONSTCAST(NMPlatformIPRoute, \ + (route), \ + NMPlatformIPXRoute, \ + NMPlatformIP4Route, \ + NMPlatformIP6Route) + +#define NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route) (NM_PLATFORM_IP_ROUTE_CAST(route)->plen <= 0) + +struct _NMPlatformIP4Route { + __NMPlatformIPRoute_COMMON; + in_addr_t network; + + /* RTA_GATEWAY. The gateway is part of the primary key for a route */ + in_addr_t gateway; + + /* RTA_PREFSRC (called "src" by iproute2). + * + * pref_src is part of the ID of an IPv4 route. When deleting a route, + * pref_src must match, unless set to 0.0.0.0 to match any. */ + in_addr_t pref_src; + + /* rtm_tos (iproute2: tos) + * + * For IPv4, tos is part of the weak-id (like metric). + * + * For IPv6, tos is ignored by kernel. */ + guint8 tos; + + /* The bitwise inverse of the route scope rtm_scope. It is inverted so that the + * default value (RT_SCOPE_NOWHERE) is zero. Use nm_platform_route_scope_inv() + * to convert back and forth between the inverse representation and the + * real value. + * + * rtm_scope is part of the primary key for IPv4 routes. When deleting a route, + * the scope must match, unless it is left at RT_SCOPE_NOWHERE, in which case the first + * matching route is deleted. + * + * For IPv6 routes, the scope is ignored and kernel always assumes global scope. + * Hence, this field is only in NMPlatformIP4Route. */ + guint8 scope_inv; +}; + +struct _NMPlatformIP6Route { + __NMPlatformIPRoute_COMMON; + struct in6_addr network; + + /* RTA_GATEWAY. The gateway is part of the primary key for a route */ + struct in6_addr gateway; + + /* RTA_PREFSRC (called "src" by iproute2). + * + * pref_src is not part of the ID for an IPv6 route. You cannot add two + * routes that only differ by pref_src. + * + * When deleting a route, pref_src is ignored by kernel. */ + struct in6_addr pref_src; + + /* RTA_SRC and rtm_src_len (called "from" by iproute2). + * + * Kernel clears the host part of src/src_plen. + * + * src/src_plen is part of the ID of a route just like network/plen. That is, + * Not only `ip route append`, but also `ip route add` allows to add routes that only + * differ in their src/src_plen. + */ + struct in6_addr src; + guint8 src_plen; + + /* RTA_PREF router preference. + * + * The type is guint8 to keep the struct size small. But the values are compatible with + * the NMIcmpv6RouterPref enum. */ + guint8 rt_pref; +}; + +typedef union { + NMPlatformIPRoute rx; + NMPlatformIP4Route r4; + NMPlatformIP6Route r6; +} NMPlatformIPXRoute; + +#undef __NMPlatformIPRoute_COMMON + +typedef struct { + /* struct fib_rule_uid_range */ + guint32 start; + guint32 end; +} NMFibRuleUidRange; + +typedef struct { + /* struct fib_rule_port_range */ + guint16 start; + guint16 end; +} NMFibRulePortRange; + +typedef struct { + NMIPAddr src; /* FRA_SRC */ + NMIPAddr dst; /* FRA_DST */ + guint64 tun_id; /* betoh64(FRA_TUN_ID) */ + guint32 table; /* (struct fib_rule_hdr).table, FRA_TABLE */ + guint32 flags; /* (struct fib_rule_hdr).flags */ + guint32 priority; /* RA_PRIORITY */ + guint32 fwmark; /* FRA_FWMARK */ + guint32 fwmask; /* FRA_FWMASK */ + guint32 goto_target; /* FRA_GOTO */ + guint32 flow; /* FRA_FLOW */ + guint32 suppress_prefixlen_inverse; /* ~(FRA_SUPPRESS_PREFIXLEN) */ + guint32 suppress_ifgroup_inverse; /* ~(FRA_SUPPRESS_IFGROUP) */ + NMFibRuleUidRange uid_range; /* FRA_UID_RANGE */ + NMFibRulePortRange sport_range; /* FRA_SPORT_RANGE */ + NMFibRulePortRange dport_range; /* FRA_DPORT_RANGE */ + char iifname[NMP_IFNAMSIZ]; /* FRA_IIFNAME */ + char oifname[NMP_IFNAMSIZ]; /* FRA_OIFNAME */ + guint8 addr_family; /* (struct fib_rule_hdr).family */ + guint8 action; /* (struct fib_rule_hdr).action */ + guint8 tos; /* (struct fib_rule_hdr).tos */ + guint8 src_len; /* (struct fib_rule_hdr).src_len */ + guint8 dst_len; /* (struct fib_rule_hdr).dst_len */ + guint8 l3mdev; /* FRA_L3MDEV */ + guint8 protocol; /* FRA_PROTOCOL */ + guint8 ip_proto; /* FRA_IP_PROTO */ + + bool uid_range_has : 1; /* has(FRA_UID_RANGE) */ +} NMPlatformRoutingRule; + +#define NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET (~((guint32) 0)) + +#define NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED ((guint32) 0x83126E97u) + +G_STATIC_ASSERT(((((guint64) NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED) * 1000u) >> 10) + == (guint64) INT_MAX); + +typedef struct { + guint32 limit; + guint32 flows; + guint32 target; + guint32 interval; + guint32 quantum; + + /* TCA_FQ_CODEL_CE_THRESHOLD: kernel internally stores this value as + * ((val64 * NSEC_PER_USEC) >> CODEL_SHIFT). The default value (in + * the domain with this coercion) is CODEL_DISABLED_THRESHOLD (INT_MAX). + * That means, "disabled" is expressed on RTM_NEWQDISC netlink API by absence of the + * netlink attribute but also as the special value 0x83126E97u + * (NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED). + * Beware: zero is not the default you must always explicitly set this value. */ + guint32 ce_threshold; + + /* TCA_FQ_CODEL_MEMORY_LIMIT: note that only values <= 2^31 are accepted by kernel + * and kernel defaults to 32MB. + * Note that we use the special value NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET + * to indicate that no explicit limit is set (when we send a RTM_NEWQDISC request). + * This will cause kernel to choose the default (32MB). + * Beware: zero is not the default you must always explicitly set this value. */ + guint32 memory_limit; + + bool ecn : 1; +} NMPlatformQdiscFqCodel; + +typedef struct { + unsigned quantum; + int perturb_period; + guint32 limit; + unsigned divisor; + unsigned flows; + unsigned depth; +} NMPlatformQdiscSfq; + +typedef struct { + guint64 rate; + guint32 burst; + guint32 limit; + guint32 latency; +} NMPlatformQdiscTbf; + +typedef struct { + __NMPlatformObjWithIfindex_COMMON; + + /* beware, kind is embedded in an NMPObject, hence you must + * take care of the lifetime of the string. */ + const char *kind; + + int addr_family; + guint32 handle; + guint32 parent; + guint32 info; + union { + NMPlatformQdiscFqCodel fq_codel; + NMPlatformQdiscSfq sfq; + NMPlatformQdiscTbf tbf; + }; +} NMPlatformQdisc; + +typedef struct { + char sdata[32]; +} NMPlatformActionSimple; + +typedef struct { + int ifindex; + bool egress : 1; + bool ingress : 1; + bool mirror : 1; + bool redirect : 1; +} NMPlatformActionMirred; + +typedef struct { + /* beware, kind is embedded in an NMPObject, hence you must + * take care of the lifetime of the string. */ + const char *kind; + + union { + NMPlatformActionSimple simple; + NMPlatformActionMirred mirred; + }; +} NMPlatformAction; + +#define NM_PLATFORM_ACTION_KIND_SIMPLE "simple" +#define NM_PLATFORM_ACTION_KIND_MIRRED "mirred" + +typedef struct { + __NMPlatformObjWithIfindex_COMMON; + + /* beware, kind is embedded in an NMPObject, hence you must + * take care of the lifetime of the string. */ + const char *kind; + + int addr_family; + guint32 handle; + guint32 parent; + guint32 info; + NMPlatformAction action; +} NMPlatformTfilter; + +#undef __NMPlatformObjWithIfindex_COMMON + +typedef struct { + gboolean is_ip4; + NMPObjectType obj_type; + int addr_family; + gsize sizeof_route; + int (*route_cmp)(const NMPlatformIPXRoute *a, + const NMPlatformIPXRoute *b, + NMPlatformIPRouteCmpType cmp_type); + const char *(*route_to_string)(const NMPlatformIPXRoute *route, char *buf, gsize len); +} NMPlatformVTableRoute; + +typedef union { + struct { + NMPlatformVTableRoute v6; + NMPlatformVTableRoute v4; + }; + NMPlatformVTableRoute vx[2]; +} _NMPlatformVTableRouteUnion; + +extern const _NMPlatformVTableRouteUnion nm_platform_vtable_route; + +typedef struct { + guint16 id; + guint32 qos; + bool proto_ad : 1; +} NMPlatformVFVlan; + +typedef struct { + guint32 index; + guint32 min_tx_rate; + guint32 max_tx_rate; + guint num_vlans; + NMPlatformVFVlan *vlans; + struct { + guint8 data[20]; /* _NM_UTILS_HWADDR_LEN_MAX */ + guint8 len; + } mac; + gint8 spoofchk; + gint8 trust; +} NMPlatformVF; + +typedef struct { + guint16 vid_start; + guint16 vid_end; + bool untagged : 1; + bool pvid : 1; +} NMPlatformBridgeVlan; + +typedef struct { + NMEtherAddr group_addr; + bool mcast_querier : 1; + bool mcast_query_use_ifaddr : 1; + bool mcast_snooping : 1; + bool stp_state : 1; + bool vlan_stats_enabled : 1; + guint16 group_fwd_mask; + guint16 priority; + guint16 vlan_protocol; + guint32 ageing_time; + guint32 forward_delay; + guint32 hello_time; + guint32 max_age; + guint32 mcast_last_member_count; + guint32 mcast_startup_query_count; + guint32 mcast_hash_max; + guint64 mcast_last_member_interval; + guint64 mcast_membership_interval; + guint64 mcast_querier_interval; + guint64 mcast_query_interval; + guint64 mcast_query_response_interval; + guint64 mcast_startup_query_interval; + guint8 mcast_router; +} NMPlatformLnkBridge; + +extern const NMPlatformLnkBridge nm_platform_lnk_bridge_default; + +typedef struct { + in_addr_t local; + in_addr_t remote; + int parent_ifindex; + guint16 input_flags; + guint16 output_flags; + guint32 input_key; + guint32 output_key; + guint8 ttl; + guint8 tos; + bool path_mtu_discovery : 1; + bool is_tap : 1; +} NMPlatformLnkGre; + +typedef struct { + int p_key; + const char *mode; +} NMPlatformLnkInfiniband; + +typedef struct { + struct in6_addr local; + struct in6_addr remote; + int parent_ifindex; + guint8 ttl; + guint8 tclass; + guint8 encap_limit; + guint8 proto; + guint flow_label; + guint32 flags; + + /* IP6GRE only */ + guint32 input_key; + guint32 output_key; + guint16 input_flags; + guint16 output_flags; + bool is_tap : 1; + bool is_gre : 1; +} NMPlatformLnkIp6Tnl; + +typedef struct { + in_addr_t local; + in_addr_t remote; + int parent_ifindex; + guint8 ttl; + guint8 tos; + bool path_mtu_discovery : 1; +} NMPlatformLnkIpIp; + +typedef struct { + int parent_ifindex; + guint64 sci; /* host byte order */ + guint64 cipher_suite; + guint32 window; + guint8 icv_length; + guint8 encoding_sa; + guint8 validation; + bool encrypt : 1; + bool protect : 1; + bool include_sci : 1; + bool es : 1; + bool scb : 1; + bool replay_protect : 1; +} NMPlatformLnkMacsec; + +typedef struct { + guint mode; + bool no_promisc : 1; + bool tap : 1; +} NMPlatformLnkMacvlan; + +typedef struct { + in_addr_t local; + in_addr_t remote; + int parent_ifindex; + guint16 flags; + guint8 ttl; + guint8 tos; + guint8 proto; + bool path_mtu_discovery : 1; +} NMPlatformLnkSit; + +typedef struct { + guint32 owner; + guint32 group; + + guint8 type; + + bool owner_valid : 1; + bool group_valid : 1; + + bool pi : 1; + bool vnet_hdr : 1; + bool multi_queue : 1; + bool persist : 1; +} NMPlatformLnkTun; + +typedef struct { + /* rtnl_link_vlan_get_id(), IFLA_VLAN_ID */ + guint16 id; + _NMVlanFlags flags; +} NMPlatformLnkVlan; + +typedef struct { + guint32 table; +} NMPlatformLnkVrf; + +typedef struct { + struct in6_addr group6; + struct in6_addr local6; + in_addr_t group; + in_addr_t local; + int parent_ifindex; + guint32 id; + guint32 ageing; + guint32 limit; + guint16 dst_port; + guint16 src_port_min; + guint16 src_port_max; + guint8 tos; + guint8 ttl; + bool learning : 1; + bool proxy : 1; + bool rsc : 1; + bool l2miss : 1; + bool l3miss : 1; +} NMPlatformLnkVxlan; + +#define NMP_WIREGUARD_PUBLIC_KEY_LEN 32 +#define NMP_WIREGUARD_SYMMETRIC_KEY_LEN 32 + +typedef struct { + guint32 fwmark; + guint16 listen_port; + guint8 private_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; + guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; +} NMPlatformLnkWireGuard; + +typedef enum { + NM_PLATFORM_WIREGUARD_CHANGE_FLAG_NONE = 0, + NM_PLATFORM_WIREGUARD_CHANGE_FLAG_REPLACE_PEERS = (1LL << 0), + NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY = (1LL << 1), + NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_LISTEN_PORT = (1LL << 2), + NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK = (1LL << 3), +} NMPlatformWireGuardChangeFlags; + +typedef enum { + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_NONE = 0, + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REMOVE_ME = (1LL << 0), + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_PRESHARED_KEY = (1LL << 1), + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_KEEPALIVE_INTERVAL = (1LL << 2), + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ENDPOINT = (1LL << 3), + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ALLOWEDIPS = (1LL << 4), + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REPLACE_ALLOWEDIPS = (1LL << 5), + + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_DEFAULT = + NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_PRESHARED_KEY + | NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_KEEPALIVE_INTERVAL + | NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ENDPOINT + | NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ALLOWEDIPS, + +} NMPlatformWireGuardChangePeerFlags; + +typedef void (*NMPlatformAsyncCallback)(GError *error, gpointer user_data); + +/*****************************************************************************/ + +typedef enum { + NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS, + NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL, + NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF, + NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV, + NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE, + NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL, + NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED, + + /* this also includes FRA_SPORT_RANGE and FRA_DPORT_RANGE which + * were added at the same time. */ + NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO, + + _NM_PLATFORM_KERNEL_SUPPORT_NUM, +} NMPlatformKernelSupportType; + +extern volatile int _nm_platform_kernel_support_state[_NM_PLATFORM_KERNEL_SUPPORT_NUM]; + +int _nm_platform_kernel_support_init(NMPlatformKernelSupportType type, int value); + +static inline gboolean +_nm_platform_kernel_support_detected(NMPlatformKernelSupportType type) +{ + nm_assert(_NM_INT_NOT_NEGATIVE(type) && type < G_N_ELEMENTS(_nm_platform_kernel_support_state)); + + return G_LIKELY(g_atomic_int_get(&_nm_platform_kernel_support_state[type]) != 0); +} + +static inline NMOptionBool +nm_platform_kernel_support_get_full(NMPlatformKernelSupportType type, gboolean init_if_not_set) +{ + int v; + + nm_assert(_NM_INT_NOT_NEGATIVE(type) && type < G_N_ELEMENTS(_nm_platform_kernel_support_state)); + + v = g_atomic_int_get(&_nm_platform_kernel_support_state[type]); + if (G_UNLIKELY(v == 0)) { + if (!init_if_not_set) + return NM_OPTION_BOOL_DEFAULT; + v = _nm_platform_kernel_support_init(type, 0); + } + return (v >= 0); +} + +static inline gboolean +nm_platform_kernel_support_get(NMPlatformKernelSupportType type) +{ + return nm_platform_kernel_support_get_full(type, TRUE) != NM_OPTION_BOOL_FALSE; +} + +/*****************************************************************************/ + +struct _NMPlatformPrivate; + +struct _NMPlatform { + GObject parent; + NMPNetns * _netns; + struct _NMPlatformPrivate *_priv; +}; + +typedef struct { + GObjectClass parent; + + gboolean (*sysctl_set)(NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + const char *value); + void (*sysctl_set_async)(NMPlatform * self, + const char * pathid, + int dirfd, + const char * path, + const char *const * values, + NMPlatformAsyncCallback callback, + gpointer data, + GCancellable * cancellable); + char *(*sysctl_get)(NMPlatform *self, const char *pathid, int dirfd, const char *path); + + void (*refresh_all)(NMPlatform *self, NMPObjectType obj_type); + void (*process_events)(NMPlatform *self); + + int (*link_add)(NMPlatform * self, + NMLinkType type, + const char * name, + int parent, + const void * address, + size_t address_len, + guint32 mtu, + gconstpointer extra_data, + const NMPlatformLink **out_link); + gboolean (*link_delete)(NMPlatform *self, int ifindex); + gboolean (*link_refresh)(NMPlatform *self, int ifindex); + gboolean (*link_set_netns)(NMPlatform *self, int ifindex, int netns_fd); + gboolean (*link_set_up)(NMPlatform *self, int ifindex, gboolean *out_no_firmware); + gboolean (*link_set_down)(NMPlatform *self, int ifindex); + gboolean (*link_set_arp)(NMPlatform *self, int ifindex); + gboolean (*link_set_noarp)(NMPlatform *self, int ifindex); + + int (*link_set_user_ipv6ll_enabled)(NMPlatform *self, int ifindex, gboolean enabled); + gboolean (*link_set_token)(NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid); + + gboolean (*link_get_permanent_address)(NMPlatform *self, + int ifindex, + guint8 * buf, + size_t * length); + int (*link_set_address)(NMPlatform *self, int ifindex, gconstpointer address, size_t length); + int (*link_set_mtu)(NMPlatform *self, int ifindex, guint32 mtu); + gboolean (*link_set_name)(NMPlatform *self, int ifindex, const char *name); + void (*link_set_sriov_params_async)(NMPlatform * self, + int ifindex, + guint num_vfs, + NMOptionBool autoprobe, + NMPlatformAsyncCallback callback, + gpointer callback_data, + GCancellable * cancellable); + gboolean (*link_set_sriov_vfs)(NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs); + gboolean (*link_set_bridge_vlans)(NMPlatform * self, + int ifindex, + gboolean on_master, + const NMPlatformBridgeVlan *const *vlans); + + char *(*link_get_physical_port_id)(NMPlatform *self, int ifindex); + guint (*link_get_dev_id)(NMPlatform *self, int ifindex); + gboolean (*link_get_wake_on_lan)(NMPlatform *self, int ifindex); + gboolean (*link_get_driver_info)(NMPlatform *self, + int ifindex, + char ** out_driver_name, + char ** out_driver_version, + char ** out_fw_version); + + gboolean (*link_supports_carrier_detect)(NMPlatform *self, int ifindex); + gboolean (*link_supports_vlans)(NMPlatform *self, int ifindex); + gboolean (*link_supports_sriov)(NMPlatform *self, int ifindex); + + gboolean (*link_enslave)(NMPlatform *self, int master, int slave); + gboolean (*link_release)(NMPlatform *self, int master, int slave); + + gboolean (*link_can_assume)(NMPlatform *self, int ifindex); + + int (*link_wireguard_change)(NMPlatform * self, + int ifindex, + const NMPlatformLnkWireGuard * lnk_wireguard, + const struct _NMPWireGuardPeer * peers, + const NMPlatformWireGuardChangePeerFlags *peer_flags, + guint peers_len, + NMPlatformWireGuardChangeFlags change_flags); + + gboolean (*link_vlan_change)(NMPlatform * self, + int ifindex, + _NMVlanFlags flags_mask, + _NMVlanFlags flags_set, + gboolean ingress_reset_all, + const NMVlanQosMapping *ingress_map, + gsize n_ingress_map, + gboolean egress_reset_all, + const NMVlanQosMapping *egress_map, + gsize n_egress_map); + gboolean (*link_tun_add)(NMPlatform * self, + const char * name, + const NMPlatformLnkTun *props, + const NMPlatformLink ** out_link, + int * out_fd); + + gboolean (*infiniband_partition_add)(NMPlatform * self, + int parent, + int p_key, + const NMPlatformLink **out_link); + gboolean (*infiniband_partition_delete)(NMPlatform *self, int parent, int p_key); + + gboolean (*wifi_get_capabilities)(NMPlatform * self, + int ifindex, + _NMDeviceWifiCapabilities *caps); + gboolean (*wifi_get_station)(NMPlatform * self, + int ifindex, + NMEtherAddr *out_bssid, + int * out_quality, + guint32 * out_rate); + gboolean (*wifi_get_bssid)(NMPlatform *self, int ifindex, guint8 *bssid); + guint32 (*wifi_get_frequency)(NMPlatform *self, int ifindex); + int (*wifi_get_quality)(NMPlatform *self, int ifindex); + guint32 (*wifi_get_rate)(NMPlatform *self, int ifindex); + _NM80211Mode (*wifi_get_mode)(NMPlatform *self, int ifindex); + void (*wifi_set_mode)(NMPlatform *self, int ifindex, _NM80211Mode mode); + void (*wifi_set_powersave)(NMPlatform *self, int ifindex, guint32 powersave); + guint32 (*wifi_find_frequency)(NMPlatform *self, int ifindex, const guint32 *freqs); + void (*wifi_indicate_addressing_running)(NMPlatform *self, int ifindex, gboolean running); + _NMSettingWirelessWakeOnWLan (*wifi_get_wake_on_wlan)(NMPlatform *self, int ifindex); + gboolean (*wifi_set_wake_on_wlan)(NMPlatform * self, + int ifindex, + _NMSettingWirelessWakeOnWLan wowl); + + guint32 (*mesh_get_channel)(NMPlatform *self, int ifindex); + gboolean (*mesh_set_channel)(NMPlatform *self, int ifindex, guint32 channel); + gboolean (*mesh_set_ssid)(NMPlatform *self, int ifindex, const guint8 *ssid, gsize len); + + guint16 (*wpan_get_pan_id)(NMPlatform *self, int ifindex); + gboolean (*wpan_set_pan_id)(NMPlatform *self, int ifindex, guint16 pan_id); + guint16 (*wpan_get_short_addr)(NMPlatform *self, int ifindex); + gboolean (*wpan_set_short_addr)(NMPlatform *self, int ifindex, guint16 short_addr); + gboolean (*wpan_set_channel)(NMPlatform *self, int ifindex, guint8 page, guint8 channel); + + gboolean (*object_delete)(NMPlatform *self, const NMPObject *obj); + + gboolean (*ip4_address_add)(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address, + in_addr_t broadcast_address, + guint32 lifetime, + guint32 preferred_lft, + guint32 flags, + const char *label); + gboolean (*ip6_address_add)(NMPlatform * self, + int ifindex, + struct in6_addr address, + guint8 plen, + struct in6_addr peer_address, + guint32 lifetime, + guint32 preferred_lft, + guint32 flags); + gboolean (*ip4_address_delete)(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address); + gboolean (*ip6_address_delete)(NMPlatform * self, + int ifindex, + struct in6_addr address, + guint8 plen); + + int (*ip_route_add)(NMPlatform * self, + NMPNlmFlags flags, + int addr_family, + const NMPlatformIPRoute *route); + int (*ip_route_get)(NMPlatform * self, + int addr_family, + gconstpointer address, + int oif_ifindex, + NMPObject ** out_route); + + int (*routing_rule_add)(NMPlatform * self, + NMPNlmFlags flags, + const NMPlatformRoutingRule *routing_rule); + + int (*qdisc_add)(NMPlatform *self, NMPNlmFlags flags, const NMPlatformQdisc *qdisc); + + int (*tfilter_add)(NMPlatform *self, NMPNlmFlags flags, const NMPlatformTfilter *tfilter); +} NMPlatformClass; + +/* NMPlatform signals + * + * Each signal handler is called with a type-specific object that provides + * key attributes that constitute identity of the object. They may also + * provide additional attributes for convenience. + * + * The object only intended to be used by the signal handler to determine + * the current values. It is no longer valid after the signal handler exits + * but you are free to copy the provided information and use it for later + * reference. + */ +#define NM_PLATFORM_SIGNAL_LINK_CHANGED "link-changed" +#define NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED "ip4-address-changed" +#define NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED "ip6-address-changed" +#define NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED "ip4-route-changed" +#define NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED "ip6-route-changed" +#define NM_PLATFORM_SIGNAL_ROUTING_RULE_CHANGED "routing-rule-changed" +#define NM_PLATFORM_SIGNAL_QDISC_CHANGED "qdisc-changed" +#define NM_PLATFORM_SIGNAL_TFILTER_CHANGED "tfilter-changed" + +const char *nm_platform_signal_change_type_to_string(NMPlatformSignalChangeType change_type); + +/*****************************************************************************/ + +GType nm_platform_get_type(void); + +/*****************************************************************************/ + +static inline in_addr_t +nm_platform_ip4_broadcast_address_create(in_addr_t address, guint8 plen) +{ + return address | ~_nm_utils_ip4_prefix_to_netmask(plen); +} + +static inline in_addr_t +nm_platform_ip4_broadcast_address_from_addr(const NMPlatformIP4Address *addr) +{ + nm_assert(addr); + + if (addr->use_ip4_broadcast_address) + return addr->broadcast_address; + + /* the set broadcast-address gets ignored, and we determine a default brd base + * on the peer IFA_ADDRESS. */ + if (addr->peer_address != 0u && addr->plen < 31 /* RFC3021 */) + return nm_platform_ip4_broadcast_address_create(addr->peer_address, addr->plen); + return 0u; +} + +/*****************************************************************************/ + +/** + * nm_platform_route_table_coerce: + * @table: the route table, in its original value as received + * from rtm_table/RTA_TABLE. + * + * Returns: returns the coerced table id, that can be stored in + * NMPlatformIPRoute.table_coerced. + */ +static inline guint32 +nm_platform_route_table_coerce(guint32 table) +{ + /* For kernel, the default table is RT_TABLE_MAIN (254). + * We want that in NMPlatformIPRoute.table_coerced a numeric + * zero is the default. Hence, @table_coerced swaps the + * value 0 and 254. Use nm_platform_route_table_coerce() + * and nm_platform_route_table_uncoerce() to convert between + * the two domains. */ + switch (table) { + case 0 /* RT_TABLE_UNSPEC */: + return 254; + case 254 /* RT_TABLE_MAIN */: + return 0; + default: + return table; + } +} + +/** + * nm_platform_route_table_uncoerce: + * @table_coerced: the route table, in its coerced value + * @normalize: whether to normalize RT_TABLE_UNSPEC to + * RT_TABLE_MAIN. For kernel, routes with a table id + * RT_TABLE_UNSPEC do not exist and are treated like + * RT_TABLE_MAIN. + * + * Returns: reverts the coerced table ID in NMPlatformIPRoute.table_coerced + * to the original value as kernel understands it. + */ +static inline guint32 +nm_platform_route_table_uncoerce(guint32 table_coerced, gboolean normalize) +{ + /* this undoes nm_platform_route_table_coerce(). */ + switch (table_coerced) { + case 0 /* RT_TABLE_UNSPEC */: + return 254; + case 254 /* RT_TABLE_MAIN */: + return normalize ? 254 : 0; + default: + return table_coerced; + } +} + +static inline gboolean +nm_platform_route_table_is_main(guint32 table) +{ + /* same as + * nm_platform_route_table_uncoerce (table, TRUE) == RT_TABLE_MAIN + * and + * nm_platform_route_table_uncoerce (nm_platform_route_table_coerce (table), TRUE) == RT_TABLE_MAIN + * + * That is, the function operates the same on @table and its coerced + * form. + */ + return table == 0 || table == 254; +} + +/** + * nm_platform_route_scope_inv: + * @scope: the route scope, either its original value, or its inverse. + * + * This function is useful, because the constants such as RT_SCOPE_NOWHERE + * are 'int', so ~scope also gives an 'int'. This function gets the type + * casts to guint8 right. + * + * Returns: the bitwise inverse of the route scope. + * */ +#define nm_platform_route_scope_inv _nm_platform_uint8_inv +static inline guint8 +_nm_platform_uint8_inv(guint8 scope) +{ + return (guint8) ~scope; +} + +/** + * nm_platform_route_type_coerce: + * @table: the route type, in its original value. + * + * Returns: returns the coerced type, that can be stored in + * NMPlatformIPRoute.type_coerced. + */ +static inline guint8 +nm_platform_route_type_coerce(guint8 type) +{ + switch (type) { + case 0 /* RTN_UNSPEC */: + return 1; + case 1 /* RTN_UNICAST */: + return 0; + default: + return type; + } +} + +/** + * nm_platform_route_type_uncoerce: + * @table: the type table, in its coerced value + * + * Returns: reverts the coerced type in NMPlatformIPRoute.type_coerced + * to the original value as kernel understands it. + */ +static inline guint8 +nm_platform_route_type_uncoerce(guint8 type_coerced) +{ + return nm_platform_route_type_coerce(type_coerced); +} + +gboolean nm_platform_get_use_udev(NMPlatform *self); +gboolean nm_platform_get_log_with_ptr(NMPlatform *self); + +NMPNetns *nm_platform_netns_get(NMPlatform *self); +gboolean nm_platform_netns_push(NMPlatform *self, NMPNetns **netns); + +const char *nm_link_type_to_string(NMLinkType link_type); + +#define NMP_SYSCTL_PATHID_ABSOLUTE(path) ((const char *) NULL), -1, (path) + +#define NMP_SYSCTL_PATHID_NETDIR_unsafe(dirfd, ifname, path) \ + nm_sprintf_buf_unsafe_a(NM_STRLEN("net:/sys/class/net//\0") + NMP_IFNAMSIZ + ({ \ + const gsize _l = strlen(path); \ + \ + nm_assert(_l < 200); \ + _l; \ + }), \ + "net:/sys/class/net/%s/%s", \ + (ifname), \ + (path)), \ + (dirfd), (path) + +#define NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, path) \ + nm_sprintf_bufa(NM_STRLEN("net:/sys/class/net//" path "/\0") + NMP_IFNAMSIZ, \ + "net:/sys/class/net/%s/%s", \ + (ifname), \ + path), \ + (dirfd), ("" path "") + +int nm_platform_sysctl_open_netdir(NMPlatform *self, int ifindex, char *out_ifname); +gboolean nm_platform_sysctl_set(NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + const char *value); +void nm_platform_sysctl_set_async(NMPlatform * self, + const char * pathid, + int dirfd, + const char * path, + const char *const * values, + NMPlatformAsyncCallback callback, + gpointer data, + GCancellable * cancellable); +char * nm_platform_sysctl_get(NMPlatform *self, const char *pathid, int dirfd, const char *path); +gint32 nm_platform_sysctl_get_int32(NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + gint32 fallback); +gint64 nm_platform_sysctl_get_int_checked(NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + guint base, + gint64 min, + gint64 max, + gint64 fallback); + +char *nm_platform_sysctl_ip_conf_get(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property); + +gint64 nm_platform_sysctl_ip_conf_get_int_checked(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property, + guint base, + gint64 min, + gint64 max, + gint64 fallback); + +gboolean nm_platform_sysctl_ip_conf_set(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property, + const char *value); + +gboolean nm_platform_sysctl_ip_conf_set_int64(NMPlatform *self, + int addr_family, + const char *ifname, + const char *property, + gint64 value); + +gboolean +nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe(NMPlatform *self, const char *iface, int value); +gboolean nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time(NMPlatform *self, + const char *iface, + guint value_ms); +gboolean nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time(NMPlatform *self, + const char *iface, + guint value_ms); +int nm_platform_sysctl_ip_conf_get_rp_filter_ipv4(NMPlatform *platform, + const char *iface, + gboolean consider_all, + gboolean * out_due_to_all); + +const char *nm_platform_if_indextoname(NMPlatform *self, + int ifindex, + char out_ifname[static 16 /* IFNAMSIZ */]); +int nm_platform_if_nametoindex(NMPlatform *self, const char *ifname); + +const NMPObject *nm_platform_link_get_obj(NMPlatform *self, int ifindex, gboolean visible_only); +const NMPlatformLink *nm_platform_link_get(NMPlatform *self, int ifindex); +const NMPlatformLink *nm_platform_link_get_by_ifname(NMPlatform *self, const char *ifname); +const NMPlatformLink *nm_platform_link_get_by_address(NMPlatform * self, + NMLinkType link_type, + gconstpointer address, + size_t length); + +GPtrArray *nm_platform_link_get_all(NMPlatform *self, gboolean sort_by_name); + +int nm_platform_link_add(NMPlatform * self, + NMLinkType type, + const char * name, + int parent, + const void * address, + size_t address_len, + guint32 mtu, + gconstpointer extra_data, + const NMPlatformLink **out_link); + +static inline int +nm_platform_link_veth_add(NMPlatform * self, + const char * name, + const char * peer, + const NMPlatformLink **out_link) +{ + return nm_platform_link_add(self, NM_LINK_TYPE_VETH, name, 0, NULL, 0, 0, peer, out_link); +} + +static inline int +nm_platform_link_dummy_add(NMPlatform *self, const char *name, const NMPlatformLink **out_link) +{ + return nm_platform_link_add(self, NM_LINK_TYPE_DUMMY, name, 0, NULL, 0, 0, NULL, out_link); +} + +static inline int +nm_platform_link_bridge_add(NMPlatform * self, + const char * name, + const void * address, + size_t address_len, + guint32 mtu, + const NMPlatformLnkBridge *props, + const NMPlatformLink ** out_link) +{ + return nm_platform_link_add(self, + NM_LINK_TYPE_BRIDGE, + name, + 0, + address, + address_len, + mtu, + props, + out_link); +} + +static inline int +nm_platform_link_bond_add(NMPlatform *self, const char *name, const NMPlatformLink **out_link) +{ + return nm_platform_link_add(self, NM_LINK_TYPE_BOND, name, 0, NULL, 0, 0, NULL, out_link); +} + +static inline int +nm_platform_link_team_add(NMPlatform *self, const char *name, const NMPlatformLink **out_link) +{ + return nm_platform_link_add(self, NM_LINK_TYPE_TEAM, name, 0, NULL, 0, 0, NULL, out_link); +} + +static inline int +nm_platform_link_wireguard_add(NMPlatform *self, const char *name, const NMPlatformLink **out_link) +{ + return nm_platform_link_add(self, NM_LINK_TYPE_WIREGUARD, name, 0, NULL, 0, 0, NULL, out_link); +} + +static inline int +nm_platform_link_gre_add(NMPlatform * self, + const char * name, + const void * address, + size_t address_len, + const NMPlatformLnkGre *props, + const NMPlatformLink ** out_link) +{ + g_return_val_if_fail(props, -NME_BUG); + + return nm_platform_link_add(self, + props->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE, + name, + 0, + address, + address_len, + 0, + props, + out_link); +} + +static inline int +nm_platform_link_sit_add(NMPlatform * self, + const char * name, + const NMPlatformLnkSit *props, + const NMPlatformLink ** out_link) +{ + return nm_platform_link_add(self, NM_LINK_TYPE_SIT, name, 0, NULL, 0, 0, props, out_link); +} + +static inline int +nm_platform_link_vlan_add(NMPlatform * self, + const char * name, + int parent, + int vlanid, + guint32 vlanflags, + const NMPlatformLink **out_link) +{ + g_return_val_if_fail(parent >= 0, -NME_BUG); + g_return_val_if_fail(vlanid >= 0, -NME_BUG); + + return nm_platform_link_add(self, + NM_LINK_TYPE_VLAN, + name, + parent, + NULL, + 0, + 0, + &((NMPlatformLnkVlan){ + .id = vlanid, + .flags = vlanflags, + }), + out_link); +} + +static inline int +nm_platform_link_vrf_add(NMPlatform * self, + const char * name, + const NMPlatformLnkVrf *props, + const NMPlatformLink ** out_link) +{ + return nm_platform_link_add(self, NM_LINK_TYPE_VRF, name, 0, NULL, 0, 0, props, out_link); +} + +static inline int +nm_platform_link_vxlan_add(NMPlatform * self, + const char * name, + const NMPlatformLnkVxlan *props, + const NMPlatformLink ** out_link) +{ + return nm_platform_link_add(self, NM_LINK_TYPE_VXLAN, name, 0, NULL, 0, 0, props, out_link); +} + +static inline int +nm_platform_link_6lowpan_add(NMPlatform * self, + const char * name, + int parent, + const NMPlatformLink **out_link) +{ + return nm_platform_link_add(self, + NM_LINK_TYPE_6LOWPAN, + name, + parent, + NULL, + 0, + 0, + NULL, + out_link); +} + +static inline int +nm_platform_link_ip6tnl_add(NMPlatform * self, + const char * name, + const NMPlatformLnkIp6Tnl *props, + const NMPlatformLink ** out_link) +{ + g_return_val_if_fail(props, -NME_BUG); + g_return_val_if_fail(!props->is_gre, -NME_BUG); + + return nm_platform_link_add(self, NM_LINK_TYPE_IP6TNL, name, 0, NULL, 0, 0, props, out_link); +} + +static inline int +nm_platform_link_ip6gre_add(NMPlatform * self, + const char * name, + const void * address, + size_t address_len, + const NMPlatformLnkIp6Tnl *props, + const NMPlatformLink ** out_link) +{ + g_return_val_if_fail(props, -NME_BUG); + g_return_val_if_fail(props->is_gre, -NME_BUG); + + return nm_platform_link_add(self, + props->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE, + name, + 0, + address, + address_len, + 0, + props, + out_link); +} + +static inline int +nm_platform_link_ipip_add(NMPlatform * self, + const char * name, + const NMPlatformLnkIpIp *props, + const NMPlatformLink ** out_link) +{ + g_return_val_if_fail(props, -NME_BUG); + + return nm_platform_link_add(self, NM_LINK_TYPE_IPIP, name, 0, NULL, 0, 0, props, out_link); +} + +static inline int +nm_platform_link_macsec_add(NMPlatform * self, + const char * name, + int parent, + const NMPlatformLnkMacsec *props, + const NMPlatformLink ** out_link) +{ + g_return_val_if_fail(props, -NME_BUG); + g_return_val_if_fail(parent > 0, -NME_BUG); + + return nm_platform_link_add(self, + NM_LINK_TYPE_MACSEC, + name, + parent, + NULL, + 0, + 0, + props, + out_link); +} + +static inline int +nm_platform_link_macvlan_add(NMPlatform * self, + const char * name, + int parent, + const NMPlatformLnkMacvlan *props, + const NMPlatformLink ** out_link) +{ + g_return_val_if_fail(props, -NME_BUG); + g_return_val_if_fail(parent > 0, -NME_BUG); + + return nm_platform_link_add(self, + props->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN, + name, + parent, + NULL, + 0, + 0, + props, + out_link); +} + +gboolean nm_platform_link_delete(NMPlatform *self, int ifindex); + +gboolean nm_platform_link_set_netns(NMPlatform *self, int ifindex, int netns_fd); + +struct _NMDedupMultiHeadEntry; +struct _NMPLookup; +const struct _NMDedupMultiHeadEntry *nm_platform_lookup(NMPlatform * self, + const struct _NMPLookup *lookup); + +#define nm_platform_iter_obj_for_each(iter, self, lookup, obj) \ + for (nm_dedup_multi_iter_init((iter), nm_platform_lookup((self), (lookup))); \ + nm_platform_dedup_multi_iter_next_obj((iter), (obj), NMP_OBJECT_TYPE_UNKNOWN);) + +gboolean nm_platform_lookup_predicate_routes_main(const NMPObject *obj, gpointer user_data); +gboolean nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel(const NMPObject *obj, + gpointer user_data); + +GPtrArray *nm_platform_lookup_clone(NMPlatform * self, + const struct _NMPLookup *lookup, + NMPObjectPredicateFunc predicate, + gpointer user_data); + +/* convenience methods to lookup the link and access fields of NMPlatformLink. */ +int nm_platform_link_get_ifindex(NMPlatform *self, const char *name); +const char *nm_platform_link_get_name(NMPlatform *self, int ifindex); +NMLinkType nm_platform_link_get_type(NMPlatform *self, int ifindex); +gboolean nm_platform_link_is_software(NMPlatform *self, int ifindex); +int nm_platform_link_get_ifi_flags(NMPlatform *self, int ifindex, guint requested_flags); +gboolean nm_platform_link_is_up(NMPlatform *self, int ifindex); +gboolean nm_platform_link_is_connected(NMPlatform *self, int ifindex); +gboolean nm_platform_link_uses_arp(NMPlatform *self, int ifindex); +guint32 nm_platform_link_get_mtu(NMPlatform *self, int ifindex); +gboolean nm_platform_link_get_user_ipv6ll_enabled(NMPlatform *self, int ifindex); + +gconstpointer nm_platform_link_get_address(NMPlatform *self, int ifindex, size_t *length); + +int nm_platform_link_get_master(NMPlatform *self, int slave); + +gboolean nm_platform_link_can_assume(NMPlatform *self, int ifindex); + +gboolean nm_platform_link_get_unmanaged(NMPlatform *self, int ifindex, gboolean *unmanaged); +gboolean nm_platform_link_supports_slaves(NMPlatform *self, int ifindex); +const char *nm_platform_link_get_type_name(NMPlatform *self, int ifindex); + +gboolean nm_platform_link_refresh(NMPlatform *self, int ifindex); +void nm_platform_process_events(NMPlatform *self); + +const NMPlatformLink * +nm_platform_process_events_ensure_link(NMPlatform *self, int ifindex, const char *ifname); + +gboolean nm_platform_link_set_up(NMPlatform *self, int ifindex, gboolean *out_no_firmware); +gboolean nm_platform_link_set_down(NMPlatform *self, int ifindex); +gboolean nm_platform_link_set_arp(NMPlatform *self, int ifindex); +gboolean nm_platform_link_set_noarp(NMPlatform *self, int ifindex); + +const char *nm_platform_link_get_udi(NMPlatform *self, int ifindex); +const char *nm_platform_link_get_path(NMPlatform *self, int ifindex); + +struct udev_device *nm_platform_link_get_udev_device(NMPlatform *self, int ifindex); + +int nm_platform_link_set_user_ipv6ll_enabled(NMPlatform *self, int ifindex, gboolean enabled); +gboolean nm_platform_link_set_ipv6_token(NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid); + +gboolean +nm_platform_link_get_permanent_address(NMPlatform *self, int ifindex, guint8 *buf, size_t *length); +int nm_platform_link_set_address(NMPlatform *self, int ifindex, const void *address, size_t length); +int nm_platform_link_set_mtu(NMPlatform *self, int ifindex, guint32 mtu); +gboolean nm_platform_link_set_name(NMPlatform *self, int ifindex, const char *name); + +void nm_platform_link_set_sriov_params_async(NMPlatform * self, + int ifindex, + guint num_vfs, + NMOptionBool autoprobe, + NMPlatformAsyncCallback callback, + gpointer callback_data, + GCancellable * cancellable); + +gboolean +nm_platform_link_set_sriov_vfs(NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs); +gboolean nm_platform_link_set_bridge_vlans(NMPlatform * self, + int ifindex, + gboolean on_master, + const NMPlatformBridgeVlan *const *vlans); + +char * nm_platform_link_get_physical_port_id(NMPlatform *self, int ifindex); +guint nm_platform_link_get_dev_id(NMPlatform *self, int ifindex); +gboolean nm_platform_link_get_wake_on_lan(NMPlatform *self, int ifindex); +gboolean nm_platform_link_get_driver_info(NMPlatform *self, + int ifindex, + char ** out_driver_name, + char ** out_driver_version, + char ** out_fw_version); + +gboolean nm_platform_link_supports_carrier_detect(NMPlatform *self, int ifindex); +gboolean nm_platform_link_supports_vlans(NMPlatform *self, int ifindex); +gboolean nm_platform_link_supports_sriov(NMPlatform *self, int ifindex); + +gboolean nm_platform_link_enslave(NMPlatform *self, int master, int slave); +gboolean nm_platform_link_release(NMPlatform *self, int master, int slave); + +gboolean nm_platform_sysctl_master_set_option(NMPlatform *self, + int ifindex, + const char *option, + const char *value); +char * nm_platform_sysctl_master_get_option(NMPlatform *self, int ifindex, const char *option); +gboolean nm_platform_sysctl_slave_set_option(NMPlatform *self, + int ifindex, + const char *option, + const char *value); +char * nm_platform_sysctl_slave_get_option(NMPlatform *self, int ifindex, const char *option); + +const NMPObject *nm_platform_link_get_lnk(NMPlatform * self, + int ifindex, + NMLinkType link_type, + const NMPlatformLink **out_link); +const NMPlatformLnkBridge * +nm_platform_link_get_lnk_bridge(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkGre * +nm_platform_link_get_lnk_gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkGre * +nm_platform_link_get_lnk_gretap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkIp6Tnl * +nm_platform_link_get_lnk_ip6tnl(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkIp6Tnl * +nm_platform_link_get_lnk_ip6gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkIp6Tnl * +nm_platform_link_get_lnk_ip6gretap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkIpIp * +nm_platform_link_get_lnk_ipip(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkInfiniband * +nm_platform_link_get_lnk_infiniband(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkIpIp * +nm_platform_link_get_lnk_ipip(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkMacsec * +nm_platform_link_get_lnk_macsec(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkMacvlan * +nm_platform_link_get_lnk_macvlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkMacvlan * +nm_platform_link_get_lnk_macvtap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkSit * +nm_platform_link_get_lnk_sit(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkTun * +nm_platform_link_get_lnk_tun(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkVlan * +nm_platform_link_get_lnk_vlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkVrf * +nm_platform_link_get_lnk_vrf(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkVxlan * +nm_platform_link_get_lnk_vxlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkWireGuard * +nm_platform_link_get_lnk_wireguard(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); + +gboolean nm_platform_link_vlan_set_ingress_map(NMPlatform *self, int ifindex, int from, int to); +gboolean nm_platform_link_vlan_set_egress_map(NMPlatform *self, int ifindex, int from, int to); +gboolean nm_platform_link_vlan_change(NMPlatform * self, + int ifindex, + _NMVlanFlags flags_mask, + _NMVlanFlags flags_set, + gboolean ingress_reset_all, + const NMVlanQosMapping *ingress_map, + gsize n_ingress_map, + gboolean egress_reset_all, + const NMVlanQosMapping *egress_map, + gsize n_egress_map); + +int nm_platform_link_infiniband_add(NMPlatform * self, + int parent, + int p_key, + const NMPlatformLink **out_link); +int nm_platform_link_infiniband_delete(NMPlatform *self, int parent, int p_key); +gboolean nm_platform_link_infiniband_get_properties(NMPlatform * self, + int ifindex, + int * parent, + int * p_key, + const char **mode); + +gboolean nm_platform_link_veth_get_properties(NMPlatform *self, int ifindex, int *out_peer_ifindex); +gboolean nm_platform_link_tun_get_properties(NMPlatform * self, + int ifindex, + NMPlatformLnkTun *out_properties); + +gboolean +nm_platform_wifi_get_capabilities(NMPlatform *self, int ifindex, _NMDeviceWifiCapabilities *caps); +guint32 nm_platform_wifi_get_frequency(NMPlatform *self, int ifindex); +gboolean nm_platform_wifi_get_station(NMPlatform * self, + int ifindex, + NMEtherAddr *out_bssid, + int * out_quality, + guint32 * out_rate); +_NM80211Mode nm_platform_wifi_get_mode(NMPlatform *self, int ifindex); +void nm_platform_wifi_set_mode(NMPlatform *self, int ifindex, _NM80211Mode mode); +void nm_platform_wifi_set_powersave(NMPlatform *self, int ifindex, guint32 powersave); +guint32 nm_platform_wifi_find_frequency(NMPlatform *self, int ifindex, const guint32 *freqs); +void nm_platform_wifi_indicate_addressing_running(NMPlatform *self, int ifindex, gboolean running); +_NMSettingWirelessWakeOnWLan nm_platform_wifi_get_wake_on_wlan(NMPlatform *self, int ifindex); +gboolean +nm_platform_wifi_set_wake_on_wlan(NMPlatform *self, int ifindex, _NMSettingWirelessWakeOnWLan wowl); + +guint32 nm_platform_mesh_get_channel(NMPlatform *self, int ifindex); +gboolean nm_platform_mesh_set_channel(NMPlatform *self, int ifindex, guint32 channel); +gboolean nm_platform_mesh_set_ssid(NMPlatform *self, int ifindex, const guint8 *ssid, gsize len); + +guint16 nm_platform_wpan_get_pan_id(NMPlatform *self, int ifindex); +gboolean nm_platform_wpan_set_pan_id(NMPlatform *self, int ifindex, guint16 pan_id); +guint16 nm_platform_wpan_get_short_addr(NMPlatform *self, int ifindex); +gboolean nm_platform_wpan_set_short_addr(NMPlatform *self, int ifindex, guint16 short_addr); +gboolean nm_platform_wpan_set_channel(NMPlatform *self, int ifindex, guint8 page, guint8 channel); + +void nm_platform_ip4_address_set_addr(NMPlatformIP4Address *addr, in_addr_t address, guint8 plen); +const struct in6_addr *nm_platform_ip6_address_get_peer(const NMPlatformIP6Address *addr); + +const NMPlatformIP4Address *nm_platform_ip4_address_get(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address); + +int nm_platform_link_sit_add(NMPlatform * self, + const char * name, + const NMPlatformLnkSit *props, + const NMPlatformLink ** out_link); +int nm_platform_link_tun_add(NMPlatform * self, + const char * name, + const NMPlatformLnkTun *props, + const NMPlatformLink ** out_link, + int * out_fd); +gboolean nm_platform_link_6lowpan_get_properties(NMPlatform *self, int ifindex, int *out_parent); + +int +nm_platform_link_wireguard_add(NMPlatform *self, const char *name, const NMPlatformLink **out_link); + +int nm_platform_link_wireguard_change(NMPlatform * self, + int ifindex, + const NMPlatformLnkWireGuard * lnk_wireguard, + const struct _NMPWireGuardPeer * peers, + const NMPlatformWireGuardChangePeerFlags *peer_flags, + guint peers_len, + NMPlatformWireGuardChangeFlags change_flags); + +const NMPlatformIP6Address * +nm_platform_ip6_address_get(NMPlatform *self, int ifindex, const struct in6_addr *address); + +gboolean nm_platform_object_delete(NMPlatform *self, const NMPObject *route); + +gboolean nm_platform_ip4_address_add(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address, + in_addr_t broadcast_address, + guint32 lifetime, + guint32 preferred_lft, + guint32 flags, + const char *label); +gboolean nm_platform_ip6_address_add(NMPlatform * self, + int ifindex, + struct in6_addr address, + guint8 plen, + struct in6_addr peer_address, + guint32 lifetime, + guint32 preferred_lft, + guint32 flags); +gboolean nm_platform_ip4_address_delete(NMPlatform *self, + int ifindex, + in_addr_t address, + guint8 plen, + in_addr_t peer_address); +gboolean +nm_platform_ip6_address_delete(NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen); + +gboolean nm_platform_ip_address_sync(NMPlatform *self, + int addr_family, + int ifindex, + GPtrArray * known_addresses, + GPtrArray * addresses_prune); + +GPtrArray *nm_platform_ip_address_get_prune_list(NMPlatform *self, + int addr_family, + int ifindex, + gboolean exclude_ipv6_temporary_addrs); + +static inline gboolean +_nm_platform_ip_address_sync(NMPlatform *self, + int addr_family, + int ifindex, + GPtrArray * known_addresses, + gboolean full_sync) +{ + gs_unref_ptrarray GPtrArray *addresses_prune = NULL; + + addresses_prune = nm_platform_ip_address_get_prune_list(self, addr_family, ifindex, !full_sync); + return nm_platform_ip_address_sync(self, + addr_family, + ifindex, + known_addresses, + addresses_prune); +} + +static inline gboolean +nm_platform_ip4_address_sync(NMPlatform *self, int ifindex, GPtrArray *known_addresses) +{ + return _nm_platform_ip_address_sync(self, AF_INET, ifindex, known_addresses, TRUE); +} + +static inline gboolean +nm_platform_ip6_address_sync(NMPlatform *self, + int ifindex, + GPtrArray * known_addresses, + gboolean full_sync) +{ + return _nm_platform_ip_address_sync(self, AF_INET6, ifindex, known_addresses, full_sync); +} + +gboolean nm_platform_ip_address_flush(NMPlatform *self, int addr_family, int ifindex); + +static inline gconstpointer +nm_platform_ip_address_get_peer_address(int addr_family, const NMPlatformIPAddress *addr) +{ + nm_assert_addr_family(addr_family); + nm_assert(addr); + + if (NM_IS_IPv4(addr_family)) + return &((NMPlatformIP4Address *) addr)->peer_address; + return &((NMPlatformIP6Address *) addr)->peer_address; +} + +void nm_platform_ip_route_normalize(int addr_family, NMPlatformIPRoute *route); + +static inline guint32 +nm_platform_ip4_route_get_effective_metric(const NMPlatformIP4Route *r) +{ + nm_assert(r); + + return r->metric_any ? nm_add_clamped_u32(NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4, r->metric) + : r->metric; +} + +static inline guint32 +nm_platform_ip6_route_get_effective_metric(const NMPlatformIP6Route *r) +{ + nm_assert(r); + + return r->metric_any ? nm_add_clamped_u32(NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6, r->metric) + : r->metric; +} + +static inline guint32 +nm_platform_ip_route_get_effective_table(const NMPlatformIPRoute *r) +{ + nm_assert(r); + nm_assert(!r->table_any || r->table_coerced == 0); + + return r->table_any ? 254u /* RT_TABLE_MAIN */ + : nm_platform_route_table_uncoerce(r->table_coerced, TRUE); +} + +static inline gconstpointer +nm_platform_ip_route_get_gateway(int addr_family, const NMPlatformIPRoute *route) +{ + nm_assert_addr_family(addr_family); + nm_assert(route); + + if (NM_IS_IPv4(addr_family)) + return &((NMPlatformIP4Route *) route)->gateway; + return &((NMPlatformIP6Route *) route)->gateway; +} + +int nm_platform_ip_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPObject *route); +int nm_platform_ip4_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP4Route *route); +int nm_platform_ip6_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP6Route *route); + +GPtrArray *nm_platform_ip_route_get_prune_list(NMPlatform * self, + int addr_family, + int ifindex, + NMIPRouteTableSyncMode route_table_sync); + +gboolean nm_platform_ip_route_sync(NMPlatform *self, + int addr_family, + int ifindex, + GPtrArray * routes, + GPtrArray * routes_prune, + GPtrArray **out_temporary_not_available); + +gboolean nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex); + +int nm_platform_ip_route_get(NMPlatform * self, + int addr_family, + gconstpointer address, + int oif_ifindex, + NMPObject ** out_route); + +int nm_platform_routing_rule_add(NMPlatform * self, + NMPNlmFlags flags, + const NMPlatformRoutingRule *routing_rule); + +int nm_platform_qdisc_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformQdisc *qdisc); +gboolean nm_platform_qdisc_sync(NMPlatform *self, int ifindex, GPtrArray *known_qdiscs); + +int nm_platform_tfilter_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformTfilter *tfilter); +gboolean nm_platform_tfilter_sync(NMPlatform *self, int ifindex, GPtrArray *known_tfilters); + +const char *nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len); +const char *nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsize len); +const char *nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len); +const char * +nm_platform_lnk_infiniband_to_string(const NMPlatformLnkInfiniband *lnk, char *buf, gsize len); +const char *nm_platform_lnk_ip6tnl_to_string(const NMPlatformLnkIp6Tnl *lnk, char *buf, gsize len); +const char *nm_platform_lnk_ipip_to_string(const NMPlatformLnkIpIp *lnk, char *buf, gsize len); +const char *nm_platform_lnk_macsec_to_string(const NMPlatformLnkMacsec *lnk, char *buf, gsize len); +const char * +nm_platform_lnk_macvlan_to_string(const NMPlatformLnkMacvlan *lnk, char *buf, gsize len); +const char *nm_platform_lnk_sit_to_string(const NMPlatformLnkSit *lnk, char *buf, gsize len); +const char *nm_platform_lnk_tun_to_string(const NMPlatformLnkTun *lnk, char *buf, gsize len); +const char *nm_platform_lnk_vlan_to_string(const NMPlatformLnkVlan *lnk, char *buf, gsize len); +const char *nm_platform_lnk_vrf_to_string(const NMPlatformLnkVrf *lnk, char *buf, gsize len); +const char *nm_platform_lnk_vxlan_to_string(const NMPlatformLnkVxlan *lnk, char *buf, gsize len); +const char * +nm_platform_lnk_wireguard_to_string(const NMPlatformLnkWireGuard *lnk, char *buf, gsize len); +const char * +nm_platform_ip4_address_to_string(const NMPlatformIP4Address *address, char *buf, gsize len); +const char * +nm_platform_ip6_address_to_string(const NMPlatformIP6Address *address, char *buf, gsize len); +const char *nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsize len); +const char *nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsize len); +const char * +nm_platform_routing_rule_to_string(const NMPlatformRoutingRule *routing_rule, char *buf, gsize len); +const char *nm_platform_qdisc_to_string(const NMPlatformQdisc *qdisc, char *buf, gsize len); +const char *nm_platform_tfilter_to_string(const NMPlatformTfilter *tfilter, char *buf, gsize len); +const char *nm_platform_vf_to_string(const NMPlatformVF *vf, char *buf, gsize len); +const char * +nm_platform_bridge_vlan_to_string(const NMPlatformBridgeVlan *vlan, char *buf, gsize len); + +const char *nm_platform_vlan_qos_mapping_to_string(const char * name, + const NMVlanQosMapping *map, + gsize n_map, + char * buf, + gsize len); + +const char * +nm_platform_wireguard_peer_to_string(const struct _NMPWireGuardPeer *peer, char *buf, gsize len); + +int nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b); +int nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b); +int nm_platform_lnk_gre_cmp(const NMPlatformLnkGre *a, const NMPlatformLnkGre *b); +int nm_platform_lnk_infiniband_cmp(const NMPlatformLnkInfiniband *a, + const NMPlatformLnkInfiniband *b); +int nm_platform_lnk_ip6tnl_cmp(const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6Tnl *b); +int nm_platform_lnk_ipip_cmp(const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b); +int nm_platform_lnk_macsec_cmp(const NMPlatformLnkMacsec *a, const NMPlatformLnkMacsec *b); +int nm_platform_lnk_macvlan_cmp(const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b); +int nm_platform_lnk_sit_cmp(const NMPlatformLnkSit *a, const NMPlatformLnkSit *b); +int nm_platform_lnk_tun_cmp(const NMPlatformLnkTun *a, const NMPlatformLnkTun *b); +int nm_platform_lnk_vlan_cmp(const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b); +int nm_platform_lnk_vrf_cmp(const NMPlatformLnkVrf *a, const NMPlatformLnkVrf *b); +int nm_platform_lnk_vxlan_cmp(const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b); +int nm_platform_lnk_wireguard_cmp(const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b); +int nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a, const NMPlatformIP4Address *b); +int nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a, const NMPlatformIP6Address *b); + +int nm_platform_ip4_address_pretty_sort_cmp(const NMPlatformIP4Address *a1, + const NMPlatformIP4Address *a2); + +int nm_platform_ip6_address_pretty_sort_cmp(const NMPlatformIP6Address *a1, + const NMPlatformIP6Address *a2, + gboolean prefer_temp); + +GHashTable *nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex); + +int nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a, + const NMPlatformIP4Route *b, + NMPlatformIPRouteCmpType cmp_type); +int nm_platform_ip6_route_cmp(const NMPlatformIP6Route *a, + const NMPlatformIP6Route *b, + NMPlatformIPRouteCmpType cmp_type); + +static inline int +nm_platform_ip4_route_cmp_full(const NMPlatformIP4Route *a, const NMPlatformIP4Route *b) +{ + return nm_platform_ip4_route_cmp(a, b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL); +} + +static inline int +nm_platform_ip6_route_cmp_full(const NMPlatformIP6Route *a, const NMPlatformIP6Route *b) +{ + return nm_platform_ip6_route_cmp(a, b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL); +} + +int nm_platform_routing_rule_cmp(const NMPlatformRoutingRule *a, + const NMPlatformRoutingRule *b, + NMPlatformRoutingRuleCmpType cmp_type); + +static inline int +nm_platform_routing_rule_cmp_full(const NMPlatformRoutingRule *a, const NMPlatformRoutingRule *b) +{ + return nm_platform_routing_rule_cmp(a, b, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL); +} + +int nm_platform_qdisc_cmp(const NMPlatformQdisc *a, const NMPlatformQdisc *b); +int nm_platform_qdisc_cmp_full(const NMPlatformQdisc *a, + const NMPlatformQdisc *b, + gboolean compare_handle); +int nm_platform_tfilter_cmp(const NMPlatformTfilter *a, const NMPlatformTfilter *b); + +void nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h); +void nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHashState *h); +void nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h); +void nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, + NMPlatformIPRouteCmpType cmp_type, + NMHashState * h); +void nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj, + NMPlatformIPRouteCmpType cmp_type, + NMHashState * h); +void nm_platform_routing_rule_hash_update(const NMPlatformRoutingRule *obj, + NMPlatformRoutingRuleCmpType cmp_type, + NMHashState * h); +void nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState *h); +void nm_platform_lnk_gre_hash_update(const NMPlatformLnkGre *obj, NMHashState *h); +void nm_platform_lnk_infiniband_hash_update(const NMPlatformLnkInfiniband *obj, NMHashState *h); +void nm_platform_lnk_ip6tnl_hash_update(const NMPlatformLnkIp6Tnl *obj, NMHashState *h); +void nm_platform_lnk_ipip_hash_update(const NMPlatformLnkIpIp *obj, NMHashState *h); +void nm_platform_lnk_macsec_hash_update(const NMPlatformLnkMacsec *obj, NMHashState *h); +void nm_platform_lnk_macvlan_hash_update(const NMPlatformLnkMacvlan *obj, NMHashState *h); +void nm_platform_lnk_sit_hash_update(const NMPlatformLnkSit *obj, NMHashState *h); +void nm_platform_lnk_tun_hash_update(const NMPlatformLnkTun *obj, NMHashState *h); +void nm_platform_lnk_vlan_hash_update(const NMPlatformLnkVlan *obj, NMHashState *h); +void nm_platform_lnk_vrf_hash_update(const NMPlatformLnkVrf *obj, NMHashState *h); +void nm_platform_lnk_vxlan_hash_update(const NMPlatformLnkVxlan *obj, NMHashState *h); +void nm_platform_lnk_wireguard_hash_update(const NMPlatformLnkWireGuard *obj, NMHashState *h); + +void nm_platform_qdisc_hash_update(const NMPlatformQdisc *obj, NMHashState *h); +void nm_platform_tfilter_hash_update(const NMPlatformTfilter *obj, NMHashState *h); + +#define NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN ((gsize) 162) + +const char *nm_platform_link_flags2str(unsigned flags, char *buf, gsize len); +const char *nm_platform_link_inet6_addrgenmode2str(guint8 mode, char *buf, gsize len); +const char *nm_platform_addr_flags2str(unsigned flags, char *buf, gsize len); +const char *nm_platform_route_scope2str(int scope, char *buf, gsize len); + +int nm_platform_ip_address_cmp_expiry(const NMPlatformIPAddress *a, const NMPlatformIPAddress *b); + +gboolean nm_platform_ethtool_set_wake_on_lan(NMPlatform * self, + int ifindex, + _NMSettingWiredWakeOnLan wol, + const char * wol_password); +gboolean nm_platform_ethtool_set_link_settings(NMPlatform * self, + int ifindex, + gboolean autoneg, + guint32 speed, + NMPlatformLinkDuplexType duplex); +gboolean nm_platform_ethtool_get_link_settings(NMPlatform * self, + int ifindex, + gboolean * out_autoneg, + guint32 * out_speed, + NMPlatformLinkDuplexType *out_duplex); + +NMEthtoolFeatureStates *nm_platform_ethtool_get_link_features(NMPlatform *self, int ifindex); +gboolean nm_platform_ethtool_set_features( + NMPlatform * self, + int ifindex, + const NMEthtoolFeatureStates *features, + const NMOptionBool *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, + gboolean do_set /* or reset */); + +gboolean nm_platform_ethtool_get_link_coalesce(NMPlatform * self, + int ifindex, + NMEthtoolCoalesceState *coalesce); + +gboolean nm_platform_ethtool_set_coalesce(NMPlatform * self, + int ifindex, + const NMEthtoolCoalesceState *coalesce); + +gboolean nm_platform_ethtool_get_link_ring(NMPlatform *self, int ifindex, NMEthtoolRingState *ring); + +gboolean +nm_platform_ethtool_set_ring(NMPlatform *self, int ifindex, const NMEthtoolRingState *ring); + +void nm_platform_ip4_dev_route_blacklist_set(NMPlatform *self, + int ifindex, + GPtrArray * ip4_dev_route_blacklist); + +struct _NMDedupMultiIndex *nm_platform_get_multi_idx(NMPlatform *self); + +/*****************************************************************************/ + +gboolean nm_platform_ip6_address_match(const NMPlatformIP6Address *addr, + NMPlatformMatchFlags match_flag); + +#endif /* __NETWORKMANAGER_PLATFORM_H__ */ diff --git a/src/libnm-platform/nmp-base.h b/src/libnm-platform/nmp-base.h new file mode 100644 index 0000000..f7dc637 --- /dev/null +++ b/src/libnm-platform/nmp-base.h @@ -0,0 +1,183 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __NMP_FWD_H__ +#define __NMP_FWD_H__ + +#include "libnm-base/nm-base.h" + +/*****************************************************************************/ + +#define NM_PLATFORM_LIFETIME_PERMANENT G_MAXUINT32 + +/*****************************************************************************/ + +typedef enum { + NM_PLATFORM_LINK_DUPLEX_UNKNOWN, + NM_PLATFORM_LINK_DUPLEX_HALF, + NM_PLATFORM_LINK_DUPLEX_FULL, +} NMPlatformLinkDuplexType; + +/*****************************************************************************/ + +typedef struct { + /* We don't want to include in header files, + * thus create a ABI compatible version of struct ethtool_drvinfo.*/ + guint32 _private_cmd; + char driver[32]; + char version[32]; + char fw_version[32]; + char _private_bus_info[32]; + char _private_erom_version[32]; + char _private_reserved2[12]; + guint32 _private_n_priv_flags; + guint32 _private_n_stats; + guint32 _private_testinfo_len; + guint32 _private_eedump_len; + guint32 _private_regdump_len; +} NMPUtilsEthtoolDriverInfo; + +typedef struct { + NMEthtoolID ethtool_id; + + guint8 n_kernel_names; + + /* one NMEthtoolID refers to one or more kernel_names. The reason for supporting this complexity + * (where one NMSettingEthtool option refers to multiple kernel features) is to follow what + * ethtool does, where "tx" is an alias for multiple features. */ + const char *const *kernel_names; +} NMEthtoolFeatureInfo; + +typedef struct { + const NMEthtoolFeatureInfo *info; + + guint idx_ss_features; + + /* one NMEthtoolFeatureInfo references one or more kernel_names. This is the index + * of the matching info->kernel_names */ + guint8 idx_kernel_name; + + bool available : 1; + bool requested : 1; + bool active : 1; + bool never_changed : 1; +} NMEthtoolFeatureState; + +typedef struct { + guint n_states; + + guint n_ss_features; + + /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */ + const NMEthtoolFeatureState *const *states_indexed[_NM_ETHTOOL_ID_FEATURE_NUM]; + + /* the same content, here as a list of n_states entries. */ + const NMEthtoolFeatureState states_list[]; +} NMEthtoolFeatureStates; + +/*****************************************************************************/ + +typedef struct { + guint32 + s[_NM_ETHTOOL_ID_COALESCE_NUM /* indexed by (NMEthtoolID - _NM_ETHTOOL_ID_COALESCE_FIRST) */ + ]; +} NMEthtoolCoalesceState; + +/*****************************************************************************/ + +typedef struct { + guint32 rx_pending; + guint32 rx_mini_pending; + guint32 rx_jumbo_pending; + guint32 tx_pending; +} NMEthtoolRingState; + +/*****************************************************************************/ + +typedef struct _NMPNetns NMPNetns; +typedef struct _NMPlatform NMPlatform; +typedef struct _NMPlatformObject NMPlatformObject; +typedef struct _NMPlatformObjWithIfindex NMPlatformObjWithIfindex; +typedef struct _NMPlatformIP4Address NMPlatformIP4Address; +typedef struct _NMPlatformIP4Route NMPlatformIP4Route; +typedef struct _NMPlatformIP6Address NMPlatformIP6Address; +typedef struct _NMPlatformIP6Route NMPlatformIP6Route; +typedef struct _NMPlatformLink NMPlatformLink; +typedef struct _NMPObject NMPObject; + +typedef enum { + NMP_OBJECT_TYPE_UNKNOWN, + NMP_OBJECT_TYPE_LINK, + +#define NMP_OBJECT_TYPE_IP_ADDRESS(is_ipv4) \ + ((is_ipv4) ? NMP_OBJECT_TYPE_IP4_ADDRESS : NMP_OBJECT_TYPE_IP6_ADDRESS) + NMP_OBJECT_TYPE_IP4_ADDRESS, + NMP_OBJECT_TYPE_IP6_ADDRESS, + +#define NMP_OBJECT_TYPE_IP_ROUTE(is_ipv4) \ + ((is_ipv4) ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE) + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE, + + NMP_OBJECT_TYPE_ROUTING_RULE, + + NMP_OBJECT_TYPE_QDISC, + + NMP_OBJECT_TYPE_TFILTER, + + NMP_OBJECT_TYPE_LNK_BRIDGE, + NMP_OBJECT_TYPE_LNK_GRE, + NMP_OBJECT_TYPE_LNK_GRETAP, + NMP_OBJECT_TYPE_LNK_INFINIBAND, + NMP_OBJECT_TYPE_LNK_IP6TNL, + NMP_OBJECT_TYPE_LNK_IP6GRE, + NMP_OBJECT_TYPE_LNK_IP6GRETAP, + NMP_OBJECT_TYPE_LNK_IPIP, + NMP_OBJECT_TYPE_LNK_MACSEC, + NMP_OBJECT_TYPE_LNK_MACVLAN, + NMP_OBJECT_TYPE_LNK_MACVTAP, + NMP_OBJECT_TYPE_LNK_SIT, + NMP_OBJECT_TYPE_LNK_TUN, + NMP_OBJECT_TYPE_LNK_VLAN, + NMP_OBJECT_TYPE_LNK_VRF, + NMP_OBJECT_TYPE_LNK_VXLAN, + NMP_OBJECT_TYPE_LNK_WIREGUARD, + + __NMP_OBJECT_TYPE_LAST, + NMP_OBJECT_TYPE_MAX = __NMP_OBJECT_TYPE_LAST - 1, +} NMPObjectType; + +static inline guint32 +nmp_object_type_to_flags(NMPObjectType obj_type) +{ + G_STATIC_ASSERT_EXPR(NMP_OBJECT_TYPE_MAX < 32); + + nm_assert(_NM_INT_NOT_NEGATIVE(obj_type)); + nm_assert(obj_type < NMP_OBJECT_TYPE_MAX); + + return ((guint32) 1u) << obj_type; +} + +/*****************************************************************************/ + +/** + * NMIPRouteTableSyncMode: + * @NM_IP_ROUTE_TABLE_SYNC_MODE_NONE: indicate an invalid setting. + * @NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN: only the main table is synced. For all + * other tables, NM won't delete any extra routes. + * @NM_IP_ROUTE_TABLE_SYNC_MODE_FULL: NM will sync all tables, except the + * local table (255). + * @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL: NM will sync all tables, including the + * local table (255). + * @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE: NM will sync all tables (including + * the local table). It will thereby remove all addresses, that is during + * deactivation. + */ +typedef enum { + NM_IP_ROUTE_TABLE_SYNC_MODE_NONE, + NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN, + NM_IP_ROUTE_TABLE_SYNC_MODE_FULL, + NM_IP_ROUTE_TABLE_SYNC_MODE_ALL, + NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE, +} NMIPRouteTableSyncMode; + +#endif /* __NMP_FWD_H__ */ diff --git a/src/libnm-platform/nmp-netns.c b/src/libnm-platform/nmp-netns.c new file mode 100644 index 0000000..aea5b3b --- /dev/null +++ b/src/libnm-platform/nmp-netns.c @@ -0,0 +1,767 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nmp-netns.h" + +#include +#include +#include +#include +#include + +#include "libnm-log-core/nm-logging.h" + +/*****************************************************************************/ + +/* NOTE: NMPNetns and all code used here must be thread-safe! */ + +/* we may not call logging functions from the main-thread alone. Hence, we + * require locking from nm-logging. Indicate that by setting NM_THREAD_SAFE_ON_MAIN_THREAD + * to zero. */ +#undef NM_THREAD_SAFE_ON_MAIN_THREAD +#define NM_THREAD_SAFE_ON_MAIN_THREAD 0 + +/*****************************************************************************/ + +#define PROC_SELF_NS_MNT "/proc/self/ns/mnt" +#define PROC_SELF_NS_NET "/proc/self/ns/net" + +#define _CLONE_NS_ALL ((int) (CLONE_NEWNS | CLONE_NEWNET)) +#define _CLONE_NS_ALL_V CLONE_NEWNS, CLONE_NEWNET + +static NM_UTILS_FLAGS2STR_DEFINE(_clone_ns_to_str, + int, + NM_UTILS_FLAGS2STR(CLONE_NEWNS, "mnt"), + NM_UTILS_FLAGS2STR(CLONE_NEWNET, "net"), ); + +static const char * +__ns_types_to_str(int ns_types, int ns_types_already_set, char *buf, gsize len) +{ + const char *b = buf; + char bb[200]; + + nm_utils_strbuf_append_c(&buf, &len, '['); + if (ns_types & ~ns_types_already_set) { + nm_utils_strbuf_append_str( + &buf, + &len, + _clone_ns_to_str(ns_types & ~ns_types_already_set, bb, sizeof(bb))); + } + if (ns_types & ns_types_already_set) { + if (ns_types & ~ns_types_already_set) + nm_utils_strbuf_append_c(&buf, &len, '/'); + nm_utils_strbuf_append_str( + &buf, + &len, + _clone_ns_to_str(ns_types & ns_types_already_set, bb, sizeof(bb))); + } + nm_utils_strbuf_append_c(&buf, &len, ']'); + return b; +} +#define _ns_types_to_str(ns_types, ns_types_already_set, buf) \ + __ns_types_to_str(ns_types, ns_types_already_set, buf, sizeof(buf)) + +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_PLATFORM +#define _NMLOG_PREFIX_NAME "netns" +#define _NMLOG(level, netns, ...) \ + G_STMT_START \ + { \ + NMLogLevel _level = (level); \ + \ + if (nm_logging_enabled(_level, _NMLOG_DOMAIN)) { \ + NMPNetns *_netns = (netns); \ + char _sbuf[20]; \ + \ + _nm_log(_level, \ + _NMLOG_DOMAIN, \ + 0, \ + NULL, \ + NULL, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + (_netns ? nm_sprintf_buf(_sbuf, "[%p]", _netns) \ + : "") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_FD_NET, PROP_FD_MNT, ); + +typedef struct { + int fd_net; + int fd_mnt; +} NMPNetnsPrivate; + +struct _NMPNetns { + GObject parent; + NMPNetnsPrivate _priv; +}; + +struct _NMPNetnsClass { + GObjectClass parent; +}; + +G_DEFINE_TYPE(NMPNetns, nmp_netns, G_TYPE_OBJECT); + +#define NMP_NETNS_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMPNetns, NMP_IS_NETNS) + +/*****************************************************************************/ + +typedef struct { + NMPNetns *netns; + int count; + int ns_types; +} NetnsInfo; + +static void _stack_push(GArray *netns_stack, NMPNetns *netns, int ns_types); +static NMPNetns *_netns_new(GError **error); + +/*****************************************************************************/ + +static NMPNetns * +_netns_get(NetnsInfo *info) +{ + nm_assert(!info || NMP_IS_NETNS(info->netns)); + return info ? info->netns : NULL; +} + +/*****************************************************************************/ + +static _nm_thread_local GArray *_netns_stack = NULL; + +static void +_netns_stack_clear_cb(gpointer data) +{ + NetnsInfo *info = data; + + nm_assert(NMP_IS_NETNS(info->netns)); + g_object_unref(info->netns); +} + +static GArray * +_netns_stack_get_impl(void) +{ + gs_unref_object NMPNetns *netns = NULL; + gs_free_error GError *error = NULL; + pthread_key_t key; + GArray * s; + + s = g_array_new(FALSE, FALSE, sizeof(NetnsInfo)); + g_array_set_clear_func(s, _netns_stack_clear_cb); + _netns_stack = s; + + /* register a destructor function to cleanup the array. If we fail + * to do so, we will leak NMPNetns instances (and their file descriptor) when the + * thread exits. */ + if (pthread_key_create(&key, (void (*)(void *)) g_array_unref) != 0) + _LOGE(NULL, "failure to initialize thread-local storage"); + else if (pthread_setspecific(key, s) != 0) + _LOGE(NULL, "failure to set thread-local storage"); + + /* at the bottom of the stack we must try to create a netns instance + * that we never pop. It's the base to which we need to return. */ + netns = _netns_new(&error); + + if (!netns) { + _LOGD(NULL, "failed to create initial netns: %s", error->message); + return s; + } + + /* we leak this instance inside the stack. */ + _stack_push(s, netns, _CLONE_NS_ALL); + + return s; +} + +#define _netns_stack_get() \ + ({ \ + GArray *_s = _netns_stack; \ + \ + if (G_UNLIKELY(!_s)) \ + _s = _netns_stack_get_impl(); \ + _s; \ + }) + +/*****************************************************************************/ + +static NMPNetns * +_stack_current_netns(GArray *netns_stack, int ns_types) +{ + guint j; + + nm_assert(netns_stack && netns_stack->len > 0); + + /* we search the stack top-down to find the netns that has + * all @ns_types set. */ + for (j = netns_stack->len; ns_types && j >= 1;) { + NetnsInfo *info; + + info = &g_array_index(netns_stack, NetnsInfo, --j); + + if (NM_FLAGS_ALL(info->ns_types, ns_types)) + return info->netns; + } + + g_return_val_if_reached(NULL); +} + +static int +_stack_current_ns_types(GArray *netns_stack, NMPNetns *netns, int ns_types) +{ + const int ns_types_check[] = {_CLONE_NS_ALL_V}; + guint i, j; + int res = 0; + + nm_assert(netns); + nm_assert(netns_stack && netns_stack->len > 0); + + /* we search the stack top-down to check which of @ns_types + * are already set to @netns. */ + for (j = netns_stack->len; ns_types && j >= 1;) { + NetnsInfo *info; + + info = &g_array_index(netns_stack, NetnsInfo, --j); + if (info->netns != netns) { + ns_types = NM_FLAGS_UNSET(ns_types, info->ns_types); + continue; + } + + for (i = 0; i < G_N_ELEMENTS(ns_types_check); i++) { + if (NM_FLAGS_ANY(ns_types, ns_types_check[i]) + && NM_FLAGS_ANY(info->ns_types, ns_types_check[i])) { + res = NM_FLAGS_SET(res, ns_types_check[i]); + ns_types = NM_FLAGS_UNSET(ns_types, ns_types_check[i]); + } + } + } + + return res; +} + +static NetnsInfo * +_stack_peek(GArray *netns_stack) +{ + if (netns_stack->len > 0) + return &g_array_index(netns_stack, NetnsInfo, (netns_stack->len - 1)); + return NULL; +} + +static NetnsInfo * +_stack_bottom(GArray *netns_stack) +{ + if (netns_stack->len > 0) + return &g_array_index(netns_stack, NetnsInfo, 0); + return NULL; +} + +static void +_stack_push(GArray *netns_stack, NMPNetns *netns, int ns_types) +{ + NetnsInfo *info; + + nm_assert(netns_stack); + nm_assert(NMP_IS_NETNS(netns)); + nm_assert(NM_FLAGS_ANY(ns_types, _CLONE_NS_ALL)); + nm_assert(!NM_FLAGS_ANY(ns_types, ~_CLONE_NS_ALL)); + + g_array_set_size(netns_stack, netns_stack->len + 1); + + info = &g_array_index(netns_stack, NetnsInfo, (netns_stack->len - 1)); + *info = (NetnsInfo){ + .netns = g_object_ref(netns), + .ns_types = ns_types, + .count = 1, + }; +} + +static void +_stack_pop(GArray *netns_stack) +{ + NetnsInfo *info; + + nm_assert(netns_stack); + nm_assert(netns_stack->len > 1); + + info = &g_array_index(netns_stack, NetnsInfo, (netns_stack->len - 1)); + + nm_assert(NMP_IS_NETNS(info->netns)); + nm_assert(info->count == 1); + + g_array_set_size(netns_stack, netns_stack->len - 1); +} + +static guint +_stack_size(GArray *netns_stack) +{ + nm_assert(netns_stack); + + return netns_stack->len; +} + +/*****************************************************************************/ + +static NMPNetns * +_netns_new(GError **error) +{ + NMPNetns *self; + int fd_net, fd_mnt; + int errsv; + + fd_net = open(PROC_SELF_NS_NET, O_RDONLY | O_CLOEXEC); + if (fd_net == -1) { + errsv = errno; + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "Failed opening netns: %s", + nm_strerror_native(errsv)); + errno = errsv; + return NULL; + } + + fd_mnt = open(PROC_SELF_NS_MNT, O_RDONLY | O_CLOEXEC); + if (fd_mnt == -1) { + errsv = errno; + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "Failed opening mntns: %s", + nm_strerror_native(errsv)); + nm_close(fd_net); + errno = errsv; + return NULL; + } + + self = g_object_new(NMP_TYPE_NETNS, NMP_NETNS_FD_NET, fd_net, NMP_NETNS_FD_MNT, fd_mnt, NULL); + + _LOGD(self, "new netns (net:%d, mnt:%d)", fd_net, fd_mnt); + + return self; +} + +static int +_setns(NMPNetns *self, int type) +{ + char buf[100]; + int fd; + NMPNetnsPrivate *priv = NMP_NETNS_GET_PRIVATE(self); + + nm_assert(NM_IN_SET(type, _CLONE_NS_ALL_V)); + + fd = (type == CLONE_NEWNET) ? priv->fd_net : priv->fd_mnt; + + _LOGt(self, "set netns(%s, %d)", _ns_types_to_str(type, 0, buf), fd); + + return setns(fd, type); +} + +static gboolean +_netns_switch_push(GArray *netns_stack, NMPNetns *self, int ns_types) +{ + int errsv; + + if (NM_FLAGS_HAS(ns_types, CLONE_NEWNET) + && !_stack_current_ns_types(netns_stack, self, CLONE_NEWNET) + && _setns(self, CLONE_NEWNET) != 0) { + errsv = errno; + _LOGE(self, "failed to switch netns: %s", nm_strerror_native(errsv)); + return FALSE; + } + if (NM_FLAGS_HAS(ns_types, CLONE_NEWNS) + && !_stack_current_ns_types(netns_stack, self, CLONE_NEWNS) + && _setns(self, CLONE_NEWNS) != 0) { + errsv = errno; + _LOGE(self, "failed to switch mntns: %s", nm_strerror_native(errsv)); + + /* try to fix the mess by returning to the previous netns. */ + if (NM_FLAGS_HAS(ns_types, CLONE_NEWNET) + && !_stack_current_ns_types(netns_stack, self, CLONE_NEWNET)) { + self = _stack_current_netns(netns_stack, CLONE_NEWNET); + if (self && _setns(self, CLONE_NEWNET) != 0) { + errsv = errno; + _LOGE(self, "failed to restore netns: %s", nm_strerror_native(errsv)); + } + } + return FALSE; + } + + return TRUE; +} + +static gboolean +_netns_switch_pop(GArray *netns_stack, NMPNetns *self, int ns_types) +{ + int errsv; + NMPNetns *current; + int success = TRUE; + + if (NM_FLAGS_HAS(ns_types, CLONE_NEWNET) + && (!self || !_stack_current_ns_types(netns_stack, self, CLONE_NEWNET))) { + current = _stack_current_netns(netns_stack, CLONE_NEWNET); + if (!current) { + g_warn_if_reached(); + success = FALSE; + } else if (_setns(current, CLONE_NEWNET) != 0) { + errsv = errno; + _LOGE(self, "failed to switch netns: %s", nm_strerror_native(errsv)); + success = FALSE; + } + } + if (NM_FLAGS_HAS(ns_types, CLONE_NEWNS) + && (!self || !_stack_current_ns_types(netns_stack, self, CLONE_NEWNS))) { + current = _stack_current_netns(netns_stack, CLONE_NEWNS); + if (!current) { + g_warn_if_reached(); + success = FALSE; + } else if (_setns(current, CLONE_NEWNS) != 0) { + errsv = errno; + _LOGE(self, "failed to switch mntns: %s", nm_strerror_native(errsv)); + success = FALSE; + } + } + + return success; +} + +/*****************************************************************************/ + +int +nmp_netns_get_fd_net(NMPNetns *self) +{ + g_return_val_if_fail(NMP_IS_NETNS(self), 0); + + return NMP_NETNS_GET_PRIVATE(self)->fd_net; +} + +int +nmp_netns_get_fd_mnt(NMPNetns *self) +{ + g_return_val_if_fail(NMP_IS_NETNS(self), 0); + + return NMP_NETNS_GET_PRIVATE(self)->fd_mnt; +} + +/*****************************************************************************/ + +static gboolean +_nmp_netns_push_type(NMPNetns *self, int ns_types) +{ + GArray * netns_stack = _netns_stack_get(); + NetnsInfo *info; + char sbuf[100]; + + info = _stack_peek(netns_stack); + g_return_val_if_fail(info, FALSE); + + if (info->netns == self && info->ns_types == ns_types) { + info->count++; + _LOGt(self, + "push#%u* %s (increase count to %d)", + _stack_size(netns_stack) - 1, + _ns_types_to_str(ns_types, ns_types, sbuf), + info->count); + return TRUE; + } + + _LOGD(self, + "push#%u %s", + _stack_size(netns_stack), + _ns_types_to_str(ns_types, _stack_current_ns_types(netns_stack, self, ns_types), sbuf)); + + if (!_netns_switch_push(netns_stack, self, ns_types)) + return FALSE; + + _stack_push(netns_stack, self, ns_types); + return TRUE; +} + +gboolean +nmp_netns_push(NMPNetns *self) +{ + g_return_val_if_fail(NMP_IS_NETNS(self), FALSE); + + return _nmp_netns_push_type(self, _CLONE_NS_ALL); +} + +gboolean +nmp_netns_push_type(NMPNetns *self, int ns_types) +{ + g_return_val_if_fail(NMP_IS_NETNS(self), FALSE); + g_return_val_if_fail(!NM_FLAGS_ANY(ns_types, ~_CLONE_NS_ALL), FALSE); + + return _nmp_netns_push_type(self, ns_types == 0 ? _CLONE_NS_ALL : ns_types); +} + +NMPNetns * +nmp_netns_new(void) +{ + GArray * netns_stack = _netns_stack_get(); + NMPNetns * self; + int errsv; + GError * error = NULL; + unsigned long mountflags = 0; + + if (!_stack_peek(netns_stack)) { + /* there are no netns instances. We cannot create a new one + * (because after unshare we couldn't return to the original one). */ + errno = ENOTSUP; + return NULL; + } + + if (unshare(_CLONE_NS_ALL) != 0) { + errsv = errno; + _LOGE(NULL, "failed to create new net and mnt namespace: %s", nm_strerror_native(errsv)); + return NULL; + } + + if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL) != 0) { + errsv = errno; + _LOGE(NULL, "failed mount --make-rslave: %s", nm_strerror_native(errsv)); + goto err_out; + } + + if (umount2("/sys", MNT_DETACH) != 0) { + errsv = errno; + _LOGE(NULL, "failed umount /sys: %s", nm_strerror_native(errsv)); + goto err_out; + } + + if (access("/sys", W_OK) == -1) + mountflags = MS_RDONLY; + + if (mount("sysfs", "/sys", "sysfs", mountflags, NULL) != 0) { + errsv = errno; + _LOGE(NULL, "failed mount /sys: %s", nm_strerror_native(errsv)); + goto err_out; + } + + self = _netns_new(&error); + if (!self) { + errsv = errno; + _LOGE(NULL, "failed to create netns after unshare: %s", error->message); + g_clear_error(&error); + goto err_out; + } + + _stack_push(netns_stack, self, _CLONE_NS_ALL); + + return self; +err_out: + _netns_switch_pop(netns_stack, NULL, _CLONE_NS_ALL); + errno = errsv; + return NULL; +} + +gboolean +nmp_netns_pop(NMPNetns *self) +{ + GArray * netns_stack = _netns_stack_get(); + NetnsInfo *info; + int ns_types; + + g_return_val_if_fail(NMP_IS_NETNS(self), FALSE); + + info = _stack_peek(netns_stack); + + g_return_val_if_fail(info, FALSE); + g_return_val_if_fail(info->netns == self, FALSE); + + if (info->count > 1) { + info->count--; + _LOGt(self, "pop#%u* (decrease count to %d)", _stack_size(netns_stack) - 1, info->count); + return TRUE; + } + g_return_val_if_fail(info->count == 1, FALSE); + + /* cannot pop the original netns. */ + g_return_val_if_fail(_stack_size(netns_stack) > 1, FALSE); + + _LOGD(self, "pop#%u", _stack_size(netns_stack) - 1); + + ns_types = info->ns_types; + + _stack_pop(netns_stack); + + return _netns_switch_pop(netns_stack, self, ns_types); +} + +NMPNetns * +nmp_netns_get_current(void) +{ + return _netns_get(_stack_peek(_netns_stack_get())); +} + +NMPNetns * +nmp_netns_get_initial(void) +{ + return _netns_get(_stack_bottom(_netns_stack_get())); +} + +gboolean +nmp_netns_is_initial(void) +{ + GArray *netns_stack = _netns_stack_get(); + + return (_netns_get(_stack_peek(netns_stack)) == _netns_get(_stack_bottom(netns_stack))); +} + +/*****************************************************************************/ + +gboolean +nmp_netns_bind_to_path(NMPNetns *self, const char *filename, int *out_fd) +{ + gs_free char * dirname = NULL; + int errsv; + int fd; + nm_auto_pop_netns NMPNetns *netns_pop = NULL; + + g_return_val_if_fail(NMP_IS_NETNS(self), FALSE); + g_return_val_if_fail(filename && filename[0] == '/', FALSE); + + if (!nmp_netns_push_type(self, CLONE_NEWNET)) + return FALSE; + netns_pop = self; + + dirname = g_path_get_dirname(filename); + if (mkdir(dirname, 0) != 0) { + errsv = errno; + if (errsv != EEXIST) { + _LOGE(self, + "bind: failed to create directory %s: %s", + dirname, + nm_strerror_native(errsv)); + return FALSE; + } + } + + if ((fd = creat(filename, S_IRUSR | S_IRGRP | S_IROTH)) == -1) { + errsv = errno; + _LOGE(self, "bind: failed to create %s: %s", filename, nm_strerror_native(errsv)); + return FALSE; + } + nm_close(fd); + + if (mount(PROC_SELF_NS_NET, filename, "none", MS_BIND, NULL) != 0) { + errsv = errno; + _LOGE(self, + "bind: failed to mount %s to %s: %s", + PROC_SELF_NS_NET, + filename, + nm_strerror_native(errsv)); + unlink(filename); + return FALSE; + } + + if (out_fd) { + if ((fd = open(filename, O_RDONLY | O_CLOEXEC)) == -1) { + errsv = errno; + _LOGE(self, "bind: failed to open %s: %s", filename, nm_strerror_native(errsv)); + umount2(filename, MNT_DETACH); + unlink(filename); + return FALSE; + } + *out_fd = fd; + } + + return TRUE; +} + +gboolean +nmp_netns_bind_to_path_destroy(NMPNetns *self, const char *filename) +{ + int errsv; + + g_return_val_if_fail(NMP_IS_NETNS(self), FALSE); + g_return_val_if_fail(filename && filename[0] == '/', FALSE); + + if (umount2(filename, MNT_DETACH) != 0) { + errsv = errno; + _LOGE(self, "bind: failed to unmount2 %s: %s", filename, nm_strerror_native(errsv)); + return FALSE; + } + if (unlink(filename) != 0) { + errsv = errno; + _LOGE(self, "bind: failed to unlink %s: %s", filename, nm_strerror_native(errsv)); + return FALSE; + } + return TRUE; +} + +/*****************************************************************************/ + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMPNetns * self = NMP_NETNS(object); + NMPNetnsPrivate *priv = NMP_NETNS_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_FD_NET: + /* construct-only */ + priv->fd_net = g_value_get_int(value); + g_return_if_fail(priv->fd_net > 0); + break; + case PROP_FD_MNT: + /* construct-only */ + priv->fd_mnt = g_value_get_int(value); + g_return_if_fail(priv->fd_mnt > 0); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +nmp_netns_init(NMPNetns *self) +{} + +static void +dispose(GObject *object) +{ + NMPNetns * self = NMP_NETNS(object); + NMPNetnsPrivate *priv = NMP_NETNS_GET_PRIVATE(self); + + nm_close(priv->fd_net); + priv->fd_net = -1; + + nm_close(priv->fd_mnt); + priv->fd_mnt = -1; + + G_OBJECT_CLASS(nmp_netns_parent_class)->dispose(object); +} + +static void +nmp_netns_class_init(NMPNetnsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->set_property = set_property; + object_class->dispose = dispose; + + obj_properties[PROP_FD_NET] = + g_param_spec_int(NMP_NETNS_FD_NET, + "", + "", + 0, + G_MAXINT, + 0, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_FD_MNT] = + g_param_spec_int(NMP_NETNS_FD_MNT, + "", + "", + 0, + G_MAXINT, + 0, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} diff --git a/src/libnm-platform/nmp-netns.h b/src/libnm-platform/nmp-netns.h new file mode 100644 index 0000000..b18bd03 --- /dev/null +++ b/src/libnm-platform/nmp-netns.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#ifndef __NMP_NETNS_UTILS_H__ +#define __NMP_NETNS_UTILS_H__ + +#include "nmp-base.h" + +/*****************************************************************************/ + +#define NMP_TYPE_NETNS (nmp_netns_get_type()) +#define NMP_NETNS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NMP_TYPE_NETNS, NMPNetns)) +#define NMP_NETNS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NMP_TYPE_NETNS, NMPNetnsClass)) +#define NMP_IS_NETNS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMP_TYPE_NETNS)) +#define NMP_IS_NETNS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NMP_TYPE_NETNS)) +#define NMP_NETNS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NMP_TYPE_NETNS, NMPNetnsClass)) + +#define NMP_NETNS_FD_NET "fd-net" +#define NMP_NETNS_FD_MNT "fd-mnt" + +typedef struct _NMPNetns NMPNetns; +typedef struct _NMPNetnsClass NMPNetnsClass; + +GType nmp_netns_get_type(void); + +NMPNetns *nmp_netns_new(void); + +gboolean nmp_netns_push(NMPNetns *self); +gboolean nmp_netns_push_type(NMPNetns *self, int ns_types); +gboolean nmp_netns_pop(NMPNetns *self); + +NMPNetns *nmp_netns_get_current(void); +NMPNetns *nmp_netns_get_initial(void); +gboolean nmp_netns_is_initial(void); + +int nmp_netns_get_fd_net(NMPNetns *self); +int nmp_netns_get_fd_mnt(NMPNetns *self); + +static inline void +_nm_auto_pop_netns(NMPNetns **p) +{ + if (*p) { + int errsv = errno; + + nmp_netns_pop(*p); + errno = errsv; + } +} +#define nm_auto_pop_netns nm_auto(_nm_auto_pop_netns) + +gboolean nmp_netns_bind_to_path(NMPNetns *self, const char *filename, int *out_fd); +gboolean nmp_netns_bind_to_path_destroy(NMPNetns *self, const char *filename); + +#endif /* __NMP_NETNS_UTILS_H__ */ diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c new file mode 100644 index 0000000..b27d8df --- /dev/null +++ b/src/libnm-platform/nmp-object.c @@ -0,0 +1,3453 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2015 - 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nmp-object.h" + +#include +#include +#include +#include + +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-platform/wifi/nm-wifi-utils.h" +#include "libnm-platform/wpan/nm-wpan-utils.h" + +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_PLATFORM +#define _NMLOG(level, obj, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + const NMPObject *const __obj = (obj); \ + \ + _nm_log(__level, \ + _NMLOG_DOMAIN, \ + 0, \ + NULL, \ + NULL, \ + "nmp-object[%p/%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __obj, \ + (__obj ? NMP_OBJECT_GET_CLASS(__obj)->obj_type_name \ + : "???") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END + +/*****************************************************************************/ + +typedef struct { + NMDedupMultiIdxType parent; + NMPCacheIdType cache_id_type; +} DedupMultiIdxType; + +struct _NMPCache { + /* the cache contains only one hash table for all object types, and similarly + * it contains only one NMMultiIndex. + * This works, because different object types don't ever compare equal and + * because their index ids also don't overlap. + * + * For routes and addresses, the cache contains an address if (and only if) the + * object was reported via netlink. + * For links, the cache contain a link if it was reported by either netlink + * or udev. That means, a link object can be alive, even if it was already + * removed via netlink. + * + * This effectively merges the udev-device cache into the NMPCache. + */ + + NMDedupMultiIndex *multi_idx; + + /* an idx_type entry for each NMP_CACHE_ID_TYPE. Note that NONE (zero) + * is skipped, so the index is shifted by one: idx_type[cache_id_type - 1]. + * + * Don't bother, use _idx_type_get() instead! */ + DedupMultiIdxType idx_types[NMP_CACHE_ID_TYPE_MAX]; + + gboolean use_udev; +}; + +/*****************************************************************************/ + +int +nm_sock_addr_union_cmp(const NMSockAddrUnion *a, const NMSockAddrUnion *b) +{ + nm_assert(!a || NM_IN_SET(a->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); + nm_assert(!b || NM_IN_SET(b->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); + + NM_CMP_SELF(a, b); + + NM_CMP_FIELD(a, b, sa.sa_family); + switch (a->sa.sa_family) { + case AF_INET: + NM_CMP_DIRECT(ntohl(a->in.sin_addr.s_addr), ntohl(b->in.sin_addr.s_addr)); + NM_CMP_DIRECT(htons(a->in.sin_port), htons(b->in.sin_port)); + break; + case AF_INET6: + NM_CMP_DIRECT_IN6ADDR(&a->in6.sin6_addr, &b->in6.sin6_addr); + NM_CMP_DIRECT(htons(a->in6.sin6_port), htons(b->in6.sin6_port)); + NM_CMP_FIELD(a, b, in6.sin6_scope_id); + NM_CMP_FIELD(a, b, in6.sin6_flowinfo); + break; + } + return 0; +} + +void +nm_sock_addr_union_hash_update(const NMSockAddrUnion *a, NMHashState *h) +{ + if (!a) { + nm_hash_update_val(h, 1241364739u); + return; + } + + nm_assert(NM_IN_SET(a->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); + + switch (a->sa.sa_family) { + case AF_INET: + nm_hash_update_vals(h, a->in.sin_family, a->in.sin_addr.s_addr, a->in.sin_port); + return; + case AF_INET6: + nm_hash_update_vals(h, + a->in6.sin6_family, + a->in6.sin6_addr, + a->in6.sin6_port, + a->in6.sin6_scope_id, + a->in6.sin6_flowinfo); + return; + default: + nm_hash_update_val(h, a->sa.sa_family); + return; + } +} + +/** + * nm_sock_addr_union_cpy: + * @dst: the destination #NMSockAddrUnion. It will always be fully initialized, + * to one of the address families AF_INET, AF_INET6, or AF_UNSPEC (in case of + * error). + * @src: (allow-none): the source buffer with an sockaddr to copy. It may be unaligned in + * memory. If not %NULL, the buffer must be at least large enough to contain + * sa.sa_family, and then, depending on sa.sa_family, it must be large enough + * to hold struct sockaddr_in or struct sockaddr_in6. + * + * @dst will always be fully initialized (including setting all un-used bytes to zero). + */ +void +nm_sock_addr_union_cpy(NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */) +{ + struct sockaddr sa; + gsize src_len; + + nm_assert(dst); + + *dst = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; + + if (!src) + return; + + memcpy(&sa.sa_family, &((struct sockaddr *) src)->sa_family, sizeof(sa.sa_family)); + + if (sa.sa_family == AF_INET) + src_len = sizeof(struct sockaddr_in); + else if (sa.sa_family == AF_INET6) + src_len = sizeof(struct sockaddr_in6); + else + return; + + memcpy(dst, src, src_len); + nm_assert(dst->sa.sa_family == sa.sa_family); +} + +/** + * nm_sock_addr_union_cpy_untrusted: + * @dst: the destination #NMSockAddrUnion. It will always be fully initialized, + * to one of the address families AF_INET, AF_INET6, or AF_UNSPEC (in case of + * error). + * @src: the source buffer with an sockaddr to copy. It may be unaligned in + * memory. + * @src_len: the length of @src in bytes. + * + * The function requires @src_len to be either sizeof(struct sockaddr_in) or sizeof (struct sockaddr_in6). + * If that's the case, then @src will be interpreted as such structure (unaligned), and + * accessed. It will check sa.sa_family to match the expected sizes, and if it does, the + * struct will be copied. + * + * On any failure, @dst will be set to sa.sa_family AF_UNSPEC. + * @dst will always be fully initialized (including setting all un-used bytes to zero). + */ +void +nm_sock_addr_union_cpy_untrusted(NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */, + gsize src_len) +{ + int f_expected; + struct sockaddr sa; + + nm_assert(dst); + + *dst = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; + + if (src_len == sizeof(struct sockaddr_in)) + f_expected = AF_INET; + else if (src_len == sizeof(struct sockaddr_in6)) + f_expected = AF_INET6; + else + return; + + memcpy(&sa.sa_family, &((struct sockaddr *) src)->sa_family, sizeof(sa.sa_family)); + + if (sa.sa_family != f_expected) + return; + + memcpy(dst, src, src_len); + nm_assert(dst->sa.sa_family == sa.sa_family); +} + +const char * +nm_sock_addr_union_to_string(const NMSockAddrUnion *sa, char *buf, gsize len) +{ + char s_addr[NM_UTILS_INET_ADDRSTRLEN]; + char s_scope_id[40]; + + if (!nm_utils_to_string_buffer_init_null(sa, &buf, &len)) + return buf; + + /* maybe we should use getnameinfo(), but here implement it ourself. + * + * We want to see the actual bytes for debugging (as we understand them), + * and now what getnameinfo() makes of it. Also, it's simpler this way. */ + + switch (sa->sa.sa_family) { + case AF_INET: + g_snprintf(buf, + len, + "%s:%u", + _nm_utils_inet4_ntop(sa->in.sin_addr.s_addr, s_addr), + (guint) htons(sa->in.sin_port)); + break; + case AF_INET6: + g_snprintf(buf, + len, + "[%s%s]:%u", + _nm_utils_inet6_ntop(&sa->in6.sin6_addr, s_addr), + (sa->in6.sin6_scope_id != 0 + ? nm_sprintf_buf(s_scope_id, "%u", sa->in6.sin6_scope_id) + : ""), + (guint) htons(sa->in6.sin6_port)); + break; + case AF_UNSPEC: + g_snprintf(buf, len, "unspec"); + break; + default: + g_snprintf(buf, len, "{addr-family:%u}", (unsigned) sa->sa.sa_family); + break; + } + + return buf; +} + +/*****************************************************************************/ + +static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class; + +static void +_idx_obj_id_hash_update(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj, + NMHashState * h) +{ + const NMPObject *o = (NMPObject *) obj; + + nm_assert(idx_type && idx_type->klass == &_dedup_multi_idx_type_class); + nm_assert(NMP_OBJECT_GET_TYPE(o) != NMP_OBJECT_TYPE_UNKNOWN); + + nmp_object_id_hash_update(o, h); +} + +static gboolean +_idx_obj_id_equal(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj_a, + const NMDedupMultiObj * obj_b) +{ + const NMPObject *o_a = (NMPObject *) obj_a; + const NMPObject *o_b = (NMPObject *) obj_b; + + nm_assert(idx_type && idx_type->klass == &_dedup_multi_idx_type_class); + nm_assert(NMP_OBJECT_GET_TYPE(o_a) != NMP_OBJECT_TYPE_UNKNOWN); + nm_assert(NMP_OBJECT_GET_TYPE(o_b) != NMP_OBJECT_TYPE_UNKNOWN); + + return nmp_object_id_equal(o_a, o_b); +} + +static guint +_idx_obj_part(const DedupMultiIdxType *idx_type, + const NMPObject * obj_a, + const NMPObject * obj_b, + NMHashState * h) +{ + NMPObjectType obj_type; + + /* the hash/equals functions are strongly related. So, keep them + * side-by-side and do it all in _idx_obj_part(). */ + + nm_assert(idx_type); + nm_assert(idx_type->parent.klass == &_dedup_multi_idx_type_class); + nm_assert(obj_a); + nm_assert(NMP_OBJECT_GET_TYPE(obj_a) != NMP_OBJECT_TYPE_UNKNOWN); + nm_assert(!obj_b || (NMP_OBJECT_GET_TYPE(obj_b) != NMP_OBJECT_TYPE_UNKNOWN)); + nm_assert(!h || !obj_b); + + switch (idx_type->cache_id_type) { + case NMP_CACHE_ID_TYPE_OBJECT_TYPE: + if (obj_b) + return NMP_OBJECT_GET_TYPE(obj_a) == NMP_OBJECT_GET_TYPE(obj_b); + if (h) { + nm_hash_update_vals(h, idx_type->cache_id_type, NMP_OBJECT_GET_TYPE(obj_a)); + } + return 1; + + case NMP_CACHE_ID_TYPE_LINK_BY_IFNAME: + if (NMP_OBJECT_GET_TYPE(obj_a) != NMP_OBJECT_TYPE_LINK) { + /* first check, whether obj_a is suitable for this idx_type. + * If not, return 0 (which is correct for partitionable(), hash() and equal() + * functions. */ + if (h) + nm_hash_update_val(h, obj_a); + return 0; + } + if (obj_b) { + /* we are in equal() mode. Compare obj_b with obj_a. */ + return NMP_OBJECT_GET_TYPE(obj_b) == NMP_OBJECT_TYPE_LINK + && nm_streq(obj_a->link.name, obj_b->link.name); + } + if (h) { + nm_hash_update_val(h, idx_type->cache_id_type); + nm_hash_update_strarr(h, obj_a->link.name); + } + /* just return 1, to indicate that obj_a is partitionable by this idx_type. */ + return 1; + + case NMP_CACHE_ID_TYPE_DEFAULT_ROUTES: + if (!NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_a), + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE) + || !NM_PLATFORM_IP_ROUTE_IS_DEFAULT(&obj_a->ip_route) + || !nmp_object_is_visible(obj_a)) { + if (h) + nm_hash_update_val(h, obj_a); + return 0; + } + if (obj_b) { + return NMP_OBJECT_GET_TYPE(obj_a) == NMP_OBJECT_GET_TYPE(obj_b) + && NM_PLATFORM_IP_ROUTE_IS_DEFAULT(&obj_b->ip_route) + && nmp_object_is_visible(obj_b); + } + if (h) { + nm_hash_update_vals(h, idx_type->cache_id_type, NMP_OBJECT_GET_TYPE(obj_a)); + } + return 1; + + case NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX: + if (!NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_a), + NMP_OBJECT_TYPE_IP4_ADDRESS, + NMP_OBJECT_TYPE_IP6_ADDRESS, + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE, + NMP_OBJECT_TYPE_QDISC, + NMP_OBJECT_TYPE_TFILTER) + || !nmp_object_is_visible(obj_a)) { + if (h) + nm_hash_update_val(h, obj_a); + return 0; + } + nm_assert(NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex > 0); + if (obj_b) { + return NMP_OBJECT_GET_TYPE(obj_a) == NMP_OBJECT_GET_TYPE(obj_b) + && NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex + == NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_b)->ifindex + && nmp_object_is_visible(obj_b); + } + if (h) { + nm_hash_update_vals(h, idx_type->cache_id_type, obj_a->obj_with_ifindex.ifindex); + } + return 1; + + case NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID: + obj_type = NMP_OBJECT_GET_TYPE(obj_a); + if (!NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) + || NMP_OBJECT_CAST_IP_ROUTE(obj_a)->ifindex <= 0) { + if (h) + nm_hash_update_val(h, obj_a); + return 0; + } + if (obj_b) { + return obj_type == NMP_OBJECT_GET_TYPE(obj_b) + && NMP_OBJECT_CAST_IP_ROUTE(obj_b)->ifindex > 0 + && (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE + ? (nm_platform_ip4_route_cmp(&obj_a->ip4_route, + &obj_b->ip4_route, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) + == 0) + : (nm_platform_ip6_route_cmp(&obj_a->ip6_route, + &obj_b->ip6_route, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) + == 0)); + } + if (h) { + nm_hash_update_val(h, idx_type->cache_id_type); + if (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE) + nm_platform_ip4_route_hash_update(&obj_a->ip4_route, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, + h); + else + nm_platform_ip6_route_hash_update(&obj_a->ip6_route, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, + h); + } + return 1; + + case NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY: + obj_type = NMP_OBJECT_GET_TYPE(obj_a); + /* currently, only routing rules are supported for this cache-id-type. */ + if (obj_type != NMP_OBJECT_TYPE_ROUTING_RULE + || !NM_IN_SET(obj_a->routing_rule.addr_family, AF_INET, AF_INET6)) { + if (h) + nm_hash_update_val(h, obj_a); + return 0; + } + if (obj_b) { + return NMP_OBJECT_GET_TYPE(obj_b) == NMP_OBJECT_TYPE_ROUTING_RULE + && obj_a->routing_rule.addr_family == obj_b->routing_rule.addr_family; + } + if (h) { + nm_hash_update_vals(h, idx_type->cache_id_type, obj_a->routing_rule.addr_family); + } + return 1; + + case NMP_CACHE_ID_TYPE_NONE: + case __NMP_CACHE_ID_TYPE_MAX: + break; + } + nm_assert_not_reached(); + return 0; +} + +static gboolean +_idx_obj_partitionable(const NMDedupMultiIdxType *idx_type, const NMDedupMultiObj *obj) +{ + return _idx_obj_part((DedupMultiIdxType *) idx_type, (NMPObject *) obj, NULL, NULL) != 0; +} + +static void +_idx_obj_partition_hash_update(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj, + NMHashState * h) +{ + _idx_obj_part((DedupMultiIdxType *) idx_type, (NMPObject *) obj, NULL, h); +} + +static gboolean +_idx_obj_partition_equal(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj_a, + const NMDedupMultiObj * obj_b) +{ + return _idx_obj_part((DedupMultiIdxType *) idx_type, + (NMPObject *) obj_a, + (NMPObject *) obj_b, + NULL); +} + +static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class = { + .idx_obj_id_hash_update = _idx_obj_id_hash_update, + .idx_obj_id_equal = _idx_obj_id_equal, + .idx_obj_partitionable = _idx_obj_partitionable, + .idx_obj_partition_hash_update = _idx_obj_partition_hash_update, + .idx_obj_partition_equal = _idx_obj_partition_equal, +}; + +static void +_dedup_multi_idx_type_init(DedupMultiIdxType *idx_type, NMPCacheIdType cache_id_type) +{ + nm_dedup_multi_idx_type_init((NMDedupMultiIdxType *) idx_type, &_dedup_multi_idx_type_class); + idx_type->cache_id_type = cache_id_type; +} + +/*****************************************************************************/ + +static void +_vlan_xgress_qos_mappings_hash_update(guint n_map, const NMVlanQosMapping *map, NMHashState *h) +{ + /* ensure no padding. */ + G_STATIC_ASSERT(sizeof(NMVlanQosMapping) == 2 * sizeof(guint32)); + + nm_hash_update_val(h, n_map); + if (n_map) + nm_hash_update(h, map, n_map * sizeof(*map)); +} + +static int +_vlan_xgress_qos_mappings_cmp(guint n_map, + const NMVlanQosMapping *map1, + const NMVlanQosMapping *map2) +{ + guint i; + + for (i = 0; i < n_map; i++) { + if (map1[i].from != map2[i].from) + return map1[i].from < map2[i].from ? -1 : 1; + if (map1[i].to != map2[i].to) + return map1[i].to < map2[i].to ? -1 : 1; + } + return 0; +} + +static void +_vlan_xgress_qos_mappings_cpy(guint * dst_n_map, + NMVlanQosMapping ** dst_map, + guint src_n_map, + const NMVlanQosMapping *src_map) +{ + if (src_n_map == 0) { + nm_clear_g_free(dst_map); + *dst_n_map = 0; + } else if (src_n_map != *dst_n_map + || _vlan_xgress_qos_mappings_cmp(src_n_map, *dst_map, src_map) != 0) { + nm_clear_g_free(dst_map); + *dst_n_map = src_n_map; + if (src_n_map > 0) + *dst_map = nm_memdup(src_map, sizeof(*src_map) * src_n_map); + } +} + +/*****************************************************************************/ + +static void +_wireguard_allowed_ip_hash_update(const NMPWireGuardAllowedIP *ip, NMHashState *h) +{ + nm_hash_update_vals(h, ip->family, ip->mask); + + if (ip->family == AF_INET) + nm_hash_update_val(h, ip->addr.addr4); + else if (ip->family == AF_INET6) + nm_hash_update_val(h, ip->addr.addr6); +} + +static int +_wireguard_allowed_ip_cmp(const NMPWireGuardAllowedIP *a, const NMPWireGuardAllowedIP *b) +{ + NM_CMP_SELF(a, b); + + NM_CMP_FIELD(a, b, family); + NM_CMP_FIELD(a, b, mask); + + if (a->family == AF_INET) + NM_CMP_FIELD(a, b, addr.addr4); + else if (a->family == AF_INET6) + NM_CMP_FIELD_IN6ADDR(a, b, addr.addr6); + + return 0; +} + +static void +_wireguard_peer_hash_update(const NMPWireGuardPeer *peer, NMHashState *h) +{ + guint i; + + nm_hash_update(h, peer->public_key, sizeof(peer->public_key)); + nm_hash_update(h, peer->preshared_key, sizeof(peer->preshared_key)); + nm_hash_update_vals(h, + peer->persistent_keepalive_interval, + peer->allowed_ips_len, + peer->rx_bytes, + peer->tx_bytes, + peer->last_handshake_time.tv_sec, + peer->last_handshake_time.tv_nsec); + + nm_sock_addr_union_hash_update(&peer->endpoint, h); + + for (i = 0; i < peer->allowed_ips_len; i++) + _wireguard_allowed_ip_hash_update(&peer->allowed_ips[i], h); +} + +static int +_wireguard_peer_cmp(const NMPWireGuardPeer *a, const NMPWireGuardPeer *b) +{ + guint i; + + NM_CMP_SELF(a, b); + + NM_CMP_FIELD(a, b, last_handshake_time.tv_sec); + NM_CMP_FIELD(a, b, last_handshake_time.tv_nsec); + NM_CMP_FIELD(a, b, rx_bytes); + NM_CMP_FIELD(a, b, tx_bytes); + NM_CMP_FIELD(a, b, allowed_ips_len); + NM_CMP_FIELD(a, b, persistent_keepalive_interval); + NM_CMP_FIELD(a, b, endpoint.sa.sa_family); + NM_CMP_FIELD_MEMCMP(a, b, public_key); + NM_CMP_FIELD_MEMCMP(a, b, preshared_key); + + NM_CMP_RETURN(nm_sock_addr_union_cmp(&a->endpoint, &b->endpoint)); + + for (i = 0; i < a->allowed_ips_len; i++) { + NM_CMP_RETURN(_wireguard_allowed_ip_cmp(&a->allowed_ips[i], &b->allowed_ips[i])); + } + + return 0; +} + +/*****************************************************************************/ + +static const char * +_link_get_driver(struct udev_device *udevice, const char *kind, int ifindex) +{ + const char *driver = NULL; + + nm_assert(kind == g_intern_string(kind)); + + if (udevice) { + driver = nmp_utils_udev_get_driver(udevice); + if (driver) + return driver; + } + + if (kind) + return kind; + + if (ifindex > 0) { + NMPUtilsEthtoolDriverInfo driver_info; + + if (nmp_utils_ethtool_get_driver_info(ifindex, &driver_info)) { + if (driver_info.driver[0]) + return g_intern_string(driver_info.driver); + } + } + + return "unknown"; +} + +void +_nmp_object_fixup_link_udev_fields(NMPObject **obj_new, NMPObject *obj_orig, gboolean use_udev) +{ + const char *driver = NULL; + gboolean initialized = FALSE; + NMPObject * obj; + + nm_assert(obj_orig || *obj_new); + nm_assert(obj_new); + nm_assert(!obj_orig || NMP_OBJECT_GET_TYPE(obj_orig) == NMP_OBJECT_TYPE_LINK); + nm_assert(!*obj_new || NMP_OBJECT_GET_TYPE(*obj_new) == NMP_OBJECT_TYPE_LINK); + + obj = *obj_new ?: obj_orig; + + /* The link contains internal fields that are combined by + * properties from netlink and udev. Update those properties */ + + /* When a link is not in netlink, its udev fields don't matter. */ + if (obj->_link.netlink.is_in_netlink) { + driver = _link_get_driver(obj->_link.udev.device, obj->link.kind, obj->link.ifindex); + if (obj->_link.udev.device) + initialized = TRUE; + else if (!use_udev) { + /* If we don't use udev, we immediately mark the link as initialized. + * + * For that, we consult @use_udev argument, that is cached via + * nmp_cache_use_udev_get(). It is on purpose not to test + * for a writable /sys on every call. A minor reason for that is + * performance, but the real reason is reproducibility. + * */ + initialized = TRUE; + } + } + + if (nm_streq0(obj->link.driver, driver) && obj->link.initialized == initialized) + return; + + if (!*obj_new) + obj = *obj_new = nmp_object_clone(obj, FALSE); + + obj->link.driver = driver; + obj->link.initialized = initialized; +} + +static void +_nmp_object_fixup_link_master_connected(NMPObject ** obj_new, + NMPObject * obj_orig, + const NMPCache *cache) +{ + NMPObject *obj; + + nm_assert(obj_orig || *obj_new); + nm_assert(obj_new); + nm_assert(!obj_orig || NMP_OBJECT_GET_TYPE(obj_orig) == NMP_OBJECT_TYPE_LINK); + nm_assert(!*obj_new || NMP_OBJECT_GET_TYPE(*obj_new) == NMP_OBJECT_TYPE_LINK); + + obj = *obj_new ?: obj_orig; + + if (nmp_cache_link_connected_needs_toggle(cache, obj, NULL, NULL)) { + if (!*obj_new) + obj = *obj_new = nmp_object_clone(obj, FALSE); + obj->link.connected = !obj->link.connected; + } +} + +/*****************************************************************************/ + +static void +_vt_cmd_obj_dispose_link(NMPObject *obj) +{ + if (obj->_link.udev.device) { + udev_device_unref(obj->_link.udev.device); + obj->_link.udev.device = NULL; + } + g_clear_object(&obj->_link.ext_data); + nmp_object_unref(obj->_link.netlink.lnk); +} + +static void +_vt_cmd_obj_dispose_lnk_vlan(NMPObject *obj) +{ + g_free((gpointer) obj->_lnk_vlan.ingress_qos_map); + g_free((gpointer) obj->_lnk_vlan.egress_qos_map); +} + +static void +_wireguard_clear(NMPObjectLnkWireGuard *lnk) +{ + guint i; + + nm_explicit_bzero(lnk->_public.private_key, sizeof(lnk->_public.private_key)); + for (i = 0; i < lnk->peers_len; i++) { + NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &lnk->peers[i]; + + nm_explicit_bzero(peer->preshared_key, sizeof(peer->preshared_key)); + } + g_free((gpointer) lnk->peers); + g_free((gpointer) lnk->_allowed_ips_buf); +} + +static void +_vt_cmd_obj_dispose_lnk_wireguard(NMPObject *obj) +{ + _wireguard_clear(&obj->_lnk_wireguard); +} + +static NMPObject * +_nmp_object_new_from_class(const NMPClass *klass) +{ + NMPObject *obj; + + nm_assert(klass); + nm_assert(klass->sizeof_data > 0); + nm_assert(klass->sizeof_public > 0 && klass->sizeof_public <= klass->sizeof_data); + + obj = g_slice_alloc0(klass->sizeof_data + G_STRUCT_OFFSET(NMPObject, object)); + obj->_class = klass; + obj->parent._ref_count = 1; + return obj; +} + +NMPObject * +nmp_object_new(NMPObjectType obj_type, gconstpointer plobj) +{ + const NMPClass *klass = nmp_class_from_type(obj_type); + NMPObject * obj; + + obj = _nmp_object_new_from_class(klass); + if (plobj) + memcpy(&obj->object, plobj, klass->sizeof_public); + return obj; +} + +NMPObject * +nmp_object_new_link(int ifindex) +{ + NMPObject *obj; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LINK, NULL); + obj->link.ifindex = ifindex; + return obj; +} + +/*****************************************************************************/ + +static void +_nmp_object_stackinit_from_class(NMPObject *obj, const NMPClass *klass) +{ + nm_assert(obj); + nm_assert(klass); + + *obj = (NMPObject){ + .parent = + { + .klass = (const NMDedupMultiObjClass *) klass, + ._ref_count = NM_OBJ_REF_COUNT_STACKINIT, + }, + }; +} + +static NMPObject * +_nmp_object_stackinit_from_type(NMPObject *obj, NMPObjectType obj_type) +{ + const NMPClass *klass; + + nm_assert(obj); + klass = nmp_class_from_type(obj_type); + nm_assert(klass); + + *obj = (NMPObject){ + .parent = + { + .klass = (const NMDedupMultiObjClass *) klass, + ._ref_count = NM_OBJ_REF_COUNT_STACKINIT, + }, + }; + return obj; +} + +const NMPObject * +nmp_object_stackinit(NMPObject *obj, NMPObjectType obj_type, gconstpointer plobj) +{ + const NMPClass *klass = nmp_class_from_type(obj_type); + + _nmp_object_stackinit_from_class(obj, klass); + if (plobj) + memcpy(&obj->object, plobj, klass->sizeof_public); + return obj; +} + +const NMPObject * +nmp_object_stackinit_id(NMPObject *obj, const NMPObject *src) +{ + const NMPClass *klass; + + nm_assert(NMP_OBJECT_IS_VALID(src)); + nm_assert(obj); + + klass = NMP_OBJECT_GET_CLASS(src); + _nmp_object_stackinit_from_class(obj, klass); + if (klass->cmd_plobj_id_copy) + klass->cmd_plobj_id_copy(&obj->object, &src->object); + return obj; +} + +const NMPObject * +nmp_object_stackinit_id_link(NMPObject *obj, int ifindex) +{ + _nmp_object_stackinit_from_type(obj, NMP_OBJECT_TYPE_LINK); + obj->link.ifindex = ifindex; + return obj; +} + +const NMPObject * +nmp_object_stackinit_id_ip4_address(NMPObject *obj, + int ifindex, + guint32 address, + guint8 plen, + guint32 peer_address) +{ + _nmp_object_stackinit_from_type(obj, NMP_OBJECT_TYPE_IP4_ADDRESS); + obj->ip4_address.ifindex = ifindex; + obj->ip4_address.address = address; + obj->ip4_address.plen = plen; + obj->ip4_address.peer_address = peer_address; + return obj; +} + +const NMPObject * +nmp_object_stackinit_id_ip6_address(NMPObject *obj, int ifindex, const struct in6_addr *address) +{ + _nmp_object_stackinit_from_type(obj, NMP_OBJECT_TYPE_IP6_ADDRESS); + obj->ip4_address.ifindex = ifindex; + if (address) + obj->ip6_address.address = *address; + return obj; +} + +/*****************************************************************************/ + +const char * +nmp_object_to_string(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size) +{ + const NMPClass *klass; + char buf2[sizeof(_nm_utils_to_string_buffer)]; + + if (!nm_utils_to_string_buffer_init_null(obj, &buf, &buf_size)) + return buf; + + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj), NULL); + + klass = NMP_OBJECT_GET_CLASS(obj); + + if (klass->cmd_obj_to_string) + return klass->cmd_obj_to_string(obj, to_string_mode, buf, buf_size); + + switch (to_string_mode) { + case NMP_OBJECT_TO_STRING_ID: + if (!klass->cmd_plobj_to_string_id) { + g_snprintf(buf, buf_size, "%p", obj); + return buf; + } + return klass->cmd_plobj_to_string_id(&obj->object, buf, buf_size); + case NMP_OBJECT_TO_STRING_ALL: + g_snprintf( + buf, + buf_size, + "[%s,%p,%u,%calive,%cvisible; %s]", + klass->obj_type_name, + obj, + obj->parent._ref_count, + nmp_object_is_alive(obj) ? '+' : '-', + nmp_object_is_visible(obj) ? '+' : '-', + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, buf2, sizeof(buf2))); + return buf; + case NMP_OBJECT_TO_STRING_PUBLIC: + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, buf, buf_size); + return buf; + default: + g_return_val_if_reached("ERROR"); + } +} + +static const char * +_vt_cmd_obj_to_string_link(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size) +{ + const NMPClass *klass = NMP_OBJECT_GET_CLASS(obj); + char * b = buf; + + switch (to_string_mode) { + case NMP_OBJECT_TO_STRING_ID: + return klass->cmd_plobj_to_string_id(&obj->object, buf, buf_size); + case NMP_OBJECT_TO_STRING_ALL: + nm_utils_strbuf_append(&b, + &buf_size, + "[%s,%p,%u,%calive,%cvisible,%cin-nl,%p; ", + klass->obj_type_name, + obj, + obj->parent._ref_count, + nmp_object_is_alive(obj) ? '+' : '-', + nmp_object_is_visible(obj) ? '+' : '-', + obj->_link.netlink.is_in_netlink ? '+' : '-', + obj->_link.udev.device); + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, b, buf_size); + nm_utils_strbuf_seek_end(&b, &buf_size); + if (obj->_link.netlink.lnk) { + nm_utils_strbuf_append_str(&b, &buf_size, "; "); + nmp_object_to_string(obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_ALL, b, buf_size); + nm_utils_strbuf_seek_end(&b, &buf_size); + } + nm_utils_strbuf_append_c(&b, &buf_size, ']'); + return buf; + case NMP_OBJECT_TO_STRING_PUBLIC: + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, b, buf_size); + if (obj->_link.netlink.lnk) { + nm_utils_strbuf_seek_end(&b, &buf_size); + nm_utils_strbuf_append_str(&b, &buf_size, "; "); + nmp_object_to_string(obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_PUBLIC, b, buf_size); + } + return buf; + default: + g_return_val_if_reached("ERROR"); + } +} + +static const char * +_vt_cmd_obj_to_string_lnk_vlan(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size) +{ + const NMPClass *klass; + char buf2[sizeof(_nm_utils_to_string_buffer)]; + char * b; + gsize l; + + klass = NMP_OBJECT_GET_CLASS(obj); + + switch (to_string_mode) { + case NMP_OBJECT_TO_STRING_ID: + g_snprintf(buf, buf_size, "%p", obj); + return buf; + case NMP_OBJECT_TO_STRING_ALL: + + g_snprintf(buf, + buf_size, + "[%s,%p,%u,%calive,%cvisible; %s]", + klass->obj_type_name, + obj, + obj->parent._ref_count, + nmp_object_is_alive(obj) ? '+' : '-', + nmp_object_is_visible(obj) ? '+' : '-', + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof(buf2))); + return buf; + case NMP_OBJECT_TO_STRING_PUBLIC: + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, buf, buf_size); + + b = buf; + l = strlen(b); + b += l; + buf_size -= l; + + if (obj->_lnk_vlan.n_ingress_qos_map) { + nm_platform_vlan_qos_mapping_to_string(" ingress-qos-map", + obj->_lnk_vlan.ingress_qos_map, + obj->_lnk_vlan.n_ingress_qos_map, + b, + buf_size); + l = strlen(b); + b += l; + buf_size -= l; + } + if (obj->_lnk_vlan.n_egress_qos_map) { + nm_platform_vlan_qos_mapping_to_string(" egress-qos-map", + obj->_lnk_vlan.egress_qos_map, + obj->_lnk_vlan.n_egress_qos_map, + b, + buf_size); + l = strlen(b); + b += l; + buf_size -= l; + } + + return buf; + default: + g_return_val_if_reached("ERROR"); + } +} + +static const char * +_vt_cmd_obj_to_string_lnk_wireguard(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size) +{ + const NMPClass *klass; + char buf2[sizeof(_nm_utils_to_string_buffer)]; + char * b; + guint i; + + klass = NMP_OBJECT_GET_CLASS(obj); + + switch (to_string_mode) { + case NMP_OBJECT_TO_STRING_ID: + g_snprintf(buf, buf_size, "%p", obj); + return buf; + case NMP_OBJECT_TO_STRING_ALL: + b = buf; + + nm_utils_strbuf_append( + &b, + &buf_size, + "[%s,%p,%u,%calive,%cvisible; %s" + "%s", + klass->obj_type_name, + obj, + obj->parent._ref_count, + nmp_object_is_alive(obj) ? '+' : '-', + nmp_object_is_visible(obj) ? '+' : '-', + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof(buf2)), + obj->_lnk_wireguard.peers_len > 0 ? " peers {" : ""); + + for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) { + const NMPWireGuardPeer *peer = &obj->_lnk_wireguard.peers[i]; + + nm_utils_strbuf_append_str(&b, &buf_size, " { "); + nm_platform_wireguard_peer_to_string(peer, b, buf_size); + nm_utils_strbuf_seek_end(&b, &buf_size); + nm_utils_strbuf_append_str(&b, &buf_size, " }"); + } + if (obj->_lnk_wireguard.peers_len) + nm_utils_strbuf_append_str(&b, &buf_size, " }"); + + return buf; + case NMP_OBJECT_TO_STRING_PUBLIC: + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, buf, buf_size); + + return buf; + default: + g_return_val_if_reached("ERROR"); + } +} + +#define _vt_cmd_plobj_to_string_id(type, plat_type, ...) \ + static const char *_vt_cmd_plobj_to_string_id_##type(const NMPlatformObject *_obj, \ + char * buf, \ + gsize buf_len) \ + { \ + plat_type *const obj = (plat_type *) _obj; \ + _nm_unused char buf1[NM_UTILS_INET_ADDRSTRLEN]; \ + _nm_unused char buf2[NM_UTILS_INET_ADDRSTRLEN]; \ + \ + g_snprintf(buf, buf_len, __VA_ARGS__); \ + return buf; \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +_vt_cmd_plobj_to_string_id(link, NMPlatformLink, "%d", obj->ifindex); + +_vt_cmd_plobj_to_string_id(ip4_address, + NMPlatformIP4Address, + "%d: %s/%d%s%s", + obj->ifindex, + _nm_utils_inet4_ntop(obj->address, buf1), + obj->plen, + obj->peer_address != obj->address ? "," : "", + obj->peer_address != obj->address ? _nm_utils_inet4_ntop( + nm_utils_ip4_address_clear_host_address(obj->peer_address, + obj->plen), + buf2) + : ""); + +_vt_cmd_plobj_to_string_id(ip6_address, + NMPlatformIP6Address, + "%d: %s", + obj->ifindex, + _nm_utils_inet6_ntop(&obj->address, buf1)); + +_vt_cmd_plobj_to_string_id(qdisc, NMPlatformQdisc, "%d: %d", obj->ifindex, obj->parent); + +_vt_cmd_plobj_to_string_id(tfilter, NMPlatformTfilter, "%d: %d", obj->ifindex, obj->parent); + +void +nmp_object_hash_update(const NMPObject *obj, NMHashState *h) +{ + const NMPClass *klass; + + g_return_if_fail(NMP_OBJECT_IS_VALID(obj)); + + klass = NMP_OBJECT_GET_CLASS(obj); + + nm_hash_update_val(h, klass->obj_type); + if (klass->cmd_obj_hash_update) + klass->cmd_obj_hash_update(obj, h); + else if (klass->cmd_plobj_hash_update) + klass->cmd_plobj_hash_update(&obj->object, h); + else + nm_hash_update_val(h, obj); +} + +static void +_vt_cmd_obj_hash_update_link(const NMPObject *obj, NMHashState *h) +{ + nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_LINK); + + nm_platform_link_hash_update(&obj->link, h); + nm_hash_update_vals(h, + obj->_link.netlink.is_in_netlink, + obj->_link.wireguard_family_id, + obj->_link.udev.device); + if (obj->_link.netlink.lnk) + nmp_object_hash_update(obj->_link.netlink.lnk, h); +} + +static void +_vt_cmd_obj_hash_update_lnk_vlan(const NMPObject *obj, NMHashState *h) +{ + nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_LNK_VLAN); + + nm_platform_lnk_vlan_hash_update(&obj->lnk_vlan, h); + _vlan_xgress_qos_mappings_hash_update(obj->_lnk_vlan.n_ingress_qos_map, + obj->_lnk_vlan.ingress_qos_map, + h); + _vlan_xgress_qos_mappings_hash_update(obj->_lnk_vlan.n_egress_qos_map, + obj->_lnk_vlan.egress_qos_map, + h); +} + +static void +_vt_cmd_obj_hash_update_lnk_wireguard(const NMPObject *obj, NMHashState *h) +{ + guint i; + + nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_LNK_WIREGUARD); + + nm_platform_lnk_wireguard_hash_update(&obj->lnk_wireguard, h); + + nm_hash_update_val(h, obj->_lnk_wireguard.peers_len); + for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) + _wireguard_peer_hash_update(&obj->_lnk_wireguard.peers[i], h); +} + +int +nmp_object_cmp(const NMPObject *obj1, const NMPObject *obj2) +{ + const NMPClass *klass1, *klass2; + + NM_CMP_SELF(obj1, obj2); + + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj1), -1); + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj2), 1); + + klass1 = NMP_OBJECT_GET_CLASS(obj1); + klass2 = NMP_OBJECT_GET_CLASS(obj2); + + if (klass1 != klass2) { + nm_assert(klass1->obj_type != klass2->obj_type); + return klass1->obj_type < klass2->obj_type ? -1 : 1; + } + + if (klass1->cmd_obj_cmp) + return klass1->cmd_obj_cmp(obj1, obj2); + return klass1->cmd_plobj_cmp(&obj1->object, &obj2->object); +} + +static int +_vt_cmd_obj_cmp_link(const NMPObject *obj1, const NMPObject *obj2) +{ + NM_CMP_RETURN(nm_platform_link_cmp(&obj1->link, &obj2->link)); + NM_CMP_DIRECT(obj1->_link.netlink.is_in_netlink, obj2->_link.netlink.is_in_netlink); + NM_CMP_RETURN(nmp_object_cmp(obj1->_link.netlink.lnk, obj2->_link.netlink.lnk)); + NM_CMP_DIRECT(obj1->_link.wireguard_family_id, obj2->_link.wireguard_family_id); + + if (obj1->_link.udev.device != obj2->_link.udev.device) { + if (!obj1->_link.udev.device) + return -1; + if (!obj2->_link.udev.device) + return 1; + + /* Only compare based on pointer values. That is ugly because it's not a + * stable sort order. + * + * Have this check as very last. */ + return (obj1->_link.udev.device < obj2->_link.udev.device) ? -1 : 1; + } + + return 0; +} + +static int +_vt_cmd_obj_cmp_lnk_vlan(const NMPObject *obj1, const NMPObject *obj2) +{ + int c; + + c = nm_platform_lnk_vlan_cmp(&obj1->lnk_vlan, &obj2->lnk_vlan); + if (c) + return c; + + if (obj1->_lnk_vlan.n_ingress_qos_map != obj2->_lnk_vlan.n_ingress_qos_map) + return obj1->_lnk_vlan.n_ingress_qos_map < obj2->_lnk_vlan.n_ingress_qos_map ? -1 : 1; + if (obj1->_lnk_vlan.n_egress_qos_map != obj2->_lnk_vlan.n_egress_qos_map) + return obj1->_lnk_vlan.n_egress_qos_map < obj2->_lnk_vlan.n_egress_qos_map ? -1 : 1; + + c = _vlan_xgress_qos_mappings_cmp(obj1->_lnk_vlan.n_ingress_qos_map, + obj1->_lnk_vlan.ingress_qos_map, + obj2->_lnk_vlan.ingress_qos_map); + if (c) + return c; + c = _vlan_xgress_qos_mappings_cmp(obj1->_lnk_vlan.n_egress_qos_map, + obj1->_lnk_vlan.egress_qos_map, + obj2->_lnk_vlan.egress_qos_map); + + return c; +} + +static int +_vt_cmd_obj_cmp_lnk_wireguard(const NMPObject *obj1, const NMPObject *obj2) +{ + guint i; + + NM_CMP_RETURN(nm_platform_lnk_wireguard_cmp(&obj1->lnk_wireguard, &obj2->lnk_wireguard)); + + NM_CMP_FIELD(obj1, obj2, _lnk_wireguard.peers_len); + + for (i = 0; i < obj1->_lnk_wireguard.peers_len; i++) + NM_CMP_RETURN( + _wireguard_peer_cmp(&obj1->_lnk_wireguard.peers[i], &obj2->_lnk_wireguard.peers[i])); + + return 0; +} + +/* @src is a const object, which is not entirely correct for link types, where + * we increase the ref count for src->_link.udev.device. + * Hence, nmp_object_copy() can violate the const promise of @src. + * */ +void +nmp_object_copy(NMPObject *dst, const NMPObject *src, gboolean id_only) +{ + g_return_if_fail(NMP_OBJECT_IS_VALID(dst)); + g_return_if_fail(NMP_OBJECT_IS_VALID(src)); + g_return_if_fail(!NMP_OBJECT_IS_STACKINIT(dst)); + + if (src != dst) { + const NMPClass *klass = NMP_OBJECT_GET_CLASS(dst); + + g_return_if_fail(klass == NMP_OBJECT_GET_CLASS(src)); + + if (id_only) { + if (klass->cmd_plobj_id_copy) + klass->cmd_plobj_id_copy(&dst->object, &src->object); + } else if (klass->cmd_obj_copy) + klass->cmd_obj_copy(dst, src); + else + memcpy(&dst->object, &src->object, klass->sizeof_data); + } +} + +static void +_vt_cmd_obj_copy_link(NMPObject *dst, const NMPObject *src) +{ + if (dst->_link.udev.device != src->_link.udev.device) { + if (src->_link.udev.device) + udev_device_ref(src->_link.udev.device); + if (dst->_link.udev.device) + udev_device_unref(dst->_link.udev.device); + dst->_link.udev.device = src->_link.udev.device; + } + if (dst->_link.netlink.lnk != src->_link.netlink.lnk) { + if (src->_link.netlink.lnk) + nmp_object_ref(src->_link.netlink.lnk); + if (dst->_link.netlink.lnk) + nmp_object_unref(dst->_link.netlink.lnk); + dst->_link.netlink.lnk = src->_link.netlink.lnk; + } + if (dst->_link.ext_data != src->_link.ext_data) { + if (dst->_link.ext_data) + g_clear_object(&dst->_link.ext_data); + if (src->_link.ext_data) + dst->_link.ext_data = g_object_ref(src->_link.ext_data); + } + dst->_link = src->_link; +} + +static void +_vt_cmd_obj_copy_lnk_vlan(NMPObject *dst, const NMPObject *src) +{ + dst->lnk_vlan = src->lnk_vlan; + _vlan_xgress_qos_mappings_cpy( + &dst->_lnk_vlan.n_ingress_qos_map, + NM_UNCONST_PPTR(NMVlanQosMapping, &dst->_lnk_vlan.ingress_qos_map), + src->_lnk_vlan.n_ingress_qos_map, + src->_lnk_vlan.ingress_qos_map); + _vlan_xgress_qos_mappings_cpy(&dst->_lnk_vlan.n_egress_qos_map, + NM_UNCONST_PPTR(NMVlanQosMapping, &dst->_lnk_vlan.egress_qos_map), + src->_lnk_vlan.n_egress_qos_map, + src->_lnk_vlan.egress_qos_map); +} + +static void +_vt_cmd_obj_copy_lnk_wireguard(NMPObject *dst, const NMPObject *src) +{ + guint i; + + nm_assert(dst != src); + + _wireguard_clear(&dst->_lnk_wireguard); + + dst->_lnk_wireguard = src->_lnk_wireguard; + + dst->_lnk_wireguard.peers = nm_memdup(dst->_lnk_wireguard.peers, + sizeof(NMPWireGuardPeer) * dst->_lnk_wireguard.peers_len); + dst->_lnk_wireguard._allowed_ips_buf = + nm_memdup(dst->_lnk_wireguard._allowed_ips_buf, + sizeof(NMPWireGuardAllowedIP) * dst->_lnk_wireguard._allowed_ips_buf_len); + + /* all the peers' pointers point into the buffer. They need to be readjusted. */ + for (i = 0; i < dst->_lnk_wireguard.peers_len; i++) { + NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &dst->_lnk_wireguard.peers[i]; + + if (peer->allowed_ips_len == 0) { + nm_assert(!peer->allowed_ips); + continue; + } + nm_assert(dst->_lnk_wireguard._allowed_ips_buf_len > 0); + nm_assert(src->_lnk_wireguard._allowed_ips_buf); + nm_assert(peer->allowed_ips >= src->_lnk_wireguard._allowed_ips_buf); + nm_assert( + &peer->allowed_ips[peer->allowed_ips_len] + <= &src->_lnk_wireguard._allowed_ips_buf[src->_lnk_wireguard._allowed_ips_buf_len]); + + peer->allowed_ips = + &dst->_lnk_wireguard + ._allowed_ips_buf[peer->allowed_ips - src->_lnk_wireguard._allowed_ips_buf]; + } + + nm_assert(nmp_object_equal(src, dst)); +} + +#define _vt_cmd_plobj_id_copy(type, plat_type, cmd) \ + static void _vt_cmd_plobj_id_copy_##type(NMPlatformObject *_dst, const NMPlatformObject *_src) \ + { \ + plat_type *const dst = (plat_type *) _dst; \ + const plat_type *const src = (const plat_type *) _src; \ + { \ + cmd \ + } \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +_vt_cmd_plobj_id_copy(link, NMPlatformLink, { dst->ifindex = src->ifindex; }); + +_vt_cmd_plobj_id_copy(ip4_address, NMPlatformIP4Address, { + dst->ifindex = src->ifindex; + dst->plen = src->plen; + dst->address = src->address; + dst->peer_address = src->peer_address; +}); + +_vt_cmd_plobj_id_copy(ip6_address, NMPlatformIP6Address, { + dst->ifindex = src->ifindex; + dst->address = src->address; +}); + +_vt_cmd_plobj_id_copy(ip4_route, NMPlatformIP4Route, { + *dst = *src; + nm_assert(nm_platform_ip4_route_cmp(dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) == 0); +}); + +_vt_cmd_plobj_id_copy(ip6_route, NMPlatformIP6Route, { + *dst = *src; + nm_assert(nm_platform_ip6_route_cmp(dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) == 0); +}); + +_vt_cmd_plobj_id_copy(routing_rule, NMPlatformRoutingRule, { + *dst = *src; + nm_assert(nm_platform_routing_rule_cmp(dst, src, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) == 0); +}); + +/* Uses internally nmp_object_copy(), hence it also violates the const + * promise for @obj. + * */ +NMPObject * +nmp_object_clone(const NMPObject *obj, gboolean id_only) +{ + NMPObject *dst; + + if (!obj) + return NULL; + + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj), NULL); + + dst = _nmp_object_new_from_class(NMP_OBJECT_GET_CLASS(obj)); + nmp_object_copy(dst, obj, id_only); + return dst; +} + +int +nmp_object_id_cmp(const NMPObject *obj1, const NMPObject *obj2) +{ + const NMPClass *klass, *klass2; + + NM_CMP_SELF(obj1, obj2); + + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj1), FALSE); + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj2), FALSE); + + klass = NMP_OBJECT_GET_CLASS(obj1); + nm_assert(!klass->cmd_plobj_id_hash_update == !klass->cmd_plobj_id_cmp); + + klass2 = NMP_OBJECT_GET_CLASS(obj2); + nm_assert(klass); + if (klass != klass2) { + nm_assert(klass2); + NM_CMP_DIRECT(klass->obj_type, klass2->obj_type); + /* resort to pointer comparison */ + NM_CMP_DIRECT_PTR(klass, klass2); + return 0; + } + + if (!klass->cmd_plobj_id_cmp) { + /* the klass doesn't implement ID cmp(). That means, different objects + * never compare equal, but the cmp() according to their pointer value. */ + NM_CMP_DIRECT_PTR(obj1, obj2); + return 0; + } + + return klass->cmd_plobj_id_cmp(&obj1->object, &obj2->object); +} + +#define _vt_cmd_plobj_id_cmp(type, plat_type, cmd) \ + static int _vt_cmd_plobj_id_cmp_##type(const NMPlatformObject *_obj1, \ + const NMPlatformObject *_obj2) \ + { \ + const plat_type *const obj1 = (const plat_type *) _obj1; \ + const plat_type *const obj2 = (const plat_type *) _obj2; \ + \ + NM_CMP_SELF(obj1, obj2); \ + { \ + cmd; \ + } \ + return 0; \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +_vt_cmd_plobj_id_cmp(link, NMPlatformLink, { NM_CMP_FIELD(obj1, obj2, ifindex); }); + +_vt_cmd_plobj_id_cmp(ip4_address, NMPlatformIP4Address, { + NM_CMP_FIELD(obj1, obj2, ifindex); + NM_CMP_FIELD(obj1, obj2, plen); + NM_CMP_FIELD(obj1, obj2, address); + /* for IPv4 addresses, you can add the same local address with differing peer-address + * (IFA_ADDRESS), provided that their net-part differs. */ + NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(obj1->peer_address, obj2->peer_address, obj1->plen); +}); + +_vt_cmd_plobj_id_cmp(ip6_address, NMPlatformIP6Address, { + NM_CMP_FIELD(obj1, obj2, ifindex); + /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ + NM_CMP_FIELD_IN6ADDR(obj1, obj2, address); +}); + +_vt_cmd_plobj_id_cmp(qdisc, NMPlatformQdisc, { + NM_CMP_FIELD(obj1, obj2, ifindex); + NM_CMP_FIELD(obj1, obj2, parent); +}); + +_vt_cmd_plobj_id_cmp(tfilter, NMPlatformTfilter, { + NM_CMP_FIELD(obj1, obj2, ifindex); + NM_CMP_FIELD(obj1, obj2, handle); +}); + +static int +_vt_cmd_plobj_id_cmp_ip4_route(const NMPlatformObject *obj1, const NMPlatformObject *obj2) +{ + return nm_platform_ip4_route_cmp((NMPlatformIP4Route *) obj1, + (NMPlatformIP4Route *) obj2, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID); +} + +static int +_vt_cmd_plobj_id_cmp_ip6_route(const NMPlatformObject *obj1, const NMPlatformObject *obj2) +{ + return nm_platform_ip6_route_cmp((NMPlatformIP6Route *) obj1, + (NMPlatformIP6Route *) obj2, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID); +} + +static int +_vt_cmd_plobj_id_cmp_routing_rule(const NMPlatformObject *obj1, const NMPlatformObject *obj2) +{ + return nm_platform_routing_rule_cmp((NMPlatformRoutingRule *) obj1, + (NMPlatformRoutingRule *) obj2, + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID); +} + +void +nmp_object_id_hash_update(const NMPObject *obj, NMHashState *h) +{ + const NMPClass *klass; + + g_return_if_fail(NMP_OBJECT_IS_VALID(obj)); + + klass = NMP_OBJECT_GET_CLASS(obj); + + nm_assert(!klass->cmd_plobj_id_hash_update == !klass->cmd_plobj_id_cmp); + + if (!klass->cmd_plobj_id_hash_update) { + /* The klass doesn't implement ID compare. It means, to use pointer + * equality. */ + nm_hash_update_val(h, obj); + return; + } + + nm_hash_update_val(h, klass->obj_type); + klass->cmd_plobj_id_hash_update(&obj->object, h); +} + +guint +nmp_object_id_hash(const NMPObject *obj) +{ + NMHashState h; + + if (!obj) + return nm_hash_static(914932607u); + + nm_hash_init(&h, 914932607u); + nmp_object_id_hash_update(obj, &h); + return nm_hash_complete(&h); +} + +#define _vt_cmd_plobj_id_hash_update(type, plat_type, cmd) \ + static void _vt_cmd_plobj_id_hash_update_##type(const NMPlatformObject *_obj, NMHashState *h) \ + { \ + const plat_type *const obj = (const plat_type *) _obj; \ + { \ + cmd; \ + } \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +_vt_cmd_plobj_id_hash_update(link, NMPlatformLink, { nm_hash_update_val(h, obj->ifindex); }); + +_vt_cmd_plobj_id_hash_update(ip4_address, NMPlatformIP4Address, { + nm_hash_update_vals( + h, + obj->ifindex, + obj->plen, + obj->address, + /* for IPv4 we must also consider the net-part of the peer-address (IFA_ADDRESS) */ + nm_utils_ip4_address_clear_host_address(obj->peer_address, obj->plen)); +}); + +_vt_cmd_plobj_id_hash_update(ip6_address, NMPlatformIP6Address, { + nm_hash_update_vals( + h, + obj->ifindex, + /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ + obj->address); +}); + +_vt_cmd_plobj_id_hash_update(ip4_route, NMPlatformIP4Route, { + nm_platform_ip4_route_hash_update(obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, h); +}); + +_vt_cmd_plobj_id_hash_update(ip6_route, NMPlatformIP6Route, { + nm_platform_ip6_route_hash_update(obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, h); +}); + +_vt_cmd_plobj_id_hash_update(routing_rule, NMPlatformRoutingRule, { + nm_platform_routing_rule_hash_update(obj, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID, h); +}); + +_vt_cmd_plobj_id_hash_update(qdisc, NMPlatformQdisc, { + nm_hash_update_vals(h, obj->ifindex, obj->parent); +}); + +_vt_cmd_plobj_id_hash_update(tfilter, NMPlatformTfilter, { + nm_hash_update_vals(h, obj->ifindex, obj->handle); +}); + +static void +_vt_cmd_plobj_hash_update_ip4_route(const NMPlatformObject *obj, NMHashState *h) +{ + return nm_platform_ip4_route_hash_update((const NMPlatformIP4Route *) obj, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL, + h); +} + +static void +_vt_cmd_plobj_hash_update_ip6_route(const NMPlatformObject *obj, NMHashState *h) +{ + return nm_platform_ip6_route_hash_update((const NMPlatformIP6Route *) obj, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL, + h); +} + +static void +_vt_cmd_plobj_hash_update_routing_rule(const NMPlatformObject *obj, NMHashState *h) +{ + return nm_platform_routing_rule_hash_update((const NMPlatformRoutingRule *) obj, + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL, + h); +} + +guint +nmp_object_indirect_id_hash(gconstpointer a) +{ + const NMPObject *const *p_obj = a; + + return nmp_object_id_hash(*p_obj); +} + +gboolean +nmp_object_indirect_id_equal(gconstpointer a, gconstpointer b) +{ + const NMPObject *const *p_obj_a = a; + const NMPObject *const *p_obj_b = b; + + return nmp_object_id_equal(*p_obj_a, *p_obj_b); +} + +/*****************************************************************************/ + +gboolean +nmp_object_is_alive(const NMPObject *obj) +{ + const NMPClass *klass; + + /* for convenience, allow NULL. */ + if (!obj) + return FALSE; + + klass = NMP_OBJECT_GET_CLASS(obj); + return !klass->cmd_obj_is_alive || klass->cmd_obj_is_alive(obj); +} + +static gboolean +_vt_cmd_obj_is_alive_link(const NMPObject *obj) +{ + return NMP_OBJECT_CAST_LINK(obj)->ifindex > 0 + && (obj->_link.netlink.is_in_netlink || obj->_link.udev.device); +} + +static gboolean +_vt_cmd_obj_is_alive_ipx_address(const NMPObject *obj) +{ + return NMP_OBJECT_CAST_IP_ADDRESS(obj)->ifindex > 0; +} + +static gboolean +_vt_cmd_obj_is_alive_ipx_route(const NMPObject *obj) +{ + /* We want to ignore routes that are RTM_F_CLONED but we still + * let nmp_object_from_nl() create such route objects, instead of + * returning NULL right away. + * + * The idea is, that if we have the same route (according to its id) + * in the cache with !RTM_F_CLONED, an update that changes the route + * to be RTM_F_CLONED must remove the instance. + * + * If nmp_object_from_nl() would just return NULL, we couldn't look + * into the cache to see if it contains a route that now disappears + * (because it changed to be cloned). + * + * Instead we create a dead object, and nmp_cache_update_netlink() + * will remove the old version of the update. + **/ + return NMP_OBJECT_CAST_IP_ROUTE(obj)->ifindex > 0 + && !NM_FLAGS_HAS(obj->ip_route.r_rtm_flags, RTM_F_CLONED); +} + +static gboolean +_vt_cmd_obj_is_alive_routing_rule(const NMPObject *obj) +{ + return NM_IN_SET(obj->routing_rule.addr_family, AF_INET, AF_INET6); +} + +static gboolean +_vt_cmd_obj_is_alive_qdisc(const NMPObject *obj) +{ + return NMP_OBJECT_CAST_QDISC(obj)->ifindex > 0; +} + +static gboolean +_vt_cmd_obj_is_alive_tfilter(const NMPObject *obj) +{ + return NMP_OBJECT_CAST_TFILTER(obj)->ifindex > 0; +} + +gboolean +nmp_object_is_visible(const NMPObject *obj) +{ + const NMPClass *klass; + + /* for convenience, allow NULL. */ + if (!obj) + return FALSE; + + klass = NMP_OBJECT_GET_CLASS(obj); + + /* a dead object is never visible. */ + if (klass->cmd_obj_is_alive && !klass->cmd_obj_is_alive(obj)) + return FALSE; + + return !klass->cmd_obj_is_visible || klass->cmd_obj_is_visible(obj); +} + +static gboolean +_vt_cmd_obj_is_visible_link(const NMPObject *obj) +{ + return obj->_link.netlink.is_in_netlink && obj->link.name[0]; +} + +/*****************************************************************************/ + +static const guint8 _supported_cache_ids_object[] = { + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, + 0, +}; + +static const guint8 _supported_cache_ids_link[] = { + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, + 0, +}; + +static const guint8 _supported_cache_ids_ipx_address[] = { + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, + 0, +}; + +static const guint8 _supported_cache_ids_ipx_route[] = { + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, + NMP_CACHE_ID_TYPE_DEFAULT_ROUTES, + NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, + 0, +}; + +static const guint8 _supported_cache_ids_routing_rules[] = { + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY, + 0, +}; + +/*****************************************************************************/ + +static void +_vt_dedup_obj_destroy(NMDedupMultiObj *obj) +{ + NMPObject * o = (NMPObject *) obj; + const NMPClass *klass; + + nm_assert(o->parent._ref_count == 0); + nm_assert(!o->parent._multi_idx); + + klass = o->_class; + if (klass->cmd_obj_dispose) + klass->cmd_obj_dispose(o); + g_slice_free1(klass->sizeof_data + G_STRUCT_OFFSET(NMPObject, object), o); +} + +static const NMDedupMultiObj * +_vt_dedup_obj_clone(const NMDedupMultiObj *obj) +{ + return (const NMDedupMultiObj *) nmp_object_clone((const NMPObject *) obj, FALSE); +} + +#define DEDUP_MULTI_OBJ_CLASS_INIT() \ + { \ + .obj_clone = _vt_dedup_obj_clone, .obj_destroy = _vt_dedup_obj_destroy, \ + .obj_full_hash_update = \ + (void (*)(const NMDedupMultiObj *obj, NMHashState *h)) nmp_object_hash_update, \ + .obj_full_equal = (gboolean(*)(const NMDedupMultiObj *obj_a, \ + const NMDedupMultiObj *obj_b)) nmp_object_equal, \ + } + +/*****************************************************************************/ + +static NMDedupMultiIdxType * +_idx_type_get(const NMPCache *cache, NMPCacheIdType cache_id_type) +{ + nm_assert(cache); + nm_assert(cache_id_type > NMP_CACHE_ID_TYPE_NONE); + nm_assert(cache_id_type <= NMP_CACHE_ID_TYPE_MAX); + nm_assert((int) cache_id_type - 1 >= 0); + nm_assert((int) cache_id_type - 1 < G_N_ELEMENTS(cache->idx_types)); + + return (NMDedupMultiIdxType *) &cache->idx_types[cache_id_type - 1]; +} + +gboolean +nmp_cache_use_udev_get(const NMPCache *cache) +{ + g_return_val_if_fail(cache, TRUE); + + return cache->use_udev; +} + +/*****************************************************************************/ + +gboolean +nmp_cache_link_connected_for_slave(int ifindex_master, const NMPObject *slave) +{ + nm_assert(NMP_OBJECT_GET_TYPE(slave) == NMP_OBJECT_TYPE_LINK); + + return ifindex_master > 0 && slave->link.master == ifindex_master && slave->link.connected + && nmp_object_is_visible(slave); +} + +/** + * nmp_cache_link_connected_needs_toggle: + * @cache: the platform cache + * @master: the link object, that is checked whether its connected property + * needs to be toggled. + * @potential_slave: (allow-none): an additional link object that is treated + * as if it was inside @cache. If given, it shaddows a link in the cache + * with the same ifindex. + * @ignore_slave: (allow-none): if set, the check will pretend that @ignore_slave + * is not in the cache. + * + * NMPlatformLink has two connected flags: (master->link.flags&IFF_LOWER_UP) (as reported + * from netlink) and master->link.connected. For bond and bridge master, kernel reports + * those links as IFF_LOWER_UP if they have no slaves attached. We want to present instead + * a combined @connected flag that shows masters without slaves as down. + * + * Check if the connected flag of @master should be toggled according to the content + * of @cache (including @potential_slave). + * + * Returns: %TRUE, if @master->link.connected should be flipped/toggled. + **/ +gboolean +nmp_cache_link_connected_needs_toggle(const NMPCache * cache, + const NMPObject *master, + const NMPObject *potential_slave, + const NMPObject *ignore_slave) +{ + gboolean is_lower_up = FALSE; + + if (!master || NMP_OBJECT_GET_TYPE(master) != NMP_OBJECT_TYPE_LINK || master->link.ifindex <= 0 + || !nmp_object_is_visible(master) + || !NM_IN_SET(master->link.type, NM_LINK_TYPE_BRIDGE, NM_LINK_TYPE_BOND)) + return FALSE; + + /* if native IFF_LOWER_UP is down, link.connected must also be down + * regardless of the slaves. */ + if (!NM_FLAGS_HAS(master->link.n_ifi_flags, IFF_LOWER_UP)) + return !!master->link.connected; + + if (potential_slave && NMP_OBJECT_GET_TYPE(potential_slave) != NMP_OBJECT_TYPE_LINK) + potential_slave = NULL; + + if (potential_slave + && nmp_cache_link_connected_for_slave(master->link.ifindex, potential_slave)) + is_lower_up = TRUE; + else { + NMPLookup lookup; + NMDedupMultiIter iter; + const NMPlatformLink *link = NULL; + + nmp_cache_iter_for_each_link ( + &iter, + nmp_cache_lookup(cache, nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK)), + &link) { + const NMPObject *obj = NMP_OBJECT_UP_CAST((NMPlatformObject *) link); + + if ((!potential_slave || potential_slave->link.ifindex != link->ifindex) + && ignore_slave != obj + && nmp_cache_link_connected_for_slave(master->link.ifindex, obj)) { + is_lower_up = TRUE; + break; + } + } + } + return !!master->link.connected != is_lower_up; +} + +/** + * nmp_cache_link_connected_needs_toggle_by_ifindex: + * @cache: + * @master_ifindex: the ifindex of a potential master that should be checked + * whether it needs toggling. + * @potential_slave: (allow-none): passed to nmp_cache_link_connected_needs_toggle(). + * It considers @potential_slave as being inside the cache, replacing an existing + * link with the same ifindex. + * @ignore_slave: (allow-onne): passed to nmp_cache_link_connected_needs_toggle(). + * + * The flag obj->link.connected depends on the state of other links in the + * @cache. See also nmp_cache_link_connected_needs_toggle(). Given an ifindex + * of a master, check if the cache contains such a master link that needs + * toggling of the connected flag. + * + * Returns: NULL if there is no master link with ifindex @master_ifindex that should be toggled. + * Otherwise, return the link object from inside the cache with the given ifindex. + * The connected flag of that master should be toggled. + */ +const NMPObject * +nmp_cache_link_connected_needs_toggle_by_ifindex(const NMPCache * cache, + int master_ifindex, + const NMPObject *potential_slave, + const NMPObject *ignore_slave) +{ + const NMPObject *master; + + if (master_ifindex > 0) { + master = nmp_cache_lookup_link(cache, master_ifindex); + if (nmp_cache_link_connected_needs_toggle(cache, master, potential_slave, ignore_slave)) + return master; + } + return NULL; +} + +/*****************************************************************************/ + +static const NMDedupMultiEntry * +_lookup_entry_with_idx_type(const NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *obj) +{ + const NMDedupMultiEntry *entry; + + nm_assert(cache); + nm_assert(NMP_OBJECT_IS_VALID(obj)); + + entry = + nm_dedup_multi_index_lookup_obj(cache->multi_idx, _idx_type_get(cache, cache_id_type), obj); + nm_assert(!entry + || (NMP_OBJECT_IS_VALID(entry->obj) + && NMP_OBJECT_GET_CLASS(entry->obj) == NMP_OBJECT_GET_CLASS(obj))); + return entry; +} + +static const NMDedupMultiEntry * +_lookup_entry(const NMPCache *cache, const NMPObject *obj) +{ + return _lookup_entry_with_idx_type(cache, NMP_CACHE_ID_TYPE_OBJECT_TYPE, obj); +} + +const NMDedupMultiEntry * +nmp_cache_lookup_entry_with_idx_type(const NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *obj) +{ + g_return_val_if_fail(cache, NULL); + g_return_val_if_fail(obj, NULL); + g_return_val_if_fail(cache_id_type > NMP_CACHE_ID_TYPE_NONE + && cache_id_type <= NMP_CACHE_ID_TYPE_MAX, + NULL); + + return _lookup_entry_with_idx_type(cache, cache_id_type, obj); +} + +const NMDedupMultiEntry * +nmp_cache_lookup_entry(const NMPCache *cache, const NMPObject *obj) +{ + g_return_val_if_fail(cache, NULL); + g_return_val_if_fail(obj, NULL); + + return _lookup_entry(cache, obj); +} + +const NMDedupMultiEntry * +nmp_cache_lookup_entry_link(const NMPCache *cache, int ifindex) +{ + NMPObject obj_needle; + + g_return_val_if_fail(cache, NULL); + g_return_val_if_fail(ifindex > 0, NULL); + + nmp_object_stackinit_id_link(&obj_needle, ifindex); + return _lookup_entry(cache, &obj_needle); +} + +const NMPObject * +nmp_cache_lookup_obj(const NMPCache *cache, const NMPObject *obj) +{ + return nm_dedup_multi_entry_get_obj(nmp_cache_lookup_entry(cache, obj)); +} + +const NMPObject * +nmp_cache_lookup_link(const NMPCache *cache, int ifindex) +{ + return nm_dedup_multi_entry_get_obj(nmp_cache_lookup_entry_link(cache, ifindex)); +} + +/*****************************************************************************/ + +const NMDedupMultiHeadEntry * +nmp_cache_lookup_all(const NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *select_obj) +{ + nm_assert(cache); + nm_assert(NMP_OBJECT_IS_VALID(select_obj)); + + return nm_dedup_multi_index_lookup_head(cache->multi_idx, + _idx_type_get(cache, cache_id_type), + select_obj); +} + +static const NMPLookup * +_L(const NMPLookup *lookup) +{ +#if NM_MORE_ASSERTS + DedupMultiIdxType idx_type; + + nm_assert(lookup); + _dedup_multi_idx_type_init(&idx_type, lookup->cache_id_type); + nm_assert( + idx_type.parent.klass->idx_obj_partitionable((NMDedupMultiIdxType *) &idx_type, + (NMDedupMultiObj *) &lookup->selector_obj)); +#endif + return lookup; +} + +const NMPLookup * +nmp_lookup_init_obj_type(NMPLookup *lookup, NMPObjectType obj_type) +{ + nm_assert(lookup); + + switch (obj_type) { + case NMP_OBJECT_TYPE_LINK: + case NMP_OBJECT_TYPE_IP4_ADDRESS: + case NMP_OBJECT_TYPE_IP6_ADDRESS: + case NMP_OBJECT_TYPE_IP4_ROUTE: + case NMP_OBJECT_TYPE_IP6_ROUTE: + case NMP_OBJECT_TYPE_ROUTING_RULE: + case NMP_OBJECT_TYPE_QDISC: + case NMP_OBJECT_TYPE_TFILTER: + _nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type); + lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_TYPE; + return _L(lookup); + default: + nm_assert_not_reached(); + return NULL; + } +} + +const NMPLookup * +nmp_lookup_init_link_by_ifname(NMPLookup *lookup, const char *ifname) +{ + NMPObject *o; + + nm_assert(lookup); + nm_assert(ifname); + nm_assert(strlen(ifname) < IFNAMSIZ); + + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, NMP_OBJECT_TYPE_LINK); + if (g_strlcpy(o->link.name, ifname, sizeof(o->link.name)) >= sizeof(o->link.name)) + g_return_val_if_reached(NULL); + lookup->cache_id_type = NMP_CACHE_ID_TYPE_LINK_BY_IFNAME; + return _L(lookup); +} + +const NMPLookup * +nmp_lookup_init_object(NMPLookup *lookup, NMPObjectType obj_type, int ifindex) +{ + NMPObject *o; + + nm_assert(lookup); + nm_assert(NM_IN_SET(obj_type, + NMP_OBJECT_TYPE_IP4_ADDRESS, + NMP_OBJECT_TYPE_IP6_ADDRESS, + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE, + NMP_OBJECT_TYPE_QDISC, + NMP_OBJECT_TYPE_TFILTER)); + + if (ifindex <= 0) { + return nmp_lookup_init_obj_type(lookup, obj_type); + } + + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type); + o->obj_with_ifindex.ifindex = ifindex; + lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX; + return _L(lookup); +} + +const NMPLookup * +nmp_lookup_init_route_default(NMPLookup *lookup, NMPObjectType obj_type) +{ + NMPObject *o; + + nm_assert(lookup); + nm_assert(NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); + + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type); + o->ip_route.ifindex = 1; + lookup->cache_id_type = NMP_CACHE_ID_TYPE_DEFAULT_ROUTES; + return _L(lookup); +} + +const NMPLookup * +nmp_lookup_init_route_by_weak_id(NMPLookup *lookup, const NMPObject *obj) +{ + const NMPlatformIP4Route *r4; + const NMPlatformIP6Route *r6; + + nm_assert(lookup); + + switch (NMP_OBJECT_GET_TYPE(obj)) { + case NMP_OBJECT_TYPE_IP4_ROUTE: + r4 = NMP_OBJECT_CAST_IP4_ROUTE(obj); + return nmp_lookup_init_ip4_route_by_weak_id(lookup, + r4->network, + r4->plen, + r4->metric, + r4->tos); + case NMP_OBJECT_TYPE_IP6_ROUTE: + r6 = NMP_OBJECT_CAST_IP6_ROUTE(obj); + return nmp_lookup_init_ip6_route_by_weak_id(lookup, + &r6->network, + r6->plen, + r6->metric, + &r6->src, + r6->src_plen); + default: + nm_assert_not_reached(); + return NULL; + } +} + +const NMPLookup * +nmp_lookup_init_ip4_route_by_weak_id(NMPLookup *lookup, + in_addr_t network, + guint plen, + guint32 metric, + guint8 tos) +{ + NMPObject *o; + + nm_assert(lookup); + + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, NMP_OBJECT_TYPE_IP4_ROUTE); + o->ip4_route.ifindex = 1; + o->ip4_route.plen = plen; + o->ip4_route.metric = metric; + if (network) + o->ip4_route.network = network; + o->ip4_route.tos = tos; + lookup->cache_id_type = NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID; + return _L(lookup); +} + +const NMPLookup * +nmp_lookup_init_ip6_route_by_weak_id(NMPLookup * lookup, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen) +{ + NMPObject *o; + + nm_assert(lookup); + + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, NMP_OBJECT_TYPE_IP6_ROUTE); + o->ip6_route.ifindex = 1; + o->ip6_route.plen = plen; + o->ip6_route.metric = metric; + if (network) + o->ip6_route.network = *network; + if (src) + o->ip6_route.src = *src; + o->ip6_route.src_plen = src_plen; + lookup->cache_id_type = NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID; + return _L(lookup); +} + +const NMPLookup * +nmp_lookup_init_object_by_addr_family(NMPLookup *lookup, NMPObjectType obj_type, int addr_family) +{ + NMPObject *o; + + nm_assert(lookup); + nm_assert(NM_IN_SET(obj_type, NMP_OBJECT_TYPE_ROUTING_RULE)); + + if (addr_family == AF_UNSPEC) + return nmp_lookup_init_obj_type(lookup, obj_type); + + nm_assert_addr_family(addr_family); + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type); + NMP_OBJECT_CAST_ROUTING_RULE(o)->addr_family = addr_family; + lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY; + return _L(lookup); +} + +/*****************************************************************************/ + +GArray * +nmp_cache_lookup_to_array(const NMDedupMultiHeadEntry *head_entry, + NMPObjectType obj_type, + gboolean visible_only) +{ + const NMPClass * klass = nmp_class_from_type(obj_type); + NMDedupMultiIter iter; + const NMPObject *o; + GArray * array; + + g_return_val_if_fail(klass, NULL); + + array = g_array_sized_new(FALSE, FALSE, klass->sizeof_public, head_entry ? head_entry->len : 0); + nmp_cache_iter_for_each (&iter, head_entry, &o) { + nm_assert(NMP_OBJECT_GET_CLASS(o) == klass); + if (visible_only && !nmp_object_is_visible(o)) + continue; + g_array_append_vals(array, &o->object, 1); + } + return array; +} + +/*****************************************************************************/ + +const NMPObject * +nmp_cache_lookup_link_full(const NMPCache * cache, + int ifindex, + const char * ifname, + gboolean visible_only, + NMLinkType link_type, + NMPObjectMatchFn match_fn, + gpointer user_data) +{ + NMPObject obj_needle; + const NMPObject * obj; + NMDedupMultiIter iter; + const NMDedupMultiHeadEntry *head_entry; + const NMPlatformLink * link = NULL; + NMPLookup lookup; + + if (ifindex > 0) { + obj = nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&obj_needle, ifindex)); + + if (!obj || (visible_only && !nmp_object_is_visible(obj)) + || (link_type != NM_LINK_TYPE_NONE && obj->link.type != link_type) + || (ifname && strcmp(obj->link.name, ifname)) + || (match_fn && !match_fn(obj, user_data))) + return NULL; + return obj; + } else if (!ifname && !match_fn) + return NULL; + else { + const NMPObject *obj_best = NULL; + + if (ifname) { + if (strlen(ifname) >= IFNAMSIZ) + return NULL; + nmp_lookup_init_link_by_ifname(&lookup, ifname); + } else + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK); + + head_entry = nmp_cache_lookup(cache, &lookup); + nmp_cache_iter_for_each_link (&iter, head_entry, &link) { + obj = NMP_OBJECT_UP_CAST(link); + + if (link_type != NM_LINK_TYPE_NONE && obj->link.type != link_type) + continue; + if (visible_only && !nmp_object_is_visible(obj)) + continue; + if (match_fn && !match_fn(obj, user_data)) + continue; + + /* if there are multiple candidates, prefer the visible ones. */ + if (visible_only || nmp_object_is_visible(obj)) + return obj; + if (!obj_best) + obj_best = obj; + } + return obj_best; + } +} + +/*****************************************************************************/ + +static NMDedupMultiIdxMode +_obj_get_add_mode(const NMPObject *obj) +{ + /* new objects are usually appended to the list. Except for + * addresses, which are prepended during `ip address add`. + * + * Actually, for routes it is more complicated, because depending on + * `ip route append`, `ip route replace`, `ip route prepend`, the object + * will be added at the tail, at the front, or even replace an element + * in the list. However, that is handled separately by nmp_cache_update_netlink_route() + * and of no concern here. */ + if (NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), + NMP_OBJECT_TYPE_IP4_ADDRESS, + NMP_OBJECT_TYPE_IP6_ADDRESS)) + return NM_DEDUP_MULTI_IDX_MODE_PREPEND; + return NM_DEDUP_MULTI_IDX_MODE_APPEND; +} + +static void +_idxcache_update_order_for_dump(NMPCache *cache, const NMDedupMultiEntry *entry) +{ + const NMPClass * klass; + const guint8 * i_idx_type; + const NMDedupMultiEntry *entry2; + + nm_dedup_multi_entry_reorder(entry, NULL, TRUE); + + klass = NMP_OBJECT_GET_CLASS(entry->obj); + for (i_idx_type = klass->supported_cache_ids; *i_idx_type; i_idx_type++) { + NMPCacheIdType id_type = *i_idx_type; + + if (id_type == NMP_CACHE_ID_TYPE_OBJECT_TYPE) + continue; + + entry2 = nm_dedup_multi_index_lookup_obj(cache->multi_idx, + _idx_type_get(cache, id_type), + entry->obj); + if (!entry2) + continue; + + nm_assert(entry2 != entry); + nm_assert(entry2->obj == entry->obj); + + nm_dedup_multi_entry_reorder(entry2, NULL, TRUE); + } +} + +static void +_idxcache_update_other_cache_ids(NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *obj_old, + const NMPObject *obj_new, + gboolean is_dump) +{ + const NMDedupMultiEntry *entry_new; + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_order; + NMDedupMultiIdxType * idx_type; + + nm_assert(obj_new || obj_old); + nm_assert(!obj_new || NMP_OBJECT_GET_TYPE(obj_new) != NMP_OBJECT_TYPE_UNKNOWN); + nm_assert(!obj_old || NMP_OBJECT_GET_TYPE(obj_old) != NMP_OBJECT_TYPE_UNKNOWN); + nm_assert(!obj_old || !obj_new + || NMP_OBJECT_GET_CLASS(obj_new) == NMP_OBJECT_GET_CLASS(obj_old)); + nm_assert(!obj_old || !obj_new || !nmp_object_equal(obj_new, obj_old)); + nm_assert(!obj_new || obj_new == nm_dedup_multi_index_obj_find(cache->multi_idx, obj_new)); + nm_assert(!obj_old || obj_old == nm_dedup_multi_index_obj_find(cache->multi_idx, obj_old)); + + idx_type = _idx_type_get(cache, cache_id_type); + + if (obj_old) { + entry_old = nm_dedup_multi_index_lookup_obj(cache->multi_idx, idx_type, obj_old); + if (!obj_new) { + if (entry_old) + nm_dedup_multi_index_remove_entry(cache->multi_idx, entry_old); + return; + } + } else + entry_old = NULL; + + if (obj_new) { + if (obj_old && nm_dedup_multi_idx_type_id_equal(idx_type, obj_old, obj_new) + && nm_dedup_multi_idx_type_partition_equal(idx_type, obj_old, obj_new)) { + /* optimize. We just looked up the @obj_old entry and @obj_new compares equal + * according to idx_obj_id_equal(). entry_new is the same as entry_old. */ + entry_new = entry_old; + } else { + entry_new = nm_dedup_multi_index_lookup_obj(cache->multi_idx, idx_type, obj_new); + } + + if (entry_new) + entry_order = entry_new; + else if (entry_old + && nm_dedup_multi_idx_type_partition_equal(idx_type, entry_old->obj, obj_new)) + entry_order = entry_old; + else + entry_order = NULL; + nm_dedup_multi_index_add_full( + cache->multi_idx, + idx_type, + obj_new, + is_dump ? NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE : _obj_get_add_mode(obj_new), + is_dump ? NULL : entry_order, + entry_new ?: NM_DEDUP_MULTI_ENTRY_MISSING, + entry_new ? entry_new->head : (entry_order ? entry_order->head : NULL), + &entry_new, + NULL); + +#if NM_MORE_ASSERTS + if (entry_new) { + nm_assert(idx_type->klass->idx_obj_partitionable); + nm_assert(idx_type->klass->idx_obj_partition_equal); + nm_assert(idx_type->klass->idx_obj_partitionable(idx_type, entry_new->obj)); + nm_assert(idx_type->klass->idx_obj_partition_equal(idx_type, + (gpointer) obj_new, + entry_new->obj)); + } +#endif + } else + entry_new = NULL; + + if (entry_old && entry_old != entry_new) + nm_dedup_multi_index_remove_entry(cache->multi_idx, entry_old); +} + +static void +_idxcache_update(NMPCache * cache, + const NMDedupMultiEntry * entry_old, + NMPObject * obj_new, + gboolean is_dump, + const NMDedupMultiEntry **out_entry_new) +{ + const NMPClass * klass; + const guint8 * i_idx_type; + NMDedupMultiIdxType * idx_type_o = _idx_type_get(cache, NMP_CACHE_ID_TYPE_OBJECT_TYPE); + const NMDedupMultiEntry *entry_new = NULL; + nm_auto_nmpobj const NMPObject *obj_old = NULL; + + /* we update an object in the cache. + * + * Note that @entry_old MUST be what is currently tracked in multi_idx, and it must + * have the same ID as @obj_new. */ + + nm_assert(cache); + nm_assert(entry_old || obj_new); + nm_assert(!obj_new || nmp_object_is_alive(obj_new)); + nm_assert( + !entry_old + || entry_old + == nm_dedup_multi_index_lookup_obj(cache->multi_idx, idx_type_o, entry_old->obj)); + nm_assert(!obj_new + || entry_old + == nm_dedup_multi_index_lookup_obj(cache->multi_idx, idx_type_o, obj_new)); + nm_assert(!entry_old || entry_old->head->idx_type == idx_type_o); + nm_assert(!entry_old || !obj_new + || nm_dedup_multi_idx_type_partition_equal(idx_type_o, entry_old->obj, obj_new)); + nm_assert(!entry_old || !obj_new + || nm_dedup_multi_idx_type_id_equal(idx_type_o, entry_old->obj, obj_new)); + nm_assert(!entry_old || !obj_new + || (obj_new->parent.klass == ((const NMPObject *) entry_old->obj)->parent.klass + && !obj_new->parent.klass->obj_full_equal((NMDedupMultiObj *) obj_new, + entry_old->obj))); + + /* keep a reference to the pre-existing entry */ + if (entry_old) + obj_old = nmp_object_ref(entry_old->obj); + + /* first update the main index NMP_CACHE_ID_TYPE_OBJECT_TYPE. + * We already know the pre-existing @entry old, so all that + * nm_dedup_multi_index_add_full() effectively does, is update the + * obj reference. + * + * We also get the new boxed object, which we need below. */ + if (obj_new) { + nm_auto_nmpobj NMPObject *obj_old2 = NULL; + + nm_dedup_multi_index_add_full(cache->multi_idx, + idx_type_o, + obj_new, + is_dump ? NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE + : _obj_get_add_mode(obj_new), + NULL, + entry_old ?: NM_DEDUP_MULTI_ENTRY_MISSING, + NULL, + &entry_new, + (const NMDedupMultiObj **) &obj_old2); + nm_assert(entry_new); + nm_assert(obj_old == obj_old2); + nm_assert(!entry_old || entry_old == entry_new); + } else + nm_dedup_multi_index_remove_entry(cache->multi_idx, entry_old); + + /* now update all other indexes. We know the previously boxed entry, and the + * newly boxed one. */ + klass = NMP_OBJECT_GET_CLASS(entry_new ? entry_new->obj : obj_old); + for (i_idx_type = klass->supported_cache_ids; *i_idx_type; i_idx_type++) { + NMPCacheIdType id_type = *i_idx_type; + + if (id_type == NMP_CACHE_ID_TYPE_OBJECT_TYPE) + continue; + _idxcache_update_other_cache_ids(cache, + id_type, + obj_old, + entry_new ? entry_new->obj : NULL, + is_dump); + } + + NM_SET_OUT(out_entry_new, entry_new); +} + +NMPCacheOpsType +nmp_cache_remove(NMPCache * cache, + const NMPObject * obj_needle, + gboolean equals_by_ptr, + gboolean only_dirty, + const NMPObject **out_obj_old) +{ + const NMDedupMultiEntry *entry_old; + const NMPObject * obj_old; + + entry_old = _lookup_entry(cache, obj_needle); + + if (!entry_old) { + NM_SET_OUT(out_obj_old, NULL); + return NMP_CACHE_OPS_UNCHANGED; + } + + obj_old = entry_old->obj; + + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + + if (equals_by_ptr && obj_old != obj_needle) { + /* We found an identical object, but we only delete it if it's the same pointer as + * @obj_needle. */ + return NMP_CACHE_OPS_UNCHANGED; + } + if (only_dirty && !entry_old->dirty) { + /* the entry is not dirty. Skip. */ + return NMP_CACHE_OPS_UNCHANGED; + } + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + return NMP_CACHE_OPS_REMOVED; +} + +NMPCacheOpsType +nmp_cache_remove_netlink(NMPCache * cache, + const NMPObject * obj_needle, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new) +{ + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new = NULL; + const NMPObject * obj_old; + nm_auto_nmpobj NMPObject *obj_new = NULL; + + entry_old = _lookup_entry(cache, obj_needle); + + if (!entry_old) { + NM_SET_OUT(out_obj_old, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_UNCHANGED; + } + + obj_old = entry_old->obj; + + if (NMP_OBJECT_GET_TYPE(obj_needle) == NMP_OBJECT_TYPE_LINK) { + /* For nmp_cache_remove_netlink() we have an incomplete @obj_needle instance to be + * removed from netlink. Link objects are alive without being in netlink when they + * have a udev-device. All we want to do in this case is clear the netlink.is_in_netlink + * flag. */ + + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + + if (!obj_old->_link.netlink.is_in_netlink) { + nm_assert(obj_old->_link.udev.device); + NM_SET_OUT(out_obj_new, nmp_object_ref(obj_old)); + return NMP_CACHE_OPS_UNCHANGED; + } + + if (!obj_old->_link.udev.device) { + /* the update would make @obj_old invalid. Remove it. */ + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_REMOVED; + } + + obj_new = nmp_object_clone(obj_old, FALSE); + obj_new->_link.netlink.is_in_netlink = FALSE; + + _nmp_object_fixup_link_master_connected(&obj_new, NULL, cache); + _nmp_object_fixup_link_udev_fields(&obj_new, NULL, cache->use_udev); + + _idxcache_update(cache, entry_old, obj_new, FALSE, &entry_new); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_UPDATED; + } + + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + NM_SET_OUT(out_obj_new, NULL); + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + return NMP_CACHE_OPS_REMOVED; +} + +/** + * nmp_cache_update_netlink: + * @cache: the platform cache + * @obj_hand_over: a #NMPObject instance as received from netlink and created via + * nmp_object_from_nl(). Especially for link, it must not have the udev + * replated fields set. + * This instance will be modified and might be put into the cache. When + * calling nmp_cache_update_netlink() you hand @obj over to the cache. + * Except, that the cache will increment the ref count as appropriate. You + * must still unref the obj to release your part of the ownership. + * @is_dump: whether this update comes during a dump of object of the same kind. + * kernel dumps objects in a certain order, which matters especially for routes. + * Before a dump we mark all objects as dirty, and remove all untouched objects + * afterwards. Hence, during a dump, every update should move the object to the + * end of the list, to obtain the correct order. That means, to use NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE, + * instead of NM_DEDUP_MULTI_IDX_MODE_APPEND. + * @out_obj_old: (allow-none) (out): return the object with same ID as @obj_hand_over, + * that was in the cache before update. If an object is returned, the caller must + * unref it afterwards. + * @out_obj_new: (allow-none) (out): return the object from the cache after update. + * The caller must unref this object. + * + * Returns: how the cache changed. + * + * Even if there was no change in the cache (NMP_CACHE_OPS_UNCHANGED), @out_obj_old + * and @out_obj_new will be set accordingly. + **/ +NMPCacheOpsType +nmp_cache_update_netlink(NMPCache * cache, + NMPObject * obj_hand_over, + gboolean is_dump, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new) +{ + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new; + const NMPObject * obj_old; + gboolean is_alive; + + nm_assert(cache); + nm_assert(NMP_OBJECT_IS_VALID(obj_hand_over)); + nm_assert(!NMP_OBJECT_IS_STACKINIT(obj_hand_over)); + /* A link object from netlink must have the udev related fields unset. + * We could implement to handle that, but there is no need to support such + * a use-case */ + nm_assert(NMP_OBJECT_GET_TYPE(obj_hand_over) != NMP_OBJECT_TYPE_LINK + || (!obj_hand_over->_link.udev.device && !obj_hand_over->link.driver)); + nm_assert(nm_dedup_multi_index_obj_find(cache->multi_idx, obj_hand_over) != obj_hand_over); + + entry_old = _lookup_entry(cache, obj_hand_over); + + if (!entry_old) { + NM_SET_OUT(out_obj_old, NULL); + + if (!nmp_object_is_alive(obj_hand_over)) { + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_UNCHANGED; + } + + if (NMP_OBJECT_GET_TYPE(obj_hand_over) == NMP_OBJECT_TYPE_LINK) { + _nmp_object_fixup_link_master_connected(&obj_hand_over, NULL, cache); + _nmp_object_fixup_link_udev_fields(&obj_hand_over, NULL, cache->use_udev); + } + + _idxcache_update(cache, entry_old, obj_hand_over, is_dump, &entry_new); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_ADDED; + } + + obj_old = entry_old->obj; + + if (NMP_OBJECT_GET_TYPE(obj_hand_over) == NMP_OBJECT_TYPE_LINK) { + if (!obj_hand_over->_link.netlink.is_in_netlink) { + if (!obj_old->_link.netlink.is_in_netlink) { + nm_assert(obj_old->_link.udev.device); + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + NM_SET_OUT(out_obj_new, nmp_object_ref(obj_old)); + return NMP_CACHE_OPS_UNCHANGED; + } + if (obj_old->_link.udev.device) { + /* @obj_hand_over is not in netlink. + * + * This is similar to nmp_cache_remove_netlink(), but there we preserve the + * preexisting netlink properties. The use case of that is when kernel_get_object() + * cannot load an object (based on the id of a needle). + * + * Here we keep the data provided from @obj_hand_over. The usecase is when receiving + * a valid @obj_hand_over instance from netlink with RTM_DELROUTE. + */ + is_alive = TRUE; + } else + is_alive = FALSE; + } else + is_alive = TRUE; + + if (is_alive) { + _nmp_object_fixup_link_master_connected(&obj_hand_over, NULL, cache); + + /* Merge the netlink parts with what we have from udev. */ + udev_device_unref(obj_hand_over->_link.udev.device); + obj_hand_over->_link.udev.device = + obj_old->_link.udev.device ? udev_device_ref(obj_old->_link.udev.device) : NULL; + _nmp_object_fixup_link_udev_fields(&obj_hand_over, NULL, cache->use_udev); + + if (obj_hand_over->_link.netlink.lnk) { + nm_auto_nmpobj const NMPObject *lnk_old = obj_hand_over->_link.netlink.lnk; + + /* let's dedup/intern the lnk object. */ + obj_hand_over->_link.netlink.lnk = + nm_dedup_multi_index_obj_intern(cache->multi_idx, lnk_old); + } + } + } else + is_alive = nmp_object_is_alive(obj_hand_over); + + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + + if (!is_alive) { + /* the update would make @obj_old invalid. Remove it. */ + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_REMOVED; + } + + if (nmp_object_equal(obj_old, obj_hand_over)) { + if (is_dump) + _idxcache_update_order_for_dump(cache, entry_old); + nm_dedup_multi_entry_set_dirty(entry_old, FALSE); + NM_SET_OUT(out_obj_new, nmp_object_ref(obj_old)); + return NMP_CACHE_OPS_UNCHANGED; + } + + _idxcache_update(cache, entry_old, obj_hand_over, is_dump, &entry_new); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_UPDATED; +} + +NMPCacheOpsType +nmp_cache_update_netlink_route(NMPCache * cache, + NMPObject * obj_hand_over, + gboolean is_dump, + guint16 nlmsgflags, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new, + const NMPObject **out_obj_replace, + gboolean * out_resync_required) +{ + NMDedupMultiIter iter; + const NMDedupMultiEntry * entry_old; + const NMDedupMultiEntry * entry_new; + const NMDedupMultiEntry * entry_cur; + const NMDedupMultiEntry * entry_replace; + const NMDedupMultiHeadEntry *head_entry; + gboolean is_alive; + NMPCacheOpsType ops_type = NMP_CACHE_OPS_UNCHANGED; + gboolean resync_required; + + nm_assert(cache); + nm_assert(NMP_OBJECT_IS_VALID(obj_hand_over)); + nm_assert(!NMP_OBJECT_IS_STACKINIT(obj_hand_over)); + /* A link object from netlink must have the udev related fields unset. + * We could implement to handle that, but there is no need to support such + * a use-case */ + nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_hand_over), + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE)); + nm_assert(nm_dedup_multi_index_obj_find(cache->multi_idx, obj_hand_over) != obj_hand_over); + + entry_old = _lookup_entry(cache, obj_hand_over); + entry_new = NULL; + + NM_SET_OUT(out_obj_old, nmp_object_ref(nm_dedup_multi_entry_get_obj(entry_old))); + + if (!entry_old) { + if (!nmp_object_is_alive(obj_hand_over)) + goto update_done; + + _idxcache_update(cache, NULL, obj_hand_over, is_dump, &entry_new); + ops_type = NMP_CACHE_OPS_ADDED; + goto update_done; + } + + is_alive = nmp_object_is_alive(obj_hand_over); + + if (!is_alive) { + /* the update would make @entry_old invalid. Remove it. */ + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + ops_type = NMP_CACHE_OPS_REMOVED; + goto update_done; + } + + if (nmp_object_equal(entry_old->obj, obj_hand_over)) { + if (is_dump) + _idxcache_update_order_for_dump(cache, entry_old); + nm_dedup_multi_entry_set_dirty(entry_old, FALSE); + goto update_done; + } + + _idxcache_update(cache, entry_old, obj_hand_over, is_dump, &entry_new); + ops_type = NMP_CACHE_OPS_UPDATED; + +update_done: + NM_SET_OUT(out_obj_new, nmp_object_ref(nm_dedup_multi_entry_get_obj(entry_new))); + + /* a RTM_GETROUTE event may signal that another object was replaced. + * Find out whether that is the case and return it as @obj_replaced. + * + * Also, fixup the order of @entry_new within NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID + * index. For most parts, we don't care about the order of objects (including routes). + * But NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID we must keep in the correct order, to + * properly find @obj_replaced. */ + resync_required = FALSE; + entry_replace = NULL; + if (is_dump) + goto out; + + if (!entry_new) { + if (NM_FLAGS_HAS(nlmsgflags, NLM_F_REPLACE) + && nmp_cache_lookup_all(cache, NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, obj_hand_over)) { + /* hm. @obj_hand_over was not added, meaning it was not alive. + * However, we track some other objects with the same weak-id. + * It's unclear what that means. To be sure, resync. */ + resync_required = TRUE; + } + goto out; + } + + /* FIXME: for routes, we only maintain the order correctly for the BY_WEAK_ID + * index. For all other indexes their order becomes messed up. */ + entry_cur = + _lookup_entry_with_idx_type(cache, NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, entry_new->obj); + if (!entry_cur) { + nm_assert_not_reached(); + goto out; + } + nm_assert(entry_cur->obj == entry_new->obj); + + head_entry = entry_cur->head; + nm_assert(head_entry + == nmp_cache_lookup_all(cache, NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, entry_cur->obj)); + + if (head_entry->len == 1) { + /* there is only one object, and we expect it to be @obj_new. */ + nm_assert(nm_dedup_multi_head_entry_get_idx(head_entry, 0) == entry_cur); + goto out; + } + + switch (nlmsgflags & (NLM_F_REPLACE | NLM_F_EXCL | NLM_F_CREATE | NLM_F_APPEND)) { + case NLM_F_REPLACE: + /* ip route change */ + + /* get the first element (but skip @obj_new). */ + nm_dedup_multi_iter_init(&iter, head_entry); + if (!nm_dedup_multi_iter_next(&iter)) + nm_assert_not_reached(); + if (iter.current == entry_cur) { + if (!nm_dedup_multi_iter_next(&iter)) + nm_assert_not_reached(); + } + entry_replace = iter.current; + + nm_assert(entry_replace && entry_cur != entry_replace); + + nm_dedup_multi_entry_reorder(entry_cur, entry_replace, FALSE); + break; + case NLM_F_CREATE | NLM_F_APPEND: + /* ip route append */ + nm_dedup_multi_entry_reorder(entry_cur, NULL, TRUE); + break; + case NLM_F_CREATE: + /* ip route prepend */ + nm_dedup_multi_entry_reorder(entry_cur, NULL, FALSE); + break; + default: + /* this is an unexpected case, probably a bug that we need to handle better. */ + resync_required = TRUE; + break; + } + +out: + NM_SET_OUT(out_obj_replace, nmp_object_ref(nm_dedup_multi_entry_get_obj(entry_replace))); + NM_SET_OUT(out_resync_required, resync_required); + return ops_type; +} + +NMPCacheOpsType +nmp_cache_update_link_udev(NMPCache * cache, + int ifindex, + struct udev_device *udevice, + const NMPObject ** out_obj_old, + const NMPObject ** out_obj_new) +{ + const NMPObject *obj_old; + nm_auto_nmpobj NMPObject *obj_new = NULL; + const NMDedupMultiEntry * entry_old; + const NMDedupMultiEntry * entry_new; + + entry_old = nmp_cache_lookup_entry_link(cache, ifindex); + + if (!entry_old) { + if (!udevice) { + NM_SET_OUT(out_obj_old, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_UNCHANGED; + } + + obj_new = nmp_object_new(NMP_OBJECT_TYPE_LINK, NULL); + obj_new->link.ifindex = ifindex; + obj_new->_link.udev.device = udev_device_ref(udevice); + + _nmp_object_fixup_link_udev_fields(&obj_new, NULL, cache->use_udev); + + _idxcache_update(cache, NULL, obj_new, FALSE, &entry_new); + NM_SET_OUT(out_obj_old, NULL); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_ADDED; + } else { + obj_old = entry_old->obj; + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + + if (obj_old->_link.udev.device == udevice) { + NM_SET_OUT(out_obj_new, nmp_object_ref(obj_old)); + return NMP_CACHE_OPS_UNCHANGED; + } + + if (!udevice && !obj_old->_link.netlink.is_in_netlink) { + /* the update would make @obj_old invalid. Remove it. */ + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_REMOVED; + } + + obj_new = nmp_object_clone(obj_old, FALSE); + + udev_device_unref(obj_new->_link.udev.device); + obj_new->_link.udev.device = udevice ? udev_device_ref(udevice) : NULL; + + _nmp_object_fixup_link_udev_fields(&obj_new, NULL, cache->use_udev); + + _idxcache_update(cache, entry_old, obj_new, FALSE, &entry_new); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_UPDATED; + } +} + +NMPCacheOpsType +nmp_cache_update_link_master_connected(NMPCache * cache, + int ifindex, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new) +{ + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new = NULL; + const NMPObject * obj_old; + nm_auto_nmpobj NMPObject *obj_new = NULL; + + entry_old = nmp_cache_lookup_entry_link(cache, ifindex); + + if (!entry_old) { + NM_SET_OUT(out_obj_old, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_UNCHANGED; + } + + obj_old = entry_old->obj; + + if (!nmp_cache_link_connected_needs_toggle(cache, obj_old, NULL, NULL)) { + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + NM_SET_OUT(out_obj_new, nmp_object_ref(obj_old)); + return NMP_CACHE_OPS_UNCHANGED; + } + + obj_new = nmp_object_clone(obj_old, FALSE); + obj_new->link.connected = !obj_old->link.connected; + + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + _idxcache_update(cache, entry_old, obj_new, FALSE, &entry_new); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_UPDATED; +} + +/*****************************************************************************/ + +void +nmp_cache_dirty_set_all_main(NMPCache *cache, const NMPLookup *lookup) +{ + const NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIter iter; + + nm_assert(cache); + nm_assert(lookup); + + head_entry = nmp_cache_lookup(cache, lookup); + + nm_dedup_multi_iter_init(&iter, head_entry); + while (nm_dedup_multi_iter_next(&iter)) { + const NMDedupMultiEntry *main_entry; + + main_entry = nmp_cache_reresolve_main_entry(cache, iter.current, lookup); + + nm_dedup_multi_entry_set_dirty(main_entry, TRUE); + } +} + +/*****************************************************************************/ + +NMPCache * +nmp_cache_new(NMDedupMultiIndex *multi_idx, gboolean use_udev) +{ + NMPCache *cache = g_slice_new0(NMPCache); + guint i; + + for (i = NMP_CACHE_ID_TYPE_NONE + 1; i <= NMP_CACHE_ID_TYPE_MAX; i++) + _dedup_multi_idx_type_init((DedupMultiIdxType *) _idx_type_get(cache, i), i); + + cache->multi_idx = nm_dedup_multi_index_ref(multi_idx); + + cache->use_udev = !!use_udev; + return cache; +} + +void +nmp_cache_free(NMPCache *cache) +{ + guint i; + + for (i = NMP_CACHE_ID_TYPE_NONE + 1; i <= NMP_CACHE_ID_TYPE_MAX; i++) + nm_dedup_multi_index_remove_idx(cache->multi_idx, _idx_type_get(cache, i)); + + nm_dedup_multi_index_unref(cache->multi_idx); + + g_slice_free(NMPCache, cache); +} + +/*****************************************************************************/ + +void +nmtst_assert_nmp_cache_is_consistent(const NMPCache *cache) +{} + +/*****************************************************************************/ + +/* below, ensure that addr_family get's automatically initialize to AF_UNSPEC. */ +G_STATIC_ASSERT(AF_UNSPEC == 0); + +typedef const char *(*CmdPlobjToStringFunc)(const NMPlatformObject *obj, char *buf, gsize len); +typedef const char *(*CmdPlobjToStringIdFunc)(const NMPlatformObject *obj, char *buf, gsize len); +typedef void (*CmdPlobjHashUpdateFunc)(const NMPlatformObject *obj, NMHashState *h); +typedef int (*CmdPlobjCmpFunc)(const NMPlatformObject *obj1, const NMPlatformObject *obj2); + +const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { + [NMP_OBJECT_TYPE_LINK - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LINK, + .sizeof_data = sizeof(NMPObjectLink), + .sizeof_public = sizeof(NMPlatformLink), + .obj_type_name = "link", + .rtm_gettype = RTM_GETLINK, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_LINK, + .signal_type = NM_PLATFORM_SIGNAL_LINK_CHANGED, + .supported_cache_ids = _supported_cache_ids_link, + .cmd_obj_hash_update = _vt_cmd_obj_hash_update_link, + .cmd_obj_cmp = _vt_cmd_obj_cmp_link, + .cmd_obj_copy = _vt_cmd_obj_copy_link, + .cmd_obj_dispose = _vt_cmd_obj_dispose_link, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_link, + .cmd_obj_is_visible = _vt_cmd_obj_is_visible_link, + .cmd_obj_to_string = _vt_cmd_obj_to_string_link, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_link, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_link, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_link, + .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_link, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_link_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_link_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_link_cmp, + }, + [NMP_OBJECT_TYPE_IP4_ADDRESS - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_IP4_ADDRESS, + .sizeof_data = sizeof(NMPObjectIP4Address), + .sizeof_public = sizeof(NMPlatformIP4Address), + .obj_type_name = "ip4-address", + .addr_family = AF_INET, + .rtm_gettype = RTM_GETADDR, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP4_ADDRESS, + .signal_type = NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + .supported_cache_ids = _supported_cache_ids_ipx_address, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_address, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip4_address, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip4_address, + .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip4_address, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_ip4_address_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_ip4_address_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_ip4_address_cmp, + }, + [NMP_OBJECT_TYPE_IP6_ADDRESS + - 1] = {.parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_IP6_ADDRESS, + .sizeof_data = sizeof(NMPObjectIP6Address), + .sizeof_public = sizeof(NMPlatformIP6Address), + .obj_type_name = "ip6-address", + .addr_family = AF_INET6, + .rtm_gettype = RTM_GETADDR, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS, + .signal_type = NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + .supported_cache_ids = _supported_cache_ids_ipx_address, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_address, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip6_address, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_address, + .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip6_address, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_ip6_address_to_string, + .cmd_plobj_hash_update = + (CmdPlobjHashUpdateFunc) nm_platform_ip6_address_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_ip6_address_cmp}, + [NMP_OBJECT_TYPE_IP4_ROUTE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_IP4_ROUTE, + .sizeof_data = sizeof(NMPObjectIP4Route), + .sizeof_public = sizeof(NMPlatformIP4Route), + .obj_type_name = "ip4-route", + .addr_family = AF_INET, + .rtm_gettype = RTM_GETROUTE, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP4_ROUTE, + .signal_type = NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, + .supported_cache_ids = _supported_cache_ids_ipx_route, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_route, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip4_route, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip4_route, + .cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_ip4_route_to_string, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_ip4_route_to_string, + .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_ip4_route, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_ip4_route_cmp_full, + }, + [NMP_OBJECT_TYPE_IP6_ROUTE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_IP6_ROUTE, + .sizeof_data = sizeof(NMPObjectIP6Route), + .sizeof_public = sizeof(NMPlatformIP6Route), + .obj_type_name = "ip6-route", + .addr_family = AF_INET6, + .rtm_gettype = RTM_GETROUTE, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP6_ROUTE, + .signal_type = NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, + .supported_cache_ids = _supported_cache_ids_ipx_route, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_route, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip6_route, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_route, + .cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_ip6_route_to_string, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_ip6_route_to_string, + .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_ip6_route, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_ip6_route_cmp_full, + }, + [NMP_OBJECT_TYPE_ROUTING_RULE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_ROUTING_RULE, + .sizeof_data = sizeof(NMPObjectRoutingRule), + .sizeof_public = sizeof(NMPlatformRoutingRule), + .obj_type_name = "routing-rule", + .rtm_gettype = RTM_GETRULE, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_ROUTING_RULE, + .signal_type = NM_PLATFORM_SIGNAL_ROUTING_RULE_CHANGED, + .supported_cache_ids = _supported_cache_ids_routing_rules, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_routing_rule, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_routing_rule, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_routing_rule, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_routing_rule, + .cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_routing_rule_to_string, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_routing_rule_to_string, + .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_routing_rule, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_routing_rule_cmp_full, + }, + [NMP_OBJECT_TYPE_QDISC - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_QDISC, + .sizeof_data = sizeof(NMPObjectQdisc), + .sizeof_public = sizeof(NMPlatformQdisc), + .obj_type_name = "qdisc", + .rtm_gettype = RTM_GETQDISC, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_QDISC, + .signal_type = NM_PLATFORM_SIGNAL_QDISC_CHANGED, + .supported_cache_ids = _supported_cache_ids_object, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_qdisc, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_qdisc, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_qdisc, + .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_qdisc, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_qdisc_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_qdisc_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_qdisc_cmp, + }, + [NMP_OBJECT_TYPE_TFILTER - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_TFILTER, + .sizeof_data = sizeof(NMPObjectTfilter), + .sizeof_public = sizeof(NMPlatformTfilter), + .obj_type_name = "tfilter", + .rtm_gettype = RTM_GETTFILTER, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_TFILTER, + .signal_type = NM_PLATFORM_SIGNAL_TFILTER_CHANGED, + .supported_cache_ids = _supported_cache_ids_object, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_tfilter, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_tfilter, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_tfilter, + .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_tfilter, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_tfilter_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_tfilter_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_tfilter_cmp, + }, + [NMP_OBJECT_TYPE_LNK_BRIDGE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_BRIDGE, + .sizeof_data = sizeof(NMPObjectLnkBridge), + .sizeof_public = sizeof(NMPlatformLnkBridge), + .obj_type_name = "bridge", + .lnk_link_type = NM_LINK_TYPE_BRIDGE, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_bridge_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_bridge_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_bridge_cmp, + }, + [NMP_OBJECT_TYPE_LNK_GRE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_GRE, + .sizeof_data = sizeof(NMPObjectLnkGre), + .sizeof_public = sizeof(NMPlatformLnkGre), + .obj_type_name = "gre", + .lnk_link_type = NM_LINK_TYPE_GRE, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_gre_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_gre_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_gre_cmp, + }, + [NMP_OBJECT_TYPE_LNK_GRETAP - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_GRETAP, + .sizeof_data = sizeof(NMPObjectLnkGre), + .sizeof_public = sizeof(NMPlatformLnkGre), + .obj_type_name = "gretap", + .lnk_link_type = NM_LINK_TYPE_GRETAP, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_gre_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_gre_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_gre_cmp, + }, + [NMP_OBJECT_TYPE_LNK_INFINIBAND - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_INFINIBAND, + .sizeof_data = sizeof(NMPObjectLnkInfiniband), + .sizeof_public = sizeof(NMPlatformLnkInfiniband), + .obj_type_name = "infiniband", + .lnk_link_type = NM_LINK_TYPE_INFINIBAND, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_infiniband_to_string, + .cmd_plobj_hash_update = + (CmdPlobjHashUpdateFunc) nm_platform_lnk_infiniband_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_infiniband_cmp, + }, + [NMP_OBJECT_TYPE_LNK_IP6TNL - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_IP6TNL, + .sizeof_data = sizeof(NMPObjectLnkIp6Tnl), + .sizeof_public = sizeof(NMPlatformLnkIp6Tnl), + .obj_type_name = "ip6tnl", + .lnk_link_type = NM_LINK_TYPE_IP6TNL, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_ip6tnl_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_ip6tnl_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_ip6tnl_cmp, + }, + [NMP_OBJECT_TYPE_LNK_IP6GRE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_IP6GRE, + .sizeof_data = sizeof(NMPObjectLnkIp6Tnl), + .sizeof_public = sizeof(NMPlatformLnkIp6Tnl), + .obj_type_name = "ip6gre", + .lnk_link_type = NM_LINK_TYPE_IP6GRE, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_ip6tnl_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_ip6tnl_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_ip6tnl_cmp, + }, + [NMP_OBJECT_TYPE_LNK_IP6GRETAP - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_IP6GRETAP, + .sizeof_data = sizeof(NMPObjectLnkIp6Tnl), + .sizeof_public = sizeof(NMPlatformLnkIp6Tnl), + .obj_type_name = "ip6gretap", + .lnk_link_type = NM_LINK_TYPE_IP6GRETAP, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_ip6tnl_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_ip6tnl_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_ip6tnl_cmp, + }, + [NMP_OBJECT_TYPE_LNK_IPIP - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_IPIP, + .sizeof_data = sizeof(NMPObjectLnkIpIp), + .sizeof_public = sizeof(NMPlatformLnkIpIp), + .obj_type_name = "ipip", + .lnk_link_type = NM_LINK_TYPE_IPIP, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_ipip_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_ipip_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_ipip_cmp, + }, + [NMP_OBJECT_TYPE_LNK_MACSEC - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_MACSEC, + .sizeof_data = sizeof(NMPObjectLnkMacsec), + .sizeof_public = sizeof(NMPlatformLnkMacsec), + .obj_type_name = "macsec", + .lnk_link_type = NM_LINK_TYPE_MACSEC, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_macsec_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_macsec_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_macsec_cmp, + }, + [NMP_OBJECT_TYPE_LNK_MACVLAN - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_MACVLAN, + .sizeof_data = sizeof(NMPObjectLnkMacvlan), + .sizeof_public = sizeof(NMPlatformLnkMacvlan), + .obj_type_name = "macvlan", + .lnk_link_type = NM_LINK_TYPE_MACVLAN, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_macvlan_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_macvlan_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_macvlan_cmp, + }, + [NMP_OBJECT_TYPE_LNK_MACVTAP - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_MACVTAP, + .sizeof_data = sizeof(NMPObjectLnkMacvtap), + .sizeof_public = sizeof(NMPlatformLnkMacvlan), + .obj_type_name = "macvtap", + .lnk_link_type = NM_LINK_TYPE_MACVTAP, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_macvlan_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_macvlan_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_macvlan_cmp, + }, + [NMP_OBJECT_TYPE_LNK_SIT - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_SIT, + .sizeof_data = sizeof(NMPObjectLnkSit), + .sizeof_public = sizeof(NMPlatformLnkSit), + .obj_type_name = "sit", + .lnk_link_type = NM_LINK_TYPE_SIT, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_sit_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_sit_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_sit_cmp, + }, + [NMP_OBJECT_TYPE_LNK_TUN - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_TUN, + .sizeof_data = sizeof(NMPObjectLnkTun), + .sizeof_public = sizeof(NMPlatformLnkTun), + .obj_type_name = "tun", + .lnk_link_type = NM_LINK_TYPE_TUN, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_tun_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_tun_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_tun_cmp, + }, + [NMP_OBJECT_TYPE_LNK_VLAN - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_VLAN, + .sizeof_data = sizeof(NMPObjectLnkVlan), + .sizeof_public = sizeof(NMPlatformLnkVlan), + .obj_type_name = "vlan", + .lnk_link_type = NM_LINK_TYPE_VLAN, + .cmd_obj_hash_update = _vt_cmd_obj_hash_update_lnk_vlan, + .cmd_obj_cmp = _vt_cmd_obj_cmp_lnk_vlan, + .cmd_obj_copy = _vt_cmd_obj_copy_lnk_vlan, + .cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_vlan, + .cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_vlan, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_vlan_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_vlan_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_vlan_cmp, + }, + [NMP_OBJECT_TYPE_LNK_VRF - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_VRF, + .sizeof_data = sizeof(NMPObjectLnkVrf), + .sizeof_public = sizeof(NMPlatformLnkVrf), + .obj_type_name = "vrf", + .lnk_link_type = NM_LINK_TYPE_VRF, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_vrf_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_vrf_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_vrf_cmp, + }, + [NMP_OBJECT_TYPE_LNK_VXLAN - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_VXLAN, + .sizeof_data = sizeof(NMPObjectLnkVxlan), + .sizeof_public = sizeof(NMPlatformLnkVxlan), + .obj_type_name = "vxlan", + .lnk_link_type = NM_LINK_TYPE_VXLAN, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_vxlan_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_vxlan_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_vxlan_cmp, + }, + [NMP_OBJECT_TYPE_LNK_WIREGUARD - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_WIREGUARD, + .sizeof_data = sizeof(NMPObjectLnkWireGuard), + .sizeof_public = sizeof(NMPlatformLnkWireGuard), + .obj_type_name = "wireguard", + .lnk_link_type = NM_LINK_TYPE_WIREGUARD, + .cmd_obj_hash_update = _vt_cmd_obj_hash_update_lnk_wireguard, + .cmd_obj_cmp = _vt_cmd_obj_cmp_lnk_wireguard, + .cmd_obj_copy = _vt_cmd_obj_copy_lnk_wireguard, + .cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_wireguard, + .cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_wireguard, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_wireguard_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_wireguard_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_wireguard_cmp, + }, +}; diff --git a/src/libnm-platform/nmp-object.h b/src/libnm-platform/nmp-object.h new file mode 100644 index 0000000..14cf1e3 --- /dev/null +++ b/src/libnm-platform/nmp-object.h @@ -0,0 +1,1144 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2015 - 2018 Red Hat, Inc. + */ + +#ifndef __NMP_OBJECT_H__ +#define __NMP_OBJECT_H__ + +#include + +#include "libnm-glib-aux/nm-obj.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "nm-platform.h" + +struct udev_device; + +/*****************************************************************************/ + +/* "struct __kernel_timespec" uses "long long", but we use gint64. In practice, + * these are the same types. */ +G_STATIC_ASSERT(sizeof(long long) == sizeof(gint64)); + +typedef struct { + /* like "struct __kernel_timespec". */ + gint64 tv_sec; + gint64 tv_nsec; +} NMPTimespec64; + +/*****************************************************************************/ + +typedef union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; +} NMSockAddrUnion; + +G_STATIC_ASSERT(sizeof(NMSockAddrUnion) == sizeof(((NMSockAddrUnion *) NULL)->in6)); + +/* we initialize the largest union member, to ensure that all fields are initialized. */ + +#define NM_SOCK_ADDR_UNION_INIT_UNSPEC \ + { \ + .in6 = { \ + .sin6_family = AF_UNSPEC, \ + }, \ + } + +int nm_sock_addr_union_cmp(const NMSockAddrUnion *a, const NMSockAddrUnion *b); + +void nm_sock_addr_union_hash_update(const NMSockAddrUnion *a, NMHashState *h); + +void nm_sock_addr_union_cpy(NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */); + +void nm_sock_addr_union_cpy_untrusted(NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */, + gsize src_len); + +const char *nm_sock_addr_union_to_string(const NMSockAddrUnion *sa, char *buf, gsize len); + +/*****************************************************************************/ + +typedef struct { + NMIPAddr addr; + guint8 family; + guint8 mask; +} NMPWireGuardAllowedIP; + +typedef struct _NMPWireGuardPeer { + NMSockAddrUnion endpoint; + + NMPTimespec64 last_handshake_time; + + guint64 rx_bytes; + guint64 tx_bytes; + + union { + const NMPWireGuardAllowedIP *allowed_ips; + guint _construct_idx_start; + }; + union { + guint allowed_ips_len; + guint _construct_idx_end; + }; + + guint16 persistent_keepalive_interval; + + guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; + guint8 preshared_key[NMP_WIREGUARD_SYMMETRIC_KEY_LEN]; +} NMPWireGuardPeer; + +/*****************************************************************************/ + +typedef enum { /*< skip >*/ + NMP_OBJECT_TO_STRING_ID, + NMP_OBJECT_TO_STRING_PUBLIC, + NMP_OBJECT_TO_STRING_ALL, +} NMPObjectToStringMode; + +typedef enum { /*< skip >*/ + NMP_CACHE_OPS_UNCHANGED = NM_PLATFORM_SIGNAL_NONE, + NMP_CACHE_OPS_ADDED = NM_PLATFORM_SIGNAL_ADDED, + NMP_CACHE_OPS_UPDATED = NM_PLATFORM_SIGNAL_CHANGED, + NMP_CACHE_OPS_REMOVED = NM_PLATFORM_SIGNAL_REMOVED, +} NMPCacheOpsType; + +/* The NMPCacheIdType are the different index types. + * + * An object of a certain object-type, can be candidate to being + * indexed by a certain NMPCacheIdType or not. For example, all + * objects are indexed via an index of type NMP_CACHE_ID_TYPE_OBJECT_TYPE, + * but only route objects can be indexed by NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_NO_DEFAULT. + * + * Of one index type, there can be multiple indexes or not. + * For example, of the index type NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX there + * are multiple instances (for different route/addresses, v4/v6, per-ifindex). + * + * But one object, can only be indexed by one particular index of a + * type. For example, a certain address instance is only indexed by + * the index NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX with + * matching v4/v6 and ifindex -- or maybe not at all if it isn't visible. + * */ +typedef enum { /*< skip >*/ + NMP_CACHE_ID_TYPE_NONE, + + /* all the objects of a certain type. + * + * This index is special. It is the only one that contains *all* object. + * Other indexes may consider some object as non "partitionable", hence + * they don't track all objects. + * + * Hence, this index type is used when looking at all objects (still + * partitioned by type). + * + * Also, note that links may be considered invisible. This index type + * expose all links, even invisible ones. For addresses/routes, this + * distinction doesn't exist, as all addresses/routes that are alive + * are visible as well. */ + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + + /* index for the link objects by ifname. */ + NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, + + /* indices for the visible default-routes, ignoring ifindex. + * This index only contains two partitions: all visible default-routes, + * separate for IPv4 and IPv6. */ + NMP_CACHE_ID_TYPE_DEFAULT_ROUTES, + + /* all the objects that have an ifindex (by object-type) for an ifindex. */ + NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, + + /* Consider all the destination fields of a route, that is, the ID without the ifindex + * and gateway (meaning: network/plen,metric). + * The reason for this is that `ip route change` can replace an existing route + * and modify its ifindex/gateway. Effectively, that means it deletes an existing + * route and adds a different one (as the ID of the route changes). However, it only + * sends one RTM_NEWADDR notification without notifying about the deletion. We detect + * that by having this index to contain overlapping routes which require special + * cache-resync. */ + NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, + + /* a filter for objects that track an explicit address family. + * + * Note that currently on NMPObjectRoutingRule is indexed by this filter. */ + NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY, + + __NMP_CACHE_ID_TYPE_MAX, + NMP_CACHE_ID_TYPE_MAX = __NMP_CACHE_ID_TYPE_MAX - 1, +} NMPCacheIdType; + +typedef struct { + NMDedupMultiObjClass parent; + const char * obj_type_name; + const char * signal_type; + const guint8 * supported_cache_ids; + int sizeof_data; + int sizeof_public; + int addr_family; + int rtm_gettype; + NMPObjectType obj_type; + NMPlatformSignalIdType signal_type_id; + + /* Only for NMPObjectLnk* types. */ + NMLinkType lnk_link_type; + + void (*cmd_obj_hash_update)(const NMPObject *obj, NMHashState *h); + int (*cmd_obj_cmp)(const NMPObject *obj1, const NMPObject *obj2); + void (*cmd_obj_copy)(NMPObject *dst, const NMPObject *src); + void (*cmd_obj_dispose)(NMPObject *obj); + gboolean (*cmd_obj_is_alive)(const NMPObject *obj); + gboolean (*cmd_obj_is_visible)(const NMPObject *obj); + const char *(*cmd_obj_to_string)(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size); + + /* functions that operate on NMPlatformObject */ + void (*cmd_plobj_id_copy)(NMPlatformObject *dst, const NMPlatformObject *src); + int (*cmd_plobj_id_cmp)(const NMPlatformObject *obj1, const NMPlatformObject *obj2); + void (*cmd_plobj_id_hash_update)(const NMPlatformObject *obj, NMHashState *h); + const char *(*cmd_plobj_to_string_id)(const NMPlatformObject *obj, char *buf, gsize buf_size); + const char *(*cmd_plobj_to_string)(const NMPlatformObject *obj, char *buf, gsize len); + void (*cmd_plobj_hash_update)(const NMPlatformObject *obj, NMHashState *h); + int (*cmd_plobj_cmp)(const NMPlatformObject *obj1, const NMPlatformObject *obj2); +} NMPClass; + +extern const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX]; + +typedef struct { + NMPlatformLink _public; + + struct { + bool is_in_netlink; + + /* Additional data that depends on the link-type (IFLA_INFO_DATA) */ + const NMPObject *lnk; + } netlink; + + struct { + /* note that "struct udev_device" references the library context + * "struct udev", but doesn't own it. + * + * Hence, the udev.device shall not be used after the library + * context is destroyed. + * + * In case of NMPObjectLink instances that you obtained from the + * platform cache, that means that you shall no keep references + * to those instances that outlife the NMPlatform instance. + * + * In practice, the requirement is less strict and you'll be even + * fine if the platform instance (and the "struct udev" instance) + * are already destroyed while you still hold onto a reference to + * the NMPObjectLink instance. Just don't make use of udev functions + * that cause access to the udev library context. + */ + struct udev_device *device; + } udev; + + /* Auxiliary data object for Wi-Fi and WPAN */ + GObject *ext_data; + + /* FIXME: not every NMPObjectLink should pay the price for tracking + * the wireguard family id. This should be tracked via ext_data, which + * would be exactly the right place. */ + int wireguard_family_id; +} NMPObjectLink; + +typedef struct { + NMPlatformLnkBridge _public; +} NMPObjectLnkBridge; + +typedef struct { + NMPlatformLnkGre _public; +} NMPObjectLnkGre; + +typedef struct { + NMPlatformLnkInfiniband _public; +} NMPObjectLnkInfiniband; + +typedef struct { + NMPlatformLnkIp6Tnl _public; +} NMPObjectLnkIp6Tnl; + +typedef struct { + NMPlatformLnkIpIp _public; +} NMPObjectLnkIpIp; + +typedef struct { + NMPlatformLnkMacsec _public; +} NMPObjectLnkMacsec; + +typedef struct { + NMPlatformLnkMacvlan _public; +} NMPObjectLnkMacvlan; + +typedef NMPObjectLnkMacvlan NMPObjectLnkMacvtap; + +typedef struct { + NMPlatformLnkSit _public; +} NMPObjectLnkSit; + +typedef struct { + NMPlatformLnkTun _public; +} NMPObjectLnkTun; + +typedef struct { + NMPlatformLnkVlan _public; + + guint n_ingress_qos_map; + guint n_egress_qos_map; + const NMVlanQosMapping *ingress_qos_map; + const NMVlanQosMapping *egress_qos_map; +} NMPObjectLnkVlan; + +typedef struct { + NMPlatformLnkVrf _public; +} NMPObjectLnkVrf; + +typedef struct { + NMPlatformLnkVxlan _public; +} NMPObjectLnkVxlan; + +typedef struct { + NMPlatformLnkWireGuard _public; + const NMPWireGuardPeer * peers; + const NMPWireGuardAllowedIP *_allowed_ips_buf; + guint peers_len; + guint _allowed_ips_buf_len; +} NMPObjectLnkWireGuard; + +typedef struct { + NMPlatformIP4Address _public; +} NMPObjectIP4Address; + +typedef struct { + NMPlatformIP4Route _public; +} NMPObjectIP4Route; + +typedef struct { + NMPlatformIP6Address _public; +} NMPObjectIP6Address; + +typedef struct { + NMPlatformIP6Route _public; +} NMPObjectIP6Route; + +typedef struct { + NMPlatformRoutingRule _public; +} NMPObjectRoutingRule; + +typedef struct { + NMPlatformQdisc _public; +} NMPObjectQdisc; + +typedef struct { + NMPlatformTfilter _public; +} NMPObjectTfilter; + +struct _NMPObject { + union { + NMDedupMultiObj parent; + const NMPClass *_class; + }; + union { + NMPlatformObject object; + + NMPlatformObjWithIfindex obj_with_ifindex; + + NMPlatformLink link; + NMPObjectLink _link; + + NMPlatformLnkBridge lnk_bridge; + NMPObjectLnkBridge _lnk_bridge; + + NMPlatformLnkGre lnk_gre; + NMPObjectLnkGre _lnk_gre; + + NMPlatformLnkInfiniband lnk_infiniband; + NMPObjectLnkInfiniband _lnk_infiniband; + + NMPlatformLnkIpIp lnk_ipip; + NMPObjectLnkIpIp _lnk_ipip; + + NMPlatformLnkIp6Tnl lnk_ip6tnl; + NMPObjectLnkIp6Tnl _lnk_ip6tnl; + + NMPlatformLnkMacsec lnk_macsec; + NMPObjectLnkMacsec _lnk_macsec; + + NMPlatformLnkMacvlan lnk_macvlan; + NMPObjectLnkMacvlan _lnk_macvlan; + + NMPlatformLnkSit lnk_sit; + NMPObjectLnkSit _lnk_sit; + + NMPlatformLnkTun lnk_tun; + NMPObjectLnkTun _lnk_tun; + + NMPlatformLnkVlan lnk_vlan; + NMPObjectLnkVlan _lnk_vlan; + + NMPlatformLnkVrf lnk_vrf; + NMPObjectLnkVrf _lnk_vrf; + + NMPlatformLnkVxlan lnk_vxlan; + NMPObjectLnkVxlan _lnk_vxlan; + + NMPlatformLnkWireGuard lnk_wireguard; + NMPObjectLnkWireGuard _lnk_wireguard; + + NMPlatformIPAddress ip_address; + NMPlatformIPXAddress ipx_address; + NMPlatformIP4Address ip4_address; + NMPlatformIP6Address ip6_address; + NMPObjectIP4Address _ip4_address; + NMPObjectIP6Address _ip6_address; + + NMPlatformIPRoute ip_route; + NMPlatformIPXRoute ipx_route; + NMPlatformIP4Route ip4_route; + NMPlatformIP6Route ip6_route; + NMPObjectIP4Route _ip4_route; + NMPObjectIP6Route _ip6_route; + + NMPlatformRoutingRule routing_rule; + NMPObjectRoutingRule _routing_rule; + + NMPlatformQdisc qdisc; + NMPObjectQdisc _qdisc; + NMPlatformTfilter tfilter; + NMPObjectTfilter _tfilter; + }; +}; + +/*****************************************************************************/ + +static inline gboolean +NMP_CLASS_IS_VALID(const NMPClass *klass) +{ + return klass >= &_nmp_classes[0] && klass <= &_nmp_classes[G_N_ELEMENTS(_nmp_classes)] + && ((((char *) klass) - ((char *) _nmp_classes)) % (sizeof(_nmp_classes[0]))) == 0; +} + +static inline const NMPClass * +nmp_class_from_type(NMPObjectType obj_type) +{ + nm_assert(obj_type > 0); + nm_assert(obj_type <= G_N_ELEMENTS(_nmp_classes)); + nm_assert(_nmp_classes[obj_type - 1].obj_type == obj_type); + nm_assert(NMP_CLASS_IS_VALID(&_nmp_classes[obj_type - 1])); + + return &_nmp_classes[obj_type - 1]; +} + +static inline NMPObject * +NMP_OBJECT_UP_CAST(const NMPlatformObject *plobj) +{ + NMPObject *obj; + + obj = plobj ? (NMPObject *) (&(((char *) plobj)[-((int) G_STRUCT_OFFSET(NMPObject, object))])) + : NULL; + nm_assert(!obj || (obj->parent._ref_count > 0 && NMP_CLASS_IS_VALID(obj->_class))); + return obj; +} +#define NMP_OBJECT_UP_CAST(plobj) (NMP_OBJECT_UP_CAST((const NMPlatformObject *) (plobj))) + +static inline gboolean +NMP_OBJECT_IS_VALID(const NMPObject *obj) +{ + nm_assert(!obj || (obj && obj->parent._ref_count > 0 && NMP_CLASS_IS_VALID(obj->_class))); + + /* There isn't really much to check. Either @obj is NULL, or we must + * assume that it points to valid memory. */ + return obj != NULL; +} + +static inline gboolean +NMP_OBJECT_IS_STACKINIT(const NMPObject *obj) +{ + nm_assert(!obj || NMP_OBJECT_IS_VALID(obj)); + + return obj && obj->parent._ref_count == NM_OBJ_REF_COUNT_STACKINIT; +} + +static inline const NMPClass * +NMP_OBJECT_GET_CLASS(const NMPObject *obj) +{ + nm_assert(NMP_OBJECT_IS_VALID(obj)); + + return obj->_class; +} + +static inline NMPObjectType +NMP_OBJECT_GET_TYPE(const NMPObject *obj) +{ + nm_assert(!obj || NMP_OBJECT_IS_VALID(obj)); + + return obj ? obj->_class->obj_type : NMP_OBJECT_TYPE_UNKNOWN; +} + +static inline gboolean +_NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMPObjectType obj_type) +{ + switch (obj_type) { + case NMP_OBJECT_TYPE_LINK: + case NMP_OBJECT_TYPE_IP4_ADDRESS: + case NMP_OBJECT_TYPE_IP6_ADDRESS: + case NMP_OBJECT_TYPE_IP4_ROUTE: + case NMP_OBJECT_TYPE_IP6_ROUTE: + + case NMP_OBJECT_TYPE_QDISC: + + case NMP_OBJECT_TYPE_TFILTER: + + case NMP_OBJECT_TYPE_LNK_BRIDGE: + case NMP_OBJECT_TYPE_LNK_GRE: + case NMP_OBJECT_TYPE_LNK_GRETAP: + case NMP_OBJECT_TYPE_LNK_INFINIBAND: + case NMP_OBJECT_TYPE_LNK_IP6TNL: + case NMP_OBJECT_TYPE_LNK_IP6GRE: + case NMP_OBJECT_TYPE_LNK_IP6GRETAP: + case NMP_OBJECT_TYPE_LNK_IPIP: + case NMP_OBJECT_TYPE_LNK_MACSEC: + case NMP_OBJECT_TYPE_LNK_MACVLAN: + case NMP_OBJECT_TYPE_LNK_MACVTAP: + case NMP_OBJECT_TYPE_LNK_SIT: + case NMP_OBJECT_TYPE_LNK_TUN: + case NMP_OBJECT_TYPE_LNK_VLAN: + case NMP_OBJECT_TYPE_LNK_VRF: + case NMP_OBJECT_TYPE_LNK_VXLAN: + case NMP_OBJECT_TYPE_LNK_WIREGUARD: + return TRUE; + + case NMP_OBJECT_TYPE_ROUTING_RULE: + return FALSE; + + case NMP_OBJECT_TYPE_UNKNOWN: + case __NMP_OBJECT_TYPE_LAST: + break; + } + nm_assert_not_reached(); + return FALSE; +} + +#define NMP_OBJECT_CAST_OBJECT(obj) \ + ({ \ + typeof(obj) _obj = (obj); \ + \ + nm_assert ( !_obj \ + || nmp_class_from_type (NMP_OBJECT_GET_TYPE (_obj)))); \ + _obj ? &NM_CONSTCAST(NMPObject, _obj)->object : NULL; \ + }) + +#define NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj) \ + ({ \ + typeof(obj) _obj = (obj); \ + \ + nm_assert(!_obj || _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMP_OBJECT_GET_TYPE(_obj))); \ + _obj ? &NM_CONSTCAST(NMPObject, _obj)->obj_with_ifindex : NULL; \ + }) + +#define _NMP_OBJECT_CAST(obj, field, ...) \ + ({ \ + typeof(obj) _obj = (obj); \ + \ + nm_assert(!_obj || NM_IN_SET(NMP_OBJECT_GET_TYPE(_obj), __VA_ARGS__)); \ + _obj ? &NM_CONSTCAST(NMPObject, _obj)->field : NULL; \ + }) + +#define NMP_OBJECT_CAST_LINK(obj) _NMP_OBJECT_CAST(obj, link, NMP_OBJECT_TYPE_LINK) +#define NMP_OBJECT_CAST_IP_ADDRESS(obj) \ + _NMP_OBJECT_CAST(obj, ip_address, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS) +#define NMP_OBJECT_CAST_IPX_ADDRESS(obj) \ + _NMP_OBJECT_CAST(obj, ipx_address, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS) +#define NMP_OBJECT_CAST_IP4_ADDRESS(obj) \ + _NMP_OBJECT_CAST(obj, ip4_address, NMP_OBJECT_TYPE_IP4_ADDRESS) +#define NMP_OBJECT_CAST_IP6_ADDRESS(obj) \ + _NMP_OBJECT_CAST(obj, ip6_address, NMP_OBJECT_TYPE_IP6_ADDRESS) +#define NMP_OBJECT_CAST_IP_ROUTE(obj) \ + _NMP_OBJECT_CAST(obj, ip_route, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) +#define NMP_OBJECT_CAST_IPX_ROUTE(obj) \ + _NMP_OBJECT_CAST(obj, ipx_route, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) +#define NMP_OBJECT_CAST_IP4_ROUTE(obj) _NMP_OBJECT_CAST(obj, ip4_route, NMP_OBJECT_TYPE_IP4_ROUTE) +#define NMP_OBJECT_CAST_IP6_ROUTE(obj) _NMP_OBJECT_CAST(obj, ip6_route, NMP_OBJECT_TYPE_IP6_ROUTE) +#define NMP_OBJECT_CAST_ROUTING_RULE(obj) \ + _NMP_OBJECT_CAST(obj, routing_rule, NMP_OBJECT_TYPE_ROUTING_RULE) +#define NMP_OBJECT_CAST_QDISC(obj) _NMP_OBJECT_CAST(obj, qdisc, NMP_OBJECT_TYPE_QDISC) +#define NMP_OBJECT_CAST_TFILTER(obj) _NMP_OBJECT_CAST(obj, tfilter, NMP_OBJECT_TYPE_TFILTER) +#define NMP_OBJECT_CAST_LNK_WIREGUARD(obj) \ + _NMP_OBJECT_CAST(obj, lnk_wireguard, NMP_OBJECT_TYPE_LNK_WIREGUARD) +#define NMP_OBJECT_CAST_LNK_BRIDGE(obj) \ + _NMP_OBJECT_CAST(obj, lnk_bridge, NMP_OBJECT_TYPE_LNK_BRIDGE) + +static inline int +NMP_OBJECT_TYPE_TO_ADDR_FAMILY(NMPObjectType obj_type) +{ + return nmp_class_from_type(obj_type)->addr_family; +} + +static inline int +NMP_OBJECT_GET_ADDR_FAMILY(const NMPObject *obj) +{ + return NMP_OBJECT_GET_CLASS(obj)->addr_family; +} + +static inline const NMPObject * +nmp_object_ref(const NMPObject *obj) +{ + if (!obj) { + /* for convenience, allow NULL. */ + return NULL; + } + + /* ref and unref accept const pointers. NMPObject is supposed to be shared + * and kept immutable. Disallowing to take/return a reference to a const + * NMPObject is cumbersome, because callers are precisely expected to + * keep a ref on the otherwise immutable object. */ + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj), NULL); + g_return_val_if_fail(obj->parent._ref_count != NM_OBJ_REF_COUNT_STACKINIT, NULL); + + return (const NMPObject *) nm_dedup_multi_obj_ref((const NMDedupMultiObj *) obj); +} + +static inline void +nmp_object_unref(const NMPObject *obj) +{ + if (obj) { + nm_assert(NMP_OBJECT_IS_VALID(obj)); + + nm_dedup_multi_obj_unref((const NMDedupMultiObj *) obj); + } +} + +#define nm_clear_nmp_object(ptr) \ + ({ \ + typeof(ptr) _ptr = (ptr); \ + typeof(*_ptr) _pptr; \ + gboolean _changed = FALSE; \ + \ + if (_ptr && (_pptr = *_ptr)) { \ + *_ptr = NULL; \ + nmp_object_unref(_pptr); \ + _changed = TRUE; \ + } \ + _changed; \ + }) + +static inline gboolean +nmp_object_ref_set(const NMPObject **pp, const NMPObject *obj) +{ + gboolean _changed = FALSE; + const NMPObject *p; + + nm_assert(!pp || !*pp || NMP_OBJECT_IS_VALID(*pp)); + nm_assert(!obj || NMP_OBJECT_IS_VALID(obj)); + + if (pp && ((p = *pp) != obj)) { + nmp_object_ref(obj); + *pp = obj; + nmp_object_unref(p); + _changed = TRUE; + } + return _changed; +} + +NMPObject *nmp_object_new(NMPObjectType obj_type, gconstpointer plobj); +NMPObject *nmp_object_new_link(int ifindex); + +const NMPObject *nmp_object_stackinit(NMPObject *obj, NMPObjectType obj_type, gconstpointer plobj); + +static inline NMPObject * +nmp_object_stackinit_obj(NMPObject *obj, const NMPObject *src) +{ + return obj == src + ? obj + : (NMPObject *) nmp_object_stackinit(obj, NMP_OBJECT_GET_TYPE(src), &src->object); +} + +const NMPObject *nmp_object_stackinit_id(NMPObject *obj, const NMPObject *src); +const NMPObject *nmp_object_stackinit_id_link(NMPObject *obj, int ifindex); +const NMPObject *nmp_object_stackinit_id_ip4_address(NMPObject *obj, + int ifindex, + guint32 address, + guint8 plen, + guint32 peer_address); +const NMPObject * +nmp_object_stackinit_id_ip6_address(NMPObject *obj, int ifindex, const struct in6_addr *address); + +const char *nmp_object_to_string(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size); +void nmp_object_hash_update(const NMPObject *obj, NMHashState *h); +int nmp_object_cmp(const NMPObject *obj1, const NMPObject *obj2); + +static inline gboolean +nmp_object_equal(const NMPObject *obj1, const NMPObject *obj2) +{ + return nmp_object_cmp(obj1, obj2) == 0; +} + +void nmp_object_copy(NMPObject *dst, const NMPObject *src, gboolean id_only); +NMPObject *nmp_object_clone(const NMPObject *obj, gboolean id_only); + +int nmp_object_id_cmp(const NMPObject *obj1, const NMPObject *obj2); +void nmp_object_id_hash_update(const NMPObject *obj, NMHashState *h); +guint nmp_object_id_hash(const NMPObject *obj); + +static inline gboolean +nmp_object_id_equal(const NMPObject *obj1, const NMPObject *obj2) +{ + return nmp_object_id_cmp(obj1, obj2) == 0; +} + +guint nmp_object_indirect_id_hash(gconstpointer a); +gboolean nmp_object_indirect_id_equal(gconstpointer a, gconstpointer b); + +gboolean nmp_object_is_alive(const NMPObject *obj); +gboolean nmp_object_is_visible(const NMPObject *obj); + +void +_nmp_object_fixup_link_udev_fields(NMPObject **obj_new, NMPObject *obj_orig, gboolean use_udev); + +static inline void +_nm_auto_nmpobj_cleanup(gpointer p) +{ + nmp_object_unref(*((const NMPObject **) p)); +} +#define nm_auto_nmpobj nm_auto(_nm_auto_nmpobj_cleanup) + +typedef struct _NMPCache NMPCache; + +typedef void (*NMPCachePreHook)(NMPCache * cache, + const NMPObject *old, + const NMPObject *new, + NMPCacheOpsType ops_type, + gpointer user_data); +typedef gboolean (*NMPObjectMatchFn)(const NMPObject *obj, gpointer user_data); + +const NMDedupMultiEntry *nmp_cache_lookup_entry(const NMPCache *cache, const NMPObject *obj); +const NMDedupMultiEntry *nmp_cache_lookup_entry_with_idx_type(const NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *obj); +const NMDedupMultiEntry *nmp_cache_lookup_entry_link(const NMPCache *cache, int ifindex); +const NMPObject * nmp_cache_lookup_obj(const NMPCache *cache, const NMPObject *obj); +const NMPObject * nmp_cache_lookup_link(const NMPCache *cache, int ifindex); + +typedef struct _NMPLookup NMPLookup; + +struct _NMPLookup { + NMPCacheIdType cache_id_type; + NMPObject selector_obj; +}; + +const NMDedupMultiHeadEntry *nmp_cache_lookup_all(const NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *select_obj); + +static inline const NMDedupMultiHeadEntry * +nmp_cache_lookup(const NMPCache *cache, const NMPLookup *lookup) +{ + return nmp_cache_lookup_all(cache, lookup->cache_id_type, &lookup->selector_obj); +} + +const NMPLookup *nmp_lookup_init_obj_type(NMPLookup *lookup, NMPObjectType obj_type); +const NMPLookup *nmp_lookup_init_link_by_ifname(NMPLookup *lookup, const char *ifname); +const NMPLookup *nmp_lookup_init_object(NMPLookup *lookup, NMPObjectType obj_type, int ifindex); +const NMPLookup *nmp_lookup_init_route_default(NMPLookup *lookup, NMPObjectType obj_type); +const NMPLookup *nmp_lookup_init_route_by_weak_id(NMPLookup *lookup, const NMPObject *obj); +const NMPLookup *nmp_lookup_init_ip4_route_by_weak_id(NMPLookup *lookup, + in_addr_t network, + guint plen, + guint32 metric, + guint8 tos); +const NMPLookup *nmp_lookup_init_ip6_route_by_weak_id(NMPLookup * lookup, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen); +const NMPLookup * +nmp_lookup_init_object_by_addr_family(NMPLookup *lookup, NMPObjectType obj_type, int addr_family); + +GArray *nmp_cache_lookup_to_array(const NMDedupMultiHeadEntry *head_entry, + NMPObjectType obj_type, + gboolean visible_only); + +static inline gboolean +nmp_cache_iter_next(NMDedupMultiIter *iter, const NMPObject **out_obj) +{ + gboolean has_next; + + has_next = nm_dedup_multi_iter_next(iter); + nm_assert(!has_next || NMP_OBJECT_IS_VALID(iter->current->obj)); + if (out_obj) + *out_obj = has_next ? iter->current->obj : NULL; + return has_next; +} + +static inline gboolean +nmp_cache_iter_next_link(NMDedupMultiIter *iter, const NMPlatformLink **out_obj) +{ + gboolean has_next; + + has_next = nm_dedup_multi_iter_next(iter); + nm_assert(!has_next || NMP_OBJECT_GET_TYPE(iter->current->obj) == NMP_OBJECT_TYPE_LINK); + if (out_obj) + *out_obj = has_next ? &(((const NMPObject *) iter->current->obj)->link) : NULL; + return has_next; +} + +#define nmp_cache_iter_for_each(iter, head, obj) \ + for (nm_dedup_multi_iter_init((iter), (head)); nmp_cache_iter_next((iter), (obj));) + +#define nmp_cache_iter_for_each_link(iter, head, obj) \ + for (nm_dedup_multi_iter_init((iter), (head)); nmp_cache_iter_next_link((iter), (obj));) + +const NMPObject *nmp_cache_lookup_link_full(const NMPCache * cache, + int ifindex, + const char * ifname, + gboolean visible_only, + NMLinkType link_type, + NMPObjectMatchFn match_fn, + gpointer user_data); + +gboolean nmp_cache_link_connected_for_slave(int ifindex_master, const NMPObject *slave); +gboolean nmp_cache_link_connected_needs_toggle(const NMPCache * cache, + const NMPObject *master, + const NMPObject *potential_slave, + const NMPObject *ignore_slave); +const NMPObject *nmp_cache_link_connected_needs_toggle_by_ifindex(const NMPCache * cache, + int master_ifindex, + const NMPObject *potential_slave, + const NMPObject *ignore_slave); + +gboolean nmp_cache_use_udev_get(const NMPCache *cache); + +void nmtst_assert_nmp_cache_is_consistent(const NMPCache *cache); + +NMPCacheOpsType nmp_cache_remove(NMPCache * cache, + const NMPObject * obj_needle, + gboolean equals_by_ptr, + gboolean only_dirty, + const NMPObject **out_obj_old); +NMPCacheOpsType nmp_cache_remove_netlink(NMPCache * cache, + const NMPObject * obj_needle, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new); +NMPCacheOpsType nmp_cache_update_netlink(NMPCache * cache, + NMPObject * obj_hand_over, + gboolean is_dump, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new); +NMPCacheOpsType nmp_cache_update_netlink_route(NMPCache * cache, + NMPObject * obj_hand_over, + gboolean is_dump, + guint16 nlmsgflags, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new, + const NMPObject **out_obj_replace, + gboolean * out_resync_required); +NMPCacheOpsType nmp_cache_update_link_udev(NMPCache * cache, + int ifindex, + struct udev_device *udevice, + const NMPObject ** out_obj_old, + const NMPObject ** out_obj_new); +NMPCacheOpsType nmp_cache_update_link_master_connected(NMPCache * cache, + int ifindex, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new); + +static inline const NMDedupMultiEntry * +nmp_cache_reresolve_main_entry(NMPCache * cache, + const NMDedupMultiEntry *entry, + const NMPLookup * lookup) +{ + const NMDedupMultiEntry *main_entry; + + nm_assert(cache); + nm_assert(entry); + nm_assert(lookup); + + if (lookup->cache_id_type == NMP_CACHE_ID_TYPE_OBJECT_TYPE) { + nm_assert(entry == nmp_cache_lookup_entry(cache, entry->obj)); + return entry; + } + + /* we only track the dirty flag for the OBJECT-TYPE index. That means, + * for other lookup types we need to check the dirty flag of the main-entry. */ + main_entry = nmp_cache_lookup_entry(cache, entry->obj); + + nm_assert(main_entry); + nm_assert(main_entry->obj == entry->obj); + + return main_entry; +} + +void nmp_cache_dirty_set_all_main(NMPCache *cache, const NMPLookup *lookup); + +NMPCache *nmp_cache_new(NMDedupMultiIndex *multi_idx, gboolean use_udev); +void nmp_cache_free(NMPCache *cache); + +static inline void +ASSERT_nmp_cache_ops(const NMPCache * cache, + NMPCacheOpsType ops_type, + const NMPObject *obj_old, + const NMPObject *obj_new) +{ +#if NM_MORE_ASSERTS + nm_assert(cache); + nm_assert(obj_old || obj_new); + nm_assert(!obj_old + || (NMP_OBJECT_IS_VALID(obj_old) && !NMP_OBJECT_IS_STACKINIT(obj_old) + && nmp_object_is_alive(obj_old))); + nm_assert(!obj_new + || (NMP_OBJECT_IS_VALID(obj_new) && !NMP_OBJECT_IS_STACKINIT(obj_new) + && nmp_object_is_alive(obj_new))); + + switch (ops_type) { + case NMP_CACHE_OPS_UNCHANGED: + nm_assert(obj_old == obj_new); + break; + case NMP_CACHE_OPS_ADDED: + nm_assert(!obj_old && obj_new); + break; + case NMP_CACHE_OPS_UPDATED: + nm_assert(obj_old && obj_new && obj_old != obj_new); + break; + case NMP_CACHE_OPS_REMOVED: + nm_assert(obj_old && !obj_new); + break; + default: + nm_assert_not_reached(); + } + + nm_assert(obj_new == NULL || obj_old == NULL || nmp_object_id_equal(obj_new, obj_old)); + nm_assert(!obj_old || !obj_new + || NMP_OBJECT_GET_CLASS(obj_old) == NMP_OBJECT_GET_CLASS(obj_new)); + + nm_assert(obj_new == nmp_cache_lookup_obj(cache, obj_new ?: obj_old)); +#endif +} + +const NMDedupMultiHeadEntry * +nm_platform_lookup_all(NMPlatform *platform, NMPCacheIdType cache_id_type, const NMPObject *obj); + +const NMDedupMultiEntry * +nm_platform_lookup_entry(NMPlatform *platform, NMPCacheIdType cache_id_type, const NMPObject *obj); + +static inline const NMPObject * +nm_platform_lookup_obj(NMPlatform *platform, NMPCacheIdType cache_id_type, const NMPObject *obj) +{ + return nm_dedup_multi_entry_get_obj(nm_platform_lookup_entry(platform, cache_id_type, obj)); +} + +static inline const NMDedupMultiHeadEntry * +nm_platform_lookup_obj_type(NMPlatform *platform, NMPObjectType obj_type) +{ + NMPLookup lookup; + + nmp_lookup_init_obj_type(&lookup, obj_type); + return nm_platform_lookup(platform, &lookup); +} + +static inline const NMDedupMultiHeadEntry * +nm_platform_lookup_link_by_ifname(NMPlatform *platform, const char *ifname) +{ + NMPLookup lookup; + + nmp_lookup_init_link_by_ifname(&lookup, ifname); + return nm_platform_lookup(platform, &lookup); +} + +static inline const NMDedupMultiHeadEntry * +nm_platform_lookup_object(NMPlatform *platform, NMPObjectType obj_type, int ifindex) +{ + NMPLookup lookup; + + nmp_lookup_init_object(&lookup, obj_type, ifindex); + return nm_platform_lookup(platform, &lookup); +} + +static inline GPtrArray * +nm_platform_lookup_object_clone(NMPlatform * platform, + NMPObjectType obj_type, + int ifindex, + NMPObjectPredicateFunc predicate, + gpointer user_data) +{ + NMPLookup lookup; + + nmp_lookup_init_object(&lookup, obj_type, ifindex); + return nm_platform_lookup_clone(platform, &lookup, predicate, user_data); +} + +static inline const NMDedupMultiHeadEntry * +nm_platform_lookup_route_default(NMPlatform *platform, NMPObjectType obj_type) +{ + NMPLookup lookup; + + nmp_lookup_init_route_default(&lookup, obj_type); + return nm_platform_lookup(platform, &lookup); +} + +static inline GPtrArray * +nm_platform_lookup_route_default_clone(NMPlatform * platform, + NMPObjectType obj_type, + NMPObjectPredicateFunc predicate, + gpointer user_data) +{ + NMPLookup lookup; + + nmp_lookup_init_route_default(&lookup, obj_type); + return nm_platform_lookup_clone(platform, &lookup, predicate, user_data); +} + +static inline const NMDedupMultiHeadEntry * +nm_platform_lookup_ip4_route_by_weak_id(NMPlatform *platform, + in_addr_t network, + guint plen, + guint32 metric, + guint8 tos) +{ + NMPLookup lookup; + + nmp_lookup_init_ip4_route_by_weak_id(&lookup, network, plen, metric, tos); + return nm_platform_lookup(platform, &lookup); +} + +static inline const NMDedupMultiHeadEntry * +nm_platform_lookup_ip6_route_by_weak_id(NMPlatform * platform, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen) +{ + NMPLookup lookup; + + nmp_lookup_init_ip6_route_by_weak_id(&lookup, network, plen, metric, src, src_plen); + return nm_platform_lookup(platform, &lookup); +} + +static inline const NMDedupMultiHeadEntry * +nm_platform_lookup_object_by_addr_family(NMPlatform * platform, + NMPObjectType obj_type, + int addr_family) +{ + NMPLookup lookup; + + nmp_lookup_init_object_by_addr_family(&lookup, obj_type, addr_family); + return nm_platform_lookup(platform, &lookup); +} + +/*****************************************************************************/ + +static inline const char * +nmp_object_link_get_ifname(const NMPObject *obj) +{ + if (!obj) + return NULL; + return NMP_OBJECT_CAST_LINK(obj)->name; +} + +static inline gboolean +nmp_object_ip_route_is_best_defaut_route(const NMPObject *obj) +{ + const NMPlatformIPRoute *r = NMP_OBJECT_CAST_IP_ROUTE(obj); + + /* return whether @obj is considered a default-route. + * + * NMIP4Config/NMIP6Config tracks the (best) default-route explicitly, because + * at various places we act differently depending on whether there is a default-route + * configured. + * + * Note that this only considers the main routing table. */ + return r && NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r) + && nm_platform_route_table_is_main(r->table_coerced) + && r->type_coerced == nm_platform_route_type_coerce(1 /* RTN_UNICAST */); +} + +static inline gboolean +nmp_object_ip6_address_is_not_link_local(const NMPObject *obj) +{ + return !IN6_IS_ADDR_LINKLOCAL(&NMP_OBJECT_CAST_IP6_ADDRESS(obj)->address); +} + +/*****************************************************************************/ + +static inline gboolean +nm_platform_dedup_multi_iter_next_obj(NMDedupMultiIter *ipconf_iter, + const NMPObject **out_obj, + NMPObjectType assert_obj_type) +{ + gboolean has_next; + + has_next = nm_dedup_multi_iter_next(ipconf_iter); + nm_assert(assert_obj_type == NMP_OBJECT_TYPE_UNKNOWN || !has_next + || NMP_OBJECT_GET_TYPE(ipconf_iter->current->obj) == assert_obj_type); + NM_SET_OUT(out_obj, has_next ? ipconf_iter->current->obj : NULL); + return has_next; +} + +#define _nm_platform_dedup_multi_iter_next(ipconf_iter, out_obj, field, ...) \ + ({ \ + NMDedupMultiIter *const _ipconf_iter = (ipconf_iter); \ + const typeof(((NMPObject *) NULL)->field) **const _out_obj = (out_obj); \ + gboolean _has_next; \ + \ + if (G_LIKELY(nm_dedup_multi_iter_next(_ipconf_iter))) { \ + if (_out_obj) { \ + *_out_obj = _NMP_OBJECT_CAST(_ipconf_iter->current->obj, field, __VA_ARGS__); \ + } else { \ + nm_assert( \ + NM_IN_SET(NMP_OBJECT_GET_TYPE(_ipconf_iter->current->obj), __VA_ARGS__)); \ + } \ + _has_next = TRUE; \ + } else { \ + if (_out_obj) \ + *_out_obj = NULL; \ + _has_next = FALSE; \ + } \ + _has_next; \ + }) + +#define nm_platform_dedup_multi_iter_next_ip_address(ipconf_iter, out_obj) \ + _nm_platform_dedup_multi_iter_next((ipconf_iter), \ + (out_obj), \ + ip_address, \ + NMP_OBJECT_TYPE_IP4_ADDRESS, \ + NMP_OBJECT_TYPE_IP6_ADDRESS) + +#define nm_platform_dedup_multi_iter_next_ip4_address(ipconf_iter, out_obj) \ + _nm_platform_dedup_multi_iter_next((ipconf_iter), \ + (out_obj), \ + ip4_address, \ + NMP_OBJECT_TYPE_IP4_ADDRESS) + +#define nm_platform_dedup_multi_iter_next_ip6_address(ipconf_iter, out_obj) \ + _nm_platform_dedup_multi_iter_next((ipconf_iter), \ + (out_obj), \ + ip6_address, \ + NMP_OBJECT_TYPE_IP6_ADDRESS) + +#define nm_platform_dedup_multi_iter_next_ip_route(ipconf_iter, out_obj) \ + _nm_platform_dedup_multi_iter_next((ipconf_iter), \ + (out_obj), \ + ip_route, \ + NMP_OBJECT_TYPE_IP4_ROUTE, \ + NMP_OBJECT_TYPE_IP6_ROUTE) + +#define nm_platform_dedup_multi_iter_next_ip4_route(ipconf_iter, out_obj) \ + _nm_platform_dedup_multi_iter_next((ipconf_iter), \ + (out_obj), \ + ip4_route, \ + NMP_OBJECT_TYPE_IP4_ROUTE) + +#define nm_platform_dedup_multi_iter_next_ip6_route(ipconf_iter, out_obj) \ + _nm_platform_dedup_multi_iter_next((ipconf_iter), \ + (out_obj), \ + ip6_route, \ + NMP_OBJECT_TYPE_IP6_ROUTE) + +#endif /* __NMP_OBJECT_H__ */ diff --git a/src/libnm-platform/nmp-rules-manager.c b/src/libnm-platform/nmp-rules-manager.c new file mode 100644 index 0000000..636c90b --- /dev/null +++ b/src/libnm-platform/nmp-rules-manager.c @@ -0,0 +1,809 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nmp-rules-manager.h" + +#include +#include + +#include "libnm-log-core/nm-logging.h" +#include "libnm-std-aux/c-list-util.h" +#include "nmp-object.h" + +/*****************************************************************************/ + +struct _NMPRulesManager { + NMPlatform *platform; + GHashTable *by_obj; + GHashTable *by_user_tag; + GHashTable *by_data; + guint ref_count; +}; + +/*****************************************************************************/ + +static void _rules_init(NMPRulesManager *self); + +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_PLATFORM +#define _NMLOG_PREFIX_NAME "rules-manager" + +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + _nm_log(__level, \ + _NMLOG_DOMAIN, \ + 0, \ + NULL, \ + NULL, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END + +/*****************************************************************************/ + +static gboolean +NMP_IS_RULES_MANAGER(gpointer self) +{ + return self && ((NMPRulesManager *) self)->ref_count > 0 + && NM_IS_PLATFORM(((NMPRulesManager *) self)->platform); +} + +#define _USER_TAG_LOG(user_tag) nm_hash_obfuscate_ptr(1240261787u, (user_tag)) + +/*****************************************************************************/ + +typedef struct { + const NMPObject *obj; + gconstpointer user_tag; + CList obj_lst; + CList user_tag_lst; + + /* track_priority_val zero is special: those are weakly tracked rules. + * That means: NetworkManager will restore them only if it removed them earlier. + * But it will not remove or add them otherwise. + * + * Otherwise, the track_priority_val goes together with track_priority_present. + * In case of one rule being tracked multiple times (with different priorities), + * the one with higher priority wins. See _rules_obj_get_best_data(). + * Then, the winning present state either enforces that the rule is present + * or absent. + * + * If a rules is not tracked at all, it is ignored by NetworkManager. Assuming + * that it was added externally by the user. But unlike weakly tracked rules, + * NM will *not* restore such rules if NetworkManager themself removed them. */ + guint32 track_priority_val; + bool track_priority_present : 1; + + bool dirty : 1; +} RulesData; + +typedef enum { + CONFIG_STATE_NONE = 0, + CONFIG_STATE_ADDED_BY_US = 1, + CONFIG_STATE_REMOVED_BY_US = 2, + + /* ConfigState encodes whether the rule was touched by us at all (CONFIG_STATE_NONE). + * + * Maybe we would only need to track whether we touched the rule at all. But we + * track it more in detail what we did: did we add it (CONFIG_STATE_ADDED_BY_US) + * or did we remove it (CONFIG_STATE_REMOVED_BY_US)? + * Finally, we need CONFIG_STATE_OWNED_BY_US, which means that we didn't actively + * add/remove it, but whenever we are about to undo the add/remove, we need to do it. + * In that sense, CONFIG_STATE_OWNED_BY_US is really just a flag that we unconditionally + * force the state next time when necessary. */ + CONFIG_STATE_OWNED_BY_US = 3, +} ConfigState; + +typedef struct { + const NMPObject *obj; + CList obj_lst_head; + + /* indicates whether we configured/removed the rule (during sync()). We need that, so + * if the rule gets untracked, that we know to remove/restore it. + * + * This makes NMPRulesManager stateful (beyond the configuration that indicates + * which rules are tracked). + * After a restart, NetworkManager would no longer remember which rules were added + * by us. + * + * That is partially fixed by NetworkManager taking over the rules that it + * actively configures (see %NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG). */ + ConfigState config_state; +} RulesObjData; + +typedef struct { + gconstpointer user_tag; + CList user_tag_lst_head; +} RulesUserTagData; + +/*****************************************************************************/ + +static void _rules_data_untrack(NMPRulesManager *self, + RulesData * rules_data, + gboolean remove_user_tag_data, + gboolean make_owned_by_us); + +/*****************************************************************************/ + +static void +_rules_data_assert(const RulesData *rules_data, gboolean linked) +{ + nm_assert(rules_data); + nm_assert(NMP_OBJECT_GET_TYPE(rules_data->obj) == NMP_OBJECT_TYPE_ROUTING_RULE); + nm_assert(nmp_object_is_visible(rules_data->obj)); + nm_assert(rules_data->user_tag); + nm_assert(!linked || !c_list_is_empty(&rules_data->obj_lst)); + nm_assert(!linked || !c_list_is_empty(&rules_data->user_tag_lst)); +} + +static guint +_rules_data_hash(gconstpointer data) +{ + const RulesData *rules_data = data; + NMHashState h; + + _rules_data_assert(rules_data, FALSE); + + nm_hash_init(&h, 269297543u); + nm_platform_routing_rule_hash_update(NMP_OBJECT_CAST_ROUTING_RULE(rules_data->obj), + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID, + &h); + nm_hash_update_val(&h, rules_data->user_tag); + return nm_hash_complete(&h); +} + +static gboolean +_rules_data_equal(gconstpointer data_a, gconstpointer data_b) +{ + const RulesData *rules_data_a = data_a; + const RulesData *rules_data_b = data_b; + + _rules_data_assert(rules_data_a, FALSE); + _rules_data_assert(rules_data_b, FALSE); + + return rules_data_a->user_tag == rules_data_b->user_tag + && (nm_platform_routing_rule_cmp(NMP_OBJECT_CAST_ROUTING_RULE(rules_data_a->obj), + NMP_OBJECT_CAST_ROUTING_RULE(rules_data_b->obj), + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) + == 0); +} + +static void +_rules_data_destroy(gpointer data) +{ + RulesData *rules_data = data; + + _rules_data_assert(rules_data, FALSE); + + c_list_unlink_stale(&rules_data->obj_lst); + c_list_unlink_stale(&rules_data->user_tag_lst); + nmp_object_unref(rules_data->obj); + g_slice_free(RulesData, rules_data); +} + +static const RulesData * +_rules_obj_get_best_data(RulesObjData *obj_data) +{ + RulesData * rules_data; + const RulesData *rd_best = NULL; + + c_list_for_each_entry (rules_data, &obj_data->obj_lst_head, obj_lst) { + _rules_data_assert(rules_data, TRUE); + + if (rd_best) { + if (rd_best->track_priority_val > rules_data->track_priority_val) + continue; + if (rd_best->track_priority_val == rules_data->track_priority_val) { + if (rd_best->track_priority_present || !rules_data->track_priority_present) { + /* if the priorities are identical, then "present" wins over + * "!present" (absent). */ + continue; + } + } + } + + rd_best = rules_data; + } + + return rd_best; +} + +static guint +_rules_obj_hash(gconstpointer data) +{ + const RulesObjData *obj_data = data; + NMHashState h; + + nm_hash_init(&h, 432817559u); + nm_platform_routing_rule_hash_update(NMP_OBJECT_CAST_ROUTING_RULE(obj_data->obj), + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID, + &h); + return nm_hash_complete(&h); +} + +static gboolean +_rules_obj_equal(gconstpointer data_a, gconstpointer data_b) +{ + const RulesObjData *obj_data_a = data_a; + const RulesObjData *obj_data_b = data_b; + + return (nm_platform_routing_rule_cmp(NMP_OBJECT_CAST_ROUTING_RULE(obj_data_a->obj), + NMP_OBJECT_CAST_ROUTING_RULE(obj_data_b->obj), + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) + == 0); +} + +static void +_rules_obj_destroy(gpointer data) +{ + RulesObjData *obj_data = data; + + c_list_unlink_stale(&obj_data->obj_lst_head); + nmp_object_unref(obj_data->obj); + g_slice_free(RulesObjData, obj_data); +} + +static guint +_rules_user_tag_hash(gconstpointer data) +{ + const RulesUserTagData *user_tag_data = data; + + return nm_hash_val(644693447u, user_tag_data->user_tag); +} + +static gboolean +_rules_user_tag_equal(gconstpointer data_a, gconstpointer data_b) +{ + const RulesUserTagData *user_tag_data_a = data_a; + const RulesUserTagData *user_tag_data_b = data_b; + + return user_tag_data_a->user_tag == user_tag_data_b->user_tag; +} + +static void +_rules_user_tag_destroy(gpointer data) +{ + RulesUserTagData *user_tag_data = data; + + c_list_unlink_stale(&user_tag_data->user_tag_lst_head); + g_slice_free(RulesUserTagData, user_tag_data); +} + +static RulesData * +_rules_data_lookup(GHashTable *by_data, const NMPObject *obj, gconstpointer user_tag) +{ + RulesData rules_data_needle = { + .obj = obj, + .user_tag = user_tag, + }; + + return g_hash_table_lookup(by_data, &rules_data_needle); +} + +/** + * nmp_rules_manager_track: + * @self: the #NMPRulesManager instance + * @routing_rule: the #NMPlatformRoutingRule to track or untrack + * @track_priority: the priority for tracking the rule. Note that + * negative values indicate a forced absence of the rule. Priorities + * are compared with their absolute values (with higher absolute + * value being more important). For example, if you track the same + * rule twice, once with priority -5 and +10, then the rule is + * present (because the positive number is more important). + * The special value 0 indicates weakly-tracked rules. + * @user_tag: the tag associated with tracking this rule. The same tag + * must be used to untrack the rule later. + * @user_tag_untrack: if not %NULL, at the same time untrack this user-tag + * for the same rule. Note that this is different from a plain nmp_rules_manager_untrack(), + * because it enforces ownership of the now tracked rule. On the other hand, + * a plain nmp_rules_manager_untrack() merely forgets about the tracking. + * The purpose here is to set this to %NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG. + */ +void +nmp_rules_manager_track(NMPRulesManager * self, + const NMPlatformRoutingRule *routing_rule, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack) +{ + NMPObject obj_stack; + const NMPObject * p_obj_stack; + RulesData * rules_data; + RulesObjData * obj_data; + RulesUserTagData *user_tag_data; + gboolean changed = FALSE; + guint32 track_priority_val; + gboolean track_priority_present; + + g_return_if_fail(NMP_IS_RULES_MANAGER(self)); + g_return_if_fail(routing_rule); + g_return_if_fail(user_tag); + nm_assert(track_priority != G_MININT32); + + _rules_init(self); + + p_obj_stack = nmp_object_stackinit(&obj_stack, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule); + + nm_assert(nmp_object_is_visible(p_obj_stack)); + + if (track_priority >= 0) { + track_priority_val = track_priority; + track_priority_present = TRUE; + } else { + track_priority_val = -track_priority; + track_priority_present = FALSE; + } + + rules_data = _rules_data_lookup(self->by_data, p_obj_stack, user_tag); + + if (!rules_data) { + rules_data = g_slice_new(RulesData); + *rules_data = (RulesData){ + .obj = nm_dedup_multi_index_obj_intern(nm_platform_get_multi_idx(self->platform), + p_obj_stack), + .user_tag = user_tag, + .track_priority_val = track_priority_val, + .track_priority_present = track_priority_present, + .dirty = FALSE, + }; + g_hash_table_add(self->by_data, rules_data); + + obj_data = g_hash_table_lookup(self->by_obj, &rules_data->obj); + if (!obj_data) { + obj_data = g_slice_new(RulesObjData); + *obj_data = (RulesObjData){ + .obj = nmp_object_ref(rules_data->obj), + .obj_lst_head = C_LIST_INIT(obj_data->obj_lst_head), + .config_state = CONFIG_STATE_NONE, + }; + g_hash_table_add(self->by_obj, obj_data); + } + c_list_link_tail(&obj_data->obj_lst_head, &rules_data->obj_lst); + + user_tag_data = g_hash_table_lookup(self->by_user_tag, &rules_data->user_tag); + if (!user_tag_data) { + user_tag_data = g_slice_new(RulesUserTagData); + *user_tag_data = (RulesUserTagData){ + .user_tag = user_tag, + .user_tag_lst_head = C_LIST_INIT(user_tag_data->user_tag_lst_head), + }; + g_hash_table_add(self->by_user_tag, user_tag_data); + } + c_list_link_tail(&user_tag_data->user_tag_lst_head, &rules_data->user_tag_lst); + changed = TRUE; + } else { + rules_data->dirty = FALSE; + if (rules_data->track_priority_val != track_priority_val + || rules_data->track_priority_present != track_priority_present) { + rules_data->track_priority_val = track_priority_val; + rules_data->track_priority_present = track_priority_present; + changed = TRUE; + } + } + + if (user_tag_untrack) { + if (user_tag != user_tag_untrack) { + RulesData *rules_data_untrack; + + rules_data_untrack = _rules_data_lookup(self->by_data, p_obj_stack, user_tag_untrack); + if (rules_data_untrack) + _rules_data_untrack(self, rules_data_untrack, FALSE, TRUE); + } else + nm_assert_not_reached(); + } + + _rules_data_assert(rules_data, TRUE); + + if (changed) { + _LOGD("routing-rule: track [" NM_HASH_OBFUSCATE_PTR_FMT ",%s%u] \"%s\")", + _USER_TAG_LOG(rules_data->user_tag), + (rules_data->track_priority_val == 0 + ? "" + : (rules_data->track_priority_present ? "+" : "-")), + (guint) rules_data->track_priority_val, + nmp_object_to_string(rules_data->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + } +} + +static void +_rules_data_untrack(NMPRulesManager *self, + RulesData * rules_data, + gboolean remove_user_tag_data, + gboolean make_owned_by_us) +{ + RulesObjData *obj_data; + + nm_assert(NMP_IS_RULES_MANAGER(self)); + _rules_data_assert(rules_data, TRUE); + nm_assert(self->by_data); + nm_assert(g_hash_table_lookup(self->by_data, rules_data) == rules_data); + + _LOGD("routing-rule: untrack [" NM_HASH_OBFUSCATE_PTR_FMT "] \"%s\"", + _USER_TAG_LOG(rules_data->user_tag), + nmp_object_to_string(rules_data->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + +#if NM_MORE_ASSERTS + { + RulesUserTagData *user_tag_data; + + user_tag_data = g_hash_table_lookup(self->by_user_tag, &rules_data->user_tag); + nm_assert(user_tag_data); + nm_assert(c_list_contains(&user_tag_data->user_tag_lst_head, &rules_data->user_tag_lst)); + } +#endif + + nm_assert(!c_list_is_empty(&rules_data->user_tag_lst)); + + obj_data = g_hash_table_lookup(self->by_obj, &rules_data->obj); + nm_assert(obj_data); + nm_assert(c_list_contains(&obj_data->obj_lst_head, &rules_data->obj_lst)); + nm_assert(obj_data == g_hash_table_lookup(self->by_obj, &rules_data->obj)); + + if (make_owned_by_us) { + if (obj_data->config_state == CONFIG_STATE_NONE) { + /* we need to mark this entry that it requires a touch on the next + * sync. */ + obj_data->config_state = CONFIG_STATE_OWNED_BY_US; + } + } else if (remove_user_tag_data && c_list_length_is(&rules_data->user_tag_lst, 1)) + g_hash_table_remove(self->by_user_tag, &rules_data->user_tag); + + /* if obj_data is marked to be "added_by_us" or "removed_by_us", we need to keep this entry + * around for the next sync -- so that we can undo what we did earlier. */ + if (obj_data->config_state == CONFIG_STATE_NONE && c_list_length_is(&rules_data->obj_lst, 1)) + g_hash_table_remove(self->by_obj, &rules_data->obj); + + g_hash_table_remove(self->by_data, rules_data); +} + +void +nmp_rules_manager_untrack(NMPRulesManager * self, + const NMPlatformRoutingRule *routing_rule, + gconstpointer user_tag) +{ + NMPObject obj_stack; + const NMPObject *p_obj_stack; + RulesData * rules_data; + + g_return_if_fail(NMP_IS_RULES_MANAGER(self)); + g_return_if_fail(routing_rule); + g_return_if_fail(user_tag); + + _rules_init(self); + + p_obj_stack = nmp_object_stackinit(&obj_stack, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule); + + nm_assert(nmp_object_is_visible(p_obj_stack)); + + rules_data = _rules_data_lookup(self->by_data, p_obj_stack, user_tag); + if (rules_data) + _rules_data_untrack(self, rules_data, TRUE, FALSE); +} + +void +nmp_rules_manager_set_dirty(NMPRulesManager *self, gconstpointer user_tag) +{ + RulesData * rules_data; + RulesUserTagData *user_tag_data; + + g_return_if_fail(NMP_IS_RULES_MANAGER(self)); + g_return_if_fail(user_tag); + + if (!self->by_data) + return; + + user_tag_data = g_hash_table_lookup(self->by_user_tag, &user_tag); + if (!user_tag_data) + return; + + c_list_for_each_entry (rules_data, &user_tag_data->user_tag_lst_head, user_tag_lst) + rules_data->dirty = TRUE; +} + +void +nmp_rules_manager_untrack_all(NMPRulesManager *self, + gconstpointer user_tag, + gboolean all /* or only dirty */) +{ + RulesData * rules_data; + RulesData * rules_data_safe; + RulesUserTagData *user_tag_data; + + g_return_if_fail(NMP_IS_RULES_MANAGER(self)); + g_return_if_fail(user_tag); + + if (!self->by_data) + return; + + user_tag_data = g_hash_table_lookup(self->by_user_tag, &user_tag); + if (!user_tag_data) + return; + + c_list_for_each_entry_safe (rules_data, + rules_data_safe, + &user_tag_data->user_tag_lst_head, + user_tag_lst) { + if (all || rules_data->dirty) + _rules_data_untrack(self, rules_data, FALSE, FALSE); + } + if (c_list_is_empty(&user_tag_data->user_tag_lst_head)) + g_hash_table_remove(self->by_user_tag, user_tag_data); +} + +void +nmp_rules_manager_sync(NMPRulesManager *self, gboolean keep_deleted_rules) +{ + const NMDedupMultiHeadEntry *pl_head_entry; + NMDedupMultiIter pl_iter; + const NMPObject * plobj; + gs_unref_ptrarray GPtrArray *rules_to_delete = NULL; + RulesObjData * obj_data; + GHashTableIter h_iter; + guint i; + const RulesData * rd_best; + + g_return_if_fail(NMP_IS_RULES_MANAGER(self)); + + if (!self->by_data) + return; + + _LOGD("sync%s", keep_deleted_rules ? " (don't remove any rules)" : ""); + + pl_head_entry = nm_platform_lookup_obj_type(self->platform, NMP_OBJECT_TYPE_ROUTING_RULE); + if (pl_head_entry) { + nmp_cache_iter_for_each (&pl_iter, pl_head_entry, &plobj) { + obj_data = g_hash_table_lookup(self->by_obj, &plobj); + + if (!obj_data) { + /* this rule is not tracked. It was externally added, hence we + * ignore it. */ + continue; + } + + rd_best = _rules_obj_get_best_data(obj_data); + if (rd_best) { + if (rd_best->track_priority_present) { + if (obj_data->config_state == CONFIG_STATE_OWNED_BY_US) + obj_data->config_state = CONFIG_STATE_ADDED_BY_US; + continue; + } + if (rd_best->track_priority_val == 0) { + if (!NM_IN_SET(obj_data->config_state, + CONFIG_STATE_ADDED_BY_US, + CONFIG_STATE_OWNED_BY_US)) { + obj_data->config_state = CONFIG_STATE_NONE; + continue; + } + obj_data->config_state = CONFIG_STATE_NONE; + } + } + + if (keep_deleted_rules) { + _LOGD("forget/leak rule added by us: %s", + nmp_object_to_string(plobj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + continue; + } + + if (!rules_to_delete) + rules_to_delete = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + + g_ptr_array_add(rules_to_delete, (gpointer) nmp_object_ref(plobj)); + + obj_data->config_state = CONFIG_STATE_REMOVED_BY_US; + } + } + + if (rules_to_delete) { + for (i = 0; i < rules_to_delete->len; i++) + nm_platform_object_delete(self->platform, rules_to_delete->pdata[i]); + } + + g_hash_table_iter_init(&h_iter, self->by_obj); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &obj_data, NULL)) { + rd_best = _rules_obj_get_best_data(obj_data); + + if (!rd_best) { + g_hash_table_iter_remove(&h_iter); + continue; + } + + if (!rd_best->track_priority_present) { + if (obj_data->config_state == CONFIG_STATE_OWNED_BY_US) + obj_data->config_state = CONFIG_STATE_REMOVED_BY_US; + continue; + } + if (rd_best->track_priority_val == 0) { + if (!NM_IN_SET(obj_data->config_state, + CONFIG_STATE_REMOVED_BY_US, + CONFIG_STATE_OWNED_BY_US)) { + obj_data->config_state = CONFIG_STATE_NONE; + continue; + } + obj_data->config_state = CONFIG_STATE_NONE; + } + + plobj = + nm_platform_lookup_obj(self->platform, NMP_CACHE_ID_TYPE_OBJECT_TYPE, obj_data->obj); + if (plobj) + continue; + + obj_data->config_state = CONFIG_STATE_ADDED_BY_US; + nm_platform_routing_rule_add(self->platform, + NMP_NLM_FLAG_ADD, + NMP_OBJECT_CAST_ROUTING_RULE(obj_data->obj)); + } +} + +void +nmp_rules_manager_track_from_platform(NMPRulesManager *self, + NMPlatform * platform, + int addr_family, + gint32 tracking_priority, + gconstpointer user_tag) +{ + NMPLookup lookup; + const NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIter iter; + const NMPObject * o; + + g_return_if_fail(NMP_IS_RULES_MANAGER(self)); + + if (!platform) + platform = self->platform; + else + g_return_if_fail(NM_IS_PLATFORM(platform)); + + nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); + + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); + head_entry = nm_platform_lookup(platform, &lookup); + nmp_cache_iter_for_each (&iter, head_entry, &o) { + const NMPlatformRoutingRule *rr = NMP_OBJECT_CAST_ROUTING_RULE(o); + + if (addr_family != AF_UNSPEC && rr->addr_family != addr_family) + continue; + + nmp_rules_manager_track(self, rr, tracking_priority, user_tag, NULL); + } +} + +/*****************************************************************************/ + +void +nmp_rules_manager_track_default(NMPRulesManager *self, + int addr_family, + gint32 track_priority, + gconstpointer user_tag) +{ + g_return_if_fail(NMP_IS_RULES_MANAGER(self)); + + nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); + + /* track the default rules. See also `man ip-rule`. */ + + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) { + nmp_rules_manager_track(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 0, + .table = RT_TABLE_LOCAL, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_rules_manager_track(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 32766, + .table = RT_TABLE_MAIN, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_rules_manager_track(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 32767, + .table = RT_TABLE_DEFAULT, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + } + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) { + nmp_rules_manager_track(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET6, + .priority = 0, + .table = RT_TABLE_LOCAL, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_rules_manager_track(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET6, + .priority = 32766, + .table = RT_TABLE_MAIN, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + } +} + +static void +_rules_init(NMPRulesManager *self) +{ + if (self->by_data) + return; + + self->by_data = + g_hash_table_new_full(_rules_data_hash, _rules_data_equal, NULL, _rules_data_destroy); + self->by_obj = + g_hash_table_new_full(_rules_obj_hash, _rules_obj_equal, NULL, _rules_obj_destroy); + self->by_user_tag = g_hash_table_new_full(_rules_user_tag_hash, + _rules_user_tag_equal, + NULL, + _rules_user_tag_destroy); +} + +/*****************************************************************************/ + +NMPRulesManager * +nmp_rules_manager_new(NMPlatform *platform) +{ + NMPRulesManager *self; + + g_return_val_if_fail(NM_IS_PLATFORM(platform), NULL); + + self = g_slice_new(NMPRulesManager); + *self = (NMPRulesManager){ + .ref_count = 1, + .platform = g_object_ref(platform), + }; + return self; +} + +void +nmp_rules_manager_ref(NMPRulesManager *self) +{ + g_return_if_fail(NMP_IS_RULES_MANAGER(self)); + + self->ref_count++; +} + +void +nmp_rules_manager_unref(NMPRulesManager *self) +{ + g_return_if_fail(NMP_IS_RULES_MANAGER(self)); + + if (--self->ref_count > 0) + return; + + if (self->by_data) { + g_hash_table_destroy(self->by_user_tag); + g_hash_table_destroy(self->by_obj); + g_hash_table_destroy(self->by_data); + } + g_object_unref(self->platform); + g_slice_free(NMPRulesManager, self); +} diff --git a/src/libnm-platform/nmp-rules-manager.h b/src/libnm-platform/nmp-rules-manager.h new file mode 100644 index 0000000..69cf907 --- /dev/null +++ b/src/libnm-platform/nmp-rules-manager.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NMP_RULES_MANAGER_H__ +#define __NMP_RULES_MANAGER_H__ + +#include "nm-platform.h" + +/*****************************************************************************/ + +#define NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG ((const void *) nmp_rules_manager_new) + +typedef struct _NMPRulesManager NMPRulesManager; + +NMPRulesManager *nmp_rules_manager_new(NMPlatform *platform); + +void nmp_rules_manager_ref(NMPRulesManager *self); +void nmp_rules_manager_unref(NMPRulesManager *self); + +#define nm_auto_unref_rules_manager nm_auto(_nmp_rules_manager_unref) +NM_AUTO_DEFINE_FCN0(NMPRulesManager *, _nmp_rules_manager_unref, nmp_rules_manager_unref); + +void nmp_rules_manager_track(NMPRulesManager * self, + const NMPlatformRoutingRule *routing_rule, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack); + +void nmp_rules_manager_track_default(NMPRulesManager *self, + int addr_family, + gint32 track_priority, + gconstpointer user_tag); + +void nmp_rules_manager_track_from_platform(NMPRulesManager *self, + NMPlatform * platform, + int addr_family, + gint32 tracking_priority, + gconstpointer user_tag); + +void nmp_rules_manager_untrack(NMPRulesManager * self, + const NMPlatformRoutingRule *routing_rule, + gconstpointer user_tag); + +void nmp_rules_manager_set_dirty(NMPRulesManager *self, gconstpointer user_tag); + +void nmp_rules_manager_untrack_all(NMPRulesManager *self, + gconstpointer user_tag, + gboolean all /* or only dirty */); + +void nmp_rules_manager_sync(NMPRulesManager *self, gboolean keep_deleted_rules); + +/*****************************************************************************/ + +#endif /* __NMP_RULES_MANAGER_H__ */ diff --git a/src/libnm-platform/tests/meson.build b/src/libnm-platform/tests/meson.build new file mode 100644 index 0000000..bec385e --- /dev/null +++ b/src/libnm-platform/tests/meson.build @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +exe = executable( + 'test-nm-platform', + 'test-nm-platform.c', + include_directories: [ + src_inc, + top_inc, + ], + dependencies: [ + glib_dep, + libudev_dep, + ], + link_with: [ + libnm_platform, + libnm_base, + libnm_udev_aux, + libnm_log_core, + libnm_glib_aux, + libnm_std_aux, + libc_siphash, + ], +) + +test( + 'src/libnm-platform/tests/test-nm-platform', + test_script, + args: test_args + [exe.full_path()], + timeout: default_test_timeout, +) diff --git a/src/libnm-platform/tests/test-nm-platform.c b/src/libnm-platform/tests/test-nm-platform.c new file mode 100644 index 0000000..5b1b8e8 --- /dev/null +++ b/src/libnm-platform/tests/test-nm-platform.c @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-glib-aux/nm-default-glib-i18n-prog.h" + +#include "libnm-log-core/nm-logging.h" +#include "libnm-platform/nm-netlink.h" +#include "libnm-platform/nmp-netns.h" + +#include "libnm-glib-aux/nm-test-utils.h" + +/*****************************************************************************/ + +void +_nm_logging_clear_platform_logging_cache(void) +{ + /* this symbols is required by nm-log-core library. */ +} + +/*****************************************************************************/ + +static void +test_use_symbols(void) +{ + static void (*const SYMBOLS[])(void) = { + (void (*)(void)) nl_nlmsghdr_to_str, + (void (*)(void)) nlmsg_hdr, + (void (*)(void)) nlmsg_reserve, + (void (*)(void)) nla_reserve, + (void (*)(void)) nlmsg_alloc_size, + (void (*)(void)) nlmsg_alloc, + (void (*)(void)) nlmsg_alloc_convert, + (void (*)(void)) nlmsg_alloc_simple, + (void (*)(void)) nlmsg_free, + (void (*)(void)) nlmsg_append, + (void (*)(void)) nlmsg_parse, + (void (*)(void)) nlmsg_put, + (void (*)(void)) nla_strlcpy, + (void (*)(void)) nla_memcpy, + (void (*)(void)) nla_put, + (void (*)(void)) nla_find, + (void (*)(void)) nla_nest_cancel, + (void (*)(void)) nla_nest_start, + (void (*)(void)) nla_nest_end, + (void (*)(void)) nla_parse, + (void (*)(void)) nlmsg_get_proto, + (void (*)(void)) nlmsg_set_proto, + (void (*)(void)) nlmsg_set_src, + (void (*)(void)) nlmsg_get_creds, + (void (*)(void)) nlmsg_set_creds, + (void (*)(void)) genlmsg_put, + (void (*)(void)) genlmsg_data, + (void (*)(void)) genlmsg_user_hdr, + (void (*)(void)) genlmsg_hdr, + (void (*)(void)) genlmsg_user_data, + (void (*)(void)) genlmsg_attrdata, + (void (*)(void)) genlmsg_len, + (void (*)(void)) genlmsg_attrlen, + (void (*)(void)) genlmsg_valid_hdr, + (void (*)(void)) genlmsg_parse, + (void (*)(void)) genl_ctrl_resolve, + (void (*)(void)) nl_socket_alloc, + (void (*)(void)) nl_socket_free, + (void (*)(void)) nl_socket_get_fd, + (void (*)(void)) nl_socket_get_local_port, + (void (*)(void)) nl_socket_get_msg_buf_size, + (void (*)(void)) nl_socket_set_passcred, + (void (*)(void)) nl_socket_set_msg_buf_size, + (void (*)(void)) nlmsg_get_dst, + (void (*)(void)) nl_socket_set_nonblocking, + (void (*)(void)) nl_socket_set_buffer_size, + (void (*)(void)) nl_socket_add_memberships, + (void (*)(void)) nl_socket_set_ext_ack, + (void (*)(void)) nl_socket_disable_msg_peek, + (void (*)(void)) nl_connect, + (void (*)(void)) nl_wait_for_ack, + (void (*)(void)) nl_recvmsgs, + (void (*)(void)) nl_sendmsg, + (void (*)(void)) nl_send_iovec, + (void (*)(void)) nl_complete_msg, + (void (*)(void)) nl_send, + (void (*)(void)) nl_send_auto, + (void (*)(void)) nl_recv, + + (void (*)(void)) nmp_netns_bind_to_path, + (void (*)(void)) nmp_netns_bind_to_path_destroy, + (void (*)(void)) nmp_netns_get_current, + (void (*)(void)) nmp_netns_get_fd_mnt, + (void (*)(void)) nmp_netns_get_fd_net, + (void (*)(void)) nmp_netns_get_initial, + (void (*)(void)) nmp_netns_is_initial, + (void (*)(void)) nmp_netns_new, + (void (*)(void)) nmp_netns_pop, + (void (*)(void)) nmp_netns_push, + (void (*)(void)) nmp_netns_push_type, + + NULL, + }; + + /* The only (not very exciting) purpose of this test is to see that + * we can use various symbols and don't get a linker error. */ + assert(G_N_ELEMENTS(SYMBOLS) == NM_PTRARRAY_LEN(SYMBOLS) + 1); +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_func("/nm-platform/test_use_symbols", test_use_symbols); + + return g_test_run(); +} diff --git a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c new file mode 100644 index 0000000..148657e --- /dev/null +++ b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c @@ -0,0 +1,908 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + * Copyright (C) 2011 Intel Corporation. All rights reserved. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-wifi-utils-nl80211.h" + +#include +#include +#include +#include +#include + +#include "libnm-log-core/nm-logging.h" +#include "libnm-platform/nm-netlink.h" +#include "nm-wifi-utils-private.h" +#include "libnm-platform/nm-platform-utils.h" + +#define _NMLOG_PREFIX_NAME "wifi-nl80211" +#define _NMLOG_DOMAIN LOGD_PLATFORM | LOGD_WIFI +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + char _ifname_buf[IFNAMSIZ]; \ + const char *_ifname = \ + self ? nmp_utils_if_indextoname(self->parent.ifindex, _ifname_buf) : NULL; \ + \ + nm_log((level), \ + _NMLOG_DOMAIN, \ + _ifname ?: NULL, \ + NULL, \ + "%s%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + NM_PRINT_FMT_QUOTED(_ifname, " (", _ifname, ")", "") \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END + +typedef struct { + NMWifiUtils parent; + struct nl_sock *nl_sock; + guint32 * freqs; + int id; + int num_freqs; + int phy; + bool can_wowlan : 1; +} NMWifiUtilsNl80211; + +typedef struct { + NMWifiUtilsClass parent; +} NMWifiUtilsNl80211Class; + +G_DEFINE_TYPE(NMWifiUtilsNl80211, nm_wifi_utils_nl80211, NM_TYPE_WIFI_UTILS) + +static int +ack_handler(struct nl_msg *msg, void *arg) +{ + int *done = arg; + *done = 1; + return NL_STOP; +} + +static int +finish_handler(struct nl_msg *msg, void *arg) +{ + int *done = arg; + *done = 1; + return NL_SKIP; +} + +static int +error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) +{ + int *done = arg; + *done = err->error; + return NL_SKIP; +} + +static struct nl_msg * +_nl80211_alloc_msg(int id, int ifindex, int phy, guint32 cmd, guint32 flags) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + + msg = nlmsg_alloc(); + genlmsg_put(msg, 0, 0, id, 0, flags, cmd, 0); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex); + if (phy != -1) + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, phy); + return g_steal_pointer(&msg); + +nla_put_failure: + g_return_val_if_reached(NULL); +} + +static struct nl_msg * +nl80211_alloc_msg(NMWifiUtilsNl80211 *self, guint32 cmd, guint32 flags) +{ + return _nl80211_alloc_msg(self->id, self->parent.ifindex, self->phy, cmd, flags); +} + +static int +nl80211_send_and_recv(NMWifiUtilsNl80211 *self, + struct nl_msg * msg, + int (*valid_handler)(struct nl_msg *, void *), + void *valid_data) +{ + int err; + int done = 0; + const struct nl_cb cb = { + .err_cb = error_handler, + .err_arg = &done, + .finish_cb = finish_handler, + .finish_arg = &done, + .ack_cb = ack_handler, + .ack_arg = &done, + .valid_cb = valid_handler, + .valid_arg = valid_data, + }; + + g_return_val_if_fail(msg != NULL, -ENOMEM); + + err = nl_send_auto(self->nl_sock, msg); + if (err < 0) + return err; + + /* Loop until one of our NL callbacks says we're done; on success + * done will be 1, on error it will be < 0. + */ + while (!done) { + err = nl_recvmsgs(self->nl_sock, &cb); + if (err < 0 && err != -EAGAIN) { + /* Kernel scan list can change while we are dumping it, as new scan + * results from H/W can arrive. BSS info is assured to be consistent + * and we don't need consistent view of whole scan list. Hence do + * not warn on DUMP_INTR error for get scan command. + */ + if (err == -NME_NL_DUMP_INTR + && genlmsg_hdr(nlmsg_hdr(msg))->cmd == NL80211_CMD_GET_SCAN) + break; + + _LOGW("nl_recvmsgs() error: (%d) %s", err, nm_strerror(err)); + break; + } + } + + if (err >= 0 && done < 0) + err = done; + return err; +} + +static void +dispose(GObject *object) +{ + NMWifiUtilsNl80211 *self = NM_WIFI_UTILS_NL80211(object); + + nm_clear_g_free(&self->freqs); +} + +struct nl80211_iface_info { + _NM80211Mode mode; + uint32_t freq; +}; + +static int +nl80211_iface_info_handler(struct nl_msg *msg, void *arg) +{ + struct nl80211_iface_info *info = arg; + struct genlmsghdr * gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr * tb[NL80211_ATTR_MAX + 1]; + + if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0) + return NL_SKIP; + + if (!tb[NL80211_ATTR_IFTYPE]) + return NL_SKIP; + + switch (nla_get_u32(tb[NL80211_ATTR_IFTYPE])) { + case NL80211_IFTYPE_ADHOC: + info->mode = _NM_802_11_MODE_ADHOC; + break; + case NL80211_IFTYPE_AP: + info->mode = _NM_802_11_MODE_AP; + break; + case NL80211_IFTYPE_STATION: + info->mode = _NM_802_11_MODE_INFRA; + break; + case NL80211_IFTYPE_MESH_POINT: + info->mode = _NM_802_11_MODE_MESH; + break; + } + + if (tb[NL80211_ATTR_WIPHY_FREQ] != NULL) + info->freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]); + + return NL_SKIP; +} + +static _NM80211Mode +wifi_nl80211_get_mode(NMWifiUtils *data) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + struct nl80211_iface_info iface_info = { + .mode = _NM_802_11_MODE_UNKNOWN, + }; + nm_auto_nlmsg struct nl_msg *msg = NULL; + + msg = nl80211_alloc_msg(self, NL80211_CMD_GET_INTERFACE, 0); + + if (nl80211_send_and_recv(self, msg, nl80211_iface_info_handler, &iface_info) < 0) + return _NM_802_11_MODE_UNKNOWN; + + return iface_info.mode; +} + +static gboolean +wifi_nl80211_set_mode(NMWifiUtils *data, const _NM80211Mode mode) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + msg = nl80211_alloc_msg(self, NL80211_CMD_SET_INTERFACE, 0); + + switch (mode) { + case _NM_802_11_MODE_INFRA: + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_STATION); + break; + case _NM_802_11_MODE_ADHOC: + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_ADHOC); + break; + case _NM_802_11_MODE_AP: + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_AP); + break; + case _NM_802_11_MODE_MESH: + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MESH_POINT); + break; + default: + g_assert_not_reached(); + } + + err = nl80211_send_and_recv(self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static gboolean +wifi_nl80211_set_powersave(NMWifiUtils *data, guint32 powersave) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + msg = nl80211_alloc_msg(self, NL80211_CMD_SET_POWER_SAVE, 0); + NLA_PUT_U32(msg, + NL80211_ATTR_PS_STATE, + powersave == 1 ? NL80211_PS_ENABLED : NL80211_PS_DISABLED); + err = nl80211_send_and_recv(self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static int +nl80211_get_wake_on_wlan_handler(struct nl_msg *msg, void *arg) +{ + _NMSettingWirelessWakeOnWLan *wowl = arg; + struct nlattr * attrs[NL80211_ATTR_MAX + 1]; + struct nlattr * trig[NUM_NL80211_WOWLAN_TRIG]; + struct genlmsghdr * gnlh = nlmsg_data(nlmsg_hdr(msg)); + + nla_parse_arr(attrs, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); + + if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) + return NL_SKIP; + + nla_parse_arr(trig, + nla_data(attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + nla_len(attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + NULL); + + *wowl = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE; + if (trig[NL80211_WOWLAN_TRIG_ANY]) + *wowl |= _NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY; + if (trig[NL80211_WOWLAN_TRIG_DISCONNECT]) + *wowl |= _NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT; + if (trig[NL80211_WOWLAN_TRIG_MAGIC_PKT]) + *wowl |= _NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC; + if (trig[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) + *wowl |= _NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE; + if (trig[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) + *wowl |= _NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST; + if (trig[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) + *wowl |= _NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE; + if (trig[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) + *wowl |= _NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE; + if (trig[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) + *wowl |= _NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP; + + return NL_SKIP; +} + +static _NMSettingWirelessWakeOnWLan +wifi_nl80211_get_wake_on_wlan(NMWifiUtils *data) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + _NMSettingWirelessWakeOnWLan wowl = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + nm_auto_nlmsg struct nl_msg *msg = NULL; + + msg = nl80211_alloc_msg(self, NL80211_CMD_GET_WOWLAN, 0); + + nl80211_send_and_recv(self, msg, nl80211_get_wake_on_wlan_handler, &wowl); + + return wowl; +} + +static gboolean +wifi_nl80211_set_wake_on_wlan(NMWifiUtils *data, _NMSettingWirelessWakeOnWLan wowl) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nlattr * triggers; + int err; + + if (wowl == _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) + return TRUE; + + msg = nl80211_alloc_msg(self, NL80211_CMD_SET_WOWLAN, 0); + + triggers = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); + if (!triggers) + goto nla_put_failure; + + if (NM_FLAGS_HAS(wowl, _NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY)) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY); + if (NM_FLAGS_HAS(wowl, _NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT)) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); + if (NM_FLAGS_HAS(wowl, _NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC)) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); + if (NM_FLAGS_HAS(wowl, _NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE)) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE); + if (NM_FLAGS_HAS(wowl, _NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST)) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST); + if (NM_FLAGS_HAS(wowl, _NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE)) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE); + if (NM_FLAGS_HAS(wowl, _NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE)) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE); + + nla_nest_end(msg, triggers); + + err = nl80211_send_and_recv(self, msg, NULL, NULL); + + return err >= 0; + +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static guint32 +wifi_nl80211_get_freq(NMWifiUtils *data) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + struct nl80211_iface_info iface_info = {}; + nm_auto_nlmsg struct nl_msg *msg = NULL; + + msg = nl80211_alloc_msg(self, NL80211_CMD_GET_INTERFACE, 0); + + if (nl80211_send_and_recv(self, msg, nl80211_iface_info_handler, &iface_info) < 0) + return 0; + + return iface_info.freq; +} + +static guint32 +wifi_nl80211_find_freq(NMWifiUtils *data, const guint32 *freqs) +{ + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; + int i; + + for (i = 0; i < self->num_freqs; i++) { + while (*freqs) { + if (self->freqs[i] == *freqs) + return *freqs; + freqs++; + } + } + return 0; +} + +/* @divisor: pass what value @xbm should be divided by to get dBm */ +static guint32 +nl80211_xbm_to_percent(gint32 xbm, guint32 divisor) +{ +#define NOISE_FLOOR_DBM -90 +#define SIGNAL_MAX_DBM -20 + + xbm /= divisor; + xbm = CLAMP(xbm, NOISE_FLOOR_DBM, SIGNAL_MAX_DBM); + + return 100 + - 70 + * (((float) SIGNAL_MAX_DBM - (float) xbm) + / ((float) SIGNAL_MAX_DBM - (float) NOISE_FLOOR_DBM)); +} + +struct nl80211_station_info { + gboolean valid; + guint8 bssid[ETH_ALEN]; + guint32 txrate; + gboolean txrate_valid; + guint8 signal; + gboolean signal_valid; +}; + +static int +nl80211_station_dump_handler(struct nl_msg *msg, void *arg) +{ + static const struct nla_policy stats_policy[] = { + [NL80211_STA_INFO_INACTIVE_TIME] = {.type = NLA_U32}, + [NL80211_STA_INFO_RX_BYTES] = {.type = NLA_U32}, + [NL80211_STA_INFO_TX_BYTES] = {.type = NLA_U32}, + [NL80211_STA_INFO_RX_PACKETS] = {.type = NLA_U32}, + [NL80211_STA_INFO_TX_PACKETS] = {.type = NLA_U32}, + [NL80211_STA_INFO_SIGNAL] = {.type = NLA_U8}, + [NL80211_STA_INFO_TX_BITRATE] = {.type = NLA_NESTED}, + [NL80211_STA_INFO_LLID] = {.type = NLA_U16}, + [NL80211_STA_INFO_PLID] = {.type = NLA_U16}, + [NL80211_STA_INFO_PLINK_STATE] = {.type = NLA_U8}, + [NL80211_STA_INFO_STA_FLAGS] = {.minlen = sizeof(struct nl80211_sta_flag_update)}, + [NL80211_STA_INFO_BEACON_SIGNAL_AVG] = {.type = NLA_U8}, + }; + static const struct nla_policy rate_policy[] = { + [NL80211_RATE_INFO_BITRATE] = {.type = NLA_U16}, + [NL80211_RATE_INFO_MCS] = {.type = NLA_U8}, + [NL80211_RATE_INFO_40_MHZ_WIDTH] = {.type = NLA_FLAG}, + [NL80211_RATE_INFO_SHORT_GI] = {.type = NLA_FLAG}, + }; + struct nlattr * rinfo[G_N_ELEMENTS(rate_policy)]; + struct nlattr * sinfo[G_N_ELEMENTS(stats_policy)]; + struct nl80211_station_info *info = arg; + struct nlattr * tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr * gnlh = nlmsg_data(nlmsg_hdr(msg)); + + if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0) + return NL_SKIP; + + if (tb[NL80211_ATTR_MAC] == NULL) + return NL_SKIP; + + if (tb[NL80211_ATTR_STA_INFO] == NULL) + return NL_SKIP; + + if (nla_parse_nested_arr(sinfo, tb[NL80211_ATTR_STA_INFO], stats_policy)) + return NL_SKIP; + + if (sinfo[NL80211_STA_INFO_STA_FLAGS] != NULL) { + const struct nl80211_sta_flag_update *flags = nla_data(sinfo[NL80211_STA_INFO_STA_FLAGS]); + + if (flags->mask & ~flags->set & (1 << NL80211_STA_FLAG_ASSOCIATED)) + return NL_SKIP; + } + + memcpy(info->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN); + info->valid = TRUE; + + if (sinfo[NL80211_STA_INFO_TX_BITRATE] != NULL + && !nla_parse_nested_arr(rinfo, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy) + && rinfo[NL80211_RATE_INFO_BITRATE] != NULL) { + /* convert from nl80211's units of 100kbps to NM's kbps */ + info->txrate = nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]) * 100; + info->txrate_valid = TRUE; + } + + if (sinfo[NL80211_STA_INFO_SIGNAL] != NULL) { + info->signal = + nl80211_xbm_to_percent((gint8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]), 1); + info->signal_valid = TRUE; + } else if (sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG] != NULL) { + /* Fall back to beacon signal strength */ + info->signal = + nl80211_xbm_to_percent((gint8) nla_get_u8(sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG]), + 1); + info->signal_valid = TRUE; + } + + return NL_SKIP; +} + +static gboolean +wifi_nl80211_get_station(NMWifiUtils *data, + NMEtherAddr *out_bssid, + int * out_quality, + guint32 * out_rate) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl80211_station_info sta_info = {}; + + msg = nl80211_alloc_msg(self, NL80211_CMD_GET_STATION, NLM_F_DUMP); + + nl80211_send_and_recv(self, msg, nl80211_station_dump_handler, &sta_info); + + if (!sta_info.valid || (out_quality && !sta_info.signal_valid) + || (out_rate && !sta_info.txrate_valid)) + return FALSE; + + if (out_bssid) + memcpy(out_bssid, sta_info.bssid, ETH_ALEN); + + if (out_quality) + *out_quality = sta_info.signal; + + if (out_rate) + *out_rate = sta_info.txrate; + + return TRUE; +} + +static gboolean +wifi_nl80211_indicate_addressing_running(NMWifiUtils *data, gboolean running) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + msg = nl80211_alloc_msg(self, + running ? 98 /* NL80211_CMD_CRIT_PROTOCOL_START */ + : 99 /* NL80211_CMD_CRIT_PROTOCOL_STOP */, + 0); + /* Despite the DHCP name, we're using this for any type of IP addressing, + * DHCPv4, DHCPv6, and IPv6 SLAAC. + */ + NLA_PUT_U16(msg, 179 /* NL80211_ATTR_CRIT_PROT_ID */, 1 /* NL80211_CRIT_PROTO_DHCP */); + if (running) { + /* Give DHCP 5 seconds to complete */ + NLA_PUT_U16(msg, 180 /* NL80211_ATTR_MAX_CRIT_PROT_DURATION */, 5000); + } + + err = nl80211_send_and_recv(self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +struct nl80211_device_info { + NMWifiUtilsNl80211 *self; + int phy; + guint32 * freqs; + int num_freqs; + guint32 freq; + guint32 caps; + gboolean can_scan; + gboolean can_scan_ssid; + gboolean supported; + gboolean success; + gboolean can_wowlan; +}; + +#define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00 +#define WLAN_CIPHER_SUITE_WEP40 0x000FAC01 +#define WLAN_CIPHER_SUITE_TKIP 0x000FAC02 +#define WLAN_CIPHER_SUITE_CCMP 0x000FAC04 +#define WLAN_CIPHER_SUITE_WEP104 0x000FAC05 +#define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06 +#define WLAN_CIPHER_SUITE_GCMP 0x000FAC08 +#define WLAN_CIPHER_SUITE_SMS4 0x00147201 + +static int +nl80211_wiphy_info_handler(struct nl_msg *msg, void *arg) +{ + static const struct nla_policy freq_policy[] = { + [NL80211_FREQUENCY_ATTR_FREQ] = {.type = NLA_U32}, + [NL80211_FREQUENCY_ATTR_DISABLED] = {.type = NLA_FLAG}, +#ifdef NL80211_FREQUENCY_ATTR_NO_IR + [NL80211_FREQUENCY_ATTR_NO_IR] = {.type = NLA_FLAG}, +#else + [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = {.type = NLA_FLAG}, + [NL80211_FREQUENCY_ATTR_NO_IBSS] = {.type = NLA_FLAG}, +#endif + [NL80211_FREQUENCY_ATTR_RADAR] = {.type = NLA_FLAG}, + [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = {.type = NLA_U32}, + }; + struct nlattr * tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr * gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nl80211_device_info *info = arg; + NMWifiUtilsNl80211 * self = info->self; + struct nlattr * tb_band[NL80211_BAND_ATTR_MAX + 1]; + struct nlattr * tb_freq[G_N_ELEMENTS(freq_policy)]; + struct nlattr * nl_band; + struct nlattr * nl_freq; + int rem_freq; + int rem_band; + int freq_idx; + +#ifdef NL80211_FREQUENCY_ATTR_NO_IR + G_STATIC_ASSERT_EXPR(NL80211_FREQUENCY_ATTR_PASSIVE_SCAN == NL80211_FREQUENCY_ATTR_NO_IR + && NL80211_FREQUENCY_ATTR_NO_IBSS == NL80211_FREQUENCY_ATTR_NO_IR); +#else + G_STATIC_ASSERT_EXPR(NL80211_FREQUENCY_ATTR_PASSIVE_SCAN != NL80211_FREQUENCY_ATTR_NO_IBSS); +#endif + + if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0) + return NL_SKIP; + + if (tb[NL80211_ATTR_WIPHY] == NULL || tb[NL80211_ATTR_WIPHY_BANDS] == NULL) + return NL_SKIP; + + info->phy = nla_get_u32(tb[NL80211_ATTR_WIPHY]); + + if (tb[NL80211_ATTR_WIPHY_FREQ]) + info->freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]); + else + info->freq = 0; + + if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) { + info->can_scan_ssid = nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) > 0; + } else { + /* old kernel that only had mac80211, so assume it can */ + info->can_scan_ssid = TRUE; + } + + if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) { + struct nlattr *nl_cmd; + int i; + + nla_for_each_nested (nl_cmd, tb[NL80211_ATTR_SUPPORTED_COMMANDS], i) { + switch (nla_get_u32(nl_cmd)) { + case NL80211_CMD_TRIGGER_SCAN: + info->can_scan = TRUE; + break; + case NL80211_CMD_CONNECT: + case NL80211_CMD_AUTHENTICATE: + /* Only devices that support CONNECT or AUTH actually support + * 802.11, unlike say ipw2x00 (up to at least kernel 3.4) which + * has minimal info support, but no actual command support. + * This check mirrors what wpa_supplicant does to determine + * whether or not to use the nl80211 driver. + */ + info->supported = TRUE; + break; + default: + break; + } + } + } + + /* Find number of supported frequencies */ + info->num_freqs = 0; + + nla_for_each_nested (nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) { + if (nla_parse_nested_arr(tb_band, nl_band, NULL) < 0) + return NL_SKIP; + + nla_for_each_nested (nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) { + if (nla_parse_nested_arr(tb_freq, nl_freq, freq_policy) < 0) + continue; + + if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) + continue; + + info->num_freqs++; + } + } + + /* Read supported frequencies */ + info->freqs = g_malloc0(sizeof(guint32) * info->num_freqs); + + freq_idx = 0; + nla_for_each_nested (nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) { + if (nla_parse_nested_arr(tb_band, nl_band, NULL) < 0) + return NL_SKIP; + + nla_for_each_nested (nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) { + if (nla_parse_nested_arr(tb_freq, nl_freq, freq_policy) < 0) + continue; + + if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) + continue; + + info->freqs[freq_idx] = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); + + info->caps |= _NM_WIFI_DEVICE_CAP_FREQ_VALID; + + if (info->freqs[freq_idx] > 2400 && info->freqs[freq_idx] < 2500) + info->caps |= _NM_WIFI_DEVICE_CAP_FREQ_2GHZ; + if (info->freqs[freq_idx] > 4900 && info->freqs[freq_idx] < 6000) + info->caps |= _NM_WIFI_DEVICE_CAP_FREQ_5GHZ; + + freq_idx++; + } + } + + /* Read security/encryption support */ + if (tb[NL80211_ATTR_CIPHER_SUITES]) { + guint32 *ciphers = nla_data(tb[NL80211_ATTR_CIPHER_SUITES]); + guint i, num; + + num = nla_len(tb[NL80211_ATTR_CIPHER_SUITES]) / sizeof(guint32); + for (i = 0; i < num; i++) { + switch (ciphers[i]) { + case WLAN_CIPHER_SUITE_WEP40: + info->caps |= _NM_WIFI_DEVICE_CAP_CIPHER_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + info->caps |= _NM_WIFI_DEVICE_CAP_CIPHER_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + info->caps |= (_NM_WIFI_DEVICE_CAP_CIPHER_TKIP | _NM_WIFI_DEVICE_CAP_WPA); + break; + case WLAN_CIPHER_SUITE_CCMP: + info->caps |= (_NM_WIFI_DEVICE_CAP_CIPHER_CCMP | _NM_WIFI_DEVICE_CAP_RSN); + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_SMS4: + break; + default: + _LOGD("don't know the meaning of NL80211_ATTR_CIPHER_SUITE %#8.8x.", ciphers[i]); + break; + } + } + } + + if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) { + struct nlattr *nl_mode; + int i; + + nla_for_each_nested (nl_mode, tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) { + switch (nla_type(nl_mode)) { + case NL80211_IFTYPE_AP: + info->caps |= _NM_WIFI_DEVICE_CAP_AP; + break; + case NL80211_IFTYPE_ADHOC: + info->caps |= _NM_WIFI_DEVICE_CAP_ADHOC; + break; + case NL80211_IFTYPE_MESH_POINT: + info->caps |= _NM_WIFI_DEVICE_CAP_MESH; + break; + } + } + } + + if (tb[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED]) + info->can_wowlan = TRUE; + + if (tb[NL80211_ATTR_SUPPORT_IBSS_RSN]) + info->caps |= _NM_WIFI_DEVICE_CAP_IBSS_RSN; + + info->success = TRUE; + + return NL_SKIP; +} + +static guint32 +wifi_nl80211_get_mesh_channel(NMWifiUtils *data) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl80211_device_info device_info = {.self = self}; + int i; + + msg = nl80211_alloc_msg(self, NL80211_CMD_GET_WIPHY, 0); + + if (nl80211_send_and_recv(self, msg, nl80211_wiphy_info_handler, &device_info) < 0) { + _LOGW("NL80211_CMD_GET_WIPHY request failed"); + return 0; + } + + for (i = 0; i < self->num_freqs; i++) { + if (device_info.freq == self->freqs[i]) + return i + 1; + } + return 0; +} + +static gboolean +wifi_nl80211_set_mesh_channel(NMWifiUtils *data, guint32 channel) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + if (channel > self->num_freqs) + return FALSE; + + msg = nl80211_alloc_msg(self, NL80211_CMD_SET_WIPHY, 0); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, self->freqs[channel - 1]); + err = nl80211_send_and_recv(self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static gboolean +wifi_nl80211_set_mesh_ssid(NMWifiUtils *data, const guint8 *ssid, gsize len) +{ + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + msg = nl80211_alloc_msg(self, NL80211_CMD_SET_INTERFACE, 0); + NLA_PUT(msg, NL80211_ATTR_MESH_ID, len, ssid); + err = nl80211_send_and_recv(self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +static void +nm_wifi_utils_nl80211_init(NMWifiUtilsNl80211 *self) +{} + +static void +nm_wifi_utils_nl80211_class_init(NMWifiUtilsNl80211Class *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMWifiUtilsClass *wifi_utils_class = NM_WIFI_UTILS_CLASS(klass); + + object_class->dispose = dispose; + + wifi_utils_class->get_mode = wifi_nl80211_get_mode; + wifi_utils_class->set_mode = wifi_nl80211_set_mode; + wifi_utils_class->set_powersave = wifi_nl80211_set_powersave; + wifi_utils_class->get_wake_on_wlan = wifi_nl80211_get_wake_on_wlan, + wifi_utils_class->set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan, + wifi_utils_class->get_freq = wifi_nl80211_get_freq; + wifi_utils_class->find_freq = wifi_nl80211_find_freq; + wifi_utils_class->get_station = wifi_nl80211_get_station; + wifi_utils_class->indicate_addressing_running = wifi_nl80211_indicate_addressing_running; + wifi_utils_class->get_mesh_channel = wifi_nl80211_get_mesh_channel; + wifi_utils_class->set_mesh_channel = wifi_nl80211_set_mesh_channel; + wifi_utils_class->set_mesh_ssid = wifi_nl80211_set_mesh_ssid; +} + +NMWifiUtils * +nm_wifi_utils_nl80211_new(int ifindex, struct nl_sock *genl) +{ + gs_unref_object NMWifiUtilsNl80211 *self = NULL; + nm_auto_nlmsg struct nl_msg * msg = NULL; + struct nl80211_device_info device_info = {}; + + if (!genl) + return NULL; + + self = g_object_new(NM_TYPE_WIFI_UTILS_NL80211, NULL); + + self->parent.ifindex = ifindex; + self->nl_sock = genl; + + self->id = genl_ctrl_resolve(self->nl_sock, "nl80211"); + if (self->id < 0) { + _LOGD("genl_ctrl_resolve: failed to resolve \"nl80211\""); + return NULL; + } + + self->phy = -1; + + msg = nl80211_alloc_msg(self, NL80211_CMD_GET_WIPHY, 0); + + device_info.self = self; + if (nl80211_send_and_recv(self, msg, nl80211_wiphy_info_handler, &device_info) < 0) { + _LOGD("NL80211_CMD_GET_WIPHY request failed"); + return NULL; + } + + if (!device_info.success) { + _LOGD("NL80211_CMD_GET_WIPHY request indicated failure"); + return NULL; + } + + if (!device_info.supported) { + _LOGD("driver does not fully support nl80211, falling back to WEXT"); + return NULL; + } + + if (!device_info.can_scan_ssid) { + _LOGE("driver does not support SSID scans"); + return NULL; + } + + if (device_info.num_freqs == 0 || device_info.freqs == NULL) { + _LOGE("driver reports no supported frequencies"); + return NULL; + } + + if (device_info.caps == 0) { + _LOGE("driver doesn't report support of any encryption"); + return NULL; + } + + self->phy = device_info.phy; + self->freqs = device_info.freqs; + self->num_freqs = device_info.num_freqs; + self->parent.caps = device_info.caps; + self->can_wowlan = device_info.can_wowlan; + + _LOGD("using nl80211 for Wi-Fi device control"); + return (NMWifiUtils *) g_steal_pointer(&self); +} diff --git a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.h b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.h new file mode 100644 index 0000000..4a63330 --- /dev/null +++ b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2011 Intel Corporation. All rights reserved. + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __WIFI_UTILS_NL80211_H__ +#define __WIFI_UTILS_NL80211_H__ + +#include "nm-wifi-utils.h" +#include "libnm-platform/nm-netlink.h" + +#define NM_TYPE_WIFI_UTILS_NL80211 (nm_wifi_utils_nl80211_get_type()) +#define NM_WIFI_UTILS_NL80211(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211)) +#define NM_WIFI_UTILS_NL80211_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211Class)) +#define NM_IS_WIFI_UTILS_NL80211(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WIFI_UTILS_NL80211)) +#define NM_IS_WIFI_UTILS_NL80211_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WIFI_UTILS_NL80211)) +#define NM_WIFI_UTILS_NL80211_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211Class)) + +GType nm_wifi_utils_nl80211_get_type(void); + +NMWifiUtils *nm_wifi_utils_nl80211_new(int ifindex, struct nl_sock *genl); + +#endif /* __WIFI_UTILS_NL80211_H__ */ diff --git a/src/libnm-platform/wifi/nm-wifi-utils-private.h b/src/libnm-platform/wifi/nm-wifi-utils-private.h new file mode 100644 index 0000000..bc1e75e --- /dev/null +++ b/src/libnm-platform/wifi/nm-wifi-utils-private.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2011 - 2018 Red Hat, Inc. + */ + +#ifndef __WIFI_UTILS_PRIVATE_H__ +#define __WIFI_UTILS_PRIVATE_H__ + +#include "nm-wifi-utils.h" + +typedef struct { + GObjectClass parent; + + _NM80211Mode (*get_mode)(NMWifiUtils *data); + + gboolean (*set_mode)(NMWifiUtils *data, const _NM80211Mode mode); + + /* Set power saving mode on an interface */ + gboolean (*set_powersave)(NMWifiUtils *data, guint32 powersave); + + /* Get WakeOnWLAN configuration on an interface */ + _NMSettingWirelessWakeOnWLan (*get_wake_on_wlan)(NMWifiUtils *data); + + /* Set WakeOnWLAN mode on an interface */ + gboolean (*set_wake_on_wlan)(NMWifiUtils *data, _NMSettingWirelessWakeOnWLan wowl); + + /* Return current frequency in MHz (really associated BSS frequency) */ + guint32 (*get_freq)(NMWifiUtils *data); + + /* Return first supported frequency in the zero-terminated list */ + guint32 (*find_freq)(NMWifiUtils *data, const guint32 *freqs); + + /* + * @out_bssid: must be NULL or an ETH_ALEN-byte buffer + * @out_quality: receives signal strength percentage 0 - 100% for the current BSSID, if not NULL + * @out_rate: receives current bitrate in Kbps if not NULL + * + * Returns %TRUE on succcess, %FALSE on errors or if not associated. + */ + gboolean (*get_station)(NMWifiUtils *data, + NMEtherAddr *out_bssid, + int * out_quality, + guint32 * out_rate); + + /* OLPC Mesh-only functions */ + + guint32 (*get_mesh_channel)(NMWifiUtils *data); + + /* channel == 0 means "auto channel" */ + gboolean (*set_mesh_channel)(NMWifiUtils *data, guint32 channel); + + /* ssid == NULL means "auto SSID" */ + gboolean (*set_mesh_ssid)(NMWifiUtils *data, const guint8 *ssid, gsize len); + + gboolean (*indicate_addressing_running)(NMWifiUtils *data, gboolean running); +} NMWifiUtilsClass; + +struct NMWifiUtils { + GObject parent; + + int ifindex; + _NMDeviceWifiCapabilities caps; +}; + +#endif /* __WIFI_UTILS_PRIVATE_H__ */ diff --git a/src/libnm-platform/wifi/nm-wifi-utils-wext.c b/src/libnm-platform/wifi/nm-wifi-utils-wext.c new file mode 100644 index 0000000..9da7924 --- /dev/null +++ b/src/libnm-platform/wifi/nm-wifi-utils-wext.c @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-wifi-utils-wext.h" + +#include +#include +#include + +/* Hacks necessary to #include wireless.h; yay for WEXT */ +#ifndef __user + #define __user +#endif +#include +#include +#include +#include + +#include "libnm-log-core/nm-logging.h" +#include "nm-wifi-utils-private.h" +#include "libnm-platform/nm-platform-utils.h" + +typedef struct { + NMWifiUtils parent; + int fd; + struct iw_quality max_qual; + gint8 num_freqs; + guint32 freqs[IW_MAX_FREQUENCIES]; +} NMWifiUtilsWext; + +typedef struct { + NMWifiUtilsClass parent; +} NMWifiUtilsWextClass; + +G_DEFINE_TYPE(NMWifiUtilsWext, nm_wifi_utils_wext, NM_TYPE_WIFI_UTILS) + +/* Until a new wireless-tools comes out that has the defs and the structure, + * need to copy them here. + */ +/* Scan capability flags - in (struct iw_range *)->scan_capa */ +#define NM_IW_SCAN_CAPA_NONE 0x00 +#define NM_IW_SCAN_CAPA_ESSID 0x01 + +struct iw_range_with_scan_capa { + guint32 throughput; + guint32 min_nwid; + guint32 max_nwid; + guint16 old_num_channels; + guint8 old_num_frequency; + + guint8 scan_capa; + /* don't need the rest... */ +}; + +#define _NMLOG_PREFIX_NAME "wifi-wext" +#define _NMLOG(level, domain, ...) \ + G_STMT_START \ + { \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END + +static guint32 +iw_freq_to_uint32(const struct iw_freq *freq) +{ + if (freq->e == 0) { + /* Some drivers report channel not frequency. Convert to a + * frequency; but this assumes that the device is in b/g mode. + */ + if ((freq->m >= 1) && (freq->m <= 13)) + return 2407 + (5 * freq->m); + else if (freq->m == 14) + return 2484; + } + return (guint32)((((double) freq->m) * nm_utils_exp10(freq->e)) / 1000000.0); +} + +static void +dispose(GObject *object) +{ + NMWifiUtilsWext *wext = NM_WIFI_UTILS_WEXT(object); + + wext->fd = nm_close(wext->fd); +} + +static gboolean +get_ifname(int ifindex, char *buffer, const char *op) +{ + int errsv; + + if (!nmp_utils_if_indextoname(ifindex, buffer)) { + errsv = errno; + _LOGW(LOGD_PLATFORM | LOGD_WIFI, + "error getting interface name for ifindex %d, operation '%s': %s (%d)", + ifindex, + op, + nm_strerror_native(errsv), + errsv); + return FALSE; + } + + return TRUE; +} + +static _NM80211Mode +wifi_wext_get_mode_ifname(NMWifiUtils *data, const char *ifname) +{ + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + struct iwreq wrq; + int errsv; + + memset(&wrq, 0, sizeof(struct iwreq)); + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + + if (ioctl(wext->fd, SIOCGIWMODE, &wrq) < 0) { + errsv = errno; + if (errsv != ENODEV) { + _LOGW(LOGD_PLATFORM | LOGD_WIFI, "(%s): error %d getting card mode", ifname, errsv); + } + return _NM_802_11_MODE_UNKNOWN; + } + + switch (wrq.u.mode) { + case IW_MODE_ADHOC: + return _NM_802_11_MODE_ADHOC; + case IW_MODE_MASTER: + return _NM_802_11_MODE_AP; + case IW_MODE_INFRA: + case IW_MODE_AUTO: /* hack for WEXT devices reporting IW_MODE_AUTO */ + return _NM_802_11_MODE_INFRA; + default: + break; + } + return _NM_802_11_MODE_UNKNOWN; +} + +static _NM80211Mode +wifi_wext_get_mode(NMWifiUtils *data) +{ + char ifname[IFNAMSIZ]; + + if (!get_ifname(data->ifindex, ifname, "get-mode")) + return FALSE; + + return wifi_wext_get_mode_ifname(data, ifname); +} + +static gboolean +wifi_wext_set_mode(NMWifiUtils *data, const _NM80211Mode mode) +{ + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + struct iwreq wrq; + char ifname[IFNAMSIZ]; + + if (!get_ifname(data->ifindex, ifname, "set-mode")) + return FALSE; + + if (wifi_wext_get_mode_ifname(data, ifname) == mode) + return TRUE; + + memset(&wrq, 0, sizeof(struct iwreq)); + switch (mode) { + case _NM_802_11_MODE_ADHOC: + wrq.u.mode = IW_MODE_ADHOC; + break; + case _NM_802_11_MODE_AP: + wrq.u.mode = IW_MODE_MASTER; + break; + case _NM_802_11_MODE_INFRA: + wrq.u.mode = IW_MODE_INFRA; + break; + default: + g_warn_if_reached(); + return FALSE; + } + + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + if (ioctl(wext->fd, SIOCSIWMODE, &wrq) < 0) { + if (errno != ENODEV) { + _LOGE(LOGD_PLATFORM | LOGD_WIFI, "(%s): error setting mode %d", ifname, mode); + } + return FALSE; + } + + return TRUE; +} + +static gboolean +wifi_wext_set_powersave(NMWifiUtils *data, guint32 powersave) +{ + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + struct iwreq wrq; + char ifname[IFNAMSIZ]; + + if (!get_ifname(data->ifindex, ifname, "set-powersave")) + return FALSE; + + memset(&wrq, 0, sizeof(struct iwreq)); + if (powersave == 1) { + wrq.u.power.flags = IW_POWER_ALL_R; + } else + wrq.u.power.disabled = 1; + + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + if (ioctl(wext->fd, SIOCSIWPOWER, &wrq) < 0) { + if (errno != ENODEV) { + _LOGE(LOGD_PLATFORM | LOGD_WIFI, + "(%s): error setting powersave %" G_GUINT32_FORMAT, + ifname, + powersave); + } + return FALSE; + } + + return TRUE; +} + +static guint32 +wifi_wext_get_freq(NMWifiUtils *data) +{ + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + struct iwreq wrq; + char ifname[IFNAMSIZ]; + + if (!get_ifname(data->ifindex, ifname, "get-freq")) + return FALSE; + + memset(&wrq, 0, sizeof(struct iwreq)); + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + if (ioctl(wext->fd, SIOCGIWFREQ, &wrq) < 0) { + _LOGW(LOGD_PLATFORM | LOGD_WIFI, + "(%s): error getting frequency: %s", + ifname, + nm_strerror_native(errno)); + return 0; + } + + return iw_freq_to_uint32(&wrq.u.freq); +} + +static guint32 +wifi_wext_find_freq(NMWifiUtils *data, const guint32 *freqs) +{ + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + int i; + + for (i = 0; i < wext->num_freqs; i++) { + while (*freqs) { + if (wext->freqs[i] == *freqs) + return *freqs; + freqs++; + } + } + return 0; +} + +static gboolean +wifi_wext_get_bssid(NMWifiUtils *data, NMEtherAddr *out_bssid) +{ + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + struct iwreq wrq; + char ifname[IFNAMSIZ]; + + if (!get_ifname(data->ifindex, ifname, "get-bssid")) + return FALSE; + + memset(&wrq, 0, sizeof(wrq)); + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + if (ioctl(wext->fd, SIOCGIWAP, &wrq) < 0) { + _LOGW(LOGD_PLATFORM | LOGD_WIFI, + "(%s): error getting associated BSSID: %s", + ifname, + nm_strerror_native(errno)); + return FALSE; + } + memcpy(out_bssid, &(wrq.u.ap_addr.sa_data), ETH_ALEN); + return TRUE; +} + +static guint32 +wifi_wext_get_rate(NMWifiUtils *data) +{ + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + struct iwreq wrq; + int err; + char ifname[IFNAMSIZ]; + + if (!get_ifname(data->ifindex, ifname, "get-rate")) + return FALSE; + + memset(&wrq, 0, sizeof(wrq)); + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + err = ioctl(wext->fd, SIOCGIWRATE, &wrq); + return ((err == 0) ? wrq.u.bitrate.value / 1000 : 0); +} + +static int +wext_qual_to_percent(const struct iw_quality *qual, const struct iw_quality *max_qual) +{ + int percent = -1; + int level_percent = -1; + + g_return_val_if_fail(qual != NULL, -1); + g_return_val_if_fail(max_qual != NULL, -1); + + /* Magically convert the many different WEXT quality representations to a percentage */ + + _LOGD(LOGD_WIFI, + "QL: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X ** MAX: qual " + "%d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X", + (__s8) qual->qual, + qual->qual, + qual->qual, + (__s8) qual->level, + qual->level, + qual->level, + (__s8) qual->noise, + qual->noise, + qual->noise, + qual->updated, + (__s8) max_qual->qual, + max_qual->qual, + max_qual->qual, + (__s8) max_qual->level, + max_qual->level, + max_qual->level, + (__s8) max_qual->noise, + max_qual->noise, + max_qual->noise, + max_qual->updated); + + /* Try using the card's idea of the signal quality first as long as it tells us what the max quality is. + * Drivers that fill in quality values MUST treat them as percentages, ie the "Link Quality" MUST be + * bounded by 0 and max_qual->qual, and MUST change in a linear fashion. Within those bounds, drivers + * are free to use whatever they want to calculate "Link Quality". + */ + if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) + && !(qual->updated & IW_QUAL_QUAL_INVALID)) + percent = (int) (100 * ((double) qual->qual / (double) max_qual->qual)); + + /* If the driver doesn't specify a complete and valid quality, we have two options: + * + * 1) dBm: driver must specify max_qual->level = 0, and have valid values for + * qual->level and (qual->noise OR max_qual->noise) + * 2) raw RSSI: driver must specify max_qual->level > 0, and have valid values for + * qual->level and max_qual->level + * + * This is the WEXT spec. If this interpretation is wrong, I'll fix it. Otherwise, + * If drivers don't conform to it, they are wrong and need to be fixed. + */ + + if ((max_qual->level == 0) + && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level == 0 */ + && !(qual->updated & IW_QUAL_LEVEL_INVALID) /* Must have valid qual->level */ + && (((max_qual->noise > 0) + && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) /* Must have valid max_qual->noise */ + || ((qual->noise > 0) + && !(qual->updated & IW_QUAL_NOISE_INVALID))) /* OR valid qual->noise */ + ) { +/* Absolute power values (dBm) */ + +/* Reasonable fallbacks for dumb drivers that don't specify either level. */ +#define FALLBACK_NOISE_FLOOR_DBM -90 +#define FALLBACK_SIGNAL_MAX_DBM -20 + int max_level = FALLBACK_SIGNAL_MAX_DBM; + int noise = FALLBACK_NOISE_FLOOR_DBM; + int level = qual->level - 0x100; + + level = CLAMP(level, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM); + + if ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID)) + noise = qual->noise - 0x100; + else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) + noise = max_qual->noise - 0x100; + noise = CLAMP(noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM - 1); + + /* A sort of signal-to-noise ratio calculation */ + level_percent = (int) (100 + - 70 + * (((double) max_level - (double) level) + / ((double) max_level - (double) noise))); + _LOGD(LOGD_WIFI, + "QL1: level_percent is %d. max_level %d, level %d, noise_floor %d.", + level_percent, + max_level, + level, + noise); + } else if ((max_qual->level != 0) + && !(max_qual->updated + & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level as upper bound */ + && !(qual->updated & IW_QUAL_LEVEL_INVALID)) { + /* Relative power values (RSSI) */ + + int level = qual->level; + + /* Signal level is relavtive (0 -> max_qual->level) */ + level = CLAMP(level, 0, max_qual->level); + level_percent = (int) (100 * ((double) level / (double) max_qual->level)); + _LOGD(LOGD_WIFI, + "QL2: level_percent is %d. max_level %d, level %d.", + level_percent, + max_qual->level, + level); + } else if (percent == -1) { + _LOGD(LOGD_WIFI, + "QL: Could not get quality %% value from driver. Driver is probably buggy."); + } + + /* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */ + if ((percent < 1) && (level_percent >= 0)) + percent = level_percent; + + _LOGD(LOGD_WIFI, "QL: Final quality percent is %d (%d).", percent, CLAMP(percent, 0, 100)); + return (CLAMP(percent, 0, 100)); +} + +static int +wifi_wext_get_qual(NMWifiUtils *data) +{ + NMWifiUtilsWext * wext = (NMWifiUtilsWext *) data; + struct iwreq wrq; + struct iw_statistics stats; + char ifname[IFNAMSIZ]; + + if (!get_ifname(data->ifindex, ifname, "get-qual")) + return FALSE; + + memset(&stats, 0, sizeof(stats)); + wrq.u.data.pointer = &stats; + wrq.u.data.length = sizeof(stats); + wrq.u.data.flags = 1; /* Clear updated flag */ + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + + if (ioctl(wext->fd, SIOCGIWSTATS, &wrq) < 0) { + _LOGW(LOGD_PLATFORM | LOGD_WIFI, + "(%s): error getting signal strength: %s", + ifname, + nm_strerror_native(errno)); + return -1; + } + + return wext_qual_to_percent(&stats.qual, &wext->max_qual); +} + +static gboolean +wifi_wext_get_station(NMWifiUtils *data, + NMEtherAddr *out_bssid, + int * out_quality, + guint32 * out_rate) +{ + NMEtherAddr local_addr; + + if (!out_bssid && !out_quality && !out_rate) { + /* hm, the caller requested no parameter at all? + * Don't simply return TRUE, but at least check that + * we can successfully fetch the bssid. */ + out_bssid = &local_addr; + } + + if (out_bssid) { + if (!wifi_wext_get_bssid(data, out_bssid)) + return FALSE; + } + if (out_quality) { + *out_quality = wifi_wext_get_qual(data); + if (*out_quality < 0) + return FALSE; + } + if (out_rate) { + *out_rate = wifi_wext_get_rate(data); + if (*out_rate == 0) + return FALSE; + } + return TRUE; +} + +/*****************************************************************************/ +/* OLPC Mesh-only functions */ + +static guint32 +wifi_wext_get_mesh_channel(NMWifiUtils *data) +{ + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + guint32 freq; + int i; + + freq = nm_wifi_utils_get_freq(data); + for (i = 0; i < wext->num_freqs; i++) { + if (freq == wext->freqs[i]) + return i + 1; + } + return 0; +} + +static gboolean +wifi_wext_set_mesh_channel(NMWifiUtils *data, guint32 channel) +{ + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + struct iwreq wrq; + char ifname[IFNAMSIZ]; + + if (!get_ifname(data->ifindex, ifname, "set-mesh-channel")) + return FALSE; + + memset(&wrq, 0, sizeof(struct iwreq)); + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + + if (channel > 0) { + wrq.u.freq.flags = IW_FREQ_FIXED; + wrq.u.freq.e = 0; + wrq.u.freq.m = channel; + } + + if (ioctl(wext->fd, SIOCSIWFREQ, &wrq) < 0) { + _LOGE(LOGD_PLATFORM | LOGD_WIFI | LOGD_OLPC, + "(%s): error setting channel to %d: %s", + ifname, + channel, + nm_strerror_native(errno)); + return FALSE; + } + + return TRUE; +} + +static gboolean +wifi_wext_set_mesh_ssid(NMWifiUtils *data, const guint8 *ssid, gsize len) +{ + NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + struct iwreq wrq; + char buf[IW_ESSID_MAX_SIZE + 1]; + char ifname[IFNAMSIZ]; + int errsv; + + if (!get_ifname(data->ifindex, ifname, "set-mesh-ssid")) + return FALSE; + + memset(buf, 0, sizeof(buf)); + memcpy(buf, ssid, MIN(sizeof(buf) - 1, len)); + + wrq.u.essid.pointer = (caddr_t) buf; + wrq.u.essid.length = len; + wrq.u.essid.flags = (len > 0) ? 1 : 0; /* 1=enable SSID, 0=disable/any */ + + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + if (ioctl(wext->fd, SIOCSIWESSID, &wrq) == 0) + return TRUE; + + errsv = errno; + if (errsv != ENODEV) { + gs_free char *ssid_str = NULL; + + _LOGE(LOGD_PLATFORM | LOGD_WIFI | LOGD_OLPC, + "(%s): error setting SSID to %s: %s", + ifname, + (ssid_str = _nm_utils_ssid_to_string_arr(ssid, len)), + nm_strerror_native(errsv)); + } + + return FALSE; +} + +/*****************************************************************************/ + +static gboolean +wext_can_scan_ifname(NMWifiUtilsWext *wext, const char *ifname) +{ + struct iwreq wrq; + + memset(&wrq, 0, sizeof(struct iwreq)); + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + if (ioctl(wext->fd, SIOCSIWSCAN, &wrq) < 0) { + if (errno == EOPNOTSUPP) + return FALSE; + } + return TRUE; +} + +static gboolean +wext_get_range_ifname(NMWifiUtilsWext *wext, + const char * ifname, + struct iw_range *range, + guint32 * response_len) +{ + int i = 26; + gboolean success = FALSE; + struct iwreq wrq; + int errsv; + + memset(&wrq, 0, sizeof(struct iwreq)); + nm_utils_ifname_cpy(wrq.ifr_name, ifname); + wrq.u.data.pointer = (caddr_t) range; + wrq.u.data.length = sizeof(struct iw_range); + + /* Need to give some drivers time to recover after suspend/resume + * (ex ipw3945 takes a few seconds to talk to its regulatory daemon; + * see rh bz#362421) + */ + while (i-- > 0) { + if (ioctl(wext->fd, SIOCGIWRANGE, &wrq) == 0) { + if (response_len) + *response_len = wrq.u.data.length; + success = TRUE; + break; + } else { + errsv = errno; + if (errsv != EAGAIN) { + _LOGE(LOGD_PLATFORM | LOGD_WIFI, + "(%s): couldn't get driver range information (%d).", + ifname, + errsv); + break; + } + } + + g_usleep(G_USEC_PER_SEC / 4); + } + + if (i <= 0) { + _LOGW(LOGD_PLATFORM | LOGD_WIFI, + "(%s): driver took too long to respond to IWRANGE query.", + ifname); + } + + return success; +} + +#define WPA_CAPS \ + (_NM_WIFI_DEVICE_CAP_CIPHER_TKIP | _NM_WIFI_DEVICE_CAP_CIPHER_CCMP | _NM_WIFI_DEVICE_CAP_WPA \ + | _NM_WIFI_DEVICE_CAP_RSN) + +static guint32 +wext_get_caps(NMWifiUtilsWext *wext, const char *ifname, struct iw_range *range) +{ + guint32 caps = _NM_WIFI_DEVICE_CAP_NONE; + + g_return_val_if_fail(wext != NULL, _NM_WIFI_DEVICE_CAP_NONE); + g_return_val_if_fail(range != NULL, _NM_WIFI_DEVICE_CAP_NONE); + + /* All drivers should support WEP by default */ + caps |= _NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | _NM_WIFI_DEVICE_CAP_CIPHER_WEP104; + + if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP) + caps |= _NM_WIFI_DEVICE_CAP_CIPHER_TKIP; + + if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP) + caps |= _NM_WIFI_DEVICE_CAP_CIPHER_CCMP; + + if (range->enc_capa & IW_ENC_CAPA_WPA) + caps |= _NM_WIFI_DEVICE_CAP_WPA; + + if (range->enc_capa & IW_ENC_CAPA_WPA2) + caps |= _NM_WIFI_DEVICE_CAP_RSN; + + /* Check for cipher support but not WPA support */ + if ((caps & (_NM_WIFI_DEVICE_CAP_CIPHER_TKIP | _NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + && !(caps & (_NM_WIFI_DEVICE_CAP_WPA | _NM_WIFI_DEVICE_CAP_RSN))) { + _LOGW(LOGD_WIFI, + "%s: device supports WPA ciphers but not WPA protocol; WPA unavailable.", + ifname); + caps &= ~WPA_CAPS; + } + + /* Check for WPA support but not cipher support */ + if ((caps & (_NM_WIFI_DEVICE_CAP_WPA | _NM_WIFI_DEVICE_CAP_RSN)) + && !(caps & (_NM_WIFI_DEVICE_CAP_CIPHER_TKIP | _NM_WIFI_DEVICE_CAP_CIPHER_CCMP))) { + _LOGW(LOGD_WIFI, + "%s: device supports WPA protocol but not WPA ciphers; WPA unavailable.", + ifname); + caps &= ~WPA_CAPS; + } + + /* There's no way to detect Ad-Hoc/AP mode support with WEXT + * (other than actually trying to do it), so just assume that + * Ad-Hoc is supported and AP isn't. + */ + caps |= _NM_WIFI_DEVICE_CAP_ADHOC; + + return caps; +} + +/*****************************************************************************/ + +static void +nm_wifi_utils_wext_init(NMWifiUtilsWext *self) +{} + +static void +nm_wifi_utils_wext_class_init(NMWifiUtilsWextClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMWifiUtilsClass *wifi_utils_class = NM_WIFI_UTILS_CLASS(klass); + + object_class->dispose = dispose; + + wifi_utils_class->get_mode = wifi_wext_get_mode; + wifi_utils_class->set_mode = wifi_wext_set_mode; + wifi_utils_class->set_powersave = wifi_wext_set_powersave; + wifi_utils_class->get_freq = wifi_wext_get_freq; + wifi_utils_class->find_freq = wifi_wext_find_freq; + wifi_utils_class->get_station = wifi_wext_get_station; + wifi_utils_class->get_mesh_channel = wifi_wext_get_mesh_channel; + wifi_utils_class->set_mesh_channel = wifi_wext_set_mesh_channel; + wifi_utils_class->set_mesh_ssid = wifi_wext_set_mesh_ssid; +} + +NMWifiUtils * +nm_wifi_utils_wext_new(int ifindex, gboolean check_scan) +{ + NMWifiUtilsWext * wext; + struct iw_range range; + guint32 response_len = 0; + struct iw_range_with_scan_capa *scan_capa_range; + int i; + gboolean freq_valid = FALSE, has_5ghz = FALSE, has_2ghz = FALSE; + char ifname[IFNAMSIZ]; + + if (!nmp_utils_if_indextoname(ifindex, ifname)) { + _LOGW(LOGD_PLATFORM | LOGD_WIFI, "can't determine interface name for ifindex %d", ifindex); + return NULL; + } + + wext = g_object_new(NM_TYPE_WIFI_UTILS_WEXT, NULL); + + wext->parent.ifindex = ifindex; + wext->fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (wext->fd < 0) + goto error; + + memset(&range, 0, sizeof(struct iw_range)); + if (wext_get_range_ifname(wext, ifname, &range, &response_len) == FALSE) { + _LOGI(LOGD_PLATFORM | LOGD_WIFI, "(%s): driver WEXT range request failed", ifname); + goto error; + } + + if ((response_len < 300) || (range.we_version_compiled < 21)) { + _LOGI(LOGD_PLATFORM | LOGD_WIFI, + "(%s): driver WEXT version too old (got %d, expected >= 21)", + ifname, + range.we_version_compiled); + goto error; + } + + wext->max_qual.qual = range.max_qual.qual; + wext->max_qual.level = range.max_qual.level; + wext->max_qual.noise = range.max_qual.noise; + wext->max_qual.updated = range.max_qual.updated; + + wext->num_freqs = MIN(range.num_frequency, IW_MAX_FREQUENCIES); + for (i = 0; i < wext->num_freqs; i++) { + wext->freqs[i] = iw_freq_to_uint32(&range.freq[i]); + freq_valid = TRUE; + if (wext->freqs[i] > 2400 && wext->freqs[i] < 2500) + has_2ghz = TRUE; + else if (wext->freqs[i] > 4900 && wext->freqs[i] < 6000) + has_5ghz = TRUE; + } + + /* Check for scanning capability; cards that can't scan are not supported */ + if (check_scan && (wext_can_scan_ifname(wext, ifname) == FALSE)) { + _LOGI(LOGD_PLATFORM | LOGD_WIFI, "(%s): drivers that cannot scan are unsupported", ifname); + goto error; + } + + /* Check for the ability to scan specific SSIDs. Until the scan_capa + * field gets added to wireless-tools, need to work around that by casting + * to the custom structure. + */ + scan_capa_range = (struct iw_range_with_scan_capa *) ⦥ + if (scan_capa_range->scan_capa & NM_IW_SCAN_CAPA_ESSID) { + _LOGI(LOGD_PLATFORM | LOGD_WIFI, + "(%s): driver supports SSID scans (scan_capa 0x%02X).", + ifname, + scan_capa_range->scan_capa); + } else { + _LOGI(LOGD_PLATFORM | LOGD_WIFI, + "(%s): driver does not support SSID scans (scan_capa 0x%02X).", + ifname, + scan_capa_range->scan_capa); + } + + wext->parent.caps = wext_get_caps(wext, ifname, &range); + if (freq_valid) + wext->parent.caps |= _NM_WIFI_DEVICE_CAP_FREQ_VALID; + if (has_2ghz) + wext->parent.caps |= _NM_WIFI_DEVICE_CAP_FREQ_2GHZ; + if (has_5ghz) + wext->parent.caps |= _NM_WIFI_DEVICE_CAP_FREQ_5GHZ; + + _LOGI(LOGD_PLATFORM | LOGD_WIFI, "(%s): using WEXT for Wi-Fi device control", ifname); + + return (NMWifiUtils *) wext; + +error: + g_object_unref(wext); + return NULL; +} + +gboolean +nm_wifi_utils_wext_is_wifi(const char *iface) +{ + int fd; + struct iwreq iwr; + gboolean is_wifi = FALSE; + + /* performing an ioctl on a non-existing name may cause the automatic + * loading of kernel modules, which should be avoided. + * + * Usually, we should thus make sure that an interface with this name + * exists. + * + * Note that wifi_wext_is_wifi() has only one caller which just verified + * that an interface with this name exists. + */ + + fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd >= 0) { + nm_utils_ifname_cpy(iwr.ifr_ifrn.ifrn_name, iface); + if (ioctl(fd, SIOCGIWNAME, &iwr) == 0) + is_wifi = TRUE; + nm_close(fd); + } + return is_wifi; +} diff --git a/src/libnm-platform/wifi/nm-wifi-utils-wext.h b/src/libnm-platform/wifi/nm-wifi-utils-wext.h new file mode 100644 index 0000000..d6f3453 --- /dev/null +++ b/src/libnm-platform/wifi/nm-wifi-utils-wext.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2011 - 2018 Red Hat, Inc. + */ + +#ifndef __WIFI_UTILS_WEXT_H__ +#define __WIFI_UTILS_WEXT_H__ + +#include "nm-wifi-utils.h" + +#define NM_TYPE_WIFI_UTILS_WEXT (nm_wifi_utils_wext_get_type()) +#define NM_WIFI_UTILS_WEXT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWext)) +#define NM_WIFI_UTILS_WEXT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWextClass)) +#define NM_IS_WIFI_UTILS_WEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WIFI_UTILS_WEXT)) +#define NM_IS_WIFI_UTILS_WEXT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WIFI_UTILS_WEXT)) +#define NM_WIFI_UTILS_WEXT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWextClass)) + +GType nm_wifi_utils_wext_get_type(void); + +NMWifiUtils *nm_wifi_utils_wext_new(int ifindex, gboolean check_scan); + +gboolean nm_wifi_utils_wext_is_wifi(const char *iface); + +#endif /* __WIFI_UTILS_WEXT_H__ */ diff --git a/src/libnm-platform/wifi/nm-wifi-utils.c b/src/libnm-platform/wifi/nm-wifi-utils.c new file mode 100644 index 0000000..3c952b6 --- /dev/null +++ b/src/libnm-platform/wifi/nm-wifi-utils.c @@ -0,0 +1,209 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-wifi-utils.h" + +#include +#include +#include + +#include "nm-wifi-utils-private.h" +#include "nm-wifi-utils-nl80211.h" +#if HAVE_WEXT + #include "nm-wifi-utils-wext.h" +#endif +#include "libnm-platform/nm-platform-utils.h" + +G_DEFINE_ABSTRACT_TYPE(NMWifiUtils, nm_wifi_utils, G_TYPE_OBJECT) + +/*****************************************************************************/ + +static void +nm_wifi_utils_init(NMWifiUtils *self) +{} + +static void +nm_wifi_utils_class_init(NMWifiUtilsClass *klass) +{} + +NMWifiUtils * +nm_wifi_utils_new(int ifindex, struct nl_sock *genl, gboolean check_scan) +{ + NMWifiUtils *ret; + + g_return_val_if_fail(ifindex > 0, NULL); + + ret = nm_wifi_utils_nl80211_new(ifindex, genl); + +#if HAVE_WEXT + if (ret == NULL) + ret = nm_wifi_utils_wext_new(ifindex, check_scan); +#endif + + return ret; +} + +_NMDeviceWifiCapabilities +nm_wifi_utils_get_caps(NMWifiUtils *data) +{ + g_return_val_if_fail(data != NULL, _NM_WIFI_DEVICE_CAP_NONE); + + return data->caps; +} + +_NM80211Mode +nm_wifi_utils_get_mode(NMWifiUtils *data) +{ + g_return_val_if_fail(data != NULL, _NM_802_11_MODE_UNKNOWN); + return NM_WIFI_UTILS_GET_CLASS(data)->get_mode(data); +} + +gboolean +nm_wifi_utils_set_mode(NMWifiUtils *data, const _NM80211Mode mode) +{ + NMWifiUtilsClass *klass; + + g_return_val_if_fail(data != NULL, FALSE); + g_return_val_if_fail((mode == _NM_802_11_MODE_INFRA) || (mode == _NM_802_11_MODE_AP) + || (mode == _NM_802_11_MODE_ADHOC) || (mode == _NM_802_11_MODE_MESH), + FALSE); + + klass = NM_WIFI_UTILS_GET_CLASS(data); + + /* nl80211 probably doesn't need this */ + return klass->set_mode ? klass->set_mode(data, mode) : TRUE; +} + +gboolean +nm_wifi_utils_set_powersave(NMWifiUtils *data, guint32 powersave) +{ + NMWifiUtilsClass *klass; + + g_return_val_if_fail(data != NULL, FALSE); + + klass = NM_WIFI_UTILS_GET_CLASS(data); + return klass->set_powersave ? klass->set_powersave(data, powersave) : TRUE; +} + +_NMSettingWirelessWakeOnWLan +nm_wifi_utils_get_wake_on_wlan(NMWifiUtils *data) +{ + NMWifiUtilsClass *klass; + + g_return_val_if_fail(data != NULL, _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE); + + klass = NM_WIFI_UTILS_GET_CLASS(data); + + return klass->get_wake_on_wlan ? klass->get_wake_on_wlan(data) + : _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; +} + +gboolean +nm_wifi_utils_set_wake_on_wlan(NMWifiUtils *data, _NMSettingWirelessWakeOnWLan wowl) +{ + NMWifiUtilsClass *klass; + + g_return_val_if_fail(data != NULL, FALSE); + + klass = NM_WIFI_UTILS_GET_CLASS(data); + return klass->set_wake_on_wlan ? klass->set_wake_on_wlan(data, wowl) : FALSE; +} + +guint32 +nm_wifi_utils_get_freq(NMWifiUtils *data) +{ + g_return_val_if_fail(data != NULL, 0); + return NM_WIFI_UTILS_GET_CLASS(data)->get_freq(data); +} + +guint32 +nm_wifi_utils_find_freq(NMWifiUtils *data, const guint32 *freqs) +{ + g_return_val_if_fail(data != NULL, 0); + g_return_val_if_fail(freqs != NULL, 0); + return NM_WIFI_UTILS_GET_CLASS(data)->find_freq(data, freqs); +} + +gboolean +nm_wifi_utils_get_station(NMWifiUtils *data, + NMEtherAddr *out_bssid, + int * out_quality, + guint32 * out_rate) +{ + g_return_val_if_fail(data != NULL, FALSE); + + return NM_WIFI_UTILS_GET_CLASS(data)->get_station(data, out_bssid, out_quality, out_rate); +} + +gboolean +nm_wifi_utils_is_wifi(int dirfd, const char *ifname) +{ + g_return_val_if_fail(dirfd >= 0, FALSE); + + if (faccessat(dirfd, "phy80211", F_OK, 0) == 0) + return TRUE; +#if HAVE_WEXT + if (nm_wifi_utils_wext_is_wifi(ifname)) + return TRUE; +#endif + return FALSE; +} + +/* OLPC Mesh-only functions */ + +guint32 +nm_wifi_utils_get_mesh_channel(NMWifiUtils *data) +{ + NMWifiUtilsClass *klass; + + g_return_val_if_fail(data != NULL, FALSE); + + klass = NM_WIFI_UTILS_GET_CLASS(data); + g_return_val_if_fail(klass->get_mesh_channel != NULL, FALSE); + + return klass->get_mesh_channel(data); +} + +gboolean +nm_wifi_utils_set_mesh_channel(NMWifiUtils *data, guint32 channel) +{ + NMWifiUtilsClass *klass; + + g_return_val_if_fail(data != NULL, FALSE); + g_return_val_if_fail(channel <= 13, FALSE); + + klass = NM_WIFI_UTILS_GET_CLASS(data); + g_return_val_if_fail(klass->set_mesh_channel != NULL, FALSE); + + return klass->set_mesh_channel(data, channel); +} + +gboolean +nm_wifi_utils_set_mesh_ssid(NMWifiUtils *data, const guint8 *ssid, gsize len) +{ + NMWifiUtilsClass *klass; + + g_return_val_if_fail(data != NULL, FALSE); + + klass = NM_WIFI_UTILS_GET_CLASS(data); + g_return_val_if_fail(klass->set_mesh_ssid != NULL, FALSE); + + return klass->set_mesh_ssid(data, ssid, len); +} + +gboolean +nm_wifi_utils_indicate_addressing_running(NMWifiUtils *data, gboolean running) +{ + NMWifiUtilsClass *klass; + + g_return_val_if_fail(data != NULL, FALSE); + + klass = NM_WIFI_UTILS_GET_CLASS(data); + return klass->indicate_addressing_running ? klass->indicate_addressing_running(data, running) + : FALSE; +} diff --git a/src/libnm-platform/wifi/nm-wifi-utils.h b/src/libnm-platform/wifi/nm-wifi-utils.h new file mode 100644 index 0000000..157522e --- /dev/null +++ b/src/libnm-platform/wifi/nm-wifi-utils.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#ifndef __WIFI_UTILS_H__ +#define __WIFI_UTILS_H__ + +#include + +#include "libnm-platform/nm-netlink.h" +#include "libnm-base/nm-base.h" + +typedef struct NMWifiUtils NMWifiUtils; + +#define NM_TYPE_WIFI_UTILS (nm_wifi_utils_get_type()) +#define NM_WIFI_UTILS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIFI_UTILS, NMWifiUtils)) +#define NM_WIFI_UTILS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WIFI_UTILS, NMWifiUtilsClass)) +#define NM_IS_WIFI_UTILS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WIFI_UTILS)) +#define NM_IS_WIFI_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WIFI_UTILS)) +#define NM_WIFI_UTILS_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WIFI_UTILS, NMWifiUtilsClass)) + +GType nm_wifi_utils_get_type(void); + +gboolean nm_wifi_utils_is_wifi(int dirfd, const char *ifname); + +NMWifiUtils *nm_wifi_utils_new(int ifindex, struct nl_sock *genl, gboolean check_scan); + +_NMDeviceWifiCapabilities nm_wifi_utils_get_caps(NMWifiUtils *data); + +_NM80211Mode nm_wifi_utils_get_mode(NMWifiUtils *data); + +gboolean nm_wifi_utils_set_mode(NMWifiUtils *data, const _NM80211Mode mode); + +/* Returns frequency in MHz */ +guint32 nm_wifi_utils_get_freq(NMWifiUtils *data); + +/* Return the first supported frequency in the zero-terminated list. + * Frequencies are specified in MHz. */ +guint32 nm_wifi_utils_find_freq(NMWifiUtils *data, const guint32 *freqs); + +/* + * @out_bssid: must be NULL or an ETH_ALEN-byte buffer + * @out_quality: receives signal quality in 0 - 100% range if not NULL + * @out_rate: receives current bitrate in Kbps if not NULL + * + * Returns %TRUE on succcess. + */ +gboolean nm_wifi_utils_get_station(NMWifiUtils *data, + NMEtherAddr *out_bssid, + int * out_quality, + guint32 * out_rate); + +/* Tells the driver DHCP or SLAAC is running */ +gboolean nm_wifi_utils_indicate_addressing_running(NMWifiUtils *data, gboolean running); + +gboolean nm_wifi_utils_set_powersave(NMWifiUtils *data, guint32 powersave); + +_NMSettingWirelessWakeOnWLan nm_wifi_utils_get_wake_on_wlan(NMWifiUtils *data); + +gboolean nm_wifi_utils_set_wake_on_wlan(NMWifiUtils *data, _NMSettingWirelessWakeOnWLan wowl); + +/* OLPC Mesh-only functions */ +guint32 nm_wifi_utils_get_mesh_channel(NMWifiUtils *data); + +gboolean nm_wifi_utils_set_mesh_channel(NMWifiUtils *data, guint32 channel); + +gboolean nm_wifi_utils_set_mesh_ssid(NMWifiUtils *data, const guint8 *ssid, gsize len); + +#endif /* __WIFI_UTILS_H__ */ diff --git a/src/libnm-platform/wpan/nm-wpan-utils.c b/src/libnm-platform/wpan/nm-wpan-utils.c new file mode 100644 index 0000000..5c2917b --- /dev/null +++ b/src/libnm-platform/wpan/nm-wpan-utils.c @@ -0,0 +1,287 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-wpan-utils.h" + +#include + +#include "libnm-log-core/nm-logging.h" +#include "libnm-platform/nm-netlink.h" +#include "linux-headers/nl802154.h" +#include "libnm-platform/nm-platform-utils.h" + +#define _NMLOG_PREFIX_NAME "wpan-nl802154" +#define _NMLOG(level, domain, ...) \ + G_STMT_START \ + { \ + char _ifname_buf[IFNAMSIZ]; \ + const char *_ifname = self ? nmp_utils_if_indextoname(self->ifindex, _ifname_buf) : NULL; \ + \ + nm_log((level), \ + (domain), \ + _ifname ?: NULL, \ + NULL, \ + "%s%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + NM_PRINT_FMT_QUOTED(_ifname, " (", _ifname, ")", "") \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END + +/*****************************************************************************/ + +struct NMWpanUtils { + GObject parent; + int ifindex; + struct nl_sock *nl_sock; + int id; +}; + +typedef struct { + GObjectClass parent; +} NMWpanUtilsClass; + +G_DEFINE_TYPE(NMWpanUtils, nm_wpan_utils, G_TYPE_OBJECT) + +/*****************************************************************************/ + +static int +ack_handler(struct nl_msg *msg, void *arg) +{ + int *done = arg; + *done = 1; + return NL_STOP; +} + +static int +finish_handler(struct nl_msg *msg, void *arg) +{ + int *done = arg; + *done = 1; + return NL_SKIP; +} + +static int +error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) +{ + int *done = arg; + *done = err->error; + return NL_SKIP; +} + +static struct nl_msg * +_nl802154_alloc_msg(int id, int ifindex, guint32 cmd, guint32 flags) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + + msg = nlmsg_alloc(); + genlmsg_put(msg, 0, 0, id, 0, flags, cmd, 0); + NLA_PUT_U32(msg, NL802154_ATTR_IFINDEX, ifindex); + return g_steal_pointer(&msg); + +nla_put_failure: + g_return_val_if_reached(NULL); +} + +static struct nl_msg * +nl802154_alloc_msg(NMWpanUtils *self, guint32 cmd, guint32 flags) +{ + return _nl802154_alloc_msg(self->id, self->ifindex, cmd, flags); +} + +static int +nl802154_send_and_recv(NMWpanUtils * self, + struct nl_msg *msg, + int (*valid_handler)(struct nl_msg *, void *), + void *valid_data) +{ + int err; + int done = 0; + const struct nl_cb cb = { + .err_cb = error_handler, + .err_arg = &done, + .finish_cb = finish_handler, + .finish_arg = &done, + .ack_cb = ack_handler, + .ack_arg = &done, + .valid_cb = valid_handler, + .valid_arg = valid_data, + }; + + g_return_val_if_fail(msg != NULL, -ENOMEM); + + err = nl_send_auto(self->nl_sock, msg); + if (err < 0) + return err; + + /* Loop until one of our NL callbacks says we're done; on success + * done will be 1, on error it will be < 0. + */ + while (!done) { + err = nl_recvmsgs(self->nl_sock, &cb); + if (err < 0 && err != -EAGAIN) { + _LOGW(LOGD_PLATFORM, "nl_recvmsgs() error: (%d) %s", err, nm_strerror(err)); + break; + } + } + + if (err >= 0 && done < 0) + err = done; + return err; +} + +struct nl802154_interface { + guint16 pan_id; + guint16 short_addr; + + gboolean valid; +}; + +static int +nl802154_get_interface_handler(struct nl_msg *msg, void *arg) +{ + static const struct nla_policy nl802154_policy[] = { + [NL802154_ATTR_PAN_ID] = {.type = NLA_U16}, + [NL802154_ATTR_SHORT_ADDR] = {.type = NLA_U16}, + }; + struct nlattr * tb[G_N_ELEMENTS(nl802154_policy)]; + struct nl802154_interface *info = arg; + struct genlmsghdr * gnlh = nlmsg_data(nlmsg_hdr(msg)); + + if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), nl802154_policy) < 0) + return NL_SKIP; + + if (tb[NL802154_ATTR_PAN_ID]) + info->pan_id = le16toh(nla_get_u16(tb[NL802154_ATTR_PAN_ID])); + + if (tb[NL802154_ATTR_SHORT_ADDR]) + info->short_addr = le16toh(nla_get_u16(tb[NL802154_ATTR_SHORT_ADDR])); + + info->valid = TRUE; + + return NL_SKIP; +} + +static void +nl802154_get_interface(NMWpanUtils *self, struct nl802154_interface *interface) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + + memset(interface, 0, sizeof(*interface)); + + msg = nl802154_alloc_msg(self, NL802154_CMD_GET_INTERFACE, 0); + + nl802154_send_and_recv(self, msg, nl802154_get_interface_handler, interface); +} + +/*****************************************************************************/ + +guint16 +nm_wpan_utils_get_pan_id(NMWpanUtils *self) +{ + struct nl802154_interface interface; + + nl802154_get_interface(self, &interface); + + return interface.pan_id; +} + +gboolean +nm_wpan_utils_set_pan_id(NMWpanUtils *self, guint16 pan_id) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + g_return_val_if_fail(self != NULL, FALSE); + + msg = nl802154_alloc_msg(self, NL802154_CMD_SET_PAN_ID, 0); + NLA_PUT_U16(msg, NL802154_ATTR_PAN_ID, htole16(pan_id)); + err = nl802154_send_and_recv(self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +guint16 +nm_wpan_utils_get_short_addr(NMWpanUtils *self) +{ + struct nl802154_interface interface; + + nl802154_get_interface(self, &interface); + + return interface.short_addr; +} + +gboolean +nm_wpan_utils_set_short_addr(NMWpanUtils *self, guint16 short_addr) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + g_return_val_if_fail(self != NULL, FALSE); + + msg = nl802154_alloc_msg(self, NL802154_CMD_SET_SHORT_ADDR, 0); + NLA_PUT_U16(msg, NL802154_ATTR_SHORT_ADDR, htole16(short_addr)); + err = nl802154_send_and_recv(self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +gboolean +nm_wpan_utils_set_channel(NMWpanUtils *self, guint8 page, guint8 channel) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + g_return_val_if_fail(self != NULL, FALSE); + + msg = nl802154_alloc_msg(self, NL802154_CMD_SET_CHANNEL, 0); + NLA_PUT_U8(msg, NL802154_ATTR_PAGE, page); + NLA_PUT_U8(msg, NL802154_ATTR_CHANNEL, channel); + err = nl802154_send_and_recv(self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + g_return_val_if_reached(FALSE); +} + +/*****************************************************************************/ + +static void +nm_wpan_utils_init(NMWpanUtils *self) +{} + +static void +nm_wpan_utils_class_init(NMWpanUtilsClass *klass) +{} + +NMWpanUtils * +nm_wpan_utils_new(int ifindex, struct nl_sock *genl, gboolean check_scan) +{ + NMWpanUtils *self; + + g_return_val_if_fail(ifindex > 0, NULL); + + if (!genl) + return NULL; + + self = g_object_new(NM_TYPE_WPAN_UTILS, NULL); + self->ifindex = ifindex; + self->nl_sock = genl; + self->id = genl_ctrl_resolve(genl, "nl802154"); + + if (self->id < 0) { + _LOGD(LOGD_PLATFORM, "genl_ctrl_resolve: failed to resolve \"nl802154\""); + g_object_unref(self); + return NULL; + } + + return self; +} diff --git a/src/libnm-platform/wpan/nm-wpan-utils.h b/src/libnm-platform/wpan/nm-wpan-utils.h new file mode 100644 index 0000000..6130c41 --- /dev/null +++ b/src/libnm-platform/wpan/nm-wpan-utils.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __WPAN_UTILS_H__ +#define __WPAN_UTILS_H__ + +#include + +#include "libnm-platform/nm-netlink.h" + +typedef struct NMWpanUtils NMWpanUtils; + +#define NM_TYPE_WPAN_UTILS (nm_wpan_utils_get_type()) +#define NM_WPAN_UTILS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WPAN_UTILS, NMWpanUtils)) +#define NM_WPAN_UTILS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WPAN_UTILS, NMWpanUtilsClass)) +#define NM_IS_WPAN_UTILS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WPAN_UTILS)) +#define NM_IS_WPAN_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WPAN_UTILS)) +#define NM_WPAN_UTILS_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WPAN_UTILS, NMWpanUtilsClass)) + +GType nm_wpan_utils_get_type(void); + +NMWpanUtils *nm_wpan_utils_new(int ifindex, struct nl_sock *genl, gboolean check_scan); + +guint16 nm_wpan_utils_get_pan_id(NMWpanUtils *self); +gboolean nm_wpan_utils_set_pan_id(NMWpanUtils *self, guint16 pan_id); + +guint16 nm_wpan_utils_get_short_addr(NMWpanUtils *self); +gboolean nm_wpan_utils_set_short_addr(NMWpanUtils *self, guint16 short_addr); + +gboolean nm_wpan_utils_set_channel(NMWpanUtils *self, guint8 page, guint8 channel); + +#endif /* __WPAN_UTILS_H__ */ diff --git a/src/libnm-std-aux/c-list-util.c b/src/libnm-std-aux/c-list-util.c new file mode 100644 index 0000000..d16bd6b --- /dev/null +++ b/src/libnm-std-aux/c-list-util.c @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "c-list-util.h" + +/*****************************************************************************/ + +/** + * c_list_relink: + * @lst: the head list entry + * + * Takes an invalid list, that has undefined prev pointers. + * Only the next pointers are valid, and the tail's next + * pointer points to %NULL instead of the head. + * + * c_list_relink() fixes the list by updating all prev pointers + * and close the circular linking by pointing the tails' next + * pointer to @lst. + * + * The use of this function is to do a bulk update, that lets the + * list degenerate by not updating the prev pointers. At the end, + * the list can be fixed by c_list_relink(). + */ +void +c_list_relink(CList *lst) +{ + CList *ls, *ls_prev; + + ls_prev = lst; + ls = lst->next; + do { + ls->prev = ls_prev; + ls_prev = ls; + ls = ls->next; + } while (ls); + ls_prev->next = lst; + lst->prev = ls_prev; +} + +/*****************************************************************************/ + +static CList * +_c_list_srt_split(CList *ls) +{ + CList *ls2; + + ls2 = ls; + ls = ls->next; + if (!ls) + return NULL; + do { + ls = ls->next; + if (!ls) + break; + ls = ls->next; + ls2 = ls2->next; + } while (ls); + ls = ls2->next; + ls2->next = NULL; + return ls; +} + +static CList * +_c_list_srt_merge(CList *ls1, CList *ls2, CListSortCmp cmp, const void *user_data) +{ + CList *ls; + CList head; + + ls = &head; + for (;;) { + /* while invoking the @cmp function, the list + * elements are not properly linked. Don't try to access + * their next/prev pointers. */ + if (cmp(ls1, ls2, user_data) <= 0) { + ls->next = ls1; + ls = ls1; + ls1 = ls1->next; + if (!ls1) + break; + } else { + ls->next = ls2; + ls = ls2; + ls2 = ls2->next; + if (!ls2) + break; + } + } + ls->next = ls1 ?: ls2; + + return head.next; +} + +typedef struct { + CList *ls1; + CList *ls2; + char ls1_sorted; +} SortStack; + +static CList * +_c_list_sort(CList *ls, CListSortCmp cmp, const void *user_data) +{ + /* reserve a huge stack-size. We need roughly log2(n) entries, hence this + * is much more we will ever need. We don't guard for stack-overflow either. */ + SortStack stack_arr[70]; + SortStack *stack_head = stack_arr; + + stack_arr[0].ls1 = ls; + + /* A simple top-down, non-recursive, stable merge-sort. + * + * Maybe natural merge-sort would be better, to do better for + * partially sorted lists. Doing that would be much more complicated, + * so it's not done. */ +_split: + stack_head[0].ls2 = _c_list_srt_split(stack_head[0].ls1); + if (stack_head[0].ls2) { + stack_head[0].ls1_sorted = 0; + stack_head[1].ls1 = stack_head[0].ls1; + stack_head++; + goto _split; + } + +_backtrack: + if (stack_head == stack_arr) + return stack_arr[0].ls1; + + stack_head--; + if (!stack_head[0].ls1_sorted) { + stack_head[0].ls1 = stack_head[1].ls1; + stack_head[0].ls1_sorted = 1; + stack_head[1].ls1 = stack_head[0].ls2; + stack_head++; + goto _split; + } + + stack_head[0].ls1 = _c_list_srt_merge(stack_head[0].ls1, stack_head[1].ls1, cmp, user_data); + goto _backtrack; +} + +/** + * c_list_sort_headless: + * @lst: the list. + * @cmp: compare function for sorting. While comparing two + * CList elements, their next/prev pointers are in undefined + * state. + * @user_data: user data for @cmp. + * + * Sorts the list @lst according to @cmp. Contrary to + * c_list_sort(), @lst is not the list head but a + * valid entry as well. This function returns the new + * list head. + */ +CList * +c_list_sort_headless(CList *lst, CListSortCmp cmp, const void *user_data) +{ + if (!c_list_is_empty(lst)) { + lst->prev->next = NULL; + lst = _c_list_sort(lst, cmp, user_data); + c_list_relink(lst); + } + return lst; +} + +/** + * c_list_sort: + * @head: the list head. + * @cmp: compare function for sorting. While comparing two + * CList elements, their next/prev pointers are in undefined + * state. + * @user_data: user data for @cmp. + * + * Sorts the list @head according to @cmp. + */ +void +c_list_sort(CList *head, CListSortCmp cmp, const void *user_data) +{ + if (!c_list_is_empty(head) && head->next->next != head) { + head->prev->next = NULL; + head->next = _c_list_sort(head->next, cmp, user_data); + c_list_relink(head); + } +} diff --git a/src/libnm-std-aux/c-list-util.h b/src/libnm-std-aux/c-list-util.h new file mode 100644 index 0000000..9d86d66 --- /dev/null +++ b/src/libnm-std-aux/c-list-util.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __C_LIST_UTIL_H__ +#define __C_LIST_UTIL_H__ + +#include "c-list/src/c-list.h" + +/*****************************************************************************/ + +void c_list_relink(CList *lst); + +typedef int (*CListSortCmp)(const CList *a, const CList *b, const void *user_data); + +CList *c_list_sort_headless(CList *lst, CListSortCmp cmp, const void *user_data); + +void c_list_sort(CList *head, CListSortCmp cmp, const void *user_data); + +/* c_list_length_is: + * @list: the #CList list head + * @check_len: the length to compare + * + * Returns: basically the same as (c_list_length (@list) == @check_len), + * but does not require to iterate the entire list first. There is only + * one real use: to find out whether there is exactly one element in the + * list, by passing @check_len as 1. + */ +static inline int +c_list_length_is(const CList *list, unsigned long check_len) +{ + unsigned long n = 0; + const CList * iter; + + c_list_for_each (iter, list) { + ++n; + if (n > check_len) + return 0; + } + + return n == check_len; +} + +#define c_list_for_each_prev(_iter, _list) \ + for (_iter = (_list)->prev; (_iter) != (_list); _iter = (_iter)->prev) + +#define c_list_for_each_prev_safe(_iter, _safe, _list) \ + for (_iter = (_list)->prev, _safe = (_iter)->prev; (_iter) != (_list); \ + _iter = (_safe), _safe = (_safe)->prev) + +#define c_list_for_each_entry_prev(_iter, _list, _m) \ + for (_iter = c_list_entry((_list)->prev, __typeof__(*_iter), _m); &(_iter)->_m != (_list); \ + _iter = c_list_entry((_iter)->_m.prev, __typeof__(*_iter), _m)) + +#endif /* __C_LIST_UTIL_H__ */ diff --git a/src/libnm-std-aux/meson.build b/src/libnm-std-aux/meson.build new file mode 100644 index 0000000..d7b2452 --- /dev/null +++ b/src/libnm-std-aux/meson.build @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_std_aux = static_library( + 'nm-std-aux', + sources: [ + 'c-list-util.c', + 'nm-std-utils.c', + ], + include_directories: [ + src_inc, + top_inc, + ], +) diff --git a/src/libnm-std-aux/nm-dbus-compat.h b/src/libnm-std-aux/nm-dbus-compat.h new file mode 100644 index 0000000..c107620 --- /dev/null +++ b/src/libnm-std-aux/nm-dbus-compat.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_DBUS_COMPAT_H__ +#define __NM_DBUS_COMPAT_H__ + +#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" + +#define DBUS_PATH_DBUS "/org/freedesktop/DBus" + +#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" +#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" +#define DBUS_INTERFACE_OBJECT_MANAGER "org.freedesktop.DBus.ObjectManager" +#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer" +#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" + +#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 +#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 +#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4 + +#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 +#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 +#define DBUS_REQUEST_NAME_REPLY_EXISTS 3 +#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 + +#endif /* __NM_DBUS_COMPAT_H__ */ diff --git a/src/libnm-std-aux/nm-default-std.h b/src/libnm-std-aux/nm-default-std.h new file mode 100644 index 0000000..5f4af3a --- /dev/null +++ b/src/libnm-std-aux/nm-default-std.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEFAULT_STD_H__ +#define __NM_DEFAULT_STD_H__ + +#include "nm-networkmanager-compilation.h" + +#ifdef NETWORKMANAGER_COMPILATION + #error Dont define NETWORKMANAGER_COMPILATION +#endif + +#ifndef G_LOG_DOMAIN + #define G_LOG_DOMAIN "nm" +#endif + +/*****************************************************************************/ + +#define NETWORKMANAGER_COMPILATION 0 + +/*****************************************************************************/ + +/* always include these headers for our internal source files. */ + +#ifndef ___CONFIG_H__ + #define ___CONFIG_H__ + #include +#endif + +#include "config-extra.h" + +/* for internal compilation we don't want the deprecation macros + * to be in effect. Define the widest range of versions to effectively + * disable deprecation checks */ +#define NM_VERSION_MIN_REQUIRED NM_VERSION_0_9_8 + +#ifndef NM_MORE_ASSERTS + #define NM_MORE_ASSERTS 0 +#endif + +#if NM_MORE_ASSERTS == 0 + /* The cast macros like NM_TYPE() are implemented via G_TYPE_CHECK_INSTANCE_CAST() + * and _G_TYPE_CIC(). The latter, by default performs runtime checks of the type + * by calling g_type_check_instance_cast(). + * This check has a certain overhead without being helpful. + * + * Example 1: + * static void foo (NMType *obj) + * { + * access_obj_without_check (obj); + * } + * foo ((NMType *) obj); + * // There is no runtime check and passing an invalid pointer + * // leads to a crash. + * + * Example 2: + * static void foo (NMType *obj) + * { + * access_obj_without_check (obj); + * } + * foo (NM_TYPE (obj)); + * // There is a runtime check which prints a g_warning(), but that doesn't + * // avoid the crash as NM_TYPE() cannot do anything then passing on the + * // invalid pointer. + * + * Example 3: + * static void foo (NMType *obj) + * { + * g_return_if_fail (NM_IS_TYPE (obj)); + * access_obj_without_check (obj); + * } + * foo ((NMType *) obj); + * // There is a runtime check which prints a g_critical() which also avoids + * // the crash. That is actually helpful to catch bugs and avoid crashes. + * + * Example 4: + * static void foo (NMType *obj) + * { + * g_return_if_fail (NM_IS_TYPE (obj)); + * access_obj_without_check (obj); + * } + * foo (NM_TYPE (obj)); + * // The runtime check is performed twice, with printing a g_warning() and + * // a g_critical() and avoiding the crash. + * + * Example 3 is how it should be done. Type checks in NM_TYPE() are pointless. + * Disable them for our production builds. + */ + #ifndef G_DISABLE_CAST_CHECKS + #define G_DISABLE_CAST_CHECKS + #endif +#endif + +/*****************************************************************************/ + +#include + +/*****************************************************************************/ + +#endif /* __NM_DEFAULT_STD_H__ */ diff --git a/src/libnm-std-aux/nm-networkmanager-compilation.h b/src/libnm-std-aux/nm-networkmanager-compilation.h new file mode 100644 index 0000000..025a158 --- /dev/null +++ b/src/libnm-std-aux/nm-networkmanager-compilation.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_NETWORKMANAGER_COMPILATION_H__ +#define __NM_NETWORKMANAGER_COMPILATION_H__ + +#define NM_NETWORKMANAGER_COMPILATION_WITH_GLIB (1 << 0) +#define NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB (1 << 1) +#define NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG (1 << 2) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM (1 << 3) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE (1 << 4) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE (1 << 5) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL (1 << 6) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE (1 << 7) +#define NM_NETWORKMANAGER_COMPILATION_WITH_DAEMON (1 << 10) +#define NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD (1 << 11) + +#define NM_NETWORKMANAGER_COMPILATION_LIBNM_CORE \ + (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL) + +#define NM_NETWORKMANAGER_COMPILATION_LIBNM \ + (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL) + +#define NM_NETWORKMANAGER_COMPILATION_CLIENT \ + (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE) + +#define NM_NETWORKMANAGER_COMPILATION_DAEMON \ + (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL \ + | NM_NETWORKMANAGER_COMPILATION_WITH_DAEMON) + +#define NM_NETWORKMANAGER_COMPILATION_SYSTEMD_SHARED \ + (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB | NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD) + +#define NM_NETWORKMANAGER_COMPILATION_SYSTEMD \ + (0 | NM_NETWORKMANAGER_COMPILATION_DAEMON | NM_NETWORKMANAGER_COMPILATION_SYSTEMD_SHARED) + +#define NM_NETWORKMANAGER_COMPILATION_GLIB (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB) + +#endif /* __NM_NETWORKMANAGER_COMPILATION_H__ */ diff --git a/src/libnm-std-aux/nm-std-aux.h b/src/libnm-std-aux/nm-std-aux.h new file mode 100644 index 0000000..30adeb5 --- /dev/null +++ b/src/libnm-std-aux/nm-std-aux.h @@ -0,0 +1,977 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_STD_AUX_H__ +#define __NM_STD_AUX_H__ + +#include +#include +#include +#include +#include +#include +#include + +/*****************************************************************************/ + +#define _nm_packed __attribute__((__packed__)) +#define _nm_unused __attribute__((__unused__)) +#define _nm_used __attribute__((__used__)) +#define _nm_pure __attribute__((__pure__)) +#define _nm_const __attribute__((__const__)) +#define _nm_printf(a, b) __attribute__((__format__(__printf__, a, b))) +#define _nm_align(s) __attribute__((__aligned__(s))) +#define _nm_section(s) __attribute__((__section__(s))) +#define _nm_alignof(type) __alignof(type) +#define _nm_alignas(type) _nm_align(_nm_alignof(type)) +#define nm_auto(fcn) __attribute__((__cleanup__(fcn))) + +/* This is required to make LTO working. + * + * See https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/76#note_112694 + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48200#c28 + */ +#ifndef __clang__ + #define _nm_externally_visible __attribute__((__externally_visible__)) +#else + #define _nm_externally_visible +#endif + +#if __GNUC__ >= 7 + #define _nm_fallthrough __attribute__((__fallthrough__)) +#else + #define _nm_fallthrough +#endif + +/*****************************************************************************/ + +#ifdef __CHECKER__ + #define _nm_bitwise __attribute__((__bitwise__)) + #define _nm_force __attribute__((__force__)) +#else + #define _nm_bitwise + #define _nm_force +#endif + +typedef uint16_t _nm_bitwise nm_le16_t; +typedef uint16_t _nm_bitwise nm_be16_t; +typedef uint32_t _nm_bitwise nm_le32_t; +typedef uint32_t _nm_bitwise nm_be32_t; +typedef uint64_t _nm_bitwise nm_le64_t; +typedef uint64_t _nm_bitwise nm_be64_t; + +/*****************************************************************************/ + +#ifdef thread_local + #define _nm_thread_local thread_local +/* + * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__ + * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 + */ +#elif __STDC_VERSION__ >= 201112L \ + && !(defined(__STDC_NO_THREADS__) \ + || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) + #define _nm_thread_local _Thread_local +#else + #define _nm_thread_local __thread +#endif + +/*****************************************************************************/ + +#define _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON struct _nm_dummy_struct_for_trailing_semicolon + +/*****************************************************************************/ + +#define NM_PASTE_ARGS(identifier1, identifier2) identifier1##identifier2 +#define NM_PASTE(identifier1, identifier2) NM_PASTE_ARGS(identifier1, identifier2) + +/* Taken from systemd's UNIQ_T and UNIQ macros. */ + +#define NM_UNIQ_T(x, uniq) NM_PASTE(__unique_prefix_, NM_PASTE(x, uniq)) +#define NM_UNIQ __COUNTER__ + +/*****************************************************************************/ + +#define _NM_BOOLEAN_EXPR_IMPL(v, expr) \ + ({ \ + int NM_UNIQ_T(V, v); \ + \ + if (expr) \ + NM_UNIQ_T(V, v) = 1; \ + else \ + NM_UNIQ_T(V, v) = 0; \ + NM_UNIQ_T(V, v); \ + }) +#define NM_BOOLEAN_EXPR(expr) _NM_BOOLEAN_EXPR_IMPL(NM_UNIQ, expr) + +#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) + #define NM_LIKELY(expr) (__builtin_expect(NM_BOOLEAN_EXPR(expr), 1)) + #define NM_UNLIKELY(expr) (__builtin_expect(NM_BOOLEAN_EXPR(expr), 0)) +#else + #define NM_LIKELY(expr) NM_BOOLEAN_EXPR(expr) + #define NM_UNLIKELY(expr) NM_BOOLEAN_EXPR(expr) +#endif + +/*****************************************************************************/ + +/* glib/C provides the following kind of assertions: + * - assert() -- disable with NDEBUG + * - g_return_if_fail() -- disable with G_DISABLE_CHECKS + * - g_assert() -- disable with G_DISABLE_ASSERT + * but they are all enabled by default and usually even production builds have + * these kind of assertions enabled. It also means, that disabling assertions + * is an untested configuration, and might have bugs. + * + * Add our own assertion macro nm_assert(), which is disabled by default and must + * be explicitly enabled. They are useful for more expensive checks or checks that + * depend less on runtime conditions (that is, are generally expected to be true). */ + +#ifndef NM_MORE_ASSERTS + #define NM_MORE_ASSERTS 0 +#endif + +#ifndef _nm_assert_call + #define _nm_assert_call(cond) assert(cond) + #define _nm_assert_call_not_reached() assert(0) +#endif + +#if NM_MORE_ASSERTS + #define nm_assert(cond) \ + do { \ + _nm_assert_call(cond); \ + } while (0) + #define nm_assert_se(cond) \ + do { \ + if (NM_LIKELY(cond)) { \ + ; \ + } else { \ + _nm_assert_call(0 && (cond)); \ + } \ + } while (0) + #define nm_assert_not_reached() \ + do { \ + _nm_assert_call_not_reached(); \ + } while (0) +#else + #define nm_assert(cond) \ + do { \ + if (0) { \ + if (cond) {} \ + } \ + } while (0) + #define nm_assert_se(cond) \ + do { \ + if (NM_LIKELY(cond)) { \ + ; \ + } \ + } while (0) + #define nm_assert_not_reached() \ + do { \ + ; \ + } while (0) +#endif + +#define nm_assert_unreachable_val(val) \ + ({ \ + nm_assert_not_reached(); \ + (val); \ + }) + +#define NM_STATIC_ASSERT(cond) static_assert(cond, "") +#define NM_STATIC_ASSERT_EXPR(cond) \ + ({ \ + NM_STATIC_ASSERT(cond); \ + 1; \ + }) + +/*****************************************************************************/ + +#define NM_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) + +/*****************************************************************************/ + +static inline uint32_t +nm_add_clamped_u32(uint32_t a, uint32_t b) +{ + uint32_t c; + + /* returns a+b, or UINT32_MAX if the result would overflow. */ + + c = a + b; + if (c < a) + return UINT32_MAX; + return c; +} + +static inline unsigned +nm_mult_clamped_u(unsigned a, unsigned b) +{ + unsigned c; + + /* returns a*b, or UINT_MAX if the result would overflow. */ + + if (b == 0) + return 0; + + c = a * b; + + if (c / b != a) + return (unsigned) -1; + + return c; +} + +/* glib's MIN()/MAX() macros don't have function-like behavior, in that they evaluate + * the argument possibly twice. + * + * Taken from systemd's MIN()/MAX() macros. */ + +#define NM_MIN(a, b) __NM_MIN(NM_UNIQ, a, NM_UNIQ, b) +#define __NM_MIN(aq, a, bq, b) \ + ({ \ + typeof(a) NM_UNIQ_T(A, aq) = (a); \ + typeof(b) NM_UNIQ_T(B, bq) = (b); \ + ((NM_UNIQ_T(A, aq) < NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \ + }) + +#define NM_MAX(a, b) __NM_MAX(NM_UNIQ, a, NM_UNIQ, b) +#define __NM_MAX(aq, a, bq, b) \ + ({ \ + typeof(a) NM_UNIQ_T(A, aq) = (a); \ + typeof(b) NM_UNIQ_T(B, bq) = (b); \ + ((NM_UNIQ_T(A, aq) > NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \ + }) + +#define NM_CLAMP(x, low, high) __NM_CLAMP(NM_UNIQ, x, NM_UNIQ, low, NM_UNIQ, high) +#define __NM_CLAMP(xq, x, lowq, low, highq, high) \ + ({ \ + typeof(x) NM_UNIQ_T(X, xq) = (x); \ + typeof(low) NM_UNIQ_T(LOW, lowq) = (low); \ + typeof(high) NM_UNIQ_T(HIGH, highq) = (high); \ + \ + ((NM_UNIQ_T(X, xq) > NM_UNIQ_T(HIGH, highq)) ? NM_UNIQ_T(HIGH, highq) \ + : (NM_UNIQ_T(X, xq) < NM_UNIQ_T(LOW, lowq)) ? NM_UNIQ_T(LOW, lowq) \ + : NM_UNIQ_T(X, xq)); \ + }) + +#define NM_MAX_WITH_CMP(cmp, a, b) \ + ({ \ + typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + \ + (((cmp(_a, _b)) >= 0) ? _a : _b); \ + }) + +/* evaluates to (void) if _A or _B are not constant or of different types */ +#define NM_CONST_MAX(_A, _B) \ + (__builtin_choose_expr((__builtin_constant_p(_A) && __builtin_constant_p(_B) \ + && __builtin_types_compatible_p(typeof(_A), typeof(_B))), \ + ((_A) > (_B)) ? (_A) : (_B), \ + ((void) 0))) + +/* Determine whether @x is a power of two (@x being an integer type). + * Basically, this returns TRUE, if @x has exactly one bit set. + * For negative values and zero, this always returns FALSE. */ +#define nm_utils_is_power_of_two(x) \ + ({ \ + typeof(x) _x2 = (x); \ + const typeof(_x2) _X_0 = ((typeof(_x2)) 0); \ + const typeof(_x2) _X_1 = ((typeof(_x2)) 1); \ + \ + ((_x2 > _X_0) && ((_x2 & (_x2 - _X_1)) == _X_0)); \ + }) + +#define nm_utils_is_power_of_two_or_zero(x) \ + ({ \ + typeof(x) _x1 = (x); \ + \ + ((_x1 == 0) || nm_utils_is_power_of_two(_x1)); \ + }) + +/*****************************************************************************/ + +#define NM_SWAP(p_a, p_b) \ + do { \ + typeof(*(p_a)) *const _p_a = (p_a); \ + typeof(*(p_a)) *const _p_b = (p_b); \ + typeof(*(p_a)) _tmp; \ + \ + _tmp = *_p_a; \ + *_p_a = *_p_b; \ + *_p_b = _tmp; \ + } while (0) + +/*****************************************************************************/ + +/* macro to return strlen() of a compile time string. */ +#define NM_STRLEN(str) (sizeof("" str "") - 1u) + +/* returns the length of a NULL terminated array of pointers, + * like g_strv_length() does. The difference is: + * - it operates on arrays of pointers (of any kind, requiring no cast). + * - it accepts NULL to return zero. */ +#define NM_PTRARRAY_LEN(array) \ + ({ \ + typeof(*(array)) *const _array = (array); \ + size_t _n = 0; \ + \ + if (_array) { \ + _nm_unused const void *_type_check_is_pointer = _array[0]; \ + \ + while (_array[_n]) \ + _n++; \ + } \ + _n; \ + }) + +/*****************************************************************************/ + +static inline int +nm_strcmp0(const char *s1, const char *s2) +{ + int c; + + /* like g_strcmp0(), but this is inlinable. + * + * Also, it is guaranteed to return either -1, 0, or 1. */ + if (s1 == s2) + return 0; + if (!s1) + return -1; + if (!s2) + return 1; + c = strcmp(s1, s2); + if (c < 0) + return -1; + if (c > 0) + return 1; + return 0; +} + +static inline int +nm_streq(const char *s1, const char *s2) +{ + return strcmp(s1, s2) == 0; +} + +static inline int +nm_streq0(const char *s1, const char *s2) +{ + return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0); +} + +#define NM_STR_HAS_PREFIX(str, prefix) \ + ({ \ + const char *const _str_has_prefix = (str); \ + \ + nm_assert(strlen(prefix) == NM_STRLEN(prefix)); \ + \ + _str_has_prefix && (strncmp(_str_has_prefix, "" prefix "", NM_STRLEN(prefix)) == 0); \ + }) + +#define NM_STR_HAS_SUFFIX(str, suffix) \ + ({ \ + const char *const _str_has_suffix = (str); \ + size_t _l; \ + \ + nm_assert(strlen(suffix) == NM_STRLEN(suffix)); \ + \ + (_str_has_suffix && ((_l = strlen(_str_has_suffix)) >= NM_STRLEN(suffix)) \ + && (memcmp(&_str_has_suffix[_l - NM_STRLEN(suffix)], "" suffix "", NM_STRLEN(suffix)) \ + == 0)); \ + }) + +/* whether @str starts with the string literal @prefix and is followed by + * some other text. It is like NM_STR_HAS_PREFIX() && !nm_streq() together. */ +#define NM_STR_HAS_PREFIX_WITH_MORE(str, prefix) \ + ({ \ + const char *const _str_has_prefix_with_more = (str); \ + \ + NM_STR_HAS_PREFIX(_str_has_prefix_with_more, "" prefix "") \ + &&_str_has_prefix_with_more[NM_STRLEN(prefix)] != '\0'; \ + }) + +#define NM_STR_HAS_SUFFIX_WITH_MORE(str, suffix) \ + ({ \ + const char *const _str_has_suffix = (str); \ + size_t _l; \ + \ + nm_assert(strlen(suffix) == NM_STRLEN(suffix)); \ + \ + (_str_has_suffix && ((_l = strlen(_str_has_suffix)) > NM_STRLEN(suffix)) \ + && (memcmp(&_str_has_suffix[_l - NM_STRLEN(suffix)], "" suffix "", NM_STRLEN(suffix)) \ + == 0)); \ + }) + +/*****************************************************************************/ + +#define _NM_IN_SET_EVAL_1(op, _x, y) (_x == (y)) +#define _NM_IN_SET_EVAL_2(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_1(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_3(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_2(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_4(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_3(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_5(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_4(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_6(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_5(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_7(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_6(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_8(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_7(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_9(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_8(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_10(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_9(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_11(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_10(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_12(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_11(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_13(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_12(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_14(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_13(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_15(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_14(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_16(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_15(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_17(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_16(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_18(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_17(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_19(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_18(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_20(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_19(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_21(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_20(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_22(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_21(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_23(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_22(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_24(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_23(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_25(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_24(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_26(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_25(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_27(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_26(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_28(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_27(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_29(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_28(op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_30(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_29(op, _x, __VA_ARGS__) + +#define _NM_IN_SET_EVAL_N2(op, _x, n, ...) (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__)) +#define _NM_IN_SET_EVAL_N(op, type, x, n, ...) \ + ({ \ + type _x = (x); \ + \ + /* trigger a -Wenum-compare warning */ \ + nm_assert(true || _x == (x)); \ + \ + !!_NM_IN_SET_EVAL_N2(op, _x, n, __VA_ARGS__); \ + }) + +#define _NM_IN_SET(op, type, x, ...) \ + _NM_IN_SET_EVAL_N(op, type, x, NM_NARG(__VA_ARGS__), __VA_ARGS__) + +/* Beware that this does short-circuit evaluation (use "||" instead of "|") + * which has a possibly unexpected non-function-like behavior. + * Use NM_IN_SET_SE if you need all arguments to be evaluated. */ +#define NM_IN_SET(x, ...) _NM_IN_SET(||, typeof(x), x, __VA_ARGS__) + +/* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do + * short-circuit evaluation, which can make a difference if the arguments have + * side-effects. */ +#define NM_IN_SET_SE(x, ...) _NM_IN_SET(|, typeof(x), x, __VA_ARGS__) + +/* the *_TYPED forms allow to explicitly select the type of "x". This is useful + * if "x" doesn't support typeof (bitfields) or you want to gracefully convert + * a type using automatic type conversion rules (but not forcing the conversion + * with a cast). */ +#define NM_IN_SET_TYPED(type, x, ...) _NM_IN_SET(||, type, x, __VA_ARGS__) +#define NM_IN_SET_SE_TYPED(type, x, ...) _NM_IN_SET(|, type, x, __VA_ARGS__) + +/*****************************************************************************/ + +#define _NM_IN_SETOP_EVAL_1(op, op_eq, _x, y) (op_eq(_x, y)) +#define _NM_IN_SETOP_EVAL_2(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_1(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_3(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_2(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_4(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_3(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_5(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_4(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_6(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_5(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_7(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_6(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_8(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_7(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_9(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_8(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_10(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_9(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_11(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_10(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_12(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_11(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_13(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_12(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_14(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_13(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_15(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_14(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_16(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_15(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_17(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_16(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_18(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_17(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_19(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_18(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_20(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_19(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_21(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_20(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_22(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_21(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_23(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_22(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_24(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_23(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_25(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_24(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_26(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_25(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_27(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_26(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_28(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_27(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_29(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_28(op, op_eq, _x, __VA_ARGS__) +#define _NM_IN_SETOP_EVAL_30(op, op_eq, _x, y, ...) \ + (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_29(op, op_eq, _x, __VA_ARGS__) + +/*****************************************************************************/ + +#define _NM_IN_STRSET_EVAL_N2(op, op_ed, _x, n, ...) \ + (_NM_IN_SETOP_EVAL_##n(op, op_ed, _x, __VA_ARGS__)) +#define _NM_IN_STRSET_EVAL_N(op, op_ed, x, n, ...) \ + ({ \ + const char *_x = (x); \ + (((_x == NULL) && _NM_IN_SET_EVAL_N2(op, ((const char *) NULL), n, __VA_ARGS__)) \ + || ((_x != NULL) && _NM_IN_STRSET_EVAL_N2(op, op_ed, _x, n, __VA_ARGS__))); \ + }) + +/*****************************************************************************/ + +static inline int +_NM_IN_STRSET_op_streq(const char *x, const char *s) +{ + return s && strcmp(x, s) == 0; +} + +/* Beware that this does short-circuit evaluation (use "||" instead of "|") + * which has a possibly unexpected non-function-like behavior. + * Use NM_IN_STRSET_SE if you need all arguments to be evaluated. */ +#define NM_IN_STRSET(x, ...) \ + _NM_IN_STRSET_EVAL_N(||, _NM_IN_STRSET_op_streq, x, NM_NARG(__VA_ARGS__), __VA_ARGS__) + +/* "SE" stands for "side-effect". Contrary to NM_IN_STRSET(), this does not do + * short-circuit evaluation, which can make a difference if the arguments have + * side-effects. */ +#define NM_IN_STRSET_SE(x, ...) \ + _NM_IN_STRSET_EVAL_N(|, _NM_IN_STRSET_op_streq, x, NM_NARG(__VA_ARGS__), __VA_ARGS__) + +/*****************************************************************************/ + +#define NM_STRCHAR_ALL(str, ch_iter, predicate) \ + ({ \ + int _val = true; \ + const char *_str = (str); \ + \ + if (_str) { \ + for (;;) { \ + const char ch_iter = _str[0]; \ + \ + if (ch_iter != '\0') { \ + if (predicate) { \ + _str++; \ + continue; \ + } \ + _val = false; \ + } \ + break; \ + } \ + } \ + _val; \ + }) + +#define NM_STRCHAR_ANY(str, ch_iter, predicate) \ + ({ \ + int _val = false; \ + const char *_str = (str); \ + \ + if (_str) { \ + for (;;) { \ + const char ch_iter = _str[0]; \ + \ + if (ch_iter != '\0') { \ + if (predicate) { \ + ; \ + } else { \ + _str++; \ + continue; \ + } \ + _val = true; \ + } \ + break; \ + } \ + } \ + _val; \ + }) + +/*****************************************************************************/ + +/** + * nm_close: + * + * Like close() but throws an assertion if the input fd is + * invalid. Closing an invalid fd is a programming error, so + * it's better to catch it early. + */ +static inline int +nm_close(int fd) +{ + int r; + + r = close(fd); + nm_assert(r != -1 || fd < 0 || errno != EBADF); + return r; +} + +/*****************************************************************************/ + +/* Note: @value is only evaluated when *out_val is present. + * Thus, + * NM_SET_OUT (out_str, g_strdup ("hallo")); + * does the right thing. + */ +#define NM_SET_OUT(out_val, value) \ + ({ \ + typeof(*(out_val)) *_out_val = (out_val); \ + \ + if (_out_val) { \ + *_out_val = (value); \ + } \ + \ + (!!_out_val); \ + }) + +/*****************************************************************************/ + +#define NM_AUTO_DEFINE_FCN_VOID(CastType, name, func) \ + static inline void name(void *v) \ + { \ + func(*((CastType *) v)); \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +#define NM_AUTO_DEFINE_FCN_VOID0(CastType, name, func) \ + static inline void name(void *v) \ + { \ + if (*((CastType *) v)) \ + func(*((CastType *) v)); \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +#define NM_AUTO_DEFINE_FCN(Type, name, func) \ + static inline void name(Type *v) \ + { \ + func(*v); \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +#define NM_AUTO_DEFINE_FCN0(Type, name, func) \ + static inline void name(Type *v) \ + { \ + if (*v) \ + func(*v); \ + } \ + _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON + +/*****************************************************************************/ + +/** + * nm_auto_free: + * + * Call free() on a variable location when it goes out of scope. + * This is for pointers that are allocated with malloc() instead of + * g_malloc(). + * + * In practice, since glib 2.45, g_malloc()/g_free() always wraps malloc()/free(). + * See bgo#751592. In that case, it would be safe to free pointers allocated with + * malloc() with gs_free or g_free(). + * + * However, let's never mix them. To free malloc'ed memory, always use + * free() or nm_auto_free. + */ +NM_AUTO_DEFINE_FCN_VOID0(void *, _nm_auto_free_impl, free); +#define nm_auto_free nm_auto(_nm_auto_free_impl) + +/*****************************************************************************/ + +static inline void +_nm_auto_close(int *pfd) +{ + if (*pfd >= 0) { + int errsv = errno; + + (void) nm_close(*pfd); + errno = errsv; + } +} +#define nm_auto_close nm_auto(_nm_auto_close) + +static inline void +_nm_auto_fclose(FILE **pfd) +{ + if (*pfd) { + int errsv = errno; + + (void) fclose(*pfd); + errno = errsv; + } +} +#define nm_auto_fclose nm_auto(_nm_auto_fclose) + +/*****************************************************************************/ + +#define nm_clear_pointer(pp, destroy) \ + ({ \ + typeof(*(pp)) *_pp = (pp); \ + typeof(*_pp) _p; \ + int _changed = false; \ + \ + if (_pp && (_p = *_pp)) { \ + _nm_unused const void *_p_check_is_pointer = _p; \ + \ + *_pp = NULL; \ + \ + /* g_clear_pointer() assigns @destroy first to a local variable, so that + * you can call "g_clear_pointer (pp, (GDestroyNotify) destroy);" without + * gcc emitting a warning. We don't do that, hence, you cannot cast + * "destroy" first. + * + * On the upside: you are not supposed to cast fcn, because the pointer + * types are preserved. If you really need a cast, you should cast @pp. + * But that is hardly ever necessary. */ \ + (destroy)(_p); \ + \ + _changed = true; \ + } \ + _changed; \ + }) + +#define nm_clear_free(pp) nm_clear_pointer(pp, free) + +/*****************************************************************************/ + +static inline void * +_nm_steal_pointer(void *pp) +{ + void **ptr = (void **) pp; + void * ref; + + ref = *ptr; + *ptr = NULL; + return ref; +} + +#define nm_steal_pointer(pp) ((typeof(*(pp))) _nm_steal_pointer(pp)) + +/** + * nm_steal_int: + * @p_val: pointer to an int type. + * + * Returns: *p_val and sets *p_val to zero the same time. + * Accepts %NULL, in which case also numeric 0 will be returned. + */ +#define nm_steal_int(p_val) \ + ({ \ + typeof(p_val) const _p_val = (p_val); \ + typeof(*_p_val) _val = 0; \ + \ + if (_p_val && (_val = *_p_val)) { \ + *_p_val = 0; \ + } \ + _val; \ + }) + +static inline int +nm_steal_fd(int *p_fd) +{ + int fd; + + if (p_fd && ((fd = *p_fd) >= 0)) { + *p_fd = -1; + return fd; + } + return -1; +} + +/*****************************************************************************/ + +static inline uintptr_t +nm_ptr_to_uintptr(const void *p) +{ + /* in C, pointers can only be compared (with less-than or greater-than) under certain + * circumstances. Since uintptr_t is supposed to be able to represent the pointer + * as a plain integer and also support to convert the integer back to the pointer, + * it should be safer to compare the pointers directly. + * + * Of course, this function isn't very useful beyond that its use makes it clear + * that we want to compare pointers by value, which otherwise may not be valid. */ + return (uintptr_t) p; +} + +/*****************************************************************************/ + +#define NM_CMP_RETURN(c) \ + do { \ + const int _cc = (c); \ + if (_cc) \ + return _cc < 0 ? -1 : 1; \ + } while (0) + +#define NM_CMP_RETURN_DIRECT(c) \ + do { \ + const int _cc = (c); \ + if (_cc) \ + return _cc; \ + } while (0) + +#define NM_CMP_SELF(a, b) \ + do { \ + typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + \ + if (_a == _b) \ + return 0; \ + if (!_a) \ + return -1; \ + if (!_b) \ + return 1; \ + } while (0) + +#define NM_CMP_DIRECT(a, b) \ + do { \ + typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + \ + if (_a != _b) \ + return (_a < _b) ? -1 : 1; \ + } while (0) + +#define NM_CMP_DIRECT_UNSAFE(a, b) \ + do { \ + if ((a) != (b)) \ + return ((a) < (b)) ? -1 : 1; \ + } while (0) + +/* In the general case, direct pointer comparison is undefined behavior in C. + * Avoid that by casting pointers to void* and then to uintptr_t. This comparison + * is not really meaningful, except that it provides some kind of stable sort order + * between pointers (that can otherwise not be compared). */ +#define NM_CMP_DIRECT_PTR(a, b) NM_CMP_DIRECT(nm_ptr_to_uintptr(a), nm_ptr_to_uintptr(b)) + +#define NM_CMP_DIRECT_MEMCMP(a, b, size) NM_CMP_RETURN(memcmp((a), (b), (size))) + +#define NM_CMP_DIRECT_STRCMP(a, b) NM_CMP_RETURN_DIRECT(strcmp((a), (b))) + +#define NM_CMP_DIRECT_STRCMP0(a, b) NM_CMP_RETURN_DIRECT(nm_strcmp0((a), (b))) + +#define NM_CMP_DIRECT_IN6ADDR(a, b) \ + do { \ + const struct in6_addr *const _a = (a); \ + const struct in6_addr *const _b = (b); \ + NM_CMP_RETURN(memcmp(_a, _b, sizeof(struct in6_addr))); \ + } while (0) + +#define NM_CMP_FIELD(a, b, field) NM_CMP_DIRECT(((a)->field), ((b)->field)) + +#define NM_CMP_FIELD_UNSAFE(a, b, field) \ + do { \ + /* it's unsafe, because it evaluates the arguments more then once. + * This is necessary for bitfields, for which typeof() doesn't work. */ \ + if (((a)->field) != ((b)->field)) \ + return ((a)->field < ((b)->field)) ? -1 : 1; \ + } while (0) + +#define NM_CMP_FIELD_BOOL(a, b, field) NM_CMP_DIRECT(!!((a)->field), !!((b)->field)) + +#define NM_CMP_FIELD_STR(a, b, field) NM_CMP_RETURN(strcmp(((a)->field), ((b)->field))) + +#define NM_CMP_FIELD_STR_INTERNED(a, b, field) \ + do { \ + const char *_a = ((a)->field); \ + const char *_b = ((b)->field); \ + \ + if (_a != _b) { \ + NM_CMP_RETURN_DIRECT(nm_strcmp0(_a, _b)); \ + } \ + } while (0) + +#define NM_CMP_FIELD_STR0(a, b, field) NM_CMP_RETURN_DIRECT(nm_strcmp0(((a)->field), ((b)->field))) + +#define NM_CMP_FIELD_MEMCMP_LEN(a, b, field, len) \ + NM_CMP_RETURN(memcmp(&((a)->field), &((b)->field), NM_MIN(len, sizeof((a)->field)))) + +#define NM_CMP_FIELD_MEMCMP(a, b, field) \ + NM_CMP_RETURN(memcmp(&((a)->field), &((b)->field), sizeof((a)->field))) + +#define NM_CMP_FIELD_IN6ADDR(a, b, field) \ + do { \ + const struct in6_addr *const _a = &((a)->field); \ + const struct in6_addr *const _b = &((b)->field); \ + NM_CMP_RETURN(memcmp(_a, _b, sizeof(struct in6_addr))); \ + } while (0) + +/*****************************************************************************/ + +#define NM_AF_UNSPEC 0 /* AF_UNSPEC */ +#define NM_AF_INET 2 /* AF_INET */ +#define NM_AF_INET6 10 /* AF_INET6 */ + +#define NM_AF_INET_SIZE 4 /* sizeof (in_addr_t) */ +#define NM_AF_INET6_SIZE 16 /* sizeof (stuct in6_addr) */ + +static inline char +nm_utils_addr_family_to_char(int addr_family) +{ + switch (addr_family) { + case NM_AF_UNSPEC: + return 'X'; + case NM_AF_INET: + return '4'; + case NM_AF_INET6: + return '6'; + } + nm_assert_not_reached(); + return '?'; +} + +static inline size_t +nm_utils_addr_family_to_size(int addr_family) +{ + switch (addr_family) { + case NM_AF_INET: + return NM_AF_INET_SIZE; + case NM_AF_INET6: + return NM_AF_INET6_SIZE; + } + nm_assert_not_reached(); + return 0; +} + +static inline int +nm_utils_addr_family_from_size(size_t len) +{ + switch (len) { + case NM_AF_INET_SIZE: + return NM_AF_INET; + case NM_AF_INET6_SIZE: + return NM_AF_INET6; + } + return NM_AF_UNSPEC; +} + +#define nm_assert_addr_family(addr_family) \ + nm_assert(NM_IN_SET((addr_family), NM_AF_INET, NM_AF_INET6)) + +#define NM_IS_IPv4(addr_family) \ + ({ \ + const int _addr_family = (addr_family); \ + \ + nm_assert_addr_family(_addr_family); \ + \ + (_addr_family == NM_AF_INET); \ + }) + +#endif /* __NM_STD_AUX_H__ */ diff --git a/src/libnm-std-aux/nm-std-utils.c b/src/libnm-std-aux/nm-std-utils.c new file mode 100644 index 0000000..18692b1 --- /dev/null +++ b/src/libnm-std-aux/nm-std-utils.c @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-default-std.h" + +#include "nm-std-utils.h" + +#include +#include +#include + +/*****************************************************************************/ + +size_t +nm_utils_get_next_realloc_size(bool true_realloc, size_t requested) +{ + size_t n, x; + + /* https://doc.qt.io/qt-5/containers.html#growth-strategies */ + + if (requested <= 40) { + /* small allocations. Increase in small steps of 8 bytes. + * + * We get thus sizes of 8, 16, 32, 40. */ + if (requested <= 8) + return 8; + if (requested <= 16) + return 16; + if (requested <= 32) + return 32; + + /* The return values for < 104 are essentially hard-coded, and the choice here is + * made without very strong reasons. + * + * We want to stay 24 bytes below the power-of-two border 64. Hence, return 40 here. + * However, the next step then is already 104 (128 - 24). It's a larger gap than in + * the steps before. + * + * It's not clear whether some of the steps should be adjusted (or how exactly). */ + return 40; + } + + if (requested <= 0x2000u - 24u || NM_UNLIKELY(!true_realloc)) { + /* mid sized allocations. Return next power of two, minus 24 bytes extra space + * at the beginning. + * That means, we double the size as we grow. + * + * With !true_realloc, it means that the caller does not intend to call + * realloc() but instead clone the buffer. This is for example the case, when we + * want to nm_explicit_bzero() the old buffer. In that case we really want to grow + * the buffer exponentially every time and not increment in page sizes of 4K (below). + * + * We get thus sizes of 104, 232, 488, 1000, 2024, 4072, 8168... */ + + if (NM_UNLIKELY(requested > SIZE_MAX / 2u - 24u)) + goto out_huge; + + x = requested + 24u; + n = 128u; + while (n < x) { + n <<= 1; + nm_assert(n > 128u); + } + + nm_assert(n > 24u && n - 24u >= requested); + return n - 24u; + } + + if (NM_UNLIKELY(requested > SIZE_MAX - 0x1000u - 24u)) { + /* overflow happened. */ + goto out_huge; + } + + /* For large allocations (with !true_realloc) we allocate memory in chunks of + * 4K (- 24 bytes extra), assuming that the memory gets mmapped and thus + * realloc() is efficient by just reordering pages. */ + n = ((requested + (0x0FFFu + 24u)) & ~((size_t) 0x0FFFu)) - 24u; + nm_assert(n >= requested); + return n; + +out_huge: + if (sizeof(size_t) > 4u) { + /* on s390x (64 bit), gcc with LTO can complain that the size argument to + * malloc must not be larger than 9223372036854775807. + * + * Work around that by returning SSIZE_MAX. It should be plenty still! */ + assert(requested <= (size_t) SSIZE_MAX); + return (size_t) SSIZE_MAX; + } + return SIZE_MAX; +} diff --git a/src/libnm-std-aux/nm-std-utils.h b/src/libnm-std-aux/nm-std-utils.h new file mode 100644 index 0000000..9c851f1 --- /dev/null +++ b/src/libnm-std-aux/nm-std-utils.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_STD_UTILS_H__ +#define __NM_STD_UTILS_H__ + +#include + +#include "nm-std-aux.h" + +/*****************************************************************************/ + +/* nm_utils_get_next_realloc_size() is used to grow buffers exponentially, when + * the final size is unknown. As such, it has borders for which it allocates + * certain buffer sizes. + * + * The use of these defines is to get favorable allocation sequences. + * For example, nm_str_buf_init() asks for an initial allocation size. Note that + * it reserves the exactly requested amount, under the assumption that the + * user may know how many bytes will be required. However, often the caller + * doesn't know in advance, and NMStrBuf grows exponentially by calling + * nm_utils_get_next_realloc_size(). + * Imagine you call nm_str_buf_init() with an initial buffer size 100, and you + * add one character at a time. Then the first reallocation will increase the + * buffer size only from 100 to 104. + * If you however start with an initial buffer size of 104, then the next reallocation + * via nm_utils_get_next_realloc_size() gives you 232, and so on. By using + * these sizes, it results in one less allocation, if you anyway don't know the + * exact size in advance. */ +#define NM_UTILS_GET_NEXT_REALLOC_SIZE_32 ((size_t) 32) +#define NM_UTILS_GET_NEXT_REALLOC_SIZE_40 ((size_t) 40) +#define NM_UTILS_GET_NEXT_REALLOC_SIZE_104 ((size_t) 104) +#define NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 ((size_t) 1000) + +size_t nm_utils_get_next_realloc_size(bool true_realloc, size_t requested); + +#endif /* __NM_STD_UTILS_H__ */ diff --git a/src/libnm-std-aux/unaligned.h b/src/libnm-std-aux/unaligned.h new file mode 100644 index 0000000..4100be0 --- /dev/null +++ b/src/libnm-std-aux/unaligned.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include + +/* BE */ + +static inline uint16_t unaligned_read_be16(const void *_u) { + const struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u; + + return be16toh(u->x); +} + +static inline uint32_t unaligned_read_be32(const void *_u) { + const struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u; + + return be32toh(u->x); +} + +static inline uint64_t unaligned_read_be64(const void *_u) { + const struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u; + + return be64toh(u->x); +} + +static inline void unaligned_write_be16(void *_u, uint16_t a) { + struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u; + + u->x = be16toh(a); +} + +static inline void unaligned_write_be32(void *_u, uint32_t a) { + struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u; + + u->x = be32toh(a); +} + +static inline void unaligned_write_be64(void *_u, uint64_t a) { + struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u; + + u->x = be64toh(a); +} + +/* LE */ + +static inline uint16_t unaligned_read_le16(const void *_u) { + const struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u; + + return le16toh(u->x); +} + +static inline uint32_t unaligned_read_le32(const void *_u) { + const struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u; + + return le32toh(u->x); +} + +static inline uint64_t unaligned_read_le64(const void *_u) { + const struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u; + + return le64toh(u->x); +} + +static inline void unaligned_write_le16(void *_u, uint16_t a) { + struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u; + + u->x = le16toh(a); +} + +static inline void unaligned_write_le32(void *_u, uint32_t a) { + struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u; + + u->x = le32toh(a); +} + +static inline void unaligned_write_le64(void *_u, uint64_t a) { + struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u; + + u->x = le64toh(a); +} + +#if __BYTE_ORDER == __BIG_ENDIAN +#define unaligned_read_ne16 unaligned_read_be16 +#define unaligned_read_ne32 unaligned_read_be32 +#define unaligned_read_ne64 unaligned_read_be64 + +#define unaligned_write_ne16 unaligned_write_be16 +#define unaligned_write_ne32 unaligned_write_be32 +#define unaligned_write_ne64 unaligned_write_be64 +#else +#define unaligned_read_ne16 unaligned_read_le16 +#define unaligned_read_ne32 unaligned_read_le32 +#define unaligned_read_ne64 unaligned_read_le64 + +#define unaligned_write_ne16 unaligned_write_le16 +#define unaligned_write_ne32 unaligned_write_le32 +#define unaligned_write_ne64 unaligned_write_le64 +#endif diff --git a/src/libnm-systemd-shared/nm-default-systemd-shared.h b/src/libnm-systemd-shared/nm-default-systemd-shared.h new file mode 100644 index 0000000..8b312f9 --- /dev/null +++ b/src/libnm-systemd-shared/nm-default-systemd-shared.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEFAULT_SYSTEMD_SHARED_H__ +#define __NM_DEFAULT_SYSTEMD_SHARED_H__ + +/*****************************************************************************/ + +#include "libnm-glib-aux/nm-default-glib.h" + +#undef NETWORKMANAGER_COMPILATION +#define NETWORKMANAGER_COMPILATION NM_NETWORKMANAGER_COMPILATION_SYSTEMD_SHARED + +/*****************************************************************************/ + +#endif /* __NM_DEFAULT_SYSTEMD_SHARED_H__ */ diff --git a/src/libnm-systemd-shared/nm-sd-utils-shared.c b/src/libnm-systemd-shared/nm-sd-utils-shared.c new file mode 100644 index 0000000..8c8934b --- /dev/null +++ b/src/libnm-systemd-shared/nm-sd-utils-shared.c @@ -0,0 +1,192 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "libnm-systemd-shared/nm-default-systemd-shared.h" + +#include "nm-sd-utils-shared.h" + +#include "nm-sd-adapt-shared.h" + +#include "dns-domain.h" +#include "hexdecoct.h" +#include "hostname-util.h" +#include "path-util.h" +#include "web-util.h" + +/*****************************************************************************/ + +const bool mempool_use_allowed = true; + +/*****************************************************************************/ + +gboolean +nm_sd_utils_path_equal(const char *a, const char *b) +{ + return path_equal(a, b); +} + +char * +nm_sd_utils_path_simplify(char *path, gboolean kill_dots) +{ + return path_simplify(path, kill_dots); +} + +const char * +nm_sd_utils_path_startswith(const char *path, const char *prefix) +{ + return path_startswith(path, prefix); +} + +/*****************************************************************************/ + +int +nm_sd_utils_unbase64char(char ch, gboolean accept_padding_equal) +{ + if (ch == '=' && accept_padding_equal) + return G_MAXINT; + return unbase64char(ch); +} + +/** + * nm_sd_utils_unbase64mem: + * @p: a valid base64 string. Whitespace is ignored, but invalid encodings + * will cause the function to fail. + * @l: the length of @p. @p is not treated as NUL terminated string but + * merely as a buffer of ascii characters. + * @secure: whether the temporary memory will be cleared to avoid leaving + * secrets in memory (see also nm_explicit_bzero()). + * @mem: (transfer full): the decoded buffer on success. + * @len: the length of @mem on success. + * + * glib provides g_base64_decode(), but that does not report any errors + * from invalid encodings. Expose systemd's implementation which does + * reject invalid inputs. + * + * Returns: a non-negative code on success. Invalid encoding let the + * function fail. + */ +int +nm_sd_utils_unbase64mem(const char *p, size_t l, gboolean secure, guint8 **mem, size_t *len) +{ + return unbase64mem_full(p, l, secure, (void **) mem, len); +} + +int +nm_sd_dns_name_to_wire_format(const char *domain, guint8 *buffer, size_t len, gboolean canonical) +{ + return dns_name_to_wire_format(domain, buffer, len, canonical); +} + +int +nm_sd_dns_name_is_valid(const char *s) +{ + return dns_name_is_valid(s); +} + +gboolean +nm_sd_hostname_is_valid(const char *s, bool allow_trailing_dot) +{ + return hostname_is_valid(s, + allow_trailing_dot ? VALID_HOSTNAME_TRAILING_DOT + : (ValidHostnameFlags) 0); +} + +char * +nm_sd_dns_name_normalize(const char *s) +{ + nm_auto_free char *n = NULL; + int r; + + r = dns_name_normalize(s, 0, &n); + if (r < 0) + return NULL; + + nm_assert(n); + + /* usually we try not to mix malloc/g_malloc and free/g_free. In practice, + * they are the same. So here we return a buffer allocated with malloc(), + * and the caller should free it with g_free(). */ + return g_steal_pointer(&n); +} + +/*****************************************************************************/ + +static gboolean +_http_url_is_valid(const char *url, gboolean only_https) +{ + if (!url || !url[0]) + return FALSE; + + if (!only_https && NM_STR_HAS_PREFIX(url, "http://")) + url += NM_STRLEN("http://"); + else if (NM_STR_HAS_PREFIX(url, "https://")) + url += NM_STRLEN("https://"); + else + return FALSE; + + if (!url[0]) + return FALSE; + + return !NM_STRCHAR_ANY(url, ch, (guchar) ch >= 128u); +} + +gboolean +nm_sd_http_url_is_valid_https(const char *url) +{ + /* We use this function to verify connection:mud-url property, it must thus + * not change behavior. + * + * Note that sd_dhcp_client_set_mud_url() and sd_dhcp6_client_set_request_mud_url() + * assert with http_url_is_valid() that the argument is valid. We thus must make + * sure to only pass URLs that are valid according to http_url_is_valid(). + * + * This is given, because our nm_sd_http_url_is_valid_https() is more strict + * than http_url_is_valid(). + * + * We only must make sure that this is also correct in the future, when we + * re-import systemd code. */ + nm_assert(_http_url_is_valid(url, FALSE) == http_url_is_valid(url)); + return _http_url_is_valid(url, TRUE); +} + +/*****************************************************************************/ + +int +nmtst_systemd_extract_first_word_all(const char *str, char ***out_strv) +{ + gs_unref_ptrarray GPtrArray *arr = NULL; + + /* we implement a str split function to parse `/proc/cmdline`. This + * code should behave like systemd, which uses extract_first_word() + * for that. + * + * As we want to unit-test our implementation to match systemd, + * expose this function for testing. */ + + g_assert(out_strv); + g_assert(!*out_strv); + + if (!str) + return 0; + + arr = g_ptr_array_new_with_free_func(g_free); + + for (;;) { + gs_free char *word = NULL; + int r; + + r = extract_first_word(&str, &word, NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX); + if (r < 0) + return r; + if (r == 0) + break; + g_ptr_array_add(arr, g_steal_pointer(&word)); + } + + g_ptr_array_add(arr, NULL); + + *out_strv = (char **) g_ptr_array_free(g_steal_pointer(&arr), FALSE); + return 1; +} diff --git a/src/libnm-systemd-shared/nm-sd-utils-shared.h b/src/libnm-systemd-shared/nm-sd-utils-shared.h new file mode 100644 index 0000000..45089c0 --- /dev/null +++ b/src/libnm-systemd-shared/nm-sd-utils-shared.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#ifndef __NM_SD_UTILS_SHARED_H__ +#define __NM_SD_UTILS_SHARED_H__ + +/*****************************************************************************/ + +gboolean nm_sd_utils_path_equal(const char *a, const char *b); + +char *nm_sd_utils_path_simplify(char *path, gboolean kill_dots); + +const char *nm_sd_utils_path_startswith(const char *path, const char *prefix); + +/*****************************************************************************/ + +int nm_sd_utils_unbase64char(char ch, gboolean accept_padding_equal); + +int nm_sd_utils_unbase64mem(const char *p, size_t l, gboolean secure, guint8 **mem, size_t *len); + +/*****************************************************************************/ + +int +nm_sd_dns_name_to_wire_format(const char *domain, guint8 *buffer, size_t len, gboolean canonical); + +int nm_sd_dns_name_is_valid(const char *s); +gboolean nm_sd_hostname_is_valid(const char *s, bool allow_trailing_dot); + +char *nm_sd_dns_name_normalize(const char *s); + +/*****************************************************************************/ + +gboolean nm_sd_http_url_is_valid_https(const char *url); + +/*****************************************************************************/ + +int nmtst_systemd_extract_first_word_all(const char *str, char ***out_strv); + +#endif /* __NM_SD_UTILS_SHARED_H__ */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/architecture.h b/src/libnm-systemd-shared/sd-adapt-shared/architecture.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/architecture.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/arphrd-list.h b/src/libnm-systemd-shared/sd-adapt-shared/arphrd-list.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/arphrd-list.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/blockdev-util.h b/src/libnm-systemd-shared/sd-adapt-shared/blockdev-util.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/blockdev-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/build.h b/src/libnm-systemd-shared/sd-adapt-shared/build.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/build.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/copy.h b/src/libnm-systemd-shared/sd-adapt-shared/copy.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/copy.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/def.h b/src/libnm-systemd-shared/sd-adapt-shared/def.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/def.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/dhcp-server-internal.h b/src/libnm-systemd-shared/sd-adapt-shared/dhcp-server-internal.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/dhcp-server-internal.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/dirent-util.h b/src/libnm-systemd-shared/sd-adapt-shared/dirent-util.h new file mode 100644 index 0000000..7132dfc --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/dirent-util.h @@ -0,0 +1,5 @@ +#pragma once + +/* dummy header */ + +#include "path-util.h" diff --git a/src/libnm-systemd-shared/sd-adapt-shared/errno-list.h b/src/libnm-systemd-shared/sd-adapt-shared/errno-list.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/errno-list.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/glob-util.h b/src/libnm-systemd-shared/sd-adapt-shared/glob-util.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/glob-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/gunicode.h b/src/libnm-systemd-shared/sd-adapt-shared/gunicode.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/gunicode.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/idn-util.h b/src/libnm-systemd-shared/sd-adapt-shared/idn-util.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/idn-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/ioprio.h b/src/libnm-systemd-shared/sd-adapt-shared/ioprio.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/ioprio.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/locale-util.h b/src/libnm-systemd-shared/sd-adapt-shared/locale-util.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/locale-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/memfd-util.h b/src/libnm-systemd-shared/sd-adapt-shared/memfd-util.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/memfd-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/missing_fs.h b/src/libnm-systemd-shared/sd-adapt-shared/missing_fs.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/missing_fs.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/missing_keyctl.h b/src/libnm-systemd-shared/sd-adapt-shared/missing_keyctl.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/missing_keyctl.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/missing_magic.h b/src/libnm-systemd-shared/sd-adapt-shared/missing_magic.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/missing_magic.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/missing_network.h b/src/libnm-systemd-shared/sd-adapt-shared/missing_network.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/missing_network.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/missing_sched.h b/src/libnm-systemd-shared/sd-adapt-shared/missing_sched.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/missing_sched.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/missing_timerfd.h b/src/libnm-systemd-shared/sd-adapt-shared/missing_timerfd.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/missing_timerfd.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/mkdir.h b/src/libnm-systemd-shared/sd-adapt-shared/mkdir.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/mkdir.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/namespace-util.h b/src/libnm-systemd-shared/sd-adapt-shared/namespace-util.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/namespace-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h b/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h new file mode 100644 index 0000000..2fc8b83 --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h @@ -0,0 +1,221 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 - 2018 Red Hat, Inc. + */ + +#ifndef __NM_SD_ADAPT_SHARED_H__ +#define __NM_SD_ADAPT_SHARED_H__ + +#include "libnm-systemd-shared/nm-default-systemd-shared.h" + +#include "libnm-glib-aux/nm-logging-fwd.h" + +/*****************************************************************************/ + +/* strerror() is not thread-safe. Patch systemd-sources via a define. */ +#define strerror(errsv) nm_strerror_native(errsv) + +/*****************************************************************************/ + +/* systemd detects whether compiler supports "-Wstringop-truncation" to disable + * the warning at particular places. Since we anyway build with -Wno-pragma, + * we don't do that and just let systemd call + * + * _Pragma("GCC diagnostic ignored \"-Wstringop-truncation\"") + * + * regadless whether that would result in a -Wpragma warning. */ +#define HAVE_WSTRINGOP_TRUNCATION 1 + +/*****************************************************************************/ + +static inline int +_nm_log_get_max_level_realm(void) +{ + /* inline function, to avoid coverity warning about constant expression. */ + return 7 /* LOG_DEBUG */; +} +#define log_get_max_level_realm(realm) _nm_log_get_max_level_realm() + +#define log_internal_realm(level, error, file, line, func, format, ...) \ + ({ \ + const int _nm_e = (error); \ + const NMLogLevel _nm_l = nm_log_level_from_syslog(LOG_PRI(level)); \ + \ + if (_nm_log_enabled_impl(!(NM_THREAD_SAFE_ON_MAIN_THREAD), _nm_l, LOGD_SYSTEMD)) { \ + const char *_nm_location = strrchr(("" file), '/'); \ + \ + _nm_log_impl(_nm_location ? _nm_location + 1 : ("" file), \ + (line), \ + (func), \ + !(NM_THREAD_SAFE_ON_MAIN_THREAD), \ + _nm_l, \ + LOGD_SYSTEMD, \ + _nm_e, \ + NULL, \ + NULL, \ + ("%s" format), \ + "libsystemd: ", \ + ##__VA_ARGS__); \ + } \ + (_nm_e > 0 ? -_nm_e : _nm_e); \ + }) + +#define log_assert_failed(text, file, line, func) \ + G_STMT_START \ + { \ + log_internal(LOG_CRIT, \ + 0, \ + file, \ + line, \ + func, \ + "Assertion '%s' failed at %s:%u, function %s(). Aborting.", \ + text, \ + file, \ + line, \ + func); \ + g_assert_not_reached(); \ + } \ + G_STMT_END + +#define log_assert_failed_unreachable(text, file, line, func) \ + G_STMT_START \ + { \ + log_internal(LOG_CRIT, \ + 0, \ + file, \ + line, \ + func, \ + "Code should not be reached '%s' at %s:%u, function %s(). Aborting.", \ + text, \ + file, \ + line, \ + func); \ + g_assert_not_reached(); \ + } \ + G_STMT_END + +#define log_assert_failed_return(text, file, line, func) \ + ({ \ + log_internal(LOG_DEBUG, \ + 0, \ + file, \ + line, \ + func, \ + "Assertion '%s' failed at %s:%u, function %s(). Ignoring.", \ + text, \ + file, \ + line, \ + func); \ + g_return_if_fail_warning(G_LOG_DOMAIN, G_STRFUNC, text); \ + (void) 0; \ + }) + +/*****************************************************************************/ + +#ifndef VALGRIND + #define VALGRIND 0 +#endif + +#define ENABLE_DEBUG_HASHMAP 0 + +/***************************************************************************** + * The remainder of the header is only enabled when building the systemd code + * itself. + *****************************************************************************/ + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD + + #include + #include + #include + + #define ENABLE_GSHADOW FALSE + + #define HAVE_SECCOMP 0 + +/*****************************************************************************/ + +/* systemd cannot be compiled with "-Wdeclaration-after-statement". In particular + * in combination with assert_cc(). */ +NM_PRAGMA_WARNING_DISABLE("-Wdeclaration-after-statement") + +/*****************************************************************************/ + +struct statx; + +/*****************************************************************************/ + +static inline pid_t +raw_getpid(void) +{ + #if defined(__alpha__) + return (pid_t) syscall(__NR_getxpid); + #else + return (pid_t) syscall(__NR_getpid); + #endif +} + +static inline pid_t +_nm_gettid(void) +{ + return (pid_t) syscall(SYS_gettid); +} + #define gettid() _nm_gettid() + + /* we build with C11 and thus provides char32_t,char16_t. */ + #define HAVE_CHAR32_T 1 + #define HAVE_CHAR16_T 1 + + #if defined(HAVE_DECL_REALLOCARRAY) && HAVE_DECL_REALLOCARRAY == 1 + #define HAVE_REALLOCARRAY 1 + #else + #define HAVE_REALLOCARRAY 0 + #endif + + #if defined(HAVE_DECL_EXPLICIT_BZERO) && HAVE_DECL_EXPLICIT_BZERO == 1 + #define HAVE_EXPLICIT_BZERO 1 + #else + #define HAVE_EXPLICIT_BZERO 0 + #endif + + #if defined(HAVE_DECL_PIDFD_OPEN) && HAVE_DECL_PIDFD_OPEN == 1 + #define HAVE_PIDFD_OPEN 1 + #else + #define HAVE_PIDFD_OPEN 0 + #endif + + #if defined(HAVE_DECL_PIDFD_SEND_SIGNAL) && HAVE_DECL_PIDFD_SEND_SIGNAL == 1 + #define HAVE_PIDFD_SEND_SIGNAL 1 + #else + #define HAVE_PIDFD_SEND_SIGNAL 0 + #endif + + #if defined(HAVE_DECL_RT_SIGQUEUEINFO) && HAVE_DECL_RT_SIGQUEUEINFO == 1 + #define HAVE_RT_SIGQUEUEINFO 1 + #else + #define HAVE_RT_SIGQUEUEINFO 0 + #endif + + #ifndef __COMPAR_FN_T + #define __COMPAR_FN_T +typedef int (*__compar_fn_t)(const void *, const void *); +typedef __compar_fn_t comparison_fn_t; +typedef int (*__compar_d_fn_t)(const void *, const void *, void *); + #endif + + #ifndef __GLIBC__ +static inline int +__register_atfork(void (*prepare)(void), + void (*parent)(void), + void (*child)(void), + void *dso_handle) +{ + return pthread_atfork(prepare, parent, child); +} + #endif + +#endif /* (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD */ + +/*****************************************************************************/ + +#endif /* __NM_SD_ADAPT_SHARED_H__ */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/nulstr-util.h b/src/libnm-systemd-shared/sd-adapt-shared/nulstr-util.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/nulstr-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/raw-clone.h b/src/libnm-systemd-shared/sd-adapt-shared/raw-clone.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/raw-clone.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/rlimit-util.h b/src/libnm-systemd-shared/sd-adapt-shared/rlimit-util.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/rlimit-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/terminal-util.h b/src/libnm-systemd-shared/sd-adapt-shared/terminal-util.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/terminal-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/unaligned.h b/src/libnm-systemd-shared/sd-adapt-shared/unaligned.h new file mode 100644 index 0000000..583a368 --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/unaligned.h @@ -0,0 +1,3 @@ +#pragma once + +#include "libnm-std-aux/unaligned.h" diff --git a/src/libnm-systemd-shared/sd-adapt-shared/user-util.h b/src/libnm-systemd-shared/sd-adapt-shared/user-util.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/user-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/virt.h b/src/libnm-systemd-shared/sd-adapt-shared/virt.h new file mode 100644 index 0000000..637892c --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/virt.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/src/basic/alloc-util.c b/src/libnm-systemd-shared/src/basic/alloc-util.c new file mode 100644 index 0000000..7f7eb43 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/alloc-util.c @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include + +#include "alloc-util.h" +#include "macro.h" +#include "memory-util.h" + +void* memdup(const void *p, size_t l) { + void *ret; + + assert(l == 0 || p); + + ret = malloc(l ?: 1); + if (!ret) + return NULL; + + memcpy(ret, p, l); + return ret; +} + +void* memdup_suffix0(const void *p, size_t l) { + void *ret; + + assert(l == 0 || p); + + /* The same as memdup() but place a safety NUL byte after the allocated memory */ + + if (_unlikely_(l == SIZE_MAX)) /* prevent overflow */ + return NULL; + + ret = malloc(l + 1); + if (!ret) + return NULL; + + *((uint8_t*) mempcpy(ret, p, l)) = 0; + return ret; +} + +void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) { + size_t a, newalloc; + void *q; + + assert(p); + assert(allocated); + + if (*allocated >= need) + return *p; + + if (_unlikely_(need > SIZE_MAX/2)) /* Overflow check */ + return NULL; + + newalloc = need * 2; + if (size_multiply_overflow(newalloc, size)) + return NULL; + + a = newalloc * size; + if (a < 64) /* Allocate at least 64 bytes */ + a = 64; + + q = realloc(*p, a); + if (!q) + return NULL; + + if (size > 0) { + size_t bn; + + /* Adjust for the 64 byte minimum */ + newalloc = a / size; + + bn = malloc_usable_size(q) / size; + if (bn > newalloc) { + void *qq; + + /* The actual size allocated is larger than what we asked for. Let's call realloc() again to + * take possession of the extra space. This should be cheap, since libc doesn't have to move + * the memory for this. */ + + qq = reallocarray(q, bn, size); + if (_likely_(qq)) { + *p = qq; + *allocated = bn; + return qq; + } + } + } + + *p = q; + *allocated = newalloc; + return q; +} + +void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) { + size_t prev; + uint8_t *q; + + assert(p); + assert(allocated); + + prev = *allocated; + + q = greedy_realloc(p, allocated, need, size); + if (!q) + return NULL; + + if (*allocated > prev) + memzero(q + prev * size, (*allocated - prev) * size); + + return q; +} diff --git a/src/libnm-systemd-shared/src/basic/alloc-util.h b/src/libnm-systemd-shared/src/basic/alloc-util.h new file mode 100644 index 0000000..f3e192d --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/alloc-util.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include + +#include "macro.h" + +#if HAS_FEATURE_MEMORY_SANITIZER +# include +#endif + +typedef void (*free_func_t)(void *p); + +/* If for some reason more than 4M are allocated on the stack, let's abort immediately. It's better than + * proceeding and smashing the stack limits. Note that by default RLIMIT_STACK is 8M on Linux. */ +#define ALLOCA_MAX (4U*1024U*1024U) + +#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n))) + +#define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t))) + +#define newa(t, n) \ + ({ \ + size_t _n_ = n; \ + assert(!size_multiply_overflow(sizeof(t), _n_)); \ + assert(sizeof(t)*_n_ <= ALLOCA_MAX); \ + (t*) alloca((sizeof(t)*_n_) ?: 1); \ + }) + +#define newa0(t, n) \ + ({ \ + size_t _n_ = n; \ + assert(!size_multiply_overflow(sizeof(t), _n_)); \ + assert(sizeof(t)*_n_ <= ALLOCA_MAX); \ + (t*) alloca0((sizeof(t)*_n_) ?: 1); \ + }) + +#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n))) + +#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n))) + +#define malloc0(n) (calloc(1, (n) ?: 1)) + +static inline void *mfree(void *memory) { + free(memory); + return NULL; +} + +#define free_and_replace(a, b) \ + ({ \ + free(a); \ + (a) = (b); \ + (b) = NULL; \ + 0; \ + }) + +void* memdup(const void *p, size_t l) _alloc_(2); +void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, since we return a buffer one byte larger than the specified size */ + +#define memdupa(p, l) \ + ({ \ + void *_q_; \ + size_t _l_ = l; \ + assert(_l_ <= ALLOCA_MAX); \ + _q_ = alloca(_l_ ?: 1); \ + memcpy(_q_, p, _l_); \ + }) + +#define memdupa_suffix0(p, l) \ + ({ \ + void *_q_; \ + size_t _l_ = l; \ + assert(_l_ <= ALLOCA_MAX); \ + _q_ = alloca(_l_ + 1); \ + ((uint8_t*) _q_)[_l_] = 0; \ + memcpy(_q_, p, _l_); \ + }) + +static inline void freep(void *p) { + free(*(void**) p); +} + +#define _cleanup_free_ _cleanup_(freep) + +static inline bool size_multiply_overflow(size_t size, size_t need) { + return _unlikely_(need != 0 && size > (SIZE_MAX / need)); +} + +_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) { + if (size_multiply_overflow(size, need)) + return NULL; + + return malloc(size * need ?: 1); +} + +#if !HAVE_REALLOCARRAY +_alloc_(2, 3) static inline void *reallocarray(void *p, size_t need, size_t size) { + if (size_multiply_overflow(size, need)) + return NULL; + + return realloc(p, size * need ?: 1); +} +#endif + +_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) { + if (size_multiply_overflow(size, need)) + return NULL; + + return memdup(p, size * need); +} + +/* Note that we can't decorate this function with _alloc_() since the returned memory area is one byte larger + * than the product of its parameters. */ +static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) { + if (size_multiply_overflow(size, need)) + return NULL; + + return memdup_suffix0(p, size * need); +} + +void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size); +void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size); + +#define GREEDY_REALLOC(array, allocated, need) \ + greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0])) + +#define GREEDY_REALLOC0(array, allocated, need) \ + greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0])) + +#define alloca0(n) \ + ({ \ + char *_new_; \ + size_t _len_ = n; \ + assert(_len_ <= ALLOCA_MAX); \ + _new_ = alloca(_len_ ?: 1); \ + (void *) memset(_new_, 0, _len_); \ + }) + +/* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */ +#define alloca_align(size, align) \ + ({ \ + void *_ptr_; \ + size_t _mask_ = (align) - 1; \ + size_t _size_ = size; \ + assert(_size_ <= ALLOCA_MAX); \ + _ptr_ = alloca((_size_ + _mask_) ?: 1); \ + (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \ + }) + +#define alloca0_align(size, align) \ + ({ \ + void *_new_; \ + size_t _xsize_ = (size); \ + _new_ = alloca_align(_xsize_, (align)); \ + (void*)memset(_new_, 0, _xsize_); \ + }) + +/* Takes inspiration from Rust's Option::take() method: reads and returns a pointer, but at the same time + * resets it to NULL. See: https://doc.rust-lang.org/std/option/enum.Option.html#method.take */ +#define TAKE_PTR(ptr) \ + ({ \ + typeof(ptr) _ptr_ = (ptr); \ + (ptr) = NULL; \ + _ptr_; \ + }) + +#if HAS_FEATURE_MEMORY_SANITIZER +# define msan_unpoison(r, s) __msan_unpoison(r, s) +#else +# define msan_unpoison(r, s) +#endif diff --git a/src/libnm-systemd-shared/src/basic/async.h b/src/libnm-systemd-shared/src/basic/async.h new file mode 100644 index 0000000..e0bbaa5 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/async.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#include "macro.h" + +int asynchronous_job(void* (*func)(void *p), void *arg); + +int asynchronous_sync(pid_t *ret_pid); +int asynchronous_close(int fd); + +DEFINE_TRIVIAL_CLEANUP_FUNC(int, asynchronous_close); diff --git a/src/libnm-systemd-shared/src/basic/cgroup-util.h b/src/libnm-systemd-shared/src/basic/cgroup-util.h new file mode 100644 index 0000000..bdc0d0d --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/cgroup-util.h @@ -0,0 +1,290 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "def.h" +#include "set.h" + +#define SYSTEMD_CGROUP_CONTROLLER_LEGACY "name=systemd" +#define SYSTEMD_CGROUP_CONTROLLER_HYBRID "name=unified" +#define SYSTEMD_CGROUP_CONTROLLER "_systemd" + +/* An enum of well known cgroup controllers */ +typedef enum CGroupController { + /* Original cgroup controllers */ + CGROUP_CONTROLLER_CPU, + CGROUP_CONTROLLER_CPUACCT, /* v1 only */ + CGROUP_CONTROLLER_CPUSET, /* v2 only */ + CGROUP_CONTROLLER_IO, /* v2 only */ + CGROUP_CONTROLLER_BLKIO, /* v1 only */ + CGROUP_CONTROLLER_MEMORY, + CGROUP_CONTROLLER_DEVICES, /* v1 only */ + CGROUP_CONTROLLER_PIDS, + + /* BPF-based pseudo-controllers, v2 only */ + CGROUP_CONTROLLER_BPF_FIREWALL, + CGROUP_CONTROLLER_BPF_DEVICES, + + _CGROUP_CONTROLLER_MAX, + _CGROUP_CONTROLLER_INVALID = -1, +} CGroupController; + +#define CGROUP_CONTROLLER_TO_MASK(c) (1U << (c)) + +/* A bit mask of well known cgroup controllers */ +typedef enum CGroupMask { + CGROUP_MASK_CPU = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPU), + CGROUP_MASK_CPUACCT = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUACCT), + CGROUP_MASK_CPUSET = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUSET), + CGROUP_MASK_IO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_IO), + CGROUP_MASK_BLKIO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BLKIO), + CGROUP_MASK_MEMORY = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_MEMORY), + CGROUP_MASK_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_DEVICES), + CGROUP_MASK_PIDS = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_PIDS), + CGROUP_MASK_BPF_FIREWALL = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_FIREWALL), + CGROUP_MASK_BPF_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_DEVICES), + + /* All real cgroup v1 controllers */ + CGROUP_MASK_V1 = CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT|CGROUP_MASK_BLKIO|CGROUP_MASK_MEMORY|CGROUP_MASK_DEVICES|CGROUP_MASK_PIDS, + + /* All real cgroup v2 controllers */ + CGROUP_MASK_V2 = CGROUP_MASK_CPU|CGROUP_MASK_CPUSET|CGROUP_MASK_IO|CGROUP_MASK_MEMORY|CGROUP_MASK_PIDS, + + /* All cgroup v2 BPF pseudo-controllers */ + CGROUP_MASK_BPF = CGROUP_MASK_BPF_FIREWALL|CGROUP_MASK_BPF_DEVICES, + + _CGROUP_MASK_ALL = CGROUP_CONTROLLER_TO_MASK(_CGROUP_CONTROLLER_MAX) - 1 +} CGroupMask; + +static inline CGroupMask CGROUP_MASK_EXTEND_JOINED(CGroupMask mask) { + /* We always mount "cpu" and "cpuacct" in the same hierarchy. Hence, when one bit is set also set the other */ + + if (mask & (CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT)) + mask |= (CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT); + + return mask; +} + +CGroupMask get_cpu_accounting_mask(void); +bool cpu_accounting_is_cheap(void); + +/* Special values for all weight knobs on unified hierarchy */ +#define CGROUP_WEIGHT_INVALID ((uint64_t) -1) +#define CGROUP_WEIGHT_MIN UINT64_C(1) +#define CGROUP_WEIGHT_MAX UINT64_C(10000) +#define CGROUP_WEIGHT_DEFAULT UINT64_C(100) + +#define CGROUP_LIMIT_MIN UINT64_C(0) +#define CGROUP_LIMIT_MAX ((uint64_t) -1) + +static inline bool CGROUP_WEIGHT_IS_OK(uint64_t x) { + return + x == CGROUP_WEIGHT_INVALID || + (x >= CGROUP_WEIGHT_MIN && x <= CGROUP_WEIGHT_MAX); +} + +/* IO limits on unified hierarchy */ +typedef enum CGroupIOLimitType { + CGROUP_IO_RBPS_MAX, + CGROUP_IO_WBPS_MAX, + CGROUP_IO_RIOPS_MAX, + CGROUP_IO_WIOPS_MAX, + + _CGROUP_IO_LIMIT_TYPE_MAX, + _CGROUP_IO_LIMIT_TYPE_INVALID = -1 +} CGroupIOLimitType; + +extern const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX]; + +const char* cgroup_io_limit_type_to_string(CGroupIOLimitType t) _const_; +CGroupIOLimitType cgroup_io_limit_type_from_string(const char *s) _pure_; + +/* Special values for the cpu.shares attribute */ +#define CGROUP_CPU_SHARES_INVALID ((uint64_t) -1) +#define CGROUP_CPU_SHARES_MIN UINT64_C(2) +#define CGROUP_CPU_SHARES_MAX UINT64_C(262144) +#define CGROUP_CPU_SHARES_DEFAULT UINT64_C(1024) + +static inline bool CGROUP_CPU_SHARES_IS_OK(uint64_t x) { + return + x == CGROUP_CPU_SHARES_INVALID || + (x >= CGROUP_CPU_SHARES_MIN && x <= CGROUP_CPU_SHARES_MAX); +} + +/* Special values for the blkio.weight attribute */ +#define CGROUP_BLKIO_WEIGHT_INVALID ((uint64_t) -1) +#define CGROUP_BLKIO_WEIGHT_MIN UINT64_C(10) +#define CGROUP_BLKIO_WEIGHT_MAX UINT64_C(1000) +#define CGROUP_BLKIO_WEIGHT_DEFAULT UINT64_C(500) + +static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) { + return + x == CGROUP_BLKIO_WEIGHT_INVALID || + (x >= CGROUP_BLKIO_WEIGHT_MIN && x <= CGROUP_BLKIO_WEIGHT_MAX); +} + +typedef enum CGroupUnified { + CGROUP_UNIFIED_UNKNOWN = -1, + CGROUP_UNIFIED_NONE = 0, /* Both systemd and controllers on legacy */ + CGROUP_UNIFIED_SYSTEMD = 1, /* Only systemd on unified */ + CGROUP_UNIFIED_ALL = 2, /* Both systemd and controllers on unified */ +} CGroupUnified; + +/* + * General rules: + * + * We accept named hierarchies in the syntax "foo" and "name=foo". + * + * We expect that named hierarchies do not conflict in name with a + * kernel hierarchy, modulo the "name=" prefix. + * + * We always generate "normalized" controller names, i.e. without the + * "name=" prefix. + * + * We require absolute cgroup paths. When returning, we will always + * generate paths with multiple adjacent / removed. + */ + +int cg_enumerate_processes(const char *controller, const char *path, FILE **_f); +int cg_read_pid(FILE *f, pid_t *_pid); +int cg_read_event(const char *controller, const char *path, const char *event, + char **val); + +int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d); +int cg_read_subgroup(DIR *d, char **fn); + +typedef enum CGroupFlags { + CGROUP_SIGCONT = 1 << 0, + CGROUP_IGNORE_SELF = 1 << 1, + CGROUP_REMOVE = 1 << 2, +} CGroupFlags; + +typedef int (*cg_kill_log_func_t)(pid_t pid, int sig, void *userdata); + +int cg_kill(const char *controller, const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata); +int cg_kill_recursive(const char *controller, const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata); + +int cg_split_spec(const char *spec, char **ret_controller, char **ret_path); +int cg_mangle_path(const char *path, char **result); + +int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs); +int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs); + +int cg_pid_get_path(const char *controller, pid_t pid, char **path); + +int cg_rmdir(const char *controller, const char *path); + +typedef enum { + CG_KEY_MODE_GRACEFUL = 1 << 0, +} CGroupKeyMode; + +int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value); +int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret); +int cg_get_keyed_attribute_full(const char *controller, const char *path, const char *attribute, char **keys, char **values, CGroupKeyMode mode); + +static inline int cg_get_keyed_attribute( + const char *controller, + const char *path, + const char *attribute, + char **keys, + char **ret_values) { + return cg_get_keyed_attribute_full(controller, path, attribute, keys, ret_values, 0); +} + +static inline int cg_get_keyed_attribute_graceful( + const char *controller, + const char *path, + const char *attribute, + char **keys, + char **ret_values) { + return cg_get_keyed_attribute_full(controller, path, attribute, keys, ret_values, CG_KEY_MODE_GRACEFUL); +} + +int cg_get_attribute_as_uint64(const char *controller, const char *path, const char *attribute, uint64_t *ret); + +/* Does a parse_boolean() on the attribute contents and sets ret accordingly */ +int cg_get_attribute_as_bool(const char *controller, const char *path, const char *attribute, bool *ret); + +int cg_set_access(const char *controller, const char *path, uid_t uid, gid_t gid); + +int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags); +int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size); +int cg_get_xattr_malloc(const char *controller, const char *path, const char *name, char **ret); +int cg_remove_xattr(const char *controller, const char *path, const char *name); + +int cg_install_release_agent(const char *controller, const char *agent); +int cg_uninstall_release_agent(const char *controller); + +int cg_is_empty(const char *controller, const char *path); +int cg_is_empty_recursive(const char *controller, const char *path); + +int cg_get_root_path(char **path); + +int cg_path_get_session(const char *path, char **session); +int cg_path_get_owner_uid(const char *path, uid_t *uid); +int cg_path_get_unit(const char *path, char **unit); +int cg_path_get_user_unit(const char *path, char **unit); +int cg_path_get_machine_name(const char *path, char **machine); +int cg_path_get_slice(const char *path, char **slice); +int cg_path_get_user_slice(const char *path, char **slice); + +int cg_shift_path(const char *cgroup, const char *cached_root, const char **shifted); +int cg_pid_get_path_shifted(pid_t pid, const char *cached_root, char **cgroup); + +int cg_pid_get_session(pid_t pid, char **session); +int cg_pid_get_owner_uid(pid_t pid, uid_t *uid); +int cg_pid_get_unit(pid_t pid, char **unit); +int cg_pid_get_user_unit(pid_t pid, char **unit); +int cg_pid_get_machine_name(pid_t pid, char **machine); +int cg_pid_get_slice(pid_t pid, char **slice); +int cg_pid_get_user_slice(pid_t pid, char **slice); + +int cg_path_decode_unit(const char *cgroup, char **unit); + +char *cg_escape(const char *p); +char *cg_unescape(const char *p) _pure_; + +bool cg_controller_is_valid(const char *p); + +int cg_slice_to_path(const char *unit, char **ret); + +typedef const char* (*cg_migrate_callback_t)(CGroupMask mask, void *userdata); + +int cg_mask_supported(CGroupMask *ret); +int cg_mask_from_string(const char *s, CGroupMask *ret); +int cg_mask_to_string(CGroupMask mask, char **ret); + +int cg_kernel_controllers(Set **controllers); + +bool cg_ns_supported(void); +bool cg_freezer_supported(void); + +int cg_all_unified(void); +int cg_hybrid_unified(void); +int cg_unified_controller(const char *controller); +int cg_unified_cached(bool flush); +static inline int cg_unified(void) { + return cg_unified_cached(true); +} + +const char* cgroup_controller_to_string(CGroupController c) _const_; +CGroupController cgroup_controller_from_string(const char *s) _pure_; + +bool is_cgroup_fs(const struct statfs *s); +bool fd_is_cgroup_fs(int fd); + +typedef enum ManagedOOMMode { + MANAGED_OOM_AUTO, + MANAGED_OOM_KILL, + _MANAGED_OOM_MODE_MAX, + _MANAGED_OOM_MODE_INVALID = -1, +} ManagedOOMMode; + +const char* managed_oom_mode_to_string(ManagedOOMMode m) _const_; +ManagedOOMMode managed_oom_mode_from_string(const char *s) _pure_; diff --git a/src/libnm-systemd-shared/src/basic/env-file.c b/src/libnm-systemd-shared/src/basic/env-file.c new file mode 100644 index 0000000..568b742 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/env-file.c @@ -0,0 +1,571 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include "alloc-util.h" +#include "env-file.h" +#include "env-util.h" +#include "escape.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" +#include "string-util.h" +#include "strv.h" +#include "tmpfile-util.h" +#include "utf8.h" + +static int parse_env_file_internal( + FILE *f, + const char *fname, + int (*push) (const char *filename, unsigned line, + const char *key, char *value, void *userdata, int *n_pushed), + void *userdata, + int *n_pushed) { + + size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1; + _cleanup_free_ char *contents = NULL, *key = NULL, *value = NULL; + unsigned line = 1; + char *p; + int r; + + enum { + PRE_KEY, + KEY, + PRE_VALUE, + VALUE, + VALUE_ESCAPE, + SINGLE_QUOTE_VALUE, + DOUBLE_QUOTE_VALUE, + DOUBLE_QUOTE_VALUE_ESCAPE, + COMMENT, + COMMENT_ESCAPE + } state = PRE_KEY; + + if (f) + r = read_full_stream(f, &contents, NULL); + else + r = read_full_file(fname, &contents, NULL); + if (r < 0) + return r; + + for (p = contents; *p; p++) { + char c = *p; + + switch (state) { + + case PRE_KEY: + if (strchr(COMMENTS, c)) + state = COMMENT; + else if (!strchr(WHITESPACE, c)) { + state = KEY; + last_key_whitespace = (size_t) -1; + + if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) + return -ENOMEM; + + key[n_key++] = c; + } + break; + + case KEY: + if (strchr(NEWLINE, c)) { + state = PRE_KEY; + line++; + n_key = 0; + } else if (c == '=') { + state = PRE_VALUE; + last_value_whitespace = (size_t) -1; + } else { + if (!strchr(WHITESPACE, c)) + last_key_whitespace = (size_t) -1; + else if (last_key_whitespace == (size_t) -1) + last_key_whitespace = n_key; + + if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) + return -ENOMEM; + + key[n_key++] = c; + } + + break; + + case PRE_VALUE: + if (strchr(NEWLINE, c)) { + state = PRE_KEY; + line++; + key[n_key] = 0; + + if (value) + value[n_value] = 0; + + /* strip trailing whitespace from key */ + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + + r = push(fname, line, key, value, userdata, n_pushed); + if (r < 0) + return r; + + n_key = 0; + value = NULL; + value_alloc = n_value = 0; + + } else if (c == '\'') + state = SINGLE_QUOTE_VALUE; + else if (c == '"') + state = DOUBLE_QUOTE_VALUE; + else if (c == '\\') + state = VALUE_ESCAPE; + else if (!strchr(WHITESPACE, c)) { + state = VALUE; + + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) + return -ENOMEM; + + value[n_value++] = c; + } + + break; + + case VALUE: + if (strchr(NEWLINE, c)) { + state = PRE_KEY; + line++; + + key[n_key] = 0; + + if (value) + value[n_value] = 0; + + /* Chomp off trailing whitespace from value */ + if (last_value_whitespace != (size_t) -1) + value[last_value_whitespace] = 0; + + /* strip trailing whitespace from key */ + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + + r = push(fname, line, key, value, userdata, n_pushed); + if (r < 0) + return r; + + n_key = 0; + value = NULL; + value_alloc = n_value = 0; + + } else if (c == '\\') { + state = VALUE_ESCAPE; + last_value_whitespace = (size_t) -1; + } else { + if (!strchr(WHITESPACE, c)) + last_value_whitespace = (size_t) -1; + else if (last_value_whitespace == (size_t) -1) + last_value_whitespace = n_value; + + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) + return -ENOMEM; + + value[n_value++] = c; + } + + break; + + case VALUE_ESCAPE: + state = VALUE; + + if (!strchr(NEWLINE, c)) { + /* Escaped newlines we eat up entirely */ + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) + return -ENOMEM; + + value[n_value++] = c; + } + break; + + case SINGLE_QUOTE_VALUE: + if (c == '\'') + state = PRE_VALUE; + else { + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) + return -ENOMEM; + + value[n_value++] = c; + } + + break; + + case DOUBLE_QUOTE_VALUE: + if (c == '"') + state = PRE_VALUE; + else if (c == '\\') + state = DOUBLE_QUOTE_VALUE_ESCAPE; + else { + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) + return -ENOMEM; + + value[n_value++] = c; + } + + break; + + case DOUBLE_QUOTE_VALUE_ESCAPE: + state = DOUBLE_QUOTE_VALUE; + + if (strchr(SHELL_NEED_ESCAPE, c)) { + /* If this is a char that needs escaping, just unescape it. */ + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) + return -ENOMEM; + value[n_value++] = c; + } else if (c != '\n') { + /* If other char than what needs escaping, keep the "\" in place, like the + * real shell does. */ + if (!GREEDY_REALLOC(value, value_alloc, n_value+3)) + return -ENOMEM; + value[n_value++] = '\\'; + value[n_value++] = c; + } + + /* Escaped newlines (aka "continuation lines") are eaten up entirely */ + break; + + case COMMENT: + if (c == '\\') + state = COMMENT_ESCAPE; + else if (strchr(NEWLINE, c)) { + state = PRE_KEY; + line++; + } + break; + + case COMMENT_ESCAPE: + state = COMMENT; + break; + } + } + + if (IN_SET(state, + PRE_VALUE, + VALUE, + VALUE_ESCAPE, + SINGLE_QUOTE_VALUE, + DOUBLE_QUOTE_VALUE, + DOUBLE_QUOTE_VALUE_ESCAPE)) { + + key[n_key] = 0; + + if (value) + value[n_value] = 0; + + if (state == VALUE) + if (last_value_whitespace != (size_t) -1) + value[last_value_whitespace] = 0; + + /* strip trailing whitespace from key */ + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + + r = push(fname, line, key, value, userdata, n_pushed); + if (r < 0) + return r; + + value = NULL; + } + + return 0; +} + +static int check_utf8ness_and_warn( + const char *filename, unsigned line, + const char *key, char *value) { + + if (!utf8_is_valid(key)) { + _cleanup_free_ char *p = NULL; + + p = utf8_escape_invalid(key); + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "%s:%u: invalid UTF-8 in key '%s', ignoring.", + strna(filename), line, p); + } + + if (value && !utf8_is_valid(value)) { + _cleanup_free_ char *p = NULL; + + p = utf8_escape_invalid(value); + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", + strna(filename), line, key, p); + } + + return 0; +} + +static int parse_env_file_push( + const char *filename, unsigned line, + const char *key, char *value, + void *userdata, + int *n_pushed) { + + const char *k; + va_list aq, *ap = userdata; + int r; + + r = check_utf8ness_and_warn(filename, line, key, value); + if (r < 0) + return r; + + va_copy(aq, *ap); + + while ((k = va_arg(aq, const char *))) { + char **v; + + v = va_arg(aq, char **); + + if (streq(key, k)) { + va_end(aq); + free(*v); + *v = value; + + if (n_pushed) + (*n_pushed)++; + + return 1; + } + } + + va_end(aq); + free(value); + + return 0; +} + +int parse_env_filev( + FILE *f, + const char *fname, + va_list ap) { + + int r, n_pushed = 0; + va_list aq; + + va_copy(aq, ap); + r = parse_env_file_internal(f, fname, parse_env_file_push, &aq, &n_pushed); + va_end(aq); + if (r < 0) + return r; + + return n_pushed; +} + +int parse_env_file_sentinel( + FILE *f, + const char *fname, + ...) { + + va_list ap; + int r; + + va_start(ap, fname); + r = parse_env_filev(f, fname, ap); + va_end(ap); + + return r; +} + +#if 0 /* NM_IGNORED */ +static int load_env_file_push( + const char *filename, unsigned line, + const char *key, char *value, + void *userdata, + int *n_pushed) { + char ***m = userdata; + char *p; + int r; + + r = check_utf8ness_and_warn(filename, line, key, value); + if (r < 0) + return r; + + p = strjoin(key, "=", value); + if (!p) + return -ENOMEM; + + r = strv_env_replace(m, p); + if (r < 0) { + free(p); + return r; + } + + if (n_pushed) + (*n_pushed)++; + + free(value); + return 0; +} + +int load_env_file(FILE *f, const char *fname, char ***rl) { + char **m = NULL; + int r; + + r = parse_env_file_internal(f, fname, load_env_file_push, &m, NULL); + if (r < 0) { + strv_free(m); + return r; + } + + *rl = m; + return 0; +} + +static int load_env_file_push_pairs( + const char *filename, unsigned line, + const char *key, char *value, + void *userdata, + int *n_pushed) { + char ***m = userdata; + int r; + + r = check_utf8ness_and_warn(filename, line, key, value); + if (r < 0) + return r; + + r = strv_extend(m, key); + if (r < 0) + return -ENOMEM; + + if (!value) { + r = strv_extend(m, ""); + if (r < 0) + return -ENOMEM; + } else { + r = strv_push(m, value); + if (r < 0) + return r; + } + + if (n_pushed) + (*n_pushed)++; + + return 0; +} + +int load_env_file_pairs(FILE *f, const char *fname, char ***rl) { + char **m = NULL; + int r; + + r = parse_env_file_internal(f, fname, load_env_file_push_pairs, &m, NULL); + if (r < 0) { + strv_free(m); + return r; + } + + *rl = m; + return 0; +} + +static int merge_env_file_push( + const char *filename, unsigned line, + const char *key, char *value, + void *userdata, + int *n_pushed) { + + char ***env = userdata; + char *expanded_value; + + assert(env); + + if (!value) { + log_error("%s:%u: invalid syntax (around \"%s\"), ignoring.", strna(filename), line, key); + return 0; + } + + if (!env_name_is_valid(key)) { + log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename), line, key); + free(value); + return 0; + } + + expanded_value = replace_env(value, *env, + REPLACE_ENV_USE_ENVIRONMENT| + REPLACE_ENV_ALLOW_BRACELESS| + REPLACE_ENV_ALLOW_EXTENDED); + if (!expanded_value) + return -ENOMEM; + + free_and_replace(value, expanded_value); + + log_debug("%s:%u: setting %s=%s", filename, line, key, value); + + return load_env_file_push(filename, line, key, value, env, n_pushed); +} + +int merge_env_file( + char ***env, + FILE *f, + const char *fname) { + + /* NOTE: this function supports braceful and braceless variable expansions, + * plus "extended" substitutions, unlike other exported parsing functions. + */ + + return parse_env_file_internal(f, fname, merge_env_file_push, env, NULL); +} + +static void write_env_var(FILE *f, const char *v) { + const char *p; + + p = strchr(v, '='); + if (!p) { + /* Fallback */ + fputs_unlocked(v, f); + fputc_unlocked('\n', f); + return; + } + + p++; + fwrite_unlocked(v, 1, p-v, f); + + if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE SHELL_NEED_QUOTES)) { + fputc_unlocked('"', f); + + for (; *p; p++) { + if (strchr(SHELL_NEED_ESCAPE, *p)) + fputc_unlocked('\\', f); + + fputc_unlocked(*p, f); + } + + fputc_unlocked('"', f); + } else + fputs_unlocked(p, f); + + fputc_unlocked('\n', f); +} + +int write_env_file(const char *fname, char **l) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *p = NULL; + char **i; + int r; + + assert(fname); + + r = fopen_temporary(fname, &f, &p); + if (r < 0) + return r; + + (void) fchmod_umask(fileno(f), 0644); + + STRV_FOREACH(i, l) + write_env_var(f, *i); + + r = fflush_and_check(f); + if (r >= 0) { + if (rename(p, fname) >= 0) + return 0; + + r = -errno; + } + + (void) unlink(p); + return r; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/env-file.h b/src/libnm-systemd-shared/src/basic/env-file.h new file mode 100644 index 0000000..de47588 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/env-file.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include + +#include "macro.h" + +int parse_env_filev(FILE *f, const char *fname, va_list ap); +int parse_env_file_sentinel(FILE *f, const char *fname, ...) _sentinel_; +#define parse_env_file(f, fname, ...) parse_env_file_sentinel(f, fname, __VA_ARGS__, NULL) +int load_env_file(FILE *f, const char *fname, char ***l); +int load_env_file_pairs(FILE *f, const char *fname, char ***l); + +int merge_env_file(char ***env, FILE *f, const char *fname); + +int write_env_file(const char *fname, char **l); diff --git a/src/libnm-systemd-shared/src/basic/env-util.c b/src/libnm-systemd-shared/src/basic/env-util.c new file mode 100644 index 0000000..a311ee0 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/env-util.c @@ -0,0 +1,767 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "env-util.h" +#include "escape.h" +#include "extract-word.h" +#include "macro.h" +#include "parse-util.h" +#include "string-util.h" +#include "strv.h" +#include "utf8.h" + +#if 0 /* NM_IGNORED */ +/* We follow bash for the character set. Different shells have different rules. */ +#define VALID_BASH_ENV_NAME_CHARS \ + DIGITS LETTERS \ + "_" + +static bool env_name_is_valid_n(const char *e, size_t n) { + const char *p; + + if (!e) + return false; + + if (n <= 0) + return false; + + if (e[0] >= '0' && e[0] <= '9') + return false; + + /* POSIX says the overall size of the environment block cannot + * be > ARG_MAX, an individual assignment hence cannot be + * either. Discounting the equal sign and trailing NUL this + * hence leaves ARG_MAX-2 as longest possible variable + * name. */ + if (n > (size_t) sysconf(_SC_ARG_MAX) - 2) + return false; + + for (p = e; p < e + n; p++) + if (!strchr(VALID_BASH_ENV_NAME_CHARS, *p)) + return false; + + return true; +} + +bool env_name_is_valid(const char *e) { + return env_name_is_valid_n(e, strlen_ptr(e)); +} + +bool env_value_is_valid(const char *e) { + if (!e) + return false; + + if (!utf8_is_valid(e)) + return false; + + /* bash allows tabs and newlines in environment variables, and so + * should we */ + if (string_has_cc(e, "\t\n")) + return false; + + /* POSIX says the overall size of the environment block cannot + * be > ARG_MAX, an individual assignment hence cannot be + * either. Discounting the shortest possible variable name of + * length 1, the equal sign and trailing NUL this hence leaves + * ARG_MAX-3 as longest possible variable value. */ + if (strlen(e) > sc_arg_max() - 3) + return false; + + return true; +} + +bool env_assignment_is_valid(const char *e) { + const char *eq; + + eq = strchr(e, '='); + if (!eq) + return false; + + if (!env_name_is_valid_n(e, eq - e)) + return false; + + if (!env_value_is_valid(eq + 1)) + return false; + + /* POSIX says the overall size of the environment block cannot + * be > ARG_MAX, hence the individual variable assignments + * cannot be either, but let's leave room for one trailing NUL + * byte. */ + if (strlen(e) > sc_arg_max() - 1) + return false; + + return true; +} + +bool strv_env_is_valid(char **e) { + char **p, **q; + + STRV_FOREACH(p, e) { + size_t k; + + if (!env_assignment_is_valid(*p)) + return false; + + /* Check if there are duplicate assignments */ + k = strcspn(*p, "="); + STRV_FOREACH(q, p + 1) + if (strneq(*p, *q, k) && (*q)[k] == '=') + return false; + } + + return true; +} + +bool strv_env_name_is_valid(char **l) { + char **p; + + STRV_FOREACH(p, l) { + if (!env_name_is_valid(*p)) + return false; + + if (strv_contains(p + 1, *p)) + return false; + } + + return true; +} + +bool strv_env_name_or_assignment_is_valid(char **l) { + char **p; + + STRV_FOREACH(p, l) { + if (!env_assignment_is_valid(*p) && !env_name_is_valid(*p)) + return false; + + if (strv_contains(p + 1, *p)) + return false; + } + + return true; +} + +static int env_append(char **r, char ***k, char **a) { + assert(r); + assert(k); + assert(*k >= r); + + if (!a) + return 0; + + /* Expects the following arguments: 'r' shall point to the beginning of an strv we are going to append to, 'k' + * to a pointer pointing to the NULL entry at the end of the same array. 'a' shall point to another strv. + * + * This call adds every entry of 'a' to 'r', either overriding an existing matching entry, or appending to it. + * + * This call assumes 'r' has enough pre-allocated space to grow by all of 'a''s items. */ + + for (; *a; a++) { + char **j, *c; + size_t n; + + n = strcspn(*a, "="); + if ((*a)[n] == '=') + n++; + + for (j = r; j < *k; j++) + if (strneq(*j, *a, n)) + break; + + c = strdup(*a); + if (!c) + return -ENOMEM; + + if (j >= *k) { /* Append to the end? */ + (*k)[0] = c; + (*k)[1] = NULL; + (*k)++; + } else + free_and_replace(*j, c); /* Override existing item */ + } + + return 0; +} + +char **strv_env_merge(size_t n_lists, ...) { + _cleanup_strv_free_ char **ret = NULL; + size_t n = 0, i; + char **l, **k; + va_list ap; + + /* Merges an arbitrary number of environment sets */ + + va_start(ap, n_lists); + for (i = 0; i < n_lists; i++) { + l = va_arg(ap, char**); + n += strv_length(l); + } + va_end(ap); + + ret = new(char*, n+1); + if (!ret) + return NULL; + + *ret = NULL; + k = ret; + + va_start(ap, n_lists); + for (i = 0; i < n_lists; i++) { + l = va_arg(ap, char**); + if (env_append(ret, &k, l) < 0) { + va_end(ap); + return NULL; + } + } + va_end(ap); + + return TAKE_PTR(ret); +} + +static bool env_match(const char *t, const char *pattern) { + assert(t); + assert(pattern); + + /* pattern a matches string a + * a matches a= + * a matches a=b + * a= matches a= + * a=b matches a=b + * a= does not match a + * a=b does not match a= + * a=b does not match a + * a=b does not match a=c */ + + if (streq(t, pattern)) + return true; + + if (!strchr(pattern, '=')) { + size_t l = strlen(pattern); + + return strneq(t, pattern, l) && t[l] == '='; + } + + return false; +} + +static bool env_entry_has_name(const char *entry, const char *name) { + const char *t; + + assert(entry); + assert(name); + + t = startswith(entry, name); + if (!t) + return false; + + return *t == '='; +} + +char **strv_env_delete(char **x, size_t n_lists, ...) { + size_t n, i = 0; + char **k, **r; + va_list ap; + + /* Deletes every entry from x that is mentioned in the other + * string lists */ + + n = strv_length(x); + + r = new(char*, n+1); + if (!r) + return NULL; + + STRV_FOREACH(k, x) { + size_t v; + + va_start(ap, n_lists); + for (v = 0; v < n_lists; v++) { + char **l, **j; + + l = va_arg(ap, char**); + STRV_FOREACH(j, l) + if (env_match(*k, *j)) + goto skip; + } + va_end(ap); + + r[i] = strdup(*k); + if (!r[i]) { + strv_free(r); + return NULL; + } + + i++; + continue; + + skip: + va_end(ap); + } + + r[i] = NULL; + + assert(i <= n); + + return r; +} + +char **strv_env_unset(char **l, const char *p) { + + char **f, **t; + + if (!l) + return NULL; + + assert(p); + + /* Drops every occurrence of the env var setting p in the + * string list. Edits in-place. */ + + for (f = t = l; *f; f++) { + + if (env_match(*f, p)) { + free(*f); + continue; + } + + *(t++) = *f; + } + + *t = NULL; + return l; +} + +char **strv_env_unset_many(char **l, ...) { + char **f, **t; + + if (!l) + return NULL; + + /* Like strv_env_unset() but applies many at once. Edits in-place. */ + + for (f = t = l; *f; f++) { + bool found = false; + const char *p; + va_list ap; + + va_start(ap, l); + + while ((p = va_arg(ap, const char*))) { + if (env_match(*f, p)) { + found = true; + break; + } + } + + va_end(ap); + + if (found) { + free(*f); + continue; + } + + *(t++) = *f; + } + + *t = NULL; + return l; +} + +int strv_env_replace(char ***l, char *p) { + const char *t, *name; + char **f; + int r; + + assert(p); + + /* Replace first occurrence of the env var or add a new one in the string list. Drop other occurrences. Edits + * in-place. Does not copy p. p must be a valid key=value assignment. + */ + + t = strchr(p, '='); + if (!t) + return -EINVAL; + + name = strndupa(p, t - p); + + STRV_FOREACH(f, *l) + if (env_entry_has_name(*f, name)) { + free_and_replace(*f, p); + strv_env_unset(f + 1, *f); + return 0; + } + + /* We didn't find a match, we need to append p or create a new strv */ + r = strv_push(l, p); + if (r < 0) + return r; + + return 1; +} + +char **strv_env_set(char **x, const char *p) { + _cleanup_strv_free_ char **ret = NULL; + size_t n, m; + char **k; + + /* Overrides the env var setting of p, returns a new copy */ + + n = strv_length(x); + m = n + 2; + if (m < n) /* overflow? */ + return NULL; + + ret = new(char*, m); + if (!ret) + return NULL; + + *ret = NULL; + k = ret; + + if (env_append(ret, &k, x) < 0) + return NULL; + + if (env_append(ret, &k, STRV_MAKE(p)) < 0) + return NULL; + + return TAKE_PTR(ret); +} + +char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) { + char **i; + + assert(name); + + if (k <= 0) + return NULL; + + STRV_FOREACH_BACKWARDS(i, l) + if (strneq(*i, name, k) && + (*i)[k] == '=') + return *i + k + 1; + + if (flags & REPLACE_ENV_USE_ENVIRONMENT) { + const char *t; + + t = strndupa(name, k); + return getenv(t); + }; + + return NULL; +} + +char *strv_env_get(char **l, const char *name) { + assert(name); + + return strv_env_get_n(l, name, strlen(name), 0); +} + +char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const char *p, void *userdata), void *userdata) { + char **p, **q; + int k = 0; + + STRV_FOREACH(p, e) { + size_t n; + bool duplicate = false; + + if (!env_assignment_is_valid(*p)) { + if (invalid_callback) + invalid_callback(*p, userdata); + free(*p); + continue; + } + + n = strcspn(*p, "="); + STRV_FOREACH(q, p + 1) + if (strneq(*p, *q, n) && (*q)[n] == '=') { + duplicate = true; + break; + } + + if (duplicate) { + free(*p); + continue; + } + + e[k++] = *p; + } + + if (e) + e[k] = NULL; + + return e; +} + +char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) { + enum { + WORD, + CURLY, + VARIABLE, + VARIABLE_RAW, + TEST, + DEFAULT_VALUE, + ALTERNATE_VALUE, + } state = WORD; + + const char *e, *word = format, *test_value; + char *k; + _cleanup_free_ char *r = NULL; + size_t i, len; + int nest = 0; + + assert(format); + + for (e = format, i = 0; *e && i < n; e ++, i ++) + switch (state) { + + case WORD: + if (*e == '$') + state = CURLY; + break; + + case CURLY: + if (*e == '{') { + k = strnappend(r, word, e-word-1); + if (!k) + return NULL; + + free_and_replace(r, k); + + word = e-1; + state = VARIABLE; + nest++; + } else if (*e == '$') { + k = strnappend(r, word, e-word); + if (!k) + return NULL; + + free_and_replace(r, k); + + word = e+1; + state = WORD; + + } else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_BASH_ENV_NAME_CHARS, *e)) { + k = strnappend(r, word, e-word-1); + if (!k) + return NULL; + + free_and_replace(r, k); + + word = e-1; + state = VARIABLE_RAW; + + } else + state = WORD; + break; + + case VARIABLE: + if (*e == '}') { + const char *t; + + t = strv_env_get_n(env, word+2, e-word-2, flags); + + k = strjoin(r, t); + if (!k) + return NULL; + + free_and_replace(r, k); + + word = e+1; + state = WORD; + } else if (*e == ':') { + if (!(flags & REPLACE_ENV_ALLOW_EXTENDED)) + /* Treat this as unsupported syntax, i.e. do no replacement */ + state = WORD; + else { + len = e-word-2; + state = TEST; + } + } + break; + + case TEST: + if (*e == '-') + state = DEFAULT_VALUE; + else if (*e == '+') + state = ALTERNATE_VALUE; + else { + state = WORD; + break; + } + + test_value = e+1; + break; + + case DEFAULT_VALUE: /* fall through */ + case ALTERNATE_VALUE: + assert(flags & REPLACE_ENV_ALLOW_EXTENDED); + + if (*e == '{') { + nest++; + break; + } + + if (*e != '}') + break; + + nest--; + if (nest == 0) { + const char *t; + _cleanup_free_ char *v = NULL; + + t = strv_env_get_n(env, word+2, len, flags); + + if (t && state == ALTERNATE_VALUE) + t = v = replace_env_n(test_value, e-test_value, env, flags); + else if (!t && state == DEFAULT_VALUE) + t = v = replace_env_n(test_value, e-test_value, env, flags); + + k = strjoin(r, t); + if (!k) + return NULL; + + free_and_replace(r, k); + + word = e+1; + state = WORD; + } + break; + + case VARIABLE_RAW: + assert(flags & REPLACE_ENV_ALLOW_BRACELESS); + + if (!strchr(VALID_BASH_ENV_NAME_CHARS, *e)) { + const char *t; + + t = strv_env_get_n(env, word+1, e-word-1, flags); + + k = strjoin(r, t); + if (!k) + return NULL; + + free_and_replace(r, k); + + word = e--; + i--; + state = WORD; + } + break; + } + + if (state == VARIABLE_RAW) { + const char *t; + + assert(flags & REPLACE_ENV_ALLOW_BRACELESS); + + t = strv_env_get_n(env, word+1, e-word-1, flags); + return strjoin(r, t); + } else + return strnappend(r, word, e-word); +} + +char **replace_env_argv(char **argv, char **env) { + char **ret, **i; + size_t k = 0, l = 0; + + l = strv_length(argv); + + ret = new(char*, l+1); + if (!ret) + return NULL; + + STRV_FOREACH(i, argv) { + + /* If $FOO appears as single word, replace it by the split up variable */ + if ((*i)[0] == '$' && !IN_SET((*i)[1], '{', '$')) { + char *e; + char **w, **m = NULL; + size_t q; + + e = strv_env_get(env, *i+1); + if (e) { + int r; + + r = strv_split_full(&m, e, WHITESPACE, EXTRACT_RELAX|EXTRACT_UNQUOTE); + if (r < 0) { + ret[k] = NULL; + strv_free(ret); + return NULL; + } + } else + m = NULL; + + q = strv_length(m); + l = l + q - 1; + + w = reallocarray(ret, l + 1, sizeof(char *)); + if (!w) { + ret[k] = NULL; + strv_free(ret); + strv_free(m); + return NULL; + } + + ret = w; + if (m) { + memcpy(ret + k, m, q * sizeof(char*)); + free(m); + } + + k += q; + continue; + } + + /* If ${FOO} appears as part of a word, replace it by the variable as-is */ + ret[k] = replace_env(*i, env, 0); + if (!ret[k]) { + strv_free(ret); + return NULL; + } + k++; + } + + ret[k] = NULL; + return ret; +} +#endif /* NM_IGNORED */ + +int getenv_bool(const char *p) { + const char *e; + + e = getenv(p); + if (!e) + return -ENXIO; + + return parse_boolean(e); +} + +int getenv_bool_secure(const char *p) { + const char *e; + + e = secure_getenv(p); + if (!e) + return -ENXIO; + + return parse_boolean(e); +} + +#if 0 /* NM_IGNORED */ +int set_unset_env(const char *name, const char *value, bool overwrite) { + int r; + + if (value) + r = setenv(name, value, overwrite); + else + r = unsetenv(name); + if (r < 0) + return -errno; + return 0; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/env-util.h b/src/libnm-systemd-shared/src/basic/env-util.h new file mode 100644 index 0000000..6684b33 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/env-util.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include + +#include "macro.h" +#include "string.h" + +static inline size_t sc_arg_max(void) { + long l = sysconf(_SC_ARG_MAX); + assert(l > 0); + return (size_t) l; +} + +bool env_name_is_valid(const char *e); +bool env_value_is_valid(const char *e); +bool env_assignment_is_valid(const char *e); + +enum { + REPLACE_ENV_USE_ENVIRONMENT = 1 << 0, + REPLACE_ENV_ALLOW_BRACELESS = 1 << 1, + REPLACE_ENV_ALLOW_EXTENDED = 1 << 2, +}; + +char *replace_env_n(const char *format, size_t n, char **env, unsigned flags); +char **replace_env_argv(char **argv, char **env); + +static inline char *replace_env(const char *format, char **env, unsigned flags) { + return replace_env_n(format, strlen(format), env, flags); +} + +bool strv_env_is_valid(char **e); +#define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL) +char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata); + +bool strv_env_name_is_valid(char **l); +bool strv_env_name_or_assignment_is_valid(char **l); + +char **strv_env_merge(size_t n_lists, ...); +char **strv_env_delete(char **x, size_t n_lists, ...); /* New copy */ + +char **strv_env_set(char **x, const char *p); /* New copy ... */ +char **strv_env_unset(char **l, const char *p); /* In place ... */ +char **strv_env_unset_many(char **l, ...) _sentinel_; +int strv_env_replace(char ***l, char *p); /* In place ... */ + +char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) _pure_; +char *strv_env_get(char **x, const char *n) _pure_; + +int getenv_bool(const char *p); +int getenv_bool_secure(const char *p); + +/* Like setenv, but calls unsetenv if value == NULL. */ +int set_unset_env(const char *name, const char *value, bool overwrite); diff --git a/src/libnm-systemd-shared/src/basic/errno-util.h b/src/libnm-systemd-shared/src/basic/errno-util.h new file mode 100644 index 0000000..5609820 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/errno-util.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include + +#include "macro.h" + +static inline void _reset_errno_(int *saved_errno) { + if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */ + return; + + errno = *saved_errno; +} + +#define PROTECT_ERRNO \ + _cleanup_(_reset_errno_) _unused_ int _saved_errno_ = errno + +#define UNPROTECT_ERRNO \ + do { \ + errno = _saved_errno_; \ + _saved_errno_ = -1; \ + } while (false) + +static inline int negative_errno(void) { + /* This helper should be used to shut up gcc if you know 'errno' is + * negative. Instead of "return -errno;", use "return negative_errno();" + * It will suppress bogus gcc warnings in case it assumes 'errno' might + * be 0 and thus the caller's error-handling might not be triggered. */ + assert_return(errno > 0, -EINVAL); + return -errno; +} + +static inline const char *strerror_safe(int error) { + /* 'safe' here does NOT mean thread safety. */ + return strerror(abs(error)); +} + +static inline int errno_or_else(int fallback) { + /* To be used when invoking library calls where errno handling is not defined clearly: we return + * errno if it is set, and the specified error otherwise. The idea is that the caller initializes + * errno to zero before doing an API call, and then uses this helper to retrieve a somewhat useful + * error code */ + if (errno > 0) + return -errno; + + return -abs(fallback); +} + +/* Hint #1: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5. + * + * Hint #2: The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases. See the + * icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources. + * + * Hint #3: When asynchronous connect() on TCP fails because the host never acknowledges a single packet, + * kernel tells us that with ETIMEDOUT, see tcp(7). */ +static inline bool ERRNO_IS_DISCONNECT(int r) { + return IN_SET(abs(r), + ECONNABORTED, + ECONNREFUSED, + ECONNRESET, + EHOSTDOWN, + EHOSTUNREACH, + ENETDOWN, + ENETRESET, + ENETUNREACH, + ENONET, + ENOPROTOOPT, + ENOTCONN, + EPIPE, + EPROTO, + ESHUTDOWN, + ETIMEDOUT); +} + +/* Transient errors we might get on accept() that we should ignore. As per error handling comment in + * the accept(2) man page. */ +static inline bool ERRNO_IS_ACCEPT_AGAIN(int r) { + return ERRNO_IS_DISCONNECT(r) || + IN_SET(abs(r), + EAGAIN, + EINTR, + EOPNOTSUPP); +} + +/* Resource exhaustion, could be our fault or general system trouble */ +static inline bool ERRNO_IS_RESOURCE(int r) { + return IN_SET(abs(r), + EMFILE, + ENFILE, + ENOMEM); +} + +/* Seven different errors for "operation/system call/ioctl/socket feature not supported" */ +static inline bool ERRNO_IS_NOT_SUPPORTED(int r) { + return IN_SET(abs(r), + EOPNOTSUPP, + ENOTTY, + ENOSYS, + EAFNOSUPPORT, + EPFNOSUPPORT, + EPROTONOSUPPORT, + ESOCKTNOSUPPORT); +} + +/* Two different errors for access problems */ +static inline bool ERRNO_IS_PRIVILEGE(int r) { + return IN_SET(abs(r), + EACCES, + EPERM); +} + +/* Three difference errors for "not enough disk space" */ +static inline bool ERRNO_IS_DISK_SPACE(int r) { + return IN_SET(abs(r), + ENOSPC, + EDQUOT, + EFBIG); +} diff --git a/src/libnm-systemd-shared/src/basic/escape.c b/src/libnm-systemd-shared/src/basic/escape.c new file mode 100644 index 0000000..094b5c5 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/escape.c @@ -0,0 +1,553 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include + +#include "alloc-util.h" +#include "escape.h" +#include "hexdecoct.h" +#include "macro.h" +#include "utf8.h" + +int cescape_char(char c, char *buf) { + char *buf_old = buf; + + /* Needs space for 4 characters in the buffer */ + + switch (c) { + + case '\a': + *(buf++) = '\\'; + *(buf++) = 'a'; + break; + case '\b': + *(buf++) = '\\'; + *(buf++) = 'b'; + break; + case '\f': + *(buf++) = '\\'; + *(buf++) = 'f'; + break; + case '\n': + *(buf++) = '\\'; + *(buf++) = 'n'; + break; + case '\r': + *(buf++) = '\\'; + *(buf++) = 'r'; + break; + case '\t': + *(buf++) = '\\'; + *(buf++) = 't'; + break; + case '\v': + *(buf++) = '\\'; + *(buf++) = 'v'; + break; + case '\\': + *(buf++) = '\\'; + *(buf++) = '\\'; + break; + case '"': + *(buf++) = '\\'; + *(buf++) = '"'; + break; + case '\'': + *(buf++) = '\\'; + *(buf++) = '\''; + break; + + default: + /* For special chars we prefer octal over + * hexadecimal encoding, simply because glib's + * g_strescape() does the same */ + if ((c < ' ') || (c >= 127)) { + *(buf++) = '\\'; + *(buf++) = octchar((unsigned char) c >> 6); + *(buf++) = octchar((unsigned char) c >> 3); + *(buf++) = octchar((unsigned char) c); + } else + *(buf++) = c; + break; + } + + return buf - buf_old; +} + +char* cescape_length(const char *s, size_t n) { + const char *f; + char *r, *t; + + assert(s || n == 0); + + /* Does C style string escaping. May be reversed with + * cunescape(). */ + + r = new(char, n*4 + 1); + if (!r) + return NULL; + + for (f = s, t = r; f < s + n; f++) + t += cescape_char(*f, t); + + *t = 0; + + return r; +} + +char* cescape(const char *s) { + assert(s); + + return cescape_length(s, strlen(s)); +} + +int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul) { + int r = 1; + + assert(p); + assert(ret); + + /* Unescapes C style. Returns the unescaped character in ret. + * Sets *eight_bit to true if the escaped sequence either fits in + * one byte in UTF-8 or is a non-unicode literal byte and should + * instead be copied directly. + */ + + if (length != (size_t) -1 && length < 1) + return -EINVAL; + + switch (p[0]) { + + case 'a': + *ret = '\a'; + break; + case 'b': + *ret = '\b'; + break; + case 'f': + *ret = '\f'; + break; + case 'n': + *ret = '\n'; + break; + case 'r': + *ret = '\r'; + break; + case 't': + *ret = '\t'; + break; + case 'v': + *ret = '\v'; + break; + case '\\': + *ret = '\\'; + break; + case '"': + *ret = '"'; + break; + case '\'': + *ret = '\''; + break; + + case 's': + /* This is an extension of the XDG syntax files */ + *ret = ' '; + break; + + case 'x': { + /* hexadecimal encoding */ + int a, b; + + if (length != (size_t) -1 && length < 3) + return -EINVAL; + + a = unhexchar(p[1]); + if (a < 0) + return -EINVAL; + + b = unhexchar(p[2]); + if (b < 0) + return -EINVAL; + + /* Don't allow NUL bytes */ + if (a == 0 && b == 0 && !accept_nul) + return -EINVAL; + + *ret = (a << 4U) | b; + *eight_bit = true; + r = 3; + break; + } + + case 'u': { + /* C++11 style 16bit unicode */ + + int a[4]; + size_t i; + uint32_t c; + + if (length != (size_t) -1 && length < 5) + return -EINVAL; + + for (i = 0; i < 4; i++) { + a[i] = unhexchar(p[1 + i]); + if (a[i] < 0) + return a[i]; + } + + c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3]; + + /* Don't allow 0 chars */ + if (c == 0 && !accept_nul) + return -EINVAL; + + *ret = c; + r = 5; + break; + } + + case 'U': { + /* C++11 style 32bit unicode */ + + int a[8]; + size_t i; + char32_t c; + + if (length != (size_t) -1 && length < 9) + return -EINVAL; + + for (i = 0; i < 8; i++) { + a[i] = unhexchar(p[1 + i]); + if (a[i] < 0) + return a[i]; + } + + c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) | + ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7]; + + /* Don't allow 0 chars */ + if (c == 0 && !accept_nul) + return -EINVAL; + + /* Don't allow invalid code points */ + if (!unichar_is_valid(c)) + return -EINVAL; + + *ret = c; + r = 9; + break; + } + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': { + /* octal encoding */ + int a, b, c; + char32_t m; + + if (length != (size_t) -1 && length < 3) + return -EINVAL; + + a = unoctchar(p[0]); + if (a < 0) + return -EINVAL; + + b = unoctchar(p[1]); + if (b < 0) + return -EINVAL; + + c = unoctchar(p[2]); + if (c < 0) + return -EINVAL; + + /* don't allow NUL bytes */ + if (a == 0 && b == 0 && c == 0 && !accept_nul) + return -EINVAL; + + /* Don't allow bytes above 255 */ + m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c; + if (m > 255) + return -EINVAL; + + *ret = m; + *eight_bit = true; + r = 3; + break; + } + + default: + return -EINVAL; + } + + return r; +} + +#if 0 /* NM_IGNORED */ +int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) { + char *r, *t; + const char *f; + size_t pl; + + assert(s); + assert(ret); + + /* Undoes C style string escaping, and optionally prefixes it. */ + + pl = strlen_ptr(prefix); + + r = new(char, pl+length+1); + if (!r) + return -ENOMEM; + + if (prefix) + memcpy(r, prefix, pl); + + for (f = s, t = r + pl; f < s + length; f++) { + size_t remaining; + bool eight_bit = false; + char32_t u; + int k; + + remaining = s + length - f; + assert(remaining > 0); + + if (*f != '\\') { + /* A literal, copy verbatim */ + *(t++) = *f; + continue; + } + + if (remaining == 1) { + if (flags & UNESCAPE_RELAX) { + /* A trailing backslash, copy verbatim */ + *(t++) = *f; + continue; + } + + free(r); + return -EINVAL; + } + + k = cunescape_one(f + 1, remaining - 1, &u, &eight_bit, flags & UNESCAPE_ACCEPT_NUL); + if (k < 0) { + if (flags & UNESCAPE_RELAX) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + continue; + } + + free(r); + return k; + } + + f += k; + if (eight_bit) + /* One byte? Set directly as specified */ + *(t++) = u; + else + /* Otherwise encode as multi-byte UTF-8 */ + t += utf8_encode_unichar(t, u); + } + + *t = 0; + + *ret = r; + return t - r; +} + +char* xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits) { + char *ans, *t, *prev, *prev2; + const char *f; + + /* Escapes all chars in bad, in addition to \ and all special chars, in \xFF style escaping. May be + * reversed with cunescape(). If eight_bits is true, characters >= 127 are let through unchanged. + * This corresponds to non-ASCII printable characters in pre-unicode encodings. + * + * If console_width is reached, output is truncated and "..." is appended. */ + + if (console_width == 0) + return strdup(""); + + ans = new(char, MIN(strlen(s), console_width) * 4 + 1); + if (!ans) + return NULL; + + memset(ans, '_', MIN(strlen(s), console_width) * 4); + ans[MIN(strlen(s), console_width) * 4] = 0; + + for (f = s, t = prev = prev2 = ans; ; f++) { + char *tmp_t = t; + + if (!*f) { + *t = 0; + return ans; + } + + if ((unsigned char) *f < ' ' || (!eight_bits && (unsigned char) *f >= 127) || + *f == '\\' || strchr(bad, *f)) { + if ((size_t) (t - ans) + 4 > console_width) + break; + + *(t++) = '\\'; + *(t++) = 'x'; + *(t++) = hexchar(*f >> 4); + *(t++) = hexchar(*f); + } else { + if ((size_t) (t - ans) + 1 > console_width) + break; + + *(t++) = *f; + } + + /* We might need to go back two cycles to fit three dots, so remember two positions */ + prev2 = prev; + prev = tmp_t; + } + + /* We can just write where we want, since chars are one-byte */ + size_t c = MIN(console_width, 3u); /* If the console is too narrow, write fewer dots */ + size_t off; + if (console_width - c >= (size_t) (t - ans)) + off = (size_t) (t - ans); + else if (console_width - c >= (size_t) (prev - ans)) + off = (size_t) (prev - ans); + else if (console_width - c >= (size_t) (prev2 - ans)) + off = (size_t) (prev2 - ans); + else + off = console_width - c; + assert(off <= (size_t) (t - ans)); + + memcpy(ans + off, "...", c); + ans[off + c] = '\0'; + return ans; +} + +char* escape_non_printable_full(const char *str, size_t console_width, bool eight_bit) { + if (eight_bit) + return xescape_full(str, "", console_width, true); + else + return utf8_escape_non_printable_full(str, console_width); +} +#endif /* NM_IGNORED */ + +char* octescape(const char *s, size_t len) { + char *r, *t; + const char *f; + + /* Escapes all chars in bad, in addition to \ and " chars, + * in \nnn style escaping. */ + + r = new(char, len * 4 + 1); + if (!r) + return NULL; + + for (f = s, t = r; f < s + len; f++) { + + if (*f < ' ' || *f >= 127 || IN_SET(*f, '\\', '"')) { + *(t++) = '\\'; + *(t++) = '0' + (*f >> 6); + *(t++) = '0' + ((*f >> 3) & 8); + *(t++) = '0' + (*f & 8); + } else + *(t++) = *f; + } + + *t = 0; + + return r; + +} + +static char* strcpy_backslash_escaped(char *t, const char *s, const char *bad, bool escape_tab_nl) { + assert(bad); + + for (; *s; s++) { + if (escape_tab_nl && IN_SET(*s, '\n', '\t')) { + *(t++) = '\\'; + *(t++) = *s == '\n' ? 'n' : 't'; + continue; + } + + if (*s == '\\' || strchr(bad, *s)) + *(t++) = '\\'; + + *(t++) = *s; + } + + return t; +} + +char* shell_escape(const char *s, const char *bad) { + char *r, *t; + + r = new(char, strlen(s)*2+1); + if (!r) + return NULL; + + t = strcpy_backslash_escaped(r, s, bad, false); + *t = 0; + + return r; +} + +char* shell_maybe_quote(const char *s, EscapeStyle style) { + const char *p; + char *r, *t; + + assert(s); + + /* Encloses a string in quotes if necessary to make it OK as a shell + * string. Note that we treat benign UTF-8 characters as needing + * escaping too, but that should be OK. */ + + for (p = s; *p; p++) + if (*p <= ' ' || + *p >= 127 || + strchr(SHELL_NEED_QUOTES, *p)) + break; + + if (!*p) + return strdup(s); + + r = new(char, (style == ESCAPE_POSIX) + 1 + strlen(s)*2 + 1 + 1); + if (!r) + return NULL; + + t = r; + switch (style) { + case ESCAPE_BACKSLASH: + case ESCAPE_BACKSLASH_ONELINE: + *(t++) = '"'; + break; + case ESCAPE_POSIX: + *(t++) = '$'; + *(t++) = '\''; + break; + default: + assert_not_reached("Bad EscapeStyle"); + } + + t = mempcpy(t, s, p - s); + + if (IN_SET(style, ESCAPE_BACKSLASH, ESCAPE_BACKSLASH_ONELINE)) + t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE, + style == ESCAPE_BACKSLASH_ONELINE); + else + t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE_POSIX, true); + + if (IN_SET(style, ESCAPE_BACKSLASH, ESCAPE_BACKSLASH_ONELINE)) + *(t++) = '"'; + else + *(t++) = '\''; + *t = 0; + + return r; +} diff --git a/src/libnm-systemd-shared/src/basic/escape.h b/src/libnm-systemd-shared/src/basic/escape.h new file mode 100644 index 0000000..691b6d8 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/escape.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include + +#include "string-util.h" +#include "missing_type.h" + +/* What characters are special in the shell? */ +/* must be escaped outside and inside double-quotes */ +#define SHELL_NEED_ESCAPE "\"\\`$" + +/* Those that can be escaped or double-quoted. + * + * Strictly speaking, ! does not need to be escaped, except in interactive + * mode, but let's be extra nice to the user and quote ! in case this + * output is ever used in interactive mode. */ +#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;!" + +/* Note that we assume control characters would need to be escaped too in + * addition to the "special" characters listed here, if they appear in the + * string. Current users disallow control characters. Also '"' shall not + * be escaped. + */ +#define SHELL_NEED_ESCAPE_POSIX "\\\'" + +typedef enum UnescapeFlags { + UNESCAPE_RELAX = 1 << 0, + UNESCAPE_ACCEPT_NUL = 1 << 1, +} UnescapeFlags; + +typedef enum EscapeStyle { + ESCAPE_BACKSLASH = 1, /* Add shell quotes ("") so the shell will consider this a single + argument, possibly multiline. Tabs and newlines are not escaped. */ + ESCAPE_BACKSLASH_ONELINE = 2, /* Similar to ESCAPE_BACKSLASH, but always produces a single-line + string instead. Shell escape sequences are produced for tabs and + newlines. */ + ESCAPE_POSIX = 3, /* Similar to ESCAPE_BACKSLASH_ONELINE, but uses POSIX shell escape + * syntax (a string enclosed in $'') instead of plain quotes. */ +} EscapeStyle; + +char* cescape(const char *s); +char* cescape_length(const char *s, size_t n); +int cescape_char(char c, char *buf); + +int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret); +static inline int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) { + return cunescape_length_with_prefix(s, length, NULL, flags, ret); +} +static inline int cunescape(const char *s, UnescapeFlags flags, char **ret) { + return cunescape_length(s, strlen(s), flags, ret); +} +int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul); + +char* xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits); +static inline char* xescape(const char *s, const char *bad) { + return xescape_full(s, bad, SIZE_MAX, false); +} +char* octescape(const char *s, size_t len); +char* escape_non_printable_full(const char *str, size_t console_width, bool eight_bit); + +char* shell_escape(const char *s, const char *bad); +char* shell_maybe_quote(const char *s, EscapeStyle style); diff --git a/src/libnm-systemd-shared/src/basic/ether-addr-util.c b/src/libnm-systemd-shared/src/basic/ether-addr-util.c new file mode 100644 index 0000000..ae83ead --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/ether-addr-util.c @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include + +#include "ether-addr-util.h" +#include "macro.h" +#include "string-util.h" + +char* hw_addr_to_string(const hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]) { + assert(addr); + assert(buffer); + assert(addr->length <= HW_ADDR_MAX_SIZE); + + for (size_t i = 0; i < addr->length; i++) { + sprintf(&buffer[3*i], "%02"PRIx8, addr->addr.bytes[i]); + if (i < addr->length - 1) + buffer[3*i + 2] = ':'; + } + + return buffer; +} + +char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) { + assert(addr); + assert(buffer); + + /* Like ether_ntoa() but uses %02x instead of %x to print + * ethernet addresses, which makes them look less funny. Also, + * doesn't use a static buffer. */ + + sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", + addr->ether_addr_octet[0], + addr->ether_addr_octet[1], + addr->ether_addr_octet[2], + addr->ether_addr_octet[3], + addr->ether_addr_octet[4], + addr->ether_addr_octet[5]); + + return buffer; +} + +int ether_addr_compare(const struct ether_addr *a, const struct ether_addr *b) { + return memcmp(a, b, ETH_ALEN); +} + +static void ether_addr_hash_func(const struct ether_addr *p, struct siphash *state) { + siphash24_compress(p, sizeof(struct ether_addr), state); +} + +DEFINE_HASH_OPS(ether_addr_hash_ops, struct ether_addr, ether_addr_hash_func, ether_addr_compare); + +int ether_addr_from_string(const char *s, struct ether_addr *ret) { + size_t pos = 0, n, field; + char sep = '\0'; + const char *hex = HEXDIGITS, *hexoff; + size_t x; + bool touched; + +#define parse_fields(v) \ + for (field = 0; field < ELEMENTSOF(v); field++) { \ + touched = false; \ + for (n = 0; n < (2 * sizeof(v[0])); n++) { \ + if (s[pos] == '\0') \ + break; \ + hexoff = strchr(hex, s[pos]); \ + if (!hexoff) \ + break; \ + assert(hexoff >= hex); \ + x = hexoff - hex; \ + if (x >= 16) \ + x -= 6; /* A-F */ \ + assert(x < 16); \ + touched = true; \ + v[field] <<= 4; \ + v[field] += x; \ + pos++; \ + } \ + if (!touched) \ + return -EINVAL; \ + if (field < (ELEMENTSOF(v)-1)) { \ + if (s[pos] != sep) \ + return -EINVAL; \ + else \ + pos++; \ + } \ + } + + assert(s); + assert(ret); + + s += strspn(s, WHITESPACE); + sep = s[strspn(s, hex)]; + + if (sep == '.') { + uint16_t shorts[3] = { 0 }; + + parse_fields(shorts); + + if (s[pos] != '\0') + return -EINVAL; + + for (n = 0; n < ELEMENTSOF(shorts); n++) { + ret->ether_addr_octet[2*n] = ((shorts[n] & (uint16_t)0xff00) >> 8); + ret->ether_addr_octet[2*n + 1] = (shorts[n] & (uint16_t)0x00ff); + } + + } else if (IN_SET(sep, ':', '-')) { + struct ether_addr out = ETHER_ADDR_NULL; + + parse_fields(out.ether_addr_octet); + + if (s[pos] != '\0') + return -EINVAL; + + for (n = 0; n < ELEMENTSOF(out.ether_addr_octet); n++) + ret->ether_addr_octet[n] = out.ether_addr_octet[n]; + + } else + return -EINVAL; + + return 0; +} diff --git a/src/libnm-systemd-shared/src/basic/ether-addr-util.h b/src/libnm-systemd-shared/src/basic/ether-addr-util.h new file mode 100644 index 0000000..942ce55 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/ether-addr-util.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include + +#include "hash-funcs.h" + +/* This is MAX_ADDR_LEN as defined in linux/netdevice.h, but net/if_arp.h + * defines a macro of the same name with a much lower size. */ +#define HW_ADDR_MAX_SIZE 32 + +union hw_addr_union { + struct ether_addr ether; + uint8_t infiniband[INFINIBAND_ALEN]; + uint8_t bytes[HW_ADDR_MAX_SIZE]; +}; + +typedef struct hw_addr_data { + union hw_addr_union addr; + size_t length; +} hw_addr_data; + +#define HW_ADDR_TO_STRING_MAX (3*HW_ADDR_MAX_SIZE) +char* hw_addr_to_string(const hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]); + +/* Use only as function argument, never stand-alone! */ +#define HW_ADDR_TO_STR(hw_addr) hw_addr_to_string((hw_addr), (char[HW_ADDR_TO_STRING_MAX]){}) + +#define HW_ADDR_NULL ((const hw_addr_data){}) + +#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X" +#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5] + +#define ETHER_ADDR_TO_STRING_MAX (3*6) +char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]); + +int ether_addr_compare(const struct ether_addr *a, const struct ether_addr *b); +static inline bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) { + return ether_addr_compare(a, b) == 0; +} + +#define ETHER_ADDR_NULL ((const struct ether_addr){}) + +static inline bool ether_addr_is_null(const struct ether_addr *addr) { + return ether_addr_equal(addr, ÐER_ADDR_NULL); +} + +int ether_addr_from_string(const char *s, struct ether_addr *ret); + +extern const struct hash_ops ether_addr_hash_ops; diff --git a/src/libnm-systemd-shared/src/basic/extract-word.c b/src/libnm-systemd-shared/src/basic/extract-word.c new file mode 100644 index 0000000..1d86033 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/extract-word.c @@ -0,0 +1,294 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "escape.h" +#include "extract-word.h" +#include "log.h" +#include "macro.h" +#include "string-util.h" +#include "strv.h" +#include "utf8.h" + +int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) { + _cleanup_free_ char *s = NULL; + size_t allocated = 0, sz = 0; + char c; + int r; + + char quote = 0; /* 0 or ' or " */ + bool backslash = false; /* whether we've just seen a backslash */ + + assert(p); + assert(ret); + + /* Bail early if called after last value or with no input */ + if (!*p) + goto finish; + c = **p; + + if (!separators) + separators = WHITESPACE; + + /* Parses the first word of a string, and returns it in + * *ret. Removes all quotes in the process. When parsing fails + * (because of an uneven number of quotes or similar), leaves + * the pointer *p at the first invalid character. */ + + if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) + if (!GREEDY_REALLOC(s, allocated, sz+1)) + return -ENOMEM; + + for (;; (*p)++, c = **p) { + if (c == 0) + goto finish_force_terminate; + else if (strchr(separators, c)) { + if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) { + (*p)++; + goto finish_force_next; + } + } else { + /* We found a non-blank character, so we will always + * want to return a string (even if it is empty), + * allocate it here. */ + if (!GREEDY_REALLOC(s, allocated, sz+1)) + return -ENOMEM; + break; + } + } + + for (;; (*p)++, c = **p) { + if (backslash) { + if (!GREEDY_REALLOC(s, allocated, sz+7)) + return -ENOMEM; + + if (c == 0) { + if ((flags & EXTRACT_CUNESCAPE_RELAX) && + (!quote || flags & EXTRACT_RELAX)) { + /* If we find an unquoted trailing backslash and we're in + * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the + * output. + * + * Unbalanced quotes will only be allowed in EXTRACT_RELAX + * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them. + */ + s[sz++] = '\\'; + goto finish_force_terminate; + } + if (flags & EXTRACT_RELAX) + goto finish_force_terminate; + return -EINVAL; + } + + if (flags & (EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS)) { + bool eight_bit = false; + char32_t u; + + if ((flags & EXTRACT_CUNESCAPE) && + (r = cunescape_one(*p, (size_t) -1, &u, &eight_bit, false)) >= 0) { + /* A valid escaped sequence */ + assert(r >= 1); + + (*p) += r - 1; + + if (eight_bit) + s[sz++] = u; + else + sz += utf8_encode_unichar(s + sz, u); + } else if ((flags & EXTRACT_UNESCAPE_SEPARATORS) && + strchr(separators, **p)) + /* An escaped separator char */ + s[sz++] = c; + else if (flags & EXTRACT_CUNESCAPE_RELAX) { + s[sz++] = '\\'; + s[sz++] = c; + } else + return -EINVAL; + } else + s[sz++] = c; + + backslash = false; + + } else if (quote) { /* inside either single or double quotes */ + for (;; (*p)++, c = **p) { + if (c == 0) { + if (flags & EXTRACT_RELAX) + goto finish_force_terminate; + return -EINVAL; + } else if (c == quote) { /* found the end quote */ + quote = 0; + break; + } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) { + backslash = true; + break; + } else { + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; + + s[sz++] = c; + } + } + + } else { + for (;; (*p)++, c = **p) { + if (c == 0) + goto finish_force_terminate; + else if (IN_SET(c, '\'', '"') && (flags & EXTRACT_UNQUOTE)) { + quote = c; + break; + } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) { + backslash = true; + break; + } else if (strchr(separators, c)) { + if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) { + (*p)++; + goto finish_force_next; + } + /* Skip additional coalesced separators. */ + for (;; (*p)++, c = **p) { + if (c == 0) + goto finish_force_terminate; + if (!strchr(separators, c)) + break; + } + goto finish; + + } else { + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; + + s[sz++] = c; + } + } + } + } + +finish_force_terminate: + *p = NULL; +finish: + if (!s) { + *p = NULL; + *ret = NULL; + return 0; + } + +finish_force_next: + s[sz] = 0; + *ret = TAKE_PTR(s); + + return 1; +} + +#if 0 /* NM_IGNORED */ +int extract_first_word_and_warn( + const char **p, + char **ret, + const char *separators, + ExtractFlags flags, + const char *unit, + const char *filename, + unsigned line, + const char *rvalue) { + + /* Try to unquote it, if it fails, warn about it and try again + * but this time using EXTRACT_CUNESCAPE_RELAX to keep the + * backslashes verbatim in invalid escape sequences. */ + + const char *save; + int r; + + save = *p; + r = extract_first_word(p, ret, separators, flags); + if (r >= 0) + return r; + + if (r == -EINVAL && !(flags & EXTRACT_CUNESCAPE_RELAX)) { + + /* Retry it with EXTRACT_CUNESCAPE_RELAX. */ + *p = save; + r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX); + if (r >= 0) { + /* It worked this time, hence it must have been an invalid escape sequence. */ + log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "Ignoring unknown escape sequences: \"%s\"", *ret); + return r; + } + + /* If it's still EINVAL; then it must be unbalanced quoting, report this. */ + if (r == -EINVAL) + return log_syntax(unit, LOG_ERR, filename, line, r, "Unbalanced quoting, ignoring: \"%s\"", rvalue); + } + + /* Can be any error, report it */ + return log_syntax(unit, LOG_ERR, filename, line, r, "Unable to decode word \"%s\", ignoring: %m", rvalue); +} + +/* We pass ExtractFlags as unsigned int (to avoid undefined behaviour when passing + * an object that undergoes default argument promotion as an argument to va_start). + * Let's make sure that ExtractFlags fits into an unsigned int. */ +assert_cc(sizeof(enum ExtractFlags) <= sizeof(unsigned)); + +int extract_many_words(const char **p, const char *separators, unsigned flags, ...) { + va_list ap; + char **l; + int n = 0, i, c, r; + + /* Parses a number of words from a string, stripping any + * quotes if necessary. */ + + assert(p); + + /* Count how many words are expected */ + va_start(ap, flags); + for (;;) { + if (!va_arg(ap, char **)) + break; + n++; + } + va_end(ap); + + if (n <= 0) + return 0; + + /* Read all words into a temporary array */ + l = newa0(char*, n); + for (c = 0; c < n; c++) { + + r = extract_first_word(p, &l[c], separators, flags); + if (r < 0) { + int j; + + for (j = 0; j < c; j++) + free(l[j]); + + return r; + } + + if (r == 0) + break; + } + + /* If we managed to parse all words, return them in the passed + * in parameters */ + va_start(ap, flags); + for (i = 0; i < n; i++) { + char **v; + + v = va_arg(ap, char **); + assert(v); + + *v = l[i]; + } + va_end(ap); + + return c; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/extract-word.h b/src/libnm-systemd-shared/src/basic/extract-word.h new file mode 100644 index 0000000..d1de32e --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/extract-word.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "macro.h" + +typedef enum ExtractFlags { + EXTRACT_RELAX = 1 << 0, + EXTRACT_CUNESCAPE = 1 << 1, + EXTRACT_CUNESCAPE_RELAX = 1 << 2, + EXTRACT_UNESCAPE_SEPARATORS = 1 << 3, + EXTRACT_UNQUOTE = 1 << 4, + EXTRACT_DONT_COALESCE_SEPARATORS = 1 << 5, + EXTRACT_RETAIN_ESCAPE = 1 << 6, +} ExtractFlags; + +int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags); +int extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue); +int extract_many_words(const char **p, const char *separators, unsigned flags, ...) _sentinel_; diff --git a/src/libnm-systemd-shared/src/basic/fd-util.c b/src/libnm-systemd-shared/src/basic/fd-util.c new file mode 100644 index 0000000..e53cf18 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/fd-util.c @@ -0,0 +1,1071 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "copy.h" +#include "dirent-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" +#include "io-util.h" +#include "macro.h" +#include "memfd-util.h" +#include "missing_fcntl.h" +#include "missing_syscall.h" +#include "parse-util.h" +#include "path-util.h" +#include "process-util.h" +#include "socket-util.h" +#include "sort-util.h" +#include "stat-util.h" +#include "stdio-util.h" +#include "tmpfile-util.h" +#include "util.h" + +/* The maximum number of iterations in the loop to close descriptors in the fallback case + * when /proc/self/fd/ is inaccessible. */ +#define MAX_FD_LOOP_LIMIT (1024*1024) + +int close_nointr(int fd) { + assert(fd >= 0); + + if (close(fd) >= 0) + return 0; + + /* + * Just ignore EINTR; a retry loop is the wrong thing to do on + * Linux. + * + * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html + * https://bugzilla.gnome.org/show_bug.cgi?id=682819 + * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR + * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain + */ + if (errno == EINTR) + return 0; + + return -errno; +} + +int safe_close(int fd) { + + /* + * Like close_nointr() but cannot fail. Guarantees errno is + * unchanged. Is a NOP with negative fds passed, and returns + * -1, so that it can be used in this syntax: + * + * fd = safe_close(fd); + */ + + if (fd >= 0) { + PROTECT_ERRNO; + + /* The kernel might return pretty much any error code + * via close(), but the fd will be closed anyway. The + * only condition we want to check for here is whether + * the fd was invalid at all... */ + + assert_se(close_nointr(fd) != -EBADF); + } + + return -1; +} + +void safe_close_pair(int p[static 2]) { + assert(p); + + if (p[0] == p[1]) { + /* Special case pairs which use the same fd in both + * directions... */ + p[0] = p[1] = safe_close(p[0]); + return; + } + + p[0] = safe_close(p[0]); + p[1] = safe_close(p[1]); +} + +void close_many(const int fds[], size_t n_fd) { + size_t i; + + assert(fds || n_fd <= 0); + + for (i = 0; i < n_fd; i++) + safe_close(fds[i]); +} + +int fclose_nointr(FILE *f) { + assert(f); + + /* Same as close_nointr(), but for fclose() */ + + errno = 0; /* Extra safety: if the FILE* object is not encapsulating an fd, it might not set errno + * correctly. Let's hence initialize it to zero first, so that we aren't confused by any + * prior errno here */ + if (fclose(f) == 0) + return 0; + + if (errno == EINTR) + return 0; + + return errno_or_else(EIO); +} + +FILE* safe_fclose(FILE *f) { + + /* Same as safe_close(), but for fclose() */ + + if (f) { + PROTECT_ERRNO; + + assert_se(fclose_nointr(f) != -EBADF); + } + + return NULL; +} + +DIR* safe_closedir(DIR *d) { + + if (d) { + PROTECT_ERRNO; + + assert_se(closedir(d) >= 0 || errno != EBADF); + } + + return NULL; +} + +int fd_nonblock(int fd, bool nonblock) { + int flags, nflags; + + assert(fd >= 0); + + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) + return -errno; + + nflags = UPDATE_FLAG(flags, O_NONBLOCK, nonblock); + if (nflags == flags) + return 0; + + if (fcntl(fd, F_SETFL, nflags) < 0) + return -errno; + + return 0; +} + +int fd_cloexec(int fd, bool cloexec) { + int flags, nflags; + + assert(fd >= 0); + + flags = fcntl(fd, F_GETFD, 0); + if (flags < 0) + return -errno; + + nflags = UPDATE_FLAG(flags, FD_CLOEXEC, cloexec); + if (nflags == flags) + return 0; + + if (fcntl(fd, F_SETFD, nflags) < 0) + return -errno; + + return 0; +} + +#if 0 /* NM_IGNORED */ +_pure_ static bool fd_in_set(int fd, const int fdset[], size_t n_fdset) { + size_t i; + + assert(n_fdset == 0 || fdset); + + for (i = 0; i < n_fdset; i++) + if (fdset[i] == fd) + return true; + + return false; +} + +static int get_max_fd(void) { + struct rlimit rl; + rlim_t m; + + /* Return the highest possible fd, based RLIMIT_NOFILE, but enforcing FD_SETSIZE-1 as lower boundary + * and INT_MAX as upper boundary. */ + + if (getrlimit(RLIMIT_NOFILE, &rl) < 0) + return -errno; + + m = MAX(rl.rlim_cur, rl.rlim_max); + if (m < FD_SETSIZE) /* Let's always cover at least 1024 fds */ + return FD_SETSIZE-1; + + if (m == RLIM_INFINITY || m > INT_MAX) /* Saturate on overflow. After all fds are "int", hence can + * never be above INT_MAX */ + return INT_MAX; + + return (int) (m - 1); +} + +int close_all_fds(const int except[], size_t n_except) { + static bool have_close_range = true; /* Assume we live in the future */ + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + int r = 0; + + assert(n_except == 0 || except); + + if (have_close_range) { + /* In the best case we have close_range() to close all fds between a start and an end fd, + * which we can use on the "inverted" exception array, i.e. all intervals between all + * adjacent pairs from the sorted exception array. This changes loop complexity from O(n) + * where n is number of open fds to O(m⋅log(m)) where m is the number of fds to keep + * open. Given that we assume n ≫ m that's preferable to us. */ + + if (n_except == 0) { + /* Close everything. Yay! */ + + if (close_range(3, -1, 0) >= 0) + return 1; + + if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) + return -errno; + + have_close_range = false; + } else { + _cleanup_free_ int *sorted_malloc = NULL; + size_t n_sorted; + int *sorted; + + assert(n_except < SIZE_MAX); + n_sorted = n_except + 1; + + if (n_sorted > 64) /* Use heap for large numbers of fds, stack otherwise */ + sorted = sorted_malloc = new(int, n_sorted); + else + sorted = newa(int, n_sorted); + + if (sorted) { + int c = 0; + + memcpy(sorted, except, n_except * sizeof(int)); + + /* Let's add fd 2 to the list of fds, to simplify the loop below, as this + * allows us to cover the head of the array the same way as the body */ + sorted[n_sorted-1] = 2; + + typesafe_qsort(sorted, n_sorted, cmp_int); + + for (size_t i = 0; i < n_sorted-1; i++) { + int start, end; + + start = MAX(sorted[i], 2); /* The first three fds shall always remain open */ + end = MAX(sorted[i+1], 2); + + assert(end >= start); + + if (end - start <= 1) + continue; + + /* Close everything between the start and end fds (both of which shall stay open) */ + if (close_range(start + 1, end - 1, 0) < 0) { + if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) + return -errno; + + have_close_range = false; + break; + } + + c += end - start - 1; + } + + if (have_close_range) { + /* The loop succeeded. Let's now close everything beyond the end */ + + if (sorted[n_sorted-1] >= INT_MAX) /* Dont let the addition below overflow */ + return c; + + if (close_range(sorted[n_sorted-1] + 1, -1, 0) >= 0) + return c + 1; + + if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) + return -errno; + + have_close_range = false; + } + } + } + + /* Fallback on OOM or if close_range() is not supported */ + } + + d = opendir("/proc/self/fd"); + if (!d) { + int fd, max_fd; + + /* When /proc isn't available (for example in chroots) the fallback is brute forcing through + * the fd table */ + + max_fd = get_max_fd(); + if (max_fd < 0) + return max_fd; + + /* Refuse to do the loop over more too many elements. It's better to fail immediately than to + * spin the CPU for a long time. */ + if (max_fd > MAX_FD_LOOP_LIMIT) + return log_debug_errno(SYNTHETIC_ERRNO(EPERM), + "/proc/self/fd is inaccessible. Refusing to loop over %d potential fds.", + max_fd); + + for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) { + int q; + + if (fd_in_set(fd, except, n_except)) + continue; + + q = close_nointr(fd); + if (q < 0 && q != -EBADF && r >= 0) + r = q; + } + + return r; + } + + FOREACH_DIRENT(de, d, return -errno) { + int fd = -1, q; + + if (safe_atoi(de->d_name, &fd) < 0) + /* Let's better ignore this, just in case */ + continue; + + if (fd < 3) + continue; + + if (fd == dirfd(d)) + continue; + + if (fd_in_set(fd, except, n_except)) + continue; + + q = close_nointr(fd); + if (q < 0 && q != -EBADF && r >= 0) /* Valgrind has its own FD and doesn't want to have it closed */ + r = q; + } + + return r; +} + +int same_fd(int a, int b) { + struct stat sta, stb; + pid_t pid; + int r, fa, fb; + + assert(a >= 0); + assert(b >= 0); + + /* Compares two file descriptors. Note that semantics are + * quite different depending on whether we have kcmp() or we + * don't. If we have kcmp() this will only return true for + * dup()ed file descriptors, but not otherwise. If we don't + * have kcmp() this will also return true for two fds of the same + * file, created by separate open() calls. Since we use this + * call mostly for filtering out duplicates in the fd store + * this difference hopefully doesn't matter too much. */ + + if (a == b) + return true; + + /* Try to use kcmp() if we have it. */ + pid = getpid_cached(); + r = kcmp(pid, pid, KCMP_FILE, a, b); + if (r == 0) + return true; + if (r > 0) + return false; + if (!IN_SET(errno, ENOSYS, EACCES, EPERM)) + return -errno; + + /* We don't have kcmp(), use fstat() instead. */ + if (fstat(a, &sta) < 0) + return -errno; + + if (fstat(b, &stb) < 0) + return -errno; + + if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT)) + return false; + + /* We consider all device fds different, since two device fds + * might refer to quite different device contexts even though + * they share the same inode and backing dev_t. */ + + if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode)) + return false; + + if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino) + return false; + + /* The fds refer to the same inode on disk, let's also check + * if they have the same fd flags. This is useful to + * distinguish the read and write side of a pipe created with + * pipe(). */ + fa = fcntl(a, F_GETFL); + if (fa < 0) + return -errno; + + fb = fcntl(b, F_GETFL); + if (fb < 0) + return -errno; + + return fa == fb; +} +#endif /* NM_IGNORED */ + +void cmsg_close_all(struct msghdr *mh) { + struct cmsghdr *cmsg; + + assert(mh); + + CMSG_FOREACH(cmsg, mh) + if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) + close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int)); +} + +bool fdname_is_valid(const char *s) { + const char *p; + + /* Validates a name for $LISTEN_FDNAMES. We basically allow + * everything ASCII that's not a control character. Also, as + * special exception the ":" character is not allowed, as we + * use that as field separator in $LISTEN_FDNAMES. + * + * Note that the empty string is explicitly allowed + * here. However, we limit the length of the names to 255 + * characters. */ + + if (!s) + return false; + + for (p = s; *p; p++) { + if (*p < ' ') + return false; + if (*p >= 127) + return false; + if (*p == ':') + return false; + } + + return p - s < 256; +} + +#if 0 /* NM_IGNORED */ +int fd_get_path(int fd, char **ret) { + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + int r; + + xsprintf(procfs_path, "/proc/self/fd/%i", fd); + r = readlink_malloc(procfs_path, ret); + if (r == -ENOENT) { + /* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's make + * things debuggable and distinguish the two. */ + + if (proc_mounted() == 0) + return -ENOSYS; /* /proc is not available or not set up properly, we're most likely in some chroot + * environment. */ + return -EBADF; /* The directory exists, hence it's the fd that doesn't. */ + } + + return r; +} + +int move_fd(int from, int to, int cloexec) { + int r; + + /* Move fd 'from' to 'to', make sure FD_CLOEXEC remains equal if requested, and release the old fd. If + * 'cloexec' is passed as -1, the original FD_CLOEXEC is inherited for the new fd. If it is 0, it is turned + * off, if it is > 0 it is turned on. */ + + if (from < 0) + return -EBADF; + if (to < 0) + return -EBADF; + + if (from == to) { + + if (cloexec >= 0) { + r = fd_cloexec(to, cloexec); + if (r < 0) + return r; + } + + return to; + } + + if (cloexec < 0) { + int fl; + + fl = fcntl(from, F_GETFD, 0); + if (fl < 0) + return -errno; + + cloexec = !!(fl & FD_CLOEXEC); + } + + r = dup3(from, to, cloexec ? O_CLOEXEC : 0); + if (r < 0) + return -errno; + + assert(r == to); + + safe_close(from); + + return to; +} + +int acquire_data_fd(const void *data, size_t size, unsigned flags) { + + _cleanup_close_pair_ int pipefds[2] = { -1, -1 }; + char pattern[] = "/dev/shm/data-fd-XXXXXX"; + _cleanup_close_ int fd = -1; + int isz = 0, r; + ssize_t n; + off_t f; + + assert(data || size == 0); + + /* Acquire a read-only file descriptor that when read from returns the specified data. This is much more + * complex than I wish it was. But here's why: + * + * a) First we try to use memfds. They are the best option, as we can seal them nicely to make them + * read-only. Unfortunately they require kernel 3.17, and – at the time of writing – we still support 3.14. + * + * b) Then, we try classic pipes. They are the second best options, as we can close the writing side, retaining + * a nicely read-only fd in the reading side. However, they are by default quite small, and unprivileged + * clients can only bump their size to a system-wide limit, which might be quite low. + * + * c) Then, we try an O_TMPFILE file in /dev/shm (that dir is the only suitable one known to exist from + * earliest boot on). To make it read-only we open the fd a second time with O_RDONLY via + * /proc/self/. Unfortunately O_TMPFILE is not available on older kernels on tmpfs. + * + * d) Finally, we try creating a regular file in /dev/shm, which we then delete. + * + * It sucks a bit that depending on the situation we return very different objects here, but that's Linux I + * figure. */ + + if (size == 0 && ((flags & ACQUIRE_NO_DEV_NULL) == 0)) { + /* As a special case, return /dev/null if we have been called for an empty data block */ + r = open("/dev/null", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (r < 0) + return -errno; + + return r; + } + + if ((flags & ACQUIRE_NO_MEMFD) == 0) { + fd = memfd_new("data-fd"); + if (fd < 0) + goto try_pipe; + + n = write(fd, data, size); + if (n < 0) + return -errno; + if ((size_t) n != size) + return -EIO; + + f = lseek(fd, 0, SEEK_SET); + if (f != 0) + return -errno; + + r = memfd_set_sealed(fd); + if (r < 0) + return r; + + return TAKE_FD(fd); + } + +try_pipe: + if ((flags & ACQUIRE_NO_PIPE) == 0) { + if (pipe2(pipefds, O_CLOEXEC|O_NONBLOCK) < 0) + return -errno; + + isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0); + if (isz < 0) + return -errno; + + if ((size_t) isz < size) { + isz = (int) size; + if (isz < 0 || (size_t) isz != size) + return -E2BIG; + + /* Try to bump the pipe size */ + (void) fcntl(pipefds[1], F_SETPIPE_SZ, isz); + + /* See if that worked */ + isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0); + if (isz < 0) + return -errno; + + if ((size_t) isz < size) + goto try_dev_shm; + } + + n = write(pipefds[1], data, size); + if (n < 0) + return -errno; + if ((size_t) n != size) + return -EIO; + + (void) fd_nonblock(pipefds[0], false); + + return TAKE_FD(pipefds[0]); + } + +try_dev_shm: + if ((flags & ACQUIRE_NO_TMPFILE) == 0) { + fd = open("/dev/shm", O_RDWR|O_TMPFILE|O_CLOEXEC, 0500); + if (fd < 0) + goto try_dev_shm_without_o_tmpfile; + + n = write(fd, data, size); + if (n < 0) + return -errno; + if ((size_t) n != size) + return -EIO; + + /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */ + return fd_reopen(fd, O_RDONLY|O_CLOEXEC); + } + +try_dev_shm_without_o_tmpfile: + if ((flags & ACQUIRE_NO_REGULAR) == 0) { + fd = mkostemp_safe(pattern); + if (fd < 0) + return fd; + + n = write(fd, data, size); + if (n < 0) { + r = -errno; + goto unlink_and_return; + } + if ((size_t) n != size) { + r = -EIO; + goto unlink_and_return; + } + + /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */ + r = open(pattern, O_RDONLY|O_CLOEXEC); + if (r < 0) + r = -errno; + + unlink_and_return: + (void) unlink(pattern); + return r; + } + + return -EOPNOTSUPP; +} + +/* When the data is smaller or equal to 64K, try to place the copy in a memfd/pipe */ +#define DATA_FD_MEMORY_LIMIT (64U*1024U) + +/* If memfd/pipe didn't work out, then let's use a file in /tmp up to a size of 1M. If it's large than that use /var/tmp instead. */ +#define DATA_FD_TMP_LIMIT (1024U*1024U) + +int fd_duplicate_data_fd(int fd) { + + _cleanup_close_ int copy_fd = -1, tmp_fd = -1; + _cleanup_free_ void *remains = NULL; + size_t remains_size = 0; + const char *td; + struct stat st; + int r; + + /* Creates a 'data' fd from the specified source fd, containing all the same data in a read-only fashion, but + * independent of it (i.e. the source fd can be closed and unmounted after this call succeeded). Tries to be + * somewhat smart about where to place the data. In the best case uses a memfd(). If memfd() are not supported + * uses a pipe instead. For larger data will use an unlinked file in /tmp, and for even larger data one in + * /var/tmp. */ + + if (fstat(fd, &st) < 0) + return -errno; + + /* For now, let's only accept regular files, sockets, pipes and char devices */ + if (S_ISDIR(st.st_mode)) + return -EISDIR; + if (S_ISLNK(st.st_mode)) + return -ELOOP; + if (!S_ISREG(st.st_mode) && !S_ISSOCK(st.st_mode) && !S_ISFIFO(st.st_mode) && !S_ISCHR(st.st_mode)) + return -EBADFD; + + /* If we have reason to believe the data is bounded in size, then let's use memfds or pipes as backing fd. Note + * that we use the reported regular file size only as a hint, given that there are plenty special files in + * /proc and /sys which report a zero file size but can be read from. */ + + if (!S_ISREG(st.st_mode) || st.st_size < DATA_FD_MEMORY_LIMIT) { + + /* Try a memfd first */ + copy_fd = memfd_new("data-fd"); + if (copy_fd >= 0) { + off_t f; + + r = copy_bytes(fd, copy_fd, DATA_FD_MEMORY_LIMIT, 0); + if (r < 0) + return r; + + f = lseek(copy_fd, 0, SEEK_SET); + if (f != 0) + return -errno; + + if (r == 0) { + /* Did it fit into the limit? If so, we are done. */ + r = memfd_set_sealed(copy_fd); + if (r < 0) + return r; + + return TAKE_FD(copy_fd); + } + + /* Hmm, pity, this didn't fit. Let's fall back to /tmp then, see below */ + + } else { + _cleanup_(close_pairp) int pipefds[2] = { -1, -1 }; + int isz; + + /* If memfds aren't available, use a pipe. Set O_NONBLOCK so that we will get EAGAIN rather + * then block indefinitely when we hit the pipe size limit */ + + if (pipe2(pipefds, O_CLOEXEC|O_NONBLOCK) < 0) + return -errno; + + isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0); + if (isz < 0) + return -errno; + + /* Try to enlarge the pipe size if necessary */ + if ((size_t) isz < DATA_FD_MEMORY_LIMIT) { + + (void) fcntl(pipefds[1], F_SETPIPE_SZ, DATA_FD_MEMORY_LIMIT); + + isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0); + if (isz < 0) + return -errno; + } + + if ((size_t) isz >= DATA_FD_MEMORY_LIMIT) { + + r = copy_bytes_full(fd, pipefds[1], DATA_FD_MEMORY_LIMIT, 0, &remains, &remains_size, NULL, NULL); + if (r < 0 && r != -EAGAIN) + return r; /* If we get EAGAIN it could be because of the source or because of + * the destination fd, we can't know, as sendfile() and friends won't + * tell us. Hence, treat this as reason to fall back, just to be + * sure. */ + if (r == 0) { + /* Everything fit in, yay! */ + (void) fd_nonblock(pipefds[0], false); + + return TAKE_FD(pipefds[0]); + } + + /* Things didn't fit in. But we read data into the pipe, let's remember that, so that + * when writing the new file we incorporate this first. */ + copy_fd = TAKE_FD(pipefds[0]); + } + } + } + + /* If we have reason to believe this will fit fine in /tmp, then use that as first fallback. */ + if ((!S_ISREG(st.st_mode) || st.st_size < DATA_FD_TMP_LIMIT) && + (DATA_FD_MEMORY_LIMIT + remains_size) < DATA_FD_TMP_LIMIT) { + off_t f; + + tmp_fd = open_tmpfile_unlinkable(NULL /* NULL as directory means /tmp */, O_RDWR|O_CLOEXEC); + if (tmp_fd < 0) + return tmp_fd; + + if (copy_fd >= 0) { + /* If we tried a memfd/pipe first and it ended up being too large, then copy this into the + * temporary file first. */ + + r = copy_bytes(copy_fd, tmp_fd, UINT64_MAX, 0); + if (r < 0) + return r; + + assert(r == 0); + } + + if (remains_size > 0) { + /* If there were remaining bytes (i.e. read into memory, but not written out yet) from the + * failed copy operation, let's flush them out next. */ + + r = loop_write(tmp_fd, remains, remains_size, false); + if (r < 0) + return r; + } + + r = copy_bytes(fd, tmp_fd, DATA_FD_TMP_LIMIT - DATA_FD_MEMORY_LIMIT - remains_size, COPY_REFLINK); + if (r < 0) + return r; + if (r == 0) + goto finish; /* Yay, it fit in */ + + /* It didn't fit in. Let's not forget to use what we already used */ + f = lseek(tmp_fd, 0, SEEK_SET); + if (f != 0) + return -errno; + + CLOSE_AND_REPLACE(copy_fd, tmp_fd); + + remains = mfree(remains); + remains_size = 0; + } + + /* As last fallback use /var/tmp */ + r = var_tmp_dir(&td); + if (r < 0) + return r; + + tmp_fd = open_tmpfile_unlinkable(td, O_RDWR|O_CLOEXEC); + if (tmp_fd < 0) + return tmp_fd; + + if (copy_fd >= 0) { + /* If we tried a memfd/pipe first, or a file in /tmp, and it ended up being too large, than copy this + * into the temporary file first. */ + r = copy_bytes(copy_fd, tmp_fd, UINT64_MAX, COPY_REFLINK); + if (r < 0) + return r; + + assert(r == 0); + } + + if (remains_size > 0) { + /* Then, copy in any read but not yet written bytes. */ + r = loop_write(tmp_fd, remains, remains_size, false); + if (r < 0) + return r; + } + + /* Copy in the rest */ + r = copy_bytes(fd, tmp_fd, UINT64_MAX, COPY_REFLINK); + if (r < 0) + return r; + + assert(r == 0); + +finish: + /* Now convert the O_RDWR file descriptor into an O_RDONLY one (and as side effect seek to the beginning of the + * file again */ + + return fd_reopen(tmp_fd, O_RDONLY|O_CLOEXEC); +} +#endif /* NM_IGNORED */ + +int fd_move_above_stdio(int fd) { + int flags, copy; + PROTECT_ERRNO; + + /* Moves the specified file descriptor if possible out of the range [0…2], i.e. the range of + * stdin/stdout/stderr. If it can't be moved outside of this range the original file descriptor is + * returned. This call is supposed to be used for long-lasting file descriptors we allocate in our code that + * might get loaded into foreign code, and where we want ensure our fds are unlikely used accidentally as + * stdin/stdout/stderr of unrelated code. + * + * Note that this doesn't fix any real bugs, it just makes it less likely that our code will be affected by + * buggy code from others that mindlessly invokes 'fprintf(stderr, …' or similar in places where stderr has + * been closed before. + * + * This function is written in a "best-effort" and "least-impact" style. This means whenever we encounter an + * error we simply return the original file descriptor, and we do not touch errno. */ + + if (fd < 0 || fd > 2) + return fd; + + flags = fcntl(fd, F_GETFD, 0); + if (flags < 0) + return fd; + + if (flags & FD_CLOEXEC) + copy = fcntl(fd, F_DUPFD_CLOEXEC, 3); + else + copy = fcntl(fd, F_DUPFD, 3); + if (copy < 0) + return fd; + + assert(copy > 2); + + (void) close(fd); + return copy; +} + +#if 0 /* NM_IGNORED */ +int rearrange_stdio(int original_input_fd, int original_output_fd, int original_error_fd) { + + int fd[3] = { /* Put together an array of fds we work on */ + original_input_fd, + original_output_fd, + original_error_fd + }; + + int r, i, + null_fd = -1, /* if we open /dev/null, we store the fd to it here */ + copy_fd[3] = { -1, -1, -1 }; /* This contains all fds we duplicate here temporarily, and hence need to close at the end */ + bool null_readable, null_writable; + + /* Sets up stdin, stdout, stderr with the three file descriptors passed in. If any of the descriptors is + * specified as -1 it will be connected with /dev/null instead. If any of the file descriptors is passed as + * itself (e.g. stdin as STDIN_FILENO) it is left unmodified, but the O_CLOEXEC bit is turned off should it be + * on. + * + * Note that if any of the passed file descriptors are > 2 they will be closed — both on success and on + * failure! Thus, callers should assume that when this function returns the input fds are invalidated. + * + * Note that when this function fails stdin/stdout/stderr might remain half set up! + * + * O_CLOEXEC is turned off for all three file descriptors (which is how it should be for + * stdin/stdout/stderr). */ + + null_readable = original_input_fd < 0; + null_writable = original_output_fd < 0 || original_error_fd < 0; + + /* First step, open /dev/null once, if we need it */ + if (null_readable || null_writable) { + + /* Let's open this with O_CLOEXEC first, and convert it to non-O_CLOEXEC when we move the fd to the final position. */ + null_fd = open("/dev/null", (null_readable && null_writable ? O_RDWR : + null_readable ? O_RDONLY : O_WRONLY) | O_CLOEXEC); + if (null_fd < 0) { + r = -errno; + goto finish; + } + + /* If this fd is in the 0…2 range, let's move it out of it */ + if (null_fd < 3) { + int copy; + + copy = fcntl(null_fd, F_DUPFD_CLOEXEC, 3); /* Duplicate this with O_CLOEXEC set */ + if (copy < 0) { + r = -errno; + goto finish; + } + + CLOSE_AND_REPLACE(null_fd, copy); + } + } + + /* Let's assemble fd[] with the fds to install in place of stdin/stdout/stderr */ + for (i = 0; i < 3; i++) { + + if (fd[i] < 0) + fd[i] = null_fd; /* A negative parameter means: connect this one to /dev/null */ + else if (fd[i] != i && fd[i] < 3) { + /* This fd is in the 0…2 territory, but not at its intended place, move it out of there, so that we can work there. */ + copy_fd[i] = fcntl(fd[i], F_DUPFD_CLOEXEC, 3); /* Duplicate this with O_CLOEXEC set */ + if (copy_fd[i] < 0) { + r = -errno; + goto finish; + } + + fd[i] = copy_fd[i]; + } + } + + /* At this point we now have the fds to use in fd[], and they are all above the stdio range, so that we + * have freedom to move them around. If the fds already were at the right places then the specific fds are + * -1. Let's now move them to the right places. This is the point of no return. */ + for (i = 0; i < 3; i++) { + + if (fd[i] == i) { + + /* fd is already in place, but let's make sure O_CLOEXEC is off */ + r = fd_cloexec(i, false); + if (r < 0) + goto finish; + + } else { + assert(fd[i] > 2); + + if (dup2(fd[i], i) < 0) { /* Turns off O_CLOEXEC on the new fd. */ + r = -errno; + goto finish; + } + } + } + + r = 0; + +finish: + /* Close the original fds, but only if they were outside of the stdio range. Also, properly check for the same + * fd passed in multiple times. */ + safe_close_above_stdio(original_input_fd); + if (original_output_fd != original_input_fd) + safe_close_above_stdio(original_output_fd); + if (original_error_fd != original_input_fd && original_error_fd != original_output_fd) + safe_close_above_stdio(original_error_fd); + + /* Close the copies we moved > 2 */ + for (i = 0; i < 3; i++) + safe_close(copy_fd[i]); + + /* Close our null fd, if it's > 2 */ + safe_close_above_stdio(null_fd); + + return r; +} + +int fd_reopen(int fd, int flags) { + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + int new_fd; + + /* Reopens the specified fd with new flags. This is useful for convert an O_PATH fd into a regular one, or to + * turn O_RDWR fds into O_RDONLY fds. + * + * This doesn't work on sockets (since they cannot be open()ed, ever). + * + * This implicitly resets the file read index to 0. */ + + xsprintf(procfs_path, "/proc/self/fd/%i", fd); + new_fd = open(procfs_path, flags); + if (new_fd < 0) { + if (errno != ENOENT) + return -errno; + + if (proc_mounted() == 0) + return -ENOSYS; /* if we have no /proc/, the concept is not implementable */ + + return -ENOENT; + } + + return new_fd; +} + +int read_nr_open(void) { + _cleanup_free_ char *nr_open = NULL; + int r; + + /* Returns the kernel's current fd limit, either by reading it of /proc/sys if that works, or using the + * hard-coded default compiled-in value of current kernels (1M) if not. This call will never fail. */ + + r = read_one_line_file("/proc/sys/fs/nr_open", &nr_open); + if (r < 0) + log_debug_errno(r, "Failed to read /proc/sys/fs/nr_open, ignoring: %m"); + else { + int v; + + r = safe_atoi(nr_open, &v); + if (r < 0) + log_debug_errno(r, "Failed to parse /proc/sys/fs/nr_open value '%s', ignoring: %m", nr_open); + else + return v; + } + + /* If we fail, fall back to the hard-coded kernel limit of 1024 * 1024. */ + return 1024 * 1024; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/fd-util.h b/src/libnm-systemd-shared/src/basic/fd-util.h new file mode 100644 index 0000000..2162537 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/fd-util.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include + +#include "macro.h" + +/* Make sure we can distinguish fd 0 and NULL */ +#define FD_TO_PTR(fd) INT_TO_PTR((fd)+1) +#define PTR_TO_FD(p) (PTR_TO_INT(p)-1) + +int close_nointr(int fd); +int safe_close(int fd); +void safe_close_pair(int p[static 2]); + +static inline int safe_close_above_stdio(int fd) { + if (fd < 3) /* Don't close stdin/stdout/stderr, but still invalidate the fd by returning -1 */ + return -1; + + return safe_close(fd); +} + +void close_many(const int fds[], size_t n_fd); + +int fclose_nointr(FILE *f); +FILE* safe_fclose(FILE *f); +DIR* safe_closedir(DIR *f); + +static inline void closep(int *fd) { + safe_close(*fd); +} + +static inline void close_pairp(int (*p)[2]) { + safe_close_pair(*p); +} + +static inline void fclosep(FILE **f) { + safe_fclose(*f); +} + +DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, pclose); +DEFINE_TRIVIAL_CLEANUP_FUNC(DIR*, closedir); + +#define _cleanup_close_ _cleanup_(closep) +#define _cleanup_fclose_ _cleanup_(fclosep) +#define _cleanup_pclose_ _cleanup_(pclosep) +#define _cleanup_closedir_ _cleanup_(closedirp) +#define _cleanup_close_pair_ _cleanup_(close_pairp) + +int fd_nonblock(int fd, bool nonblock); +int fd_cloexec(int fd, bool cloexec); + +int close_all_fds(const int except[], size_t n_except); + +int same_fd(int a, int b); + +void cmsg_close_all(struct msghdr *mh); + +bool fdname_is_valid(const char *s); + +int fd_get_path(int fd, char **ret); + +int move_fd(int from, int to, int cloexec); + +enum { + ACQUIRE_NO_DEV_NULL = 1 << 0, + ACQUIRE_NO_MEMFD = 1 << 1, + ACQUIRE_NO_PIPE = 1 << 2, + ACQUIRE_NO_TMPFILE = 1 << 3, + ACQUIRE_NO_REGULAR = 1 << 4, +}; + +int acquire_data_fd(const void *data, size_t size, unsigned flags); + +int fd_duplicate_data_fd(int fd); + +int fd_move_above_stdio(int fd); + +int rearrange_stdio(int original_input_fd, int original_output_fd, int original_error_fd); + +static inline int make_null_stdio(void) { + return rearrange_stdio(-1, -1, -1); +} + +/* Like TAKE_PTR() but for file descriptors, resetting them to -1 */ +#define TAKE_FD(fd) \ + ({ \ + int _fd_ = (fd); \ + (fd) = -1; \ + _fd_; \ + }) + +/* Like free_and_replace(), but for file descriptors */ +#define CLOSE_AND_REPLACE(a, b) \ + ({ \ + int *_fdp_ = &(a); \ + safe_close(*_fdp_); \ + *_fdp_ = TAKE_FD(b); \ + 0; \ + }) + + +int fd_reopen(int fd, int flags); + +int read_nr_open(void); diff --git a/src/libnm-systemd-shared/src/basic/fileio.c b/src/libnm-systemd-shared/src/basic/fileio.c new file mode 100644 index 0000000..ea90614 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/fileio.c @@ -0,0 +1,1360 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" +#include "hexdecoct.h" +#include "log.h" +#include "macro.h" +#include "mkdir.h" +#include "parse-util.h" +#include "path-util.h" +#include "socket-util.h" +#include "stdio-util.h" +#include "string-util.h" +#include "tmpfile-util.h" + +#define READ_FULL_BYTES_MAX (4U*1024U*1024U) + +int fopen_unlocked(const char *path, const char *options, FILE **ret) { + assert(ret); + + FILE *f = fopen(path, options); + if (!f) + return -errno; + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + *ret = f; + return 0; +} + +int fdopen_unlocked(int fd, const char *options, FILE **ret) { + assert(ret); + + FILE *f = fdopen(fd, options); + if (!f) + return -errno; + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + *ret = f; + return 0; +} + +int take_fdopen_unlocked(int *fd, const char *options, FILE **ret) { + int r; + + assert(fd); + + r = fdopen_unlocked(*fd, options, ret); + if (r < 0) + return r; + + *fd = -1; + + return 0; +} + +FILE* take_fdopen(int *fd, const char *options) { + assert(fd); + + FILE *f = fdopen(*fd, options); + if (!f) + return NULL; + + *fd = -1; + + return f; +} + +DIR* take_fdopendir(int *dfd) { + assert(dfd); + + DIR *d = fdopendir(*dfd); + if (!d) + return NULL; + + *dfd = -1; + + return d; +} + +FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc) { + FILE *f = open_memstream(ptr, sizeloc); + if (!f) + return NULL; + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + return f; +} + +FILE* fmemopen_unlocked(void *buf, size_t size, const char *mode) { + FILE *f = fmemopen(buf, size, mode); + if (!f) + return NULL; + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + return f; +} + +#if 0 /* NM_IGNORED */ +int write_string_stream_ts( + FILE *f, + const char *line, + WriteStringFileFlags flags, + const struct timespec *ts) { + + bool needs_nl; + int r, fd; + + assert(f); + assert(line); + + if (ferror(f)) + return -EIO; + + if (ts) { + /* If we shall set the timestamp we need the fd. But fmemopen() streams generally don't have + * an fd. Let's fail early in that case. */ + fd = fileno(f); + if (fd < 0) + return -EBADF; + } + + needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n"); + + if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) { + /* If STDIO buffering was disabled, then let's append the newline character to the string itself, so + * that the write goes out in one go, instead of two */ + + line = strjoina(line, "\n"); + needs_nl = false; + } + + if (fputs(line, f) == EOF) + return -errno; + + if (needs_nl) + if (fputc('\n', f) == EOF) + return -errno; + + if (flags & WRITE_STRING_FILE_SYNC) + r = fflush_sync_and_check(f); + else + r = fflush_and_check(f); + if (r < 0) + return r; + + if (ts) { + const struct timespec twice[2] = {*ts, *ts}; + + if (futimens(fd, twice) < 0) + return -errno; + } + + return 0; +} + +static int write_string_file_atomic( + const char *fn, + const char *line, + WriteStringFileFlags flags, + const struct timespec *ts) { + + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *p = NULL; + int r; + + assert(fn); + assert(line); + + /* Note that we'd really like to use O_TMPFILE here, but can't really, since we want replacement + * semantics here, and O_TMPFILE can't offer that. i.e. rename() replaces but linkat() doesn't. */ + + r = fopen_temporary(fn, &f, &p); + if (r < 0) + return r; + + r = write_string_stream_ts(f, line, flags, ts); + if (r < 0) + goto fail; + + r = fchmod_umask(fileno(f), FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0644); + if (r < 0) + goto fail; + + if (rename(p, fn) < 0) { + r = -errno; + goto fail; + } + + if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) { + /* Sync the rename, too */ + r = fsync_directory_of_file(fileno(f)); + if (r < 0) + return r; + } + + return 0; + +fail: + (void) unlink(p); + return r; +} + +int write_string_file_ts( + const char *fn, + const char *line, + WriteStringFileFlags flags, + const struct timespec *ts) { + + _cleanup_fclose_ FILE *f = NULL; + int q, r, fd; + + assert(fn); + assert(line); + + /* We don't know how to verify whether the file contents was already on-disk. */ + assert(!((flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE) && (flags & WRITE_STRING_FILE_SYNC))); + + if (flags & WRITE_STRING_FILE_MKDIR_0755) { + r = mkdir_parents(fn, 0755); + if (r < 0) + return r; + } + + if (flags & WRITE_STRING_FILE_ATOMIC) { + assert(flags & WRITE_STRING_FILE_CREATE); + + r = write_string_file_atomic(fn, line, flags, ts); + if (r < 0) + goto fail; + + return r; + } else + assert(!ts); + + /* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */ + fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY | + (FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) | + (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) | + (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0), + (FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0666)); + if (fd < 0) { + r = -errno; + goto fail; + } + + r = fdopen_unlocked(fd, "w", &f); + if (r < 0) { + safe_close(fd); + goto fail; + } + + if (flags & WRITE_STRING_FILE_DISABLE_BUFFER) + setvbuf(f, NULL, _IONBF, 0); + + r = write_string_stream_ts(f, line, flags, ts); + if (r < 0) + goto fail; + + return 0; + +fail: + if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE)) + return r; + + f = safe_fclose(f); + + /* OK, the operation failed, but let's see if the right + * contents in place already. If so, eat up the error. */ + + q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); + if (q <= 0) + return r; + + return 0; +} + +int write_string_filef( + const char *fn, + WriteStringFileFlags flags, + const char *format, ...) { + + _cleanup_free_ char *p = NULL; + va_list ap; + int r; + + va_start(ap, format); + r = vasprintf(&p, format, ap); + va_end(ap); + + if (r < 0) + return -ENOMEM; + + return write_string_file(fn, p, flags); +} + +int read_one_line_file(const char *fn, char **line) { + _cleanup_fclose_ FILE *f = NULL; + int r; + + assert(fn); + assert(line); + + r = fopen_unlocked(fn, "re", &f); + if (r < 0) + return r; + + return read_line(f, LONG_LINE_MAX, line); +} + +int verify_file(const char *fn, const char *blob, bool accept_extra_nl) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *buf = NULL; + size_t l, k; + int r; + + assert(fn); + assert(blob); + + l = strlen(blob); + + if (accept_extra_nl && endswith(blob, "\n")) + accept_extra_nl = false; + + buf = malloc(l + accept_extra_nl + 1); + if (!buf) + return -ENOMEM; + + r = fopen_unlocked(fn, "re", &f); + if (r < 0) + return r; + + /* We try to read one byte more than we need, so that we know whether we hit eof */ + errno = 0; + k = fread(buf, 1, l + accept_extra_nl + 1, f); + if (ferror(f)) + return errno_or_else(EIO); + + if (k != l && k != l + accept_extra_nl) + return 0; + if (memcmp(buf, blob, l) != 0) + return 0; + if (k > l && buf[l] != '\n') + return 0; + + return 1; +} +#endif /* NM_IGNORED */ + +int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size) { + _cleanup_free_ char *buf = NULL; + _cleanup_close_ int fd = -1; + struct stat st; + size_t n, size; + int n_retries; + char *p; + + assert(ret_contents); + + /* Virtual filesystems such as sysfs or procfs use kernfs, and kernfs can work + * with two sorts of virtual files. One sort uses "seq_file", and the results of + * the first read are buffered for the second read. The other sort uses "raw" + * reads which always go direct to the device. In the latter case, the content of + * the virtual file must be retrieved with a single read otherwise a second read + * might get the new value instead of finding EOF immediately. That's the reason + * why the usage of fread(3) is prohibited in this case as it always performs a + * second call to read(2) looking for EOF. See issue 13585. */ + + fd = open(filename, O_RDONLY|O_CLOEXEC); + if (fd < 0) + return -errno; + + /* Start size for files in /proc which usually report a file size of 0. */ + size = LINE_MAX / 2; + + /* Limit the number of attempts to read the number of bytes returned by fstat(). */ + n_retries = 3; + + for (;;) { + if (n_retries <= 0) + return -EIO; + + if (fstat(fd, &st) < 0) + return -errno; + + if (!S_ISREG(st.st_mode)) + return -EBADF; + + /* Be prepared for files from /proc which generally report a file size of 0. */ + if (st.st_size > 0) { + size = st.st_size; + n_retries--; + } else + size = size * 2; + + if (size > READ_FULL_BYTES_MAX) + return -E2BIG; + + p = realloc(buf, size + 1); + if (!p) + return -ENOMEM; + buf = TAKE_PTR(p); + + for (;;) { + ssize_t k; + + /* Read one more byte so we can detect whether the content of the + * file has already changed or the guessed size for files from /proc + * wasn't large enough . */ + k = read(fd, buf, size + 1); + if (k >= 0) { + n = k; + break; + } + + if (errno != EINTR) + return -errno; + } + + /* Consider a short read as EOF */ + if (n <= size) + break; + + /* Hmm... either we read too few bytes from /proc or less likely the content + * of the file might have been changed (and is now bigger) while we were + * processing, let's try again either with a bigger guessed size or the new + * file size. */ + + if (lseek(fd, 0, SEEK_SET) < 0) + return -errno; + } + + if (n < size) { + p = realloc(buf, n + 1); + if (!p) + return -ENOMEM; + buf = TAKE_PTR(p); + } + + if (!ret_size) { + /* Safety check: if the caller doesn't want to know the size of what we + * just read it will rely on the trailing NUL byte. But if there's an + * embedded NUL byte, then we should refuse operation as otherwise + * there'd be ambiguity about what we just read. */ + + if (memchr(buf, 0, n)) + return -EBADMSG; + } else + *ret_size = n; + + buf[n] = 0; + *ret_contents = TAKE_PTR(buf); + + return 0; +} + +int read_full_stream_full( + FILE *f, + const char *filename, + uint64_t offset, + size_t size, + ReadFullFileFlags flags, + char **ret_contents, + size_t *ret_size) { + + _cleanup_free_ char *buf = NULL; + size_t n, n_next, l; + int fd, r; + + assert(f); + assert(ret_contents); + assert(!FLAGS_SET(flags, READ_FULL_FILE_UNBASE64 | READ_FULL_FILE_UNHEX)); + + if (offset != UINT64_MAX && offset > LONG_MAX) + return -ERANGE; + + n_next = size != SIZE_MAX ? size : LINE_MAX; /* Start size */ + + fd = fileno(f); + if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see + * fmemopen()), let's optimize our buffering */ + struct stat st; + + if (fstat(fd, &st) < 0) + return -errno; + + if (S_ISREG(st.st_mode)) { + if (size == SIZE_MAX) { + uint64_t rsize = + LESS_BY((uint64_t) st.st_size, offset == UINT64_MAX ? 0 : offset); + + /* Safety check */ + if (rsize > READ_FULL_BYTES_MAX) + return -E2BIG; + + /* Start with the right file size. Note that we increase the size to read + * here by one, so that the first read attempt already makes us notice the + * EOF. If the reported size of the file is zero, we avoid this logic + * however, since quite likely it might be a virtual file in procfs that all + * report a zero file size. */ + if (st.st_size > 0) + n_next = rsize + 1; + } + + if (flags & READ_FULL_FILE_WARN_WORLD_READABLE) + (void) warn_file_is_world_accessible(filename, &st, NULL, 0); + } + } + + if (offset != UINT64_MAX && fseek(f, offset, SEEK_SET) < 0) + return -errno; + + n = l = 0; + for (;;) { + char *t; + size_t k; + + if (flags & READ_FULL_FILE_SECURE) { + t = malloc(n_next + 1); + if (!t) { + r = -ENOMEM; + goto finalize; + } + memcpy_safe(t, buf, n); + explicit_bzero_safe(buf, n); + buf = mfree(buf); + } else { + t = realloc(buf, n_next + 1); + if (!t) + return -ENOMEM; + } + + buf = t; + n = n_next; + + errno = 0; + k = fread(buf + l, 1, n - l, f); + + assert(k <= n - l); + l += k; + + if (ferror(f)) { + r = errno_or_else(EIO); + goto finalize; + } + if (feof(f)) + break; + + if (size != SIZE_MAX) { /* If we got asked to read some specific size, we already sized the buffer right, hence leave */ + assert(l == size); + break; + } + + assert(k > 0); /* we can't have read zero bytes because that would have been EOF */ + + /* Safety check */ + if (n >= READ_FULL_BYTES_MAX) { + r = -E2BIG; + goto finalize; + } + + n_next = MIN(n * 2, READ_FULL_BYTES_MAX); + } + + if (flags & (READ_FULL_FILE_UNBASE64 | READ_FULL_FILE_UNHEX)) { + _cleanup_free_ void *decoded = NULL; + size_t decoded_size; + + buf[l++] = 0; + if (flags & READ_FULL_FILE_UNBASE64) + r = unbase64mem_full(buf, l, flags & READ_FULL_FILE_SECURE, &decoded, &decoded_size); + else + r = unhexmem_full(buf, l, flags & READ_FULL_FILE_SECURE, &decoded, &decoded_size); + if (r < 0) + goto finalize; + + if (flags & READ_FULL_FILE_SECURE) + explicit_bzero_safe(buf, n); + free_and_replace(buf, decoded); + n = l = decoded_size; + } + + if (!ret_size) { + /* Safety check: if the caller doesn't want to know the size of what we just read it will rely on the + * trailing NUL byte. But if there's an embedded NUL byte, then we should refuse operation as otherwise + * there'd be ambiguity about what we just read. */ + + if (memchr(buf, 0, l)) { + r = -EBADMSG; + goto finalize; + } + } + + buf[l] = 0; + *ret_contents = TAKE_PTR(buf); + + if (ret_size) + *ret_size = l; + + return 0; + +finalize: + if (flags & READ_FULL_FILE_SECURE) + explicit_bzero_safe(buf, n); + + return r; +} + +int read_full_file_full( + int dir_fd, + const char *filename, + uint64_t offset, + size_t size, + ReadFullFileFlags flags, + const char *bind_name, + char **ret_contents, + size_t *ret_size) { + + _cleanup_fclose_ FILE *f = NULL; + int r; + + assert(filename); + assert(ret_contents); + + r = xfopenat(dir_fd, filename, "re", 0, &f); + if (r < 0) { + _cleanup_close_ int dfd = -1, sk = -1; + union sockaddr_union sa; + + /* ENXIO is what Linux returns if we open a node that is an AF_UNIX socket */ + if (r != -ENXIO) + return r; + + /* If this is enabled, let's try to connect to it */ + if (!FLAGS_SET(flags, READ_FULL_FILE_CONNECT_SOCKET)) + return -ENXIO; + + /* Seeking is not supported on AF_UNIX sockets */ + if (offset != UINT64_MAX) + return -ESPIPE; + + if (dir_fd == AT_FDCWD) + r = sockaddr_un_set_path(&sa.un, filename); + else { + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + + /* If we shall operate relative to some directory, then let's use O_PATH first to + * open the socket inode, and then connect to it via /proc/self/fd/. We have to do + * this since there's not connectat() that takes a directory fd as first arg. */ + + dfd = openat(dir_fd, filename, O_PATH|O_CLOEXEC); + if (dfd < 0) + return -errno; + + xsprintf(procfs_path, "/proc/self/fd/%i", dfd); + r = sockaddr_un_set_path(&sa.un, procfs_path); + } + if (r < 0) + return r; + + sk = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); + if (sk < 0) + return -errno; + + if (bind_name) { + /* If the caller specified a socket name to bind to, do so before connecting. This is + * useful to communicate some minor, short meta-information token from the client to + * the server. */ + union sockaddr_union bsa; + + r = sockaddr_un_set_path(&bsa.un, bind_name); + if (r < 0) + return r; + + if (bind(sk, &bsa.sa, r) < 0) + return r; + } + + if (connect(sk, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) + return errno == ENOTSOCK ? -ENXIO : -errno; /* propagate original error if this is + * not a socket after all */ + + if (shutdown(sk, SHUT_WR) < 0) + return -errno; + + f = fdopen(sk, "r"); + if (!f) + return -errno; + + TAKE_FD(sk); + } + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + return read_full_stream_full(f, filename, offset, size, flags, ret_contents, ret_size); +} + +#if 0 /* NM_IGNORED */ +int executable_is_script(const char *path, char **interpreter) { + _cleanup_free_ char *line = NULL; + size_t len; + char *ans; + int r; + + assert(path); + + r = read_one_line_file(path, &line); + if (r == -ENOBUFS) /* First line overly long? if so, then it's not a script */ + return 0; + if (r < 0) + return r; + + if (!startswith(line, "#!")) + return 0; + + ans = strstrip(line + 2); + len = strcspn(ans, " \t"); + + if (len == 0) + return 0; + + ans = strndup(ans, len); + if (!ans) + return -ENOMEM; + + *interpreter = ans; + return 1; +} +#endif /* NM_IGNORED */ + +/** + * Retrieve one field from a file like /proc/self/status. pattern + * should not include whitespace or the delimiter (':'). pattern matches only + * the beginning of a line. Whitespace before ':' is skipped. Whitespace and + * zeros after the ':' will be skipped. field must be freed afterwards. + * terminator specifies the terminating characters of the field value (not + * included in the value). + */ +int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) { + _cleanup_free_ char *status = NULL; + char *t, *f; + size_t len; + int r; + + assert(terminator); + assert(filename); + assert(pattern); + assert(field); + + r = read_full_virtual_file(filename, &status, NULL); + if (r < 0) + return r; + + t = status; + + do { + bool pattern_ok; + + do { + t = strstr(t, pattern); + if (!t) + return -ENOENT; + + /* Check that pattern occurs in beginning of line. */ + pattern_ok = (t == status || t[-1] == '\n'); + + t += strlen(pattern); + + } while (!pattern_ok); + + t += strspn(t, " \t"); + if (!*t) + return -ENOENT; + + } while (*t != ':'); + + t++; + + if (*t) { + t += strspn(t, " \t"); + + /* Also skip zeros, because when this is used for + * capabilities, we don't want the zeros. This way the + * same capability set always maps to the same string, + * irrespective of the total capability set size. For + * other numbers it shouldn't matter. */ + t += strspn(t, "0"); + /* Back off one char if there's nothing but whitespace + and zeros */ + if (!*t || isspace(*t)) + t--; + } + + len = strcspn(t, terminator); + + f = strndup(t, len); + if (!f) + return -ENOMEM; + + *field = f; + return 0; +} + +DIR *xopendirat(int fd, const char *name, int flags) { + int nfd; + DIR *d; + + assert(!(flags & O_CREAT)); + + nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0); + if (nfd < 0) + return NULL; + + d = fdopendir(nfd); + if (!d) { + safe_close(nfd); + return NULL; + } + + return d; +} + +static int mode_to_flags(const char *mode) { + const char *p; + int flags; + + if ((p = startswith(mode, "r+"))) + flags = O_RDWR; + else if ((p = startswith(mode, "r"))) + flags = O_RDONLY; + else if ((p = startswith(mode, "w+"))) + flags = O_RDWR|O_CREAT|O_TRUNC; + else if ((p = startswith(mode, "w"))) + flags = O_WRONLY|O_CREAT|O_TRUNC; + else if ((p = startswith(mode, "a+"))) + flags = O_RDWR|O_CREAT|O_APPEND; + else if ((p = startswith(mode, "a"))) + flags = O_WRONLY|O_CREAT|O_APPEND; + else + return -EINVAL; + + for (; *p != 0; p++) { + + switch (*p) { + + case 'e': + flags |= O_CLOEXEC; + break; + + case 'x': + flags |= O_EXCL; + break; + + case 'm': + /* ignore this here, fdopen() might care later though */ + break; + + case 'c': /* not sure what to do about this one */ + default: + return -EINVAL; + } + } + + return flags; +} + +int xfopenat(int dir_fd, const char *path, const char *mode, int flags, FILE **ret) { + FILE *f; + + /* A combination of fopen() with openat() */ + + if (dir_fd == AT_FDCWD && flags == 0) { + f = fopen(path, mode); + if (!f) + return -errno; + } else { + int fd, mode_flags; + + mode_flags = mode_to_flags(mode); + if (mode_flags < 0) + return mode_flags; + + fd = openat(dir_fd, path, mode_flags | flags); + if (fd < 0) + return -errno; + + f = fdopen(fd, mode); + if (!f) { + safe_close(fd); + return -errno; + } + } + + *ret = f; + return 0; +} + +#if 0 /* NM_IGNORED */ +static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) { + char **i; + + assert(path); + assert(mode); + assert(_f); + + if (!path_strv_resolve_uniq(search, root)) + return -ENOMEM; + + STRV_FOREACH(i, search) { + _cleanup_free_ char *p = NULL; + FILE *f; + + p = path_join(root, *i, path); + if (!p) + return -ENOMEM; + + f = fopen(p, mode); + if (f) { + *_f = f; + return 0; + } + + if (errno != ENOENT) + return -errno; + } + + return -ENOENT; +} + +int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) { + _cleanup_strv_free_ char **copy = NULL; + + assert(path); + assert(mode); + assert(_f); + + if (path_is_absolute(path)) { + FILE *f; + + f = fopen(path, mode); + if (f) { + *_f = f; + return 0; + } + + return -errno; + } + + copy = strv_copy((char**) search); + if (!copy) + return -ENOMEM; + + return search_and_fopen_internal(path, mode, root, copy, _f); +} + +int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) { + _cleanup_strv_free_ char **s = NULL; + + if (path_is_absolute(path)) { + FILE *f; + + f = fopen(path, mode); + if (f) { + *_f = f; + return 0; + } + + return -errno; + } + + s = strv_split_nulstr(search); + if (!s) + return -ENOMEM; + + return search_and_fopen_internal(path, mode, root, s, _f); +} + +int chase_symlinks_and_fopen_unlocked( + const char *path, + const char *root, + unsigned chase_flags, + const char *open_flags, + FILE **ret_file, + char **ret_path) { + + _cleanup_close_ int fd = -1; + _cleanup_free_ char *final_path = NULL; + int mode_flags, r; + FILE *f; + + assert(path); + assert(open_flags); + assert(ret_file); + + mode_flags = mode_to_flags(open_flags); + if (mode_flags < 0) + return mode_flags; + + fd = chase_symlinks_and_open(path, root, chase_flags, mode_flags, ret_path ? &final_path : NULL); + if (fd < 0) + return fd; + + r = fdopen_unlocked(fd, open_flags, &f); + if (r < 0) + return r; + TAKE_FD(fd); + + *ret_file = f; + if (ret_path) + *ret_path = TAKE_PTR(final_path); + return 0; +} +#endif /* NM_IGNORED */ + +int fflush_and_check(FILE *f) { + assert(f); + + errno = 0; + fflush(f); + + if (ferror(f)) + return errno_or_else(EIO); + + return 0; +} + +#if 0 /* NM_IGNORED */ +int fflush_sync_and_check(FILE *f) { + int r, fd; + + assert(f); + + r = fflush_and_check(f); + if (r < 0) + return r; + + /* Not all file streams have an fd associated (think: fmemopen()), let's handle this gracefully and + * assume that in that case we need no explicit syncing */ + fd = fileno(f); + if (fd < 0) + return 0; + + if (fsync(fd) < 0) + return -errno; + + r = fsync_directory_of_file(fd); + if (r < 0) + return r; + + return 0; +} + +int write_timestamp_file_atomic(const char *fn, usec_t n) { + char ln[DECIMAL_STR_MAX(n)+2]; + + /* Creates a "timestamp" file, that contains nothing but a + * usec_t timestamp, formatted in ASCII. */ + + if (n <= 0 || n >= USEC_INFINITY) + return -ERANGE; + + xsprintf(ln, USEC_FMT "\n", n); + + return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC); +} + +int read_timestamp_file(const char *fn, usec_t *ret) { + _cleanup_free_ char *ln = NULL; + uint64_t t; + int r; + + r = read_one_line_file(fn, &ln); + if (r < 0) + return r; + + r = safe_atou64(ln, &t); + if (r < 0) + return r; + + if (t <= 0 || t >= (uint64_t) USEC_INFINITY) + return -ERANGE; + + *ret = (usec_t) t; + return 0; +} +#endif /* NM_IGNORED */ + +int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) { + int r; + + assert(s); + + /* Outputs the specified string with fputs(), but optionally prefixes it with a separator. The *space parameter + * when specified shall initially point to a boolean variable initialized to false. It is set to true after the + * first invocation. This call is supposed to be use in loops, where a separator shall be inserted between each + * element, but not before the first one. */ + + if (!f) + f = stdout; + + if (space) { + if (!separator) + separator = " "; + + if (*space) { + r = fputs(separator, f); + if (r < 0) + return r; + } + + *space = true; + } + + return fputs(s, f); +} + +#if 0 /* NM_IGNORED */ +/* A bitmask of the EOL markers we know */ +typedef enum EndOfLineMarker { + EOL_NONE = 0, + EOL_ZERO = 1 << 0, /* \0 (aka NUL) */ + EOL_TEN = 1 << 1, /* \n (aka NL, aka LF) */ + EOL_THIRTEEN = 1 << 2, /* \r (aka CR) */ +} EndOfLineMarker; + +static EndOfLineMarker categorize_eol(char c, ReadLineFlags flags) { + + if (!IN_SET(flags, READ_LINE_ONLY_NUL)) { + if (c == '\n') + return EOL_TEN; + if (c == '\r') + return EOL_THIRTEEN; + } + + if (c == '\0') + return EOL_ZERO; + + return EOL_NONE; +} + +DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile); + +int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) { + size_t n = 0, allocated = 0, count = 0; + _cleanup_free_ char *buffer = NULL; + int r; + + assert(f); + + /* Something like a bounded version of getline(). + * + * Considers EOF, \n, \r and \0 end of line delimiters (or combinations of these), and does not include these + * delimiters in the string returned. Specifically, recognizes the following combinations of markers as line + * endings: + * + * • \n (UNIX) + * • \r (old MacOS) + * • \0 (C strings) + * • \n\0 + * • \r\0 + * • \r\n (Windows) + * • \n\r + * • \r\n\0 + * • \n\r\0 + * + * Returns the number of bytes read from the files (i.e. including delimiters — this hence usually differs from + * the number of characters in the returned string). When EOF is hit, 0 is returned. + * + * The input parameter limit is the maximum numbers of characters in the returned string, i.e. excluding + * delimiters. If the limit is hit we fail and return -ENOBUFS. + * + * If a line shall be skipped ret may be initialized as NULL. */ + + if (ret) { + if (!GREEDY_REALLOC(buffer, allocated, 1)) + return -ENOMEM; + } + + { + _unused_ _cleanup_(funlockfilep) FILE *flocked = f; + EndOfLineMarker previous_eol = EOL_NONE; + flockfile(f); + + for (;;) { + EndOfLineMarker eol; + char c; + + if (n >= limit) + return -ENOBUFS; + + if (count >= INT_MAX) /* We couldn't return the counter anymore as "int", hence refuse this */ + return -ENOBUFS; + + r = safe_fgetc(f, &c); + if (r < 0) + return r; + if (r == 0) /* EOF is definitely EOL */ + break; + + eol = categorize_eol(c, flags); + + if (FLAGS_SET(previous_eol, EOL_ZERO) || + (eol == EOL_NONE && previous_eol != EOL_NONE) || + (eol != EOL_NONE && (previous_eol & eol) != 0)) { + /* Previous char was a NUL? This is not an EOL, but the previous char was? This type of + * EOL marker has been seen right before? In either of these three cases we are + * done. But first, let's put this character back in the queue. (Note that we have to + * cast this to (unsigned char) here as ungetc() expects a positive 'int', and if we + * are on an architecture where 'char' equals 'signed char' we need to ensure we don't + * pass a negative value here. That said, to complicate things further ungetc() is + * actually happy with most negative characters and implicitly casts them back to + * positive ones as needed, except for \xff (aka -1, aka EOF), which it refuses. What a + * godawful API!) */ + assert_se(ungetc((unsigned char) c, f) != EOF); + break; + } + + count++; + + if (eol != EOL_NONE) { + /* If we are on a tty, we can't shouldn't wait for more input, because that + * generally means waiting for the user, interactively. In the case of a TTY + * we expect only \n as the single EOL marker, so we are in the lucky + * position that there is no need to wait. We check this condition last, to + * avoid isatty() check if not necessary. */ + + if ((flags & (READ_LINE_IS_A_TTY|READ_LINE_NOT_A_TTY)) == 0) { + int fd; + + fd = fileno(f); + if (fd < 0) /* Maybe an fmemopen() stream? Handle this gracefully, + * and don't call isatty() on an invalid fd */ + flags |= READ_LINE_NOT_A_TTY; + else + flags |= isatty(fd) ? READ_LINE_IS_A_TTY : READ_LINE_NOT_A_TTY; + } + if (FLAGS_SET(flags, READ_LINE_IS_A_TTY)) + break; + } + + if (eol != EOL_NONE) { + previous_eol |= eol; + continue; + } + + if (ret) { + if (!GREEDY_REALLOC(buffer, allocated, n + 2)) + return -ENOMEM; + + buffer[n] = c; + } + + n++; + } + } + + if (ret) { + buffer[n] = 0; + + *ret = TAKE_PTR(buffer); + } + + return (int) count; +} + +int safe_fgetc(FILE *f, char *ret) { + int k; + + assert(f); + + /* A safer version of plain fgetc(): let's propagate the error that happened while reading as such, and + * separate the EOF condition from the byte read, to avoid those confusion signed/unsigned issues fgetc() + * has. */ + + errno = 0; + k = fgetc(f); + if (k == EOF) { + if (ferror(f)) + return errno_or_else(EIO); + + if (ret) + *ret = 0; + + return 0; + } + + if (ret) + *ret = k; + + return 1; +} +#endif /* NM_IGNORED */ + +int warn_file_is_world_accessible(const char *filename, struct stat *st, const char *unit, unsigned line) { + struct stat _st; + + if (!filename) + return 0; + + if (!st) { + if (stat(filename, &_st) < 0) + return -errno; + st = &_st; + } + + if ((st->st_mode & S_IRWXO) == 0) + return 0; + + if (unit) + log_syntax(unit, LOG_WARNING, filename, line, 0, + "%s has %04o mode that is too permissive, please adjust the ownership and access mode.", + filename, st->st_mode & 07777); + else + log_warning("%s has %04o mode that is too permissive, please adjust the ownership and access mode.", + filename, st->st_mode & 07777); + return 0; +} + +#if 0 /* NM_IGNORED */ +int sync_rights(int from, int to) { + struct stat st; + + if (fstat(from, &st) < 0) + return -errno; + + return fchmod_and_chown(to, st.st_mode & 07777, st.st_uid, st.st_gid); +} + +int rename_and_apply_smack_floor_label(const char *from, const char *to) { + int r = 0; + if (rename(from, to) < 0) + return -errno; + +#ifdef SMACK_RUN_LABEL + r = mac_smack_apply(to, SMACK_ATTR_ACCESS, SMACK_FLOOR_LABEL); + if (r < 0) + return r; +#endif + return r; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/fileio.h b/src/libnm-systemd-shared/src/basic/fileio.h new file mode 100644 index 0000000..5a02856 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/fileio.h @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include +#if 0 /* NM_IGNORED */ +#include +#else /* NM_IGNORED */ +#include +#endif /* NM_IGNORED */ +#include + +#include "macro.h" +#include "time-util.h" + +#define LONG_LINE_MAX (1U*1024U*1024U) + +typedef enum { + WRITE_STRING_FILE_CREATE = 1 << 0, + WRITE_STRING_FILE_TRUNCATE = 1 << 1, + WRITE_STRING_FILE_ATOMIC = 1 << 2, + WRITE_STRING_FILE_AVOID_NEWLINE = 1 << 3, + WRITE_STRING_FILE_VERIFY_ON_FAILURE = 1 << 4, + WRITE_STRING_FILE_SYNC = 1 << 5, + WRITE_STRING_FILE_DISABLE_BUFFER = 1 << 6, + WRITE_STRING_FILE_NOFOLLOW = 1 << 7, + WRITE_STRING_FILE_MKDIR_0755 = 1 << 8, + WRITE_STRING_FILE_MODE_0600 = 1 << 9, + + /* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one + more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file() + and friends. */ + +} WriteStringFileFlags; + +typedef enum { + READ_FULL_FILE_SECURE = 1 << 0, /* erase any buffers we employ internally, after use */ + READ_FULL_FILE_UNBASE64 = 1 << 1, /* base64 decode what we read */ + READ_FULL_FILE_UNHEX = 1 << 2, /* hex decode what we read */ + READ_FULL_FILE_WARN_WORLD_READABLE = 1 << 3, /* if regular file, log at LOG_WARNING level if access mode above 0700 */ + READ_FULL_FILE_CONNECT_SOCKET = 1 << 4, /* if socket inode, connect to it and read off it */ +} ReadFullFileFlags; + +int fopen_unlocked(const char *path, const char *options, FILE **ret); +int fdopen_unlocked(int fd, const char *options, FILE **ret); +int take_fdopen_unlocked(int *fd, const char *options, FILE **ret); +FILE* take_fdopen(int *fd, const char *options); +DIR* take_fdopendir(int *dfd); +FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc); +FILE* fmemopen_unlocked(void *buf, size_t size, const char *mode); + +int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, const struct timespec *ts); +static inline int write_string_stream(FILE *f, const char *line, WriteStringFileFlags flags) { + return write_string_stream_ts(f, line, flags, NULL); +} +int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, const struct timespec *ts); +static inline int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) { + return write_string_file_ts(fn, line, flags, NULL); +} + +int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); + +int read_one_line_file(const char *filename, char **line); +int read_full_file_full(int dir_fd, const char *filename, uint64_t offset, size_t size, ReadFullFileFlags flags, const char *bind_name, char **ret_contents, size_t *ret_size); +static inline int read_full_file(const char *filename, char **ret_contents, size_t *ret_size) { + return read_full_file_full(AT_FDCWD, filename, UINT64_MAX, SIZE_MAX, 0, NULL, ret_contents, ret_size); +} +int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size); +int read_full_stream_full(FILE *f, const char *filename, uint64_t offset, size_t size, ReadFullFileFlags flags, char **ret_contents, size_t *ret_size); +static inline int read_full_stream(FILE *f, char **ret_contents, size_t *ret_size) { + return read_full_stream_full(f, NULL, UINT64_MAX, SIZE_MAX, 0, ret_contents, ret_size); +} + +int verify_file(const char *fn, const char *blob, bool accept_extra_nl); + +int executable_is_script(const char *path, char **interpreter); + +int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field); + +DIR *xopendirat(int dirfd, const char *name, int flags); +int xfopenat(int dir_fd, const char *path, const char *mode, int flags, FILE **ret); + +int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f); +int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f); + +int chase_symlinks_and_fopen_unlocked( + const char *path, + const char *root, + unsigned chase_flags, + const char *open_flags, + FILE **ret_file, + char **ret_path); + +int fflush_and_check(FILE *f); +int fflush_sync_and_check(FILE *f); + +int write_timestamp_file_atomic(const char *fn, usec_t n); +int read_timestamp_file(const char *fn, usec_t *ret); + +int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space); + +typedef enum ReadLineFlags { + READ_LINE_ONLY_NUL = 1 << 0, + READ_LINE_IS_A_TTY = 1 << 1, + READ_LINE_NOT_A_TTY = 1 << 2, +} ReadLineFlags; + +int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret); + +static inline int read_line(FILE *f, size_t limit, char **ret) { + return read_line_full(f, limit, 0, ret); +} + +static inline int read_nul_string(FILE *f, size_t limit, char **ret) { + return read_line_full(f, limit, READ_LINE_ONLY_NUL, ret); +} + +int safe_fgetc(FILE *f, char *ret); + +int warn_file_is_world_accessible(const char *filename, struct stat *st, const char *unit, unsigned line); + +int sync_rights(int from, int to); + +int rename_and_apply_smack_floor_label(const char *temp_path, const char *dest_path); diff --git a/src/libnm-systemd-shared/src/basic/format-util.c b/src/libnm-systemd-shared/src/basic/format-util.c new file mode 100644 index 0000000..42224b6 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/format-util.c @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include "format-util.h" +#include "memory-util.h" +#include "stdio-util.h" + +assert_cc(DECIMAL_STR_MAX(int) + 1 <= IF_NAMESIZE + 1); +char *format_ifname_full(int ifindex, char buf[static IF_NAMESIZE + 1], FormatIfnameFlag flag) { + /* Buffer is always cleared */ + memzero(buf, IF_NAMESIZE + 1); + if (if_indextoname(ifindex, buf)) + return buf; + + if (!FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX)) + return NULL; + + if (FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX_WITH_PERCENT)) + snprintf(buf, IF_NAMESIZE + 1, "%%%d", ifindex); + else + snprintf(buf, IF_NAMESIZE + 1, "%d", ifindex); + + return buf; +} + +char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) { + typedef struct { + const char *suffix; + uint64_t factor; + } suffix_table; + static const suffix_table table_iec[] = { + { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) }, + { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) }, + { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) }, + { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) }, + { "M", UINT64_C(1024)*UINT64_C(1024) }, + { "K", UINT64_C(1024) }, + }, table_si[] = { + { "E", UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000) }, + { "P", UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000) }, + { "T", UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000) }, + { "G", UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000) }, + { "M", UINT64_C(1000)*UINT64_C(1000) }, + { "K", UINT64_C(1000) }, + }; + const suffix_table *table; + size_t n, i; + + assert_cc(ELEMENTSOF(table_iec) == ELEMENTSOF(table_si)); + + if (t == (uint64_t) -1) + return NULL; + + table = flag & FORMAT_BYTES_USE_IEC ? table_iec : table_si; + n = ELEMENTSOF(table_iec); + + for (i = 0; i < n; i++) + if (t >= table[i].factor) { + if (flag & FORMAT_BYTES_BELOW_POINT) { + snprintf(buf, l, + "%" PRIu64 ".%" PRIu64 "%s", + t / table[i].factor, + i != n - 1 ? + (t / table[i + 1].factor * UINT64_C(10) / table[n - 1].factor) % UINT64_C(10): + (t * UINT64_C(10) / table[i].factor) % UINT64_C(10), + table[i].suffix); + } else + snprintf(buf, l, + "%" PRIu64 "%s", + t / table[i].factor, + table[i].suffix); + + goto finish; + } + + snprintf(buf, l, "%" PRIu64 "%s", t, flag & FORMAT_BYTES_TRAILING_B ? "B" : ""); + +finish: + buf[l-1] = 0; + return buf; + +} diff --git a/src/libnm-systemd-shared/src/basic/format-util.h b/src/libnm-systemd-shared/src/basic/format-util.h new file mode 100644 index 0000000..b7e1876 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/format-util.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include + +#include "cgroup-util.h" +#include "macro.h" + +assert_cc(sizeof(pid_t) == sizeof(int32_t)); +#define PID_PRI PRIi32 +#define PID_FMT "%" PID_PRI + +assert_cc(sizeof(uid_t) == sizeof(uint32_t)); +#define UID_FMT "%" PRIu32 + +assert_cc(sizeof(gid_t) == sizeof(uint32_t)); +#define GID_FMT "%" PRIu32 + +#if SIZEOF_TIME_T == 8 +# define PRI_TIME PRIi64 +#elif SIZEOF_TIME_T == 4 +# define PRI_TIME "li" +#else +# error Unknown time_t size +#endif + +#if defined __x86_64__ && defined __ILP32__ +# define PRI_TIMEX PRIi64 +#else +# define PRI_TIMEX "li" +#endif + +#if SIZEOF_RLIM_T == 8 +# define RLIM_FMT "%" PRIu64 +#elif SIZEOF_RLIM_T == 4 +# define RLIM_FMT "%" PRIu32 +#else +# error Unknown rlim_t size +#endif + +#if SIZEOF_DEV_T == 8 +# define DEV_FMT "%" PRIu64 +#elif SIZEOF_DEV_T == 4 +# define DEV_FMT "%" PRIu32 +#else +# error Unknown dev_t size +#endif + +#if SIZEOF_INO_T == 8 +# define INO_FMT "%" PRIu64 +#elif SIZEOF_INO_T == 4 +# define INO_FMT "%" PRIu32 +#else +# error Unknown ino_t size +#endif + +typedef enum { + FORMAT_IFNAME_IFINDEX = 1 << 0, + FORMAT_IFNAME_IFINDEX_WITH_PERCENT = (1 << 1) | FORMAT_IFNAME_IFINDEX, +} FormatIfnameFlag; + +char *format_ifname_full(int ifindex, char buf[static IF_NAMESIZE + 1], FormatIfnameFlag flag); +static inline char *format_ifname(int ifindex, char buf[static IF_NAMESIZE + 1]) { + return format_ifname_full(ifindex, buf, 0); +} + +typedef enum { + FORMAT_BYTES_USE_IEC = 1 << 0, + FORMAT_BYTES_BELOW_POINT = 1 << 1, + FORMAT_BYTES_TRAILING_B = 1 << 2, +} FormatBytesFlag; + +#define FORMAT_BYTES_MAX 16U + +char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag); + +static inline char *format_bytes(char *buf, size_t l, uint64_t t) { + return format_bytes_full(buf, l, t, FORMAT_BYTES_USE_IEC | FORMAT_BYTES_BELOW_POINT | FORMAT_BYTES_TRAILING_B); +} + +static inline char *format_bytes_cgroup_protection(char *buf, size_t l, uint64_t t) { + if (t == CGROUP_LIMIT_MAX) { + (void) snprintf(buf, l, "%s", "infinity"); + return buf; + } + return format_bytes(buf, l, t); +} diff --git a/src/libnm-systemd-shared/src/basic/fs-util.c b/src/libnm-systemd-shared/src/basic/fs-util.c new file mode 100644 index 0000000..2ed9ee0 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/fs-util.c @@ -0,0 +1,1706 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "blockdev-util.h" +#include "dirent-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" +#include "locale-util.h" +#include "log.h" +#include "macro.h" +#include "missing_fcntl.h" +#include "missing_fs.h" +#include "missing_syscall.h" +#include "mkdir.h" +#include "parse-util.h" +#include "path-util.h" +#include "process-util.h" +#include "random-util.h" +#include "stat-util.h" +#include "stdio-util.h" +#include "string-util.h" +#include "strv.h" +#include "time-util.h" +#include "tmpfile-util.h" +#include "user-util.h" +#include "util.h" + +int unlink_noerrno(const char *path) { + PROTECT_ERRNO; + int r; + + r = unlink(path); + if (r < 0) + return -errno; + + return 0; +} + +#if 0 /* NM_IGNORED */ +int rmdir_parents(const char *path, const char *stop) { + size_t l; + int r = 0; + + assert(path); + assert(stop); + + l = strlen(path); + + /* Skip trailing slashes */ + while (l > 0 && path[l-1] == '/') + l--; + + while (l > 0) { + char *t; + + /* Skip last component */ + while (l > 0 && path[l-1] != '/') + l--; + + /* Skip trailing slashes */ + while (l > 0 && path[l-1] == '/') + l--; + + if (l <= 0) + break; + + t = strndup(path, l); + if (!t) + return -ENOMEM; + + if (path_startswith(stop, t)) { + free(t); + return 0; + } + + r = rmdir(t); + free(t); + + if (r < 0) + if (errno != ENOENT) + return -errno; + } + + return 0; +} + +int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) { + int r; + + /* Try the ideal approach first */ + if (renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE) >= 0) + return 0; + + /* renameat2() exists since Linux 3.15, btrfs and FAT added support for it later. If it is not implemented, + * fall back to a different method. */ + if (!IN_SET(errno, EINVAL, ENOSYS, ENOTTY)) + return -errno; + + /* Let's try to use linkat()+unlinkat() as fallback. This doesn't work on directories and on some file systems + * that do not support hard links (such as FAT, most prominently), but for files it's pretty close to what we + * want — though not atomic (i.e. for a short period both the new and the old filename will exist). */ + if (linkat(olddirfd, oldpath, newdirfd, newpath, 0) >= 0) { + + if (unlinkat(olddirfd, oldpath, 0) < 0) { + r = -errno; /* Backup errno before the following unlinkat() alters it */ + (void) unlinkat(newdirfd, newpath, 0); + return r; + } + + return 0; + } + + if (!IN_SET(errno, EINVAL, ENOSYS, ENOTTY, EPERM)) /* FAT returns EPERM on link()… */ + return -errno; + + /* OK, neither RENAME_NOREPLACE nor linkat()+unlinkat() worked. Let's then fall back to the racy TOCTOU + * vulnerable accessat(F_OK) check followed by classic, replacing renameat(), we have nothing better. */ + + if (faccessat(newdirfd, newpath, F_OK, AT_SYMLINK_NOFOLLOW) >= 0) + return -EEXIST; + if (errno != ENOENT) + return -errno; + + if (renameat(olddirfd, oldpath, newdirfd, newpath) < 0) + return -errno; + + return 0; +} +#endif /* NM_IGNORED */ + +int readlinkat_malloc(int fd, const char *p, char **ret) { + size_t l = FILENAME_MAX+1; + int r; + + assert(p); + assert(ret); + + for (;;) { + char *c; + ssize_t n; + + c = new(char, l); + if (!c) + return -ENOMEM; + + n = readlinkat(fd, p, c, l-1); + if (n < 0) { + r = -errno; + free(c); + return r; + } + + if ((size_t) n < l-1) { + c[n] = 0; + *ret = c; + return 0; + } + + free(c); + l *= 2; + } +} + +int readlink_malloc(const char *p, char **ret) { + return readlinkat_malloc(AT_FDCWD, p, ret); +} + +#if 0 /* NM_IGNORED */ +int readlink_value(const char *p, char **ret) { + _cleanup_free_ char *link = NULL; + char *value; + int r; + + r = readlink_malloc(p, &link); + if (r < 0) + return r; + + value = basename(link); + if (!value) + return -ENOENT; + + value = strdup(value); + if (!value) + return -ENOMEM; + + *ret = value; + + return 0; +} + +int readlink_and_make_absolute(const char *p, char **r) { + _cleanup_free_ char *target = NULL; + char *k; + int j; + + assert(p); + assert(r); + + j = readlink_malloc(p, &target); + if (j < 0) + return j; + + k = file_in_same_dir(p, target); + if (!k) + return -ENOMEM; + + *r = k; + return 0; +} + +int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { + _cleanup_close_ int fd = -1; + + assert(path); + + fd = open(path, O_PATH|O_CLOEXEC|O_NOFOLLOW); /* Let's acquire an O_PATH fd, as precaution to change + * mode/owner on the same file */ + if (fd < 0) + return -errno; + + return fchmod_and_chown(fd, mode, uid, gid); +} + +int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) { + bool do_chown, do_chmod; + struct stat st; + int r; + + /* Change ownership and access mode of the specified fd. Tries to do so safely, ensuring that at no + * point in time the access mode is above the old access mode under the old ownership or the new + * access mode under the new ownership. Note: this call tries hard to leave the access mode + * unaffected if the uid/gid is changed, i.e. it undoes implicit suid/sgid dropping the kernel does + * on chown(). + * + * This call is happy with O_PATH fds. */ + + if (fstat(fd, &st) < 0) + return -errno; + + do_chown = + (uid != UID_INVALID && st.st_uid != uid) || + (gid != GID_INVALID && st.st_gid != gid); + + do_chmod = + !S_ISLNK(st.st_mode) && /* chmod is not defined on symlinks */ + ((mode != MODE_INVALID && ((st.st_mode ^ mode) & 07777) != 0) || + do_chown); /* If we change ownership, make sure we reset the mode afterwards, since chown() + * modifies the access mode too */ + + if (mode == MODE_INVALID) + mode = st.st_mode; /* If we only shall do a chown(), save original mode, since chown() might break it. */ + else if ((mode & S_IFMT) != 0 && ((mode ^ st.st_mode) & S_IFMT) != 0) + return -EINVAL; /* insist on the right file type if it was specified */ + + if (do_chown && do_chmod) { + mode_t minimal = st.st_mode & mode; /* the subset of the old and the new mask */ + + if (((minimal ^ st.st_mode) & 07777) != 0) { + r = fchmod_opath(fd, minimal & 07777); + if (r < 0) + return r; + } + } + + if (do_chown) + if (fchownat(fd, "", uid, gid, AT_EMPTY_PATH) < 0) + return -errno; + + if (do_chmod) { + r = fchmod_opath(fd, mode & 07777); + if (r < 0) + return r; + } + + return do_chown || do_chmod; +} + +int fchmod_umask(int fd, mode_t m) { + mode_t u; + int r; + + u = umask(0777); + r = fchmod(fd, m & (~u)) < 0 ? -errno : 0; + umask(u); + + return r; +} + +int fchmod_opath(int fd, mode_t m) { + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + + /* This function operates also on fd that might have been opened with + * O_PATH. Indeed fchmodat() doesn't have the AT_EMPTY_PATH flag like + * fchownat() does. */ + + xsprintf(procfs_path, "/proc/self/fd/%i", fd); + if (chmod(procfs_path, m) < 0) { + if (errno != ENOENT) + return -errno; + + if (proc_mounted() == 0) + return -ENOSYS; /* if we have no /proc/, the concept is not implementable */ + + return -ENOENT; + } + + return 0; +} + +int futimens_opath(int fd, const struct timespec ts[2]) { + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + + /* Similar to fchmod_path() but for futimens() */ + + xsprintf(procfs_path, "/proc/self/fd/%i", fd); + if (utimensat(AT_FDCWD, procfs_path, ts, 0) < 0) { + if (errno != ENOENT) + return -errno; + + if (proc_mounted() == 0) + return -ENOSYS; /* if we have no /proc/, the concept is not implementable */ + + return -ENOENT; + } + + return 0; +} + +int stat_warn_permissions(const char *path, const struct stat *st) { + assert(path); + assert(st); + + /* Don't complain if we are reading something that is not a file, for example /dev/null */ + if (!S_ISREG(st->st_mode)) + return 0; + + if (st->st_mode & 0111) + log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path); + + if (st->st_mode & 0002) + log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path); + + if (getpid_cached() == 1 && (st->st_mode & 0044) != 0044) + log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path); + + return 0; +} + +int fd_warn_permissions(const char *path, int fd) { + struct stat st; + + assert(path); + assert(fd >= 0); + + if (fstat(fd, &st) < 0) + return -errno; + + return stat_warn_permissions(path, &st); +} + +int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) { + char fdpath[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + _cleanup_close_ int fd = -1; + int r, ret = 0; + + assert(path); + + /* Note that touch_file() does not follow symlinks: if invoked on an existing symlink, then it is the symlink + * itself which is updated, not its target + * + * Returns the first error we encounter, but tries to apply as much as possible. */ + + if (parents) + (void) mkdir_parents(path, 0755); + + /* Initially, we try to open the node with O_PATH, so that we get a reference to the node. This is useful in + * case the path refers to an existing device or socket node, as we can open it successfully in all cases, and + * won't trigger any driver magic or so. */ + fd = open(path, O_PATH|O_CLOEXEC|O_NOFOLLOW); + if (fd < 0) { + if (errno != ENOENT) + return -errno; + + /* if the node doesn't exist yet, we create it, but with O_EXCL, so that we only create a regular file + * here, and nothing else */ + fd = open(path, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, IN_SET(mode, 0, MODE_INVALID) ? 0644 : mode); + if (fd < 0) + return -errno; + } + + /* Let's make a path from the fd, and operate on that. With this logic, we can adjust the access mode, + * ownership and time of the file node in all cases, even if the fd refers to an O_PATH object — which is + * something fchown(), fchmod(), futimensat() don't allow. */ + xsprintf(fdpath, "/proc/self/fd/%i", fd); + + ret = fchmod_and_chown(fd, mode, uid, gid); + + if (stamp != USEC_INFINITY) { + struct timespec ts[2]; + + timespec_store(&ts[0], stamp); + ts[1] = ts[0]; + r = utimensat(AT_FDCWD, fdpath, ts, 0); + } else + r = utimensat(AT_FDCWD, fdpath, NULL, 0); + if (r < 0 && ret >= 0) + return -errno; + + return ret; +} + +int touch(const char *path) { + return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID); +} + +int symlink_idempotent(const char *from, const char *to, bool make_relative) { + _cleanup_free_ char *relpath = NULL; + int r; + + assert(from); + assert(to); + + if (make_relative) { + _cleanup_free_ char *parent = NULL; + + parent = dirname_malloc(to); + if (!parent) + return -ENOMEM; + + r = path_make_relative(parent, from, &relpath); + if (r < 0) + return r; + + from = relpath; + } + + if (symlink(from, to) < 0) { + _cleanup_free_ char *p = NULL; + + if (errno != EEXIST) + return -errno; + + r = readlink_malloc(to, &p); + if (r == -EINVAL) /* Not a symlink? In that case return the original error we encountered: -EEXIST */ + return -EEXIST; + if (r < 0) /* Any other error? In that case propagate it as is */ + return r; + + if (!streq(p, from)) /* Not the symlink we want it to be? In that case, propagate the original -EEXIST */ + return -EEXIST; + } + + return 0; +} + +int symlink_atomic(const char *from, const char *to) { + _cleanup_free_ char *t = NULL; + int r; + + assert(from); + assert(to); + + r = tempfn_random(to, NULL, &t); + if (r < 0) + return r; + + if (symlink(from, t) < 0) + return -errno; + + if (rename(t, to) < 0) { + unlink_noerrno(t); + return -errno; + } + + return 0; +} + +int mknod_atomic(const char *path, mode_t mode, dev_t dev) { + _cleanup_free_ char *t = NULL; + int r; + + assert(path); + + r = tempfn_random(path, NULL, &t); + if (r < 0) + return r; + + if (mknod(t, mode, dev) < 0) + return -errno; + + if (rename(t, path) < 0) { + unlink_noerrno(t); + return -errno; + } + + return 0; +} + +int mkfifo_atomic(const char *path, mode_t mode) { + _cleanup_free_ char *t = NULL; + int r; + + assert(path); + + r = tempfn_random(path, NULL, &t); + if (r < 0) + return r; + + if (mkfifo(t, mode) < 0) + return -errno; + + if (rename(t, path) < 0) { + unlink_noerrno(t); + return -errno; + } + + return 0; +} + +int mkfifoat_atomic(int dirfd, const char *path, mode_t mode) { + _cleanup_free_ char *t = NULL; + int r; + + assert(path); + + if (path_is_absolute(path)) + return mkfifo_atomic(path, mode); + + /* We're only interested in the (random) filename. */ + r = tempfn_random_child("", NULL, &t); + if (r < 0) + return r; + + if (mkfifoat(dirfd, t, mode) < 0) + return -errno; + + if (renameat(dirfd, t, dirfd, path) < 0) { + unlink_noerrno(t); + return -errno; + } + + return 0; +} + +int get_files_in_directory(const char *path, char ***list) { + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + size_t bufsize = 0, n = 0; + _cleanup_strv_free_ char **l = NULL; + + assert(path); + + /* Returns all files in a directory in *list, and the number + * of files as return value. If list is NULL returns only the + * number. */ + + d = opendir(path); + if (!d) + return -errno; + + FOREACH_DIRENT_ALL(de, d, return -errno) { + dirent_ensure_type(d, de); + + if (!dirent_is_file(de)) + continue; + + if (list) { + /* one extra slot is needed for the terminating NULL */ + if (!GREEDY_REALLOC(l, bufsize, n + 2)) + return -ENOMEM; + + l[n] = strdup(de->d_name); + if (!l[n]) + return -ENOMEM; + + l[++n] = NULL; + } else + n++; + } + + if (list) + *list = TAKE_PTR(l); + + return n; +} +#endif /* NM_IGNORED */ + +static int getenv_tmp_dir(const char **ret_path) { + const char *n; + int r, ret = 0; + + assert(ret_path); + + /* We use the same order of environment variables python uses in tempfile.gettempdir(): + * https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir */ + FOREACH_STRING(n, "TMPDIR", "TEMP", "TMP") { + const char *e; + + e = secure_getenv(n); + if (!e) + continue; + if (!path_is_absolute(e)) { + r = -ENOTDIR; + goto next; + } + if (!path_is_normalized(e)) { + r = -EPERM; + goto next; + } + + r = is_dir(e, true); + if (r < 0) + goto next; + if (r == 0) { + r = -ENOTDIR; + goto next; + } + + *ret_path = e; + return 1; + + next: + /* Remember first error, to make this more debuggable */ + if (ret >= 0) + ret = r; + } + + if (ret < 0) + return ret; + + *ret_path = NULL; + return ret; +} + +static int tmp_dir_internal(const char *def, const char **ret) { + const char *e; + int r, k; + + assert(def); + assert(ret); + + r = getenv_tmp_dir(&e); + if (r > 0) { + *ret = e; + return 0; + } + + k = is_dir(def, true); + if (k == 0) + k = -ENOTDIR; + if (k < 0) + return r < 0 ? r : k; + + *ret = def; + return 0; +} + +#if 0 /* NM_IGNORED */ +int var_tmp_dir(const char **ret) { + + /* Returns the location for "larger" temporary files, that is backed by physical storage if available, and thus + * even might survive a boot: /var/tmp. If $TMPDIR (or related environment variables) are set, its value is + * returned preferably however. Note that both this function and tmp_dir() below are affected by $TMPDIR, + * making it a variable that overrides all temporary file storage locations. */ + + return tmp_dir_internal("/var/tmp", ret); +} +#endif /* NM_IGNORED */ + +int tmp_dir(const char **ret) { + + /* Similar to var_tmp_dir() above, but returns the location for "smaller" temporary files, which is usually + * backed by an in-memory file system: /tmp. */ + + return tmp_dir_internal("/tmp", ret); +} + +#if 0 /* NM_IGNORED */ +int unlink_or_warn(const char *filename) { + if (unlink(filename) < 0 && errno != ENOENT) + /* If the file doesn't exist and the fs simply was read-only (in which + * case unlink() returns EROFS even if the file doesn't exist), don't + * complain */ + if (errno != EROFS || access(filename, F_OK) >= 0) + return log_error_errno(errno, "Failed to remove \"%s\": %m", filename); + + return 0; +} +#endif /* NM_IGNORED */ + +int inotify_add_watch_fd(int fd, int what, uint32_t mask) { + char path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; + int wd; + + /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */ + xsprintf(path, "/proc/self/fd/%i", what); + + wd = inotify_add_watch(fd, path, mask); + if (wd < 0) + return -errno; + + return wd; +} + +#if 0 /* NM_IGNORED */ +int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask) { + int wd; + + wd = inotify_add_watch(fd, pathname, mask); + if (wd < 0) { + if (errno == ENOSPC) + return log_error_errno(errno, "Failed to add a watch for %s: inotify watch limit reached", pathname); + + return log_error_errno(errno, "Failed to add a watch for %s: %m", pathname); + } + + return wd; +} + +static bool unsafe_transition(const struct stat *a, const struct stat *b) { + /* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to + * privileged files or directories. Why bother? So that unprivileged code can't symlink to privileged files + * making us believe we read something safe even though it isn't safe in the specific context we open it in. */ + + if (a->st_uid == 0) /* Transitioning from privileged to unprivileged is always fine */ + return false; + + return a->st_uid != b->st_uid; /* Otherwise we need to stay within the same UID */ +} + +static int log_unsafe_transition(int a, int b, const char *path, unsigned flags) { + _cleanup_free_ char *n1 = NULL, *n2 = NULL; + + if (!FLAGS_SET(flags, CHASE_WARN)) + return -ENOLINK; + + (void) fd_get_path(a, &n1); + (void) fd_get_path(b, &n2); + + return log_warning_errno(SYNTHETIC_ERRNO(ENOLINK), + "Detected unsafe path transition %s %s %s during canonicalization of %s.", + strna(n1), special_glyph(SPECIAL_GLYPH_ARROW), strna(n2), path); +} + +static int log_autofs_mount_point(int fd, const char *path, unsigned flags) { + _cleanup_free_ char *n1 = NULL; + + if (!FLAGS_SET(flags, CHASE_WARN)) + return -EREMOTE; + + (void) fd_get_path(fd, &n1); + + return log_warning_errno(SYNTHETIC_ERRNO(EREMOTE), + "Detected autofs mount point %s during canonicalization of %s.", + strna(n1), path); +} + +int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret_path, int *ret_fd) { + _cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL; + _cleanup_close_ int fd = -1; + unsigned max_follow = CHASE_SYMLINKS_MAX; /* how many symlinks to follow before giving up and returning ELOOP */ + struct stat previous_stat; + bool exists = true; + char *todo; + int r; + + assert(path); + + /* Either the file may be missing, or we return an fd to the final object, but both make no sense */ + if ((flags & CHASE_NONEXISTENT) && ret_fd) + return -EINVAL; + + if ((flags & CHASE_STEP) && ret_fd) + return -EINVAL; + + if (isempty(path)) + return -EINVAL; + + /* This is a lot like canonicalize_file_name(), but takes an additional "root" parameter, that allows following + * symlinks relative to a root directory, instead of the root of the host. + * + * Note that "root" primarily matters if we encounter an absolute symlink. It is also used when following + * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed is + * assumed to be already prefixed by it, except if the CHASE_PREFIX_ROOT flag is set, in which case it is first + * prefixed accordingly. + * + * Algorithmically this operates on two path buffers: "done" are the components of the path we already + * processed and resolved symlinks, "." and ".." of. "todo" are the components of the path we still need to + * process. On each iteration, we move one component from "todo" to "done", processing it's special meaning + * each time. The "todo" path always starts with at least one slash, the "done" path always ends in no + * slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races + * to a minimum. + * + * Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got + * as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this + * function what to do when encountering a symlink with an absolute path as directory: prefix it by the + * specified path. + * + * There are five ways to invoke this function: + * + * 1. Without CHASE_STEP or ret_fd: in this case the path is resolved and the normalized path is + * returned in `ret_path`. The return value is < 0 on error. If CHASE_NONEXISTENT is also set, 0 + * is returned if the file doesn't exist, > 0 otherwise. If CHASE_NONEXISTENT is not set, >= 0 is + * returned if the destination was found, -ENOENT if it wasn't. + * + * 2. With ret_fd: in this case the destination is opened after chasing it as O_PATH and this file + * descriptor is returned as return value. This is useful to open files relative to some root + * directory. Note that the returned O_PATH file descriptors must be converted into a regular one (using + * fd_reopen() or such) before it can be used for reading/writing. ret_fd may not be combined with + * CHASE_NONEXISTENT. + * + * 3. With CHASE_STEP: in this case only a single step of the normalization is executed, i.e. only the first + * symlink or ".." component of the path is resolved, and the resulting path is returned. This is useful if + * a caller wants to trace the path through the file system verbosely. Returns < 0 on error, > 0 if the + * path is fully normalized, and == 0 for each normalization step. This may be combined with + * CHASE_NONEXISTENT, in which case 1 is returned when a component is not found. + * + * 4. With CHASE_SAFE: in this case the path must not contain unsafe transitions, i.e. transitions from + * unprivileged to privileged files or directories. In such cases the return value is -ENOLINK. If + * CHASE_WARN is also set, a warning describing the unsafe transition is emitted. + * + * 5. With CHASE_NO_AUTOFS: in this case if an autofs mount point is encountered, path normalization + * is aborted and -EREMOTE is returned. If CHASE_WARN is also set, a warning showing the path of + * the mount point is emitted. + */ + + /* A root directory of "/" or "" is identical to none */ + if (empty_or_root(original_root)) + original_root = NULL; + + if (!original_root && !ret_path && !(flags & (CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_STEP)) && ret_fd) { + /* Shortcut the ret_fd case if the caller isn't interested in the actual path and has no root set + * and doesn't care about any of the other special features we provide either. */ + r = open(path, O_PATH|O_CLOEXEC|((flags & CHASE_NOFOLLOW) ? O_NOFOLLOW : 0)); + if (r < 0) + return -errno; + + *ret_fd = r; + return 0; + } + + if (original_root) { + r = path_make_absolute_cwd(original_root, &root); + if (r < 0) + return r; + + /* Simplify the root directory, so that it has no duplicate slashes and nothing at the + * end. While we won't resolve the root path we still simplify it. Note that dropping the + * trailing slash should not change behaviour, since when opening it we specify O_DIRECTORY + * anyway. Moreover at the end of this function after processing everything we'll always turn + * the empty string back to "/". */ + delete_trailing_chars(root, "/"); + path_simplify(root, true); + + if (flags & CHASE_PREFIX_ROOT) { + /* We don't support relative paths in combination with a root directory */ + if (!path_is_absolute(path)) + return -EINVAL; + + path = prefix_roota(root, path); + } + } + + r = path_make_absolute_cwd(path, &buffer); + if (r < 0) + return r; + + fd = open(root ?: "/", O_CLOEXEC|O_DIRECTORY|O_PATH); + if (fd < 0) + return -errno; + + if (flags & CHASE_SAFE) { + if (fstat(fd, &previous_stat) < 0) + return -errno; + } + + if (root) { + _cleanup_free_ char *absolute = NULL; + const char *e; + + /* If we are operating on a root directory, let's take the root directory as it is. */ + + e = path_startswith(buffer, root); + if (!e) + return log_full_errno(flags & CHASE_WARN ? LOG_WARNING : LOG_DEBUG, + SYNTHETIC_ERRNO(ECHRNG), + "Specified path '%s' is outside of specified root directory '%s', refusing to resolve.", + path, root); + + done = strdup(root); + if (!done) + return -ENOMEM; + + /* Make sure "todo" starts with a slash */ + absolute = strjoin("/", e); + if (!absolute) + return -ENOMEM; + + free_and_replace(buffer, absolute); + } + + todo = buffer; + for (;;) { + _cleanup_free_ char *first = NULL; + _cleanup_close_ int child = -1; + struct stat st; + size_t n, m; + + /* Determine length of first component in the path */ + n = strspn(todo, "/"); /* The slashes */ + + if (n > 1) { + /* If we are looking at more than a single slash then skip all but one, so that when + * we are done with everything we have a normalized path with only single slashes + * separating the path components. */ + todo += n - 1; + n = 1; + } + + m = n + strcspn(todo + n, "/"); /* The entire length of the component */ + + /* Extract the first component. */ + first = strndup(todo, m); + if (!first) + return -ENOMEM; + + todo += m; + + /* Empty? Then we reached the end. */ + if (isempty(first)) + break; + + /* Just a single slash? Then we reached the end. */ + if (path_equal(first, "/")) { + /* Preserve the trailing slash */ + + if (flags & CHASE_TRAIL_SLASH) + if (!strextend(&done, "/")) + return -ENOMEM; + + break; + } + + /* Just a dot? Then let's eat this up. */ + if (path_equal(first, "/.")) + continue; + + /* Two dots? Then chop off the last bit of what we already found out. */ + if (path_equal(first, "/..")) { + _cleanup_free_ char *parent = NULL; + _cleanup_close_ int fd_parent = -1; + + /* If we already are at the top, then going up will not change anything. This is in-line with + * how the kernel handles this. */ + if (empty_or_root(done)) + continue; + + parent = dirname_malloc(done); + if (!parent) + return -ENOMEM; + + /* Don't allow this to leave the root dir. */ + if (root && + path_startswith(done, root) && + !path_startswith(parent, root)) + continue; + + free_and_replace(done, parent); + + if (flags & CHASE_STEP) + goto chased_one; + + fd_parent = openat(fd, "..", O_CLOEXEC|O_NOFOLLOW|O_PATH); + if (fd_parent < 0) + return -errno; + + if (flags & CHASE_SAFE) { + if (fstat(fd_parent, &st) < 0) + return -errno; + + if (unsafe_transition(&previous_stat, &st)) + return log_unsafe_transition(fd, fd_parent, path, flags); + + previous_stat = st; + } + + safe_close(fd); + fd = TAKE_FD(fd_parent); + + continue; + } + + /* Otherwise let's see what this is. */ + child = openat(fd, first + n, O_CLOEXEC|O_NOFOLLOW|O_PATH); + if (child < 0) { + + if (errno == ENOENT && + (flags & CHASE_NONEXISTENT) && + (isempty(todo) || path_is_normalized(todo))) { + + /* If CHASE_NONEXISTENT is set, and the path does not exist, then that's OK, return + * what we got so far. But don't allow this if the remaining path contains "../ or "./" + * or something else weird. */ + + /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */ + if (streq_ptr(done, "/")) + *done = '\0'; + + if (!strextend(&done, first, todo)) + return -ENOMEM; + + exists = false; + break; + } + + return -errno; + } + + if (fstat(child, &st) < 0) + return -errno; + if ((flags & CHASE_SAFE) && + unsafe_transition(&previous_stat, &st)) + return log_unsafe_transition(fd, child, path, flags); + + previous_stat = st; + + if ((flags & CHASE_NO_AUTOFS) && + fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0) + return log_autofs_mount_point(child, path, flags); + + if (S_ISLNK(st.st_mode) && !((flags & CHASE_NOFOLLOW) && isempty(todo))) { + char *joined; + _cleanup_free_ char *destination = NULL; + + /* This is a symlink, in this case read the destination. But let's make sure we don't follow + * symlinks without bounds. */ + if (--max_follow <= 0) + return -ELOOP; + + r = readlinkat_malloc(fd, first + n, &destination); + if (r < 0) + return r; + if (isempty(destination)) + return -EINVAL; + + if (path_is_absolute(destination)) { + + /* An absolute destination. Start the loop from the beginning, but use the root + * directory as base. */ + + safe_close(fd); + fd = open(root ?: "/", O_CLOEXEC|O_DIRECTORY|O_PATH); + if (fd < 0) + return -errno; + + if (flags & CHASE_SAFE) { + if (fstat(fd, &st) < 0) + return -errno; + + if (unsafe_transition(&previous_stat, &st)) + return log_unsafe_transition(child, fd, path, flags); + + previous_stat = st; + } + + free(done); + + /* Note that we do not revalidate the root, we take it as is. */ + if (isempty(root)) + done = NULL; + else { + done = strdup(root); + if (!done) + return -ENOMEM; + } + + /* Prefix what's left to do with what we just read, and start the loop again, but + * remain in the current directory. */ + joined = path_join(destination, todo); + } else + joined = path_join("/", destination, todo); + if (!joined) + return -ENOMEM; + + free(buffer); + todo = buffer = joined; + + if (flags & CHASE_STEP) + goto chased_one; + + continue; + } + + /* If this is not a symlink, then let's just add the name we read to what we already verified. */ + if (!done) + done = TAKE_PTR(first); + else { + /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */ + if (streq(done, "/")) + *done = '\0'; + + if (!strextend(&done, first)) + return -ENOMEM; + } + + /* And iterate again, but go one directory further down. */ + safe_close(fd); + fd = TAKE_FD(child); + } + + if (!done) { + /* Special case, turn the empty string into "/", to indicate the root directory. */ + done = strdup("/"); + if (!done) + return -ENOMEM; + } + + if (ret_path) + *ret_path = TAKE_PTR(done); + + if (ret_fd) { + /* Return the O_PATH fd we currently are looking to the caller. It can translate it to a + * proper fd by opening /proc/self/fd/xyz. */ + + assert(fd >= 0); + *ret_fd = TAKE_FD(fd); + } + + if (flags & CHASE_STEP) + return 1; + + return exists; + +chased_one: + if (ret_path) { + char *c; + + c = strjoin(strempty(done), todo); + if (!c) + return -ENOMEM; + + *ret_path = c; + } + + return 0; +} + +int chase_symlinks_and_open( + const char *path, + const char *root, + unsigned chase_flags, + int open_flags, + char **ret_path) { + + _cleanup_close_ int path_fd = -1; + _cleanup_free_ char *p = NULL; + int r; + + if (chase_flags & CHASE_NONEXISTENT) + return -EINVAL; + + if (empty_or_root(root) && !ret_path && (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE)) == 0) { + /* Shortcut this call if none of the special features of this call are requested */ + r = open(path, open_flags); + if (r < 0) + return -errno; + + return r; + } + + r = chase_symlinks(path, root, chase_flags, ret_path ? &p : NULL, &path_fd); + if (r < 0) + return r; + assert(path_fd >= 0); + + r = fd_reopen(path_fd, open_flags); + if (r < 0) + return r; + + if (ret_path) + *ret_path = TAKE_PTR(p); + + return r; +} + +int chase_symlinks_and_opendir( + const char *path, + const char *root, + unsigned chase_flags, + char **ret_path, + DIR **ret_dir) { + + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + _cleanup_close_ int path_fd = -1; + _cleanup_free_ char *p = NULL; + DIR *d; + int r; + + if (!ret_dir) + return -EINVAL; + if (chase_flags & CHASE_NONEXISTENT) + return -EINVAL; + + if (empty_or_root(root) && !ret_path && (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE)) == 0) { + /* Shortcut this call if none of the special features of this call are requested */ + d = opendir(path); + if (!d) + return -errno; + + *ret_dir = d; + return 0; + } + + r = chase_symlinks(path, root, chase_flags, ret_path ? &p : NULL, &path_fd); + if (r < 0) + return r; + assert(path_fd >= 0); + + xsprintf(procfs_path, "/proc/self/fd/%i", path_fd); + d = opendir(procfs_path); + if (!d) + return -errno; + + if (ret_path) + *ret_path = TAKE_PTR(p); + + *ret_dir = d; + return 0; +} + +int chase_symlinks_and_stat( + const char *path, + const char *root, + unsigned chase_flags, + char **ret_path, + struct stat *ret_stat, + int *ret_fd) { + + _cleanup_close_ int path_fd = -1; + _cleanup_free_ char *p = NULL; + int r; + + assert(path); + assert(ret_stat); + + if (chase_flags & CHASE_NONEXISTENT) + return -EINVAL; + + if (empty_or_root(root) && !ret_path && (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE)) == 0) { + /* Shortcut this call if none of the special features of this call are requested */ + if (stat(path, ret_stat) < 0) + return -errno; + + return 1; + } + + r = chase_symlinks(path, root, chase_flags, ret_path ? &p : NULL, &path_fd); + if (r < 0) + return r; + assert(path_fd >= 0); + + if (fstat(path_fd, ret_stat) < 0) + return -errno; + + if (ret_path) + *ret_path = TAKE_PTR(p); + if (ret_fd) + *ret_fd = TAKE_FD(path_fd); + + return 1; +} + +int access_fd(int fd, int mode) { + char p[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1]; + + /* Like access() but operates on an already open fd */ + + xsprintf(p, "/proc/self/fd/%i", fd); + if (access(p, mode) < 0) { + if (errno != ENOENT) + return -errno; + + /* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's + * make things debuggable and distinguish the two. */ + + if (proc_mounted() == 0) + return -ENOSYS; /* /proc is not available or not set up properly, we're most likely in some chroot + * environment. */ + + return -EBADF; /* The directory exists, hence it's the fd that doesn't. */ + } + + return 0; +} + +void unlink_tempfilep(char (*p)[]) { + /* If the file is created with mkstemp(), it will (almost always) + * change the suffix. Treat this as a sign that the file was + * successfully created. We ignore both the rare case where the + * original suffix is used and unlink failures. */ + if (!endswith(*p, ".XXXXXX")) + (void) unlink_noerrno(*p); +} + +int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags) { + _cleanup_close_ int truncate_fd = -1; + struct stat st; + off_t l, bs; + + assert((flags & ~(UNLINK_REMOVEDIR|UNLINK_ERASE)) == 0); + + /* Operates like unlinkat() but also deallocates the file contents if it is a regular file and there's no other + * link to it. This is useful to ensure that other processes that might have the file open for reading won't be + * able to keep the data pinned on disk forever. This call is particular useful whenever we execute clean-up + * jobs ("vacuuming"), where we want to make sure the data is really gone and the disk space released and + * returned to the free pool. + * + * Deallocation is preferably done by FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE (👊) if supported, which means + * the file won't change size. That's a good thing since we shouldn't needlessly trigger SIGBUS in other + * programs that have mmap()ed the file. (The assumption here is that changing file contents to all zeroes + * underneath those programs is the better choice than simply triggering SIGBUS in them which truncation does.) + * However if hole punching is not implemented in the kernel or file system we'll fall back to normal file + * truncation (🔪), as our goal of deallocating the data space trumps our goal of being nice to readers (💐). + * + * Note that we attempt deallocation, but failure to succeed with that is not considered fatal, as long as the + * primary job – to delete the file – is accomplished. */ + + if (!FLAGS_SET(flags, UNLINK_REMOVEDIR)) { + truncate_fd = openat(fd, name, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW|O_NONBLOCK); + if (truncate_fd < 0) { + + /* If this failed because the file doesn't exist propagate the error right-away. Also, + * AT_REMOVEDIR wasn't set, and we tried to open the file for writing, which means EISDIR is + * returned when this is a directory but we are not supposed to delete those, hence propagate + * the error right-away too. */ + if (IN_SET(errno, ENOENT, EISDIR)) + return -errno; + + if (errno != ELOOP) /* don't complain if this is a symlink */ + log_debug_errno(errno, "Failed to open file '%s' for deallocation, ignoring: %m", name); + } + } + + if (unlinkat(fd, name, FLAGS_SET(flags, UNLINK_REMOVEDIR) ? AT_REMOVEDIR : 0) < 0) + return -errno; + + if (truncate_fd < 0) /* Don't have a file handle, can't do more ☹️ */ + return 0; + + if (fstat(truncate_fd, &st) < 0) { + log_debug_errno(errno, "Failed to stat file '%s' for deallocation, ignoring: %m", name); + return 0; + } + + if (!S_ISREG(st.st_mode)) + return 0; + + if (FLAGS_SET(flags, UNLINK_ERASE) && st.st_size > 0 && st.st_nlink == 0) { + uint64_t left = st.st_size; + char buffer[64 * 1024]; + + /* If erasing is requested, let's overwrite the file with random data once before deleting + * it. This isn't going to give you shred(1) semantics, but hopefully should be good enough + * for stuff backed by tmpfs at least. + * + * Note that we only erase like this if the link count of the file is zero. If it is higher it + * is still linked by someone else and we'll leave it to them to remove it securely + * eventually! */ + + random_bytes(buffer, sizeof(buffer)); + + while (left > 0) { + ssize_t n; + + n = write(truncate_fd, buffer, MIN(sizeof(buffer), left)); + if (n < 0) { + log_debug_errno(errno, "Failed to erase data in file '%s', ignoring.", name); + break; + } + + assert(left >= (size_t) n); + left -= n; + } + + /* Let's refresh metadata */ + if (fstat(truncate_fd, &st) < 0) { + log_debug_errno(errno, "Failed to stat file '%s' for deallocation, ignoring: %m", name); + return 0; + } + } + + /* Don't dallocate if there's nothing to deallocate or if the file is linked elsewhere */ + if (st.st_blocks == 0 || st.st_nlink > 0) + return 0; + + /* If this is a regular file, it actually took up space on disk and there are no other links it's time to + * punch-hole/truncate this to release the disk space. */ + + bs = MAX(st.st_blksize, 512); + l = DIV_ROUND_UP(st.st_size, bs) * bs; /* Round up to next block size */ + + if (fallocate(truncate_fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, 0, l) >= 0) + return 0; /* Successfully punched a hole! 😊 */ + + /* Fall back to truncation */ + if (ftruncate(truncate_fd, 0) < 0) { + log_debug_errno(errno, "Failed to truncate file to 0, ignoring: %m"); + return 0; + } + + return 0; +} + +#if 0 /* NM_IGNORED */ +int fsync_directory_of_file(int fd) { + _cleanup_free_ char *path = NULL; + _cleanup_close_ int dfd = -1; + int r; + + r = fd_verify_regular(fd); + if (r < 0) + return r; + + r = fd_get_path(fd, &path); + if (r < 0) { + log_debug_errno(r, "Failed to query /proc/self/fd/%d%s: %m", + fd, + r == -ENOSYS ? ", ignoring" : ""); + + if (r == -ENOSYS) + /* If /proc is not available, we're most likely running in some + * chroot environment, and syncing the directory is not very + * important in that case. Let's just silently do nothing. */ + return 0; + + return r; + } + + if (!path_is_absolute(path)) + return -EINVAL; + + dfd = open_parent(path, O_CLOEXEC, 0); + if (dfd < 0) + return dfd; + + if (fsync(dfd) < 0) + return -errno; + + return 0; +} +#endif /* NM_IGNORED */ + +int fsync_full(int fd) { + int r, q; + + /* Sync both the file and the directory */ + + r = fsync(fd) < 0 ? -errno : 0; + q = fsync_directory_of_file(fd); + + return r < 0 ? r : q; +} + +int fsync_path_at(int at_fd, const char *path) { + _cleanup_close_ int opened_fd = -1; + int fd; + + if (isempty(path)) { + if (at_fd == AT_FDCWD) { + opened_fd = open(".", O_RDONLY|O_DIRECTORY|O_CLOEXEC); + if (opened_fd < 0) + return -errno; + + fd = opened_fd; + } else + fd = at_fd; + } else { + + opened_fd = openat(at_fd, path, O_RDONLY|O_CLOEXEC); + if (opened_fd < 0) + return -errno; + + fd = opened_fd; + } + + if (fsync(fd) < 0) + return -errno; + + return 0; +} + +int syncfs_path(int atfd, const char *path) { + _cleanup_close_ int fd = -1; + + assert(path); + + fd = openat(atfd, path, O_CLOEXEC|O_RDONLY|O_NONBLOCK); + if (fd < 0) + return -errno; + + if (syncfs(fd) < 0) + return -errno; + + return 0; +} + +int open_parent(const char *path, int flags, mode_t mode) { + _cleanup_free_ char *parent = NULL; + int fd; + + if (isempty(path)) + return -EINVAL; + if (path_equal(path, "/")) /* requesting the parent of the root dir is fishy, let's prohibit that */ + return -EINVAL; + + parent = dirname_malloc(path); + if (!parent) + return -ENOMEM; + + /* Let's insist on O_DIRECTORY since the parent of a file or directory is a directory. Except if we open an + * O_TMPFILE file, because in that case we are actually create a regular file below the parent directory. */ + + if (FLAGS_SET(flags, O_PATH)) + flags |= O_DIRECTORY; + else if (!FLAGS_SET(flags, O_TMPFILE)) + flags |= O_DIRECTORY|O_RDONLY; + + fd = open(parent, flags, mode); + if (fd < 0) + return -errno; + + return fd; +} + +static int blockdev_is_encrypted(const char *sysfs_path, unsigned depth_left) { + _cleanup_free_ char *p = NULL, *uuids = NULL; + _cleanup_closedir_ DIR *d = NULL; + int r, found_encrypted = false; + + assert(sysfs_path); + + if (depth_left == 0) + return -EINVAL; + + p = path_join(sysfs_path, "dm/uuid"); + if (!p) + return -ENOMEM; + + r = read_one_line_file(p, &uuids); + if (r != -ENOENT) { + if (r < 0) + return r; + + /* The DM device's uuid attribute is prefixed with "CRYPT-" if this is a dm-crypt device. */ + if (startswith(uuids, "CRYPT-")) + return true; + } + + /* Not a dm-crypt device itself. But maybe it is on top of one? Follow the links in the "slaves/" + * subdir. */ + + p = mfree(p); + p = path_join(sysfs_path, "slaves"); + if (!p) + return -ENOMEM; + + d = opendir(p); + if (!d) { + if (errno == ENOENT) /* Doesn't have underlying devices */ + return false; + + return -errno; + } + + for (;;) { + _cleanup_free_ char *q = NULL; + struct dirent *de; + + errno = 0; + de = readdir_no_dot(d); + if (!de) { + if (errno != 0) + return -errno; + + break; /* No more underlying devices */ + } + + q = path_join(p, de->d_name); + if (!q) + return -ENOMEM; + + r = blockdev_is_encrypted(q, depth_left - 1); + if (r < 0) + return r; + if (r == 0) /* we found one that is not encrypted? then propagate that immediately */ + return false; + + found_encrypted = true; + } + + return found_encrypted; +} + +int path_is_encrypted(const char *path) { + char p[SYS_BLOCK_PATH_MAX(NULL)]; + dev_t devt; + int r; + + r = get_block_device(path, &devt); + if (r < 0) + return r; + if (r == 0) /* doesn't have a block device */ + return false; + + xsprintf_sys_block_path(p, NULL, devt); + + return blockdev_is_encrypted(p, 10 /* safety net: maximum recursion depth */); +} + +int conservative_rename( + int olddirfd, const char *oldpath, + int newdirfd, const char *newpath) { + + _cleanup_close_ int old_fd = -1, new_fd = -1; + struct stat old_stat, new_stat; + + /* Renames the old path to thew new path, much like renameat() — except if both are regular files and + * have the exact same contents and basic file attributes already. In that case remove the new file + * instead. This call is useful for reducing inotify wakeups on files that are updated but don't + * actually change. This function is written in a style that we rather rename too often than suppress + * too much. i.e. whenever we are in doubt we rather rename than fail. After all reducing inotify + * events is an optimization only, not more. */ + + old_fd = openat(olddirfd, oldpath, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_NOFOLLOW); + if (old_fd < 0) + goto do_rename; + + new_fd = openat(newdirfd, newpath, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_NOFOLLOW); + if (new_fd < 0) + goto do_rename; + + if (fstat(old_fd, &old_stat) < 0) + goto do_rename; + + if (!S_ISREG(old_stat.st_mode)) + goto do_rename; + + if (fstat(new_fd, &new_stat) < 0) + goto do_rename; + + if (new_stat.st_ino == old_stat.st_ino && + new_stat.st_dev == old_stat.st_dev) + goto is_same; + + if (old_stat.st_mode != new_stat.st_mode || + old_stat.st_size != new_stat.st_size || + old_stat.st_uid != new_stat.st_uid || + old_stat.st_gid != new_stat.st_gid) + goto do_rename; + + for (;;) { + char buf1[16*1024]; + char buf2[sizeof(buf1) + 1]; + ssize_t l1, l2; + + l1 = read(old_fd, buf1, sizeof(buf1)); + if (l1 < 0) + goto do_rename; + + l2 = read(new_fd, buf2, l1 + 1); + if (l1 != l2) + goto do_rename; + + if (l1 == 0) /* EOF on both! And everything's the same so far, yay! */ + break; + + if (memcmp(buf1, buf2, l1) != 0) + goto do_rename; + } + +is_same: + /* Everything matches? Then don't rename, instead remove the source file, and leave the existing + * destination in place */ + + if (unlinkat(olddirfd, oldpath, 0) < 0) + goto do_rename; + + return 0; + +do_rename: + if (renameat(olddirfd, oldpath, newdirfd, newpath) < 0) + return -errno; + + return 1; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/fs-util.h b/src/libnm-systemd-shared/src/basic/fs-util.h new file mode 100644 index 0000000..9a39473 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/fs-util.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "errno-util.h" +#include "time-util.h" + +#define MODE_INVALID ((mode_t) -1) + +/* The following macros add 1 when converting things, since 0 is a valid mode, while the pointer + * NULL is special */ +#define PTR_TO_MODE(p) ((mode_t) ((uintptr_t) (p)-1)) +#define MODE_TO_PTR(u) ((void *) ((uintptr_t) (u)+1)) + +int unlink_noerrno(const char *path); + +int rmdir_parents(const char *path, const char *stop); + +int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); + +int readlinkat_malloc(int fd, const char *p, char **ret); +int readlink_malloc(const char *p, char **r); +int readlink_value(const char *p, char **ret); +int readlink_and_make_absolute(const char *p, char **r); + +int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid); +int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid); + +int fchmod_umask(int fd, mode_t mode); +int fchmod_opath(int fd, mode_t m); + +int futimens_opath(int fd, const struct timespec ts[2]); + +int fd_warn_permissions(const char *path, int fd); +int stat_warn_permissions(const char *path, const struct stat *st); + +#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW) + +int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode); +int touch(const char *path); + +int symlink_idempotent(const char *from, const char *to, bool make_relative); + +int symlink_atomic(const char *from, const char *to); +int mknod_atomic(const char *path, mode_t mode, dev_t dev); +int mkfifo_atomic(const char *path, mode_t mode); +int mkfifoat_atomic(int dir_fd, const char *path, mode_t mode); + +int get_files_in_directory(const char *path, char ***list); + +int tmp_dir(const char **ret); +int var_tmp_dir(const char **ret); + +int unlink_or_warn(const char *filename); + +#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1) + +#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \ + for ((e) = &buffer.ev; \ + (uint8_t*) (e) < (uint8_t*) (buffer.raw) + (sz); \ + (e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len)) + +union inotify_event_buffer { + struct inotify_event ev; + uint8_t raw[INOTIFY_EVENT_MAX]; +}; + +int inotify_add_watch_fd(int fd, int what, uint32_t mask); +int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask); + +enum { + CHASE_PREFIX_ROOT = 1 << 0, /* The specified path will be prefixed by the specified root before beginning the iteration */ + CHASE_NONEXISTENT = 1 << 1, /* It's OK if the path doesn't actually exist. */ + CHASE_NO_AUTOFS = 1 << 2, /* Return -EREMOTE if autofs mount point found */ + CHASE_SAFE = 1 << 3, /* Return -EPERM if we ever traverse from unprivileged to privileged files or directories */ + CHASE_TRAIL_SLASH = 1 << 4, /* Any trailing slash will be preserved */ + CHASE_STEP = 1 << 5, /* Just execute a single step of the normalization */ + CHASE_NOFOLLOW = 1 << 6, /* Do not follow the path's right-most component. With ret_fd, when the path's + * right-most component refers to symlink, return O_PATH fd of the symlink. */ + CHASE_WARN = 1 << 7, /* Emit an appropriate warning when an error is encountered */ +}; + +/* How many iterations to execute before returning -ELOOP */ +#define CHASE_SYMLINKS_MAX 32 + +int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret_path, int *ret_fd); + +int chase_symlinks_and_open(const char *path, const char *root, unsigned chase_flags, int open_flags, char **ret_path); +int chase_symlinks_and_opendir(const char *path, const char *root, unsigned chase_flags, char **ret_path, DIR **ret_dir); +int chase_symlinks_and_stat(const char *path, const char *root, unsigned chase_flags, char **ret_path, struct stat *ret_stat, int *ret_fd); + +/* Useful for usage with _cleanup_(), removes a directory and frees the pointer */ +static inline void rmdir_and_free(char *p) { + PROTECT_ERRNO; + (void) rmdir(p); + free(p); +} +DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free); + +static inline void unlink_and_free(char *p) { + (void) unlink_noerrno(p); + free(p); +} +DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free); + +int access_fd(int fd, int mode); + +void unlink_tempfilep(char (*p)[]); + +typedef enum UnlinkDeallocateFlags { + UNLINK_REMOVEDIR = 1 << 0, + UNLINK_ERASE = 1 << 1, +} UnlinkDeallocateFlags; + +int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags); + +int fsync_directory_of_file(int fd); +int fsync_full(int fd); +int fsync_path_at(int at_fd, const char *path); + +int syncfs_path(int atfd, const char *path); + +int open_parent(const char *path, int flags, mode_t mode); + +int path_is_encrypted(const char *path); + +int conservative_rename(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); diff --git a/src/libnm-systemd-shared/src/basic/hash-funcs.c b/src/libnm-systemd-shared/src/basic/hash-funcs.c new file mode 100644 index 0000000..6f540b2 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/hash-funcs.c @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include + +#include "hash-funcs.h" +#include "path-util.h" + +void string_hash_func(const char *p, struct siphash *state) { + siphash24_compress(p, strlen(p) + 1, state); +} + +DEFINE_HASH_OPS(string_hash_ops, char, string_hash_func, string_compare_func); +DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(string_hash_ops_free, + char, string_hash_func, string_compare_func, free); +DEFINE_HASH_OPS_FULL(string_hash_ops_free_free, + char, string_hash_func, string_compare_func, free, + char, free); + +#if 0 /* NM_IGNORED */ +void path_hash_func(const char *q, struct siphash *state) { + size_t n; + + assert(q); + assert(state); + + /* Calculates a hash for a path in a way this duplicate inner slashes don't make a differences, and also + * whether there's a trailing slash or not. This fits well with the semantics of path_compare(), which does + * similar checks and also doesn't care for trailing slashes. Note that relative and absolute paths (i.e. those + * which begin in a slash or not) will hash differently though. */ + + n = strspn(q, "/"); + if (n > 0) { /* Eat up initial slashes, and add one "/" to the hash for all of them */ + siphash24_compress(q, 1, state); + q += n; + } + + for (;;) { + /* Determine length of next component */ + n = strcspn(q, "/"); + if (n == 0) /* Reached the end? */ + break; + + /* Add this component to the hash and skip over it */ + siphash24_compress(q, n, state); + q += n; + + /* How many slashes follow this component? */ + n = strspn(q, "/"); + if (q[n] == 0) /* Is this a trailing slash? If so, we are at the end, and don't care about the slashes anymore */ + break; + + /* We are not add the end yet. Hash exactly one slash for all of the ones we just encountered. */ + siphash24_compress(q, 1, state); + q += n; + } +} + +DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare); +DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(path_hash_ops_free, + char, path_hash_func, path_compare, free); +#endif /* NM_IGNORED */ + +void trivial_hash_func(const void *p, struct siphash *state) { + siphash24_compress(&p, sizeof(p), state); +} + +int trivial_compare_func(const void *a, const void *b) { + return CMP(a, b); +} + +const struct hash_ops trivial_hash_ops = { + .hash = trivial_hash_func, + .compare = trivial_compare_func, +}; + +const struct hash_ops trivial_hash_ops_free = { + .hash = trivial_hash_func, + .compare = trivial_compare_func, + .free_key = free, +}; + +const struct hash_ops trivial_hash_ops_free_free = { + .hash = trivial_hash_func, + .compare = trivial_compare_func, + .free_key = free, + .free_value = free, +}; + +void uint64_hash_func(const uint64_t *p, struct siphash *state) { + siphash24_compress(p, sizeof(uint64_t), state); +} + +int uint64_compare_func(const uint64_t *a, const uint64_t *b) { + return CMP(*a, *b); +} + +DEFINE_HASH_OPS(uint64_hash_ops, uint64_t, uint64_hash_func, uint64_compare_func); + +#if 0 /* NM_IGNORED */ +#if SIZEOF_DEV_T != 8 +void devt_hash_func(const dev_t *p, struct siphash *state) { + siphash24_compress(p, sizeof(dev_t), state); +} + +int devt_compare_func(const dev_t *a, const dev_t *b) { + return CMP(*a, *b); +} + +DEFINE_HASH_OPS(devt_hash_ops, dev_t, devt_hash_func, devt_compare_func); +#endif +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/hash-funcs.h b/src/libnm-systemd-shared/src/basic/hash-funcs.h new file mode 100644 index 0000000..5672df1 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/hash-funcs.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "alloc-util.h" +#include "macro.h" +#include "siphash24.h" + +typedef void (*hash_func_t)(const void *p, struct siphash *state); +typedef int (*compare_func_t)(const void *a, const void *b); + +struct hash_ops { + hash_func_t hash; + compare_func_t compare; + free_func_t free_key; + free_func_t free_value; +}; + +#define _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, free_key_func, free_value_func, scope) \ + _unused_ static void (* UNIQ_T(static_hash_wrapper, uq))(const type *, struct siphash *) = hash_func; \ + _unused_ static int (* UNIQ_T(static_compare_wrapper, uq))(const type *, const type *) = compare_func; \ + scope const struct hash_ops name = { \ + .hash = (hash_func_t) hash_func, \ + .compare = (compare_func_t) compare_func, \ + .free_key = free_key_func, \ + .free_value = free_value_func, \ + } + +#define _DEFINE_FREE_FUNC(uq, type, wrapper_name, func) \ + /* Type-safe free function */ \ + static void UNIQ_T(wrapper_name, uq)(void *a) { \ + type *_a = a; \ + func(_a); \ + } + +#define _DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(uq, name, type, hash_func, compare_func, free_func, scope) \ + _DEFINE_FREE_FUNC(uq, type, static_free_wrapper, free_func); \ + _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \ + UNIQ_T(static_free_wrapper, uq), NULL, scope) + +#define _DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(uq, name, type, hash_func, compare_func, type_value, free_func, scope) \ + _DEFINE_FREE_FUNC(uq, type_value, static_free_wrapper, free_func); \ + _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \ + NULL, UNIQ_T(static_free_wrapper, uq), scope) + +#define _DEFINE_HASH_OPS_FULL(uq, name, type, hash_func, compare_func, free_key_func, type_value, free_value_func, scope) \ + _DEFINE_FREE_FUNC(uq, type, static_free_key_wrapper, free_key_func); \ + _DEFINE_FREE_FUNC(uq, type_value, static_free_value_wrapper, free_value_func); \ + _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \ + UNIQ_T(static_free_key_wrapper, uq), \ + UNIQ_T(static_free_value_wrapper, uq), scope) + +#define DEFINE_HASH_OPS(name, type, hash_func, compare_func) \ + _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, NULL, NULL,) + +#define DEFINE_PRIVATE_HASH_OPS(name, type, hash_func, compare_func) \ + _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, NULL, NULL, static) + +#define DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(name, type, hash_func, compare_func, free_func) \ + _DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, free_func,) + +#define DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(name, type, hash_func, compare_func, free_func) \ + _DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, free_func, static) + +#define DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(name, type, hash_func, compare_func, value_type, free_func) \ + _DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, value_type, free_func,) + +#define DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(name, type, hash_func, compare_func, value_type, free_func) \ + _DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, value_type, free_func, static) + +#define DEFINE_HASH_OPS_FULL(name, type, hash_func, compare_func, free_key_func, value_type, free_value_func) \ + _DEFINE_HASH_OPS_FULL(UNIQ, name, type, hash_func, compare_func, free_key_func, value_type, free_value_func,) + +#define DEFINE_PRIVATE_HASH_OPS_FULL(name, type, hash_func, compare_func, free_key_func, value_type, free_value_func) \ + _DEFINE_HASH_OPS_FULL(UNIQ, name, type, hash_func, compare_func, free_key_func, value_type, free_value_func, static) + +void string_hash_func(const char *p, struct siphash *state); +#define string_compare_func strcmp +extern const struct hash_ops string_hash_ops; +extern const struct hash_ops string_hash_ops_free; +extern const struct hash_ops string_hash_ops_free_free; + +void path_hash_func(const char *p, struct siphash *state); +extern const struct hash_ops path_hash_ops; +extern const struct hash_ops path_hash_ops_free; + +/* This will compare the passed pointers directly, and will not dereference them. This is hence not useful for strings + * or suchlike. */ +void trivial_hash_func(const void *p, struct siphash *state); +int trivial_compare_func(const void *a, const void *b) _const_; +extern const struct hash_ops trivial_hash_ops; +extern const struct hash_ops trivial_hash_ops_free; +extern const struct hash_ops trivial_hash_ops_free_free; + +/* 32bit values we can always just embed in the pointer itself, but in order to support 32bit archs we need store 64bit + * values indirectly, since they don't fit in a pointer. */ +void uint64_hash_func(const uint64_t *p, struct siphash *state); +int uint64_compare_func(const uint64_t *a, const uint64_t *b) _pure_; +extern const struct hash_ops uint64_hash_ops; + +/* On some archs dev_t is 32bit, and on others 64bit. And sometimes it's 64bit on 32bit archs, and sometimes 32bit on + * 64bit archs. Yuck! */ +#if SIZEOF_DEV_T != 8 +void devt_hash_func(const dev_t *p, struct siphash *state) _pure_; +int devt_compare_func(const dev_t *a, const dev_t *b) _pure_; +extern const struct hash_ops devt_hash_ops; +#else +#define devt_hash_func uint64_hash_func +#define devt_compare_func uint64_compare_func +#define devt_hash_ops uint64_hash_ops +#endif diff --git a/src/libnm-systemd-shared/src/basic/hashmap.c b/src/libnm-systemd-shared/src/basic/hashmap.c new file mode 100644 index 0000000..0a5deab --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/hashmap.c @@ -0,0 +1,2032 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include + +#include "alloc-util.h" +#include "fileio.h" +#include "hashmap.h" +#include "macro.h" +#include "memory-util.h" +#include "mempool.h" +#include "missing_syscall.h" +#include "process-util.h" +#include "random-util.h" +#include "set.h" +#include "siphash24.h" +#include "string-util.h" +#include "strv.h" + +#if ENABLE_DEBUG_HASHMAP +#include "list.h" +#endif + +/* + * Implementation of hashmaps. + * Addressing: open + * - uses less RAM compared to closed addressing (chaining), because + * our entries are small (especially in Sets, which tend to contain + * the majority of entries in systemd). + * Collision resolution: Robin Hood + * - tends to equalize displacement of entries from their optimal buckets. + * Probe sequence: linear + * - though theoretically worse than random probing/uniform hashing/double + * hashing, it is good for cache locality. + * + * References: + * Celis, P. 1986. Robin Hood Hashing. + * Ph.D. Dissertation. University of Waterloo, Waterloo, Ont., Canada, Canada. + * https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf + * - The results are derived for random probing. Suggests deletion with + * tombstones and two mean-centered search methods. None of that works + * well for linear probing. + * + * Janson, S. 2005. Individual displacements for linear probing hashing with different insertion policies. + * ACM Trans. Algorithms 1, 2 (October 2005), 177-213. + * DOI=10.1145/1103963.1103964 http://doi.acm.org/10.1145/1103963.1103964 + * http://www.math.uu.se/~svante/papers/sj157.pdf + * - Applies to Robin Hood with linear probing. Contains remarks on + * the unsuitability of mean-centered search with linear probing. + * + * Viola, A. 2005. Exact distribution of individual displacements in linear probing hashing. + * ACM Trans. Algorithms 1, 2 (October 2005), 214-242. + * DOI=10.1145/1103963.1103965 http://doi.acm.org/10.1145/1103963.1103965 + * - Similar to Janson. Note that Viola writes about C_{m,n} (number of probes + * in a successful search), and Janson writes about displacement. C = d + 1. + * + * Goossaert, E. 2013. Robin Hood hashing: backward shift deletion. + * http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/ + * - Explanation of backward shift deletion with pictures. + * + * Khuong, P. 2013. The Other Robin Hood Hashing. + * http://www.pvk.ca/Blog/2013/11/26/the-other-robin-hood-hashing/ + * - Short summary of random vs. linear probing, and tombstones vs. backward shift. + */ + +/* + * XXX Ideas for improvement: + * For unordered hashmaps, randomize iteration order, similarly to Perl: + * http://blog.booking.com/hardening-perls-hash-function.html + */ + +/* INV_KEEP_FREE = 1 / (1 - max_load_factor) + * e.g. 1 / (1 - 0.8) = 5 ... keep one fifth of the buckets free. */ +#define INV_KEEP_FREE 5U + +/* Fields common to entries of all hashmap/set types */ +struct hashmap_base_entry { + const void *key; +}; + +/* Entry types for specific hashmap/set types + * hashmap_base_entry must be at the beginning of each entry struct. */ + +struct plain_hashmap_entry { + struct hashmap_base_entry b; + void *value; +}; + +struct ordered_hashmap_entry { + struct plain_hashmap_entry p; + unsigned iterate_next, iterate_previous; +}; + +struct set_entry { + struct hashmap_base_entry b; +}; + +/* In several functions it is advantageous to have the hash table extended + * virtually by a couple of additional buckets. We reserve special index values + * for these "swap" buckets. */ +#define _IDX_SWAP_BEGIN (UINT_MAX - 3) +#define IDX_PUT (_IDX_SWAP_BEGIN + 0) +#define IDX_TMP (_IDX_SWAP_BEGIN + 1) +#define _IDX_SWAP_END (_IDX_SWAP_BEGIN + 2) + +#define IDX_FIRST (UINT_MAX - 1) /* special index for freshly initialized iterators */ +#define IDX_NIL UINT_MAX /* special index value meaning "none" or "end" */ + +assert_cc(IDX_FIRST == _IDX_SWAP_END); +assert_cc(IDX_FIRST == _IDX_ITERATOR_FIRST); + +/* Storage space for the "swap" buckets. + * All entry types can fit into a ordered_hashmap_entry. */ +struct swap_entries { + struct ordered_hashmap_entry e[_IDX_SWAP_END - _IDX_SWAP_BEGIN]; +}; + +/* Distance from Initial Bucket */ +typedef uint8_t dib_raw_t; +#define DIB_RAW_OVERFLOW ((dib_raw_t)0xfdU) /* indicates DIB value is greater than representable */ +#define DIB_RAW_REHASH ((dib_raw_t)0xfeU) /* entry yet to be rehashed during in-place resize */ +#define DIB_RAW_FREE ((dib_raw_t)0xffU) /* a free bucket */ +#define DIB_RAW_INIT ((char)DIB_RAW_FREE) /* a byte to memset a DIB store with when initializing */ + +#define DIB_FREE UINT_MAX + +#if ENABLE_DEBUG_HASHMAP +struct hashmap_debug_info { + LIST_FIELDS(struct hashmap_debug_info, debug_list); + unsigned max_entries; /* high watermark of n_entries */ + + /* who allocated this hashmap */ + int line; + const char *file; + const char *func; + + /* fields to detect modification while iterating */ + unsigned put_count; /* counts puts into the hashmap */ + unsigned rem_count; /* counts removals from hashmap */ + unsigned last_rem_idx; /* remembers last removal index */ +}; + +/* Tracks all existing hashmaps. Get at it from gdb. See sd_dump_hashmaps.py */ +static LIST_HEAD(struct hashmap_debug_info, hashmap_debug_list); +static pthread_mutex_t hashmap_debug_list_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +enum HashmapType { + HASHMAP_TYPE_PLAIN, + HASHMAP_TYPE_ORDERED, + HASHMAP_TYPE_SET, + _HASHMAP_TYPE_MAX +}; + +struct _packed_ indirect_storage { + void *storage; /* where buckets and DIBs are stored */ + uint8_t hash_key[HASH_KEY_SIZE]; /* hash key; changes during resize */ + + unsigned n_entries; /* number of stored entries */ + unsigned n_buckets; /* number of buckets */ + + unsigned idx_lowest_entry; /* Index below which all buckets are free. + Makes "while(hashmap_steal_first())" loops + O(n) instead of O(n^2) for unordered hashmaps. */ + uint8_t _pad[3]; /* padding for the whole HashmapBase */ + /* The bitfields in HashmapBase complete the alignment of the whole thing. */ +}; + +struct direct_storage { + /* This gives us 39 bytes on 64bit, or 35 bytes on 32bit. + * That's room for 4 set_entries + 4 DIB bytes + 3 unused bytes on 64bit, + * or 7 set_entries + 7 DIB bytes + 0 unused bytes on 32bit. */ + uint8_t storage[sizeof(struct indirect_storage)]; +}; + +#define DIRECT_BUCKETS(entry_t) \ + (sizeof(struct direct_storage) / (sizeof(entry_t) + sizeof(dib_raw_t))) + +/* We should be able to store at least one entry directly. */ +assert_cc(DIRECT_BUCKETS(struct ordered_hashmap_entry) >= 1); + +/* We have 3 bits for n_direct_entries. */ +assert_cc(DIRECT_BUCKETS(struct set_entry) < (1 << 3)); + +/* Hashmaps with directly stored entries all use this shared hash key. + * It's no big deal if the key is guessed, because there can be only + * a handful of directly stored entries in a hashmap. When a hashmap + * outgrows direct storage, it gets its own key for indirect storage. */ +static uint8_t shared_hash_key[HASH_KEY_SIZE]; + +/* Fields that all hashmap/set types must have */ +struct HashmapBase { + const struct hash_ops *hash_ops; /* hash and compare ops to use */ + + union _packed_ { + struct indirect_storage indirect; /* if has_indirect */ + struct direct_storage direct; /* if !has_indirect */ + }; + + enum HashmapType type:2; /* HASHMAP_TYPE_* */ + bool has_indirect:1; /* whether indirect storage is used */ + unsigned n_direct_entries:3; /* Number of entries in direct storage. + * Only valid if !has_indirect. */ + bool from_pool:1; /* whether was allocated from mempool */ + bool dirty:1; /* whether dirtied since last iterated_cache_get() */ + bool cached:1; /* whether this hashmap is being cached */ + +#if ENABLE_DEBUG_HASHMAP + struct hashmap_debug_info debug; +#endif +}; + +/* Specific hash types + * HashmapBase must be at the beginning of each hashmap struct. */ + +struct Hashmap { + struct HashmapBase b; +}; + +struct OrderedHashmap { + struct HashmapBase b; + unsigned iterate_list_head, iterate_list_tail; +}; + +struct Set { + struct HashmapBase b; +}; + +typedef struct CacheMem { + const void **ptr; + size_t n_populated, n_allocated; + bool active:1; +} CacheMem; + +struct IteratedCache { + HashmapBase *hashmap; + CacheMem keys, values; +}; + +DEFINE_MEMPOOL(hashmap_pool, Hashmap, 8); +DEFINE_MEMPOOL(ordered_hashmap_pool, OrderedHashmap, 8); +/* No need for a separate Set pool */ +assert_cc(sizeof(Hashmap) == sizeof(Set)); + +struct hashmap_type_info { + size_t head_size; + size_t entry_size; + struct mempool *mempool; + unsigned n_direct_buckets; +}; + +static _used_ const struct hashmap_type_info hashmap_type_info[_HASHMAP_TYPE_MAX] = { + [HASHMAP_TYPE_PLAIN] = { + .head_size = sizeof(Hashmap), + .entry_size = sizeof(struct plain_hashmap_entry), + .mempool = &hashmap_pool, + .n_direct_buckets = DIRECT_BUCKETS(struct plain_hashmap_entry), + }, + [HASHMAP_TYPE_ORDERED] = { + .head_size = sizeof(OrderedHashmap), + .entry_size = sizeof(struct ordered_hashmap_entry), + .mempool = &ordered_hashmap_pool, + .n_direct_buckets = DIRECT_BUCKETS(struct ordered_hashmap_entry), + }, + [HASHMAP_TYPE_SET] = { + .head_size = sizeof(Set), + .entry_size = sizeof(struct set_entry), + .mempool = &hashmap_pool, + .n_direct_buckets = DIRECT_BUCKETS(struct set_entry), + }, +}; + +#if VALGRIND +_destructor_ static void cleanup_pools(void) { + _cleanup_free_ char *t = NULL; + int r; + + /* Be nice to valgrind */ + + /* The pool is only allocated by the main thread, but the memory can + * be passed to other threads. Let's clean up if we are the main thread + * and no other threads are live. */ + /* We build our own is_main_thread() here, which doesn't use C11 + * TLS based caching of the result. That's because valgrind apparently + * doesn't like malloc() (which C11 TLS internally uses) to be called + * from a GCC destructors. */ + if (getpid() != gettid()) + return; + + r = get_proc_field("/proc/self/status", "Threads", WHITESPACE, &t); + if (r < 0 || !streq(t, "1")) + return; + + mempool_drop(&hashmap_pool); + mempool_drop(&ordered_hashmap_pool); +} +#endif + +static unsigned n_buckets(HashmapBase *h) { + return h->has_indirect ? h->indirect.n_buckets + : hashmap_type_info[h->type].n_direct_buckets; +} + +static unsigned n_entries(HashmapBase *h) { + return h->has_indirect ? h->indirect.n_entries + : h->n_direct_entries; +} + +static void n_entries_inc(HashmapBase *h) { + if (h->has_indirect) + h->indirect.n_entries++; + else + h->n_direct_entries++; +} + +static void n_entries_dec(HashmapBase *h) { + if (h->has_indirect) + h->indirect.n_entries--; + else + h->n_direct_entries--; +} + +static void* storage_ptr(HashmapBase *h) { + return h->has_indirect ? h->indirect.storage + : h->direct.storage; +} + +static uint8_t* hash_key(HashmapBase *h) { + return h->has_indirect ? h->indirect.hash_key + : shared_hash_key; +} + +static unsigned base_bucket_hash(HashmapBase *h, const void *p) { + struct siphash state; + uint64_t hash; + + siphash24_init(&state, hash_key(h)); + + h->hash_ops->hash(p, &state); + + hash = siphash24_finalize(&state); + + return (unsigned) (hash % n_buckets(h)); +} +#define bucket_hash(h, p) base_bucket_hash(HASHMAP_BASE(h), p) + +static void base_set_dirty(HashmapBase *h) { + h->dirty = true; +} +#define hashmap_set_dirty(h) base_set_dirty(HASHMAP_BASE(h)) + +static void get_hash_key(uint8_t hash_key[HASH_KEY_SIZE], bool reuse_is_ok) { + static uint8_t current[HASH_KEY_SIZE]; + static bool current_initialized = false; + + /* Returns a hash function key to use. In order to keep things + * fast we will not generate a new key each time we allocate a + * new hash table. Instead, we'll just reuse the most recently + * generated one, except if we never generated one or when we + * are rehashing an entire hash table because we reached a + * fill level */ + + if (!current_initialized || !reuse_is_ok) { + random_bytes(current, sizeof(current)); + current_initialized = true; + } + + memcpy(hash_key, current, sizeof(current)); +} + +static struct hashmap_base_entry* bucket_at(HashmapBase *h, unsigned idx) { + return (struct hashmap_base_entry*) + ((uint8_t*) storage_ptr(h) + idx * hashmap_type_info[h->type].entry_size); +} + +static struct plain_hashmap_entry* plain_bucket_at(Hashmap *h, unsigned idx) { + return (struct plain_hashmap_entry*) bucket_at(HASHMAP_BASE(h), idx); +} + +static struct ordered_hashmap_entry* ordered_bucket_at(OrderedHashmap *h, unsigned idx) { + return (struct ordered_hashmap_entry*) bucket_at(HASHMAP_BASE(h), idx); +} + +static struct set_entry *set_bucket_at(Set *h, unsigned idx) { + return (struct set_entry*) bucket_at(HASHMAP_BASE(h), idx); +} + +static struct ordered_hashmap_entry* bucket_at_swap(struct swap_entries *swap, unsigned idx) { + return &swap->e[idx - _IDX_SWAP_BEGIN]; +} + +/* Returns a pointer to the bucket at index idx. + * Understands real indexes and swap indexes, hence "_virtual". */ +static struct hashmap_base_entry* bucket_at_virtual(HashmapBase *h, struct swap_entries *swap, + unsigned idx) { + if (idx < _IDX_SWAP_BEGIN) + return bucket_at(h, idx); + + if (idx < _IDX_SWAP_END) + return &bucket_at_swap(swap, idx)->p.b; + + assert_not_reached("Invalid index"); +} + +static dib_raw_t* dib_raw_ptr(HashmapBase *h) { + return (dib_raw_t*) + ((uint8_t*) storage_ptr(h) + hashmap_type_info[h->type].entry_size * n_buckets(h)); +} + +static unsigned bucket_distance(HashmapBase *h, unsigned idx, unsigned from) { + return idx >= from ? idx - from + : n_buckets(h) + idx - from; +} + +static unsigned bucket_calculate_dib(HashmapBase *h, unsigned idx, dib_raw_t raw_dib) { + unsigned initial_bucket; + + if (raw_dib == DIB_RAW_FREE) + return DIB_FREE; + + if (_likely_(raw_dib < DIB_RAW_OVERFLOW)) + return raw_dib; + + /* + * Having an overflow DIB value is very unlikely. The hash function + * would have to be bad. For example, in a table of size 2^24 filled + * to load factor 0.9 the maximum observed DIB is only about 60. + * In theory (assuming I used Maxima correctly), for an infinite size + * hash table with load factor 0.8 the probability of a given entry + * having DIB > 40 is 1.9e-8. + * This returns the correct DIB value by recomputing the hash value in + * the unlikely case. XXX Hitting this case could be a hint to rehash. + */ + initial_bucket = bucket_hash(h, bucket_at(h, idx)->key); + return bucket_distance(h, idx, initial_bucket); +} + +static void bucket_set_dib(HashmapBase *h, unsigned idx, unsigned dib) { + dib_raw_ptr(h)[idx] = dib != DIB_FREE ? MIN(dib, DIB_RAW_OVERFLOW) : DIB_RAW_FREE; +} + +static unsigned skip_free_buckets(HashmapBase *h, unsigned idx) { + dib_raw_t *dibs; + + dibs = dib_raw_ptr(h); + + for ( ; idx < n_buckets(h); idx++) + if (dibs[idx] != DIB_RAW_FREE) + return idx; + + return IDX_NIL; +} + +static void bucket_mark_free(HashmapBase *h, unsigned idx) { + memzero(bucket_at(h, idx), hashmap_type_info[h->type].entry_size); + bucket_set_dib(h, idx, DIB_FREE); +} + +static void bucket_move_entry(HashmapBase *h, struct swap_entries *swap, + unsigned from, unsigned to) { + struct hashmap_base_entry *e_from, *e_to; + + assert(from != to); + + e_from = bucket_at_virtual(h, swap, from); + e_to = bucket_at_virtual(h, swap, to); + + memcpy(e_to, e_from, hashmap_type_info[h->type].entry_size); + + if (h->type == HASHMAP_TYPE_ORDERED) { + OrderedHashmap *lh = (OrderedHashmap*) h; + struct ordered_hashmap_entry *le, *le_to; + + le_to = (struct ordered_hashmap_entry*) e_to; + + if (le_to->iterate_next != IDX_NIL) { + le = (struct ordered_hashmap_entry*) + bucket_at_virtual(h, swap, le_to->iterate_next); + le->iterate_previous = to; + } + + if (le_to->iterate_previous != IDX_NIL) { + le = (struct ordered_hashmap_entry*) + bucket_at_virtual(h, swap, le_to->iterate_previous); + le->iterate_next = to; + } + + if (lh->iterate_list_head == from) + lh->iterate_list_head = to; + if (lh->iterate_list_tail == from) + lh->iterate_list_tail = to; + } +} + +static unsigned next_idx(HashmapBase *h, unsigned idx) { + return (idx + 1U) % n_buckets(h); +} + +static unsigned prev_idx(HashmapBase *h, unsigned idx) { + return (n_buckets(h) + idx - 1U) % n_buckets(h); +} + +static void* entry_value(HashmapBase *h, struct hashmap_base_entry *e) { + switch (h->type) { + + case HASHMAP_TYPE_PLAIN: + case HASHMAP_TYPE_ORDERED: + return ((struct plain_hashmap_entry*)e)->value; + + case HASHMAP_TYPE_SET: + return (void*) e->key; + + default: + assert_not_reached("Unknown hashmap type"); + } +} + +static void base_remove_entry(HashmapBase *h, unsigned idx) { + unsigned left, right, prev, dib; + dib_raw_t raw_dib, *dibs; + + dibs = dib_raw_ptr(h); + assert(dibs[idx] != DIB_RAW_FREE); + +#if ENABLE_DEBUG_HASHMAP + h->debug.rem_count++; + h->debug.last_rem_idx = idx; +#endif + + left = idx; + /* Find the stop bucket ("right"). It is either free or has DIB == 0. */ + for (right = next_idx(h, left); ; right = next_idx(h, right)) { + raw_dib = dibs[right]; + if (IN_SET(raw_dib, 0, DIB_RAW_FREE)) + break; + + /* The buckets are not supposed to be all occupied and with DIB > 0. + * That would mean we could make everyone better off by shifting them + * backward. This scenario is impossible. */ + assert(left != right); + } + + if (h->type == HASHMAP_TYPE_ORDERED) { + OrderedHashmap *lh = (OrderedHashmap*) h; + struct ordered_hashmap_entry *le = ordered_bucket_at(lh, idx); + + if (le->iterate_next != IDX_NIL) + ordered_bucket_at(lh, le->iterate_next)->iterate_previous = le->iterate_previous; + else + lh->iterate_list_tail = le->iterate_previous; + + if (le->iterate_previous != IDX_NIL) + ordered_bucket_at(lh, le->iterate_previous)->iterate_next = le->iterate_next; + else + lh->iterate_list_head = le->iterate_next; + } + + /* Now shift all buckets in the interval (left, right) one step backwards */ + for (prev = left, left = next_idx(h, left); left != right; + prev = left, left = next_idx(h, left)) { + dib = bucket_calculate_dib(h, left, dibs[left]); + assert(dib != 0); + bucket_move_entry(h, NULL, left, prev); + bucket_set_dib(h, prev, dib - 1); + } + + bucket_mark_free(h, prev); + n_entries_dec(h); + base_set_dirty(h); +} +#define remove_entry(h, idx) base_remove_entry(HASHMAP_BASE(h), idx) + +static unsigned hashmap_iterate_in_insertion_order(OrderedHashmap *h, Iterator *i) { + struct ordered_hashmap_entry *e; + unsigned idx; + + assert(h); + assert(i); + + if (i->idx == IDX_NIL) + goto at_end; + + if (i->idx == IDX_FIRST && h->iterate_list_head == IDX_NIL) + goto at_end; + + if (i->idx == IDX_FIRST) { + idx = h->iterate_list_head; + e = ordered_bucket_at(h, idx); + } else { + idx = i->idx; + e = ordered_bucket_at(h, idx); + /* + * We allow removing the current entry while iterating, but removal may cause + * a backward shift. The next entry may thus move one bucket to the left. + * To detect when it happens, we remember the key pointer of the entry we were + * going to iterate next. If it does not match, there was a backward shift. + */ + if (e->p.b.key != i->next_key) { + idx = prev_idx(HASHMAP_BASE(h), idx); + e = ordered_bucket_at(h, idx); + } + assert(e->p.b.key == i->next_key); + } + +#if ENABLE_DEBUG_HASHMAP + i->prev_idx = idx; +#endif + + if (e->iterate_next != IDX_NIL) { + struct ordered_hashmap_entry *n; + i->idx = e->iterate_next; + n = ordered_bucket_at(h, i->idx); + i->next_key = n->p.b.key; + } else + i->idx = IDX_NIL; + + return idx; + +at_end: + i->idx = IDX_NIL; + return IDX_NIL; +} + +static unsigned hashmap_iterate_in_internal_order(HashmapBase *h, Iterator *i) { + unsigned idx; + + assert(h); + assert(i); + + if (i->idx == IDX_NIL) + goto at_end; + + if (i->idx == IDX_FIRST) { + /* fast forward to the first occupied bucket */ + if (h->has_indirect) { + i->idx = skip_free_buckets(h, h->indirect.idx_lowest_entry); + h->indirect.idx_lowest_entry = i->idx; + } else + i->idx = skip_free_buckets(h, 0); + + if (i->idx == IDX_NIL) + goto at_end; + } else { + struct hashmap_base_entry *e; + + assert(i->idx > 0); + + e = bucket_at(h, i->idx); + /* + * We allow removing the current entry while iterating, but removal may cause + * a backward shift. The next entry may thus move one bucket to the left. + * To detect when it happens, we remember the key pointer of the entry we were + * going to iterate next. If it does not match, there was a backward shift. + */ + if (e->key != i->next_key) + e = bucket_at(h, --i->idx); + + assert(e->key == i->next_key); + } + + idx = i->idx; +#if ENABLE_DEBUG_HASHMAP + i->prev_idx = idx; +#endif + + i->idx = skip_free_buckets(h, i->idx + 1); + if (i->idx != IDX_NIL) + i->next_key = bucket_at(h, i->idx)->key; + else + i->idx = IDX_NIL; + + return idx; + +at_end: + i->idx = IDX_NIL; + return IDX_NIL; +} + +static unsigned hashmap_iterate_entry(HashmapBase *h, Iterator *i) { + if (!h) { + i->idx = IDX_NIL; + return IDX_NIL; + } + +#if ENABLE_DEBUG_HASHMAP + if (i->idx == IDX_FIRST) { + i->put_count = h->debug.put_count; + i->rem_count = h->debug.rem_count; + } else { + /* While iterating, must not add any new entries */ + assert(i->put_count == h->debug.put_count); + /* ... or remove entries other than the current one */ + assert(i->rem_count == h->debug.rem_count || + (i->rem_count == h->debug.rem_count - 1 && + i->prev_idx == h->debug.last_rem_idx)); + /* Reset our removals counter */ + i->rem_count = h->debug.rem_count; + } +#endif + + return h->type == HASHMAP_TYPE_ORDERED ? hashmap_iterate_in_insertion_order((OrderedHashmap*) h, i) + : hashmap_iterate_in_internal_order(h, i); +} + +bool _hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key) { + struct hashmap_base_entry *e; + void *data; + unsigned idx; + + idx = hashmap_iterate_entry(h, i); + if (idx == IDX_NIL) { + if (value) + *value = NULL; + if (key) + *key = NULL; + + return false; + } + + e = bucket_at(h, idx); + data = entry_value(h, e); + if (value) + *value = data; + if (key) + *key = e->key; + + return true; +} + +#define HASHMAP_FOREACH_IDX(idx, h, i) \ + for ((i) = ITERATOR_FIRST, (idx) = hashmap_iterate_entry((h), &(i)); \ + (idx != IDX_NIL); \ + (idx) = hashmap_iterate_entry((h), &(i))) + +IteratedCache* _hashmap_iterated_cache_new(HashmapBase *h) { + IteratedCache *cache; + + assert(h); + assert(!h->cached); + + if (h->cached) + return NULL; + + cache = new0(IteratedCache, 1); + if (!cache) + return NULL; + + cache->hashmap = h; + h->cached = true; + + return cache; +} + +static void reset_direct_storage(HashmapBase *h) { + const struct hashmap_type_info *hi = &hashmap_type_info[h->type]; + void *p; + + assert(!h->has_indirect); + + p = mempset(h->direct.storage, 0, hi->entry_size * hi->n_direct_buckets); + memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets); +} + +static void shared_hash_key_initialize(void) { + random_bytes(shared_hash_key, sizeof(shared_hash_key)); +} + +static struct HashmapBase* hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) { + HashmapBase *h; + const struct hashmap_type_info *hi = &hashmap_type_info[type]; + bool up; + + up = mempool_enabled(); + + h = up ? mempool_alloc0_tile(hi->mempool) : malloc0(hi->head_size); + if (!h) + return NULL; + + h->type = type; + h->from_pool = up; + h->hash_ops = hash_ops ?: &trivial_hash_ops; + + if (type == HASHMAP_TYPE_ORDERED) { + OrderedHashmap *lh = (OrderedHashmap*)h; + lh->iterate_list_head = lh->iterate_list_tail = IDX_NIL; + } + + reset_direct_storage(h); + + static pthread_once_t once = PTHREAD_ONCE_INIT; + assert_se(pthread_once(&once, shared_hash_key_initialize) == 0); + +#if ENABLE_DEBUG_HASHMAP + h->debug.func = func; + h->debug.file = file; + h->debug.line = line; + assert_se(pthread_mutex_lock(&hashmap_debug_list_mutex) == 0); + LIST_PREPEND(debug_list, hashmap_debug_list, &h->debug); + assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0); +#endif + + return h; +} + +Hashmap *_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) { + return (Hashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS); +} + +OrderedHashmap *_ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) { + return (OrderedHashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS); +} + +Set *_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) { + return (Set*) hashmap_base_new(hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS); +} + +static int hashmap_base_ensure_allocated(HashmapBase **h, const struct hash_ops *hash_ops, + enum HashmapType type HASHMAP_DEBUG_PARAMS) { + HashmapBase *q; + + assert(h); + + if (*h) + return 0; + + q = hashmap_base_new(hash_ops, type HASHMAP_DEBUG_PASS_ARGS); + if (!q) + return -ENOMEM; + + *h = q; + return 1; +} + +int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) { + return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS); +} + +int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) { + return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS); +} + +int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) { + return hashmap_base_ensure_allocated((HashmapBase**)s, hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS); +} + +int _ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS) { + int r; + + r = _ordered_hashmap_ensure_allocated(h, hash_ops HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + return ordered_hashmap_put(*h, key, value); +} + +static void hashmap_free_no_clear(HashmapBase *h) { + assert(!h->has_indirect); + assert(h->n_direct_entries == 0); + +#if ENABLE_DEBUG_HASHMAP + assert_se(pthread_mutex_lock(&hashmap_debug_list_mutex) == 0); + LIST_REMOVE(debug_list, hashmap_debug_list, &h->debug); + assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0); +#endif + + if (h->from_pool) { + /* Ensure that the object didn't get migrated between threads. */ + assert_se(is_main_thread()); + mempool_free_tile(hashmap_type_info[h->type].mempool, h); + } else + free(h); +} + +HashmapBase* _hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) { + if (h) { + _hashmap_clear(h, default_free_key, default_free_value); + hashmap_free_no_clear(h); + } + + return NULL; +} + +void _hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) { + free_func_t free_key, free_value; + if (!h) + return; + + free_key = h->hash_ops->free_key ?: default_free_key; + free_value = h->hash_ops->free_value ?: default_free_value; + + if (free_key || free_value) { + + /* If destructor calls are defined, let's destroy things defensively: let's take the item out of the + * hash table, and only then call the destructor functions. If these destructors then try to unregister + * themselves from our hash table a second time, the entry is already gone. */ + + while (_hashmap_size(h) > 0) { + void *k = NULL; + void *v; + + v = _hashmap_first_key_and_value(h, true, &k); + + if (free_key) + free_key(k); + + if (free_value) + free_value(v); + } + } + + if (h->has_indirect) { + free(h->indirect.storage); + h->has_indirect = false; + } + + h->n_direct_entries = 0; + reset_direct_storage(h); + + if (h->type == HASHMAP_TYPE_ORDERED) { + OrderedHashmap *lh = (OrderedHashmap*) h; + lh->iterate_list_head = lh->iterate_list_tail = IDX_NIL; + } + + base_set_dirty(h); +} + +static int resize_buckets(HashmapBase *h, unsigned entries_add); + +/* + * Finds an empty bucket to put an entry into, starting the scan at 'idx'. + * Performs Robin Hood swaps as it goes. The entry to put must be placed + * by the caller into swap slot IDX_PUT. + * If used for in-place resizing, may leave a displaced entry in swap slot + * IDX_PUT. Caller must rehash it next. + * Returns: true if it left a displaced entry to rehash next in IDX_PUT, + * false otherwise. + */ +static bool hashmap_put_robin_hood(HashmapBase *h, unsigned idx, + struct swap_entries *swap) { + dib_raw_t raw_dib, *dibs; + unsigned dib, distance; + +#if ENABLE_DEBUG_HASHMAP + h->debug.put_count++; +#endif + + dibs = dib_raw_ptr(h); + + for (distance = 0; ; distance++) { + raw_dib = dibs[idx]; + if (IN_SET(raw_dib, DIB_RAW_FREE, DIB_RAW_REHASH)) { + if (raw_dib == DIB_RAW_REHASH) + bucket_move_entry(h, swap, idx, IDX_TMP); + + if (h->has_indirect && h->indirect.idx_lowest_entry > idx) + h->indirect.idx_lowest_entry = idx; + + bucket_set_dib(h, idx, distance); + bucket_move_entry(h, swap, IDX_PUT, idx); + if (raw_dib == DIB_RAW_REHASH) { + bucket_move_entry(h, swap, IDX_TMP, IDX_PUT); + return true; + } + + return false; + } + + dib = bucket_calculate_dib(h, idx, raw_dib); + + if (dib < distance) { + /* Found a wealthier entry. Go Robin Hood! */ + bucket_set_dib(h, idx, distance); + + /* swap the entries */ + bucket_move_entry(h, swap, idx, IDX_TMP); + bucket_move_entry(h, swap, IDX_PUT, idx); + bucket_move_entry(h, swap, IDX_TMP, IDX_PUT); + + distance = dib; + } + + idx = next_idx(h, idx); + } +} + +/* + * Puts an entry into a hashmap, boldly - no check whether key already exists. + * The caller must place the entry (only its key and value, not link indexes) + * in swap slot IDX_PUT. + * Caller must ensure: the key does not exist yet in the hashmap. + * that resize is not needed if !may_resize. + * Returns: 1 if entry was put successfully. + * -ENOMEM if may_resize==true and resize failed with -ENOMEM. + * Cannot return -ENOMEM if !may_resize. + */ +static int hashmap_base_put_boldly(HashmapBase *h, unsigned idx, + struct swap_entries *swap, bool may_resize) { + struct ordered_hashmap_entry *new_entry; + int r; + + assert(idx < n_buckets(h)); + + new_entry = bucket_at_swap(swap, IDX_PUT); + + if (may_resize) { + r = resize_buckets(h, 1); + if (r < 0) + return r; + if (r > 0) + idx = bucket_hash(h, new_entry->p.b.key); + } + assert(n_entries(h) < n_buckets(h)); + + if (h->type == HASHMAP_TYPE_ORDERED) { + OrderedHashmap *lh = (OrderedHashmap*) h; + + new_entry->iterate_next = IDX_NIL; + new_entry->iterate_previous = lh->iterate_list_tail; + + if (lh->iterate_list_tail != IDX_NIL) { + struct ordered_hashmap_entry *old_tail; + + old_tail = ordered_bucket_at(lh, lh->iterate_list_tail); + assert(old_tail->iterate_next == IDX_NIL); + old_tail->iterate_next = IDX_PUT; + } + + lh->iterate_list_tail = IDX_PUT; + if (lh->iterate_list_head == IDX_NIL) + lh->iterate_list_head = IDX_PUT; + } + + assert_se(hashmap_put_robin_hood(h, idx, swap) == false); + + n_entries_inc(h); +#if ENABLE_DEBUG_HASHMAP + h->debug.max_entries = MAX(h->debug.max_entries, n_entries(h)); +#endif + + base_set_dirty(h); + + return 1; +} +#define hashmap_put_boldly(h, idx, swap, may_resize) \ + hashmap_base_put_boldly(HASHMAP_BASE(h), idx, swap, may_resize) + +/* + * Returns 0 if resize is not needed. + * 1 if successfully resized. + * -ENOMEM on allocation failure. + */ +static int resize_buckets(HashmapBase *h, unsigned entries_add) { + struct swap_entries swap; + void *new_storage; + dib_raw_t *old_dibs, *new_dibs; + const struct hashmap_type_info *hi; + unsigned idx, optimal_idx; + unsigned old_n_buckets, new_n_buckets, n_rehashed, new_n_entries; + uint8_t new_shift; + bool rehash_next; + + assert(h); + + hi = &hashmap_type_info[h->type]; + new_n_entries = n_entries(h) + entries_add; + + /* overflow? */ + if (_unlikely_(new_n_entries < entries_add)) + return -ENOMEM; + + /* For direct storage we allow 100% load, because it's tiny. */ + if (!h->has_indirect && new_n_entries <= hi->n_direct_buckets) + return 0; + + /* + * Load factor = n/m = 1 - (1/INV_KEEP_FREE). + * From it follows: m = n + n/(INV_KEEP_FREE - 1) + */ + new_n_buckets = new_n_entries + new_n_entries / (INV_KEEP_FREE - 1); + /* overflow? */ + if (_unlikely_(new_n_buckets < new_n_entries)) + return -ENOMEM; + + if (_unlikely_(new_n_buckets > UINT_MAX / (hi->entry_size + sizeof(dib_raw_t)))) + return -ENOMEM; + + old_n_buckets = n_buckets(h); + + if (_likely_(new_n_buckets <= old_n_buckets)) + return 0; + + new_shift = log2u_round_up(MAX( + new_n_buckets * (hi->entry_size + sizeof(dib_raw_t)), + 2 * sizeof(struct direct_storage))); + + /* Realloc storage (buckets and DIB array). */ + new_storage = realloc(h->has_indirect ? h->indirect.storage : NULL, + 1U << new_shift); + if (!new_storage) + return -ENOMEM; + + /* Must upgrade direct to indirect storage. */ + if (!h->has_indirect) { + memcpy(new_storage, h->direct.storage, + old_n_buckets * (hi->entry_size + sizeof(dib_raw_t))); + h->indirect.n_entries = h->n_direct_entries; + h->indirect.idx_lowest_entry = 0; + h->n_direct_entries = 0; + } + + /* Get a new hash key. If we've just upgraded to indirect storage, + * allow reusing a previously generated key. It's still a different key + * from the shared one that we used for direct storage. */ + get_hash_key(h->indirect.hash_key, !h->has_indirect); + + h->has_indirect = true; + h->indirect.storage = new_storage; + h->indirect.n_buckets = (1U << new_shift) / + (hi->entry_size + sizeof(dib_raw_t)); + + old_dibs = (dib_raw_t*)((uint8_t*) new_storage + hi->entry_size * old_n_buckets); + new_dibs = dib_raw_ptr(h); + + /* + * Move the DIB array to the new place, replacing valid DIB values with + * DIB_RAW_REHASH to indicate all of the used buckets need rehashing. + * Note: Overlap is not possible, because we have at least doubled the + * number of buckets and dib_raw_t is smaller than any entry type. + */ + for (idx = 0; idx < old_n_buckets; idx++) { + assert(old_dibs[idx] != DIB_RAW_REHASH); + new_dibs[idx] = old_dibs[idx] == DIB_RAW_FREE ? DIB_RAW_FREE + : DIB_RAW_REHASH; + } + + /* Zero the area of newly added entries (including the old DIB area) */ + memzero(bucket_at(h, old_n_buckets), + (n_buckets(h) - old_n_buckets) * hi->entry_size); + + /* The upper half of the new DIB array needs initialization */ + memset(&new_dibs[old_n_buckets], DIB_RAW_INIT, + (n_buckets(h) - old_n_buckets) * sizeof(dib_raw_t)); + + /* Rehash entries that need it */ + n_rehashed = 0; + for (idx = 0; idx < old_n_buckets; idx++) { + if (new_dibs[idx] != DIB_RAW_REHASH) + continue; + + optimal_idx = bucket_hash(h, bucket_at(h, idx)->key); + + /* + * Not much to do if by luck the entry hashes to its current + * location. Just set its DIB. + */ + if (optimal_idx == idx) { + new_dibs[idx] = 0; + n_rehashed++; + continue; + } + + new_dibs[idx] = DIB_RAW_FREE; + bucket_move_entry(h, &swap, idx, IDX_PUT); + /* bucket_move_entry does not clear the source */ + memzero(bucket_at(h, idx), hi->entry_size); + + do { + /* + * Find the new bucket for the current entry. This may make + * another entry homeless and load it into IDX_PUT. + */ + rehash_next = hashmap_put_robin_hood(h, optimal_idx, &swap); + n_rehashed++; + + /* Did the current entry displace another one? */ + if (rehash_next) + optimal_idx = bucket_hash(h, bucket_at_swap(&swap, IDX_PUT)->p.b.key); + } while (rehash_next); + } + + assert(n_rehashed == n_entries(h)); + + return 1; +} + +/* + * Finds an entry with a matching key + * Returns: index of the found entry, or IDX_NIL if not found. + */ +static unsigned base_bucket_scan(HashmapBase *h, unsigned idx, const void *key) { + struct hashmap_base_entry *e; + unsigned dib, distance; + dib_raw_t *dibs = dib_raw_ptr(h); + + assert(idx < n_buckets(h)); + + for (distance = 0; ; distance++) { + if (dibs[idx] == DIB_RAW_FREE) + return IDX_NIL; + + dib = bucket_calculate_dib(h, idx, dibs[idx]); + + if (dib < distance) + return IDX_NIL; + if (dib == distance) { + e = bucket_at(h, idx); + if (h->hash_ops->compare(e->key, key) == 0) + return idx; + } + + idx = next_idx(h, idx); + } +} +#define bucket_scan(h, idx, key) base_bucket_scan(HASHMAP_BASE(h), idx, key) + +int hashmap_put(Hashmap *h, const void *key, void *value) { + struct swap_entries swap; + struct plain_hashmap_entry *e; + unsigned hash, idx; + + assert(h); + + hash = bucket_hash(h, key); + idx = bucket_scan(h, hash, key); + if (idx != IDX_NIL) { + e = plain_bucket_at(h, idx); + if (e->value == value) + return 0; + return -EEXIST; + } + + e = &bucket_at_swap(&swap, IDX_PUT)->p; + e->b.key = key; + e->value = value; + return hashmap_put_boldly(h, hash, &swap, true); +} + +int set_put(Set *s, const void *key) { + struct swap_entries swap; + struct hashmap_base_entry *e; + unsigned hash, idx; + + assert(s); + + hash = bucket_hash(s, key); + idx = bucket_scan(s, hash, key); + if (idx != IDX_NIL) + return 0; + + e = &bucket_at_swap(&swap, IDX_PUT)->p.b; + e->key = key; + return hashmap_put_boldly(s, hash, &swap, true); +} + +int _set_ensure_put(Set **s, const struct hash_ops *hash_ops, const void *key HASHMAP_DEBUG_PARAMS) { + int r; + + r = _set_ensure_allocated(s, hash_ops HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + return set_put(*s, key); +} + +int _set_ensure_consume(Set **s, const struct hash_ops *hash_ops, void *key HASHMAP_DEBUG_PARAMS) { + int r; + + r = _set_ensure_put(s, hash_ops, key HASHMAP_DEBUG_PASS_ARGS); + if (r <= 0) { + if (hash_ops && hash_ops->free_key) + hash_ops->free_key(key); + else + free(key); + } + + return r; +} + +int hashmap_replace(Hashmap *h, const void *key, void *value) { + struct swap_entries swap; + struct plain_hashmap_entry *e; + unsigned hash, idx; + + assert(h); + + hash = bucket_hash(h, key); + idx = bucket_scan(h, hash, key); + if (idx != IDX_NIL) { + e = plain_bucket_at(h, idx); +#if ENABLE_DEBUG_HASHMAP + /* Although the key is equal, the key pointer may have changed, + * and this would break our assumption for iterating. So count + * this operation as incompatible with iteration. */ + if (e->b.key != key) { + h->b.debug.put_count++; + h->b.debug.rem_count++; + h->b.debug.last_rem_idx = idx; + } +#endif + e->b.key = key; + e->value = value; + hashmap_set_dirty(h); + + return 0; + } + + e = &bucket_at_swap(&swap, IDX_PUT)->p; + e->b.key = key; + e->value = value; + return hashmap_put_boldly(h, hash, &swap, true); +} + +int hashmap_update(Hashmap *h, const void *key, void *value) { + struct plain_hashmap_entry *e; + unsigned hash, idx; + + assert(h); + + hash = bucket_hash(h, key); + idx = bucket_scan(h, hash, key); + if (idx == IDX_NIL) + return -ENOENT; + + e = plain_bucket_at(h, idx); + e->value = value; + hashmap_set_dirty(h); + + return 0; +} + +void* _hashmap_get(HashmapBase *h, const void *key) { + struct hashmap_base_entry *e; + unsigned hash, idx; + + if (!h) + return NULL; + + hash = bucket_hash(h, key); + idx = bucket_scan(h, hash, key); + if (idx == IDX_NIL) + return NULL; + + e = bucket_at(h, idx); + return entry_value(h, e); +} + +void* hashmap_get2(Hashmap *h, const void *key, void **key2) { + struct plain_hashmap_entry *e; + unsigned hash, idx; + + if (!h) + return NULL; + + hash = bucket_hash(h, key); + idx = bucket_scan(h, hash, key); + if (idx == IDX_NIL) + return NULL; + + e = plain_bucket_at(h, idx); + if (key2) + *key2 = (void*) e->b.key; + + return e->value; +} + +bool _hashmap_contains(HashmapBase *h, const void *key) { + unsigned hash; + + if (!h) + return false; + + hash = bucket_hash(h, key); + return bucket_scan(h, hash, key) != IDX_NIL; +} + +void* _hashmap_remove(HashmapBase *h, const void *key) { + struct hashmap_base_entry *e; + unsigned hash, idx; + void *data; + + if (!h) + return NULL; + + hash = bucket_hash(h, key); + idx = bucket_scan(h, hash, key); + if (idx == IDX_NIL) + return NULL; + + e = bucket_at(h, idx); + data = entry_value(h, e); + remove_entry(h, idx); + + return data; +} + +void* hashmap_remove2(Hashmap *h, const void *key, void **rkey) { + struct plain_hashmap_entry *e; + unsigned hash, idx; + void *data; + + if (!h) { + if (rkey) + *rkey = NULL; + return NULL; + } + + hash = bucket_hash(h, key); + idx = bucket_scan(h, hash, key); + if (idx == IDX_NIL) { + if (rkey) + *rkey = NULL; + return NULL; + } + + e = plain_bucket_at(h, idx); + data = e->value; + if (rkey) + *rkey = (void*) e->b.key; + + remove_entry(h, idx); + + return data; +} + +int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value) { + struct swap_entries swap; + struct plain_hashmap_entry *e; + unsigned old_hash, new_hash, idx; + + if (!h) + return -ENOENT; + + old_hash = bucket_hash(h, old_key); + idx = bucket_scan(h, old_hash, old_key); + if (idx == IDX_NIL) + return -ENOENT; + + new_hash = bucket_hash(h, new_key); + if (bucket_scan(h, new_hash, new_key) != IDX_NIL) + return -EEXIST; + + remove_entry(h, idx); + + e = &bucket_at_swap(&swap, IDX_PUT)->p; + e->b.key = new_key; + e->value = value; + assert_se(hashmap_put_boldly(h, new_hash, &swap, false) == 1); + + return 0; +} + +int set_remove_and_put(Set *s, const void *old_key, const void *new_key) { + struct swap_entries swap; + struct hashmap_base_entry *e; + unsigned old_hash, new_hash, idx; + + if (!s) + return -ENOENT; + + old_hash = bucket_hash(s, old_key); + idx = bucket_scan(s, old_hash, old_key); + if (idx == IDX_NIL) + return -ENOENT; + + new_hash = bucket_hash(s, new_key); + if (bucket_scan(s, new_hash, new_key) != IDX_NIL) + return -EEXIST; + + remove_entry(s, idx); + + e = &bucket_at_swap(&swap, IDX_PUT)->p.b; + e->key = new_key; + assert_se(hashmap_put_boldly(s, new_hash, &swap, false) == 1); + + return 0; +} + +int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value) { + struct swap_entries swap; + struct plain_hashmap_entry *e; + unsigned old_hash, new_hash, idx_old, idx_new; + + if (!h) + return -ENOENT; + + old_hash = bucket_hash(h, old_key); + idx_old = bucket_scan(h, old_hash, old_key); + if (idx_old == IDX_NIL) + return -ENOENT; + + old_key = bucket_at(HASHMAP_BASE(h), idx_old)->key; + + new_hash = bucket_hash(h, new_key); + idx_new = bucket_scan(h, new_hash, new_key); + if (idx_new != IDX_NIL) + if (idx_old != idx_new) { + remove_entry(h, idx_new); + /* Compensate for a possible backward shift. */ + if (old_key != bucket_at(HASHMAP_BASE(h), idx_old)->key) + idx_old = prev_idx(HASHMAP_BASE(h), idx_old); + assert(old_key == bucket_at(HASHMAP_BASE(h), idx_old)->key); + } + + remove_entry(h, idx_old); + + e = &bucket_at_swap(&swap, IDX_PUT)->p; + e->b.key = new_key; + e->value = value; + assert_se(hashmap_put_boldly(h, new_hash, &swap, false) == 1); + + return 0; +} + +void* _hashmap_remove_value(HashmapBase *h, const void *key, void *value) { + struct hashmap_base_entry *e; + unsigned hash, idx; + + if (!h) + return NULL; + + hash = bucket_hash(h, key); + idx = bucket_scan(h, hash, key); + if (idx == IDX_NIL) + return NULL; + + e = bucket_at(h, idx); + if (entry_value(h, e) != value) + return NULL; + + remove_entry(h, idx); + + return value; +} + +static unsigned find_first_entry(HashmapBase *h) { + Iterator i = ITERATOR_FIRST; + + if (!h || !n_entries(h)) + return IDX_NIL; + + return hashmap_iterate_entry(h, &i); +} + +void* _hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key) { + struct hashmap_base_entry *e; + void *key, *data; + unsigned idx; + + idx = find_first_entry(h); + if (idx == IDX_NIL) { + if (ret_key) + *ret_key = NULL; + return NULL; + } + + e = bucket_at(h, idx); + key = (void*) e->key; + data = entry_value(h, e); + + if (remove) + remove_entry(h, idx); + + if (ret_key) + *ret_key = key; + + return data; +} + +unsigned _hashmap_size(HashmapBase *h) { + if (!h) + return 0; + + return n_entries(h); +} + +unsigned _hashmap_buckets(HashmapBase *h) { + if (!h) + return 0; + + return n_buckets(h); +} + +int _hashmap_merge(Hashmap *h, Hashmap *other) { + Iterator i; + unsigned idx; + + assert(h); + + HASHMAP_FOREACH_IDX(idx, HASHMAP_BASE(other), i) { + struct plain_hashmap_entry *pe = plain_bucket_at(other, idx); + int r; + + r = hashmap_put(h, pe->b.key, pe->value); + if (r < 0 && r != -EEXIST) + return r; + } + + return 0; +} + +int set_merge(Set *s, Set *other) { + Iterator i; + unsigned idx; + + assert(s); + + HASHMAP_FOREACH_IDX(idx, HASHMAP_BASE(other), i) { + struct set_entry *se = set_bucket_at(other, idx); + int r; + + r = set_put(s, se->b.key); + if (r < 0) + return r; + } + + return 0; +} + +int _hashmap_reserve(HashmapBase *h, unsigned entries_add) { + int r; + + assert(h); + + r = resize_buckets(h, entries_add); + if (r < 0) + return r; + + return 0; +} + +/* + * The same as hashmap_merge(), but every new item from other is moved to h. + * Keys already in h are skipped and stay in other. + * Returns: 0 on success. + * -ENOMEM on alloc failure, in which case no move has been done. + */ +int _hashmap_move(HashmapBase *h, HashmapBase *other) { + struct swap_entries swap; + struct hashmap_base_entry *e, *n; + Iterator i; + unsigned idx; + int r; + + assert(h); + + if (!other) + return 0; + + assert(other->type == h->type); + + /* + * This reserves buckets for the worst case, where none of other's + * entries are yet present in h. This is preferable to risking + * an allocation failure in the middle of the moving and having to + * rollback or return a partial result. + */ + r = resize_buckets(h, n_entries(other)); + if (r < 0) + return r; + + HASHMAP_FOREACH_IDX(idx, other, i) { + unsigned h_hash; + + e = bucket_at(other, idx); + h_hash = bucket_hash(h, e->key); + if (bucket_scan(h, h_hash, e->key) != IDX_NIL) + continue; + + n = &bucket_at_swap(&swap, IDX_PUT)->p.b; + n->key = e->key; + if (h->type != HASHMAP_TYPE_SET) + ((struct plain_hashmap_entry*) n)->value = + ((struct plain_hashmap_entry*) e)->value; + assert_se(hashmap_put_boldly(h, h_hash, &swap, false) == 1); + + remove_entry(other, idx); + } + + return 0; +} + +int _hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key) { + struct swap_entries swap; + unsigned h_hash, other_hash, idx; + struct hashmap_base_entry *e, *n; + int r; + + assert(h); + + h_hash = bucket_hash(h, key); + if (bucket_scan(h, h_hash, key) != IDX_NIL) + return -EEXIST; + + if (!other) + return -ENOENT; + + assert(other->type == h->type); + + other_hash = bucket_hash(other, key); + idx = bucket_scan(other, other_hash, key); + if (idx == IDX_NIL) + return -ENOENT; + + e = bucket_at(other, idx); + + n = &bucket_at_swap(&swap, IDX_PUT)->p.b; + n->key = e->key; + if (h->type != HASHMAP_TYPE_SET) + ((struct plain_hashmap_entry*) n)->value = + ((struct plain_hashmap_entry*) e)->value; + r = hashmap_put_boldly(h, h_hash, &swap, true); + if (r < 0) + return r; + + remove_entry(other, idx); + return 0; +} + +HashmapBase* _hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS) { + HashmapBase *copy; + int r; + + assert(h); + + copy = hashmap_base_new(h->hash_ops, h->type HASHMAP_DEBUG_PASS_ARGS); + if (!copy) + return NULL; + + switch (h->type) { + case HASHMAP_TYPE_PLAIN: + case HASHMAP_TYPE_ORDERED: + r = hashmap_merge((Hashmap*)copy, (Hashmap*)h); + break; + case HASHMAP_TYPE_SET: + r = set_merge((Set*)copy, (Set*)h); + break; + default: + assert_not_reached("Unknown hashmap type"); + } + + if (r < 0) + return _hashmap_free(copy, false, false); + + return copy; +} + +char** _hashmap_get_strv(HashmapBase *h) { + char **sv; + Iterator i; + unsigned idx, n; + + sv = new(char*, n_entries(h)+1); + if (!sv) + return NULL; + + n = 0; + HASHMAP_FOREACH_IDX(idx, h, i) + sv[n++] = entry_value(h, bucket_at(h, idx)); + sv[n] = NULL; + + return sv; +} + +void* ordered_hashmap_next(OrderedHashmap *h, const void *key) { + struct ordered_hashmap_entry *e; + unsigned hash, idx; + + if (!h) + return NULL; + + hash = bucket_hash(h, key); + idx = bucket_scan(h, hash, key); + if (idx == IDX_NIL) + return NULL; + + e = ordered_bucket_at(h, idx); + if (e->iterate_next == IDX_NIL) + return NULL; + return ordered_bucket_at(h, e->iterate_next)->p.value; +} + +int set_consume(Set *s, void *value) { + int r; + + assert(s); + assert(value); + + r = set_put(s, value); + if (r <= 0) + free(value); + + return r; +} + +#if 0 /* NM_IGNORED */ +int _hashmap_put_strdup_full(Hashmap **h, const struct hash_ops *hash_ops, const char *k, const char *v HASHMAP_DEBUG_PARAMS) { + int r; + + r = _hashmap_ensure_allocated(h, hash_ops HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + _cleanup_free_ char *kdup = NULL, *vdup = NULL; + + kdup = strdup(k); + if (!kdup) + return -ENOMEM; + + if (v) { + vdup = strdup(v); + if (!vdup) + return -ENOMEM; + } + + r = hashmap_put(*h, kdup, vdup); + if (r < 0) { + if (r == -EEXIST && streq_ptr(v, hashmap_get(*h, kdup))) + return 0; + return r; + } + + /* 0 with non-null vdup would mean vdup is already in the hashmap, which cannot be */ + assert(vdup == NULL || r > 0); + if (r > 0) + kdup = vdup = NULL; + + return r; +} +#endif /* NM_IGNORED */ + +int _set_put_strdup_full(Set **s, const struct hash_ops *hash_ops, const char *p HASHMAP_DEBUG_PARAMS) { + char *c; + int r; + + assert(s); + assert(p); + + r = _set_ensure_allocated(s, hash_ops HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + if (set_contains(*s, (char*) p)) + return 0; + + c = strdup(p); + if (!c) + return -ENOMEM; + + return set_consume(*s, c); +} + +int _set_put_strdupv_full(Set **s, const struct hash_ops *hash_ops, char **l HASHMAP_DEBUG_PARAMS) { + int n = 0, r; + char **i; + + assert(s); + + STRV_FOREACH(i, l) { + r = _set_put_strdup_full(s, hash_ops, *i HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + n += r; + } + + return n; +} + +int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags) { + const char *p = v; + int r; + + assert(s); + assert(v); + + for (;;) { + char *word; + + r = extract_first_word(&p, &word, separators, flags); + if (r <= 0) + return r; + + r = set_consume(s, word); + if (r < 0) + return r; + } +} + +/* expand the cachemem if needed, return true if newly (re)activated. */ +static int cachemem_maintain(CacheMem *mem, unsigned size) { + assert(mem); + + if (!GREEDY_REALLOC(mem->ptr, mem->n_allocated, size)) { + if (size > 0) + return -ENOMEM; + } + + if (!mem->active) { + mem->active = true; + return true; + } + + return false; +} + +int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries) { + bool sync_keys = false, sync_values = false; + unsigned size; + int r; + + assert(cache); + assert(cache->hashmap); + + size = n_entries(cache->hashmap); + + if (res_keys) { + r = cachemem_maintain(&cache->keys, size); + if (r < 0) + return r; + + sync_keys = r; + } else + cache->keys.active = false; + + if (res_values) { + r = cachemem_maintain(&cache->values, size); + if (r < 0) + return r; + + sync_values = r; + } else + cache->values.active = false; + + if (cache->hashmap->dirty) { + if (cache->keys.active) + sync_keys = true; + if (cache->values.active) + sync_values = true; + + cache->hashmap->dirty = false; + } + + if (sync_keys || sync_values) { + unsigned i, idx; + Iterator iter; + + i = 0; + HASHMAP_FOREACH_IDX(idx, cache->hashmap, iter) { + struct hashmap_base_entry *e; + + e = bucket_at(cache->hashmap, idx); + + if (sync_keys) + cache->keys.ptr[i] = e->key; + if (sync_values) + cache->values.ptr[i] = entry_value(cache->hashmap, e); + i++; + } + } + + if (res_keys) + *res_keys = cache->keys.ptr; + if (res_values) + *res_values = cache->values.ptr; + if (res_n_entries) + *res_n_entries = size; + + return 0; +} + +IteratedCache* iterated_cache_free(IteratedCache *cache) { + if (cache) { + free(cache->keys.ptr); + free(cache->values.ptr); + } + + return mfree(cache); +} + +int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **ret) { + size_t separator_len, allocated = 0, len = 0; + _cleanup_free_ char *str = NULL; + const char *value; + bool first; + + assert(ret); + + if (set_isempty(s)) { + *ret = NULL; + return 0; + } + + separator_len = strlen_ptr(separator); + + if (separator_len == 0) + wrap_with_separator = false; + + first = !wrap_with_separator; + + SET_FOREACH(value, s) { + size_t l = strlen_ptr(value); + + if (l == 0) + continue; + + if (!GREEDY_REALLOC(str, allocated, len + l + (first ? 0 : separator_len) + (wrap_with_separator ? separator_len : 0) + 1)) + return -ENOMEM; + + if (separator_len > 0 && !first) { + memcpy(str + len, separator, separator_len); + len += separator_len; + } + + memcpy(str + len, value, l); + len += l; + first = false; + } + + if (wrap_with_separator) { + memcpy(str + len, separator, separator_len); + len += separator_len; + } + + str[len] = '\0'; + + *ret = TAKE_PTR(str); + return 0; +} diff --git a/src/libnm-systemd-shared/src/basic/hashmap.h b/src/libnm-systemd-shared/src/basic/hashmap.h new file mode 100644 index 0000000..e994483 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/hashmap.h @@ -0,0 +1,449 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include + +#include "hash-funcs.h" +#include "macro.h" +#include "util.h" + +/* + * A hash table implementation. As a minor optimization a NULL hashmap object + * will be treated as empty hashmap for all read operations. That way it is not + * necessary to instantiate an object for each Hashmap use. + * + * If ENABLE_DEBUG_HASHMAP is defined (by configuring with -Ddebug-extra=hashmap), + * the implementation will: + * - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py) + * - perform extra checks for invalid use of iterators + */ + +#define HASH_KEY_SIZE 16 + +typedef void* (*hashmap_destroy_t)(void *p); + +/* The base type for all hashmap and set types. Many functions in the implementation take (HashmapBase*) + * parameters and are run-time polymorphic, though the API is not meant to be polymorphic (do not call + * underscore-prefixed functions directly). */ +typedef struct HashmapBase HashmapBase; + +/* Specific hashmap/set types */ +typedef struct Hashmap Hashmap; /* Maps keys to values */ +typedef struct OrderedHashmap OrderedHashmap; /* Like Hashmap, but also remembers entry insertion order */ +typedef struct Set Set; /* Stores just keys */ + +typedef struct IteratedCache IteratedCache; /* Caches the iterated order of one of the above */ + +/* Ideally the Iterator would be an opaque struct, but it is instantiated + * by hashmap users, so the definition has to be here. Do not use its fields + * directly. */ +typedef struct { + unsigned idx; /* index of an entry to be iterated next */ + const void *next_key; /* expected value of that entry's key pointer */ +#if ENABLE_DEBUG_HASHMAP + unsigned put_count; /* hashmap's put_count recorded at start of iteration */ + unsigned rem_count; /* hashmap's rem_count in previous iteration */ + unsigned prev_idx; /* idx in previous iteration */ +#endif +} Iterator; + +#define _IDX_ITERATOR_FIRST (UINT_MAX - 1) +#define ITERATOR_FIRST ((Iterator) { .idx = _IDX_ITERATOR_FIRST, .next_key = NULL }) + +/* Macros for type checking */ +#define PTR_COMPATIBLE_WITH_HASHMAP_BASE(h) \ + (__builtin_types_compatible_p(typeof(h), HashmapBase*) || \ + __builtin_types_compatible_p(typeof(h), Hashmap*) || \ + __builtin_types_compatible_p(typeof(h), OrderedHashmap*) || \ + __builtin_types_compatible_p(typeof(h), Set*)) + +#define PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h) \ + (__builtin_types_compatible_p(typeof(h), Hashmap*) || \ + __builtin_types_compatible_p(typeof(h), OrderedHashmap*)) \ + +#define HASHMAP_BASE(h) \ + __builtin_choose_expr(PTR_COMPATIBLE_WITH_HASHMAP_BASE(h), \ + (HashmapBase*)(h), \ + (void)0) + +#define PLAIN_HASHMAP(h) \ + __builtin_choose_expr(PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h), \ + (Hashmap*)(h), \ + (void)0) + +#if ENABLE_DEBUG_HASHMAP +# define HASHMAP_DEBUG_PARAMS , const char *func, const char *file, int line +# define HASHMAP_DEBUG_SRC_ARGS , __func__, PROJECT_FILE, __LINE__ +# define HASHMAP_DEBUG_PASS_ARGS , func, file, line +#else +# define HASHMAP_DEBUG_PARAMS +# define HASHMAP_DEBUG_SRC_ARGS +# define HASHMAP_DEBUG_PASS_ARGS +#endif + +Hashmap* _hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +OrderedHashmap* _ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +#define hashmap_new(ops) _hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS) +#define ordered_hashmap_new(ops) _ordered_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS) + +#define hashmap_free_and_replace(a, b) \ + ({ \ + hashmap_free(a); \ + (a) = (b); \ + (b) = NULL; \ + 0; \ + }) + +HashmapBase* _hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value); +static inline Hashmap* hashmap_free(Hashmap *h) { + return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, NULL); +} +static inline OrderedHashmap* ordered_hashmap_free(OrderedHashmap *h) { + return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, NULL); +} + +static inline Hashmap* hashmap_free_free(Hashmap *h) { + return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, free); +} +static inline OrderedHashmap* ordered_hashmap_free_free(OrderedHashmap *h) { + return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, free); +} + +static inline Hashmap* hashmap_free_free_key(Hashmap *h) { + return (void*) _hashmap_free(HASHMAP_BASE(h), free, NULL); +} +static inline OrderedHashmap* ordered_hashmap_free_free_key(OrderedHashmap *h) { + return (void*) _hashmap_free(HASHMAP_BASE(h), free, NULL); +} + +static inline Hashmap* hashmap_free_free_free(Hashmap *h) { + return (void*) _hashmap_free(HASHMAP_BASE(h), free, free); +} +static inline OrderedHashmap* ordered_hashmap_free_free_free(OrderedHashmap *h) { + return (void*) _hashmap_free(HASHMAP_BASE(h), free, free); +} + +IteratedCache* iterated_cache_free(IteratedCache *cache); +int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries); + +HashmapBase* _hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS); +#define hashmap_copy(h) ((Hashmap*) _hashmap_copy(HASHMAP_BASE(h) HASHMAP_DEBUG_SRC_ARGS)) +#define ordered_hashmap_copy(h) ((OrderedHashmap*) _hashmap_copy(HASHMAP_BASE(h) HASHMAP_DEBUG_SRC_ARGS)) + +int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +#define hashmap_ensure_allocated(h, ops) _hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS) +#define ordered_hashmap_ensure_allocated(h, ops) _ordered_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS) + +int _ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS); +#define ordered_hashmap_ensure_put(s, ops, key, value) _ordered_hashmap_ensure_put(s, ops, key, value HASHMAP_DEBUG_SRC_ARGS) + +IteratedCache* _hashmap_iterated_cache_new(HashmapBase *h); +static inline IteratedCache* hashmap_iterated_cache_new(Hashmap *h) { + return (IteratedCache*) _hashmap_iterated_cache_new(HASHMAP_BASE(h)); +} +static inline IteratedCache* ordered_hashmap_iterated_cache_new(OrderedHashmap *h) { + return (IteratedCache*) _hashmap_iterated_cache_new(HASHMAP_BASE(h)); +} + +int hashmap_put(Hashmap *h, const void *key, void *value); +static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *value) { + return hashmap_put(PLAIN_HASHMAP(h), key, value); +} + +int _hashmap_put_strdup_full(Hashmap **h, const struct hash_ops *hash_ops, const char *k, const char *v HASHMAP_DEBUG_PARAMS); +#define hashmap_put_strdup_full(h, hash_ops, k, v) _hashmap_put_strdup_full(h, hash_ops, k, v HASHMAP_DEBUG_SRC_ARGS) +#define hashmap_put_strdup(h, k, v) hashmap_put_strdup_full(h, &string_hash_ops_free_free, k, v) + +int hashmap_update(Hashmap *h, const void *key, void *value); +static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) { + return hashmap_update(PLAIN_HASHMAP(h), key, value); +} + +int hashmap_replace(Hashmap *h, const void *key, void *value); +static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, void *value) { + return hashmap_replace(PLAIN_HASHMAP(h), key, value); +} + +void* _hashmap_get(HashmapBase *h, const void *key); +static inline void *hashmap_get(Hashmap *h, const void *key) { + return _hashmap_get(HASHMAP_BASE(h), key); +} +static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) { + return _hashmap_get(HASHMAP_BASE(h), key); +} + +void* hashmap_get2(Hashmap *h, const void *key, void **rkey); +static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, void **rkey) { + return hashmap_get2(PLAIN_HASHMAP(h), key, rkey); +} + +bool _hashmap_contains(HashmapBase *h, const void *key); +static inline bool hashmap_contains(Hashmap *h, const void *key) { + return _hashmap_contains(HASHMAP_BASE(h), key); +} +static inline bool ordered_hashmap_contains(OrderedHashmap *h, const void *key) { + return _hashmap_contains(HASHMAP_BASE(h), key); +} + +void* _hashmap_remove(HashmapBase *h, const void *key); +static inline void *hashmap_remove(Hashmap *h, const void *key) { + return _hashmap_remove(HASHMAP_BASE(h), key); +} +static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) { + return _hashmap_remove(HASHMAP_BASE(h), key); +} + +void* hashmap_remove2(Hashmap *h, const void *key, void **rkey); +static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key, void **rkey) { + return hashmap_remove2(PLAIN_HASHMAP(h), key, rkey); +} + +void* _hashmap_remove_value(HashmapBase *h, const void *key, void *value); +static inline void *hashmap_remove_value(Hashmap *h, const void *key, void *value) { + return _hashmap_remove_value(HASHMAP_BASE(h), key, value); +} + +static inline void* ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) { + return hashmap_remove_value(PLAIN_HASHMAP(h), key, value); +} + +int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value); +static inline int ordered_hashmap_remove_and_put(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) { + return hashmap_remove_and_put(PLAIN_HASHMAP(h), old_key, new_key, value); +} + +int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value); +static inline int ordered_hashmap_remove_and_replace(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) { + return hashmap_remove_and_replace(PLAIN_HASHMAP(h), old_key, new_key, value); +} + +/* Since merging data from a OrderedHashmap into a Hashmap or vice-versa + * should just work, allow this by having looser type-checking here. */ +int _hashmap_merge(Hashmap *h, Hashmap *other); +#define hashmap_merge(h, other) _hashmap_merge(PLAIN_HASHMAP(h), PLAIN_HASHMAP(other)) +#define ordered_hashmap_merge(h, other) hashmap_merge(h, other) + +int _hashmap_reserve(HashmapBase *h, unsigned entries_add); +static inline int hashmap_reserve(Hashmap *h, unsigned entries_add) { + return _hashmap_reserve(HASHMAP_BASE(h), entries_add); +} +static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) { + return _hashmap_reserve(HASHMAP_BASE(h), entries_add); +} + +int _hashmap_move(HashmapBase *h, HashmapBase *other); +/* Unlike hashmap_merge, hashmap_move does not allow mixing the types. */ +static inline int hashmap_move(Hashmap *h, Hashmap *other) { + return _hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other)); +} +static inline int ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) { + return _hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other)); +} + +int _hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key); +static inline int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) { + return _hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key); +} +static inline int ordered_hashmap_move_one(OrderedHashmap *h, OrderedHashmap *other, const void *key) { + return _hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key); +} + +unsigned _hashmap_size(HashmapBase *h) _pure_; +static inline unsigned hashmap_size(Hashmap *h) { + return _hashmap_size(HASHMAP_BASE(h)); +} +static inline unsigned ordered_hashmap_size(OrderedHashmap *h) { + return _hashmap_size(HASHMAP_BASE(h)); +} + +static inline bool hashmap_isempty(Hashmap *h) { + return hashmap_size(h) == 0; +} +static inline bool ordered_hashmap_isempty(OrderedHashmap *h) { + return ordered_hashmap_size(h) == 0; +} + +unsigned _hashmap_buckets(HashmapBase *h) _pure_; +static inline unsigned hashmap_buckets(Hashmap *h) { + return _hashmap_buckets(HASHMAP_BASE(h)); +} +static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) { + return _hashmap_buckets(HASHMAP_BASE(h)); +} + +bool _hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key); +static inline bool hashmap_iterate(Hashmap *h, Iterator *i, void **value, const void **key) { + return _hashmap_iterate(HASHMAP_BASE(h), i, value, key); +} +static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void **value, const void **key) { + return _hashmap_iterate(HASHMAP_BASE(h), i, value, key); +} + +void _hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value); +static inline void hashmap_clear(Hashmap *h) { + _hashmap_clear(HASHMAP_BASE(h), NULL, NULL); +} +static inline void ordered_hashmap_clear(OrderedHashmap *h) { + _hashmap_clear(HASHMAP_BASE(h), NULL, NULL); +} + +static inline void hashmap_clear_free(Hashmap *h) { + _hashmap_clear(HASHMAP_BASE(h), NULL, free); +} +static inline void ordered_hashmap_clear_free(OrderedHashmap *h) { + _hashmap_clear(HASHMAP_BASE(h), NULL, free); +} + +static inline void hashmap_clear_free_key(Hashmap *h) { + _hashmap_clear(HASHMAP_BASE(h), free, NULL); +} +static inline void ordered_hashmap_clear_free_key(OrderedHashmap *h) { + _hashmap_clear(HASHMAP_BASE(h), free, NULL); +} + +static inline void hashmap_clear_free_free(Hashmap *h) { + _hashmap_clear(HASHMAP_BASE(h), free, free); +} +static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) { + _hashmap_clear(HASHMAP_BASE(h), free, free); +} + +/* + * Note about all *_first*() functions + * + * For plain Hashmaps and Sets the order of entries is undefined. + * The functions find whatever entry is first in the implementation + * internal order. + * + * Only for OrderedHashmaps the order is well defined and finding + * the first entry is O(1). + */ + +void *_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key); +static inline void *hashmap_steal_first_key_and_value(Hashmap *h, void **ret) { + return _hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret); +} +static inline void *ordered_hashmap_steal_first_key_and_value(OrderedHashmap *h, void **ret) { + return _hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret); +} +static inline void *hashmap_first_key_and_value(Hashmap *h, void **ret) { + return _hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret); +} +static inline void *ordered_hashmap_first_key_and_value(OrderedHashmap *h, void **ret) { + return _hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret); +} + +static inline void *hashmap_steal_first(Hashmap *h) { + return _hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL); +} +static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) { + return _hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL); +} +static inline void *hashmap_first(Hashmap *h) { + return _hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL); +} +static inline void *ordered_hashmap_first(OrderedHashmap *h) { + return _hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL); +} + +static inline void *_hashmap_first_key(HashmapBase *h, bool remove) { + void *key = NULL; + + (void) _hashmap_first_key_and_value(HASHMAP_BASE(h), remove, &key); + return key; +} +static inline void *hashmap_steal_first_key(Hashmap *h) { + return _hashmap_first_key(HASHMAP_BASE(h), true); +} +static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) { + return _hashmap_first_key(HASHMAP_BASE(h), true); +} +static inline void *hashmap_first_key(Hashmap *h) { + return _hashmap_first_key(HASHMAP_BASE(h), false); +} +static inline void *ordered_hashmap_first_key(OrderedHashmap *h) { + return _hashmap_first_key(HASHMAP_BASE(h), false); +} + +#define hashmap_clear_with_destructor(_s, _f) \ + ({ \ + void *_item; \ + while ((_item = hashmap_steal_first(_s))) \ + _f(_item); \ + }) +#define hashmap_free_with_destructor(_s, _f) \ + ({ \ + hashmap_clear_with_destructor(_s, _f); \ + hashmap_free(_s); \ + }) +#define ordered_hashmap_clear_with_destructor(_s, _f) \ + ({ \ + void *_item; \ + while ((_item = ordered_hashmap_steal_first(_s))) \ + _f(_item); \ + }) +#define ordered_hashmap_free_with_destructor(_s, _f) \ + ({ \ + ordered_hashmap_clear_with_destructor(_s, _f); \ + ordered_hashmap_free(_s); \ + }) + +/* no hashmap_next */ +void* ordered_hashmap_next(OrderedHashmap *h, const void *key); + +char** _hashmap_get_strv(HashmapBase *h); +static inline char** hashmap_get_strv(Hashmap *h) { + return _hashmap_get_strv(HASHMAP_BASE(h)); +} +static inline char** ordered_hashmap_get_strv(OrderedHashmap *h) { + return _hashmap_get_strv(HASHMAP_BASE(h)); +} + +/* + * Hashmaps are iterated in unpredictable order. + * OrderedHashmaps are an exception to this. They are iterated in the order + * the entries were inserted. + * It is safe to remove the current entry. + */ +#define _HASHMAP_FOREACH(e, h, i) \ + for (Iterator i = ITERATOR_FIRST; hashmap_iterate((h), &i, (void**)&(e), NULL); ) +#define HASHMAP_FOREACH(e, h) \ + _HASHMAP_FOREACH(e, h, UNIQ_T(i, UNIQ)) + +#define _ORDERED_HASHMAP_FOREACH(e, h, i) \ + for (Iterator i = ITERATOR_FIRST; ordered_hashmap_iterate((h), &i, (void**)&(e), NULL); ) +#define ORDERED_HASHMAP_FOREACH(e, h) \ + _ORDERED_HASHMAP_FOREACH(e, h, UNIQ_T(i, UNIQ)) + +#define _HASHMAP_FOREACH_KEY(e, k, h, i) \ + for (Iterator i = ITERATOR_FIRST; hashmap_iterate((h), &i, (void**)&(e), (const void**) &(k)); ) +#define HASHMAP_FOREACH_KEY(e, k, h) \ + _HASHMAP_FOREACH_KEY(e, k, h, UNIQ_T(i, UNIQ)) + +#define _ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \ + for (Iterator i = ITERATOR_FIRST; ordered_hashmap_iterate((h), &i, (void**)&(e), (const void**) &(k)); ) +#define ORDERED_HASHMAP_FOREACH_KEY(e, k, h) \ + _ORDERED_HASHMAP_FOREACH_KEY(e, k, h, UNIQ_T(i, UNIQ)) + +DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_key); +DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_key); +DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_free); + +#define _cleanup_hashmap_free_ _cleanup_(hashmap_freep) +#define _cleanup_hashmap_free_free_ _cleanup_(hashmap_free_freep) +#define _cleanup_hashmap_free_free_free_ _cleanup_(hashmap_free_free_freep) +#define _cleanup_ordered_hashmap_free_ _cleanup_(ordered_hashmap_freep) +#define _cleanup_ordered_hashmap_free_free_ _cleanup_(ordered_hashmap_free_freep) +#define _cleanup_ordered_hashmap_free_free_free_ _cleanup_(ordered_hashmap_free_free_freep) + +DEFINE_TRIVIAL_CLEANUP_FUNC(IteratedCache*, iterated_cache_free); + +#define _cleanup_iterated_cache_free_ _cleanup_(iterated_cache_freep) diff --git a/src/libnm-systemd-shared/src/basic/hexdecoct.c b/src/libnm-systemd-shared/src/basic/hexdecoct.c new file mode 100644 index 0000000..78930b3 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/hexdecoct.c @@ -0,0 +1,869 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include + +#include "alloc-util.h" +#include "hexdecoct.h" +#include "macro.h" +#include "memory-util.h" +#include "string-util.h" + +char octchar(int x) { + return '0' + (x & 7); +} + +int unoctchar(char c) { + + if (c >= '0' && c <= '7') + return c - '0'; + + return -EINVAL; +} + +char decchar(int x) { + return '0' + (x % 10); +} + +int undecchar(char c) { + + if (c >= '0' && c <= '9') + return c - '0'; + + return -EINVAL; +} + +char hexchar(int x) { + static const char table[16] = "0123456789abcdef"; + + return table[x & 15]; +} + +int unhexchar(char c) { + + if (c >= '0' && c <= '9') + return c - '0'; + + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + + return -EINVAL; +} + +char *hexmem(const void *p, size_t l) { + const uint8_t *x; + char *r, *z; + + z = r = new(char, l * 2 + 1); + if (!r) + return NULL; + + for (x = p; x < (const uint8_t*) p + l; x++) { + *(z++) = hexchar(*x >> 4); + *(z++) = hexchar(*x & 15); + } + + *z = 0; + return r; +} + +static int unhex_next(const char **p, size_t *l) { + int r; + + assert(p); + assert(l); + + /* Find the next non-whitespace character, and decode it. We + * greedily skip all preceding and all following whitespace. */ + + for (;;) { + if (*l == 0) + return -EPIPE; + + if (!strchr(WHITESPACE, **p)) + break; + + /* Skip leading whitespace */ + (*p)++, (*l)--; + } + + r = unhexchar(**p); + if (r < 0) + return r; + + for (;;) { + (*p)++, (*l)--; + + if (*l == 0 || !strchr(WHITESPACE, **p)) + break; + + /* Skip following whitespace */ + } + + return r; +} + +int unhexmem_full(const char *p, size_t l, bool secure, void **ret, size_t *ret_len) { + _cleanup_free_ uint8_t *buf = NULL; + size_t buf_size; + const char *x; + uint8_t *z; + int r; + + assert(ret); + assert(ret_len); + assert(p || l == 0); + + if (l == (size_t) -1) + l = strlen(p); + + /* Note that the calculation of memory size is an upper boundary, as we ignore whitespace while decoding */ + buf_size = (l + 1) / 2 + 1; + buf = malloc(buf_size); + if (!buf) + return -ENOMEM; + + for (x = p, z = buf;;) { + int a, b; + + a = unhex_next(&x, &l); + if (a == -EPIPE) /* End of string */ + break; + if (a < 0) { + r = a; + goto on_failure; + } + + b = unhex_next(&x, &l); + if (b < 0) { + r = b; + goto on_failure; + } + + *(z++) = (uint8_t) a << 4 | (uint8_t) b; + } + + *z = 0; + + *ret_len = (size_t) (z - buf); + *ret = TAKE_PTR(buf); + + return 0; + +on_failure: + if (secure) + explicit_bzero_safe(buf, buf_size); + + return r; +} + +#if 0 /* NM_IGNORED */ +/* https://tools.ietf.org/html/rfc4648#section-6 + * Notice that base32hex differs from base32 in the alphabet it uses. + * The distinction is that the base32hex representation preserves the + * order of the underlying data when compared as bytestrings, this is + * useful when representing NSEC3 hashes, as one can then verify the + * order of hashes directly from their representation. */ +char base32hexchar(int x) { + static const char table[32] = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUV"; + + return table[x & 31]; +} + +int unbase32hexchar(char c) { + unsigned offset; + + if (c >= '0' && c <= '9') + return c - '0'; + + offset = '9' - '0' + 1; + + if (c >= 'A' && c <= 'V') + return c - 'A' + offset; + + return -EINVAL; +} + +char *base32hexmem(const void *p, size_t l, bool padding) { + char *r, *z; + const uint8_t *x; + size_t len; + + assert(p || l == 0); + + if (padding) + /* five input bytes makes eight output bytes, padding is added so we must round up */ + len = 8 * (l + 4) / 5; + else { + /* same, but round down as there is no padding */ + len = 8 * l / 5; + + switch (l % 5) { + case 4: + len += 7; + break; + case 3: + len += 5; + break; + case 2: + len += 4; + break; + case 1: + len += 2; + break; + } + } + + z = r = malloc(len + 1); + if (!r) + return NULL; + + for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) { + /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ + * x[3] == QQQQQQQQ; x[4] == WWWWWWWW */ + *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */ + *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */ + *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */ + *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */ + *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */ + *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */ + *(z++) = base32hexchar((x[3] & 3) << 3 | x[4] >> 5); /* 000QQWWW */ + *(z++) = base32hexchar((x[4] & 31)); /* 000WWWWW */ + } + + switch (l % 5) { + case 4: + *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */ + *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */ + *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */ + *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */ + *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */ + *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */ + *(z++) = base32hexchar((x[3] & 3) << 3); /* 000QQ000 */ + if (padding) + *(z++) = '='; + + break; + + case 3: + *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */ + *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */ + *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */ + *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */ + *(z++) = base32hexchar((x[2] & 15) << 1); /* 000ZZZZ0 */ + if (padding) { + *(z++) = '='; + *(z++) = '='; + *(z++) = '='; + } + + break; + + case 2: + *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */ + *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */ + *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */ + *(z++) = base32hexchar((x[1] & 1) << 4); /* 000Y0000 */ + if (padding) { + *(z++) = '='; + *(z++) = '='; + *(z++) = '='; + *(z++) = '='; + } + + break; + + case 1: + *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */ + *(z++) = base32hexchar((x[0] & 7) << 2); /* 000XXX00 */ + if (padding) { + *(z++) = '='; + *(z++) = '='; + *(z++) = '='; + *(z++) = '='; + *(z++) = '='; + *(z++) = '='; + } + + break; + } + + *z = 0; + return r; +} + +int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_len) { + _cleanup_free_ uint8_t *r = NULL; + int a, b, c, d, e, f, g, h; + uint8_t *z; + const char *x; + size_t len; + unsigned pad = 0; + + assert(p || l == 0); + assert(mem); + assert(_len); + + if (l == (size_t) -1) + l = strlen(p); + + /* padding ensures any base32hex input has input divisible by 8 */ + if (padding && l % 8 != 0) + return -EINVAL; + + if (padding) { + /* strip the padding */ + while (l > 0 && p[l - 1] == '=' && pad < 7) { + pad++; + l--; + } + } + + /* a group of eight input bytes needs five output bytes, in case of + * padding we need to add some extra bytes */ + len = (l / 8) * 5; + + switch (l % 8) { + case 7: + len += 4; + break; + case 5: + len += 3; + break; + case 4: + len += 2; + break; + case 2: + len += 1; + break; + case 0: + break; + default: + return -EINVAL; + } + + z = r = malloc(len + 1); + if (!r) + return -ENOMEM; + + for (x = p; x < p + (l / 8) * 8; x += 8) { + /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW + * e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */ + a = unbase32hexchar(x[0]); + if (a < 0) + return -EINVAL; + + b = unbase32hexchar(x[1]); + if (b < 0) + return -EINVAL; + + c = unbase32hexchar(x[2]); + if (c < 0) + return -EINVAL; + + d = unbase32hexchar(x[3]); + if (d < 0) + return -EINVAL; + + e = unbase32hexchar(x[4]); + if (e < 0) + return -EINVAL; + + f = unbase32hexchar(x[5]); + if (f < 0) + return -EINVAL; + + g = unbase32hexchar(x[6]); + if (g < 0) + return -EINVAL; + + h = unbase32hexchar(x[7]); + if (h < 0) + return -EINVAL; + + *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */ + *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */ + *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */ + *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */ + *(z++) = (uint8_t) g << 5 | (uint8_t) h; /* VVVRRRRR */ + } + + switch (l % 8) { + case 7: + a = unbase32hexchar(x[0]); + if (a < 0) + return -EINVAL; + + b = unbase32hexchar(x[1]); + if (b < 0) + return -EINVAL; + + c = unbase32hexchar(x[2]); + if (c < 0) + return -EINVAL; + + d = unbase32hexchar(x[3]); + if (d < 0) + return -EINVAL; + + e = unbase32hexchar(x[4]); + if (e < 0) + return -EINVAL; + + f = unbase32hexchar(x[5]); + if (f < 0) + return -EINVAL; + + g = unbase32hexchar(x[6]); + if (g < 0) + return -EINVAL; + + /* g == 000VV000 */ + if (g & 7) + return -EINVAL; + + *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */ + *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */ + *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */ + *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */ + + break; + case 5: + a = unbase32hexchar(x[0]); + if (a < 0) + return -EINVAL; + + b = unbase32hexchar(x[1]); + if (b < 0) + return -EINVAL; + + c = unbase32hexchar(x[2]); + if (c < 0) + return -EINVAL; + + d = unbase32hexchar(x[3]); + if (d < 0) + return -EINVAL; + + e = unbase32hexchar(x[4]); + if (e < 0) + return -EINVAL; + + /* e == 000SSSS0 */ + if (e & 1) + return -EINVAL; + + *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */ + *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */ + *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */ + + break; + case 4: + a = unbase32hexchar(x[0]); + if (a < 0) + return -EINVAL; + + b = unbase32hexchar(x[1]); + if (b < 0) + return -EINVAL; + + c = unbase32hexchar(x[2]); + if (c < 0) + return -EINVAL; + + d = unbase32hexchar(x[3]); + if (d < 0) + return -EINVAL; + + /* d == 000W0000 */ + if (d & 15) + return -EINVAL; + + *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */ + *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */ + + break; + case 2: + a = unbase32hexchar(x[0]); + if (a < 0) + return -EINVAL; + + b = unbase32hexchar(x[1]); + if (b < 0) + return -EINVAL; + + /* b == 000YYY00 */ + if (b & 3) + return -EINVAL; + + *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */ + + break; + case 0: + break; + default: + return -EINVAL; + } + + *z = 0; + + *mem = TAKE_PTR(r); + *_len = len; + + return 0; +} + +/* https://tools.ietf.org/html/rfc4648#section-4 */ +char base64char(int x) { + static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + return table[x & 63]; +} +#endif /* NM_IGNORED */ + +int unbase64char(char c) { + unsigned offset; + + if (c >= 'A' && c <= 'Z') + return c - 'A'; + + offset = 'Z' - 'A' + 1; + + if (c >= 'a' && c <= 'z') + return c - 'a' + offset; + + offset += 'z' - 'a' + 1; + + if (c >= '0' && c <= '9') + return c - '0' + offset; + + offset += '9' - '0' + 1; + + if (c == '+') + return offset; + + offset++; + + if (c == '/') + return offset; + + return -EINVAL; +} + +#if 0 /* NM_IGNORED */ +ssize_t base64mem(const void *p, size_t l, char **out) { + char *r, *z; + const uint8_t *x; + + assert(p || l == 0); + assert(out); + + /* three input bytes makes four output bytes, padding is added so we must round up */ + z = r = malloc(4 * (l + 2) / 3 + 1); + if (!r) + return -ENOMEM; + + for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) { + /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */ + *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */ + *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */ + *(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */ + *(z++) = base64char(x[2] & 63); /* 00ZZZZZZ */ + } + + switch (l % 3) { + case 2: + *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */ + *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */ + *(z++) = base64char((x[1] & 15) << 2); /* 00YYYY00 */ + *(z++) = '='; + + break; + case 1: + *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */ + *(z++) = base64char((x[0] & 3) << 4); /* 00XX0000 */ + *(z++) = '='; + *(z++) = '='; + + break; + } + + *z = 0; + *out = r; + return z - r; +} + +static int base64_append_width( + char **prefix, int plen, + char sep, int indent, + const void *p, size_t l, + int width) { + + _cleanup_free_ char *x = NULL; + char *t, *s; + ssize_t len, avail, line, lines; + + len = base64mem(p, l, &x); + if (len <= 0) + return len; + + lines = DIV_ROUND_UP(len, width); + + if ((size_t) plen >= SSIZE_MAX - 1 - 1 || + lines > (SSIZE_MAX - plen - 1 - 1) / (indent + width + 1)) + return -ENOMEM; + + t = realloc(*prefix, (ssize_t) plen + 1 + 1 + (indent + width + 1) * lines); + if (!t) + return -ENOMEM; + + t[plen] = sep; + + for (line = 0, s = t + plen + 1, avail = len; line < lines; line++) { + int act = MIN(width, avail); + + if (line > 0 || sep == '\n') { + memset(s, ' ', indent); + s += indent; + } + + memcpy(s, x + width * line, act); + s += act; + *(s++) = line < lines - 1 ? '\n' : '\0'; + avail -= act; + } + assert(avail == 0); + + *prefix = t; + return 0; +} + +int base64_append( + char **prefix, int plen, + const void *p, size_t l, + int indent, int width) { + + if (plen > width / 2 || plen + indent > width) + /* leave indent on the left, keep last column free */ + return base64_append_width(prefix, plen, '\n', indent, p, l, width - indent - 1); + else + /* leave plen on the left, keep last column free */ + return base64_append_width(prefix, plen, ' ', plen + 1, p, l, width - plen - 1); +} +#endif /* NM_IGNORED */ + +static int unbase64_next(const char **p, size_t *l) { + int ret; + + assert(p); + assert(l); + + /* Find the next non-whitespace character, and decode it. If we find padding, we return it as INT_MAX. We + * greedily skip all preceding and all following whitespace. */ + + for (;;) { + if (*l == 0) + return -EPIPE; + + if (!strchr(WHITESPACE, **p)) + break; + + /* Skip leading whitespace */ + (*p)++, (*l)--; + } + + if (**p == '=') + ret = INT_MAX; /* return padding as INT_MAX */ + else { + ret = unbase64char(**p); + if (ret < 0) + return ret; + } + + for (;;) { + (*p)++, (*l)--; + + if (*l == 0) + break; + if (!strchr(WHITESPACE, **p)) + break; + + /* Skip following whitespace */ + } + + return ret; +} + +int unbase64mem_full(const char *p, size_t l, bool secure, void **ret, size_t *ret_size) { + _cleanup_free_ uint8_t *buf = NULL; + const char *x; + uint8_t *z; + size_t len; + int r; + + assert(p || l == 0); + assert(ret); + assert(ret_size); + + if (l == (size_t) -1) + l = strlen(p); + + /* A group of four input bytes needs three output bytes, in case of padding we need to add two or three extra + * bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */ + len = (l / 4) * 3 + (l % 4 != 0 ? (l % 4) - 1 : 0); + + buf = malloc(len + 1); + if (!buf) + return -ENOMEM; + + for (x = p, z = buf;;) { + int a, b, c, d; /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */ + + a = unbase64_next(&x, &l); + if (a == -EPIPE) /* End of string */ + break; + if (a < 0) { + r = a; + goto on_failure; + } + if (a == INT_MAX) { /* Padding is not allowed at the beginning of a 4ch block */ + r = -EINVAL; + goto on_failure; + } + + b = unbase64_next(&x, &l); + if (b < 0) { + r = b; + goto on_failure; + } + if (b == INT_MAX) { /* Padding is not allowed at the second character of a 4ch block either */ + r = -EINVAL; + goto on_failure; + } + + c = unbase64_next(&x, &l); + if (c < 0) { + r = c; + goto on_failure; + } + + d = unbase64_next(&x, &l); + if (d < 0) { + r = d; + goto on_failure; + } + + if (c == INT_MAX) { /* Padding at the third character */ + + if (d != INT_MAX) { /* If the third character is padding, the fourth must be too */ + r = -EINVAL; + goto on_failure; + } + + /* b == 00YY0000 */ + if (b & 15) { + r = -EINVAL; + goto on_failure; + } + + if (l > 0) { /* Trailing rubbish? */ + r = -ENAMETOOLONG; + goto on_failure; + } + + *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */ + break; + } + + if (d == INT_MAX) { + /* c == 00ZZZZ00 */ + if (c & 3) { + r = -EINVAL; + goto on_failure; + } + + if (l > 0) { /* Trailing rubbish? */ + r = -ENAMETOOLONG; + goto on_failure; + } + + *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */ + *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */ + break; + } + + *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */ + *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */ + *(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */ + } + + *z = 0; + + *ret_size = (size_t) (z - buf); + *ret = TAKE_PTR(buf); + + return 0; + +on_failure: + if (secure) + explicit_bzero_safe(buf, len); + + return r; +} + +#if 0 /* NM_IGNORED */ +void hexdump(FILE *f, const void *p, size_t s) { + const uint8_t *b = p; + unsigned n = 0; + + assert(b || s == 0); + + if (!f) + f = stdout; + + while (s > 0) { + size_t i; + + fprintf(f, "%04x ", n); + + for (i = 0; i < 16; i++) { + + if (i >= s) + fputs(" ", f); + else + fprintf(f, "%02x ", b[i]); + + if (i == 7) + fputc(' ', f); + } + + fputc(' ', f); + + for (i = 0; i < 16; i++) { + + if (i >= s) + fputc(' ', f); + else + fputc(isprint(b[i]) ? (char) b[i] : '.', f); + } + + fputc('\n', f); + + if (s < 16) + break; + + n += 16; + b += 16; + s -= 16; + } +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/hexdecoct.h b/src/libnm-systemd-shared/src/basic/hexdecoct.h new file mode 100644 index 0000000..7e2a689 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/hexdecoct.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include + +#include "macro.h" + +char octchar(int x) _const_; +int unoctchar(char c) _const_; + +char decchar(int x) _const_; +int undecchar(char c) _const_; + +char hexchar(int x) _const_; +int unhexchar(char c) _const_; + +char *hexmem(const void *p, size_t l); +int unhexmem_full(const char *p, size_t l, bool secure, void **mem, size_t *len); +static inline int unhexmem(const char *p, size_t l, void **mem, size_t *len) { + return unhexmem_full(p, l, false, mem, len); +} + +char base32hexchar(int x) _const_; +int unbase32hexchar(char c) _const_; + +char base64char(int x) _const_; +int unbase64char(char c) _const_; + +char *base32hexmem(const void *p, size_t l, bool padding); +int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *len); + +ssize_t base64mem(const void *p, size_t l, char **out); +int base64_append(char **prefix, int plen, + const void *p, size_t l, + int margin, int width); +int unbase64mem_full(const char *p, size_t l, bool secure, void **mem, size_t *len); +static inline int unbase64mem(const char *p, size_t l, void **mem, size_t *len) { + return unbase64mem_full(p, l, false, mem, len); +} + +void hexdump(FILE *f, const void *p, size_t s); diff --git a/src/libnm-systemd-shared/src/basic/hostname-util.c b/src/libnm-systemd-shared/src/basic/hostname-util.c new file mode 100644 index 0000000..a3cdc62 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/hostname-util.c @@ -0,0 +1,196 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "hostname-util.h" +#include "string-util.h" +#include "strv.h" + +#if 0 /* NM_IGNORED */ +char* gethostname_malloc(void) { + struct utsname u; + const char *s; + + /* This call tries to return something useful, either the actual hostname + * or it makes something up. The only reason it might fail is OOM. + * It might even return "localhost" if that's set. */ + + assert_se(uname(&u) >= 0); + + s = u.nodename; + if (isempty(s) || streq(s, "(none)")) + s = FALLBACK_HOSTNAME; + + return strdup(s); +} + +char* gethostname_short_malloc(void) { + struct utsname u; + const char *s; + + /* Like above, but kills the FQDN part if present. */ + + assert_se(uname(&u) >= 0); + + s = u.nodename; + if (isempty(s) || streq(s, "(none)") || s[0] == '.') { + s = FALLBACK_HOSTNAME; + assert(s[0] != '.'); + } + + return strndup(s, strcspn(s, ".")); +} +#endif /* NM_IGNORED */ + +int gethostname_strict(char **ret) { + struct utsname u; + char *k; + + /* This call will rather fail than make up a name. It will not return "localhost" either. */ + + assert_se(uname(&u) >= 0); + + if (isempty(u.nodename)) + return -ENXIO; + + if (streq(u.nodename, "(none)")) + return -ENXIO; + + if (is_localhost(u.nodename)) + return -ENXIO; + + k = strdup(u.nodename); + if (!k) + return -ENOMEM; + + *ret = k; + return 0; +} + +bool valid_ldh_char(char c) { + /* "LDH" → "Letters, digits, hyphens", as per RFC 5890, Section 2.3.1 */ + + return + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '-'; +} + +bool hostname_is_valid(const char *s, ValidHostnameFlags flags) { + unsigned n_dots = 0; + const char *p; + bool dot, hyphen; + + /* Check if s looks like a valid hostname or FQDN. This does not do full DNS validation, but only + * checks if the name is composed of allowed characters and the length is not above the maximum + * allowed by Linux (c.f. dns_name_is_valid()). A trailing dot is allowed if + * VALID_HOSTNAME_TRAILING_DOT flag is set and at least two components are present in the name. Note + * that due to the restricted charset and length this call is substantially more conservative than + * dns_name_is_valid(). Doesn't accept empty hostnames, hostnames with leading dots, and hostnames + * with multiple dots in a sequence. Doesn't allow hyphens at the beginning or end of label. */ + + if (isempty(s)) + return false; + + if (streq(s, ".host")) /* Used by the container logic to denote the "root container" */ + return FLAGS_SET(flags, VALID_HOSTNAME_DOT_HOST); + + for (p = s, dot = hyphen = true; *p; p++) + if (*p == '.') { + if (dot || hyphen) + return false; + + dot = true; + hyphen = false; + n_dots++; + + } else if (*p == '-') { + if (dot) + return false; + + dot = false; + hyphen = true; + + } else { + if (!valid_ldh_char(*p)) + return false; + + dot = false; + hyphen = false; + } + + if (dot && (n_dots < 2 || !FLAGS_SET(flags, VALID_HOSTNAME_TRAILING_DOT))) + return false; + if (hyphen) + return false; + + if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on Linux, but DNS allows domain names up to + * 255 characters */ + return false; + + return true; +} + +char* hostname_cleanup(char *s) { + char *p, *d; + bool dot, hyphen; + + assert(s); + + for (p = s, d = s, dot = hyphen = true; *p && d - s < HOST_NAME_MAX; p++) + if (*p == '.') { + if (dot || hyphen) + continue; + + *(d++) = '.'; + dot = true; + hyphen = false; + + } else if (*p == '-') { + if (dot) + continue; + + *(d++) = '-'; + dot = false; + hyphen = true; + + } else if (valid_ldh_char(*p)) { + *(d++) = *p; + dot = false; + hyphen = false; + } + + if (d > s && IN_SET(d[-1], '-', '.')) + /* The dot can occur at most once, but we might have multiple + * hyphens, hence the loop */ + d--; + *d = 0; + + return s; +} + +bool is_localhost(const char *hostname) { + assert(hostname); + + /* This tries to identify local host and domain names + * described in RFC6761 plus the redhatism of localdomain */ + + return STRCASE_IN_SET( + hostname, + "localhost", + "localhost.", + "localhost.localdomain", + "localhost.localdomain.") || + endswith_no_case(hostname, ".localhost") || + endswith_no_case(hostname, ".localhost.") || + endswith_no_case(hostname, ".localhost.localdomain") || + endswith_no_case(hostname, ".localhost.localdomain."); +} diff --git a/src/libnm-systemd-shared/src/basic/hostname-util.h b/src/libnm-systemd-shared/src/basic/hostname-util.h new file mode 100644 index 0000000..6cff9c1 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/hostname-util.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include + +#include "macro.h" +#include "strv.h" + +char* gethostname_malloc(void); +char* gethostname_short_malloc(void); +int gethostname_strict(char **ret); + +bool valid_ldh_char(char c) _const_; + +typedef enum ValidHostnameFlags { + VALID_HOSTNAME_TRAILING_DOT = 1 << 0, /* Accept trailing dot on multi-label names */ + VALID_HOSTNAME_DOT_HOST = 1 << 1, /* Accept ".host" as valid hostname */ +} ValidHostnameFlags; + +bool hostname_is_valid(const char *s, ValidHostnameFlags flags) _pure_; +char* hostname_cleanup(char *s); + +bool is_localhost(const char *hostname); + +static inline bool is_gateway_hostname(const char *hostname) { + /* This tries to identify the valid syntaxes for the our synthetic "gateway" host. */ + return STRCASE_IN_SET(hostname, "_gateway", "_gateway."); +} diff --git a/src/libnm-systemd-shared/src/basic/in-addr-util.c b/src/libnm-systemd-shared/src/basic/in-addr-util.c new file mode 100644 index 0000000..c315dcb --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/in-addr-util.c @@ -0,0 +1,792 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "errno-util.h" +#include "in-addr-util.h" +#include "macro.h" +#include "parse-util.h" +#include "random-util.h" +#include "string-util.h" +#include "strxcpyx.h" +#include "util.h" + +bool in4_addr_is_null(const struct in_addr *a) { + assert(a); + + return a->s_addr == 0; +} + +int in_addr_is_null(int family, const union in_addr_union *u) { + assert(u); + + if (family == AF_INET) + return in4_addr_is_null(&u->in); + + if (family == AF_INET6) + return IN6_IS_ADDR_UNSPECIFIED(&u->in6); + + return -EAFNOSUPPORT; +} + +bool in4_addr_is_link_local(const struct in_addr *a) { + assert(a); + + return (be32toh(a->s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16); +} + +int in_addr_is_link_local(int family, const union in_addr_union *u) { + assert(u); + + if (family == AF_INET) + return in4_addr_is_link_local(&u->in); + + if (family == AF_INET6) + return IN6_IS_ADDR_LINKLOCAL(&u->in6); + + return -EAFNOSUPPORT; +} + +bool in6_addr_is_link_local_all_nodes(const struct in6_addr *a) { + assert(a); + + /* ff02::1 */ + return be32toh(a->s6_addr32[0]) == UINT32_C(0xff020000) && + a->s6_addr32[1] == 0 && + a->s6_addr32[2] == 0 && + be32toh(a->s6_addr32[3]) == UINT32_C(0x00000001); +} + +int in_addr_is_multicast(int family, const union in_addr_union *u) { + assert(u); + + if (family == AF_INET) + return IN_MULTICAST(be32toh(u->in.s_addr)); + + if (family == AF_INET6) + return IN6_IS_ADDR_MULTICAST(&u->in6); + + return -EAFNOSUPPORT; +} + +bool in4_addr_is_local_multicast(const struct in_addr *a) { + assert(a); + + return (be32toh(a->s_addr) & UINT32_C(0xffffff00)) == UINT32_C(0xe0000000); +} + +bool in4_addr_is_localhost(const struct in_addr *a) { + assert(a); + + /* All of 127.x.x.x is localhost. */ + return (be32toh(a->s_addr) & UINT32_C(0xFF000000)) == UINT32_C(127) << 24; +} + +bool in4_addr_is_non_local(const struct in_addr *a) { + /* Whether the address is not null and not localhost. + * + * As such, it is suitable to configure as DNS/NTP server from DHCP. */ + return !in4_addr_is_null(a) && + !in4_addr_is_localhost(a); +} + +int in_addr_is_localhost(int family, const union in_addr_union *u) { + assert(u); + + if (family == AF_INET) + return in4_addr_is_localhost(&u->in); + + if (family == AF_INET6) + return IN6_IS_ADDR_LOOPBACK(&u->in6); + + return -EAFNOSUPPORT; +} + +bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b) { + assert(a); + assert(b); + + return a->s_addr == b->s_addr; +} + +int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b) { + assert(a); + assert(b); + + if (family == AF_INET) + return in4_addr_equal(&a->in, &b->in); + + if (family == AF_INET6) + return IN6_ARE_ADDR_EQUAL(&a->in6, &b->in6); + + return -EAFNOSUPPORT; +} + +#if 0 /* NM_IGNORED */ +int in_addr_prefix_intersect( + int family, + const union in_addr_union *a, + unsigned aprefixlen, + const union in_addr_union *b, + unsigned bprefixlen) { + + unsigned m; + + assert(a); + assert(b); + + /* Checks whether there are any addresses that are in both + * networks */ + + m = MIN(aprefixlen, bprefixlen); + + if (family == AF_INET) { + uint32_t x, nm; + + x = be32toh(a->in.s_addr ^ b->in.s_addr); + nm = (m == 0) ? 0 : 0xFFFFFFFFUL << (32 - m); + + return (x & nm) == 0; + } + + if (family == AF_INET6) { + unsigned i; + + if (m > 128) + m = 128; + + for (i = 0; i < 16; i++) { + uint8_t x, nm; + + x = a->in6.s6_addr[i] ^ b->in6.s6_addr[i]; + + if (m < 8) + nm = 0xFF << (8 - m); + else + nm = 0xFF; + + if ((x & nm) != 0) + return 0; + + if (m > 8) + m -= 8; + else + m = 0; + } + + return 1; + } + + return -EAFNOSUPPORT; +} + +int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen) { + assert(u); + + /* Increases the network part of an address by one. Returns + * positive if that succeeds, or -ERANGE if this overflows. */ + + return in_addr_prefix_nth(family, u, prefixlen, 1); +} + +/* + * Calculates the nth prefix of size prefixlen starting from the address denoted by u. + * + * On success 1 will be returned and the calculated prefix will be available in + * u. In the case nth == 0 the input will be left unchanged and 1 will be returned. + * In case the calculation cannot be performed (invalid prefix length, + * overflows would occur) -ERANGE is returned. If the address family given isn't + * supported -EAFNOSUPPORT will be returned. + * + * + * Examples: + * - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 2), returns 1, writes 192.168.2.0 to u + * - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 0), returns 1, no data written + * - in_addr_prefix_nth(AF_INET, 255.255.255.0, 24, 1), returns -ERANGE, no data written + * - in_addr_prefix_nth(AF_INET, 255.255.255.0, 0, 1), returns -ERANGE, no data written + * - in_addr_prefix_nth(AF_INET6, 2001:db8, 64, 0xff00) returns 1, writes 2001:0db8:0000:ff00:: to u + */ +int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth) { + assert(u); + + if (prefixlen <= 0) + return -ERANGE; + + if (nth == 0) + return 1; + + if (family == AF_INET) { + uint32_t c, n, t; + if (prefixlen > 32) + prefixlen = 32; + + c = be32toh(u->in.s_addr); + + t = nth << (32 - prefixlen); + + /* Check for wrap */ + if (c > UINT32_MAX - t) + return -ERANGE; + + n = c + t; + + n &= UINT32_C(0xFFFFFFFF) << (32 - prefixlen); + u->in.s_addr = htobe32(n); + return 1; + } + + if (family == AF_INET6) { + struct in6_addr result = {}; + uint8_t overflow = 0; + uint64_t delta; /* this assumes that we only ever have to up to 1<<64 subnets */ + unsigned start_byte = (prefixlen - 1) / 8; + + if (prefixlen > 128) + prefixlen = 128; + + /* First calculate what we have to add */ + delta = nth << ((128 - prefixlen) % 8); + + for (unsigned i = 16; i > 0; i--) { + unsigned j = i - 1; + unsigned d = 0; + + if (j <= start_byte) { + int16_t t; + + d = delta & 0xFF; + delta >>= 8; + + t = u->in6.s6_addr[j] + d + overflow; + overflow = t > UINT8_MAX ? t - UINT8_MAX : 0; + + result.s6_addr[j] = (uint8_t)t; + } else + result.s6_addr[j] = u->in6.s6_addr[j]; + } + + if (overflow || delta != 0) + return -ERANGE; + + u->in6 = result; + return 1; + } + + return -EAFNOSUPPORT; +} + +int in_addr_random_prefix( + int family, + union in_addr_union *u, + unsigned prefixlen_fixed_part, + unsigned prefixlen) { + + assert(u); + + /* Random network part of an address by one. */ + + if (prefixlen <= 0) + return 0; + + if (family == AF_INET) { + uint32_t c, n; + + if (prefixlen_fixed_part > 32) + prefixlen_fixed_part = 32; + if (prefixlen > 32) + prefixlen = 32; + if (prefixlen_fixed_part >= prefixlen) + return -EINVAL; + + c = be32toh(u->in.s_addr); + c &= ((UINT32_C(1) << prefixlen_fixed_part) - 1) << (32 - prefixlen_fixed_part); + + random_bytes(&n, sizeof(n)); + n &= ((UINT32_C(1) << (prefixlen - prefixlen_fixed_part)) - 1) << (32 - prefixlen); + + u->in.s_addr = htobe32(n | c); + return 1; + } + + if (family == AF_INET6) { + struct in6_addr n; + unsigned i, j; + + if (prefixlen_fixed_part > 128) + prefixlen_fixed_part = 128; + if (prefixlen > 128) + prefixlen = 128; + if (prefixlen_fixed_part >= prefixlen) + return -EINVAL; + + random_bytes(&n, sizeof(n)); + + for (i = 0; i < 16; i++) { + uint8_t mask_fixed_part = 0, mask = 0; + + if (i < (prefixlen_fixed_part + 7) / 8) { + if (i < prefixlen_fixed_part / 8) + mask_fixed_part = 0xffu; + else { + j = prefixlen_fixed_part % 8; + mask_fixed_part = ((UINT8_C(1) << (j + 1)) - 1) << (8 - j); + } + } + + if (i < (prefixlen + 7) / 8) { + if (i < prefixlen / 8) + mask = 0xffu ^ mask_fixed_part; + else { + j = prefixlen % 8; + mask = (((UINT8_C(1) << (j + 1)) - 1) << (8 - j)) ^ mask_fixed_part; + } + } + + u->in6.s6_addr[i] &= mask_fixed_part; + u->in6.s6_addr[i] |= n.s6_addr[i] & mask; + } + + return 1; + } + + return -EAFNOSUPPORT; +} +#endif /* NM_IGNORED */ + +int in_addr_to_string(int family, const union in_addr_union *u, char **ret) { + _cleanup_free_ char *x = NULL; + size_t l; + + assert(u); + assert(ret); + + if (family == AF_INET) + l = INET_ADDRSTRLEN; + else if (family == AF_INET6) + l = INET6_ADDRSTRLEN; + else + return -EAFNOSUPPORT; + + x = new(char, l); + if (!x) + return -ENOMEM; + + errno = 0; + if (!inet_ntop(family, u, x, l)) + return errno_or_else(EINVAL); + + *ret = TAKE_PTR(x); + return 0; +} + +#if 0 /* NM_IGNORED */ +int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned prefixlen, char **ret) { + _cleanup_free_ char *x = NULL; + char *p; + size_t l; + + assert(u); + assert(ret); + + if (family == AF_INET) + l = INET_ADDRSTRLEN + 3; + else if (family == AF_INET6) + l = INET6_ADDRSTRLEN + 4; + else + return -EAFNOSUPPORT; + + if (prefixlen > FAMILY_ADDRESS_SIZE(family) * 8) + return -EINVAL; + + x = new(char, l); + if (!x) + return -ENOMEM; + + errno = 0; + if (!inet_ntop(family, u, x, l)) + return errno_or_else(EINVAL); + + p = x + strlen(x); + l -= strlen(x); + (void) strpcpyf(&p, l, "/%u", prefixlen); + + *ret = TAKE_PTR(x); + return 0; +} +#endif /* NM_IGNORED */ + +int in_addr_port_ifindex_name_to_string(int family, const union in_addr_union *u, uint16_t port, int ifindex, const char *server_name, char **ret) { + _cleanup_free_ char *ip_str = NULL, *x = NULL; + int r; + + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(u); + assert(ret); + + /* Much like in_addr_to_string(), but optionally appends the zone interface index to the address, to properly + * handle IPv6 link-local addresses. */ + + r = in_addr_to_string(family, u, &ip_str); + if (r < 0) + return r; + + if (family == AF_INET6) { + r = in_addr_is_link_local(family, u); + if (r < 0) + return r; + if (r == 0) + ifindex = 0; + } else + ifindex = 0; /* For IPv4 address, ifindex is always ignored. */ + + if (port == 0 && ifindex == 0 && isempty(server_name)) { + *ret = TAKE_PTR(ip_str); + return 0; + } + + const char *separator = isempty(server_name) ? "" : "#"; + server_name = strempty(server_name); + + if (port > 0) { + if (family == AF_INET6) { + if (ifindex > 0) + r = asprintf(&x, "[%s]:%"PRIu16"%%%i%s%s", ip_str, port, ifindex, separator, server_name); + else + r = asprintf(&x, "[%s]:%"PRIu16"%s%s", ip_str, port, separator, server_name); + } else + r = asprintf(&x, "%s:%"PRIu16"%s%s", ip_str, port, separator, server_name); + } else { + if (ifindex > 0) + r = asprintf(&x, "%s%%%i%s%s", ip_str, ifindex, separator, server_name); + else { + x = strjoin(ip_str, separator, server_name); + r = x ? 0 : -ENOMEM; + } + } + if (r < 0) + return -ENOMEM; + + *ret = TAKE_PTR(x); + return 0; +} + +int in_addr_from_string(int family, const char *s, union in_addr_union *ret) { + union in_addr_union buffer; + assert(s); + + if (!IN_SET(family, AF_INET, AF_INET6)) + return -EAFNOSUPPORT; + + errno = 0; + if (inet_pton(family, s, ret ?: &buffer) <= 0) + return errno_or_else(EINVAL); + + return 0; +} + +int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret) { + int r; + + assert(s); + + r = in_addr_from_string(AF_INET, s, ret); + if (r >= 0) { + if (ret_family) + *ret_family = AF_INET; + return 0; + } + + r = in_addr_from_string(AF_INET6, s, ret); + if (r >= 0) { + if (ret_family) + *ret_family = AF_INET6; + return 0; + } + + return -EINVAL; +} + +unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr) { + assert(addr); + + return 32U - u32ctz(be32toh(addr->s_addr)); +} + +struct in_addr* in4_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen) { + assert(addr); + assert(prefixlen <= 32); + + /* Shifting beyond 32 is not defined, handle this specially. */ + if (prefixlen == 0) + addr->s_addr = 0; + else + addr->s_addr = htobe32((0xffffffff << (32 - prefixlen)) & 0xffffffff); + + return addr; +} + +int in4_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen) { + uint8_t msb_octet = *(uint8_t*) addr; + + /* addr may not be aligned, so make sure we only access it byte-wise */ + + assert(addr); + assert(prefixlen); + + if (msb_octet < 128) + /* class A, leading bits: 0 */ + *prefixlen = 8; + else if (msb_octet < 192) + /* class B, leading bits 10 */ + *prefixlen = 16; + else if (msb_octet < 224) + /* class C, leading bits 110 */ + *prefixlen = 24; + else + /* class D or E, no default prefixlen */ + return -ERANGE; + + return 0; +} + +int in4_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask) { + unsigned char prefixlen; + int r; + + assert(addr); + assert(mask); + + r = in4_addr_default_prefixlen(addr, &prefixlen); + if (r < 0) + return r; + + in4_addr_prefixlen_to_netmask(mask, prefixlen); + return 0; +} + +#if 0 /* NM_IGNORED */ +int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen) { + assert(addr); + + if (family == AF_INET) { + struct in_addr mask; + + if (!in4_addr_prefixlen_to_netmask(&mask, prefixlen)) + return -EINVAL; + + addr->in.s_addr &= mask.s_addr; + return 0; + } + + if (family == AF_INET6) { + unsigned i; + + for (i = 0; i < 16; i++) { + uint8_t mask; + + if (prefixlen >= 8) { + mask = 0xFF; + prefixlen -= 8; + } else { + mask = 0xFF << (8 - prefixlen); + prefixlen = 0; + } + + addr->in6.s6_addr[i] &= mask; + } + + return 0; + } + + return -EAFNOSUPPORT; +} + +int in_addr_prefix_covers(int family, + const union in_addr_union *prefix, + unsigned char prefixlen, + const union in_addr_union *address) { + + union in_addr_union masked_prefix, masked_address; + int r; + + assert(prefix); + assert(address); + + masked_prefix = *prefix; + r = in_addr_mask(family, &masked_prefix, prefixlen); + if (r < 0) + return r; + + masked_address = *address; + r = in_addr_mask(family, &masked_address, prefixlen); + if (r < 0) + return r; + + return in_addr_equal(family, &masked_prefix, &masked_address); +} + +int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret) { + uint8_t u; + int r; + + if (!IN_SET(family, AF_INET, AF_INET6)) + return -EAFNOSUPPORT; + + r = safe_atou8(p, &u); + if (r < 0) + return r; + + if (u > FAMILY_ADDRESS_SIZE(family) * 8) + return -ERANGE; + + *ret = u; + return 0; +} + +int in_addr_prefix_from_string( + const char *p, + int family, + union in_addr_union *ret_prefix, + unsigned char *ret_prefixlen) { + + _cleanup_free_ char *str = NULL; + union in_addr_union buffer; + const char *e, *l; + unsigned char k; + int r; + + assert(p); + + if (!IN_SET(family, AF_INET, AF_INET6)) + return -EAFNOSUPPORT; + + e = strchr(p, '/'); + if (e) { + str = strndup(p, e - p); + if (!str) + return -ENOMEM; + + l = str; + } else + l = p; + + r = in_addr_from_string(family, l, &buffer); + if (r < 0) + return r; + + if (e) { + r = in_addr_parse_prefixlen(family, e+1, &k); + if (r < 0) + return r; + } else + k = FAMILY_ADDRESS_SIZE(family) * 8; + + if (ret_prefix) + *ret_prefix = buffer; + if (ret_prefixlen) + *ret_prefixlen = k; + + return 0; +} + +int in_addr_prefix_from_string_auto_internal( + const char *p, + InAddrPrefixLenMode mode, + int *ret_family, + union in_addr_union *ret_prefix, + unsigned char *ret_prefixlen) { + + _cleanup_free_ char *str = NULL; + union in_addr_union buffer; + const char *e, *l; + unsigned char k; + int family, r; + + assert(p); + + e = strchr(p, '/'); + if (e) { + str = strndup(p, e - p); + if (!str) + return -ENOMEM; + + l = str; + } else + l = p; + + r = in_addr_from_string_auto(l, &family, &buffer); + if (r < 0) + return r; + + if (e) { + r = in_addr_parse_prefixlen(family, e+1, &k); + if (r < 0) + return r; + } else + switch (mode) { + case PREFIXLEN_FULL: + k = FAMILY_ADDRESS_SIZE(family) * 8; + break; + case PREFIXLEN_REFUSE: + return -ENOANO; /* To distinguish this error from others. */ + case PREFIXLEN_LEGACY: + if (family == AF_INET) { + r = in4_addr_default_prefixlen(&buffer.in, &k); + if (r < 0) + return r; + } else + k = 0; + break; + default: + assert_not_reached("Invalid prefixlen mode"); + } + + if (ret_family) + *ret_family = family; + if (ret_prefix) + *ret_prefix = buffer; + if (ret_prefixlen) + *ret_prefixlen = k; + + return 0; + +} + +static void in_addr_data_hash_func(const struct in_addr_data *a, struct siphash *state) { + siphash24_compress(&a->family, sizeof(a->family), state); + siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state); +} + +static int in_addr_data_compare_func(const struct in_addr_data *x, const struct in_addr_data *y) { + int r; + + r = CMP(x->family, y->family); + if (r != 0) + return r; + + return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family)); +} + +DEFINE_HASH_OPS(in_addr_data_hash_ops, struct in_addr_data, in_addr_data_hash_func, in_addr_data_compare_func); + +void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state) { + assert(addr); + + siphash24_compress(addr, sizeof(*addr), state); +} + +int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b) { + return memcmp(a, b, sizeof(*a)); +} + +DEFINE_HASH_OPS(in6_addr_hash_ops, struct in6_addr, in6_addr_hash_func, in6_addr_compare_func); +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/in-addr-util.h b/src/libnm-systemd-shared/src/basic/in-addr-util.h new file mode 100644 index 0000000..24308b7 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/in-addr-util.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include + +#include "hash-funcs.h" +#include "macro.h" +#include "util.h" + +union in_addr_union { + struct in_addr in; + struct in6_addr in6; + uint8_t bytes[CONST_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))]; +}; + +struct in_addr_data { + int family; + union in_addr_union address; +}; + +bool in4_addr_is_null(const struct in_addr *a); +int in_addr_is_null(int family, const union in_addr_union *u); + +int in_addr_is_multicast(int family, const union in_addr_union *u); + +bool in4_addr_is_link_local(const struct in_addr *a); +int in_addr_is_link_local(int family, const union in_addr_union *u); +bool in6_addr_is_link_local_all_nodes(const struct in6_addr *a); + +bool in4_addr_is_localhost(const struct in_addr *a); +int in_addr_is_localhost(int family, const union in_addr_union *u); + +bool in4_addr_is_local_multicast(const struct in_addr *a); +bool in4_addr_is_non_local(const struct in_addr *a); + +bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b); +int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b); +int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen); +int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); +int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth); +int in_addr_random_prefix(int family, union in_addr_union *u, unsigned prefixlen_fixed_part, unsigned prefixlen); +int in_addr_to_string(int family, const union in_addr_union *u, char **ret); +int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned prefixlen, char **ret); +int in_addr_port_ifindex_name_to_string(int family, const union in_addr_union *u, uint16_t port, int ifindex, const char *server_name, char **ret); +static inline int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret) { + return in_addr_port_ifindex_name_to_string(family, u, 0, ifindex, NULL, ret); +} +static inline int in_addr_port_to_string(int family, const union in_addr_union *u, uint16_t port, char **ret) { + return in_addr_port_ifindex_name_to_string(family, u, port, 0, NULL, ret); +} +int in_addr_from_string(int family, const char *s, union in_addr_union *ret); +int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret); + +unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr); +struct in_addr* in4_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen); +int in4_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen); +int in4_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask); +int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen); +int in_addr_prefix_covers(int family, const union in_addr_union *prefix, unsigned char prefixlen, const union in_addr_union *address); +int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret); +int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen); + +typedef enum InAddrPrefixLenMode { + PREFIXLEN_FULL, /* Default to prefixlen of address size, 32 for IPv4 or 128 for IPv6, if not specified. */ + PREFIXLEN_REFUSE, /* Fail with -ENOANO if prefixlen is not specified. */ + PREFIXLEN_LEGACY, /* Default to legacy default prefixlen calculation from address if not specified. */ +} InAddrPrefixLenMode; + +int in_addr_prefix_from_string_auto_internal(const char *p, InAddrPrefixLenMode mode, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen); +static inline int in_addr_prefix_from_string_auto(const char *p, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) { + return in_addr_prefix_from_string_auto_internal(p, PREFIXLEN_FULL, ret_family, ret_prefix, ret_prefixlen); +} + +static inline size_t FAMILY_ADDRESS_SIZE(int family) { + assert(IN_SET(family, AF_INET, AF_INET6)); + return family == AF_INET6 ? 16 : 4; +} + +/* Workaround for clang, explicitly specify the maximum-size element here. + * See also oss-fuzz#11344. */ +#define IN_ADDR_NULL ((union in_addr_union) { .in6 = {} }) + +void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state); +int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b); + +extern const struct hash_ops in_addr_data_hash_ops; +extern const struct hash_ops in6_addr_hash_ops; diff --git a/src/libnm-systemd-shared/src/basic/io-util.c b/src/libnm-systemd-shared/src/basic/io-util.c new file mode 100644 index 0000000..f09c7fd --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/io-util.c @@ -0,0 +1,343 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include + +#include "io-util.h" +#include "string-util.h" +#include "time-util.h" + +#if 0 /* NM_IGNORED */ +int flush_fd(int fd) { + int count = 0; + + /* Read from the specified file descriptor, until POLLIN is not set anymore, throwing away everything + * read. Note that some file descriptors (notable IP sockets) will trigger POLLIN even when no data can be read + * (due to IP packet checksum mismatches), hence this function is only safe to be non-blocking if the fd used + * was set to non-blocking too. */ + + for (;;) { + char buf[LINE_MAX]; + ssize_t l; + int r; + + r = fd_wait_for_event(fd, POLLIN, 0); + if (r < 0) { + if (r == -EINTR) + continue; + + return r; + } + if (r == 0) + return count; + + l = read(fd, buf, sizeof(buf)); + if (l < 0) { + if (errno == EINTR) + continue; + + if (errno == EAGAIN) + return count; + + return -errno; + } else if (l == 0) + return count; + + count += (int) l; + } +} +#endif /* NM_IGNORED */ + +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { + uint8_t *p = buf; + ssize_t n = 0; + + assert(fd >= 0); + assert(buf); + + /* If called with nbytes == 0, let's call read() at least + * once, to validate the operation */ + + if (nbytes > (size_t) SSIZE_MAX) + return -EINVAL; + + do { + ssize_t k; + + k = read(fd, p, nbytes); + if (k < 0) { + if (errno == EINTR) + continue; + + if (errno == EAGAIN && do_poll) { + + /* We knowingly ignore any return value here, + * and expect that any error/EOF is reported + * via read() */ + + (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY); + continue; + } + + return n > 0 ? n : -errno; + } + + if (k == 0) + return n; + + assert((size_t) k <= nbytes); + + p += k; + nbytes -= k; + n += k; + } while (nbytes > 0); + + return n; +} + +int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) { + ssize_t n; + + n = loop_read(fd, buf, nbytes, do_poll); + if (n < 0) + return (int) n; + if ((size_t) n != nbytes) + return -EIO; + + return 0; +} + +#if 0 /* NM_IGNORED */ +int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { + const uint8_t *p = buf; + + assert(fd >= 0); + assert(buf); + + if (_unlikely_(nbytes > (size_t) SSIZE_MAX)) + return -EINVAL; + + do { + ssize_t k; + + k = write(fd, p, nbytes); + if (k < 0) { + if (errno == EINTR) + continue; + + if (errno == EAGAIN && do_poll) { + /* We knowingly ignore any return value here, + * and expect that any error/EOF is reported + * via write() */ + + (void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY); + continue; + } + + return -errno; + } + + if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */ + return -EIO; + + assert((size_t) k <= nbytes); + + p += k; + nbytes -= k; + } while (nbytes > 0); + + return 0; +} + +int pipe_eof(int fd) { + int r; + + r = fd_wait_for_event(fd, POLLIN, 0); + if (r <= 0) + return r; + + return !!(r & POLLHUP); +} +#endif /* NM_IGNORED */ + +int fd_wait_for_event(int fd, int event, usec_t t) { + + struct pollfd pollfd = { + .fd = fd, + .events = event, + }; + + struct timespec ts; + int r; + + r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL); + if (r < 0) + return -errno; + if (r == 0) + return 0; + + if (pollfd.revents & POLLNVAL) + return -EBADF; + + return pollfd.revents; +} + +#if 0 /* NM_IGNORED */ +static size_t nul_length(const uint8_t *p, size_t sz) { + size_t n = 0; + + while (sz > 0) { + if (*p != 0) + break; + + n++; + p++; + sz--; + } + + return n; +} + +ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) { + const uint8_t *q, *w, *e; + ssize_t l; + + q = w = p; + e = q + sz; + while (q < e) { + size_t n; + + n = nul_length(q, e - q); + + /* If there are more than the specified run length of + * NUL bytes, or if this is the beginning or the end + * of the buffer, then seek instead of write */ + if ((n > run_length) || + (n > 0 && q == p) || + (n > 0 && q + n >= e)) { + if (q > w) { + l = write(fd, w, q - w); + if (l < 0) + return -errno; + if (l != q -w) + return -EIO; + } + + if (lseek(fd, n, SEEK_CUR) == (off_t) -1) + return -errno; + + q += n; + w = q; + } else if (n > 0) + q += n; + else + q++; + } + + if (q > w) { + l = write(fd, w, q - w); + if (l < 0) + return -errno; + if (l != q - w) + return -EIO; + } + + return q - (const uint8_t*) p; +} + +char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value) { + char *x; + + x = strjoin(field, value); + if (x) + iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(x); + return x; +} + +char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const char *field, char *value) { + char *x; + + x = set_iovec_string_field(iovec, n_iovec, field, value); + free(value); + return x; +} + +struct iovec_wrapper *iovw_new(void) { + return malloc0(sizeof(struct iovec_wrapper)); +} + +void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors) { + if (free_vectors) + for (size_t i = 0; i < iovw->count; i++) + free(iovw->iovec[i].iov_base); + + iovw->iovec = mfree(iovw->iovec); + iovw->count = 0; + iovw->size_bytes = 0; +} + +struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw) { + iovw_free_contents(iovw, true); + + return mfree(iovw); +} + +struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw) { + iovw_free_contents(iovw, false); + + return mfree(iovw); +} + +int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len) { + if (iovw->count >= IOV_MAX) + return -E2BIG; + + if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1)) + return -ENOMEM; + + iovw->iovec[iovw->count++] = IOVEC_MAKE(data, len); + return 0; +} + +int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const char *value) { + _cleanup_free_ char *x = NULL; + int r; + + x = strjoin(field, value); + if (!x) + return -ENOMEM; + + r = iovw_put(iovw, x, strlen(x)); + if (r >= 0) + TAKE_PTR(x); + + return r; +} + +int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value) { + _cleanup_free_ _unused_ char *free_ptr = value; + + return iovw_put_string_field(iovw, field, value); +} + +void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new) { + size_t i; + + for (i = 0; i < iovw->count; i++) + iovw->iovec[i].iov_base = (char *)iovw->iovec[i].iov_base - old + new; +} + +size_t iovw_size(struct iovec_wrapper *iovw) { + size_t n = 0, i; + + for (i = 0; i < iovw->count; i++) + n += iovw->iovec[i].iov_len; + + return n; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/io-util.h b/src/libnm-systemd-shared/src/basic/io-util.h new file mode 100644 index 0000000..d817714 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/io-util.h @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include + +#include "macro.h" +#include "time-util.h" + +int flush_fd(int fd); + +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll); +int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll); +int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll); + +int pipe_eof(int fd); + +int fd_wait_for_event(int fd, int event, usec_t timeout); + +ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length); + +static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, size_t n) { + size_t j, r = 0; + + for (j = 0; j < n; j++) + r += i[j].iov_len; + + return r; +} + +static inline size_t IOVEC_INCREMENT(struct iovec *i, size_t n, size_t k) { + size_t j; + + for (j = 0; j < n; j++) { + size_t sub; + + if (_unlikely_(k <= 0)) + break; + + sub = MIN(i[j].iov_len, k); + i[j].iov_len -= sub; + i[j].iov_base = (uint8_t*) i[j].iov_base + sub; + k -= sub; + } + + return k; +} + +static inline bool FILE_SIZE_VALID(uint64_t l) { + /* ftruncate() and friends take an unsigned file size, but actually cannot deal with file sizes larger than + * 2^63 since the kernel internally handles it as signed value. This call allows checking for this early. */ + + return (l >> 63) == 0; +} + +static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) { + + /* Same as above, but allows one extra value: -1 as indication for infinity. */ + + if (l == (uint64_t) -1) + return true; + + return FILE_SIZE_VALID(l); + +} + +#define IOVEC_INIT(base, len) { .iov_base = (base), .iov_len = (len) } +#define IOVEC_MAKE(base, len) (struct iovec) IOVEC_INIT(base, len) +#define IOVEC_INIT_STRING(string) IOVEC_INIT((char*) string, strlen(string)) +#define IOVEC_MAKE_STRING(string) (struct iovec) IOVEC_INIT_STRING(string) + +char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value); +char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const char *field, char *value); + +struct iovec_wrapper { + struct iovec *iovec; + size_t count; + size_t size_bytes; +}; + +struct iovec_wrapper *iovw_new(void); +struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw); +struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw); +void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors); +int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len); +int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const char *value); +int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value); +void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new); +size_t iovw_size(struct iovec_wrapper *iovw); diff --git a/src/libnm-systemd-shared/src/basic/list.h b/src/libnm-systemd-shared/src/basic/list.h new file mode 100644 index 0000000..256b718 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/list.h @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "macro.h" + +/* The head of the linked list. Use this in the structure that shall + * contain the head of the linked list */ +#define LIST_HEAD(t,name) \ + t *name + +/* The pointers in the linked list's items. Use this in the item structure */ +#define LIST_FIELDS(t,name) \ + t *name##_next, *name##_prev + +/* Initialize the list's head */ +#define LIST_HEAD_INIT(head) \ + do { \ + (head) = NULL; \ + } while (false) + +/* Initialize a list item */ +#define LIST_INIT(name,item) \ + do { \ + typeof(*(item)) *_item = (item); \ + assert(_item); \ + _item->name##_prev = _item->name##_next = NULL; \ + } while (false) + +/* Prepend an item to the list */ +#define LIST_PREPEND(name,head,item) \ + do { \ + typeof(*(head)) **_head = &(head), *_item = (item); \ + assert(_item); \ + if ((_item->name##_next = *_head)) \ + _item->name##_next->name##_prev = _item; \ + _item->name##_prev = NULL; \ + *_head = _item; \ + } while (false) + +/* Append an item to the list */ +#define LIST_APPEND(name,head,item) \ + do { \ + typeof(*(head)) **_hhead = &(head), *_tail; \ + LIST_FIND_TAIL(name, *_hhead, _tail); \ + LIST_INSERT_AFTER(name, *_hhead, _tail, item); \ + } while (false) + +/* Remove an item from the list */ +#define LIST_REMOVE(name,head,item) \ + do { \ + typeof(*(head)) **_head = &(head), *_item = (item); \ + assert(_item); \ + if (_item->name##_next) \ + _item->name##_next->name##_prev = _item->name##_prev; \ + if (_item->name##_prev) \ + _item->name##_prev->name##_next = _item->name##_next; \ + else { \ + assert(*_head == _item); \ + *_head = _item->name##_next; \ + } \ + _item->name##_next = _item->name##_prev = NULL; \ + } while (false) + +/* Find the head of the list */ +#define LIST_FIND_HEAD(name,item,head) \ + do { \ + typeof(*(item)) *_item = (item); \ + if (!_item) \ + (head) = NULL; \ + else { \ + while (_item->name##_prev) \ + _item = _item->name##_prev; \ + (head) = _item; \ + } \ + } while (false) + +/* Find the tail of the list */ +#define LIST_FIND_TAIL(name,item,tail) \ + do { \ + typeof(*(item)) *_item = (item); \ + if (!_item) \ + (tail) = NULL; \ + else { \ + while (_item->name##_next) \ + _item = _item->name##_next; \ + (tail) = _item; \ + } \ + } while (false) + +/* Insert an item after another one (a = where, b = what) */ +#define LIST_INSERT_AFTER(name,head,a,b) \ + do { \ + typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \ + assert(_b); \ + if (!_a) { \ + if ((_b->name##_next = *_head)) \ + _b->name##_next->name##_prev = _b; \ + _b->name##_prev = NULL; \ + *_head = _b; \ + } else { \ + if ((_b->name##_next = _a->name##_next)) \ + _b->name##_next->name##_prev = _b; \ + _b->name##_prev = _a; \ + _a->name##_next = _b; \ + } \ + } while (false) + +/* Insert an item before another one (a = where, b = what) */ +#define LIST_INSERT_BEFORE(name,head,a,b) \ + do { \ + typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \ + assert(_b); \ + if (!_a) { \ + if (!*_head) { \ + _b->name##_next = NULL; \ + _b->name##_prev = NULL; \ + *_head = _b; \ + } else { \ + typeof(*(head)) *_tail = (head); \ + while (_tail->name##_next) \ + _tail = _tail->name##_next; \ + _b->name##_next = NULL; \ + _b->name##_prev = _tail; \ + _tail->name##_next = _b; \ + } \ + } else { \ + if ((_b->name##_prev = _a->name##_prev)) \ + _b->name##_prev->name##_next = _b; \ + else \ + *_head = _b; \ + _b->name##_next = _a; \ + _a->name##_prev = _b; \ + } \ + } while (false) + +#define LIST_JUST_US(name,item) \ + (!(item)->name##_prev && !(item)->name##_next) \ + +#define LIST_FOREACH(name,i,head) \ + for ((i) = (head); (i); (i) = (i)->name##_next) + +#define LIST_FOREACH_SAFE(name,i,n,head) \ + for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n)) + +#define LIST_FOREACH_BEFORE(name,i,p) \ + for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev) + +#define LIST_FOREACH_AFTER(name,i,p) \ + for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next) + +/* Iterate through all the members of the list p is included in, but skip over p */ +#define LIST_FOREACH_OTHERS(name,i,p) \ + for (({ \ + (i) = (p); \ + while ((i) && (i)->name##_prev) \ + (i) = (i)->name##_prev; \ + if ((i) == (p)) \ + (i) = (p)->name##_next; \ + }); \ + (i); \ + (i) = (i)->name##_next == (p) ? (p)->name##_next : (i)->name##_next) + +/* Loop starting from p->next until p->prev. + p can be adjusted meanwhile. */ +#define LIST_LOOP_BUT_ONE(name,i,head,p) \ + for ((i) = (p)->name##_next ? (p)->name##_next : (head); \ + (i) != (p); \ + (i) = (i)->name##_next ? (i)->name##_next : (head)) + +#define LIST_IS_EMPTY(head) \ + (!(head)) + +/* Join two lists tail to head: a->b, c->d to a->b->c->d and de-initialise second list */ +#define LIST_JOIN(name,a,b) \ + do { \ + assert(b); \ + if (!(a)) \ + (a) = (b); \ + else { \ + typeof(*(a)) *_head = (b), *_tail; \ + LIST_FIND_TAIL(name, (a), _tail); \ + _tail->name##_next = _head; \ + _head->name##_prev = _tail; \ + } \ + (b) = NULL; \ + } while (false) diff --git a/src/libnm-systemd-shared/src/basic/log.h b/src/libnm-systemd-shared/src/basic/log.h new file mode 100644 index 0000000..ee2e483 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/log.h @@ -0,0 +1,401 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include + +#include "macro.h" + +/* Some structures we reference but don't want to pull in headers for */ +struct iovec; +struct signalfd_siginfo; + +typedef enum LogRealm { + LOG_REALM_SYSTEMD, + LOG_REALM_UDEV, + _LOG_REALM_MAX, +} LogRealm; + +#ifndef LOG_REALM +# define LOG_REALM LOG_REALM_SYSTEMD +#endif + +typedef enum LogTarget{ + LOG_TARGET_CONSOLE, + LOG_TARGET_CONSOLE_PREFIXED, + LOG_TARGET_KMSG, + LOG_TARGET_JOURNAL, + LOG_TARGET_JOURNAL_OR_KMSG, + LOG_TARGET_SYSLOG, + LOG_TARGET_SYSLOG_OR_KMSG, + LOG_TARGET_AUTO, /* console if stderr is not journal, JOURNAL_OR_KMSG otherwise */ + LOG_TARGET_NULL, + _LOG_TARGET_MAX, + _LOG_TARGET_INVALID = -1 +} LogTarget; + +/* Note to readers: << and >> have lower precedence than & and | */ +#define LOG_REALM_PLUS_LEVEL(realm, level) ((realm) << 10 | (level)) +#define LOG_REALM_REMOVE_LEVEL(realm_level) ((realm_level) >> 10) +#define SYNTHETIC_ERRNO(num) (1 << 30 | (num)) +#define IS_SYNTHETIC_ERRNO(val) ((val) >> 30 & 1) +#define ERRNO_VALUE(val) (abs(val) & 255) + +void log_set_target(LogTarget target); + +void log_set_max_level_realm(LogRealm realm, int level); + +#define log_set_max_level(level) \ + log_set_max_level_realm(LOG_REALM, (level)) + +static inline void log_set_max_level_all_realms(int level) { + for (LogRealm realm = 0; realm < _LOG_REALM_MAX; realm++) + log_set_max_level_realm(realm, level); +} + +void log_set_facility(int facility); + +int log_set_target_from_string(const char *e); +int log_set_max_level_from_string_realm(LogRealm realm, const char *e); +#define log_set_max_level_from_string(e) \ + log_set_max_level_from_string_realm(LOG_REALM, (e)) + +void log_show_color(bool b); +bool log_get_show_color(void) _pure_; +void log_show_location(bool b); +bool log_get_show_location(void) _pure_; +void log_show_time(bool b); +bool log_get_show_time(void) _pure_; +void log_show_tid(bool b); +bool log_get_show_tid(void) _pure_; + +int log_show_color_from_string(const char *e); +int log_show_location_from_string(const char *e); +int log_show_time_from_string(const char *e); +int log_show_tid_from_string(const char *e); + +LogTarget log_get_target(void) _pure_; +#if 0 /* NM_IGNORED */ +int log_get_max_level_realm(LogRealm realm) _pure_; +#endif /* NM_IGNORED */ +#define log_get_max_level() \ + log_get_max_level_realm(LOG_REALM) + +/* Functions below that open and close logs or configure logging based on the + * environment should not be called from library code — this is always a job + * for the application itself. + */ + +#if 0 /* NM_IGNORED */ +assert_cc(STRLEN(__FILE__) > STRLEN(RELATIVE_SOURCE_PATH) + 1); +#define PROJECT_FILE (&__FILE__[STRLEN(RELATIVE_SOURCE_PATH) + 1]) +#endif /* NM_IGNORED */ +#define PROJECT_FILE __FILE__ + +int log_open(void); +void log_close(void); +void log_forget_fds(void); + +void log_parse_environment_realm(LogRealm realm); +void log_parse_environment_cli_realm(LogRealm realm); +#define log_parse_environment() \ + log_parse_environment_realm(LOG_REALM) +#define log_parse_environment_cli() \ + log_parse_environment_cli_realm(LOG_REALM) + +#if 0 /* NM_IGNORED */ +int log_dispatch_internal( + int level, + int error, + const char *file, + int line, + const char *func, + const char *object_field, + const char *object, + const char *extra, + const char *extra_field, + char *buffer); + +int log_internal_realm( + int level, + int error, + const char *file, + int line, + const char *func, + const char *format, ...) _printf_(6,7); +#endif /* NM_IGNORED */ +#define log_internal(level, ...) \ + log_internal_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__) + +#define log_object_internal(level, \ + error, \ + file, \ + line, \ + func, \ + object_field, \ + object, \ + extra_field, \ + extra, \ + format, \ + ...) \ + ({ \ + const char *const _object = (object); \ + \ + log_internal_realm((level), \ + (error), \ + file, \ + (line), \ + (func), \ + "%s%s" format, \ + _object ?: "", \ + _object ? ": " : "", \ + ##__VA_ARGS__); \ + }) + +#if 0 /* NM_IGNORED */ +int log_internalv_realm( + int level, + int error, + const char *file, + int line, + const char *func, + const char *format, + va_list ap) _printf_(6,0); +#define log_internalv(level, ...) \ + log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__) + +/* Realm is fixed to LOG_REALM_SYSTEMD for those */ +int log_object_internalv( + int level, + int error, + const char *file, + int line, + const char *func, + const char *object_field, + const char *object, + const char *extra_field, + const char *extra, + const char *format, + va_list ap) _printf_(10,0); + +int log_object_internal( + int level, + int error, + const char *file, + int line, + const char *func, + const char *object_field, + const char *object, + const char *extra_field, + const char *extra, + const char *format, ...) _printf_(10,11); + +int log_struct_internal( + int level, + int error, + const char *file, + int line, + const char *func, + const char *format, ...) _printf_(6,0) _sentinel_; + +int log_oom_internal( + int level, + const char *file, + int line, + const char *func); +#endif /* NM_IGNORED */ +#define log_oom_internal(realm, file, line, func) \ + log_internal_realm (LOG_REALM_PLUS_LEVEL (realm, LOG_ERR), \ + ENOMEM, file, line, func, "Out of memory.") + +#if 0 /* NM_IGNORED */ +int log_format_iovec( + struct iovec *iovec, + size_t iovec_len, + size_t *n, + bool newline_separator, + int error, + const char *format, + va_list ap) _printf_(6, 0); + +int log_struct_iovec_internal( + int level, + int error, + const char *file, + int line, + const char *func, + const struct iovec *input_iovec, + size_t n_input_iovec); + +/* This modifies the buffer passed! */ +int log_dump_internal( + int level, + int error, + const char *file, + int line, + const char *func, + char *buffer); + +/* Logging for various assertions */ +_noreturn_ void log_assert_failed_realm( + LogRealm realm, + const char *text, + const char *file, + int line, + const char *func); +#define log_assert_failed(text, ...) \ + log_assert_failed_realm(LOG_REALM, (text), __VA_ARGS__) + +_noreturn_ void log_assert_failed_unreachable_realm( + LogRealm realm, + const char *text, + const char *file, + int line, + const char *func); +#define log_assert_failed_unreachable(text, ...) \ + log_assert_failed_unreachable_realm(LOG_REALM, (text), __VA_ARGS__) + +void log_assert_failed_return_realm( + LogRealm realm, + const char *text, + const char *file, + int line, + const char *func); +#define log_assert_failed_return(text, ...) \ + log_assert_failed_return_realm(LOG_REALM, (text), __VA_ARGS__) + +#define log_dispatch(level, error, buffer) \ + log_dispatch_internal(level, error, PROJECT_FILE, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer) +#endif /* NM_IGNORED */ + +/* Logging with level */ +#define log_full_errno_realm(realm, level, error, ...) \ + ({ \ + int _level = (level), _e = (error), _realm = (realm); \ + (log_get_max_level_realm(_realm) >= LOG_PRI(_level)) \ + ? log_internal_realm(LOG_REALM_PLUS_LEVEL(_realm, _level), _e, \ + PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \ + : -ERRNO_VALUE(_e); \ + }) + +#define log_full_errno(level, error, ...) \ + log_full_errno_realm(LOG_REALM, (level), (error), __VA_ARGS__) + +#define log_full(level, ...) (void) log_full_errno((level), 0, __VA_ARGS__) + +int log_emergency_level(void); + +/* Normal logging */ +#define log_debug(...) log_full_errno(LOG_DEBUG, 0, __VA_ARGS__) +#define log_info(...) log_full(LOG_INFO, __VA_ARGS__) +#define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__) +#define log_warning(...) log_full(LOG_WARNING, __VA_ARGS__) +#define log_error(...) log_full(LOG_ERR, __VA_ARGS__) +#define log_emergency(...) log_full(log_emergency_level(), __VA_ARGS__) + +/* Logging triggered by an errno-like error */ +#define log_debug_errno(error, ...) log_full_errno(LOG_DEBUG, error, __VA_ARGS__) +#define log_info_errno(error, ...) log_full_errno(LOG_INFO, error, __VA_ARGS__) +#define log_notice_errno(error, ...) log_full_errno(LOG_NOTICE, error, __VA_ARGS__) +#define log_warning_errno(error, ...) log_full_errno(LOG_WARNING, error, __VA_ARGS__) +#define log_error_errno(error, ...) log_full_errno(LOG_ERR, error, __VA_ARGS__) +#define log_emergency_errno(error, ...) log_full_errno(log_emergency_level(), error, __VA_ARGS__) + +#ifdef LOG_TRACE +# define log_trace(...) log_debug(__VA_ARGS__) +#else +# define log_trace(...) do {} while (0) +#endif + +/* Structured logging */ +#define log_struct_errno(level, error, ...) \ + log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \ + error, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__, NULL) +#define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__) + +#define log_struct_iovec_errno(level, error, iovec, n_iovec) \ + log_struct_iovec_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \ + error, PROJECT_FILE, __LINE__, __func__, iovec, n_iovec) +#define log_struct_iovec(level, iovec, n_iovec) log_struct_iovec_errno(level, 0, iovec, n_iovec) + +/* This modifies the buffer passed! */ +#define log_dump(level, buffer) \ + log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \ + 0, PROJECT_FILE, __LINE__, __func__, buffer) + +#define log_oom() log_oom_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, LOG_ERR), PROJECT_FILE, __LINE__, __func__) +#define log_oom_debug() log_oom_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, LOG_DEBUG), PROJECT_FILE, __LINE__, __func__) + +bool log_on_console(void) _pure_; + +const char *log_target_to_string(LogTarget target) _const_; +LogTarget log_target_from_string(const char *s) _pure_; + +/* Helper to prepare various field for structured logging */ +#define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__ + +void log_received_signal(int level, const struct signalfd_siginfo *si); + +/* If turned on, any requests for a log target involving "syslog" will be implicitly upgraded to the equivalent journal target */ +void log_set_upgrade_syslog_to_journal(bool b); + +/* If turned on, and log_open() is called, we'll not use STDERR_FILENO for logging ever, but rather open /dev/console */ +void log_set_always_reopen_console(bool b); + +/* If turned on, we'll open the log stream implicitly if needed on each individual log call. This is normally not + * desired as we want to reuse our logging streams. It is useful however */ +void log_set_open_when_needed(bool b); + +/* If turned on, then we'll never use IPC-based logging, i.e. never log to syslog or the journal. We'll only log to + * stderr, the console or kmsg */ +void log_set_prohibit_ipc(bool b); + +int log_dup_console(void); + +#if 0 /* NM_IGNORED */ +int log_syntax_internal( + const char *unit, + int level, + const char *config_file, + unsigned config_line, + int error, + const char *file, + int line, + const char *func, + const char *format, ...) _printf_(9, 10); +#endif /* NM_IGNORED */ +#define log_syntax_internal(unit, level, config_file, config_line, error, file, line, func, format, ...) \ + log_internal_realm((level), (error), file, (line), (func), "syntax[%s]: "format, (config_file), __VA_ARGS__) \ + +int log_syntax_invalid_utf8_internal( + const char *unit, + int level, + const char *config_file, + unsigned config_line, + const char *file, + int line, + const char *func, + const char *rvalue); + +#define log_syntax(unit, level, config_file, config_line, error, ...) \ + ({ \ + int _level = (level), _e = (error); \ + (log_get_max_level() >= LOG_PRI(_level)) \ + ? log_syntax_internal(unit, _level, config_file, config_line, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \ + : -ERRNO_VALUE(_e); \ + }) + +#define log_syntax_invalid_utf8(unit, level, config_file, config_line, rvalue) \ + ({ \ + int _level = (level); \ + (log_get_max_level() >= LOG_PRI(_level)) \ + ? log_syntax_invalid_utf8_internal(unit, _level, config_file, config_line, PROJECT_FILE, __LINE__, __func__, rvalue) \ + : -EINVAL; \ + }) + +#define DEBUG_LOGGING _unlikely_(log_get_max_level() >= LOG_DEBUG) + +void log_setup_service(void); +void log_setup_cli(void); diff --git a/src/libnm-systemd-shared/src/basic/macro.h b/src/libnm-systemd-shared/src/basic/macro.h new file mode 100644 index 0000000..34416b3 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/macro.h @@ -0,0 +1,666 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#define _printf_(a, b) __attribute__((__format__(printf, a, b))) +#ifdef __clang__ +# define _alloc_(...) +#else +# define _alloc_(...) __attribute__((__alloc_size__(__VA_ARGS__))) +#endif +#define _sentinel_ __attribute__((__sentinel__)) +#define _section_(x) __attribute__((__section__(x))) +#define _used_ __attribute__((__used__)) +#define _unused_ __attribute__((__unused__)) +#define _destructor_ __attribute__((__destructor__)) +#define _pure_ __attribute__((__pure__)) +#define _const_ __attribute__((__const__)) +#define _deprecated_ __attribute__((__deprecated__)) +#define _packed_ __attribute__((__packed__)) +#define _malloc_ __attribute__((__malloc__)) +#define _weak_ __attribute__((__weak__)) +#define _likely_(x) (__builtin_expect(!!(x), 1)) +#define _unlikely_(x) (__builtin_expect(!!(x), 0)) +#define _public_ __attribute__((__visibility__("default"))) +#define _hidden_ __attribute__((__visibility__("hidden"))) +#define _weakref_(x) __attribute__((__weakref__(#x))) +#define _align_(x) __attribute__((__aligned__(x))) +#define _alignas_(x) __attribute__((__aligned__(__alignof(x)))) +#define _alignptr_ __attribute__((__aligned__(sizeof(void*)))) +#define _cleanup_(x) __attribute__((__cleanup__(x))) +#if __GNUC__ >= 7 +#define _fallthrough_ __attribute__((__fallthrough__)) +#else +#define _fallthrough_ +#endif +/* Define C11 noreturn without and even on older gcc + * compiler versions */ +#ifndef _noreturn_ +#if __STDC_VERSION__ >= 201112L +#define _noreturn_ _Noreturn +#else +#define _noreturn_ __attribute__((__noreturn__)) +#endif +#endif + +#if !defined(HAS_FEATURE_MEMORY_SANITIZER) +# if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# define HAS_FEATURE_MEMORY_SANITIZER 1 +# endif +# endif +# if !defined(HAS_FEATURE_MEMORY_SANITIZER) +# define HAS_FEATURE_MEMORY_SANITIZER 0 +# endif +#endif + +#if !defined(HAS_FEATURE_ADDRESS_SANITIZER) +# ifdef __SANITIZE_ADDRESS__ +# define HAS_FEATURE_ADDRESS_SANITIZER 1 +# elif defined(__has_feature) +# if __has_feature(address_sanitizer) +# define HAS_FEATURE_ADDRESS_SANITIZER 1 +# endif +# endif +# if !defined(HAS_FEATURE_ADDRESS_SANITIZER) +# define HAS_FEATURE_ADDRESS_SANITIZER 0 +# endif +#endif + +/* Note: on GCC "no_sanitize_address" is a function attribute only, on llvm it may also be applied to global + * variables. We define a specific macro which knows this. Note that on GCC we don't need this decorator so much, since + * our primary usecase for this attribute is registration structures placed in named ELF sections which shall not be + * padded, but GCC doesn't pad those anyway if AddressSanitizer is enabled. */ +#if HAS_FEATURE_ADDRESS_SANITIZER && defined(__clang__) +#define _variable_no_sanitize_address_ __attribute__((__no_sanitize_address__)) +#else +#define _variable_no_sanitize_address_ +#endif + +/* Apparently there's no has_feature() call defined to check for ubsan, hence let's define this + * unconditionally on llvm */ +#if defined(__clang__) +#define _function_no_sanitize_float_cast_overflow_ __attribute__((no_sanitize("float-cast-overflow"))) +#else +#define _function_no_sanitize_float_cast_overflow_ +#endif + +#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) || defined (__clang__) +/* Temporarily disable some warnings */ +#define DISABLE_WARNING_DEPRECATED_DECLARATIONS \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") + +#define DISABLE_WARNING_FORMAT_NONLITERAL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") + +#define DISABLE_WARNING_MISSING_PROTOTYPES \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") + +#define DISABLE_WARNING_NONNULL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wnonnull\"") + +#define DISABLE_WARNING_SHADOW \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wshadow\"") + +#define DISABLE_WARNING_INCOMPATIBLE_POINTER_TYPES \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"") + +#if HAVE_WSTRINGOP_TRUNCATION +# define DISABLE_WARNING_STRINGOP_TRUNCATION \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wstringop-truncation\"") +#else +# define DISABLE_WARNING_STRINGOP_TRUNCATION \ + _Pragma("GCC diagnostic push") +#endif + +#define DISABLE_WARNING_FLOAT_EQUAL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") + +#define DISABLE_WARNING_TYPE_LIMITS \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") + +#define REENABLE_WARNING \ + _Pragma("GCC diagnostic pop") +#else +#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT +#define DISABLE_WARNING_FORMAT_NONLITERAL +#define DISABLE_WARNING_MISSING_PROTOTYPES +#define DISABLE_WARNING_NONNULL +#define DISABLE_WARNING_SHADOW +#define REENABLE_WARNING +#endif + +/* automake test harness */ +#define EXIT_TEST_SKIP 77 + +#define XSTRINGIFY(x) #x +#define STRINGIFY(x) XSTRINGIFY(x) + +#define XCONCATENATE(x, y) x ## y +#define CONCATENATE(x, y) XCONCATENATE(x, y) + +#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq)) +#define UNIQ __COUNTER__ + +/* builtins */ +#if __SIZEOF_INT__ == 4 +#define BUILTIN_FFS_U32(x) __builtin_ffs(x); +#elif __SIZEOF_LONG__ == 4 +#define BUILTIN_FFS_U32(x) __builtin_ffsl(x); +#else +#error "neither int nor long are four bytes long?!?" +#endif + +/* Rounds up */ + +#define ALIGN4(l) (((l) + 3) & ~3) +#define ALIGN8(l) (((l) + 7) & ~7) + +#if __SIZEOF_POINTER__ == 8 +#define ALIGN(l) ALIGN8(l) +#elif __SIZEOF_POINTER__ == 4 +#define ALIGN(l) ALIGN4(l) +#else +#error "Wut? Pointers are neither 4 nor 8 bytes long?" +#endif + +#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) (p))) +#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) (p))) +#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) (p))) + +static inline size_t ALIGN_TO(size_t l, size_t ali) { + return ((l + ali - 1) & ~(ali - 1)); +} + +#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) (p), (ali))) + +/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */ +static inline unsigned long ALIGN_POWER2(unsigned long u) { + + /* Avoid subtraction overflow */ + if (u == 0) + return 0; + + /* clz(0) is undefined */ + if (u == 1) + return 1; + + /* left-shift overflow is undefined */ + if (__builtin_clzl(u - 1UL) < 1) + return 0; + + return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL)); +} + +static inline size_t GREEDY_ALLOC_ROUND_UP(size_t l) { + size_t m; + + /* Round up allocation sizes a bit to some reasonable, likely larger value. This is supposed to be + * used for cases which are likely called in an allocation loop of some form, i.e. that repetitively + * grow stuff, for example strv_extend() and suchlike. + * + * Note the difference to GREEDY_REALLOC() here, as this helper operates on a single size value only, + * and rounds up to next multiple of 2, needing no further counter. + * + * Note the benefits of direct ALIGN_POWER2() usage: type-safety for size_t, sane handling for very + * small (i.e. <= 2) and safe handling for very large (i.e. > SSIZE_MAX) values. */ + + if (l <= 2) + return 2; /* Never allocate less than 2 of something. */ + + m = ALIGN_POWER2(l); + if (m == 0) /* overflow? */ + return l; + + return m; +} + +#ifndef __COVERITY__ +# define VOID_0 ((void)0) +#else +# define VOID_0 ((void*)0) +#endif + +#define ELEMENTSOF(x) \ + (__builtin_choose_expr( \ + !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \ + sizeof(x)/sizeof((x)[0]), \ + VOID_0)) + +/* + * STRLEN - return the length of a string literal, minus the trailing NUL byte. + * Contrary to strlen(), this is a constant expression. + * @x: a string literal. + */ +#define STRLEN(x) (sizeof(""x"") - 1) + +/* + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + */ +#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member) +#define __container_of(uniq, ptr, type, member) \ + ({ \ + const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \ + (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type, member) ); \ + }) + +#undef MAX +#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b)) +#define __MAX(aq, a, bq, b) \ + ({ \ + const typeof(a) UNIQ_T(A, aq) = (a); \ + const typeof(b) UNIQ_T(B, bq) = (b); \ + UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \ + }) + +/* evaluates to (void) if _A or _B are not constant or of different types */ +#define CONST_MAX(_A, _B) \ + (__builtin_choose_expr( \ + __builtin_constant_p(_A) && \ + __builtin_constant_p(_B) && \ + __builtin_types_compatible_p(typeof(_A), typeof(_B)), \ + ((_A) > (_B)) ? (_A) : (_B), \ + VOID_0)) + +/* takes two types and returns the size of the larger one */ +#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; })) + +#define MAX3(x, y, z) \ + ({ \ + const typeof(x) _c = MAX(x, y); \ + MAX(_c, z); \ + }) + +#define MAX4(x, y, z, a) \ + ({ \ + const typeof(x) _d = MAX3(x, y, z); \ + MAX(_d, a); \ + }) + +#undef MIN +#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b)) +#define __MIN(aq, a, bq, b) \ + ({ \ + const typeof(a) UNIQ_T(A, aq) = (a); \ + const typeof(b) UNIQ_T(B, bq) = (b); \ + UNIQ_T(A, aq) < UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \ + }) + +/* evaluates to (void) if _A or _B are not constant or of different types */ +#define CONST_MIN(_A, _B) \ + (__builtin_choose_expr( \ + __builtin_constant_p(_A) && \ + __builtin_constant_p(_B) && \ + __builtin_types_compatible_p(typeof(_A), typeof(_B)), \ + ((_A) < (_B)) ? (_A) : (_B), \ + VOID_0)) + +#define MIN3(x, y, z) \ + ({ \ + const typeof(x) _c = MIN(x, y); \ + MIN(_c, z); \ + }) + +#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b)) +#define __LESS_BY(aq, a, bq, b) \ + ({ \ + const typeof(a) UNIQ_T(A, aq) = (a); \ + const typeof(b) UNIQ_T(B, bq) = (b); \ + UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) - UNIQ_T(B, bq) : 0; \ + }) + +#define CMP(a, b) __CMP(UNIQ, (a), UNIQ, (b)) +#define __CMP(aq, a, bq, b) \ + ({ \ + const typeof(a) UNIQ_T(A, aq) = (a); \ + const typeof(b) UNIQ_T(B, bq) = (b); \ + UNIQ_T(A, aq) < UNIQ_T(B, bq) ? -1 : \ + UNIQ_T(A, aq) > UNIQ_T(B, bq) ? 1 : 0; \ + }) + +#undef CLAMP +#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high)) +#define __CLAMP(xq, x, lowq, low, highq, high) \ + ({ \ + const typeof(x) UNIQ_T(X, xq) = (x); \ + const typeof(low) UNIQ_T(LOW, lowq) = (low); \ + const typeof(high) UNIQ_T(HIGH, highq) = (high); \ + UNIQ_T(X, xq) > UNIQ_T(HIGH, highq) ? \ + UNIQ_T(HIGH, highq) : \ + UNIQ_T(X, xq) < UNIQ_T(LOW, lowq) ? \ + UNIQ_T(LOW, lowq) : \ + UNIQ_T(X, xq); \ + }) + +/* [(x + y - 1) / y] suffers from an integer overflow, even though the + * computation should be possible in the given type. Therefore, we use + * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the + * quotient and the remainder, so both should be equally fast. */ +#define DIV_ROUND_UP(x, y) __DIV_ROUND_UP(UNIQ, (x), UNIQ, (y)) +#define __DIV_ROUND_UP(xq, x, yq, y) \ + ({ \ + const typeof(x) UNIQ_T(X, xq) = (x); \ + const typeof(y) UNIQ_T(Y, yq) = (y); \ + (UNIQ_T(X, xq) / UNIQ_T(Y, yq) + !!(UNIQ_T(X, xq) % UNIQ_T(Y, yq))); \ + }) + +#ifdef __COVERITY__ + +/* Use special definitions of assertion macros in order to prevent + * false positives of ASSERT_SIDE_EFFECT on Coverity static analyzer + * for uses of assert_se() and assert_return(). + * + * These definitions make expression go through a (trivial) function + * call to ensure they are not discarded. Also use ! or !! to ensure + * the boolean expressions are seen as such. + * + * This technique has been described and recommended in: + * https://community.synopsys.com/s/question/0D534000046Yuzb/suppressing-assertsideeffect-for-functions-that-allow-for-sideeffects + */ + +extern void __coverity_panic__(void); + +static inline void __coverity_check__(int condition) { + if (!condition) + __coverity_panic__(); +} + +static inline int __coverity_check_and_return__(int condition) { + return condition; +} + +#define assert_message_se(expr, message) __coverity_check__(!!(expr)) + +#define assert_log(expr, message) __coverity_check_and_return__(!!(expr)) + +#else /* ! __COVERITY__ */ + +#define assert_message_se(expr, message) \ + do { \ + if (_unlikely_(!(expr))) \ + log_assert_failed(message, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__); \ + } while (false) + +#define assert_log(expr, message) ((_likely_(expr)) \ + ? (true) \ + : (log_assert_failed_return(message, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__), false)) + +#endif /* __COVERITY__ */ + +#define assert_se(expr) assert_message_se(expr, #expr) + +/* We override the glibc assert() here. */ +#undef assert +#ifdef NDEBUG +#define assert(expr) do {} while (false) +#else +#define assert(expr) assert_message_se(expr, #expr) +#endif + +#define assert_not_reached(t) \ + log_assert_failed_unreachable(t, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__) + +#if defined(static_assert) +#define assert_cc(expr) \ + static_assert(expr, #expr) +#else +#define assert_cc(expr) \ + struct CONCATENATE(_assert_struct_, __COUNTER__) { \ + char x[(expr) ? 0 : -1]; \ + } +#endif + +#define assert_return(expr, r) \ + do { \ + if (!assert_log(expr, #expr)) \ + return (r); \ + } while (false) + +#define assert_return_errno(expr, r, err) \ + do { \ + if (!assert_log(expr, #expr)) { \ + errno = err; \ + return (r); \ + } \ + } while (false) + +#define return_with_errno(r, err) \ + do { \ + errno = abs(err); \ + return r; \ + } while (false) + +#define PTR_TO_INT(p) ((int) ((intptr_t) (p))) +#define INT_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT(p) ((unsigned) ((uintptr_t) (p))) +#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_LONG(p) ((long) ((intptr_t) (p))) +#define LONG_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p))) +#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_UINT8(p) ((uint8_t) ((uintptr_t) (p))) +#define UINT8_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p))) +#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p))) +#define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p))) +#define INT64_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p))) +#define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p))) +#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define CHAR_TO_STR(x) ((char[2]) { x, 0 }) + +#define char_array_0(x) x[sizeof(x)-1] = 0; + +#define sizeof_field(struct_type, member) sizeof(((struct_type *) 0)->member) + +/* Returns the number of chars needed to format variables of the + * specified type as a decimal string. Adds in extra space for a + * negative '-' prefix (hence works correctly on signed + * types). Includes space for the trailing NUL. */ +#define DECIMAL_STR_MAX(type) \ + (2+(sizeof(type) <= 1 ? 3 : \ + sizeof(type) <= 2 ? 5 : \ + sizeof(type) <= 4 ? 10 : \ + sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)]))) + +#define DECIMAL_STR_WIDTH(x) \ + ({ \ + typeof(x) _x_ = (x); \ + unsigned ans = 1; \ + while ((_x_ /= 10) != 0) \ + ans++; \ + ans; \ + }) + +#define UPDATE_FLAG(orig, flag, b) \ + ((b) ? ((orig) | (flag)) : ((orig) & ~(flag))) +#define SET_FLAG(v, flag, b) \ + (v) = UPDATE_FLAG(v, flag, b) +#define FLAGS_SET(v, flags) \ + ((~(v) & (flags)) == 0) + +#define CASE_F(X) case X: +#define CASE_F_1(CASE, X) CASE_F(X) +#define CASE_F_2(CASE, X, ...) CASE(X) CASE_F_1(CASE, __VA_ARGS__) +#define CASE_F_3(CASE, X, ...) CASE(X) CASE_F_2(CASE, __VA_ARGS__) +#define CASE_F_4(CASE, X, ...) CASE(X) CASE_F_3(CASE, __VA_ARGS__) +#define CASE_F_5(CASE, X, ...) CASE(X) CASE_F_4(CASE, __VA_ARGS__) +#define CASE_F_6(CASE, X, ...) CASE(X) CASE_F_5(CASE, __VA_ARGS__) +#define CASE_F_7(CASE, X, ...) CASE(X) CASE_F_6(CASE, __VA_ARGS__) +#define CASE_F_8(CASE, X, ...) CASE(X) CASE_F_7(CASE, __VA_ARGS__) +#define CASE_F_9(CASE, X, ...) CASE(X) CASE_F_8(CASE, __VA_ARGS__) +#define CASE_F_10(CASE, X, ...) CASE(X) CASE_F_9(CASE, __VA_ARGS__) +#define CASE_F_11(CASE, X, ...) CASE(X) CASE_F_10(CASE, __VA_ARGS__) +#define CASE_F_12(CASE, X, ...) CASE(X) CASE_F_11(CASE, __VA_ARGS__) +#define CASE_F_13(CASE, X, ...) CASE(X) CASE_F_12(CASE, __VA_ARGS__) +#define CASE_F_14(CASE, X, ...) CASE(X) CASE_F_13(CASE, __VA_ARGS__) +#define CASE_F_15(CASE, X, ...) CASE(X) CASE_F_14(CASE, __VA_ARGS__) +#define CASE_F_16(CASE, X, ...) CASE(X) CASE_F_15(CASE, __VA_ARGS__) +#define CASE_F_17(CASE, X, ...) CASE(X) CASE_F_16(CASE, __VA_ARGS__) +#define CASE_F_18(CASE, X, ...) CASE(X) CASE_F_17(CASE, __VA_ARGS__) +#define CASE_F_19(CASE, X, ...) CASE(X) CASE_F_18(CASE, __VA_ARGS__) +#define CASE_F_20(CASE, X, ...) CASE(X) CASE_F_19(CASE, __VA_ARGS__) + +#define GET_CASE_F(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,NAME,...) NAME +#define FOR_EACH_MAKE_CASE(...) \ + GET_CASE_F(__VA_ARGS__,CASE_F_20,CASE_F_19,CASE_F_18,CASE_F_17,CASE_F_16,CASE_F_15,CASE_F_14,CASE_F_13,CASE_F_12,CASE_F_11, \ + CASE_F_10,CASE_F_9,CASE_F_8,CASE_F_7,CASE_F_6,CASE_F_5,CASE_F_4,CASE_F_3,CASE_F_2,CASE_F_1) \ + (CASE_F,__VA_ARGS__) + +#define IN_SET(x, ...) \ + ({ \ + bool _found = false; \ + /* If the build breaks in the line below, you need to extend the case macros. (We use "long double" as \ + * type for the array, in the hope that checkers such as ubsan don't complain that the initializers for \ + * the array are not representable by the base type. Ideally we'd use typeof(x) as base type, but that \ + * doesn't work, as we want to use this on bitfields and gcc refuses typeof() on bitfields.) */ \ + static const long double __assert_in_set[] _unused_ = { __VA_ARGS__ }; \ + assert_cc(ELEMENTSOF(__assert_in_set) <= 20); \ + switch(x) { \ + FOR_EACH_MAKE_CASE(__VA_ARGS__) \ + _found = true; \ + break; \ + default: \ + break; \ + } \ + _found; \ + }) + +#define SWAP_TWO(x, y) do { \ + typeof(x) _t = (x); \ + (x) = (y); \ + (y) = (_t); \ + } while (false) + +#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL })) +#define STRV_MAKE_EMPTY ((char*[1]) { NULL }) + +/* Pointers range from NULL to POINTER_MAX */ +#define POINTER_MAX ((void*) UINTPTR_MAX) + +/* Iterates through a specified list of pointers. Accepts NULL pointers, but uses POINTER_MAX as internal marker for EOL. */ +#define FOREACH_POINTER(p, x, ...) \ + for (typeof(p) *_l = (typeof(p)[]) { ({ p = x; }), ##__VA_ARGS__, POINTER_MAX }; \ + p != (typeof(p)) POINTER_MAX; \ + p = *(++_l)) + +/* Define C11 thread_local attribute even on older gcc compiler + * version */ +#ifndef thread_local +/* + * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__ + * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 + */ +#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) +#define thread_local _Thread_local +#else +#define thread_local __thread +#endif +#endif + +#define DEFINE_TRIVIAL_DESTRUCTOR(name, type, func) \ + static inline void name(type *p) { \ + func(p); \ + } + +#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ + static inline void func##p(type *p) { \ + if (*p) \ + func(*p); \ + } + +#define _DEFINE_TRIVIAL_REF_FUNC(type, name, scope) \ + scope type *name##_ref(type *p) { \ + if (!p) \ + return NULL; \ + \ + assert(p->n_ref > 0); \ + p->n_ref++; \ + return p; \ + } + +#define _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, scope) \ + scope type *name##_unref(type *p) { \ + if (!p) \ + return NULL; \ + \ + assert(p->n_ref > 0); \ + p->n_ref--; \ + if (p->n_ref > 0) \ + return NULL; \ + \ + return free_func(p); \ + } + +#define DEFINE_TRIVIAL_REF_FUNC(type, name) \ + _DEFINE_TRIVIAL_REF_FUNC(type, name,) +#define DEFINE_PRIVATE_TRIVIAL_REF_FUNC(type, name) \ + _DEFINE_TRIVIAL_REF_FUNC(type, name, static) +#define DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name) \ + _DEFINE_TRIVIAL_REF_FUNC(type, name, _public_) + +#define DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func) \ + _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func,) +#define DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(type, name, free_func) \ + _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, static) +#define DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func) \ + _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, _public_) + +#define DEFINE_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \ + DEFINE_TRIVIAL_REF_FUNC(type, name); \ + DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func); + +#define DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \ + DEFINE_PRIVATE_TRIVIAL_REF_FUNC(type, name); \ + DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(type, name, free_func); + +#define DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \ + DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name); \ + DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func); + +/* A macro to force copying of a variable from memory. This is useful whenever we want to read something from + * memory and want to make sure the compiler won't optimize away the destination variable for us. It's not + * supposed to be a full CPU memory barrier, i.e. CPU is still allowed to reorder the reads, but it is not + * allowed to remove our local copies of the variables. We want this to work for unaligned memory, hence + * memcpy() is great for our purposes. */ +#define READ_NOW(x) \ + ({ \ + typeof(x) _copy; \ + memcpy(&_copy, &(x), sizeof(_copy)); \ + asm volatile ("" : : : "memory"); \ + _copy; \ + }) + +static inline size_t size_add(size_t x, size_t y) { + return y >= SIZE_MAX - x ? SIZE_MAX : x + y; +} + +#include "log.h" diff --git a/src/libnm-systemd-shared/src/basic/memory-util.c b/src/libnm-systemd-shared/src/basic/memory-util.c new file mode 100644 index 0000000..7ee7c94 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/memory-util.c @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include + +#include "memory-util.h" + +size_t page_size(void) { + static thread_local size_t pgsz = 0; + long r; + + if (_likely_(pgsz > 0)) + return pgsz; + + r = sysconf(_SC_PAGESIZE); + assert(r > 0); + + pgsz = (size_t) r; + return pgsz; +} + +bool memeqzero(const void *data, size_t length) { + /* Does the buffer consist entirely of NULs? + * Copied from https://github.com/systemd/casync/, copied in turn from + * https://github.com/rustyrussell/ccan/blob/master/ccan/mem/mem.c#L92, + * which is licensed CC-0. + */ + + const uint8_t *p = data; + size_t i; + + /* Check first 16 bytes manually */ + for (i = 0; i < 16; i++, length--) { + if (length == 0) + return true; + if (p[i]) + return false; + } + + /* Now we know first 16 bytes are NUL, memcmp with self. */ + return memcmp(data, p + i, length) == 0; +} + +#if !HAVE_EXPLICIT_BZERO +/* + * The pointer to memset() is volatile so that compiler must de-reference the pointer and can't assume that + * it points to any function in particular (such as memset(), which it then might further "optimize"). This + * approach is inspired by openssl's crypto/mem_clr.c. + */ +typedef void *(*memset_t)(void *,int,size_t); + +static volatile memset_t memset_func = memset; + +void* explicit_bzero_safe(void *p, size_t l) { + if (l > 0) + memset_func(p, '\0', l); + + return p; +} +#endif diff --git a/src/libnm-systemd-shared/src/basic/memory-util.h b/src/libnm-systemd-shared/src/basic/memory-util.h new file mode 100644 index 0000000..179edd2 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/memory-util.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "macro.h" + +size_t page_size(void) _pure_; +#define PAGE_ALIGN(l) ALIGN_TO((l), page_size()) +#define PAGE_ALIGN_DOWN(l) ((l) & ~(page_size() - 1)) +#define PAGE_OFFSET(l) ((l) & (page_size() - 1)) + +/* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */ +static inline void memcpy_safe(void *dst, const void *src, size_t n) { + if (n == 0) + return; + assert(src); + memcpy(dst, src, n); +} + +/* Normal memcmp requires s1 and s2 to be nonnull. We do nothing if n is 0. */ +static inline int memcmp_safe(const void *s1, const void *s2, size_t n) { + if (n == 0) + return 0; + assert(s1); + assert(s2); + return memcmp(s1, s2, n); +} + +/* Compare s1 (length n1) with s2 (length n2) in lexicographic order. */ +static inline int memcmp_nn(const void *s1, size_t n1, const void *s2, size_t n2) { + return memcmp_safe(s1, s2, MIN(n1, n2)) + ?: CMP(n1, n2); +} + +#define memzero(x,l) \ + ({ \ + size_t _l_ = (l); \ + if (_l_ > 0) \ + memset(x, 0, _l_); \ + }) + +#define zero(x) (memzero(&(x), sizeof(x))) + +bool memeqzero(const void *data, size_t length); + +#define eqzero(x) memeqzero(x, sizeof(x)) + +static inline void *mempset(void *s, int c, size_t n) { + memset(s, c, n); + return (uint8_t*)s + n; +} + +/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */ +static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { + + if (needlelen <= 0) + return (void*) haystack; + + if (haystacklen < needlelen) + return NULL; + + assert(haystack); + assert(needle); + + return memmem(haystack, haystacklen, needle, needlelen); +} + +#if HAVE_EXPLICIT_BZERO +static inline void* explicit_bzero_safe(void *p, size_t l) { + if (l > 0) + explicit_bzero(p, l); + + return p; +} +#else +void *explicit_bzero_safe(void *p, size_t l); +#endif + +static inline void* erase_and_free(void *p) { + size_t l; + + if (!p) + return NULL; + + l = malloc_usable_size(p); + explicit_bzero_safe(p, l); + return mfree(p); +} + +static inline void erase_and_freep(void *p) { + erase_and_free(*(void**) p); +} + +/* Use with _cleanup_ to erase a single 'char' when leaving scope */ +static inline void erase_char(char *p) { + explicit_bzero_safe(p, sizeof(char)); +} diff --git a/src/libnm-systemd-shared/src/basic/mempool.c b/src/libnm-systemd-shared/src/basic/mempool.c new file mode 100644 index 0000000..46c4491 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/mempool.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include + +#include "env-util.h" +#include "macro.h" +#include "memory-util.h" +#include "mempool.h" +#include "process-util.h" +#include "util.h" + +struct pool { + struct pool *next; + size_t n_tiles; + size_t n_used; +}; + +void* mempool_alloc_tile(struct mempool *mp) { + size_t i; + + /* When a tile is released we add it to the list and simply + * place the next pointer at its offset 0. */ + + assert(mp->tile_size >= sizeof(void*)); + assert(mp->at_least > 0); + + if (mp->freelist) { + void *r; + + r = mp->freelist; + mp->freelist = * (void**) mp->freelist; + return r; + } + + if (_unlikely_(!mp->first_pool) || + _unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) { + size_t size, n; + struct pool *p; + + n = mp->first_pool ? mp->first_pool->n_tiles : 0; + n = MAX(mp->at_least, n * 2); + size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*mp->tile_size); + n = (size - ALIGN(sizeof(struct pool))) / mp->tile_size; + + p = malloc(size); + if (!p) + return NULL; + + p->next = mp->first_pool; + p->n_tiles = n; + p->n_used = 0; + + mp->first_pool = p; + } + + i = mp->first_pool->n_used++; + + return ((uint8_t*) mp->first_pool) + ALIGN(sizeof(struct pool)) + i*mp->tile_size; +} + +void* mempool_alloc0_tile(struct mempool *mp) { + void *p; + + p = mempool_alloc_tile(mp); + if (p) + memzero(p, mp->tile_size); + return p; +} + +void mempool_free_tile(struct mempool *mp, void *p) { + * (void**) p = mp->freelist; + mp->freelist = p; +} + +bool mempool_enabled(void) { + static int b = -1; + + if (!is_main_thread()) + return false; + + if (!mempool_use_allowed) + b = false; + if (b < 0) + b = getenv_bool("SYSTEMD_MEMPOOL") != 0; + + return b; +} + +#if VALGRIND +void mempool_drop(struct mempool *mp) { + struct pool *p = mp->first_pool; + while (p) { + struct pool *n; + n = p->next; + free(p); + p = n; + } +} +#endif diff --git a/src/libnm-systemd-shared/src/basic/mempool.h b/src/libnm-systemd-shared/src/basic/mempool.h new file mode 100644 index 0000000..0fe2f27 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/mempool.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include + +struct pool; + +struct mempool { + struct pool *first_pool; + void *freelist; + size_t tile_size; + unsigned at_least; +}; + +void* mempool_alloc_tile(struct mempool *mp); +void* mempool_alloc0_tile(struct mempool *mp); +void mempool_free_tile(struct mempool *mp, void *p); + +#define DEFINE_MEMPOOL(pool_name, tile_type, alloc_at_least) \ +static struct mempool pool_name = { \ + .tile_size = sizeof(tile_type), \ + .at_least = alloc_at_least, \ +} + +extern const bool mempool_use_allowed; +bool mempool_enabled(void); + +#if VALGRIND +void mempool_drop(struct mempool *mp); +#endif diff --git a/src/libnm-systemd-shared/src/basic/missing_fcntl.h b/src/libnm-systemd-shared/src/basic/missing_fcntl.h new file mode 100644 index 0000000..00937d2 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/missing_fcntl.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#ifndef F_LINUX_SPECIFIC_BASE +#define F_LINUX_SPECIFIC_BASE 1024 +#endif + +#ifndef F_SETPIPE_SZ +#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7) +#endif + +#ifndef F_GETPIPE_SZ +#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8) +#endif + +#ifndef F_ADD_SEALS +#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9) +#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10) + +#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */ +#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */ +#define F_SEAL_GROW 0x0004 /* prevent file from growing */ +#define F_SEAL_WRITE 0x0008 /* prevent writes */ +#endif + +#ifndef F_OFD_GETLK +#define F_OFD_GETLK 36 +#define F_OFD_SETLK 37 +#define F_OFD_SETLKW 38 +#endif + +#ifndef MAX_HANDLE_SZ +#define MAX_HANDLE_SZ 128 +#endif + +/* The precise definition of __O_TMPFILE is arch specific; use the + * values defined by the kernel (note: some are hexa, some are octal, + * duplicated as-is from the kernel definitions): + * - alpha, parisc, sparc: each has a specific value; + * - others: they use the "generic" value. + */ + +#ifndef __O_TMPFILE +#if defined(__alpha__) +#define __O_TMPFILE 0100000000 +#elif defined(__parisc__) || defined(__hppa__) +#define __O_TMPFILE 0400000000 +#elif defined(__sparc__) || defined(__sparc64__) +#define __O_TMPFILE 0x2000000 +#else +#define __O_TMPFILE 020000000 +#endif +#endif + +/* a horrid kludge trying to make sure that this will fail on old kernels */ +#ifndef O_TMPFILE +#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) +#endif diff --git a/src/libnm-systemd-shared/src/basic/missing_random.h b/src/libnm-systemd-shared/src/basic/missing_random.h new file mode 100644 index 0000000..443b913 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/missing_random.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#if USE_SYS_RANDOM_H +# include +#else +# include +#endif + +#ifndef GRND_NONBLOCK +#define GRND_NONBLOCK 0x0001 +#endif + +#ifndef GRND_RANDOM +#define GRND_RANDOM 0x0002 +#endif + +#ifndef GRND_INSECURE +#define GRND_INSECURE 0x0004 +#endif diff --git a/src/libnm-systemd-shared/src/basic/missing_socket.h b/src/libnm-systemd-shared/src/basic/missing_socket.h new file mode 100644 index 0000000..a4f6836 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/missing_socket.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#if 0 /* NM_IGNORED */ +#if HAVE_LINUX_VM_SOCKETS_H +#include +#else +#define VMADDR_CID_ANY -1U +struct sockaddr_vm { + unsigned short svm_family; + unsigned short svm_reserved1; + unsigned int svm_port; + unsigned int svm_cid; + unsigned char svm_zero[sizeof(struct sockaddr) - + sizeof(unsigned short) - + sizeof(unsigned short) - + sizeof(unsigned int) - + sizeof(unsigned int)]; +}; +#endif /* !HAVE_LINUX_VM_SOCKETS_H */ +#endif /* NM_IGNORED */ + +#ifndef AF_VSOCK +#define AF_VSOCK 40 +#endif + +#ifndef SO_REUSEPORT +#define SO_REUSEPORT 15 +#endif + +#ifndef SO_PEERGROUPS +#define SO_PEERGROUPS 59 +#endif + +#ifndef SO_BINDTOIFINDEX +#define SO_BINDTOIFINDEX 62 +#endif + +#ifndef SOL_NETLINK +#define SOL_NETLINK 270 +#endif + +#ifndef SOL_ALG +#define SOL_ALG 279 +#endif + +/* Not exposed yet. Defined in include/linux/socket.h. */ +#ifndef SOL_SCTP +#define SOL_SCTP 132 +#endif + +/* Not exposed yet. Defined in include/linux/socket.h */ +#ifndef SCM_SECURITY +#define SCM_SECURITY 0x03 +#endif + +/* netinet/in.h */ +#ifndef IP_FREEBIND +#define IP_FREEBIND 15 +#endif + +#ifndef IP_TRANSPARENT +#define IP_TRANSPARENT 19 +#endif + +#ifndef IPV6_FREEBIND +#define IPV6_FREEBIND 78 +#endif + +#ifndef IP_RECVFRAGSIZE +#define IP_RECVFRAGSIZE 25 +#endif + +#ifndef IPV6_RECVFRAGSIZE +#define IPV6_RECVFRAGSIZE 77 +#endif + +/* linux/sockios.h */ +#ifndef SIOCGSKNS +#define SIOCGSKNS 0x894C +#endif diff --git a/src/libnm-systemd-shared/src/basic/missing_stat.h b/src/libnm-systemd-shared/src/basic/missing_stat.h new file mode 100644 index 0000000..9c1df69 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/missing_stat.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include + +#if 0 /* NM_IGNORED */ +#if WANT_LINUX_STAT_H +#include +#endif + +/* Thew newest definition we are aware of (fa2fcf4f1df1559a0a4ee0f46915b496cc2ebf60; 5.8) */ +#define STATX_DEFINITION { \ + __u32 stx_mask; \ + __u32 stx_blksize; \ + __u64 stx_attributes; \ + __u32 stx_nlink; \ + __u32 stx_uid; \ + __u32 stx_gid; \ + __u16 stx_mode; \ + __u16 __spare0[1]; \ + __u64 stx_ino; \ + __u64 stx_size; \ + __u64 stx_blocks; \ + __u64 stx_attributes_mask; \ + struct statx_timestamp stx_atime; \ + struct statx_timestamp stx_btime; \ + struct statx_timestamp stx_ctime; \ + struct statx_timestamp stx_mtime; \ + __u32 stx_rdev_major; \ + __u32 stx_rdev_minor; \ + __u32 stx_dev_major; \ + __u32 stx_dev_minor; \ + __u64 stx_mnt_id; \ + __u64 __spare2; \ + __u64 __spare3[12]; \ +} + +#if !HAVE_STRUCT_STATX +struct statx_timestamp { + __s64 tv_sec; + __u32 tv_nsec; + __s32 __reserved; +}; + +struct statx STATX_DEFINITION; +#endif + +/* Always define the newest version we are aware of as a distinct type, so that we can use it even if glibc + * defines an older definition */ +struct new_statx STATX_DEFINITION; +#endif /* NM_IGNORED */ + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef AT_STATX_SYNC_AS_STAT +#define AT_STATX_SYNC_AS_STAT 0x0000 +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef AT_STATX_FORCE_SYNC +#define AT_STATX_FORCE_SYNC 0x2000 +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef AT_STATX_DONT_SYNC +#define AT_STATX_DONT_SYNC 0x4000 +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_TYPE +#define STATX_TYPE 0x00000001U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_MODE +#define STATX_MODE 0x00000002U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_NLINK +#define STATX_NLINK 0x00000004U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_UID +#define STATX_UID 0x00000008U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_GID +#define STATX_GID 0x00000010U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_ATIME +#define STATX_ATIME 0x00000020U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_MTIME +#define STATX_MTIME 0x00000040U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_CTIME +#define STATX_CTIME 0x00000080U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_INO +#define STATX_INO 0x00000100U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_SIZE +#define STATX_SIZE 0x00000200U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_BLOCKS +#define STATX_BLOCKS 0x00000400U +#endif + +/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */ +#ifndef STATX_BTIME +#define STATX_BTIME 0x00000800U +#endif + +/* fa2fcf4f1df1559a0a4ee0f46915b496cc2ebf60 (5.8) */ +#ifndef STATX_MNT_ID +#define STATX_MNT_ID 0x00001000U +#endif + +/* 80340fe3605c0e78cfe496c3b3878be828cfdbfe (5.8) */ +#ifndef STATX_ATTR_MOUNT_ROOT +#define STATX_ATTR_MOUNT_ROOT 0x00002000 /* Root of a mount */ +#endif diff --git a/src/libnm-systemd-shared/src/basic/missing_syscall.h b/src/libnm-systemd-shared/src/basic/missing_syscall.h new file mode 100644 index 0000000..42d6475 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/missing_syscall.h @@ -0,0 +1,889 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +/* Missing glibc definitions to access certain kernel APIs */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef ARCH_MIPS +#include +#endif + +#if defined(__alpha__) +# define systemd_SC_arch_bias(x) (110 + (x)) +#elif defined(__ia64__) +# define systemd_SC_arch_bias(x) (1024 + (x)) +#elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_SC_arch_bias(x) (4000 + (x)) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_SC_arch_bias(x) (6000 + (x)) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_SC_arch_bias(x) (5000 + (x)) +# else +# error "Unknown MIPS ABI" +# endif +#elif defined(__x86_64__) && defined(__ILP32__) +# define systemd_SC_arch_bias(x) ((x) | /* __X32_SYSCALL_BIT */ 0x40000000) +#else +# define systemd_SC_arch_bias(x) (x) +#endif + +#include "missing_keyctl.h" +#include "missing_stat.h" + +#if 0 /* NM_IGNORED */ + +/* linux/kcmp.h */ +#ifndef KCMP_FILE /* 3f4994cfc15f38a3159c6e3a4b3ab2e1481a6b02 (3.19) */ +#define KCMP_FILE 0 +#endif + +#if !HAVE_PIVOT_ROOT +static inline int missing_pivot_root(const char *new_root, const char *put_old) { + return syscall(__NR_pivot_root, new_root, put_old); +} + +# define pivot_root missing_pivot_root +#endif + +/* ======================================================================= */ + +#if defined(__aarch64__) +# define systemd_NR_memfd_create 279 +#elif defined(__alpha__) +# define systemd_NR_memfd_create 512 +#elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_memfd_create 279 +#elif defined(__arm__) +# define systemd_NR_memfd_create 385 +#elif defined(__i386__) +# define systemd_NR_memfd_create 356 +#elif defined(__ia64__) +# define systemd_NR_memfd_create systemd_SC_arch_bias(316) +#elif defined(__m68k__) +# define systemd_NR_memfd_create 353 +#elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_memfd_create systemd_SC_arch_bias(354) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_memfd_create systemd_SC_arch_bias(318) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_memfd_create systemd_SC_arch_bias(314) +# endif +#elif defined(__powerpc__) +# define systemd_NR_memfd_create 360 +#elif defined(__s390__) +# define systemd_NR_memfd_create 350 +#elif defined(__sparc__) +# define systemd_NR_memfd_create 348 +#elif defined(__x86_64__) +# define systemd_NR_memfd_create systemd_SC_arch_bias(319) +#else +# warning "memfd_create() syscall number is unknown for your architecture" +#endif + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_memfd_create && __NR_memfd_create >= 0 +# if defined systemd_NR_memfd_create +assert_cc(__NR_memfd_create == systemd_NR_memfd_create); +# endif +#else +# if defined __NR_memfd_create +# undef __NR_memfd_create +# endif +# if defined systemd_NR_memfd_create +# define __NR_memfd_create systemd_NR_memfd_create +# endif +#endif + +#if !HAVE_MEMFD_CREATE +static inline int missing_memfd_create(const char *name, unsigned int flags) { +# ifdef __NR_memfd_create + return syscall(__NR_memfd_create, name, flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define memfd_create missing_memfd_create +#endif + +/* ======================================================================= */ + +#if defined(__aarch64__) +# define systemd_NR_getrandom 278 +#elif defined(__alpha__) +# define systemd_NR_getrandom 511 +#elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_getrandom 278 +#elif defined(__arm__) +# define systemd_NR_getrandom 384 +#elif defined(__i386__) +# define systemd_NR_getrandom 355 +#elif defined(__ia64__) +# define systemd_NR_getrandom systemd_SC_arch_bias(318) +#elif defined(__m68k__) +# define systemd_NR_getrandom 352 +#elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_getrandom systemd_SC_arch_bias(353) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_getrandom systemd_SC_arch_bias(317) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_getrandom systemd_SC_arch_bias(313) +# endif +#elif defined(__powerpc__) +# define systemd_NR_getrandom 359 +#elif defined(__s390__) +# define systemd_NR_getrandom 349 +#elif defined(__sparc__) +# define systemd_NR_getrandom 347 +#elif defined(__x86_64__) +# define systemd_NR_getrandom systemd_SC_arch_bias(318) +#else +# warning "getrandom() syscall number is unknown for your architecture" +#endif + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_getrandom && __NR_getrandom >= 0 +# if defined systemd_NR_getrandom +assert_cc(__NR_getrandom == systemd_NR_getrandom); +# endif +#else +# if defined __NR_getrandom +# undef __NR_getrandom +# endif +# if defined systemd_NR_getrandom +# define __NR_getrandom systemd_NR_getrandom +# endif +#endif + +#if !HAVE_GETRANDOM +static inline int missing_getrandom(void *buffer, size_t count, unsigned flags) { +# ifdef __NR_getrandom + return syscall(__NR_getrandom, buffer, count, flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define getrandom missing_getrandom +#endif + +/* ======================================================================= */ + +/* The syscall has been defined since forever, but the glibc wrapper was missing. */ +#if !HAVE_GETTID +static inline pid_t missing_gettid(void) { +# if defined __NR_gettid && __NR_gettid >= 0 + return (pid_t) syscall(__NR_gettid); +# else +# error "__NR_gettid not defined" +# endif +} + +# define gettid missing_gettid +#endif + +/* ======================================================================= */ + +#if defined(__aarch64__) +# define systemd_NR_name_to_handle_at 264 +#elif defined(__alpha__) +# define systemd_NR_name_to_handle_at 497 +#elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_name_to_handle_at 264 +#elif defined(__arm__) +# define systemd_NR_name_to_handle_at 370 +#elif defined(__i386__) +# define systemd_NR_name_to_handle_at 341 +#elif defined(__ia64__) +# define systemd_NR_name_to_handle_at systemd_SC_arch_bias(302) +#elif defined(__m68k__) +# define systemd_NR_name_to_handle_at 340 +#elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_name_to_handle_at systemd_SC_arch_bias(339) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_name_to_handle_at systemd_SC_arch_bias(303) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_name_to_handle_at systemd_SC_arch_bias(298) +# endif +#elif defined(__powerpc__) +# define systemd_NR_name_to_handle_at 345 +#elif defined(__s390__) +# define systemd_NR_name_to_handle_at 335 +#elif defined(__sparc__) +# define systemd_NR_name_to_handle_at 332 +#elif defined(__x86_64__) +# define systemd_NR_name_to_handle_at systemd_SC_arch_bias(303) +#else +# warning "name_to_handle_at() syscall number is unknown for your architecture" +#endif + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_name_to_handle_at && __NR_name_to_handle_at >= 0 +# if defined systemd_NR_name_to_handle_at +assert_cc(__NR_name_to_handle_at == systemd_NR_name_to_handle_at); +# endif +#else +# if defined __NR_name_to_handle_at +# undef __NR_name_to_handle_at +# endif +# if defined systemd_NR_name_to_handle_at +# define __NR_name_to_handle_at systemd_NR_name_to_handle_at +# endif +#endif + +#if !HAVE_NAME_TO_HANDLE_AT +struct file_handle { + unsigned int handle_bytes; + int handle_type; + unsigned char f_handle[0]; +}; + +static inline int missing_name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) { +# ifdef __NR_name_to_handle_at + return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define name_to_handle_at missing_name_to_handle_at +#endif + +/* ======================================================================= */ + +#if defined(__aarch64__) +# define systemd_NR_setns 268 +#elif defined(__alpha__) +# define systemd_NR_setns 501 +#elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_setns 268 +#elif defined(__arm__) +# define systemd_NR_setns 375 +#elif defined(__i386__) +# define systemd_NR_setns 346 +#elif defined(__ia64__) +# define systemd_NR_setns systemd_SC_arch_bias(306) +#elif defined(__m68k__) +# define systemd_NR_setns 344 +#elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_setns systemd_SC_arch_bias(344) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_setns systemd_SC_arch_bias(308) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_setns systemd_SC_arch_bias(303) +# endif +#elif defined(__powerpc__) +# define systemd_NR_setns 350 +#elif defined(__s390__) +# define systemd_NR_setns 339 +#elif defined(__sparc__) +# define systemd_NR_setns 337 +#elif defined(__x86_64__) +# define systemd_NR_setns systemd_SC_arch_bias(308) +#else +# warning "setns() syscall number is unknown for your architecture" +#endif + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_setns && __NR_setns >= 0 +# if defined systemd_NR_setns +assert_cc(__NR_setns == systemd_NR_setns); +# endif +#else +# if defined __NR_setns +# undef __NR_setns +# endif +# if defined systemd_NR_setns +# define __NR_setns systemd_NR_setns +# endif +#endif + +#if !HAVE_SETNS +static inline int missing_setns(int fd, int nstype) { +# ifdef __NR_setns + return syscall(__NR_setns, fd, nstype); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define setns missing_setns +#endif + +/* ======================================================================= */ + +static inline pid_t raw_getpid(void) { +#if defined(__alpha__) + return (pid_t) syscall(__NR_getxpid); +#else + return (pid_t) syscall(__NR_getpid); +#endif +} + +/* ======================================================================= */ + +#if defined(__aarch64__) +# define systemd_NR_renameat2 276 +#elif defined(__alpha__) +# define systemd_NR_renameat2 510 +#elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_renameat2 276 +#elif defined(__arm__) +# define systemd_NR_renameat2 382 +#elif defined(__i386__) +# define systemd_NR_renameat2 353 +#elif defined(__ia64__) +# define systemd_NR_renameat2 systemd_SC_arch_bias(314) +#elif defined(__m68k__) +# define systemd_NR_renameat2 351 +#elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_renameat2 systemd_SC_arch_bias(351) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_renameat2 systemd_SC_arch_bias(315) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_renameat2 systemd_SC_arch_bias(311) +# endif +#elif defined(__powerpc__) +# define systemd_NR_renameat2 357 +#elif defined(__s390__) +# define systemd_NR_renameat2 347 +#elif defined(__sparc__) +# define systemd_NR_renameat2 345 +#elif defined(__x86_64__) +# define systemd_NR_renameat2 systemd_SC_arch_bias(316) +#else +# warning "renameat2() syscall number is unknown for your architecture" +#endif + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_renameat2 && __NR_renameat2 >= 0 +# if defined systemd_NR_renameat2 +assert_cc(__NR_renameat2 == systemd_NR_renameat2); +# endif +#else +# if defined __NR_renameat2 +# undef __NR_renameat2 +# endif +# if defined systemd_NR_renameat2 +# define __NR_renameat2 systemd_NR_renameat2 +# endif +#endif + +#if !HAVE_RENAMEAT2 +static inline int missing_renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) { +# ifdef __NR_renameat2 + return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define renameat2 missing_renameat2 +#endif + +/* ======================================================================= */ + +#if !HAVE_KCMP +static inline int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) { +# if defined __NR_kcmp && __NR_kcmp >= 0 + return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define kcmp missing_kcmp +#endif + +/* ======================================================================= */ + +#if !HAVE_KEYCTL +static inline long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { +# if defined __NR_keyctl && __NR_keyctl >= 0 + return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5); +# else + errno = ENOSYS; + return -1; +# endif + +# define keyctl missing_keyctl +} + +static inline key_serial_t missing_add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) { +# if defined __NR_add_key && __NR_add_key >= 0 + return syscall(__NR_add_key, type, description, payload, plen, ringid); +# else + errno = ENOSYS; + return -1; +# endif + +# define add_key missing_add_key +} + +static inline key_serial_t missing_request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) { +# if defined __NR_request_key && __NR_request_key >= 0 + return syscall(__NR_request_key, type, description, callout_info, destringid); +# else + errno = ENOSYS; + return -1; +# endif + +# define request_key missing_request_key +} +#endif + +/* ======================================================================= */ + +#if defined(__aarch64__) +# define systemd_NR_copy_file_range 285 +#elif defined(__alpha__) +# define systemd_NR_copy_file_range 519 +#elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_copy_file_range 285 +#elif defined(__arm__) +# define systemd_NR_copy_file_range 391 +#elif defined(__i386__) +# define systemd_NR_copy_file_range 377 +#elif defined(__ia64__) +# define systemd_NR_copy_file_range systemd_SC_arch_bias(323) +#elif defined(__m68k__) +# define systemd_NR_copy_file_range 376 +#elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_copy_file_range systemd_SC_arch_bias(360) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_copy_file_range systemd_SC_arch_bias(324) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_copy_file_range systemd_SC_arch_bias(320) +# endif +#elif defined(__powerpc__) +# define systemd_NR_copy_file_range 379 +#elif defined(__s390__) +# define systemd_NR_copy_file_range 375 +#elif defined(__sparc__) +# define systemd_NR_copy_file_range 357 +#elif defined(__x86_64__) +# define systemd_NR_copy_file_range systemd_SC_arch_bias(326) +#else +# warning "copy_file_range() syscall number is unknown for your architecture" +#endif + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_copy_file_range && __NR_copy_file_range >= 0 +# if defined systemd_NR_copy_file_range +assert_cc(__NR_copy_file_range == systemd_NR_copy_file_range); +# endif +#else +# if defined __NR_copy_file_range +# undef __NR_copy_file_range +# endif +# if defined systemd_NR_copy_file_range +# define __NR_copy_file_range systemd_NR_copy_file_range +# endif +#endif + +#if !HAVE_COPY_FILE_RANGE +static inline ssize_t missing_copy_file_range(int fd_in, loff_t *off_in, + int fd_out, loff_t *off_out, + size_t len, + unsigned int flags) { +# ifdef __NR_copy_file_range + return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define copy_file_range missing_copy_file_range +#endif + +/* ======================================================================= */ + +#if defined(__aarch64__) +# define systemd_NR_bpf 280 +#elif defined(__alpha__) +# define systemd_NR_bpf 515 +#elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_bpf 280 +#elif defined(__arm__) +# define systemd_NR_bpf 386 +#elif defined(__i386__) +# define systemd_NR_bpf 357 +#elif defined(__ia64__) +# define systemd_NR_bpf systemd_SC_arch_bias(317) +#elif defined(__m68k__) +# define systemd_NR_bpf 354 +#elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_bpf systemd_SC_arch_bias(355) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_bpf systemd_SC_arch_bias(319) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_bpf systemd_SC_arch_bias(315) +# endif +#elif defined(__powerpc__) +# define systemd_NR_bpf 361 +#elif defined(__s390__) +# define systemd_NR_bpf 351 +#elif defined(__sparc__) +# define systemd_NR_bpf 349 +#elif defined(__x86_64__) +# define systemd_NR_bpf systemd_SC_arch_bias(321) +#else +# warning "bpf() syscall number is unknown for your architecture" +#endif + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_bpf && __NR_bpf >= 0 +# if defined systemd_NR_bpf +assert_cc(__NR_bpf == systemd_NR_bpf); +# endif +#else +# if defined __NR_bpf +# undef __NR_bpf +# endif +# if defined systemd_NR_bpf +# define __NR_bpf systemd_NR_bpf +# endif +#endif + +#if !HAVE_BPF +union bpf_attr; + +static inline int missing_bpf(int cmd, union bpf_attr *attr, size_t size) { +#ifdef __NR_bpf + return (int) syscall(__NR_bpf, cmd, attr, size); +#else + errno = ENOSYS; + return -1; +#endif +} + +# define bpf missing_bpf +#endif + +/* ======================================================================= */ + +#ifndef __IGNORE_pkey_mprotect +# if defined(__aarch64__) +# define systemd_NR_pkey_mprotect 288 +# elif defined(__alpha__) +# define systemd_NR_pkey_mprotect 524 +# elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_pkey_mprotect 226 +# elif defined(__arm__) +# define systemd_NR_pkey_mprotect 394 +# elif defined(__i386__) +# define systemd_NR_pkey_mprotect 380 +# elif defined(__ia64__) +# define systemd_NR_pkey_mprotect systemd_SC_arch_bias(330) +# elif defined(__m68k__) +# define systemd_NR_pkey_mprotect 381 +# elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_pkey_mprotect systemd_SC_arch_bias(363) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_pkey_mprotect systemd_SC_arch_bias(327) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_pkey_mprotect systemd_SC_arch_bias(323) +# endif +# elif defined(__powerpc__) +# define systemd_NR_pkey_mprotect 386 +# elif defined(__s390__) +# define systemd_NR_pkey_mprotect 384 +# elif defined(__sparc__) +# define systemd_NR_pkey_mprotect 362 +# elif defined(__x86_64__) +# define systemd_NR_pkey_mprotect systemd_SC_arch_bias(329) +# else +# warning "pkey_mprotect() syscall number is unknown for your architecture" +# endif + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +# if defined __NR_pkey_mprotect && __NR_pkey_mprotect >= 0 +# if defined systemd_NR_pkey_mprotect +assert_cc(__NR_pkey_mprotect == systemd_NR_pkey_mprotect); +# endif +# else +# if defined __NR_pkey_mprotect +# undef __NR_pkey_mprotect +# endif +# if defined systemd_NR_pkey_mprotect +# define __NR_pkey_mprotect systemd_NR_pkey_mprotect +# endif +# endif +#endif + +/* ======================================================================= */ + +#if defined(__aarch64__) +# define systemd_NR_statx 291 +#elif defined(__alpha__) +# define systemd_NR_statx 522 +#elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_statx 291 +#elif defined(__arm__) +# define systemd_NR_statx 397 +#elif defined(__i386__) +# define systemd_NR_statx 383 +#elif defined(__ia64__) +# define systemd_NR_statx systemd_SC_arch_bias(326) +#elif defined(__m68k__) +# define systemd_NR_statx 379 +#elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_statx systemd_SC_arch_bias(366) +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_statx systemd_SC_arch_bias(330) +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_statx systemd_SC_arch_bias(326) +# endif +#elif defined(__powerpc__) +# define systemd_NR_statx 383 +#elif defined(__s390__) +# define systemd_NR_statx 379 +#elif defined(__sparc__) +# define systemd_NR_statx 360 +#elif defined(__x86_64__) +# define systemd_NR_statx systemd_SC_arch_bias(332) +#else +# warning "statx() syscall number is unknown for your architecture" +#endif + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_statx && __NR_statx >= 0 +# if defined systemd_NR_statx +assert_cc(__NR_statx == systemd_NR_statx); +# endif +#else +# if defined __NR_statx +# undef __NR_statx +# endif +# if defined systemd_NR_statx +# define __NR_statx systemd_NR_statx +# endif +#endif + +#if !HAVE_STATX +struct statx; + +static inline ssize_t missing_statx(int dfd, const char *filename, unsigned flags, unsigned int mask, struct statx *buffer) { +# ifdef __NR_statx + return syscall(__NR_statx, dfd, filename, flags, mask, buffer); +# else + errno = ENOSYS; + return -1; +# endif +} +#endif + +/* This typedef is supposed to be always defined. */ +typedef struct statx struct_statx; + +#if !HAVE_STATX +# define statx(dfd, filename, flags, mask, buffer) missing_statx(dfd, filename, flags, mask, buffer) +#endif + +/* ======================================================================= */ + +#if !HAVE_SET_MEMPOLICY +enum { + MPOL_DEFAULT, + MPOL_PREFERRED, + MPOL_BIND, + MPOL_INTERLEAVE, + MPOL_LOCAL, +}; + +static inline long missing_set_mempolicy(int mode, const unsigned long *nodemask, + unsigned long maxnode) { + long i; +# if defined __NR_set_mempolicy && __NR_set_mempolicy >= 0 + i = syscall(__NR_set_mempolicy, mode, nodemask, maxnode); +# else + errno = ENOSYS; + i = -1; +# endif + return i; +} + +# define set_mempolicy missing_set_mempolicy +#endif + +#if !HAVE_GET_MEMPOLICY +static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask, + unsigned long maxnode, void *addr, + unsigned long flags) { + long i; +# if defined __NR_get_mempolicy && __NR_get_mempolicy >= 0 + i = syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags); +# else + errno = ENOSYS; + i = -1; +# endif + return i; +} + +# define get_mempolicy missing_get_mempolicy +#endif + +#endif /* NM_IGNORED */ + +/* ======================================================================= */ + +/* should be always defined, see kernel 39036cd2727395c3369b1051005da74059a85317 */ +#define systemd_NR_pidfd_send_signal systemd_SC_arch_bias(424) + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_pidfd_send_signal && __NR_pidfd_send_signal >= 0 +# if defined systemd_NR_pidfd_send_signal +assert_cc(__NR_pidfd_send_signal == systemd_NR_pidfd_send_signal); +# endif +#else +# if defined __NR_pidfd_send_signal +# undef __NR_pidfd_send_signal +# endif +# define __NR_pidfd_send_signal systemd_NR_pidfd_send_signal +#endif + +#if !HAVE_PIDFD_SEND_SIGNAL +static inline int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) { +# ifdef __NR_pidfd_send_signal + return syscall(__NR_pidfd_send_signal, fd, sig, info, flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define pidfd_send_signal missing_pidfd_send_signal +#endif + +/* should be always defined, see kernel 7615d9e1780e26e0178c93c55b73309a5dc093d7 */ +#define systemd_NR_pidfd_open systemd_SC_arch_bias(434) + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_pidfd_open && __NR_pidfd_open >= 0 +# if defined systemd_NR_pidfd_open +assert_cc(__NR_pidfd_open == systemd_NR_pidfd_open); +# endif +#else +# if defined __NR_pidfd_open +# undef __NR_pidfd_open +# endif +# define __NR_pidfd_open systemd_NR_pidfd_open +#endif + +#if !HAVE_PIDFD_OPEN +static inline int missing_pidfd_open(pid_t pid, unsigned flags) { +# ifdef __NR_pidfd_open + return syscall(__NR_pidfd_open, pid, flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define pidfd_open missing_pidfd_open +#endif + +/* ======================================================================= */ + +#if !HAVE_RT_SIGQUEUEINFO +static inline int missing_rt_sigqueueinfo(pid_t tgid, int sig, siginfo_t *info) { +# if defined __NR_rt_sigqueueinfo && __NR_rt_sigqueueinfo >= 0 + return syscall(__NR_rt_sigqueueinfo, tgid, sig, info); +# else +# error "__NR_rt_sigqueueinfo not defined" +# endif +} + +# define rt_sigqueueinfo missing_rt_sigqueueinfo +#endif + +/* ======================================================================= */ + +#if 0 /* NM_IGNORED */ +#if !HAVE_EXECVEAT +static inline int missing_execveat(int dirfd, const char *pathname, + char *const argv[], char *const envp[], + int flags) { +# if defined __NR_execveat && __NR_execveat >= 0 + return syscall(__NR_execveat, dirfd, pathname, argv, envp, flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# undef AT_EMPTY_PATH +# define AT_EMPTY_PATH 0x1000 +# define execveat missing_execveat +#endif + +/* ======================================================================= */ + +#define systemd_NR_close_range systemd_SC_arch_bias(436) + +/* may be (invalid) negative number due to libseccomp, see PR 13319 */ +#if defined __NR_close_range && __NR_close_range >= 0 +# if defined systemd_NR_close_range +assert_cc(__NR_close_range == systemd_NR_close_range); +# endif +#else +# if defined __NR_close_range +# undef __NR_close_range +# endif +# if defined systemd_NR_close_range +# define __NR_close_range systemd_NR_close_range +# endif +#endif + +#if !HAVE_CLOSE_RANGE +static inline int missing_close_range(int first_fd, int end_fd, unsigned flags) { +# ifdef __NR_close_range + /* Kernel-side the syscall expects fds as unsigned integers (just like close() actually), while + * userspace exclusively uses signed integers for fds. We don't know just yet how glibc is going to + * wrap this syscall, but let's assume it's going to be similar to what they do for close(), + * i.e. make the same unsigned → signed type change from the raw kernel syscall compared to the + * userspace wrapper. There's only one caveat for this: unlike for close() there's the special + * UINT_MAX fd value for the 'end_fd' argument. Let's safely map that to -1 here. And let's refuse + * any other negative values. */ + if ((first_fd < 0) || (end_fd < 0 && end_fd != -1)) { + errno = -EBADF; + return -1; + } + + return syscall(__NR_close_range, + (unsigned) first_fd, + end_fd == -1 ? UINT_MAX : (unsigned) end_fd, /* Of course, the compiler should figure out that this is the identity mapping IRL */ + flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define close_range missing_close_range +#endif +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/missing_type.h b/src/libnm-systemd-shared/src/basic/missing_type.h new file mode 100644 index 0000000..f623309 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/missing_type.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#if !HAVE_CHAR32_T +#define char32_t uint32_t +#endif + +#if !HAVE_CHAR16_T +#define char16_t uint16_t +#endif diff --git a/src/libnm-systemd-shared/src/basic/parse-util.c b/src/libnm-systemd-shared/src/basic/parse-util.c new file mode 100644 index 0000000..d53bf62 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/parse-util.c @@ -0,0 +1,912 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "errno-list.h" +#include "extract-word.h" +#include "locale-util.h" +#include "macro.h" +#include "missing_network.h" +#include "parse-util.h" +#include "process-util.h" +#if HAVE_SECCOMP +#include "seccomp-util.h" +#endif +#include "stat-util.h" +#include "string-util.h" +#include "strv.h" + +int parse_boolean(const char *v) { + if (!v) + return -EINVAL; + + if (STRCASE_IN_SET(v, + "1", + "yes", + "y", + "true", + "t", + "on")) + return 1; + + if (STRCASE_IN_SET(v, + "0", + "no", + "n", + "false", + "f", + "off")) + return 0; + + return -EINVAL; +} + +#if 0 /* NM_IGNORED */ +int parse_pid(const char *s, pid_t* ret_pid) { + unsigned long ul = 0; + pid_t pid; + int r; + + assert(s); + assert(ret_pid); + + r = safe_atolu(s, &ul); + if (r < 0) + return r; + + pid = (pid_t) ul; + + if ((unsigned long) pid != ul) + return -ERANGE; + + if (!pid_is_valid(pid)) + return -ERANGE; + + *ret_pid = pid; + return 0; +} + +int parse_mode(const char *s, mode_t *ret) { + unsigned m; + int r; + + assert(s); + + r = safe_atou_full(s, 8 | + SAFE_ATO_REFUSE_PLUS_MINUS, /* Leading '+' or even '-' char? that's just weird, + * refuse. User might have wanted to add mode flags or + * so, but this parser doesn't allow that, so let's + * better be safe. */ + &m); + if (r < 0) + return r; + if (m > 07777) + return -ERANGE; + + if (ret) + *ret = m; + return 0; +} + +int parse_ifindex(const char *s) { + int ifi, r; + + assert(s); + + r = safe_atoi(s, &ifi); + if (r < 0) + return r; + if (ifi <= 0) + return -EINVAL; + + return ifi; +} + +int parse_mtu(int family, const char *s, uint32_t *ret) { + uint64_t u; + size_t m; + int r; + + r = parse_size(s, 1024, &u); + if (r < 0) + return r; + + if (u > UINT32_MAX) + return -ERANGE; + + if (family == AF_INET6) + m = IPV6_MIN_MTU; /* This is 1280 */ + else + m = IPV4_MIN_MTU; /* For all other protocols, including 'unspecified' we assume the IPv4 minimal MTU */ + + if (u < m) + return -ERANGE; + + *ret = (uint32_t) u; + return 0; +} + +int parse_size(const char *t, uint64_t base, uint64_t *size) { + + /* Soo, sometimes we want to parse IEC binary suffixes, and + * sometimes SI decimal suffixes. This function can parse + * both. Which one is the right way depends on the + * context. Wikipedia suggests that SI is customary for + * hardware metrics and network speeds, while IEC is + * customary for most data sizes used by software and volatile + * (RAM) memory. Hence be careful which one you pick! + * + * In either case we use just K, M, G as suffix, and not Ki, + * Mi, Gi or so (as IEC would suggest). That's because that's + * frickin' ugly. But this means you really need to make sure + * to document which base you are parsing when you use this + * call. */ + + struct table { + const char *suffix; + unsigned long long factor; + }; + + static const struct table iec[] = { + { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "T", 1024ULL*1024ULL*1024ULL*1024ULL }, + { "G", 1024ULL*1024ULL*1024ULL }, + { "M", 1024ULL*1024ULL }, + { "K", 1024ULL }, + { "B", 1ULL }, + { "", 1ULL }, + }; + + static const struct table si[] = { + { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL }, + { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL }, + { "T", 1000ULL*1000ULL*1000ULL*1000ULL }, + { "G", 1000ULL*1000ULL*1000ULL }, + { "M", 1000ULL*1000ULL }, + { "K", 1000ULL }, + { "B", 1ULL }, + { "", 1ULL }, + }; + + const struct table *table; + const char *p; + unsigned long long r = 0; + unsigned n_entries, start_pos = 0; + + assert(t); + assert(IN_SET(base, 1000, 1024)); + assert(size); + + if (base == 1000) { + table = si; + n_entries = ELEMENTSOF(si); + } else { + table = iec; + n_entries = ELEMENTSOF(iec); + } + + p = t; + do { + unsigned long long l, tmp; + double frac = 0; + char *e; + unsigned i; + + p += strspn(p, WHITESPACE); + + errno = 0; + l = strtoull(p, &e, 10); + if (errno > 0) + return -errno; + if (e == p) + return -EINVAL; + if (*p == '-') + return -ERANGE; + + if (*e == '.') { + e++; + + /* strtoull() itself would accept space/+/- */ + if (*e >= '0' && *e <= '9') { + unsigned long long l2; + char *e2; + + l2 = strtoull(e, &e2, 10); + if (errno > 0) + return -errno; + + /* Ignore failure. E.g. 10.M is valid */ + frac = l2; + for (; e < e2; e++) + frac /= 10; + } + } + + e += strspn(e, WHITESPACE); + + for (i = start_pos; i < n_entries; i++) + if (startswith(e, table[i].suffix)) + break; + + if (i >= n_entries) + return -EINVAL; + + if (l + (frac > 0) > ULLONG_MAX / table[i].factor) + return -ERANGE; + + tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor); + if (tmp > ULLONG_MAX - r) + return -ERANGE; + + r += tmp; + if ((unsigned long long) (uint64_t) r != r) + return -ERANGE; + + p = e + strlen(table[i].suffix); + + start_pos = i + 1; + + } while (*p); + + *size = r; + + return 0; +} + +int parse_range(const char *t, unsigned *lower, unsigned *upper) { + _cleanup_free_ char *word = NULL; + unsigned l, u; + int r; + + assert(lower); + assert(upper); + + /* Extract the lower bound. */ + r = extract_first_word(&t, &word, "-", EXTRACT_DONT_COALESCE_SEPARATORS); + if (r < 0) + return r; + if (r == 0) + return -EINVAL; + + r = safe_atou(word, &l); + if (r < 0) + return r; + + /* Check for the upper bound and extract it if needed */ + if (!t) + /* Single number with no dashes. */ + u = l; + else if (!*t) + /* Trailing dash is an error. */ + return -EINVAL; + else { + r = safe_atou(t, &u); + if (r < 0) + return r; + } + + *lower = l; + *upper = u; + return 0; +} + +int parse_errno(const char *t) { + int r, e; + + assert(t); + + r = errno_from_name(t); + if (r > 0) + return r; + + r = safe_atoi(t, &e); + if (r < 0) + return r; + + /* 0 is also allowed here */ + if (!errno_is_valid(e) && e != 0) + return -ERANGE; + + return e; +} + +#if HAVE_SECCOMP +int parse_syscall_and_errno(const char *in, char **name, int *error) { + _cleanup_free_ char *n = NULL; + char *p; + int e = -1; + + assert(in); + assert(name); + assert(error); + + /* + * This parse "syscall:errno" like "uname:EILSEQ", "@sync:255". + * If errno is omitted, then error is set to -1. + * Empty syscall name is not allowed. + * Here, we do not check that the syscall name is valid or not. + */ + + p = strchr(in, ':'); + if (p) { + e = seccomp_parse_errno_or_action(p + 1); + if (e < 0) + return e; + + n = strndup(in, p - in); + } else + n = strdup(in); + + if (!n) + return -ENOMEM; + + if (isempty(n)) + return -EINVAL; + + *error = e; + *name = TAKE_PTR(n); + + return 0; +} +#endif +#endif /* NM_IGNORED */ + +static const char *mangle_base(const char *s, unsigned *base) { + const char *k; + + assert(s); + assert(base); + + /* Base already explicitly specified, then don't do anything. */ + if (SAFE_ATO_MASK_FLAGS(*base) != 0) + return s; + + /* Support Python 3 style "0b" and 0x" prefixes, because they truly make sense, much more than C's "0" prefix for octal. */ + k = STARTSWITH_SET(s, "0b", "0B"); + if (k) { + *base = 2 | (*base & SAFE_ATO_ALL_FLAGS); + return k; + } + + k = STARTSWITH_SET(s, "0o", "0O"); + if (k) { + *base = 8 | (*base & SAFE_ATO_ALL_FLAGS); + return k; + } + + return s; +} + +int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) { + char *x = NULL; + unsigned long l; + + assert(s); + assert(SAFE_ATO_MASK_FLAGS(base) <= 16); + + /* strtoul() is happy to parse negative values, and silently converts them to unsigned values without + * generating an error. We want a clean error, hence let's look for the "-" prefix on our own, and + * generate an error. But let's do so only after strtoul() validated that the string is clean + * otherwise, so that we return EINVAL preferably over ERANGE. */ + + if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_WHITESPACE) && + strchr(WHITESPACE, s[0])) + return -EINVAL; + + s += strspn(s, WHITESPACE); + + if (FLAGS_SET(base, SAFE_ATO_REFUSE_PLUS_MINUS) && + IN_SET(s[0], '+', '-')) + return -EINVAL; /* Note that we check the "-" prefix again a second time below, but return a + * different error. I.e. if the SAFE_ATO_REFUSE_PLUS_MINUS flag is set we + * blanket refuse +/- prefixed integers, while if it is missing we'll just + * return ERANGE, because the string actually parses correctly, but doesn't + * fit in the return type. */ + + if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_ZERO) && + s[0] == '0' && !streq(s, "0")) + return -EINVAL; /* This is particularly useful to avoid ambiguities between C's octal + * notation and assumed-to-be-decimal integers with a leading zero. */ + + s = mangle_base(s, &base); + + errno = 0; + l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base) /* Let's mask off the flags bits so that only the actual + * base is left */); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; + if (l != 0 && s[0] == '-') + return -ERANGE; + if ((unsigned long) (unsigned) l != l) + return -ERANGE; + + if (ret_u) + *ret_u = (unsigned) l; + + return 0; +} + +int safe_atoi(const char *s, int *ret_i) { + unsigned base = 0; + char *x = NULL; + long l; + + assert(s); + + s += strspn(s, WHITESPACE); + s = mangle_base(s, &base); + + errno = 0; + l = strtol(s, &x, base); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; + if ((long) (int) l != l) + return -ERANGE; + + if (ret_i) + *ret_i = (int) l; + + return 0; +} + +int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) { + char *x = NULL; + unsigned long long l; + + assert(s); + assert(SAFE_ATO_MASK_FLAGS(base) <= 16); + + if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_WHITESPACE) && + strchr(WHITESPACE, s[0])) + return -EINVAL; + + s += strspn(s, WHITESPACE); + + if (FLAGS_SET(base, SAFE_ATO_REFUSE_PLUS_MINUS) && + IN_SET(s[0], '+', '-')) + return -EINVAL; + + if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_ZERO) && + s[0] == '0' && s[1] != 0) + return -EINVAL; + + s = mangle_base(s, &base); + + errno = 0; + l = strtoull(s, &x, SAFE_ATO_MASK_FLAGS(base)); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; + if (l != 0 && s[0] == '-') + return -ERANGE; + + if (ret_llu) + *ret_llu = l; + + return 0; +} + +int safe_atolli(const char *s, long long int *ret_lli) { + unsigned base = 0; + char *x = NULL; + long long l; + + assert(s); + + s += strspn(s, WHITESPACE); + s = mangle_base(s, &base); + + errno = 0; + l = strtoll(s, &x, base); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; + + if (ret_lli) + *ret_lli = l; + + return 0; +} + +int safe_atou8(const char *s, uint8_t *ret) { + unsigned base = 0; + unsigned long l; + char *x = NULL; + + assert(s); + + s += strspn(s, WHITESPACE); + s = mangle_base(s, &base); + + errno = 0; + l = strtoul(s, &x, base); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; + if (l != 0 && s[0] == '-') + return -ERANGE; + if ((unsigned long) (uint8_t) l != l) + return -ERANGE; + + if (ret) + *ret = (uint8_t) l; + return 0; +} + +int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) { + char *x = NULL; + unsigned long l; + + assert(s); + assert(SAFE_ATO_MASK_FLAGS(base) <= 16); + + if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_WHITESPACE) && + strchr(WHITESPACE, s[0])) + return -EINVAL; + + s += strspn(s, WHITESPACE); + + if (FLAGS_SET(base, SAFE_ATO_REFUSE_PLUS_MINUS) && + IN_SET(s[0], '+', '-')) + return -EINVAL; + + if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_ZERO) && + s[0] == '0' && s[1] != 0) + return -EINVAL; + + s = mangle_base(s, &base); + + errno = 0; + l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base)); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; + if (l != 0 && s[0] == '-') + return -ERANGE; + if ((unsigned long) (uint16_t) l != l) + return -ERANGE; + + if (ret) + *ret = (uint16_t) l; + + return 0; +} + +int safe_atoi16(const char *s, int16_t *ret) { + unsigned base = 0; + char *x = NULL; + long l; + + assert(s); + + s += strspn(s, WHITESPACE); + s = mangle_base(s, &base); + + errno = 0; + l = strtol(s, &x, base); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; + if ((long) (int16_t) l != l) + return -ERANGE; + + if (ret) + *ret = (int16_t) l; + + return 0; +} + +#if 0 /* NM_IGNORED */ +int safe_atod(const char *s, double *ret_d) { + _cleanup_(freelocalep) locale_t loc = (locale_t) 0; + char *x = NULL; + double d = 0; + + assert(s); + + loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0); + if (loc == (locale_t) 0) + return -errno; + + errno = 0; + d = strtod_l(s, &x, loc); + if (errno > 0) + return -errno; + if (!x || x == s || *x != 0) + return -EINVAL; + + if (ret_d) + *ret_d = (double) d; + + return 0; +} + +int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) { + size_t i; + unsigned val = 0; + const char *s; + + s = *p; + + /* accept any number of digits, strtoull is limited to 19 */ + for (i=0; i < digits; i++,s++) { + if (*s < '0' || *s > '9') { + if (i == 0) + return -EINVAL; + + /* too few digits, pad with 0 */ + for (; i < digits; i++) + val *= 10; + + break; + } + + val *= 10; + val += *s - '0'; + } + + /* maybe round up */ + if (*s >= '5' && *s <= '9') + val++; + + s += strspn(s, DIGITS); + + *p = s; + *res = val; + + return 0; +} + +int parse_percent_unbounded(const char *p) { + const char *pc, *n; + int r, v; + + pc = endswith(p, "%"); + if (!pc) + return -EINVAL; + + n = strndupa(p, pc - p); + r = safe_atoi(n, &v); + if (r < 0) + return r; + if (v < 0) + return -ERANGE; + + return v; +} + +int parse_percent(const char *p) { + int v; + + v = parse_percent_unbounded(p); + if (v > 100) + return -ERANGE; + + return v; +} + +int parse_permille_unbounded(const char *p) { + const char *pc, *pm, *dot, *n; + int r, q, v; + + pm = endswith(p, "‰"); + if (pm) { + n = strndupa(p, pm - p); + r = safe_atoi(n, &v); + if (r < 0) + return r; + if (v < 0) + return -ERANGE; + } else { + pc = endswith(p, "%"); + if (!pc) + return -EINVAL; + + dot = memchr(p, '.', pc - p); + if (dot) { + if (dot + 2 != pc) + return -EINVAL; + if (dot[1] < '0' || dot[1] > '9') + return -EINVAL; + q = dot[1] - '0'; + n = strndupa(p, dot - p); + } else { + q = 0; + n = strndupa(p, pc - p); + } + r = safe_atoi(n, &v); + if (r < 0) + return r; + if (v < 0) + return -ERANGE; + if (v > (INT_MAX - q) / 10) + return -ERANGE; + + v = v * 10 + q; + } + + return v; +} + +int parse_permille(const char *p) { + int v; + + v = parse_permille_unbounded(p); + if (v > 1000) + return -ERANGE; + + return v; +} + +int parse_nice(const char *p, int *ret) { + int n, r; + + r = safe_atoi(p, &n); + if (r < 0) + return r; + + if (!nice_is_valid(n)) + return -ERANGE; + + *ret = n; + return 0; +} + +int parse_ip_port(const char *s, uint16_t *ret) { + uint16_t l; + int r; + + r = safe_atou16(s, &l); + if (r < 0) + return r; + + if (l == 0) + return -EINVAL; + + *ret = (uint16_t) l; + + return 0; +} + +int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high) { + unsigned l, h; + int r; + + r = parse_range(s, &l, &h); + if (r < 0) + return r; + + if (l <= 0 || l > 65535 || h <= 0 || h > 65535) + return -EINVAL; + + if (h < l) + return -EINVAL; + + *low = l; + *high = h; + + return 0; +} + +int parse_ip_prefix_length(const char *s, int *ret) { + unsigned l; + int r; + + r = safe_atou(s, &l); + if (r < 0) + return r; + + if (l > 128) + return -ERANGE; + + *ret = (int) l; + + return 0; +} + +int parse_dev(const char *s, dev_t *ret) { + const char *major; + unsigned x, y; + size_t n; + int r; + + n = strspn(s, DIGITS); + if (n == 0) + return -EINVAL; + if (s[n] != ':') + return -EINVAL; + + major = strndupa(s, n); + r = safe_atou(major, &x); + if (r < 0) + return r; + + r = safe_atou(s + n + 1, &y); + if (r < 0) + return r; + + if (!DEVICE_MAJOR_VALID(x) || !DEVICE_MINOR_VALID(y)) + return -ERANGE; + + *ret = makedev(x, y); + return 0; +} + +int parse_oom_score_adjust(const char *s, int *ret) { + int r, v; + + assert(s); + assert(ret); + + r = safe_atoi(s, &v); + if (r < 0) + return r; + + if (v < OOM_SCORE_ADJ_MIN || v > OOM_SCORE_ADJ_MAX) + return -ERANGE; + + *ret = v; + return 0; +} + +int store_loadavg_fixed_point(unsigned long i, unsigned long f, loadavg_t *ret) { + assert(ret); + + if (i >= (~0UL << FSHIFT)) + return -ERANGE; + + i = i << FSHIFT; + f = DIV_ROUND_UP((f << FSHIFT), 100); + + if (f >= FIXED_1) + return -ERANGE; + + *ret = i | f; + return 0; +} + +int parse_loadavg_fixed_point(const char *s, loadavg_t *ret) { + const char *d, *f_str, *i_str; + unsigned long i, f; + int r; + + assert(s); + assert(ret); + + d = strchr(s, '.'); + if (!d) + return -EINVAL; + + i_str = strndupa(s, d - s); + f_str = d + 1; + + r = safe_atolu_full(i_str, 10, &i); + if (r < 0) + return r; + + r = safe_atolu_full(f_str, 10, &f); + if (r < 0) + return r; + + return store_loadavg_fixed_point(i, f, ret); +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/parse-util.h b/src/libnm-systemd-shared/src/basic/parse-util.h new file mode 100644 index 0000000..ba4e727 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/parse-util.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#if 0 /* NM_IGNORED */ +#include +#endif /* NM_IGNORED */ +#include +#include +#include + +#include "macro.h" + +typedef unsigned long loadavg_t; + +int parse_boolean(const char *v) _pure_; +int parse_dev(const char *s, dev_t *ret); +int parse_pid(const char *s, pid_t* ret_pid); +int parse_mode(const char *s, mode_t *ret); +int parse_ifindex(const char *s); +int parse_mtu(int family, const char *s, uint32_t *ret); + +int parse_size(const char *t, uint64_t base, uint64_t *size); +int parse_range(const char *t, unsigned *lower, unsigned *upper); +int parse_errno(const char *t); +#if HAVE_SECCOMP +int parse_syscall_and_errno(const char *in, char **name, int *error); +#endif + +#define SAFE_ATO_REFUSE_PLUS_MINUS (1U << 30) +#define SAFE_ATO_REFUSE_LEADING_ZERO (1U << 29) +#define SAFE_ATO_REFUSE_LEADING_WHITESPACE (1U << 28) +#define SAFE_ATO_ALL_FLAGS (SAFE_ATO_REFUSE_PLUS_MINUS|SAFE_ATO_REFUSE_LEADING_ZERO|SAFE_ATO_REFUSE_LEADING_WHITESPACE) +#define SAFE_ATO_MASK_FLAGS(base) ((base) & ~SAFE_ATO_ALL_FLAGS) + +int safe_atou_full(const char *s, unsigned base, unsigned *ret_u); + +static inline int safe_atou(const char *s, unsigned *ret_u) { + return safe_atou_full(s, 0, ret_u); +} + +int safe_atoi(const char *s, int *ret_i); +int safe_atolli(const char *s, long long int *ret_i); + +int safe_atou8(const char *s, uint8_t *ret); + +int safe_atou16_full(const char *s, unsigned base, uint16_t *ret); + +static inline int safe_atou16(const char *s, uint16_t *ret) { + return safe_atou16_full(s, 0, ret); +} + +static inline int safe_atoux16(const char *s, uint16_t *ret) { + return safe_atou16_full(s, 16, ret); +} + +int safe_atoi16(const char *s, int16_t *ret); + +static inline int safe_atou32_full(const char *s, unsigned base, uint32_t *ret_u) { + assert_cc(sizeof(uint32_t) == sizeof(unsigned)); + return safe_atou_full(s, base, (unsigned*) ret_u); +} + +static inline int safe_atou32(const char *s, uint32_t *ret_u) { + return safe_atou32_full(s, 0, (unsigned*) ret_u); +} + +static inline int safe_atoi32(const char *s, int32_t *ret_i) { + assert_cc(sizeof(int32_t) == sizeof(int)); + return safe_atoi(s, (int*) ret_i); +} + +int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu); + +static inline int safe_atollu(const char *s, long long unsigned *ret_llu) { + return safe_atollu_full(s, 0, ret_llu); +} + +static inline int safe_atou64(const char *s, uint64_t *ret_u) { + assert_cc(sizeof(uint64_t) == sizeof(unsigned long long)); + return safe_atollu(s, (unsigned long long*) ret_u); +} + +static inline int safe_atoi64(const char *s, int64_t *ret_i) { + assert_cc(sizeof(int64_t) == sizeof(long long int)); + return safe_atolli(s, (long long int*) ret_i); +} + +static inline int safe_atoux64(const char *s, uint64_t *ret) { + assert_cc(sizeof(int64_t) == sizeof(long long unsigned)); + return safe_atollu_full(s, 16, (long long unsigned*) ret); +} + +#if LONG_MAX == INT_MAX +static inline int safe_atolu_full(const char *s, unsigned base, long unsigned *ret_u) { + assert_cc(sizeof(unsigned long) == sizeof(unsigned)); + return safe_atou_full(s, base, (unsigned*) ret_u); +} +static inline int safe_atoli(const char *s, long int *ret_u) { + assert_cc(sizeof(long int) == sizeof(int)); + return safe_atoi(s, (int*) ret_u); +} +#else +static inline int safe_atolu_full(const char *s, unsigned base, unsigned long *ret_u) { + assert_cc(sizeof(unsigned long) == sizeof(unsigned long long)); + return safe_atollu_full(s, base, (unsigned long long*) ret_u); +} +static inline int safe_atoli(const char *s, long int *ret_u) { + assert_cc(sizeof(long int) == sizeof(long long int)); + return safe_atolli(s, (long long int*) ret_u); +} +#endif + +static inline int safe_atolu(const char *s, unsigned long *ret_u) { + return safe_atolu_full(s, 0, ret_u); +} + +#if SIZE_MAX == UINT_MAX +static inline int safe_atozu(const char *s, size_t *ret_u) { + assert_cc(sizeof(size_t) == sizeof(unsigned)); + return safe_atou(s, (unsigned *) ret_u); +} +#else +static inline int safe_atozu(const char *s, size_t *ret_u) { + assert_cc(sizeof(size_t) == sizeof(long unsigned)); + return safe_atolu(s, ret_u); +} +#endif + +int safe_atod(const char *s, double *ret_d); + +int parse_fractional_part_u(const char **s, size_t digits, unsigned *res); + +int parse_percent_unbounded(const char *p); +int parse_percent(const char *p); + +int parse_permille_unbounded(const char *p); +int parse_permille(const char *p); + +int parse_nice(const char *p, int *ret); + +int parse_ip_port(const char *s, uint16_t *ret); +int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high); + +int parse_ip_prefix_length(const char *s, int *ret); + +int parse_oom_score_adjust(const char *s, int *ret); + +/* Given a Linux load average (e.g. decimal number 34.89 where 34 is passed as i and 89 is passed as f), convert it + * to a loadavg_t. */ +int store_loadavg_fixed_point(unsigned long i, unsigned long f, loadavg_t *ret); +int parse_loadavg_fixed_point(const char *s, loadavg_t *ret); diff --git a/src/libnm-systemd-shared/src/basic/path-util.c b/src/libnm-systemd-shared/src/basic/path-util.c new file mode 100644 index 0000000..ea44c32 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/path-util.c @@ -0,0 +1,1188 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include + +/* When we include libgen.h because we need dirname() we immediately + * undefine basename() since libgen.h defines it as a macro to the + * POSIX version which is really broken. We prefer GNU basename(). */ +#include +#undef basename + +#include "alloc-util.h" +#include "extract-word.h" +#include "fd-util.h" +#include "fs-util.h" +#include "glob-util.h" +#include "log.h" +#include "macro.h" +#include "nulstr-util.h" +#include "parse-util.h" +#include "path-util.h" +#include "stat-util.h" +#include "string-util.h" +#include "strv.h" +#include "time-util.h" +#include "utf8.h" + +#if 0 /* NM_IGNORED */ +int path_split_and_make_absolute(const char *p, char ***ret) { + char **l; + int r; + + assert(p); + assert(ret); + + l = strv_split(p, ":"); + if (!l) + return -ENOMEM; + + r = path_strv_make_absolute_cwd(l); + if (r < 0) { + strv_free(l); + return r; + } + + *ret = l; + return r; +} + +char *path_make_absolute(const char *p, const char *prefix) { + assert(p); + + /* Makes every item in the list an absolute path by prepending + * the prefix, if specified and necessary */ + + if (path_is_absolute(p) || isempty(prefix)) + return strdup(p); + + return path_join(prefix, p); +} + +int safe_getcwd(char **ret) { + char *cwd; + + cwd = get_current_dir_name(); + if (!cwd) + return negative_errno(); + + /* Let's make sure the directory is really absolute, to protect us from the logic behind + * CVE-2018-1000001 */ + if (cwd[0] != '/') { + free(cwd); + return -ENOMEDIUM; + } + + *ret = cwd; + return 0; +} + +int path_make_absolute_cwd(const char *p, char **ret) { + char *c; + int r; + + assert(p); + assert(ret); + + /* Similar to path_make_absolute(), but prefixes with the + * current working directory. */ + + if (path_is_absolute(p)) + c = strdup(p); + else { + _cleanup_free_ char *cwd = NULL; + + r = safe_getcwd(&cwd); + if (r < 0) + return r; + + c = path_join(cwd, p); + } + if (!c) + return -ENOMEM; + + *ret = c; + return 0; +} + +int path_make_relative(const char *from_dir, const char *to_path, char **_r) { + char *f, *t, *r, *p; + unsigned n_parents = 0; + + assert(from_dir); + assert(to_path); + assert(_r); + + /* Strips the common part, and adds ".." elements as necessary. */ + + if (!path_is_absolute(from_dir) || !path_is_absolute(to_path)) + return -EINVAL; + + f = strdupa(from_dir); + t = strdupa(to_path); + + path_simplify(f, true); + path_simplify(t, true); + + /* Skip the common part. */ + for (;;) { + size_t a, b; + + f += *f == '/'; + t += *t == '/'; + + if (!*f) { + if (!*t) + /* from_dir equals to_path. */ + r = strdup("."); + else + /* from_dir is a parent directory of to_path. */ + r = strdup(t); + if (!r) + return -ENOMEM; + + *_r = r; + return 0; + } + + if (!*t) + break; + + a = strcspn(f, "/"); + b = strcspn(t, "/"); + + if (a != b || memcmp(f, t, a) != 0) + break; + + f += a; + t += b; + } + + /* If we're here, then "from_dir" has one or more elements that need to + * be replaced with "..". */ + + /* Count the number of necessary ".." elements. */ + for (; *f;) { + size_t w; + + w = strcspn(f, "/"); + + /* If this includes ".." we can't do a simple series of "..", refuse */ + if (w == 2 && f[0] == '.' && f[1] == '.') + return -EINVAL; + + /* Count number of elements */ + n_parents++; + + f += w; + f += *f == '/'; + } + + r = new(char, n_parents * 3 + strlen(t) + 1); + if (!r) + return -ENOMEM; + + for (p = r; n_parents > 0; n_parents--) + p = mempcpy(p, "../", 3); + + if (*t) + strcpy(p, t); + else + /* Remove trailing slash */ + *(--p) = 0; + + *_r = r; + return 0; +} + +char* path_startswith_strv(const char *p, char **set) { + char **s, *t; + + STRV_FOREACH(s, set) { + t = path_startswith(p, *s); + if (t) + return t; + } + + return NULL; +} + +int path_strv_make_absolute_cwd(char **l) { + char **s; + int r; + + /* Goes through every item in the string list and makes it + * absolute. This works in place and won't rollback any + * changes on failure. */ + + STRV_FOREACH(s, l) { + char *t; + + r = path_make_absolute_cwd(*s, &t); + if (r < 0) + return r; + + path_simplify(t, false); + free_and_replace(*s, t); + } + + return 0; +} + +char **path_strv_resolve(char **l, const char *root) { + char **s; + unsigned k = 0; + bool enomem = false; + int r; + + if (strv_isempty(l)) + return l; + + /* Goes through every item in the string list and canonicalize + * the path. This works in place and won't rollback any + * changes on failure. */ + + STRV_FOREACH(s, l) { + _cleanup_free_ char *orig = NULL; + char *t, *u; + + if (!path_is_absolute(*s)) { + free(*s); + continue; + } + + if (root) { + orig = *s; + t = path_join(root, orig); + if (!t) { + enomem = true; + continue; + } + } else + t = *s; + + r = chase_symlinks(t, root, 0, &u, NULL); + if (r == -ENOENT) { + if (root) { + u = TAKE_PTR(orig); + free(t); + } else + u = t; + } else if (r < 0) { + free(t); + + if (r == -ENOMEM) + enomem = true; + + continue; + } else if (root) { + char *x; + + free(t); + x = path_startswith(u, root); + if (x) { + /* restore the slash if it was lost */ + if (!startswith(x, "/")) + *(--x) = '/'; + + t = strdup(x); + free(u); + if (!t) { + enomem = true; + continue; + } + u = t; + } else { + /* canonicalized path goes outside of + * prefix, keep the original path instead */ + free_and_replace(u, orig); + } + } else + free(t); + + l[k++] = u; + } + + l[k] = NULL; + + if (enomem) + return NULL; + + return l; +} + +char **path_strv_resolve_uniq(char **l, const char *root) { + + if (strv_isempty(l)) + return l; + + if (!path_strv_resolve(l, root)) + return NULL; + + return strv_uniq(l); +} +#endif /* NM_IGNORED */ + +char *path_simplify(char *path, bool kill_dots) { + char *f, *t; + bool slash = false, ignore_slash = false, absolute; + + assert(path); + + /* Removes redundant inner and trailing slashes. Also removes unnecessary dots + * if kill_dots is true. Modifies the passed string in-place. + * + * ///foo//./bar/. becomes /foo/./bar/. (if kill_dots is false) + * ///foo//./bar/. becomes /foo/bar (if kill_dots is true) + * .//./foo//./bar/. becomes ././foo/./bar/. (if kill_dots is false) + * .//./foo//./bar/. becomes foo/bar (if kill_dots is true) + */ + + if (isempty(path)) + return path; + + absolute = path_is_absolute(path); + + f = path; + if (kill_dots && *f == '.' && IN_SET(f[1], 0, '/')) { + ignore_slash = true; + f++; + } + + for (t = path; *f; f++) { + + if (*f == '/') { + slash = true; + continue; + } + + if (slash) { + if (kill_dots && *f == '.' && IN_SET(f[1], 0, '/')) + continue; + + slash = false; + if (ignore_slash) + ignore_slash = false; + else + *(t++) = '/'; + } + + *(t++) = *f; + } + + /* Special rule, if we stripped everything, we either need a "/" (for the root directory) + * or "." for the current directory */ + if (t == path) { + if (absolute) + *(t++) = '/'; + else + *(t++) = '.'; + } + + *t = 0; + return path; +} + +#if 0 /* NM_IGNORED */ +int path_simplify_and_warn( + char *path, + unsigned flag, + const char *unit, + const char *filename, + unsigned line, + const char *lvalue) { + + bool fatal = flag & PATH_CHECK_FATAL; + + assert(!FLAGS_SET(flag, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)); + + if (!utf8_is_valid(path)) + return log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path); + + if (flag & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) { + bool absolute; + + absolute = path_is_absolute(path); + + if (!absolute && (flag & PATH_CHECK_ABSOLUTE)) + return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), + "%s= path is not absolute%s: %s", + lvalue, fatal ? "" : ", ignoring", path); + + if (absolute && (flag & PATH_CHECK_RELATIVE)) + return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), + "%s= path is absolute%s: %s", + lvalue, fatal ? "" : ", ignoring", path); + } + + path_simplify(path, true); + + if (!path_is_valid(path)) + return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), + "%s= path has invalid length (%zu bytes)%s.", + lvalue, strlen(path), fatal ? "" : ", ignoring"); + + if (!path_is_normalized(path)) + return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), + "%s= path is not normalized%s: %s", + lvalue, fatal ? "" : ", ignoring", path); + + return 0; +} +#endif /* NM_IGNORED */ + +char* path_startswith(const char *path, const char *prefix) { + assert(path); + assert(prefix); + + /* Returns a pointer to the start of the first component after the parts matched by + * the prefix, iff + * - both paths are absolute or both paths are relative, + * and + * - each component in prefix in turn matches a component in path at the same position. + * An empty string will be returned when the prefix and path are equivalent. + * + * Returns NULL otherwise. + */ + + if ((path[0] == '/') != (prefix[0] == '/')) + return NULL; + + for (;;) { + size_t a, b; + + path += strspn(path, "/"); + prefix += strspn(prefix, "/"); + + if (*prefix == 0) + return (char*) path; + + if (*path == 0) + return NULL; + + a = strcspn(path, "/"); + b = strcspn(prefix, "/"); + + if (a != b) + return NULL; + + if (memcmp(path, prefix, a) != 0) + return NULL; + + path += a; + prefix += b; + } +} + +int path_compare(const char *a, const char *b) { + int d; + + assert(a); + assert(b); + + /* A relative path and an absolute path must not compare as equal. + * Which one is sorted before the other does not really matter. + * Here a relative path is ordered before an absolute path. */ + d = (a[0] == '/') - (b[0] == '/'); + if (d != 0) + return d; + + for (;;) { + size_t j, k; + + a += strspn(a, "/"); + b += strspn(b, "/"); + + if (*a == 0 && *b == 0) + return 0; + + /* Order prefixes first: "/foo" before "/foo/bar" */ + if (*a == 0) + return -1; + if (*b == 0) + return 1; + + j = strcspn(a, "/"); + k = strcspn(b, "/"); + + /* Alphabetical sort: "/foo/aaa" before "/foo/b" */ + d = memcmp(a, b, MIN(j, k)); + if (d != 0) + return (d > 0) - (d < 0); /* sign of d */ + + /* Sort "/foo/a" before "/foo/aaa" */ + d = (j > k) - (j < k); /* sign of (j - k) */ + if (d != 0) + return d; + + a += j; + b += k; + } +} + +bool path_equal(const char *a, const char *b) { + return path_compare(a, b) == 0; +} + +#if 0 /* NM_IGNORED */ +bool path_equal_or_files_same(const char *a, const char *b, int flags) { + return path_equal(a, b) || files_same(a, b, flags) > 0; +} +#endif /* NM_IGNORED */ + +char* path_join_internal(const char *first, ...) { + char *joined, *q; + const char *p; + va_list ap; + bool slash; + size_t sz; + + /* Joins all listed strings until the sentinel and places a "/" between them unless the strings end/begin + * already with one so that it is unnecessary. Note that slashes which are already duplicate won't be + * removed. The string returned is hence always equal to or longer than the sum of the lengths of each + * individual string. + * + * Note: any listed empty string is simply skipped. This can be useful for concatenating strings of which some + * are optional. + * + * Examples: + * + * path_join("foo", "bar") → "foo/bar" + * path_join("foo/", "bar") → "foo/bar" + * path_join("", "foo", "", "bar", "") → "foo/bar" */ + + sz = strlen_ptr(first); + va_start(ap, first); + while ((p = va_arg(ap, char*)) != POINTER_MAX) + if (!isempty(p)) + sz += 1 + strlen(p); + va_end(ap); + + joined = new(char, sz + 1); + if (!joined) + return NULL; + + if (!isempty(first)) { + q = stpcpy(joined, first); + slash = endswith(first, "/"); + } else { + /* Skip empty items */ + joined[0] = 0; + q = joined; + slash = true; /* no need to generate a slash anymore */ + } + + va_start(ap, first); + while ((p = va_arg(ap, char*)) != POINTER_MAX) { + if (isempty(p)) + continue; + + if (!slash && p[0] != '/') + *(q++) = '/'; + + q = stpcpy(q, p); + slash = endswith(p, "/"); + } + va_end(ap); + + return joined; +} + +#if 0 /* NM_IGNORED */ +static int check_x_access(const char *path, int *ret_fd) { + if (ret_fd) { + _cleanup_close_ int fd = -1; + int r; + + /* We need to use O_PATH because there may be executables for which we have only exec + * permissions, but not read (usually suid executables). */ + fd = open(path, O_PATH|O_CLOEXEC); + if (fd < 0) + return -errno; + + r = access_fd(fd, X_OK); + if (r < 0) + return r; + + *ret_fd = TAKE_FD(fd); + } else { + /* Let's optimize things a bit by not opening the file if we don't need the fd. */ + if (access(path, X_OK) < 0) + return -errno; + } + + return 0; +} + +int find_executable_full(const char *name, bool use_path_envvar, char **ret_filename, int *ret_fd) { + int last_error, r; + const char *p = NULL; + + assert(name); + + if (is_path(name)) { + _cleanup_close_ int fd = -1; + + r = check_x_access(name, ret_fd ? &fd : NULL); + if (r < 0) + return r; + + if (ret_filename) { + r = path_make_absolute_cwd(name, ret_filename); + if (r < 0) + return r; + } + + if (ret_fd) + *ret_fd = TAKE_FD(fd); + + return 0; + } + + if (use_path_envvar) + /* Plain getenv, not secure_getenv, because we want to actually allow the user to pick the + * binary. */ + p = getenv("PATH"); + if (!p) + p = DEFAULT_PATH; + + last_error = -ENOENT; + + /* Resolve a single-component name to a full path */ + for (;;) { + _cleanup_free_ char *j = NULL, *element = NULL; + _cleanup_close_ int fd = -1; + + r = extract_first_word(&p, &element, ":", EXTRACT_RELAX|EXTRACT_DONT_COALESCE_SEPARATORS); + if (r < 0) + return r; + if (r == 0) + break; + + if (!path_is_absolute(element)) + continue; + + j = path_join(element, name); + if (!j) + return -ENOMEM; + + r = check_x_access(j, ret_fd ? &fd : NULL); + if (r >= 0) { + _cleanup_free_ char *with_dash; + + with_dash = strjoin(j, "/"); + if (!with_dash) + return -ENOMEM; + + /* If this passes, it must be a directory, and so should be skipped. */ + if (access(with_dash, X_OK) >= 0) + continue; + + /* We can't just `continue` inverting this case, since we need to update last_error. */ + if (errno == ENOTDIR) { + /* Found it! */ + if (ret_filename) + *ret_filename = path_simplify(TAKE_PTR(j), false); + if (ret_fd) + *ret_fd = TAKE_FD(fd); + + return 0; + } + } + + /* PATH entries which we don't have access to are ignored, as per tradition. */ + if (errno != EACCES) + last_error = -errno; + } + + return last_error; +} + +bool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool update) { + bool changed = false; + const char* const* i; + + assert(timestamp); + + if (!paths) + return false; + + STRV_FOREACH(i, paths) { + struct stat stats; + usec_t u; + + if (stat(*i, &stats) < 0) + continue; + + u = timespec_load(&stats.st_mtim); + + /* first check */ + if (*timestamp >= u) + continue; + + log_debug("timestamp of '%s' changed", *i); + + /* update timestamp */ + if (update) { + *timestamp = u; + changed = true; + } else + return true; + } + + return changed; +} + +static int executable_is_good(const char *executable) { + _cleanup_free_ char *p = NULL, *d = NULL; + int r; + + r = find_executable(executable, &p); + if (r == -ENOENT) + return 0; + if (r < 0) + return r; + + /* An fsck that is linked to /bin/true is a non-existent fsck */ + + r = readlink_malloc(p, &d); + if (r == -EINVAL) /* not a symlink */ + return 1; + if (r < 0) + return r; + + return !PATH_IN_SET(d, "true" + "/bin/true", + "/usr/bin/true", + "/dev/null"); +} + +int fsck_exists(const char *fstype) { + const char *checker; + + assert(fstype); + + if (streq(fstype, "auto")) + return -EINVAL; + + checker = strjoina("fsck.", fstype); + return executable_is_good(checker); +} + +int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg) { + char *p; + int r; + + /* + * This function is intended to be used in command line + * parsers, to handle paths that are passed in. It makes the + * path absolute, and reduces it to NULL if omitted or + * root (the latter optionally). + * + * NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON + * SUCCESS! Hence, do not pass in uninitialized pointers. + */ + + if (isempty(path)) { + *arg = mfree(*arg); + return 0; + } + + r = path_make_absolute_cwd(path, &p); + if (r < 0) + return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path); + + path_simplify(p, false); + if (suppress_root && empty_or_root(p)) + p = mfree(p); + + free_and_replace(*arg, p); + + return 0; +} + +char* dirname_malloc(const char *path) { + char *d, *dir, *dir2; + + assert(path); + + d = strdup(path); + if (!d) + return NULL; + + dir = dirname(d); + assert(dir); + + if (dir == d) + return d; + + dir2 = strdup(dir); + free(d); + + return dir2; +} + +const char *last_path_component(const char *path) { + + /* Finds the last component of the path, preserving the optional trailing slash that signifies a directory. + * + * a/b/c → c + * a/b/c/ → c/ + * x → x + * x/ → x/ + * /y → y + * /y/ → y/ + * / → / + * // → / + * /foo/a → a + * /foo/a/ → a/ + * + * Also, the empty string is mapped to itself. + * + * This is different than basename(), which returns "" when a trailing slash is present. + */ + + unsigned l, k; + + if (!path) + return NULL; + + l = k = strlen(path); + if (l == 0) /* special case — an empty string */ + return path; + + while (k > 0 && path[k-1] == '/') + k--; + + if (k == 0) /* the root directory */ + return path + l - 1; + + while (k > 0 && path[k-1] != '/') + k--; + + return path + k; +} + +int path_extract_filename(const char *p, char **ret) { + _cleanup_free_ char *a = NULL; + const char *c, *e = NULL, *q; + + /* Extracts the filename part (i.e. right-most component) from a path, i.e. string that passes + * filename_is_valid(). A wrapper around last_path_component(), but eats up trailing slashes. */ + + if (!p) + return -EINVAL; + + c = last_path_component(p); + + for (q = c; *q != 0; q++) + if (*q != '/') + e = q + 1; + + if (!e) /* no valid character? */ + return -EINVAL; + + a = strndup(c, e - c); + if (!a) + return -ENOMEM; + + if (!filename_is_valid(a)) + return -EINVAL; + + *ret = TAKE_PTR(a); + + return 0; +} +#endif /* NM_IGNORED */ + +bool filename_is_valid(const char *p) { + const char *e; + + if (isempty(p)) + return false; + + if (dot_or_dot_dot(p)) + return false; + + e = strchrnul(p, '/'); + if (*e != 0) + return false; + + if (e - p > FILENAME_MAX) /* FILENAME_MAX is counted *without* the trailing NUL byte */ + return false; + + return true; +} + +bool path_is_valid(const char *p) { + + if (isempty(p)) + return false; + + if (strlen(p) >= PATH_MAX) /* PATH_MAX is counted *with* the trailing NUL byte */ + return false; + + return true; +} + +bool path_is_normalized(const char *p) { + + if (!path_is_valid(p)) + return false; + + if (dot_or_dot_dot(p)) + return false; + + if (startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../")) + return false; + + if (startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./")) + return false; + + if (strstr(p, "//")) + return false; + + return true; +} + +#if 0 /* NM_IGNORED */ +char *file_in_same_dir(const char *path, const char *filename) { + char *e, *ret; + size_t k; + + assert(path); + assert(filename); + + /* This removes the last component of path and appends + * filename, unless the latter is absolute anyway or the + * former isn't */ + + if (path_is_absolute(filename)) + return strdup(filename); + + e = strrchr(path, '/'); + if (!e) + return strdup(filename); + + k = strlen(filename); + ret = new(char, (e + 1 - path) + k + 1); + if (!ret) + return NULL; + + memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1); + return ret; +} + +bool hidden_or_backup_file(const char *filename) { + const char *p; + + assert(filename); + + if (filename[0] == '.' || + streq(filename, "lost+found") || + streq(filename, "aquota.user") || + streq(filename, "aquota.group") || + endswith(filename, "~")) + return true; + + p = strrchr(filename, '.'); + if (!p) + return false; + + /* Please, let's not add more entries to the list below. If external projects think it's a good idea to come up + * with always new suffixes and that everybody else should just adjust to that, then it really should be on + * them. Hence, in future, let's not add any more entries. Instead, let's ask those packages to instead adopt + * one of the generic suffixes/prefixes for hidden files or backups, possibly augmented with an additional + * string. Specifically: there's now: + * + * The generic suffixes "~" and ".bak" for backup files + * The generic prefix "." for hidden files + * + * Thus, if a new package manager "foopkg" wants its own set of ".foopkg-new", ".foopkg-old", ".foopkg-dist" + * or so registered, let's refuse that and ask them to use ".foopkg.new", ".foopkg.old" or ".foopkg~" instead. + */ + + return STR_IN_SET(p + 1, + "rpmnew", + "rpmsave", + "rpmorig", + "dpkg-old", + "dpkg-new", + "dpkg-tmp", + "dpkg-dist", + "dpkg-bak", + "dpkg-backup", + "dpkg-remove", + "ucf-new", + "ucf-old", + "ucf-dist", + "swp", + "bak", + "old", + "new"); +} + +bool is_device_path(const char *path) { + + /* Returns true on paths that likely refer to a device, either by path in sysfs or to something in /dev */ + + return PATH_STARTSWITH_SET(path, "/dev/", "/sys/"); +} + +bool valid_device_node_path(const char *path) { + + /* Some superficial checks whether the specified path is a valid device node path, all without looking at the + * actual device node. */ + + if (!PATH_STARTSWITH_SET(path, "/dev/", "/run/systemd/inaccessible/")) + return false; + + if (endswith(path, "/")) /* can't be a device node if it ends in a slash */ + return false; + + return path_is_normalized(path); +} + +bool valid_device_allow_pattern(const char *path) { + assert(path); + + /* Like valid_device_node_path(), but also allows full-subsystem expressions, like DeviceAllow= and DeviceDeny= + * accept it */ + + if (STARTSWITH_SET(path, "block-", "char-")) + return true; + + return valid_device_node_path(path); +} + +int systemd_installation_has_version(const char *root, unsigned minimal_version) { + const char *pattern; + int r; + + /* Try to guess if systemd installation is later than the specified version. This + * is hacky and likely to yield false negatives, particularly if the installation + * is non-standard. False positives should be relatively rare. + */ + + NULSTR_FOREACH(pattern, + /* /lib works for systems without usr-merge, and for systems with a sane + * usr-merge, where /lib is a symlink to /usr/lib. /usr/lib is necessary + * for Gentoo which does a merge without making /lib a symlink. + */ + "lib/systemd/libsystemd-shared-*.so\0" + "lib64/systemd/libsystemd-shared-*.so\0" + "usr/lib/systemd/libsystemd-shared-*.so\0" + "usr/lib64/systemd/libsystemd-shared-*.so\0") { + + _cleanup_strv_free_ char **names = NULL; + _cleanup_free_ char *path = NULL; + char *c, **name; + + path = path_join(root, pattern); + if (!path) + return -ENOMEM; + + r = glob_extend(&names, path, 0); + if (r == -ENOENT) + continue; + if (r < 0) + return r; + + assert_se(c = endswith(path, "*.so")); + *c = '\0'; /* truncate the glob part */ + + STRV_FOREACH(name, names) { + /* This is most likely to run only once, hence let's not optimize anything. */ + char *t, *t2; + unsigned version; + + t = startswith(*name, path); + if (!t) + continue; + + t2 = endswith(t, ".so"); + if (!t2) + continue; + + t2[0] = '\0'; /* truncate the suffix */ + + r = safe_atou(t, &version); + if (r < 0) { + log_debug_errno(r, "Found libsystemd shared at \"%s.so\", but failed to parse version: %m", *name); + continue; + } + + log_debug("Found libsystemd shared at \"%s.so\", version %u (%s).", + *name, version, + version >= minimal_version ? "OK" : "too old"); + if (version >= minimal_version) + return true; + } + } + + return false; +} +#endif /* NM_IGNORED */ + +bool dot_or_dot_dot(const char *path) { + if (!path) + return false; + if (path[0] != '.') + return false; + if (path[1] == 0) + return true; + if (path[1] != '.') + return false; + + return path[2] == 0; +} + +#if 0 /* NM_IGNORED */ +bool empty_or_root(const char *root) { + + /* For operations relative to some root directory, returns true if the specified root directory is redundant, + * i.e. either / or NULL or the empty string or any equivalent. */ + + if (!root) + return true; + + return root[strspn(root, "/")] == 0; +} + +bool path_strv_contains(char **l, const char *path) { + char **i; + + STRV_FOREACH(i, l) + if (path_equal(*i, path)) + return true; + + return false; +} + +bool prefixed_path_strv_contains(char **l, const char *path) { + char **i, *j; + + STRV_FOREACH(i, l) { + j = *i; + if (*j == '-') + j++; + if (*j == '+') + j++; + if (path_equal(j, path)) + return true; + } + + return false; +} + +bool credential_name_valid(const char *s) { + /* We want that credential names are both valid in filenames (since that's our primary way to pass + * them around) and as fdnames (which is how we might want to pass them around eventually) */ + return filename_is_valid(s) && fdname_is_valid(s); +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/path-util.h b/src/libnm-systemd-shared/src/basic/path-util.h new file mode 100644 index 0000000..988f058 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/path-util.h @@ -0,0 +1,190 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include + +#include "macro.h" +#include "string-util.h" +#include "strv.h" +#include "time-util.h" + +#if 0 /* NM_IGNORED */ +#define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin" +#define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0" + +#define PATH_NORMAL_SBIN_BIN(x) x "bin" +#define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0" + +#if HAVE_SPLIT_BIN +# define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x) +# define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x) +#else +# define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x) +# define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x) +#endif + +#define DEFAULT_PATH_NORMAL PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/") +#define DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/") +#define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_SBIN_BIN("/") +#define DEFAULT_PATH_SPLIT_USR_NULSTR DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/") +#define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/") + +#if HAVE_SPLIT_USR +# define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR +# define DEFAULT_PATH_NULSTR DEFAULT_PATH_SPLIT_USR_NULSTR +#else +# define DEFAULT_PATH DEFAULT_PATH_NORMAL +# define DEFAULT_PATH_NULSTR DEFAULT_PATH_NORMAL_NULSTR +#endif +#endif /* NM_IGNORED */ + +#ifndef DEFAULT_USER_PATH +# define DEFAULT_USER_PATH DEFAULT_PATH +#endif + +static inline bool is_path(const char *p) { + assert(p); + return strchr(p, '/'); +} + +static inline bool path_is_absolute(const char *p) { + assert(p); + return p[0] == '/'; +} + +int path_split_and_make_absolute(const char *p, char ***ret); +char* path_make_absolute(const char *p, const char *prefix); +int safe_getcwd(char **ret); +int path_make_absolute_cwd(const char *p, char **ret); +int path_make_relative(const char *from_dir, const char *to_path, char **_r); +char* path_startswith(const char *path, const char *prefix) _pure_; +int path_compare(const char *a, const char *b) _pure_; +bool path_equal(const char *a, const char *b) _pure_; +bool path_equal_or_files_same(const char *a, const char *b, int flags); +char* path_join_internal(const char *first, ...); +#define path_join(x, ...) path_join_internal(x, __VA_ARGS__, POINTER_MAX) + +char* path_simplify(char *path, bool kill_dots); + +enum { + PATH_CHECK_FATAL = 1 << 0, /* If not set, then error message is appended with 'ignoring'. */ + PATH_CHECK_ABSOLUTE = 1 << 1, + PATH_CHECK_RELATIVE = 1 << 2, +}; + +int path_simplify_and_warn(char *path, unsigned flag, const char *unit, const char *filename, unsigned line, const char *lvalue); + +static inline bool path_equal_ptr(const char *a, const char *b) { + return !!a == !!b && (!a || path_equal(a, b)); +} + +/* Note: the search terminates on the first NULL item. */ +#define PATH_IN_SET(p, ...) path_strv_contains(STRV_MAKE(__VA_ARGS__), p) + +char* path_startswith_strv(const char *p, char **set); +#define PATH_STARTSWITH_SET(p, ...) path_startswith_strv(p, STRV_MAKE(__VA_ARGS__)) + +int path_strv_make_absolute_cwd(char **l); +char** path_strv_resolve(char **l, const char *root); +char** path_strv_resolve_uniq(char **l, const char *root); + +int find_executable_full(const char *name, bool use_path_envvar, char **ret_filename, int *ret_fd); +static inline int find_executable(const char *name, char **ret_filename) { + return find_executable_full(name, true, ret_filename, NULL); +} + +bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update); + +int fsck_exists(const char *fstype); + +/* Iterates through the path prefixes of the specified path, going up + * the tree, to root. Also returns "" (and not "/"!) for the root + * directory. Excludes the specified directory itself */ +#define PATH_FOREACH_PREFIX(prefix, path) \ + for (char *_slash = ({ \ + path_simplify(strcpy(prefix, path), false); \ + streq(prefix, "/") ? NULL : strrchr(prefix, '/'); \ + }); \ + _slash && ((*_slash = 0), true); \ + _slash = strrchr((prefix), '/')) + +/* Same as PATH_FOREACH_PREFIX but also includes the specified path itself */ +#define PATH_FOREACH_PREFIX_MORE(prefix, path) \ + for (char *_slash = ({ \ + path_simplify(strcpy(prefix, path), false); \ + if (streq(prefix, "/")) \ + prefix[0] = 0; \ + strrchr(prefix, 0); \ + }); \ + _slash && ((*_slash = 0), true); \ + _slash = strrchr((prefix), '/')) + +/* Similar to path_join(), but only works for two components, and only the first one may be NULL and returns + * an alloca() buffer, or possibly a const pointer into the path parameter. */ +#define prefix_roota(root, path) \ + ({ \ + const char* _path = (path), *_root = (root), *_ret; \ + char *_p, *_n; \ + size_t _l; \ + while (_path[0] == '/' && _path[1] == '/') \ + _path ++; \ + if (isempty(_root)) \ + _ret = _path; \ + else { \ + _l = strlen(_root) + 1 + strlen(_path) + 1; \ + _n = newa(char, _l); \ + _p = stpcpy(_n, _root); \ + while (_p > _n && _p[-1] == '/') \ + _p--; \ + if (_path[0] != '/') \ + *(_p++) = '/'; \ + strcpy(_p, _path); \ + _ret = _n; \ + } \ + _ret; \ + }) + +int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg); + +char* dirname_malloc(const char *path); +const char *last_path_component(const char *path); +int path_extract_filename(const char *p, char **ret); + +bool filename_is_valid(const char *p) _pure_; +bool path_is_valid(const char *p) _pure_; +bool path_is_normalized(const char *p) _pure_; + +char *file_in_same_dir(const char *path, const char *filename); + +bool hidden_or_backup_file(const char *filename) _pure_; + +bool is_device_path(const char *path); + +bool valid_device_node_path(const char *path); +bool valid_device_allow_pattern(const char *path); + +int systemd_installation_has_version(const char *root, unsigned minimal_version); + +bool dot_or_dot_dot(const char *path); + +static inline const char *skip_dev_prefix(const char *p) { + const char *e; + + /* Drop any /dev prefix if there is any */ + + e = path_startswith(p, "/dev/"); + + return e ?: p; +} + +bool empty_or_root(const char *root); +static inline const char *empty_to_root(const char *path) { + return isempty(path) ? "/" : path; +} + +bool path_strv_contains(char **l, const char *path); +bool prefixed_path_strv_contains(char **l, const char *path); + +bool credential_name_valid(const char *s); diff --git a/src/libnm-systemd-shared/src/basic/prioq.c b/src/libnm-systemd-shared/src/basic/prioq.c new file mode 100644 index 0000000..19a9bc5 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/prioq.c @@ -0,0 +1,302 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* + * Priority Queue + * The prioq object implements a priority queue. That is, it orders objects by + * their priority and allows O(1) access to the object with the highest + * priority. Insertion and removal are Θ(log n). Optionally, the caller can + * provide a pointer to an index which will be kept up-to-date by the prioq. + * + * The underlying algorithm used in this implementation is a Heap. + */ + +#include "nm-sd-adapt-shared.h" + +#include +#include + +#include "alloc-util.h" +#include "hashmap.h" +#include "prioq.h" + +struct prioq_item { + void *data; + unsigned *idx; +}; + +struct Prioq { + compare_func_t compare_func; + unsigned n_items, n_allocated; + + struct prioq_item *items; +}; + +Prioq *prioq_new(compare_func_t compare_func) { + Prioq *q; + + q = new(Prioq, 1); + if (!q) + return q; + + *q = (Prioq) { + .compare_func = compare_func, + }; + + return q; +} + +Prioq* prioq_free(Prioq *q) { + if (!q) + return NULL; + + free(q->items); + return mfree(q); +} + +int prioq_ensure_allocated(Prioq **q, compare_func_t compare_func) { + assert(q); + + if (*q) + return 0; + + *q = prioq_new(compare_func); + if (!*q) + return -ENOMEM; + + return 0; +} + +static void swap(Prioq *q, unsigned j, unsigned k) { + assert(q); + assert(j < q->n_items); + assert(k < q->n_items); + + assert(!q->items[j].idx || *(q->items[j].idx) == j); + assert(!q->items[k].idx || *(q->items[k].idx) == k); + + SWAP_TWO(q->items[j].data, q->items[k].data); + SWAP_TWO(q->items[j].idx, q->items[k].idx); + + if (q->items[j].idx) + *q->items[j].idx = j; + + if (q->items[k].idx) + *q->items[k].idx = k; +} + +static unsigned shuffle_up(Prioq *q, unsigned idx) { + assert(q); + assert(idx < q->n_items); + + while (idx > 0) { + unsigned k; + + k = (idx-1)/2; + + if (q->compare_func(q->items[k].data, q->items[idx].data) <= 0) + break; + + swap(q, idx, k); + idx = k; + } + + return idx; +} + +static unsigned shuffle_down(Prioq *q, unsigned idx) { + assert(q); + + for (;;) { + unsigned j, k, s; + + k = (idx+1)*2; /* right child */ + j = k-1; /* left child */ + + if (j >= q->n_items) + break; + + if (q->compare_func(q->items[j].data, q->items[idx].data) < 0) + + /* So our left child is smaller than we are, let's + * remember this fact */ + s = j; + else + s = idx; + + if (k < q->n_items && + q->compare_func(q->items[k].data, q->items[s].data) < 0) + + /* So our right child is smaller than we are, let's + * remember this fact */ + s = k; + + /* s now points to the smallest of the three items */ + + if (s == idx) + /* No swap necessary, we're done */ + break; + + swap(q, idx, s); + idx = s; + } + + return idx; +} + +int prioq_put(Prioq *q, void *data, unsigned *idx) { + struct prioq_item *i; + unsigned k; + + assert(q); + + if (q->n_items >= q->n_allocated) { + unsigned n; + struct prioq_item *j; + + n = MAX((q->n_items+1) * 2, 16u); + j = reallocarray(q->items, n, sizeof(struct prioq_item)); + if (!j) + return -ENOMEM; + + q->items = j; + q->n_allocated = n; + } + + k = q->n_items++; + i = q->items + k; + i->data = data; + i->idx = idx; + + if (idx) + *idx = k; + + shuffle_up(q, k); + + return 0; +} + +static void remove_item(Prioq *q, struct prioq_item *i) { + struct prioq_item *l; + + assert(q); + assert(i); + + l = q->items + q->n_items - 1; + + if (i == l) + /* Last entry, let's just remove it */ + q->n_items--; + else { + unsigned k; + + /* Not last entry, let's replace the last entry with + * this one, and reshuffle */ + + k = i - q->items; + + i->data = l->data; + i->idx = l->idx; + if (i->idx) + *i->idx = k; + q->n_items--; + + k = shuffle_down(q, k); + shuffle_up(q, k); + } +} + +_pure_ static struct prioq_item* find_item(Prioq *q, void *data, unsigned *idx) { + struct prioq_item *i; + + assert(q); + + if (q->n_items <= 0) + return NULL; + + if (idx) { + if (*idx == PRIOQ_IDX_NULL || + *idx >= q->n_items) + return NULL; + + i = q->items + *idx; + if (i->data != data) + return NULL; + + return i; + } else { + for (i = q->items; i < q->items + q->n_items; i++) + if (i->data == data) + return i; + return NULL; + } +} + +int prioq_remove(Prioq *q, void *data, unsigned *idx) { + struct prioq_item *i; + + if (!q) + return 0; + + i = find_item(q, data, idx); + if (!i) + return 0; + + remove_item(q, i); + return 1; +} + +int prioq_reshuffle(Prioq *q, void *data, unsigned *idx) { + struct prioq_item *i; + unsigned k; + + assert(q); + + i = find_item(q, data, idx); + if (!i) + return 0; + + k = i - q->items; + k = shuffle_down(q, k); + shuffle_up(q, k); + return 1; +} + +void *prioq_peek_by_index(Prioq *q, unsigned idx) { + if (!q) + return NULL; + + if (idx >= q->n_items) + return NULL; + + return q->items[idx].data; +} + +void *prioq_pop(Prioq *q) { + void *data; + + if (!q) + return NULL; + + if (q->n_items <= 0) + return NULL; + + data = q->items[0].data; + remove_item(q, q->items); + return data; +} + +unsigned prioq_size(Prioq *q) { + + if (!q) + return 0; + + return q->n_items; +} + +bool prioq_isempty(Prioq *q) { + + if (!q) + return true; + + return q->n_items <= 0; +} diff --git a/src/libnm-systemd-shared/src/basic/prioq.h b/src/libnm-systemd-shared/src/basic/prioq.h new file mode 100644 index 0000000..951576c --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/prioq.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#include "hashmap.h" +#include "macro.h" + +typedef struct Prioq Prioq; + +#define PRIOQ_IDX_NULL ((unsigned) -1) + +Prioq *prioq_new(compare_func_t compare); +Prioq *prioq_free(Prioq *q); +DEFINE_TRIVIAL_CLEANUP_FUNC(Prioq*, prioq_free); +int prioq_ensure_allocated(Prioq **q, compare_func_t compare_func); + +int prioq_put(Prioq *q, void *data, unsigned *idx); +int prioq_remove(Prioq *q, void *data, unsigned *idx); +int prioq_reshuffle(Prioq *q, void *data, unsigned *idx); + +void *prioq_peek_by_index(Prioq *q, unsigned idx) _pure_; +static inline void *prioq_peek(Prioq *q) { + return prioq_peek_by_index(q, 0); +} +void *prioq_pop(Prioq *q); + +#define PRIOQ_FOREACH_ITEM(q, p) \ + for (unsigned _i = 0; (p = prioq_peek_by_index(q, _i)); _i++) + +unsigned prioq_size(Prioq *q) _pure_; +bool prioq_isempty(Prioq *q) _pure_; diff --git a/src/libnm-systemd-shared/src/basic/process-util.c b/src/libnm-systemd-shared/src/basic/process-util.c new file mode 100644 index 0000000..0e25b02 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/process-util.c @@ -0,0 +1,1662 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if 0 /* NM_IGNORED */ +#if HAVE_VALGRIND_VALGRIND_H +#include +#endif +#endif /* NM_IGNORED */ + +#include "alloc-util.h" +#include "architecture.h" +#include "env-util.h" +#include "errno-util.h" +#include "escape.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" +#include "ioprio.h" +#include "locale-util.h" +#include "log.h" +#include "macro.h" +#include "memory-util.h" +#include "missing_sched.h" +#include "missing_syscall.h" +#include "namespace-util.h" +#include "path-util.h" +#include "process-util.h" +#include "raw-clone.h" +#include "rlimit-util.h" +#include "signal-util.h" +#include "stat-util.h" +#include "stdio-util.h" +#include "string-table.h" +#include "string-util.h" +#include "terminal-util.h" +#include "user-util.h" +#include "utf8.h" + +#if 0 /* NM_IGNORED */ + +/* The kernel limits userspace processes to TASK_COMM_LEN (16 bytes), but allows higher values for its own + * workers, e.g. "kworker/u9:3-kcryptd/253:0". Let's pick a fixed smallish limit that will work for the kernel. + */ +#define COMM_MAX_LEN 128 + +static int get_process_state(pid_t pid) { + _cleanup_free_ char *line = NULL; + const char *p; + char state; + int r; + + assert(pid >= 0); + + /* Shortcut: if we are enquired about our own state, we are obviously running */ + if (pid == 0 || pid == getpid_cached()) + return (unsigned char) 'R'; + + p = procfs_file_alloca(pid, "stat"); + + r = read_one_line_file(p, &line); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; + + p = strrchr(line, ')'); + if (!p) + return -EIO; + + p++; + + if (sscanf(p, " %c", &state) != 1) + return -EIO; + + return (unsigned char) state; +} + +int get_process_comm(pid_t pid, char **ret) { + _cleanup_free_ char *escaped = NULL, *comm = NULL; + int r; + + assert(ret); + assert(pid >= 0); + + if (pid == 0 || pid == getpid_cached()) { + comm = new0(char, TASK_COMM_LEN + 1); /* Must fit in 16 byte according to prctl(2) */ + if (!comm) + return -ENOMEM; + + if (prctl(PR_GET_NAME, comm) < 0) + return -errno; + } else { + const char *p; + + p = procfs_file_alloca(pid, "comm"); + + /* Note that process names of kernel threads can be much longer than TASK_COMM_LEN */ + r = read_one_line_file(p, &comm); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; + } + + escaped = new(char, COMM_MAX_LEN); + if (!escaped) + return -ENOMEM; + + /* Escape unprintable characters, just in case, but don't grow the string beyond the underlying size */ + cellescape(escaped, COMM_MAX_LEN, comm); + + *ret = TAKE_PTR(escaped); + return 0; +} + +int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **line) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *t = NULL, *ans = NULL; + const char *p; + int r; + size_t k; + + /* This is supposed to be a safety guard against runaway command lines. */ + size_t max_length = sc_arg_max(); + + assert(line); + assert(pid >= 0); + + /* Retrieves a process' command line. Replaces non-utf8 bytes by replacement character (�). If + * max_columns is != -1 will return a string of the specified console width at most, abbreviated with + * an ellipsis. If PROCESS_CMDLINE_COMM_FALLBACK is specified in flags and the process has no command + * line set (the case for kernel threads), or has a command line that resolves to the empty string + * will return the "comm" name of the process instead. This will use at most _SC_ARG_MAX bytes of + * input data. + * + * Returns -ESRCH if the process doesn't exist, and -ENOENT if the process has no command line (and + * comm_fallback is false). Returns 0 and sets *line otherwise. */ + + p = procfs_file_alloca(pid, "cmdline"); + r = fopen_unlocked(p, "re", &f); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; + + /* We assume that each four-byte character uses one or two columns. If we ever check for combining + * characters, this assumption will need to be adjusted. */ + if ((size_t) 4 * max_columns + 1 < max_columns) + max_length = MIN(max_length, (size_t) 4 * max_columns + 1); + + t = new(char, max_length); + if (!t) + return -ENOMEM; + + k = fread(t, 1, max_length, f); + if (k > 0) { + /* Arguments are separated by NULs. Let's replace those with spaces. */ + for (size_t i = 0; i < k - 1; i++) + if (t[i] == '\0') + t[i] = ' '; + + t[k] = '\0'; /* Normally, t[k] is already NUL, so this is just a guard in case of short read */ + } else { + /* We only treat getting nothing as an error. We *could* also get an error after reading some + * data, but we ignore that case, as such an error is rather unlikely and we prefer to get + * some data rather than none. */ + if (ferror(f)) + return -errno; + + if (!(flags & PROCESS_CMDLINE_COMM_FALLBACK)) + return -ENOENT; + + /* Kernel threads have no argv[] */ + _cleanup_free_ char *t2 = NULL; + + r = get_process_comm(pid, &t2); + if (r < 0) + return r; + + mfree(t); + t = strjoin("[", t2, "]"); + if (!t) + return -ENOMEM; + } + + delete_trailing_chars(t, WHITESPACE); + + bool eight_bit = (flags & PROCESS_CMDLINE_USE_LOCALE) && !is_locale_utf8(); + + ans = escape_non_printable_full(t, max_columns, eight_bit); + if (!ans) + return -ENOMEM; + + (void) str_realloc(&ans); + *line = TAKE_PTR(ans); + return 0; +} + +static int update_argv(const char name[], size_t l) { + static int can_do = -1; + + if (can_do == 0) + return 0; + can_do = false; /* We'll set it to true only if the whole process works */ + + /* Let's not bother with this if we don't have euid == 0. Strictly speaking we should check for the + * CAP_SYS_RESOURCE capability which is independent of the euid. In our own code the capability generally is + * present only for euid == 0, hence let's use this as quick bypass check, to avoid calling mmap() if + * PR_SET_MM_ARG_{START,END} fails with EPERM later on anyway. After all geteuid() is dead cheap to call, but + * mmap() is not. */ + if (geteuid() != 0) + return log_debug_errno(SYNTHETIC_ERRNO(EPERM), + "Skipping PR_SET_MM, as we don't have privileges."); + + static size_t mm_size = 0; + static char *mm = NULL; + int r; + + if (mm_size < l+1) { + size_t nn_size; + char *nn; + + nn_size = PAGE_ALIGN(l+1); + nn = mmap(NULL, nn_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (nn == MAP_FAILED) + return log_debug_errno(errno, "mmap() failed: %m"); + + strncpy(nn, name, nn_size); + + /* Now, let's tell the kernel about this new memory */ + if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) { + if (ERRNO_IS_PRIVILEGE(errno)) + return log_debug_errno(errno, "PR_SET_MM_ARG_START failed: %m"); + + /* HACK: prctl() API is kind of dumb on this point. The existing end address may already be + * below the desired start address, in which case the kernel may have kicked this back due + * to a range-check failure (see linux/kernel/sys.c:validate_prctl_map() to see this in + * action). The proper solution would be to have a prctl() API that could set both start+end + * simultaneously, or at least let us query the existing address to anticipate this condition + * and respond accordingly. For now, we can only guess at the cause of this failure and try + * a workaround--which will briefly expand the arg space to something potentially huge before + * resizing it to what we want. */ + log_debug_errno(errno, "PR_SET_MM_ARG_START failed, attempting PR_SET_MM_ARG_END hack: %m"); + + if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0) { + r = log_debug_errno(errno, "PR_SET_MM_ARG_END hack failed, proceeding without: %m"); + (void) munmap(nn, nn_size); + return r; + } + + if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) + return log_debug_errno(errno, "PR_SET_MM_ARG_START still failed, proceeding without: %m"); + } else { + /* And update the end pointer to the new end, too. If this fails, we don't really know what + * to do, it's pretty unlikely that we can rollback, hence we'll just accept the failure, + * and continue. */ + if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0) + log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m"); + } + + if (mm) + (void) munmap(mm, mm_size); + + mm = nn; + mm_size = nn_size; + } else { + strncpy(mm, name, mm_size); + + /* Update the end pointer, continuing regardless of any failure. */ + if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) mm + l + 1, 0, 0) < 0) + log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m"); + } + + can_do = true; + return 0; +} + +int rename_process(const char name[]) { + bool truncated = false; + + /* This is a like a poor man's setproctitle(). It changes the comm field, argv[0], and also the glibc's + * internally used name of the process. For the first one a limit of 16 chars applies; to the second one in + * many cases one of 10 (i.e. length of "/sbin/init") — however if we have CAP_SYS_RESOURCES it is unbounded; + * to the third one 7 (i.e. the length of "systemd". If you pass a longer string it will likely be + * truncated. + * + * Returns 0 if a name was set but truncated, > 0 if it was set but not truncated. */ + + if (isempty(name)) + return -EINVAL; /* let's not confuse users unnecessarily with an empty name */ + + if (!is_main_thread()) + return -EPERM; /* Let's not allow setting the process name from other threads than the main one, as we + * cache things without locking, and we make assumptions that PR_SET_NAME sets the + * process name that isn't correct on any other threads */ + + size_t l = strlen(name); + + /* First step, change the comm field. The main thread's comm is identical to the process comm. This means we + * can use PR_SET_NAME, which sets the thread name for the calling thread. */ + if (prctl(PR_SET_NAME, name) < 0) + log_debug_errno(errno, "PR_SET_NAME failed: %m"); + if (l >= TASK_COMM_LEN) /* Linux userspace process names can be 15 chars at max */ + truncated = true; + + /* Second step, change glibc's ID of the process name. */ + if (program_invocation_name) { + size_t k; + + k = strlen(program_invocation_name); + strncpy(program_invocation_name, name, k); + if (l > k) + truncated = true; + } + + /* Third step, completely replace the argv[] array the kernel maintains for us. This requires privileges, but + * has the advantage that the argv[] array is exactly what we want it to be, and not filled up with zeros at + * the end. This is the best option for changing /proc/self/cmdline. */ + (void) update_argv(name, l); + + /* Fourth step: in all cases we'll also update the original argv[], so that our own code gets it right too if + * it still looks here */ + if (saved_argc > 0) { + if (saved_argv[0]) { + size_t k; + + k = strlen(saved_argv[0]); + strncpy(saved_argv[0], name, k); + if (l > k) + truncated = true; + } + + for (int i = 1; i < saved_argc; i++) { + if (!saved_argv[i]) + break; + + memzero(saved_argv[i], strlen(saved_argv[i])); + } + } + + return !truncated; +} + +int is_kernel_thread(pid_t pid) { + _cleanup_free_ char *line = NULL; + unsigned long long flags; + size_t l, i; + const char *p; + char *q; + int r; + + if (IN_SET(pid, 0, 1) || pid == getpid_cached()) /* pid 1, and we ourselves certainly aren't a kernel thread */ + return 0; + if (!pid_is_valid(pid)) + return -EINVAL; + + p = procfs_file_alloca(pid, "stat"); + r = read_one_line_file(p, &line); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; + + /* Skip past the comm field */ + q = strrchr(line, ')'); + if (!q) + return -EINVAL; + q++; + + /* Skip 6 fields to reach the flags field */ + for (i = 0; i < 6; i++) { + l = strspn(q, WHITESPACE); + if (l < 1) + return -EINVAL; + q += l; + + l = strcspn(q, WHITESPACE); + if (l < 1) + return -EINVAL; + q += l; + } + + /* Skip preceding whitespace */ + l = strspn(q, WHITESPACE); + if (l < 1) + return -EINVAL; + q += l; + + /* Truncate the rest */ + l = strcspn(q, WHITESPACE); + if (l < 1) + return -EINVAL; + q[l] = 0; + + r = safe_atollu(q, &flags); + if (r < 0) + return r; + + return !!(flags & PF_KTHREAD); +} + +int get_process_capeff(pid_t pid, char **capeff) { + const char *p; + int r; + + assert(capeff); + assert(pid >= 0); + + p = procfs_file_alloca(pid, "status"); + + r = get_proc_field(p, "CapEff", WHITESPACE, capeff); + if (r == -ENOENT) + return -ESRCH; + + return r; +} + +static int get_process_link_contents(const char *proc_file, char **name) { + int r; + + assert(proc_file); + assert(name); + + r = readlink_malloc(proc_file, name); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; + + return 0; +} + +int get_process_exe(pid_t pid, char **name) { + const char *p; + char *d; + int r; + + assert(pid >= 0); + + p = procfs_file_alloca(pid, "exe"); + r = get_process_link_contents(p, name); + if (r < 0) + return r; + + d = endswith(*name, " (deleted)"); + if (d) + *d = '\0'; + + return 0; +} + +static int get_process_id(pid_t pid, const char *field, uid_t *uid) { + _cleanup_fclose_ FILE *f = NULL; + const char *p; + int r; + + assert(field); + assert(uid); + + if (pid < 0) + return -EINVAL; + + p = procfs_file_alloca(pid, "status"); + r = fopen_unlocked(p, "re", &f); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; + + for (;;) { + _cleanup_free_ char *line = NULL; + char *l; + + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) + break; + + l = strstrip(line); + + if (startswith(l, field)) { + l += strlen(field); + l += strspn(l, WHITESPACE); + + l[strcspn(l, WHITESPACE)] = 0; + + return parse_uid(l, uid); + } + } + + return -EIO; +} + +int get_process_uid(pid_t pid, uid_t *uid) { + + if (pid == 0 || pid == getpid_cached()) { + *uid = getuid(); + return 0; + } + + return get_process_id(pid, "Uid:", uid); +} + +int get_process_gid(pid_t pid, gid_t *gid) { + + if (pid == 0 || pid == getpid_cached()) { + *gid = getgid(); + return 0; + } + + assert_cc(sizeof(uid_t) == sizeof(gid_t)); + return get_process_id(pid, "Gid:", gid); +} + +int get_process_cwd(pid_t pid, char **cwd) { + const char *p; + + assert(pid >= 0); + + if (pid == 0 || pid == getpid_cached()) + return safe_getcwd(cwd); + + p = procfs_file_alloca(pid, "cwd"); + + return get_process_link_contents(p, cwd); +} + +int get_process_root(pid_t pid, char **root) { + const char *p; + + assert(pid >= 0); + + p = procfs_file_alloca(pid, "root"); + + return get_process_link_contents(p, root); +} + +#define ENVIRONMENT_BLOCK_MAX (5U*1024U*1024U) + +int get_process_environ(pid_t pid, char **env) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *outcome = NULL; + size_t allocated = 0, sz = 0; + const char *p; + int r; + + assert(pid >= 0); + assert(env); + + p = procfs_file_alloca(pid, "environ"); + + r = fopen_unlocked(p, "re", &f); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; + + for (;;) { + char c; + + if (sz >= ENVIRONMENT_BLOCK_MAX) + return -ENOBUFS; + + if (!GREEDY_REALLOC(outcome, allocated, sz + 5)) + return -ENOMEM; + + r = safe_fgetc(f, &c); + if (r < 0) + return r; + if (r == 0) + break; + + if (c == '\0') + outcome[sz++] = '\n'; + else + sz += cescape_char(c, outcome + sz); + } + + outcome[sz] = '\0'; + *env = TAKE_PTR(outcome); + + return 0; +} + +int get_process_ppid(pid_t pid, pid_t *_ppid) { + int r; + _cleanup_free_ char *line = NULL; + long unsigned ppid; + const char *p; + + assert(pid >= 0); + assert(_ppid); + + if (pid == 0 || pid == getpid_cached()) { + *_ppid = getppid(); + return 0; + } + + p = procfs_file_alloca(pid, "stat"); + r = read_one_line_file(p, &line); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; + + /* Let's skip the pid and comm fields. The latter is enclosed + * in () but does not escape any () in its value, so let's + * skip over it manually */ + + p = strrchr(line, ')'); + if (!p) + return -EIO; + + p++; + + if (sscanf(p, " " + "%*c " /* state */ + "%lu ", /* ppid */ + &ppid) != 1) + return -EIO; + + if ((long unsigned) (pid_t) ppid != ppid) + return -ERANGE; + + *_ppid = (pid_t) ppid; + + return 0; +} + +int get_process_umask(pid_t pid, mode_t *umask) { + _cleanup_free_ char *m = NULL; + const char *p; + int r; + + assert(umask); + assert(pid >= 0); + + p = procfs_file_alloca(pid, "status"); + + r = get_proc_field(p, "Umask", WHITESPACE, &m); + if (r == -ENOENT) + return -ESRCH; + + return parse_mode(m, umask); +} + +int wait_for_terminate(pid_t pid, siginfo_t *status) { + siginfo_t dummy; + + assert(pid >= 1); + + if (!status) + status = &dummy; + + for (;;) { + zero(*status); + + if (waitid(P_PID, pid, status, WEXITED) < 0) { + + if (errno == EINTR) + continue; + + return negative_errno(); + } + + return 0; + } +} + +/* + * Return values: + * < 0 : wait_for_terminate() failed to get the state of the + * process, the process was terminated by a signal, or + * failed for an unknown reason. + * >=0 : The process terminated normally, and its exit code is + * returned. + * + * That is, success is indicated by a return value of zero, and an + * error is indicated by a non-zero value. + * + * A warning is emitted if the process terminates abnormally, + * and also if it returns non-zero unless check_exit_code is true. + */ +int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) { + _cleanup_free_ char *buffer = NULL; + siginfo_t status; + int r, prio; + + assert(pid > 1); + + if (!name) { + r = get_process_comm(pid, &buffer); + if (r < 0) + log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pid); + else + name = buffer; + } + + prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG; + + r = wait_for_terminate(pid, &status); + if (r < 0) + return log_full_errno(prio, r, "Failed to wait for %s: %m", strna(name)); + + if (status.si_code == CLD_EXITED) { + if (status.si_status != EXIT_SUCCESS) + log_full(flags & WAIT_LOG_NON_ZERO_EXIT_STATUS ? LOG_ERR : LOG_DEBUG, + "%s failed with exit status %i.", strna(name), status.si_status); + else + log_debug("%s succeeded.", name); + + return status.si_status; + + } else if (IN_SET(status.si_code, CLD_KILLED, CLD_DUMPED)) { + + log_full(prio, "%s terminated by signal %s.", strna(name), signal_to_string(status.si_status)); + return -EPROTO; + } + + log_full(prio, "%s failed due to unknown reason.", strna(name)); + return -EPROTO; +} + +/* + * Return values: + * + * < 0 : wait_for_terminate_with_timeout() failed to get the state of the process, the process timed out, the process + * was terminated by a signal, or failed for an unknown reason. + * + * >=0 : The process terminated normally with no failures. + * + * Success is indicated by a return value of zero, a timeout is indicated by ETIMEDOUT, and all other child failure + * states are indicated by error is indicated by a non-zero value. + * + * This call assumes SIGCHLD has been blocked already, in particular before the child to wait for has been forked off + * to remain entirely race-free. + */ +int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout) { + sigset_t mask; + int r; + usec_t until; + + assert_se(sigemptyset(&mask) == 0); + assert_se(sigaddset(&mask, SIGCHLD) == 0); + + /* Drop into a sigtimewait-based timeout. Waiting for the + * pid to exit. */ + until = now(CLOCK_MONOTONIC) + timeout; + for (;;) { + usec_t n; + siginfo_t status = {}; + struct timespec ts; + + n = now(CLOCK_MONOTONIC); + if (n >= until) + break; + + r = sigtimedwait(&mask, NULL, timespec_store(&ts, until - n)) < 0 ? -errno : 0; + /* Assuming we woke due to the child exiting. */ + if (waitid(P_PID, pid, &status, WEXITED|WNOHANG) == 0) { + if (status.si_pid == pid) { + /* This is the correct child.*/ + if (status.si_code == CLD_EXITED) + return (status.si_status == 0) ? 0 : -EPROTO; + else + return -EPROTO; + } + } + /* Not the child, check for errors and proceed appropriately */ + if (r < 0) { + switch (r) { + case -EAGAIN: + /* Timed out, child is likely hung. */ + return -ETIMEDOUT; + case -EINTR: + /* Received a different signal and should retry */ + continue; + default: + /* Return any unexpected errors */ + return r; + } + } + } + + return -EPROTO; +} + +void sigkill_wait(pid_t pid) { + assert(pid > 1); + + if (kill(pid, SIGKILL) >= 0) + (void) wait_for_terminate(pid, NULL); +} + +void sigkill_waitp(pid_t *pid) { + PROTECT_ERRNO; + + if (!pid) + return; + if (*pid <= 1) + return; + + sigkill_wait(*pid); +} + +void sigterm_wait(pid_t pid) { + assert(pid > 1); + + if (kill_and_sigcont(pid, SIGTERM) >= 0) + (void) wait_for_terminate(pid, NULL); +} + +int kill_and_sigcont(pid_t pid, int sig) { + int r; + + r = kill(pid, sig) < 0 ? -errno : 0; + + /* If this worked, also send SIGCONT, unless we already just sent a SIGCONT, or SIGKILL was sent which isn't + * affected by a process being suspended anyway. */ + if (r >= 0 && !IN_SET(sig, SIGCONT, SIGKILL)) + (void) kill(pid, SIGCONT); + + return r; +} + +int getenv_for_pid(pid_t pid, const char *field, char **ret) { + _cleanup_fclose_ FILE *f = NULL; + char *value = NULL; + const char *path; + size_t l, sum = 0; + int r; + + assert(pid >= 0); + assert(field); + assert(ret); + + if (pid == 0 || pid == getpid_cached()) { + const char *e; + + e = getenv(field); + if (!e) { + *ret = NULL; + return 0; + } + + value = strdup(e); + if (!value) + return -ENOMEM; + + *ret = value; + return 1; + } + + if (!pid_is_valid(pid)) + return -EINVAL; + + path = procfs_file_alloca(pid, "environ"); + + r = fopen_unlocked(path, "re", &f); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; + + l = strlen(field); + for (;;) { + _cleanup_free_ char *line = NULL; + + if (sum > ENVIRONMENT_BLOCK_MAX) /* Give up searching eventually */ + return -ENOBUFS; + + r = read_nul_string(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) /* EOF */ + break; + + sum += r; + + if (strneq(line, field, l) && line[l] == '=') { + value = strdup(line + l + 1); + if (!value) + return -ENOMEM; + + *ret = value; + return 1; + } + } + + *ret = NULL; + return 0; +} + +int pid_is_my_child(pid_t pid) { + pid_t ppid; + int r; + + if (pid <= 1) + return false; + + r = get_process_ppid(pid, &ppid); + if (r < 0) + return r; + + return ppid == getpid_cached(); +} + +bool pid_is_unwaited(pid_t pid) { + /* Checks whether a PID is still valid at all, including a zombie */ + + if (pid < 0) + return false; + + if (pid <= 1) /* If we or PID 1 would be dead and have been waited for, this code would not be running */ + return true; + + if (pid == getpid_cached()) + return true; + + if (kill(pid, 0) >= 0) + return true; + + return errno != ESRCH; +} + +bool pid_is_alive(pid_t pid) { + int r; + + /* Checks whether a PID is still valid and not a zombie */ + + if (pid < 0) + return false; + + if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */ + return true; + + if (pid == getpid_cached()) + return true; + + r = get_process_state(pid); + if (IN_SET(r, -ESRCH, 'Z')) + return false; + + return true; +} + +int pid_from_same_root_fs(pid_t pid) { + const char *root; + + if (pid < 0) + return false; + + if (pid == 0 || pid == getpid_cached()) + return true; + + root = procfs_file_alloca(pid, "root"); + + return files_same(root, "/proc/1/root", 0); +} +#endif /* NM_IGNORED */ + +bool is_main_thread(void) { + static thread_local int cached = 0; + + if (_unlikely_(cached == 0)) + cached = getpid_cached() == gettid() ? 1 : -1; + + return cached > 0; +} + +#if 0 /* NM_IGNORED */ +_noreturn_ void freeze(void) { + + log_close(); + + /* Make sure nobody waits for us on a socket anymore */ + (void) close_all_fds(NULL, 0); + + sync(); + + /* Let's not freeze right away, but keep reaping zombies. */ + for (;;) { + int r; + siginfo_t si = {}; + + r = waitid(P_ALL, 0, &si, WEXITED); + if (r < 0 && errno != EINTR) + break; + } + + /* waitid() failed with an unexpected error, things are really borked. Freeze now! */ + for (;;) + pause(); +} + +bool oom_score_adjust_is_valid(int oa) { + return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX; +} + +unsigned long personality_from_string(const char *p) { + int architecture; + + if (!p) + return PERSONALITY_INVALID; + + /* Parse a personality specifier. We use our own identifiers that indicate specific ABIs, rather than just + * hints regarding the register size, since we want to keep things open for multiple locally supported ABIs for + * the same register size. */ + + architecture = architecture_from_string(p); + if (architecture < 0) + return PERSONALITY_INVALID; + + if (architecture == native_architecture()) + return PER_LINUX; +#ifdef SECONDARY_ARCHITECTURE + if (architecture == SECONDARY_ARCHITECTURE) + return PER_LINUX32; +#endif + + return PERSONALITY_INVALID; +} + +const char* personality_to_string(unsigned long p) { + int architecture = _ARCHITECTURE_INVALID; + + if (p == PER_LINUX) + architecture = native_architecture(); +#ifdef SECONDARY_ARCHITECTURE + else if (p == PER_LINUX32) + architecture = SECONDARY_ARCHITECTURE; +#endif + + if (architecture < 0) + return NULL; + + return architecture_to_string(architecture); +} + +int safe_personality(unsigned long p) { + int ret; + + /* So here's the deal, personality() is weirdly defined by glibc. In some cases it returns a failure via errno, + * and in others as negative return value containing an errno-like value. Let's work around this: this is a + * wrapper that uses errno if it is set, and uses the return value otherwise. And then it sets both errno and + * the return value indicating the same issue, so that we are definitely on the safe side. + * + * See https://github.com/systemd/systemd/issues/6737 */ + + errno = 0; + ret = personality(p); + if (ret < 0) { + if (errno != 0) + return -errno; + + errno = -ret; + } + + return ret; +} + +int opinionated_personality(unsigned long *ret) { + int current; + + /* Returns the current personality, or PERSONALITY_INVALID if we can't determine it. This function is a bit + * opinionated though, and ignores all the finer-grained bits and exotic personalities, only distinguishing the + * two most relevant personalities: PER_LINUX and PER_LINUX32. */ + + current = safe_personality(PERSONALITY_INVALID); + if (current < 0) + return current; + + if (((unsigned long) current & 0xffff) == PER_LINUX32) + *ret = PER_LINUX32; + else + *ret = PER_LINUX; + + return 0; +} + +void valgrind_summary_hack(void) { +#if HAVE_VALGRIND_VALGRIND_H + if (getpid_cached() == 1 && RUNNING_ON_VALGRIND) { + pid_t pid; + pid = raw_clone(SIGCHLD); + if (pid < 0) + log_emergency_errno(errno, "Failed to fork off valgrind helper: %m"); + else if (pid == 0) + exit(EXIT_SUCCESS); + else { + log_info("Spawned valgrind helper as PID "PID_FMT".", pid); + (void) wait_for_terminate(pid, NULL); + } + } +#endif +} + +int pid_compare_func(const pid_t *a, const pid_t *b) { + /* Suitable for usage in qsort() */ + return CMP(*a, *b); +} + +int ioprio_parse_priority(const char *s, int *ret) { + int i, r; + + assert(s); + assert(ret); + + r = safe_atoi(s, &i); + if (r < 0) + return r; + + if (!ioprio_priority_is_valid(i)) + return -EINVAL; + + *ret = i; + return 0; +} +#endif /* NM_IGNORED */ + +/* The cached PID, possible values: + * + * == UNSET [0] → cache not initialized yet + * == BUSY [-1] → some thread is initializing it at the moment + * any other → the cached PID + */ + +#define CACHED_PID_UNSET ((pid_t) 0) +#define CACHED_PID_BUSY ((pid_t) -1) + +static pid_t cached_pid = CACHED_PID_UNSET; + +void reset_cached_pid(void) { + /* Invoked in the child after a fork(), i.e. at the first moment the PID changed */ + cached_pid = CACHED_PID_UNSET; +} + +/* We use glibc __register_atfork() + __dso_handle directly here, as they are not included in the glibc + * headers. __register_atfork() is mostly equivalent to pthread_atfork(), but doesn't require us to link against + * libpthread, as it is part of glibc anyway. */ +extern int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void *dso_handle); +extern void* __dso_handle _weak_; + +pid_t getpid_cached(void) { + static bool installed = false; + pid_t current_value; + + /* getpid_cached() is much like getpid(), but caches the value in local memory, to avoid having to invoke a + * system call each time. This restores glibc behaviour from before 2.24, when getpid() was unconditionally + * cached. Starting with 2.24 getpid() started to become prohibitively expensive when used for detecting when + * objects were used across fork()s. With this caching the old behaviour is somewhat restored. + * + * https://bugzilla.redhat.com/show_bug.cgi?id=1443976 + * https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c579f48edba88380635ab98cb612030e3ed8691e + */ + + current_value = __sync_val_compare_and_swap(&cached_pid, CACHED_PID_UNSET, CACHED_PID_BUSY); + + switch (current_value) { + + case CACHED_PID_UNSET: { /* Not initialized yet, then do so now */ + pid_t new_pid; + + new_pid = raw_getpid(); + + if (!installed) { + /* __register_atfork() either returns 0 or -ENOMEM, in its glibc implementation. Since it's + * only half-documented (glibc doesn't document it but LSB does — though only superficially) + * we'll check for errors only in the most generic fashion possible. */ + + if (__register_atfork(NULL, NULL, reset_cached_pid, __dso_handle) != 0) { + /* OOM? Let's try again later */ + cached_pid = CACHED_PID_UNSET; + return new_pid; + } + + installed = true; + } + + cached_pid = new_pid; + return new_pid; + } + + case CACHED_PID_BUSY: /* Somebody else is currently initializing */ + return raw_getpid(); + + default: /* Properly initialized */ + return current_value; + } +} + +#if 0 /* NM_IGNORED */ +int must_be_root(void) { + + if (geteuid() == 0) + return 0; + + return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root."); +} + +static void restore_sigsetp(sigset_t **ssp) { + if (*ssp) + (void) sigprocmask(SIG_SETMASK, *ssp, NULL); +} + +int safe_fork_full( + const char *name, + const int except_fds[], + size_t n_except_fds, + ForkFlags flags, + pid_t *ret_pid) { + + pid_t original_pid, pid; + sigset_t saved_ss, ss; + _cleanup_(restore_sigsetp) sigset_t *saved_ssp = NULL; + bool block_signals = false, block_all = false; + int prio, r; + + /* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always + * returns the child's PID in *ret_pid. Returns == 0 in the child, and > 0 in the parent. */ + + prio = flags & FORK_LOG ? LOG_ERR : LOG_DEBUG; + + original_pid = getpid_cached(); + + if (flags & (FORK_RESET_SIGNALS|FORK_DEATHSIG)) { + /* We temporarily block all signals, so that the new child has them blocked initially. This way, we can + * be sure that SIGTERMs are not lost we might send to the child. */ + + assert_se(sigfillset(&ss) >= 0); + block_signals = block_all = true; + + } else if (flags & FORK_WAIT) { + /* Let's block SIGCHLD at least, so that we can safely watch for the child process */ + + assert_se(sigemptyset(&ss) >= 0); + assert_se(sigaddset(&ss, SIGCHLD) >= 0); + block_signals = true; + } + + if (block_signals) { + if (sigprocmask(SIG_SETMASK, &ss, &saved_ss) < 0) + return log_full_errno(prio, errno, "Failed to set signal mask: %m"); + saved_ssp = &saved_ss; + } + + if (flags & FORK_NEW_MOUNTNS) + pid = raw_clone(SIGCHLD|CLONE_NEWNS); + else + pid = fork(); + if (pid < 0) + return log_full_errno(prio, errno, "Failed to fork: %m"); + if (pid > 0) { + /* We are in the parent process */ + + log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid); + + if (flags & FORK_WAIT) { + if (block_all) { + /* undo everything except SIGCHLD */ + ss = saved_ss; + assert_se(sigaddset(&ss, SIGCHLD) >= 0); + (void) sigprocmask(SIG_SETMASK, &ss, NULL); + } + + r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0)); + if (r < 0) + return r; + if (r != EXIT_SUCCESS) /* exit status > 0 should be treated as failure, too */ + return -EPROTO; + } + + if (ret_pid) + *ret_pid = pid; + + return 1; + } + + /* We are in the child process */ + + /* Restore signal mask manually */ + saved_ssp = NULL; + + if (flags & FORK_REOPEN_LOG) { + /* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */ + log_close(); + log_set_open_when_needed(true); + } + + if (name) { + r = rename_process(name); + if (r < 0) + log_full_errno(flags & FORK_LOG ? LOG_WARNING : LOG_DEBUG, + r, "Failed to rename process, ignoring: %m"); + } + + if (flags & (FORK_DEATHSIG|FORK_DEATHSIG_SIGINT)) + if (prctl(PR_SET_PDEATHSIG, (flags & FORK_DEATHSIG_SIGINT) ? SIGINT : SIGTERM) < 0) { + log_full_errno(prio, errno, "Failed to set death signal: %m"); + _exit(EXIT_FAILURE); + } + + if (flags & FORK_RESET_SIGNALS) { + r = reset_all_signal_handlers(); + if (r < 0) { + log_full_errno(prio, r, "Failed to reset signal handlers: %m"); + _exit(EXIT_FAILURE); + } + + /* This implicitly undoes the signal mask stuff we did before the fork()ing above */ + r = reset_signal_mask(); + if (r < 0) { + log_full_errno(prio, r, "Failed to reset signal mask: %m"); + _exit(EXIT_FAILURE); + } + } else if (block_signals) { /* undo what we did above */ + if (sigprocmask(SIG_SETMASK, &saved_ss, NULL) < 0) { + log_full_errno(prio, errno, "Failed to restore signal mask: %m"); + _exit(EXIT_FAILURE); + } + } + + if (flags & FORK_DEATHSIG) { + pid_t ppid; + /* Let's see if the parent PID is still the one we started from? If not, then the parent + * already died by the time we set PR_SET_PDEATHSIG, hence let's emulate the effect */ + + ppid = getppid(); + if (ppid == 0) + /* Parent is in a different PID namespace. */; + else if (ppid != original_pid) { + log_debug("Parent died early, raising SIGTERM."); + (void) raise(SIGTERM); + _exit(EXIT_FAILURE); + } + } + + if (FLAGS_SET(flags, FORK_NEW_MOUNTNS | FORK_MOUNTNS_SLAVE)) { + + /* Optionally, make sure we never propagate mounts to the host. */ + + if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) { + log_full_errno(prio, errno, "Failed to remount root directory as MS_SLAVE: %m"); + _exit(EXIT_FAILURE); + } + } + + if (flags & FORK_CLOSE_ALL_FDS) { + /* Close the logs here in case it got reopened above, as close_all_fds() would close them for us */ + log_close(); + + r = close_all_fds(except_fds, n_except_fds); + if (r < 0) { + log_full_errno(prio, r, "Failed to close all file descriptors: %m"); + _exit(EXIT_FAILURE); + } + } + + /* When we were asked to reopen the logs, do so again now */ + if (flags & FORK_REOPEN_LOG) { + log_open(); + log_set_open_when_needed(false); + } + + if (flags & FORK_NULL_STDIO) { + r = make_null_stdio(); + if (r < 0) { + log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m"); + _exit(EXIT_FAILURE); + } + + } else if (flags & FORK_STDOUT_TO_STDERR) { + if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) { + log_full_errno(prio, errno, "Failed to connect stdout to stderr: %m"); + _exit(EXIT_FAILURE); + } + } + + if (flags & FORK_RLIMIT_NOFILE_SAFE) { + r = rlimit_nofile_safe(); + if (r < 0) { + log_full_errno(prio, r, "Failed to lower RLIMIT_NOFILE's soft limit to 1K: %m"); + _exit(EXIT_FAILURE); + } + } + + if (ret_pid) + *ret_pid = getpid_cached(); + + return 0; +} + +int namespace_fork( + const char *outer_name, + const char *inner_name, + const int except_fds[], + size_t n_except_fds, + ForkFlags flags, + int pidns_fd, + int mntns_fd, + int netns_fd, + int userns_fd, + int root_fd, + pid_t *ret_pid) { + + int r; + + /* This is much like safe_fork(), but forks twice, and joins the specified namespaces in the middle + * process. This ensures that we are fully a member of the destination namespace, with pidns an all, so that + * /proc/self/fd works correctly. */ + + r = safe_fork_full(outer_name, except_fds, n_except_fds, (flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid); + if (r < 0) + return r; + if (r == 0) { + pid_t pid; + + /* Child */ + + r = namespace_enter(pidns_fd, mntns_fd, netns_fd, userns_fd, root_fd); + if (r < 0) { + log_full_errno(FLAGS_SET(flags, FORK_LOG) ? LOG_ERR : LOG_DEBUG, r, "Failed to join namespace: %m"); + _exit(EXIT_FAILURE); + } + + /* We mask a few flags here that either make no sense for the grandchild, or that we don't have to do again */ + r = safe_fork_full(inner_name, except_fds, n_except_fds, flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_NULL_STDIO), &pid); + if (r < 0) + _exit(EXIT_FAILURE); + if (r == 0) { + /* Child */ + if (ret_pid) + *ret_pid = pid; + return 0; + } + + r = wait_for_terminate_and_check(inner_name, pid, FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0); + if (r < 0) + _exit(EXIT_FAILURE); + + _exit(r); + } + + return 1; +} + +int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret_pid, const char *path, ...) { + bool stdout_is_tty, stderr_is_tty; + size_t n, i; + va_list ap; + char **l; + int r; + + assert(path); + + /* Spawns a temporary TTY agent, making sure it goes away when we go away */ + + r = safe_fork_full(name, except, n_except, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS, ret_pid); + if (r < 0) + return r; + if (r > 0) + return 0; + + /* In the child: */ + + stdout_is_tty = isatty(STDOUT_FILENO); + stderr_is_tty = isatty(STDERR_FILENO); + + if (!stdout_is_tty || !stderr_is_tty) { + int fd; + + /* Detach from stdout/stderr. and reopen + * /dev/tty for them. This is important to + * ensure that when systemctl is started via + * popen() or a similar call that expects to + * read EOF we actually do generate EOF and + * not delay this indefinitely by because we + * keep an unused copy of stdin around. */ + fd = open("/dev/tty", O_WRONLY); + if (fd < 0) { + log_error_errno(errno, "Failed to open /dev/tty: %m"); + _exit(EXIT_FAILURE); + } + + if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) { + log_error_errno(errno, "Failed to dup2 /dev/tty: %m"); + _exit(EXIT_FAILURE); + } + + if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) { + log_error_errno(errno, "Failed to dup2 /dev/tty: %m"); + _exit(EXIT_FAILURE); + } + + safe_close_above_stdio(fd); + } + + (void) rlimit_nofile_safe(); + + /* Count arguments */ + va_start(ap, path); + for (n = 0; va_arg(ap, char*); n++) + ; + va_end(ap); + + /* Allocate strv */ + l = newa(char*, n + 1); + + /* Fill in arguments */ + va_start(ap, path); + for (i = 0; i <= n; i++) + l[i] = va_arg(ap, char*); + va_end(ap); + + execv(path, l); + _exit(EXIT_FAILURE); +} + +int set_oom_score_adjust(int value) { + char t[DECIMAL_STR_MAX(int)]; + + sprintf(t, "%i", value); + + return write_string_file("/proc/self/oom_score_adj", t, + WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER); +} + +int pidfd_get_pid(int fd, pid_t *ret) { + char path[STRLEN("/proc/self/fdinfo/") + DECIMAL_STR_MAX(int)]; + _cleanup_free_ char *fdinfo = NULL; + char *p; + int r; + + if (fd < 0) + return -EBADF; + + xsprintf(path, "/proc/self/fdinfo/%i", fd); + + r = read_full_file(path, &fdinfo, NULL); + if (r == -ENOENT) /* if fdinfo doesn't exist we assume the process does not exist */ + return -ESRCH; + if (r < 0) + return r; + + p = startswith(fdinfo, "Pid:"); + if (!p) { + p = strstr(fdinfo, "\nPid:"); + if (!p) + return -ENOTTY; /* not a pidfd? */ + + p += 5; + } + + p += strspn(p, WHITESPACE); + p[strcspn(p, WHITESPACE)] = 0; + + return parse_pid(p, ret); +} + +static int rlimit_to_nice(rlim_t limit) { + if (limit <= 1) + return PRIO_MAX-1; /* i.e. 19 */ + + if (limit >= -PRIO_MIN + PRIO_MAX) + return PRIO_MIN; /* i.e. -20 */ + + return PRIO_MAX - (int) limit; +} + +int setpriority_closest(int priority) { + int current, limit, saved_errno; + struct rlimit highest; + + /* Try to set requested nice level */ + if (setpriority(PRIO_PROCESS, 0, priority) >= 0) + return 1; + + /* Permission failed */ + saved_errno = -errno; + if (!ERRNO_IS_PRIVILEGE(saved_errno)) + return saved_errno; + + errno = 0; + current = getpriority(PRIO_PROCESS, 0); + if (errno != 0) + return -errno; + + if (priority == current) + return 1; + + /* Hmm, we'd expect that raising the nice level from our status quo would always work. If it doesn't, + * then the whole setpriority() system call is blocked to us, hence let's propagate the error + * right-away */ + if (priority > current) + return saved_errno; + + if (getrlimit(RLIMIT_NICE, &highest) < 0) + return -errno; + + limit = rlimit_to_nice(highest.rlim_cur); + + /* We are already less nice than limit allows us */ + if (current < limit) { + log_debug("Cannot raise nice level, permissions and the resource limit do not allow it."); + return 0; + } + + /* Push to the allowed limit */ + if (setpriority(PRIO_PROCESS, 0, limit) < 0) + return -errno; + + log_debug("Cannot set requested nice level (%i), used next best (%i).", priority, limit); + return 0; +} + +static const char *const ioprio_class_table[] = { + [IOPRIO_CLASS_NONE] = "none", + [IOPRIO_CLASS_RT] = "realtime", + [IOPRIO_CLASS_BE] = "best-effort", + [IOPRIO_CLASS_IDLE] = "idle", +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, IOPRIO_N_CLASSES); + +static const char *const sigchld_code_table[] = { + [CLD_EXITED] = "exited", + [CLD_KILLED] = "killed", + [CLD_DUMPED] = "dumped", + [CLD_TRAPPED] = "trapped", + [CLD_STOPPED] = "stopped", + [CLD_CONTINUED] = "continued", +}; + +DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int); + +static const char* const sched_policy_table[] = { + [SCHED_OTHER] = "other", + [SCHED_BATCH] = "batch", + [SCHED_IDLE] = "idle", + [SCHED_FIFO] = "fifo", + [SCHED_RR] = "rr", +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX); +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/process-util.h b/src/libnm-systemd-shared/src/basic/process-util.h new file mode 100644 index 0000000..aab2c7a --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/process-util.h @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "format-util.h" +#include "ioprio.h" +#include "macro.h" +#include "time-util.h" + +#define procfs_file_alloca(pid, field) \ + ({ \ + pid_t _pid_ = (pid); \ + const char *_field_ = (field); \ + char *_r_; \ + if (_pid_ == 0) { \ + _r_ = newa(char, STRLEN("/proc/self/") + strlen(_field_) + 1); \ + strcpy(stpcpy(_r_, "/proc/self/"), _field_); \ + } else { \ + _r_ = newa(char, STRLEN("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + strlen(_field_) + 1); \ + sprintf(_r_, "/proc/" PID_FMT "/%s", _pid_, _field_); \ + } \ + (const char*) _r_; \ + }) + +typedef enum ProcessCmdlineFlags { + PROCESS_CMDLINE_COMM_FALLBACK = 1 << 0, + PROCESS_CMDLINE_USE_LOCALE = 1 << 1, +} ProcessCmdlineFlags; + +int get_process_comm(pid_t pid, char **name); +int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **line); +int get_process_exe(pid_t pid, char **name); +int get_process_uid(pid_t pid, uid_t *uid); +int get_process_gid(pid_t pid, gid_t *gid); +int get_process_capeff(pid_t pid, char **capeff); +int get_process_cwd(pid_t pid, char **cwd); +int get_process_root(pid_t pid, char **root); +int get_process_environ(pid_t pid, char **environ); +int get_process_ppid(pid_t pid, pid_t *ppid); +int get_process_umask(pid_t pid, mode_t *umask); + +int wait_for_terminate(pid_t pid, siginfo_t *status); + +typedef enum WaitFlags { + WAIT_LOG_ABNORMAL = 1 << 0, + WAIT_LOG_NON_ZERO_EXIT_STATUS = 1 << 1, + + /* A shortcut for requesting the most complete logging */ + WAIT_LOG = WAIT_LOG_ABNORMAL|WAIT_LOG_NON_ZERO_EXIT_STATUS, +} WaitFlags; + +int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags); +int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout); + +void sigkill_wait(pid_t pid); +void sigkill_waitp(pid_t *pid); +void sigterm_wait(pid_t pid); + +int kill_and_sigcont(pid_t pid, int sig); + +int rename_process(const char name[]); +int is_kernel_thread(pid_t pid); + +int getenv_for_pid(pid_t pid, const char *field, char **_value); + +bool pid_is_alive(pid_t pid); +bool pid_is_unwaited(pid_t pid); +int pid_is_my_child(pid_t pid); +int pid_from_same_root_fs(pid_t pid); + +bool is_main_thread(void); + +_noreturn_ void freeze(void); + +bool oom_score_adjust_is_valid(int oa); + +#ifndef PERSONALITY_INVALID +/* personality(7) documents that 0xffffffffUL is used for querying the + * current personality, hence let's use that here as error + * indicator. */ +#define PERSONALITY_INVALID 0xffffffffLU +#endif + +unsigned long personality_from_string(const char *p); +const char *personality_to_string(unsigned long); + +int safe_personality(unsigned long p); +int opinionated_personality(unsigned long *ret); + +int ioprio_class_to_string_alloc(int i, char **s); +int ioprio_class_from_string(const char *s); + +const char *sigchld_code_to_string(int i) _const_; +int sigchld_code_from_string(const char *s) _pure_; + +int sched_policy_to_string_alloc(int i, char **s); +int sched_policy_from_string(const char *s); + +static inline pid_t PTR_TO_PID(const void *p) { + return (pid_t) ((uintptr_t) p); +} + +static inline void* PID_TO_PTR(pid_t pid) { + return (void*) ((uintptr_t) pid); +} + +void valgrind_summary_hack(void); + +int pid_compare_func(const pid_t *a, const pid_t *b); + +#if 0 /* NM_IGNORED */ +static inline bool nice_is_valid(int n) { + return n >= PRIO_MIN && n < PRIO_MAX; +} + +static inline bool sched_policy_is_valid(int i) { + return IN_SET(i, SCHED_OTHER, SCHED_BATCH, SCHED_IDLE, SCHED_FIFO, SCHED_RR); +} + +static inline bool sched_priority_is_valid(int i) { + return i >= 0 && i <= sched_get_priority_max(SCHED_RR); +} + +static inline bool ioprio_class_is_valid(int i) { + return IN_SET(i, IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE); +} + +static inline bool ioprio_priority_is_valid(int i) { + return i >= 0 && i < IOPRIO_BE_NR; +} + +static inline bool pid_is_valid(pid_t p) { + return p > 0; +} +#endif /* NM_IGNORED */ + +int ioprio_parse_priority(const char *s, int *ret); + +pid_t getpid_cached(void); +void reset_cached_pid(void); + +int must_be_root(void); + +typedef enum ForkFlags { + FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */ + FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */ + FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child to SIGTERM */ + FORK_DEATHSIG_SIGINT = 1 << 3, /* Set PR_DEATHSIG in the child to SIGINT */ + FORK_NULL_STDIO = 1 << 4, /* Connect 0,1,2 to /dev/null */ + FORK_REOPEN_LOG = 1 << 5, /* Reopen log connection */ + FORK_LOG = 1 << 6, /* Log above LOG_DEBUG log level about failures */ + FORK_WAIT = 1 << 7, /* Wait until child exited */ + FORK_NEW_MOUNTNS = 1 << 8, /* Run child in its own mount namespace */ + FORK_MOUNTNS_SLAVE = 1 << 9, /* Make child's mount namespace MS_SLAVE */ + FORK_RLIMIT_NOFILE_SAFE = 1 << 10, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */ + FORK_STDOUT_TO_STDERR = 1 << 11, /* Make stdout a copy of stderr */ +} ForkFlags; + +int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid); + +static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) { + return safe_fork_full(name, NULL, 0, flags, ret_pid); +} + +int namespace_fork(const char *outer_name, const char *inner_name, const int except_fds[], size_t n_except_fds, ForkFlags flags, int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd, pid_t *ret_pid); + +int fork_agent(const char *name, const int except[], size_t n_except, pid_t *pid, const char *path, ...) _sentinel_; + +int set_oom_score_adjust(int value); + +/* The highest possibly (theoretic) pid_t value on this architecture. */ +#define PID_T_MAX ((pid_t) INT32_MAX) +/* The maximum number of concurrent processes Linux allows on this architecture, as well as the highest valid PID value + * the kernel will potentially assign. This reflects a value compiled into the kernel (PID_MAX_LIMIT), and sets the + * upper boundary on what may be written to the /proc/sys/kernel/pid_max sysctl (but do note that the sysctl is off by + * 1, since PID 0 can never exist and there can hence only be one process less than the limit would suggest). Since + * these values are documented in proc(5) we feel quite confident that they are stable enough for the near future at + * least to define them here too. */ +#define TASKS_MAX 4194303U + +assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX); + +/* Like TAKE_PTR() but for child PIDs, resetting them to 0 */ +#define TAKE_PID(pid) \ + ({ \ + pid_t _pid_ = (pid); \ + (pid) = 0; \ + _pid_; \ + }) + +int pidfd_get_pid(int fd, pid_t *ret); + +int setpriority_closest(int priority); diff --git a/src/libnm-systemd-shared/src/basic/random-util.c b/src/libnm-systemd-shared/src/basic/random-util.c new file mode 100644 index 0000000..4f67d9a --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/random-util.c @@ -0,0 +1,507 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#if defined(__i386__) || defined(__x86_64__) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_SYS_AUXV_H +# include +#endif + +#include "alloc-util.h" +#include "env-util.h" +#include "errno-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "io-util.h" +#include "missing_random.h" +#include "missing_syscall.h" +#include "parse-util.h" +#include "random-util.h" +#include "siphash24.h" +#include "time-util.h" + +static bool srand_called = false; + +int rdrand(unsigned long *ret) { + + /* So, you are a "security researcher", and you wonder why we bother with using raw RDRAND here, + * instead of sticking to /dev/urandom or getrandom()? + * + * Here's why: early boot. On Linux, during early boot the random pool that backs /dev/urandom and + * getrandom() is generally not initialized yet. It is very common that initialization of the random + * pool takes a longer time (up to many minutes), in particular on embedded devices that have no + * explicit hardware random generator, as well as in virtualized environments such as major cloud + * installations that do not provide virtio-rng or a similar mechanism. + * + * In such an environment using getrandom() synchronously means we'd block the entire system boot-up + * until the pool is initialized, i.e. *very* long. Using getrandom() asynchronously (GRND_NONBLOCK) + * would mean acquiring randomness during early boot would simply fail. Using /dev/urandom would mean + * generating many kmsg log messages about our use of it before the random pool is properly + * initialized. Neither of these outcomes is desirable. + * + * Thus, for very specific purposes we use RDRAND instead of either of these three options. RDRAND + * provides us quickly and relatively reliably with random values, without having to delay boot, + * without triggering warning messages in kmsg. + * + * Note that we use RDRAND only under very specific circumstances, when the requirements on the + * quality of the returned entropy permit it. Specifically, here are some cases where we *do* use + * RDRAND: + * + * • UUID generation: UUIDs are supposed to be universally unique but are not cryptographic + * key material. The quality and trust level of RDRAND should hence be OK: UUIDs should be + * generated in a way that is reliably unique, but they do not require ultimate trust into + * the entropy generator. systemd generates a number of UUIDs during early boot, including + * 'invocation IDs' for every unit spawned that identify the specific invocation of the + * service globally, and a number of others. Other alternatives for generating these UUIDs + * have been considered, but don't really work: for example, hashing uuids from a local + * system identifier combined with a counter falls flat because during early boot disk + * storage is not yet available (think: initrd) and thus a system-specific ID cannot be + * stored or retrieved yet. + * + * • Hash table seed generation: systemd uses many hash tables internally. Hash tables are + * generally assumed to have O(1) access complexity, but can deteriorate to prohibitive + * O(n) access complexity if an attacker manages to trigger a large number of hash + * collisions. Thus, systemd (as any software employing hash tables should) uses seeded + * hash functions for its hash tables, with a seed generated randomly. The hash tables + * systemd employs watch the fill level closely and reseed if necessary. This allows use of + * a low quality RNG initially, as long as it improves should a hash table be under attack: + * the attacker after all needs to trigger many collisions to exploit it for the purpose + * of DoS, but if doing so improves the seed the attack surface is reduced as the attack + * takes place. + * + * Some cases where we do NOT use RDRAND are: + * + * • Generation of cryptographic key material 🔑 + * + * • Generation of cryptographic salt values 🧂 + * + * This function returns: + * + * -EOPNOTSUPP → RDRAND is not available on this system 😔 + * -EAGAIN → The operation failed this time, but is likely to work if you try again a few + * times ♻ + * -EUCLEAN → We got some random value, but it looked strange, so we refused using it. + * This failure might or might not be temporary. 😕 + */ + +#if defined(__i386__) || defined(__x86_64__) + static int have_rdrand = -1; + unsigned long v; + uint8_t success; + + if (have_rdrand < 0) { + uint32_t eax, ebx, ecx, edx; + + /* Check if RDRAND is supported by the CPU */ + if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0) { + have_rdrand = false; + return -EOPNOTSUPP; + } + +/* Compat with old gcc where bit_RDRND didn't exist yet */ +#ifndef bit_RDRND +#define bit_RDRND (1U << 30) +#endif + + have_rdrand = !!(ecx & bit_RDRND); + + if (have_rdrand > 0) { + /* Allow disabling use of RDRAND with SYSTEMD_RDRAND=0 + If it is unset getenv_bool_secure will return a negative value. */ + if (getenv_bool_secure("SYSTEMD_RDRAND") == 0) { + have_rdrand = false; + return -EOPNOTSUPP; + } + } + } + + if (have_rdrand == 0) + return -EOPNOTSUPP; + + asm volatile("rdrand %0;" + "setc %1" + : "=r" (v), + "=qm" (success)); + msan_unpoison(&success, sizeof(success)); + if (!success) + return -EAGAIN; + + /* Apparently on some AMD CPUs RDRAND will sometimes (after a suspend/resume cycle?) report success + * via the carry flag but nonetheless return the same fixed value -1 in all cases. This appears to be + * a bad bug in the CPU or firmware. Let's deal with that and work-around this by explicitly checking + * for this special value (and also 0, just to be sure) and filtering it out. This is a work-around + * only however and something AMD really should fix properly. The Linux kernel should probably work + * around this issue by turning off RDRAND altogether on those CPUs. See: + * https://github.com/systemd/systemd/issues/11810 */ + if (v == 0 || v == ULONG_MAX) + return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN), + "RDRAND returned suspicious value %lx, assuming bad hardware RNG, not using value.", v); + + *ret = v; + return 0; +#else + return -EOPNOTSUPP; +#endif +} + +int genuine_random_bytes(void *p, size_t n, RandomFlags flags) { + static int have_syscall = -1; + _cleanup_close_ int fd = -1; + bool got_some = false; + int r; + + /* Gathers some high-quality randomness from the kernel (or potentially mid-quality randomness from + * the CPU if the RANDOM_ALLOW_RDRAND flag is set). This call won't block, unless the RANDOM_BLOCK + * flag is set. If RANDOM_MAY_FAIL is set, an error is returned if the random pool is not + * initialized. Otherwise it will always return some data from the kernel, regardless of whether the + * random pool is fully initialized or not. If RANDOM_EXTEND_WITH_PSEUDO is set, and some but not + * enough better quality randomness could be acquired, the rest is filled up with low quality + * randomness. + * + * Of course, when creating cryptographic key material you really shouldn't use RANDOM_ALLOW_DRDRAND + * or even RANDOM_EXTEND_WITH_PSEUDO. + * + * When generating UUIDs it's fine to use RANDOM_ALLOW_RDRAND but not OK to use + * RANDOM_EXTEND_WITH_PSEUDO. In fact RANDOM_EXTEND_WITH_PSEUDO is only really fine when invoked via + * an "all bets are off" wrapper, such as random_bytes(), see below. */ + + if (n == 0) + return 0; + + if (FLAGS_SET(flags, RANDOM_ALLOW_RDRAND)) + /* Try x86-64' RDRAND intrinsic if we have it. We only use it if high quality randomness is + * not required, as we don't trust it (who does?). Note that we only do a single iteration of + * RDRAND here, even though the Intel docs suggest calling this in a tight loop of 10 + * invocations or so. That's because we don't really care about the quality here. We + * generally prefer using RDRAND if the caller allows us to, since this way we won't upset + * the kernel's random subsystem by accessing it before the pool is initialized (after all it + * will kmsg log about every attempt to do so)..*/ + for (;;) { + unsigned long u; + size_t m; + + if (rdrand(&u) < 0) { + if (got_some && FLAGS_SET(flags, RANDOM_EXTEND_WITH_PSEUDO)) { + /* Fill in the remaining bytes using pseudo-random values */ + pseudo_random_bytes(p, n); + return 0; + } + + /* OK, this didn't work, let's go to getrandom() + /dev/urandom instead */ + break; + } + + m = MIN(sizeof(u), n); + memcpy(p, &u, m); + + p = (uint8_t*) p + m; + n -= m; + + if (n == 0) + return 0; /* Yay, success! */ + + got_some = true; + } + + /* Use the getrandom() syscall unless we know we don't have it. */ + if (have_syscall != 0 && !HAS_FEATURE_MEMORY_SANITIZER) { + + for (;;) { +#if !HAVE_GETRANDOM + /* NetworkManager Note: systemd calls the syscall directly in this case. Don't add that workaround. + * If you don't compile against a libc that provides getrandom(), you don't get it. */ + r = -1; + errno = ENOSYS; +#else + r = getrandom(p, n, + (FLAGS_SET(flags, RANDOM_BLOCK) ? 0 : GRND_NONBLOCK) | + (FLAGS_SET(flags, RANDOM_ALLOW_INSECURE) ? GRND_INSECURE : 0)); +#endif + if (r > 0) { + have_syscall = true; + + if ((size_t) r == n) + return 0; /* Yay, success! */ + + assert((size_t) r < n); + p = (uint8_t*) p + r; + n -= r; + + if (FLAGS_SET(flags, RANDOM_EXTEND_WITH_PSEUDO)) { + /* Fill in the remaining bytes using pseudo-random values */ + pseudo_random_bytes(p, n); + return 0; + } + + got_some = true; + + /* Hmm, we didn't get enough good data but the caller insists on good data? Then try again */ + if (FLAGS_SET(flags, RANDOM_BLOCK)) + continue; + + /* Fill in the rest with /dev/urandom */ + break; + + } else if (r == 0) { + have_syscall = true; + return -EIO; + + } else if (ERRNO_IS_NOT_SUPPORTED(errno)) { + /* We lack the syscall, continue with reading from /dev/urandom. */ + have_syscall = false; + break; + + } else if (errno == EAGAIN) { + /* The kernel has no entropy whatsoever. Let's remember to use the syscall + * the next time again though. + * + * If RANDOM_MAY_FAIL is set, return an error so that random_bytes() can + * produce some pseudo-random bytes instead. Otherwise, fall back to + * /dev/urandom, which we know is empty, but the kernel will produce some + * bytes for us on a best-effort basis. */ + have_syscall = true; + + if (got_some && FLAGS_SET(flags, RANDOM_EXTEND_WITH_PSEUDO)) { + /* Fill in the remaining bytes using pseudorandom values */ + pseudo_random_bytes(p, n); + return 0; + } + + if (FLAGS_SET(flags, RANDOM_MAY_FAIL)) + return -ENODATA; + + /* Use /dev/urandom instead */ + break; + + } else if (errno == EINVAL) { + + /* Most likely: unknown flag. We know that GRND_INSECURE might cause this, + * hence try without. */ + + if (FLAGS_SET(flags, RANDOM_ALLOW_INSECURE)) { + flags = flags &~ RANDOM_ALLOW_INSECURE; + continue; + } + + return -errno; + } else + return -errno; + } + } + + fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return errno == ENOENT ? -ENOSYS : -errno; + + return loop_read_exact(fd, p, n, true); +} + +static void clear_srand_initialization(void) { + srand_called = false; +} + +void initialize_srand(void) { + static bool pthread_atfork_registered = false; + unsigned x; +#if HAVE_SYS_AUXV_H + const void *auxv; +#endif + unsigned long k; + + if (srand_called) + return; + +#if HAVE_SYS_AUXV_H + /* The kernel provides us with 16 bytes of entropy in auxv, so let's try to make use of that to seed + * the pseudo-random generator. It's better than nothing... But let's first hash it to make it harder + * to recover the original value by watching any pseudo-random bits we generate. After all the + * AT_RANDOM data might be used by other stuff too (in particular: ASLR), and we probably shouldn't + * leak the seed for that. */ + + auxv = ULONG_TO_PTR(getauxval(AT_RANDOM)); + if (auxv) { + static const uint8_t auxval_hash_key[16] = { + 0x92, 0x6e, 0xfe, 0x1b, 0xcf, 0x00, 0x52, 0x9c, 0xcc, 0x42, 0xcf, 0xdc, 0x94, 0x1f, 0x81, 0x0f + }; + + x = (unsigned) siphash24(auxv, 16, auxval_hash_key); + } else +#endif + x = 0; + + x ^= (unsigned) now(CLOCK_REALTIME); + x ^= (unsigned) gettid(); + + if (rdrand(&k) >= 0) + x ^= (unsigned) k; + + srand(x); + srand_called = true; + + if (!pthread_atfork_registered) { + (void) pthread_atfork(NULL, NULL, clear_srand_initialization); + pthread_atfork_registered = true; + } +} + +/* INT_MAX gives us only 31 bits, so use 24 out of that. */ +#if RAND_MAX >= INT_MAX +assert_cc(RAND_MAX >= 16777215); +# define RAND_STEP 3 +#else +/* SHORT_INT_MAX or lower gives at most 15 bits, we just use 8 out of that. */ +assert_cc(RAND_MAX >= 255); +# define RAND_STEP 1 +#endif + +void pseudo_random_bytes(void *p, size_t n) { + uint8_t *q; + + /* This returns pseudo-random data using libc's rand() function. You probably never want to call this + * directly, because why would you use this if you can get better stuff cheaply? Use random_bytes() + * instead, see below: it will fall back to this function if there's nothing better to get, but only + * then. */ + + initialize_srand(); + + for (q = p; q < (uint8_t*) p + n; q += RAND_STEP) { + unsigned rr; + + rr = (unsigned) rand(); + +#if RAND_STEP >= 3 + if ((size_t) (q - (uint8_t*) p + 2) < n) + q[2] = rr >> 16; +#endif +#if RAND_STEP >= 2 + if ((size_t) (q - (uint8_t*) p + 1) < n) + q[1] = rr >> 8; +#endif + q[0] = rr; + } +} + +void random_bytes(void *p, size_t n) { + + /* This returns high quality randomness if we can get it cheaply. If we can't because for some reason + * it is not available we'll try some crappy fallbacks. + * + * What this function will do: + * + * • This function will preferably use the CPU's RDRAND operation, if it is available, in + * order to return "mid-quality" random values cheaply. + * + * • Use getrandom() with GRND_NONBLOCK, to return high-quality random values if they are + * cheaply available. + * + * • This function will return pseudo-random data, generated via libc rand() if nothing + * better is available. + * + * • This function will work fine in early boot + * + * • This function will always succeed + * + * What this function won't do: + * + * • This function will never fail: it will give you randomness no matter what. It might not + * be high quality, but it will return some, possibly generated via libc's rand() call. + * + * • This function will never block: if the only way to get good randomness is a blocking, + * synchronous getrandom() we'll instead provide you with pseudo-random data. + * + * This function is hence great for things like seeding hash tables, generating random numeric UNIX + * user IDs (that are checked for collisions before use) and such. + * + * This function is hence not useful for generating UUIDs or cryptographic key material. + */ + + if (genuine_random_bytes(p, n, RANDOM_EXTEND_WITH_PSEUDO|RANDOM_MAY_FAIL|RANDOM_ALLOW_RDRAND|RANDOM_ALLOW_INSECURE) >= 0) + return; + + /* If for some reason some user made /dev/urandom unavailable to us, or the kernel has no entropy, use a PRNG instead. */ + pseudo_random_bytes(p, n); +} + +#if 0 /* NM_IGNORED */ +size_t random_pool_size(void) { + _cleanup_free_ char *s = NULL; + int r; + + /* Read pool size, if possible */ + r = read_one_line_file("/proc/sys/kernel/random/poolsize", &s); + if (r < 0) + log_debug_errno(r, "Failed to read pool size from kernel: %m"); + else { + unsigned sz; + + r = safe_atou(s, &sz); + if (r < 0) + log_debug_errno(r, "Failed to parse pool size: %s", s); + else + /* poolsize is in bits on 2.6, but we want bytes */ + return CLAMP(sz / 8, RANDOM_POOL_SIZE_MIN, RANDOM_POOL_SIZE_MAX); + } + + /* Use the minimum as default, if we can't retrieve the correct value */ + return RANDOM_POOL_SIZE_MIN; +} + +int random_write_entropy(int fd, const void *seed, size_t size, bool credit) { + _cleanup_close_ int opened_fd = -1; + int r; + + assert(seed || size == 0); + + if (size == 0) + return 0; + + if (fd < 0) { + opened_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY); + if (opened_fd < 0) + return -errno; + + fd = opened_fd; + } + + if (credit) { + _cleanup_free_ struct rand_pool_info *info = NULL; + + /* The kernel API only accepts "int" as entropy count (which is in bits), let's avoid any + * chance for confusion here. */ + if (size > INT_MAX / 8) + return -EOVERFLOW; + + info = malloc(offsetof(struct rand_pool_info, buf) + size); + if (!info) + return -ENOMEM; + + info->entropy_count = size * 8; + info->buf_size = size; + memcpy(info->buf, seed, size); + + if (ioctl(fd, RNDADDENTROPY, info) < 0) + return -errno; + } else { + r = loop_write(fd, seed, size, false); + if (r < 0) + return r; + } + + return 1; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/random-util.h b/src/libnm-systemd-shared/src/basic/random-util.h new file mode 100644 index 0000000..f661fc0 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/random-util.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include + +typedef enum RandomFlags { + RANDOM_EXTEND_WITH_PSEUDO = 1 << 0, /* If we can't get enough genuine randomness, but some, fill up the rest with pseudo-randomness */ + RANDOM_BLOCK = 1 << 1, /* Rather block than return crap randomness (only if the kernel supports that) */ + RANDOM_MAY_FAIL = 1 << 2, /* If we can't get any randomness at all, return early with -ENODATA */ + RANDOM_ALLOW_RDRAND = 1 << 3, /* Allow usage of the CPU RNG */ + RANDOM_ALLOW_INSECURE = 1 << 4, /* Allow usage of GRND_INSECURE flag to kernel's getrandom() API */ +} RandomFlags; + +int genuine_random_bytes(void *p, size_t n, RandomFlags flags); /* returns "genuine" randomness, optionally filled up with pseudo random, if not enough is available */ +void pseudo_random_bytes(void *p, size_t n); /* returns only pseudo-randommess (but possibly seeded from something better) */ +void random_bytes(void *p, size_t n); /* returns genuine randomness if cheaply available, and pseudo randomness if not. */ + +void initialize_srand(void); + +static inline uint64_t random_u64(void) { + uint64_t u; + random_bytes(&u, sizeof(u)); + return u; +} + +static inline uint32_t random_u32(void) { + uint32_t u; + random_bytes(&u, sizeof(u)); + return u; +} + +int rdrand(unsigned long *ret); + +/* Some limits on the pool sizes when we deal with the kernel random pool */ +#define RANDOM_POOL_SIZE_MIN 512U +#define RANDOM_POOL_SIZE_MAX (10U*1024U*1024U) + +size_t random_pool_size(void); + +int random_write_entropy(int fd, const void *seed, size_t size, bool credit); diff --git a/src/libnm-systemd-shared/src/basic/ratelimit.c b/src/libnm-systemd-shared/src/basic/ratelimit.c new file mode 100644 index 0000000..12c8324 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/ratelimit.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include + +#include "macro.h" +#include "ratelimit.h" + +/* Modelled after Linux' lib/ratelimit.c by Dave Young + * , which is licensed GPLv2. */ + +bool ratelimit_below(RateLimit *r) { + usec_t ts; + + assert(r); + + if (!ratelimit_configured(r)) + return true; + + ts = now(CLOCK_MONOTONIC); + + if (r->begin <= 0 || + ts - r->begin > r->interval) { + r->begin = ts; + + /* Reset counter */ + r->num = 0; + goto good; + } + + if (r->num < r->burst) + goto good; + + return false; + +good: + r->num++; + return true; +} diff --git a/src/libnm-systemd-shared/src/basic/ratelimit.h b/src/libnm-systemd-shared/src/basic/ratelimit.h new file mode 100644 index 0000000..ee1d17c --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/ratelimit.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#include "time-util.h" +#include "util.h" + +typedef struct RateLimit { + usec_t interval; /* Keep those two fields first so they can be initialized easily: */ + unsigned burst; /* RateLimit rl = { INTERVAL, BURST }; */ + unsigned num; + usec_t begin; +} RateLimit; + +static inline void ratelimit_reset(RateLimit *rl) { + rl->num = rl->begin = 0; +} + +static inline bool ratelimit_configured(RateLimit *rl) { + return rl->interval > 0 && rl->burst > 0; +} + +bool ratelimit_below(RateLimit *r); diff --git a/src/libnm-systemd-shared/src/basic/set.h b/src/libnm-systemd-shared/src/basic/set.h new file mode 100644 index 0000000..57ff713 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/set.h @@ -0,0 +1,154 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "extract-word.h" +#include "hashmap.h" +#include "macro.h" + +#define set_free_and_replace(a, b) \ + ({ \ + set_free(a); \ + (a) = (b); \ + (b) = NULL; \ + 0; \ + }) + +Set* _set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +#define set_new(ops) _set_new(ops HASHMAP_DEBUG_SRC_ARGS) + +static inline Set* set_free(Set *s) { + return (Set*) _hashmap_free(HASHMAP_BASE(s), NULL, NULL); +} + +static inline Set* set_free_free(Set *s) { + return (Set*) _hashmap_free(HASHMAP_BASE(s), free, NULL); +} + +/* no set_free_free_free */ + +#define set_copy(s) ((Set*) _hashmap_copy(HASHMAP_BASE(h) HASHMAP_DEBUG_SRC_ARGS)) + +int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +#define set_ensure_allocated(h, ops) _set_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS) + +int set_put(Set *s, const void *key); +/* no set_update */ +/* no set_replace */ +static inline void *set_get(const Set *s, const void *key) { + return _hashmap_get(HASHMAP_BASE((Set *) s), key); +} +/* no set_get2 */ + +static inline bool set_contains(const Set *s, const void *key) { + return _hashmap_contains(HASHMAP_BASE((Set *) s), key); +} + +static inline void *set_remove(Set *s, const void *key) { + return _hashmap_remove(HASHMAP_BASE(s), key); +} + +/* no set_remove2 */ +/* no set_remove_value */ +int set_remove_and_put(Set *s, const void *old_key, const void *new_key); +/* no set_remove_and_replace */ +int set_merge(Set *s, Set *other); + +static inline int set_reserve(Set *h, unsigned entries_add) { + return _hashmap_reserve(HASHMAP_BASE(h), entries_add); +} + +static inline int set_move(Set *s, Set *other) { + return _hashmap_move(HASHMAP_BASE(s), HASHMAP_BASE(other)); +} + +static inline int set_move_one(Set *s, Set *other, const void *key) { + return _hashmap_move_one(HASHMAP_BASE(s), HASHMAP_BASE(other), key); +} + +static inline unsigned set_size(const Set *s) { + return _hashmap_size(HASHMAP_BASE((Set *) s)); +} + +static inline bool set_isempty(const Set *s) { + return set_size(s) == 0; +} + +static inline unsigned set_buckets(const Set *s) { + return _hashmap_buckets(HASHMAP_BASE((Set *) s)); +} + +static inline bool set_iterate(const Set *s, Iterator *i, void **value) { + return _hashmap_iterate(HASHMAP_BASE((Set*) s), i, value, NULL); +} + +static inline void set_clear(Set *s) { + _hashmap_clear(HASHMAP_BASE(s), NULL, NULL); +} + +static inline void set_clear_free(Set *s) { + _hashmap_clear(HASHMAP_BASE(s), free, NULL); +} + +/* no set_clear_free_free */ + +static inline void *set_steal_first(Set *s) { + return _hashmap_first_key_and_value(HASHMAP_BASE(s), true, NULL); +} + +#define set_clear_with_destructor(_s, _f) \ + ({ \ + void *_item; \ + while ((_item = set_steal_first(_s))) \ + _f(_item); \ + }) +#define set_free_with_destructor(_s, _f) \ + ({ \ + set_clear_with_destructor(_s, _f); \ + set_free(_s); \ + }) + +/* no set_steal_first_key */ +/* no set_first_key */ + +static inline void *set_first(const Set *s) { + return _hashmap_first_key_and_value(HASHMAP_BASE((Set *) s), false, NULL); +} + +/* no set_next */ + +static inline char **set_get_strv(Set *s) { + return _hashmap_get_strv(HASHMAP_BASE(s)); +} + +int _set_ensure_put(Set **s, const struct hash_ops *hash_ops, const void *key HASHMAP_DEBUG_PARAMS); +#define set_ensure_put(s, hash_ops, key) _set_ensure_put(s, hash_ops, key HASHMAP_DEBUG_SRC_ARGS) + +int _set_ensure_consume(Set **s, const struct hash_ops *hash_ops, void *key HASHMAP_DEBUG_PARAMS); +#define set_ensure_consume(s, hash_ops, key) _set_ensure_consume(s, hash_ops, key HASHMAP_DEBUG_SRC_ARGS) + +int set_consume(Set *s, void *value); + +int _set_put_strdup_full(Set **s, const struct hash_ops *hash_ops, const char *p HASHMAP_DEBUG_PARAMS); +#define set_put_strdup_full(s, hash_ops, p) _set_put_strdup_full(s, hash_ops, p HASHMAP_DEBUG_SRC_ARGS) +#define set_put_strdup(s, p) set_put_strdup_full(s, &string_hash_ops_free, p) +int _set_put_strdupv_full(Set **s, const struct hash_ops *hash_ops, char **l HASHMAP_DEBUG_PARAMS); +#define set_put_strdupv_full(s, hash_ops, l) _set_put_strdupv_full(s, hash_ops, l HASHMAP_DEBUG_SRC_ARGS) +#define set_put_strdupv(s, l) set_put_strdupv_full(s, &string_hash_ops_free, l) + +int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags); + +#define _SET_FOREACH(e, s, i) \ + for (Iterator i = ITERATOR_FIRST; set_iterate((s), &i, (void**)&(e)); ) +#define SET_FOREACH(e, s) \ + _SET_FOREACH(e, s, UNIQ_T(i, UNIQ)) + +#define SET_FOREACH_MOVE(e, d, s) \ + for (; ({ e = set_first(s); assert_se(!e || set_move_one(d, s, e) >= 0); e; }); ) + +DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free); + +#define _cleanup_set_free_ _cleanup_(set_freep) +#define _cleanup_set_free_free_ _cleanup_(set_free_freep) + +int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **ret); diff --git a/src/libnm-systemd-shared/src/basic/signal-util.c b/src/libnm-systemd-shared/src/basic/signal-util.c new file mode 100644 index 0000000..0c6f581 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/signal-util.c @@ -0,0 +1,299 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include + +#include "macro.h" +#include "parse-util.h" +#include "signal-util.h" +#include "stdio-util.h" +#include "string-table.h" +#include "string-util.h" + +#if 0 /* NM_IGNORED */ +int reset_all_signal_handlers(void) { + static const struct sigaction sa = { + .sa_handler = SIG_DFL, + .sa_flags = SA_RESTART, + }; + int sig, r = 0; + + for (sig = 1; sig < _NSIG; sig++) { + + /* These two cannot be caught... */ + if (IN_SET(sig, SIGKILL, SIGSTOP)) + continue; + + /* On Linux the first two RT signals are reserved by + * glibc, and sigaction() will return EINVAL for them. */ + if (sigaction(sig, &sa, NULL) < 0) + if (errno != EINVAL && r >= 0) + r = -errno; + } + + return r; +} + +int reset_signal_mask(void) { + sigset_t ss; + + if (sigemptyset(&ss) < 0) + return -errno; + + if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) + return -errno; + + return 0; +} + +static int sigaction_many_ap(const struct sigaction *sa, int sig, va_list ap) { + int r = 0; + + /* negative signal ends the list. 0 signal is skipped. */ + for (; sig >= 0; sig = va_arg(ap, int)) { + + if (sig == 0) + continue; + + if (sigaction(sig, sa, NULL) < 0) { + if (r >= 0) + r = -errno; + } + } + + return r; +} + +int sigaction_many(const struct sigaction *sa, ...) { + va_list ap; + int r; + + va_start(ap, sa); + r = sigaction_many_ap(sa, 0, ap); + va_end(ap); + + return r; +} + +int ignore_signals(int sig, ...) { + + static const struct sigaction sa = { + .sa_handler = SIG_IGN, + .sa_flags = SA_RESTART, + }; + + va_list ap; + int r; + + va_start(ap, sig); + r = sigaction_many_ap(&sa, sig, ap); + va_end(ap); + + return r; +} + +int default_signals(int sig, ...) { + + static const struct sigaction sa = { + .sa_handler = SIG_DFL, + .sa_flags = SA_RESTART, + }; + + va_list ap; + int r; + + va_start(ap, sig); + r = sigaction_many_ap(&sa, sig, ap); + va_end(ap); + + return r; +} + +static int sigset_add_many_ap(sigset_t *ss, va_list ap) { + int sig, r = 0; + + assert(ss); + + while ((sig = va_arg(ap, int)) >= 0) { + + if (sig == 0) + continue; + + if (sigaddset(ss, sig) < 0) { + if (r >= 0) + r = -errno; + } + } + + return r; +} + +int sigset_add_many(sigset_t *ss, ...) { + va_list ap; + int r; + + va_start(ap, ss); + r = sigset_add_many_ap(ss, ap); + va_end(ap); + + return r; +} + +int sigprocmask_many(int how, sigset_t *old, ...) { + va_list ap; + sigset_t ss; + int r; + + if (sigemptyset(&ss) < 0) + return -errno; + + va_start(ap, old); + r = sigset_add_many_ap(&ss, ap); + va_end(ap); + + if (r < 0) + return r; + + if (sigprocmask(how, &ss, old) < 0) + return -errno; + + return 0; +} + +static const char *const __signal_table[] = { + [SIGHUP] = "HUP", + [SIGINT] = "INT", + [SIGQUIT] = "QUIT", + [SIGILL] = "ILL", + [SIGTRAP] = "TRAP", + [SIGABRT] = "ABRT", + [SIGBUS] = "BUS", + [SIGFPE] = "FPE", + [SIGKILL] = "KILL", + [SIGUSR1] = "USR1", + [SIGSEGV] = "SEGV", + [SIGUSR2] = "USR2", + [SIGPIPE] = "PIPE", + [SIGALRM] = "ALRM", + [SIGTERM] = "TERM", +#ifdef SIGSTKFLT + [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */ +#endif + [SIGCHLD] = "CHLD", + [SIGCONT] = "CONT", + [SIGSTOP] = "STOP", + [SIGTSTP] = "TSTP", + [SIGTTIN] = "TTIN", + [SIGTTOU] = "TTOU", + [SIGURG] = "URG", + [SIGXCPU] = "XCPU", + [SIGXFSZ] = "XFSZ", + [SIGVTALRM] = "VTALRM", + [SIGPROF] = "PROF", + [SIGWINCH] = "WINCH", + [SIGIO] = "IO", + [SIGPWR] = "PWR", + [SIGSYS] = "SYS" +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int); + +const char *signal_to_string(int signo) { + static thread_local char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int) + 1]; + const char *name; + + name = __signal_to_string(signo); + if (name) + return name; + + if (signo >= SIGRTMIN && signo <= SIGRTMAX) + xsprintf(buf, "RTMIN+%d", signo - SIGRTMIN); + else + xsprintf(buf, "%d", signo); + + return buf; +} + +int signal_from_string(const char *s) { + const char *p; + int signo, r; + + /* Check that the input is a signal number. */ + if (safe_atoi(s, &signo) >= 0) { + if (SIGNAL_VALID(signo)) + return signo; + else + return -ERANGE; + } + + /* Drop "SIG" prefix. */ + if (startswith(s, "SIG")) + s += 3; + + /* Check that the input is a signal name. */ + signo = __signal_from_string(s); + if (signo > 0) + return signo; + + /* Check that the input is RTMIN or + * RTMIN+n (0 <= n <= SIGRTMAX-SIGRTMIN). */ + p = startswith(s, "RTMIN"); + if (p) { + if (*p == '\0') + return SIGRTMIN; + if (*p != '+') + return -EINVAL; + + r = safe_atoi(p, &signo); + if (r < 0) + return r; + + if (signo < 0 || signo > SIGRTMAX - SIGRTMIN) + return -ERANGE; + + return signo + SIGRTMIN; + } + + /* Check that the input is RTMAX or + * RTMAX-n (0 <= n <= SIGRTMAX-SIGRTMIN). */ + p = startswith(s, "RTMAX"); + if (p) { + if (*p == '\0') + return SIGRTMAX; + if (*p != '-') + return -EINVAL; + + r = safe_atoi(p, &signo); + if (r < 0) + return r; + + if (signo > 0 || signo < SIGRTMIN - SIGRTMAX) + return -ERANGE; + + return signo + SIGRTMAX; + } + + return -EINVAL; +} + +void nop_signal_handler(int sig) { + /* nothing here */ +} +#endif /* NM_IGNORED */ + +int signal_is_blocked(int sig) { + sigset_t ss; + int r; + + r = pthread_sigmask(SIG_SETMASK, NULL, &ss); + if (r != 0) + return -r; + + r = sigismember(&ss, sig); + if (r < 0) + return -errno; + + return r; +} diff --git a/src/libnm-systemd-shared/src/basic/signal-util.h b/src/libnm-systemd-shared/src/basic/signal-util.h new file mode 100644 index 0000000..bdd39d4 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/signal-util.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#include "macro.h" + +int reset_all_signal_handlers(void); +int reset_signal_mask(void); + +int ignore_signals(int sig, ...); +int default_signals(int sig, ...); +int sigaction_many(const struct sigaction *sa, ...); + +int sigset_add_many(sigset_t *ss, ...); +int sigprocmask_many(int how, sigset_t *old, ...); + +const char *signal_to_string(int i) _const_; +int signal_from_string(const char *s) _pure_; + +void nop_signal_handler(int sig); + +static inline void block_signals_reset(sigset_t *ss) { + assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0); +} + +#define BLOCK_SIGNALS(...) \ + _cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({ \ + sigset_t _t; \ + assert_se(sigprocmask_many(SIG_BLOCK, &_t, __VA_ARGS__, -1) >= 0); \ + _t; \ + }) + +static inline bool SIGNAL_VALID(int signo) { + return signo > 0 && signo < _NSIG; +} + +static inline const char* signal_to_string_with_check(int n) { + if (!SIGNAL_VALID(n)) + return NULL; + + return signal_to_string(n); +} + +int signal_is_blocked(int sig); diff --git a/src/libnm-systemd-shared/src/basic/siphash24.h b/src/libnm-systemd-shared/src/basic/siphash24.h new file mode 100644 index 0000000..e46f3cc --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/siphash24.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: CC0-1.0 */ + +#pragma once + +#include +#include +#include +#include + +#include "string-util.h" +#include "time-util.h" + +#if 0 /* NM_IGNORED */ +struct siphash { + uint64_t v0; + uint64_t v1; + uint64_t v2; + uint64_t v3; + uint64_t padding; + size_t inlen; +}; +#else /* NM_IGNORED */ +struct siphash { + CSipHash _csiphash; +}; + +static inline void +siphash24_init (struct siphash *state, const uint8_t k[16]) +{ + c_siphash_init ((CSipHash *) state, k); +} + +static inline void +siphash24_compress (const void *in, size_t inlen, struct siphash *state) +{ + c_siphash_append ((CSipHash *) state, in, inlen); +} + +static inline uint64_t +siphash24_finalize (struct siphash *state) +{ + return c_siphash_finalize ((CSipHash *) state); +} + +static inline uint64_t +siphash24 (const void *in, size_t inlen, const uint8_t k[16]) +{ + return c_siphash_hash (k, in, inlen); +} +#endif /* NM_IGNORED */ + +void siphash24_init(struct siphash *state, const uint8_t k[static 16]); +void siphash24_compress(const void *in, size_t inlen, struct siphash *state); +#define siphash24_compress_byte(byte, state) siphash24_compress((const uint8_t[]) { (byte) }, 1, (state)) + +static inline void siphash24_compress_boolean(bool in, struct siphash *state) { + uint8_t i = in; + + siphash24_compress(&i, sizeof i, state); +} + +static inline void siphash24_compress_usec_t(usec_t in, struct siphash *state) { + siphash24_compress(&in, sizeof in, state); +} + +static inline void siphash24_compress_safe(const void *in, size_t inlen, struct siphash *state) { + if (inlen == 0) + return; + + siphash24_compress(in, inlen, state); +} + +static inline void siphash24_compress_string(const char *in, struct siphash *state) { + siphash24_compress_safe(in, strlen_ptr(in), state); +} + +uint64_t siphash24_finalize(struct siphash *state); + +uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[static 16]); + +static inline uint64_t siphash24_string(const char *s, const uint8_t k[static 16]) { + return siphash24(s, strlen(s) + 1, k); +} diff --git a/src/libnm-systemd-shared/src/basic/socket-util.c b/src/libnm-systemd-shared/src/basic/socket-util.c new file mode 100644 index 0000000..e224091 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/socket-util.c @@ -0,0 +1,1360 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if 0 /* NM_IGNORED */ +#include +#endif /* NM_IGNORED */ + +#include "alloc-util.h" +#include "errno-util.h" +#include "escape.h" +#include "fd-util.h" +#include "fileio.h" +#include "format-util.h" +#include "io-util.h" +#include "log.h" +#include "memory-util.h" +#include "parse-util.h" +#include "path-util.h" +#include "process-util.h" +#include "socket-util.h" +#include "string-table.h" +#include "string-util.h" +#include "strv.h" +#include "user-util.h" +#include "utf8.h" + +#if 0 /* NM_IGNORED */ +#if ENABLE_IDN +# define IDN_FLAGS NI_IDN +#else +# define IDN_FLAGS 0 +#endif + +static const char* const socket_address_type_table[] = { + [SOCK_STREAM] = "Stream", + [SOCK_DGRAM] = "Datagram", + [SOCK_RAW] = "Raw", + [SOCK_RDM] = "ReliableDatagram", + [SOCK_SEQPACKET] = "SequentialPacket", + [SOCK_DCCP] = "DatagramCongestionControl", +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int); + +int socket_address_verify(const SocketAddress *a, bool strict) { + assert(a); + + /* With 'strict' we enforce additional sanity constraints which are not set by the standard, + * but should only apply to sockets we create ourselves. */ + + switch (socket_address_family(a)) { + + case AF_INET: + if (a->size != sizeof(struct sockaddr_in)) + return -EINVAL; + + if (a->sockaddr.in.sin_port == 0) + return -EINVAL; + + if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM)) + return -EINVAL; + + return 0; + + case AF_INET6: + if (a->size != sizeof(struct sockaddr_in6)) + return -EINVAL; + + if (a->sockaddr.in6.sin6_port == 0) + return -EINVAL; + + if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM)) + return -EINVAL; + + return 0; + + case AF_UNIX: + if (a->size < offsetof(struct sockaddr_un, sun_path)) + return -EINVAL; + if (a->size > sizeof(struct sockaddr_un) + !strict) + /* If !strict, allow one extra byte, since getsockname() on Linux will append + * a NUL byte if we have path sockets that are above sun_path's full size. */ + return -EINVAL; + + if (a->size > offsetof(struct sockaddr_un, sun_path) && + a->sockaddr.un.sun_path[0] != 0 && + strict) { + /* Only validate file system sockets here, and only in strict mode */ + const char *e; + + e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path)); + if (e) { + /* If there's an embedded NUL byte, make sure the size of the socket address matches it */ + if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1) + return -EINVAL; + } else { + /* If there's no embedded NUL byte, then the size needs to match the whole + * structure or the structure with one extra NUL byte suffixed. (Yeah, Linux is awful, + * and considers both equivalent: getsockname() even extends sockaddr_un beyond its + * size if the path is non NUL terminated.)*/ + if (!IN_SET(a->size, sizeof(a->sockaddr.un.sun_path), sizeof(a->sockaddr.un.sun_path)+1)) + return -EINVAL; + } + } + + if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET)) + return -EINVAL; + + return 0; + + case AF_NETLINK: + + if (a->size != sizeof(struct sockaddr_nl)) + return -EINVAL; + + if (!IN_SET(a->type, 0, SOCK_RAW, SOCK_DGRAM)) + return -EINVAL; + + return 0; + + case AF_VSOCK: + if (a->size != sizeof(struct sockaddr_vm)) + return -EINVAL; + + if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM)) + return -EINVAL; + + return 0; + + default: + return -EAFNOSUPPORT; + } +} + +int socket_address_print(const SocketAddress *a, char **ret) { + int r; + + assert(a); + assert(ret); + + r = socket_address_verify(a, false); /* We do non-strict validation, because we want to be + * able to pretty-print any socket the kernel considers + * valid. We still need to do validation to know if we + * can meaningfully print the address. */ + if (r < 0) + return r; + + if (socket_address_family(a) == AF_NETLINK) { + _cleanup_free_ char *sfamily = NULL; + + r = netlink_family_to_string_alloc(a->protocol, &sfamily); + if (r < 0) + return r; + + r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups); + if (r < 0) + return -ENOMEM; + + return 0; + } + + return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret); +} + +bool socket_address_can_accept(const SocketAddress *a) { + assert(a); + + return + IN_SET(a->type, SOCK_STREAM, SOCK_SEQPACKET); +} + +bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) { + assert(a); + assert(b); + + /* Invalid addresses are unequal to all */ + if (socket_address_verify(a, false) < 0 || + socket_address_verify(b, false) < 0) + return false; + + if (a->type != b->type) + return false; + + if (socket_address_family(a) != socket_address_family(b)) + return false; + + switch (socket_address_family(a)) { + + case AF_INET: + if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr) + return false; + + if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port) + return false; + + break; + + case AF_INET6: + if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0) + return false; + + if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port) + return false; + + break; + + case AF_UNIX: + if (a->size <= offsetof(struct sockaddr_un, sun_path) || + b->size <= offsetof(struct sockaddr_un, sun_path)) + return false; + + if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0)) + return false; + + if (a->sockaddr.un.sun_path[0]) { + if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, 0)) + return false; + } else { + if (a->size != b->size) + return false; + + if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0) + return false; + } + + break; + + case AF_NETLINK: + if (a->protocol != b->protocol) + return false; + + if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups) + return false; + + break; + + case AF_VSOCK: + if (a->sockaddr.vm.svm_cid != b->sockaddr.vm.svm_cid) + return false; + + if (a->sockaddr.vm.svm_port != b->sockaddr.vm.svm_port) + return false; + + break; + + default: + /* Cannot compare, so we assume the addresses are different */ + return false; + } + + return true; +} + +const char* socket_address_get_path(const SocketAddress *a) { + assert(a); + + if (socket_address_family(a) != AF_UNIX) + return NULL; + + if (a->sockaddr.un.sun_path[0] == 0) + return NULL; + + /* Note that this is only safe because we know that there's an extra NUL byte after the sockaddr_un + * structure. On Linux AF_UNIX file system socket addresses don't have to be NUL terminated if they take up the + * full sun_path space. */ + assert_cc(sizeof(union sockaddr_union) >= sizeof(struct sockaddr_un)+1); + return a->sockaddr.un.sun_path; +} + +bool socket_ipv6_is_supported(void) { + if (access("/proc/net/if_inet6", F_OK) != 0) + return false; + + return true; +} + +bool socket_address_matches_fd(const SocketAddress *a, int fd) { + SocketAddress b; + socklen_t solen; + + assert(a); + assert(fd >= 0); + + b.size = sizeof(b.sockaddr); + if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0) + return false; + + if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family) + return false; + + solen = sizeof(b.type); + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0) + return false; + + if (b.type != a->type) + return false; + + if (a->protocol != 0) { + solen = sizeof(b.protocol); + if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0) + return false; + + if (b.protocol != a->protocol) + return false; + } + + return socket_address_equal(a, &b); +} + +int sockaddr_port(const struct sockaddr *_sa, unsigned *ret_port) { + const union sockaddr_union *sa = (const union sockaddr_union*) _sa; + + /* Note, this returns the port as 'unsigned' rather than 'uint16_t', as AF_VSOCK knows larger ports */ + + assert(sa); + + switch (sa->sa.sa_family) { + + case AF_INET: + *ret_port = be16toh(sa->in.sin_port); + return 0; + + case AF_INET6: + *ret_port = be16toh(sa->in6.sin6_port); + return 0; + + case AF_VSOCK: + *ret_port = sa->vm.svm_port; + return 0; + + default: + return -EAFNOSUPPORT; + } +} + +const union in_addr_union *sockaddr_in_addr(const struct sockaddr *_sa) { + const union sockaddr_union *sa = (const union sockaddr_union*) _sa; + + if (!sa) + return NULL; + + switch (sa->sa.sa_family) { + + case AF_INET: + return (const union in_addr_union*) &sa->in.sin_addr; + + case AF_INET6: + return (const union in_addr_union*) &sa->in6.sin6_addr; + + default: + return NULL; + } +} + +int sockaddr_pretty( + const struct sockaddr *_sa, + socklen_t salen, + bool translate_ipv6, + bool include_port, + char **ret) { + + union sockaddr_union *sa = (union sockaddr_union*) _sa; + char *p; + int r; + + assert(sa); + assert(salen >= sizeof(sa->sa.sa_family)); + + switch (sa->sa.sa_family) { + + case AF_INET: { + uint32_t a; + + a = be32toh(sa->in.sin_addr.s_addr); + + if (include_port) + r = asprintf(&p, + "%u.%u.%u.%u:%u", + a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF, + be16toh(sa->in.sin_port)); + else + r = asprintf(&p, + "%u.%u.%u.%u", + a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF); + if (r < 0) + return -ENOMEM; + break; + } + + case AF_INET6: { + static const unsigned char ipv4_prefix[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF + }; + + if (translate_ipv6 && + memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) { + const uint8_t *a = sa->in6.sin6_addr.s6_addr+12; + if (include_port) + r = asprintf(&p, + "%u.%u.%u.%u:%u", + a[0], a[1], a[2], a[3], + be16toh(sa->in6.sin6_port)); + else + r = asprintf(&p, + "%u.%u.%u.%u", + a[0], a[1], a[2], a[3]); + if (r < 0) + return -ENOMEM; + } else { + char a[INET6_ADDRSTRLEN], ifname[IF_NAMESIZE + 1]; + + inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a)); + if (sa->in6.sin6_scope_id != 0) + format_ifname_full(sa->in6.sin6_scope_id, ifname, FORMAT_IFNAME_IFINDEX); + + if (include_port) { + r = asprintf(&p, + "[%s]:%u%s%s", + a, + be16toh(sa->in6.sin6_port), + sa->in6.sin6_scope_id != 0 ? "%" : "", + sa->in6.sin6_scope_id != 0 ? ifname : ""); + if (r < 0) + return -ENOMEM; + } else { + p = sa->in6.sin6_scope_id != 0 ? strjoin(a, "%", ifname) : strdup(a); + if (!p) + return -ENOMEM; + } + } + + break; + } + + case AF_UNIX: + if (salen <= offsetof(struct sockaddr_un, sun_path) || + (sa->un.sun_path[0] == 0 && salen == offsetof(struct sockaddr_un, sun_path) + 1)) + /* The name must have at least one character (and the leading NUL does not count) */ + p = strdup(""); + else { + /* Note that we calculate the path pointer here through the .un_buffer[] field, in order to + * outtrick bounds checking tools such as ubsan, which are too smart for their own good: on + * Linux the kernel may return sun_path[] data one byte longer than the declared size of the + * field. */ + char *path = (char*) sa->un_buffer + offsetof(struct sockaddr_un, sun_path); + size_t path_len = salen - offsetof(struct sockaddr_un, sun_path); + + if (path[0] == 0) { + /* Abstract socket. When parsing address information from, we + * explicitly reject overly long paths and paths with embedded NULs. + * But we might get such a socket from the outside. Let's return + * something meaningful and printable in this case. */ + + _cleanup_free_ char *e = NULL; + + e = cescape_length(path + 1, path_len - 1); + if (!e) + return -ENOMEM; + + p = strjoin("@", e); + } else { + if (path[path_len - 1] == '\0') + /* We expect a terminating NUL and don't print it */ + path_len --; + + p = cescape_length(path, path_len); + } + } + if (!p) + return -ENOMEM; + + break; + + case AF_VSOCK: + if (include_port) { + if (sa->vm.svm_cid == VMADDR_CID_ANY) + r = asprintf(&p, "vsock::%u", sa->vm.svm_port); + else + r = asprintf(&p, "vsock:%u:%u", sa->vm.svm_cid, sa->vm.svm_port); + } else + r = asprintf(&p, "vsock:%u", sa->vm.svm_cid); + if (r < 0) + return -ENOMEM; + break; + + default: + return -EOPNOTSUPP; + } + + *ret = p; + return 0; +} + +int getpeername_pretty(int fd, bool include_port, char **ret) { + union sockaddr_union sa; + socklen_t salen = sizeof(sa); + int r; + + assert(fd >= 0); + assert(ret); + + if (getpeername(fd, &sa.sa, &salen) < 0) + return -errno; + + if (sa.sa.sa_family == AF_UNIX) { + struct ucred ucred = {}; + + /* UNIX connection sockets are anonymous, so let's use + * PID/UID as pretty credentials instead */ + + r = getpeercred(fd, &ucred); + if (r < 0) + return r; + + if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0) + return -ENOMEM; + + return 0; + } + + /* For remote sockets we translate IPv6 addresses back to IPv4 + * if applicable, since that's nicer. */ + + return sockaddr_pretty(&sa.sa, salen, true, include_port, ret); +} + +int getsockname_pretty(int fd, char **ret) { + union sockaddr_union sa; + socklen_t salen = sizeof(sa); + + assert(fd >= 0); + assert(ret); + + if (getsockname(fd, &sa.sa, &salen) < 0) + return -errno; + + /* For local sockets we do not translate IPv6 addresses back + * to IPv6 if applicable, since this is usually used for + * listening sockets where the difference between IPv4 and + * IPv6 matters. */ + + return sockaddr_pretty(&sa.sa, salen, false, true, ret); +} + +int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) { + int r; + char host[NI_MAXHOST], *ret; + + assert(_ret); + + r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0, IDN_FLAGS); + if (r != 0) { + int saved_errno = errno; + + r = sockaddr_pretty(&sa->sa, salen, true, true, &ret); + if (r < 0) + return r; + + log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret); + } else { + ret = strdup(host); + if (!ret) + return -ENOMEM; + } + + *_ret = ret; + return 0; +} + +static const char* const netlink_family_table[] = { + [NETLINK_ROUTE] = "route", + [NETLINK_FIREWALL] = "firewall", + [NETLINK_INET_DIAG] = "inet-diag", + [NETLINK_NFLOG] = "nflog", + [NETLINK_XFRM] = "xfrm", + [NETLINK_SELINUX] = "selinux", + [NETLINK_ISCSI] = "iscsi", + [NETLINK_AUDIT] = "audit", + [NETLINK_FIB_LOOKUP] = "fib-lookup", + [NETLINK_CONNECTOR] = "connector", + [NETLINK_NETFILTER] = "netfilter", + [NETLINK_IP6_FW] = "ip6-fw", + [NETLINK_DNRTMSG] = "dnrtmsg", + [NETLINK_KOBJECT_UEVENT] = "kobject-uevent", + [NETLINK_GENERIC] = "generic", + [NETLINK_SCSITRANSPORT] = "scsitransport", + [NETLINK_ECRYPTFS] = "ecryptfs", + [NETLINK_RDMA] = "rdma", +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX); + +static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = { + [SOCKET_ADDRESS_DEFAULT] = "default", + [SOCKET_ADDRESS_BOTH] = "both", + [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only" +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); + +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *n) { + int r; + + r = parse_boolean(n); + if (r > 0) + return SOCKET_ADDRESS_IPV6_ONLY; + if (r == 0) + return SOCKET_ADDRESS_BOTH; + + return socket_address_bind_ipv6_only_from_string(n); +} + +bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) { + assert(a); + assert(b); + + if (a->sa.sa_family != b->sa.sa_family) + return false; + + if (a->sa.sa_family == AF_INET) + return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr; + + if (a->sa.sa_family == AF_INET6) + return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0; + + if (a->sa.sa_family == AF_VSOCK) + return a->vm.svm_cid == b->vm.svm_cid; + + return false; +} + +int fd_set_sndbuf(int fd, size_t n, bool increase) { + int r, value; + socklen_t l = sizeof(value); + + if (n > INT_MAX) + return -ERANGE; + + r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l); + if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2) + return 0; + + /* First, try to set the buffer size with SO_SNDBUF. */ + r = setsockopt_int(fd, SOL_SOCKET, SO_SNDBUF, n); + if (r < 0) + return r; + + /* SO_SNDBUF above may set to the kernel limit, instead of the requested size. + * So, we need to check the actual buffer size here. */ + l = sizeof(value); + r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l); + if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2) + return 1; + + /* If we have the privileges we will ignore the kernel limit. */ + r = setsockopt_int(fd, SOL_SOCKET, SO_SNDBUFFORCE, n); + if (r < 0) + return r; + + return 1; +} + +int fd_set_rcvbuf(int fd, size_t n, bool increase) { + int r, value; + socklen_t l = sizeof(value); + + if (n > INT_MAX) + return -ERANGE; + + r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l); + if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2) + return 0; + + /* First, try to set the buffer size with SO_RCVBUF. */ + r = setsockopt_int(fd, SOL_SOCKET, SO_RCVBUF, n); + if (r < 0) + return r; + + /* SO_RCVBUF above may set to the kernel limit, instead of the requested size. + * So, we need to check the actual buffer size here. */ + l = sizeof(value); + r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l); + if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2) + return 1; + + /* If we have the privileges we will ignore the kernel limit. */ + r = setsockopt_int(fd, SOL_SOCKET, SO_RCVBUFFORCE, n); + if (r < 0) + return r; + + return 1; +} + +static const char* const ip_tos_table[] = { + [IPTOS_LOWDELAY] = "low-delay", + [IPTOS_THROUGHPUT] = "throughput", + [IPTOS_RELIABILITY] = "reliability", + [IPTOS_LOWCOST] = "low-cost", +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff); + +bool ifname_valid_full(const char *p, IfnameValidFlags flags) { + bool numeric = true; + + /* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources + * but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We + * also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */ + + assert(!(flags & ~_IFNAME_VALID_ALL)); + + if (isempty(p)) + return false; + + if (flags & IFNAME_VALID_ALTERNATIVE) { + if (strlen(p) >= ALTIFNAMSIZ) + return false; + } else { + if (strlen(p) >= IFNAMSIZ) + return false; + } + + if (dot_or_dot_dot(p)) + return false; + + for (const char *t = p; *t; t++) { + if ((unsigned char) *t >= 127U) + return false; + + if ((unsigned char) *t <= 32U) + return false; + + if (IN_SET(*t, ':', '/')) + return false; + + numeric = numeric && (*t >= '0' && *t <= '9'); + } + + if (numeric) { + if (!(flags & IFNAME_VALID_NUMERIC)) + return false; + + /* Verify that the number is well-formatted and in range. */ + if (parse_ifindex(p) < 0) + return false; + } + + return true; +} + +bool address_label_valid(const char *p) { + + if (isempty(p)) + return false; + + if (strlen(p) >= IFNAMSIZ) + return false; + + while (*p) { + if ((uint8_t) *p >= 127U) + return false; + + if ((uint8_t) *p <= 31U) + return false; + p++; + } + + return true; +} + +int getpeercred(int fd, struct ucred *ucred) { + socklen_t n = sizeof(struct ucred); + struct ucred u; + int r; + + assert(fd >= 0); + assert(ucred); + + r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n); + if (r < 0) + return -errno; + + if (n != sizeof(struct ucred)) + return -EIO; + + /* Check if the data is actually useful and not suppressed due to namespacing issues */ + if (!pid_is_valid(u.pid)) + return -ENODATA; + + /* Note that we don't check UID/GID here, as namespace translation works differently there: instead of + * receiving in "invalid" user/group we get the overflow UID/GID. */ + + *ucred = u; + return 0; +} + +int getpeersec(int fd, char **ret) { + _cleanup_free_ char *s = NULL; + socklen_t n = 64; + + assert(fd >= 0); + assert(ret); + + for (;;) { + s = new0(char, n+1); + if (!s) + return -ENOMEM; + + if (getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n) >= 0) + break; + + if (errno != ERANGE) + return -errno; + + s = mfree(s); + } + + if (isempty(s)) + return -EOPNOTSUPP; + + *ret = TAKE_PTR(s); + + return 0; +} + +int getpeergroups(int fd, gid_t **ret) { + socklen_t n = sizeof(gid_t) * 64; + _cleanup_free_ gid_t *d = NULL; + + assert(fd >= 0); + assert(ret); + + for (;;) { + d = malloc(n); + if (!d) + return -ENOMEM; + + if (getsockopt(fd, SOL_SOCKET, SO_PEERGROUPS, d, &n) >= 0) + break; + + if (errno != ERANGE) + return -errno; + + d = mfree(d); + } + + assert_se(n % sizeof(gid_t) == 0); + n /= sizeof(gid_t); + + if ((socklen_t) (int) n != n) + return -E2BIG; + + *ret = TAKE_PTR(d); + + return (int) n; +} + +ssize_t send_one_fd_iov_sa( + int transport_fd, + int fd, + struct iovec *iov, size_t iovlen, + const struct sockaddr *sa, socklen_t len, + int flags) { + + CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control = {}; + struct msghdr mh = { + .msg_name = (struct sockaddr*) sa, + .msg_namelen = len, + .msg_iov = iov, + .msg_iovlen = iovlen, + }; + ssize_t k; + + assert(transport_fd >= 0); + + /* + * We need either an FD or data to send. + * If there's nothing, return an error. + */ + if (fd < 0 && !iov) + return -EINVAL; + + if (fd >= 0) { + struct cmsghdr *cmsg; + + mh.msg_control = &control; + mh.msg_controllen = sizeof(control); + + cmsg = CMSG_FIRSTHDR(&mh); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); + } + k = sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags); + if (k < 0) + return (ssize_t) -errno; + + return k; +} + +int send_one_fd_sa( + int transport_fd, + int fd, + const struct sockaddr *sa, socklen_t len, + int flags) { + + assert(fd >= 0); + + return (int) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, sa, len, flags); +} + +ssize_t receive_one_fd_iov( + int transport_fd, + struct iovec *iov, size_t iovlen, + int flags, + int *ret_fd) { + + CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control; + struct msghdr mh = { + .msg_control = &control, + .msg_controllen = sizeof(control), + .msg_iov = iov, + .msg_iovlen = iovlen, + }; + struct cmsghdr *found; + ssize_t k; + + assert(transport_fd >= 0); + assert(ret_fd); + + /* + * Receive a single FD via @transport_fd. We don't care for + * the transport-type. We retrieve a single FD at most, so for + * packet-based transports, the caller must ensure to send + * only a single FD per packet. This is best used in + * combination with send_one_fd(). + */ + + k = recvmsg_safe(transport_fd, &mh, MSG_CMSG_CLOEXEC | flags); + if (k < 0) + return k; + + found = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, CMSG_LEN(sizeof(int))); + if (!found) { + cmsg_close_all(&mh); + + /* If didn't receive an FD or any data, return an error. */ + if (k == 0) + return -EIO; + } + + if (found) + *ret_fd = *(int*) CMSG_DATA(found); + else + *ret_fd = -1; + + return k; +} + +int receive_one_fd(int transport_fd, int flags) { + int fd; + ssize_t k; + + k = receive_one_fd_iov(transport_fd, NULL, 0, flags, &fd); + if (k == 0) + return fd; + + /* k must be negative, since receive_one_fd_iov() only returns + * a positive value if data was received through the iov. */ + assert(k < 0); + return (int) k; +} +#endif /* NM_IGNORED */ + +ssize_t next_datagram_size_fd(int fd) { + ssize_t l; + int k; + + /* This is a bit like FIONREAD/SIOCINQ, however a bit more powerful. The difference being: recv(MSG_PEEK) will + * actually cause the next datagram in the queue to be validated regarding checksums, which FIONREAD doesn't + * do. This difference is actually of major importance as we need to be sure that the size returned here + * actually matches what we will read with recvmsg() next, as otherwise we might end up allocating a buffer of + * the wrong size. */ + + l = recv(fd, NULL, 0, MSG_PEEK|MSG_TRUNC); + if (l < 0) { + if (IN_SET(errno, EOPNOTSUPP, EFAULT)) + goto fallback; + + return -errno; + } + if (l == 0) + goto fallback; + + return l; + +fallback: + k = 0; + + /* Some sockets (AF_PACKET) do not support null-sized recv() with MSG_TRUNC set, let's fall back to FIONREAD + * for them. Checksums don't matter for raw sockets anyway, hence this should be fine. */ + + if (ioctl(fd, FIONREAD, &k) < 0) + return -errno; + + return (ssize_t) k; +} + +#if 0 /* NM_IGNORED */ +/* Put a limit on how many times will attempt to call accept4(). We loop + * only on "transient" errors, but let's make sure we don't loop forever. */ +#define MAX_FLUSH_ITERATIONS 1024 + +int flush_accept(int fd) { + + int r, b; + socklen_t l = sizeof(b); + + /* Similar to flush_fd() but flushes all incoming connections by accepting and immediately closing + * them. */ + + if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &b, &l) < 0) + return -errno; + + assert(l == sizeof(b)); + if (!b) /* Let's check if this socket accepts connections before calling accept(). accept4() can + * return EOPNOTSUPP if the fd is not a listening socket, which we should treat as a fatal + * error, or in case the incoming TCP connection triggered a network issue, which we want to + * treat as a transient error. Thus, let's rule out the first reason for EOPNOTSUPP early, so + * we can loop safely on transient errors below. */ + return -ENOTTY; + + for (unsigned iteration = 0;; iteration++) { + int cfd; + + r = fd_wait_for_event(fd, POLLIN, 0); + if (r < 0) { + if (r == -EINTR) + continue; + + return r; + } + if (r == 0) + return 0; + + if (iteration >= MAX_FLUSH_ITERATIONS) + return log_debug_errno(SYNTHETIC_ERRNO(EBUSY), + "Failed to flush connections within " STRINGIFY(MAX_FLUSH_ITERATIONS) " iterations."); + + cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); + if (cfd < 0) { + if (errno == EAGAIN) + return 0; + + if (ERRNO_IS_ACCEPT_AGAIN(errno)) + continue; + + return -errno; + } + + safe_close(cfd); + } +} +#endif /* NM_IGNORED */ + +struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length) { + struct cmsghdr *cmsg; + + assert(mh); + + CMSG_FOREACH(cmsg, mh) + if (cmsg->cmsg_level == level && + cmsg->cmsg_type == type && + (length == (socklen_t) -1 || length == cmsg->cmsg_len)) + return cmsg; + + return NULL; +} + +#if 0 /* NM_IGNORED */ +int socket_ioctl_fd(void) { + int fd; + + /* Create a socket to invoke the various network interface ioctl()s on. Traditionally only AF_INET was good for + * that. Since kernel 4.6 AF_NETLINK works for this too. We first try to use AF_INET hence, but if that's not + * available (for example, because it is made unavailable via SECCOMP or such), we'll fall back to the more + * generic AF_NETLINK. */ + + fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0); + if (fd < 0) + fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_GENERIC); + if (fd < 0) + return -errno; + + return fd; +} + +int sockaddr_un_unlink(const struct sockaddr_un *sa) { + const char *p, * nul; + + assert(sa); + + if (sa->sun_family != AF_UNIX) + return -EPROTOTYPE; + + if (sa->sun_path[0] == 0) /* Nothing to do for abstract sockets */ + return 0; + + /* The path in .sun_path is not necessarily NUL terminated. Let's fix that. */ + nul = memchr(sa->sun_path, 0, sizeof(sa->sun_path)); + if (nul) + p = sa->sun_path; + else + p = memdupa_suffix0(sa->sun_path, sizeof(sa->sun_path)); + + if (unlink(p) < 0) + return -errno; + + return 1; +} +#endif /* NM_IGNORED */ + +int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path) { + size_t l; + + assert(ret); + assert(path); + + /* Initialize ret->sun_path from the specified argument. This will interpret paths starting with '@' as + * abstract namespace sockets, and those starting with '/' as regular filesystem sockets. It won't accept + * anything else (i.e. no relative paths), to avoid ambiguities. Note that this function cannot be used to + * reference paths in the abstract namespace that include NUL bytes in the name. */ + + l = strlen(path); + if (l < 2) + return -EINVAL; + if (!IN_SET(path[0], '/', '@')) + return -EINVAL; + + /* Don't allow paths larger than the space in sockaddr_un. Note that we are a tiny bit more restrictive than + * the kernel is: we insist on NUL termination (both for abstract namespace and regular file system socket + * addresses!), which the kernel doesn't. We do this to reduce chance of incompatibility with other apps that + * do not expect non-NUL terminated file system path*/ + if (l+1 > sizeof(ret->sun_path)) + return -EINVAL; + + *ret = (struct sockaddr_un) { + .sun_family = AF_UNIX, + }; + + if (path[0] == '@') { + /* Abstract namespace socket */ + memcpy(ret->sun_path + 1, path + 1, l); /* copy *with* trailing NUL byte */ + return (int) (offsetof(struct sockaddr_un, sun_path) + l); /* 🔥 *don't* 🔥 include trailing NUL in size */ + + } else { + assert(path[0] == '/'); + + /* File system socket */ + memcpy(ret->sun_path, path, l + 1); /* copy *with* trailing NUL byte */ + return (int) (offsetof(struct sockaddr_un, sun_path) + l + 1); /* include trailing NUL in size */ + } +} + +int socket_bind_to_ifname(int fd, const char *ifname) { + assert(fd >= 0); + + /* Call with NULL to drop binding */ + + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen_ptr(ifname)) < 0) + return -errno; + + return 0; +} + +int socket_bind_to_ifindex(int fd, int ifindex) { + char ifname[IF_NAMESIZE + 1]; + int r; + + assert(fd >= 0); + + if (ifindex <= 0) { + /* Drop binding */ + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, NULL, 0) < 0) + return -errno; + + return 0; + } + + r = setsockopt_int(fd, SOL_SOCKET, SO_BINDTOIFINDEX, ifindex); + if (r != -ENOPROTOOPT) + return r; + + /* Fall back to SO_BINDTODEVICE on kernels < 5.0 which didn't have SO_BINDTOIFINDEX */ + if (!format_ifname(ifindex, ifname)) + return -errno; + + return socket_bind_to_ifname(fd, ifname); +} + +ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags) { + ssize_t n; + + /* A wrapper around recvmsg() that checks for MSG_CTRUNC, and turns it into an error, in a reasonably + * safe way, closing any SCM_RIGHTS fds in the error path. + * + * Note that unlike our usual coding style this might modify *msg on failure. */ + + n = recvmsg(sockfd, msg, flags); + if (n < 0) + return -errno; + + if (FLAGS_SET(msg->msg_flags, MSG_CTRUNC)) { + cmsg_close_all(msg); + return -EXFULL; /* a recognizable error code */ + } + + return n; +} + +#if 0 /* NM_IGNORED */ +int socket_get_family(int fd, int *ret) { + int af; + socklen_t sl = sizeof(af); + + if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &af, &sl) < 0) + return -errno; + + if (sl != sizeof(af)) + return -EINVAL; + + return af; +} + +int socket_set_recvpktinfo(int fd, int af, bool b) { + int r; + + if (af == AF_UNSPEC) { + r = socket_get_family(fd, &af); + if (r < 0) + return r; + } + + switch (af) { + + case AF_INET: + return setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, b); + + case AF_INET6: + return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, b); + + case AF_NETLINK: + return setsockopt_int(fd, SOL_NETLINK, NETLINK_PKTINFO, b); + + case AF_PACKET: + return setsockopt_int(fd, SOL_PACKET, PACKET_AUXDATA, b); + + default: + return -EAFNOSUPPORT; + } +} + +int socket_set_unicast_if(int fd, int af, int ifi) { + be32_t ifindex_be = htobe32(ifi); + int r; + + if (af == AF_UNSPEC) { + r = socket_get_family(fd, &af); + if (r < 0) + return r; + } + + switch (af) { + + case AF_INET: + if (setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex_be, sizeof(ifindex_be)) < 0) + return -errno; + + return 0; + + case AF_INET6: + if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex_be, sizeof(ifindex_be)) < 0) + return -errno; + + return 0; + + default: + return -EAFNOSUPPORT; + } +} + +int socket_set_option(int fd, int af, int opt_ipv4, int opt_ipv6, int val) { + int r; + + if (af == AF_UNSPEC) { + r = socket_get_family(fd, &af); + if (r < 0) + return r; + } + + switch (af) { + + case AF_INET: + return setsockopt_int(fd, IPPROTO_IP, opt_ipv4, val); + + case AF_INET6: + return setsockopt_int(fd, IPPROTO_IPV6, opt_ipv6, val); + + default: + return -EAFNOSUPPORT; + } +} + +int socket_get_mtu(int fd, int af, size_t *ret) { + int mtu, r; + + if (af == AF_UNSPEC) { + r = socket_get_family(fd, &af); + if (r < 0) + return r; + } + + switch (af) { + + case AF_INET: + r = getsockopt_int(fd, IPPROTO_IP, IP_MTU, &mtu); + break; + + case AF_INET6: + r = getsockopt_int(fd, IPPROTO_IPV6, IPV6_MTU, &mtu); + break; + + default: + return -EAFNOSUPPORT; + } + + if (r < 0) + return r; + if (mtu <= 0) + return -EINVAL; + + *ret = (size_t) mtu; + return 0; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/socket-util.h b/src/libnm-systemd-shared/src/basic/socket-util.h new file mode 100644 index 0000000..1de0694 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/socket-util.h @@ -0,0 +1,307 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "missing_network.h" +#include "missing_socket.h" +#include "sparse-endian.h" + +union sockaddr_union { + /* The minimal, abstract version */ + struct sockaddr sa; + + /* The libc provided version that allocates "enough room" for every protocol */ + struct sockaddr_storage storage; + + /* Protoctol-specific implementations */ + struct sockaddr_in in; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_nl nl; + struct sockaddr_ll ll; +#if 0 /* NM_IGNORED */ + struct sockaddr_vm vm; +#endif /* NM_IGNORED */ + + /* Ensure there is enough space to store Infiniband addresses */ + uint8_t ll_buffer[offsetof(struct sockaddr_ll, sll_addr) + CONST_MAX(ETH_ALEN, INFINIBAND_ALEN)]; + + /* Ensure there is enough space after the AF_UNIX sun_path for one more NUL byte, just to be sure that the path + * component is always followed by at least one NUL byte. */ + uint8_t un_buffer[sizeof(struct sockaddr_un) + 1]; +}; + +#define SUN_PATH_LEN (sizeof(((struct sockaddr_un){}).sun_path)) + +typedef struct SocketAddress { + union sockaddr_union sockaddr; + + /* We store the size here explicitly due to the weird + * sockaddr_un semantics for abstract sockets */ + socklen_t size; + + /* Socket type, i.e. SOCK_STREAM, SOCK_DGRAM, ... */ + int type; + + /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */ + int protocol; +} SocketAddress; + +typedef enum SocketAddressBindIPv6Only { + SOCKET_ADDRESS_DEFAULT, + SOCKET_ADDRESS_BOTH, + SOCKET_ADDRESS_IPV6_ONLY, + _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX, + _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -1 +} SocketAddressBindIPv6Only; + +#define socket_address_family(a) ((a)->sockaddr.sa.sa_family) + +const char* socket_address_type_to_string(int t) _const_; +int socket_address_type_from_string(const char *s) _pure_; + +int sockaddr_un_unlink(const struct sockaddr_un *sa); + +static inline int socket_address_unlink(const SocketAddress *a) { + return socket_address_family(a) == AF_UNIX ? sockaddr_un_unlink(&a->sockaddr.un) : 0; +} + +bool socket_address_can_accept(const SocketAddress *a) _pure_; + +int socket_address_listen( + const SocketAddress *a, + int flags, + int backlog, + SocketAddressBindIPv6Only only, + const char *bind_to_device, + bool reuse_port, + bool free_bind, + bool transparent, + mode_t directory_mode, + mode_t socket_mode, + const char *label); + +int socket_address_verify(const SocketAddress *a, bool strict) _pure_; +int socket_address_print(const SocketAddress *a, char **p); +bool socket_address_matches_fd(const SocketAddress *a, int fd); + +bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_; + +const char* socket_address_get_path(const SocketAddress *a); + +bool socket_ipv6_is_supported(void); + +int sockaddr_port(const struct sockaddr *_sa, unsigned *port); +const union in_addr_union *sockaddr_in_addr(const struct sockaddr *sa); + +int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret); +int getpeername_pretty(int fd, bool include_port, char **ret); +int getsockname_pretty(int fd, char **ret); + +int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret); + +const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_; +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_; +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *s); + +int netlink_family_to_string_alloc(int b, char **s); +int netlink_family_from_string(const char *s) _pure_; + +bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b); + +int fd_set_sndbuf(int fd, size_t n, bool increase); +static inline int fd_inc_sndbuf(int fd, size_t n) { + return fd_set_sndbuf(fd, n, true); +} +int fd_set_rcvbuf(int fd, size_t n, bool increase); +static inline int fd_inc_rcvbuf(int fd, size_t n) { + return fd_set_rcvbuf(fd, n, true); +} + +int ip_tos_to_string_alloc(int i, char **s); +int ip_tos_from_string(const char *s); + +typedef enum { + IFNAME_VALID_ALTERNATIVE = 1 << 0, + IFNAME_VALID_NUMERIC = 1 << 1, + _IFNAME_VALID_ALL = IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC, +} IfnameValidFlags; +bool ifname_valid_full(const char *p, IfnameValidFlags flags); +static inline bool ifname_valid(const char *p) { + return ifname_valid_full(p, 0); +} +bool address_label_valid(const char *p); + +int getpeercred(int fd, struct ucred *ucred); +int getpeersec(int fd, char **ret); +int getpeergroups(int fd, gid_t **ret); + +ssize_t send_one_fd_iov_sa( + int transport_fd, + int fd, + struct iovec *iov, size_t iovlen, + const struct sockaddr *sa, socklen_t len, + int flags); +int send_one_fd_sa(int transport_fd, + int fd, + const struct sockaddr *sa, socklen_t len, + int flags); +#define send_one_fd_iov(transport_fd, fd, iov, iovlen, flags) send_one_fd_iov_sa(transport_fd, fd, iov, iovlen, NULL, 0, flags) +#define send_one_fd(transport_fd, fd, flags) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, NULL, 0, flags) +ssize_t receive_one_fd_iov(int transport_fd, struct iovec *iov, size_t iovlen, int flags, int *ret_fd); +int receive_one_fd(int transport_fd, int flags); + +ssize_t next_datagram_size_fd(int fd); + +int flush_accept(int fd); + +#define CMSG_FOREACH(cmsg, mh) \ + for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg))) + +struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length); + +/* Type-safe, dereferencing version of cmsg_find() */ +#define CMSG_FIND_DATA(mh, level, type, ctype) \ + ({ \ + struct cmsghdr *_found; \ + _found = cmsg_find(mh, level, type, CMSG_LEN(sizeof(ctype))); \ + (ctype*) (_found ? CMSG_DATA(_found) : NULL); \ + }) + +/* Resolves to a type that can carry cmsghdr structures. Make sure things are properly aligned, i.e. the type + * itself is placed properly in memory and the size is also aligned to what's appropriate for "cmsghdr" + * structures. */ +#define CMSG_BUFFER_TYPE(size) \ + union { \ + struct cmsghdr cmsghdr; \ + uint8_t buf[size]; \ + uint8_t align_check[(size) >= CMSG_SPACE(0) && \ + (size) == CMSG_ALIGN(size) ? 1 : -1]; \ + } + +/* + * Certain hardware address types (e.g Infiniband) do not fit into sll_addr + * (8 bytes) and run over the structure. This macro returns the correct size that + * must be passed to kernel. + */ +#define SOCKADDR_LL_LEN(sa) \ + ({ \ + const struct sockaddr_ll *_sa = &(sa); \ + size_t _mac_len = sizeof(_sa->sll_addr); \ + assert(_sa->sll_family == AF_PACKET); \ + if (be16toh(_sa->sll_hatype) == ARPHRD_ETHER) \ + _mac_len = MAX(_mac_len, (size_t) ETH_ALEN); \ + if (be16toh(_sa->sll_hatype) == ARPHRD_INFINIBAND) \ + _mac_len = MAX(_mac_len, (size_t) INFINIBAND_ALEN); \ + offsetof(struct sockaddr_ll, sll_addr) + _mac_len; \ + }) + +/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */ +#define SOCKADDR_UN_LEN(sa) \ + ({ \ + const struct sockaddr_un *_sa = &(sa); \ + assert(_sa->sun_family == AF_UNIX); \ + offsetof(struct sockaddr_un, sun_path) + \ + (_sa->sun_path[0] == 0 ? \ + 1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \ + strnlen(_sa->sun_path, sizeof(_sa->sun_path))+1); \ + }) + +#define SOCKADDR_LEN(sa) \ + ({ \ + const union sockaddr_union *__sa = &(sa); \ + size_t _len; \ + switch(__sa->sa.sa_family) { \ + case AF_INET: \ + _len = sizeof(struct sockaddr_in); \ + break; \ + case AF_INET6: \ + _len = sizeof(struct sockaddr_in6); \ + break; \ + case AF_UNIX: \ + _len = SOCKADDR_UN_LEN(__sa->un); \ + break; \ + case AF_PACKET: \ + _len = SOCKADDR_LL_LEN(__sa->ll); \ + break; \ + case AF_NETLINK: \ + _len = sizeof(struct sockaddr_nl); \ + break; \ + case AF_VSOCK: \ + _len = sizeof(struct sockaddr_vm); \ + break; \ + default: \ + assert_not_reached("invalid socket family"); \ + } \ + _len; \ + }) + +int socket_ioctl_fd(void); + +int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path); + +static inline int setsockopt_int(int fd, int level, int optname, int value) { + if (setsockopt(fd, level, optname, &value, sizeof(value)) < 0) + return -errno; + + return 0; +} + +static inline int getsockopt_int(int fd, int level, int optname, int *ret) { + int v; + socklen_t sl = sizeof(v); + + if (getsockopt(fd, level, optname, &v, &sl) < 0) + return -errno; + if (sl != sizeof(v)) + return -EIO; + + *ret = v; + return 0; +} + +int socket_bind_to_ifname(int fd, const char *ifname); +int socket_bind_to_ifindex(int fd, int ifindex); + +ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags); + +int socket_get_family(int fd, int *ret); +int socket_set_recvpktinfo(int fd, int af, bool b); +int socket_set_unicast_if(int fd, int af, int ifi); + +int socket_set_option(int fd, int af, int opt_ipv4, int opt_ipv6, int val); +#if 0 /* NM_IGNORED */ +static inline int socket_set_recverr(int fd, int af, bool b) { + return socket_set_option(fd, af, IP_RECVERR, IPV6_RECVERR, b); +} +static inline int socket_set_recvttl(int fd, int af, bool b) { + return socket_set_option(fd, af, IP_RECVTTL, IPV6_RECVHOPLIMIT, b); +} +static inline int socket_set_ttl(int fd, int af, int ttl) { + return socket_set_option(fd, af, IP_TTL, IPV6_UNICAST_HOPS, ttl); +} +static inline int socket_set_freebind(int fd, int af, bool b) { + return socket_set_option(fd, af, IP_FREEBIND, IPV6_FREEBIND, b); +} +static inline int socket_set_transparent(int fd, int af, bool b) { + return socket_set_option(fd, af, IP_TRANSPARENT, IPV6_TRANSPARENT, b); +} +static inline int socket_set_recvfragsize(int fd, int af, bool b) { + return socket_set_option(fd, af, IP_RECVFRAGSIZE, IPV6_RECVFRAGSIZE, b); +} +#endif /* NM_IGNORED */ + +int socket_get_mtu(int fd, int af, size_t *ret); diff --git a/src/libnm-systemd-shared/src/basic/sort-util.h b/src/libnm-systemd-shared/src/basic/sort-util.h new file mode 100644 index 0000000..a8984fc --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/sort-util.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#include "macro.h" + +void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, + __compar_d_fn_t compar, void *arg); + +#define typesafe_bsearch_r(k, b, n, func, userdata) \ + ({ \ + const typeof(b[0]) *_k = k; \ + int (*_func_)(const typeof(b[0])*, const typeof(b[0])*, typeof(userdata)) = func; \ + xbsearch_r((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_d_fn_t) _func_, userdata); \ + }) + +/** + * Normal bsearch requires base to be nonnull. Here were require + * that only if nmemb > 0. + */ +static inline void* bsearch_safe(const void *key, const void *base, + size_t nmemb, size_t size, __compar_fn_t compar) { + if (nmemb <= 0) + return NULL; + + assert(base); + return bsearch(key, base, nmemb, size, compar); +} + +#define typesafe_bsearch(k, b, n, func) \ + ({ \ + const typeof(b[0]) *_k = k; \ + int (*_func_)(const typeof(b[0])*, const typeof(b[0])*) = func; \ + bsearch_safe((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_fn_t) _func_); \ + }) + +/** + * Normal qsort requires base to be nonnull. Here were require + * that only if nmemb > 0. + */ +static inline void _qsort_safe(void *base, size_t nmemb, size_t size, __compar_fn_t compar) { + if (nmemb <= 1) + return; + + assert(base); + qsort(base, nmemb, size, compar); +} + +/* A wrapper around the above, but that adds typesafety: the element size is automatically derived from the type and so + * is the prototype for the comparison function */ +#define typesafe_qsort(p, n, func) \ + ({ \ + int (*_func_)(const typeof(p[0])*, const typeof(p[0])*) = func; \ + _qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_); \ + }) + +#if 0 /* NM_IGNORED */ +static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, __compar_d_fn_t compar, void *userdata) { + if (nmemb <= 1) + return; + + assert(base); + qsort_r(base, nmemb, size, compar, userdata); +} + +#define typesafe_qsort_r(p, n, func, userdata) \ + ({ \ + int (*_func_)(const typeof(p[0])*, const typeof(p[0])*, typeof(userdata)) = func; \ + qsort_r_safe((p), (n), sizeof((p)[0]), (__compar_d_fn_t) _func_, userdata); \ + }) +#endif /* NM_IGNORED */ + +int cmp_int(const int *a, const int *b); diff --git a/src/libnm-systemd-shared/src/basic/sparse-endian.h b/src/libnm-systemd-shared/src/basic/sparse-endian.h new file mode 100644 index 0000000..9583dda --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/sparse-endian.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2012 Josh Triplett + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#pragma once + +#include +#include +#include + +#ifdef __CHECKER__ +#define __sd_bitwise __attribute__((__bitwise__)) +#define __sd_force __attribute__((__force__)) +#else +#define __sd_bitwise +#define __sd_force +#endif + +typedef uint16_t __sd_bitwise le16_t; +typedef uint16_t __sd_bitwise be16_t; +typedef uint32_t __sd_bitwise le32_t; +typedef uint32_t __sd_bitwise be32_t; +typedef uint64_t __sd_bitwise le64_t; +typedef uint64_t __sd_bitwise be64_t; + +#undef htobe16 +#undef htole16 +#undef be16toh +#undef le16toh +#undef htobe32 +#undef htole32 +#undef be32toh +#undef le32toh +#undef htobe64 +#undef htole64 +#undef be64toh +#undef le64toh + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define bswap_16_on_le(x) __bswap_16(x) +#define bswap_32_on_le(x) __bswap_32(x) +#define bswap_64_on_le(x) __bswap_64(x) +#define bswap_16_on_be(x) (x) +#define bswap_32_on_be(x) (x) +#define bswap_64_on_be(x) (x) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define bswap_16_on_le(x) (x) +#define bswap_32_on_le(x) (x) +#define bswap_64_on_le(x) (x) +#define bswap_16_on_be(x) __bswap_16(x) +#define bswap_32_on_be(x) __bswap_32(x) +#define bswap_64_on_be(x) __bswap_64(x) +#endif + +static inline le16_t htole16(uint16_t value) { return (le16_t __sd_force) bswap_16_on_be(value); } +static inline le32_t htole32(uint32_t value) { return (le32_t __sd_force) bswap_32_on_be(value); } +static inline le64_t htole64(uint64_t value) { return (le64_t __sd_force) bswap_64_on_be(value); } + +static inline be16_t htobe16(uint16_t value) { return (be16_t __sd_force) bswap_16_on_le(value); } +static inline be32_t htobe32(uint32_t value) { return (be32_t __sd_force) bswap_32_on_le(value); } +static inline be64_t htobe64(uint64_t value) { return (be64_t __sd_force) bswap_64_on_le(value); } + +static inline uint16_t le16toh(le16_t value) { return bswap_16_on_be((uint16_t __sd_force)value); } +static inline uint32_t le32toh(le32_t value) { return bswap_32_on_be((uint32_t __sd_force)value); } +static inline uint64_t le64toh(le64_t value) { return bswap_64_on_be((uint64_t __sd_force)value); } + +static inline uint16_t be16toh(be16_t value) { return bswap_16_on_le((uint16_t __sd_force)value); } +static inline uint32_t be32toh(be32_t value) { return bswap_32_on_le((uint32_t __sd_force)value); } +static inline uint64_t be64toh(be64_t value) { return bswap_64_on_le((uint64_t __sd_force)value); } + +#undef __sd_bitwise +#undef __sd_force diff --git a/src/libnm-systemd-shared/src/basic/stat-util.c b/src/libnm-systemd-shared/src/basic/stat-util.c new file mode 100644 index 0000000..a988009 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/stat-util.c @@ -0,0 +1,480 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "dirent-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" +#include "macro.h" +#include "missing_fs.h" +#include "missing_magic.h" +#include "missing_syscall.h" +#include "parse-util.h" +#include "stat-util.h" +#include "string-util.h" + +#if 0 /* NM_IGNORED */ +int is_symlink(const char *path) { + struct stat info; + + assert(path); + + if (lstat(path, &info) < 0) + return -errno; + + return !!S_ISLNK(info.st_mode); +} +#endif /* NM_IGNORED */ + +int is_dir(const char* path, bool follow) { + struct stat st; + int r; + + assert(path); + + if (follow) + r = stat(path, &st); + else + r = lstat(path, &st); + if (r < 0) + return -errno; + + return !!S_ISDIR(st.st_mode); +} + +#if 0 /* NM_IGNORED */ +int is_dir_fd(int fd) { + struct stat st; + + if (fstat(fd, &st) < 0) + return -errno; + + return !!S_ISDIR(st.st_mode); +} + +int is_device_node(const char *path) { + struct stat info; + + assert(path); + + if (lstat(path, &info) < 0) + return -errno; + + return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode)); +} + +int dir_is_empty_at(int dir_fd, const char *path) { + _cleanup_close_ int fd = -1; + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + + if (path) + fd = openat(dir_fd, path, O_RDONLY|O_DIRECTORY|O_CLOEXEC); + else + fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); + if (fd < 0) + return -errno; + + d = take_fdopendir(&fd); + if (!d) + return -errno; + + FOREACH_DIRENT(de, d, return -errno) + return 0; + + return 1; +} + +bool null_or_empty(struct stat *st) { + assert(st); + + if (S_ISREG(st->st_mode) && st->st_size <= 0) + return true; + + /* We don't want to hardcode the major/minor of /dev/null, hence we do a simpler "is this a character + * device node?" check. */ + + if (S_ISCHR(st->st_mode)) + return true; + + return false; +} + +int null_or_empty_path(const char *fn) { + struct stat st; + + assert(fn); + + /* If we have the path, let's do an easy text comparison first. */ + if (path_equal(fn, "/dev/null")) + return true; + + if (stat(fn, &st) < 0) + return -errno; + + return null_or_empty(&st); +} + +int null_or_empty_fd(int fd) { + struct stat st; + + assert(fd >= 0); + + if (fstat(fd, &st) < 0) + return -errno; + + return null_or_empty(&st); +} + +int path_is_read_only_fs(const char *path) { + struct statvfs st; + + assert(path); + + if (statvfs(path, &st) < 0) + return -errno; + + if (st.f_flag & ST_RDONLY) + return true; + + /* On NFS, statvfs() might not reflect whether we can actually + * write to the remote share. Let's try again with + * access(W_OK) which is more reliable, at least sometimes. */ + if (access(path, W_OK) < 0 && errno == EROFS) + return true; + + return false; +} + +int files_same(const char *filea, const char *fileb, int flags) { + struct stat a, b; + + assert(filea); + assert(fileb); + + if (fstatat(AT_FDCWD, filea, &a, flags) < 0) + return -errno; + + if (fstatat(AT_FDCWD, fileb, &b, flags) < 0) + return -errno; + + return a.st_dev == b.st_dev && + a.st_ino == b.st_ino; +} + +bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) { + assert(s); + assert_cc(sizeof(statfs_f_type_t) >= sizeof(s->f_type)); + + return F_TYPE_EQUAL(s->f_type, magic_value); +} + +int fd_is_fs_type(int fd, statfs_f_type_t magic_value) { + struct statfs s; + + if (fstatfs(fd, &s) < 0) + return -errno; + + return is_fs_type(&s, magic_value); +} + +int path_is_fs_type(const char *path, statfs_f_type_t magic_value) { + struct statfs s; + + if (statfs(path, &s) < 0) + return -errno; + + return is_fs_type(&s, magic_value); +} + +bool is_temporary_fs(const struct statfs *s) { + return is_fs_type(s, TMPFS_MAGIC) || + is_fs_type(s, RAMFS_MAGIC); +} + +bool is_network_fs(const struct statfs *s) { + return is_fs_type(s, CIFS_MAGIC_NUMBER) || + is_fs_type(s, CODA_SUPER_MAGIC) || + is_fs_type(s, NCP_SUPER_MAGIC) || + is_fs_type(s, NFS_SUPER_MAGIC) || + is_fs_type(s, SMB_SUPER_MAGIC) || + is_fs_type(s, V9FS_MAGIC) || + is_fs_type(s, AFS_SUPER_MAGIC) || + is_fs_type(s, OCFS2_SUPER_MAGIC); +} + +int fd_is_temporary_fs(int fd) { + struct statfs s; + + if (fstatfs(fd, &s) < 0) + return -errno; + + return is_temporary_fs(&s); +} + +int fd_is_network_fs(int fd) { + struct statfs s; + + if (fstatfs(fd, &s) < 0) + return -errno; + + return is_network_fs(&s); +} + +int path_is_temporary_fs(const char *path) { + struct statfs s; + + if (statfs(path, &s) < 0) + return -errno; + + return is_temporary_fs(&s); +} +#endif /* NM_IGNORED */ + +int stat_verify_regular(const struct stat *st) { + assert(st); + + /* Checks whether the specified stat() structure refers to a regular file. If not returns an appropriate error + * code. */ + + if (S_ISDIR(st->st_mode)) + return -EISDIR; + + if (S_ISLNK(st->st_mode)) + return -ELOOP; + + if (!S_ISREG(st->st_mode)) + return -EBADFD; + + return 0; +} + +int fd_verify_regular(int fd) { + struct stat st; + + assert(fd >= 0); + + if (fstat(fd, &st) < 0) + return -errno; + + return stat_verify_regular(&st); +} + +#if 0 /* NM_IGNORED */ +int stat_verify_directory(const struct stat *st) { + assert(st); + + if (S_ISLNK(st->st_mode)) + return -ELOOP; + + if (!S_ISDIR(st->st_mode)) + return -ENOTDIR; + + return 0; +} + +int fd_verify_directory(int fd) { + struct stat st; + + assert(fd >= 0); + + if (fstat(fd, &st) < 0) + return -errno; + + return stat_verify_directory(&st); +} + +int device_path_make_major_minor(mode_t mode, dev_t devno, char **ret) { + const char *t; + + /* Generates the /dev/{char|block}/MAJOR:MINOR path for a dev_t */ + + if (S_ISCHR(mode)) + t = "char"; + else if (S_ISBLK(mode)) + t = "block"; + else + return -ENODEV; + + if (asprintf(ret, "/dev/%s/%u:%u", t, major(devno), minor(devno)) < 0) + return -ENOMEM; + + return 0; +} + +int device_path_make_canonical(mode_t mode, dev_t devno, char **ret) { + _cleanup_free_ char *p = NULL; + int r; + + /* Finds the canonical path for a device, i.e. resolves the /dev/{char|block}/MAJOR:MINOR path to the end. */ + + assert(ret); + + if (major(devno) == 0 && minor(devno) == 0) { + char *s; + + /* A special hack to make sure our 'inaccessible' device nodes work. They won't have symlinks in + * /dev/block/ and /dev/char/, hence we handle them specially here. */ + + if (S_ISCHR(mode)) + s = strdup("/run/systemd/inaccessible/chr"); + else if (S_ISBLK(mode)) + s = strdup("/run/systemd/inaccessible/blk"); + else + return -ENODEV; + + if (!s) + return -ENOMEM; + + *ret = s; + return 0; + } + + r = device_path_make_major_minor(mode, devno, &p); + if (r < 0) + return r; + + return chase_symlinks(p, NULL, 0, ret, NULL); +} + +int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret_devno) { + mode_t mode; + dev_t devno; + int r; + + /* Tries to extract the major/minor directly from the device path if we can. Handles /dev/block/ and /dev/char/ + * paths, as well out synthetic inaccessible device nodes. Never goes to disk. Returns -ENODEV if the device + * path cannot be parsed like this. */ + + if (path_equal(path, "/run/systemd/inaccessible/chr")) { + mode = S_IFCHR; + devno = makedev(0, 0); + } else if (path_equal(path, "/run/systemd/inaccessible/blk")) { + mode = S_IFBLK; + devno = makedev(0, 0); + } else { + const char *w; + + w = path_startswith(path, "/dev/block/"); + if (w) + mode = S_IFBLK; + else { + w = path_startswith(path, "/dev/char/"); + if (!w) + return -ENODEV; + + mode = S_IFCHR; + } + + r = parse_dev(w, &devno); + if (r < 0) + return r; + } + + if (ret_mode) + *ret_mode = mode; + if (ret_devno) + *ret_devno = devno; + + return 0; +} + +int proc_mounted(void) { + int r; + + /* A quick check of procfs is properly mounted */ + + r = path_is_fs_type("/proc/", PROC_SUPER_MAGIC); + if (r == -ENOENT) /* not mounted at all */ + return false; + + return r; +} + +bool stat_inode_unmodified(const struct stat *a, const struct stat *b) { + + /* Returns if the specified stat structures reference the same, unmodified inode. This check tries to + * be reasonably careful when detecting changes: we check both inode and mtime, to cater for file + * systems where mtimes are fixed to 0 (think: ostree/nixos type installations). We also check file + * size, backing device, inode type and if this refers to a device not the major/minor. + * + * Note that we don't care if file attributes such as ownership or access mode change, this here is + * about contents of the file. The purpose here is to detect file contents changes, and nothing + * else. */ + + return a && b && + (a->st_mode & S_IFMT) != 0 && /* We use the check for .st_mode if the structure was ever initialized */ + ((a->st_mode ^ b->st_mode) & S_IFMT) == 0 && /* same inode type */ + a->st_mtim.tv_sec == b->st_mtim.tv_sec && + a->st_mtim.tv_nsec == b->st_mtim.tv_nsec && + (!S_ISREG(a->st_mode) || a->st_size == b->st_size) && /* if regular file, compare file size */ + a->st_dev == b->st_dev && + a->st_ino == b->st_ino && + (!(S_ISCHR(a->st_mode) || S_ISBLK(a->st_mode)) || a->st_rdev == b->st_rdev); /* if device node, also compare major/minor, because we can */ +} + +int statx_fallback(int dfd, const char *path, int flags, unsigned mask, struct statx *sx) { + static bool avoid_statx = false; + struct stat st; + + if (!avoid_statx) { + if (statx(dfd, path, flags, mask, sx) < 0) { + if (!ERRNO_IS_NOT_SUPPORTED(errno) && errno != EPERM) + return -errno; + + /* If statx() is not supported or if we see EPERM (which might indicate seccomp + * filtering or so), let's do a fallback. Not that on EACCES we'll not fall back, + * since that is likely an indication of fs access issues, which we should + * propagate */ + } else + return 0; + + avoid_statx = true; + } + + /* Only do fallback if fstatat() supports the flag too, or if it's one of the sync flags, which are + * OK to ignore */ + if ((flags & ~(AT_EMPTY_PATH|AT_NO_AUTOMOUNT|AT_SYMLINK_NOFOLLOW| + AT_STATX_SYNC_AS_STAT|AT_STATX_FORCE_SYNC|AT_STATX_DONT_SYNC)) != 0) + return -EOPNOTSUPP; + + if (fstatat(dfd, path, &st, flags & (AT_EMPTY_PATH|AT_NO_AUTOMOUNT|AT_SYMLINK_NOFOLLOW)) < 0) + return -errno; + + *sx = (struct statx) { + .stx_mask = STATX_TYPE|STATX_MODE| + STATX_NLINK|STATX_UID|STATX_GID| + STATX_ATIME|STATX_MTIME|STATX_CTIME| + STATX_INO|STATX_SIZE|STATX_BLOCKS, + .stx_blksize = st.st_blksize, + .stx_nlink = st.st_nlink, + .stx_uid = st.st_uid, + .stx_gid = st.st_gid, + .stx_mode = st.st_mode, + .stx_ino = st.st_ino, + .stx_size = st.st_size, + .stx_blocks = st.st_blocks, + .stx_rdev_major = major(st.st_rdev), + .stx_rdev_minor = minor(st.st_rdev), + .stx_dev_major = major(st.st_dev), + .stx_dev_minor = minor(st.st_dev), + .stx_atime.tv_sec = st.st_atim.tv_sec, + .stx_atime.tv_nsec = st.st_atim.tv_nsec, + .stx_mtime.tv_sec = st.st_mtim.tv_sec, + .stx_mtime.tv_nsec = st.st_mtim.tv_nsec, + .stx_ctime.tv_sec = st.st_ctim.tv_sec, + .stx_ctime.tv_nsec = st.st_ctim.tv_nsec, + }; + + return 0; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/stat-util.h b/src/libnm-systemd-shared/src/basic/stat-util.h new file mode 100644 index 0000000..a566114 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/stat-util.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "missing_stat.h" + +int is_symlink(const char *path); +int is_dir(const char *path, bool follow); +int is_dir_fd(int fd); +int is_device_node(const char *path); + +int dir_is_empty_at(int dir_fd, const char *path); +static inline int dir_is_empty(const char *path) { + return dir_is_empty_at(AT_FDCWD, path); +} + +static inline int dir_is_populated(const char *path) { + int r; + r = dir_is_empty(path); + if (r < 0) + return r; + return !r; +} + +bool null_or_empty(struct stat *st) _pure_; +int null_or_empty_path(const char *fn); +int null_or_empty_fd(int fd); + +int path_is_read_only_fs(const char *path); + +int files_same(const char *filea, const char *fileb, int flags); + +/* The .f_type field of struct statfs is really weird defined on + * different archs. Let's give its type a name. */ +typedef typeof(((struct statfs*)NULL)->f_type) statfs_f_type_t; + +bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) _pure_; +int fd_is_fs_type(int fd, statfs_f_type_t magic_value); +int path_is_fs_type(const char *path, statfs_f_type_t magic_value); + +bool is_temporary_fs(const struct statfs *s) _pure_; +bool is_network_fs(const struct statfs *s) _pure_; + +int fd_is_temporary_fs(int fd); +int fd_is_network_fs(int fd); + +int path_is_temporary_fs(const char *path); + +/* Because statfs.t_type can be int on some architectures, we have to cast + * the const magic to the type, otherwise the compiler warns about + * signed/unsigned comparison, because the magic can be 32 bit unsigned. + */ +#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b) + +int stat_verify_regular(const struct stat *st); +int fd_verify_regular(int fd); + +int stat_verify_directory(const struct stat *st); +int fd_verify_directory(int fd); + +/* glibc and the Linux kernel have different ideas about the major/minor size. These calls will check whether the + * specified major is valid by the Linux kernel's standards, not by glibc's. Linux has 20bits of minor, and 12 bits of + * major space. See MINORBITS in linux/kdev_t.h in the kernel sources. (If you wonder why we define _y here, instead of + * comparing directly >= 0: it's to trick out -Wtype-limits, which would otherwise complain if the type is unsigned, as + * such a test would be pointless in such a case.) */ + +#define DEVICE_MAJOR_VALID(x) \ + ({ \ + typeof(x) _x = (x), _y = 0; \ + _x >= _y && _x < (UINT32_C(1) << 12); \ + \ + }) + +#define DEVICE_MINOR_VALID(x) \ + ({ \ + typeof(x) _x = (x), _y = 0; \ + _x >= _y && _x < (UINT32_C(1) << 20); \ + }) + +int device_path_make_major_minor(mode_t mode, dev_t devno, char **ret); +int device_path_make_canonical(mode_t mode, dev_t devno, char **ret); +int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret_devno); + +int proc_mounted(void); + +bool stat_inode_unmodified(const struct stat *a, const struct stat *b); + +int statx_fallback(int dfd, const char *path, int flags, unsigned mask, struct statx *sx); + +#if HAS_FEATURE_MEMORY_SANITIZER +# warning "Explicitly initializing struct statx, to work around msan limitation. Please remove as soon as msan has been updated to not require this." +# define STRUCT_STATX_DEFINE(var) \ + struct statx var = {} +# define STRUCT_NEW_STATX_DEFINE(var) \ + union { \ + struct statx sx; \ + struct new_statx nsx; \ + } var = {} +#else +# define STRUCT_STATX_DEFINE(var) \ + struct statx var +# define STRUCT_NEW_STATX_DEFINE(var) \ + union { \ + struct statx sx; \ + struct new_statx nsx; \ + } var +#endif diff --git a/src/libnm-systemd-shared/src/basic/stdio-util.h b/src/libnm-systemd-shared/src/basic/stdio-util.h new file mode 100644 index 0000000..d45d3c1 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/stdio-util.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#if 0 /* NM_IGNORED */ +#include +#endif /* NM_IGNORED */ +#include +#include +#include + +#include "macro.h" +#include "memory-util.h" + +#define snprintf_ok(buf, len, fmt, ...) \ + ((size_t) snprintf(buf, len, fmt, __VA_ARGS__) < (len)) + +#define xsprintf(buf, fmt, ...) \ + assert_message_se(snprintf_ok(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__), "xsprintf: " #buf "[] must be big enough") + +#define VA_FORMAT_ADVANCE(format, ap) \ +do { \ + int _argtypes[128]; \ + size_t _i, _k; \ + /* See https://github.com/google/sanitizers/issues/992 */ \ + if (HAS_FEATURE_MEMORY_SANITIZER) \ + zero(_argtypes); \ + _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \ + assert(_k < ELEMENTSOF(_argtypes)); \ + for (_i = 0; _i < _k; _i++) { \ + if (_argtypes[_i] & PA_FLAG_PTR) { \ + (void) va_arg(ap, void*); \ + continue; \ + } \ + \ + switch (_argtypes[_i]) { \ + case PA_INT: \ + case PA_INT|PA_FLAG_SHORT: \ + case PA_CHAR: \ + (void) va_arg(ap, int); \ + break; \ + case PA_INT|PA_FLAG_LONG: \ + (void) va_arg(ap, long int); \ + break; \ + case PA_INT|PA_FLAG_LONG_LONG: \ + (void) va_arg(ap, long long int); \ + break; \ + case PA_WCHAR: \ + (void) va_arg(ap, wchar_t); \ + break; \ + case PA_WSTRING: \ + case PA_STRING: \ + case PA_POINTER: \ + (void) va_arg(ap, void*); \ + break; \ + case PA_FLOAT: \ + case PA_DOUBLE: \ + (void) va_arg(ap, double); \ + break; \ + case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \ + (void) va_arg(ap, long double); \ + break; \ + default: \ + assert_not_reached("Unknown format string argument."); \ + } \ + } \ +} while (false) diff --git a/src/libnm-systemd-shared/src/basic/string-table.c b/src/libnm-systemd-shared/src/basic/string-table.c new file mode 100644 index 0000000..bd8047e --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/string-table.c @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include "string-table.h" +#include "string-util.h" + +ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) { + if (!key) + return -1; + + for (size_t i = 0; i < len; ++i) + if (streq_ptr(table[i], key)) + return (ssize_t) i; + + return -1; +} diff --git a/src/libnm-systemd-shared/src/basic/string-table.h b/src/libnm-systemd-shared/src/basic/string-table.h new file mode 100644 index 0000000..ae4ea14 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/string-table.h @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#pragma once + +#include +#include +#include +#include + +#include "macro.h" +#include "parse-util.h" +#include "string-util.h" + +ssize_t string_table_lookup(const char * const *table, size_t len, const char *key); + +/* For basic lookup tables with strictly enumerated entries */ +#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \ + scope const char *name##_to_string(type i) { \ + if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \ + return NULL; \ + return name##_table[i]; \ + } + +#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) \ + scope type name##_from_string(const char *s) { \ + return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \ + } + +#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \ + scope type name##_from_string(const char *s) { \ + if (!s) \ + return -1; \ + int b = parse_boolean(s); \ + if (b == 0) \ + return (type) 0; \ + if (b > 0) \ + return yes; \ + return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \ + } + +#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,scope) \ + scope int name##_to_string_alloc(type i, char **str) { \ + char *s; \ + if (i < 0 || i > max) \ + return -ERANGE; \ + if (i < (type) ELEMENTSOF(name##_table) && name##_table[i]) { \ + s = strdup(name##_table[i]); \ + if (!s) \ + return -ENOMEM; \ + } else { \ + if (asprintf(&s, "%i", i) < 0) \ + return -ENOMEM; \ + } \ + *str = s; \ + return 0; \ + } + +#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,scope) \ + scope type name##_from_string(const char *s) { \ + unsigned u = 0; \ + type i; \ + if (!s) \ + return (type) -1; \ + i = (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \ + if (i >= 0) \ + return i; \ + if (safe_atou(s, &u) >= 0 && u <= max) \ + return (type) u; \ + return (type) -1; \ + } \ + +#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \ + _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \ + _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope) + +#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope) \ + _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \ + _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) + +#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,) +#define DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static) + +#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,static) + +/* For string conversions where numbers are also acceptable */ +#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \ + _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,) \ + _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,) + +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max) \ + _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,static) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max) \ + _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,static) + +#define DUMP_STRING_TABLE(name,type,max) \ + do { \ + type _k; \ + flockfile(stdout); \ + for (_k = 0; _k < (max); _k++) { \ + const char *_t; \ + _t = name##_to_string(_k); \ + if (!_t) \ + continue; \ + fputs_unlocked(_t, stdout); \ + fputc_unlocked('\n', stdout); \ + } \ + funlockfile(stdout); \ + } while(false) diff --git a/src/libnm-systemd-shared/src/basic/string-util.c b/src/libnm-systemd-shared/src/basic/string-util.c new file mode 100644 index 0000000..744a360 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/string-util.c @@ -0,0 +1,1146 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "escape.h" +#include "extract-word.h" +#include "fileio.h" +#include "gunicode.h" +#include "locale-util.h" +#include "macro.h" +#include "memory-util.h" +#include "string-util.h" +#include "strv.h" +#include "terminal-util.h" +#include "utf8.h" +#include "util.h" + +int strcmp_ptr(const char *a, const char *b) { + /* Like strcmp(), but tries to make sense of NULL pointers */ + + if (a && b) + return strcmp(a, b); + return CMP(a, b); /* Direct comparison of pointers, one of which is NULL */ +} + +int strcasecmp_ptr(const char *a, const char *b) { + /* Like strcasecmp(), but tries to make sense of NULL pointers */ + + if (a && b) + return strcasecmp(a, b); + return CMP(a, b); /* Direct comparison of pointers, one of which is NULL */ +} + +char* endswith(const char *s, const char *postfix) { + size_t sl, pl; + + assert(s); + assert(postfix); + + sl = strlen(s); + pl = strlen(postfix); + + if (pl == 0) + return (char*) s + sl; + + if (sl < pl) + return NULL; + + if (memcmp(s + sl - pl, postfix, pl) != 0) + return NULL; + + return (char*) s + sl - pl; +} + +char* endswith_no_case(const char *s, const char *postfix) { + size_t sl, pl; + + assert(s); + assert(postfix); + + sl = strlen(s); + pl = strlen(postfix); + + if (pl == 0) + return (char*) s + sl; + + if (sl < pl) + return NULL; + + if (strcasecmp(s + sl - pl, postfix) != 0) + return NULL; + + return (char*) s + sl - pl; +} + +char* first_word(const char *s, const char *word) { + size_t sl, wl; + const char *p; + + assert(s); + assert(word); + + /* Checks if the string starts with the specified word, either + * followed by NUL or by whitespace. Returns a pointer to the + * NUL or the first character after the whitespace. */ + + sl = strlen(s); + wl = strlen(word); + + if (sl < wl) + return NULL; + + if (wl == 0) + return (char*) s; + + if (memcmp(s, word, wl) != 0) + return NULL; + + p = s + wl; + if (*p == 0) + return (char*) p; + + if (!strchr(WHITESPACE, *p)) + return NULL; + + p += strspn(p, WHITESPACE); + return (char*) p; +} + +char *strnappend(const char *s, const char *suffix, size_t b) { + size_t a; + char *r; + + if (!s && !suffix) + return strdup(""); + + if (!s) + return strndup(suffix, b); + + if (!suffix) + return strdup(s); + + assert(s); + assert(suffix); + + a = strlen(s); + if (b > ((size_t) -1) - a) + return NULL; + + r = new(char, a+b+1); + if (!r) + return NULL; + + memcpy(r, s, a); + memcpy(r+a, suffix, b); + r[a+b] = 0; + + return r; +} + +char *strjoin_real(const char *x, ...) { + va_list ap; + size_t l = 1; + char *r, *p; + + va_start(ap, x); + for (const char *t = x; t; t = va_arg(ap, const char *)) { + size_t n; + + n = strlen(t); + if (n > SIZE_MAX - l) { + va_end(ap); + return NULL; + } + l += n; + } + va_end(ap); + + p = r = new(char, l); + if (!r) + return NULL; + + va_start(ap, x); + for (const char *t = x; t; t = va_arg(ap, const char *)) + p = stpcpy(p, t); + va_end(ap); + + *p = 0; + + return r; +} + +#if 0 /* NM_IGNORED */ +char *strstrip(char *s) { + if (!s) + return NULL; + + /* Drops trailing whitespace. Modifies the string in place. Returns pointer to first non-space character */ + + return delete_trailing_chars(skip_leading_chars(s, WHITESPACE), WHITESPACE); +} + +char *delete_chars(char *s, const char *bad) { + char *f, *t; + + /* Drops all specified bad characters, regardless where in the string */ + + if (!s) + return NULL; + + if (!bad) + bad = WHITESPACE; + + for (f = s, t = s; *f; f++) { + if (strchr(bad, *f)) + continue; + + *(t++) = *f; + } + + *t = 0; + + return s; +} + +char *delete_trailing_chars(char *s, const char *bad) { + char *p, *c = s; + + /* Drops all specified bad characters, at the end of the string */ + + if (!s) + return NULL; + + if (!bad) + bad = WHITESPACE; + + for (p = s; *p; p++) + if (!strchr(bad, *p)) + c = p + 1; + + *c = 0; + + return s; +} +#endif /* NM_IGNORED */ + +char *truncate_nl(char *s) { + assert(s); + + s[strcspn(s, NEWLINE)] = 0; + return s; +} + +char ascii_tolower(char x) { + + if (x >= 'A' && x <= 'Z') + return x - 'A' + 'a'; + + return x; +} + +char ascii_toupper(char x) { + + if (x >= 'a' && x <= 'z') + return x - 'a' + 'A'; + + return x; +} + +char *ascii_strlower(char *t) { + char *p; + + assert(t); + + for (p = t; *p; p++) + *p = ascii_tolower(*p); + + return t; +} + +char *ascii_strupper(char *t) { + char *p; + + assert(t); + + for (p = t; *p; p++) + *p = ascii_toupper(*p); + + return t; +} + +char *ascii_strlower_n(char *t, size_t n) { + size_t i; + + if (n <= 0) + return t; + + for (i = 0; i < n; i++) + t[i] = ascii_tolower(t[i]); + + return t; +} + +int ascii_strcasecmp_n(const char *a, const char *b, size_t n) { + + for (; n > 0; a++, b++, n--) { + int x, y; + + x = (int) (uint8_t) ascii_tolower(*a); + y = (int) (uint8_t) ascii_tolower(*b); + + if (x != y) + return x - y; + } + + return 0; +} + +int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m) { + int r; + + r = ascii_strcasecmp_n(a, b, MIN(n, m)); + if (r != 0) + return r; + + return CMP(n, m); +} + +bool chars_intersect(const char *a, const char *b) { + const char *p; + + /* Returns true if any of the chars in a are in b. */ + for (p = a; *p; p++) + if (strchr(b, *p)) + return true; + + return false; +} + +bool string_has_cc(const char *p, const char *ok) { + const char *t; + + assert(p); + + /* + * Check if a string contains control characters. If 'ok' is + * non-NULL it may be a string containing additional CCs to be + * considered OK. + */ + + for (t = p; *t; t++) { + if (ok && strchr(ok, *t)) + continue; + + if (*t > 0 && *t < ' ') + return true; + + if (*t == 127) + return true; + } + + return false; +} + +#if 0 /* NM_IGNORED */ +static int write_ellipsis(char *buf, bool unicode) { + if (unicode || is_locale_utf8()) { + buf[0] = 0xe2; /* tri-dot ellipsis: … */ + buf[1] = 0x80; + buf[2] = 0xa6; + } else { + buf[0] = '.'; + buf[1] = '.'; + buf[2] = '.'; + } + + return 3; +} + +static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) { + size_t x, need_space, suffix_len; + char *t; + + assert(s); + assert(percent <= 100); + assert(new_length != (size_t) -1); + + if (old_length <= new_length) + return strndup(s, old_length); + + /* Special case short ellipsations */ + switch (new_length) { + + case 0: + return strdup(""); + + case 1: + if (is_locale_utf8()) + return strdup("…"); + else + return strdup("."); + + case 2: + if (!is_locale_utf8()) + return strdup(".."); + + break; + + default: + break; + } + + /* Calculate how much space the ellipsis will take up. If we are in UTF-8 mode we only need space for one + * character ("…"), otherwise for three characters ("..."). Note that in both cases we need 3 bytes of storage, + * either for the UTF-8 encoded character or for three ASCII characters. */ + need_space = is_locale_utf8() ? 1 : 3; + + t = new(char, new_length+3); + if (!t) + return NULL; + + assert(new_length >= need_space); + + x = ((new_length - need_space) * percent + 50) / 100; + assert(x <= new_length - need_space); + + memcpy(t, s, x); + write_ellipsis(t + x, false); + suffix_len = new_length - x - need_space; + memcpy(t + x + 3, s + old_length - suffix_len, suffix_len); + *(t + x + 3 + suffix_len) = '\0'; + + return t; +} + +char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) { + size_t x, k, len, len2; + const char *i, *j; + char *e; + int r; + + /* Note that 'old_length' refers to bytes in the string, while 'new_length' refers to character cells taken up + * on screen. This distinction doesn't matter for ASCII strings, but it does matter for non-ASCII UTF-8 + * strings. + * + * Ellipsation is done in a locale-dependent way: + * 1. If the string passed in is fully ASCII and the current locale is not UTF-8, three dots are used ("...") + * 2. Otherwise, a unicode ellipsis is used ("…") + * + * In other words: you'll get a unicode ellipsis as soon as either the string contains non-ASCII characters or + * the current locale is UTF-8. + */ + + assert(s); + assert(percent <= 100); + + if (new_length == (size_t) -1) + return strndup(s, old_length); + + if (new_length == 0) + return strdup(""); + + /* If no multibyte characters use ascii_ellipsize_mem for speed */ + if (ascii_is_valid_n(s, old_length)) + return ascii_ellipsize_mem(s, old_length, new_length, percent); + + x = ((new_length - 1) * percent) / 100; + assert(x <= new_length - 1); + + k = 0; + for (i = s; i < s + old_length; i = utf8_next_char(i)) { + char32_t c; + int w; + + r = utf8_encoded_to_unichar(i, &c); + if (r < 0) + return NULL; + + w = unichar_iswide(c) ? 2 : 1; + if (k + w <= x) + k += w; + else + break; + } + + for (j = s + old_length; j > i; ) { + char32_t c; + int w; + const char *jj; + + jj = utf8_prev_char(j); + r = utf8_encoded_to_unichar(jj, &c); + if (r < 0) + return NULL; + + w = unichar_iswide(c) ? 2 : 1; + if (k + w <= new_length) { + k += w; + j = jj; + } else + break; + } + assert(i <= j); + + /* we don't actually need to ellipsize */ + if (i == j) + return memdup_suffix0(s, old_length); + + /* make space for ellipsis, if possible */ + if (j < s + old_length) + j = utf8_next_char(j); + else if (i > s) + i = utf8_prev_char(i); + + len = i - s; + len2 = s + old_length - j; + e = new(char, len + 3 + len2 + 1); + if (!e) + return NULL; + + /* + printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n", + old_length, new_length, x, len, len2, k); + */ + + memcpy(e, s, len); + write_ellipsis(e + len, true); + memcpy(e + len + 3, j, len2); + *(e + len + 3 + len2) = '\0'; + + return e; +} + +char *cellescape(char *buf, size_t len, const char *s) { + /* Escape and ellipsize s into buffer buf of size len. Only non-control ASCII + * characters are copied as they are, everything else is escaped. The result + * is different then if escaping and ellipsization was performed in two + * separate steps, because each sequence is either stored in full or skipped. + * + * This function should be used for logging about strings which expected to + * be plain ASCII in a safe way. + * + * An ellipsis will be used if s is too long. It was always placed at the + * very end. + */ + + size_t i = 0, last_char_width[4] = {}, k = 0, j; + + assert(len > 0); /* at least a terminating NUL */ + + for (;;) { + char four[4]; + int w; + + if (*s == 0) /* terminating NUL detected? then we are done! */ + goto done; + + w = cescape_char(*s, four); + if (i + w + 1 > len) /* This character doesn't fit into the buffer anymore? In that case let's + * ellipsize at the previous location */ + break; + + /* OK, there was space, let's add this escaped character to the buffer */ + memcpy(buf + i, four, w); + i += w; + + /* And remember its width in the ring buffer */ + last_char_width[k] = w; + k = (k + 1) % 4; + + s++; + } + + /* Ellipsation is necessary. This means we might need to truncate the string again to make space for 4 + * characters ideally, but the buffer is shorter than that in the first place take what we can get */ + for (j = 0; j < ELEMENTSOF(last_char_width); j++) { + + if (i + 4 <= len) /* nice, we reached our space goal */ + break; + + k = k == 0 ? 3 : k - 1; + if (last_char_width[k] == 0) /* bummer, we reached the beginning of the strings */ + break; + + assert(i >= last_char_width[k]); + i -= last_char_width[k]; + } + + if (i + 4 <= len) /* yay, enough space */ + i += write_ellipsis(buf + i, false); + else if (i + 3 <= len) { /* only space for ".." */ + buf[i++] = '.'; + buf[i++] = '.'; + } else if (i + 2 <= len) /* only space for a single "." */ + buf[i++] = '.'; + else + assert(i + 1 <= len); + + done: + buf[i] = '\0'; + return buf; +} +#endif /* NM_IGNORED */ + +char* strshorten(char *s, size_t l) { + assert(s); + + if (strnlen(s, l+1) > l) + s[l] = 0; + + return s; +} + +char *strreplace(const char *text, const char *old_string, const char *new_string) { + size_t l, old_len, new_len, allocated = 0; + char *t, *ret = NULL; + const char *f; + + assert(old_string); + assert(new_string); + + if (!text) + return NULL; + + old_len = strlen(old_string); + new_len = strlen(new_string); + + l = strlen(text); + if (!GREEDY_REALLOC(ret, allocated, l+1)) + return NULL; + + f = text; + t = ret; + while (*f) { + size_t d, nl; + + if (!startswith(f, old_string)) { + *(t++) = *(f++); + continue; + } + + d = t - ret; + nl = l - old_len + new_len; + + if (!GREEDY_REALLOC(ret, allocated, nl + 1)) + return mfree(ret); + + l = nl; + t = ret + d; + + t = stpcpy(t, new_string); + f += old_len; + } + + *t = 0; + return ret; +} + +#if 0 /* NM_IGNORED */ +static void advance_offsets( + ssize_t diff, + size_t offsets[2], /* note: we can't use [static 2] here, since this may be NULL */ + size_t shift[static 2], + size_t size) { + + if (!offsets) + return; + + assert(shift); + + if ((size_t) diff < offsets[0]) + shift[0] += size; + if ((size_t) diff < offsets[1]) + shift[1] += size; +} + +char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { + const char *begin = NULL; + enum { + STATE_OTHER, + STATE_ESCAPE, + STATE_CSI, + STATE_CSO, + } state = STATE_OTHER; + char *obuf = NULL; + size_t osz = 0, isz, shift[2] = {}, n_carriage_returns = 0; + FILE *f; + + assert(ibuf); + assert(*ibuf); + + /* This does three things: + * + * 1. Replaces TABs by 8 spaces + * 2. Strips ANSI color sequences (a subset of CSI), i.e. ESC '[' … 'm' sequences + * 3. Strips ANSI operating system sequences (CSO), i.e. ESC ']' … BEL sequences + * 4. Strip trailing \r characters (since they would "move the cursor", but have no + * other effect). + * + * Everything else will be left as it is. In particular other ANSI sequences are left as they are, as + * are any other special characters. Truncated ANSI sequences are left-as is too. This call is + * supposed to suppress the most basic formatting noise, but nothing else. + * + * Why care for CSO sequences? Well, to undo what terminal_urlify() and friends generate. */ + + isz = _isz ? *_isz : strlen(*ibuf); + + /* Note we turn off internal locking on f for performance reasons. It's safe to do so since we + * created f here and it doesn't leave our scope. */ + f = open_memstream_unlocked(&obuf, &osz); + if (!f) + return NULL; + + for (const char *i = *ibuf; i < *ibuf + isz + 1; i++) { + + switch (state) { + + case STATE_OTHER: + if (i >= *ibuf + isz) /* EOT */ + break; + + if (*i == '\r') { + n_carriage_returns++; + break; + } else if (*i == '\n') + /* Ignore carriage returns before new line */ + n_carriage_returns = 0; + for (; n_carriage_returns > 0; n_carriage_returns--) + fputc('\r', f); + + if (*i == '\x1B') + state = STATE_ESCAPE; + else if (*i == '\t') { + fputs(" ", f); + advance_offsets(i - *ibuf, highlight, shift, 7); + } else + fputc(*i, f); + + break; + + case STATE_ESCAPE: + assert(n_carriage_returns == 0); + + if (i >= *ibuf + isz) { /* EOT */ + fputc('\x1B', f); + advance_offsets(i - *ibuf, highlight, shift, 1); + break; + } else if (*i == '[') { /* ANSI CSI */ + state = STATE_CSI; + begin = i + 1; + } else if (*i == ']') { /* ANSI CSO */ + state = STATE_CSO; + begin = i + 1; + } else { + fputc('\x1B', f); + fputc(*i, f); + advance_offsets(i - *ibuf, highlight, shift, 1); + state = STATE_OTHER; + } + + break; + + case STATE_CSI: + assert(n_carriage_returns == 0); + + if (i >= *ibuf + isz || /* EOT … */ + !strchr("01234567890;m", *i)) { /* … or invalid chars in sequence */ + fputc('\x1B', f); + fputc('[', f); + advance_offsets(i - *ibuf, highlight, shift, 2); + state = STATE_OTHER; + i = begin-1; + } else if (*i == 'm') + state = STATE_OTHER; + + break; + + case STATE_CSO: + assert(n_carriage_returns == 0); + + if (i >= *ibuf + isz || /* EOT … */ + (*i != '\a' && (uint8_t) *i < 32U) || (uint8_t) *i > 126U) { /* … or invalid chars in sequence */ + fputc('\x1B', f); + fputc(']', f); + advance_offsets(i - *ibuf, highlight, shift, 2); + state = STATE_OTHER; + i = begin-1; + } else if (*i == '\a') + state = STATE_OTHER; + + break; + } + } + + if (fflush_and_check(f) < 0) { + fclose(f); + return mfree(obuf); + } + fclose(f); + + free_and_replace(*ibuf, obuf); + + if (_isz) + *_isz = osz; + + if (highlight) { + highlight[0] += shift[0]; + highlight[1] += shift[1]; + } + + return *ibuf; +} + +char *strextend_with_separator_internal(char **x, const char *separator, ...) { + size_t f, l, l_separator; + bool need_separator; + char *nr, *p; + va_list ap; + + assert(x); + + l = f = strlen_ptr(*x); + + need_separator = !isempty(*x); + l_separator = strlen_ptr(separator); + + va_start(ap, separator); + for (;;) { + const char *t; + size_t n; + + t = va_arg(ap, const char *); + if (!t) + break; + + n = strlen(t); + + if (need_separator) + n += l_separator; + + if (n >= SIZE_MAX - l) { + va_end(ap); + return NULL; + } + + l += n; + need_separator = true; + } + va_end(ap); + + need_separator = !isempty(*x); + + nr = realloc(*x, GREEDY_ALLOC_ROUND_UP(l+1)); + if (!nr) + return NULL; + + *x = nr; + p = nr + f; + + va_start(ap, separator); + for (;;) { + const char *t; + + t = va_arg(ap, const char *); + if (!t) + break; + + if (need_separator && separator) + p = stpcpy(p, separator); + + p = stpcpy(p, t); + + need_separator = true; + } + va_end(ap); + + assert(p == nr + l); + + *p = 0; + + return p; +} +#endif /* NM_IGNORED */ + +char *strrep(const char *s, unsigned n) { + size_t l; + char *r, *p; + unsigned i; + + assert(s); + + l = strlen(s); + p = r = malloc(l * n + 1); + if (!r) + return NULL; + + for (i = 0; i < n; i++) + p = stpcpy(p, s); + + *p = 0; + return r; +} + +int split_pair(const char *s, const char *sep, char **l, char **r) { + char *x, *a, *b; + + assert(s); + assert(sep); + assert(l); + assert(r); + + if (isempty(sep)) + return -EINVAL; + + x = strstr(s, sep); + if (!x) + return -EINVAL; + + a = strndup(s, x - s); + if (!a) + return -ENOMEM; + + b = strdup(x + strlen(sep)); + if (!b) { + free(a); + return -ENOMEM; + } + + *l = a; + *r = b; + + return 0; +} + +int free_and_strdup(char **p, const char *s) { + char *t; + + assert(p); + + /* Replaces a string pointer with a strdup()ed new string, + * possibly freeing the old one. */ + + if (streq_ptr(*p, s)) + return 0; + + if (s) { + t = strdup(s); + if (!t) + return -ENOMEM; + } else + t = NULL; + + free(*p); + *p = t; + + return 1; +} + +int free_and_strndup(char **p, const char *s, size_t l) { + char *t; + + assert(p); + assert(s || l == 0); + + /* Replaces a string pointer with a strndup()ed new string, + * freeing the old one. */ + + if (!*p && !s) + return 0; + + if (*p && s && strneq(*p, s, l) && (l > strlen(*p) || (*p)[l] == '\0')) + return 0; + + if (s) { + t = strndup(s, l); + if (!t) + return -ENOMEM; + } else + t = NULL; + + free_and_replace(*p, t); + return 1; +} + +bool string_is_safe(const char *p) { + const char *t; + + if (!p) + return false; + + /* Checks if the specified string contains no quotes or control characters */ + + for (t = p; *t; t++) { + if (*t > 0 && *t < ' ') /* no control characters */ + return false; + + if (strchr(QUOTES "\\\x7f", *t)) + return false; + } + + return true; +} + +#if 0 /* NM_IGNORED */ +char* string_erase(char *x) { + if (!x) + return NULL; + + /* A delicious drop of snake-oil! To be called on memory where we stored passphrases or so, after we + * used them. */ + explicit_bzero_safe(x, strlen(x)); + return x; +} + +int string_truncate_lines(const char *s, size_t n_lines, char **ret) { + const char *p = s, *e = s; + bool truncation_applied = false; + char *copy; + size_t n = 0; + + assert(s); + + /* Truncate after the specified number of lines. Returns > 0 if a truncation was applied or == 0 if + * there were fewer lines in the string anyway. Trailing newlines on input are ignored, and not + * generated either. */ + + for (;;) { + size_t k; + + k = strcspn(p, "\n"); + + if (p[k] == 0) { + if (k == 0) /* final empty line */ + break; + + if (n >= n_lines) /* above threshold */ + break; + + e = p + k; /* last line to include */ + break; + } + + assert(p[k] == '\n'); + + if (n >= n_lines) + break; + + if (k > 0) + e = p + k; + + p += k + 1; + n++; + } + + /* e points after the last character we want to keep */ + if (isempty(e)) + copy = strdup(s); + else { + if (!in_charset(e, "\n")) /* We only consider things truncated if we remove something that + * isn't a new-line or a series of them */ + truncation_applied = true; + + copy = strndup(s, e - s); + } + if (!copy) + return -ENOMEM; + + *ret = copy; + return truncation_applied; +} + +int string_extract_line(const char *s, size_t i, char **ret) { + const char *p = s; + size_t c = 0; + + /* Extract the i'nth line from the specified string. Returns > 0 if there are more lines after that, + * and == 0 if we are looking at the last line or already beyond the last line. As special + * optimization, if the first line is requested and the string only consists of one line we return + * NULL, indicating the input string should be used as is, and avoid a memory allocation for a very + * common case. */ + + for (;;) { + const char *q; + + q = strchr(p, '\n'); + if (i == c) { + /* The line we are looking for! */ + + if (q) { + char *m; + + m = strndup(p, q - p); + if (!m) + return -ENOMEM; + + *ret = m; + return !isempty(q + 1); /* more coming? */ + } else { + if (p == s) + *ret = NULL; /* Just use the input string */ + else { + char *m; + + m = strdup(p); + if (!m) + return -ENOMEM; + + *ret = m; + } + + return 0; /* The end */ + } + } + + if (!q) { + char *m; + + /* No more lines, return empty line */ + + m = strdup(""); + if (!m) + return -ENOMEM; + + *ret = m; + return 0; /* The end */ + } + + p = q + 1; + c++; + } +} + +int string_contains_word_strv(const char *string, const char *separators, char **words, const char **ret_word) { + /* In the default mode with no separators specified, we split on whitespace and + * don't coalesce separators. */ + const ExtractFlags flags = separators ? EXTRACT_DONT_COALESCE_SEPARATORS : 0; + + const char *found = NULL; + + for (const char *p = string;;) { + _cleanup_free_ char *w = NULL; + int r; + + r = extract_first_word(&p, &w, separators, flags); + if (r < 0) + return r; + if (r == 0) + break; + + found = strv_find(words, w); + if (found) + break; + } + + if (ret_word) + *ret_word = found; + return !!found; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/string-util.h b/src/libnm-systemd-shared/src/basic/string-util.h new file mode 100644 index 0000000..593cf04 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/string-util.h @@ -0,0 +1,280 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include + +#include "alloc-util.h" +#include "macro.h" + +/* What is interpreted as whitespace? */ +#define WHITESPACE " \t\n\r" +#define NEWLINE "\n\r" +#define QUOTES "\"\'" +#define COMMENTS "#;" +#define GLOB_CHARS "*?[" +#define DIGITS "0123456789" +#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz" +#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS +#define ALPHANUMERICAL LETTERS DIGITS +#define HEXDIGITS DIGITS "abcdefABCDEF" + +#define streq(a,b) (strcmp((a),(b)) == 0) +#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) +#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0) +#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0) + +int strcmp_ptr(const char *a, const char *b) _pure_; +int strcasecmp_ptr(const char *a, const char *b) _pure_; + +static inline bool streq_ptr(const char *a, const char *b) { + return strcmp_ptr(a, b) == 0; +} + +static inline char* strstr_ptr(const char *haystack, const char *needle) { + if (!haystack || !needle) + return NULL; + return strstr(haystack, needle); +} + +static inline const char* strempty(const char *s) { + return s ?: ""; +} + +static inline const char* strnull(const char *s) { + return s ?: "(null)"; +} + +static inline const char *strna(const char *s) { + return s ?: "n/a"; +} + +static inline const char* yes_no(bool b) { + return b ? "yes" : "no"; +} + +static inline const char* true_false(bool b) { + return b ? "true" : "false"; +} + +static inline const char* plus_minus(bool b) { + return b ? "+" : "-"; +} + +static inline const char* one_zero(bool b) { + return b ? "1" : "0"; +} + +static inline const char* enable_disable(bool b) { + return b ? "enable" : "disable"; +} + +static inline bool isempty(const char *p) { + return !p || !p[0]; +} + +static inline const char *empty_to_null(const char *p) { + return isempty(p) ? NULL : p; +} + +static inline const char *empty_to_dash(const char *str) { + return isempty(str) ? "-" : str; +} + +static inline bool empty_or_dash(const char *str) { + return !str || + str[0] == 0 || + (str[0] == '-' && str[1] == 0); +} + +static inline const char *empty_or_dash_to_null(const char *p) { + return empty_or_dash(p) ? NULL : p; +} + +static inline char *startswith(const char *s, const char *prefix) { + size_t l; + + l = strlen(prefix); + if (strncmp(s, prefix, l) == 0) + return (char*) s + l; + + return NULL; +} + +static inline char *startswith_no_case(const char *s, const char *prefix) { + size_t l; + + l = strlen(prefix); + if (strncasecmp(s, prefix, l) == 0) + return (char*) s + l; + + return NULL; +} + +char *endswith(const char *s, const char *postfix) _pure_; +char *endswith_no_case(const char *s, const char *postfix) _pure_; + +char *first_word(const char *s, const char *word) _pure_; + +char *strnappend(const char *s, const char *suffix, size_t length); + +char *strjoin_real(const char *x, ...) _sentinel_; +#define strjoin(a, ...) strjoin_real((a), __VA_ARGS__, NULL) + +#define strjoina(a, ...) \ + ({ \ + const char *_appendees_[] = { a, __VA_ARGS__ }; \ + char *_d_, *_p_; \ + size_t _len_ = 0; \ + size_t _i_; \ + for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \ + _len_ += strlen(_appendees_[_i_]); \ + _p_ = _d_ = newa(char, _len_ + 1); \ + for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \ + _p_ = stpcpy(_p_, _appendees_[_i_]); \ + *_p_ = 0; \ + _d_; \ + }) + +char *strstrip(char *s); +char *delete_chars(char *s, const char *bad); +char *delete_trailing_chars(char *s, const char *bad); +char *truncate_nl(char *s); + +static inline char *skip_leading_chars(const char *s, const char *bad) { + if (!s) + return NULL; + + if (!bad) + bad = WHITESPACE; + + return (char*) s + strspn(s, bad); +} + +char ascii_tolower(char x); +char *ascii_strlower(char *s); +char *ascii_strlower_n(char *s, size_t n); + +char ascii_toupper(char x); +char *ascii_strupper(char *s); + +int ascii_strcasecmp_n(const char *a, const char *b, size_t n); +int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m); + +bool chars_intersect(const char *a, const char *b) _pure_; + +static inline bool _pure_ in_charset(const char *s, const char* charset) { + assert(s); + assert(charset); + return s[strspn(s, charset)] == '\0'; +} + +bool string_has_cc(const char *p, const char *ok) _pure_; + +char *ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent); +static inline char *ellipsize(const char *s, size_t length, unsigned percent) { + return ellipsize_mem(s, strlen(s), length, percent); +} + +char *cellescape(char *buf, size_t len, const char *s); + +/* This limit is arbitrary, enough to give some idea what the string contains */ +#define CELLESCAPE_DEFAULT_LENGTH 64 + +char* strshorten(char *s, size_t l); + +char *strreplace(const char *text, const char *old_string, const char *new_string); + +char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]); + +char *strextend_with_separator_internal(char **x, const char *separator, ...) _sentinel_; + +#define strextend_with_separator(x, separator, ...) strextend_with_separator_internal(x, separator, __VA_ARGS__, NULL) +#define strextend(x, ...) strextend_with_separator_internal(x, NULL, __VA_ARGS__, NULL) + +char *strrep(const char *s, unsigned n); + +int split_pair(const char *s, const char *sep, char **l, char **r); + +int free_and_strdup(char **p, const char *s); +static inline int free_and_strdup_warn(char **p, const char *s) { + if (free_and_strdup(p, s) < 0) + return log_oom(); + return 0; +} +int free_and_strndup(char **p, const char *s, size_t l); + +bool string_is_safe(const char *p) _pure_; + +static inline size_t strlen_ptr(const char *s) { + if (!s) + return 0; + + return strlen(s); +} + +DISABLE_WARNING_STRINGOP_TRUNCATION; +static inline void strncpy_exact(char *buf, const char *src, size_t buf_len) { + strncpy(buf, src, buf_len); +} +REENABLE_WARNING; + +/* Like startswith(), but operates on arbitrary memory blocks */ +static inline void *memory_startswith(const void *p, size_t sz, const char *token) { + assert(token); + + size_t n = strlen(token); + if (sz < n) + return NULL; + + assert(p); + + if (memcmp(p, token, n) != 0) + return NULL; + + return (uint8_t*) p + n; +} + +/* Like startswith_no_case(), but operates on arbitrary memory blocks. + * It works only for ASCII strings. + */ +static inline void *memory_startswith_no_case(const void *p, size_t sz, const char *token) { + assert(token); + + size_t n = strlen(token); + if (sz < n) + return NULL; + + assert(p); + + for (size_t i = 0; i < n; i++) + if (ascii_tolower(((char *)p)[i]) != ascii_tolower(token[i])) + return NULL; + + return (uint8_t*) p + n; +} + +static inline char* str_realloc(char **p) { + /* Reallocate *p to actual size */ + + if (!*p) + return NULL; + + char *t = realloc(*p, strlen(*p) + 1); + if (!t) + return NULL; + + return (*p = t); +} + +char* string_erase(char *x); + +int string_truncate_lines(const char *s, size_t n_lines, char **ret); +int string_extract_line(const char *s, size_t i, char **ret); + +int string_contains_word_strv(const char *string, const char *separators, char **words, const char **ret_word); +static inline int string_contains_word(const char *string, const char *separators, const char *word) { + return string_contains_word_strv(string, separators, STRV_MAKE(word), NULL); +} diff --git a/src/libnm-systemd-shared/src/basic/strv.c b/src/libnm-systemd-shared/src/basic/strv.c new file mode 100644 index 0000000..7d3e3fc --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/strv.c @@ -0,0 +1,1005 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "escape.h" +#include "extract-word.h" +#include "fileio.h" +#include "memory-util.h" +#include "nulstr-util.h" +#include "sort-util.h" +#include "string-util.h" +#include "strv.h" + +char *strv_find(char * const *l, const char *name) { + char * const *i; + + assert(name); + + STRV_FOREACH(i, l) + if (streq(*i, name)) + return *i; + + return NULL; +} + +char *strv_find_case(char * const *l, const char *name) { + char * const *i; + + assert(name); + + STRV_FOREACH(i, l) + if (strcaseeq(*i, name)) + return *i; + + return NULL; +} + +char *strv_find_prefix(char * const *l, const char *name) { + char * const *i; + + assert(name); + + STRV_FOREACH(i, l) + if (startswith(*i, name)) + return *i; + + return NULL; +} + +char *strv_find_startswith(char * const *l, const char *name) { + char * const *i, *e; + + assert(name); + + /* Like strv_find_prefix, but actually returns only the + * suffix, not the whole item */ + + STRV_FOREACH(i, l) { + e = startswith(*i, name); + if (e) + return e; + } + + return NULL; +} + +char **strv_free(char **l) { + char **k; + + if (!l) + return NULL; + + for (k = l; *k; k++) + free(*k); + + return mfree(l); +} + +char **strv_free_erase(char **l) { + char **i; + + STRV_FOREACH(i, l) + erase_and_freep(i); + + return mfree(l); +} + +char **strv_copy(char * const *l) { + char **r, **k; + + k = r = new(char*, strv_length(l) + 1); + if (!r) + return NULL; + + if (l) + for (; *l; k++, l++) { + *k = strdup(*l); + if (!*k) { + strv_free(r); + return NULL; + } + } + + *k = NULL; + return r; +} + +size_t strv_length(char * const *l) { + size_t n = 0; + + if (!l) + return 0; + + for (; *l; l++) + n++; + + return n; +} + +char **strv_new_ap(const char *x, va_list ap) { + _cleanup_strv_free_ char **a = NULL; + size_t n = 0, i = 0; + va_list aq; + + /* As a special trick we ignore all listed strings that equal + * STRV_IGNORE. This is supposed to be used with the + * STRV_IFNOTNULL() macro to include possibly NULL strings in + * the string list. */ + + va_copy(aq, ap); + for (const char *s = x; s; s = va_arg(aq, const char*)) { + if (s == STRV_IGNORE) + continue; + + n++; + } + va_end(aq); + + a = new(char*, n+1); + if (!a) + return NULL; + + for (const char *s = x; s; s = va_arg(ap, const char*)) { + if (s == STRV_IGNORE) + continue; + + a[i] = strdup(s); + if (!a[i]) + return NULL; + + i++; + } + + a[i] = NULL; + + return TAKE_PTR(a); +} + +char **strv_new_internal(const char *x, ...) { + char **r; + va_list ap; + + va_start(ap, x); + r = strv_new_ap(x, ap); + va_end(ap); + + return r; +} + +int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates) { + char * const *s, **t; + size_t p, q, i = 0, j; + + assert(a); + + if (strv_isempty(b)) + return 0; + + p = strv_length(*a); + q = strv_length(b); + + if (p >= SIZE_MAX - q) + return -ENOMEM; + + t = reallocarray(*a, GREEDY_ALLOC_ROUND_UP(p + q + 1), sizeof(char *)); + if (!t) + return -ENOMEM; + + t[p] = NULL; + *a = t; + + STRV_FOREACH(s, b) { + + if (filter_duplicates && strv_contains(t, *s)) + continue; + + t[p+i] = strdup(*s); + if (!t[p+i]) + goto rollback; + + i++; + t[p+i] = NULL; + } + + assert(i <= q); + + return (int) i; + +rollback: + for (j = 0; j < i; j++) + free(t[p + j]); + + t[p] = NULL; + return -ENOMEM; +} + +#if 0 /* NM_IGNORED */ +int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix) { + char * const *s; + int r; + + STRV_FOREACH(s, b) { + char *v; + + v = strjoin(*s, suffix); + if (!v) + return -ENOMEM; + + r = strv_push(a, v); + if (r < 0) { + free(v); + return r; + } + } + + return 0; +} +#endif /* NM_IGNORED */ + +char **strv_split_newlines(const char *s) { + char **l; + size_t n; + + assert(s); + + /* Special version of strv_split() that splits on newlines and + * suppresses an empty string at the end */ + + l = strv_split(s, NEWLINE); + if (!l) + return NULL; + + n = strv_length(l); + if (n <= 0) + return l; + + if (isempty(l[n - 1])) + l[n - 1] = mfree(l[n - 1]); + + return l; +} + +int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags) { + _cleanup_strv_free_ char **l = NULL; + size_t n = 0, allocated = 0; + int r; + + assert(t); + assert(s); + + for (;;) { + _cleanup_free_ char *word = NULL; + + r = extract_first_word(&s, &word, separators, flags); + if (r < 0) + return r; + if (r == 0) + break; + + if (!GREEDY_REALLOC(l, allocated, n + 2)) + return -ENOMEM; + + l[n++] = TAKE_PTR(word); + + l[n] = NULL; + } + + if (!l) { + l = new0(char*, 1); + if (!l) + return -ENOMEM; + } + + *t = TAKE_PTR(l); + + return (int) n; +} + +#if 0 /* NM_IGNORED */ +int strv_split_colon_pairs(char ***t, const char *s) { + _cleanup_strv_free_ char **l = NULL; + size_t n = 0, allocated = 0; + int r; + + assert(t); + assert(s); + + for (;;) { + _cleanup_free_ char *first = NULL, *second = NULL, *tuple = NULL, *second_or_empty = NULL; + + r = extract_first_word(&s, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE); + if (r < 0) + return r; + if (r == 0) + break; + + const char *p = tuple; + r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, + &first, &second, NULL); + if (r < 0) + return r; + if (r == 0) + continue; + /* Enforce that at most 2 colon-separated words are contained in each group */ + if (!isempty(p)) + return -EINVAL; + + second_or_empty = strdup(strempty(second)); + if (!second_or_empty) + return -ENOMEM; + + if (!GREEDY_REALLOC(l, allocated, n + 3)) + return -ENOMEM; + + l[n++] = TAKE_PTR(first); + l[n++] = TAKE_PTR(second_or_empty); + + l[n] = NULL; + } + + if (!l) { + l = new0(char*, 1); + if (!l) + return -ENOMEM; + } + + *t = TAKE_PTR(l); + + return (int) n; +} +#endif /* NM_IGNORED */ + +char *strv_join_full(char * const *l, const char *separator, const char *prefix, bool unescape_separators) { + char * const *s; + char *r, *e; + size_t n, k, m; + + if (!separator) + separator = " "; + + k = strlen(separator); + m = strlen_ptr(prefix); + + if (unescape_separators) /* If there separator is multi-char, we won't know how to escape it. */ + assert(k == 1); + + n = 0; + STRV_FOREACH(s, l) { + if (s != l) + n += k; + + bool needs_escaping = unescape_separators && strchr(*s, separator[0]); + + n += m + strlen(*s) * (1 + needs_escaping); + } + + r = new(char, n+1); + if (!r) + return NULL; + + e = r; + STRV_FOREACH(s, l) { + if (s != l) + e = stpcpy(e, separator); + + if (prefix) + e = stpcpy(e, prefix); + + bool needs_escaping = unescape_separators && strchr(*s, separator[0]); + + if (needs_escaping) + for (size_t i = 0; (*s)[i]; i++) { + if ((*s)[i] == separator[0]) + *(e++) = '\\'; + *(e++) = (*s)[i]; + } + else + e = stpcpy(e, *s); + } + + *e = 0; + + return r; +} + +int strv_push(char ***l, char *value) { + char **c; + size_t n; + + if (!value) + return 0; + + n = strv_length(*l); + + /* Check for overflow */ + if (n > SIZE_MAX-2) + return -ENOMEM; + + c = reallocarray(*l, GREEDY_ALLOC_ROUND_UP(n + 2), sizeof(char*)); + if (!c) + return -ENOMEM; + + c[n] = value; + c[n+1] = NULL; + + *l = c; + return 0; +} + +int strv_push_pair(char ***l, char *a, char *b) { + char **c; + size_t n; + + if (!a && !b) + return 0; + + n = strv_length(*l); + + /* Check for overflow */ + if (n > SIZE_MAX-3) + return -ENOMEM; + + /* increase and check for overflow */ + c = reallocarray(*l, GREEDY_ALLOC_ROUND_UP(n + !!a + !!b + 1), sizeof(char*)); + if (!c) + return -ENOMEM; + + if (a) + c[n++] = a; + if (b) + c[n++] = b; + c[n] = NULL; + + *l = c; + return 0; +} + +int strv_insert(char ***l, size_t position, char *value) { + char **c; + size_t n, m, i; + + if (!value) + return 0; + + n = strv_length(*l); + position = MIN(position, n); + + /* increase and check for overflow */ + m = n + 2; + if (m < n) + return -ENOMEM; + + c = new(char*, m); + if (!c) + return -ENOMEM; + + for (i = 0; i < position; i++) + c[i] = (*l)[i]; + c[position] = value; + for (i = position; i < n; i++) + c[i+1] = (*l)[i]; + + c[n+1] = NULL; + + free(*l); + *l = c; + + return 0; +} + +int strv_consume(char ***l, char *value) { + int r; + + r = strv_push(l, value); + if (r < 0) + free(value); + + return r; +} + +int strv_consume_pair(char ***l, char *a, char *b) { + int r; + + r = strv_push_pair(l, a, b); + if (r < 0) { + free(a); + free(b); + } + + return r; +} + +int strv_consume_prepend(char ***l, char *value) { + int r; + + r = strv_push_prepend(l, value); + if (r < 0) + free(value); + + return r; +} + +int strv_prepend(char ***l, const char *value) { + char *v; + + if (!value) + return 0; + + v = strdup(value); + if (!v) + return -ENOMEM; + + return strv_consume_prepend(l, v); +} + +int strv_extend(char ***l, const char *value) { + char *v; + + if (!value) + return 0; + + v = strdup(value); + if (!v) + return -ENOMEM; + + return strv_consume(l, v); +} + +int strv_extend_front(char ***l, const char *value) { + size_t n, m; + char *v, **c; + + assert(l); + + /* Like strv_extend(), but prepends rather than appends the new entry */ + + if (!value) + return 0; + + n = strv_length(*l); + + /* Increase and overflow check. */ + m = n + 2; + if (m < n) + return -ENOMEM; + + v = strdup(value); + if (!v) + return -ENOMEM; + + c = reallocarray(*l, m, sizeof(char*)); + if (!c) { + free(v); + return -ENOMEM; + } + + memmove(c+1, c, n * sizeof(char*)); + c[0] = v; + c[n+1] = NULL; + + *l = c; + return 0; +} + +char **strv_uniq(char **l) { + char **i; + + /* Drops duplicate entries. The first identical string will be + * kept, the others dropped */ + + STRV_FOREACH(i, l) + strv_remove(i+1, *i); + + return l; +} + +bool strv_is_uniq(char * const *l) { + char * const *i; + + STRV_FOREACH(i, l) + if (strv_find(i+1, *i)) + return false; + + return true; +} + +char **strv_remove(char **l, const char *s) { + char **f, **t; + + if (!l) + return NULL; + + assert(s); + + /* Drops every occurrence of s in the string list, edits + * in-place. */ + + for (f = t = l; *f; f++) + if (streq(*f, s)) + free(*f); + else + *(t++) = *f; + + *t = NULL; + return l; +} + +char **strv_parse_nulstr(const char *s, size_t l) { + /* l is the length of the input data, which will be split at NULs into + * elements of the resulting strv. Hence, the number of items in the resulting strv + * will be equal to one plus the number of NUL bytes in the l bytes starting at s, + * unless s[l-1] is NUL, in which case the final empty string is not stored in + * the resulting strv, and length is equal to the number of NUL bytes. + * + * Note that contrary to a normal nulstr which cannot contain empty strings, because + * the input data is terminated by any two consequent NUL bytes, this parser accepts + * empty strings in s. + */ + + const char *p; + size_t c = 0, i = 0; + char **v; + + assert(s || l <= 0); + + if (l <= 0) + return new0(char*, 1); + + for (p = s; p < s + l; p++) + if (*p == 0) + c++; + + if (s[l-1] != 0) + c++; + + v = new0(char*, c+1); + if (!v) + return NULL; + + p = s; + while (p < s + l) { + const char *e; + + e = memchr(p, 0, s + l - p); + + v[i] = strndup(p, e ? e - p : s + l - p); + if (!v[i]) { + strv_free(v); + return NULL; + } + + i++; + + if (!e) + break; + + p = e + 1; + } + + assert(i == c); + + return v; +} + +#if 0 /* NM_IGNORED */ +char **strv_split_nulstr(const char *s) { + const char *i; + char **r = NULL; + + NULSTR_FOREACH(i, s) + if (strv_extend(&r, i) < 0) { + strv_free(r); + return NULL; + } + + if (!r) + return strv_new(NULL); + + return r; +} +#endif /* NM_IGNORED */ + +int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) { + /* A valid nulstr with two NULs at the end will be created, but + * q will be the length without the two trailing NULs. Thus the output + * string is a valid nulstr and can be iterated over using NULSTR_FOREACH, + * and can also be parsed by strv_parse_nulstr as long as the length + * is provided separately. + */ + + size_t n_allocated = 0, n = 0; + _cleanup_free_ char *m = NULL; + char * const *i; + + assert(ret); + assert(ret_size); + + STRV_FOREACH(i, l) { + size_t z; + + z = strlen(*i); + + if (!GREEDY_REALLOC(m, n_allocated, n + z + 2)) + return -ENOMEM; + + memcpy(m + n, *i, z + 1); + n += z + 1; + } + + if (!m) { + m = new0(char, 1); + if (!m) + return -ENOMEM; + n = 1; + } else + /* make sure there is a second extra NUL at the end of resulting nulstr */ + m[n] = '\0'; + + assert(n > 0); + *ret = m; + *ret_size = n - 1; + + m = NULL; + + return 0; +} + +bool strv_overlap(char * const *a, char * const *b) { + char * const *i; + + STRV_FOREACH(i, a) + if (strv_contains(b, *i)) + return true; + + return false; +} + +#if 0 /* NM_IGNORED */ +static int str_compare(char * const *a, char * const *b) { + return strcmp(*a, *b); +} + +char **strv_sort(char **l) { + typesafe_qsort(l, strv_length(l), str_compare); + return l; +} +#endif /* NM_IGNORED */ + +int strv_compare(char * const *a, char * const *b) { + int r; + + if (strv_isempty(a)) { + if (strv_isempty(b)) + return 0; + else + return -1; + } + + if (strv_isempty(b)) + return 1; + + for ( ; *a || *b; ++a, ++b) { + r = strcmp_ptr(*a, *b); + if (r != 0) + return r; + } + + return 0; +} + +void strv_print(char * const *l) { + char * const *s; + + STRV_FOREACH(s, l) + puts(*s); +} + +int strv_extendf(char ***l, const char *format, ...) { + va_list ap; + char *x; + int r; + + va_start(ap, format); + r = vasprintf(&x, format, ap); + va_end(ap); + + if (r < 0) + return -ENOMEM; + + return strv_consume(l, x); +} + +char **strv_reverse(char **l) { + size_t n, i; + + n = strv_length(l); + if (n <= 1) + return l; + + for (i = 0; i < n / 2; i++) + SWAP_TWO(l[i], l[n-1-i]); + + return l; +} + +char **strv_shell_escape(char **l, const char *bad) { + char **s; + + /* Escapes every character in every string in l that is in bad, + * edits in-place, does not roll-back on error. */ + + STRV_FOREACH(s, l) { + char *v; + + v = shell_escape(*s, bad); + if (!v) + return NULL; + + free(*s); + *s = v; + } + + return l; +} + +bool strv_fnmatch_full(char* const* patterns, const char *s, int flags, size_t *matched_pos) { + for (size_t i = 0; patterns && patterns[i]; i++) + if (fnmatch(patterns[i], s, flags) == 0) { + if (matched_pos) + *matched_pos = i; + return true; + } + + return false; +} + +char ***strv_free_free(char ***l) { + char ***i; + + if (!l) + return NULL; + + for (i = l; *i; i++) + strv_free(*i); + + return mfree(l); +} + +char **strv_skip(char **l, size_t n) { + + while (n > 0) { + if (strv_isempty(l)) + return l; + + l++, n--; + } + + return l; +} + +int strv_extend_n(char ***l, const char *value, size_t n) { + size_t i, j, k; + char **nl; + + assert(l); + + if (!value) + return 0; + if (n == 0) + return 0; + + /* Adds the value n times to l */ + + k = strv_length(*l); + if (n >= SIZE_MAX - k) + return -ENOMEM; + + nl = reallocarray(*l, GREEDY_ALLOC_ROUND_UP(k + n + 1), sizeof(char *)); + if (!nl) + return -ENOMEM; + + *l = nl; + + for (i = k; i < k + n; i++) { + nl[i] = strdup(value); + if (!nl[i]) + goto rollback; + } + + nl[i] = NULL; + return 0; + +rollback: + for (j = k; j < i; j++) + free(nl[j]); + + nl[k] = NULL; + return -ENOMEM; +} + +int fputstrv(FILE *f, char * const *l, const char *separator, bool *space) { + bool b = false; + char * const *s; + int r; + + /* Like fputs(), but for strv, and with a less stupid argument order */ + + if (!space) + space = &b; + + STRV_FOREACH(s, l) { + r = fputs_with_space(f, *s, separator, space); + if (r < 0) + return r; + } + + return 0; +} + +static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const char *value) { + char **l; + int r; + + l = hashmap_get(h, key); + if (l) { + /* A list for this key already exists, let's append to it if it is not listed yet */ + if (strv_contains(l, value)) + return 0; + + r = strv_extend(&l, value); + if (r < 0) + return r; + + assert_se(hashmap_update(h, key, l) >= 0); + } else { + /* No list for this key exists yet, create one */ + _cleanup_strv_free_ char **l2 = NULL; + _cleanup_free_ char *t = NULL; + + t = strdup(key); + if (!t) + return -ENOMEM; + + r = strv_extend(&l2, value); + if (r < 0) + return r; + + r = hashmap_put(h, t, l2); + if (r < 0) + return r; + TAKE_PTR(t); + TAKE_PTR(l2); + } + + return 1; +} + +int _string_strv_hashmap_put(Hashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS) { + int r; + + r = _hashmap_ensure_allocated(h, &string_strv_hash_ops HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + return string_strv_hashmap_put_internal(*h, key, value); +} + +int _string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS) { + int r; + + r = _ordered_hashmap_ensure_allocated(h, &string_strv_hash_ops HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + return string_strv_hashmap_put_internal(PLAIN_HASHMAP(*h), key, value); +} + +DEFINE_HASH_OPS_FULL(string_strv_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free); diff --git a/src/libnm-systemd-shared/src/basic/strv.h b/src/libnm-systemd-shared/src/basic/strv.h new file mode 100644 index 0000000..6b3e8e7 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/strv.h @@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "extract-word.h" +#include "hashmap.h" +#include "macro.h" +#include "string-util.h" + +char *strv_find(char * const *l, const char *name) _pure_; +char *strv_find_case(char * const *l, const char *name) _pure_; +char *strv_find_prefix(char * const *l, const char *name) _pure_; +char *strv_find_startswith(char * const *l, const char *name) _pure_; + +#define strv_contains(l, s) (!!strv_find((l), (s))) +#define strv_contains_case(l, s) (!!strv_find_case((l), (s))) + +char **strv_free(char **l); +DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free); +#define _cleanup_strv_free_ _cleanup_(strv_freep) + +char **strv_free_erase(char **l); +DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase); +#define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep) + +char **strv_copy(char * const *l); +size_t strv_length(char * const *l) _pure_; + +int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates); +int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix); +int strv_prepend(char ***l, const char *value); +int strv_extend(char ***l, const char *value); +int strv_extendf(char ***l, const char *format, ...) _printf_(2,0); +int strv_extend_front(char ***l, const char *value); +int strv_push(char ***l, char *value); +int strv_push_pair(char ***l, char *a, char *b); +int strv_insert(char ***l, size_t position, char *value); + +static inline int strv_push_prepend(char ***l, char *value) { + return strv_insert(l, 0, value); +} + +int strv_consume(char ***l, char *value); +int strv_consume_pair(char ***l, char *a, char *b); +int strv_consume_prepend(char ***l, char *value); + +char **strv_remove(char **l, const char *s); +char **strv_uniq(char **l); +bool strv_is_uniq(char * const *l); + +int strv_compare(char * const *a, char * const *b); +static inline bool strv_equal(char * const *a, char * const *b) { + return strv_compare(a, b) == 0; +} + +char **strv_new_internal(const char *x, ...) _sentinel_; +char **strv_new_ap(const char *x, va_list ap); +#define strv_new(...) strv_new_internal(__VA_ARGS__, NULL) + +#define STRV_IGNORE ((const char *) POINTER_MAX) + +static inline const char* STRV_IFNOTNULL(const char *x) { + return x ? x : STRV_IGNORE; +} + +static inline bool strv_isempty(char * const *l) { + return !l || !*l; +} + +char **strv_split_newlines(const char *s); + +int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags); +static inline char **strv_split(const char *s, const char *separators) { + char **ret; + int r; + + r = strv_split_full(&ret, s, separators, 0); + if (r < 0) + return NULL; + + return ret; +} + +/* Given a string containing white-space separated tuples of words themselves separated by ':', + * returns a vector of strings. If the second element in a tuple is missing, the corresponding + * string in the vector is an empty string. */ +int strv_split_colon_pairs(char ***t, const char *s); + +char *strv_join_full(char * const *l, const char *separator, const char *prefix, bool escape_separtor); +static inline char *strv_join(char * const *l, const char *separator) { + return strv_join_full(l, separator, NULL, false); +} + +char **strv_parse_nulstr(const char *s, size_t l); +char **strv_split_nulstr(const char *s); +int strv_make_nulstr(char * const *l, char **p, size_t *n); + +static inline int strv_from_nulstr(char ***a, const char *nulstr) { + char **t; + + t = strv_split_nulstr(nulstr); + if (!t) + return -ENOMEM; + *a = t; + return 0; +} + +bool strv_overlap(char * const *a, char * const *b) _pure_; + +#define STRV_FOREACH(s, l) \ + for ((s) = (l); (s) && *(s); (s)++) + +#define STRV_FOREACH_BACKWARDS(s, l) \ + for (s = ({ \ + typeof(l) _l = l; \ + _l ? _l + strv_length(_l) - 1U : NULL; \ + }); \ + (l) && ((s) >= (l)); \ + (s)--) + +#define STRV_FOREACH_PAIR(x, y, l) \ + for ((x) = (l), (y) = (x) ? (x+1) : NULL; (x) && *(x) && *(y); (x) += 2, (y) = (x + 1)) + +char **strv_sort(char **l); +void strv_print(char * const *l); + +#define strv_from_stdarg_alloca(first) \ + ({ \ + char **_l; \ + \ + if (!first) \ + _l = (char**) &first; \ + else { \ + size_t _n; \ + va_list _ap; \ + \ + _n = 1; \ + va_start(_ap, first); \ + while (va_arg(_ap, char*)) \ + _n++; \ + va_end(_ap); \ + \ + _l = newa(char*, _n+1); \ + _l[_n = 0] = (char*) first; \ + va_start(_ap, first); \ + for (;;) { \ + _l[++_n] = va_arg(_ap, char*); \ + if (!_l[_n]) \ + break; \ + } \ + va_end(_ap); \ + } \ + _l; \ + }) + +#define STR_IN_SET(x, ...) strv_contains(STRV_MAKE(__VA_ARGS__), x) +#define STRPTR_IN_SET(x, ...) \ + ({ \ + const char* _x = (x); \ + _x && strv_contains(STRV_MAKE(__VA_ARGS__), _x); \ + }) + +#define STRCASE_IN_SET(x, ...) strv_contains_case(STRV_MAKE(__VA_ARGS__), x) +#define STRCASEPTR_IN_SET(x, ...) \ + ({ \ + const char* _x = (x); \ + _x && strv_contains_case(STRV_MAKE(__VA_ARGS__), _x); \ + }) + +#define STARTSWITH_SET(p, ...) \ + ({ \ + const char *_p = (p); \ + char *_found = NULL, **_i; \ + STRV_FOREACH(_i, STRV_MAKE(__VA_ARGS__)) { \ + _found = startswith(_p, *_i); \ + if (_found) \ + break; \ + } \ + _found; \ + }) + +#define ENDSWITH_SET(p, ...) \ + ({ \ + const char *_p = (p); \ + char *_found = NULL, **_i; \ + STRV_FOREACH(_i, STRV_MAKE(__VA_ARGS__)) { \ + _found = endswith(_p, *_i); \ + if (_found) \ + break; \ + } \ + _found; \ + }) + +#define FOREACH_STRING(x, y, ...) \ + for (char **_l = STRV_MAKE(({ x = y; }), ##__VA_ARGS__); \ + x; \ + x = *(++_l)) + +char **strv_reverse(char **l); +char **strv_shell_escape(char **l, const char *bad); + +bool strv_fnmatch_full(char* const* patterns, const char *s, int flags, size_t *matched_pos); +static inline bool strv_fnmatch(char* const* patterns, const char *s) { + return strv_fnmatch_full(patterns, s, 0, NULL); +} + +static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, int flags) { + assert(s); + return strv_isempty(patterns) || + strv_fnmatch_full(patterns, s, flags, NULL); +} + +char ***strv_free_free(char ***l); +DEFINE_TRIVIAL_CLEANUP_FUNC(char***, strv_free_free); + +char **strv_skip(char **l, size_t n); + +int strv_extend_n(char ***l, const char *value, size_t n); + +int fputstrv(FILE *f, char * const *l, const char *separator, bool *space); + +#define strv_free_and_replace(a, b) \ + ({ \ + strv_free(a); \ + (a) = (b); \ + (b) = NULL; \ + 0; \ + }) + +extern const struct hash_ops string_strv_hash_ops; +int _string_strv_hashmap_put(Hashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS); +int _string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS); +#define string_strv_hashmap_put(h, k, v) _string_strv_hashmap_put(h, k, v HASHMAP_DEBUG_SRC_ARGS) +#define string_strv_ordered_hashmap_put(h, k, v) _string_strv_ordered_hashmap_put(h, k, v HASHMAP_DEBUG_SRC_ARGS) diff --git a/src/libnm-systemd-shared/src/basic/strxcpyx.c b/src/libnm-systemd-shared/src/basic/strxcpyx.c new file mode 100644 index 0000000..39aebb8 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/strxcpyx.c @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* + * Concatenates/copies strings. In any case, terminates in all cases + * with '\0' and moves the @dest pointer forward to the added '\0'. + * Returns the remaining size, and 0 if the string was truncated. + * + * Due to the intended usage, these helpers silently noop invocations + * having zero size. This is technically an exception to the above + * statement "terminates in all cases". It's unexpected for such calls to + * occur outside of a loop where this is the preferred behavior. + */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include + +#include "strxcpyx.h" + +size_t strnpcpy(char **dest, size_t size, const char *src, size_t len) { + assert(dest); + assert(src); + + if (size == 0) + return 0; + + if (len >= size) { + if (size > 1) + *dest = mempcpy(*dest, src, size-1); + size = 0; + } else if (len > 0) { + *dest = mempcpy(*dest, src, len); + size -= len; + } + + *dest[0] = '\0'; + return size; +} + +size_t strpcpy(char **dest, size_t size, const char *src) { + assert(dest); + assert(src); + + return strnpcpy(dest, size, src, strlen(src)); +} + +size_t strpcpyf(char **dest, size_t size, const char *src, ...) { + va_list va; + int i; + + assert(dest); + assert(src); + + if (size == 0) + return 0; + + va_start(va, src); + i = vsnprintf(*dest, size, src, va); + if (i < (int)size) { + *dest += i; + size -= i; + } else + size = 0; + va_end(va); + return size; +} + +size_t strpcpyl(char **dest, size_t size, const char *src, ...) { + va_list va; + + assert(dest); + assert(src); + + va_start(va, src); + do { + size = strpcpy(dest, size, src); + src = va_arg(va, char *); + } while (src); + va_end(va); + return size; +} + +size_t strnscpy(char *dest, size_t size, const char *src, size_t len) { + char *s; + + assert(dest); + assert(src); + + s = dest; + return strnpcpy(&s, size, src, len); +} + +size_t strscpy(char *dest, size_t size, const char *src) { + assert(dest); + assert(src); + + return strnscpy(dest, size, src, strlen(src)); +} + +size_t strscpyl(char *dest, size_t size, const char *src, ...) { + va_list va; + char *s; + + assert(dest); + assert(src); + + va_start(va, src); + s = dest; + do { + size = strpcpy(&s, size, src); + src = va_arg(va, char *); + } while (src); + va_end(va); + + return size; +} diff --git a/src/libnm-systemd-shared/src/basic/strxcpyx.h b/src/libnm-systemd-shared/src/basic/strxcpyx.h new file mode 100644 index 0000000..cdef492 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/strxcpyx.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#include "macro.h" + +size_t strnpcpy(char **dest, size_t size, const char *src, size_t len); +size_t strpcpy(char **dest, size_t size, const char *src); +size_t strpcpyf(char **dest, size_t size, const char *src, ...) _printf_(3, 4); +size_t strpcpyl(char **dest, size_t size, const char *src, ...) _sentinel_; +size_t strnscpy(char *dest, size_t size, const char *src, size_t len); +size_t strscpy(char *dest, size_t size, const char *src); +size_t strscpyl(char *dest, size_t size, const char *src, ...) _sentinel_; diff --git a/src/libnm-systemd-shared/src/basic/time-util.c b/src/libnm-systemd-shared/src/basic/time-util.c new file mode 100644 index 0000000..e5faa33 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/time-util.c @@ -0,0 +1,1620 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alloc-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" +#include "io-util.h" +#include "log.h" +#include "macro.h" +#include "missing_timerfd.h" +#include "parse-util.h" +#include "path-util.h" +#include "process-util.h" +#include "stat-util.h" +#include "string-table.h" +#include "string-util.h" +#include "strv.h" +#include "time-util.h" + +static clockid_t map_clock_id(clockid_t c) { + + /* Some more exotic archs (s390, ppc, …) lack the "ALARM" flavour of the clocks. Thus, clock_gettime() will + * fail for them. Since they are essentially the same as their non-ALARM pendants (their only difference is + * when timers are set on them), let's just map them accordingly. This way, we can get the correct time even on + * those archs. */ + + switch (c) { + + case CLOCK_BOOTTIME_ALARM: + return CLOCK_BOOTTIME; + + case CLOCK_REALTIME_ALARM: + return CLOCK_REALTIME; + + default: + return c; + } +} + +usec_t now(clockid_t clock_id) { + struct timespec ts; + + assert_se(clock_gettime(map_clock_id(clock_id), &ts) == 0); + + return timespec_load(&ts); +} + +nsec_t now_nsec(clockid_t clock_id) { + struct timespec ts; + + assert_se(clock_gettime(map_clock_id(clock_id), &ts) == 0); + + return timespec_load_nsec(&ts); +} + +dual_timestamp* dual_timestamp_get(dual_timestamp *ts) { + assert(ts); + + ts->realtime = now(CLOCK_REALTIME); + ts->monotonic = now(CLOCK_MONOTONIC); + + return ts; +} + +triple_timestamp* triple_timestamp_get(triple_timestamp *ts) { + assert(ts); + + ts->realtime = now(CLOCK_REALTIME); + ts->monotonic = now(CLOCK_MONOTONIC); + ts->boottime = clock_boottime_supported() ? now(CLOCK_BOOTTIME) : USEC_INFINITY; + + return ts; +} + +static usec_t map_clock_usec_internal(usec_t from, usec_t from_base, usec_t to_base) { + + /* Maps the time 'from' between two clocks, based on a common reference point where the first clock + * is at 'from_base' and the second clock at 'to_base'. Basically calculates: + * + * from - from_base + to_base + * + * But takes care of overflows/underflows and avoids signed operations. */ + + if (from >= from_base) { /* In the future */ + usec_t delta = from - from_base; + + if (to_base >= USEC_INFINITY - delta) /* overflow? */ + return USEC_INFINITY; + + return to_base + delta; + + } else { /* In the past */ + usec_t delta = from_base - from; + + if (to_base <= delta) /* underflow? */ + return 0; + + return to_base - delta; + } +} + +usec_t map_clock_usec(usec_t from, clockid_t from_clock, clockid_t to_clock) { + + /* Try to avoid any inaccuracy needlessly added in case we convert from effectively the same clock + * onto itself */ + if (map_clock_id(from_clock) == map_clock_id(to_clock)) + return from; + + /* Keep infinity as is */ + if (from == USEC_INFINITY) + return from; + + return map_clock_usec_internal(from, now(from_clock), now(to_clock)); +} + +dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) { + assert(ts); + + if (u == USEC_INFINITY || u == 0) { + ts->realtime = ts->monotonic = u; + return ts; + } + + ts->realtime = u; + ts->monotonic = map_clock_usec(u, CLOCK_REALTIME, CLOCK_MONOTONIC); + return ts; +} + +triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u) { + usec_t nowr; + + assert(ts); + + if (u == USEC_INFINITY || u == 0) { + ts->realtime = ts->monotonic = ts->boottime = u; + return ts; + } + + nowr = now(CLOCK_REALTIME); + + ts->realtime = u; + ts->monotonic = map_clock_usec_internal(u, nowr, now(CLOCK_MONOTONIC)); + ts->boottime = clock_boottime_supported() ? + map_clock_usec_internal(u, nowr, now(CLOCK_BOOTTIME)) : + USEC_INFINITY; + + return ts; +} + +dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) { + assert(ts); + + if (u == USEC_INFINITY) { + ts->realtime = ts->monotonic = USEC_INFINITY; + return ts; + } + + ts->monotonic = u; + ts->realtime = map_clock_usec(u, CLOCK_MONOTONIC, CLOCK_REALTIME); + return ts; +} + +dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, usec_t u) { + clockid_t cid; + usec_t nowm; + + if (u == USEC_INFINITY) { + ts->realtime = ts->monotonic = USEC_INFINITY; + return ts; + } + + cid = clock_boottime_or_monotonic(); + nowm = now(cid); + + if (cid == CLOCK_MONOTONIC) + ts->monotonic = u; + else + ts->monotonic = map_clock_usec_internal(u, nowm, now(CLOCK_MONOTONIC)); + + ts->realtime = map_clock_usec_internal(u, nowm, now(CLOCK_REALTIME)); + return ts; +} + +usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock) { + + switch (clock) { + + case CLOCK_REALTIME: + case CLOCK_REALTIME_ALARM: + return ts->realtime; + + case CLOCK_MONOTONIC: + return ts->monotonic; + + case CLOCK_BOOTTIME: + case CLOCK_BOOTTIME_ALARM: + return ts->boottime; + + default: + return USEC_INFINITY; + } +} + +usec_t timespec_load(const struct timespec *ts) { + assert(ts); + + if (ts->tv_sec < 0 || ts->tv_nsec < 0) + return USEC_INFINITY; + + if ((usec_t) ts->tv_sec > (UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / USEC_PER_SEC) + return USEC_INFINITY; + + return + (usec_t) ts->tv_sec * USEC_PER_SEC + + (usec_t) ts->tv_nsec / NSEC_PER_USEC; +} + +nsec_t timespec_load_nsec(const struct timespec *ts) { + assert(ts); + + if (ts->tv_sec < 0 || ts->tv_nsec < 0) + return NSEC_INFINITY; + + if ((nsec_t) ts->tv_sec >= (UINT64_MAX - ts->tv_nsec) / NSEC_PER_SEC) + return NSEC_INFINITY; + + return (nsec_t) ts->tv_sec * NSEC_PER_SEC + (nsec_t) ts->tv_nsec; +} + +struct timespec *timespec_store(struct timespec *ts, usec_t u) { + assert(ts); + + if (u == USEC_INFINITY || + u / USEC_PER_SEC >= TIME_T_MAX) { + ts->tv_sec = (time_t) -1; + ts->tv_nsec = -1L; + return ts; + } + + ts->tv_sec = (time_t) (u / USEC_PER_SEC); + ts->tv_nsec = (long) ((u % USEC_PER_SEC) * NSEC_PER_USEC); + + return ts; +} + +struct timespec *timespec_store_nsec(struct timespec *ts, nsec_t n) { + assert(ts); + + if (n == NSEC_INFINITY || + n / NSEC_PER_SEC >= TIME_T_MAX) { + ts->tv_sec = (time_t) -1; + ts->tv_nsec = -1L; + return ts; + } + + ts->tv_sec = (time_t) (n / NSEC_PER_SEC); + ts->tv_nsec = (long) (n % NSEC_PER_SEC); + + return ts; +} + +#if 0 /* NM_IGNORED */ +usec_t timeval_load(const struct timeval *tv) { + assert(tv); + + if (tv->tv_sec < 0 || tv->tv_usec < 0) + return USEC_INFINITY; + + if ((usec_t) tv->tv_sec > (UINT64_MAX - tv->tv_usec) / USEC_PER_SEC) + return USEC_INFINITY; + + return + (usec_t) tv->tv_sec * USEC_PER_SEC + + (usec_t) tv->tv_usec; +} + +struct timeval *timeval_store(struct timeval *tv, usec_t u) { + assert(tv); + + if (u == USEC_INFINITY || + u / USEC_PER_SEC > TIME_T_MAX) { + tv->tv_sec = (time_t) -1; + tv->tv_usec = (suseconds_t) -1; + } else { + tv->tv_sec = (time_t) (u / USEC_PER_SEC); + tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC); + } + + return tv; +} + +char *format_timestamp_style( + char *buf, + size_t l, + usec_t t, + TimestampStyle style) { + + /* The weekdays in non-localized (English) form. We use this instead of the localized form, so that our + * generated timestamps may be parsed with parse_timestamp(), and always read the same. */ + static const char * const weekdays[] = { + [0] = "Sun", + [1] = "Mon", + [2] = "Tue", + [3] = "Wed", + [4] = "Thu", + [5] = "Fri", + [6] = "Sat", + }; + + struct tm tm; + time_t sec; + size_t n; + bool utc = false, us = false; + + assert(buf); + + switch (style) { + case TIMESTAMP_PRETTY: + break; + case TIMESTAMP_US: + us = true; + break; + case TIMESTAMP_UTC: + utc = true; + break; + case TIMESTAMP_US_UTC: + us = true; + utc = true; + break; + default: + return NULL; + } + + if (l < (size_t) (3 + /* week day */ + 1 + 10 + /* space and date */ + 1 + 8 + /* space and time */ + (us ? 1 + 6 : 0) + /* "." and microsecond part */ + 1 + 1 + /* space and shortest possible zone */ + 1)) + return NULL; /* Not enough space even for the shortest form. */ + if (t <= 0 || t == USEC_INFINITY) + return NULL; /* Timestamp is unset */ + + /* Let's not format times with years > 9999 */ + if (t > USEC_TIMESTAMP_FORMATTABLE_MAX) { + assert(l >= STRLEN("--- XXXX-XX-XX XX:XX:XX") + 1); + strcpy(buf, "--- XXXX-XX-XX XX:XX:XX"); + return buf; + } + + sec = (time_t) (t / USEC_PER_SEC); /* Round down */ + + if (!localtime_or_gmtime_r(&sec, &tm, utc)) + return NULL; + + /* Start with the week day */ + assert((size_t) tm.tm_wday < ELEMENTSOF(weekdays)); + memcpy(buf, weekdays[tm.tm_wday], 4); + + /* Add the main components */ + if (strftime(buf + 3, l - 3, " %Y-%m-%d %H:%M:%S", &tm) <= 0) + return NULL; /* Doesn't fit */ + + /* Append the microseconds part, if that's requested */ + if (us) { + n = strlen(buf); + if (n + 8 > l) + return NULL; /* Microseconds part doesn't fit. */ + + sprintf(buf + n, ".%06"PRI_USEC, t % USEC_PER_SEC); + } + + /* Append the timezone */ + n = strlen(buf); + if (utc) { + /* If this is UTC then let's explicitly use the "UTC" string here, because gmtime_r() normally uses the + * obsolete "GMT" instead. */ + if (n + 5 > l) + return NULL; /* "UTC" doesn't fit. */ + + strcpy(buf + n, " UTC"); + + } else if (!isempty(tm.tm_zone)) { + size_t tn; + + /* An explicit timezone is specified, let's use it, if it fits */ + tn = strlen(tm.tm_zone); + if (n + 1 + tn + 1 > l) { + /* The full time zone does not fit in. Yuck. */ + + if (n + 1 + _POSIX_TZNAME_MAX + 1 > l) + return NULL; /* Not even enough space for the POSIX minimum (of 6)? In that case, complain that it doesn't fit */ + + /* So the time zone doesn't fit in fully, but the caller passed enough space for the POSIX + * minimum time zone length. In this case suppress the timezone entirely, in order not to dump + * an overly long, hard to read string on the user. This should be safe, because the user will + * assume the local timezone anyway if none is shown. And so does parse_timestamp(). */ + } else { + buf[n++] = ' '; + strcpy(buf + n, tm.tm_zone); + } + } + + return buf; +} + +char *format_timestamp_relative(char *buf, size_t l, usec_t t) { + const char *s; + usec_t n, d; + + if (t <= 0 || t == USEC_INFINITY) + return NULL; + + n = now(CLOCK_REALTIME); + if (n > t) { + d = n - t; + s = "ago"; + } else { + d = t - n; + s = "left"; + } + + if (d >= USEC_PER_YEAR) + snprintf(buf, l, USEC_FMT " years " USEC_FMT " months %s", + d / USEC_PER_YEAR, + (d % USEC_PER_YEAR) / USEC_PER_MONTH, s); + else if (d >= USEC_PER_MONTH) + snprintf(buf, l, USEC_FMT " months " USEC_FMT " days %s", + d / USEC_PER_MONTH, + (d % USEC_PER_MONTH) / USEC_PER_DAY, s); + else if (d >= USEC_PER_WEEK) + snprintf(buf, l, USEC_FMT " weeks " USEC_FMT " days %s", + d / USEC_PER_WEEK, + (d % USEC_PER_WEEK) / USEC_PER_DAY, s); + else if (d >= 2*USEC_PER_DAY) + snprintf(buf, l, USEC_FMT " days %s", d / USEC_PER_DAY, s); + else if (d >= 25*USEC_PER_HOUR) + snprintf(buf, l, "1 day " USEC_FMT "h %s", + (d - USEC_PER_DAY) / USEC_PER_HOUR, s); + else if (d >= 6*USEC_PER_HOUR) + snprintf(buf, l, USEC_FMT "h %s", + d / USEC_PER_HOUR, s); + else if (d >= USEC_PER_HOUR) + snprintf(buf, l, USEC_FMT "h " USEC_FMT "min %s", + d / USEC_PER_HOUR, + (d % USEC_PER_HOUR) / USEC_PER_MINUTE, s); + else if (d >= 5*USEC_PER_MINUTE) + snprintf(buf, l, USEC_FMT "min %s", + d / USEC_PER_MINUTE, s); + else if (d >= USEC_PER_MINUTE) + snprintf(buf, l, USEC_FMT "min " USEC_FMT "s %s", + d / USEC_PER_MINUTE, + (d % USEC_PER_MINUTE) / USEC_PER_SEC, s); + else if (d >= USEC_PER_SEC) + snprintf(buf, l, USEC_FMT "s %s", + d / USEC_PER_SEC, s); + else if (d >= USEC_PER_MSEC) + snprintf(buf, l, USEC_FMT "ms %s", + d / USEC_PER_MSEC, s); + else if (d > 0) + snprintf(buf, l, USEC_FMT"us %s", + d, s); + else + snprintf(buf, l, "now"); + + buf[l-1] = 0; + return buf; +} +#endif /* NM_IGNORED */ + +char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { + static const struct { + const char *suffix; + usec_t usec; + } table[] = { + { "y", USEC_PER_YEAR }, + { "month", USEC_PER_MONTH }, + { "w", USEC_PER_WEEK }, + { "d", USEC_PER_DAY }, + { "h", USEC_PER_HOUR }, + { "min", USEC_PER_MINUTE }, + { "s", USEC_PER_SEC }, + { "ms", USEC_PER_MSEC }, + { "us", 1 }, + }; + + size_t i; + char *p = buf; + bool something = false; + + assert(buf); + assert(l > 0); + + if (t == USEC_INFINITY) { + strncpy(p, "infinity", l-1); + p[l-1] = 0; + return p; + } + + if (t <= 0) { + strncpy(p, "0", l-1); + p[l-1] = 0; + return p; + } + + /* The result of this function can be parsed with parse_sec */ + + for (i = 0; i < ELEMENTSOF(table); i++) { + int k = 0; + size_t n; + bool done = false; + usec_t a, b; + + if (t <= 0) + break; + + if (t < accuracy && something) + break; + + if (t < table[i].usec) + continue; + + if (l <= 1) + break; + + a = t / table[i].usec; + b = t % table[i].usec; + + /* Let's see if we should shows this in dot notation */ + if (t < USEC_PER_MINUTE && b > 0) { + usec_t cc; + signed char j; + + j = 0; + for (cc = table[i].usec; cc > 1; cc /= 10) + j++; + + for (cc = accuracy; cc > 1; cc /= 10) { + b /= 10; + j--; + } + + if (j > 0) { + k = snprintf(p, l, + "%s"USEC_FMT".%0*"PRI_USEC"%s", + p > buf ? " " : "", + a, + j, + b, + table[i].suffix); + + t = 0; + done = true; + } + } + + /* No? Then let's show it normally */ + if (!done) { + k = snprintf(p, l, + "%s"USEC_FMT"%s", + p > buf ? " " : "", + a, + table[i].suffix); + + t = b; + } + + n = MIN((size_t) k, l); + + l -= n; + p += n; + + something = true; + } + + *p = 0; + + return buf; +} + +#if 0 /* NM_IGNORED */ +static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) { + static const struct { + const char *name; + const int nr; + } day_nr[] = { + { "Sunday", 0 }, + { "Sun", 0 }, + { "Monday", 1 }, + { "Mon", 1 }, + { "Tuesday", 2 }, + { "Tue", 2 }, + { "Wednesday", 3 }, + { "Wed", 3 }, + { "Thursday", 4 }, + { "Thu", 4 }, + { "Friday", 5 }, + { "Fri", 5 }, + { "Saturday", 6 }, + { "Sat", 6 }, + }; + + const char *k, *utc = NULL, *tzn = NULL; + struct tm tm, copy; + time_t x; + usec_t x_usec, plus = 0, minus = 0, ret; + int r, weekday = -1, dst = -1; + size_t i; + + /* Allowed syntaxes: + * + * 2012-09-22 16:34:22 + * 2012-09-22 16:34 (seconds will be set to 0) + * 2012-09-22 (time will be set to 00:00:00) + * 16:34:22 (date will be set to today) + * 16:34 (date will be set to today, seconds to 0) + * now + * yesterday (time is set to 00:00:00) + * today (time is set to 00:00:00) + * tomorrow (time is set to 00:00:00) + * +5min + * -5days + * @2147483647 (seconds since epoch) + */ + + assert(t); + + if (t[0] == '@' && !with_tz) + return parse_sec(t + 1, usec); + + ret = now(CLOCK_REALTIME); + + if (!with_tz) { + if (streq(t, "now")) + goto finish; + + else if (t[0] == '+') { + r = parse_sec(t+1, &plus); + if (r < 0) + return r; + + goto finish; + + } else if (t[0] == '-') { + r = parse_sec(t+1, &minus); + if (r < 0) + return r; + + goto finish; + + } else if ((k = endswith(t, " ago"))) { + t = strndupa(t, k - t); + + r = parse_sec(t, &minus); + if (r < 0) + return r; + + goto finish; + + } else if ((k = endswith(t, " left"))) { + t = strndupa(t, k - t); + + r = parse_sec(t, &plus); + if (r < 0) + return r; + + goto finish; + } + + /* See if the timestamp is suffixed with UTC */ + utc = endswith_no_case(t, " UTC"); + if (utc) + t = strndupa(t, utc - t); + else { + const char *e = NULL; + int j; + + tzset(); + + /* See if the timestamp is suffixed by either the DST or non-DST local timezone. Note that we only + * support the local timezones here, nothing else. Not because we wouldn't want to, but simply because + * there are no nice APIs available to cover this. By accepting the local time zone strings, we make + * sure that all timestamps written by format_timestamp() can be parsed correctly, even though we don't + * support arbitrary timezone specifications. */ + + for (j = 0; j <= 1; j++) { + + if (isempty(tzname[j])) + continue; + + e = endswith_no_case(t, tzname[j]); + if (!e) + continue; + if (e == t) + continue; + if (e[-1] != ' ') + continue; + + break; + } + + if (IN_SET(j, 0, 1)) { + /* Found one of the two timezones specified. */ + t = strndupa(t, e - t - 1); + dst = j; + tzn = tzname[j]; + } + } + } + + x = (time_t) (ret / USEC_PER_SEC); + x_usec = 0; + + if (!localtime_or_gmtime_r(&x, &tm, utc)) + return -EINVAL; + + tm.tm_isdst = dst; + if (!with_tz && tzn) + tm.tm_zone = tzn; + + if (streq(t, "today")) { + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto from_tm; + + } else if (streq(t, "yesterday")) { + tm.tm_mday--; + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto from_tm; + + } else if (streq(t, "tomorrow")) { + tm.tm_mday++; + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto from_tm; + } + + for (i = 0; i < ELEMENTSOF(day_nr); i++) { + size_t skip; + + if (!startswith_no_case(t, day_nr[i].name)) + continue; + + skip = strlen(day_nr[i].name); + if (t[skip] != ' ') + continue; + + weekday = day_nr[i].nr; + t += skip + 1; + break; + } + + copy = tm; + k = strptime(t, "%y-%m-%d %H:%M:%S", &tm); + if (k) { + if (*k == '.') + goto parse_usec; + else if (*k == 0) + goto from_tm; + } + + tm = copy; + k = strptime(t, "%Y-%m-%d %H:%M:%S", &tm); + if (k) { + if (*k == '.') + goto parse_usec; + else if (*k == 0) + goto from_tm; + } + + tm = copy; + k = strptime(t, "%y-%m-%d %H:%M", &tm); + if (k && *k == 0) { + tm.tm_sec = 0; + goto from_tm; + } + + tm = copy; + k = strptime(t, "%Y-%m-%d %H:%M", &tm); + if (k && *k == 0) { + tm.tm_sec = 0; + goto from_tm; + } + + tm = copy; + k = strptime(t, "%y-%m-%d", &tm); + if (k && *k == 0) { + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto from_tm; + } + + tm = copy; + k = strptime(t, "%Y-%m-%d", &tm); + if (k && *k == 0) { + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto from_tm; + } + + tm = copy; + k = strptime(t, "%H:%M:%S", &tm); + if (k) { + if (*k == '.') + goto parse_usec; + else if (*k == 0) + goto from_tm; + } + + tm = copy; + k = strptime(t, "%H:%M", &tm); + if (k && *k == 0) { + tm.tm_sec = 0; + goto from_tm; + } + + return -EINVAL; + +parse_usec: + { + unsigned add; + + k++; + r = parse_fractional_part_u(&k, 6, &add); + if (r < 0) + return -EINVAL; + + if (*k) + return -EINVAL; + + x_usec = add; + } + +from_tm: + if (weekday >= 0 && tm.tm_wday != weekday) + return -EINVAL; + + x = mktime_or_timegm(&tm, utc); + if (x < 0) + return -EINVAL; + + ret = (usec_t) x * USEC_PER_SEC + x_usec; + if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX) + return -EINVAL; + +finish: + if (ret + plus < ret) /* overflow? */ + return -EINVAL; + ret += plus; + if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX) + return -EINVAL; + + if (ret >= minus) + ret -= minus; + else + return -EINVAL; + + if (usec) + *usec = ret; + return 0; +} + +typedef struct ParseTimestampResult { + usec_t usec; + int return_value; +} ParseTimestampResult; + +int parse_timestamp(const char *t, usec_t *usec) { + char *last_space, *tz = NULL; + ParseTimestampResult *shared, tmp; + int r; + + last_space = strrchr(t, ' '); + if (last_space != NULL && timezone_is_valid(last_space + 1, LOG_DEBUG)) + tz = last_space + 1; + + if (!tz || endswith_no_case(t, " UTC")) + return parse_timestamp_impl(t, usec, false); + + shared = mmap(NULL, sizeof *shared, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); + if (shared == MAP_FAILED) + return negative_errno(); + + r = safe_fork("(sd-timestamp)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT, NULL); + if (r < 0) { + (void) munmap(shared, sizeof *shared); + return r; + } + if (r == 0) { + bool with_tz = true; + char *colon_tz; + + /* tzset(3) says $TZ should be prefixed with ":" if we reference timezone files */ + colon_tz = strjoina(":", tz); + + if (setenv("TZ", colon_tz, 1) != 0) { + shared->return_value = negative_errno(); + _exit(EXIT_FAILURE); + } + + tzset(); + + /* If there is a timezone that matches the tzname fields, leave the parsing to the implementation. + * Otherwise just cut it off. */ + with_tz = !STR_IN_SET(tz, tzname[0], tzname[1]); + + /* Cut off the timezone if we don't need it. */ + if (with_tz) + t = strndupa(t, last_space - t); + + shared->return_value = parse_timestamp_impl(t, &shared->usec, with_tz); + + _exit(EXIT_SUCCESS); + } + + tmp = *shared; + if (munmap(shared, sizeof *shared) != 0) + return negative_errno(); + + if (tmp.return_value == 0 && usec) + *usec = tmp.usec; + + return tmp.return_value; +} + +static const char* extract_multiplier(const char *p, usec_t *multiplier) { + static const struct { + const char *suffix; + usec_t usec; + } table[] = { + { "seconds", USEC_PER_SEC }, + { "second", USEC_PER_SEC }, + { "sec", USEC_PER_SEC }, + { "s", USEC_PER_SEC }, + { "minutes", USEC_PER_MINUTE }, + { "minute", USEC_PER_MINUTE }, + { "min", USEC_PER_MINUTE }, + { "months", USEC_PER_MONTH }, + { "month", USEC_PER_MONTH }, + { "M", USEC_PER_MONTH }, + { "msec", USEC_PER_MSEC }, + { "ms", USEC_PER_MSEC }, + { "m", USEC_PER_MINUTE }, + { "hours", USEC_PER_HOUR }, + { "hour", USEC_PER_HOUR }, + { "hr", USEC_PER_HOUR }, + { "h", USEC_PER_HOUR }, + { "days", USEC_PER_DAY }, + { "day", USEC_PER_DAY }, + { "d", USEC_PER_DAY }, + { "weeks", USEC_PER_WEEK }, + { "week", USEC_PER_WEEK }, + { "w", USEC_PER_WEEK }, + { "years", USEC_PER_YEAR }, + { "year", USEC_PER_YEAR }, + { "y", USEC_PER_YEAR }, + { "usec", 1ULL }, + { "us", 1ULL }, + { "µs", 1ULL }, + }; + size_t i; + + for (i = 0; i < ELEMENTSOF(table); i++) { + char *e; + + e = startswith(p, table[i].suffix); + if (e) { + *multiplier = table[i].usec; + return e; + } + } + + return p; +} + +int parse_time(const char *t, usec_t *usec, usec_t default_unit) { + const char *p, *s; + usec_t r = 0; + bool something = false; + + assert(t); + assert(default_unit > 0); + + p = t; + + p += strspn(p, WHITESPACE); + s = startswith(p, "infinity"); + if (s) { + s += strspn(s, WHITESPACE); + if (*s != 0) + return -EINVAL; + + if (usec) + *usec = USEC_INFINITY; + return 0; + } + + for (;;) { + usec_t multiplier = default_unit, k; + long long l; + char *e; + + p += strspn(p, WHITESPACE); + + if (*p == 0) { + if (!something) + return -EINVAL; + + break; + } + + if (*p == '-') /* Don't allow "-0" */ + return -ERANGE; + + errno = 0; + l = strtoll(p, &e, 10); + if (errno > 0) + return -errno; + if (l < 0) + return -ERANGE; + + if (*e == '.') { + p = e + 1; + p += strspn(p, DIGITS); + } else if (e == p) + return -EINVAL; + else + p = e; + + s = extract_multiplier(p + strspn(p, WHITESPACE), &multiplier); + if (s == p && *s != '\0') + /* Don't allow '12.34.56', but accept '12.34 .56' or '12.34s.56'*/ + return -EINVAL; + + p = s; + + if ((usec_t) l >= USEC_INFINITY / multiplier) + return -ERANGE; + + k = (usec_t) l * multiplier; + if (k >= USEC_INFINITY - r) + return -ERANGE; + + r += k; + + something = true; + + if (*e == '.') { + usec_t m = multiplier / 10; + const char *b; + + for (b = e + 1; *b >= '0' && *b <= '9'; b++, m /= 10) { + k = (usec_t) (*b - '0') * m; + if (k >= USEC_INFINITY - r) + return -ERANGE; + + r += k; + } + + /* Don't allow "0.-0", "3.+1", "3. 1", "3.sec" or "3.hoge"*/ + if (b == e + 1) + return -EINVAL; + } + } + + if (usec) + *usec = r; + return 0; +} + +int parse_sec(const char *t, usec_t *usec) { + return parse_time(t, usec, USEC_PER_SEC); +} + +int parse_sec_fix_0(const char *t, usec_t *ret) { + usec_t k; + int r; + + assert(t); + assert(ret); + + r = parse_sec(t, &k); + if (r < 0) + return r; + + *ret = k == 0 ? USEC_INFINITY : k; + return r; +} + +int parse_sec_def_infinity(const char *t, usec_t *ret) { + t += strspn(t, WHITESPACE); + if (isempty(t)) { + *ret = USEC_INFINITY; + return 0; + } + return parse_sec(t, ret); +} + +static const char* extract_nsec_multiplier(const char *p, nsec_t *multiplier) { + static const struct { + const char *suffix; + nsec_t nsec; + } table[] = { + { "seconds", NSEC_PER_SEC }, + { "second", NSEC_PER_SEC }, + { "sec", NSEC_PER_SEC }, + { "s", NSEC_PER_SEC }, + { "minutes", NSEC_PER_MINUTE }, + { "minute", NSEC_PER_MINUTE }, + { "min", NSEC_PER_MINUTE }, + { "months", NSEC_PER_MONTH }, + { "month", NSEC_PER_MONTH }, + { "M", NSEC_PER_MONTH }, + { "msec", NSEC_PER_MSEC }, + { "ms", NSEC_PER_MSEC }, + { "m", NSEC_PER_MINUTE }, + { "hours", NSEC_PER_HOUR }, + { "hour", NSEC_PER_HOUR }, + { "hr", NSEC_PER_HOUR }, + { "h", NSEC_PER_HOUR }, + { "days", NSEC_PER_DAY }, + { "day", NSEC_PER_DAY }, + { "d", NSEC_PER_DAY }, + { "weeks", NSEC_PER_WEEK }, + { "week", NSEC_PER_WEEK }, + { "w", NSEC_PER_WEEK }, + { "years", NSEC_PER_YEAR }, + { "year", NSEC_PER_YEAR }, + { "y", NSEC_PER_YEAR }, + { "usec", NSEC_PER_USEC }, + { "us", NSEC_PER_USEC }, + { "µs", NSEC_PER_USEC }, + { "nsec", 1ULL }, + { "ns", 1ULL }, + { "", 1ULL }, /* default is nsec */ + }; + size_t i; + + for (i = 0; i < ELEMENTSOF(table); i++) { + char *e; + + e = startswith(p, table[i].suffix); + if (e) { + *multiplier = table[i].nsec; + return e; + } + } + + return p; +} + +int parse_nsec(const char *t, nsec_t *nsec) { + const char *p, *s; + nsec_t r = 0; + bool something = false; + + assert(t); + assert(nsec); + + p = t; + + p += strspn(p, WHITESPACE); + s = startswith(p, "infinity"); + if (s) { + s += strspn(s, WHITESPACE); + if (*s != 0) + return -EINVAL; + + *nsec = NSEC_INFINITY; + return 0; + } + + for (;;) { + nsec_t multiplier = 1, k; + long long l; + char *e; + + p += strspn(p, WHITESPACE); + + if (*p == 0) { + if (!something) + return -EINVAL; + + break; + } + + if (*p == '-') /* Don't allow "-0" */ + return -ERANGE; + + errno = 0; + l = strtoll(p, &e, 10); + if (errno > 0) + return -errno; + if (l < 0) + return -ERANGE; + + if (*e == '.') { + p = e + 1; + p += strspn(p, DIGITS); + } else if (e == p) + return -EINVAL; + else + p = e; + + s = extract_nsec_multiplier(p + strspn(p, WHITESPACE), &multiplier); + if (s == p && *s != '\0') + /* Don't allow '12.34.56', but accept '12.34 .56' or '12.34s.56'*/ + return -EINVAL; + + p = s; + + if ((nsec_t) l >= NSEC_INFINITY / multiplier) + return -ERANGE; + + k = (nsec_t) l * multiplier; + if (k >= NSEC_INFINITY - r) + return -ERANGE; + + r += k; + + something = true; + + if (*e == '.') { + nsec_t m = multiplier / 10; + const char *b; + + for (b = e + 1; *b >= '0' && *b <= '9'; b++, m /= 10) { + k = (nsec_t) (*b - '0') * m; + if (k >= NSEC_INFINITY - r) + return -ERANGE; + + r += k; + } + + /* Don't allow "0.-0", "3.+1", "3. 1", "3.sec" or "3.hoge"*/ + if (b == e + 1) + return -EINVAL; + } + } + + *nsec = r; + + return 0; +} + +bool ntp_synced(void) { + struct timex txc = {}; + + if (adjtimex(&txc) < 0) + return false; + + /* Consider the system clock synchronized if the reported maximum error is smaller than the maximum + * value (16 seconds). Ignore the STA_UNSYNC flag as it may have been set to prevent the kernel from + * touching the RTC. */ + if (txc.maxerror >= 16000000) + return false; + + return true; +} + +int get_timezones(char ***ret) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_strv_free_ char **zones = NULL; + size_t n_zones = 0, n_allocated = 0; + int r; + + assert(ret); + + zones = strv_new("UTC"); + if (!zones) + return -ENOMEM; + + n_allocated = 2; + n_zones = 1; + + f = fopen("/usr/share/zoneinfo/zone1970.tab", "re"); + if (f) { + for (;;) { + _cleanup_free_ char *line = NULL; + char *p, *w; + size_t k; + + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) + break; + + p = strstrip(line); + + if (isempty(p) || *p == '#') + continue; + + /* Skip over country code */ + p += strcspn(p, WHITESPACE); + p += strspn(p, WHITESPACE); + + /* Skip over coordinates */ + p += strcspn(p, WHITESPACE); + p += strspn(p, WHITESPACE); + + /* Found timezone name */ + k = strcspn(p, WHITESPACE); + if (k <= 0) + continue; + + w = strndup(p, k); + if (!w) + return -ENOMEM; + + if (!GREEDY_REALLOC(zones, n_allocated, n_zones + 2)) { + free(w); + return -ENOMEM; + } + + zones[n_zones++] = w; + zones[n_zones] = NULL; + } + + strv_sort(zones); + strv_uniq(zones); + + } else if (errno != ENOENT) + return -errno; + + *ret = TAKE_PTR(zones); + + return 0; +} +#endif /* NM_IGNORED */ + +bool timezone_is_valid(const char *name, int log_level) { + bool slash = false; + const char *p, *t; + _cleanup_close_ int fd = -1; + char buf[4]; + int r; + + if (isempty(name)) + return false; + + /* Always accept "UTC" as valid timezone, since it's the fallback, even if user has no timezones installed. */ + if (streq(name, "UTC")) + return true; + + if (name[0] == '/') + return false; + + for (p = name; *p; p++) { + if (!(*p >= '0' && *p <= '9') && + !(*p >= 'a' && *p <= 'z') && + !(*p >= 'A' && *p <= 'Z') && + !IN_SET(*p, '-', '_', '+', '/')) + return false; + + if (*p == '/') { + + if (slash) + return false; + + slash = true; + } else + slash = false; + } + + if (slash) + return false; + + if (p - name >= PATH_MAX) + return false; + + t = strjoina("/usr/share/zoneinfo/", name); + + fd = open(t, O_RDONLY|O_CLOEXEC); + if (fd < 0) { + log_full_errno(log_level, errno, "Failed to open timezone file '%s': %m", t); + return false; + } + + r = fd_verify_regular(fd); + if (r < 0) { + log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t); + return false; + } + + r = loop_read_exact(fd, buf, 4, false); + if (r < 0) { + log_full_errno(log_level, r, "Failed to read from timezone file '%s': %m", t); + return false; + } + + /* Magic from tzfile(5) */ + if (memcmp(buf, "TZif", 4) != 0) { + log_full(log_level, "Timezone file '%s' has wrong magic bytes", t); + return false; + } + + return true; +} + +bool clock_boottime_supported(void) { + static int supported = -1; + + /* Note that this checks whether CLOCK_BOOTTIME is available in general as well as available for timerfds()! */ + + if (supported < 0) { + int fd; + + fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC); + if (fd < 0) + supported = false; + else { + safe_close(fd); + supported = true; + } + } + + return supported; +} + +clockid_t clock_boottime_or_monotonic(void) { + if (clock_boottime_supported()) + return CLOCK_BOOTTIME; + else + return CLOCK_MONOTONIC; +} + +bool clock_supported(clockid_t clock) { + struct timespec ts; + + switch (clock) { + + case CLOCK_MONOTONIC: + case CLOCK_REALTIME: + return true; + + case CLOCK_BOOTTIME: + return clock_boottime_supported(); + + case CLOCK_BOOTTIME_ALARM: + if (!clock_boottime_supported()) + return false; + + _fallthrough_; + default: + /* For everything else, check properly */ + return clock_gettime(clock, &ts) >= 0; + } +} + +#if 0 /* NM_IGNORED */ +int get_timezone(char **ret) { + _cleanup_free_ char *t = NULL; + const char *e; + char *z; + int r; + + r = readlink_malloc("/etc/localtime", &t); + if (r == -ENOENT) { + /* If the symlink does not exist, assume "UTC", like glibc does*/ + z = strdup("UTC"); + if (!z) + return -ENOMEM; + + *ret = z; + return 0; + } + if (r < 0) + return r; /* returns EINVAL if not a symlink */ + + e = PATH_STARTSWITH_SET(t, "/usr/share/zoneinfo/", "../usr/share/zoneinfo/"); + if (!e) + return -EINVAL; + + if (!timezone_is_valid(e, LOG_DEBUG)) + return -EINVAL; + + z = strdup(e); + if (!z) + return -ENOMEM; + + *ret = z; + return 0; +} + +time_t mktime_or_timegm(struct tm *tm, bool utc) { + return utc ? timegm(tm) : mktime(tm); +} + +struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc) { + return utc ? gmtime_r(t, tm) : localtime_r(t, tm); +} + +static uint32_t sysconf_clock_ticks_cached(void) { + static thread_local uint32_t hz = 0; + long r; + + if (hz == 0) { + r = sysconf(_SC_CLK_TCK); + + assert(r > 0); + hz = r; + } + + return hz; +} + +uint32_t usec_to_jiffies(usec_t u) { + uint32_t hz = sysconf_clock_ticks_cached(); + return DIV_ROUND_UP(u, USEC_PER_SEC / hz); +} + +usec_t jiffies_to_usec(uint32_t j) { + uint32_t hz = sysconf_clock_ticks_cached(); + return DIV_ROUND_UP(j * USEC_PER_SEC, hz); +} + +usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) { + usec_t a, b; + + if (x == USEC_INFINITY) + return USEC_INFINITY; + if (map_clock_id(from) == map_clock_id(to)) + return x; + + a = now(from); + b = now(to); + + if (x > a) + /* x lies in the future */ + return usec_add(b, usec_sub_unsigned(x, a)); + else + /* x lies in the past */ + return usec_sub_unsigned(b, usec_sub_unsigned(a, x)); +} + +bool in_utc_timezone(void) { + tzset(); + + return timezone == 0 && daylight == 0; +} + +int time_change_fd(void) { + + /* We only care for the cancellation event, hence we set the timeout to the latest possible value. */ + static const struct itimerspec its = { + .it_value.tv_sec = TIME_T_MAX, + }; + + _cleanup_close_ int fd; + + assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX)); + + /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever CLOCK_REALTIME makes a jump relative to + * CLOCK_MONOTONIC. */ + + fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC); + if (fd < 0) + return -errno; + + if (timerfd_settime(fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) >= 0) + return TAKE_FD(fd); + + /* So apparently there are systems where time_t is 64bit, but the kernel actually doesn't support + * 64bit time_t. In that case configuring a timer to TIME_T_MAX will fail with EOPNOTSUPP or a + * similar error. If that's the case let's try with INT32_MAX instead, maybe that works. It's a bit + * of a black magic thing though, but what can we do? + * + * We don't want this code on x86-64, hence let's conditionalize this for systems with 64bit time_t + * but where "long" is shorter than 64bit, i.e. 32bit archs. + * + * See: https://github.com/systemd/systemd/issues/14362 */ + +#if SIZEOF_TIME_T == 8 && ULONG_MAX < UINT64_MAX + if (ERRNO_IS_NOT_SUPPORTED(errno) || errno == EOVERFLOW) { + static const struct itimerspec its32 = { + .it_value.tv_sec = INT32_MAX, + }; + + if (timerfd_settime(fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its32, NULL) >= 0) + return TAKE_FD(fd); + } +#endif + + return -errno; +} + +static const char* const timestamp_style_table[_TIMESTAMP_STYLE_MAX] = { + [TIMESTAMP_PRETTY] = "pretty", + [TIMESTAMP_US] = "us", + [TIMESTAMP_UTC] = "utc", + [TIMESTAMP_US_UTC] = "us+utc", +}; + +/* Use the macro for enum → string to allow for aliases */ +_DEFINE_STRING_TABLE_LOOKUP_TO_STRING(timestamp_style, TimestampStyle,); + +/* For the string → enum mapping we use the generic implementation, but also support two aliases */ +TimestampStyle timestamp_style_from_string(const char *s) { + TimestampStyle t; + + t = (TimestampStyle) string_table_lookup(timestamp_style_table, ELEMENTSOF(timestamp_style_table), s); + if (t >= 0) + return t; + if (streq_ptr(s, "µs")) + return TIMESTAMP_US; + if (streq_ptr(s, "µs+utc")) + return TIMESTAMP_US_UTC; + return t; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/time-util.h b/src/libnm-systemd-shared/src/basic/time-util.h new file mode 100644 index 0000000..89ee8b4 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/time-util.h @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include +#include +#include + +typedef uint64_t usec_t; +typedef uint64_t nsec_t; + +#define PRI_NSEC PRIu64 +#define PRI_USEC PRIu64 +#define NSEC_FMT "%" PRI_NSEC +#define USEC_FMT "%" PRI_USEC + +#include "macro.h" + +typedef struct dual_timestamp { + usec_t realtime; + usec_t monotonic; +} dual_timestamp; + +typedef struct triple_timestamp { + usec_t realtime; + usec_t monotonic; + usec_t boottime; +} triple_timestamp; + +typedef enum TimestampStyle { + TIMESTAMP_PRETTY, + TIMESTAMP_US, + TIMESTAMP_UTC, + TIMESTAMP_US_UTC, + _TIMESTAMP_STYLE_MAX, + _TIMESTAMP_STYLE_INVALID = -1, +} TimestampStyle; + +#define USEC_INFINITY ((usec_t) UINT64_MAX) +#define NSEC_INFINITY ((nsec_t) UINT64_MAX) + +#define MSEC_PER_SEC 1000ULL +#define USEC_PER_SEC ((usec_t) 1000000ULL) +#define USEC_PER_MSEC ((usec_t) 1000ULL) +#define NSEC_PER_SEC ((nsec_t) 1000000000ULL) +#define NSEC_PER_MSEC ((nsec_t) 1000000ULL) +#define NSEC_PER_USEC ((nsec_t) 1000ULL) + +#define USEC_PER_MINUTE ((usec_t) (60ULL*USEC_PER_SEC)) +#define NSEC_PER_MINUTE ((nsec_t) (60ULL*NSEC_PER_SEC)) +#define USEC_PER_HOUR ((usec_t) (60ULL*USEC_PER_MINUTE)) +#define NSEC_PER_HOUR ((nsec_t) (60ULL*NSEC_PER_MINUTE)) +#define USEC_PER_DAY ((usec_t) (24ULL*USEC_PER_HOUR)) +#define NSEC_PER_DAY ((nsec_t) (24ULL*NSEC_PER_HOUR)) +#define USEC_PER_WEEK ((usec_t) (7ULL*USEC_PER_DAY)) +#define NSEC_PER_WEEK ((nsec_t) (7ULL*NSEC_PER_DAY)) +#define USEC_PER_MONTH ((usec_t) (2629800ULL*USEC_PER_SEC)) +#define NSEC_PER_MONTH ((nsec_t) (2629800ULL*NSEC_PER_SEC)) +#define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC)) +#define NSEC_PER_YEAR ((nsec_t) (31557600ULL*NSEC_PER_SEC)) + +/* We assume a maximum timezone length of 6. TZNAME_MAX is not defined on Linux, but glibc internally initializes this + * to 6. Let's rely on that. */ +#define FORMAT_TIMESTAMP_MAX (3U+1U+10U+1U+8U+1U+6U+1U+6U+1U) +#define FORMAT_TIMESTAMP_WIDTH 28U /* when outputting, assume this width */ +#define FORMAT_TIMESTAMP_RELATIVE_MAX 256U +#define FORMAT_TIMESPAN_MAX 64U + +#define TIME_T_MAX (time_t)((UINTMAX_C(1) << ((sizeof(time_t) << 3) - 1)) - 1) + +#define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) {}) +#define TRIPLE_TIMESTAMP_NULL ((struct triple_timestamp) {}) + +usec_t now(clockid_t clock); +nsec_t now_nsec(clockid_t clock); + +usec_t map_clock_usec(usec_t from, clockid_t from_clock, clockid_t to_clock); + +dual_timestamp* dual_timestamp_get(dual_timestamp *ts); +dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u); +dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u); +dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, usec_t u); + +triple_timestamp* triple_timestamp_get(triple_timestamp *ts); +triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u); + +#define DUAL_TIMESTAMP_HAS_CLOCK(clock) \ + IN_SET(clock, CLOCK_REALTIME, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC) + +#define TRIPLE_TIMESTAMP_HAS_CLOCK(clock) \ + IN_SET(clock, CLOCK_REALTIME, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) + +static inline bool timestamp_is_set(usec_t timestamp) { + return timestamp > 0 && timestamp != USEC_INFINITY; +} + +static inline bool dual_timestamp_is_set(const dual_timestamp *ts) { + return timestamp_is_set(ts->realtime) || + timestamp_is_set(ts->monotonic); +} + +static inline bool triple_timestamp_is_set(const triple_timestamp *ts) { + return timestamp_is_set(ts->realtime) || + timestamp_is_set(ts->monotonic) || + timestamp_is_set(ts->boottime); +} + +usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock); + +usec_t timespec_load(const struct timespec *ts) _pure_; +nsec_t timespec_load_nsec(const struct timespec *ts) _pure_; +struct timespec *timespec_store(struct timespec *ts, usec_t u); +struct timespec *timespec_store_nsec(struct timespec *ts, nsec_t n); + +usec_t timeval_load(const struct timeval *tv) _pure_; +struct timeval *timeval_store(struct timeval *tv, usec_t u); + +char *format_timestamp_style(char *buf, size_t l, usec_t t, TimestampStyle style); +char *format_timestamp_relative(char *buf, size_t l, usec_t t); +char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy); + +static inline char *format_timestamp(char *buf, size_t l, usec_t t) { + return format_timestamp_style(buf, l, t, TIMESTAMP_PRETTY); +} + +int parse_timestamp(const char *t, usec_t *usec); + +int parse_sec(const char *t, usec_t *usec); +int parse_sec_fix_0(const char *t, usec_t *usec); +int parse_sec_def_infinity(const char *t, usec_t *usec); +int parse_time(const char *t, usec_t *usec, usec_t default_unit); +int parse_nsec(const char *t, nsec_t *nsec); + +bool ntp_synced(void); + +int get_timezones(char ***l); +bool timezone_is_valid(const char *name, int log_level); + +bool clock_boottime_supported(void); +bool clock_supported(clockid_t clock); +clockid_t clock_boottime_or_monotonic(void); + +usec_t usec_shift_clock(usec_t, clockid_t from, clockid_t to); + +int get_timezone(char **timezone); + +time_t mktime_or_timegm(struct tm *tm, bool utc); +struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc); + +uint32_t usec_to_jiffies(usec_t usec); +usec_t jiffies_to_usec(uint32_t jiffies); + +bool in_utc_timezone(void); + +static inline usec_t usec_add(usec_t a, usec_t b) { + usec_t c; + + /* Adds two time values, and makes sure USEC_INFINITY as input results as USEC_INFINITY in output, and doesn't + * overflow. */ + + c = a + b; + if (c < a || c < b) /* overflow check */ + return USEC_INFINITY; + + return c; +} + +static inline usec_t usec_sub_unsigned(usec_t timestamp, usec_t delta) { + + if (timestamp == USEC_INFINITY) /* Make sure infinity doesn't degrade */ + return USEC_INFINITY; + if (timestamp < delta) + return 0; + + return timestamp - delta; +} + +static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) { + if (delta < 0) + return usec_add(timestamp, (usec_t) (-delta)); + else + return usec_sub_unsigned(timestamp, (usec_t) delta); +} + +#if SIZEOF_TIME_T == 8 +/* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit year + * territory. However, since we want to stay away from this in all timezones we take one day off. */ +#define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 253402214399000000) +#elif SIZEOF_TIME_T == 4 +/* With a 32bit time_t we can't go beyond 2038... */ +#define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 2147483647000000) +#else +#error "Yuck, time_t is neither 4 nor 8 bytes wide?" +#endif + +int time_change_fd(void); + +const char* timestamp_style_to_string(TimestampStyle t) _const_; +TimestampStyle timestamp_style_from_string(const char *s) _pure_; diff --git a/src/libnm-systemd-shared/src/basic/tmpfile-util.c b/src/libnm-systemd-shared/src/basic/tmpfile-util.c new file mode 100644 index 0000000..bbd6a1e --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/tmpfile-util.c @@ -0,0 +1,344 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include + +#include "alloc-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "fs-util.h" +#include "hexdecoct.h" +#include "macro.h" +#include "memfd-util.h" +#include "missing_fcntl.h" +#include "missing_syscall.h" +#include "path-util.h" +#include "process-util.h" +#include "random-util.h" +#include "stdio-util.h" +#include "string-util.h" +#include "tmpfile-util.h" +#include "umask-util.h" + +int fopen_temporary(const char *path, FILE **ret_f, char **ret_temp_path) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *t = NULL; + _cleanup_close_ int fd = -1; + int r; + + if (path) { + r = tempfn_xxxxxx(path, NULL, &t); + if (r < 0) + return r; + } else { + const char *d; + + r = tmp_dir(&d); + if (r < 0) + return r; + + t = path_join(d, "XXXXXX"); + if (!t) + return -ENOMEM; + } + + fd = mkostemp_safe(t); + if (fd < 0) + return -errno; + + /* This assumes that returned FILE object is short-lived and used within the same single-threaded + * context and never shared externally, hence locking is not necessary. */ + + r = take_fdopen_unlocked(&fd, "w", &f); + if (r < 0) { + (void) unlink(t); + return r; + } + + if (ret_f) + *ret_f = TAKE_PTR(f); + + if (ret_temp_path) + *ret_temp_path = TAKE_PTR(t); + + return 0; +} + +/* This is much like mkostemp() but is subject to umask(). */ +int mkostemp_safe(char *pattern) { + int fd = -1; /* avoid false maybe-uninitialized warning */ + + assert(pattern); + + RUN_WITH_UMASK(0077) + fd = mkostemp(pattern, O_CLOEXEC); + if (fd < 0) + return -errno; + + return fd; +} + +#if 0 /* NM_IGNORED */ +int fmkostemp_safe(char *pattern, const char *mode, FILE **ret_f) { + _cleanup_close_ int fd = -1; + FILE *f; + + fd = mkostemp_safe(pattern); + if (fd < 0) + return fd; + + f = take_fdopen(&fd, mode); + if (!f) + return -errno; + + *ret_f = f; + return 0; +} +#endif /* NM_IGNORED */ + +int tempfn_xxxxxx(const char *p, const char *extra, char **ret) { + const char *fn; + char *t; + + assert(ret); + + if (isempty(p)) + return -EINVAL; + if (path_equal(p, "/")) + return -EINVAL; + + /* + * Turns this: + * /foo/bar/waldo + * + * Into this: + * /foo/bar/.#waldoXXXXXX + */ + + fn = basename(p); + if (!filename_is_valid(fn)) + return -EINVAL; + + extra = strempty(extra); + + t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1); + if (!t) + return -ENOMEM; + + strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX"); + + *ret = path_simplify(t, false); + return 0; +} + +#if 0 /* NM_IGNORED */ +int tempfn_random(const char *p, const char *extra, char **ret) { + const char *fn; + char *t, *x; + uint64_t u; + unsigned i; + + assert(ret); + + if (isempty(p)) + return -EINVAL; + if (path_equal(p, "/")) + return -EINVAL; + + /* + * Turns this: + * /foo/bar/waldo + * + * Into this: + * /foo/bar/.#waldobaa2a261115984a9 + */ + + fn = basename(p); + if (!filename_is_valid(fn)) + return -EINVAL; + + extra = strempty(extra); + + t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1); + if (!t) + return -ENOMEM; + + x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn); + + u = random_u64(); + for (i = 0; i < 16; i++) { + *(x++) = hexchar(u & 0xF); + u >>= 4; + } + + *x = 0; + + *ret = path_simplify(t, false); + return 0; +} + +int tempfn_random_child(const char *p, const char *extra, char **ret) { + char *t, *x; + uint64_t u; + unsigned i; + int r; + + assert(ret); + + /* Turns this: + * /foo/bar/waldo + * Into this: + * /foo/bar/waldo/.#3c2b6219aa75d7d0 + */ + + if (!p) { + r = tmp_dir(&p); + if (r < 0) + return r; + } + + extra = strempty(extra); + + t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1); + if (!t) + return -ENOMEM; + + if (isempty(p)) + x = stpcpy(stpcpy(t, ".#"), extra); + else + x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra); + + u = random_u64(); + for (i = 0; i < 16; i++) { + *(x++) = hexchar(u & 0xF); + u >>= 4; + } + + *x = 0; + + *ret = path_simplify(t, false); + return 0; +} + +int open_tmpfile_unlinkable(const char *directory, int flags) { + char *p; + int fd, r; + + if (!directory) { + r = tmp_dir(&directory); + if (r < 0) + return r; + } else if (isempty(directory)) + return -EINVAL; + + /* Returns an unlinked temporary file that cannot be linked into the file system anymore */ + + /* Try O_TMPFILE first, if it is supported */ + fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR); + if (fd >= 0) + return fd; + + /* Fall back to unguessable name + unlinking */ + p = strjoina(directory, "/systemd-tmp-XXXXXX"); + + fd = mkostemp_safe(p); + if (fd < 0) + return fd; + + (void) unlink(p); + + return fd; +} + +int open_tmpfile_linkable(const char *target, int flags, char **ret_path) { + _cleanup_free_ char *tmp = NULL; + int r, fd; + + assert(target); + assert(ret_path); + + /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */ + assert((flags & O_EXCL) == 0); + + /* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – in + * which case "ret_path" will be returned as NULL. If not possible the temporary path name used is returned in + * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */ + + fd = open_parent(target, O_TMPFILE|flags, 0640); + if (fd >= 0) { + *ret_path = NULL; + return fd; + } + + log_debug_errno(fd, "Failed to use O_TMPFILE for %s: %m", target); + + r = tempfn_random(target, NULL, &tmp); + if (r < 0) + return r; + + fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640); + if (fd < 0) + return -errno; + + *ret_path = TAKE_PTR(tmp); + + return fd; +} + +int link_tmpfile(int fd, const char *path, const char *target) { + int r; + + assert(fd >= 0); + assert(target); + + /* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd + * created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported + * on the directory, and renameat2() is used instead. + * + * Note that in both cases we will not replace existing files. This is because linkat() does not support this + * operation currently (renameat2() does), and there is no nice way to emulate this. */ + + if (path) { + r = rename_noreplace(AT_FDCWD, path, AT_FDCWD, target); + if (r < 0) + return r; + } else { + char proc_fd_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1]; + + xsprintf(proc_fd_path, "/proc/self/fd/%i", fd); + + if (linkat(AT_FDCWD, proc_fd_path, AT_FDCWD, target, AT_SYMLINK_FOLLOW) < 0) + return -errno; + } + + return 0; +} + +int mkdtemp_malloc(const char *template, char **ret) { + _cleanup_free_ char *p = NULL; + int r; + + assert(ret); + + if (template) + p = strdup(template); + else { + const char *tmp; + + r = tmp_dir(&tmp); + if (r < 0) + return r; + + p = path_join(tmp, "XXXXXX"); + } + if (!p) + return -ENOMEM; + + if (!mkdtemp(p)) + return -errno; + + *ret = TAKE_PTR(p); + return 0; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/tmpfile-util.h b/src/libnm-systemd-shared/src/basic/tmpfile-util.h new file mode 100644 index 0000000..45255fc --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/tmpfile-util.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +int fopen_temporary(const char *path, FILE **_f, char **_temp_path); +int mkostemp_safe(char *pattern); +int fmkostemp_safe(char *pattern, const char *mode, FILE**_f); + +int tempfn_xxxxxx(const char *p, const char *extra, char **ret); +int tempfn_random(const char *p, const char *extra, char **ret); +int tempfn_random_child(const char *p, const char *extra, char **ret); + +int open_tmpfile_unlinkable(const char *directory, int flags); +int open_tmpfile_linkable(const char *target, int flags, char **ret_path); + +int link_tmpfile(int fd, const char *path, const char *target); + +int mkdtemp_malloc(const char *template, char **ret); diff --git a/src/libnm-systemd-shared/src/basic/umask-util.h b/src/libnm-systemd-shared/src/basic/umask-util.h new file mode 100644 index 0000000..bd7c2bd --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/umask-util.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include + +#include "macro.h" + +static inline void umaskp(mode_t *u) { + umask(*u & 0777); +} + +#define _cleanup_umask_ _cleanup_(umaskp) + +/* We make use of the fact here that the umask() concept is using only the lower 9 bits of mode_t, although + * mode_t has space for the file type in the bits further up. We simply OR in the file type mask S_IFMT to + * distinguish the first and the second iteration of the RUN_WITH_UMASK() loop, so that we can run the first + * one, and exit on the second. */ + +assert_cc((S_IFMT & 0777) == 0); + +#define RUN_WITH_UMASK(mask) \ + for (_cleanup_umask_ mode_t _saved_umask_ = umask(mask) | S_IFMT; \ + FLAGS_SET(_saved_umask_, S_IFMT); \ + _saved_umask_ &= 0777) diff --git a/src/libnm-systemd-shared/src/basic/utf8.c b/src/libnm-systemd-shared/src/basic/utf8.c new file mode 100644 index 0000000..a7679bf --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/utf8.c @@ -0,0 +1,595 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* Parts of this file are based on the GLIB utf8 validation functions. The + * original license text follows. */ + +/* gutf8.c - Operations on UTF-8 strings. + * + * Copyright (C) 1999 Tom Tromey + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include + +#include "alloc-util.h" +#include "gunicode.h" +#include "hexdecoct.h" +#include "macro.h" +#include "string-util.h" +#include "utf8.h" + +bool unichar_is_valid(char32_t ch) { + + if (ch >= 0x110000) /* End of unicode space */ + return false; + if ((ch & 0xFFFFF800) == 0xD800) /* Reserved area for UTF-16 */ + return false; + if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) /* Reserved */ + return false; + if ((ch & 0xFFFE) == 0xFFFE) /* BOM (Byte Order Mark) */ + return false; + + return true; +} + +static bool unichar_is_control(char32_t ch) { + + /* + 0 to ' '-1 is the C0 range. + DEL=0x7F, and DEL+1 to 0x9F is C1 range. + '\t' is in C0 range, but more or less harmless and commonly used. + */ + + return (ch < ' ' && !IN_SET(ch, '\t', '\n')) || + (0x7F <= ch && ch <= 0x9F); +} + +/* count of characters used to encode one unicode char */ +static size_t utf8_encoded_expected_len(uint8_t c) { + if (c < 0x80) + return 1; + if ((c & 0xe0) == 0xc0) + return 2; + if ((c & 0xf0) == 0xe0) + return 3; + if ((c & 0xf8) == 0xf0) + return 4; + if ((c & 0xfc) == 0xf8) + return 5; + if ((c & 0xfe) == 0xfc) + return 6; + + return 0; +} + +/* decode one unicode char */ +int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) { + char32_t unichar; + size_t len, i; + + assert(str); + + len = utf8_encoded_expected_len(str[0]); + + switch (len) { + case 1: + *ret_unichar = (char32_t)str[0]; + return 0; + case 2: + unichar = str[0] & 0x1f; + break; + case 3: + unichar = (char32_t)str[0] & 0x0f; + break; + case 4: + unichar = (char32_t)str[0] & 0x07; + break; + case 5: + unichar = (char32_t)str[0] & 0x03; + break; + case 6: + unichar = (char32_t)str[0] & 0x01; + break; + default: + return -EINVAL; + } + + for (i = 1; i < len; i++) { + if (((char32_t)str[i] & 0xc0) != 0x80) + return -EINVAL; + + unichar <<= 6; + unichar |= (char32_t)str[i] & 0x3f; + } + + *ret_unichar = unichar; + + return 0; +} + +bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newline) { + const char *p; + + assert(str); + + for (p = str; length > 0;) { + int encoded_len, r; + char32_t val; + + encoded_len = utf8_encoded_valid_unichar(p, length); + if (encoded_len < 0) + return false; + assert(encoded_len > 0 && (size_t) encoded_len <= length); + + r = utf8_encoded_to_unichar(p, &val); + if (r < 0 || + unichar_is_control(val) || + (!allow_newline && val == '\n')) + return false; + + length -= encoded_len; + p += encoded_len; + } + + return true; +} + +char *utf8_is_valid_n(const char *str, size_t len_bytes) { + /* Check if the string is composed of valid utf8 characters. If length len_bytes is given, stop after + * len_bytes. Otherwise, stop at NUL. */ + + assert(str); + + for (const char *p = str; len_bytes != (size_t) -1 ? (size_t) (p - str) < len_bytes : *p != '\0'; ) { + int len; + + if (_unlikely_(*p == '\0') && len_bytes != (size_t) -1) + return NULL; /* embedded NUL */ + + len = utf8_encoded_valid_unichar(p, + len_bytes != (size_t) -1 ? len_bytes - (p - str) : (size_t) -1); + if (_unlikely_(len < 0)) + return NULL; /* invalid character */ + + p += len; + } + + return (char*) str; +} + +char *utf8_escape_invalid(const char *str) { + char *p, *s; + + assert(str); + + p = s = malloc(strlen(str) * 4 + 1); + if (!p) + return NULL; + + while (*str) { + int len; + + len = utf8_encoded_valid_unichar(str, (size_t) -1); + if (len > 0) { + s = mempcpy(s, str, len); + str += len; + } else { + s = stpcpy(s, UTF8_REPLACEMENT_CHARACTER); + str += 1; + } + } + + *s = '\0'; + (void) str_realloc(&p); + return p; +} + +#if 0 /* NM_IGNORED */ +static int utf8_char_console_width(const char *str) { + char32_t c; + int r; + + r = utf8_encoded_to_unichar(str, &c); + if (r < 0) + return r; + + /* TODO: we should detect combining characters */ + + return unichar_iswide(c) ? 2 : 1; +} + +char *utf8_escape_non_printable_full(const char *str, size_t console_width) { + char *p, *s, *prev_s; + size_t n = 0; /* estimated print width */ + + assert(str); + + if (console_width == 0) + return strdup(""); + + p = s = prev_s = malloc(strlen(str) * 4 + 1); + if (!p) + return NULL; + + for (;;) { + int len; + char *saved_s = s; + + if (!*str) /* done! */ + goto finish; + + len = utf8_encoded_valid_unichar(str, (size_t) -1); + if (len > 0) { + if (utf8_is_printable(str, len)) { + int w; + + w = utf8_char_console_width(str); + assert(w >= 0); + if (n + w > console_width) + goto truncation; + + s = mempcpy(s, str, len); + str += len; + n += w; + + } else { + for (; len > 0; len--) { + if (n + 4 > console_width) + goto truncation; + + *(s++) = '\\'; + *(s++) = 'x'; + *(s++) = hexchar((int) *str >> 4); + *(s++) = hexchar((int) *str); + + str += 1; + n += 4; + } + } + } else { + if (n + 1 > console_width) + goto truncation; + + s = mempcpy(s, UTF8_REPLACEMENT_CHARACTER, strlen(UTF8_REPLACEMENT_CHARACTER)); + str += 1; + n += 1; + } + + prev_s = saved_s; + } + + truncation: + /* Try to go back one if we don't have enough space for the ellipsis */ + if (n + 1 >= console_width) + s = prev_s; + + s = mempcpy(s, "…", strlen("…")); + + finish: + *s = '\0'; + (void) str_realloc(&p); + return p; +} +#endif /* NM_IGNORED */ + +char *ascii_is_valid(const char *str) { + const char *p; + + /* Check whether the string consists of valid ASCII bytes, + * i.e values between 0 and 127, inclusive. */ + + assert(str); + + for (p = str; *p; p++) + if ((unsigned char) *p >= 128) + return NULL; + + return (char*) str; +} + +#if 0 /* NM_IGNORED */ +char *ascii_is_valid_n(const char *str, size_t len) { + size_t i; + + /* Very similar to ascii_is_valid(), but checks exactly len + * bytes and rejects any NULs in that range. */ + + assert(str); + + for (i = 0; i < len; i++) + if ((unsigned char) str[i] >= 128 || str[i] == 0) + return NULL; + + return (char*) str; +} +#endif /* NM_IGNORED */ + +/** + * utf8_encode_unichar() - Encode single UCS-4 character as UTF-8 + * @out_utf8: output buffer of at least 4 bytes or NULL + * @g: UCS-4 character to encode + * + * This encodes a single UCS-4 character as UTF-8 and writes it into @out_utf8. + * The length of the character is returned. It is not zero-terminated! If the + * output buffer is NULL, only the length is returned. + * + * Returns: The length in bytes that the UTF-8 representation does or would + * occupy. + */ +size_t utf8_encode_unichar(char *out_utf8, char32_t g) { + + if (g < (1 << 7)) { + if (out_utf8) + out_utf8[0] = g & 0x7f; + return 1; + } else if (g < (1 << 11)) { + if (out_utf8) { + out_utf8[0] = 0xc0 | ((g >> 6) & 0x1f); + out_utf8[1] = 0x80 | (g & 0x3f); + } + return 2; + } else if (g < (1 << 16)) { + if (out_utf8) { + out_utf8[0] = 0xe0 | ((g >> 12) & 0x0f); + out_utf8[1] = 0x80 | ((g >> 6) & 0x3f); + out_utf8[2] = 0x80 | (g & 0x3f); + } + return 3; + } else if (g < (1 << 21)) { + if (out_utf8) { + out_utf8[0] = 0xf0 | ((g >> 18) & 0x07); + out_utf8[1] = 0x80 | ((g >> 12) & 0x3f); + out_utf8[2] = 0x80 | ((g >> 6) & 0x3f); + out_utf8[3] = 0x80 | (g & 0x3f); + } + return 4; + } + + return 0; +} + +#if 0 /* NM_IGNORED */ +char *utf16_to_utf8(const char16_t *s, size_t length /* bytes! */) { + const uint8_t *f; + char *r, *t; + + assert(s); + + /* Input length is in bytes, i.e. the shortest possible character takes 2 bytes. Each unicode character may + * take up to 4 bytes in UTF-8. Let's also account for a trailing NUL byte. */ + if (length * 2 < length) + return NULL; /* overflow */ + + r = new(char, length * 2 + 1); + if (!r) + return NULL; + + f = (const uint8_t*) s; + t = r; + + while (f + 1 < (const uint8_t*) s + length) { + char16_t w1, w2; + + /* see RFC 2781 section 2.2 */ + + w1 = f[1] << 8 | f[0]; + f += 2; + + if (!utf16_is_surrogate(w1)) { + t += utf8_encode_unichar(t, w1); + continue; + } + + if (utf16_is_trailing_surrogate(w1)) + continue; /* spurious trailing surrogate, ignore */ + + if (f + 1 >= (const uint8_t*) s + length) + break; + + w2 = f[1] << 8 | f[0]; + f += 2; + + if (!utf16_is_trailing_surrogate(w2)) { + f -= 2; + continue; /* surrogate missing its trailing surrogate, ignore */ + } + + t += utf8_encode_unichar(t, utf16_surrogate_pair_to_unichar(w1, w2)); + } + + *t = 0; + return r; +} + +size_t utf16_encode_unichar(char16_t *out, char32_t c) { + + /* Note that this encodes as little-endian. */ + + switch (c) { + + case 0 ... 0xd7ffU: + case 0xe000U ... 0xffffU: + out[0] = htole16(c); + return 1; + + case 0x10000U ... 0x10ffffU: + c -= 0x10000U; + out[0] = htole16((c >> 10) + 0xd800U); + out[1] = htole16((c & 0x3ffU) + 0xdc00U); + return 2; + + default: /* A surrogate (invalid) */ + return 0; + } +} + +char16_t *utf8_to_utf16(const char *s, size_t length) { + char16_t *n, *p; + size_t i; + int r; + + assert(s); + + n = new(char16_t, length + 1); + if (!n) + return NULL; + + p = n; + + for (i = 0; i < length;) { + char32_t unichar; + size_t e; + + e = utf8_encoded_expected_len(s[i]); + if (e <= 1) /* Invalid and single byte characters are copied as they are */ + goto copy; + + if (i + e > length) /* sequence longer than input buffer, then copy as-is */ + goto copy; + + r = utf8_encoded_to_unichar(s + i, &unichar); + if (r < 0) /* sequence invalid, then copy as-is */ + goto copy; + + p += utf16_encode_unichar(p, unichar); + i += e; + continue; + + copy: + *(p++) = htole16(s[i++]); + } + + *p = 0; + return n; +} + +size_t char16_strlen(const char16_t *s) { + size_t n = 0; + + assert(s); + + while (*s != 0) + n++, s++; + + return n; +} +#endif /* NM_IGNORED */ + +/* expected size used to encode one unicode char */ +static int utf8_unichar_to_encoded_len(char32_t unichar) { + + if (unichar < 0x80) + return 1; + if (unichar < 0x800) + return 2; + if (unichar < 0x10000) + return 3; + if (unichar < 0x200000) + return 4; + if (unichar < 0x4000000) + return 5; + + return 6; +} + +/* validate one encoded unicode char and return its length */ +int utf8_encoded_valid_unichar(const char *str, size_t length /* bytes */) { + char32_t unichar; + size_t len, i; + int r; + + assert(str); + assert(length > 0); + + /* We read until NUL, at most length bytes. (size_t) -1 may be used to disable the length check. */ + + len = utf8_encoded_expected_len(str[0]); + if (len == 0) + return -EINVAL; + + /* Do we have a truncated multi-byte character? */ + if (len > length) + return -EINVAL; + + /* ascii is valid */ + if (len == 1) + return 1; + + /* check if expected encoded chars are available */ + for (i = 0; i < len; i++) + if ((str[i] & 0x80) != 0x80) + return -EINVAL; + + r = utf8_encoded_to_unichar(str, &unichar); + if (r < 0) + return r; + + /* check if encoded length matches encoded value */ + if (utf8_unichar_to_encoded_len(unichar) != (int) len) + return -EINVAL; + + /* check if value has valid range */ + if (!unichar_is_valid(unichar)) + return -EINVAL; + + return (int) len; +} + +#if 0 /* NM_IGNORED */ +size_t utf8_n_codepoints(const char *str) { + size_t n = 0; + + /* Returns the number of UTF-8 codepoints in this string, or (size_t) -1 if the string is not valid UTF-8. */ + + while (*str != 0) { + int k; + + k = utf8_encoded_valid_unichar(str, (size_t) -1); + if (k < 0) + return (size_t) -1; + + str += k; + n++; + } + + return n; +} + +size_t utf8_console_width(const char *str) { + size_t n = 0; + + /* Returns the approximate width a string will take on screen when printed on a character cell + * terminal/console. */ + + while (*str) { + int w; + + w = utf8_char_console_width(str); + if (w < 0) + return (size_t) -1; + + n += w; + str = utf8_next_char(str); + } + + return n; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/utf8.h b/src/libnm-systemd-shared/src/basic/utf8.h new file mode 100644 index 0000000..a6ea942 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/utf8.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include + +#include "macro.h" +#include "missing_type.h" + +#define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd" +#define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf" + +bool unichar_is_valid(char32_t c); + +char *utf8_is_valid_n(const char *str, size_t len_bytes) _pure_; +static inline char *utf8_is_valid(const char *s) { + return utf8_is_valid_n(s, (size_t) -1); +} +char *ascii_is_valid(const char *s) _pure_; +char *ascii_is_valid_n(const char *str, size_t len); + +bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newline) _pure_; +#define utf8_is_printable(str, length) utf8_is_printable_newline(str, length, true) + +char *utf8_escape_invalid(const char *s); +char *utf8_escape_non_printable_full(const char *str, size_t console_width); +static inline char *utf8_escape_non_printable(const char *str) { + return utf8_escape_non_printable_full(str, (size_t) -1); +} + +size_t utf8_encode_unichar(char *out_utf8, char32_t g); +size_t utf16_encode_unichar(char16_t *out, char32_t c); + +char *utf16_to_utf8(const char16_t *s, size_t length /* bytes! */); +char16_t *utf8_to_utf16(const char *s, size_t length); + +size_t char16_strlen(const char16_t *s); /* returns the number of 16bit words in the string (not bytes!) */ + +int utf8_encoded_valid_unichar(const char *str, size_t length); +int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar); + +static inline bool utf16_is_surrogate(char16_t c) { + return c >= 0xd800U && c <= 0xdfffU; +} + +static inline bool utf16_is_trailing_surrogate(char16_t c) { + return c >= 0xdc00U && c <= 0xdfffU; +} + +static inline char32_t utf16_surrogate_pair_to_unichar(char16_t lead, char16_t trail) { + return ((((char32_t) lead - 0xd800U) << 10) + ((char32_t) trail - 0xdc00U) + 0x10000U); +} + +size_t utf8_n_codepoints(const char *str); +size_t utf8_console_width(const char *str); diff --git a/src/libnm-systemd-shared/src/basic/util.c b/src/libnm-systemd-shared/src/basic/util.c new file mode 100644 index 0000000..10a5bcf --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/util.c @@ -0,0 +1,277 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include + +#include "alloc-util.h" +#include "build.h" +#include "dirent-util.h" +#include "env-file.h" +#include "env-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "hostname-util.h" +#include "log.h" +#include "macro.h" +#include "parse-util.h" +#include "stat-util.h" +#include "string-util.h" +#include "util.h" +#include "virt.h" + +#if 0 /* NM_IGNORED */ +int saved_argc = 0; +char **saved_argv = NULL; +static int saved_in_initrd = -1; + +bool kexec_loaded(void) { + _cleanup_free_ char *s = NULL; + + if (read_one_line_file("/sys/kernel/kexec_loaded", &s) < 0) + return false; + + return s[0] == '1'; +} + +int prot_from_flags(int flags) { + + switch (flags & O_ACCMODE) { + + case O_RDONLY: + return PROT_READ; + + case O_WRONLY: + return PROT_WRITE; + + case O_RDWR: + return PROT_READ|PROT_WRITE; + + default: + return -EINVAL; + } +} + +bool in_initrd(void) { + struct statfs s; + int r; + + if (saved_in_initrd >= 0) + return saved_in_initrd; + + /* We make two checks here: + * + * 1. the flag file /etc/initrd-release must exist + * 2. the root file system must be a memory file system + * + * The second check is extra paranoia, since misdetecting an + * initrd can have bad consequences due the initrd + * emptying when transititioning to the main systemd. + */ + + r = getenv_bool_secure("SYSTEMD_IN_INITRD"); + if (r < 0 && r != -ENXIO) + log_debug_errno(r, "Failed to parse $SYSTEMD_IN_INITRD, ignoring: %m"); + + if (r >= 0) + saved_in_initrd = r > 0; + else + saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0 && + statfs("/", &s) >= 0 && + is_temporary_fs(&s); + + return saved_in_initrd; +} + +void in_initrd_force(bool value) { + saved_in_initrd = value; +} + +int on_ac_power(void) { + bool found_offline = false, found_online = false; + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + + d = opendir("/sys/class/power_supply"); + if (!d) + return errno == ENOENT ? true : -errno; + + FOREACH_DIRENT(de, d, return -errno) { + _cleanup_close_ int fd = -1, device = -1; + char contents[6]; + ssize_t n; + + device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (device < 0) { + if (IN_SET(errno, ENOENT, ENOTDIR)) + continue; + + return -errno; + } + + fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + if (errno == ENOENT) + continue; + + return -errno; + } + + n = read(fd, contents, sizeof(contents)); + if (n < 0) + return -errno; + + if (n != 6 || memcmp(contents, "Mains\n", 6)) + continue; + + safe_close(fd); + fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + if (errno == ENOENT) + continue; + + return -errno; + } + + n = read(fd, contents, sizeof(contents)); + if (n < 0) + return -errno; + + if (n != 2 || contents[1] != '\n') + return -EIO; + + if (contents[0] == '1') { + found_online = true; + break; + } else if (contents[0] == '0') + found_offline = true; + else + return -EIO; + } + + return found_online || !found_offline; +} + +int container_get_leader(const char *machine, pid_t *pid) { + _cleanup_free_ char *s = NULL, *class = NULL; + const char *p; + pid_t leader; + int r; + + assert(machine); + assert(pid); + + if (streq(machine, ".host")) { + *pid = 1; + return 0; + } + + if (!hostname_is_valid(machine, 0)) + return -EINVAL; + + p = strjoina("/run/systemd/machines/", machine); + r = parse_env_file(NULL, p, + "LEADER", &s, + "CLASS", &class); + if (r == -ENOENT) + return -EHOSTDOWN; + if (r < 0) + return r; + if (!s) + return -EIO; + + if (!streq_ptr(class, "container")) + return -EIO; + + r = parse_pid(s, &leader); + if (r < 0) + return r; + if (leader <= 1) + return -EIO; + + *pid = leader; + return 0; +} + +int version(void) { + printf("systemd " STRINGIFY(PROJECT_VERSION) " (" GIT_VERSION ")\n%s\n", + systemd_features); + return 0; +} + +/* This is a direct translation of str_verscmp from boot.c */ +static bool is_digit(int c) { + return c >= '0' && c <= '9'; +} + +static int c_order(int c) { + if (c == 0 || is_digit(c)) + return 0; + + if ((c >= 'a') && (c <= 'z')) + return c; + + return c + 0x10000; +} + +int str_verscmp(const char *s1, const char *s2) { + const char *os1, *os2; + + assert(s1); + assert(s2); + + os1 = s1; + os2 = s2; + + while (*s1 || *s2) { + int first; + + while ((*s1 && !is_digit(*s1)) || (*s2 && !is_digit(*s2))) { + int order; + + order = c_order(*s1) - c_order(*s2); + if (order != 0) + return order; + s1++; + s2++; + } + + while (*s1 == '0') + s1++; + while (*s2 == '0') + s2++; + + first = 0; + while (is_digit(*s1) && is_digit(*s2)) { + if (first == 0) + first = *s1 - *s2; + s1++; + s2++; + } + + if (is_digit(*s1)) + return 1; + if (is_digit(*s2)) + return -1; + + if (first != 0) + return first; + } + + return strcmp(os1, os2); +} + +/* Turn off core dumps but only if we're running outside of a container. */ +void disable_coredumps(void) { + int r; + + if (detect_container() > 0) + return; + + r = write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", WRITE_STRING_FILE_DISABLE_BUFFER); + if (r < 0) + log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m"); +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/util.h b/src/libnm-systemd-shared/src/basic/util.h new file mode 100644 index 0000000..942d773 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/util.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#include "macro.h" + +extern int saved_argc; +extern char **saved_argv; + +static inline void save_argc_argv(int argc, char **argv) { + saved_argc = argc; + saved_argv = argv; +} + +bool kexec_loaded(void); + +int prot_from_flags(int flags) _const_; + +bool in_initrd(void); +void in_initrd_force(bool value); + +int on_ac_power(void); + +static inline unsigned u64log2(uint64_t n) { +#if __SIZEOF_LONG_LONG__ == 8 + return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0; +#else +#error "Wut?" +#endif +} + +static inline unsigned u32ctz(uint32_t n) { +#if __SIZEOF_INT__ == 4 + return n != 0 ? __builtin_ctz(n) : 32; +#else +#error "Wut?" +#endif +} + +static inline unsigned log2i(int x) { + assert(x > 0); + + return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1; +} + +static inline unsigned log2u(unsigned x) { + assert(x > 0); + + return sizeof(unsigned) * 8 - __builtin_clz(x) - 1; +} + +static inline unsigned log2u_round_up(unsigned x) { + assert(x > 0); + + if (x == 1) + return 0; + + return log2u(x - 1) + 1; +} + +int container_get_leader(const char *machine, pid_t *pid); + +int version(void); + +int str_verscmp(const char *s1, const char *s2); + +void disable_coredumps(void); diff --git a/src/libnm-systemd-shared/src/shared/dns-domain.c b/src/libnm-systemd-shared/src/shared/dns-domain.c new file mode 100644 index 0000000..95e4a93 --- /dev/null +++ b/src/libnm-systemd-shared/src/shared/dns-domain.c @@ -0,0 +1,1429 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include +#include +#include +#include + +#include "alloc-util.h" +#include "dns-domain.h" +#include "hashmap.h" +#include "hexdecoct.h" +#include "hostname-util.h" +#include "idn-util.h" +#include "in-addr-util.h" +#include "macro.h" +#include "parse-util.h" +#include "string-util.h" +#include "strv.h" +#include "utf8.h" + +int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags) { + const char *n; + char *d, last_char = 0; + int r = 0; + + assert(name); + assert(*name); + + n = *name; + d = dest; + + for (;;) { + if (IN_SET(*n, 0, '.')) { + if (FLAGS_SET(flags, DNS_LABEL_LDH) && last_char == '-') + /* Trailing dash */ + return -EINVAL; + + if (n[0] == '.' && (n[1] != 0 || !FLAGS_SET(flags, DNS_LABEL_LEAVE_TRAILING_DOT))) + n++; + + break; + } + + if (r >= DNS_LABEL_MAX) + return -EINVAL; + + if (sz <= 0) + return -ENOBUFS; + + if (*n == '\\') { + /* Escaped character */ + if (FLAGS_SET(flags, DNS_LABEL_NO_ESCAPES)) + return -EINVAL; + + n++; + + if (*n == 0) + /* Ending NUL */ + return -EINVAL; + + else if (IN_SET(*n, '\\', '.')) { + /* Escaped backslash or dot */ + + if (FLAGS_SET(flags, DNS_LABEL_LDH)) + return -EINVAL; + + last_char = *n; + if (d) + *(d++) = *n; + sz--; + r++; + n++; + + } else if (n[0] >= '0' && n[0] <= '9') { + unsigned k; + + /* Escaped literal ASCII character */ + + if (!(n[1] >= '0' && n[1] <= '9') || + !(n[2] >= '0' && n[2] <= '9')) + return -EINVAL; + + k = ((unsigned) (n[0] - '0') * 100) + + ((unsigned) (n[1] - '0') * 10) + + ((unsigned) (n[2] - '0')); + + /* Don't allow anything that doesn't + * fit in 8bit. Note that we do allow + * control characters, as some servers + * (e.g. cloudflare) are happy to + * generate labels with them + * inside. */ + if (k > 255) + return -EINVAL; + + if (FLAGS_SET(flags, DNS_LABEL_LDH) && + !valid_ldh_char((char) k)) + return -EINVAL; + + last_char = (char) k; + if (d) + *(d++) = (char) k; + sz--; + r++; + + n += 3; + } else + return -EINVAL; + + } else if ((uint8_t) *n >= (uint8_t) ' ' && *n != 127) { + + /* Normal character */ + + if (FLAGS_SET(flags, DNS_LABEL_LDH)) { + if (!valid_ldh_char(*n)) + return -EINVAL; + if (r == 0 && *n == '-') + /* Leading dash */ + return -EINVAL; + } + + last_char = *n; + if (d) + *(d++) = *n; + sz--; + r++; + n++; + } else + return -EINVAL; + } + + /* Empty label that is not at the end? */ + if (r == 0 && *n) + return -EINVAL; + + /* More than one trailing dot? */ + if (n[0] == '.' && !FLAGS_SET(flags, DNS_LABEL_LEAVE_TRAILING_DOT)) + return -EINVAL; + + if (sz >= 1 && d) + *d = 0; + + *name = n; + return r; +} + +#if 0 /* NM_IGNORED */ +/* @label_terminal: terminal character of a label, updated to point to the terminal character of + * the previous label (always skipping one dot) or to NULL if there are no more + * labels. */ +int dns_label_unescape_suffix(const char *name, const char **label_terminal, char *dest, size_t sz) { + const char *terminal; + int r; + + assert(name); + assert(label_terminal); + assert(dest); + + /* no more labels */ + if (!*label_terminal) { + if (sz >= 1) + *dest = 0; + + return 0; + } + + terminal = *label_terminal; + assert(IN_SET(*terminal, 0, '.')); + + /* Skip current terminal character (and accept domain names ending it ".") */ + if (*terminal == 0) + terminal--; + if (terminal >= name && *terminal == '.') + terminal--; + + /* Point name to the last label, and terminal to the preceding terminal symbol (or make it a NULL pointer) */ + for (;;) { + if (terminal < name) { + /* Reached the first label, so indicate that there are no more */ + terminal = NULL; + break; + } + + /* Find the start of the last label */ + if (*terminal == '.') { + const char *y; + unsigned slashes = 0; + + for (y = terminal - 1; y >= name && *y == '\\'; y--) + slashes++; + + if (slashes % 2 == 0) { + /* The '.' was not escaped */ + name = terminal + 1; + break; + } else { + terminal = y; + continue; + } + } + + terminal--; + } + + r = dns_label_unescape(&name, dest, sz, 0); + if (r < 0) + return r; + + *label_terminal = terminal; + + return r; +} +#endif /* NM_IGNORED */ + +int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) { + char *q; + + /* DNS labels must be between 1 and 63 characters long. A + * zero-length label does not exist. See RFC 2182, Section + * 11. */ + + if (l <= 0 || l > DNS_LABEL_MAX) + return -EINVAL; + if (sz < 1) + return -ENOBUFS; + + assert(p); + assert(dest); + + q = dest; + while (l > 0) { + + if (IN_SET(*p, '.', '\\')) { + + /* Dot or backslash */ + + if (sz < 3) + return -ENOBUFS; + + *(q++) = '\\'; + *(q++) = *p; + + sz -= 2; + + } else if (IN_SET(*p, '_', '-') || + (*p >= '0' && *p <= '9') || + (*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z')) { + + /* Proper character */ + + if (sz < 2) + return -ENOBUFS; + + *(q++) = *p; + sz -= 1; + + } else { + + /* Everything else */ + + if (sz < 5) + return -ENOBUFS; + + *(q++) = '\\'; + *(q++) = '0' + (char) ((uint8_t) *p / 100); + *(q++) = '0' + (char) (((uint8_t) *p / 10) % 10); + *(q++) = '0' + (char) ((uint8_t) *p % 10); + + sz -= 4; + } + + p++; + l--; + } + + *q = 0; + return (int) (q - dest); +} + +#if 0 /* NM_IGNORED */ +int dns_label_escape_new(const char *p, size_t l, char **ret) { + _cleanup_free_ char *s = NULL; + int r; + + assert(p); + assert(ret); + + if (l <= 0 || l > DNS_LABEL_MAX) + return -EINVAL; + + s = new(char, DNS_LABEL_ESCAPED_MAX); + if (!s) + return -ENOMEM; + + r = dns_label_escape(p, l, s, DNS_LABEL_ESCAPED_MAX); + if (r < 0) + return r; + + *ret = TAKE_PTR(s); + + return r; +} + +#if HAVE_LIBIDN +int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) { + _cleanup_free_ uint32_t *input = NULL; + size_t input_size, l; + const char *p; + bool contains_8bit = false; + char buffer[DNS_LABEL_MAX+1]; + int r; + + assert(encoded); + assert(decoded); + + /* Converts an U-label into an A-label */ + + r = dlopen_idn(); + if (r < 0) + return r; + + if (encoded_size <= 0) + return -EINVAL; + + for (p = encoded; p < encoded + encoded_size; p++) + if ((uint8_t) *p > 127) + contains_8bit = true; + + if (!contains_8bit) { + if (encoded_size > DNS_LABEL_MAX) + return -EINVAL; + + return 0; + } + + input = sym_stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size); + if (!input) + return -ENOMEM; + + if (sym_idna_to_ascii_4i(input, input_size, buffer, 0) != 0) + return -EINVAL; + + l = strlen(buffer); + + /* Verify that the result is not longer than one DNS label. */ + if (l <= 0 || l > DNS_LABEL_MAX) + return -EINVAL; + if (l > decoded_max) + return -ENOBUFS; + + memcpy(decoded, buffer, l); + + /* If there's room, append a trailing NUL byte, but only then */ + if (decoded_max > l) + decoded[l] = 0; + + return (int) l; +} + +int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) { + size_t input_size, output_size; + _cleanup_free_ uint32_t *input = NULL; + _cleanup_free_ char *result = NULL; + uint32_t *output = NULL; + size_t w; + int r; + + /* To be invoked after unescaping. Converts an A-label into an U-label. */ + + assert(encoded); + assert(decoded); + + r = dlopen_idn(); + if (r < 0) + return r; + + if (encoded_size <= 0 || encoded_size > DNS_LABEL_MAX) + return -EINVAL; + + if (!memory_startswith(encoded, encoded_size, IDNA_ACE_PREFIX)) + return 0; + + input = sym_stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size); + if (!input) + return -ENOMEM; + + output_size = input_size; + output = newa(uint32_t, output_size); + + sym_idna_to_unicode_44i(input, input_size, output, &output_size, 0); + + result = sym_stringprep_ucs4_to_utf8(output, output_size, NULL, &w); + if (!result) + return -ENOMEM; + if (w <= 0) + return -EINVAL; + if (w > decoded_max) + return -ENOBUFS; + + memcpy(decoded, result, w); + + /* Append trailing NUL byte if there's space, but only then. */ + if (decoded_max > w) + decoded[w] = 0; + + return w; +} +#endif +#endif /* NM_IGNORED */ + +int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_ret) { + _cleanup_free_ char *ret = NULL; + size_t n = 0, allocated = 0; + const char *p; + bool first = true; + int r; + + if (a) + p = a; + else if (b) + p = TAKE_PTR(b); + else + goto finish; + + for (;;) { + char label[DNS_LABEL_MAX]; + + r = dns_label_unescape(&p, label, sizeof label, flags); + if (r < 0) + return r; + if (r == 0) { + if (*p != 0) + return -EINVAL; + + if (b) { + /* Now continue with the second string, if there is one */ + p = TAKE_PTR(b); + continue; + } + + break; + } + + if (_ret) { + if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) + return -ENOMEM; + + r = dns_label_escape(label, r, ret + n + !first, DNS_LABEL_ESCAPED_MAX); + if (r < 0) + return r; + + if (!first) + ret[n] = '.'; + } else { + char escaped[DNS_LABEL_ESCAPED_MAX]; + + r = dns_label_escape(label, r, escaped, sizeof(escaped)); + if (r < 0) + return r; + } + + if (!first) + n++; + else + first = false; + + n += r; + } + +finish: + if (n > DNS_HOSTNAME_MAX) + return -EINVAL; + + if (_ret) { + if (n == 0) { + /* Nothing appended? If so, generate at least a single dot, to indicate the DNS root domain */ + if (!GREEDY_REALLOC(ret, allocated, 2)) + return -ENOMEM; + + ret[n++] = '.'; + } else { + if (!GREEDY_REALLOC(ret, allocated, n + 1)) + return -ENOMEM; + } + + ret[n] = 0; + *_ret = TAKE_PTR(ret); + } + + return 0; +} + +#if 0 /* NM_IGNORED */ +void dns_name_hash_func(const char *p, struct siphash *state) { + int r; + + assert(p); + + for (;;) { + char label[DNS_LABEL_MAX+1]; + + r = dns_label_unescape(&p, label, sizeof label, 0); + if (r < 0) + break; + if (r == 0) + break; + + ascii_strlower_n(label, r); + siphash24_compress(label, r, state); + siphash24_compress_byte(0, state); /* make sure foobar and foo.bar result in different hashes */ + } + + /* enforce that all names are terminated by the empty label */ + string_hash_func("", state); +} + +int dns_name_compare_func(const char *a, const char *b) { + const char *x, *y; + int r, q; + + assert(a); + assert(b); + + x = a + strlen(a); + y = b + strlen(b); + + for (;;) { + char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX]; + + if (x == NULL && y == NULL) + return 0; + + r = dns_label_unescape_suffix(a, &x, la, sizeof(la)); + q = dns_label_unescape_suffix(b, &y, lb, sizeof(lb)); + if (r < 0 || q < 0) + return CMP(r, q); + + r = ascii_strcasecmp_nn(la, r, lb, q); + if (r != 0) + return r; + } +} + +DEFINE_HASH_OPS(dns_name_hash_ops, char, dns_name_hash_func, dns_name_compare_func); + +int dns_name_equal(const char *x, const char *y) { + int r, q; + + assert(x); + assert(y); + + for (;;) { + char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX]; + + r = dns_label_unescape(&x, la, sizeof la, 0); + if (r < 0) + return r; + + q = dns_label_unescape(&y, lb, sizeof lb, 0); + if (q < 0) + return q; + + if (r != q) + return false; + if (r == 0) + return true; + + if (ascii_strcasecmp_n(la, lb, r) != 0) + return false; + } +} + +int dns_name_endswith(const char *name, const char *suffix) { + const char *n, *s, *saved_n = NULL; + int r, q; + + assert(name); + assert(suffix); + + n = name; + s = suffix; + + for (;;) { + char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX]; + + r = dns_label_unescape(&n, ln, sizeof ln, 0); + if (r < 0) + return r; + + if (!saved_n) + saved_n = n; + + q = dns_label_unescape(&s, ls, sizeof ls, 0); + if (q < 0) + return q; + + if (r == 0 && q == 0) + return true; + if (r == 0 && saved_n == n) + return false; + + if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) { + + /* Not the same, let's jump back, and try with the next label again */ + s = suffix; + n = TAKE_PTR(saved_n); + } + } +} + +int dns_name_startswith(const char *name, const char *prefix) { + const char *n, *p; + int r, q; + + assert(name); + assert(prefix); + + n = name; + p = prefix; + + for (;;) { + char ln[DNS_LABEL_MAX], lp[DNS_LABEL_MAX]; + + r = dns_label_unescape(&p, lp, sizeof lp, 0); + if (r < 0) + return r; + if (r == 0) + return true; + + q = dns_label_unescape(&n, ln, sizeof ln, 0); + if (q < 0) + return q; + + if (r != q) + return false; + if (ascii_strcasecmp_n(ln, lp, r) != 0) + return false; + } +} + +int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret) { + const char *n, *s, *saved_before = NULL, *saved_after = NULL, *prefix; + int r, q; + + assert(name); + assert(old_suffix); + assert(new_suffix); + assert(ret); + + n = name; + s = old_suffix; + + for (;;) { + char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX]; + + if (!saved_before) + saved_before = n; + + r = dns_label_unescape(&n, ln, sizeof ln, 0); + if (r < 0) + return r; + + if (!saved_after) + saved_after = n; + + q = dns_label_unescape(&s, ls, sizeof ls, 0); + if (q < 0) + return q; + + if (r == 0 && q == 0) + break; + if (r == 0 && saved_after == n) { + *ret = NULL; /* doesn't match */ + return 0; + } + + if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) { + + /* Not the same, let's jump back, and try with the next label again */ + s = old_suffix; + n = TAKE_PTR(saved_after); + saved_before = NULL; + } + } + + /* Found it! Now generate the new name */ + prefix = strndupa(name, saved_before - name); + + r = dns_name_concat(prefix, new_suffix, 0, ret); + if (r < 0) + return r; + + return 1; +} + +int dns_name_between(const char *a, const char *b, const char *c) { + /* Determine if b is strictly greater than a and strictly smaller than c. + We consider the order of names to be circular, so that if a is + strictly greater than c, we consider b to be between them if it is + either greater than a or smaller than c. This is how the canonical + DNS name order used in NSEC records work. */ + + if (dns_name_compare_func(a, c) < 0) + /* + a and c are properly ordered: + a<---b--->c + */ + return dns_name_compare_func(a, b) < 0 && + dns_name_compare_func(b, c) < 0; + else + /* + a and c are equal or 'reversed': + <--b--c a-----> + or: + <-----c a--b--> + */ + return dns_name_compare_func(b, c) < 0 || + dns_name_compare_func(a, b) < 0; +} + +int dns_name_reverse(int family, const union in_addr_union *a, char **ret) { + const uint8_t *p; + int r; + + assert(a); + assert(ret); + + p = (const uint8_t*) a; + + if (family == AF_INET) + r = asprintf(ret, "%u.%u.%u.%u.in-addr.arpa", p[3], p[2], p[1], p[0]); + else if (family == AF_INET6) + r = asprintf(ret, "%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.ip6.arpa", + hexchar(p[15] & 0xF), hexchar(p[15] >> 4), hexchar(p[14] & 0xF), hexchar(p[14] >> 4), + hexchar(p[13] & 0xF), hexchar(p[13] >> 4), hexchar(p[12] & 0xF), hexchar(p[12] >> 4), + hexchar(p[11] & 0xF), hexchar(p[11] >> 4), hexchar(p[10] & 0xF), hexchar(p[10] >> 4), + hexchar(p[ 9] & 0xF), hexchar(p[ 9] >> 4), hexchar(p[ 8] & 0xF), hexchar(p[ 8] >> 4), + hexchar(p[ 7] & 0xF), hexchar(p[ 7] >> 4), hexchar(p[ 6] & 0xF), hexchar(p[ 6] >> 4), + hexchar(p[ 5] & 0xF), hexchar(p[ 5] >> 4), hexchar(p[ 4] & 0xF), hexchar(p[ 4] >> 4), + hexchar(p[ 3] & 0xF), hexchar(p[ 3] >> 4), hexchar(p[ 2] & 0xF), hexchar(p[ 2] >> 4), + hexchar(p[ 1] & 0xF), hexchar(p[ 1] >> 4), hexchar(p[ 0] & 0xF), hexchar(p[ 0] >> 4)); + else + return -EAFNOSUPPORT; + if (r < 0) + return -ENOMEM; + + return 0; +} + +int dns_name_address(const char *p, int *ret_family, union in_addr_union *ret_address) { + int r; + + assert(p); + assert(ret_family); + assert(ret_address); + + r = dns_name_endswith(p, "in-addr.arpa"); + if (r < 0) + return r; + if (r > 0) { + uint8_t a[4]; + unsigned i; + + for (i = 0; i < ELEMENTSOF(a); i++) { + char label[DNS_LABEL_MAX+1]; + + r = dns_label_unescape(&p, label, sizeof label, 0); + if (r < 0) + return r; + if (r == 0) + return -EINVAL; + if (r > 3) + return -EINVAL; + + r = safe_atou8(label, &a[i]); + if (r < 0) + return r; + } + + r = dns_name_equal(p, "in-addr.arpa"); + if (r <= 0) + return r; + + *ret_family = AF_INET; + ret_address->in.s_addr = htobe32(((uint32_t) a[3] << 24) | + ((uint32_t) a[2] << 16) | + ((uint32_t) a[1] << 8) | + (uint32_t) a[0]); + + return 1; + } + + r = dns_name_endswith(p, "ip6.arpa"); + if (r < 0) + return r; + if (r > 0) { + struct in6_addr a; + unsigned i; + + for (i = 0; i < ELEMENTSOF(a.s6_addr); i++) { + char label[DNS_LABEL_MAX+1]; + int x, y; + + r = dns_label_unescape(&p, label, sizeof label, 0); + if (r <= 0) + return r; + if (r != 1) + return -EINVAL; + x = unhexchar(label[0]); + if (x < 0) + return -EINVAL; + + r = dns_label_unescape(&p, label, sizeof label, 0); + if (r <= 0) + return r; + if (r != 1) + return -EINVAL; + y = unhexchar(label[0]); + if (y < 0) + return -EINVAL; + + a.s6_addr[ELEMENTSOF(a.s6_addr) - i - 1] = (uint8_t) y << 4 | (uint8_t) x; + } + + r = dns_name_equal(p, "ip6.arpa"); + if (r <= 0) + return r; + + *ret_family = AF_INET6; + ret_address->in6 = a; + return 1; + } + + *ret_family = AF_UNSPEC; + *ret_address = IN_ADDR_NULL; + + return 0; +} +#endif /* NM_IGNORED */ + +bool dns_name_is_root(const char *name) { + + assert(name); + + /* There are exactly two ways to encode the root domain name: + * as empty string, or with a single dot. */ + + return STR_IN_SET(name, "", "."); +} + +bool dns_name_is_single_label(const char *name) { + int r; + + assert(name); + + r = dns_name_parent(&name); + if (r <= 0) + return false; + + return dns_name_is_root(name); +} + +/* Encode a domain name according to RFC 1035 Section 3.1, without compression */ +int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, bool canonical) { + uint8_t *label_length, *out; + int r; + + assert(domain); + assert(buffer); + + out = buffer; + + do { + /* Reserve a byte for label length */ + if (len <= 0) + return -ENOBUFS; + len--; + label_length = out; + out++; + + /* Convert and copy a single label. Note that + * dns_label_unescape() returns 0 when it hits the end + * of the domain name, which we rely on here to encode + * the trailing NUL byte. */ + r = dns_label_unescape(&domain, (char *) out, len, 0); + if (r < 0) + return r; + + /* Optionally, output the name in DNSSEC canonical + * format, as described in RFC 4034, section 6.2. Or + * in other words: in lower-case. */ + if (canonical) + ascii_strlower_n((char*) out, (size_t) r); + + /* Fill label length, move forward */ + *label_length = r; + out += r; + len -= r; + + } while (r != 0); + + /* Verify the maximum size of the encoded name. The trailing + * dot + NUL byte account are included this time, hence + * compare against DNS_HOSTNAME_MAX + 2 (which is 255) this + * time. */ + if (out - buffer > DNS_HOSTNAME_MAX + 2) + return -EINVAL; + + return out - buffer; +} + +#if 0 /* NM_IGNORED */ +static bool srv_type_label_is_valid(const char *label, size_t n) { + size_t k; + + assert(label); + + if (n < 2) /* Label needs to be at least 2 chars long */ + return false; + + if (label[0] != '_') /* First label char needs to be underscore */ + return false; + + /* Second char must be a letter */ + if (!(label[1] >= 'A' && label[1] <= 'Z') && + !(label[1] >= 'a' && label[1] <= 'z')) + return false; + + /* Third and further chars must be alphanumeric or a hyphen */ + for (k = 2; k < n; k++) { + if (!(label[k] >= 'A' && label[k] <= 'Z') && + !(label[k] >= 'a' && label[k] <= 'z') && + !(label[k] >= '0' && label[k] <= '9') && + label[k] != '-') + return false; + } + + return true; +} + +bool dns_srv_type_is_valid(const char *name) { + unsigned c = 0; + int r; + + if (!name) + return false; + + for (;;) { + char label[DNS_LABEL_MAX]; + + /* This more or less implements RFC 6335, Section 5.1 */ + + r = dns_label_unescape(&name, label, sizeof label, 0); + if (r < 0) + return false; + if (r == 0) + break; + + if (c >= 2) + return false; + + if (!srv_type_label_is_valid(label, r)) + return false; + + c++; + } + + return c == 2; /* exactly two labels */ +} + +bool dnssd_srv_type_is_valid(const char *name) { + return dns_srv_type_is_valid(name) && + ((dns_name_endswith(name, "_tcp") > 0) || + (dns_name_endswith(name, "_udp") > 0)); /* Specific to DNS-SD. RFC 6763, Section 7 */ +} + +bool dns_service_name_is_valid(const char *name) { + size_t l; + + /* This more or less implements RFC 6763, Section 4.1.1 */ + + if (!name) + return false; + + if (!utf8_is_valid(name)) + return false; + + if (string_has_cc(name, NULL)) + return false; + + l = strlen(name); + if (l <= 0) + return false; + if (l > 63) + return false; + + return true; +} + +int dns_service_join(const char *name, const char *type, const char *domain, char **ret) { + char escaped[DNS_LABEL_ESCAPED_MAX]; + _cleanup_free_ char *n = NULL; + int r; + + assert(type); + assert(domain); + assert(ret); + + if (!dns_srv_type_is_valid(type)) + return -EINVAL; + + if (!name) + return dns_name_concat(type, domain, 0, ret); + + if (!dns_service_name_is_valid(name)) + return -EINVAL; + + r = dns_label_escape(name, strlen(name), escaped, sizeof(escaped)); + if (r < 0) + return r; + + r = dns_name_concat(type, domain, 0, &n); + if (r < 0) + return r; + + return dns_name_concat(escaped, n, 0, ret); +} + +static bool dns_service_name_label_is_valid(const char *label, size_t n) { + char *s; + + assert(label); + + if (memchr(label, 0, n)) + return false; + + s = strndupa(label, n); + return dns_service_name_is_valid(s); +} + +int dns_service_split(const char *joined, char **_name, char **_type, char **_domain) { + _cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL; + const char *p = joined, *q = NULL, *d = NULL; + char a[DNS_LABEL_MAX], b[DNS_LABEL_MAX], c[DNS_LABEL_MAX]; + int an, bn, cn, r; + unsigned x = 0; + + assert(joined); + + /* Get first label from the full name */ + an = dns_label_unescape(&p, a, sizeof(a), 0); + if (an < 0) + return an; + + if (an > 0) { + x++; + + /* If there was a first label, try to get the second one */ + bn = dns_label_unescape(&p, b, sizeof(b), 0); + if (bn < 0) + return bn; + + if (bn > 0) { + x++; + + /* If there was a second label, try to get the third one */ + q = p; + cn = dns_label_unescape(&p, c, sizeof(c), 0); + if (cn < 0) + return cn; + + if (cn > 0) + x++; + } else + cn = 0; + } else + an = 0; + + if (x >= 2 && srv_type_label_is_valid(b, bn)) { + + if (x >= 3 && srv_type_label_is_valid(c, cn)) { + + if (dns_service_name_label_is_valid(a, an)) { + /* OK, got . . . */ + + name = strndup(a, an); + if (!name) + return -ENOMEM; + + type = strjoin(b, ".", c); + if (!type) + return -ENOMEM; + + d = p; + goto finish; + } + + } else if (srv_type_label_is_valid(a, an)) { + + /* OK, got . . */ + + name = NULL; + + type = strjoin(a, ".", b); + if (!type) + return -ENOMEM; + + d = q; + goto finish; + } + } + + name = NULL; + type = NULL; + d = joined; + +finish: + r = dns_name_normalize(d, 0, &domain); + if (r < 0) + return r; + + if (_domain) + *_domain = TAKE_PTR(domain); + + if (_type) + *_type = TAKE_PTR(type); + + if (_name) + *_name = TAKE_PTR(name); + + return 0; +} + +static int dns_name_build_suffix_table(const char *name, const char *table[]) { + const char *p; + unsigned n = 0; + int r; + + assert(name); + assert(table); + + p = name; + for (;;) { + if (n > DNS_N_LABELS_MAX) + return -EINVAL; + + table[n] = p; + r = dns_name_parent(&p); + if (r < 0) + return r; + if (r == 0) + break; + + n++; + } + + return (int) n; +} + +int dns_name_suffix(const char *name, unsigned n_labels, const char **ret) { + const char* labels[DNS_N_LABELS_MAX+1]; + int n; + + assert(name); + assert(ret); + + n = dns_name_build_suffix_table(name, labels); + if (n < 0) + return n; + + if ((unsigned) n < n_labels) + return -EINVAL; + + *ret = labels[n - n_labels]; + return (int) (n - n_labels); +} + +int dns_name_skip(const char *a, unsigned n_labels, const char **ret) { + int r; + + assert(a); + assert(ret); + + for (; n_labels > 0; n_labels--) { + r = dns_name_parent(&a); + if (r < 0) + return r; + if (r == 0) { + *ret = ""; + return 0; + } + } + + *ret = a; + return 1; +} + +int dns_name_count_labels(const char *name) { + unsigned n = 0; + const char *p; + int r; + + assert(name); + + p = name; + for (;;) { + r = dns_name_parent(&p); + if (r < 0) + return r; + if (r == 0) + break; + + if (n >= DNS_N_LABELS_MAX) + return -EINVAL; + + n++; + } + + return (int) n; +} + +int dns_name_equal_skip(const char *a, unsigned n_labels, const char *b) { + int r; + + assert(a); + assert(b); + + r = dns_name_skip(a, n_labels, &a); + if (r <= 0) + return r; + + return dns_name_equal(a, b); +} + +int dns_name_common_suffix(const char *a, const char *b, const char **ret) { + const char *a_labels[DNS_N_LABELS_MAX+1], *b_labels[DNS_N_LABELS_MAX+1]; + int n = 0, m = 0, k = 0, r, q; + + assert(a); + assert(b); + assert(ret); + + /* Determines the common suffix of domain names a and b */ + + n = dns_name_build_suffix_table(a, a_labels); + if (n < 0) + return n; + + m = dns_name_build_suffix_table(b, b_labels); + if (m < 0) + return m; + + for (;;) { + char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX]; + const char *x, *y; + + if (k >= n || k >= m) { + *ret = a_labels[n - k]; + return 0; + } + + x = a_labels[n - 1 - k]; + r = dns_label_unescape(&x, la, sizeof la, 0); + if (r < 0) + return r; + + y = b_labels[m - 1 - k]; + q = dns_label_unescape(&y, lb, sizeof lb, 0); + if (q < 0) + return q; + + if (r != q || ascii_strcasecmp_n(la, lb, r) != 0) { + *ret = a_labels[n - k]; + return 0; + } + + k++; + } +} + +int dns_name_apply_idna(const char *name, char **ret) { + + /* Return negative on error, 0 if not implemented, positive on success. */ + +#if HAVE_LIBIDN2 || HAVE_LIBIDN2 + int r; + + r = dlopen_idn(); + if (r == -EOPNOTSUPP) { + *ret = NULL; + return 0; + } + if (r < 0) + return r; +#endif + +#if HAVE_LIBIDN2 + _cleanup_free_ char *t = NULL; + + assert(name); + assert(ret); + + /* First, try non-transitional mode (i.e. IDN2008 rules) */ + r = sym_idn2_lookup_u8((uint8_t*) name, (uint8_t**) &t, + IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL); + if (r == IDN2_DISALLOWED) /* If that failed, because of disallowed characters, try transitional mode. + * (i.e. IDN2003 rules which supports some unicode chars IDN2008 doesn't allow). */ + r = sym_idn2_lookup_u8((uint8_t*) name, (uint8_t**) &t, + IDN2_NFC_INPUT | IDN2_TRANSITIONAL); + + log_debug("idn2_lookup_u8: %s → %s", name, t); + if (r == IDN2_OK) { + if (!startswith(name, "xn--")) { + _cleanup_free_ char *s = NULL; + + r = sym_idn2_to_unicode_8z8z(t, &s, 0); + if (r != IDN2_OK) { + log_debug("idn2_to_unicode_8z8z(\"%s\") failed: %d/%s", + t, r, sym_idn2_strerror(r)); + *ret = NULL; + return 0; + } + + if (!streq_ptr(name, s)) { + log_debug("idn2 roundtrip failed: \"%s\" → \"%s\" → \"%s\", ignoring.", + name, t, s); + *ret = NULL; + return 0; + } + } + + *ret = TAKE_PTR(t); + return 1; /* *ret has been written */ + } + + log_debug("idn2_lookup_u8(\"%s\") failed: %d/%s", name, r, sym_idn2_strerror(r)); + if (r == IDN2_2HYPHEN) + /* The name has two hyphens — forbidden by IDNA2008 in some cases */ + return 0; + if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL)) + return -ENOSPC; + + return -EINVAL; +#elif HAVE_LIBIDN + _cleanup_free_ char *buf = NULL; + size_t n = 0, allocated = 0; + bool first = true; + int r, q; + + assert(name); + assert(ret); + + for (;;) { + char label[DNS_LABEL_MAX]; + + r = dns_label_unescape(&name, label, sizeof label, 0); + if (r < 0) + return r; + if (r == 0) + break; + + q = dns_label_apply_idna(label, r, label, sizeof label); + if (q < 0) + return q; + if (q > 0) + r = q; + + if (!GREEDY_REALLOC(buf, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) + return -ENOMEM; + + r = dns_label_escape(label, r, buf + n + !first, DNS_LABEL_ESCAPED_MAX); + if (r < 0) + return r; + + if (first) + first = false; + else + buf[n++] = '.'; + + n += r; + } + + if (n > DNS_HOSTNAME_MAX) + return -EINVAL; + + if (!GREEDY_REALLOC(buf, allocated, n + 1)) + return -ENOMEM; + + buf[n] = 0; + *ret = TAKE_PTR(buf); + + return 1; +#else + *ret = NULL; + return 0; +#endif +} + +int dns_name_is_valid_or_address(const char *name) { + /* Returns > 0 if the specified name is either a valid IP address formatted as string or a valid DNS name */ + + if (isempty(name)) + return 0; + + if (in_addr_from_string_auto(name, NULL, NULL) >= 0) + return 1; + + return dns_name_is_valid(name); +} + +int dns_name_dot_suffixed(const char *name) { + const char *p = name; + int r; + + for (;;) { + if (streq(p, ".")) + return true; + + r = dns_label_unescape(&p, NULL, DNS_LABEL_MAX, DNS_LABEL_LEAVE_TRAILING_DOT); + if (r < 0) + return r; + if (r == 0) + return false; + } +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/shared/dns-domain.h b/src/libnm-systemd-shared/src/shared/dns-domain.h new file mode 100644 index 0000000..984f484 --- /dev/null +++ b/src/libnm-systemd-shared/src/shared/dns-domain.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include +#include + +#include "hashmap.h" +#include "in-addr-util.h" + +/* Length of a single label, with all escaping removed, excluding any trailing dot or NUL byte */ +#define DNS_LABEL_MAX 63 + +/* Worst case length of a single label, with all escaping applied and room for a trailing NUL byte. */ +#define DNS_LABEL_ESCAPED_MAX (DNS_LABEL_MAX*4+1) + +/* Maximum length of a full hostname, consisting of a series of unescaped labels, and no trailing dot or NUL byte */ +#define DNS_HOSTNAME_MAX 253 + +/* Maximum length of a full hostname, on the wire, including the final NUL byte */ +#define DNS_WIRE_FORMAT_HOSTNAME_MAX 255 + +/* Maximum number of labels per valid hostname */ +#define DNS_N_LABELS_MAX 127 + +typedef enum DNSLabelFlags { + DNS_LABEL_LDH = 1 << 0, /* Follow the "LDH" rule — only letters, digits, and internal hyphens. */ + DNS_LABEL_NO_ESCAPES = 1 << 1, /* Do not treat backslashes specially */ + DNS_LABEL_LEAVE_TRAILING_DOT = 1 << 2, /* Leave trailing dot in place */ +} DNSLabelFlags; + +int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags); +int dns_label_unescape_suffix(const char *name, const char **label_end, char *dest, size_t sz); +int dns_label_escape(const char *p, size_t l, char *dest, size_t sz); +int dns_label_escape_new(const char *p, size_t l, char **ret); + +static inline int dns_name_parent(const char **name) { + return dns_label_unescape(name, NULL, DNS_LABEL_MAX, 0); +} + +#if 0 /* NM_IGNORED */ +#if HAVE_LIBIDN +int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max); +int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max); +#endif +#endif /* NM_IGNORED */ + +int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **ret); + +static inline int dns_name_normalize(const char *s, DNSLabelFlags flags, char **ret) { + /* dns_name_concat() normalizes as a side-effect */ + return dns_name_concat(s, NULL, flags, ret); +} + +static inline int dns_name_is_valid(const char *s) { + int r; + + /* dns_name_normalize() verifies as a side effect */ + r = dns_name_normalize(s, 0, NULL); + if (r == -EINVAL) + return 0; + if (r < 0) + return r; + return 1; +} + +static inline int dns_name_is_valid_ldh(const char *s) { + int r; + + r = dns_name_concat(s, NULL, DNS_LABEL_LDH|DNS_LABEL_NO_ESCAPES, NULL); + if (r == -EINVAL) + return 0; + if (r < 0) + return r; + return 1; +} + +void dns_name_hash_func(const char *s, struct siphash *state); +int dns_name_compare_func(const char *a, const char *b); +extern const struct hash_ops dns_name_hash_ops; + +int dns_name_between(const char *a, const char *b, const char *c); +int dns_name_equal(const char *x, const char *y); +int dns_name_endswith(const char *name, const char *suffix); +int dns_name_startswith(const char *name, const char *prefix); + +int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret); + +int dns_name_reverse(int family, const union in_addr_union *a, char **ret); +int dns_name_address(const char *p, int *family, union in_addr_union *a); + +bool dns_name_is_root(const char *name); +bool dns_name_is_single_label(const char *name); + +int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, bool canonical); + +bool dns_srv_type_is_valid(const char *name); +bool dnssd_srv_type_is_valid(const char *name); +bool dns_service_name_is_valid(const char *name); + +int dns_service_join(const char *name, const char *type, const char *domain, char **ret); +int dns_service_split(const char *joined, char **name, char **type, char **domain); + +int dns_name_suffix(const char *name, unsigned n_labels, const char **ret); +int dns_name_count_labels(const char *name); + +int dns_name_skip(const char *a, unsigned n_labels, const char **ret); +int dns_name_equal_skip(const char *a, unsigned n_labels, const char *b); + +int dns_name_common_suffix(const char *a, const char *b, const char **ret); + +int dns_name_apply_idna(const char *name, char **ret); + +int dns_name_is_valid_or_address(const char *name); + +int dns_name_dot_suffixed(const char *name); diff --git a/src/libnm-systemd-shared/src/shared/log-link.h b/src/libnm-systemd-shared/src/shared/log-link.h new file mode 100644 index 0000000..3a4dcaa --- /dev/null +++ b/src/libnm-systemd-shared/src/shared/log-link.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "log.h" + +#define log_interface_full_errno(ifname, level, error, ...) \ + ({ \ + const char *_ifname = (ifname); \ + _ifname ? log_object_internal(level, error, PROJECT_FILE, __LINE__, __func__, "INTERFACE=", _ifname, NULL, NULL, ##__VA_ARGS__) : \ + log_internal(level, error, PROJECT_FILE, __LINE__, __func__, ##__VA_ARGS__); \ + }) + +/* + * The following macros append INTERFACE= to the message. + * The macros require a struct named 'Link' which contains 'char *ifname': + * + * typedef struct Link { + * char *ifname; + * } Link; + * + * See, network/networkd-link.h for example. + */ + +#define log_link_full_errno(link, level, error, ...) \ + ({ \ + const Link *_l = (link); \ + log_interface_full_errno(_l ? _l->ifname : NULL, level, error, ##__VA_ARGS__); \ + }) + +#define log_link_full(link, level, ...) (void) log_link_full_errno(link, level, 0, __VA_ARGS__) + +#define log_link_debug(link, ...) log_link_full_errno(link, LOG_DEBUG, 0, __VA_ARGS__) +#define log_link_info(link, ...) log_link_full(link, LOG_INFO, __VA_ARGS__) +#define log_link_notice(link, ...) log_link_full(link, LOG_NOTICE, __VA_ARGS__) +#define log_link_warning(link, ...) log_link_full(link, LOG_WARNING, __VA_ARGS__) +#define log_link_error(link, ...) log_link_full(link, LOG_ERR, __VA_ARGS__) + +#define log_link_debug_errno(link, error, ...) log_link_full_errno(link, LOG_DEBUG, error, __VA_ARGS__) +#define log_link_info_errno(link, error, ...) log_link_full_errno(link, LOG_INFO, error, __VA_ARGS__) +#define log_link_notice_errno(link, error, ...) log_link_full_errno(link, LOG_NOTICE, error, __VA_ARGS__) +#define log_link_warning_errno(link, error, ...) log_link_full_errno(link, LOG_WARNING, error, __VA_ARGS__) +#define log_link_error_errno(link, error, ...) log_link_full_errno(link, LOG_ERR, error, __VA_ARGS__) + +#define LOG_LINK_MESSAGE(link, fmt, ...) "MESSAGE=%s: " fmt, (link)->ifname, ##__VA_ARGS__ +#define LOG_LINK_INTERFACE(link) "INTERFACE=%s", (link)->ifname diff --git a/src/libnm-systemd-shared/src/shared/web-util.c b/src/libnm-systemd-shared/src/shared/web-util.c new file mode 100644 index 0000000..35ba1a2 --- /dev/null +++ b/src/libnm-systemd-shared/src/shared/web-util.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include + +#include "string-util.h" +#include "strv.h" +#include "utf8.h" +#include "web-util.h" + +#if 0 /* NM_IGNORED */ +bool http_etag_is_valid(const char *etag) { + if (isempty(etag)) + return false; + + if (!endswith(etag, "\"")) + return false; + + if (!STARTSWITH_SET(etag, "\"", "W/\"")) + return false; + + return true; +} +#endif /* NM_IGNORED */ + +/* NM: we use http_url_is_valid() for our own code, and it must not + * change behavior. If a re-import results in a merge-conflict, you must + * ensure that it does not change behavior, and possibly do something + * about that. */ +/**/ bool http_url_is_valid(const char *url) { +/**/ const char *p; +/**/ +/**/ if (isempty(url)) +/**/ return false; +/**/ +/**/ p = STARTSWITH_SET(url, "http://", "https://"); +/**/ if (!p) +/**/ return false; +/**/ +/**/ if (isempty(p)) +/**/ return false; +/**/ +/**/ return ascii_is_valid(p); +/**/ } + +#if 0 /* NM_IGNORED */ +bool documentation_url_is_valid(const char *url) { + const char *p; + + if (isempty(url)) + return false; + + if (http_url_is_valid(url)) + return true; + + p = STARTSWITH_SET(url, "file:/", "info:", "man:"); + if (isempty(p)) + return false; + + return ascii_is_valid(p); +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/shared/web-util.h b/src/libnm-systemd-shared/src/shared/web-util.h new file mode 100644 index 0000000..ec54669 --- /dev/null +++ b/src/libnm-systemd-shared/src/shared/web-util.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +#include "macro.h" + +bool http_url_is_valid(const char *url) _pure_; + +bool documentation_url_is_valid(const char *url) _pure_; + +bool http_etag_is_valid(const char *etag); diff --git a/src/libnm-udev-aux/meson.build b/src/libnm-udev-aux/meson.build new file mode 100644 index 0000000..8ba1248 --- /dev/null +++ b/src/libnm-udev-aux/meson.build @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_udev_aux = static_library( + 'nm-udev-aux', + sources: 'nm-udev-utils.c', + include_directories: [ + src_inc, + top_inc, + ], + dependencies: [ + glib_dep, + libudev_dep, + ], +) diff --git a/src/libnm-udev-aux/nm-udev-utils.c b/src/libnm-udev-aux/nm-udev-utils.c new file mode 100644 index 0000000..ef1cf26 --- /dev/null +++ b/src/libnm-udev-aux/nm-udev-utils.c @@ -0,0 +1,265 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-udev-utils.h" + +#include + +struct _NMPUdevClient { + char ** subsystems; + GSource * watch_source; + struct udev * udev; + struct udev_monitor *monitor; + NMUdevClientEvent event_handler; + gpointer event_user_data; +}; + +/*****************************************************************************/ + +gboolean +nm_udev_utils_property_as_boolean(const char *uproperty) +{ + /* taken from g_udev_device_get_property_as_boolean() */ + + if (uproperty) { + if (strcmp(uproperty, "1") == 0 || g_ascii_strcasecmp(uproperty, "true") == 0) + return TRUE; + } + return FALSE; +} + +const char * +nm_udev_utils_property_decode(const char *uproperty, char **to_free) +{ + const char *p; + char * unescaped = NULL; + char * n = NULL; + + if (!uproperty) { + *to_free = NULL; + return NULL; + } + + p = uproperty; + while (*p) { + int a, b; + + if (p[0] == '\\' && p[1] == 'x' && (a = g_ascii_xdigit_value(p[2])) >= 0 + && (b = g_ascii_xdigit_value(p[3])) >= 0 && (a || b)) { + if (!n) { + gssize l = p - uproperty; + + unescaped = g_malloc(l + strlen(p) + 1 - 3); + memcpy(unescaped, uproperty, l); + n = &unescaped[l]; + } + *n++ = (a << 4) | b; + p += 4; + } else { + if (n) + *n++ = *p; + p++; + } + } + + if (!n) { + *to_free = NULL; + return uproperty; + } + + *n++ = '\0'; + return (*to_free = unescaped); +} + +char * +nm_udev_utils_property_decode_cp(const char *uproperty) +{ + char *cpy; + + uproperty = nm_udev_utils_property_decode(uproperty, &cpy); + return cpy ?: g_strdup(uproperty); +} + +/*****************************************************************************/ + +static void +_subsystem_split(const char * subsystem_full, + const char **out_subsystem, + const char **out_devtype, + char ** to_free) +{ + char *tmp, *s; + + nm_assert(subsystem_full); + nm_assert(out_subsystem); + nm_assert(out_devtype); + nm_assert(to_free); + + s = strstr(subsystem_full, "/"); + if (s) { + tmp = g_strdup(subsystem_full); + s = &tmp[s - subsystem_full]; + *s = '\0'; + *out_subsystem = tmp; + *out_devtype = &s[1]; + *to_free = tmp; + } else { + *out_subsystem = subsystem_full; + *out_devtype = NULL; + *to_free = NULL; + } +} + +static struct udev_enumerate * +nm_udev_utils_enumerate(struct udev *uclient, const char *const *subsystems) +{ + struct udev_enumerate *enumerate; + guint n; + + enumerate = udev_enumerate_new(uclient); + + if (subsystems) { + for (n = 0; subsystems[n]; n++) { + const char * subsystem; + const char * devtype; + gs_free char *to_free = NULL; + + _subsystem_split(subsystems[n], &subsystem, &devtype, &to_free); + + udev_enumerate_add_match_subsystem(enumerate, subsystem); + + if (devtype != NULL) + udev_enumerate_add_match_property(enumerate, "DEVTYPE", devtype); + } + } + + return enumerate; +} + +struct udev * +nm_udev_client_get_udev(NMUdevClient *self) +{ + g_return_val_if_fail(self, NULL); + + return self->udev; +} + +struct udev_enumerate * +nm_udev_client_enumerate_new(NMUdevClient *self) +{ + g_return_val_if_fail(self, NULL); + + return nm_udev_utils_enumerate(self->udev, (const char *const *) self->subsystems); +} + +/*****************************************************************************/ + +static gboolean +monitor_event(int fd, GIOCondition condition, gpointer user_data) +{ + NMUdevClient * self = user_data; + struct udev_device *udevice; + + if (!self->monitor) + goto out; + + udevice = udev_monitor_receive_device(self->monitor); + if (udevice == NULL) + goto out; + + self->event_handler(self, udevice, self->event_user_data); + udev_device_unref(udevice); + +out: + return TRUE; +} + +/** + * nm_udev_client_new: + * @subsystems: the subsystems + * @event_handler: callback for events + * @event_user_data: user-data for @event_handler + * + * Basically, it is g_udev_client_new(), and most notably + * g_udev_client_constructed(). + * + * Returns: a new NMUdevClient instance. + */ +NMUdevClient * +nm_udev_client_new(const char *const *subsystems, + NMUdevClientEvent event_handler, + gpointer event_user_data) +{ + NMUdevClient *self; + guint n; + + self = g_slice_new0(NMUdevClient); + + self->event_handler = event_handler; + self->event_user_data = event_user_data; + self->subsystems = subsystems && subsystems[0] ? g_strdupv((char **) subsystems) : NULL; + + self->udev = udev_new(); + if (!self->udev) + goto fail; + + /* connect to event source */ + if (self->event_handler) { + self->monitor = udev_monitor_new_from_netlink(self->udev, "udev"); + if (!self->monitor) + goto fail; + + if (self->subsystems) { + /* install subsystem filters to only wake up for certain events */ + for (n = 0; self->subsystems[n]; n++) { + gs_free char *to_free = NULL; + const char * subsystem; + const char * devtype; + + _subsystem_split(self->subsystems[n], &subsystem, &devtype, &to_free); + udev_monitor_filter_add_match_subsystem_devtype(self->monitor, subsystem, devtype); + } + + /* listen to events, and buffer them */ + udev_monitor_set_receive_buffer_size(self->monitor, 4 * 1024 * 1024); + udev_monitor_enable_receiving(self->monitor); + + self->watch_source = nm_g_unix_fd_source_new(udev_monitor_get_fd(self->monitor), + G_IO_IN, + G_PRIORITY_DEFAULT, + monitor_event, + self, + NULL); + g_source_attach(self->watch_source, g_main_context_get_thread_default()); + } + } + + return self; + +fail: + return nm_udev_client_destroy(self); +} + +NMUdevClient * +nm_udev_client_destroy(NMUdevClient *self) +{ + if (!self) + return NULL; + + nm_clear_g_source_inst(&self->watch_source); + + udev_monitor_unref(self->monitor); + self->monitor = NULL; + udev_unref(self->udev); + self->udev = NULL; + + g_strfreev(self->subsystems); + + g_slice_free(NMUdevClient, self); + + return NULL; +} diff --git a/src/libnm-udev-aux/nm-udev-utils.h b/src/libnm-udev-aux/nm-udev-utils.h new file mode 100644 index 0000000..191f9a8 --- /dev/null +++ b/src/libnm-udev-aux/nm-udev-utils.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 Red Hat, Inc. + */ + +#ifndef __NM_UDEV_UTILS_H__ +#define __NM_UDEV_UTILS_H__ + +struct udev; +struct udev_device; +struct udev_enumerate; + +gboolean nm_udev_utils_property_as_boolean(const char *uproperty); +const char *nm_udev_utils_property_decode(const char *uproperty, char **to_free); +char * nm_udev_utils_property_decode_cp(const char *uproperty); + +typedef struct _NMPUdevClient NMUdevClient; + +typedef void (*NMUdevClientEvent)(NMUdevClient * udev_client, + struct udev_device *udevice, + gpointer event_user_data); + +NMUdevClient *nm_udev_client_new(const char *const *subsystems, + NMUdevClientEvent event_handler, + gpointer event_user_data); + +NMUdevClient *nm_udev_client_destroy(NMUdevClient *self); + +struct udev *nm_udev_client_get_udev(NMUdevClient *self); + +struct udev_enumerate *nm_udev_client_enumerate_new(NMUdevClient *self); + +#endif /* __NM_UDEV_UTILS_H__ */ diff --git a/src/libnmc-base/nm-client-utils.c b/src/libnmc-base/nm-client-utils.c new file mode 100644 index 0000000..701f8e1 --- /dev/null +++ b/src/libnmc-base/nm-client-utils.c @@ -0,0 +1,886 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2010 - 2017 Red Hat, Inc. + */ + +#include "libnm-client-aux-extern/nm-default-client.h" + +#include "nm-client-utils.h" + +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "nm-utils.h" +#include "nm-device-bond.h" +#include "nm-device-bridge.h" +#include "nm-device-team.h" + +/*****************************************************************************/ + +static int +_nmc_objects_sort_by_path_cmp(gconstpointer pa, gconstpointer pb, gpointer user_data) +{ + NMObject *a = *((NMObject **) pa); + NMObject *b = *((NMObject **) pb); + + NM_CMP_SELF(a, b); + NM_CMP_RETURN(nm_utils_dbus_path_cmp(nm_object_get_path(a), nm_object_get_path(b))); + return 0; +} + +const NMObject ** +nmc_objects_sort_by_path(const NMObject *const *objs, gssize len) +{ + const NMObject **arr; + gsize i, l; + + if (len < 0) + l = NM_PTRARRAY_LEN(objs); + else + l = len; + + arr = g_new(const NMObject *, l + 1); + for (i = 0; i < l; i++) + arr[i] = objs[i]; + arr[l] = NULL; + + if (l > 1) { + g_qsort_with_data(arr, l, sizeof(gpointer), _nmc_objects_sort_by_path_cmp, NULL); + } + return arr; +} + +/*****************************************************************************/ +/* + * Convert string to unsigned integer. + * If required, the resulting number is checked to be in the range. + */ +static gboolean +nmc_string_to_uint_base(const char * str, + int base, + gboolean range_check, + unsigned long int min, + unsigned long int max, + unsigned long int *value) +{ + char * end; + unsigned long int tmp; + + if (!str || !str[0]) + return FALSE; + + /* FIXME: don't use this function, replace by _nm_utils_ascii_str_to_int64() */ + errno = 0; + tmp = strtoul(str, &end, base); + if (errno || *end != '\0' || (range_check && (tmp < min || tmp > max))) { + return FALSE; + } + *value = tmp; + return TRUE; +} + +gboolean +nmc_string_to_uint(const char * str, + gboolean range_check, + unsigned long int min, + unsigned long int max, + unsigned long int *value) +{ + return nmc_string_to_uint_base(str, 10, range_check, min, max, value); +} + +gboolean +nmc_string_to_bool(const char *str, gboolean *val_bool, GError **error) +{ + const char *s_true[] = {"true", "yes", "on", "1", NULL}; + const char *s_false[] = {"false", "no", "off", "0", NULL}; + + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + + if (g_strcmp0(str, "o") == 0) { + g_set_error(error, + 1, + 0, + /* TRANSLATORS: the first %s is the partial value entered by + * the user, the second %s a list of compatible values. + */ + _("'%s' is ambiguous (%s)"), + str, + "on x off"); + return FALSE; + } + + if (nmc_string_is_valid(str, s_true, NULL)) + *val_bool = TRUE; + else if (nmc_string_is_valid(str, s_false, NULL)) + *val_bool = FALSE; + else { + g_set_error(error, + 1, + 0, + _("'%s' is not valid; use [%s] or [%s]"), + str, + "true, yes, on", + "false, no, off"); + return FALSE; + } + return TRUE; +} + +gboolean +nmc_string_to_ternary(const char *str, NMTernary *val, GError **error) +{ + const char *s_true[] = {"true", "yes", "on", NULL}; + const char *s_false[] = {"false", "no", "off", NULL}; + const char *s_unknown[] = {"unknown", NULL}; + + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + + if (g_strcmp0(str, "o") == 0) { + g_set_error(error, + 1, + 0, + /* TRANSLATORS: the first %s is the partial value entered by + * the user, the second %s a list of compatible values. + */ + _("'%s' is ambiguous (%s)"), + str, + "on x off"); + return FALSE; + } + + if (nmc_string_is_valid(str, s_true, NULL)) + *val = NM_TERNARY_TRUE; + else if (nmc_string_is_valid(str, s_false, NULL)) + *val = NM_TERNARY_FALSE; + else if (nmc_string_is_valid(str, s_unknown, NULL)) + *val = NM_TERNARY_DEFAULT; + else { + g_set_error(error, + 1, + 0, + _("'%s' is not valid; use [%s], [%s] or [%s]"), + str, + "true, yes, on", + "false, no, off", + "unknown"); + return FALSE; + } + return TRUE; +} + +/* + * Check whether 'input' is contained in 'allowed' array. It performs case + * insensitive comparison and supports shortcut strings if they are unique. + * Returns: a pointer to found string in allowed array on success or NULL. + * On failure: error->code : 0 - string not found; 1 - string is ambiguous + */ +const char * +nmc_string_is_valid(const char *input, const char **allowed, GError **error) +{ + const char **p; + size_t input_ln, p_len; + const char * partial_match = NULL; + gboolean ambiguous = FALSE; + + g_return_val_if_fail(!error || !*error, NULL); + + if (!input || !*input) + goto finish; + + input_ln = strlen(input); + for (p = allowed; p && *p; p++) { + p_len = strlen(*p); + if (g_ascii_strncasecmp(input, *p, input_ln) == 0) { + if (input_ln == p_len) + return *p; + if (!partial_match) + partial_match = *p; + else + ambiguous = TRUE; + } + } + + if (ambiguous) { + GString *candidates = g_string_new(""); + + for (p = allowed; *p; p++) { + if (g_ascii_strncasecmp(input, *p, input_ln) == 0) { + if (candidates->len > 0) + g_string_append(candidates, ", "); + g_string_append(candidates, *p); + } + } + g_set_error(error, 1, 1, _("'%s' is ambiguous: %s"), input, candidates->str); + g_string_free(candidates, TRUE); + return NULL; + } +finish: + if (!partial_match) { + char *valid_vals = g_strjoinv(", ", (char **) allowed); + + if (!input || !*input) + g_set_error(error, 1, 0, _("missing name, try one of [%s]"), valid_vals); + else + g_set_error(error, 1, 0, _("'%s' not among [%s]"), input, valid_vals); + + g_free(valid_vals); + } + + return partial_match; +} + +gboolean +matches(const char *cmd, const char *pattern) +{ + size_t len = strlen(cmd); + if (!len || len > strlen(pattern)) + return FALSE; + return memcmp(pattern, cmd, len) == 0; +} + +const char * +nmc_bond_validate_mode(const char *mode, GError **error) +{ + unsigned long mode_int; + static const char *valid_modes[] = {"balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + NULL}; + if (nmc_string_to_uint(mode, TRUE, 0, 6, &mode_int)) { + /* Translate bonding mode numbers to mode names: + * https://www.kernel.org/doc/Documentation/networking/bonding.txt + */ + return valid_modes[mode_int]; + } else + return nmc_string_is_valid(mode, valid_modes, error); +} + +NM_UTILS_LOOKUP_STR_DEFINE( + nmc_device_state_to_string, + NMDeviceState, + NM_UTILS_LOOKUP_DEFAULT(N_("unknown")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_UNMANAGED, N_("unmanaged")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_UNAVAILABLE, N_("unavailable")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_DISCONNECTED, N_("disconnected")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_PREPARE, N_("connecting (prepare)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_CONFIG, N_("connecting (configuring)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_NEED_AUTH, N_("connecting (need authentication)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_IP_CONFIG, N_("connecting (getting IP configuration)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_IP_CHECK, N_("connecting (checking IP connectivity)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_SECONDARIES, + N_("connecting (starting secondary connections)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_ACTIVATED, N_("connected")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_DEACTIVATING, N_("deactivating")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_FAILED, N_("connection failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_UNKNOWN, N_("unknown")), ); + +static NM_UTILS_LOOKUP_STR_DEFINE( + _device_state_to_string, + NMDeviceState, + NM_UTILS_LOOKUP_DEFAULT(NULL), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_PREPARE, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_CONFIG, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_NEED_AUTH, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_IP_CONFIG, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_IP_CHECK, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_SECONDARIES, N_("connecting (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_ACTIVATED, N_("connected (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_DEACTIVATING, N_("deactivating (externally)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_FAILED, N_("deactivating (externally)")), + NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER(), ); + +const char * +nmc_device_state_to_string_with_external(NMDevice *device) +{ + NMActiveConnection *ac; + NMDeviceState state; + const char * s; + + state = nm_device_get_state(device); + + if ((ac = nm_device_get_active_connection(device)) + && NM_FLAGS_HAS(nm_active_connection_get_state_flags(ac), NM_ACTIVATION_STATE_FLAG_EXTERNAL) + && (s = _device_state_to_string(state))) + return s; + + return nmc_device_state_to_string(state); +} + +NM_UTILS_LOOKUP_STR_DEFINE(nmc_device_metered_to_string, + NMMetered, + NM_UTILS_LOOKUP_DEFAULT(N_("unknown")), + NM_UTILS_LOOKUP_ITEM(NM_METERED_YES, N_("yes")), + NM_UTILS_LOOKUP_ITEM(NM_METERED_NO, N_("no")), + NM_UTILS_LOOKUP_ITEM(NM_METERED_GUESS_YES, N_("yes (guessed)")), + NM_UTILS_LOOKUP_ITEM(NM_METERED_GUESS_NO, N_("no (guessed)")), + NM_UTILS_LOOKUP_ITEM(NM_METERED_UNKNOWN, N_("unknown")), ); + +NM_UTILS_LOOKUP_STR_DEFINE( + nmc_device_reason_to_string, + NMDeviceStateReason, + /* TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) */ + NM_UTILS_LOOKUP_DEFAULT(N_("Unknown")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NONE, N_("No reason given")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_UNKNOWN, N_("Unknown error")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NOW_MANAGED, N_("Device is now managed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NOW_UNMANAGED, N_("Device is now unmanaged")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_CONFIG_FAILED, + N_("The device could not be readied for configuration")), + NM_UTILS_LOOKUP_ITEM( + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE, + N_("IP configuration could not be reserved (no available address, timeout, etc.)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED, + N_("The IP configuration is no longer valid")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NO_SECRETS, + N_("Secrets were required, but not provided")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT, + N_("802.1X supplicant disconnected")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED, + N_("802.1X supplicant configuration failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED, N_("802.1X supplicant failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT, + N_("802.1X supplicant took too long to authenticate")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PPP_START_FAILED, + N_("PPP service failed to start")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PPP_DISCONNECT, N_("PPP service disconnected")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PPP_FAILED, N_("PPP failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DHCP_START_FAILED, + N_("DHCP client failed to start")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DHCP_ERROR, N_("DHCP client error")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DHCP_FAILED, N_("DHCP client failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SHARED_START_FAILED, + N_("Shared connection service failed to start")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SHARED_FAILED, + N_("Shared connection service failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED, + N_("AutoIP service failed to start")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_ERROR, N_("AutoIP service error")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_FAILED, N_("AutoIP service failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_BUSY, N_("The line is busy")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE, N_("No dial tone")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER, + N_("No carrier could be established")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT, + N_("The dialing request timed out")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, + N_("The dialing attempt failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, + N_("Modem initialization failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_APN_FAILED, + N_("Failed to select the specified APN")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING, + N_("Not searching for networks")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED, + N_("Network registration denied")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT, + N_("Network registration timed out")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, + N_("Failed to register with the requested network")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED, N_("PIN check failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_FIRMWARE_MISSING, + N_("Necessary firmware for the device may be missing")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_REMOVED, N_("The device was removed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SLEEPING, N_("NetworkManager went to sleep")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, + N_("The device's active connection disappeared")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_USER_REQUESTED, + N_("Device disconnected by user or client")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_CARRIER, N_("Carrier/link changed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, + N_("The device's existing connection was assumed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, + N_("The supplicant is now available")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND, + N_("The modem could not be found")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_BT_FAILED, + N_("The Bluetooth connection failed or timed out")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED, + N_("GSM Modem's SIM card not inserted")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED, + N_("GSM Modem's SIM PIN required")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED, + N_("GSM Modem's SIM PUK required")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_WRONG, N_("GSM Modem's SIM wrong")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_INFINIBAND_MODE, + N_("InfiniBand device does not support connected mode")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED, + N_("A dependency of the connection failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_BR2684_FAILED, + N_("A problem with the RFC 2684 Ethernet over ADSL bridge")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE, + N_("ModemManager is unavailable")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SSID_NOT_FOUND, + N_("The Wi-Fi network could not be found")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED, + N_("A secondary connection of the base connection failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED, N_("DCB or FCoE setup failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED, N_("teamd control failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_FAILED, + N_("Modem failed or no longer available")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, + N_("Modem now ready and available")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT, N_("SIM PIN was incorrect")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NEW_ACTIVATION, + N_("New connection activation was enqueued")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PARENT_CHANGED, N_("The device's parent changed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED, + N_("The device parent's management changed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_OVSDB_FAILED, + N_("Open vSwitch database connection failed")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE, + N_("A duplicate IP address was detected")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, + N_("The selected IP method is not supported")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED, + N_("Failed to configure SR-IOV parameters")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_PEER_NOT_FOUND, + N_("The Wi-Fi P2P peer could not be found")), ); + +NM_UTILS_LOOKUP_STR_DEFINE( + nm_active_connection_state_reason_to_string, + NMActiveConnectionStateReason, + /* TRANSLATORS: Unknown reason for a connection state change (NMActiveConnectionStateReason) */ + NM_UTILS_LOOKUP_DEFAULT(N_("Unknown")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN, N_("Unknown reason")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_NONE, + N_("The connection was disconnected")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED, + N_("Disconnected by user")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED, + N_("The base network connection was interrupted")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_STOPPED, + N_("The VPN service stopped unexpectedly")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID, + N_("The VPN service returned invalid configuration")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, + N_("The connection attempt timed out")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT, + N_("The VPN service did not start in time")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED, + N_("The VPN service failed to start")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS, N_("No valid secrets")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_LOGIN_FAILED, N_("Invalid secrets")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_CONNECTION_REMOVED, + N_("The connection was removed")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_DEPENDENCY_FAILED, + N_("Master connection failed")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REALIZE_FAILED, + N_("Could not create a software link")), + NM_UTILS_LOOKUP_ITEM(NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REMOVED, + N_("The device disappeared")), ); + +NMActiveConnectionState +nmc_activation_get_effective_state(NMActiveConnection *active, + NMDevice * device, + const char ** reason) +{ + NMActiveConnectionState ac_state; + NMActiveConnectionStateReason ac_reason; + NMDeviceState dev_state = NM_DEVICE_STATE_UNKNOWN; + NMDeviceStateReason dev_reason = NM_DEVICE_STATE_REASON_UNKNOWN; + + g_return_val_if_fail(active, NM_ACTIVE_CONNECTION_STATE_UNKNOWN); + g_return_val_if_fail(reason, NM_ACTIVE_CONNECTION_STATE_UNKNOWN); + + *reason = NULL; + ac_reason = nm_active_connection_get_state_reason(active); + + if (device) { + dev_state = nm_device_get_state(device); + dev_reason = nm_device_get_state_reason(device); + } + + ac_state = nm_active_connection_get_state(active); + switch (ac_state) { + case NM_ACTIVE_CONNECTION_STATE_DEACTIVATED: + if (!device || ac_reason != NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED + || nm_device_get_active_connection(device) != active) { + /* (1) + * - we have no device, + * - or, @ac_reason is specific + * - or, @device no longer references the current @active + * >> we complete with @ac_reason. */ + *reason = gettext(nm_active_connection_state_reason_to_string(ac_reason)); + } else if (dev_state <= NM_DEVICE_STATE_DISCONNECTED + || dev_state >= NM_DEVICE_STATE_FAILED) { + /* (2) + * - not (1) + * - and, the device is no longer in an activated state, + * >> we complete with @dev_reason. */ + *reason = gettext(nmc_device_reason_to_string(dev_reason)); + } else { + /* (3) + * we wait for the device go disconnect. We will get a better + * failure reason from the device (2). */ + return NM_ACTIVE_CONNECTION_STATE_UNKNOWN; + } + break; + case NM_ACTIVE_CONNECTION_STATE_ACTIVATING: + /* activating master connection does not automatically activate any slaves, so their + * active connection state will not progress beyond ACTIVATING state. + * Monitor the device instead. */ + if (device + && (NM_IS_DEVICE_BOND(device) || NM_IS_DEVICE_TEAM(device) + || NM_IS_DEVICE_BRIDGE(device)) + && dev_state >= NM_DEVICE_STATE_IP_CONFIG && dev_state <= NM_DEVICE_STATE_ACTIVATED) { + *reason = "master waiting for slaves"; + return NM_ACTIVE_CONNECTION_STATE_ACTIVATED; + } + break; + default: + break; + } + + return ac_state; +} + +static gboolean +can_show_utf8(void) +{ + static gboolean can_show_utf8_set = FALSE; + static gboolean can_show_utf8 = TRUE; + char * locale_str; + + if (G_LIKELY(can_show_utf8_set)) + return can_show_utf8; + + if (!g_get_charset(NULL)) { + /* Non-UTF-8 locale */ + locale_str = g_locale_from_utf8("\342\226\202\342\226\204\342\226\206\342\226\210", + -1, + NULL, + NULL, + NULL); + if (locale_str) + g_free(locale_str); + else + can_show_utf8 = FALSE; + } + + return can_show_utf8; +} + +static gboolean +can_show_graphics(void) +{ + static gboolean can_show_graphics_set = FALSE; + static gboolean can_show_graphics = TRUE; + + if (G_LIKELY(can_show_graphics_set)) + return can_show_graphics; + + can_show_graphics = can_show_utf8(); + + /* The linux console font typically doesn't have characters we need */ + if (g_strcmp0(g_getenv("TERM"), "linux") == 0) + can_show_graphics = FALSE; + + return can_show_graphics; +} + +/** + * nmc_wifi_strength_bars: + * @strength: the access point strength, from 0 to 100 + * + * Converts @strength into a 4-character-wide graphical representation of + * strength suitable for printing to stdout. If the current locale and terminal + * support it, this will use unicode graphics characters to represent + * "bars". Otherwise, it will use 0 to 4 asterisks. + * + * Returns: the graphical representation of the access point strength + */ +const char * +nmc_wifi_strength_bars(guint8 strength) +{ + if (!can_show_graphics()) + return nm_utils_wifi_strength_bars(strength); + + if (strength > 80) + return /* ▂▄▆█ */ "\342\226\202\342\226\204\342\226\206\342\226\210"; + else if (strength > 55) + return /* ▂▄▆_ */ "\342\226\202\342\226\204\342\226\206_"; + else if (strength > 30) + return /* ▂▄__ */ "\342\226\202\342\226\204__"; + else if (strength > 5) + return /* ▂___ */ "\342\226\202___"; + else + return /* ____ */ "____"; +} + +/** + * nmc_utils_password_subst_char: + * + * Returns: the string substituted when hiding actual password glyphs + */ +const char * +nmc_password_subst_char(void) +{ + if (can_show_graphics()) + return "\u2022"; /* Bullet */ + else + return "*"; +} + +/* + * We actually use a small part of qrcodegen.c, but we'd prefer to keep it + * intact. Include it instead of linking to it to give the compiler a + * chance to optimize bits we don't need away. + */ + +#pragma GCC visibility push(hidden) +NM_PRAGMA_WARNING_DISABLE("-Wdeclaration-after-statement") +#undef NDEBUG +#define NDEBUG +#include "qrcodegen.c" +NM_PRAGMA_WARNING_REENABLE +#pragma GCC visibility pop + +void +nmc_print_qrcode(const char *str) +{ + uint8_t tempBuffer[qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX)]; + uint8_t qrcode[qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX)]; + gboolean term_linux; + int size; + int x; + int y; + + term_linux = g_strcmp0(g_getenv("TERM"), "linux") == 0; + if (!term_linux && !can_show_graphics()) + return; + + if (!qrcodegen_encodeText(str, + tempBuffer, + qrcode, + qrcodegen_Ecc_LOW, + qrcodegen_VERSION_MIN, + qrcodegen_VERSION_MAX, + qrcodegen_Mask_AUTO, + FALSE)) { + return; + } + + size = qrcodegen_getSize(qrcode); + + g_print("\n"); + + if (term_linux) { + /* G1 alternate character set on Linux console. */ + for (y = -1; y < size + 1; y += 1) { + g_print(" \033[37;40;1m\016"); + for (x = -1; x < size + 1; x++) { + g_print(qrcodegen_getModule(qrcode, x, y) ? " " : "\060\060"); + } + g_print("\017\033[0m\n"); + } + } else { + /* UTF-8 */ + for (y = -2; y < size + 2; y += 2) { + g_print(" \033[37;40m"); + for (x = -2; x < size + 2; x++) { + bool top = qrcodegen_getModule(qrcode, x, y); + bool bottom = qrcodegen_getModule(qrcode, x, y + 1); + if (top) { + g_print(bottom ? " " : "\u2584"); + } else { + g_print(bottom ? "\u2580" : "\u2588"); + } + } + g_print("\033[0m\n"); + } + } +} + +/** + * nmc_utils_read_passwd_file: + * @passwd_file: file with passwords to parse + * @out_error_line: returns in case of a syntax error in the file, the line + * on which it occurred. + * @error: location to store error, or %NULL + * + * Parse passwords given in @passwd_file and insert them into a hash table. + * Example of @passwd_file contents: + * wifi.psk:tajne heslo + * 802-1x.password:krakonos + * 802-11-wireless-security:leap-password:my leap password + * + * Returns: (transfer full): hash table with parsed passwords, or %NULL on an error + */ +GHashTable * +nmc_utils_read_passwd_file(const char *passwd_file, gssize *out_error_line, GError **error) +{ + nm_auto_clear_secret_ptr NMSecretPtr contents = {0}; + + NM_SET_OUT(out_error_line, -1); + + if (!passwd_file) + return g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) nm_free_secret); + + if (!nm_utils_file_get_contents(-1, + passwd_file, + 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET, + &contents.str, + &contents.len, + NULL, + error)) + return NULL; + + return nmc_utils_parse_passwd_file(contents.str, out_error_line, error); +} + +GHashTable * +nmc_utils_parse_passwd_file(char * contents /* will be modified */, + gssize * out_error_line, + GError **error) +{ + gs_unref_hashtable GHashTable *pwds_hash = NULL; + const char * contents_str; + gsize contents_line; + + pwds_hash = + g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, (GDestroyNotify) nm_free_secret); + + NM_SET_OUT(out_error_line, -1); + + contents_str = contents; + contents_line = 0; + while (contents_str[0]) { + nm_auto_free_secret char *l_hash_key = NULL; + nm_auto_free_secret char *l_hash_val = NULL; + const char * l_content_line; + const char * l_setting; + const char * l_prop; + const char * l_val; + const char * s; + gsize l_hash_val_len; + + /* consume first line. As line delimiters we accept "\r\n", "\n", and "\r". */ + l_content_line = contents_str; + s = l_content_line; + while (!NM_IN_SET(s[0], '\0', '\r', '\n')) + s++; + if (s[0] != '\0') { + if (s[0] == '\r' && s[1] == '\n') { + ((char *) s)[0] = '\0'; + s += 2; + } else { + ((char *) s)[0] = '\0'; + s += 1; + } + } + contents_str = s; + contents_line++; + + l_content_line = nm_str_skip_leading_spaces(l_content_line); + if (NM_IN_SET(l_content_line[0], '\0', '#')) { + /* a comment or empty line. Ignore. */ + continue; + } + + l_setting = l_content_line; + + s = l_setting; + while (!NM_IN_SET(s[0], '\0', ':', '=')) + s++; + if (s[0] == '\0') { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("missing colon for \".:\" format")); + return NULL; + } + ((char *) s)[0] = '\0'; + s++; + + l_val = s; + + g_strchomp((char *) l_setting); + + nm_assert(nm_str_is_stripped(l_setting)); + + s = strchr(l_setting, '.'); + if (!s) { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("missing dot for \".:\" format")); + return NULL; + } else if (s == l_setting) { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("missing setting for \".:\" format")); + return NULL; + } + ((char *) s)[0] = '\0'; + s++; + + l_prop = s; + if (l_prop[0] == '\0') { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("missing property for \".:\" format")); + return NULL; + } + + /* Accept wifi-sec or wifi instead of cumbersome '802-11-wireless-security' */ + if (NM_IN_STRSET(l_setting, "wifi-sec", "wifi")) + l_setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; + + if (nm_setting_lookup_type(l_setting) == G_TYPE_INVALID) { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("invalid setting name")); + return NULL; + } + + if (nm_streq(l_setting, "vpn") && NM_STR_HAS_PREFIX(l_prop, "secret.")) { + /* in 1.12.0, we wrongly required the VPN secrets to be named + * "vpn.secret". It should be "vpn.secrets". Work around it + * (rh#1628833). */ + l_hash_key = g_strdup_printf("vpn.secrets.%s", &l_prop[NM_STRLEN("secret.")]); + } else + l_hash_key = g_strdup_printf("%s.%s", l_setting, l_prop); + + if (!g_utf8_validate(l_hash_key, -1, NULL)) { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("property name is not UTF-8")); + return NULL; + } + + /* Support backslash escaping in the secret value. We strip non-escaped leading/trailing whitespaces. */ + s = nm_utils_buf_utf8safe_unescape(l_val, + NM_UTILS_STR_UTF8_SAFE_UNESCAPE_STRIP_SPACES, + &l_hash_val_len, + (gpointer *) &l_hash_val); + if (!l_hash_val) + l_hash_val = g_strdup(s); + + if (!g_utf8_validate(l_hash_val, -1, NULL)) { + /* In some cases it might make sense to support binary secrets (like the WPA-PSK which has no + * defined encoding. However, all API that follows can only handle UTF-8, and no mechanism + * to escape the secrets. Reject non-UTF-8 early. */ + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("secret is not UTF-8")); + return NULL; + } + + if (strlen(l_hash_val) != l_hash_val_len) { + NM_SET_OUT(out_error_line, contents_line); + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, _("secret is not UTF-8")); + return NULL; + } + + g_hash_table_insert(pwds_hash, g_steal_pointer(&l_hash_key), g_steal_pointer(&l_hash_val)); + } + + return g_steal_pointer(&pwds_hash); +} diff --git a/src/libnmc-base/nm-client-utils.h b/src/libnmc-base/nm-client-utils.h new file mode 100644 index 0000000..7017e39 --- /dev/null +++ b/src/libnmc-base/nm-client-utils.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2010 - 2017 Red Hat, Inc. + */ + +#ifndef __NM_CLIENT_UTILS_H__ +#define __NM_CLIENT_UTILS_H__ + +#include "nm-active-connection.h" +#include "nm-device.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" + +const NMObject **nmc_objects_sort_by_path(const NMObject *const *objs, gssize len); + +const char *nmc_string_is_valid(const char *input, const char **allowed, GError **error); + +gboolean nmc_string_to_uint(const char * str, + gboolean range_check, + unsigned long int min, + unsigned long int max, + unsigned long int *value); +gboolean nmc_string_to_bool(const char *str, gboolean *val_bool, GError **error); +gboolean nmc_string_to_ternary(const char *str, NMTernary *val, GError **error); + +gboolean matches(const char *cmd, const char *pattern); + +/* FIXME: don't expose this function on its own, at least not from this file. */ +const char *nmc_bond_validate_mode(const char *mode, GError **error); + +const char *nmc_device_state_to_string_with_external(NMDevice *device); + +const char *nm_active_connection_state_reason_to_string(NMActiveConnectionStateReason reason); +const char *nmc_device_state_to_string(NMDeviceState state); +const char *nmc_device_reason_to_string(NMDeviceStateReason reason); +const char *nmc_device_metered_to_string(NMMetered value); + +NMActiveConnectionState nmc_activation_get_effective_state(NMActiveConnection *active, + NMDevice * device, + const char ** reason); + +const char *nmc_wifi_strength_bars(guint8 strength); + +const char *nmc_password_subst_char(void); + +void nmc_print_qrcode(const char *str); + +GHashTable *nmc_utils_parse_passwd_file(char *contents, gssize *out_error_line, GError **error); + +GHashTable * +nmc_utils_read_passwd_file(const char *passwd_file, gssize *out_error_line, GError **error); + +#endif /* __NM_CLIENT_UTILS_H__ */ diff --git a/src/libnmc-base/nm-polkit-listener.c b/src/libnmc-base/nm-polkit-listener.c new file mode 100644 index 0000000..29c25b4 --- /dev/null +++ b/src/libnmc-base/nm-polkit-listener.c @@ -0,0 +1,910 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +/** + * SECTION:nm-polkit-listener + * @short_description: A polkit agent listener + * + * #NMPolkitListener is the polkit agent listener used by nmcli and nmtui. + * http://www.freedesktop.org/software/polkit/docs/latest/index.html + * + * For an example polkit agent you can look at polkit source tree: + * http://cgit.freedesktop.org/polkit/tree/src/polkitagent/polkitagenttextlistener.c + * http://cgit.freedesktop.org/polkit/tree/src/programs/pkttyagent.c + * or LXDE polkit agent: + * http://git.lxde.org/gitweb/?p=debian/lxpolkit.git;a=blob;f=src/lxpolkit-listener.c + * https://github.com/lxde/lxqt-policykit/tree/master/src + */ + +#include "libnm-client-aux-extern/nm-default-client.h" + +#include "nm-polkit-listener.h" + +#include +#include +#include + +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" +#include "c-list/src/c-list.h" + +#define LOGIND_BUS_NAME "org.freedesktop.login1" +#define POLKIT_BUS_NAME "org.freedesktop.PolicyKit1" + +#define POLKIT_AUTHORITY_OBJ_PATH "/org/freedesktop/PolicyKit1/Authority" +#define POLKIT_AUTHORITY_IFACE_NAME "org.freedesktop.PolicyKit1.Authority" + +#define POLKIT_AGENT_OBJ_PATH "/org/freedesktop/PolicyKit1/AuthenticationAgent" +#define POLKIT_AGENT_DBUS_INTERFACE "org.freedesktop.PolicyKit1.AuthenticationAgent" + +#define LOGIND_OBJ_PATH "/org/freedesktop/login1" +#define LOGIND_MANAGER_INTERFACE "org.freedesktop.login1.Manager" + +#define NM_POLKIT_LISTENER_DBUS_CONNECTION "dbus-connection" +#define NM_POLKIT_LISTENER_SESSION_AGENT "session-agent" + +#define POLKIT_DBUS_ERROR_FAILED "org.freedesktop.PolicyKit1.Error.Failed" + +/*****************************************************************************/ + +enum { REGISTERED, REQUEST_SYNC, ERROR, LAST_SIGNAL }; + +static guint signals[LAST_SIGNAL] = {0}; + +struct _NMPolkitListener { + GObject parent; + GDBusConnection *dbus_connection; + char * name_owner; + GCancellable * cancellable; + GMainContext * main_context; + CList request_lst_head; + guint pk_auth_agent_reg_id; + guint name_owner_changed_id; + bool session_agent : 1; +}; + +struct _NMPolkitListenerClass { + GObjectClass parent; +}; + +G_DEFINE_TYPE(NMPolkitListener, nm_polkit_listener, G_TYPE_OBJECT); + +/*****************************************************************************/ + +typedef struct { + CList request_lst; + + NMPolkitListener * listener; + GSource * child_stdout_watch_source; + GSource * child_stdin_watch_source; + GDBusMethodInvocation *dbus_invocation; + char * action_id; + char * message; + char * username; + char * cookie; + NMStrBuf in_buffer; + NMStrBuf out_buffer; + gsize out_buffer_offset; + + int child_stdout; + int child_stdin; + + bool request_any_response : 1; + bool request_is_completed : 1; +} AuthRequest; + +static const GDBusInterfaceInfo interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + POLKIT_AGENT_DBUS_INTERFACE, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS( + NM_DEFINE_GDBUS_METHOD_INFO("BeginAuthentication", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("action_id", "s"), + NM_DEFINE_GDBUS_ARG_INFO("message", "s"), + NM_DEFINE_GDBUS_ARG_INFO("icon_name", "s"), + NM_DEFINE_GDBUS_ARG_INFO("details", "a{ss}"), + NM_DEFINE_GDBUS_ARG_INFO("cookie", "s"), + NM_DEFINE_GDBUS_ARG_INFO("identities", "a(sa{sv})"), ), ), + NM_DEFINE_GDBUS_METHOD_INFO("CancelAuthentication", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("cookie", "s"), ), ), ), ); + +static void +auth_request_complete(AuthRequest *request, gboolean success) +{ + c_list_unlink(&request->request_lst); + + if (success) + g_dbus_method_invocation_return_value(request->dbus_invocation, NULL); + else { + g_dbus_method_invocation_return_dbus_error(request->dbus_invocation, + POLKIT_DBUS_ERROR_FAILED, + ""); + } + + nm_clear_g_free(&request->action_id); + nm_clear_g_free(&request->message); + nm_clear_g_free(&request->username); + nm_clear_g_free(&request->cookie); + nm_clear_g_source_inst(&request->child_stdout_watch_source); + nm_clear_g_source_inst(&request->child_stdin_watch_source); + + nm_str_buf_destroy(&request->in_buffer); + nm_str_buf_destroy(&request->out_buffer); + + if (request->child_stdout != -1) { + nm_close(request->child_stdout); + request->child_stdout = -1; + } + + if (request->child_stdin != -1) { + nm_close(request->child_stdin); + request->child_stdin = -1; + } + + nm_g_slice_free(request); +} + +static gboolean +uid_to_name(uid_t uid, gboolean *out_cached, char **out_name) +{ + if (!*out_cached) { + *out_cached = TRUE; + *out_name = nm_utils_uid_to_name(uid); + } + return !!(*out_name); +} + +static char * +choose_identity(GVariant *identities) +{ + GVariantIter identity_iter; + GVariant * details_tmp; + const char * kind; + gs_free char *username_first = NULL; + gs_free char *username_root = NULL; + const char * user; + + /* Choose identity. First try current user, then root, and else + * take the first one we find. */ + + user = getenv("USER"); + + g_variant_iter_init(&identity_iter, identities); + while (g_variant_iter_next(&identity_iter, "(&s@a{sv})", &kind, &details_tmp)) { + gs_unref_variant GVariant *details = g_steal_pointer(&details_tmp); + + if (nm_streq(kind, "unix-user")) { + gs_unref_variant GVariant *v = NULL; + + v = g_variant_lookup_value(details, "uid", G_VARIANT_TYPE_UINT32); + if (v) { + guint32 uid = g_variant_get_uint32(v); + gs_free char *u = NULL; + gboolean cached = FALSE; + + if (user) { + if (!uid_to_name(uid, &cached, &u)) + continue; + if (nm_streq(u, user)) + return g_steal_pointer(&u); + } + if (!username_root && uid == 0) { + if (!uid_to_name(uid, &cached, &u)) + continue; + username_root = g_strdup(u); + if (!user) + break; + } + if (!username_root && !username_first) { + if (!uid_to_name(uid, &cached, &u)) + continue; + username_first = g_strdup(u); + } + } + } + } + + if (username_root) + return g_steal_pointer(&username_root); + + if (username_first) + return g_steal_pointer(&username_first); + + return NULL; +} + +static void +agent_register_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + NMPolkitListener *listener = NM_POLKIT_LISTENER(user_data); + GDBusConnection * dbus_connection = G_DBUS_CONNECTION(source_object); + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *ret = NULL; + + ret = g_dbus_connection_call_finish(dbus_connection, res, &error); + + if (nm_utils_error_is_cancelled(error)) { + return; + } + + if (ret) { + g_signal_emit(listener, signals[REGISTERED], 0); + } else { + g_signal_emit(listener, signals[ERROR], 0, error->message); + } +} + +static void +agent_register(NMPolkitListener *self, const char *session_id) +{ + const char * locale = NULL; + gs_unref_object NMAuthSubject *subject = NULL; + GVariant * subject_variant = NULL; + + locale = g_getenv("LANG"); + if (locale == NULL) { + locale = "en_US.UTF-8"; + } + + if (self->session_agent) { + subject = nm_auth_subject_new_unix_session(session_id); + } else { + subject = nm_auth_subject_new_unix_process_self(); + } + subject_variant = nm_auth_subject_unix_to_polkit_gvariant(subject); + + g_dbus_connection_call( + self->dbus_connection, + self->name_owner, + POLKIT_AUTHORITY_OBJ_PATH, + POLKIT_AUTHORITY_IFACE_NAME, + "RegisterAuthenticationAgent", + g_variant_new("(@(sa{sv})ss)", subject_variant, locale, POLKIT_AGENT_OBJ_PATH), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + self->cancellable, + agent_register_cb, + self); +} + +static void +agent_unregister(NMPolkitListener *self) +{ + gs_unref_object NMAuthSubject *subject = NULL; + GVariant * subject_variant = NULL; + + subject = nm_auth_subject_new_unix_process_self(); + subject_variant = nm_auth_subject_unix_to_polkit_gvariant(subject); + + g_dbus_connection_call(self->dbus_connection, + self->name_owner, + POLKIT_AUTHORITY_OBJ_PATH, + POLKIT_AUTHORITY_IFACE_NAME, + "UnregisterAuthenticationAgent", + g_variant_new("(@(sa{sv})s)", subject_variant, POLKIT_AGENT_OBJ_PATH), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + self); +} + +static void +retrieve_session_id_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + NMPolkitListener * listener = NM_POLKIT_LISTENER(user_data); + char * session_id; + guint32 session_uid; + nm_auto_free_variant_iter GVariantIter *iter = NULL; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + gs_free char * err_str = NULL; + uid_t uid = getuid(); + + ret = g_dbus_connection_call_finish(listener->dbus_connection, res, &error); + + if (nm_utils_error_is_cancelled(error)) { + return; + } + + if (ret) { + g_variant_get_child(ret, 0, "a(susso)", &iter); + + while ( + g_variant_iter_next(iter, "(&su@s@s@o)", &session_id, &session_uid, NULL, NULL, NULL)) { + if (session_uid == uid) { + agent_register(listener, session_id); + return; + } + } + err_str = g_strdup_printf(_("Could not find any session id for uid %d"), uid); + } else { + err_str = g_strdup_printf(_("Could not retrieve session id: %s"), error->message); + } + + g_signal_emit(listener, signals[ERROR], 0, err_str); +} + +static void +retrieve_session_id(NMPolkitListener *self) +{ + g_dbus_connection_call(self->dbus_connection, + LOGIND_BUS_NAME, + LOGIND_OBJ_PATH, + LOGIND_MANAGER_INTERFACE, + "ListSessions", + NULL, + G_VARIANT_TYPE("(a(susso))"), + G_DBUS_CALL_FLAGS_NONE, + -1, + self->cancellable, + retrieve_session_id_cb, + self); +} + +static gboolean +io_watch_can_write(int fd, GIOCondition condition, gpointer user_data) +{ + AuthRequest *request = user_data; + gssize n_written; + + if (NM_FLAGS_ANY(condition, (G_IO_HUP | G_IO_ERR))) + goto done; + + n_written = + write(request->child_stdin, + &((nm_str_buf_get_str_unsafe(&request->out_buffer))[request->out_buffer_offset]), + request->out_buffer.len - request->out_buffer_offset); + + if (n_written < 0 && errno != EAGAIN) + goto done; + + if (n_written > 0) { + if ((gsize) n_written >= (request->out_buffer.len - request->out_buffer_offset)) { + nm_assert((gsize) n_written == (request->out_buffer.len - request->out_buffer_offset)); + goto done; + } + request->out_buffer_offset += (gsize) n_written; + } + + return G_SOURCE_CONTINUE; + +done: + nm_str_buf_set_size(&request->out_buffer, 0, TRUE, FALSE); + request->out_buffer_offset = 0; + nm_clear_g_source_inst(&request->child_stdin_watch_source); + + if (request->request_is_completed) + auth_request_complete(request, TRUE); + + return G_SOURCE_CONTINUE; +} + +static void +queue_string_to_helper(AuthRequest *request, const char *response) +{ + g_return_if_fail(response); + + if (!nm_str_buf_is_initalized(&request->out_buffer)) + nm_str_buf_init(&request->out_buffer, strlen(response) + 2u, TRUE); + + nm_str_buf_append(&request->out_buffer, response); + nm_str_buf_ensure_trailing_c(&request->out_buffer, '\n'); + + if (!request->child_stdin_watch_source) { + request->child_stdin_watch_source = nm_g_unix_fd_source_new(request->child_stdin, + G_IO_OUT | G_IO_ERR | G_IO_HUP, + G_PRIORITY_DEFAULT, + io_watch_can_write, + request, + NULL); + g_source_attach(request->child_stdin_watch_source, request->listener->main_context); + } +} + +static gboolean +io_watch_have_data(int fd, GIOCondition condition, gpointer user_data) +{ + AuthRequest *request = user_data; + gboolean auth_result; + gssize n_read; + + if (NM_FLAGS_ANY(condition, G_IO_HUP | G_IO_ERR)) + n_read = -EIO; + else + n_read = nm_utils_fd_read(fd, &request->in_buffer); + + if (n_read <= 0) { + if (n_read == -EAGAIN) { + /* wait longer. */ + return G_SOURCE_CONTINUE; + } + + /* Either an error or EOF happened. The data we parsed so far was not relevant. + * Regardless of what we still have unprocessed in the receive buffers, we are done. + * + * We would expect that the other side completed with SUCCESS or FAILURE. Apparently + * it didn't. If we had any good request, we assume success. */ + auth_result = request->request_any_response; + goto out; + } + + while (TRUE) { + char * line_terminator; + const char *line; + + line = nm_str_buf_get_str(&request->in_buffer); + line_terminator = (char *) strchr(line, '\n'); + if (!line_terminator) { + /* We don't have a complete line. Wait longer. */ + return G_SOURCE_CONTINUE; + } + line_terminator[0] = '\0'; + + if (NM_STR_HAS_PREFIX(line, "PAM_PROMPT_ECHO_OFF ") + || NM_STR_HAS_PREFIX(line, "PAM_PROMPT_ECHO_ON ")) { + nm_auto_free_secret char *response = NULL; + + /* FIXME(cli-async): emit signal and wait for response (blocking) */ + g_signal_emit(request->listener, + signals[REQUEST_SYNC], + 0, + request->action_id, + request->message, + request->username, + &response); + + if (response) { + queue_string_to_helper(request, response); + request->request_any_response = TRUE; + goto erase_line; + } + auth_result = FALSE; + } else if (nm_streq(line, "SUCCESS")) + auth_result = TRUE; + else if (nm_streq(line, "FAILURE")) + auth_result = FALSE; + else if (NM_STR_HAS_PREFIX(line, "PAM_ERROR_MSG ") + || NM_STR_HAS_PREFIX(line, "PAM_TEXT_INFO ")) { + /* ignore. */ + goto erase_line; + } else { + /* unknown command. Fail. */ + auth_result = FALSE; + } + + break; +erase_line: + nm_str_buf_erase(&request->in_buffer, 0, line_terminator - line + 1u, TRUE); + } + +out: + request->request_is_completed = TRUE; + nm_clear_g_source_inst(&request->child_stdout_watch_source); + if (auth_result && request->child_stdin_watch_source) { + /* we need to wait for the buffer to send the response. */ + } else + auth_request_complete(request, auth_result); + + return G_SOURCE_CONTINUE; +} + +static void +begin_authentication(AuthRequest *request) +{ + int fd_flags; + const char *helper_argv[] = { + POLKIT_AGENT_HELPER_1_PATH, + request->username, + NULL, + }; + + if (!request->username) { + auth_request_complete(request, FALSE); + return; + } + + if (!g_spawn_async_with_pipes(NULL, + (char **) helper_argv, + NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, + NULL, + NULL, + &request->child_stdin, + &request->child_stdout, + NULL, + NULL)) { + /* not findind the PolicyKit setuid helper is a critical error */ + request->child_stdin = -1; + request->child_stdout = -1; + g_signal_emit(request->listener, + signals[ERROR], + 0, + "The PolicyKit setuid helper 'polkit-agent-helper-1' has not been found"); + + auth_request_complete(request, FALSE); + return; + } + + fd_flags = fcntl(request->child_stdin, F_GETFD, 0); + fcntl(request->child_stdin, F_SETFL, fd_flags | O_NONBLOCK); + + fd_flags = fcntl(request->child_stdout, F_GETFD, 0); + fcntl(request->child_stdout, F_SETFL, fd_flags | O_NONBLOCK); + + request->child_stdout_watch_source = nm_g_unix_fd_source_new(request->child_stdout, + G_IO_IN | G_IO_ERR | G_IO_HUP, + G_PRIORITY_DEFAULT, + io_watch_have_data, + request, + NULL); + g_source_attach(request->child_stdout_watch_source, request->listener->main_context); + + /* Write the cookie on stdin so it can't be seen by other processes */ + queue_string_to_helper(request, request->cookie); + + return; +} + +static AuthRequest * +get_request(NMPolkitListener *listener, const char *cookie) +{ + AuthRequest *request; + + c_list_for_each_entry (request, &listener->request_lst_head, request_lst) { + if (nm_streq0(cookie, request->cookie)) { + return request; + } + } + return NULL; +} + +static AuthRequest * +create_request(NMPolkitListener * listener, + GDBusMethodInvocation *invocation, + const char * action_id, + const char * message, + char * username_take, + const char * cookie) +{ + AuthRequest *request; + + request = g_slice_new(AuthRequest); + *request = (AuthRequest){ + .listener = listener, + .dbus_invocation = invocation, + .action_id = g_strdup(action_id), + .message = g_strdup(message), + .username = g_steal_pointer(&username_take), + .cookie = g_strdup(cookie), + .request_any_response = FALSE, + .request_is_completed = FALSE, + }; + + nm_str_buf_init(&request->in_buffer, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, FALSE); + + c_list_link_tail(&listener->request_lst_head, &request->request_lst); + return request; +} + +static void +dbus_method_call_cb(GDBusConnection * connection, + const char * sender, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + NMPolkitListener *listener = NM_POLKIT_LISTENER(user_data); + const char * action_id; + const char * message; + const char * cookie; + AuthRequest * request; + gs_unref_variant GVariant *identities_gvariant = NULL; + + if (nm_streq(method_name, "BeginAuthentication")) { + g_variant_get(parameters, + "(&s&s&s@a{ss}&s@a(sa{sv}))", + &action_id, + &message, + NULL, + NULL, + &cookie, + &identities_gvariant); + + request = create_request(listener, + invocation, + action_id, + message, + choose_identity(identities_gvariant), + cookie); + begin_authentication(request); + return; + } + + if (nm_streq(method_name, "CancelAuthentication")) { + g_variant_get(parameters, "&s", &cookie); + request = get_request(listener, cookie); + + if (!request) { + gs_free char *msg = NULL; + + msg = g_strdup_printf("No pending authentication request for cookie '%s'", cookie); + g_dbus_method_invocation_return_dbus_error(invocation, POLKIT_DBUS_ERROR_FAILED, msg); + return; + } + + /* Complete a cancelled request with success. */ + auth_request_complete(request, TRUE); + return; + } + + g_dbus_method_invocation_return_error(invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "Unknown method %s", + method_name); +} + +static gboolean +export_dbus_iface(NMPolkitListener *self, GError **error) +{ + GDBusInterfaceVTable interface_vtable = { + .method_call = dbus_method_call_cb, + .set_property = NULL, + .get_property = NULL, + }; + + g_return_val_if_fail(NM_IS_POLKIT_LISTENER(self), FALSE); + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + + /* Agent listener iface has been exported already */ + if (self->pk_auth_agent_reg_id) { + return TRUE; + } + + self->pk_auth_agent_reg_id = + g_dbus_connection_register_object(self->dbus_connection, + POLKIT_AGENT_OBJ_PATH, + (GDBusInterfaceInfo *) &interface_info, + &interface_vtable, + self, + NULL, + error); + if (!self->pk_auth_agent_reg_id) { + g_signal_emit(self, + signals[ERROR], + 0, + "Could not register as a PolicyKit Authentication Agent"); + } + return self->pk_auth_agent_reg_id; +} + +static void +name_owner_changed(NMPolkitListener *self, const char *name_owner) +{ + gs_free_error GError *error = NULL; + + name_owner = nm_str_not_empty(name_owner); + + if (nm_streq0(self->name_owner, name_owner)) { + return; + } + + g_free(self->name_owner); + self->name_owner = g_strdup(name_owner); + + if (!self->name_owner) { + return; + } + + if (export_dbus_iface(self, &error)) { + if (self->session_agent) { + retrieve_session_id(self); + } else { + agent_register(self, NULL); + } + } else { + g_signal_emit(self, + signals[ERROR], + 0, + "Could not export the PolicyKit Authentication Agent DBus interface"); + } +} + +static void +name_owner_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMPolkitListener *self = user_data; + const char * new_owner; + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) { + return; + } + + g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_owner); + + name_owner_changed(self, new_owner); +} + +static void +get_name_owner_cb(const char *name_owner, GError *error, gpointer user_data) +{ + if (!name_owner && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + return; + } + name_owner_changed(user_data, name_owner); +} + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMPolkitListener, PROP_DBUS_CONNECTION, PROP_SESSION_AGENT, ); + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMPolkitListener *self = NM_POLKIT_LISTENER(object); + + switch (prop_id) { + case PROP_DBUS_CONNECTION: + self->dbus_connection = g_value_dup_object(value); + break; + case PROP_SESSION_AGENT: + self->session_agent = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +nm_polkit_listener_init(NMPolkitListener *self) +{ + c_list_init(&self->request_lst_head); + self->main_context = g_main_context_ref_thread_default(); +} + +static void +constructed(GObject *object) +{ + NMPolkitListener *self = NM_POLKIT_LISTENER(object); + + self->cancellable = g_cancellable_new(); + + self->name_owner_changed_id = + nm_dbus_connection_signal_subscribe_name_owner_changed(self->dbus_connection, + POLKIT_BUS_NAME, + name_owner_changed_cb, + self, + NULL); + + nm_dbus_connection_call_get_name_owner(self->dbus_connection, + POLKIT_BUS_NAME, + -1, + self->cancellable, + get_name_owner_cb, + self); + + G_OBJECT_CLASS(nm_polkit_listener_parent_class)->constructed(object); +} + +/** + * nm_polkit_listener_new: + * @dbus_connection: a open DBus connection + * @session_agent: TRUE if a session agent is wanted, FALSE for a process agent + * + * Creates a new #NMPolkitListener and registers it as a polkit agent. + * + * Returns: a new #NMPolkitListener + */ +NMPolkitListener * +nm_polkit_listener_new(GDBusConnection *dbus_connection, gboolean session_agent) +{ + return g_object_new(NM_TYPE_POLKIT_LISTENER, + NM_POLKIT_LISTENER_DBUS_CONNECTION, + dbus_connection, + NM_POLKIT_LISTENER_SESSION_AGENT, + session_agent, + NULL); +} + +static void +dispose(GObject *object) +{ + NMPolkitListener *self = NM_POLKIT_LISTENER(object); + AuthRequest * request; + + nm_clear_g_cancellable(&self->cancellable); + + while ((request = c_list_first_entry(&self->request_lst_head, AuthRequest, request_lst))) + auth_request_complete(request, FALSE); + + if (self->dbus_connection) { + nm_clear_g_dbus_connection_signal(self->dbus_connection, &self->name_owner_changed_id); + g_dbus_connection_unregister_object(self->dbus_connection, self->pk_auth_agent_reg_id); + agent_unregister(self); + nm_clear_g_free(&self->name_owner); + g_clear_object(&self->dbus_connection); + } + + nm_clear_pointer(&self->main_context, g_main_context_unref); + + G_OBJECT_CLASS(nm_polkit_listener_parent_class)->dispose(object); +} + +static void +nm_polkit_listener_class_init(NMPolkitListenerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->set_property = set_property; + object_class->constructed = constructed; + object_class->dispose = dispose; + + obj_properties[PROP_DBUS_CONNECTION] = + g_param_spec_object(NM_POLKIT_LISTENER_DBUS_CONNECTION, + "", + "", + G_TYPE_DBUS_CONNECTION, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SESSION_AGENT] = + g_param_spec_boolean(NM_POLKIT_LISTENER_SESSION_AGENT, + "", + "", + FALSE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + signals[REQUEST_SYNC] = g_signal_new(NM_POLKIT_LISTENER_SIGNAL_REQUEST_SYNC, + NM_TYPE_POLKIT_LISTENER, + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + NULL, + G_TYPE_STRING, + 3, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + + signals[REGISTERED] = g_signal_new(NM_POLKIT_LISTENER_SIGNAL_REGISTERED, + NM_TYPE_POLKIT_LISTENER, + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0); + + signals[ERROR] = g_signal_new(NM_POLKIT_LISTENER_SIGNAL_ERROR, + NM_TYPE_POLKIT_LISTENER, + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_STRING); +} diff --git a/src/libnmc-base/nm-polkit-listener.h b/src/libnmc-base/nm-polkit-listener.h new file mode 100644 index 0000000..8a4c6c3 --- /dev/null +++ b/src/libnmc-base/nm-polkit-listener.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NM_POLKIT_LISTENER_H__ +#define __NM_POLKIT_LISTENER_H__ + +#define NM_POLKIT_LISTENER_SIGNAL_REGISTERED "registered" +#define NM_POLKIT_LISTENER_SIGNAL_REQUEST_SYNC "request-sync" +#define NM_POLKIT_LISTENER_SIGNAL_AUTH_SUCCESS "auth-success" +#define NM_POLKIT_LISTENER_SIGNAL_AUTH_FAILURE "auth-failure" +#define NM_POLKIT_LISTENER_SIGNAL_ERROR "error" + +typedef struct _NMPolkitListener NMPolkitListener; +typedef struct _NMPolkitListenerClass NMPolkitListenerClass; + +#define NM_TYPE_POLKIT_LISTENER (nm_polkit_listener_get_type()) +#define NM_POLKIT_LISTENER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_POLKIT_LISTENER, NMPolkitListener)) +#define NM_POLKIT_LISTENER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_POLKIT_LISTENER, NMPolkitListenerClass)) +#define NM_IS_POLKIT_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_POLKIT_LISTENER)) +#define NM_IS_POLKIT_LISTENER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_POLKIT_LISTENER)) +#define NM_POLKIT_LISTENER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_POLKIT_LISTENER, NMPolkitListenerClass)) + +GType nm_polkit_listener_get_type(void); + +NMPolkitListener *nm_polkit_listener_new(GDBusConnection *dbus_connection, gboolean session_agent); + +#endif /* __NM_POLKIT_LISTENER_H__ */ diff --git a/src/libnmc-base/nm-secret-agent-simple.c b/src/libnmc-base/nm-secret-agent-simple.c new file mode 100644 index 0000000..69617d0 --- /dev/null +++ b/src/libnmc-base/nm-secret-agent-simple.c @@ -0,0 +1,1402 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2011 - 2015 Red Hat, Inc. + * Copyright (C) 2011 Giovanni Campagna + */ + +/** + * SECTION:nm-secret-agent-simple + * @short_description: A simple secret agent for NetworkManager + * + * #NMSecretAgentSimple is the secret agent used by nmtui-connect and nmcli. + * + * This is a stripped-down version of gnome-shell's ShellNetworkAgent, + * with bits of the corresponding JavaScript code squished down into + * it. It is intended to eventually be generic enough that it could + * replace ShellNetworkAgent. + */ + +#include "libnm-client-aux-extern/nm-default-client.h" + +#include "nm-secret-agent-simple.h" + +#include +#include + +#include "nm-vpn-service-plugin.h" +#include "nm-vpn-helpers.h" +#include "libnm-glib-aux/nm-secret-utils.h" + +/*****************************************************************************/ + +typedef struct { + char *request_id; + + NMSecretAgentSimple *self; + + NMConnection * connection; + const char * setting_name; + char ** hints; + NMSecretAgentOldGetSecretsFunc callback; + gpointer callback_data; + GCancellable * cancellable; + NMSecretAgentGetSecretsFlags flags; +} RequestData; + +enum { + REQUEST_SECRETS, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +typedef struct { + GHashTable *requests; + + char * path; + gboolean enabled; +} NMSecretAgentSimplePrivate; + +struct _NMSecretAgentSimple { + NMSecretAgentOld parent; + NMSecretAgentSimplePrivate _priv; +}; + +struct _NMSecretAgentSimpleClass { + NMSecretAgentOldClass parent; +}; + +G_DEFINE_TYPE(NMSecretAgentSimple, nm_secret_agent_simple, NM_TYPE_SECRET_AGENT_OLD) + +#define NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSecretAgentSimple, NM_IS_SECRET_AGENT_SIMPLE, NMSecretAgentOld) + +/*****************************************************************************/ + +static void +_request_data_free(gpointer data) +{ + RequestData *request = data; + + g_free(request->request_id); + nm_clear_g_cancellable(&request->cancellable); + g_object_unref(request->connection); + g_strfreev(request->hints); + + g_slice_free(RequestData, request); +} + +static void +_request_data_complete(RequestData * request, + GVariant * secrets, + GError * error, + GHashTableIter *iter_to_remove) +{ + NMSecretAgentSimple * self = request->self; + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(self); + + nm_assert((secrets != NULL) != (error != NULL)); + + request->callback(NM_SECRET_AGENT_OLD(request->self), + request->connection, + secrets, + error, + request->callback_data); + + if (iter_to_remove) + g_hash_table_iter_remove(iter_to_remove); + else + g_hash_table_remove(priv->requests, request); +} + +/*****************************************************************************/ + +/** + * NMSecretAgentSimpleSecret: + * @name: the user-visible name of the secret. Eg, "WEP Passphrase". + * @value: the value of the secret + * @password: %TRUE if this secret represents a password, %FALSE + * if it represents non-secret data. + * + * A single "secret" being requested. + */ + +typedef struct { + NMSecretAgentSimpleSecret base; + NMSetting * setting; + char * property; +} SecretReal; + +static void +_secret_real_free(NMSecretAgentSimpleSecret *secret) +{ + SecretReal *real = (SecretReal *) secret; + + g_free((char *) secret->pretty_name); + g_free((char *) secret->entry_id); + nm_free_secret(secret->value); + g_free((char *) secret->vpn_type); + g_free(real->property); + g_clear_object(&real->setting); + + g_slice_free(SecretReal, real); +} + +static NMSecretAgentSimpleSecret * +_secret_real_new_plain(NMSecretAgentSecretType secret_type, + const char * pretty_name, + NMSetting * setting, + const char * property) +{ + SecretReal * real; + gs_free char *value = NULL; + + nm_assert(property); + nm_assert(NM_IS_SETTING(setting)); + nm_assert(NM_IN_SET(secret_type, + NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + NM_SECRET_AGENT_SECRET_TYPE_SECRET)); + nm_assert(g_object_class_find_property(G_OBJECT_GET_CLASS(setting), property)); + nm_assert((secret_type == NM_SECRET_AGENT_SECRET_TYPE_SECRET) + == nm_setting_get_secret_flags(setting, property, NULL, NULL)); + + g_object_get(setting, property, &value, NULL); + + real = g_slice_new(SecretReal); + *real = (SecretReal){ + .base.secret_type = secret_type, + .base.pretty_name = g_strdup(pretty_name), + .base.entry_id = g_strdup_printf("%s.%s", nm_setting_get_name(setting), property), + .base.value = g_steal_pointer(&value), + .base.is_secret = (secret_type != NM_SECRET_AGENT_SECRET_TYPE_PROPERTY), + .setting = g_object_ref(setting), + .property = g_strdup(property), + }; + return &real->base; +} + +static NMSecretAgentSimpleSecret * +_secret_real_new_vpn_secret(const char *pretty_name, + NMSetting * setting, + const char *property, + const char *vpn_type) +{ + SecretReal *real; + const char *value; + + nm_assert(property); + nm_assert(NM_IS_SETTING_VPN(setting)); + nm_assert(vpn_type); + + value = nm_setting_vpn_get_secret(NM_SETTING_VPN(setting), property); + + real = g_slice_new(SecretReal); + *real = (SecretReal){ + .base.secret_type = NM_SECRET_AGENT_SECRET_TYPE_VPN_SECRET, + .base.pretty_name = g_strdup(pretty_name), + .base.entry_id = + g_strdup_printf("%s%s", NM_SECRET_AGENT_ENTRY_ID_PREFX_VPN_SECRETS, property), + .base.value = g_strdup(value), + .base.is_secret = TRUE, + .base.vpn_type = g_strdup(vpn_type), + .setting = g_object_ref(setting), + .property = g_strdup(property), + }; + return &real->base; +} + +static NMSecretAgentSimpleSecret * +_secret_real_new_wireguard_peer_psk(NMSettingWireGuard *s_wg, + const char * public_key, + const char * preshared_key) +{ + SecretReal *real; + + nm_assert(NM_IS_SETTING_WIREGUARD(s_wg)); + nm_assert(public_key); + + real = g_slice_new(SecretReal); + *real = (SecretReal){ + .base.secret_type = NM_SECRET_AGENT_SECRET_TYPE_WIREGUARD_PEER_PSK, + .base.pretty_name = g_strdup_printf(_("Preshared-key for %s"), public_key), + .base.entry_id = g_strdup_printf(NM_SETTING_WIREGUARD_SETTING_NAME + "." NM_SETTING_WIREGUARD_PEERS + ".%s." NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY, + public_key), + .base.value = g_strdup(preshared_key), + .base.is_secret = TRUE, + .base.no_prompt_entry_id = TRUE, + .setting = NM_SETTING(g_object_ref(s_wg)), + .property = g_strdup(public_key), + }; + return &real->base; +} + +/*****************************************************************************/ + +static gboolean +add_8021x_secrets(RequestData *request, GPtrArray *secrets) +{ + NMSetting8021x * s_8021x = nm_connection_get_setting_802_1x(request->connection); + const char * eap_method; + NMSecretAgentSimpleSecret *secret; + + /* If hints are given, then always ask for what the hints require */ + if (request->hints && request->hints[0]) { + char **iter; + + for (iter = request->hints; *iter; iter++) { + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _(*iter), + NM_SETTING(s_8021x), + *iter); + g_ptr_array_add(secrets, secret); + } + + return TRUE; + } + + eap_method = nm_setting_802_1x_get_eap_method(s_8021x, 0); + if (!eap_method) + return FALSE; + + if (NM_IN_STRSET(eap_method, "md5", "leap", "ttls", "peap")) { + /* TTLS and PEAP are actually much more complicated, but this complication + * is not visible here since we only care about phase2 authentication + * (and don't even care of which one) + */ + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + _("Username"), + NM_SETTING(s_8021x), + NM_SETTING_802_1X_IDENTITY); + g_ptr_array_add(secrets, secret); + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING(s_8021x), + NM_SETTING_802_1X_PASSWORD); + g_ptr_array_add(secrets, secret); + return TRUE; + } + + if (nm_streq(eap_method, "tls")) { + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + _("Identity"), + NM_SETTING(s_8021x), + NM_SETTING_802_1X_IDENTITY); + g_ptr_array_add(secrets, secret); + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Private key password"), + NM_SETTING(s_8021x), + NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + g_ptr_array_add(secrets, secret); + return TRUE; + } + + return FALSE; +} + +static gboolean +add_wireless_secrets(RequestData *request, GPtrArray *secrets) +{ + NMSettingWirelessSecurity *s_wsec = + nm_connection_get_setting_wireless_security(request->connection); + const char * key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + NMSecretAgentSimpleSecret *secret; + + if (!key_mgmt || nm_streq(key_mgmt, "owe")) + return FALSE; + + if (NM_IN_STRSET(key_mgmt, "wpa-psk", "sae")) { + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING(s_wsec), + NM_SETTING_WIRELESS_SECURITY_PSK); + g_ptr_array_add(secrets, secret); + return TRUE; + } + + if (nm_streq(key_mgmt, "none")) { + guint32 index; + char key[100]; + + index = nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec); + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Key"), + NM_SETTING(s_wsec), + nm_sprintf_buf(key, "wep-key%u", (guint) index)); + g_ptr_array_add(secrets, secret); + return TRUE; + } + + if (nm_streq(key_mgmt, "iee8021x")) { + if (nm_streq0(nm_setting_wireless_security_get_auth_alg(s_wsec), "leap")) { + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING(s_wsec), + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD); + g_ptr_array_add(secrets, secret); + return TRUE; + } else + return add_8021x_secrets(request, secrets); + } + + if (nm_streq(key_mgmt, "wpa-eap") || nm_streq(key_mgmt, "wpa-eap-suite-b-192")) + return add_8021x_secrets(request, secrets); + + return FALSE; +} + +static gboolean +add_pppoe_secrets(RequestData *request, GPtrArray *secrets) +{ + NMSettingPppoe * s_pppoe = nm_connection_get_setting_pppoe(request->connection); + NMSecretAgentSimpleSecret *secret; + + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + _("Username"), + NM_SETTING(s_pppoe), + NM_SETTING_PPPOE_USERNAME); + g_ptr_array_add(secrets, secret); + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + _("Service"), + NM_SETTING(s_pppoe), + NM_SETTING_PPPOE_SERVICE); + g_ptr_array_add(secrets, secret); + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING(s_pppoe), + NM_SETTING_PPPOE_PASSWORD); + g_ptr_array_add(secrets, secret); + return TRUE; +} + +static NMSettingSecretFlags +get_vpn_secret_flags(NMSettingVpn *s_vpn, const char *secret_name) +{ + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + GHashTable * vpn_data; + + g_object_get(s_vpn, NM_SETTING_VPN_DATA, &vpn_data, NULL); + nm_vpn_service_plugin_get_secret_flags(vpn_data, secret_name, &flags); + g_hash_table_unref(vpn_data); + + return flags; +} + +static void +add_vpn_secret_helper(GPtrArray * secrets, + NMSettingVpn *s_vpn, + const char * name, + const char * ui_name) +{ + NMSecretAgentSimpleSecret *secret; + NMSettingSecretFlags flags; + int i; + + flags = get_vpn_secret_flags(s_vpn, name); + if (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED || flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) { + secret = _secret_real_new_vpn_secret(ui_name, + NM_SETTING(s_vpn), + name, + nm_setting_vpn_get_service_type(s_vpn)); + + /* Check for duplicates */ + for (i = 0; i < secrets->len; i++) { + NMSecretAgentSimpleSecret *s = secrets->pdata[i]; + + if (s->secret_type == secret->secret_type && nm_streq0(s->vpn_type, secret->vpn_type) + && nm_streq0(s->entry_id, secret->entry_id)) { + _secret_real_free(secret); + return; + } + } + + g_ptr_array_add(secrets, secret); + } +} + +#define VPN_MSG_TAG "x-vpn-message:" + +static gboolean +add_vpn_secrets(RequestData *request, GPtrArray *secrets, char **msg) +{ + NMSettingVpn * s_vpn = nm_connection_get_setting_vpn(request->connection); + const NmcVpnPasswordName *p; + const char * vpn_msg = NULL; + char ** iter; + + /* If hints are given, then always ask for what the hints require */ + if (request->hints) { + for (iter = request->hints; *iter; iter++) { + if (!vpn_msg && g_str_has_prefix(*iter, VPN_MSG_TAG)) + vpn_msg = &(*iter)[NM_STRLEN(VPN_MSG_TAG)]; + else + add_vpn_secret_helper(secrets, s_vpn, *iter, *iter); + } + } + + NM_SET_OUT(msg, g_strdup(vpn_msg)); + + /* Now add what client thinks might be required, because hints may be empty or incomplete */ + p = nm_vpn_get_secret_names(nm_setting_vpn_get_service_type(s_vpn)); + while (p && p->name) { + add_vpn_secret_helper(secrets, s_vpn, p->name, _(p->ui_name)); + p++; + } + + return TRUE; +} + +static gboolean +add_wireguard_secrets(RequestData *request, GPtrArray *secrets, char **msg, GError **error) +{ + NMSettingWireGuard * s_wg; + NMSecretAgentSimpleSecret *secret; + guint i; + + s_wg = NM_SETTING_WIREGUARD( + nm_connection_get_setting(request->connection, NM_TYPE_SETTING_WIREGUARD)); + if (!s_wg) { + g_set_error(error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "Cannot service a WireGuard secrets request %s for a connection without " + "WireGuard settings", + request->request_id); + return FALSE; + } + + if (!request->hints || !request->hints[0] + || g_strv_contains(NM_CAST_STRV_CC(request->hints), NM_SETTING_WIREGUARD_PRIVATE_KEY)) { + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("WireGuard private-key"), + NM_SETTING(s_wg), + NM_SETTING_WIREGUARD_PRIVATE_KEY); + g_ptr_array_add(secrets, secret); + } + + if (request->hints) { + for (i = 0; request->hints[i]; i++) { + NMWireGuardPeer *peer; + const char * name = request->hints[i]; + gs_free char * public_key = NULL; + + if (nm_streq(name, NM_SETTING_WIREGUARD_PRIVATE_KEY)) + continue; + + if (NM_STR_HAS_PREFIX(name, NM_SETTING_WIREGUARD_PEERS ".")) { + const char *tmp; + + tmp = &name[NM_STRLEN(NM_SETTING_WIREGUARD_PEERS ".")]; + if (NM_STR_HAS_SUFFIX(tmp, "." NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY)) { + public_key = g_strndup( + tmp, + strlen(tmp) - NM_STRLEN("." NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY)); + } + } + + if (!public_key) + continue; + + peer = nm_setting_wireguard_get_peer_by_public_key(s_wg, public_key, NULL); + + g_ptr_array_add(secrets, + _secret_real_new_wireguard_peer_psk( + s_wg, + (peer ? nm_wireguard_peer_get_public_key(peer) : public_key), + (peer ? nm_wireguard_peer_get_preshared_key(peer) : NULL))); + } + } + + *msg = g_strdup_printf(_("Secrets are required to connect WireGuard VPN '%s'"), + nm_connection_get_id(request->connection)); + return TRUE; +} + +typedef struct { + GPid auth_dialog_pid; + GString * auth_dialog_response; + RequestData * request; + GPtrArray * secrets; + GCancellable * cancellable; + gulong cancellable_id; + guint child_watch_id; + GInputStream * input_stream; + GOutputStream *output_stream; + char read_buf[5]; +} AuthDialogData; + +static void +_auth_dialog_data_free(AuthDialogData *data) +{ + nm_clear_g_signal_handler(data->cancellable, &data->cancellable_id); + g_clear_object(&data->cancellable); + nm_clear_g_source(&data->child_watch_id); + g_ptr_array_unref(data->secrets); + g_spawn_close_pid(data->auth_dialog_pid); + g_string_free(data->auth_dialog_response, TRUE); + g_object_unref(data->input_stream); + g_object_unref(data->output_stream); + g_slice_free(AuthDialogData, data); +} + +static void +_auth_dialog_exited(GPid pid, int status, gpointer user_data) +{ + AuthDialogData * data = user_data; + RequestData * request = data->request; + GPtrArray * secrets = data->secrets; + NMSettingVpn * s_vpn = nm_connection_get_setting_vpn(request->connection); + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + gs_strfreev char ** groups = NULL; + gs_free char * title = NULL; + gs_free char * message = NULL; + int i; + gs_free_error GError *error = NULL; + + data->child_watch_id = 0; + + nm_clear_g_cancellable_disconnect(data->cancellable, &data->cancellable_id); + + if (status != 0) { + g_set_error(&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "Auth dialog failed with error code %d\n", + status); + goto out; + } + + keyfile = g_key_file_new(); + if (!g_key_file_load_from_data(keyfile, + data->auth_dialog_response->str, + data->auth_dialog_response->len, + G_KEY_FILE_NONE, + &error)) { + goto out; + } + + groups = g_key_file_get_groups(keyfile, NULL); + if (!nm_streq0(groups[0], "VPN Plugin UI")) { + g_set_error(&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "Expected [VPN Plugin UI] in auth dialog response"); + goto out; + } + + title = g_key_file_get_string(keyfile, "VPN Plugin UI", "Title", &error); + if (!title) + goto out; + + message = g_key_file_get_string(keyfile, "VPN Plugin UI", "Description", &error); + if (!message) + goto out; + + for (i = 1; groups[i]; i++) { + gs_free char *pretty_name = NULL; + + if (!g_key_file_get_boolean(keyfile, groups[i], "IsSecret", NULL)) + continue; + if (!g_key_file_get_boolean(keyfile, groups[i], "ShouldAsk", NULL)) + continue; + + pretty_name = g_key_file_get_string(keyfile, groups[i], "Label", NULL); + g_ptr_array_add(secrets, + _secret_real_new_vpn_secret(pretty_name, + NM_SETTING(s_vpn), + groups[i], + nm_setting_vpn_get_service_type(s_vpn))); + } + +out: + /* Try to fall back to the hardwired VPN support if the auth dialog fails. + * We may eventually get rid of the whole hardwired secrets handling at some point, + * when the auth helpers are goode enough.. */ + if (error && add_vpn_secrets(request, secrets, &message)) { + g_clear_error(&error); + if (!message) { + message = g_strdup_printf(_("A password is required to connect to '%s'."), + nm_connection_get_id(request->connection)); + } + } + + if (error) + _request_data_complete(request, NULL, error, NULL); + else { + g_signal_emit(request->self, + signals[REQUEST_SECRETS], + 0, + request->request_id, + title, + message, + secrets); + } + + _auth_dialog_data_free(data); +} + +static void +_request_cancelled(GObject *object, gpointer user_data) +{ + _auth_dialog_data_free(user_data); +} + +static void +_auth_dialog_read_done(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GInputStream * auth_dialog_out = G_INPUT_STREAM(source_object); + AuthDialogData *data = user_data; + gssize read_size; + gs_free_error GError *error = NULL; + + read_size = g_input_stream_read_finish(auth_dialog_out, res, &error); + switch (read_size) { + case -1: + if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + _request_data_complete(data->request, NULL, error, NULL); + _auth_dialog_data_free(data); + break; + case 0: + /* Done reading. Let's wait for the auth dialog to exit so that we're able to collect the status. + * Remember we can be cancelled in between. */ + data->child_watch_id = g_child_watch_add(data->auth_dialog_pid, _auth_dialog_exited, data); + data->cancellable = g_object_ref(data->request->cancellable); + data->cancellable_id = + g_cancellable_connect(data->cancellable, G_CALLBACK(_request_cancelled), data, NULL); + break; + default: + g_string_append_len(data->auth_dialog_response, data->read_buf, read_size); + g_input_stream_read_async(auth_dialog_out, + data->read_buf, + sizeof(data->read_buf), + G_PRIORITY_DEFAULT, + NULL, + _auth_dialog_read_done, + data); + return; + } + + g_input_stream_close(auth_dialog_out, NULL, NULL); +} + +static void +_auth_dialog_write_done(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GOutputStream *auth_dialog_out = G_OUTPUT_STREAM(source_object); + _nm_unused gs_free char *auth_dialog_request_free = user_data; + + /* We don't care about write errors. If there are any problems, the + * reader shall notice. */ + g_output_stream_write_finish(auth_dialog_out, res, NULL); + g_output_stream_close(auth_dialog_out, NULL, NULL); +} + +static void +_add_to_string(GString *string, const char *key, const char *value) +{ + gs_strfreev char **lines = NULL; + int i; + + lines = g_strsplit(value, "\n", -1); + + g_string_append(string, key); + for (i = 0; lines[i]; i++) { + g_string_append_c(string, '='); + g_string_append(string, lines[i]); + g_string_append_c(string, '\n'); + } +} + +static void +_add_data_item_to_string(const char *key, const char *value, gpointer user_data) +{ + GString *string = user_data; + + _add_to_string(string, "DATA_KEY", key); + _add_to_string(string, "DATA_VAL", value); + g_string_append_c(string, '\n'); +} + +static void +_add_secret_to_string(const char *key, const char *value, gpointer user_data) +{ + GString *string = user_data; + + _add_to_string(string, "SECRET_KEY", key); + _add_to_string(string, "SECRET_VAL", value); + g_string_append_c(string, '\n'); +} + +static gboolean +try_spawn_vpn_auth_helper(RequestData *request, GPtrArray *secrets) +{ + NMSettingVpn * s_vpn = nm_connection_get_setting_vpn(request->connection); + gs_unref_ptrarray GPtrArray *auth_dialog_argv = NULL; + NMVpnPluginInfo * plugin_info; + const char * s; + GPid auth_dialog_pid; + int auth_dialog_in_fd; + int auth_dialog_out_fd; + GOutputStream * auth_dialog_in; + GInputStream * auth_dialog_out; + GError * error = NULL; + GString * auth_dialog_request; + char * auth_dialog_request_str; + gsize auth_dialog_request_len; + AuthDialogData * data; + int i; + + plugin_info = nm_vpn_plugin_info_list_find_by_service(nm_vpn_get_plugin_infos(), + nm_setting_vpn_get_service_type(s_vpn)); + if (!plugin_info) + return FALSE; + + s = nm_vpn_plugin_info_lookup_property(plugin_info, "GNOME", "supports-external-ui-mode"); + if (!_nm_utils_ascii_str_to_bool(s, FALSE)) + return FALSE; + + auth_dialog_argv = g_ptr_array_new(); + + s = nm_vpn_plugin_info_lookup_property(plugin_info, "GNOME", "auth-dialog"); + g_return_val_if_fail(s, FALSE); + g_ptr_array_add(auth_dialog_argv, (gpointer) s); + + g_ptr_array_add(auth_dialog_argv, "-u"); + g_ptr_array_add(auth_dialog_argv, (gpointer) nm_connection_get_uuid(request->connection)); + g_ptr_array_add(auth_dialog_argv, "-n"); + g_ptr_array_add(auth_dialog_argv, (gpointer) nm_connection_get_id(request->connection)); + g_ptr_array_add(auth_dialog_argv, "-s"); + g_ptr_array_add(auth_dialog_argv, (gpointer) nm_setting_vpn_get_service_type(s_vpn)); + g_ptr_array_add(auth_dialog_argv, "--external-ui-mode"); + g_ptr_array_add(auth_dialog_argv, "-i"); + + if (request->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW) + g_ptr_array_add(auth_dialog_argv, "-r"); + + s = nm_vpn_plugin_info_lookup_property(plugin_info, "GNOME", "supports-hints"); + if (_nm_utils_ascii_str_to_bool(s, FALSE)) { + for (i = 0; request->hints[i]; i++) { + g_ptr_array_add(auth_dialog_argv, "-t"); + g_ptr_array_add(auth_dialog_argv, request->hints[i]); + } + } + + g_ptr_array_add(auth_dialog_argv, NULL); + if (!g_spawn_async_with_pipes(NULL, + (char **) auth_dialog_argv->pdata, + NULL, + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &auth_dialog_pid, + &auth_dialog_in_fd, + &auth_dialog_out_fd, + NULL, + &error)) { + g_warning("Failed to spawn the auth dialog%s\n", error->message); + return FALSE; + } + + auth_dialog_in = g_unix_output_stream_new(auth_dialog_in_fd, TRUE); + auth_dialog_out = g_unix_input_stream_new(auth_dialog_out_fd, TRUE); + + auth_dialog_request = g_string_new_len(NULL, 1024); + nm_setting_vpn_foreach_data_item(s_vpn, _add_data_item_to_string, auth_dialog_request); + nm_setting_vpn_foreach_secret(s_vpn, _add_secret_to_string, auth_dialog_request); + g_string_append(auth_dialog_request, "DONE\nQUIT\n"); + auth_dialog_request_len = auth_dialog_request->len; + auth_dialog_request_str = g_string_free(auth_dialog_request, FALSE); + + data = g_slice_new(AuthDialogData); + *data = (AuthDialogData){ + .auth_dialog_response = g_string_new_len(NULL, sizeof(data->read_buf)), + .auth_dialog_pid = auth_dialog_pid, + .request = request, + .secrets = g_ptr_array_ref(secrets), + .input_stream = auth_dialog_out, + .output_stream = auth_dialog_in, + }; + + g_output_stream_write_async(auth_dialog_in, + auth_dialog_request_str, + auth_dialog_request_len, + G_PRIORITY_DEFAULT, + request->cancellable, + _auth_dialog_write_done, + auth_dialog_request_str); + + g_input_stream_read_async(auth_dialog_out, + data->read_buf, + sizeof(data->read_buf), + G_PRIORITY_DEFAULT, + request->cancellable, + _auth_dialog_read_done, + data); + + return TRUE; +} + +static void +request_secrets_from_ui(RequestData *request) +{ + gs_unref_ptrarray GPtrArray *secrets = NULL; + gs_free_error GError * error = NULL; + NMSecretAgentSimplePrivate *priv; + NMSecretAgentSimpleSecret * secret; + const char * title; + gs_free char * msg = NULL; + + priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(request->self); + g_return_if_fail(priv->enabled); + + /* We only handle requests for connection with @path if set. */ + if (priv->path && !g_str_has_prefix(request->request_id, priv->path)) { + g_set_error(&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "Request for %s secrets doesn't match path %s", + request->request_id, + priv->path); + goto out_fail_error; + } + + secrets = g_ptr_array_new_with_free_func((GDestroyNotify) _secret_real_free); + + if (nm_connection_is_type(request->connection, NM_SETTING_WIRELESS_SETTING_NAME)) { + NMSettingWireless *s_wireless; + GBytes * ssid; + char * ssid_utf8; + + s_wireless = nm_connection_get_setting_wireless(request->connection); + ssid = nm_setting_wireless_get_ssid(s_wireless); + ssid_utf8 = nm_utils_ssid_to_utf8(g_bytes_get_data(ssid, NULL), g_bytes_get_size(ssid)); + + title = _("Authentication required by wireless network"); + msg = g_strdup_printf( + _("Passwords or encryption keys are required to access the wireless network '%s'."), + ssid_utf8); + + if (!add_wireless_secrets(request, secrets)) + goto out_fail; + } else if (nm_connection_is_type(request->connection, NM_SETTING_WIRED_SETTING_NAME)) { + title = _("Wired 802.1X authentication"); + msg = g_strdup_printf(_("Secrets are required to access the wired network '%s'"), + nm_connection_get_id(request->connection)); + + if (!add_8021x_secrets(request, secrets)) + goto out_fail; + } else if (nm_connection_is_type(request->connection, NM_SETTING_PPPOE_SETTING_NAME)) { + title = _("DSL authentication"); + msg = g_strdup_printf(_("Secrets are required for the DSL connection '%s'"), + nm_connection_get_id(request->connection)); + + if (!add_pppoe_secrets(request, secrets)) + goto out_fail; + } else if (nm_connection_is_type(request->connection, NM_SETTING_GSM_SETTING_NAME)) { + NMSettingGsm *s_gsm = nm_connection_get_setting_gsm(request->connection); + + if (g_strv_contains(NM_CAST_STRV_CC(request->hints), NM_SETTING_GSM_PIN)) { + title = _("PIN code required"); + msg = g_strdup(_("PIN code is needed for the mobile broadband device")); + + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("PIN"), + NM_SETTING(s_gsm), + NM_SETTING_GSM_PIN); + g_ptr_array_add(secrets, secret); + } else { + title = _("Mobile broadband network password"); + msg = g_strdup_printf(_("A password is required to connect to '%s'."), + nm_connection_get_id(request->connection)); + + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING(s_gsm), + NM_SETTING_GSM_PASSWORD); + g_ptr_array_add(secrets, secret); + } + } else if (nm_connection_is_type(request->connection, NM_SETTING_MACSEC_SETTING_NAME)) { + NMSettingMacsec *s_macsec = nm_connection_get_setting_macsec(request->connection); + + msg = g_strdup_printf(_("Secrets are required to access the MACsec network '%s'"), + nm_connection_get_id(request->connection)); + + if (nm_setting_macsec_get_mode(s_macsec) == NM_SETTING_MACSEC_MODE_PSK) { + title = _("MACsec PSK authentication"); + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("MKA CAK"), + NM_SETTING(s_macsec), + NM_SETTING_MACSEC_MKA_CAK); + g_ptr_array_add(secrets, secret); + } else { + title = _("MACsec EAP authentication"); + if (!add_8021x_secrets(request, secrets)) + goto out_fail; + } + } else if (nm_connection_is_type(request->connection, NM_SETTING_WIREGUARD_SETTING_NAME)) { + title = _("WireGuard VPN secret"); + if (!add_wireguard_secrets(request, secrets, &msg, &error)) + goto out_fail_error; + } else if (nm_connection_is_type(request->connection, NM_SETTING_CDMA_SETTING_NAME)) { + NMSettingCdma *s_cdma = nm_connection_get_setting_cdma(request->connection); + + title = _("Mobile broadband network password"); + msg = g_strdup_printf(_("A password is required to connect to '%s'."), + nm_connection_get_id(request->connection)); + + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + NM_SETTING(s_cdma), + NM_SETTING_CDMA_PASSWORD); + g_ptr_array_add(secrets, secret); + } else if (nm_connection_is_type(request->connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) { + NMSetting *setting = NULL; + + setting = nm_connection_get_setting_by_name(request->connection, + NM_SETTING_BLUETOOTH_SETTING_NAME); + if (setting + && !nm_streq0(nm_setting_bluetooth_get_connection_type(NM_SETTING_BLUETOOTH(setting)), + NM_SETTING_BLUETOOTH_TYPE_NAP)) { + setting = + nm_connection_get_setting_by_name(request->connection, NM_SETTING_GSM_SETTING_NAME); + if (!setting) + setting = nm_connection_get_setting_by_name(request->connection, + NM_SETTING_CDMA_SETTING_NAME); + } + + if (!setting) + goto out_fail; + + title = _("Mobile broadband network password"); + msg = g_strdup_printf(_("A password is required to connect to '%s'."), + nm_connection_get_id(request->connection)); + + secret = _secret_real_new_plain(NM_SECRET_AGENT_SECRET_TYPE_SECRET, + _("Password"), + setting, + "password"); + g_ptr_array_add(secrets, secret); + } else if (nm_connection_is_type(request->connection, NM_SETTING_VPN_SETTING_NAME)) { + title = _("VPN password required"); + + if (try_spawn_vpn_auth_helper(request, secrets)) { + /* This will emit REQUEST_SECRETS when ready */ + return; + } + + if (!add_vpn_secrets(request, secrets, &msg)) + goto out_fail; + if (!msg) { + msg = g_strdup_printf(_("A password is required to connect to '%s'."), + nm_connection_get_id(request->connection)); + } + } else + goto out_fail; + + if (secrets->len == 0) + goto out_fail; + + g_signal_emit(request->self, + signals[REQUEST_SECRETS], + 0, + request->request_id, + title, + msg, + secrets); + return; + +out_fail: + g_set_error(&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "Cannot service a secrets request %s for a %s connection", + request->request_id, + nm_connection_get_connection_type(request->connection)); +out_fail_error: + _request_data_complete(request, NULL, error, NULL); +} + +static void +get_secrets(NMSecretAgentOld * agent, + NMConnection * connection, + const char * connection_path, + const char * setting_name, + const char ** hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer callback_data) +{ + NMSecretAgentSimple * self = NM_SECRET_AGENT_SIMPLE(agent); + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(self); + RequestData * request; + gs_free_error GError *error = NULL; + gs_free char * request_id = NULL; + const char * request_id_setting_name; + + request_id = g_strdup_printf("%s/%s", connection_path, setting_name); + + if (g_hash_table_contains(priv->requests, &request_id)) { + /* We already have a request pending for this (connection, setting) */ + error = g_error_new(NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "Request for %s secrets already pending", + request_id); + callback(agent, connection, NULL, error, callback_data); + return; + } + + if (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION)) { + /* We don't do stored passwords */ + error = g_error_new(NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_NO_SECRETS, + "Stored passwords not supported"); + callback(agent, connection, NULL, error, callback_data); + return; + } + + nm_assert(g_str_has_suffix(request_id, setting_name)); + request_id_setting_name = &request_id[strlen(request_id) - strlen(setting_name)]; + nm_assert(nm_streq(request_id_setting_name, setting_name)); + + request = g_slice_new(RequestData); + *request = (RequestData){ + .self = self, + .connection = g_object_ref(connection), + .setting_name = request_id_setting_name, + .hints = g_strdupv((char **) hints), + .callback = callback, + .callback_data = callback_data, + .request_id = g_steal_pointer(&request_id), + .flags = flags, + .cancellable = g_cancellable_new(), + }; + g_hash_table_add(priv->requests, request); + + if (priv->enabled) + request_secrets_from_ui(request); +} + +/** + * nm_secret_agent_simple_response: + * @self: the #NMSecretAgentSimple + * @request_id: the request ID being responded to + * @secrets: (allow-none): the array of secrets, or %NULL + * + * Response to a #NMSecretAgentSimple::get-secrets signal. + * + * If the user provided secrets, the caller should set the + * corresponding value fields in the + * #NMSecretAgentSimpleSecrets (freeing any initial values they had), and + * pass the array to nm_secret_agent_simple_response(). If the user + * cancelled the request, @secrets should be NULL. + */ +void +nm_secret_agent_simple_response(NMSecretAgentSimple *self, + const char * request_id, + GPtrArray * secrets) +{ + NMSecretAgentSimplePrivate *priv; + RequestData * request; + gs_unref_variant GVariant *secrets_dict = NULL; + gs_free_error GError *error = NULL; + int i; + + g_return_if_fail(NM_IS_SECRET_AGENT_SIMPLE(self)); + + priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(self); + request = g_hash_table_lookup(priv->requests, &request_id); + g_return_if_fail(request != NULL); + + if (secrets) { + GVariantBuilder conn_builder, *setting_builder; + GVariantBuilder vpn_secrets_builder; + GVariantBuilder wg_secrets_builder; + GVariantBuilder wg_peer_builder; + GHashTable * settings; + GHashTableIter iter; + const char * name; + gboolean has_vpn = FALSE; + gboolean has_wg = FALSE; + + settings = g_hash_table_new_full(nm_str_hash, + g_str_equal, + NULL, + (GDestroyNotify) g_variant_builder_unref); + for (i = 0; i < secrets->len; i++) { + SecretReal *secret = secrets->pdata[i]; + + setting_builder = g_hash_table_lookup(settings, nm_setting_get_name(secret->setting)); + if (!setting_builder) { + setting_builder = g_variant_builder_new(NM_VARIANT_TYPE_SETTING); + g_hash_table_insert(settings, + (char *) nm_setting_get_name(secret->setting), + setting_builder); + } + + switch (secret->base.secret_type) { + case NM_SECRET_AGENT_SECRET_TYPE_PROPERTY: + case NM_SECRET_AGENT_SECRET_TYPE_SECRET: + g_variant_builder_add(setting_builder, + "{sv}", + secret->property, + g_variant_new_string(secret->base.value)); + break; + case NM_SECRET_AGENT_SECRET_TYPE_VPN_SECRET: + if (!has_vpn) { + g_variant_builder_init(&vpn_secrets_builder, G_VARIANT_TYPE("a{ss}")); + has_vpn = TRUE; + } + g_variant_builder_add(&vpn_secrets_builder, + "{ss}", + secret->property, + secret->base.value); + break; + case NM_SECRET_AGENT_SECRET_TYPE_WIREGUARD_PEER_PSK: + if (!has_wg) { + g_variant_builder_init(&wg_secrets_builder, G_VARIANT_TYPE("aa{sv}")); + has_wg = TRUE; + } + g_variant_builder_init(&wg_peer_builder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(&wg_peer_builder, + "{sv}", + NM_WIREGUARD_PEER_ATTR_PUBLIC_KEY, + g_variant_new_string(secret->property)); + g_variant_builder_add(&wg_peer_builder, + "{sv}", + NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY, + g_variant_new_string(secret->base.value)); + g_variant_builder_add(&wg_secrets_builder, "a{sv}", &wg_peer_builder); + break; + } + } + + if (has_vpn) { + g_variant_builder_add(setting_builder, + "{sv}", + "secrets", + g_variant_builder_end(&vpn_secrets_builder)); + } + + if (has_wg) { + g_variant_builder_add(setting_builder, + "{sv}", + NM_SETTING_WIREGUARD_PEERS, + g_variant_builder_end(&wg_secrets_builder)); + } + + g_variant_builder_init(&conn_builder, NM_VARIANT_TYPE_CONNECTION); + g_hash_table_iter_init(&iter, settings); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &setting_builder)) + g_variant_builder_add(&conn_builder, "{sa{sv}}", name, setting_builder); + secrets_dict = g_variant_ref_sink(g_variant_builder_end(&conn_builder)); + g_hash_table_destroy(settings); + } else { + error = g_error_new(NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_USER_CANCELED, + "User cancelled"); + } + + _request_data_complete(request, secrets_dict, error, NULL); +} + +static void +cancel_get_secrets(NMSecretAgentOld *agent, const char *connection_path, const char *setting_name) +{ + NMSecretAgentSimple * self = NM_SECRET_AGENT_SIMPLE(agent); + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(self); + gs_free_error GError *error = NULL; + gs_free char * request_id = NULL; + RequestData * request; + + request_id = g_strdup_printf("%s/%s", connection_path, setting_name); + request = g_hash_table_lookup(priv->requests, &request_id); + if (!request) { + /* this is really a bug of the caller (or us?). We cannot invoke a callback, + * hence the caller cannot cleanup the request. */ + g_return_if_reached(); + } + + g_set_error(&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_AGENT_CANCELED, + "The secret agent is going away"); + _request_data_complete(request, NULL, error, NULL); +} + +static void +save_secrets(NMSecretAgentOld * agent, + NMConnection * connection, + const char * connection_path, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer callback_data) +{ + /* We don't support secret storage */ + callback(agent, connection, NULL, callback_data); +} + +static void +delete_secrets(NMSecretAgentOld * agent, + NMConnection * connection, + const char * connection_path, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer callback_data) +{ + /* We don't support secret storage, so there's nothing to delete. */ + callback(agent, connection, NULL, callback_data); +} + +/** + * nm_secret_agent_simple_enable: + * @self: the #NMSecretAgentSimple + * @path: (allow-none): the path of the connection (if any) to handle secrets + * for. If %NULL, secrets for any connection will be handled. + * + * Enables servicing the requests including the already queued ones. If @path + * is given, the agent will only handle requests for connections that match + * @path. + */ +void +nm_secret_agent_simple_enable(NMSecretAgentSimple *self, const char *path) +{ + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(self); + gs_free RequestData **requests = NULL; + gsize i; + gs_free char * path_full = NULL; + + /* The path is only used to match a request_id with the current + * connection. Since the request_id is "${CONNECTION_PATH}/${SETTING}", + * add a trailing '/' to the path to match the full connection path. + */ + path_full = path ? g_strdup_printf("%s/", path) : NULL; + + if (!nm_streq0(path_full, priv->path)) { + g_free(priv->path); + priv->path = g_steal_pointer(&path_full); + } + + if (priv->enabled) + return; + priv->enabled = TRUE; + + /* Service pending secret requests. */ + requests = (RequestData **) g_hash_table_get_keys_as_array(priv->requests, NULL); + for (i = 0; requests[i]; i++) + request_secrets_from_ui(requests[i]); +} + +/*****************************************************************************/ + +static void +nm_secret_agent_simple_init(NMSecretAgentSimple *agent) +{ + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(agent); + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(RequestData, request_id) == 0); + priv->requests = g_hash_table_new_full(nm_pstr_hash, nm_pstr_equal, NULL, _request_data_free); +} + +/** + * nm_secret_agent_simple_new: + * @name: the identifier of secret agent + * + * Creates a new #NMSecretAgentSimple. It does not serve any requests until + * nm_secret_agent_simple_enable() is called. + * + * Returns: a new #NMSecretAgentSimple if the agent creation is successful + * or %NULL in case of a failure. + */ +NMSecretAgentSimple * +nm_secret_agent_simple_new(const char *name) +{ + return g_initable_new(NM_TYPE_SECRET_AGENT_SIMPLE, + NULL, + NULL, + NM_SECRET_AGENT_OLD_IDENTIFIER, + name, + NM_SECRET_AGENT_OLD_CAPABILITIES, + NM_SECRET_AGENT_CAPABILITY_VPN_HINTS, + NULL); +} + +static void +dispose(GObject *object) +{ + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(object); + gs_free_error GError *error = NULL; + GHashTableIter iter; + RequestData * request; + + g_hash_table_iter_init(&iter, priv->requests); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &request)) { + if (!error) + nm_utils_error_set_cancelled(&error, TRUE, "NMSecretAgentSimple"); + _request_data_complete(request, NULL, error, &iter); + } + + G_OBJECT_CLASS(nm_secret_agent_simple_parent_class)->dispose(object); +} + +static void +finalize(GObject *object) +{ + NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(object); + + g_hash_table_destroy(priv->requests); + + g_free(priv->path); + + G_OBJECT_CLASS(nm_secret_agent_simple_parent_class)->finalize(object); +} + +void +nm_secret_agent_simple_class_init(NMSecretAgentSimpleClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSecretAgentOldClass *agent_class = NM_SECRET_AGENT_OLD_CLASS(klass); + + object_class->dispose = dispose; + object_class->finalize = finalize; + + agent_class->get_secrets = get_secrets; + agent_class->cancel_get_secrets = cancel_get_secrets; + agent_class->save_secrets = save_secrets; + agent_class->delete_secrets = delete_secrets; + + /** + * NMSecretAgentSimple::request-secrets: + * @agent: the #NMSecretAgentSimple + * @request_id: request ID, to eventually pass to + * nm_secret_agent_simple_response(). + * @title: a title for the password dialog + * @prompt: a prompt message for the password dialog + * @secrets: (element-type #NMSecretAgentSimpleSecret): array of secrets + * being requested. + * + * Emitted when the agent requires secrets from the user. + * + * The application should ask user for the secrets. For example, + * nmtui should create a password dialog (#NmtPasswordDialog) + * with the given title and prompt, and an entry for each + * element of @secrets. If any of the secrets already have a + * value filled in, the corresponding entry + * should be initialized to that value. + * + * When the dialog is complete, the app must call + * nm_secret_agent_simple_response() with the results. + */ + signals[REQUEST_SECRETS] = g_signal_new(NM_SECRET_AGENT_SIMPLE_REQUEST_SECRETS, + G_TYPE_FROM_CLASS(klass), + 0, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 4, + G_TYPE_STRING, /* request_id */ + G_TYPE_STRING, /* title */ + G_TYPE_STRING, /* prompt */ + G_TYPE_PTR_ARRAY); +} diff --git a/src/libnmc-base/nm-secret-agent-simple.h b/src/libnmc-base/nm-secret-agent-simple.h new file mode 100644 index 0000000..878f9c7 --- /dev/null +++ b/src/libnmc-base/nm-secret-agent-simple.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2013 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_SECRET_AGENT_SIMPLE_H__ +#define __NM_SECRET_AGENT_SIMPLE_H__ + +#include "nm-secret-agent-old.h" + +typedef enum { + NM_SECRET_AGENT_SECRET_TYPE_PROPERTY, + NM_SECRET_AGENT_SECRET_TYPE_SECRET, + NM_SECRET_AGENT_SECRET_TYPE_VPN_SECRET, + NM_SECRET_AGENT_SECRET_TYPE_WIREGUARD_PEER_PSK, +} NMSecretAgentSecretType; + +typedef struct { + NMSecretAgentSecretType secret_type; + const char * pretty_name; + const char * entry_id; + char * value; + const char * vpn_type; + bool is_secret : 1; + bool no_prompt_entry_id : 1; +} NMSecretAgentSimpleSecret; + +#define NM_SECRET_AGENT_ENTRY_ID_PREFX_VPN_SECRETS "vpn.secrets." + +#define NM_SECRET_AGENT_VPN_TYPE_OPENCONNECT NM_DBUS_INTERFACE ".openconnect" + +/*****************************************************************************/ + +#define NM_TYPE_SECRET_AGENT_SIMPLE (nm_secret_agent_simple_get_type()) +#define NM_SECRET_AGENT_SIMPLE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimple)) +#define NM_SECRET_AGENT_SIMPLE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimpleClass)) +#define NM_IS_SECRET_AGENT_SIMPLE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SECRET_AGENT_SIMPLE)) +#define NM_IS_SECRET_AGENT_SIMPLE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SECRET_AGENT_SIMPLE)) +#define NM_SECRET_AGENT_SIMPLE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimpleClass)) + +#define NM_SECRET_AGENT_SIMPLE_REQUEST_SECRETS "request-secrets" + +typedef struct _NMSecretAgentSimple NMSecretAgentSimple; +typedef struct _NMSecretAgentSimpleClass NMSecretAgentSimpleClass; + +GType nm_secret_agent_simple_get_type(void); + +NMSecretAgentSimple *nm_secret_agent_simple_new(const char *name); + +void nm_secret_agent_simple_response(NMSecretAgentSimple *self, + const char * request_id, + GPtrArray * secrets); + +void nm_secret_agent_simple_enable(NMSecretAgentSimple *self, const char *path); + +#endif /* __NM_SECRET_AGENT_SIMPLE_H__ */ diff --git a/src/libnmc-base/nm-vpn-helpers.c b/src/libnmc-base/nm-vpn-helpers.c new file mode 100644 index 0000000..72691e3 --- /dev/null +++ b/src/libnmc-base/nm-vpn-helpers.c @@ -0,0 +1,821 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2013 - 2015 Red Hat, Inc. + */ + +/** + * SECTION:nm-vpn-helpers + * @short_description: VPN-related utilities + */ + +#include "libnm-client-aux-extern/nm-default-client.h" + +#include "nm-vpn-helpers.h" + +#include +#include + +#include "nm-client-utils.h" +#include "nm-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-secret-utils.h" + +/*****************************************************************************/ + +NMVpnEditorPlugin * +nm_vpn_get_editor_plugin(const char *service_type, GError **error) +{ + NMVpnEditorPlugin *plugin = NULL; + NMVpnPluginInfo * plugin_info; + gs_free_error GError *local = NULL; + + g_return_val_if_fail(service_type, NULL); + g_return_val_if_fail(error == NULL || *error == NULL, NULL); + + plugin_info = nm_vpn_plugin_info_list_find_by_service(nm_vpn_get_plugin_infos(), service_type); + + if (!plugin_info) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("unknown VPN plugin \"%s\""), + service_type); + return NULL; + } + plugin = nm_vpn_plugin_info_get_editor_plugin(plugin_info); + if (!plugin) + plugin = nm_vpn_plugin_info_load_editor_plugin(plugin_info, &local); + + if (!plugin) { + if (!nm_vpn_plugin_info_get_plugin(plugin_info) + && nm_vpn_plugin_info_lookup_property(plugin_info, + NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, + "properties")) { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("cannot load legacy-only VPN plugin \"%s\" for \"%s\""), + nm_vpn_plugin_info_get_name(plugin_info), + nm_vpn_plugin_info_get_filename(plugin_info)); + } else if (g_error_matches(local, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { + g_set_error( + error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("cannot load VPN plugin \"%s\" due to missing \"%s\". Missing client plugin?"), + nm_vpn_plugin_info_get_name(plugin_info), + nm_vpn_plugin_info_get_plugin(plugin_info)); + } else { + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("failed to load VPN plugin \"%s\": %s"), + nm_vpn_plugin_info_get_name(plugin_info), + local->message); + } + return NULL; + } + + return plugin; +} + +GSList * +nm_vpn_get_plugin_infos(void) +{ + static bool plugins_loaded; + static GSList *plugins = NULL; + + if (G_LIKELY(plugins_loaded)) + return plugins; + plugins_loaded = TRUE; + plugins = nm_vpn_plugin_info_list_load(); + return plugins; +} + +gboolean +nm_vpn_supports_ipv6(NMConnection *connection) +{ + NMSettingVpn * s_vpn; + const char * service_type; + NMVpnEditorPlugin *plugin; + guint32 capabilities; + + s_vpn = nm_connection_get_setting_vpn(connection); + g_return_val_if_fail(s_vpn != NULL, FALSE); + + service_type = nm_setting_vpn_get_service_type(s_vpn); + if (!service_type) + return FALSE; + + plugin = nm_vpn_get_editor_plugin(service_type, NULL); + if (!plugin) + return FALSE; + + capabilities = nm_vpn_editor_plugin_get_capabilities(plugin); + return NM_FLAGS_HAS(capabilities, NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6); +} + +const NmcVpnPasswordName * +nm_vpn_get_secret_names(const char *service_type) +{ + const char *type; + + if (!service_type) + return NULL; + + if (!NM_STR_HAS_PREFIX(service_type, NM_DBUS_INTERFACE) + || service_type[NM_STRLEN(NM_DBUS_INTERFACE)] != '.') { + /* all our well-known, hard-coded vpn-types start with NM_DBUS_INTERFACE. */ + return NULL; + } + + type = service_type + (NM_STRLEN(NM_DBUS_INTERFACE) + 1); + +#define _VPN_PASSWORD_LIST(...) \ + ({ \ + static const NmcVpnPasswordName _arr[] = { \ + __VA_ARGS__{0}, \ + }; \ + _arr; \ + }) + + if (NM_IN_STRSET(type, "pptp", "iodine", "ssh", "l2tp", "fortisslvpn")) { + return _VPN_PASSWORD_LIST({"password", N_("Password")}, ); + } + + if (NM_IN_STRSET(type, "openvpn")) { + return _VPN_PASSWORD_LIST({"password", N_("Password")}, + {"cert-pass", N_("Certificate password")}, + {"http-proxy-password", N_("HTTP proxy password")}, ); + } + + if (NM_IN_STRSET(type, "vpnc")) { + return _VPN_PASSWORD_LIST({"Xauth password", N_("Password")}, + {"IPSec secret", N_("Group password")}, ); + }; + + if (NM_IN_STRSET(type, "openswan", "libreswan", "strongswan")) { + return _VPN_PASSWORD_LIST({"xauthpassword", N_("Password")}, + {"pskvalue", N_("Group password")}, ); + }; + + if (NM_IN_STRSET(type, "openconnect")) { + return _VPN_PASSWORD_LIST({"gateway", N_("Gateway")}, + {"cookie", N_("Cookie")}, + {"gwcert", N_("Gateway certificate hash")}, ); + }; + + return NULL; +} + +static gboolean +_extract_variable_value(char *line, const char *tag, char **value) +{ + char *p1, *p2; + + if (!g_str_has_prefix(line, tag)) + return FALSE; + + p1 = line + strlen(tag); + p2 = line + strlen(line) - 1; + if ((*p1 == '\'' || *p1 == '"') && (*p1 == *p2)) { + p1++; + *p2 = '\0'; + } + NM_SET_OUT(value, g_strdup(p1)); + return TRUE; +} + +gboolean +nm_vpn_openconnect_authenticate_helper(const char *host, + char ** cookie, + char ** gateway, + char ** gwcert, + int * status, + GError ** error) +{ + gs_free char * output = NULL; + gs_free const char **output_v = NULL; + const char *const * iter; + const char * path; + const char *const DEFAULT_PATHS[] = { + "/sbin/", + "/usr/sbin/", + "/usr/local/sbin/", + "/bin/", + "/usr/bin/", + "/usr/local/bin/", + NULL, + }; + + path = nm_utils_file_search_in_paths("openconnect", + "/usr/sbin/openconnect", + DEFAULT_PATHS, + G_FILE_TEST_IS_EXECUTABLE, + NULL, + NULL, + error); + if (!path) + return FALSE; + + if (!g_spawn_sync(NULL, + (char **) NM_MAKE_STRV(path, "--authenticate", host), + NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_CHILD_INHERITS_STDIN, + NULL, + NULL, + &output, + NULL, + status, + error)) + return FALSE; + + /* Parse output and set cookie, gateway and gwcert + * output example: + * COOKIE='loremipsum' + * HOST='1.2.3.4' + * FINGERPRINT='sha1:32bac90cf09a722e10ecc1942c67fe2ac8c21e2e' + */ + output_v = nm_utils_strsplit_set_with_empty(output, "\r\n"); + for (iter = output_v; iter && *iter; iter++) { + char *s_mutable = (char *) *iter; + + _extract_variable_value(s_mutable, "COOKIE=", cookie); + _extract_variable_value(s_mutable, "HOST=", gateway); + _extract_variable_value(s_mutable, "FINGERPRINT=", gwcert); + } + + return TRUE; +} + +static gboolean +_wg_complete_peer(GPtrArray ** p_peers, + NMWireGuardPeer *peer_take, + gsize peer_start_line_nr, + const char * filename, + GError ** error) +{ + nm_auto_unref_wgpeer NMWireGuardPeer *peer = peer_take; + gs_free_error GError *local = NULL; + + if (!peer) + return TRUE; + + if (!nm_wireguard_peer_is_valid(peer, TRUE, TRUE, &local)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + _("Invalid peer starting at %s:%zu: %s"), + filename, + peer_start_line_nr, + local->message); + return FALSE; + } + + if (!*p_peers) + *p_peers = g_ptr_array_new_with_free_func((GDestroyNotify) nm_wireguard_peer_unref); + g_ptr_array_add(*p_peers, g_steal_pointer(&peer)); + return TRUE; +} + +static gboolean +_line_match(char *line, const char *key, gsize key_len, const char **out_key, char **out_value) +{ + nm_assert(line); + nm_assert(key); + nm_assert(strlen(key) == key_len); + nm_assert(!strchr(key, '=')); + nm_assert(out_key && !*out_key); + nm_assert(out_value && !*out_value); + + /* Note that `wg-quick` (linux.bash) does case-insensitive comparison (shopt -s nocasematch). + * `wg setconf` does case-insensitive comparison too (with strncasecmp, which is locale dependent). + * + * We do a case-insensitive comparison of the key, however in a locale-independent manner. */ + + if (g_ascii_strncasecmp(line, key, key_len) != 0) + return FALSE; + + if (line[key_len] != '=') + return FALSE; + + *out_key = key; + *out_value = &line[key_len + 1]; + return TRUE; +} + +#define line_match(line, key, out_key, out_value) \ + _line_match((line), "" key "", NM_STRLEN(key), (out_key), (out_value)) + +static gboolean +value_split_word(char **line_remainder, char **out_word) +{ + char *str; + + if ((*line_remainder)[0] == '\0') + return FALSE; + + *out_word = *line_remainder; + + str = strchrnul(*line_remainder, ','); + if (str[0] == ',') { + str[0] = '\0'; + *line_remainder = &str[1]; + } else + *line_remainder = str; + return TRUE; +} + +NMConnection * +nm_vpn_wireguard_import(const char *filename, GError **error) +{ + nm_auto_clear_secret_ptr NMSecretPtr file_content = NM_SECRET_PTR_INIT(); + char ifname[IFNAMSIZ]; + gs_free char * uuid = NULL; + gboolean ifname_valid = FALSE; + const char * cstr; + char * line_remainder; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingWireGuard * s_wg; + gs_free_error GError *local = NULL; + enum { + LINE_CONTEXT_INIT, + LINE_CONTEXT_INTERFACE, + LINE_CONTEXT_PEER, + } line_context; + gsize line_nr; + gsize current_peer_start_line_nr = 0; + nm_auto_unref_wgpeer NMWireGuardPeer *current_peer = NULL; + gs_unref_ptrarray GPtrArray *data_dns_search = NULL; + gs_unref_ptrarray GPtrArray *data_dns_v4 = NULL; + gs_unref_ptrarray GPtrArray *data_dns_v6 = NULL; + gs_unref_ptrarray GPtrArray *data_addr_v4 = NULL; + gs_unref_ptrarray GPtrArray *data_addr_v6 = NULL; + gs_unref_ptrarray GPtrArray *data_peers = NULL; + const char * data_private_key = NULL; + gint64 data_table; + guint data_listen_port = 0; + guint data_fwmark = 0; + guint data_mtu = 0; + int is_v4; + guint i; + + g_return_val_if_fail(filename, NULL); + g_return_val_if_fail(!error || !*error, NULL); + + /* contrary to "wg-quick", we never interpret the filename as "/etc/wireguard/$INTERFACE.conf". + * If the filename has no '/', it is interpreted as relative to the current working directory. + * However, we do require a suitable filename suffix and that the name corresponds to the interface + * name. */ + cstr = strrchr(filename, '/'); + cstr = cstr ? &cstr[1] : filename; + if (NM_STR_HAS_SUFFIX(cstr, ".conf")) { + gsize len = strlen(cstr) - NM_STRLEN(".conf"); + + if (len > 0 && len < sizeof(ifname)) { + memcpy(ifname, cstr, len); + ifname[len] = '\0'; + + if (nm_utils_ifname_valid(ifname, NMU_IFACE_KERNEL, NULL)) + ifname_valid = TRUE; + } + } + if (!ifname_valid) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_UNKNOWN, + _("The name of the WireGuard config must be a valid interface " + "name followed by \".conf\"")); + return FALSE; + } + + if (!nm_utils_file_get_contents(-1, + filename, + 10 * 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET, + &file_content.str, + &file_content.len, + NULL, + error)) + return NULL; + + /* We interpret the file like `wg-quick up` and `wg setconf` do. + * + * Of course the WireGuard scripts do something fundamentlly different. They + * perform actions to configure the WireGuard link in kernel, add routes and + * addresses, and call resolvconf. It all happens at the time when the script + * run. + * + * This code here instead generates a NetworkManager connection profile so that + * NetworkManager will apply a similar configuration when later activating the profile. */ + +#define _TABLE_AUTO ((gint64) -1) +#define _TABLE_OFF ((gint64) -2) + + data_table = _TABLE_AUTO; + + line_remainder = file_content.str; + line_context = LINE_CONTEXT_INIT; + line_nr = 0; + while (line_remainder[0] != '\0') { + const char *matched_key = NULL; + char * value = NULL; + char * line; + char ch; + gint64 i64; + + line_nr++; + + line = line_remainder; + line_remainder = strchrnul(line, '\n'); + if (line_remainder[0] != '\0') + (line_remainder++)[0] = '\0'; + + /* Drop all spaces and truncate at first '#'. + * See wg's config_read_line(). + * + * Note that wg-quick doesn't do that. + * + * Neither `wg setconf` nor `wg-quick` does a strict parsing. + * We don't either. Just try to interpret the file (mostly) the same as + * they would. + */ + { + gsize l, n; + + n = 0; + for (l = 0; (ch = line[l]); l++) { + if (g_ascii_isspace(ch)) { + /* wg-setconf strips all whitespace before parsing the content. That means, + * *[I nterface]" will be accepted. We do that too. */ + continue; + } + if (ch == '#') + break; + line[n++] = line[l]; + } + if (n == 0) + continue; + line[n] = '\0'; + } + + if (g_ascii_strcasecmp(line, "[Interface]") == 0) { + if (!_wg_complete_peer(&data_peers, + g_steal_pointer(¤t_peer), + current_peer_start_line_nr, + filename, + error)) + return FALSE; + line_context = LINE_CONTEXT_INTERFACE; + continue; + } + + if (g_ascii_strcasecmp(line, "[Peer]") == 0) { + if (!_wg_complete_peer(&data_peers, + g_steal_pointer(¤t_peer), + current_peer_start_line_nr, + filename, + error)) + return FALSE; + current_peer_start_line_nr = line_nr; + current_peer = nm_wireguard_peer_new(); + line_context = LINE_CONTEXT_PEER; + continue; + } + + if (line_context == LINE_CONTEXT_INTERFACE) { + if (line_match(line, "Address", &matched_key, &value)) { + char *value_word; + + while (value_split_word(&value, &value_word)) { + GPtrArray **p_data_addr; + NMIPAddr addr_bin; + int addr_family; + int prefix_len; + + if (!nm_utils_parse_inaddr_prefix_bin(AF_UNSPEC, + value_word, + &addr_family, + &addr_bin, + &prefix_len)) + goto fail_invalid_value; + + p_data_addr = (addr_family == AF_INET) ? &data_addr_v4 : &data_addr_v6; + + if (!*p_data_addr) + *p_data_addr = + g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + + g_ptr_array_add( + *p_data_addr, + nm_ip_address_new_binary( + addr_family, + &addr_bin, + prefix_len == -1 ? ((addr_family == AF_INET) ? 32 : 128) : prefix_len, + NULL)); + } + continue; + } + + if (line_match(line, "MTU", &matched_key, &value)) { + i64 = _nm_utils_ascii_str_to_int64(value, 0, 0, G_MAXUINT32, -1); + if (i64 == -1) + goto fail_invalid_value; + + /* wg-quick accepts the "MTU" value, but it also fetches routes to + * autodetect it. NetworkManager won't do that, we can only configure + * an explicit MTU or no autodetection will be performed. */ + data_mtu = i64; + continue; + } + + if (line_match(line, "DNS", &matched_key, &value)) { + char *value_word; + + while (value_split_word(&value, &value_word)) { + GPtrArray **p_data_dns; + NMIPAddr addr_bin; + int addr_family; + + if (nm_utils_parse_inaddr_bin(AF_UNSPEC, value_word, &addr_family, &addr_bin)) { + p_data_dns = (addr_family == AF_INET) ? &data_dns_v4 : &data_dns_v6; + if (!*p_data_dns) + *p_data_dns = g_ptr_array_new_with_free_func(g_free); + + g_ptr_array_add(*p_data_dns, + nm_utils_inet_ntop_dup(addr_family, &addr_bin)); + continue; + } + + if (!data_dns_search) + data_dns_search = g_ptr_array_new_with_free_func(g_free); + g_ptr_array_add(data_dns_search, g_strdup(value_word)); + } + continue; + } + + if (line_match(line, "Table", &matched_key, &value)) { + if (nm_streq(value, "auto")) + data_table = _TABLE_AUTO; + else if (nm_streq(value, "off")) + data_table = _TABLE_OFF; + else { + /* we don't support table names from /etc/iproute2/rt_tables + * But we accept hex like `ip route add` would. */ + i64 = _nm_utils_ascii_str_to_int64(value, 0, 0, G_MAXINT32, -1); + if (i64 == -1) + goto fail_invalid_value; + data_table = i64; + } + continue; + } + + if (line_match(line, "PreUp", &matched_key, &value) + || line_match(line, "PreDown", &matched_key, &value) + || line_match(line, "PostUp", &matched_key, &value) + || line_match(line, "PostDown", &matched_key, &value)) { + /* we don't run any scripts. Silently ignore these parameters. */ + continue; + } + + if (line_match(line, "SaveConfig", &matched_key, &value)) { + /* we ignore the setting, but enforce that it's either true or false (like + * wg-quick. */ + if (!NM_IN_STRSET(value, "true", "false")) + goto fail_invalid_value; + continue; + } + + if (line_match(line, "ListenPort", &matched_key, &value)) { + /* we don't use getaddrinfo(), unlike `wg setconf`. Just interpret + * the port as plain decimal number. */ + i64 = _nm_utils_ascii_str_to_int64(value, 10, 0, 0xFFFF, -1); + if (i64 == -1) + goto fail_invalid_value; + data_listen_port = i64; + continue; + } + + if (line_match(line, "FwMark", &matched_key, &value)) { + if (nm_streq(value, "off")) + data_fwmark = 0; + else { + i64 = _nm_utils_ascii_str_to_int64(value, 0, 0, G_MAXINT32, -1); + if (i64 == -1) + goto fail_invalid_value; + data_fwmark = i64; + } + continue; + } + + if (line_match(line, "PrivateKey", &matched_key, &value)) { + if (!nm_utils_base64secret_decode(value, NM_WIREGUARD_PUBLIC_KEY_LEN, NULL)) + goto fail_invalid_secret; + data_private_key = value; + continue; + } + + goto fail_invalid_line; + } + + if (line_context == LINE_CONTEXT_PEER) { + if (line_match(line, "Endpoint", &matched_key, &value)) { + if (!nm_wireguard_peer_set_endpoint(current_peer, value, FALSE)) + goto fail_invalid_value; + continue; + } + + if (line_match(line, "PublicKey", &matched_key, &value)) { + if (!nm_wireguard_peer_set_public_key(current_peer, value, FALSE)) + goto fail_invalid_value; + continue; + } + + if (line_match(line, "AllowedIPs", &matched_key, &value)) { + char *value_word; + + while (value_split_word(&value, &value_word)) { + if (!nm_wireguard_peer_append_allowed_ip(current_peer, value_word, FALSE)) + goto fail_invalid_value; + } + continue; + } + + if (line_match(line, "PersistentKeepalive", &matched_key, &value)) { + if (nm_streq(value, "off")) + i64 = 0; + else { + i64 = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT16, -1); + if (i64 == -1) + goto fail_invalid_value; + } + nm_wireguard_peer_set_persistent_keepalive(current_peer, i64); + continue; + } + + if (line_match(line, "PresharedKey", &matched_key, &value)) { + if (!nm_wireguard_peer_set_preshared_key(current_peer, value, FALSE)) + goto fail_invalid_secret; + nm_wireguard_peer_set_preshared_key_flags(current_peer, + NM_SETTING_SECRET_FLAG_NONE); + continue; + } + + goto fail_invalid_line; + } + +fail_invalid_line: + nm_utils_error_set(error, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("unrecognized line at %s:%zu"), + filename, + line_nr); + return FALSE; +fail_invalid_value: + nm_utils_error_set(error, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid value for '%s' at %s:%zu"), + matched_key, + filename, + line_nr); + return FALSE; +fail_invalid_secret: + nm_utils_error_set(error, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid secret '%s' at %s:%zu"), + matched_key, + filename, + line_nr); + return FALSE; + } + + if (!_wg_complete_peer(&data_peers, + g_steal_pointer(¤t_peer), + current_peer_start_line_nr, + filename, + error)) + return FALSE; + + connection = nm_simple_connection_new(); + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + s_wg = NM_SETTING_WIREGUARD(nm_setting_wireguard_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wg)); + + uuid = nm_utils_uuid_generate(); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + ifname, + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIREGUARD_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME, + ifname, + NULL); + + g_object_set(s_wg, + NM_SETTING_WIREGUARD_PRIVATE_KEY, + data_private_key, + NM_SETTING_WIREGUARD_LISTEN_PORT, + data_listen_port, + NM_SETTING_WIREGUARD_FWMARK, + data_fwmark, + NM_SETTING_WIREGUARD_MTU, + data_mtu, + NULL); + + if (data_peers) { + for (i = 0; i < data_peers->len; i++) + nm_setting_wireguard_append_peer(s_wg, data_peers->pdata[i]); + } + + for (is_v4 = 0; is_v4 < 2; is_v4++) { + const char *method_disabled = + is_v4 ? NM_SETTING_IP4_CONFIG_METHOD_DISABLED : NM_SETTING_IP6_CONFIG_METHOD_DISABLED; + const char *method_manual = + is_v4 ? NM_SETTING_IP4_CONFIG_METHOD_MANUAL : NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + NMSettingIPConfig *s_ip = is_v4 ? s_ip4 : s_ip6; + GPtrArray * data_dns = is_v4 ? data_dns_v4 : data_dns_v6; + GPtrArray * data_addr = is_v4 ? data_addr_v4 : data_addr_v6; + GPtrArray * data_dns_search2 = data_dns_search; + + if (data_dns && !data_addr) { + /* When specifying "DNS", we also require an "Address" for the same address + * family. That is because a NMSettingIPConfig cannot have @method_disabled + * and DNS settings at the same time. + * + * We don't have addresses. Silently ignore the DNS setting. */ + data_dns = NULL; + data_dns_search2 = NULL; + } + + g_object_set(s_ip, + NM_SETTING_IP_CONFIG_METHOD, + data_addr ? method_manual : method_disabled, + NULL); + + /* For WireGuard profiles, always set dns-priority to a negative value, + * so that DNS servers on other profiles get ignored. This is also what + * wg-quick does, by calling `resolvconf -x`. */ + g_object_set(s_ip, NM_SETTING_IP_CONFIG_DNS_PRIORITY, (int) -50, NULL); + + if (data_addr) { + for (i = 0; i < data_addr->len; i++) + nm_setting_ip_config_add_address(s_ip, data_addr->pdata[i]); + } + if (data_dns) { + for (i = 0; i < data_dns->len; i++) + nm_setting_ip_config_add_dns(s_ip, data_dns->pdata[i]); + + /* Of the wg-quick doesn't specify a search domain, assume the user + * wants to use the domain server for all searches. */ + if (!data_dns_search2) + nm_setting_ip_config_add_dns_search(s_ip, "~"); + } + if (data_dns_search2) { + for (i = 0; i < data_dns_search2->len; i++) + nm_setting_ip_config_add_dns_search(s_ip, data_dns_search2->pdata[i]); + } + + if (data_table == _TABLE_AUTO) { + /* in the "auto" setting, wg-quick adds peer-routes automatically to the main + * table. NetworkManager will do that too, but there are differences: + * + * - NetworkManager (contrary to wg-quick) does not check whether the peer-route is necessary. + * It will always add a route for each allowed-ips range, even if there is already another + * route that would ensure packets to the endpoint are routed via the WireGuard interface. + * If you don't want that, disable "wireguard.peer-routes", and add the necessary routes + * yourself to "ipv4.routes" and "ipv6.routes". + * + * - With "auto", wg-quick also configures policy routing to handle default-routes (/0) to + * avoid routing loops. + * The imported connection profile will have wireguard.ip4-auto-default-route and + * wireguard.ip6-auto-default-route set to "default". It will thus configure wg-quick's + * policy routing if the profile has any AllowedIPs ranges with /0. + */ + } else if (data_table == _TABLE_OFF) { + if (is_v4) { + g_object_set(s_wg, NM_SETTING_WIREGUARD_PEER_ROUTES, FALSE, NULL); + } + } else { + g_object_set(s_ip, NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) data_table, NULL); + } + } + + if (!nm_connection_normalize(connection, NULL, NULL, &local)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("Failed to create WireGuard connection: %s"), + local->message); + return FALSE; + } + + return g_steal_pointer(&connection); +} diff --git a/src/libnmc-base/nm-vpn-helpers.h b/src/libnmc-base/nm-vpn-helpers.h new file mode 100644 index 0000000..1cf0674 --- /dev/null +++ b/src/libnmc-base/nm-vpn-helpers.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2013 - 2015 Red Hat, Inc. + */ + +#ifndef __NM_VPN_HELPERS_H__ +#define __NM_VPN_HELPERS_H__ + +typedef struct { + const char *name; + const char *ui_name; +} NmcVpnPasswordName; + +GSList *nm_vpn_get_plugin_infos(void); + +NMVpnEditorPlugin *nm_vpn_get_editor_plugin(const char *service_type, GError **error); + +gboolean nm_vpn_supports_ipv6(NMConnection *connection); + +const NmcVpnPasswordName *nm_vpn_get_secret_names(const char *service_type); + +gboolean nm_vpn_openconnect_authenticate_helper(const char *host, + char ** cookie, + char ** gateway, + char ** gwcert, + int * status, + GError ** error); + +NMConnection *nm_vpn_wireguard_import(const char *filename, GError **error); + +#endif /* __NM_VPN_HELPERS_H__ */ diff --git a/src/libnmc-base/qrcodegen.c b/src/libnmc-base/qrcodegen.c new file mode 100644 index 0000000..2c40fcb --- /dev/null +++ b/src/libnmc-base/qrcodegen.c @@ -0,0 +1,1141 @@ +/* + * QR Code generator library (C) + * + * Copyright (c) Project Nayuki. (MIT License) + * https://www.nayuki.io/page/qr-code-generator-library + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +#include +#include +#include +#include +#include "qrcodegen.h" + +#ifndef QRCODEGEN_TEST + #define testable static // Keep functions private +#else + #define testable // Expose private functions +#endif + +/*---- Forward declarations for private functions ----*/ + +// Regarding all public and private functions defined in this source file: +// - They require all pointer/array arguments to be not null unless the array length is zero. +// - They only read input scalar/array arguments, write to output pointer/array +// arguments, and return scalar values; they are "pure" functions. +// - They don't read mutable global variables or write to any global variables. +// - They don't perform I/O, read the clock, print to console, etc. +// - They allocate a small and constant amount of stack memory. +// - They don't allocate or free any memory on the heap. +// - They don't recurse or mutually recurse. All the code +// could be inlined into the top-level public functions. +// - They run in at most quadratic time with respect to input arguments. +// Most functions run in linear time, and some in constant time. +// There are no unbounded loops or non-obvious termination conditions. +// - They are completely thread-safe if the caller does not give the +// same writable buffer to concurrent calls to these functions. + +testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen); + +testable void +addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]); +testable int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl); +testable int getNumRawDataModules(int ver); + +testable void calcReedSolomonGenerator(int degree, uint8_t result[]); +testable void calcReedSolomonRemainder(const uint8_t data[], + int dataLen, + const uint8_t generator[], + int degree, + uint8_t result[]); +testable uint8_t finiteFieldMultiply(uint8_t x, uint8_t y); + +testable void initializeFunctionModules(int version, uint8_t qrcode[]); +static void drawWhiteFunctionModules(uint8_t qrcode[], int version); +static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[]); +testable int getAlignmentPatternPositions(int version, uint8_t result[7]); +static void fillRectangle(int left, int top, int width, int height, uint8_t qrcode[]); + +static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[]); +static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], enum qrcodegen_Mask mask); +static long getPenaltyScore(const uint8_t qrcode[]); +static void addRunToHistory(unsigned char run, unsigned char history[7]); +static bool hasFinderLikePattern(unsigned char runHistory[7]); + +testable bool getModule(const uint8_t qrcode[], int x, int y); +testable void setModule(uint8_t qrcode[], int x, int y, bool isBlack); +testable void setModuleBounded(uint8_t qrcode[], int x, int y, bool isBlack); +static bool getBit(int x, int i); + +testable int calcSegmentBitLength(enum qrcodegen_Mode mode, size_t numChars); +testable int getTotalBits(const struct qrcodegen_Segment segs[], size_t len, int version); +static int numCharCountBits(enum qrcodegen_Mode mode, int version); + +/*---- Private tables of constants ----*/ + +// The set of all legal characters in alphanumeric mode, where each character +// value maps to the index in the string. For checking text and encoding segments. +static const char *ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; + +// For generating error correction codes. +testable const int8_t ECC_CODEWORDS_PER_BLOCK[4][41] = { + // Version: (note that index 0 is for padding, and is set to an illegal value) + //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level + {-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, + 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Low + {-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, + 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, // Medium + {-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, + 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Quartile + {-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, + 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // High +}; + +#define qrcodegen_REED_SOLOMON_DEGREE_MAX 30 // Based on the table above + +// For generating error correction codes. +testable const int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41] = { + // Version: (note that index 0 is for padding, and is set to an illegal value) + //0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level + {-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, + 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low + {-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, + 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium + {-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, + 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile + {-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, + 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High +}; + +// For automatic mask pattern selection. +static const int PENALTY_N1 = 3; +static const int PENALTY_N2 = 3; +static const int PENALTY_N3 = 40; +static const int PENALTY_N4 = 10; + +/*---- High-level QR Code encoding functions ----*/ + +// Public function - see documentation comment in header file. +bool +qrcodegen_encodeText(const char * text, + uint8_t tempBuffer[], + uint8_t qrcode[], + enum qrcodegen_Ecc ecl, + int minVersion, + int maxVersion, + enum qrcodegen_Mask mask, + bool boostEcl) +{ + size_t textLen = strlen(text); + if (textLen == 0) + return qrcodegen_encodeSegmentsAdvanced(NULL, + 0, + ecl, + minVersion, + maxVersion, + mask, + boostEcl, + tempBuffer, + qrcode); + size_t bufLen = qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion); + + struct qrcodegen_Segment seg; + if (qrcodegen_isNumeric(text)) { + if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_NUMERIC, textLen) > bufLen) + goto fail; + seg = qrcodegen_makeNumeric(text, tempBuffer); + } else if (qrcodegen_isAlphanumeric(text)) { + if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ALPHANUMERIC, textLen) > bufLen) + goto fail; + seg = qrcodegen_makeAlphanumeric(text, tempBuffer); + } else { + if (textLen > bufLen) + goto fail; + for (size_t i = 0; i < textLen; i++) + tempBuffer[i] = (uint8_t) text[i]; + seg.mode = qrcodegen_Mode_BYTE; + seg.bitLength = calcSegmentBitLength(seg.mode, textLen); + if (seg.bitLength == -1) + goto fail; + seg.numChars = (int) textLen; + seg.data = tempBuffer; + } + return qrcodegen_encodeSegmentsAdvanced(&seg, + 1, + ecl, + minVersion, + maxVersion, + mask, + boostEcl, + tempBuffer, + qrcode); + +fail: + qrcode[0] = 0; // Set size to invalid value for safety + return false; +} + +// Public function - see documentation comment in header file. +bool +qrcodegen_encodeBinary(uint8_t dataAndTemp[], + size_t dataLen, + uint8_t qrcode[], + enum qrcodegen_Ecc ecl, + int minVersion, + int maxVersion, + enum qrcodegen_Mask mask, + bool boostEcl) +{ + struct qrcodegen_Segment seg; + seg.mode = qrcodegen_Mode_BYTE; + seg.bitLength = calcSegmentBitLength(seg.mode, dataLen); + if (seg.bitLength == -1) { + qrcode[0] = 0; // Set size to invalid value for safety + return false; + } + seg.numChars = (int) dataLen; + seg.data = dataAndTemp; + return qrcodegen_encodeSegmentsAdvanced(&seg, + 1, + ecl, + minVersion, + maxVersion, + mask, + boostEcl, + dataAndTemp, + qrcode); +} + +// Appends the given number of low-order bits of the given value to the given byte-based +// bit buffer, increasing the bit length. Requires 0 <= numBits <= 16 and val < 2^numBits. +testable void +appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen) +{ + assert(0 <= numBits && numBits <= 16 && (unsigned long) val >> numBits == 0); + for (int i = numBits - 1; i >= 0; i--, (*bitLen)++) + buffer[*bitLen >> 3] |= ((val >> i) & 1) << (7 - (*bitLen & 7)); +} + +/*---- Low-level QR Code encoding functions ----*/ + +// Public function - see documentation comment in header file. +bool +qrcodegen_encodeSegments(const struct qrcodegen_Segment segs[], + size_t len, + enum qrcodegen_Ecc ecl, + uint8_t tempBuffer[], + uint8_t qrcode[]) +{ + return qrcodegen_encodeSegmentsAdvanced(segs, + len, + ecl, + qrcodegen_VERSION_MIN, + qrcodegen_VERSION_MAX, + -1, + true, + tempBuffer, + qrcode); +} + +// Public function - see documentation comment in header file. +bool +qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], + size_t len, + enum qrcodegen_Ecc ecl, + int minVersion, + int maxVersion, + int mask, + bool boostEcl, + uint8_t tempBuffer[], + uint8_t qrcode[]) +{ + assert(segs != NULL || len == 0); + assert(qrcodegen_VERSION_MIN <= minVersion && minVersion <= maxVersion + && maxVersion <= qrcodegen_VERSION_MAX); + assert(0 <= (int) ecl && (int) ecl <= 3 && -1 <= (int) mask && (int) mask <= 7); + + // Find the minimal version number to use + int version, dataUsedBits; + for (version = minVersion;; version++) { + int dataCapacityBits = + getNumDataCodewords(version, ecl) * 8; // Number of data bits available + dataUsedBits = getTotalBits(segs, len, version); + if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits) + break; // This version number is found to be suitable + if (version >= maxVersion) { // All versions in the range could not fit the given data + qrcode[0] = 0; // Set size to invalid value for safety + return false; + } + } + assert(dataUsedBits != -1); + + // Increase the error correction level while the data still fits in the current version number + for (int i = (int) qrcodegen_Ecc_MEDIUM; i <= (int) qrcodegen_Ecc_HIGH; + i++) { // From low to high + if (boostEcl && dataUsedBits <= getNumDataCodewords(version, (enum qrcodegen_Ecc) i) * 8) + ecl = (enum qrcodegen_Ecc) i; + } + + // Concatenate all segments to create the data bit string + memset(qrcode, 0, qrcodegen_BUFFER_LEN_FOR_VERSION(version) * sizeof(qrcode[0])); + int bitLen = 0; + for (size_t i = 0; i < len; i++) { + const struct qrcodegen_Segment *seg = &segs[i]; + appendBitsToBuffer((int) seg->mode, 4, qrcode, &bitLen); + appendBitsToBuffer(seg->numChars, numCharCountBits(seg->mode, version), qrcode, &bitLen); + for (int j = 0; j < seg->bitLength; j++) + appendBitsToBuffer((seg->data[j >> 3] >> (7 - (j & 7))) & 1, 1, qrcode, &bitLen); + } + assert(bitLen == dataUsedBits); + + // Add terminator and pad up to a byte if applicable + int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; + assert(bitLen <= dataCapacityBits); + int terminatorBits = dataCapacityBits - bitLen; + if (terminatorBits > 4) + terminatorBits = 4; + appendBitsToBuffer(0, terminatorBits, qrcode, &bitLen); + appendBitsToBuffer(0, (8 - bitLen % 8) % 8, qrcode, &bitLen); + assert(bitLen % 8 == 0); + + // Pad with alternating bytes until data capacity is reached + for (uint8_t padByte = 0xEC; bitLen < dataCapacityBits; padByte ^= 0xEC ^ 0x11) + appendBitsToBuffer(padByte, 8, qrcode, &bitLen); + + // Draw function and data codeword modules + addEccAndInterleave(qrcode, version, ecl, tempBuffer); + initializeFunctionModules(version, qrcode); + drawCodewords(tempBuffer, getNumRawDataModules(version) / 8, qrcode); + drawWhiteFunctionModules(qrcode, version); + initializeFunctionModules(version, tempBuffer); + + // Handle masking + if (mask == qrcodegen_Mask_AUTO) { // Automatically choose best mask + long minPenalty = LONG_MAX; + for (int i = 0; i < 8; i++) { + enum qrcodegen_Mask msk = (enum qrcodegen_Mask) i; + drawFormatBits(ecl, msk, qrcode); + applyMask(tempBuffer, qrcode, msk); + long penalty = getPenaltyScore(qrcode); + if (penalty < minPenalty) { + mask = msk; + minPenalty = penalty; + } + applyMask(tempBuffer, qrcode, msk); // Undoes the mask due to XOR + } + } + assert(0 <= (int) mask && (int) mask <= 7); + drawFormatBits(ecl, mask, qrcode); + applyMask(tempBuffer, qrcode, mask); + return true; +} + +/*---- Error correction code generation functions ----*/ + +// Appends error correction bytes to each block of the given data array, then interleaves +// bytes from the blocks and stores them in the result array. data[0 : dataLen] contains +// the input data. data[dataLen : rawCodewords] is used as a temporary work area and will +// be clobbered by this function. The final answer is stored in result[0 : rawCodewords]. +testable void +addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]) +{ + // Calculate parameter numbers + assert(0 <= (int) ecl && (int) ecl < 4 && qrcodegen_VERSION_MIN <= version + && version <= qrcodegen_VERSION_MAX); + int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[(int) ecl][version]; + int blockEccLen = ECC_CODEWORDS_PER_BLOCK[(int) ecl][version]; + int rawCodewords = getNumRawDataModules(version) / 8; + int dataLen = getNumDataCodewords(version, ecl); + int numShortBlocks = numBlocks - rawCodewords % numBlocks; + int shortBlockDataLen = rawCodewords / numBlocks - blockEccLen; + + // Split data into blocks, calculate ECC, and interleave + // (not concatenate) the bytes into a single sequence + uint8_t generator[qrcodegen_REED_SOLOMON_DEGREE_MAX]; + calcReedSolomonGenerator(blockEccLen, generator); + const uint8_t *dat = data; + for (int i = 0; i < numBlocks; i++) { + int datLen = shortBlockDataLen + (i < numShortBlocks ? 0 : 1); + uint8_t *ecc = &data[dataLen]; // Temporary storage + calcReedSolomonRemainder(dat, datLen, generator, blockEccLen, ecc); + for (int j = 0, k = i; j < datLen; j++, k += numBlocks) { // Copy data + if (j == shortBlockDataLen) + k -= numShortBlocks; + result[k] = dat[j]; + } + for (int j = 0, k = dataLen + i; j < blockEccLen; j++, k += numBlocks) // Copy ECC + result[k] = ecc[j]; + dat += datLen; + } +} + +// Returns the number of 8-bit codewords that can be used for storing data (not ECC), +// for the given version number and error correction level. The result is in the range [9, 2956]. +testable int +getNumDataCodewords(int version, enum qrcodegen_Ecc ecl) +{ + int v = version, e = (int) ecl; + assert(0 <= e && e < 4); + return getNumRawDataModules(v) / 8 + - ECC_CODEWORDS_PER_BLOCK[e][v] * NUM_ERROR_CORRECTION_BLOCKS[e][v]; +} + +// Returns the number of data bits that can be stored in a QR Code of the given version number, after +// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8. +// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table. +testable int +getNumRawDataModules(int ver) +{ + assert(qrcodegen_VERSION_MIN <= ver && ver <= qrcodegen_VERSION_MAX); + int result = (16 * ver + 128) * ver + 64; + if (ver >= 2) { + int numAlign = ver / 7 + 2; + result -= (25 * numAlign - 10) * numAlign - 55; + if (ver >= 7) + result -= 36; + } + return result; +} + +/*---- Reed-Solomon ECC generator functions ----*/ + +// Calculates the Reed-Solomon generator polynomial of the given degree, storing in result[0 : degree]. +testable void +calcReedSolomonGenerator(int degree, uint8_t result[]) +{ + // Start with the monomial x^0 + assert(1 <= degree && degree <= qrcodegen_REED_SOLOMON_DEGREE_MAX); + memset(result, 0, degree * sizeof(result[0])); + result[degree - 1] = 1; + + // Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}), + // drop the highest term, and store the rest of the coefficients in order of descending powers. + // Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D). + uint8_t root = 1; + for (int i = 0; i < degree; i++) { + // Multiply the current product by (x - r^i) + for (int j = 0; j < degree; j++) { + result[j] = finiteFieldMultiply(result[j], root); + if (j + 1 < degree) + result[j] ^= result[j + 1]; + } + root = finiteFieldMultiply(root, 0x02); + } +} + +// Calculates the remainder of the polynomial data[0 : dataLen] when divided by the generator[0 : degree], where all +// polynomials are in big endian and the generator has an implicit leading 1 term, storing the result in result[0 : degree]. +testable void +calcReedSolomonRemainder(const uint8_t data[], + int dataLen, + const uint8_t generator[], + int degree, + uint8_t result[]) +{ + // Perform polynomial division + assert(1 <= degree && degree <= qrcodegen_REED_SOLOMON_DEGREE_MAX); + memset(result, 0, degree * sizeof(result[0])); + for (int i = 0; i < dataLen; i++) { + uint8_t factor = data[i] ^ result[0]; + memmove(&result[0], &result[1], (degree - 1) * sizeof(result[0])); + result[degree - 1] = 0; + for (int j = 0; j < degree; j++) + result[j] ^= finiteFieldMultiply(generator[j], factor); + } +} + +#undef qrcodegen_REED_SOLOMON_DEGREE_MAX + +// Returns the product of the two given field elements modulo GF(2^8/0x11D). +// All inputs are valid. This could be implemented as a 256*256 lookup table. +testable uint8_t +finiteFieldMultiply(uint8_t x, uint8_t y) +{ + // Russian peasant multiplication + uint8_t z = 0; + for (int i = 7; i >= 0; i--) { + z = (z << 1) ^ ((z >> 7) * 0x11D); + z ^= ((y >> i) & 1) * x; + } + return z; +} + +/*---- Drawing function modules ----*/ + +// Clears the given QR Code grid with white modules for the given +// version's size, then marks every function module as black. +testable void +initializeFunctionModules(int version, uint8_t qrcode[]) +{ + // Initialize QR Code + int qrsize = version * 4 + 17; + memset(qrcode, 0, ((qrsize * qrsize + 7) / 8 + 1) * sizeof(qrcode[0])); + qrcode[0] = (uint8_t) qrsize; + + // Fill horizontal and vertical timing patterns + fillRectangle(6, 0, 1, qrsize, qrcode); + fillRectangle(0, 6, qrsize, 1, qrcode); + + // Fill 3 finder patterns (all corners except bottom right) and format bits + fillRectangle(0, 0, 9, 9, qrcode); + fillRectangle(qrsize - 8, 0, 8, 9, qrcode); + fillRectangle(0, qrsize - 8, 9, 8, qrcode); + + // Fill numerous alignment patterns + uint8_t alignPatPos[7]; + int numAlign = getAlignmentPatternPositions(version, alignPatPos); + for (int i = 0; i < numAlign; i++) { + for (int j = 0; j < numAlign; j++) { + // Don't draw on the three finder corners + if (!((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) + || (i == numAlign - 1 && j == 0))) + fillRectangle(alignPatPos[i] - 2, alignPatPos[j] - 2, 5, 5, qrcode); + } + } + + // Fill version blocks + if (version >= 7) { + fillRectangle(qrsize - 11, 0, 3, 6, qrcode); + fillRectangle(0, qrsize - 11, 6, 3, qrcode); + } +} + +// Draws white function modules and possibly some black modules onto the given QR Code, without changing +// non-function modules. This does not draw the format bits. This requires all function modules to be previously +// marked black (namely by initializeFunctionModules()), because this may skip redrawing black function modules. +static void +drawWhiteFunctionModules(uint8_t qrcode[], int version) +{ + // Draw horizontal and vertical timing patterns + int qrsize = qrcodegen_getSize(qrcode); + for (int i = 7; i < qrsize - 7; i += 2) { + setModule(qrcode, 6, i, false); + setModule(qrcode, i, 6, false); + } + + // Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules) + for (int dy = -4; dy <= 4; dy++) { + for (int dx = -4; dx <= 4; dx++) { + int dist = abs(dx); + if (abs(dy) > dist) + dist = abs(dy); + if (dist == 2 || dist == 4) { + setModuleBounded(qrcode, 3 + dx, 3 + dy, false); + setModuleBounded(qrcode, qrsize - 4 + dx, 3 + dy, false); + setModuleBounded(qrcode, 3 + dx, qrsize - 4 + dy, false); + } + } + } + + // Draw numerous alignment patterns + uint8_t alignPatPos[7]; + int numAlign = getAlignmentPatternPositions(version, alignPatPos); + for (int i = 0; i < numAlign; i++) { + for (int j = 0; j < numAlign; j++) { + if ((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) + || (i == numAlign - 1 && j == 0)) + continue; // Don't draw on the three finder corners + for (int dy = -1; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++) + setModule(qrcode, alignPatPos[i] + dx, alignPatPos[j] + dy, dx == 0 && dy == 0); + } + } + } + + // Draw version blocks + if (version >= 7) { + // Calculate error correction code and pack bits + int rem = version; // version is uint6, in the range [7, 40] + for (int i = 0; i < 12; i++) + rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); + long bits = (long) version << 12 | rem; // uint18 + assert(bits >> 18 == 0); + + // Draw two copies + for (int i = 0; i < 6; i++) { + for (int j = 0; j < 3; j++) { + int k = qrsize - 11 + j; + setModule(qrcode, k, i, (bits & 1) != 0); + setModule(qrcode, i, k, (bits & 1) != 0); + bits >>= 1; + } + } + } +} + +// Draws two copies of the format bits (with its own error correction code) based +// on the given mask and error correction level. This always draws all modules of +// the format bits, unlike drawWhiteFunctionModules() which might skip black modules. +static void +drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[]) +{ + // Calculate error correction code and pack bits + assert(0 <= (int) mask && (int) mask <= 7); + static const int table[] = {1, 0, 3, 2}; + int data = table[(int) ecl] << 3 | (int) mask; // errCorrLvl is uint2, mask is uint3 + int rem = data; + for (int i = 0; i < 10; i++) + rem = (rem << 1) ^ ((rem >> 9) * 0x537); + int bits = (data << 10 | rem) ^ 0x5412; // uint15 + assert(bits >> 15 == 0); + + // Draw first copy + for (int i = 0; i <= 5; i++) + setModule(qrcode, 8, i, getBit(bits, i)); + setModule(qrcode, 8, 7, getBit(bits, 6)); + setModule(qrcode, 8, 8, getBit(bits, 7)); + setModule(qrcode, 7, 8, getBit(bits, 8)); + for (int i = 9; i < 15; i++) + setModule(qrcode, 14 - i, 8, getBit(bits, i)); + + // Draw second copy + int qrsize = qrcodegen_getSize(qrcode); + for (int i = 0; i < 8; i++) + setModule(qrcode, qrsize - 1 - i, 8, getBit(bits, i)); + for (int i = 8; i < 15; i++) + setModule(qrcode, 8, qrsize - 15 + i, getBit(bits, i)); + setModule(qrcode, 8, qrsize - 8, true); // Always black +} + +// Calculates and stores an ascending list of positions of alignment patterns +// for this version number, returning the length of the list (in the range [0,7]). +// Each position is in the range [0,177), and are used on both the x and y axes. +// This could be implemented as lookup table of 40 variable-length lists of unsigned bytes. +testable int +getAlignmentPatternPositions(int version, uint8_t result[7]) +{ + if (version == 1) + return 0; + int numAlign = version / 7 + 2; + int step = (version == 32) ? 26 : (version * 4 + numAlign * 2 + 1) / (numAlign * 2 - 2) * 2; + for (int i = numAlign - 1, pos = version * 4 + 10; i >= 1; i--, pos -= step) + result[i] = pos; + result[0] = 6; + return numAlign; +} + +// Sets every pixel in the range [left : left + width] * [top : top + height] to black. +static void +fillRectangle(int left, int top, int width, int height, uint8_t qrcode[]) +{ + for (int dy = 0; dy < height; dy++) { + for (int dx = 0; dx < width; dx++) + setModule(qrcode, left + dx, top + dy, true); + } +} + +/*---- Drawing data modules and masking ----*/ + +// Draws the raw codewords (including data and ECC) onto the given QR Code. This requires the initial state of +// the QR Code to be black at function modules and white at codeword modules (including unused remainder bits). +static void +drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[]) +{ + int qrsize = qrcodegen_getSize(qrcode); + int i = 0; // Bit index into the data + // Do the funny zigzag scan + for (int right = qrsize - 1; right >= 1; + right -= 2) { // Index of right column in each column pair + if (right == 6) + right = 5; + for (int vert = 0; vert < qrsize; vert++) { // Vertical counter + for (int j = 0; j < 2; j++) { + int x = right - j; // Actual x coordinate + bool upward = ((right + 1) & 2) == 0; + int y = upward ? qrsize - 1 - vert : vert; // Actual y coordinate + if (!getModule(qrcode, x, y) && i < dataLen * 8) { + bool black = getBit(data[i >> 3], 7 - (i & 7)); + setModule(qrcode, x, y, black); + i++; + } + // If this QR Code has any remainder bits (0 to 7), they were assigned as + // 0/false/white by the constructor and are left unchanged by this method + } + } + } + assert(i == dataLen * 8); +} + +// XORs the codeword modules in this QR Code with the given mask pattern. +// The function modules must be marked and the codeword bits must be drawn +// before masking. Due to the arithmetic of XOR, calling applyMask() with +// the same mask value a second time will undo the mask. A final well-formed +// QR Code needs exactly one (not zero, two, etc.) mask applied. +static void +applyMask(const uint8_t functionModules[], uint8_t qrcode[], enum qrcodegen_Mask mask) +{ + assert(0 <= (int) mask && (int) mask <= 7); // Disallows qrcodegen_Mask_AUTO + int qrsize = qrcodegen_getSize(qrcode); + for (int y = 0; y < qrsize; y++) { + for (int x = 0; x < qrsize; x++) { + if (getModule(functionModules, x, y)) + continue; + bool invert; + switch ((int) mask) { + case 0: + invert = (x + y) % 2 == 0; + break; + case 1: + invert = y % 2 == 0; + break; + case 2: + invert = x % 3 == 0; + break; + case 3: + invert = (x + y) % 3 == 0; + break; + case 4: + invert = (x / 3 + y / 2) % 2 == 0; + break; + case 5: + invert = x * y % 2 + x * y % 3 == 0; + break; + case 6: + invert = (x * y % 2 + x * y % 3) % 2 == 0; + break; + case 7: + invert = ((x + y) % 2 + x * y % 3) % 2 == 0; + break; + default: + assert(false); + return; + } + bool val = getModule(qrcode, x, y); + setModule(qrcode, x, y, val ^ invert); + } + } +} + +// Calculates and returns the penalty score based on state of the given QR Code's current modules. +// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. +static long +getPenaltyScore(const uint8_t qrcode[]) +{ + int qrsize = qrcodegen_getSize(qrcode); + long result = 0; + + // Adjacent modules in row having same color, and finder-like patterns + for (int y = 0; y < qrsize; y++) { + unsigned char runHistory[7] = {0}; + bool color = false; + unsigned char runX = 0; + for (int x = 0; x < qrsize; x++) { + if (getModule(qrcode, x, y) == color) { + runX++; + if (runX == 5) + result += PENALTY_N1; + else if (runX > 5) + result++; + } else { + addRunToHistory(runX, runHistory); + if (!color && hasFinderLikePattern(runHistory)) + result += PENALTY_N3; + color = getModule(qrcode, x, y); + runX = 1; + } + } + addRunToHistory(runX, runHistory); + if (color) + addRunToHistory(0, runHistory); // Dummy run of white + if (hasFinderLikePattern(runHistory)) + result += PENALTY_N3; + } + // Adjacent modules in column having same color, and finder-like patterns + for (int x = 0; x < qrsize; x++) { + unsigned char runHistory[7] = {0}; + bool color = false; + unsigned char runY = 0; + for (int y = 0; y < qrsize; y++) { + if (getModule(qrcode, x, y) == color) { + runY++; + if (runY == 5) + result += PENALTY_N1; + else if (runY > 5) + result++; + } else { + addRunToHistory(runY, runHistory); + if (!color && hasFinderLikePattern(runHistory)) + result += PENALTY_N3; + color = getModule(qrcode, x, y); + runY = 1; + } + } + addRunToHistory(runY, runHistory); + if (color) + addRunToHistory(0, runHistory); // Dummy run of white + if (hasFinderLikePattern(runHistory)) + result += PENALTY_N3; + } + + // 2*2 blocks of modules having same color + for (int y = 0; y < qrsize - 1; y++) { + for (int x = 0; x < qrsize - 1; x++) { + bool color = getModule(qrcode, x, y); + if (color == getModule(qrcode, x + 1, y) && color == getModule(qrcode, x, y + 1) + && color == getModule(qrcode, x + 1, y + 1)) + result += PENALTY_N2; + } + } + + // Balance of black and white modules + int black = 0; + for (int y = 0; y < qrsize; y++) { + for (int x = 0; x < qrsize; x++) { + if (getModule(qrcode, x, y)) + black++; + } + } + int total = qrsize * qrsize; // Note that size is odd, so black/total != 1/2 + // Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)% + int k = (int) ((labs(black * 20L - total * 10L) + total - 1) / total) - 1; + result += k * PENALTY_N4; + return result; +} + +// Inserts the given value to the front of the given array, which shifts over the +// existing values and deletes the last value. A helper function for getPenaltyScore(). +static void +addRunToHistory(unsigned char run, unsigned char history[7]) +{ + memmove(&history[1], &history[0], 6 * sizeof(history[0])); + history[0] = run; +} + +// Tests whether the given run history has the pattern of ratio 1:1:3:1:1 in the middle, and +// surrounded by at least 4 on either or both ends. A helper function for getPenaltyScore(). +// Must only be called immediately after a run of white modules has ended. +static bool +hasFinderLikePattern(unsigned char runHistory[7]) +{ + unsigned char n = runHistory[1]; + // The maximum QR Code size is 177, hence the run length n <= 177. + // Arithmetic is promoted to int, so n*4 will not overflow. + return n > 0 && runHistory[2] == n && runHistory[4] == n && runHistory[5] == n + && runHistory[3] == n * 3 && (runHistory[0] >= n * 4 || runHistory[6] >= n * 4); +} + +/*---- Basic QR Code information ----*/ + +// Public function - see documentation comment in header file. +int +qrcodegen_getSize(const uint8_t qrcode[]) +{ + assert(qrcode != NULL); + int result = qrcode[0]; + assert((qrcodegen_VERSION_MIN * 4 + 17) <= result + && result <= (qrcodegen_VERSION_MAX * 4 + 17)); + return result; +} + +// Public function - see documentation comment in header file. +bool +qrcodegen_getModule(const uint8_t qrcode[], int x, int y) +{ + assert(qrcode != NULL); + int qrsize = qrcode[0]; + return (0 <= x && x < qrsize && 0 <= y && y < qrsize) && getModule(qrcode, x, y); +} + +// Gets the module at the given coordinates, which must be in bounds. +testable bool +getModule(const uint8_t qrcode[], int x, int y) +{ + int qrsize = qrcode[0]; + assert(21 <= qrsize && qrsize <= 177 && 0 <= x && x < qrsize && 0 <= y && y < qrsize); + int index = y * qrsize + x; + return getBit(qrcode[(index >> 3) + 1], index & 7); +} + +// Sets the module at the given coordinates, which must be in bounds. +testable void +setModule(uint8_t qrcode[], int x, int y, bool isBlack) +{ + int qrsize = qrcode[0]; + assert(21 <= qrsize && qrsize <= 177 && 0 <= x && x < qrsize && 0 <= y && y < qrsize); + int index = y * qrsize + x; + int bitIndex = index & 7; + int byteIndex = (index >> 3) + 1; + if (isBlack) + qrcode[byteIndex] |= 1 << bitIndex; + else + qrcode[byteIndex] &= (1 << bitIndex) ^ 0xFF; +} + +// Sets the module at the given coordinates, doing nothing if out of bounds. +testable void +setModuleBounded(uint8_t qrcode[], int x, int y, bool isBlack) +{ + int qrsize = qrcode[0]; + if (0 <= x && x < qrsize && 0 <= y && y < qrsize) + setModule(qrcode, x, y, isBlack); +} + +// Returns true iff the i'th bit of x is set to 1. Requires x >= 0 and 0 <= i <= 14. +static bool +getBit(int x, int i) +{ + return ((x >> i) & 1) != 0; +} + +/*---- Segment handling ----*/ + +// Public function - see documentation comment in header file. +bool +qrcodegen_isAlphanumeric(const char *text) +{ + assert(text != NULL); + for (; *text != '\0'; text++) { + if (strchr(ALPHANUMERIC_CHARSET, *text) == NULL) + return false; + } + return true; +} + +// Public function - see documentation comment in header file. +bool +qrcodegen_isNumeric(const char *text) +{ + assert(text != NULL); + for (; *text != '\0'; text++) { + if (*text < '0' || *text > '9') + return false; + } + return true; +} + +// Public function - see documentation comment in header file. +size_t +qrcodegen_calcSegmentBufferSize(enum qrcodegen_Mode mode, size_t numChars) +{ + int temp = calcSegmentBitLength(mode, numChars); + if (temp == -1) + return SIZE_MAX; + assert(0 <= temp && temp <= INT16_MAX); + return ((size_t) temp + 7) / 8; +} + +// Returns the number of data bits needed to represent a segment +// containing the given number of characters using the given mode. Notes: +// - Returns -1 on failure, i.e. numChars > INT16_MAX or +// the number of needed bits exceeds INT16_MAX (i.e. 32767). +// - Otherwise, all valid results are in the range [0, INT16_MAX]. +// - For byte mode, numChars measures the number of bytes, not Unicode code points. +// - For ECI mode, numChars must be 0, and the worst-case number of bits is returned. +// An actual ECI segment can have shorter data. For non-ECI modes, the result is exact. +testable int +calcSegmentBitLength(enum qrcodegen_Mode mode, size_t numChars) +{ + // All calculations are designed to avoid overflow on all platforms + if (numChars > (unsigned int) INT16_MAX) + return -1; + long result = (long) numChars; + if (mode == qrcodegen_Mode_NUMERIC) + result = (result * 10 + 2) / 3; // ceil(10/3 * n) + else if (mode == qrcodegen_Mode_ALPHANUMERIC) + result = (result * 11 + 1) / 2; // ceil(11/2 * n) + else if (mode == qrcodegen_Mode_BYTE) + result *= 8; + else if (mode == qrcodegen_Mode_KANJI) + result *= 13; + else if (mode == qrcodegen_Mode_ECI && numChars == 0) + result = 3 * 8; + else { // Invalid argument + assert(false); + return -1; + } + assert(result >= 0); + if (result > (unsigned int) INT16_MAX) + return -1; + return (int) result; +} + +// Public function - see documentation comment in header file. +struct qrcodegen_Segment +qrcodegen_makeBytes(const uint8_t data[], size_t len, uint8_t buf[]) +{ + assert(data != NULL || len == 0); + struct qrcodegen_Segment result; + result.mode = qrcodegen_Mode_BYTE; + result.bitLength = calcSegmentBitLength(result.mode, len); + assert(result.bitLength != -1); + result.numChars = (int) len; + if (len > 0) + memcpy(buf, data, len * sizeof(buf[0])); + result.data = buf; + return result; +} + +// Public function - see documentation comment in header file. +struct qrcodegen_Segment +qrcodegen_makeNumeric(const char *digits, uint8_t buf[]) +{ + assert(digits != NULL); + struct qrcodegen_Segment result; + size_t len = strlen(digits); + result.mode = qrcodegen_Mode_NUMERIC; + int bitLen = calcSegmentBitLength(result.mode, len); + assert(bitLen != -1); + result.numChars = (int) len; + if (bitLen > 0) + memset(buf, 0, ((size_t) bitLen + 7) / 8 * sizeof(buf[0])); + result.bitLength = 0; + + unsigned int accumData = 0; + int accumCount = 0; + for (; *digits != '\0'; digits++) { + char c = *digits; + assert('0' <= c && c <= '9'); + accumData = accumData * 10 + (unsigned int) (c - '0'); + accumCount++; + if (accumCount == 3) { + appendBitsToBuffer(accumData, 10, buf, &result.bitLength); + accumData = 0; + accumCount = 0; + } + } + if (accumCount > 0) // 1 or 2 digits remaining + appendBitsToBuffer(accumData, accumCount * 3 + 1, buf, &result.bitLength); + assert(result.bitLength == bitLen); + result.data = buf; + return result; +} + +// Public function - see documentation comment in header file. +struct qrcodegen_Segment +qrcodegen_makeAlphanumeric(const char *text, uint8_t buf[]) +{ + assert(text != NULL); + struct qrcodegen_Segment result; + size_t len = strlen(text); + result.mode = qrcodegen_Mode_ALPHANUMERIC; + int bitLen = calcSegmentBitLength(result.mode, len); + assert(bitLen != -1); + result.numChars = (int) len; + if (bitLen > 0) + memset(buf, 0, ((size_t) bitLen + 7) / 8 * sizeof(buf[0])); + result.bitLength = 0; + + unsigned int accumData = 0; + int accumCount = 0; + for (; *text != '\0'; text++) { + const char *temp = strchr(ALPHANUMERIC_CHARSET, *text); + assert(temp != NULL); + accumData = accumData * 45 + (unsigned int) (temp - ALPHANUMERIC_CHARSET); + accumCount++; + if (accumCount == 2) { + appendBitsToBuffer(accumData, 11, buf, &result.bitLength); + accumData = 0; + accumCount = 0; + } + } + if (accumCount > 0) // 1 character remaining + appendBitsToBuffer(accumData, 6, buf, &result.bitLength); + assert(result.bitLength == bitLen); + result.data = buf; + return result; +} + +// Public function - see documentation comment in header file. +struct qrcodegen_Segment +qrcodegen_makeEci(long assignVal, uint8_t buf[]) +{ + struct qrcodegen_Segment result; + result.mode = qrcodegen_Mode_ECI; + result.numChars = 0; + result.bitLength = 0; + if (assignVal < 0) + assert(false); + else if (assignVal < (1 << 7)) { + memset(buf, 0, 1 * sizeof(buf[0])); + appendBitsToBuffer(assignVal, 8, buf, &result.bitLength); + } else if (assignVal < (1 << 14)) { + memset(buf, 0, 2 * sizeof(buf[0])); + appendBitsToBuffer(2, 2, buf, &result.bitLength); + appendBitsToBuffer(assignVal, 14, buf, &result.bitLength); + } else if (assignVal < 1000000L) { + memset(buf, 0, 3 * sizeof(buf[0])); + appendBitsToBuffer(6, 3, buf, &result.bitLength); + appendBitsToBuffer(assignVal >> 10, 11, buf, &result.bitLength); + appendBitsToBuffer(assignVal & 0x3FF, 10, buf, &result.bitLength); + } else + assert(false); + result.data = buf; + return result; +} + +// Calculates the number of bits needed to encode the given segments at the given version. +// Returns a non-negative number if successful. Otherwise, returns -1 if a segment has too +// many characters to fit its length field, or the total bits exceeds INT16_MAX. +testable int +getTotalBits(const struct qrcodegen_Segment segs[], size_t len, int version) +{ + assert(segs != NULL || len == 0); + long result = 0; + for (size_t i = 0; i < len; i++) { + int numChars = segs[i].numChars; + int bitLength = segs[i].bitLength; + assert(0 <= numChars && numChars <= INT16_MAX); + assert(0 <= bitLength && bitLength <= INT16_MAX); + int ccbits = numCharCountBits(segs[i].mode, version); + assert(0 <= ccbits && ccbits <= 16); + if (numChars >= (1L << ccbits)) + return -1; // The segment's length doesn't fit the field's bit width + result += 4L + ccbits + bitLength; + if (result > INT16_MAX) + return -1; // The sum might overflow an int type + } + assert(0 <= result && result <= INT16_MAX); + return (int) result; +} + +// Returns the bit width of the character count field for a segment in the given mode +// in a QR Code at the given version number. The result is in the range [0, 16]. +static int +numCharCountBits(enum qrcodegen_Mode mode, int version) +{ + assert(qrcodegen_VERSION_MIN <= version && version <= qrcodegen_VERSION_MAX); + int i = (version + 7) / 17; + switch (mode) { + case qrcodegen_Mode_NUMERIC: + { + static const int temp[] = {10, 12, 14}; + return temp[i]; + } + case qrcodegen_Mode_ALPHANUMERIC: + { + static const int temp[] = {9, 11, 13}; + return temp[i]; + } + case qrcodegen_Mode_BYTE: + { + static const int temp[] = {8, 16, 16}; + return temp[i]; + } + case qrcodegen_Mode_KANJI: + { + static const int temp[] = {8, 10, 12}; + return temp[i]; + } + case qrcodegen_Mode_ECI: + return 0; + default: + assert(false); + return -1; // Dummy value + } +} diff --git a/src/libnmc-base/qrcodegen.h b/src/libnmc-base/qrcodegen.h new file mode 100644 index 0000000..b91ae49 --- /dev/null +++ b/src/libnmc-base/qrcodegen.h @@ -0,0 +1,312 @@ +/* + * QR Code generator library (C) + * + * Copyright (c) Project Nayuki. (MIT License) + * https://www.nayuki.io/page/qr-code-generator-library + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This library creates QR Code symbols, which is a type of two-dimension barcode. + * Invented by Denso Wave and described in the ISO/IEC 18004 standard. + * A QR Code structure is an immutable square grid of black and white cells. + * The library provides functions to create a QR Code from text or binary data. + * The library covers the QR Code Model 2 specification, supporting all versions (sizes) + * from 1 to 40, all 4 error correction levels, and 4 character encoding modes. + * + * Ways to create a QR Code object: + * - High level: Take the payload data and call qrcodegen_encodeText() or qrcodegen_encodeBinary(). + * - Low level: Custom-make the list of segments and call + * qrcodegen_encodeSegments() or qrcodegen_encodeSegmentsAdvanced(). + * (Note that all ways require supplying the desired error correction level and various byte buffers.) + */ + +/*---- Enum and struct types----*/ + +/* + * The error correction level in a QR Code symbol. + */ +enum qrcodegen_Ecc { + // Must be declared in ascending order of error protection + // so that an internal qrcodegen function works properly + qrcodegen_Ecc_LOW = 0, // The QR Code can tolerate about 7% erroneous codewords + qrcodegen_Ecc_MEDIUM, // The QR Code can tolerate about 15% erroneous codewords + qrcodegen_Ecc_QUARTILE, // The QR Code can tolerate about 25% erroneous codewords + qrcodegen_Ecc_HIGH, // The QR Code can tolerate about 30% erroneous codewords +}; + +/* + * The mask pattern used in a QR Code symbol. + */ +enum qrcodegen_Mask { + // A special value to tell the QR Code encoder to + // automatically select an appropriate mask pattern + qrcodegen_Mask_AUTO = -1, + // The eight actual mask patterns + qrcodegen_Mask_0 = 0, + qrcodegen_Mask_1, + qrcodegen_Mask_2, + qrcodegen_Mask_3, + qrcodegen_Mask_4, + qrcodegen_Mask_5, + qrcodegen_Mask_6, + qrcodegen_Mask_7, +}; + +/* + * Describes how a segment's data bits are interpreted. + */ +enum qrcodegen_Mode { + qrcodegen_Mode_NUMERIC = 0x1, + qrcodegen_Mode_ALPHANUMERIC = 0x2, + qrcodegen_Mode_BYTE = 0x4, + qrcodegen_Mode_KANJI = 0x8, + qrcodegen_Mode_ECI = 0x7, +}; + +/* + * A segment of character/binary/control data in a QR Code symbol. + * The mid-level way to create a segment is to take the payload data + * and call a factory function such as qrcodegen_makeNumeric(). + * The low-level way to create a segment is to custom-make the bit buffer + * and initialize a qrcodegen_Segment struct with appropriate values. + * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data. + * Any segment longer than this is meaningless for the purpose of generating QR Codes. + * Moreover, the maximum allowed bit length is 32767 because + * the largest QR Code (version 40) has 31329 modules. + */ +struct qrcodegen_Segment { + // The mode indicator of this segment. + enum qrcodegen_Mode mode; + + // The length of this segment's unencoded data. Measured in characters for + // numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode. + // Always zero or positive. Not the same as the data's bit length. + int numChars; + + // The data bits of this segment, packed in bitwise big endian. + // Can be null if the bit length is zero. + uint8_t *data; + + // The number of valid data bits used in the buffer. Requires + // 0 <= bitLength <= 32767, and bitLength <= (capacity of data array) * 8. + // The character count (numChars) must agree with the mode and the bit buffer length. + int bitLength; +}; + +/*---- Macro constants and functions ----*/ + +#define qrcodegen_VERSION_MIN \ + 1 // The minimum version number supported in the QR Code Model 2 standard +#define qrcodegen_VERSION_MAX \ + 40 // The maximum version number supported in the QR Code Model 2 standard + +// Calculates the number of bytes needed to store any QR Code up to and including the given version number, +// as a compile-time constant. For example, 'uint8_t buffer[qrcodegen_BUFFER_LEN_FOR_VERSION(25)];' +// can store any single QR Code from version 1 to 25 (inclusive). The result fits in an int (or int16). +// Requires qrcodegen_VERSION_MIN <= n <= qrcodegen_VERSION_MAX. +#define qrcodegen_BUFFER_LEN_FOR_VERSION(n) ((((n) *4 + 17) * ((n) *4 + 17) + 7) / 8 + 1) + +// The worst-case number of bytes needed to store one QR Code, up to and including +// version 40. This value equals 3918, which is just under 4 kilobytes. +// Use this more convenient value to avoid calculating tighter memory bounds for buffers. +#define qrcodegen_BUFFER_LEN_MAX qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX) + +/*---- Functions (high level) to generate QR Codes ----*/ + +/* + * Encodes the given text string to a QR Code, returning true if encoding succeeded. + * If the data is too long to fit in any version in the given range + * at the given ECC level, then false is returned. + * - The input text must be encoded in UTF-8 and contain no NULs. + * - The variables ecl and mask must correspond to enum constant values. + * - Requires 1 <= minVersion <= maxVersion <= 40. + * - The arrays tempBuffer and qrcode must each have a length + * of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion). + * - After the function returns, tempBuffer contains no useful data. + * - If successful, the resulting QR Code may use numeric, + * alphanumeric, or byte mode to encode the text. + * - In the most optimistic case, a QR Code at version 40 with low ECC + * can hold any UTF-8 string up to 2953 bytes, or any alphanumeric string + * up to 4296 characters, or any digit string up to 7089 characters. + * These numbers represent the hard upper limit of the QR Code standard. + * - Please consult the QR Code specification for information on + * data capacities per version, ECC level, and text encoding mode. + */ +bool qrcodegen_encodeText(const char * text, + uint8_t tempBuffer[], + uint8_t qrcode[], + enum qrcodegen_Ecc ecl, + int minVersion, + int maxVersion, + enum qrcodegen_Mask mask, + bool boostEcl); + +/* + * Encodes the given binary data to a QR Code, returning true if encoding succeeded. + * If the data is too long to fit in any version in the given range + * at the given ECC level, then false is returned. + * - The input array range dataAndTemp[0 : dataLen] should normally be + * valid UTF-8 text, but is not required by the QR Code standard. + * - The variables ecl and mask must correspond to enum constant values. + * - Requires 1 <= minVersion <= maxVersion <= 40. + * - The arrays dataAndTemp and qrcode must each have a length + * of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion). + * - After the function returns, the contents of dataAndTemp may have changed, + * and does not represent useful data anymore. + * - If successful, the resulting QR Code will use byte mode to encode the data. + * - In the most optimistic case, a QR Code at version 40 with low ECC can hold any byte + * sequence up to length 2953. This is the hard upper limit of the QR Code standard. + * - Please consult the QR Code specification for information on + * data capacities per version, ECC level, and text encoding mode. + */ +bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], + size_t dataLen, + uint8_t qrcode[], + enum qrcodegen_Ecc ecl, + int minVersion, + int maxVersion, + enum qrcodegen_Mask mask, + bool boostEcl); + +/*---- Functions (low level) to generate QR Codes ----*/ + +/* + * Renders a QR Code representing the given segments at the given error correction level. + * The smallest possible QR Code version is automatically chosen for the output. Returns true if + * QR Code creation succeeded, or false if the data is too long to fit in any version. The ECC level + * of the result may be higher than the ecl argument if it can be done without increasing the version. + * This function allows the user to create a custom sequence of segments that switches + * between modes (such as alphanumeric and byte) to encode text in less space. + * This is a low-level API; the high-level API is qrcodegen_encodeText() and qrcodegen_encodeBinary(). + * To save memory, the segments' data buffers can alias/overlap tempBuffer, and will + * result in them being clobbered, but the QR Code output will still be correct. + * But the qrcode array must not overlap tempBuffer or any segment's data buffer. + */ +bool qrcodegen_encodeSegments(const struct qrcodegen_Segment segs[], + size_t len, + enum qrcodegen_Ecc ecl, + uint8_t tempBuffer[], + uint8_t qrcode[]); + +/* + * Renders a QR Code representing the given segments with the given encoding parameters. + * Returns true if QR Code creation succeeded, or false if the data is too long to fit in the range of versions. + * The smallest possible QR Code version within the given range is automatically + * chosen for the output. Iff boostEcl is true, then the ECC level of the result + * may be higher than the ecl argument if it can be done without increasing the + * version. The mask number is either between 0 to 7 (inclusive) to force that + * mask, or -1 to automatically choose an appropriate mask (which may be slow). + * This function allows the user to create a custom sequence of segments that switches + * between modes (such as alphanumeric and byte) to encode text in less space. + * This is a low-level API; the high-level API is qrcodegen_encodeText() and qrcodegen_encodeBinary(). + * To save memory, the segments' data buffers can alias/overlap tempBuffer, and will + * result in them being clobbered, but the QR Code output will still be correct. + * But the qrcode array must not overlap tempBuffer or any segment's data buffer. + */ +bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], + size_t len, + enum qrcodegen_Ecc ecl, + int minVersion, + int maxVersion, + int mask, + bool boostEcl, + uint8_t tempBuffer[], + uint8_t qrcode[]); + +/* + * Tests whether the given string can be encoded as a segment in alphanumeric mode. + * A string is encodable iff each character is in the following set: 0 to 9, A to Z + * (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon. + */ +bool qrcodegen_isAlphanumeric(const char *text); + +/* + * Tests whether the given string can be encoded as a segment in numeric mode. + * A string is encodable iff each character is in the range 0 to 9. + */ +bool qrcodegen_isNumeric(const char *text); + +/* + * Returns the number of bytes (uint8_t) needed for the data buffer of a segment + * containing the given number of characters using the given mode. Notes: + * - Returns SIZE_MAX on failure, i.e. numChars > INT16_MAX or + * the number of needed bits exceeds INT16_MAX (i.e. 32767). + * - Otherwise, all valid results are in the range [0, ceil(INT16_MAX / 8)], i.e. at most 4096. + * - It is okay for the user to allocate more bytes for the buffer than needed. + * - For byte mode, numChars measures the number of bytes, not Unicode code points. + * - For ECI mode, numChars must be 0, and the worst-case number of bytes is returned. + * An actual ECI segment can have shorter data. For non-ECI modes, the result is exact. + */ +size_t qrcodegen_calcSegmentBufferSize(enum qrcodegen_Mode mode, size_t numChars); + +/* + * Returns a segment representing the given binary data encoded in + * byte mode. All input byte arrays are acceptable. Any text string + * can be converted to UTF-8 bytes and encoded as a byte mode segment. + */ +struct qrcodegen_Segment qrcodegen_makeBytes(const uint8_t data[], size_t len, uint8_t buf[]); + +/* + * Returns a segment representing the given string of decimal digits encoded in numeric mode. + */ +struct qrcodegen_Segment qrcodegen_makeNumeric(const char *digits, uint8_t buf[]); + +/* + * Returns a segment representing the given text string encoded in alphanumeric mode. + * The characters allowed are: 0 to 9, A to Z (uppercase only), space, + * dollar, percent, asterisk, plus, hyphen, period, slash, colon. + */ +struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char *text, uint8_t buf[]); + +/* + * Returns a segment representing an Extended Channel Interpretation + * (ECI) designator with the given assignment value. + */ +struct qrcodegen_Segment qrcodegen_makeEci(long assignVal, uint8_t buf[]); + +/*---- Functions to extract raw data from QR Codes ----*/ + +/* + * Returns the side length of the given QR Code, assuming that encoding succeeded. + * The result is in the range [21, 177]. Note that the length of the array buffer + * is related to the side length - every 'uint8_t qrcode[]' must have length at least + * qrcodegen_BUFFER_LEN_FOR_VERSION(version), which equals ceil(size^2 / 8 + 1). + */ +int qrcodegen_getSize(const uint8_t qrcode[]); + +/* + * Returns the color of the module (pixel) at the given coordinates, which is false + * for white or true for black. The top left corner has the coordinates (x=0, y=0). + * If the given coordinates are out of bounds, then false (white) is returned. + */ +bool qrcodegen_getModule(const uint8_t qrcode[], int x, int y); + +#ifdef __cplusplus +} +#endif diff --git a/src/libnmc-setting/meson.build b/src/libnmc-setting/meson.build new file mode 100644 index 0000000..8f07ae6 --- /dev/null +++ b/src/libnmc-setting/meson.build @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +if enable_docs + settings_docs_input_xml = custom_target( + 'settings-docs-input.xml', + input: [nm_settings_docs_xml_gir, nm_property_infos_xml['nmcli']], + output: 'settings-docs-input.xml', + command: [ + python.path(), + join_paths(meson.source_root(), 'tools', 'generate-docs-nm-settings-docs-merge.py'), + '@OUTPUT@', + nm_property_infos_xml['nmcli'], + nm_settings_docs_xml_gir, + ], + ) + + settings_docs_source = custom_target( + 'settings-docs.h', + input: settings_docs_input_xml, + output: 'settings-docs.h', + command: [xsltproc, '--output', '@OUTPUT@', join_paths(meson.current_source_dir(), 'settings-docs.xsl'), '@INPUT@'], + ) + + test( + 'check-settings-docs', + find_program(join_paths(source_root, 'tools', 'check-compare-generated.sh')), + args: [ + source_root, + build_root, + 'src/libnmc-setting/settings-docs.h', + ], + ) +else + settings_docs_source = configure_file( + input: 'settings-docs.h.in', + output: '@BASENAME@', + configuration: configuration_data(), + ) +endif + +libnmc_setting = static_library( + 'nmc-setting', + sources: [settings_docs_source] + files( + 'nm-meta-setting-access.c', + 'nm-meta-setting-base-impl.c', + 'nm-meta-setting-desc.c', + ), + dependencies: [ + libnm_dep, + ], + link_depends: settings_docs_source, +) diff --git a/src/libnmc-setting/nm-meta-setting-access.c b/src/libnmc-setting/nm-meta-setting-access.c new file mode 100644 index 0000000..cd4cbdd --- /dev/null +++ b/src/libnmc-setting/nm-meta-setting-access.c @@ -0,0 +1,653 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2010 - 2017 Red Hat, Inc. + */ + +#include "libnm-client-aux-extern/nm-default-client.h" + +#include "nm-meta-setting-access.h" + +/*****************************************************************************/ + +static const NMMetaSettingInfoEditor * +_get_meta_setting_info_editor_from_msi(const NMMetaSettingInfo *meta_setting_info) +{ + const NMMetaSettingInfoEditor *setting_info; + + if (!meta_setting_info) + return NULL; + + nm_assert(meta_setting_info->get_setting_gtype); + nm_assert(meta_setting_info->meta_type < G_N_ELEMENTS(nm_meta_setting_infos_editor)); + + setting_info = &nm_meta_setting_infos_editor[meta_setting_info->meta_type]; + + nm_assert(setting_info->general == meta_setting_info); + return setting_info; +} + +const NMMetaSettingInfoEditor * +nm_meta_setting_info_editor_find_by_name(const char *setting_name, gboolean use_alias) +{ + const NMMetaSettingInfoEditor *setting_info; + guint i; + + g_return_val_if_fail(setting_name, NULL); + + setting_info = + _get_meta_setting_info_editor_from_msi(nm_meta_setting_infos_by_name(setting_name)); + if (!setting_info && use_alias) { + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + if (nm_streq0(nm_meta_setting_infos_editor[i].alias, setting_name)) { + setting_info = &nm_meta_setting_infos_editor[i]; + break; + } + } + } + + return setting_info; +} + +const NMMetaSettingInfoEditor * +nm_meta_setting_info_editor_find_by_gtype(GType gtype) +{ + return _get_meta_setting_info_editor_from_msi(nm_meta_setting_infos_by_gtype(gtype)); +} + +const NMMetaSettingInfoEditor * +nm_meta_setting_info_editor_find_by_setting(NMSetting *setting) +{ + const NMMetaSettingInfoEditor *setting_info; + + g_return_val_if_fail(NM_IS_SETTING(setting), NULL); + + setting_info = nm_meta_setting_info_editor_find_by_gtype(G_OBJECT_TYPE(setting)); + + nm_assert(setting_info); + nm_assert(G_TYPE_CHECK_INSTANCE_TYPE(setting, setting_info->general->get_setting_gtype())); + return setting_info; +} + +/*****************************************************************************/ + +const NMMetaPropertyInfo * +nm_meta_setting_info_editor_get_property_info(const NMMetaSettingInfoEditor *setting_info, + const char * property_name) +{ + guint i; + + g_return_val_if_fail(setting_info, NULL); + g_return_val_if_fail(property_name, NULL); + + for (i = 0; i < setting_info->properties_num; i++) { + nm_assert(setting_info->properties[i]->property_name); + nm_assert(setting_info->properties[i]->setting_info == setting_info); + if (nm_streq(setting_info->properties[i]->property_name, property_name)) + return setting_info->properties[i]; + } + + return NULL; +} + +gboolean +nm_meta_setting_info_editor_has_secrets(const NMMetaSettingInfoEditor *setting_info) +{ + guint i; + + if (!setting_info) + return FALSE; + + for (i = 0; i < setting_info->properties_num; i++) { + if (setting_info->properties[i]->is_secret) + return TRUE; + } + + return FALSE; +} + +const NMMetaPropertyInfo * +nm_meta_property_info_find_by_name(const char *setting_name, const char *property_name) +{ + const NMMetaSettingInfoEditor *setting_info; + const NMMetaPropertyInfo * property_info; + + setting_info = nm_meta_setting_info_editor_find_by_name(setting_name, FALSE); + if (!setting_info) + return NULL; + + property_info = nm_meta_setting_info_editor_get_property_info(setting_info, property_name); + if (!property_info) + return NULL; + + nm_assert(property_info->setting_info == setting_info); + + return property_info; +} + +const NMMetaPropertyInfo * +nm_meta_property_info_find_by_setting(NMSetting *setting, const char *property_name) +{ + const NMMetaSettingInfoEditor *setting_info; + const NMMetaPropertyInfo * property_info; + + setting_info = nm_meta_setting_info_editor_find_by_setting(setting); + if (!setting_info) + return NULL; + property_info = nm_meta_setting_info_editor_get_property_info(setting_info, property_name); + if (!property_info) + return NULL; + + nm_assert(property_info->setting_info == setting_info); + nm_assert(property_info + == nm_meta_property_info_find_by_name(nm_setting_get_name(setting), property_name)); + + return property_info; +} + +NMSetting * +nm_meta_setting_info_editor_new_setting(const NMMetaSettingInfoEditor *setting_info, + NMMetaAccessorSettingInitType init_type) +{ + NMSetting *setting; + + g_return_val_if_fail(setting_info, NULL); + + setting = g_object_new(setting_info->general->get_setting_gtype(), NULL); + + if (setting_info->setting_init_fcn && init_type != NM_META_ACCESSOR_SETTING_INIT_TYPE_DEFAULT) { + setting_info->setting_init_fcn(setting_info, setting, init_type); + } + + return setting; +} + +/*****************************************************************************/ + +const NMMetaSettingInfoEditor *const * +nm_meta_setting_infos_editor_p(void) +{ + static const NMMetaSettingInfoEditor *cache[_NM_META_SETTING_TYPE_NUM + 1] = {NULL}; + guint i; + + if (G_UNLIKELY(!cache[0])) { + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) + cache[i] = &nm_meta_setting_infos_editor[i]; + } + return cache; +} + +/*****************************************************************************/ + +const char * +nm_meta_abstract_info_get_name(const NMMetaAbstractInfo *abstract_info, gboolean for_header) +{ + const char *n; + + nm_assert(abstract_info); + nm_assert(abstract_info->meta_type); + nm_assert(abstract_info->meta_type->get_name); + n = abstract_info->meta_type->get_name(abstract_info, for_header); + nm_assert(n && n[0]); + return n; +} + +const NMMetaAbstractInfo *const * +nm_meta_abstract_info_get_nested(const NMMetaAbstractInfo *abstract_info, + guint * out_len, + gpointer * nested_to_free) +{ + const NMMetaAbstractInfo *const *nested; + guint l = 0; + gs_free gpointer f = NULL; + + nm_assert(abstract_info); + nm_assert(abstract_info->meta_type); + nm_assert(nested_to_free && !*nested_to_free); + + if (abstract_info->meta_type->get_nested) { + nested = abstract_info->meta_type->get_nested(abstract_info, &l, &f); + nm_assert(NM_PTRARRAY_LEN(nested) == l); + nm_assert(!f || nested == f); + if (nested && nested[0]) { + NM_SET_OUT(out_len, l); + *nested_to_free = g_steal_pointer(&f); + return nested; + } + } + NM_SET_OUT(out_len, 0); + return NULL; +} + +gconstpointer +nm_meta_abstract_info_get(const NMMetaAbstractInfo * abstract_info, + const NMMetaEnvironment * environment, + gpointer environment_user_data, + gpointer target, + gpointer target_data, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, + gboolean * out_is_default, + gpointer * out_to_free) +{ + nm_assert(abstract_info); + nm_assert(abstract_info->meta_type); + nm_assert(!out_to_free || !*out_to_free); + nm_assert(out_flags); + + *out_flags = NM_META_ACCESSOR_GET_OUT_FLAGS_NONE; + NM_SET_OUT(out_is_default, FALSE); + + if (!abstract_info->meta_type->get_fcn) + g_return_val_if_reached(NULL); + + return abstract_info->meta_type->get_fcn(abstract_info, + environment, + environment_user_data, + target, + target_data, + get_type, + get_flags, + out_flags, + out_is_default, + out_to_free); +} + +const char *const * +nm_meta_abstract_info_complete(const NMMetaAbstractInfo * abstract_info, + const NMMetaEnvironment * environment, + gpointer environment_user_data, + const NMMetaOperationContext *operation_context, + const char * text, + gboolean * out_complete_filename, + char *** out_to_free) +{ + const char *const *values; + gsize i, j, text_len; + + nm_assert(abstract_info); + nm_assert(abstract_info->meta_type); + nm_assert(out_to_free && !*out_to_free); + + *out_to_free = NULL; + + if (!abstract_info->meta_type->complete_fcn) + return NULL; + + values = abstract_info->meta_type->complete_fcn(abstract_info, + environment, + environment_user_data, + operation_context, + text, + out_complete_filename, + out_to_free); + + nm_assert(!*out_to_free || values == (const char *const *) *out_to_free); + + if (!values) + return NULL; + + if (!values[0]) { + nm_clear_g_free(out_to_free); + return NULL; + } + + if (!text || !text[0]) + return values; + + /* for convenience, we allow the complete_fcn() implementations to + * ignore "text". We filter out invalid matches here. */ + + text_len = strlen(text); + + if (*out_to_free) { + char **v = *out_to_free; + + for (i = 0, j = 0; v[i]; i++) { + if (strncmp(v[i], text, text_len) != 0) { + g_free(v[i]); + continue; + } + v[j++] = v[i]; + } + if (j) + v[j++] = NULL; + else { + g_free(v); + *out_to_free = v = NULL; + } + return (const char *const *) v; + } else { + const char *const *v = values; + char ** r; + + for (i = 0, j = 0; v[i]; i++) { + if (strncmp(v[i], text, text_len) != 0) + continue; + j++; + } + if (j == i) + return values; + else if (!j) + return NULL; + + r = g_new(char *, j + 1); + v = values; + for (i = 0, j = 0; v[i]; i++) { + if (strncmp(v[i], text, text_len) != 0) + continue; + r[j++] = g_strdup(v[i]); + } + r[j++] = NULL; + return (const char *const *) (*out_to_free = r); + } +} + +/*****************************************************************************/ + +char * +nm_meta_abstract_info_get_nested_names_str(const NMMetaAbstractInfo *abstract_info, + const char * name_prefix) +{ + gs_free gpointer nested_to_free = NULL; + const NMMetaAbstractInfo *const *nested; + + nested = nm_meta_abstract_info_get_nested(abstract_info, NULL, &nested_to_free); + if (!nested) + return NULL; + + if (!name_prefix) + name_prefix = nm_meta_abstract_info_get_name(abstract_info, FALSE); + + return nm_meta_abstract_infos_get_names_str(nested, name_prefix); +} + +char * +nm_meta_abstract_infos_get_names_str(const NMMetaAbstractInfo *const *fields_array, + const char * name_prefix) +{ + GString *str; + guint i; + + if (!fields_array || !fields_array[0]) + return NULL; + + str = g_string_sized_new(128); + for (i = 0; fields_array[i]; i++) { + if (str->len > 0) + g_string_append_c(str, ','); + if (name_prefix) { + g_string_append(str, name_prefix); + g_string_append_c(str, '.'); + } + g_string_append(str, nm_meta_abstract_info_get_name(fields_array[i], FALSE)); + } + return g_string_free(str, FALSE); +} + +/*****************************************************************************/ + +typedef struct { + guint idx; + gsize self_offset_plus_1; + gsize sub_offset_plus_1; +} OutputSelectionItem; + +static NMMetaSelectionResultList * +_output_selection_pack(const NMMetaAbstractInfo *const *fields_array, GArray *array, GString *str) +{ + NMMetaSelectionResultList *result; + guint i; + guint len; + + len = array ? array->len : 0; + + /* re-organize the collected output data in one buffer that can be freed using + * g_free(). This makes allocation more complicated, but saves us from special + * handling for free. */ + result = g_malloc0(sizeof(NMMetaSelectionResultList) + (len * sizeof(NMMetaSelectionItem)) + + (str ? str->len : 0)); + *((guint *) &result->num) = len; + if (len > 0) { + char *pdata = + &((char *) + result)[sizeof(NMMetaSelectionResultList) + (len * sizeof(NMMetaSelectionItem))]; + + if (str) + memcpy(pdata, str->str, str->len); + for (i = 0; i < len; i++) { + const OutputSelectionItem *a = &g_array_index(array, OutputSelectionItem, i); + NMMetaSelectionItem * p = (NMMetaSelectionItem *) &result->items[i]; + + p->info = fields_array[a->idx]; + p->idx = a->idx; + if (a->self_offset_plus_1 > 0) + p->self_selection = &pdata[a->self_offset_plus_1 - 1]; + if (a->sub_offset_plus_1 > 0) + p->sub_selection = &pdata[a->sub_offset_plus_1 - 1]; + } + } + + return result; +} + +static gboolean +_output_selection_select_one(const NMMetaAbstractInfo *const *fields_array, + const char * fields_prefix, + const char * fields_str, + gboolean validate_nested, + GArray ** p_array, + GString ** p_str, + GError ** error) +{ + guint i, j; + const char * i_name; + const char * right; + gboolean found = FALSE; + const NMMetaAbstractInfo *fields_array_failure = NULL; + gs_free char * fields_str_clone = NULL; + + nm_assert(fields_str); + nm_assert(p_array); + nm_assert(p_str); + nm_assert(!error || !*error); + + right = strchr(fields_str, '.'); + if (right) { + fields_str_clone = g_strdup(fields_str); + fields_str_clone[right - fields_str] = '\0'; + i_name = fields_str_clone; + right = &fields_str_clone[right - fields_str + 1]; + } else + i_name = fields_str; + + if (!fields_array) + goto not_found; + + for (i = 0; fields_array[i]; i++) { + const NMMetaAbstractInfo * fi = fields_array[i]; + const NMMetaAbstractInfo *const *nested; + gs_free gpointer nested_to_free = NULL; + + if (g_ascii_strcasecmp(i_name, nm_meta_abstract_info_get_name(fi, FALSE)) != 0) + continue; + + if (!right || !validate_nested) { + found = TRUE; + break; + } + + nested = nm_meta_abstract_info_get_nested(fi, NULL, &nested_to_free); + if (nested) { + for (j = 0; nested[j]; nested++) { + if (g_ascii_strcasecmp(right, nm_meta_abstract_info_get_name(nested[j], FALSE)) + == 0) { + found = TRUE; + break; + } + } + } + fields_array_failure = fields_array[i]; + break; + } + + if (!found) { +not_found: + if (!right && !fields_prefix + && (!g_ascii_strcasecmp(i_name, "all") || !g_ascii_strcasecmp(i_name, "common"))) + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("field '%s' has to be alone"), + i_name); + else { + gs_free char *allowed_fields = NULL; + + if (fields_array_failure) { + gs_free char *p = NULL; + + if (fields_prefix) { + p = g_strdup_printf( + "%s.%s", + fields_prefix, + nm_meta_abstract_info_get_name(fields_array_failure, FALSE)); + } + allowed_fields = + nm_meta_abstract_info_get_nested_names_str(fields_array_failure, p); + } else + allowed_fields = nm_meta_abstract_infos_get_names_str(fields_array, NULL); + + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + _("invalid field '%s%s%s%s%s'; %s%s%s"), + fields_prefix ?: "", + fields_prefix ? "." : "", + i_name, + right ? "." : "", + right ?: "", + NM_PRINT_FMT_QUOTED(allowed_fields, + "allowed fields: ", + allowed_fields, + "", + "no fields")); + } + return FALSE; + } + + { + GString * str; + OutputSelectionItem s = { + .idx = i, + }; + + if (!*p_str) + *p_str = g_string_sized_new(64); + str = *p_str; + + s.self_offset_plus_1 = str->len + 1; + if (fields_prefix) { + g_string_append(str, fields_prefix); + g_string_append_c(str, '.'); + } + g_string_append_len(str, i_name, strlen(i_name) + 1); + + if (right) { + s.sub_offset_plus_1 = str->len + 1; + g_string_append_len(str, right, strlen(right) + 1); + } + + if (!*p_array) + *p_array = g_array_new(FALSE, FALSE, sizeof(OutputSelectionItem)); + g_array_append_val(*p_array, s); + } + + return TRUE; +} + +NMMetaSelectionResultList * +nm_meta_selection_create_all(const NMMetaAbstractInfo *const *fields_array) +{ + gs_unref_array GArray *array = NULL; + guint i; + + if (fields_array) { + array = g_array_new(FALSE, FALSE, sizeof(OutputSelectionItem)); + for (i = 0; fields_array[i]; i++) { + OutputSelectionItem s = { + .idx = i, + }; + + g_array_append_val(array, s); + } + } + + return _output_selection_pack(fields_array, array, NULL); +} + +NMMetaSelectionResultList * +nm_meta_selection_create_parse_one( + const NMMetaAbstractInfo *const *fields_array, + const char * fields_prefix, + const char * + fields_str, /* one field selector (contains no commas) and is already stripped of spaces. */ + gboolean validate_nested, + GError **error) +{ + gs_unref_array GArray *array = NULL; + nm_auto_free_gstring GString *str = NULL; + + g_return_val_if_fail(!error || !*error, NULL); + nm_assert(fields_str && !strchr(fields_str, ',')); + + if (!_output_selection_select_one(fields_array, + fields_prefix, + fields_str, + validate_nested, + &array, + &str, + error)) + return NULL; + return _output_selection_pack(fields_array, array, str); +} + +NMMetaSelectionResultList * +nm_meta_selection_create_parse_list( + const NMMetaAbstractInfo *const *fields_array, + const char * fields_str, /* a comma separated list of selectors */ + gboolean validate_nested, + GError ** error) +{ + gs_unref_array GArray *array = NULL; + nm_auto_free_gstring GString *str = NULL; + gs_free char * fields_str_clone = NULL; + char * fields_str_cur; + char * fields_str_next; + + g_return_val_if_fail(!error || !*error, NULL); + + if (!fields_str) + return nm_meta_selection_create_all(fields_array); + + fields_str_clone = g_strdup(fields_str); + for (fields_str_cur = fields_str_clone; fields_str_cur; fields_str_cur = fields_str_next) { + fields_str_cur = nm_str_skip_leading_spaces(fields_str_cur); + fields_str_next = strchr(fields_str_cur, ','); + if (fields_str_next) + *fields_str_next++ = '\0'; + + g_strchomp(fields_str_cur); + if (!fields_str_cur[0]) + continue; + if (!_output_selection_select_one(fields_array, + NULL, + fields_str_cur, + validate_nested, + &array, + &str, + error)) + return NULL; + } + + return _output_selection_pack(fields_array, array, str); +} diff --git a/src/libnmc-setting/nm-meta-setting-access.h b/src/libnmc-setting/nm-meta-setting-access.h new file mode 100644 index 0000000..81aa3b6 --- /dev/null +++ b/src/libnmc-setting/nm-meta-setting-access.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2010 - 2017 Red Hat, Inc. + */ + +#ifndef _NM_META_SETTING_ACCESS_H__ +#define _NM_META_SETTING_ACCESS_H__ + +#include "nm-meta-setting-desc.h" + +/*****************************************************************************/ + +NMSetting *nm_meta_setting_info_editor_new_setting(const NMMetaSettingInfoEditor *setting_info, + NMMetaAccessorSettingInitType init_type); + +const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_name(const char *setting_name, + gboolean use_alias); +const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_gtype(GType gtype); +const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_setting(NMSetting *setting); + +const NMMetaPropertyInfo * +nm_meta_setting_info_editor_get_property_info(const NMMetaSettingInfoEditor *setting_info, + const char * property_name); +const NMMetaPropertyInfo *nm_meta_property_info_find_by_name(const char *setting_name, + const char *property_name); +const NMMetaPropertyInfo *nm_meta_property_info_find_by_setting(NMSetting * setting, + const char *property_name); + +gboolean nm_meta_setting_info_editor_has_secrets(const NMMetaSettingInfoEditor *setting_info); + +/*****************************************************************************/ + +const NMMetaSettingInfoEditor *const *nm_meta_setting_infos_editor_p(void); + +/*****************************************************************************/ + +const char *nm_meta_abstract_info_get_name(const NMMetaAbstractInfo *abstract_info, + gboolean for_header); + +const NMMetaAbstractInfo *const * +nm_meta_abstract_info_get_nested(const NMMetaAbstractInfo *abstract_info, + guint * out_len, + gpointer * nested_to_free); + +gconstpointer nm_meta_abstract_info_get(const NMMetaAbstractInfo * abstract_info, + const NMMetaEnvironment * environment, + gpointer environment_user_data, + gpointer target, + gpointer target_data, + NMMetaAccessorGetType get_type, + NMMetaAccessorGetFlags get_flags, + NMMetaAccessorGetOutFlags *out_flags, + gboolean * out_is_default, + gpointer * out_to_free); + +const char *const *nm_meta_abstract_info_complete(const NMMetaAbstractInfo *abstract_info, + const NMMetaEnvironment * environment, + gpointer environment_user_data, + const NMMetaOperationContext *operation_context, + const char * text, + gboolean *out_complete_filename, + char *** out_to_free); + +/*****************************************************************************/ + +char *nm_meta_abstract_info_get_nested_names_str(const NMMetaAbstractInfo *abstract_info, + const char * name_prefix); +char *nm_meta_abstract_infos_get_names_str(const NMMetaAbstractInfo *const *fields_array, + const char * name_prefix); + +/*****************************************************************************/ + +typedef struct { + const NMMetaAbstractInfo *info; + const char * self_selection; + const char * sub_selection; + guint idx; +} NMMetaSelectionItem; + +typedef struct { + const guint num; + const NMMetaSelectionItem items[]; +} NMMetaSelectionResultList; + +NMMetaSelectionResultList * +nm_meta_selection_create_all(const NMMetaAbstractInfo *const *fields_array); +NMMetaSelectionResultList * +nm_meta_selection_create_parse_one(const NMMetaAbstractInfo *const *fields_array, + const char * fields_prefix, + const char * fields_str, + gboolean validate_nested, + GError ** error); +NMMetaSelectionResultList * +nm_meta_selection_create_parse_list(const NMMetaAbstractInfo *const *fields_array, + const char * fields_str, + gboolean validate_nested, + GError ** error); + +#endif /* _NM_META_SETTING_ACCESS_H__ */ diff --git a/src/libnmc-setting/nm-meta-setting-base-impl.c b/src/libnmc-setting/nm-meta-setting-base-impl.c new file mode 100644 index 0000000..da85e56 --- /dev/null +++ b/src/libnmc-setting/nm-meta-setting-base-impl.c @@ -0,0 +1,641 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 - 2018 Red Hat, Inc. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-meta-setting-base.h" + +#include "nm-setting-6lowpan.h" +#include "nm-setting-8021x.h" +#include "nm-setting-adsl.h" +#include "nm-setting-bluetooth.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-bridge.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-dcb.h" +#include "nm-setting-dummy.h" +#include "nm-setting-ethtool.h" +#include "nm-setting-generic.h" +#include "nm-setting-gsm.h" +#include "nm-setting-hostname.h" +#include "nm-setting-infiniband.h" +#include "nm-setting-ip-config.h" +#include "nm-setting-ip-tunnel.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" +#include "nm-setting-macsec.h" +#include "nm-setting-macvlan.h" +#include "nm-setting-match.h" +#include "nm-setting-olpc-mesh.h" +#include "nm-setting-ovs-bridge.h" +#include "nm-setting-ovs-interface.h" +#include "nm-setting-ovs-dpdk.h" +#include "nm-setting-ovs-external-ids.h" +#include "nm-setting-ovs-patch.h" +#include "nm-setting-ovs-port.h" +#include "nm-setting-ppp.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-proxy.h" +#include "nm-setting-serial.h" +#include "nm-setting-tc-config.h" +#include "nm-setting-team-port.h" +#include "nm-setting-team.h" +#include "nm-setting-tun.h" +#include "nm-setting-user.h" +#include "nm-setting-veth.h" +#include "nm-setting-vlan.h" +#include "nm-setting-vpn.h" +#include "nm-setting-vrf.h" +#include "nm-setting-vxlan.h" +#include "nm-setting-wifi-p2p.h" +#include "nm-setting-wimax.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireguard.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wpan.h" + +/*****************************************************************************/ + +const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = { + +#define _D(_scheme_type, ...) [(_scheme_type)] = {.scheme_type = (_scheme_type), __VA_ARGS__} + + _D(NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT, + .setting_key = NM_SETTING_802_1X_CA_CERT, + .scheme_func = nm_setting_802_1x_get_ca_cert_scheme, + .format_func = NULL, + .path_func = nm_setting_802_1x_get_ca_cert_path, + .blob_func = nm_setting_802_1x_get_ca_cert_blob, + .uri_func = nm_setting_802_1x_get_ca_cert_uri, + .passwd_func = nm_setting_802_1x_get_ca_cert_password, + .pwflag_func = nm_setting_802_1x_get_ca_cert_password_flags, + .set_cert_func = nm_setting_802_1x_set_ca_cert, + .file_suffix = "ca-cert", ), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT, + .setting_key = NM_SETTING_802_1X_PHASE2_CA_CERT, + .scheme_func = nm_setting_802_1x_get_phase2_ca_cert_scheme, + .format_func = NULL, + .path_func = nm_setting_802_1x_get_phase2_ca_cert_path, + .blob_func = nm_setting_802_1x_get_phase2_ca_cert_blob, + .uri_func = nm_setting_802_1x_get_phase2_ca_cert_uri, + .passwd_func = nm_setting_802_1x_get_phase2_ca_cert_password, + .pwflag_func = nm_setting_802_1x_get_phase2_ca_cert_password_flags, + .set_cert_func = nm_setting_802_1x_set_phase2_ca_cert, + .file_suffix = "inner-ca-cert", ), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT, + .setting_key = NM_SETTING_802_1X_CLIENT_CERT, + .scheme_func = nm_setting_802_1x_get_client_cert_scheme, + .format_func = NULL, + .path_func = nm_setting_802_1x_get_client_cert_path, + .blob_func = nm_setting_802_1x_get_client_cert_blob, + .uri_func = nm_setting_802_1x_get_client_cert_uri, + .passwd_func = nm_setting_802_1x_get_client_cert_password, + .pwflag_func = nm_setting_802_1x_get_client_cert_password_flags, + .set_cert_func = nm_setting_802_1x_set_client_cert, + .file_suffix = "client-cert", ), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT, + .setting_key = NM_SETTING_802_1X_PHASE2_CLIENT_CERT, + .scheme_func = nm_setting_802_1x_get_phase2_client_cert_scheme, + .format_func = NULL, + .path_func = nm_setting_802_1x_get_phase2_client_cert_path, + .blob_func = nm_setting_802_1x_get_phase2_client_cert_blob, + .uri_func = nm_setting_802_1x_get_phase2_client_cert_uri, + .passwd_func = nm_setting_802_1x_get_phase2_client_cert_password, + .pwflag_func = nm_setting_802_1x_get_phase2_client_cert_password_flags, + .set_cert_func = nm_setting_802_1x_set_phase2_client_cert, + .file_suffix = "inner-client-cert", ), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY, + .setting_key = NM_SETTING_802_1X_PRIVATE_KEY, + .scheme_func = nm_setting_802_1x_get_private_key_scheme, + .format_func = nm_setting_802_1x_get_private_key_format, + .path_func = nm_setting_802_1x_get_private_key_path, + .blob_func = nm_setting_802_1x_get_private_key_blob, + .uri_func = nm_setting_802_1x_get_private_key_uri, + .passwd_func = nm_setting_802_1x_get_private_key_password, + .pwflag_func = nm_setting_802_1x_get_private_key_password_flags, + .set_private_key_func = nm_setting_802_1x_set_private_key, + .file_suffix = "private-key", + .is_secret = TRUE, ), + + _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY, + .setting_key = NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, + .scheme_func = nm_setting_802_1x_get_phase2_private_key_scheme, + .format_func = nm_setting_802_1x_get_phase2_private_key_format, + .path_func = nm_setting_802_1x_get_phase2_private_key_path, + .blob_func = nm_setting_802_1x_get_phase2_private_key_blob, + .uri_func = nm_setting_802_1x_get_phase2_private_key_uri, + .passwd_func = nm_setting_802_1x_get_phase2_private_key_password, + .pwflag_func = nm_setting_802_1x_get_phase2_private_key_password_flags, + .set_private_key_func = nm_setting_802_1x_set_phase2_private_key, + .file_suffix = "inner-private-key", + .is_secret = TRUE, ), + +#undef _D +}; + +/*****************************************************************************/ + +const NMMetaSettingInfo nm_meta_setting_infos[] = { + [NM_META_SETTING_TYPE_6LOWPAN] = + { + .meta_type = NM_META_SETTING_TYPE_6LOWPAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_6LOWPAN_SETTING_NAME, + .get_setting_gtype = nm_setting_6lowpan_get_type, + }, + [NM_META_SETTING_TYPE_802_1X] = + { + .meta_type = NM_META_SETTING_TYPE_802_1X, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, + .setting_name = NM_SETTING_802_1X_SETTING_NAME, + .get_setting_gtype = nm_setting_802_1x_get_type, + }, + [NM_META_SETTING_TYPE_ADSL] = + { + .meta_type = NM_META_SETTING_TYPE_ADSL, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_ADSL_SETTING_NAME, + .get_setting_gtype = nm_setting_adsl_get_type, + }, + [NM_META_SETTING_TYPE_BLUETOOTH] = + { + .meta_type = NM_META_SETTING_TYPE_BLUETOOTH, + .setting_priority = NM_SETTING_PRIORITY_HW_NON_BASE, + .setting_name = NM_SETTING_BLUETOOTH_SETTING_NAME, + .get_setting_gtype = nm_setting_bluetooth_get_type, + }, + [NM_META_SETTING_TYPE_BOND] = + { + .meta_type = NM_META_SETTING_TYPE_BOND, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_BOND_SETTING_NAME, + .get_setting_gtype = nm_setting_bond_get_type, + }, + [NM_META_SETTING_TYPE_BRIDGE] = + { + .meta_type = NM_META_SETTING_TYPE_BRIDGE, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_BRIDGE_SETTING_NAME, + .get_setting_gtype = nm_setting_bridge_get_type, + }, + [NM_META_SETTING_TYPE_BRIDGE_PORT] = + { + .meta_type = NM_META_SETTING_TYPE_BRIDGE_PORT, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_BRIDGE_PORT_SETTING_NAME, + .get_setting_gtype = nm_setting_bridge_port_get_type, + }, + [NM_META_SETTING_TYPE_CDMA] = + { + .meta_type = NM_META_SETTING_TYPE_CDMA, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_CDMA_SETTING_NAME, + .get_setting_gtype = nm_setting_cdma_get_type, + }, + [NM_META_SETTING_TYPE_CONNECTION] = + { + .meta_type = NM_META_SETTING_TYPE_CONNECTION, + .setting_priority = NM_SETTING_PRIORITY_CONNECTION, + .setting_name = NM_SETTING_CONNECTION_SETTING_NAME, + .get_setting_gtype = nm_setting_connection_get_type, + }, + [NM_META_SETTING_TYPE_DCB] = + { + .meta_type = NM_META_SETTING_TYPE_DCB, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, + .setting_name = NM_SETTING_DCB_SETTING_NAME, + .get_setting_gtype = nm_setting_dcb_get_type, + }, + [NM_META_SETTING_TYPE_DUMMY] = + { + .meta_type = NM_META_SETTING_TYPE_DUMMY, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_DUMMY_SETTING_NAME, + .get_setting_gtype = nm_setting_dummy_get_type, + }, + [NM_META_SETTING_TYPE_ETHTOOL] = + { + .meta_type = NM_META_SETTING_TYPE_ETHTOOL, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_ETHTOOL_SETTING_NAME, + .get_setting_gtype = nm_setting_ethtool_get_type, + }, + [NM_META_SETTING_TYPE_GENERIC] = + { + .meta_type = NM_META_SETTING_TYPE_GENERIC, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_GENERIC_SETTING_NAME, + .get_setting_gtype = nm_setting_generic_get_type, + }, + [NM_META_SETTING_TYPE_GSM] = + { + .meta_type = NM_META_SETTING_TYPE_GSM, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_GSM_SETTING_NAME, + .get_setting_gtype = nm_setting_gsm_get_type, + }, + [NM_META_SETTING_TYPE_HOSTNAME] = + { + .meta_type = NM_META_SETTING_TYPE_HOSTNAME, + .setting_priority = NM_SETTING_PRIORITY_IP, + .setting_name = NM_SETTING_HOSTNAME_SETTING_NAME, + .get_setting_gtype = nm_setting_hostname_get_type, + }, + [NM_META_SETTING_TYPE_INFINIBAND] = + { + .meta_type = NM_META_SETTING_TYPE_INFINIBAND, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_INFINIBAND_SETTING_NAME, + .get_setting_gtype = nm_setting_infiniband_get_type, + }, + [NM_META_SETTING_TYPE_IP4_CONFIG] = + { + .meta_type = NM_META_SETTING_TYPE_IP4_CONFIG, + .setting_priority = NM_SETTING_PRIORITY_IP, + .setting_name = NM_SETTING_IP4_CONFIG_SETTING_NAME, + .get_setting_gtype = nm_setting_ip4_config_get_type, + }, + [NM_META_SETTING_TYPE_IP6_CONFIG] = + { + .meta_type = NM_META_SETTING_TYPE_IP6_CONFIG, + .setting_priority = NM_SETTING_PRIORITY_IP, + .setting_name = NM_SETTING_IP6_CONFIG_SETTING_NAME, + .get_setting_gtype = nm_setting_ip6_config_get_type, + }, + [NM_META_SETTING_TYPE_IP_TUNNEL] = + { + .meta_type = NM_META_SETTING_TYPE_IP_TUNNEL, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_IP_TUNNEL_SETTING_NAME, + .get_setting_gtype = nm_setting_ip_tunnel_get_type, + }, + [NM_META_SETTING_TYPE_MACSEC] = + { + .meta_type = NM_META_SETTING_TYPE_MACSEC, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_MACSEC_SETTING_NAME, + .get_setting_gtype = nm_setting_macsec_get_type, + }, + [NM_META_SETTING_TYPE_MACVLAN] = + { + .meta_type = NM_META_SETTING_TYPE_MACVLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_MACVLAN_SETTING_NAME, + .get_setting_gtype = nm_setting_macvlan_get_type, + }, + [NM_META_SETTING_TYPE_MATCH] = + { + .meta_type = NM_META_SETTING_TYPE_MATCH, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_MATCH_SETTING_NAME, + .get_setting_gtype = nm_setting_match_get_type, + }, + [NM_META_SETTING_TYPE_OLPC_MESH] = + { + .meta_type = NM_META_SETTING_TYPE_OLPC_MESH, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OLPC_MESH_SETTING_NAME, + .get_setting_gtype = nm_setting_olpc_mesh_get_type, + }, + [NM_META_SETTING_TYPE_OVS_BRIDGE] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_BRIDGE, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OVS_BRIDGE_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_bridge_get_type, + }, + [NM_META_SETTING_TYPE_OVS_DPDK] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_DPDK, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OVS_DPDK_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_dpdk_get_type, + }, + [NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_external_ids_get_type, + }, + [NM_META_SETTING_TYPE_OVS_INTERFACE] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_INTERFACE, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OVS_INTERFACE_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_interface_get_type, + }, + [NM_META_SETTING_TYPE_OVS_PATCH] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_PATCH, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OVS_PATCH_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_patch_get_type, + }, + [NM_META_SETTING_TYPE_OVS_PORT] = + { + .meta_type = NM_META_SETTING_TYPE_OVS_PORT, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_OVS_PORT_SETTING_NAME, + .get_setting_gtype = nm_setting_ovs_port_get_type, + }, + [NM_META_SETTING_TYPE_PPPOE] = + { + .meta_type = NM_META_SETTING_TYPE_PPPOE, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_PPPOE_SETTING_NAME, + .get_setting_gtype = nm_setting_pppoe_get_type, + }, + [NM_META_SETTING_TYPE_PPP] = + { + .meta_type = NM_META_SETTING_TYPE_PPP, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_PPP_SETTING_NAME, + .get_setting_gtype = nm_setting_ppp_get_type, + }, + [NM_META_SETTING_TYPE_PROXY] = + { + .meta_type = NM_META_SETTING_TYPE_PROXY, + .setting_priority = NM_SETTING_PRIORITY_IP, + .setting_name = NM_SETTING_PROXY_SETTING_NAME, + .get_setting_gtype = nm_setting_proxy_get_type, + }, + [NM_META_SETTING_TYPE_SERIAL] = + { + .meta_type = NM_META_SETTING_TYPE_SERIAL, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, + .setting_name = NM_SETTING_SERIAL_SETTING_NAME, + .get_setting_gtype = nm_setting_serial_get_type, + }, + [NM_META_SETTING_TYPE_SRIOV] = + { + .meta_type = NM_META_SETTING_TYPE_SRIOV, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, + .setting_name = NM_SETTING_SRIOV_SETTING_NAME, + .get_setting_gtype = nm_setting_sriov_get_type, + }, + [NM_META_SETTING_TYPE_TC_CONFIG] = + { + .meta_type = NM_META_SETTING_TYPE_TC_CONFIG, + .setting_priority = NM_SETTING_PRIORITY_IP, + .setting_name = NM_SETTING_TC_CONFIG_SETTING_NAME, + .get_setting_gtype = nm_setting_tc_config_get_type, + }, + [NM_META_SETTING_TYPE_TEAM] = + { + .meta_type = NM_META_SETTING_TYPE_TEAM, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_TEAM_SETTING_NAME, + .get_setting_gtype = nm_setting_team_get_type, + }, + [NM_META_SETTING_TYPE_TEAM_PORT] = + { + .meta_type = NM_META_SETTING_TYPE_TEAM_PORT, + .setting_priority = NM_SETTING_PRIORITY_AUX, + .setting_name = NM_SETTING_TEAM_PORT_SETTING_NAME, + .get_setting_gtype = nm_setting_team_port_get_type, + }, + [NM_META_SETTING_TYPE_TUN] = + { + .meta_type = NM_META_SETTING_TYPE_TUN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_TUN_SETTING_NAME, + .get_setting_gtype = nm_setting_tun_get_type, + }, + [NM_META_SETTING_TYPE_USER] = + { + .meta_type = NM_META_SETTING_TYPE_USER, + .setting_priority = NM_SETTING_PRIORITY_USER, + .setting_name = NM_SETTING_USER_SETTING_NAME, + .get_setting_gtype = nm_setting_user_get_type, + }, + [NM_META_SETTING_TYPE_VETH] = + { + .meta_type = NM_META_SETTING_TYPE_VETH, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VETH_SETTING_NAME, + .get_setting_gtype = nm_setting_veth_get_type, + }, + [NM_META_SETTING_TYPE_VLAN] = + { + .meta_type = NM_META_SETTING_TYPE_VLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VLAN_SETTING_NAME, + .get_setting_gtype = nm_setting_vlan_get_type, + }, + [NM_META_SETTING_TYPE_VPN] = + { + .meta_type = NM_META_SETTING_TYPE_VPN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VPN_SETTING_NAME, + .get_setting_gtype = nm_setting_vpn_get_type, + }, + [NM_META_SETTING_TYPE_VRF] = + { + .meta_type = NM_META_SETTING_TYPE_VRF, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VRF_SETTING_NAME, + .get_setting_gtype = nm_setting_vrf_get_type, + }, + [NM_META_SETTING_TYPE_VXLAN] = + { + .meta_type = NM_META_SETTING_TYPE_VXLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VXLAN_SETTING_NAME, + .get_setting_gtype = nm_setting_vxlan_get_type, + }, + [NM_META_SETTING_TYPE_WIFI_P2P] = + { + .meta_type = NM_META_SETTING_TYPE_WIFI_P2P, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WIFI_P2P_SETTING_NAME, + .get_setting_gtype = nm_setting_wifi_p2p_get_type, + }, + [NM_META_SETTING_TYPE_WIMAX] = + { + .meta_type = NM_META_SETTING_TYPE_WIMAX, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WIMAX_SETTING_NAME, + .get_setting_gtype = nm_setting_wimax_get_type, + }, + [NM_META_SETTING_TYPE_WIRED] = + { + .meta_type = NM_META_SETTING_TYPE_WIRED, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WIRED_SETTING_NAME, + .get_setting_gtype = nm_setting_wired_get_type, + }, + [NM_META_SETTING_TYPE_WIREGUARD] = + { + .meta_type = NM_META_SETTING_TYPE_WIREGUARD, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WIREGUARD_SETTING_NAME, + .get_setting_gtype = nm_setting_wireguard_get_type, + }, + [NM_META_SETTING_TYPE_WIRELESS] = + { + .meta_type = NM_META_SETTING_TYPE_WIRELESS, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WIRELESS_SETTING_NAME, + .get_setting_gtype = nm_setting_wireless_get_type, + }, + [NM_META_SETTING_TYPE_WIRELESS_SECURITY] = + { + .meta_type = NM_META_SETTING_TYPE_WIRELESS_SECURITY, + .setting_priority = NM_SETTING_PRIORITY_HW_AUX, + .setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + .get_setting_gtype = nm_setting_wireless_security_get_type, + }, + [NM_META_SETTING_TYPE_WPAN] = + { + .meta_type = NM_META_SETTING_TYPE_WPAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_WPAN_SETTING_NAME, + .get_setting_gtype = nm_setting_wpan_get_type, + }, + + [NM_META_SETTING_TYPE_UNKNOWN] = + { + .meta_type = NM_META_SETTING_TYPE_UNKNOWN, + }, +}; + +const NMMetaSettingInfo * +nm_meta_setting_infos_by_name(const char *name) +{ + gssize idx; + + if (NM_MORE_ASSERTS > 10) { + guint i, j; + + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + const NMMetaSettingInfo *setting_info = &nm_meta_setting_infos[i]; + + nm_assert(setting_info->meta_type == (NMMetaSettingType) i); + nm_assert(setting_info->setting_name); + nm_assert(setting_info->setting_name[0]); + nm_assert(setting_info->get_setting_gtype); + nm_assert(setting_info->setting_priority != NM_SETTING_PRIORITY_INVALID); + if (i > 0 + && strcmp(nm_meta_setting_infos[i - 1].setting_name, setting_info->setting_name) + >= 0) { + g_error("nm_meta_setting_infos[%u, \"%s\"] is wrongly sorted before " + "nm_meta_setting_infos[%u, \"%s\"]. Rearange NMMetaSettingType enum", + i - 1, + nm_meta_setting_infos[i - 1].setting_name, + i, + setting_info->setting_name); + } + for (j = 0; j < i; j++) { + const NMMetaSettingInfo *s = &nm_meta_setting_infos[j]; + + nm_assert(setting_info->get_setting_gtype != s->get_setting_gtype); + } + } + } + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMMetaSettingInfo, setting_name) == 0); + idx = nm_utils_array_find_binary_search(nm_meta_setting_infos, + sizeof(NMMetaSettingInfo), + _NM_META_SETTING_TYPE_NUM, + &name, + nm_strcmp_p_with_data, + NULL); + + return idx >= 0 ? &nm_meta_setting_infos[idx] : NULL; +} + +const NMMetaSettingInfo * +nm_meta_setting_infos_by_gtype(GType gtype) +{ +#if _NM_META_SETTING_BASE_IMPL_LIBNM + nm_auto_unref_gtypeclass GTypeClass *gtypeclass_unref = NULL; + GTypeClass * gtypeclass; + NMSettingClass * klass; + + if (!g_type_is_a(gtype, NM_TYPE_SETTING)) + goto out_none; + + gtypeclass = g_type_class_peek(gtype); + if (!gtypeclass) + gtypeclass = gtypeclass_unref = g_type_class_ref(gtype); + + nm_assert(NM_IS_SETTING_CLASS(gtypeclass)); + + klass = (NMSettingClass *) gtypeclass; + + if (!klass->setting_info) + goto out_none; + + nm_assert(klass->setting_info->get_setting_gtype); + nm_assert(klass->setting_info->get_setting_gtype() == gtype); + + return klass->setting_info; + +out_none: + + if (NM_MORE_ASSERTS > 10) { + int i; + + /* this might hint to a bug, but it would be expected for NM_TYPE_SETTING + * and NM_TYPE_SETTING_IP_CONFIG. + * + * Assert that we didn't lookup for a gtype, which we would expect to find. + * An assertion failure here, hints to a bug in nm_setting_*_class_init(). + */ + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) + nm_assert(nm_meta_setting_infos[i].get_setting_gtype() != gtype); + } + + return NULL; +#else + guint i; + + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + if (nm_meta_setting_infos[i].get_setting_gtype() == gtype) + return &nm_meta_setting_infos[i]; + } + return NULL; +#endif +} + +/*****************************************************************************/ + +NMSettingPriority +nm_meta_setting_info_get_base_type_priority(const NMMetaSettingInfo *setting_info, GType gtype) +{ + /* Historical oddity: PPPoE is a base-type even though it's not + * priority 1. It needs to be sorted *after* lower-level stuff like + * Wi-Fi security or 802.1x for secrets, but it's still allowed as a + * base type. + */ + + if (setting_info) { + if (NM_IN_SET(setting_info->setting_priority, + NM_SETTING_PRIORITY_HW_BASE, + NM_SETTING_PRIORITY_HW_NON_BASE) + || gtype == NM_TYPE_SETTING_PPPOE) + return setting_info->setting_priority; + } + + return NM_SETTING_PRIORITY_INVALID; +} + +NMSettingPriority +_nm_setting_type_get_base_type_priority(GType type) +{ + return nm_meta_setting_info_get_base_type_priority(nm_meta_setting_infos_by_gtype(type), type); +} + +/*****************************************************************************/ diff --git a/src/libnmc-setting/nm-meta-setting-base-impl.h b/src/libnmc-setting/nm-meta-setting-base-impl.h new file mode 100644 index 0000000..94b14e8 --- /dev/null +++ b/src/libnmc-setting/nm-meta-setting-base-impl.h @@ -0,0 +1,187 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2017 - 2018 Red Hat, Inc. + */ + +#ifndef __NM_META_SETTING_BASE_IMPL_H__ +#define __NM_META_SETTING_BASE_IMPL_H__ + +#include "nm-setting-8021x.h" + +/*****************************************************************************/ + +/* + * A setting's priority should roughly follow the OSI layer model, but it also + * controls which settings get asked for secrets first. Thus settings which + * relate to things that must be working first, like hardware, should get a + * higher priority than things which layer on top of the hardware. For example, + * the GSM/CDMA settings should provide secrets before the PPP setting does, + * because a PIN is required to unlock the device before PPP can even start. + * Even settings without secrets should be assigned the right priority. + * + * 0: reserved for invalid + * + * 1: reserved for the Connection setting + * + * 2,3: hardware-related settings like Ethernet, Wi-Fi, InfiniBand, Bridge, etc. + * These priority 1 settings are also "base types", which means that at least + * one of them is required for the connection to be valid, and their name is + * valid in the 'type' property of the Connection setting. + * + * 4: hardware-related auxiliary settings that require a base setting to be + * successful first, like Wi-Fi security, 802.1x, etc. + * + * 5: hardware-independent settings that are required before IP connectivity + * can be established, like PPP, PPPoE, etc. + * + * 6: IP-level stuff + * + * 10: NMSettingUser + */ +typedef enum { /*< skip >*/ + NM_SETTING_PRIORITY_INVALID = 0, + NM_SETTING_PRIORITY_CONNECTION = 1, + NM_SETTING_PRIORITY_HW_BASE = 2, + NM_SETTING_PRIORITY_HW_NON_BASE = 3, + NM_SETTING_PRIORITY_HW_AUX = 4, + NM_SETTING_PRIORITY_AUX = 5, + NM_SETTING_PRIORITY_IP = 6, + NM_SETTING_PRIORITY_USER = 10, +} NMSettingPriority; + +/*****************************************************************************/ + +typedef enum { + NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT, + NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT, + NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT, + NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT, + NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY, + NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY, + + NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN, + + _NM_SETTING_802_1X_SCHEME_TYPE_NUM = NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN, +} NMSetting8021xSchemeType; + +typedef struct { + const char *setting_key; + NMSetting8021xCKScheme (*scheme_func)(NMSetting8021x *setting); + NMSetting8021xCKFormat (*format_func)(NMSetting8021x *setting); + const char *(*path_func)(NMSetting8021x *setting); + GBytes *(*blob_func)(NMSetting8021x *setting); + const char *(*uri_func)(NMSetting8021x *setting); + const char *(*passwd_func)(NMSetting8021x *setting); + NMSettingSecretFlags (*pwflag_func)(NMSetting8021x *setting); + gboolean (*set_cert_func)(NMSetting8021x * setting, + const char * value, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error); + gboolean (*set_private_key_func)(NMSetting8021x * setting, + const char * value, + const char * password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError ** error); + const char * file_suffix; + NMSetting8021xSchemeType scheme_type; + bool is_secret : 1; +} NMSetting8021xSchemeVtable; + +extern const NMSetting8021xSchemeVtable + nm_setting_8021x_scheme_vtable[_NM_SETTING_802_1X_SCHEME_TYPE_NUM + 1]; + +/*****************************************************************************/ + +typedef enum { + /* the enum (and their numeric values) are internal API. Do not assign + * any meaning the numeric values, because they already have one: + * + * they are sorted in a way, that corresponds to the asciibetical sort + * order of the corresponding setting-name. */ + + NM_META_SETTING_TYPE_6LOWPAN, + NM_META_SETTING_TYPE_OLPC_MESH, + NM_META_SETTING_TYPE_WIRELESS, + NM_META_SETTING_TYPE_WIRELESS_SECURITY, + NM_META_SETTING_TYPE_802_1X, + NM_META_SETTING_TYPE_WIRED, + NM_META_SETTING_TYPE_ADSL, + NM_META_SETTING_TYPE_BLUETOOTH, + NM_META_SETTING_TYPE_BOND, + NM_META_SETTING_TYPE_BRIDGE, + NM_META_SETTING_TYPE_BRIDGE_PORT, + NM_META_SETTING_TYPE_CDMA, + NM_META_SETTING_TYPE_CONNECTION, + NM_META_SETTING_TYPE_DCB, + NM_META_SETTING_TYPE_DUMMY, + NM_META_SETTING_TYPE_ETHTOOL, + NM_META_SETTING_TYPE_GENERIC, + NM_META_SETTING_TYPE_GSM, + NM_META_SETTING_TYPE_HOSTNAME, + NM_META_SETTING_TYPE_INFINIBAND, + NM_META_SETTING_TYPE_IP_TUNNEL, + NM_META_SETTING_TYPE_IP4_CONFIG, + NM_META_SETTING_TYPE_IP6_CONFIG, + NM_META_SETTING_TYPE_MACSEC, + NM_META_SETTING_TYPE_MACVLAN, + NM_META_SETTING_TYPE_MATCH, + NM_META_SETTING_TYPE_OVS_BRIDGE, + NM_META_SETTING_TYPE_OVS_DPDK, + NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS, + NM_META_SETTING_TYPE_OVS_INTERFACE, + NM_META_SETTING_TYPE_OVS_PATCH, + NM_META_SETTING_TYPE_OVS_PORT, + NM_META_SETTING_TYPE_PPP, + NM_META_SETTING_TYPE_PPPOE, + NM_META_SETTING_TYPE_PROXY, + NM_META_SETTING_TYPE_SERIAL, + NM_META_SETTING_TYPE_SRIOV, + NM_META_SETTING_TYPE_TC_CONFIG, + NM_META_SETTING_TYPE_TEAM, + NM_META_SETTING_TYPE_TEAM_PORT, + NM_META_SETTING_TYPE_TUN, + NM_META_SETTING_TYPE_USER, + NM_META_SETTING_TYPE_VETH, + NM_META_SETTING_TYPE_VLAN, + NM_META_SETTING_TYPE_VPN, + NM_META_SETTING_TYPE_VRF, + NM_META_SETTING_TYPE_VXLAN, + NM_META_SETTING_TYPE_WIFI_P2P, + NM_META_SETTING_TYPE_WIMAX, + NM_META_SETTING_TYPE_WIREGUARD, + NM_META_SETTING_TYPE_WPAN, + + NM_META_SETTING_TYPE_UNKNOWN, + + _NM_META_SETTING_TYPE_NUM = NM_META_SETTING_TYPE_UNKNOWN, +} NMMetaSettingType; + +#if _NM_META_SETTING_BASE_IMPL_LIBNM + #define _NMMetaSettingInfo_Alias _NMMetaSettingInfo +#else + #define _NMMetaSettingInfo_Alias _NMMetaSettingInfoCli +#endif + +struct _NMMetaSettingInfo_Alias { + const char *setting_name; + GType (*get_setting_gtype)(void); + NMMetaSettingType meta_type; + NMSettingPriority setting_priority; +}; + +typedef struct _NMMetaSettingInfo_Alias NMMetaSettingInfo; + +extern const NMMetaSettingInfo nm_meta_setting_infos[_NM_META_SETTING_TYPE_NUM + 1]; + +const NMMetaSettingInfo *nm_meta_setting_infos_by_name(const char *name); +const NMMetaSettingInfo *nm_meta_setting_infos_by_gtype(GType gtype); + +/*****************************************************************************/ + +NMSettingPriority nm_meta_setting_info_get_base_type_priority(const NMMetaSettingInfo *setting_info, + GType gtype); +NMSettingPriority _nm_setting_type_get_base_type_priority(GType type); + +#endif /* __NM_META_SETTING_BASE_IMPL_H__ */ diff --git a/src/libnmc-setting/nm-meta-setting-base.h b/src/libnmc-setting/nm-meta-setting-base.h new file mode 100644 index 0000000..85d790a --- /dev/null +++ b/src/libnmc-setting/nm-meta-setting-base.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_META_SETTING_BASE_H__ +#define __NM_META_SETTING_BASE_H__ + +#define _NM_META_SETTING_BASE_IMPL_LIBNM 0 + +#include "nm-meta-setting-base-impl.h" + +#endif /* __NM_META_SETTING_BASE_H__ */ diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c new file mode 100644 index 0000000..3daa6ad --- /dev/null +++ b/src/libnmc-setting/nm-meta-setting-desc.c @@ -0,0 +1,8575 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2010 - 2018 Red Hat, Inc. + */ + +#include "libnm-client-aux-extern/nm-default-client.h" + +#include "nm-meta-setting-desc.h" + +#include +#include +#include +#include + +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "libnm-glib-aux/nm-enum-utils.h" +#include "libnm-glib-aux/nm-secret-utils.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" +#include "libnm-core-aux-extern/nm-libnm-core-aux.h" + +#include "libnmc-base/nm-vpn-helpers.h" +#include "libnmc-base/nm-client-utils.h" +#include "nm-meta-setting-access.h" + +/*****************************************************************************/ + +static char *secret_flags_to_string(guint32 flags, NMMetaAccessorGetType get_type); + +#define ALL_SECRET_FLAGS \ + (NM_SETTING_SECRET_FLAG_NONE | NM_SETTING_SECRET_FLAG_AGENT_OWNED \ + | NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED) + +/*****************************************************************************/ + +static GType +_gobject_property_get_gtype(GObject *gobject, const char *property_name) +{ + GParamSpec *param_spec; + + param_spec = g_object_class_find_property(G_OBJECT_GET_CLASS(gobject), property_name); + if (param_spec) + return param_spec->value_type; + g_return_val_if_reached(G_TYPE_INVALID); +} + +static GType +_gtype_property_get_gtype(GType gtype, const char *property_name) +{ + /* given @gtype, a type for a GObject, lookup the property @property_name + * and return its value_type. */ + if (G_TYPE_IS_CLASSED(gtype)) { + GParamSpec * param_spec; + nm_auto_unref_gtypeclass GTypeClass *gtypeclass = g_type_class_ref(gtype); + + if (G_IS_OBJECT_CLASS(gtypeclass)) { + param_spec = g_object_class_find_property(G_OBJECT_CLASS(gtypeclass), property_name); + if (param_spec) + return param_spec->value_type; + } + } + g_return_val_if_reached(G_TYPE_INVALID); +} + +/*****************************************************************************/ + +static char * +bytes_to_string(GBytes *bytes) +{ + const guint8 *data; + gsize len; + + if (!bytes) + return NULL; + + data = g_bytes_get_data(bytes, &len); + return nm_utils_bin2hexstr_full(data, len, '\0', TRUE, NULL); +} + +/*****************************************************************************/ + +static int +_int64_cmp_desc(gconstpointer a, gconstpointer b, gpointer user_data) +{ + NM_CMP_DIRECT(*((const gint64 *) b), *((const gint64 *) a)); + return 0; +} + +static gint64 * +_value_str_as_index_list(const char *value, gsize *out_len) +{ + gs_free char *str_clone_free = NULL; + gboolean str_cloned = FALSE; + char * str; + gsize i, j; + gsize n_alloc; + gsize len; + gs_free gint64 *arr = NULL; + + *out_len = 0; + + if (!value) + return NULL; + + str = (char *) value; + n_alloc = 0; + len = 0; + while (TRUE) { + gint64 i64; + const char *s; + gsize good; + + good = strcspn(str, "," NM_ASCII_SPACES); + if (good == 0) { + if (str[0] == '\0') + break; + str++; + continue; + } + if (str[good] == '\0') { + s = str; + str += good; + } else { + if (!str_cloned) { + str_cloned = TRUE; + str = nm_strndup_a(200, str, strlen(str), &str_clone_free); + } + s = str; + str[good] = '\0'; + str += good + 1; + } + + i64 = _nm_utils_ascii_str_to_int64(s, 10, 0, G_MAXINT64, -1); + if (i64 == -1) + return NULL; + + if (len >= n_alloc) { + if (n_alloc > 0) { + n_alloc = n_alloc * 2; + arr = g_realloc(arr, n_alloc * sizeof(gint64)); + } else { + n_alloc = 4; + arr = g_new(gint64, n_alloc); + } + } + arr[len++] = i64; + } + + if (len > 1) { + /* sort the list of indexes descendingly, and drop duplicates. */ + g_qsort_with_data(arr, len, sizeof(gint64), _int64_cmp_desc, NULL); + j = 1; + for (i = 1; i < len; i++) { + nm_assert(arr[i - 1] >= arr[i]); + if (arr[i - 1] > arr[i]) + arr[j++] = arr[i]; + } + len = j; + } + + *out_len = len; + return g_steal_pointer(&arr); +} + +#define ESCAPED_TOKENS_WITH_SPACES_DELIMTER ' ' +#define ESCAPED_TOKENS_WITH_SPACES_DELIMTERS NM_ASCII_SPACES "," + +#define ESCAPED_TOKENS_DELIMITER ',' +#define ESCAPED_TOKENS_DELIMITERS "," + +typedef enum { + VALUE_STRSPLIT_MODE_OBJLIST, + VALUE_STRSPLIT_MODE_MULTILIST, + VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, + VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES, +} ValueStrsplitMode; + +static const char ** +_value_strsplit(const char *value, ValueStrsplitMode split_mode, gsize *out_len) +{ + gs_free const char **strv = NULL; + + /* FIXME: some modes should support backslash escaping. + * In particular, to distinguish from _value_str_as_index_list(), which + * does not accept '\\'. */ + + /* note that all modes remove empty tokens (",", "a,,b", ",,"). */ + switch (split_mode) { + case VALUE_STRSPLIT_MODE_OBJLIST: + strv = nm_utils_strsplit_set_full(value, + ESCAPED_TOKENS_DELIMITERS, + NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); + break; + case VALUE_STRSPLIT_MODE_MULTILIST: + strv = nm_utils_strsplit_set_full(value, + ESCAPED_TOKENS_WITH_SPACES_DELIMTERS, + NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); + break; + case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS: + strv = nm_utils_escaped_tokens_split(value, ESCAPED_TOKENS_DELIMITERS); + break; + case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES: + strv = nm_utils_escaped_tokens_split(value, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS); + break; + } + + NM_SET_OUT(out_len, NM_PTRARRAY_LEN(strv)); + return g_steal_pointer(&strv); +} + +static gboolean +_value_strsplit_assert_unsplitable(const char *str) +{ +#if NM_MORE_ASSERTS > 5 + gs_free const char **strv_test = NULL; + gsize j, l; + + /* Assert that we cannot split the token and that it + * has no unescaped delimiters. */ + + strv_test = _value_strsplit(str, VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, NULL); + nm_assert(NM_PTRARRAY_LEN(strv_test) == 1); + + for (j = 0; str[j] != '\0';) { + if (str[j] == '\\') { + j++; + nm_assert(str[j] != '\0'); + } else + nm_assert(!NM_IN_SET(str[j], '\0', ',')); + j++; + } + l = j; + nm_assert(!g_ascii_isspace(str[l - 1]) || (l >= 2 && str[l - 2] == '\\')); +#endif + + return TRUE; +} + +static NMIPAddress * +_parse_ip_address(int family, const char *address, GError **error) +{ + gs_free char *ip_str = NULL; + const int MAX_PREFIX = (family == AF_INET) ? 32 : 128; + NMIPAddress * addr; + char * plen; + int prefix; + GError * local = NULL; + + g_return_val_if_fail(address, NULL); + g_return_val_if_fail(!error || !*error, NULL); + + ip_str = g_strstrip(g_strdup(address)); + + prefix = MAX_PREFIX; + + plen = strchr(ip_str, '/'); + if (plen) { + *plen++ = '\0'; + if ((prefix = _nm_utils_ascii_str_to_int64(plen, 10, 1, MAX_PREFIX, -1)) == -1) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid prefix '%s'; <1-%d> allowed"), + plen, + MAX_PREFIX); + return NULL; + } + } + + addr = nm_ip_address_new(family, ip_str, prefix, &local); + if (!addr) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid IP address: %s"), + local->message); + g_clear_error(&local); + } + return addr; +} + +static NMIPRoute * +_parse_ip_route(int family, const char *str, GError **error) +{ + const int MAX_PREFIX = (family == AF_INET) ? 32 : 128; + const char * next_hop = NULL; + int prefix; + NMIPRoute * route = NULL; + GError * local = NULL; + gint64 metric = -1; + guint i; + gs_free const char **routev = NULL; + gs_free char * str_clean_free = NULL; + const char * str_clean; + gs_free char * dest_clone = NULL; + const char * dest; + const char * plen; + gs_unref_hashtable GHashTable *attrs = NULL; +#define ROUTE_SYNTAX \ + _("The valid syntax is: 'ip[/prefix] [next-hop] [metric] [attribute=val]... [,ip[/prefix] " \ + "...]'") + + nm_assert(NM_IN_SET(family, AF_INET, AF_INET6)); + nm_assert(str); + nm_assert(!error || !*error); + + str_clean = nm_strstrip_avoid_copy_a(300, str, &str_clean_free); + routev = nm_utils_strsplit_set(str_clean, " \t"); + if (!routev) { + g_set_error(error, 1, 0, "'%s' is not valid. %s", str, ROUTE_SYNTAX); + return NULL; + } + + dest = routev[0]; + plen = strchr(dest, '/'); /* prefix delimiter */ + if (plen) { + dest_clone = g_strdup(dest); + plen = &dest_clone[plen - dest]; + dest = dest_clone; + *((char *) plen) = '\0'; + plen++; + } + prefix = MAX_PREFIX; + if (plen) { + if ((prefix = _nm_utils_ascii_str_to_int64(plen, 10, 0, MAX_PREFIX, -1)) == -1) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid prefix '%s'; <1-%d> allowed"), + plen, + MAX_PREFIX); + return NULL; + } + } + + for (i = 1; routev[i]; i++) { + gint64 tmp64; + + if (nm_utils_ipaddr_is_valid(family, routev[i])) { + if (metric != -1 || attrs) { + g_set_error(error, 1, 0, _("the next hop ('%s') must be first"), routev[i]); + return NULL; + } + next_hop = routev[i]; + } else if ((tmp64 = _nm_utils_ascii_str_to_int64(routev[i], 10, 0, G_MAXUINT32, -1)) + != -1) { + if (attrs) { + g_set_error(error, + 1, + 0, + _("the metric ('%s') must be before attributes"), + routev[i]); + return NULL; + } + metric = tmp64; + } else if (strchr(routev[i], '=')) { + GHashTableIter iter; + char * iter_key; + GVariant * iter_value; + gs_unref_hashtable GHashTable *tmp_attrs = NULL; + + tmp_attrs = nm_utils_parse_variant_attributes(routev[i], + ' ', + '=', + FALSE, + nm_ip_route_get_variant_attribute_spec(), + error); + if (!tmp_attrs) { + g_prefix_error(error, "invalid option '%s': ", routev[i]); + return NULL; + } + + if (!attrs) { + attrs = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref); + } + + g_hash_table_iter_init(&iter, tmp_attrs); + while ( + g_hash_table_iter_next(&iter, (gpointer *) &iter_key, (gpointer *) &iter_value)) { + /* need to sink the reference, because nm_utils_parse_variant_attributes() returns + * floating refs. */ + g_variant_ref_sink(iter_value); + + if (!nm_ip_route_attribute_validate(iter_key, iter_value, family, NULL, error)) { + g_prefix_error(error, "%s: ", iter_key); + return NULL; + } + g_hash_table_insert(attrs, iter_key, iter_value); + g_hash_table_iter_steal(&iter); + } + } else { + g_set_error(error, 1, 0, "%s", ROUTE_SYNTAX); + return NULL; + } + } + + route = nm_ip_route_new(family, dest, prefix, next_hop, metric, &local); + if (!route) { + g_set_error(error, 1, 0, _("invalid route: %s. %s"), local->message, ROUTE_SYNTAX); + g_clear_error(&local); + return NULL; + } + + if (attrs) { + GHashTableIter iter; + char * name; + GVariant * variant; + + g_hash_table_iter_init(&iter, attrs); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) + nm_ip_route_set_attribute(route, name, variant); + } + + return route; +} + +/*****************************************************************************/ + +/* Max priority values from libnm-core/nm-setting-vlan.c */ +#define MAX_SKB_PRIO G_MAXUINT32 +#define MAX_8021P_PRIO 7 /* Max 802.1p priority */ + +/* + * nmc_proxy_check_script: + * @script: file name with PAC script, or raw PAC Script data + * @out_script: raw PAC Script (with removed new-line characters) + * @error: location to store error, or %NULL + * + * Check PAC Script from @script parameter and return the checked/sanitized + * config in @out_script. + * + * Returns: %TRUE if the script is valid, %FALSE if it is invalid + */ +static gboolean +nmc_proxy_check_script(const char *script, char **out_script, GError **error) +{ + enum { + _PAC_SCRIPT_TYPE_GUESS, + _PAC_SCRIPT_TYPE_FILE, + _PAC_SCRIPT_TYPE_JSON, + } desired_type = _PAC_SCRIPT_TYPE_GUESS; + const char * filename = NULL; + size_t c_len = 0; + gs_free char *script_clone = NULL; + + *out_script = NULL; + + if (!script || !script[0]) + return TRUE; + + if (g_str_has_prefix(script, "file://")) { + script += NM_STRLEN("file://"); + desired_type = _PAC_SCRIPT_TYPE_FILE; + } else if (g_str_has_prefix(script, "js://")) { + script += NM_STRLEN("js://"); + desired_type = _PAC_SCRIPT_TYPE_JSON; + } + + if (NM_IN_SET(desired_type, _PAC_SCRIPT_TYPE_FILE, _PAC_SCRIPT_TYPE_GUESS)) { + gs_free char *contents = NULL; + + if (!g_file_get_contents(script, &contents, &c_len, NULL)) { + if (desired_type == _PAC_SCRIPT_TYPE_FILE) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("cannot read pac-script from file '%s'"), + script); + return FALSE; + } + } else { + if (c_len != strlen(contents)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("file '%s' contains non-valid utf-8"), + script); + return FALSE; + } + filename = script; + script = script_clone = g_steal_pointer(&contents); + } + } + + if (!strstr(script, "FindProxyForURL") || !g_utf8_validate(script, -1, NULL)) { + if (filename) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' does not contain a valid PAC Script"), + filename); + } else { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("Not a valid PAC Script")); + } + return FALSE; + } + + *out_script = (script == script_clone) ? g_steal_pointer(&script_clone) : g_strdup(script); + return TRUE; +} + +/* + * nmc_team_check_config: + * @config: file name with team config, or raw team JSON config data + * @out_config: raw team JSON config data + * The value must be freed with g_free(). + * @error: location to store error, or %NUL + * + * Check team config from @config parameter and return the checked + * config in @out_config. + * + * Returns: %TRUE if the config is valid, %FALSE if it is invalid + */ +static gboolean +nmc_team_check_config(const char *config, char **out_config, GError **error) +{ + enum { + _TEAM_CONFIG_TYPE_GUESS, + _TEAM_CONFIG_TYPE_FILE, + _TEAM_CONFIG_TYPE_JSON, + } desired_type = _TEAM_CONFIG_TYPE_GUESS; + size_t c_len = 0; + gs_free char *config_clone = NULL; + + *out_config = NULL; + + if (!config || !config[0]) + return TRUE; + + if (g_str_has_prefix(config, "file://")) { + config += NM_STRLEN("file://"); + desired_type = _TEAM_CONFIG_TYPE_FILE; + } else if (g_str_has_prefix(config, "json://")) { + config += NM_STRLEN("json://"); + desired_type = _TEAM_CONFIG_TYPE_JSON; + } + + if (NM_IN_SET(desired_type, _TEAM_CONFIG_TYPE_FILE, _TEAM_CONFIG_TYPE_GUESS)) { + gs_free char *contents = NULL; + + if (!g_file_get_contents(config, &contents, &c_len, NULL)) { + if (desired_type == _TEAM_CONFIG_TYPE_FILE) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("cannot read team config from file '%s'"), + config); + return FALSE; + } + } else { + if (c_len != strlen(contents)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("team config file '%s' contains non-valid utf-8"), + config); + return FALSE; + } + config = config_clone = g_steal_pointer(&contents); + } + } + + *out_config = (config == config_clone) ? g_steal_pointer(&config_clone) : g_strdup(config); + return TRUE; +} + +static const char * +_get_text_hidden(NMMetaAccessorGetType get_type) +{ + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _(NM_META_TEXT_HIDDEN); + return NM_META_TEXT_HIDDEN; +} + +/*****************************************************************************/ + +G_GNUC_PRINTF(4, 5) +static void +_env_warn_fcn(const NMMetaEnvironment *environment, + gpointer environment_user_data, + NMMetaEnvWarnLevel warn_level, + const char * fmt_l10n, + ...) +{ + va_list ap; + + if (!environment || !environment->warn_fcn) + return; + + va_start(ap, fmt_l10n); + environment->warn_fcn(environment, environment_user_data, warn_level, fmt_l10n, ap); + va_end(ap); +} + +/*****************************************************************************/ + +#define ARGS_DESCRIBE_FCN const NMMetaPropertyInfo *property_info, char **out_to_free + +#define ARGS_GET_FCN \ + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \ + gpointer environment_user_data, NMSetting *setting, NMMetaAccessorGetType get_type, \ + NMMetaAccessorGetFlags get_flags, NMMetaAccessorGetOutFlags *out_flags, \ + gboolean *out_is_default, gpointer *out_to_free + +#define ARGS_SET_FCN \ + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \ + gpointer environment_user_data, NMSetting *setting, NMMetaAccessorModifier modifier, \ + const char *value, GError **error + +#define ARGS_REMOVE_FCN \ + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \ + gpointer environment_user_data, NMSetting *setting, const char *value, GError **error + +#define ARGS_COMPLETE_FCN \ + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \ + gpointer environment_user_data, const NMMetaOperationContext *operation_context, \ + const char *text, gboolean *out_complete_filename, char ***out_to_free + +#define ARGS_VALUES_FCN const NMMetaPropertyInfo *property_info, char ***out_to_free + +#define ARGS_SETTING_INIT_FCN \ + const NMMetaSettingInfoEditor *setting_info, NMSetting *setting, \ + NMMetaAccessorSettingInitType init_type + +static gboolean _set_fcn_optionlist(ARGS_SET_FCN); + +static gboolean +_SET_FCN_DO_RESET_DEFAULT(const NMMetaPropertyInfo *property_info, + NMMetaAccessorModifier modifier, + const char * value) +{ + nm_assert(property_info); + nm_assert(!property_info->property_type->set_supports_remove); + nm_assert(NM_IN_SET(modifier, NM_META_ACCESSOR_MODIFIER_SET, NM_META_ACCESSOR_MODIFIER_ADD)); + nm_assert(value || modifier == NM_META_ACCESSOR_MODIFIER_SET); + + return value == NULL; +} + +static gboolean +_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(const NMMetaPropertyInfo *property_info, + NMMetaAccessorModifier modifier, + const char * value) +{ + nm_assert(property_info); + nm_assert(property_info->property_type->set_supports_remove); + nm_assert(NM_IN_SET(modifier, + NM_META_ACCESSOR_MODIFIER_SET, + NM_META_ACCESSOR_MODIFIER_ADD, + NM_META_ACCESSOR_MODIFIER_DEL)); + nm_assert(value || modifier == NM_META_ACCESSOR_MODIFIER_SET); + + return value == NULL; +} + +static gboolean +_SET_FCN_DO_SET_ALL(NMMetaAccessorModifier modifier, const char *value) +{ + nm_assert(NM_IN_SET(modifier, + NM_META_ACCESSOR_MODIFIER_SET, + NM_META_ACCESSOR_MODIFIER_ADD, + NM_META_ACCESSOR_MODIFIER_DEL)); + nm_assert(value); + + return modifier == NM_META_ACCESSOR_MODIFIER_SET; +} + +static gboolean +_SET_FCN_DO_REMOVE(NMMetaAccessorModifier modifier, const char *value) +{ + nm_assert(NM_IN_SET(modifier, + NM_META_ACCESSOR_MODIFIER_SET, + NM_META_ACCESSOR_MODIFIER_ADD, + NM_META_ACCESSOR_MODIFIER_DEL)); + nm_assert(value); + + return modifier == NM_META_ACCESSOR_MODIFIER_DEL; +} + +#define RETURN_UNSUPPORTED_GET_TYPE() \ + G_STMT_START \ + { \ + if (!NM_IN_SET(get_type, \ + NM_META_ACCESSOR_GET_TYPE_PARSABLE, \ + NM_META_ACCESSOR_GET_TYPE_PRETTY)) { \ + nm_assert_not_reached(); \ + return NULL; \ + } \ + } \ + G_STMT_END; + +#define RETURN_STR_TO_FREE(val) \ + G_STMT_START \ + { \ + char *_val = (val); \ + \ + return ((*(out_to_free)) = _val); \ + } \ + G_STMT_END + +#define RETURN_STR_TEMPORARY(val) \ + G_STMT_START \ + { \ + const char *_val = (val); \ + \ + if (_val == NULL) \ + return NULL; \ + if (_val[0] == '\0') \ + return ""; \ + return ((*(out_to_free)) = g_strdup(_val)); \ + } \ + G_STMT_END + +static gboolean +_gobject_property_is_default(NMSetting *setting, const char *prop_name) +{ + nm_auto_unset_gvalue GValue v = G_VALUE_INIT; + GParamSpec * pspec; + GHashTable * ht; + char ** strv; + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), prop_name); + if (!G_IS_PARAM_SPEC(pspec)) + g_return_val_if_reached(FALSE); + + g_value_init(&v, pspec->value_type); + g_object_get_property(G_OBJECT(setting), prop_name, &v); + + if (pspec->value_type == G_TYPE_STRV) { + strv = g_value_get_boxed(&v); + return !strv || !strv[0]; + } else if (pspec->value_type == G_TYPE_HASH_TABLE) { + ht = g_value_get_boxed(&v); + return !ht || !g_hash_table_size(ht); + } + + return g_param_value_defaults(pspec, &v); +} + +static gboolean +_gobject_property_reset(NMSetting *setting, const char *prop_name, gboolean reset_default) +{ + nm_auto_unset_gvalue GValue v = G_VALUE_INIT; + GParamSpec * pspec; + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), prop_name); + if (!G_IS_PARAM_SPEC(pspec)) + g_return_val_if_reached(FALSE); + + g_value_init(&v, pspec->value_type); + if (reset_default) + g_param_value_set_default(pspec, &v); + g_object_set_property(G_OBJECT(setting), prop_name, &v); + return TRUE; +} + +static gboolean +_gobject_property_reset_default(NMSetting *setting, const char *prop_name) +{ + return _gobject_property_reset(setting, prop_name, TRUE); +} + +static const char * +_coerce_str_emptyunset(NMMetaAccessorGetType get_type, + gboolean is_default, + const char * cstr, + char ** out_str) +{ + nm_assert(out_str && !*out_str); + nm_assert((!is_default && cstr && cstr[0] != '\0') || NM_IN_STRSET(cstr, NULL, "")); + + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) { + if (!cstr || cstr[0] == '\0') { + if (is_default) + return ""; + else + return "\"\""; + } + nm_assert(!is_default); + return (*out_str = g_strdup_printf("\"%s\"", cstr)); + } + + /* we coerce NULL/"" to either "" or " ". */ + if (!cstr || cstr[0] == '\0') { + if (is_default) + return ""; + else + return " "; + } + nm_assert(!is_default); + return cstr; +} + +#define RETURN_STR_EMPTYUNSET(get_type, is_default, cstr) \ + G_STMT_START \ + { \ + char * _str = NULL; \ + const char *_cstr; \ + \ + _cstr = _coerce_str_emptyunset((get_type), (is_default), (cstr), &_str); \ + if (_str) \ + RETURN_STR_TO_FREE(_str); \ + RETURN_STR_TEMPORARY(_cstr); \ + } \ + G_STMT_END + +static gboolean +_is_default(const NMMetaPropertyInfo *property_info, NMSetting *setting) +{ + if (property_info->property_typ_data && property_info->property_typ_data->is_default_fcn) + return !!(property_info->property_typ_data->is_default_fcn(setting)); + + return _gobject_property_is_default(setting, property_info->property_name); +} + +static gconstpointer +_get_fcn_gobject_impl(const NMMetaPropertyInfo *property_info, + NMSetting * setting, + NMMetaAccessorGetType get_type, + gboolean handle_emptyunset, + gboolean * out_is_default, + gpointer * out_to_free) +{ + const char * cstr; + GType gtype_prop; + nm_auto_unset_gvalue GValue val = G_VALUE_INIT; + gboolean is_default; + gboolean glib_handles_str_transform; + + RETURN_UNSUPPORTED_GET_TYPE(); + + is_default = _is_default(property_info, setting); + + NM_SET_OUT(out_is_default, is_default); + + gtype_prop = _gobject_property_get_gtype(G_OBJECT(setting), property_info->property_name); + + glib_handles_str_transform = + !NM_IN_SET(gtype_prop, G_TYPE_BOOLEAN, G_TYPE_STRV, G_TYPE_BYTES, G_TYPE_HASH_TABLE); + + if (glib_handles_str_transform) { + /* We rely on the type conversion of the gobject property to string. */ + g_value_init(&val, G_TYPE_STRING); + } else + g_value_init(&val, gtype_prop); + + g_object_get_property(G_OBJECT(setting), property_info->property_name, &val); + + /* Currently, only one particular property asks us to "handle_emptyunset". + * So, don't implement it (yet) for the other types, where it's unneeded. */ + nm_assert(!handle_emptyunset || (gtype_prop == G_TYPE_STRV && !glib_handles_str_transform)); + + if (gtype_prop == G_TYPE_STRING) { + nm_assert(glib_handles_str_transform); + nm_assert(!handle_emptyunset); + if (property_info->property_typ_data + && property_info->property_typ_data->subtype.gobject_string.handle_emptyunset) { + /* This string property can both be empty and NULL. We need to + * signal them differently. */ + cstr = g_value_get_string(&val); + nm_assert((!!is_default) == (cstr == NULL)); + RETURN_STR_EMPTYUNSET(get_type, is_default, NULL); + } + } + + if (glib_handles_str_transform) + RETURN_STR_TEMPORARY(g_value_get_string(&val)); + + if (gtype_prop == G_TYPE_BOOLEAN) { + gboolean b; + + b = g_value_get_boolean(&val); + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + cstr = b ? _("yes") : _("no"); + else + cstr = b ? "yes" : "no"; + return cstr; + } + + if (gtype_prop == G_TYPE_STRV) { + const char *const *strv; + + strv = g_value_get_boxed(&val); + if (strv && strv[0]) + RETURN_STR_TO_FREE(g_strjoinv(",", (char **) strv)); + + if (handle_emptyunset) { + /* we need to express empty lists from unset lists differently. */ + RETURN_STR_EMPTYUNSET(get_type, is_default, NULL); + } + + return ""; + } + + if (gtype_prop == G_TYPE_BYTES) { + char *str; + + str = bytes_to_string(g_value_get_boxed(&val)); + NM_SET_OUT(out_is_default, !str || !str[0]); + RETURN_STR_TO_FREE(str); + } + + if (gtype_prop == G_TYPE_HASH_TABLE) { + GHashTable * strdict; + gs_free const char **keys = NULL; + GString * str; + gsize i; + + nm_assert(property_info->setting_info + == &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_WIRED] + && NM_IN_STRSET(property_info->property_name, NM_SETTING_WIRED_S390_OPTIONS)); + nm_assert(property_info->property_type->set_fcn == _set_fcn_optionlist); + + strdict = g_value_get_boxed(&val); + keys = nm_utils_strdict_get_keys(strdict, TRUE, NULL); + if (!keys) + return NULL; + + str = g_string_new(NULL); + for (i = 0; keys[i]; i++) { + const char * key = keys[i]; + const char * v = g_hash_table_lookup(strdict, key); + gs_free char *escaped_key = NULL; + gs_free char *escaped_val = NULL; + + if (str->len > 0) + g_string_append_c(str, ','); + g_string_append(str, nm_utils_escaped_tokens_options_escape_key(key, &escaped_key)); + g_string_append_c(str, '='); + g_string_append(str, nm_utils_escaped_tokens_options_escape_val(v, &escaped_val)); + } + RETURN_STR_TO_FREE(g_string_free(str, FALSE)); + } + + nm_assert_not_reached(); + return NULL; +} + +static gconstpointer _get_fcn_gobject(ARGS_GET_FCN) +{ + return _get_fcn_gobject_impl(property_info, + setting, + get_type, + FALSE, + out_is_default, + out_to_free); +} + +static gconstpointer _get_fcn_gobject_int(ARGS_GET_FCN) +{ + GParamSpec * pspec; + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + gboolean is_uint64 = FALSE; + NMMetaSignUnsignInt64 v; + guint base = 10; + const NMMetaUtilsIntValueInfo *value_infos; + char * return_str; + + RETURN_UNSUPPORTED_GET_TYPE(); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), + property_info->property_name); + if (!G_IS_PARAM_SPEC(pspec)) + g_return_val_if_reached(FALSE); + + g_value_init(&gval, pspec->value_type); + g_object_get_property(G_OBJECT(setting), property_info->property_name, &gval); + NM_SET_OUT(out_is_default, g_param_value_defaults(pspec, &gval)); + switch (pspec->value_type) { + case G_TYPE_INT: + v.i64 = g_value_get_int(&gval); + break; + case G_TYPE_UINT: + v.u64 = g_value_get_uint(&gval); + is_uint64 = TRUE; + break; + case G_TYPE_INT64: + v.i64 = g_value_get_int64(&gval); + break; + case G_TYPE_UINT64: + v.u64 = g_value_get_uint64(&gval); + is_uint64 = TRUE; + break; + default: + g_return_val_if_reached(NULL); + break; + } + + if (property_info->property_typ_data + && property_info->property_typ_data->subtype.gobject_int.base > 0) { + base = property_info->property_typ_data->subtype.gobject_int.base; + } + + switch (base) { + case 10: + if (is_uint64) + return_str = g_strdup_printf("%" G_GUINT64_FORMAT, v.u64); + else + return_str = g_strdup_printf("%" G_GINT64_FORMAT, v.i64); + break; + case 16: + if (is_uint64) + return_str = g_strdup_printf("0x%" G_GINT64_MODIFIER "x", v.u64); + else + return_str = g_strdup_printf("0x%" G_GINT64_MODIFIER "x", (guint64) v.i64); + break; + default: + return_str = NULL; + g_assert_not_reached(); + } + + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY && property_info->property_typ_data + && (value_infos = property_info->property_typ_data->subtype.gobject_int.value_infos)) { + for (; value_infos->nick; value_infos++) { + if ((is_uint64 && value_infos->value.u64 == v.u64) + || (!is_uint64 && value_infos->value.i64 == v.i64)) { + gs_free char *old_str = return_str; + + return_str = g_strdup_printf("%s (%s)", old_str, value_infos->nick); + break; + } + } + } + + RETURN_STR_TO_FREE(return_str); +} + +static gconstpointer _get_fcn_gobject_mtu(ARGS_GET_FCN) +{ + guint32 mtu; + + RETURN_UNSUPPORTED_GET_TYPE(); + + if (!property_info->property_typ_data || !property_info->property_typ_data->subtype.mtu.get_fcn) + return _get_fcn_gobject_impl(property_info, + setting, + get_type, + FALSE, + out_is_default, + out_to_free); + + mtu = property_info->property_typ_data->subtype.mtu.get_fcn(setting); + if (mtu == 0) { + NM_SET_OUT(out_is_default, TRUE); + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return _("auto"); + return "auto"; + } + RETURN_STR_TO_FREE(g_strdup_printf("%u", (unsigned) mtu)); +} + +static gconstpointer _get_fcn_gobject_secret_flags(ARGS_GET_FCN) +{ + guint v; + GValue val = G_VALUE_INIT; + + RETURN_UNSUPPORTED_GET_TYPE(); + + g_value_init(&val, G_TYPE_UINT); + g_object_get_property(G_OBJECT(setting), property_info->property_name, &val); + v = g_value_get_uint(&val); + g_value_unset(&val); + RETURN_STR_TO_FREE(secret_flags_to_string(v, get_type)); +} + +static gconstpointer _get_fcn_gobject_enum(ARGS_GET_FCN) +{ + GType gtype = 0; + nm_auto_unref_gtypeclass GTypeClass *gtype_class = NULL; + nm_auto_unref_gtypeclass GTypeClass *gtype_prop_class = NULL; + const struct _NMUtilsEnumValueInfo * value_infos = NULL; + gboolean has_gtype = FALSE; + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + gint64 v; + gboolean format_numeric = FALSE; + gboolean format_numeric_hex = FALSE; + gboolean format_numeric_hex_unknown = FALSE; + gboolean format_text = FALSE; + gboolean format_text_l10n = FALSE; + gs_free char * s = NULL; + char s_numeric[64]; + GParamSpec * pspec; + + RETURN_UNSUPPORTED_GET_TYPE(); + + if (property_info->property_typ_data) { + if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) { + gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype(); + has_gtype = TRUE; + } + } + + if (property_info->property_typ_data && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY + && NM_FLAGS_ANY(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC + | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC_HEX + | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT + | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT_L10N)) { + format_numeric_hex = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC_HEX); + format_numeric = format_numeric_hex + || NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC); + format_text_l10n = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT_L10N); + format_text = format_text_l10n + || NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT); + } else if (property_info->property_typ_data && get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY + && NM_FLAGS_ANY(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC + | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC_HEX + | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT)) { + format_numeric_hex = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC_HEX); + format_numeric = format_numeric + && NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC); + format_text = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags, + NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT); + } else if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) { + /* by default, output in format "%u (%s)" (with hex for flags and l10n). */ + format_numeric = TRUE; + format_numeric_hex_unknown = TRUE; + format_text = TRUE; + format_text_l10n = TRUE; + } else { + /* by default, output only numeric (with hex for flags). */ + format_numeric = TRUE; + format_numeric_hex_unknown = TRUE; + } + + nm_assert(format_text || format_numeric); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(setting), property_info->property_name); + g_return_val_if_fail(pspec, NULL); + + g_value_init(&gval, pspec->value_type); + g_object_get_property(G_OBJECT(setting), property_info->property_name, &gval); + NM_SET_OUT(out_is_default, g_param_value_defaults(pspec, &gval)); + + if (pspec->value_type == G_TYPE_INT + || (G_TYPE_IS_CLASSED(pspec->value_type) + && G_IS_ENUM_CLASS( + (gtype_prop_class ?: (gtype_prop_class = g_type_class_ref(pspec->value_type)))))) { + if (pspec->value_type == G_TYPE_INT) { + if (!has_gtype) + g_return_val_if_reached(NULL); + v = g_value_get_int(&gval); + } else + v = g_value_get_enum(&gval); + } else if (pspec->value_type == G_TYPE_UINT + || (G_TYPE_IS_CLASSED(pspec->value_type) + && G_IS_FLAGS_CLASS( + (gtype_prop_class + ?: (gtype_prop_class = g_type_class_ref(pspec->value_type)))))) { + if (pspec->value_type == G_TYPE_UINT) { + if (!has_gtype) + g_return_val_if_reached(NULL); + v = g_value_get_uint(&gval); + } else + v = g_value_get_flags(&gval); + } else + g_return_val_if_reached(NULL); + + if (!has_gtype) { + gtype = pspec->value_type; + gtype_class = g_steal_pointer(>ype_prop_class); + } + + nm_assert(({ + nm_auto_unref_gtypeclass GTypeClass *t = NULL; + + (G_TYPE_IS_CLASSED(gtype) && (t = g_type_class_ref(gtype)) + && (G_IS_ENUM_CLASS(t) || G_IS_FLAGS_CLASS(t))); + })); + + if (format_numeric && !format_text) { + s = format_numeric_hex + || (format_numeric_hex_unknown + && !G_IS_ENUM_CLASS(gtype_class ?: (gtype_class = g_type_class_ref(gtype)))) + ? g_strdup_printf("0x%" G_GINT64_MODIFIER "x", v) + : g_strdup_printf("%" G_GINT64_FORMAT, v); + RETURN_STR_TO_FREE(g_steal_pointer(&s)); + } + + /* the gobject_enum.value_infos are currently ignored for the getter. They + * only declare additional aliases for the setter. */ + + if (property_info->property_typ_data) + value_infos = property_info->property_typ_data->subtype.gobject_enum.value_infos_get; + s = _nm_utils_enum_to_str_full(gtype, (int) v, ", ", value_infos); + + if (!format_numeric) + RETURN_STR_TO_FREE(g_steal_pointer(&s)); + + if (format_numeric_hex + || (format_numeric_hex_unknown + && !G_IS_ENUM_CLASS(gtype_class ?: (gtype_class = g_type_class_ref(gtype))))) + nm_sprintf_buf(s_numeric, "0x%" G_GINT64_MODIFIER "x", v); + else + nm_sprintf_buf(s_numeric, "%" G_GINT64_FORMAT, v); + + if (nm_streq0(s, s_numeric)) + RETURN_STR_TO_FREE(g_steal_pointer(&s)); + + if (format_text_l10n) + RETURN_STR_TO_FREE(g_strdup_printf(_("%s (%s)"), s_numeric, s)); + else + RETURN_STR_TO_FREE(g_strdup_printf("%s (%s)", s_numeric, s)); +} + +/*****************************************************************************/ + +static gboolean _set_fcn_gobject_string(ARGS_SET_FCN) +{ + gs_free char *to_free = NULL; + + if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + if (property_info->property_typ_data) { + if (property_info->property_typ_data->subtype.gobject_string.handle_emptyunset) { + if (value && value[0] && NM_STRCHAR_ALL(value, ch, ch == ' ')) { + /* this string property can both be %NULL and empty. To express that, we coerce + * a value of all whitespaces to dropping the first whitespace. That means, + * " " gives "", " " gives " ", and so on. + * + * This way the user can set the string value to "" (meaning NULL) and to + * " " (meaning ""), and any other string. + * + * This is and non-obvious escaping mechanism. But out of all the possible + * solutions, it seems the most sensible one. */ + value++; + } + } + if (property_info->property_typ_data->subtype.gobject_string.validate_fcn) { + value = property_info->property_typ_data->subtype.gobject_string.validate_fcn(value, + &to_free, + error); + if (!value) + return FALSE; + } else if (property_info->property_typ_data->values_static) { + value = + nmc_string_is_valid(value, + (const char **) property_info->property_typ_data->values_static, + error); + if (!value) + return FALSE; + } + } + g_object_set(setting, property_info->property_name, value, NULL); + return TRUE; +} + +static gboolean _set_fcn_gobject_bool(ARGS_SET_FCN) +{ + gboolean val_bool; + + if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + if (!nmc_string_to_bool(value, &val_bool, error)) + return FALSE; + + g_object_set(setting, property_info->property_name, val_bool, NULL); + return TRUE; +} + +static gboolean _set_fcn_gobject_int(ARGS_SET_FCN) +{ + int errsv; + const GParamSpec * pspec; + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + gboolean is_uint64; + NMMetaSignUnsignInt64 v; + gboolean has_minmax = FALSE; + NMMetaSignUnsignInt64 min = {0}; + NMMetaSignUnsignInt64 max = {0}; + guint base = 10; + const NMMetaUtilsIntValueInfo *value_infos; + + if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), + property_info->property_name); + if (!G_IS_PARAM_SPEC(pspec)) + g_return_val_if_reached(FALSE); + + is_uint64 = NM_IN_SET(pspec->value_type, G_TYPE_UINT, G_TYPE_UINT64); + + if (property_info->property_typ_data) { + if (value + && (value_infos = property_info->property_typ_data->subtype.gobject_int.value_infos)) { + gs_free char *vv_free = NULL; + const char * vv; + + vv = nm_strstrip_avoid_copy_a(300, value, &vv_free); + for (; value_infos->nick; value_infos++) { + if (nm_streq(value_infos->nick, vv)) { + v = value_infos->value; + goto have_value_from_nick; + } + } + } + + if (property_info->property_typ_data->subtype.gobject_int.base > 0) + base = property_info->property_typ_data->subtype.gobject_int.base; + + if ((is_uint64 + && (property_info->property_typ_data->subtype.gobject_int.min.u64 + || property_info->property_typ_data->subtype.gobject_int.max.u64)) + || (!is_uint64 + && (property_info->property_typ_data->subtype.gobject_int.min.i64 + || property_info->property_typ_data->subtype.gobject_int.max.i64))) { + min = property_info->property_typ_data->subtype.gobject_int.min; + max = property_info->property_typ_data->subtype.gobject_int.max; + has_minmax = TRUE; + } + } + + if (!has_minmax) { + switch (pspec->value_type) { + case G_TYPE_INT: + { + const GParamSpecInt *p = (GParamSpecInt *) pspec; + + min.i64 = p->minimum; + max.i64 = p->maximum; + } break; + case G_TYPE_UINT: + { + const GParamSpecUInt *p = (GParamSpecUInt *) pspec; + + min.u64 = p->minimum; + max.u64 = p->maximum; + } break; + case G_TYPE_INT64: + { + const GParamSpecInt64 *p = (GParamSpecInt64 *) pspec; + + min.i64 = p->minimum; + max.i64 = p->maximum; + } break; + case G_TYPE_UINT64: + { + const GParamSpecUInt64 *p = (GParamSpecUInt64 *) pspec; + + min.u64 = p->minimum; + max.u64 = p->maximum; + } break; + default: + g_return_val_if_reached(FALSE); + } + } + + if (is_uint64) + v.u64 = _nm_utils_ascii_str_to_uint64(value, base, min.u64, max.u64, 0); + else + v.i64 = _nm_utils_ascii_str_to_int64(value, base, min.i64, max.i64, 0); + + if ((errsv = errno) != 0) { + if (errsv == ERANGE) { + if (is_uint64) { + g_set_error( + error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is out of range [%" G_GUINT64_FORMAT ", %" G_GUINT64_FORMAT "]"), + value, + min.u64, + max.u64); + } else { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is out of range [%" G_GINT64_FORMAT ", %" G_GINT64_FORMAT "]"), + value, + min.i64, + max.i64); + } + } else { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is not a valid number"), + value); + } + return FALSE; + } + +have_value_from_nick: + + g_value_init(&gval, pspec->value_type); + switch (pspec->value_type) { + case G_TYPE_INT: + g_value_set_int(&gval, v.i64); + break; + case G_TYPE_UINT: + g_value_set_uint(&gval, v.u64); + break; + case G_TYPE_INT64: + g_value_set_int64(&gval, v.i64); + break; + case G_TYPE_UINT64: + g_value_set_uint64(&gval, v.u64); + break; + default: + g_return_val_if_reached(FALSE); + break; + } + + /* Validate the number according to the property spec */ + if (!nm_g_object_set_property(G_OBJECT(setting), property_info->property_name, &gval, error)) + g_return_val_if_reached(FALSE); + + return TRUE; +} + +static gboolean _set_fcn_gobject_mtu(ARGS_SET_FCN) +{ + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + const GParamSpec * pspec; + gint64 v; + + if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + if (nm_streq(value, "auto")) + value = "0"; + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), + property_info->property_name); + if (!pspec || pspec->value_type != G_TYPE_UINT) + g_return_val_if_reached(FALSE); + + v = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT32, -1); + if (v < 0) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is out of range [0, %u]"), + value, + (unsigned) G_MAXUINT32); + return FALSE; + } + + g_value_init(&gval, pspec->value_type); + g_value_set_uint(&gval, v); + + if (!nm_g_object_set_property(G_OBJECT(setting), property_info->property_name, &gval, error)) + g_return_val_if_reached(FALSE); + + return TRUE; +} + +/* Ideally we'll be able to get this from a public header. */ +#ifndef IEEE802154_ADDR_LEN + #define IEEE802154_ADDR_LEN 8 +#endif + +static gboolean _set_fcn_gobject_mac(ARGS_SET_FCN) +{ + NMMetaPropertyTypeMacMode mode; + gboolean valid; + + if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + if (property_info->property_typ_data) + mode = property_info->property_typ_data->subtype.mac.mode; + else + mode = NM_META_PROPERTY_TYPE_MAC_MODE_DEFAULT; + + if (mode == NM_META_PROPERTY_TYPE_MAC_MODE_INFINIBAND) { + valid = nm_utils_hwaddr_valid(value, INFINIBAND_ALEN); + } else if (mode == NM_META_PROPERTY_TYPE_MAC_MODE_WPAN) { + valid = nm_utils_hwaddr_valid(value, IEEE802154_ADDR_LEN); + } else { + valid = + nm_utils_hwaddr_valid(value, ETH_ALEN) + || (mode == NM_META_PROPERTY_TYPE_MAC_MODE_CLONED && NM_CLONED_MAC_IS_SPECIAL(value)); + } + + if (!valid) { + g_set_error(error, 1, 0, _("'%s' is not a valid Ethernet MAC"), value); + return FALSE; + } + + g_object_set(setting, property_info->property_name, value, NULL); + return TRUE; +} + +static gboolean _set_fcn_gobject_enum(ARGS_SET_FCN) +{ + GType gtype = 0; + GType gtype_prop; + gboolean has_gtype = FALSE; + nm_auto_unset_gvalue GValue gval = G_VALUE_INIT; + nm_auto_unref_gtypeclass GTypeClass *gtype_prop_class = NULL; + nm_auto_unref_gtypeclass GTypeClass *gtype_class = NULL; + gboolean is_flags; + int v; + + if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + if (property_info->property_typ_data) { + if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) { + gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype(); + has_gtype = TRUE; + } + } + + gtype_prop = _gobject_property_get_gtype(G_OBJECT(setting), property_info->property_name); + + if (has_gtype && NM_IN_SET(gtype_prop, G_TYPE_INT, G_TYPE_UINT) && G_TYPE_IS_CLASSED(gtype) + && (gtype_prop_class = g_type_class_ref(gtype)) + && ((is_flags = G_IS_FLAGS_CLASS(gtype_prop_class)) || G_IS_ENUM_CLASS(gtype_prop_class))) { + /* valid */ + } else if (!has_gtype && G_TYPE_IS_CLASSED(gtype_prop) + && (gtype_prop_class = g_type_class_ref(gtype_prop)) + && ((is_flags = G_IS_FLAGS_CLASS(gtype_prop_class)) + || G_IS_ENUM_CLASS(gtype_prop_class))) { + gtype = gtype_prop; + } else + g_return_val_if_reached(FALSE); + + if (!_nm_utils_enum_from_str_full( + gtype, + value, + &v, + NULL, + property_info->property_typ_data + ? property_info->property_typ_data->subtype.gobject_enum.value_infos + : NULL)) + goto fail; + + if (property_info->property_typ_data + && property_info->property_typ_data->subtype.gobject_enum.pre_set_notify) { + property_info->property_typ_data->subtype.gobject_enum.pre_set_notify(property_info, + environment, + environment_user_data, + setting, + v); + } + + gtype_class = g_type_class_ref(gtype); + + if (G_IS_FLAGS_CLASS(gtype_class) && !_SET_FCN_DO_SET_ALL(modifier, value)) { + nm_auto_unset_gvalue GValue int_value = {}; + guint v_flag; + + g_value_init(&int_value, G_TYPE_UINT); + g_object_get_property(G_OBJECT(setting), property_info->property_name, &int_value); + v_flag = g_value_get_uint(&int_value); + + if (_SET_FCN_DO_REMOVE(modifier, value)) + v = (int) (v_flag & ~((guint) v)); + else + v = (int) (v_flag | ((guint) v)); + } + + g_value_init(&gval, gtype_prop); + if (gtype_prop == G_TYPE_INT) + g_value_set_int(&gval, v); + else if (gtype_prop == G_TYPE_UINT) + g_value_set_uint(&gval, v); + else if (is_flags) { + nm_assert(G_IS_FLAGS_CLASS(gtype_prop_class)); + g_value_set_flags(&gval, v); + } else { + nm_assert(G_IS_ENUM_CLASS(gtype_prop_class)); + g_value_set_enum(&gval, v); + } + + if (!nm_g_object_set_property(G_OBJECT(setting), property_info->property_name, &gval, NULL)) + goto fail; + + return TRUE; + +fail: + if (error) { + gs_free const char **valid_all = NULL; + gs_free const char * valid_str = NULL; + gboolean has_minmax = FALSE; + int min = G_MININT; + int max = G_MAXINT; + + if (property_info->property_typ_data) { + if (property_info->property_typ_data->subtype.gobject_enum.min + || property_info->property_typ_data->subtype.gobject_enum.max) { + min = property_info->property_typ_data->subtype.gobject_enum.min; + max = property_info->property_typ_data->subtype.gobject_enum.max; + has_minmax = TRUE; + } + } + + if (!has_minmax && is_flags) { + min = 0; + max = (int) G_MAXUINT; + } + + valid_all = nm_utils_enum_get_values(gtype, min, max); + valid_str = g_strjoinv(",", (char **) valid_all); + if (is_flags) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid option '%s', use a combination of [%s]"), + value, + valid_str); + } else { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("invalid option '%s', use one of [%s]"), + value, + valid_str); + } + } + return FALSE; +} + +/*****************************************************************************/ + +static const char *const *_values_fcn_gobject_enum(ARGS_VALUES_FCN) +{ + GType gtype = 0; + gboolean has_gtype = FALSE; + gboolean has_minmax = FALSE; + int min = G_MININT; + int max = G_MAXINT; + char ** v; + + if (property_info->property_typ_data) { + if (property_info->property_typ_data->subtype.gobject_enum.min + || property_info->property_typ_data->subtype.gobject_enum.max) { + min = property_info->property_typ_data->subtype.gobject_enum.min; + max = property_info->property_typ_data->subtype.gobject_enum.max; + has_minmax = TRUE; + } + if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) { + gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype(); + has_gtype = TRUE; + } + } + + if (!has_gtype) { + gtype = _gtype_property_get_gtype(property_info->setting_info->general->get_setting_gtype(), + property_info->property_name); + } + + if (!has_minmax && G_TYPE_IS_CLASSED(gtype)) { + nm_auto_unref_gtypeclass GTypeClass *class = NULL; + + class = g_type_class_ref(gtype); + if (G_IS_FLAGS_CLASS(class)) { + min = 0; + max = (int) G_MAXUINT; + } + } + + /* the gobject_enum.value_infos are currently ignored for the list of + * values. They only declare additional (hidden) aliases for the setter. */ + + v = nm_utils_strv_make_deep_copied(nm_utils_enum_get_values(gtype, min, max)); + return (const char *const *) (*out_to_free = v); +} + +/*****************************************************************************/ + +static const char *const *_complete_fcn_gobject_bool(ARGS_COMPLETE_FCN) +{ + static const char *const v[] = { + "true", + "false", + "on", + "off", + "1", + "0", + "yes", + "no", + NULL, + }; + + if (!text || !text[0]) + return &v[6]; + return v; +} + +static const char *const *_complete_fcn_gobject_devices(ARGS_COMPLETE_FCN) +{ + NMDevice *const *devices = NULL; + guint i, j; + guint len = 0; + char ** ifnames; + + if (environment && environment->get_nm_devices) { + devices = environment->get_nm_devices(environment, environment_user_data, &len); + } + + if (len == 0) + return NULL; + + ifnames = g_new(char *, len + 1); + for (i = 0, j = 0; i < len; i++) { + const char *ifname; + + nm_assert(NM_IS_DEVICE(devices[i])); + + ifname = nm_device_get_iface(devices[i]); + if (ifname) + ifnames[j++] = g_strdup(ifname); + } + ifnames[j++] = NULL; + + *out_to_free = ifnames; + return (const char *const *) ifnames; +} + +/*****************************************************************************/ + +static char * +wep_key_type_to_string(NMWepKeyType type) +{ + switch (type) { + case NM_WEP_KEY_TYPE_KEY: + return g_strdup_printf(_("%d (key)"), type); + case NM_WEP_KEY_TYPE_PASSPHRASE: + return g_strdup_printf(_("%d (passphrase)"), type); + case NM_WEP_KEY_TYPE_UNKNOWN: + default: + return g_strdup_printf(_("%d (unknown)"), type); + } +} + +static char * +vlan_flags_to_string(guint32 flags, NMMetaAccessorGetType get_type) +{ + GString *flag_str; + + if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) + return g_strdup_printf("%u", flags); + + if (flags == 0) + return g_strdup(_("0 (NONE)")); + + flag_str = g_string_new(NULL); + g_string_printf(flag_str, "%d (", flags); + + if (flags & NM_VLAN_FLAG_REORDER_HEADERS) + g_string_append(flag_str, _("REORDER_HEADERS, ")); + if (flags & NM_VLAN_FLAG_GVRP) + g_string_append(flag_str, _("GVRP, ")); + if (flags & NM_VLAN_FLAG_LOOSE_BINDING) + g_string_append(flag_str, _("LOOSE_BINDING, ")); + if (flags & NM_VLAN_FLAG_MVRP) + g_string_append(flag_str, _("MVRP, ")); + + if (flag_str->str[flag_str->len - 1] == '(') + g_string_append(flag_str, _("unknown")); + else + g_string_truncate(flag_str, flag_str->len - 2); /* chop off trailing ', ' */ + + g_string_append_c(flag_str, ')'); + + return g_string_free(flag_str, FALSE); +} + +static char * +secret_flags_to_string(guint32 flags, NMMetaAccessorGetType get_type) +{ + GString *flag_str; + + if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) + return g_strdup_printf("%u", flags); + + if (flags == 0) + return g_strdup(_("0 (none)")); + + flag_str = g_string_new(NULL); + g_string_printf(flag_str, "%u (", flags); + + if (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED) + g_string_append(flag_str, _("agent-owned, ")); + if (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) + g_string_append(flag_str, _("not saved, ")); + if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) + g_string_append(flag_str, _("not required, ")); + + if (flag_str->str[flag_str->len - 1] == '(') + g_string_append(flag_str, _("unknown")); + else + g_string_truncate(flag_str, flag_str->len - 2); /* chop off trailing ', ' */ + + g_string_append_c(flag_str, ')'); + + return g_string_free(flag_str, FALSE); +} + +static const char * +_multilist_do_validate(const NMMetaPropertyInfo *property_info, + NMSetting * setting, + const char * item, + GError ** error) +{ + if (property_info->property_typ_data->values_static) { + nm_assert(!property_info->property_typ_data->subtype.multilist.validate_fcn); + return nmc_string_is_valid(item, + (const char **) property_info->property_typ_data->values_static, + error); + } + if (property_info->property_typ_data->subtype.multilist.validate_fcn) { + return property_info->property_typ_data->subtype.multilist.validate_fcn(item, error); + } + if (property_info->property_typ_data->subtype.multilist.validate2_fcn) { + return property_info->property_typ_data->subtype.multilist.validate2_fcn(setting, + item, + error); + } + + return item; +} + +static gconstpointer _get_fcn_multilist(ARGS_GET_FCN) +{ + return _get_fcn_gobject_impl( + property_info, + setting, + get_type, + property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn != NULL, + out_is_default, + out_to_free); +} + +static gboolean +_multilist_clear_property(const NMMetaPropertyInfo *property_info, + NMSetting * setting, + gboolean is_set /* or else set default */) +{ + if (property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn) { + property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn(setting, is_set); + return TRUE; + } + if (property_info->property_typ_data->subtype.multilist.clear_all_fcn) { + property_info->property_typ_data->subtype.multilist.clear_all_fcn(setting); + return TRUE; + } + return _gobject_property_reset(setting, property_info->property_name, FALSE); +} + +static gboolean _set_fcn_multilist(ARGS_SET_FCN) +{ + gs_free const char **strv = NULL; + gsize i, j, nstrv; + + if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value)) + return _multilist_clear_property(property_info, setting, FALSE); + + if (_SET_FCN_DO_REMOVE(modifier, value) + && (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32 + || property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s + || property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u)) { + gs_free gint64 *indexes = NULL; + + indexes = _value_str_as_index_list(value, &nstrv); + if (indexes) { + gint64 num; + + if (property_info->property_typ_data->subtype.multilist.get_num_fcn_u32) + num = property_info->property_typ_data->subtype.multilist.get_num_fcn_u32(setting); + else + num = property_info->property_typ_data->subtype.multilist.get_num_fcn_u(setting); + for (i = 0; i < nstrv; i++) { + gint64 idx = indexes[i]; + + if (idx >= num) + continue; + + if (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32) + property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32( + setting, + idx); + else if (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s) + property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s(setting, + idx); + else + property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u(setting, + idx); + } + return TRUE; + } + } + + if (_SET_FCN_DO_SET_ALL(modifier, value) + && property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn + && value[0] == '\0') + return _multilist_clear_property(property_info, setting, FALSE); + + strv = _value_strsplit( + value, + property_info->property_typ_data->subtype.multilist.strsplit_plain + ? VALUE_STRSPLIT_MODE_MULTILIST + : (property_info->property_typ_data->subtype.multilist.strsplit_with_spaces + ? VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES + : VALUE_STRSPLIT_MODE_ESCAPED_TOKENS), + &nstrv); + + j = 0; + for (i = 0; i < nstrv; i++) { + const char *item = strv[i]; + + item = _multilist_do_validate(property_info, setting, item, error); + if (!item) + return FALSE; + strv[j++] = item; + } + nstrv = j; + + if (_SET_FCN_DO_SET_ALL(modifier, value)) + _multilist_clear_property(property_info, setting, TRUE); + else if (property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn + && _is_default(property_info, setting)) { + /* the property is already the default. But we hav here a '+' / '-' modifier, so + * that always makes it non-default (empty) first. */ + _multilist_clear_property(property_info, setting, TRUE); + } + + for (i = 0; i < nstrv; i++) { + if (_SET_FCN_DO_REMOVE(modifier, value)) { + property_info->property_typ_data->subtype.multilist.remove_by_value_fcn(setting, + strv[i]); + } else { + if (property_info->property_typ_data->subtype.multilist.add2_fcn) + property_info->property_typ_data->subtype.multilist.add2_fcn(setting, strv[i]); + else + property_info->property_typ_data->subtype.multilist.add_fcn(setting, strv[i]); + } + } + return TRUE; +} + +static gboolean _set_fcn_optionlist(ARGS_SET_FCN) +{ + gs_free const char **strv = NULL; + gs_free const char **strv_val = NULL; + gsize strv_len; + gsize i, nstrv; + + nm_assert(!error || !*error); + + if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value)) + return _gobject_property_reset_default(setting, property_info->property_name); + + nstrv = 0; + strv = nm_utils_escaped_tokens_options_split_list(value); + if (strv) { + strv_len = NM_PTRARRAY_LEN(strv); + + strv_val = g_new(const char *, strv_len); + for (i = 0; strv[i]; i++) { + const char *opt_name; + const char *opt_value; + + nm_utils_escaped_tokens_options_split((char *) strv[i], &opt_name, &opt_value); + + if (property_info->property_type->values_fcn + || property_info->property_typ_data->values_static) { + gs_strfreev char **valid_options_to_free = NULL; + const char *const *valid_options; + + if (property_info->property_type->values_fcn) + valid_options = + property_info->property_type->values_fcn(property_info, + &valid_options_to_free); + else + valid_options = property_info->property_typ_data->values_static; + + opt_name = nmc_string_is_valid(opt_name, (const char **) valid_options, error); + if (!opt_name) + return FALSE; + } + + if (opt_value) { + if (_SET_FCN_DO_REMOVE(modifier, value)) + opt_value = NULL; + } else { + if (!_SET_FCN_DO_REMOVE(modifier, value)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is not valid; use